Skip to content
Snippets Groups Projects
Commit ae2e33eb authored by Jeremy M Fee's avatar Jeremy M Fee
Browse files

Implement common TimeseriesFactory._put_timeseries method, integrate into IAGA factory

parent 50a03548
No related branches found
No related tags found
No related merge requests found
...@@ -84,13 +84,13 @@ class TimeseriesFactory(object): ...@@ -84,13 +84,13 @@ class TimeseriesFactory(object):
""" """
raise NotImplementedError('"get_timeseries" not implemented') raise NotImplementedError('"get_timeseries" not implemented')
def parse_string(self, iaga2002String): def parse_string(self, data):
"""Parse the contents of a string in the format of an IAGA2002 file. """Parse the contents of a string in the format of an IAGA2002 file.
Parameters Parameters
---------- ----------
iaga2002String : str data : str
string containing IAGA2002 content. string containing parsable content.
Returns Returns
------- -------
...@@ -129,6 +129,20 @@ class TimeseriesFactory(object): ...@@ -129,6 +129,20 @@ class TimeseriesFactory(object):
""" """
raise NotImplementedError('"put_timeseries" not implemented') raise NotImplementedError('"put_timeseries" not implemented')
def write_file(self, fh, timeseries, channels):
"""Write timeseries data to the given file object.
Parameters
----------
fh : writable
file handle where data is written.
timeseries : obspy.core.Stream
stream containing traces to store.
channels : list
list of channels to store.
"""
raise NotImplementedError('"write_file" not implemented')
def _get_file_from_url(self, url): def _get_file_from_url(self, url):
"""Get a file for writing. """Get a file for writing.
...@@ -387,3 +401,61 @@ class TimeseriesFactory(object): ...@@ -387,3 +401,61 @@ class TimeseriesFactory(object):
raise TimeseriesFactoryException( raise TimeseriesFactoryException(
'Unsupported type "%s"' % type) 'Unsupported type "%s"' % type)
return type_name return type_name
def _put_timeseries(self, timeseries, starttime=None, endtime=None,
channels=None, type=None, interval=None):
"""A basic implementation of put_timeseries using write_file.
Parameters
----------
timeseries : obspy.core.Stream
stream containing traces to store.
starttime : UTCDateTime
time of first sample in timeseries to store.
uses first sample if unspecified.
endtime : UTCDateTime
time of last sample in timeseries to store.
uses last sample if unspecified.
channels : array_like
list of channels to store, optional.
uses default if unspecified.
type : {'definitive', 'provisional', 'quasi-definitive', 'variation'}
data type, optional.
uses default if unspecified.
interval : {'daily', 'hourly', 'minute', 'monthly', 'second'}
data interval, optional.
uses default if unspecified.
Raises
------
TimeseriesFactoryException
if any errors occur.
"""
if not self.urlTemplate.startswith('file://'):
raise TimeseriesFactoryException('Only file urls are supported')
channels = channels or self.channels
type = type or self.type
interval = interval or self.interval
stats = timeseries[0].stats
delta = stats.delta
observatory = stats.station
starttime = starttime or stats.starttime
endtime = endtime or stats.endtime
urlIntervals = Util.get_intervals(
starttime=starttime,
endtime=endtime,
size=self.urlInterval)
for urlInterval in urlIntervals:
url = self._get_url(
observatory=observatory,
date=urlInterval['start'],
type=type,
interval=interval,
channels=channels)
url_data = timeseries.slice(
starttime=urlInterval['start'],
# subtract delta to omit the sample at end: `[start, end)`
endtime=(urlInterval['end'] - delta))
url_file = Util.get_file_from_url(url, createParentDirectory=True)
with open(url_file, 'wb') as fh:
self.write_file(fh, url_data, channels)
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
import obspy.core import obspy.core
from .. import ChannelConverter from .. import ChannelConverter
from ..TimeseriesFactory import TimeseriesFactory from ..TimeseriesFactory import TimeseriesFactory
from ..TimeseriesFactoryException import TimeseriesFactoryException
from IAGA2002Parser import IAGA2002Parser from IAGA2002Parser import IAGA2002Parser
from IAGA2002Writer import IAGA2002Writer from IAGA2002Writer import IAGA2002Writer
...@@ -105,54 +104,6 @@ class IAGA2002Factory(TimeseriesFactory): ...@@ -105,54 +104,6 @@ class IAGA2002Factory(TimeseriesFactory):
stream += obspy.core.Trace(data[channel], stats) stream += obspy.core.Trace(data[channel], stats)
return stream return stream
def _get_days(self, starttime, endtime):
"""Get days between (inclusive) starttime and endtime.
Parameters
----------
starttime : obspy.core.UTCDateTime
the start time
endtime : obspy.core.UTCDateTime
the end time
Returns
-------
array_like
list of times, one per day, for all days between and including
``starttime`` and ``endtime``.
Raises
------
TimeseriesFactoryException
if starttime is after endtime
"""
if starttime > endtime:
raise TimeseriesFactoryException(
'starttime must be before endtime')
days = []
day = starttime
lastday = (endtime.year, endtime.month, endtime.day)
while True:
days.append(day)
if lastday == (day.year, day.month, day.day):
break
# move to next day
day = obspy.core.UTCDateTime(day.timestamp + 86400)
return days
def write_file(self, fh, timeseries, channels):
"""writes timeseries data to the given file object.
Parameters
----------
fh: file object
timeseries : obspy.core.Stream
stream containing traces to store.
channels : array_like
list of channels to store
"""
IAGA2002Writer().write(fh, timeseries, channels)
def put_timeseries(self, timeseries, starttime=None, endtime=None, def put_timeseries(self, timeseries, starttime=None, endtime=None,
channels=None, type=None, interval=None): channels=None, type=None, interval=None):
"""Store timeseries data. """Store timeseries data.
...@@ -177,42 +128,23 @@ class IAGA2002Factory(TimeseriesFactory): ...@@ -177,42 +128,23 @@ class IAGA2002Factory(TimeseriesFactory):
data interval, optional. data interval, optional.
uses default if unspecified. uses default if unspecified.
""" """
if not self.urlTemplate.startswith('file://'): return self._put_timeseries(
raise TimeseriesFactoryException('Only file urls are supported') timeseries=timeseries,
channels = channels or self.channels starttime=starttime,
type = type or self.type endtime=endtime,
interval = interval or self.interval channels=channels,
stats = timeseries[0].stats type=type,
observatory = stats.station interval=interval)
starttime = starttime or stats.starttime
endtime = endtime or stats.endtime def write_file(self, fh, timeseries, channels):
days = self._get_days(starttime, endtime) """writes timeseries data to the given file object.
for day in days:
day_filename = self._get_file_from_url(
self._get_url(observatory, day, type, interval))
day_timeseries = self._get_slice(timeseries, day, interval)
with open(day_filename, 'wb') as fh:
self.write_file(fh, day_timeseries, channels)
def _get_slice(self, timeseries, day, interval):
"""Get the first and last time for a day
Parameters Parameters
---------- ----------
fh: file object
timeseries : obspy.core.Stream timeseries : obspy.core.Stream
timeseries to slice stream containing traces to store.
day : UTCDateTime channels : array_like
time in day to slice list of channels to store
Returns
-------
obspy.core.Stream
sliced stream
""" """
day = day.datetime IAGA2002Writer().write(fh, timeseries, channels)
start = obspy.core.UTCDateTime(day.year, day.month, day.day, 0, 0, 0)
if interval == 'minute':
end = start + 86340.0
else:
end = start + 86399.999999
return timeseries.slice(start, end)
"""Tests for IAGA2002Factory."""
from geomagio.iaga2002 import IAGA2002Factory
from obspy.core.utcdatetime import UTCDateTime
from nose.tools import assert_equals
def test__get_days():
"""iaga2002_test.IAGA2002Factory_test.test__get_days()
Call the _get_days method with starttime and endtime separated by more
than one day.
Verify it returns all days between the given starttime and endtime.
"""
starttime = UTCDateTime('2014-01-01')
endtime = UTCDateTime('2014-01-07')
assert_equals(IAGA2002Factory()._get_days(starttime, endtime), [
UTCDateTime('2014-01-01'),
UTCDateTime('2014-01-02'),
UTCDateTime('2014-01-03'),
UTCDateTime('2014-01-04'),
UTCDateTime('2014-01-05'),
UTCDateTime('2014-01-06'),
UTCDateTime('2014-01-07')])
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment