Building an instrumentation_base file

Instrumentation files represent a complete instrumentation, with one or more channels consisting of a sensor, a preamplifier and possible a datalogger. The _base part of the filetype indicates that this file can have configurations and can be modified from higher levels. Instrumentation files can call lower-level files in order to avoid repeating information. The figure below compares the hierarchy of files beneath the instrumentation_base file with the StationXML element hierarchy:

../_images/instrumentation_obsinfo_stationxml.png

The obsinfo hierarchy replicates the information in the StationXML hierarchy, with the least repeated information possible. Instead of fully and separately declaring each channel, it declares a default channel, and then any differences that the other channels have with the default. Instead of having one list of stages that integrates the sensor, preamplifier and datalogger, each of these instrument components has its own list of stages. The “InstrumentSensitivity” element is absent in obsinfo, as it can be calculated from the stages. The StationXML Sensor, Preamplifier and Datalogger elements, which are simply implementations of the Equipment element type, are declared as “sensor:equipment”, “preamplifier:equipment” and “datalogger:equipment” in obsinfo.

Creating the instrumentation_base file

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

---
format_version: "1.0"
revision:
    authors:
        - {$ref: "persons/EXAMPLE.person.yaml"} # Reference to a file,
                                                 # or fields of a person element
    date: "2024-09-30" # yyyy-mm-dd
