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 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 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}