示例#1
0
 def setup(self):
     cv = paths.CoordinateFunctionCV('x', lambda x: x.xyz[0][0])
     vol_A = paths.CVDefinedVolume(cv, float("-inf"), 0.0)
     vol_B = paths.CVDefinedVolume(cv, 1.0, float("inf"))
     ensembles = [
         paths.LengthEnsemble(1).named("len1"),
         paths.LengthEnsemble(3).named("len3"),
         paths.SequentialEnsemble([
             paths.LengthEnsemble(1) & paths.AllInXEnsemble(vol_A),
             paths.AllOutXEnsemble(vol_A | vol_B),
             paths.LengthEnsemble(1) & paths.AllInXEnsemble(vol_A)
         ]).named('return'),
         paths.SequentialEnsemble([
             paths.LengthEnsemble(1) & paths.AllInXEnsemble(vol_A),
             paths.AllOutXEnsemble(vol_A | vol_B),
             paths.LengthEnsemble(1) & paths.AllInXEnsemble(vol_B)
         ]).named('transition'),
     ]
     self.ensembles = {ens.name: ens for ens in ensembles}
     self.traj_vals = [-0.1, 1.1, 0.5, -0.2, 0.1, -0.3, 0.4, 1.4, -1.0]
     self.trajectory = make_1d_traj(self.traj_vals)
     self.engine = CalvinistDynamics(self.traj_vals)
     self.satisfied_when_traj_len = {
         "len1": 1,
         "len3": 3,
         "return": 6,
         "transition": 8,
     }
     self.conditions = EnsembleSatisfiedContinueConditions(ensembles)
示例#2
0
    def __init__(self, storage, engine=None, states=None, randomizer=None,
                 initial_snapshots=None, direction=None):
        all_state_volume = paths.join_volumes(states)
        no_state_volume = ~all_state_volume
        # shoot forward until we hit a state
        forward_ensemble = paths.SequentialEnsemble([
            paths.AllOutXEnsemble(all_state_volume),
            paths.AllInXEnsemble(all_state_volume) & paths.LengthEnsemble(1)
        ])
        # or shoot backward until we hit a state
        backward_ensemble = paths.SequentialEnsemble([
            paths.AllInXEnsemble(all_state_volume) & paths.LengthEnsemble(1),
            paths.AllOutXEnsemble(all_state_volume)
        ])
        super(CommittorSimulation, self).__init__(
            storage=storage,
            engine=engine,
            starting_volume=no_state_volume,
            forward_ensemble=forward_ensemble,
            backward_ensemble=backward_ensemble,
            randomizer=randomizer,
            initial_snapshots=initial_snapshots
        )
        self.states = states
        self.direction = direction

        # override the default self.mover given by the superclass
        if self.direction is None:
            self.mover = paths.RandomChoiceMover([self.forward_mover,
                                                  self.backward_mover])
        elif self.direction > 0:
            self.mover = self.forward_mover
        elif self.direction < 0:
            self.mover = self.backward_mover
示例#3
0
    def analyze_transition_duration(self, trajectory, stateA, stateB):
        """Analysis to obtain transition durations for given state.

        Parameters
        ----------
        trajectory : :class:`.Trajectory`
            trajectory to analyze
        stateA : :class:`.Volume`
            initial state volume for the transition
        stateB : :class:`.Volume`
            final state volume for the transition

        Returns
        -------
        :class:`.TrajectorySegmentContainer`
            transitions from `stateA` to `stateB` within `trajectory`
        """
        # we define the transitions ensemble just in case the transition is,
        # e.g., fixed path length TPS. We want flexible path length ensemble
        transition_ensemble = paths.SequentialEnsemble([
            paths.AllInXEnsemble(stateA) & paths.LengthEnsemble(1),
            paths.OptionalEnsemble( # optional to allow instantaneous hops
                paths.AllOutXEnsemble(stateA) & paths.AllOutXEnsemble(stateB)
            ),
            paths.AllInXEnsemble(stateB) & paths.LengthEnsemble(1)
        ])
        segments = [seg[1:-1] for seg in transition_ensemble.split(trajectory)]
        return TrajectorySegmentContainer(segments, self.dt)
