diff --git a/geomagio/ChannelConverter.py b/geomagio/ChannelConverter.py index 54d2c5cf33bbd39672ebf369ebb6da240b29bbc0..c4292b1ed1c7d3a468cc199881d2ad9cb62668ca 100644 --- a/geomagio/ChannelConverter.py +++ b/geomagio/ChannelConverter.py @@ -83,7 +83,7 @@ def get_geo_x_from_mag(h, d): array_like x component """ - return h * numpy.cos(d) + return numpy.multiply(h, numpy.cos(d)) def get_geo_y_from_mag(h, d): @@ -101,7 +101,7 @@ def get_geo_y_from_mag(h, d): array_like y component """ - return h * numpy.sin(d) + return numpy.multiply(h, numpy.sin(d)) # ### @@ -168,7 +168,7 @@ def get_mag_d_from_obs(h, e, d0=0): array_like the total magnetic declination """ - return d0 + get_obs_d_from_obs(h, e) + return numpy.add(d0, get_obs_d_from_obs(h, e)) def get_mag_d_from_geo(x, y): @@ -310,7 +310,7 @@ def get_obs_d_from_mag_d(d, d0=0): array_like the observatory d declination """ - return d - d0 + return numpy.subtract(d, d0) def get_obs_e_from_mag(h, d, d0=0): @@ -331,7 +331,7 @@ def get_obs_e_from_mag(h, d, d0=0): the observatory e component """ obs_d = get_obs_d_from_mag_d(d, d0) - return h * numpy.sin(obs_d) + return numpy.multiply(h, numpy.sin(obs_d)) def get_obs_e_from_obs(h, d): @@ -349,7 +349,7 @@ def get_obs_e_from_obs(h, d): array_like the observatory e component """ - return h * numpy.tan(d) + return numpy.multiply(h, numpy.tan(d)) def get_obs_h_from_mag(h, d, d0=0): @@ -370,7 +370,7 @@ def get_obs_h_from_mag(h, d, d0=0): the observatory h component """ obs_d = get_obs_d_from_mag_d(d, d0) - return h * numpy.cos(obs_d) + return numpy.multiply(h, numpy.cos(obs_d)) def get_radians_from_minutes(m): @@ -380,7 +380,7 @@ def get_radians_from_minutes(m): d: array_like the decimal value to be converted """ - return m * M2R + return numpy.multiply(m, M2R) def get_minutes_from_radians(r): @@ -391,4 +391,4 @@ def get_minutes_from_radians(r): r: float the radian value to be converted """ - return r * R2M + return numpy.multiply(r, R2M) diff --git a/geomagio/ChannelConverterTest.py b/geomagio/ChannelConverterTest.py index c52e39399d3a75199a79b68e8086c31f565f3034..5c653142f10899b4769c6da45ca87f2c3dbb2cd6 100644 --- a/geomagio/ChannelConverterTest.py +++ b/geomagio/ChannelConverterTest.py @@ -40,6 +40,10 @@ class ChannelConverterTest: geographic north. Y: the component corresponding to the field strength along geographic east. + + We are using triangle identities for variables to test with. Specifically + the hypotenuse is normally equal to 1, causing the adjacent angle + length to be cos(angle) and the opposite length to be sin(angle) """ def test_get_geo_from_obs(self): diff --git a/geomagio/StreamConverter.py b/geomagio/StreamConverter.py index 4d1fda284d16a59aaf0283f7136dbf2d5442cd8d..4c6184d81456ae586c221fedc39bc8654fed6c37 100644 --- a/geomagio/StreamConverter.py +++ b/geomagio/StreamConverter.py @@ -13,7 +13,29 @@ import ChannelConverter def get_geo_from_mag(mag): - pass + """Convert a stream to geographic coordinate system. + + Parameters + ---------- + stream : obspy.core.Stream + stream containing observatory components H, D, Z, and F. + + Returns + ------- + obspy.core.Stream + new stream object containing geographic components X, Y, Z, and F. + """ + h = mag.select(channel='H')[0] + d = mag.select(channel='D')[0] + z = mag.select(channel='Z')[0] + f = mag.select(channel='F')[0] + mag_h = h.data + mag_d = d.data + (geo_x, geo_y) = ChannelConverter.get_geo_from_mag(mag_h, mag_d) + return obspy.core.Stream(( + __get_trace('X', h.stats, geo_x), + __get_trace('Y', d.stats, geo_y), + z, f)) def get_geo_from_obs(obs): @@ -33,7 +55,29 @@ def get_geo_from_obs(obs): def get_mag_from_geo(geo): - pass + """Convert a stream to magnetic coordinate system. + + Parameters + ---------- + geo: obspy.core.Stream + stream containing observatory components X, Y, Z, and F. + + Returns + ------- + obspy.core.Stream + new stream object containing magnetic components H, D, Z, and F. + """ + x = geo.select(channel='X')[0] + y = geo.select(channel='Y')[0] + z = geo.select(channel='Z')[0] + f = geo.select(channel='F')[0] + geo_x = x.data + geo_y = y.data + (mag_h, mag_d) = ChannelConverter.get_mag_from_geo(geo_x, geo_y) + return obspy.core.Stream(( + __get_trace('H', x.stats, mag_h), + __get_trace('D', y.stats, mag_d), + z, f)) def get_mag_from_obs(obs): @@ -50,22 +94,22 @@ def get_mag_from_obs(obs): new stream object containing magnetic components H, D, Z, and F. """ h = obs.select(channel='H')[0] - d = __get_obs_d_from_obs(obs) + e = __get_obs_e_from_obs(obs) z = obs.select(channel='Z')[0] f = obs.select(channel='F')[0] obs_h = h.data - obs_d = d.data + obs_e = e.data d0 = ChannelConverter.get_radians_from_minutes( - numpy.float64(d.stats['DECBAS']) / 10) - (mag_h, mag_d) = ChannelConverter.get_mag_from_obs(obs_h, obs_d, d0) + numpy.float64(e.stats['DECBAS']) / 10) + (mag_h, mag_d) = ChannelConverter.get_mag_from_obs(obs_h, obs_e, d0) return obspy.core.Stream(( __get_trace('H', h.stats, mag_h), - __get_trace('D', d.stats, mag_d), + __get_trace('D', e.stats, mag_d), z, f)) -def get_obs_from_geo(geo, include_e=False): - """Convert a stream to geographic coordinate system. +def get_obs_from_geo(geo, include_d=False): + """Convert a stream to observatory coordinate system. Parameters ---------- @@ -79,15 +123,72 @@ def get_obs_from_geo(geo, include_e=False): obspy.core.Stream new stream object containing observatory components H, D, E, Z, and F. """ - return get_obs_from_mag(get_mag_from_geo(geo)) + return get_obs_from_mag(get_mag_from_geo(geo), include_d) + + +def get_obs_from_mag(mag, include_d=False): + """Convert a stream to magnetic observatory coordinate system. + + Parameters + ---------- + stream: obspy.core.Stream + stream containing magnetic components H, D, Z, and F. + include_e: boolean + whether to also include the observatory E component + + Returns + ------- + obspy.core.Stream + new stream object containing observatory components H, D, E, Z, and F + """ + h = mag.select(channel='H')[0] + d = mag.select(channel='D')[0] + z = mag.select(channel='Z')[0] + f = mag.select(channel='F')[0] + mag_h = h.data + mag_d = d.data + d0 = ChannelConverter.get_radians_from_minutes( + numpy.float64(d.stats['DECBAS']) / 10) + (obs_h, obs_e) = ChannelConverter.get_obs_from_mag(mag_h, mag_d, d0) + traces = ( + __get_trace('H', h.stats, obs_h), + __get_trace('E', d.stats, obs_e), + z, f) + if include_d: + obs_d = ChannelConverter.get_obs_d_from_obs(obs_h, obs_e) + traces = traces + (__get_trace('D', d.stats, obs_d),) + return obspy.core.Stream(traces) -def get_obs_from_mag(mag, include_e=False): - # TODO - obs = obspy.core.Stream() + +def get_obs_from_obs(obs, include_e=False, include_d=False): + """Fill in the observatory parameters as requested + + Parameters + ---------- + stream: obspy.core.Stream + stream containing the observatory components H, D of E, Z, and F. + include_e: boolean + whether to include the e component + include_d: boolean + whether to include the d component + + Returns + ------- + obspy.core.Stream + new stream object containing observatory components H, D, E, Z, and F + """ + h = obs.select(channel='H')[0] + z = obs.select(channel='Z')[0] + f = obs.select(channel='F')[0] + traces = (h, z, f) + if include_d: + d = __get_obs_d_from_obs(obs) + traces = traces + (d, ) if include_e: - obs += __get_obs_e_from_obs(obs) - return obs + e = __get_obs_e_from_obs(obs) + traces = traces + (e, ) + return obspy.core.Stream(traces) def __get_trace(channel, stats, data): diff --git a/geomagio/StreamConverter_test.py b/geomagio/StreamConverter_test.py new file mode 100644 index 0000000000000000000000000000000000000000..64667c5b58019b9671d221a2cb50c6dacbb248ff --- /dev/null +++ b/geomagio/StreamConverter_test.py @@ -0,0 +1,313 @@ +"""Unit Tests for StreamConverter + +Notes +----- + +We are using triangle identities for variables to test with. Specifically + the hypotenuse is normally equal to 1, causing the adjacent angle length + to be cos(angle) and the opposite length to be sin(angle) + +For more info on the components see the Notes in ChannelConverterTest.py. +""" +import obspy.core +import numpy +import StreamConverter +import ChannelConverter + +assert_equals = numpy.testing.assert_equal +assert_almost_equals = numpy.testing.assert_almost_equal + +cos = numpy.cos +sin = numpy.sin + +D2R = numpy.pi / 180 +D2I = 60 * 10 # Degrees to Iaga Decbas +STARTTIME = obspy.core.UTCDateTime('2014-11-01') + + +def test_get_geo_from_mag(): + """geomag.StreamConverter_test.test_get_geo_from_mag() + + The magnetic north stream containing the traces ''h'', ''d'', ''z'', and + ''f'' converts to the geographics stream containing the traces ''x'', + ''y'', ''z'' and ''f'' + """ + mag = obspy.core.Stream() + + # Call get_geo_from_magusing a decbas of 15 degrees, and streams with + # H = [1, 1], and D = [15 degrees, 30 degrees], expect streams of + # X = [cos(15), cos(30)] and Y = [sin(15), sin(30)] + # stats.DECBAS = 15 * D2I + mag += __create_trace('H', [1, 1]) + mag += __create_trace('D', [15 * D2R, 30 * D2R]) + mag += __create_trace('Z', [1, 1]) + mag += __create_trace('F', [1, 1]) + geo = StreamConverter.get_geo_from_mag(mag) + X = geo.select(channel='X')[0].data + Y = geo.select(channel='Y')[0].data + assert_equals(X, [cos(15 * D2R), cos(30 * D2R)], + 'Expect X to equal [cos(15), cos(30)]', True) + assert_equals(Y, [sin(15 * D2R), sin(30 * D2R)], + 'Expect Y to equal [sin(15), sin(30)]', True) + + +def test_get_geo_from_obs(): + """geomag.StreamConverter_test.test_get_geo_from_obs() + + The observatory stream containing the observatory traces + ''h'', ''d'' or ''e'', ''z'', and ''f'' converts to the geographic + stream containing the traces ''x'', ''y'', ''z'', and ''f'' + """ + obs = obspy.core.Stream() + + # 1) Call get_geo_from_obs using equal h, e streams with a decbas of 0 + # the geographic stream values X, Y will be the same. + obs += __create_trace('H', [1]) + obs += __create_trace('E', [1]) + obs += __create_trace('Z', [1]) + obs += __create_trace('F', [1]) + geo = StreamConverter.get_geo_from_obs(obs) + X = geo.select(channel='X')[0].data + Y = geo.select(channel='Y')[0].data + assert_almost_equals(X[0], 1, 9, + 'Expect X to almost equal 1', True) + assert_almost_equals(Y[0], 1, 9, + 'Expect Y to almost equal 1', True) + + # 2) Call get_geo_from_obs using a decbas of 15 degrees, and streams + # with H = [cos(15), cos(30)], and E = [sin(15), sin(30)]. + # Expect streams of X = [cos(30), cos(45)] and Y = sin(30), sin(45) + obs = obspy.core.Stream() + DECBAS = 15 * D2I + obs += __create_trace('H', [cos(15 * D2R), cos(30 * D2R)], DECBAS) + obs += __create_trace('E', [sin(15 * D2R), sin(30 * D2R)], DECBAS) + obs += __create_trace('Z', [1, 1], DECBAS) + obs += __create_trace('F', [1, 1], DECBAS) + geo = StreamConverter.get_geo_from_obs(obs) + X = geo.select(channel='X')[0].data + Y = geo.select(channel='Y')[0].data + assert_equals(X, [cos(30 * D2R), cos(45 * D2R)], + 'Expect X to equal [cos(30), cos(45)]', True) + assert_equals(Y, [sin(30 * D2R), sin(45 * D2R)], + 'Expect Y to equal [sin(30), sin(45)]', True) + + +def test_get_mag_from_geo(): + """geomag.StreamConverter_test.test_get_mag_from_geo() + + The geographic stream containing the traces ''x'', ''y'', ''z'', and + ''f'' converts to the magnetic stream containing the traces + ''h'', ''d'', ''z'' and ''f''. + """ + geo = obspy.core.Stream() + + # Call get_mag_from_geo using a decbas of 15, a X stream of + # [cos(15), cos(30)], and a Y stream of [sin(15), sin(30)]. + # Expect a H stream of [1,1] and a D strem of [15 degrees, 30 degrees] + DECBAS = 15 * D2I + geo += __create_trace('X', [cos(15 * D2R), cos(30 * D2R)], DECBAS) + geo += __create_trace('Y', [sin(15 * D2R), sin(30 * D2R)], DECBAS) + geo += __create_trace('Z', [1, 1], DECBAS) + geo += __create_trace('F', [1, 1], DECBAS) + mag = StreamConverter.get_mag_from_geo(geo) + H = mag.select(channel='H')[0].data + D = mag.select(channel='D')[0].data + assert_equals(H, [1, 1], + 'Expect H to equal [1,1]', True) + assert_equals(D, [15 * D2R, 30 * D2R], + 'Expect D to equal [15 degrees, 30 degrees]', True) + + +def test_get_mag_from_obs(): + """geomag.StreamConverter_test.test_get_mag_from_obs() + + The observatory stream containing the traces ''h'', ''e'' or ''d'', + ''z'' and ''f'' + """ + obs = obspy.core.Stream() + + # Call get_mag_from_obs using a DECBAS of 15 degrees, a H stream of + # [cos(15), cos(30)] and a E stream of [sin(15), sin(30)]. + # Expect a H stream of [1, 1] and a D stream of [30 degrees, 45 degrees] + DECBAS = 15 * D2I + obs += __create_trace('H', [cos(15 * D2R), cos(30 * D2R)], DECBAS) + obs += __create_trace('E', [sin(15 * D2R), sin(30 * D2R)], DECBAS) + obs += __create_trace('Z', [1, 1], DECBAS) + obs += __create_trace('F', [1, 1], DECBAS) + mag = StreamConverter.get_mag_from_obs(obs) + H = mag.select(channel='H')[0].data + D = mag.select(channel='D')[0].data + assert_equals(H, [1, 1], + 'Expect H to equal [1,1]', True) + assert_equals(D, [30 * D2R, 45 * D2R], + 'Expect D to equal [30 degrees, 45 degrees]', True) + + +def test_get_obs_from_geo(): + """geomag.StreamConverter_test.test_get_obs_from_geo() + + The geographic stream containing the traces ''x'', ''y'', ''z'', and + ''f'' converts to the observatory stream containing the traces + ''h'', ''d'' or ''e'', ''z'', and ''f''. + """ + geo = obspy.core.Stream() + + # Call get_geo_from_obs using a decbas of 15, a X stream of + # [cos(30), cos(45)], and a Y stream of [sin(30), sin(45)]. + # Expect a H stream of [cos(15), cos(30)] and a + # E stream of [sin(15), sin(30)] + DECBAS = 15 * D2I + geo += __create_trace('X', [cos(30 * D2R), cos(45 * D2R)], DECBAS) + geo += __create_trace('Y', [sin(30 * D2R), sin(45 * D2R)], DECBAS) + geo += __create_trace('Z', [1, 1], DECBAS) + geo += __create_trace('F', [1, 1], DECBAS) + obs = StreamConverter.get_obs_from_geo(geo, True) + H = obs.select(channel='H')[0].data + E = obs.select(channel='E')[0].data + D = obs.select(channel='D')[0].data + assert_almost_equals(H, [cos(15 * D2R), cos(30 * D2R)], 9, + 'Expect H to equal [cos(15), cos(30)]', True) + assert_almost_equals(E, [sin(15 * D2R), sin(30 * D2R)], 9, + 'Expect E to equal [sin(15), sin(30)', True) + assert_almost_equals(D, [15 * D2R, 30 * D2R], 9, + 'Expect D to equal [15 degress, 30 degrees]', True) + + +def test_get_obs_from_mag(): + """geomag.StreamConverter_test.test_get_obs_from_mag() + + The magnetic stream containing the traces ''h'', ''d'', ''z'', and ''f'' + converts to the observatory stream containing the traces + ''h'', ''e'' and/or ''d'', ''z'', and ''f'' + """ + mag = obspy.core.Stream() + + # Call get_obs_from_mag using a decbas of 15, a H stream of [1,1], + # and a D stream of [30 degrees, 45 degrees]. Expect a H stream + # of [cos(15), cos(30)], a D stream of [30 degrees, 45 degrees], + # and a E stream of [sin(15), sin(30)] + DECBAS = 15 * D2I + mag += __create_trace('H', [1, 1], DECBAS) + mag += __create_trace('D', [30 * D2R, 45 * D2R], DECBAS) + mag += __create_trace('Z', [1, 1], DECBAS) + mag += __create_trace('F', [1, 1], DECBAS) + obs = StreamConverter.get_obs_from_mag(mag, True) + H = obs.select(channel='H')[0].data + D = obs.select(channel='D')[0].data + E = obs.select(channel='E')[0].data + assert_almost_equals(H, [cos(15 * D2R), cos(30 * D2R)], 9, + 'Expect H to equal [cos(15), cos(30)', True) + assert_almost_equals(D, [15 * D2R, 30 * D2R], 9, + 'Expect D to equal [15 degrees, 30 degrees', True) + assert_almost_equals(E, [sin(15 * D2R), sin(30 * D2R)], 9, + 'Expect E to equal [sin(15), sin(30)', True) + + +def test_get_obs_from_obs(): + """geomag.StreamConverter_test.test_get_obs_from_obs() + + The observatory stream can contain either ''d'' or ''e'' depending + on it's source. get_obs_from_obs will return either or both as part + of the obs Stream. + """ + + # 1) Call get_obs_from_obs using a decbas of 15, a H stream of + # [cos(15), cos(30)], and a E stream of [sin(15), sin(30)]. + # Expect a D stream of [15 degrees, 30 degrees] + obs_e = obspy.core.Stream() + DECBAS = 15 * D2I + obs_e += __create_trace('H', [cos(15 * D2R), cos(30 * D2R)], DECBAS) + obs_e += __create_trace('E', [sin(15 * D2R), sin(30 * D2R)], DECBAS) + obs_e += __create_trace('Z', [1, 1], DECBAS) + obs_e += __create_trace('F', [1, 1], DECBAS) + obs_D = StreamConverter.get_obs_from_obs(obs_e, False, True) + d = obs_D.select(channel='D')[0].data + assert_almost_equals(d, [15 * D2R, 30 * D2R], 9, + 'Expect D to equal [15 degrees, 30 degrees]', True) + + # 2) Call get_obs_from_obs using a decbase of 15 degrees, a H stream of + # [cos(15), cos(30)], and a D stream of [15, 30]. + # Expect a D stream of [sin(15), sin(30)] + obs_d = obspy.core.Stream() + obs_d += __create_trace('H', [cos(15 * D2R), cos(30 * D2R)], DECBAS) + obs_d += __create_trace('D', [15 * D2R, 30 * D2R], DECBAS) + obs_d += __create_trace('Z', [1, 1], DECBAS) + obs_d += __create_trace('F', [1, 1], DECBAS) + obs_E = StreamConverter.get_obs_from_obs(obs_d, True, False) + e = obs_E.select(channel='E')[0].data + assert_almost_equals(e, [sin(15 * D2R), sin(30 * D2R)], 9, + 'Expect E to equal [sin(15), sin(30)', True) + + +def test_verification_data(): + """ + This is a verification test of data done with different + converters, to see if the same result is returned. + Since the small angle approximation was used in the other + converters, AND round off was done differently, we can't + get the exact results. + Change the precision in assert_almost_equals to larger precision + (ie 2 to 8) to see how off the data is. Most are well within + expectations. + """ + DECBAS = 552.7 + obs_v = obspy.core.Stream() + obs_v += __create_trace('H', + [20889.55, 20889.57, 20889.74, 20889.86, 20889.91, 20889.81], DECBAS) + obs_v += __create_trace('E', + [-21.10, -20.89, -20.72, -20.57, -20.39, -20.12], DECBAS) + obs_v += __create_trace('Z', + [47565.29, 47565.34, 47565.39, 47565.45, 47565.51, 47565.54], DECBAS) + obs_v += __create_trace('F', + [52485.77, 52485.84, 52485.94, 52486.06, 52486.11, 52486.10], DECBAS) + obs_V = StreamConverter.get_obs_from_obs(obs_v, True, True) + d = obs_V.select(channel='D')[0].data + d = ChannelConverter.get_minutes_from_radians(d) + # Using d values calculated using small angle approximation. + assert_almost_equals(d, + [-3.47, -3.43, -3.40, -3.38, -3.35, -3.31], 2, + 'Expect d to equal [-3.47, -3.43, -3.40, -3.38, -3.35, -3.31]', True) + + mag = obspy.core.Stream() + DECBAS = 552.7 + mag += __create_trace('H', + [20884.04, 20883.45, 20883.38, 20883.43, 20883.07, 20882.76], DECBAS) + d = ChannelConverter.get_radians_from_minutes( + [556.51, 556.52, 556.56, 556.61, 556.65, 556.64]) + mag += __create_trace('D', d, DECBAS) + mag += __create_trace('Z', + [48546.90, 48546.80, 48546.80, 48546.70, 48546.80, 48546.90], DECBAS) + mag += __create_trace('F', + [0.10, 0.00, 0.10, 0.00, 0.00, 0.00, 0.00], DECBAS) + geo = StreamConverter.get_geo_from_mag(mag) + X = geo.select(channel='X')[0].data + Y = geo.select(channel='Y')[0].data + assert_almost_equals(X, + [20611.00, 20610.40, 20610.30, 20610.30, 20609.90, 20609.60], 2) + assert_almost_equals(Y, + [3366.00, 3366.00, 3366.20, 3366.50, 3366.70, 3366.60], 1) + + +def __create_trace(channel, data, decbase=0): + """ + Utility to create a trace containing the given numpy array. + + Parameters + ---------- + channel: string + The name of the trace being created. + data: array + The array to be inserted into the trace. + + Returns + ------- + obspy.core.Stream + Stream containing the channel. + """ + stats = obspy.core.Stats() + stats.starttime = STARTTIME + stats.sampling_rate = 0.0166666666667 + stats.DECBAS = decbase + stats.channel = channel + numpy_data = numpy.array(data, dtype=numpy.float64) + return obspy.core.Trace(numpy_data, stats) diff --git a/geomagio/iaga2002/IAGA2002Factory.py b/geomagio/iaga2002/IAGA2002Factory.py index 849643794d84e89412aa87e791dd77470f9243f6..32e70c16df367ba30de6f03c4b44812d1629a8e7 100644 --- a/geomagio/iaga2002/IAGA2002Factory.py +++ b/geomagio/iaga2002/IAGA2002Factory.py @@ -6,6 +6,7 @@ import os from geomagio import TimeseriesFactory, TimeseriesFactoryException from IAGA2002Parser import IAGA2002Parser from IAGA2002Writer import IAGA2002Writer +from geomagio import ChannelConverter # pattern for iaga 2002 file names @@ -103,14 +104,15 @@ class IAGA2002Factory(TimeseriesFactory): timeseries = obspy.core.Stream() for day in days: url = self._get_url(observatory, day, type, interval) - timeseries += self._parse_url(url) + iagaFile = read_url(url) + timeseries += self.parse_file(iagaFile) # merge channel traces for multiple days timeseries.merge() # trim to requested start/end time timeseries.trim(starttime, endtime) return timeseries - def _parse_url(self, url): + def parse_file(self, iagaFile): """Parse the contents of a url to an IAGA2002 file. Parameters @@ -124,7 +126,7 @@ class IAGA2002Factory(TimeseriesFactory): parsed data. """ parser = IAGA2002Parser() - parser.parse(read_url(url)) + parser.parse(iagaFile) headers = parser.headers station = headers['IAGA CODE'] comments = tuple(parser.comments) @@ -143,6 +145,9 @@ class IAGA2002Factory(TimeseriesFactory): stats.network = 'IAGA' stats.station = station stats.channel = channel + if stats.channel == 'D': + data[channel] = ChannelConverter.get_radians_from_minutes( + data[channel]) stream += obspy.core.Trace(data[channel], stats) return stream diff --git a/geomagio/iaga2002/IAGA2002Writer.py b/geomagio/iaga2002/IAGA2002Writer.py index a36d6108b04b6536fa9dbe793935420c42e18853..572f905f33777f0f1b70c94bd03dca7209ee3510 100644 --- a/geomagio/iaga2002/IAGA2002Writer.py +++ b/geomagio/iaga2002/IAGA2002Writer.py @@ -1,6 +1,6 @@ from cStringIO import StringIO -from geomagio import TimeseriesFactoryException +from geomagio import TimeseriesFactoryException, ChannelConverter import numpy import IAGA2002Parser import textwrap @@ -105,6 +105,9 @@ class IAGA2002Writer(object): list and order of channel values to output. """ buf = [] + if timeseries.select(channel='D'): + d = timeseries.select(channel='D') + d[0].data = ChannelConverter.get_minutes_from_radians(d[0].data) traces = [timeseries.select(channel=c)[0] for c in channels] starttime = float(traces[0].stats.starttime) delta = traces[0].stats.delta