atomica.utils¶
Define utility classes used throughout Atomica
Functions

Evaluate a plotting output specification 

Userfriendly string format of a duration 

Zip list of lists in order 
Classes

Store and sync items with a name property 



Class to store timeseries data 

class
atomica.utils.
TimeSeries
(t=None, vals=None, units=None, assumption=None, sigma=None)[source]¶ Class to store timeseries data
Internally values are stored as lists rather than numpy arrays because insert/remove operations on lists tend to be faster (and working with sparse data is a key role of TimeSeries objects). Note that methods like
interpolate()
return numpy arrays, so the output types from such functions should generally match up with what is required by the calling function. Parameters
t – Optionally specify a scalar, list, or array of time values
vals – Optionally specify a scalar, list, or array of values (must be same size as
t
)units (
Optional
[str
]) – Optionally specify units (as a string)assumption (
Optional
[float
]) – Optionally specify a scalar assumptionsigma (
Optional
[float
]) – Optionally specify a scalar uncertainty

_sampled
= None¶ Flag to indicate whether sampling has been performed. Once sampling has been performed, cannot sample again

assumption
= None¶ The timeindependent scalar assumption

get
(t)[source]¶ Retrieve value at a particular time
This function will automatically retrieve the value of the assumption if no time specific values have been provided, or if any time specific values are provided, will return the value entered at that time. If time specific values have been entered and the requested time is not explicitly present, an error will be raised.
This function may be deprecated in future because generally it is more useful to either call
TimeSeries.interpolate()
if interested in getting values at arbitrary times, orTimeSeries.get_arrays()
if interested in retrieving values that have been entered. Parameters
t – A time value. If
None
, will return assumption regardless of whether time data has been entered or not Return type
float
 Returns
The value at the corresponding time. Returns None if the value no value present

get_arrays
()[source]¶ Return arrays with the contents of this TimeSeries
The TimeSeries instance may have time values, or may simply have an assumption. If obtaining raw arrays is desired, this function will return arrays with values extracted from the appropriate attribute of the TimeSeries. However, in general, it is usually .interpolate() that is desired, rather than .get_arrays()
 Returns
Tuple with two arrays  the first item is times (with a single NaN if the TimeSeries only has an assumption) and the second item is values

property
has_data
¶ Check if any data has been provided
 Return type
bool
 Returns
True
if any data has been entered (assumption or timespecific)

property
has_time_data
¶ Check if timespecific data has been provided
Unlike
has_data
, this will returnFalse
if only an assumption has been entered Return type
bool
 Returns
True
if any timespecific data has been entered

insert
(t, v)[source]¶ Insert a value at a particular time
If the value already exists in the
TimeSeries
, it will be overwritten/updated. The arrays are internally sorted by time value, and this order will be maintained. Parameters
t – Time value to insert or update. If
None
, the value will be assigned to the assumptionv – Value to insert. If
None
, this function will return immediately without doing anything
 Return type
None

interpolate
(t2, method='linear', **kwargs)[source]¶ Return interpolated values
This method returns interpolated values from the time series at time points t2 according to a given interpolation method. There are 4 possibilities for the method
‘linear’  normal linear interpolation (with constant, zerogradient extrapolation)
‘pchip’  legacy interpolation with some curvature between points (with constant, zerogradient extrapolation)
‘previous’  stepped interpolation, maintain value until the next timepoint is reached (with constant, zerogradient extrapolation)
Interpolation class or generator function
That final option allows the use of arbitrary interpolation methods. The underlying call will be
c = method(t1, v1, **kwargs) return c(t2)
so for example, if you wanted to use the base Scipy pchip method with no extrapolation, then could pass in
>>> TimeSeries.interpolate(...,method=scipy.interpolate.PchipInterpolator)
Note that the following special behaviours apply:
If there is no data at all, this function will return
np.nan
for all requested time pointsIf only an assumption exists, this assumption will be returned for all requested time points
 Otherwise, arrays will be formed with all finite time values
If no finite time values remain, an error will be raised (in general, a TimeSeries should not store such values anyway)
If only one finite time value remains, then that value will be returned for all requested time points
Otherwise, the specified interpolation method will be used
 Parameters
