API Reference

Core Utilities

postprocessing_seismo_lib.utils.update_dataretrieval_input(file_path, output_file_path, Host, Method, Port, Window, SavePath=None, Url=None, directory=None, evid=None)[source]

Loads a JSON file, updates the ‘RetrieveParameters’ section with provided values, and writes the updated JSON to a new output file.

Mandatory parameters (‘Host’, ‘Method’, ‘Port’, ‘Window’) are always added or overwritten. Optional parameters (‘SavePath’, ‘Url’, ‘directory’, ‘evid’) are added only if provided, except for ‘SavePath’, which is always included (as an empty string if not provided).

Parameters:
  • file_path (str) – Path to the existing JSON file to load and update.

  • output_file_path (str) – Path where the updated JSON file should be saved.

  • Host (str) – Host address to include in ‘RetrieveParameters’.

  • Method (str) – HTTP method (e.g., ‘GET’, ‘POST’) to include in ‘RetrieveParameters’.

  • Port (int) – Port number to include in ‘RetrieveParameters’.

  • Window (str) – Identifier for the window or context.

  • SavePath (str, optional) – Path where results should be saved. Defaults to an empty string if not provided.

  • Url (str, optional) – URL to include in ‘RetrieveParameters’.

  • directory (str, optional) – Directory path to include in ‘RetrieveParameters’.

  • evid (str, optional) – Event ID to include in ‘RetrieveParameters’ under the ‘inEvid’ key. Omitted entirely (no ‘inEvid’ key added) if not provided.

Returns:

The updated JSON content with modified ‘RetrieveParameters’.

Return type:

dict

Raises:
  • FileNotFoundError – If the specified JSON file does not exist.

  • json.JSONDecodeError – If the file content is not valid JSON.

  • IOError – If there is an error saving the output file.

postprocessing_seismo_lib.utils.convert_file_to_json(input_file: str, output_file: str, id: str, event_file: str | None = None, pick_file: str | None = None, error_log_file: str | None = None)[source]

Auto-detect format (csv, quakeml, arcout) and convert to standard JSON response.

Parameters:
  • input_file (str) – Main input file (for quakeml or arcout).

  • output_file (str) – Output JSON filename.

  • id (str) – Event ID to use in the JSON.

  • event_file (str) – (Optional) For CSV: Path to events CSV file.

  • pick_file (str) – (Optional) For CSV: Path to picks CSV file.

  • error_log_file (str) – Optional path to write traceback if an error occurs.

postprocessing_seismo_lib.utils.build_message(body, id_str, format_str)[source]

Constructs the full JSON message given body content, ID, and format.

postprocessing_seismo_lib.utils.log_error(message)[source]
postprocessing_seismo_lib.utils.validate_pick_data(pick_data, schema)[source]

Validates pick data list against a specified schema.

postprocessing_seismo_lib.utils.validate_output_structure(wrapped_data)[source]

Validate the final output structure using output schema.

postprocessing_seismo_lib.utils.wrap_data(input_file_path, output_file_path, evid='stubvalue', module='associator', mode='hypoPN', testType='local', logging='False')[source]

Load, validate, wrap, and export pick data for use in associator or pickfilter modules.

This function reads a list of pick dictionaries from a JSON file, validates them against a schema, wraps the data into a module-specific JSON structure, validates the output, and writes it to a new file.

Parameters:
  • input_file_path (str) – Path to the input JSON file containing pick data.

  • output_file_path (str) – Path to write the validated and wrapped output JSON.

  • evid (str) – Event ID used in the output structure (e.g., file name or evid key).

  • module (str, optional) – Mode to wrap the data. Must be either: - ‘associator’: wraps with an “evid” key. - ‘pickfilter’: wraps with a “pickFile” key. Defaults to ‘associator’.

Raises:
  • ValueError – If the module is not ‘associator’ or ‘pickfilter’.

  • ValueError – If input data fails validation.

  • Exception – For any other unexpected errors during processing.

Side Effects:
  • Logs errors to a file named ‘wrap_data_errors.log’.

  • Prints validation or error status to the console.

Example

wrap_data(“input.json”, “output.json”, “event_123”, module=”pickfilter”) wrap_data(“input.json”, “output.json”, “event_456”, module=”associator”)

