Welcome To Quantities
After getting the TimeSeries factory working and proving the TimeSeries functionality works with real data it was time to implement another of the key features missing from the old LightCurve class.
--- Queue Drumroll---
AstroPy Quantity support!
With the rest of SunPy moving to support astropy Quantities, that allows for the easy conversion of data from one unit to another the LightCurve was starting to look pretty dated.In the TimeSeries class I included space for a units dictionary, the basic design would use it to store a series of key/value pairs, where the key matches the column name/title and the value is the associated unit. This would give us rudimentary unit functionality without modifying the Pandas DataFrame class (which would be a very complex task) and we can easily integrate this into other functions to allow more easy access.
To implement this there were a number of changes that needed
to be made, firstly I needed to manually define the units for each column in an
instruments source files, next I needed to add the ability for the parse_file
methods to send the units dictionary out to the factory and for the
constructors to include it.
This gave me working units for the TimeSeries instrument data.
This gave me working units for the TimeSeries instrument data.
Manually Creating TimeSeries Objects
Something that hadn’t been fully implemented was the ability
to manually create a TimeSeries given some source data. To fix this I needed to
change the code I permanently burrowed from the Map Factory to adjust for the
differences of a time series.
Firstly the time series is more likely to take a pandas DataFrame object then an array for the data. In-fact, after a discussion with my supervisors it was decided that it’d be sensible to accept the data as an Numpy Array, DataFrame or astropy Table. This is pretty easy as pandas includes code for using arrays and the Table class has a to_pandas method.
Firstly the time series is more likely to take a pandas DataFrame object then an array for the data. In-fact, after a discussion with my supervisors it was decided that it’d be sensible to accept the data as an Numpy Array, DataFrame or astropy Table. This is pretty easy as pandas includes code for using arrays and the Table class has a to_pandas method.
The units will also often be included, ideally as an optional
argument. This means that I needed a way to check a dictionary is a valid
units dictionary and so I created a _validate_units method in the factory.
So with these changes made we have the ability to make TimeSeries using any arbitrary data:
So with these changes made we have the ability to make TimeSeries using any arbitrary data:
>>> a = [1, 4, 5]
>>> b = [2.0, 5.0, 8.2]
>>> c = ['x', 'y', 'z']
>>> t = Table([a, b, c], names=('a', 'b', 'c'), meta={'name':
'first table'})
>>> df = t.to_pandas()
>>> ts_from_table = sunpy.timeseries.TimeSeries(t,{})
>>> ts_from_df = sunpy.timeseries.TimeSeries(df,{})
In this case units are extracted from the astropy Table, but
otherwise you can manually specify using the units kwarg:
>>> units = OrderedDict([('a', u.Unit("ct")),
('b', u.Unit("ct")),
('c',
u.Unit("ct"))])
>>> ts_from_df = sunpy.timeseries.TimeSeries(df,{} , units)
We can peek this:
>>> ts_from_table.peek()
>>> ts_from_table.peek()
The quantity(col_name) Method
With this units data stored in the TimeSeries, we could then
implement a method like the quantity property that allows you to extract a
column of values from an astropy Table as an astropy Quantity object.
For a TimeSeries this can be done as:
For a TimeSeries this can be done as:
ts_from_table = ts_eve.quantity(‘b')
print(qua)