atomica.utils¶
Define utility classes used throughout Atomica
Functions
evaluate_plot_string (plot_string) 
Evaluate a plotting output specification 
format_duration (t[, pluralize]) 
Userfriendly string format of a duration 
nested_loop (inputs, loop_order) 
Zip list of lists in order 
parent_dir () 
Classes
NDict (*args, **kwargs) 
Store and sync items with a name property 
NamedItem ([name]) 

TimeSeries ([t, vals, units, assumption, sigma]) 
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 assumption  sigma (
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 notReturn 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

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

has_time_data
¶ Check if timespecific data has been provided
Unlike
has_data
, this will returnFalse
if only an assumption has been enteredReturn 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 assumption  v – Value to insert. If
None
, this function will return immediately without doing anything
Return type: None
 t – Time value to insert or update. If

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 points  If 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 assumptionReturn 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 years  pluralize – 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'
 t (

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.