From 9e1fc95748709cd408aee06be52c4e2a535784d1 Mon Sep 17 00:00:00 2001
From: bgeels <bgeels@usgs.gov>
Date: Tue, 26 Mar 2024 14:35:25 -0600
Subject: [PATCH] Overhaul geomagio/Metadata.py

---
 geomagio/Metadata.py | 1670 ++++++++----------------------------------
 1 file changed, 320 insertions(+), 1350 deletions(-)

diff --git a/geomagio/Metadata.py b/geomagio/Metadata.py
index ebdb7b8c..a4ad6e64 100644
--- a/geomagio/Metadata.py
+++ b/geomagio/Metadata.py
@@ -1,1363 +1,333 @@
-"""Simulate metadata service until it is implemented.
-"""
-
 from obspy import UTCDateTime
 
+from geomagio.metadata import Metadata, MetadataFactory, MetadataCategory
+
+
+class InstrumentCalibrations:
+    """
+    A class used to get calibrations from instrument metadata.
+
+    ...
+
+    Attributes
+    ----------
+    metadata_list : list
+        a list of metadata objects to be processed
+    previous_calibration : dict
+        a dictionary to store the previous calibration values for each axis and key
+    station : str
+        the station code, checked for consistency across all metadata objects
+    location : str
+        the location code, checked for consistency across all metadata objects
+    network : str
+        the network code, checked for consistency across all metadata objects
+
+    Methods
+    -------
+    get_calibrations():
+        Main method to gather applicable calibrations from the metadata list.
+    create_overlap_interval(current_metadata):
+        Creates an overlap interval from the current metadata.
+    update_overlap_interval(overlap_interval, current_metadata):
+        Updates the overlap interval with the current metadata.
+    update_overlap_interval_with_same_starttime(i, sorted_metadata_list, overlap_interval):
+        Updates the overlap interval with metadata that have the same starttime.
+    set_endtime(i, sorted_metadata_list, overlap_interval, current_metadata):
+        Sets the endtime for the overlap interval.
+    convert_to_calibration(overlap_metadata):
+        Converts overlapping metadata information to an applicable calibration.
+    get_channels(overlap_metadata):
+        Gets the channels for the applicable calibration.
+    """
+
+    def __init__(self, metadata_list):
+        """
+        Constructs necessary attributes for the InstrumentCalibrations object and verify consistency of metadata_list.
+
+        Parameters
+        ----------
+            metadata_list : list
+                a list of metadata objects to be processed
+        """
+        self.metadata_list = metadata_list
+        self.previous_calibration = {
+            f"{axis}_{key}": None
+            for axis in ["u", "v", "w"]
+            for key in ["constant", "bin", "offset"]
+        }
+        self.previous_calibration.update(
+            {"resistance": None, "temperature_scale": None, "type": None}
+        )
+
+        # Check for consistency in "station", "location", and "network" codes
+        stations = {metadata.station for metadata in metadata_list}
+        locations = {metadata.location for metadata in metadata_list}
+        networks = {metadata.network for metadata in metadata_list}
+
+        if len(stations) > 1 or len(locations) > 1 or len(networks) > 1:
+            raise ValueError(
+                "Inconsistent 'station', 'location', or 'network' codes in metadata_list"
+            )
+        else:
+            self.station = stations.pop()
+            self.location = locations.pop()
+            self.network = networks.pop()
+
+    def get_calibrations(self):
+        """
+        Main method to compile applicable calibrations from the metadata list.
+
+        Parameters
+                ----------
+                query_starttime : UTCDateTime
+                    the query starttime
+
+        Returns
+        -------
+        list
+            a list of dictionaries, each representing an applicable calibration
+        """
+        sorted_metadata_list = sorted(
+            self.metadata_list,
+            key=lambda x: x.starttime if x.starttime is not None else UTCDateTime(0),
+        )
+        i = 0
+        calibrations = []
+        while i < len(sorted_metadata_list):
+            current_metadata = sorted_metadata_list[i]
+            overlap_interval = self.create_overlap_interval(current_metadata)
+            i = self.update_overlap_interval_with_same_starttime(
+                i, sorted_metadata_list, overlap_interval
+            )
+            self.set_endtime(
+                i, sorted_metadata_list, overlap_interval, current_metadata
+            )
+            calibration = self.convert_to_calibration(overlap_interval)
+            # if (
+            #     calibration["end_time"] >= query_starttime
+            #     or calibration["end_time"] == None
+            # ):
+            calibrations.append(calibration)
+            i += 1
+        return calibrations
+
+    def create_overlap_interval(self, current_metadata):
+        """
+        Creates an overlap interval from the current metadata.
+
+        Parameters
+        ----------
+        current_metadata : Metadata
+            the current metadata object
 
-def get_instrument(observatory, start_time=None, end_time=None, metadata=None):
+        Returns
+        -------
+        dict
+            a dictionary representing an overlap interval
+        """
+        overlap_interval = {"starttime": current_metadata.starttime}
+        self.update_overlap_interval(overlap_interval, current_metadata)
+        return overlap_interval
+
+    def update_overlap_interval(self, overlap_interval, current_metadata):
+        """
+        Updates the overlap interval with the current metadata.
+
+        Parameters
+        ----------
+        overlap_interval : dict
+            the overlap interval to be updated
+        current_metadata : Metadata
+            the current metadata object
+        """
+        for axis in ["u", "v", "w"]:
+            for key in ["constant", "bin", "offset"]:
+                current_key = f"{axis}_{key}"
+                if current_key in current_metadata.metadata:
+                    overlap_interval[current_key] = current_metadata.metadata[
+                        current_key
+                    ]
+                    self.previous_calibration[current_key] = current_metadata.metadata[
+                        current_key
+                    ]
+                elif current_key in self.previous_calibration:
+                    overlap_interval[current_key] = self.previous_calibration[
+                        current_key
+                    ]
+        for key in ["resistance", "temperature_scale", "type"]:
+            if key in current_metadata.metadata:
+                overlap_interval[key] = current_metadata.metadata[key]
+                self.previous_calibration[key] = current_metadata.metadata[key]
+            elif key in self.previous_calibration:
+                overlap_interval[key] = self.previous_calibration[key]
+
+    def update_overlap_interval_with_same_starttime(
+        self, i, sorted_metadata_list, overlap_interval
+    ):
+        """
+        Updates the overlap interval with metadata that have the same starttime.
+
+        Parameters
+        ----------
+        i : int
+            the current index in the sorted metadata list
+        sorted_metadata_list : list
+            the sorted list of metadata objects
+        overlap_interval : dict
+            the overlap interval to be updated
+
+        Returns
+        -------
+        int
+            the updated index in the sorted metadata list
+        """
+        while (
+            i + 1 < len(sorted_metadata_list)
+            and sorted_metadata_list[i + 1].starttime
+            == sorted_metadata_list[i].starttime
+        ):
+            i += 1
+            next_metadata = sorted_metadata_list[i]
+            self.update_overlap_interval(overlap_interval, next_metadata)
+        return i
+
+    def set_endtime(self, i, sorted_metadata_list, overlap_interval, current_metadata):
+        """
+        Sets the endtime for the overlap interval.
+
+        Parameters
+        ----------
+        i : int
+            the current index in the sorted metadata list
+        sorted_metadata_list : list
+            the sorted list of metadata objects
+        overlap_interval : dict
+            the overlap interval to be updated
+        current_metadata : Metadata
+            the current metadata object
+        """
+        if (
+            i + 1 < len(sorted_metadata_list)
+            and sorted_metadata_list[i + 1].starttime != current_metadata.starttime
+        ):
+            overlap_interval["endtime"] = sorted_metadata_list[i + 1].starttime
+        else:
+            overlap_interval["endtime"] = current_metadata.endtime
+
+    def convert_to_calibration(self, overlap_metadata):
+        """
+        Converts an overlap_metadata object to an applicable calibration.
+
+        Parameters
+        ----------
+        overlap_metadata : dict
+            the metadata overlap data to be converted
+
+        Returns
+        -------
+        dict
+            a dictionary representing an applicable calibration
+        """
+        calibration = {
+            "network": self.network,
+            "station": self.station,
+            "location": self.location,
+            "start_time": overlap_metadata["starttime"],
+            "end_time": overlap_metadata["endtime"],
+            "instrument": {
+                "type": overlap_metadata["type"],
+                "channels": self.get_channels(overlap_metadata),
+            },
+        }
+        return calibration
+
+    def get_channels(self, overlap_metadata):
+        """
+        Gets the channels for the applicable calibration.
+
+        Parameters
+        ----------
+        overlap_metadata : dict
+            the metadata overlap data from which to get the channels
+
+        Returns
+        -------
+        dict
+            a dictionary representing the channels for the applicable calibration
+        """
+        channels = {}
+        for axis in ["U", "V", "W"]:
+            if (
+                f"{axis.lower()}_bin" in overlap_metadata
+                and overlap_metadata[f"{axis.lower()}_bin"] is not None
+            ):
+                channels[axis] = [
+                    {
+                        "channel": f"{axis}_Volt",
+                        "offset": (
+                            overlap_metadata[f"{axis.lower()}_offset"]
+                            if overlap_metadata[f"{axis.lower()}_offset"] is not None
+                            else 0
+                        ),
+                        "scale": overlap_metadata[f"{axis.lower()}_constant"],
+                    },
+                    {
+                        "channel": f"{axis}_Bin",
+                        "offset": 0,
+                        "scale": overlap_metadata[f"{axis.lower()}_bin"],
+                    },
+                ]
+            elif (
+                "resistance" in overlap_metadata
+                and overlap_metadata["resistance"] is not None
+            ):
+                channels[axis] = [
+                    {
+                        "channel": f"{axis}_Volt",
+                        "offset": (
+                            overlap_metadata[f"{axis.lower()}_offset"]
+                            if overlap_metadata[f"{axis.lower()}_offset"] is not None
+                            else 0
+                        ),
+                        "scale": overlap_metadata[f"{axis.lower()}_constant"]
+                        / overlap_metadata["resistance"],
+                    }
+                ]
+        return channels
+
+
+def get_instrument(
+    observatory, start_time=None, end_time=None, calibrations=None, metadata_url=None
+):
     """Get instrument metadata
 
     Args:
       observatory: observatory code
       start_time: start time to match, or None to match any.
       end_time: end time to match, or None to match any.
-      metadata: use custom list, defaults to _INSTRUMENT_METADATA
+      calibrations: use custom list, defaults to pulling and converting metadata
     Returns:
-      list of matching metadata
+      list of applicable instrument calibrations
     """
