11.1. Auxiliary Readers — MDAnalysis.auxiliary
The auxiliary submodule contains code for reading ‘auxiliary’ data from a
trajectory and allowing alignment with trajectory timesteps. Additional
methods in MDAnalysis.coordinates.base.ProtoReader allow auxiliary data
to be added and read alongside a trajectory.
Auxiliary data are timeseries accompanying a trajectory not stored in the regular trajectory file to be read by the trajectory Reader. They may be stored internally (e.g. in an array) or read from a file. In general, auxiliary data is assumed to be time ordered and contain no duplicates.
11.1.1. Supported formats
Currently supported formats:
Reader
Format
Extension (if file)
Remarks
XVG
xvg
(default)
Produced by Gromacs during simulation or analysis. Reads full file on initialisation.
XVG-F
xvg
Alternate xvg file reader, reading each step from the file in turn for a lower memory footprint.
XVGReaderis the default reader for .xvg files.EDR
edr
Produced by Gromacs during simulation. Reads full file on initialisation
11.1.2. Auxiliary API
Auxiliary readers inherit from the base
AuxReader. In stand-alone use they
allow iteration over each step in a set of auxiliary data:
aux = MDAnalysis.auxiliary.XVG.XVGReader('auxdata.xvg')
for auxstep in aux:
print(auxstep)
To iterate over only certain sections of the auxiliary:
for auxstep in aux[100:200]:
# only steps 100-200
do_something(auxstep)
Or to skip steps:
for auxstep in aux[100::10]:
# every 10th step starting at 100
do_something(auxstep)
A base AuxFileReader is also provided,
extending AuxReader with attributes/methods
for when auxiliary data is to be read from a file by keeping the file open and
reading steps one-at-time as needed.
A get_auxreader_for() function is available to
return an appropriate AuxReader class for
a supplied format or set of auxiliary data, guessing the format from the
datatype/file extension:
auxreader = MDAnalysis.auxiliary.core.get_auxreader_for('auxdata.xvg')
# will return the default XVGReader class
auxreader = MDAnalysis.auxiliary.core.get_auxreader_for(format='XVG-F')
# will return the XVGFileReader class
To directly load an instance of the guessed auxiliary reader class given the
supplied auxdata and any additional auxiliary reader options, the
function auxreader() can be used:
aux = MDAnalysis.auxiliary.auxreader('auxdata.xvg', dt=2)
for auxstep in aux:
do_something(auxstep)
11.1.2.1. Auxiliaries and trajectories
For alignment with trajectory data, auxiliary readers provide methods to assign each auxiliary step to the nearest trajectory timestep, read all steps assigned to a trajectory timestep and calculate ‘representative’ value(s) of the auxiliary data for that timestep.
‘Assignment’ of auxiliary steps to trajectory timesteps is determined from the time
of the auxiliary step, dt of the trajectory and time at the first frame of the
trajectory (obtained through a Timestep
instance from the trajectory), as:
frame = floor((time_at_step - time_at_frame_0 + dt/2)/dt)
If there are no auxiliary steps assigned to a given timestep (or none within
cutoff, if set), the representative value(s) are set to np.nan.
11.1.2.1.1. Adding an auxiliary to a trajectory
Auxiliary data may be added to a trajectory Reader through the
add_auxiliary() method. Auxiliary data
may be passed in as a AuxReader instance, or directly as e.g. a filename, in
which case get_auxreader_for() is used to
guess an appropriate reader. e.g.:
u = MDAnalysis.Universe(PDB, XTC)
u.trajectory.add_auxiliary('pullforce', './pull_force.xvg')
As the trajectory frame is updated, the auxiliary data will be read
correspondingly,
updated, and the representative auxiliary value(s) will be available as e.g.
u.trajectory.ts.aux.pullforce.
11.1.2.1.2. Iterating by an auxiliary
The trajectory ProtoReader methods
next_as_aux() and
iter_as_aux() allow for movement
through only trajectory timesteps to which one or more steps that fall within
cutoff from a given auxiliary have been assigned. This may be used to
avoid representative values set to np.nan, particularly when auxiliary data
is less frequent:
u.trajectory.add_auxiliary('low_f', 'low_freq_aux_data.xvg')
for ts in u.trajectory.iter_as_aux('low_f'):
do_something(ts.aux.low_f) # do something with 'low_f' auxiliary data without
# worrying about having to deal with np.nan
If the auxiliary data are more frequent and the cutoff (if set) is
sufficiently high, next_as_aux()
and iter_as_aux() behave the same
as the ProtoReader
next() and
__iter__().
In order to access auxiliary values at every individual step, including those
outside the time range of the trajectory,
iter_auxiliary() allows iteration
over the auxiliary independent of the trajectory:
for auxstep in u.trajectory.iter_auxiliary('pullforce'):
do_something(auxstep)
To iterate over only a certain section of the auxiliary:
for auxstep in u.trajectory.iter_auxiliary('pullforce', start=100, step=10):
# every 10th step from 100
do_something(auxstep)
The trajectory remains unchanged, and the auxiliary will be returned to the current timestep after iteration is complete.
11.1.2.1.3. Accessing auxiliary attributes
To check the values of attributes of an added auxiliary, use
get_aux_attribute(), e.g.:
pullf_dt = u.trajectory.get_aux_attribute('pullforce', 'dt')
If attributes are settable, they can be changed using
set_aux_attribute(), e.g.:
u.trajectory.set_aux_attribute('pullforce', 'data_selector', [1])
The auxiliary may be renamed using set_aux_attribute with ‘auxname’, or more
directly by using rename_aux():
u.trajectory.rename_aux('pullforce', 'pullf')
11.1.2.2. Recreating auxiliaries
To recreate an auxiliary, the set of attributes necessary to replicate it can
first be obtained with get_description().
The returned dictionary can then be passed to
auxreader() to load a new copy of the
original auxiliary reader:
description = aux.get_description()
del(aux)
reload_aux = MDAnalysis.auxiliary.auxreader(**description)
The ‘description’ of any or all the auxiliaries added to a trajectory can be
obtained using get_aux_descriptions():
descriptions = u.trajectory.get_aux_descriptions()
Get descriptions for selected auxiliaries only:
descriptions = u.trajectory.get_aux_descriptions(['pullf', 'pullx'])
And to reload:
for descr in descriptions:
new_u.new_trajectory.add_auxiliary(**descr)
11.1.2.3. AuxStep class
An AuxStep instance holds the auxiliary data for the current step. It is updated whenever a new auxiliary step is read.
AuxStep classes are derived from the base class
AuxStep. The appropriate AuxStep class for
a given auxiliary reader is identified in the reader by the _Auxstep attribute.
11.1.2.3.1. Attributes
The following are inherited from AuxStep:
stepCurrent auxiliary step (0-based).
_dataAll recorded data for the current step, as a numpy array.
timeTime of current auxiliary step, as a float (in ps). Determined from the
_dataif time selection is enabled and a validtime_selectorprovided; otherwise calculated usingdtandinitial_time.dataAuxiliary values of interest for the current step, as a numpy array. Determined from
_dataid data selection is enabled at a validdata_selectoris provided; otherwise set to_data.
The following are stored in AuxStep. The parent auxiliary reader has the equivalent attributes, though non-private (no _) (see AuxReader class below).
_dtChange in time between auxiliary steps (in ps). If not specified, will attempt to determine from auxiliary data; otherwise defaults to 1 ps.
_initial_timeTime of first auxiliary step (in ps). If not specified, will attempt to determine from auxiliary data; otherwise defaults to 0 ps.
_time_selectorSelection key to get time from full set of auxiliary data read with each step(
_data) (ignored if time selection is not enabled by the reader). Type depends on the auxiliary format - e.g. where data is stored in columns, time_selector may be an index of ‘time’ column. Default value isNone, in which case step time is calculated fromdt,initial_timeandstep._data_selectorSelection key(s) to get data of interest from full set of auxiliary data read with each step (
_data) (ignored if data selection is not enabled by the reader). As fortime_selector, type depends on the auxiliary format. IfNone(default value),_datais returned._constant_dtBoolean of whether dt is constant throughout auxiliary data. Default is
True.
11.1.2.3.2. Methods
The following methods are inherited from
AuxStep:
__init__(**kwargs)Setup appropriate attributes based on kwargs.
To enabled time/data selection in a particular AusStep, the following must be provided:
_select_time(key)Return, as a float, the time value indicated by key from
_data(the full set of data read in from the current step). RaiseValueErrorif key is not a valid time selector for the auxiliary format._select_data(key)Return, as a ndarray, the value(s) indicated by key (may be e.g. a list of multiple individual ‘keys’) from
_data. RaiseValueErrorif key is not a valid data selector for the auxiliary format.
Depending on the format of the auxiliary and hence the format of data, it
may be necessary to overload the following for a particular AuxStep:
_empty_data()Return a np.array in the same format as
datawith all values set tonp.nan. Used as the representative auxiliary value for a trajectory when no auxiliary steps are assigned to the current frame.
11.1.2.4. AuxReader class
11.1.2.4.1. Registry
In order to facilitate guessing of appropriate AuxReaders, all AuxReaders should set as appropriate format attribute. For files, this will be the expected file extension (in all caps).
11.1.2.4.2. Replicating auxiliaries
The names of the necessary attributes for replicating an auxiliary are stored in required_attrs, initially set in the base AuxReader. If a particular AuxReader introduces additional attributes required to reload an auxiliary, these should be added.
11.1.2.4.3. Attributes
The following attributes are inherited from
AuxReader:
auxnameName under which auxiliary data will be stored in trajectory.
represent_ts_asMethod to use in calculating representative auxiliary value for a timestep. Default is ‘closest’.
cutoffCutoff (in ps) for ignoring auxiliary steps when calculating representative value(s) for a timestep.
auxstepThe
AuxStepobject to store data for the current step. The particular AuxStep used will depend on the auxiliary format.n_stepsTotal number of auxiliary steps.
frame_datadata from each auxiliary step assigned to the last-read trajectory timestep.
frame_repRepresentative value(s) of auxiliary data for last-read trajectory timestep.
The following are stored in auxstep as private attributes (with _)
but may be accessed from the auxiliary reader; see the AuxStep class above.
step
time
dt
initial_time
time_selector
data_selector
constant_dt
AuxFileReader provides:
auxfileFile object for the auxiliary file.
Each auxiliary reader subclass will additionally set:
_auxdataValue of ‘auxdata’ used to load the auxiliary - e.g. path to the file containing the auxiliary data. Will be used when getting the ‘description’ of the auxiliary for recreating.
Each auxiliary reader class must also identify an appropriate
AuxStep with the _Auxstep class attribute
11.1.2.4.4. Methods
The following methods are inherited from
AuxReader:
__init__(**kwargs)Setup appropriate attributes based on kwargs.
__len__()Number of steps in auxiliary data.
next()Advance to next step.
__iter__()Allow iteration through each auxiliary step.
__getitem__(step)If step is a single index, move to that step and return the
AuxStep; if a list or slice, return an iterator over the specified auxiliary steps. See examples in Auxiliary API above.rewind()Reposition to first step.
update_ts(ts)Read auxiliary steps assigned to trajectory step ts, calculate and update the representative value in ts. Return ts.
read_ts(ts)Read auxiliary steps assigned to trajectory step ts and calculate representative value.
move_to_ts(ts)Move to the auxiliary step before the trajectory timestep ts, such that calling
_read_next_stepreads the first step assigned to ts or, when auxiliary data are less frequent and no steps are assigned to ts, the first step following ts.step_to_frame(step, ts, return_time_diff=False)Return the frame number of the trajectory described by ts to which the auxiliary step step is assigned. Optionally also return the difference it time between the step and the returned frame.
step_to_time(step)Return the time of the auxiliary step step.
next_nonempty_frame(ts)Return the frame number of the next trajectory frame (after the current auxiliary time) for which a representative auxiliary value can be calculated (i.e., there is at least one assigned auxiliary step within
cutoff).calc_representative()Return the representative value calculated from
datafollowing the method specified byrepresent_ts_asandcutoff.__enter__()Entry method for Context Manager (returns self).
__exit__()Exit method for Context Manager (calls
close()).__del__()Calls
close().get_descriptionGet the values of the attributes required for replicating an auxiliary (as listed in
required_attrs) and return as a dictionary.__eq__Check for equality by checking each of the attributes required for replicating an auxiliary (as listed in
required_attrs) are equal.
Each AuxReader must subclass AuxReader
and addionally define:
__init__(auxdata, **kwargs)Additional processing of kwargs and any necessary initial processing of auxdata. Must
super()throughAuxReader._read_next_step()Read the data from the next auxiliary step and update
auxstepas appropriate. Raise StopIteration when attempting to read past last step._go_to_step(i)Move to and read step i (0-based) from the auxiliary data. Raise ValueError when i is out of range. Update the
auxstepand return.
Depending on the format of the auxiliary data, it may also be necessary to define/overwrite the following:
read_all_times()Return the list of times for each step (only required if
constant_dtmay be false).count_n_steps()Return the total number of steps (only required if _n_steps not otherwise set during __init__).
_restart()Reposition before the first step
close()
For convenience, when reading auxiliary data from an open file, one step at a
time, AuxFileReader
extends AuxReader by providing the
following (these may be overwritten by subclasses as appropriate):
__init__(auxfile, **kwargs)Open auxfile and any additional processing of kwargs.
_restart(),Seek to the start of
auxfileclose()Close
auxfile_go_to_step(i)Iterate through all steps until step i is reached.
_reopen()Close
auxfileand reopen.