def __init__(self, initial_states, final_states, allow_self_transitions=False, **kwargs): # **kwargs gets passed to the transition super(GeneralizedTPSNetwork, self).__init__() try: iter(initial_states) except TypeError: initial_states = [initial_states] try: iter(final_states) except TypeError: final_states = [final_states] self.special_ensembles = {None: {}} self.initial_states = initial_states self.final_states = final_states all_initial = paths.join_volumes(initial_states) if len(initial_states) > 1: all_initial.name = "|".join([v.name for v in initial_states]) if set(initial_states) == set(final_states) or len(final_states) == 1: all_final = all_initial else: all_final = paths.join_volumes(final_states) all_final.name = "|".join([v.name for v in final_states]) self._sampling_transitions = [] for my_initial in initial_states: my_final_states = [ final for final in final_states if my_initial != final or allow_self_transitions ] my_final = paths.join_volumes(my_final_states) if len(my_final_states) > 1: my_final.name = "|".join([v.name for v in my_final_states]) if len(self._sampling_transitions) == 0: self._sampling_transitions = [ self.TransitionType(my_initial, my_final, **kwargs) ] elif len(self._sampling_transitions) == 1: self._sampling_transitions[0].add_transition( my_initial, my_final) else: raise RuntimeError( "More than one sampling transition for TPS?") self.transitions = { (initial, final): self.TransitionType(initial, final, **kwargs) for (initial, final) in itertools.product(initial_states, final_states) if initial != final }
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()
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()
def __init__(self, initial_states, final_states, allow_self_transitions=False, **kwargs): # **kwargs gets passed to the transition super(GeneralizedTPSNetwork, self).__init__() try: iter(initial_states) except TypeError: initial_states = [initial_states] try: iter(final_states) except TypeError: final_states = [final_states] self.special_ensembles = {None: {}} self.initial_states = initial_states self.final_states = final_states all_initial = paths.join_volumes(initial_states) if len(initial_states) > 1: all_initial.name = "|".join([v.name for v in initial_states]) if set(initial_states) == set(final_states) or len(final_states) == 1: all_final = all_initial else: all_final = paths.join_volumes(final_states) all_final.name = "|".join([v.name for v in final_states]) self._sampling_transitions = [] for my_initial in initial_states: my_final_states = [final for final in final_states if my_initial != final or allow_self_transitions] my_final = paths.join_volumes(my_final_states) if len(my_final_states) > 1: my_final.name = "|".join([v.name for v in my_final_states]) if len(self._sampling_transitions) == 0: self._sampling_transitions = [ self.TransitionType(my_initial, my_final, **kwargs) ] elif len(self._sampling_transitions) == 1: self._sampling_transitions[0].add_transition(my_initial, my_final) else: raise RuntimeError("More than one sampling transition for TPS?") self.transitions = { (initial, final) : self.TransitionType(initial, final, **kwargs) for (initial, final) in itertools.product(initial_states, final_states) if initial != final }
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
def _build_fromstate_transitions(self, trans_info): """ Builds the sampling transitions (the self.from_state dictionary). This also sets self.states (list of states volumes), self.outers (list of interface volumes making the MS-outer interface), and self.outer_ensembles (list of TISEnsembles associated with the self.outers interfaces). Additionally, it gives default names volumes, interfaces, and transitions. Parameters ---------- trans_info : list of 2-tuples See description in __init__. """ states, interfaces = zip(*trans_info) orderparams = [iface_set.cv for iface_set in interfaces] # NAMING STATES (give default names) all_states = paths.join_volumes(states).named("all states") all_names = list(set([s.name for s in states])) unnamed_states = [s for s in states if not s.is_named] _name_unnamed_states(unnamed_states, all_names) # BUILDING ENSEMBLES self.states = states for (state, ifaces) in trans_info: this_trans = self.build_one_state_sampling_transition( state=state, interfaces=ifaces, all_states=states) # op = ifaces.cv # state_index = states.index(state) # other_states = states[:state_index]+states[state_index+1:] # other_states = list(set(states) - set([state])) # union_others = paths.join_volumes( # volume_list=other_states, # name="all states except " + str(state.name) # ) # union_others = paths.volume.join_volumes(other_states) # union_others.named("all states except " + str(state.name)) # out_others = paths.AllOutXEnsemble(union_others) # this_trans = paths.TISTransition( # stateA=state, # stateB=union_others, # interfaces=ifaces, # name="Out " + state.name, # orderparameter=op # ) self.from_state[state] = this_trans this_minus = self.from_state[state].minus_ensemble #& out_others this_inner = self.from_state[state].ensembles[0] # TODO: this should use defaultdict, I think try: self.special_ensembles['minus'][this_minus] = [this_trans] except KeyError: self.special_ensembles['minus'] = {this_minus: [this_trans]}
def _build_sampling_transitions(self, initial_states, final_states, allow_self_transitions, **kwargs): if allow_self_transitions: initial_to_joined_final = { initial: paths.join_volumes(final_states, _or_bar_namer) for initial in initial_states } else: initial_to_joined_final = { initial: paths.join_volumes( [final for final in final_states if initial != final], _or_bar_namer) for initial in initial_states } sampling_transitions = self._sampling_transitions_from_pairs( state_pairs=list(initial_to_joined_final.items()), **kwargs) return sampling_transitions
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 __init__(self, initial_states, final_states, allow_self_transitions=False, **kwargs): # **kwargs gets passed to the transition super(GeneralizedTPSNetwork, self).__init__() self.initial_states = listify(initial_states) self.final_states = listify(final_states) self.special_ensembles = {None: {}} all_initial = paths.join_volumes(self.initial_states, _or_bar_namer) if set(self.initial_states) == set(self.final_states): all_final = all_initial # so we don't create 2 objs for it else: all_final = paths.join_volumes(self.final_states, _or_bar_namer) self._sampling_transitions, self.transitions = \ self._build_transitions(self.initial_states, self.final_states, allow_self_transitions, **kwargs)
def _build_sampling_transitions(self, initial_states, final_states, allow_self_transitions, **kwargs): if allow_self_transitions: initial_to_joined_final = { initial: paths.join_volumes(final_states, _or_bar_namer) for initial in initial_states } else: initial_to_joined_final = { initial: paths.join_volumes([final for final in final_states if initial != final], _or_bar_namer) for initial in initial_states } sampling_transitions = self._sampling_transitions_from_pairs( state_pairs=list(initial_to_joined_final.items()), **kwargs ) return sampling_transitions
def build_one_state_sampling_transition(state, interfaces, all_states): other_states = list(set(all_states) - set([state])) union_others = paths.join_volumes(volume_list=other_states, name="all states except " + str(state.name)) this_trans = paths.TISTransition(stateA=state, stateB=union_others, interfaces=interfaces, name="Out " + state.name, orderparameter=interfaces.cv) return this_trans
def build_one_state_sampling_transition(state, interfaces, all_states): other_states = list(set(all_states) - set([state])) union_others = paths.join_volumes( volume_list=other_states, name="all states except " + str(state.name) ) this_trans = paths.TISTransition( stateA=state, stateB=union_others, interfaces=interfaces, name="Out " + state.name, orderparameter=interfaces.cv ) return this_trans
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
def __init__(self, initial_states, final_states): super(TPSNetwork, self).__init__() try: iter(initial_states) except TypeError: initial_states = [initial_states] try: iter(final_states) except TypeError: final_states = [final_states] all_initial = paths.join_volumes(initial_states) all_initial.name = "|".join([v.name for v in initial_states]) all_final = paths.join_volumes(final_states) all_final.name = "|".join([v.name for v in final_states]) self._sampling_transitions = [ paths.TPSTransition(all_initial, all_final) ] self.transitions = { (initial, final): paths.TPSTransition(initial, final) for (initial, final) in itertools.product(initial_states, final_states) if initial != final }
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
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()
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
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)
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
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)
def build_sampling_transitions(self, transitions): # identify transition pairs for initial in self.initial_states: transition_pair_dict = {} for t1 in [t for t in transitions if t.stateA==initial]: reverse_trans = None for t2 in transitions: if t2.stateA==t1.stateB and t2.stateB==t1.stateA: transition_pair_dict[t1] = t2 # TODO: speed this up with a set? for key in transition_pair_dict.keys(): value = transition_pair_dict[key] if value in transition_pair_dict.keys(): del transition_pair_dict[value] self.transition_pairs = [(k, transition_pair_dict[k]) for k in transition_pair_dict.keys()] all_in_pairs = reduce(list.__add__, map(lambda x: list(x), self.transition_pairs)) # build sampling transitions # TODO: really, I'd like to FORBID all other states (change the # ensemble to intersection with AllOutXEnsemble(other_states)), but # for now, let's accept all other states -- the key is to stop the # trajectory. Forbidding all other states can be done once building # the movers is better separated. all_states = paths.join_volumes(self.initial_states + self.final_states) self.transition_to_sampling = {} for transition in transitions: stateA = transition.stateA stateB = transition.stateB if transition not in all_in_pairs: sample_trans = paths.TISTransition( stateA=stateA, stateB=all_states, interfaces=transition.interfaces, orderparameter=transition.orderparameter ) else: sample_trans = paths.TISTransition( stateA=stateA, stateB=all_states, interfaces=transition.interfaces[:-1], orderparameter=transition.orderparameter ) sample_trans.name = "Sampling " + str(stateA) + "->" + str(stateB) self.transition_to_sampling[transition] = sample_trans self.x_sampling_transitions = self.transition_to_sampling.values() # build non-transition interfaces # combining the MS-outer interfaces for pair in self.transition_pairs: this_outer = paths.ensemble.join_ensembles( [pair[0].ensembles[-1], pair[1].ensembles[-1]] ) s_pair = [self.transition_to_sampling[p] for p in pair] try: self.special_ensembles['ms_outer'][this_outer] = list(s_pair) except KeyError: self.special_ensembles['ms_outer'] = {this_outer : list(s_pair)} # 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, 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 __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 _build_fromstate_transitions(self, trans_info): """ Builds the sampling transitions (the self.from_state dictionary). This also sets self.states (list of states volumes), self.outers (list of interface volumes making the MS-outer interface), and self.outer_ensembles (list of TISEnsembles associated with the self.outers interfaces). Additionally, it gives default names volumes, interfaces, and transitions. Parameters ---------- trans_info : list of 2-tuples See description in __init__. """ states, interfaces = zip(*trans_info) orderparams = [iface_set.cv for iface_set in interfaces] # NAMING STATES (give default names) all_states = paths.join_volumes(states).named("all states") all_names = list(set([s.name for s in states])) unnamed_states = [s for s in states if not s.is_named] _name_unnamed_states(unnamed_states, all_names) # BUILDING ENSEMBLES self.states = states for (state, ifaces) in trans_info: this_trans = self.build_one_state_sampling_transition( state=state, interfaces=ifaces, all_states=states ) # op = ifaces.cv # state_index = states.index(state) # other_states = states[:state_index]+states[state_index+1:] # other_states = list(set(states) - set([state])) # union_others = paths.join_volumes( # volume_list=other_states, # name="all states except " + str(state.name) # ) # union_others = paths.volume.join_volumes(other_states) # union_others.named("all states except " + str(state.name)) # out_others = paths.AllOutXEnsemble(union_others) # this_trans = paths.TISTransition( # stateA=state, # stateB=union_others, # interfaces=ifaces, # name="Out " + state.name, # orderparameter=op # ) self.from_state[state] = this_trans this_minus = self.from_state[state].minus_ensemble #& out_others this_inner = self.from_state[state].ensembles[0] # TODO: this should use defaultdict, I think try: self.special_ensembles['minus'][this_minus] = [this_trans] except KeyError: self.special_ensembles['minus'] = {this_minus : [this_trans]}
def build_sampling_transitions(self, transitions): # identify transition pairs for initial in self.initial_states: transition_pair_dict = {} for t1 in [t for t in transitions if t.stateA == initial]: reverse_trans = None for t2 in transitions: if t2.stateA == t1.stateB and t2.stateB == t1.stateA: transition_pair_dict[t1] = t2 # TODO: speed this up with a set? for key in transition_pair_dict.keys(): value = transition_pair_dict[key] if value in transition_pair_dict.keys(): del transition_pair_dict[value] self.transition_pairs = [(k, transition_pair_dict[k]) for k in transition_pair_dict.keys()] all_in_pairs = reduce(list.__add__, map(lambda x: list(x), self.transition_pairs)) # build sampling transitions # TODO: really, I'd like to FORBID all other states (change the # ensemble to intersection with AllOutXEnsemble(other_states)), but # for now, let's accept all other states -- the key is to stop the # trajectory. Forbidding all other states can be done once building # the movers is better separated. all_states = paths.join_volumes(self.initial_states + self.final_states) self.transition_to_sampling = {} for transition in transitions: stateA = transition.stateA stateB = transition.stateB if transition not in all_in_pairs: sample_trans = paths.TISTransition( stateA=stateA, stateB=all_states, interfaces=transition.interfaces, orderparameter=transition.orderparameter) else: sample_trans = paths.TISTransition( stateA=stateA, stateB=all_states, interfaces=transition.interfaces[:-1], orderparameter=transition.orderparameter) sample_trans.named("Sampling " + str(stateA) + "->" + str(stateB)) self.transition_to_sampling[transition] = sample_trans self.x_sampling_transitions = self.transition_to_sampling.values() # build non-transition interfaces # combining the MS-outer interfaces for pair in self.transition_pairs: this_outer = paths.ensemble.join_ensembles( [pair[0].ensembles[-1], pair[1].ensembles[-1]]) s_pair = [self.transition_to_sampling[p] for p in pair] try: self.special_ensembles['ms_outer'][this_outer] = list(s_pair) except KeyError: self.special_ensembles['ms_outer'] = {this_outer: list(s_pair)} # 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 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}