def asymptotic_areas(tres, roots, QAA, QFF, QAF, QFA, kA, kF, GAF, GFA): """ Find the areas of the asymptotic pdf (Eq. 58, HJC92). Parameters ---------- tres : float Time resolution (dead time). roots : array_like, shape (1,kA) Roots of the asymptotic pdf. QAA : array_like, shape (kA, kA) QFF : array_like, shape (kF, kF) QAF : array_like, shape (kA, kF) QFA : array_like, shape (kF, kA) QAA, QFF, QAF, QFA - submatrices of Q. kA : int A number of open states in kinetic scheme. kF : int A number of shut states in kinetic scheme. GAF : array_like, shape (kA, kB) GFA : array_like, shape (kB, kA) GAF, GFA- transition probabilities Returns ------- areas : ndarray, shape (1, kA) """ expQFF = qml.expQt(QFF, tres) expQAA = qml.expQt(QAA, tres) eGAF = qml.eGs(GAF, GFA, kA, kF, expQFF) eGFA = qml.eGs(GFA, GAF, kF, kA, expQAA) phiA = qml.phiHJC(eGAF, eGFA, kA) R = qml.AR(roots, tres, QAA, QFF, QAF, QFA, kA, kF) uF = np.ones((kF, 1)) areas = np.zeros(kA) for i in range(kA): areas[i] = ( (-1 / roots[i]) * np.dot(phiA, np.dot(np.dot(R[i], np.dot(QAF, expQFF)), uF))) # rowA = np.zeros((kA,kA)) # colA = np.zeros((kA,kA)) # for i in range(kA): # WA = qml.W(roots[i], tres, # QAA, QFF, QAF, QFA, kA, kF) # rowA[i] = qml.pinf(WA) # AW = np.transpose(WA) # colA[i] = qml.pinf(AW) # # for i in range(kA): # uF = np.ones((kF,1)) # nom = np.dot(np.dot(np.dot(np.dot(np.dot(phiA, colA[i]), rowA[i]), # QAF), expQFF), uF) # W1A = qml.dW(roots[i], tres, QAF, QFF, QFA, kA, kF) # denom = -roots[i] * np.dot(np.dot(rowA[i], W1A), colA[i]) # areas[i] = nom / denom return areas
def adjacent_open_to_shut_range_mean(u1, u2, QAA, QAF, QFF, QFA, phiA): """ Calculate mean (ideal- no missed events) open times adjacent to a specified shut time range. Parameters ---------- u1, u2 : floats Shut time range. QAA, QAF, QFF, QFA : array_like Submatrices of Q. phiA : array_like, shape (1, kA) Initial vector for openings Returns ------- m : float Mean open time. """ kA = QAA.shape[0] uA = np.ones((kA))[:,np.newaxis] invQAA, invQFF = -nplin.inv(QAA), nplin.inv(QFF) expQFFr = qml.expQt(QFF, u2) - qml.expQt(QFF, u1) col = np.dot(np.dot(np.dot(np.dot(QAF, invQFF), expQFFr), QFA), uA) row1 = np.dot(phiA, qml.Qpow(invQAA, 2)) row2 = np.dot(phiA, invQAA) m = np.dot(row1, col)[0, 0] / np.dot(row2, col)[0, 0] return m
def adjacent_open_to_shut_range_mean(u1, u2, QAA, QAF, QFF, QFA, phiA): """ Calculate mean (ideal- no missed events) open times adjacent to a specified shut time range. Parameters ---------- u1, u2 : floats Shut time range. QAA, QAF, QFF, QFA : array_like Submatrices of Q. phiA : array_like, shape (1, kA) Initial vector for openings Returns ------- m : float Mean open time. """ kA = QAA.shape[0] uA = np.ones((kA))[:, np.newaxis] invQAA, invQFF = -nplin.inv(QAA), nplin.inv(QFF) expQFFr = qml.expQt(QFF, u2) - qml.expQt(QFF, u1) col = np.dot(np.dot(np.dot(np.dot(QAF, invQFF), expQFFr), QFA), uA) row1 = np.dot(phiA, qml.Qpow(invQAA, 2)) row2 = np.dot(phiA, invQAA) m = np.dot(row1, col)[0, 0] / np.dot(row2, col)[0, 0] return m
def asymptotic_areas(tres, roots, QAA, QFF, QAF, QFA, kA, kF, GAF, GFA): """ Find the areas of the asymptotic pdf (Eq. 58, HJC92). Parameters ---------- tres : float Time resolution (dead time). roots : array_like, shape (1,kA) Roots of the asymptotic pdf. QAA : array_like, shape (kA, kA) QFF : array_like, shape (kF, kF) QAF : array_like, shape (kA, kF) QFA : array_like, shape (kF, kA) QAA, QFF, QAF, QFA - submatrices of Q. kA : int A number of open states in kinetic scheme. kF : int A number of shut states in kinetic scheme. GAF : array_like, shape (kA, kB) GFA : array_like, shape (kB, kA) GAF, GFA- transition probabilities Returns ------- areas : ndarray, shape (1, kA) """ expQFF = qml.expQt(QFF, tres) expQAA = qml.expQt(QAA, tres) eGAF = qml.eGs(GAF, GFA, kA, kF, expQFF) eGFA = qml.eGs(GFA, GAF, kF, kA, expQAA) phiA = qml.phiHJC(eGAF, eGFA, kA) R = qml.AR(roots, tres, QAA, QFF, QAF, QFA, kA, kF) uF = np.ones((kF,1)) areas = np.zeros(kA) for i in range(kA): areas[i] = ((-1 / roots[i]) * np.dot(phiA, np.dot(np.dot(R[i], np.dot(QAF, expQFF)), uF))) # rowA = np.zeros((kA,kA)) # colA = np.zeros((kA,kA)) # for i in range(kA): # WA = qml.W(roots[i], tres, # QAA, QFF, QAF, QFA, kA, kF) # rowA[i] = qml.pinf(WA) # AW = np.transpose(WA) # colA[i] = qml.pinf(AW) # # for i in range(kA): # uF = np.ones((kF,1)) # nom = np.dot(np.dot(np.dot(np.dot(np.dot(phiA, colA[i]), rowA[i]), # QAF), expQFF), uF) # W1A = qml.dW(roots[i], tres, QAF, QFF, QFA, kA, kF) # denom = -roots[i] * np.dot(np.dot(rowA[i], W1A), colA[i]) # areas[i] = nom / denom return areas
def HJC_adjacent_mean_open_to_shut_time_pdf(sht, tres, Q, QAA, QAF, QFF, QFA): """ Calculate theoretical HJC (with missed events correction) mean open time given previous/next gap length (continuous function; CHS96 Eq.3.5). Parameters ---------- sht : array of floats Shut time interval. tres : float Time resolution. Q : array, shape (k,k) Q matrix. QAA, QAF, QFF, QFA : array_like Submatrices of Q. Returns ------- mp : ndarray of floats Mean open time given previous gap length. mn : ndarray of floats Mean open time given next gap length. """ kA, kF = QAA.shape[0], QFF.shape[0] uA = np.ones((kA))[:, np.newaxis] uF = np.ones((kF))[:, np.newaxis] expQFF = qml.expQt(QFF, tres) expQAA = qml.expQt(QAA, tres) GAF, GFA = qml.iGs(Q, kA, kF) eGAF = qml.eGs(GAF, GFA, kA, kF, expQFF) eGFA = qml.eGs(GFA, GAF, kF, kA, expQAA) phiA = qml.phiHJC(eGAF, eGFA, kA) phiF = qml.phiHJC(eGFA, eGAF, kF) DARS = qml.dARSdS(tres, QAA, QFF, GAF, GFA, expQFF, kA, kF) eigs, A = qml.eigs(-Q) Feigvals, FZ00, FZ10, FZ11 = qml.Zxx(Q, eigs, A, kA, QAA, QFA, QAF, expQAA, False) Froots = asymptotic_roots(tres, QFF, QAA, QFA, QAF, kF, kA) FR = qml.AR(Froots, tres, QFF, QAA, QFA, QAF, kF, kA) Q1 = np.dot(np.dot(DARS, QAF), expQFF) col1 = np.dot(Q1, uF) row1 = np.dot(phiA, Q1) mp = [] mn = [] for t in sht: eGFAt = qml.eGAF(t, tres, Feigvals, FZ00, FZ10, FZ11, Froots, FR, QFA, expQAA) denom = np.dot(np.dot(phiF, eGFAt), uA)[0] nom1 = np.dot(np.dot(phiF, eGFAt), col1)[0] nom2 = np.dot(np.dot(row1, eGFAt), uA)[0] mp.append(nom1 / denom) mn.append(nom2 / denom) return np.array(mp), np.array(mn)
def HJC_adjacent_mean_open_to_shut_time_pdf(sht, tres, Q, QAA, QAF, QFF, QFA): """ Calculate theoretical HJC (with missed events correction) mean open time given previous/next gap length (continuous function; CHS96 Eq.3.5). Parameters ---------- sht : array of floats Shut time interval. tres : float Time resolution. Q : array, shape (k,k) Q matrix. QAA, QAF, QFF, QFA : array_like Submatrices of Q. Returns ------- mp : ndarray of floats Mean open time given previous gap length. mn : ndarray of floats Mean open time given next gap length. """ kA, kF = QAA.shape[0], QFF.shape[0] uA = np.ones((kA))[:,np.newaxis] uF = np.ones((kF))[:,np.newaxis] expQFF = qml.expQt(QFF, tres) expQAA = qml.expQt(QAA, tres) GAF, GFA = qml.iGs(Q, kA, kF) eGAF = qml.eGs(GAF, GFA, kA, kF, expQFF) eGFA = qml.eGs(GFA, GAF, kF, kA, expQAA) phiA = qml.phiHJC(eGAF, eGFA, kA) phiF = qml.phiHJC(eGFA, eGAF, kF) DARS = qml.dARSdS(tres, QAA, QFF, GAF, GFA, expQFF, kA, kF) eigs, A = qml.eigs(-Q) Feigvals, FZ00, FZ10, FZ11 = qml.Zxx(Q, eigs, A, kA, QAA, QFA, QAF, expQAA, False) Froots = asymptotic_roots(tres, QFF, QAA, QFA, QAF, kF, kA) FR = qml.AR(Froots, tres, QFF, QAA, QFA, QAF, kF, kA) Q1 = np.dot(np.dot(DARS, QAF), expQFF) col1 = np.dot(Q1, uF) row1 = np.dot(phiA, Q1) mp = [] mn = [] for t in sht: eGFAt = qml.eGAF(t, tres, Feigvals, FZ00, FZ10, FZ11, Froots, FR, QFA, expQAA) denom = np.dot(np.dot(phiF, eGFAt), uA)[0] nom1 = np.dot(np.dot(phiF, eGFAt), col1)[0] nom2 = np.dot(np.dot(row1, eGFAt), uA)[0] mp.append(nom1 / denom) mn.append(nom2 / denom) return np.array(mp), np.array(mn)
def HJC_dependency(top, tsh, tres, Q, QAA, QAF, QFF, QFA): """ Calculate normalised joint distribution (CHS96, Eq. 3.22) of an open time and the following shut time as proposed by Magleby & Song 1992. Parameters ---------- top, tsh : array_like of floats Open and shut tims. tres : float Time resolution. Q : array, shape (k,k) Q matrix. QAA, QAF, QFF, QFA : array_like Submatrices of Q. Returns ------- dependency : ndarray """ kA, kF = QAA.shape[0], QFF.shape[0] uA = np.ones((kA))[:, np.newaxis] uF = np.ones((kF))[:, np.newaxis] expQFF = qml.expQt(QFF, tres) expQAA = qml.expQt(QAA, tres) GAF, GFA = qml.iGs(Q, kA, kF) eGAF = qml.eGs(GAF, GFA, kA, kF, expQFF) eGFA = qml.eGs(GFA, GAF, kF, kA, expQAA) phiA = qml.phiHJC(eGAF, eGFA, kA) phiF = qml.phiHJC(eGFA, eGAF, kF) eigs, A = qml.eigs(-Q) Feigvals, FZ00, FZ10, FZ11 = qml.Zxx(Q, eigs, A, kA, QAA, QFA, QAF, expQAA, False) Froots = asymptotic_roots(tres, QFF, QAA, QFA, QAF, kF, kA) FR = qml.AR(Froots, tres, QFF, QAA, QFA, QAF, kF, kA) Aeigvals, AZ00, AZ10, AZ11 = qml.Zxx(Q, eigs, A, kA, QFF, QAF, QFA, expQFF, True) Aroots = asymptotic_roots(tres, QAA, QFF, QAF, QFA, kA, kF) AR = qml.AR(Aroots, tres, QAA, QFF, QAF, QFA, kA, kF) dependency = np.zeros((top.shape[0], tsh.shape[0])) for i in range(top.shape[0]): eGAFt = qml.eGAF(top[i], tres, Aeigvals, AZ00, AZ10, AZ11, Aroots, AR, QAF, expQFF) fo = np.dot(np.dot(phiA, eGAFt), uF)[0] for j in range(tsh.shape[0]): eGFAt = qml.eGAF(tsh[j], tres, Feigvals, FZ00, FZ10, FZ11, Froots, FR, QFA, expQAA) fs = np.dot(np.dot(phiF, eGFAt), uA)[0] fos = np.dot(np.dot(np.dot(phiA, eGAFt), eGFAt), uA)[0] dependency[i, j] = (fos - (fo * fs)) / (fo * fs) return dependency
def HJC_dependency(top, tsh, tres, Q, QAA, QAF, QFF, QFA): """ Calculate normalised joint distribution (CHS96, Eq. 3.22) of an open time and the following shut time as proposed by Magleby & Song 1992. Parameters ---------- top, tsh : array_like of floats Open and shut tims. tres : float Time resolution. Q : array, shape (k,k) Q matrix. QAA, QAF, QFF, QFA : array_like Submatrices of Q. Returns ------- dependency : ndarray """ kA, kF = QAA.shape[0], QFF.shape[0] uA = np.ones((kA))[:,np.newaxis] uF = np.ones((kF))[:,np.newaxis] expQFF = qml.expQt(QFF, tres) expQAA = qml.expQt(QAA, tres) GAF, GFA = qml.iGs(Q, kA, kF) eGAF = qml.eGs(GAF, GFA, kA, kF, expQFF) eGFA = qml.eGs(GFA, GAF, kF, kA, expQAA) phiA = qml.phiHJC(eGAF, eGFA, kA) phiF = qml.phiHJC(eGFA, eGAF, kF) eigs, A = qml.eigs(-Q) Feigvals, FZ00, FZ10, FZ11 = qml.Zxx(Q, eigs, A, kA, QAA, QFA, QAF, expQAA, False) Froots = asymptotic_roots(tres, QFF, QAA, QFA, QAF, kF, kA) FR = qml.AR(Froots, tres, QFF, QAA, QFA, QAF, kF, kA) Aeigvals, AZ00, AZ10, AZ11 = qml.Zxx(Q, eigs, A, kA, QFF, QAF, QFA, expQFF, True) Aroots = asymptotic_roots(tres, QAA, QFF, QAF, QFA, kA, kF) AR = qml.AR(Aroots, tres, QAA, QFF, QAF, QFA, kA, kF) dependency = np.zeros((top.shape[0], tsh.shape[0])) for i in range(top.shape[0]): eGAFt = qml.eGAF(top[i], tres, Aeigvals, AZ00, AZ10, AZ11, Aroots, AR, QAF, expQFF) fo = np.dot(np.dot(phiA, eGAFt), uF)[0] for j in range(tsh.shape[0]): eGFAt = qml.eGAF(tsh[j], tres, Feigvals, FZ00, FZ10, FZ11, Froots, FR, QFA, expQAA) fs = np.dot(np.dot(phiF, eGFAt), uA)[0] fos = np.dot(np.dot(np.dot(phiA, eGAFt), eGFAt), uA)[0] dependency[i, j] = (fos - (fo * fs)) / (fo * fs) return dependency
def ideal_dwell_time_pdf(t, QAA, phiA): """ Probability density function of the open time. f(t) = phiOp * exp(-QAA * t) * (-QAA) * uA For shut time pdf A by F in function call. Parameters ---------- t : float Time (sec). QAA : array_like, shape (kA, kA) Submatrix of Q. phiA : array_like, shape (1, kA) Initial vector for openings Returns ------- f : float """ kA = QAA.shape[0] uA = np.ones((kA, 1)) expQAA = qml.expQt(QAA, t) f = np.dot(np.dot(np.dot(phiA, expQAA), -QAA), uA) return f
def ideal_dwell_time_pdf(t, QAA, phiA): """ Probability density function of the open time. f(t) = phiOp * exp(-QAA * t) * (-QAA) * uA For shut time pdf A by F in function call. Parameters ---------- t : float Time (sec). QAA : array_like, shape (kA, kA) Submatrix of Q. phiA : array_like, shape (1, kA) Initial vector for openings Returns ------- f : float """ kA = QAA.shape[0] uA = np.ones((kA, 1)) expQAA = qml.expQt(QAA, t) f = np.dot(np.dot(np.dot(phiA, expQAA), -QAA), uA) return f
def exact_mean_open_shut_time(mec, tres): """ Calculate exact mean open or shut time from HJC probability density function. Parameters ---------- tres : float Time resolution (dead time). QAA : array_like, shape (kA, kA) QFF : array_like, shape (kF, kF) QAF : array_like, shape (kA, kF) QAA, QFF, QAF - submatrices of Q. kA : int A number of open states in kinetic scheme. kF : int A number of shut states in kinetic scheme. GAF : array_like, shape (kA, kB) GFA : array_like, shape (kB, kA) GAF, GFA- transition probabilities Returns ------- mean : float Apparent mean open/shut time. """ GAF, GFA = qml.iGs(mec.Q, mec.kA, mec.kF) expQFF = qml.expQt(mec.QFF, tres) expQAA = qml.expQt(mec.QAA, tres) eGAF = qml.eGs(GAF, GFA, mec.kA, mec.kF, expQFF) eGFA = qml.eGs(GFA, GAF, mec.kF, mec.kA, expQAA) phiA = qml.phiHJC(eGAF, eGFA, mec.kA) phiF = qml.phiHJC(eGFA, eGAF, mec.kF) QexpQF = np.dot(mec.QAF, expQFF) QexpQA = np.dot(mec.QFA, expQAA) DARS = qml.dARSdS(tres, mec.QAA, mec.QFF, GAF, GFA, expQFF, mec.kA, mec.kF) DFRS = qml.dARSdS(tres, mec.QFF, mec.QAA, GFA, GAF, expQAA, mec.kF, mec.kA) uF, uA = np.ones((mec.kF, 1)), np.ones((mec.kA, 1)) # meanOpenTime = tres + phiA * DARS * QexpQF * uF meanA = tres + np.dot(phiA, np.dot(np.dot(DARS, QexpQF), uF))[0] meanF = tres + np.dot(phiF, np.dot(np.dot(DFRS, QexpQA), uA))[0] return meanA, meanF
def exact_mean_open_shut_time(mec, tres): """ Calculate exact mean open or shut time from HJC probability density function. Parameters ---------- tres : float Time resolution (dead time). QAA : array_like, shape (kA, kA) QFF : array_like, shape (kF, kF) QAF : array_like, shape (kA, kF) QAA, QFF, QAF - submatrices of Q. kA : int A number of open states in kinetic scheme. kF : int A number of shut states in kinetic scheme. GAF : array_like, shape (kA, kB) GFA : array_like, shape (kB, kA) GAF, GFA- transition probabilities Returns ------- mean : float Apparent mean open/shut time. """ GAF, GFA = qml.iGs(mec.Q, mec.kA, mec.kF) expQFF = qml.expQt(mec.QFF, tres) expQAA = qml.expQt(mec.QAA, tres) eGAF = qml.eGs(GAF, GFA, mec.kA, mec.kF, expQFF) eGFA = qml.eGs(GFA, GAF, mec.kF, mec.kA, expQAA) phiA = qml.phiHJC(eGAF, eGFA, mec.kA) phiF = qml.phiHJC(eGFA, eGAF, mec.kF) QexpQF = np.dot(mec.QAF, expQFF) QexpQA = np.dot(mec.QFA, expQAA) DARS = qml.dARSdS(tres, mec.QAA, mec.QFF, GAF, GFA, expQFF, mec.kA, mec.kF) DFRS = qml.dARSdS(tres, mec.QFF, mec.QAA, GFA, GAF, expQAA, mec.kF, mec.kA) uF, uA = np.ones((mec.kF, 1)), np.ones((mec.kA, 1)) # meanOpenTime = tres + phiA * DARS * QexpQF * uF meanA = tres + np.dot(phiA, np.dot(np.dot(DARS, QexpQF), uF))[0] meanF = tres + np.dot(phiF, np.dot(np.dot(DFRS, QexpQA), uA))[0] return meanA, meanF
def exact_GAMAxx(mec, tres, open): """ Calculate gama coeficients for the exact open time pdf (Eq. 3.22, HJC90). Parameters ---------- tres : float mec : dcpyps.Mechanism The mechanism to be analysed. open : bool True for open time pdf and False for shut time pdf. Returns ------- eigen : ndarray, shape (k,) Eigenvalues of -Q matrix. gama00, gama10, gama11 : ndarrays Constants for the exact open/shut time pdf. """ expQFF = qml.expQt(mec.QII, tres) expQAA = qml.expQt(mec.QAA, tres) GAF, GFA = qml.iGs(mec.Q, mec.kA, mec.kI) eGAF = qml.eGs(GAF, GFA, mec.kA, mec.kI, expQFF) eGFA = qml.eGs(GFA, GAF, mec.kI, mec.kA, expQAA) eigs, A = qml.eigs_sorted(-mec.Q) if open: phi = qml.phiHJC(eGAF, eGFA, mec.kA) eigen, Z00, Z10, Z11 = qml.Zxx(mec.Q, eigs, A, mec.kA, mec.QII, mec.QAI, mec.QIA, expQFF, open) u = np.ones((mec.kI,1)) else: phi = qml.phiHJC(eGFA, eGAF, mec.kI) eigen, Z00, Z10, Z11 = qml.Zxx(mec.Q, eigs, A, mec.kA, mec.QAA, mec.QIA, mec.QAI, expQAA, open) u = np.ones((mec.kA, 1)) gama00 = (np.dot(np.dot(phi, Z00), u)).T[0] gama10 = (np.dot(np.dot(phi, Z10), u)).T[0] gama11 = (np.dot(np.dot(phi, Z11), u)).T[0] return eigen, gama00, gama10, gama11
def ideal_subset_time_pdf(Q, k1, k2, t): """ """ u = np.ones((k2 - k1 + 1, 1)) phi, QSub = qml.phiSub(Q, k1, k2) expQSub = qml.expQt(QSub, t) f = np.dot(np.dot(np.dot(phi, expQSub), -QSub), u) return f
def exact_GAMAxx(mec, tres, open): """ Calculate gama coeficients for the exact open time pdf (Eq. 3.22, HJC90). Parameters ---------- tres : float mec : dcpyps.Mechanism The mechanism to be analysed. open : bool True for open time pdf and False for shut time pdf. Returns ------- eigen : ndarray, shape (k,) Eigenvalues of -Q matrix. gama00, gama10, gama11 : ndarrays Constants for the exact open/shut time pdf. """ expQFF = qml.expQt(mec.QII, tres) expQAA = qml.expQt(mec.QAA, tres) GAF, GFA = qml.iGs(mec.Q, mec.kA, mec.kI) eGAF = qml.eGs(GAF, GFA, mec.kA, mec.kI, expQFF) eGFA = qml.eGs(GFA, GAF, mec.kI, mec.kA, expQAA) eigs, A = qml.eigs_sorted(-mec.Q) if open: phi = qml.phiHJC(eGAF, eGFA, mec.kA) eigen, Z00, Z10, Z11 = qml.Zxx(mec.Q, eigs, A, mec.kA, mec.QII, mec.QAI, mec.QIA, expQFF, open) u = np.ones((mec.kI, 1)) else: phi = qml.phiHJC(eGFA, eGAF, mec.kI) eigen, Z00, Z10, Z11 = qml.Zxx(mec.Q, eigs, A, mec.kA, mec.QAA, mec.QIA, mec.QAI, expQAA, open) u = np.ones((mec.kA, 1)) gama00 = (np.dot(np.dot(phi, Z00), u)).T[0] gama10 = (np.dot(np.dot(phi, Z10), u)).T[0] gama11 = (np.dot(np.dot(phi, Z11), u)).T[0] return eigen, gama00, gama10, gama11
def ideal_subset_time_pdf(Q, k1, k2, t): """ """ u = np.ones((k2 - k1 + 1, 1)) phi, QSub = qml.phiSub(Q, k1, k2) expQSub = qml.expQt(QSub, t) f = np.dot(np.dot(np.dot(phi, expQSub), -QSub), u) return f
def adjacent_open_to_shut_range_pdf_components(u1, u2, QAA, QAF, QFF, QFA, phiA): """ Calculate time constants and areas for an ideal (no missed events) exponential probability density function of open times adjacent to a specified shut time range. Parameters ---------- t : float Time (sec). QAA : array_like, shape (kA, kA) Submatrix of Q. phiA : array_like, shape (1, kA) Initial vector for openings Returns ------- taus : ndarray, shape(k, 1) Time constants. areas : ndarray, shape(k, 1) Component relative areas. """ kA = QAA.shape[0] uA = np.ones((kA))[:, np.newaxis] invQAA, invQFF = -nplin.inv(QAA), nplin.inv(QFF) expQFFr = qml.expQt(QFF, u2) - qml.expQt(QFF, u1) col = np.dot(np.dot(np.dot(np.dot(QAF, invQFF), expQFFr), QFA), uA) w = np.zeros(kA) eigs, A = qml.eigs(-QAA) row = np.dot(phiA, invQAA) den = np.dot(row, col)[0, 0] #TODO: remove 'for' for i in range(kA): w[i] = np.dot(np.dot(phiA, A[i]), col) / den return eigs, w
def adjacent_open_to_shut_range_pdf_components(u1, u2, QAA, QAF, QFF, QFA, phiA): """ Calculate time constants and areas for an ideal (no missed events) exponential probability density function of open times adjacent to a specified shut time range. Parameters ---------- t : float Time (sec). QAA : array_like, shape (kA, kA) Submatrix of Q. phiA : array_like, shape (1, kA) Initial vector for openings Returns ------- taus : ndarray, shape(k, 1) Time constants. areas : ndarray, shape(k, 1) Component relative areas. """ kA = QAA.shape[0] uA = np.ones((kA))[:,np.newaxis] invQAA, invQFF = -nplin.inv(QAA), nplin.inv(QFF) expQFFr = qml.expQt(QFF, u2) - qml.expQt(QFF, u1) col = np.dot(np.dot(np.dot(np.dot(QAF, invQFF), expQFFr), QFA), uA) w = np.zeros(kA) eigs, A = qml.eigs(-QAA) row = np.dot(phiA, invQAA) den = np.dot(row, col)[0, 0] #TODO: remove 'for' for i in range(kA): w[i] = np.dot(np.dot(phiA, A[i]), col) / den return eigs, w
def length_pdf(mec, t): """ Probability density function of the burst length (Eq. 3.17, CH82). f(t) = phiB * [PEE(t)]AA * (-QAA) * eB, where PEE(t) = exp(QEE * t) Parameters ---------- mec : dcpyps.Mechanism The mechanism to be analysed. Returns ------- f : float """ expQEEA = qml.expQt(mec.QEE, t)[:mec.kA, :mec.kA] f = np.dot(np.dot(np.dot(phiBurst(mec), expQEEA), -mec.QAA), endBurst(mec)) return f
def length_pdf(mec, t): """ Probability density function of the burst length (Eq. 3.17, CH82). f(t) = phiB * [PEE(t)]AA * (-QAA) * eB, where PEE(t) = exp(QEE * t) Parameters ---------- mec : dcpyps.Mechanism The mechanism to be analysed. Returns ------- f : float """ expQEEA = qml.expQt(mec.QEE, t)[:mec.kA, :mec.kA] f = np.dot(np.dot(np.dot(phiBurst(mec), expQEEA), -mec.QAA), endBurst(mec)) return f
def length_cond_pdf(mec, t): """ The distribution of burst length coditional on starting state. Parameters ---------- mec : dcpyps.Mechanism The mechanism to be analysed. t : float Length. Returns ------- vec : array_like, shape (kA, 1) Probability of seeing burst length t depending on starting state. """ expQEEA = qml.expQt(mec.QEE, t)[:mec.kA, :mec.kA] vec = np.dot(np.dot(expQEEA, -mec.QAA), endBurst(mec)) vec = vec.transpose() return vec
def length_cond_pdf(mec, t): """ The distribution of burst length coditional on starting state. Parameters ---------- mec : dcpyps.Mechanism The mechanism to be analysed. t : float Length. Returns ------- vec : array_like, shape (kA, 1) Probability of seeing burst length t depending on starting state. """ expQEEA = qml.expQt(mec.QEE, t)[:mec.kA, :mec.kA] vec = np.dot(np.dot(expQEEA, -mec.QAA), endBurst(mec)) vec = vec.transpose() return vec
def printout_occupancies(mec, tres): """ """ str = ('\n\n\n*******************************************\n\n' + 'Open\tEquilibrium\tMean life\tMean latency (ms)\n' + 'state\toccupancy\t(ms)\tto next shutting\n' + '\t\t\tgiven start in this state\n') pinf = qml.pinf(mec.Q) for i in range(mec.k): if i == 0: mean_life_A = ideal_subset_mean_life_time(mec.Q, 1, mec.kA) str += ('Subset A ' + '\t{0:.5g}'.format(np.sum(pinf[:mec.kA])) + '\t{0:.5g}\n'.format(mean_life_A * 1000)) if i == mec.kA: mean_life_B = ideal_subset_mean_life_time(mec.Q, mec.kA + 1, mec.kE) str += ('\nShut\tEquilibrium\tMean life\tMean latency (ms)\n' + 'state\toccupancy\t(ms)\tto next opening\n' + '\t\t\tgiven start in this state\n' + 'Subset B ' + '\t{0:.5g}'.format(np.sum(pinf[mec.kA:mec.kE])) + '\t{0:.5g}\n'.format(mean_life_B * 1000)) if i == mec.kE: mean_life_C = ideal_subset_mean_life_time(mec.Q, mec.kE + 1, mec.kG) str += ('\nSubset C ' + '\t{0:.5g}'.format(np.sum(pinf[mec.kE:mec.kG])) + '\t{0:.5g}\n'.format(mean_life_C * 1000)) if i == mec.kG: mean_life_D = ideal_subset_mean_life_time(mec.Q, mec.kG + 1, mec.k) str += ('\nSubset D ' + '\t{0:.5g}'.format(np.sum(pinf[mec.kG:mec.k])) + '\t{0:.5g}\n'.format(mean_life_D * 1000)) mean = ideal_mean_latency_given_start_state(mec, i + 1) str += ('{0:d}'.format(i + 1) + '\t{0:.5g}'.format(pinf[i]) + '\t{0:.5g}'.format(-1 / mec.Q[i, i] * 1000) + '\t{0:.5g}\n'.format(mean * 1000)) expQFF = qml.expQt(mec.QFF, tres) expQAA = qml.expQt(mec.QAA, tres) GAF, GFA = qml.iGs(mec.Q, mec.kA, mec.kF) eGAF = qml.eGs(GAF, GFA, mec.kA, mec.kF, expQFF) eGFA = qml.eGs(GFA, GAF, mec.kF, mec.kA, expQAA) phiA = qml.phiHJC(eGAF, eGFA, mec.kA) phiF = qml.phiHJC(eGFA, eGAF, mec.kF) str += ('\n\nInitial vector for HJC openings phiOp =\n') for i in range(phiA.shape[0]): str += ('\t{0:.5g}'.format(phiA[i])) str += ('\nInitial vector for ideal openings phiOp =\n') phiAi = qml.phiA(mec) for i in range(phiA.shape[0]): str += ('\t{0:.5g}'.format(phiAi[i])) str += ('\nInitial vector for HJC shuttings phiSh =\n') for i in range(phiF.shape[0]): str += ('\t{0:.5g}'.format(phiF[i])) str += ('\nInitial vector for ideal shuttings phiSh =\n') phiFi = qml.phiF(mec) for i in range(phiF.shape[0]): str += ('\t{0:.5g}'.format(phiFi[i])) str += '\n' return str
def test_openshut(self): # # # Initial HJC vectors. expQFF = qml.expQt(self.mec.QFF, self.tres) expQAA = qml.expQt(self.mec.QAA, self.tres) GAF, GFA = qml.iGs(self.mec.Q, self.mec.kA, self.mec.kF) eGAF = qml.eGs(GAF, GFA, self.mec.kA, self.mec.kF, expQFF) eGFA = qml.eGs(GFA, GAF, self.mec.kF, self.mec.kA, expQAA) phiA = qml.phiHJC(eGAF, eGFA, self.mec.kA) phiF = qml.phiHJC(eGFA, eGAF, self.mec.kF) self.assertAlmostEqual(phiA[0], 0.153966, 6) self.assertAlmostEqual(phiA[1], 0.846034, 6) self.assertAlmostEqual(phiF[0], 0.530369, 6) self.assertAlmostEqual(phiF[1], 0.386116, 6) self.assertAlmostEqual(phiF[2], 0.0835153, 6) # Ideal shut time pdf eigs, w = scl.ideal_dwell_time_pdf_components(self.mec.QFF, qml.phiF(self.mec)) self.assertAlmostEqual(eigs[0], 0.263895, 6) self.assertAlmostEqual(eigs[1], 2062.93, 2) self.assertAlmostEqual(eigs[2], 19011.8, 1) self.assertAlmostEqual(w[0], 0.0691263, 6) self.assertAlmostEqual(w[1], 17.2607, 4) self.assertAlmostEqual(w[2], 13872.7, 1) # Asymptotic shut time pdf roots = scl.asymptotic_roots(self.tres, self.mec.QFF, self.mec.QAA, self.mec.QFA, self.mec.QAF, self.mec.kF, self.mec.kA) areas = scl.asymptotic_areas(self.tres, roots, self.mec.QFF, self.mec.QAA, self.mec.QFA, self.mec.QAF, self.mec.kF, self.mec.kA, GFA, GAF) mean = scl.exact_mean_time(self.tres, self.mec.QFF, self.mec.QAA, self.mec.QFA, self.mec.kF, self.mec.kA, GFA, GAF) self.assertAlmostEqual(-roots[0], 17090.2, 1) self.assertAlmostEqual(-roots[1], 2058.08, 2) self.assertAlmostEqual(-roots[2], 0.243565, 6) self.assertAlmostEqual(areas[0] * 100, 28.5815, 4) self.assertAlmostEqual(areas[1] * 100, 1.67311, 5) self.assertAlmostEqual(areas[2] * 100, 68.3542, 4) # Exact pdf eigvals, gamma00, gamma10, gamma11 = scl.exact_GAMAxx( self.mec, self.tres, False) self.assertAlmostEqual(gamma00[0], 0.940819, 6) self.assertAlmostEqual(gamma00[1], 117.816, 3) self.assertAlmostEqual(gamma00[2], 24.8962, 4) self.assertAlmostEqual(gamma00[3], 1.28843, 5) self.assertAlmostEqual(gamma00[4], 5370.18, 2) self.assertAlmostEqual(gamma10[0], 4.57792, 5) self.assertAlmostEqual(gamma10[1], 100.211, 3) self.assertAlmostEqual(gamma10[2], -5.49855, 4) self.assertAlmostEqual(gamma10[3], 0.671548, 6) self.assertAlmostEqual(gamma10[4], -99.9617, 4) self.assertAlmostEqual(gamma11[0], 0.885141, 6) self.assertAlmostEqual(gamma11[1], 43634.99, 1) self.assertAlmostEqual(gamma11[2], 718.068, 3) self.assertAlmostEqual(gamma11[3], -39.7437, 3) self.assertAlmostEqual(gamma11[4], -1.9832288e+06, 0)
def HJClik(theta, opts): """ Calculate likelihood for a series of open and shut times using HJC missed events probability density functions (first two dead time intervals- exact solution, then- asymptotic). Lik = phi * eGAF(t1) * eGFA(t2) * eGAF(t3) * ... * eGAF(tn) * uF where t1, t3,..., tn are open times; t2, t4,..., t(n-1) are shut times. Gaps > tcrit are treated as unusable (e.g. contain double or bad bit of record, or desens gaps that are not in the model, or gaps so long that next opening may not be from the same channel). However this calculation DOES assume that all the shut times predicted by the model are present within each group. The series of multiplied likelihoods is terminated at the end of the opening before an unusable gap. A new series is then started, using appropriate initial vector to give Lik(2), ... At end these are multiplied to give final likelihood. Parameters ---------- theta : array_like Guesses. bursts : dictionary A dictionary containing lists of open and shut intervals. opts : dictionary opts['mec'] : instance of type Mechanism opts['tres'] : float Time resolution (dead time). opts['tcrit'] : float Ctritical time interval. opts['isCHS'] : bool True if CHS vectors should be used (Eq. 5.7, CHS96). Returns ------- loglik : float Log-likelihood. newrates : array_like Updated rates/guesses. """ # TODO: Errors. mec = opts['mec'] conc = opts['conc'] tres = opts['tres'] tcrit = opts['tcrit'] is_chsvec = opts['isCHS'] bursts = opts['data'] mec.theta_unsqueeze(np.exp(theta)) mec.set_eff('c', conc) GAF, GFA = qml.iGs(mec.Q, mec.kA, mec.kF) expQFF = qml.expQt(mec.QFF, tres) expQAA = qml.expQt(mec.QAA, tres) eGAF = qml.eGs(GAF, GFA, mec.kA, mec.kF, expQFF) eGFA = qml.eGs(GFA, GAF, mec.kF, mec.kA, expQAA) phiF = qml.phiHJC(eGFA, eGAF, mec.kF) startB = qml.phiHJC(eGAF, eGFA, mec.kA) endB = np.ones((mec.kF, 1)) eigen, A = qml.eigs(-mec.Q) Aeigvals, AZ00, AZ10, AZ11 = qml.Zxx(mec.Q, eigen, A, mec.kA, mec.QFF, mec.QAF, mec.QFA, expQFF, True) Aroots = asymptotic_roots(tres, mec.QAA, mec.QFF, mec.QAF, mec.QFA, mec.kA, mec.kF) AR = qml.AR(Aroots, tres, mec.QAA, mec.QFF, mec.QAF, mec.QFA, mec.kA, mec.kF) Feigvals, FZ00, FZ10, FZ11 = qml.Zxx(mec.Q, eigen, A, mec.kA, mec.QAA, mec.QFA, mec.QAF, expQAA, False) Froots = asymptotic_roots(tres, mec.QFF, mec.QAA, mec.QFA, mec.QAF, mec.kF, mec.kA) FR = qml.AR(Froots, tres, mec.QFF, mec.QAA, mec.QFA, mec.QAF, mec.kF, mec.kA) if is_chsvec: startB, endB = qml.CHSvec(Froots, tres, tcrit, mec.QFA, mec.kA, expQAA, phiF, FR) loglik = 0 for ind in range(len(bursts)): burst = bursts[ind] grouplik = startB for i in range(len(burst)): t = burst[i] if i % 2 == 0: # open time eGAFt = qml.eGAF(t, tres, Aeigvals, AZ00, AZ10, AZ11, Aroots, AR, mec.QAF, expQFF) else: # shut eGAFt = qml.eGAF(t, tres, Feigvals, FZ00, FZ10, FZ11, Froots, FR, mec.QFA, expQAA) grouplik = np.dot(grouplik, eGAFt) if grouplik.max() > 1e50: grouplik = grouplik * 1e-100 #print 'grouplik was scaled down' grouplik = np.dot(grouplik, endB) try: loglik += log(grouplik[0]) except: print ('HJClik: Warning: likelihood has been set to 0') print ('likelihood=', grouplik[0]) print ('rates=', mec.unit_rates()) loglik = 0 break newrates = np.log(mec.theta()) return -loglik, newrates
def HJClik(theta, opts): """ Calculate likelihood for a series of open and shut times using HJC missed events probability density functions (first two dead time intervals- exact solution, then- asymptotic). Lik = phi * eGAF(t1) * eGFA(t2) * eGAF(t3) * ... * eGAF(tn) * uF where t1, t3,..., tn are open times; t2, t4,..., t(n-1) are shut times. Gaps > tcrit are treated as unusable (e.g. contain double or bad bit of record, or desens gaps that are not in the model, or gaps so long that next opening may not be from the same channel). However this calculation DOES assume that all the shut times predicted by the model are present within each group. The series of multiplied likelihoods is terminated at the end of the opening before an unusable gap. A new series is then started, using appropriate initial vector to give Lik(2), ... At end these are multiplied to give final likelihood. Parameters ---------- theta : array_like Guesses. bursts : dictionary A dictionary containing lists of open and shut intervals. opts : dictionary opts['mec'] : instance of type Mechanism opts['tres'] : float Time resolution (dead time). opts['tcrit'] : float Ctritical time interval. opts['isCHS'] : bool True if CHS vectors should be used (Eq. 5.7, CHS96). Returns ------- loglik : float Log-likelihood. newrates : array_like Updated rates/guesses. """ # TODO: Errors. mec = opts['mec'] conc = opts['conc'] tres = opts['tres'] tcrit = opts['tcrit'] is_chsvec = opts['isCHS'] bursts = opts['data'] mec.theta_unsqueeze(np.exp(theta)) mec.set_eff('c', conc) GAF, GFA = qml.iGs(mec.Q, mec.kA, mec.kF) expQFF = qml.expQt(mec.QFF, tres) expQAA = qml.expQt(mec.QAA, tres) eGAF = qml.eGs(GAF, GFA, mec.kA, mec.kF, expQFF) eGFA = qml.eGs(GFA, GAF, mec.kF, mec.kA, expQAA) phiF = qml.phiHJC(eGFA, eGAF, mec.kF) startB = qml.phiHJC(eGAF, eGFA, mec.kA) endB = np.ones((mec.kF, 1)) eigen, A = qml.eigs(-mec.Q) Aeigvals, AZ00, AZ10, AZ11 = qml.Zxx(mec.Q, eigen, A, mec.kA, mec.QFF, mec.QAF, mec.QFA, expQFF, True) Aroots = asymptotic_roots(tres, mec.QAA, mec.QFF, mec.QAF, mec.QFA, mec.kA, mec.kF) AR = qml.AR(Aroots, tres, mec.QAA, mec.QFF, mec.QAF, mec.QFA, mec.kA, mec.kF) Feigvals, FZ00, FZ10, FZ11 = qml.Zxx(mec.Q, eigen, A, mec.kA, mec.QAA, mec.QFA, mec.QAF, expQAA, False) Froots = asymptotic_roots(tres, mec.QFF, mec.QAA, mec.QFA, mec.QAF, mec.kF, mec.kA) FR = qml.AR(Froots, tres, mec.QFF, mec.QAA, mec.QFA, mec.QAF, mec.kF, mec.kA) if is_chsvec: startB, endB = qml.CHSvec(Froots, tres, tcrit, mec.QFA, mec.kA, expQAA, phiF, FR) loglik = 0 for ind in range(len(bursts)): burst = bursts[ind] grouplik = startB for i in range(len(burst)): t = burst[i] if i % 2 == 0: # open time eGAFt = qml.eGAF(t, tres, Aeigvals, AZ00, AZ10, AZ11, Aroots, AR, mec.QAF, expQFF) else: # shut eGAFt = qml.eGAF(t, tres, Feigvals, FZ00, FZ10, FZ11, Froots, FR, mec.QFA, expQAA) grouplik = np.dot(grouplik, eGAFt) if grouplik.max() > 1e50: grouplik = grouplik * 1e-100 #print 'grouplik was scaled down' grouplik = np.dot(grouplik, endB) try: loglik += log(grouplik[0]) except: print('HJClik: Warning: likelihood has been set to 0') print('likelihood=', grouplik[0]) print('rates=', mec.unit_rates()) loglik = 0 break newrates = np.log(mec.theta()) return -loglik, newrates
def printout_occupancies(mec, tres): """ """ str = ('\n\n\n*******************************************\n\n' + 'Open\tEquilibrium\tMean life\tMean latency (ms)\n' + 'state\toccupancy\t(ms)\tto next shutting\n' + '\t\t\tgiven start in this state\n') pinf = qml.pinf(mec.Q) for i in range(mec.k): if i == 0: mean_life_A = ideal_subset_mean_life_time(mec.Q, 1, mec.kA) str += ('Subset A ' + '\t{0:.5g}'.format(np.sum(pinf[:mec.kA])) + '\t{0:.5g}\n'.format(mean_life_A * 1000)) if i == mec.kA: mean_life_B = ideal_subset_mean_life_time(mec.Q, mec.kA + 1, mec.kE) str += ('\nShut\tEquilibrium\tMean life\tMean latency (ms)\n' + 'state\toccupancy\t(ms)\tto next opening\n' + '\t\t\tgiven start in this state\n' + 'Subset B ' + '\t{0:.5g}'.format(np.sum(pinf[mec.kA : mec.kE])) + '\t{0:.5g}\n'.format(mean_life_B * 1000)) if i == mec.kE: mean_life_C = ideal_subset_mean_life_time(mec.Q, mec.kE + 1, mec.kG) str += ('\nSubset C ' + '\t{0:.5g}'.format(np.sum(pinf[mec.kE : mec.kG])) + '\t{0:.5g}\n'.format(mean_life_C * 1000)) if i == mec.kG: mean_life_D = ideal_subset_mean_life_time(mec.Q, mec.kG + 1, mec.k) str += ('\nSubset D ' + '\t{0:.5g}'.format(np.sum(pinf[mec.kG : mec.k])) + '\t{0:.5g}\n'.format(mean_life_D * 1000)) mean = ideal_mean_latency_given_start_state(mec, i+1) str += ('{0:d}'.format(i+1) + '\t{0:.5g}'.format(pinf[i]) + '\t{0:.5g}'.format(-1 / mec.Q[i,i] * 1000) + '\t{0:.5g}\n'.format(mean * 1000)) expQFF = qml.expQt(mec.QFF, tres) expQAA = qml.expQt(mec.QAA, tres) GAF, GFA = qml.iGs(mec.Q, mec.kA, mec.kF) eGAF = qml.eGs(GAF, GFA, mec.kA, mec.kF, expQFF) eGFA = qml.eGs(GFA, GAF, mec.kF, mec.kA, expQAA) phiA = qml.phiHJC(eGAF, eGFA, mec.kA) phiF = qml.phiHJC(eGFA, eGAF, mec.kF) str += ('\n\nInitial vector for HJC openings phiOp =\n') for i in range(phiA.shape[0]): str += ('\t{0:.5g}'.format(phiA[i])) str += ('\nInitial vector for ideal openings phiOp =\n') phiAi = qml.phiA(mec) for i in range(phiA.shape[0]): str += ('\t{0:.5g}'.format(phiAi[i])) str += ('\nInitial vector for HJC shuttings phiSh =\n') for i in range(phiF.shape[0]): str += ('\t{0:.5g}'.format(phiF[i])) str += ('\nInitial vector for ideal shuttings phiSh =\n') phiFi = qml.phiF(mec) for i in range(phiF.shape[0]): str += ('\t{0:.5g}'.format(phiFi[i])) str += '\n' return str