lifetimes
- mdtools.dtrj.lifetimes(dtrj, axis=-1, uncensored=False, discard_neg_start=False, discard_all_neg=False, return_states=False, return_cmp_ix=False)[source]
Calculate the state lifetimes for each compound.
- Parameters:
dtrj (
array_like
) – Array containing the discrete trajectory.axis (
int
, optional) – The axis along which to search for state transitions. For ordinary discrete trajectories with shape(n, f)
or(f,)
, wheren
is the number of compounds andf
is the number of frames, set axis to-1
. If you parse a transposed discrete trajectory of shape(f, n)
, set axis to0
.uncensored (
bool
, optional) – IfTrue
only take into account uncensored states, i.e. states whose start and end lie within the trajectory. In other words, discard the truncated (censored) states at the beginning and end of the trajectory. For these states the start/end time is unknown.discard_neg_start (
bool
, optional) – IfTrue
, discard the lifetimes of all negative states (see notes). This is equivalent to discarding all transitions starting from a negative state when calculating transition rates withmdtools.dtrj.trans_rate()
or remain probabilities withmdtools.dtrj.remain_prob()
. Has no effect if discard_all_neg isTrue
.discard_all_neg (
bool
, optional) – IfTrue
, discard the lifetimes of all negative states and of all states that are followed by a negative state (see notes). This is equivalent to discarding all transitions starting from or ending in a negative state when calculating transition rates withmdtools.dtrj.trans_rate()
or remain probabilities withmdtools.dtrj.remain_prob()
.return_states (
bool
, optional) – IfTrue
, return the state indices associated with the returned lifetimes.return_cmp_ix (
bool
, optional) – IfTrue
, return the compound indices associated with the returned lifetimes.
- Returns:
lt (
numpy.ndarray
) – 1-dimensional array containing the lifetimes for all compounds in all states.states (
numpy.ndarray
) – 1-dimensional array of the same shape as lt containing the corresponding states indices. Only returned if return_states isTrue
.cmp_ix (
numpy.ndarray
) – 1-dimensional array of the same shape as lt containing the corresponding compound indices. Only returned if return_cmp_ix isTrue
.
See also
mdtools.dtrj.lifetimes_per_state()
Calculate the state lifetimes for each state
mdtools.dtrj.trans_rate()
Calculate the transition rate for each compound averaged over all states
mdtools.dtrj.kaplan_meier()
Estimate the state survival function using the Kaplan-Meier estimator
mdtools.dtrj.remain_prob()
Calculate the probability that a compound is still (or again) in the same state as at time \(t_0\) after a lag time \(\Delta t\)
Notes
State lifetimes are calculated by simply counting the number of frames a given compound stays in a given state. Note that lifetimes calculated in this way are usually biased to lower values because of the limited length of the trajectory and because of truncation/censoring at the trajectory edges: At the beginning and end of the trajectory it is impossible to say how long a compound has already been it’s initial state or how long it will stay in it’s final state. For better estimates of the average state lifetime use
mdtools.dtrj.kaplan_meier()
,mdtools.dtrj.trans_rate()
, ormdtools.dtrj.remain_prob()
.If uncensored is
True
, the truncated states at the trajectory edges are ignored. Thus, lifetimes calculated in this way can at maximum be as long as the trajectory minus the first and last frame. Depending on the length of the trajectory and the average state lifetime, uncensored counting might waste a significant amount of the trajectory.Valid and Invalid States
By default, all states in the given discrete trajectory are valid. However, in some cases you might want to treat certain states as invalid, e.g. because you only want to consider specific states. This can be achieved with the arguments discard_neg_start or discard_all_neg which treat negative states (i.e. states with a negative state number/index) as invalid states.
Note
If you want to treat states with index zero as invalid, too, simply subtract one from dtrj. If you want to treat all states below a certain cutoff as invalid, subtract this cutoff from dtrj. If you want to treat certain states as invalid, make these states negative, e.g. by multiplying these states with minus one.
The arguments discard_neg_start and discard_all_neg affect the counting of frames in which a given compound resides in a given state.
If both, discard_neg_start and discard_all_neg, are
False
(the default), all states are valid, i.e. all frames are counted.If discard_neg_start is
True
, negative states are not counted, i.e. the lifetimes of negative states are discarded. Thus, the resulting average lifetime is the average lifetime of all positive states.If discard_all_neg is
True
, negative states and states that are followed by a negative state are not counted. This means transitions from or to negative states are completely discarded. Thus, the resulting average lifetime is the average lifetime of positive states that transition to another positive state.Examples
>>> dtrj = np.array([[1, 2, 2, 3, 3, 3], ... [2, 2, 3, 3, 3, 1], ... [6, 6, 6, 1, 4, 4], ... [1, 6, 6, 6, 4, 4]]) >>> lt, states, cmp_ix = mdt.dtrj.lifetimes( ... dtrj, return_states=True, return_cmp_ix=True ... ) >>> lt array([1, 2, 3, 2, 3, 1, 3, 1, 2, 1, 3, 2]) >>> states array([1, 2, 3, 2, 3, 1, 6, 1, 4, 1, 6, 4]) >>> cmp_ix array([0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3]) >>> mdt.nph.group_by(states, lt) [array([1, 1, 1, 1]), array([2, 2]), array([3, 3]), array([2, 2]), array([3, 3])] >>> mdt.nph.group_by(cmp_ix, lt, assume_sorted=True) [array([1, 2, 3]), array([2, 3, 1]), array([3, 1, 2]), array([1, 3, 2])] >>> lt, states, cmp_ix = mdt.dtrj.lifetimes( ... dtrj, axis=0, return_states=True, return_cmp_ix=True ... ) >>> lt array([1, 1, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2]) >>> states array([1, 2, 6, 1, 2, 6, 2, 3, 6, 3, 1, 6, 3, 4, 3, 1, 4]) >>> cmp_ix array([0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5]) >>> mdt.nph.group_by(states, lt) [array([1, 1, 1, 1]), array([1, 2, 1]), array([1, 2, 2, 1]), array([2, 2]), array([1, 2, 2, 1])] >>> mdt.nph.group_by(cmp_ix, lt, assume_sorted=True) [array([1, 1, 1, 1]), array([2, 2]), array([1, 1, 2]), array([2, 1, 1]), array([2, 2]), array([1, 1, 2])]
>>> dtrj = np.array([[1, 2, 2, 3, 3, 3], ... [2, 2, 3, 3, 3, 1], ... [3, 3, 3, 1, 2, 2], ... [1, 3, 3, 3, 2, 2]]) >>> lt, states, cmp_ix = mdt.dtrj.lifetimes( ... dtrj, return_states=True, return_cmp_ix=True ... ) >>> lt array([1, 2, 3, 2, 3, 1, 3, 1, 2, 1, 3, 2]) >>> states array([1, 2, 3, 2, 3, 1, 3, 1, 2, 1, 3, 2]) >>> cmp_ix array([0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3]) >>> mdt.nph.group_by(states, lt) [array([1, 1, 1, 1]), array([2, 2, 2, 2]), array([3, 3, 3, 3])] >>> mdt.nph.group_by(cmp_ix, lt, assume_sorted=True) [array([1, 2, 3]), array([2, 3, 1]), array([3, 1, 2]), array([1, 3, 2])] >>> np.mean(lt) 2.0 >>> np.std(lt, ddof=1) 0.8528028654224418 >>> lt_unc, states_unc, cmp_ix_unc = mdt.dtrj.lifetimes( ... dtrj, ... uncensored=True, ... return_states=True, ... return_cmp_ix=True, ... ) >>> lt_unc array([2, 3, 1, 3]) >>> states_unc array([2, 3, 1, 3]) >>> cmp_ix_unc array([0, 1, 2, 3]) >>> ax = 0 >>> lt, states, cmp_ix = mdt.dtrj.lifetimes( ... dtrj, axis=ax, return_states=True, return_cmp_ix=True ... ) >>> lt array([1, 1, 1, 1, 2, 2, 1, 3, 2, 1, 1, 2, 2, 1, 1, 2]) >>> states array([1, 2, 3, 1, 2, 3, 2, 3, 3, 1, 3, 3, 2, 3, 1, 2]) >>> cmp_ix array([0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5]) >>> mdt.nph.group_by(states, lt) [array([1, 1, 1, 1]), array([1, 2, 1, 2, 2]), array([1, 2, 3, 2, 1, 2, 1])] >>> mdt.nph.group_by(cmp_ix, lt, assume_sorted=True) [array([1, 1, 1, 1]), array([2, 2]), array([1, 3]), array([2, 1, 1]), array([2, 2]), array([1, 1, 2])] >>> np.mean(lt) 1.5 >>> np.std(lt, ddof=1) 0.6324555320336759 >>> lt_unc, states_unc, cmp_ix_unc = mdt.dtrj.lifetimes( ... dtrj, ... axis=ax, ... uncensored=True, ... return_states=True, ... return_cmp_ix=True, ... ) >>> lt_unc array([1, 1, 1, 1]) >>> states_unc array([2, 3, 1, 1]) >>> cmp_ix_unc array([0, 0, 3, 5])
>>> dtrj = np.array([[ 1, 2, 2, 1, 1, 1], ... [ 2, 2, 3, 3, 3, 2], ... [-3, -3, -3, -1, 2, 2], ... [ 2, 3, 3, 3, -2, -2]]) >>> lt, states, cmp_ix = mdt.dtrj.lifetimes( ... dtrj, return_states=True, return_cmp_ix=True ... ) >>> lt array([1, 2, 3, 2, 3, 1, 3, 1, 2, 1, 3, 2]) >>> states array([ 1, 2, 1, 2, 3, 2, -3, -1, 2, 2, 3, -2]) >>> cmp_ix array([0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3]) >>> mdt.nph.group_by(states, lt) [array([3]), array([2]), array([1]), array([1, 3]), array([2, 2, 1, 2, 1]), array([3, 3])] >>> mdt.nph.group_by(cmp_ix, lt, assume_sorted=True) [array([1, 2, 3]), array([2, 3, 1]), array([3, 1, 2]), array([1, 3, 2])] >>> lt_unc, states_unc, cmp_ix_unc = mdt.dtrj.lifetimes( ... dtrj, ... uncensored=True, ... return_states=True, ... return_cmp_ix=True ... ) >>> lt_unc array([2, 3, 1, 3]) >>> states_unc array([ 2, 3, -1, 3]) >>> cmp_ix_unc array([0, 1, 2, 3]) >>> lt_start, states_start, cmp_ix_start = mdt.dtrj.lifetimes( ... dtrj, ... discard_neg_start=True, ... return_states=True, ... return_cmp_ix=True, ... ) >>> lt_start array([1, 2, 3, 2, 3, 1, 2, 1, 3]) >>> states_start array([1, 2, 1, 2, 3, 2, 2, 2, 3]) >>> cmp_ix_start array([0, 0, 0, 1, 1, 1, 2, 3, 3]) >>> mdt.nph.group_by(states_start, lt_start) [array([1, 3]), array([2, 2, 1, 2, 1]), array([3, 3])] >>> mdt.nph.group_by(cmp_ix_start, lt_start, assume_sorted=True) [array([1, 2, 3]), array([2, 3, 1]), array([2]), array([1, 3])] >>> lt_start_unc, states_start_unc, cmp_ix_start_unc = mdt.dtrj.lifetimes( ... dtrj, ... uncensored=True, ... discard_neg_start=True, ... return_states=True, ... return_cmp_ix=True ... ) >>> lt_start_unc array([2, 3, 3]) >>> states_start_unc array([2, 3, 3]) >>> cmp_ix_start_unc array([0, 1, 3]) >>> lt_all, states_all, cmp_ix_all = mdt.dtrj.lifetimes( ... dtrj, ... discard_all_neg=True, ... return_states=True, ... return_cmp_ix=True, ... ) >>> lt_all array([1, 2, 3, 2, 3, 1, 2, 1]) >>> states_all array([1, 2, 1, 2, 3, 2, 2, 2]) >>> cmp_ix_all array([0, 0, 0, 1, 1, 1, 2, 3]) >>> mdt.nph.group_by(states_all, lt_all) [array([1, 3]), array([2, 2, 1, 2, 1]), array([3])] >>> mdt.nph.group_by(cmp_ix_all, lt_all, assume_sorted=True) [array([1, 2, 3]), array([2, 3, 1]), array([2]), array([1])] >>> lt_all_unc, states_all_unc, cmp_ix_all_unc = mdt.dtrj.lifetimes( ... dtrj, ... uncensored=True, ... discard_all_neg=True, ... return_states=True, ... return_cmp_ix=True ... ) >>> lt_all_unc array([2, 3]) >>> states_all_unc array([2, 3]) >>> cmp_ix_all_unc array([0, 1]) >>> ax = 0 >>> lt, states, cmp_ix = mdt.dtrj.lifetimes( ... dtrj, axis=ax, return_states=True, return_cmp_ix=True ... ) >>> lt array([1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1]) >>> states array([ 1, 2, -3, 2, 2, -3, 3, 2, 3, -3, 3, 1, 3, -1, 3, 1, 3, 2, -2, 1, 2, -2]) >>> cmp_ix array([0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5]) >>> lt_unc, states_unc, cmp_ix_unc = mdt.dtrj.lifetimes( ... dtrj, ... axis=ax, ... uncensored=True, ... return_states=True, ... return_cmp_ix=True ... ) >>> lt_unc array([1, 1, 1, 1, 1, 1, 1, 1, 1, 2]) >>> states_unc array([ 2, -3, -3, 3, -3, 3, -1, 3, 2, 2]) >>> cmp_ix_unc array([0, 0, 1, 2, 2, 3, 3, 4, 4, 5]) >>> lt_start, states_start, cmp_ix_start = mdt.dtrj.lifetimes( ... dtrj, ... axis=ax, ... discard_neg_start=True, ... return_states=True, ... return_cmp_ix=True, ... ) >>> lt_start array([1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2]) >>> states_start array([1, 2, 2, 2, 3, 2, 3, 3, 1, 3, 3, 1, 3, 2, 1, 2]) >>> cmp_ix_start array([0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5]) >>> lt_start_unc, states_start_unc, cmp_ix_start_unc = mdt.dtrj.lifetimes( ... dtrj, ... axis=ax, ... uncensored=True, ... discard_neg_start=True, ... return_states=True, ... return_cmp_ix=True ... ) >>> lt_start_unc array([1, 1, 1, 1, 1, 2]) >>> states_start_unc array([2, 3, 3, 3, 2, 2]) >>> cmp_ix_start_unc array([0, 2, 3, 4, 4, 5]) >>> lt_all, states_all, cmp_ix_all = mdt.dtrj.lifetimes( ... dtrj, ... axis=ax, ... discard_all_neg=True, ... return_states=True, ... return_cmp_ix=True, ... ) >>> lt_all array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1]) >>> states_all array([1, 2, 3, 2, 3, 1, 3, 1, 3, 1]) >>> cmp_ix_all array([0, 0, 1, 2, 2, 3, 3, 4, 4, 5]) >>> lt_all_unc, states_all_unc, cmp_ix_all_unc = mdt.dtrj.lifetimes( ... dtrj, ... axis=ax, ... uncensored=True, ... discard_all_neg=True, ... return_states=True, ... return_cmp_ix=True ... ) >>> lt_all_unc array([1]) >>> states_all_unc array([3]) >>> cmp_ix_all_unc array([4])
>>> dtrj = np.array([[ 1, -2, -2, 3, 3, 3], ... [-2, -2, 3, 3, 3, 1], ... [ 3, 3, 3, 1, -2, -2], ... [ 1, 3, 3, 3, -2, -2], ... [ 1, 4, 4, 4, 4, -1]]) >>> lt, states, cmp_ix = mdt.dtrj.lifetimes( ... dtrj, return_states=True, return_cmp_ix=True ... ) >>> lt array([1, 2, 3, 2, 3, 1, 3, 1, 2, 1, 3, 2, 1, 4, 1]) >>> states array([ 1, -2, 3, -2, 3, 1, 3, 1, -2, 1, 3, -2, 1, 4, -1]) >>> cmp_ix array([0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]) >>> mdt.nph.group_by(states, lt) [array([2, 2, 2, 2]), array([1]), array([1, 1, 1, 1, 1]), array([3, 3, 3, 3]), array([4])] >>> mdt.nph.group_by(cmp_ix, lt, assume_sorted=True) [array([1, 2, 3]), array([2, 3, 1]), array([3, 1, 2]), array([1, 3, 2]), array([1, 4, 1])] >>> lt_unc, states_unc, cmp_ix_unc = mdt.dtrj.lifetimes( ... dtrj, ... uncensored=True, ... return_states=True, ... return_cmp_ix=True, ... ) >>> lt_unc array([2, 3, 1, 3, 4]) >>> states_unc array([-2, 3, 1, 3, 4]) >>> cmp_ix_unc array([0, 1, 2, 3, 4]) >>> lt_start, states_start, cmp_ix_start = mdt.dtrj.lifetimes( ... dtrj, ... discard_neg_start=True, ... return_states=True, ... return_cmp_ix=True, ... ) >>> lt_start array([1, 3, 3, 1, 3, 1, 1, 3, 1, 4]) >>> states_start array([1, 3, 3, 1, 3, 1, 1, 3, 1, 4]) >>> cmp_ix_start array([0, 0, 1, 1, 2, 2, 3, 3, 4, 4]) >>> mdt.nph.group_by(states_start, lt_start) [array([1, 1, 1, 1, 1]), array([3, 3, 3, 3]), array([4])] >>> mdt.nph.group_by(cmp_ix_start, lt_start, assume_sorted=True) [array([1, 3]), array([3, 1]), array([3, 1]), array([1, 3]), array([1, 4])] >>> lt_start_unc, states_start_unc, cmp_ix_start_unc = mdt.dtrj.lifetimes( ... dtrj, ... uncensored=True, ... discard_neg_start=True, ... return_states=True, ... return_cmp_ix=True, ... ) >>> lt_start_unc array([3, 1, 3, 4]) >>> states_start_unc array([3, 1, 3, 4]) >>> cmp_ix_start_unc array([1, 2, 3, 4]) >>> lt_all, states_all, cmp_ix_all = mdt.dtrj.lifetimes( ... dtrj, ... discard_all_neg=True, ... return_states=True, ... return_cmp_ix=True, ... ) >>> lt_all array([3, 3, 1, 3, 1, 1]) >>> states_all array([3, 3, 1, 3, 1, 1]) >>> cmp_ix_all array([0, 1, 1, 2, 3, 4]) >>> mdt.nph.group_by(states_all, lt_all) [array([1, 1, 1]), array([3, 3, 3])] >>> mdt.nph.group_by(cmp_ix_all, lt_all, assume_sorted=True) [array([3]), array([3, 1]), array([3]), array([1]), array([1])] >>> lt_all_unc, states_all_unc, cmp_ix_all_unc = mdt.dtrj.lifetimes( ... dtrj, ... uncensored=True, ... discard_all_neg=True, ... return_states=True, ... return_cmp_ix=True, ... ) >>> lt_all_unc array([3]) >>> states_all_unc array([3]) >>> cmp_ix_all_unc array([1]) >>> ax = 0 >>> lt, states, cmp_ix = mdt.dtrj.lifetimes( ... dtrj, axis=ax, return_states=True, return_cmp_ix=True ... ) >>> lt array([1, 1, 1, 2, 2, 2, 1, 1, 3, 1, 2, 1, 1, 1, 2, 2, 1, 1, 1, 2, 1]) >>> states array([ 1, -2, 3, 1, -2, 3, 4, -2, 3, 4, 3, 1, 3, 4, 3, -2, 4, 3, 1, -2, -1]) >>> cmp_ix array([0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5, 5]) >>> lt_start, states_start, cmp_ix_start = mdt.dtrj.lifetimes( ... dtrj, ... axis=ax, ... discard_neg_start=True, ... return_states=True, ... return_cmp_ix=True, ... ) >>> lt_start array([1, 1, 2, 2, 1, 3, 1, 2, 1, 1, 1, 2, 1, 1, 1]) >>> states_start array([1, 3, 1, 3, 4, 3, 4, 3, 1, 3, 4, 3, 4, 3, 1]) >>> cmp_ix_start array([0, 0, 0, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5]) >>> lt_start_unc, states_start_unc, cmp_ix_start_unc = mdt.dtrj.lifetimes( ... dtrj, ... axis=ax, ... uncensored=True, ... discard_neg_start=True, ... return_states=True, ... return_cmp_ix=True, ... ) >>> lt_start_unc array([1, 2, 3, 1, 1, 1]) >>> states_start_unc array([3, 3, 3, 1, 3, 1]) >>> cmp_ix_start_unc array([0, 1, 2, 3, 3, 5]) >>> lt_all, states_all, cmp_ix_all = mdt.dtrj.lifetimes( ... dtrj, ... axis=ax, ... discard_all_neg=True, ... return_states=True, ... return_cmp_ix=True, ... ) >>> lt_all array([1, 2, 2, 1, 3, 1, 2, 1, 1, 1, 1, 1]) >>> states_all array([3, 1, 3, 4, 3, 4, 3, 1, 3, 4, 4, 3]) >>> cmp_ix_all array([0, 0, 1, 1, 2, 2, 3, 3, 3, 3, 4, 5]) >>> lt_all_unc, states_all_unc, cmp_ix_all_unc = mdt.dtrj.lifetimes( ... dtrj, ... axis=ax, ... uncensored=True, ... discard_all_neg=True, ... return_states=True, ... return_cmp_ix=True, ... ) >>> lt_all_unc array([1, 2, 3, 1, 1]) >>> states_all_unc array([3, 3, 3, 1, 3]) >>> cmp_ix_all_unc array([0, 1, 2, 3, 3])
>>> dtrj = np.array([[1, 2, 2], ... [3, 3, 3]]) >>> lt_unc, states_unc, cmp_ix_unc = mdt.dtrj.lifetimes( ... dtrj, ... uncensored=True, ... return_states=True, ... return_cmp_ix=True ... ) >>> lt_unc array([], dtype=int64) >>> states_unc array([], dtype=int64) >>> cmp_ix_unc array([], dtype=int64) >>> lt_unc, states_unc, cmp_ix_unc = mdt.dtrj.lifetimes( ... dtrj, ... axis=0, ... uncensored=True, ... return_states=True, ... return_cmp_ix=True ... ) >>> lt_unc array([], dtype=int64) >>> states_unc array([], dtype=int64) >>> cmp_ix_unc array([], dtype=int64)