def get_lifetime_segments(trajectory, from_vol, to_vol, forbidden=None, padding=[0, -1]): """General script to get lifetimes. Lifetimes for a transition between volumes are used in several other calculations: obviously, the state lifetime, but also the flux through an interface. This is a generic function to calculate that. Parameters ---------- trajectory : :class:`.Trajectory` trajectory to analyze from_vol : :class:`.Volume` the volume for which this represents the lifetime: the trajectory segments returned are associated with the lifetime of `from_vol` to_vol : :class:`.Volume` the volume which indicates the end of the lifetime: a frame in this volume means the trajectory is no longer associated with `from_vol` forbidden : :class:`.Volume` if a frame is in `forbidden`, it cannot be part of the lifetime of `from_vol`. This isn't needed in 2-state lifetime calculations; however, it is useful to exclude other states from a flux calculation padding : list adjusts which frames are returned as list indices. That is, the returned segments are `full_segment[padding[0]:padding[1]]`. The `full_segment`s are the segments from (and including) each first frame in `from_vol` (after a visit to `to_vol`) until (and including) the first frame in `to_vol`. To get the full segment as output, use `padding=[None, None]`. The default is to remove the final frame (`padding=[0, -1]`) so that it doesn't include the frame in `to_vol`. Returns ------- list of :class:`.Trajectory` the frames from (and including) each first entry from `to_vol` into `from_vol` until (and including) the next entry into `to_vol`, with no frames in `forbidden`, and with frames removed from the ends according to `padding` """ if forbidden is None: forbidden = paths.EmptyVolume() ensemble_BAB = paths.SequentialEnsemble([ paths.LengthEnsemble(1) & paths.AllInXEnsemble(to_vol), paths.PartInXEnsemble(from_vol) & paths.AllOutXEnsemble(to_vol), paths.LengthEnsemble(1) & paths.AllInXEnsemble(to_vol) ]) & paths.AllOutXEnsemble(forbidden) ensemble_AB = paths.SequentialEnsemble([ paths.LengthEnsemble(1) & paths.AllInXEnsemble(from_vol), paths.OptionalEnsemble(paths.AllOutXEnsemble(to_vol)), paths.LengthEnsemble(1) & paths.AllInXEnsemble(to_vol) ]) BAB_split = ensemble_BAB.split(trajectory) AB_split = [ensemble_AB.split(part)[0] for part in BAB_split] return [subtraj[padding[0]:padding[1]] for subtraj in AB_split]
def test_subtrajectory_indices(self): # simplify more complicated expressions stateA = self.stateA stateB = self.stateB pretraj = [ 0.20, 0.30, 0.60, 0.40, 0.65, 2.10, 2.20, 2.60, 2.10, 0.80, 0.55, 0.40, 0.20 ] # 00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12 # A, A, I, A, I, B, B, X, B, X, I, A, A trajectory = make_1d_traj(coordinates=pretraj, velocities=[1.0] * len(pretraj)) ensemble_A = paths.AllInXEnsemble(stateA) ensemble_B = paths.AllInXEnsemble(stateB) ensemble_ABA = paths.SequentialEnsemble([ paths.AllInXEnsemble(stateA) & paths.LengthEnsemble(1), paths.PartInXEnsemble(stateB) & paths.AllOutXEnsemble(stateA), paths.AllInXEnsemble(stateA) & paths.LengthEnsemble(1) ]) subtrajectoriesA = ensemble_A.split(trajectory, overlap=0) subtrajectoriesB = ensemble_B.split(trajectory, overlap=0) subtrajectoriesABA = ensemble_ABA.split(trajectory) # make sure we have the trajectories we expect assert_equal(len(subtrajectoriesA), 3) assert_equal(len(subtrajectoriesB), 2) assert_equal(len(subtrajectoriesABA), 1) # the following assertions check that the subtrajectories are the # ones that we expect; the numbers here are linked to the indices # we'll test next assert_equal(subtrajectoriesA[0], trajectory[0:2]) assert_equal(subtrajectoriesA[1], trajectory[3:4]) assert_equal(subtrajectoriesA[2], trajectory[11:13]) assert_equal(subtrajectoriesB[0], trajectory[5:7]) assert_equal(subtrajectoriesB[1], trajectory[8:9]) assert_equal(subtrajectoriesABA[0], trajectory[3:12]) # now we run the subtrajectory_indices function and test it indicesA = trajectory.subtrajectory_indices(subtrajectoriesA) indicesB = trajectory.subtrajectory_indices(subtrajectoriesB) indicesABA = trajectory.subtrajectory_indices(subtrajectoriesABA) assert_equal(indicesA, [[0, 1], [3], [11, 12]]) assert_equal(indicesB, [[5, 6], [8]]) assert_equal(indicesABA, [[3, 4, 5, 6, 7, 8, 9, 10, 11]])
def _tps_ensemble(self, stateA, stateB): return paths.SequentialEnsemble([ paths.LengthEnsemble(1) & paths.AllInXEnsemble(stateA), paths.LengthEnsemble(self.length - 1) \ & paths.PartInXEnsemble(stateB) ])