示例#4
0
    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 __init__(self,
                 storage,
                 engine=None,
                 states=None,
                 randomizer=None,
                 initial_snapshots=None,
                 direction=None):
        super(CommittorSimulation, self).__init__(storage)
        self.engine = engine
        paths.EngineMover.default_engine = engine
        self.states = states
        self.randomizer = randomizer
        try:
            initial_snapshots = list(initial_snapshots)
        except TypeError:
            initial_snapshots = [initial_snapshots]
        self.initial_snapshots = initial_snapshots
        self.direction = direction

        all_state_volume = paths.join_volumes(states)

        # we should always start from a single frame not in any state
        self.starting_ensemble = (paths.AllOutXEnsemble(all_state_volume)
                                  & paths.LengthEnsemble(1))
        # shoot forward until we hit a state
        self.forward_ensemble = paths.SequentialEnsemble([
            paths.AllOutXEnsemble(all_state_volume),
            paths.AllInXEnsemble(all_state_volume) & paths.LengthEnsemble(1)
        ])
        # or shoot backward until we hit a state
        self.backward_ensemble = paths.SequentialEnsemble([
            paths.AllInXEnsemble(all_state_volume) & paths.LengthEnsemble(1),
            paths.AllOutXEnsemble(all_state_volume)
        ])

        self.forward_mover = paths.ForwardExtendMover(
            ensemble=self.starting_ensemble,
            target_ensemble=self.forward_ensemble)
        self.backward_mover = paths.BackwardExtendMover(
            ensemble=self.starting_ensemble,
            target_ensemble=self.backward_ensemble)

        if self.direction is None:
            self.mover = paths.RandomChoiceMover(
                [self.forward_mover, self.backward_mover])
        elif self.direction > 0:
            self.mover = self.forward_mover
        elif self.direction < 0:
            self.mover = self.backward_mover
示例#6
0
def A2BEnsemble(volume_a, volume_b, trusted=True):
    # this is a little replacement for the same name that used to be in
    # EnsembleFactory. It was only used in tests.
    return paths.SequentialEnsemble([
        paths.AllInXEnsemble(volume_a) & paths.LengthEnsemble(1),
        paths.AllOutXEnsemble(volume_a | volume_b),
        paths.AllInXEnsemble(volume_b) & paths.LengthEnsemble(1)
    ])
示例#7
0
    def __init__(self, transition, snapshot, storage=None, engine=None,
                 extra_interfaces=None, forbidden_states=None):
        super(FullBootstrapping, self).__init__(storage, engine)
        if extra_interfaces is None:
            extra_interfaces = list()

        if forbidden_states is None:
            forbidden_states = list()
        interface0 = transition.interfaces[0]
        ensemble0 = transition.ensembles[0]
        state = transition.stateA
        self.state = state
        self.first_traj_ensemble = paths.SequentialEnsemble([
            paths.OptionalEnsemble(paths.AllOutXEnsemble(state)),
            paths.AllInXEnsemble(state),
            paths.OptionalEnsemble(
                paths.AllOutXEnsemble(state) & paths.AllInXEnsemble(interface0)
            ),
            paths.OptionalEnsemble(paths.AllInXEnsemble(interface0)),
            paths.AllOutXEnsemble(interface0),
            paths.OptionalEnsemble(paths.AllOutXEnsemble(state)),
            paths.SingleFrameEnsemble(paths.AllInXEnsemble(state))
        ]) & paths.AllOutXEnsemble(paths.join_volumes(forbidden_states))

        self.extra_ensembles = [paths.TISEnsemble(transition.stateA,
                                                  transition.stateB, iface,
                                                  transition.orderparameter)
                                for iface in extra_interfaces
        ]

        self.transition_shooters = [
            paths.OneWayShootingMover(selector=paths.UniformSelector(), 
                                      ensemble=ens) 
            for ens in transition.ensembles
        ]

        self.extra_shooters = [
            paths.OneWayShootingMover(selector=paths.UniformSelector(), 
                                      ensemble=ens) 
            for ens in self.extra_ensembles
        ]
        self.snapshot = snapshot.copy()
        self.ensemble0 = ensemble0
        self.all_ensembles = transition.ensembles + self.extra_ensembles
        self.n_ensembles = len(self.all_ensembles)
        self.error_max_rounds = True
