def getRates(self, source=None, sink=None): """ Get the rates between two states Parameters ---------- source : int, optional The state index to use as source sink : int, optional The state index to use as sink Returns ------- rates : :class:`Rates` object A Rates object containing the rates Example ------- >>> kin = Kinetics(model, temperature=300, concentration=0.015) >>> r = kin.getRates() >>> print(r) >>> dg = r.g0eq """ actset = self.model.hmm.active_set if source is None: source = self.source else: source = np.where(actset == source)[0] if sink is None: sink = self.sink else: sink = np.where(actset == sink)[0] logger.info('Calculating rates between source: {} and sink: {} states.'.format(actset[source], actset[sink])) if source == sink: logger.info('Calculating rates between state and itself gives 0') r = Rates(); r.mfpton = 0; r.mfptoff=0; r.koff=0; r.kon=0; r.g0eq=0; r.kdeq=0; return r if source == self.source: # Apply concentration only on the bulk state conc = self.concentration elif sink == self.source: conc = 1 / self.concentration else: conc = 1 model = self.model from msmtools.analysis import mfpt r = Rates() r.mfpton = model.data.fstep * model.hmm.lag * mfpt(self.model.hmm.transition_matrix, origin=source, target=sink) r.mfptoff = model.data.fstep * model.hmm.lag * mfpt(self.model.hmm.transition_matrix, origin=sink, target=source) r.koff = 1E9 / r.mfptoff r.kon = 1E9 / (r.mfpton * conc) eq = model.hmm.stationary_distribution sinkeq = np.sum(eq[sink]) sourceeq = np.sum(eq[source]) if conc != 1: logger.info('Concentration correction of {:.2f} kcal/mol.'.format(-self._kBT * np.log(1 / conc))) r.g0eq = -self._kBT * np.log(sinkeq / (conc * sourceeq)) r.kdeq = np.exp(r.g0eq / self._kBT) return r
def getRates(self, source=None, sink=None, states='macro'): """ Get the rates between two states Parameters ---------- source : int, optional The state index to use as source sink : int, optional The state index to use as sink states : ['macro','micro'], optional The state type of the states given before Returns ------- rates : :class:`Rates` object A Rates object containing the rates Example ------- >>> kin = Kinetics(model, temperature=300, concentration=0.015) >>> r = kin.getRates() >>> print(r) >>> dg = r.g0eq """ self._intergrityCheck() if source is None: source = self.source if sink is None: sink = self.sink if source == sink: logger.info('Calculating rates between state and itself gives 0') r = Rates(); r.mfpton = 0; r.mfptoff=0; r.koff=0; r.kon=0; r.g0eq=0; r.kdeq=0; return r if source == self.source: # Apply concentration only on the bulk state conc = self.concentration elif sink == self.source: conc = 1 / self.concentration else: conc = 1 model = self.model from msmtools.analysis import mfpt r = Rates() r.mfpton = model.data.fstep * model.lag * mfpt(self.model.P, origin=source, target=sink) r.mfptoff = model.data.fstep * model.lag * mfpt(self.model.P, origin=sink, target=source) r.koff = 1E9 / r.mfptoff r.kon = 1E9 / (r.mfpton * conc) eq = model.hmm.stationary_distribution sinkeq = eq[sink] sourceeq = eq[source] r.g0eq = -self._kBT * np.log(sinkeq / (conc * sourceeq)) r.kdeq = np.exp(r.g0eq / self._kBT) return r
def getRates(self, source=None, sink=None): """ Get the rates between two states Parameters ---------- source : int, optional The state index to use as source sink : int, optional The state index to use as sink Returns ------- rates : :class:`Rates` object A Rates object containing the rates Example ------- >>> kin = Kinetics(model, temperature=300, concentration=0.015) >>> r = kin.getRates() >>> print(r) >>> dg = r.g0eq """ if source is None: source = self.source if sink is None: sink = self.sink logger.info('Calculating rates between source: {} and sink: {} states.'.format(source, sink)) if source == sink: logger.info('Calculating rates between state and itself gives 0') r = Rates(); r.mfpton = 0; r.mfptoff=0; r.koff=0; r.kon=0; r.g0eq=0; r.kdeq=0; return r if source == self.source: # Apply concentration only on the bulk state conc = self.concentration elif sink == self.source: conc = 1 / self.concentration else: conc = 1 model = self.model from msmtools.analysis import mfpt r = Rates() r.mfpton = model.data.fstep * model.hmm.lag * mfpt(self.model.hmm.transition_matrix, origin=source, target=sink) r.mfptoff = model.data.fstep * model.hmm.lag * mfpt(self.model.hmm.transition_matrix, origin=sink, target=source) r.koff = 1E9 / r.mfptoff r.kon = 1E9 / (r.mfpton * conc) eq = model.hmm.stationary_distribution sinkeq = np.sum(eq[sink]) sourceeq = np.sum(eq[source]) if conc != 1: logger.info('Concentration correction of {:.2f} kcal/mol.'.format(-self._kBT * np.log(1 / conc))) r.g0eq = -self._kBT * np.log(sinkeq / (conc * sourceeq)) r.kdeq = np.exp(r.g0eq / self._kBT) return r
def test_mfpt_between_sets(self): x = mfpt(self.P, [1, 2], origin=0) assert_allclose(x, self.o0t12) x = mfpt(self.P, [0, 1], origin=2) assert_allclose(x, self.o2t01) x = mfpt(self.P, 2, origin=[0, 1]) assert_allclose(x, self.o01t2) x = mfpt(self.P, 0, origin=[1, 2]) assert_allclose(x, self.o12t0)
def test_mfpt(self): x = mfpt(self.P, 0) assert_allclose(x, self.m0) x = mfpt(self.P, 1) assert_allclose(x, self.m1) x = mfpt(self.P, 2) assert_allclose(x, self.m2) x = mfpt(self.P, [0, 1]) assert_allclose(x, self.m01) x = mfpt(self.P, [1, 2]) assert_allclose(x, self.m12)
def test_time_units(self): dtraj = np.random.randint(0, 4, 1000) tau = 12 dt = 0.456 msmobj = estimate_markov_model(dtraj, lag=tau, dt_traj='%f ns' % dt) # check MFPT consistency mfpt_ref = msmobj.mfpt([0], [1]) tptobj = tpt(msmobj, [0], [1]) assert_allclose(tptobj.mfpt, mfpt_ref) assert_allclose(msmana.mfpt(msmobj.P, [1], [0], tau=tau) * dt, mfpt_ref) assert_allclose(np.dot(msmobj.stationary_distribution, tptobj.backward_committor) / tptobj.total_flux, mfpt_ref) # check flux consistency total_flux_ref = tptobj.total_flux A = tptobj.A B = tptobj.B I = tptobj.I assert_allclose(tptobj.gross_flux[A, :][:, B].sum() + tptobj.gross_flux[A, :][:, I].sum(), total_flux_ref) assert_allclose(tptobj.net_flux[A, :][:, B].sum() + tptobj.net_flux[A, :][:, I].sum(), total_flux_ref) assert_allclose(tptobj.flux[A, :][:, B].sum() + tptobj.flux[A, :][:, I].sum(), total_flux_ref) mf = tptobj.major_flux(1.0) assert_allclose(mf[A, :][:, B].sum() + mf[A, :][:, I].sum(), total_flux_ref) # check that the coarse-grained version is consistent too _, tptobj2 = tptobj.coarse_grain([A, I, B]) assert_allclose(tptobj2.total_flux, total_flux_ref) assert_allclose(tptobj2.mfpt, mfpt_ref)
def mfpt_all(T, mss): Nmss = mss.shape[0] m_t = [] for i in range(Nmss): for j in range(Nmss): if ( i != j ): m_t.append( mfpt(T,mss[j],origin=mss[i]) ) return np.array(m_t)
def setUpClass(cls): # 5-state toy system cls.P = np.array([[0.8, 0.15, 0.05, 0.0, 0.0], [0.1, 0.75, 0.05, 0.05, 0.05], [0.05, 0.1, 0.8, 0.0, 0.05], [0.0, 0.2, 0.0, 0.8, 0.0], [0.0, 0.02, 0.02, 0.0, 0.96]]) cls.A = [0] cls.B = [4] cls.P_mfpt = np.zeros_like(cls.P) for ii in np.arange(cls.P.shape[0]): for jj in np.arange(cls.P.shape[1]): cls.P_mfpt[ii, jj] = mfpt(cls.P, [ii], [jj]) return cls
def getRates(self, source=None, sink=None, states='macro', _logger=True): """ Get the rates between two (sets of) states Parameters ---------- source : int, optional The state index to use as source sink : int, optional The state index to use as sink states : ['macro','micro'], optional The state type of the states given before Returns ------- rates : :class:`Rates` object A Rates object containing the rates Example ------- >>> kin = Kinetics(model, temperature=300, concentration=0.015) >>> r = kin.getRates() >>> print(r) >>> dg = r.g0eq >>> r = kin.getRates(source=4, sink=[0,1,2,3]) """ import numbers self._intergrityCheck() if source is None: source = self.source if sink is None: sink = self.sink if isinstance(source, numbers.Integral): source = [ source, ] if isinstance(sink, numbers.Integral): sink = [ sink, ] if _logger: logger.info( 'Calculating rates between source: {} and sink: {} states.'. format(source, sink)) if len(np.intersect1d(source, sink)) != 0: if _logger: logger.info( 'Calculating rates between state and itself gives 0') r = Rates() return r if self.source in source: # Apply concentration only on the bulk state conc = self.concentration elif self.source in sink: # Invert concentration is bulk state is in sink if _logger: logger.info( 'Bulk state detected in sink. Applying concentration correction to sink instead of source.' ) conc = 1 / self.concentration else: conc = 1 model = self.model if states == 'macro': # Finding the microstates of the macrostates eq = model.eqDistribution( plot=False ) # If macro, use the membership probs to calculate eq prob sinkeq = np.sum( eq[sink] ) # sink and source might be multiple macros so we have to sum them sourceeq = np.sum(eq[source]) sourcemicros = [] for s in source: sourcemicros += list(np.where(model.macro_ofmicro == s)[0]) sinkmicros = [] for s in sink: sinkmicros += list(np.where(model.macro_ofmicro == s)[0]) elif states == 'micro': eq = model.msm.stationary_distribution sinkeq = np.sum(eq[sink]) sourceeq = np.sum(eq[source]) sourcemicros = source sinkmicros = sink from msmtools.analysis import mfpt r = Rates() r.mfpton = model.data.fstep * model.lag * mfpt( self.model.P, origin=sourcemicros, target=sinkmicros) r.mfptoff = model.data.fstep * model.lag * mfpt( self.model.P, origin=sinkmicros, target=sourcemicros) r.koff = 1E9 / r.mfptoff r.kon = 1E9 / (r.mfpton * conc) if conc != 1: if _logger: logger.info( 'Concentration correction of {:.2f} kcal/mol.'.format( -self._kBT * np.log(1 / conc))) r.g0eq = -self._kBT * np.log(sinkeq / (conc * sourceeq)) r.kdeq = np.exp(r.g0eq / self._kBT) return r
def getRates(self, source=None, sink=None, states='macro', _logger=True): """ Get the rates between two (sets of) states Parameters ---------- source : int, optional The state index to use as source sink : int, optional The state index to use as sink states : ['macro','micro'], optional The state type of the states given before Returns ------- rates : :class:`Rates` object A Rates object containing the rates Example ------- >>> kin = Kinetics(model, temperature=300, concentration=0.015) >>> r = kin.getRates() >>> print(r) >>> dg = r.g0eq >>> r = kin.getRates(source=4, sink=[0,1,2,3]) """ import numbers self._intergrityCheck() if source is None: source = self.source if sink is None: sink = self.sink if isinstance(source, numbers.Integral): source = [source, ] if isinstance(sink, numbers.Integral): sink = [sink, ] if _logger: logger.info('Calculating rates between source: {} and sink: {} states.'.format(source, sink)) if len(np.intersect1d(source, sink)) != 0: if _logger: logger.info('Calculating rates between state and itself gives 0') r = Rates() return r if self.source in source: # Apply concentration only on the bulk state conc = self.concentration elif self.source in sink: # Invert concentration is bulk state is in sink if _logger: logger.info('Bulk state detected in sink. Applying concentration correction to sink instead of source.') conc = 1 / self.concentration else: conc = 1 model = self.model if states == 'macro': # Finding the microstates of the macrostates eq = model.eqDistribution(plot=False) # If macro, use the membership probs to calculate eq prob sinkeq = np.sum(eq[sink]) # sink and source might be multiple macros so we have to sum them sourceeq = np.sum(eq[source]) sourcemicros = [] for s in source: sourcemicros += list(np.where(model.macro_ofmicro == s)[0]) sinkmicros = [] for s in sink: sinkmicros += list(np.where(model.macro_ofmicro == s)[0]) elif states == 'micro': eq = model.msm.stationary_distribution sinkeq = np.sum(eq[sink]) sourceeq = np.sum(eq[source]) sourcemicros = source sinkmicros = sink from msmtools.analysis import mfpt r = Rates() r.mfpton = model.data.fstep * model.lag * mfpt(self.model.P, origin=sourcemicros, target=sinkmicros) r.mfptoff = model.data.fstep * model.lag * mfpt(self.model.P, origin=sinkmicros, target=sourcemicros) r.koff = 1E9 / r.mfptoff r.kon = 1E9 / (r.mfpton * conc) if conc != 1: if _logger: logger.info('Concentration correction of {:.2f} kcal/mol.'.format(-self._kBT * np.log(1 / conc))) r.g0eq = -self._kBT * np.log(sinkeq / (conc * sourceeq)) r.kdeq = np.exp(r.g0eq / self._kBT) return r