-    metadata = metadata or _INSTRUMENT_METADATA
-    return [
-        m
-        for m in metadata
-        if m["station"] == observatory
-        and (end_time is None or m["start_time"] is None or m["start_time"] < end_time)
-        and (start_time is None or m["end_time"] is None or m["end_time"] > start_time)
-    ]
 
+    if not calibrations:
+        factory = MetadataFactory(
+            url=metadata_url or "https://staging-geomag.cr.usgs.gov/ws/secure/metadata",
+        )
+        query = Metadata(
+            category=MetadataCategory.INSTRUMENT,
+            starttime=start_time,
+            endtime=end_time,
+            station=observatory,
+        )
+        metadata = factory.get_metadata(query=query)
+        instrumentCalibrations = InstrumentCalibrations(metadata)
+        calibrations = instrumentCalibrations.get_calibrations()
 
-"""
-To make this list easier to maintain:
- - List NT network stations first, then other networks in alphabetical order
- - Within networks, alphabetize by station, then start_time.
- - When updating a metadata object, copy/paste the current one to the end of the list and update the endtime appropriately.
-    - Then update the existing object with the new information.
-"""
-_INSTRUMENT_METADATA = [
-    {
-        "network": "NT",
-        "station": "BDT",
-        "start_time": None,
-        "end_time": UTCDateTime("2023-09-22T00:00:00.000Z"),
-        "instrument": {
-            "type": "FGE",
-            "channels": {
-                # each channel maps to a list of components to calculate nT
-                # TODO: calculate these lists based on "FGE" type
-                "U": [{"channel": "U_Volt", "offset": 20613, "scale": 966.7624}],
-                "V": [{"channel": "V_Volt", "offset": 0, "scale": 944.1253}],
-                "W": [{"channel": "W_Volt", "offset": 47450, "scale": 975.5875}],
-            },
-            "electronics": {
-                "serial": "E574",
-                # these scale values are calculated manually.
-                "x-scale": 966.7624,  # nT/V
-                "y-scale": 944.1253,  # nT/V
-                "z-scale": 975.5875,  # nT/V
-                "temperature-scale": 0.01,  # V/K
-            },
-            "sensor": {
-                "serial": "S0449",
-                # these constants combine with instrument setting for offset
-                "x-constant": 37027,  # nT/mA
-                "y-constant": 36160,  # nT/mA
-                "z-constant": 37365,  # nT/mA
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "BDT",
-        "start_time": UTCDateTime("2023-09-22T00:00:00.000Z"),
-        "end_time": UTCDateTime("2024-03-07T00:00:00.000Z"),
-        "instrument": {
-            "type": "FGE",
-            "channels": {
-                # each channel maps to a list of components to calculate nT
-                # TODO: calculate these lists based on "FGE" type
-                "U": [{"channel": "U_Volt", "offset": 20729.5, "scale": 966.7624}],
-                "V": [{"channel": "V_Volt", "offset": 0, "scale": 944.1253}],
-                "W": [{"channel": "W_Volt", "offset": 47042.5, "scale": 975.5875}],
-            },
-            "electronics": {
-                "serial": "E574",
-                # these scale values are calculated manually.
-                "x-scale": 966.7624,  # nT/V
-                "y-scale": 944.1253,  # nT/V
-                "z-scale": 975.5875,  # nT/V
-                "temperature-scale": 0.01,  # V/K
-            },
-            "sensor": {
-                "serial": "S0449",
-                # these constants combine with instrument setting for offset
-                "x-constant": 37027,  # nT/mA
-                "y-constant": 36160,  # nT/mA
-                "z-constant": 37365,  # nT/mA
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "BDT",
-        "start_time": UTCDateTime("2024-03-07T00:00:00.000Z"),
-        "end_time": None,
-        "instrument": {
-            "type": "FGE",
-            "channels": {
-                # each channel maps to a list of components to calculate nT
-                # TODO: calculate these lists based on "FGE" type
-                "U": [{"channel": "U_Volt", "offset": 20724.67, "scale": 966.7624}],
-                "V": [{"channel": "V_Volt", "offset": -13.59, "scale": 944.1253}],
-                "W": [{"channel": "W_Volt", "offset": 47048.96, "scale": 975.5875}],
-            },
-            "electronics": {
-                "serial": "E574",
-                # these scale values are calculated manually.
-                "x-scale": 966.7624,  # nT/V
-                "y-scale": 944.1253,  # nT/V
-                "z-scale": 975.5875,  # nT/V
-                "temperature-scale": 0.01,  # V/K
-            },
-            "sensor": {
-                "serial": "S0449",
-                # these constants combine with instrument setting for offset
-                "x-constant": 37027,  # nT/mA
-                "y-constant": 36160,  # nT/mA
-                "z-constant": 37365,  # nT/mA
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "BOU",
-        "start_time": None,
-        "end_time": None,
-        "instrument": {
-            "type": "Narod",
-            "channels": {
-                "U": [
-                    {"channel": "U_Volt", "offset": 0, "scale": 100},
-                    {"channel": "U_Bin", "offset": 0, "scale": 500},
-                ],
-                "V": [
-                    {"channel": "V_Volt", "offset": 0, "scale": 100},
-                    {"channel": "V_Bin", "offset": 0, "scale": 500},
-                ],
-                "W": [
-                    {"channel": "W_Volt", "offset": 0, "scale": 100},
-                    {"channel": "W_Bin", "offset": 0, "scale": 500},
-                ],
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "BXX",
-        "start_time": None,
-        "end_time": None,
-        "instrument": {
-            "type": "Narod",
-            "channels": {
-                "U": [
-                    {"channel": "U_Volt", "offset": 0, "scale": 100},
-                    {"channel": "U_Bin", "offset": 0, "scale": 500},
-                ],
-                "V": [
-                    {"channel": "V_Volt", "offset": 0, "scale": 100},
-                    {"channel": "V_Bin", "offset": 0, "scale": 500},
-                ],
-                "W": [
-                    {"channel": "W_Volt", "offset": 0, "scale": 100},
-                    {"channel": "W_Bin", "offset": 0, "scale": 500},
-                ],
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "BRT",
-        "start_time": None,
-        "end_time": None,
-        "instrument": {
-            "type": "Narod",
-            "channels": {
-                "U": [
-                    {"channel": "U_Volt", "offset": 0, "scale": 100},
-                    {"channel": "U_Bin", "offset": 0, "scale": 506},
-                ],
-                "V": [
-                    {"channel": "V_Volt", "offset": 0, "scale": 100},
-                    {"channel": "V_Bin", "offset": 0, "scale": 505.6},
-                ],
-                "W": [
-                    {"channel": "W_Volt", "offset": 0, "scale": 100},
-                    {"channel": "W_Bin", "offset": 0, "scale": 506},
-                ],
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "BRW",
-        "start_time": UTCDateTime("2023-10-24T22:45:00.000Z"),
-        "end_time": None,
-        "instrument": {
-            "type": "FGE",
-            "channels": {
-                # each channel maps to a list of components to calculate nT
-                # TODO: calculate these lists based on "FGE" type
-                "U": [{"channel": "U_Volt", "offset": 9214, "scale": 5797.3}],
-                "V": [{"channel": "V_Volt", "offset": 0, "scale": 5777.6}],
-                "W": [{"channel": "W_Volt", "offset": 37172, "scale": 5895.6}],
-            },
-            "electronics": {
-                "serial": "????",
-                # these scale values are calculated manually.
-                "x-scale": 5797.3,  # nT/V
-                "y-scale": 5777.6,  # nT/V
-                "z-scale": 5895.6,  # nT/V
-                "temperature-scale": 0.01,  # V/K
-            },
-            "sensor": {
-                "serial": "????",
-                # these constants combine with instrument setting for offset
-                "x-constant": None,  # nT/mA
-                "y-constant": None,  # nT/mA
-                "z-constant": None,  # nT/mA
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "BSL",
-        "start_time": None,
-        "end_time": None,
-        "instrument": {
-            "type": "Narod",
-            "channels": {
-                "U": [
-                    {"channel": "U_Volt", "offset": 0, "scale": 100},
-                    {"channel": "U_Bin", "offset": 0, "scale": 500},
-                ],
-                "V": [
-                    {"channel": "V_Volt", "offset": 0, "scale": 100},
-                    {"channel": "V_Bin", "offset": 0, "scale": 500},
-                ],
-                "W": [
-                    {"channel": "W_Volt", "offset": 0, "scale": 100},
-                    {"channel": "W_Bin", "offset": 0, "scale": 500},
-                ],
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "CMO",
-        "start_time": UTCDateTime("2023-10-27T16:20:00.000Z"),
-        "end_time": None,
-        "instrument": {
-            "type": "FGE",
-            "channels": {
-                # each channel maps to a list of components to calculate nT
-                # TODO: calculate these lists based on "FGE" type
-                "U": [{"channel": "U_Volt", "offset": 12620, "scale": 967.7}],
-                "V": [{"channel": "V_Volt", "offset": 0, "scale": 969.7}],
-                "W": [{"channel": "W_Volt", "offset": 54907, "scale": 973.4}],
-            },
-            "electronics": {
-                "serial": "E0568",
-                # these scale values are used to convert voltage
-                "x-scale": 967.7,  # nT/V
-                "y-scale": 969.7,  # nT/V
-                "z-scale": 973.4,  # nT/V
-                "temperature-scale": 0.01,  # V/K
-            },
-            "sensor": {
-                "serial": "S0443",
-                # these constants combine with instrument setting for offset
-                "x-constant": 37062,  # nT/mA
-                "y-constant": 37141,  # nT/mA
-                "z-constant": 37281,  # nT/mA
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "CMT",
-        "start_time": UTCDateTime("2023-10-26T21:00:00.000Z"),
-        "end_time": None,
-        "instrument": {
-            "type": "Narod",
-            "channels": {
-                "U": [
-                    {"channel": "U_Volt", "offset": 0, "scale": 99.4},
-                    {"channel": "U_Bin", "offset": 0, "scale": 502.5},
-                ],
-                "V": [
-                    {"channel": "V_Volt", "offset": 0, "scale": 101.5},
-                    {"channel": "V_Bin", "offset": 0, "scale": 512.5},
-                ],
-                "W": [
-                    {"channel": "W_Volt", "offset": 0, "scale": 100.98},
-                    {"channel": "W_Bin", "offset": 0, "scale": 509.15},
-                ],
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "DED",
-        "start_time": None,
-        "end_time": None,
-        "instrument": {
-            "type": "Narod",
-            "channels": {
-                "U": [
-                    {"channel": "U_Volt", "offset": 0, "scale": 100},
-                    {"channel": "U_Bin", "offset": 0, "scale": 508.20},
-                ],
-                "V": [
-                    {"channel": "V_Volt", "offset": 0, "scale": 100},
-                    {"channel": "V_Bin", "offset": 0, "scale": 508.40},
-                ],
-                "W": [
-                    {"channel": "W_Volt", "offset": 0, "scale": 100},
-                    {"channel": "W_Bin", "offset": 0, "scale": 508.03},
-                ],
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "FDT",
-        "start_time": None,
-        "end_time": None,
-        "instrument": {
-            "type": "Narod",
-            "channels": {
-                "U": [
-                    {"channel": "U_Volt", "offset": 0, "scale": 100},
-                    {"channel": "U_Bin", "offset": 0, "scale": 500},
-                ],
-                "V": [
-                    {"channel": "V_Volt", "offset": 0, "scale": 100},
-                    {"channel": "V_Bin", "offset": 0, "scale": 500},
-                ],
-                "W": [
-                    {"channel": "W_Volt", "offset": 0, "scale": 100},
-                    {"channel": "W_Bin", "offset": 0, "scale": 500},
-                ],
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "FRD",
-        "start_time": None,
-        "end_time": UTCDateTime("2023-08-23T00:00:00.000Z"),
-        "instrument": {
-            "type": "Narod",
-            "channels": {
-                "U": [
-                    {"channel": "U_Volt", "offset": 0, "scale": 100},
-                    {"channel": "U_Bin", "offset": 0, "scale": 500},
-                ],
-                "V": [
-                    {"channel": "V_Volt", "offset": 0, "scale": 100},
-                    {"channel": "V_Bin", "offset": 0, "scale": 500},
-                ],
-                "W": [
-                    {"channel": "W_Volt", "offset": 0, "scale": 100},
-                    {"channel": "W_Bin", "offset": 0, "scale": 500},
-                ],
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "FRD",
-        "start_time": UTCDateTime("2023-08-23T00:00:00.000Z"),
-        "end_time": UTCDateTime("2023-08-30T00:00:00.000Z"),
-        "instrument": {
-            "type": "FGE",
-            "channels": {
-                # each channel maps to a list of components to calculate nT
-                # TODO: calculate these lists based on "FGE" type
-                "U": [{"channel": "U_Volt", "offset": 21639, "scale": 978.4}],
-                "V": [{"channel": "V_Volt", "offset": 0, "scale": 971.0}],
-                "W": [{"channel": "W_Volt", "offset": 45573, "scale": 966.7}],
-            },
-            "electronics": {
-                "serial": "E570",
-                # these scale values are used to convert voltage
-                "x-scale": 978.4,  # nT/V
-                "y-scale": 971.0,  # nT/V
-                "z-scale": 966.7,  # nT/V
-                "temperature-scale": 0.01,  # V/K
-            },
-            "sensor": {
-                "serial": "S0445",
-                # these constants combine with instrument setting for offset
-                "x-constant": 37474,  # nT/mA
-                "y-constant": 37191,  # nT/mA
-                "z-constant": 37025,  # nT/mA
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "FRD",
-        "start_time": UTCDateTime("2023-08-30T00:00:00.000Z"),
-        "end_time": None,
-        "instrument": {
-            "type": "FGE",
-            "channels": {
-                # each channel maps to a list of components to calculate nT
-                # TODO: calculate these lists based on "FGE" type
-                "U": [{"channel": "U_Volt", "offset": 21639, "scale": 978.4}],
-                "V": [{"channel": "V_Volt", "offset": 0, "scale": 971.0}],
-                "W": [{"channel": "W_Volt", "offset": 45573, "scale": 966.7}],
-            },
-            "electronics": {
-                "serial": "E570",
-                # these scale values are used to convert voltage
-                "x-scale": 978.4,  # nT/V
-                "y-scale": 971.0,  # nT/V
-                "z-scale": 966.7,  # nT/V
-                "temperature-scale": 0.01,  # V/K
-            },
-            "sensor": {
-                "serial": "S0445",
-                # these constants combine with instrument setting for offset
-                "x-constant": 37474,  # nT/mA
-                "y-constant": 37191,  # nT/mA
-                "z-constant": 37025,  # nT/mA
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "FRN",
-        "start_time": None,
-        "end_time": None,
-        "instrument": {
-            "type": "Narod",
-            "channels": {
-                "U": [
-                    {"channel": "U_Volt", "offset": 0, "scale": 98.48},
-                    {"channel": "U_Bin", "offset": 0, "scale": 497.50},
-                ],
-                "V": [
-                    {"channel": "V_Volt", "offset": 0, "scale": 100.60},
-                    {"channel": "V_Bin", "offset": 0, "scale": 506},
-                ],
-                "W": [
-                    {"channel": "W_Volt", "offset": 0, "scale": 99},
-                    {"channel": "W_Bin", "offset": 0, "scale": 501},
-                ],
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "GUA",
-        "start_time": None,
-        "end_time": UTCDateTime("2024-02-26T03:00:00.000Z"),
-        "instrument": {
-            "type": "Narod",
-            "channels": {
-                "U": [
-                    {"channel": "U_Volt", "offset": 0, "scale": 100},
-                    {"channel": "U_Bin", "offset": 0, "scale": 500},
-                ],
-                "V": [
-                    {"channel": "V_Volt", "offset": 0, "scale": 100},
-                    {"channel": "V_Bin", "offset": 0, "scale": 500},
-                ],
-                "W": [
-                    {"channel": "W_Volt", "offset": 0, "scale": 100},
-                    {"channel": "W_Bin", "offset": 0, "scale": 500},
-                ],
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "GUA",
-        "start_time": UTCDateTime("2024-02-26T03:00:00.000Z"),
-        "end_time": UTCDateTime("2024-03-07T00:00:00.000Z"),
-        "instrument": {
-            "type": "FGE",
-            "channels": {
-                # each channel maps to a list of components to calculate nT
-                # TODO: calculate these lists based on "FGE" type
-                "U": [{"channel": "U_Volt", "offset": 35975, "scale": 314.28}],
-                "V": [{"channel": "V_Volt", "offset": 0, "scale": 310.48}],
-                "W": [{"channel": "W_Volt", "offset": 7750, "scale": 317.5}],
-            },
-            "electronics": {
-                "serial": "E0542",
-                # these scale values are used to convert voltage
-                "x-scale": 314.28,  # V/nT
-                "y-scale": 310.48,  # V/nT
-                "z-scale": 317.5,  # V/nT
-                "temperature-scale": 0.01,  # V/K
-            },
-            "sensor": {
-                "serial": "S0420",
-                # these constants combine with instrument setting for offset
-                "x-constant": 37085,  # nT/mA
-                "y-constant": 36637,  # nT/mA
-                "z-constant": 37465,  # nT/mA
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "GUA",
-        "start_time": UTCDateTime("2024-03-07T00:00:00.000Z"),
-        "end_time": None,
-        "instrument": {
-            "type": "FGE",
-            "channels": {
-                # each channel maps to a list of components to calculate nT
-                # TODO: calculate these lists based on "FGE" type
-                "U": [{"channel": "U_Volt", "offset": 35976, "scale": 314.28}],
-                "V": [{"channel": "V_Volt", "offset": 0, "scale": 310.48}],
-                "W": [{"channel": "W_Volt", "offset": 7745, "scale": 317.5}],
-            },
-            "electronics": {
-                "serial": "E0542",
-                # these scale values are used to convert voltage
-                "x-scale": 314.28,  # V/nT
-                "y-scale": 310.48,  # V/nT
-                "z-scale": 317.5,  # V/nT
-                "temperature-scale": 0.01,  # V/K
-            },
-            "sensor": {
-                "serial": "S0420",
-                # these constants combine with instrument setting for offset
-                "x-constant": 37085,  # nT/mA
-                "y-constant": 36637,  # nT/mA
-                "z-constant": 37465,  # nT/mA
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "GUT",
-        "start_time": None,
-        "end_time": UTCDateTime("2023-09-22T00:00:00.000Z"),
-        "instrument": {
-            "type": "FGE",
-            "channels": {
-                # each channel maps to a list of components to calculate nT
-                # TODO: calculate these lists based on "FGE" type
-                "U": [{"channel": "U_Volt", "offset": 35989, "scale": 314.28}],
-                "V": [{"channel": "V_Volt", "offset": 0, "scale": 310.48}],
-                "W": [{"channel": "W_Volt", "offset": 7654, "scale": 317.5}],
-            },
-            "electronics": {
-                "serial": "E0542",
-                # these scale values are used to convert voltage
-                "x-scale": 314.28,  # V/nT
-                "y-scale": 310.48,  # V/nT
-                "z-scale": 317.5,  # V/nT
-                "temperature-scale": 0.01,  # V/K
-            },
-            "sensor": {
-                "serial": "S0420",
-                # these constants combine with instrument setting for offset
-                "x-constant": 37085,  # nT/mA
-                "y-constant": 36637,  # nT/mA
-                "z-constant": 37465,  # nT/mA
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "GUT",
-        "start_time": UTCDateTime("2023-09-22T00:00:00.000Z"),
-        "end_time": UTCDateTime("2024-02-26T03:00:00.000Z"),
-        "instrument": {
-            "type": "FGE",
-            "channels": {
-                # each channel maps to a list of components to calculate nT
-                # TODO: calculate these lists based on "FGE" type
-                "U": [{"channel": "U_Volt", "offset": 35975, "scale": 314.28}],
-                "V": [{"channel": "V_Volt", "offset": 0, "scale": 310.48}],
-                "W": [{"channel": "W_Volt", "offset": 7750, "scale": 317.5}],
-            },
-            "electronics": {
-                "serial": "E0542",
-                # these scale values are used to convert voltage
-                "x-scale": 314.28,  # V/nT
-                "y-scale": 310.48,  # V/nT
-                "z-scale": 317.5,  # V/nT
-                "temperature-scale": 0.01,  # V/K
-            },
-            "sensor": {
-                "serial": "S0420",
-                # these constants combine with instrument setting for offset
-                "x-constant": 37085,  # nT/mA
-                "y-constant": 36637,  # nT/mA
-                "z-constant": 37465,  # nT/mA
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "GUT",
-        "start_time": UTCDateTime("2024-02-26T03:00:00.000Z"),
-        "end_time": None,
-        "instrument": {
-            "type": "Narod",
-            "channels": {
-                "U": [
-                    {"channel": "U_Volt", "offset": 0, "scale": 100},
-                    {"channel": "U_Bin", "offset": 0, "scale": 500},
-                ],
-                "V": [
-                    {"channel": "V_Volt", "offset": 0, "scale": 100},
-                    {"channel": "V_Bin", "offset": 0, "scale": 500},
-                ],
-                "W": [
-                    {"channel": "W_Volt", "offset": 0, "scale": 100},
-                    {"channel": "W_Bin", "offset": 0, "scale": 500},
-                ],
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "HON",
-        "start_time": None,
-        "end_time": UTCDateTime("2024-02-20T20:30:00.000Z"),
-        "instrument": {
-            "type": "Narod",
-            "channels": {
-                "U": [
-                    {"channel": "U_Volt", "offset": 0, "scale": 100},
-                    {"channel": "U_Bin", "offset": 0, "scale": 500},
-                ],
-                "V": [
-                    {"channel": "V_Volt", "offset": 0, "scale": 100},
-                    {"channel": "V_Bin", "offset": 0, "scale": 500},
-                ],
-                "W": [
-                    {"channel": "W_Volt", "offset": 0, "scale": 100},
-                    {"channel": "W_Bin", "offset": 0, "scale": 500},
-                ],
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "HON",
-        "start_time": UTCDateTime("2024-02-20T20:30:00.000Z"),
-        "end_time": UTCDateTime("2024-03-07T00:00:00.000Z"),
-        "instrument": {
-            "type": "FGE",
-            "channels": {
-                # each channel maps to a list of components to calculate nT
-                # TODO: calculate these lists based on "FGE" type
-                "U": [{"channel": "U_Volt", "offset": 27126, "scale": 315.4}],
-                "V": [{"channel": "V_Volt", "offset": 0, "scale": 315.0}],
-                "W": [{"channel": "W_Volt", "offset": 21107.5, "scale": 311.7}],
-            },
-            # this info should get updated when available
-            "electronics": {
-                "serial": "E558",
-                # these scale values are used to convert voltage
-                # these are calculated using Ohm's law, given scaling resistor value, and given nT/mA values.
-                "x-scale": 315.4,  # nT/V
-                "y-scale": 315.0,  # nT/V
-                "z-scale": 311.7,  # nT/V
-                "temperature-scale": 0.01,  # V/K
-            },
-            "sensor": {
-                "serial": "S0428",
-                # these constants combine with instrument setting for offset
-                "x-constant": 37220,  # nT/mA
-                "y-constant": 37175,  # nT/mA
-                "z-constant": 36775,  # nT/mA
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "HON",
-        "start_time": UTCDateTime("2024-03-07T00:00:00.000Z"),
-        "end_time": None,
-        "instrument": {
-            "type": "FGE",
-            "channels": {
-                # each channel maps to a list of components to calculate nT
-                # TODO: calculate these lists based on "FGE" type
-                "U": [{"channel": "U_Volt", "offset": 27126, "scale": 315.4}],
-                "V": [{"channel": "V_Volt", "offset": 0, "scale": 315.0}],
-                "W": [{"channel": "W_Volt", "offset": 21207.5, "scale": 311.7}],
-            },
-            # this info should get updated when available
-            "electronics": {
-                "serial": "E558",
-                # these scale values are used to convert voltage
-                # these are calculated using Ohm's law, given scaling resistor value, and given nT/mA values.
-                "x-scale": 315.4,  # nT/V
-                "y-scale": 315.0,  # nT/V
-                "z-scale": 311.7,  # nT/V
-                "temperature-scale": 0.01,  # V/K
-            },
-            "sensor": {
-                "serial": "S0428",
-                # these constants combine with instrument setting for offset
-                "x-constant": 37220,  # nT/mA
-                "y-constant": 37175,  # nT/mA
-                "z-constant": 36775,  # nT/mA
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "HOT",
-        "start_time": None,
-        "end_time": UTCDateTime("2022-07-14T16:07:30.000Z"),
-        "instrument": {
-            "type": "FGE",
-            "channels": {
-                # each channel maps to a list of components to calculate nT
-                # TODO: calculate these lists based on "FGE" type
-                "U": [{"channel": "U_Volt", "offset": 0, "scale": 971.8}],
-                "V": [{"channel": "V_Volt", "offset": 0, "scale": 970.6}],
-                "W": [{"channel": "W_Volt", "offset": 0, "scale": 960.2}],
-            },
-            # this info should get updated when available
-            "electronics": {
-                "serial": "E558",
-                # these scale values are used to convert voltage
-                # these are calculated using Ohm's law, given scaling resistor value, and given nT/mA values.
-                "x-scale": 971.8,  # nT/V
-                "y-scale": 970.6,  # nT/V
-                "z-scale": 960.2,  # nT/V
-                "temperature-scale": 0.01,  # V/K
-            },
-            "sensor": {
-                "serial": "S0428",
-                # these constants combine with instrument setting for offset
-                "x-constant": 37220,  # nT/mA
-                "y-constant": 37175,  # nT/mA
-                "z-constant": 36775,  # nT/mA
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "HOT",
-        "start_time": UTCDateTime("2022-07-14T16:07:30.000Z"),
-        "end_time": UTCDateTime("2023-09-22T00:00:00.000Z"),
-        "instrument": {
-            "type": "FGE",
-            "channels": {
-                # each channel maps to a list of components to calculate nT
-                # TODO: calculate these lists based on "FGE" type
-                "U": [{"channel": "U_Volt", "offset": 27123, "scale": 315.4}],
-                "V": [{"channel": "V_Volt", "offset": 0, "scale": 315.0}],
-                "W": [{"channel": "W_Volt", "offset": 21158, "scale": 311.7}],
-            },
-            # this info should get updated when available
-            "electronics": {
-                "serial": "E558",
-                # these scale values are used to convert voltage
-                # these are calculated using Ohm's law, given scaling resistor value, and given nT/mA values.
-                "x-scale": 315.4,  # nT/V
-                "y-scale": 315.0,  # nT/V
-                "z-scale": 311.7,  # nT/V
-                "temperature-scale": 0.01,  # V/K
-            },
-            "sensor": {
-                "serial": "S0428",
-                # these constants combine with instrument setting for offset
-                "x-constant": 37220,  # nT/mA
-                "y-constant": 37175,  # nT/mA
-                "z-constant": 36775,  # nT/mA
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "HOT",
-        "start_time": UTCDateTime("2023-09-22T00:00:00.000Z"),
-        "end_time": UTCDateTime("2024-02-20T20:30:00.000Z"),
-        "instrument": {
-            "type": "FGE",
-            "channels": {
-                # each channel maps to a list of components to calculate nT
-                # TODO: calculate these lists based on "FGE" type
-                "U": [{"channel": "U_Volt", "offset": 27126, "scale": 315.4}],
-                "V": [{"channel": "V_Volt", "offset": 0, "scale": 315.0}],
-                "W": [{"channel": "W_Volt", "offset": 21107.5, "scale": 311.7}],
-            },
-            # this info should get updated when available
-            "electronics": {
-                "serial": "E558",
-                # these scale values are used to convert voltage
-                # these are calculated using Ohm's law, given scaling resistor value, and given nT/mA values.
-                "x-scale": 315.4,  # nT/V
-                "y-scale": 315.0,  # nT/V
-                "z-scale": 311.7,  # nT/V
-                "temperature-scale": 0.01,  # V/K
-            },
-            "sensor": {
-                "serial": "S0428",
-                # these constants combine with instrument setting for offset
-                "x-constant": 37220,  # nT/mA
-                "y-constant": 37175,  # nT/mA
-                "z-constant": 36775,  # nT/mA
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "HOT",
-        "start_time": UTCDateTime("2024-02-20T20:30:00.000Z"),
-        "end_time": None,
-        "instrument": {
-            "type": "Narod",
-            "channels": {
-                "U": [
-                    {"channel": "U_Volt", "offset": 0, "scale": 100},
-                    {"channel": "U_Bin", "offset": 0, "scale": 500},
-                ],
-                "V": [
-                    {"channel": "V_Volt", "offset": 0, "scale": 100},
-                    {"channel": "V_Bin", "offset": 0, "scale": 500},
-                ],
-                "W": [
-                    {"channel": "W_Volt", "offset": 0, "scale": 100},
-                    {"channel": "W_Bin", "offset": 0, "scale": 500},
-                ],
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "NEW",
-        "start_time": None,
-        "end_time": None,
-        "instrument": {
-            "type": "Narod",
-            "channels": {
-                "U": [
-                    {"channel": "U_Volt", "offset": 0, "scale": 100},
-                    {"channel": "U_Bin", "offset": 0, "scale": 500},
-                ],
-                "V": [
-                    {"channel": "V_Volt", "offset": 0, "scale": 100},
-                    {"channel": "V_Bin", "offset": 0, "scale": 500},
-                ],
-                "W": [
-                    {"channel": "W_Volt", "offset": 0, "scale": 100},
-                    {"channel": "W_Bin", "offset": 0, "scale": 500},
-                ],
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "LLO",
-        "start_time": None,
-        "end_time": None,
-        "instrument": {
-            "type": "Narod",
-            "channels": {
-                "U": [
-                    {"channel": "U_Volt", "offset": 0, "scale": 100},
-                    {"channel": "U_Bin", "offset": 0, "scale": 500},
-                ],
-                "V": [
-                    {"channel": "V_Volt", "offset": 0, "scale": 100},
-                    {"channel": "V_Bin", "offset": 0, "scale": 500},
-                ],
-                "W": [
-                    {"channel": "W_Volt", "offset": 0, "scale": 100},
-                    {"channel": "W_Bin", "offset": 0, "scale": 500},
-                ],
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "SHU",
-        "start_time": None,
-        "end_time": UTCDateTime("2023-06-28T00:00:00.000Z"),
-        "instrument": {
-            "type": "Narod",
-            "channels": {
-                "U": [
-                    {"channel": "U_Volt", "offset": 0, "scale": 100},
-                    {"channel": "U_Bin", "offset": 0, "scale": 505},
-                ],
-                "V": [
-                    {"channel": "V_Volt", "offset": 0, "scale": 100},
-                    {"channel": "V_Bin", "offset": 0, "scale": 505},
-                ],
-                "W": [
-                    {"channel": "W_Volt", "offset": 0, "scale": 100},
-                    {"channel": "W_Bin", "offset": 0, "scale": 505},
-                ],
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "SHU",
-        "start_time": UTCDateTime("2023-06-28T00:00:00.000Z"),
-        "end_time": UTCDateTime("2023-09-07T00:00:00.000Z"),
-        "instrument": {
-            "type": "FGE",
-            "channels": {
-                # each channel maps to a list of components to calculate nT
-                # TODO: calculate these lists based on "FGE" type
-                "U": [{"channel": "U_Volt", "offset": 19710, "scale": 944.935}],
-                "V": [{"channel": "V_Volt", "offset": 0, "scale": 964.909}],
-                "W": [{"channel": "W_Volt", "offset": 48068, "scale": 966.893}],
-            },
-            # this info should get updated when available
-            "electronics": {
-                "serial": "E566",
-                # these scale values are used to convert voltage
-                # these are calculated using Ohm's law, given scaling resistor value (38.3 kohm), and given nT/mA values.
-                "x-scale": 944.935,  # nT/V
-                "y-scale": 964.909,  # nT/V
-                "z-scale": 966.893,  # nT/V
-                "temperature-scale": 0.01,  # V/K
-            },
-            "sensor": {
-                "serial": "S0441",
-                # these constants combine with instrument setting for offset
-                "x-constant": 36191,  # nT/mA
-                "y-constant": 36956,  # nT/mA
-                "z-constant": 37032,  # nT/mA
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "SHU",
-        "start_time": UTCDateTime("2023-09-07T00:00:00.000Z"),
-        "end_time": None,
-        "instrument": {
-            "type": "FGE",
-            "channels": {
-                # each channel maps to a list of components to calculate nT
-                # TODO: calculate these lists based on "FGE" type
-                "U": [{"channel": "U_Volt", "offset": 19710, "scale": 975.1}],
-                "V": [{"channel": "V_Volt", "offset": 0, "scale": 969.4}],
-                "W": [{"channel": "W_Volt", "offset": 48068, "scale": 978.5}],
-            },
-            # this info should get updated when available
-            "electronics": {
-                "serial": "E0598",
-                # these scale values are used to convert voltage
-                "x-scale": 975.1,  # nT/V
-                "y-scale": 969.4,  # nT/V
-                "z-scale": 978.5,  # nT/V
-                "temperature-scale": 0.01,  # V/K
-            },
-            "sensor": {
-                "serial": "S0460",
-                "x-constant": 37348,  # nT/mA
-                "y-constant": 37127,  # nT/mA
-                "z-constant": 37477,  # nT/mA
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "SIT",
-        "start_time": None,
-        "end_time": None,
-        "instrument": {
-            "type": "Narod",
-            "channels": {
-                "U": [
-                    {"channel": "U_Volt", "offset": 0, "scale": 100},
-                    {"channel": "U_Bin", "offset": 0, "scale": 500},
-                ],
-                "V": [
-                    {"channel": "V_Volt", "offset": 0, "scale": 100},
-                    {"channel": "V_Bin", "offset": 0, "scale": 500},
-                ],
-                "W": [
-                    {"channel": "W_Volt", "offset": 0, "scale": 100},
-                    {"channel": "W_Bin", "offset": 0, "scale": 500},
-                ],
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "SJG",
-        "start_time": None,
-        "end_time": UTCDateTime("2023-08-18T19:02:34.000Z"),
-        "instrument": {
-            "type": "Narod",
-            "channels": {
-                "U": [
-                    {"channel": "U_Volt", "offset": 0, "scale": 100},
-                    {"channel": "U_Bin", "offset": 0, "scale": 500},
-                ],
-                "V": [
-                    {"channel": "V_Volt", "offset": 0, "scale": 100},
-                    {"channel": "V_Bin", "offset": 0, "scale": 500},
-                ],
-                "W": [
-                    {"channel": "W_Volt", "offset": 0, "scale": 100},
-                    {"channel": "W_Bin", "offset": 0, "scale": 500},
-                ],
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "SJG",
-        "start_time": UTCDateTime("2023-08-18T19:02:34.000Z"),
-        "end_time": UTCDateTime("2023-08-30T00:00:00.000Z"),
-        "instrument": {
-            "type": "FGE",
-            "channels": {
-                # each channel maps to a list of components to calculate nT
-                # TODO: calculate these lists based on "FGE" type
-                "U": [{"channel": "U_Volt", "offset": 27047, "scale": 313.2034}],
-                "V": [{"channel": "V_Volt", "offset": 0, "scale": 312.2797}],
-                "W": [{"channel": "W_Volt", "offset": 24288, "scale": 311.9576}],
-            },
-            "electronics": {
-                "serial": "E0543",
-                # these scale values are calculated manually
-                "x-scale": 313.2034,  # nT/V
-                "y-scale": 312.2797,  # nT/V
-                "z-scale": 311.9576,  # nT/V
-                "temperature-scale": 0.01,  # V/K
-            },
-            "sensor": {
-                "serial": "S0419",
-                # these constants combine with instrument setting for offset
-                "x-constant": 36958,  # nT/mA
-                "y-constant": 36849,  # nT/mA
-                "z-constant": 36811,  # nT/mA
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "SJG",
-        "start_time": UTCDateTime("2023-08-30T00:00:00.000Z"),
-        "end_time": None,
-        "instrument": {
-            "type": "FGE",
-            "channels": {
-                # each channel maps to a list of components to calculate nT
-                # TODO: calculate these lists based on "FGE" type
-                "U": [{"channel": "U_Volt", "offset": 26947.5, "scale": 313.2034}],
-                "V": [{"channel": "V_Volt", "offset": 0, "scale": 312.2797}],
-                "W": [{"channel": "W_Volt", "offset": 24690, "scale": 311.9576}],
-            },
-            "electronics": {
-                "serial": "E0543",
-                # these scale values are calculated manually
-                "x-scale": 313.2034,  # nT/V
-                "y-scale": 312.2797,  # nT/V
-                "z-scale": 311.9576,  # nT/V
-                "temperature-scale": 0.01,  # V/K
-            },
-            "sensor": {
-                "serial": "S0419",
-                # these constants combine with instrument setting for offset
-                "x-constant": 36958,  # nT/mA
-                "y-constant": 36849,  # nT/mA
-                "z-constant": 36811,  # nT/mA
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "SJT",
-        "start_time": None,
-        "end_time": UTCDateTime("2023-08-18T19:02:34.000Z"),
-        "instrument": {
-            "type": "FGE",
-            "channels": {
-                # each channel maps to a list of components to calculate nT
-                # TODO: calculate these lists based on "FGE" type
-                "U": [{"channel": "U_Volt", "offset": 27047, "scale": 313.2034}],
-                "V": [{"channel": "V_Volt", "offset": 0, "scale": 312.2797}],
-                "W": [{"channel": "W_Volt", "offset": 24288, "scale": 311.9576}],
-            },
-            # this info should get updated when available
-            "electronics": {
-                "serial": "E0543",
-                # these scale values are calculated manually
-                "x-scale": 313.2034,  # nT/V
-                "y-scale": 312.2797,  # nT/V
-                "z-scale": 311.9576,  # nT/V
-                "temperature-scale": 0.01,  # V/K
-            },
-            "sensor": {
-                "serial": "S0419",
-                # these constants combine with instrument setting for offset
-                "x-constant": 36958,  # nT/mA
-                "y-constant": 36849,  # nT/mA
-                "z-constant": 36811,  # nT/mA
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "SJT",
-        "start_time": UTCDateTime("2023-08-18T19:02:34.000Z"),
-        "end_time": None,
-        "instrument": {
-            "type": "Narod",
-            "channels": {
-                "U": [
-                    {"channel": "U_Volt", "offset": 0, "scale": 100},
-                    {"channel": "U_Bin", "offset": 0, "scale": 500},
-                ],
-                "V": [
-                    {"channel": "V_Volt", "offset": 0, "scale": 100},
-                    {"channel": "V_Bin", "offset": 0, "scale": 500},
-                ],
-                "W": [
-                    {"channel": "W_Volt", "offset": 0, "scale": 100},
-                    {"channel": "W_Bin", "offset": 0, "scale": 500},
-                ],
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "TUC",
-        "start_time": None,
-        "end_time": UTCDateTime("2023-03-29T00:00:00.000Z"),
-        "instrument": {
-            "type": "Narod",
-            "channels": {
-                "U": [
-                    {"channel": "U_Volt", "offset": 0, "scale": 100},
-                    {"channel": "U_Bin", "offset": 0, "scale": 500},
-                ],
-                "V": [
-                    {"channel": "V_Volt", "offset": 0, "scale": 100},
-                    {"channel": "V_Bin", "offset": 0, "scale": 500},
-                ],
-                "W": [
-                    {"channel": "W_Volt", "offset": 0, "scale": 100},
-                    {"channel": "W_Bin", "offset": 0, "scale": 500},
-                ],
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "TUC",
-        "start_time": UTCDateTime("2023-03-29T00:00:00.000Z"),
-        "end_time": UTCDateTime("2023-08-30T00:00:00.000Z"),
-        "instrument": {
-            "type": "FGE",
-            "channels": {
-                # each channel maps to a list of components to calculate nT
-                # TODO: calculate these lists based on "FGE" type
-                "U": [{"channel": "U_Volt", "offset": 24024, "scale": 978.355}],
-                "V": [{"channel": "V_Volt", "offset": 0, "scale": 965.901}],
-                "W": [{"channel": "W_Volt", "offset": 40040, "scale": 954.543}],
-            },
-            # this info should get updated when available
-            "electronics": {
-                "serial": "E571",
-                # these scale values are calculated manually
-                "x-scale": 978.355,  # nT/V
-                "y-scale": 965.901,  # nT/V
-                "z-scale": 954.543,  # nT/V
-                "temperature-scale": 0.01,  # V/K
-            },
-            "sensor": {
-                "serial": "S0446",
-                # these constants combine with instrument setting for offset
-                "x-constant": 37471,  # nT/mA
-                "y-constant": 36994,  # nT/mA
-                "z-constant": 36559,  # nT/mA
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "TUC",
-        "start_time": UTCDateTime("2023-08-30T00:00:00.000Z"),
-        "end_time": None,
-        "instrument": {
-            "type": "FGE",
-            "channels": {
-                # each channel maps to a list of components to calculate nT
-                # TODO: calculate these lists based on "FGE" type
-                "U": [{"channel": "U_Volt", "offset": 24016.5, "scale": 978.355}],
-                "V": [{"channel": "V_Volt", "offset": 0, "scale": 965.901}],
-                "W": [{"channel": "W_Volt", "offset": 39953.5, "scale": 954.543}],
-            },
-            # this info should get updated when available
-            "electronics": {
-                "serial": "E571",
-                # these scale values are calculated manually
-                "x-scale": 978.355,  # nT/V
-                "y-scale": 965.901,  # nT/V
-                "z-scale": 954.543,  # nT/V
-                "temperature-scale": 0.01,  # V/K
-            },
-            "sensor": {
-                "serial": "S0446",
-                # these constants combine with instrument setting for offset
-                "x-constant": 37471,  # nT/mA
-                "y-constant": 36994,  # nT/mA
-                "z-constant": 36559,  # nT/mA
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "BRW",
-        "start_time": None,
-        "end_time": UTCDateTime("2023-10-23T20:00:00.000Z"),
-        "instrument": {
-            "type": "Narod",
-            "channels": {
-                "U": [
-                    {"channel": "U_Volt", "offset": 0, "scale": 100},
-                    {"channel": "U_Bin", "offset": 0, "scale": 506},
-                ],
-                "V": [
-                    {"channel": "V_Volt", "offset": 0, "scale": 100},
-                    {"channel": "V_Bin", "offset": 0, "scale": 505.6},
-                ],
-                "W": [
-                    {"channel": "W_Volt", "offset": 0, "scale": 100},
-                    {"channel": "W_Bin", "offset": 0, "scale": 506},
-                ],
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "BRW",
-        "start_time": UTCDateTime("2023-10-23T19:00:00.000Z"),
-        "end_time": UTCDateTime("2023-10-24T22:45:00.000Z"),
-        "instrument": {
-            "type": "FGE",
-            "channels": {
-                # each channel maps to a list of components to calculate nT
-                # TODO: calculate these lists based on "FGE" type
-                "U": [{"channel": "U_Volt", "offset": 9217, "scale": 5797.3}],
-                "V": [{"channel": "V_Volt", "offset": 0, "scale": 5777.6}],
-                "W": [{"channel": "W_Volt", "offset": 56442, "scale": 5895.6}],
-            },
-            "electronics": {
-                "serial": "????",
-                # these scale values are calculated manually.
-                "x-scale": 5797.3,  # nT/V
-                "y-scale": 5777.6,  # nT/V
-                "z-scale": 5895.6,  # nT/V
-                "temperature-scale": 0.01,  # V/K
-            },
-            "sensor": {
-                "serial": "????",
-                # these constants combine with instrument setting for offset
-                "x-constant": None,  # nT/mA
-                "y-constant": None,  # nT/mA
-                "z-constant": None,  # nT/mA
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "CMO",
-        "start_time": None,
-        "end_time": UTCDateTime("2023-10-26T21:00:00.000Z"),
-        "instrument": {
-            "type": "Narod",
-            "channels": {
-                "U": [
-                    {"channel": "U_Volt", "offset": 0, "scale": 99.4},
-                    {"channel": "U_Bin", "offset": 0, "scale": 502.5},
-                ],
-                "V": [
-                    {"channel": "V_Volt", "offset": 0, "scale": 101.5},
-                    {"channel": "V_Bin", "offset": 0, "scale": 512.5},
-                ],
-                "W": [
-                    {"channel": "W_Volt", "offset": 0, "scale": 100.98},
-                    {"channel": "W_Bin", "offset": 0, "scale": 509.15},
-                ],
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "CMT",
-        "start_time": None,
-        "end_time": UTCDateTime("2023-10-26T21:00:00.000Z"),
-        "instrument": {
-            "type": "FGE",
-            "channels": {
-                # each channel maps to a list of components to calculate nT
-                # TODO: calculate these lists based on "FGE" type
-                "U": [{"channel": "U_Volt", "offset": 0, "scale": 967.7}],
-                "V": [{"channel": "V_Volt", "offset": 0, "scale": 969.7}],
-                "W": [{"channel": "W_Volt", "offset": 0, "scale": 973.4}],
-            },
-            "electronics": {
-                "serial": "E0568",
-                # these scale values are used to convert voltage
-                "x-scale": 967.7,  # nT/V
-                "y-scale": 969.7,  # nT/V
-                "z-scale": 973.4,  # nT/V
-                "temperature-scale": 0.01,  # V/K
-            },
-            "sensor": {
-                "serial": "S0443",
-                # these constants combine with instrument setting for offset
-                "x-constant": 37062,  # nT/mA
-                "y-constant": 37141,  # nT/mA
-                "z-constant": 37281,  # nT/mA
-            },
-        },
-    },
-    {
-        "network": "NT",
-        "station": "CMO",
-        "start_time": UTCDateTime("2023-10-26T21:00:00.000Z"),
-        "end_time": UTCDateTime("2023-10-27T16:20:00.000Z"),
-        "instrument": {
-            "type": "FGE",
-            "channels": {
-                # each channel maps to a list of components to calculate nT
-                # TODO: calculate these lists based on "FGE" type
-                "U": [{"channel": "U_Volt", "offset": 0, "scale": 967.7}],
-                "V": [{"channel": "V_Volt", "offset": 0, "scale": 969.7}],
-                "W": [{"channel": "W_Volt", "offset": 0, "scale": 973.4}],
-            },
-            "electronics": {
-                "serial": "E0568",
-                # these scale values are used to convert voltage
-                "x-scale": 967.7,  # nT/V
-                "y-scale": 969.7,  # nT/V
-                "z-scale": 973.4,  # nT/V
-                "temperature-scale": 0.01,  # V/K
-            },
-            "sensor": {
-                "serial": "S0443",
-                # these constants combine with instrument setting for offset
-                "x-constant": 37062,  # nT/mA
-                "y-constant": 37141,  # nT/mA
-                "z-constant": 37281,  # nT/mA
-            },
-        },
-    },
-]
+    return [
+        c
+        for c in calibrations
+        if c["station"] == observatory
+        and (end_time is None or c["start_time"] is None or c["start_time"] < end_time)
+        and (start_time is None or c["end_time"] is None or c["end_time"] > start_time)
+    ]
-- 
GitLab