instrumentation_base:
    equipment:
        model: "MY_OBS"
        type: "My Ocean Bottom Seismometer"
        description: "This is my OBS!" 
        manufacturer: "My OBS park"
        # BEGIN OPTIONAL equipment elements
        vendor: "various"
        serial_number: "2014a2"
        installation_date: "2024-09-30"
        removal_date: "2025-08-31"
        resource_id: "IPGP:2004iepw44" # Unique ID of the filter, typically
                                       # "GENERATOR:Meaningful_ID"
        calibration_dates: 
           - "2004-09-22T07:00:00"
           - "2014-08-31T07:00:00"
        # END OPTIONAL equipment elements
    channels:
        default:
            datalogger:
                base: {$ref: "datalogger_bases/EXAMPLE.datalogger_base.yaml"}
                # BEGIN OPTIONAL datalogger elements
                configuration: "100sps_LINEAR"  # Must be a configuration defined in the datalogger_base
                serial_number: "20"
                notes: ["A note"]
                equipment: # modify elements of the equipment defined in datalogger_base
                    model: "ADS1281"
                    manufacturer: "Texas Instruments"
                    description: "Single Chip High-Resolution Analog-to-Digital Converter"
                    # BEGIN OPTIONAL equipment elements.
                    type: "delta-sigma A/D converter + digital filter"
                    vendor: "various"
                    serial_number: "2014a2"
                    installation_date: "2024-09-30"
                    removal_date: "2025-08-31"
                    resource_id: "IPGP:2004iepw44"
                    calibration_dates: 
                       - "2004-09-22T07:00:00"
                    # END OPTIONAL equipment elements.
                stages:   # replace all stages 
                    - {base: {$ref: "datalogger_bases/stage_bases/EXAMPLE_FIR1.stage_base.yaml"}}
                    - {base: {$ref: "datalogger_bases/stage_bases/EXAMPLE_FIR2.stage_base.yaml"}}
                    - {base: {$ref: "datalogger_bases/stage_bases/EXAMPLE_FIR2.stage_base.yaml"}}
                    - {base: {$ref: "datalogger_bases/stage_bases/EXAMPLE_FIR2.stage_base.yaml"}}
                    - {base: {$ref: "datalogger_bases/stage_bases/EXAMPLE_FIR2.stage_base.yaml"}}
                    - {base: {$ref: "datalogger_bases/stage_bases/EXAMPLE_FIR2.stage_base.yaml"}}
                    - {base: {$ref: "datalogger_bases/stage_bases/EXAMPLE_FIR2.stage_base.yaml"}}
                    - {base: {$ref: "datalogger_bases/stage_bases/EXAMPLE_FIR2.stage_base.yaml"}}
                    - {base: {$ref: "datalogger_bases/stage_bases/EXAMPLE_FIR3.stage_base.yaml"}}
                stage_modifications: # Modify certain stages
                    "1": {gain: {value: 100}}  # Modifies the "gain" subelement of stage 1
                sample_rate: 125  # Only needed if you replace/modify stages
                correction: 24    # Only needed if you replace/modify stages
                # END OPTIONAL datalogger elements
            sensor:
                base: {$ref: "sensor_bases/EXAMPLE_BBSeismometer.sensor_base.yaml"}
                # BEGIN OPTIONAL sensor elements
                configuration: "something"  # Must be a configuration defined in the sensor_base
                serial_number: "A16"
                notes: ["A note"]
                equipment:
                    # All elements are optional, see datalogger:equipment above
                    model: "Example sensor"
                stages:
                    - {base: {$ref: "sensor_bases/stage_bases/EXAMPLE_DPG.stage_base.yaml"}}
                stage_modifications:
                     "1": {gain: {value: 100}}  # Modifies the "gain" subelement of stage 1
                seed_codes:  # Modify values given in sensor_base
                    # BEGIN OPTIONAL seed_codes elements
                    band: "shortperiod"  # "shortperiod" or "broadband" to
                                         # automatically choose the appropriate
                                         # band code for the sample rate, or
                                         # one of the "non-band" band codes:
                                         # ('A', 'I', 'O', 'L' or 'S')
                    instrument: "H"      # Seed instrument code
                    # END OPTIONAL seed_codes elements                    
                # END OPTIONAL sensor elements
            # BEGIN OPTIONAL default elements
            preamplifier:
                base: {$ref: "preamplifier_bases/EXAMPLE_DPG.preamplifier_base.yaml"}
                # BEGIN OPTIONAL preamplifier elements
                configuration: "16x"  # Must be a configuration defined in the preamplifier_base
                serial_number: "2020_003"
                notes: ["A note"]
                equipment:
                    # All elements are optional, see datalogger:equipment above
                    model: "Example sensor"
                stages:
                    - {base: {$ref: "preamplifier_bases/stage_bases/EXAMPLE_DPG-Card.stage_base.yaml"}}
                stage_modifications:
                     "1": {gain: {value: 100}}   # Modifies the "gain" subelement of stage 1
                # END OPTIONAL preamplifier elements
            location_code: "01"        # If not specified, use station's location code
            restricted_status: "open"  # "open", "closed", or "partial"
            source_id: "FDSN:XX_SS_00_H_H_Z"    # StationXML sourceID: FDSN:<network>_<station>_<location>_<band>_<source>_<subsource>
            identifiers: ["DOI:10.7915/SN/XX"]  # List of identifiers
            external_references:  # List of external references
                -   uri: "http://usgs.gov"
                    description:  "USGS website"
            comments:   # List of comments
                - "A simple channel-level comment"
                -   value: "A full channel-level comment"
                    # OPTIONAL full comment elements
                    begin_effective_time: "2020-01-01T00:00:00Z"
                    end_effective_time:   "2024-09-30T00:00:00Z"
                    id: 1      # integer id
                    subject: "My subject"  # An attribute
                    authors:
                        - {$ref: "persons/EXAMPLE.person.yaml"}
                    # END OPTIONAL full comment elements
            extras: {}  # anything you want, written as an object (put into comments)
            # END OPTIONAL default elements
        "1":   # One element per instrument channel, name is generally the 
               # datalogger's channel #
            orientation:
                code: "Z"   # The SEED orientation (or sub-source) code for this channel
                azimuth.deg:
                    value: 0
                    # BEGIN OPTIONAL azimuth.deg elements
                    uncertainty: 180
                    # END OPTIONAL azimuth.deg elements
                dip.deg:
                    value: -90
                    # BEGIN OPTIONAL dip.deg elements
                    uncertainty: 5
                    # END OPTIONAL dip.deg elements
            # BEGIN OPTIONAL channel elements that MODIFY the specified elements
            sensor: {configuration: "blah"}  # UPDATE default sensor's fields
            datalogger: {configuration: "bleh"}  # UPDATE default datalogger's fields
            preamplifier: {configuration: "bluh"}  # UPDATE default preamplifier's fields
            identifiers:  ["DOI:10.7915/SN/YY"]
            external_references:
                -   uri: "http://ipgp.fr"
                    description:  "IPGP website"
            comments : 
                - "A simple channel-level comment"
            extras:  {}
            # END OPTIONAL channel elements that MODIFY the specified elements
            # BEGIN OPTIONAL channel elements that REPLACE default elements
            location_code: '03'
            restricted_status: "closed"
            source_id: "FDSN:XX_SS_00_H_H_H"
            replace_sensor: 
                base: {$ref: "sensor_bases/EXAMPLE_DPG.sensor_base.yaml"}  
            replace_datalogger: 
                base: {$ref: "datalogger_bases/EXAMPLE.datalogger_base.yaml"}
                # BEGIN OPTIONAL replace_datalogger elements
                configuration: "250sps"
                # END OPTIONAL replace_datalogger elements
            replace_preamplifier:
                base: {$ref: "preamplifier_bases/EXAMPLE_DPG.preamplifier_base.yaml"}
            replace_identifiers:   ["DOI:10.7915/SN/YY"]
            replace_external_references:
                -   uri: "http://ipgp.fr"
                    description:  "IPGP website"
            replace_comments:
                - "A replacement channel-level comment"
            replace_extras: {}
            # END OPTIONAL channel elements that REPLACE default elements
    # BEGIN OPTIONAL instrumentation_base elements
    configuration_default: "CONFIG1"
    configurations:
        "CONFIG1":  # Modifications to the base instrumentation
            channels:
                "default": {replace_datalogger:  {base: {$ref: "datalogger_bases/EXAMPLE.datalogger_base.yaml"}}}
        "CONFIG2":  # Modifications to the base instrumentation
            channels:
                "default":
                    replace_datalogger:  {base: {$ref: "datalogger_bases/EXAMPLE.datalogger_base.yaml"}}
                    replace_preamplifier:
                        base: {$ref: "preamplifier_bases/EXAMPLE_DPG.preamplifier_base.yaml"}
                        configuration: "16x gain"
        "SN01":
            equipment: {serial_number: '01'}
            channels:
                default: {sensor: {configuration: "Sphere01"}}
                "4": {sensor: {configuration: "generic"}}
    # END OPTIONAL instrumentation_base elements
