示例#1
0
    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
示例#2
0
    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
示例#3
0
    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
示例#4
0
    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)
示例#5
0
    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)
示例#6
0
    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)
示例#7
0
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)
示例#8
0
    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
示例#9
0
    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
示例#10
0
文件: kinetics.py 项目: Acellera/htmd
    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