SEP-0007 - Lightcurve Factory Refactor
|title||Lightcurve Factory Refactor|
We all knew this day was coming, Lightcurve cannot escape the spotlight any longer. Lightcurve moves away from conditional dispatch to a Factory based creation system so that it behaves like Map.
This proposal makes an API change, which will move LightCurve to follow the API of the Map submodule. This will provide end users a consistent interface submodules and allow for cleaner and easier to read code for developers, much like the map refactor did for the map submodule. Also it will seperate the interests of the Lightcruve module, into the core datatype and the data downloaders which belong in the net submodule.
- PR #729 The update to the base factory class, currently used for Map.
- PR #896 The work in progress implementation of this SEP.
A factory instance (as proposed in #729) called LightCurve will be available in
the top level of the
sunpy.lightcurve which will allow creation of all
registered LightCurve subclasses with the following API:
def LightCurve(*args, source=None, concatenate=True, **kwargs): """ Parameters ---------------- filename: string or File A file to read. source: string A string identifier for a registered subclass, matched by that subclasses `_is_source_for` method. concatenate : boolean Concatenate all files into one Lightcurve object if True, or return one Lightcurve for each file if False. All other keywords are passed to _is_source_for and then __init__. """
This factory will be able to create lightcurves from one or multiple files,
with the multiple file behavior being determined by the
- Create a LightCurve from a file, not-autodetected:
>>> my_lc = LightCurve('filename.csv', source='goes')
- Create a LightCurve from a file understood by sunpy.io:
>>> my_lc = LightCurve('filename.fits')
- URLs are handled just like files, they are downloaded to the data dir:
>>> my_lc = LightCurve(url) >>> my_lc = LightCurve(url, url, source='goes', concatenate=True)
- Extra keyword arguments are passed to the
>>> my_lc = LightCurve('lyrafile.fits', source='lyra', date_events=[x,y,z])
- Multiple files can be combined into one LightCurve, as long as they are the same source:
>>> my_lc = LightCurve(['goesfile1.fits', 'goesfile2.fits'], concatenate=True)
Which can then be cropped to a timerange:
>>> my_lc = LightCurve(['myfile1.fits', 'myfile2.fits']).truncate(atimerange)
LightCurve parsing order:
- Expand any iterable objects.
- Attempt to read with
- Parse metadata to
_is_source_forand find relevant subclass
- Create that LightCurve.
- Parse metadata to
- Match ‘source’ flag to subclass and get subclass to read file:
- return data, meta pair, create instance.
- Other kwargs are processed and passed to subclass class method for returning
Required class methods:
- Parse specific data files that cannot be read by the
sunpy.iomodule, i.e. CSV or ASCII files. Class Method named
_parse_filetaking a filename and
**kwargswhich returns a
- Provide a
_is_source_forwhich if possible auto detects the data type from a (data, meta) pair, and also matches string names for the subclass i.e. 'goes' or 'lyra', which will be passed into the factory to specify type for download etc.
None, due to the current implementation of LightCurve it will be very hard to
maintain backwards compatibility.
It may be possible to implement a
.create() method that calls the Factory,
however I would not recommend it.
Accepted at the board meeting on 2015-12-07 by a vote of 6-0