def shut_times_between_burst_pdf_components(mec): """ Calculate time constants and amplitudes for a PDF of gaps between bursts. Parameters ---------- mec : dcpyps.Mechanism The mechanism to be analysed. Returns ------- eigs : ndarray, shape(k, 1) Time constants. w : ndarray, shape(k, 1) Component amplitudes. """ uA = np.ones((mec.kA, 1)) eigsB, AmatB = qml.eigs(-mec.QBB) eigsF, AmatF = qml.eigs(-mec.QFF) pA = qml.pinf(mec.Q)[:mec.kA] end = np.dot(-mec.QAA, endBurst(mec)) start = pA / np.dot(pA, end) rowB = np.dot(start, mec.QAB) rowF = np.dot(start, mec.QAF) colB = np.dot(mec.QBA, uA) colF = np.dot(mec.QFA, uA) wB = -np.dot(np.dot(rowB, AmatB), colB) wF = np.dot(np.dot(rowF, AmatF), colF) w = np.append(wB, wF) eigs = np.append(eigsB, eigsF) return eigs, w
def length_no_single_openings_pdf_components(mec): """ Calculate time constants and amplitudes for an ideal (no missed events) exponential burst length probability density function for bursts with two or more openings. Parameters ---------- mec : dcpyps.Mechanism The mechanism to be analysed. Returns ------- eigs : ndarray, shape(k, 1) Time constants. w : ndarray, shape(k, 1) Component amplitudes. """ eigsA, AmatA = qml.eigs(-mec.QAA) eigsE, AmatE = qml.eigs(-mec.QEE) eigs = np.append(eigsE, eigsA) A = np.append(AmatE[:,:mec.kA, :mec.kA], -AmatA, axis=0) w = np.zeros(mec.kA + mec.kE) endB = endBurst(mec) start = phiBurst(mec) norm = 1 - np.dot(start, endB)[0] for i in range(mec.kA + mec.kE): w[i] = np.dot(np.dot(np.dot(start, A[i]), (-mec.QAA)), endB) / norm return eigs, w
def corr_decay_amplitude_A(phiA, QAA, XAA, kA): """ Calculate scalar coefficients for correlation coefficien decay (Eq. 2.11, CH83). Parameters ---------- Returns ------- w : ndarray, shape (1, k) eigs : ndarray, shape (1, k) """ varA = corr_variance_A(phiA, QAA, kA) eigs, A = qml.eigs(XAA) uA = np.ones((kA))[:,np.newaxis] invQAA = -nplin.inv(QAA) row = np.dot(phiA, invQAA) col = np.dot(invQAA, uA) ncA = np.rank(XAA) - 1 w = np.zeros((ncA)) n = 0 for i in range(kA): if fabs(eigs[i]) > 1e-12 and fabs(eigs[i] - 1) > 1e-12: w[n] = np.dot(np.dot(row, A[i, :, :]), col)[0,0] / varA n += 1 return w, eigs
def first_opening_length_pdf_components(mec): """ Calculate time constants and amplitudes for an ideal (no missed events) pdf of first opening in a burst with 2 or more openings. Parameters ---------- mec : dcpyps.Mechanism The mechanism to be analysed. Returns ------- eigs : ndarray, shape(k, 1) Time constants. w : ndarray, shape(k, 1) Component amplitudes. """ uA = np.ones((mec.kA, 1)) eigs, A = qml.eigs(-mec.QAA) GAB, GBA = qml.iGs(mec.Q, mec.kA, mec.kB) GG = np.dot(GAB, GBA) norm = np.dot(np.dot(phiBurst(mec), GG), uA)[0] w = np.zeros(mec.kA) for i in range(mec.kA): w[i] = np.dot(np.dot(np.dot(np.dot(phiBurst(mec), A[i]), (-mec.QAA)), GG), uA) / norm return eigs, w
def shut_time_total_pdf_components_2more_openings(mec): """ Calculate time constants and amplitudes for a PDF of total shut time per burst (Eq. 3.40, CH82) for bursts with at least 2 openings. Parameters ---------- mec : dcpyps.Mechanism The mechanism to be analysed. Returns ------- eigs : ndarray, shape(k, 1) Time constants. w : ndarray, shape(k, 1) Component amplitudes. """ GAB, GBA = qml.iGs(mec.Q, mec.kA, mec.kB) WBB = mec.QBB + np.dot(mec.QBA, GAB) eigs, A = qml.eigs(-WBB) norm = 1 - np.dot(phiBurst(mec), endBurst(mec))[0] w = np.zeros(mec.kB) for i in range(mec.kB): w[i] = np.dot(np.dot(np.dot(np.dot(phiBurst(mec), GAB), A[i]), (mec.QBA)), endBurst(mec)) / norm return eigs, w
def shut_times_inside_burst_pdf_components(mec): """ Calculate time constants and amplitudes for a PDF of all gaps within bursts (Eq. 3.75, CH82). Parameters ---------- mec : dcpyps.Mechanism The mechanism to be analysed. Returns ------- eigs : ndarray, shape(k, 1) Time constants. w : ndarray, shape(k, 1) Component amplitudes. """ uA = np.ones((mec.kA, 1)) eigs, A = qml.eigs(-mec.QBB) GAB, GBA = qml.iGs(mec.Q, mec.kA, mec.kB) interm = nplin.inv(np.eye(mec.kA) - np.dot(GAB, GBA)) norm = openings_mean(mec) - 1 w = np.zeros(mec.kB) for i in range(mec.kB): w[i] = np.dot(np.dot(np.dot(np.dot(np.dot(np.dot(phiBurst(mec), interm), GAB), A[i]), (-mec.QBB)), GBA), uA) / norm return eigs, w
def open_time_total_pdf_components(mec): """ Eq. 3.23, CH82 Parameters ---------- mec : dcpyps.Mechanism The mechanism to be analysed. Returns ------- eigs : ndarray, shape(k, 1) Time constants. w : ndarray, shape(k, 1) Component amplitudes. """ GAB, GBA = qml.iGs(mec.Q, mec.kA, mec.kB) VAA = mec.QAA + np.dot(mec.QAB, GBA) eigs, A = qml.eigs(-VAA) uA = np.ones((mec.kA, 1)) w = np.zeros(mec.kA) for i in range(mec.kA): w[i] = np.dot(np.dot(np.dot(phiBurst(mec), A[i]), (-VAA)), uA) return eigs, w
def openings_distr_components(mec): """ Calculate coeficients for geometric ditribution P(r)- probability of seeing r openings (Eq. 3.9 CH82): P(r) = sum(W * rho^(r-1)) where w wm = phiB * Am * endB (Eq. 3.10 CH82) and rho- eigenvalues of GAB * GBA. Parameters ---------- mec : dcpyps.Mechanism The mechanism to be analysed. r : int Number of openings per burst. Returns ------- rho : ndarray, shape (kA,) w : ndarray, shape (kA,) """ GAB, GBA = qml.iGs(mec.Q, mec.kA, mec.kB) GG = np.dot(GAB, GBA) rho, A = qml.eigs(GG) w = np.dot(np.dot(phiBurst(mec), A), endBurst(mec)).transpose()[0] return rho, w
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 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_components(mec): """ Calculate time constants and amplitudes for an ideal (no missed events) exponential burst length probability density function. Parameters ---------- mec : dcpyps.Mechanism The mechanism to be analysed. Returns ------- eigs : ndarray, shape(k, 1) Time constants. w : ndarray, shape(k, 1) Component amplitudes. """ w = np.zeros(mec.kE) eigs, A = qml.eigs(-mec.QEE) for i in range(mec.kE): w[i] = np.dot(np.dot(np.dot(phiBurst(mec), A[i][:mec.kA, :mec.kA]), (-mec.QAA)), endBurst(mec)) return eigs, w
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_correlations(mec, output=sys.stdout, eff='c'): """ """ str = ('\n\n*************************************\n' + 'CORRELATIONS\n') kA, kI = mec.kA, mec.kI str += ('kA, kF = {0:d}, {1:d}\n'.format(kA, kI)) GAF, GFA = qml.iGs(mec.Q, kA, kI) rGAF, rGFA = np.rank(GAF), np.rank(GFA) str += ('Ranks of GAF, GFA = {0:d}, {1:d}\n'.format(rGAF, rGFA)) XFF = np.dot(GFA, GAF) rXFF = np.rank(XFF) str += ('Rank of GFA * GAF = {0:d}\n'.format(rXFF)) ncF = rXFF - 1 eigXFF, AXFF = qml.eigs(XFF) str += ('Eigenvalues of GFA * GAF:\n') str1 = '' for i in range(kI): str1 += '\t{0:.5g}'.format(eigXFF[i]) str += str1 + '\n' XAA = np.dot(GAF, GFA) rXAA = np.rank(XAA) str += ('Rank of GAF * GFA = {0:d}\n'.format(rXAA)) ncA = rXAA - 1 eigXAA, AXAA = qml.eigs(XAA) str += ('Eigenvalues of GAF * GFA:\n') str1 = '' for i in range(kA): str1 += '\t{0:.5g}'.format(eigXAA[i]) str += str1 + '\n' phiA, phiF = qml.phiA(mec).reshape((1,kA)), qml.phiF(mec).reshape((1,kI)) varA = corr_variance_A(phiA, mec.QAA, kA) varF = corr_variance_A(phiF, mec.QII, kI) # open - open time correlations str += ('\n OPEN - OPEN TIME CORRELATIONS') str += ('Variance of open time = {0:.5g}\n'.format(varA)) SDA = sqrt(varA) str += ('SD of all open times = {0:.5g} ms\n'.format(SDA * 1000)) n = 50 SDA_mean_n = SDA / sqrt(float(n)) str += ('SD of means of {0:d} open times if'.format(n) + 'uncorrelated = {0:.5g} ms\n'.format(SDA_mean_n * 1000)) covAtot = 0 for i in range(1, n): covA = corr_covariance_A(i+1, phiA, mec.QAA, XAA, kA) ro = correlation_coefficient(covA, varA, varA) covAtot += (n - i) * ro * varA vtot = n * varA + 2. * covAtot actSDA = sqrt(vtot / (n * n)) str += ('Actual SD of mean = {0:.5g} ms\n'.format(actSDA * 1000)) pA = 100 * (actSDA - SDA_mean_n) / SDA_mean_n str += ('Percent difference as result of correlation = {0:.5g}\n'. format(pA)) v2A = corr_limit_A(phiA, mec.QAA, AXAA, eigXAA, kA) pmaxA = 100 * (sqrt(1 + 2 * v2A / varA) - 1) str += ('Limiting value of percent difference for large n = {0:.5g}\n'. format(pmaxA)) str += ('Correlation coefficients, r(k), for up to lag k = 5:\n') for i in range(5): covA = corr_covariance_A(i+1, phiA, mec.QAA, XAA, kA) ro = correlation_coefficient(covA, varA, varA) str += ('r({0:d}) = {1:.5g}\n'.format(i+1, ro)) # shut - shut time correlations str += ('\n SHUT - SHUT TIME CORRELATIONS\n') str += ('Variance of shut time = {0:.5g}\n'.format(varF)) SDF = sqrt(varF) str += ('SD of all shut times = {0:.5g} ms\n'.format(SDF * 1000)) n = 50 SDF_mean_n = SDF / sqrt(float(n)) str += ('SD of means of {0:d} shut times if'.format(n) + 'uncorrelated = {0:.5g} ms\n'.format(SDF_mean_n * 1000)) covFtot = 0 for i in range(1, n): covF = corr_covariance_A(i+1, phiF, mec.QII, XFF, kI) ro = correlation_coefficient(covF, varF, varF) covFtot += (n - i) * ro * varF vtotF = 50 * varF + 2. * covFtot actSDF = sqrt(vtotF / (50. * 50.)) str += ('Actual SD of mean = {0:.5g} ms\n'.format(actSDF * 1000)) pF = 100 * (actSDF - SDF_mean_n) / SDF_mean_n str += ('Percent difference as result of correlation = {0:.5g}\n'. format(pF)) v2F = corr_limit_A(phiF, mec.QII, AXFF, eigXFF, kI) pmaxF = 100 * (sqrt(1 + 2 * v2F / varF) - 1) str += ('Limiting value of percent difference for large n = {0:.5g}\n'. format(pmaxF)) str += ('Correlation coefficients, r(k), for up to k = 5 lags:\n') for i in range(5): covF = corr_covariance_A(i+1, phiF, mec.QII, XFF, kI) ro = correlation_coefficient(covF, varF, varF) str += ('r({0:d}) = {1:.5g}\n'.format(i+1, ro)) # open - shut time correlations str += ('\n OPEN - SHUT TIME CORRELATIONS\n') str += ('Correlation coefficients, r(k), for up to k= 5 lags:\n') for i in range(5): covAF = corr_covariance_AF(i+1, phiA, mec.QAA, mec.QII, XAA, GAF, kA, kI) ro = correlation_coefficient(covAF, varA, varF) str += ('r({0:d}) = {1:.5g}\n'.format(i+1, ro)) return str