# Source code for p4.model

```import p4.pf as pf
import sys
import random
import math
import p4.func
from p4.var import var
from p4.p4exceptions import P4Error
import numpy

class BigQAndEig(object):  # not used

def __init__(self, dim, comp, rMatrix):
self.dim = dim
self.comp = comp
self.rMatrix = rMatrix
self.bigR = numpy.zeros((dim, dim), numpy.float)
self.bigQ = numpy.zeros((dim, dim), numpy.float)
self.eval = None
self.evec = None
self.inv_evec = None

if not comp.val:
raise P4Error("comp.val should be set at this point.")

for i in range(self.dim):
if self.comp.val[i] < var.PIVEC_MIN:
self.setBigR()
self.setBigQ()
self.eig()

def setBigR(self):
i = 0
k = 0
while i < self.dim - 2:
j = i + 1
while j < self.dim:
# print i,j,k
self.bigR[i, j] = self.rMatrix.val[k]
self.bigR[j, i] = self.rMatrix.val[k]
k += 1
j += 1
i += 1
self.bigR[self.dim - 2, self.dim - 1] = 1.0
self.bigR[self.dim - 1, self.dim - 2] = 1.0
# print self.bigR

def setBigQ(self):
for i in range(self.dim):
rowSum = 0.0
for j in range(self.dim):
if i != j:
self.bigQ[i, j] = self.bigR[i, j] * self.comp.val[j]
rowSum += self.bigQ[i, j]
self.bigQ[i, i] = -rowSum
self.bigQ /= -sum(diagonal(self.bigQ) * self.comp.val)
# print self.bigQ

def eig(self):
self.eval, self.evec = numpy.linalg.eig(self.bigQ)
self.evec = numpy.transpose(self.evec)
self.inv_evec = numpy.linalg.inv(self.evec)

def calcBigP(self, mat, brLen, nCat, rates):

# Making a new array of zeros is faster than passing a
# pre-allocated result (which needs zeroing), cuz zeroing
# it takes too long.
#result = zeros((self.dim, self.dim), numpy.float)
for catNum in range(nCat):
for i in range(self.dim):
for j in range(self.dim):
mat[catNum, i, j] = 0.0

#xx = exp(self.eval * brLen)
# for i in range(self.dim):
#    for j in range(self.dim):
#        for k in range(self.dim):
#            mat[i,j] += self.evec[i,k] * self.inv_evec[k,j] * xx[k]

for catNum in range(nCat):
if rates:
xx = numpy.exp(self.eval * brLen * rates[catNum])
else:
xx = numpy.exp(self.eval * brLen)
for i in range(self.dim):
for j in range(self.dim):
for k in range(self.dim):
mat[catNum, i, j] += self.evec[i, k] * \
self.inv_evec[k, j] * xx[k]
# print mat
#import sys; sys.exit()

def calcBigPCat(self, mat, brLenTimesRate):
for i in range(self.dim):
for j in range(self.dim):
mat[i, j] = 0.0

xx = numpy.exp(self.eval * brLenTimesRate)
for i in range(self.dim):
for j in range(self.dim):
for k in range(self.dim):
mat[i, j] += self.evec[i, k] * self.inv_evec[k, j] * xx[k]
# print mat
#import sys; sys.exit()

class ModelPart(object):

"""Model description for one data partition."""

def __init__(self):
self.num = -1
self.dim = 0
self.comps = []
self.rMatrices = []
self.gdasrvs = []
self.nGammaCat = 1
self.pInvar = None  # only one, not a list
self.relRate = 1.0
self.isHet = 0
self.symbols = None
#self.bigQAndEigArray = None
self.bQETneedsReset = None

self.nCat = 0      # This is set by Tree.modelSanityCheck()

self.ndch2 = False
self.ndch2_leafAlpha = 50.0      # Leaf
self.ndch2_internalAlpha = 30.0  # Internal
self.ndch2_globalComp = None
self.ndch2_writeComps = True

@property
def nComps(self):
return len(self.comps)

@property
def nRMatrices(self):
return len(self.rMatrices)

@property
def nGdasrvs(self):
return len(self.gdasrvs)

def setCStuff(self, theModel):
gm = ['ModelPart.setCStuff()']
#print(gm[0])
for mNum in range(self.nComps):
#print(mNum)
mt = self.comps[mNum]
#print("comp %i = %s" % (mNum, mt.val))
if 1:
theSum = numpy.sum(mt.val)
theDiff = math.fabs(1.0 - theSum)
if theDiff > 1e-15:
print("Model.setCStuff().  1.0 - sum(comp.val) = %g" % theDiff)
# for i in range(self.dim):
#     if mt.val[i] < var.PIVEC_MIN:
#         gm = ['ModelPart.setCStuff()']
#         gm.append("Part %i, comp %i, val %i is too small. %g" % (
#             self.num, mNum, i, mt.val[i]))
#         gm.append("mt.val = %s" % mt.val)
#         gm.append("Programming error!  This should not happen.")
#         raise P4Error(gm)
#     # no longer needed, as comp.val is a numpy array
#     #pf.p4_setCompVal(theModel.cModel, self.num, mNum, i, mt.val[i])
assert numpy.min(mt.val) >= var.PIVEC_MIN

# Do the rMatrices
for mNum in range(self.nRMatrices):
mt = self.rMatrices[mNum]
# print "Model.setCStuff()   rMatrix.spec is %s" % mt.spec
if mt.spec == '2p':
pf.p4_setKappa(theModel.cModel, self.num, mNum, mt.val[0])
elif mt.free or mt.spec == 'specified':
k = 0
if var.rMatrixNormalizeTo1:
for i in range(self.dim - 1):
for j in range(i + 1, self.dim):
# print i, j, k
pf.p4_setRMatrixBigR(
theModel.cModel, self.num, mNum, i, j, mt.val[k])
k += 1
else:
for i in range(self.dim - 2):
for j in range(i + 1, self.dim):
# print i, j, k
pf.p4_setRMatrixBigR(
theModel.cModel, self.num, mNum, i, j, mt.val[k])
k += 1

# Do the gdasrvs
# if self.nGammaCat > 1:
#    for mNum in range(self.nGdasrvs):
#        mt = self.gdasrvs[mNum]
# pf.p4_setGdasrvVal(theModel.cModel, self.num, mNum, mt.val)   # no
# longer needed.

# Do the pInvar and relRate
pf.p4_setPInvarVal(theModel.cModel, self.num, self.pInvar.val)
pf.p4_setRelRateVal(theModel.cModel, self.num, self.relRate)

def copyValsTo(self, otherModelPart):
sp = self
op = otherModelPart

# comps
for mtNum in range(sp.nComps):
smt = sp.comps[mtNum]
if smt.free:
omt = op.comps[mtNum]
for i in range(sp.dim):
omt.val[i] = smt.val[i]
if sp.isHet:
omt = op.comps[mtNum]
omt.nNodes = smt.nNodes

# rMatrices
for mtNum in range(sp.nRMatrices):
smt = sp.rMatrices[mtNum]
if smt.free:
omt = op.rMatrices[mtNum]
if smt.spec == '2p':
omt.val[0] = smt.val[0]
else:
if var.rMatrixNormalizeTo1:
for i in range(((sp.dim * sp.dim) - sp.dim) // 2):
omt.val[i] = smt.val[i]
else:
for i in range((((sp.dim * sp.dim) - sp.dim) // 2) - 1):
omt.val[i] = smt.val[i]
if sp.isHet:
omt.nNodes = smt.nNodes

# gdasrvs
for mtNum in range(sp.nGdasrvs):
smt = sp.gdasrvs[mtNum]
if smt.free:
omt = op.gdasrvs[mtNum]
omt.val[0] = smt.val[0]

# pInvar
if sp.pInvar.free:
op.pInvar.val = sp.pInvar.val

# relRate
op.relRate = sp.relRate

op.ndch2_leafAlpha = sp.ndch2_leafAlpha
op.ndch2_internalAlpha = sp.ndch2_internalAlpha

def copyBQETneedsResetTo(self, otherModelPart):
sp = self
op = otherModelPart
# if hasattr(sp.bQETneedsReset, 'size'):  # Can't simply ask 'if
# sp.bQETneedsReset'
if 1:
for i in range(sp.nComps):
for j in range(sp.nRMatrices):
op.bQETneedsReset[i][j] = sp.bQETneedsReset[i][j]

def copyNNodesTo(self, otherModelPart):
sp = self
op = otherModelPart

# comps
for mtNum in range(sp.nComps):
op.comps[mtNum].nNodes = sp.comps[mtNum].nNodes

# rMatrices
for mtNum in range(sp.nRMatrices):
op.rMatrices[mtNum].nNodes = sp.rMatrices[mtNum].nNodes

# gdasrvs
for mtNum in range(sp.nGdasrvs):
op.gdasrvs[mtNum].nNodes = sp.gdasrvs[mtNum].nNodes

[docs]class Model(object):

def __init__(self, nParts):
self.parts = []
self.cModel = None
self.doRelRates = 0

self.relRatesAreFree = 0
"""Boolean that says whether relRates for each data partition are free parameters."""

self.nFreePrams = 0
self.isHet = 0
for i in range(nParts):
mp = ModelPart()
mp.num = i
self.parts.append(mp)

@property
def nParts(self):
return len(self.parts)

def __del__(self, freeModel=pf.p4_freeModel):
if self.cModel:
freeModel(self.cModel)
self.cModel = None

[docs]    def dump(self):
"""Print a summary of self.  Part by part."""

# def _writeCharFreqToOpenFile(theCharFreq, dim, symbols, openFile, offset=23):
# def _writeRMatrixTupleToOpenFile(theTuple, dim, openFile, offset=23):

print("\nModel.dump().  nParts=%s" % self.nParts)

if self.nParts == 0:
print("nParts is zero.")
return
if self.doRelRates:
if self.relRatesAreFree:
print("Relative rates are set and free.")
else:
print("Relative rates are set but not free.")

for pNum in range(self.nParts):
mp = self.parts[pNum]
print("\n==== Part %s, dim=%s" % (pNum, mp.dim))

if self.doRelRates:
print("\n  ---- relRate = %s" % mp.relRate)

print("\n  ---- Comp Info")
if mp.nComps == 0:
print("    No comps.")
else:
print()
print("%4s %6s %9s %6s %4s" % (
'', 'num', 'spec', 'free', 'symb'))
for i in range(mp.nComps):
c = mp.comps[i]
print("%4s" % '', end=' ')
print("%6s" % c.num, end=' ')
print("%9s" % c.spec, end=' ')
print("%6s" % c.free, end=' ')
print("%4s" % c.symbol, end=' ')
print('')
print('')
for i in range(mp.nComps):
c = mp.comps[i]
print('%6s part %i, num %i' % ('', pNum, i))
if c.val is not None:
print(" " * 14, end='')
if mp.symbols:
theseSymbols = mp.symbols
else:
theseSymbols = '?' * mp.dim
p4.func._writeCharFreqToOpenFile(
c.val, mp.dim, theseSymbols, sys.stdout, offset=15)
print(" %s]" % c.spec)
else:
print(' ' * 14, 'No values defined.')

#import sys; sys.exit()
print("\n  ---- rMatrix Info")
if mp.nRMatrices == 0:
print("    No rMatrices.")
else:
print()
print("%4s %6s %9s %6s %6s" % (
'', 'num', 'spec', 'free', 'symb'))

for i in range(mp.nRMatrices):
c = mp.rMatrices[i]
print("%4s" % '', end=' ')
print("%6s" % c.num, end=' ')

if c.spec in var.rMatrixSpecs:
theSpec = c.spec
else:
theSpec = 'unknown'

print("%9s" % theSpec, end=' ')
print("%6s" % c.free, end=' ')
print("%6s" % c.symbol)
print('')
for i in range(mp.nRMatrices):
c = mp.rMatrices[i]
if theSpec in var.rMatrixProteinSpecs:
pass
elif theSpec == '2p':
print("%6s part %i, num %i" % ('', pNum, i))
print(" " * 15, end='')
print("kappa = %f" % c.val[0])
else:
print("%6s part %i, num %i" % ('', pNum, i))
print(" " * 15, end='')
if mp.dim > 2:
p4.func._writeRMatrixTupleToOpenFile(
c.val, mp.dim, sys.stdout, offset=15)
elif mp.dim == 2:
print("dim = 2.  No free values")
else:
raise P4Error(
"dim=%s  How did *that* happen?" % mp.dim)

print("\n  ---- gdasrv Info.  nGammaCat=%s" % mp.nGammaCat)
if mp.nGdasrvs == 0:
print("    No gdasrvs.")
else:
print()
print("%4s %6s %6s %6s %8s" % (
'', 'num', 'free', 'symb', 'val'))
for i in range(mp.nGdasrvs):
c = mp.gdasrvs[i]
print("%4s" % '', end=' ')
print("%6s" % c.num, end=' ')
print("%6s" % c.free, end=' ')
print("%6s" % c.symbol, end=' ')
if c.val:
print("    %6.3f" % c.val)
else:
print("%6s" % 'None')  # This should never happen

print("\n  ---- pInvar Info")
c = mp.pInvar
if c:
print(" %6s %6s %8s" % ('', 'free', 'val'))
print("%6s" % '', end=' ')  # indent
print("%6s" % c.free, end=' ')
if c.val or c.val == 0.0:
print("    %6.3f" % c.val)
else:
print("%6s" % 'None')  # This should never happen
else:
print("    No pInvar.")

# def allocBigQAndEig(self):
# for pNum in range(self.nParts):
##            mp = self.parts[pNum]
##            qe = []
# for cNum in range(mp.nComps):
##                qe.append([None] * mp.nRMatrices)
# for cNum in range(mp.nComps):
# for rNum in range(mp.nRMatrices):
##                    qe[cNum][rNum] = BigQAndEig(mp.dim, mp.comps[cNum], mp.rMatrices[rNum])
##            mp.bigQAndEigArray = qe

def writePramsProfile(self, flob, runNum):
"""Write commented lines as a key to the model prams."""

flob.write("# Model.writePramsProfile() runNum %i\n" % runNum)
flob.write("# \n")
flob.write("# There are %i free parameters in this model.\n" %
self.nFreePrams)
flob.write("# The parameters sampled at a given gen+1 are written on one line.\n")
flob.write("# The first number is gen+1, followed by any changeable model parameters.\n")
flob.write("# The number of changeable model parameters may be more than the \n")
flob.write("#  number of free model parameters, eg for DNA composition, there are\n")
flob.write("#  3 free parameters, but 4 changeable parameters.\n")
flob.write("# The column number or column range for each parameter or\n")
flob.write("#  parameter set is given twice-- the first is zero-based \n")
flob.write("#  numbering, and the second is one-based numbering.\n")
flob.write("# Numbers in square brackets are the number of parameters listed.\n")
flob.write("# \n")
nPrams = 0
spacer1 = ' ' * 23
spacer2 = ' ' * 12
flob.write("#   0-based 1-based\n")
flob.write("#   ------- -------\n")
flob.write("#%s%i data partitions\n" % (spacer1, self.nParts))
if self.doRelRates:
if self.relRatesAreFree:
flob.write("#%sRelative rates are set and free.\n" % spacer1)
else:
flob.write(
"#%sRelative rates are set but not free.\n" % spacer1)

pramsList = []
zeroBasedColNum = 1
oneBasedColNum = 2
for pNum in range(self.nParts):
pramsList.append([])
flob.write("#%sData Partition %i\n" % (spacer1, pNum))
mp = self.parts[pNum]
if self.doRelRates and self.relRatesAreFree:
flob.write("#   %7i %7i " % (zeroBasedColNum, oneBasedColNum))
flob.write("%srelRate[1]\n" % spacer2)
pramsList[pNum].append(['relRate', 1])
nPrams += 1
zeroBasedColNum += 1
oneBasedColNum += 1
if mp.nComps:
if mp.ndch2 and not mp.ndch2_writeComps:
pass
else:
for i in range(mp.nComps):
if mp.comps[i].free:
flob.write("#   ")
begin = zeroBasedColNum
end = zeroBasedColNum + (mp.dim - 1)
theRangeString = "%s-%s" % (begin, end)
flob.write("%7s " % theRangeString)
begin = oneBasedColNum
end = oneBasedColNum + (mp.dim - 1)
theRangeString = "%s-%s" % (begin, end)
flob.write("%7s " % theRangeString)
flob.write("%scomp[%i]\n" % (spacer2, mp.dim))
pramsList[pNum].append(['comp', mp.dim])
nPrams += mp.dim
zeroBasedColNum += mp.dim
oneBasedColNum += mp.dim

if mp.nRMatrices:
for i in range(mp.nRMatrices):
mt = mp.rMatrices[i]
if mt.free:
if mt.spec == '2p':
flob.write("#   %7i %7i " %
(zeroBasedColNum, oneBasedColNum))
flob.write("%srMatrix[1]\n" % spacer2)
pramsList[pNum].append(['rMatrix', 1])
nPrams += 1
zeroBasedColNum += 1
oneBasedColNum += 1
else:
lenMtVal = len(mt.val)
flob.write("#   ")
begin = zeroBasedColNum
end = zeroBasedColNum + (lenMtVal - 1)
theRangeString = "%s-%s" % (begin, end)
flob.write("%7s " % theRangeString)
begin = oneBasedColNum
end = oneBasedColNum + (lenMtVal - 1)
theRangeString = "%s-%s" % (begin, end)
flob.write("%7s " % theRangeString)
flob.write("%srMatrix[%i]\n" % (spacer2, lenMtVal))
pramsList[pNum].append(['rMatrix', lenMtVal])
nPrams += lenMtVal
zeroBasedColNum += lenMtVal
oneBasedColNum += lenMtVal
if mp.nGdasrvs:
for i in range(mp.nGdasrvs):
mt = mp.gdasrvs[i]
if mt.free:
flob.write("#   %7i %7i " %
(zeroBasedColNum, oneBasedColNum))
flob.write("%sgdasrv[1]\n" % spacer2)
pramsList[pNum].append(['gdasrv', 1])
nPrams += 1
zeroBasedColNum += 1
oneBasedColNum += 1
if mp.pInvar and mp.pInvar.free:
flob.write("#   %7i %7i " % (zeroBasedColNum, oneBasedColNum))
flob.write("%spInvar[1]\n" % spacer2)
pramsList[pNum].append(['pInvar', 1])
nPrams += 1
zeroBasedColNum += 1
oneBasedColNum += 1

flob.write("# \n")
flob.write("# %i changeable prams in all.\n" % nPrams)
flob.write("# \n")

f = open("mcmc_pramsProfile_%i.py" % runNum, 'w')
f.write(
"# This file, 'mcmc_pramsProfile_%i.py', is used by func.summarizeMcmcPrams() and PosteriorSamples\n" % runNum)
f.write("pramsProfile = %s\n" % pramsList)
f.write("nPrams = %i\n" % nPrams)
f.close()

def writePramsLine(self, flob):
"""Write a line of model parameters for mcmc output."""

profile1 = "\t%12.6f"
profile2 = "\t%10.8f"
for pNum in range(self.nParts):
mp = self.parts[pNum]
if self.doRelRates and self.relRatesAreFree:
flob.write(profile1 % mp.relRate)
if mp.nComps:
if mp.ndch2 and not mp.ndch2_writeComps:
pass
else:
for i in range(mp.nComps):
mt = mp.comps[i]
if mt.free:
for j in mt.val:
flob.write(profile2 % j)
if mp.nRMatrices:
for i in range(mp.nRMatrices):
mt = mp.rMatrices[i]
if mt.free:
for j in mt.val:
flob.write(profile2 % j)
if mp.nGdasrvs:
for i in range(mp.nGdasrvs):
mt = mp.gdasrvs[i]
if mt.free:
flob.write(profile1 % mt.val[0])
if mp.pInvar and mp.pInvar.free:
flob.write(profile2 % mp.pInvar.val)
flob.write("\n")

def writeHypersLine(self, flob):
"""Write a line of model hyperparameters for mcmc output."""

profile1 = "\t%12.6f"
profile2 = "\t%10.8f"
for pNum in range(self.nParts):
mp = self.parts[pNum]
if mp.ndch2:
flob.write(profile1 % mp.ndch2_leafAlpha)
flob.write(profile1 % mp.ndch2_internalAlpha)
flob.write("\n")

"""Write a header line of model parameters for mcmc output."""

for pNum in range(self.nParts):
mp = self.parts[pNum]
if self.doRelRates and self.relRatesAreFree:
flob.write('\trelRate.%i' % pNum)
if mp.nComps:
if mp.ndch2 and not mp.ndch2_writeComps:
pass
else:
for i in range(mp.nComps):
mt = mp.comps[i]
if mt.free:
for j in range(len(mt.val)):
flob.write('\tcomp.%i.%i.%i' % (pNum, i, j))
if mp.nRMatrices:
for i in range(mp.nRMatrices):
mt = mp.rMatrices[i]
if mt.free:
for j in range(len(mt.val)):
flob.write('\trMatrix.%i.%i.%i' % (pNum, i, j))
if mp.nGdasrvs:
for i in range(mp.nGdasrvs):
mt = mp.gdasrvs[i]
if mt.free:
flob.write('\tgdasrv.%i.%i' % (pNum, i))
if mp.pInvar and mp.pInvar.free:
flob.write('\tpInvar.%i' % pNum)
flob.write("\n")

"""Write a header line of model hyperparameters for mcmc output."""

for pNum in range(self.nParts):
mp = self.parts[pNum]
if mp.ndch2:
flob.write('\tndch2_leafAlpha.%i' % pNum)
flob.write('\tndch2_internalAlpha.%i' % pNum)
flob.write("\n")

def allocCStuff(self):
if 0:
print("nParts = %s %s" % (self.nParts, type(self.nParts)))
print("doRelRates = %s %s" % (self.doRelRates, type(self.doRelRates)))
print("relRatesAreFree = %s %s" % (self.relRatesAreFree, type(self.relRatesAreFree)))
print("nFreePrams = %s  %s" % (self.nFreePrams, type(self.nFreePrams)))                 # a float ?!
print("isHet = %s %s" % (self.isHet, type(self.isHet)))
print("_rMatrixNormaizeTo1 = %s %s" % (var._rMatrixNormalizeTo1, type(var._rMatrixNormalizeTo1)))
if self.cModel:
raise P4Error(gm)
self.cModel = pf.p4_newModel(self.nParts,
self.doRelRates,
self.relRatesAreFree,
int(self.nFreePrams),
self.isHet,
var._rMatrixNormalizeTo1,
var._PINVAR_MIN,
var._PINVAR_MAX,
var._KAPPA_MIN,
var._KAPPA_MAX,
var._GAMMA_SHAPE_MIN,
var._GAMMA_SHAPE_MAX,
var._PIVEC_MIN,
var._PIVEC_MAX,
var._RATE_MIN,
var._RATE_MAX,
var._RELRATE_MIN,
var._RELRATE_MAX,
var._BRLEN_MIN,
var._BRLEN_MAX)
#print("                                          ==== new cModel %s"  % self.cModel)
for pNum in range(self.nParts):
mp = self.parts[pNum]
if 0:
print(self.cModel, end=' ')
print(pNum, end=' ')
print(mp.dim, end=' ')
print(mp.nComps, end=' ')
print(mp.nRMatrices, end=' ')
print(mp.nGdasrvs, end=' ')
print(mp.nGammaCat, end=' ')
print(mp.pInvar.free, end=' ')

nGammaCat = mp.nGammaCat

mp.bQETneedsReset = numpy.ones(
(mp.nComps, mp.nRMatrices), numpy.int32)

pf.p4_newModelPart(self.cModel,
pNum, mp.dim, mp.nComps, mp.nRMatrices, mp.nGdasrvs, nGammaCat,
mp.pInvar.free, mp.bQETneedsReset)
for mNum in range(mp.nComps):
mt = mp.comps[mNum]
assert mt.val is not None  # mt.val is a numpy array
pf.p4_newComp(self.cModel, pNum, mNum, mt.free, mt.val)
for mNum in range(mp.nRMatrices):
mt = mp.rMatrices[mNum]
theSpec = None
if mt.spec == 'ones':
theSpec = 100
elif mt.spec == 'specified' or mt.spec == 'optimized':
theSpec = 20
elif mt.spec == '2p':
theSpec = 5
elif mt.spec == 'cpREV':
theSpec = 101
elif mt.spec == 'd78':
theSpec = 102
elif mt.spec == 'jtt':
theSpec = 103
elif mt.spec == 'mtREV24':
theSpec = 104
elif mt.spec == 'mtmam':
theSpec = 105
elif mt.spec == 'wag':
theSpec = 106
# the one I have, from MrBayes.  Same as phyml.
elif mt.spec == 'blosum62':
theSpec = 107
# elif mt.spec == 'blosum62b':
#    theSpec = 108
# elif mt.spec == 'phat70':
#    theSpec = 109
elif mt.spec == 'rtRev':
theSpec = 110
elif mt.spec == 'tmjtt94':
theSpec = 111
elif mt.spec == 'tmlg99':
theSpec = 112
elif mt.spec == 'lg':
theSpec = 113
elif mt.spec == 'hivb':
theSpec = 114
elif mt.spec == 'mtart':
theSpec = 115
elif mt.spec == 'mtzoa':
theSpec = 116
elif mt.spec == 'gcpREV':
theSpec = 117
elif mt.spec == 'stmtREV':
theSpec = 118
elif mt.spec == 'vt':
theSpec = 119
elif mt.spec == 'pmb':
theSpec = 120
else:
gm.append("Programming error.")
gm.append("Bad rMatrix spec '%s'.  Part %i" %
(mt.spec, pNum))
gm.append("Should be one of %s" % var.rMatrixSpecs)
raise P4Error(gm)
# This next function sets the values of the rMatrices.
# For protein matrices, the values are set only in c.
# For ones and specified matrices, the rmatrix is set
# to all ones-- any specifed values are poked in
# later, in ModelPart.setCStuff()
pf.p4_newRMatrix(self.cModel, pNum, mNum, mt.free, theSpec)
for mNum in range(mp.nGdasrvs):
mt = mp.gdasrvs[mNum]
# print 'about to pf.p4_newGdasrv(), mt.val=%f, mt.val[0]=%f' %
# (mt.val, mt.val[0])
mt.c = pf.p4_newGdasrv(
self.cModel, pNum, mNum, mt.nGammaCat, mt.free, mt.val, mt.freqs, mt.rates)
mt.calcRates()
# print "finished Model.allocCStuff()"

def setCStuff(self, partNum=None):

if partNum == None:
for pNum in range(self.nParts):
self.parts[pNum].setCStuff(self)
else:
self.parts[partNum].setCStuff(self)

def restoreFreePrams(self, prams):

if 0:
print("nFreePrams = %s" % self.nFreePrams)
print("prams=%s" % prams)
sys.exit()
pos = 0
for pNum in range(self.nParts):
mp = self.parts[pNum]

# Do the comps
for mNum in range(mp.nComps):
mt = mp.comps[mNum]
if mt.free:
mt.spec = 'optimized'
# Restore all but the last val
for i in range(mp.dim - 1):
#mt.val[i] = prams[pos]
pos += 1
# # Calculate the last val
# mt.val[mp.dim - 1] = 1.0 - sum(mt.val[:-1])
# # Make sure the vals are not too small
# needsNormalizing = 0
# theSum = 0.0
# for i in range(mp.dim):
#     if mt.val[i] < var.PIVEC_MIN:
#         mt.val[i] = var.PIVEC_MIN + (var.PIVEC_MIN * 0.2) + (var.PIVEC_MIN * random.random())
#         needsNormalizing = 1
#     theSum += mt.val[i]
# if needsNormalizing or theSum != 1.0:
#     for i in range(mp.dim):
#         mt.val[i] /= theSum
assert math.fabs(1.0 - numpy.sum(mt.val)) < 1.e-15
if numpy.min(mt.val) < var.PIVEC_MIN:
gm.append("var.PIVEC_MIN is currently %g" % var.PIVEC_MIN)
gm.append("Got comp %i val %g ; too small" % (mNum, numpy.min(mt.val)))
raise P4Error(gm)
if 0:
theSum = sum(mt.val)
print("restoreFreePrams(). pNum %i, comp %i, sum=%g, 1.0 - sum = %g" % (
pNum, mNum, theSum, (1.0 - theSum)))

# Do the rMatrices.
for mNum in range(mp.nRMatrices):
mt = mp.rMatrices[mNum]
if mt.free:
if mt.spec == '2p':
mt.val[0] = prams[pos]
pos += 1
else:
mt.spec = 'optimized'
k = 0
for i in range(mp.dim - 2):
for j in range(i + 1, mp.dim):
# print i, j, k, pos
mt.val[k] = prams[pos]
k += 1
pos += 1
if var.rMatrixNormalizeTo1:
# Calculate the last value
mt.val[-1] = 1.0 - sum(mt.val[:-1])
needsNormalizing = 0
theSum = 0.0
# print mt.val, sum(mt.val)
for i in range(len(mt.val)):
if mt.val[i] < var.RATE_MIN:
mt.val[i] = var.RATE_MIN + \
(var.RATE_MIN * random.random())
needsNormalizing = 1
theSum += mt.val[i]
if needsNormalizing or theSum != 1.0:
mt.val /= theSum

# Do the gdasrvs
if mp.nGammaCat > 1:
for mNum in range(mp.nGdasrvs):
mt = mp.gdasrvs[mNum]
if mt.free:
# print 'restoreFreePrams().  mt.val=%f, mt.val[0]=%f, prams[pos]=%f' % (
# mt.val, mt.val[0], prams[pos])
if (mt.val - prams[pos]) > 1.e-10:
raise P4Error(
#mt.val = prams[pos]
pos += 1

# Do the pInvar
if mp.pInvar.free:
mp.pInvar.val = prams[pos]
pos += 1

# Do the relRates, after the loop
if self.relRatesAreFree:
for pNum in range(self.nParts - 1):
mp = self.parts[pNum]
mp.relRate = prams[pos]
pos += 1
# Get the last relRate
mp = self.parts[self.nParts - 1]
mp.relRate = pf.p4_getRelRate(self.cModel, self.nParts - 1)

def copyValsTo(self, otherModel):

for pNum in range(self.nParts):
sp = self.parts[pNum]
op = otherModel.parts[pNum]
sp.copyValsTo(op)

def copyBQETneedsResetTo(self, otherModel):
for pNum in range(self.nParts):
self.parts[pNum].copyBQETneedsResetTo(otherModel.parts[pNum])

def copyNNodesTo(self, otherModel):

if self.isHet:
for pNum in range(self.nParts):
sp = self.parts[pNum]
if sp.isHet:
op = otherModel.parts[pNum]
sp.copyNNodesTo(op)

def verifyValsWith(self, otherModel):

epsilon1 = 1.e-15

for pNum in range(self.nParts):
sp = self.parts[pNum]
op = otherModel.parts[pNum]

# comps
for mtNum in range(sp.nComps):
smt = sp.comps[mtNum]
if smt.free:
omt = op.comps[mtNum]
for i in range(sp.dim):
if math.fabs(smt.val[i] - omt.val[i]) > epsilon1:
print("Model.verifyValsWith()  comp vals differ.")
break
if self.isHet:
for mtNum in range(sp.nComps):
if op.comps[mtNum].nNodes != sp.comps[mtNum].nNodes:
print("Model.verifyValsWith()  nNodes differ.")
break

# rMatrices
for mtNum in range(sp.nRMatrices):
smt = sp.rMatrices[mtNum]
if smt.free:
omt = op.rMatrices[mtNum]
if smt.spec == '2p':
if math.fabs(smt.val[0] - omt.val[0]) > epsilon1:
break
else:
# for i in range((((sp.dim * sp.dim) - sp.dim) // 2) - 1):
for i in range(len(smt.val)):
if math.fabs(smt.val[i] - omt.val[i]) > epsilon1:
break
if self.isHet:
for mtNum in range(sp.nRMatrices):
if op.rMatrices[mtNum].nNodes != sp.rMatrices[mtNum].nNodes:
break

# gdasrvs
for mtNum in range(sp.nGdasrvs):
smt = sp.gdasrvs[mtNum]
if smt.free:
omt = op.gdasrvs[mtNum]
if math.fabs(smt.val[0] - omt.val[0]) > epsilon1:
break

# pInvar
if sp.pInvar.free:
if math.fabs(sp.pInvar.val - op.pInvar.val) > epsilon1:
break

# relRate
if self.doRelRates and self.relRatesAreFree:
if math.fabs(sp.relRate - op.relRate) > epsilon1:
break

# bQETneedsReset
# if hasattr(sp.bQETneedsReset, 'size'):  # Can't simply ask 'if
# sp.bQETneedsReset'
if 0:
for i in range(sp.nComps):
for j in range(sp.nRMatrices):
# integers
if op.bQETneedsReset[i][j] != sp.bQETneedsReset[i][j]:
print("Mis-matched bQETneedsReset.")
print("self.bQETneedsReset is")
print(sp.bQETneedsReset)
print("other.bQETneedsReset is")
print(op.bQETneedsReset)
break
if 1:
# bQETneedsReset is a numpy array of ints
assert isinstance(op.bQETneedsReset, numpy.ndarray)
# ret is an array of booleans.
ret = op.bQETneedsReset != sp.bQETneedsReset
if numpy.any(ret):
print("Mis-matched bQETneedsReset.  Part %i" % pNum)
print("self.bQETneedsReset is")
print(sp.bQETneedsReset)
print("other.bQETneedsReset is")
print(op.bQETneedsReset)
print("positions differing:")
print(ret)
break

print("    Mis-matched model prams.")
return var.DIFFERENT
return var.SAME

[docs]    def getBigQ(self, pNum=0, compNum=0, rMatrixNum=0):
"""Returns a dim * dim numpy array with the bigQ """

mp = self.parts[pNum]
c = mp.comps[compNum]
r = mp.rMatrices[rMatrixNum]
a = numpy.zeros((mp.dim, mp.dim), numpy.float)
pf.getBigQ(self.cModel, mp.dim, pNum, compNum, rMatrixNum, a)
return a
```