Building a subnetwork file

Setup

Before runnning this tutorial, install obsinfo and run obsinfo setup, as explained in Installation.

Creating a subnetwork file

The easiest way to create a subnetwork file is from a template. By typing obsinfo template subnetwork, you will create the following file, named TEMPLATE.subnetwork.yaml.

---
format_version: "1.0"
revision:
    authors:
        - {$ref: "persons/EXAMPLE.person.yaml"} # a person element
    date: "2024-09-30" # yyyy-mm-dd
subnetwork:
    operators: # Default station operators
        - {$ref: "operators/EXAMPLE.operator.yaml"}
    network: {$ref: "networks/EXAMPLE.network.yaml"}
    stations:
        "STA1":
            start_date: "2022-01-01T01:00:00"
            end_date: "2022-07-01T01:00:00" 
            locations:
                "00":
                    base: {$ref: "location_bases/EXAMPLE.location_base.yaml"}
                    position: {lon.deg: -1.5, lat.deg: 46.1, elev.m: -200}
                    # BEGIN OPTIONAL locations elements
                    water_level.m: 200  # if water surface is not at sea level
                    # END OPTIONAL locations elements
            instrumentation:  # or instrumentations (list)  
                base: {$ref: "instrumentation_bases/EXAMPLE.instrumentation_base.yaml"}  # `obsinfo template instrumentation_base` for details
                # BEGIN OPTIONAL instrumentation elements
                configuration: "SN01_2012+"  # instrumentation configuration
                modifications:
                    # BEGIN OPTIONAL modifications elements (ALL are optional)
                    equipment:  {model: "MOD_MODEL"}    # shortcut for base: {equipment:}
                    channels:       # replace channel definitions in the instrumentation_base
                        "2":  # do something to channel 2 only 
                            sensor: {base: {$ref: 'sensor_bases/EXAMPLE_BBSeismometer.sensor_base.yaml'}}  # replace the sensor on all channels
                    # END OPTIONAL modifications elements
                channel_modifications:  # All possible attributes under channel, in hierarchical order, except selecting response stages>
                    "1-*":      # {componentcode}-{locationcode} (either can be '*'), or {componentcode}, or "SEISMIC", or "PRESSURE"
                        # BEGIN OPTIONAL channel_modifications elements (ANY channel element is allowed, none is required)
                        orientation: {azimuth.deg: {value: 30, uncertainty: 5, measurement_method: 'P-pol'}}
                        replace_preamplifier: {base: {$ref: "preamplifier_bases/EXAMPLE_DPG.preamplifier_base.yaml"}}
                        comments: ["This is a channel-level comment"]
                        source_id: "FDSN:XX_STA1_D_H_Z"     # should this be "generate_source_id" boolean?
                        start_date:  "2022-02-01T02:00:00"  # Set a channel start_date that is different from the station start_date
                        end_date:    "2022-05-01T00:00:00"  # Set a channel end_date that is different from the station end_date
                        # END OPTIONAL channel_modifications elements
                notes:
                    - "This is a note.  It doesn't get written to the StationXML file"
                serial_number: "A14"  # shortcut for modifications: {equipment: {serial_number: "A14"}}
                datalogger_configuration: '500sps'  # shortcut for channel_modifications: {"*": {datalogger: {configuration: }}}
                datalogger_serial_number: '11'  # shortcut for channel_modifications: {"*": {datalogger: {equipment: {serial_number: }}}}
                seismic_sensor_serial_number: 'T1341'  # shortcut for channel_modifications: {"SEISMIC": {sensor: {equipment: {serial_number: }}}}
                pressure_sensor_serial_number: 'SIO0056'  # shortcut for channel_modifications: {"PRESSURE": {sensor: {equipment: {serial_number: }}}}
                seismic_sensor_configuration: 'Sphere02'  # shortcut for channel_modifications: {"SEISMIC": {sensor: {configuration: }}}
                pressure_sensor_configuration: '5018'  # shortcut for channel_modifications: {"PRESSURE": {sensor: {configuration: }}}
                # END OPTIONAL instrumentation elements
            # BEGIN OPTIONAL station elements
            site: "West volcano flank"  # Something specific about this station's position
            location_code: "00"  # Only needed if there is more than one location
            operators: # if not specified, will copy from subnetwork operators
                - {$ref: "operators/EXAMPLE.operator.yaml"}
            processing:
                - clock_correction:
                        drift:
                            base: {$ref: "timing_bases/EXAMPLE.timing_base.yaml"} # timing_base element
                            type: "piecewise_linear"  # or "cubic_spline", or "polynomial {a0} {a1} {a2}..."
                            syncs_instrument_reference:  # Specify datetimes as yyyy-mm-22Thh:mm:ss.mmmmZ
                                - ['2022-01-01T00:00:00Z', '2022-01-01T00:00:00Z']
                                - ['2022-07-01T03:00:00Z', '2022-07-01T03:00:00.345Z']
                        # BEGIN OPTIONAL clock_correction element
                        leapsecond_applied_corrections:
                            # BEGIN OPTIONAL leapsecond_applied_corrections elements
                            not_clock_corrected_miniseed: True  # does not-clock-corrected miniseed have leapsecond corrected? (False)
                            syncs_instrument: True              # Are the instrument syncs corrected for the leapsecond(s)?
                            # END OPTIONAL leapsecond_applied_corrections elements
                        # END OPTIONAL clock_correction element
            comments: 
                - "This is a station-level comment"
            extras: {whatever: "anything"}  # Free-form entry, saved in a station-level Comment
            notes: ["This is a note.  It doesn't get written to the StationXML file"]
            source_id: "FDSN:XX_STA1"      # should this be "generate_source_id" boolean? (or have run-time option?)
            # external_references:  # Commented out because obspy does not implement (as of 1.4.0)
            #     - uri: "http://usgs.gov"
            #       description: "USGS website"
            identifiers:
                - "DOI:10.7915/SN/XX"
            description: "Station description"
            restricted_status: "open" # "open", "closed" or "partial"
            # END OPTIONAL station elements
    # BEGIN OPTIONAL subnetwork elements
    leapseconds: # Leapseconds occuring during the data collection campaign
        list_file_entries:
            - line_text: "3692217600      37      # 1 Jan 2017"
              leap_type: '+'
        default_applied_corrections:
            not_clock_corrected_miniseed: False  # does not-clock-corrected miniseed have leapsecond corrected? (False)
            syncs_instrument: True               # Are the instrument syncs corrected for the leapsecond(s)?
    comments: 
       - "This is a simple network-level comment"
       -    value: "This is a full network-level comment"
            # OPTIONAL full comment elements
            begin_effective_time: "2022-01-02T00:00:00"
            end_effective_time: "2022-01-03T00:00:00"
            id: 4000    # integer
            subject: "comment subject"
            authors: [{$ref: "persons/EXAMPLE.person.yaml"}]
            # END OPTIONAL full comment elements      
    extras: {example: "an example", example_list: [1,2,3,4,5]}  # Saved to a network-level Comment
    # END OPTIONAL subnetwork elements
