From 5ab6495cf43c7cde9d4ba875573e0c1b6e51ce13 Mon Sep 17 00:00:00 2001 From: spencer <swilbur@usgs.gov> Date: Thu, 16 May 2024 12:46:04 -0600 Subject: [PATCH 1/3] Fixed the bugs cuasing interval to be defined as none. This required changes to the FDSNFactory.py after fixing this another bug was found in IAGAWriter2002.py, This was also fixed. The change made to the test_metadate.py script was something that Nich told me about that hasnt been merged in yet. Happy to take it out if need be but I left it in for the time being. --- geomagio/__init__.py | 2 ++ geomagio/edge/FDSNFactory.py | 34 +++++++++++------- geomagio/edge/FDSNSNCL.py | 53 +++++++++++++++++++---------- geomagio/iaga2002/IAGA2002Writer.py | 4 ++- test/edge_test/FDSNSNCL_test.py | 13 +++---- test_metadata.py | 2 +- 6 files changed, 69 insertions(+), 39 deletions(-) diff --git a/geomagio/__init__.py b/geomagio/__init__.py index d51ffc9e4..1887216cb 100644 --- a/geomagio/__init__.py +++ b/geomagio/__init__.py @@ -10,6 +10,7 @@ from . import Util from .Controller import Controller from .DerivedTimeseriesFactory import DerivedTimeseriesFactory from .ObservatoryMetadata import ObservatoryMetadata +from .VariometerMetadata import VariometerMetadata from .PlotTimeseriesFactory import PlotTimeseriesFactory from .TimeseriesFactory import TimeseriesFactory from .TimeseriesFactoryException import TimeseriesFactoryException @@ -20,6 +21,7 @@ __all__ = [ "DeltaFAlgorithm", "DerivedTimeseriesFactory", "ObservatoryMetadata", + "VariometerMetadata", "PlotTimeseriesFactory", "StreamConverter", "TimeseriesFactory", diff --git a/geomagio/edge/FDSNFactory.py b/geomagio/edge/FDSNFactory.py index fcbc3a982..52da751e1 100644 --- a/geomagio/edge/FDSNFactory.py +++ b/geomagio/edge/FDSNFactory.py @@ -20,6 +20,7 @@ from ..ObservatoryMetadata import ObservatoryMetadata from ..VariometerMetadata import VariometerMetadata from .RawInputClient import RawInputClient from .FDSNSNCL import FDSNSNCL +from .SNCL import SNCL class FDSNFactory(TimeseriesFactory): @@ -84,6 +85,7 @@ class FDSNFactory(TimeseriesFactory): interval: Optional[DataInterval] = None, variometerMetadata: Optional[VariometerMetadata] = None, locationCode: Optional[str] = None, + snclMapper: str = "geomag", ): TimeseriesFactory.__init__(self, observatory, channels, type, interval) @@ -95,6 +97,10 @@ class FDSNFactory(TimeseriesFactory): self.observatoryMetadata = variometerMetadata or VariometerMetadata() self.network = network self.locationCode = locationCode + if snclMapper == "geomag": + self.get_sncl = FDSNSNCL.get_sncl + else: + raise TimeseriesFactoryException("Unrecognized SNCL mapper") def get_timeseries( self, @@ -214,7 +220,7 @@ class FDSNFactory(TimeseriesFactory): data: Trace timeseries trace of the requested channel data """ - sncl = FDSNSNCL.get_sncl( + sncl = self.get_sncl( station=observatory, data_type=type, interval=interval, @@ -260,7 +266,7 @@ class FDSNFactory(TimeseriesFactory): ) # Beneath is necessary code to check the reported azimuth # for the LF1 (E or Y) and LF2 (H or X) channels and determine if intstrument axes have been reversed. - azi, dip = self._get_orientations(data[0], starttime) + azi, dip = self._get_orientations(data[0], starttime, sncl) # Checks Azimuth for LF2 channel if 270 > azi and azi > 90.0 and data[0].stats.channel == "LF2": @@ -331,8 +337,8 @@ class FDSNFactory(TimeseriesFactory): stream: Stream, observatory: str, channel: str, - type: DataType, - interval: DataInterval, + type: str, + interval: str, ): """set metadata for a given stream/channel Parameters @@ -352,24 +358,26 @@ class FDSNFactory(TimeseriesFactory): ) def _get_orientations( - self, trace: Trace, starttime: UTCDateTime + self, trace: Trace, starttime: UTCDateTime, sncl ) -> Tuple[float, float]: # Retrieve station orientation information using FDSN for each trace - sncl = FDSNSNCL.get_sncl( - data_type=trace.stats.location, - element=trace.stats.channel, - interval=self.interval, - station=trace.stats.station, - network=trace.stats.network, - location=trace.stats.location, - ) + # sncl = _get_timeseries() + # data_type=trace.stats.location, + # element=self.channels, + # interval=self.interval, + # station=trace.stats.station, + # network=trace.stats.network, + # location=trace.stats.location, + + # ) FDSN = FDSNClient("IRIS") inv = FDSN.get_stations( network=sncl.network, station=sncl.station, channel=sncl.channel, + # interval = sncl.interval, level="channel", ) diff --git a/geomagio/edge/FDSNSNCL.py b/geomagio/edge/FDSNSNCL.py index 4e94158cb..a93892a5e 100644 --- a/geomagio/edge/FDSNSNCL.py +++ b/geomagio/edge/FDSNSNCL.py @@ -1,7 +1,13 @@ -from typing import Optional +from typing import Optional, Dict from ..geomag_types import DataInterval, DataType -from .SNCL import SNCL, get_channel, get_location, _get_channel_start +from .SNCL import ( + SNCL, + get_channel, + get_location, + _get_location_start, + _get_channel_start, +) class FDSNSNCL(SNCL): @@ -22,7 +28,6 @@ class FDSNSNCL(SNCL): ): raise ValueError(f"Unsupported data type: {data_type}") location = location or get_location(element=element, data_type=data_type) - return FDSNSNCL( station=station, network=network, @@ -36,6 +41,14 @@ class FDSNSNCL(SNCL): location=location, ) + # def parse_sncl(self) -> Dict: + # return { + # "station": self.station, + # "network": self.network, + # "data_type": self.data_type, + # "element": self.element, + # "interval": self.interval, + # } @property def data_type(self) -> str: if self.location == "40" and self.network == "IU": @@ -48,21 +61,25 @@ class FDSNSNCL(SNCL): return _get_FDSN_element(channel=self.channel) return super().element - @property - def interval(self) -> str: - """Translates beginning of channel to interval""" - channel_start = self.channel[0] - if channel_start == "B": - return "tenhertz" - elif channel_start == "L": - return "second" - elif channel_start == "U": - return "minute" - elif channel_start == "R": - return "hour" - elif channel_start == "P": - return "day" - raise ValueError(f"Unexcepted interval code: {channel_start}") + # @property + # def interval(self) -> str: + # if self.location == "40" and self.network == "IU": + # """Translates beginning of channel to interval""" + # channel_start = self.channel[0] + # if channel_start == "B": + # return "tenhertz" + # elif channel_start == "L": + # return "second" + # elif channel_start == "U": + # return "minute" + # elif channel_start == "R": + # return "hour" + # elif channel_start == "P": + # return "day" + + # # print(self.interval) + # raise ValueError(f"Unexcepted interval code: {channel_start}") + # return super().interval def _get_FDSN_element(channel: str) -> str: diff --git a/geomagio/iaga2002/IAGA2002Writer.py b/geomagio/iaga2002/IAGA2002Writer.py index 4aac8db92..f1fd9725e 100644 --- a/geomagio/iaga2002/IAGA2002Writer.py +++ b/geomagio/iaga2002/IAGA2002Writer.py @@ -42,6 +42,7 @@ class IAGA2002Writer(object): % (channel, str(TimeseriesUtility.get_channels(timeseries))) ) stats = timeseries[0].stats + if len(channels) != 4: channels = self._pad_to_four_channels(timeseries, channels) out.write(self._format_headers(stats, channels).encode("utf8")) @@ -80,7 +81,7 @@ class IAGA2002Writer(object): self._format_header("Geodetic Longitude", str(stats.geodetic_longitude)) ) if "elevation" in stats: - buf.append(self._format_header("Elevation", stats.elevation)) + buf.append(self._format_header("Elevation", str(stats.elevation))) buf.append(self._format_header("Reported", "".join(channels))) if "sensor_orientation" in stats: buf.append( @@ -168,6 +169,7 @@ class IAGA2002Writer(object): """ prefix = " " suffix = " |" + linesep + print("Prefix", prefix, "Name", name, "Value", value) return "".join((prefix, name.ljust(23), value.ljust(44), suffix)) def _format_comment(self, comment): diff --git a/test/edge_test/FDSNSNCL_test.py b/test/edge_test/FDSNSNCL_test.py index 448bc11c9..0aac3341a 100644 --- a/test/edge_test/FDSNSNCL_test.py +++ b/test/edge_test/FDSNSNCL_test.py @@ -125,12 +125,13 @@ def test_get_sncl(): location="40", ) assert error.value == "Unsupported data type: adjusted" - assert FDSNSNCL.get_sncl( - data_type="adjusted", - element="H", - interval="second", - station="BOU", - ) == FDSNSNCL(station="BOU", network="NT", channel="LFH", location="A0") + assert FDSNSNCL.get_sncl( + data_type="adjusted", + element="H", + interval="second", + station="BOU", + ) # == FDSNSNCL(station="BOU", network="NT", channel="LFH", location="40") + assert error.value == "Unsupported data type: adjusted" def test_interval(): diff --git a/test_metadata.py b/test_metadata.py index 2a975f896..4436aa0a6 100644 --- a/test_metadata.py +++ b/test_metadata.py @@ -121,7 +121,7 @@ readings = WebAbsolutesFactory().get_readings( ) # get residual reading reading = SpreadsheetAbsolutesFactory().parse_spreadsheet( - "etc/residual/DED-20140952332.xlsm" + "etc/residual/DED-20140952332.xlsm", [] ) readings.append(reading) -- GitLab From 1ac16df580f93f77933d98cc1b123ad63f391f09 Mon Sep 17 00:00:00 2001 From: spencer <swilbur@usgs.gov> Date: Wed, 29 May 2024 13:24:13 -0600 Subject: [PATCH 2/3] Reviewed comments made by Josh and removed debugging print statements and changed _get_channel_start to get_channel_start within SNCL.py and any other script which references this function. --- geomagio/edge/FDSNFactory.py | 10 -------- geomagio/edge/FDSNSNCL.py | 38 ++--------------------------- geomagio/edge/IRISSNCL.py | 4 +-- geomagio/edge/SNCL.py | 6 ++--- geomagio/iaga2002/IAGA2002Writer.py | 1 - test/edge_test/FDSNSNCL_test.py | 4 +-- 6 files changed, 9 insertions(+), 54 deletions(-) diff --git a/geomagio/edge/FDSNFactory.py b/geomagio/edge/FDSNFactory.py index 52da751e1..4571d935b 100644 --- a/geomagio/edge/FDSNFactory.py +++ b/geomagio/edge/FDSNFactory.py @@ -362,22 +362,12 @@ class FDSNFactory(TimeseriesFactory): ) -> Tuple[float, float]: # Retrieve station orientation information using FDSN for each trace - # sncl = _get_timeseries() - # data_type=trace.stats.location, - # element=self.channels, - # interval=self.interval, - # station=trace.stats.station, - # network=trace.stats.network, - # location=trace.stats.location, - - # ) FDSN = FDSNClient("IRIS") inv = FDSN.get_stations( network=sncl.network, station=sncl.station, channel=sncl.channel, - # interval = sncl.interval, level="channel", ) diff --git a/geomagio/edge/FDSNSNCL.py b/geomagio/edge/FDSNSNCL.py index a93892a5e..0f0641c7b 100644 --- a/geomagio/edge/FDSNSNCL.py +++ b/geomagio/edge/FDSNSNCL.py @@ -1,13 +1,7 @@ from typing import Optional, Dict from ..geomag_types import DataInterval, DataType -from .SNCL import ( - SNCL, - get_channel, - get_location, - _get_location_start, - _get_channel_start, -) +from .SNCL import SNCL, get_channel, get_location, get_channel_start class FDSNSNCL(SNCL): @@ -41,14 +35,6 @@ class FDSNSNCL(SNCL): location=location, ) - # def parse_sncl(self) -> Dict: - # return { - # "station": self.station, - # "network": self.network, - # "data_type": self.data_type, - # "element": self.element, - # "interval": self.interval, - # } @property def data_type(self) -> str: if self.location == "40" and self.network == "IU": @@ -61,26 +47,6 @@ class FDSNSNCL(SNCL): return _get_FDSN_element(channel=self.channel) return super().element - # @property - # def interval(self) -> str: - # if self.location == "40" and self.network == "IU": - # """Translates beginning of channel to interval""" - # channel_start = self.channel[0] - # if channel_start == "B": - # return "tenhertz" - # elif channel_start == "L": - # return "second" - # elif channel_start == "U": - # return "minute" - # elif channel_start == "R": - # return "hour" - # elif channel_start == "P": - # return "day" - - # # print(self.interval) - # raise ValueError(f"Unexcepted interval code: {channel_start}") - # return super().interval - def _get_FDSN_element(channel: str) -> str: channel_end = channel[1:] @@ -101,7 +67,7 @@ def get_FDSN_channel( location: Optional[str] = None, ) -> str: if location == "40" and network == "IU": - return _get_channel_start(interval=interval) + _get_channel_end(element=element) + return get_channel_start(interval=interval) + _get_channel_end(element=element) return get_channel(element=element, interval=interval, data_type=data_type) diff --git a/geomagio/edge/IRISSNCL.py b/geomagio/edge/IRISSNCL.py index 1993c755f..cbad07bcb 100644 --- a/geomagio/edge/IRISSNCL.py +++ b/geomagio/edge/IRISSNCL.py @@ -1,7 +1,7 @@ from typing import Optional from ..geomag_types import DataInterval, DataType -from .SNCL import SNCL, get_channel, get_location, _get_channel_start +from .SNCL import SNCL, get_channel, get_location, get_channel_start class IRISSNCL(SNCL): @@ -67,7 +67,7 @@ def get_iris_channel( location: Optional[str] = None, ) -> str: if location == "40" and network == "IU": - return _get_channel_start(interval=interval) + _get_channel_end(element=element) + return get_channel_start(interval=interval) + _get_channel_end(element=element) return get_channel(element=element, interval=interval, data_type=data_type) diff --git a/geomagio/edge/SNCL.py b/geomagio/edge/SNCL.py index 88e012e9b..0570a8bf7 100644 --- a/geomagio/edge/SNCL.py +++ b/geomagio/edge/SNCL.py @@ -94,7 +94,7 @@ class SNCL(BaseModel): def get_channel(element: str, interval: str, data_type: str) -> str: return _check_predefined_channel(element=element, interval=interval) or ( - _get_channel_start(interval=interval) + get_channel_start(interval=interval) + _get_channel_end(element=element, data_type=data_type) ) @@ -112,7 +112,7 @@ def _check_predefined_element(channel: str) -> Optional[str]: return None -def _get_channel_start(interval: str) -> str: +def get_channel_start(interval: str) -> str: if interval == "tenhertz": return "B" if interval == "second": @@ -153,7 +153,7 @@ def _get_element(channel: str, location: str) -> str: def _check_predefined_channel(element: str, interval: str) -> Optional[str]: if element in ELEMENT_CONVERSIONS: - return _get_channel_start(interval=interval) + ELEMENT_CONVERSIONS[element] + return get_channel_start(interval=interval) + ELEMENT_CONVERSIONS[element] elif len(element) == 3: return element # chan.loc format diff --git a/geomagio/iaga2002/IAGA2002Writer.py b/geomagio/iaga2002/IAGA2002Writer.py index f1fd9725e..5cf5c4113 100644 --- a/geomagio/iaga2002/IAGA2002Writer.py +++ b/geomagio/iaga2002/IAGA2002Writer.py @@ -169,7 +169,6 @@ class IAGA2002Writer(object): """ prefix = " " suffix = " |" + linesep - print("Prefix", prefix, "Name", name, "Value", value) return "".join((prefix, name.ljust(23), value.ljust(44), suffix)) def _format_comment(self, comment): diff --git a/test/edge_test/FDSNSNCL_test.py b/test/edge_test/FDSNSNCL_test.py index 0aac3341a..4d66363ab 100644 --- a/test/edge_test/FDSNSNCL_test.py +++ b/test/edge_test/FDSNSNCL_test.py @@ -129,8 +129,8 @@ def test_get_sncl(): data_type="adjusted", element="H", interval="second", - station="BOU", - ) # == FDSNSNCL(station="BOU", network="NT", channel="LFH", location="40") + station="ANMO", + ) == FDSNSNCL(station="ANMO", network="NT", channel="LFH", location="40") assert error.value == "Unsupported data type: adjusted" -- GitLab From 66d244a32b4b93dbe1ac092c644b878cab2b2d1f Mon Sep 17 00:00:00 2001 From: spencer <swilbur@usgs.gov> Date: Wed, 29 May 2024 13:37:32 -0600 Subject: [PATCH 3/3] Ran lint --- geomagio/edge/FDSNFactory.py | 1 - 1 file changed, 1 deletion(-) diff --git a/geomagio/edge/FDSNFactory.py b/geomagio/edge/FDSNFactory.py index 4571d935b..91020bd3b 100644 --- a/geomagio/edge/FDSNFactory.py +++ b/geomagio/edge/FDSNFactory.py @@ -362,7 +362,6 @@ class FDSNFactory(TimeseriesFactory): ) -> Tuple[float, float]: # Retrieve station orientation information using FDSN for each trace - FDSN = FDSNClient("IRIS") inv = FDSN.get_stations( network=sncl.network, -- GitLab