示例#8
0
 def add_transition(self, stateA, stateB):
     new_ens = paths.SequentialEnsemble([
         paths.AllInXEnsemble(stateA) & paths.LengthEnsemble(1),
         paths.AllOutXEnsemble(stateA | stateB),
         paths.AllInXEnsemble(stateB) & paths.LengthEnsemble(1)
     ])
     try:
         self.ensembles[0] = self.ensembles[0] | new_ens
     except AttributeError:
         self.ensembles = [new_ens]
示例#9
0
    def _build_sampling_transitions(self, transitions):
        transitions = list(transitions)  # input may be iterator
        # TODO: I don't think transition pairs are used (see comment below;
        # I think that was the previous use case -- as input to all_in_pairs
        # However, existing files store this, so we won't actually remove it
        # yet.
        self.transition_pairs = self._build_transition_pairs(transitions)
        # this seems to no longer be used; I think it was necessary when the
        # MSOuter interface was done implicitly, instead of explicitly. Then
        # we turn the outermost to MS if and only if it was paired with the
        # reverse transition
        # if len(self.transition_pairs) > 0:
        # all_in_pairs = reduce(list.__add__, map(lambda x: list(x),
        # self.transition_pairs))
        # else:
        # all_in_pairs = []

        # build sampling transitions
        all_states = paths.join_volumes(self.initial_states +
                                        self.final_states)
        all_states_set = set(self.initial_states + self.final_states)
        self.transition_to_sampling = {}
        for transition in transitions:
            stateA = transition.stateA
            stateB = transition.stateB
            if self.strict_sampling:
                final_state = stateB
                other_states = paths.join_volumes(all_states_set -
                                                  set([stateA, stateB]))
                ensemble_to_intersect = paths.AllOutXEnsemble(other_states)
            else:
                final_state = paths.join_volumes(all_states_set)
                ensemble_to_intersect = paths.FullEnsemble()

            sample_trans = paths.TISTransition(
                stateA=stateA,
                stateB=final_state,
                interfaces=transition.interfaces,
                name=stateA.name + "->" + stateB.name,
                orderparameter=transition.orderparameter)

            new_ensembles = [
                e & ensemble_to_intersect for e in sample_trans.ensembles
            ]
            if self.strict_sampling:
                for (old, new) in zip(new_ensembles, sample_trans.ensembles):
                    old.name = new.name + " strict"
            sample_trans.ensembles = new_ensembles
            sample_trans.named("Sampling " + str(stateA) + "->" + str(stateB))
            self.transition_to_sampling[transition] = sample_trans

        self.x_sampling_transitions = \
                list(self.transition_to_sampling.values())

        self._build_sampling_minus_ensembles()