t2 (<builtin function array>) – float, list, or array, with times
method – A string ‘linear’, ‘pchip’ or ‘stepped’ OR a callable item that returns an Interpolator
 Return type
<builtin function array>
 Returns
array the same length as t2, with interpolated values

remove
(t)[source]¶ Remove single time point
 Parameters
t – Time value to remove. Set to
None
to remove the assumption Return type
None

remove_after
(t_remove)[source]¶ Remove times from start
 Parameters
tval – Remove times up to but not including this time
 Return type
None

remove_before
(t_remove)[source]¶ Remove times from start
 Parameters
tval – Remove times up to but not including this time
 Return type
None

remove_between
(t_remove)[source]¶ Remove a range of times
Note that the endpoints are not included
 Parameters
t_remove – two element iterable e.g. array, with [min,max] times
 Return type
None

sample
(constant=True)[source]¶ Return a sampled copy of the TimeSeries
This method returns a copy of the TimeSeries in which the values have been perturbed based on the uncertainty value.
 Parameters
constant – If True, time series will be perturbed by a single constant offset. If False, an different perturbation will be applied to each time specific value independently.
 Returns
A copied
TimeSeries
with perturbed values

sigma
= None¶ Uncertainty value, assumed to be a standard deviation

units
= None¶ The units of the quantity

vals
= None¶ Timespecific values  indices correspond to
self.t

atomica.utils.
evaluate_plot_string
(plot_string)[source]¶ Evaluate a plotting output specification
The plots in the framework are specified as strings  for example,
>>> plot_string = "{'New active DSTB':['pd_div:flow','nd_div:flow']}"
This needs to be (safely) evaluated so that the actual dict can be used. This function evaluates a string like this and returns a variable accordingly. For example
>>> x = evaluate_plot_string("{'New active DSTB':['pd_div:flow','nd_div:flow']}")
is the same as
>>> x = {'New active DSTB':['pd_div:flow','nd_div:flow']}
This will only happen if tokens associated with dicts and lists are present  otherwise the original string will just be returned directly
 Parameters
plot_string (
str
) – A string representation of Python structures (e.g., lists, dicts) Returns
Evaluated expression, the same as if it has originally been entered in a .py file

atomica.utils.
format_duration
(t, pluralize=False)[source]¶ Userfriendly string format of a duration
This helper function is used when displaying durations in plots. It takes in a duration in units of years, and returns a string representation in userfriendly units. This function is mainly intended to be used to format denominators e.g., going from ‘probability’ and ‘1/365’ to ‘probability/day’
 Parameters
t (
float
) – A duration in units of yearspluralize – Always return a plural suffix
 Return type
str
 Returns
A string
Example usage:
>>> format_duration(1) 'year' >>> format_duration(1, pluralize=True) 'years' >>> format_duration(1/365) 'day' >>> format_duration(2/365) '2 days' >>> format_duration(1.5/52) '1.5 weeks' >>> format_duration(2/52) 'fortnight' >>> format_duration(2.5/12) '2.5 months'

atomica.utils.
nested_loop
(inputs, loop_order)[source]¶ Zip list of lists in order
This is used in
plot_bars()
to control whether ‘times’ or ‘results’ are the outer grouping. This function takes in a list of lists to iterate over, and their nesting order. It then yields tuples of items in the given order. Only tested for two levels (which are all that get used inplot_bars()
but in theory supports an arbitrary number of items. Parameters
inputs – List of lists. All lists should have the same length
loop_order – Nesting order for the lists
 Returns
Generator yielding tuples of items, one for each list
Example usage:
>>> list(nested_loop([['a','b'],[1,2]],[0,1])) [['a', 1], ['a', 2], ['b', 1], ['b', 2]]
Notice how the first two items have the same value for the first list while the items from the second list vary. If the loop_order is reversed, then:
>>> list(nested_loop([['a','b'],[1,2]],[1,0])) [['a', 1], ['b', 1], ['a', 2], ['b', 2]]
Notice now how now the first two items have different values from the first list but the same items from the second list.