/* * MrBayes 2.0 * * John P. Huelsenbeck * Department of Biology * University of Rochester * Rochester, NY 14627 * * johnh@brahms.biology.rochester.edu * * Fredrik Ronquist * Dept. Systematic Zoology * Evolutionary Biology Centre * Uppsala University * Norbyv. 18D, SE-752 36 Uppsala, Sweden * * fredrik.ronquist@ebc.uu.se * */ #include #include #include #include #include #include #include "jph.h" #include "tree.h" #include "mcmc.h" #include "command.h" #include "gamma.h" #include "linalg.h" #include "matrices.h" #include "complex.h" #define MORPH #if defined (MORPH) #define NUM_ALLOCS 45 #else #define NUM_ALLOCS 44 #endif #define ALLOC_KAPPA 0 #define ALLOC_SUBPARAMS 1 #define ALLOC_BASEFREQS 2 #define ALLOC_GAMMA_SHAPE 3 #define ALLOC_SITE_RATES 4 #define ALLOC_UNSCALED_SITE_RATES 5 #define ALLOC_NSITES_IN_PART 6 #define ALLOC_MATRIX 7 #define ALLOC_N_SITE_PATS 8 #define ALLOC_PART_ID 9 #define ALLOC_NODES 10 #define ALLOC_ROOT 11 #define ALLOC_ALLDOWNPASS 12 #define ALLOC_INTDOWNPASS 13 #define ALLOC_CLUPDATE_FLAG 14 #define ALLOC_COND_LIKES 15 #define ALLOC_COND_SCALER 16 #define ALLOC_DISTANCES 17 #define ALLOC_TREE_HEIGHT 18 #define ALLOC_ANC_STATES 19 #define ALLOC_TEMP_ANC_STATES 20 #define ALLOC_PAT_IDS 21 #define ALLOC_SP_RATE 22 #define ALLOC_EX_RATE 23 #define ALLOC_OMEGA 24 #define ALLOC_PUR 25 #define ALLOC_NEU 26 #define ALLOC_POS 27 #define ALLOC_AUTO_GAMMA 28 #define ALLOC_AUTO_GAMMA2 29 #define ALLOC_LAG 30 #define ALLOC_INV_P 31 #define ALLOC_SWITCH_RATE 32 #define ALLOC_SWITCH_PI 33 #define ALLOC_GC1 34 #define ALLOC_GC2 35 #define ALLOC_FRAC_A 36 #define ALLOC_FRAC_G 37 #define ALLOC_LN_SITE_SCALER 38 #define ALLOC_SCALER_UPDATE_FLAG 39 #define ALLOC_TERM_STATES 40 #define ALLOC_TI_PROBS 41 #define ALLOC_TI_FLAGS 42 #define ALLOC_STATE_SET 43 #if defined (MORPH) #define ALLOC_BETA 44 #endif #define MAX_PROPOSAL_SIZE 33 #if defined (MORPH) #define NUM_PROPOSAL_TYPES 24 #else #define NUM_PROPOSAL_TYPES 23 #endif #define CHANGE_QMAT 0 #define CHANGE_BASEFREQS 1 #define CHANGE_GAMMA_SHAPE 2 #define CHANGE_SITE_RATES 3 #define CHANGE_UNROOT_LOCAL 4 #define CHANGE_CLOCK_LOCAL 5 #define CHANGE_CLOCK_TIME_LOCAL 6 #define CHANGE_TREE_HEIGHT 7 #define CHANGE_WORM 8 #define CHANGE_NODE_TIME 9 #define CHANGE_BD_PARAMS 10 #define CHANGE_OMEGA 11 #define CHANGE_OMEGA_PROBS 12 #define CHANGE_AUTO_CORR 13 #define CHANGE_LAG 14 #define CHANGE_TREE_SPR 15 #define CHANGE_INV_P 16 #define CHANGE_SWITCH_RATE 17 #define CHANGE_UNROOT_TBR 18 #define CHANGE_GCSWITCH 19 #define CHANGE_TREE_FTBR 20 #define CHANGE_BRLEN 21 #define CHANGE_ERASER 22 #if defined (MORPH) #define CHANGE_BETA_SHAPE 23 #endif #define LIKE_EPSILON 1.0e-300 #define BRLEN_EPSILON 1.0e-8 #define RESCALE_FREQ 5 #define MAX_COVARIATES 20000 #define A 0 #define C 1 #define G 2 #define T 3 #define AA 0 #define AC 1 #define AG 2 #define AT 3 #define CA 4 #define CC 5 #define CG 6 #define CT 7 #define GA 8 #define GC 9 #define GG 10 #define GT 11 #define TA 12 #define TC 13 #define TG 14 #define TT 15 #define ROOTED 0 #define UNROOTED 1 #define SCREENWIDTH 60 #define SCREENWIDTH2 61 #undef DEBUG_START_TREE #undef DEBUG_LOCAL #undef DEBUG_LOCAL_CLOCK #undef DEBUG_LOCAL_TIME_CLOCK #undef SHOW_MOVE_WORM #undef DEBUG_SPR #undef DEBUG_TBR #undef DEBUG_FTBR #undef DEBUG_BRLENMOVE #undef DEBUG_INITCONDLIKES #undef TOPOLOGY_MOVE_STATS #undef DEBUG_LNLIKEBIN #undef TRANSLATE_TO_AA #define SUPER_FAST #define SMART_TI_PROBS /*-pac- #define MORPH //NB! MORPH also defined earlier in this file to fix #define statements */ void BetaBreaks (double alpha, double beta, double *values, double *probs, int K); double BetaCf (double a, double b, double x); double BetaQuantile (double alpha, double beta, double x); int BuildStartingTree (int numTaxa, int numChars, long int *seed, int showStartTree); void CalcCijk (double *c_ijk, int n, double **u, double **v); void CalcPij (double *c_ijk, int n, double *eigenValues, double v, double r, double **p); void CalcPFSij (double *c_ijk, int n, double *eigenValues, double v, double r, double **p, double **f_p, double **s_p); # if defined (SMART_TI_PROBS) int CalcTransitionProbs (int whichState, int whichChain, int numRateCats); int CalcTransAA (int whichState, int whichChain, int numRateCats); int CalcTransCodon (int whichState, int whichChain); int CalcTransCovarion (int whichState, int whichChain, int numRateCats); int CalcTransDNA (int whichState, int whichChain, int numRateCats); # endif int CheckConstraints (void); int ComplexChangeMatrix (double *eigenValues, double *eigvalsImag, complex **Ceigvecs, complex **CinverseEigvecs, int n, double **p, double t, double r); int ComplexDerivativesMatrix (double *eigenValues, double *eigvalsImag, complex **Ceigvecs, complex **CinverseEigvecs, int n, double **f, double **s, double t, double r); int CompressMatrix (int *numTaxa, int *numChars); int CompressMatrixPars (int *numTaxa, int *numChars); void CopyConditionalLikelihoods (int from, int to, int whichChain, int numTaxa, int numChars, int numRateCats); void CopyTree (int from, int to, int whichChain); void DirichletRandomVariable (double *alp, double *z, int n, long int *seed); void FreeMemory (void); double GetTreeLength (int whichState, int whichChain); int GetDistances (int numTaxa, int numChars); void GetDownPassSeq (TreeNode *p, int whichTree, int whichChain, int numTaxa, int *i, int *j); int GetEigens (int n, double **q, double *eigenValues, double *eigvalsImag, double **eigvecs, double **inverseEigvecs, complex **Ceigvecs, complex **CinverseEigvecs); void GetEmpiricalAAFreqs (void); void GetEmpiricalBaseFreqs (void); void GetPossibleAAs (int nucCode, int nuc[]); void GetPossibleNucs (int nucCode, int nuc[]); void GetTempDownPassSeq (TreeNode *p, int *i, TreeNode **dp); void HkyChangeMat (double **ch_prob, double time, double k, double r, double piA, double piC, double piG, double piT); void HkyFirstMat (double **ch_prob, double time, double k, double r, double piA, double piC, double piG, double piT); void HkySecondMat (double **ch_prob, double time, double k, double r, double piA, double piC, double piG, double piT); double IncompleteBetaFunction (double alpha, double beta, double x); int InitializeConditionalLikes (int numTaxa, int numChars, int numRateCats); int InitializeTipStates (int numTaxa, int numChars); int InitTiMatrix (double m[3][3], double x, double y, double z, double pPurifying, double pNeutral, double pPositive, int model); int IsKink (TreeNode *p); int IsLeaf (TreeNode *p); int LnBDPrior (int whichState, int whichChain, int numTaxa, double *prob); double LnGamma (double alp); int LnLike (int whichState, int whichChain, int numChars, int numRateCats, double *lnL, int refreshScalers); int LnLikeAA (int whichState, int whichChain, int numChars, int numRateCats, double *lnL, int refreshScalers); int LnLikeCodon (int whichState, int whichChain, int numChars, double *lnL, int refreshScalers); int LnLikeCovarion (int whichState, int whichChain, int numChars, int numRateCats, double *lnL, int refreshScalers); int LnLikeDNA (int whichState, int whichChain, int numChars, int numRateCats, double *lnL, int refreshScalers); int LnLikeRestriction (int whichState, int whichChain, int numChars, int numRateCats, double *lnL, int refreshScalers); int LnLikeStandardBin (int whichState, int whichChain, int numChars, int numRateCats, double *lnL, int refreshScalers); int LnLikeStandardMk (int whichState, int whichChain, int numChars, int numRateCats, double *lnL, int refreshScalers); double lnP1 (double t, double l, double m, double r); double lnVt (double t, double l, double m, double r); int MarkovChain (int numTaxa, int numChars, int numRateCats, long int *seed); int MarkovChainPars (int numTaxa, int numChars, long int *seed); void MarkPathDown (TreeNode *p, TreeNode *q); int Move_ChangeAutoCorr (int proposedState, int whichChain, long int *seed, double *lnPriorRatio); int Move_ChangeBaseFreqs (int proposedState, int whichChain, long int *seed, double *lnPriorRatio, double *lnProposalRatio); int Move_ChangeBetaShape (int proposedState, int whichChain, long int *seed, double *lnPriorRatio); int Move_ChangeBD (int proposedState, int whichChain, long int *seed); int Move_ChangeBrLen (int proposedState, int whichChain, long int *seed, double *lnProposalRatio, double *lnPriorRatio); int Move_ChangeClockWithLocal (int numTaxa, int proposedState, int whichChain, long int *seed, double *lnProposalRatio, double *lnPriorRatio); int Move_ChangeEraser (int numTaxa, int proposedState, int whichChain, long int *seed, double *lnProposalRatio, double *lnPriorRatio); int Move_ChangeGammaShape (int proposedState, int whichChain, long int *seed, double *lnPriorRatio); int Move_ChangeGCSwitch (int proposedState, int whichChain, long int *seed, double *lnPriorRatio, double *lnProposalRatio); int Move_ChangeLag (int proposedState, int whichChain, long int *seed, double *lnPriorRatio, double *lnProposalRatio); int Move_ChangeNNI (int numTaxa, int proposedState, int whichChain, long int *seed); int Move_ChangeQMatrix (int proposedState, int whichChain, long int *seed, double *lnPriorRatio); int Move_ChangeSiteRates (int proposedState, int whichChain, long int *seed, double *lnPriorRatio); int Move_ChangeNodeTime (int numTaxa, int proposedState, int whichChain, long int *seed, double *lnProposalRatio, double *lnPriorRatio); int Move_ChangeOmega (int proposedState, int whichChain, long int *seed, double *lnPriorRatio); int Move_ChangeOmegaProbs (int proposedState, int whichChain, long int *seed, double *lnPriorRatio, double *lnProposalRatio); int Move_ChangePropInv (int proposedState, int whichChain, long int *seed, double *lnPriorRatio); int Move_ChangeSwitchRate (int proposedState, int whichChain, long int *seed, double *lnPriorRatio); int Move_ChangeTimeClockWithLocal (int numTaxa, int proposedState, int whichChain, long int *seed, double *lnProposalRatio, double *lnPriorRatio); int Move_ChangeTreeHeight (int proposedState, int whichChain, long int *seed, double *lnProposalRatio); int Move_ChangeUnrootedWithLocal (int numTaxa, int proposedState, int whichChain, long int *seed, double *lnProposalRatio, double *lnPriorRatio); int Move_SingleWorm (int numTaxa, int proposedState, int whichChain, long int *seed, double *lnProposalRatio, double *lnPriorRatio); int Move_ChangeUnrootedWithSPR (int numTaxa, int proposedState, int whichChain, long int *seed, double *lnProposalRatio, double *lnPriorRatio); int Move_ChangeTBR (int numTaxa, int proposedState, int whichChain, long int *seed, double *lnProposalRatio, double *lnPriorRatio); int Move_ChangeFTBR (int numTaxa, int proposedState, int whichChain, long int *seed, double *lnProposalRatio, double *lnPriorRatio); int NumAdjacentMarked (TreeNode *p); FILE *OpenFile(char *filename, int isNexus); double ParsimonyLength (int whichState, int whichChain, int numChars); int PerturnStartingTree (int numTaxa, long int *seed); int PrepareOutputFiles (void); int PrepareParsOutputFiles (void); int PrintAncStatesAA (int whichState, int whichChain, int numChars, int numRateCats, int whichGen); int PrintAncStatesDNA (int whichState, int whichChain, int numChars, int numRateCats, int whichGen); int PrintPosSelProbs (int whichState, int whichChain, int numChars, int numRateCats, int whichGen); int PrintRateFactors (int whichState, int whichChain, int numChars, int numRateCats, int whichGen); int PrintStatesToFile (int n, int coldId, int whichState, double logLike, double *constrainedNodes, double *calibratedNodes); int ProposeNewState (long int *seed); double RandomNumber (long int *seed); double RndGamma (double s, long int *seed); double RndGamma1 (double s, long int *seed); double RndGamma2 (double s, long int *seed); int SetAARates (void); void SetCode (void); int SetModel (int *numRateCats); int SetAAQMatrix (double **a, int whichTree, int whichChain); int SetCodonQMatrix (double **a, int whichTree, int whichChain, double nonsyn, double kap); int SetCodonSwitchQMatrix (double **a, int whichTree, int whichChain, double nonsyn, double kap, double sr); int SetAACovQMatrix (double **a, int whichTree, int whichChain, double r); int SetDNACovQMatrix (double **a, int whichTree, int whichChain, double r); int SetGCSwitchQMatrix (double **a, int whichTree, int whichChain, double r); int SetQMatrix (double **a, int whichTree, int whichChain); # if defined (SMART_TI_PROBS) int SetUpTransitionProbs (int numRateCats); # endif int SetUpTrees (int numTaxa); int ShowStartTree (TreeNode *r, int nt, int isThisTreeRooted); #if defined (TRANSLATE_TO_AA) void TranslateToAA (void); # endif void UpDateAllCls (int whichState, int whichChain); void UpDateAllTIs (int whichState, int whichChain); char WhichAA (int x); void WriteTreeToFile (TreeNode *p, FILE *fp, int showBrlens); void WriteTreeToScreen (TreeNode *p, int showBrlens); int YesNo (void); static int nStates, nst, isStartingTreeRandom, allocatedMemory[NUM_ALLOCS], *nSitesInPartition, *matrix, *numSitesOfPat, *partitionId, treeModel, intNodeNum, localOutgroup, numNodes, numIntNodes, *clUpdateFlag, *patternId, nSampled, *numCovEvents, aaJones[20][20], aaDayhoff[20][20], codon[64], transCodon[64], codonNucs[64][3], *lag, nExcluded, numDummyChars, numBetaCats, *scalerUpdateFlag; #if defined (TRANSLATE_TO_AA) static int treatAsAA; // temporary solution, should be declared as global instead #endif static unsigned int *stateSet; static double *kappa, *subParams, *baseFreq, *alpha, relProposalProbs[NUM_PROPOSAL_TYPES], *rateCorrelation, chainMins[NUM_PROPOSAL_TYPES], chainMaxs[NUM_PROPOSAL_TYPES], *scaledRates, *unscaledRates, *condLike, *distances, *treeHeight, *clScaler, *ancStatesProbs, *tempStateProbs, *covInvariable, *covLambda, *spRate, *exRate, *posSelProbs, *rateCorrelation2, dayhoffPi[20], jonesPi[20], *omega, *probPur, *probNeu, *probPos, *invP, *rateFactors, *switchRate, *switchPi, *rateProbs, *gc1, *gc2, *fracA, *fracG, *lnSiteScaler, EigValexp[200]; static char proposalName[NUM_PROPOSAL_TYPES][MAX_PROPOSAL_SIZE] = {"changes to Q matrix", "changes to base frequencies", "changes to gamma shape", "changes to site rates", "changes to tree (stochastic NNI)", "changes to clock tree", "changes to tree", "changes to tree height", "changes to tree (one worm)", "changes to node time", "changes to bd parameters", "changes to omega", "changes to omega probabilities", "changes to auto correlation", "changes to lag", "changes to tree (stochastic SPR)", "changes to proportion invariant", "changes to covarion parameter", "changes to tree (TBR1)", "changes to GC swith parameters", "changes to tree (TBR2)", "changes to a branch length", "changes to tree (eraser)", "changes to beta/dirichlet shape"}; static TreeNode *nodes, **root, *tempNodes, **intNodeDownPassSeq, **allNodesDownPassSeq; FILE *tFile, *pFile, *bpFile; extern int nTaxa, nChar, *origDataMatrix, dataType, isUserTreeDefined, isTreeRooted, numChains, *excludedTaxa, *excludedSites, isPartitionDefined, nPartitions, *sitePartitions, nRateCats, enforceConstraints, enforceCalibrations, inferAncStates, *constraints, nConstraints, *calibrations, nCalibrations, outgroupNum, nGen, printFreq, sampleFreq, saveBrlens, autoclose, nPerturbations, userBrlensDef, aaModelType, saveAncFiles, enforceCodonModel, aaCode, inferPoseSel, lagNumber, inferRates, useCovarion, mcmcBurn, cycleFreq, calcPseudoBf, useParsCriterion; extern long int randomSeed; extern double tRatio, revRates[6], nonRevRates[12], qmatprExp, qmatprUni[2], basefreqprDir, shape, shapeprUni[2], shapeprExp, siteRates[50], siterateprExp, siterateprUni[2], brlenprExp, brlenprUni[2], chainTemp, calibrationTimes[32][2], seqErrorProb, speciationRate, extinctionRate, samplingFraction, omegaRatio, omegaprUni[2], omegaprExp, lagprUni[2], lagprExp, qMatWinProp, piAlphaProp, rateWinProp, tuningProp, clockTuneProp, timeTuneProp, mTuneProp, extendPProp, wormTuneProp, bdWinProp, omegaWinProp, rhoWinProp, omegaAlphaProp, invSlideProp, switchWinProp, alphaWinProp, nodeTimeTuneProp, reconLimProp, tbrExtendPProp, tbrTuneProp, blTuneProp, statefreqprDir, moveRates[100]; extern char startingTreeModel[20], subModel[20], baseFreqModel[20], ratesModel[20], qmatprModel[20], basefreqprModel[20], shapeModel[20], shapeprModel[20], defPartitionName[50], partitionName[50], siterateprModel[20], clockModel[20], covarionModelType[20], brlenprModel[20], *taxonLabels, calibrationLabels[32][100], constraintLabels[32][100], outFile[100], codonModelType[20], omegaRatioModel[20], omegaprModel[20], lagModel[20], lagprModel[20], codingType[20], stateFreqPrModel[20]; extern TreeNode *userTree, *userTreeRoot; # if defined (TOPOLOGY_MOVE_STATS) int gTopologyHasChanged, gNodeMoves, nAcceptedTopology[NUM_PROPOSAL_TYPES], nProposedTopology[NUM_PROPOSAL_TYPES], nProposedNodes[NUM_PROPOSAL_TYPES], nAcceptedNodes[NUM_PROPOSAL_TYPES]; # endif # if defined (MORPH) double pObserved, *statefreqP; # endif // termState: vector with terminal state code, multiplied with 4 to give suitable index // isPartAmbig: flag signalling if terminal is partly ambiguous for some sites # if defined (SUPER_FAST) int *termState, *isPartAmbig; # endif # if defined (SMART_TI_PROBS) int *updateTiFlag, nodeTiSize; double *transitionProbs; # endif void BetaBreaks (double alpha, double beta, double *values, double *probs, int K) { int i; double r, quantile, lower, upper; r = (1.0 / K) * 0.5; lower = 0.0; upper = (1.0 / K); r = (upper - lower) * 0.5 + lower; for (i=0; i 100) { printf ("Error in BetaCf.\n"); exit (-1); } return (h); } double BetaQuantile (double alpha, double beta, double x) { int i, stopIter, direction, nswitches; double curPos, curFraction, increment; i = nswitches = 0; curPos = 0.5; stopIter = NO; increment = 0.25; curFraction = IncompleteBetaFunction (alpha, beta, curPos); if (curFraction > x) direction = DOWN; else direction = UP; while (stopIter == NO) { curFraction = IncompleteBetaFunction (alpha, beta, curPos); if (curFraction > x && direction == DOWN) { /* continue going down */ while (curPos - increment <= 0.0) { increment /= 2.0; } curPos -= increment; } else if (curFraction > x && direction == UP) { /* switch directions, and go down */ nswitches++; direction = DOWN; while (curPos - increment <= 0.0) { increment /= 2.0; } increment /= 2.0; curPos -= increment; } else if (curFraction < x && direction == UP) { /* continue going up */ while (curPos + increment >= 1.0) { increment /= 2.0; } curPos += increment; } else if (curFraction < x && direction == DOWN) { /* switch directions, and go up */ nswitches++; direction = UP; while (curPos + increment >= 1.0) { increment /= 2.0; } increment /= 2.0; curPos += increment; } else { stopIter = YES; } if (i > 1000 || nswitches > 20) stopIter = YES; i++; } return (curPos); } int BuildStartingTree (int numTaxa, int numChars, long int *seed, int showStartTree) { int i, j, k, n, tSize, nNodes, nTips, nInts, nextTip, nextInt, nPotentialPlaces, whichNode, consistentNode, uniqueBipart1[32], uniqueBipart2[32], isMarked, nId, nLftId, nRhtId, nAncId, nUserNodes, tempLength; unsigned int conLft, conRht, conAnc, conNde, conNum1, conNum2, *localConstraints, *localCalibrations; double treeLength, sum, oldestAbove, oldestBelow; TreeNode *p, *a, *b, *c, *d, *e, **availTips, **availInts, **tempDP, *tempRoot, **potentialPlaces, *lft, *m1, *m2, *um1, *um2, *out; if (enforceConstraints == YES || enforceCalibrations == YES) { if (CheckConstraints () == NO) { printf ("\n ERROR: Constraints and/or calibrations are inconsistent with a single tree\n"); FreeMemory (); return (ERROR); } } printf (" Making starting trees\n"); if (treeModel == ROOTED) { tSize = 2*numTaxa; printf (" Starting tree(s) are rooted\n"); } else if (treeModel == UNROOTED) { tSize = 2*numTaxa-2; printf (" Starting tree(s) are unrooted\n"); } else { printf ("\n ERROR: Cannot decide if the tree is rooted or unrooted\n"); FreeMemory (); return (ERROR); } /* allocate memory for nodes */ nodes = (TreeNode *)malloc(sizeof(TreeNode) * numChains * 2 * tSize); if (!nodes) { printf ("\n ERROR: Could not allocate nodes\n"); FreeMemory (); return (ERROR); } else allocatedMemory[ALLOC_NODES] = YES; root = (TreeNode **)malloc(sizeof(TreeNode *) * numChains * 2); if (!root) { printf ("\n ERROR: Could not allocate root\n"); FreeMemory (); return (ERROR); } else allocatedMemory[ALLOC_ROOT] = YES; printf (" Allocated memory for trees\n"); /* set the tree pointers to null */ for (i=0; iindex = j; p->memoryIndex = j; if (enforceConstraints == YES) p->constraints = localConstraints[i]; if (enforceCalibrations == YES) p->calibrations = localCalibrations[i]; k = 0; while (taxonLabels[i*100+k] != '|') { p->label[k] = taxonLabels[i*100+k]; k++; } p->label[k] = '\0'; j++; } } k = 0; for (i=numTaxa; i<2*numTaxa; i++) { p = &tempNodes[j]; availInts[k] = p; p->index = j; p->memoryIndex = j; j++; k++; } /* set up initial split at base with two taxa */ a = availTips[0]; b = availTips[1]; c = availInts[0]; d = availInts[1]; a->anc = b->anc = c; c->left = a; c->right = b; c->anc = d; d->left = c; tempRoot = d; nNodes = 4; nTips = 2; nInts = 2; nextTip = 2; nextInt = 2; if (enforceConstraints == YES) { for (i=0; iconstraints; conRht = conNde & b->constraints; if (conLft == conNde) uniqueBipart1[i] = NO; if (conRht == conNde) uniqueBipart1[i] = NO; } # if defined (DEBUG_START_TREE) printf ("unique bipartitions: "); for (i=0; icalibrations; conRht = conNde & b->calibrations; if (conLft == conNde) uniqueBipart2[i] = NO; if (conRht == conNde) uniqueBipart2[i] = NO; } # if defined (DEBUG_START_TREE) printf ("unique bipartitions: "); for (i=0; ileft != NULL && p->right != NULL) { conLft = p->left->constraints; conRht = p->right->constraints; conNde = conLft & conRht; p->constraints = conNde; } else if (p->left != NULL && p->right == NULL && p->anc == NULL) p->constraints = 0; # if defined (DEBUG_START_TREE) printf ("%4d -- %d\n", p->index, p->constraints); # endif } } if (enforceCalibrations == YES) { for (i=0; ileft != NULL && p->right != NULL) { conLft = p->left->calibrations; conRht = p->right->calibrations; conNde = conLft & conRht; p->calibrations = conNde; } else if (p->left != NULL && p->right == NULL && p->anc == NULL) p->calibrations = 0; # if defined (DEBUG_START_TREE) printf ("%4d -- %d\n", p->index, p->calibrations); # endif } } /* make list of acceptable nodes */ a = availTips[nextTip]; # if defined (DEBUG_START_TREE) printf ("adding taxon %s\n", a->label); # endif if (enforceConstraints == YES) { conNum1 = a->constraints; for (j=0; j 0 && uniqueBipart1[j] == YES) { conNum1 -= (int)pow(2.0, (double)j); uniqueBipart1[j] = NO; } } # if defined (DEBUG_START_TREE) printf ("conNum1 = %d\n", conNum1); # endif } if (enforceCalibrations == YES) { conNum2 = a->calibrations; for (j=0; j 0 && uniqueBipart2[j] == YES) { conNum2 -= (int)pow(2.0, (double)j); uniqueBipart2[j] = NO; } } # if defined (DEBUG_START_TREE) printf ("conNum2 = %d\n", conNum2); # endif } nPotentialPlaces = 0; if (enforceConstraints == YES || enforceCalibrations == YES) { for (i=0; ianc != NULL) { consistentNode = YES; if (enforceConstraints == YES) { for (j=0; jconstraints & (int)pow(2.0, (double)j); conRht = p->anc->constraints & (int)pow(2.0, (double)j); conNde = conNum1 & (int)pow(2.0, (double)j); if (conNde != conLft && conNde != conRht) consistentNode = NO; } } if (enforceCalibrations == YES) { for (j=0; jcalibrations & (int)pow(2.0, (double)j); conRht = p->anc->calibrations & (int)pow(2.0, (double)j); conNde = conNum2 & (int)pow(2.0, (double)j); if (conNde != conLft && conNde != conRht) consistentNode = NO; } } if (consistentNode == YES) potentialPlaces[nPotentialPlaces++] = p; } } } else { for (i=0; ianc != NULL) potentialPlaces[nPotentialPlaces++] = p; } } # if defined (DEBUG_START_TREE) printf ("potential nodes = "); for (i=0; iindex); } printf ("\n"); # endif if (nPotentialPlaces <= 0) { free (availTips); free (availInts); free (tempDP); free (potentialPlaces); free (tempNodes); free (localConstraints); free (localCalibrations); printf ("\n ERROR: Could not add tip to tree\n"); return (ERROR); } /* randomly choose node from acceptable list */ whichNode = (int)(RandomNumber (seed) * nPotentialPlaces); p = potentialPlaces[whichNode]; /* add next tip taxon to tree */ b = availInts[nextInt]; c = p->anc; if (c->left == p) { b->anc = c; b->left = p; b->right = a; c->left = b; a->anc = b; p->anc = b; } else { b->anc = c; b->left = a; b->right = p; c->right = b; a->anc = b; p->anc = b; } /* increment nTips, etc. */ nTips++; nInts++; nextTip++; nextInt++; nNodes += 2; } /* clean tree up */ if (treeModel == UNROOTED) { i = 0; GetTempDownPassSeq (tempRoot, &i, tempDP); isMarked = NO; for (i=0; ileft == NULL && p->right == NULL) { if (p->index == localOutgroup) { p->marked = YES; isMarked = YES; } else p->marked = NO; } else if (p->left != NULL && p->right != NULL && p->anc != NULL) { if (p->left->marked == YES || p->right->marked == YES) p->marked = YES; else p->marked = NO; } else { p->marked = YES; } } if (isMarked == NO) { printf ("\n ERROR: Could not find outgroup taxon\n"); free (availTips); free (availInts); free (tempDP); free (potentialPlaces); free (tempNodes); free (localConstraints); free (localCalibrations); return (ERROR); } lft = tempRoot->left; while (lft->left->index != localOutgroup && lft->right->index != localOutgroup) { if (lft->left->marked == YES && lft->right->marked == NO) { m1 = lft->left; um1 = lft->right; if (m1->left != NULL && m1->right != NULL) { if (m1->left->marked == YES) { m2 = m1->left; um2 = m1->right; } else { m2 = m1->right; um2 = m1->left; } lft->left = m2; lft->right = m1; m2->anc = lft; m1->left = um2; m1->right = um1; m1->anc = lft; um1->anc = m1; um2->anc = m1; m1->marked = NO; } else { printf ("\n ERROR: Rooting routine is lost\n"); free (availTips); free (availInts); free (tempDP); free (potentialPlaces); free (tempNodes); free (localConstraints); free (localCalibrations); return (ERROR); } } else if (lft->left->marked == NO && lft->right->marked == YES) { m1 = lft->right; um1 = lft->left; if (m1->left != NULL && m1->right != NULL) { if (m1->left->marked == YES) { m2 = m1->left; um2 = m1->right; } else { m2 = m1->right; um2 = m1->left; } lft->left = m1; lft->right = m2; m2->anc = lft; m1->left = um1; m1->right = um2; m1->anc = lft; um1->anc = m1; um2->anc = m1; m1->marked = NO; } else { printf ("\n ERROR: Rooting routine is lost\n"); free (availTips); free (availInts); free (tempDP); free (potentialPlaces); free (tempNodes); free (localConstraints); free (localCalibrations); return (ERROR); } } else { printf (" ERROR: Rooting routine is lost\n"); free (availTips); free (availInts); free (tempDP); free (potentialPlaces); free (tempNodes); free (localConstraints); free (localCalibrations); return (ERROR); } } /* make certain outgroup is to the right of the root */ if (tempRoot->left->left->index == localOutgroup) { m1 = tempRoot->left->left; m2 = tempRoot->left->right; lft = tempRoot->left; lft->left = m2; lft->right = m1; } /* now, take outgroup and make it point down */ m1 = tempRoot; m2 = tempRoot->left; lft = tempRoot->left->left; out = tempRoot->left->right; lft->anc = out; out->left = lft; out->right = NULL; out->anc = NULL; m1->left = NULL; m2->left = NULL; m1->right = NULL; m2->right = NULL; m1->anc = NULL; m2->anc = NULL; tempRoot = out; } i = numTaxa; if (treeModel == UNROOTED) FinishTree (tempRoot, &i, NO); else FinishTree (tempRoot, &i, YES); # if defined (DEBUG_START_TREE) printf ("final tree for chain %d (before copy)\n",n); ShowNodes (tempRoot, 2, YES); //ShowStartTree (tempRoot, nTips, YES); # endif /* copy this tree into nodes */ i = 0; GetTempDownPassSeq (tempRoot, &i, tempDP); for (i=0; iindex; a = &nodes[n*2*tSize+nId]; a->index = nId; a->memoryIndex = nId; a->length = 0.1; /* TEMP: May decide to use different starting branch lengths later */ if (p->left != NULL) { nLftId = p->left->index; b = &nodes[n*2*tSize+nLftId]; a->left = b; } else a->left = NULL; if (p->right != NULL) { nRhtId = p->right->index; c = &nodes[n*2*tSize+nRhtId]; a->right = c; } else a->right = NULL; if (p->anc != NULL) { nAncId = p->anc->index; d = &nodes[n*2*tSize+nAncId]; a->anc = d; } else a->anc = NULL; if (a->left == NULL && a->right == NULL) strcpy (a->label, p->label); if (treeModel == UNROOTED && a->left != NULL && a->right == NULL && a->anc == NULL) strcpy (a->label, p->label); } nId = tempRoot->index; root[n*2+0] = &nodes[n*2*tSize+nId]; # if defined (DEBUG_START_TREE) printf ("final tree for chain %d (copied version)\n",n); ShowNodes (root[n*2+0], 2, YES); //ShowStartTree (tempRoot, nTips, YES); # endif } } else { /* user tree starts chain */ printf (" Starting tree(s) are user-specified\n"); if (treeModel == ROOTED && isTreeRooted == NO) { printf (" Rooting user tree\n"); if (RootTree (userTreeRoot) == ERROR) { FreeMemory (); free (availTips); free (availInts); free (tempDP); free (potentialPlaces); free (tempNodes); free (localConstraints); free (localCalibrations); return (ERROR); } isTreeRooted = YES; } else if (treeModel == UNROOTED && isTreeRooted == YES) { printf (" Derooting user tree\n"); if (DerootTree (userTreeRoot) == ERROR) { FreeMemory (); free (availTips); free (availInts); free (tempDP); free (potentialPlaces); free (tempNodes); free (localConstraints); free (localCalibrations); return (ERROR); } isTreeRooted = NO; } for (n=0; nindex; a = &tempNodes[nId]; a->index = nId; a->memoryIndex = nId; a->length = p->length; if (p->left != NULL) { nLftId = p->left->index; b = &tempNodes[nLftId]; a->left = b; } else a->left = NULL; if (p->right != NULL) { nRhtId = p->right->index; c = &tempNodes[nRhtId]; a->right = c; } else a->right = NULL; if (p->anc != NULL) { nAncId = p->anc->index; d = &tempNodes[nAncId]; a->anc = d; } else a->anc = NULL; if (a->left == NULL && a->right == NULL) strcpy (a->label, p->label); if (treeModel == UNROOTED && a->left != NULL && a->right == NULL && a->anc == NULL) strcpy (a->label, p->label); } nId = userTreeRoot->index; tempRoot = &tempNodes[nId]; /* delete unused nodes from temporary nodes*/ i = 0; GetTempDownPassSeq (tempRoot, &i, tempDP); for (i=0; imarked = NO; if (p->left == NULL && p->right == NULL && p->anc != NULL && excludedTaxa[p->index] == YES) { p->marked = YES; } else if (p->left != NULL && p->right == NULL && p->anc == NULL) { if (isTreeRooted == NO && excludedTaxa[p->index] == YES) { p->marked = YES; } } } for (i=0; imarked == YES) { if (p->anc != NULL) { b = p->anc; if (b->left == p) a = b->right; else a = b->left; c = b->anc; if (c->left == b) c->left = a; else c->right = a; a->anc = c; a->length += b->length; p->anc = p->left = p->right = NULL; b->anc = b->left = b->right = NULL; p->marked = NO; b->marked = NO; } else { /* first rotate tree so that left, left is a tip */ a = p->left; b = a->left; while (b->left != NULL && b->right != NULL) { c = b->left; d = b->right; e = a->right; c->anc = a; a->left = c; a->right = b; b->left = d; b->right = e; b->anc = a; d->anc = e->anc = b; e->length += b->length; b->length = c->length / 2.0; c->length = b->length; a = p->left; b = a->left; } if (treeModel == ROOTED) ShowNodes (tempRoot, 2, YES); else ShowNodes (tempRoot, 2, NO); /* now that the tree is rotated around the root, remove the root */ a = p->left; b = a->left; c = a->right; c->anc = b; c->length += b->length; b->left = c; b->right = b->anc = NULL; a->left = a->right = a->anc = NULL; p->left = p->right = p->anc = NULL; tempRoot = b; } } } /* if constraints are enforced, check that the user tree is consistent with the constraints */ i = 0; GetTempDownPassSeq (tempRoot, &i, tempDP); if (enforceConstraints == YES) { for (j=0; jleft == NULL && p->right == NULL && p->anc != NULL) { conLft = (unsigned int)pow(2.0, (double)j); nId = 0; for (k=0; kindex) break; nId++; } } conNde = conLft & (unsigned int)constraints[k]; if (conNde > 0) p->constraints = 2; else p->constraints = 1; } else if (p->left != NULL && p->right != NULL && p->anc != NULL) { conLft = p->left->constraints; conRht = p->right->constraints; conNde = conLft & conRht; if (conNde == 0) p->constraints = conLft | conRht; else p->constraints = conNde; } else { if (treeModel == UNROOTED) { conLft = (unsigned int)pow(2.0, (double)j); nId = 0; for (k=0; kindex) break; nId++; } } conNde = conLft & (unsigned int)constraints[k]; if (conNde > 0) p->constraints = 2; else p->constraints = 1; } else p->constraints = 0; } } /* now pass up tree and count changes */ consistentNode = 0; for (i=tSize-1; i>=0; i--) { p = tempDP[i]; if (p->left != NULL && p->right != NULL && p->anc != NULL) { conLft = p->constraints; conRht = p->anc->constraints; conNde = conLft & conRht; if (conNde > 0) p->constraints = conNde; } if (p->anc != NULL) { if (p->anc->anc == NULL) { if (p->constraints != p->anc->constraints && treeModel == UNROOTED) consistentNode++; } else { if (p->constraints != p->anc->constraints) consistentNode++; } } } if (consistentNode > 1) { printf ("\n ERROR: User tree is inconsistent with the specied constraints\n"); free (availTips); free (availInts); free (tempDP); free (potentialPlaces); free (tempNodes); free (localConstraints); free (localCalibrations); return (ERROR); } } } /* if calibrations are enforced, check that the user tree is consistent with the constraints */ if (enforceCalibrations == YES) { for (j=0; jleft == NULL && p->right == NULL && p->anc != NULL) { conLft = (unsigned int)pow(2.0, (double)j); nId = 0; for (k=0; kindex) break; nId++; } } conNde = conLft & (unsigned int)calibrations[k]; if (conNde > 0) p->calibrations = 2; else p->calibrations = 1; } else if (p->left != NULL && p->right != NULL && p->anc != NULL) { conLft = p->left->calibrations; conRht = p->right->calibrations; conNde = conLft & conRht; if (conNde == 0) p->calibrations = conLft | conRht; else p->calibrations = conNde; } else { if (treeModel == UNROOTED) { conLft = (unsigned int)pow(2.0, (double)j); nId = 0; for (k=0; kindex) break; nId++; } } conNde = conLft & (unsigned int)calibrations[k]; if (conNde > 0) p->calibrations = 2; else p->calibrations = 1; } else p->calibrations = 0; } } /* now pass up tree and count changes */ consistentNode = 0; for (i=tSize-1; i>=0; i--) { p = tempDP[i]; if (p->left != NULL && p->right != NULL && p->anc != NULL) { conLft = p->calibrations; conRht = p->anc->calibrations; conNde = conLft & conRht; if (conNde > 0) p->calibrations = conNde; } if (p->anc != NULL) { if (p->anc->anc == NULL) { if (p->calibrations != p->anc->calibrations && treeModel == UNROOTED) consistentNode++; } else { if (p->calibrations != p->anc->calibrations) consistentNode++; } } } if (consistentNode > 1) { printf ("\n ERROR: User tree is inconsistent with the specied calibrations\n"); free (availTips); free (availInts); free (tempDP); free (potentialPlaces); free (tempNodes); free (localConstraints); free (localCalibrations); return (ERROR); } } } /* relabel nodes */ i = 0; GetTempDownPassSeq (tempRoot, &i, tempDP); if (treeModel == ROOTED) nUserNodes = 2*numTaxa; else nUserNodes = 2*numTaxa-2; for (i=0; ileft == NULL && p->right == NULL && p->anc != NULL) { k = 0; for (j=0; jindex; j++) { if (excludedTaxa[j] == NO) k++; } p->index = k; } else if (p->left != NULL && p->right == NULL && p->anc == NULL) { if (treeModel == UNROOTED) { k = 0; for (j=0; jindex; j++) { if (excludedTaxa[j] == NO) k++; } p->index = k; } } } i = numTaxa; if (treeModel == UNROOTED) FinishTree (tempRoot, &i, NO); else FinishTree (tempRoot, &i, YES); /* copy tree into nodes */ for (i=0; iindex; a = &nodes[n*2*tSize+nId]; a->index = nId; a->memoryIndex = nId; a->length = p->length; if (p->left != NULL) { nLftId = p->left->index; b = &nodes[n*2*tSize+nLftId]; a->left = b; } else a->left = NULL; if (p->right != NULL) { nRhtId = p->right->index; c = &nodes[n*2*tSize+nRhtId]; a->right = c; } else a->right = NULL; if (p->anc != NULL) { nAncId = p->anc->index; d = &nodes[n*2*tSize+nAncId]; a->anc = d; } else a->anc = NULL; if (a->left == NULL && a->right == NULL) strcpy (a->label, p->label); if (treeModel == UNROOTED && a->left != NULL && a->right == NULL && a->anc == NULL) strcpy (a->label, p->label); } nId = tempRoot->index; root[n*2+0] = &nodes[n*2*tSize+nId]; # if defined (DEBUG_START_TREE) printf ("final tree for chain %d (copied version)\n",n); if (treeModel == ROOTED) ShowNodes (root[n*2+0], 2, YES); else ShowNodes (root[n*2+0], 2, NO); //ShowStartTree (tempRoot, nTips, YES); # endif } } # if defined (DEBUG_START_TREE) printf ("tidying up trees\n"); # endif /* tidy up trees, assigning constraints, calibrations, and branch lengths */ printf (" Setting branch lengths\n"); for (n=0; nconstraints = 0; p->isConstrained = NO; p->constraintNum = 0; } for (i=0; iconstraints = 0; } conNde = (unsigned int)pow(2.0, (double)i); for (j=0; jleft == NULL && p->right == NULL && p->anc != NULL) { nId = 0; for (k=0; kindex) break; nId++; } } conLft = conNde & (unsigned int)constraints[k]; if (conNde == conLft) p->constraints = conNde; else p->constraints = 0; } else if (p->left != NULL && p->right == NULL && p->anc == NULL && treeModel == UNROOTED) { nId = 0; for (k=0; kindex) break; nId++; } } conLft = conNde & (unsigned int)constraints[k]; if (conNde == conLft) p->constraints = conNde; else p->constraints = 0; } } /* pass down */ for (j=0; jleft != NULL && p->right != NULL && p->anc != NULL) { conLft = p->left->constraints; conRht = p->right->constraints; conNum1 = conLft & conRht; if (conNum1 == conNde) p->constraints = conNde; } } /* pass up */ for (j=tSize-1; j>=0; j--) { p = tempDP[j]; if (p->left != NULL && p->right != NULL && p->anc != NULL) { conAnc = p->anc->constraints; conLft = p->left->constraints; conRht = p->right->constraints; conNum1 = conAnc & conLft; conNum2 = conAnc & conRht; if (conNum1 == conNde || conNum2 == conNde) p->constraints = conNde; } } /* assign constraints */ for (j=0; janc != NULL) { if (p->constraints == conNde && p->anc->constraints == 0) { p->isConstrained = YES; p->constraintNum = i+1; k = 0; while (constraintLabels[p->constraintNum-1][k] != '|' && k < 99) { p->constraintName[k] = constraintLabels[p->constraintNum-1][k]; k++; } p->constraintName[k] = '\0'; } else if (p->anc->constraints == conNde && p->constraints == 0) { p->anc->isConstrained = YES; p->anc->constraintNum = i+1; k = 0; while (constraintLabels[p->anc->constraintNum-1][k] != '|' && k < 99) { p->anc->constraintName[k] = constraintLabels[p->anc->constraintNum-1][k]; k++; } p->anc->constraintName[k] = '\0'; } } else { if (p->constraints == conNde && p->left->constraints == 0 && treeModel == UNROOTED) { p->isConstrained = YES; p->constraintNum = i+1; k = 0; while (constraintLabels[p->constraintNum-1][k] != '|' && k < 99) { p->constraintName[k] = constraintLabels[p->constraintNum-1][k]; k++; } p->constraintName[k] = '\0'; } } } } # if 0 for (j=0; jisConstrained == YES) printf ("%2d %4d -- %d (%s)\n", conNde, p->index, p->constraintNum, p->constraintName); else printf ("%2d %4d --\n", conNde, p->index); } # endif } /* set calibrations */ if (enforceCalibrations == YES) { for (j=0; jcalibrations = 0; p->isCalibrated = NO; p->calibrationNum = 0; p->calTime[0] = p->calTime[1] = 0.0; } for (i=0; icalibrations = 0; } conNde = (unsigned int)pow(2.0, (double)i); for (j=0; jleft == NULL && p->right == NULL && p->anc != NULL) { nId = 0; for (k=0; kindex) break; nId++; } } conLft = conNde & (unsigned int)calibrations[k]; if (conNde == conLft) p->calibrations = conNde; else p->calibrations = 0; } else if (p->left != NULL && p->right == NULL && p->anc == NULL && treeModel == UNROOTED) { nId = 0; for (k=0; kindex) break; nId++; } } conLft = conNde & (unsigned int)calibrations[k]; if (conNde == conLft) p->calibrations = conNde; else p->calibrations = 0; } } /* pass down */ for (j=0; jleft != NULL && p->right != NULL && p->anc != NULL) { conLft = p->left->calibrations; conRht = p->right->calibrations; conNum1 = conLft & conRht; if (conNum1 == conNde) p->calibrations = conNde; } } /* pass up */ for (j=tSize-1; j>=0; j--) { p = tempDP[j]; if (p->left != NULL && p->right != NULL && p->anc != NULL) { conAnc = p->anc->calibrations; conLft = p->left->calibrations; conRht = p->right->calibrations; conNum1 = conAnc & conLft; conNum2 = conAnc & conRht; if (conNum1 == conNde || conNum2 == conNde) p->calibrations = conNde; } } /* assign calibrations */ for (j=0; janc != NULL) { if (p->calibrations == conNde && p->anc->calibrations == 0) { p->isCalibrated = YES; p->calibrationNum = i+1; k = 0; while (calibrationLabels[p->calibrationNum-1][k] != '|' && k < 99) { p->calibrationName[k] = calibrationLabels[p->calibrationNum-1][k]; k++; } p->calibrationName[k] = '\0'; p->calTime[0] = calibrationTimes[p->calibrationNum-1][0]; p->calTime[1] = calibrationTimes[p->calibrationNum-1][1]; } else if (p->anc->calibrations == conNde && p->calibrations == 0) { p->anc->isCalibrated = YES; p->anc->calibrationNum = i+1; k = 0; while (calibrationLabels[p->anc->calibrationNum-1][k] != '|' && k < 99) { p->anc->calibrationName[k] = calibrationLabels[p->anc->calibrationNum-1][k]; k++; } p->anc->calibrationName[k] = '\0'; p->anc->calTime[0] = calibrationTimes[p->calibrationNum-1][0]; p->anc->calTime[1] = calibrationTimes[p->calibrationNum-1][1]; } } else { if (p->calibrations == conNde && p->left->calibrations == 0 && treeModel == UNROOTED) { p->isCalibrated = YES; p->calibrationNum = i+1; k = 0; while (calibrationLabels[p->calibrationNum-1][k] != '|' && k < 99) { p->calibrationName[k] = calibrationLabels[p->calibrationNum-1][k]; k++; } p->calibrationName[k] = '\0'; p->calTime[0] = calibrationTimes[p->calibrationNum-1][0]; p->calTime[1] = calibrationTimes[p->calibrationNum-1][1]; } } } } # if 0 for (j=0; jisCalibrated == YES) printf ("%2d %4d -- %d (%s) (%lf %lf)\n", conNde, p->index, p->calibrationNum, p->calibrationName, p->calTime[0], p->calTime[1]); else printf ("%2d %4d --\n", conNde, p->index); } # endif } /* set branch lengths */ /* get parsimony tree length */ treeLength = 0.0; sum = 0.0; for (i=0; ileft == NULL && p->right == NULL && p->anc != NULL) { p->farrisSet = matrix[pos(p->index,i,numChars)]; } else if (p->left != NULL && p->right != NULL && p->anc != NULL) { conLft = p->left->farrisSet; conRht = p->right->farrisSet; conNde = conLft & conRht; if (conNde == 0) { conNde = conLft | conRht; tempLength++; } p->farrisSet = conNde; } else { if (treeModel == UNROOTED) { p->farrisSet = matrix[pos(p->index,i,numChars)]; conLft = p->left->farrisSet; conRht = p->farrisSet; conNde = conLft & conRht; if (conNde == 0) { tempLength++; } } } } sum += (double)numSitesOfPat[i]; treeLength += tempLength * numSitesOfPat[i]; } if (treeLength <= 0.0) treeLength = 0.01; else treeLength /= sum; //printf ("tree length = %lf\n", treeLength); if (treeModel == UNROOTED) { if (!strcmp(startingTreeModel, "random") || (!strcmp(startingTreeModel, "user") && userBrlensDef == NO)) { sum = 0.0; for (j=0; janc != NULL) { p->length = RandomNumber (seed); sum += p->length; } } for (j=0; janc != NULL) p->length /= treeLength; } } } else { if (!strcmp(clockModel, "relaxed") || !strcmp(clockModel, "strict")) { if (enforceCalibrations == YES) { /* get node times under the clock constraint with calibrations*/ for (j=0; jleft == NULL && p->right == NULL && p->anc != NULL) { if (p->isCalibrated == YES) { p->nodeTime = p->calTime[0]; } else p->nodeTime = 0.0; } else if (p->left != NULL && p->right != NULL && p->anc != NULL) { oldestAbove = p->left->nodeTime; if (p->right->nodeTime > oldestAbove) oldestAbove = p->right->nodeTime; if (p->isCalibrated == YES) { if (oldestAbove > p->calTime[0] + p->calTime[1]) { printf ("\n ERROR: Inconsistent times for calibrations\n"); free (availTips); free (availInts); free (tempDP); free (potentialPlaces); free (tempNodes); free (localConstraints); free (localCalibrations); return (ERROR); } else if (oldestAbove > p->calTime[0] && oldestAbove < p->calTime[0] + p->calTime[1]) { p->nodeTime = oldestAbove + 0.0001; } else { p->nodeTime = p->calTime[0]; } } else { p->nodeTime = oldestAbove + 0.0001; } } } for (i=0; i<10; i++) { for (j=0; janc != NULL) { if (p->isCalibrated == NO) { if (p->left == NULL && p->right == NULL && p->anc != NULL) { oldestAbove = 0.0; } else { oldestAbove = p->left->nodeTime; if (p->right->nodeTime > oldestAbove) oldestAbove = p->right->nodeTime; } if (p->anc->anc != NULL) oldestBelow = p->anc->nodeTime; else oldestBelow = 2 * p->nodeTime; if (p->left != NULL && p->right != NULL) p->nodeTime = oldestAbove + (oldestBelow - oldestAbove) * RandomNumber(seed); } } } } if (GetDistances (numTaxa, numChars) == ERROR) { printf ("\n ERROR: Could not calculate distances\n"); free (availTips); free (availInts); free (tempDP); free (potentialPlaces); free (tempNodes); free (localConstraints); free (localCalibrations); return (ERROR); } else allocatedMemory[ALLOC_DISTANCES] = YES; sum = 0.0; for (i=0; i sum) sum = distances[pos(i,j,numTaxa)]; free (distances); allocatedMemory[ALLOC_DISTANCES] = NO; //treeHeight[n*2+0] = sum * 0.5; treeHeight[n*2+0] = 0.0005; /* TEMP */ for (j=0; janc != NULL) { if (p->anc->anc != NULL) { p->length = treeHeight[n*2+0] * (p->anc->nodeTime - p->nodeTime); if (p->length < BRLEN_EPSILON) p->length = BRLEN_EPSILON; } else { p->length = 0.0; } } else { p->length = 0.0; } } } else { /* get node times under the clock constraint without calibrations*/ for (j=0; jleft == NULL && p->right == NULL && p->anc != NULL) { p->nodeTime = 0.0; } else if (p->left != NULL && p->right != NULL && p->anc != NULL) { oldestAbove = p->left->nodeTime; if (p->right->nodeTime > oldestAbove) oldestAbove = p->right->nodeTime; p->nodeTime = oldestAbove + 0.0001; } } sum = root[n*2+0]->left->nodeTime; for (j=0; janc != NULL) p->nodeTime /= sum; } if (GetDistances (numTaxa, numChars) == ERROR) { printf ("\n ERROR: Could not calculate distances\n"); free (availTips); free (availInts); free (tempDP); free (potentialPlaces); free (tempNodes); free (localConstraints); free (localCalibrations); return (ERROR); } else allocatedMemory[ALLOC_DISTANCES] = YES; sum = 0.0; for (i=0; i sum) sum = distances[pos(i,j,numTaxa)]; free (distances); allocatedMemory[ALLOC_DISTANCES] = NO; sum *= 0.5; for (j=0; janc != NULL) { if (p->anc->anc != NULL) p->length = sum * (p->anc->nodeTime - p->nodeTime); else p->length = 0.0; } else p->length = 0.0; } } } else { if (!strcmp(startingTreeModel, "random") || (!strcmp(startingTreeModel, "user") && userBrlensDef == NO)) { sum = 0.0; for (j=0; janc != NULL) { if (p->anc->anc != NULL) { p->length = RandomNumber (seed); sum += p->length; } } } for (j=0; janc != NULL) if (p->anc->anc != NULL) p->length /= treeLength; } } } } # if 0 if (treeModel == ROOTED) { printf ("nodes for rooted tree:\n"); ShowNodes (root[n*2+0], 2, YES); //ShowStartTree (root[n*2+0], numTaxa, YES); } else { printf ("nodes for unrooted tree:\n"); ShowNodes (root[n*2+0], 2, NO); //ShowStartTree (root[n*2+0], numTaxa, NO); } # endif } if (showStartTree == YES) { for (n=0; n 1) { for (i=0; iindex] = NO; if (p->anc != NULL) { if ((p->anc->anc != NULL || (p->anc->anc == NULL && treeModel == UNROOTED)) && p->upDateTi == YES) { p->upDateTi = NO; updateTiFlag[p->index] = YES; ptr = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->index)*nodeTiSize); for (m=index=0; mlength, theRate, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, lnStates, probs, p->length, theRate) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; ianc != NULL) { if ((p->anc->anc != NULL || (p->anc->anc == NULL && treeModel == UNROOTED)) && p->upDateTi == YES) { ptr = transitionProbs + (index1 + (p->index)*nodeTiSize); if (isComplex == NO) CalcPij (c_ijk, lnStates, eigenValues, p->length, 1.0, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, lnStates, probs, p->length, 1.0) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } index = 0; for (i=0; ianc != NULL) { if ((p->anc->anc != NULL || (p->anc->anc == NULL && treeModel == UNROOTED)) && p->upDateTi == YES) { ptr = transitionProbs + (index1 + (p->index)*nodeTiSize + lnStatesSquared); if (isComplex == NO) CalcPij (c_ijk, lnStates, eigenValues, p->length, 1.0, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, lnStates, probs, p->length, 1.0) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } index = 0; for (i=0; ianc != NULL) { if ((p->anc->anc != NULL || (p->anc->anc == NULL && treeModel == UNROOTED)) && p->upDateTi == YES) { ptr = transitionProbs + (index1 + (p->index)*nodeTiSize + 2*lnStatesSquared); if (isComplex == NO) CalcPij (c_ijk, lnStates, eigenValues, p->length, 1.0, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, lnStates, probs, p->length, 1.0) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } index = 0; for (i=0; iindex] = NO; if (p->anc != NULL) { if ((p->anc->anc != NULL || (p->anc->anc == NULL && treeModel == UNROOTED)) && p->upDateTi == YES) { p->upDateTi = NO; updateTiFlag[p->index] = YES; } } } /* free memory */ free (bs); free_psdmatrix (probs); free_psdmatrix (q); free (eigenValues); free (c_ijk); free_psdmatrix (eigvecs); free_psdmatrix (inverseEigvecs); free_pscmatrix (Ceigvecs); free_pscmatrix (CinverseEigvecs); return (NO_ERROR); error_exit: return (ERROR); } int CalcTransCovarion (int whichState, int whichChain, int numRateCats) { register int i, j, k, m, b, index; int n, lnStates, lnStatesSquared, lnStatesCube, nRates, lnPartitions, lnumRateCats, isComplex, allNodesPointer, allNodesStop, nForOneState, index1, index2; double **probs, *catFreq, *catRate, *partRate, **q, *eigenValues, *eigvalsImag, **eigvecs, **inverseEigvecs, *c_ijk, correlation, **markovTi, *bs, *ptr, s01, s10, prob0, prob1; complex **Ceigvecs, **CinverseEigvecs; TreeNode *p; allNodesPointer = whichChain*2*numNodes + whichState*numNodes; allNodesStop = allNodesPointer + numNodes; /* twice nStates because matrix is doubled */ lnStates = 2 * nStates; lnStatesSquared = lnStates * lnStates; lnStatesCube = lnStates * lnStatesSquared; /* load base frequencies */ index = whichChain*2*lnStates + whichState*lnStates; index1 = whichChain*4 + whichState*2; index2 = whichChain*2 + whichState; bs = (double *)malloc((size_t) (lnStates * sizeof(double))); if (!bs) { printf ("\n ERROR: Problem allocating bs.\n"); goto error_exit; } if (!strcmp(covarionModelType, "ts98")) { k = 0; for (j=0; j<2; j++) { for (i=0; i 1) { for (i=0; ianc != NULL) { if ((p->anc->anc != NULL || (p->anc->anc == NULL && treeModel == UNROOTED)) && p->upDateTi == YES) { ptr = transitionProbs + (index1 + (p->index)*nodeTiSize + b*lnStatesSquared); if (isComplex == NO) CalcPij (c_ijk, lnStates, eigenValues, p->length, 1.0, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, lnStates, probs, p->length, 1.0) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } index = 0; for (i=0; iindex] = NO; if (p->anc != NULL) { if ((p->anc->anc != NULL || (p->anc->anc == NULL && treeModel == UNROOTED)) && p->upDateTi == YES) { p->upDateTi = NO; updateTiFlag[p->index] = YES; } } } /* free memory */ free (bs); free (catFreq); free_psdmatrix (probs); free_psdmatrix (q); free (eigenValues); free (c_ijk); free_psdmatrix (eigvecs); free_psdmatrix (inverseEigvecs); free_pscmatrix (Ceigvecs); free_pscmatrix (CinverseEigvecs); if (!strcmp(ratesModel, "adgamma") || !strcmp(ratesModel, "ssadgamma")) free_psdmatrix(markovTi); return (NO_ERROR); error_exit: return (ERROR); } int CalcTransDNA (int whichState, int whichChain, int numRateCats) { register int i, j, k, m, index; int n, lnStates, lnStatesCubed, nRates, lnPartitions, lnumRateCats, isComplex, allNodesPointer, allNodesStop, nForOneState; double **probs, *catFreq, *catRate, *partRate, lkappa, **q, *eigenValues, *eigvalsImag, **eigvecs, **inverseEigvecs, *c_ijk, correlation, **markovTi, theRate, bs[4], *ptr; complex **Ceigvecs, **CinverseEigvecs; TreeNode *p; allNodesPointer = whichChain*2*numNodes + whichState*numNodes; allNodesStop = allNodesPointer + numNodes; /* standard 4 X 4 model of DNA substitution ***************************************************************************/ lnStates = 4; lnStatesCubed = 64; /* base frequencies */ index = whichChain*2*nStates + whichState*nStates; bs[A] = baseFreq[index + A]; bs[C] = baseFreq[index + C]; bs[G] = baseFreq[index + G]; bs[T] = baseFreq[index + T]; /* allocate memory for transition probabilities along a single branch */ probs = psdmatrix (lnStates); /* find kappa if nst == 1 or nst == 2 */ if (nst == 1) lkappa = 1.0; else if (nst == 2) lkappa = kappa[whichChain*2 + whichState]; /* get eigenvalues and eigenvectors if nst=6 or nst=12 */ if (nst == 6 || nst == 12) { q = psdmatrix (lnStates); eigenValues = (double *)malloc((size_t) (2 * lnStates * sizeof(double))); if (!eigenValues) { printf ("\n ERROR: Problem allocating eigenValues and eigvalsImag.\n"); goto error_exit; } eigvalsImag = eigenValues + lnStates; eigvecs = psdmatrix (lnStates); inverseEigvecs = psdmatrix (lnStates); Ceigvecs = pscmatrix (lnStates); CinverseEigvecs = pscmatrix (lnStates); if (SetQMatrix (q, whichState, whichChain) == ERROR) goto error_exit; isComplex = GetEigens (lnStates, q, eigenValues, eigvalsImag, eigvecs, inverseEigvecs, Ceigvecs, CinverseEigvecs); if (isComplex == NO) { c_ijk = (double *)malloc((size_t) (lnStatesCubed * sizeof(double))); if (!c_ijk) { printf ("\n ERROR: Problem allocating c_ijk.\n"); goto error_exit; } CalcCijk (c_ijk, lnStates, eigvecs, inverseEigvecs); } } /* how many rates are there? */ if (!strcmp(ratesModel, "sitespec") || !strcmp(ratesModel, "ssgamma") || !strcmp(ratesModel, "ssadgamma")) lnPartitions = nPartitions; else lnPartitions = 1; if (!strcmp(ratesModel, "equal") || !strcmp(ratesModel, "sitespec")) lnumRateCats = 1; else lnumRateCats = numRateCats; nRates = lnPartitions * lnumRateCats; /* allocate memory for rate and rate category frequencies */ catFreq = (double *)malloc((size_t) ((2 * lnumRateCats + lnPartitions) * sizeof(double))); if (!catFreq) { printf ("\n ERROR: Problem allocating space for rate multipliers and rate category freqs.\n"); goto error_exit; } catRate = catFreq + lnumRateCats; partRate = catRate + lnumRateCats; /* fill in rate categories with frequencies and rates by dividing the */ if (!strcmp(ratesModel,"gamma") || !strcmp(ratesModel, "ssgamma")) { DiscreteGamma (catFreq, catRate, alpha[whichChain*2 + whichState], alpha[whichChain*2 + whichState], lnumRateCats, 0); } else if (!strcmp(ratesModel, "adgamma") || !strcmp(ratesModel, "ssadgamma")) { markovTi = psdmatrix (lnumRateCats); AutodGamma (markovTi, catFreq, catRate, &correlation, alpha[whichChain*2 + whichState], rateCorrelation[whichChain*2 + whichState], lnumRateCats); } else if (!strcmp(ratesModel, "invgamma")) { DiscreteGamma (catFreq, catRate, alpha[whichChain*2 + whichState], alpha[whichChain*2 + whichState], lnumRateCats-1, 0); catRate[lnumRateCats-1] = 0.0; catFreq[lnumRateCats-1] = invP[whichChain*2 + whichState]; for (i=0; i 1) { for (i=0; iindex] = NO; if (p->anc != NULL) { if ((p->anc->anc != NULL || (p->anc->anc == NULL && treeModel == UNROOTED)) && p->upDateTi == YES) { //printf (" updating %d\n", p->index); p->upDateTi = NO; updateTiFlag[p->index] = YES; ptr = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->index)*nodeTiSize); if (nst == 1 || nst == 2) { for (m=index=0; mlength, lkappa, theRate, bs[A], bs[C], bs[G], bs[T]); for (i=0; ilength, theRate, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, lnStates, probs, p->length, theRate) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; i 0) foundLft = YES; else foundLft = NO; conNde = rhtPart & (unsigned int)pow(2.0, (double)y); if (conNde > 0) foundRht = YES; else foundRht = NO; if (foundLft == YES && foundRht == YES) nBothOverlap++; if (foundLft == YES && foundRht == NO) nRhtOverlap++; else if (foundLft == NO && foundRht == YES) nLftOverlap++; } } //printf (" nlftover = %d nrhtover = %d\n", nLftOverlap, nRhtOverlap); if (nBothOverlap > 0 && nLftOverlap > 0 && nRhtOverlap > 0) { consAreConsistent = NO; return (consAreConsistent); } } } } else if (enforceConstraints == YES && enforceCalibrations == NO) { for (i=0; i 0) foundLft = YES; else foundLft = NO; conNde = rhtPart & (unsigned int)pow(2.0, (double)y); if (conNde > 0) foundRht = YES; else foundRht = NO; if (foundLft == YES && foundRht == YES) nBothOverlap++; if (foundLft == YES && foundRht == NO) nRhtOverlap++; else if (foundLft == NO && foundRht == YES) nLftOverlap++; } } //printf (" nlftover = %d nrhtover = %d\n", nLftOverlap, nRhtOverlap); if (nBothOverlap > 0 && nLftOverlap > 0 && nRhtOverlap > 0) { consAreConsistent = NO; return (consAreConsistent); } } } } else if (enforceConstraints == NO && enforceCalibrations == YES) { for (i=0; i 0) foundLft = YES; else foundLft = NO; conNde = rhtPart & (unsigned int)pow(2.0, (double)y); if (conNde > 0) foundRht = YES; else foundRht = NO; if (foundLft == YES && foundRht == YES) nBothOverlap++; if (foundLft == YES && foundRht == NO) nRhtOverlap++; else if (foundLft == NO && foundRht == YES) nLftOverlap++; } } //printf (" nlftover = %d nrhtover = %d\n", nLftOverlap, nRhtOverlap); if (nBothOverlap > 0 && nLftOverlap > 0 && nRhtOverlap > 0) { consAreConsistent = NO; return (consAreConsistent); } } } } return (consAreConsistent); } int ComplexChangeMatrix (double *eigenValues, double *eigvalsImag, complex **Ceigvecs, complex **CinverseEigvecs, int n, double **p, double t, double r) { int i, j, k, rc; complex **Cwork; rc = NO_ERROR; Cwork = pscmatrix(n); for(i=0; i 0.1) { printf ("i = %lf\n", Cwork[i][j].im); rc = ERROR; } } } free_pscmatrix (Cwork); return (rc); } int ComplexDerivativesMatrix (double *eigenValues, double *eigvalsImag, complex **Ceigvecs, complex **CinverseEigvecs, int n, double **f, double **s, double t, double r) { int i, j, k, rc; complex ceval, **Cwork1, **Cwork2, rate; rc = NO_ERROR; rate.re = r; rate.im = 0.0; Cwork1 = pscmatrix(n); Cwork2 = pscmatrix(n); for(i=0; i 0.000000000001 || fabs(Cwork2[i][j].im) > 0.000000000001) { rc = ERROR; } } } free_pscmatrix (Cwork1); free_pscmatrix (Cwork2); return (rc); } int CompressMatrix (int *numTaxa, int *numChars) { int i, j, k, *numOfThisPat, isSame, nPat, nt, siteNum, taxNum, *tempMatrix, *tempNumSitePats, *tempPartId, nOnes, nTwos; #if defined (MORPH) int index; #endif nExcluded = 0; for (i=0; i 0) { patternId[i] = siteNum; for (j=i+1; j<(nChar/3); j++) { if (numOfThisPat[j] > 0) { isSame = YES; for (k=0; k 0) nPat++; } nt = 0; for (j=0; j 0) { numSitesOfPat[siteNum] = numOfThisPat[i]; taxNum = 0; for (j=0; j 0) { patternId[i] = siteNum; for (j=i+1; j 0) { isSame = YES; for (k=0; k 0) nPat++; } nt = 0; for (j=0; j 0) { patternId[i] = siteNum; taxNum = 0; for (j=0; j= nPartitions) { printf ("\n ERROR: Invalid partition ID.\n"); free (numOfThisPat); FreeMemory (); return (ERROR); } siteNum++; } } free (numOfThisPat); } else { /* compress for other types of rate models */ numOfThisPat = (int *)malloc((size_t) (nChar * sizeof(int))); if (!numOfThisPat) { printf ("\n ERROR: Problem allocating numOfThisPat.\n"); FreeMemory (); return (ERROR); } for (i=0; i 0) { patternId[i] = siteNum; for (j=i+1; j 0) { isSame = YES; for (k=0; k 0) nPat++; } nt = 0; for (j=0; j 0) { taxNum = 0; for (j=0; j 0) { patternId[i] = siteNum; for (j=i+1; j 0) { isSame = YES; for (k=0; k 0) nPat++; } nt = 0; for (j=0; j 0) { taxNum = 0; for (j=0; j 0) { patternId[i] = siteNum; for (j=i+1; j 0) { isSame = YES; for (k=0; k 0) nPat++; } nt = 0; for (j=0; j 0) { taxNum = 0; for (j=0; j= index || nTwos >= index) { printf ("\n Warning: Not expecting this character pattern under the chosen coding (%d).\n", i-numDummyChars+1); printf ("\n Continue with chain? (yes/no): "); if (YesNo() == YES) { printf (" Continuing with chain, even if it is not a good idea... \n\n"); break; } else { FreeMemory (); free (numOfThisPat); return (ERROR); } } } # else /* check to see if the dummy characters are present elsewhere */ for (i=numDummyChars; i 0) { patternId[i] = siteNum; for (j=i+1; j 0) { isSame = YES; for (k=0; k 0) nPat++; } nt = 0; for (j=0; j 0) { taxNum = 0; for (j=0; j 0) { patternId[i] = siteNum; for (j=i+1; j 0) { isSame = YES; for (k=0; k 0) nPat++; } nt = 0; for (j=0; j 0) { taxNum = 0; for (j=0; j 0) { patternId[i] = siteNum; for (j=i+1; j 0) { isSame = YES; for (k=0; k 0) nPat++; } nt = 0; for (j=0; j 0) { taxNum = 0; for (j=0; janc != NULL) { pA = p->anc; iA = pA->memoryIndex; } if (p->left != NULL) { pL = p->left; iL = pL->memoryIndex; } if (p->right != NULL) { pR = p->right; iR = pR->memoryIndex; } /* to pointers should be offset sizeOfTree from from pointers */ q = nodes + (whichChain*2*numNodes + to * numNodes + i); if (p->anc != NULL) { qA = nodes + (whichChain*2*numNodes + to * numNodes + iA); q->anc = qA; } else { q->anc = NULL; } if (p->left != NULL) { qL = nodes + (whichChain*2*numNodes + to * numNodes + iL); q->left = qL; } else { q->left = NULL; } if (p->right != NULL) { qR = nodes + (whichChain*2*numNodes + to * numNodes + iR); q->right = qR; } else { q->right = NULL; } q->memoryIndex = p->memoryIndex; q->index = p->index; q->upDateCl = p->upDateCl; q->marked = p->marked; q->x = p->x; q->y = p->y; q->constraints = p->constraints; q->calibrations = p->calibrations; q->scaler = p->scaler; q->scalerNode = p->scalerNode; q->flag = p->flag; q->isCalibrated = p->isCalibrated; q->isConstrained = p->isConstrained; q->constraintNum = p->constraintNum; q->calibrationNum = p->calibrationNum; q->farrisSet = p->farrisSet; q->length = p->length; q->nodeTime = p->nodeTime; q->calTime[0] = p->calTime[0]; q->calTime[1] = p->calTime[1]; q->scalerIndex = p->scalerIndex; # if defined (SMART_TI_PROBS) q->upDateTi = p->upDateTi; # endif strcpy (q->label, p->label); strcpy (q->calibrationName, p->calibrationName); strcpy (q->constraintName, p->constraintName); if (p == r) root[whichChain*2 + to] = q; } for (i=0; imemoryIndex); intNodeDownPassSeq[whichChain*2*numIntNodes + to * numIntNodes + i] = q; } for (i=0; imemoryIndex); allNodesDownPassSeq[whichChain*2*numNodes + to * numNodes + i] = q; } if (allocatedMemory[ALLOC_TREE_HEIGHT] == YES) treeHeight[whichChain*2 + to] = treeHeight[whichChain*2 + from]; if (allocatedMemory[ALLOC_KAPPA] == YES) kappa[whichChain*2 + to] = kappa[whichChain*2 + from]; if (allocatedMemory[ALLOC_OMEGA] == YES) omega[whichChain*2 + to] = omega[whichChain*2 + from]; if (allocatedMemory[ALLOC_PUR] == YES) probPur[whichChain*2 + to] = probPur[whichChain*2 + from]; if (allocatedMemory[ALLOC_NEU] == YES) probNeu[whichChain*2 + to] = probNeu[whichChain*2 + from]; if (allocatedMemory[ALLOC_POS] == YES) probPos[whichChain*2 + to] = probPos[whichChain*2 + from]; if (allocatedMemory[ALLOC_GAMMA_SHAPE] == YES) alpha[whichChain*2 + to] = alpha[whichChain*2 + from]; if (allocatedMemory[ALLOC_INV_P] == YES) invP[whichChain*2 + to] = invP[whichChain*2 + from]; if (allocatedMemory[ALLOC_AUTO_GAMMA] == YES) rateCorrelation[whichChain*2 + to] = rateCorrelation[whichChain*2 + from]; if (allocatedMemory[ALLOC_AUTO_GAMMA2] == YES) { for (i=0; i<2; i++) rateCorrelation2[whichChain*4 + to*2 + i] = rateCorrelation2[whichChain*4 + from*2 + i]; } if (allocatedMemory[ALLOC_LAG] == YES) lag[whichChain*2 + to] = lag[whichChain*2 + from]; if (allocatedMemory[ALLOC_SUBPARAMS] == YES) { for (i=0; ianc != NULL) { if (p->anc->anc != NULL) sum += p->length; else if (treeModel == UNROOTED) sum += p->length; } } return (sum); } int GetDistances (int numTaxa, int numChars) { int i, j, k, x, y; double nSame, nDiff, d, p; distances = (double *)malloc(sizeof(double) * numTaxa * numTaxa); if (!distances) { printf ("\n ERROR: Could not allocate distances\n"); FreeMemory (); return (ERROR); } else allocatedMemory[ALLOC_DISTANCES] = YES; x = 0; for (i=0; i= 0.74999) d = 9.999999999; else d = -0.75 * log (1.0 - (4.0/3.0) * p); distances[pos(x,y,numTaxa)] = d; } y++; } } x++; } } for (i=0; ileft, whichTree, whichChain, numTaxa, i, j); GetDownPassSeq (p->right, whichTree, whichChain, numTaxa, i, j); if (p->left != NULL && p->right != NULL && p->anc != NULL) { intNodeDownPassSeq[whichChain*2*numIntNodes + whichTree*numIntNodes + (*i)++] = p; allNodesDownPassSeq[whichChain*2*numNodes + whichTree*numNodes + (*j)++] = p; } else if (p->left == NULL && p->right == NULL && p->anc != NULL) { allNodesDownPassSeq[whichChain*2*numNodes + whichTree*numNodes + (*j)++] = p; } else if (p->left != NULL && p->right == NULL && p->anc == NULL) { allNodesDownPassSeq[whichChain*2*numNodes + whichTree*numNodes + (*j)++] = p; } } } int GetEigens (int n, double **q, double *eigenValues, double *eigvalsImag, double **eigvecs, double **inverseEigvecs, complex **Ceigvecs, complex **CinverseEigvecs) { int i, j, rc, *iwork, isComplex; double **mwork, *dwork; complex **Cwork, *Ccol; /* allocate memory */ dwork = (double *)malloc((size_t) (n * sizeof(double))); iwork = (int *)malloc((size_t) (n * sizeof(int))); /* calculate eigenvalues and eigenvectors */ isComplex = NO; rc = EigenRealGeneral (n, q, eigenValues, eigvalsImag, eigvecs, iwork, dwork); if (rc != NO_ERROR) { if (rc == RC_COMPLEX_EVAL) { isComplex = YES; } } /* invert U = eigenvectors (InvertMatrix destroys its input matrix, so copy U to temp) */ if (isComplex == NO) { mwork = psdmatrix (n); copy_psdmatrix (eigvecs, mwork, n); InvertMatrix (mwork, n, dwork, iwork, inverseEigvecs); free_psdmatrix (mwork); } else { for(i=0; i 0.0) { for (j=0; j 0 && aaCode <= 20) aa[aaCode-1] = 1; else { for (m=0; m<20; m++) aa[m] = 1; } # if 0 printf ("%2d -- ", aaCode); for (m=0; m<20; m++) printf("%d", aa[m]); printf ("\n"); # endif } void GetPossibleNucs (int nucCode, int nuc[]) { if (nucCode == 1) { nuc[0] = 1; nuc[1] = 0; nuc[2] = 0; nuc[3] = 0; } else if (nucCode == 2) { nuc[0] = 0; nuc[1] = 1; nuc[2] = 0; nuc[3] = 0; } else if (nucCode == 3) { nuc[0] = 1; nuc[1] = 1; nuc[2] = 0; nuc[3] = 0; } else if (nucCode == 4) { nuc[0] = 0; nuc[1] = 0; nuc[2] = 1; nuc[3] = 0; } else if (nucCode == 5) { nuc[0] = 1; nuc[1] = 0; nuc[2] = 1; nuc[3] = 0; } else if (nucCode == 6) { nuc[0] = 0; nuc[1] = 1; nuc[2] = 1; nuc[3] = 0; } else if (nucCode == 7) { nuc[0] = 1; nuc[1] = 1; nuc[2] = 1; nuc[3] = 0; } else if (nucCode == 8) { nuc[0] = 0; nuc[1] = 0; nuc[2] = 0; nuc[3] = 1; } else if (nucCode == 9) { nuc[0] = 1; nuc[1] = 0; nuc[2] = 0; nuc[3] = 1; } else if (nucCode == 10) { nuc[0] = 0; nuc[1] = 1; nuc[2] = 0; nuc[3] = 1; } else if (nucCode == 11) { nuc[0] = 1; nuc[1] = 1; nuc[2] = 0; nuc[3] = 1; } else if (nucCode == 12) { nuc[0] = 0; nuc[1] = 0; nuc[2] = 1; nuc[3] = 1; } else if (nucCode == 13) { nuc[0] = 1; nuc[1] = 0; nuc[2] = 1; nuc[3] = 1; } else if (nucCode == 14) { nuc[0] = 0; nuc[1] = 1; nuc[2] = 1; nuc[3] = 1; } else if (nucCode == 15) { nuc[0] = 1; nuc[1] = 1; nuc[2] = 1; nuc[3] = 1; } } void GetTempDownPassSeq (TreeNode *p, int *i, TreeNode **dp) { if (p != NULL) { GetTempDownPassSeq (p->left, i, dp); GetTempDownPassSeq (p->right, i, dp); dp[(*i)++] = p; } } void HkyChangeMat (double **ch_prob, double time, double k, double r, double piA, double piC, double piG, double piT) { int i, j; double t, u, w, x, y, z, beta, bigPi_j[4], pij, bigPij, pis[4]; /* rescale beta */ pis[0] = piA; pis[1] = piC; pis[2] = piG; pis[3] = piT; beta = 0.5 / ((piA + piG)*(piC + piT) + k*((piA*piG) + (piC*piT))); bigPi_j[0] = piA + piG; bigPi_j[1] = piC + piT; bigPi_j[2] = piA + piG; bigPi_j[3] = piC + piT; t = time * r; for (i=0; i<4; i++) { for (j=0; j<4; j++) { bigPij = bigPi_j[j]; pij = pis[j]; u = 1.0/bigPij - 1.0; w = -beta * (1.0 + bigPij * (k - 1.0)); x = exp(-beta * t); y = exp(w * t); z = (bigPij - pij) / bigPij; if (i == j) ch_prob[i][j] = pij + pij * u * x + z * y; else if ((i == 0 && j == 2) || (i == 2 && j == 0) || (i == 1 && j == 3) || (i == 3 && j == 1)) ch_prob[i][j] = pij + pij * u * x - (pij/bigPij) * y; else ch_prob[i][j] = pij * (1.0 - x); } } # if 0 printf ("Change probabilities (HKY 85, v = %lf):\n", time); for (i=0; i<4; i++) { for (j=0; j<4; j++) { printf ("%lf ", ch_prob[i][j]); } printf ("\n"); } # endif } void HkyFirstMat (double **ch_prob, double time, double k, double r, double piA, double piC, double piG, double piT) { int i, j; double t, u, w, x, y, z, beta, bigPi_j[4], pij, bigPij, pis[4]; pis[0] = piA; pis[1] = piC; pis[2] = piG; pis[3] = piT; beta = 0.5 / ((piA + piG)*(piC + piT) + k*((piA*piG) + (piC*piT))); bigPi_j[0] = piA + piG; bigPi_j[1] = piC + piT; bigPi_j[2] = piA + piG; bigPi_j[3] = piC + piT; t = time * r; for (i=0; i<4; i++) { for (j=0; j<4; j++) { bigPij = bigPi_j[j]; pij = pis[j]; u = 1.0/bigPij - 1.0; w = -beta * (1.0 + bigPij * (k - 1.0)); x = exp(-beta * t); y = exp(w * t); z = (bigPij - pij) / bigPij; if (i == j) ch_prob[i][j] = pij * u * (-beta) * r * x + z * w * r * y; else if ((i == 0 && j == 2) || (i == 2 && j == 0) || (i == 1 && j == 3) || (i == 3 && j == 1)) ch_prob[i][j] = pij * u * (-beta) * r * x - (pij/bigPij) * w * r * y; else ch_prob[i][j] = (beta) * pij * r * x; } } # if defined (SHOWTIPROBS) printf ("Change probabilities (first dv) (HKY 85, time = %lf):\n", time); for (i=0; i<4; i++) { for (j=0; j<4; j++) { printf ("%lf ", ch_prob[i][j]); } printf ("\n"); } # endif } void HkySecondMat (double **ch_prob, double time, double k, double r, double piA, double piC, double piG, double piT) { int i, j; double t, u, w, x, y, z, beta, bigPi_j[4], pij, bigPij, pis[4]; pis[0] = piA; pis[1] = piC; pis[2] = piG; pis[3] = piT; beta = 0.5 / ((piA + piG)*(piC + piT) + k*((piA*piG) + (piC*piT))); bigPi_j[0] = piA + piG; bigPi_j[1] = piC + piT; bigPi_j[2] = piA + piG; bigPi_j[3] = piC + piT; t = time * r; for (i=0; i<4; i++) { for (j=0; j<4; j++) { bigPij = bigPi_j[j]; pij = pis[j]; u = 1.0/bigPij - 1.0; w = -beta * (1.0 + bigPij * (k - 1.0)); x = exp(-beta * t); y = exp(w * t); z = (bigPij - pij) / bigPij; if (i == j) ch_prob[i][j] = pij * u * beta * beta * r * r* x + z * w * w * r * r * y; else if ((i == 0 && j == 2) || (i == 2 && j == 0) || (i == 1 && j == 3) || (i == 3 && j == 1)) ch_prob[i][j] = pij * u * beta * beta * r * r * x - (pij/bigPij) * w * w * r * r * y; else ch_prob[i][j] = - beta * beta * pij * r * r * x; } } # if defined (SHOWTIPROBS) printf ("Change probabilities (first dv) (HKY 85, time = %lf):\n", time); for (i=0; i<4; i++) { for (j=0; j<4; j++) { printf ("%lf ", ch_prob[i][j]); } printf ("\n"); } # endif } double IncompleteBetaFunction (double alpha, double beta, double x) { double bt, gm1, gm2, gm3, temp; if (x < 0.0 || x > 1.0) { printf ("Error in IncompleteBetaFunction.\n"); exit (-1); } if (x == 0.0 || x == 1.0) { bt = 0.0; } else { gm1 = LnGamma (alpha + beta); gm2 = LnGamma (alpha); gm3 = LnGamma (beta); temp = gm1 - gm2 - gm3 + (alpha) * log(x) + (beta) * log(1.0 - x); bt = exp(temp); } if (x < (alpha + 1.0)/(alpha + beta + 2.0)) return (bt * BetaCf(alpha, beta, x) / alpha); else return (1.0 - bt * BetaCf(beta, alpha, 1.0-x) / beta); } int InitializeConditionalLikes (int numTaxa, int numChars, int numRateCats) { int i, b, c, s, s1, s2, s3, k, n, *nuc1, cd1[4], cd2[4], cd3[4], oneMatSize, nNucs, aaId, rsId, foundCodon, nLocalStates; double *cl0, *cl1, uncertObs, uncertUnobs; if ((dataType == DNA || dataType == RNA) && enforceCodonModel == YES) { if (!strcmp(codonModelType, "covny98")) nLocalStates = 3 * nStates; else nLocalStates = nStates; } else { if (useCovarion == YES) nLocalStates = 2 * nStates; else nLocalStates = nStates; } printf (" Initializing conditional likelihoods\n"); oneMatSize = numNodes * numChars * numRateCats * nLocalStates * numBetaCats; nuc1 = (int *)malloc((size_t) (nStates * sizeof(int))); if (!nuc1) { printf ("ERROR: Problem allocating nuc1\n"); return (ERROR); } condLike = (double *)malloc((size_t) (numChains * 2 * oneMatSize * sizeof(double))); if (!condLike) { printf ("\n ERROR: Problem allocating conditional likelihoods.\n"); printf (" Try allocating more memory to the program or\n"); printf (" running the program on a computer with more\n"); printf (" memory.\n"); free (nuc1); FreeMemory (); return (ERROR); } else allocatedMemory[ALLOC_COND_LIKES] = YES; # if defined (SUPER_FAST) isPartAmbig = (int *)malloc((size_t) ((numTaxa + numTaxa * numChars) * sizeof(int))); if (!isPartAmbig) { printf ("ERROR: Problem allocating isPartAmbig and termStates\n"); return (ERROR); } else allocatedMemory[ALLOC_TERM_STATES] = YES; termState = isPartAmbig + numTaxa; # endif for (i=0; i 0 && aaId <= 20) { for (k=0; k 0 && aaId <= 20) { for (k=0; k 1) { if (nNucs == 64) //all states are possible termState[b] = nStates * nLocalStates; else isPartAmbig[i] = YES; } b++; } } } else if (dataType == DNA || dataType == RNA) /* 4 x 4 DNA or RNA model */ { b = 0; for (i=0; i 0 && aaId <= 20) termState[b] = (aaId - 1) * 20; else termState[b] = 20 * 20; b++; } } } if (useCovarion == YES) // nStates is doubled if covarion model is used { for (i=b=0; i 0 && aaId <= 20) { x = 1 << (aaId-1); cl[c] = x; //printf ("%d -> %d\n", aaId, cl[c]); } else { cl[c] = 0; for (s=0; s<20; s++) { x = 1 << s; cl[c] |= x; } //printf ("%d -> %d\n", aaId, cl[c]); } } else if (dataType == RESTRICTION) { rsId = matrix[pos(i,c,numChars)]; if (rsId == 1) { cl[c] = 1; } else if (rsId == 2) { cl[c] = 2; } else { cl[c] = 3; } } else if (dataType == STANDARD) { rsId = matrix[pos(i,c,numChars)]; if (rsId == 1) { cl[c] = 1; } else if (rsId == 2) { cl[c] = 2; } else { cl[c] = 3; } } } } } return (NO_ERROR); } int InitTiMatrix (double m[3][3], double x, double y, double z, double pPurifying, double pNeutral, double pPositive, int model) { if (model == 1) { m[0][1] = (1.0 - x) * pNeutral; m[0][2] = (1.0 - x) * pPositive; m[1][0] = (1.0 - x) * pPurifying; m[1][2] = (1.0 - x) * pPositive; m[2][0] = (1.0 - x) * pPurifying; m[2][1] = (1.0 - x) * pNeutral; m[0][0] = 1.0 - (m[0][1] + m[0][2]); m[1][1] = 1.0 - (m[1][0] + m[1][2]); m[2][2] = 1.0 - (m[2][0] + m[2][1]); } else if (model == 2) { m[0][1] = (1.0 - x) * pNeutral; m[0][2] = (1.0 - y) * pPositive; m[1][0] = (1.0 - x) * pPurifying; m[1][2] = (1.0 - z) * pPositive; m[2][0] = (1.0 - y) * pPurifying; m[2][1] = (1.0 - z) * pNeutral; m[0][0] = 1.0 - (m[0][1] + m[0][2]); m[1][1] = 1.0 - (m[1][0] + m[1][2]); m[2][2] = 1.0 - (m[2][0] + m[2][1]); } else { return (ERROR); } # if 0 { int i, j; printf ("%lf %lf %lf %lf %lf %lf (%d)\n", x, y, z, pPurifying, pNeutral, pPositive, model); for (i=0; i<3; i++) { for (j=0; j<3; j++) { printf ("%lf ", m[i][j]); } printf ("\n"); } } # endif return (NO_ERROR); } int IsKink (TreeNode *p) { int numMarked; if (p->anc == NULL) return (YES); if (p->anc->marked == NO) /* added 4/20/00 */ return (YES); numMarked = 0; if (p->left != NULL) if (p->left->marked == YES) numMarked++; if (p->right != NULL) if (p->right->marked == YES) numMarked++; if (numMarked == 2) return (YES); return (NO); } int IsLeaf (TreeNode *p) { if (p->left == NULL || p->right == NULL || p->anc == NULL) return (YES); return (NO); } int LnBDPrior (int whichState, int whichChain, int numTaxa, double *prob) { int i, j; double sR, eR, sF, rootTime, *nt; TreeNode *p; sR = spRate[whichChain*2 + whichState]; eR = exRate[whichChain*2 + whichState]; sF = samplingFraction; rootTime = root[whichChain*2+whichState]->left->nodeTime; if (enforceCalibrations == NO) { /* get node times */ for (i=0; ileft == NULL && p->right == NULL) p->nodeTime = 0.0; else p->nodeTime += p->left->nodeTime + p->left->length; } for (i=0; ileft == NULL && p->right == NULL) p->nodeTime = 0.0; else p->nodeTime /= rootTime; } } /* allocate memory */ nt = (double *)malloc((size_t) (numTaxa-1) * sizeof(double)); if (!nt) { printf ("\n ERROR: Problem allocating nt\n"); return (ERROR); } /* put node times into vector */ j = 0; for (i=0; ileft != NULL && p->right != NULL && p->anc != NULL) { nt[j] = p->nodeTime; j++; } } # if 0 for (i=0; i 1) { for (i=0; iupDateCl = YES; clUpdateFlag[p->index] = NO; if (p->anc->anc == NULL && treeModel == UNROOTED) { if (p->upDateCl == YES) { //printf ("visiting basal node %d\n", p->index); /* get transition probabilities */ # if defined (SMART_TI_PROBS) pL = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->left->index)*nodeTiSize); pR = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->right->index)*nodeTiSize); pA = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->index)*nodeTiSize); # else for (m=indexL=indexR=indexA=0; mleft->length, theRate, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, N_STATES, probs, p->left->length, theRate) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; iright->length, theRate, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, N_STATES, probs, p->right->length, theRate) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; ilength, theRate, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, N_STATES, probs, p->length, theRate) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; ileft->index)*oneNodeSize]; clR = &condLike[condLikeOffset + (p->right->index)*oneNodeSize]; clA = &condLike[condLikeOffset + (p->anc->index)*oneNodeSize]; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; /* then branch to models */ if (!strcmp(ratesModel, "equal")) { for (c=0; cupDateCl = NO; clUpdateFlag[p->index] = YES; } // done if p->upDateCl == YES for internal root node } // done with internal root node else { if (p->upDateCl == YES) { //printf ("visiting interior node %d\n", p->index); /* get transition probabilities */ # if defined (SMART_TI_PROBS) pL = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->left->index)*nodeTiSize); pR = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->right->index)*nodeTiSize); # else for (m=indexL=indexR=0; mleft->length, theRate, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, N_STATES, probs, p->left->length, theRate) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; iright->length, theRate, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, N_STATES, probs, p->right->length, theRate) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; ileft->index)*oneNodeSize]; clR = &condLike[condLikeOffset + (p->right->index)*oneNodeSize]; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; /* then branch to models */ if (!strcmp(ratesModel, "equal")) { for (c=0; c1.0) printf(""); h++; } } } } else if (!strcmp(ratesModel, "ssgamma") || !strcmp(ratesModel, "ssadgamma")) { for (c=0; cupDateCl = NO; clUpdateFlag[p->index] = YES; } // done with interior node if p->upDateCl == YES } // done with interior node // deal with scaling // first check if we need to refresh scalers and potentially shift scaler nodes // we have to remember scalerIndex because the node may move in the tree if (refreshScalers == YES) { if (n % RESCALE_FREQ == 0) { p->scalerNode = YES; p->scalerIndex = n; } else p->scalerNode = NO; } if (p->scalerNode == YES && clUpdateFlag[p->index] == YES) { scalerUpdateFlag[p->scalerIndex] = YES; scP = &clScaler[scalerOffset + (p->scalerIndex)*numChars]; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; i = j = 0; for (c=0; c scaler) scaler = clP[i]; i++; } } for (k=0; kleft; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; (*lnL) = 0.0; // reset lnL if (!strcmp(ratesModel, "equal") || !strcmp(ratesModel, "sitespec")) { for (c=0; c=0; c--) { cn = c*lnumRateCats; if (patternId[c] >= 0) { pat = patternId[c]; if (c + localLag >= nChar) { max = 0.0; for (k=0; k max) max = biN[cn + k]; } if (max > 0.0) { for (k=0; k max) max = biN[cn + i]; usedBin[c+localLag] = YES; } if (max > 0.0) { for (k=0; kupDateCl = YES; clUpdateFlag[p->index] = NO; if (p->anc->anc == NULL && treeModel == UNROOTED) { if (p->upDateCl == YES) { //printf ("visiting basal node %d\n", p->index); /* get transition probabilities */ # if defined (SMART_TI_PROBS) pL = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->left->index)*nodeTiSize); pR = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->right->index)*nodeTiSize); pA = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->index)*nodeTiSize); # else indexL = indexR = indexA = 0; // calculate transition probabilities for left branch if (isComplex == NO) CalcPij (c_ijk, lnStates, eigenValues, p->left->length, 1.0, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, lnStates, probs, p->left->length, 1.0) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; iright->length, 1.0, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, lnStates, probs, p->right->length, 1.0) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; ilength, 1.0, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, lnStates, probs, p->length, 1.0) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; ileft->length, 1.0, probs); else if (ComplexChangeMatrix (eigenValues2, eigvalsImag2, Ceigvecs2, CinverseEigvecs2, lnStates, probs, p->left->length, 1.0) == ERROR) printf ("Problem calculating transition probabilities for complex eigen values.\n"); for (i=0; iright->length, 1.0, probs); else if (ComplexChangeMatrix (eigenValues2, eigvalsImag2, Ceigvecs2, CinverseEigvecs2, lnStates, probs, p->right->length, 1.0) == ERROR) printf ("Problem calculating transition probabilities for complex eigen values.\n"); for (i=0; ilength, 1.0, probs); else if (ComplexChangeMatrix (eigenValues2, eigvalsImag2, Ceigvecs2, CinverseEigvecs2, lnStates, probs, p->length, 1.0) == ERROR) printf ("Problem calculating transition probabilities for complex eigen values.\n"); for (i=0; ileft->length, 1.0, probs); else if (ComplexChangeMatrix (eigenValues3, eigvalsImag3, Ceigvecs3, CinverseEigvecs3, lnStates, probs, p->left->length, 1.0) == ERROR) printf ("Problem calculating transition probabilities for complex eigen values.\n"); for (i=0; iright->length, 1.0, probs); else if (ComplexChangeMatrix (eigenValues3, eigvalsImag3, Ceigvecs3, CinverseEigvecs3, lnStates, probs, p->right->length, 1.0) == ERROR) printf ("Problem calculating transition probabilities for complex eigen values.\n"); for (i=0; ilength, 1.0, probs); else if (ComplexChangeMatrix (eigenValues3, eigvalsImag3, Ceigvecs3, CinverseEigvecs3, lnStates, probs, p->length, 1.0) == ERROR) printf ("Problem calculating transition probabilities for complex eigen values.\n"); for (i=0; ileft->index)*oneNodeSize]; clR = &condLike[condLikeOffset + (p->right->index)*oneNodeSize]; clA = &condLike[condLikeOffset + (p->anc->index)*oneNodeSize]; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; /* then branch to models */ if (!strcmp(codonModelType, "ny98") || !strcmp(codonModelType, "ac1ny98") || !strcmp(codonModelType, "ac2ny98")) { for (c=0; cupDateCl = NO; clUpdateFlag[p->index] = YES; } // done if p->upDateCl == YES for internal root node } // done with internal root node else { if (p->upDateCl == YES) { //printf ("visiting interior node %d\n", p->index); /* get transition probabilities */ # if defined (SMART_TI_PROBS) pL = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->left->index)*nodeTiSize); pR = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->right->index)*nodeTiSize); # else indexL = indexR = 0; // calculate transition probabilities for left branch if (isComplex == NO) CalcPij (c_ijk, lnStates, eigenValues, p->left->length, 1.0, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, lnStates, probs, p->left->length, 1.0) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; iright->length, 1.0, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, lnStates, probs, p->right->length, 1.0) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; ileft->length, 1.0, probs); else if (ComplexChangeMatrix (eigenValues2, eigvalsImag2, Ceigvecs2, CinverseEigvecs2, lnStates, probs, p->left->length, 1.0) == ERROR) printf ("Problem calculating transition probabilities for complex eigen values.\n"); for (i=0; iright->length, 1.0, probs); else if (ComplexChangeMatrix (eigenValues2, eigvalsImag2, Ceigvecs2, CinverseEigvecs2, lnStates, probs, p->right->length, 1.0) == ERROR) printf ("Problem calculating transition probabilities for complex eigen values.\n"); for (i=0; ileft->length, 1.0, probs); else if (ComplexChangeMatrix (eigenValues3, eigvalsImag3, Ceigvecs3, CinverseEigvecs3, lnStates, probs, p->left->length, 1.0) == ERROR) printf ("Problem calculating transition probabilities for complex eigen values.\n"); for (i=0; iright->length, 1.0, probs); else if (ComplexChangeMatrix (eigenValues3, eigvalsImag3, Ceigvecs3, CinverseEigvecs3, lnStates, probs, p->right->length, 1.0) == ERROR) printf ("Problem calculating transition probabilities for complex eigen values.\n"); for (i=0; ileft->index)*oneNodeSize]; clR = &condLike[condLikeOffset + (p->right->index)*oneNodeSize]; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; /* then branch to models */ if (!strcmp(codonModelType, "ny98") || !strcmp(codonModelType, "ac1ny98") || !strcmp(codonModelType, "ac2ny98")) { for (c=0; cupDateCl = NO; clUpdateFlag[p->index] = YES; } // done with interior node if p->upDateCl == YES } // done with interior node // deal with scaling // first check if we need to refresh scalers and potentially shift scaler nodes // we have to remember scalerIndex because the node may move in the tree if (refreshScalers == YES) { if (n % RESCALE_FREQ == 0) { p->scalerNode = YES; p->scalerIndex = n; } else p->scalerNode = NO; } if (p->scalerNode == YES && clUpdateFlag[p->index] == YES) { scalerUpdateFlag[p->scalerIndex] = YES; scP = &clScaler[scalerOffset + (p->scalerIndex)*numChars]; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; i = j = 0; for (c=0; c scaler) scaler = clP[i]; i++; } } for (k=0; kleft; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; (*lnL) = 0.0; // reset lnL if (!strcmp(codonModelType, "ny98")) { for (c=0; c=0; c--) { cn = c*3; if (patternId[c] >= 0) { pat = patternId[c]; if (isFirst == YES) { max = 0.0; for (k=0; k<3; k++) { biN[cn + k] = omegaPr[pat*3 + k]; if (biN[cn + k] > max) max = biN[cn + k]; } if (max > 0.0) { for (k=0; k<3; k++) biN[cn + k] /= max; lnC += log(max); } else { printf (" ERROR: Scaling factor for ac1ny98 or ac2ny98 model is less than 0\n"); goto error_exit; } isFirst = NO; } else // isFirst == NO { for (i=0; i<3; i++) { temp = max = 0.0; for (j=0; j<3; j++) temp += markovTi[i][j] * biN[(c+1)*3 + j]; biN[cn + i] = omegaPr[pat*3+i] * temp; if (biN[cn + i] > max) max = biN[cn + i]; } if (max > 0.0) { for (k=0; k<3; k++) biN[cn + k] /= max; lnC += log(max); } else { printf (" ERROR: Scaling factor for adgamma model is less than 0\n"); goto error_exit; } } } else { printf (" ERROR: Unidentified pattern\n"); goto error_exit; } } temp = biN[0] * probPur[whichChain*2 + whichState]; temp += biN[1] * probNeu[whichChain*2 + whichState]; temp += biN[2] * probPos[whichChain*2 + whichState]; (*lnL) = lnC + log(temp); } else /* no omega variation or covarion-like model */ { for (c=0; c 1) { for (i=0; iupDateCl = YES; clUpdateFlag[p->index] = NO; if (p->anc->anc == NULL && treeModel == UNROOTED) { if (p->upDateCl == YES) { //printf ("visiting basal node %d\n", p->index); /* get transition probabilities */ # if defined (SMART_TI_PROBS) pL = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->left->index)*nodeTiSize); pR = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->right->index)*nodeTiSize); pA = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->index)*nodeTiSize); # else for (m=indexL=indexR=indexA=b=a=0; mleft->length, 1.0, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, lnStates, probs, p->left->length, 1.0) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; iright->length, 1.0, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, lnStates, probs, p->right->length, 1.0) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; ilength, 1.0, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, lnStates, probs, p->length, 1.0) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; ileft->index)*oneNodeSize]; clR = &condLike[condLikeOffset + (p->right->index)*oneNodeSize]; clA = &condLike[condLikeOffset + (p->anc->index)*oneNodeSize]; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; /* then branch to models */ if (!strcmp(ratesModel, "equal")) { for (c=0; cupDateCl = NO; clUpdateFlag[p->index] = YES; } // done if p->upDateCl == YES for internal root node } // done with internal root node else { if (p->upDateCl == YES) { //printf ("visiting interior node %d\n", p->index); /* get transition probabilities */ # if defined (SMART_TI_PROBS) pL = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->left->index)*nodeTiSize); pR = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->right->index)*nodeTiSize); # else for (m=indexL=indexR=b=a=0; mleft->length, 1.0, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, lnStates, probs, p->left->length, 1.0) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; iright->length, 1.0, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, lnStates, probs, p->right->length, 1.0) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; ileft->index)*oneNodeSize]; clR = &condLike[condLikeOffset + (p->right->index)*oneNodeSize]; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; /* then branch to models */ if (!strcmp(ratesModel, "equal")) { for (c=0; cupDateCl = NO; clUpdateFlag[p->index] = YES; } // done with interior node if p->upDateCl == YES } // done with interior node // deal with scaling // first check if we need to refresh scalers and potentially shift scaler nodes // we have to remember scalerIndex because the node may move in the tree if (refreshScalers == YES) { if (n % RESCALE_FREQ == 0) { p->scalerNode = YES; p->scalerIndex = n; } else p->scalerNode = NO; } if (p->scalerNode == YES && clUpdateFlag[p->index] == YES) { scalerUpdateFlag[p->scalerIndex] = YES; scP = &clScaler[scalerOffset + (p->scalerIndex)*numChars]; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; i = j = 0; for (c=0; c scaler) scaler = clP[i]; i++; } } for (k=0; kleft; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; (*lnL) = 0.0; // reset lnL if (!strcmp(ratesModel, "equal") || !strcmp(ratesModel, "sitespec")) { for (c=0; c=0; c--) { cn = c*lnumRateCats; if (patternId[c] >= 0) { pat = patternId[c]; if (c + localLag >= nChar) { max = 0.0; for (k=0; k max) max = biN[cn + k]; } if (max > 0.0) { for (k=0; k max) max = biN[cn + i]; usedBin[c+localLag] = YES; } if (max > 0.0) { for (k=0; k 1) { for (i=0; iupDateCl = YES; clUpdateFlag[p->index] = NO; if (p->anc->anc == NULL && treeModel == UNROOTED) { if (p->upDateCl == YES) { //printf ("visiting basal node %d\n", p->index); /* get transition probabilities */ # if defined (SMART_TI_PROBS) pL = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->left->index)*nodeTiSize); pR = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->right->index)*nodeTiSize); pA = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->index)*nodeTiSize); # else if (nst == 1 || nst == 2) { for (m=indexL=indexR=indexA=0; mleft->length, lkappa, theRate, bs[A], bs[C], bs[G], bs[T]); for (i=0; i<4; i++) for (j=0; j<4; j++) pL[indexL++] = probs[i][j]; /* calculate transition probabilities for right branch */ HkyChangeMat (probs, p->right->length, lkappa, theRate, bs[A], bs[C], bs[G], bs[T]); for (i=0; i<4; i++) for (j=0; j<4; j++) pR[indexR++] = probs[i][j]; /* calculate transition probabilities for ancestral branch */ HkyChangeMat (probs, p->length, lkappa, theRate, bs[A], bs[C], bs[G], bs[T]); for (i=0; i<4; i++) for (j=0; j<4; j++) pA[indexA++] = probs[i][j]; } } } else // nst == 6 or nst == 12 { for (m=indexL=indexR=indexA=0; mleft->length, theRate, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, 4, probs, p->left->length, theRate) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; i<4; i++) for (j=0; j<4; j++) pL[indexL++] = probs[i][j]; // calculate transition probabilities for right branch if (isComplex == NO) CalcPij (c_ijk, 4, eigenValues, p->right->length, theRate, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, 4, probs, p->right->length, theRate) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; i<4; i++) for (j=0; j<4; j++) pR[indexR++] = probs[i][j]; // calculate transition probabilities for ancestral branch if (isComplex == NO) CalcPij (c_ijk, 4, eigenValues, p->length, theRate, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, 4, probs, p->length, theRate) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; i<4; i++) for (j=0; j<4; j++) pA[indexA++] = probs[i][j]; } } } # endif /* calculate conditional likelihoods */ /* first set pointers to cond likes of left, right, p and anc */ clL = &condLike[condLikeOffset + (p->left->index)*oneNodeSize]; clR = &condLike[condLikeOffset + (p->right->index)*oneNodeSize]; clA = &condLike[condLikeOffset + (p->anc->index)*oneNodeSize]; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; if (!strcmp(ratesModel, "equal")) { tiPL = pL; tiPR = pR; tiPA = pA; for (c=0; cupDateCl = NO; clUpdateFlag[p->index] = YES; } // done if p->upDateCl == YES for internal root node } // done with internal root node else { if (p->upDateCl == YES) { //printf ("visiting interior node %d\n", p->index); /* get transition probabilities */ # if defined (SMART_TI_PROBS) pL = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->left->index)*nodeTiSize); pR = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->right->index)*nodeTiSize); # else if (nst == 1 || nst == 2) { for (m=indexL=indexR=0; mleft->length, lkappa, theRate, bs[A], bs[C], bs[G], bs[T]); for (i=0; i<4; i++) for (j=0; j<4; j++) pL[indexL++] = probs[i][j]; /* calculate transition probabilities for right branch */ HkyChangeMat (probs, p->right->length, lkappa, theRate, bs[A], bs[C], bs[G], bs[T]); for (i=0; i<4; i++) for (j=0; j<4; j++) pR[indexR++] = probs[i][j]; } } } else // nst == 6 or nst == 12 { for (m=indexL=indexR=0; mleft->length, theRate, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, 4, probs, p->left->length, theRate) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; i<4; i++) for (j=0; j<4; j++) pL[indexL++] = probs[i][j]; // calculate transition probabilities for right branch if (isComplex == NO) CalcPij (c_ijk, 4, eigenValues, p->right->length, theRate, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, 4, probs, p->right->length, theRate) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; i<4; i++) for (j=0; j<4; j++) pR[indexR++] = probs[i][j]; } } } # endif /* calculate conditional likelihoods */ /* first set pointers to cond likes of left, right and p */ clL = &condLike[condLikeOffset + (p->left->index)*oneNodeSize]; clR = &condLike[condLikeOffset + (p->right->index)*oneNodeSize]; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; if (!strcmp(ratesModel, "equal")) { tiPL = pL; tiPR = pR; for (c=0; cupDateCl = NO; clUpdateFlag[p->index] = YES; } // done with interior node if p->upDateCl == YES } // done with interior node // deal with scaling // first check if we need to refresh scalers and potentially shift scaler nodes // we have to remember scalerIndex because the node may move in the tree if (refreshScalers == YES) { if (n % RESCALE_FREQ == 0) { p->scalerNode = YES; p->scalerIndex = n; } else p->scalerNode = NO; } if (p->scalerNode == YES && clUpdateFlag[p->index] == YES) { scalerUpdateFlag[p->scalerIndex] = YES; scP = &clScaler[scalerOffset + (p->scalerIndex)*numChars]; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; i = j = 0; if (lnumRateCats > 1) { for (c=0; c scaler) scaler = clP[i]; i++; if (clP[i] > scaler) scaler = clP[i]; i++; if (clP[i] > scaler) scaler = clP[i]; i++; if (clP[i] > scaler) scaler = clP[i]; i++; } for (k=0; k scaler) scaler = clP[i]; i++; if (clP[i] > scaler) scaler = clP[i]; i++; if (clP[i] > scaler) scaler = clP[i]; i++; clP[j++] /= scaler; clP[j++] /= scaler; clP[j++] /= scaler; clP[j++] /= scaler; lnScaler[c] -= scP[c]; //subtract old value scP[c] = log(scaler); lnScaler[c] += scP[c]; //add new value } } } } // next node /* get likelihood at base of tree */ p = root[whichChain*2+whichState]->left; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; (*lnL) = 0.0; // reset lnL if (!strcmp(ratesModel, "equal") || !strcmp(ratesModel, "sitespec")) { for (c=0; c=0; c--) { cn = c*lnumRateCats; if (patternId[c] >= 0) { pat = patternId[c]; if (c + localLag >= nChar) { max = 0.0; for (k=0; k max) max = biN[cn + k]; } if (max > 0.0) { for (k=0; k max) max = biN[cn + i]; usedBin[c+localLag] = YES; } if (max > 0.0) { for (k=0; k 1) { for (i=0; iupDateCl = YES; clUpdateFlag[p->index] = NO; if (p->anc->anc == NULL && treeModel == UNROOTED) { if (p->upDateCl == YES) { //printf ("visiting basal node %d\n", p->index); /* get transition probabilities */ # if defined (SMART_TI_PROBS) pL = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->left->index)*nodeTiSize); pR = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->right->index)*nodeTiSize); pA = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->index)*nodeTiSize); # else if (nst == 1 || nst == 2) { for (m=indexL=indexR=indexA=0; mleft->length, lkappa, theRate, bs[A], bs[C], bs[G], bs[T]); for (i=0; i<4; i++) for (j=0; j<4; j++) pL[indexL++] = probs[i][j]; /* calculate transition probabilities for right branch */ HkyChangeMat (probs, p->right->length, lkappa, theRate, bs[A], bs[C], bs[G], bs[T]); for (i=0; i<4; i++) for (j=0; j<4; j++) pR[indexR++] = probs[i][j]; /* calculate transition probabilities for ancestral branch */ HkyChangeMat (probs, p->length, lkappa, theRate, bs[A], bs[C], bs[G], bs[T]); for (i=0; i<4; i++) for (j=0; j<4; j++) pA[indexA++] = probs[i][j]; } } } else // nst == 6 or nst == 12 { for (m=indexL=indexR=indexA=0; mleft->length, theRate, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, N_STATES, probs, p->left->length, theRate) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; i<4; i++) for (j=0; j<4; j++) pL[indexL++] = probs[i][j]; // calculate transition probabilities for right branch if (isComplex == NO) CalcPij (c_ijk, N_STATES, eigenValues, p->right->length, theRate, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, 4, probs, p->right->length, theRate) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; i<4; i++) for (j=0; j<4; j++) pR[indexR++] = probs[i][j]; // calculate transition probabilities for ancestral branch if (isComplex == NO) CalcPij (c_ijk, 4, eigenValues, p->length, theRate, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, 4, probs, p->length, theRate) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; i<4; i++) for (j=0; j<4; j++) pA[indexA++] = probs[i][j]; } } } # endif if (!strcmp(ratesModel, "invariant") || !strcmp(ratesModel, "invgamma")) { for (i=0; ileft->left == NULL && isPartAmbig[p->left->index] == NO) { shortCut |= 1; lState = termState + p->left->index * numChars; tiPL = pL; for (m=j=0; mright->left == NULL && isPartAmbig[p->right->index] == NO) { shortCut |= 2; rState = termState + p->right->index * numChars; tiPR = pR; for (m=j=0; manc->index] == YES) { shortCut = 4; } else { aState = termState + p->anc->index * numChars; tiPA = pA; for (m=j=0; mleft->index)*oneNodeSize]; clR = &condLike[condLikeOffset + (p->right->index)*oneNodeSize]; clA = &condLike[condLikeOffset + (p->anc->index)*oneNodeSize]; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; /* then branch to model */ if (!strcmp(ratesModel, "equal")) { tiPL = pL; tiPR = pR; tiPA = pA; switch (shortCut) { case 4: // anc is partially ambiguous for (c=h=0; cupDateCl = NO; clUpdateFlag[p->index] = YES; } // done if p->upDateCl == YES for internal root node } // done with internal root node else { if (p->upDateCl == YES) { //printf ("visiting interior node %d\n", p->index); /* get transition probabilities */ # if defined (SMART_TI_PROBS) pL = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->left->index)*nodeTiSize); pR = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->right->index)*nodeTiSize); # else if (nst == 1 || nst == 2) { for (m=indexL=indexR=0; mleft->length, lkappa, theRate, bs[A], bs[C], bs[G], bs[T]); for (i=0; i<4; i++) for (j=0; j<4; j++) pL[indexL++] = probs[i][j]; /* calculate transition probabilities for right branch */ HkyChangeMat (probs, p->right->length, lkappa, theRate, bs[A], bs[C], bs[G], bs[T]); for (i=0; i<4; i++) for (j=0; j<4; j++) pR[indexR++] = probs[i][j]; } } } else // nst == 6 or nst == 12 { for (m=indexL=indexR=0; mleft->length, theRate, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, 4, probs, p->left->length, theRate) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; i<4; i++) for (j=0; j<4; j++) pL[indexL++] = probs[i][j]; // calculate transition probabilities for right branch if (isComplex == NO) CalcPij (c_ijk, 4, eigenValues, p->right->length, theRate, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, 4, probs, p->right->length, theRate) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; i<4; i++) for (j=0; j<4; j++) pR[indexR++] = probs[i][j]; } } } # endif if (!strcmp(ratesModel, "invariant") || !strcmp(ratesModel, "invgamma")) { for (i=0; ileft->left == NULL && isPartAmbig[p->left->index] == NO) { shortCut |= 1; lState = termState + p->left->index * numChars; tiPL = pL; for (m=j=0; mright->left == NULL && isPartAmbig[p->right->index] == NO) { shortCut |= 2; rState = termState + p->right->index * numChars; tiPR = pR; for (m=j=0; mleft->index)*oneNodeSize]; clR = &condLike[condLikeOffset + (p->right->index)*oneNodeSize]; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; /* then branch to model */ if (!strcmp(ratesModel, "equal")) { tiPL = pL; tiPR = pR; switch (shortCut) { case 0: for (c=h=0; cupDateCl = NO; clUpdateFlag[p->index] = YES; } // done with interior node if p->upDateCl == YES } // done with interior node // deal with scaling // first check if we need to refresh scalers and potentially shift scaler nodes // we have to remember scalerIndex because the node may move in the tree if (refreshScalers == YES) { if (n % RESCALE_FREQ == 0) { p->scalerNode = YES; p->scalerIndex = n; } else p->scalerNode = NO; } if (p->scalerNode == YES && clUpdateFlag[p->index] == YES) { scalerUpdateFlag[p->scalerIndex] = YES; scP = &clScaler[scalerOffset + (p->scalerIndex)*numChars]; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; i = j = 0; if (lnumRateCats > 1) { for (c=0; c scaler) scaler = clP[i]; i++; if (clP[i] > scaler) scaler = clP[i]; i++; if (clP[i] > scaler) scaler = clP[i]; i++; if (clP[i] > scaler) scaler = clP[i]; i++; } for (k=0; k scaler) scaler = clP[i]; i++; if (clP[i] > scaler) scaler = clP[i]; i++; if (clP[i] > scaler) scaler = clP[i]; i++; clP[j++] /= scaler; clP[j++] /= scaler; clP[j++] /= scaler; clP[j++] /= scaler; lnScaler[c] -= scP[c]; //subtract old value scP[c] = log(scaler); lnScaler[c] += scP[c]; //add new value } } } } // next node /* get likelihood at base of tree */ p = root[whichChain*2+whichState]->left; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; (*lnL) = 0.0; // reset lnL if (!strcmp(ratesModel, "equal") || !strcmp(ratesModel, "sitespec")) { for (c=0; c=0; c--) { cn = c*lnumRateCats; if (patternId[c] >= 0) { pat = patternId[c]; if (c + localLag >= nChar) { max = 0.0; for (k=0; k max) max = biN[cn + k]; } if (max > 0.0) { for (k=0; k max) max = biN[cn + i]; usedBin[c+localLag] = YES; } if (max > 0.0) { for (k=0; k 1) { for (i=0; iupDateCl = YES; clUpdateFlag[p->index] = NO; if (p->anc->anc == NULL && treeModel == UNROOTED) { if (p->upDateCl == YES) { //printf ("visiting basal node %d\n", p->index); /* get transition probabilities */ # if defined (SMART_TI_PROBS) pL = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->left->index)*nodeTiSize); pR = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->right->index)*nodeTiSize); pA = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->index)*nodeTiSize); # else for (m=indexL=indexR=indexA=0; mleft->length, theRate, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, N_STATES, probs, p->left->length, theRate) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; iright->length, theRate, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, N_STATES, probs, p->right->length, theRate) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; ilength, theRate, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, N_STATES, probs, p->length, theRate) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; ileft->left == NULL && isPartAmbig[p->left->index] == NO) { shortCut |= 1; lState = termState + p->left->index * numChars; for (m=a=b=0; mright->left == NULL && isPartAmbig[p->right->index] == NO) { shortCut |= 2; rState = termState + p->right->index * numChars; for (m=a=b=0; manc->index] == YES) { shortCut = 4; } else { aState = termState + p->anc->index * numChars; for (m=a=b=0; mleft->index)*oneNodeSize]; clR = &condLike[condLikeOffset + (p->right->index)*oneNodeSize]; clA = &condLike[condLikeOffset + (p->anc->index)*oneNodeSize]; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; /* then branch to models */ if (!strcmp(ratesModel, "equal")) { switch (shortCut) { case 4: // anc is partially ambiguous, do not use any shortcut for (c=0; cupDateCl = NO; clUpdateFlag[p->index] = YES; } // done if p->upDateCl == YES for internal root node } // done with internal root node else { if (p->upDateCl == YES) { //printf ("visiting interior node %d\n", p->index); /* get transition probabilities */ # if defined (SMART_TI_PROBS) pL = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->left->index)*nodeTiSize); pR = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->right->index)*nodeTiSize); # else for (m=indexL=indexR=0; mleft->length, theRate, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, N_STATES, probs, p->left->length, theRate) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; iright->length, theRate, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, N_STATES, probs, p->right->length, theRate) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; ileft->left == NULL && isPartAmbig[p->left->index] == NO) { shortCut |= 1; lState = termState + p->left->index * numChars; for (m=a=b=0; mright->left == NULL && isPartAmbig[p->right->index] == NO) { shortCut |= 2; rState = termState + p->right->index * numChars; for (m=a=b=0; mleft->index)*oneNodeSize]; clR = &condLike[condLikeOffset + (p->right->index)*oneNodeSize]; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; /* then branch to models */ if (!strcmp(ratesModel, "equal")) { switch (shortCut) { case 0: // none is terminal for (c=0; cupDateCl = NO; clUpdateFlag[p->index] = YES; } // done with interior node if p->upDateCl == YES } // done with interior node // deal with scaling // first check if we need to refresh scalers and potentially shift scaler nodes // we have to remember scalerIndex because the node may move in the tree if (refreshScalers == YES) { if (n % RESCALE_FREQ == 0) { p->scalerNode = YES; p->scalerIndex = n; } else p->scalerNode = NO; } if (p->scalerNode == YES && clUpdateFlag[p->index] == YES) { scalerUpdateFlag[p->scalerIndex] = YES; scP = &clScaler[scalerOffset + (p->scalerIndex)*numChars]; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; i = j = 0; for (c=0; c scaler) scaler = clP[i]; i++; } } for (k=0; kleft; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; (*lnL) = 0.0; // reset lnL if (!strcmp(ratesModel, "equal") || !strcmp(ratesModel, "sitespec")) { for (c=0; c=0; c--) { cn = c*lnumRateCats; if (patternId[c] >= 0) { pat = patternId[c]; if (c + localLag >= nChar) { max = 0.0; for (k=0; k max) max = biN[cn + k]; } if (max > 0.0) { for (k=0; k max) max = biN[cn + i]; usedBin[c+localLag] = YES; } if (max > 0.0) { for (k=0; kupDateCl = YES; clUpdateFlag[p->index] = NO; if (p->anc->anc == NULL && treeModel == UNROOTED) { if (p->upDateCl == YES) { # if defined (SMART_TI_PROBS) pL = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->left->index)*nodeTiSize); pR = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->right->index)*nodeTiSize); pA = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->index)*nodeTiSize); # else //printf ("visiting basal node %d\n", p->index); /* get transition probabilities */ indexL = indexR = indexA = 0; // calculate transition probabilities for left branch if (isComplex == NO) CalcPij (c_ijk, lnStates, eigenValues, p->left->length, 1.0, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, lnStates, probs, p->left->length, 1.0) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; iright->length, 1.0, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, lnStates, probs, p->right->length, 1.0) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; ilength, 1.0, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, lnStates, probs, p->length, 1.0) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; ileft->length, 1.0, probs); else if (ComplexChangeMatrix (eigenValues2, eigvalsImag2, Ceigvecs2, CinverseEigvecs2, lnStates, probs, p->left->length, 1.0) == ERROR) printf ("Problem calculating transition probabilities for complex eigen values.\n"); for (i=0; iright->length, 1.0, probs); else if (ComplexChangeMatrix (eigenValues2, eigvalsImag2, Ceigvecs2, CinverseEigvecs2, lnStates, probs, p->right->length, 1.0) == ERROR) printf ("Problem calculating transition probabilities for complex eigen values.\n"); for (i=0; ilength, 1.0, probs); else if (ComplexChangeMatrix (eigenValues2, eigvalsImag2, Ceigvecs2, CinverseEigvecs2, lnStates, probs, p->length, 1.0) == ERROR) printf ("Problem calculating transition probabilities for complex eigen values.\n"); for (i=0; ileft->length, 1.0, probs); else if (ComplexChangeMatrix (eigenValues3, eigvalsImag3, Ceigvecs3, CinverseEigvecs3, lnStates, probs, p->left->length, 1.0) == ERROR) printf ("Problem calculating transition probabilities for complex eigen values.\n"); for (i=0; iright->length, 1.0, probs); else if (ComplexChangeMatrix (eigenValues3, eigvalsImag3, Ceigvecs3, CinverseEigvecs3, lnStates, probs, p->right->length, 1.0) == ERROR) printf ("Problem calculating transition probabilities for complex eigen values.\n"); for (i=0; ilength, 1.0, probs); else if (ComplexChangeMatrix (eigenValues3, eigvalsImag3, Ceigvecs3, CinverseEigvecs3, lnStates, probs, p->length, 1.0) == ERROR) printf ("Problem calculating transition probabilities for complex eigen values.\n"); for (i=0; ileft->left == NULL && isPartAmbig[p->left->index] == NO) { shortCut |= 1; lState = termState + p->left->index * numChars; for (k=m=0; kright->left == NULL && isPartAmbig[p->right->index] == NO) { shortCut |= 2; rState = termState + p->right->index * numChars; for (k=m=0; kanc->index] == YES) { shortCut = 4; } else { aState = termState + p->anc->index * numChars; for (k=m=0; kleft->index)*oneNodeSize]; clR = &condLike[condLikeOffset + (p->right->index)*oneNodeSize]; clA = &condLike[condLikeOffset + (p->anc->index)*oneNodeSize]; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; /* then branch to models */ if (!strcmp(codonModelType, "ny98") || !strcmp(codonModelType, "ac1ny98") || !strcmp(codonModelType, "ac2ny98")) { switch (shortCut) { case 4: // anc is partially ambiguous for (c=0; cupDateCl = NO; clUpdateFlag[p->index] = YES; } // done if p->upDateCl == YES for internal root node } // done with internal root node else { if (p->upDateCl == YES) { //printf ("visiting interior node %d\n", p->index); /* get transition probabilities */ # if defined (SMART_TI_PROBS) pL = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->left->index)*nodeTiSize); pR = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->right->index)*nodeTiSize); # else indexL = indexR = 0; // calculate transition probabilities for left branch if (isComplex == NO) CalcPij (c_ijk, lnStates, eigenValues, p->left->length, 1.0, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, lnStates, probs, p->left->length, 1.0) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; iright->length, 1.0, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, lnStates, probs, p->right->length, 1.0) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; ileft->length, 1.0, probs); else if (ComplexChangeMatrix (eigenValues2, eigvalsImag2, Ceigvecs2, CinverseEigvecs2, lnStates, probs, p->left->length, 1.0) == ERROR) printf ("Problem calculating transition probabilities for complex eigen values.\n"); for (i=0; iright->length, 1.0, probs); else if (ComplexChangeMatrix (eigenValues2, eigvalsImag2, Ceigvecs2, CinverseEigvecs2, lnStates, probs, p->right->length, 1.0) == ERROR) printf ("Problem calculating transition probabilities for complex eigen values.\n"); for (i=0; ileft->length, 1.0, probs); else if (ComplexChangeMatrix (eigenValues3, eigvalsImag3, Ceigvecs3, CinverseEigvecs3, lnStates, probs, p->left->length, 1.0) == ERROR) printf ("Problem calculating transition probabilities for complex eigen values.\n"); for (i=0; iright->length, 1.0, probs); else if (ComplexChangeMatrix (eigenValues3, eigvalsImag3, Ceigvecs3, CinverseEigvecs3, lnStates, probs, p->right->length, 1.0) == ERROR) printf ("Problem calculating transition probabilities for complex eigen values.\n"); for (i=0; ileft->left == NULL && isPartAmbig[p->left->index] == NO) { shortCut |= 1; lState = termState + p->left->index * numChars; for (k=m=0; kright->left == NULL && isPartAmbig[p->right->index] == NO) { shortCut |= 2; rState = termState + p->right->index * numChars; for (k=m=0; kleft->index)*oneNodeSize]; clR = &condLike[condLikeOffset + (p->right->index)*oneNodeSize]; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; /* then branch to models */ if (!strcmp(codonModelType, "ny98") || !strcmp(codonModelType, "ac1ny98") || !strcmp(codonModelType, "ac2ny98")) { switch (shortCut) { case 0: // none is terminal for (c=0; cupDateCl = NO; clUpdateFlag[p->index] = YES; } // done with interior node if p->upDateCl == YES } // done with interior node // deal with scaling // first check if we need to refresh scalers and potentially shift scaler nodes // we have to remember scalerIndex because the node may move in the tree if (refreshScalers == YES) { if (n % RESCALE_FREQ == 0) { p->scalerNode = YES; p->scalerIndex = n; } else p->scalerNode = NO; } if (p->scalerNode == YES && clUpdateFlag[p->index] == YES) { scalerUpdateFlag[p->scalerIndex] = YES; scP = &clScaler[scalerOffset + (p->scalerIndex)*numChars]; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; i = j = 0; for (c=0; c scaler) scaler = clP[i]; i++; } } for (k=0; kleft; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; (*lnL) = 0.0; // reset lnL if (!strcmp(codonModelType, "ny98")) { for (c=0; c=0; c--) { cn = c*3; if (patternId[c] >= 0) { pat = patternId[c]; if (isFirst == YES) { max = 0.0; for (k=0; k<3; k++) { biN[cn + k] = omegaPr[pat*3 + k]; if (biN[cn + k] > max) max = biN[cn + k]; } if (max > 0.0) { for (k=0; k<3; k++) biN[cn + k] /= max; lnC += log(max); } else { printf (" ERROR: Scaling factor for ac1ny98 or ac2ny98 model is less than 0\n"); goto error_exit; } isFirst = NO; } else // isFirst == NO { for (i=0; i<3; i++) { temp = max = 0.0; for (j=0; j<3; j++) temp += markovTi[i][j] * biN[(c+1)*3 + j]; biN[cn + i] = omegaPr[pat*3+i] * temp; if (biN[cn + i] > max) max = biN[cn + i]; } if (max > 0.0) { for (k=0; k<3; k++) biN[cn + k] /= max; lnC += log(max); } else { printf (" ERROR: Scaling factor for adgamma model is less than 0\n"); goto error_exit; } } } else { printf (" ERROR: Unidentified pattern\n"); goto error_exit; } } temp = biN[0] * probPur[whichChain*2 + whichState]; temp += biN[1] * probNeu[whichChain*2 + whichState]; temp += biN[2] * probPos[whichChain*2 + whichState]; (*lnL) = lnC + log(temp); } else /* no omega variation or covarion-like model */ { for (c=0; c 1) { for (i=0; iupDateCl = YES; clUpdateFlag[p->index] = NO; if (p->anc->anc == NULL && treeModel == UNROOTED) { if (p->upDateCl == YES) { //printf ("visiting basal node %d\n", p->index); /* get transition probabilities */ # if defined (SMART_TI_PROBS) pL = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->left->index)*nodeTiSize); pR = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->right->index)*nodeTiSize); pA = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->index)*nodeTiSize); # else for (m=indexL=indexR=indexA=b=a=0; mleft->length, 1.0, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, lnStates, probs, p->left->length, 1.0) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; iright->length, 1.0, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, lnStates, probs, p->right->length, 1.0) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; ilength, 1.0, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, lnStates, probs, p->length, 1.0) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; ileft->left == NULL && isPartAmbig[p->left->index] == NO) { shortCut |= 1; lState = termState + p->left->index * numChars; for (m=a=b=0; mright->left == NULL && isPartAmbig[p->right->index] == NO) { shortCut |= 2; rState = termState + p->right->index * numChars; for (m=a=b=0; manc->index] == YES) { shortCut = 4; } else { aState = termState + p->anc->index * numChars; for (m=a=b=0; mleft->index)*oneNodeSize]; clR = &condLike[condLikeOffset + (p->right->index)*oneNodeSize]; clA = &condLike[condLikeOffset + (p->anc->index)*oneNodeSize]; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; /* then branch to models */ if (!strcmp(ratesModel, "equal")) { switch (shortCut) { case 4: // anc is partially ambiguous, do not use any shortcut for (c=0; cupDateCl = NO; clUpdateFlag[p->index] = YES; } // done if p->upDateCl == YES for internal root node } // done with internal root node else { if (p->upDateCl == YES) { //printf ("visiting interior node %d\n", p->index); /* get transition probabilities */ # if defined (SMART_TI_PROBS) pL = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->left->index)*nodeTiSize); pR = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->right->index)*nodeTiSize); # else for (m=indexL=indexR=b=a=0; mleft->length, 1.0, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, lnStates, probs, p->left->length, 1.0) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; iright->length, 1.0, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, lnStates, probs, p->right->length, 1.0) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; ileft->left == NULL && isPartAmbig[p->left->index] == NO) { shortCut |= 1; lState = termState + p->left->index * numChars; for (m=a=b=0; mright->left == NULL && isPartAmbig[p->right->index] == NO) { shortCut |= 2; rState = termState + p->right->index * numChars; for (m=a=b=0; mleft->index)*oneNodeSize]; clR = &condLike[condLikeOffset + (p->right->index)*oneNodeSize]; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; /* then branch to models */ if (!strcmp(ratesModel, "equal")) { switch (shortCut) { case 0: // none is terminal for (c=0; cupDateCl = NO; clUpdateFlag[p->index] = YES; } // done with interior node if p->upDateCl == YES } // done with interior node // deal with scaling // first check if we need to refresh scalers and potentially shift scaler nodes // we have to remember scalerIndex because the node may move in the tree if (refreshScalers == YES) { if (n % RESCALE_FREQ == 0) { p->scalerNode = YES; p->scalerIndex = n; } else p->scalerNode = NO; } if (p->scalerNode == YES && clUpdateFlag[p->index] == YES) { scalerUpdateFlag[p->scalerIndex] = YES; scP = &clScaler[scalerOffset + (p->scalerIndex)*numChars]; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; i = j = 0; for (c=0; c scaler) scaler = clP[i]; i++; } } for (k=0; kleft; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; (*lnL) = 0.0; // reset lnL if (!strcmp(ratesModel, "equal") || !strcmp(ratesModel, "sitespec")) { for (c=0; c=0; c--) { cn = c*lnumRateCats; if (patternId[c] >= 0) { pat = patternId[c]; if (c + localLag >= nChar) { max = 0.0; for (k=0; k max) max = biN[cn + k]; } if (max > 0.0) { for (k=0; k max) max = biN[cn + i]; usedBin[c+localLag] = YES; } if (max > 0.0) { for (k=0; k 1) { DiscreteGamma (catFreq, catRate, alpha[whichChain*2 + whichState], alpha[whichChain*2 + whichState], lnumRateCats, 0); } else { catRate[0] = 1.0; catFreq[0] = 1.0; } /* initialize partition rates, if appropriate */ if (lnPartitions > 1) { for (i=0; iupDateCl = YES; clUpdateFlag[p->index] = NO; if (p->anc->anc == NULL && treeModel == UNROOTED) { if (p->upDateCl == YES) { //printf ("visiting basal node %d\n", p->index); /* get transition probabilities */ for (m=indexL=indexR=indexA=0; mleft->length * theRate; eV = exp(-(alp+bet)*v); pL[indexL++] = bs[0] + bs[1] * eV; pL[indexL++] = bs[1] - bs[1] * eV; pL[indexL++] = bs[0] - bs[0] * eV; pL[indexL++] = bs[1] + bs[0] * eV; v = p->right->length * theRate; eV = exp(-(alp+bet)*v); pR[indexR++] = bs[0] + bs[1] * eV; pR[indexR++] = bs[1] - bs[1] * eV; pR[indexR++] = bs[0] - bs[0] * eV; pR[indexR++] = bs[1] + bs[0] * eV; v = p->length * theRate; eV = exp(-(alp+bet)*v); pA[indexA++] = bs[0] + bs[1] * eV; pA[indexA++] = bs[1] - bs[1] * eV; pA[indexA++] = bs[0] - bs[0] * eV; pA[indexA++] = bs[1] + bs[0] * eV; } } /* calculate conditional likelihoods */ /* first set pointers to cond likes of left, right, p and anc */ clL = &condLike[condLikeOffset + (p->left->index)*oneNodeSize]; clR = &condLike[condLikeOffset + (p->right->index)*oneNodeSize]; clA = &condLike[condLikeOffset + (p->anc->index)*oneNodeSize]; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; if (!strcmp(ratesModel, "equal")) { tiPL = pL; tiPR = pR; tiPA = pA; for (c=0; cupDateCl = NO; clUpdateFlag[p->index] = YES; } // done if p->upDateCl == YES for root node } // done with root node else { if (p->upDateCl == YES) { //printf ("visiting internal node %d\n", p->index); /* get transition probabilities */ for (m=indexL=indexR=0; mleft->length * theRate; eV = exp(-(alp+bet)*v); pL[indexL++] = bs[0] + bs[1] * eV; pL[indexL++] = bs[1] - bs[1] * eV; pL[indexL++] = bs[0] - bs[0] * eV; pL[indexL++] = bs[1] + bs[0] * eV; v = p->right->length * theRate; eV = exp(-(alp+bet)*v); pR[indexR++] = bs[0] + bs[1] * eV; pR[indexR++] = bs[1] - bs[1] * eV; pR[indexR++] = bs[0] - bs[0] * eV; pR[indexR++] = bs[1] + bs[0] * eV; } } /* calculate conditional likelihoods */ /* first assign pointers to right, left and p */ clL = &condLike[condLikeOffset + (p->left->index)*oneNodeSize]; clR = &condLike[condLikeOffset + (p->right->index)*oneNodeSize]; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; if (!strcmp(ratesModel, "equal")) { tiPL = pL; tiPR = pR; for (c=0; cupDateCl = NO; clUpdateFlag[p->index] = YES; } // done with interior node if p->upDateCl == YES } // done with interior node // deal with scaling // first check if we need to refresh scalers // and potentially shift scaler nodes // we have to remember scalerIndex // because the node may move in the tree if (refreshScalers == YES) { if (n % RESCALE_FREQ == 0) { p->scalerNode = YES; p->scalerIndex = n; } else p->scalerNode = NO; } if (p->scalerNode == YES && clUpdateFlag[p->index] == YES) { scalerUpdateFlag[p->scalerIndex] = YES; scP = &clScaler[scalerOffset + (p->scalerIndex)*numChars]; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; i = j = 0; for (c=0; c scaler) scaler = clP[i]; i++; if (clP[i] > scaler) scaler = clP[i]; i++; } } for (k=0; kleft; (*lnL) = 0.0; for (k=0; kindex)*oneNodeSize]; if (!strcmp(ratesModel, "equal") || !strcmp(ratesModel, "sitespec")) { for (c=j=0; c 1) { DiscreteGamma (catFreq, catRate, alpha[whichChain*2 + whichState], alpha[whichChain*2 + whichState], lnumRateCats, 0); } else { catRate[0] = 1.0; catFreq[0] = 1.0; } /* initialize partition rates, if appropriate */ if (lnPartitions > 1) { for (i=0; iupDateCl = YES; clUpdateFlag[p->index] = NO; if (p->anc->anc == NULL && treeModel == UNROOTED) { if (p->upDateCl == YES) { //printf ("visiting basal node %d\n", p->index); /* get transition probabilities */ for (m=indexL=indexR=indexA=0; mleft->length * theRate; eV = exp(-(alp+bet)*v); pL[indexL++] = (bs0) + (bs1) * eV; pL[indexL++] = (bs1) - (bs1) * eV; pL[indexL++] = (bs0) - (bs0) * eV; pL[indexL++] = (bs1) + (bs0) * eV; v = p->right->length * theRate; eV = exp(-(alp+bet)*v); pR[indexR++] = (bs0) + (bs1) * eV; pR[indexR++] = (bs1) - (bs1) * eV; pR[indexR++] = (bs0) - (bs0) * eV; pR[indexR++] = (bs1) + (bs0) * eV; v = p->length * theRate; eV = exp(-(alp+bet)*v); pA[indexA++] = (bs0) + (bs1) * eV; pA[indexA++] = (bs1) - (bs1) * eV; pA[indexA++] = (bs0) - (bs0) * eV; pA[indexA++] = (bs1) + (bs0) * eV; } } } /* calculate conditional likelihoods */ /* first set pointers to cond likes of left, right, p and anc */ clL = &condLike[condLikeOffset + (p->left->index)*oneNodeSize]; clR = &condLike[condLikeOffset + (p->right->index)*oneNodeSize]; clA = &condLike[condLikeOffset + (p->anc->index)*oneNodeSize]; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; if (!strcmp(ratesModel, "equal")) { for (c=0; cupDateCl = NO; clUpdateFlag[p->index] = YES; } // done if p->upDateCl == YES for root node } // done with root node else { if (p->upDateCl == YES) { //printf ("visiting internal node %d\n", p->index); /* get transition probabilities */ for (m=indexL=indexR=0; mleft->length * theRate; eV = exp(-(alp+bet)*v); pL[indexL++] = (bs0) + (bs1) * eV; pL[indexL++] = (bs1) - (bs1) * eV; pL[indexL++] = (bs0) - (bs0) * eV; pL[indexL++] = (bs1) + (bs0) * eV; v = p->right->length * theRate; eV = exp(-(alp+bet)*v); pR[indexR++] = (bs0) + (bs1) * eV; pR[indexR++] = (bs1) - (bs1) * eV; pR[indexR++] = (bs0) - (bs0) * eV; pR[indexR++] = (bs1) + (bs0) * eV; } } } /* calculate conditional likelihoods */ /* first assign pointers to right, left and p */ clL = &condLike[condLikeOffset + (p->left->index)*oneNodeSize]; clR = &condLike[condLikeOffset + (p->right->index)*oneNodeSize]; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; if (!strcmp(ratesModel, "equal")) { for (c=0; cupDateCl = NO; clUpdateFlag[p->index] = YES; } // done with interior node if p->upDateCl == YES } // done with interior node // deal with scaling // first check if we need to refresh scalers // and potentially shift scaler nodes // we have to remember scalerIndex // because the node may move in the tree if (refreshScalers == YES) { if (n % RESCALE_FREQ == 0) { p->scalerNode = YES; p->scalerIndex = n; } else p->scalerNode = NO; } if (p->scalerNode == YES && clUpdateFlag[p->index] == YES) { scalerUpdateFlag[p->scalerIndex] = YES; scP = &clScaler[scalerOffset + (p->scalerIndex)*numChars]; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; i = j = 0; m = lnumRateCats * numBetaCats; for (c=0; c scaler) scaler = clP[i]; i++; if (clP[i] > scaler) scaler = clP[i]; i++; } for (k=0; kleft; (*lnL) = 0.0; pObserved = 0.0; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; if (!strcmp(ratesModel, "equal") || !strcmp(ratesModel, "sitespec")) { for (c=j=0; c pObserved) { printf (" WARNING: Character likelihood > p(observed)\n"); goto error_exit; } if (like < LIKE_EPSILON) /* likelihood for a site can go to zero when */ { /* two adjacent terminal branches have zero length. */ printf (" WARNING: In LIKE_EPSILON\n"); goto error_exit; } else (*lnL) += (lnScaler[c] + log(like)) * numSitesOfPat[c]; } } else if (!strcmp(ratesModel, "gamma") || !strcmp(ratesModel, "ssgamma")) { for (c=j=0; c pObserved) { printf (" WARNING: Character likelihood > p(observed)\n"); goto error_exit; } if (like < LIKE_EPSILON) /* likelihood for a site can go to zero when */ { /* two adjacent terminal branches have zero length. */ printf (" WARNING: In LIKE_EPSILON\n"); goto error_exit; } else (*lnL) += (lnScaler[c] + log(like)) * numSitesOfPat[c]; } } /* correct for absent characters */ (*lnL) -= log(pObserved) * (nChar); /* free memory */ free (pL); free (catFreq); free (betaFreq); return (NO_ERROR); error_exit: free (pL); free (catFreq); free (betaFreq); return (ERROR); # undef N_STATES_SQUARED # undef N_STATES } /*---------------------------------------------------------------------- LnLikeStandardMk: Likelihood function for standard data This function is prepared for dealing with varying number of states It needs help by a vector array indicating the number of states for each site pattern, instead of relying on the global nStates, as in the present code, and a help function that sets up the Q and P matrices It uses 1/nStates as the probability of the state at the root It deals with ordered/unordered chars given suitable help functions It deals with gamma, ssgamma, sitespec and equal models of rate variation Core written 2001-03-11 ------------------------------------------------------------------------*/ int LnLikeStandardMk (int whichState, int whichChain, int numChars, int numRateCats, double *lnL, int refreshScalers) { register int i, j, k, c, n, m; int nPij, lnumRateCats, lnPartitions, oneMatSize, oneNodeSize, intNodeOffset, nStatesSquared, index, nRates, condLikeOffset, scalerOffset, indexL, indexR, indexA; double **probs, *stateFreq, *pL, *pR, *pA, *catFreq, *catRate, *clL, *clR, *clA, *clP, *tiPL, *tiPR, *tiPA, like, theRate, *lnScaler, *scP, *partRate, scaler; double likeA, likeL, likeR; TreeNode *p; /* initialize intNodeOffset and nStatesSquared*/ intNodeOffset = whichChain*2*numIntNodes + whichState*numIntNodes; nStatesSquared = nStates * nStates; /* load state frequencies */ stateFreq = (double *)malloc((size_t) (nStates * sizeof(double))); if (!stateFreq) { printf ("\n ERROR: Problem allocating stateFreq\n"); goto error_exit; } index = whichChain*2*nStates + whichState*nStates; for (i = 0; i < nStates; i++) stateFreq[i] = 1.0 / nStates; /* how many different rate categories */ /* deal with relevant models */ /* lnumRateCats contains a local copy of numRateCats if appropriate, else 1 */ /* lnPartitions contains a local copy of nPartitions if appropriate, else 1 */ /* this is to make sure that these variables are set to 1 even if not "in use" */ if (!strcmp(ratesModel, "sitespec") || !strcmp(ratesModel, "ssgamma")) lnPartitions = nPartitions; else lnPartitions = 1; if (!strcmp(ratesModel, "equal") || !strcmp(ratesModel, "sitespec")) lnumRateCats = 1; else if (!strcmp(ratesModel, "gamma") || !strcmp(ratesModel, "ssgamma")) lnumRateCats = numRateCats; nRates = lnPartitions * lnumRateCats; // number of rates needing P matrices /* allocate memory for the calculations */ /* pL, pR and pA will contain the transition probs for Left, Right and Anc */ /* one trans prob matrix needed for each possible rate */ nPij = nRates * nStatesSquared; pL = (double *)malloc((size_t)(3 * nPij * sizeof(double))); if (!pL) { printf ("\n ERROR: Problem allocating Pij\n"); goto error_exit; } pR = pL + nPij; pA = pR + nPij; /* allocate memory for rate and rate category frequencies */ catFreq = (double *)malloc((size_t) ((2 * lnumRateCats + lnPartitions) * sizeof(double))); if (!catFreq) { printf ("\n ERROR: Problem allocating space for rate multipliers and rate category freqs.\n"); goto error_exit; } catRate = catFreq + lnumRateCats; partRate = catRate + lnumRateCats; probs = (double **) malloc ((size_t) (nStates * sizeof(double *))); if (!probs) { printf ("\n ERROR: Problem allocating space for transition matrices\n"); goto error_exit; } probs[0] = (double *) malloc ((size_t) (nStatesSquared * sizeof(double))); if (!probs[0]) { printf ("\n ERROR: Problem allocating space for transition matrices\n"); goto error_exit; } for (i=1; i 1) { DiscreteGamma (catFreq, catRate, alpha[whichChain*2 + whichState], alpha[whichChain*2 + whichState], lnumRateCats, 0); } else { catRate[0] = 1.0; catFreq[0] = 1.0; } /* initialize partition rates, if appropriate */ if (lnPartitions > 1) { for (i=0; iupDateCl = YES; clUpdateFlag[p->index] = NO; if (p->anc->anc == NULL && treeModel == UNROOTED) { if (p->upDateCl == YES) { //printf ("visiting basal node %d\n", p->index); /* get transition probabilities, currently only for M2 model */ /* replace this with call to suitable function(s) setting up */ /* ordered and unordered transition matrices for 2-5 states */ for (m=indexL=indexR=indexA=0; mleft->length*theRate)); probs[0][1] = probs[1][0] = 0.5 - 0.5 * exp(-(p->left->length*theRate)); for (i=0; iright->length*theRate)); probs[0][1] = probs[1][0] = 0.5 - 0.5 * exp(-(p->right->length*theRate)); for (i=0; ilength*theRate)); probs[0][1] = probs[1][0] = 0.5 - 0.5 * exp(-(p->length*theRate)); for (i=0; ileft->index)*oneNodeSize]; clR = &condLike[condLikeOffset + (p->right->index)*oneNodeSize]; clA = &condLike[condLikeOffset + (p->anc->index)*oneNodeSize]; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; if (!strcmp(ratesModel, "equal")) { tiPL = pL; tiPR = pR; tiPA = pA; for (c=0; cupDateCl = NO; clUpdateFlag[p->index] = YES; } // done if p->upDateCl == YES for interior root } // done with interior root else { if (p->upDateCl == YES) { //printf ("visiting internal node %d\n", p->index); /* get transition probabilities */ /* currently only for M2 model */ /* replace this with call to function(s) setting up */ /* the necessary transition probability matrices */ for (m=indexL=indexR=indexA=0; mleft->length*theRate)); probs[0][1] = probs[1][0] = 0.5 - 0.5 * exp(-(p->left->length*theRate)); for (i=0; iright->length*theRate)); probs[0][1] = probs[1][0] = 0.5 - 0.5 * exp(-(p->right->length*theRate)); for (i=0; ilength*theRate)); probs[0][1] = probs[1][0] = 0.5 - 0.5 * exp(-(p->length*theRate)); for (i=0; ileft->index)*oneNodeSize]; clR = &condLike[condLikeOffset + (p->right->index)*oneNodeSize]; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; if (!strcmp(ratesModel, "equal")) { tiPL = pL; tiPR = pR; for (c=0; cupDateCl = NO; clUpdateFlag[p->index] = YES; } // done with interior node if p->upDateCl == YES } // done with interior node // deal with scaling // first check if we need to refresh scalers // and potentially shift scaler nodes // we have to remember scalerIndex // because the node may move in the tree if (refreshScalers == YES) { if (n % RESCALE_FREQ == 0) { p->scalerNode = YES; p->scalerIndex = n; } else p->scalerNode = NO; } if (p->scalerNode == YES && clUpdateFlag[p->index] == YES) { scalerUpdateFlag[p->scalerIndex] = YES; scP = &clScaler[scalerOffset + (p->scalerIndex)*numChars]; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; i = j = 0; for (c=0; c scaler) scaler = clP[i]; i++; } } for (k=0; kleft; (*lnL) = 0.0; clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; if (!strcmp(ratesModel, "equal") || !strcmp(ratesModel, "sitespec")) { for (c=0; c 0) { constrainedNodes = (double *)malloc((size_t) (nConstraints * sizeof(double))); if (!constrainedNodes) { printf ("\n ERROR: Problem allocating constrainedNodes.\n"); free (lnL); free (curS); free (newS); free (chainTempId); return (ERROR); } } calibratedNodes = (double *)malloc((size_t) (nCalibrations * sizeof(double))); if (!calibratedNodes) { printf ("\n ERROR: Problem allocating calibratedNodes.\n"); free (lnL); free (curS); free (newS); free (chainTempId); free (constrainedNodes); return (ERROR); } } if (inferAncStates == YES) { ancStatesProbs = (double *)malloc((size_t) (nConstraints * nChar * nStates * sizeof(double))); if (!ancStatesProbs) { printf ("ERROR: Problem allocating ancStatesProbs\n"); free (lnL); free (curS); free (newS); free (chainTempId); if (enforceCalibrations == YES) { free (constrainedNodes); free (calibratedNodes); } return (ERROR); } else allocatedMemory[ALLOC_ANC_STATES] = YES; for (i=0; i 0.0) r = 1.0; else r = exp(lnLikelihoodRatio + lnPriorRatio + lnProposalRatio); /* decide to accept or reject the move */ acceptMove = NO; if (RandomNumber(seed) < r) acceptMove = YES; # if defined (TOPOLOGY_MOVE_STATS) /* record diagnostics for topology moves */ switch (move) { case CHANGE_UNROOT_LOCAL: case CHANGE_CLOCK_LOCAL: case CHANGE_CLOCK_TIME_LOCAL: case CHANGE_TREE_SPR: case CHANGE_WORM: case CHANGE_UNROOT_TBR: case CHANGE_TREE_FTBR: case CHANGE_ERASER: if (gTopologyHasChanged == YES) { nProposedNodes[move] += gNodeMoves; nProposedTopology[move]++; if (acceptMove == YES) { nAcceptedNodes[move] += gNodeMoves; nAcceptedTopology[move]++; } } } # endif /* update the chain */ if (acceptMove == YES) { curS[chain] = newS[chain]; if (curS[chain] == 1) newS[chain] = 0; else newS[chain] = 1; nAccepted[move]++; } lnL[chain*2 + newS[chain]] = lnL[chain*2 + curS[chain]]; CopyTree (curS[chain], newS[chain], chain); CopyConditionalLikelihoods (curS[chain], newS[chain], chain, numTaxa, numChars, numRateCats); } /* attemp to swap states for two chains */ if (numChains > 1) { nSwapsProposed++; chain1 = RandomNumber(seed) * numChains; do { chain2 = RandomNumber(seed) * numChains; } while (chain1 == chain2); lnR = (1.0 / (1.0 + chainTemp*(double)chainTempId[chain1])) * lnL[chain2*2 + curS[chain2]]; lnR += (1.0 / (1.0 + chainTemp*(double)chainTempId[chain2])) * lnL[chain1*2 + curS[chain1]]; lnR -= (1.0 / (1.0 + chainTemp*(double)chainTempId[chain1])) * lnL[chain1*2 + curS[chain1]]; lnR -= (1.0 / (1.0 + chainTemp*(double)chainTempId[chain2])) * lnL[chain2*2 + curS[chain2]]; if (lnR < -100.0) r = 0.0; else if (lnR > 0.0) r = 1.0; else r = exp(lnR); acceptMove = NO; if (RandomNumber(seed) < r) { acceptMove = YES; } if (acceptMove == YES) { nSwapsAccepted++; tempId = chainTempId[chain1]; chainTempId[chain1] = chainTempId[chain2]; chainTempId[chain2] = tempId; } /* print update to screen */ endingT = time(NULL); if (n % printFreq == 0) { timePerGen = (double)(difftime (endingT, startingT) / n); nSecs = (int)((nGen - n) * timePerGen); nHours = (int)nSecs / 3600; nSecs -= nHours * 3600; nMins = nSecs / 60; nSecs -= nMins * 60; printf (" %4d -- ", n); sum = 0.0; for (chain=0; chain 9) printf ("%d:", nMins); else printf ("0%d:", nMins); if (nSecs > 9) printf ("%d", nSecs); else printf ("0%d", nSecs); if (acceptMove == YES) printf (" (%d~%d)\n", chain1+1, chain2+1); else printf ("\n"); } } else { endingT = time(NULL); /* print update to screen */ if (n % printFreq == 0) { timePerGen = (double)(difftime (endingT, startingT) / n); nSecs = (int)((nGen - n) * timePerGen); nHours = (int)nSecs / 3600; nSecs -= nHours * 3600; nMins = nSecs / 60; nSecs -= nMins * 60; printf (" %4d -- %1.2lf ", n, lnL[curS[0]]); printf ("-- %d:", nHours); if (nMins > 9) printf ("%d:", nMins); else printf ("0%d:", nMins); if (nSecs > 9) printf ("%d\n", nSecs); else printf ("0%d\n", nSecs); } } /* check to see if we should continue chain */ if (n == nGen && autoclose == NO) { stoppingT1 = time(NULL); printf ("\n Continue with chain? (yes/no): "); if (YesNo() == YES) { tempInt = 0; do { if (tempInt < 0) printf (" Number must be greater than or equal to 0: "); else printf (" Additional number of generations: "); tempInt = (int)EnterNum (); } while (tempInt < 0); nGen += tempInt; } printf ("\n"); stoppingT2 = time(NULL); startingT -= (stoppingT2 - stoppingT1); } /* print states to file */ if (n % sampleFreq == 0 || n == 1 || n == nGen) { for (i=0; i= mcmcBurn) nSampled++; if (inferAncStates == YES && n >= mcmcBurn) { if ((dataType == DNA || dataType == RNA) && enforceCodonModel == NO) { if (PrintAncStatesDNA (curS[coldId], coldId, numChars, numRateCats, n) == ERROR) goto error_exit; UpDateAllCls (0, coldId); if (LnLikeDNA (0, coldId, numChars, numRateCats, &x, YES) == ERROR) goto error_exit; UpDateAllCls (1, coldId); if (LnLikeDNA (1, coldId, numChars, numRateCats, &x, YES) == ERROR) goto error_exit; } else if ((dataType == DNA || dataType == RNA) && enforceCodonModel == YES) { printf ("\n ERROR: Cannot calculate ancestral states for codon models (yet)\n"); goto error_exit; } else if (dataType == PROTEIN) { PrintAncStatesAA (curS[coldId], coldId, numChars, numRateCats, n); UpDateAllCls (0, coldId); if (LnLikeAA (0, coldId, numChars, numRateCats, &x, YES) == ERROR) goto error_exit; UpDateAllCls (1, coldId); if (LnLikeAA (1, coldId, numChars, numRateCats, &x, YES) == ERROR) goto error_exit; } } if (inferPoseSel == YES && n >= mcmcBurn) { if ((dataType == DNA || dataType == RNA) && enforceCodonModel == YES && (!strcmp(codonModelType, "ny98") || !strcmp(codonModelType, "ac1ny98") || !strcmp(codonModelType, "ac2ny98"))) { PrintPosSelProbs (curS[coldId], coldId, numChars, numRateCats, n); } } if (inferRates == YES && nExcluded == 0 && n >= mcmcBurn) { if (((dataType == DNA || dataType == RNA) && enforceCodonModel == NO) || dataType == PROTEIN) { PrintRateFactors (curS[coldId], coldId, numChars, numRateCats, n); } } else if (inferRates == YES && nExcluded > 0 && n == 1 && n >= mcmcBurn) { printf (" Warning: You requested that site rates be estimated. However, this option\n"); printf (" does not currently work when sites are excluded. Site rates will not\n"); printf (" be estimated in this run.\n"); } } } endingT = time(NULL); endCPUTime = clock(); printf (" Chain completed in %1.0f seconds\n", difftime (endingT, startingT)); printf (" Chain used %1.2f seconds of CPU time\n", (endCPUTime - startCPUTime)/(float)CLOCKS_PER_SEC); printf (" Acceptance rates for proposal mechanisms\n"); for (i=0; i 0) printf (" %1.2lf percent of the time accepted %s\n", ((double)nAccepted[i]/nProposed[i])*100.0, proposalName[i]); } if (nSwapsProposed > 0) { printf (" %1.2lf percent of the time accepted a swap of the states for two chains\n", ((double)nSwapsAccepted/nSwapsProposed)*100.0); } # if defined (TOPOLOGY_MOVE_STATS) printf (" Detailed statistics for moves that change tree topology\n"); for (i = 0; i 0) printf (" %1.2f percent of proposed topology changes were accepted\n", (float)nAcceptedTopology[i]/(float)nProposedTopology[i] * 100.0); printf (" Proposed topology changes by definition break 1 partition\n"); break; case CHANGE_TREE_SPR: case CHANGE_WORM: case CHANGE_UNROOT_TBR: case CHANGE_TREE_FTBR: printf (" %s\n", proposalName[i]); printf (" %d moves were proposed\n", nProposed[i]); printf (" %d moves were accepted\n",nAccepted[i]); printf (" %d topology changes were proposed\n",nProposedTopology[i]); printf (" %d topology changes were accepted\n",nAcceptedTopology[i]); if (nProposedTopology[i] > 0) { printf (" %1.2f percent of proposed topology changes were accepted\n", (float)nAcceptedTopology[i]/(float)nProposedTopology[i] * 100.0); printf (" Proposed topology changes on average broke %f partitions\n", (float)nProposedNodes[i] / (float)nProposedTopology[i]); if (nAcceptedTopology[i] > 0) { printf (" Accepted topology changes on average broke %f partitions\n", nAcceptedNodes[i] / (float)nAcceptedTopology[i]); } } } } # endif # if defined (MORPH) if (numDummyChars > 0) { printf (" Probability of unobserved characters in ending state of chain"); LnLike (curS[coldId], coldId, numChars, numRateCats, &x, YES); printf (": %1.8f\n",1.0 - pObserved); } # endif /* free memory and leave */ free (lnL); free (curS); free (newS); free (chainTempId); if (enforceCalibrations == YES) { free (constrainedNodes); free (calibratedNodes); } /* close output files */ fclose (pFile); fclose (bpFile); fclose (tFile); return (NO_ERROR); error_exit: free (lnL); free (curS); free (newS); free (chainTempId); if (enforceCalibrations == YES) { free (constrainedNodes); free (calibratedNodes); } /* close output files */ if (pFile != NULL) fclose (pFile); if (bpFile != NULL) fclose (bpFile); if (tFile != NULL) fclose (tFile); printf ("\n ERROR: Problem running Markov chain\n"); return (ERROR); } int MarkovChainPars (int numTaxa, int numChars, long int *seed) { int i, n, chain, *curS, *newS, acceptMove, chain1, chain2, tempInt, *chainTempId, tempId, coldId, nHours, nMins, nSecs; double *lnL, lnR, lnLikelihoodRatio, lnPriorRatio, lnProposalRatio, r, sum, timePerGen, nk, lnK; time_t startingT, endingT, stoppingT1, stoppingT2; clock_t startCPUTime, endCPUTime; FILE *fp1, *fp2; /* get number of characters */ nk = 0.0; for (i=0; i %lf\n", lnL[chain*2+curS[chain]], lnL[chain*2+newS[chain]]); /* heat */ lnLikelihoodRatio *= (1.0 / (1.0 + chainTemp*(double)chainTempId[chain])); lnPriorRatio *= (1.0 / (1.0 + chainTemp*(double)chainTempId[chain])); /* calculate the acceptance probability */ if (lnLikelihoodRatio + lnPriorRatio + lnProposalRatio < -100.0) r = 0.0; else if (lnLikelihoodRatio + lnPriorRatio + lnProposalRatio > 0.0) r = 1.0; else r = exp(lnLikelihoodRatio + lnPriorRatio + lnProposalRatio); /* decide to accept or reject the move */ acceptMove = NO; if (RandomNumber(seed) < r) acceptMove = YES; /* update the chain */ if (acceptMove == YES) { curS[chain] = newS[chain]; if (curS[chain] == 1) newS[chain] = 0; else newS[chain] = 1; } lnL[chain*2 + newS[chain]] = lnL[chain*2 + curS[chain]]; CopyTree (curS[chain], newS[chain], chain); } /* attemp to swap states for two chains */ if (numChains > 1) { chain1 = RandomNumber(seed) * numChains; do { chain2 = RandomNumber(seed) * numChains; } while (chain1 == chain2); lnR = (1.0 / (1.0 + chainTemp*(double)chainTempId[chain1])) * (-(lnL[chain2*2 + curS[chain2]] + nk) * lnK); lnR += (1.0 / (1.0 + chainTemp*(double)chainTempId[chain2])) * (-(lnL[chain1*2 + curS[chain1]] + nk) * lnK); lnR -= (1.0 / (1.0 + chainTemp*(double)chainTempId[chain1])) * (-(lnL[chain1*2 + curS[chain1]] + nk) * lnK); lnR -= (1.0 / (1.0 + chainTemp*(double)chainTempId[chain2])) * (-(lnL[chain2*2 + curS[chain2]] + nk) * lnK); if (lnR < -100.0) r = 0.0; else if (lnR > 0.0) r = 1.0; else r = exp(lnR); acceptMove = NO; if (RandomNumber(seed) < r) { acceptMove = YES; } if (acceptMove == YES) { tempId = chainTempId[chain1]; chainTempId[chain1] = chainTempId[chain2]; chainTempId[chain2] = tempId; } /* print update to screen */ endingT = time(NULL); if (n % printFreq == 0) { timePerGen = (double)(difftime (endingT, startingT) / n); nSecs = (int)((nGen - n) * timePerGen); nHours = (int)nSecs / 3600; nSecs -= nHours * 3600; nMins = nSecs / 60; nSecs -= nMins * 60; printf (" %4d -- ", n); sum = 0.0; for (chain=0; chain 9) printf ("%d:", nMins); else printf ("0%d:", nMins); if (nSecs > 9) printf ("%d", nSecs); else printf ("0%d", nSecs); if (acceptMove == YES) printf (" (%d~%d)\n", chain1+1, chain2+1); else printf ("\n"); } } else { endingT = time(NULL); /* print update to screen */ if (n % printFreq == 0) { timePerGen = (double)(difftime (endingT, startingT) / n); nSecs = (int)((nGen - n) * timePerGen); nHours = (int)nSecs / 3600; nSecs -= nHours * 3600; nMins = nSecs / 60; nSecs -= nMins * 60; printf (" %4d -- %1.2lf ", n, lnL[curS[0]]); printf ("-- %d:", nHours); if (nMins > 9) printf ("%d:", nMins); else printf ("0%d:", nMins); if (nSecs > 9) printf ("%d\n", nSecs); else printf ("0%d\n", nSecs); } } /* check to see if we should continue chain */ if (n == nGen && autoclose == NO) { stoppingT1 = time(NULL); printf ("\n Continue with chain? (yes/no): "); if (YesNo() == YES) { tempInt = 0; do { if (tempInt < 0) printf (" Number must be greater than or equal to 0: "); else printf (" Additional number of generations: "); tempInt = (int)EnterNum (); } while (tempInt < 0); nGen += tempInt; } printf ("\n"); stoppingT2 = time(NULL); startingT -= (stoppingT2 - stoppingT1); } /* print states to file */ if (n % sampleFreq == 0 || n == 1 || n == nGen) { for (i=0; ileft, q); MarkPathDown (p->right, q); p->flag = NO; if (p == q) { p->flag = YES; } if (p->left != NULL && p->right != NULL) { if (p->left->flag == YES || p->right->flag == YES) p->flag = YES; } else if (p->left != NULL && p->right == NULL) { if (p->left->flag == YES) p->flag = YES; } /*printf ("node %d %d\n", p->index, p->flag);*/ } } /* change auto correlation parameter */ int Move_ChangeAutoCorr (int proposedState, int whichChain, long int *seed, double *lnPriorRatio) { int whichToChange; double oldP, newP, ran, pSlide, minP, maxP; minP = chainMins[CHANGE_AUTO_CORR]; maxP = chainMaxs[CHANGE_AUTO_CORR]; pSlide = rhoWinProp; if (allocatedMemory[ALLOC_AUTO_GAMMA2] == NO) { oldP = rateCorrelation[whichChain*2 + proposedState]; ran = (RandomNumber(seed) * pSlide) - (pSlide/2.0); newP = oldP + ran; if (newP < minP) newP = (minP - newP) + minP; if (newP > maxP) newP = maxP - (newP - maxP); rateCorrelation[whichChain*2 + proposedState] = newP; } else { whichToChange = RandomNumber(seed) * 3; if (whichToChange == 0) { oldP = rateCorrelation[whichChain*2 + proposedState]; ran = (RandomNumber(seed) * pSlide) - (pSlide/2.0); newP = oldP + ran; if (newP < minP) newP = (minP - newP) + minP; if (newP > maxP) newP = maxP - (newP - maxP); rateCorrelation[whichChain*2 + proposedState] = newP; } else { oldP = rateCorrelation2[whichChain*4 + proposedState*2 + (whichToChange-1)]; ran = (RandomNumber(seed) * pSlide) - (pSlide/2.0); newP = oldP + ran; if (newP < minP) newP = (minP - newP) + minP; if (newP > maxP) newP = maxP - (newP - maxP); rateCorrelation2[whichChain*4 + proposedState*2 + (whichToChange-1)] = newP; } } /* set prior ratio */ (*lnPriorRatio) = 0.0; UpDateAllCls (proposedState, whichChain); # if defined (SMART_TI_PROBS) UpDateAllTIs (proposedState, whichChain); # endif return (NO_ERROR); } /* change pi */ int Move_ChangeBaseFreqs (int proposedState, int whichChain, long int *seed, double *lnPriorRatio, double *lnProposalRatio) { int i; double *dirichletParameters, *newPi, *oldPi, sum, alphaPi, priorPi, x, y, oneOverS; oneOverS = 1.0 / nStates; dirichletParameters = (double *)malloc((size_t) (nStates * sizeof(double))); if (!dirichletParameters) goto error_exit; newPi = (double *)malloc((size_t) (nStates * sizeof(double))); if (!newPi) goto error_exit; oldPi = (double *)malloc((size_t) (nStates * sizeof(double))); if (!oldPi) goto error_exit; alphaPi = piAlphaProp; priorPi = basefreqprDir; for (i=0; i maxP) newP = maxP - (newP - maxP); // set new value statefreqP[whichChain*2 + proposedState] = newP; /* set prior ratio */ // this is only for uniform prior, exponential prior also reasonable? (*lnPriorRatio) = 0.0; UpDateAllCls (proposedState, whichChain); # if defined (SMART_TI_PROBS) // SMART_TI_PROBS not implemented for binary and restriction data? UpDateAllTIs (proposedState, whichChain); # endif return (NO_ERROR); } #endif /* change branch lengths and topology (potentially) using eraser */ #undef MULTIPLE_BR_HIT int Move_ChangeEraser (int numTaxa, int proposedState, int whichChain, long int *seed, double *lnProposalRatio, double *lnPriorRatio) { int i, j, topologyHasChanged; double ran, tuning, # if !defined (MULTIPLE_BR_HIT) rndUM[5], oldM, newM, # endif lnOldBrlenPr,lnNewBrlenPr; TreeNode *p, *a, *b, *c, *d, *u, *v; tuning = tuningProp; topologyHasChanged = NO; # if defined (DEBUG_ERASER) printf ("Before:\n"); ShowNodes (root[whichChain*2+proposedState], 2, NO); # endif /* set all updates to "NO" */ for (i=0; iupDateCl = NO; } /* initialize proposal ratio to 0.0 */ (*lnProposalRatio) = 0.0; lnNewBrlenPr = lnOldBrlenPr = 0.0; /* pick an internal branch */ do { p = intNodeDownPassSeq[whichChain*2*numIntNodes + proposedState*numIntNodes + (int)(RandomNumber(seed)*numIntNodes)]; } while (p->anc->anc == NULL); if (!strcmp(clockModel, "unconstrained") && treeModel == UNROOTED) { /* if tree is unrooted and the branch lengths are unconstrained */ u = p; v = p->anc; a = p->left; b = p->right; c = v->anc; if (v->left == u) d = v->right; else d = v->left; # if !defined (MULTIPLE_BR_HIT) oldM = a->length + b->length + u->length + d->length + v->length; newM = oldM * exp(tuning *(RandomNumber(seed) - 0.5)); # endif if (!strcmp(brlenprModel, "exponential")) { lnOldBrlenPr = log(brlenprExp) - brlenprExp * (a->length); lnOldBrlenPr += log(brlenprExp) - brlenprExp * (b->length); lnOldBrlenPr += log(brlenprExp) - brlenprExp * (u->length); lnOldBrlenPr += log(brlenprExp) - brlenprExp * (d->length); lnOldBrlenPr += log(brlenprExp) - brlenprExp * (v->length); } # if defined (MULTIPLE_BR_HIT) (*lnProposalRatio) -= (a->length + b->length + u->length + d->length + v->length); a->length *= exp(tuning * (RandomNumber(seed) - 0.5)); b->length *= exp(tuning * (RandomNumber(seed) - 0.5)); u->length *= exp(tuning * (RandomNumber(seed) - 0.5)); d->length *= exp(tuning * (RandomNumber(seed) - 0.5)); v->length *= exp(tuning * (RandomNumber(seed) - 0.5)); (*lnProposalRatio) += (a->length + b->length + u->length + d->length + v->length); # else for (i=0; i<4; i++) rndUM[i] = RandomNumber(seed) * newM; SortVector (rndUM, 4); a->length = rndUM[0]; b->length = rndUM[1] - rndUM[0]; u->length = rndUM[2] - rndUM[1]; d->length = rndUM[3] - rndUM[2]; v->length = newM - rndUM[3]; # endif if (u->isConstrained == YES || v->isConstrained == YES) ran = 1.0; else ran = RandomNumber(seed); if (ran < 0.333) { u->left = a; u->right = d; a->anc = d->anc = u; v->left = u; v->right = b; u->anc = b->anc = v; topologyHasChanged = YES; } else if (ran >= 0.333 && ran < 0.666) { u->left = b; u->right = d; b->anc = d->anc = u; v->left = u; v->right = a; u->anc = a->anc = v; topologyHasChanged = YES; } if (!strcmp(brlenprModel, "exponential")) { lnNewBrlenPr = log(brlenprExp) - brlenprExp * (a->length); lnNewBrlenPr += log(brlenprExp) - brlenprExp * (b->length); lnNewBrlenPr += log(brlenprExp) - brlenprExp * (u->length); lnNewBrlenPr += log(brlenprExp) - brlenprExp * (d->length); lnNewBrlenPr += log(brlenprExp) - brlenprExp * (v->length); } # if !defined (MULTIPLE_BR_HIT) (*lnProposalRatio) = 5.0 * (log(newM) - log(oldM)); # endif a->upDateCl = YES; b->upDateCl = YES; u->upDateCl = YES; d->upDateCl = YES; v->upDateCl = YES; c->upDateCl = YES; p = c; while (p->anc != NULL) { p = p->anc; p->upDateCl = YES; } # if defined (SMART_TI_PROBS) a->upDateTi = YES; b->upDateTi = YES; u->upDateTi = YES; d->upDateTi = YES; v->upDateTi = YES; # endif } /* get down pass sequence if tree topology has changed */ if (topologyHasChanged == YES) { i = j = 0; GetDownPassSeq (root[whichChain*2 + proposedState], proposedState, whichChain, numTaxa, &i, &j); } # if defined (DEBUG_ERASER) printf ("After:\n"); ShowNodes (root[whichChain*2+proposedState], 2, NO); # endif (*lnPriorRatio) = lnNewBrlenPr - lnOldBrlenPr; # if defined (TOPOLOGY_MOVE_STATS) if (topologyHasChanged == YES) gTopologyHasChanged = YES; else gTopologyHasChanged = NO; gNodeMoves = 1; # endif # if defined (SMART_TI_PROBS) UpDateAllTIs (proposedState, whichChain); # endif return (NO_ERROR); } /* change gc switch params */ int Move_ChangeGCSwitch (int proposedState, int whichChain, long int *seed, double *lnPriorRatio, double *lnProposalRatio) { double ran, ran1, maxP, minP, newP, oldP, pSlide; ran1 = RandomNumber(seed); if (ran1 < 0.25) { minP = 0.0; maxP = 0.5; pSlide = 0.1; oldP = gc1[whichChain*2 + proposedState]; ran = (RandomNumber(seed) * pSlide) - (pSlide/2.0); newP = oldP + ran; if (newP < minP) newP = (minP - newP) + minP; if (newP > maxP) newP = maxP - (newP - maxP); gc1[whichChain*2 + proposedState] = newP; } else if (ran1 >= 0.25 && ran1 < 0.50) { minP = 0.5; maxP = 1.0; pSlide = 0.1; oldP = gc2[whichChain*2 + proposedState]; ran = (RandomNumber(seed) * pSlide) - (pSlide/2.0); newP = oldP + ran; if (newP < minP) newP = (minP - newP) + minP; if (newP > maxP) newP = maxP - (newP - maxP); gc2[whichChain*2 + proposedState] = newP; } else if (ran1 >= 0.50 && ran1 < 0.75) { minP = 0.0; maxP = 1.0; pSlide = 0.1; oldP = fracA[whichChain*2 + proposedState]; ran = (RandomNumber(seed) * pSlide) - (pSlide/2.0); newP = oldP + ran; if (newP < minP) newP = (minP - newP) + minP; if (newP > maxP) newP = maxP - (newP - maxP); fracA[whichChain*2 + proposedState] = newP; } else { minP = 0.0; maxP = 1.0; pSlide = 0.1; oldP = fracG[whichChain*2 + proposedState]; ran = (RandomNumber(seed) * pSlide) - (pSlide/2.0); newP = oldP + ran; if (newP < minP) newP = (minP - newP) + minP; if (newP > maxP) newP = maxP - (newP - maxP); fracG[whichChain*2 + proposedState] = newP; } (*lnPriorRatio) = (*lnProposalRatio) = 0.0; UpDateAllCls (proposedState, whichChain); # if defined (SMART_TI_PROBS) UpDateAllTIs (proposedState, whichChain); # endif return (NO_ERROR); } /* change branch lengths and topology (potentially) using BAMBE's LOCAL (unrooted) */ int Move_ChangeClockWithLocal (int numTaxa, int proposedState, int whichChain, long int *seed, double *lnProposalRatio, double *lnPriorRatio) { int i, j, topologyHasChanged, isAtRoot, isTreeConstrained, isForcedBackMove, isForcedForwardMove, dID[3], dTemp; double ran, x, tuning, y, dAW, dBW, dCW, dAV, dBV, dCV, h[3], oldH1, newH1, temp, newDAW, newDBW, newDCW, newDAV, newDBV, newDCV, lnNewBrlenPr, lnOldBrlenPr, *nt, rootTime, sR, eR, sF; TreeNode *p, *q, *a, *b, *c, *u, *v, *w; lnNewBrlenPr = lnOldBrlenPr = 0.0; if (!strcmp(brlenprModel, "exponential")) { for (i=0; ilength); } } else if (!strcmp(brlenprModel, "birth-death")) { sR = spRate[whichChain*2 + proposedState]; eR = exRate[whichChain*2 + proposedState]; sF = samplingFraction; /* allocate memory */ nt = (double *)malloc((size_t) (numTaxa-1) * sizeof(double)); if (!nt) { printf ("\n ERROR: Problem allocating nt\n"); return (ERROR); } /* get node times */ for (i=0; ileft == NULL && q->right == NULL) q->nodeTime = 0.0; else q->nodeTime += q->left->nodeTime + q->left->length; } rootTime = root[whichChain*2+proposedState]->left->nodeTime; for (i=0; ileft == NULL && q->right == NULL) q->nodeTime = 0.0; else q->nodeTime /= rootTime; } /* put node times into vector */ j = 0; for (i=0; ileft != NULL && q->right != NULL && q->anc != NULL) { nt[j] = q->nodeTime; j++; } } /* calculate probabilities of tree */ lnOldBrlenPr = (numTaxa-2)*log(sR); for (i=0; iupDateCl = NO; } (*lnProposalRatio) = 0.0; /* pick an internal branch */ do { p = intNodeDownPassSeq[whichChain*2*numIntNodes + proposedState*numIntNodes + (int)(RandomNumber(seed)*numIntNodes)]; } while (p->anc->anc == NULL); isTreeConstrained = NO; if (p->isConstrained == YES) isTreeConstrained = YES; isAtRoot = NO; if (p->anc->anc->anc == NULL) isAtRoot = YES; if (isAtRoot == NO) { /* initialize pointers */ u = p; v = u->anc; w = v->anc; a = u->left; b = u->right; if (v->left == u) c = v->right; else c = v->left; dAW = a->length + u->length + v->length; dBW = b->length + u->length + v->length; dCW = c->length + v->length; h[0] = dAW; h[1] = dBW; h[2] = dCW; dID[0] = 0; dID[1] = 1; dID[2] = 2; if (h[0] > h[1]) { temp = h[0]; h[0] = h[1]; h[1] = temp; dTemp = dID[0]; dID[0] = dID[1]; dID[1] = dTemp; } if (h[0] > h[2]) { temp = h[0]; h[0] = h[2]; h[2] = temp; dTemp = dID[0]; dID[0] = dID[2]; dID[2] = dTemp; } if (h[1] > h[2]) { temp = h[1]; h[1] = h[2]; h[2] = temp; dTemp = dID[1]; dID[1] = dID[2]; dID[2] = dTemp; } for (i=0; i<3; i++) { if (dID[i] == 0) newDAW = h[i]; else if (dID[i] == 1) newDBW = h[i]; else newDCW = h[i]; } # if defined (DEBUG_LOCAL_CLOCK) printf ("newDAW = %lf newDBW = %lf newDCW = %lf\n", newDAW, newDBW, newDCW); # endif if (isTreeConstrained == NO) { x = RandomNumber(seed) * h[0]; y = RandomNumber(seed) * h[1]; if (y > x) { temp = y; y = x; x = temp; } } else { if (dAW < dBW) temp = dAW; else temp = dBW; x = RandomNumber(seed) * temp; if (dCW < temp) y = RandomNumber(seed) * dCW; else y = RandomNumber(seed) * temp; if (y > x) { temp = y; y = x; x = temp; } } # if defined (DEBUG_LOCAL_CLOCK) printf ("x = %lf y = %lf\n", x, y); # endif if (isTreeConstrained == NO) { /* tree is not constrained at u */ if (x < h[0]) { /* topology is free to vary */ ran = RandomNumber(seed); if (ran <= 0.3333) { a->anc = b->anc = u; u->left = a; u->right = b; v->left = u; v->right = c; c->anc = v; a->length = newDAW - x; b->length = newDBW - x; c->length = newDCW - y; u->length = x - y; v->length = y; } else if (ran > 0.3333 && ran <= 0.6666) { a->anc = c->anc = u; u->left = a; u->right = c; v->left = u; v->right = b; b->anc = v; a->length = newDAW - x; c->length = newDCW - x; b->length = newDBW - y; u->length = x - y; v->length = y; } else { b->anc = c->anc = u; u->left = b; u->right = c; v->left = u; v->right = a; a->anc = v; b->length = newDBW - x; c->length = newDCW - x; a->length = newDAW - y; u->length = x - y; v->length = y; } } else { /* topology forced */ if (dID[0] == 0) { /* a + b */ b->anc = c->anc = u; u->left = b; u->right = c; v->left = u; v->right = a; a->anc = v; b->length = newDBW - x; c->length = newDCW - x; a->length = newDAW - y; u->length = x - y; v->length = y; } else if (dID[0] == 1) { /* a + c */ a->anc = c->anc = u; u->left = a; u->right = c; v->left = u; v->right = b; b->anc = v; a->length = newDAW - x; c->length = newDCW - x; b->length = newDBW - y; u->length = x - y; v->length = y; } else { /* b + c */ a->anc = b->anc = u; u->left = a; u->right = b; v->left = u; v->right = c; c->anc = v; a->length = newDAW - x; b->length = newDBW - x; c->length = newDCW - y; u->length = x - y; v->length = y; } } /* get hastings ratio here */ if (u->length > c->length && x < h[0]) (*lnProposalRatio) += log(3.0); else if (u->length < c->length && x > h[0]) (*lnProposalRatio) += log(1.0/3.0); else (*lnProposalRatio) += 0.0; } else { /* tree is constrained at u */ a->length = newDAW - x; b->length = newDBW - x; c->length = newDCW - y; u->length = x - y; v->length = y; } # if defined (SMART_TI_PROBS) a->upDateTi = YES; b->upDateTi = YES; u->upDateTi = YES; c->upDateTi = YES; v->upDateTi = YES; # endif } else { /* deal with root of tree differently if this is a rooted and uncontrained tree */ /* initialize pointers */ u = p; v = p->anc; a = u->left; b = u->right; if (v->left == u) c = v->right; else c = v->left; /* v is at root of tree */ if (u->length < c->length) isForcedBackMove = NO; else isForcedBackMove = YES; dAV = a->length + u->length; dBV = b->length + u->length; dCV = c->length; if (dAV < dBV && dAV < dCV) oldH1 = dAV; else if (dBV < dAV && dBV < dCV) oldH1 = dBV; else oldH1 = dCV; tuning = clockTuneProp; newH1 = oldH1 * exp(tuning*(RandomNumber(seed) - 0.5)); dAV = dAV + (newH1 - oldH1); dBV = dBV + (newH1 - oldH1); dCV = dCV + (newH1 - oldH1); h[0] = dAV; h[1] = dBV; h[2] = dCV; dID[0] = 0; dID[1] = 1; dID[2] = 2; if (h[0] > h[1]) { temp = h[0]; h[0] = h[1]; h[1] = temp; dTemp = dID[0]; dID[0] = dID[1]; dID[1] = dTemp; } if (h[0] > h[2]) { temp = h[0]; h[0] = h[2]; h[2] = temp; dTemp = dID[0]; dID[0] = dID[2]; dID[2] = dTemp; } if (h[1] > h[2]) { temp = h[1]; h[1] = h[2]; h[2] = temp; dTemp = dID[1]; dID[1] = dID[2]; dID[2] = dTemp; } for (i=0; i<3; i++) { if (dID[i] == 0) newDAV = h[i]; else if (dID[i] == 1) newDBV = h[i]; else newDCV = h[i]; } # if defined (DEBUG_LOCAL_CLOCK) printf ("h[0] = %lf h[1] = %lf h[2] = %lf (%d %d %d)\n", h[0], h[1], h[2], dID[0], dID[1], dID[2]); printf ("x = %lf\n", x); # endif (*lnProposalRatio) += 2.0 * (log(newH1) - log(oldH1)); if (isTreeConstrained == NO) x = RandomNumber(seed) * h[1]; else { if (newDAV < newDBV) x = RandomNumber(seed) * newDAV; else x = RandomNumber(seed) * newDBV; } if (isTreeConstrained == NO) { /* tree is not constrained */ if (x > h[0]) { isForcedForwardMove = YES; if (dID[0] == 0) { /* a is shortest, (b,c) forced */ u->left = b; u->right = c; u->anc = v; a->anc = v; b->anc = u; c->anc = u; v->left = a; v->right = u; u->length = x; a->length = dAV; b->length = dBV - x; c->length = dCV - x; } else if (dID[0] == 1) { /* b is shortest, (a,c) forced */ u->left = a; u->right = c; u->anc = v; a->anc = u; b->anc = v; c->anc = u; v->left = b; v->right = u; u->length = x; a->length = dAV - x; b->length = dBV; c->length = dCV - x; } else { /* c is shortest, (a,b) forced */ u->left = a; u->right = b; u->anc = v; a->anc = u; b->anc = u; c->anc = v; v->left = c; v->right = u; u->length = x; a->length = dAV - x; b->length = dBV - x; c->length = dCV; } } else { isForcedForwardMove = NO; ran = RandomNumber(seed); if (ran <= 0.33333) { /* a with c */ u->right = c; b->anc = v; c->anc = u; if (v->left == u) v->right = b; else v->left = b; u->length = x; a->length = newDAV - x; b->length = newDBV; c->length = newDCV - x; } else if (ran > 0.33333 && ran <= 0.66666) { /* b with c */ u->left = c; a->anc = v; c->anc = u; if (v->left == u) v->right = a; else v->left = a; a->length += u->length; c->length -= u->length; u->length = x; a->length = newDAV; b->length = newDBV - x; c->length = newDCV - x; } else { /* no change */ u->length = x; a->length = newDAV - x; b->length = newDBV - x; c->length = newDCV; } } /* get hastings ratio here */ if (isForcedForwardMove == NO && isForcedBackMove == YES) (*lnProposalRatio) += log(3.0); else if (isForcedForwardMove == YES && isForcedBackMove == NO) (*lnProposalRatio) += log(1.0/3.0); } else { /* tree is constrained at node u */ u->length = x; a->length = dAV - x; b->length = dBV - x; c->length = dCV; } # if defined (SMART_TI_PROBS) a->upDateTi = YES; b->upDateTi = YES; u->upDateTi = YES; c->upDateTi = YES; # endif } p = u; while (p->anc != NULL) { p->upDateCl = YES; p = p->anc; } topologyHasChanged = YES; /* get down pass sequence if tree topology has changed */ if (topologyHasChanged == YES) { i = j = 0; GetDownPassSeq (root[whichChain*2 + proposedState], proposedState, whichChain, numTaxa, &i, &j); } # if defined (DEBUG_LOCAL_CLOCK) printf ("After:\n"); ShowNodes (root[whichChain*2+proposedState], 2, YES); # endif if (!strcmp(brlenprModel, "exponential")) { for (i=0; ilength); } } else if (!strcmp(brlenprModel, "birth-death")) { /* get node times */ for (i=0; ileft == NULL && q->right == NULL) q->nodeTime = 0.0; else q->nodeTime += q->left->nodeTime + q->left->length; } rootTime = root[whichChain*2+proposedState]->left->nodeTime; for (i=0; ileft == NULL && q->right == NULL) q->nodeTime = 0.0; else q->nodeTime /= rootTime; } /* put node times into vector */ j = 0; for (i=0; ileft != NULL && q->right != NULL && q->anc != NULL) { nt[j] = q->nodeTime; j++; } } /* calculate probabilities of tree */ lnNewBrlenPr = (numTaxa-2)*log(sR); for (i=0; i maxAlpha) newA = maxAlpha - (newA - maxAlpha); alpha[whichChain*2 + proposedState] = newA; /* set prior ratio */ if (!strcmp(qmatprModel, "exponential")) (*lnPriorRatio) = (shapeprExp*oldA - shapeprExp*newA); else if (!strcmp(qmatprModel, "uniform")) (*lnPriorRatio) = 0.0; UpDateAllCls (proposedState, whichChain); # if defined (SMART_TI_PROBS) UpDateAllTIs (proposedState, whichChain); # endif return (NO_ERROR); } /* change lag parameter */ int Move_ChangeLag (int proposedState, int whichChain, long int *seed, double *lnPriorRatio, double *lnProposalRatio) { int minLag, maxLag, oldLag, newLag, jumpSize; double ran; minLag = (int)chainMins[CHANGE_LAG]; maxLag = (int)chainMaxs[CHANGE_LAG]; # if 0 if (oldLag == 1) { newLag = 2; (*lnProposalRatio) = log(0.5); } else if (oldLag == maxLag) { newLag = maxLag - 1; (*lnProposalRatio) = log(0.5); } else { if (RandomNumber(seed) < 0.5) newLag = oldLag + 1; else newLag = oldLag - 1; (*lnProposalRatio) = 0.0; } if (newLag == 1) (*lnProposalRatio) = log(2.0); else if (newLag == maxLag) (*lnProposalRatio) = log(2.0); lag[whichChain*2 + proposedState] = newLag; # else ran = RandomNumber(seed); if (ran <= (5.0 / 15.0)) jumpSize = 1; else if (ran > (5.0 / 15.0) && ran <= (9.0 / 15.0)) jumpSize = 2; else if (ran > (9.0 / 15.0) && ran <= (12.0 / 15.0)) jumpSize = 3; else if (ran > (12.0 / 15.0) && ran <= (14.0 / 15.0)) jumpSize = 4; else jumpSize = 5; oldLag = lag[whichChain*2 + proposedState]; if (oldLag - jumpSize < 1) { newLag = oldLag + jumpSize; (*lnProposalRatio) = log(0.5); } else if (oldLag + jumpSize > maxLag) { newLag = oldLag - jumpSize; (*lnProposalRatio) = log(0.5); } else { if (RandomNumber(seed) < 0.5) newLag = oldLag + jumpSize; else newLag = oldLag - jumpSize; (*lnProposalRatio) = 0.0; } if (newLag <= jumpSize) (*lnProposalRatio) = log(2.0); else if (newLag > maxLag - jumpSize) (*lnProposalRatio) = log(2.0); lag[whichChain*2 + proposedState] = newLag; # endif /* set prior ratio */ (*lnPriorRatio) = 0.0; if (!strcmp(lagprModel, "exponential")) { (*lnPriorRatio) = log(exp(-(newLag-0.5)) - exp(-(newLag+0.5))); (*lnPriorRatio) -= log(exp(-(oldLag-0.5)) - exp(-(oldLag+0.5))); } UpDateAllCls (proposedState, whichChain); # if defined (SMART_TI_PROBS) UpDateAllTIs (proposedState, whichChain); # endif return (NO_ERROR); } /* change Q matrix */ int Move_ChangeQMatrix (int proposedState, int whichChain, long int *seed, double *lnPriorRatio) { int param; double oldK, newK, ran, kappaSlide, minKappa, maxKappa; if (!strcmp(qmatprModel, "exponential")) { minKappa = 0.0000001; maxKappa = 1000.0; } else if (!strcmp(qmatprModel, "uniform")) { minKappa = qmatprUni[0]; maxKappa = qmatprUni[1]; } kappaSlide = qMatWinProp; if ((dataType == DNA || dataType == RNA) && enforceCodonModel == NO) { if (nst == 2) { oldK = kappa[whichChain*2 + proposedState]; ran = (RandomNumber(seed) * kappaSlide) - (kappaSlide/2.0); newK = oldK + ran; if (newK < minKappa) newK = (minKappa - newK) + minKappa; if (newK > maxKappa) newK = maxKappa - (newK - maxKappa); kappa[whichChain*2 + proposedState] = newK; } else if (nst == 6) { ran = RandomNumber(seed); if (ran > 0 && ran <= 0.2) param = 1; else if (ran > 0.2 && ran <= 0.4) param = 2; else if (ran > 0.4 && ran <= 0.6) param = 3; else if (ran > 0.6 && ran <= 0.8) param = 4; else if (ran > 0.8 && ran <= 1.0) param = 5; oldK = subParams[whichChain*12 + proposedState*6 + param]; ran = (RandomNumber(seed) * kappaSlide) - (kappaSlide/2.0); newK = oldK + ran; if (newK < 0.0) newK = -newK; if (newK > maxKappa) newK = maxKappa - (newK - maxKappa); subParams[whichChain*12 + proposedState*6 + param] = newK; } else if (nst == 12) { ran = RandomNumber(seed); if (ran > 0.0 && ran <= 1.0/11.0) param = 1; else if (ran > 1.0/11.0 && ran <= 2.0/11.0) param = 2; else if (ran > 2.0/11.0 && ran <= 3.0/11.0) param = 3; else if (ran > 3.0/11.0 && ran <= 4.0/11.0) param = 4; else if (ran > 4.0/11.0 && ran <= 5.0/11.0) param = 5; else if (ran > 5.0/11.0 && ran <= 6.0/11.0) param = 6; else if (ran > 6.0/11.0 && ran <= 7.0/11.0) param = 7; else if (ran > 7.0/11.0 && ran <= 8.0/11.0) param = 8; else if (ran > 8.0/11.0 && ran <= 9.0/11.0) param = 9; else if (ran > 9.0/11.0 && ran <= 10.0/11.0) param = 10; else if (ran > 10.0/11.0 && ran <= 1.0) param = 11; oldK = subParams[whichChain*24 + proposedState*12 + param]; ran = (RandomNumber(seed) * kappaSlide) - (kappaSlide/2.0); newK = oldK + ran; if (newK < 0.0) newK = -newK; if (newK > maxKappa) newK = maxKappa - (newK - maxKappa); subParams[whichChain*24 + proposedState*12 + param] = newK; } else { printf ("\n ERROR: Should not be in this move\n"); return (ERROR); } } else if ((dataType == DNA || dataType == RNA) && enforceCodonModel == YES) { oldK = kappa[whichChain*2 + proposedState]; ran = (RandomNumber(seed) * kappaSlide) - (kappaSlide/2.0); newK = oldK + ran; if (newK < minKappa) newK = (minKappa - newK) + minKappa; if (newK > maxKappa) newK = maxKappa - (newK - maxKappa); kappa[whichChain*2 + proposedState] = newK; } else if (dataType == PROTEIN) { param = RandomNumber(seed) * 189; param++; if (param < 1 || param >= 190) { printf ("\n ERROR: parameter to be changed is invalid \n"); return (ERROR); } oldK = subParams[whichChain*2*190 + proposedState*190 + param]; ran = (RandomNumber(seed) * kappaSlide) - (kappaSlide/2.0); newK = oldK + ran; if (newK < 0.0) newK = -newK; if (newK > maxKappa) newK = maxKappa - (newK - maxKappa); subParams[whichChain*2*190 + proposedState*190 + param] = newK; } else if (dataType == RESTRICTION) { oldK = kappa[whichChain*2 + proposedState]; ran = (RandomNumber(seed) * kappaSlide) - (kappaSlide/2.0); newK = oldK + ran; if (newK < minKappa) newK = (minKappa - newK) + minKappa; if (newK > maxKappa) newK = maxKappa - (newK - maxKappa); kappa[whichChain*2 + proposedState] = newK; //kappa[whichChain*2 + proposedState] = 1.0; } /* set prior ratio */ if (!strcmp(qmatprModel, "exponential")) (*lnPriorRatio) = (qmatprExp*oldK - qmatprExp*newK); else if (!strcmp(qmatprModel, "uniform")) (*lnPriorRatio) = 0.0; UpDateAllCls (proposedState, whichChain); # if defined (SMART_TI_PROBS) UpDateAllTIs (proposedState, whichChain); # endif return (NO_ERROR); } /* change rates of rate categories */ int Move_ChangeSiteRates (int proposedState, int whichChain, long int *seed, double *lnPriorRatio) { int i, nIncludedChars; double oldA, newA, ran, alphaSlide, minAlpha, maxAlpha, scaler; if (!strcmp(siterateprModel, "exponential")) { minAlpha = 0.01; maxAlpha = 100.0; } else if (!strcmp(siterateprModel, "uniform")) { minAlpha = siterateprUni[0]; maxAlpha = siterateprUni[1]; } alphaSlide = rateWinProp; (*lnPriorRatio) = 0.0; for (i=0; i maxAlpha) newA = maxAlpha - (newA - maxAlpha); unscaledRates[whichChain*2*nPartitions + proposedState*nPartitions + i] = newA; /* set prior ratio */ if (!strcmp(qmatprModel, "exponential")) (*lnPriorRatio) += (siterateprExp*oldA - siterateprExp*newA); } scaler = 0.0; nIncludedChars = 0; for (i=0; ilength); } } for (i=0; iupDateCl = NO; } (*lnProposalRatio) = 0.0; /* pick an internal branch */ do { p = intNodeDownPassSeq[whichChain*2*numIntNodes + proposedState*numIntNodes + (int)(RandomNumber(seed)*numIntNodes)]; } while (p->anc->anc == NULL); isTreeConstrained = NO; if (p->isConstrained == YES || p->anc->isConstrained == YES) isTreeConstrained = YES; specialRoot = NO; if (p->anc->anc->anc == NULL && treeModel == ROOTED) specialRoot = YES; # if defined (DEBUG_LOCAL) if (isTreeConstrained == YES) printf ("node (%d %d) is constrained\n", p->isConstrained, p->anc->isConstrained); # endif if (specialRoot == NO) { /* set up pointers according to Larget and Simon (MBE, 1999: 754) */ v = p; u = p->anc; u->upDateCl = YES; v->upDateCl = YES; if (RandomNumber(seed) < 0.5) { c = v->left; d = v->right; } else { c = v->right; d = v->left; } if (RandomNumber(seed) < 0.5) { if (u->left == v) a = u->right; else a = u->left; b = u->anc; isAUp = YES; } else { if (u->left == v) b = u->right; else b = u->left; a = u->anc; isAUp = NO; } # if defined (DEBUG_LOCAL) printf ("%d %d %d %d %d %d (%d)\n", u->index, v->index, a->index, b->index, c->index, d->index, isAUp); # endif /* get lengths of paths */ m = c->length + v->length; if (isAUp == YES) { m += a->length; x = a->length; } else { m += u->length; x = u->length; } y = v->length + x; /* change m */ ran = RandomNumber(seed); newM = m * exp(tuning * (ran - 0.5)); # if defined (DEBUG_LOCAL) printf ("m = %lf newM = %lf tuning = %lf\n", m, newM, tuning); # endif /* calculate proposal ratio */ (*lnProposalRatio) += (log(newM) - log(m)); /* change branch length proportions */ if (RandomNumber(seed) < 0.5) { /* detach u */ ran = RandomNumber(seed); if (isTreeConstrained == NO) { newY = y * (newM / m); newX = ran * newM; (*lnProposalRatio) += (log(newM) - log(m)); } else { newY = y * (newM / m); newX = ran * newY; (*lnProposalRatio) += (log(newY) - log(y)); } } else { /* detach v */ ran = RandomNumber(seed); if (isTreeConstrained == NO) { newX = x * (newM / m); newY = ran * newM; (*lnProposalRatio) += (log(newM) - log(m)); } else { newX = x * (newM / m); newY = newX + ran * (newM - newX); (*lnProposalRatio) += (log(newM - newX) - log(m - x)); } } /* check to see if topology changed */ if (newX > newY) topologyHasChanged = YES; else topologyHasChanged = NO; /* update pointers and branch lengths of tree */ if (topologyHasChanged == YES) { if (isAUp == YES) { if (v->left == c) v->right = a; else v->left = a; if (u->left == v) u->right = d; else u->left = d; a->anc = v; d->anc = u; c->length = newM - newX; v->length = newX - newY; a->length = newY; } else { if (v->left == c) v->right = b; else v->left = b; if (u->left == v) u->right = d; else u->left = d; b->anc = v; d->anc = u; c->length = newM - newX; u->length = newY; v->length = newX - newY; } } else { if (isAUp == YES) { c->length = newM - newY; u->length = newY - newX; a->length = newX; } else { c->length = newM - newY; v->length = newY - newX; u->length = newX; } } /* check branch lengths */ maxV = chainMaxs[CHANGE_UNROOT_LOCAL]; if (isAUp == YES) { if (c->length < BRLEN_EPSILON) c->length = BRLEN_EPSILON; if (a->length < BRLEN_EPSILON) a->length = BRLEN_EPSILON; if (d->length < BRLEN_EPSILON) d->length = BRLEN_EPSILON; if (u->length < BRLEN_EPSILON) u->length = BRLEN_EPSILON; if (v->length < BRLEN_EPSILON) v->length = BRLEN_EPSILON; if (c->length > maxV) c->length = maxV; if (a->length > maxV) a->length = maxV; if (d->length > maxV) d->length = maxV; if (u->length > maxV) u->length = maxV; if (v->length > maxV) v->length = maxV; } else { if (c->length < BRLEN_EPSILON) c->length = BRLEN_EPSILON; if (b->length < BRLEN_EPSILON) b->length = BRLEN_EPSILON; if (d->length < BRLEN_EPSILON) d->length = BRLEN_EPSILON; if (u->length < BRLEN_EPSILON) u->length = BRLEN_EPSILON; if (v->length < BRLEN_EPSILON) v->length = BRLEN_EPSILON; if (c->length > maxV) c->length = maxV; if (b->length > maxV) b->length = maxV; if (d->length > maxV) d->length = maxV; if (u->length > maxV) u->length = maxV; if (v->length > maxV) v->length = maxV; } v->upDateCl = YES; p = u; while (p->anc != NULL) { p->upDateCl = YES; p = p->anc; } # if defined (SMART_TI_PROBS) c->upDateTi = YES; v->upDateTi = YES; if (isAUp == YES) a->upDateTi = YES; else u->upDateTi = YES; a->upDateTi = YES; u->upDateTi = YES; # endif } else { /* deal with root of tree differently if this is a rooted and uncontrained tree */ /* check constraints again */ if (isTreeConstrained == YES) { if (p->isConstrained == NO && p->anc->isConstrained == YES) isTreeConstrained = NO; } /* initialize pointers */ u = p; v = p->anc; a = u->left; b = u->right; if (v->left == u) c = v->right; else c = v->left; if (isTreeConstrained == NO) { /* node is unconstrained */ if (u->length < c->length) isForcedBackMove = NO; else isForcedBackMove = YES; dAV = a->length + u->length; dBV = b->length + u->length; dCV = c->length; if (dAV < dBV && dAV < dCV) oldH1 = dAV; else if (dBV < dAV && dBV < dCV) oldH1 = dBV; else oldH1 = dCV; tuning = tuning; newH1 = oldH1 * exp(tuning*(RandomNumber(seed) - 0.5)); dAV = dAV + (newH1 - oldH1); dBV = dBV + (newH1 - oldH1); dCV = dCV + (newH1 - oldH1); h[0] = dAV; h[1] = dBV; h[2] = dCV; dID[0] = 0; dID[1] = 1; dID[2] = 2; if (h[0] > h[1]) { temp = h[0]; h[0] = h[1]; h[1] = temp; dTemp = dID[0]; dID[0] = dID[1]; dID[1] = dTemp; } if (h[0] > h[2]) { temp = h[0]; h[0] = h[2]; h[2] = temp; dTemp = dID[0]; dID[0] = dID[2]; dID[2] = dTemp; } if (h[1] > h[2]) { temp = h[1]; h[1] = h[2]; h[2] = temp; dTemp = dID[1]; dID[1] = dID[2]; dID[2] = dTemp; } for (i=0; i<3; i++) { if (dID[i] == 0) newDAV = h[i]; else if (dID[i] == 1) newDBV = h[i]; else newDCV = h[i]; } x = RandomNumber(seed) * h[1]; # if defined (DEBUG_LOCAL) printf ("h[0] = %lf h[1] = %lf h[2] = %lf (%d %d %d)\n", h[0], h[1], h[2], dID[0], dID[1], dID[2]); printf ("x = %lf\n", x); # endif (*lnProposalRatio) += 2.0 * (log(newH1) - log(oldH1)); if (x > h[0]) { isForcedForwardMove = YES; if (dID[0] == 0) { /* a is shortest, (b,c) forced */ u->left = b; u->right = c; u->anc = v; a->anc = v; b->anc = u; c->anc = u; v->left = a; v->right = u; u->length = x; a->length = dAV; b->length = dBV - x; c->length = dCV - x; } else if (dID[0] == 1) { /* b is shortest, (a,c) forced */ u->left = a; u->right = c; u->anc = v; a->anc = u; b->anc = v; c->anc = u; v->left = b; v->right = u; u->length = x; a->length = dAV - x; b->length = dBV; c->length = dCV - x; } else { /* c is shortest, (a,b) forced */ u->left = a; u->right = b; u->anc = v; a->anc = u; b->anc = u; c->anc = v; v->left = c; v->right = u; u->length = x; a->length = dAV - x; b->length = dBV - x; c->length = dCV; } } else { isForcedForwardMove = NO; ran = RandomNumber(seed); if (ran <= 0.33333) { /* a with c */ u->right = c; b->anc = v; c->anc = u; if (v->left == u) v->right = b; else v->left = b; u->length = x; a->length = newDAV - x; b->length = newDBV; c->length = newDCV - x; } else if (ran > 0.33333 && ran <= 0.66666) { /* b with c */ u->left = c; a->anc = v; c->anc = u; if (v->left == u) v->right = a; else v->left = a; a->length += u->length; c->length -= u->length; u->length = x; a->length = newDAV; b->length = newDBV - x; c->length = newDCV - x; } else { /* no change */ u->length = x; a->length = newDAV - x; b->length = newDBV - x; c->length = newDCV; } } /* get hastings ratio here */ if (isForcedForwardMove == NO && isForcedBackMove == YES) (*lnProposalRatio) += log(3.0); else if (isForcedForwardMove == YES && isForcedBackMove == NO) (*lnProposalRatio) += log(1.0/3.0); } else { /* node is constrained */ dAV = a->length + u->length; dBV = b->length + u->length; dCV = c->length; if (dAV < dBV) oldH1 = dAV; else oldH1 = dBV; tuning = tuning; newH1 = oldH1 * exp(tuning*(RandomNumber(seed) - 0.5)); dAV = dAV + (newH1 - oldH1); dBV = dBV + (newH1 - oldH1); dCV = dCV + (newH1 - oldH1); (*lnProposalRatio) += 2.0 * (log(newH1) - log(oldH1)); x = RandomNumber(seed) * newH1; u->length = x; a->length = dAV - x; b->length = dBV - x; c->length = dCV; } p = u; while (p->anc != NULL) { p->upDateCl = YES; p = p->anc; } topologyHasChanged = YES; # if defined (SMART_TI_PROBS) a->upDateTi = YES; b->upDateTi = YES; c->upDateTi = YES; u->upDateTi = YES; # endif } /* get down pass sequence if tree topology has changed */ if (topologyHasChanged == YES) { i = j = 0; GetDownPassSeq (root[whichChain*2 + proposedState], proposedState, whichChain, numTaxa, &i, &j); } # if defined (DEBUG_LOCAL) printf ("After:\n"); ShowNodes (root[whichChain*2+proposedState], 2, NO); # endif if (!strcmp(brlenprModel, "exponential")) { for (i=0; ilength); } } (*lnPriorRatio) = lnNewBrlenPr - lnOldBrlenPr; # if defined (TOPOLOGY_MOVE_STATS) if (topologyHasChanged == YES) gTopologyHasChanged = YES; else gTopologyHasChanged = NO; gNodeMoves = 1; # endif # if defined (SMART_TI_PROBS) //UpDateAllTIs (proposedState, whichChain); # endif return (NO_ERROR); } /* change branch lengths and topology (potentially) using BAMBE's LOCAL (rooted with calibrations) */ int Move_ChangeTimeClockWithLocal (int numTaxa, int proposedState, int whichChain, long int *seed, double *lnProposalRatio, double *lnPriorRatio) { int i, j, isAtRoot, dID[3], dTemp, topologyHasChanged, forceAB; double h[3], temp, maxTime1, maxTime2, minTime1, minTime2, x, y, ran, tuning, lnNewBrlenPr, lnOldBrlenPr, *nt, rootTime, sR, eR, sF; TreeNode *p, *q, *a, *b, *c, *u, *v, *w; lnNewBrlenPr = lnOldBrlenPr = 0.0; if (!strcmp(brlenprModel, "exponential")) { for (i=0; ilength); } } else if (!strcmp(brlenprModel, "birth-death")) { sR = spRate[whichChain*2 + proposedState]; eR = exRate[whichChain*2 + proposedState]; sF = samplingFraction; /* allocate memory */ nt = (double *)malloc((size_t) (numTaxa-1) * sizeof(double)); if (!nt) { printf ("\n ERROR: Problem allocating nt\n"); return (ERROR); } /* get root time */ rootTime = root[whichChain*2+proposedState]->left->nodeTime; /* put node times into vector */ j = 0; for (i=0; ileft != NULL && q->right != NULL && q->anc != NULL) { nt[j] = q->nodeTime; j++; } } /* calculate probabilities of tree */ lnOldBrlenPr = (numTaxa-2)*log(sR); for (i=0; iupDateCl = NO; } /* initialize proposal ratio */ (*lnProposalRatio) = 0.0; /* pick an internal branch and assign pointers */ do { p = intNodeDownPassSeq[whichChain*2*numIntNodes + proposedState*numIntNodes + (int)(RandomNumber(seed)*numIntNodes)]; } while (p->anc->anc == NULL); u = p; v = u->anc; if (u->anc->anc->anc == NULL) isAtRoot = YES; else { isAtRoot = NO; w = v->anc; } a = u->left; b = u->right; if (v->left == u) c = v->right; else c = v->left; # if defined (DEBUG_LOCAL_TIME_CLOCK) if (isAtRoot == NO) printf ("u=%d v=%d w=%d (%d %d %d)\n", Dex2(u), Dex2(v), Dex2(w), Dex2(a), Dex2(b), Dex2(c)); else printf ("u=%d v=%d (%d %d %d)\n", Dex2(u), Dex2(v), Dex2(a), Dex2(b), Dex2(c)); # endif /* sort times of nodes a, b, and c */ h[0] = a->nodeTime; h[1] = b->nodeTime; h[2] = c->nodeTime; dID[0] = 0; dID[1] = 1; dID[2] = 2; if (h[0] < h[1]) { temp = h[0]; h[0] = h[1]; h[1] = temp; dTemp = dID[0]; dID[0] = dID[1]; dID[1] = dTemp; } if (h[0] < h[2]) { temp = h[0]; h[0] = h[2]; h[2] = temp; dTemp = dID[0]; dID[0] = dID[2]; dID[2] = dTemp; } if (h[1] < h[2]) { temp = h[1]; h[1] = h[2]; h[2] = temp; dTemp = dID[1]; dID[1] = dID[2]; dID[2] = dTemp; } # if defined (DEBUG_LOCAL_TIME_CLOCK) printf ("%lf %lf %lf (%d %d %d)\n", h[0], h[1], h[2], dID[0], dID[1], dID[2]); # endif topologyHasChanged = NO; /* no constraints or calibrations in area of move (except, v can be constrained) */ if (isAtRoot == NO) { /* at internal node of tree */ forceAB = NO; maxTime1 = maxTime2 = w->nodeTime; minTime1 = h[0]; minTime2 = h[1]; if (u->isConstrained == YES && u->isCalibrated == NO) { forceAB = YES; if (a->nodeTime > b->nodeTime) minTime1 = minTime2 = a->nodeTime; else minTime1 = minTime2 = b->nodeTime; minTime2 = h[0]; } else if (u->isCalibrated == YES) { forceAB = YES; if (a->nodeTime > b->nodeTime) minTime1 = minTime2 = a->nodeTime; else minTime1 = minTime2 = b->nodeTime; minTime2 = h[0]; if (u->calTime[0] > minTime1) minTime1 = minTime2 = u->calTime[0]; if (u->calTime[0] + u->calTime[1] < maxTime1) maxTime1 = u->calTime[0] + u->calTime[1]; if (minTime2 < h[0]) minTime2 = h[0]; } if (v->isCalibrated == YES) { if (v->calTime[0] > minTime2) minTime2 = v->calTime[0]; if (v->calTime[0] + v->calTime[1] < maxTime2) maxTime2 = v->calTime[0] + v->calTime[1]; if (maxTime1 > maxTime2) maxTime1 = maxTime2; } x = RandomNumber(seed) * (maxTime1 - minTime1) + minTime1; y = RandomNumber(seed) * (maxTime2 - minTime2) + minTime2; if (x > y) { temp = x; x = y; y = temp; } if (x > minTime1 && forceAB == NO) { /* topology not forced */ ran = RandomNumber(seed); if (ran < 0.333) { u->left = a; u->right = c; a->anc = c->anc = u; if (v->left == u) v->right = b; else v->left = b; b->anc = v; topologyHasChanged = YES; } else if (ran >= 0.333 && ran < 0.666) { u->left = b; u->right = c; b->anc = c->anc = u; if (v->left == u) v->right = a; else v->left = a; a->anc = v; topologyHasChanged = YES; } u->nodeTime = x; v->nodeTime = y; } else { /* topology forced */ if (forceAB == NO) { if ((dID[1] == 0 && dID[2] == 2) || (dID[1] == 2 && dID[2] == 0)) { u->left = a; u->right = c; a->anc = c->anc = u; if (v->left == u) v->right = b; else v->left = b; b->anc = v; topologyHasChanged = YES; } else if ((dID[1] == 1 && dID[2] == 2) || (dID[1] == 2 && dID[2] == 1)) { u->left = b; u->right = c; b->anc = c->anc = u; if (v->left == u) v->right = a; else v->left = a; a->anc = v; topologyHasChanged = YES; } } u->nodeTime = x; v->nodeTime = y; } if (forceAB == NO) { if (u->nodeTime < c->nodeTime && x < h[0]) (*lnProposalRatio) += log(3.0); else if (u->nodeTime > c->nodeTime && x > h[0]) (*lnProposalRatio) += log(1.0/3.0); } # if defined (DEBUG_LOCAL_TIME_CLOCK) printf ("max1 = %lf max2 = %lf min = %lf %lf (%lf %lf)\n", maxTime1, maxTime2, minTime1, minTime2, x, y); # endif } else { /* at root of tree */ forceAB = NO; maxTime1 = maxTime2 = v->nodeTime; minTime1 = h[0]; minTime2 = h[1]; tuning = timeTuneProp; if (u->isCalibrated == NO && v->isCalibrated == NO) { y = minTime1 + (maxTime1 - minTime1) * exp(tuning*(RandomNumber(seed)-0.5)); (*lnProposalRatio) += log((y-minTime1) / (maxTime1-minTime1)); if (u->isConstrained == YES) { forceAB = YES; minTime2 = minTime1; } x = minTime2 + RandomNumber(seed) * (y - minTime2); } else if (u->isCalibrated == YES && v->isCalibrated == NO) { forceAB = YES; minTime2 = minTime1; if (u->calTime[0] > minTime1) minTime1 = minTime2 = u->calTime[0]; if (minTime1 > maxTime1) { printf ("\n ERROR: problem with order of nodes\n"); return (ERROR); } y = minTime1 + (maxTime1 - minTime1) * exp(tuning*(RandomNumber(seed)-0.5)); (*lnProposalRatio) += log((y-minTime1) / (maxTime1-minTime1)); if (u->calTime[0] + u->calTime[1] < y) maxTime2 = u->calTime[0] + u->calTime[1]; else maxTime2 = y; x = minTime2 + RandomNumber(seed) * (maxTime2 - minTime2); if (x > y) { temp = x; x = y; y = temp; } } else if (u->isCalibrated == NO && v->isCalibrated == YES) { if (v->calTime[0] < minTime1) minTime1 = v->calTime[0]; maxTime1 = v->calTime[0] + v->calTime[1]; y = minTime1 + RandomNumber(seed) * (maxTime1 - minTime1); if (u->isConstrained == YES) { forceAB = YES; minTime2 = minTime1; } maxTime2 = maxTime1; x = minTime2 + RandomNumber(seed) * (maxTime2 - minTime2); if (x > y) { temp = x; x = y; y = temp; } } else if (u->isCalibrated == YES && v->isCalibrated == YES) { forceAB = YES; minTime2 = minTime1; if (u->calTime[0] > minTime1) minTime1 = u->calTime[0]; maxTime1 = u->calTime[0] + u->calTime[1]; if (v->calTime[0] > minTime2) minTime2 = v->calTime[0]; maxTime2 = v->calTime[0] + v->calTime[1]; x = minTime1 + RandomNumber(seed) * (maxTime1 - minTime1); y = minTime2 + RandomNumber(seed) * (maxTime2 - minTime2); if (x > y) { temp = x; x = y; y = temp; } } if (x > minTime1 && forceAB == NO) { /* topology not forced */ ran = RandomNumber(seed); if (ran < 0.333) { u->left = a; u->right = c; a->anc = c->anc = u; if (v->left == u) v->right = b; else v->left = b; b->anc = v; topologyHasChanged = YES; } else if (ran >= 0.333 && ran < 0.666) { u->left = b; u->right = c; b->anc = c->anc = u; if (v->left == u) v->right = a; else v->left = a; a->anc = v; topologyHasChanged = YES; } u->nodeTime = x; v->nodeTime = y; } else { if (forceAB == NO) { /* topology forced to ac or bc */ if ((dID[1] == 0 && dID[2] == 2) || (dID[1] == 2 && dID[2] == 0)) { u->left = a; u->right = c; a->anc = c->anc = u; if (v->left == u) v->right = b; else v->left = b; b->anc = v; topologyHasChanged = YES; } else if ((dID[1] == 1 && dID[2] == 2) || (dID[1] == 2 && dID[2] == 1)) { u->left = b; u->right = c; b->anc = c->anc = u; if (v->left == u) v->right = a; else v->left = a; a->anc = v; topologyHasChanged = YES; } } u->nodeTime = x; v->nodeTime = y; } if (forceAB == NO) { if (u->nodeTime < c->nodeTime && x < h[2]) (*lnProposalRatio) += log(3.0); else if (u->nodeTime > c->nodeTime && x > h[2]) (*lnProposalRatio) += log(1.0/3.0); } } /* set update flags to YES */ p = u; while (p->anc != NULL) { p->upDateCl = YES; p = p->anc; } /* get down pass sequence */ if (topologyHasChanged == YES) { i = j = 0; GetDownPassSeq (root[whichChain*2 + proposedState], proposedState, whichChain, numTaxa, &i, &j); } /* get branch lengths on tree */ //printf ("m = %lf\n", treeHeight[whichChain*2+proposedState]); for (i=0; ilength = 0.0; if (p->anc != NULL) if (p->anc->anc != NULL) p->length = (p->anc->nodeTime - p->nodeTime) * treeHeight[whichChain*2+proposedState]; if (p->length < 0.0) { printf ("\n ERROR: negative branch length\n"); ShowNodes (root[whichChain*2+proposedState], 2, YES); return (ERROR); } if (p->length < BRLEN_EPSILON) p->length = BRLEN_EPSILON; } # if defined (DEBUG_LOCAL_TIME_CLOCK) printf ("After:\n"); ShowNodes (root[whichChain*2+proposedState], 2, YES); # endif if (!strcmp(brlenprModel, "exponential")) { for (i=0; ilength); } } else if (!strcmp(brlenprModel, "birth-death")) { /* get root time */ rootTime = root[whichChain*2+proposedState]->left->nodeTime; /* put node times into vector */ j = 0; for (i=0; ileft != NULL && p->right != NULL && p->anc != NULL) { nt[j] = p->nodeTime; j++; } } /* calculate probabilities of tree */ lnNewBrlenPr = (numTaxa-2)*log(sR); for (i=0; ianc->anc == NULL || p->isConstrained == YES); /* set up area of rearrangement */ u = p; v = u->anc; a = u->left; b = u->right; if (v->left == u) c = v->right; else c = v->left; /* change topology */ if (RandomNumber(seed) < 0.5) { if (v->left == u) v->right = b; else v->left = b; u->left = a; u->right = c; a->anc = c->anc = u; b->anc = v; } else { if (v->left == u) v->right = a; else v->left = a; u->left = b; u->right = c; b->anc = c->anc = u; a->anc = v; } i = j = 0; GetDownPassSeq (root[whichChain*2 + proposedState], proposedState, whichChain, numTaxa, &i, &j); return (NO_ERROR); } int Move_ChangeNodeTime (int numTaxa, int proposedState, int whichChain, long int *seed, double *lnProposalRatio, double *lnPriorRatio) { int i, j, isRoot; double minTime, maxTime, newT, oldT, tuning, lnNewBrlenPr, lnOldBrlenPr, *nt, rootTime, sR, eR, sF; TreeNode *p, *q; (*lnPriorRatio) = 0.0; (*lnProposalRatio) = 0.0; /* pick an internal branch */ do { p = intNodeDownPassSeq[whichChain*2*numIntNodes + proposedState*numIntNodes + (int)(RandomNumber(seed)*numIntNodes)]; } while (p->anc->anc == NULL); isRoot = NO; if (p->anc->anc == NULL) isRoot = YES; oldT = p->nodeTime; /* get prior probability of beginning branch lengths */ if (!strcmp(brlenprModel, "exponential")) { lnOldBrlenPr = log(brlenprExp) - brlenprExp * (p->left->length); lnOldBrlenPr += log(brlenprExp) - brlenprExp * (p->right->length); lnOldBrlenPr += log(brlenprExp) - brlenprExp * (p->length); } else if (!strcmp(brlenprModel, "birth-death")) { sR = spRate[whichChain*2 + proposedState]; eR = exRate[whichChain*2 + proposedState]; sF = samplingFraction; /* allocate memory */ nt = (double *)malloc((size_t) (numTaxa-1) * sizeof(double)); if (!nt) { printf ("\n ERROR: Problem allocating nt\n"); return (ERROR); } /* get root time */ rootTime = root[whichChain*2+proposedState]->left->nodeTime; /* put node times into vector */ j = 0; for (i=0; ileft != NULL && q->right != NULL && q->anc != NULL) { nt[j] = q->nodeTime; j++; } } /* calculate probabilities of tree */ lnOldBrlenPr = (numTaxa-2)*log(sR); for (i=0; ileft->nodeTime > p->right->nodeTime) minTime = p->left->nodeTime; else minTime = p->right->nodeTime; if (isRoot == NO) { maxTime = p->anc->nodeTime; } if (p->isCalibrated == YES) { if (p->calTime[0] > minTime) minTime = p->calTime[0]; if (p->calTime[0] + p->calTime[1] < maxTime && isRoot == NO) maxTime = p->calTime[0] + p->calTime[1]; } /* choose new node time */ if (isRoot == NO) { newT = minTime + RandomNumber(seed) * (maxTime - minTime); p->nodeTime = newT; p->left->length = (p->nodeTime - p->left->nodeTime) * treeHeight[whichChain*2+proposedState]; p->right->length = (p->nodeTime - p->right->nodeTime) * treeHeight[whichChain*2+proposedState]; p->length = (p->anc->nodeTime - p->nodeTime) * treeHeight[whichChain*2+proposedState]; } else { tuning = nodeTimeTuneProp; newT = minTime + (maxTime - minTime) * exp(tuning*(RandomNumber(seed)-0.5)); p->nodeTime = newT; p->left->length = (p->nodeTime - p->left->nodeTime) * treeHeight[whichChain*2+proposedState]; p->right->length = (p->nodeTime - p->right->nodeTime) * treeHeight[whichChain*2+proposedState]; (*lnProposalRatio) = log((newT-minTime) / (oldT - minTime)); } /* get prior probability of ending branch lengths */ if (!strcmp(brlenprModel, "exponential")) { lnNewBrlenPr = log(brlenprExp) - brlenprExp * (p->left->length); lnNewBrlenPr += log(brlenprExp) - brlenprExp * (p->right->length); lnNewBrlenPr += log(brlenprExp) - brlenprExp * (p->length); (*lnPriorRatio) = lnNewBrlenPr - lnOldBrlenPr; } else if (!strcmp(brlenprModel, "birth-death")) { /* get root time */ rootTime = root[whichChain*2+proposedState]->left->nodeTime; /* put node times into vector */ j = 0; for (i=0; ileft != NULL && q->right != NULL && q->anc != NULL) { nt[j] = q->nodeTime; j++; } } /* calculate probabilities of tree */ lnNewBrlenPr = (numTaxa-2)*log(sR); for (i=0; iupDateCl = YES; while (p->anc != NULL) { p->upDateCl = YES; p = p->anc; } /* TEMP */ //UpDateAllCls (proposedState, whichChain); # if defined (SMART_TI_PROBS) UpDateAllTIs (proposedState, whichChain); /* NOTE: This could be made better, but this function probably will go, so don't bother. */ # endif return (NO_ERROR); } /* change omega */ int Move_ChangeOmega (int proposedState, int whichChain, long int *seed, double *lnPriorRatio) { double oldW, newW, ran, omegaSlide, minOmega, maxOmega; minOmega = chainMins[CHANGE_OMEGA]; maxOmega = chainMaxs[CHANGE_OMEGA]; omegaSlide = omegaWinProp; oldW = omega[whichChain*2 + proposedState]; ran = (RandomNumber(seed) * omegaSlide) - (omegaSlide/2.0); newW = oldW + ran; if (newW < minOmega) newW = (minOmega - newW) + minOmega; if (newW > maxOmega) newW = maxOmega - (newW - maxOmega); omega[whichChain*2 + proposedState] = newW; /* set prior ratio */ if (!strcmp(qmatprModel, "exponential")) (*lnPriorRatio) = (omegaprExp*oldW - omegaprExp*newW); else if (!strcmp(qmatprModel, "uniform")) (*lnPriorRatio) = 0.0; UpDateAllCls (proposedState, whichChain); # if defined (SMART_TI_PROBS) UpDateAllTIs (proposedState, whichChain); # endif return (NO_ERROR); } /* change omega pi */ int Move_ChangeOmegaProbs (int proposedState, int whichChain, long int *seed, double *lnPriorRatio, double *lnProposalRatio) { int i; double *dirichletParameters, *newPi, *oldPi, sum, alphaPi, priorPi, x, y; dirichletParameters = (double *)malloc((size_t) (3 * sizeof(double))); if (!dirichletParameters) goto error_exit; newPi = (double *)malloc((size_t) (3 * sizeof(double))); if (!newPi) goto error_exit; oldPi = (double *)malloc((size_t) (3 * sizeof(double))); if (!oldPi) goto error_exit; alphaPi = omegaAlphaProp; priorPi = 3.0; oldPi[0] = probPos[whichChain*2 + proposedState]; oldPi[1] = probPur[whichChain*2 + proposedState]; oldPi[2] = probNeu[whichChain*2 + proposedState]; dirichletParameters[0] = oldPi[0] * alphaPi; dirichletParameters[1] = oldPi[1] * alphaPi; dirichletParameters[2] = oldPi[2] * alphaPi; DirichletRandomVariable (dirichletParameters, newPi, 3, seed); sum = 0.0; for (i=0; i<3; i++) { if (newPi[i] < 0.0001) newPi[i] = 0.0001; sum += newPi[i]; } for (i=0; i<3; i++) newPi[i] = newPi[i] / sum; probPos[whichChain*2 + proposedState] = newPi[0]; probPur[whichChain*2 + proposedState] = newPi[1]; probNeu[whichChain*2 + proposedState] = newPi[2]; /* get proposal ratio */ sum = 0.0; for (i=0; i<3; i++) sum += newPi[i]*alphaPi; x = LnGamma(sum); for (i=0; i<3; i++) x -= LnGamma(newPi[i]*alphaPi); for (i=0; i<3; i++) x += (newPi[i]*alphaPi-1.0)*log(oldPi[i]); sum = 0.0; for (i=0; i<3; i++) sum += oldPi[i]*alphaPi; y = LnGamma(sum); for (i=0; i<3; i++) y -= LnGamma(oldPi[i]*alphaPi); for (i=0; i<3; i++) y += (oldPi[i]*alphaPi-1.0)*log(newPi[i]); (*lnProposalRatio) = x - y; /* get prior ratio */ x = LnGamma(priorPi); for (i=0; i<3; i++) x -= LnGamma(0.33333*priorPi); for (i=0; i<3; i++) x += (0.33333*priorPi-1.0)*log(newPi[i]); y = LnGamma(priorPi); for (i=0; i<3; i++) y -= LnGamma(0.33333*priorPi); for (i=0; i<3; i++) y += (0.33333*priorPi-1.0)*log(oldPi[i]); (*lnPriorRatio) = x - y; UpDateAllCls (proposedState, whichChain); # if defined (SMART_TI_PROBS) if (!strcmp(codonModelType, "covny98")) UpDateAllTIs (proposedState, whichChain); # endif free (dirichletParameters); free (newPi); free (oldPi); return (NO_ERROR); error_exit: free (dirichletParameters); free (newPi); free (oldPi); return (ERROR); } /* change proportion of invariant sites */ int Move_ChangePropInv (int proposedState, int whichChain, long int *seed, double *lnPriorRatio) { double oldP, newP, ran, pSlide, minP, maxP; minP = 0.0; maxP = 1.0; pSlide = invSlideProp; oldP = invP[whichChain*2 + proposedState]; ran = (RandomNumber(seed) * pSlide) - (pSlide/2.0); newP = oldP + ran; if (newP < minP) newP = (minP - newP) + minP; if (newP > maxP) newP = maxP - (newP - maxP); invP[whichChain*2 + proposedState] = newP; (*lnPriorRatio) = 0.0; UpDateAllCls (proposedState, whichChain); # if defined (SMART_TI_PROBS) UpDateAllTIs (proposedState, whichChain); # endif return (NO_ERROR); } int Move_ChangeTreeHeight (int proposedState, int whichChain, long int *seed, double *lnProposalRatio) { double tuning, oldM, newM; tuning = mTuneProp; oldM = treeHeight[whichChain*2+proposedState]; newM = oldM * exp(tuning*(RandomNumber(seed)-0.5)); treeHeight[whichChain*2+proposedState] = newM; (*lnProposalRatio) = log(newM / oldM); UpDateAllCls (proposedState, whichChain); # if defined (SMART_TI_PROBS) UpDateAllTIs (proposedState, whichChain); # endif return (NO_ERROR); } /* change branch lengths and topology (potentially) using the growing worm mechanism (unrooted) */ int Move_SingleWorm (int numTaxa, int proposedState, int whichChain, long int *seed, double *lnProposalRatio, double *lnPriorRatio) { int i, j, n, numBackbone, numExtendable, numDanglies, whichAnchor, isDanglyUp; double ran, oldM, newM, tuning, extensionProb, newPoint, sum, lnNewBrlenPr, lnOldBrlenPr; TreeNode *p, *q, *r, *a, *aa, *b, *c, *d, **backbone, *extendable[4], **danglies, *anchors[2]; lnNewBrlenPr = lnOldBrlenPr = 0.0; if (!strcmp(brlenprModel, "exponential")) { for (i=0; ilength); } } extensionProb = extendPProp; tuning = wormTuneProp; for (i=0; iupDateCl = NO; p->marked = NO; # if defined (TOPOLOGY_MOVE_STATS) p->flag = NO; # endif } # if defined (SHOW_MOVE_WORM) printf ("Before:\n"); ShowNodes (root[whichChain*2+proposedState], 2, NO); # endif (*lnProposalRatio) = 0.0; backbone = (TreeNode **)malloc((size_t) (numNodes) * sizeof(TreeNode *)); if (!backbone) { printf ("Could not allocate backbone (%d)\n", sizeof(TreeNode *) * (numNodes)); return (ERROR); } danglies = (TreeNode **)malloc((size_t) (numNodes) * sizeof(TreeNode *)); if (!danglies) { printf ("Could not allocate danglies (%d)\n", sizeof(TreeNode *) * (numNodes)); free (backbone); return (ERROR); } for (i=0; iindex); # endif backbone[0] = p; numBackbone = 1; numExtendable = 0; if (IsLeaf(p->anc) == NO) extendable[numExtendable++] = p->anc; if (IsLeaf(p->left) == NO) extendable[numExtendable++] = p->left; if (IsLeaf(p->right) == NO) extendable[numExtendable++] = p->right; backbone[0]->marked = YES; # if defined (SHOW_MOVE_WORM) printf (" %d -- ", numExtendable); for (i=0; iindex); printf ("\n"); # endif /* get backbone */ while (RandomNumber(seed) < extensionProb && numExtendable >= 1) { p = extendable[(int)(RandomNumber(seed) * numExtendable)]; backbone[numBackbone] = p; p->marked = YES; numBackbone++; # if defined (SHOW_MOVE_WORM) printf ("extended backbone to %d\n", p->index); # endif numExtendable = 0; for (i=0; iindex, NumAdjacentMarked (backbone[i]), backbone[i]->left->marked, backbone[i]->right->marked, backbone[i]->anc->marked); # endif if (NumAdjacentMarked (backbone[i]) == 1) { if (backbone[i]->anc->marked == NO && IsLeaf(backbone[i]->anc) == NO) extendable[numExtendable++] = backbone[i]->anc; if (backbone[i]->left->marked == NO && IsLeaf(backbone[i]->left) == NO) extendable[numExtendable++] = backbone[i]->left; if (backbone[i]->right->marked == NO && IsLeaf(backbone[i]->right) == NO) extendable[numExtendable++] = backbone[i]->right; } } # if defined (SHOW_MOVE_WORM) printf (" %d -- ", numExtendable); for (i=0; iindex); printf ("\n"); # endif } /* get anchors and danglies */ numDanglies = 0; whichAnchor = 0; for (i=0; ileft; anchors[1] = p->right; danglies[numDanglies++] = p->anc; } else if (ran >= 0.3333 && ran < 0.6666) { anchors[0] = p->anc; anchors[1] = p->right; danglies[numDanglies++] = p->left; } else { anchors[0] = p->left; anchors[1] = p->anc; danglies[numDanglies++] = p->right; } } else if (n == 1) { numExtendable = 0; if (p->anc->marked == NO) extendable[numExtendable++] = p->anc; if (p->left->marked == NO) extendable[numExtendable++] = p->left; if (p->right->marked == NO) extendable[numExtendable++] = p->right; if (RandomNumber(seed) < 0.5) { anchors[whichAnchor++] = extendable[0]; danglies[numDanglies++] = extendable[1]; } else { anchors[whichAnchor++] = extendable[1]; danglies[numDanglies++] = extendable[0]; } } else if (n == 2) { if (p->anc->marked == NO) danglies[numDanglies++] = p->anc; else if (p->left->marked == NO) danglies[numDanglies++] = p->left; else if (p->right->marked == NO) danglies[numDanglies++] = p->right; else { printf ("ERROR: Should have at least one dangly!\n"); free (backbone); free (danglies); return (ERROR); } } else { printf ("ERROR: Too many marked neighbors!\n"); free (backbone); free (danglies); return (ERROR); } } /* add the anchors to the backbone */ backbone[numBackbone++] = anchors[0]; backbone[numBackbone++] = anchors[1]; # if defined (SHOW_MOVE_WORM) printf ("Backbone and danglies:\n"); printf (" %d -- ", numBackbone); for (i=0; iindex); printf ("\n"); printf (" %d -- ", numDanglies); for (i=0; iindex); printf ("\n"); # endif /* get path length */ oldM = 0; for (i=0; ilength; # if defined (SMART_TI_PROBS) for (i=0; iupDateTi = YES; # endif /* change path length */ ran = RandomNumber(seed); newM = oldM * exp(tuning * (ran - 0.5)); for (i=0; ilength *= (newM/oldM); /* calculate proposal ratio */ (*lnProposalRatio) += 2.0 * (log(newM) - log(oldM)); /* pick a dangly to detach */ p = danglies[(int)(RandomNumber(seed)*numDanglies)]; /* pick a new attachment point */ newPoint = RandomNumber(seed) * newM; sum = 0.0; for (i=0; ilength; if (sum > newPoint) r = backbone[i]; } } /* see if chosen dangly is up or down with reference to the backbone */ if (p->anc == NULL) isDanglyUp = NO; else { if (p->anc->marked == YES) isDanglyUp = YES; else isDanglyUp = NO; } # if defined (SHOW_MOVE_WORM) printf ("Dangly to detach = %d\n", p->index); printf ("New attachment pt = %d\n", r->index); printf ("isDanglyUp = %d\n", isDanglyUp); # endif # if defined (TOPOLOGY_MOVE_STATS) gNodeMoves = 0; if (isDanglyUp == YES) a = p->anc; else a = p; while (a->anc != NULL) { a = a->anc; a->flag = YES; gNodeMoves++; } a = r; while (a->anc != NULL) { if (a->anc->left == a) q = a->anc->right; else q = a->anc->left; a = a->anc; if (a->flag == NO && a != p) gNodeMoves++; else if (a->anc == NULL) // root; q == NULL gNodeMoves--; else if (a->flag == YES && q->flag != YES) gNodeMoves--; } # endif /* adjust topology */ if (isDanglyUp == YES) { /* dangly is up */ a = p->anc; aa = a->anc; if (a->left == p) q = a->right; else q = a->left; if (aa->left == a) aa->left = q; else aa->right = q; q->anc = aa; q->length += a->length; a->anc = NULL; # if defined (SMART_TI_PROBS) q->upDateTi = YES; # endif aa = r->anc; if (aa->left == r) aa->left = a; else aa->right = a; a->anc = aa; r->anc = a; p->anc = a; a->left = r; a->right = p; ran = RandomNumber(seed) * r->length; a->length = r->length - ran; r->length = ran; # if defined (SMART_TI_PROBS) r->upDateTi = YES; a->upDateTi = YES; # endif } else { /* dangly is down */ if (p->anc != NULL) { if (p->left->marked == YES && p->right->marked == NO) p = p->left; else if (p->left->marked == NO && p->right->marked == YES) p = p->right; else { printf ("ERROR: Problem determining dangly\n"); free (backbone); free (danglies); return (ERROR); } } else { p = p->left; } for (i=0; iflag = NO; } q = r; do { q->flag = YES; q = q->anc; } while (q->anc != NULL); while (p->left != r && p->right != r) { if (p->left->flag == YES && p->right->flag == NO) { a = p->left; c = p->right; } else if (p->left->flag == NO && p->right->flag == YES) { a = p->right; c = p->left; } else { printf ("ERROR: Problem shifting tree!\n"); free (backbone); free (danglies); return (ERROR); } if (a->left == NULL || a->right == NULL) { printf ("ERROR: Problem trying to shift subtree to nonexistent branch\n"); free (backbone); free (danglies); return (ERROR); } if (a->left->flag == YES && a->right->flag == NO) { b = a->left; d = a->right; } else if (a->left->flag == NO && a->right->flag == YES) { b = a->right; d = a->left; } else { printf ("ERROR: Problem shifting tree!\n"); ShowNodes (root[whichChain*2+proposedState], 2, NO); printf ("p = %d, a = %d r = %d c = %d \n", p->index, a->index, r->index, c->index); for (i=0; iindex, q->flag); } for (i=0; iindex); printf ("\n"); free (backbone); free (danglies); return (ERROR); } p->left = a; p->right = b; a->left = c; a->right = d; a->anc = p; b->anc = p; c->anc = a; d->anc = a; c->length += a->length; b->length /= 2.0; a->length = b->length; ran = RandomNumber(seed) * (a->length + b->length); a->length = (a->length + b->length) - ran; b->length = ran; a->flag = NO; # if defined (SMART_TI_PROBS) c->upDateTi = YES; b->upDateTi = YES; a->upDateTi = YES; # endif } } i = j = 0; GetDownPassSeq (root[whichChain*2+proposedState], proposedState, whichChain, numTaxa, &i, &j); /* check for very small branches */ for (i=0; ilength < BRLEN_EPSILON) p->length = BRLEN_EPSILON; } /* mark branches to update */ UpDateAllCls (proposedState, whichChain); free (backbone); free (danglies); # if defined (SHOW_MOVE_WORM) printf ("After:\n"); ShowNodes (root[whichChain*2+proposedState], 2, NO); # endif if (!strcmp(brlenprModel, "exponential")) { for (i=0; ilength); } } (*lnPriorRatio) = lnNewBrlenPr - lnOldBrlenPr; # if defined (TOPOLOGY_MOVE_STATS) if (gNodeMoves > 0) gTopologyHasChanged = YES; else gTopologyHasChanged = NO; # endif return (NO_ERROR); } /* change switching rate for covarion model */ int Move_ChangeSwitchRate (int proposedState, int whichChain, long int *seed, double *lnPriorRatio) { int whichS; double oldS, newS, ran, sSlide, minS, maxS, sum; /* There are two rates for the covarion model. One rate is from on -> off and the other from off ->on. The first rate (on -> off) is 0 and the other is 1 in the vectors, below */ minS = chainMins[CHANGE_SWITCH_RATE]; maxS = chainMaxs[CHANGE_SWITCH_RATE]; sSlide = switchWinProp; # if 0 if (RandomNumber(seed) < 0.5) whichS = 0; else whichS = 1; if ((dataType == DNA || dataType == RNA) && enforceCodonModel == YES && !strcmp(codonModelType, "covny98")) whichS = 0; oldS = switchRate[whichChain*4 + proposedState*2 + whichS]; ran = (RandomNumber(seed) * sSlide) - (sSlide/2.0); newS = oldS + ran; if (newS < minS) newS = (minS - newS) + minS; if (newS > maxS) newS = maxS - (newS - maxS); switchRate[whichChain*4 + proposedState*2 + whichS] = newS; # else whichS = 0; if ((dataType == DNA || dataType == RNA) && enforceCodonModel == YES && !strcmp(codonModelType, "covny98")) whichS = 0; oldS = switchRate[whichChain*4 + proposedState*2 + whichS]; ran = (RandomNumber(seed) * sSlide) - (sSlide/2.0); newS = oldS + ran; if (newS < minS) newS = (minS - newS) + minS; if (newS > maxS) newS = maxS - (newS - maxS); switchRate[whichChain*4 + proposedState*2 + whichS] = newS; whichS = 1; if ((dataType == DNA || dataType == RNA) && enforceCodonModel == YES && !strcmp(codonModelType, "covny98")) { whichS = 0; } else { oldS = switchRate[whichChain*4 + proposedState*2 + whichS]; ran = (RandomNumber(seed) * sSlide) - (sSlide/2.0); newS = oldS + ran; if (newS < minS) newS = (minS - newS) + minS; if (newS > maxS) newS = maxS - (newS - maxS); switchRate[whichChain*4 + proposedState*2 + whichS] = newS; } # endif /* set stationary frequencies of on and off */ if ((dataType == DNA || dataType == RNA) && enforceCodonModel == YES && !strcmp(codonModelType, "covny98")) { if ((dataType == DNA || dataType == RNA) && enforceCodonModel == YES && !strcmp(codonModelType, "covny98")) switchRate[whichChain*4 + proposedState*2 + 1] = newS; } else { sum = switchRate[whichChain*4 + proposedState*2 + 0] + switchRate[whichChain*4 + proposedState*2 + 1]; switchPi[whichChain*4 + proposedState*2 + 0] = switchRate[whichChain*4 + proposedState*2 + 1] / sum; /* stationary prob that it is on */ switchPi[whichChain*4 + proposedState*2 + 1] = switchRate[whichChain*4 + proposedState*2 + 0] / sum; /* stationary prob that it is off */ } /* set switch prior ratio */ (*lnPriorRatio) = 0.0; /* do this later */ UpDateAllCls (proposedState, whichChain); # if defined (SMART_TI_PROBS) UpDateAllTIs (proposedState, whichChain); # endif return (NO_ERROR); } /* change branch lengths and topology using SPR (unrooted, unconstrained, uncalibrated) */ int Move_ChangeUnrootedWithSPR (int numTaxa, int proposedState, int whichChain, long int *seed, double *lnProposalRatio, double *lnPriorRatio) { int i, j, stopLoop, nNodesSubTree1; double v1, v2, v1a, v1b, v2a, v2b; TreeNode *p, *q, *a, *b, *c, *d, *subRoot1, *subRoot2, **subTree1DP; # if defined (DEBUG_SPR) printf ("Before:\n"); ShowNodes (root[whichChain*2+proposedState], 2, NO); # endif subTree1DP = (TreeNode **)malloc(sizeof(TreeNode *) * 2 * numTaxa); if (!subTree1DP) { printf ("\n ERROR: Could not allocate subTree1DP\n"); FreeMemory (); return (ERROR); } for (i=0; iupDateCl = NO; } /* pick a branch at random */ stopLoop = NO; do { p = allNodesDownPassSeq[whichChain*2*numNodes + proposedState*numNodes + (int)(RandomNumber(seed)*numNodes)]; stopLoop = YES; if (p->anc != NULL) { if (p->anc->anc == NULL) stopLoop = NO; } } while (stopLoop == NO); # if defined (TOPOLOGY_MOVE_STATS) gNodeMoves = 0; for (i=0; imarked = NO; } a = p; if (a->anc != NULL) { a = a->anc; while (a->anc!=NULL) { a = a->anc; a->marked = YES; gNodeMoves++; } } else { a = a->left; while (a->left!=NULL) { a = a->left; a->marked = YES; gNodeMoves++; } } # endif /* now detach the chosen branch from the tree */ if (p->anc == NULL) { q = p->left; v1 = q->left->length + q->right->length; v1a = q->left->length; v1b = q->right->length; /* now shift tree such that that tip is sister to everyone else */ stopLoop = NO; while (stopLoop == NO) { q = p->left; a = q->left; b = q->right; a->upDateCl = YES; # if defined (TOPOLOGY_MOVE_STATS) a->marked = YES; # endif if (a->left != NULL && a->right != NULL) { c = a->left; d = a->right; q->left = c; q->right = a; c->anc = q; a->anc = q; a->left = d; a->right = b; d->anc = a; b->anc = a; b->length += a->length; c->length *= 0.5; a->length = c->length; } else { stopLoop = YES; } } /* now reroot tree at left-most tip and detach old root */ p->left = q; subRoot1 = q->left; subRoot1->upDateCl = YES; a = q->right; a->anc = subRoot1; subRoot1->left = a; subRoot1->right = subRoot1->anc = NULL; a->length += subRoot1->length; subRoot1->length = 0.0; subRoot2 = q; subRoot2->left = p; p->anc = subRoot2; p->left = p->right = NULL; subRoot2->right = subRoot2->anc = NULL; subRoot2->upDateCl = p->upDateCl = YES; } else { q = p; while (q->anc != NULL) { q->upDateCl = YES; q = q->anc; q->upDateCl = YES; } v1 = p->length; v1a = p->anc->length; if (p->anc->left == p) v1b = p->anc->right->length; else v1b = p->anc->left->length; subRoot1 = root[whichChain*2 + proposedState]; subRoot2 = p->anc; if (subRoot2->left == p) a = subRoot2->right; else a = subRoot2->left; b = subRoot2->anc; if (b->left == subRoot2) b->left = a; else b->right = a; a->anc = b; a->length += subRoot2->length; subRoot2->left = p; subRoot2->right = subRoot2->anc = NULL; subRoot2->length = 0.0; } /* We now have two subtrees. One is rooted at subRoot1. The other, which is the detached portion, is rooted at subRoot2. We want to pick a branch at random on the tree rooted at subRoot1 and put subRoot2 on that branch. */ i = 0; GetTempDownPassSeq (subRoot1, &i, subTree1DP); nNodesSubTree1 = i; do { p = subTree1DP[(int)(RandomNumber(seed)*nNodesSubTree1)]; } while (p->anc == NULL); v2 = p->length; q = p->anc; b = subRoot2->left; if (q->left == p) { q->left = subRoot2; subRoot2->left = p; p->anc = subRoot2; subRoot2->anc = q; subRoot2->right = b; } else { q->right = subRoot2; subRoot2->right = p; p->anc = subRoot2; subRoot2->anc = q; subRoot2->left = b; } v2a = v2 * RandomNumber(seed); v2b = v2 - v2a; subRoot2->length = v2a; p->length = v2b; q = p; q->upDateCl = YES; while (q->anc != NULL) { q->upDateCl = YES; q = q->anc; q->upDateCl = YES; } /* get down pass sequence if tree topology has changed */ root[whichChain*2 + proposedState] = subRoot1; i = j = 0; GetDownPassSeq (root[whichChain*2 + proposedState], proposedState, whichChain, numTaxa, &i, &j); /* get proposal and prior ratios */ (*lnProposalRatio) = log(v2) - log(v1); (*lnPriorRatio) = 0.0; if (!strcmp(brlenprModel, "exponential")) { (*lnPriorRatio) = (log(brlenprExp) - brlenprExp * (v1a)) + (log(brlenprExp) - brlenprExp * (v1b)) - (log(brlenprExp) - brlenprExp * (v2a)) - (log(brlenprExp) - brlenprExp * (v2b)); } //UpDateAllCls (proposedState, whichChain); # if defined (DEBUG_SPR) printf ("After:\n"); ShowNodes (root[whichChain*2+proposedState], 2, NO); # endif # if defined (TOPOLOGY_MOVE_STATS) a = subRoot2; while (a->anc!=NULL) { if (a->anc->left == a) b = a->anc->right; else b = a->anc->left; a = a->anc; if (a->marked == NO) gNodeMoves++; else if (a->anc == NULL) gNodeMoves--; else if (a->marked == YES && b->marked == NO) gNodeMoves--; } if (gNodeMoves > 0) gTopologyHasChanged = YES; else gTopologyHasChanged = NO; # endif # if defined (SMART_TI_PROBS) // TO DO: Figure out exactly which branches need their transition matrices updated. UpDateAllTIs (proposedState, whichChain); # endif free (subTree1DP); return (NO_ERROR); } int Move_ChangeBD (int proposedState, int whichChain, long int *seed) { double oldEx, newEx, oldSp, newSp, ran, rateSlide, minExRate, minSpRate, maxExRate, maxSpRate; rateSlide = bdWinProp; minExRate = chainMins[CHANGE_BD_PARAMS]; maxExRate = chainMaxs[CHANGE_BD_PARAMS]; oldEx = exRate[whichChain*2 + proposedState]; ran = (RandomNumber(seed) * rateSlide) - (rateSlide/2.0); newEx = oldEx + ran; if (newEx < minExRate) newEx = (minExRate - newEx) + minExRate; if (newEx > maxExRate) newEx = maxExRate - (newEx - maxExRate); exRate[whichChain*2 + proposedState] = newEx; minSpRate = exRate[whichChain*2 + proposedState]; maxSpRate = chainMaxs[CHANGE_BD_PARAMS]; oldSp = spRate[whichChain*2 + proposedState]; ran = (RandomNumber(seed) * rateSlide) - (rateSlide/2.0); newSp = oldSp + ran; if (newSp < minSpRate) newSp = (minSpRate - newSp) + minSpRate; if (newSp > maxSpRate) newSp = maxSpRate - (newSp - maxSpRate); spRate[whichChain*2 + proposedState] = newSp; return (NO_ERROR); } /* Change branch lengths and possibly topology using probabilistic TBR branch swapping. */ int Move_ChangeTBR (int numTaxa, int proposedState, int whichChain, long int *seed, double *lnProposalRatio, double *lnPriorRatio) { int i, j, reconLimit, nMarkedAbove, nMarkedBelow, whichBranch, nVisited, stopLoop, hasTopologyChanged; double tempLength, newLength, tuning, mult, forwardP, backwardP, oldM, newM, lnNewBrlenPr, lnOldBrlenPr; TreeNode *p, *q, *u, *a, *b0, *b1, *b11, *b10; # if defined (DEBUG_TBR) printf ("Before:\n"); ShowNodes (root[whichChain*2+proposedState], 2, NO); # endif /* Set paramters of move. */ *lnProposalRatio = *lnPriorRatio = 0.0; reconLimit = (int)reconLimProp; tuning = wormTuneProp; mult = exp(tuning*(RandomNumber(seed)-0.5)); forwardP = backwardP = 1.0; oldM = newM = 0.0; lnNewBrlenPr = lnOldBrlenPr = 0.0; if (!strcmp(brlenprModel, "exponential")) { for (i=0; ilength); } } /* Set flags for updating conditional likelihoods to NO (meaning don't update CL). */ for (i=0; iupDateCl = NO; } /* Pick a branch at random. This is the branch that is "removed". */ do { p = allNodesDownPassSeq[whichChain*2*numNodes + proposedState*numNodes + (int)(RandomNumber(seed)*numNodes)]; } while (p->anc == NULL); q = p->anc; oldM += p->length; p->length *= mult; newM += p->length; /* Mark all branches with distance from removed branch (p). */ for (i=0; iflag = -1; u->marked = NO; } p->flag = 0; for (i=numNodes-1; i>=0; i--) { u = allNodesDownPassSeq[whichChain*2*numNodes + proposedState*numNodes + i]; if (u != p && u != q && u->anc != NULL && u->flag == -1) { if (u->anc->flag >= 0) u->flag = u->anc->flag + 1; } } /* mark branches above p that are within reconnection limit of p */ nMarkedAbove = 0; for (i=0; iflag <= reconLimit && u->flag >= 0) { u->marked = YES; nMarkedAbove++; } } if (p->left != NULL && p->right != NULL) { if (p->right->marked == YES) { p->right->marked = NO; nMarkedAbove--; } } /* now pick one of the branches above p to be the new point of attachment */ if (nMarkedAbove > 0) { whichBranch = RandomNumber(seed) * nMarkedAbove; nVisited = 0; for (i=0; imarked == YES) { if (whichBranch == nVisited) break; nVisited++; } } a = u; } else a = p; /* update proposal probabilities */ if (nMarkedAbove > 0) forwardP *= (1.0 / (double)(nMarkedAbove)); if (p->left != NULL && p->right != NULL) backwardP *= 1.0 / (p->left->length + p->right->length); /* rotate tree above p until a is just to the left or right of p */ for (i=0; imarked = NO; } u = a; u->marked = YES; while (u != p && u->anc != NULL) { oldM += u->length; u->length *= mult; newM += u->length; u->marked = YES; u = u->anc; } if (a != p) /* update proposal */ forwardP *= 1.0 / (a->length); /* probabilities */ stopLoop = NO; hasTopologyChanged = NO; # if defined (TOPOLOGY_MOVE_STATS) gNodeMoves = 0; # endif while (stopLoop == NO) { if (p->left != NULL && p->right != NULL) { if (p == a) stopLoop = YES; else if (p->left == a || p->right == a) stopLoop = YES; else { if (p->left->marked == YES) { b1 = p->left; b0 = p->right; } else { b1 = p->right; b0 = p->left; } if (b1->left != NULL && b1->right != NULL) { if (b1->left->marked == YES && b1->right->marked == NO) { b11 = b1->left; b10 = b1->right; } else if (b1->left->marked == NO && b1->right->marked == YES) { b11 = b1->right; b10 = b1->left; } else { b11 = b1->left; b10 = b1->right; } } else stopLoop = YES; if (stopLoop == NO) { if (p->right == b1) { p->left = b1; p->right = b11; b1->anc = b11->anc = p; b1->left = b0; b1->right = b10; b0->anc = b10->anc = b1; b0->length += b1->length; tempLength = b11->length; newLength = RandomNumber(seed) * tempLength; b1->length = newLength; b11->length = tempLength - newLength; b1->marked = NO; } else { p->left = b11; p->right = b1; b1->anc = b11->anc = p; b1->left = b0; b1->right = b10; b0->anc = b10->anc = b1; b0->length += b1->length; tempLength = b11->length; newLength = RandomNumber(seed) * tempLength; b1->length = newLength; b11->length = tempLength - newLength; b1->marked = NO; } hasTopologyChanged = YES; # if defined (TOPOLOGY_MOVE_STATS) gNodeMoves++; # endif } } } else stopLoop = YES; } # if defined (DEBUG_TBR) for (i=0; iindex, u->flag, u->marked, p->index, q->index); } printf ("nMarkedAbove = %d, %d\n", nMarkedAbove, a->index); printf ("Middle:\n"); ShowNodes (root[whichChain*2+proposedState], 2, NO); # endif /* update downpass sequence, if the topology has changed */ if (hasTopologyChanged == YES) { i = j = 0; GetDownPassSeq (root[whichChain*2 + proposedState], proposedState, whichChain, numTaxa, &i, &j); } /* mark all branches with distance from removed branch (q) */ for (i=0; iflag = -1; u->marked = NO; } q->flag = 0; u = q; while (u->anc != NULL) { u->anc->flag = u->flag + 1; u = u->anc; } for (i=numNodes-1; i>=0; i--) { u = allNodesDownPassSeq[whichChain*2*numNodes + proposedState*numNodes + i]; if (u != p && u != q && u->anc != NULL && u->flag == -1 && u->anc->flag >= 0) { u->flag = u->anc->flag + 1; } } /* mark branches above q that are within reconnection limit of q */ nMarkedBelow = 0; for (i=0; iflag <= reconLimit && u->flag >= 0 && u->anc != NULL) { u->marked = YES; nMarkedBelow++; } } /* now pick one of the branches marked around q to be the new point of attachment */ if (nMarkedBelow > 0) { whichBranch = RandomNumber(seed) * nMarkedBelow; nVisited = 0; for (i=0; imarked == YES) { if (whichBranch == nVisited) break; nVisited++; } } a = u; } else a = q; /* update proposal probabilities */ if (nMarkedBelow > 0) forwardP *= (1.0 / (double)(nMarkedBelow)); if (q->anc != NULL) { tempLength = q->length; if (q->left == p) tempLength += q->right->length; else tempLength += q->left->length; backwardP *= 1.0 / tempLength; } if (a != q) { forwardP *= 1.0 / (a->length*mult); } /* multiply branches on path between a and q by mult */ for (i=0; imarked = NO; if (u == a || u == q) u->marked = YES; } for (i=0; ileft != NULL && u->right != NULL) { if (u->left->marked == YES && u->right->marked == NO) u->marked = YES; else if (u->left->marked == NO && u->right->marked == YES) u->marked = YES; } if (u->marked == YES) { # if defined (TOPOLOGY_MOVE_STATS) if (u != q) gNodeMoves++; # endif oldM += u->length; u->length *= mult; newM += u->length; } } /* move q to new position at branch a */ if (q->anc == NULL || nMarkedBelow == 0) { /* don't do anything, as q is at the root of the tree */ } else { if (q->left == p) b1 = q->right; else b1 = q->left; b0 = q->anc; if (b0->left == q) { b0->left = b1; b1->anc = b0; b1->length += q->length; q->length = 0.0; q->anc = NULL; } else if (b0->right != NULL) { if (b0->right == q) { b0->right = b1; b1->anc = b0; b1->length += q->length; q->length = 0.0; q->anc = NULL; } else { printf ("problems in tbr\n"); } } if (a->anc == NULL) printf ("problem in tbr\n"); else { b1 = a->anc; if (b1->left == a) b1->left = q; else b1->right = q; q->anc = b1; q->left = p; q->right = a; p->anc = a->anc = q; tempLength = a->length; newLength = tempLength * RandomNumber(seed); a->length = newLength; q->length = tempLength - newLength; } } /* update downpass sequence */ i = j = 0; GetDownPassSeq (root[whichChain*2 + proposedState], proposedState, whichChain, numTaxa, &i, &j); /* update conditional likelihoods */ UpDateAllCls (proposedState, whichChain); /* update proposal probabilities */ for (i=0; iflag = -1; u->marked = NO; } p->flag = 0; for (i=numNodes-1; i>=0; i--) { u = allNodesDownPassSeq[whichChain*2*numNodes + proposedState*numNodes + i]; if (u != p && u != q && u->anc != NULL && u->flag == -1) { if (u->anc->flag >= 0) u->flag = u->anc->flag + 1; } } nMarkedAbove = 0; for (i=0; iflag <= reconLimit && u->flag >= 0) { u->marked = YES; nMarkedAbove++; } } if (p->left != NULL && p->right != NULL) { if (p->right->marked == YES) { p->right->marked = NO; nMarkedAbove--; } } for (i=0; iflag = -1; u->marked = NO; } q->flag = 0; u = q; while (u->anc != NULL) { u->anc->flag = u->flag + 1; u = u->anc; } for (i=numNodes-1; i>=0; i--) { u = allNodesDownPassSeq[whichChain*2*numNodes + proposedState*numNodes + i]; if (u != p && u != q && u->anc != NULL && u->flag == -1 && u->anc->flag >= 0) { u->flag = u->anc->flag + 1; } } nMarkedBelow = 0; for (i=0; iflag <= reconLimit && u->flag >= 0 && u->anc != NULL) { u->marked = YES; nMarkedBelow++; } } if (nMarkedAbove > 0) backwardP *= (1.0 / (double)nMarkedAbove); if (nMarkedBelow > 0) backwardP *= (1.0 / (double)nMarkedBelow); forwardP *= oldM; backwardP *= newM; *lnProposalRatio = log(backwardP) - log(forwardP); //printf ("%lf %lf \n", log(backwardP), log(forwardP)); # if defined (DEBUG_TBR) for (i=0; iindex, u->flag, u->marked, p->index, q->index); } printf ("nMarkedBelow = %d, %d\n", nMarkedBelow, a->index); printf ("End:\n"); ShowNodes (root[whichChain*2+proposedState], 2, NO); //exit (0); # endif if (!strcmp(brlenprModel, "exponential")) { for (i=0; ilength); } } (*lnPriorRatio) = lnNewBrlenPr - lnOldBrlenPr; # if defined (TOPOLOGY_MOVE_STATS) if (hasTopologyChanged == YES) gTopologyHasChanged = YES; else gTopologyHasChanged = NO; # endif # if defined (SMART_TI_PROBS) // TO DO: Figure out exactly which branches need their transition matrices updated. UpDateAllTIs (proposedState, whichChain); # endif return (NO_ERROR); } /* change branch lengths and topology (potentially) using TBR (unrooted) */ int Move_ChangeFTBR (int numTaxa, int proposedState, int whichChain, long int *seed, double *lnProposalRatio, double *lnPriorRatio) { /* this move type picks a branch and two "danglies", modifies their length independently according to the method of Larget & Simon (1999: MBE); it then moves the danglies away from their original position one node at a time with a probability determined by the extensionProb parameter when the danglies are moved, their direction is changed this "reflection" is necessary to enable the back move As of 5 March 2001 06:00 the move type has been tested extensively on unrooted and unconstrained trees (replicase.nex and adh.nex) and gives similar results to BAMBE's local However, convergence in branch lengths may be slow unless it is combined with a move that changes single branchlengths or the proportionality of adjacent branches, like BAMBE's local The move type should work also for rooted or constrained trees */ int i, j, topologyHasChanged, nCrownNodes, nRootNodes, directionLeft, directionUp; int allNodesPointer, intNodePointer, allNodesStop; double m, x, y, tuning, maxV, extensionProb; TreeNode *p, *a, *b, *c, *d, *u, *v; // these parameters should be possible to set by user extensionProb = tbrExtendPProp; // extension probability tuning = tbrTuneProp; /* Larget & Simon's tuning parameter lambda */ // max brlen maxV = chainMaxs[CHANGE_UNROOT_LOCAL]; topologyHasChanged = NO; // set pointers allNodesPointer = whichChain*2*numNodes + proposedState*numNodes; intNodePointer = whichChain*2*numIntNodes + proposedState*numIntNodes; allNodesStop = allNodesPointer + numNodes; // unmark all nodes with respect to update for (i=allNodesPointer; iupDateCl = NO; } # if defined (DEBUG_FTBR) printf ("Before:\n"); ShowNodes (root[whichChain*2+proposedState], 2, NO); getchar(); # endif /* pick an internal branch */ do { p = intNodeDownPassSeq[intNodePointer + (int)(RandomNumber(seed)*numIntNodes)]; } while (p->anc->anc == NULL); /* set up pointers for nodes around the picked branch */ /* cut the tree into crown, root and attachment part */ /* change the relevant lengths in the attachment part */ /* the lengths of a and v are automatically contained in the */ /* "attachment" part but the length of c has to be stored in x */ v = p; u = p->anc; /* set up pointers for crown part */ /* this also determines direction of move in crown part */ if (RandomNumber(seed) < 0.5) { c = v->left; d = v->right; directionLeft = YES; } else { c = v->right; d = v->left; directionLeft = NO; } /* cut and reconnect crown part */ c->anc = d; d->anc = c; /* record c length and adjust */ m = c->length; x = c->length * exp(tuning * (RandomNumber(seed) - 0.5)); // save the modified dangling branch for later use if (x < BRLEN_EPSILON) x = BRLEN_EPSILON; if (x > maxV) x = maxV; /* calculate proposal and prior ratio based on length modification */ (*lnProposalRatio) = (log(x) - log(m)); if (!strcmp(brlenprModel, "exponential")) (*lnPriorRatio) += brlenprExp * m - brlenprExp * x; /* record v length and adjust */ m = v->length; v->length *= exp(tuning * (RandomNumber(seed) - 0.5)); if (v->length < BRLEN_EPSILON) v->length = BRLEN_EPSILON; if (v->length > maxV) v->length = maxV; /* adjust proposal and prior ratio based on length modification */ (*lnProposalRatio) += (log(v->length) - log(m)); if (!strcmp(brlenprModel, "exponential")) (*lnPriorRatio) += brlenprExp * m - brlenprExp * v->length; /* mark nodes in root part */ /* also determines direction of move in root part */ if (RandomNumber(seed) < 0.5) { if (u->left == v) a = u->right; else a = u->left; b = u->anc; directionUp = YES; } else { if (u->left == v) b = u->right; else b = u->left; a = u->anc; directionUp = NO; } /* cut root part*/ /* store branch to be modified in u->length */ if (directionUp == NO) { b->anc = a; if (a->left == u) a->left = b; else a->right = b; } else { a->anc = b; if (b->left == u) b->left = a; else b->right = a; y = a->length; a->length = u->length; u->length = y; } /* adjust length of branch to be modified */ /* if it is not the root branch of a rooted tree */ if (!(treeModel == ROOTED && u->anc->anc == NULL)) { m = u->length; u->length *= exp(tuning * (RandomNumber(seed) - 0.5)); if (u->length < BRLEN_EPSILON) u->length = BRLEN_EPSILON; if (u->length > maxV) u->length = maxV; /* adjust proposal and prior ratio based on length modification */ (*lnProposalRatio) += (log(u->length) - log(m)); if (!strcmp(brlenprModel, "exponential")) (*lnPriorRatio) += brlenprExp * m - brlenprExp * u->length; } // adjust proposal ratio for backward move in root subtree // if starting from interior, unconstrained branch // double test needed to capture the case of no move if (directionUp == NO && b->left!=NULL && b->isConstrained == NO && a->anc!=NULL && a->isConstrained == NO) (*lnProposalRatio) += log(1-extensionProb); if (directionUp == YES && a->left!=NULL && a->isConstrained == NO && b->anc!=NULL && b->isConstrained == NO) (*lnProposalRatio) += log(1-extensionProb); // adjust proposal ratio for backward move in crown subtree // if starting from interior, unconstrained branch // double test is needed to capture the case of no move if (c->left!=NULL && c->isConstrained == NO && d->left!=NULL && d->isConstrained == NO) (*lnProposalRatio) += log(1-extensionProb); // move around in root subtree nRootNodes = 0; if (u->isConstrained == NO) { for (; RandomNumber(seed)left == NULL || a->isConstrained == YES) break; /* can't go further */ topologyHasChanged = YES; b = a; if (RandomNumber(seed)<0.5) a = a->left; else a = a->right; } else { // going down tree if (a->anc == NULL || a->isConstrained == YES) break; /*can't go further */ topologyHasChanged = YES; if (RandomNumber(seed)<0.5) { directionUp = YES; // switch direction // find sister of a if (a->left == b) { b = a; a = a->right; } else { b = a; a = a->left; } // as long as we are moving upwards // the cond likes to update will be // flagged by the last pass from u to the root } else { // continue down b = a; a = a->anc; b->upDateCl = YES; } } } } // adjust proposal ratio for forward move if stop branch is interior & unconstrained // test of both ends makes sure that no adjustment is made if no move was made if (directionUp == YES) { if (a->left != NULL && a->isConstrained == NO && b->anc != NULL && b->isConstrained == NO) (*lnProposalRatio) -= log(1-extensionProb); } else { if (a->anc != NULL && a->isConstrained == NO && b->left != NULL && b->isConstrained == NO) (*lnProposalRatio) -= log(1-extensionProb); } // move around in crown subtree nCrownNodes = 0; if (v->isConstrained == NO) { for (; RandomNumber(seed)left == NULL || c->isConstrained == YES) break; /* can't go further */ topologyHasChanged = YES; if (RandomNumber(seed)<0.5) { // rotate c anticlockwise - prepare pointers for move left c->anc = c->left; // the root will be in the direction we are heading c->left = c->right; c->right = d; } else { // rotate c clockwise - prepare pointers for move right c->anc = c->right; // the root will be in the direction we are heading c->right = c->left; c->left = d; } /* OK - let's move!; c->anc points in the right direction don't forget to move the branch lengths as well */ d = c; c = c->anc; d->length = c->length; d->upDateCl = YES; } } // adjust proposal ratio for forward move if stop branch is interior & unconstrained // double test makes sure that no adjustment is made if no move was made if (c->left != NULL && c->isConstrained == NO && d->left != NULL && d->isConstrained == NO) (*lnProposalRatio) -= log(1-extensionProb); // combine the subtrees c->anc = v; d->anc = v; if (directionLeft == YES) { v->left = c; v->right = d; } else { v->left = d; v->right = c; } // the dangling branch is inserted in reverted position // such that the back move will be possible // if we have moved around in crown subtree // otherwise it is left in its original position if (nCrownNodes > 0) d->length = x; else c->length = x; if (directionUp == YES) { u->anc = b; if (u->left == v) u->right = a; else u->left = a; a->anc = u; if (b->left == a) b->left = u; else b->right = u; /* the dangling branch is contained in u->length and will automatically be inserted in the right position to enable the back move regardless of whether it was initially directed upwards or downwards BUT if we haven't moved in root subtree, it is advantageous (necessary for rooted trees) to avoid switching branches, which occurs otherwise */ // if directionUp == YES if (nRootNodes == 0) { x = u->length; u->length = a->length; a->length = x; } } else { u->anc = a; if (u->left == v) u->right = b; else u->left = b; b->anc = u; if (a->left == b) a->left = u; else a->right = u; /* the modified branch contained in u->length will have to be moved to b->length to enable back move BUT if we haven't moved, it is better to keep it in place (necessary for rooted trees) */ if (nRootNodes > 0) { x = u->length; u->length = b->length; b->length = x; } } /* set flags for update of cond likes from v and down to root */ p = v; while (p->anc != NULL) { p->upDateCl = YES; p = p->anc; } /* get down pass sequence if tree topology has changed */ if (topologyHasChanged == YES) { i = j = 0; GetDownPassSeq (root[whichChain*2 + proposedState], proposedState, whichChain, numTaxa, &i, &j); } # if defined (DEBUG_FTBR) printf ("After:\n"); ShowNodes (root[whichChain*2+proposedState], 2, NO); getchar(); printf ("Proposal ratio: %f\n",(*lnProposalRatio)); printf ("v: %d u: %d c: %d d: %d a: %d b: %d\n",v->index, u->index, c->index, d->index, a->index, b->index); printf ("No. nodes moved in root subtree: %d\n",nRootNodes); printf ("No. nodes moved in crown subtree: %d\n",nCrownNodes); printf ("Has topology changed? %d\n",topologyHasChanged); getchar(); # endif # if defined (TOPOLOGY_MOVE_STATS) if (topologyHasChanged == YES) gTopologyHasChanged = YES; else gTopologyHasChanged = NO; gNodeMoves = nCrownNodes + nRootNodes; # endif # if defined (SMART_TI_PROBS) // TO DO: Figure out exactly which branches need their transition matrices updated. UpDateAllTIs (proposedState, whichChain); # endif return (NO_ERROR); } /* change one branch length */ int Move_ChangeBrLen (int proposedState, int whichChain, long int *seed, double *lnProposalRatio, double *lnPriorRatio) { int i, allNodesPointer, allNodesStop; double lenFactor, tuning, maxV, m; TreeNode *p; /* this parameter should be possible to set by user For the dataset adh.nex, multiplying Larget & Simon's suggested tuning parameter (0.19) with 10.0 results in acceptance probability around 50%, which is, arguably, optimal */ tuning = blTuneProp; /* Larget & Simon's tuning parameter lambda */ // max brlen maxV = chainMaxs[CHANGE_UNROOT_LOCAL]; // set up pointers allNodesPointer = whichChain*2*numNodes + proposedState*numNodes; allNodesStop = allNodesPointer + numNodes; // unmark all nodes with respect to update for (i=allNodesPointer; iupDateCl = NO; } /* pick a branch */ do { p = allNodesDownPassSeq[allNodesPointer + (int)(RandomNumber(seed)*numNodes)]; } while (p->anc == NULL || (treeModel == ROOTED && p->anc->anc == NULL)); /* determine length multiplication factor */ lenFactor = exp(tuning * (RandomNumber(seed) - 0.5)); m = p->length; p->length *= lenFactor; // check new length of p if (p->length < BRLEN_EPSILON) p->length = BRLEN_EPSILON; if (p->length > maxV) p->length = maxV; /* set flags for update of cond likes from p->anc and down to root */ p->upDateCl = YES; while (p->anc != NULL) { p->upDateCl = YES; p = p->anc; } /* set flags for update of transition probabilities at p */ # if defined (SMART_TI_PROBS) p->upDateTi = YES; # endif /* calculate proposal ratio */ (*lnProposalRatio) = (log(m * lenFactor) - log(m)); /* calculate prior ratio if exponential prior on branch lengths */ /* if birth-death prior we should not be in this move type */ if (!strcmp(brlenprModel, "exponential")) (*lnPriorRatio) = brlenprExp * m - brlenprExp * m * lenFactor; else (*lnPriorRatio) = 0.0; # if defined (SMART_TI_PROBS) UpDateAllTIs (proposedState, whichChain); # endif return (NO_ERROR); } /*------------------------------------------------------------ | OpenFile: open a file, print #NEXUS if a new NEXUS file, | print appropriate error message if operation failed \-----------------------------------------------------------*/ FILE *OpenFile (char *filename, int isNexus) { FILE *fp; if ((fp = fopen (filename, "r")) == NULL) { fp = fopen (filename, "w"); if (fp != NULL) { printf (" Creating output file %s\n", filename); #if defined (MORPH) if (isNexus == YES) fprintf (fp, "#NEXUS\n"); } #endif } else { fclose (fp); if (autoclose == YES) { printf (" Appending information to file %s\n", filename); fp = fopen (filename, "a+"); } else { printf ("\n File \"%s\" already exists.\n Overwrite? (yes/no): ", filename); if (YesNo() == YES) { printf (" Overwriting information to file %s\n", filename); fp = fopen (filename, "w+"); } else { printf (" Appending information to file %s\n", filename); fp = fopen (filename, "a+"); } } } if (fp == NULL) { printf ("\n ERROR: Could not open file (%s).\n", filename); } return fp; } int NumAdjacentMarked (TreeNode *p) { int i; i = 0; if (p->left != NULL) { if (p->left->marked == YES) i++; } if (p->right != NULL) { if (p->right->marked == YES) i++; } if (p->anc != NULL) { if (p->anc->marked == YES) i++; } return (i); } double ParsimonyLength (int whichState, int whichChain, int numChars) { register int c; int n, intNodeOffset, oneMatSize; unsigned int *cl, *clL, *clR, *clA, x, y, z; double pLength; TreeNode *p; intNodeOffset = whichChain*2*numIntNodes + whichState*numIntNodes; oneMatSize = numNodes * numChars; pLength = 0.0; for (n=0; nindex); cl = &stateSet[whichChain*oneMatSize + (p->index)*numChars]; if (p->anc->anc == NULL) { clL = &stateSet[whichChain*oneMatSize + (p->left->index)*numChars]; clR = &stateSet[whichChain*oneMatSize + (p->right->index)*numChars]; clA = &stateSet[whichChain*oneMatSize + (p->anc->index)*numChars]; for (c=0; cleft->index)*numChars]; clR = &stateSet[whichChain*oneMatSize + (p->right->index)*numChars]; for (c=0; c= 0.0 && ran <= cumProposalProbs[0]) move = CHANGE_QMAT; else if (ran >cumProposalProbs[0] && ran <= cumProposalProbs[1]) move = CHANGE_BASEFREQS; else if (ran >cumProposalProbs[1] && ran <= cumProposalProbs[2]) move = CHANGE_GAMMA_SHAPE; else if (ran >cumProposalProbs[2] && ran <= cumProposalProbs[3]) move = CHANGE_SITE_RATES; else if (ran >cumProposalProbs[3] && ran <= cumProposalProbs[4]) move = CHANGE_UNROOT_LOCAL; else if (ran >cumProposalProbs[4] && ran <= cumProposalProbs[5]) move = CHANGE_CLOCK_LOCAL; else if (ran >cumProposalProbs[5] && ran <= cumProposalProbs[6]) move = CHANGE_CLOCK_TIME_LOCAL; else if (ran >cumProposalProbs[6] && ran <= cumProposalProbs[7]) move = CHANGE_TREE_HEIGHT; else if (ran >cumProposalProbs[7] && ran <= cumProposalProbs[8]) move = CHANGE_WORM; else if (ran >cumProposalProbs[8] && ran <= cumProposalProbs[9]) move = CHANGE_NODE_TIME; else if (ran >cumProposalProbs[9] && ran <= cumProposalProbs[10]) move = CHANGE_BD_PARAMS; /* make perturbation */ lnPriorRatio = lnProposalRatio = 0.0; if (move == CHANGE_UNROOT_LOCAL) { /* change topology of unrooted tree or rooted and unconstrained tree using LOCAL */ if (Move_ChangeUnrootedWithLocal (numTaxa, 0, chain, seed, &lnProposalRatio, &lnPriorRatio) == ERROR) return (ERROR); } else if (move == CHANGE_CLOCK_LOCAL) { /* change topology of rooted tree with clock constraint using LOCAL */ if (Move_ChangeClockWithLocal (numTaxa, 0, chain, seed, &lnProposalRatio, &lnPriorRatio) == ERROR) return (ERROR); } else if (move == CHANGE_CLOCK_TIME_LOCAL) { /* change topology and times of rooted tree with clock constraint using LOCAL (divergence time estimation) */ if (Move_ChangeTimeClockWithLocal (numTaxa, 0, chain, seed, &lnProposalRatio, &lnPriorRatio) == ERROR) return (ERROR); } else { printf (" ERROR: Unknown perturbation\n"); return (ERROR); } /* copy information */ CopyTree (0, 1, chain); } } # if 0 for (n=0; n 1) { fprintf (fp1, "alpha\t"); // TODO: change header to something more suitable fprintf (fp2, ", alpha"); } #endif if (((dataType == DNA || dataType == RNA) && enforceCodonModel == NO) || dataType == PROTEIN || dataType == RESTRICTION) { if (!strcmp(ratesModel, "gamma")) { fprintf (fp1, "alpha\t"); fprintf (fp2, ", alpha"); } else if (!strcmp(ratesModel, "adgamma")) { fprintf (fp1, "alpha\t"); fprintf (fp2, ", alpha"); fprintf (fp1, "rho\t"); fprintf (fp2, ", rho"); if (!strcmp(lagprModel, "uniform") || !strcmp(lagprModel, "exponential")) { fprintf (fp1, "offset\t"); fprintf (fp2, ", offset"); } } else if (!strcmp(ratesModel, "sitespec")) { for (i=0; ileft == NULL || p->right == NULL || (treeModel == UNROOTED && p->anc == NULL)) { if (isFirst == NO) fprintf (fp2, ",\n"); if (treeModel == ROOTED && p->anc != NULL) fprintf (fp2, " %4d %s", p->index + 1, p->label); else if (treeModel == UNROOTED) fprintf (fp2, " %4d %s", p->index + 1, p->label); isFirst = NO; } } fprintf (fp2, ";\n"); fflush (fp2); return NO_ERROR; error_exit: if (pFile!=NULL) fclose(pFile); if (bpFile!=NULL) fclose(bpFile); if (tFile!=NULL) fclose(tFile); return ERROR; } int PrepareParsOutputFiles (void) { int i, j, isFirst; char pFilename[100], bpFilename[100], tFilename[100]; TreeNode *p; FILE *fp1, *fp2; /* prepare output file names */ strcpy (pFilename, outFile); strcpy (bpFilename, outFile); strcpy (tFilename, outFile); strcat (pFilename, ".p"); strcat (bpFilename, ".bp"); strcat (tFilename, ".t"); /* reset output file pointers */ pFile = bpFile = tFile = NULL; /* open files */ if ((pFile = OpenFile(pFilename, NO))==NULL) goto error_exit; if ((bpFile = OpenFile(bpFilename, YES))==NULL) goto error_exit; if ((tFile = OpenFile(tFilename, YES))==NULL) goto error_exit; fp1 = pFile; fp2 = bpFile; /* print headers to pFile and bpFile */ fprintf (fp2, "#NEXUS\n\n"); fprintf (fp2, "begin bayesparams;\n"); fprintf (fp1, "Gen\tlnL\t"); fprintf (fp1, "TL\t"); fprintf (fp2, " header Gen, lnL"); fprintf (fp2, ", TL"); fprintf (fp1, "\n"); fprintf (fp2, ";\n"); fflush(fp1); fflush(fp2); fp2 = tFile; fprintf (fp2, "begin trees;\n"); fprintf (fp2, " translate\n"); isFirst = YES; j = 0; for (i=0; ileft == NULL || p->right == NULL || (treeModel == UNROOTED && p->anc == NULL)) { if (isFirst == NO) fprintf (fp2, ",\n"); if (treeModel == ROOTED && p->anc != NULL) fprintf (fp2, " %4d %s", p->index + 1, p->label); else if (treeModel == UNROOTED) fprintf (fp2, " %4d %s", p->index + 1, p->label); isFirst = NO; } } fprintf (fp2, ";\n"); fflush (fp2); return NO_ERROR; error_exit: if (pFile!=NULL) fclose(pFile); if (bpFile!=NULL) fclose(bpFile); if (tFile!=NULL) fclose(tFile); return ERROR; } int PrintAncStatesDNA (int whichState, int whichChain, int numChars, int numRateCats, int whichGen) { #define N_STATES 4 #define N_STATES_SQUARED 16 #define N_STATES_CUBE 64 register int i, j, k, c, n, n1, l, startingJ; int lnumRateCats, lnPartitions, oneMatSize, oneNodeSize, index, nRates, pat, intNodeOffset, allNodeOffset, condLikeOffset; double bs[N_STATES], *pL, *pR, *pA, *catFreq, *catRate, *partRate, *clL, *clR, *clA, *clP, *tiPL, *tiPR, *tiPA, *lnScaler, correlation, lnSeqProb, maxProb, **markovTi, like[4], sum, postProb[4], *f, *b, *expPr, *logCf, *logCb, *tempRatePr, *rateProbs, logC, temp, logLike, *ancCls; char tempFile[100], tempFileA[100], tempFileC[100], tempFileG[100], tempFileT[100], bestNuc; TreeNode *p, *r, *rDn, *rUp; FILE *fp, *fopen(); # if defined (SMART_TI_PROBS) int nForOneState; # else register int m; int isComplex, indexL, indexR, indexA, nPij; double v, lkappa, theRate, **probs, **q, *eigenValues, *eigvalsImag, **eigvecs, **inverseEigvecs, *c_ijk; complex **Ceigvecs, **CinverseEigvecs; # endif /* initialize intNodeOffset */ intNodeOffset = whichChain*2*numIntNodes + whichState*numIntNodes; allNodeOffset = whichChain*2*numNodes + whichState*numNodes; /* initialize offset for transition probabilities */ # if defined (SMART_TI_PROBS) nForOneState = numNodes*nodeTiSize; # endif /* load base frequencies */ index = whichChain*2*N_STATES + whichState*N_STATES; bs[A] = baseFreq[index + A]; bs[C] = baseFreq[index + C]; bs[G] = baseFreq[index + G]; bs[T] = baseFreq[index + T]; /* how many different rates? */ /* lnumRateCats contains a local copy of numRateCats if appropriate, else 1 */ /* lnPartitions contains a local copy of nPartitions if appropriate, else 1 */ /* the code introduced here only makes sure that the number of partitions */ /* or rate categories is set to 1 when appropriate, in case the global variables */ /* are not set to 1 when they are not "in use" */ if (!strcmp(ratesModel, "sitespec") || !strcmp(ratesModel, "ssgamma") || !strcmp(ratesModel, "ssadgamma")) lnPartitions = nPartitions; else lnPartitions = 1; if (!strcmp(ratesModel, "equal") || !strcmp(ratesModel, "sitespec")) lnumRateCats = 1; else lnumRateCats = numRateCats; nRates = lnPartitions * lnumRateCats; // number of rates needing P matrices /* allocate memory for the calculations */ /* pL, pR and pA will contain the transition probs for Left, Right and Anc */ /* One transition probability matrix is needed for each possible rate */ # if !defined (SMART_TI_PROBS) probs = psdmatrix (N_STATES); nPij = nRates * N_STATES_SQUARED; pL = (double *)malloc((size_t)(3 * nPij * sizeof(double))); if (!pL) { printf ("\n ERROR: Problem allocating Pij\n"); goto error_exit; } pR = pL + nPij; pA = pR + nPij; # endif /* allocate memory for ancestral conditional likelihoods (it may be a tip, and we don't want to overwrite these cls) */ ancCls = (double *)malloc((size_t) (lnumRateCats * numChars * N_STATES * sizeof(double))); if (!ancCls) { printf ("\n ERROR: Problem allocating space for rate multipliers and rate category freqs.\n"); goto error_exit; } /* allocate memory for rate and rate category frequencies */ catFreq = (double *)malloc((size_t) ((2 * lnumRateCats + lnPartitions) * sizeof(double))); if (!catFreq) { printf ("\n ERROR: Problem allocating space for rate multipliers and rate category freqs.\n"); goto error_exit; } catRate = catFreq + lnumRateCats; partRate = catRate + lnumRateCats; /* allocate memory for autocorrelated gamma models */ if (!strcmp(ratesModel, "adgamma") || !strcmp(ratesModel, "ssadgamma")) { f = (double *)malloc((size_t) (((lnumRateCats * nChar) * 2 + lnumRateCats + nChar*2) * sizeof(double))); if (!f) { printf ("\n ERROR: Problem allocating f.\n"); goto error_exit; } b = f + lnumRateCats * nChar; expPr = b + lnumRateCats * nChar; logCf = expPr + lnumRateCats; logCb = logCf + nChar; for (i=0; i 1) { for (i=0; iisConstrained == YES) { /* mark nodes below p */ for (n1=0; n1flag = 0; if (r == p) r->flag = 1; if (r->left != NULL && r->right != NULL) { if (r->left->flag == 1 || r->right->flag == 1) r->flag = 1; } } /* get conditional likelihoods down tree */ for (n1=0; n1flag != 1) { //printf ("visiting interior node %d dn\n", r->index); /* get transition probabilities */ # if defined (SMART_TI_PROBS) pL = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (r->left->index)*nodeTiSize); pR = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (r->right->index)*nodeTiSize); # else if (nst == 1 || nst == 2) { for (m=indexL=indexR=0; mleft->length, lkappa, theRate, bs[A], bs[C], bs[G], bs[T]); for (i=0; i<4; i++) for (j=0; j<4; j++) pL[indexL++] = probs[i][j]; /* calculate transition probabilities for right branch */ HkyChangeMat (probs, r->right->length, lkappa, theRate, bs[A], bs[C], bs[G], bs[T]); for (i=0; i<4; i++) for (j=0; j<4; j++) pR[indexR++] = probs[i][j]; } } } else // nst == 6 or nst == 12 { for (m=indexL=indexR=0; mleft->length, theRate, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, 4, probs, r->left->length, theRate) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; i<4; i++) for (j=0; j<4; j++) pL[indexL++] = probs[i][j]; // calculate transition probabilities for right branch if (isComplex == NO) CalcPij (c_ijk, 4, eigenValues, r->right->length, theRate, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, 4, probs, r->right->length, theRate) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; i<4; i++) for (j=0; j<4; j++) pR[indexR++] = probs[i][j]; } } } # endif /* first set pointers to cond likes of left, right and p */ clL = &condLike[condLikeOffset + (r->left->index)*oneNodeSize]; clR = &condLike[condLikeOffset + (r->right->index)*oneNodeSize]; clP = &condLike[condLikeOffset + (r->index)*oneNodeSize]; if (!strcmp(ratesModel, "equal")) { tiPL = pL; tiPR = pR; for (c=0; c=0; n1--) { r = intNodeDownPassSeq[intNodeOffset + n1]; if (r->flag == 1 && p != r) { rDn = r->anc; if (r->left->flag == 0) rUp = r->left; else rUp = r->right; //printf ("visiting interior node %d up\n", r->index); /* get transition probabilities */ # if defined (SMART_TI_PROBS) pL = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (rUp->index)*nodeTiSize); pR = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (r->index)*nodeTiSize); # else if (nst == 1 || nst == 2) { for (m=indexL=indexR=0; mlength, lkappa, theRate, bs[A], bs[C], bs[G], bs[T]); for (i=0; i<4; i++) for (j=0; j<4; j++) pL[indexL++] = probs[i][j]; /* calculate transition probabilities for right branch */ HkyChangeMat (probs, r->length, lkappa, theRate, bs[A], bs[C], bs[G], bs[T]); for (i=0; i<4; i++) for (j=0; j<4; j++) pR[indexR++] = probs[i][j]; } } } else // nst == 6 or nst == 12 { for (m=indexL=indexR=0; mlength, theRate, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, 4, probs, rUp->length, theRate) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; i<4; i++) for (j=0; j<4; j++) pL[indexL++] = probs[i][j]; // calculate transition probabilities for right branch if (isComplex == NO) CalcPij (c_ijk, 4, eigenValues, r->length, theRate, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, 4, probs, r->length, theRate) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; i<4; i++) for (j=0; j<4; j++) pR[indexR++] = probs[i][j]; } } } # endif /* first set pointers to cond likes of left, right and p */ clL = &condLike[condLikeOffset + (rUp->index)*oneNodeSize]; clR = &condLike[condLikeOffset + (rDn->index)*oneNodeSize]; clP = &condLike[condLikeOffset + (r->index)*oneNodeSize]; if (!strcmp(ratesModel, "equal")) { tiPL = pL; tiPR = pR; for (c=0; cindex); /* get transition probabilities */ # if defined (SMART_TI_PROBS) if (p->left == NULL || p->right == NULL || p->anc == NULL) { if (p->anc == NULL) pA = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->left->index)*nodeTiSize); else pA = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->index)*nodeTiSize); } else { pL = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->left->index)*nodeTiSize); pR = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->right->index)*nodeTiSize); pA = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->index)*nodeTiSize); } # else if (nst == 1 || nst == 2) { if (p->left == NULL || p->right == NULL || p->anc == NULL) { if (p->anc == NULL) v = p->left->length; else v = p->length; for (m=indexL=indexR=indexA=0; mleft->length, lkappa, theRate, bs[A], bs[C], bs[G], bs[T]); for (i=0; i<4; i++) for (j=0; j<4; j++) pL[indexL++] = probs[i][j]; /* calculate transition probabilities for right branch */ HkyChangeMat (probs, p->right->length, lkappa, theRate, bs[A], bs[C], bs[G], bs[T]); for (i=0; i<4; i++) for (j=0; j<4; j++) pR[indexR++] = probs[i][j]; /* calculate transition probabilities for ancestral branch */ HkyChangeMat (probs, p->length, lkappa, theRate, bs[A], bs[C], bs[G], bs[T]); for (i=0; i<4; i++) for (j=0; j<4; j++) pA[indexA++] = probs[i][j]; } } } } else // nst == 6 or nst == 12 { if (p->left == NULL || p->right == NULL || p->anc == NULL) { if (p->anc == NULL) v = p->left->length; else v = p->length; for (m=indexL=indexR=indexA=0; mleft->length, theRate, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, 4, probs, p->left->length, theRate) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; i<4; i++) for (j=0; j<4; j++) pL[indexL++] = probs[i][j]; // calculate transition probabilities for right branch if (isComplex == NO) CalcPij (c_ijk, 4, eigenValues, p->right->length, theRate, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, 4, probs, p->right->length, theRate) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; i<4; i++) for (j=0; j<4; j++) pR[indexR++] = probs[i][j]; // calculate transition probabilities for ancestral branch if (isComplex == NO) CalcPij (c_ijk, 4, eigenValues, p->length, theRate, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, 4, probs, p->length, theRate) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; i<4; i++) for (j=0; j<4; j++) pA[indexA++] = probs[i][j]; } } } } # endif if (p->left == NULL || p->right == NULL || p->anc == NULL) { //clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; clP = ancCls; if (p->anc == NULL) clA = &condLike[condLikeOffset + (p->left->index)*oneNodeSize]; else clA = &condLike[condLikeOffset + (p->anc->index)*oneNodeSize]; if (!strcmp(ratesModel, "equal")) { tiPA = pA; for (c=0; cleft->index)*oneNodeSize]; clR = &condLike[condLikeOffset + (p->right->index)*oneNodeSize]; clA = &condLike[condLikeOffset + (p->anc->index)*oneNodeSize]; //clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; clP = ancCls; if (!strcmp(ratesModel, "equal")) { tiPL = pL; tiPR = pR; tiPA = pA; for (c=0; cindex)*oneNodeSize]; clP = ancCls; if (!strcmp(ratesModel, "equal") || !strcmp(ratesModel, "sitespec")) { for (c=0; c= 0) { like[A] = clP[pat*4 + A]; like[C] = clP[pat*4 + C]; like[G] = clP[pat*4 + G]; like[T] = clP[pat*4 + T]; sum = like[A] * bs[A] + like[C] * bs[C] + like[G] * bs[G] + like[T] * bs[T]; postProb[A] = (like[A] * bs[A]) / sum; postProb[C] = (like[C] * bs[C]) / sum; postProb[G] = (like[G] * bs[G]) / sum; postProb[T] = (like[T] * bs[T]) / sum; tempStateProbs[(p->constraintNum-1)*nChar*4 + c*4 + A] = postProb[A]; tempStateProbs[(p->constraintNum-1)*nChar*4 + c*4 + C] = postProb[C]; tempStateProbs[(p->constraintNum-1)*nChar*4 + c*4 + G] = postProb[G]; tempStateProbs[(p->constraintNum-1)*nChar*4 + c*4 + T] = postProb[T]; ancStatesProbs[(p->constraintNum-1)*nChar*4 + c*4 + A] += postProb[A]; ancStatesProbs[(p->constraintNum-1)*nChar*4 + c*4 + C] += postProb[C]; ancStatesProbs[(p->constraintNum-1)*nChar*4 + c*4 + G] += postProb[G]; ancStatesProbs[(p->constraintNum-1)*nChar*4 + c*4 + T] += postProb[T]; } } } else if (!strcmp(ratesModel, "gamma") || !strcmp(ratesModel, "invariant") || !strcmp(ratesModel, "invgamma") || !strcmp(ratesModel, "ssgamma")) { for (c=0; c= 0) { like[A] = like[C] = like[G] = like[T] = 0.0; for (k=0; kconstraintNum-1)*nChar*4 + c*4 + A] = postProb[A]; tempStateProbs[(p->constraintNum-1)*nChar*4 + c*4 + C] = postProb[C]; tempStateProbs[(p->constraintNum-1)*nChar*4 + c*4 + G] = postProb[G]; tempStateProbs[(p->constraintNum-1)*nChar*4 + c*4 + T] = postProb[T]; ancStatesProbs[(p->constraintNum-1)*nChar*4 + c*4 + A] += postProb[A]; ancStatesProbs[(p->constraintNum-1)*nChar*4 + c*4 + C] += postProb[C]; ancStatesProbs[(p->constraintNum-1)*nChar*4 + c*4 + G] += postProb[G]; ancStatesProbs[(p->constraintNum-1)*nChar*4 + c*4 + T] += postProb[T]; } } } else if (!strcmp(ratesModel, "adgamma") || !strcmp(ratesModel, "ssadgamma")) { /* get probabilities of observations conditioned on each category */ for (c=0; c= 0) { pat = patternId[c]; if (c == 0) { for (k=0; k=0; c--) { if (patternId[c] >= 0) { if (c == nChar - 1) { for (k=0; k 0.0) expPr[k] = 1.0; else if (temp < -100.0) expPr[k] = 0.0; else expPr[k] = exp(temp); } for (k=0; kindex)*oneNodeSize]; clP = ancCls; for (c=0; cconstraintNum-1)*nChar*4 + c*4 + A] = postProb[A]; tempStateProbs[(p->constraintNum-1)*nChar*4 + c*4 + C] = postProb[C]; tempStateProbs[(p->constraintNum-1)*nChar*4 + c*4 + G] = postProb[G]; tempStateProbs[(p->constraintNum-1)*nChar*4 + c*4 + T] = postProb[T]; ancStatesProbs[(p->constraintNum-1)*nChar*4 + c*4 + A] += postProb[A]; ancStatesProbs[(p->constraintNum-1)*nChar*4 + c*4 + C] += postProb[C]; ancStatesProbs[(p->constraintNum-1)*nChar*4 + c*4 + G] += postProb[G]; ancStatesProbs[(p->constraintNum-1)*nChar*4 + c*4 + T] += postProb[T]; } } } } /* summarize states */ /* print probabilities to a file */ strcpy (tempFileA, outFile); strcpy (tempFileC, outFile); strcpy (tempFileG, outFile); strcpy (tempFileT, outFile); strcat (tempFileA, ".A."); strcat (tempFileC, ".C."); strcat (tempFileG, ".G."); strcat (tempFileT, ".T."); if (nSampled == 1) { if (saveAncFiles == YES) startingJ = 0; else startingJ = 4; for (j=startingJ; j<5; j++) { if (j == 0) strcpy (tempFile, tempFileA); else if (j == 1) strcpy (tempFile, tempFileC); else if (j == 2) strcpy (tempFile, tempFileG); else if (j == 3) strcpy (tempFile, tempFileT); else { strcpy (tempFile, outFile); strcat (tempFile, ".sum."); } for (i=0; i= 0) { pat = patternId[c]; fprintf (fp, "%lf\t", tempStateProbs[i*nChar*4 + c*4 + A]); } } fprintf (fp, "\n"); fclose (fp); } /* C */ strcpy (tempFile, tempFileC); for (i=0; i= 0) { pat = patternId[c]; fprintf (fp, "%lf\t", tempStateProbs[i*nChar*4 + c*4 + C]); } } fprintf (fp, "\n"); fclose (fp); } /* G */ strcpy (tempFile, tempFileG); for (i=0; i= 0) { pat = patternId[c]; fprintf (fp, "%lf\t", tempStateProbs[i*nChar*4 + c*4 + G]); } } fprintf (fp, "\n"); fclose (fp); } /* T */ strcpy (tempFile, tempFileT); for (i=0; i= 0) { pat = patternId[c]; fprintf (fp, "%lf\t", tempStateProbs[i*nChar*4 + c*4 + T]); } } fprintf (fp, "\n"); fclose (fp); } } /* summarize states */ if (whichGen == nGen && nSampled >= 1) { strcpy (tempFile, outFile); strcat (tempFile, ".sum."); for (i=0; i= 0) { pat = patternId[c]; fprintf (fp, "%4d %4d -- ", c+1, pat); fprintf (fp, "%lf %lf %lf %lf ", ancStatesProbs[i*nChar*4 + c*4 + A] / nSampled, ancStatesProbs[i*nChar*4 + c*4 + C] / nSampled, ancStatesProbs[i*nChar*4 + c*4 + G] / nSampled, ancStatesProbs[i*nChar*4 + c*4 + T] / nSampled); maxProb = -1.0; bestNuc = 'N'; if (ancStatesProbs[i*nChar*4 + c*4 + A] > maxProb) { maxProb = ancStatesProbs[i*nChar*4 + c*4 + A]; bestNuc = 'A'; } if (ancStatesProbs[i*nChar*4 + c*4 + C] > maxProb) { maxProb = ancStatesProbs[i*nChar*4 + c*4 + C]; bestNuc = 'C'; } if (ancStatesProbs[i*nChar*4 + c*4 + G] > maxProb) { maxProb = ancStatesProbs[i*nChar*4 + c*4 + G]; bestNuc = 'G'; } if (ancStatesProbs[i*nChar*4 + c*4 + T] > maxProb) { maxProb = ancStatesProbs[i*nChar*4 + c*4 + T]; bestNuc = 'T'; } lnSeqProb += log(maxProb/nSampled); fprintf (fp, "%c\n", bestNuc); } } fprintf (fp, "Most probable sequence [ln(Probability) = %lf]:\n", lnSeqProb); for (c=0; c= 0) { pat = patternId[c]; maxProb = -1.0; bestNuc = 'N'; if (ancStatesProbs[i*nChar*4 + c*4 + A] > maxProb) { maxProb = ancStatesProbs[i*nChar*4 + c*4 + A]; bestNuc = 'A'; } if (ancStatesProbs[i*nChar*4 + c*4 + C] > maxProb) { maxProb = ancStatesProbs[i*nChar*4 + c*4 + C]; bestNuc = 'C'; } if (ancStatesProbs[i*nChar*4 + c*4 + G] > maxProb) { maxProb = ancStatesProbs[i*nChar*4 + c*4 + G]; bestNuc = 'G'; } if (ancStatesProbs[i*nChar*4 + c*4 + T] > maxProb) { maxProb = ancStatesProbs[i*nChar*4 + c*4 + T]; bestNuc = 'T'; } fprintf (fp, "%c", bestNuc); } } fprintf (fp, "\n"); fclose (fp); } } /* free memory */ # if !defined (SMART_TI_PROBS) free_psdmatrix (probs); free (pL); if (nst == 6 || nst == 12) { free_psdmatrix (q); free (eigenValues); free_psdmatrix (eigvecs); free_psdmatrix (inverseEigvecs); free_pscmatrix (Ceigvecs); free_pscmatrix (CinverseEigvecs); if (isComplex != YES) free (c_ijk); } # endif free (catFreq); free (ancCls); if (!strcmp(ratesModel, "adgamma") || !strcmp(ratesModel, "ssadgamma")) { free_psdmatrix(markovTi); free (f); free (tempRatePr); } return (NO_ERROR); error_exit: # if !defined (SMART_TI_PROBS) free_psdmatrix (probs); free (pL); if (nst == 6 || nst == 12) { free_psdmatrix (q); free (eigenValues); free_psdmatrix (eigvecs); free_psdmatrix (inverseEigvecs); free_pscmatrix (Ceigvecs); free_pscmatrix (CinverseEigvecs); if (isComplex != YES) free (c_ijk); } # endif free (catFreq); free (ancCls); if (!strcmp(ratesModel, "adgamma") || !strcmp(ratesModel, "ssadgamma")) { free_psdmatrix(markovTi); free (f); free (tempRatePr); } return (ERROR); #undef N_STATES #undef N_STATES_SQUARED #undef N_STATES_CUBE } int PrintAncStatesAA (int whichState, int whichChain, int numChars, int numRateCats, int whichGen) { #define N_STATES 20 #define N_STATES_SQUARED 400 #define N_STATES_CUBE 8000 register int i, j, k, c, m, n, n1, l; int lnumRateCats, lnPartitions, oneMatSize, oneNodeSize, index, nRates, pat, intNodeOffset, allNodeOffset, condLikeOffset; double bs[N_STATES], *pL, *pR, *pA, *catFreq, *catRate, *partRate, *clL, *clR, *clA, *clP, *ancCls, *lnScaler, correlation, lnSeqProb, maxProb, **markovTi, like[N_STATES], sum, postProb[N_STATES], *f, *b, *expPr, *logCf, *logCb, *tempRatePr, *rateProbs, logC, temp, logLike, likeL, likeR, likeA; char tempFile[100], bestNuc; TreeNode *p, *r, *rDn, *rUp; FILE *fp, *fopen(); # if defined (SMART_TI_PROBS) int nForOneState; # else int isComplex, indexL, indexR, indexA, nPij; double v, theRate, **probs, **q, *eigenValues, *eigvalsImag, **eigvecs, **inverseEigvecs, *c_ijk; complex **Ceigvecs, **CinverseEigvecs; # endif /* initialize intNodeOffset */ intNodeOffset = whichChain*2*numIntNodes + whichState*numIntNodes; allNodeOffset = whichChain*2*numNodes + whichState*numNodes; /* initialize offset for transition probabilities */ # if defined (SMART_TI_PROBS) nForOneState = numNodes*nodeTiSize; # endif /* load base frequencies */ index = whichChain*2*N_STATES + whichState*N_STATES; for (i=0; i 1) { for (i=0; iisConstrained == YES) { /* mark nodes below p */ for (n1=0; n1flag = 0; if (r == p) r->flag = 1; if (r->left != NULL && r->right != NULL) { if (r->left->flag == 1 || r->right->flag == 1) r->flag = 1; } } /* get conditional likelihoods down tree */ for (n1=0; n1flag != 1) { //printf ("visiting interior node %d dn\n", r->index); /* get transition probabilities */ # if defined (SMART_TI_PROBS) pL = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (r->left->index)*nodeTiSize); pR = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (r->right->index)*nodeTiSize); # else for (m=indexL=indexR=0; mleft->length, theRate, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, N_STATES, probs, r->left->length, theRate) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; iright->length, theRate, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, N_STATES, probs, r->right->length, theRate) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; ileft->index)*oneNodeSize]; clR = &condLike[condLikeOffset + (r->right->index)*oneNodeSize]; clP = &condLike[condLikeOffset + (r->index)*oneNodeSize]; if (!strcmp(ratesModel, "equal")) { for (c=0; c=0; n1--) { r = intNodeDownPassSeq[intNodeOffset + n1]; if (r->flag == 1 && p != r) { rDn = r->anc; if (r->left->flag == 0) rUp = r->left; else rUp = r->right; //printf ("visiting interior node %d up\n", r->index); /* get transition probabilities */ # if defined (SMART_TI_PROBS) pL = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (rUp->index)*nodeTiSize); pR = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (r->index)*nodeTiSize); # else for (m=indexL=indexR=0; mlength, theRate, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, N_STATES, probs, rUp->length, theRate) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; ilength, theRate, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, N_STATES, probs, r->length, theRate) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; iindex)*oneNodeSize]; clR = &condLike[condLikeOffset + (rDn->index)*oneNodeSize]; clP = &condLike[condLikeOffset + (r->index)*oneNodeSize]; if (!strcmp(ratesModel, "equal")) { for (c=0; cindex); /* get transition probabilities */ # if defined (SMART_TI_PROBS) if (p->left == NULL || p->right == NULL || p->anc == NULL) { if (p->anc == NULL) pL = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->left->index)*nodeTiSize); else pR = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (p->index)*nodeTiSize); } else { pL = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (r->left->index)*nodeTiSize); pR = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (r->right->index)*nodeTiSize); pA = transitionProbs + (whichChain*2*nForOneState + whichState*nForOneState + (r->index)*nodeTiSize); } # else if (p->left == NULL || p->right == NULL || p->anc == NULL) { if (p->anc == NULL) v = p->left->length; else v = p->length; for (m=indexL=indexR=indexA=0; mleft->length, theRate, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, N_STATES, probs, p->left->length, theRate) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; iright->length, theRate, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, N_STATES, probs, p->right->length, theRate) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; ilength, theRate, probs); else if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, N_STATES, probs, p->length, theRate) == ERROR) { printf ("Problem calculating transition probabilities for complex eigen values.\n"); goto error_exit; } for (i=0; ileft == NULL || p->right == NULL || p->anc == NULL) { //clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; clP = ancCls; if (p->anc == NULL) clA = &condLike[condLikeOffset + (p->left->index)*oneNodeSize]; else clA = &condLike[condLikeOffset + (p->anc->index)*oneNodeSize]; if (!strcmp(ratesModel, "equal")) { for (c=0; cleft->index)*oneNodeSize]; clR = &condLike[condLikeOffset + (p->right->index)*oneNodeSize]; clA = &condLike[condLikeOffset + (p->anc->index)*oneNodeSize]; //clP = &condLike[condLikeOffset + (p->index)*oneNodeSize]; clP = ancCls; if (!strcmp(ratesModel, "equal")) { for (c=0; cindex)*oneNodeSize]; clP = ancCls; if (!strcmp(ratesModel, "equal") || !strcmp(ratesModel, "sitespec")) { for (c=0; c= 0) { sum = 0.0; for (i=0; iconstraintNum-1)*nChar*N_STATES + c*N_STATES + i] = postProb[i]; ancStatesProbs[(p->constraintNum-1)*nChar*N_STATES + c*N_STATES + i] += postProb[i]; } } } } else if (!strcmp(ratesModel, "gamma") || !strcmp(ratesModel, "invariant") || !strcmp(ratesModel, "invgamma") || !strcmp(ratesModel, "ssgamma")) { for (c=0; c= 0) { for (i=0; iconstraintNum-1)*nChar*N_STATES + c*N_STATES + i] = postProb[i]; ancStatesProbs[(p->constraintNum-1)*nChar*N_STATES + c*N_STATES + i] += postProb[i]; } } } } else if (!strcmp(ratesModel, "adgamma") || !strcmp(ratesModel, "ssadgamma")) { /* get probabilities of observations conditioned on each category */ for (c=0; c= 0) { pat = patternId[c]; if (c == 0) { for (k=0; k=0; c--) { if (patternId[c] >= 0) { if (c == nChar - 1) { for (k=0; k 0.0) expPr[k] = 1.0; else if (temp < -100.0) expPr[k] = 0.0; else expPr[k] = exp(temp); } for (k=0; kindex)*oneNodeSize]; clP = ancCls; for (c=0; c= 0) { for (i=0; iconstraintNum-1)*nChar*N_STATES + c*N_STATES + i] = postProb[i]; ancStatesProbs[(p->constraintNum-1)*nChar*N_STATES + c*N_STATES + i] += postProb[i]; } } } } } } /* summarize states */ /* print probabilities to a file */ if (nSampled == 1) { strcpy (tempFile, outFile); strcat (tempFile, ".sum."); for (i=0; i= 1) { strcpy (tempFile, outFile); strcat (tempFile, ".sum."); for (i=0; i= 0) { pat = patternId[c]; fprintf (fp, "%4d %4d -- ", c+1, pat); for (j=0; j maxProb) { maxProb = ancStatesProbs[i*nChar*N_STATES + c*N_STATES + j]; bestNuc = WhichAA (j); } } lnSeqProb += log(maxProb/nSampled); fprintf (fp, "%c\n", bestNuc); } } fprintf (fp, "Most probable sequence [ln(Probability) = %lf]:\n", lnSeqProb); for (c=0; c= 0) { pat = patternId[c]; maxProb = -1.0; bestNuc = 'N'; for (j=0; j maxProb) { maxProb = ancStatesProbs[i*nChar*N_STATES + c*N_STATES + j]; bestNuc = WhichAA (j); } } fprintf (fp, "%c", bestNuc); } } fprintf (fp, "\n"); fclose (fp); } } /* free memory */ # if !defined (SMART_TI_PROBS) free_psdmatrix (probs); free (pL); free_psdmatrix (q); free (eigenValues); free_psdmatrix (eigvecs); free_psdmatrix (inverseEigvecs); free_pscmatrix (Ceigvecs); free_pscmatrix (CinverseEigvecs); if (isComplex != YES) free (c_ijk); # endif free (catFreq); free (ancCls); if (!strcmp(ratesModel, "adgamma") || !strcmp(ratesModel, "ssadgamma")) { free_psdmatrix(markovTi); free (f); free (tempRatePr); } return (NO_ERROR); error_exit: # if !defined (SMART_TI_PROBS) free_psdmatrix (probs); free (pL); free_psdmatrix (q); free (eigenValues); free_psdmatrix (eigvecs); free_psdmatrix (inverseEigvecs); free_pscmatrix (Ceigvecs); free_pscmatrix (CinverseEigvecs); if (isComplex != YES) free (c_ijk); # endif free (catFreq); free (ancCls); if (!strcmp(ratesModel, "adgamma") || !strcmp(ratesModel, "ssadgamma")) { free_psdmatrix(markovTi); free (f); free (tempRatePr); } return (ERROR); #undef N_STATES #undef N_STATES_SQUARED #undef N_STATES_CUBE } int PrintPosSelProbs (int whichState, int whichChain, int numChars, int numRateCats, int whichGen) { int i, k, c, l, oneMatSize, nLocalCats, nOff, kTimesS, pat; double likePur, likeNeu, likePos, *clP, *bs, *tempProb, a[3][3], *f, *b, *e, sum, logC, *logCf, *logCb, temp, logLike, x; char tempFile1[100], tempFile2[100]; FILE *fp1, *fp2, *fopen(); TreeNode *p; /* open files, allocate some memory */ strcpy (tempFile1, outFile); strcpy (tempFile2, outFile); strcat (tempFile1, ".possummary"); strcat (tempFile2, ".posexhaust"); if (nSampled == 1) { if ((fp1 = fopen (tempFile1, "r")) == NULL) { if ((fp1 = fopen (tempFile1, "w")) == NULL) { printf ("\n ERROR: Could not open file (%s).\n", tempFile1); goto error_exit; } } else { fclose (fp1); if (autoclose == YES) { printf (" Overwriting information to file %s\n", tempFile1); if ((fp1 = fopen (tempFile1, "w+")) == NULL) { printf ("\n ERROR: Could not open file (%s).\n", tempFile1); goto error_exit; } } else { printf ("\n File \"%s\" already exists.\n Overwrite? (yes/no): ", tempFile1); if (YesNo() == YES) { printf (" Overwriting information to file %s\n", tempFile1); if ((fp1 = fopen (tempFile1, "w+")) == NULL) { printf ("\n ERROR: Could not open file (%s).\n", tempFile1); goto error_exit; } } else { printf (" Appending information to file %s\n", tempFile1); if ((fp1 = fopen (tempFile1, "a+")) == NULL) { printf ("\n ERROR: Could not open file (%s).\n", tempFile1); goto error_exit; } } } } if ((fp2 = fopen (tempFile2, "r")) == NULL) { if ((fp2 = fopen (tempFile2, "w")) == NULL) { printf ("\n ERROR: Could not open file (%s).\n", tempFile2); goto error_exit; } } else { fclose (fp2); if (autoclose == YES) { printf (" Overwriting information to file %s\n", tempFile2); if ((fp2 = fopen (tempFile2, "w+")) == NULL) { printf ("\n ERROR: Could not open file (%s).\n", tempFile2); goto error_exit; } } else { printf ("\n File \"%s\" already exists.\n Overwrite? (yes/no): ", tempFile2); if (YesNo() == YES) { printf (" Overwriting information to file %s\n", tempFile2); if ((fp2 = fopen (tempFile2, "w+")) == NULL) { printf ("\n ERROR: Could not open file (%s).\n", tempFile2); goto error_exit; } } else { printf (" Appending information to file %s\n", tempFile2); if ((fp2 = fopen (tempFile2, "a+")) == NULL) { printf ("\n ERROR: Could not open file (%s).\n", tempFile2); goto error_exit; } } } } fprintf (fp2, "Probability that each site is in the positively selected category\n"); for (i=0; i<(nChar/3); i++) { if (patternId[i] >= 0) { fprintf (fp2, "%d\t", i+1); } } fprintf (fp2, "\n"); posSelProbs = (double *)malloc((size_t) ((nChar/3) * sizeof(double))); if (!posSelProbs) { printf ("\n ERROR: Problem allocating posSelProbs.\n"); goto error_exit; } for (i=0; i<(nChar/3); i++) posSelProbs[i] = 0.0; } else { if ((fp1 = fopen (tempFile1, "a+")) == NULL) { printf ("\n ERROR: Could not open file (%s).\n", tempFile1); goto error_exit; } if ((fp2 = fopen (tempFile2, "a+")) == NULL) { printf ("\n ERROR: Could not open file (%s).\n", tempFile2); goto error_exit; } } /* start calculations of posterior probabilities by initializing necessary variables*/ if (!strcmp(codonModelType, "ac1ny98")) InitTiMatrix (a, rateCorrelation[whichChain*2 + whichState], 0.0, 0.0, probPur[whichChain*2 + whichState], probNeu[whichChain*2 + whichState], probPos[whichChain*2 + whichState], 1); else if (!strcmp(codonModelType, "ac2ny98")) InitTiMatrix (a, rateCorrelation[whichChain*2 + whichState], rateCorrelation2[whichChain*4 + whichState*2 + 0], rateCorrelation2[whichChain*4 + whichState*2 + 1], probPur[whichChain*2 + whichState], probNeu[whichChain*2 + whichState], probPos[whichChain*2 + whichState], 2); if (!strcmp(codonModelType, "ac1ny98") || !strcmp(codonModelType, "ac2ny98")) { f = (double *)malloc((size_t) (3 * (nChar/3) * sizeof(double))); if (!f) { printf ("\n ERROR: Problem allocating f.\n"); goto error_exit; } for (i=0; i<3*(nChar/3); i++) f[i] = 0.0; b = (double *)malloc((size_t) (3 * (nChar/3) * sizeof(double))); if (!b) { printf ("\n ERROR: Problem allocating b.\n"); goto error_exit; } for (i=0; i<3*(nChar/3); i++) b[i] = 0.0; e = (double *)malloc((size_t) (3 * (nChar/3) * sizeof(double))); if (!e) { printf ("\n ERROR: Problem allocating e.\n"); goto error_exit; } for (i=0; i<3*(nChar/3); i++) e[i] = 0.0; logCf = (double *)malloc((size_t) ((nChar/3) * sizeof(double))); if (!logCf) { printf ("\n ERROR: Problem allocating f.\n"); goto error_exit; } for (i=0; i<(nChar/3); i++) logCf[i] = 0.0; logCb = (double *)malloc((size_t) ((nChar/3) * sizeof(double))); if (!logCb) { printf ("\n ERROR: Problem allocating b.\n"); goto error_exit; } for (i=0; i<(nChar/3); i++) logCb[i] = 0.0; } bs = (double *)malloc((size_t) (nStates * sizeof(double))); if (!bs) { printf ("\n ERROR: Problem allocating bs.\n"); goto error_exit; } for (i=0; ileft; clP = &condLike[whichChain*2*oneMatSize + whichState*oneMatSize + (p->index)*numChars*numRateCats*nStates]; nOff = numRateCats*nStates; for (c=0; c= 0) { pat = patternId[i]; fprintf (fp2, "%1.4lf\t", tempProb[pat]); posSelProbs[i] += tempProb[pat]; } } fprintf (fp2, "\n"); } else if (!strcmp(codonModelType, "ac1ny98") || !strcmp(codonModelType, "ac2ny98")) { /* get emission probabilities */ nLocalCats = numRateCats; oneMatSize = numNodes * numChars * nLocalCats * nStates; p = root[whichChain*2 + whichState]->left; clP = &condLike[whichChain*2*oneMatSize + whichState*oneMatSize + (p->index)*numChars*numRateCats*nStates]; nOff = numRateCats * nStates; for (c=0; c= 0) { pat = patternId[i]; e[0 * (nChar/3) + i] = tempProb[0 * numChars + pat]; e[1 * (nChar/3) + i] = tempProb[1 * numChars + pat]; e[2 * (nChar/3) + i] = tempProb[2 * numChars + pat]; } } /* forward algorithm */ logC = 0.0; for (i=0; i<(nChar/3); i++) { if (i == 0) { for (k=0; k<3; k++) f[k * (nChar/3) + i] = e[k * (nChar/3) + i]; } else { for (l=0; l<3; l++) { temp = 0.0; for (k=0; k<3; k++) temp += f[k * (nChar/3) + (i-1)] * a[k][l]; f[l * (nChar/3) + i] = temp * e[l * (nChar/3) + i]; } } sum = 0.0; for (k=0; k<3; k++) sum += f[k * (nChar/3) + i]; for (k=0; k<3; k++) f[k * (nChar/3)+i] /= sum; logC += log(sum); logCf[i] = logC; } temp = f[0 * (nChar/3) + ((nChar/3)-1)] * probPur[whichChain*2 + whichState]; temp += f[1 * (nChar/3) + ((nChar/3)-1)] * probNeu[whichChain*2 + whichState]; temp += f[2 * (nChar/3) + ((nChar/3)-1)] * probPos[whichChain*2 + whichState]; logLike = log(temp) + logC; /* backward algorithm */ logC = 0.0; for (i=(nChar/3)-1; i>=0; i--) { if (i == (nChar/3) - 1) { b[0 * (nChar/3) + i] = probPur[whichChain*2 + whichState]; b[1 * (nChar/3) + i] = probNeu[whichChain*2 + whichState]; b[2 * (nChar/3) + i] = probPos[whichChain*2 + whichState]; } else { for (k=0; k<3; k++) { temp = 0.0; for (l=0; l<3; l++) temp += a[k][l] * e[l * (nChar/3) + (i+1)] * b[l * (nChar/3) + (i+1)]; b[k * (nChar/3) + i] = temp; } } sum = 0.0; for (k=0; k<3; k++) sum += b[k * (nChar/3) + i]; for (k=0; k<3; k++) b[k * (nChar/3) + i] /= sum; logC += log(sum); logCb[i] = logC; } temp = 0.0; for (l=0; l<3; l++) temp += e[l * (nChar/3) + 0] * b[l * (nChar/3) + 0]; logLike = log (temp) + logC; for (i=0; i<(nChar/3); i++) { temp = (log(f[2 * (nChar/3) + i]) + logCf[i] + log(b[2 * (nChar/3) + i]) + logCb[i]) - logLike; if (temp > 0.0) x = 1.0; else if (temp < -100.0) x = 0.0; else x = exp(temp); fprintf (fp2, "%1.4lf\t", x); posSelProbs[i] += x; //printf ("%4d -- %lf %lf\n", i+1, temp, x); } fprintf (fp2, "\n"); } else { printf ("\n ERROR: Unknown model for positive selection.\n"); goto error_exit; } /* print summary of probabilities to a file */ if (whichGen == nGen && nSampled >= 1) { fprintf (fp1, "Summary of posterior probability of being in positively selected class\n"); for (i=0; i<(nChar/3); i++) { fprintf (fp1, "%d\t%1.4lf\n", i+1, posSelProbs[i] / nSampled); } free (posSelProbs); } free (bs); free (tempProb); fclose (fp1); fclose (fp2); if (!strcmp(codonModelType, "ac1ny98") || !strcmp(codonModelType, "ac2ny98")) { free (f); free (b); free (e); free (logCf); free (logCb); } return (NO_ERROR); error_exit: free (bs); free (tempProb); #if defined (MORPH) if (fp1 != NULL) fclose (fp1); if (fp2 != NULL) fclose (fp2); #else fclose (fp1); fclose (fp2); #endif free (posSelProbs); if (!strcmp(codonModelType, "ac1ny98") || !strcmp(codonModelType, "ac2ny98")) { free (f); free (b); free (e); free (logCf); free (logCb); } return (ERROR); } int PrintRateFactors (int whichState, int whichChain, int numChars, int numRateCats, int whichGen) { int i, k, c, l, oneMatSize, nLocalCats, nOff, kTimesS, pat; double *clP, *bs, *tempRatePr, **a, correlation, like, *aveRate, *f, *b, *expPr, sum, logC, *logCf, *logCb, temp, logLike, x, mult, *catFreq, *catRate; char tempFile1[100], tempFile2[100]; FILE *fp1, *fp2, *fopen(); TreeNode *p; /* calculate number of rate categories */ if (!strcmp(ratesModel, "equal")) nLocalCats = 1; else if (!strcmp(ratesModel, "gamma") || !strcmp(ratesModel, "adgamma") || !strcmp(ratesModel, "invariant") || !strcmp(ratesModel, "invgamma")) nLocalCats = numRateCats; else if (!strcmp(ratesModel, "sitespec")) nLocalCats = nPartitions; else if (!strcmp(ratesModel, "ssgamma") || !strcmp(ratesModel, "ssadgamma")) nLocalCats = numRateCats; /* open files, allocate some memory */ strcpy (tempFile1, outFile); strcat (tempFile1, ".ratesummary"); strcpy (tempFile2, outFile); strcat (tempFile2, ".exhaustrates"); if (nSampled == 1) { if ((fp1 = fopen (tempFile1, "r")) == NULL) { if ((fp1 = fopen (tempFile1, "w")) == NULL) { printf ("\n ERROR: Could not open file (%s).\n", tempFile1); goto error_exit; } } else { fclose (fp1); if (autoclose == YES) { printf (" Overwriting information to file %s\n", tempFile1); if ((fp1 = fopen (tempFile1, "w+")) == NULL) { printf ("\n ERROR: Could not open file (%s).\n", tempFile1); goto error_exit; } } else { printf ("\n File \"%s\" already exists.\n Overwrite? (yes/no): ", tempFile1); if (YesNo() == YES) { printf (" Overwriting information to file %s\n", tempFile1); if ((fp1 = fopen (tempFile1, "w+")) == NULL) { printf ("\n ERROR: Could not open file (%s).\n", tempFile1); goto error_exit; } } else { printf (" Appending information to file %s\n", tempFile1); if ((fp1 = fopen (tempFile1, "a+")) == NULL) { printf ("\n ERROR: Could not open file (%s).\n", tempFile1); goto error_exit; } } } } if ((fp2 = fopen (tempFile2, "r")) == NULL) { if ((fp2 = fopen (tempFile2, "w")) == NULL) { printf ("\n ERROR: Could not open file (%s).\n", tempFile2); goto error_exit; } } else { fclose (fp2); if (autoclose == YES) { printf (" Overwriting information to file %s\n", tempFile2); if ((fp2 = fopen (tempFile2, "w+")) == NULL) { printf ("\n ERROR: Could not open file (%s).\n", tempFile2); goto error_exit; } } else { printf ("\n File \"%s\" already exists.\n Overwrite? (yes/no): ", tempFile2); if (YesNo() == YES) { printf (" Overwriting information to file %s\n", tempFile2); if ((fp2 = fopen (tempFile2, "w+")) == NULL) { printf ("\n ERROR: Could not open file (%s).\n", tempFile2); goto error_exit; } } else { printf (" Appending information to file %s\n", tempFile2); if ((fp2 = fopen (tempFile2, "a+")) == NULL) { printf ("\n ERROR: Could not open file (%s).\n", tempFile2); goto error_exit; } } } } fprintf (fp2, "Rate factor for each site\n"); for (i=0; i= 0) { fprintf (fp2, "%d\t", i+1); } } fprintf (fp2, "\n"); rateFactors = (double *)malloc((size_t) (nChar * sizeof(double))); if (!rateFactors) { printf ("\n ERROR: Problem allocating rateFactors.\n"); goto error_exit; } for (i=0; ileft; if (!strcmp(ratesModel, "equal") || !strcmp(ratesModel, "sitespec")) { clP = &condLike[whichChain*2*oneMatSize + whichState*oneMatSize + (p->index)*numChars*nStates]; for (c=0; cindex)*numChars*nLocalCats*nStates]; nOff = nLocalCats * nStates; for (c=0; cindex)*numChars*nLocalCats*nStates]; nOff = nLocalCats * nStates; for (c=0; c= 0) { pat = patternId[c]; if (c == 0) { for (k=0; k=0; c--) { if (patternId[c] >= 0) { if (c == nChar - 1) { for (k=0; k 0.0) printf ("x.xxxxxx "); else if (temp < -100.0) printf ("%lf ", 0.0); else printf ("%lf ", exp(temp));*/ if (temp > 0.0) expPr[k] = 1.0; else if (temp < -100.0) expPr[k] = 0.0; else expPr[k] = exp(temp); } if (!strcmp(ratesModel, "adgamma")) { x = 0.0; for (k=0; k= 0) { pat = patternId[c]; aveRate[c] = catRate[partitionId[pat]]; rateProbs[c] = 1.0; fprintf (fp2, "%1.4lf\t", aveRate[c]); } } } else if (!strcmp(ratesModel, "ssgamma")) { for (c=0; c= 0) { pat = patternId[c]; mult = scaledRates[whichChain*2*nPartitions + whichState*nPartitions + partitionId[pat]]; sum = 0.0; for (k=0; k= 0) { pat = patternId[c]; sum = 0.0; for (k=0; k= 1) { fprintf (fp1, "Summary of rate factors for each site\n"); for (i=0; i 1) { fprintf (fp1, "%lf\t", statefreqP[coldId*2 + whichState]); fprintf (fp2, ", %lf", statefreqP[coldId*2 + whichState]); } #endif if (((dataType == DNA || dataType == RNA) && enforceCodonModel == NO) || dataType == PROTEIN || dataType == RESTRICTION) { if (!strcmp(ratesModel, "gamma")) { fprintf (fp1, "%lf\t", alpha[coldId*2 + whichState]); fprintf (fp2, ", %lf", alpha[coldId*2 + whichState]); } else if (!strcmp(ratesModel, "adgamma")) { fprintf (fp1, "%lf\t", alpha[coldId*2 + whichState]); fprintf (fp2, ", %lf", alpha[coldId*2 + whichState]); fprintf (fp1, "%lf\t", rateCorrelation[coldId*2 + whichState]); fprintf (fp2, ", %lf", rateCorrelation[coldId*2 + whichState]); if (!strcmp(lagprModel, "uniform") || !strcmp(lagprModel, "exponential")) { fprintf (fp1, "%d\t", lag[coldId*2 + whichState]); fprintf (fp2, ", %d", lag[coldId*2 + whichState]); } } else if (!strcmp(ratesModel, "sitespec")) { for (i=0; iisConstrained == YES) { if (p->constraintNum-1 >= nConstraints) { printf ("\n ERROR: Constraint out of bounds\n"); return ERROR; } else constrainedNodes[p->constraintNum-1] = p->nodeTime; } if (p->isCalibrated == YES) { if (p->calibrationNum-1 >= nCalibrations) { printf ("\n ERROR: Calibration out of bounds\n"); return ERROR; } else calibratedNodes[p->calibrationNum-1] = p->nodeTime; } } for (i=0; i= 0.0 && ran <= cumProposalProbs[0]) proposedState = CHANGE_QMAT; else if (ran >cumProposalProbs[0] && ran <= cumProposalProbs[1]) proposedState = CHANGE_BASEFREQS; else if (ran >cumProposalProbs[1] && ran <= cumProposalProbs[2]) proposedState = CHANGE_GAMMA_SHAPE; else if (ran >cumProposalProbs[2] && ran <= cumProposalProbs[3]) proposedState = CHANGE_SITE_RATES; else if (ran >cumProposalProbs[3] && ran <= cumProposalProbs[4]) proposedState = CHANGE_UNROOT_LOCAL; else if (ran >cumProposalProbs[4] && ran <= cumProposalProbs[5]) proposedState = CHANGE_CLOCK_LOCAL; else if (ran >cumProposalProbs[5] && ran <= cumProposalProbs[6]) proposedState = CHANGE_CLOCK_TIME_LOCAL; else if (ran >cumProposalProbs[6] && ran <= cumProposalProbs[7]) proposedState = CHANGE_TREE_HEIGHT; else if (ran >cumProposalProbs[7] && ran <= cumProposalProbs[8]) proposedState = CHANGE_WORM; else if (ran >cumProposalProbs[8] && ran <= cumProposalProbs[9]) proposedState = CHANGE_NODE_TIME; else if (ran >cumProposalProbs[9] && ran <= cumProposalProbs[10]) proposedState = CHANGE_BD_PARAMS; else if (ran >cumProposalProbs[10] && ran <= cumProposalProbs[11]) proposedState = CHANGE_OMEGA; else if (ran >cumProposalProbs[11] && ran <= cumProposalProbs[12]) proposedState = CHANGE_OMEGA_PROBS; else if (ran >cumProposalProbs[12] && ran <= cumProposalProbs[13]) proposedState = CHANGE_AUTO_CORR; else if (ran >cumProposalProbs[13] && ran <= cumProposalProbs[14]) proposedState = CHANGE_LAG; else if (ran >cumProposalProbs[14] && ran <= cumProposalProbs[15]) proposedState = CHANGE_TREE_SPR; else if (ran >cumProposalProbs[15] && ran <= cumProposalProbs[16]) proposedState = CHANGE_INV_P; else if (ran >cumProposalProbs[16] && ran <= cumProposalProbs[17]) proposedState = CHANGE_SWITCH_RATE; else if (ran >cumProposalProbs[17] && ran <= cumProposalProbs[18]) proposedState = CHANGE_UNROOT_TBR; else if (ran >cumProposalProbs[18] && ran <= cumProposalProbs[19]) proposedState = CHANGE_GCSWITCH; else if (ran >cumProposalProbs[19] && ran <= cumProposalProbs[20]) proposedState = CHANGE_TREE_FTBR; else if (ran >cumProposalProbs[20] && ran <= cumProposalProbs[21]) proposedState = CHANGE_BRLEN; else if (ran >cumProposalProbs[21] && ran <= cumProposalProbs[22]) proposedState = CHANGE_ERASER; #if defined (MORPH) else if (ran >cumProposalProbs[22] && ran <= cumProposalProbs[23]) proposedState = CHANGE_BETA_SHAPE; #endif return (proposedState); } /*-------| RandomNumber |------------------------------------------------ | This pseudorandom number generator is described in: | Park, S. K. and K. W. Miller. 1988. Random number generators: good | ones are hard to find. Communications of the ACM, 31(10):1192-1201. */ double RandomNumber (long int *seed) { long int lo, hi, test; hi = (*seed) / 127773; lo = (*seed) % 127773; test = 16807 * lo - 2836 * hi; if (test > 0) *seed = test; else *seed = test + 2147483647; return (double)(*seed) / (double)2147483647; } double RndGamma (double s, long int *seed) { double r=0.0; if (s <= 0.0) puts ("jgl gamma.."); else if (s < 1.0) r = RndGamma1 (s, seed); else if (s > 1.0) r = RndGamma2 (s, seed); else r =- log(RandomNumber(seed)); return (r); } double RndGamma1 (double s, long int *seed) { double r, x=0.0, small=1e-37, w; static double a, p, uf, ss=10.0, d; if (s!=ss) { a = 1.0-s; p = a/(a+s*exp(-a)); uf = p*pow(small/a,s); d = a*log(a); ss = s; } for (;;) { r = RandomNumber(seed); if (r > p) x = a-log((1.0-r)/(1.0-p)), w=a*log(x)-d; else if (r>uf) x = a*pow(r/p,1/s), w=x; else return (0.0); r = RandomNumber(seed); if (1.0-r <= w && r > 0.0) if (r*(w+1.0) >= 1.0 || -log(r) <= w) continue; break; } return (x); } double RndGamma2 (double s, long int *seed) { double r ,d, f, g, x; static double b, h, ss=0; if (s!=ss) { b = s-1.0; h = sqrt(3.0*s-0.75); ss = s; } for (;;) { r = RandomNumber(seed); g = r-r*r; f = (r-0.5)*h/sqrt(g); x = b+f; if (x <= 0.0) continue; r = RandomNumber(seed); d = 64*r*r*g*g*g; if (d*x < x-2.0*f*f || log(d) < 2*(b*log(x/b)-f)) break; } return (x); } int RunChain (void) { int i, n, numTaxa, numChars, numRateCats; long int seed; printf (" Running Markov chain\n"); seed = randomSeed; /* set all of the indicators for allocated memory to "NO" */ for (i=0; i 1 */ if (useParsCriterion == NO) { printf (" Copying states in memory\n"); for (n=0; n 0) { printf (" Perturbing starting trees\n"); if (PerturnStartingTree (numTaxa, &seed) == ERROR) { FreeMemory (); return (ERROR); } } /* run Markov chain */ printf (" Running Markov chain\n"); if (useParsCriterion == NO) { if (MarkovChain (numTaxa, numChars, numRateCats, &seed) == ERROR) { FreeMemory (); return (ERROR); } } else { if (MarkovChainPars (numTaxa, numChars, &seed) == ERROR) { FreeMemory (); return (ERROR); } } /* free memory */ FreeMemory (); printf (" Chain successfully run\n"); randomSeed = seed; return (NO_ERROR); } void SetCode (void) { int i, s, s1, s2, s3; printf (" Setting genetic code\n"); codon[ 0] = 12; /* AAA Lys */ codon[ 1] = 3; /* AAC Asn */ codon[ 2] = 12; /* AAG Lys */ codon[ 3] = 3; /* AAT Asn */ codon[ 4] = 17; /* ACA Thr */ codon[ 5] = 17; /* ACC Thr */ codon[ 6] = 17; /* ACG Thr */ codon[ 7] = 17; /* ACT Thr */ codon[ 8] = 2; /* AGA Arg */ codon[ 9] = 16; /* AGC Ser */ codon[10] = 2; /* AGG Arg */ codon[11] = 16; /* AGT Ser */ codon[12] = 10; /* ATA Ile */ codon[13] = 10; /* ATC Ile */ codon[14] = 13; /* ATG Met */ codon[15] = 10; /* ATT Ile */ codon[16] = 6; /* CAA Gln */ codon[17] = 9; /* CAC His */ codon[18] = 6; /* CAG Gln */ codon[19] = 9; /* CAT His */ codon[20] = 15; /* CCA Pro */ codon[21] = 15; /* CCC Pro */ codon[22] = 15; /* CCG Pro */ codon[23] = 15; /* CCT Pro */ codon[24] = 2; /* CGA Arg */ codon[25] = 2; /* CGC Arg */ codon[26] = 2; /* CGG Arg */ codon[27] = 2; /* CGT Arg */ codon[28] = 11; /* CTA Leu */ codon[29] = 11; /* CTC Leu */ codon[30] = 11; /* CTG Leu */ codon[31] = 11; /* CTT Leu */ codon[32] = 7; /* GAA Glu */ codon[33] = 4; /* GAC Asp */ codon[34] = 7; /* GAG Glu */ codon[35] = 4; /* GAT Asp */ codon[36] = 1; /* GCA Ala */ codon[37] = 1; /* GCC Ala */ codon[38] = 1; /* GCG Ala */ codon[39] = 1; /* GCT Ala */ codon[40] = 8; /* GGA Gly */ codon[41] = 8; /* GGC Gly */ codon[42] = 8; /* GGG Gly */ codon[43] = 8; /* GGT Gly */ codon[44] = 20; /* GTA Val */ codon[45] = 20; /* GTC Val */ codon[46] = 20; /* GTG Val */ codon[47] = 20; /* GTT Val */ codon[48] = 21; /* TAA Stop*/ codon[49] = 19; /* TAC Tyr */ codon[50] = 21; /* TAG Stop*/ codon[51] = 19; /* TAT Tyr */ codon[52] = 16; /* TCA Ser */ codon[53] = 16; /* TCC Ser */ codon[54] = 16; /* TCG Ser */ codon[55] = 16; /* TCT Ser */ codon[56] = 21; /* TGA Stop*/ codon[57] = 5; /* TGC Cys */ codon[58] = 18; /* TGG Trp */ codon[59] = 5; /* TGT Cys */ codon[60] = 11; /* TTA Leu */ codon[61] = 14; /* TTC Phe */ codon[62] = 11; /* TTG Leu */ codon[63] = 14; /* TTT Phe */ if (aaCode == VERTMT) { printf (" Vertebrate mitochondrial code\n"); printf (" UGA: Ter -> Trp\n"); printf (" AUA: Ile -> Met\n"); printf (" AGA: Arg -> Ter\n"); printf (" AGG: Arg -> Ter\n"); codon[ 8] = 21; /* AGA Stop */ codon[10] = 21; /* AGG Stop */ codon[12] = 13; /* ATA Met */ codon[56] = 18; /* TGA Trp */ } else if (aaCode == MYCO) { printf (" Mycoplasma nuclear code\n"); printf (" UGA: Ter -> Trp\n"); codon[56] = 18; /* TGA Trp */ } else if (aaCode == YEAST) { printf (" Yeast mitochondrial code\n"); printf (" UGA: Ter -> Trp\n"); printf (" AUA: Ile -> Met\n"); printf (" CUA: Leu -> Thr\n"); printf (" CUC: Leu -> Thr\n"); printf (" CUG: Leu -> Thr\n"); printf (" CUU: Leu -> Thr\n"); codon[12] = 13; /* ATA Met */ codon[28] = 17; /* CTA Thr */ codon[29] = 17; /* CTC Thr */ codon[30] = 17; /* CTG Thr */ codon[31] = 17; /* CTT Thr */ codon[56] = 18; /* TGA Trp */ } else if (aaCode == CILIATES) { printf (" Ciliate nuclear code\n"); printf (" UAA: Ter -> Gln\n"); printf (" UAG: Ter -> Gln\n"); codon[48] = 6; /* TAA Gln */ codon[50] = 6; /* TAG Gln */ } else if (aaCode == METMT) { printf (" Metazoan (except vertebrates) mitochondrial code\n"); printf (" UGA: Ter -> Trp\n"); printf (" AUA: Ile -> Met\n"); printf (" AGA: Arg -> Ser\n"); printf (" AGG: Arg -> Ser\n"); codon[ 8] = 16; /* AGA Ser */ codon[10] = 16; /* AGG Ser */ codon[12] = 13; /* ATA Met */ codon[56] = 18; /* TGA Trp */ } else { printf (" Universal code\n"); } nStates = 0; for (i=0; i<64; i++) { if (codon[i] != 21) nStates++; } printf (" There are a total of %d coding triplets\n", nStates); s = 0; for (s1=0; s1<4; s1++) { for (s2=0; s2<4; s2++) { for (s3=0; s3<4; s3++) { if (codon[s1*16 + s2*4 + s3] != 21) { transCodon[s] = codon[s1*16 + s2*4 + s3]; codonNucs[s][0] = s1; codonNucs[s][1] = s2; codonNucs[s][2] = s3; s++; } } } } } int SetModel (int *numRateCats) { int i, j, chain, nIncludedTaxa, nIncludedChars, x, y, isDiff; double scaler, sum; /* set all proposal mechanisms to zero */ for (i=0; i 1) { printf (" Chains (i: {1, ..., %d}) are incrementally heated, with the heat\n", numChains); printf (" being 1 / (1 + (i - 1) T), where T = %lf\n", chainTemp); } } /* how many substitution parameters ************************************************************/ chainMins[CHANGE_QMAT] = 0.000001; chainMaxs[CHANGE_QMAT] = 1000.0; printf (" Substitution model\n"); if (dataType == DNA || dataType == RNA) { if (enforceCodonModel == NO) { /* 4 X 4 model of DNA substitution */ if (!strcmp(subModel, "1")) { printf (" All substitution types have equal rates.\n"); printf (" This corresponds to the JC69 or F81 models.\n"); nst = 1; } else if (!strcmp(subModel, "2")) { printf (" Two substitution types. Transitions have one\n"); printf (" rate whereas tranversions have another.\n"); printf (" This corresponds to the K80 or HKY85 models.\n"); nst = 2; kappa = (double *)malloc((size_t) (numChains * 2 * sizeof(double))); if (!kappa) { printf ("\n ERROR: Problem allocating kappa.\n"); FreeMemory (); return (ERROR); } else allocatedMemory[ALLOC_KAPPA] = YES; for (i=0; i<2*numChains; i++) kappa[i] = tRatio; printf (" Starting kappa = %lf\n", kappa[0]); } else if (!strcmp(subModel, "6")) { printf (" There are six substitution types: A <-> C, A <-> G, A <-> T\n"); printf (" C <-> G, C <-> T, and G <-> T, each with a potentially\n"); printf (" different rate. This corresponds to the GTR model.\n"); nst = 6; subParams = (double *)malloc((size_t) (numChains * 2 * 6 * sizeof(double))); if (!subParams) { printf ("\n ERROR: Problem allocating subParams.\n"); FreeMemory (); return (ERROR); } else allocatedMemory[ALLOC_SUBPARAMS] = YES; for (chain=0; chain C, A -> G, A -> T\n"); printf (" C -> A, C -> G, C -> T, G -> A, G -> C, G -> T, T -> A\n"); printf (" T -> C and T -> G. This corresponds to the general\n"); printf (" nonreversible model.\n"); nst = 12; if (isStartingTreeRandom == NO && isUserTreeDefined == YES && isTreeRooted == NO) { printf ("\n WARNING: You requested that the chain start with a user-\n"); printf (" specified tree. Such a tree was provided, but the\n"); printf (" tree is unrooted. The nonreversible model requires\n"); printf (" rooted trees. The tree is being rooted at the outgroup\n"); printf (" species\n\n"); if (RootTree (userTreeRoot) == ERROR) { FreeMemory (); return (ERROR); } } subParams = (double *)malloc((size_t) (numChains * 2 * 12 * sizeof(double))); if (!subParams) { printf ("\n ERROR: Problem allocating subParams.\n"); FreeMemory (); return (ERROR); } else allocatedMemory[ALLOC_SUBPARAMS] = YES; for (chain=0; chain 1) { if (!strcmp(qmatprModel, "fixed")) { printf (" Instantaneous rate matrix is fixed\n"); } else if (!strcmp(qmatprModel, "exponential")) { printf (" Instantaneous rate matrix has exponential(%1.4lf) prior\n", qmatprExp); relProposalProbs[CHANGE_QMAT] = moveRates[CHANGE_QMAT]; } else if (!strcmp(qmatprModel, "uniform")) { printf (" Instantaneous rate matrix has uniform(%1.4lf, %1.4lf) prior\n", qmatprUni[0], qmatprUni[1]); relProposalProbs[CHANGE_QMAT] = moveRates[CHANGE_QMAT]; chainMins[CHANGE_QMAT] = qmatprUni[0]; chainMaxs[CHANGE_QMAT] = qmatprUni[1]; } else { printf ("\n ERROR: Unknown prior model on instantaneous rates\n"); FreeMemory (); return (ERROR); } } } else { /* 61 X 61 (codon) model of DNA substitution */ if (!strcmp(qmatprModel, "fixed")) { printf (" Kappa is fixed\n"); } else if (!strcmp(qmatprModel, "exponential")) { printf (" Kappa has an exponential(%1.4lf) prior\n", qmatprExp); relProposalProbs[CHANGE_QMAT] = moveRates[CHANGE_QMAT]; } else if (!strcmp(qmatprModel, "uniform")) { printf (" Kappa has a uniform(%1.4lf, %1.4lf) prior\n", qmatprUni[0], qmatprUni[1]); relProposalProbs[CHANGE_QMAT] = moveRates[CHANGE_QMAT]; chainMins[CHANGE_QMAT] = qmatprUni[0]; chainMaxs[CHANGE_QMAT] = qmatprUni[1]; } else { printf ("\n ERROR: Unknown prior model on instantaneous rates\n"); FreeMemory (); return (ERROR); } if (!strcmp(omegaprModel, "fixed")) { printf (" Omega is fixed\n"); } else if (!strcmp(omegaprModel, "exponential")) { printf (" Omega has an exponential(%1.4lf) prior\n", omegaprExp); relProposalProbs[CHANGE_OMEGA] = moveRates[CHANGE_OMEGA]; } else if (!strcmp(qmatprModel, "uniform")) { printf (" Omega has a uniform(%1.4lf, %1.4lf) prior\n", omegaprUni[0], omegaprUni[1]); relProposalProbs[CHANGE_OMEGA] = moveRates[CHANGE_OMEGA]; chainMins[CHANGE_OMEGA] = omegaprUni[0]; chainMaxs[CHANGE_OMEGA] = omegaprUni[1]; } else { printf ("\n ERROR: Unknown prior model on instantaneous rates\n"); FreeMemory (); return (ERROR); } } } else if (dataType == PROTEIN) { if (aaModelType == GTR) { if (!strcmp(qmatprModel, "fixed")) { printf (" Instantaneous rate matrix is fixed\n"); } else if (!strcmp(qmatprModel, "exponential")) { printf (" Instantaneous rate matrix has exponential(%1.4lf) prior\n", qmatprExp); relProposalProbs[CHANGE_QMAT] = moveRates[CHANGE_QMAT]; } else if (!strcmp(qmatprModel, "uniform")) { printf (" Instantaneous rate matrix has uniform(%1.4lf, %1.4lf) prior\n", qmatprUni[0], qmatprUni[1]); relProposalProbs[CHANGE_QMAT] = moveRates[CHANGE_QMAT]; chainMins[CHANGE_QMAT] = qmatprUni[0]; chainMaxs[CHANGE_QMAT] = qmatprUni[1]; } else { printf ("\n ERROR: Unknown prior model on instantaneous rates\n"); FreeMemory (); return (ERROR); } } } else if (dataType == RESTRICTION) { if (!strcmp(qmatprModel, "fixed")) { printf (" Instantaneous rate matrix is fixed\n"); } else if (!strcmp(qmatprModel, "exponential")) { printf (" Instantaneous rate matrix has exponential(%1.4lf) prior\n", qmatprExp); relProposalProbs[CHANGE_QMAT] = moveRates[CHANGE_QMAT]; } else if (!strcmp(qmatprModel, "uniform")) { printf (" Instantaneous rate matrix has uniform(%1.4lf, %1.4lf) prior\n", qmatprUni[0], qmatprUni[1]); relProposalProbs[CHANGE_QMAT] = moveRates[CHANGE_QMAT]; chainMins[CHANGE_QMAT] = qmatprUni[0]; chainMaxs[CHANGE_QMAT] = qmatprUni[1]; } else { printf ("\n ERROR: Unknown prior model on instantaneous rates\n"); FreeMemory (); return (ERROR); } } else if (dataType == STANDARD) { if (!strcmp(stateFreqPrModel, "fixed")) { printf (" State frequencies are fixed to 0.5\n"); } #if defined (MORPH) else if (!strcmp(stateFreqPrModel, "dirichlet")) { numBetaCats = 5; /* this should be set to some arbitrary (but odd) number by user */ printf (" Stationary frequencies follow a symmetric dirichlet/beta distribution\n"); printf (" The shape of this distribution is estimated\n"); printf (" Starting shape parameter: %1.4lf\n", statefreqprDir); printf (" Shape parameter has a uniform(%1.4lf, %1.4lf) prior\n", 0.0, 100.0); printf (" The distribution is divided into %d discrete categories\n", numBetaCats); statefreqP = (double *)malloc((size_t) (numChains * 2 * sizeof(double))); if (!statefreqP) { printf ("\n ERROR: Problem allocating statefreqP.\n"); FreeMemory (); return (ERROR); } else allocatedMemory[ALLOC_BETA] = YES; for (i=0; i<2*numChains; i++) statefreqP[i] = statefreqprDir; relProposalProbs[CHANGE_BETA_SHAPE] = moveRates[CHANGE_BETA_SHAPE]; chainMins[CHANGE_BETA_SHAPE] = 0.0; chainMaxs[CHANGE_BETA_SHAPE] = 100.0; } #endif else { printf ("\n ERROR: Unknown prior model on state frequencies\n"); FreeMemory (); return (ERROR); } } /* set base frequencies ************************************************************************/ chainMins[CHANGE_BASEFREQS] = 0.0; chainMaxs[CHANGE_BASEFREQS] = 1.0; printf (" Base frequencies\n"); if (((dataType == DNA || dataType == RNA) && enforceCodonModel == NO) && useCovarion == YES && !strcmp(covarionModelType, "gcswitch")) { gc1 = (double *)malloc((size_t) (numChains * 2 * sizeof(double))); if (!gc1) { printf ("\n ERROR: Problem allocating gc1.\n"); FreeMemory (); return (ERROR); } else allocatedMemory[ALLOC_GC1] = YES; gc2 = (double *)malloc((size_t) (numChains * 2 * sizeof(double))); if (!gc2) { printf ("\n ERROR: Problem allocating gc2.\n"); FreeMemory (); return (ERROR); } else allocatedMemory[ALLOC_GC2] = YES; fracA = (double *)malloc((size_t) (numChains * 2 * sizeof(double))); if (!fracA) { printf ("\n ERROR: Problem allocating fracA.\n"); FreeMemory (); return (ERROR); } else allocatedMemory[ALLOC_FRAC_A] = YES; fracG = (double *)malloc((size_t) (numChains * 2 * sizeof(double))); if (!fracG) { printf ("\n ERROR: Problem allocating fracA.\n"); FreeMemory (); return (ERROR); } else allocatedMemory[ALLOC_FRAC_G] = YES; for (i=0; i<2*numChains; i++) { gc1[i] = 0.25; gc2[i] = 0.75; fracA[i] = 0.50; fracG[i] = 0.50; } printf (" Two classes of base frequencies, with switching between\n"); printf (" the classes. The first class has GC content constrained\n"); printf (" to be less than 1/2 and the other has GC content con-\n"); printf (" strained to be greater than 1/2.\n"); relProposalProbs[CHANGE_GCSWITCH] = moveRates[CHANGE_GCSWITCH]; } else if (dataType == DNA || dataType == RNA || dataType == PROTEIN) { baseFreq = (double *)malloc((size_t) (numChains * 2 * nStates * sizeof(double))); if (!baseFreq) { printf ("\n ERROR: Problem allocating baseFreq.\n"); FreeMemory (); return (ERROR); } else allocatedMemory[ALLOC_BASEFREQS] = YES; if (dataType == DNA || dataType == RNA) { if (enforceCodonModel == NO) { /* 4 X 4 model of DNA substitution */ if (nst == 12) { printf (" Base frequencies are determined by the Q matrix (model of\n"); printf (" DNA substitution is non-reversible).\n"); for (i=0; i\"\n"); FreeMemory (); return (ERROR); } if (isPartitionDefined == NO) { printf ("\n ERROR: You must define a partition\n"); FreeMemory (); return (ERROR); } x = strlen(partitionName); y = strlen(defPartitionName); if (x != y) { printf ("\n ERROR: The partition you defined (using \"partition\") \n"); printf (" and the partition you specified (using \"lset\") do\n"); printf (" not match.\n"); FreeMemory (); return (ERROR); } else { isDiff = NO; i = 0; while (partitionName[i] != '\0') { if (partitionName[i] != defPartitionName[i]) isDiff = YES; i++; } if (isDiff == YES) { printf ("\n ERROR: The partition you defined (using \"partition\") \n"); printf (" and the partition you specified (using \"lset\") do\n"); printf (" not match.\n"); FreeMemory (); return (ERROR); } } printf (" Partition name: \"%s\"\n", partitionName); printf (" Data is partitioned into %d parts\n", nPartitions); if (nPartitions <= 1) { printf ("\n ERROR: There are too few partitions of the data. You must\n"); printf (" have at least two partitions.\n"); FreeMemory (); return (ERROR); } else if (nPartitions > 49) { printf ("\n ERROR: There are too many partitions of the data. You must\n"); printf (" have fewer than 49 partitions.\n"); FreeMemory (); return (ERROR); } scaledRates = (double *)malloc((size_t) (numChains * 2 * nPartitions * sizeof(double))); if (!scaledRates) { printf ("\n ERROR: Problem allocating scaledRates.\n"); FreeMemory (); return (ERROR); } else allocatedMemory[ALLOC_SITE_RATES] = YES; unscaledRates = (double *)malloc((size_t) (numChains * 2 * nPartitions * sizeof(double))); if (!unscaledRates) { printf ("\n ERROR: Problem allocating unscaledRates.\n"); FreeMemory (); return (ERROR); } else allocatedMemory[ALLOC_UNSCALED_SITE_RATES] = YES; for (chain=0; chain 0.0) printf (" %1.2lf percent of the time attempts %s\n", (relProposalProbs[i]/sum)*100.0, proposalName[i]); } return (NO_ERROR); } #if defined (TRANSLATE_TO_AA) /*------------------------------------------------------------------- TranslateToAA: Translate data matrix from DNA or RNA to AA -------------------------------------------------------------------*/ void TranslateToAA (void) { } #endif int SetAARates (void) { aaJones[ 0][ 0] = 0; aaJones[ 0][ 1] = 58; aaJones[ 0][ 2] = 54; aaJones[ 0][ 3] = 81; aaJones[ 0][ 4] = 56; aaJones[ 0][ 5] = 57; aaJones[ 0][ 6] = 105; aaJones[ 0][ 7] = 179; aaJones[ 0][ 8] = 27; aaJones[ 0][ 9] = 36; aaJones[ 0][10] = 30; aaJones[ 0][11] = 35; aaJones[ 0][12] = 54; aaJones[ 0][13] = 15; aaJones[ 0][14] = 194; aaJones[ 0][15] = 378; aaJones[ 0][16] = 475; aaJones[ 0][17] = 9; aaJones[ 0][18] = 11; aaJones[ 0][19] = 298; aaJones[ 1][ 0] = 58; aaJones[ 1][ 1] = 0; aaJones[ 1][ 2] = 45; aaJones[ 1][ 3] = 16; aaJones[ 1][ 4] = 113; aaJones[ 1][ 5] = 310; aaJones[ 1][ 6] = 29; aaJones[ 1][ 7] = 137; aaJones[ 1][ 8] = 328; aaJones[ 1][ 9] = 22; aaJones[ 1][10] = 38; aaJones[ 1][11] = 646; aaJones[ 1][12] = 44; aaJones[ 1][13] = 5; aaJones[ 1][14] = 74; aaJones[ 1][15] = 101; aaJones[ 1][16] = 64; aaJones[ 1][17] = 126; aaJones[ 1][18] = 20; aaJones[ 1][19] = 17; aaJones[ 2][ 0] = 54; aaJones[ 2][ 1] = 45; aaJones[ 2][ 2] = 0; aaJones[ 2][ 3] = 528; aaJones[ 2][ 4] = 34; aaJones[ 2][ 5] = 86; aaJones[ 2][ 6] = 58; aaJones[ 2][ 7] = 81; aaJones[ 2][ 8] = 391; aaJones[ 2][ 9] = 47; aaJones[ 2][10] = 12; aaJones[ 2][11] = 263; aaJones[ 2][12] = 30; aaJones[ 2][13] = 10; aaJones[ 2][14] = 15; aaJones[ 2][15] = 503; aaJones[ 2][16] = 232; aaJones[ 2][17] = 8; aaJones[ 2][18] = 70; aaJones[ 2][19] = 16; aaJones[ 3][ 0] = 81; aaJones[ 3][ 1] = 16; aaJones[ 3][ 2] = 528; aaJones[ 3][ 3] = 0; aaJones[ 3][ 4] = 10; aaJones[ 3][ 5] = 49; aaJones[ 3][ 6] = 767; aaJones[ 3][ 7] = 130; aaJones[ 3][ 8] = 112; aaJones[ 3][ 9] = 11; aaJones[ 3][10] = 7; aaJones[ 3][11] = 26; aaJones[ 3][12] = 15; aaJones[ 3][13] = 4; aaJones[ 3][14] = 15; aaJones[ 3][15] = 59; aaJones[ 3][16] = 38; aaJones[ 3][17] = 4; aaJones[ 3][18] = 46; aaJones[ 3][19] = 31; aaJones[ 4][ 0] = 56; aaJones[ 4][ 1] = 113; aaJones[ 4][ 2] = 34; aaJones[ 4][ 3] = 10; aaJones[ 4][ 4] = 0; aaJones[ 4][ 5] = 9; aaJones[ 4][ 6] = 5; aaJones[ 4][ 7] = 59; aaJones[ 4][ 8] = 69; aaJones[ 4][ 9] = 17; aaJones[ 4][10] = 23; aaJones[ 4][11] = 7; aaJones[ 4][12] = 31; aaJones[ 4][13] = 78; aaJones[ 4][14] = 14; aaJones[ 4][15] = 223; aaJones[ 4][16] = 42; aaJones[ 4][17] = 115; aaJones[ 4][18] = 209; aaJones[ 4][19] = 62; aaJones[ 5][ 0] = 57; aaJones[ 5][ 1] = 310; aaJones[ 5][ 2] = 86; aaJones[ 5][ 3] = 49; aaJones[ 5][ 4] = 9; aaJones[ 5][ 5] = 0; aaJones[ 5][ 6] = 323; aaJones[ 5][ 7] = 26; aaJones[ 5][ 8] = 597; aaJones[ 5][ 9] = 9; aaJones[ 5][10] = 72; aaJones[ 5][11] = 292; aaJones[ 5][12] = 43; aaJones[ 5][13] = 4; aaJones[ 5][14] = 164; aaJones[ 5][15] = 53; aaJones[ 5][16] = 51; aaJones[ 5][17] = 18; aaJones[ 5][18] = 24; aaJones[ 5][19] = 20; aaJones[ 6][ 0] = 105; aaJones[ 6][ 1] = 29; aaJones[ 6][ 2] = 58; aaJones[ 6][ 3] = 767; aaJones[ 6][ 4] = 5; aaJones[ 6][ 5] = 323; aaJones[ 6][ 6] = 0; aaJones[ 6][ 7] = 119; aaJones[ 6][ 8] = 26; aaJones[ 6][ 9] = 12; aaJones[ 6][10] = 9; aaJones[ 6][11] = 181; aaJones[ 6][12] = 18; aaJones[ 6][13] = 5; aaJones[ 6][14] = 18; aaJones[ 6][15] = 30; aaJones[ 6][16] = 32; aaJones[ 6][17] = 10; aaJones[ 6][18] = 7; aaJones[ 6][19] = 45; aaJones[ 7][ 0] = 179; aaJones[ 7][ 1] = 137; aaJones[ 7][ 2] = 81; aaJones[ 7][ 3] = 130; aaJones[ 7][ 4] = 59; aaJones[ 7][ 5] = 26; aaJones[ 7][ 6] = 119; aaJones[ 7][ 7] = 0; aaJones[ 7][ 8] = 23; aaJones[ 7][ 9] = 6; aaJones[ 7][10] = 6; aaJones[ 7][11] = 27; aaJones[ 7][12] = 14; aaJones[ 7][13] = 5; aaJones[ 7][14] = 24; aaJones[ 7][15] = 201; aaJones[ 7][16] = 33; aaJones[ 7][17] = 55; aaJones[ 7][18] = 8; aaJones[ 7][19] = 47; aaJones[ 8][ 0] = 27; aaJones[ 8][ 1] = 328; aaJones[ 8][ 2] = 391; aaJones[ 8][ 3] = 112; aaJones[ 8][ 4] = 69; aaJones[ 8][ 5] = 597; aaJones[ 8][ 6] = 26; aaJones[ 8][ 7] = 23; aaJones[ 8][ 8] = 0; aaJones[ 8][ 9] = 16; aaJones[ 8][10] = 56; aaJones[ 8][11] = 45; aaJones[ 8][12] = 33; aaJones[ 8][13] = 40; aaJones[ 8][14] = 115; aaJones[ 8][15] = 73; aaJones[ 8][16] = 46; aaJones[ 8][17] = 8; aaJones[ 8][18] = 573; aaJones[ 8][19] = 11; aaJones[ 9][ 0] = 36; aaJones[ 9][ 1] = 22; aaJones[ 9][ 2] = 47; aaJones[ 9][ 3] = 11; aaJones[ 9][ 4] = 17; aaJones[ 9][ 5] = 9; aaJones[ 9][ 6] = 12; aaJones[ 9][ 7] = 6; aaJones[ 9][ 8] = 16; aaJones[ 9][ 9] = 0; aaJones[ 9][10] = 229; aaJones[ 9][11] = 21; aaJones[ 9][12] = 479; aaJones[ 9][13] = 89; aaJones[ 9][14] = 10; aaJones[ 9][15] = 40; aaJones[ 9][16] = 245; aaJones[ 9][17] = 9; aaJones[ 9][18] = 32; aaJones[ 9][19] = 961; aaJones[10][ 0] = 30; aaJones[10][ 1] = 38; aaJones[10][ 2] = 12; aaJones[10][ 3] = 7; aaJones[10][ 4] = 23; aaJones[10][ 5] = 72; aaJones[10][ 6] = 9; aaJones[10][ 7] = 6; aaJones[10][ 8] = 56; aaJones[10][ 9] = 229; aaJones[10][10] = 0; aaJones[10][11] = 14; aaJones[10][12] = 388; aaJones[10][13] = 248; aaJones[10][14] = 102; aaJones[10][15] = 59; aaJones[10][16] = 25; aaJones[10][17] = 52; aaJones[10][18] = 24; aaJones[10][19] = 180; aaJones[11][ 0] = 35; aaJones[11][ 1] = 646; aaJones[11][ 2] = 263; aaJones[11][ 3] = 26; aaJones[11][ 4] = 7; aaJones[11][ 5] = 292; aaJones[11][ 6] = 181; aaJones[11][ 7] = 27; aaJones[11][ 8] = 45; aaJones[11][ 9] = 21; aaJones[11][10] = 14; aaJones[11][11] = 0; aaJones[11][12] = 65; aaJones[11][13] = 4; aaJones[11][14] = 21; aaJones[11][15] = 47; aaJones[11][16] = 103; aaJones[11][17] = 10; aaJones[11][18] = 8; aaJones[11][19] = 14; aaJones[12][ 0] = 54; aaJones[12][ 1] = 44; aaJones[12][ 2] = 30; aaJones[12][ 3] = 15; aaJones[12][ 4] = 31; aaJones[12][ 5] = 43; aaJones[12][ 6] = 18; aaJones[12][ 7] = 14; aaJones[12][ 8] = 33; aaJones[12][ 9] = 479; aaJones[12][10] = 388; aaJones[12][11] = 65; aaJones[12][12] = 0; aaJones[12][13] = 43; aaJones[12][14] = 16; aaJones[12][15] = 29; aaJones[12][16] = 226; aaJones[12][17] = 24; aaJones[12][18] = 18; aaJones[12][19] = 323; aaJones[13][ 0] = 15; aaJones[13][ 1] = 5; aaJones[13][ 2] = 10; aaJones[13][ 3] = 4; aaJones[13][ 4] = 78; aaJones[13][ 5] = 4; aaJones[13][ 6] = 5; aaJones[13][ 7] = 5; aaJones[13][ 8] = 40; aaJones[13][ 9] = 89; aaJones[13][10] = 248; aaJones[13][11] = 4; aaJones[13][12] = 43; aaJones[13][13] = 0; aaJones[13][14] = 17; aaJones[13][15] = 92; aaJones[13][16] = 12; aaJones[13][17] = 53; aaJones[13][18] = 536; aaJones[13][19] = 62; aaJones[14][ 0] = 194; aaJones[14][ 1] = 74; aaJones[14][ 2] = 15; aaJones[14][ 3] = 15; aaJones[14][ 4] = 14; aaJones[14][ 5] = 164; aaJones[14][ 6] = 18; aaJones[14][ 7] = 24; aaJones[14][ 8] = 115; aaJones[14][ 9] = 10; aaJones[14][10] = 102; aaJones[14][11] = 21; aaJones[14][12] = 16; aaJones[14][13] = 17; aaJones[14][14] = 0; aaJones[14][15] = 285; aaJones[14][16] = 118; aaJones[14][17] = 6; aaJones[14][18] = 10; aaJones[14][19] = 23; aaJones[15][ 0] = 378; aaJones[15][ 1] = 101; aaJones[15][ 2] = 503; aaJones[15][ 3] = 59; aaJones[15][ 4] = 223; aaJones[15][ 5] = 53; aaJones[15][ 6] = 30; aaJones[15][ 7] = 201; aaJones[15][ 8] = 73; aaJones[15][ 9] = 40; aaJones[15][10] = 59; aaJones[15][11] = 47; aaJones[15][12] = 29; aaJones[15][13] = 92; aaJones[15][14] = 285; aaJones[15][15] = 0; aaJones[15][16] = 477; aaJones[15][17] = 35; aaJones[15][18] = 63; aaJones[15][19] = 38; aaJones[16][ 0] = 475; aaJones[16][ 1] = 64; aaJones[16][ 2] = 232; aaJones[16][ 3] = 38; aaJones[16][ 4] = 42; aaJones[16][ 5] = 51; aaJones[16][ 6] = 32; aaJones[16][ 7] = 33; aaJones[16][ 8] = 46; aaJones[16][ 9] = 245; aaJones[16][10] = 25; aaJones[16][11] = 103; aaJones[16][12] = 226; aaJones[16][13] = 12; aaJones[16][14] = 118; aaJones[16][15] = 477; aaJones[16][16] = 0; aaJones[16][17] = 12; aaJones[16][18] = 21; aaJones[16][19] = 112; aaJones[17][ 0] = 9; aaJones[17][ 1] = 126; aaJones[17][ 2] = 8; aaJones[17][ 3] = 4; aaJones[17][ 4] = 115; aaJones[17][ 5] = 18; aaJones[17][ 6] = 10; aaJones[17][ 7] = 55; aaJones[17][ 8] = 8; aaJones[17][ 9] = 9; aaJones[17][10] = 52; aaJones[17][11] = 10; aaJones[17][12] = 24; aaJones[17][13] = 53; aaJones[17][14] = 6; aaJones[17][15] = 35; aaJones[17][16] = 12; aaJones[17][17] = 0; aaJones[17][18] = 71; aaJones[17][19] = 25; aaJones[18][ 0] = 11; aaJones[18][ 1] = 20; aaJones[18][ 2] = 70; aaJones[18][ 3] = 46; aaJones[18][ 4] = 209; aaJones[18][ 5] = 24; aaJones[18][ 6] = 7; aaJones[18][ 7] = 8; aaJones[18][ 8] = 573; aaJones[18][ 9] = 32; aaJones[18][10] = 24; aaJones[18][11] = 8; aaJones[18][12] = 18; aaJones[18][13] = 536; aaJones[18][14] = 10; aaJones[18][15] = 63; aaJones[18][16] = 21; aaJones[18][17] = 71; aaJones[18][18] = 0; aaJones[18][19] = 16; aaJones[19][ 0] = 298; aaJones[19][ 1] = 17; aaJones[19][ 2] = 16; aaJones[19][ 3] = 31; aaJones[19][ 4] = 62; aaJones[19][ 5] = 20; aaJones[19][ 6] = 45; aaJones[19][ 7] = 47; aaJones[19][ 8] = 11; aaJones[19][ 9] = 961; aaJones[19][10] = 180; aaJones[19][11] = 14; aaJones[19][12] = 323; aaJones[19][13] = 62; aaJones[19][14] = 23; aaJones[19][15] = 38; aaJones[19][16] = 112; aaJones[19][17] = 25; aaJones[19][18] = 16; aaJones[19][19] = 0; jonesPi[ 0] = 0.076748; jonesPi[ 1] = 0.051691; jonesPi[ 2] = 0.042645; jonesPi[ 3] = 0.051544; jonesPi[ 4] = 0.019803; jonesPi[ 5] = 0.040752; jonesPi[ 6] = 0.061830; jonesPi[ 7] = 0.073152; jonesPi[ 8] = 0.022944; jonesPi[ 9] = 0.053761; jonesPi[10] = 0.091904; jonesPi[11] = 0.058676; jonesPi[12] = 0.023826; jonesPi[13] = 0.040126; jonesPi[14] = 0.050901; jonesPi[15] = 0.068765; jonesPi[16] = 0.058565; jonesPi[17] = 0.014261; jonesPi[18] = 0.032102; jonesPi[19] = 0.066005; aaDayhoff[ 0][ 0] = 0; aaDayhoff[ 0][ 1] = 27; aaDayhoff[ 0][ 2] = 98; aaDayhoff[ 0][ 3] = 120; aaDayhoff[ 0][ 4] = 36; aaDayhoff[ 0][ 5] = 89; aaDayhoff[ 0][ 6] = 198; aaDayhoff[ 0][ 7] = 240; aaDayhoff[ 0][ 8] = 23; aaDayhoff[ 0][ 9] = 65; aaDayhoff[ 0][10] = 41; aaDayhoff[ 0][11] = 26; aaDayhoff[ 0][12] = 72; aaDayhoff[ 0][13] = 18; aaDayhoff[ 0][14] = 250; aaDayhoff[ 0][15] = 409; aaDayhoff[ 0][16] = 371; aaDayhoff[ 0][17] = 0; aaDayhoff[ 0][18] = 24; aaDayhoff[ 0][19] = 208; aaDayhoff[ 1][ 0] = 27; aaDayhoff[ 1][ 1] = 0; aaDayhoff[ 1][ 2] = 32; aaDayhoff[ 1][ 3] = 0; aaDayhoff[ 1][ 4] = 23; aaDayhoff[ 1][ 5] = 246; aaDayhoff[ 1][ 6] = 1; aaDayhoff[ 1][ 7] = 9; aaDayhoff[ 1][ 8] = 240; aaDayhoff[ 1][ 9] = 64; aaDayhoff[ 1][10] = 15; aaDayhoff[ 1][11] = 464; aaDayhoff[ 1][12] = 90; aaDayhoff[ 1][13] = 14; aaDayhoff[ 1][14] = 103; aaDayhoff[ 1][15] = 154; aaDayhoff[ 1][16] = 26; aaDayhoff[ 1][17] = 201; aaDayhoff[ 1][18] = 8; aaDayhoff[ 1][19] = 24; aaDayhoff[ 2][ 0] = 98; aaDayhoff[ 2][ 1] = 32; aaDayhoff[ 2][ 2] = 0; aaDayhoff[ 2][ 3] = 905; aaDayhoff[ 2][ 4] = 0; aaDayhoff[ 2][ 5] = 103; aaDayhoff[ 2][ 6] = 148; aaDayhoff[ 2][ 7] = 139; aaDayhoff[ 2][ 8] = 535; aaDayhoff[ 2][ 9] = 77; aaDayhoff[ 2][10] = 34; aaDayhoff[ 2][11] = 318; aaDayhoff[ 2][12] = 1; aaDayhoff[ 2][13] = 14; aaDayhoff[ 2][14] = 42; aaDayhoff[ 2][15] = 495; aaDayhoff[ 2][16] = 229; aaDayhoff[ 2][17] = 23; aaDayhoff[ 2][18] = 95; aaDayhoff[ 2][19] = 15; aaDayhoff[ 3][ 0] = 120; aaDayhoff[ 3][ 1] = 0; aaDayhoff[ 3][ 2] = 905; aaDayhoff[ 3][ 3] = 0; aaDayhoff[ 3][ 4] = 0; aaDayhoff[ 3][ 5] = 134; aaDayhoff[ 3][ 6] = 1153; aaDayhoff[ 3][ 7] = 125; aaDayhoff[ 3][ 8] = 86; aaDayhoff[ 3][ 9] = 24; aaDayhoff[ 3][10] = 0; aaDayhoff[ 3][11] = 71; aaDayhoff[ 3][12] = 0; aaDayhoff[ 3][13] = 0; aaDayhoff[ 3][14] = 13; aaDayhoff[ 3][15] = 95; aaDayhoff[ 3][16] = 66; aaDayhoff[ 3][17] = 0; aaDayhoff[ 3][18] = 0; aaDayhoff[ 3][19] = 18; aaDayhoff[ 4][ 0] = 36; aaDayhoff[ 4][ 1] = 23; aaDayhoff[ 4][ 2] = 0; aaDayhoff[ 4][ 3] = 0; aaDayhoff[ 4][ 4] = 0; aaDayhoff[ 4][ 5] = 0; aaDayhoff[ 4][ 6] = 0; aaDayhoff[ 4][ 7] = 11; aaDayhoff[ 4][ 8] = 28; aaDayhoff[ 4][ 9] = 44; aaDayhoff[ 4][10] = 0; aaDayhoff[ 4][11] = 0; aaDayhoff[ 4][12] = 0; aaDayhoff[ 4][13] = 0; aaDayhoff[ 4][14] = 19; aaDayhoff[ 4][15] = 161; aaDayhoff[ 4][16] = 16; aaDayhoff[ 4][17] = 0; aaDayhoff[ 4][18] = 96; aaDayhoff[ 4][19] = 49; aaDayhoff[ 5][ 0] = 89; aaDayhoff[ 5][ 1] = 246; aaDayhoff[ 5][ 2] = 103; aaDayhoff[ 5][ 3] = 134; aaDayhoff[ 5][ 4] = 0; aaDayhoff[ 5][ 5] = 0; aaDayhoff[ 5][ 6] = 716; aaDayhoff[ 5][ 7] = 28; aaDayhoff[ 5][ 8] = 606; aaDayhoff[ 5][ 9] = 18; aaDayhoff[ 5][10] = 73; aaDayhoff[ 5][11] = 153; aaDayhoff[ 5][12] = 114; aaDayhoff[ 5][13] = 0; aaDayhoff[ 5][14] = 153; aaDayhoff[ 5][15] = 56; aaDayhoff[ 5][16] = 53; aaDayhoff[ 5][17] = 0; aaDayhoff[ 5][18] = 0; aaDayhoff[ 5][19] = 35; aaDayhoff[ 6][ 0] = 198; aaDayhoff[ 6][ 1] = 1; aaDayhoff[ 6][ 2] = 148; aaDayhoff[ 6][ 3] = 1153; aaDayhoff[ 6][ 4] = 0; aaDayhoff[ 6][ 5] = 716; aaDayhoff[ 6][ 6] = 0; aaDayhoff[ 6][ 7] = 81; aaDayhoff[ 6][ 8] = 43; aaDayhoff[ 6][ 9] = 61; aaDayhoff[ 6][10] = 11; aaDayhoff[ 6][11] = 83; aaDayhoff[ 6][12] = 30; aaDayhoff[ 6][13] = 0; aaDayhoff[ 6][14] = 51; aaDayhoff[ 6][15] = 79; aaDayhoff[ 6][16] = 34; aaDayhoff[ 6][17] = 0; aaDayhoff[ 6][18] = 22; aaDayhoff[ 6][19] = 37; aaDayhoff[ 7][ 0] = 240; aaDayhoff[ 7][ 1] = 9; aaDayhoff[ 7][ 2] = 139; aaDayhoff[ 7][ 3] = 125; aaDayhoff[ 7][ 4] = 11; aaDayhoff[ 7][ 5] = 28; aaDayhoff[ 7][ 6] = 81; aaDayhoff[ 7][ 7] = 0; aaDayhoff[ 7][ 8] = 10; aaDayhoff[ 7][ 9] = 0; aaDayhoff[ 7][10] = 7; aaDayhoff[ 7][11] = 27; aaDayhoff[ 7][12] = 17; aaDayhoff[ 7][13] = 15; aaDayhoff[ 7][14] = 34; aaDayhoff[ 7][15] = 234; aaDayhoff[ 7][16] = 30; aaDayhoff[ 7][17] = 0; aaDayhoff[ 7][18] = 0; aaDayhoff[ 7][19] = 54; aaDayhoff[ 8][ 0] = 23; aaDayhoff[ 8][ 1] = 240; aaDayhoff[ 8][ 2] = 535; aaDayhoff[ 8][ 3] = 86; aaDayhoff[ 8][ 4] = 28; aaDayhoff[ 8][ 5] = 606; aaDayhoff[ 8][ 6] = 43; aaDayhoff[ 8][ 7] = 10; aaDayhoff[ 8][ 8] = 0; aaDayhoff[ 8][ 9] = 7; aaDayhoff[ 8][10] = 44; aaDayhoff[ 8][11] = 26; aaDayhoff[ 8][12] = 0; aaDayhoff[ 8][13] = 48; aaDayhoff[ 8][14] = 94; aaDayhoff[ 8][15] = 35; aaDayhoff[ 8][16] = 22; aaDayhoff[ 8][17] = 27; aaDayhoff[ 8][18] = 127; aaDayhoff[ 8][19] = 44; aaDayhoff[ 9][ 0] = 65; aaDayhoff[ 9][ 1] = 64; aaDayhoff[ 9][ 2] = 77; aaDayhoff[ 9][ 3] = 24; aaDayhoff[ 9][ 4] = 44; aaDayhoff[ 9][ 5] = 18; aaDayhoff[ 9][ 6] = 61; aaDayhoff[ 9][ 7] = 0; aaDayhoff[ 9][ 8] = 7; aaDayhoff[ 9][ 9] = 0; aaDayhoff[ 9][10] = 257; aaDayhoff[ 9][11] = 46; aaDayhoff[ 9][12] = 336; aaDayhoff[ 9][13] = 196; aaDayhoff[ 9][14] = 12; aaDayhoff[ 9][15] = 24; aaDayhoff[ 9][16] = 192; aaDayhoff[ 9][17] = 0; aaDayhoff[ 9][18] = 37; aaDayhoff[ 9][19] = 889; aaDayhoff[10][ 0] = 41; aaDayhoff[10][ 1] = 15; aaDayhoff[10][ 2] = 34; aaDayhoff[10][ 3] = 0; aaDayhoff[10][ 4] = 0; aaDayhoff[10][ 5] = 73; aaDayhoff[10][ 6] = 11; aaDayhoff[10][ 7] = 7; aaDayhoff[10][ 8] = 44; aaDayhoff[10][ 9] = 257; aaDayhoff[10][10] = 0; aaDayhoff[10][11] = 18; aaDayhoff[10][12] = 527; aaDayhoff[10][13] = 157; aaDayhoff[10][14] = 32; aaDayhoff[10][15] = 17; aaDayhoff[10][16] = 33; aaDayhoff[10][17] = 46; aaDayhoff[10][18] = 28; aaDayhoff[10][19] = 175; aaDayhoff[11][ 0] = 26; aaDayhoff[11][ 1] = 464; aaDayhoff[11][ 2] = 318; aaDayhoff[11][ 3] = 71; aaDayhoff[11][ 4] = 0; aaDayhoff[11][ 5] = 153; aaDayhoff[11][ 6] = 83; aaDayhoff[11][ 7] = 27; aaDayhoff[11][ 8] = 26; aaDayhoff[11][ 9] = 46; aaDayhoff[11][10] = 18; aaDayhoff[11][11] = 0; aaDayhoff[11][12] = 243; aaDayhoff[11][13] = 0; aaDayhoff[11][14] = 33; aaDayhoff[11][15] = 96; aaDayhoff[11][16] = 136; aaDayhoff[11][17] = 0; aaDayhoff[11][18] = 13; aaDayhoff[11][19] = 10; aaDayhoff[12][ 0] = 72; aaDayhoff[12][ 1] = 90; aaDayhoff[12][ 2] = 1; aaDayhoff[12][ 3] = 0; aaDayhoff[12][ 4] = 0; aaDayhoff[12][ 5] = 114; aaDayhoff[12][ 6] = 30; aaDayhoff[12][ 7] = 17; aaDayhoff[12][ 8] = 0; aaDayhoff[12][ 9] = 336; aaDayhoff[12][10] = 527; aaDayhoff[12][11] = 243; aaDayhoff[12][12] = 0; aaDayhoff[12][13] = 92; aaDayhoff[12][14] = 17; aaDayhoff[12][15] = 62; aaDayhoff[12][16] = 104; aaDayhoff[12][17] = 0; aaDayhoff[12][18] = 0; aaDayhoff[12][19] = 258; aaDayhoff[13][ 0] = 18; aaDayhoff[13][ 1] = 14; aaDayhoff[13][ 2] = 14; aaDayhoff[13][ 3] = 0; aaDayhoff[13][ 4] = 0; aaDayhoff[13][ 5] = 0; aaDayhoff[13][ 6] = 0; aaDayhoff[13][ 7] = 15; aaDayhoff[13][ 8] = 48; aaDayhoff[13][ 9] = 196; aaDayhoff[13][10] = 157; aaDayhoff[13][11] = 0; aaDayhoff[13][12] = 92; aaDayhoff[13][13] = 0; aaDayhoff[13][14] = 11; aaDayhoff[13][15] = 46; aaDayhoff[13][16] = 13; aaDayhoff[13][17] = 76; aaDayhoff[13][18] = 698; aaDayhoff[13][19] = 12; aaDayhoff[14][ 0] = 250; aaDayhoff[14][ 1] = 103; aaDayhoff[14][ 2] = 42; aaDayhoff[14][ 3] = 13; aaDayhoff[14][ 4] = 19; aaDayhoff[14][ 5] = 153; aaDayhoff[14][ 6] = 51; aaDayhoff[14][ 7] = 34; aaDayhoff[14][ 8] = 94; aaDayhoff[14][ 9] = 12; aaDayhoff[14][10] = 32; aaDayhoff[14][11] = 33; aaDayhoff[14][12] = 17; aaDayhoff[14][13] = 11; aaDayhoff[14][14] = 0; aaDayhoff[14][15] = 245; aaDayhoff[14][16] = 78; aaDayhoff[14][17] = 0; aaDayhoff[14][18] = 0; aaDayhoff[14][19] = 48; aaDayhoff[15][ 0] = 409; aaDayhoff[15][ 1] = 154; aaDayhoff[15][ 2] = 495; aaDayhoff[15][ 3] = 95; aaDayhoff[15][ 4] = 161; aaDayhoff[15][ 5] = 56; aaDayhoff[15][ 6] = 79; aaDayhoff[15][ 7] = 234; aaDayhoff[15][ 8] = 35; aaDayhoff[15][ 9] = 24; aaDayhoff[15][10] = 17; aaDayhoff[15][11] = 96; aaDayhoff[15][12] = 62; aaDayhoff[15][13] = 46; aaDayhoff[15][14] = 245; aaDayhoff[15][15] = 0; aaDayhoff[15][16] = 550; aaDayhoff[15][17] = 75; aaDayhoff[15][18] = 34; aaDayhoff[15][19] = 30; aaDayhoff[16][ 0] = 371; aaDayhoff[16][ 1] = 26; aaDayhoff[16][ 2] = 229; aaDayhoff[16][ 3] = 66; aaDayhoff[16][ 4] = 16; aaDayhoff[16][ 5] = 53; aaDayhoff[16][ 6] = 34; aaDayhoff[16][ 7] = 30; aaDayhoff[16][ 8] = 22; aaDayhoff[16][ 9] = 192; aaDayhoff[16][10] = 33; aaDayhoff[16][11] = 136; aaDayhoff[16][12] = 104; aaDayhoff[16][13] = 13; aaDayhoff[16][14] = 78; aaDayhoff[16][15] = 550; aaDayhoff[16][16] = 0; aaDayhoff[16][17] = 0; aaDayhoff[16][18] = 42; aaDayhoff[16][19] = 157; aaDayhoff[17][ 0] = 0; aaDayhoff[17][ 1] = 201; aaDayhoff[17][ 2] = 23; aaDayhoff[17][ 3] = 0; aaDayhoff[17][ 4] = 0; aaDayhoff[17][ 5] = 0; aaDayhoff[17][ 6] = 0; aaDayhoff[17][ 7] = 0; aaDayhoff[17][ 8] = 27; aaDayhoff[17][ 9] = 0; aaDayhoff[17][10] = 46; aaDayhoff[17][11] = 0; aaDayhoff[17][12] = 0; aaDayhoff[17][13] = 76; aaDayhoff[17][14] = 0; aaDayhoff[17][15] = 75; aaDayhoff[17][16] = 0; aaDayhoff[17][17] = 0; aaDayhoff[17][18] = 61; aaDayhoff[17][19] = 0; aaDayhoff[18][ 0] = 24; aaDayhoff[18][ 1] = 8; aaDayhoff[18][ 2] = 95; aaDayhoff[18][ 3] = 0; aaDayhoff[18][ 4] = 96; aaDayhoff[18][ 5] = 0; aaDayhoff[18][ 6] = 22; aaDayhoff[18][ 7] = 0; aaDayhoff[18][ 8] = 127; aaDayhoff[18][ 9] = 37; aaDayhoff[18][10] = 28; aaDayhoff[18][11] = 13; aaDayhoff[18][12] = 0; aaDayhoff[18][13] = 698; aaDayhoff[18][14] = 0; aaDayhoff[18][15] = 34; aaDayhoff[18][16] = 42; aaDayhoff[18][17] = 61; aaDayhoff[18][18] = 0; aaDayhoff[18][19] = 28; aaDayhoff[19][ 0] = 208; aaDayhoff[19][ 1] = 24; aaDayhoff[19][ 2] = 15; aaDayhoff[19][ 3] = 18; aaDayhoff[19][ 4] = 49; aaDayhoff[19][ 5] = 35; aaDayhoff[19][ 6] = 37; aaDayhoff[19][ 7] = 54; aaDayhoff[19][ 8] = 44; aaDayhoff[19][ 9] = 889; aaDayhoff[19][10] = 175; aaDayhoff[19][11] = 10; aaDayhoff[19][12] = 258; aaDayhoff[19][13] = 12; aaDayhoff[19][14] = 48; aaDayhoff[19][15] = 30; aaDayhoff[19][16] = 157; aaDayhoff[19][17] = 0; aaDayhoff[19][18] = 28; aaDayhoff[19][19] = 0; dayhoffPi[ 0] = 0.087127; dayhoffPi[ 1] = 0.040904; dayhoffPi[ 2] = 0.040432; dayhoffPi[ 3] = 0.046872; dayhoffPi[ 4] = 0.033474; dayhoffPi[ 5] = 0.038255; dayhoffPi[ 6] = 0.049530; dayhoffPi[ 7] = 0.088612; dayhoffPi[ 8] = 0.033618; dayhoffPi[ 9] = 0.036886; dayhoffPi[10] = 0.085357; dayhoffPi[11] = 0.080482; dayhoffPi[12] = 0.014753; dayhoffPi[13] = 0.039772; dayhoffPi[14] = 0.050680; dayhoffPi[15] = 0.069577; dayhoffPi[16] = 0.058542; dayhoffPi[17] = 0.010494; dayhoffPi[18] = 0.029916; dayhoffPi[19] = 0.064718; return (NO_ERROR); } int SetAAQMatrix (double **a, int whichTree, int whichChain) { register int i, j, count, temp; double scaler, mult; /* set diagonal of Q matrix to 0 */ for (i=0; i= 190) { printf (" ERROR: AA model went out of bounds\n"); return (ERROR); } mult = subParams[temp + count]; a[i][i] -= (a[i][j] = baseFreq[whichChain*2*nStates + whichTree*nStates + j] * mult); a[j][j] -= (a[j][i] = baseFreq[whichChain*2*nStates + whichTree*nStates + i] * mult); scaler += baseFreq[whichChain*2*nStates + whichTree*nStates + i] * a[i][j]; scaler += baseFreq[whichChain*2*nStates + whichTree*nStates + j] * a[j][i]; count++; } } } /* rescale Q matrix */ scaler = 1.0 / scaler; for (i=0; i 1) { mult = 0.0; } else { if (transCodon[i] == transCodon[j]) mult = 1.0; else mult = nonsyn; if (isTransition == YES) mult *= kap; } a[i][i] -= (a[i][j] = baseFreq[whichChain*2*nStates + whichTree*nStates + j] * mult); a[j][j] -= (a[j][i] = baseFreq[whichChain*2*nStates + whichTree*nStates + i] * mult); scaler += baseFreq[whichChain*2*nStates + whichTree*nStates + i] * a[i][j]; scaler += baseFreq[whichChain*2*nStates + whichTree*nStates + j] * a[j][i]; } } /* rescale Q matrix */ scaler = 1.0 / scaler; for (i=0; i 1) { multPur = multNeu = multPos = 0.0; } else { if (transCodon[i] == transCodon[j]) { multPur = 1.0; multNeu = 1.0; multPos = 1.0; } else { multPur = 0.0; multNeu = 1.0; multPos = nonsyn; } if (isTransition == YES) { multPur *= kap; multNeu *= kap; multPos *= kap; } } sPur[i][j] = baseFreq[temp + j] * multPur; sPur[j][i] = baseFreq[temp + i] * multPur; sNeu[i][j] = baseFreq[temp + j] * multNeu; sNeu[j][i] = baseFreq[temp + i] * multNeu; sPos[i][j] = baseFreq[temp + j] * multPos; sPos[j][i] = baseFreq[temp + i] * multPos; } } /* get scalers for q matrices */ scaler = 0.0; for (i=0; i= 190) { printf (" ERROR: AA model went out of bounds\n"); return (ERROR); } mult = subParams[temp + count]; s[i][j] = baseFreq[whichChain*2*nStates + whichTree*nStates + j] * mult; s[j][i] = baseFreq[whichChain*2*nStates + whichTree*nStates + i] * mult; scaler += baseFreq[whichChain*2*nStates + whichTree*nStates + i] * s[i][j] * probOn; scaler += baseFreq[whichChain*2*nStates + whichTree*nStates + j] * s[j][i] * probOn; count++; } } } /* rescale off diagonal elements of Q matrix */ scaler = 1.0 / scaler; for (i=0; i infty) */ probs = psdmatrix (4); q = psdmatrix (4); eigenValues = (double *)malloc((size_t) (4 * sizeof(double))); if (!eigenValues) { printf ("\n ERROR: Cannot allocate eigenValues.\n"); return (ERROR); } eigvalsImag = (double *)malloc((size_t) (4 * sizeof(double))); if (!eigvalsImag) { printf ("\n ERROR: Cannot allocate eigvalsImag.\n"); free (eigenValues); return (ERROR); } eigvecs = psdmatrix (4); inverseEigvecs = psdmatrix (4); Ceigvecs = pscmatrix (4); CinverseEigvecs = pscmatrix (4); for (i=0; i<4; i++) for (j=0; j<4; j++) q[i][j] = a[i][j]; isComplex = GetEigens (4, q, eigenValues, eigvalsImag, eigvecs, inverseEigvecs, Ceigvecs, CinverseEigvecs); if (isComplex == NO) { c_ijk = (double *)malloc((size_t) (4 * 4 * 4 * sizeof(double))); if (!c_ijk) { printf ("\n ERROR: Cannot allocate c_ijk.\n"); free (eigenValues); free (eigvalsImag); return (ERROR); } CalcCijk (c_ijk, 4, eigvecs, inverseEigvecs); } stopLoop = NO; v = 0.1; do { if (isComplex == NO) { CalcPij (c_ijk, 4, eigenValues, v, 1.0, probs); } else { if (ComplexChangeMatrix (eigenValues, eigvalsImag, Ceigvecs, CinverseEigvecs, 4, probs, v, 1.0) == ERROR) printf ("Problem calculating transition probabilities for complex eigen values.\n"); } stopLoop = YES; for (i=0; i<4; i++) { max = 0.0; for (j=0; j<3; j++) { for (k=j+1; k<4; k++) { if (fabs(probs[j][i] - probs[k][i]) > max) max = fabs(probs[j][i] - probs[k][i]); } } if (max > 0.00000001) stopLoop = NO; } /*printf ("v = %lf\n", v); for (i=0; i<4; i++) { for (j=0; j<4; j++) printf ("%lf ", probsL[i][j]); printf ("\n"); }*/ v *= 2.0; if (v > 10000.0) { printf ("\n ERROR: Q matrix does not have a stationary distribution\n"); for (i=0; i<4; i++) { for (j=0; j<4; j++) printf ("%lf ", a[i][j]); printf ("\n"); } free_psdmatrix (probs); free_psdmatrix (q); free (eigenValues); free (eigvalsImag); free_psdmatrix (eigvecs); free_psdmatrix (inverseEigvecs); free_pscmatrix (Ceigvecs); free_pscmatrix (CinverseEigvecs); if (isComplex == NO) free (c_ijk); return (ERROR); } } while (stopLoop == NO); baseFreq[whichChain*8 + whichTree*4 + A] = probs[whichTree][0]; baseFreq[whichChain*8 + whichTree*4 + C] = probs[whichTree][1]; baseFreq[whichChain*8 + whichTree*4 + G] = probs[whichTree][2]; baseFreq[whichChain*8 + whichTree*4 + T] = probs[whichTree][3]; free_psdmatrix (probs); free_psdmatrix (q); free (eigenValues); free (eigvalsImag); free_psdmatrix (eigvecs); free_psdmatrix (inverseEigvecs); free_pscmatrix (Ceigvecs); free_pscmatrix (CinverseEigvecs); if (isComplex == NO) free (c_ijk); /* get scaler */ scaler = 0.0; for (i=0; i<4; i++) scaler += baseFreq[whichChain*8 + whichTree*4 + i] * (-a[i][i]); /* rescale Q matrix */ scaler = 1.0 / scaler; for (i=0; i<4; i++) for (j=0; j<4; j++) a[i][j] *= scaler; /*printf ("%lf %lf %lf %lf\n", baseFreq[whichChain*8 + whichTree*4 + A], baseFreq[whichChain*8 + whichTree*4 + C], baseFreq[whichChain*8 + whichTree*4 + G], baseFreq[whichChain*8 + whichTree*4 + T]);*/ } else { printf ("\n ERROR: Unknown model type in Q matrix\n"); return (ERROR); } # if 0 for (i=0; i<4; i++) { for (j=0; j<4; j++) printf ("%0.5lf ", a[i][j]); printf ("\n"); } # endif return (NO_ERROR); } # if defined (SMART_TI_PROBS) int SetUpTransitionProbs (int numRateCats) { int i, lnStates, nRates, lnPartitions, lnumRateCats; /* how many states and rates are there? */ if ((dataType == DNA || dataType == RNA) && enforceCodonModel == NO) { if (!strcmp(ratesModel, "sitespec") || !strcmp(ratesModel, "ssgamma") || !strcmp(ratesModel, "ssadgamma")) lnPartitions = nPartitions; else lnPartitions = 1; if (!strcmp(ratesModel, "equal") || !strcmp(ratesModel, "sitespec")) lnumRateCats = 1; else lnumRateCats = numRateCats; nRates = lnPartitions * lnumRateCats; if (useCovarion == NO) { lnStates = 4; } else { lnStates = 2 * nStates; } } else if ((dataType == DNA || dataType == RNA) && enforceCodonModel == YES) { if (useCovarion == NO) { if (!strcmp(codonModelType, "covny98")) lnStates = 3 * nStates; else lnStates = nStates; if (!strcmp(codonModelType, "ny98") || !strcmp(codonModelType, "ac1ny98") || !strcmp(codonModelType, "ac2ny98")) nRates = 3; else nRates = 1; } else { return (ERROR); } } else if (dataType == PROTEIN) { if (!strcmp(ratesModel, "sitespec") || !strcmp(ratesModel, "ssgamma") || !strcmp(ratesModel, "ssadgamma")) lnPartitions = nPartitions; else lnPartitions = 1; if (!strcmp(ratesModel, "equal") || !strcmp(ratesModel, "sitespec")) lnumRateCats = 1; else lnumRateCats = numRateCats; nRates = lnPartitions * lnumRateCats; if (useCovarion == NO) { lnStates = 20; } else { lnStates = 2 * nStates; } } else if (dataType == RESTRICTION) { if (!strcmp(ratesModel, "sitespec") || !strcmp(ratesModel, "ssgamma") || !strcmp(ratesModel, "ssadgamma")) lnPartitions = nPartitions; else lnPartitions = 1; if (!strcmp(ratesModel, "equal") || !strcmp(ratesModel, "sitespec")) lnumRateCats = 1; else lnumRateCats = numRateCats; nRates = lnPartitions * lnumRateCats; if (useCovarion == NO) { lnStates = 2; } else { return (ERROR); } } else if (dataType == STANDARD) { if (!strcmp(ratesModel, "sitespec") || !strcmp(ratesModel, "ssgamma") || !strcmp(ratesModel, "ssadgamma")) lnPartitions = nPartitions; else lnPartitions = 1; if (!strcmp(ratesModel, "equal") || !strcmp(ratesModel, "sitespec")) lnumRateCats = 1; else lnumRateCats = numRateCats; nRates = lnPartitions * lnumRateCats; if (useCovarion == NO) { lnStates = 2; } else { return (ERROR); } } else return (ERROR); /* how big is the information at one node */ nodeTiSize = nRates * lnStates * lnStates; /* allocate enough memory for all of the transition probabilities on the tree */ transitionProbs = (double *)malloc((size_t) (numChains * 2 * numNodes * nodeTiSize * sizeof(double))); if (!transitionProbs) { printf ("ERROR: Problem allocating transitionProbs\n"); return (ERROR); } else allocatedMemory[ALLOC_TI_PROBS] = YES; updateTiFlag = (int *)malloc((size_t) (numNodes * sizeof(int))); if (!updateTiFlag) { printf ("ERROR: Problem allocating updateTiFlag\n"); return (ERROR); } else allocatedMemory[ALLOC_TI_FLAGS] = YES; for (i=0; iscaler = 0.0; p->scalerNode = NO; if (p->length < BRLEN_EPSILON) p->length = 2 * BRLEN_EPSILON; } //printf ("Starting tree %d:\n", n); //ShowTree (spTreeRoot[n*2+0], 2); } clUpdateFlag = (int *)malloc((size_t) numNodes * sizeof(int)); if (!clUpdateFlag) { printf ("\n ERROR: Problem allocating clUpdateFlag\n"); FreeMemory (); return (ERROR); } else allocatedMemory[ALLOC_CLUPDATE_FLAG] = YES; for (i=0; ileft == NULL && p->right == NULL) { p->x = x; x += 2; p->y = 0; nLines += 2; } else if (p->left != NULL && p->right != NULL && p->anc != NULL) { p->x = p->left->x + (p->right->x - p->left->x) / 2; if (p->left->y > p->right->y) p->y = p->left->y + 1; else p->y = p->right->y + 1; } else { p->x = x; x += 2; p->y = 0; } } /* print tree out, line-by-line */ levelDepth = SCREENWIDTH / r->left->y; nLevels = r->left->y; for (j=0; j<=nLines-2; j++) { if (j % 2 == 0) { for (i=0; ileft == NULL && p->x == j) { strcpy (labelLine, p->label); } } } for (i=0; ianc != NULL) { if (p->anc->anc != NULL) { if (p->x == j) { from = (nLevels - p->anc->y) * levelDepth; to = (nLevels - p->y) * levelDepth; if (p->y == 0) to = SCREENWIDTH-1; if (to >= SCREENWIDTH) to = SCREENWIDTH-1; for (k=from; kanc->left == p) treeLine[from] = '/'; else treeLine[from] = '\\'; if (p->left != NULL) { # if defined (EDDIE_NODES) treeLine[to] = '|'; # else treeLine[to] = '+'; # endif } if (p->anc->anc == r && p->anc->right == p) { if (isThisTreeRooted == NO) { if (p->left != NULL) # if defined (EDDIE_NODES) treeLine[to] = '|'; # else treeLine[to] = '+'; # endif } else treeLine[from] = '\\'; } } else if (p->left != NULL && p->right != NULL) { if (j < p->x && j > p->left->x) { from = (nLevels - p->y) * levelDepth; treeLine[from] = '|'; } else if (j > p->x && j < p->right->x) { from = (nLevels - p->y) * levelDepth; treeLine[from] = '|'; } } } else { if (p->x == j) { treeLine[0] = '|'; /* temp */ } else if (j < p->x && j > p->left->x) { treeLine[0] = '|'; } else if (j > p->x && j < p->right->x) { treeLine[0] = '|'; } if (isThisTreeRooted == NO) { if (j > p->x && j <= nLines-2) treeLine[0] = '|'; if (j == p->right->x) # if defined (EDDIE_NODES) treeLine[0] = '|'; # else treeLine[0] = '+'; # endif } else { if (j == p->x) # if defined (EDDIE_NODES) treeLine[0] = '|'; # else treeLine[0] = '+'; # endif } } } } if (j % 2 == 0) printf (" %s %s\n", treeLine, labelLine); else printf (" %s \n", treeLine); } if (isThisTreeRooted == NO) { for (i=0; ilabel); labelLine[19] = '\0'; printf (" %s %s\n", treeLine, labelLine); } free (downPass); return (NO_ERROR); } void UpDateAllCls (int whichState, int whichChain) { int i; TreeNode *p; for (i=0; iupDateCl = YES; } } #if defined (SMART_TI_PROBS) void UpDateAllTIs (int whichState, int whichChain) { int i; TreeNode *p; for (i=0; iupDateTi = YES; } } #endif char WhichAA (int x) { if (x == 0) return ('A'); else if (x == 1) return ('R'); else if (x == 2) return ('N'); else if (x == 3) return ('D'); else if (x == 4) return ('C'); else if (x == 5) return ('Q'); else if (x == 6) return ('E'); else if (x == 7) return ('G'); else if (x == 8) return ('H'); else if (x == 9) return ('I'); else if (x == 10) return ('L'); else if (x == 11) return ('K'); else if (x == 12) return ('M'); else if (x == 13) return ('F'); else if (x == 14) return ('P'); else if (x == 15) return ('S'); else if (x == 16) return ('T'); else if (x == 17) return ('W'); else if (x == 18) return ('Y'); else if (x == 19) return ('V'); else return ('?'); } void WriteTreeToFile (TreeNode *p, FILE *fp, int showBrlens) { if (p != NULL) { if (p->left == NULL && p->right == NULL) { if (showBrlens == YES) fprintf (fp, "%d:%1.6lf", p->index + 1, p->length); else fprintf (fp, "%d", p->index + 1); } else { if (p->anc != NULL) fprintf (fp, "("); WriteTreeToFile (p->left, fp, showBrlens); if (p->anc != NULL) fprintf (fp, ","); WriteTreeToFile (p->right, fp, showBrlens); if (p->anc != NULL) { if (p->anc->anc == NULL) { if (treeModel == UNROOTED) { if (showBrlens == YES) fprintf (fp, ",%d:%1.6lf);\n", p->anc->index + 1, p->length); else fprintf (fp, ",%d);\n", p->anc->index + 1); } else fprintf (fp, ");\n"); } else { if (showBrlens == YES) fprintf (fp, "):%1.6lf", p->length); else fprintf (fp, ")"); } } } } } void WriteTreeToScreen (TreeNode *p, int showBrlens) { if (p != NULL) { if (p->left == NULL && p->right == NULL) { if (showBrlens == YES) printf ("%s:%1.6lf", p->label, p->length); else printf ("%s", p->label); } else { if (p->anc != NULL) printf ("("); WriteTreeToScreen (p->left, showBrlens); if (p->anc != NULL) printf (","); WriteTreeToScreen (p->right, showBrlens); if (p->anc != NULL) { if (p->anc->anc == NULL) { if (showBrlens == YES) printf (",%s:%1.6lf);\n", p->anc->label, p->length); else printf (",%s);\n", p->anc->label); } else { if (showBrlens == YES) printf ("):%1.6lf", p->length); else printf (")"); } } } } } int YesNo (void) { char tempString[20], *s; unsigned int i; for (;;) { fgets (tempString,20,stdin); s = strtok(tempString," ;\n"); for (i=0; i