示例#10
0
 def __init__(self, stateA, stateB, name=None):
     super(TPSTransition, self).__init__(stateA, stateB)
     if name is not None:
         self.name = name
     if not hasattr(self, "ensembles"):
         self.ensembles = [
             paths.SequentialEnsemble([
                 paths.AllInXEnsemble(stateA) & paths.LengthEnsemble(1),
                 paths.AllOutXEnsemble(stateA | stateB),
                 paths.AllInXEnsemble(stateB) & paths.LengthEnsemble(1)
             ])
         ]
    def setup(self):
        cv = paths.FunctionCV("Id", lambda snap: snap.xyz[0][0])
        self.state_A = paths.CVDefinedVolume(cv, -0.1, 0.1)
        self.state_B = ~paths.CVDefinedVolume(cv, -1.0, 1.0)
        nml_increasing = paths.CVDefinedVolume(cv, 0.1, 1.0)
        nml_decreasing = paths.CVDefinedVolume(cv, -1.0, -0.1)
        increasing = paths.AllInXEnsemble(nml_increasing)
        decreasing = paths.AllInXEnsemble(nml_decreasing)
        self.ensemble = paths.SequentialEnsemble([
            paths.LengthEnsemble(1) & paths.AllInXEnsemble(self.state_A),
            paths.AllOutXEnsemble(self.state_A | self.state_B),
            paths.LengthEnsemble(1) & paths.AllInXEnsemble(self.state_B)
        ])
        self.incr_1 = self._make_active([0.0, 0.5, 1.1])
        self.incr_2 = self._make_active([0.05, 0.6, 1.2])
        self.decr_1 = self._make_active([0.0, -0.5, -1.1])
        self.both_1 = self._make_active([0.0, 0.5, -0.5, 1.1])
        self.both_2 = self._make_active([0.0, -0.4, 0.4, -1.1])
        self.none_1 = self._make_active([0.0, 1.1])
        self.none_2 = self._make_active([0.0, -1.1])

        self.channels = {'incr': increasing, 'decr': decreasing}

        # used in simplest tests of relabeling
        self.toy_results = {
            'a': [(0, 5), (8, 10)],
            'b': [(3, 9)],
            'c': [(7, 9)]
        }
        self.results_with_none = {
            'a': [(0, 2), (6, 9)],
            'b': [(5, 7), (9, 10)],
            None: [(2, 5)]
        }
        self.set_a = frozenset(['a'])
        self.set_b = frozenset(['b'])
        self.set_c = frozenset(['c'])
        self.toy_expanded_results = [(0, 5, self.set_a), (3, 9, self.set_b),
                                     (7, 9, self.set_c), (8, 10, self.set_a)]
        self.expanded_results_simultaneous_ending = [(0, 5, self.set_a),
                                                     (3, 9, self.set_b),
                                                     (7, 10, self.set_c),
                                                     (8, 10, self.set_a)]
        self.expanded_oldest_skips_internal = [(0, 5, self.set_a),
                                               (3, 9, self.set_b),
                                               (7, 8, self.set_c),
                                               (8, 10, self.set_a),
                                               (10, 11, self.set_b)]
 def __init__(self, states, progress='default', timestep=None):
     self.states = states
     self.all_states = paths.join_volumes(states)
     all_states_ens = paths.join_ensembles([paths.AllOutXEnsemble(s)
                                            for s in states])
     ensemble = paths.SequentialEnsemble([
         all_states_ens,
         paths.AllInXEnsemble(self.all_states) & paths.LengthEnsemble(1)
     ])
     super(VisitAllStatesEnsemble, self).__init__(ensemble)
     self.timestep = timestep
     self.report_frequency = 10
     self.progress_formatter, self.progress_emitter = \
             self._progress_indicator(progress)
     self.cache = EnsembleCache(direction=+1)
     self._reset_cache_contents()