postprocessing_seismo_lib.utils.extract_body_from_file(filepath)[source]

Extracts and returns the ‘body’ field from a JSON file.

This function reads a JSON file from the specified filepath, parses its contents, and returns the value associated with the top-level “body” key, if present.

Parameters:

filepath (str) – Path to the JSON file to be read.

Returns:

The value of the “body” field in the JSON file, which may be a dictionary, list, string, number, or None depending on the file contents. If the “body” key is not present, returns None.

Return type:

Any

Raises:
  • FileNotFoundError – If the specified file does not exist.

  • json.JSONDecodeError – If the file contents are not valid JSON.

  • Exception – For other unexpected I/O or parsing errors.

Example

Given a file example.json with contents: {

“body”: {

“message”: “Hello, world!”

}, “status”: “ok”

}

Calling extract_body_from_file(“example.json”) returns: {

“message”: “Hello, world!”

}

postprocessing_seismo_lib.utils.detection_anss_to_scsn(detection)[source]

Convert an ANSS detection dict to the SCSN detection JSON format.

Takes the dict produced by postprocessing_seismo_lib.json_writers.dumps_detection_anss (the anssformats Detection schema) and returns a dict in the SCSN detection format documented at services/formats/format-docs/detection.md (capitalized keys; Source/Hypocenter objects; Data array of picks; Magnitude array).

Field mapping notes

  • Hypocenter coordinates are GeoJSON [lon, lat, depth]; they are split into Latitude/Longitude/Depth.

  • ANSS method maps to SCSN Picker.

  • ANSS associationInfo (phase) and locationInfo (distance/azimuth/residual) are merged into SCSN AssociationInfo.

  • Pick Quality (a non-schema extension the builder injects) is passed through to SCSN Quality.

  • Fields with no ANSS source are omitted: location weight (no SCSN AssociationInfo counterpart) and Sigma/error fields.

param detection:

ANSS detection dict.

type detection:

dict

returns:

The detection in SCSN format.

rtype:

dict

Pick / Detection Format Conversions

postprocessing_seismo_lib.conversions.anss_to_soa_pick_format(anss_file_path)[source]

Convert ANSS-formatted (anss-formats==0.1.3) picks back to SOA format.

Parameters:

anss_file_pathstr

Path to the JSON file containing ANSS picks.

Returns:

dict
{

“success”: True/False, “num_picks”: int, “num_errors”: int, “picks”: list of SOA-format picks, “errors”: list of errors with traceback

}

postprocessing_seismo_lib.conversions.create_channel(CHANNEL_GEOMETRY, CHANNEL_PROPERTIES)[source]
postprocessing_seismo_lib.conversions.soa_to_anss_pick_format(pick_file_path, station_csv_path=None)[source]

Convert a list of SOA-format picks (in a JSON file) into anss-formats==0.1.3 Pick dicts.

Parameters:

pick_file_pathstr

Path to the JSON file containing a bare list of SOA-format picks.

station_csv_pathstr, optional

Path to a station metadata CSV (NET, STA, CHA, LON, LAT, ELEV columns). If not provided, the archive_stations_loc_dates.csv bundled with this library is used.

Returns:

dict

{“success”, “num_picks”, “num_errors”, “picks”, “errors”}

postprocessing_seismo_lib.conversions.phasenet_soa_to_anss_pick_format(soa_source, station_csv_path=None)[source]

[FIRST] Convert SOA picks from the Phasenet lambda’s response into anss-formats==0.1.3 Pick dicts.

Parameters:

soa_source :
One of:
  • a path to a lambda HTTP response envelope JSON file ({“status”, “headers”, “body”: [<SOA pick>, …]})

  • a path to a JSON file containing a bare list of SOA picks

  • an already-loaded envelope dict, or an already-loaded bare list of SOA picks

station_csv_pathstr, optional

Path to a station metadata CSV. If not provided, the archive_stations_loc_dates.csv bundled with this library is used.

Returns:

dict

{“success”, “num_picks”, “num_errors”, “picks”, “errors”}

postprocessing_seismo_lib.conversions.pickfilter_soa_to_anss_pick_format(pickfilter_source, station_csv_path=None)[source]

[SECOND] Convert a list of SOA picks returned by pick-filter-spec’s PickProcess/v2 endpoint (a “localpick”-style request) into anss-formats==0.1.3 Pick dicts.