# BEGIN OPTIONAL top-level elements
notes: 
    - ""
# END OPTIONAL top-level elements

The template file points to information files in the example database. For the following, your DATAPATH should point there (see Copy an example database into your own folder)

Validating the instrumentation_base file

Validating your instrumentation file follows the same sequences as Validating your subnetwork file :

Run the schema subcommand

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

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

Run the print subcommand

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

TEMPLATE.instrumentation_base.yaml:
    Instrumentation:
        equipment: Equipment:
            type: My Ocean Bottom Seismometer
            description: This is my OBS!
            model: MY_OBS
            manufacturer: My OBS park
            vendor: various
            serial_number: 2014a2
            resource_id: IPGP:2004iepw44
            installation_date: 2024-09-30
            removal_date: 2025-08-31
            calibration_dates: OIDates: 2 OIDates
        channels: Channels: [Channel 03.CDH]

Run the plot subcommand

Type obsinfo plot TEMPLATE.instrumentation_base.yaml. The program will plot the instrument responses for each channel:

../_images/obsinfo_plot_instrumentation_base.png

Since the template file only has one channel, only one response is plotted.

Modifying the instrumentation_base file

Simplifying

Every line between an # BEGIN OPTIONAL {...} and its matching # END OPTIONAL {...} comment lines can be removed. Copy TEMPLATE.instrumentation_base.yaml to a new file called SIMPLE.instrumentation_base.yaml, and remove all optional lines from this new file. You will obtain a greatly simplified file that still validates, prints and plots:

---
format_version: "1.0"
revision:
    authors:
        - {$ref: "persons/EXAMPLE.person.yaml"}
    date: "2024-09-30"
instrumentation_base:
    equipment:
        model: "MY_OBS"
        type: "My Ocean Bottom Seismometer"
        description: "This is my OBS!"
        manufacturer: "My OBS park"
    channels:
        default:
            datalogger:
                base: {$ref: "datalogger_bases/EXAMPLE.datalogger_base.yaml"}
            sensor:
                base: {$ref: "sensor_bases/EXAMPLE_BBSeismometer.sensor_base.yaml"}
        "1":   # One element per instrument channel
            orientation:
                code: "H"   # The SEED orientation (or sub-source) code for this channel
                azimuth.deg:
                    value: 0
                dip.deg:
                    value: -90