示例#13
0
 def __init__(self,
              initial_state,
              known_states,
              stable_contact_state,
              excluded_volume=None):
     super(MultipleBindingEnsemble, self).__init__()
     self.initial_state = initial_state
     self.known_states = known_states
     self.final_state = paths.join_volumes(
         set(known_states) - set([initial_state]))
     self.states = paths.join_volumes(set([initial_state] + known_states))
     self.stable_contact_state = stable_contact_state
     if excluded_volume is None:
         excluded_volume = paths.EmptyVolume()
     self.excluded_volume = excluded_volume
     self.excluded_volume_ensemble = \
             paths.AllOutXEnsemble(self.excluded_volume)
     self.cache = self._initialize_cache()
    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 fill_minus(minus_ensemble, innermost_ensemble, forbidden_states,
               initial_trj, engine):
    initial_state = minus_ensemble.state_vol
    print(f"Filling minus ensemble for state {initial_state.name}")
    forbidden_states_ensemble = paths.AllOutXEnsemble(
        paths.join_volumes(forbidden_states)
    )
    desired_ensemble = innermost_ensemble & forbidden_states_ensemble
    # ensure we're A->A, not A->B
    sample_A_to_A = shoot_until_A_to_A(innermost_ensemble, desired_ensemble,
                                       initial_trj, engine)

    # with an A->A segment, just use this to extend into the minus ensemble
    sample = minus_ensemble.extend_sample_from_trajectories(
        sample_A_to_A,
        engine=engine,
        replica=-1
    )
    return sample.trajectory
示例#16
0
    def make_ensemble(self, transitions, forbidden=None):
        """
        Create the ensemble for this MS outer interface.

        Parameters
        ----------
        transitions : list of :class:`.TISTransition`
            possible transitions of relevance
        forbidden : list of :class:`.Volume` or None
            (optional) volumes to disallow from the ensemble (e.g.,
            other states that should cause the trajectory to stop)

        Returns
        -------
        :class:`.Ensemble`
            the union of the TISEnsembles for each volume of the MS outer
            interface
        """
        if forbidden is None:
            ensemble_to_intersect = paths.FullEnsemble()
        else:
            try:
                _ = len(forbidden)
            except TypeError:
                forbidden = [forbidden]
            forbidden_vol = paths.join_volumes(forbidden)
            ensemble_to_intersect = paths.AllOutXEnsemble(forbidden_vol)

        # TODO: maybe we should crash if given transitions aren't relevant?
        relevant_transitions = self.relevant_transitions(transitions)

        outer_ensembles = []
        for trans in relevant_transitions:
            initial = trans.stateA
            final = trans.stateB
            volume = self.volume_for_interface_set(trans.interfaces)
            # TODO: move following to a logger.debug
            #print initial.name, final.name,\
            #self.lambda_for_interface_set(trans.interfaces)
            outer_ensembles.append(ensemble_to_intersect
                                   & paths.TISEnsemble(initial, final, volume))

        return paths.join_ensembles(outer_ensembles)