# BEGIN OPTIONAL top-level elements
notes: 
    - ""
# END OPTIONAL top-level elements

(Alternatively, you can copy one of the ``DATAPATH/subnetwork_files/EXAMPLE_.subnetwork.yaml`` files to your working directory)*

TEMPLATE.subnetwork.yaml contains JREF links to information files that are found in the example database: for this tutorial, your DATAPATH should point there. If you installed as instructed, this should already be the case. If not, see Copy an example database into your own folder.

Validating your subnetwork file

Run the schema subcommand

Type obsinfo schema TEMPLATE.subnetwork.yaml. The console output should be:

Validating subnetwork file
Reading {somepath}/TEMPLATE.subnetwork.yaml
schema =   subnetwork.schema.json
    Testing instance ...OK
subnetwork test for: {somepath}/TEMPLATE.subnetwork.yaml: PASSED

Where {somepath} is the full path to the current directory

Run the print subcommand

Type obsinfo print TEMPLATE.subnetwork.yaml. The console output should be:

Subnetwork:
    references:
        operator: MY_OPERATOR_NAME
        campaign: MY_CAMPAIGN_NAME
    network: Network:
        code: XX
        name: EXAMPLE NETWORK
        operators: Operators: []
        start_date: 2011-01-01
        end_date: 2016-12-31
        description: The code XX is reserved for test or transient data
        restricted_status: None
        identifiers: Identifiers: []
    extras: List of strings:
    - example: an example
    - example_list: [1, 2, 3, 4, 5]
    stations_comments: List of strings:
    - Comment:
        value: This is a simple network-level comment
    - Comment:
        value: This is a full network-level comment
        authors: Persons: [Person ["Teddy Riner"]]
        begin_effective_time: 2022-01-02T00:00:00
        end_effective_time: 2022-01-03T00:00:00
        id: 4000
        subject: comment subject
    - Comment:
        value: Extra attributes: ["example: an example", "example_list: [1, 2, 3, 4, 5]"]
    stations_operators: Operators: [agency: Example marine seismology instrumentation operator]
    stations: Stations: [Station STA1]

