Skip to content
Snippets Groups Projects
Commit e5d5f37a authored by emcwhirter-usgs's avatar emcwhirter-usgs
Browse files

Merge pull request #65 from jmfee-usgs/refactor-algorithm-arguments

Move algorithms to separate package, abstract algorithm arguments
parents ddbcbc71 2e6ee5d3
No related branches found
No related tags found
No related merge requests found
Showing
with 163 additions and 71 deletions
......@@ -6,7 +6,7 @@ and a scalar total-field measurement made by independent sensors. Read more
about the [DeltaF Algorithm](./DeltaF.md).
`geomag.py --deltaf {geo, obs, obsd}`
`geomag.py --algorithm deltaf [--deltaf-from {geo, obs, obsd}]`
### Reference Frames
......@@ -21,7 +21,7 @@ about the [DeltaF Algorithm](./DeltaF.md).
To compute DeltaF from HEZF data for Tucson observatory:
```
geomag.py \
--deltaf obs \
--algorithm deltaf \
--observatory TUC \
--type variation \
--interval minute \
......
......@@ -5,7 +5,7 @@ The XYZ Algorithm rotates between `geographic`, `observatory`, and `magnetic`,
channel orientations. Read more about the [XYZ Algorithm](./XYZ.md).
`geomag.py --xyz {geo, mag, obs, obsd} {geo, mag, obs, obsd}`
`geomag.py --algorithm xyz [--xyz-from {geo,mag,obs,obsd}] [--xyz-to {geo,mag,obs,obsd}]`
### Reference Frames
......@@ -30,7 +30,7 @@ There are 3 reference frames in this library.
To convert HEZF data in pcdcp files to XYZF for Tucson observatory for all of
March 2013 output to iaga2002 files:
geomag.py --xyz obs geo --observatory TUC \
geomag.py --algorithm xyz --observatory TUC \
--starttime 2013-03-01T00:00:00Z --endtime 2013-03-31T23:59:00Z \
--input-pcdcp-url file://data-pcdcp/./%(OBS)s%(year)s%(julian)s.%(i)s \
--output-iaga-url file://data-iaga/./$(obs)s%(Y)s%(j)s.%(i)s \
......
......@@ -44,11 +44,11 @@ Exception base class is `geomagio.TimeseriesFactoryException`.
## Algorithms
Base class is `geomagio.Algorithm`
Exception base class is `geomagio.AlgorithmException`
Base class is `geomagio.algorithm.Algorithm`
Exception base class is `geomagio.algorithm.AlgorithmException`
- Delta F `geomagio.DeltaFAlgorithm`
- XYZ `geomagio.XYZAlgorithm`
- Delta F `geomagio.algorithm.DeltaFAlgorithm`
- XYZ `geomagio.algorithm.XYZAlgorithm`
## Example
......@@ -60,7 +60,7 @@ The following example:
- Plots the data using matplotlib
```python
from geomagio import XYZAlgorithm
from geomagio.algorithm import XYZAlgorithm
from geomagio.edge import EdgeFactory
from obspy.core import UTCDateTime
......
......@@ -68,10 +68,12 @@ There are flags to specify certain algorithms should be run against the data.
#### XYZ ####
`--xyz {geo, mag, obs, obsd} {geo, mag, obs, obsd}`
`--algorithm xyz`
`--xyz-from {geo, mag, obs, obsd}` (default is `obs`)
`--xyz-to {geo, mag, obs, obsd}` (default is `geo`)
#### [XYZ Usage](./algorithms/XYZ_usage.md) ####
Rotate data from HEZ or HDZ to XYZ and back.
Rotate data from HEZ (obs) or HDZ (mag) to XYZ (geo) and back.
Extensive explanation of all input and output methods:
[IO Methods](./io.md)
......@@ -4,7 +4,7 @@
import argparse
import sys
from obspy.core import UTCDateTime
from Algorithm import Algorithm
from algorithm import algorithms
import TimeseriesUtility
from TimeseriesFactoryException import TimeseriesFactoryException
from Util import ObjectView
......@@ -14,9 +14,6 @@ import iaga2002
import pcdcp
import imfv283
from DeltaFAlgorithm import DeltaFAlgorithm
from XYZAlgorithm import XYZAlgorithm
class Controller(object):
"""Controller for geomag algorithms.
......@@ -301,17 +298,8 @@ def main(args):
else:
print >> sys.stderr, "Missing required output directive"
if args.xyz is not None:
algorithm = XYZAlgorithm(informat=args.xyz[0],
outformat=args.xyz[1])
elif args.deltaf is not None:
algorithm = DeltaFAlgorithm(informat=args.deltaf)
else:
# TODO get smarter on inchannels/outchannels since input doesn't always
# need to use the --inchannels argument, but might (as in iaga2002),
# get it from the file.
algorithm = Algorithm(inchannels=args.inchannels,
outchannels=args.outchannels or args.inchannels)
algorithm = algorithms[args.algorithm]()
algorithm.configure(args)
# TODO check for unused arguments.
......@@ -481,14 +469,11 @@ def parse_args(args):
help='Edge IP #. See --output-edge-* for other optional arguments')
# Algorithms group
algorithm_group = parser.add_mutually_exclusive_group()
algorithm_group.add_argument('--xyz',
nargs=2,
choices=['geo', 'mag', 'obs', 'obsd'],
help='Enter the geomagnetic orientation(s) you want to read from' +
' and to respectfully.')
algorithm_group.add_argument('--deltaf',
choices=['geo', 'obs', 'obsd'],
help='Enter the geomagnetic orientation you want to read from')
parser.add_argument('--algorithm',
choices=[k for k in algorithms],
default='default')
for k in algorithms:
algorithms[k].add_arguments(parser)
return parser.parse_args(args)
......@@ -4,19 +4,14 @@ Geomag Algorithm Module
import ChannelConverter
import StreamConverter
from Algorithm import Algorithm
from AlgorithmException import AlgorithmException
from Controller import Controller
from ObservatoryMetadata import ObservatoryMetadata
from TimeseriesFactory import TimeseriesFactory
from TimeseriesFactoryException import TimeseriesFactoryException
import TimeseriesUtility
import Util
from XYZAlgorithm import XYZAlgorithm
__all__ = [
'Algorithm',
'AlgorithmException',
'ChannelConverter',
'Controller',
'DeltaFAlgorithm',
......
"""Algorithm Interface."""
import TimeseriesUtility
from .. import TimeseriesUtility
class Algorithm(object):
......@@ -91,3 +91,25 @@ class Algorithm(object):
endtime < input_gap[2]):
return False
return True
@classmethod
def add_arguments(cls, parser):
"""Add command line arguments to argparse parser.
Parameters
----------
parser: ArgumentParser
command line argument parser
"""
pass
def configure(self, arguments):
"""Configure algorithm using comand line arguments.
Parameters
----------
arguments: Namespace
parsed command line arguments
"""
self._inchannels = arguments.inchannels
self._outchannels = arguments.outchannels or arguments.inchannels
......@@ -4,7 +4,7 @@
from Algorithm import Algorithm
from AlgorithmException import AlgorithmException
import StreamConverter as StreamConverter
from .. import StreamConverter
# List of channels by geomagnetic observatory orientation.
# geo represents a geographic north/south orientation
......@@ -27,10 +27,10 @@ class DeltaFAlgorithm(Algorithm):
will be converting from.
"""
def __init__(self, informat=None):
def __init__(self, informat='obs'):
Algorithm.__init__(self, inchannels=CHANNELS[informat],
outchannels=['G'])
self.informat = informat
self._informat = informat
def check_stream(self, timeseries):
"""checks a stream to make certain all the required channels
......@@ -61,10 +61,35 @@ class DeltaFAlgorithm(Algorithm):
"""
self.check_stream(timeseries)
out_stream = None
if self.informat == 'geo':
informat = self._informat
if informat == 'geo':
out_stream = StreamConverter.get_deltaf_from_geo(timeseries)
elif self.informat == 'obs' or self.informat == 'obsd':
elif informat == 'obs' or informat == 'obsd':
out_stream = StreamConverter.get_deltaf_from_obs(timeseries)
return out_stream
@classmethod
def add_arguments(cls, parser):
"""Add command line arguments to argparse parser.
Parameters
----------
parser: ArgumentParser
command line argument parser
"""
parser.add_argument('--deltaf-from',
choices=['geo', 'obs', 'obsd'],
default='obs',
help='Geomagnetic orientation to read from')
def configure(self, arguments):
"""Configure algorithm using comand line arguments.
Parameters
----------
arguments: Namespace
parsed command line arguments
"""
self._informat = arguments.deltaf_from
self._inchannels = CHANNELS[self._informat]
......@@ -5,7 +5,7 @@
from Algorithm import Algorithm
from AlgorithmException import AlgorithmException
import StreamConverter as StreamConverter
from .. import StreamConverter
# List of channels by geomagnetic observatory orientation.
# geo represents a geographic north/south orientation
......@@ -33,11 +33,11 @@ class XYZAlgorithm(Algorithm):
be converting to.
"""
def __init__(self, informat=None, outformat=None):
def __init__(self, informat='obs', outformat='geo'):
Algorithm.__init__(self, inchannels=CHANNELS[informat],
outchannels=CHANNELS[outformat])
self.informat = informat
self.outformat = outformat
self._informat = informat
self._outformat = outformat
def check_stream(self, timeseries):
"""checks an stream to make certain all the required channels
......@@ -69,36 +69,69 @@ class XYZAlgorithm(Algorithm):
"""
self.check_stream(timeseries)
out_stream = None
if self.outformat == 'geo':
if self.informat == 'geo':
informat = self._informat
outformat = self._outformat
if outformat == 'geo':
if informat == 'geo':
out_stream = timeseries
elif self.informat == 'mag':
elif informat == 'mag':
out_stream = StreamConverter.get_geo_from_mag(timeseries)
elif self.informat == 'obs' or self.informat == 'obsd':
elif informat == 'obs' or informat == 'obsd':
out_stream = StreamConverter.get_geo_from_obs(timeseries)
elif self.outformat == 'mag':
if self.informat == 'geo':
elif outformat == 'mag':
if informat == 'geo':
out_stream = StreamConverter.get_mag_from_geo(timeseries)
elif self.informat == 'mag':
elif informat == 'mag':
out_stream = timeseries
elif self.informat == 'obs' or self.informat == 'obsd':
elif informat == 'obs' or informat == 'obsd':
out_stream = StreamConverter.get_mag_from_obs(timeseries)
elif self.outformat == 'obs':
if self.informat == 'geo':
elif outformat == 'obs':
if informat == 'geo':
out_stream = StreamConverter.get_obs_from_geo(timeseries)
elif self.informat == 'mag':
elif informat == 'mag':
out_stream = StreamConverter.get_obs_from_mag(timeseries)
elif self.informat == 'obs' or self.informat == 'obsd':
elif informat == 'obs' or informat == 'obsd':
out_stream = StreamConverter.get_obs_from_obs(timeseries,
include_e=True)
elif self.outformat == 'obsd':
if self.informat == 'geo':
elif outformat == 'obsd':
if informat == 'geo':
out_stream = StreamConverter.get_obs_from_geo(timeseries,
include_d=True)
elif self.informat == 'mag':
elif informat == 'mag':
out_stream = StreamConverter.get_obs_from_mag(timeseries,
include_d=True)
elif self.informat == 'obs' or self.informat == 'obsd':
elif informat == 'obs' or informat == 'obsd':
out_stream = StreamConverter.get_obs_from_obs(timeseries,
include_d=True)
return out_stream
@classmethod
def add_arguments(cls, parser):
"""Add command line arguments to argparse parser.
Parameters
----------
parser: ArgumentParser
command line argument parser
"""
parser.add_argument('--xyz-from',
choices=['geo', 'mag', 'obs', 'obsd'],
default='obs',
help='Geomagnetic orientation to read from')
parser.add_argument('--xyz-to',
choices=['geo', 'mag', 'obs', 'obsd'],
default='geo',
help='Geomagnetic orientation to convert to')
def configure(self, arguments):
"""Configure algorithm using comand line arguments.
Parameters
----------
arguments: Namespace
parsed command line arguments
"""
self._informat = arguments.xyz_from
self._outformat = arguments.xyz_to
self._inchannels = CHANNELS[self._informat]
self._outchannels = CHANNELS[self._outformat]
"""
Geomag Algorithms module
"""
# base classes
from Algorithm import Algorithm
from AlgorithmException import AlgorithmException
# algorithms
from DeltaFAlgorithm import DeltaFAlgorithm
from XYZAlgorithm import XYZAlgorithm
# algorithms is used by Controller to auto generate arguments
algorithms = {
'identity': Algorithm,
'deltaf': DeltaFAlgorithm,
'xyz': XYZAlgorithm
}
__all__ = [
# base classes
'Algorithm',
'AlgorithmException',
# algorithms
'DeltaFAlgorithm',
'XYZAlgorithm'
]
......@@ -7,6 +7,7 @@ setup(
url='https://github.com/usgs/geomag-algorithms',
packages=[
'geomagio',
'geomagio.algorithm',
'geomagio.iaga2002',
'geomagio.imfv283',
'geomagio.edge',
......
#! /usr/bin/env python
from geomagio import Algorithm, Controller, TimeseriesFactory
from geomagio import Controller, TimeseriesFactory
from geomagio.algorithm import Algorithm
from nose.tools import assert_is_instance
......
......@@ -2,7 +2,7 @@
from obspy.core.stream import Stream
from nose.tools import assert_equals
from nose.tools import assert_is_instance
from geomagio import Algorithm
from geomagio.algorithm import Algorithm
def test_algorithm_process():
......
......@@ -2,8 +2,8 @@
from obspy.core.stream import Stream
from nose.tools import assert_equals
from nose.tools import assert_is
from geomagio import XYZAlgorithm
from StreamConverter_test import __create_trace
from geomagio.algorithm import XYZAlgorithm
from ..StreamConverter_test import __create_trace
def test_xyzalgorithm_process():
......
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