示例#17
0
    def strict_can_prepend(self, trajectory, trusted=False):
        n_frames = self.stable_contact_state.n_frames
        if len(trajectory) < n_frames:
            # NOTE: technically we might be able to abort earlier on these
            # short trajectories, but I'm not going to implement that now
            # (requires checking the freq of contacts and comparing with
            # possibility of ever having enough)
            no_known_state_ens = paths.AllOutXEnsemble(self.states)
            final_frame_allowed = not self.initial_state(trajectory[-1])
            other_frames_allowed = (no_known_state_ens(trajectory[:-1])
                                    or len(trajectory) == 1)
            logger.debug("final_frame_allowed: %s;  other_frames_allowed: %s",
                         final_frame_allowed, other_frames_allowed)
            return final_frame_allowed and other_frames_allowed

        known_state = self.final_state(trajectory[-1])
        subtraj = trajectory[slice(-n_frames, None)]
        stable_contacts = (self.stable_contact_state.check_end(trajectory)
                           and self.excluded_volume_ensemble(subtraj))
        logger.debug("ends in known state: %s; ends in stable contacts: %s",
                     known_state, stable_contacts)
        return ((known_state or stable_contacts)
                and self.can_prepend(trajectory, trusted))
    def __init__(self,
                 storage,
                 initial_file,
                 mover,
                 network,
                 options=None,
                 options_rejected=None):
        # TODO: mke the initial file into an initial trajectory
        if options is None:
            options = TPSConverterOptions()
        if options_rejected is None:
            options_rejected = options
        self.options = options
        self.options_rejected = options_rejected

        self.initial_file = initial_file  # needed for restore
        traj = self.load_trajectory(initial_file)
        # assume we're TPS here
        ensemble = network.sampling_ensembles[0]
        initial_trajectories = ensemble.split(traj)
        if len(initial_trajectories) == 0:  # pragma: no cover
            raise RuntimeError("Initial trajectory in " + str(initial_file) +
                               " has no subtrajectory satisfying the " +
                               "TPS ensemble.")
        elif len(initial_trajectories) > 1:  # pragma: no cover
            raise RuntimeWarning("More than one potential initial " +
                                 "subtrajectory. We use the first.")

        initial_trajectory = initial_trajectories[0]

        initial_conditions = paths.SampleSet([
            paths.Sample(replica=0,
                         trajectory=initial_trajectory,
                         ensemble=ensemble)
        ])

        self.extra_bw_frames = traj.index(initial_trajectory[0])
        final_frame_index = traj.index(initial_trajectory[-1])
        self.extra_fw_frames = len(traj) - final_frame_index - 1
        # extra -1 bc frame index counts from 0; len counts from 1

        self.summary_root_dir = None
        self.report_progress = None
        super(OneWayTPSConverter,
              self).__init__(storage=storage,
                             initial_conditions=initial_conditions,
                             mover=mover,
                             network=network)

        # initial_states = self.network.initial_states
        # final_states = self.network.final_states
        # TODO: prefer the above, but the below work until fix for network
        # storage
        initial_states = [self.network.sampling_transitions[0].stateA]
        final_states = [self.network.sampling_transitions[0].stateB]

        all_states = paths.join_volumes(initial_states + final_states)

        self.fw_ensemble = paths.SequentialEnsemble([
            paths.AllOutXEnsemble(all_states),
            paths.AllInXEnsemble(all_states) & paths.LengthEnsemble(1)
        ])
        self.bw_ensemble = paths.SequentialEnsemble([
            paths.AllInXEnsemble(all_states) & paths.LengthEnsemble(1),
            paths.AllOutXEnsemble(all_states)
        ])
        self.full_ensemble = paths.SequentialEnsemble([
            paths.AllInXEnsemble(all_states) & paths.LengthEnsemble(1),
            paths.AllOutXEnsemble(all_states),
            paths.AllInXEnsemble(all_states) & paths.LengthEnsemble(1)
        ])
        self.all_states = all_states
 def _tps_ensemble(self, stateA, stateB):
     return paths.SequentialEnsemble([
         paths.AllInXEnsemble(stateA) & paths.LengthEnsemble(1),
         paths.AllOutXEnsemble(stateA | stateB),
         paths.AllInXEnsemble(stateB) & paths.LengthEnsemble(1)
     ])
# The idea here is a little subtle, but it makes nice use of our generalized path ensemble idea.
# 
# We want a path which contains at least one frame in each state. The question is, what ensemble can we use to create such a trajectory?
# 
# The first obvious thought would be `goal_ensemble = PartInXEnsemble(stateA) & PartInXEnsemble(stateB)` (which can, of course, be further generalized to more states). However, while that *is* the ensemble we want to eventually satisfy, we can't use its `can_append` to create it, because its `can_append` always returns `True`: the trajectory will go on forever!
# 
# But we can use a trick: since what we want is the first trajectory that satisfies `goal_ensemble`, we know that every shorter trajectory will not satisfy it. This means that the shorter trajectories must satisfy the *complement* of `goal_ensemble`, and the trajectory we want will be the first trajectory that does *not* satisfy the complement!
# 
# So the trick we'll use is to build the trajectory by using the fact that the shorter trajectories are in the complement of `goal_ensemble`, which is given by `complement = AllOutXEnsemble(stateA) | AllOutXEnsemble(stateB)`. The `generate` function will stop when that is no longer true, giving us the trajectory we want. This can be directly generalized to more states.
# 
# Note that here we're not even using the `can_append` function. That happens to be the same as the ensemble itself for this particular ensemble, but conceptually, we're actually using the test of whether a trajectory is in the ensemble at all.