Unlike a Phasenet-only pick, a pick-filter pick typically carries an “Onset” and a 2-entry “Quality” list (PhaseNet probability + Hypoinverse pick-weight code), both of which are preserved here (onset -> Pick.onset, Quality -> Pick.analyticsInfo.predictions).

Parameters:

pickfilter_source :
One of:
  • a path to the PickProcess/v2 response envelope JSON file ({“status”, “headers”, “body”: [<SOA pick>, …]})

  • a path to a JSON file containing a bare list of SOA picks

  • an already-loaded envelope dict, or an already-loaded bare list of SOA picks

station_csv_pathstr, optional

Path to a station metadata CSV. If not provided, the archive_stations_loc_dates.csv bundled with this library is used.

Returns:

dict

{“success”, “num_picks”, “num_errors”, “picks”, “errors”}

postprocessing_seismo_lib.conversions.pickfilter_soa_to_anss_detection_format(detection_source, station_csv_path=None)[source]

[THIRD] Convert an SOA-format detection returned by pick-filter-spec’s PickProcess/v2 endpoint (a “localdetection”-style request) into a single anss-formats==0.1.3 Detection dict.

Parameters:

detection_source :
One of:
  • a path to the PickProcess/v2 response envelope JSON file ({“status”, “headers”, “body”: {Type, ID, Source, Hypocenter, Magnitude, Data}})

  • a path to a JSON file containing the bare detection body dict

  • an already-loaded envelope dict, or an already-loaded bare detection body dict

station_csv_pathstr, optional

Path to a station metadata CSV. If not provided, the archive_stations_loc_dates.csv bundled with this library is used.

Returns:

dict

{“success”, “detection”, “num_picks”, “num_errors”, “errors”}

postprocessing_seismo_lib.conversions.soa_to_soa_detection_format_using_anss_libraries(detection_source, station_csv_path=None)[source]

Normalize/round-trip an SOA-format detection by taking a detour through anss-formats==0.1.3’s Detection/Pick classes, then converting the result back to SOA detection format – the detection-level analogue of soa_to_soa_pick_format_using_anss_libraries.

Recognizes, independently and automatically:
  • Envelope vs bare body: a lambda/PickProcess-style {“status”, “headers”, “body”: {…}} envelope, or an already-unwrapped detection body dict (see e.g. 61146748_filteredpicks_detectionSPECFORMAT_TEST_2026CHECK_DETECT.json vs 1204954_detection.json / association_detection_wrapped_data.json).

  • Optional Magnitude: a “Magnitude” list of {Type, Value, Author}, or absent entirely.

  • Per-pick shape: pick-filter-style picks (Filter/Amplitude/Quality, no AssociationInfo, e.g. 1204954_detection.json’s Data) and association-style picks (AssociationInfo with Phase/Distance/Azimuth/Residual, no Filter/Amplitude, e.g. association_detection_wrapped_data.json’s Data) both round-trip correctly, since filterInfo/amplitudeInfo and locationInfo are independent, optional Pick fields.

Parameters:

detection_source :
One of:
  • a path to a detection envelope or bare-body JSON file

  • an already-loaded envelope dict, or an already-loaded bare detection body dict

station_csv_pathstr, optional

Path to a station metadata CSV. If not provided, the archive_stations_loc_dates.csv bundled with this library is used.

Returns:

dict

{“success”, “detection”, “num_picks”, “num_errors”, “errors”} “detection” is the SOA-format detection dict (Type/ID/Source/Hypocenter/Data[/Magnitude]).

postprocessing_seismo_lib.conversions.phasenet_csv_to_soa_pick_format(picks_file, highpass_filt)[source]
postprocessing_seismo_lib.conversions.capitalize_keys(obj)[source]

Recursively capitalize the first letter of every key in a nested structure.

postprocessing_seismo_lib.conversions.soa_to_soa_pick_format_using_anss_libraries(pick_file_used)[source]

Normalize/enhance a list of SOA picks using anss-formats==0.1.3 classes (ChannelProperties, Source, Filter, Amplitude) for field validation, then capitalize the resulting keys back to SOA’s convention.