> obsinfo print SIMPLE.instrumentation_base.yaml
SIMPLE.instrumentation_base.yaml:
    Instrumentation:
        equipment: Equipment:
            type: My Ocean Bottom Seismometer
            description: This is my OBS!
            model: MY_OBS
            manufacturer: My OBS park
        channels: Channels: [Channel 00.HHZ]
> obsinfo plot SIMPLE.instrumentation_base.yaml
../_images/obsinfo_plot_simple_instrumentation_base_corrected.png

The sensor response is different because the sensor was replaced in the original template file.

Adding channels

Below we add some channels, to create a typical ocean bottom seismometer, with three seismometer channels and one pressure channel. Copy SIMPLE.instrumentation_base.yaml to MULTICHANNEL.instrumentation_base.yaml and add new channels “2”, “3” and “4” to obtain the following:

channels:
    default:
        datalogger:
            base: {$ref: "datalogger_bases/EXAMPLE.datalogger_base.yaml"}
        sensor:
            base: {$ref: "sensor_bases/EXAMPLE_BBSeismometer.sensor_base.yaml"}
    "1":
        orientation: {code: "Z", azimuth.deg: {value: 0}, dip.deg: {value: -90}}
    "2":
        orientation: {code: "1", azimuth.deg: {value: 0, uncertainty: 180},
                      dip.deg: {value: -90}}
    "3":
        orientation: {code: "2", azimuth.deg: {value: 90, uncertainty: 180},
                      dip.deg: {value: -90}}
    "4":
        orientation: {code: "H", azimuth.deg: {value: 0}, dip.deg: {value: -90}}
        replace_sensor:
            base: {$ref: "sensor_bases/EXAMPLE_DPG.sensor_base.yaml"}

(the declaration of channel “1” is then same as before, but we have used a more compact, JSON-based, syntax). Some notes are: - The replace_sensor element in channel key=``”4”`` completely replaces the sensor. If we had used sensor, it would have modified the existing sensor, replacing all the sub-elements specified in sensor_bases/EXAMPLE_DPG.sensor_base.yaml but leaving any non-specified values, for example configurations with different names, which we rarely want to do. Also note that the channel key is not the same as its code. The key is not seen in the output StationXML file and can be any text string. We recommend using a code for the instrumentations’ internal port, which can be useful for noting which internal datalogger channel ports are used.

The print and plot outputs change accordingly:

MULTCHANNEL.instrumentation_base.yaml:
    Instrumentation:
        equipment: Equipment:
            type: My Ocean Bottom Seismometer
            description: This is my OBS!
            model: MY_OBS
            manufacturer: My OBS park
        channels: Channels:
            - Channel 00.HHZ
            - Channel 00.HH1
            - Channel 00.HH2
            - Channel 00.HDH
../_images/obsinfo_plot_multichannel_instrumentation_base.png

We only see two traces in each plot, because all of the seismometer channels have the same response.

Modifying channels

You can use the configuration, modification and/or stage_modification elements to modify from the instrument components' default properties.

Copy MULTICHANNEL.instrumentation_base.yaml to MODIFIIED.instrumentation_base.yaml, then modify channel key:

  • “2”, to specify a configuration using the configuration element:

  • “3”, to change a stage gain using the stage_modifications element:

You should obtain the following (with 2 lines changed from the previous version):

channels:
    default:
        datalogger:
            base: {$ref: "datalogger_bases/EXAMPLE.datalogger_base.yaml"}
        sensor:
            base: {$ref: "sensor_bases/EXAMPLE_BBSeismometer.sensor_base.yaml"}
    "1":
        orientation: {code: "Z", azimuth.deg: {value: 0}, dip.deg: {value: -90}}
    "2":
        orientation: {code: "1", azimuth.deg: {value: 0, uncertainty: 180},
                      dip.deg: {value: -90}}
        sensor: {configuration: "SN1-399, differential"}
    "3":
        orientation: {code: "2", azimuth.deg: {value: 90, uncertainty: 180},
                      dip.deg: {value: -90}}
        sensor: {stage_modifications: {"1": {gain: {value: 20}}}}
    "4":
        orientation: {code: "H", azimuth.deg: {value: 0}, dip.deg: {value: -90}}
        replace_sensor:
            base: {$ref: "sensor_bases/EXAMPLE_DPG.sensor_base.yaml"}

Each channel now has a different gain:

../_images/obsinfo_plot_modified_instrumentation_base.png