# In[8]:


init_traj_ensemble = paths.AllOutXEnsemble(C_7eq) | paths.AllOutXEnsemble(alpha_R)


# In[9]:


# generate trajectory that includes frame in both states
trajectory = hi_T_engine.generate(hi_T_engine.current_snapshot, [init_traj_ensemble])


# In[10]:


# create a network so we can use its ensemble to obtain an initial trajectory
# use all-to-all because we don't care if initial traj is A->B or B->A: it can be reversed
tmp_network = paths.TPSNetwork.from_states_all_to_all([C_7eq, alpha_R])
示例#21
0
interfaces = paths.VolumeInterfaceSet(cv,
                                      minvals=0.0,
                                      maxvals=np.linspace(
                                          max_bound, min_unbound - 0.01,
                                          ninterfaces))

print('Creating network...')
mistis = paths.MISTISNetwork([(bound, interfaces, unbound)])

initial_trajectory_method = 'bootstrap'
if initial_trajectory_method == 'high-temperature':
    # We are starting in the bound state, so
    # generate high-temperature trajectory that reaches the unbound state
    print('Generating high-temperature trajectory...')
    #ensemble = not (paths.ExitsXEnsemble(bound) & paths.EntersXEnsemble(unbound))
    unbinding_ensemble = paths.AllOutXEnsemble(unbound)
    bridging_ensemble = paths.AllOutXEnsemble(bound) & paths.AllOutXEnsemble(
        unbound)
    initial_trajectories = list()
    minus_trajectories = list()
    tmp_network = paths.TPSNetwork(bound, unbound)
    attempt = 0
    while (len(initial_trajectories) == 0) or (len(minus_trajectories) == 0):
        print('Attempt %d' % attempt)
        long_trajectory = engine_hot.generate(initial_snapshot_hot,
                                              [unbinding_ensemble])
        print('long trajectory:')
        print(long_trajectory)
        distances = np.array([cv(snapshot) for snapshot in long_trajectory])
        print(distances)
        # split out the subtrajectory of interest
