From a4bc6d95fba3ac6cbd607af810d850ed3c614cab Mon Sep 17 00:00:00 2001 From: "E. Joshua Rigler" <erigler@usgs.gov> Date: Mon, 20 Mar 2023 16:31:37 -0600 Subject: [PATCH 1/3] print nothing if sensor_sampling_rate is not invertable The _format_headers() function in IAGA2002Writer.py would choke when the sensor_sampling_rate parameter in the trace.stats metadata could not be inverted. This occurred, at least, when the "Digital Sampling" IAGA2002 header line was not parsed properly, or was blank. --- geomagio/iaga2002/IAGA2002Writer.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/geomagio/iaga2002/IAGA2002Writer.py b/geomagio/iaga2002/IAGA2002Writer.py index bd215ef98..4aac8db92 100644 --- a/geomagio/iaga2002/IAGA2002Writer.py +++ b/geomagio/iaga2002/IAGA2002Writer.py @@ -87,11 +87,15 @@ class IAGA2002Writer(object): self._format_header("Sensor Orientation", stats.sensor_orientation) ) if "sensor_sampling_rate" in stats: - buf.append( - self._format_header( - "Digital Sampling", str(1 / stats.sensor_sampling_rate) + " second" + try: + buf.append( + self._format_header( + "Digital Sampling", + str(1 / stats.sensor_sampling_rate) + " second", + ) ) - ) + except TypeError: + buf.append(self._format_header("Digital Sampling", "")) if "data_interval_type" in stats: buf.append( self._format_header("Data Interval Type", stats.data_interval_type) -- GitLab From af72dc0ff323eed8a1ce5ca87b0c76f223cd7050 Mon Sep 17 00:00:00 2001 From: "E. Joshua Rigler" <erigler@usgs.gov> Date: Mon, 20 Mar 2023 16:39:31 -0600 Subject: [PATCH 2/3] Force traces in stream to first dtype before merge A Stream corresponding to a given network, station, location, and channel can (but probably shouldn't) have more than 1 trace returned from an ObsPy client.get_waveforms() function. This happens, for example, when the data type generated by a given station changes. This change forces the dtype of the data array for all Traces in the Stream to match the dtype of the data array in the first Trace of the Stream, thus allowing the Stream.merge() function to work as intended. --- geomagio/edge/MiniSeedFactory.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/geomagio/edge/MiniSeedFactory.py b/geomagio/edge/MiniSeedFactory.py index ff03c0406..c9c3122c1 100644 --- a/geomagio/edge/MiniSeedFactory.py +++ b/geomagio/edge/MiniSeedFactory.py @@ -361,6 +361,8 @@ class MiniSeedFactory(TimeseriesFactory): data = self.client.get_waveforms( sncl.network, sncl.station, sncl.location, sncl.channel, starttime, endtime ) + for trace in data: + trace.data = trace.data.astype(data[0].data.dtype) data.merge() if data.count() == 0 and add_empty_channels: data += self._get_empty_trace( -- GitLab From c2c6c6444b3d8aceaffe095a108246523ffde4a7 Mon Sep 17 00:00:00 2001 From: "E. Joshua Rigler" <erigler@usgs.gov> Date: Tue, 21 Mar 2023 14:42:03 -0600 Subject: [PATCH 3/3] Fixes issue #77 As per discussion in issue #77 with Dave K., this commit adds delta/2 to the requested `endtime` to ensure that starttime and endtime are fully inclusive in Edge-related I/O factories. I would have liked to generalized this and reduce the duplicate code between EdgeFactory and MiniSeedFactory, but couldn't figure out how to do this without adding considerably *more* code to the project than what is in this commit. --- geomagio/edge/EdgeFactory.py | 6 +++++- geomagio/edge/MiniSeedFactory.py | 11 ++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/geomagio/edge/EdgeFactory.py b/geomagio/edge/EdgeFactory.py index 525999834..d07f3fa5e 100644 --- a/geomagio/edge/EdgeFactory.py +++ b/geomagio/edge/EdgeFactory.py @@ -333,6 +333,10 @@ class EdgeFactory(TimeseriesFactory): element=channel, location=self.locationCode, ) + # geomag-algorithms *should* treat starttime/endtime as inclusive everywhere; + # according to its author, EdgeCWB is inclusive of starttime, but exclusive of + # endtime, to satisfy seismic standards/requirements, to precision delta/2; + half_delta = TimeseriesUtility.get_delta_from_interval(interval) / 2 try: data = self.client.get_waveforms( sncl.network, @@ -340,7 +344,7 @@ class EdgeFactory(TimeseriesFactory): sncl.location, sncl.channel, starttime, - endtime, + endtime + half_delta, ) except TypeError: # get_waveforms() fails if no data is returned from Edge diff --git a/geomagio/edge/MiniSeedFactory.py b/geomagio/edge/MiniSeedFactory.py index c9c3122c1..daf02420c 100644 --- a/geomagio/edge/MiniSeedFactory.py +++ b/geomagio/edge/MiniSeedFactory.py @@ -358,8 +358,17 @@ class MiniSeedFactory(TimeseriesFactory): element=channel, location=self.locationCode, ) + # geomag-algorithms *should* treat starttime/endtime as inclusive everywhere; + # according to its author, EdgeCWB is inclusive of starttime, but exclusive of + # endtime, to satisfy seismic standards/requirements, to precision delta/2; + half_delta = TimeseriesUtility.get_delta_from_interval(interval) / 2 data = self.client.get_waveforms( - sncl.network, sncl.station, sncl.location, sncl.channel, starttime, endtime + sncl.network, + sncl.station, + sncl.location, + sncl.channel, + starttime, + endtime + half_delta, ) for trace in data: trace.data = trace.data.astype(data[0].data.dtype) -- GitLab