Note: anss-formats==0.1.3 removed anssformats.quality.Quality (folded into Pick.analyticsInfo elsewhere in this module), so Quality here is passed through as a plain dict – the SOA Quality shape itself (list of {Standard, Value}) hasn’t changed.

AQMS / pick-filter-spec Detection JSON Writer

postprocessing_seismo_lib.json_writers.detection_json_anss.dumps_detection_anss(*data, agencyID=None, author=None)[source]

Build ANSS detection JSON and return it as a dict.

Accepts either data source:

  • dumps_detection_anss(event, origin, netmag, arrivals) – the AQMS dicts, whose arrivals already carry each station’s lon/lat/elev via arr['site'].

  • dumps_detection_anss(picks_df, evt, agencyID=..., author=...) – a pandas DataFrame of picks and an evt dict. agencyID and author set the detection-level Source (the DataFrame carries no event agency/author). No station-CSV lookup is performed: if a row’s Site dict carries Lon/Lat/Elev, they’re passed through to the pick’s Channel geometry; otherwise that pick is emitted with no channel.geometry at all (rather than a fabricated lon/lat/elev) – see _assemble_json().

postprocessing_seismo_lib.json_writers.detection_json_anss.dump_detection_anss(*data, fp, agencyID=None, author=None, **json_kwargs)[source]

Build ANSS detection JSON and write it to fp.

Mirrors json.dump: fp is a .write()-supporting file-like object and json_kwargs (e.g. indent) pass through to json.dump. Accepts the same data sources as dumps_detection_anss(); fp is keyword-only.

postprocessing_seismo_lib.json_writers.detection_json_anss.map_arrival_quality_to_score(quality, channel)[source]

Map a pick’s ML quality/probability to an integer hypoinverse score (0-4).

Copied verbatim from db-detection’s db2detectionjson.py so the SCSN quality thresholds live alongside the builder; behavior is intentionally identical.

Hypocenter JSON Writer

class postprocessing_seismo_lib.json_writers.hypocenter_json.HypocenterJSON(**kwargs)[source]

Bases: object

orid_sql = 'select lat, lon, depth, datetime, erlat, erlon, sdep, stime from origin where orid = :orid'
evid_sql = 'select lat, lon, depth, datetime, erlat, erlon, sdep, stime from origin join event on event.prefor = origin.orid where event.evid = :evid'
DIRECT_FIELDS = ('lat', 'lon', 'depth', 'origin_time')
hypocenter()[source]

Build the ANSS hypocenter JSON, from either of two input paths.

orid or evid -> look the origin up in the database lat, lon, depth, origin_time -> build directly, no database access

An id wins when both are supplied, since the database is authoritative. The direct path needs origin_time as well as the coordinates: originTime is required by HypocenterProperties and cannot be derived from a location.

Raises ValueError when neither path has complete input, and LookupError (via _from_database) when an id matches no usable row.

postprocessing_seismo_lib.json_writers.hypocenter_json.dumps_hypocenter_anss(*, orid=None, evid=None, lat=None, lon=None, depth=None, origin_time=None, db_name=None, db_hostname=None, db_user=None, db_password=None, db_port=5432)[source]

Build ANSS hypocenter JSON and return it as a dict.

Thin wrapper around HypocenterJSON, matching the dumps_detection_anss/dump_detection_anss calling convention used elsewhere in postprocessing_seismo_lib.json_writers. Two input paths:

  • orid or evid – looks the origin up in the AQMS database via db_name/db_hostname/db_user/db_password/db_port. An id wins when both an id and lat/lon/depth/origin_time are supplied.

  • lat, lon, depth, origin_time – builds directly, no database access.

Raises ValueError when neither input path has complete input, and LookupError when an id matches no usable row (see HypocenterJSON.hypocenter()).

postprocessing_seismo_lib.json_writers.hypocenter_json.dump_hypocenter_anss(*, fp, orid=None, evid=None, lat=None, lon=None, depth=None, origin_time=None, db_name=None, db_hostname=None, db_user=None, db_password=None, db_port=5432, **json_kwargs)[source]

Build ANSS hypocenter JSON and write it to fp.

Mirrors json.dump: fp is a .write()-supporting file-like object and json_kwargs (e.g. indent) pass through to json.dump. Accepts the same input paths as dumps_hypocenter_anss(); fp is keyword-only.