示例#22
0
    def build_sampling_transitions(self, transitions):
        # identify transition pairs
        transition_pair_set_dict = {}
        for initial in self.initial_states:
            for t1 in [t for t in transitions if t.stateA==initial]:
                t_reverse = [
                    t for t in transitions 
                    if t.stateA == t1.stateB and t.stateB == t1.stateA
                ]
                if len(t_reverse) == 1:
                    key = frozenset([t1.stateA, t1.stateB])
                    new_v = [t1, t_reverse[0]]
                    if key not in transition_pair_set_dict.keys():
                        transition_pair_set_dict[key] = new_v
                elif len(t_reverse) > 1:  # pragma: no cover
                    raise RuntimeError("More than one reverse transition")
                # if len(t_reverse) is 0, we just pass

        self.transition_pairs = transition_pair_set_dict.values()

        if len(self.transition_pairs) > 0:
            all_in_pairs = reduce(list.__add__, map(lambda x: list(x), 
                                                    self.transition_pairs))
        else:
            all_in_pairs = []

        # build sampling transitions
        all_states = paths.join_volumes(self.initial_states + self.final_states)
        all_states_set = set(self.initial_states + self.final_states)
        self.transition_to_sampling = {}
        for transition in transitions:
            stateA = transition.stateA
            stateB = transition.stateB
            if self.strict_sampling:
                final_state = stateB
                other_states = paths.join_volumes(all_states_set -
                                                  set([stateA, stateB]))
                ensemble_to_intersect = paths.AllOutXEnsemble(other_states)
            else:
                final_state = all_states
                ensemble_to_intersect = paths.FullEnsemble()

            sample_trans = paths.TISTransition(
                stateA=stateA,
                stateB=final_state,
                interfaces=transition.interfaces,
                orderparameter=transition.orderparameter
            )

            new_ensembles = [e & ensemble_to_intersect 
                             for e in sample_trans.ensembles]
            if self.strict_sampling:
                for (old, new) in zip(new_ensembles, sample_trans.ensembles):
                    old.name = new.name + " strict"
            sample_trans.ensembles = new_ensembles
            sample_trans.named("Sampling " + str(stateA) + "->" + str(stateB))
            self.transition_to_sampling[transition] = sample_trans

        self.x_sampling_transitions = self.transition_to_sampling.values()

        # combining the minus interfaces
        for initial in self.initial_states:
            innermosts = []
            trans_from_initial = [
                t for t in self.x_sampling_transitions
                if t.stateA==initial
            ]
            for t1 in trans_from_initial:
                innermosts.append(t1.interfaces[0])
            minus = paths.MinusInterfaceEnsemble(
                state_vol=initial,
                innermost_vols=innermosts
            )
            try:
                self.special_ensembles['minus'][minus] = trans_from_initial
            except KeyError:
                self.special_ensembles['minus'] = {minus : trans_from_initial}
    def __init__(self, storage, engine=None, states=None, randomizer=None,
                 initial_snapshots=None, rc=None):

        # state definition
        self.states = states
        state_A = states[0]
        state_B = states[1]

        # get min/max reaction coordinate of initial snapshots
        self.rc = rc
        rc_array = np.array(self.rc(initial_snapshots))
        rc_min = np.nextafter(rc_array.min(), -np.inf)
        rc_max = np.nextafter(rc_array.max(), np.inf)

        # define reaction coordinate region of initial snapshots
        # = starting_volume
        self.dividing_surface = paths.CVDefinedVolume(self.rc, rc_min, rc_max)

        # define volume between state A and the dividing surface (including A)
        self.volume_towards_A = paths.CVDefinedVolume(self.rc, -np.inf, rc_max)

        # shoot backward until we hit A but never cross the dividing surface
        backward_ensemble = paths.SequentialEnsemble([
            paths.AllInXEnsemble(state_A) & paths.LengthEnsemble(1),
            paths.AllInXEnsemble(self.volume_towards_A - state_A)
        ])

        # shoot forward until we hit state B without hitting A first
        # caution: since the mover will consist of backward and forward
        #          shoot in sequence, the starting ensemble for the forward
        #          shoot is the output of the backward shoot, i.e. a
        #          trajectory that runs from A to the dividing surface and
        #          not just a point there.
        forward_ensemble = paths.SequentialEnsemble([
            paths.AllInXEnsemble(state_A) & paths.LengthEnsemble(1),
            paths.AllOutXEnsemble(state_A | state_B),
            paths.AllInXEnsemble(state_B) & paths.LengthEnsemble(1),
        ])

        super(ReactiveFluxSimulation, self).__init__(
            storage=storage,
            engine=engine,
            starting_volume=self.dividing_surface,
            forward_ensemble=forward_ensemble,
            backward_ensemble=backward_ensemble,
            randomizer=randomizer,
            initial_snapshots=initial_snapshots
        )

        # create backward mover (starting from single point)
        self.backward_mover = paths.BackwardExtendMover(
            ensemble=self.starting_ensemble,
            target_ensemble=self.backward_ensemble
        )

        # create forward mover (starting from the backward ensemble)
        self.forward_mover = paths.ForwardExtendMover(
            ensemble=self.backward_ensemble,
            target_ensemble=self.forward_ensemble
        )

        # create mover combining forward and backward shooting,
        # abort if backward mover fails
        self.mover = paths.NonCanonicalConditionalSequentialMover([
            self.backward_mover,
            self.forward_mover
        ])