If you type obsinfo print TEMPLATE.subnetwork.yaml -n 2, you will get two levels of detail: notably, the details of STA1.

Run the plot subcommand

Type obsinfo plot TEMPLATE.subnetwork.yaml. The program will plot a station map:

../_images/obsinfo_plot_subnetwork_stationmap.png

and the channel time spans:

../_images/obsinfo_plot_subnetwork_timespans.png

The time span for *.CH1 is shorter than the others, as specified in TEMPLATE.subnetwork.yaml`.

Run the xml subcommand

Type obsinfo xml TEMPLATE.subnetwork.yaml The console output will be:

Reading subnetwork file...Creating Subnetwork object...[station][to_obspy()] [WARNING ] obspy 1.4.0 could not create station-level external_references, so your's will not be written. If this has been fixed in obspy, put an issue on the obsinfo gitlab page so that we can update this
Network XX (EXAMPLE NETWORK - The code XX is reserved for test or transient data)
    Station Count: 1/None (Selected/Total)
    2011-01-01T00:00:00.000000Z - 2016-12-31T00:00:00.000000Z
    Access: UNKNOWN
    Contains:
        Stations (1):
            XX.STA1 (West volcano flank)
        Channels (4):
            XX.STA1.00.CDG, XX.STA1.00.CHZ, XX.STA1.00.CH1, XX.STA1.00.CH2
StationXML file created: TEMPLATE.station.xml
Running /Users/crawford/_Work/Programming/obsinfo/src/obsinfo/stationxml-validator/stationxml-validator-1.7.5.jar ... 112,Error,XX,,,,2011-01-01T00:00:00,2016-12-31T00:00:00,Sta: STA1 endDate 2022-07-01T01:00:00 cannot occur after network endDate 2016-12-31T00:00:00

The program creates a StationXML file named TEMPLATE.station.xml, and validates it using stationxml-validator.

Your turn!

You can modify the subnetwork file and see what the outputs are. Some ideas are:

  • Remove all of the elements between the # OPTIONAL … and # END OPTIONAL … comments. This will make a much shorter subnetwork file with only essential information.

  • Copy the STA1 element a few times and change the copies’ name, locations and dates. obsinfo plot will reflect the changes.

In general, use the subcommand sequence:

  1. obsinfo schema

  2. obsinfo print,

  3. obsinfo plot

  4. obsinfo xml

to check your information files from the most basic (schema checking) to the highest (StationXML creation) levels, with the plot command letting you check that the station positions and active times are what you wanted.

Relevant references:

Details about some of the concepts are found in: