+/*
+ * MrBayes 3
+ *
+ * (c) 2002-2013
+ *
+ * John P. Huelsenbeck
+ * Dept. Integrative Biology
+ * University of California, Berkeley
+ * Berkeley, CA 94720-3140
+ * johnh@berkeley.edu
+ *
+ * Fredrik Ronquist
+ * Swedish Museum of Natural History
+ * Box 50007
+ * SE-10405 Stockholm, SWEDEN
+ * fredrik.ronquist@nrm.se
+ *
+ * With important contributions by
+ *
+ * Paul van der Mark (paulvdm@sc.fsu.edu)
+ * Maxim Teslenko (maxim.teslenko@nrm.se)
+ *
+ * and by many users (run 'acknowledgments' to see more info)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details (www.gnu.org).
+ *
+ */
+
+#include "bayes.h"
+#include "best.h"
+#include "command.h"
+#include "model.h"
+#include "mcmc.h"
+#include "proposal.h"
+#include "sumpt.h"
+#include "utils.h"
+#if defined(__MWERKS__)
+#include "SIOUX.h"
+#endif
+
+const char* const svnRevisionModelC = "$Rev: 1067 $"; /* Revision keyword which is expended/updated by svn on each commit/update */
+
+#undef DEBUG_ADDDUMMYCHARS
+#undef DEBUG_CONSTRAINTS
+#undef DEBUG_COMPRESSDATA
+#undef DEBUG_CPP
+
+/* local prototypes */
+int AddDummyChars (void);
+void AllocateCppEvents (Param *p);
+MCMCMove *AllocateMove (MoveType *moveType, Param *param);
+int AllocateNormalParams (void);
+int AllocateTreeParams (void);
+void CheckCharCodingType (Matrix *m, CharInfo *ci);
+int CheckExpandedModels (void);
+int CompressData (void);
+int InitializeChainTrees (Param *p, int from, int to, int isRooted);
+int FillBrlensSubParams (Param *param, int chn, int state);
+void FreeCppEvents (Param *p);
+void FreeMove (MCMCMove *mv);
+void GetPossibleAAs (int aaCode, int aa[]);
+void GetPossibleNucs (int nucCode, int nuc[]);
+void GetPossibleRestrictionSites (int resSiteCode, int *sites);
+int GetUserTreeFromName (int *index, char *treeName);
+void InitializeMcmcTrees (Param *p);
+int IsApplicable (Param *param);
+int IsApplicable_FiveTaxaOrMore (Param *param);
+int IsApplicable_FourTaxaOrMore (Param *param);
+int IsApplicable_ThreeTaxaOrMore (Param *param);
+int IsApplicableTreeAgeMove (Param *param);
+int IsModelSame (int whichParam, int part1, int part2, int *isApplic1, int *isApplic2);
+int LargestMovableSubtree(Param *treeParam);
+int NumActiveParts (void);
+int NumInformativeHardConstraints (ModelParams *mp);
+int NumNonExcludedChar (void);
+int NumStates (int part);
+int PrintCompMatrix (void);
+int PrintMatrix (void);
+int ProcessStdChars (RandLong *seed);
+void SetCode (int part);
+int SetModelParams (void);
+int SetPopSizeParam (Param *param, int chn, int state, PolyTree *pt);
+int SetRelaxedClockParam (Param *param, int chn, int state, PolyTree *pt);
+int SetUpLinkTable (void);
+int ShowMoves (int used);
+int ShowParameters (int showStartVals, int showMoves, int showAllAvailable);
+int UpdateCppEvolLength (int *nEvents, MrBFlt **pos, MrBFlt **rateMult, MrBFlt *evolLength, TreeNode *p, MrBFlt baseRate);
+
+/* globals */
+int *activeParams[NUM_LINKED]; /* a table holding the parameter link status */
+int localOutGroup; /* outgroup for non-excluded taxa */
+Calibration **localTaxonCalibration = NULL; /* stores local taxon calibrations (ages) */
+char **localTaxonNames = NULL; /* points to names of non-excluded taxa */
+Model *modelParams; /* holds model params */
+ModelInfo *modelSettings; /* stores important info on model params */
+MCMCMove **moves; /* vector of pointers to applicable moves */
+int numApplicableMoves; /* number of moves applicable to model parameters */
+int numCurrentDivisions; /* number of partitions of data */
+int numGlobalChains; /* number of global chains */
+int numLocalTaxa; /* number of non-excluded taxa */
+int numLocalChar; /* number of non-excluded characters */
+int numParams; /* number of parameters in model */
+int numTopologies; /* number of topologies for one chain and state */
+int numTrees; /* number of trees for one chain and state */
+Param *params; /* vector of parameters */
+Param *printParams; /* vector of subst model parameters to print */
+ShowmovesParams showmovesParams; /* holds parameters for Showmoves command */
+Param *treePrintparams; /* vector of tree parameters to print */
+int setUpAnalysisSuccess; /* Set to YES if analysis is set without error */
+
+/* globals used to describe and change the current model; allocated in AllocCharacters and SetPartition */
+int *numVars; /* number of variables in setting arrays */
+int *activeParts; /* partitions changes should apply to */
+int *linkTable[NUM_LINKED]; /* how parameters are linked across parts */
+int *tempLinkUnlink[NUM_LINKED]; /* for changing parameter linkage */
+int *tempLinkUnlinkVec; /* for changing parameter linkage */
+MrBFlt *tempNum; /* vector of numbers used for setting arrays */
+
+/* Aamodel parameters */
+MrBFlt aaJones[20][20]; /* rates for Jones model */
+MrBFlt aaDayhoff[20][20]; /* rates for Dayhoff model */
+MrBFlt aaMtrev24[20][20]; /* rates for mtrev24 model */
+MrBFlt aaMtmam[20][20]; /* rates for mtmam model */
+MrBFlt aartREV[20][20]; /* rates for rtREV model */
+MrBFlt aaWAG[20][20]; /* rates for WAG model */
+MrBFlt aacpREV[20][20]; /* rates for aacpREV model */
+MrBFlt aaVt[20][20]; /* rates for VT model */
+MrBFlt aaBlosum[20][20]; /* rates for Blosum62 model */
+MrBFlt aaLG[20][20]; /* rates for LG model */
+MrBFlt jonesPi[20]; /* stationary frequencies for Jones model */
+MrBFlt dayhoffPi[20]; /* stationary frequencies for Dayhoff model */
+MrBFlt mtrev24Pi[20]; /* stationary frequencies for mtrev24 model */
+MrBFlt mtmamPi[20]; /* stationary frequencies for mtmam model */
+MrBFlt rtrevPi[20]; /* stationary frequencies for rtREV model */
+MrBFlt wagPi[20]; /* stationary frequencies for WAG model */
+MrBFlt cprevPi[20]; /* stationary frequencies for aacpREV model */
+MrBFlt vtPi[20]; /* stationary frequencies for VT model */
+MrBFlt blosPi[20]; /* stationary frequencies for Blosum62 model */
+MrBFlt lgPi[20]; /* stationary frequencies for LG model */
+
+/* parser flags and variables */
+int fromI, toJ, foundDash, foundComma, foundEqual, foundBeta,
+ foundAaSetting, foundExp, modelIsFixed, linkNum, foundLeftPar,
+ foundFSNum[999], foundFSTime[999], tempNumStates, isNegative;
+MrBFlt tempStateFreqs[200], tempAaModelPrs[10];
+char colonPr[100], clockPr[30];
+
+/* other local variables (this file) */
+MrBFlt empiricalFreqs[200]; /* emprical base frequencies for partition */
+int intValsRowSize = 0; /* row size of intValues matrix */
+int *intValues = NULL; /* stores int values of chain parameters */
+Tree **mcmcTree; /* pointers to trees for mcmc */
+int paramValsRowSize = 0; /* row size of paramValues matrix */
+MrBFlt *paramValues = NULL; /* stores actual values and subvalues of chain parameters */
+int *relevantParts = NULL; /* partitions that are affected by this move */
+Param **subParamPtrs; /* pointer to subparams for topology params */
+int *stateSize; /* # states for each compressed char */
+// int foundCurly;
+// char *plotTokenP; /* plotToken[CMD_STRING_LENGTH];*/
+
+
+/*-----------------------------------------------------------------------
+|
+| AddDummyChars: Add dummy characters to relevant partitions
+|
+------------------------------------------------------------------------*/
+int AddDummyChars (void)
+{
+ int i, j, k, d, numIncompatible, numDeleted, numStdChars, oldRowSize,
+ newRowSize, numDummyChars, newColumn, newChar, oldColumn, oldChar,
+ isCompat, *tempChar, numIncompatibleChars;
+ BitsLong *tempMatrix, bitsLongOne = 1;
+ CLFlt *tempSitesOfPat;
+ ModelInfo *m;
+ ModelParams *mp;
+ CharInfo cinfo;
+ Matrix matrix;
+
+ /* set pointers to NULL */
+ tempMatrix = NULL;
+ tempSitesOfPat = NULL;
+ tempChar = NULL;
+
+ /* check how many dummy characters needed in total */
+ numDummyChars = 0;
+ numStdChars = 0;
+ for (d=0; d<numCurrentDivisions; d++)
+ {
+ m = &modelSettings[d];
+ mp = &modelParams[d];
+
+ m->numDummyChars = 0;
+
+ if (mp->dataType == RESTRICTION && !strcmp(mp->parsModel,"No"))
+ {
+ if (mp->coding & NOABSENCESITES)
+ m->numDummyChars++;
+ if (mp->coding & NOPRESENCESITES)
+ m->numDummyChars++;
+ if (mp->coding & NOSINGLETONABSENCE)
+ m->numDummyChars += numLocalTaxa;
+ if (mp->coding & NOSINGLETONPRESENCE)
+ m->numDummyChars += numLocalTaxa;
+ }
+
+ if (mp->dataType == STANDARD && !strcmp(mp->parsModel,"No"))
+ {
+ if (mp->coding & VARIABLE)
+ m->numDummyChars += 2;
+ if (mp->coding & NOSINGLETONS)
+ m->numDummyChars += 2*numLocalTaxa;
+ numStdChars += (m->numChars + m->numDummyChars);
+ }
+
+ numDummyChars += m->numDummyChars;
+ m->numChars += m->numDummyChars;
+ }
+
+ /* exit if dummy characters not needed */
+ if (numDummyChars == 0)
+ return NO_ERROR;
+
+ /* print original compressed matrix */
+# if defined (DEBUG_ADDDUMMYCHARS)
+ MrBayesPrint ("Compressed matrix before adding dummy characters...\n");
+ PrintCompMatrix();
+# endif
+
+ /* set row sizes for old and new matrices */
+ oldRowSize = compMatrixRowSize;
+ compMatrixRowSize += numDummyChars;
+ newRowSize = compMatrixRowSize;
+ numCompressedChars += numDummyChars;
+
+ /* allocate space for new data */
+ tempMatrix = (BitsLong *) SafeCalloc (numLocalTaxa * newRowSize, sizeof(BitsLong));
+ tempSitesOfPat = (CLFlt *) SafeCalloc (numCompressedChars, sizeof(CLFlt));
+ tempChar = (int *) SafeCalloc (compMatrixRowSize, sizeof(int));
+ if (!tempMatrix || !tempSitesOfPat || !tempChar)
+ {
+ MrBayesPrint ("%s Problem allocating temporary variables in AddDummyChars\n", spacer);
+ goto errorExit;
+ }
+
+ /* initialize indices */
+ oldChar = newChar = newColumn = numDeleted = 0;
+
+ /* set up matrix struct */
+ matrix.origin = compMatrix;
+ matrix.nRows = numLocalTaxa;
+ matrix.rowSize = oldRowSize;
+
+ /* loop over divisions */
+ for (d=0; d<numCurrentDivisions; d++)
+ {
+ m = &modelSettings[d];
+ mp = &modelParams[d];
+
+ /* insert the dummy characters first for each division */
+ if (m->numDummyChars > 0)
+ {
+ // MrBayesPrint("%s Adding dummy characters (unobserved site patterns) for division %d\n", spacer, d+1);
+ // do not print this every time
+
+ for (k=0; k<2; k++)
+ {
+ if (((mp->coding & NOSINGLETONPRESENCE) && k == 0) || ((mp->coding & NOSINGLETONABSENCE) && k == 1))
+ {
+ for (i=0; i< numLocalTaxa; i++)
+ {
+ for (j=0; j<numLocalTaxa; j++)
+ {
+ if (j == i)
+ tempMatrix[pos(j,newColumn,newRowSize)] = (bitsLongOne << k) ^ 3;
+ else
+ tempMatrix[pos(j,newColumn,newRowSize)] = bitsLongOne << k;
+ }
+ tempSitesOfPat[newChar] = 0;
+ tempChar[newColumn] = -1;
+ newChar++;
+ newColumn++;
+ }
+ }
+ }
+
+ if (mp->coding & NOABSENCESITES)
+ {
+ for (i=0; i<numLocalTaxa; i++)
+ tempMatrix[pos(i,newColumn,newRowSize)] = 1;
+ tempSitesOfPat[newChar] = 0;
+ tempChar[newColumn] = -1;
+ newChar++;
+ newColumn++;
+ }
+
+ if (mp->coding & NOPRESENCESITES)
+ {
+ for (i=0; i<numLocalTaxa; i++)
+ tempMatrix[pos(i,newColumn,newRowSize)] = 2;
+ tempSitesOfPat[newChar] = 0;
+ tempChar[newColumn] = -1;
+ newChar++;
+ newColumn++;
+ }
+ }
+
+ /* add the normal characters */
+ numIncompatible = numIncompatibleChars = 0;
+ for (oldColumn=m->compMatrixStart; oldColumn<m->compMatrixStop; oldColumn++)
+ {
+ isCompat = YES;
+ /* first check if the character is supposed to be present */
+ if (m->numDummyChars > 0)
+ {
+ /* set up matrix struct */
+ matrix.column = oldColumn;
+ /* set up charinfo struct */
+ cinfo.dType = mp->dataType;
+ cinfo.cType = charInfo[origChar[oldChar]].ctype;
+ cinfo.nStates = charInfo[origChar[oldChar]].numStates;
+ CheckCharCodingType(&matrix, &cinfo);
+
+ if (mp->coding & VARIABLE)
+ {
+ if((mp->coding & VARIABLE) == VARIABLE && cinfo.variable == NO)
+ {
+ isCompat = NO;
+ }
+ else if((mp->coding & NOABSENCESITES) && cinfo.constant[0] == YES)
+ {
+ isCompat = NO;
+ }
+ else if((mp->coding & NOPRESENCESITES) && cinfo.constant[1] == YES)
+ {
+ isCompat = NO;
+ }
+ }
+ if (mp->coding & NOSINGLETONS)
+ {
+ if((mp->coding & NOSINGLETONS) == NOSINGLETONS && cinfo.informative == NO && cinfo.variable == YES)
+ {
+ isCompat = NO;
+ }
+ else if((mp->coding & NOSINGLETONABSENCE) && cinfo.singleton[0] == YES && cinfo.informative == NO)
+ {
+ isCompat = NO;
+ }
+ else if((mp->coding & NOSINGLETONPRESENCE) && cinfo.singleton[1] == YES && cinfo.informative == NO)
+ {
+ isCompat = NO;
+ }
+ }
+ }
+
+ if (isCompat == NO)
+ {
+ numIncompatible++;
+ numIncompatibleChars += (int) numSitesOfPat[oldChar];
+ oldChar++;
+ }
+ else
+ {
+ /* add character */
+ for (i=0; i<numLocalTaxa; i++)
+ tempMatrix[pos(i,newColumn,newRowSize)] = compMatrix[pos(i,oldColumn,oldRowSize)];
+ /* set indices */
+ compCharPos[origChar[oldColumn]] = newChar;
+ compColPos[origChar[oldColumn]] = newColumn;
+ tempSitesOfPat[newChar] = numSitesOfPat[oldChar];
+ tempChar[newColumn] = origChar[oldColumn];
+ newColumn++;
+ if ((oldColumn-m->compMatrixStart+1) % m->nCharsPerSite == 0)
+ {
+ newChar++;
+ oldChar++;
+ }
+ }
+ }
+
+ /* print a warning if there are incompatible characters */
+ if (numIncompatible > 0)
+ {
+ m->numChars -= numIncompatible;
+ m->numUncompressedChars -= numIncompatibleChars;
+ numDeleted += numIncompatible;
+ if (numIncompatibleChars > 1)
+ {
+ MrBayesPrint ("%s WARNING: There are %d characters incompatible with the specified\n", spacer, numIncompatibleChars);
+ MrBayesPrint ("%s coding bias. These characters will be excluded.\n", spacer);
+ }
+ else
+ {
+ MrBayesPrint ("%s WARNING: There is one character incompatible with the specified\n", spacer);
+ MrBayesPrint ("%s coding bias. This character will be excluded.\n", spacer);
+ }
+ }
+
+ /* update division comp matrix and comp char pointers */
+ m->compCharStop = newChar;
+ m->compMatrixStop = newColumn;
+ m->compCharStart = newChar - m->numChars;
+ m->compMatrixStart = newColumn - m->nCharsPerSite * m->numChars;
+
+ } /* next division */
+
+ /* compress matrix if necessary */
+ if (numDeleted > 0)
+ {
+ for (i=k=0; i<numLocalTaxa; i++)
+ {
+ for (j=0; j<newRowSize-numDeleted; j++)
+ {
+ tempMatrix[k++] = tempMatrix[j+i*newRowSize];
+ }
+ }
+ numCompressedChars -= numDeleted;
+ compMatrixRowSize -= numDeleted;
+ }
+
+ /* free old data, set pointers to new data */
+ free (compMatrix);
+ free (numSitesOfPat);
+ free (origChar);
+
+ compMatrix = tempMatrix;
+ numSitesOfPat = tempSitesOfPat;
+ origChar = tempChar;
+
+ tempMatrix = NULL;
+ tempSitesOfPat = NULL;
+ tempChar = NULL;
+
+ /* print new compressed matrix */
+# if defined (DEBUG_ADDDUMMYCHARS)
+ MrBayesPrint ("After adding dummy characters...\n");
+ PrintCompMatrix();
+# endif
+
+ return NO_ERROR;
+
+ errorExit:
+ if (tempMatrix)
+ free (tempMatrix);
+ if (tempSitesOfPat)
+ free (tempSitesOfPat);
+ if (tempChar)
+ free (tempChar);
+
+ return ERROR;
+}
+
+
+/* Allocate space for cpp events */
+void AllocateCppEvents (Param *p)
+{
+ int i;
+
+ p->nEvents = (int **) SafeCalloc (2*numGlobalChains, sizeof (int *));
+ p->nEvents[0] = (int *) SafeCalloc (2*numGlobalChains*(2*numLocalTaxa), sizeof (int));
+ for (i=1; i<2*numGlobalChains; i++)
+ p->nEvents[i] = p->nEvents[i-1] + (2*numLocalTaxa);
+ p->position = (MrBFlt ***) SafeCalloc (2*numGlobalChains, sizeof (MrBFlt **));
+ p->position[0] = (MrBFlt **) SafeCalloc (2*numGlobalChains*(2*numLocalTaxa), sizeof (MrBFlt *));
+ for (i=1; i<2*numGlobalChains; i++)
+ p->position[i] = p->position[i-1] + (2*numLocalTaxa);
+ p->rateMult = (MrBFlt ***) SafeCalloc (2*numGlobalChains, sizeof (MrBFlt **));
+ p->rateMult[0] = (MrBFlt **) SafeCalloc (2*numGlobalChains*(2*numLocalTaxa), sizeof (MrBFlt *));
+ for (i=1; i<2*numGlobalChains; i++)
+ p->rateMult[i] = p->rateMult[i-1] + (2*numLocalTaxa);
+
+}
+
+
+/*----------------------------------------------------------------------------
+|
+| AllocateMove: Allocate space for and initialize one applicable move
+|
+-----------------------------------------------------------------------------*/
+MCMCMove *AllocateMove (MoveType *moveType, Param *param)
+{
+ int i, j, nameLength;
+ char *partitionDescriptor = "";
+ MCMCMove *temp;
+
+ if ((temp = (MCMCMove *) SafeCalloc (1, sizeof (MCMCMove))) == NULL)
+ return (NULL);
+
+ /* calculate length */
+ if (strcmp (moveType->paramName, "") == 0)
+ nameLength = (int) (strlen (moveType->shortName) + strlen (param->name)) + 10;
+ else
+ {
+ partitionDescriptor = param->name;
+ while (*partitionDescriptor != '\0')
+ {
+ if (*partitionDescriptor == '{')
+ break;
+ partitionDescriptor++;
+ }
+ nameLength = (int) (strlen (moveType->shortName) + strlen (moveType->paramName) + strlen (partitionDescriptor)) + 10;
+ }
+ /* add length of names of subparams */
+ if (moveType->subParams == YES)
+ {
+ for (i=0; i<param->nSubParams; i++)
+ nameLength += (int)(strlen(param->subParams[i]->name)) + 1;
+ }
+
+ if ((temp->name = (char *) SafeCalloc (nameLength, sizeof (char))) == NULL)
+ {
+ free (temp);
+ return NULL;
+ }
+
+ if ((temp->nAccepted = (int *) SafeCalloc (5*numGlobalChains, sizeof (int))) == NULL)
+ {
+ free (temp->name);
+ free (temp);
+ return NULL;
+ }
+ temp->nTried = temp->nAccepted + numGlobalChains;
+ temp->nBatches = temp->nAccepted + 2*numGlobalChains;
+ temp->nTotAccepted = temp->nAccepted + 3*numGlobalChains;
+ temp->nTotTried = temp->nAccepted + 4*numGlobalChains;
+
+ if ((temp->relProposalProb = (MrBFlt *) SafeCalloc (4*numGlobalChains, sizeof (MrBFlt))) == NULL)
+ {
+ free (temp->nAccepted);
+ free (temp->name);
+ free (temp);
+ return NULL;
+ }
+ temp->cumProposalProb = temp->relProposalProb + numGlobalChains;
+ temp->targetRate = temp->relProposalProb + 2*numGlobalChains;
+ temp->lastAcceptanceRate = temp->relProposalProb + 3*numGlobalChains;
+
+ if ((temp->tuningParam = (MrBFlt **) SafeCalloc (numGlobalChains, sizeof (MrBFlt *))) == NULL)
+ {
+ free (temp->relProposalProb);
+ free (temp->nAccepted);
+ free (temp->name);
+ free (temp);
+ return NULL;
+ }
+ if ((temp->tuningParam[0] = (MrBFlt *) SafeCalloc (moveType->numTuningParams*numGlobalChains, sizeof (MrBFlt))) == NULL)
+ {
+ free (temp->tuningParam);
+ free (temp->relProposalProb);
+ free (temp->nAccepted);
+ free (temp->name);
+ free (temp);
+ return NULL;
+ }
+ for (i=1; i<numGlobalChains; i++)
+ temp->tuningParam[i] = temp->tuningParam[0] + (i * moveType->numTuningParams);
+
+ /* set default values */
+ if (strcmp(moveType->paramName, "") != 0)
+ sprintf (temp->name, "%s(%s%s)", moveType->shortName, moveType->paramName, partitionDescriptor);
+ else
+ {
+ sprintf (temp->name, "%s(%s", moveType->shortName, param->name);
+ if (moveType->subParams == YES)
+ {
+ for (i=0; i<param->nSubParams; i++)
+ {
+ strcat(temp->name,",");
+ strcat(temp->name,param->subParams[i]->name);
+ }
+ }
+ strcat (temp->name,")");
+ }
+
+ temp->moveType = moveType;
+ temp->moveFxn = moveType->moveFxn;
+ for (i=0; i<numGlobalChains; i++)
+ {
+ temp->relProposalProb[i] = moveType->relProposalProb;
+ temp->cumProposalProb[i] = 0.0;
+ temp->nAccepted[i] = 0;
+ temp->nTried[i] = 0;
+ temp->nBatches[i] = 0;
+ temp->nTotAccepted[i] = 0;
+ temp->nTotTried[i] = 0;
+ temp->targetRate[i] = moveType->targetRate;
+ temp->lastAcceptanceRate[i] = 0.0;
+ for (j=0; j<moveType->numTuningParams; j++)
+ temp->tuningParam[i][j] = moveType->tuningParam[j];
+ }
+ return (temp);
+}
+
+
+/*----------------------------------------------------------------------
+|
+| AllocateNormalParams: Allocate space for normal parameters
+|
+-----------------------------------------------------------------------*/
+int AllocateNormalParams (void)
+{
+ int i, k, nOfParams, nOfIntParams;
+ Param *p;
+
+ /* Count the number of param values and subvalues */
+ nOfParams = 0;
+ nOfIntParams = 0;
+ for (k=0; k<numParams; k++)
+ {
+ nOfParams += params[k].nValues;
+ nOfParams += params[k].nSubValues;
+ nOfIntParams += params[k].nIntValues;
+ }
+
+ /* Set row size and find total number of values */
+ paramValsRowSize = nOfParams;
+ intValsRowSize = nOfIntParams;
+ nOfParams *= (2 * numGlobalChains);
+ nOfIntParams *= (2 * numGlobalChains);
+
+ if (memAllocs[ALLOC_PARAMVALUES] == YES)
+ {
+ paramValues = (MrBFlt *) SafeRealloc ((void *) paramValues, nOfParams * sizeof (MrBFlt));
+ for (i=0; i<nOfParams; i++)
+ paramValues[i] = 0.0;
+ if (nOfIntParams > 0)
+ intValues = (int *) SafeRealloc ((void *) intValues, nOfIntParams * sizeof(int));
+ }
+ else
+ {
+ paramValues = (MrBFlt *) SafeCalloc (nOfParams, sizeof(MrBFlt));
+ if (nOfIntParams > 0)
+ intValues = (int *) SafeCalloc (nOfIntParams, sizeof(int));
+ else
+ intValues = NULL;
+ }
+ if (!paramValues || (nOfIntParams > 0 && !intValues))
+ {
+ MrBayesPrint ("%s Problem allocating paramValues\n", spacer);
+ if (paramValues)
+ free (paramValues);
+ if (intValues)
+ free (intValues);
+ return ERROR;
+ }
+ else
+ memAllocs[ALLOC_PARAMVALUES] = YES;
+
+ /* set pointers to values for chain 1 state 0 */
+ /* this scheme keeps the chain and state values together */
+ nOfParams = 0;
+ nOfIntParams = 0;
+ for (k=0; k<numParams; k++)
+ {
+ p = ¶ms[k];
+ if (p->nValues > 0)
+ p->values = paramValues + nOfParams;
+ else
+ p->values = NULL;
+ nOfParams += p->nValues;
+ if (p->nSubValues > 0)
+ p->subValues = paramValues + nOfParams;
+ else
+ p->subValues = NULL;
+ nOfParams += p->nSubValues;
+ if (p->nIntValues > 0)
+ p->intValues = intValues + nOfIntParams;
+ else
+ p->intValues = NULL;
+ nOfIntParams += p->nIntValues;
+ }
+
+ /* allocate space for cpp events */
+ for (k=0; k<numParams; k++)
+ {
+ p = ¶ms[k];
+ if (p->paramType == P_CPPEVENTS)
+ AllocateCppEvents(p);
+ }
+
+ return (NO_ERROR);
+}
+
+
+/*----------------------------------------------------------------------
+|
+| AllocateTreeParams: Allocate space for tree parameters
+|
+-----------------------------------------------------------------------*/
+int AllocateTreeParams (void)
+{
+ int i, j, k, n, nOfParams, nOfTrees, isRooted, numSubParamPtrs;
+ Param *p, *q;
+
+ /* Count the number of trees and dated trees */
+ /* based on branch length parameters */
+ /* One tree is needed for each brlen parameter.
+ A topology may apply to several trees; a topology parameter
+ contains pointers to all trees it applies to */
+ numTrees = 0;
+ numTopologies = 0;
+ for (k=0; k<numParams; k++)
+ {
+ if (params[k].paramType == P_BRLENS)
+ numTrees++;
+ else if (params[k].paramType == P_TOPOLOGY)
+ numTopologies++;
+ }
+
+ /* We need to add the trees that do not have any branch lengths */
+ /* that is, the pure parsimony model trees, and the species trees */
+ for (k=0; k<numParams; k++)
+ {
+ if (params[k].paramType == P_TOPOLOGY)
+ {
+ if (!strcmp(modelParams[params[k].relParts[0]].parsModel, "Yes"))
+ numTrees++;
+ }
+ else if (params[k].paramType == P_SPECIESTREE)
+ {
+ numTopologies++;
+ numTrees++;
+ }
+ }
+
+ /* Finally add subparam pointers for relaxed clock parameters and species trees */
+ numSubParamPtrs = 0;
+ for (k=0; k<numParams; k++)
+ {
+ if (params[k].paramType == P_TOPOLOGY && params[k].paramId == TOPOLOGY_SPECIESTREE)
+ numSubParamPtrs += 1;
+ else if (params[k].paramType == P_BRLENS)
+ numSubParamPtrs += 1;
+ else if (params[k].paramType == P_CPPEVENTS)
+ numSubParamPtrs += 3;
+ else if (params[k].paramType == P_TK02BRANCHRATES)
+ numSubParamPtrs += 2;
+ else if (params[k].paramType == P_IGRBRANCHRATES)
+ numSubParamPtrs += 2;
+ else if (params[k].paramType == P_MIXEDBRCHRATES)
+ numSubParamPtrs += 2;
+ }
+
+ /* Allocate space for trees and subparam pointers */
+ if (memAllocs[ALLOC_MCMCTREES] == YES)
+ {
+ free (subParamPtrs);
+ free (mcmcTree);
+ subParamPtrs = NULL;
+ mcmcTree = NULL;
+ memAllocs[ALLOC_MCMCTREES] = NO;
+ }
+ subParamPtrs = (Param **) SafeCalloc (numSubParamPtrs, sizeof (Param *));
+ mcmcTree = (Tree **) SafeCalloc (numTrees * 2 * numGlobalChains, sizeof (Tree *));
+ if (!subParamPtrs || !mcmcTree)
+ {
+ if (subParamPtrs) free (subParamPtrs);
+ if (mcmcTree) free (mcmcTree);
+ subParamPtrs = NULL;
+ mcmcTree = NULL;
+ MrBayesPrint ("%s Problem allocating mcmc trees\n", spacer);
+ return (ERROR);
+ }
+ else
+ memAllocs[ALLOC_MCMCTREES] = YES;
+
+ /* Initialize number of subparams, just in case */
+ for (k=0; k<numParams; k++)
+ params[k].nSubParams = 0;
+
+ /* Count number of trees (brlens) for each topology or species tree */
+ for (k=0; k<numParams; k++)
+ {
+ p = ¶ms[k];
+ if (params[k].paramType == P_BRLENS)
+ {
+ q = modelSettings[p->relParts[0]].topology;
+ q->nSubParams++;
+ if (p->printParam == YES)
+ q->nPrintSubParams++;
+ }
+ else if (params[k].paramType == P_TOPOLOGY)
+ {
+ q = modelSettings[p->relParts[0]].speciesTree;
+ if (q != NULL)
+ q->nSubParams++;
+ }
+ }
+
+ /* Make sure there is also one subparam for a parsimony tree */
+ for (k=0; k<numParams; k++)
+ if (params[k].paramType == P_TOPOLOGY)
+ {
+ p = ¶ms[k];
+ if (p->nSubParams == 0)
+ p->nSubParams = 1;
+ }
+
+ /* Count subparams for relaxed clock parameters */
+ for (k=0; k<numParams; k++)
+ {
+ p = ¶ms[k];
+ if (p->paramType == P_CPPEVENTS)
+ {
+ q = modelSettings[p->relParts[0]].cppRate;
+ q->nSubParams++;
+ q = modelSettings[p->relParts[0]].cppMultDev;
+ q->nSubParams++;
+ q = modelSettings[p->relParts[0]].brlens;
+ q->nSubParams++;
+ }
+ else if (p->paramType == P_TK02BRANCHRATES)
+ {
+ q = modelSettings[p->relParts[0]].tk02var;
+ q->nSubParams++;
+ q = modelSettings[p->relParts[0]].brlens;
+ q->nSubParams++;
+ }
+ else if (p->paramType == P_IGRBRANCHRATES)
+ {
+ q = modelSettings[p->relParts[0]].igrvar;
+ q->nSubParams++;
+ q = modelSettings[p->relParts[0]].brlens;
+ q->nSubParams++;
+ }
+ else if (p->paramType == P_MIXEDBRCHRATES)
+ {
+ q = modelSettings[p->relParts[0]].mixedvar;
+ q->nSubParams++;
+ q = modelSettings[p->relParts[0]].brlens;
+ q->nSubParams++;
+ }
+ }
+
+ /* set pointers to subparams */
+ nOfParams = 0;
+ for (k=0; k<numParams; k++)
+ {
+ p = ¶ms[k];
+ if (p->nSubParams > 0)
+ {
+ p->subParams = subParamPtrs + nOfParams;
+ nOfParams += p->nSubParams;
+ }
+ }
+ assert (nOfParams == numSubParamPtrs);
+
+ /* Set brlens param pointers and tree values */
+ /* the scheme below keeps trees for the same state and chain together */
+ nOfTrees = 0;
+ for (k=0; k<numParams; k++)
+ {
+ p = ¶ms[k];
+ if ((p->paramType == P_BRLENS) ||
+ (p->paramType == P_TOPOLOGY && p->paramId == TOPOLOGY_PARSIMONY_UNIFORM) ||
+ (p->paramType == P_TOPOLOGY && p->paramId == TOPOLOGY_PARSIMONY_CONSTRAINED) ||
+ (p->paramType == P_SPECIESTREE))
+ {
+ /* allocate space for trees and initialize trees */
+ p->treeIndex = nOfTrees;
+ p->tree = mcmcTree + nOfTrees;
+ nOfTrees++;
+ }
+ }
+
+ /* Set topology params and associated brlen subparams */
+ for (k=0; k<numParams; k++)
+ {
+ p = ¶ms[k];
+ if (p->paramType == P_TOPOLOGY)
+ {
+ if (p->paramId == TOPOLOGY_PARSIMONY_UNIFORM ||
+ p->paramId == TOPOLOGY_PARSIMONY_CONSTRAINED)
+ /* pure parsimony topology case */
+ {
+ /* there is no brlen subparam */
+ /* so let subparam point to the param itself */
+ q = p->subParams[0] = p;
+ /* p->tree and p->treeIndex have been set above */
+ }
+ else
+ {
+ /* first set brlens pointers for any parsimony partitions */
+ for (i=j=0; i<p->nRelParts; i++)
+ {
+ if (modelSettings[p->relParts[i]].parsModelId == YES)
+ {
+ modelSettings[p->relParts[i]].brlens = p;
+ }
+ }
+
+ /* now proceed with pointer assignment */
+ q = modelSettings[p->relParts[0]].brlens;
+ n = 0; /* number of stored subParams */
+ i = 0; /* relevant partition number */
+ while (i < p->nRelParts)
+ {
+ for (j=0; j<n; j++)
+ if (q == p->subParams[j])
+ break;
+
+ if (j == n && q != p) /* a new tree (brlens) for this topology */
+ {
+ p->subParams[n++] = q;
+ }
+ q = modelSettings[p->relParts[++i]].brlens;
+ }
+
+ p->tree = p->subParams[0]->tree;
+ p->treeIndex = p->subParams[0]->treeIndex;
+ }
+ }
+ else if (p->paramType == P_SPECIESTREE)
+ {
+ /* now proceed with pointer assignment */
+ q = modelSettings[p->relParts[0]].topology;
+ n = 0; /* number of stored subParams */
+ i = 0; /* relevant partition number */
+ while (i < p->nRelParts)
+ {
+ for (j=0; j<n; j++)
+ if (q == p->subParams[j])
+ break;
+
+ if (j == n && q != p) /* a new topology for this species tree */
+ {
+ p->subParams[n++] = q;
+ }
+ q = modelSettings[p->relParts[++i]].topology;
+ }
+ }
+ }
+
+ /* Check for constraints */
+ for (k=0; k<numParams; k++)
+ {
+ p = ¶ms[k];
+ if (p->paramType == P_TOPOLOGY)
+ {
+ if (!strcmp(modelParams[p->relParts[0]].topologyPr, "Constraints"))
+ {
+ for (i=0; i<p->nSubParams; i++)
+ {
+ q = p->subParams[i];
+ q->checkConstraints = YES;
+ }
+ }
+ else
+ {
+ for (i=0; i<p->nSubParams; i++)
+ {
+ q = p->subParams[i];
+ q->checkConstraints = NO;
+ }
+ }
+ }
+ }
+
+ /* update paramId */
+ for (k=0; k<numParams; k++)
+ {
+ p = ¶ms[k];
+ if (p->paramType == P_TOPOLOGY)
+ {
+ if (p->nSubParams > 1)
+ {
+ if (p->paramId == TOPOLOGY_NCL_UNIFORM_HOMO)
+ p->paramId = TOPOLOGY_NCL_UNIFORM_HETERO;
+ else if (p->paramId == TOPOLOGY_NCL_CONSTRAINED_HOMO)
+ p->paramId = TOPOLOGY_NCL_CONSTRAINED_HETERO;
+ else if (p->paramId == TOPOLOGY_NCL_FIXED_HOMO)
+ p->paramId = TOPOLOGY_NCL_FIXED_HETERO;
+ else
+ {
+ MrBayesPrint ("%s A clock tree cannot have more than one set of branch lengths\n", spacer);
+ printf ("nparam:%d paramid:%d",p->nSubParams,p->paramId);
+ return (ERROR);
+ }
+ }
+ }
+ }
+
+ /* finally initialize trees */
+ for (k=0; k<numParams; k++)
+ {
+ p = ¶ms[k];
+ if (p->paramType == P_BRLENS)
+ {
+ /* find type of tree */
+ if (!strcmp(modelParams[p->relParts[0]].brlensPr,"Clock"))
+ isRooted = YES;
+ else
+ isRooted = NO;
+
+ if (InitializeChainTrees (p, 0, numGlobalChains, isRooted) == ERROR)
+ return (ERROR);
+ }
+ else if (p->paramType == P_SPECIESTREE)
+ {
+ if (InitializeChainTrees (p, 0, numGlobalChains, YES) == ERROR)
+ return (ERROR);
+ }
+ }
+
+ /* now initialize subparam pointers for relaxed clock models */
+ /* use nSubParams to point to the next available subParam by first
+ resetting all nSubParams to 0 */
+ for (k=0; k<numParams; k++)
+ {
+ p = ¶ms[k];
+ if (p->paramType == P_CPPRATE ||
+ p->paramType == P_CPPMULTDEV ||
+ p->paramType == P_BRLENS ||
+ p->paramType == P_TK02VAR ||
+ p->paramType == P_IGRVAR ||
+ p->paramType == P_MIXEDVAR)
+ p->nSubParams = 0;
+ }
+ for (k=0; k<numParams; k++)
+ {
+ p = ¶ms[k];
+ if (p->paramType == P_CPPEVENTS)
+ {
+ q = modelSettings[p->relParts[0]].cppRate;
+ q->subParams[q->nSubParams++] = p;
+ q = modelSettings[p->relParts[0]].cppMultDev;
+ q->subParams[q->nSubParams++] = p;
+ q = modelSettings[p->relParts[0]].brlens;
+ q->subParams[q->nSubParams++] = p;
+ p->treeIndex = q->treeIndex;
+ p->tree = q->tree;
+ if (p->printParam == YES)
+ q->nPrintSubParams++;
+ }
+ else if (p->paramType == P_TK02BRANCHRATES)
+ {
+ q = modelSettings[p->relParts[0]].tk02var;
+ q->subParams[q->nSubParams++] = p;
+ q = modelSettings[p->relParts[0]].brlens;
+ q->subParams[q->nSubParams++] = p;
+ p->treeIndex = q->treeIndex;
+ p->tree = q->tree;
+ if (p->printParam == YES)
+ q->nPrintSubParams++;
+ }
+ else if (p->paramType == P_IGRBRANCHRATES)
+ {
+ q = modelSettings[p->relParts[0]].igrvar;
+ q->subParams[q->nSubParams++] = p;
+ q = modelSettings[p->relParts[0]].brlens;
+ q->subParams[q->nSubParams++] = p;
+ p->treeIndex = q->treeIndex;
+ p->tree = q->tree;
+ if (p->printParam == YES)
+ q->nPrintSubParams++;
+ }
+ else if (p->paramType == P_MIXEDBRCHRATES)
+ {
+ q = modelSettings[p->relParts[0]].mixedvar;
+ q->subParams[q->nSubParams++] = p;
+ q = modelSettings[p->relParts[0]].brlens;
+ q->subParams[q->nSubParams++] = p;
+ p->treeIndex = q->treeIndex;
+ p->tree = q->tree;
+ if (p->printParam == YES)
+ q->nPrintSubParams++;
+ }
+ }
+
+ return (NO_ERROR);
+}
+
+
+int AreDoublesEqual (MrBFlt x, MrBFlt y, MrBFlt tol)
+{
+ if ((x - y) < -tol || (x - y) > tol)
+ return (NO);
+ else
+ return (YES);
+}
+
+
+int ChangeNumChains (int from, int to)
+{
+ int i, i1, j, k, m, st, nRuns, fromIndex, toIndex, run, chn, *tempIntVals, nCppEventParams, *toEvents, *fromEvents;
+ MCMCMove **tempMoves, *fromMove, *toMove;
+ Tree **tempTrees;
+ MrBFlt *tempVals, **toRateMult, **toPosition, **fromRateMult, **fromPosition, *stdStateFreqsOld;
+ Param *p, *q, *cppEventParams = NULL;
+ Tree **oldMcmcTree, *tree;
+
+ if (from == to)
+ return (NO_ERROR);
+
+ /* set new number of chains */
+ chainParams.numChains = to;
+ nRuns = chainParams.numRuns;
+ numGlobalChains = chainParams.numRuns * chainParams.numChains;
+
+ /* Do the normal parameters */
+ /* first save old values */
+ tempVals = paramValues;
+ paramValues = NULL;
+ tempIntVals = intValues;
+ intValues = NULL;
+ memAllocs[ALLOC_PARAMS] = NO;
+ /* .. and old cpp events parameters */
+ nCppEventParams = 0;
+ for (i=0; i<numParams; i++)
+ {
+ p = ¶ms[i];
+ if (p->paramType == P_CPPEVENTS)
+ nCppEventParams++;
+ }
+ cppEventParams = (Param *) SafeCalloc (nCppEventParams, sizeof(Param));
+ for (i=0; i<nCppEventParams; i++)
+ {
+ cppEventParams[i].paramType = P_CPPEVENTS;
+ AllocateCppEvents (&cppEventParams[i]);
+ }
+ for (i=j=0; i<numParams; i++)
+ {
+ p = ¶ms[i];
+ if (p->paramType == P_CPPEVENTS)
+ {
+ cppEventParams[j].nEvents = p->nEvents;
+ p->nEvents = NULL;
+ cppEventParams[j].position = p->position;
+ p->position = NULL;
+ cppEventParams[j].rateMult = p->rateMult;
+ p->rateMult = NULL;
+ j++;
+ }
+ }
+ if (AllocateNormalParams () == ERROR)
+ return (ERROR);
+
+ /* then fill all params */
+ FillNormalParams (&globalSeed, 0, numGlobalChains);
+
+ /* finally overwrite with old values if present */
+ for (run=0; run<nRuns; run++)
+ {
+ for (chn=0; chn<from; chn++)
+ {
+ if (chn < to)
+ {
+ fromIndex = (run*from + chn)*2*paramValsRowSize;
+ toIndex = (run*to + chn)*2*paramValsRowSize;
+ for (i=0; i<2*paramValsRowSize; i++)
+ paramValues[toIndex++] = tempVals[fromIndex++];
+ fromIndex = (run*from + chn)*2*intValsRowSize;
+ toIndex = (run*to + chn)*2*intValsRowSize;
+ for (i=0; i<2*intValsRowSize; i++)
+ intValues[toIndex++] = tempIntVals[fromIndex++];
+ for (i=i1=0; i<numParams; i++)
+ {
+ p = ¶ms[i];
+ if (p->paramType == P_CPPEVENTS)
+ {
+ fromIndex = 2*(run*from + chn);
+ toIndex = 2*(run*to + chn);
+ fromEvents = cppEventParams[i1].nEvents[fromIndex];
+ toEvents = p->nEvents[toIndex];
+ fromPosition = cppEventParams[i1].position[fromIndex];
+ toPosition = p->position[toIndex];
+ fromRateMult = cppEventParams[i1].rateMult[fromIndex];
+ toRateMult = p->rateMult[toIndex];
+ for (j=0; j<2*numLocalTaxa; j++)
+ {
+ toEvents[j] = fromEvents[j];
+ toPosition[j] = (MrBFlt *) SafeRealloc ((void *)toPosition[j], toEvents[j]*sizeof(MrBFlt));
+ toRateMult[j] = (MrBFlt *) SafeRealloc ((void *)toRateMult[j], toEvents[j]*sizeof(MrBFlt));
+ for (k=0; k<toEvents[j]; k++)
+ {
+ toPosition[j][k] = fromPosition[j][k];
+ toRateMult[j][k] = fromRateMult[j][k];
+ }
+ }
+ i1++;
+ }
+ }
+ assert (nCppEventParams==i1);
+ }
+ }
+ }
+
+ /* and free up space */
+ free (tempVals);
+ if (intValsRowSize > 0)
+ free (tempIntVals);
+ for (i=0; i<nCppEventParams; i++)
+ {
+ numGlobalChains = chainParams.numRuns * from; /* Revert to the old value to clean old Cpp events in FreeCppEvents() */
+ FreeCppEvents(&cppEventParams[i]);
+ numGlobalChains = chainParams.numRuns * chainParams.numChains; /*Set to proper value again*/
+ }
+ if (nCppEventParams > 0)
+ free (cppEventParams);
+
+ /* then do the trees (they cannot be done before the parameters because otherwise FillTreeParams will overwrite
+ relaxed clock parameters that need to be saved) */
+
+ /* reallocate trees */
+ tempTrees = (Tree **) SafeCalloc (2*nRuns*from*numTrees, sizeof(Tree *));
+ for (i=0; i<2*nRuns*from*numTrees; i++)
+ tempTrees[i] = mcmcTree[i];
+ oldMcmcTree = mcmcTree;
+ mcmcTree = (Tree **) SafeRealloc ((void *)(mcmcTree), 2 * (size_t)numGlobalChains * (size_t)numTrees * sizeof(Tree*));
+ for (i=0; i<2*nRuns*to*numTrees; i++)
+ mcmcTree[i] = NULL;
+
+ /* move the old trees over */
+ for (run=0; run<nRuns; run++)
+ {
+ for (chn=0; chn<from; chn++)
+ {
+ if (chn >= to)
+ continue;
+ /*Here we move only one tree per chain/state?! Should not we move numTrees??*/
+ fromIndex = 2*(run*from + chn) * numTrees;
+ toIndex = 2*(run*to + chn) * numTrees;
+ for (k=0;k<2*numTrees;k++)
+ {
+ mcmcTree[toIndex+k] = tempTrees[fromIndex+k];
+ tempTrees[fromIndex+k] = NULL;
+ }
+ }
+ }
+
+ /* remove any remaining old trees */
+ for (i=0; i<2*nRuns*from*numTrees; i++)
+ if (tempTrees[i] != NULL)
+ FreeTree (tempTrees[i]);
+ free (tempTrees);
+
+ /* now fill in the tree parameters */
+ for (i=0; i<numParams; i++)
+ {
+ p = ¶ms[i];
+ if (p->paramType == P_TOPOLOGY)
+ {
+ p->tree += (mcmcTree - oldMcmcTree); /* calculate new address */
+ for (j=0; j<p->nSubParams; j++)
+ {
+ q = p->subParams[j];
+ assert (q->paramType==P_BRLENS);
+ q->tree += (mcmcTree - oldMcmcTree); /* calculate new address */
+ if (to > from)
+ for (run=0; run<nRuns; run++)
+ {
+ /*rename old trees because each run has more chains*/
+ for (m=0; m<from; m++)
+ {
+ for (st=0; st<2; st++)
+ {
+ tree = GetTree (q,run*to + m, st);
+ if (numTrees > 1)
+ sprintf (tree->name, "mcmc.tree%d_%d", p->treeIndex+1, run*to + m +1);
+ else /* if (numTrees == 1) */
+ sprintf (tree->name, "mcmc.tree_%d", run*to + m +1);
+ }
+ }
+ InitializeChainTrees (q, run*to + from, run*to + to , GetTree (q, 0, 0)->isRooted);
+ }
+ }
+ }
+ else if (p->paramType == P_CPPEVENTS || p->paramType == P_TK02BRANCHRATES || p->paramType == P_IGRBRANCHRATES || p->paramType == P_MIXEDBRCHRATES)
+ p->tree += (mcmcTree - oldMcmcTree);
+ else
+ assert (p->paramType==P_BRLENS || p->tree==NULL);
+ }
+
+
+ /* fill new tree parameters */
+ if (to > from)
+ {
+ for (run=0; run<nRuns; run++)
+ {
+ for (chn=from; chn<to; chn++)
+ {
+ toIndex = run*to + chn;
+ FillTreeParams (&globalSeed, toIndex, toIndex+1);
+ }
+ }
+ }
+
+ /* fix stationary frequencies for standard data */
+ if (stdStateFreqsRowSize > 0)
+ {
+ assert (memAllocs[ALLOC_STDSTATEFREQS] == YES);
+ stdStateFreqsOld=stdStateFreqs;
+ stdStateFreqs = (MrBFlt *) SafeMalloc (2 * (size_t)stdStateFreqsRowSize * (size_t)numGlobalChains * sizeof (MrBFlt));
+ if (!stdStateFreqs)
+ {
+ MrBayesPrint ("%s Problem reallocating stdStateFreqs\n", spacer);
+ return (ERROR);
+ }
+
+ /* set pointers */
+ for (k=0; k<numParams; k++)
+ {
+ p = ¶ms[k];
+ if (p->paramType != P_PI || modelParams[p->relParts[0]].dataType != STANDARD)
+ continue;
+ p->stdStateFreqs += stdStateFreqs-stdStateFreqsOld;
+ }
+
+ for (run=0; run<nRuns; run++)
+ {
+ /* copy old chains values*/
+ for (chn=0; chn<from; chn++)
+ {
+ if (chn >= to)
+ break;
+
+ fromIndex = 2*(run*from + chn)*stdStateFreqsRowSize;
+ toIndex = 2*(run*to + chn)*stdStateFreqsRowSize;
+ for (k=0;k<2*stdStateFreqsRowSize;k++)
+ {
+ stdStateFreqs[toIndex+k]=stdStateFreqsOld[fromIndex+k];
+ }
+ }
+ /* set new chains */
+ FillStdStateFreqs (run*to+from, run*to+to, &globalSeed);
+ }
+ free(stdStateFreqsOld);
+ }
+
+ /* Do the moves */
+ /* first allocate space and set up default moves */
+ tempMoves = moves;
+ moves = NULL;
+ memAllocs[ALLOC_MOVES] = NO;
+ SetMoves ();
+
+ /* then overwrite with old values if present */
+ for (i=0; i<numApplicableMoves; i++)
+ {
+ toMove = moves[i];
+ fromMove = tempMoves[i];
+ for (run=0; run<nRuns; run++)
+ {
+ for (chn=0; chn<from; chn++)
+ {
+ if (chn < to)
+ {
+ fromIndex = run*from + chn;
+ toIndex = run*to + chn;
+ toMove->relProposalProb[toIndex] = fromMove->relProposalProb[fromIndex];
+ for (j=0; j<toMove->moveType->numTuningParams; j++)
+ {
+ toMove->tuningParam[toIndex][j] = fromMove->tuningParam[fromIndex][j];
+ }
+ }
+ }
+ }
+ }
+
+ /* and free up space */
+ for (i=0; i<numApplicableMoves; i++)
+ FreeMove (tempMoves[i]);
+ free (tempMoves);
+
+ return (NO_ERROR);
+}
+
+
+int ChangeNumRuns (int from, int to)
+{
+ int i, i1, j, k, n, nChains;
+ Param *p, *q;
+ MoveType *mvt;
+ Tree **oldMcmcTree;
+ MrBFlt *oldParamValues;
+ MrBFlt *stdStateFreqsOld;
+ int *oldintValues;
+
+ if (from == to)
+ return (NO_ERROR);
+
+#if 0
+ for (i=0; i<numParams; i++)
+ {
+ p = ¶ms[i];
+ if (p->paramType == P_CPPEVENTS)
+ {
+ printf ("Trees before changing number of runs\n");
+ for (j=0; j<numGlobalChains; j++)
+ {
+ printf ("Event tree for chain %d\n", j+1);
+ for (k=0; k<2*numLocalTaxa; k++)
+ {
+ printf ("%d -- %d:", k, p->nEvents[2*j][k]);
+ for (i1=0; i1<p->nEvents[2*j][k]; i1++)
+ {
+ if (i1 == 0)
+ printf (" (%lf %lf,", p->position[2*j][k], p->rateMult[2*j][k]);
+ else if (i1 == p->nEvents[2*j][k]-1)
+ printf (" %lf %lf)", p->position[2*j][k], p->rateMult[2*j][k]);
+ else
+ printf (" %lf %lf,", p->position[2*j][k], p->rateMult[2*j][k]);
+ }
+ printf ("\n");
+ }
+ for (k=0; k<2*numLocalTaxa; k++)
+ {
+ printf ("%d -- %d:", k, p->nEvents[2*j][k]);
+ for (i1=0; i1<p->nEvents[2*j+1][k]; i1++)
+ {
+ if (i1 == 0)
+ printf (" (%lf %lf,", p->position[2*j+1][k], p->rateMult[2*j+1][k]);
+ else if (i1 == p->nEvents[2*j][k]-1)
+ printf (" %lf %lf)", p->position[2*j+1][k], p->rateMult[2*j+1][k]);
+ else
+ printf (" %lf %lf,", p->position[2*j+1][k], p->rateMult[2*j+1][k]);
+ }
+ printf ("\n");
+ }
+ }
+ }
+ }
+#endif
+
+ /* set new number of runs */
+ chainParams.numRuns = to;
+ nChains = chainParams.numChains;
+ numGlobalChains = chainParams.numRuns * chainParams.numChains;
+
+ /* do the trees, free tree's memory if we reduce number of trees. */
+ for (i=to*2*nChains*numTrees; i<from*2*nChains*numTrees; i++)
+ {
+ FreeTree (mcmcTree[i]);
+ }
+ oldMcmcTree = mcmcTree;
+ mcmcTree = (Tree **) SafeRealloc ((void *) mcmcTree, numTrees * 2 * numGlobalChains * sizeof (Tree *));
+ if (mcmcTree == NULL)
+ {
+ memAllocs[ALLOC_MCMCTREES] = NO;
+ MrBayesPrint ("%s Problem reallocating mcmcTree\n", spacer);
+ return (ERROR);
+ }
+
+ for (i=from*2*nChains*numTrees; i<to*2*nChains*numTrees; i++)
+ {
+ mcmcTree[i]=NULL;
+ }
+ /* then the cppevents parameters */
+ for (i1=0; i1<numParams; i1++)
+ {
+ p = ¶ms[i1];
+ if (p->paramType == P_CPPEVENTS)
+ {
+ p->nEvents = (int **) SafeRealloc ((void *)p->nEvents, 2*numGlobalChains*sizeof (int *));
+ p->nEvents[0] = (int *) SafeRealloc ((void *)p->nEvents[0], 2*numGlobalChains*(2*numLocalTaxa)*sizeof (int));
+ for (i=1; i<2*numGlobalChains; i++)
+ p->nEvents[i] = p->nEvents[i-1] + (2*numLocalTaxa);
+ if (from > to)
+ {
+ for (j=numGlobalChains; j<from*nChains; j++)
+ {
+ for (k=0; k<2*numLocalTaxa; k++)
+ {
+ free (p->position[2*j+0][k]);
+ p->position[2*j+0][k] = NULL;
+ free (p->rateMult[2*j+0][k]);
+ p->rateMult[2*j+0][k] = NULL;
+ }
+ }
+ }
+ p->position = (MrBFlt ***) SafeRealloc ((void *)p->position, 2*numGlobalChains*sizeof (MrBFlt **));
+ p->position[0] = (MrBFlt **) SafeRealloc ((void *)p->position[0], 2*numGlobalChains*(2*numLocalTaxa)*sizeof (MrBFlt *));
+ for (i=1; i<2*numGlobalChains; i++)
+ p->position[i] = p->position[i-1] + (2*numLocalTaxa);
+ p->rateMult = (MrBFlt ***) SafeRealloc ((void *)p->rateMult, 2*numGlobalChains*sizeof (MrBFlt **));
+ p->rateMult[0] = (MrBFlt **) SafeRealloc ((void *)p->rateMult[0], 2*numGlobalChains*(2*numLocalTaxa)*sizeof (MrBFlt *));
+ for (i=1; i<2*numGlobalChains; i++)
+ p->rateMult[i] = p->rateMult[i-1] + (2*numLocalTaxa);
+ if (to > from)
+ {
+ for (j=from*nChains; j<numGlobalChains; j++)
+ {
+ for (k=0; k<2*numLocalTaxa; k++)
+ {
+ p->nEvents[2*j+0][k] = 0;
+ p->position[2*j+0][k] = NULL;
+ p->rateMult[2*j+0][k] = NULL;
+ p->nEvents[2*j+1][k] = 0;
+ p->position[2*j+1][k] = NULL;
+ p->rateMult[2*j+1][k] = NULL;
+ }
+ }
+ }
+ }
+ }
+ /* and finally the normal parameters */
+ oldParamValues = paramValues;
+ paramValues = (MrBFlt *) SafeRealloc ((void *) paramValues, paramValsRowSize * 2 * numGlobalChains * sizeof (MrBFlt));
+ oldintValues = intValues;
+ intValues = (int *) SafeRealloc ((void *) intValues, intValsRowSize * 2 * numGlobalChains * sizeof (int));
+ if (paramValues == NULL)
+ {
+ memAllocs[ALLOC_PARAMVALUES] = NO;
+ MrBayesPrint ("%s Problem reallocating paramValues\n", spacer);
+ return (ERROR);
+ }
+ for (i=0; i<numParams; i++)
+ {
+ params[i].values += (paramValues - oldParamValues);
+ params[i].subValues += (paramValues - oldParamValues);
+ params[i].intValues += (intValues - oldintValues);
+ }
+
+ /* fill new chains paramiters with appropriate values */
+ if (to > from)
+ FillNormalParams (&globalSeed, from*nChains, to*nChains);
+
+ /* now fill in the tree parameters */
+ for (i=0; i<numParams; i++)
+ {
+ p = ¶ms[i];
+ if (p->paramType == P_TOPOLOGY)
+ {
+ p->tree += (mcmcTree - oldMcmcTree); /* calculate new address */
+ for (j=0; j<p->nSubParams; j++)
+ {
+ q = p->subParams[j];
+ assert (q->paramType==P_BRLENS);
+ q->tree += (mcmcTree - oldMcmcTree); /* calculate new address */
+ InitializeChainTrees (q, from*nChains, to*nChains, GetTree (q, 0, 0)->isRooted);
+ }
+ }
+ else if (p->paramType == P_CPPEVENTS || p->paramType == P_TK02BRANCHRATES || p->paramType == P_IGRBRANCHRATES || p->paramType == P_MIXEDBRCHRATES)
+ p->tree += (mcmcTree - oldMcmcTree);
+ }
+
+ FillTreeParams (&globalSeed, from*nChains, to*nChains);
+
+ /* fix stationary frequencies for standard data */
+ if (stdStateFreqsRowSize > 0)
+ {
+ assert (memAllocs[ALLOC_STDSTATEFREQS] == YES);
+ stdStateFreqsOld=stdStateFreqs;
+ stdStateFreqs = (MrBFlt *) SafeRealloc ((void *) stdStateFreqs, stdStateFreqsRowSize * 2 * numGlobalChains * sizeof (MrBFlt));
+ if (!stdStateFreqs)
+ {
+ MrBayesPrint ("%s Problem reallocating stdStateFreqs\n", spacer);
+ return (ERROR);
+ }
+
+ /* set pointers */
+ for (k=n=0; k<numParams; k++)
+ {
+ p = ¶ms[k];
+ if (p->paramType != P_PI || modelParams[p->relParts[0]].dataType != STANDARD)
+ continue;
+ p->stdStateFreqs += stdStateFreqs-stdStateFreqsOld;
+ }
+
+ FillStdStateFreqs (from*nChains, to*nChains, &globalSeed);
+ }
+
+ /* do the moves */
+ for (i=0; i<numApplicableMoves; i++)
+ {
+ mvt = moves[i]->moveType;
+ moves[i]->tuningParam = (MrBFlt **) SafeRealloc ((void *) moves[i]->tuningParam, (size_t)numGlobalChains * sizeof (MrBFlt *));
+ moves[i]->tuningParam[0] = (MrBFlt *) SafeRealloc ((void *) moves[i]->tuningParam[0], (size_t)numGlobalChains * (size_t)(mvt->numTuningParams) * sizeof (MrBFlt));
+ for (j=1; j<numGlobalChains; j++)
+ moves[i]->tuningParam[j] = moves[i]->tuningParam[0] + j * mvt->numTuningParams;
+ moves[i]->relProposalProb = (MrBFlt *) SafeRealloc ((void *) moves[i]->relProposalProb, 4 * (size_t)numGlobalChains * sizeof (MrBFlt));
+ moves[i]->cumProposalProb = moves[i]->relProposalProb + numGlobalChains;
+ moves[i]->targetRate = moves[i]->relProposalProb + 2*numGlobalChains;
+ moves[i]->lastAcceptanceRate = moves[i]->relProposalProb + 3*numGlobalChains;
+ moves[i]->nAccepted = (int *) SafeRealloc ((void *) moves[i]->nAccepted, 5* (size_t)numGlobalChains * sizeof (int));
+ moves[i]->nTried = moves[i]->nAccepted + numGlobalChains;
+ moves[i]->nBatches = moves[i]->nAccepted + 2*numGlobalChains;
+ moves[i]->nTotAccepted = moves[i]->nAccepted + 3*numGlobalChains;
+ moves[i]->nTotTried = moves[i]->nAccepted + 4*numGlobalChains;
+ /* initialize all values to default */
+ for (j=0; j<numGlobalChains; j++)
+ {
+ moves[i]->nAccepted[j] = 0;
+ moves[i]->nTried[j] = 0;
+ moves[i]->nBatches[j] = 0;
+ moves[i]->nTotAccepted[j] = 0;
+ moves[i]->nTotTried[j] = 0;
+ moves[i]->relProposalProb[j] = mvt->relProposalProb;
+ moves[i]->cumProposalProb[j] = 0.0;
+ moves[i]->lastAcceptanceRate[j] = 0.0;
+ for (k=0; k<mvt->numTuningParams; k++)
+ moves[i]->tuningParam[j][k] = mvt->tuningParam[k];
+ moves[i]->targetRate[j] = mvt->targetRate;
+ }
+ }
+
+#if 0
+ for (i=0; i<numParams; i++)
+ {
+ p = ¶ms[i];
+ if (p->paramType == P_CPPEVENTS)
+ {
+ printf ("Trees after changing number of runs\n");
+ for (j=0; j<numGlobalChains; j++)
+ {
+ printf ("Event tree for chain %d\n", j+1);
+ for (k=0; k<2*numLocalTaxa; k++)
+ {
+ printf ("%d -- %d:", k, p->nEvents[2*j][k]);
+ assert (p->nEvents[2*j] >= 0);
+ for (i1=0; i1<p->nEvents[2*j][k]; i1++)
+ {
+ if (i1 == 0)
+ printf (" (%lf %lf,", p->position[2*j][k], p->rateMult[2*j][k]);
+ else if (i1 == p->nEvents[2*j][k]-1)
+ printf (" %lf %lf)", p->position[2*j][k], p->rateMult[2*j][k]);
+ else
+ printf (" %lf %lf,", p->position[2*j][k], p->rateMult[2*j][k]);
+ }
+ printf ("\n");
+ }
+ for (k=0; k<2*numLocalTaxa; k++)
+ {
+ printf ("%d -- %d:", k, p->nEvents[2*j+1][k]);
+ assert (p->nEvents[2*j+1] >= 0);
+ for (i1=0; i1<p->nEvents[2*j+1][k]; i1++)
+ {
+ if (i1 == 0)
+ printf (" (%lf %lf,", p->position[2*j+1][k], p->rateMult[2*j+1][k]);
+ else if (i1 == p->nEvents[2*j][k]-1)
+ printf (" %lf %lf)", p->position[2*j+1][k], p->rateMult[2*j+1][k]);
+ else
+ printf (" %lf %lf,", p->position[2*j+1][k], p->rateMult[2*j+1][k]);
+ }
+ printf ("\n");
+ }
+ }
+ }
+ }
+#endif
+
+ return (NO_ERROR);
+}
+
+
+/*-----------------------------------------------------------
+|
+| CheckCharCodingType: check if character is parsimony-
+| informative, variable, or constant
+|
+-----------------------------------------------------------*/
+void CheckCharCodingType (Matrix *m, CharInfo *ci)
+{
+ int i, j, k, x, n1[10], n2[10], largest, smallest, numPartAmbig,
+ numConsidered, numInformative, lastInformative=0, uniqueBits,
+ newPoss, oldPoss;
+ BitsLong combinations[2048], *tempComb, *newComb, *oldComb, bitsLongOne=1;
+
+ /* set up comb pointers */
+ oldComb = combinations;
+ newComb = oldComb + 1024;
+
+ /* set counters to 0 */
+ numPartAmbig = numConsidered = 0;
+
+ /* set variable and informative to yes */
+ ci->variable = ci->informative = YES;
+
+ /* set constant to no and state counters to 0 for all states */
+ for (i=0; i<10; i++)
+ {
+ ci->constant[i] = ci->singleton[i] = NO;
+ n1[i] = n2[i] = 0;
+ }
+
+ for (i=0; i<m->nRows; i++)
+ {
+ /* retrieve character */
+ x = (int) m->origin[m->column + i*m->rowSize];
+
+ /* add it to counters if not all ambiguous */
+ if (NBits(x) < ci->nStates)
+ {
+ numConsidered++;
+ if (NBits(x) > 1)
+ numPartAmbig++;
+ for (j=0; j<10; j++)
+ {
+ if (((bitsLongOne<<j) & x) != 0)
+ {
+ n1[j]++;
+ if (NBits(x) == 1)
+ n2[j]++;
+ }
+ }
+ }
+ }
+
+ /* if the ambig counter for any state is equal to the number of considered
+ states, then set constant for that state and set variable and informative to no */
+ for (i=0; i<10; i++)
+ {
+ if (n1[i] == numConsidered)
+ {
+ ci->constant[i] = YES;
+ ci->variable = ci->informative = NO;
+ }
+ else if (n1[i] == 1)
+ {
+ ci->singleton[i] = YES;
+ }
+ }
+
+ /* return if variable is no */
+ if (ci->variable == NO)
+ return;
+
+ /* the character is either (variable and uninformative) or informative */
+
+ /* first consider unambiguous characters */
+ /* find smallest and largest unambiguous state for this character */
+ smallest = 9;
+ largest = 0;
+ for (i=0; i<10; i++)
+ {
+ if (n2[i] > 0)
+ {
+ if (i < smallest)
+ smallest = i;
+ if (i > largest)
+ largest = i;
+ }
+ }
+
+ /* count the number of informative states in the unambiguous codings */
+ for (i=numInformative=0; i<10; i++)
+ {
+ if (ci->cType == ORD && n2[i] > 0 && i != smallest && i != largest)
+ {
+ numInformative++;
+ lastInformative = i;
+ }
+ else if (n2[i] > 1)
+ {
+ numInformative++;
+ lastInformative = i;
+ }
+ }
+
+ /* set informative */
+ if (numInformative > 1)
+ ci->informative = YES;
+ else
+ ci->informative = NO;
+
+
+ /* we can return now unless informative is no and numPartAmbig is not 0 */
+ if (!(numPartAmbig > 0 && ci->informative == NO))
+ return;
+
+ /* check if partially ambiguous observations make this character informative
+ after all */
+
+ /* first set the bits for the taken states */
+ x = 0;
+ for (i=0; i<10; i++)
+ {
+ if (n2[i] > 0 && i != lastInformative)
+ x |= (bitsLongOne<<i);
+ }
+ oldPoss = 1;
+ oldComb[0] = x;
+
+ /* now go through all partambig chars and see if we can add them without
+ making the character informative */
+ for (i=0; i<m->nRows; i++)
+ {
+ x = (int) m->origin[m->column + i*m->rowSize];
+ /* if partambig */
+ if (NBits(x) > 1 && NBits(x) < ci->nStates)
+ {
+ /* remove lastInformative */
+ x &= !(bitsLongOne<<lastInformative);
+ /* reset newPoss */
+ newPoss = 0;
+ /* see if we can add it, store all possible combinations */
+ for (j=0; j<oldPoss; j++)
+ {
+ uniqueBits = x & (!oldComb[j]);
+ for (k=0; k<10; k++)
+ {
+ if (((bitsLongOne<<k) & uniqueBits) != 0)
+ newComb[newPoss++] = oldComb[j] | (bitsLongOne<<k);
+ }
+ }
+ /* break out if we could not add it */
+ if (newPoss == 0)
+ break;
+
+ /* prepare for next partAmbig */
+ oldPoss = newPoss;
+ tempComb = oldComb;
+ oldComb = newComb;
+ newComb = tempComb;
+ }
+ }
+
+ if (i < m->nRows)
+ ci->informative = YES;
+
+ return;
+}
+
+
+/*-----------------------------------------------------------
+|
+| CheckModel: check model and warn user if strange things
+| are discovered.
+|
+-------------------------------------------------------------*/
+int CheckModel (void)
+{
+ int i, j, k, answer;
+ Tree *t = NULL;
+ TreeNode *p;
+
+ /* there should only be one calibrated tree */
+ for (i=0; i<numTrees; i++)
+ {
+ t = GetTreeFromIndex(i,0,0);
+ if (t->isCalibrated == YES)
+ break;
+ }
+
+ if (i < numTrees)
+ {
+ if (!strcmp(modelParams[t->relParts[0]].clockRatePr, "Fixed") && AreDoublesEqual(modelParams[t->relParts[0]].clockRateFix, 1.0, 1E-6) == YES)
+ {
+ MrBayesPrint("%s WARNING: You have calibrated the tree but the clock rate is fixed to 1.0.\n", spacer);
+ MrBayesPrint("%s This means that time is measured in expected changes per time unit. If\n", spacer);
+ MrBayesPrint("%s the calibrations use a different time scale, you need to modify the model\n", spacer);
+ MrBayesPrint("%s by introducing a prior for the clock rate ('prset clockratepr').\n", spacer);
+
+ if (noWarn == NO)
+ {
+ answer = WantTo("Do you want to continue with the run regardless");
+ if (answer == YES)
+ {
+ MrBayesPrint("%s Continuing with the run...\n\n", spacer);
+ }
+ else
+ {
+ MrBayesPrint("%s Stopping the run...\n\n", spacer);
+ return (ERROR);
+ }
+ }
+ }
+ }
+
+ /* check coalescence model */
+ for (i=0; i<numTrees; i++)
+ {
+ t = GetTreeFromIndex(i, 0, 0);
+ if ((!strcmp(modelParams[t->relParts[0]].clockPr,"Coalescence") || !strcmp(modelParams[t->relParts[0]].clockPr,"Speciestreecoalescence"))
+ && !strcmp(modelParams[t->relParts[0]].clockRatePr, "Fixed") && AreDoublesEqual(modelParams[t->relParts[0]].clockRateFix, 1.0, 1E-6) == YES)
+ {
+ MrBayesPrint("%s WARNING: You are using a coalescent model but the clock rate is fixed to 1.0.\n", spacer);
+ MrBayesPrint("%s This is likely to be incorrect unless you have set the population size prior\n", spacer);
+ MrBayesPrint("%s ('prset popsizepr') to reflect an appropriate prior on theta. \n", spacer);
+
+ if (noWarn == NO)
+ {
+ answer = WantTo("Do you want to continue with the run regardless");
+ if (answer == YES)
+ {
+ MrBayesPrint("%s Continuing with the run...\n\n", spacer);
+ }
+ else
+ {
+ MrBayesPrint("%s Stopping the run...\n\n", spacer);
+ return (ERROR);
+ }
+ }
+ }
+ }
+
+ /* Check consistency of best model. First we guarantee that if one topology has
+ a species tree prior, then all topologies have the same prior. Then we make
+ sure that all clock trees have a coalescence prior. */
+
+ j = 0;
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (!strcmp(modelParams[i].topologyPr, "Speciestree"))
+ j++;
+ }
+
+ if (j > 0)
+ {
+ if (j != numCurrentDivisions)
+ {
+ MrBayesPrint("%s ERROR: If one gene tree has a speciestree prior then all\n", spacer);
+ MrBayesPrint("%s gene trees must have the same prior.\n", spacer);
+ return (ERROR);
+ }
+ for (i=0; i<numTrees-1; i++)
+ {
+ t = GetTreeFromIndex(i,0,0);
+ if (strcmp(modelParams[t->relParts[0]].clockPr,"Speciestreecoalescence") != 0)
+ {
+ MrBayesPrint("%s ERROR: All gene trees must have a speciestreecoalescence prior\n", spacer);
+ MrBayesPrint("%s if they fold into a species tree.\n", spacer);
+ return (ERROR);
+ }
+ if (t->isCalibrated == YES)
+ {
+ for (k=0; k<t->nNodes-1; k++)
+ {
+ p = t->allDownPass[k];
+ if (p->calibration != NULL)
+ {
+ MrBayesPrint("%s ERROR: Gene trees cannot be individually calibrated\n", spacer);
+ MrBayesPrint("%s if they fold into a species tree.\n", spacer);
+ return (ERROR);
+ }
+ }
+ }
+ }
+ }
+
+ return NO_ERROR;
+}
+
+
+/*-----------------------------------------------------------
+|
+| CheckExpandedModels: check data partitions that have
+| the codon or doublet model specified
+|
+-------------------------------------------------------------*/
+int CheckExpandedModels (void)
+{
+ int c, d, i, t, s, s1, s2, s3, whichNuc, uniqueId, numCharsInPart,
+ firstChar, lastChar, contiguousPart, badBreak, badExclusion,
+ nGone, nuc1, nuc2, nuc3, foundStopCodon, posNucs1[4], posNucs2[4], posNucs3[4],
+ oneGoodCodon, foundUnpaired, nPair, allCheckedOut;
+ char *tempStr;
+ int tempStrSize=100;
+ ModelParams *mp;
+
+ tempStr = (char *) SafeMalloc((size_t)tempStrSize * sizeof(char));
+ if (!tempStr)
+ {
+ MrBayesPrint ("%s Problem allocating tempString (%d)\n", spacer, tempStrSize * sizeof(char));
+ return (ERROR);
+ }
+
+ /* first, set charId to 0 for all characters */
+ for (i=0; i<numChar; i++)
+ charInfo[i].charId = 0;
+
+ /* loop over partitions */
+ allCheckedOut = 0;
+ uniqueId = 1;
+ for (d=0; d<numCurrentDivisions; d++)
+ {
+ mp = &modelParams[d];
+
+ if (mp->dataType == DNA || mp->dataType == RNA)
+ {
+ if (!strcmp(mp->nucModel,"Codon") || !strcmp(mp->nucModel,"Protein"))
+ {
+ /* start check that the codon model is appropriate for this partition */
+
+ /* find first character in this partition */
+ for (c=0; c<numChar; c++)
+ {
+ if (partitionId[c][partitionNum] == d+1)
+ break;
+ }
+ firstChar = c;
+ /*printf (" first character = %d\n", firstChar);*/
+
+ /* find last character in this partition */
+ for (c=numChar-1; c>=0; c--)
+ {
+ if (partitionId[c][partitionNum] == d+1)
+ break;
+ }
+ lastChar = c;
+ /*printf (" last character = %d\n", lastChar);*/
+
+ /* check that the number of characters in partition is divisible by 3 */
+ numCharsInPart = 0;
+ for (c=firstChar; c<=lastChar; c++)
+ {
+ if (charInfo[c].isExcluded == YES || partitionId[c][partitionNum] != d+1)
+ continue;
+ numCharsInPart++;
+ }
+ /*printf (" numCharsInPart = %d\n", numCharsInPart);*/
+ if (numCharsInPart % 3 != 0)
+ {
+ if (numCurrentDivisions == 1)
+ {
+ MrBayesPrint ("%s The number of characters is not divisible by three.\n", spacer);
+ MrBayesPrint ("%s You specified a %s model which requires triplets\n", spacer, mp->nucModel);
+ MrBayesPrint ("%s However, you have %d characters.\n", spacer, numCharsInPart);
+ }
+ else
+ {
+ MrBayesPrint ("%s The number of characters in partition %d is not\n", spacer, d+1);
+ MrBayesPrint ("%s divisible by three. You specified a %s model\n", spacer, mp->nucModel);
+ MrBayesPrint ("%s which requires triplets. \n", spacer);
+ MrBayesPrint ("%s However, you have %d characters in this partition\n", spacer, numCharsInPart);
+ }
+ free (tempStr);
+ return (ERROR);
+ }
+
+ /* check that all of the characters in the partition are contiguous */
+ contiguousPart = YES;
+ for (c=firstChar; c<=lastChar; c++)
+ {
+ if (charInfo[c].isExcluded == NO && partitionId[c][partitionNum] != d+1)
+ contiguousPart = NO;
+ }
+ if (contiguousPart == NO)
+ {
+ MrBayesPrint ("%s Partition %d is not contiguous. You specified that\n", spacer, d+1);
+ MrBayesPrint ("%s a %s model be used for this partition. However, there\n", spacer, mp->nucModel);
+ MrBayesPrint ("%s is another partition that is between some of the characters\n", spacer);
+ MrBayesPrint ("%s in this partition. \n", spacer);
+ free (tempStr);
+ return (ERROR);
+ }
+
+ /* check that there is not a break inside a triplet of characters */
+ badBreak = NO;
+ whichNuc = 0;
+ for (c=firstChar; c<=lastChar; c++)
+ {
+ if (charInfo[c].isExcluded == NO)
+ continue;
+ whichNuc++;
+ if (charInfo[c].bigBreakAfter == YES && whichNuc != 3)
+ badBreak = YES;
+ if (whichNuc == 3)
+ whichNuc = 0;
+ }
+ if (badBreak == YES)
+ {
+ MrBayesPrint ("%s You specified a databreak inside of a coding triplet.\n", spacer);
+ MrBayesPrint ("%s This is a problem, as you imply that part of the codon\n", spacer);
+ MrBayesPrint ("%s lies in one gene and the remainder in another gene. \n", spacer);
+ free (tempStr);
+ return (ERROR);
+ }
+
+ /* make certain excluded characters are in triplets but allow frameshift exclusions first in sequence */
+ badExclusion = NO;
+ whichNuc = nGone = 0;
+ for (c=firstChar; c<=lastChar; c++)
+ if (charInfo[c].isExcluded == NO)
+ break;
+ for (; c<=lastChar; c++)
+ {
+ whichNuc++;
+ if (charInfo[c].isExcluded == YES)
+ nGone++;
+ if (whichNuc == 3)
+ {
+ if (nGone == 1 || nGone == 2)
+ badExclusion = YES;
+ whichNuc = nGone = 0;
+ }
+ }
+ if (badExclusion == YES)
+ {
+ MrBayesPrint ("%s In excluding characters, you failed to remove all of the\n", spacer);
+ MrBayesPrint ("%s sites of at least one codon. If you exclude sites, make \n", spacer);
+ MrBayesPrint ("%s certain to exclude all of the sites in the codon(s). \n", spacer);
+ free (tempStr);
+ return (ERROR);
+ }
+
+ /* check that there are no stop codons */
+ foundStopCodon = NO;
+ /* allow frameshifting exclusions in the beginning */
+ for (c=firstChar; c<=lastChar; c++)
+ if (charInfo[c].isExcluded == NO)
+ break;
+ for (; c<=lastChar; c+=3)
+ {
+ if (charInfo[c].isExcluded == NO)
+ {
+ for (t=0; t<numTaxa; t++)
+ {
+ if (taxaInfo[t].isDeleted == YES)
+ continue;
+ nuc1 = matrix[pos(t,c+0,numChar)];
+ nuc2 = matrix[pos(t,c+1,numChar)];
+ nuc3 = matrix[pos(t,c+2,numChar)];
+ /*nucX is in range 0-15 to represent any possible set of states that nucleatide could be in*/
+ GetPossibleNucs (nuc1, posNucs1);
+ GetPossibleNucs (nuc2, posNucs2);
+ GetPossibleNucs (nuc3, posNucs3);
+
+ oneGoodCodon = NO;
+ s = 0;
+ for (s1=0; s1<4; s1++)
+ {
+ for (s2=0; s2<4; s2++)
+ {
+ for (s3=0; s3<4; s3++)
+ {
+ if (posNucs1[s1] == 1 && posNucs2[s2] == 1 && posNucs3[s3] == 1)
+ {
+ if (mp->codon[s1*16 + s2*4 + s3] != 21)
+ oneGoodCodon = YES;
+ }
+ s++;
+ }
+ }
+ }
+ if (oneGoodCodon == NO)
+ {
+ foundStopCodon = YES;
+ MrBayesPrint ("%s Stop codon: taxon %s, sites %d to %d (%c%c%c, %s code)\n", spacer,
+ taxaNames[t], c+1, c+3, WhichNuc (nuc1), WhichNuc (nuc2), WhichNuc (nuc3), mp->geneticCode);
+ }
+ }
+ }
+ }
+ if (foundStopCodon == YES)
+ {
+ MrBayesPrint ("%s At least one stop codon was found. Stop codons are not\n", spacer);
+ MrBayesPrint ("%s allowed under the codon models. \n", spacer);
+ free (tempStr);
+ return (ERROR);
+ }
+
+ /* everything checks out. Now we can initialize charId */
+ whichNuc = 0;
+ for (c=firstChar; c<=lastChar; c++)
+ {
+ whichNuc++;
+ charInfo[c].charId = uniqueId;
+ if (whichNuc == 3)
+ {
+ whichNuc = 0;
+ uniqueId++;
+ }
+ }
+
+ allCheckedOut++;
+ /* end check that the codon model is appropriate for this partition */
+ }
+ else if (!strcmp(mp->nucModel,"Doublet"))
+ {
+ /* start check that the doublet model is appropriate for this partition */
+
+ /* Check that pairsId does not equal 0 for any of the characters in
+ the partition. If it does, then this means that at least one
+ site was not appropriately paired. Remember, that pairsId is
+ initialized 1, 2, 3, ... for the first pair, second pair, etc.
+ Also, check that every pair is only represented two times. */
+ foundUnpaired = NO;
+ for (c=0; c<numChar; c++)
+ {
+ if (partitionId[c][partitionNum] == d+1 && charInfo[c].pairsId == 0 && charInfo[c].isExcluded == NO)
+ foundUnpaired = YES;
+ }
+
+ for (c=0; c<numChar; c++)
+ {
+ if (partitionId[c][partitionNum] == d+1 && charInfo[c].isExcluded == NO)
+ {
+ nPair = 1;
+ for (i=0; i<numChar; i++)
+ {
+ if (i != c && partitionId[i][partitionNum] == d+1 && charInfo[i].isExcluded == NO && charInfo[c].pairsId == charInfo[i].pairsId)
+ nPair++;
+ }
+ if (nPair != 2)
+ foundUnpaired = YES;
+ }
+ }
+ if (foundUnpaired == YES)
+ {
+ if (numCurrentDivisions == 1)
+ {
+ MrBayesPrint ("%s Found unpaired nucleotide sites. The doublet model\n", spacer);
+ MrBayesPrint ("%s requires that all sites are paired. \n", spacer);
+ }
+ else
+ {
+ MrBayesPrint ("%s Found unpaired nucleotide sites in partition %d.\n", spacer, d+1);
+ MrBayesPrint ("%s The doublet model requires that all sites are paired. \n", spacer);
+ }
+ free (tempStr);
+ return (ERROR);
+ }
+
+ /* everything checks out. Now we can initialize charId */
+ for (c=0; c<numChar; c++)
+ {
+ nuc1 = nuc2 = -1;
+ if (partitionId[c][partitionNum] == d+1 && charInfo[c].charId == 0)
+ {
+ nuc1 = c;
+ for (i=0; i<numChar; i++)
+ {
+ if (i != c && charInfo[i].charId == 0 && charInfo[c].pairsId == charInfo[i].pairsId)
+ nuc2 = i;
+ }
+ if (nuc1 >= 0 && nuc2 >= 0)
+ {
+ charInfo[nuc1].charId = charInfo[nuc2].charId = uniqueId;
+ uniqueId++;
+ }
+ else
+ {
+ MrBayesPrint ("%s Weird doublet problem in partition %d.\n", spacer, d+1);
+ free (tempStr);
+ return (ERROR);
+ }
+ }
+ }
+
+ allCheckedOut++;
+ /* end check that the doublet model is appropriate for this partition */
+ }
+ }
+ }
+
+ /*
+ if (allCheckedOut > 0)
+ MrBayesPrint ("%s Codon/Doublet models successfully checked\n", spacer);
+ */
+
+# if 0
+ for (c=0; c<numChar; c++)
+ printf (" %d", charId[c]);
+ printf ("\n");
+# endif
+
+ free (tempStr);
+ return (NO_ERROR);
+}
+
+void CodingToString(int coding, char* string)
+{
+ if(coding == ALL)
+ strcpy(string, "All");
+ else if(coding == INFORMATIVE)
+ strcpy(string, "Informative");
+ else if((coding & VARIABLE) == VARIABLE)
+ {
+ if (coding == VARIABLE)
+ {
+ strcpy(string, "Variable");
+ }
+ else if (coding & NOSINGLETONABSENCE)
+ {
+ strcpy(string, "Variable|Nosingletonabsence");
+ }
+ else if (coding & NOSINGLETONPRESENCE)
+ {
+ strcpy(string, "Variable|Nosingletonpresence");
+ }
+ }
+ else if((coding & NOSINGLETONS) == NOSINGLETONS)
+ {
+ if (coding == NOSINGLETONS)
+ {
+ strcpy(string, "Nosingletons");
+ }
+ else if (coding & NOABSENCESITES)
+ {
+ strcpy(string, "Noabsencesites|Nosingletons");
+ }
+ else if (coding & NOPRESENCESITES)
+ {
+ strcpy(string, "Nopresencesites|Nosingletons");
+ }
+ }
+ else if(coding == NOABSENCESITES)
+ {
+ strcpy(string, "Noabsencesites");
+ }
+ else if(coding == NOPRESENCESITES)
+ {
+ strcpy(string, "Nopresencesites");
+ }
+ else if(coding == NOSINGLETONABSENCE)
+ {
+ strcpy(string, "Nosingletonabsence");
+ }
+ else if(coding == NOSINGLETONPRESENCE)
+ {
+ strcpy(string, "Nosingletonpresence");
+ }
+ else if(coding == (NOABSENCESITES | NOSINGLETONABSENCE))
+ {
+ strcpy(string, "Noabsencesites|Nosingletonabsence");
+ }
+ else if(coding == (NOABSENCESITES | NOSINGLETONPRESENCE))
+ {
+ strcpy(string, "Noabsencesites|Nosingletonpresence");
+ }
+ else if(coding == (NOPRESENCESITES | NOSINGLETONABSENCE))
+ {
+ strcpy(string, "Nopresencesites|Nosingletonabsence");
+ }
+ else if(coding == (NOPRESENCESITES | NOSINGLETONPRESENCE))
+ {
+ strcpy(string, "Nopresencesites|Nosingletonpresence");
+ }
+}
+
+
+/*-----------------------------------------------------------
+|
+| CompressData: compress original data matrix
+|
+-------------------------------------------------------------*/
+int CompressData (void)
+{
+ int a, c, d, i, j, k, t, col[3], isSame, newRow, newColumn,
+ *isTaken, *tempSitesOfPat, *tempChar;
+ BitsLong *tempMatrix;
+ ModelInfo *m;
+ ModelParams *mp;
+
+# if defined DEBUG_COMPRESSDATA
+ if (PrintMatrix() == ERROR)
+ goto errorExit;
+ getchar();
+# endif
+
+ /* set all pointers that will be allocated locally to NULL */
+ isTaken = NULL;
+ tempMatrix = NULL;
+ tempSitesOfPat = NULL;
+ tempChar = NULL;
+
+ /* allocate indices pointing from original to compressed matrix */
+ if (memAllocs[ALLOC_COMPCOLPOS] == YES)
+ {
+ free (compColPos);
+ compColPos = NULL;
+ memAllocs[ALLOC_COMPCOLPOS] = NO;
+ }
+ compColPos = (int *)SafeMalloc((size_t)numChar * sizeof(int));
+ if (!compColPos)
+ {
+ MrBayesPrint ("%s Problem allocating compColPos (%d)\n", spacer, numChar * sizeof(int));
+ goto errorExit;
+ }
+ for (i=0; i<numChar; i++)
+ compColPos[i] = 0;
+ memAllocs[ALLOC_COMPCOLPOS] = YES;
+
+ if (memAllocs[ALLOC_COMPCHARPOS] == YES)
+ {
+ free (compCharPos);
+ compCharPos = NULL;
+ memAllocs[ALLOC_COMPCHARPOS] = NO;
+ }
+ compCharPos = (int *)SafeMalloc((size_t)numChar * sizeof(int));
+ if (!compCharPos)
+ {
+ MrBayesPrint ("%s Problem allocating compCharPos (%d)\n", spacer, numChar * sizeof(int));
+ goto errorExit;
+ }
+ for (i=0; i<numChar; i++)
+ compCharPos[i] = 0;
+ memAllocs[ALLOC_COMPCHARPOS] = YES;
+
+ /* allocate space for temporary matrix, tempSitesOfPat, */
+ /* vector keeping track of whether a character has been compressed, */
+ /* and vector indexing first original char for each compressed char */
+ tempMatrix = (BitsLong *) SafeCalloc (numLocalTaxa * numLocalChar, sizeof(BitsLong));
+ tempSitesOfPat = (int *) SafeCalloc (numLocalChar, sizeof(int));
+ isTaken = (int *) SafeCalloc (numChar, sizeof(int));
+ tempChar = (int *) SafeCalloc (numLocalChar, sizeof(int));
+ if (!tempMatrix || !tempSitesOfPat || !isTaken || !tempChar)
+ {
+ MrBayesPrint ("%s Problem allocating temporary variables in CompressData\n", spacer);
+ goto errorExit;
+ }
+
+ /* initialize isTaken */
+ for (c=0; c<numChar; c++)
+ isTaken[c] = NO;
+
+ /* set index to first empty column in temporary matrix */
+ newColumn = 0;
+
+ /* initialize number of compressed characters */
+ numCompressedChars = 0;
+
+ /* sort and compress data */
+ for (d=0; d<numCurrentDivisions; d++)
+ {
+ /* set pointers to the model params and settings for this division */
+ m = &modelSettings[d];
+ mp = &modelParams[d];
+
+ /* set column offset for this division in compressed matrix */
+ m->compMatrixStart = newColumn;
+
+ /* set compressed character offset for this division */
+ m->compCharStart = numCompressedChars;
+
+ /* set number of compressed characters to 0 for this division */
+ m->numChars = 0;
+
+ /* find the number of original characters per model site */
+ m->nCharsPerSite = 1;
+ if (mp->dataType == DNA || mp->dataType == RNA)
+ {
+ if (!strcmp(mp->nucModel, "Doublet"))
+ m->nCharsPerSite = 2;
+ if (!strcmp(mp->nucModel, "Codon") || !strcmp(mp->nucModel, "Protein"))
+ m->nCharsPerSite = 3;
+ }
+
+ /* sort and compress the characters for this division */
+ for (c=0; c<numChar; c++)
+ {
+ if (charInfo[c].isExcluded == YES || partitionId[c][partitionNum] != d+1 || isTaken[c] == YES)
+ continue;
+
+ col[0] = c;
+ isTaken[c] = YES;
+
+ /* find additional columns if more than one character per model site */
+ /* return error if the number of matching characters is smaller or larger */
+ /* than the actual number of characters per model site */
+ if (m->nCharsPerSite > 1)
+ {
+ j = 1;
+ if (charInfo[c].charId == 0)
+ {
+ MrBayesPrint("%s Character %d is not properly defined\n", spacer, c+1);
+ goto errorExit;
+ }
+ for (i=c+1; i<numChar; i++)
+ {
+ if (charInfo[i].charId == charInfo[c].charId)
+ {
+ if (j >= m->nCharsPerSite)
+ {
+ MrBayesPrint("%s Too many matches in charId (division %d char %d)\n", spacer, d, numCompressedChars);
+ goto errorExit;
+ }
+ else
+ {
+ col[j++] = i;
+ isTaken[i] = YES;
+ }
+ }
+ }
+ if (j != m->nCharsPerSite)
+ {
+ MrBayesPrint ("%s Too few matches in charId (division %d char %d)\n", spacer, d, numCompressedChars);
+ goto errorExit;
+ }
+ }
+
+ /* add character to temporary matrix in column(s) at newColumn */
+ for (t=newRow=0; t<numTaxa; t++)
+ {
+ if (taxaInfo[t].isDeleted == YES)
+ continue;
+
+ for (k=0; k<m->nCharsPerSite; k++)
+ {
+ tempMatrix[pos(newRow,newColumn+k,numLocalChar)] = matrix[pos(t,col[k],numChar)];
+ }
+ newRow++;
+ }
+
+ /* is it unique? */
+ isSame = NO;
+ if (mp->dataType != CONTINUOUS)
+ {
+ for (i=m->compMatrixStart; i<newColumn; i+=m->nCharsPerSite)
+ {
+ isSame = YES;
+ for (j=0; j<numLocalTaxa; j++)
+ {
+ for (k=0; k<m->nCharsPerSite; k++)
+ if (tempMatrix[pos(j,newColumn+k,numLocalChar)] != tempMatrix[pos(j,i+k,numLocalChar)])
+ {
+ isSame = NO;
+ break;
+ }
+ if (isSame == NO)
+ break;
+ }
+ if (isSame == YES)
+ break;
+ }
+ }
+
+ /* if subject to data augmentation, it is always unique */
+ if (!strcmp(mp->augmentData, "Yes"))
+ {
+ for (k=0; k<m->nCharsPerSite; k++)
+ {
+ if (charInfo[col[k]].isMissAmbig == YES)
+ isSame = NO;
+ }
+ }
+
+ if (isSame == NO)
+ {
+ /* if it is unique then it should be added */
+ tempSitesOfPat[numCompressedChars] = 1;
+ for (k=0; k<m->nCharsPerSite; k++)
+ {
+ compColPos[col[k]] = newColumn + k;
+ compCharPos[col[k]] = numCompressedChars;
+ tempChar[newColumn + k] = col[k];
+ }
+ newColumn+=m->nCharsPerSite;
+ m->numChars++;
+ numCompressedChars++;
+ }
+ else
+ {
+ /* if it is not unique then simply update tempSitesOfPat */
+ /* calculate compressed character position and put it into a */
+ /* (i points to compressed column position) */
+ a = m->compCharStart + ((i - m->compMatrixStart) / m->nCharsPerSite);
+ tempSitesOfPat[a]++;
+ for (k=0; k<m->nCharsPerSite; k++)
+ {
+ compColPos[col[k]] = i;
+ compCharPos[col[k]] = a;
+ /* tempChar (pointing from compressed to uncompresed) */
+ /* can only be set for first pattern */
+ }
+ }
+ } /* next character */
+
+ /* check that the partition has at least a single character */
+ if (m->numChars <= 0)
+ {
+ MrBayesPrint ("%s You must have at least one site in a partition. Partition %d\n", spacer, d+1);
+ MrBayesPrint ("%s has %d site patterns.\n", spacer, m->numChars);
+ goto errorExit;
+ }
+
+ m->compCharStop = m->compCharStart + m->numChars;
+ m->compMatrixStop = newColumn;
+
+ } /* next division */
+
+ compMatrixRowSize = newColumn;
+
+ /* now we know the size, so we can allocate space for the compressed matrix ... */
+ if (memAllocs[ALLOC_COMPMATRIX] == YES)
+ {
+ free (compMatrix);
+ compMatrix = NULL;
+ memAllocs[ALLOC_COMPMATRIX] = NO;
+ }
+ compMatrix = (BitsLong *) SafeCalloc (compMatrixRowSize * numLocalTaxa, sizeof(BitsLong));
+ if (!compMatrix)
+ {
+ MrBayesPrint ("%s Problem allocating compMatrix (%d)\n", spacer, compMatrixRowSize * numLocalTaxa * sizeof(BitsLong));
+ goto errorExit;
+ }
+ memAllocs[ALLOC_COMPMATRIX] = YES;
+
+ if (memAllocs[ALLOC_NUMSITESOFPAT] == YES)
+ {
+ free (numSitesOfPat);
+ numSitesOfPat = NULL;
+ memAllocs[ALLOC_NUMSITESOFPAT] = NO;
+ }
+ numSitesOfPat = (CLFlt *) SafeCalloc (numCompressedChars, sizeof(CLFlt));
+ if (!numSitesOfPat)
+ {
+ MrBayesPrint ("%s Problem allocating numSitesOfPat (%d)\n", spacer, numCompressedChars * sizeof(MrBFlt));
+ goto errorExit;
+ }
+ memAllocs[ALLOC_NUMSITESOFPAT] = YES;
+
+ if (memAllocs[ALLOC_ORIGCHAR] == YES)
+ {
+ free (origChar);
+ origChar = NULL;
+ memAllocs[ALLOC_ORIGCHAR] = NO;
+ }
+ origChar = (int *)SafeMalloc((size_t)compMatrixRowSize * sizeof(int));
+ if (!origChar)
+ {
+ MrBayesPrint ("%s Problem allocating origChar (%d)\n", spacer, numCompressedChars * sizeof(int));
+ goto errorExit;
+ }
+ memAllocs[ALLOC_ORIGCHAR] = YES;
+
+ /* ... and copy the data there */
+ for (i=0; i<numLocalTaxa; i++)
+ for (j=0; j<compMatrixRowSize; j++)
+ compMatrix[pos(i,j,compMatrixRowSize)] = tempMatrix[pos(i,j,numLocalChar)];
+
+ for (i=0; i<numCompressedChars; i++)
+ numSitesOfPat[i] = (CLFlt) tempSitesOfPat[i];
+
+ for (i=0; i<compMatrixRowSize; i++)
+ origChar[i] = tempChar[i];
+
+# if defined (DEBUG_COMPRESSDATA)
+ if (PrintCompMatrix() == ERROR)
+ goto errorExit;
+ getchar();
+# endif
+
+ /* free the temporary variables */
+ free (tempSitesOfPat);
+ free (tempMatrix);
+ free (isTaken);
+ free (tempChar);
+
+ return NO_ERROR;
+
+ errorExit:
+ if (tempMatrix)
+ free (tempMatrix);
+ if (tempSitesOfPat)
+ free (tempSitesOfPat);
+ if (isTaken)
+ free (isTaken);
+ if (tempChar)
+ free (tempChar);
+
+ return ERROR;
+}
+
+
+int DataType (int part)
+{
+ int i;
+
+ for (i=0; i<numChar; i++)
+ {
+ if (partitionId[i][partitionNum] == part + 1)
+ break;
+ }
+
+ return (charInfo[i].charType);
+}
+
+
+int DoLink (void)
+{
+ int i, j, newLine;
+
+ MrBayesPrint ("%s Linking\n", spacer);
+
+ /* update status of linkTable */
+ for (j=0; j<NUM_LINKED; j++)
+ {
+ newLine = YES;
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (tempLinkUnlink[j][i] == YES)
+ {
+ if (newLine == YES)
+ {
+ linkNum++;
+ newLine = NO;
+ }
+ linkTable[j][i] = linkNum;
+ }
+ }
+ }
+
+# if 0
+ for (j=0; j<NUM_LINKED; j++)
+ {
+ MrBayesPrint ("%s ", spacer);
+ for (i=0; i<numCurrentDivisions; i++)
+ MrBayesPrint ("%d", linkTable[j][i]);
+ MrBayesPrint ("\n");
+ }
+# endif
+
+ /* reinitialize the temporary table */
+ for (j=0; j<NUM_LINKED; j++)
+ for (i=0; i<numCurrentDivisions; i++)
+ tempLinkUnlink[j][i] = NO;
+
+ /* set up parameters and moves */
+ if (SetUpAnalysis (&globalSeed) == ERROR)
+ return (ERROR);
+
+ return (NO_ERROR);
+}
+
+
+int DoLinkParm (char *parmName, char *tkn)
+{
+ int i, j, tempInt;
+
+ if (defMatrix == NO)
+ {
+ MrBayesPrint ("%s A matrix must be specified before the model can be defined\n", spacer);
+ return (ERROR);
+ }
+
+ if (inValidCommand == YES)
+ {
+ for (j=0; j<NUM_LINKED; j++)
+ for (i=0; i<numCurrentDivisions; i++)
+ tempLinkUnlink[j][i] = NO;
+ inValidCommand = NO;
+ }
+
+ if (expecting == Expecting(PARAMETER))
+ {
+ expecting = Expecting(EQUALSIGN);
+ }
+ else if (expecting == Expecting(EQUALSIGN))
+ {
+ expecting = Expecting(LEFTPAR);
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ /* initialize tempLinkUnlinkVec to no */
+ for (i=0; i<numCurrentDivisions; i++)
+ tempLinkUnlinkVec[i] = NO;
+ fromI = toJ = -1;
+ foundDash = NO;
+ expecting = Expecting(NUMBER) | Expecting(ALPHA);
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ if (fromI != -1)
+ tempLinkUnlinkVec[fromI-1] = YES;
+ /* now copy tempLinkUnlinkVec to appropriate row of tempLinkUnlink */
+ if (!strcmp(parmName, "Tratio"))
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ tempLinkUnlink[P_TRATIO][i] = tempLinkUnlinkVec[i];
+ }
+ else if (!strcmp(parmName, "Revmat"))
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ tempLinkUnlink[P_REVMAT][i] = tempLinkUnlinkVec[i];
+ }
+ else if (!strcmp(parmName, "Omega"))
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ tempLinkUnlink[P_OMEGA][i] = tempLinkUnlinkVec[i];
+ }
+ else if (!strcmp(parmName, "Statefreq"))
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ tempLinkUnlink[P_PI][i] = tempLinkUnlinkVec[i];
+ }
+ else if (!strcmp(parmName, "Shape"))
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ tempLinkUnlink[P_SHAPE][i] = tempLinkUnlinkVec[i];
+ }
+ else if (!strcmp(parmName, "Pinvar"))
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ tempLinkUnlink[P_PINVAR][i] = tempLinkUnlinkVec[i];
+ }
+ else if (!strcmp(parmName, "Correlation"))
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ tempLinkUnlink[P_CORREL][i] = tempLinkUnlinkVec[i];
+ }
+ else if (!strcmp(parmName, "Ratemultiplier"))
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ tempLinkUnlink[P_RATEMULT][i] = tempLinkUnlinkVec[i];
+ }
+ else if (!strcmp(parmName, "Switchrates"))
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ tempLinkUnlink[P_SWITCH][i] = tempLinkUnlinkVec[i];
+ }
+ else if (!strcmp(parmName, "Topology"))
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ tempLinkUnlink[P_TOPOLOGY][i] = tempLinkUnlinkVec[i];
+ }
+ else if (!strcmp(parmName, "Brlens"))
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ tempLinkUnlink[P_BRLENS][i] = tempLinkUnlinkVec[i];
+ }
+ else if (!strcmp(parmName, "Speciationrate"))
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ tempLinkUnlink[P_SPECRATE][i] = tempLinkUnlinkVec[i];
+ }
+ else if (!strcmp(parmName, "Extinctionrate"))
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ tempLinkUnlink[P_EXTRATE][i] = tempLinkUnlinkVec[i];
+ }
+ else if (!strcmp(parmName, "Fossilizationrate"))
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ tempLinkUnlink[P_FOSLRATE][i] = tempLinkUnlinkVec[i];
+ }
+ else if (!strcmp(parmName, "Popsize"))
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ tempLinkUnlink[P_POPSIZE][i] = tempLinkUnlinkVec[i];
+ }
+ else if (!strcmp(parmName, "Growthrate"))
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ tempLinkUnlink[P_GROWTH][i] = tempLinkUnlinkVec[i];
+ }
+ else if (!strcmp(parmName, "Aamodel"))
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ tempLinkUnlink[P_AAMODEL][i] = tempLinkUnlinkVec[i];
+ }
+ else if (!strcmp(parmName, "Cpprate"))
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ tempLinkUnlink[P_CPPRATE][i] = tempLinkUnlinkVec[i];
+ }
+ else if (!strcmp(parmName, "Cppmultdev"))
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ tempLinkUnlink[P_CPPMULTDEV][i] = tempLinkUnlinkVec[i];
+ }
+ else if (!strcmp(parmName, "Cppevents"))
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ tempLinkUnlink[P_CPPEVENTS][i] = tempLinkUnlinkVec[i];
+ }
+ else if (!strcmp(parmName, "TK02var") || !strcmp(parmName, "Bmvar"))
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ tempLinkUnlink[P_TK02VAR][i] = tempLinkUnlinkVec[i];
+ }
+ else if (!strcmp(parmName, "TK02branchrates") || !strcmp(parmName, "Bmbranchrates"))
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ tempLinkUnlink[P_TK02BRANCHRATES][i] = tempLinkUnlinkVec[i];
+ }
+ else if (!strcmp(parmName, "Igrvar") || !strcmp(parmName, "Ibrvar"))
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ tempLinkUnlink[P_IGRVAR][i] = tempLinkUnlinkVec[i];
+ }
+ else if (!strcmp(parmName, "Igrbranchrates") || !strcmp(parmName, "Ibrbranchlens"))
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ tempLinkUnlink[P_IGRBRANCHRATES][i] = tempLinkUnlinkVec[i];
+ }
+ else if (!strcmp(parmName, "Mixedvar"))
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ tempLinkUnlink[P_MIXEDVAR][i] = tempLinkUnlinkVec[i];
+ }
+ else if (!strcmp(parmName, "Mixedbrchrates"))
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ tempLinkUnlink[P_MIXEDBRCHRATES][i] = tempLinkUnlinkVec[i];
+ }
+ else
+ {
+ MrBayesPrint ("%s Couldn't find parameter %s to link\n", spacer, parmName);
+ }
+
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ foundComma = YES;
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsSame ("All", tkn) == DIFFERENT)
+ {
+ MrBayesPrint ("%s Do not understand delimiter \"%s\"\n", spacer, tkn);
+ return (ERROR);
+ }
+ for (i=0; i<numCurrentDivisions; i++)
+ tempLinkUnlinkVec[i] = YES;
+ expecting = Expecting(RIGHTPAR);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ sscanf (tkn, "%d", &tempInt);
+ if (tempInt > numCurrentDivisions)
+ {
+ MrBayesPrint ("%s Partition delimiter is too large\n", spacer);
+ return (ERROR);
+ }
+ if (fromI == -1)
+ fromI = tempInt;
+ else if (fromI != -1 && toJ == -1 && foundDash == YES && foundComma == NO)
+ {
+ toJ = tempInt;
+ for (i=fromI-1; i<toJ; i++)
+ tempLinkUnlinkVec[i] = YES;
+ fromI = toJ = -1;
+ foundDash = NO;
+ }
+ else if (fromI != -1 && toJ == -1 && foundDash == NO && foundComma == YES)
+ {
+ tempLinkUnlinkVec[fromI-1] = YES;
+ fromI = tempInt;
+ foundComma = NO;
+ }
+ expecting = Expecting(COMMA);
+ expecting |= Expecting(DASH);
+ expecting |= Expecting(RIGHTPAR);
+ }
+ else if (expecting == Expecting(DASH))
+ {
+ foundDash = YES;
+ expecting = Expecting(NUMBER);
+ }
+ else
+ return (ERROR);
+
+ return (NO_ERROR);
+}
+
+
+int DoLset (void)
+{
+ int i, nApplied, lastActive=0;
+
+ nApplied = NumActiveParts ();
+ for (i=numCurrentDivisions-1; i>=0; i--)
+ {
+ if (activeParts[i] == YES)
+ {
+ lastActive = i;
+ break;
+ }
+ }
+
+ /* MrBayesPrint ("\n"); */
+ if (numCurrentDivisions == 1)
+ MrBayesPrint ("%s Successfully set likelihood model parameters\n", spacer);
+ else
+ {
+ if (nApplied == numCurrentDivisions || nApplied == 0)
+ {
+ MrBayesPrint ("%s Successfully set likelihood model parameters to all\n", spacer);
+ MrBayesPrint ("%s applicable data partitions \n", spacer);
+ }
+ else
+ {
+ MrBayesPrint ("%s Successfully set likelihood model parameters to\n", spacer);
+ if (nApplied == 1)
+ MrBayesPrint ("%s partition", spacer);
+ else
+ MrBayesPrint ("%s partitions", spacer);
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES)
+ {
+ if (i == lastActive && nApplied > 1)
+ MrBayesPrint (" and %d", i+1);
+ else
+ MrBayesPrint (" %d", i+1);
+ if (nApplied > 2 && i != lastActive)
+ MrBayesPrint (",");
+ }
+ }
+ MrBayesPrint (" (if applicable)\n");
+ }
+ }
+
+ if (SetUpAnalysis (&globalSeed) == ERROR)
+ return (ERROR);
+
+ return (NO_ERROR);
+}
+
+
+int DoLsetParm (char *parmName, char *tkn)
+{
+ int i, j, tempInt, nApplied;
+ char tempStr[100];
+
+ if (defMatrix == NO)
+ {
+ MrBayesPrint ("%s A matrix must be specified before the model can be defined\n", spacer);
+ return (ERROR);
+ }
+ if (inValidCommand == YES)
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ activeParts[i] = NO;
+ inValidCommand = NO;
+ }
+
+ if (expecting == Expecting(PARAMETER))
+ {
+ expecting = Expecting(EQUALSIGN);
+ }
+ else
+ {
+ /* set Applyto (Applyto) *************************************************************/
+ if (!strcmp(parmName, "Applyto"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(LEFTPAR);
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ activeParts[i] = NO;
+ fromI = toJ = -1;
+ foundDash = NO;
+ expecting = Expecting(NUMBER) | Expecting(ALPHA);
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ if (fromI != -1)
+ activeParts[fromI-1] = YES;
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ foundComma = YES;
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsSame ("All", tkn) == DIFFERENT)
+ {
+ MrBayesPrint ("%s Do not understand delimiter \"%s\"\n", spacer, tkn);
+ return (ERROR);
+ }
+ for (i=0; i<numCurrentDivisions; i++)
+ activeParts[i] = YES;
+ expecting = Expecting(RIGHTPAR);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ sscanf (tkn, "%d", &tempInt);
+ if (tempInt > numCurrentDivisions)
+ {
+ MrBayesPrint ("%s Partition delimiter is too large\n", spacer);
+ return (ERROR);
+ }
+ if (fromI == -1)
+ fromI = tempInt;
+ else if (fromI != -1 && toJ == -1 && foundDash == YES && foundComma == NO)
+ {
+ toJ = tempInt;
+ for (i=fromI-1; i<toJ; i++)
+ activeParts[i] = YES;
+ fromI = toJ = -1;
+ foundDash = NO;
+ }
+ else if (fromI != -1 && toJ == -1 && foundDash == NO && foundComma == YES)
+ {
+ activeParts[fromI-1] = YES;
+ fromI = tempInt;
+ foundComma = NO;
+ }
+
+ expecting = Expecting(COMMA);
+ expecting |= Expecting(DASH);
+ expecting |= Expecting(RIGHTPAR);
+ }
+ else if (expecting == Expecting(DASH))
+ {
+ foundDash = YES;
+ expecting = Expecting(NUMBER);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Nucmodel (nucModel) ************************************************************/
+ else if (!strcmp(parmName, "Nucmodel"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ tempInt = NO;
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA))
+ {
+ strcpy(modelParams[i].nucModel, tempStr);
+ modelParams[i].nStates = NumStates (i);
+
+ /* set state frequencies back to default */
+ strcpy(modelParams[i].stateFreqPr, "Dirichlet");
+ strcpy(modelParams[i].stateFreqsFixType, "Equal");
+ for (j=0; j<200; j++)
+ {
+ modelParams[i].stateFreqsFix[j] = 0.0;
+ modelParams[i].stateFreqsDir[j] = 1.0;
+ }
+ tempInt = YES;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Nucmodel to %s\n", spacer, modelParams[i].nucModel);
+ else
+ MrBayesPrint ("%s Setting Nucmodel to %s for partition %d\n", spacer, modelParams[i].nucModel, i+1);
+ }
+ }
+ if (tempInt == YES)
+ MrBayesPrint ("%s Set state frequency prior to default\n", spacer);
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid DNA substitution model\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Nst (nst) **********************************************************************/
+ else if (!strcmp(parmName, "Nst"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(NUMBER) | Expecting(ALPHA);
+ else if (expecting == Expecting(NUMBER) || expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ {
+ if (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA)
+ {
+ strcpy(modelParams[i].nst, tempStr);
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Nst to %s\n", spacer, modelParams[i].nst);
+ else
+ MrBayesPrint ("%s Setting Nst to %s for partition %d\n", spacer, modelParams[i].nst, i+1);
+ }
+ else {
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Nst =%s unchanged ", spacer, modelParams[i].nst);
+ else
+ MrBayesPrint ("%s Nst =%s unchanged for partition %d ", spacer, modelParams[i].nst, i+1);
+ MrBayesPrint ("because dataType is not DNA or RNA\n");
+ }
+ }
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Nst argument\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Ncat (numGammaCats) ************************************************************/
+ else if (!strcmp(parmName, "Ngammacat"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(NUMBER);
+ else if (expecting == Expecting(NUMBER))
+ {
+ sscanf (tkn, "%d", &tempInt);
+ if (tempInt >= 2 && tempInt < MAX_GAMMA_CATS)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType != CONTINUOUS))
+ {
+ modelParams[i].numGammaCats = tempInt;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Ngammacat to %d\n", spacer, modelParams[i].numGammaCats);
+ else
+ MrBayesPrint ("%s Setting Ngammacat to %d for partition %d\n", spacer, modelParams[i].numGammaCats, i+1);
+ }
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Ngammacat argument (should be between 2 and %d)\n", spacer, MAX_GAMMA_CATS);
+ return (ERROR);
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Usegibbs (useGibbs) *************************************************************/
+ else if (!strcmp(parmName, "Usegibbs"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ {
+ if (!strcmp(tempStr, "Yes"))
+ {
+ MrBayesPrint ("%s Downsampling of site rates ('usegibbs = yes') disabled temporarily because of conflict with likelihood calculators\n", spacer);
+ return (ERROR);
+ strcpy(modelParams[i].useGibbs, "Yes");
+ }
+ else
+ {
+ strcpy(modelParams[i].useGibbs, "No");
+ }
+
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Usegibbs to %s (if applicable)\n", spacer, modelParams[i].useGibbs);
+ else
+ MrBayesPrint ("%s Setting Usegibbs to %s (if applicable) for partition %d\n", spacer, modelParams[i].useGibbs, i+1);
+ }
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid argument for Usegibbs (using Gibbs sampling of discrete gamma)\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Gibbsfreq (gibbsFreq) ************************************************************/
+ else if (!strcmp(parmName, "Gibbsfreq"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(NUMBER);
+ else if (expecting == Expecting(NUMBER))
+ {
+ sscanf (tkn, "%d", &tempInt);
+ if (tempInt >= 1 && tempInt <= 1000)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ {
+ modelParams[i].gibbsFreq = tempInt;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Gibbsfreq to %d\n", spacer, modelParams[i].gibbsFreq);
+ else
+ MrBayesPrint ("%s Setting Gibbsfreq to %d for partition %d\n", spacer, modelParams[i].gibbsFreq, i+1);
+ }
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Gibbsgammafreq argument (should be between 1 and 1000)\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set NumM10GammaCats (numM10GammaCats) ************************************************************/
+ else if (!strcmp(parmName, "NumM10GammaCats"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(NUMBER);
+ else if (expecting == Expecting(NUMBER))
+ {
+ sscanf (tkn, "%d", &tempInt);
+ if (tempInt >= 2 && tempInt < MAX_GAMMA_CATS)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType != CONTINUOUS))
+ {
+ modelParams[i].numM10GammaCats = tempInt;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting NumM10GammaCats to %d\n", spacer, modelParams[i].numM10GammaCats);
+ else
+ MrBayesPrint ("%s Setting NumM10GammaCats to %d for partition %d\n", spacer, modelParams[i].numM10GammaCats, i+1);
+ }
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid NumM10GammaCats argument (should be between 2 and %d)\n", spacer, MAX_GAMMA_CATS);
+ return (ERROR);
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set NumM10BetaCats (numM10BetaCats) ************************************************************/
+ else if (!strcmp(parmName, "NumM10BetaCats"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(NUMBER);
+ else if (expecting == Expecting(NUMBER))
+ {
+ sscanf (tkn, "%d", &tempInt);
+ if (tempInt >= 2 && tempInt < MAX_GAMMA_CATS)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType != CONTINUOUS))
+ {
+ modelParams[i].numM10BetaCats = tempInt;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting NumM10BetaCats to %d\n", spacer, modelParams[i].numM10BetaCats);
+ else
+ MrBayesPrint ("%s Setting NumM10BetaCats to %d for partition %d\n", spacer, modelParams[i].numM10BetaCats, i+1);
+ }
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid NumM10GammaCats argument (should be between 2 and %d)\n", spacer, MAX_GAMMA_CATS);
+ return (ERROR);
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Nbetacat (numBetaCats) *****************************************************/
+ else if (!strcmp(parmName, "Nbetacat"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(NUMBER);
+ else if (expecting == Expecting(NUMBER))
+ {
+ sscanf (tkn, "%d", &tempInt);
+ if (tempInt >= 2 && tempInt < MAX_GAMMA_CATS)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == STANDARD || modelParams[i].dataType == RESTRICTION))
+ {
+ modelParams[i].numBetaCats = tempInt;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Nbetacat to %d\n", spacer, modelParams[i].numBetaCats);
+ else
+ MrBayesPrint ("%s Setting Nbetacat to %d for partition %d\n", spacer, modelParams[i].numBetaCats, i+1);
+ }
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Nbetacat argument (should be between 2 and %d)\n", spacer, MAX_GAMMA_CATS);
+ return (ERROR);
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Aamodel (aaModel) **************************************************************/
+ else if (!strcmp(parmName, "Aamodel"))
+ {
+ MrBayesPrint ("%s Aamodel argument for lset deprecated.\n", spacer);
+ MrBayesPrint ("%s Use 'prset aamodelpr=fixed(<aamodel>)' instead.\n", spacer);
+ return (ERROR);
+ }
+ /* set Parsmodel (useParsModel) *******************************************************/
+ else if (!strcmp(parmName, "Parsmodel"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ {
+ if (!strcmp(tempStr, "Yes"))
+ strcpy(modelParams[i].parsModel, "Yes");
+ else
+ strcpy(modelParams[i].parsModel, "No");
+
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Parsmodel to %s\n", spacer, modelParams[i].parsModel);
+ else
+ MrBayesPrint ("%s Setting Parsmodel to %s for partition %d\n", spacer, modelParams[i].parsModel, i+1);
+ }
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid argument for using (so-called) parsimony model\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Augment (augmentData) **********************************************************/
+ else if (!strcmp(parmName, "Augment"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && modelParams[i].dataType != CONTINUOUS)
+ {
+ if (!strcmp(tempStr, "Yes"))
+ strcpy(modelParams[i].augmentData, "Yes");
+ else
+ strcpy(modelParams[i].augmentData, "No");
+
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Augmentdata to %s\n", spacer, modelParams[i].augmentData);
+ else
+ MrBayesPrint ("%s Setting Augmentdata to %s for partition %d\n", spacer, modelParams[i].augmentData, i+1);
+ }
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid argument for data augmentation\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Omegavar (wVarModel) ***********************************************************/
+ else if (!strcmp(parmName, "Omegavar"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA))
+ {
+ strcpy(modelParams[i].omegaVar, tempStr);
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Omegavar to %s\n", spacer, modelParams[i].omegaVar);
+ else
+ MrBayesPrint ("%s Setting Omegavar to %s for partition %d\n", spacer, modelParams[i].omegaVar, i+1);
+ }
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid omega variation argument\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Code (codeModel) ***************************************************************/
+ else if (!strcmp(parmName, "Code"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA))
+ {
+ strcpy(modelParams[i].geneticCode, tempStr);
+ SetCode (i);
+ modelParams[i].nStates = NumStates (i);
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Code to %s\n", spacer, modelParams[i].geneticCode);
+ else
+ MrBayesPrint ("%s Setting Code to %s for partition %d\n", spacer, modelParams[i].geneticCode, i+1);
+ }
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid genetic code argument\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Ploidy (ploidy) ***************************************************************/
+ else if (!strcmp(parmName, "Ploidy"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA))
+ {
+ strcpy(modelParams[i].ploidy, tempStr);
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting ploidy level to %s\n", spacer, modelParams[i].ploidy);
+ else
+ MrBayesPrint ("%s Setting ploidy level to %s for partition %d\n", spacer, modelParams[i].ploidy, i+1);
+ }
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid ploidy level argument\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Rates (ratesModel) *************************************************************/
+ else if (!strcmp(parmName, "Rates"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && modelParams[i].dataType != CONTINUOUS)
+ {
+ if (!strcmp(tempStr, "Adgamma") && (modelParams[i].dataType != DNA && modelParams[i].dataType != RNA && modelParams[i].dataType != PROTEIN))
+ {
+ /* we won't apply an adgamma model to anything but DNA, RNA, or PROTEIN data */
+ }
+ else if ((!strcmp(tempStr, "Propinv") || !strcmp(tempStr, "Invgamma")) && (modelParams[i].dataType == STANDARD || modelParams[i].dataType == RESTRICTION))
+ {
+ /* we will not apply pinvar to standard or restriction site data */
+ }
+ else
+ {
+ strcpy(modelParams[i].ratesModel, tempStr);
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Rates to %s\n", spacer, modelParams[i].ratesModel);
+ else
+ MrBayesPrint ("%s Setting Rates to %s for partition %d\n", spacer, modelParams[i].ratesModel, i+1);
+ }
+ }
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Rates argument\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Covarion (covarionModel) *******************************************************/
+ else if (!strcmp(parmName, "Covarion"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA || modelParams[i].dataType == PROTEIN))
+ {
+ strcpy(modelParams[i].covarionModel, tempStr);
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Covarion to %s\n", spacer, modelParams[i].covarionModel);
+ else
+ MrBayesPrint ("%s Setting Covarion to %s for partition %d\n", spacer, modelParams[i].covarionModel, i+1);
+ }
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Rates argument\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Coding (missingType) ***********************************************************/
+ else if (!strcmp(parmName, "Coding"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ modelParams[i].coding = ALL;
+
+ expecting = Expecting(ALPHA);
+ }
+ else if (expecting == Expecting(VERTICALBAR))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == RESTRICTION || modelParams[i].dataType == STANDARD))
+ {
+ if(!strcmp(tempStr, "Nosingletons"))
+ {
+ modelParams[i].coding |= NOSINGLETONS;
+ }
+ else if(!strcmp(tempStr, "Variable"))
+ {
+ modelParams[i].coding |= VARIABLE;
+ }
+ else if(!strcmp(tempStr, "Informative"))
+ {
+ modelParams[i].coding |= INFORMATIVE;
+ }
+ else
+ {
+ if(modelParams[i].dataType != RESTRICTION)
+ {
+ MrBayesPrint ("%s Invalid coding for standard characters: %s\n", spacer, tempStr);
+ return (ERROR);
+ }
+
+ if(!strcmp(tempStr, "Noabsencesites"))
+ {
+ modelParams[i].coding |= NOABSENCESITES;
+ }
+ else if(!strcmp(tempStr, "Nopresencesites"))
+ {
+ modelParams[i].coding |= NOPRESENCESITES;
+ }
+ else if(!strcmp(tempStr, "Nosingletonpresence"))
+ {
+ modelParams[i].coding |= NOSINGLETONPRESENCE;
+ }
+ else if(!strcmp(tempStr, "Nosingletonabsence"))
+ {
+ modelParams[i].coding |= NOSINGLETONABSENCE;
+ }
+ }
+
+ CodingToString(modelParams[i].coding, modelParams[i].codingString);
+
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Enabling Coding %s\n", spacer, tempStr);
+ else
+ MrBayesPrint ("%s Enabling Coding %s for partition %d\n", spacer, tempStr, i+1);
+ }
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid argument for missing patterns\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON) | Expecting(VERTICALBAR);
+ }
+ else
+ return (ERROR);
+ }
+
+
+
+
+ else
+ return (ERROR);
+ }
+
+ return (NO_ERROR);
+}
+
+
+int DoPlot (void)
+{
+ int i, n, nHeaders, burnin, len, longestHeader, whichIsX, whichIsY, numPlotted;
+ char temp[100], **headerNames = NULL;
+ SumpFileInfo fileInfo;
+ ParameterSample *parameterSamples;
+
+# if defined (MPI_ENABLED)
+ if (proc_id != 0)
+ return NO_ERROR;
+# endif
+
+ /* initialize values */
+ headerNames = NULL;
+ nHeaders = 0;
+ parameterSamples = NULL;
+
+ /* tell user we are ready to go */
+ MrBayesPrint ("%s Plotting parameters in file %s ...\n", spacer, plotParams.plotFileName);
+
+ /* examine plot file */
+ if (ExamineSumpFile (plotParams.plotFileName, &fileInfo, &headerNames, &nHeaders) == ERROR)
+ return ERROR;
+
+ /* Calculate burn in */
+ burnin = fileInfo.firstParamLine - fileInfo.headerLine - 1;
+
+ /* tell the user that everything is fine */
+ MrBayesPrint ("%s Found %d parameter lines in file \"%s\"\n", spacer, fileInfo.numRows + burnin, plotParams.plotFileName);
+ if (burnin > 0)
+ MrBayesPrint ("%s Of the %d lines, %d of them will be summarized (starting at line %d)\n", spacer, fileInfo.numRows+burnin, fileInfo.numRows, fileInfo.firstParamLine);
+ else
+ MrBayesPrint ("%s All %d lines will be summarized (starting at line %d)\n", spacer, fileInfo.numRows, fileInfo.firstParamLine);
+ MrBayesPrint ("%s (Only the last set of lines will be read, in case multiple\n", spacer);
+ MrBayesPrint ("%s parameter blocks are present in the same file.)\n", spacer);
+
+ /* allocate space to hold parameter information */
+ if (AllocateParameterSamples (¶meterSamples, 1, fileInfo.numRows, fileInfo.numColumns) == ERROR)
+ goto errorExit;
+
+ /* Now we read the file for real. First, rewind file pointer to beginning of file... */
+ if (ReadParamSamples (plotParams.plotFileName, &fileInfo, parameterSamples, 0) == ERROR)
+ goto errorExit;
+
+ /* get length of longest header */
+ longestHeader = 9; /* 9 is the length of the word "parameter" (for printing table) */
+ for (i=0; i<nHeaders; i++)
+ {
+ len = (int) strlen(headerNames[i]);
+ if (len > longestHeader)
+ longestHeader = len;
+ }
+
+ /* print x-y plot of parameter vs. generation */
+ whichIsX = -1;
+ for (i=0; i<nHeaders; i++)
+ {
+ if (IsSame (headerNames[i], "Gen") == SAME)
+ whichIsX = i;
+ }
+
+ if (whichIsX < 0)
+ {
+ MrBayesPrint ("%s Could not find a column labelled \"Gen\" \n", spacer);
+ goto errorExit;
+ }
+
+ numPlotted = 0;
+ for (n=0; n<nHeaders; n++)
+ {
+ strcpy (temp, headerNames[n]);
+ whichIsY = -1;
+ if (!strcmp(plotParams.match, "Perfect"))
+ {
+ if (IsSame (temp, plotParams.parameter) == SAME)
+ whichIsY = n;
+ }
+ else if (!strcmp(plotParams.match, "All"))
+ {
+ whichIsY = n;
+ }
+ else
+ {
+ if (IsSame (temp, plotParams.parameter) == CONSISTENT_WITH)
+ whichIsY = n;
+ }
+
+ if (whichIsY >= 0 && whichIsX != whichIsY)
+ {
+ MrBayesPrint ("\n%s Rough trace plot of parameter %s:\n", spacer, headerNames[whichIsY]);
+ if (PrintPlot (parameterSamples[whichIsX].values[0], parameterSamples[whichIsY].values[0], fileInfo.numRows) == ERROR)
+ goto errorExit;
+ numPlotted++;
+ }
+ }
+
+ if (numPlotted == 0)
+ {
+ MrBayesPrint ("%s Did not find any parameters matching \"%s\" to plot\n", spacer, plotParams.parameter);
+ }
+
+ /* free memory */
+ for (i=0; i<nHeaders; i++)
+ free (headerNames[i]);
+ free(headerNames);
+ FreeParameterSamples(parameterSamples);
+
+ expecting = Expecting(COMMAND);
+
+ return (NO_ERROR);
+
+errorExit:
+
+ /* free memory */
+ for (i=0; i<nHeaders; i++)
+ free (headerNames[i]);
+ free(headerNames);
+ FreeParameterSamples(parameterSamples);
+
+ expecting = Expecting(COMMAND);
+
+ return (ERROR);
+}
+
+
+int DoPlotParm (char *parmName, char *tkn)
+{
+ int tempI;
+ MrBFlt tempD;
+ char tempStr[100];
+
+ if (defMatrix == NO)
+ {
+ MrBayesPrint ("%s A matrix must be specified before sumt can be used\n", spacer);
+ return (ERROR);
+ }
+
+ if (expecting == Expecting(PARAMETER))
+ {
+ expecting = Expecting(EQUALSIGN);
+ }
+ else
+ {
+ if (!strcmp(parmName, "Xxxxxxxxxx"))
+ {
+ expecting = Expecting(PARAMETER);
+ expecting |= Expecting(SEMICOLON);
+ }
+ /* set Filename (plotParams.plotFileName) ***************************************************/
+ else if (!strcmp(parmName, "Filename"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ {
+ expecting = Expecting(ALPHA);
+ readWord = YES;
+ }
+ else if (expecting == Expecting(ALPHA))
+ {
+ strcpy (plotParams.plotFileName, tkn);
+ MrBayesPrint ("%s Setting plot filename to %s\n", spacer, plotParams.plotFileName);
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Relburnin (chainParams.relativeBurnin) ********************************************************/
+ else if (!strcmp(parmName, "Relburnin"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ if (!strcmp(tempStr, "Yes"))
+ chainParams.relativeBurnin = YES;
+ else
+ chainParams.relativeBurnin = NO;
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid argument for Relburnin\n", spacer);
+ return (ERROR);
+ }
+ if (chainParams.relativeBurnin == YES)
+ MrBayesPrint ("%s Using relative burnin (a fraction of samples discarded).\n", spacer);
+ else
+ MrBayesPrint ("%s Using absolute burnin (a fixed number of samples discarded).\n", spacer);
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ {
+ return (ERROR);
+ }
+ }
+ /* set Burnin (chainParams.chainBurnIn) *******************************************************/
+ else if (!strcmp(parmName, "Burnin"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(NUMBER);
+ else if (expecting == Expecting(NUMBER))
+ {
+ sscanf (tkn, "%d", &tempI);
+ chainParams.chainBurnIn = tempI;
+ MrBayesPrint ("%s Setting burnin to %d\n", spacer, chainParams.chainBurnIn);
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Burninfrac (chainParams.burninFraction) ************************************************************/
+ else if (!strcmp(parmName, "Burninfrac"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(NUMBER);
+ else if (expecting == Expecting(NUMBER))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ if (tempD < 0.01)
+ {
+ MrBayesPrint ("%s Burnin fraction too low (< 0.01)\n", spacer);
+ return (ERROR);
+ }
+ if (tempD > 0.50)
+ {
+ MrBayesPrint ("%s Burnin fraction too high (> 0.50)\n", spacer);
+ return (ERROR);
+ }
+ chainParams.burninFraction = tempD;
+ MrBayesPrint ("%s Setting burnin fraction to %.2f\n", spacer, chainParams.burninFraction);
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ {
+ return (ERROR);
+ }
+ }
+ /* set Parameter (plotParams.parameter) *******************************************************/
+ else if (!strcmp(parmName, "Parameter"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ {
+ expecting = Expecting(ALPHA);
+ readWord = YES;
+ }
+ else if (expecting == Expecting(ALPHA))
+ {
+ strcpy (plotParams.parameter, tkn);
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Parameter (plotParams.match) *******************************************************/
+ else if (!strcmp(parmName, "Match"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ strcpy (plotParams.match, tempStr);
+ else
+ return (ERROR);
+
+ MrBayesPrint ("%s Setting plot matching to %s\n", spacer, plotParams.match);
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+
+ else
+ return (ERROR);
+ }
+
+ return (NO_ERROR);
+}
+
+
+int DoPropset (void)
+{
+ MrBayesPrint ("%s Successfully set proposal parameters\n", spacer);
+
+ return (NO_ERROR);
+}
+
+
+int DoPropsetParm (char *parmName, char *tkn)
+{
+ int i, j, k, nMatches, tempInt;
+ MrBFlt tempFloat;
+ static MCMCMove *mv = NULL;
+ static MrBFlt *theValue, theValueMin, theValueMax;
+ static int jump, runIndex, chainIndex;
+ static char *temp=NULL, *localTkn=NULL; /*freed at the end of the call*/
+ static char *tempName=NULL; /*not freed at the end of the call*/
+
+ if (defMatrix == NO)
+ {
+ MrBayesPrint ("%s A matrix must be specified before proposal parameters can be changed\n", spacer);
+ return (ERROR);
+ }
+
+ if (expecting == Expecting(PARAMETER))
+ {
+ if (!strcmp(parmName, "Xxxxxxxxxx"))
+ {
+ /* we expect a move name with possible run and chain specification as follows:
+ <move_name>$<tuning_param_name>(<run>,<chain>)=<number> -- apply to run <run> and chain <chain>
+ <move_name>$<tuning_param_name>(,<chain>)=<number> -- apply to chain <chain> for all runs
+ <move_name>$<tuning_param_name>(<run>,)=<number> -- apply to all chains of run <run>
+ <move_name>$prob(<run>,<chain>)=<number> -- change relative proposal probability
+ <move_name>$targetrate(<run>,<chain>)=<number> -- change target acc rate for autotuning
+
+ the parsing is complicated by the fact that the move name can look something like:
+ eTBR(Tau{all})
+ eTBR(Tau{1,4,5})
+ so we need to assemble the move name from several tokens that are parsed out separately;
+ here we receive only the first part (before the left parenthesis)
+ */
+
+ /* copy to local move name */
+ SafeStrcpy(&tempName, tkn);
+ mv = NULL;
+ foundComma = foundEqual = NO;
+ expecting = Expecting(LEFTCURL) | Expecting(RIGHTCURL) | Expecting(COMMA) |
+ Expecting(LEFTPAR) | Expecting(RIGHTPAR) | Expecting(NUMBER) | Expecting(ALPHA) |
+ Expecting(DOLLAR);
+ }
+ else
+ return (ERROR);
+ }
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (mv == NULL)
+ {
+ /* we are still assembling the move name */
+ SafeStrcat(&tempName, tkn);
+ expecting = Expecting(LEFTCURL) | Expecting(RIGHTCURL) | Expecting(COMMA) |
+ Expecting(LEFTPAR) | Expecting(RIGHTPAR) | Expecting(NUMBER) | Expecting(ALPHA) |
+ Expecting(DOLLAR);
+ }
+ else
+ {
+ /* we have a parameter name; now find the parameter name, case insensitive */
+ SafeStrcpy(&localTkn, tkn);
+ for (i=0; i<(int)strlen(localTkn); i++)
+ localTkn[i] = tolower(localTkn[i]);
+ nMatches = j = 0;
+ for (i=0; i<mv->moveType->numTuningParams; i++)
+ {
+ SafeStrcpy(&temp, mv->moveType->shortTuningName[i]);
+ for (k=0; k<(int)strlen(temp); k++)
+ temp[k] = tolower(temp[k]);
+ if (strncmp(localTkn,temp,strlen(localTkn)) == 0)
+ {
+ j = i;
+ nMatches++;
+ }
+ }
+ if (strncmp(localTkn,"prob",strlen(localTkn)) == 0)
+ {
+ j = -1;
+ nMatches++;
+ }
+ else if (strncmp(localTkn,"targetrate",strlen(localTkn)) == 0)
+ {
+ j = -2;
+ nMatches++;
+ }
+ if (nMatches == 0)
+ {
+ MrBayesPrint ("%s Could not find move parameter to change '%s'\n", spacer, localTkn);
+ return (ERROR);
+ }
+ else if (nMatches > 1)
+ {
+ MrBayesPrint ("%s Several move parameters matched the abbreviated name '%s'\n", spacer, localTkn);
+ return (ERROR);
+ }
+
+ if (j == -1)
+ {
+ theValue = mv->relProposalProb;
+ theValueMin = 0.0;
+ theValueMax = 1000.0;
+ jump = 1;
+ }
+ else if (j == -2)
+ {
+ theValue = mv->targetRate;
+ theValueMin = 0.10;
+ theValueMax = 0.70;
+ jump = 1;
+ }
+ else
+ {
+ theValue = &mv->tuningParam[0][j];
+ theValueMin = mv->moveType->minimum[j];
+ theValueMax = mv->moveType->maximum[j];
+ jump = mv->moveType->numTuningParams;
+ }
+ chainIndex = -1;
+ runIndex = -1;
+ expecting = Expecting(LEFTPAR) | Expecting(EQUALSIGN);
+ }
+ }
+ else if (expecting == Expecting(LEFTCURL) || expecting == Expecting(RIGHTCURL))
+ {
+ /* we are still assembling the move name */
+ SafeStrcat (&tempName, tkn);
+ expecting = Expecting(LEFTCURL) | Expecting(RIGHTCURL) | Expecting(COMMA) |
+ Expecting(LEFTPAR) | Expecting(RIGHTPAR) | Expecting(NUMBER) | Expecting(ALPHA) |
+ Expecting(DOLLAR);
+ }
+ else if (expecting == Expecting(DOLLAR))
+ {
+ /* we know that the name is complete now; find the move by its name,
+ case insensitive */
+ SafeStrcpy(&localTkn, tempName);
+ j=(int)strlen(localTkn);
+ for (i=0; i<j; i++)
+ localTkn[i] = tolower(localTkn[i]);
+
+ /* find the move */
+ nMatches = j = 0;
+ for (i=0; i<numApplicableMoves; i++)
+ {
+ mv = moves[i];
+ SafeStrcpy(&temp,mv->name);
+ for (k=0; k<(int)strlen(temp); k++)
+ temp[k] = tolower(temp[k]);
+ if (strncmp(temp,localTkn,strlen(localTkn)) == 0)
+ {
+ j = i;
+ nMatches++;
+ }
+ }
+ if (nMatches == 0)
+ {
+ MrBayesPrint ("%s Could not find move '%s'\n", spacer, localTkn);
+ return (ERROR);
+ }
+ else if (nMatches > 1)
+ {
+ MrBayesPrint ("%s Several moves matched the abbreviated name '%s'\n", spacer, localTkn);
+ return (ERROR);
+ }
+ else
+ mv = moves[j];
+
+ foundComma = foundEqual = NO;
+ expecting = Expecting(ALPHA);
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ if (mv == NULL)
+ {
+ /* we are still assembling the move name */
+ SafeStrcat (&tempName, tkn);
+ expecting = Expecting(LEFTCURL) | Expecting(RIGHTCURL) | Expecting(COMMA) |
+ Expecting(LEFTPAR) | Expecting(RIGHTPAR) | Expecting(NUMBER) | Expecting(ALPHA) |
+ Expecting(DOLLAR);
+ }
+ else /* if (mv != NULL) */
+ {
+ /* we will be reading in run and chain indices */
+ expecting = Expecting(NUMBER) | Expecting(COMMA);
+ }
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ if (mv == NULL)
+ {
+ /* we are still assembling the move name */
+ SafeStrcat (&tempName, tkn);
+ expecting = Expecting(LEFTCURL) | Expecting(RIGHTCURL) | Expecting(COMMA) |
+ Expecting(LEFTPAR) | Expecting(RIGHTPAR) | Expecting(NUMBER) | Expecting(ALPHA) |
+ Expecting(DOLLAR);
+ }
+ else if (foundEqual == YES)
+ {
+ sscanf (tkn, "%lf", &tempFloat);
+ if (tempFloat < theValueMin || tempFloat > theValueMax)
+ {
+ MrBayesPrint ("%s The value is out of range (min = %lf; max = %lf)\n", spacer, theValueMin, theValueMax);
+ return (ERROR);
+ }
+ if (runIndex == -1 && chainIndex == -1)
+ {
+ for (i=0; i<chainParams.numRuns; i++)
+ {
+ for (j=0; j<chainParams.numChains; j++)
+ {
+ *theValue = tempFloat;
+ theValue += jump;
+ }
+ }
+ }
+ else if (runIndex == -1 && chainIndex >= 0)
+ {
+ theValue += chainIndex*jump;
+ for (i=0; i<chainParams.numRuns; i++)
+ {
+ *theValue = tempFloat;
+ theValue += chainParams.numChains*jump;
+ }
+ }
+ else if (runIndex >= 0 && chainIndex == -1)
+ {
+ theValue += runIndex*chainParams.numChains*jump;
+ for (i=0; i<chainParams.numChains; i++)
+ {
+ *theValue = tempFloat;
+ theValue += jump;
+ }
+ }
+ else /* if (runIndex >= 0 && chainIndex >= 0) */
+ {
+ theValue[runIndex*chainParams.numChains*jump+chainIndex*jump] = tempFloat;
+ }
+ expecting = Expecting (PARAMETER) | Expecting(SEMICOLON);
+ }
+ else /* if (foundEqual == NO) */
+ {
+ sscanf (tkn, "%d", &tempInt);
+ if (foundComma == NO)
+ {
+ if (tempInt <= 0 || tempInt > chainParams.numRuns)
+ {
+ MrBayesPrint ("%s Run index is out of range (min=1; max=%d)\n", spacer, chainParams.numRuns);
+ return (ERROR);
+ }
+ runIndex = tempInt - 1;
+ expecting = Expecting(COMMA);
+ }
+ else
+ {
+ if (tempInt <= 0 || tempInt > chainParams.numChains)
+ {
+ MrBayesPrint ("%s Chain index is out of range (min=1; max=%d)\n", spacer, chainParams.numChains);
+ return (ERROR);
+ }
+ chainIndex = tempInt - 1;
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ if (mv == NULL)
+ {
+ /* we are still assembling the move name */
+ SafeStrcat (&tempName, tkn);
+ expecting = Expecting(LEFTCURL) | Expecting(RIGHTCURL) | Expecting(COMMA) |
+ Expecting(LEFTPAR) | Expecting(RIGHTPAR) | Expecting(NUMBER) | Expecting(ALPHA) |
+ Expecting(DOLLAR);
+ }
+ else
+ {
+ /* we will be reading in chain index, if present */
+ foundComma = YES;
+ expecting = Expecting(RIGHTPAR) | Expecting(NUMBER);
+ }
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ if (mv == NULL)
+ {
+ /* we are still assembling the move name */
+ SafeStrcat (&tempName, tkn);
+ expecting = Expecting(LEFTCURL) | Expecting(RIGHTCURL) | Expecting(COMMA) |
+ Expecting(LEFTPAR) | Expecting(RIGHTPAR) | Expecting(NUMBER) | Expecting(ALPHA) |
+ Expecting(DOLLAR);
+ }
+ else
+ expecting = Expecting(EQUALSIGN);
+ }
+ else if (expecting == Expecting(EQUALSIGN))
+ {
+ foundEqual = YES;
+ expecting = Expecting(NUMBER);
+ }
+ else
+ return (ERROR);
+
+ SafeFree ((void **)&temp);
+ SafeFree ((void **)&localTkn);
+ return (NO_ERROR);
+}
+
+
+int DoPrset (void)
+{
+ int i, nApplied, lastActive=0;
+
+ nApplied = NumActiveParts ();
+ for (i=numCurrentDivisions-1; i>=0; i--)
+ {
+ if (activeParts[i] == YES)
+ {
+ lastActive = i;
+ break;
+ }
+ }
+
+ if (numCurrentDivisions == 1)
+ MrBayesPrint ("%s Successfully set prior model parameters\n", spacer);
+ else
+ {
+ if (nApplied == numCurrentDivisions || nApplied == 0)
+ {
+ MrBayesPrint ("%s Successfully set prior model parameters to all\n", spacer);
+ MrBayesPrint ("%s applicable data partitions \n", spacer);
+ }
+ else
+ {
+ MrBayesPrint ("%s Successfully set prior model parameters to\n", spacer);
+ if (nApplied == 1)
+ MrBayesPrint ("%s partition", spacer);
+ else
+ MrBayesPrint ("%s partitions", spacer);
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES)
+ {
+ if (i == lastActive && nApplied > 1)
+ MrBayesPrint (" and %d", i+1);
+ else
+ MrBayesPrint (" %d", i+1);
+ if (nApplied > 2 && i != lastActive)
+ MrBayesPrint (",");
+ }
+ }
+ MrBayesPrint (" (if applicable)\n");
+ }
+ }
+
+ if (SetUpAnalysis (&globalSeed) == ERROR)
+ return (ERROR);
+
+ return (NO_ERROR);
+}
+
+
+int DoPrsetParm (char *parmName, char *tkn)
+{
+ int i, j, k, tempInt, nApplied, index, ns, flag=0;
+ MrBFlt tempD, sum;
+ char tempStr[100];
+
+ if (defMatrix == NO)
+ {
+ MrBayesPrint ("%s A matrix must be specified before the model can be defined\n", spacer);
+ return (ERROR);
+ }
+ if (inValidCommand == YES)
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ activeParts[i] = NO;
+ inValidCommand = NO;
+ }
+
+ if (expecting == Expecting(PARAMETER))
+ {
+ expecting = Expecting(EQUALSIGN);
+ }
+ else
+ {
+ /* set Applyto (Applyto) *************************************************************/
+ if (!strcmp(parmName, "Applyto"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(LEFTPAR);
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ activeParts[i] = NO;
+ fromI = toJ = -1;
+ foundDash = NO;
+ expecting = Expecting(NUMBER) | Expecting(ALPHA);
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ if (fromI != -1)
+ activeParts[fromI-1] = YES;
+# if 0
+ for (i=0; i<numCurrentDivisions; i++)
+ MrBayesPrint("%d ", activeParts[i]);
+ MrBayesPrint ("\n");
+# endif
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ foundComma = YES;
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsSame ("All", tkn) == DIFFERENT)
+ {
+ MrBayesPrint ("%s Do not understand delimiter \"%s\"\n", spacer, tkn);
+ return (ERROR);
+ }
+ for (i=0; i<numCurrentDivisions; i++)
+ activeParts[i] = YES;
+ expecting = Expecting(RIGHTPAR);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ sscanf (tkn, "%d", &tempInt);
+ if (tempInt > numCurrentDivisions)
+ {
+ MrBayesPrint ("%s Partition delimiter is too large\n", spacer);
+ return (ERROR);
+ }
+ if (fromI == -1)
+ fromI = tempInt;
+ else if (fromI != -1 && toJ == -1 && foundDash == YES && foundComma == NO)
+ {
+ toJ = tempInt;
+ for (i=fromI-1; i<toJ; i++)
+ activeParts[i] = YES;
+ fromI = toJ = -1;
+ foundDash = NO;
+ }
+ else if (fromI != -1 && toJ == -1 && foundDash == NO && foundComma == YES)
+ {
+ activeParts[fromI-1] = YES;
+ fromI = tempInt;
+ foundComma = NO;
+ }
+
+ expecting = Expecting(COMMA);
+ expecting |= Expecting(DASH);
+ expecting |= Expecting(RIGHTPAR);
+ }
+ else if (expecting == Expecting(DASH))
+ {
+ foundDash = YES;
+ expecting = Expecting(NUMBER);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Tratiopr (tRatioPr) ************************************************************/
+ else if (!strcmp(parmName, "Tratiopr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ flag = 0;
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA))
+ {
+ strcpy(modelParams[i].tRatioPr, tempStr);
+ modelParams[i].tRatioDir[0] = modelParams[i].tRatioDir[1] = 1.0;
+ modelParams[i].tRatioFix = 1.0;
+ flag = 1;
+ }
+ }
+ if (flag == 0)
+ {
+ MrBayesPrint ("%s Warning: %s can be set only for partition containing either DNA or RNA data.\
+ Currently there is no active partition with such data.\n", spacer, parmName);
+ return (ERROR);
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Tratiopr argument \n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(LEFTPAR);
+ for (i=0; i<numCurrentDivisions; i++)
+ numVars[i] = 0;
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA))
+ {
+ if (!strcmp(modelParams[i].tRatioPr,"Beta"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ if (tempD > ALPHA_MAX)
+ {
+ MrBayesPrint ("%s Beta parameter cannot be greater than %1.2lf\n", spacer, ALPHA_MAX);
+ return (ERROR);
+ }
+ if (tempD < ALPHA_MIN)
+ {
+ MrBayesPrint ("%s Beta parameter cannot be less than %1.2lf\n", spacer, ALPHA_MIN);
+ return (ERROR);
+ }
+ modelParams[i].tRatioDir[numVars[i]++] = tempD;
+ if (numVars[i] < 2)
+ expecting = Expecting(COMMA);
+ else
+ {
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Tratiopr to Beta(%1.2lf,%1.2lf)\n", spacer, modelParams[i].tRatioDir[0], modelParams[i].tRatioDir[1]);
+ else
+ MrBayesPrint ("%s Setting Tratiopr to Beta(%1.2lf,%1.2lf) for partition %d\n", spacer, modelParams[i].tRatioDir[0], modelParams[i].tRatioDir[1], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ else if (!strcmp(modelParams[i].tRatioPr,"Fixed"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].tRatioFix = tempD;
+ if (modelParams[i].tRatioFix > KAPPA_MAX)
+ {
+ MrBayesPrint ("%s Tratio cannot be greater than %1.2lf\n", spacer, KAPPA_MAX);
+ return (ERROR);
+ }
+ if (modelParams[i].tRatioFix < 0.0)
+ {
+ MrBayesPrint ("%s Tratio cannot be less than %1.2lf\n", spacer, 0.0);
+ return (ERROR);
+ }
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Tratiopr to Fixed(%1.2lf)\n", spacer, modelParams[i].tRatioFix);
+ else
+ MrBayesPrint ("%s Setting Tratiopr to Fixed(%1.2lf) for partition %d\n", spacer, modelParams[i].tRatioFix, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ }
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Revmatpr (revMatPr) ************************************************************/
+ else if (!strcmp(parmName, "Revmatpr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ flag = 0;
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA))
+ {
+ strcpy(modelParams[i].revMatPr, tempStr);
+ modelParams[i].revMatDir[0] = modelParams[i].revMatDir[1] = 1.0;
+ modelParams[i].revMatDir[2] = modelParams[i].revMatDir[3] = 1.0;
+ modelParams[i].revMatDir[4] = modelParams[i].revMatDir[5] = 1.0;
+ flag = 1;
+ }
+ }
+ if (flag == 0)
+ {
+ MrBayesPrint ("%s Warning: %s can be set only for partition containing either DNA or RNA data.\
+ Currently there is no active partition with such data.\n", spacer, parmName);
+ return (ERROR);
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Revmatpr argument\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(LEFTPAR);
+ tempNumStates = 0;
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ /* find out what type of prior is being set */
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA))
+ strcpy (tempStr,modelParams[i].revMatPr);
+ }
+ /* find and store the number */
+ sscanf (tkn, "%lf", &tempD);
+ if (!strcmp(tempStr,"Dirichlet"))
+ {
+ if (tempD > ALPHA_MAX)
+ {
+ MrBayesPrint ("%s Dirichlet parameter cannot be greater than %1.2lf\n", spacer, ALPHA_MAX);
+ return (ERROR);
+ }
+ if (tempD < ALPHA_MIN)
+ {
+ MrBayesPrint ("%s Dirichlet parameter cannot be less than %1.2lf\n", spacer, ALPHA_MIN);
+ return (ERROR);
+ }
+ }
+ else if (!strcmp(tempStr,"Fixed"))
+ {
+ if (tempD > KAPPA_MAX)
+ {
+ MrBayesPrint ("%s Rate value cannot be greater than %1.2lf\n", spacer, KAPPA_MAX);
+ return (ERROR);
+ }
+ if (tempD < 0.0001)
+ {
+ MrBayesPrint ("%s Rate value cannot be less than %1.2lf\n", spacer, 0.0001);
+ return (ERROR);
+ }
+ }
+ tempNum[tempNumStates++] = tempD;
+ if (tempNumStates == 1 && !strcmp(tempStr,"Dirichlet"))
+ expecting = Expecting(COMMA) | Expecting(RIGHTPAR);
+ else if (tempNumStates < 6)
+ expecting = Expecting(COMMA);
+ else
+ expecting = Expecting(RIGHTPAR);
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA))
+ {
+ if (!strcmp(modelParams[i].revMatPr,"Dirichlet"))
+ {
+ for (j=0; j<6; j++)
+ {
+ if (tempNumStates == 1)
+ modelParams[i].revMatDir[j] = tempNum[0] / (MrBFlt) 6.0;
+ else
+ modelParams[i].revMatDir[j] = tempNum[j];
+ }
+
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Revmatpr to Dirichlet(%1.2lf,%1.2lf,%1.2lf,%1.2lf,%1.2lf,%1.2lf)\n", spacer,
+ modelParams[i].revMatDir[0], modelParams[i].revMatDir[1], modelParams[i].revMatDir[2],
+ modelParams[i].revMatDir[3], modelParams[i].revMatDir[4], modelParams[i].revMatDir[5]);
+ else
+ MrBayesPrint ("%s Setting Revmatpr to Dirichlet(%1.2lf,%1.2lf,%1.2lf,%1.2lf,%1.2lf,%1.2lf) for partition %d\n", spacer,
+ modelParams[i].revMatDir[0], modelParams[i].revMatDir[1], modelParams[i].revMatDir[2],
+ modelParams[i].revMatDir[3], modelParams[i].revMatDir[4], modelParams[i].revMatDir[5], i+1);
+ }
+ else if (!strcmp(modelParams[i].revMatPr,"Fixed"))
+ {
+ for (j=0; j<6; j++)
+ modelParams[i].revMatFix[j] = tempNum[j];
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Revmatpr to Fixed(%1.2lf,%1.2lf,%1.2lf,%1.2lf,%1.2lf,%1.2lf)\n", spacer,
+ modelParams[i].revMatFix[0], modelParams[i].revMatFix[1], modelParams[i].revMatFix[2],
+ modelParams[i].revMatFix[3], modelParams[i].revMatFix[4], modelParams[i].revMatFix[5]);
+ else
+ MrBayesPrint ("%s Setting Revmatpr to Fixed(%1.2lf,%1.2lf,%1.2lf,%1.2lf,%1.2lf,%1.2lf) for partition %d\n", spacer,
+ modelParams[i].revMatFix[0], modelParams[i].revMatFix[1], modelParams[i].revMatFix[2],
+ modelParams[i].revMatFix[3], modelParams[i].revMatFix[4], modelParams[i].revMatFix[5], i+1);
+ }
+ }
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Aarevmatpr (aaRevMatPr) ********************************************************/
+ else if (!strcmp(parmName, "Aarevmatpr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ flag = 0;
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && modelSettings[i].dataType == PROTEIN)
+ {
+ strcpy(modelParams[i].aaRevMatPr, tempStr);
+ for (j=0; j<190; j++)
+ modelParams[i].aaRevMatDir[j] = 1.0;
+ flag = 1;
+ }
+ }
+ if (flag == 0)
+ {
+ MrBayesPrint ("%s Warning: %s can be set only for partition containing PROTEIN.\
+ Currently there is no active partition with such data.\n", spacer, parmName);
+ return (ERROR);
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Aarevmatpr argument\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(LEFTPAR);
+ tempNumStates = 0;
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ /* find out what type of prior is being set */
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && modelSettings[i].dataType == PROTEIN)
+ strcpy (tempStr,modelParams[i].aaRevMatPr);
+ }
+ /* find and store the number */
+ sscanf (tkn, "%lf", &tempD);
+ if (!strcmp(tempStr,"Dirichlet"))
+ {
+ if (tempD > ALPHA_MAX)
+ {
+ MrBayesPrint ("%s Dirichlet parameter cannot be greater than %1.2lf\n", spacer, ALPHA_MAX);
+ return (ERROR);
+ }
+ if (tempD < ALPHA_MIN)
+ {
+ MrBayesPrint ("%s Dirichlet parameter cannot be less than %1.2lf\n", spacer, ALPHA_MIN);
+ return (ERROR);
+ }
+ }
+ else if (!strcmp(tempStr,"Fixed"))
+ {
+ if (tempD > KAPPA_MAX)
+ {
+ MrBayesPrint ("%s Rate value cannot be greater than %1.2lf\n", spacer, KAPPA_MAX);
+ return (ERROR);
+ }
+ if (tempD < 0.0001)
+ {
+ MrBayesPrint ("%s Rate value cannot be less than %1.2lf\n", spacer, 0.0001);
+ return (ERROR);
+ }
+ }
+ tempStateFreqs[tempNumStates++] = tempD;
+ if (tempNumStates == 1 && !strcmp(tempStr,"Dirichlet"))
+ expecting = Expecting(COMMA) | Expecting(RIGHTPAR);
+ else if (tempNumStates < 190)
+ expecting = Expecting(COMMA);
+ else
+ expecting = Expecting(RIGHTPAR);
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && modelParams[i].dataType == PROTEIN)
+ {
+ if (!strcmp(modelParams[i].aaRevMatPr,"Dirichlet"))
+ {
+ for (j=0; j<190; j++)
+ {
+ if (tempNumStates == 1)
+ modelParams[i].aaRevMatDir[j] = tempStateFreqs[0] / (MrBFlt) 190.0;
+ else
+ modelParams[i].aaRevMatDir[j] = tempStateFreqs[j];
+ }
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ {
+ for (j=0; j<190; j++)
+ if (AreDoublesEqual(modelParams[i].aaRevMatDir[0], modelParams[i].aaRevMatDir[j], 0.00001) == NO)
+ break;
+ if (j == 190)
+ MrBayesPrint ("%s Setting Aarevmatpr to Dirichlet(%1.2lf,%1.2lf,...)\n", spacer,
+ modelParams[i].aaRevMatDir[0], modelParams[i].aaRevMatDir[0]);
+ else
+ {
+ MrBayesPrint ("%s Setting Aarevmatpr to Dirichlet(\n", spacer);
+ for (j=0; j<190; j++)
+ {
+ if (j % 10 == 0)
+ MrBayesPrint ("%s ", spacer);
+ MrBayesPrint ("%1.2lf", modelParams[i].aaRevMatDir[j]);
+ if (j == 189)
+ MrBayesPrint (")\n");
+ else if ((j+1) % 10 == 0)
+ MrBayesPrint (",\n");
+ else
+ MrBayesPrint (",");
+ }
+ }
+ }
+ else
+ {
+ for (j=0; j<190; j++)
+ if (AreDoublesEqual(modelParams[i].aaRevMatDir[0], modelParams[i].aaRevMatDir[j], 0.00001) == NO)
+ break;
+ if (j == 190)
+ MrBayesPrint ("%s Setting Aarevmatpr to Dirichlet(%1.2lf,%1.2lf,...) for partition %d\n",
+ spacer, modelParams[i].aaRevMatDir[0], modelParams[i].aaRevMatDir[0], i+1);
+ else
+ {
+ MrBayesPrint ("%s Setting Aarevmatpr to Dirichlet(\n", spacer);
+ for (j=0; j<190; j++)
+ {
+ if (j % 10 == 0)
+ MrBayesPrint ("%s ", spacer);
+ MrBayesPrint ("%1.2lf", modelParams[i].aaRevMatDir[j]);
+ if (j == 189)
+ MrBayesPrint (")\n");
+ else if ((j+1) % 10 == 0)
+ MrBayesPrint (",\n");
+ else
+ MrBayesPrint (",");
+ }
+ }
+ MrBayesPrint ("%s for partition %d\n", spacer, i+1);
+ }
+ }
+ else if (!strcmp(modelParams[i].aaRevMatPr,"Fixed"))
+ {
+ for (j=0; j<190; j++)
+ modelParams[i].aaRevMatFix[j] = tempStateFreqs[j];
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ {
+ for (j=0; j<190; j++)
+ if (AreDoublesEqual(modelParams[i].aaRevMatFix[0], modelParams[i].aaRevMatFix[j], 0.00001) == NO)
+ break;
+ if (j == 190)
+ MrBayesPrint ("%s Setting Aarevmatpr to Fixed(%1.2lf,%1.2lf,...)\n", spacer, modelParams[i].aaRevMatFix[0],
+ modelParams[i].aaRevMatFix[0]);
+ else
+ {
+ MrBayesPrint ("%s Setting Aarevmatpr to Fixed(\n", spacer);
+ for (j=0; j<190; j++)
+ {
+ if (j % 10 == 0)
+ MrBayesPrint ("%s ", spacer);
+ MrBayesPrint ("%1.2lf", modelParams[i].aaRevMatFix[j]);
+ if (j == 189)
+ MrBayesPrint (")\n");
+ else if ((j+1) % 10 == 0)
+ MrBayesPrint (",\n");
+ else
+ MrBayesPrint (",");
+ }
+ }
+ }
+ else
+ {
+ for (j=0; j<190; j++)
+ if (AreDoublesEqual(modelParams[i].aaRevMatFix[0], modelParams[i].aaRevMatFix[j], 0.00001) == NO)
+ break;
+ if (j == 190)
+ MrBayesPrint ("%s Setting Aarevmatpr to Fixed(%1.2lf,%1.2lf,...) for partition %d\n", spacer,
+ modelParams[i].aaRevMatFix[0], modelParams[i].aaRevMatFix[0], i+1);
+ else
+ {
+ MrBayesPrint ("%s Setting Aarevmatpr to Fixed(\n", spacer);
+ for (j=0; j<190; j++)
+ {
+ if (j % 10 == 0)
+ MrBayesPrint ("%s ", spacer);
+ MrBayesPrint ("%1.2lf", modelParams[i].aaRevMatFix[j]);
+ if (j == 189)
+ MrBayesPrint (")\n");
+ else if ((j+1) % 10 == 0)
+ MrBayesPrint (",\n");
+ else
+ MrBayesPrint (",");
+ }
+ }
+ MrBayesPrint ("%s for partition %d\n", spacer, i+1);
+ }
+ }
+ }
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Revratepr (revSymDirPr) ****************************************************/
+ else if (!strcmp(parmName, "Revratepr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == ERROR) /* we only allow symmetric dirichlet prior, so no need to store the value */
+ {
+ MrBayesPrint ("%s Invalid Revratepr argument\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(LEFTPAR);
+ for (i=0; i<numCurrentDivisions; i++)
+ numVars[i] = 0;
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ {
+ sscanf (tkn, "%lf", &tempD);
+ if (tempD <= 0.0)
+ {
+ MrBayesPrint ("%s Symmetric Dirichlet parameter must be positive\n", spacer);
+ return (ERROR);
+ }
+ modelParams[i].revMatSymDir = tempD;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Revratepr to Symmetric Dirichlet(%1.2lf)\n", spacer, modelParams[i].revMatSymDir);
+ else
+ MrBayesPrint ("%s Setting Revratepr to Symmetric Dirichlet(%1.2lf) for partition %d\n", spacer, modelParams[i].revMatSymDir, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Omegapr (omegaPr) **************************************************************/
+ else if (!strcmp(parmName, "Omegapr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ flag = 0;
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA))
+ {
+ strcpy(modelParams[i].omegaPr, tempStr);
+ modelParams[i].omegaDir[0] = modelParams[i].omegaDir[1] = 1.0;
+ modelParams[i].omegaFix = 1.0;
+ flag = 1;
+ }
+ }
+ if (flag == 0)
+ {
+ MrBayesPrint ("%s Warning: %s can be set only for partition containing either DNA or RNA data.\
+ Currently there is no active partition with such data.\n", spacer, parmName);
+ return (ERROR);
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Omegapr argument\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(LEFTPAR);
+ for (i=0; i<numCurrentDivisions; i++)
+ numVars[i] = 0;
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA))
+ {
+ if (!strcmp(modelParams[i].omegaPr,"Dirichlet"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ if (tempD > ALPHA_MAX)
+ {
+ MrBayesPrint ("%s Dirichlet parameter cannot be greater than %1.2lf\n", spacer, ALPHA_MAX);
+ return (ERROR);
+ }
+ if (tempD < ALPHA_MIN)
+ {
+ MrBayesPrint ("%s Dirichlet parameter cannot be less than %1.2lf\n", spacer, ALPHA_MIN);
+ return (ERROR);
+ }
+ modelParams[i].omegaDir[numVars[i]++] = tempD;
+ if (numVars[i] == 1)
+ expecting = Expecting(COMMA);
+ else
+ {
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Omegapr to Dirichlet(%1.2lf,%1.2lf)\n", spacer, modelParams[i].omegaDir[0], modelParams[i].omegaDir[1]);
+ else
+ MrBayesPrint ("%s Setting Omegapr to Dirichlet(%1.2lf,%1.2lf) for partition %d\n", spacer, modelParams[i].omegaDir[0], modelParams[i].omegaDir[1], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ else if (!strcmp(modelParams[i].omegaPr,"Fixed"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].omegaFix = tempD;
+ if (modelParams[i].omegaFix > KAPPA_MAX)
+ {
+ MrBayesPrint ("%s Omega ratio cannot be greater than %1.2lf\n", spacer, KAPPA_MAX);
+ return (ERROR);
+ }
+ if (modelParams[i].omegaFix < 0.0)
+ {
+ MrBayesPrint ("%s Omega ratio cannot be less than %1.2lf\n", spacer, 0.0);
+ return (ERROR);
+ }
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Omegapr to Fixed(%1.2lf)\n", spacer, modelParams[i].omegaFix);
+ else
+ MrBayesPrint ("%s Setting Omegapr to Fixed(%1.2lf) for partition %d\n", spacer, modelParams[i].omegaFix, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ }
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Ny98omega1pr (ny98omega1pr) ********************************************************/
+ else if (!strcmp(parmName, "Ny98omega1pr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ flag = 0;
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA))
+ {
+ strcpy(modelParams[i].ny98omega1pr, tempStr);
+ flag = 1;
+ }
+ }
+ if (flag == 0)
+ {
+ MrBayesPrint ("%s Warning: %s can be set only for partition containing either DNA or RNA data.\
+ Currently there is no active partition with such data. The setting is ignored.\n", spacer, parmName);
+ return (ERROR);
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Ny98omega1pr argument\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(LEFTPAR);
+ for (i=0; i<numCurrentDivisions; i++)
+ numVars[i] = 0;
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA))
+ {
+ if (!strcmp(modelParams[i].ny98omega1pr,"Beta"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].ny98omega1Beta[numVars[i]++] = tempD;
+ if (numVars[i] == 1)
+ expecting = Expecting(COMMA);
+ else
+ {
+ if (modelParams[i].ny98omega1Beta[0] < 0 || modelParams[i].ny98omega1Beta[1] < 0)
+ {
+ MrBayesPrint ("%s Beta parameter should be greater than 0\n", spacer);
+ return (ERROR);
+ }
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Ny98omega1pr to Beta(%1.2lf,%1.2lf)\n", spacer, modelParams[i].ny98omega1Beta[0], modelParams[i].ny98omega1Beta[1]);
+ else
+ MrBayesPrint ("%s Setting Ny98omega1pr to Beta(%1.2lf,%1.2lf) for partition %d\n", spacer, modelParams[i].ny98omega1Beta[0], modelParams[i].ny98omega1Beta[1], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ else if (!strcmp(modelParams[i].ny98omega1pr,"Fixed"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].ny98omega1Fixed = tempD;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Ny98omega1pr to Fixed(%1.2lf)\n", spacer, modelParams[i].ny98omega1Fixed);
+ else
+ MrBayesPrint ("%s Setting Ny98omega1pr to Fixed(%1.2lf) for partition %d\n", spacer, modelParams[i].ny98omega1Fixed, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ }
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Ny98omega3pr (ny98omega3pr) ********************************************************/
+ else if (!strcmp(parmName, "Ny98omega3pr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ flag = 0;
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA))
+ {
+ strcpy(modelParams[i].ny98omega3pr, tempStr);
+ flag = 1;
+ }
+ }
+ if (flag == 0)
+ {
+ MrBayesPrint ("%s Warning: %s can be set only for partition containing either DNA or RNA data.\
+ Currently there is no active partition with such data. The setting is ignored.\n", spacer, parmName);
+ return (ERROR);
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Ny98omega3pr argument\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(LEFTPAR);
+ for (i=0; i<numCurrentDivisions; i++)
+ numVars[i] = 0;
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA))
+ {
+ if (!strcmp(modelParams[i].ny98omega3pr,"Uniform"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].ny98omega3Uni[numVars[i]++] = tempD;
+ if (numVars[i] == 1)
+ expecting = Expecting(COMMA);
+ else
+ {
+ if (modelParams[i].ny98omega3Uni[0] >= modelParams[i].ny98omega3Uni[1])
+ {
+ MrBayesPrint ("%s Lower value for uniform should be greater than upper value\n", spacer);
+ return (ERROR);
+ }
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Ny98omega3pr to Uniform(%1.2lf,%1.2lf)\n", spacer, modelParams[i].ny98omega3Uni[0], modelParams[i].ny98omega3Uni[1]);
+ else
+ MrBayesPrint ("%s Setting Ny98omega3pr to Uniform(%1.2lf,%1.2lf) for partition %d\n", spacer, modelParams[i].ny98omega3Uni[0], modelParams[i].ny98omega3Uni[1], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ else if (!strcmp(modelParams[i].ny98omega3pr,"Exponential"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].ny98omega3Exp = tempD;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Ny98omega3pr to Exponential(%1.2lf)\n", spacer, modelParams[i].ny98omega3Exp);
+ else
+ MrBayesPrint ("%s Setting Ny98omega3pr to Exponential(%1.2lf) for partition %d\n", spacer, modelParams[i].ny98omega3Exp, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ else if (!strcmp(modelParams[i].ny98omega3pr,"Fixed"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].ny98omega3Fixed = tempD;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Ny98omega3pr to Fixed(%1.2lf)\n", spacer, modelParams[i].ny98omega3Fixed);
+ else
+ MrBayesPrint ("%s Setting Ny98omega3pr to Fixed(%1.2lf) for partition %d\n", spacer, modelParams[i].ny98omega3Fixed, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ }
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set M3omegapr (m3omegapr) ********************************************************/
+ else if (!strcmp(parmName, "M3omegapr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ flag = 0;
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA))
+ {
+ strcpy(modelParams[i].m3omegapr, tempStr);
+ flag = 1;
+ }
+ }
+ if (flag == 0)
+ {
+ MrBayesPrint ("%s Warning: %s can be set only for partition containing either DNA or RNA data.\
+ Currently there is no active partition with such data. The setting is ignored.\n", spacer, parmName);
+ return (ERROR);
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid M3omegapr argument\n", spacer);
+ return (ERROR);
+ }
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA))
+ {
+ if (!strcmp(modelParams[i].m3omegapr,"Exponential"))
+ {
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting M3omegapr to Exponential\n", spacer);
+ else
+ MrBayesPrint ("%s Setting M3omegapr to Exponential for partition %d\n", spacer, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ }
+ if (!strcmp(tempStr,"Exponential"))
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ else
+ expecting = Expecting(LEFTPAR);
+ for (i=0; i<numCurrentDivisions; i++)
+ numVars[i] = 0;
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA))
+ {
+ if (!strcmp(modelParams[i].m3omegapr,"Fixed"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].m3omegaFixed[numVars[i]++] = tempD;
+ if (numVars[i] == 1 || numVars[i] == 2)
+ expecting = Expecting(COMMA);
+ else
+ {
+ if (modelParams[i].m3omegaFixed[0] >= modelParams[i].m3omegaFixed[1] || modelParams[i].m3omegaFixed[0] >= modelParams[i].m3omegaFixed[2] || modelParams[i].m3omegaFixed[1] >= modelParams[i].m3omegaFixed[2])
+ {
+ MrBayesPrint ("%s The three omega values must be ordered, such that omega1 < omega2 < omega3\n", spacer);
+ return (ERROR);
+ }
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting M3omegapr to Fixed(%1.2lf,%1.2lf,%1.2lf)\n", spacer, modelParams[i].m3omegaFixed[0], modelParams[i].m3omegaFixed[1], modelParams[i].m3omegaFixed[2]);
+ else
+ MrBayesPrint ("%s Setting M3omegapr to Fixed(%1.2lf,%1.2lf,%1.2lf) for partition %d\n", spacer, modelParams[i].m3omegaFixed[0], modelParams[i].m3omegaFixed[1], modelParams[i].m3omegaFixed[2], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ }
+ }
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Codoncatfreqs (codonCatFreqPr) ********************************************************/
+ else if (!strcmp(parmName, "Codoncatfreqs"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ flag = 0;
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA))
+ {
+ strcpy(modelParams[i].codonCatFreqPr, tempStr);
+ flag = 1;
+ }
+ }
+ if (flag == 0)
+ {
+ MrBayesPrint ("%s Warning: %s can be set only for partition containing either DNA or RNA data.\
+ Currently there is no active partition with such data. The setting is ignored.\n", spacer, parmName);
+ return (ERROR);
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Omegapurpr argument\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(LEFTPAR);
+ for (i=0; i<numCurrentDivisions; i++)
+ numVars[i] = 0;
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA))
+ {
+ if (!strcmp(modelParams[i].codonCatFreqPr,"Dirichlet"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].codonCatDir[numVars[i]++] = tempD;
+ if (numVars[i] == 1 || numVars[i] == 2)
+ expecting = Expecting(COMMA);
+ else
+ {
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Codoncatfreqs prior to Dirichlet(%1.2lf,%1.2lf,%1.2lf)\n", spacer, modelParams[i].codonCatDir[0], modelParams[i].codonCatDir[1], modelParams[i].codonCatDir[2]);
+ else
+ MrBayesPrint ("%s Setting Codoncatfreqs prior to Dirichlet(%1.2lf,%1.2lf) for partition %d\n", spacer, modelParams[i].codonCatDir[0], modelParams[i].codonCatDir[1], modelParams[i].codonCatDir[2], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ else if (!strcmp(modelParams[i].codonCatFreqPr,"Fixed"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].codonCatFreqFix[numVars[i]++] = tempD;
+ if (numVars[i] == 1 || numVars[i] == 2)
+ expecting = Expecting(COMMA);
+ else
+ {
+ if (AreDoublesEqual (modelParams[i].codonCatFreqFix[0] + modelParams[i].codonCatFreqFix[1] + modelParams[i].codonCatFreqFix[2], (MrBFlt) 1.0, (MrBFlt) 0.001) == NO)
+ {
+ MrBayesPrint ("%s Codon category frequencies must sum to 1\n", spacer);
+ return (ERROR);
+ }
+
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Codoncatfreqs prior to Fixed(%1.2lf,%1.2lf,%1.2lf)\n", spacer, modelParams[i].codonCatFreqFix[0], modelParams[i].codonCatFreqFix[1], modelParams[i].codonCatFreqFix[2]);
+ else
+ MrBayesPrint ("%s Setting Codoncatfreqs prior to Fixed(%1.2lf,%1.2lf) for partition %d\n", spacer, modelParams[i].codonCatFreqFix[0], modelParams[i].codonCatFreqFix[1], modelParams[i].codonCatFreqFix[2], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ }
+ }
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+
+ /* set Shapepr (shapePr) **************************************************************/
+ else if (!strcmp(parmName, "Shapepr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ flag = 0;
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA || modelParams[i].dataType == PROTEIN || modelParams[i].dataType == RESTRICTION || modelParams[i].dataType == STANDARD))
+ {
+ strcpy(modelParams[i].shapePr, tempStr);
+ flag = 1;
+ }
+ }
+ if (flag == 0)
+ {
+ MrBayesPrint ("%s Warning: %s can be set only for partition containing data of at least one of following type: DNA, RNA, PROTEIN, RESTRICTION, STANDARD.\
+ Currently there is no active partition with such data.\n", spacer, parmName);
+ return (ERROR);
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Shapepr argument\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(LEFTPAR);
+ for (i=0; i<numCurrentDivisions; i++)
+ numVars[i] = 0;
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA || modelParams[i].dataType == PROTEIN || modelParams[i].dataType == RESTRICTION || modelParams[i].dataType == STANDARD))
+ {
+ if (!strcmp(modelParams[i].shapePr,"Uniform"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].shapeUni[numVars[i]++] = tempD;
+ if (numVars[i] == 1)
+ expecting = Expecting(COMMA);
+ else
+ {
+ if (modelParams[i].shapeUni[0] >= modelParams[i].shapeUni[1])
+ {
+ MrBayesPrint ("%s Lower value for uniform should be greater than upper value\n", spacer);
+ return (ERROR);
+ }
+ if (modelParams[i].shapeUni[1] > MAX_SHAPE_PARAM)
+ {
+ MrBayesPrint ("%s Upper value for uniform cannot be greater than %1.2lf\n", spacer, MAX_SHAPE_PARAM);
+ return (ERROR);
+ }
+ if (modelParams[i].shapeUni[0] < MIN_SHAPE_PARAM)
+ {
+ MrBayesPrint ("%s Lower value for uniform cannot be less than %1.2lf\n", spacer, MIN_SHAPE_PARAM);
+ return (ERROR);
+ }
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Shapepr to Uniform(%1.2lf,%1.2lf)\n", spacer, modelParams[i].shapeUni[0], modelParams[i].shapeUni[1]);
+ else
+ MrBayesPrint ("%s Setting Shapepr to Uniform(%1.2lf,%1.2lf) for partition %d\n", spacer, modelParams[i].shapeUni[0], modelParams[i].shapeUni[1], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ else if (!strcmp(modelParams[i].shapePr,"Exponential"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].shapeExp = tempD;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Shapepr to Exponential(%1.2lf)\n", spacer, modelParams[i].shapeExp);
+ else
+ MrBayesPrint ("%s Setting Shapepr to Exponential(%1.2lf) for partition %d\n", spacer, modelParams[i].shapeExp, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ else if (!strcmp(modelParams[i].shapePr,"Fixed"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].shapeFix = tempD;
+ if (modelParams[i].shapeFix > MAX_SHAPE_PARAM)
+ {
+ MrBayesPrint ("%s Shape parameter cannot be greater than %1.2lf\n", spacer, MAX_SHAPE_PARAM);
+ return (ERROR);
+ }
+ if (modelParams[i].shapeFix < MIN_SHAPE_PARAM)
+ {
+ MrBayesPrint ("%s Shape parameter cannot be less than %1.2lf\n", spacer, MIN_SHAPE_PARAM);
+ return (ERROR);
+ }
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Shapepr to Fixed(%1.2lf)\n", spacer, modelParams[i].shapeFix);
+ else
+ MrBayesPrint ("%s Setting Shapepr to Fixed(%1.2lf) for partition %d\n", spacer, modelParams[i].shapeFix, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ }
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Pinvarpr (pInvarPr) ************************************************************/
+ else if (!strcmp(parmName, "Pinvarpr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ flag = 0;
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA || modelParams[i].dataType == PROTEIN))
+ {
+ strcpy(modelParams[i].pInvarPr, tempStr);
+ flag = 1;
+ }
+ }
+ if (flag == 0)
+ {
+ MrBayesPrint ("%s Warning: %s can be set only for partition containing data of at least one of the following type: DNA, RNA, PROTEIN.\
+ Currently there is no active partition with such data.\n", spacer, parmName);
+ return (ERROR);
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Pinvarpr argument\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(LEFTPAR);
+ for (i=0; i<numCurrentDivisions; i++)
+ numVars[i] = 0;
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA || modelParams[i].dataType == PROTEIN))
+ {
+ if (!strcmp(modelParams[i].pInvarPr,"Uniform"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].pInvarUni[numVars[i]++] = tempD;
+ if (numVars[i] == 1)
+ expecting = Expecting(COMMA);
+ else
+ {
+ if (modelParams[i].pInvarUni[0] >= modelParams[i].pInvarUni[1])
+ {
+ MrBayesPrint ("%s Lower value for uniform should be greater than upper value\n", spacer);
+ return (ERROR);
+ }
+ if (modelParams[i].pInvarUni[1] > 1.0)
+ {
+ MrBayesPrint ("%s Upper value for uniform should be less than or equal to 1.0\n", spacer);
+ return (ERROR);
+ }
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Pinvarpr to Uniform(%1.2lf,%1.2lf)\n", spacer, modelParams[i].pInvarUni[0], modelParams[i].pInvarUni[1]);
+ else
+ MrBayesPrint ("%s Setting Pinvarpr to Uniform(%1.2lf,%1.2lf) for partition %d\n", spacer, modelParams[i].pInvarUni[0], modelParams[i].pInvarUni[1], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ else if (!strcmp(modelParams[i].pInvarPr,"Fixed"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ if (tempD > 1.0)
+ {
+ MrBayesPrint ("%s Value for Pinvar should be in the interval (0, 1)\n", spacer);
+ return (ERROR);
+ }
+ modelParams[i].pInvarFix = tempD;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Pinvarpr to Fixed(%1.2lf)\n", spacer, modelParams[i].pInvarFix);
+ else
+ MrBayesPrint ("%s Setting Pinvarpr to Fixed(%1.2lf) for partition %d\n", spacer, modelParams[i].pInvarFix, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ }
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Ratecorrpr (adGammaCorPr) ******************************************************/
+ else if (!strcmp(parmName, "Ratecorrpr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ flag = 0;
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA))
+ {
+ strcpy(modelParams[i].adGammaCorPr, tempStr);
+ flag = 1;
+ }
+ }
+ if (flag == 0)
+ {
+ MrBayesPrint ("%s Warning: %s can be set only for partition containing data of at least one of the following type: DNA, RNA.\
+ Currently there is no active partition with such data.\n", spacer, parmName);
+ return (ERROR);
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Ratecorrpr argument\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(LEFTPAR);
+ for (i=0; i<numCurrentDivisions; i++)
+ numVars[i] = 0;
+ foundDash = NO;
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ expecting = Expecting(NUMBER) | Expecting(DASH);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA))
+ {
+ if (!strcmp(modelParams[i].adGammaCorPr,"Uniform"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ if (foundDash == YES)
+ tempD *= -1.0;
+ modelParams[i].corrUni[numVars[i]++] = tempD;
+ if (numVars[i] == 1)
+ expecting = Expecting(COMMA);
+ else
+ {
+ if (modelParams[i].corrUni[0] >= modelParams[i].corrUni[1])
+ {
+ MrBayesPrint ("%s Lower value for uniform should be greater than upper value\n", spacer);
+ return (ERROR);
+ }
+ if (modelParams[i].corrUni[1] > 1.0)
+ {
+ MrBayesPrint ("%s Upper value for uniform should be less than or equal to 1.0\n", spacer);
+ return (ERROR);
+ }
+ if (modelParams[i].corrUni[0] < -1.0)
+ {
+ MrBayesPrint ("%s Lower value for uniform should be greater than or equal to -1.0\n", spacer);
+ return (ERROR);
+ }
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Ratecorrpr to Uniform(%1.2lf,%1.2lf)\n", spacer, modelParams[i].corrUni[0], modelParams[i].corrUni[1]);
+ else
+ MrBayesPrint ("%s Setting Ratecorrpr to Uniform(%1.2lf,%1.2lf) for partition %d\n", spacer, modelParams[i].corrUni[0], modelParams[i].corrUni[1], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ else if (!strcmp(modelParams[i].adGammaCorPr,"Fixed"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ if (foundDash == YES)
+ tempD *= -1.0;
+ if (tempD > 1.0 || tempD < -1.0)
+ {
+ MrBayesPrint ("%s Value for Ratecorrpr should be in the interval (-1, +1)\n", spacer);
+ return (ERROR);
+ }
+ modelParams[i].corrFix = tempD;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Ratecorrpr to Fixed(%1.2lf)\n", spacer, modelParams[i].corrFix);
+ else
+ MrBayesPrint ("%s Setting Ratecorrpr to Fixed(%1.2lf) for partition %d\n", spacer, modelParams[i].corrFix, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ }
+ foundDash = NO;
+ }
+ else if (expecting == Expecting(DASH))
+ {
+ foundDash = YES;
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ expecting = Expecting(NUMBER) | Expecting(DASH);
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Browncorrpr (brownCorPr) ******************************************************/
+ else if (!strcmp(parmName, "Browncorrpr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ flag = 0;
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && modelParams[i].dataType == CONTINUOUS)
+ {
+ strcpy(modelParams[i].brownCorPr, tempStr);
+ flag = 1;
+ }
+ }
+ if (flag == 0)
+ {
+ MrBayesPrint ("%s Warning: %s can be set only for partition containing CONTINUOUS data.\
+ Currently there is no active partition with such data.\n", spacer, parmName);
+ return (ERROR);
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Browncorrpr argument\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(LEFTPAR);
+ for (i=0; i<numCurrentDivisions; i++)
+ numVars[i] = 0;
+ foundDash = NO;
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ expecting = Expecting(NUMBER) | Expecting(DASH);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && modelParams[i].dataType == CONTINUOUS)
+ {
+ if (!strcmp(modelParams[i].brownCorPr,"Uniform"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ if (foundDash == YES)
+ tempD *= -1.0;
+ modelParams[i].brownCorrUni[numVars[i]++] = tempD;
+ if (numVars[i] == 1)
+ expecting = Expecting(COMMA);
+ else
+ {
+ if (modelParams[i].brownCorrUni[0] >= modelParams[i].brownCorrUni[1])
+ {
+ MrBayesPrint ("%s Lower value for uniform should be greater than upper value\n", spacer);
+ return (ERROR);
+ }
+ if (modelParams[i].brownCorrUni[1] > 1.0)
+ {
+ MrBayesPrint ("%s Upper value for uniform should be less than or equal to 1.0\n", spacer);
+ return (ERROR);
+ }
+ if (modelParams[i].brownCorrUni[0] < -1.0)
+ {
+ MrBayesPrint ("%s Lower value for uniform should be greater than or equal to -1.0\n", spacer);
+ return (ERROR);
+ }
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Browncorrpr to Uniform(%1.2lf,%1.2lf)\n", spacer, modelParams[i].brownCorrUni[0], modelParams[i].brownCorrUni[1]);
+ else
+ MrBayesPrint ("%s Setting Browncorrpr to Uniform(%1.2lf,%1.2lf) for partition %d\n", spacer, modelParams[i].brownCorrUni[0], modelParams[i].brownCorrUni[1], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ else if (!strcmp(modelParams[i].brownCorPr,"Fixed"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ if (foundDash == YES)
+ tempD *= -1.0;
+ if (tempD > 1.0 || tempD < -1.0)
+ {
+ MrBayesPrint ("%s Value for Browncorrpr should be in the interval (-1, +1)\n", spacer);
+ return (ERROR);
+ }
+ modelParams[i].brownCorrFix = tempD;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Browncorrpr to Fixed(%1.2lf)\n", spacer, modelParams[i].brownCorrFix);
+ else
+ MrBayesPrint ("%s Setting Browncorrpr to Fixed(%1.2lf) for partition %d\n", spacer, modelParams[i].brownCorrFix, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ }
+ foundDash = NO;
+ }
+ else if (expecting == Expecting(DASH))
+ {
+ foundDash = YES;
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ expecting = Expecting(NUMBER) | Expecting(DASH);
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Ratepr (ratePr) *****************************************************************/
+ else if (!strcmp(parmName, "Ratepr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && modelParams[i].dataType != CONTINUOUS)
+ {
+ if (!strcmp(tempStr,"Variable"))
+ strcpy(modelParams[i].ratePr, "Dirichlet");
+ else
+ strcpy(modelParams[i].ratePr, tempStr);
+ modelParams[i].ratePrDir = 1.0;
+ if (!strcmp(tempStr,"Variable") || !strcmp(tempStr,"Fixed"))
+ {
+ if (tempStr[0]=='V')
+ strcat (tempStr," [Dirichlet(..,1,..)]");
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Ratepr to %s\n", spacer, tempStr);
+ else
+ MrBayesPrint ("%s Setting Ratepr to %s for partition %d\n", spacer, tempStr, i+1);
+ if (tempStr[0]=='V')
+ strcpy (tempStr,"Variable");
+ }
+ }
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Ratepr argument\n", spacer);
+ return (ERROR);
+ }
+ if (!strcmp(tempStr,"Fixed") || !strcmp(tempStr,"Variable"))
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ else
+ expecting = Expecting(LEFTPAR);
+ for (i=0; i<numCurrentDivisions; i++)
+ numVars[i] = 0;
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ expecting = Expecting (NUMBER);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ /* find next partition to fill in */
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ if ((activeParts[i] == YES || nApplied == 0) && numVars[i] == 0)
+ break;
+ if (i == numCurrentDivisions)
+ {
+ MrBayesPrint ("%s Could not find first ratemultiplier partition\n", spacer);
+ return (ERROR);
+ }
+ numVars[i] = 1;
+ /* read in the parameter */
+ sscanf (tkn, "%lf", &tempD);
+ if (tempD < ALPHA_MIN || tempD > ALPHA_MAX)
+ {
+ MrBayesPrint ("%s Ratemultiplier Dirichlet parameter %lf out of range\n", spacer, tempD);
+ return (ERROR);
+ }
+ /* set the parameter */
+ modelParams[i].ratePrDir = tempD;
+ /* check if all partitions have been filled in */
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && numVars[i] == 0)
+ break;
+ }
+ /* set expecting accordingly so that we know what should be coming next */
+ if (i == numCurrentDivisions)
+ expecting = Expecting (RIGHTPAR);
+ else
+ expecting = Expecting (COMMA);
+ }
+ else if (expecting == Expecting (COMMA))
+ expecting = Expecting (NUMBER);
+ else if (expecting == Expecting (RIGHTPAR))
+ {
+ /* print message */
+ for (i=j=0; i<numCurrentDivisions; i++)
+ {
+ if (numVars[i] == 1)
+ {
+ j++;
+ if (j == 1)
+ {
+ MrBayesPrint ("%s Setting Ratepr to Dirichlet(%1.2f",
+ spacer, modelParams[i].ratePrDir);
+ }
+ else
+ MrBayesPrint(",%1.2f", modelParams[i].ratePrDir);
+ }
+ }
+ if (numCurrentDivisions == 1)
+ MrBayesPrint (")\n");
+ else
+ {
+ MrBayesPrint (") for partition");
+ if (j > 1)
+ MrBayesPrint ("s");
+ for (i=k=0; i<numCurrentDivisions; i++)
+ {
+ if (numVars[i] == 1)
+ {
+ k++;
+ if (k == j && j > 1)
+ MrBayesPrint (", and %d", i+1);
+ else if (k == 1)
+ MrBayesPrint (" %d", i+1);
+ else
+ MrBayesPrint (", %d", i+1);
+ }
+ }
+ MrBayesPrint ("\n");
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Generatepr (generatePr) *****************************************************************/
+ else if (!strcmp(parmName, "Generatepr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && modelParams[i].dataType != CONTINUOUS)
+ {
+ if (!strcmp(tempStr,"Variable"))
+ strcpy(modelParams[i].generatePr, "Dirichlet");
+ else
+ strcpy(modelParams[i].generatePr, tempStr);
+ modelParams[i].generatePrDir = 1.0;
+ if (!strcmp(tempStr,"Variable") || !strcmp(tempStr,"Fixed"))
+ {
+ if (tempStr[0]=='V')
+ strcat (tempStr," [Dirichlet(..,1,..)]");
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Generatepr to %s\n", spacer, tempStr);
+ else
+ MrBayesPrint ("%s Setting Generatepr to %s for partition %d\n", spacer, tempStr, i+1);
+ if (tempStr[0]=='V')
+ strcpy (tempStr,"Variable");
+ }
+ }
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Generatepr argument\n", spacer);
+ return (ERROR);
+ }
+ if (!strcmp(tempStr,"Fixed") || !strcmp(tempStr,"Variable"))
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ else
+ expecting = Expecting(LEFTPAR);
+ for (i=0; i<numCurrentDivisions; i++)
+ numVars[i] = 0;
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ expecting = Expecting (NUMBER);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ /* find next partition to fill in */
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ if ((activeParts[i] == YES || nApplied == 0) && numVars[i] == 0)
+ break;
+ if (i == numCurrentDivisions)
+ {
+ MrBayesPrint ("%s Could not find first generate multiplier partition\n", spacer);
+ return (ERROR);
+ }
+ numVars[i] = 1;
+ /* read in the parameter */
+ sscanf (tkn, "%lf", &tempD);
+ if (tempD < ALPHA_MIN || tempD > ALPHA_MAX)
+ {
+ MrBayesPrint ("%s Generate multiplier Dirichlet parameter %lf out of range\n", spacer, tempD);
+ return (ERROR);
+ }
+ /* set the parameter */
+ modelParams[i].generatePrDir = tempD;
+ /* check if all partitions have been filled in */
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && numVars[i] == 0)
+ break;
+ }
+ /* set expecting accordingly so that we know what should be coming next */
+ if (i == numCurrentDivisions)
+ expecting = Expecting (RIGHTPAR);
+ else
+ expecting = Expecting (COMMA);
+ }
+ else if (expecting == Expecting (COMMA))
+ expecting = Expecting (NUMBER);
+ else if (expecting == Expecting (RIGHTPAR))
+ {
+ /* print message */
+ for (i=j=0; i<numCurrentDivisions; i++)
+ {
+ if (numVars[i] == 1)
+ {
+ j++;
+ if (j == 1)
+ {
+ MrBayesPrint ("%s Setting Generatepr to Dirichlet(%1.2f",
+ spacer, modelParams[i].generatePrDir);
+ }
+ else
+ MrBayesPrint(",%1.2f", modelParams[i].generatePrDir);
+ }
+ }
+ if (numCurrentDivisions == 1)
+ MrBayesPrint (")\n");
+ else
+ {
+ MrBayesPrint (") for partition");
+ if (j > 1)
+ MrBayesPrint ("s");
+ for (i=k=0; i<numCurrentDivisions; i++)
+ {
+ if (numVars[i] == 1)
+ {
+ k++;
+ if (k == j && j > 1)
+ MrBayesPrint (", and %d", i+1);
+ else if (k == 1)
+ MrBayesPrint (" %d", i+1);
+ else
+ MrBayesPrint (", %d", i+1);
+ }
+ }
+ MrBayesPrint ("\n");
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Covswitchpr (covSwitchPr) ******************************************************/
+ else if (!strcmp(parmName, "Covswitchpr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ flag = 0;
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA || modelParams[i].dataType == PROTEIN))
+ {
+ strcpy(modelParams[i].covSwitchPr, tempStr);
+ flag = 1;
+ }
+ }
+ if (flag == 0)
+ {
+ MrBayesPrint ("%s Warning: %s can be set only for partition containing data of at least one of the following type: DNA, RNA, PROTEIN.\
+ Currently there is no active partition with such data. ", spacer, parmName);
+ return (ERROR);
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Covswitchpr argument\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(LEFTPAR);
+ for (i=0; i<numCurrentDivisions; i++)
+ numVars[i] = 0;
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA || modelParams[i].dataType == PROTEIN))
+ {
+ if (!strcmp(modelParams[i].covSwitchPr,"Uniform"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].covswitchUni[numVars[i]++] = tempD;
+ if (numVars[i] == 1)
+ expecting = Expecting(COMMA);
+ else
+ {
+ if (modelParams[i].covswitchUni[0] >= modelParams[i].covswitchUni[1])
+ {
+ MrBayesPrint ("%s Lower value for uniform should be greater than upper value\n", spacer);
+ return (ERROR);
+ }
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Covswitchpr to Uniform(%1.2lf,%1.2lf)\n", spacer, modelParams[i].covswitchUni[0], modelParams[i].covswitchUni[1]);
+ else
+ MrBayesPrint ("%s Setting Covswitchpr to Uniform(%1.2lf,%1.2lf) for partition %d\n", spacer, modelParams[i].covswitchUni[0], modelParams[i].covswitchUni[1], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ else if (!strcmp(modelParams[i].covSwitchPr,"Exponential"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].covswitchExp = tempD;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Covswitchpr to Exponential(%1.2lf)\n", spacer, modelParams[i].covswitchExp);
+ else
+ MrBayesPrint ("%s Setting Covswitchpr to Exponential(%1.2lf) for partition %d\n", spacer, modelParams[i].covswitchExp, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ else if (!strcmp(modelParams[i].covSwitchPr,"Fixed"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].covswitchFix[numVars[i]++] = tempD;
+ if (numVars[i] == 1)
+ expecting = Expecting(COMMA);
+ else
+ {
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Covswitchpr to Fixed(%1.4lf,%1.4lf)\n", spacer, modelParams[i].covswitchFix[0], modelParams[i].covswitchFix[1]);
+ else
+ MrBayesPrint ("%s Setting Covswitchpr to Fixed(%1.4lf,%1.4lf) for partition %d\n", spacer, modelParams[i].covswitchFix[0], modelParams[i].covswitchFix[1], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ }
+ }
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Symdirihyperpr (symPiPr) ******************************************************/
+ else if (!strcmp(parmName, "Symdirihyperpr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ {
+ foundBeta = NO;
+ expecting = Expecting(ALPHA);
+ }
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (foundBeta == NO)
+ {
+ /* expecting to see Uniform, Exponential, or Fixed */
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ flag = 0;
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == STANDARD || modelParams[i].dataType == RESTRICTION))
+ {
+ strcpy(modelParams[i].symPiPr, tempStr);
+ flag = 1;
+ }
+ }
+ if (flag == 0)
+ {
+ MrBayesPrint ("%s Warning: %s can be set only for partition containing data", spacer, parmName);
+ MrBayesPrint (" of at least one of the following type: STANDARD, RESTRICTION.");
+ MrBayesPrint ("Currently there is no active partition with such data. ");
+ return (ERROR);
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Symdirihyperpr argument\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(LEFTPAR);
+ for (i=0; i<numCurrentDivisions; i++)
+ numVars[i] = 0;
+ foundBeta = YES;
+ }
+ else
+ {
+ /* expecting infinity */
+ if (IsSame("Infinity", tkn) == SAME || IsSame("Infinity", tkn) == CONSISTENT_WITH)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == STANDARD || modelParams[i].dataType == RESTRICTION))
+ {
+ if (!strcmp(modelParams[i].symPiPr, "Fixed"))
+ {
+ modelParams[i].symBetaFix = -1;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Symdirihyperpr to Beta(Infinity)\n", spacer);
+ else
+ MrBayesPrint ("%s Setting Symdirihyperpr to Beta(Infinity) for partition %d\n", spacer, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ else
+ {
+ MrBayesPrint ("%s Problem setting Symdirihyperpr\n", spacer);
+ return (ERROR);
+ }
+ }
+ }
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ expecting = Expecting(NUMBER) | Expecting(ALPHA);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == STANDARD || modelParams[i].dataType == RESTRICTION))
+ {
+ if (!strcmp(modelParams[i].symPiPr,"Fixed"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].symBetaFix = tempD;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Symdirihyperpr to Fixed(%1.2lf)\n", spacer, modelParams[i].symBetaFix);
+ else
+ MrBayesPrint ("%s Setting Symdirihyperpr to Fixed(%1.2lf) for partition %d\n", spacer, modelParams[i].symBetaFix, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ else if (!strcmp(modelParams[i].symPiPr,"Exponential"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].symBetaExp = tempD;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Symdirihyperpr to Exponential(%1.2lf)\n", spacer, modelParams[i].symBetaExp);
+ else
+ MrBayesPrint ("%s Setting Symdirihyperpr to Exponential(%1.2lf) for partition %d\n", spacer, modelParams[i].symBetaExp, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ else if (!strcmp(modelParams[i].symPiPr,"Uniform"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].symBetaUni[numVars[i]++] = tempD;
+ if (numVars[i] == 1)
+ expecting = Expecting(COMMA);
+ else
+ {
+ if (modelParams[i].symBetaUni[0] >= modelParams[i].symBetaUni[1])
+ {
+ MrBayesPrint ("%s Lower value for uniform should be greater than upper value\n", spacer);
+ return (ERROR);
+ }
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Symdirihyperpr to Uniform(%1.2lf,%1.2lf)\n", spacer, modelParams[i].symBetaUni[0], modelParams[i].symBetaUni[1]);
+ else
+ MrBayesPrint ("%s Setting Symdirihyperpr to Uniform(%1.2lf,%1.2lf) for partition %d\n", spacer, modelParams[i].symBetaUni[0], modelParams[i].symBetaUni[1], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Problem setting Symdirihyperpr\n", spacer);
+ return (ERROR);
+ }
+ }
+ }
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Statefreqpr (stateFreqPr) ******************************************************/
+ else if (!strcmp(parmName, "Statefreqpr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsSame ("Equal", tkn) == DIFFERENT && IsSame ("Empirical", tkn) == DIFFERENT)
+ {
+ /* the user wants to specify a dirichlet or fixed prior */
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && modelParams[i].dataType != CONTINUOUS)
+ strcpy(modelParams[i].stateFreqPr, tempStr);
+ }
+ /* if (flag == 0)
+ {
+ MrBayesPrint ("%s Warning: %s can be set only for partition containing CONTINUOUS data.\
+ Currently there is no active partition with such data. ", spacer, parmName);
+ return (ERROR);
+ } */
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Statefreqpr argument\n", spacer);
+ return (ERROR);
+ }
+ /* TODO: Here we set flat dirichlet parameters */
+ expecting = Expecting(LEFTPAR);
+ }
+ else
+ {
+ /* the user wants equal or empirical state frequencies */
+ nApplied = NumActiveParts ();
+ if (IsSame ("Equal", tkn) == SAME || IsSame ("Equal", tkn) == CONSISTENT_WITH)
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && modelParams[i].dataType != CONTINUOUS)
+ strcpy(modelParams[i].stateFreqsFixType, "Equal");
+ }
+ }
+ else if (IsSame ("Empirical", tkn) == SAME || IsSame ("Empirical", tkn) == CONSISTENT_WITH)
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && modelParams[i].dataType != CONTINUOUS)
+ strcpy(modelParams[i].stateFreqsFixType, "Empirical");
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Statefreqpr delimiter\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ tempNumStates = 0;
+ expecting = Expecting(NUMBER) | Expecting(ALPHA);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ nApplied = NumActiveParts ();
+ sscanf (tkn, "%lf", &tempD);
+ tempStateFreqs[tempNumStates++] = tempD;
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && modelParams[i].dataType != CONTINUOUS)
+ if (!strcmp(modelParams[i].stateFreqPr,"Fixed"))
+ strcpy(modelParams[i].stateFreqsFixType, "User");
+ }
+ expecting = Expecting(COMMA) | Expecting(RIGHTPAR);
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && modelParams[i].dataType != CONTINUOUS)
+ {
+ ns = NumStates(i);
+ if (!strcmp(modelParams[i].stateFreqPr,"Dirichlet"))
+ {
+ if (tempNumStates == 1)
+ {
+ for (j=0; j<ns; j++)
+ modelParams[i].stateFreqsDir[j] = tempStateFreqs[0] / ns;
+ MrBayesPrint ("%s Setting Statefreqpr to Dirichlet(", spacer);
+ for (j=0; j<ns; j++)
+ {
+ MrBayesPrint("%1.2lf", modelParams[i].stateFreqsDir[j]);
+ if (j == ns - 1)
+ MrBayesPrint (")");
+ else
+ MrBayesPrint (",");
+ }
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("\n");
+ else
+ MrBayesPrint (" for partition %d\n", i+1);
+ modelParams[i].numDirParams = ns;
+ }
+ else
+ {
+ if (tempNumStates != ns)
+ {
+ MrBayesPrint ("%s Found %d dirichlet parameters but expecting %d\n", spacer, tempNumStates, modelParams[i].nStates);
+ return (ERROR);
+ }
+ else
+ {
+ modelParams[i].numDirParams = ns;
+ for (j=0; j<ns; j++)
+ modelParams[i].stateFreqsDir[j] = tempStateFreqs[j];
+ MrBayesPrint ("%s Setting Statefreqpr to Dirichlet(", spacer);
+ for (j=0; j<ns; j++)
+ {
+ MrBayesPrint("%1.2lf", modelParams[i].stateFreqsDir[j]);
+ if (j == ns - 1)
+ MrBayesPrint (")");
+ else
+ MrBayesPrint (",");
+ }
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("\n");
+ else
+ MrBayesPrint (" for partition %d\n", i+1);
+ }
+ }
+ }
+ else if (!strcmp(modelParams[i].stateFreqPr,"Fixed"))
+ {
+ if (tempNumStates == 0)
+ {
+ if (!strcmp(modelParams[i].stateFreqsFixType, "Equal"))
+ MrBayesPrint ("%s Setting Statefreqpr to Fixed(Equal)", spacer);
+ else if (!strcmp(modelParams[i].stateFreqsFixType, "Empirical"))
+ MrBayesPrint ("%s Setting Statefreqpr to Fixed(Empirical)", spacer);
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("\n");
+ else
+ MrBayesPrint (" for partition %d\n", i+1);
+ }
+ else
+ {
+ if (tempNumStates == ns)
+ {
+ sum = 0.0;
+ for (j=0; j<ns; j++)
+ sum += tempStateFreqs[j];
+ if (AreDoublesEqual (sum, (MrBFlt) 1.0, (MrBFlt) 0.001) == NO)
+ {
+ MrBayesPrint ("%s State frequencies do not sum to 1.0\n", spacer);
+ return (ERROR);
+ }
+ strcpy(modelParams[i].stateFreqsFixType, "User");
+ for (j=0; j<ns; j++)
+ modelParams[i].stateFreqsFix[j] = tempStateFreqs[j];
+ MrBayesPrint ("%s Setting Statefreqpr to Fixed(", spacer);
+ for (j=0; j<ns; j++)
+ {
+ MrBayesPrint("%1.2lf", modelParams[i].stateFreqsFix[j]);
+ if (j == ns - 1)
+ MrBayesPrint (")");
+ else
+ MrBayesPrint (",");
+ }
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("\n");
+ else
+ MrBayesPrint (" for partition %d\n", i+1);
+ }
+ else
+ {
+ MrBayesPrint ("%s Found %d state frequencies but expecting %d\n", spacer, tempNumStates, modelParams[i].nStates);
+ return (ERROR);
+ }
+ }
+
+ }
+ }
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Topologypr (topologyPr) ********************************************************/
+ else if (!strcmp(parmName, "Topologypr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ {
+ foundEqual = YES;
+ expecting = Expecting(ALPHA);
+ }
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (foundEqual == YES)
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ /* set topology prior */
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ {
+ strcpy(modelParams[i].topologyPr, tempStr);
+ /* erase previous constraints, if any */
+ for (j=0; j<numDefinedConstraints; j++)
+ modelParams[i].activeConstraints[j] = NO;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Topologypr to %s\n", spacer, modelParams[i].topologyPr);
+ else
+ MrBayesPrint ("%s Setting Topologypr to %s for partition %d\n", spacer, modelParams[i].topologyPr, i+1);
+ /* adjust branch length prior if necessary */
+ if (strcmp(modelParams[i].topologyPr,"Fixed") != 0 && strcmp(modelParams[i].brlensPr,"Fixed") == 0)
+ {
+ MrBayesPrint ("%s Resetting Brlenspr to default\n", spacer);
+ if (strcmp(modelParams[i].clockPr,"Clock") == 0)
+ strcpy(modelParams[i].brlensPr, "Uniform");
+ else
+ strcpy(modelParams[i].brlensPr, defaultModel.brlensPr);
+ }
+ }
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Topologypr argument\n", spacer);
+ return (ERROR);
+ }
+ /* make sure we know what to do next */
+ if (!strcmp(tempStr, "Uniform") || !strcmp(tempStr, "Speciestree"))
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ else
+ expecting = Expecting(LEFTPAR);
+ foundEqual = NO;
+ }
+ else
+ {
+ /* find out whether we need a tree name or constraint name */
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ if (activeParts[i] == YES || nApplied == 0)
+ break;
+
+ if (foundDash == YES) /* we must be collecting constraint numbers */
+ {
+ MrBayesPrint ("%s Expecting a number\n", spacer);
+ return (ERROR);
+ }
+ if (!strcmp(modelParams[i].topologyPr,"Constraints"))
+ {
+ /* find constraint number */
+ if (CheckString (constraintNames, numDefinedConstraints, tkn, &index) == ERROR)
+ {
+ MrBayesPrint ("%s Could not find constraint named %s\n", spacer, tkn);
+ return (ERROR);
+ }
+ tempActiveConstraints[index] = YES;
+ expecting = Expecting(RIGHTPAR);
+ expecting |= Expecting(COMMA);
+ }
+ else
+ {
+ /* find tree number */
+ if (GetUserTreeFromName (&index, tkn) == ERROR)
+ {
+ MrBayesPrint ("%s Could not set fixed topology from user tree '%s'\n", spacer, tkn);
+ return (ERROR);
+ }
+ fromI = index + 1; /* fromI is used to hold the index of the user tree, 1-based */
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ for (i=0; i<numDefinedConstraints; i++)
+ tempActiveConstraints[i] = NO;
+ fromI = toJ = -1;
+ foundDash = foundComma = NO;
+ expecting = Expecting(NUMBER) | Expecting(ALPHA);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ /* find out whether we need a tree number or constraint number */
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ if (activeParts[i] == YES || nApplied == 0)
+ break;
+
+ if (!strcmp(modelParams[i].topologyPr,"Constraints"))
+ {
+ if (numDefinedConstraints == 0)
+ {
+ MrBayesPrint ("%s No constraints have been defined\n", spacer);
+ return (ERROR);
+ }
+ sscanf (tkn, "%d", &tempInt);
+ if (tempInt > numDefinedConstraints)
+ {
+ MrBayesPrint ("%s Constraint number is too large\n", spacer);
+ return (ERROR);
+ }
+ if (fromI == -1)
+ {
+ if (foundDash == YES)
+ {
+ MrBayesPrint ("%s Unexpected dash\n", spacer);
+ return (ERROR);
+ }
+ fromI = tempInt;
+ tempActiveConstraints[fromI-1] = YES;
+ }
+ else if (fromI != -1 && toJ == -1 && foundDash == YES && foundComma == NO)
+ {
+ toJ = tempInt;
+ //for (i=fromI-1; i<toJ; i++)
+ for (i=fromI; i<toJ; i++)
+ tempActiveConstraints[i] = YES;
+ fromI = toJ = -1;
+ foundDash = NO;
+ }
+ else if (fromI != -1 && toJ == -1 && foundDash == NO && foundComma == YES)
+ {
+ fromI = tempInt;
+ tempActiveConstraints[fromI-1] = YES;
+ foundComma = NO;
+ }
+ expecting = Expecting(COMMA);
+ expecting |= Expecting(DASH);
+ expecting |= Expecting(RIGHTPAR);
+ }
+ else /* if (!strcmp(modelParams[i].topologyPr,"Fixed")) */
+ {
+ if (numUserTrees == 0)
+ {
+ MrBayesPrint ("%s No user trees have been defined\n", spacer);
+ return (ERROR);
+ }
+ sscanf (tkn, "%d", &tempInt);
+ if (tempInt > numUserTrees)
+ {
+ MrBayesPrint ("%s Tree number is too large\n", spacer);
+ return (ERROR);
+ }
+ if (tempInt < 1)
+ {
+ MrBayesPrint ("%s Tree number is too small\n", spacer);
+ return (ERROR);
+ }
+ fromI = tempInt;
+ expecting = Expecting(RIGHTPAR); /* only one tree number acceptable */
+ }
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ foundComma = YES;
+ expecting = Expecting(NUMBER) | Expecting(ALPHA);
+ }
+ else if (expecting == Expecting(DASH))
+ {
+ foundDash = YES;
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ /* find out whether we need a tree number or constraint number(s) */
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ if (activeParts[i] == YES || nApplied == 0)
+ break;
+
+ if (!strcmp(modelParams[i].topologyPr,"Constraints"))
+ {
+ /* set constraints */
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ {
+ modelParams[i].numActiveConstraints = 0;
+ for (j=0; j<numDefinedConstraints; j++)
+ {
+ if (tempActiveConstraints[j] == YES)
+ {
+ modelParams[i].activeConstraints[j] = YES;
+ modelParams[i].numActiveConstraints++;
+ }
+ else
+ modelParams[i].activeConstraints[j] = NO;
+ }
+ if (modelParams[i].numActiveConstraints == 0)
+ {
+ MrBayesPrint ("%s No constraints have been defined\n", spacer);
+ return (ERROR);
+ }
+ }
+ }
+ }
+ else /* if (!strcmp(modelParams[i].topologyPr,"Constraints")) */
+ {
+ /* set start tree index */
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ modelParams[i].topologyFix = fromI-1;
+ }
+ }
+# if 0
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ MrBayesPrint ("%4d -- ", i+1);
+ for (j=0; j<numDefinedConstraints; j++)
+ MrBayesPrint (" %d", modelParams[i].activeConstraints[j]);
+ MrBayesPrint ("\n");
+ }
+# endif
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Nodeagepr (nodeAgePr) ********************************************************/
+ else if (!strcmp(parmName, "Nodeagepr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ {
+ strcpy(modelParams[i].nodeAgePr, tempStr);
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Nodeagepr to %s\n", spacer, modelParams[i].nodeAgePr);
+ else
+ MrBayesPrint ("%s Setting Nodeagepr to %s for partition %d\n", spacer, modelParams[i].nodeAgePr, i+1);
+ }
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Nodeagepr argument\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Clockvarpr (clockVarPr) ********************************************************/
+ else if (!strcmp(parmName, "Clockvarpr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ if (strcmp(tempStr, "Bm") == 0)
+ strcpy(tempStr, "TK02");
+ else if (strcmp(tempStr, "Ibr") == 0)
+ strcpy(tempStr, "Igr");
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ {
+ strcpy(modelParams[i].clockVarPr, tempStr);
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Clockvarpr to %s\n", spacer, modelParams[i].clockVarPr);
+ else
+ MrBayesPrint ("%s Setting Clockvarpr to %s for partition %d\n", spacer, modelParams[i].clockVarPr, i+1);
+ }
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Clockvarpr argument\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Brlenspr (brlensPr) ************************************************************/
+ else if (!strcmp(parmName, "Brlenspr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ numVars[i] = NO;
+ foundEqual = YES;
+ foundLeftPar = NO;
+ expecting = Expecting(ALPHA);
+ }
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (foundEqual == YES)
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ strcpy (colonPr, tempStr);
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ if (activeParts[i] == YES || nApplied == 0)
+ strcpy(modelParams[i].brlensPr, tempStr);
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Brlenspr argument\n", spacer);
+ return (ERROR);
+ }
+ foundEqual = NO;
+ if (!strcmp(colonPr,"Fixed"))
+ expecting = Expecting(LEFTPAR);
+ else
+ expecting = Expecting(COLON);
+ }
+ else if (foundLeftPar == YES)
+ {
+ /*process argument of fixed() prior*/
+ /* find tree number */
+ if (GetUserTreeFromName (&tempInt, tkn) == ERROR)
+ {
+ MrBayesPrint ("%s Could not set fixed branch lengths from the user tree '%s'\n", spacer, tkn);
+ return (ERROR);
+ }
+ fromI = tempInt + 1; /* fromI is used to hold the index of the user tree, 1-based */
+ expecting = Expecting(RIGHTPAR);
+ foundLeftPar = NO;
+ }
+ else
+ {
+ if (!strcmp(colonPr, "Unconstrained"))
+ {
+ /* have unconstrained branch lengths, which we expect to have a uniform or exponential distribution */
+ nApplied = NumActiveParts ();
+ if (IsSame ("Uniform", tkn) == SAME || IsSame ("Uniform", tkn) == CONSISTENT_WITH)
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ if (activeParts[i] == YES || nApplied == 0)
+ strcpy(modelParams[i].unconstrainedPr, "Uniform");
+ }
+ else if (IsSame ("Exponential", tkn) == SAME || IsSame ("Exponential", tkn) == CONSISTENT_WITH)
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ if (activeParts[i] == YES || nApplied == 0)
+ strcpy(modelParams[i].unconstrainedPr, "Exponential");
+ }
+ else if (IsSame ("GammaDirichlet", tkn) == SAME || IsSame ("GammaDirichlet", tkn) == CONSISTENT_WITH)
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ if (activeParts[i] == YES || nApplied == 0)
+ strcpy(modelParams[i].unconstrainedPr, "GammaDir");
+ }
+ else if (IsSame ("invGamDirichlet", tkn) == SAME || IsSame ("invGamDirichlet", tkn) == CONSISTENT_WITH)
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ if (activeParts[i] == YES || nApplied == 0)
+ strcpy(modelParams[i].unconstrainedPr, "invGamDir");
+ }
+ else if (IsSame ("twoExponential", tkn) == SAME || IsSame ("twoExponential", tkn) == CONSISTENT_WITH)
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ if (activeParts[i] == YES || nApplied == 0)
+ strcpy(modelParams[i].unconstrainedPr, "twoExp");
+ }
+ else
+ {
+ MrBayesPrint ("%s Do not understand %s\n", spacer, tkn);
+ return (ERROR);
+ }
+ expecting = Expecting(LEFTPAR);
+ }
+ else if (!strcmp(colonPr, "Clock"))
+ {
+ /* otherwise we have a clock constraint and expect uniform, birthdeath, coalescence or fixed prior */
+ nApplied = NumActiveParts ();
+ if (IsSame ("Uniform", tkn) == SAME || IsSame ("Uniform", tkn) == CONSISTENT_WITH)
+ {
+ strcpy (clockPr, "Uniform");
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ strcpy(modelParams[i].clockPr, "Uniform");
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Brlenspr to Clock:Uniform\n", spacer);
+ else
+ MrBayesPrint ("%s Setting Brlenspr to Clock:Uniform for partition %d\n", spacer, i+1);
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else if (IsSame ("Birthdeath", tkn) == SAME || IsSame ("Birthdeath", tkn) == CONSISTENT_WITH)
+ {
+ strcpy (clockPr, "Birthdeath");
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ strcpy(modelParams[i].clockPr, "Birthdeath");
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Brlenspr to Clock:Birthdeath\n", spacer);
+ else
+ MrBayesPrint ("%s Setting Brlenspr to Clock:Birthdeath for partition %d\n", spacer, i+1);
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else if (IsSame ("Coalescence", tkn) == SAME || IsSame ("Coalescence", tkn) == CONSISTENT_WITH)
+ {
+ strcpy (clockPr, "Coalescence");
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ strcpy(modelParams[i].clockPr, "Coalescence");
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Brlenspr to Clock:Coalescence\n", spacer);
+ else
+ MrBayesPrint ("%s Setting Brlenspr to Clock:Coalescence for partition %d\n", spacer, i+1);
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else if (IsSame ("Speciestreecoalescence", tkn) == SAME || IsSame ("Speciestreecoalescence", tkn) == CONSISTENT_WITH)
+ {
+ strcpy (clockPr, "Speciestreecoalescence");
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ strcpy(modelParams[i].clockPr, "Speciestreecoalescence");
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Brlenspr to Clock:Speciestreecoalescence\n", spacer);
+ else
+ MrBayesPrint ("%s Setting Brlenspr to Clock:Speciestreecoalescence for partition %d\n", spacer, i+1);
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else if (IsSame ("Fossilization", tkn) == SAME || IsSame ("Fossilization", tkn) == CONSISTENT_WITH)
+ {
+ strcpy (clockPr, "Fossilization");
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ strcpy(modelParams[i].clockPr, "Fossilization");
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Brlenspr to Clock:Fossilization\n", spacer);
+ else
+ MrBayesPrint ("%s Setting Brlenspr to Clock:Fossilization for partition %d\n", spacer, i+1);
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else if (IsSame ("Fixed", tkn) == SAME || IsSame ("Fixed", tkn) == CONSISTENT_WITH)
+ {
+ strcpy (clockPr, "Fixed");
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ strcpy(modelParams[i].clockPr, "Fixed");
+ }
+ expecting = Expecting(LEFTPAR); /* Proceed with tree name */
+ }
+ else
+ {
+ MrBayesPrint ("%s Do not understand %s\n", spacer, tkn);
+ return (ERROR);
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Do not understand %s\n", spacer, tkn);
+ return (ERROR);
+ }
+ }
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ foundLeftPar = YES;
+ expecting = Expecting(NUMBER);
+ if (!strcmp(colonPr,"Fixed") || (!strcmp(colonPr,"Clock") && !strcmp(clockPr,"Fixed")))
+ {
+ expecting |= Expecting(ALPHA);
+ }
+ else
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ numVars[i] = 0;
+ }
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ if (!strcmp(colonPr, "Unconstrained"))
+ {
+ /* have unconstrained branch lengths */
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ {
+ if (!strcmp(modelParams[i].unconstrainedPr,"Uniform"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].brlensUni[numVars[i]++] = tempD;
+ if (numVars[i] == 1)
+ expecting = Expecting(COMMA);
+ else
+ {
+ if (modelParams[i].brlensUni[0] > 0.000001)
+ {
+ MrBayesPrint ("%s Lower value for uniform must equal 0.0\n", spacer);
+ return (ERROR);
+ }
+ if (modelParams[i].brlensUni[0] >= modelParams[i].brlensUni[1])
+ {
+ MrBayesPrint ("%s Lower value for uniform should be greater than upper value\n", spacer);
+ return (ERROR);
+ }
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Brlenspr to Unconstrained:Uniform(%1.2lf,%1.2lf)\n", spacer, modelParams[i].brlensUni[0], modelParams[i].brlensUni[1]);
+ else
+ MrBayesPrint ("%s Setting Brlenspr to Unconstrained:Uniform(%1.2lf,%1.2lf) for partition %d\n", spacer, modelParams[i].brlensUni[0], modelParams[i].brlensUni[1], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ else if (!strcmp(modelParams[i].unconstrainedPr,"Exponential"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].brlensExp = tempD;
+ if (modelParams[i].brlensExp <= 0.0)
+ {
+ MrBayesPrint ("%s Value for exponential must > 0.0\n", spacer);
+ return (ERROR);
+ }
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Brlenspr to Unconstrained:Exponential(%1.2lf)\n", spacer, modelParams[i].brlensExp);
+ else
+ MrBayesPrint ("%s Setting Brlenspr to Unconstrained:Exponential(%1.2lf) for partition %d\n", spacer, modelParams[i].brlensExp, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ else if (!strcmp(modelParams[i].unconstrainedPr,"GammaDir"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].brlensDir[numVars[i]++] = tempD;
+ if (numVars[i] == 1 || numVars[i] == 2 || numVars[i] == 3)
+ expecting = Expecting(COMMA);
+ else
+ {
+ if (modelParams[i].brlensDir[0] <= 0.0 || modelParams[i].brlensDir[1] <= 0.0 || modelParams[i].brlensDir[2] <= 0.0 || modelParams[i].brlensDir[3] <= 0.0)
+ {
+ MrBayesPrint ("%s alphaT & betaT & a & c for GammaDir prior must > 0.0\n", spacer);
+ return (ERROR);
+ }
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Brlenspr to Unconstrained:GammaDir(%1.2lf,%1.4lf,%1.2lf,%1.2lf)\n", spacer, modelParams[i].brlensDir[0], modelParams[i].brlensDir[1], modelParams[i].brlensDir[2], modelParams[i].brlensDir[3]);
+ else
+ MrBayesPrint ("%s Setting Brlenspr to Unconstrained:GammaDir(%1.2lf,%1.4lf,%1.2lf,%1.2lf) for partition %d\n", spacer, modelParams[i].brlensDir[0], modelParams[i].brlensDir[1], modelParams[i].brlensDir[2], modelParams[i].brlensDir[3], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ else if (!strcmp(modelParams[i].unconstrainedPr,"invGamDir"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].brlensDir[numVars[i]++] = tempD;
+ if (numVars[i] == 1 || numVars[i] == 2 || numVars[i] == 3)
+ expecting = Expecting(COMMA);
+ else
+ {
+ if (modelParams[i].brlensDir[0] <= 2.0 || modelParams[i].brlensDir[1] <= 0.0 || modelParams[i].brlensDir[2] <= 0.0 || modelParams[i].brlensDir[3] <= 0.0)
+ {
+ MrBayesPrint ("%s alphaT must > 2.0, betaT & a & c for invGamDir prior must > 0.0\n", spacer);
+ return (ERROR);
+ }
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Brlenspr to Unconstrained:invGamDir(%1.2lf,%1.4lf,%1.2lf,%1.2lf)\n", spacer, modelParams[i].brlensDir[0], modelParams[i].brlensDir[1], modelParams[i].brlensDir[2], modelParams[i].brlensDir[3]);
+ else
+ MrBayesPrint ("%s Setting Brlenspr to Unconstrained:invGamDir(%1.2lf,%1.4lf,%1.2lf,%1.2lf) for partition %d\n", spacer, modelParams[i].brlensDir[0], modelParams[i].brlensDir[1], modelParams[i].brlensDir[2], modelParams[i].brlensDir[3], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ else if (!strcmp(modelParams[i].unconstrainedPr,"twoExp"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].brlens2Exp[numVars[i]++] = tempD;
+ if (numVars[i] == 1)
+ expecting = Expecting(COMMA);
+ else
+ {
+ if (modelParams[i].brlens2Exp[0] <= 0.0 || modelParams[i].brlens2Exp[1] <= 0.0)
+ {
+ MrBayesPrint ("%s Values for the two exponentials must > 0.0\n", spacer);
+ return (ERROR);
+ }
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Brlenspr to Unconstrained:twoExp(%1.2lf,%1.2lf)\n", spacer, modelParams[i].brlens2Exp[0], modelParams[i].brlens2Exp[1]);
+ else
+ MrBayesPrint ("%s Setting Brlenspr to Unconstrained:twoExp(%1.2lf,%1.2lf) for partition %d\n", spacer, modelParams[i].brlens2Exp[0], modelParams[i].brlens2Exp[1], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ }
+ }
+ }
+ else if (!strcmp(colonPr,"Fixed") || !strcmp(colonPr,"Clock"))
+ {
+ sscanf (tkn, "%d", &tempInt);
+ if (tempInt < 1 || tempInt > numUserTrees)
+ {
+ MrBayesPrint ("%s Tree needs to be in the range %d to %d\n", spacer, 1, numUserTrees);
+ return (ERROR);
+ }
+ fromI = tempInt;
+ expecting = Expecting(RIGHTPAR);
+ }
+ foundLeftPar = NO;
+ }
+ else if (expecting == Expecting(COLON))
+ {
+ expecting = Expecting(ALPHA);
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ if (!strcmp(colonPr,"Fixed") || (!strcmp(colonPr,"Clock") && !strcmp(clockPr,"Fixed")))
+ {
+ /* index of a tree which set up branch lengths*/
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ modelParams[i].brlensFix = fromI-1;
+ if (!strcmp(colonPr,"Fixed"))
+ {
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Brlenspr to Fixed(%s)\n", spacer, userTree[fromI-1]->name);
+ else
+ MrBayesPrint ("%s Setting Brlenspr to Fixed(%s) for partition %d\n", spacer, userTree[fromI-1]->name, i+1);
+ }
+ else
+ {
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Brlenspr to Fixed(%s)\n", spacer, userTree[fromI-1]->name);
+ else
+ MrBayesPrint ("%s Setting Brlenspr to Fixed(%s) for partition %d\n", spacer, userTree[fromI-1]->name, i+1);
+ }
+ }
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Speciationpr (speciationPr) *************************************************/
+ else if (!strcmp(parmName, "Speciationpr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ if (activeParts[i] == YES || nApplied == 0)
+ strcpy(modelParams[i].speciationPr, tempStr);
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Speciationpr argument\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(LEFTPAR);
+ for (i=0; i<numCurrentDivisions; i++)
+ numVars[i] = 0;
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ {
+ if (!strcmp(modelParams[i].speciationPr,"Uniform"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].speciationUni[numVars[i]++] = tempD;
+ if (numVars[i] == 1)
+ expecting = Expecting(COMMA);
+ else
+ {
+ if (modelParams[i].speciationUni[0] >= modelParams[i].speciationUni[1])
+ {
+ MrBayesPrint ("%s Lower value for uniform should be greater than upper value\n", spacer);
+ return (ERROR);
+ }
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Speciationpr to Uniform(%1.2lf,%1.2lf)\n", spacer, modelParams[i].speciationUni[0], modelParams[i].speciationUni[1]);
+ else
+ MrBayesPrint ("%s Setting Speciationpr to Uniform(%1.2lf,%1.2lf) for partition %d\n", spacer, modelParams[i].speciationUni[0], modelParams[i].speciationUni[1], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ else if (!strcmp(modelParams[i].speciationPr,"Exponential"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ if (tempD <= 0.0)
+ {
+ MrBayesPrint ("%s Exponential parameter must be positive\n", spacer);
+ return (ERROR);
+ }
+ modelParams[i].speciationExp = tempD;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Speciationpr to Exponential(%1.2lf)\n", spacer, modelParams[i].speciationExp);
+ else
+ MrBayesPrint ("%s Setting Speciationpr to Exponential(%1.2lf) for partition %d\n", spacer, modelParams[i].speciationExp, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ else if (!strcmp(modelParams[i].speciationPr,"Fixed"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ if (tempD <= 0.0)
+ {
+ MrBayesPrint ("%s Net speciation rate must be positive\n", spacer);
+ return (ERROR);
+ }
+ modelParams[i].speciationFix = tempD;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Speciationpr to Fixed(%1.2lf)\n", spacer, modelParams[i].speciationFix);
+ else
+ MrBayesPrint ("%s Setting Speciationpr to Fixed(%1.2lf) for partition %d\n", spacer, modelParams[i].speciationFix, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ }
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Extinctionpr (extinctionPr) *************************************************/
+ else if (!strcmp(parmName, "Extinctionpr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ if (activeParts[i] == YES || nApplied == 0)
+ strcpy(modelParams[i].extinctionPr, tempStr);
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Extinctionpr argument\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(LEFTPAR);
+ for (i=0; i<numCurrentDivisions; i++)
+ numVars[i] = 0;
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ {
+ if (!strcmp(modelParams[i].extinctionPr,"Beta"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ if (tempD <= 0.0)
+ {
+ MrBayesPrint ("%s Beta parameter must be positive\n", spacer);
+ return (ERROR);
+ }
+ modelParams[i].extinctionBeta[numVars[i]++] = tempD;
+ if (numVars[i] == 1)
+ expecting = Expecting(COMMA);
+ else
+ {
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Extinctionpr to Beta(%1.2lf,%1.2lf)\n", spacer, modelParams[i].extinctionBeta[0], modelParams[i].extinctionBeta[1]);
+ else
+ MrBayesPrint ("%s Setting Extinctionpr to Beta(%1.2lf,%1.2lf) for partition %d\n", spacer, modelParams[i].extinctionBeta[0], modelParams[i].extinctionBeta[1], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ else if (!strcmp(modelParams[i].extinctionPr,"Fixed"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ if (tempD < 0.0 || tempD >= 1.0)
+ {
+ MrBayesPrint ("%s Relative extinction rate must be in range [0,1)\n", spacer);
+ return (ERROR);
+ }
+ modelParams[i].extinctionFix = tempD;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Extinctionpr to Fixed(%1.2lf)\n", spacer, modelParams[i].extinctionFix);
+ else
+ MrBayesPrint ("%s Setting Extinctionpr to Fixed(%1.2lf) for partition %d\n", spacer, modelParams[i].extinctionFix, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ }
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Fossilizationpr (fossilizationPr) */
+ else if (!strcmp(parmName, "Fossilizationpr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ if (activeParts[i] == YES || nApplied == 0)
+ strcpy(modelParams[i].fossilizationPr, tempStr);
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Fossilization argument\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(LEFTPAR);
+ for (i=0; i<numCurrentDivisions; i++)
+ numVars[i] = 0;
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ {
+ if (!strcmp(modelParams[i].fossilizationPr,"Beta"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ if (tempD <= 0.0)
+ {
+ MrBayesPrint ("%s Beta parameter must be positive\n", spacer);
+ return (ERROR);
+ }
+ modelParams[i].fossilizationBeta[numVars[i]++] = tempD;
+ if (numVars[i] == 1)
+ expecting = Expecting(COMMA);
+ else
+ {
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Fossilizationpr to Beta(%1.2lf,%1.2lf)\n", spacer, modelParams[i].fossilizationBeta[0], modelParams[i].fossilizationBeta[1]);
+ else
+ MrBayesPrint ("%s Setting Fossilizationpr to Beta(%1.2lf,%1.2lf) for partition %d\n", spacer, modelParams[i].fossilizationBeta[0], modelParams[i].fossilizationBeta[1], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ else if (!strcmp(modelParams[i].fossilizationPr,"Fixed"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ if (tempD < 0.0 || tempD > 1.0)
+ {
+ MrBayesPrint ("%s Relative fossilization rate must be in the range (0,1]\n", spacer);
+ return (ERROR);
+ }
+ modelParams[i].fossilizationFix = tempD;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Fossilizationpr to Fixed(%1.2lf)\n", spacer, modelParams[i].fossilizationFix);
+ else
+ MrBayesPrint ("%s Setting Fossilizationpr to Fixed(%1.2lf) for partition %d\n", spacer, modelParams[i].fossilizationFix, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ }
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set SampleStrat (sampleStrat) ***************************************************/
+ else if (!strcmp(parmName, "Samplestrat"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ {
+ expecting = Expecting(ALPHA);
+ }
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ {
+ strcpy(modelParams[i].sampleStrat, tempStr);
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting SampleStrat to %s\n", spacer, modelParams[i].sampleStrat);
+ else
+ MrBayesPrint ("%s Setting SampleStrat to %s for partition %d\n", spacer, modelParams[i].sampleStrat, i+1);
+ if (!strcmp(modelParams[i].sampleStrat,"Random") || !strcmp(modelParams[i].sampleStrat,"Diversity"))
+ {
+ foundFSNum[i] = foundFSTime[i] = NO;
+ modelParams[i].sampleFSNum = 0;
+ numVars[i] = 0;
+ expecting = Expecting(NUMBER);
+ expecting |= Expecting(PARAMETER);
+ expecting |= Expecting(SEMICOLON);
+ }
+ else
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Samplestrat argument\n", spacer);
+ return (ERROR);
+ }
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ {
+ if (foundFSNum[i] == NO)
+ {
+ sscanf (tkn, "%d", &tempInt);
+ if (tempInt <= 0)
+ {
+ MrBayesPrint ("%s Number of fossil slice sampling events must be > 0\n", spacer);
+ return (ERROR);
+ }
+ modelParams[i].sampleFSNum = tempInt;
+ if (memAllocs[ALLOC_SAMPLEFOSSILSLICE] == YES)
+ {
+ free(modelParams[i].sampleFSProb);
+ free(modelParams[i].sampleFSTime);
+ }
+ modelParams[i].sampleFSTime = (MrBFlt *) SafeMalloc ((size_t)tempInt * sizeof(MrBFlt));
+ modelParams[i].sampleFSProb = (MrBFlt *) SafeMalloc ((size_t)tempInt * sizeof(MrBFlt));
+ memAllocs[ALLOC_SAMPLEFOSSILSLICE] = YES;
+ foundFSNum[i] = YES;
+ expecting = Expecting(COLON);
+ }
+ else if (foundFSTime[i] == NO)
+ {
+ sscanf (tkn, "%lf", &tempD);
+ if (tempD <= 0.0)
+ {
+ MrBayesPrint ("%s Time of fossil slice sampling events must be > 0.\n", spacer);
+ return (ERROR);
+ }
+ if (numVars[i] > 0 && modelParams[i].sampleFSTime[numVars[i]-1] < tempD)
+ {
+ MrBayesPrint ("%s Time of fossil slice sampling events must be in decreasing order\n", spacer);
+ return (ERROR);
+ }
+ modelParams[i].sampleFSTime[numVars[i]] = tempD;
+ foundFSTime[i] = YES;
+ expecting = Expecting(NUMBER);
+ }
+ else
+ {
+ sscanf (tkn, "%lf", &tempD);
+ if (tempD < 0.0 || tempD > 1.0)
+ {
+ MrBayesPrint ("%s Prob of fossil slice sampling events must be in [0,1]\n", spacer);
+ return (ERROR);
+ }
+ modelParams[i].sampleFSProb[numVars[i]] = tempD;
+ foundFSTime[i] = NO;
+ expecting = Expecting(COMMA);
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting %d FSTime FSProb to %1.2lf %1.6lf\n", spacer, numVars[i]+1,
+ modelParams[i].sampleFSTime[numVars[i]], modelParams[i].sampleFSProb[numVars[i]]);
+ else
+ MrBayesPrint ("%s Setting %d FSTime FSProb to %1.2lf %1.6lf for partition %d\n", spacer, numVars[i]+1,
+ modelParams[i].sampleFSTime[numVars[i]], modelParams[i].sampleFSProb[numVars[i]], i+1);
+ numVars[i]++;
+ if (numVars[i] == modelParams[i].sampleFSNum)
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ }
+ }
+ }
+ else if (expecting == Expecting(COLON) || expecting == Expecting(COMMA))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else
+ {
+ return (ERROR);
+ }
+ }
+ /* set Sampleprob (sampleProb) *****************************************************/
+ else if (!strcmp(parmName, "Sampleprob"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(NUMBER);
+ else if (expecting == Expecting(NUMBER))
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ if (tempD <= 0.0 || tempD > 1.0)
+ {
+ MrBayesPrint ("%s Sampleprob should be in range (0,1]\n", spacer);
+ return (ERROR);
+ }
+ modelParams[i].sampleProb = tempD;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Sampleprob to %1.8lf\n", spacer, modelParams[i].sampleProb);
+ else
+ MrBayesPrint ("%s Setting Sampleprob to %1.8lf for partition %d\n", spacer, modelParams[i].sampleProb, i+1);
+ }
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Treeagepr (treeAgePr) *******************************************************/
+ else if (!strcmp(parmName, "Treeagepr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ if (activeParts[i] == YES || nApplied == 0)
+ {
+ strcpy(modelParams[i].treeAgePr.name, tempStr);
+ if (!strcmp(tempStr,"Fixed"))
+ modelParams[i].treeAgePr.prior = fixed;
+ else if (!strcmp(tempStr,"Uniform"))
+ modelParams[i].treeAgePr.prior = uniform;
+ else if (!strcmp(tempStr,"Offsetexponential"))
+ modelParams[i].treeAgePr.prior = offsetExponential;
+ else if (!strcmp(tempStr,"Truncatednormal"))
+ modelParams[i].treeAgePr.prior = truncatedNormal;
+ else if (!strcmp(tempStr,"Lognormal"))
+ modelParams[i].treeAgePr.prior = logNormal;
+ else if (!strcmp(tempStr,"Offsetlognormal"))
+ modelParams[i].treeAgePr.prior = offsetLogNormal;
+ else if (!strcmp(tempStr,"Gamma"))
+ modelParams[i].treeAgePr.prior = standardGamma;
+ else if (!strcmp(tempStr,"Offsetgamma"))
+ modelParams[i].treeAgePr.prior = offsetGamma;
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Treeagepr argument\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(LEFTPAR);
+ for (i=0; i<numCurrentDivisions; i++)
+ numVars[i] = 0;
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ if (activeParts[i] == YES || nApplied == 0)
+ strcat(modelParams[i].treeAgePr.name, "(");
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ sprintf (tempStr, "%1.2lf", tempD);
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ {
+ if (numVars[i] == 0 && tempD < 0.0)
+ {
+ if (modelParams[i].treeAgePr.prior == uniform ||
+ modelParams[i].treeAgePr.prior == offsetExponential ||
+ modelParams[i].treeAgePr.prior == truncatedNormal ||
+ modelParams[i].treeAgePr.prior == offsetLogNormal ||
+ modelParams[i].treeAgePr.prior == offsetGamma)
+ MrBayesPrint("%s Minimum, offset or truncation point must be nonnegative\n", spacer);
+ else if (modelParams[i].treeAgePr.prior == fixed)
+ MrBayesPrint("%s Fixed age must be nonnegative\n", spacer);
+ else
+ MrBayesPrint("%s Mean must be nonnegative\n", spacer);
+ break;
+ }
+ else if (numVars[i] == 1)
+ {
+ if (modelParams[i].treeAgePr.prior == uniform && tempD <= modelParams[i].treeAgePr.priorParams[0])
+ {
+ MrBayesPrint("%s Max of uniform distribution must be larger than min\n", spacer);
+ break;
+ }
+ else if ((modelParams[i].treeAgePr.prior == standardGamma || modelParams[i].treeAgePr.prior == logNormal) && tempD <= 0.0)
+ {
+ MrBayesPrint("%s Standard deviation must be positive\n", spacer);
+ break;
+ }
+ else if ((modelParams[i].treeAgePr.prior == offsetExponential ||
+ modelParams[i].treeAgePr.prior == offsetGamma ||
+ modelParams[i].treeAgePr.prior == offsetLogNormal) && tempD <= modelParams[i].treeAgePr.priorParams[0])
+ {
+ MrBayesPrint("%s Mean must be larger than offset\n", spacer);
+ break;
+ }
+ }
+ else if (numVars[i] == 2 && tempD <= 0.0)
+ {
+ MrBayesPrint("%s Standard deviation must be positive\n", spacer);
+ break;
+ }
+ modelParams[i].treeAgePr.priorParams[numVars[i]++] = tempD;
+ sprintf (tempStr, "%1.2lf", tempD);
+ strcat(modelParams[i].treeAgePr.name, tempStr);
+ if (modelParams[i].treeAgePr.prior == fixed || numVars[i] == 3)
+ expecting = Expecting(RIGHTPAR);
+ else if (numVars[i] == 1)
+ expecting = Expecting(COMMA);
+ else if (modelParams[i].treeAgePr.prior == standardGamma ||
+ modelParams[i].treeAgePr.prior == uniform ||
+ modelParams[i].treeAgePr.prior == offsetExponential ||
+ modelParams[i].treeAgePr.prior == logNormal)
+ expecting = Expecting(RIGHTPAR);
+ else
+ expecting = Expecting(COMMA);
+ }
+ }
+ if (i < numCurrentDivisions)
+ {
+ /* An error occurred. Reset calibrations and bail out */
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ {
+ strcpy(modelParams[i].treeAgePr.name, "Gamma(1.00,1.00)");
+ modelParams[i].treeAgePr.prior = standardGamma;
+ modelParams[i].treeAgePr.priorParams[0] = 1.0;
+ modelParams[i].treeAgePr.priorParams[1] = 1.0;
+ modelParams[i].treeAgePr.priorParams[2] = -1.0;
+ modelParams[i].treeAgePr.min = 0.0;
+ modelParams[i].treeAgePr.max = POS_INFINITY;
+ }
+ }
+ return (ERROR);
+ }
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ if (activeParts[i] == YES || nApplied == 0)
+ strcat(modelParams[i].treeAgePr.name, ",");
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ {
+ strcat(modelParams[i].treeAgePr.name, ")");
+ MrBayesPrint ("%s Setting Treeagepr to %s\n", spacer, modelParams[i].treeAgePr.name);
+
+ if (modelParams[i].treeAgePr.prior == fixed)
+ {
+ modelParams[i].treeAgePr.LnPriorProb = &LnPriorProbFix;
+ modelParams[i].treeAgePr.LnPriorRatio = &LnProbRatioFix;
+ modelParams[i].treeAgePr.min = modelParams[i].treeAgePr.priorParams[0];
+ modelParams[i].treeAgePr.max = modelParams[i].treeAgePr.priorParams[0];
+ }
+ else if (modelParams[i].treeAgePr.prior == uniform)
+ {
+ modelParams[i].treeAgePr.LnPriorProb = &LnPriorProbUniform;
+ modelParams[i].treeAgePr.LnPriorRatio = &LnProbRatioUniform;
+ modelParams[i].treeAgePr.min = modelParams[i].treeAgePr.priorParams[0];
+ modelParams[i].treeAgePr.max = modelParams[i].treeAgePr.priorParams[1];
+ }
+ else if (modelParams[i].treeAgePr.prior == offsetExponential)
+ {
+ modelParams[i].treeAgePr.LnPriorProb = &LnPriorProbOffsetExponential_Param_Offset_Mean;
+ modelParams[i].treeAgePr.LnPriorRatio = &LnProbRatioOffsetExponential_Param_Offset_Mean;
+ modelParams[i].treeAgePr.min = modelParams[i].treeAgePr.priorParams[0];
+ modelParams[i].treeAgePr.max = POS_INFINITY;
+ }
+ else if (modelParams[i].treeAgePr.prior == truncatedNormal)
+ {
+ modelParams[i].treeAgePr.LnPriorProb = &LnPriorProbTruncatedNormal_Param_Trunc_Mean_Sd;
+ modelParams[i].treeAgePr.LnPriorRatio = &LnProbRatioTruncatedNormal_Param_Trunc_Mean_Sd;
+ modelParams[i].treeAgePr.min = modelParams[i].treeAgePr.priorParams[0];
+ modelParams[i].treeAgePr.max = POS_INFINITY;
+ }
+ else if (modelParams[i].treeAgePr.prior == logNormal)
+ {
+ modelParams[i].treeAgePr.LnPriorProb = &LnPriorProbLognormal_Param_Mean_Sd;
+ modelParams[i].treeAgePr.LnPriorRatio = &LnProbRatioLognormal_Param_Mean_Sd;
+ modelParams[i].treeAgePr.min = 0.0;
+ modelParams[i].treeAgePr.max = POS_INFINITY;
+ }
+ else if (modelParams[i].treeAgePr.prior == offsetLogNormal)
+ {
+ modelParams[i].treeAgePr.LnPriorProb = &LnPriorProbOffsetLognormal_Param_Offset_Mean_Sd;
+ modelParams[i].treeAgePr.LnPriorRatio = &LnProbRatioOffsetLognormal_Param_Offset_Mean_Sd;
+ modelParams[i].treeAgePr.min = modelParams[i].treeAgePr.priorParams[0];
+ modelParams[i].treeAgePr.max = POS_INFINITY;
+ }
+ else if (modelParams[i].treeAgePr.prior == standardGamma)
+ {
+ modelParams[i].treeAgePr.LnPriorProb = &LnPriorProbGamma_Param_Mean_Sd;
+ modelParams[i].treeAgePr.LnPriorRatio = &LnProbRatioGamma_Param_Mean_Sd;
+ modelParams[i].treeAgePr.min = 0.0;
+ modelParams[i].treeAgePr.max = POS_INFINITY;
+ }
+ else if (modelParams[i].treeAgePr.prior == offsetGamma)
+ {
+ modelParams[i].treeAgePr.LnPriorProb = &LnPriorProbOffsetGamma_Param_Offset_Mean_Sd;
+ modelParams[i].treeAgePr.LnPriorRatio = &LnProbRatioOffsetGamma_Param_Offset_Mean_Sd;
+ modelParams[i].treeAgePr.min = modelParams[i].treeAgePr.priorParams[0];
+ modelParams[i].treeAgePr.max = POS_INFINITY;
+ }
+ }
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Clockratepr (clockRatePr) ****************************************************/
+ else if (!strcmp(parmName, "Clockratepr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ {
+ foundDash = NO;
+ expecting = Expecting(ALPHA);
+ }
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ strcpy(modelParams[i].clockRatePr, tempStr);
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Clockratepr argument\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(LEFTPAR);
+ for (i=0; i<numCurrentDivisions; i++)
+ numVars[i] = 0;
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ expecting = Expecting(NUMBER);
+ expecting |= Expecting(DASH); /* negative numbers possible */
+ }
+ else if (expecting == Expecting(DASH))
+ {
+ foundDash = YES;
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ if (foundDash == YES)
+ {
+ foundDash = NO;
+ tempD *= -1.0;
+ }
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ {
+ if (!strcmp(modelParams[i].clockRatePr,"Normal"))
+ {
+ if (tempD <= 0.0)
+ {
+ if (numVars[i] == 0)
+ MrBayesPrint ("%s Mean of the normal must be positive\n", spacer);
+ else if (numVars[i] == 1)
+ MrBayesPrint ("%s Standard deviation of the normal must be positive\n", spacer);
+ return (ERROR);
+ }
+ modelParams[i].clockRateNormal[numVars[i]] = tempD;
+ numVars[i]++;
+ if (numVars[i] == 1)
+ expecting = Expecting(COMMA);
+ else
+ {
+ if (nApplied == 0 || numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Clockratepr to Normal(%1.6lf,%1.6lf)\n", spacer, modelParams[i].clockRateNormal[0], modelParams[i].clockRateNormal[1]);
+ else
+ MrBayesPrint ("%s Setting Clockratepr to Normal(%1.6lf,%1.6lf) for partition %d\n", spacer, modelParams[i].clockRateNormal[0], modelParams[i].clockRateNormal[1], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ else if (!strcmp(modelParams[i].clockRatePr,"Lognormal"))
+ {
+ modelParams[i].clockRateLognormal[numVars[i]] = tempD;
+ numVars[i]++;
+ if (numVars[i] == 1)
+ expecting = Expecting(COMMA);
+ else
+ {
+ if (nApplied == 0 || numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Clockratepr to Lognormal(%1.2lf,%1.2lf)\n", spacer, modelParams[i].clockRateLognormal[0], modelParams[i].clockRateLognormal[1]);
+ else
+ MrBayesPrint ("%s Setting Clockratepr to Lognormal(%1.2lf,%1.2lf) for partition %d\n", spacer, modelParams[i].clockRateLognormal[0], modelParams[i].clockRateLognormal[1], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ else if (!strcmp(modelParams[i].clockRatePr,"Exponential"))
+ {
+ if (tempD <= 0.0)
+ {
+ MrBayesPrint ("%s Rate of the exponential must be positive\n", spacer);
+ return (ERROR);
+ }
+ modelParams[i].clockRateExp = tempD;
+ numVars[i]++;
+ if (nApplied == 0 || numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Clockratepr to Exponential(%1.2lf)\n", spacer, modelParams[i].clockRateExp);
+ else
+ MrBayesPrint ("%s Setting Clockratepr to Exponential(%1.2lf) for partition %d\n", spacer, modelParams[i].clockRateExp, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ else if (!strcmp(modelParams[i].clockRatePr,"Gamma"))
+ {
+ if (tempD <= 0.0)
+ {
+ if (numVars[i] == 0)
+ MrBayesPrint ("%s Shape of the gamma must be positive\n", spacer);
+ else if (numVars[i] == 1)
+ MrBayesPrint ("%s Rate (inverse scale) of the gamma must be positive\n", spacer);
+ return (ERROR);
+ }
+ modelParams[i].clockRateGamma[numVars[i]] = tempD;
+ numVars[i]++;
+ if (numVars[i] == 1)
+ expecting = Expecting(COMMA);
+ else
+ {
+ if (nApplied == 0 || numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Clockratepr to Gamma(%1.2lf,%1.2lf)\n", spacer, modelParams[i].clockRateGamma[0], modelParams[i].clockRateGamma[1]);
+ else
+ MrBayesPrint ("%s Setting Clockratepr to Gamma(%1.2lf,%1.2lf) for partition %d\n", spacer, modelParams[i].clockRateGamma[0], modelParams[i].clockRateGamma[1], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ else if (!strcmp(modelParams[i].clockRatePr,"Fixed"))
+ {
+ if (tempD <= 0.0)
+ {
+ MrBayesPrint ("%s Fixed clock rate must be positive\n", spacer);
+ return (ERROR);
+ }
+ modelParams[i].clockRateFix = tempD;
+ numVars[i]++;
+ if (nApplied == 0 || numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Clockratepr to Fixed(%1.6lf)\n", spacer, modelParams[i].clockRateFix);
+ else
+ MrBayesPrint ("%s Setting Clockratepr to Fixed(%1.6lf) for partition %d\n", spacer, modelParams[i].clockRateFix, i+1);
+ for (k=0; k<numGlobalChains; k++)
+ {
+ if (UpdateClockRate(tempD, k) == ERROR)
+ return (ERROR);
+ }
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ }
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Popsizepr (popSizePr) **************************************************************/
+ else if (!strcmp(parmName, "Popsizepr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ strcpy(modelParams[i].popSizePr, tempStr);
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Popsizepr argument\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(LEFTPAR);
+ for (i=0; i<numCurrentDivisions; i++)
+ numVars[i] = 0;
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA))
+ {
+ if (!strcmp(modelParams[i].popSizePr,"Uniform"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].popSizeUni[numVars[i]++] = tempD;
+ if (numVars[i] == 1)
+ {
+ if (tempD <= 0.0)
+ {
+ MrBayesPrint ("%s Lower value for Uniform must be a positive number\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(COMMA);
+ }
+ else
+ {
+ if (modelParams[i].popSizeUni[0] >= modelParams[i].popSizeUni[1])
+ {
+ MrBayesPrint ("%s Lower value for Uniform should be greater than upper value\n", spacer);
+ return (ERROR);
+ }
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Popsizepr to Uniform(%1.2lf,%1.2lf)\n", spacer, modelParams[i].popSizeUni[0], modelParams[i].popSizeUni[1]);
+ else
+ MrBayesPrint ("%s Setting Popsizepr to Uniform(%1.2lf,%1.2lf) for partition %d\n", spacer, modelParams[i].popSizeUni[0], modelParams[i].popSizeUni[1], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ else if (!strcmp(modelParams[i].popSizePr,"Lognormal"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].popSizeLognormal[numVars[i]++] = tempD;
+ if (numVars[i] == 1)
+ {
+ expecting = Expecting(COMMA);
+ }
+ else
+ {
+ if (modelParams[i].popSizeLognormal[1] <= 0.0)
+ {
+ MrBayesPrint ("%s Standard deviation of Lognormal must be a positive number\n", spacer);
+ return (ERROR);
+ }
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Popsizepr to Lognormal(%1.2lf,%1.2lf)\n", spacer, modelParams[i].popSizeLognormal[0], modelParams[i].popSizeLognormal[1]);
+ else
+ MrBayesPrint ("%s Setting Popsizepr to Lognormal(%1.2lf,%1.2lf) for partition %d\n", spacer, modelParams[i].popSizeLognormal[0], modelParams[i].popSizeLognormal[1], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ else if (!strcmp(modelParams[i].popSizePr,"Normal"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].popSizeNormal[numVars[i]++] = tempD;
+ if (numVars[i] == 1)
+ {
+ if (modelParams[i].popSizeNormal[0] <= 0.0)
+ {
+ MrBayesPrint ("%s Mean of Truncated Normal must be a positive number\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(COMMA);
+ }
+ else
+ {
+ if (modelParams[i].popSizeNormal[1] <= 0.0)
+ {
+ MrBayesPrint ("%s Standard deviation of Truncated Normal must be a positive number\n", spacer);
+ return (ERROR);
+ }
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Popsizepr to Truncated Normal(%1.2lf,%1.2lf)\n", spacer, modelParams[i].popSizeNormal[0], modelParams[i].popSizeNormal[1]);
+ else
+ MrBayesPrint ("%s Setting Popsizepr to Truncated Normal(%1.2lf,%1.2lf) for partition %d\n", spacer, modelParams[i].popSizeNormal[0], modelParams[i].popSizeNormal[1], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ else if (!strcmp(modelParams[i].popSizePr,"Gamma"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].popSizeGamma[numVars[i]++] = tempD;
+ if (numVars[i] == 1)
+ {
+ if (modelParams[i].popSizeGamma[0] <= 0.0)
+ {
+ MrBayesPrint ("%s Shape (alpha) of Gamma must be a positive number\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(COMMA);
+ }
+ else
+ {
+ if (modelParams[i].popSizeGamma[1] <= 0.0)
+ {
+ MrBayesPrint ("%s Rate (beta) of Gamma must be a positive number\n", spacer);
+ return (ERROR);
+ }
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Popsizepr to Gamma(%1.2lf,%1.2lf)\n", spacer, modelParams[i].popSizeGamma[0], modelParams[i].popSizeGamma[1]);
+ else
+ MrBayesPrint ("%s Setting Popsizepr to Gamma(%1.2lf,%1.2lf) for partition %d\n", spacer, modelParams[i].popSizeGamma[0], modelParams[i].popSizeGamma[1], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ else if (!strcmp(modelParams[i].popSizePr,"Fixed"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ if (AreDoublesEqual(tempD, 0.0, ETA)==YES)
+ {
+ MrBayesPrint ("%s Popsizepr cannot be fixed to 0.0\n", spacer);
+ return (ERROR);
+ }
+ modelParams[i].popSizeFix = tempD;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Popsizepr to Fixed(%1.5lf)\n", spacer, modelParams[i].popSizeFix);
+ else
+ MrBayesPrint ("%s Setting Popsizepr to Fixed(%1.5lf) for partition %d\n", spacer, modelParams[i].popSizeFix, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ }
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Popvarpr (popVarPr) **************************************************************/
+ else if (!strcmp(parmName, "Popvarpr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ {
+ strcpy(modelParams[i].popVarPr, tempStr);
+
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Popvarpr to %s\n", spacer, modelParams[i].popVarPr);
+ else
+ MrBayesPrint ("%s Setting Popvarpr to %s for partition %d\n", spacer, modelParams[i].popVarPr, i+1);
+ }
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Popvarpr argument\n", spacer);
+ return (ERROR);
+ }
+ }
+ else
+ return (ERROR);
+ }
+ /* set Compound Poisson Process rate prior (cppRatePr) *********************************************************/
+ else if (!strcmp(parmName, "Cppratepr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ strcpy(modelParams[i].cppRatePr, tempStr);
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Cppratepr argument\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(LEFTPAR);
+ for (i=0; i<numCurrentDivisions; i++)
+ numVars[i] = 0;
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ {
+ if (!strcmp(modelParams[i].cppRatePr,"Exponential"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].cppRateExp = tempD;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Cppratepr to Exponential(%1.2lf)\n", spacer, modelParams[i].cppRateExp);
+ else
+ MrBayesPrint ("%s Setting Cppratepr to Exponential(%1.2lf) for partition %d\n", spacer, modelParams[i].cppRateExp, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ else if (!strcmp(modelParams[i].cppRatePr,"Fixed"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ if (tempD < CPPLAMBDA_MIN || tempD > CPPLAMBDA_MAX)
+ {
+ MrBayesPrint ("%s CPP rate must be in the range %f - %f\n", spacer, CPPLAMBDA_MIN, CPPLAMBDA_MAX);
+ return (ERROR);
+ }
+ modelParams[i].cppRateFix = tempD;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Cppratepr to Fixed(%1.2lf)\n", spacer, modelParams[i].cppRateFix);
+ else
+ MrBayesPrint ("%s Setting Cppratepr to Fixed(%1.2lf) for partition %d\n", spacer, modelParams[i].cppRateFix, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ }
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Compound Poisson Process rate multiplier standard deviation (log scale) ***********************/
+ else if (!strcmp(parmName, "Cppmultdevpr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ strcpy(modelParams[i].cppMultDevPr, tempStr);
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Cppmultdevpr argument\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(LEFTPAR);
+ for (i=0; i<numCurrentDivisions; i++)
+ numVars[i] = 0;
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ {
+ if (!strcmp(modelParams[i].cppMultDevPr,"Fixed"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ if (tempD < POSREAL_MIN || tempD > POSREAL_MAX)
+ {
+ MrBayesPrint ("%s The log standard deviation of rate multipliers must be in the range %f - %f\n", spacer, POSREAL_MIN, POSREAL_MAX);
+ return (ERROR);
+ }
+ modelParams[i].cppMultDevFix = tempD;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Cppmultdevpr to Fixed(%1.2lf)\n", spacer, modelParams[i].cppMultDevFix);
+ else
+ MrBayesPrint ("%s Setting Cppmultdevpr to Fixed(%1.2lf) for partition %d\n", spacer, modelParams[i].cppMultDevFix, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ }
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set prior for variance of lognormal of autocorrelated rates (tk02varPr) ***********************/
+ else if (!strcmp(parmName, "TK02varpr") || !strcmp(parmName,"Bmvarpr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ strcpy(modelParams[i].tk02varPr, tempStr);
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid TK02varpr argument\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(LEFTPAR);
+ for (i=0; i<numCurrentDivisions; i++)
+ numVars[i] = 0;
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ {
+ if (!strcmp(modelParams[i].tk02varPr,"Uniform"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].tk02varUni[numVars[i]++] = tempD;
+ if (numVars[i] == 1)
+ expecting = Expecting(COMMA);
+ else
+ {
+ if (modelParams[i].tk02varUni[0] >= modelParams[i].tk02varUni[1])
+ {
+ MrBayesPrint ("%s Lower value for uniform should be greater than upper value\n", spacer);
+ return (ERROR);
+ }
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting TK02varpr to Uniform(%1.2lf,%1.2lf)\n", spacer, modelParams[i].tk02varUni[0], modelParams[i].tk02varUni[1]);
+ else
+ MrBayesPrint ("%s Setting TK02varpr to Uniform(%1.2lf,%1.2lf) for partition %d\n", spacer, modelParams[i].tk02varUni[0], modelParams[i].tk02varUni[1], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ else if (!strcmp(modelParams[i].tk02varPr,"Exponential"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].tk02varExp = tempD;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting TK02varpr to Exponential(%1.2lf)\n", spacer, modelParams[i].tk02varExp);
+ else
+ MrBayesPrint ("%s Setting TK02varpr to Exponential(%1.2lf) for partition %d\n", spacer, modelParams[i].tk02varExp, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ else if (!strcmp(modelParams[i].tk02varPr,"Fixed"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ if (tempD < TK02VAR_MIN || tempD > TK02VAR_MAX)
+ {
+ MrBayesPrint ("%s Ratevar (nu) must be in the range %f - %f\n", spacer, TK02VAR_MIN, TK02VAR_MAX);
+ return (ERROR);
+ }
+ modelParams[i].tk02varFix = tempD;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting TK02varpr to Fixed(%1.2lf)\n", spacer, modelParams[i].tk02varFix);
+ else
+ MrBayesPrint ("%s Setting TK02varpr to Fixed(%1.2lf) for partition %d\n", spacer, modelParams[i].tk02varFix, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ }
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set prior for shape of independent branch rate gamma distribution (igrvarPr) ***********************/
+ else if (!strcmp(parmName, "Igrvarpr") || !strcmp(parmName, "Ibrvarpr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ strcpy(modelParams[i].igrvarPr, tempStr);
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Igrvarpr argument\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(LEFTPAR);
+ for (i=0; i<numCurrentDivisions; i++)
+ numVars[i] = 0;
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ {
+ if (!strcmp(modelParams[i].igrvarPr,"Uniform"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].igrvarUni[numVars[i]++] = tempD;
+ if (numVars[i] == 1)
+ expecting = Expecting(COMMA);
+ else
+ {
+ if (modelParams[i].igrvarUni[0] >= modelParams[i].igrvarUni[1])
+ {
+ MrBayesPrint ("%s Lower value for uniform should be greater than upper value\n", spacer);
+ return (ERROR);
+ }
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Igrvarpr to Uniform(%1.2lf,%1.2lf)\n", spacer, modelParams[i].igrvarUni[0], modelParams[i].igrvarUni[1]);
+ else
+ MrBayesPrint ("%s Setting Igrvarpr to Uniform(%1.2lf,%1.2lf) for partition %d\n", spacer, modelParams[i].igrvarUni[0], modelParams[i].igrvarUni[1], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ else if (!strcmp(modelParams[i].igrvarPr,"Exponential"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].igrvarExp = tempD;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Igrvarpr to Exponential(%1.2lf)\n", spacer, modelParams[i].igrvarExp);
+ else
+ MrBayesPrint ("%s Setting Igrvarpr to Exponential(%1.2lf) for partition %d\n", spacer, modelParams[i].igrvarExp, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ else if (!strcmp(modelParams[i].igrvarPr,"Fixed"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ if (tempD < IGRVAR_MIN || tempD > IGRVAR_MAX)
+ {
+ MrBayesPrint ("%s Igrvar must be in the range %f - %f\n", spacer, IGRVAR_MIN, IGRVAR_MAX);
+ return (ERROR);
+ }
+ modelParams[i].igrvarFix = tempD;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Igrvarpr to Fixed(%1.2lf)\n", spacer, modelParams[i].igrvarFix);
+ else
+ MrBayesPrint ("%s Setting Igrvarpr to Fixed(%1.2lf) for partition %d\n", spacer, modelParams[i].igrvarFix, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ }
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set prior for variance of mixed relaxed clock model (mixedvarPr) ***********************/
+ else if (!strcmp(parmName, "Mixedvarpr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ strcpy(modelParams[i].mixedvarPr, tempStr);
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Mixedvarpr argument\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(LEFTPAR);
+ for (i=0; i<numCurrentDivisions; i++)
+ numVars[i] = 0;
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ {
+ if (!strcmp(modelParams[i].mixedvarPr,"Uniform"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].mixedvarUni[numVars[i]++] = tempD;
+ if (numVars[i] == 1)
+ expecting = Expecting(COMMA);
+ else
+ {
+ if (modelParams[i].mixedvarUni[0] >= modelParams[i].mixedvarUni[1])
+ {
+ MrBayesPrint ("%s Lower value for uniform should be greater than upper value\n", spacer);
+ return (ERROR);
+ }
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Mixedvarpr to Uniform(%1.2lf,%1.2lf)\n", spacer, modelParams[i].mixedvarUni[0], modelParams[i].mixedvarUni[1]);
+ else
+ MrBayesPrint ("%s Setting Mixedvarpr to Uniform(%1.2lf,%1.2lf) for partition %d\n", spacer, modelParams[i].mixedvarUni[0], modelParams[i].mixedvarUni[1], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ else if (!strcmp(modelParams[i].mixedvarPr,"Exponential"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].mixedvarExp = tempD;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Mixedvarpr to Exponential(%1.2lf)\n", spacer, modelParams[i].mixedvarExp);
+ else
+ MrBayesPrint ("%s Setting Mixedvarpr to Exponential(%1.2lf) for partition %d\n", spacer, modelParams[i].mixedvarExp, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ else if (!strcmp(modelParams[i].mixedvarPr,"Fixed"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ if (tempD < IGRVAR_MIN || tempD > IGRVAR_MAX || tempD < TK02VAR_MIN || tempD > TK02VAR_MAX)
+ {
+ MrBayesPrint ("%s Mixedvar must be in the range %f - %f\n", spacer, IGRVAR_MIN, IGRVAR_MAX);
+ return (ERROR);
+ }
+ modelParams[i].mixedvarFix = tempD;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Mixedvarpr to Fixed(%1.2lf)\n", spacer, modelParams[i].mixedvarFix);
+ else
+ MrBayesPrint ("%s Setting Mixedvarpr to Fixed(%1.2lf) for partition %d\n", spacer, modelParams[i].mixedvarFix, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ }
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Growthpr (growthPr) **************************************************************/
+ else if (!strcmp(parmName, "Growthpr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ {
+ expecting = Expecting(ALPHA);
+ isNegative = NO;
+ }
+ else if (expecting == Expecting(ALPHA))
+ {
+ isNegative = NO;
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ strcpy(modelParams[i].growthPr, tempStr);
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Growthpr argument\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(LEFTPAR);
+ for (i=0; i<numCurrentDivisions; i++)
+ numVars[i] = 0;
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ expecting = Expecting(NUMBER) | Expecting(DASH);
+ }
+ else if (expecting == Expecting(DASH))
+ {
+ expecting = Expecting(NUMBER);
+ isNegative = YES;
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA))
+ {
+ if (!strcmp(modelParams[i].growthPr,"Uniform"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ if (isNegative == YES)
+ tempD *= -1.0;
+ modelParams[i].growthUni[numVars[i]++] = tempD;
+ if (numVars[i] == 1)
+ expecting = Expecting(COMMA);
+ else
+ {
+ if (modelParams[i].growthUni[0] >= modelParams[i].growthUni[1])
+ {
+ MrBayesPrint ("%s Lower value for uniform should be greater than upper value\n", spacer);
+ return (ERROR);
+ }
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Growthpr to Uniform(%1.2lf,%1.2lf)\n", spacer, modelParams[i].growthUni[0], modelParams[i].growthUni[1]);
+ else
+ MrBayesPrint ("%s Setting Growthpr to Uniform(%1.2lf,%1.2lf) for partition %d\n", spacer, modelParams[i].growthUni[0], modelParams[i].growthUni[1], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ else if (!strcmp(modelParams[i].growthPr,"Normal"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ if (isNegative == YES)
+ tempD *= -1.0;
+ modelParams[i].growthNorm[numVars[i]++] = tempD;
+ if (numVars[i] == 1)
+ expecting = Expecting(COMMA);
+ else
+ {
+ if (modelParams[i].growthNorm[1] < 0.0)
+ {
+ MrBayesPrint ("%s Variance for normal distribution should be greater than zero\n", spacer);
+ return (ERROR);
+ }
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Growthpr to Normal(%1.2lf,%1.2lf)\n", spacer, modelParams[i].growthNorm[0], modelParams[i].growthNorm[1]);
+ else
+ MrBayesPrint ("%s Setting Growthpr to Normal(%1.2lf,%1.2lf) for partition %d\n", spacer, modelParams[i].growthNorm[0], modelParams[i].growthNorm[1], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ else if (!strcmp(modelParams[i].growthPr,"Exponential"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].growthExp = tempD;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Growthpr to Exponential(%1.2lf)\n", spacer, modelParams[i].growthExp);
+ else
+ MrBayesPrint ("%s Setting Growthpr to Exponential(%1.2lf) for partition %d\n", spacer, modelParams[i].growthExp, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ else if (!strcmp(modelParams[i].growthPr,"Fixed"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ if (isNegative == YES)
+ tempD *= -1.0;
+ modelParams[i].growthFix = tempD;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Growthpr to Fixed(%1.2lf)\n", spacer, modelParams[i].growthFix);
+ else
+ MrBayesPrint ("%s Setting Growthpr to Fixed(%1.2lf) for partition %d\n", spacer, modelParams[i].growthFix, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ }
+ isNegative = NO;
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Aamodelpr (aaModelPr) **************************************************************/
+ else if (!strcmp(parmName, "Aamodelpr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ {
+ expecting = Expecting(ALPHA);
+ foundAaSetting = foundExp = modelIsFixed = foundDash = NO;
+ fromI = 0;
+ for (i=0; i<10; i++)
+ tempAaModelPrs[i] = 0.0;
+ }
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (foundAaSetting == NO)
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0))
+ {
+ strcpy(modelParams[i].aaModelPr, tempStr);
+ if (!strcmp(modelParams[i].aaModelPr, "Mixed"))
+ {
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Aamodelpr to %s\n", spacer, modelParams[i].aaModelPr);
+ else
+ MrBayesPrint ("%s Setting Aamodelpr to %s for partition %d\n", spacer, modelParams[i].aaModelPr, i+1);
+ }
+ }
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Aamodelpr argument\n", spacer);
+ return (ERROR);
+ }
+ foundAaSetting = YES;
+ if (!strcmp(tempStr, "Fixed"))
+ {
+ modelIsFixed = YES;
+ expecting = Expecting(LEFTPAR);
+ }
+ else
+ {
+ expecting = Expecting(LEFTPAR) | Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ }
+ else
+ {
+ if (modelIsFixed == YES)
+ {
+ if (IsSame ("Poisson", tkn) == SAME || IsSame ("Poisson", tkn) == CONSISTENT_WITH)
+ strcpy (tempStr, "Poisson");
+ else if (IsSame ("Equalin", tkn) == SAME || IsSame ("Equalin", tkn) == CONSISTENT_WITH)
+ strcpy (tempStr, "Equalin");
+ else if (IsSame ("Jones", tkn) == SAME || IsSame ("Jones", tkn) == CONSISTENT_WITH)
+ strcpy (tempStr, "Jones");
+ else if (IsSame ("Dayhoff", tkn) == SAME || IsSame ("Dayhoff", tkn) == CONSISTENT_WITH)
+ strcpy (tempStr, "Dayhoff");
+ else if (IsSame ("Mtrev", tkn) == SAME || IsSame ("Mtrev", tkn) == CONSISTENT_WITH)
+ strcpy (tempStr, "Mtrev");
+ else if (IsSame ("Mtmam", tkn) == SAME || IsSame ("Mtmam", tkn) == CONSISTENT_WITH)
+ strcpy (tempStr, "Mtmam");
+ else if (IsSame ("Wag", tkn) == SAME || IsSame ("Wag", tkn) == CONSISTENT_WITH)
+ strcpy (tempStr, "Wag");
+ else if (IsSame ("Rtrev", tkn) == SAME || IsSame ("Rtrev", tkn) == CONSISTENT_WITH)
+ strcpy (tempStr, "Rtrev");
+ else if (IsSame ("Cprev", tkn) == SAME || IsSame ("Cprev", tkn) == CONSISTENT_WITH)
+ strcpy (tempStr, "Cprev");
+ else if (IsSame ("Vt", tkn) == SAME || IsSame ("Vt", tkn) == CONSISTENT_WITH)
+ strcpy (tempStr, "Vt");
+ else if (IsSame ("Blosum", tkn) == SAME || IsSame ("Blosum", tkn) == CONSISTENT_WITH)
+ strcpy (tempStr, "Blosum");
+ else if (IsSame ("Blossum", tkn) == SAME || IsSame ("Blossum", tkn) == CONSISTENT_WITH)
+ strcpy (tempStr, "Blosum");
+ else if (IsSame ("LG", tkn) == SAME || IsSame ("LG", tkn) == CONSISTENT_WITH)
+ strcpy (tempStr, "LG");
+ else if (IsSame ("Gtr", tkn) == SAME || IsSame ("Gtr", tkn) == CONSISTENT_WITH)
+ strcpy (tempStr, "Gtr");
+ else
+ {
+ MrBayesPrint ("%s Invalid amino acid model\n", spacer);
+ return (ERROR);
+ }
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0))
+ {
+ if (!strcmp(modelParams[i].aaModelPr, "Fixed"))
+ {
+ strcpy(modelParams[i].aaModel, tempStr);
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Aamodelpr to Fixed(%s)\n", spacer, modelParams[i].aaModel);
+ else
+ MrBayesPrint ("%s Setting Aamodelpr to Fixed(%s) for partition %d\n", spacer, modelParams[i].aaModel, i+1);
+ }
+ else
+ {
+ MrBayesPrint ("%s You cannot assign an amino acid matrix for mixed models\n", spacer);
+ return (ERROR);
+ }
+ }
+ }
+ expecting = Expecting(RIGHTPAR);
+ }
+ else
+ {
+ if (IsSame ("Exponential", tkn) == SAME || IsSame ("Exponential", tkn) == CONSISTENT_WITH)
+ {
+ foundExp = YES;
+ expecting = Expecting(LEFTPAR);
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid argument \"%s\"\n", spacer, tkn);
+ return (ERROR);
+ }
+ }
+
+ }
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ if (fromI >= 10)
+ {
+ MrBayesPrint ("%s Too many arguments in Aamodelpr\n", spacer);
+ return (ERROR);
+ }
+ if (modelIsFixed == NO)
+ {
+ if (foundExp == YES)
+ {
+ if (foundDash == YES)
+ tempAaModelPrs[fromI++] = -tempD;
+ else
+ tempAaModelPrs[fromI++] = tempD;
+ expecting = Expecting(RIGHTPAR);
+ }
+ else
+ {
+ if (foundDash == YES)
+ {
+ MrBayesPrint ("%s Unexpected \"-\" in Aamodelpr\n", spacer);
+ return (ERROR);
+ }
+ else
+ {
+ if (tempD <= 0.000000000001)
+ tempAaModelPrs[fromI++] = -1000000000;
+ else
+ tempAaModelPrs[fromI++] = (MrBFlt) log(tempD);
+ }
+ expecting = Expecting(COMMA) | Expecting(RIGHTPAR);
+ }
+ foundDash = NO;
+ }
+ else
+ {
+ MrBayesPrint ("%s Not expecting a number\n", spacer);
+ return (ERROR);
+ }
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ if (modelIsFixed == YES)
+ expecting = Expecting(ALPHA);
+ else
+ {
+ if (foundExp == YES)
+ expecting = Expecting(NUMBER) | Expecting(DASH);
+ else
+ expecting = Expecting(NUMBER) | Expecting(ALPHA);
+ }
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ if (modelIsFixed == YES)
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ else
+ {
+ if (foundExp == YES)
+ {
+ foundExp = NO;
+ expecting = Expecting(COMMA) | Expecting(RIGHTPAR);
+ }
+ else
+ {
+ if (fromI < 10)
+ {
+ MrBayesPrint ("%s Too few arguments in Aamodelpr\n", spacer);
+ return (ERROR);
+ }
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && modelParams[i].dataType == PROTEIN)
+ {
+ if (!strcmp(modelParams[i].aaModelPr, "Fixed"))
+ {
+ MrBayesPrint ("%s You cannot assign model prior probabilities for a fixed amino acid model\n", spacer);
+ return (ERROR);
+ }
+ else
+ {
+ for (j=0; j<10; j++)
+ modelParams[i].aaModelPrProbs[j] = tempAaModelPrs[j];
+ }
+ }
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ }
+ }
+ else if (expecting == Expecting(DASH))
+ {
+ if (foundExp == YES)
+ {
+ foundDash = YES;
+ expecting = Expecting(NUMBER);
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid argument \"%s\"\n", spacer, tkn);
+ return (ERROR);
+ }
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ if (modelIsFixed == YES)
+ {
+ MrBayesPrint ("%s Not expecting \"%s\"\n", spacer, tkn);
+ return (ERROR);
+ }
+ else
+ expecting = Expecting(NUMBER) | Expecting(ALPHA);
+ }
+ else
+ return (ERROR);
+ }
+ /* set Brownscalepr (brownScalesPr) ****************************************************/
+ else if (!strcmp(parmName, "Brownscalepr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ flag = 0;
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && modelParams[i].dataType == CONTINUOUS)
+ {
+ strcpy(modelParams[i].brownScalesPr, tempStr);
+ flag = 1;
+ }
+ }
+ if (flag == 0)
+ {
+ MrBayesPrint ("%s Warning: %s can be set only for partition containing CONTINUOUS data.\
+ Currently there is no active partition with such data. ", spacer, parmName);
+ return (ERROR);
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid Brownscalepr argument\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(LEFTPAR);
+ for (i=0; i<numCurrentDivisions; i++)
+ numVars[i] = 0;
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && modelParams[i].dataType == CONTINUOUS)
+ {
+ if (!strcmp(modelParams[i].brownScalesPr,"Uniform"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].brownScalesUni[numVars[i]++] = tempD;
+ if (numVars[i] == 1)
+ expecting = Expecting(COMMA);
+ else
+ {
+ if (modelParams[i].brownScalesUni[0] >= modelParams[i].brownScalesUni[1])
+ {
+ MrBayesPrint ("%s Lower value for uniform should be greater than upper value\n", spacer);
+ return (ERROR);
+ }
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Brownscalepr to Uniform(%1.2lf,%1.2lf)\n", spacer, modelParams[i].brownScalesUni[0], modelParams[i].brownScalesUni[1]);
+ else
+ MrBayesPrint ("%s Setting Brownscalepr to Uniform(%1.2lf,%1.2lf) for partition %d\n", spacer, modelParams[i].brownScalesUni[0], modelParams[i].brownScalesUni[1], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ else if (!strcmp(modelParams[i].brownScalesPr,"Gamma"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].brownScalesGamma[numVars[i]++] = tempD;
+ if (numVars[i] == 1)
+ expecting = Expecting(COMMA);
+ else
+ {
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Brownscalepr to Gamma Mean=%1.2lf Var=%1.2lf\n", spacer, modelParams[i].brownScalesGamma[0], modelParams[i].brownScalesGamma[1]);
+ else
+ MrBayesPrint ("%s Setting Brownscalepr to Gamma Mean=%1.2lf Var=%1.2lf for partition %d\n", spacer, modelParams[i].brownScalesGamma[0], modelParams[i].brownScalesGamma[1], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ else if (!strcmp(modelParams[i].brownScalesPr,"Gammamean"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].brownScalesGammaMean = tempD;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Brownscalepr to Gamma Mean=<char. ave.> Var=%1.2lf\n", spacer, modelParams[i].brownScalesGammaMean);
+ else
+ MrBayesPrint ("%s Setting Brownscalepr to Gamma Mean=<char.ave.> Var=%1.2lf for partition %d\n", spacer, modelParams[i].brownScalesGammaMean, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ else if (!strcmp(modelParams[i].brownScalesPr,"Fixed"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].brownScalesFix = tempD;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting Brownscalepr to Fixed(%1.2lf)\n", spacer, modelParams[i].brownScalesFix);
+ else
+ MrBayesPrint ("%s Setting Brownscalepr to Fixed(%1.2lf) for partition %d\n", spacer, modelParams[i].brownScalesFix, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ }
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set M10betapr (m10betapr) ********************************************************/
+ else if (!strcmp(parmName, "M10betapr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ flag = 0;
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA))
+ {
+ strcpy(modelParams[i].m10betapr, tempStr);
+ flag = 1;
+ }
+ }
+ if (flag == 0)
+ {
+ MrBayesPrint ("%s Warning: %s can be set only for partition containing data of at least one of the following type: DNA, RNA.\
+ Currently there is no active partition with such data. ", spacer, parmName);
+ return (ERROR);
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid M10betapr argument\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(LEFTPAR);
+ for (i=0; i<numCurrentDivisions; i++)
+ numVars[i] = 0;
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA))
+ {
+ if (!strcmp(modelParams[i].m10betapr,"Uniform"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].m10betaUni[numVars[i]++] = tempD;
+ if (numVars[i] == 1)
+ expecting = Expecting(COMMA);
+ else
+ {
+ if (modelParams[i].m10betaUni[0] >= modelParams[i].m10betaUni[1])
+ {
+ MrBayesPrint ("%s Lower value for uniform should be greater than upper value\n", spacer);
+ return (ERROR);
+ }
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting M10betapr to Uniform(%1.2lf,%1.2lf)\n", spacer, modelParams[i].m10betaUni[0], modelParams[i].m10betaUni[1]);
+ else
+ MrBayesPrint ("%s Setting M10betapr to Uniform(%1.2lf,%1.2lf) for partition %d\n", spacer, modelParams[i].m10betaUni[0], modelParams[i].m10betaUni[1], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ else if (!strcmp(modelParams[i].m10betapr,"Exponential"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].m10betaExp = tempD;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting M10betapr to Exponential(%1.2lf)\n", spacer, modelParams[i].m10betaExp);
+ else
+ MrBayesPrint ("%s Setting M10betapr to Exponential(%1.2lf) for partition %d\n", spacer, modelParams[i].m10betaExp, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ else if (!strcmp(modelParams[i].m10betapr,"Fixed"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].m10betaFix[numVars[i]++] = tempD;
+ if (numVars[i] == 1)
+ expecting = Expecting(COMMA);
+ else
+ {
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting M10betapr to Fixed(%1.2lf,%1.2lf)\n", spacer, modelParams[i].m10betaFix[0], modelParams[i].m10betaFix[1]);
+ else
+ MrBayesPrint ("%s Setting M10betapr to Fixed(%1.2lf,%1.2lf) for partition %d\n", spacer, modelParams[i].m10betaFix[0], modelParams[i].m10betaFix[1], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ }
+ }
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set M10gammapr (m10gammapr) ********************************************************/
+ else if (!strcmp(parmName, "M10gammapr"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ flag = 0;
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA))
+ {
+ strcpy(modelParams[i].m10gammapr, tempStr);
+ flag = 1;
+ }
+ }
+ if (flag == 0)
+ {
+ MrBayesPrint ("%s Warning: %s can be set only for partition containing data of at least one of the following type: DNA, RNA.\
+ Currently there is no active partition with such data. ", spacer, parmName);
+ return (ERROR);
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid M10gammapr argument\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(LEFTPAR);
+ for (i=0; i<numCurrentDivisions; i++)
+ numVars[i] = 0;
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA))
+ {
+ if (!strcmp(modelParams[i].m10gammapr,"Uniform"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].m10gammaUni[numVars[i]++] = tempD;
+ if (numVars[i] == 1)
+ expecting = Expecting(COMMA);
+ else
+ {
+ if (modelParams[i].m10gammaUni[0] >= modelParams[i].m10gammaUni[1])
+ {
+ MrBayesPrint ("%s Lower value for uniform should be greater than upper value\n", spacer);
+ return (ERROR);
+ }
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting M10gammapr to Uniform(%1.2lf,%1.2lf)\n", spacer, modelParams[i].m10gammaUni[0], modelParams[i].m10gammaUni[1]);
+ else
+ MrBayesPrint ("%s Setting M10gammapr to Uniform(%1.2lf,%1.2lf) for partition %d\n", spacer, modelParams[i].m10gammaUni[0], modelParams[i].m10gammaUni[1], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ else if (!strcmp(modelParams[i].m10gammapr,"Exponential"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].m10gammaExp = tempD;
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting M10gammapr to Exponential(%1.2lf)\n", spacer, modelParams[i].m10gammaExp);
+ else
+ MrBayesPrint ("%s Setting M10gammapr to Exponential(%1.2lf) for partition %d\n", spacer, modelParams[i].m10gammaExp, i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ else if (!strcmp(modelParams[i].m10gammapr,"Fixed"))
+ {
+ sscanf (tkn, "%lf", &tempD);
+ modelParams[i].m10gammaFix[numVars[i]++] = tempD;
+ if (numVars[i] == 1)
+ expecting = Expecting(COMMA);
+ else
+ {
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting M10gammapr to Fixed(%1.2lf,%1.2lf)\n", spacer, modelParams[i].m10gammaFix[0], modelParams[i].m10gammaFix[1]);
+ else
+ MrBayesPrint ("%s Setting M10gammapr to Fixed(%1.2lf,%1.2lf) for partition %d\n", spacer, modelParams[i].m10gammaFix[0], modelParams[i].m10gammaFix[1], i+1);
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ }
+ }
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+
+ else
+ return (ERROR);
+ }
+
+ return (NO_ERROR);
+}
+
+
+int DoQuit (void)
+{
+ int i;
+ char tempName[100];
+
+ /* free information for model and matrix */
+ FreeModel ();
+ FreeMatrix ();
+
+ SafeFclose (&logFileFp);
+ logToFile = NO;
+
+ /* check to see if any memory has not been freed */
+ for (i=0; i<NUM_ALLOCS; i++)
+ {
+ if (memAllocs[i] == YES)
+ {
+ MrBayesPrint (" WARNING: Memory (%d) has not been freed\n", i);
+ if (mode == INTERACTIVE && quitOnError == NO)
+ {
+ MrBayesPrint ("%s Hit return key to continue ", spacer);
+ fflush (stdin);
+ if (fgets (tempName, 100, stdin) == NULL)
+ {
+ printf ("Error in function: %s at line: %d in file: %s", __FUNCTION__, __LINE__, __FILE__);
+ }
+ }
+ }
+ }
+
+ /* free modelIndicatorParams and modelElementNames */
+ for (i=0; i<203; i++)
+ free (modelElementNames[1][i]);
+ for (i=0; i<3; i++)
+ free (modelElementNames[i]);
+ free (modelElementNames);
+ free (modelIndicatorParams);
+
+ MrBayesPrint (" Quitting program\n\n");
+
+ /* If we quit while reading a mrbayes block, then we need to make certain
+ that we return a NO_ERROR_QUIT so we can break out of DoExecute cleanly,
+ and dealloc "s" there. */
+ if (inMrbayesBlock == YES)
+ {
+ inMrbayesBlock = NO;
+ return (NO_ERROR_QUIT);
+ }
+
+ return (NO_ERROR);
+}
+
+
+int DoReport (void)
+{
+ /* TODO: smart update */
+ if (SetUpAnalysis (&globalSeed) == ERROR)
+ return (ERROR);
+ return (NO_ERROR);
+}
+
+
+int DoReportParm (char *parmName, char *tkn)
+{
+ int i, tempInt, nApplied;
+ char tempStr[100];
+
+ if (defMatrix == NO)
+ {
+ MrBayesPrint ("%s A matrix must be specified before the report settings can be altered\n", spacer);
+ return (ERROR);
+ }
+ if (inValidCommand == YES)
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ activeParts[i] = NO;
+ inValidCommand = NO;
+ }
+
+ if (expecting == Expecting(PARAMETER))
+ {
+ expecting = Expecting(EQUALSIGN);
+ }
+ else
+ {
+ /* set Applyto (Applyto) *************************************************************/
+ if (!strcmp(parmName, "Applyto"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(LEFTPAR);
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ activeParts[i] = NO;
+ fromI = toJ = -1;
+ foundDash = NO;
+ expecting = Expecting(NUMBER) | Expecting(ALPHA);
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ if (fromI != -1)
+ activeParts[fromI-1] = YES;
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ foundComma = YES;
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsSame ("All", tkn) == DIFFERENT)
+ {
+ MrBayesPrint ("%s Do not understand delimiter \"%s\"\n", spacer, tkn);
+ return (ERROR);
+ }
+ for (i=0; i<numCurrentDivisions; i++)
+ activeParts[i] = YES;
+ expecting = Expecting(RIGHTPAR);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ sscanf (tkn, "%d", &tempInt);
+ if (tempInt > numCurrentDivisions)
+ {
+ MrBayesPrint ("%s Partition delimiter is too large\n", spacer);
+ return (ERROR);
+ }
+ if (fromI == -1)
+ fromI = tempInt;
+ else if (fromI != -1 && toJ == -1 && foundDash == YES && foundComma == NO)
+ {
+ toJ = tempInt;
+ for (i=fromI-1; i<toJ; i++)
+ activeParts[i] = YES;
+ fromI = toJ = -1;
+ foundDash = NO;
+ }
+ else if (fromI != -1 && toJ == -1 && foundDash == NO && foundComma == YES)
+ {
+ activeParts[fromI-1] = YES;
+ fromI = tempInt;
+ foundComma = NO;
+ }
+
+ expecting = Expecting(COMMA);
+ expecting |= Expecting(DASH);
+ expecting |= Expecting(RIGHTPAR);
+ }
+ else if (expecting == Expecting(DASH))
+ {
+ foundDash = YES;
+ expecting = Expecting(NUMBER);
+ }
+ else
+ return (ERROR);
+ }
+ /* set report format of tratio ***************************************************/
+ else if (!strcmp(parmName, "Tratio"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting (ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ tempInt = NO;
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ /* check that data type is correct; we do not know yet if the user will specify
+ a nst=2 model so we cannot check that tratio is an active parameter */
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA))
+ {
+ strcpy(modelParams[i].tratioFormat, tempStr);
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting transition/transversion rate ratio (tratio) format to %s\n", spacer, modelParams[i].tratioFormat);
+ else
+ MrBayesPrint ("%s Setting transition/transversion rate ratio (tratio) format to %s for partition %d\n", spacer, modelParams[i].tratioFormat, i+1);
+ }
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid transition/transversion rate ratio (tratio) format \n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set report format of revmat ***************************************************/
+ else if (!strcmp(parmName, "Revmat"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting (ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ tempInt = NO;
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ /* check that data type is correct; we do not know yet if the user will specify
+ a nst=6 model so we cannot check that revmat is an active parameter */
+ if ((activeParts[i] == YES || nApplied == 0) && (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA))
+ {
+ strcpy(modelParams[i].revmatFormat, tempStr);
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting reversible rate matrix (revmat) format to %s\n", spacer, modelParams[i].revmatFormat);
+ else
+ MrBayesPrint ("%s Setting reversible rate matrix (revmat) format to %s for partition %d\n", spacer, modelParams[i].revmatFormat, i+1);
+ }
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid reversible rate matrix (revmat) format \n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set report format of ratemult *************************************************/
+ else if (!strcmp(parmName, "Ratemult"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting (ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ tempInt = NO;
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ /* we do not know yet if the user will specify variable rates across partitions
+ so only check that we have more than one partition in the model */
+ if ((activeParts[i] == YES || nApplied == 0) && numCurrentDivisions > 1)
+ {
+ strcpy(modelParams[i].ratemultFormat, tempStr);
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting rate multiplier (ratemult) format to %s\n", spacer, modelParams[i].ratemultFormat);
+ else
+ MrBayesPrint ("%s Setting rate multiplier (ratemult) format to %s for partition %d\n", spacer, modelParams[i].ratemultFormat, i+1);
+ }
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid rate multiplier (ratemult) format \n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set report format of tree ***************************************************/
+ else if (!strcmp(parmName, "Tree"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting (ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ tempInt = NO;
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ strcpy(modelParams[i].treeFormat, tempStr);
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Setting tree report format to %s\n", spacer, modelParams[i].treeFormat);
+ else
+ MrBayesPrint ("%s Setting tree report format to %s for partition %d\n", spacer, modelParams[i].treeFormat, i+1);
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid tree report format \n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set inferancstates ***********************************************************/
+ else if (!strcmp(parmName, "Ancstates"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting (ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ {
+ strcpy(modelParams[i].inferAncStates,tempStr);
+ if (!strcmp(tempStr,"Yes"))
+ {
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Reporting ancestral states (if applicable)\n", spacer);
+ else
+ MrBayesPrint ("%s Reporting ancestral states for partition %d (if applicable)\n", spacer, i+1);
+ }
+ else
+ {
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Not reporting ancestral states\n", spacer);
+ else
+ MrBayesPrint ("%s Not reporting ancestral states for partition %d\n", spacer, i+1);
+ }
+ }
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid ancstates option\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set inferSiteRates ***************************************************************/
+ else if (!strcmp(parmName, "Siterates"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting (ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ {
+ strcpy (modelParams[i].inferSiteRates, tempStr);
+ if (!strcmp(tempStr,"Yes"))
+ {
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Reporting site rates (if applicable)\n", spacer);
+ else
+ MrBayesPrint ("%s Reporting site rates for partition %d (if applicable)\n", spacer, i+1);
+ }
+ else
+ {
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Not reporting site rates\n", spacer);
+ else
+ MrBayesPrint ("%s Not reporting site rates for partition %d\n", spacer, i+1);
+ }
+ }
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid siterates option\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set inferpossel *************************************************************/
+ else if (!strcmp(parmName, "Possel"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting (ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ {
+ strcpy (modelParams[i].inferPosSel, tempStr);
+ if (!strcmp(tempStr, "Yes"))
+ {
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Reporting positive selection (if applicable)\n", spacer);
+ else
+ MrBayesPrint ("%s Reporting positive selection for partition %d (if applicable)\n", spacer, i+1);
+ }
+ else
+ {
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Not reporting positive selection\n", spacer);
+ else
+ MrBayesPrint ("%s Not reporting positive selection for partition %d\n", spacer, i+1);
+ }
+ }
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid possel option\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ /* set inferSiteOmegas *************************************************************/
+ else if (!strcmp(parmName, "Siteomega"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting (ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ nApplied = NumActiveParts ();
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParts[i] == YES || nApplied == 0)
+ {
+ strcpy (modelParams[i].inferSiteOmegas, tempStr);
+ if (!strcmp(tempStr, "Yes"))
+ {
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Reporting site omega values (if applicable)\n", spacer);
+ else
+ MrBayesPrint ("%s Reporting site omega values for partition %d (if applicable)\n", spacer, i+1);
+ }
+ else
+ {
+ if (nApplied == 0 && numCurrentDivisions == 1)
+ MrBayesPrint ("%s Not reporting site omega values\n", spacer);
+ else
+ MrBayesPrint ("%s Not reporting site omega values for partition %d\n", spacer, i+1);
+ }
+ }
+ }
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid siteomega option\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ else
+ {
+ return (ERROR);
+ }
+ }
+
+ return (NO_ERROR);
+}
+
+
+int DoStartvals (void)
+{
+ MrBayesPrint ("%s Successfully set starting values\n", spacer);
+ /*
+ for (i=0; i<numParams; i++)
+ assert (IsTreeConsistent(¶ms[i], 0, 0) == YES);
+ */
+ return (NO_ERROR);
+}
+
+
+int DoStartvalsParm (char *parmName, char *tkn)
+{
+ int i, j, k, nMatches, tempInt, treeIndex, chainId, ret;
+ MrBFlt tempFloat, *value, *subValue;
+ Tree *theTree, *usrTree;
+ PolyTree *thePolyTree;
+ MrBFlt minRate, maxRate, clockRate;
+ static Param *param = NULL;
+ static MrBFlt *theValue, theValueMin, theValueMax;
+ static int useSubvalues, useStdStateFreqs, useIntValues, numExpectedValues, nValuesRead, runIndex, chainIndex, foundName, foundDash;
+ static char *temp=NULL, *tempName=NULL;
+
+ if (defMatrix == NO)
+ {
+ MrBayesPrint ("%s A matrix must be specified before starting values can be changed\n", spacer);
+ return (ERROR);
+ }
+
+ if (expecting == Expecting(PARAMETER))
+ {
+ if (!strcmp(parmName, "Xxxxxxxxxx"))
+ {
+ /* we expect a parameter name with possible run and chain specification as follows:
+ <param_name>(<run>,<chain>)=(<number>,...) -- apply to run <run> and chain <chain>
+ <param_name>(,<chain>)=(<number>,...) -- apply to chain <chain> for all runs
+ <param_name>(<run>,)=(<number>,...) -- apply to run <run> for all chains
+
+ topology and branch length parameters are specified like
+ <param_name>(<run>,<chain>)=<tree_name>|<Newick_tree_spec>
+
+ parameter names will often be followed by partition specifiers like:
+ pi{all}
+ pinvar{1,4,5}
+ so we need to assemble the parameter name from several tokens that are parsed out separately;
+ here we receive only the first part (before the left curly, if present)
+ */
+
+ /* copy to local parameter name */
+ SafeStrcpy (&tempName, tkn);
+ param = NULL;
+ runIndex = chainIndex = -1;
+ useSubvalues = NO;
+ useIntValues = NO;
+ useStdStateFreqs = NO;
+ foundComma = foundEqual = foundName = foundDash = NO;
+ expecting = Expecting(LEFTCURL) | Expecting(LEFTPAR) | Expecting(EQUALSIGN);
+ }
+ else
+ return (ERROR);
+ }
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (param == NULL)
+ {
+ /* we are still assembling the parameter name */
+ SafeStrcat (&tempName, tkn);
+ expecting = Expecting(RIGHTCURL) | Expecting(COMMA) | Expecting(LEFTPAR) | Expecting(EQUALSIGN);
+ }
+ else
+ {
+ /* we have a tree name; now find the tree based on name, case insensitive */
+ if (GetUserTreeFromName (&treeIndex, tkn) == ERROR || treeIndex == -1)
+ {
+ MrBayesPrint ("%s Error in finding user tree\n", spacer);
+ return (ERROR);
+ }
+
+ /* set the tree parameter */
+ for (i=0; i<chainParams.numRuns; i++)
+ {
+ if (runIndex != -1 && i != runIndex)
+ continue;
+ for (j=0; j<chainParams.numChains; j++)
+ {
+ if (chainIndex != -1 && j != chainIndex)
+ continue;
+ chainId = i*chainParams.numChains + j;
+ if (param->paramType != P_POPSIZE)
+ {
+ if (param->paramType == P_TOPOLOGY || param->paramType == P_BRLENS || param->paramType == P_SPECIESTREE)
+ {
+ /* topology or brlens or speciestree params */
+ theTree = GetTree (param, chainId, 0);
+ usrTree = GetTree (param, chainId, 1); /* use as scratch space */
+ }
+ else
+ {
+ /* relaxed clock params */
+ theTree = GetTree (modelSettings[param->relParts[0]].brlens, chainId, 0);
+ usrTree = GetTree (modelSettings[param->relParts[0]].brlens, chainId, 1);
+ }
+ CopyToTreeFromTree (usrTree, theTree);
+ if (param->paramType == P_SPECIESTREE)
+ thePolyTree = AllocatePolyTree(numSpecies);
+ else
+ thePolyTree = AllocatePolyTree (numTaxa);
+ CopyToPolyTreeFromPolyTree (thePolyTree, userTree[treeIndex]);
+ if (param->paramType == P_SPECIESTREE)
+ {
+ ResetIntNodeIndices(thePolyTree);
+ }
+ else
+ {
+ PrunePolyTree (thePolyTree);
+ ResetTipIndices(thePolyTree);
+ }
+ RandResolve (NULL, thePolyTree, &globalSeed, theTree->isRooted);
+ GetPolyDownPass(thePolyTree);
+ ResetIntNodeIndices(thePolyTree);
+ if (param->paramType == P_SPECIESTREE)
+ {
+ ret=CopyToSpeciesTreeFromPolyTree (usrTree, thePolyTree);
+ }
+ else
+ ret=CopyToTreeFromPolyTree (usrTree, thePolyTree);
+ FreePolyTree (thePolyTree);
+ if (ret==ERROR)
+ return ERROR;
+ }
+ else
+ {
+ /* param->paramType == P_POPSIZE */
+ theTree = GetTree (modelSettings[param->relParts[0]].speciesTree, chainId, 0);
+ usrTree = GetTree (modelSettings[param->relParts[0]].speciesTree, chainId, 1);
+ CopyToTreeFromTree (usrTree, theTree);
+ thePolyTree = AllocatePolyTree(numSpecies);
+ CopyToPolyTreeFromPolyTree (thePolyTree, userTree[treeIndex]);
+ ResetIntNodeIndices(thePolyTree);
+ RandResolve (NULL, thePolyTree, &globalSeed, theTree->isRooted);
+ CopyToSpeciesTreeFromPolyTree (usrTree, thePolyTree);
+ FreePolyTree (thePolyTree);
+ }
+ if (param->paramType == P_TOPOLOGY)
+ {
+ if (theTree->checkConstraints == YES && CheckSetConstraints (usrTree) == ERROR)
+ {
+ MrBayesPrint ("%s Could not set the constraints for topology parameter '%s'\n", spacer, param->name);
+ return (ERROR);
+ }
+ if (ResetTopologyFromTree (theTree, usrTree) == ERROR)
+ {
+ MrBayesPrint ("%s Could not set the topology parameter '%s'\n", spacer, param->name);
+ return (ERROR);
+ }
+ if (theTree->checkConstraints == YES && CheckSetConstraints (theTree)==ERROR)
+ {
+ MrBayesPrint ("%s Could not set the constraints for topology parameter '%s'\n", spacer, param->name);
+ return (ERROR);
+ }
+ FillTopologySubParams (param, chainId, 0, &globalSeed);
+ //MrBayesPrint ("%s Branch lengths and relaxed clock subparameters of a parameter '%s' are reset.\n", spacer, param->name);
+ if (param->paramId == TOPOLOGY_SPECIESTREE)
+ FillSpeciesTreeParams(&globalSeed, chainId, chainId+1);
+ //assert (IsTreeConsistent(param, chainId, 0) == YES);
+ }
+ else if (param->paramType == P_BRLENS)
+ {
+ if (usrTree->allDownPass[0]->length == 0.0 && param->paramId != BRLENS_CLOCK_FOSSIL)
+ {
+ MrBayesPrint ("%s User tree '%s' does not have branch lengths so it cannot be used in setting parameter '%s'\n", spacer, userTree[treeIndex]->name, param->name);
+ return (ERROR);
+ }
+ if (AreTopologiesSame (theTree, usrTree) == NO)
+ {
+ MrBayesPrint ("%s Topology of user tree '%s' wrong in setting parameter '%s'\n", spacer, userTree[treeIndex]->name, param->name);
+ return (ERROR);
+ }
+ //assert (IsTreeConsistent(param, chainId, 0) == YES);
+ /* reset node depths to ensure that non-dated tips have node depth 0.0 */
+ /* if (usrTree->isClock == YES)
+ SetNodeDepths(usrTree); */
+ if (ResetBrlensFromTree (theTree, usrTree) == ERROR)
+ {
+ MrBayesPrint ("%s Could not set parameter '%s' from user tree '%s'\n", spacer, param->name, userTree[treeIndex]->name);
+ return (ERROR);
+ }
+ if (theTree->isClock == YES && modelParams[theTree->relParts[0]].treeAgePr.prior == fixed)
+ {
+ if (!strcmp(modelParams[theTree->relParts[0]].clockPr,"Uniform")
+ || !strcmp(modelParams[theTree->relParts[0]].clockPr,"Fossilization"))
+ ResetRootHeight (theTree, modelParams[theTree->relParts[0]].treeAgePr.priorParams[0]);
+ }
+ /* the test will find suitable clock rate and ages of nodes in theTree */
+ if (theTree->isClock == YES && IsClockSatisfied (theTree,0.001) == NO)
+ {
+ MrBayesPrint ("%s Non-calibrated tips are not at the same level after setting up starting tree branch lengthes(%s) from user tree '%s'.\n",
+ spacer, param->name, userTree[treeIndex]->name);
+ ShowNodes(theTree->root,0,YES);
+ return (ERROR);
+ }
+ if (theTree->isCalibrated == YES && IsCalibratedClockSatisfied (theTree, &minRate,&maxRate, 0.001) == NO)
+ {
+ MrBayesPrint ("%s Problem setting calibrated tree parameters\n", spacer);
+ return (ERROR);
+ }
+ if (theTree->isCalibrated == YES && !strcmp(modelParams[theTree->relParts[0]].clockRatePr, "Fixed"))
+ {
+ clockRate = modelParams[theTree->relParts[0]].clockRateFix;
+ if ((clockRate < minRate && AreDoublesEqual (clockRate, minRate , 0.001) == NO) || (clockRate > maxRate && AreDoublesEqual (clockRate, maxRate , 0.001) == NO))
+ {
+ MrBayesPrint("%s Fixed branch lengths do not satisfy fixed clockrate\n", spacer);
+ return (ERROR);
+ }
+ }
+ theTree->fromUserTree=YES;
+
+ FillBrlensSubParams (param, chainId, 0);
+ //MrBayesPrint ("%s Rrelaxed clock subparamiters of a parameter '%s' are reset.\n", spacer, param->name);
+ //assert (IsTreeConsistent(param, chainId, 0) == YES);
+ if (param->paramId == BRLENS_CLOCK_SPCOAL)
+ FillSpeciesTreeParams(&globalSeed, chainId, chainId+1);
+ //assert (IsTreeConsistent(param, chainId, 0) == YES);
+ }
+ else if (param->paramType == P_CPPEVENTS || param->paramType == P_TK02BRANCHRATES ||
+ param->paramType == P_IGRBRANCHRATES || param->paramType == P_MIXEDBRCHRATES)
+ {
+ if (theTree->isCalibrated == YES && theTree->fromUserTree == NO)
+ { /* if theTree is not set from user tree then we can not garanty that branch lenghts will stay the same
+ by the time we start mcmc run because of clockrate adjustment. */
+ MrBayesPrint ("%s Set starting values for branch lengthes first before setting starting values of relaxed parameters!\n", spacer);
+ return (ERROR);
+ }
+ if (theTree->isCalibrated == NO && IsClockSatisfied (usrTree, 0.001) == NO) // user tree is not calibrated so do not check it if calibration is in place
+ {
+ MrBayesPrint ("%s Branch lengths of the user tree '%s' do not satisfy clock in setting parameter '%s'\n", spacer, userTree[treeIndex], param->name);
+ ShowNodes(usrTree->root,0,YES);
+ return (ERROR);
+ }
+ if (AreTopologiesSame (theTree, usrTree) == NO)
+ {
+ MrBayesPrint ("%s Topology of user tree '%s' is wrong in setting parameter '%s'\n", spacer, userTree[treeIndex]->name, param->name);
+ return (ERROR);
+ }
+ if (SetRelaxedClockParam (param, chainId, 0, userTree[treeIndex]) == ERROR)
+ {
+ MrBayesPrint ("%s Could not set parameter '%s' from user tree '%s'\n", spacer, param->name, userTree[treeIndex]->name);
+ return (ERROR);
+ }
+ //assert (IsTreeConsistent(param, chainId, 0) == YES);
+ }
+ else if (param->paramType == P_POPSIZE)
+ {
+ if (AreTopologiesSame (theTree, usrTree) == NO)
+ {
+ MrBayesPrint ("%s Topology of user tree '%s' is wrong in setting parameter '%s'\n", spacer, userTree[treeIndex]->name, param->name);
+ return (ERROR);
+ }
+ if (SetPopSizeParam (param, chainId, 0, userTree[treeIndex]) == ERROR)
+ {
+ MrBayesPrint ("%s Could not set parameter '%s' from user tree '%s'\n", spacer, param->name, userTree[treeIndex]->name);
+ return (ERROR);
+ }
+ }
+ else if (param->paramType == P_SPECIESTREE)
+ {
+ if (IsSpeciesTreeConsistent (usrTree, chainId) == NO)
+ {
+ MrBayesPrint ("%s User-specified species tree '%s' is inconsistent with gene trees\n", spacer, userTree[treeIndex]->name);
+ return (ERROR);
+ }
+ if (CopyToTreeFromTree (theTree, usrTree) == ERROR)
+ {
+ MrBayesPrint ("%s Could not set the species tree parameter '%s'\n", spacer, param->name);
+ return (ERROR);
+ }
+ //assert (IsTreeConsistent(param, chainId, 0) == YES);
+ }
+ }
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ }
+ else if (expecting == Expecting(LEFTCURL))
+ {
+ /* we are still assembling the parameter name */
+ SafeStrcat (&tempName, tkn);
+ expecting = Expecting(NUMBER) | Expecting(ALPHA) | Expecting(LEFTPAR) | Expecting(EQUALSIGN);
+ }
+ else if (expecting == Expecting(RIGHTCURL))
+ {
+ /* we are still assembling the parameter name */
+ SafeStrcat (&tempName, tkn);
+ foundComma = NO; /*! if there was a comma in the partition part, we should reset this variable. Otherwise we can't parse something like A{1,2}(3,4) */
+ expecting = Expecting(LEFTPAR) | Expecting(EQUALSIGN);
+ }
+ else if (expecting == Expecting(LEFTPAR))
+ {
+ if (foundEqual == NO)
+ {
+ foundName = YES; /* we found the name */
+ /* we will be reading in run and chain indices */
+ expecting = Expecting(NUMBER) | Expecting(COMMA);
+ }
+ else
+ {
+ expecting = Expecting(NUMBER);
+ expecting |= Expecting(DASH);
+ }
+ }
+ else if (expecting == Expecting(DASH))
+ {
+ foundDash = YES;
+ expecting = Expecting(NUMBER);
+ }
+ else if (expecting == Expecting(NUMBER))
+ {
+ if (foundName == NO)
+ {
+ /* we are still assembling the parameter name */
+ SafeStrcat (&tempName, tkn);
+ expecting = Expecting(COMMA) | Expecting(LEFTPAR) | Expecting(RIGHTCURL) | Expecting(EQUALSIGN);
+ }
+ else if (foundEqual == YES)
+ {
+ theValueMin = param->min;
+ theValueMax = param->max;
+
+ /* we are reading in a parameter value */
+ if (param->paramType==P_OMEGA && nValuesRead==numExpectedValues && useSubvalues == NO)
+ {
+ /* continue with subvalues */
+ nValuesRead = 0;
+ numExpectedValues = param->nSubValues/2;
+ useSubvalues = YES;
+ theValueMin = ETA;
+ theValueMax = 1.0;
+ }
+ if (param->paramType==P_OMEGA && nValuesRead==numExpectedValues && useSubvalues == NO)
+ {
+ /* continue with subvalues */
+ nValuesRead = 0;
+ numExpectedValues = param->nSubValues/2;
+ useSubvalues = YES;
+ theValueMin = ETA;
+ theValueMax = 1.0;
+ }
+ if (param->nIntValues > 0 && nValuesRead==numExpectedValues && useIntValues == NO)
+ {
+ /* continue with intValues */
+ nValuesRead = 0;
+ numExpectedValues = param->nIntValues;
+ useIntValues = YES;
+ }
+ if (param->paramType==P_PI && modelSettings[param->relParts[0]].dataType == STANDARD && param->paramId != SYMPI_EQUAL
+ && nValuesRead==numExpectedValues && useStdStateFreqs == NO)
+ {
+ /* we have read alpha_symdir, continue with multistate char state freqs */
+ nValuesRead = 0;
+ numExpectedValues = param->nStdStateFreqs;
+ if (param->hasBinaryStd == YES)
+ numExpectedValues -= 2 * modelSettings[param->relParts[0]].numBetaCats;
+ useStdStateFreqs = YES;
+ theValueMin = ETA;
+ theValueMax = 1.0;
+ }
+ nValuesRead++;
+ if (nValuesRead > numExpectedValues)
+ {
+ if (param->paramType == P_OMEGA)
+ MrBayesPrint ("%s Only %d values were expected for parameter '%s'\n", spacer, param->nValues+param->nSubValues/2, param->name);
+ else if (param->nIntValues > 0)
+ MrBayesPrint ("%s Only %d values were expected for parameter '%s'\n", spacer, param->nValues+param->nIntValues, param->name);
+ else
+ MrBayesPrint ("%s Only %d values were expected for parameter '%s'\n", spacer, numExpectedValues, param->name);
+ return (ERROR);
+ }
+ if (useIntValues == YES)
+ sscanf (tkn, "%d", &tempInt);
+ else
+ sscanf (tkn, "%lf", &tempFloat);
+ if (foundDash == YES)
+ {
+ if (useIntValues == NO)
+ tempFloat = -tempFloat;
+ else
+ tempInt = -tempInt;
+ foundDash = NO;
+ }
+ if (useIntValues == NO && (tempFloat < theValueMin || tempFloat > theValueMax))
+ {
+ MrBayesPrint ("%s The value is out of range (min = %lf; max = %lf)\n", spacer, theValueMin, theValueMax);
+ return (ERROR);
+ }
+ for (i=0; i<chainParams.numRuns; i++)
+ {
+ if (runIndex != -1 && runIndex != i)
+ continue;
+ for (j=0; j<chainParams.numChains; j++)
+ {
+ if (chainIndex != -1 && chainIndex != j)
+ continue;
+ if (useIntValues == YES)
+ {
+ GetParamIntVals (param, i*chainParams.numChains+j, 0)[nValuesRead-1] = tempInt;
+ }
+ else
+ {
+ if (useSubvalues == NO && useStdStateFreqs == NO)
+ theValue = GetParamVals (param, i*chainParams.numChains+j, 0);
+ else if (useSubvalues == YES)
+ theValue = GetParamSubVals (param, i*chainParams.numChains+j, 0);
+ else if (useStdStateFreqs == YES)
+ {
+ theValue = GetParamStdStateFreqs (param, i*chainParams.numChains+j, 0);
+ if (param->hasBinaryStd == YES)
+ theValue += 2 * modelSettings[param->relParts[0]].numBetaCats;
+ }
+ else
+ return (ERROR);
+ if (param->paramType == P_CLOCKRATE)
+ {
+ if (UpdateClockRate(tempFloat, i*chainParams.numChains+j) == ERROR)
+ {
+ return (ERROR);
+ }
+ }
+ theValue[nValuesRead-1] = tempFloat;
+ }
+ }
+ }
+ expecting = Expecting (COMMA) | Expecting(RIGHTPAR);
+ }
+ else /* if (foundEqual == NO) */
+ {
+ sscanf (tkn, "%d", &tempInt);
+ if (foundComma == NO)
+ {
+ if (tempInt <= 0 || tempInt > chainParams.numRuns)
+ {
+ MrBayesPrint ("%s Run index is out of range (min=1; max=%d)\n", spacer, chainParams.numRuns);
+ return (ERROR);
+ }
+ runIndex = tempInt - 1;
+ expecting = Expecting(COMMA);
+ }
+ else
+ {
+ if (tempInt <= 0 || tempInt > chainParams.numChains)
+ {
+ MrBayesPrint ("%s Chain index is out of range (min=1; max=%d)\n", spacer, chainParams.numChains);
+ return (ERROR);
+ }
+ chainIndex = tempInt - 1;
+ foundComma = NO;
+ expecting = Expecting(RIGHTPAR);
+ }
+ }
+ }
+ else if (expecting == Expecting(COMMA))
+ {
+ if (foundEqual == YES)
+ {
+ /* we expect another parameter value */
+ expecting = Expecting(NUMBER);
+ }
+ else /* if (foundEqual == NO) */
+ {
+ /* we will be reading in chain index, if present */
+ foundComma = YES;
+ expecting = Expecting(RIGHTPAR) | Expecting(NUMBER);
+ /* if the comma is in a list of partitions (so between { and }) we have to add the comma to the parameter name */
+ if (param == NULL && strchr(tempName, '}')==NULL && strchr(tempName, '{')!=NULL)
+ SafeStrcat (&tempName, ",");
+ }
+ }
+ else if (expecting == Expecting(RIGHTPAR))
+ {
+ if (foundEqual == NO)
+ {
+ /* this is the end of the run and chain specification */
+ expecting = Expecting(EQUALSIGN);
+ }
+ else /* if (foundEqual == YES) */
+ {
+ /* this is the end of the parameter values */
+ if (nValuesRead != numExpectedValues)
+ {
+ MrBayesPrint ("%s Expected %d values but only found %d values for parameter '%s'\n", spacer, numExpectedValues, nValuesRead, param->name);
+ return (ERROR);
+ }
+ /* Post processing needed for some parameters */
+ if (param->paramType == P_SHAPE || param->paramType == P_CORREL)
+ {
+ for (i=0; i<chainParams.numRuns; i++)
+ {
+ if (runIndex != -1 && runIndex != i)
+ continue;
+ for (j=0; j<chainParams.numChains; j++)
+ {
+ if (chainIndex != -1 && chainIndex != j)
+ continue;
+ value = GetParamVals(param,i*chainParams.numChains+j,0);
+ subValue = GetParamSubVals(param,i*chainParams.numChains+j,0);
+ if (param->paramType == P_SHAPE && !strncmp(param->name, "Alpha", 5))
+ {
+ if (DiscreteGamma (subValue, value[0], value[0], param->nSubValues, 0) == ERROR)
+ return (ERROR);
+ }
+ else if (param->paramType == P_SHAPE && !strncmp(param->name, "Sigma", 5))
+ {
+ if( DiscreteLogNormal(subValue, value[0], param->nSubValues, 1) == ERROR)
+ return (ERROR);
+ }
+ else if (param->paramType == P_CORREL)
+ {
+ if (AutodGamma (subValue, value[0], (int)(sqrt(param->nSubValues) + 0.5)) == ERROR)
+ return (ERROR);
+ }
+ }
+ }
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ }
+ else if (expecting == Expecting(EQUALSIGN))
+ {
+ foundEqual = YES;
+ foundName = YES;
+
+ /* we now know that the name is complete; try to find the parameter with this name (case insensitive) */
+ for (i=0; i<(int)strlen(tempName); i++)
+ tempName[i] = tolower(tempName[i]);
+
+ /* first check exact matches */
+ nMatches = j = 0;
+ for (i=0; i<numParams; i++)
+ {
+ param = ¶ms[i];
+ SafeStrcpy (&temp, param->name);
+ for (k=0; k<(int)(strlen(temp)); k++)
+ temp[k] = tolower(temp[k]);
+ if (strcmp(tempName,temp) == 0)
+ {
+ j = i;
+ nMatches++;
+ }
+ }
+ /* now check unambiguous abbreviation matches */
+ if (nMatches == 0)
+ {
+ nMatches = j = 0;
+ for (i=0; i<numParams; i++)
+ {
+ param = ¶ms[i];
+ SafeStrcpy (&temp, param->name);
+ for (k=0; k<(int)strlen(temp); k++)
+ temp[k] = tolower(temp[k]);
+ if (strncmp(tempName,temp,strlen(tempName)) == 0)
+ {
+ j = i;
+ nMatches++;
+ }
+ }
+ }
+
+ if (nMatches == 0)
+ {
+ extern char *tokenP;
+ MrBayesPrint ("%s Could not find parameter '%s': ignoring values\n", spacer, tempName);
+ while (*tokenP && *tokenP++!=')') {};
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ return (*tokenP ? NO_ERROR:ERROR);
+ }
+ else if (nMatches > 1)
+ {
+ MrBayesPrint ("%s Several parameters matched the abbreviated name '%s'\n", spacer, tempName);
+ return (ERROR);
+ }
+
+ param = ¶ms[j];
+ if (param->printParam == NO && !(param->paramType == P_TOPOLOGY && strcmp(modelParams[param->relParts[0]].topologyPr,"Fixed")!=0)
+ && !(param->paramType == P_CPPEVENTS)
+ && !(param->paramType == P_TK02BRANCHRATES)
+ && !(param->paramType == P_IGRBRANCHRATES)
+ && !(param->paramType == P_MIXEDBRCHRATES)
+ && !(param->paramType == P_POPSIZE && param->nValues > 1))
+ {
+ MrBayesPrint ("%s The parameter '%s' is fixed so the starting value cannot be set\n", spacer, param->name);
+ return (ERROR);
+ }
+ if (param->paramType == P_BRLENS || param->paramType == P_TOPOLOGY || param->paramType == P_CPPEVENTS ||
+ param->paramType == P_TK02BRANCHRATES || param->paramType == P_IGRBRANCHRATES || param->paramType == P_MIXEDBRCHRATES ||
+ param->paramType == P_SPECIESTREE || (param->paramType == P_POPSIZE && param->nValues > 1))
+ {
+ /* all these parameters are set from a tree */
+ expecting = Expecting (ALPHA);
+ }
+ else
+ /* run of the mill character */
+ {
+ theValueMin = param->min;
+ theValueMax = param->max;
+ if ((param->paramType == P_PI && modelParams[param->relParts[0]].dataType != STANDARD))
+ {
+ useSubvalues = YES;
+ useIntValues = NO;
+ numExpectedValues = param->nSubValues;
+ }
+ else if (param->nValues == 0 && param->nIntValues > 0)
+ {
+ useSubvalues = NO;
+ useIntValues = YES;
+ numExpectedValues = param->nIntValues;
+ }
+ else if (param->nValues > 0)
+ {
+ useSubvalues = NO;
+ useIntValues = NO;
+ numExpectedValues = param->nValues;
+ }
+ else
+ {
+ MrBayesPrint ("%s Not expecting any values for parameter '%s'\n", spacer, param->name);
+ return (ERROR);
+ }
+ nValuesRead = 0;
+ expecting = Expecting(LEFTPAR);
+ }
+ }
+ else
+ return (ERROR);
+
+ SafeFree ((void **)&temp);
+ return (NO_ERROR);
+}
+
+
+int DoUnlink (void)
+{
+ int i, j;
+
+ MrBayesPrint ("%s Unlinking\n", spacer);
+
+ /* update status of linkTable */
+ for (j=0; j<NUM_LINKED; j++)
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (tempLinkUnlink[j][i] == YES)
+ {
+ linkTable[j][i] = ++linkNum;
+ }
+ }
+ }
+
+# if 0
+ for (j=0; j<NUM_LINKED; j++)
+ {
+ MrBayesPrint ("%s ", spacer);
+ for (i=0; i<numCurrentDivisions; i++)
+ MrBayesPrint ("%d", linkTable[j][i]);
+ MrBayesPrint ("\n");
+ }
+# endif
+
+ /* reinitialize the temporary table */
+ for (j=0; j<NUM_LINKED; j++)
+ for (i=0; i<numCurrentDivisions; i++)
+ tempLinkUnlink[j][i] = NO;
+
+ /* set up parameters and moves */
+ if (SetUpAnalysis (&globalSeed) == ERROR)
+ return (ERROR);
+
+ return (NO_ERROR);
+}
+
+
+int DoShowMcmcTrees (void)
+{
+ int run, chain, chainIndex, i;
+ Tree *t;
+
+ for (run=0; run<chainParams.numRuns; run++)
+ {
+ for (chain=0; chain<chainParams.numChains; chain++)
+ {
+ chainIndex = run*chainParams.numChains + chain;
+ for (i=0; i<numTrees; i++)
+ {
+ t = GetTreeFromIndex (i, chainIndex, 0);
+ if (t->isRooted == YES)
+ MrBayesPrint ("\n Tree '%s' [rooted]:\n\n", t->name);
+ else
+ MrBayesPrint ("\n Tree '%s' [unrooted]:\n\n", t->name);
+ if (ShowTree (t) == ERROR)
+ return (ERROR);
+ else
+ MrBayesPrint ("\n");
+ }
+ }
+ }
+
+ return (NO_ERROR);
+}
+
+
+int DoShowModel (void)
+{
+ if (defMatrix == NO)
+ {
+ MrBayesPrint ("%s A matrix must be specified before the model can be defined\n", spacer);
+ return (ERROR);
+ }
+
+ if (ShowModel() == ERROR)
+ return (ERROR);
+
+ return (NO_ERROR);
+}
+
+
+int DoShowMoves (void)
+{
+ if (defMatrix == NO)
+ {
+ MrBayesPrint ("%s A matrix must be specified before moves can be assigned\n", spacer);
+ return (ERROR);
+ }
+
+ MrBayesPrint ("%s Moves that will be used by MCMC sampler (rel. proposal prob. > 0.0):\n\n", spacer);
+ if (ShowMoves(YES) == ERROR)
+ return (ERROR);
+
+ if (showmovesParams.allavailable == YES)
+ {
+ MrBayesPrint ("%s Other available moves (rel. proposal prob. = 0.0):\n\n", spacer);
+ if (ShowMoves(NO) == ERROR)
+ return (ERROR);
+ }
+ else
+ MrBayesPrint ("%s Use 'Showmoves allavailable=yes' to see a list of all available moves\n", spacer);
+
+ return (NO_ERROR);
+}
+
+
+int DoShowmovesParm (char *parmName, char *tkn)
+{
+ char tempStr[100];
+
+ if (expecting == Expecting(PARAMETER))
+ {
+ expecting = Expecting(EQUALSIGN);
+ }
+ else
+ {
+ /* set Allavailable **********************************************************/
+ if (!strcmp(parmName, "Allavailable"))
+ {
+ if (expecting == Expecting(EQUALSIGN))
+ expecting = Expecting(ALPHA);
+ else if (expecting == Expecting(ALPHA))
+ {
+ if (IsArgValid(tkn, tempStr) == NO_ERROR)
+ {
+ if (!strcmp(tempStr, "Yes"))
+ showmovesParams.allavailable = YES;
+ else
+ showmovesParams.allavailable = NO;
+ }
+ else
+ {
+ MrBayesPrint ("%s Invalid argument for allavailable\n", spacer);
+ return (ERROR);
+ }
+ expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
+ }
+ else
+ return (ERROR);
+ }
+ else
+ return (ERROR);
+
+ }
+
+ return (NO_ERROR);
+}
+
+
+int DoShowParams (void)
+{
+ if (defMatrix == NO)
+ {
+ MrBayesPrint ("%s A matrix must be specified before model parameters can be shown\n", spacer);
+ return (ERROR);
+ }
+
+ if (ShowParameters(YES, YES, YES) == ERROR)
+ return (ERROR);
+
+ return (NO_ERROR);
+}
+
+
+/*------------------------------------------------------------------------
+|
+| FillNormalParams: Allocate and fill in non-tree parameters
+|
+-------------------------------------------------------------------------*/
+int FillNormalParams (RandLong *seed, int fromChain, int toChain)
+{
+ int i, j, k, chn, tempInt, *intValue;
+ MrBFlt *bs, *value, *subValue, scaler;
+ Tree *tree;
+ Param *p;
+ ModelInfo *m;
+ ModelParams *mp;
+
+ /* fill in values for nontree params for state 0 of chains */
+ for (chn=fromChain; chn<toChain; chn++)
+ {
+ for (k=0; k<numParams; k++)
+ {
+ p = ¶ms[k];
+ mp = &modelParams[p->relParts[0]];
+ m = &modelSettings[p->relParts[0]];
+
+ /* find model settings and nStates, pInvar, invar cond likes */
+
+ value = GetParamVals (p, chn, 0);
+ subValue = GetParamSubVals (p, chn, 0);
+ intValue = GetParamIntVals (p, chn, 0);
+
+ if (p->paramType == P_TRATIO)
+ {
+ /* Fill in tratios **************************************************************************************/
+ if (p->paramId == TRATIO_DIR)
+ value[0] = 1.0;
+ else if (p->paramId == TRATIO_FIX)
+ value[0] = mp->tRatioFix;
+ }
+ else if (p->paramType == P_REVMAT)
+ {
+ /* Fill in revMat ***************************************************************************************/
+ /* rates are stored in order, AC or AR first, using the Dirichlet parameterization */
+ if (p->paramId == REVMAT_DIR)
+ {
+ for (j=0; j<p->nValues; j++)
+ value[j] = 1.0 / (MrBFlt) (p->nValues);
+ }
+ else if (p->paramId == REVMAT_FIX)
+ {
+ scaler = 0.0;
+ if (m->dataType == PROTEIN)
+ {
+ for (j=0; j<190; j++)
+ scaler += (value[j] = mp->aaRevMatFix[j]);
+ for (j=0; j<190; j++)
+ value[j] /= scaler;
+ }
+ else
+ {
+ for (j=0; j<6; j++)
+ scaler += (value[j] = mp->revMatFix[j]);
+ for (j=0; j<6; j++)
+ value[j] /= scaler;
+ }
+ }
+ else if (p->paramId == REVMAT_MIX)
+ {
+ for (j=0; j<6; j++)
+ {
+ value[j] = 1.0 / 6.0;
+ intValue[j] = 0;
+ }
+ }
+ }
+ else if (p->paramType == P_OMEGA)
+ {
+ /* Fill in omega ****************************************************************************************/
+ if (p->nValues == 1)
+ {
+ if (p->paramId == OMEGA_DIR)
+ value[0] = 1.0;
+ else if (p->paramId == OMEGA_FIX)
+ value[0] = mp->omegaFix;
+ }
+ else
+ {
+ if (!strcmp(mp->omegaVar, "Ny98"))
+ {
+ if (p->paramId == OMEGA_BUD || p->paramId == OMEGA_BUF || p->paramId == OMEGA_BED ||
+ p->paramId == OMEGA_BEF || p->paramId == OMEGA_BFD || p->paramId == OMEGA_BFF)
+ value[0] = RandomNumber(seed);
+ else if (p->paramId == OMEGA_FUD || p->paramId == OMEGA_FUF || p->paramId == OMEGA_FED ||
+ p->paramId == OMEGA_FEF || p->paramId == OMEGA_FFD || p->paramId == OMEGA_FFF)
+ value[0] = mp->ny98omega1Fixed;
+ value[1] = 1.0;
+ if (p->paramId == OMEGA_BUD || p->paramId == OMEGA_BUF || p->paramId == OMEGA_FUD ||
+ p->paramId == OMEGA_FUF)
+ value[2] = mp->ny98omega3Uni[0] + RandomNumber(seed) * (mp->ny98omega3Uni[1] - mp->ny98omega3Uni[0]);
+ else if (p->paramId == OMEGA_BED || p->paramId == OMEGA_BEF || p->paramId == OMEGA_FED ||
+ p->paramId == OMEGA_FEF)
+ value[2] = (1.0 - (1.0/mp->ny98omega3Exp) * log(RandomNumber(seed)));
+ else
+ value[2] = mp->ny98omega3Fixed;
+ if (p->paramId == OMEGA_BUD || p->paramId == OMEGA_BED || p->paramId == OMEGA_BFD ||
+ p->paramId == OMEGA_FUD || p->paramId == OMEGA_FED || p->paramId == OMEGA_FFD)
+ {
+ subValue[3] = mp->codonCatDir[0];
+ subValue[4] = mp->codonCatDir[1];
+ subValue[5] = mp->codonCatDir[2];
+ DirichletRandomVariable (&subValue[3], &subValue[0], 3, seed);
+ }
+ else
+ {
+ subValue[0] = mp->codonCatFreqFix[0];
+ subValue[1] = mp->codonCatFreqFix[1];
+ subValue[2] = mp->codonCatFreqFix[2];
+ subValue[3] = 0.0;
+ subValue[4] = 0.0;
+ subValue[5] = 0.0;
+ }
+ }
+ else if (!strcmp(mp->omegaVar, "M3"))
+ {
+ if (p->paramId == OMEGA_FD || p->paramId == OMEGA_FF)
+ {
+ value[0] = mp->m3omegaFixed[0];
+ value[1] = mp->m3omegaFixed[1];
+ value[2] = mp->m3omegaFixed[2];
+ }
+ else
+ {
+ value[0] = 0.1;
+ value[1] = 1.0;
+ value[2] = 3.0;
+ }
+ if (p->paramId == OMEGA_ED || p->paramId == OMEGA_FD)
+ {
+ subValue[3] = mp->codonCatDir[0];
+ subValue[4] = mp->codonCatDir[1];
+ subValue[5] = mp->codonCatDir[2];
+ DirichletRandomVariable (&subValue[3], &subValue[0], 3, seed);
+ }
+ else
+ {
+ subValue[0] = mp->codonCatFreqFix[0];
+ subValue[1] = mp->codonCatFreqFix[1];
+ subValue[2] = mp->codonCatFreqFix[2];
+ subValue[3] = 0.0;
+ subValue[4] = 0.0;
+ subValue[5] = 0.0;
+ }
+ }
+ else if (!strcmp(mp->omegaVar, "M10"))
+ {
+ if (p->paramId == OMEGA_10UUB || p->paramId == OMEGA_10UEB || p->paramId == OMEGA_10UFB ||
+ p->paramId == OMEGA_10EUB || p->paramId == OMEGA_10EEB || p->paramId == OMEGA_10EFB ||
+ p->paramId == OMEGA_10FUB || p->paramId == OMEGA_10FEB || p->paramId == OMEGA_10FFB)
+ {
+ subValue[mp->numM10BetaCats + mp->numM10GammaCats + 2] = mp->codonCatDir[0];
+ subValue[mp->numM10BetaCats + mp->numM10GammaCats + 3] = mp->codonCatDir[1];
+ DirichletRandomVariable (&subValue[mp->numM10BetaCats + mp->numM10GammaCats + 2], &subValue[mp->numM10BetaCats + mp->numM10GammaCats + 0], 2, seed);
+ }
+ else
+ {
+ subValue[mp->numM10BetaCats + mp->numM10GammaCats + 0] = mp->codonCatFreqFix[0];
+ subValue[mp->numM10BetaCats + mp->numM10GammaCats + 1] = mp->codonCatFreqFix[1];
+ subValue[mp->numM10BetaCats + mp->numM10GammaCats + 2] = 0.0;
+ subValue[mp->numM10BetaCats + mp->numM10GammaCats + 3] = 0.0;
+ }
+
+ for (i=0; i<mp->numM10BetaCats; i++)
+ subValue[i] = subValue[mp->numM10BetaCats + mp->numM10GammaCats + 0] / mp->numM10BetaCats;
+ for (i=mp->numM10BetaCats; i<mp->numM10BetaCats+mp->numM10GammaCats; i++)
+ subValue[i] = subValue[mp->numM10BetaCats + mp->numM10GammaCats + 1] / mp->numM10GammaCats;
+
+ if (p->paramId == OMEGA_10FUB || p->paramId == OMEGA_10FUF || p->paramId == OMEGA_10FEB ||
+ p->paramId == OMEGA_10FEF || p->paramId == OMEGA_10FFB || p->paramId == OMEGA_10FFF)
+ {
+ subValue[mp->numM10BetaCats + mp->numM10GammaCats + 4] = mp->m10betaFix[0];
+ subValue[mp->numM10BetaCats + mp->numM10GammaCats + 5] = mp->m10betaFix[1];
+ }
+ else
+ {
+ subValue[mp->numM10BetaCats + mp->numM10GammaCats + 4] = 1.0;
+ subValue[mp->numM10BetaCats + mp->numM10GammaCats + 5] = 1.0;
+ }
+
+ if (p->paramId == OMEGA_10UFB || p->paramId == OMEGA_10UFF || p->paramId == OMEGA_10EFB ||
+ p->paramId == OMEGA_10EFF || p->paramId == OMEGA_10FFB || p->paramId == OMEGA_10FFF)
+ {
+ subValue[mp->numM10BetaCats + mp->numM10GammaCats + 6] = mp->m10gammaFix[0];
+ subValue[mp->numM10BetaCats + mp->numM10GammaCats + 7] = mp->m10gammaFix[1];
+ }
+ else
+ {
+ subValue[mp->numM10BetaCats + mp->numM10GammaCats + 6] = 1.0;
+ subValue[mp->numM10BetaCats + mp->numM10GammaCats + 7] = 1.0;
+ }
+
+ BetaBreaks (subValue[mp->numM10BetaCats + mp->numM10GammaCats + 4], subValue[mp->numM10BetaCats + mp->numM10GammaCats + 5], &value[0], mp->numM10BetaCats);
+ if (DiscreteGamma (&value[mp->numM10BetaCats], subValue[mp->numM10BetaCats + mp->numM10GammaCats + 6],
+ subValue[mp->numM10BetaCats + mp->numM10GammaCats + 7], mp->numM10GammaCats, 0) == ERROR)
+ return (ERROR);
+ for (i=0; i<mp->numM10GammaCats; i++)
+ value[mp->numM10BetaCats + i] += 1.0;
+ }
+ }
+ }
+ else if (p->paramType == P_PI)
+ {
+ /* Fill in state frequencies ****************************************************************************/
+ /* note that standard chars are mainly dealt with in ProcessStdChars in mcmc.c */
+ if (p->paramId == SYMPI_UNI || p->paramId == SYMPI_UNI_MS)
+ value[0] = 1.0;
+ else if (p->paramId == SYMPI_EXP || p->paramId == SYMPI_EXP_MS)
+ value[0] = 1.0;
+
+ else if (p->paramId == SYMPI_FIX || p->paramId == SYMPI_FIX_MS)
+ value[0] = mp->symBetaFix;
+
+ else if (p->paramId == PI_DIR)
+ {
+ if (mp->numDirParams != mp->nStates && mp->numDirParams != 0)
+ {
+ MrBayesPrint ("%s Mismatch between number of dirichlet parameters (%d) and the number of states (%d)\n", spacer, mp->numDirParams, m->numStates);
+ return ERROR;
+ }
+
+ /* if user has not set dirichlet parameters, go with default */
+ /* overall variance equals number of states */
+ if (mp->numDirParams == 0)
+ for (i=0; i<mp->nStates; i++)
+ value[i] = mp->stateFreqsDir[i] = 1.0;
+ else
+ for (i=0; i<m->numStates; i++)
+ value[i] = mp->stateFreqsDir[i];
+
+ /* now fill in subvalues */
+ for (i=0; i<m->numStates; i++)
+ subValue[i] = 1.0 / mp->nStates;
+ }
+
+ else if (p->paramId == PI_USER)
+ {
+ for (i=0; i<m->numStates; i++)
+ subValue[i] = mp->stateFreqsFix[i];
+ }
+
+ else if (p->paramId == PI_FIXED)
+ {
+ if (!strcmp(mp->aaModelPr, "Fixed"))
+ {
+ if (!strcmp(mp->aaModel, "Jones"))
+ {
+ for (i=0; i<mp->nStates; i++)
+ subValue[i] = jonesPi[i];
+ }
+ else if (!strcmp(mp->aaModel, "Dayhoff"))
+ {
+ for (i=0; i<mp->nStates; i++)
+ subValue[i] = dayhoffPi[i];
+ }
+ else if (!strcmp(mp->aaModel, "Mtrev"))
+ {
+ for (i=0; i<mp->nStates; i++)
+ subValue[i] = mtrev24Pi[i];
+ }
+ else if (!strcmp(mp->aaModel, "Mtmam"))
+ {
+ for (i=0; i<mp->nStates; i++)
+ subValue[i] = mtmamPi[i];
+ }
+ else if (!strcmp(mp->aaModel, "Wag"))
+ {
+ for (i=0; i<mp->nStates; i++)
+ subValue[i] = wagPi[i];
+ }
+ else if (!strcmp(mp->aaModel, "Rtrev"))
+ {
+ for (i=0; i<mp->nStates; i++)
+ subValue[i] = rtrevPi[i];
+ }
+ else if (!strcmp(mp->aaModel, "Cprev"))
+ {
+ for (i=0; i<mp->nStates; i++)
+ subValue[i] = cprevPi[i];
+ }
+ else if (!strcmp(mp->aaModel, "Vt"))
+ {
+ for (i=0; i<mp->nStates; i++)
+ subValue[i] = vtPi[i];
+ }
+ else if (!strcmp(mp->aaModel, "Blosum"))
+ {
+ for (i=0; i<mp->nStates; i++)
+ subValue[i] = blosPi[i];
+ }
+ else if (!strcmp(mp->aaModel, "LG"))
+ {
+ for (i=0; i<mp->nStates; i++)
+ subValue[i] = lgPi[i];
+ }
+ }
+ }
+
+ else if (p->paramId == PI_EMPIRICAL)
+ {
+ if (GetEmpiricalFreqs (p->relParts, p->nRelParts) == ERROR)
+ return (ERROR);
+ for (i=0; i<mp->nStates; i++)
+ subValue[i] = empiricalFreqs[i];
+ }
+
+ else if (p->paramId == PI_EQUAL)
+ {
+ for (i=0; i<mp->nStates; i++)
+ subValue[i] = 1.0 / mp->nStates;
+ }
+ }
+ else if (p->paramType == P_SHAPE)
+ {
+ /* Fill in shape values ********************************************************************************/
+ /* first get hyperprior */
+ if (p->paramId == SHAPE_UNI)
+ {
+ value[0] = 1.0;
+ if (value[0] < mp->shapeUni[0] || value[0] > mp->shapeUni[1])
+ value[0] = mp->shapeUni[0] + (mp->shapeUni[1] - mp->shapeUni[0]) * 0.5;
+ }
+ else if (p->paramId == SHAPE_EXP)
+ value[0] = 1.0; // was 100.0
+ else if (p->paramId == SHAPE_FIX)
+ value[0] = mp->shapeFix;
+ /* now fill in rates */
+ if (!strcmp(mp->ratesModel, "LNorm"))
+ {
+ if (DiscreteLogNormal (subValue, value[0], mp->numGammaCats, 1) == ERROR)
+ return (ERROR);
+ }
+ else /* gamma rate */
+ {
+ if (DiscreteGamma (subValue, value[0], value[0], mp->numGammaCats, 0) == ERROR)
+ return (ERROR);
+ }
+ }
+ else if (p->paramType == P_PINVAR)
+ {
+ /* Fill in pInvar ***************************************************************************************/
+ if (p->paramId == PINVAR_UNI)
+ value[0] = 0.0;
+
+ else if (p->paramId == PINVAR_FIX)
+ value[0] = mp->pInvarFix;
+ }
+ else if (p->paramType == P_CORREL)
+ {
+ /* Fill in correlation parameter of adgamma model *******************************************************/
+ if (p->paramId == CORREL_UNI)
+ value[0] = 0.0;
+
+ else if (p->paramId == CORREL_FIX)
+ value[0] = mp->corrFix;
+
+ /* Fill in correlation matrices */
+ AutodGamma (subValue, value[0], mp->numGammaCats);
+ }
+ else if (p->paramType == P_SWITCH)
+ {
+ /* Fill in switchRates for covarion model ***************************************************************/
+ for (j=0; j<2; j++)
+ {
+ if (p->paramId == SWITCH_UNI)
+ value[j] = RandomNumber(seed) * (mp->covswitchUni[1] - mp->covswitchUni[0]) + mp->covswitchUni[0];
+
+ else if (p->paramId == SWITCH_EXP)
+ value[j] = -(1.0/mp->covswitchExp) * log(RandomNumber(seed));
+
+ else if (p->paramId == SWITCH_FIX)
+ value[j] = mp->covswitchFix[j];
+ }
+ }
+ else if (p->paramType == P_RATEMULT)
+ {
+ /* Fill in division rates *****************************************************************************/
+ for (j=0; j<p->nValues; j++)
+ {
+ value[j] = 1.0;
+ /* fill in more info about the divisions if this is a true rate multiplier
+ and not a base rate */
+ if (p->nSubValues > 0)
+ {
+ /* num uncompressed chars */
+ subValue[j] = (modelSettings[p->relParts[j]].numUncompressedChars);
+ /* Dirichlet parameters */
+ subValue[p->nValues + j] = modelParams[p->relParts[j]].ratePrDir;
+ }
+ }
+ }
+ else if (p->paramType == P_GENETREERATE)
+ {
+ /* Fill in division rates *****************************************************************************/
+ for (j=0; j<p->nValues; j++)
+ {
+ value[j] = 1.0;
+ /* Dirichlet parameters fixed to 1.0 for now; ignored if the rate is fixed */
+ subValue[p->nValues + j] = 1.0;
+ /* Get number of uncompressed chars from tree */
+ tree = GetTreeFromIndex(j, 0, 0);
+ subValue[j] = 0.0;
+ for (i=0; i<tree->nRelParts; i++) /* num uncompressed chars */
+ subValue[j] += modelSettings[tree->relParts[i]].numUncompressedChars;
+ }
+ }
+ else if (p->paramType == P_SPECRATE)
+ {
+ /* Fill in speciation rates *****************************************************************************/
+ for (j=0; j<p->nValues; j++)
+ {
+ if (p->paramId == SPECRATE_FIX)
+ value[j] = mp->speciationFix;
+ else
+ value[j] = 0.1;
+ }
+ }
+ else if (p->paramType == P_EXTRATE)
+ {
+ /* Fill in extinction rates *****************************************************************************/
+ for (j=0; j<p->nValues; j++)
+ {
+ if (p->paramId == EXTRATE_FIX)
+ value[j] = mp->extinctionFix;
+ else
+ value[j] = 0.8;
+ }
+ }
+ else if (p->paramType == P_FOSLRATE)
+ {
+ /* Fill in fossilization rates */
+ for (j=0; j<p->nValues; j++)
+ {
+ if (p->paramId == FOSLRATE_FIX)
+ value[j] = mp->fossilizationFix;
+ else
+ value[j] = 0.2;
+ }
+ }
+ else if (p->paramType == P_GROWTH)
+ {
+ /* Fill in growth rate ****************************************************************************************/
+ if (p->paramId == GROWTH_FIX)
+ value[0] = mp->growthFix;
+ else
+ value[0] = 1.0;
+ }
+ else if (p->paramType == P_POPSIZE)
+ {
+ /* Fill in population size ****************************************************************************************/
+ for (j=0; j<p->nValues; j++)
+ {
+ if (p->paramId == POPSIZE_UNI)
+ value[j] = RandomNumber(seed) * (mp->popSizeUni[1] - mp->popSizeUni[0]) + mp->popSizeUni[0];
+ else if (p->paramId == POPSIZE_LOGNORMAL)
+ value[j] = exp(mp->popSizeLognormal[0]);
+ else if (p->paramId == POPSIZE_NORMAL)
+ value[j] = mp->popSizeNormal[0];
+ else if (p->paramId == POPSIZE_GAMMA)
+ value[j] = mp->popSizeGamma[0] / mp->popSizeGamma[1];
+ else if (p->paramId == POPSIZE_FIX)
+ value[j] = mp->popSizeFix;
+ }
+ }
+ else if (p->paramType == P_AAMODEL)
+ {
+ /* Fill in theta ****************************************************************************************/
+ if (p->paramId == AAMODEL_MIX)
+ {
+ /* amino acid model ID's
+ AAMODEL_POISSON 0
+ AAMODEL_JONES 1
+ AAMODEL_DAY 2
+ AAMODEL_MTREV 3
+ AAMODEL_MTMAM 4
+ AAMODEL_WAG 5
+ AAMODEL_RTREV 6
+ AAMODEL_CPREV 7
+ AAMODEL_VT 8
+ AAMODEL_BLOSUM 9 */
+
+ /* set the amino acid model (the meaning of the numbers is defined) */
+ tempInt = (int)(RandomNumber(seed) * 10);
+ value[0] = tempInt;
+
+ /* we need to make certain that the aa frequencies are filled in correctly */
+ bs = GetParamSubVals (m->stateFreq, chn, 0);
+ if (tempInt == AAMODEL_POISSON)
+ {
+ for (i=0; i<mp->nStates; i++)
+ bs[i] = (1.0 / 20.0);
+ }
+ else if (tempInt == AAMODEL_JONES)
+ {
+ for (i=0; i<mp->nStates; i++)
+ bs[i] = jonesPi[i];
+ }
+ else if (tempInt == AAMODEL_DAY)
+ {
+ for (i=0; i<mp->nStates; i++)
+ bs[i] = dayhoffPi[i];
+ }
+ else if (tempInt == AAMODEL_MTREV)
+ {
+ for (i=0; i<mp->nStates; i++)
+ bs[i] = mtrev24Pi[i];
+ }
+ else if (tempInt == AAMODEL_MTMAM)
+ {
+ for (i=0; i<mp->nStates; i++)
+ bs[i] = mtmamPi[i];
+ }
+ else if (tempInt == AAMODEL_WAG)
+ {
+ for (i=0; i<mp->nStates; i++)
+ bs[i] = wagPi[i];
+ }
+ else if (tempInt == AAMODEL_RTREV)
+ {
+ for (i=0; i<mp->nStates; i++)
+ bs[i] = rtrevPi[i];
+ }
+ else if (tempInt == AAMODEL_CPREV)
+ {
+ for (i=0; i<mp->nStates; i++)
+ bs[i] = cprevPi[i];
+ }
+ else if (tempInt == AAMODEL_VT)
+ {
+ for (i=0; i<mp->nStates; i++)
+ bs[i] = vtPi[i];
+ }
+ else if (tempInt == AAMODEL_BLOSUM)
+ {
+ for (i=0; i<mp->nStates; i++)
+ bs[i] = blosPi[i];
+ }
+
+ for (i=0; i<p->nSubValues; i++)
+ {
+ subValue[i] = mp->aaModelPrProbs[i];
+ }
+ }
+ }
+ else if (p->paramType == P_CPPRATE)
+ {
+ /* Fill in lambda (cpp rate) ********************************************************************************************/
+ if (p->paramId == CPPRATE_EXP)
+ value[0] = -(1.0/mp->cppRateExp) * log(RandomNumber(seed));
+ else if (p->paramId == CPPRATE_FIX)
+ value[0] = mp->cppRateFix;
+ }
+ else if (p->paramType == P_CPPMULTDEV)
+ {
+ /* Fill in log standard deviation (for relaxed clock rate multiplier) ***********************************************************/
+ if (p->paramId == CPPMULTDEV_FIX)
+ value[0] = mp->cppMultDevFix;
+ }
+ else if (p->paramType == P_CPPEVENTS)
+ {
+ /* We fill in these when we fill in tree params **************************************************************************/
+ }
+ else if (p->paramType == P_TK02VAR)
+ {
+ /* Fill in variance of relaxed clock lognormal **************************************************************************/
+ if (p->paramId == TK02VAR_UNI)
+ value[0] = RandomNumber(seed) * (mp->tk02varUni[1] - mp->tk02varUni[0]) + mp->tk02varUni[0];
+ else if (p->paramId == TK02VAR_EXP)
+ value[0] = 2.0/(mp->tk02varExp);
+ else if (p->paramId == TK02VAR_FIX)
+ value[0] = mp->tk02varFix;
+ }
+ else if (p->paramType == P_TK02BRANCHRATES)
+ {
+ /* We fill in these when we fill in tree params **************************************************************************/
+ }
+ else if (p->paramType == P_IGRVAR)
+ {
+ /* Fill in variance of relaxed clock lognormal **************************************************************************/
+ if (p->paramId == IGRVAR_UNI)
+ value[0] = RandomNumber(seed) * (mp->igrvarUni[1] - mp->igrvarUni[0]) + mp->igrvarUni[0];
+ else if (p->paramId == IGRVAR_EXP)
+ value[0] = 1.0/(mp->igrvarExp);
+ else if (p->paramId == IGRVAR_FIX)
+ value[0] = mp->igrvarFix;
+ }
+ else if (p->paramType == P_IGRBRANCHRATES)
+ {
+ /* We fill in these when we fill in tree params **************************************************************************/
+ }
+ else if (p->paramType == P_MIXEDVAR)
+ {
+ /* Fill in variance of mixed relaxed clock **************************************************************************/
+ if (p->paramId == MIXEDVAR_UNI)
+ value[0] = RandomNumber(seed) * (mp->mixedvarUni[1] - mp->mixedvarUni[0]) + mp->mixedvarUni[0];
+ else if (p->paramId == MIXEDVAR_EXP)
+ value[0] = 1.0/(mp->mixedvarExp);
+ else if (p->paramId == MIXEDVAR_FIX)
+ value[0] = mp->mixedvarFix;
+ }
+ else if (p->paramType == P_MIXEDBRCHRATES)
+ {
+ /* initialize the mixed relaxed clock model to TK02 or IGR */
+ intValue[0] = (RandomNumber(seed) <0.5) ? RCL_TK02 : RCL_IGR;
+ /* We fill in the rest when we fill in tree params **************************************************************************/
+ }
+ else if (p->paramType == P_CLOCKRATE)
+ {
+ /* Fill in base rate of molecular clock **************************************************************************/
+ if (p->paramId == CLOCKRATE_FIX)
+ value[0] = mp->clockRateFix;
+ else if (p->paramId == CLOCKRATE_NORMAL)
+ value[0] = mp->clockRateNormal[0];
+ else if (p->paramId == CLOCKRATE_LOGNORMAL)
+ value[0] = exp(mp->clockRateLognormal[0]);
+ else if (p->paramId == CLOCKRATE_EXP)
+ value[0] = 1.0/(mp->clockRateExp);
+ else if (p->paramId == CLOCKRATE_GAMMA)
+ value[0] = mp->clockRateGamma[0]/mp->clockRateGamma[1];
+ }
+ } /* next param */
+ } /* next chain */
+
+ return NO_ERROR;
+}
+
+
+int FillRelPartsString (Param *p, char **relPartString)
+{
+ int i, n, filledString;
+ char *tempStr;
+ int tempStrSize=50;
+
+ tempStr = (char *) SafeMalloc((size_t)tempStrSize * sizeof(char));
+ if (!tempStr)
+ {
+ MrBayesPrint ("%s Problem allocating tempString (%d)\n", spacer, tempStrSize * sizeof(char));
+ return (ERROR);
+ }
+
+ if (numCurrentDivisions == 1)
+ {
+ filledString = NO;
+ SafeStrcpy (relPartString, "");
+ }
+ else
+ {
+ filledString = YES;
+ if (p->nRelParts == numCurrentDivisions)
+ {
+ SafeStrcpy (relPartString, "{all}");
+ }
+ else
+ {
+ SafeStrcpy (relPartString, "{");
+ for (i=n=0; i<p->nRelParts; i++)
+ {
+ n++;
+ SafeSprintf (&tempStr, &tempStrSize, "%d", p->relParts[i] + 1);
+ SafeStrcat (relPartString, tempStr);
+ if (n < p->nRelParts)
+ SafeStrcat (relPartString, ",");
+ }
+ SafeStrcat (relPartString, "}");
+ }
+ }
+ free (tempStr);
+ return (filledString);
+}
+
+
+/*--------------------------------------------------------------
+ |
+ | FillStdStateFreqs: fills stationary frequencies for standard data divisions of chains in range [chfrom, chto)
+ |
+ ---------------------------------------------------------------*/
+void FillStdStateFreqs (int chfrom, int chto, RandLong *seed)
+{
+ int chn, n, i, j, k, b, c, nb, index;
+ MrBFlt *subValue, sum, symDir[10];
+ Param *p;
+
+ for (chn=chfrom; chn<chto; chn++)
+ {
+ for (k=0; k<numParams; k++)
+ {
+ p = ¶ms[k];
+ if (p->paramType != P_PI || modelParams[p->relParts[0]].dataType != STANDARD)
+ continue;
+ subValue = GetParamStdStateFreqs (p, chn, 0);
+ if (p->paramId == SYMPI_EQUAL)
+ {
+ for (n=index=0; n<9; n++)
+ {
+ for (i=0; i<p->nRelParts; i++)
+ if (modelSettings[p->relParts[i]].isTiNeeded[n] == YES)
+ break;
+ if (i < p->nRelParts)
+ {
+ for (j=0; j<(n+2); j++)
+ {
+ subValue[index++] = (1.0 / (n + 2));
+ }
+ }
+ }
+ for (n=9; n<13; n++)
+ {
+ for (i=0; i<p->nRelParts; i++)
+ if (modelSettings[p->relParts[i]].isTiNeeded[n] == YES)
+ break;
+ if (i < p->nRelParts)
+ {
+ for (j=0; j<(n-6); j++)
+ {
+ subValue[index++] = (1.0 / (n - 6));
+ }
+ }
+ }
+ }
+
+ /* Deal with transition asymmetry for standard characters */
+ /* First, fill in stationary frequencies for beta categories if needed; */
+ /* discard category frequencies (assume equal) */
+ if (p->paramId == SYMPI_FIX || p->paramId == SYMPI_UNI || p->paramId == SYMPI_EXP ||
+ p->paramId == SYMPI_FIX_MS || p->paramId == SYMPI_UNI_MS || p->paramId == SYMPI_EXP_MS)
+ {
+ if (p->hasBinaryStd == YES)
+ {
+ nb=modelParams[p->relParts[0]].numBetaCats;
+ BetaBreaks (p->values[0], p->values[0], subValue, nb);
+ b = 2*nb;
+ for (i=b-2; i>0; i-=2)
+ {
+ subValue[i] = subValue[i/2];
+ }
+ for (i=1; i<b; i+=2)
+ {
+ subValue[i] = (1.0 - subValue[i-1]);
+ }
+ subValue += (2 * nb);
+ }
+
+ /* Then fill in state frequencies for multistate chars, one set for each */
+ for (i=0; i<10; i++)
+ symDir[i] = p->values[0];
+
+ for (c=0; c<p->nSympi; c++)
+ {
+ /* now fill in subvalues */
+ DirichletRandomVariable (symDir, subValue, p->sympinStates[c], seed);
+ sum = 0.0;
+ for (i=0; i<p->sympinStates[c]; i++)
+ {
+ if (subValue[i] < 0.0001)
+ subValue[i] = 0.0001;
+ sum += subValue[i];
+ }
+ for (i=0; i<modelParams[p->relParts[0]].nStates; i++)
+ subValue[i] /= sum;
+ subValue += p->sympinStates[c];
+ }
+ }
+ } /* next parameter */
+ } /* next chain */
+}
+
+
+/* FillTopologySubParams: Fill subparams (brlens) for a topology */
+int FillTopologySubParams (Param *param, int chn, int state, RandLong *seed)
+{
+ int i,returnVal;
+ Tree *tree, *tree1;
+ Param *q;
+ MrBFlt clockRate;
+ PolyTree *sourceTree;
+ MrBFlt minRate,maxRate;
+
+ tree = GetTree (param, chn, state);
+
+ for (i=1; i<param->nSubParams; i++)
+ {
+ q = param->subParams[i];
+ tree1 = GetTree (q, chn, state);
+ if (CopyToTreeFromTree(tree1, tree) == ERROR)
+ return (ERROR);
+ }
+ for (i=0; i<param->nSubParams; i++)
+ {
+ q = param->subParams[i];
+ tree = GetTree (q, chn, state);
+ if (q->paramId == BRLENS_FIXED || q->paramId == BRLENS_CLOCK_FIXED)
+ {
+ if (param->paramId == TOPOLOGY_NCL_FIXED ||
+ param->paramId == TOPOLOGY_NCL_FIXED_HOMO ||
+ param->paramId == TOPOLOGY_NCL_FIXED_HETERO ||
+ param->paramId == TOPOLOGY_CL_FIXED ||
+ param->paramId == TOPOLOGY_RCL_FIXED ||
+ param->paramId == TOPOLOGY_CCL_FIXED ||
+ param->paramId == TOPOLOGY_RCCL_FIXED||
+ param->paramId == TOPOLOGY_FIXED)
+ {
+ sourceTree = AllocatePolyTree(numTaxa);
+ CopyToPolyTreeFromPolyTree (sourceTree, userTree[modelParams[q->relParts[0]].brlensFix]);
+ PrunePolyTree (sourceTree);
+ ResetTipIndices (sourceTree);
+ ResetIntNodeIndices (sourceTree);
+ if (tree->isRooted != sourceTree->isRooted)
+ {
+ MrBayesPrint("%s Cannot set fixed branch lengths because of mismatch in rootedness", spacer);
+ FreePolyTree (sourceTree);
+ return (ERROR);
+ }
+ if (CopyToTreeFromPolyTree(tree,sourceTree) == ERROR)
+ {
+ MrBayesPrint("%s Problem setting fixed branch lengths", spacer);
+ FreePolyTree (sourceTree);
+ return (ERROR);
+ }
+ FreePolyTree (sourceTree);
+ if (tree->isClock == YES && IsClockSatisfied(tree, 0.0001) == NO)
+ {
+ MrBayesPrint("%s Fixed branch lengths do not satisfy clock", spacer);
+ return (ERROR);
+ }
+ if (tree->isCalibrated == YES && IsCalibratedClockSatisfied(tree,&minRate,&maxRate, 0.0001) == NO)
+ {
+ MrBayesPrint("%s Fixed branch lengths do not satisfy calibrations", spacer);
+ return (ERROR);
+ }
+ if (tree->isCalibrated == YES && !strcmp(modelParams[tree->relParts[0]].clockRatePr, "Fixed"))
+ {
+ clockRate = modelParams[tree->relParts[0]].clockRateFix;
+ if ((clockRate < minRate && AreDoublesEqual (clockRate, minRate , 0.0001) == NO) ||
+ (clockRate > maxRate && AreDoublesEqual (clockRate, maxRate , 0.0001) == NO))
+ {
+ MrBayesPrint("%s Fixed branch lengths do not satisfy fixed clockrate", spacer);
+ return (ERROR);
+ }
+ }
+
+ tree->fromUserTree=YES;
+ returnVal = NO_ERROR;
+ }
+ else
+ {
+ MrBayesPrint("%s Fixed branch lengths can only be used for a fixed topology\n", spacer);
+ return (ERROR);
+ }
+ }
+ else if (tree->isCalibrated == YES || (tree->isClock == YES && (!strcmp(modelParams[tree->relParts[0]].clockPr,"Uniform") ||
+ !strcmp(modelParams[tree->relParts[0]].clockPr,"Fossilization"))))
+ {
+ assert (tree->isClock == YES);
+ clockRate = *GetParamVals(modelSettings[tree->relParts[0]].clockRate, chn, state);
+ returnVal = InitCalibratedBrlens (tree, clockRate, seed);
+ if (IsClockSatisfied (tree,0.0001) == NO)
+ {
+ MrBayesPrint ("%s Branch lengths of the tree does not satisfy clock\n", spacer);
+ return (ERROR);
+ }
+ tree->fromUserTree=NO;
+ }
+ else if (tree->isClock == YES)
+ returnVal = InitClockBrlens (tree);
+ else
+ returnVal = InitBrlens (tree, 0.02);
+
+ if (returnVal == ERROR)
+ return (ERROR);
+
+ if (FillBrlensSubParams (q, chn, state) == ERROR)
+ return (ERROR);
+ }
+
+ return (NO_ERROR);
+}
+
+
+/* FillBrlensSubParams: Fill any relaxed clock subparams of a brlens param */
+int FillBrlensSubParams (Param *param, int chn, int state)
+{
+ int i, j, *nEvents;
+ MrBFlt *brlen, *branchRate, **position, **rateMult;
+ Tree *tree;
+ TreeNode *p;
+ Param *q;
+
+ tree = GetTree (param, chn, state);
+
+ for (i=0; i<param->nSubParams; i++)
+ {
+ q = param->subParams[i];
+ if (q->paramType == P_CPPEVENTS)
+ {
+ nEvents = q->nEvents[2*chn+state];
+ position = q->position[2*chn+state];
+ rateMult = q->rateMult[2*chn+state];
+ brlen = GetParamSubVals (q, chn, state);
+ for (j=0; j<tree->nNodes-1; j++)
+ {
+ p = tree->allDownPass[j];
+ if (nEvents[p->index] != 0)
+ {
+ free (position[p->index]);
+ position[p->index] = NULL;
+ free (rateMult[p->index]);
+ rateMult[p->index] = NULL;
+ }
+ nEvents[p->index] = 0;
+ assert (j==tree->nNodes-2 || fabs(p->length - (p->anc->nodeDepth - p->nodeDepth)) < 0.000001);
+ brlen[p->index] = p->length;
+ }
+ }
+ else if (q->paramType == P_TK02BRANCHRATES || q->paramType == P_IGRBRANCHRATES || q->paramType == P_MIXEDBRCHRATES)
+ {
+ branchRate = GetParamVals (q, chn, state);
+ brlen = GetParamSubVals (q, chn, state);
+ for (j=0; j<tree->nNodes-1; j++)
+ {
+ p = tree->allDownPass[j];
+ assert (j==tree->nNodes-2 || fabs(p->length - (p->anc->nodeDepth - p->nodeDepth)) < 0.000001);
+ branchRate[p->index] = 1.0;
+ brlen[p->index] = p->length;
+ }
+ }
+ }
+
+ return (NO_ERROR);
+}
+
+
+/* Note: In PruneConstraintPartitions() we can not relay on specific rootnes of a tree since different partitions
+ may theoreticly have different clock models, while constraints apply to all partitions/trees */
+int PruneConstraintPartitions()
+{
+ int i, j, constraintId, nLongsNeeded;
+
+ nLongsNeeded = (numLocalTaxa - 1) / nBitsInALong + 1;
+
+ for (constraintId=0; constraintId<numDefinedConstraints; constraintId++)
+ {
+ definedConstraintPruned[constraintId] = (BitsLong *) SafeRealloc ((void *)definedConstraintPruned[constraintId], nLongsNeeded*sizeof(BitsLong));
+ if (!definedConstraintPruned[constraintId])
+ {
+ MrBayesPrint ("%s Problems allocating constraintPartition in PruneConstraintPartitions", spacer);
+ return (ERROR);
+ }
+
+ /* initialize bits in partition to add; get rid of deleted taxa in the process */
+ ClearBits(definedConstraintPruned[constraintId], nLongsNeeded);
+ for (i=j=0; i<numTaxa; i++)
+ {
+ if (taxaInfo[i].isDeleted == YES)
+ continue;
+ if (IsBitSet(i, definedConstraint[constraintId]) == YES)
+ SetBit(j, definedConstraintPruned[constraintId]);
+ j++;
+ }
+ assert (j == numLocalTaxa);
+
+ if (definedConstraintsType[constraintId] == PARTIAL)
+ {
+ definedConstraintTwoPruned[constraintId] = (BitsLong *) SafeRealloc ((void *)definedConstraintTwoPruned[constraintId], nLongsNeeded*sizeof(BitsLong));
+ if (!definedConstraintTwoPruned[constraintId])
+ {
+ MrBayesPrint ("%s Problems allocating constraintPartition in PruneConstraintPartitions", spacer);
+ return (ERROR);
+ }
+
+ /* initialize bits in partition to add; get rid of deleted taxa in the process */
+ ClearBits(definedConstraintTwoPruned[constraintId], nLongsNeeded);
+ for (i=j=0; i<numTaxa; i++)
+ {
+ if (taxaInfo[i].isDeleted == YES)
+ continue;
+ if (IsBitSet(i, definedConstraintTwo[constraintId]) == YES)
+ SetBit(j, definedConstraintTwoPruned[constraintId]);
+ j++;
+ }
+ assert (j == numLocalTaxa);
+ }
+ else if (definedConstraintsType[constraintId] == NEGATIVE || (definedConstraintsType[constraintId] == HARD))
+ {
+ /* Here we create definedConstraintTwoPruned[constraintId] which is complemente of definedConstraintPruned[constraintId] */
+ definedConstraintTwoPruned[constraintId] = (BitsLong *) SafeRealloc ((void *)definedConstraintTwoPruned[constraintId], nLongsNeeded*sizeof(BitsLong));
+ if (!definedConstraintTwoPruned[constraintId])
+ {
+ MrBayesPrint ("%s Problems allocating constraintPartition in PruneConstraintPartitions", spacer);
+ return (ERROR);
+ }
+
+ /* initialize bits in partition to add; get rid of deleted taxa in the process */
+ ClearBits(definedConstraintTwoPruned[constraintId], nLongsNeeded);
+ for (i=j=0; i<numTaxa; i++)
+ {
+ if (taxaInfo[i].isDeleted == YES)
+ continue;
+ if (IsBitSet(i, definedConstraint[constraintId]) == NO)
+ SetBit(j, definedConstraintTwoPruned[constraintId]);
+ j++;
+ }
+ assert (j == numLocalTaxa);
+ }
+ }
+
+ return NO_ERROR;
+}
+
+
+int DoesTreeSatisfyConstraints(Tree *t)
+{
+ int i, k, numTaxa, nLongsNeeded;
+ TreeNode *p;
+ int CheckFirst, CheckSecond; /*Flag indicating wheather corresponding set(first/second) of partial constraint has to be checked*/
+# if defined (DEBUG_CONSTRAINTS)
+ int locks_count=0;
+# endif
+
+ if (t->checkConstraints == NO)
+ return YES;
+ /* get some handy numbers */
+ numTaxa = t->nNodes - t->nIntNodes - (t->isRooted == YES ? 1 : 0);
+ nLongsNeeded = (numTaxa - 1) / nBitsInALong + 1;
+
+ if (t->bitsets == NULL)
+ {
+ AllocateTreePartitions(t);
+ }
+ else
+ {
+ ResetTreePartitions(t); /*Inefficient function, rewrite faster version*/
+ }
+# if defined (DEBUG_CONSTRAINTS)
+ for (i=0; i<t->nIntNodes; i++)
+ {
+ p = t->intDownPass[i];
+ if (p->isLocked == YES)
+ {
+ if (IsUnionEqThird (definedConstraintPruned[p->lockID], definedConstraintPruned[p->lockID], p->partition, nLongsNeeded) == NO && IsUnionEqThird (definedConstraintTwoPruned[p->lockID], definedConstraintTwoPruned[p->lockID], p->partition, nLongsNeeded) == NO)
+ {
+ printf ("DEBUG ERROR: Locked node does not represent right partition. \n");
+ return ABORT;
+ }
+ else
+ {
+ locks_count++;
+ }
+ }
+ }
+
+ if (locks_count != t->nLocks)
+ {
+ printf ("DEBUG ERROR: locks_count:%d should be locks_count:%d\n", locks_count, t->nLocks);
+ return ABORT;
+ }
+# endif
+
+ for (k=0; k<numDefinedConstraints; k++)
+ {
+# if defined (DEBUG_CONSTRAINTS)
+ if (t->constraints[k] == YES && definedConstraintsType[k] == HARD)
+ {
+ if (t->isRooted == YES)
+ {
+ CheckFirst = YES;
+ CheckSecond = NO;
+ }
+ else
+ {
+ /*exactly one of next two will be YES*/
+ CheckFirst = IsBitSet(localOutGroup, definedConstraintPruned[k])==YES ? NO : YES;
+ CheckSecond = IsBitSet(localOutGroup, definedConstraintTwoPruned[k])==YES ? NO : YES;
+ assert ((CheckFirst^CheckSecond)==1);
+ }
+
+ for (i=0; i<t->nIntNodes; i++)
+ {
+ p = t->intDownPass[i];
+ if (p->anc != NULL)
+ {
+ if (CheckFirst==YES && IsPartNested(definedConstraintPruned[k], p->partition, nLongsNeeded) && IsPartNested(p->partition,definedConstraintPruned[k], nLongsNeeded))
+ break;
+ if (CheckSecond==YES && IsPartNested(definedConstraintTwoPruned[k], p->partition, nLongsNeeded) && IsPartNested(p->partition, definedConstraintTwoPruned[k], nLongsNeeded))
+ break;
+ }
+ }
+
+ if (i==t->nIntNodes)
+ {
+ printf ("DEBUG ERROR: Hard constraint is not satisfied. \n");
+ return ABORT;
+ //assert (0);
+ }
+ }
+# endif
+
+ if (t->constraints[k] == NO || definedConstraintsType[k] == HARD)
+ continue;
+
+ if (definedConstraintsType[k] == PARTIAL)
+ {
+ /* alternative way
+ if (t->isRooted == NO && !IsBitSet(localOutGroup, definedConstraintPruned[k]))
+ {
+ m = FirstTaxonInPartition (constraintPartition, nLongsNeeded);
+ for (i=0; t->nodes[i].index != m; i++)
+ ;
+ p = &t->nodes[i];
+
+ p=p->anc;
+ while (!IsPartNested(definedConstraintPruned[k], p->partition, nLongsNeeded))
+ p=p->anc;
+
+ if (IsSectionEmpty(definedConstraintTwoPruned[k], p->partition, nLongsNeeded))
+ continue;
+ }
+ */
+ if (t->isRooted == YES)
+ {
+ CheckFirst = YES;
+ CheckSecond = NO; /* In rooted case even if we have a node with partition fully containing second set and not containing the first set it would not satisfy the constraint */
+ }
+ else
+ {
+ if (NumBits(definedConstraintPruned[k], nLongsNeeded) == 1 || NumBits(definedConstraintTwoPruned[k], nLongsNeeded) == 1)
+ continue;
+ /*one or two of the next two statments will be YES*/
+ CheckFirst = IsBitSet(localOutGroup, definedConstraintPruned[k])==YES ? NO : YES;
+ CheckSecond = IsBitSet(localOutGroup, definedConstraintTwoPruned[k])==YES ? NO : YES;
+ assert ((CheckFirst|CheckSecond)==1);
+ }
+ for (i=0; i<t->nIntNodes; i++)
+ {
+ p = t->intDownPass[i];
+ if (p->anc != NULL)
+ {
+ if (CheckFirst== YES && IsPartNested(definedConstraintPruned[k], p->partition, nLongsNeeded) && IsSectionEmpty(definedConstraintTwoPruned[k], p->partition, nLongsNeeded))
+ break;
+ if (CheckSecond==YES && IsPartNested(definedConstraintTwoPruned[k], p->partition, nLongsNeeded) && IsSectionEmpty(definedConstraintPruned[k], p->partition, nLongsNeeded))
+ break;
+ }
+ }
+ if (i==t->nIntNodes)
+ return NO;
+ }
+ else
+ {
+ assert (definedConstraintsType[k] == NEGATIVE);
+ if (t->isRooted == YES)
+ {
+ CheckFirst = YES;
+ CheckSecond = NO;
+ }
+ else
+ {
+ /*exactly one of next two will be YES*/
+ CheckFirst = IsBitSet(localOutGroup, definedConstraintPruned[k])==YES ? NO : YES;
+ CheckSecond = IsBitSet(localOutGroup, definedConstraintTwoPruned[k])==YES ? NO : YES;
+ assert ((CheckFirst^CheckSecond)==1);
+ }
+
+ for (i=0; i<t->nIntNodes; i++)
+ {
+ p = t->intDownPass[i];
+ if (p->anc != NULL)
+ {
+ if (CheckFirst==YES && AreBitfieldsEqual(definedConstraintPruned[k], p->partition, nLongsNeeded))
+ break;
+ if (CheckSecond==YES && AreBitfieldsEqual(definedConstraintTwoPruned[k], p->partition, nLongsNeeded))
+ break;
+ }
+ }
+ if (i!=t->nIntNodes)
+ return NO;
+ }
+ }
+
+ return YES;
+}
+
+
+/*------------------------------------------------------------------
+|
+| FillTreeParams: Fill in trees and branch lengths
+|
+| Note: Should be run after FillNormalParams because
+| clockrate needs to be set if calibrated tree needs
+| to be filled.
+|
+------------------------------------------------------------------*/
+int FillTreeParams (RandLong *seed, int fromChain, int toChain)
+{
+ int i, k, chn, nTaxa, tmp;
+ Param *p, *q;
+ Tree *tree;
+ PolyTree *constraintTree;
+ PolyTree *constraintTreeRef;
+
+ if (PruneConstraintPartitions() == ERROR)
+ return ERROR;
+
+ /* Build starting trees for state 0 */
+ for (chn=fromChain; chn<toChain; chn++)
+ {
+ for (k=0; k<numParams; k++)
+ {
+ p = ¶ms[k];
+ if (p->paramType == P_TOPOLOGY)
+ {
+ q = p->subParams[0];
+ tree = GetTree (q, chn, 0);
+ if (tree->isRooted == YES)
+ nTaxa = tree->nNodes - tree->nIntNodes - 1;
+ else
+ nTaxa = tree->nNodes - tree->nIntNodes;
+
+ /* fixed topology */
+ if (p->paramId == TOPOLOGY_NCL_FIXED ||
+ p->paramId == TOPOLOGY_NCL_FIXED_HOMO ||
+ p->paramId == TOPOLOGY_NCL_FIXED_HETERO ||
+ p->paramId == TOPOLOGY_CL_FIXED ||
+ p->paramId == TOPOLOGY_RCL_FIXED ||
+ p->paramId == TOPOLOGY_CCL_FIXED ||
+ p->paramId == TOPOLOGY_RCCL_FIXED||
+ p->paramId == TOPOLOGY_FIXED ||
+ p->paramId == TOPOLOGY_PARSIMONY_FIXED)
+ {
+ constraintTree = AllocatePolyTree (numTaxa);
+ CopyToPolyTreeFromPolyTree (constraintTree, userTree[modelParams[p->relParts[0]].topologyFix]);
+ PrunePolyTree (constraintTree);
+ ResetTipIndices(constraintTree);
+ ResetIntNodeIndices(constraintTree);
+ RandResolve (NULL, constraintTree, seed, constraintTree->isRooted);
+ if (tree->nIntNodes != constraintTree->nIntNodes)
+ {
+ if (tree->isRooted != constraintTree->isRooted)
+ {
+ MrBayesPrint ("%s Could not fix topology because user tree '%s' differs in rootedness with the model tree.\n", spacer,
+ userTree[modelParams[p->relParts[0]].topologyFix]->name);
+ MrBayesPrint ("%s The user tree %s is%srooted, while expected model tree is%srooted.\n", spacer,
+ userTree[modelParams[p->relParts[0]].topologyFix]->name, (constraintTree->isRooted?" ":" not "), (tree->isRooted?" ":" not "));
+ MrBayesPrint ("%s Check brlenspr is set correctly before fixing topology.\n", spacer);
+ }
+ else
+ MrBayesPrint ("%s Could not fix topology because user tree '%s' is not fully resolved.\n",
+ spacer, userTree[modelParams[p->relParts[0]].topologyFix]->name);
+ FreePolyTree (constraintTree);
+ return (ERROR);
+ }
+ if (CopyToTreeFromPolyTree(tree, constraintTree) == ERROR)
+ {
+ MrBayesPrint ("%s Could not fix topology according to user tree '%s'\n", spacer, userTree[modelParams[p->relParts[0]].topologyFix]->name);
+ FreePolyTree (constraintTree);
+ return (ERROR);
+ }
+ FreePolyTree (constraintTree);
+ }
+ /* constrained topology */
+ else if (tree->nConstraints > 0)
+ {
+ constraintTreeRef = AllocatePolyTree (nTaxa);
+ if (!constraintTreeRef)
+ return (ERROR);
+ if (BuildConstraintTree (tree, constraintTreeRef, localTaxonNames) == ERROR)
+ {
+ FreePolyTree (constraintTreeRef);
+ return (ERROR);
+ }
+ if (AllocatePolyTreePartitions (constraintTreeRef) == ERROR)
+ return (ERROR);
+
+ constraintTree = AllocatePolyTree (nTaxa);
+ if (!constraintTree)
+ return (ERROR);
+ if (AllocatePolyTreePartitions (constraintTree) == ERROR)
+ return (ERROR);
+
+ for (i=0;i<100;i++)
+ {
+ CopyToPolyTreeFromPolyTree(constraintTree,constraintTreeRef);
+ tmp = RandResolve (tree, constraintTree, &globalSeed, tree->isRooted);
+ if (tmp != NO_ERROR)
+ {
+ if (tmp == ERROR)
+ {
+ FreePolyTree (constraintTree);
+ return (ERROR);
+ }
+ else
+ {
+ assert (tmp == ABORT);
+ continue;
+ }
+ }
+
+ CopyToTreeFromPolyTree(tree, constraintTree);
+ if (DoesTreeSatisfyConstraints(tree)==YES)
+ break;
+ }
+# if defined (DEBUG_CONSTRAINTS)
+ if (theTree->checkConstraints == YES && CheckConstraints (tree) == ERROR)
+ {
+ printf ("Error in constraints of starting tree\n");
+ getchar();
+ }
+# endif
+ FreePolyTree (constraintTree);
+ FreePolyTree (constraintTreeRef);
+ if (i==100)
+ {
+ MrBayesPrint ("%s Could not build a starting tree satisfying all constraints\n", spacer);
+ return (ERROR);
+ }
+ }
+ /* random topology */
+ else
+ {
+ if (tree->isRooted == YES)
+ {
+ if (BuildRandomRTopology (tree, &globalSeed) == ERROR)
+ return (ERROR);
+ }
+ else
+ {
+ if (BuildRandomUTopology (tree, &globalSeed) == ERROR)
+ return (ERROR);
+ if (MoveCalculationRoot (tree, localOutGroup) == ERROR)
+ return (ERROR);
+ }
+ }
+
+ if (LabelTree (tree, localTaxonNames) == ERROR)
+ return (ERROR);
+ if (q == p)
+ continue; /* this is a parsimony tree without branch lengths */
+ if (InitializeTreeCalibrations (tree) == ERROR)
+ return (ERROR);
+ if (FillTopologySubParams(p, chn, 0, seed)== ERROR)
+ return (ERROR);
+ }
+ }
+ }
+
+ if (numTopologies > 1 && !strcmp(modelParams[0].topologyPr,"Speciestree"))
+ {
+ if (FillSpeciesTreeParams(seed, fromChain, toChain) == ERROR)
+ return (ERROR);
+ }
+
+ return (NO_ERROR);
+}
+
+
+void FreeCppEvents (Param *p)
+{
+ int i, j;
+
+ if (p->paramType != P_CPPEVENTS)
+ return;
+
+ if (p->nEvents != NULL)
+ {
+ free (p->nEvents[0]);
+ free (p->nEvents);
+ for (i=0; i<numGlobalChains; i++)
+ {
+ for (j=0; j<2*numLocalTaxa; j++)
+ {
+ free (p->position[2*i][j]);
+ free (p->rateMult[2*i][j]);
+ free (p->position[2*i+1][j]);
+ free (p->rateMult[2*i+1][j]);
+ }
+ }
+ free (p->position[0]);
+ free (p->position);
+ free (p->rateMult[0]);
+ free (p->rateMult);
+ p->nEvents = NULL;
+ p->position = NULL;
+ p->rateMult = NULL;
+ }
+}
+
+
+int FreeModel (void)
+{
+ int i;
+ Param *p;
+
+ if (memAllocs[ALLOC_MODEL] == YES)
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ free (modelParams[i].activeConstraints);
+ if (memAllocs[ALLOC_SAMPLEFOSSILSLICE] == YES)
+ {
+ free(modelParams[i].sampleFSProb);
+ free(modelParams[i].sampleFSTime);
+ memAllocs[ALLOC_SAMPLEFOSSILSLICE] = NO;
+ }
+ }
+ free (modelParams);
+ free (modelSettings);
+ memAllocs[ALLOC_MODEL] = NO;
+ }
+ if (memAllocs[ALLOC_MOVES] == YES)
+ {
+ for (i=0; i<numApplicableMoves; i++)
+ FreeMove (moves[i]);
+ free (moves);
+ moves = NULL;
+ numApplicableMoves = 0;
+ memAllocs[ALLOC_MOVES] = NO;
+ }
+ if (memAllocs[ALLOC_COMPMATRIX] == YES)
+ {
+ free (compMatrix);
+ memAllocs[ALLOC_COMPMATRIX] = NO;
+ }
+ if (memAllocs[ALLOC_NUMSITESOFPAT] == YES)
+ {
+ free (numSitesOfPat);
+ memAllocs[ALLOC_NUMSITESOFPAT] = NO;
+ }
+ if (memAllocs[ALLOC_COMPCOLPOS] == YES)
+ {
+ free (compColPos);
+ memAllocs[ALLOC_COMPCOLPOS] = NO;
+ }
+ if (memAllocs[ALLOC_COMPCHARPOS] == YES)
+ {
+ free (compCharPos);
+ memAllocs[ALLOC_COMPCHARPOS] = NO;
+ }
+ if (memAllocs[ALLOC_ORIGCHAR] == YES)
+ {
+ free (origChar);
+ memAllocs[ALLOC_ORIGCHAR] = NO;
+ }
+ if (memAllocs[ALLOC_STDTYPE] == YES)
+ {
+ free (stdType);
+ memAllocs[ALLOC_STDTYPE] = NO;
+ }
+ if (memAllocs[ALLOC_STDSTATEFREQS] == YES)
+ {
+ free (stdStateFreqs);
+ stdStateFreqs = NULL;
+ memAllocs[ALLOC_STDSTATEFREQS] = NO;
+ }
+ if (memAllocs[ALLOC_PARAMVALUES] == YES)
+ {
+ for (i=0; i<numParams; i++)
+ {
+ p = ¶ms[i];
+ if (p->paramType == P_CPPEVENTS)
+ FreeCppEvents(p);
+ }
+ free (paramValues);
+ paramValues = NULL;
+ free (intValues);
+ intValues = NULL;
+ paramValsRowSize = intValsRowSize = 0;
+ memAllocs[ALLOC_PARAMVALUES] = NO;
+ }
+ if (memAllocs[ALLOC_PARAMS] == YES)
+ {
+ for (i=0; i<numParams; i++)
+ {
+ SafeFree ((void **)¶ms[i].name);
+ if (params[i].paramHeader)
+ {
+ free (params[i].paramHeader);
+ params[i].paramHeader = NULL;
+ }
+ }
+ free (params);
+ free (relevantParts);
+ params = NULL;
+ relevantParts = NULL;
+ numParams = 0;
+ memAllocs[ALLOC_PARAMS] = NO;
+ }
+ if (memAllocs[ALLOC_MCMCTREES] == YES)
+ {
+ free (mcmcTree);
+ free (subParamPtrs);
+ mcmcTree = NULL;
+ subParamPtrs = NULL;
+ memAllocs[ALLOC_MCMCTREES] = NO;
+ }
+ if (memAllocs[ALLOC_SYMPIINDEX] == YES)
+ {
+ free (sympiIndex);
+ memAllocs[ALLOC_SYMPIINDEX] = NO;
+ }
+ if (memAllocs[ALLOC_LOCTAXANAMES] == YES)
+ {
+ free (localTaxonNames);
+ memAllocs[ALLOC_LOCTAXANAMES] = NO;
+ }
+ if (memAllocs[ALLOC_LOCALTAXONCALIBRATION] == YES)
+ {
+ free (localTaxonCalibration);
+ memAllocs[ALLOC_LOCALTAXONCALIBRATION] = NO;
+ }
+
+ return (NO_ERROR);
+}
+
+
+void FreeMove (MCMCMove *mv)
+{
+ free (mv->tuningParam[0]);
+ free (mv->tuningParam);
+ free (mv->relProposalProb);
+ free (mv->nAccepted);
+ free (mv->name);
+ free (mv);
+}
+
+
+/* Compute empirical state freq are return it in global array empiricalFreqs[] */
+int GetEmpiricalFreqs (int *relParts, int nRelParts)
+{
+ int i, j, k, m, n, thePartition, nuc[20], ns, temp, isDNA, isProtein, firstRel;
+ MrBFlt freqN[20], sum, sumN[20]/*, rawCounts[20]*/;
+
+ isDNA = isProtein = NO;
+ ns = 0;
+ firstRel = 0;
+ for (i=0; i<nRelParts; i++)
+ {
+ thePartition = relParts[i];
+ if (i == 0)
+ {
+ if (modelParams[thePartition].dataType == DNA || modelParams[i].dataType == RNA)
+ {
+ isDNA = YES;
+ ns = 4;
+ }
+ else if (modelParams[thePartition].dataType == PROTEIN)
+ {
+ isProtein = YES;
+ ns = 20;
+ }
+ else if (modelParams[thePartition].dataType == RESTRICTION)
+ {
+ ns = 2;
+ }
+ else
+ {
+ MrBayesPrint ("%s Cannot get empirical state frequencies for this datatype (%d)\n", spacer, modelSettings[i].dataType);
+ return (ERROR);
+ }
+ firstRel = thePartition;
+ }
+ else
+ {
+ if (modelParams[thePartition].dataType == DNA || modelParams[i].dataType == RNA)
+ temp = 4;
+ else if (modelParams[thePartition].dataType == PROTEIN)
+ temp = 20;
+ else if (modelParams[thePartition].dataType == RESTRICTION)
+ temp = 2;
+ else
+ {
+ MrBayesPrint ("%s Unknown data type in GetEmpiricalFreqs\n", spacer);
+ return (ERROR);
+ }
+ if (ns != temp)
+ {
+ MrBayesPrint ("%s Averaging state frequencies over partitions with different data types\n", spacer);
+ return (ERROR);
+ }
+ }
+ }
+ if (ns == 0)
+ {
+ MrBayesPrint ("%s Could not find a relevant partition\n", spacer);
+ return (ERROR);
+ }
+
+ for (i=0; i<200; i++)
+ empiricalFreqs[i] = 0.0;
+
+ for (m=0; m<ns; m++)
+ freqN[m] = 1.0 / ns;
+
+ /* for (m=0; m<ns; m++)
+ rawCounts[m] = 0.0; NEVER USED */
+
+ for (m=0; m<ns; m++)
+ sumN[m] = 0.0;
+ for (k=0; k<nRelParts; k++)
+ {
+ thePartition = relParts[k];
+ for (i=0; i<numTaxa; i++)
+ {
+ if (taxaInfo[i].isDeleted == NO)
+ {
+ for (j=0; j<numChar; j++)
+ {
+ if (charInfo[j].isExcluded == NO && partitionId[j][partitionNum] - 1 == thePartition)
+ {
+ if (isDNA == YES)
+ GetPossibleNucs (matrix[pos(i,j,numChar)], nuc);
+ else if (isProtein == YES)
+ GetPossibleAAs (matrix[pos(i,j,numChar)], nuc);
+ else
+ GetPossibleRestrictionSites (matrix[pos(i,j,numChar)], nuc);
+ sum = 0.0;
+ for (m=0; m<ns; m++)
+ sum += freqN[m] * nuc[m];
+ for (m=0; m<ns; m++)
+ sumN[m] += freqN[m] * nuc[m] / sum;
+ }
+ }
+ }
+ }
+ }
+ sum = 0.0;
+ for (m=0; m<ns; m++)
+ sum += sumN[m];
+ for (m=0; m<ns; m++)
+ freqN[m] = sumN[m] / sum;
+
+ if (modelParams[firstRel].dataType == DNA || modelParams[firstRel].dataType == RNA)
+ {
+ if (!strcmp(modelParams[firstRel].nucModel, "4by4"))
+ {
+ for (m=0; m<ns; m++)
+ empiricalFreqs[m] = freqN[m];
+ }
+ else if (!strcmp(modelParams[firstRel].nucModel, "Doublet"))
+ {
+ i = 0;
+ for (m=0; m<ns; m++)
+ for (n=0; n<ns; n++)
+ empiricalFreqs[i++] = freqN[m] * freqN[n];
+ }
+ else
+ {
+ if (!strcmp(modelParams[firstRel].geneticCode, "Universal"))
+ {
+ for (i=0; i<61; i++)
+ empiricalFreqs[i] = freqN[modelParams[firstRel].codonNucs[i][0]] * freqN[modelParams[firstRel].codonNucs[i][1]] * freqN[modelParams[firstRel].codonNucs[i][2]];
+ }
+ else if (!strcmp(modelParams[firstRel].geneticCode, "Vertmt"))
+ {
+ for (i=0; i<60; i++)
+ empiricalFreqs[i] = freqN[modelParams[firstRel].codonNucs[i][0]] * freqN[modelParams[firstRel].codonNucs[i][1]] * freqN[modelParams[firstRel].codonNucs[i][2]];
+ }
+ else if (!strcmp(modelParams[firstRel].geneticCode, "Invermt"))
+ {
+ for (i=0; i<62; i++)
+ empiricalFreqs[i] = freqN[modelParams[firstRel].codonNucs[i][0]] * freqN[modelParams[firstRel].codonNucs[i][1]] * freqN[modelParams[firstRel].codonNucs[i][2]];
+ }
+ else if (!strcmp(modelParams[firstRel].geneticCode, "Mycoplasma"))
+ {
+ for (i=0; i<62; i++)
+ empiricalFreqs[i] = freqN[modelParams[firstRel].codonNucs[i][0]] * freqN[modelParams[firstRel].codonNucs[i][1]] * freqN[modelParams[firstRel].codonNucs[i][2]];
+ }
+ else if (!strcmp(modelParams[firstRel].geneticCode, "Yeast"))
+ {
+ for (i=0; i<62; i++)
+ empiricalFreqs[i] = freqN[modelParams[firstRel].codonNucs[i][0]] * freqN[modelParams[firstRel].codonNucs[i][1]] * freqN[modelParams[firstRel].codonNucs[i][2]];
+ }
+ else if (!strcmp(modelParams[firstRel].geneticCode, "Ciliate"))
+ {
+ for (i=0; i<63; i++)
+ empiricalFreqs[i] = freqN[modelParams[firstRel].codonNucs[i][0]] * freqN[modelParams[firstRel].codonNucs[i][1]] * freqN[modelParams[firstRel].codonNucs[i][2]];
+ }
+ else if (!strcmp(modelParams[firstRel].geneticCode, "Echinoderm"))
+ {
+ for (i=0; i<62; i++)
+ empiricalFreqs[i] = freqN[modelParams[firstRel].codonNucs[i][0]] * freqN[modelParams[firstRel].codonNucs[i][1]] * freqN[modelParams[firstRel].codonNucs[i][2]];
+ }
+ else if (!strcmp(modelParams[firstRel].geneticCode, "Euplotid"))
+ {
+ for (i=0; i<62; i++)
+ empiricalFreqs[i] = freqN[modelParams[firstRel].codonNucs[i][0]] * freqN[modelParams[firstRel].codonNucs[i][1]] * freqN[modelParams[firstRel].codonNucs[i][2]];
+ }
+ else if (!strcmp(modelParams[firstRel].geneticCode, "Metmt"))
+ {
+ for (i=0; i<62; i++)
+ empiricalFreqs[i] = freqN[modelParams[firstRel].codonNucs[i][0]] * freqN[modelParams[firstRel].codonNucs[i][1]] * freqN[modelParams[firstRel].codonNucs[i][2]];
+ }
+ sum = 0.0;
+ for (i=0; i<64; i++)
+ sum += empiricalFreqs[i];
+ for (i=0; i<64; i++)
+ empiricalFreqs[i] /= sum;
+
+ }
+ }
+ else
+ {
+ for (m=0; m<ns; m++)
+ empiricalFreqs[m] = freqN[m];
+ }
+
+ return (NO_ERROR);
+}
+
+
+int GetNumDivisionChars (void)
+{
+ int c, d, n;
+ ModelInfo *m;
+
+ /* count number of characters in each division */
+ for (d=0; d<numCurrentDivisions; d++)
+ {
+ m = &modelSettings[d];
+
+ n = 0;
+ for (c=0; c<numChar; c++)
+ {
+ if (charInfo[c].isExcluded == NO && partitionId[c][partitionNum] == d+1)
+ n++;
+ }
+ if (m->dataType == DNA || m->dataType == RNA)
+ {
+ if (m->nucModelId == NUCMODEL_DOUBLET)
+ n *= 2;
+ else if (m->nucModelId == NUCMODEL_CODON)
+ n *= 3;
+ }
+
+ m->numUncompressedChars = n;
+ }
+
+ return (NO_ERROR);
+}
+
+
+int *GetParamIntVals (Param *parm, int chain, int state)
+{
+ return parm->intValues + (2 * chain + state) * intValsRowSize;
+}
+
+
+MrBFlt *GetParamStdStateFreqs (Param *parm, int chain, int state)
+{
+ return parm->stdStateFreqs + (2 * chain + state) * stdStateFreqsRowSize;
+}
+
+
+MrBFlt *GetParamSubVals (Param *parm, int chain, int state)
+{
+ return parm->subValues + (2 * chain + state) * paramValsRowSize;
+}
+
+
+MrBFlt *GetParamVals (Param *parm, int chain, int state)
+{
+ return parm->values + (2 * chain + state) * paramValsRowSize;
+}
+
+
+void GetPossibleAAs (int aaCode, int aa[])
+{
+ int m;
+
+ for (m=0; m<20; m++)
+ aa[m] = 0;
+
+ if (aaCode > 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
+ {
+ nuc[0] = 1;
+ nuc[1] = 1;
+ nuc[2] = 1;
+ nuc[3] = 1;
+ }
+}
+
+
+void GetPossibleRestrictionSites (int resSiteCode, int *sites)
+{
+ int m;
+
+ for (m=0; m<2; m++)
+ sites[m] = 0;
+
+ if (resSiteCode == 1)
+ sites[0] = 1;
+ else if (resSiteCode == 2)
+ sites[1] = 1;
+ else
+ sites[0] = sites[1] = 1;
+
+# if 0
+ printf ("%2d -- ", aaCode);
+ for (m=0; m<20; m++)
+ printf ("%d", aa[m]);
+ printf ("\n");
+# endif
+}
+
+
+Tree *GetTree (Param *parm, int chain, int state)
+{
+ return mcmcTree[parm->treeIndex + ((2 * chain + state) * numTrees)];
+}
+
+
+Tree *GetTreeFromIndex (int index, int chain, int state)
+{
+ return mcmcTree[index + ((2 * chain + state) * numTrees)];
+}
+
+
+/*-----------------------------------------------------------
+|
+| GetUserTreeFromName: Do case-insensitive search for user
+| tree, return index if match, -1 and ERROR if error
+|
+------------------------------------------------------------*/
+int GetUserTreeFromName (int *index, char *treeName)
+{
+ int i, j, k, nMatches;
+ char localName[100], temp[100];
+
+ (*index) = -1; /* appropriate return if no match */
+
+ if ((int)strlen(treeName) > 99)
+ {
+ MrBayesPrint ("%s Too many characters in tree name\n", spacer);
+ return (ERROR);
+ }
+
+ strcpy (localName, treeName);
+ for (i=0; i<(int)strlen(localName); i++)
+ localName[i] = tolower(localName[i]);
+
+ nMatches = j = 0;
+ for (i=0; i<numUserTrees; i++)
+ {
+ strcpy (temp, userTree[i]->name);
+ for (k=0; k<(int)strlen(temp); k++)
+ temp[k] = tolower(temp[k]);
+ if (strcmp(localName,temp) == 0)
+ {
+ j = i;
+ nMatches++;
+ }
+ }
+ if (nMatches==0)
+ {
+ for (i=0; i<numUserTrees; i++)
+ {
+ strcpy (temp, userTree[i]->name);
+ for (k=0; k<(int)strlen(temp); k++)
+ temp[k] = tolower(temp[k]);
+ if (strncmp(localName,temp,strlen(localName)) == 0)
+ {
+ j = i;
+ nMatches++;
+ }
+ }
+ }
+ if (nMatches == 0)
+ {
+ MrBayesPrint ("%s Could not find tree '%s'\n", spacer, localName);
+ return (ERROR);
+ }
+ else if (nMatches > 1)
+ {
+ MrBayesPrint ("%s Several trees matched the abbreviated name '%s'\n", spacer, localName);
+ return (ERROR);
+ }
+ else
+ {
+ (*index) = j;
+ return (NO_ERROR);
+ }
+}
+
+
+/*----------------------------------------------------------------------
+ |
+ | InitializeChainTrees: 'Constructor' for chain trees
+ |
+ -----------------------------------------------------------------------*/
+int InitializeChainTrees (Param *p, int from, int to, int isRooted)
+{
+ int i, st, isCalibrated, isClock, nTaxa, numActiveHardConstraints=0;
+ Tree *tree, **treeHandle;
+ Model *mp;
+
+ mp = &modelParams[p->relParts[0]];
+
+ if (p->paramType == P_SPECIESTREE)
+ nTaxa = numSpecies;
+ else
+ nTaxa = numLocalTaxa;
+
+ /* figure out whether the trees are clock */
+ if (!strcmp(mp->brlensPr,"Clock"))
+ isClock = YES;
+ else
+ isClock = NO;
+
+ /* figure out whether the trees are calibrated */
+ if (!strcmp(mp->brlensPr,"Clock") && (strcmp(mp->nodeAgePr,"Calibrated") == 0 || strcmp(mp->clockRatePr,"Fixed") != 0 ||
+ (strcmp(mp->clockRatePr, "Fixed") == 0 && AreDoublesEqual(mp->clockRateFix, 1.0, 1E-6) == NO)))
+ isCalibrated = YES;
+ else
+ isCalibrated = NO;
+
+ if (p->checkConstraints == YES)
+ {
+ for (i=0; i<numDefinedConstraints; i++)
+ {
+ if (mp->activeConstraints[i] == YES && definedConstraintsType[i] == HARD)
+ numActiveHardConstraints++;
+ }
+ }
+
+ /* allocate space for and construct the trees */
+ /* NOTE: The memory allocation scheme used here must match GetTree and GetTreeFromIndex */
+ for (i=from; i<to; i++)
+ {
+ treeHandle = mcmcTree + p->treeIndex + 2*i*numTrees;
+ if (*treeHandle)
+ free(*treeHandle);
+ if ((*treeHandle = AllocateTree (nTaxa)) == NULL)
+ {
+ MrBayesPrint ("%s Problem allocating mcmc trees\n", spacer);
+ return (ERROR);
+ }
+ treeHandle = mcmcTree + p->treeIndex + (2*i + 1)*numTrees;
+ if (*treeHandle)
+ free(*treeHandle);
+ if ((*treeHandle = AllocateTree (nTaxa)) == NULL)
+ {
+ MrBayesPrint ("%s Problem allocating mcmc trees\n", spacer);
+ return (ERROR);
+ }
+ }
+
+ /* initialize the trees */
+ for (i=from; i<to; i++)
+ {
+ for (st=0; st<2; st++)
+ {
+ tree = GetTree (p, i, st);
+ if (numTrees > 1)
+ sprintf (tree->name, "mcmc.tree%d_%d", p->treeIndex+1, i+1);
+ else /* if (numTrees == 1) */
+ sprintf (tree->name, "mcmc.tree_%d", i+1);
+ tree->nRelParts = p->nRelParts;
+ tree->relParts = p->relParts;
+ tree->isRooted = isRooted;
+ tree->isClock = isClock;
+ tree->isCalibrated = isCalibrated;
+ if (p->paramType == P_SPECIESTREE)
+ {
+ tree->nNodes = 2*numSpecies;
+ tree->nIntNodes = numSpecies - 1;
+ }
+ else if (tree->isRooted == YES)
+ {
+ tree->nNodes = 2*numLocalTaxa;
+ tree->nIntNodes = numLocalTaxa - 1;
+ }
+ else /* if (tree->isRooted == NO) */
+ {
+ tree->nNodes = 2*numLocalTaxa - 2;
+ tree->nIntNodes = numLocalTaxa - 2;
+ }
+ if (p->checkConstraints == YES)
+ {
+ tree->checkConstraints = YES;
+ tree->nLocks = NumInformativeHardConstraints(mp);
+ tree->nConstraints = mp->numActiveConstraints; /* nConstraints is number of constraints to check */
+ tree->constraints = mp->activeConstraints;
+ }
+ else
+ {
+ tree->checkConstraints = NO;
+ tree->nConstraints = tree->nLocks = 0;
+ tree->constraints = NULL;
+ }
+ }
+ }
+
+ return (NO_ERROR);
+}
+
+
+int InitializeLinks (void)
+{
+ int i, j;
+
+ linkNum = 0;
+ for (i=0; i<NUM_LINKED; i++)
+ {
+ for (j=0; j<numCurrentDivisions; j++)
+ linkTable[i][j] = linkNum;
+ }
+
+ return (NO_ERROR);
+}
+
+
+/* InitializeTreeCalibrations: Set calibrations for tree nodes */
+int InitializeTreeCalibrations (Tree *t)
+{
+ int i;
+ TreeNode *p;
+
+ if (t->isCalibrated == NO)
+ return (NO_ERROR);
+
+ /* Set tip calibrations */
+ for (i=0; i<t->nNodes; i++)
+ {
+ p = t->allDownPass[i];
+ if (p->left == NULL && p->right == NULL && localTaxonCalibration[p->index]->prior != unconstrained)
+ {
+ p->isDated = YES;
+ p->calibration = localTaxonCalibration[p->index];
+ p->age = p->calibration->min;
+ }
+ else if (p->left == NULL && p->right == NULL)
+ {
+ p->isDated = NO;
+ p->calibration = NULL;
+ p->age = -1.0;
+ }
+ }
+
+ /* Initialize interior calibrations */
+ if (CheckSetConstraints(t) == ERROR)
+ return (ERROR);
+
+ return (NO_ERROR);
+}
+
+
+int IsApplicable (Param *param)
+{
+ if (param == NULL)
+ return NO;
+
+ return YES;
+}
+
+
+int IsApplicable_ThreeTaxaOrMore (Param *param)
+{
+ if (LargestMovableSubtree (param) >= 3)
+ return YES;
+ else
+ return NO;
+}
+
+
+int IsApplicable_FourTaxaOrMore (Param *param)
+{
+ if (LargestMovableSubtree (param) >= 4)
+ return YES;
+ else
+ return NO;
+}
+
+
+int IsApplicable_FiveTaxaOrMore (Param *param)
+{
+ if (LargestMovableSubtree (param) >= 5)
+ return YES;
+ else
+ return NO;
+}
+
+
+int IsApplicable_TreeAgeMove (Param *param)
+{
+ Tree *t;
+ TreeNode *p;
+
+ if (param == NULL)
+ return NO;
+
+ if (param->paramType != P_BRLENS)
+ return NO;
+
+ t = GetTree (param, 0, 0);
+
+ p = t->root->left;
+ if (p->isDated == NO)
+ return NO;
+ if (p->calibration->prior == fixed)
+ return NO;
+ else
+ return YES;
+}
+
+
+int IsApplicable_AncestralFossil (Param *param)
+{
+ ModelParams *mp = &modelParams[param->relParts[0]];
+
+ if (!strcmp(mp->sampleStrat, "FossilTip"))
+ return NO;
+ else if (mp->fossilizationFix == 0.0)
+ return NO;
+ else /* fossils may be ancestors of other fossils or extant species */
+ return YES;
+}
+
+
+int IsModelSame (int whichParam, int part1, int part2, int *isApplic1, int *isApplic2)
+{
+ int i, isSame, isFirstNucleotide, isSecondNucleotide, isFirstProtein, isSecondProtein, nDiff, temp1, temp2;
+
+ isSame = YES;
+ *isApplic1 = YES;
+ *isApplic2 = YES;
+
+ /* We cannot rely on SetModelInfo being called first so we need to be smart in figuring out model data type by looking at several model params */
+ isFirstNucleotide = isSecondNucleotide = NO;
+ if ((modelParams[part1].dataType == DNA || modelParams[part1].dataType == RNA) && strcmp(modelParams[part1].nucModel,"Protein") != 0)
+ isFirstNucleotide = YES;
+ if ((modelParams[part2].dataType == DNA || modelParams[part2].dataType == RNA) && strcmp(modelParams[part2].nucModel,"Protein") != 0)
+ isSecondNucleotide = YES;
+ isFirstProtein = isSecondProtein = NO;
+ if (modelParams[part1].dataType == PROTEIN || ((modelParams[part1].dataType == DNA || modelParams[part1].dataType == RNA) && !strcmp(modelParams[part1].nucModel,"Protein")))
+ isFirstProtein = YES;
+ if (modelParams[part2].dataType == PROTEIN || ((modelParams[part2].dataType == DNA || modelParams[part2].dataType == RNA) && !strcmp(modelParams[part2].nucModel,"Protein")))
+ isSecondProtein = YES;
+
+ if (whichParam == P_TRATIO)
+ {
+ /* Check the ti/tv rate ratio for partitions 1 and 2. */
+
+ /* Check if the model is parsimony for either partition */
+ if (!strcmp(modelParams[part1].parsModel, "Yes"))
+ *isApplic1 = NO; /* part1 has a parsimony model and tratio does not apply */
+ if (!strcmp(modelParams[part2].parsModel, "Yes"))
+ *isApplic2 = NO; /* part2 has a parsimony model and tratio does not apply */
+
+ /* Check that the data are nucleotide for both partitions 1 and 2 */
+ if (isFirstNucleotide == NO)
+ *isApplic1 = NO; /* part1 is not nucleotide data so tratio does not apply */
+ if (isSecondNucleotide == NO)
+ *isApplic2 = NO; /* part2 is not nucleotide data so tratio does not apply */
+
+ /* check that nst=2 for both partitions */
+ if (strcmp(modelParams[part1].nst, "2"))
+ *isApplic1 = NO; /* part1 does not have nst=2 and tratio does not apply */
+ if (strcmp(modelParams[part2].nst, "2"))
+ *isApplic2 = NO; /* part2 does not have nst=2 and tratio does not apply */
+
+ /* Check if part1 & part2 are restriction */
+ if (modelParams[part1].dataType == RESTRICTION)
+ *isApplic1 = NO;
+ if (modelParams[part2].dataType == RESTRICTION)
+ *isApplic2 = NO;
+
+ /* If Nst = 2 for both part1 and part2, we now need to check if the prior is the same for both. */
+ if (!strcmp(modelParams[part1].tRatioPr,"Beta") && !strcmp(modelParams[part2].tRatioPr,"Beta"))
+ {
+ if (AreDoublesEqual (modelParams[part1].tRatioDir[0], modelParams[part2].tRatioDir[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].tRatioDir[1], modelParams[part2].tRatioDir[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].tRatioPr,"Fixed") && !strcmp(modelParams[part2].tRatioPr,"Fixed"))
+ {
+ if (AreDoublesEqual (modelParams[part1].tRatioFix, modelParams[part2].tRatioFix, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else
+ isSame = NO; /* the priors are not the same, so we cannot set the parameter to be equal for both partitions */
+
+ /* Check to see if tratio is inapplicable for either partition. */
+ if ((*isApplic1) == NO || (*isApplic2) == NO)
+ isSame = NO; /* if tratio is inapplicable for either partition, then the parameter cannot be the same */
+ }
+ else if (whichParam == P_REVMAT)
+ {
+ /* Check the GTR rates for partitions 1 and 2. */
+
+ /* Check if the model is parsimony for either partition */
+ if (!strcmp(modelParams[part1].parsModel, "Yes"))
+ *isApplic1 = NO; /* part1 has a parsimony model and GTR rates do not apply */
+ if (!strcmp(modelParams[part2].parsModel, "Yes"))
+ *isApplic2 = NO; /* part2 has a parsimony model and GTR rates do not apply */
+
+ /* Check that the data are nucleotide or protein for both partitions 1 and 2 */
+ if (isFirstNucleotide == NO && isFirstProtein == NO)
+ *isApplic1 = NO; /* part1 is not nucleotide or protein data so GTR rates do not apply */
+ if (isSecondNucleotide == NO && isSecondProtein == NO)
+ *isApplic2 = NO; /* part2 is not nucleotide or protein data so GTR rates do not apply */
+
+ /* check that nst=6 or mixed for both partitions if nucleotide */
+ if (isFirstNucleotide == YES && strcmp(modelParams[part1].nst, "6") && strcmp(modelParams[part1].nst, "Mixed"))
+ *isApplic1 = NO; /* part1 does not have nst=6/Mixed and GTR rates do not apply */
+ if (isSecondNucleotide == YES && strcmp(modelParams[part2].nst, "6") && strcmp(modelParams[part2].nst, "Mixed"))
+ *isApplic2 = NO; /* part2 does not have nst=6/Mixed and GTR rates do not apply */
+
+ /* check that model is GTR for both partitions if protein */
+ if (isFirstProtein == YES && (strcmp(modelParams[part1].aaModel,"Gtr")!=0 || strcmp(modelParams[part1].aaModelPr,"Fixed")!=0))
+ *isApplic1 = NO;
+ if (isSecondProtein == YES && (strcmp(modelParams[part2].aaModel,"Gtr")!=0 || strcmp(modelParams[part2].aaModelPr,"Fixed")!=0))
+ *isApplic2 = NO;
+
+ /* check that data type is the same for both partitions */
+ if (isFirstNucleotide == YES && isSecondNucleotide == NO)
+ isSame = NO;
+ if (isFirstProtein == YES && isSecondProtein == NO)
+ isSame = NO;
+
+ /* GTR applies to both part1 and part2. We now need to check if the prior is the same for both. */
+ if (isFirstNucleotide == YES)
+ {
+ if (strcmp(modelParams[part1].nst, modelParams[part2].nst) != 0)
+ isSame = NO;
+ if (!strcmp(modelParams[part1].nst,"Mixed"))
+ {
+ if (AreDoublesEqual (modelParams[part1].revMatSymDir, modelParams[part2].revMatSymDir, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].nst,"6") && !strcmp(modelParams[part1].revMatPr,"Dirichlet") && !strcmp(modelParams[part2].revMatPr,"Dirichlet"))
+ {
+ for (i=0; i<6; i++)
+ {
+ if (AreDoublesEqual (modelParams[part1].revMatDir[i], modelParams[part2].revMatDir[i], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ }
+ else if (!strcmp(modelParams[part1].nst,"6") && !strcmp(modelParams[part1].revMatPr,"Fixed") && !strcmp(modelParams[part2].revMatPr,"Fixed"))
+ {
+ for (i=0; i<6; i++)
+ {
+ if (AreDoublesEqual (modelParams[part1].revMatFix[i], modelParams[part2].revMatFix[i], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ }
+ else
+ isSame = NO; /* the priors are not the same, so we cannot set the parameter to be equal for both partitions */
+ }
+ else /* if (isFirstProtein == YES) */
+ {
+ if (!strcmp(modelParams[part1].aaRevMatPr,"Dirichlet") && !strcmp(modelParams[part2].aaRevMatPr,"Dirichlet"))
+ {
+ for (i=0; i<190; i++)
+ {
+ if (AreDoublesEqual (modelParams[part1].aaRevMatDir[i], modelParams[part2].aaRevMatDir[i], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ }
+ else if (!strcmp(modelParams[part1].aaRevMatPr,"Fixed") && !strcmp(modelParams[part2].aaRevMatPr,"Fixed"))
+ {
+ for (i=0; i<190; i++)
+ {
+ if (AreDoublesEqual (modelParams[part1].aaRevMatFix[i], modelParams[part2].aaRevMatFix[i], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ }
+ else
+ isSame = NO; /* the priors are not the same, so we cannot set the parameter to be equal for both partitions */
+ }
+
+ /* Check to see if the GTR rates are inapplicable for either partition. */
+ if ((*isApplic1) == NO || (*isApplic2) == NO)
+ isSame = NO; /* if GTR rates are inapplicable for either partition, then the parameter cannot be the same */
+ }
+ else if (whichParam == P_OMEGA)
+ {
+ /* Check the nonsynonymous/synonymous rate ratio for partitions 1 and 2. */
+
+ /* Check if the model is parsimony for either partition */
+ if (!strcmp(modelParams[part1].parsModel, "Yes"))
+ *isApplic1 = NO; /* part1 has a parsimony model and nonsynonymous/synonymous rate ratio does not apply */
+ if (!strcmp(modelParams[part2].parsModel, "Yes"))
+ *isApplic2 = NO; /* part2 has a parsimony model and nonsynonymous/synonymous rate ratio does not apply */
+
+ /* Check that the data are nucleotide for both partitions 1 and 2 */
+ if (isFirstNucleotide == NO)
+ *isApplic1 = NO; /* part1 is not nucleotide data so a nonsynonymous/synonymous rate ratio does not apply */
+ if (isSecondNucleotide == NO)
+ *isApplic2 = NO; /* part2 is not nucleotide data so a nonsynonymous/synonymous rate ratio does not apply */
+
+ /* Check that the model structure is the same for both. The nucmodel should be "codon". */
+ if (strcmp(modelParams[part1].nucModel, "Codon"))
+ *isApplic1 = NO; /* part1 does not have Nucmodel = Codon and nonsynonymous/synonymous rate ratio does not apply */
+ if (strcmp(modelParams[part2].nucModel, "Codon"))
+ *isApplic2 = NO; /* part2 does not have Nucmodel = Codon and nonsynonymous/synonymous rate ratio does not apply */
+
+ /* Assuming that Nucmodel = Codon for both part1 and part2, we now need to check if the prior is the
+ same for both. */
+ if (!strcmp(modelParams[part1].omegaVar, "M3") && !strcmp(modelParams[part2].omegaVar, "M3"))
+ {
+ if (!strcmp(modelParams[part1].m3omegapr, "Exponential") && !strcmp(modelParams[part2].m3omegapr, "Exponential"))
+ {
+ }
+ else if (!strcmp(modelParams[part1].m3omegapr, "Fixed") && !strcmp(modelParams[part1].m3omegapr, "Fixed"))
+ {
+ if (AreDoublesEqual (modelParams[part1].m3omegaFixed[0], modelParams[part2].m3omegaFixed[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].m3omegaFixed[1], modelParams[part2].m3omegaFixed[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else
+ isSame = NO; /* the priors are not the same, so we cannot set the parameter to be equal for both partitions */
+
+ if (!strcmp(modelParams[part1].codonCatFreqPr, "Dirichlet") && !strcmp(modelParams[part2].codonCatFreqPr, "Dirichlet"))
+ {
+ if (AreDoublesEqual (modelParams[part1].codonCatDir[0], modelParams[part2].codonCatDir[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].codonCatDir[1], modelParams[part2].codonCatDir[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].codonCatDir[2], modelParams[part2].codonCatDir[2], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].codonCatFreqPr, "Fixed") && !strcmp(modelParams[part1].codonCatFreqPr, "Fixed"))
+ {
+ if (AreDoublesEqual (modelParams[part1].codonCatFreqFix[0], modelParams[part2].codonCatFreqFix[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].codonCatFreqFix[1], modelParams[part2].codonCatFreqFix[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].codonCatFreqFix[2], modelParams[part2].codonCatFreqFix[2], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else
+ isSame = NO; /* the priors are not the same, so we cannot set the parameter to be equal for both partitions */
+ }
+ else if (!strcmp(modelParams[part1].omegaVar, "M10") && !strcmp(modelParams[part2].omegaVar, "M10"))
+ {
+ if (!strcmp(modelParams[part1].codonCatFreqPr, "Dirichlet") && !strcmp(modelParams[part2].codonCatFreqPr, "Dirichlet"))
+ {
+ if (AreDoublesEqual (modelParams[part1].codonCatDir[0], modelParams[part2].codonCatDir[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].codonCatDir[1], modelParams[part2].codonCatDir[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].codonCatFreqPr, "Fixed") && !strcmp(modelParams[part1].codonCatFreqPr, "Fixed"))
+ {
+ if (AreDoublesEqual (modelParams[part1].codonCatFreqFix[0], modelParams[part2].codonCatFreqFix[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].codonCatFreqFix[1], modelParams[part2].codonCatFreqFix[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else
+ isSame = NO; /* the priors are not the same, so we cannot set the parameter to be equal for both partitions */
+ }
+ else if (!strcmp(modelParams[part1].omegaVar, "Ny98") && !strcmp(modelParams[part2].omegaVar, "Ny98"))
+ {
+ if (!strcmp(modelParams[part1].ny98omega1pr, "Beta") && !strcmp(modelParams[part2].ny98omega1pr, "Beta"))
+ {
+ if (AreDoublesEqual (modelParams[part1].ny98omega1Beta[0], modelParams[part2].ny98omega1Beta[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].ny98omega1Beta[1], modelParams[part2].ny98omega1Beta[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].ny98omega1pr, "Fixed") && !strcmp(modelParams[part1].ny98omega1pr, "Fixed"))
+ {
+ if (AreDoublesEqual (modelParams[part1].ny98omega1Fixed, modelParams[part2].ny98omega1Fixed, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else
+ isSame = NO; /* the priors are not the same, so we cannot set the parameter to be equal for both partitions */
+ if (!strcmp(modelParams[part1].ny98omega3pr, "Uniform") && !strcmp(modelParams[part2].ny98omega3pr, "Uniform"))
+ {
+ if (AreDoublesEqual (modelParams[part1].ny98omega3Uni[0], modelParams[part2].ny98omega3Uni[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].ny98omega3Uni[1], modelParams[part2].ny98omega3Uni[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].ny98omega3pr, "Exponential") && !strcmp(modelParams[part1].ny98omega3pr, "Exponential"))
+ {
+ if (AreDoublesEqual (modelParams[part1].ny98omega3Exp, modelParams[part2].ny98omega3Exp, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].ny98omega3pr, "Fixed") && !strcmp(modelParams[part1].ny98omega3pr, "Fixed"))
+ {
+ if (AreDoublesEqual (modelParams[part1].ny98omega3Fixed, modelParams[part2].ny98omega3Fixed, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else
+ isSame = NO; /* the priors are not the same, so we cannot set the parameter to be equal for both partitions */
+ if (!strcmp(modelParams[part1].codonCatFreqPr, "Dirichlet") && !strcmp(modelParams[part2].codonCatFreqPr, "Dirichlet"))
+ {
+ if (AreDoublesEqual (modelParams[part1].codonCatDir[0], modelParams[part2].codonCatDir[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].codonCatDir[1], modelParams[part2].codonCatDir[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].codonCatDir[2], modelParams[part2].codonCatDir[2], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].codonCatFreqPr, "Fixed") && !strcmp(modelParams[part1].codonCatFreqPr, "Fixed"))
+ {
+ if (AreDoublesEqual (modelParams[part1].codonCatFreqFix[0], modelParams[part2].codonCatFreqFix[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].codonCatFreqFix[1], modelParams[part2].codonCatFreqFix[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].codonCatFreqFix[2], modelParams[part2].codonCatFreqFix[2], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else
+ isSame = NO; /* the priors are not the same, so we cannot set the parameter to be equal for both partitions */
+ }
+ else if (!strcmp(modelParams[part1].omegaVar, "Equal") && !strcmp(modelParams[part2].omegaVar, "Equal"))
+ {
+ if (!strcmp(modelParams[part1].omegaPr,"Dirichlet") && !strcmp(modelParams[part2].omegaPr,"Dirichlet"))
+ {
+ if (AreDoublesEqual (modelParams[part1].omegaDir[0], modelParams[part2].omegaDir[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].omegaDir[1], modelParams[part2].omegaDir[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].omegaPr,"Fixed") && !strcmp(modelParams[part2].omegaPr,"Fixed"))
+ {
+ if (AreDoublesEqual (modelParams[part1].omegaFix, modelParams[part2].omegaFix, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else
+ isSame = NO; /* the priors are not the same, so we cannot set the parameter to be equal for both partitions */
+ }
+ else
+ isSame = NO; /* the priors are not the same, so we cannot set the parameter to be equal for both partitions */
+
+ /* Check to see if omega is inapplicable for either partition. */
+ if ((*isApplic1) == NO || (*isApplic2) == NO)
+ isSame = NO; /* if omega is inapplicable for either partition, then the parameter cannot be the same */
+ }
+ else if (whichParam == P_PI)
+ {
+ /* Check the state frequencies for partitions 1 and 2. */
+
+ /* Check if the model is parsimony for either partition */
+ if (!strcmp(modelParams[part1].parsModel, "Yes"))
+ *isApplic1 = NO; /* part1 has a parsimony model and state frequencies do not apply */
+ if (!strcmp(modelParams[part2].parsModel, "Yes"))
+ *isApplic2 = NO; /* part2 has a parsimony model and state frequencies do not apply */
+
+ /* Check that the data are not CONTINUOUS for partitions 1 and 2 */
+ if (modelParams[part1].dataType == CONTINUOUS)
+ *isApplic1 = NO; /* state frequencies do not make sense for part1 */
+ if (modelParams[part2].dataType == CONTINUOUS)
+ *isApplic2 = NO; /* state frequencies do not make sense for part2 */
+
+ /* Now, check that the data are the same (i.e., both nucleotide or both amino acid, or whatever). */
+ if (isFirstNucleotide != isSecondNucleotide)
+ isSame = NO; /* data are not both nucleotide or both note nucleotide */
+ else if (modelParams[part1].dataType != modelParams[part2].dataType && isFirstNucleotide == NO)
+ isSame = NO; /* data are not the same */
+
+ /* Check that the model structure is the same for both partitions */
+ if (strcmp(modelParams[part1].nucModel, modelParams[part2].nucModel))
+ isSame = NO; /* the nucleotide models are different */
+ if (strcmp(modelParams[part1].covarionModel, modelParams[part2].covarionModel) && !(!strcmp(modelParams[part1].nucModel, "Codon") && !strcmp(modelParams[part2].nucModel, "Codon")))
+ isSame = NO; /* the models have different covarion struture */
+
+ /* If both partitions have nucmodel=codon, then we also have to make certain that the same genetic code is used. */
+ if (!strcmp(modelParams[part1].nucModel, "Codon") && !strcmp(modelParams[part2].nucModel, "Codon"))
+ {
+ if (strcmp(modelParams[part1].geneticCode, modelParams[part2].geneticCode))
+ isSame = NO; /* the models have different genetic codes */
+ }
+
+ /* Let's see if the prior is the same. */
+ if (modelParams[part1].dataType == STANDARD && modelParams[part2].dataType == STANDARD)
+ {
+ /* The data are morphological (STANDARD). The state frequencies are specified by a
+ symmetric beta distribution, the parameter of which needs to be the same to apply to both
+ partitions. Note that symPiPr = -1 is equivalent to setting the variance to 0.0. */
+ if (!strcmp(modelParams[part1].symPiPr,"Uniform") && !strcmp(modelParams[part2].symPiPr,"Uniform"))
+ {
+ if (AreDoublesEqual (modelParams[part1].symBetaUni[0], modelParams[part2].symBetaUni[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].symBetaUni[1], modelParams[part2].symBetaUni[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (modelParams[part1].numBetaCats != modelParams[part2].numBetaCats)
+ isSame = NO; /* can't link because the discrete beta approximation is different */
+ }
+ else if (!strcmp(modelParams[part1].symPiPr,"Exponential") && !strcmp(modelParams[part2].symPiPr,"Exponential"))
+ {
+ if (AreDoublesEqual (modelParams[part1].symBetaExp, modelParams[part2].symBetaExp, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (modelParams[part1].numBetaCats != modelParams[part2].numBetaCats)
+ isSame = NO; /* can't link because the discrete beta approximation is different */
+ }
+ else if (!strcmp(modelParams[part1].symPiPr,"Fixed") && !strcmp(modelParams[part2].symPiPr,"Fixed"))
+ {
+ if (AreDoublesEqual (modelParams[part1].symBetaFix, modelParams[part2].symBetaFix, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].symBetaFix, (MrBFlt) -1.0, (MrBFlt) 0.00001) == NO && modelParams[part1].numBetaCats != modelParams[part2].numBetaCats)
+ isSame = NO; /* can't link because the discrete beta approximation is different */
+ }
+ else
+ isSame = NO; /* the priors are not the same, so we cannot set the parameter to be equal for both partitions */
+ }
+ if (modelSettings[part1].dataType == PROTEIN && modelSettings[part2].dataType == PROTEIN)
+ {
+ /* We are dealing with protein data. */
+ if (!strcmp(modelParams[part1].aaModelPr, modelParams[part2].aaModelPr))
+ {
+ if (!strcmp(modelParams[part1].aaModelPr, "Fixed"))
+ {
+ /* only have a single, fixed, amino acid rate matrix */
+ if (!strcmp(modelParams[part1].aaModel, modelParams[part2].aaModel))
+ {}
+ else
+ isSame = NO; /* we have different amino acid models, and the state frequencies must be different */
+ /* if we have an equalin model or Gtr model, then we need to check the prior on the state frequencies */
+ if (!strcmp(modelParams[part1].aaModel, "Equalin") || !strcmp(modelParams[part1].aaModel, "Gtr"))
+ {
+ if (!strcmp(modelParams[part1].stateFreqPr, modelParams[part2].stateFreqPr))
+ {
+ /* the prior form is the same */
+ if (!strcmp(modelParams[part1].stateFreqPr, "Dirichlet")) /* both prior models must be dirichlet */
+ {
+ for (i=0; i<modelParams[part1].nStates; i++)
+ if (AreDoublesEqual (modelParams[part1].stateFreqsDir[i], modelParams[part2].stateFreqsDir[i], (MrBFlt) 0.00001) == NO)
+ isSame = NO; /* the dirichlet parameters are different */
+ }
+ else /* both prior models must be fixed */
+ {
+ if (!strcmp(modelParams[part1].stateFreqsFixType, modelParams[part2].stateFreqsFixType))
+ {
+ /* if (!strcmp(modelParams[part1].stateFreqsFixType, "Empirical"))
+ isSame = NO; Even though it is unlikely that the empirical values for both partitions are exactly the same, we will
+ allow isSame to equal YES. This means pooled base frequencies are used to determine the empirical
+ base frequencies. The user can still unlink this parameter. */
+ if (!strcmp(modelParams[part1].stateFreqsFixType, "User"))
+ {
+ for (i=0; i<modelParams[part1].nStates; i++)
+ if (AreDoublesEqual (modelParams[part1].stateFreqsDir[i], modelParams[part2].stateFreqsDir[i], (MrBFlt) 0.00001) == NO)
+ isSame = NO; /* the user-specified base frequencies are different */
+ }
+ /* if the frequencies were both fixed to "equal", we are golden, and they are the same */
+ }
+ else
+ isSame = NO; /* the fixed parameters must be the same. The only other possibility is that the
+ user specified equal or empirical for one partition and then specified specific
+ numbers (user) for the other _and_ happened to set the user values to the equal
+ or empirical values. We ignore this possibility. */
+ }
+ }
+ }
+ }
+ else
+ {
+ /* averaging over models */
+ if (linkTable[P_AAMODEL][part1] != linkTable[P_AAMODEL][part2])
+ isSame = NO; /* the amino acid model is mixed, but independently estimated */
+ }
+ }
+ }
+ else
+ {
+ /* Otherwise, we are dealing with RESTRICTION or NUCLEOTIDE data. The dirichlet should be the same
+ for both partitions. */
+ if (!strcmp(modelParams[part1].stateFreqPr, modelParams[part2].stateFreqPr))
+ {
+ /* the prior form is the same */
+ if (!strcmp(modelParams[part1].stateFreqPr, "Dirichlet")) /* both prior models must be dirichlet */
+ {
+ for (i=0; i<modelParams[part1].nStates; i++)
+ if (AreDoublesEqual (modelParams[part1].stateFreqsDir[i], modelParams[part2].stateFreqsDir[i], (MrBFlt) 0.00001) == NO)
+ isSame = NO; /* the dirichlet parameters are different */
+ }
+ else /* both prior models must be fixed */
+ {
+ if (!strcmp(modelParams[part1].stateFreqsFixType, modelParams[part2].stateFreqsFixType))
+ {
+ /* if (!strcmp(modelParams[part1].stateFreqsFixType, "Empirical"))
+ isSame = NO; Even though it is unlikely that the empirical values for both partitions are exactly the same, we will
+ allow isSame to equal YES. This means pooled base frequencies are used to determine the empirical
+ base frequencies. The user can still unlink this parameter. */
+ if (!strcmp(modelParams[part1].stateFreqsFixType, "User"))
+ {
+ for (i=0; i<modelParams[part1].nStates; i++)
+ if (AreDoublesEqual (modelParams[part1].stateFreqsDir[i], modelParams[part2].stateFreqsDir[i], (MrBFlt) 0.00001) == NO)
+ isSame = NO; /* the user-specified base frequencies are different */
+ }
+ /* if the frequencies were both fixed to "equal", we are golden, and they are the same */
+ }
+ else
+ isSame = NO; /* the fixed parameters must be the same. The only other possibility is that the
+ user specified equal or empirical for one partition and then specified specific
+ numbers (user) for the other _and_ happened to set the user values to the equal
+ or empirical values. We ignore this possibility. */
+ }
+ }
+ }
+
+ /* Check to see if the state frequencies are inapplicable for either partition. */
+ if ((*isApplic1) == NO || (*isApplic2) == NO)
+ isSame = NO; /* if the state frequencies are inapplicable for either partition, then the parameter cannot be the same */
+ }
+ else if (whichParam == P_SHAPE)
+ {
+ /* Check the shape parameter for partitions 1 and 2. */
+
+ /* Check if the model is parsimony for either partition */
+ if (!strcmp(modelParams[part1].parsModel, "Yes"))
+ *isApplic1 = NO; /* part1 has a parsimony model and shape parameter does not apply */
+ if (!strcmp(modelParams[part2].parsModel, "Yes"))
+ *isApplic2 = NO; /* part2 has a parsimony model and shape parameter does not apply */
+
+ /* Check that the data are not CONTINUOUS for partitions 1 and 2 */
+ if (modelParams[part1].dataType == CONTINUOUS)
+ *isApplic1 = NO; /* the shape parameter does not make sense for part1 */
+ if (modelParams[part2].dataType == CONTINUOUS)
+ *isApplic2 = NO; /* the shape parameter does not make sense for part2 */
+
+ /* Now, check that the data are the same (i.e., both nucleotide or both amino acid, or whatever). */
+ if (isFirstNucleotide != isSecondNucleotide)
+ isSame = NO; /* data are not both nucleotide */
+ else if (modelParams[part1].dataType != modelParams[part2].dataType && isFirstNucleotide == NO)
+ isSame = NO; /* data are not the same */
+
+ /* Let's check that the shape parameter is even relevant for the two partitions */
+ if (!strcmp(modelParams[part1].ratesModel, "Equal") || !strcmp(modelParams[part1].ratesModel, "Propinv"))
+ *isApplic1 = NO; /* the shape parameter does not make sense for part1 */
+ if (!strcmp(modelParams[part2].ratesModel, "Equal") || !strcmp(modelParams[part2].ratesModel, "Propinv"))
+ *isApplic2 = NO; /* the shape parameter does not make sense for part2 */
+
+ /* We may have a nucleotide model. Make certain the models are not of type codon. */
+ if (!strcmp(modelParams[part1].nucModel, "Codon"))
+ *isApplic1 = NO; /* we have a codon model for part1, and a shape parameter does not apply */
+ if (!strcmp(modelParams[part2].nucModel, "Codon"))
+ *isApplic2 = NO;/* we have a codon model for part2, and a shape parameter does not apply */
+
+ /* Check that the model structure is the same for both partitions */
+ if ((!strcmp(modelParams[part1].nucModel, "4by4") || !strcmp(modelParams[part1].nucModel, "Doublet")) && !strcmp(modelParams[part2].nucModel, "Codon"))
+ isSame = NO; /* the nucleotide models are incompatible with the same shape parameter */
+ if ((!strcmp(modelParams[part2].nucModel, "4by4") || !strcmp(modelParams[part2].nucModel, "Doublet")) && !strcmp(modelParams[part1].nucModel, "Codon"))
+ isSame = NO; /* the nucleotide models are incompatible with the same shape parameter */
+ /* if (strcmp(modelParams[part1].covarionModel, modelParams[part2].covarionModel))
+ isSame = NO; */ /* the models have different covarion struture */
+ /* NOTE: Perhaps we should allow the possiblity that the shape parameter is the same for the case
+ where one partition has a covarion model but the other does not and both datatypes are the same. */
+
+ /* Check that the number of rate categories is the same */
+ if (modelParams[part1].numGammaCats != modelParams[part2].numGammaCats)
+ isSame = NO; /* the number of rate categories is not the same, so we cannot set the parameter to be equal for both partitions */
+
+ /* Check that the priors are the same. */
+ if (!strcmp(modelParams[part1].shapePr,"Uniform") && !strcmp(modelParams[part2].shapePr,"Uniform"))
+ {
+ if (AreDoublesEqual (modelParams[part1].shapeUni[0], modelParams[part2].shapeUni[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].shapeUni[1], modelParams[part2].shapeUni[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].shapePr,"Exponential") && !strcmp(modelParams[part2].shapePr,"Exponential"))
+ {
+ if (AreDoublesEqual (modelParams[part1].shapeExp, modelParams[part2].shapeExp, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].shapePr,"Fixed") && !strcmp(modelParams[part2].shapePr,"Fixed"))
+ {
+ if (AreDoublesEqual (modelParams[part1].shapeFix, modelParams[part2].shapeFix, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else
+ isSame = NO; /* the priors are not the same, so we cannot set the parameter to be equal for both partitions */
+
+ /* Check to see if the shape parameter is inapplicable for either partition. */
+ if ((*isApplic1) == NO || (*isApplic2) == NO)
+ isSame = NO; /* if the shape parameter is inapplicable for either partition, then the parameter cannot be the same */
+ }
+ else if (whichParam == P_PINVAR)
+ {
+ /* Check the proportion of invariable sites parameter for partitions 1 and 2. */
+
+ /* Check if the model is parsimony for either partition */
+ if (!strcmp(modelParams[part1].parsModel, "Yes"))
+ *isApplic1 = NO; /* part1 has a parsimony model and proportion of invariable sites parameter does not apply */
+ if (!strcmp(modelParams[part2].parsModel, "Yes"))
+ *isApplic2 = NO; /* part2 has a parsimony model and proportion of invariable sites parameter does not apply */
+
+ /* Check that the data are not CONTINUOUS for partitions 1 and 2 */
+ if (modelParams[part1].dataType == CONTINUOUS)
+ *isApplic1 = NO; /* the proportion of invariable sites parameter does not make sense for part1 */
+ if (modelParams[part2].dataType == CONTINUOUS)
+ *isApplic2 = NO; /* the proportion of invariable sites parameter does not make sense for part2 */
+
+ /* Now, check that the data are the same (i.e., both nucleotide or both amino acid, or whatever). */
+ if (isFirstNucleotide != isSecondNucleotide)
+ isSame = NO; /* data are not both nucleotide */
+ else if (modelParams[part1].dataType != modelParams[part2].dataType && isFirstNucleotide == NO)
+ isSame = NO; /* data are not the same */
+
+ /* Let's check that proportion of invariable sites parameter is even relevant for the two partitions */
+ if (!strcmp(modelParams[part1].ratesModel, "Equal") || !strcmp(modelParams[part1].ratesModel, "Gamma") ||
+ !strcmp(modelParams[part1].ratesModel, "LNorm") || !strcmp(modelParams[part1].ratesModel, "Adgamma"))
+ *isApplic1 = NO; /* the proportion of invariable sites parameter does not make sense for part1 */
+ if (!strcmp(modelParams[part2].ratesModel, "Equal") || !strcmp(modelParams[part2].ratesModel, "Gamma") ||
+ !strcmp(modelParams[part2].ratesModel, "LNorm") || !strcmp(modelParams[part2].ratesModel, "Adgamma"))
+ *isApplic2 = NO; /* the proportion of invariable sites parameter does not make sense for part2 */
+
+ /* It is not sensible to have a covarion model and a proportion of invariable sites */
+ if (!strcmp(modelParams[part1].covarionModel, "Yes"))
+ *isApplic1 = NO;
+ if (!strcmp(modelParams[part2].covarionModel, "Yes"))
+ *isApplic2 = NO;
+
+ /* We have a nucleotide model. Make certain the models are not of type codon. */
+ if (!strcmp(modelParams[part1].nucModel, "Codon"))
+ *isApplic1 = NO; /* we have a codon model for part1, and a proportion of invariable sites parameter does not apply */
+ if (!strcmp(modelParams[part2].nucModel, "Codon"))
+ *isApplic2 = NO;/* we have a codon model for part2, and a proportion of invariable sites parameter does not apply */
+
+ /* Check that the model structure is the same for both partitions */
+ if (strcmp(modelParams[part1].nucModel, modelParams[part2].nucModel))
+ isSame = NO; /* the nucleotide models are different */
+ if (strcmp(modelParams[part1].covarionModel, modelParams[part2].covarionModel))
+ isSame = NO; /* the models have different covarion struture */
+
+ /* check the priors */
+ if (!strcmp(modelParams[part1].pInvarPr,"Uniform") && !strcmp(modelParams[part2].pInvarPr,"Uniform"))
+ {
+ if (AreDoublesEqual (modelParams[part1].pInvarUni[0], modelParams[part2].pInvarUni[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].pInvarUni[1], modelParams[part2].pInvarUni[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].pInvarPr,"Fixed") && !strcmp(modelParams[part2].pInvarPr,"Fixed"))
+ {
+ if (AreDoublesEqual (modelParams[part1].pInvarFix, modelParams[part2].pInvarFix, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else
+ isSame = NO; /* the priors are not the same, so we cannot set the parameter to be equal for both partitions */
+
+ /* Check to see if the switching rates are inapplicable for either partition. */
+ if ((*isApplic1) == NO || (*isApplic2) == NO)
+ isSame = NO; /* if the switching rates are inapplicable for either partition, then the parameter cannot be the same */
+ }
+ else if (whichParam == P_CORREL)
+ {
+ /* Check the autocorrelation parameter for gamma rates on partitions 1 and 2. */
+
+ /* Check if the model is parsimony for either partition */
+ if (!strcmp(modelParams[part1].parsModel, "Yes"))
+ *isApplic1 = NO; /* part1 has a parsimony model and autocorrelation parameter does not apply */
+ if (!strcmp(modelParams[part2].parsModel, "Yes"))
+ *isApplic2 = NO; /* part2 has a parsimony model and autocorrelation parameter does not apply */
+
+ /* Check that the data are either DNA, RNA, or PROTEIN for partitions 1 and 2 */
+ if (modelSettings[part1].dataType != DNA && modelSettings[part1].dataType != RNA && modelSettings[part1].dataType != PROTEIN)
+ *isApplic1 = NO; /* the switching rates do not make sense for part1 */
+ if (modelSettings[part2].dataType != DNA && modelSettings[part2].dataType != RNA && modelSettings[part2].dataType != PROTEIN)
+ *isApplic2 = NO; /* the switching rates do not make sense for part2 */
+
+ /* Now, check that the data are the same (i.e., both nucleotide or both amino acid). */
+ if (isFirstNucleotide != isSecondNucleotide)
+ isSame = NO; /* one or the other is nucleotide, so they cannot be the same */
+ else if (modelSettings[part1].dataType != modelSettings[part2].dataType && isFirstNucleotide == NO)
+ isSame = NO; /* data are not both nucleotide or both amino acid */
+
+ /* Let's check that autocorrelation parameter is even relevant for the two partitions */
+ if (strcmp(modelParams[part1].ratesModel, "Adgamma"))
+ *isApplic1 = NO; /* the autocorrelation parameter does not make sense for part1 */
+ if (strcmp(modelParams[part2].ratesModel, "Adgamma"))
+ *isApplic2 = NO; /* the autocorrelation parameter does not make sense for part2 */
+
+ /* Assuming that we have a nucleotide model, make certain the models are not of type codon. */
+ if (!strcmp(modelParams[part1].nucModel, "Codon"))
+ *isApplic1 = NO; /* we have a codon model for part1, and a autocorrelation parameter does not apply */
+ if (!strcmp(modelParams[part2].nucModel, "Codon"))
+ *isApplic2 = NO; /* we have a codon model for part2, and a autocorrelation parameter does not apply */
+
+ /* Check that the model structure is the same for both partitions */
+ if (strcmp(modelParams[part1].nucModel, modelParams[part2].nucModel))
+ isSame = NO; /* the nucleotide models are different */
+ if (strcmp(modelParams[part1].covarionModel, modelParams[part2].covarionModel))
+ isSame = NO; /* the models have different covarion struture */
+
+ /* Check the priors for both partitions. */
+ if (!strcmp(modelParams[part1].adGammaCorPr,"Uniform") && !strcmp(modelParams[part2].adGammaCorPr,"Uniform"))
+ {
+ if (AreDoublesEqual (modelParams[part1].corrUni[0], modelParams[part2].corrUni[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].corrUni[1], modelParams[part2].corrUni[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].adGammaCorPr,"Fixed") && !strcmp(modelParams[part2].adGammaCorPr,"Fixed"))
+ {
+ if (AreDoublesEqual (modelParams[part1].corrFix, modelParams[part2].corrFix, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else
+ isSame = NO; /* the priors are not the same, so we cannot set the parameter to be equal for both partitions */
+
+ /* Check to see if the switching rates are inapplicable for either partition. */
+ if ((*isApplic1) == NO || (*isApplic2) == NO)
+ isSame = NO; /* if the switching rates are inapplicable for either partition, then the parameter cannot be the same */
+ }
+ else if (whichParam == P_SWITCH)
+ {
+ /* Check the covarion switching rates on partitions 1 and 2. */
+
+ /* Check if the model is parsimony for either partition */
+ if (!strcmp(modelParams[part1].parsModel, "Yes"))
+ *isApplic1 = NO; /* part1 has a parsimony model and switching rates do not apply */
+ if (!strcmp(modelParams[part2].parsModel, "Yes"))
+ *isApplic2 = NO; /* part2 has a parsimony model and switching rates do not apply */
+
+ /* Check that the data are either DNA, RNA, or PROTEIN for partitions 1 and 2 */
+ if (modelSettings[part1].dataType != DNA && modelSettings[part1].dataType != RNA && modelSettings[part1].dataType != PROTEIN)
+ *isApplic1 = NO; /* the switching rates do not make sense for part1 */
+ if (modelSettings[part2].dataType != DNA && modelSettings[part2].dataType != RNA && modelSettings[part2].dataType != PROTEIN)
+ *isApplic2 = NO; /* the switching rates do not make sense for part2 */
+
+ /* Now, check that the data are the same (i.e., both nucleotide or both amino acid). */
+ if (isFirstNucleotide != isSecondNucleotide)
+ isSame = NO; /* one or the other is nucleotide, so they cannot be the same */
+ else if (modelSettings[part1].dataType != modelSettings[part2].dataType && isFirstNucleotide == NO)
+ isSame = NO; /* data are not both nucleotide or both amino acid */
+
+ /* Lets check that covarion model has been selected for partitions 1 and 2 */
+ if (!strcmp(modelParams[part1].covarionModel, "No"))
+ *isApplic1 = NO; /* the switching rates do not make sense for part1 */
+ if (!strcmp(modelParams[part2].covarionModel, "No"))
+ *isApplic2 = NO; /* the switching rates do not make sense for part2 */
+
+ /* If we have a nucleotide model make certain the models are not of type codon or doublet. */
+ if (!strcmp(modelParams[part1].nucModel, "Codon") || !strcmp(modelParams[part1].nucModel, "Doublet"))
+ *isApplic1 = NO; /* we have a codon model for part1, and a covarion switch parameter does not apply */
+ if (!strcmp(modelParams[part2].nucModel, "Codon") || !strcmp(modelParams[part2].nucModel, "Doublet"))
+ *isApplic2 = NO; /* we have a codon model for part2, and a covarion switch parameter does not apply */
+
+ /* Check that the priors are the same. */
+ if (!strcmp(modelParams[part1].covSwitchPr,"Uniform") && !strcmp(modelParams[part2].covSwitchPr,"Uniform"))
+ {
+ if (AreDoublesEqual (modelParams[part1].covswitchUni[0], modelParams[part2].covswitchUni[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].covswitchUni[1], modelParams[part2].covswitchUni[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].covSwitchPr,"Exponential") && !strcmp(modelParams[part2].covSwitchPr,"Exponential"))
+ {
+ if (AreDoublesEqual (modelParams[part1].covswitchExp, modelParams[part2].covswitchExp, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].covSwitchPr,"Fixed") && !strcmp(modelParams[part2].covSwitchPr,"Fixed"))
+ {
+ if (AreDoublesEqual (modelParams[part1].covswitchFix[0], modelParams[part2].covswitchFix[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].covswitchFix[1], modelParams[part2].covswitchFix[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else
+ isSame = NO; /* the priors are not the same, so we cannot set the parameter to be equal for both partitions */
+
+ /* Check to see if the switching rates are inapplicable for either partition. */
+ if ((*isApplic1) == NO || (*isApplic2) == NO)
+ isSame = NO; /* if the switching rates are inapplicable for either partition, then the parameter cannot be the same */
+ }
+ else if (whichParam == P_RATEMULT)
+ {
+ /* Check if the model is parsimony for either partition. If so, then the branch lengths cannot apply (as parsimony is very
+ silly and doesn't take this information into account) and a rate multiplier is nonsensical. */
+ if (!strcmp(modelParams[part1].parsModel, "Yes"))
+ *isApplic1 = NO;
+ if (!strcmp(modelParams[part2].parsModel, "Yes"))
+ *isApplic2 = NO;
+
+ /* Check that the branch lengths are at least proportional. */
+ if (IsModelSame (P_BRLENS, part1, part2, &temp1, &temp2) == NO)
+ isSame = NO;
+ if (linkTable[P_BRLENS][part1] != linkTable[P_BRLENS][part2])
+ isSame = NO;
+
+ /* See if the rate prior is the same for the partitions */
+ if (strcmp(modelParams[part1].ratePr, modelParams[part2].ratePr) != 0)
+ isSame = NO;
+
+ /* Check to see if rate multipliers are inapplicable for either partition. */
+ if ((*isApplic1) == NO || (*isApplic2) == NO)
+ isSame = NO;
+
+ }
+ else if (whichParam == P_TOPOLOGY)
+ {
+ /* Check the topology for partitions 1 and 2. */
+
+ /* If the prior is different, then the topologies cannot be the same. */
+ if (strcmp(modelParams[part1].topologyPr, modelParams[part2].topologyPr))
+ isSame = NO;
+
+ /* If both partitions have topologies constrained, then we need to make certain that the constraints are the same. */
+ /* This also guarantees that any calibrations will be the same. */
+ if (!strcmp(modelParams[part1].topologyPr, "Constraints") && !strcmp(modelParams[part2].topologyPr, "Constraints"))
+ {
+ if (modelParams[part1].numActiveConstraints != modelParams[part2].numActiveConstraints)
+ isSame = NO;
+ else
+ {
+ nDiff = 0;
+ for (i=0; i<numDefinedConstraints; i++)
+ if (modelParams[part1].activeConstraints[i] != modelParams[part2].activeConstraints[i])
+ nDiff++;
+ if (nDiff != 0)
+ isSame = NO;
+ }
+ }
+ }
+ else if (whichParam == P_BRLENS)
+ {
+ /* Check the branch lengths for partitions 1 and 2. */
+
+ /* First, if the topologies are different, the same branch lengths cannot apply. */
+ if (IsModelSame (P_TOPOLOGY, part1, part2, &temp1, &temp2) == NO)
+ isSame = NO;
+ if (linkTable[P_TOPOLOGY][part1] != linkTable[P_TOPOLOGY][part2])
+ isSame = NO;
+
+ /* Check if the model is parsimony for either partition. If so, then the branch lengths cannot apply (as parsimony is very
+ silly and doesn't take this information into account). */
+ if (!strcmp(modelParams[part1].parsModel, "Yes"))
+ *isApplic1 = NO;
+ if (!strcmp(modelParams[part2].parsModel, "Yes"))
+ *isApplic2 = NO;
+
+ /* Check to see if the branch lengths are inapplicable for either partition. */
+ if ((*isApplic1) == NO || (*isApplic2) == NO)
+ isSame = NO;
+
+ /* Make sure the branch lengths have the same priors and are not unlinked */
+ if (*isApplic1 == YES && *isApplic2 == YES)
+ {
+ /* We are dealing with real branch lengths (not parsimony) for both partitions */
+
+ /* The branch length prior should be the same */
+ if (strcmp(modelParams[part1].brlensPr, modelParams[part2].brlensPr))
+ isSame = NO;
+
+ /* if both partitions have unconstrained brlens, then we need to check that the priors on the branch lengths are the same */
+ if (!strcmp(modelParams[part1].brlensPr, "Unconstrained") && !strcmp(modelParams[part2].brlensPr, "Unconstrained"))
+ {
+ if (strcmp(modelParams[part1].unconstrainedPr, modelParams[part2].unconstrainedPr))
+ isSame = NO;
+ else
+ {
+ if (!strcmp(modelParams[part1].unconstrainedPr, "Uniform"))
+ {
+ if (AreDoublesEqual (modelParams[part1].brlensUni[0], modelParams[part2].brlensUni[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].brlensUni[1], modelParams[part2].brlensUni[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].unconstrainedPr, "Exponential"))
+ {
+ if (AreDoublesEqual (modelParams[part1].brlensExp, modelParams[part2].brlensExp, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].unconstrainedPr, "twoExp"))
+ {
+ if (AreDoublesEqual (modelParams[part1].brlens2Exp[0], modelParams[part2].brlens2Exp[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].brlens2Exp[1], modelParams[part2].brlens2Exp[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else
+ {
+ if (AreDoublesEqual (modelParams[part1].brlensDir[0], modelParams[part2].brlensDir[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].brlensDir[1], modelParams[part2].brlensDir[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].brlensDir[2], modelParams[part2].brlensDir[2], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].brlensDir[3], modelParams[part2].brlensDir[3], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ }
+ }
+
+ /* if both partitions have clock brlens, then we need to check that the priors on the clock are the same */
+ if (!strcmp(modelParams[part1].brlensPr, "Clock") && !strcmp(modelParams[part2].brlensPr, "Clock"))
+ {
+ if (strcmp(modelParams[part1].clockPr, modelParams[part2].clockPr))
+ isSame = NO;
+ else
+ {
+ if (!strcmp(modelParams[part1].clockPr, "Birthdeath"))
+ {
+ if (!strcmp(modelParams[part1].speciationPr,"Uniform") && !strcmp(modelParams[part2].speciationPr,"Uniform"))
+ {
+ if (AreDoublesEqual (modelParams[part1].speciationUni[0], modelParams[part2].speciationUni[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].speciationUni[1], modelParams[part2].speciationUni[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].speciationPr,"Exponential") && !strcmp(modelParams[part2].speciationPr,"Exponential"))
+ {
+ if (AreDoublesEqual (modelParams[part1].speciationExp, modelParams[part2].speciationExp, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].speciationPr,"Fixed") && !strcmp(modelParams[part2].speciationPr,"Fixed"))
+ {
+ if (AreDoublesEqual (modelParams[part1].speciationFix, modelParams[part2].speciationFix, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else
+ isSame = NO;
+
+ if (!strcmp(modelParams[part1].extinctionPr,"Beta") && !strcmp(modelParams[part2].extinctionPr,"Beta"))
+ {
+ if (AreDoublesEqual (modelParams[part1].extinctionBeta[0], modelParams[part2].extinctionBeta[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].extinctionBeta[1], modelParams[part2].extinctionBeta[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].extinctionPr,"Fixed") && !strcmp(modelParams[part2].extinctionPr,"Fixed"))
+ {
+ if (AreDoublesEqual (modelParams[part1].extinctionFix, modelParams[part2].extinctionFix, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else
+ isSame = NO;
+
+ if (AreDoublesEqual (modelParams[part1].sampleProb, modelParams[part2].sampleProb, 0.00001) == NO)
+ isSame = NO;
+ if (strcmp(modelParams[part1].sampleStrat,modelParams[part2].sampleStrat))
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].clockPr, "Coalescence") || !strcmp(modelParams[part1].clockPr, "Speciestreecoalescence"))
+ {
+ if (!strcmp(modelParams[part1].popSizePr,"Uniform") && !strcmp(modelParams[part2].popSizePr,"Uniform"))
+ {
+ if (AreDoublesEqual (modelParams[part1].popSizeUni[0], modelParams[part2].popSizeUni[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].popSizeUni[1], modelParams[part2].popSizeUni[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].popSizePr,"Lognormal") && !strcmp(modelParams[part2].popSizePr,"Lognormal"))
+ {
+ if (AreDoublesEqual (modelParams[part1].popSizeLognormal[0], modelParams[part2].popSizeLognormal[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].popSizeLognormal[1], modelParams[part2].popSizeLognormal[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].popSizePr,"Normal") && !strcmp(modelParams[part2].popSizePr,"Normal"))
+ {
+ if (AreDoublesEqual (modelParams[part1].popSizeNormal[0], modelParams[part2].popSizeNormal[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].popSizeNormal[1], modelParams[part2].popSizeNormal[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].popSizePr,"Gamma") && !strcmp(modelParams[part2].popSizePr,"Gamma"))
+ {
+ if (AreDoublesEqual (modelParams[part1].popSizeGamma[0], modelParams[part2].popSizeGamma[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].popSizeGamma[1], modelParams[part2].popSizeGamma[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].popSizePr,"Fixed") && !strcmp(modelParams[part2].popSizePr,"Fixed"))
+ {
+ if (AreDoublesEqual (modelParams[part1].popSizeFix, modelParams[part2].popSizeFix, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else
+ isSame = NO;
+
+ if (strcmp(modelParams[part1].ploidy, modelParams[part2].ploidy) != 0)
+ isSame = NO;
+ }
+ if (strcmp(modelParams[part1].clockPr, "Uniform") == 0 && strcmp(modelParams[part1].nodeAgePr, "Calibrated") != 0)
+ {
+ if (modelParams[part1].treeAgePr.prior != modelParams[part2].treeAgePr.prior)
+ isSame = NO;
+ if (modelParams[part1].treeAgePr.prior == fixed)
+ {
+ if (AreDoublesEqual (modelParams[part1].treeAgePr.priorParams[0], modelParams[part2].treeAgePr.priorParams[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (modelParams[part1].treeAgePr.prior == offsetLogNormal ||
+ modelParams[part1].treeAgePr.prior == truncatedNormal ||
+ modelParams[part1].treeAgePr.prior == offsetGamma)
+ {
+ for (i=0; i<3; i++)
+ {
+ if (AreDoublesEqual (modelParams[part1].treeAgePr.priorParams[i], modelParams[part2].treeAgePr.priorParams[i], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ }
+ else
+ {
+ for (i=0; i<2; i++)
+ {
+ if (AreDoublesEqual (modelParams[part1].treeAgePr.priorParams[i], modelParams[part2].treeAgePr.priorParams[i], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ }
+ }
+ else if (strcmp(modelParams[part1].clockPr, "Fossilization") == 0)
+ {
+ if (modelParams[part1].treeAgePr.prior != modelParams[part2].treeAgePr.prior)
+ isSame = NO;
+ if (modelParams[part1].treeAgePr.prior == fixed)
+ {
+ if (AreDoublesEqual (modelParams[part1].treeAgePr.priorParams[0], modelParams[part2].treeAgePr.priorParams[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (modelParams[part1].treeAgePr.prior == offsetLogNormal ||
+ modelParams[part1].treeAgePr.prior == truncatedNormal ||
+ modelParams[part1].treeAgePr.prior == offsetGamma)
+ {
+ for (i=0; i<3; i++)
+ {
+ if (AreDoublesEqual (modelParams[part1].treeAgePr.priorParams[i], modelParams[part2].treeAgePr.priorParams[i], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ }
+ else
+ {
+ for (i=0; i<2; i++)
+ {
+ if (AreDoublesEqual (modelParams[part1].treeAgePr.priorParams[i], modelParams[part2].treeAgePr.priorParams[i], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ }
+
+ if (!strcmp(modelParams[part1].speciationPr,"Uniform") && !strcmp(modelParams[part2].speciationPr,"Uniform"))
+ {
+ if (AreDoublesEqual (modelParams[part1].speciationUni[0], modelParams[part2].speciationUni[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].speciationUni[1], modelParams[part2].speciationUni[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].speciationPr,"Exponential") && !strcmp(modelParams[part2].speciationPr,"Exponential"))
+ {
+ if (AreDoublesEqual (modelParams[part1].speciationExp, modelParams[part2].speciationExp, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].speciationPr,"Fixed") && !strcmp(modelParams[part2].speciationPr,"Fixed"))
+ {
+ if (AreDoublesEqual (modelParams[part1].speciationFix, modelParams[part2].speciationFix, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else
+ isSame = NO;
+
+ if (!strcmp(modelParams[part1].extinctionPr,"Beta") && !strcmp(modelParams[part2].extinctionPr,"Beta"))
+ {
+ if (AreDoublesEqual (modelParams[part1].extinctionBeta[0], modelParams[part2].extinctionBeta[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].extinctionBeta[1], modelParams[part2].extinctionBeta[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].extinctionPr,"Fixed") && !strcmp(modelParams[part2].extinctionPr,"Fixed"))
+ {
+ if (AreDoublesEqual (modelParams[part1].extinctionFix, modelParams[part2].extinctionFix, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else
+ isSame = NO;
+
+ if (!strcmp(modelParams[part1].fossilizationPr,"Beta") && !strcmp(modelParams[part2].fossilizationPr,"Beta"))
+ {
+ if (AreDoublesEqual (modelParams[part1].fossilizationBeta[0], modelParams[part2].fossilizationBeta[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].fossilizationBeta[1], modelParams[part2].fossilizationBeta[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].fossilizationPr,"Fixed") && !strcmp(modelParams[part2].fossilizationPr,"Fixed"))
+ {
+ if (AreDoublesEqual (modelParams[part1].fossilizationFix, modelParams[part2].fossilizationFix, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else
+ isSame = NO;
+
+ if (AreDoublesEqual (modelParams[part1].sampleProb, modelParams[part2].sampleProb, 0.00001) == NO)
+ isSame = NO;
+ if (strcmp(modelParams[part1].sampleStrat,modelParams[part2].sampleStrat))
+ isSame = NO;
+ }
+ }
+
+ /* if the same clock prior, we need to check calibrations */
+ if (strcmp(modelParams[part1].nodeAgePr,modelParams[part2].nodeAgePr) != 0)
+ isSame = NO;
+
+ /* If fixed clock brlens, check if the brlens come from the same tree */
+ if (!strcmp(modelParams[part1].clockPr, "Fixed") && !strcmp(modelParams[part2].clockPr, "Fixed"))
+ {
+ if (modelParams[part1].brlensFix != modelParams[part2].brlensFix)
+ isSame = NO;
+ }
+ }
+ /* If fixed brlens, check if the brlens come from the same tree */
+ if (!strcmp(modelParams[part1].brlensPr, "Fixed") && !strcmp(modelParams[part2].brlensPr, "Fixed"))
+ {
+ if (modelParams[part1].brlensFix != modelParams[part2].brlensFix)
+ isSame = NO;
+ }
+ }
+ }
+ else if (whichParam == P_SPECRATE)
+ {
+ /* Check the speciation rates for partitions 1 and 2. */
+
+ /* Check if the model is parsimony for either partition. If so, then the branch lengths cannot apply (as parsimony is very
+ silly and doesn't take this information into account) and a speciation rate cannot be estimated. */
+ if (!strcmp(modelParams[part1].parsModel, "Yes"))
+ *isApplic1 = NO;
+ if (!strcmp(modelParams[part2].parsModel, "Yes"))
+ *isApplic2 = NO;
+
+ /* Check that the branch length prior is a clock:birthdeath or clock:fossilization for both partitions. */
+ if (strcmp(modelParams[part1].brlensPr, "Clock"))
+ *isApplic1 = NO;
+ if (strcmp(modelParams[part2].brlensPr, "Clock"))
+ *isApplic2 = NO;
+ if (strcmp(modelParams[part1].clockPr, "Birthdeath") != 0 && strcmp(modelParams[part1].clockPr, "Fossilization") != 0)
+ *isApplic1 = NO;
+ if (strcmp(modelParams[part2].clockPr, "Birthdeath") != 0 && strcmp(modelParams[part2].clockPr, "Fossilization") != 0)
+ *isApplic2 = NO;
+
+ /* Now, check that the prior on the speciation rates are the same. */
+ if (!strcmp(modelParams[part1].speciationPr,"Uniform") && !strcmp(modelParams[part2].speciationPr,"Uniform"))
+ {
+ if (AreDoublesEqual (modelParams[part1].speciationUni[0], modelParams[part2].speciationUni[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].speciationUni[1], modelParams[part2].speciationUni[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].speciationPr,"Exponential") && !strcmp(modelParams[part2].speciationPr,"Exponential"))
+ {
+ if (AreDoublesEqual (modelParams[part1].speciationExp, modelParams[part2].speciationExp, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].speciationPr,"Fixed") && !strcmp(modelParams[part2].speciationPr,"Fixed"))
+ {
+ if (AreDoublesEqual (modelParams[part1].speciationFix, modelParams[part2].speciationFix, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else
+ isSame = NO;
+
+ /* Check to see if the speciation rates are inapplicable for either partition. */
+ if ((*isApplic1) == NO || (*isApplic2) == NO)
+ isSame = NO;
+ }
+ else if (whichParam == P_EXTRATE)
+ {
+ /* Check the extinction rates for partitions 1 and 2. */
+
+ /* Check if the model is parsimony for either partition. If so, then the branch lengths cannot apply (as parsimony is very
+ silly and doesn't take this information into account) and a extinction rate cannot be estimated. */
+ if (!strcmp(modelParams[part1].parsModel, "Yes"))
+ *isApplic1 = NO;
+ if (!strcmp(modelParams[part2].parsModel, "Yes"))
+ *isApplic2 = NO;
+
+ /* Check that the branch length prior is a clock:birthdeath or clock:fossilization for both partitions. */
+ if (strcmp(modelParams[part1].brlensPr, "Clock"))
+ *isApplic1 = NO;
+ if (strcmp(modelParams[part2].brlensPr, "Clock"))
+ *isApplic2 = NO;
+ if (strcmp(modelParams[part1].clockPr, "Birthdeath")!= 0 && strcmp(modelParams[part1].clockPr, "Fossilization") != 0)
+ *isApplic1 = NO;
+ if (strcmp(modelParams[part2].clockPr, "Birthdeath")!= 0 && strcmp(modelParams[part2].clockPr, "Fossilization") != 0)
+ *isApplic2 = NO;
+
+ /* Now, check that the prior on the extinction rates are the same. */
+ if (!strcmp(modelParams[part1].extinctionPr,"Beta") && !strcmp(modelParams[part2].extinctionPr,"Beta"))
+ {
+ if (AreDoublesEqual (modelParams[part1].extinctionBeta[0], modelParams[part2].extinctionBeta[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].extinctionBeta[1], modelParams[part2].extinctionBeta[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].extinctionPr,"Fixed") && !strcmp(modelParams[part2].extinctionPr,"Fixed"))
+ {
+ if (AreDoublesEqual (modelParams[part1].extinctionFix, modelParams[part2].extinctionFix, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else
+ isSame = NO;
+
+ /* Check to see if the extinction rates are inapplicable for either partition. */
+ if ((*isApplic1) == NO || (*isApplic2) == NO)
+ isSame = NO;
+ }
+ else if (whichParam == P_FOSLRATE)
+ {
+ /* Check the fossilization rates for partitions 1 and 2. */
+
+ /* Check if the model is parsimony for either partition. */
+ if (!strcmp(modelParams[part1].parsModel, "Yes"))
+ *isApplic1 = NO;
+ if (!strcmp(modelParams[part2].parsModel, "Yes"))
+ *isApplic2 = NO;
+
+ /* Check that the branch length prior is a clock:birthdeath or clock:fossilization for both partitions. */
+ if (strcmp(modelParams[part1].brlensPr, "Clock"))
+ *isApplic1 = NO;
+ if (strcmp(modelParams[part2].brlensPr, "Clock"))
+ *isApplic2 = NO;
+ if (strcmp(modelParams[part1].clockPr, "Fossilization") != 0)
+ *isApplic1 = NO;
+ if (strcmp(modelParams[part2].clockPr, "Fossilization") != 0)
+ *isApplic2 = NO;
+
+ /* Now, check that the prior on the fossilization rates are the same. */
+ if (!strcmp(modelParams[part1].fossilizationPr,"Beta") && !strcmp(modelParams[part2].fossilizationPr,"Beta"))
+ {
+ if (AreDoublesEqual (modelParams[part1].fossilizationBeta[0], modelParams[part2].fossilizationBeta[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].fossilizationBeta[1], modelParams[part2].fossilizationBeta[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].fossilizationPr,"Fixed") && !strcmp(modelParams[part2].fossilizationPr,"Fixed"))
+ {
+ if (AreDoublesEqual (modelParams[part1].fossilizationFix, modelParams[part2].fossilizationFix, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else
+ isSame = NO;
+
+ /* Check to see if the fossilization rates are inapplicable for either partition. */
+ if ((*isApplic1) == NO || (*isApplic2) == NO)
+ isSame = NO;
+ }
+ else if (whichParam == P_POPSIZE)
+ {
+ /* Check population size for partitions 1 and 2. */
+
+ /* Check if the model is parsimony for either partition. If so, then the branch lengths cannot apply (as parsimony is very
+ silly and doesn't take this information into account) and population size cannot be estimated. */
+ if (!strcmp(modelParams[part1].parsModel, "Yes"))
+ *isApplic1 = NO;
+ if (!strcmp(modelParams[part2].parsModel, "Yes"))
+ *isApplic2 = NO;
+
+ /* Check that the branch length prior is a clock:coalescence or clock:speciestreecoalescence for both partitions. */
+ if (strcmp(modelParams[part1].brlensPr, "Clock"))
+ *isApplic1 = NO;
+ if (strcmp(modelParams[part2].brlensPr, "Clock"))
+ *isApplic2 = NO;
+ if (strcmp(modelParams[part1].clockPr, "Coalescence") != 0 && strcmp(modelParams[part1].clockPr, "Speciestreecoalescence") != 0)
+ *isApplic1 = NO;
+ if (strcmp(modelParams[part2].clockPr, "Coalescence") != 0 && strcmp(modelParams[part2].clockPr, "Speciestreecoalescence") != 0)
+ *isApplic2 = NO;
+
+ /* Now, check that the prior on population size is the same. */
+ if (!strcmp(modelParams[part1].popSizePr,"Uniform") && !strcmp(modelParams[part2].popSizePr,"Uniform"))
+ {
+ if (AreDoublesEqual (modelParams[part1].popSizeUni[0], modelParams[part2].popSizeUni[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].popSizeUni[1], modelParams[part2].popSizeUni[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].popSizePr,"Lognormal") && !strcmp(modelParams[part2].popSizePr,"Lognormal"))
+ {
+ if (AreDoublesEqual (modelParams[part1].popSizeLognormal[0], modelParams[part2].popSizeLognormal[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].popSizeLognormal[1], modelParams[part2].popSizeLognormal[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].popSizePr,"Normal") && !strcmp(modelParams[part2].popSizePr,"Normal"))
+ {
+ if (AreDoublesEqual (modelParams[part1].popSizeNormal[0], modelParams[part2].popSizeNormal[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].popSizeNormal[1], modelParams[part2].popSizeNormal[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].popSizePr,"Gamma") && !strcmp(modelParams[part2].popSizePr,"Gamma"))
+ {
+ if (AreDoublesEqual (modelParams[part1].popSizeGamma[0], modelParams[part2].popSizeGamma[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].popSizeGamma[1], modelParams[part2].popSizeGamma[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].popSizePr,"Fixed") && !strcmp(modelParams[part2].popSizePr,"Fixed"))
+ {
+ if (AreDoublesEqual (modelParams[part1].popSizeFix, modelParams[part2].popSizeFix, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else
+ isSame = NO;
+
+ /* Check to see if population size is inapplicable for either partition. */
+ if ((*isApplic1) == NO || (*isApplic2) == NO)
+ isSame = NO;
+ }
+ else if (whichParam == P_GROWTH)
+ {
+ /* Check growth rate for partitions 1 and 2. */
+
+ /* Check if the model is parsimony for either partition. If so, then the branch lengths cannot apply (as parsimony is very
+ silly and doesn't take this information into account) and growth rate cannot be estimated. */
+ if (!strcmp(modelParams[part1].parsModel, "Yes"))
+ *isApplic1 = NO;
+ if (!strcmp(modelParams[part2].parsModel, "Yes"))
+ *isApplic2 = NO;
+
+ /* Check that the branch length prior is a clock:coalescence for both partitions. */
+ if (strcmp(modelParams[part1].brlensPr, "Clock"))
+ *isApplic1 = NO;
+ if (strcmp(modelParams[part2].brlensPr, "Clock"))
+ *isApplic2 = NO;
+ if (strcmp(modelParams[part1].clockPr, "Coalescence"))
+ *isApplic1 = NO;
+ if (strcmp(modelParams[part2].clockPr, "Coalescence"))
+ *isApplic2 = NO;
+
+ /* Now, check that the prior on growth rate is the same. */
+ if (!strcmp(modelParams[part1].growthPr,"Uniform") && !strcmp(modelParams[part2].growthPr,"Uniform"))
+ {
+ if (AreDoublesEqual (modelParams[part1].growthUni[0], modelParams[part2].growthUni[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].growthUni[1], modelParams[part2].growthUni[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].growthPr,"Exponential") && !strcmp(modelParams[part2].growthPr,"Exponential"))
+ {
+ if (AreDoublesEqual (modelParams[part1].growthExp, modelParams[part2].growthExp, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].growthPr,"Fixed") && !strcmp(modelParams[part2].growthPr,"Fixed"))
+ {
+ if (AreDoublesEqual (modelParams[part1].growthFix, modelParams[part2].growthFix, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else
+ isSame = NO;
+
+ /* Check to see if growth rate is inapplicable for either partition. */
+ if ((*isApplic1) == NO || (*isApplic2) == NO)
+ isSame = NO;
+ }
+ else if (whichParam == P_AAMODEL)
+ {
+ /* Check the amino acid model settings for partitions 1 and 2. */
+
+ /* Check if the model is parsimony for either partition */
+ if (!strcmp(modelParams[part1].parsModel, "Yes"))
+ *isApplic1 = NO; /* part1 has a parsimony model and aamodel does not apply */
+ if (!strcmp(modelParams[part2].parsModel, "Yes"))
+ *isApplic2 = NO; /* part2 has a parsimony model and aamodel does not apply */
+
+ /* Check that the data are protein for both partitions 1 and 2 */
+ if (isFirstProtein == NO)
+ *isApplic1 = NO; /* part1 is not amino acid data so tratio does not apply */
+ if (isSecondProtein == NO)
+ *isApplic2 = NO; /* part2 is not amino acid data so tratio does not apply */
+
+ /* If the model is fixed for a partition, then it is not a free parameter and
+ we set it to isApplic = NO */
+ if (!strcmp(modelParams[part1].aaModelPr,"Fixed"))
+ *isApplic1 = NO;
+ if (!strcmp(modelParams[part2].aaModelPr,"Fixed"))
+ *isApplic2 = NO;
+
+ /* We now need to check if the prior is the same for both. */
+ if (!strcmp(modelParams[part1].aaModelPr,"Mixed") && !strcmp(modelParams[part2].aaModelPr,"Mixed"))
+ {
+ }
+ else if (!strcmp(modelParams[part1].aaModelPr,"Fixed") && !strcmp(modelParams[part2].aaModelPr,"Fixed"))
+ {
+ if (strcmp(modelParams[part1].aaModel,modelParams[part2].aaModel))
+ isSame = NO;
+ }
+ else
+ isSame = NO; /* the priors are not the same, so we cannot set the parameter to be equal for both partitions */
+
+ /* Check to see if amino acid model is inapplicable for either partition. */
+ if ((*isApplic1) == NO || (*isApplic2) == NO)
+ isSame = NO; /* if tratio is inapplicable for either partition, then the parameter cannot be the same */
+ }
+ else if (whichParam == P_BRCORR)
+ {
+ /* Check the correlation parameter for brownian motion 1 and 2. */
+
+ /* Check that the data are either CONTINUOUS for partitions 1 and 2 */
+ if (modelParams[part1].dataType != CONTINUOUS)
+ *isApplic1 = NO; /* the correlation parameter does not make sense for part1 */
+ if (modelParams[part2].dataType != CONTINUOUS)
+ *isApplic2 = NO; /* the correlation parameter does not make sense for part2 */
+
+ /* Now, check that the data are the same. */
+ if (modelParams[part1].dataType != modelParams[part2].dataType)
+ isSame = NO; /* data are not both continuous */
+
+ /* Check the priors for both partitions. */
+ if (!strcmp(modelParams[part1].brownCorPr,"Uniform") && !strcmp(modelParams[part2].brownCorPr,"Uniform"))
+ {
+ if (AreDoublesEqual (modelParams[part1].brownCorrUni[0], modelParams[part2].brownCorrUni[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].brownCorrUni[1], modelParams[part2].brownCorrUni[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].brownCorPr,"Fixed") && !strcmp(modelParams[part2].brownCorPr,"Fixed"))
+ {
+ if (AreDoublesEqual (modelParams[part1].brownCorrFix, modelParams[part2].brownCorrFix, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else
+ isSame = NO; /* the priors are not the same, so we cannot set the parameter to be equal for both partitions */
+
+ /* Check to see if the correlation parameters are inapplicable for either partition. */
+ if ((*isApplic1) == NO || (*isApplic2) == NO)
+ isSame = NO; /* if the correlation parameters are inapplicable for either partition, then the parameter cannot be the same */
+ }
+ else if (whichParam == P_BRSIGMA)
+ {
+ /* Check the sigma parameter for brownian motion 1 and 2. */
+
+ /* Check that the data are either CONTINUOUS for partitions 1 and 2 */
+ if (modelParams[part1].dataType != CONTINUOUS)
+ *isApplic1 = NO; /* the sigma parameter does not make sense for part1 */
+ if (modelParams[part2].dataType != CONTINUOUS)
+ *isApplic2 = NO; /* the sigma parameter does not make sense for part2 */
+
+ /* Now, check that the data are the same. */
+ if (modelParams[part1].dataType != modelParams[part2].dataType)
+ isSame = NO; /* data are not both continuous */
+
+ /* Check the priors for both partitions. */
+ if (!strcmp(modelParams[part1].brownScalesPr,"Uniform") && !strcmp(modelParams[part2].brownScalesPr,"Uniform"))
+ {
+ if (AreDoublesEqual (modelParams[part1].brownScalesUni[0], modelParams[part2].brownScalesUni[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].brownScalesUni[1], modelParams[part2].brownScalesUni[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].brownScalesPr,"Fixed") && !strcmp(modelParams[part2].brownScalesPr,"Fixed"))
+ {
+ if (AreDoublesEqual (modelParams[part1].brownScalesFix, modelParams[part2].brownScalesFix, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].brownScalesPr,"Gamma") && !strcmp(modelParams[part2].brownScalesPr,"Gamma"))
+ {
+ if (AreDoublesEqual (modelParams[part1].brownScalesGamma[0], modelParams[part2].brownScalesGamma[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].brownScalesGamma[1], modelParams[part2].brownScalesGamma[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].brownScalesPr,"Gammamean") && !strcmp(modelParams[part2].brownScalesPr,"Gammamean"))
+ {
+ if (AreDoublesEqual (modelParams[part1].brownScalesGammaMean, modelParams[part2].brownScalesGammaMean, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else
+ isSame = NO; /* the priors are not the same, so we cannot set the parameter to be equal for both partitions */
+
+ /* Check to see if the sigma parameters are inapplicable for either partition. */
+ if ((*isApplic1) == NO || (*isApplic2) == NO)
+ isSame = NO; /* if the sigma parameters are inapplicable for either partition, then the parameter cannot be the same */
+ }
+ else if (whichParam == P_CPPRATE)
+ {
+ /* Check cpp rate for partitions 1 and 2. */
+
+ /* Check if the model is parsimony for either partition. If so, then the branch lengths cannot apply (as parsimony is very
+ silly and doesn't take this information into account) and cpp rate cannot be estimated. */
+ if (!strcmp(modelParams[part1].parsModel, "Yes"))
+ *isApplic1 = NO;
+ if (!strcmp(modelParams[part2].parsModel, "Yes"))
+ *isApplic2 = NO;
+
+ /* Check that the branch length prior is clock for both partitions. */
+ if (strcmp(modelParams[part1].brlensPr, "Clock"))
+ *isApplic1 = NO;
+ if (strcmp(modelParams[part2].brlensPr, "Clock"))
+ *isApplic2 = NO;
+
+ /* Check that the clock rate prior is cpp for both partitions */
+ if (strcmp(modelParams[part1].clockVarPr, "Cpp"))
+ *isApplic1 = NO;
+ if (strcmp(modelParams[part2].clockVarPr, "Cpp"))
+ *isApplic2 = NO;
+
+ /* Now, check that the prior on cpp rate is the same. */
+ if (!strcmp(modelParams[part1].cppRatePr,"Exponential") && !strcmp(modelParams[part2].cppRatePr,"Exponential"))
+ {
+ if (AreDoublesEqual (modelParams[part1].cppRateExp, modelParams[part2].cppRateExp, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].cppRatePr,"Fixed") && !strcmp(modelParams[part2].cppRatePr,"Fixed"))
+ {
+ if (AreDoublesEqual (modelParams[part1].cppRateFix, modelParams[part2].cppRateFix, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else
+ isSame = NO;
+
+ /* Check to see if cpp rate is inapplicable for either partition. */
+ if ((*isApplic1) == NO || (*isApplic2) == NO)
+ isSame = NO;
+ }
+ else if (whichParam == P_CPPMULTDEV)
+ {
+ /* Check cpp multiplier deviation prior for partitions 1 and 2. */
+
+ /* Check if the model is parsimony for either partition. If so, then the branch lengths cannot apply (as parsimony is very
+ silly and doesn't take this information into account) and this parameter is inapplicable. */
+ if (!strcmp(modelParams[part1].parsModel, "Yes"))
+ *isApplic1 = NO;
+ if (!strcmp(modelParams[part2].parsModel, "Yes"))
+ *isApplic2 = NO;
+
+ /* Check that the branch length prior is clock for both partitions. */
+ if (strcmp(modelParams[part1].brlensPr, "Clock"))
+ *isApplic1 = NO;
+ if (strcmp(modelParams[part2].brlensPr, "Clock"))
+ *isApplic2 = NO;
+
+ /* Check that the clock rate prior is cpp for both partitions */
+ if (strcmp(modelParams[part1].clockVarPr, "Cpp"))
+ *isApplic1 = NO;
+ if (strcmp(modelParams[part2].clockVarPr, "Cpp"))
+ *isApplic2 = NO;
+
+ /* Now, check that the prior on sigma is the same. */
+ if (!strcmp(modelParams[part1].cppMultDevPr,"Fixed") && !strcmp(modelParams[part2].cppMultDevPr,"Fixed"))
+ {
+ if (AreDoublesEqual (modelParams[part1].cppMultDevFix, modelParams[part2].cppMultDevFix, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else
+ isSame = NO;
+
+ /* Check to see if cpp multiplier sigma is inapplicable for either partition. */
+ if ((*isApplic1) == NO || (*isApplic2) == NO)
+ isSame = NO;
+ }
+ else if (whichParam == P_CPPEVENTS)
+ {
+ /* Check cpp events for partitions 1 and 2. */
+
+ /* Check if the model is parsimony for either partition. If so, then branch lengths do not apply (as parsimony is very
+ silly and doesn't take this information into account) and cpp events are inapplicable. */
+ if (!strcmp(modelParams[part1].parsModel, "Yes"))
+ *isApplic1 = NO;
+ if (!strcmp(modelParams[part2].parsModel, "Yes"))
+ *isApplic2 = NO;
+
+ /* Check that the branch length prior is clock for both partitions. */
+ if (strcmp(modelParams[part1].brlensPr, "Clock"))
+ *isApplic1 = NO;
+ if (strcmp(modelParams[part2].brlensPr, "Clock"))
+ *isApplic2 = NO;
+
+ /* Check that the clock rate prior is cpp for both partitions */
+ if (strcmp(modelParams[part1].clockVarPr, "Cpp"))
+ *isApplic1 = NO;
+ if (strcmp(modelParams[part2].clockVarPr, "Cpp"))
+ *isApplic2 = NO;
+
+ /* Now, check that the cpp parameter is the same */
+ if (IsModelSame (P_CPPRATE, part1, part2, &temp1, &temp2) == NO)
+ isSame = NO;
+ if (linkTable[P_CPPRATE][part1] != linkTable[P_CPPRATE][part2])
+ isSame = NO;
+
+ /* ... and that the psigamma parameter is the same */
+ if (IsModelSame (P_CPPMULTDEV, part1, part2, &temp1, &temp2) == NO)
+ isSame = NO;
+ if (linkTable[P_CPPMULTDEV][part1] != linkTable[P_CPPRATE][part2])
+ isSame = NO;
+
+ /* Not same if branch lengths are not the same */
+ if (IsModelSame(P_BRLENS, part1, part2, &temp1, &temp2) == NO)
+ isSame = NO;
+ if (linkTable[P_BRLENS][part1] != linkTable[P_BRLENS][part2])
+ isSame = NO;
+
+ /* Set isSame to NO if cpp events are inapplicable for either partition. */
+ if ((*isApplic1) == NO || (*isApplic2) == NO)
+ isSame = NO;
+ }
+ else if (whichParam == P_TK02VAR)
+ {
+ /* Check prior for variance of rate autocorrelation for partitions 1 and 2. */
+
+ /* Check if the model is parsimony for either partition. If so, then the branch lengths cannot apply (as parsimony is very
+ silly and doesn't take this information into account) and ratevar is inapplicable. */
+ if (!strcmp(modelParams[part1].parsModel, "Yes"))
+ *isApplic1 = NO;
+ if (!strcmp(modelParams[part2].parsModel, "Yes"))
+ *isApplic2 = NO;
+
+ /* Check that the branch length prior is clock for both partitions. */
+ if (strcmp(modelParams[part1].brlensPr, "Clock"))
+ *isApplic1 = NO;
+ if (strcmp(modelParams[part2].brlensPr, "Clock"))
+ *isApplic2 = NO;
+
+ /* Check that the clock rate prior is tk02 for both partitions */
+ if (strcmp(modelParams[part1].clockVarPr, "TK02"))
+ *isApplic1 = NO;
+ if (strcmp(modelParams[part2].clockVarPr, "TK02"))
+ *isApplic2 = NO;
+
+ /* Now, check that the prior on tk02 variance is the same. */
+ if (!strcmp(modelParams[part1].tk02varPr,"Uniform") && !strcmp(modelParams[part2].tk02varPr,"Uniform"))
+ {
+ if (AreDoublesEqual (modelParams[part1].tk02varUni[0], modelParams[part2].tk02varUni[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].tk02varUni[1], modelParams[part2].tk02varUni[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].tk02varPr,"Exponential") && !strcmp(modelParams[part2].tk02varPr,"Exponential"))
+ {
+ if (AreDoublesEqual (modelParams[part1].tk02varExp, modelParams[part2].tk02varExp, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].tk02varPr,"Fixed") && !strcmp(modelParams[part2].tk02varPr,"Fixed"))
+ {
+ if (AreDoublesEqual (modelParams[part1].tk02varFix, modelParams[part2].tk02varFix, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else
+ isSame = NO;
+
+ /* Check to see if tk02 variance is inapplicable for either partition. */
+ if ((*isApplic1) == NO || (*isApplic2) == NO)
+ isSame = NO;
+ }
+ else if (whichParam == P_TK02BRANCHRATES)
+ {
+ /* Check TK02 relaxed clock branch rates for partitions 1 and 2. */
+
+ /* Check if the model is parsimony for either partition. If so, then branch lengths do not apply (as parsimony is very
+ silly and doesn't take this information into account) and tk02 relaxed clock branch rates are inapplicable. */
+ if (!strcmp(modelParams[part1].parsModel, "Yes"))
+ *isApplic1 = NO;
+ if (!strcmp(modelParams[part2].parsModel, "Yes"))
+ *isApplic2 = NO;
+
+ /* Check that the branch length prior is clock for both partitions. */
+ if (strcmp(modelParams[part1].brlensPr, "Clock"))
+ *isApplic1 = NO;
+ if (strcmp(modelParams[part2].brlensPr, "Clock"))
+ *isApplic2 = NO;
+
+ /* Check that the clock rate prior is tk02 for both partitions */
+ if (strcmp(modelParams[part1].clockVarPr, "TK02"))
+ *isApplic1 = NO;
+ if (strcmp(modelParams[part2].clockVarPr, "TK02"))
+ *isApplic2 = NO;
+
+ /* Now, check that the tk02 variance parameter is the same */
+ if (IsModelSame (P_TK02VAR, part1, part2, &temp1, &temp2) == NO)
+ isSame = NO;
+ if (linkTable[P_TK02VAR][part1] != linkTable[P_TK02VAR][part2])
+ isSame = NO;
+
+ /* Not same if branch lengths are not the same */
+ if (IsModelSame(P_BRLENS, part1, part2, &temp1, &temp2) == NO)
+ isSame = NO;
+ if (linkTable[P_BRLENS][part1] != linkTable[P_BRLENS][part2])
+ isSame = NO;
+
+ /* Set isSame to NO if tk02 branch rates are inapplicable for either partition. */
+ if ((*isApplic1) == NO || (*isApplic2) == NO)
+ isSame = NO;
+ }
+ else if (whichParam == P_IGRVAR)
+ {
+ /* Check prior for igr shape for partitions 1 and 2. */
+
+ /* Check if the model is parsimony for either partition. If so, then the branch lengths cannot apply (as parsimony is very
+ silly and doesn't take this information into account) and igr shape is inapplicable. */
+ if (!strcmp(modelParams[part1].parsModel, "Yes"))
+ *isApplic1 = NO;
+ if (!strcmp(modelParams[part2].parsModel, "Yes"))
+ *isApplic2 = NO;
+
+ /* Check that the branch length prior is clock for both partitions. */
+ if (strcmp(modelParams[part1].brlensPr, "Clock"))
+ *isApplic1 = NO;
+ if (strcmp(modelParams[part2].brlensPr, "Clock"))
+ *isApplic2 = NO;
+
+ /* Check that the clock rate prior is igr for both partitions */
+ if (strcmp(modelParams[part1].clockVarPr, "Igr"))
+ *isApplic1 = NO;
+ if (strcmp(modelParams[part2].clockVarPr, "Igr"))
+ *isApplic2 = NO;
+
+ /* Now, check that the prior on igr shape is the same. */
+ if (!strcmp(modelParams[part1].igrvarPr,"Uniform") && !strcmp(modelParams[part2].igrvarPr,"Uniform"))
+ {
+ if (AreDoublesEqual (modelParams[part1].igrvarUni[0], modelParams[part2].igrvarUni[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].igrvarUni[1], modelParams[part2].igrvarUni[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].igrvarPr,"Exponential") && !strcmp(modelParams[part2].igrvarPr,"Exponential"))
+ {
+ if (AreDoublesEqual (modelParams[part1].igrvarExp, modelParams[part2].igrvarExp, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].igrvarPr,"Fixed") && !strcmp(modelParams[part2].igrvarPr,"Fixed"))
+ {
+ if (AreDoublesEqual (modelParams[part1].igrvarFix, modelParams[part2].igrvarFix, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else
+ isSame = NO;
+
+ /* Check to see if igr variance is inapplicable for either partition. */
+ if ((*isApplic1) == NO || (*isApplic2) == NO)
+ isSame = NO;
+ }
+ else if (whichParam == P_IGRBRANCHRATES)
+ {
+ /* Check IGR relaxed clock branch rates for partitions 1 and 2. */
+
+ /* Check if the model is parsimony for either partition. If so, then branch lengths do not apply (as parsimony is very
+ silly and doesn't take this information into account) and igr relaxed clock branch rates are inapplicable. */
+ if (!strcmp(modelParams[part1].parsModel, "Yes"))
+ *isApplic1 = NO;
+ if (!strcmp(modelParams[part2].parsModel, "Yes"))
+ *isApplic2 = NO;
+
+ /* Check that the branch length prior is clock for both partitions. */
+ if (strcmp(modelParams[part1].brlensPr, "Clock"))
+ *isApplic1 = NO;
+ if (strcmp(modelParams[part2].brlensPr, "Clock"))
+ *isApplic2 = NO;
+
+ /* Check that the clock rate prior is igr for both partitions */
+ if (strcmp(modelParams[part1].clockVarPr, "Igr"))
+ *isApplic1 = NO;
+ if (strcmp(modelParams[part2].clockVarPr, "Igr"))
+ *isApplic2 = NO;
+
+ /* Now, check that the igr shape parameter is the same */
+ if (IsModelSame (P_IGRVAR, part1, part2, &temp1, &temp2) == NO)
+ isSame = NO;
+ if (linkTable[P_IGRVAR][part1] != linkTable[P_IGRVAR][part2])
+ isSame = NO;
+
+ /* Not same if branch lengths are not the same */
+ if (IsModelSame(P_BRLENS, part1, part2, &temp1, &temp2) == NO)
+ isSame = NO;
+ if (linkTable[P_BRLENS][part1] != linkTable[P_BRLENS][part2])
+ isSame = NO;
+
+ /* Set isSame to NO if igr branch rates are inapplicable for either partition. */
+ if ((*isApplic1) == NO || (*isApplic2) == NO)
+ isSame = NO;
+ }
+ else if (whichParam == P_MIXEDVAR)
+ {
+ /* Check prior for mixed var for partitions 1 and 2. */
+
+ /* Check if the model is parsimony for either partition. If so, then the branch lengths cannot apply (as parsimony is very
+ silly and doesn't take this information into account) and variance is inapplicable. */
+ if (!strcmp(modelParams[part1].parsModel, "Yes"))
+ *isApplic1 = NO;
+ if (!strcmp(modelParams[part2].parsModel, "Yes"))
+ *isApplic2 = NO;
+
+ /* Check that the branch length prior is clock for both partitions. */
+ if (strcmp(modelParams[part1].brlensPr, "Clock"))
+ *isApplic1 = NO;
+ if (strcmp(modelParams[part2].brlensPr, "Clock"))
+ *isApplic2 = NO;
+
+ /* Check that the clock rate prior is mixed for both partitions */
+ if (strcmp(modelParams[part1].clockVarPr, "Mixed"))
+ *isApplic1 = NO;
+ if (strcmp(modelParams[part2].clockVarPr, "Mixed"))
+ *isApplic2 = NO;
+
+ /* Now, check that the prior on var mixed is the same. */
+ if (!strcmp(modelParams[part1].mixedvarPr,"Uniform") && !strcmp(modelParams[part2].mixedvarPr,"Uniform"))
+ {
+ if (AreDoublesEqual (modelParams[part1].mixedvarUni[0], modelParams[part2].mixedvarUni[0], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ if (AreDoublesEqual (modelParams[part1].mixedvarUni[1], modelParams[part2].mixedvarUni[1], (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].mixedvarPr,"Exponential") && !strcmp(modelParams[part2].mixedvarPr,"Exponential"))
+ {
+ if (AreDoublesEqual (modelParams[part1].mixedvarExp, modelParams[part2].mixedvarExp, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else if (!strcmp(modelParams[part1].mixedvarPr,"Fixed") && !strcmp(modelParams[part2].mixedvarPr,"Fixed"))
+ {
+ if (AreDoublesEqual (modelParams[part1].mixedvarFix, modelParams[part2].mixedvarFix, (MrBFlt) 0.00001) == NO)
+ isSame = NO;
+ }
+ else
+ isSame = NO;
+
+ /* Check to see if variance is inapplicable for either partition. */
+ if ((*isApplic1) == NO || (*isApplic2) == NO)
+ isSame = NO;
+ }
+ else if (whichParam == P_MIXEDBRCHRATES)
+ {
+ /* Check mixed relaxed clock branch rates for partitions 1 and 2. */
+
+ /* Check if the model is parsimony for either partition. If so, then branch lengths do not apply (as parsimony is very
+ silly and doesn't take this information into account) and relaxed clock branch rates are inapplicable. */
+ if (!strcmp(modelParams[part1].parsModel, "Yes"))
+ *isApplic1 = NO;
+ if (!strcmp(modelParams[part2].parsModel, "Yes"))
+ *isApplic2 = NO;
+
+ /* Check that the branch length prior is clock for both partitions. */
+ if (strcmp(modelParams[part1].brlensPr, "Clock"))
+ *isApplic1 = NO;
+ if (strcmp(modelParams[part2].brlensPr, "Clock"))
+ *isApplic2 = NO;
+
+ /* Check that the clock rate prior is mixed for both partitions */
+ if (strcmp(modelParams[part1].clockVarPr, "Mixed"))
+ *isApplic1 = NO;
+ if (strcmp(modelParams[part2].clockVarPr, "Mixed"))
+ *isApplic2 = NO;
+
+ /* Now, check that the var parameter is the same */
+ if (IsModelSame (P_MIXEDVAR, part1, part2, &temp1, &temp2) == NO)
+ isSame = NO;
+ if (linkTable[P_MIXEDVAR][part1] != linkTable[P_MIXEDVAR][part2])
+ isSame = NO;
+
+ /* Not same if branch lengths are not the same */
+ if (IsModelSame(P_BRLENS, part1, part2, &temp1, &temp2) == NO)
+ isSame = NO;
+ if (linkTable[P_BRLENS][part1] != linkTable[P_BRLENS][part2])
+ isSame = NO;
+
+ /* Set isSame to NO if mixed branch rates are inapplicable for either partition. */
+ if ((*isApplic1) == NO || (*isApplic2) == NO)
+ isSame = NO;
+ }
+ else if (whichParam == P_CLOCKRATE)
+ {
+ /* Check base substitution rates of clock tree for partitions 1 and 2. */
+
+ /* Check if the model is parsimony for either partition. If so, then branch lengths do not apply (as parsimony is very
+ silly and doesn't take this information into account) and clock branch rates are inapplicable. */
+ if (!strcmp(modelParams[part1].parsModel, "Yes"))
+ *isApplic1 = NO;
+ if (!strcmp(modelParams[part2].parsModel, "Yes"))
+ *isApplic2 = NO;
+
+ /* Check that the branch length prior is clock for both partitions. */
+ if (strcmp(modelParams[part1].brlensPr, "Clock"))
+ *isApplic1 = NO;
+ if (strcmp(modelParams[part2].brlensPr, "Clock"))
+ *isApplic2 = NO;
+
+ /* Set isSame to NO if base substitution rate parameter is inapplicable for either partition. */
+ if ((*isApplic1) == NO || (*isApplic2) == NO)
+ isSame = NO;
+ }
+ else if (whichParam == P_SPECIESTREE)
+ {
+ /* Species tree; check that it is used in both partitions */
+ if (strcmp(modelParams[part1].topologyPr, "Speciestree") != 0)
+ *isApplic1 = NO;
+ if (strcmp(modelParams[part2].topologyPr, "Speciestree") != 0)
+ *isApplic2 = NO;
+
+ /* Not same if inapplicable to either partition */
+ if ((*isApplic1) == NO || (*isApplic2) == NO)
+ isSame = NO;
+ }
+ else if (whichParam == P_GENETREERATE)
+ {
+ /* Gene tree rate; check that it is used in both partitions */
+ if (strcmp(modelParams[part1].topologyPr, "Speciestree") != 0)
+ *isApplic1 = NO;
+ if (strcmp(modelParams[part2].topologyPr, "Speciestree") != 0)
+ *isApplic2 = NO;
+
+ /* Not same if inapplicable to either partition */
+ if ((*isApplic1) == NO || (*isApplic2) == NO)
+ isSame = NO;
+ }
+ else
+ {
+ MrBayesPrint ("%s Could not find parameter in IsModelSame\n", spacer);
+ return (NO);
+ }
+
+ return (isSame);
+}
+
+
+int LargestMovableSubtree(Param *treeParam)
+{
+ int i, j, k, a, nLongsNeeded, numPartitions, largestSubtree;
+ BitsLong **constraintPartition, *subtreePartition, *testPartition, *mask;
+ ModelParams *mp;
+
+ mp = &modelParams[treeParam->relParts[0]];
+
+ if (treeParam->paramType == P_SPECIESTREE)
+ return numLocalTaxa; /* no constraints allowed in species tree; set constraints in gene trees instead */
+
+ /* This is difficult because we cannot rely on the tree being initialized.
+ We need to retrieve the bitfields ourselves and figure out what they mean. */
+ nLongsNeeded = ((numLocalTaxa - 1) / nBitsInALong) + 1;
+ subtreePartition = (BitsLong *) SafeCalloc(3*nLongsNeeded, sizeof(BitsLong));
+ constraintPartition = (BitsLong **) SafeCalloc (numDefinedConstraints+1, sizeof(BitsLong *));
+ constraintPartition[0] = (BitsLong *) SafeCalloc ((numDefinedConstraints+1)*nLongsNeeded, sizeof(BitsLong));
+ for (i=1; i<numDefinedConstraints+1; i++)
+ constraintPartition[i] = constraintPartition[i-1] + nLongsNeeded;
+ testPartition = subtreePartition + nLongsNeeded;
+ mask = testPartition + nLongsNeeded;
+
+ /* set mask (needed to take care of unused bits when flipping partitions) */
+ for (i=0; i<numLocalTaxa; i++)
+ SetBit (i, mask);
+
+ /* retrieve partitions */
+ numPartitions = 0;
+ for (a=0; a<numDefinedConstraints; a++)
+ {
+ if (mp->activeConstraints[a] == NO || definedConstraintsType[a] != HARD)
+ continue;
+
+ /* set bits in partition under consideration */
+ ClearBits(constraintPartition[numPartitions], nLongsNeeded);
+ for (i=j=0; i<numTaxa; i++)
+ {
+ if (taxaInfo[i].isDeleted == YES)
+ continue;
+ if (IsBitSet(i, definedConstraint[a]) == YES)
+ SetBit(j, constraintPartition[numPartitions]);
+ j++;
+ }
+
+ /* make sure outgroup is outside constrained partition (marked 0) */
+ if (strcmp(mp->brlensPr,"Clock") != 0 && IsBitSet(localOutGroup, constraintPartition[numPartitions]) == YES)
+ FlipBits(constraintPartition[numPartitions], nLongsNeeded, mask);
+
+ /* skip partition if uninformative */
+ k = NumBits(constraintPartition[numPartitions], nLongsNeeded);
+ if (k == 0 || k == 1)
+ continue;
+
+ numPartitions++;
+ }
+
+ /* Add all-species partition */
+ CopyBits(constraintPartition[numPartitions], mask, nLongsNeeded);
+ numPartitions++;
+
+ /* Now we have all constraints. Calculate the movable subtree for each */
+ largestSubtree = 0;
+ for (i=0; i<numPartitions; i++)
+ {
+ CopyBits (subtreePartition, constraintPartition[i], nLongsNeeded);
+ k = 0;
+ for (j=0; j<numPartitions; j++)
+ {
+ if (j==i)
+ continue;
+ if (IsPartNested(constraintPartition[j], constraintPartition[i], nLongsNeeded))
+ {
+ k++; /* add one for clade we are removing from subtreePartition */
+ CopyBits (testPartition, constraintPartition[j], nLongsNeeded);
+ FlipBits (testPartition, nLongsNeeded, mask);
+ for (k=0; k<nLongsNeeded; k++)
+ subtreePartition[k] = subtreePartition[k] & testPartition[k];
+ }
+ }
+ k += NumBits (subtreePartition, nLongsNeeded); /* add remaming free tips in subtreePartition */
+ /* add calculation root if an unrooted tree and we are dealing with the root partition */
+ if (strcmp(mp->brlensPr,"Clock") != 0 && NumBits (constraintPartition[i], nLongsNeeded) == numLocalTaxa - 1)
+ k++;
+ if (k > largestSubtree)
+ largestSubtree = k;
+ }
+
+ free(subtreePartition);
+ free(constraintPartition[0]);
+ free(constraintPartition);
+
+ return largestSubtree;
+}
+
+
+int Link (void)
+{
+ int i, j;
+
+ for (j=0; j<NUM_LINKED; j++)
+ {
+ MrBayesPrint ("%4d -- ", j+1);
+ for (i=0; i<numCurrentDivisions; i++)
+ MrBayesPrint (" %2d", tempLinkUnlink[j][i]);
+ MrBayesPrint ("\n");
+ }
+
+ return (NO_ERROR);
+}
+
+
+int NumActiveParts (void)
+{
+ int i, nApplied;
+
+ nApplied = 0;
+ for (i=0; i<numCurrentDivisions; i++)
+ if (activeParts[i] == YES)
+ nApplied++;
+
+ return (nApplied);
+}
+
+
+int NumInformativeHardConstraints (ModelParams *mp)
+{
+ int i, j, k, a, numInformativeHardConstraints, nLongsNeeded;
+ BitsLong *constraintPartition, *mask;
+
+ numInformativeHardConstraints = 0;
+
+ nLongsNeeded = ((numLocalTaxa - 1) / nBitsInALong) + 1;
+ constraintPartition = (BitsLong *) SafeCalloc (2*nLongsNeeded, sizeof(BitsLong));
+ if (!constraintPartition)
+ {
+ MrBayesPrint ("%s Problems allocating constraintPartition", spacer);
+ return ERROR;
+ }
+ mask = constraintPartition + nLongsNeeded;
+
+ /* set mask (needed to take care of unused bits when flipping partitions) */
+ for (i=0; i<numLocalTaxa; i++)
+ SetBit (i, mask);
+
+ for (a=0; a<numDefinedConstraints; a++)
+ {
+ if (mp->activeConstraints[a] == NO || definedConstraintsType[a] != HARD)
+ continue;
+
+ /* set bits in partition to add */
+ ClearBits(constraintPartition, nLongsNeeded);
+ for (i=j=0; i<numTaxa; i++)
+ {
+ if (taxaInfo[i].isDeleted == YES)
+ continue;
+ if (IsBitSet(i, definedConstraint[a]) == YES)
+ SetBit(j, constraintPartition);
+ j++;
+ }
+
+ /* make sure outgroup is outside constrained partition (marked 0) */
+ if (strcmp(mp->brlensPr,"Clock") != 0 && IsBitSet(localOutGroup, constraintPartition) == YES)
+ FlipBits(constraintPartition, nLongsNeeded, mask);
+
+ /* skip partition if uninformative */
+ k = NumBits(constraintPartition, nLongsNeeded);
+ if (k == 0 || k == 1)
+ continue;
+
+ numInformativeHardConstraints++;
+ }
+
+ return numInformativeHardConstraints;
+}
+
+
+int NumNonExcludedChar (void)
+{
+ int i, n;
+
+ /* count number of non-excluded characters */
+ n = 0;
+ for (i=0; i<numChar; i++)
+ {
+ if (charInfo[i].isExcluded == NO)
+ {
+ n++;
+ }
+ }
+
+ return n;
+}
+
+
+int NumStates (int part)
+{
+ if (modelParams[part].dataType == DNA || modelParams[part].dataType == RNA)
+ {
+ if (!strcmp(modelParams[part].nucModel, "4by4"))
+ return (4);
+ else if (!strcmp(modelParams[part].nucModel, "Doublet"))
+ return (16);
+ else if (!strcmp(modelParams[part].nucModel, "Protein"))
+ return (20);
+ else
+ {
+ if (!strcmp(modelParams[part].geneticCode, "Universal"))
+ return (61);
+ else if (!strcmp(modelParams[part].geneticCode, "Vertmt"))
+ return (60);
+ else if (!strcmp(modelParams[part].geneticCode, "Invermt"))
+ return (62);
+ else if (!strcmp(modelParams[part].geneticCode, "Mycoplasma"))
+ return (62);
+ else if (!strcmp(modelParams[part].geneticCode, "Yeast"))
+ return (62);
+ else if (!strcmp(modelParams[part].geneticCode, "Ciliate"))
+ return (63);
+ else if (!strcmp(modelParams[part].geneticCode, "Echinoderm"))
+ return (62);
+ else if (!strcmp(modelParams[part].geneticCode, "Euplotid"))
+ return (62);
+ else if (!strcmp(modelParams[part].geneticCode, "Metmt"))
+ return (62);
+ }
+ }
+ else if (modelParams[part].dataType == PROTEIN)
+ {
+ return (20);
+ }
+ else if (modelParams[part].dataType == RESTRICTION)
+ {
+ return (2);
+ }
+ else if (modelParams[part].dataType == STANDARD)
+ {
+ return (10);
+ }
+
+ return (-1);
+}
+
+
+/*-----------------------------------------------------------------------
+|
+| PrintCompMatrix: Print compressed matrix
+|
+------------------------------------------------------------------------*/
+int PrintCompMatrix (void)
+{
+ int i, j, k, c, d;
+ ModelInfo *m;
+ ModelParams *mp;
+ char tempName[100];
+ char (*whichChar)(int);
+
+ if (!compMatrix)
+ return ERROR;
+
+ whichChar = &WhichNuc;
+
+ for (d=0; d<numCurrentDivisions; d++)
+ {
+ m = &modelSettings[d];
+ mp = &modelParams[d];
+
+ if (mp->dataType == DNA || mp->dataType == RNA)
+ whichChar = &WhichNuc;
+ if (mp->dataType == PROTEIN)
+ whichChar = &WhichAA;
+ if (mp->dataType == RESTRICTION)
+ whichChar = &WhichRes;
+ if (mp->dataType == STANDARD)
+ whichChar = &WhichStand;
+
+ MrBayesPrint ("\nCompressed matrix for division %d\n\n", d+1);
+
+ k = 66;
+ if (mp->dataType == CONTINUOUS)
+ k /= 4;
+
+ for (c=m->compMatrixStart; c<m->compMatrixStop; c+=k)
+ {
+ for (i=0; i<numLocalTaxa; i++)
+ {
+ strcpy (tempName, localTaxonNames[i]);
+ MrBayesPrint ("%-10.10s ", tempName);
+ for (j=c; j<c+k; j++)
+ {
+ if (j >= m->compMatrixStop)
+ break;
+ if (mp->dataType == CONTINUOUS)
+ MrBayesPrint ("%3d ", compMatrix[pos(i,j,compMatrixRowSize)]);
+ else
+ MrBayesPrint ("%c", whichChar((int)compMatrix[pos(i,j,compMatrixRowSize)]));
+ }
+ MrBayesPrint("\n");
+ }
+ MrBayesPrint("\nNo. sites ");
+ for (j=c; j<c+k; j++)
+ {
+ if (j >= m->compMatrixStop)
+ break;
+ i = (int) numSitesOfPat[m->compCharStart + (0*numCompressedChars) + (j - m->compMatrixStart)/m->nCharsPerSite]; /* NOTE: We are printing the unadulterated site pat nums */
+ if (i>9)
+ i = 'A' + i - 10;
+ else
+ i = '0' + i;
+ if (mp->dataType == CONTINUOUS)
+ MrBayesPrint(" %c ", i);
+ else
+ {
+ if ((j-m->compMatrixStart) % m->nCharsPerSite == 0)
+ MrBayesPrint ("%c", i);
+ else
+ MrBayesPrint(" ");
+ }
+ }
+ MrBayesPrint ("\nOrig. char ");
+ for (j=c; j<c+k; j++)
+ {
+ if (j >= m->compMatrixStop)
+ break;
+ i = origChar[j];
+ if (i>9)
+ i = '0' + (i % 10);
+ else
+ i = '0' +i;
+ if (mp->dataType == CONTINUOUS)
+ MrBayesPrint(" %c ", i);
+ else
+ MrBayesPrint ("%c", i);
+ }
+
+ if (mp->dataType == STANDARD && m->nStates != NULL)
+ {
+ MrBayesPrint ("\nNo. states ");
+ for (j=c; j<c+k; j++)
+ {
+ if (j >= m->compMatrixStop)
+ break;
+ i = m->nStates[j-m->compCharStart];
+ MrBayesPrint ("%d", i);
+ }
+ MrBayesPrint ("\nCharType ");
+ for (j=c; j<c+k; j++)
+ {
+ if (j >= m->compMatrixStop)
+ break;
+ i = m->cType[j-m->compMatrixStart];
+ if (i == ORD)
+ MrBayesPrint ("%c", 'O');
+ else if (i == UNORD)
+ MrBayesPrint ("%c", 'U');
+ else
+ MrBayesPrint ("%c", 'I');
+ }
+ MrBayesPrint ("\ntiIndex ");
+ for (j=c; j<c+k; j++)
+ {
+ if (j >= m->compMatrixStop)
+ break;
+ i = m->tiIndex[j-m->compCharStart];
+ MrBayesPrint ("%d", i % 10);
+ }
+ MrBayesPrint ("\nbsIndex ");
+ for (j=c; j<c+k; j++)
+ {
+ if (j >= m->compMatrixStop)
+ break;
+ i = m->bsIndex[j-m->compCharStart];
+ MrBayesPrint ("%d", i % 10);
+ }
+ }
+ MrBayesPrint ("\n\n");
+ }
+ MrBayesPrint ("Press return to continue\n");
+ getchar();
+ } /* next division */
+
+ return NO_ERROR;
+}
+
+
+/*----------------------------------------------------------------------
+|
+| PrintMatrix: Print data matrix
+|
+|
+------------------------------------------------------------------------*/
+int PrintMatrix (void)
+{
+ int i, j=0, c, printWidth, nextColumn;
+
+ if (!matrix)
+ return ERROR;
+
+ MrBayesPrint ("\nData matrix\n\n");
+
+ printWidth = 79;
+
+ for (c=0; c<numChar; c=j)
+ {
+ for (i=0; i<numTaxa; i++)
+ {
+ MrBayesPrint ("%-10.10s ", taxaNames[i]);
+ j = c;
+ for (nextColumn=13; nextColumn < printWidth; nextColumn++)
+ {
+ if (j >= numChar)
+ break;
+ if (charInfo[j].charType == CONTINUOUS && nextColumn < printWidth - 3)
+ break;
+ if (charInfo[j].charType == CONTINUOUS)
+ {
+ MrBayesPrint ("%3d ", matrix[pos(i,j,numChar)]);
+ nextColumn += 3;
+ }
+ else if (charInfo[j].charType == DNA || charInfo[j].charType == RNA)
+ MrBayesPrint ("%c", WhichNuc(matrix[pos(i,j,numChar)]));
+ else if (charInfo[j].charType == PROTEIN)
+ MrBayesPrint ("%c", WhichAA(matrix[pos(i,j,numChar)]));
+ else if (charInfo[j].charType == RESTRICTION)
+ MrBayesPrint ("%c", WhichRes(matrix[pos(i,j,numChar)]));
+ else if (charInfo[j].charType == STANDARD)
+ MrBayesPrint ("%c", WhichStand(matrix[pos(i,j,numChar)]));
+ j++;
+ }
+ MrBayesPrint("\n");
+ }
+ MrBayesPrint ("\n");
+ }
+
+ return NO_ERROR;
+}
+
+
+/*--------------------------------------------------------------
+|
+| ProcessStdChars: process standard characters
+|
+---------------------------------------------------------------*/
+int ProcessStdChars (RandLong *seed)
+{
+ int c, d, i, j, k, n, ts, index, numStandardChars, origCharPos, *bsIndex;
+ char piHeader[30];
+ ModelInfo *m;
+ ModelParams *mp=NULL;
+ Param *p;
+
+ /* set character type, no. states, ti index and bs index for standard characters */
+ /* first calculate how many standard characters we have */
+ numStandardChars = 0;
+ for (d=0; d<numCurrentDivisions; d++)
+ {
+ mp = &modelParams[d];
+ m = &modelSettings[d];
+
+ if (mp->dataType != STANDARD)
+ continue;
+
+ numStandardChars += m->numChars;
+ }
+
+ /* return if there are no standard characters */
+ if (numStandardChars == 0)
+ return (NO_ERROR);
+
+ /* we are still here so we have standard characters and need to deal with them */
+
+ /* first allocate space for stdType, stateSize, tiIndex, bsIndex */
+ if (memAllocs[ALLOC_STDTYPE] == YES)
+ {
+ free (stdType);
+ stdType = NULL;
+ memAllocs[ALLOC_STDTYPE] = NO;
+ }
+ stdType = (int *)SafeCalloc(4 * (size_t)numStandardChars, sizeof(int));
+ if (!stdType)
+ {
+ MrBayesPrint ("%s Problem allocating stdType (%d ints)\n", 4 * numStandardChars);
+ return ERROR;
+ }
+ memAllocs[ALLOC_STDTYPE] = YES;
+ stateSize = stdType + numStandardChars;
+ tiIndex = stateSize + numStandardChars;
+ bsIndex = tiIndex + numStandardChars;
+
+ /* then fill in stdType and stateSize, set pointers */
+ /* also fill in isTiNeeded for each division and tiIndex for each character */
+ for (d=j=0; d<numCurrentDivisions; d++)
+ {
+ mp = &modelParams[d];
+ m = &modelSettings[d];
+
+ if (mp->dataType != STANDARD)
+ continue;
+
+ m->cType = stdType + j;
+ m->nStates = stateSize + j;
+ m->tiIndex = tiIndex + j;
+ m->bsIndex = bsIndex + j;
+
+ m->cijkLength = 0;
+ m->nCijkParts = 0;
+ for (c=0; c<m->numChars; c++)
+ {
+ if (origChar[c+m->compMatrixStart] < 0)
+ {
+ /* this is a dummy character */
+ m->cType[c] = UNORD;
+ m->nStates[c] = 2;
+ }
+ else
+ {
+ /* this is an ordinary character */
+ m->cType[c] = charInfo[origChar[c + m->compMatrixStart]].ctype;
+ m->nStates[c] = charInfo[origChar[c + m->compMatrixStart]].numStates;
+ }
+
+ /* check ctype settings */
+ if (m->nStates[c] < 2)
+ {
+ MrBayesPrint ("%s WARNING: Compressed character %d (original character %d) of division %d has less \n", spacer, c+m->compCharStart,origChar[c+m->compCharStart]+1, d+1);
+ MrBayesPrint ("%s than two observed states; it will be assumed to have two states.\n", spacer);
+ m->nStates[c] = 2;
+ }
+ if (m->nStates[c] > 6 && m->cType[c] != UNORD)
+ {
+ MrBayesPrint ("%s Only unordered model supported for characters with more than 6 states\n", spacer);
+ return ERROR;
+ }
+ if (m->nStates[c] == 2 && m->cType[c] == ORD)
+ m->cType[c] = UNORD;
+ if (m->cType[c] == IRREV)
+ {
+ MrBayesPrint ("%s Irreversible model not yet supported\n", spacer);
+ return ERROR;
+ }
+
+ /* find max number of states */
+ if (m->nStates[c] > m->numModelStates)
+ m->numModelStates = m->nStates[c];
+
+ /* update Cijk info */
+ if (strcmp(mp->symPiPr,"Fixed") != 0 || AreDoublesEqual(mp->symBetaFix, -1.0, 0.00001) == NO)
+ {
+ /* Asymmetry between stationary state frequencies -- we need one cijk and eigenvalue
+ set for each multistate character */
+ if (m->nStates[c] > 2 && (m->cType[c] == UNORD || m->cType[c] == ORD))
+ {
+ ts = m->nStates[c];
+ m->cijkLength += (ts * ts * ts) + (2 * ts);
+ m->nCijkParts++;
+ }
+ }
+
+ /* set the ti probs needed */
+ if (m->stateFreq->nValues == 0 || m->nStates[c] == 2)
+ {
+ if (m->cType[c] == UNORD)
+ m->isTiNeeded[m->nStates[c]-2] = YES;
+ if (m->cType[c] == ORD)
+ m->isTiNeeded[m->nStates[c]+6] = YES;
+ if (m->cType[c] == IRREV)
+ m->isTiNeeded[m->nStates[c]+11] = YES;
+ }
+ }
+
+ /* set ti index for each compressed character first */
+ /* set bs index later (below) */
+
+ /* set base index, valid for binary chars */
+ m->tiIndex[c] = 0;
+
+ /* first adjust for unordered characters */
+ for (k=0; k<9; k++)
+ {
+ if (m->isTiNeeded [k] == NO)
+ continue;
+
+ for (c=0; c<m->numChars; c++)
+ {
+ if (m->cType[c] != UNORD || m->nStates[c] > k + 2)
+ {
+ m->tiIndex[c] += (k + 2) * (k + 2) * m->numGammaCats;
+ }
+ }
+ }
+
+ /* second for ordered characters */
+ for (k=9; k<13; k++)
+ {
+ if (m->isTiNeeded [k] == NO)
+ continue;
+
+ for (c=0; c<m->numChars; c++)
+ {
+ if (m->cType[c] == IRREV || (m->cType[c] == ORD && m->nStates[c] > k - 6))
+ {
+ m->tiIndex[c] += (k - 6) * (k - 6) * m->numGammaCats;
+ }
+ }
+ }
+
+ /* third for irrev characters */
+ for (k=13; k<18; k++)
+ {
+ if (m->isTiNeeded [k] == NO)
+ continue;
+
+ for (c=0; c<m->numChars; c++)
+ {
+ if (m->cType[c] == IRREV && m->nStates[c] > k - 11)
+ {
+ m->tiIndex[c] += (k - 11) * (k - 11) * m->numGammaCats;
+ }
+ }
+ }
+
+ /* finally take beta cats into account in tiIndex */
+ /* the beta cats will only be used for binary characters */
+ /* multistate characters get their ti indices reset here */
+ if (m->numBetaCats > 1 && m->isTiNeeded[0] == YES)
+ {
+ k = 4 * m->numBetaCats * m->numGammaCats; /* offset for binary character ti probs */
+ for (c=0; c<m->numChars; c++)
+ {
+ if (m->nStates[c] > 2)
+ {
+ m->tiIndex[c] = k;
+ k += m->nStates[c] * m->nStates[c] * m->numGammaCats;
+ }
+ }
+ }
+ j += m->numChars;
+ }
+
+ /* deal with bsIndex */
+ for (k=0; k<numParams; k++)
+ {
+ p = ¶ms[k];
+ if (p->paramType != P_PI || modelParams[p->relParts[0]].dataType != STANDARD)
+ continue;
+ p->nSympi = 0;
+ p->hasBinaryStd = NO;
+ for (i=0; i<p->nRelParts; i++)
+ if (modelSettings[p->relParts[i]].isTiNeeded[0] == YES)
+ break;
+ if (i < p->nRelParts)
+ p->hasBinaryStd = YES;
+ if (p->paramId == SYMPI_EQUAL)
+ {
+ /* calculate the number of state frequencies needed */
+ /* also set bsIndex appropriately */
+ for (n=index=0; n<9; n++)
+ {
+ for (i=0; i<p->nRelParts; i++)
+ if (modelSettings[p->relParts[i]].isTiNeeded[n] == YES)
+ break;
+ if (i < p->nRelParts)
+ {
+ for (i=0; i<p->nRelParts; i++)
+ {
+ m = &modelSettings[p->relParts[i]];
+ for (c=0; c<m->numChars; c++)
+ {
+ if (m->cType[c] != UNORD || m->nStates[c] > n + 2)
+ {
+ m->bsIndex[c] += (n + 2);
+ }
+ }
+ }
+ index += (n + 2);
+ }
+ }
+ for (n=9; n<13; n++)
+ {
+ for (i=0; i<p->nRelParts; i++)
+ if (modelSettings[p->relParts[i]].isTiNeeded[n] == YES)
+ break;
+ if (i < p->nRelParts)
+ {
+ for (i=0; i<p->nRelParts; i++)
+ {
+ m = &modelSettings[p->relParts[i]];
+ for (c=0; c<m->numChars; c++)
+ {
+ if (m->cType[c] == ORD && m->nStates[c] > n - 6)
+ {
+ m->bsIndex[c] += (n - 6);
+ }
+ }
+ }
+ index += (n - 6);
+ }
+ }
+ p->nStdStateFreqs = index;
+ }
+ else
+ {
+ /* if not equal we need space for beta category frequencies */
+ index = 0;
+ if (p->hasBinaryStd == YES)
+ index += (2 * modelSettings[p->relParts[0]].numBetaCats);
+ /* as well as one set of frequencies for each multistate character */
+ for (i=0; i<p->nRelParts; i++)
+ {
+ m = &modelSettings[p->relParts[i]];
+ for (c=0; c<m->numChars; c++)
+ {
+ if (m->nStates[c] > 2 && (m->cType[c] == UNORD || m->cType[c] == ORD))
+ {
+ m->bsIndex[c] = index;
+ index += m->nStates[c];
+ p->nSympi++;
+ }
+ }
+ }
+ }
+ p->nStdStateFreqs = index;
+ }
+
+ /* allocate space for bsIndex, sympiIndex, stdStateFreqs; then fill */
+
+ /* first count number of sympis needed */
+ for (k=n=i=0; k<numParams; k++)
+ {
+ p = ¶ms[k];
+ n += p->nSympi; /* nsympi calculated above */
+ }
+
+ /* then allocate and fill in */
+ if (n > 0)
+ {
+ if (memAllocs[ALLOC_SYMPIINDEX] == YES)
+ {
+ sympiIndex = (int *) SafeRealloc ((void *) sympiIndex, 3*n * sizeof (int));
+ for (i=0; i<3*n; i++)
+ sympiIndex[i] = 0;
+ }
+ else
+ sympiIndex = (int *) SafeCalloc (3*n, sizeof (int));
+ if (!sympiIndex)
+ {
+ MrBayesPrint ("%s Problem allocating sympiIndex\n", spacer);
+ return (ERROR);
+ }
+ else
+ memAllocs[ALLOC_SYMPIINDEX] = YES;
+
+ /* set up sympi pointers and fill sympiIndex */
+ for (k=i=0; k<numParams; k++)
+ {
+ p = ¶ms[k];
+ if (p->nSympi > 0)
+ {
+ p->printParam = YES; /* print even if fixed alpha_symdir */
+ index = 0;
+ p->sympiBsIndex = sympiIndex + i;
+ p->sympinStates = sympiIndex + i + n;
+ p->sympiCType = sympiIndex + i + (2 * n);
+ for (j=0; j<p->nRelParts; j++)
+ {
+ m = &modelSettings[p->relParts[j]];
+ for (c=0; c<m->numChars; c++)
+ {
+ if (m->nStates[c] > 2 && (m->cType[c] == UNORD || m->cType[c] == ORD))
+ {
+ p->sympinStates[index] = m->nStates[c];
+ p->sympiBsIndex[index] = m->bsIndex[c];
+ p->sympiCType[index] = m->cType[c];
+ origCharPos = origChar[m->compCharStart + c];
+ for (ts=0; ts<m->nStates[c]; ts++)
+ {
+ sprintf (piHeader, "\tpi_%d(%d)", origCharPos+1, ts);
+ SafeStrcat(&p->paramHeader, piHeader);
+ }
+ index++;
+ }
+ }
+ }
+ assert (index == p->nSympi);
+ i += p->nSympi;
+ }
+ }
+ assert (i == n);
+ }
+
+ /* count space needed for state frequencies */
+ for (k=n=0; k<numParams; k++)
+ {
+ p = ¶ms[k];
+ if (p->paramType != P_PI || modelParams[p->relParts[0]].dataType != STANDARD)
+ continue;
+ n += p->nStdStateFreqs;
+ }
+
+ stdStateFreqsRowSize = n;
+
+ /* allocate space */
+ if (memAllocs[ALLOC_STDSTATEFREQS] == YES)
+ {
+ free (stdStateFreqs);
+ stdStateFreqs = NULL;
+ memAllocs[ALLOC_STDSTATEFREQS] = NO;
+ }
+ stdStateFreqs = (MrBFlt *) SafeCalloc (n * 2 * numGlobalChains, sizeof (MrBFlt));
+ if (!stdStateFreqs)
+ {
+ MrBayesPrint ("%s Problem allocating stdStateFreqs in ProcessStdChars\n", spacer);
+ return (ERROR);
+ }
+ else
+ memAllocs[ALLOC_STDSTATEFREQS] = YES;
+
+ /* set pointers */
+ for (k=n=0; k<numParams; k++)
+ {
+ p = ¶ms[k];
+ if (p->paramType != P_PI || modelParams[p->relParts[0]].dataType != STANDARD)
+ continue;
+ p->stdStateFreqs = stdStateFreqs + n;
+ n += p->nStdStateFreqs;
+ }
+
+ FillStdStateFreqs (0 , numGlobalChains, seed);
+
+ return (NO_ERROR);
+}
+
+
+int SetAARates (void)
+{
+ int i, j;
+ MrBFlt diff, sum, scaler;
+
+ /* A R N D C Q E G H I L K M F P S T W Y V */
+
+ /* jones */
+ 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;
+
+ /* dayhoff */
+ 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;
+
+ /* mtrev24 */
+ aaMtrev24[ 0][ 0] = 0.00; aaMtrev24[ 0][ 1] = 23.18; aaMtrev24[ 0][ 2] = 26.95; aaMtrev24[ 0][ 3] = 17.67; aaMtrev24[ 0][ 4] = 59.93;
+ aaMtrev24[ 0][ 5] = 1.90; aaMtrev24[ 0][ 6] = 9.77; aaMtrev24[ 0][ 7] = 120.71; aaMtrev24[ 0][ 8] = 13.90; aaMtrev24[ 0][ 9] = 96.49;
+ aaMtrev24[ 0][10] = 25.46; aaMtrev24[ 0][11] = 8.36; aaMtrev24[ 0][12] = 141.88; aaMtrev24[ 0][13] = 6.37; aaMtrev24[ 0][14] = 54.31;
+ aaMtrev24[ 0][15] = 387.86; aaMtrev24[ 0][16] = 480.72; aaMtrev24[ 0][17] = 1.90; aaMtrev24[ 0][18] = 6.48; aaMtrev24[ 0][19] = 195.06;
+ aaMtrev24[ 1][ 0] = 23.18; aaMtrev24[ 1][ 1] = 0.00; aaMtrev24[ 1][ 2] = 13.24; aaMtrev24[ 1][ 3] = 1.90; aaMtrev24[ 1][ 4] = 103.33;
+ aaMtrev24[ 1][ 5] = 220.99; aaMtrev24[ 1][ 6] = 1.90; aaMtrev24[ 1][ 7] = 23.03; aaMtrev24[ 1][ 8] = 165.23; aaMtrev24[ 1][ 9] = 1.90;
+ aaMtrev24[ 1][10] = 15.58; aaMtrev24[ 1][11] = 141.40; aaMtrev24[ 1][12] = 1.90; aaMtrev24[ 1][13] = 4.69; aaMtrev24[ 1][14] = 23.64;
+ aaMtrev24[ 1][15] = 6.04; aaMtrev24[ 1][16] = 2.08; aaMtrev24[ 1][17] = 21.95; aaMtrev24[ 1][18] = 1.90; aaMtrev24[ 1][19] = 7.64;
+ aaMtrev24[ 2][ 0] = 26.95; aaMtrev24[ 2][ 1] = 13.24; aaMtrev24[ 2][ 2] = 0.00; aaMtrev24[ 2][ 3] = 794.38; aaMtrev24[ 2][ 4] = 58.94;
+ aaMtrev24[ 2][ 5] = 173.56; aaMtrev24[ 2][ 6] = 63.05; aaMtrev24[ 2][ 7] = 53.30; aaMtrev24[ 2][ 8] = 496.13; aaMtrev24[ 2][ 9] = 27.10;
+ aaMtrev24[ 2][10] = 15.16; aaMtrev24[ 2][11] = 608.70; aaMtrev24[ 2][12] = 65.41; aaMtrev24[ 2][13] = 15.20; aaMtrev24[ 2][14] = 73.31;
+ aaMtrev24[ 2][15] = 494.39; aaMtrev24[ 2][16] = 238.46; aaMtrev24[ 2][17] = 10.68; aaMtrev24[ 2][18] = 191.36; aaMtrev24[ 2][19] = 1.90;
+ aaMtrev24[ 3][ 0] = 17.67; aaMtrev24[ 3][ 1] = 1.90; aaMtrev24[ 3][ 2] = 794.38; aaMtrev24[ 3][ 3] = 0.00; aaMtrev24[ 3][ 4] = 1.90;
+ aaMtrev24[ 3][ 5] = 55.28; aaMtrev24[ 3][ 6] = 583.55; aaMtrev24[ 3][ 7] = 56.77; aaMtrev24[ 3][ 8] = 113.99; aaMtrev24[ 3][ 9] = 4.34;
+ aaMtrev24[ 3][10] = 1.90; aaMtrev24[ 3][11] = 2.31; aaMtrev24[ 3][12] = 1.90; aaMtrev24[ 3][13] = 4.98; aaMtrev24[ 3][14] = 13.43;
+ aaMtrev24[ 3][15] = 69.02; aaMtrev24[ 3][16] = 28.01; aaMtrev24[ 3][17] = 19.86; aaMtrev24[ 3][18] = 21.21; aaMtrev24[ 3][19] = 1.90;
+ aaMtrev24[ 4][ 0] = 59.93; aaMtrev24[ 4][ 1] = 103.33; aaMtrev24[ 4][ 2] = 58.94; aaMtrev24[ 4][ 3] = 1.90; aaMtrev24[ 4][ 4] = 0.00;
+ aaMtrev24[ 4][ 5] = 75.24; aaMtrev24[ 4][ 6] = 1.90; aaMtrev24[ 4][ 7] = 30.71; aaMtrev24[ 4][ 8] = 141.49; aaMtrev24[ 4][ 9] = 62.73;
+ aaMtrev24[ 4][10] = 25.65; aaMtrev24[ 4][11] = 1.90; aaMtrev24[ 4][12] = 6.18; aaMtrev24[ 4][13] = 70.80; aaMtrev24[ 4][14] = 31.26;
+ aaMtrev24[ 4][15] = 277.05; aaMtrev24[ 4][16] = 179.97; aaMtrev24[ 4][17] = 33.60; aaMtrev24[ 4][18] = 254.77; aaMtrev24[ 4][19] = 1.90;
+ aaMtrev24[ 5][ 0] = 1.90; aaMtrev24[ 5][ 1] = 220.99; aaMtrev24[ 5][ 2] = 173.56; aaMtrev24[ 5][ 3] = 55.28; aaMtrev24[ 5][ 4] = 75.24;
+ aaMtrev24[ 5][ 5] = 0.00; aaMtrev24[ 5][ 6] = 313.56; aaMtrev24[ 5][ 7] = 6.75; aaMtrev24[ 5][ 8] = 582.40; aaMtrev24[ 5][ 9] = 8.34;
+ aaMtrev24[ 5][10] = 39.70; aaMtrev24[ 5][11] = 465.58; aaMtrev24[ 5][12] = 47.37; aaMtrev24[ 5][13] = 19.11; aaMtrev24[ 5][14] = 137.29;
+ aaMtrev24[ 5][15] = 54.11; aaMtrev24[ 5][16] = 94.93; aaMtrev24[ 5][17] = 1.90; aaMtrev24[ 5][18] = 38.82; aaMtrev24[ 5][19] = 19.00;
+ aaMtrev24[ 6][ 0] = 9.77; aaMtrev24[ 6][ 1] = 1.90; aaMtrev24[ 6][ 2] = 63.05; aaMtrev24[ 6][ 3] = 583.55; aaMtrev24[ 6][ 4] = 1.90;
+ aaMtrev24[ 6][ 5] = 313.56; aaMtrev24[ 6][ 6] = 0.00; aaMtrev24[ 6][ 7] = 28.28; aaMtrev24[ 6][ 8] = 49.12; aaMtrev24[ 6][ 9] = 3.31;
+ aaMtrev24[ 6][10] = 1.90; aaMtrev24[ 6][11] = 313.86; aaMtrev24[ 6][12] = 1.90; aaMtrev24[ 6][13] = 2.67; aaMtrev24[ 6][14] = 12.83;
+ aaMtrev24[ 6][15] = 54.71; aaMtrev24[ 6][16] = 14.82; aaMtrev24[ 6][17] = 1.90; aaMtrev24[ 6][18] = 13.12; aaMtrev24[ 6][19] = 21.14;
+ aaMtrev24[ 7][ 0] = 120.71; aaMtrev24[ 7][ 1] = 23.03; aaMtrev24[ 7][ 2] = 53.30; aaMtrev24[ 7][ 3] = 56.77; aaMtrev24[ 7][ 4] = 30.71;
+ aaMtrev24[ 7][ 5] = 6.75; aaMtrev24[ 7][ 6] = 28.28; aaMtrev24[ 7][ 7] = 0.00; aaMtrev24[ 7][ 8] = 1.90; aaMtrev24[ 7][ 9] = 5.98;
+ aaMtrev24[ 7][10] = 2.41; aaMtrev24[ 7][11] = 22.73; aaMtrev24[ 7][12] = 1.90; aaMtrev24[ 7][13] = 1.90; aaMtrev24[ 7][14] = 1.90;
+ aaMtrev24[ 7][15] = 125.93; aaMtrev24[ 7][16] = 11.17; aaMtrev24[ 7][17] = 10.92; aaMtrev24[ 7][18] = 3.21; aaMtrev24[ 7][19] = 2.53;
+ aaMtrev24[ 8][ 0] = 13.90; aaMtrev24[ 8][ 1] = 165.23; aaMtrev24[ 8][ 2] = 496.13; aaMtrev24[ 8][ 3] = 113.99; aaMtrev24[ 8][ 4] = 141.49;
+ aaMtrev24[ 8][ 5] = 582.40; aaMtrev24[ 8][ 6] = 49.12; aaMtrev24[ 8][ 7] = 1.90; aaMtrev24[ 8][ 8] = 0.00; aaMtrev24[ 8][ 9] = 12.26;
+ aaMtrev24[ 8][10] = 11.49; aaMtrev24[ 8][11] = 127.67; aaMtrev24[ 8][12] = 11.97; aaMtrev24[ 8][13] = 48.16; aaMtrev24[ 8][14] = 60.97;
+ aaMtrev24[ 8][15] = 77.46; aaMtrev24[ 8][16] = 44.78; aaMtrev24[ 8][17] = 7.08; aaMtrev24[ 8][18] = 670.14; aaMtrev24[ 8][19] = 1.90;
+ aaMtrev24[ 9][ 0] = 96.49; aaMtrev24[ 9][ 1] = 1.90; aaMtrev24[ 9][ 2] = 27.10; aaMtrev24[ 9][ 3] = 4.34; aaMtrev24[ 9][ 4] = 62.73;
+ aaMtrev24[ 9][ 5] = 8.34; aaMtrev24[ 9][ 6] = 3.31; aaMtrev24[ 9][ 7] = 5.98; aaMtrev24[ 9][ 8] = 12.26; aaMtrev24[ 9][ 9] = 0.00;
+ aaMtrev24[ 9][10] = 329.09; aaMtrev24[ 9][11] = 19.57; aaMtrev24[ 9][12] = 517.98; aaMtrev24[ 9][13] = 84.67; aaMtrev24[ 9][14] = 20.63;
+ aaMtrev24[ 9][15] = 47.70; aaMtrev24[ 9][16] = 368.43; aaMtrev24[ 9][17] = 1.90; aaMtrev24[ 9][18] = 25.01; aaMtrev24[ 9][19] =1222.94;
+ aaMtrev24[10][ 0] = 25.46; aaMtrev24[10][ 1] = 15.58; aaMtrev24[10][ 2] = 15.16; aaMtrev24[10][ 3] = 1.90; aaMtrev24[10][ 4] = 25.65;
+ aaMtrev24[10][ 5] = 39.70; aaMtrev24[10][ 6] = 1.90; aaMtrev24[10][ 7] = 2.41; aaMtrev24[10][ 8] = 11.49; aaMtrev24[10][ 9] = 329.09;
+ aaMtrev24[10][10] = 0.00; aaMtrev24[10][11] = 14.88; aaMtrev24[10][12] = 537.53; aaMtrev24[10][13] = 216.06; aaMtrev24[10][14] = 40.10;
+ aaMtrev24[10][15] = 73.61; aaMtrev24[10][16] = 126.40; aaMtrev24[10][17] = 32.44; aaMtrev24[10][18] = 44.15; aaMtrev24[10][19] = 91.67;
+ aaMtrev24[11][ 0] = 8.36; aaMtrev24[11][ 1] = 141.40; aaMtrev24[11][ 2] = 608.70; aaMtrev24[11][ 3] = 2.31; aaMtrev24[11][ 4] = 1.90;
+ aaMtrev24[11][ 5] = 465.58; aaMtrev24[11][ 6] = 313.86; aaMtrev24[11][ 7] = 22.73; aaMtrev24[11][ 8] = 127.67; aaMtrev24[11][ 9] = 19.57;
+ aaMtrev24[11][10] = 14.88; aaMtrev24[11][11] = 0.00; aaMtrev24[11][12] = 91.37; aaMtrev24[11][13] = 6.44; aaMtrev24[11][14] = 50.10;
+ aaMtrev24[11][15] = 105.79; aaMtrev24[11][16] = 136.33; aaMtrev24[11][17] = 24.00; aaMtrev24[11][18] = 51.17; aaMtrev24[11][19] = 1.90;
+ aaMtrev24[12][ 0] = 141.88; aaMtrev24[12][ 1] = 1.90; aaMtrev24[12][ 2] = 65.41; aaMtrev24[12][ 3] = 1.90; aaMtrev24[12][ 4] = 6.18;
+ aaMtrev24[12][ 5] = 47.37; aaMtrev24[12][ 6] = 1.90; aaMtrev24[12][ 7] = 1.90; aaMtrev24[12][ 8] = 11.97; aaMtrev24[12][ 9] = 517.98;
+ aaMtrev24[12][10] = 537.53; aaMtrev24[12][11] = 91.37; aaMtrev24[12][12] = 0.00; aaMtrev24[12][13] = 90.82; aaMtrev24[12][14] = 18.84;
+ aaMtrev24[12][15] = 111.16; aaMtrev24[12][16] = 528.17; aaMtrev24[12][17] = 21.71; aaMtrev24[12][18] = 39.96; aaMtrev24[12][19] = 387.54;
+ aaMtrev24[13][ 0] = 6.37; aaMtrev24[13][ 1] = 4.69; aaMtrev24[13][ 2] = 15.20; aaMtrev24[13][ 3] = 4.98; aaMtrev24[13][ 4] = 70.80;
+ aaMtrev24[13][ 5] = 19.11; aaMtrev24[13][ 6] = 2.67; aaMtrev24[13][ 7] = 1.90; aaMtrev24[13][ 8] = 48.16; aaMtrev24[13][ 9] = 84.67;
+ aaMtrev24[13][10] = 216.06; aaMtrev24[13][11] = 6.44; aaMtrev24[13][12] = 90.82; aaMtrev24[13][13] = 0.00; aaMtrev24[13][14] = 17.31;
+ aaMtrev24[13][15] = 64.29; aaMtrev24[13][16] = 33.85; aaMtrev24[13][17] = 7.84; aaMtrev24[13][18] = 465.58; aaMtrev24[13][19] = 6.35;
+ aaMtrev24[14][ 0] = 54.31; aaMtrev24[14][ 1] = 23.64; aaMtrev24[14][ 2] = 73.31; aaMtrev24[14][ 3] = 13.43; aaMtrev24[14][ 4] = 31.26;
+ aaMtrev24[14][ 5] = 137.29; aaMtrev24[14][ 6] = 12.83; aaMtrev24[14][ 7] = 1.90; aaMtrev24[14][ 8] = 60.97; aaMtrev24[14][ 9] = 20.63;
+ aaMtrev24[14][10] = 40.10; aaMtrev24[14][11] = 50.10; aaMtrev24[14][12] = 18.84; aaMtrev24[14][13] = 17.31; aaMtrev24[14][14] = 0.00;
+ aaMtrev24[14][15] = 169.90; aaMtrev24[14][16] = 128.22; aaMtrev24[14][17] = 4.21; aaMtrev24[14][18] = 16.21; aaMtrev24[14][19] = 8.23;
+ aaMtrev24[15][ 0] = 387.86; aaMtrev24[15][ 1] = 6.04; aaMtrev24[15][ 2] = 494.39; aaMtrev24[15][ 3] = 69.02; aaMtrev24[15][ 4] = 277.05;
+ aaMtrev24[15][ 5] = 54.11; aaMtrev24[15][ 6] = 54.71; aaMtrev24[15][ 7] = 125.93; aaMtrev24[15][ 8] = 77.46; aaMtrev24[15][ 9] = 47.70;
+ aaMtrev24[15][10] = 73.61; aaMtrev24[15][11] = 105.79; aaMtrev24[15][12] = 111.16; aaMtrev24[15][13] = 64.29; aaMtrev24[15][14] = 169.90;
+ aaMtrev24[15][15] = 0.00; aaMtrev24[15][16] = 597.21; aaMtrev24[15][17] = 38.58; aaMtrev24[15][18] = 64.92; aaMtrev24[15][19] = 1.90;
+ aaMtrev24[16][ 0] = 480.72; aaMtrev24[16][ 1] = 2.08; aaMtrev24[16][ 2] = 238.46; aaMtrev24[16][ 3] = 28.01; aaMtrev24[16][ 4] = 179.97;
+ aaMtrev24[16][ 5] = 94.93; aaMtrev24[16][ 6] = 14.82; aaMtrev24[16][ 7] = 11.17; aaMtrev24[16][ 8] = 44.78; aaMtrev24[16][ 9] = 368.43;
+ aaMtrev24[16][10] = 126.40; aaMtrev24[16][11] = 136.33; aaMtrev24[16][12] = 528.17; aaMtrev24[16][13] = 33.85; aaMtrev24[16][14] = 128.22;
+ aaMtrev24[16][15] = 597.21; aaMtrev24[16][16] = 0.00; aaMtrev24[16][17] = 9.99; aaMtrev24[16][18] = 38.73; aaMtrev24[16][19] = 204.54;
+ aaMtrev24[17][ 0] = 1.90; aaMtrev24[17][ 1] = 21.95; aaMtrev24[17][ 2] = 10.68; aaMtrev24[17][ 3] = 19.86; aaMtrev24[17][ 4] = 33.60;
+ aaMtrev24[17][ 5] = 1.90; aaMtrev24[17][ 6] = 1.90; aaMtrev24[17][ 7] = 10.92; aaMtrev24[17][ 8] = 7.08; aaMtrev24[17][ 9] = 1.90;
+ aaMtrev24[17][10] = 32.44; aaMtrev24[17][11] = 24.00; aaMtrev24[17][12] = 21.71; aaMtrev24[17][13] = 7.84; aaMtrev24[17][14] = 4.21;
+ aaMtrev24[17][15] = 38.58; aaMtrev24[17][16] = 9.99; aaMtrev24[17][17] = 0.00; aaMtrev24[17][18] = 26.25; aaMtrev24[17][19] = 5.37;
+ aaMtrev24[18][ 0] = 6.48; aaMtrev24[18][ 1] = 1.90; aaMtrev24[18][ 2] = 191.36; aaMtrev24[18][ 3] = 21.21; aaMtrev24[18][ 4] = 254.77;
+ aaMtrev24[18][ 5] = 38.82; aaMtrev24[18][ 6] = 13.12; aaMtrev24[18][ 7] = 3.21; aaMtrev24[18][ 8] = 670.14; aaMtrev24[18][ 9] = 25.01;
+ aaMtrev24[18][10] = 44.15; aaMtrev24[18][11] = 51.17; aaMtrev24[18][12] = 39.96; aaMtrev24[18][13] = 465.58; aaMtrev24[18][14] = 16.21;
+ aaMtrev24[18][15] = 64.92; aaMtrev24[18][16] = 38.73; aaMtrev24[18][17] = 26.25; aaMtrev24[18][18] = 0.00; aaMtrev24[18][19] = 1.90;
+ aaMtrev24[19][ 0] = 195.06; aaMtrev24[19][ 1] = 7.64; aaMtrev24[19][ 2] = 1.90; aaMtrev24[19][ 3] = 1.90; aaMtrev24[19][ 4] = 1.90;
+ aaMtrev24[19][ 5] = 19.00; aaMtrev24[19][ 6] = 21.14; aaMtrev24[19][ 7] = 2.53; aaMtrev24[19][ 8] = 1.90; aaMtrev24[19][ 9] =1222.94;
+ aaMtrev24[19][10] = 91.67; aaMtrev24[19][11] = 1.90; aaMtrev24[19][12] = 387.54; aaMtrev24[19][13] = 6.35; aaMtrev24[19][14] = 8.23;
+ aaMtrev24[19][15] = 1.90; aaMtrev24[19][16] = 204.54; aaMtrev24[19][17] = 5.37; aaMtrev24[19][18] = 1.90; aaMtrev24[19][19] = 0.00;
+
+ mtrev24Pi[ 0] = 0.072;
+ mtrev24Pi[ 1] = 0.019;
+ mtrev24Pi[ 2] = 0.039;
+ mtrev24Pi[ 3] = 0.019;
+ mtrev24Pi[ 4] = 0.006;
+ mtrev24Pi[ 5] = 0.025;
+ mtrev24Pi[ 6] = 0.024;
+ mtrev24Pi[ 7] = 0.056;
+ mtrev24Pi[ 8] = 0.028;
+ mtrev24Pi[ 9] = 0.088;
+ mtrev24Pi[10] = 0.168;
+ mtrev24Pi[11] = 0.023;
+ mtrev24Pi[12] = 0.054;
+ mtrev24Pi[13] = 0.061;
+ mtrev24Pi[14] = 0.054;
+ mtrev24Pi[15] = 0.072;
+ mtrev24Pi[16] = 0.086;
+ mtrev24Pi[17] = 0.029;
+ mtrev24Pi[18] = 0.033;
+ mtrev24Pi[19] = 0.043;
+
+ /* mtmam */
+ aaMtmam[ 0][ 0] = 0; aaMtmam[ 0][ 1] = 32; aaMtmam[ 0][ 2] = 2; aaMtmam[ 0][ 3] = 11; aaMtmam[ 0][ 4] = 0;
+ aaMtmam[ 0][ 5] = 0; aaMtmam[ 0][ 6] = 0; aaMtmam[ 0][ 7] = 78; aaMtmam[ 0][ 8] = 8; aaMtmam[ 0][ 9] = 75;
+ aaMtmam[ 0][10] = 21; aaMtmam[ 0][11] = 0; aaMtmam[ 0][12] = 76; aaMtmam[ 0][13] = 0; aaMtmam[ 0][14] = 53;
+ aaMtmam[ 0][15] = 342; aaMtmam[ 0][16] = 681; aaMtmam[ 0][17] = 5; aaMtmam[ 0][18] = 0; aaMtmam[ 0][19] = 398;
+ aaMtmam[ 1][ 0] = 32; aaMtmam[ 1][ 1] = 0; aaMtmam[ 1][ 2] = 4; aaMtmam[ 1][ 3] = 0; aaMtmam[ 1][ 4] = 186;
+ aaMtmam[ 1][ 5] = 246; aaMtmam[ 1][ 6] = 0; aaMtmam[ 1][ 7] = 18; aaMtmam[ 1][ 8] = 232; aaMtmam[ 1][ 9] = 0;
+ aaMtmam[ 1][10] = 6; aaMtmam[ 1][11] = 50; aaMtmam[ 1][12] = 0; aaMtmam[ 1][13] = 0; aaMtmam[ 1][14] = 9;
+ aaMtmam[ 1][15] = 3; aaMtmam[ 1][16] = 0; aaMtmam[ 1][17] = 16; aaMtmam[ 1][18] = 0; aaMtmam[ 1][19] = 0;
+ aaMtmam[ 2][ 0] = 2; aaMtmam[ 2][ 1] = 4; aaMtmam[ 2][ 2] = 0; aaMtmam[ 2][ 3] = 864; aaMtmam[ 2][ 4] = 0;
+ aaMtmam[ 2][ 5] = 8; aaMtmam[ 2][ 6] = 0; aaMtmam[ 2][ 7] = 47; aaMtmam[ 2][ 8] = 458; aaMtmam[ 2][ 9] = 19;
+ aaMtmam[ 2][10] = 0; aaMtmam[ 2][11] = 408; aaMtmam[ 2][12] = 21; aaMtmam[ 2][13] = 6; aaMtmam[ 2][14] = 33;
+ aaMtmam[ 2][15] = 446; aaMtmam[ 2][16] = 110; aaMtmam[ 2][17] = 6; aaMtmam[ 2][18] = 156; aaMtmam[ 2][19] = 0;
+ aaMtmam[ 3][ 0] = 11; aaMtmam[ 3][ 1] = 0; aaMtmam[ 3][ 2] = 864; aaMtmam[ 3][ 3] = 0; aaMtmam[ 3][ 4] = 0;
+ aaMtmam[ 3][ 5] = 49; aaMtmam[ 3][ 6] = 569; aaMtmam[ 3][ 7] = 79; aaMtmam[ 3][ 8] = 11; aaMtmam[ 3][ 9] = 0;
+ aaMtmam[ 3][10] = 0; aaMtmam[ 3][11] = 0; aaMtmam[ 3][12] = 0; aaMtmam[ 3][13] = 5; aaMtmam[ 3][14] = 2;
+ aaMtmam[ 3][15] = 16; aaMtmam[ 3][16] = 0; aaMtmam[ 3][17] = 0; aaMtmam[ 3][18] = 0; aaMtmam[ 3][19] = 10;
+ aaMtmam[ 4][ 0] = 0; aaMtmam[ 4][ 1] = 186; aaMtmam[ 4][ 2] = 0; aaMtmam[ 4][ 3] = 0; aaMtmam[ 4][ 4] = 0;
+ aaMtmam[ 4][ 5] = 0; aaMtmam[ 4][ 6] = 0; aaMtmam[ 4][ 7] = 0; aaMtmam[ 4][ 8] = 305; aaMtmam[ 4][ 9] = 41;
+ aaMtmam[ 4][10] = 27; aaMtmam[ 4][11] = 0; aaMtmam[ 4][12] = 0; aaMtmam[ 4][13] = 7; aaMtmam[ 4][14] = 0;
+ aaMtmam[ 4][15] = 347; aaMtmam[ 4][16] = 114; aaMtmam[ 4][17] = 65; aaMtmam[ 4][18] = 530; aaMtmam[ 4][19] = 0;
+ aaMtmam[ 5][ 0] = 0; aaMtmam[ 5][ 1] = 246; aaMtmam[ 5][ 2] = 8; aaMtmam[ 5][ 3] = 49; aaMtmam[ 5][ 4] = 0;
+ aaMtmam[ 5][ 5] = 0; aaMtmam[ 5][ 6] = 274; aaMtmam[ 5][ 7] = 0; aaMtmam[ 5][ 8] = 550; aaMtmam[ 5][ 9] = 0;
+ aaMtmam[ 5][10] = 20; aaMtmam[ 5][11] = 242; aaMtmam[ 5][12] = 22; aaMtmam[ 5][13] = 0; aaMtmam[ 5][14] = 51;
+ aaMtmam[ 5][15] = 30; aaMtmam[ 5][16] = 0; aaMtmam[ 5][17] = 0; aaMtmam[ 5][18] = 54; aaMtmam[ 5][19] = 33;
+ aaMtmam[ 6][ 0] = 0; aaMtmam[ 6][ 1] = 0; aaMtmam[ 6][ 2] = 0; aaMtmam[ 6][ 3] = 569; aaMtmam[ 6][ 4] = 0;
+ aaMtmam[ 6][ 5] = 274; aaMtmam[ 6][ 6] = 0; aaMtmam[ 6][ 7] = 22; aaMtmam[ 6][ 8] = 22; aaMtmam[ 6][ 9] = 0;
+ aaMtmam[ 6][10] = 0; aaMtmam[ 6][11] = 215; aaMtmam[ 6][12] = 0; aaMtmam[ 6][13] = 0; aaMtmam[ 6][14] = 0;
+ aaMtmam[ 6][15] = 21; aaMtmam[ 6][16] = 4; aaMtmam[ 6][17] = 0; aaMtmam[ 6][18] = 0; aaMtmam[ 6][19] = 20;
+ aaMtmam[ 7][ 0] = 78; aaMtmam[ 7][ 1] = 18; aaMtmam[ 7][ 2] = 47; aaMtmam[ 7][ 3] = 79; aaMtmam[ 7][ 4] = 0;
+ aaMtmam[ 7][ 5] = 0; aaMtmam[ 7][ 6] = 22; aaMtmam[ 7][ 7] = 0; aaMtmam[ 7][ 8] = 0; aaMtmam[ 7][ 9] = 0;
+ aaMtmam[ 7][10] = 0; aaMtmam[ 7][11] = 0; aaMtmam[ 7][12] = 0; aaMtmam[ 7][13] = 0; aaMtmam[ 7][14] = 0;
+ aaMtmam[ 7][15] = 112; aaMtmam[ 7][16] = 0; aaMtmam[ 7][17] = 0; aaMtmam[ 7][18] = 1; aaMtmam[ 7][19] = 5;
+ aaMtmam[ 8][ 0] = 8; aaMtmam[ 8][ 1] = 232; aaMtmam[ 8][ 2] = 458; aaMtmam[ 8][ 3] = 11; aaMtmam[ 8][ 4] = 305;
+ aaMtmam[ 8][ 5] = 550; aaMtmam[ 8][ 6] = 22; aaMtmam[ 8][ 7] = 0; aaMtmam[ 8][ 8] = 0; aaMtmam[ 8][ 9] = 0;
+ aaMtmam[ 8][10] = 26; aaMtmam[ 8][11] = 0; aaMtmam[ 8][12] = 0; aaMtmam[ 8][13] = 0; aaMtmam[ 8][14] = 53;
+ aaMtmam[ 8][15] = 20; aaMtmam[ 8][16] = 1; aaMtmam[ 8][17] = 0; aaMtmam[ 8][18] =1525; aaMtmam[ 8][19] = 0;
+ aaMtmam[ 9][ 0] = 75; aaMtmam[ 9][ 1] = 0; aaMtmam[ 9][ 2] = 19; aaMtmam[ 9][ 3] = 0; aaMtmam[ 9][ 4] = 41;
+ aaMtmam[ 9][ 5] = 0; aaMtmam[ 9][ 6] = 0; aaMtmam[ 9][ 7] = 0; aaMtmam[ 9][ 8] = 0; aaMtmam[ 9][ 9] = 0;
+ aaMtmam[ 9][10] = 232; aaMtmam[ 9][11] = 6; aaMtmam[ 9][12] = 378; aaMtmam[ 9][13] = 57; aaMtmam[ 9][14] = 5;
+ aaMtmam[ 9][15] = 0; aaMtmam[ 9][16] = 360; aaMtmam[ 9][17] = 0; aaMtmam[ 9][18] = 16; aaMtmam[ 9][19] =2220;
+ aaMtmam[10][ 0] = 21; aaMtmam[10][ 1] = 6; aaMtmam[10][ 2] = 0; aaMtmam[10][ 3] = 0; aaMtmam[10][ 4] = 27;
+ aaMtmam[10][ 5] = 20; aaMtmam[10][ 6] = 0; aaMtmam[10][ 7] = 0; aaMtmam[10][ 8] = 26; aaMtmam[10][ 9] = 232;
+ aaMtmam[10][10] = 0; aaMtmam[10][11] = 4; aaMtmam[10][12] = 609; aaMtmam[10][13] = 246; aaMtmam[10][14] = 43;
+ aaMtmam[10][15] = 74; aaMtmam[10][16] = 34; aaMtmam[10][17] = 12; aaMtmam[10][18] = 25; aaMtmam[10][19] = 100;
+ aaMtmam[11][ 0] = 0; aaMtmam[11][ 1] = 50; aaMtmam[11][ 2] = 408; aaMtmam[11][ 3] = 0; aaMtmam[11][ 4] = 0;
+ aaMtmam[11][ 5] = 242; aaMtmam[11][ 6] = 215; aaMtmam[11][ 7] = 0; aaMtmam[11][ 8] = 0; aaMtmam[11][ 9] = 6;
+ aaMtmam[11][10] = 4; aaMtmam[11][11] = 0; aaMtmam[11][12] = 59; aaMtmam[11][13] = 0; aaMtmam[11][14] = 18;
+ aaMtmam[11][15] = 65; aaMtmam[11][16] = 50; aaMtmam[11][17] = 0; aaMtmam[11][18] = 67; aaMtmam[11][19] = 0;
+ aaMtmam[12][ 0] = 76; aaMtmam[12][ 1] = 0; aaMtmam[12][ 2] = 21; aaMtmam[12][ 3] = 0; aaMtmam[12][ 4] = 0;
+ aaMtmam[12][ 5] = 22; aaMtmam[12][ 6] = 0; aaMtmam[12][ 7] = 0; aaMtmam[12][ 8] = 0; aaMtmam[12][ 9] = 378;
+ aaMtmam[12][10] = 609; aaMtmam[12][11] = 59; aaMtmam[12][12] = 0; aaMtmam[12][13] = 11; aaMtmam[12][14] = 0;
+ aaMtmam[12][15] = 47; aaMtmam[12][16] = 691; aaMtmam[12][17] = 13; aaMtmam[12][18] = 0; aaMtmam[12][19] = 832;
+ aaMtmam[13][ 0] = 0; aaMtmam[13][ 1] = 0; aaMtmam[13][ 2] = 6; aaMtmam[13][ 3] = 5; aaMtmam[13][ 4] = 7;
+ aaMtmam[13][ 5] = 0; aaMtmam[13][ 6] = 0; aaMtmam[13][ 7] = 0; aaMtmam[13][ 8] = 0; aaMtmam[13][ 9] = 57;
+ aaMtmam[13][10] = 246; aaMtmam[13][11] = 0; aaMtmam[13][12] = 11; aaMtmam[13][13] = 0; aaMtmam[13][14] = 17;
+ aaMtmam[13][15] = 90; aaMtmam[13][16] = 8; aaMtmam[13][17] = 0; aaMtmam[13][18] = 682; aaMtmam[13][19] = 6;
+ aaMtmam[14][ 0] = 53; aaMtmam[14][ 1] = 9; aaMtmam[14][ 2] = 33; aaMtmam[14][ 3] = 2; aaMtmam[14][ 4] = 0;
+ aaMtmam[14][ 5] = 51; aaMtmam[14][ 6] = 0; aaMtmam[14][ 7] = 0; aaMtmam[14][ 8] = 53; aaMtmam[14][ 9] = 5;
+ aaMtmam[14][10] = 43; aaMtmam[14][11] = 18; aaMtmam[14][12] = 0; aaMtmam[14][13] = 17; aaMtmam[14][14] = 0;
+ aaMtmam[14][15] = 202; aaMtmam[14][16] = 78; aaMtmam[14][17] = 7; aaMtmam[14][18] = 8; aaMtmam[14][19] = 0;
+ aaMtmam[15][ 0] = 342; aaMtmam[15][ 1] = 3; aaMtmam[15][ 2] = 446; aaMtmam[15][ 3] = 16; aaMtmam[15][ 4] = 347;
+ aaMtmam[15][ 5] = 30; aaMtmam[15][ 6] = 21; aaMtmam[15][ 7] = 112; aaMtmam[15][ 8] = 20; aaMtmam[15][ 9] = 0;
+ aaMtmam[15][10] = 74; aaMtmam[15][11] = 65; aaMtmam[15][12] = 47; aaMtmam[15][13] = 90; aaMtmam[15][14] = 202;
+ aaMtmam[15][15] = 0; aaMtmam[15][16] = 614; aaMtmam[15][17] = 17; aaMtmam[15][18] = 107; aaMtmam[15][19] = 0;
+ aaMtmam[16][ 0] = 681; aaMtmam[16][ 1] = 0; aaMtmam[16][ 2] = 110; aaMtmam[16][ 3] = 0; aaMtmam[16][ 4] = 114;
+ aaMtmam[16][ 5] = 0; aaMtmam[16][ 6] = 4; aaMtmam[16][ 7] = 0; aaMtmam[16][ 8] = 1; aaMtmam[16][ 9] = 360;
+ aaMtmam[16][10] = 34; aaMtmam[16][11] = 50; aaMtmam[16][12] = 691; aaMtmam[16][13] = 8; aaMtmam[16][14] = 78;
+ aaMtmam[16][15] = 614; aaMtmam[16][16] = 0; aaMtmam[16][17] = 0; aaMtmam[16][18] = 0; aaMtmam[16][19] = 237;
+ aaMtmam[17][ 0] = 5; aaMtmam[17][ 1] = 16; aaMtmam[17][ 2] = 6; aaMtmam[17][ 3] = 0; aaMtmam[17][ 4] = 65;
+ aaMtmam[17][ 5] = 0; aaMtmam[17][ 6] = 0; aaMtmam[17][ 7] = 0; aaMtmam[17][ 8] = 0; aaMtmam[17][ 9] = 0;
+ aaMtmam[17][10] = 12; aaMtmam[17][11] = 0; aaMtmam[17][12] = 13; aaMtmam[17][13] = 0; aaMtmam[17][14] = 7;
+ aaMtmam[17][15] = 17; aaMtmam[17][16] = 0; aaMtmam[17][17] = 0; aaMtmam[17][18] = 14; aaMtmam[17][19] = 0;
+ aaMtmam[18][ 0] = 0; aaMtmam[18][ 1] = 0; aaMtmam[18][ 2] = 156; aaMtmam[18][ 3] = 0; aaMtmam[18][ 4] = 530;
+ aaMtmam[18][ 5] = 54; aaMtmam[18][ 6] = 0; aaMtmam[18][ 7] = 1; aaMtmam[18][ 8] =1525; aaMtmam[18][ 9] = 16;
+ aaMtmam[18][10] = 25; aaMtmam[18][11] = 67; aaMtmam[18][12] = 0; aaMtmam[18][13] = 682; aaMtmam[18][14] = 8;
+ aaMtmam[18][15] = 107; aaMtmam[18][16] = 0; aaMtmam[18][17] = 14; aaMtmam[18][18] = 0; aaMtmam[18][19] = 0;
+ aaMtmam[19][ 0] = 398; aaMtmam[19][ 1] = 0; aaMtmam[19][ 2] = 0; aaMtmam[19][ 3] = 10; aaMtmam[19][ 4] = 0;
+ aaMtmam[19][ 5] = 33; aaMtmam[19][ 6] = 20; aaMtmam[19][ 7] = 5; aaMtmam[19][ 8] = 0; aaMtmam[19][ 9] =2220;
+ aaMtmam[19][10] = 100; aaMtmam[19][11] = 0; aaMtmam[19][12] = 832; aaMtmam[19][13] = 6; aaMtmam[19][14] = 0;
+ aaMtmam[19][15] = 0; aaMtmam[19][16] = 237; aaMtmam[19][17] = 0; aaMtmam[19][18] = 0; aaMtmam[19][19] = 0;
+
+ mtmamPi[ 0] = 0.0692;
+ mtmamPi[ 1] = 0.0184;
+ mtmamPi[ 2] = 0.0400;
+ mtmamPi[ 3] = 0.0186;
+ mtmamPi[ 4] = 0.0065;
+ mtmamPi[ 5] = 0.0238;
+ mtmamPi[ 6] = 0.0236;
+ mtmamPi[ 7] = 0.0557;
+ mtmamPi[ 8] = 0.0277;
+ mtmamPi[ 9] = 0.0905;
+ mtmamPi[10] = 0.1675;
+ mtmamPi[11] = 0.0221;
+ mtmamPi[12] = 0.0561;
+ mtmamPi[13] = 0.0611;
+ mtmamPi[14] = 0.0536;
+ mtmamPi[15] = 0.0725;
+ mtmamPi[16] = 0.0870;
+ mtmamPi[17] = 0.0293;
+ mtmamPi[18] = 0.0340;
+ mtmamPi[19] = 0.0428;
+
+ /* rtRev */
+ aartREV[ 0][ 0] = 0; aartREV[ 1][ 0] = 34; aartREV[ 2][ 0] = 51; aartREV[ 3][ 0] = 10; aartREV[ 4][ 0] = 439;
+ aartREV[ 5][ 0] = 32; aartREV[ 6][ 0] = 81; aartREV[ 7][ 0] = 135; aartREV[ 8][ 0] = 30; aartREV[ 9][ 0] = 1;
+ aartREV[10][ 0] = 45; aartREV[11][ 0] = 38; aartREV[12][ 0] = 235; aartREV[13][ 0] = 1; aartREV[14][ 0] = 97;
+ aartREV[15][ 0] = 460; aartREV[16][ 0] = 258; aartREV[17][ 0] = 5; aartREV[18][ 0] = 55; aartREV[19][ 0] = 197;
+ aartREV[ 0][ 1] = 34; aartREV[ 1][ 1] = 0; aartREV[ 2][ 1] = 35; aartREV[ 3][ 1] = 30; aartREV[ 4][ 1] = 92;
+ aartREV[ 5][ 1] = 221; aartREV[ 6][ 1] = 10; aartREV[ 7][ 1] = 41; aartREV[ 8][ 1] = 90; aartREV[ 9][ 1] = 24;
+ aartREV[10][ 1] = 18; aartREV[11][ 1] = 593; aartREV[12][ 1] = 57; aartREV[13][ 1] = 7; aartREV[14][ 1] = 24;
+ aartREV[15][ 1] = 102; aartREV[16][ 1] = 64; aartREV[17][ 1] = 13; aartREV[18][ 1] = 47; aartREV[19][ 1] = 29;
+ aartREV[ 0][ 2] = 51; aartREV[ 1][ 2] = 35; aartREV[ 2][ 2] = 0; aartREV[ 3][ 2] = 384; aartREV[ 4][ 2] = 128;
+ aartREV[ 5][ 2] = 236; aartREV[ 6][ 2] = 79; aartREV[ 7][ 2] = 94; aartREV[ 8][ 2] = 320; aartREV[ 9][ 2] = 35;
+ aartREV[10][ 2] = 15; aartREV[11][ 2] = 123; aartREV[12][ 2] = 1; aartREV[13][ 2] = 49; aartREV[14][ 2] = 33;
+ aartREV[15][ 2] = 294; aartREV[16][ 2] = 148; aartREV[17][ 2] = 16; aartREV[18][ 2] = 28; aartREV[19][ 2] = 21;
+ aartREV[ 0][ 3] = 10; aartREV[ 1][ 3] = 30; aartREV[ 2][ 3] = 384; aartREV[ 3][ 3] = 0; aartREV[ 4][ 3] = 1;
+ aartREV[ 5][ 3] = 78; aartREV[ 6][ 3] = 542; aartREV[ 7][ 3] = 61; aartREV[ 8][ 3] = 91; aartREV[ 9][ 3] = 1;
+ aartREV[10][ 3] = 5; aartREV[11][ 3] = 20; aartREV[12][ 3] = 1; aartREV[13][ 3] = 1; aartREV[14][ 3] = 55;
+ aartREV[15][ 3] = 136; aartREV[16][ 3] = 55; aartREV[17][ 3] = 1; aartREV[18][ 3] = 1; aartREV[19][ 3] = 6;
+ aartREV[ 0][ 4] = 439; aartREV[ 1][ 4] = 92; aartREV[ 2][ 4] = 128; aartREV[ 3][ 4] = 1; aartREV[ 4][ 4] = 0;
+ aartREV[ 5][ 4] = 70; aartREV[ 6][ 4] = 1; aartREV[ 7][ 4] = 48; aartREV[ 8][ 4] = 124; aartREV[ 9][ 4] = 104;
+ aartREV[10][ 4] = 110; aartREV[11][ 4] = 16; aartREV[12][ 4] = 156; aartREV[13][ 4] = 70; aartREV[14][ 4] = 1;
+ aartREV[15][ 4] = 75; aartREV[16][ 4] = 117; aartREV[17][ 4] = 55; aartREV[18][ 4] = 131; aartREV[19][ 4] = 295;
+ aartREV[ 0][ 5] = 32; aartREV[ 1][ 5] = 221; aartREV[ 2][ 5] = 236; aartREV[ 3][ 5] = 78; aartREV[ 4][ 5] = 70;
+ aartREV[ 5][ 5] = 0; aartREV[ 6][ 5] = 372; aartREV[ 7][ 5] = 18; aartREV[ 8][ 5] = 387; aartREV[ 9][ 5] = 33;
+ aartREV[10][ 5] = 54; aartREV[11][ 5] = 309; aartREV[12][ 5] = 158; aartREV[13][ 5] = 1; aartREV[14][ 5] = 68;
+ aartREV[15][ 5] = 225; aartREV[16][ 5] = 146; aartREV[17][ 5] = 10; aartREV[18][ 5] = 45; aartREV[19][ 5] = 36;
+ aartREV[ 0][ 6] = 81; aartREV[ 1][ 6] = 10; aartREV[ 2][ 6] = 79; aartREV[ 3][ 6] = 542; aartREV[ 4][ 6] = 1;
+ aartREV[ 5][ 6] = 372; aartREV[ 6][ 6] = 0; aartREV[ 7][ 6] = 70; aartREV[ 8][ 6] = 34; aartREV[ 9][ 6] = 1;
+ aartREV[10][ 6] = 21; aartREV[11][ 6] = 141; aartREV[12][ 6] = 1; aartREV[13][ 6] = 1; aartREV[14][ 6] = 52;
+ aartREV[15][ 6] = 95; aartREV[16][ 6] = 82; aartREV[17][ 6] = 17; aartREV[18][ 6] = 1; aartREV[19][ 6] = 35;
+ aartREV[ 0][ 7] = 135; aartREV[ 1][ 7] = 41; aartREV[ 2][ 7] = 94; aartREV[ 3][ 7] = 61; aartREV[ 4][ 7] = 48;
+ aartREV[ 5][ 7] = 18; aartREV[ 6][ 7] = 70; aartREV[ 7][ 7] = 0; aartREV[ 8][ 7] = 68; aartREV[ 9][ 7] = 1;
+ aartREV[10][ 7] = 3; aartREV[11][ 7] = 30; aartREV[12][ 7] = 37; aartREV[13][ 7] = 7; aartREV[14][ 7] = 17;
+ aartREV[15][ 7] = 152; aartREV[16][ 7] = 7; aartREV[17][ 7] = 23; aartREV[18][ 7] = 21; aartREV[19][ 7] = 3;
+ aartREV[ 0][ 8] = 30; aartREV[ 1][ 8] = 90; aartREV[ 2][ 8] = 320; aartREV[ 3][ 8] = 91; aartREV[ 4][ 8] = 124;
+ aartREV[ 5][ 8] = 387; aartREV[ 6][ 8] = 34; aartREV[ 7][ 8] = 68; aartREV[ 8][ 8] = 0; aartREV[ 9][ 8] = 34;
+ aartREV[10][ 8] = 51; aartREV[11][ 8] = 76; aartREV[12][ 8] = 116; aartREV[13][ 8] = 141; aartREV[14][ 8] = 44;
+ aartREV[15][ 8] = 183; aartREV[16][ 8] = 49; aartREV[17][ 8] = 48; aartREV[18][ 8] = 307; aartREV[19][ 8] = 1;
+ aartREV[ 0][ 9] = 1; aartREV[ 1][ 9] = 24; aartREV[ 2][ 9] = 35; aartREV[ 3][ 9] = 1; aartREV[ 4][ 9] = 104;
+ aartREV[ 5][ 9] = 33; aartREV[ 6][ 9] = 1; aartREV[ 7][ 9] = 1; aartREV[ 8][ 9] = 34; aartREV[ 9][ 9] = 0;
+ aartREV[10][ 9] = 385; aartREV[11][ 9] = 34; aartREV[12][ 9] = 375; aartREV[13][ 9] = 64; aartREV[14][ 9] = 10;
+ aartREV[15][ 9] = 4; aartREV[16][ 9] = 72; aartREV[17][ 9] = 39; aartREV[18][ 9] = 26; aartREV[19][ 9] =1048;
+ aartREV[ 0][10] = 45; aartREV[ 1][10] = 18; aartREV[ 2][10] = 15; aartREV[ 3][10] = 5; aartREV[ 4][10] = 110;
+ aartREV[ 5][10] = 54; aartREV[ 6][10] = 21; aartREV[ 7][10] = 3; aartREV[ 8][10] = 51; aartREV[ 9][10] = 385;
+ aartREV[10][10] = 0; aartREV[11][10] = 23; aartREV[12][10] = 581; aartREV[13][10] = 179; aartREV[14][10] = 22;
+ aartREV[15][10] = 24; aartREV[16][10] = 25; aartREV[17][10] = 47; aartREV[18][10] = 64; aartREV[19][10] = 112;
+ aartREV[ 0][11] = 38; aartREV[ 1][11] = 593; aartREV[ 2][11] = 123; aartREV[ 3][11] = 20; aartREV[ 4][11] = 16;
+ aartREV[ 5][11] = 309; aartREV[ 6][11] = 141; aartREV[ 7][11] = 30; aartREV[ 8][11] = 76; aartREV[ 9][11] = 34;
+ aartREV[10][11] = 23; aartREV[11][11] = 0; aartREV[12][11] = 134; aartREV[13][11] = 14; aartREV[14][11] = 43;
+ aartREV[15][11] = 77; aartREV[16][11] = 110; aartREV[17][11] = 6; aartREV[18][11] = 1; aartREV[19][11] = 19;
+ aartREV[ 0][12] = 235; aartREV[ 1][12] = 57; aartREV[ 2][12] = 1; aartREV[ 3][12] = 1; aartREV[ 4][12] = 156;
+ aartREV[ 5][12] = 158; aartREV[ 6][12] = 1; aartREV[ 7][12] = 37; aartREV[ 8][12] = 116; aartREV[ 9][12] = 375;
+ aartREV[10][12] = 581; aartREV[11][12] = 134; aartREV[12][12] = 0; aartREV[13][12] = 247; aartREV[14][12] = 1;
+ aartREV[15][12] = 1; aartREV[16][12] = 131; aartREV[17][12] = 111; aartREV[18][12] = 74; aartREV[19][12] = 236;
+ aartREV[ 0][13] = 1; aartREV[ 1][13] = 7; aartREV[ 2][13] = 49; aartREV[ 3][13] = 1; aartREV[ 4][13] = 70;
+ aartREV[ 5][13] = 1; aartREV[ 6][13] = 1; aartREV[ 7][13] = 7; aartREV[ 8][13] = 141; aartREV[ 9][13] = 64;
+ aartREV[10][13] = 179; aartREV[11][13] = 14; aartREV[12][13] = 247; aartREV[13][13] = 0; aartREV[14][13] = 11;
+ aartREV[15][13] = 20; aartREV[16][13] = 69; aartREV[17][13] = 182; aartREV[18][13] =1017; aartREV[19][13] = 92;
+ aartREV[ 0][14] = 97; aartREV[ 1][14] = 24; aartREV[ 2][14] = 33; aartREV[ 3][14] = 55; aartREV[ 4][14] = 1;
+ aartREV[ 5][14] = 68; aartREV[ 6][14] = 52; aartREV[ 7][14] = 17; aartREV[ 8][14] = 44; aartREV[ 9][14] = 10;
+ aartREV[10][14] = 22; aartREV[11][14] = 43; aartREV[12][14] = 1; aartREV[13][14] = 11; aartREV[14][14] = 0;
+ aartREV[15][14] = 134; aartREV[16][14] = 62; aartREV[17][14] = 9; aartREV[18][14] = 14; aartREV[19][14] = 25;
+ aartREV[ 0][15] = 460; aartREV[ 1][15] = 102; aartREV[ 2][15] = 294; aartREV[ 3][15] = 136; aartREV[ 4][15] = 75;
+ aartREV[ 5][15] = 225; aartREV[ 6][15] = 95; aartREV[ 7][15] = 152; aartREV[ 8][15] = 183; aartREV[ 9][15] = 4;
+ aartREV[10][15] = 24; aartREV[11][15] = 77; aartREV[12][15] = 1; aartREV[13][15] = 20; aartREV[14][15] = 134;
+ aartREV[15][15] = 0; aartREV[16][15] = 671; aartREV[17][15] = 14; aartREV[18][15] = 31; aartREV[19][15] = 39;
+ aartREV[ 0][16] = 258; aartREV[ 1][16] = 64; aartREV[ 2][16] = 148; aartREV[ 3][16] = 55; aartREV[ 4][16] = 117;
+ aartREV[ 5][16] = 146; aartREV[ 6][16] = 82; aartREV[ 7][16] = 7; aartREV[ 8][16] = 49; aartREV[ 9][16] = 72;
+ aartREV[10][16] = 25; aartREV[11][16] = 110; aartREV[12][16] = 131; aartREV[13][16] = 69; aartREV[14][16] = 62;
+ aartREV[15][16] = 671; aartREV[16][16] = 0; aartREV[17][16] = 1; aartREV[18][16] = 34; aartREV[19][16] = 196;
+ aartREV[ 0][17] = 5; aartREV[ 1][17] = 13; aartREV[ 2][17] = 16; aartREV[ 3][17] = 1; aartREV[ 4][17] = 55;
+ aartREV[ 5][17] = 10; aartREV[ 6][17] = 17; aartREV[ 7][17] = 23; aartREV[ 8][17] = 48; aartREV[ 9][17] = 39;
+ aartREV[10][17] = 47; aartREV[11][17] = 6; aartREV[12][17] = 111; aartREV[13][17] = 182; aartREV[14][17] = 9;
+ aartREV[15][17] = 14; aartREV[16][17] = 1; aartREV[17][17] = 0; aartREV[18][17] = 176; aartREV[19][17] = 26;
+ aartREV[ 0][18] = 55; aartREV[ 1][18] = 47; aartREV[ 2][18] = 28; aartREV[ 3][18] = 1; aartREV[ 4][18] = 131;
+ aartREV[ 5][18] = 45; aartREV[ 6][18] = 1; aartREV[ 7][18] = 21; aartREV[ 8][18] = 307; aartREV[ 9][18] = 26;
+ aartREV[10][18] = 64; aartREV[11][18] = 1; aartREV[12][18] = 74; aartREV[13][18] =1017; aartREV[14][18] = 14;
+ aartREV[15][18] = 31; aartREV[16][18] = 34; aartREV[17][18] = 176; aartREV[18][18] = 0; aartREV[19][18] = 59;
+ aartREV[ 0][19] = 197; aartREV[ 1][19] = 29; aartREV[ 2][19] = 21; aartREV[ 3][19] = 6; aartREV[ 4][19] = 295;
+ aartREV[ 5][19] = 36; aartREV[ 6][19] = 35; aartREV[ 7][19] = 3; aartREV[ 8][19] = 1; aartREV[ 9][19] =1048;
+ aartREV[10][19] = 112; aartREV[11][19] = 19; aartREV[12][19] = 236; aartREV[13][19] = 92; aartREV[14][19] = 25;
+ aartREV[15][19] = 39; aartREV[16][19] = 196; aartREV[17][19] = 26; aartREV[18][19] = 59; aartREV[19][19] = 0;
+ rtrevPi[ 0] = 0.0646;
+ rtrevPi[ 1] = 0.0453;
+ rtrevPi[ 2] = 0.0376;
+ rtrevPi[ 3] = 0.0422;
+ rtrevPi[ 4] = 0.0114;
+ rtrevPi[ 5] = 0.0606;
+ rtrevPi[ 6] = 0.0607;
+ rtrevPi[ 7] = 0.0639;
+ rtrevPi[ 8] = 0.0273;
+ rtrevPi[ 9] = 0.0679;
+ rtrevPi[10] = 0.1018;
+ rtrevPi[11] = 0.0751;
+ rtrevPi[12] = 0.0150;
+ rtrevPi[13] = 0.0287;
+ rtrevPi[14] = 0.0681;
+ rtrevPi[15] = 0.0488;
+ rtrevPi[16] = 0.0622;
+ rtrevPi[17] = 0.0251;
+ rtrevPi[18] = 0.0318;
+ rtrevPi[19] = 0.0619;
+
+ /* wag */
+ aaWAG[ 0][ 0] = 0.0000000; aaWAG[ 1][ 0] = 0.5515710; aaWAG[ 2][ 0] = 0.5098480; aaWAG[ 3][ 0] = 0.7389980; aaWAG[ 4][ 0] = 1.0270400;
+ aaWAG[ 5][ 0] = 0.9085980; aaWAG[ 6][ 0] = 1.5828500; aaWAG[ 7][ 0] = 1.4167200; aaWAG[ 8][ 0] = 0.3169540; aaWAG[ 9][ 0] = 0.1933350;
+ aaWAG[10][ 0] = 0.3979150; aaWAG[11][ 0] = 0.9062650; aaWAG[12][ 0] = 0.8934960; aaWAG[13][ 0] = 0.2104940; aaWAG[14][ 0] = 1.4385500;
+ aaWAG[15][ 0] = 3.3707900; aaWAG[16][ 0] = 2.1211100; aaWAG[17][ 0] = 0.1131330; aaWAG[18][ 0] = 0.2407350; aaWAG[19][ 0] = 2.0060100;
+ aaWAG[ 0][ 1] = 0.5515710; aaWAG[ 1][ 1] = 0.0000000; aaWAG[ 2][ 1] = 0.6353460; aaWAG[ 3][ 1] = 0.1473040; aaWAG[ 4][ 1] = 0.5281910;
+ aaWAG[ 5][ 1] = 3.0355000; aaWAG[ 6][ 1] = 0.4391570; aaWAG[ 7][ 1] = 0.5846650; aaWAG[ 8][ 1] = 2.1371500; aaWAG[ 9][ 1] = 0.1869790;
+ aaWAG[10][ 1] = 0.4976710; aaWAG[11][ 1] = 5.3514200; aaWAG[12][ 1] = 0.6831620; aaWAG[13][ 1] = 0.1027110; aaWAG[14][ 1] = 0.6794890;
+ aaWAG[15][ 1] = 1.2241900; aaWAG[16][ 1] = 0.5544130; aaWAG[17][ 1] = 1.1639200; aaWAG[18][ 1] = 0.3815330; aaWAG[19][ 1] = 0.2518490;
+ aaWAG[ 0][ 2] = 0.5098480; aaWAG[ 1][ 2] = 0.6353460; aaWAG[ 2][ 2] = 0.0000000; aaWAG[ 3][ 2] = 5.4294200; aaWAG[ 4][ 2] = 0.2652560;
+ aaWAG[ 5][ 2] = 1.5436400; aaWAG[ 6][ 2] = 0.9471980; aaWAG[ 7][ 2] = 1.1255600; aaWAG[ 8][ 2] = 3.9562900; aaWAG[ 9][ 2] = 0.5542360;
+ aaWAG[10][ 2] = 0.1315280; aaWAG[11][ 2] = 3.0120100; aaWAG[12][ 2] = 0.1982210; aaWAG[13][ 2] = 0.0961621; aaWAG[14][ 2] = 0.1950810;
+ aaWAG[15][ 2] = 3.9742300; aaWAG[16][ 2] = 2.0300600; aaWAG[17][ 2] = 0.0719167; aaWAG[18][ 2] = 1.0860000; aaWAG[19][ 2] = 0.1962460;
+ aaWAG[ 0][ 3] = 0.7389980; aaWAG[ 1][ 3] = 0.1473040; aaWAG[ 2][ 3] = 5.4294200; aaWAG[ 3][ 3] = 0.0000000; aaWAG[ 4][ 3] = 0.0302949;
+ aaWAG[ 5][ 3] = 0.6167830; aaWAG[ 6][ 3] = 6.1741600; aaWAG[ 7][ 3] = 0.8655840; aaWAG[ 8][ 3] = 0.9306760; aaWAG[ 9][ 3] = 0.0394370;
+ aaWAG[10][ 3] = 0.0848047; aaWAG[11][ 3] = 0.4798550; aaWAG[12][ 3] = 0.1037540; aaWAG[13][ 3] = 0.0467304; aaWAG[14][ 3] = 0.4239840;
+ aaWAG[15][ 3] = 1.0717600; aaWAG[16][ 3] = 0.3748660; aaWAG[17][ 3] = 0.1297670; aaWAG[18][ 3] = 0.3257110; aaWAG[19][ 3] = 0.1523350;
+ aaWAG[ 0][ 4] = 1.0270400; aaWAG[ 1][ 4] = 0.5281910; aaWAG[ 2][ 4] = 0.2652560; aaWAG[ 3][ 4] = 0.0302949; aaWAG[ 4][ 4] = 0.0000000;
+ aaWAG[ 5][ 4] = 0.0988179; aaWAG[ 6][ 4] = 0.0213520; aaWAG[ 7][ 4] = 0.3066740; aaWAG[ 8][ 4] = 0.2489720; aaWAG[ 9][ 4] = 0.1701350;
+ aaWAG[10][ 4] = 0.3842870; aaWAG[11][ 4] = 0.0740339; aaWAG[12][ 4] = 0.3904820; aaWAG[13][ 4] = 0.3980200; aaWAG[14][ 4] = 0.1094040;
+ aaWAG[15][ 4] = 1.4076600; aaWAG[16][ 4] = 0.5129840; aaWAG[17][ 4] = 0.7170700; aaWAG[18][ 4] = 0.5438330; aaWAG[19][ 4] = 1.0021400;
+ aaWAG[ 0][ 5] = 0.9085980; aaWAG[ 1][ 5] = 3.0355000; aaWAG[ 2][ 5] = 1.5436400; aaWAG[ 3][ 5] = 0.6167830; aaWAG[ 4][ 5] = 0.0988179;
+ aaWAG[ 5][ 5] = 0.0000000; aaWAG[ 6][ 5] = 5.4694700; aaWAG[ 7][ 5] = 0.3300520; aaWAG[ 8][ 5] = 4.2941100; aaWAG[ 9][ 5] = 0.1139170;
+ aaWAG[10][ 5] = 0.8694890; aaWAG[11][ 5] = 3.8949000; aaWAG[12][ 5] = 1.5452600; aaWAG[13][ 5] = 0.0999208; aaWAG[14][ 5] = 0.9333720;
+ aaWAG[15][ 5] = 1.0288700; aaWAG[16][ 5] = 0.8579280; aaWAG[17][ 5] = 0.2157370; aaWAG[18][ 5] = 0.2277100; aaWAG[19][ 5] = 0.3012810;
+ aaWAG[ 0][ 6] = 1.5828500; aaWAG[ 1][ 6] = 0.4391570; aaWAG[ 2][ 6] = 0.9471980; aaWAG[ 3][ 6] = 6.1741600; aaWAG[ 4][ 6] = 0.0213520;
+ aaWAG[ 5][ 6] = 5.4694700; aaWAG[ 6][ 6] = 0.0000000; aaWAG[ 7][ 6] = 0.5677170; aaWAG[ 8][ 6] = 0.5700250; aaWAG[ 9][ 6] = 0.1273950;
+ aaWAG[10][ 6] = 0.1542630; aaWAG[11][ 6] = 2.5844300; aaWAG[12][ 6] = 0.3151240; aaWAG[13][ 6] = 0.0811339; aaWAG[14][ 6] = 0.6823550;
+ aaWAG[15][ 6] = 0.7049390; aaWAG[16][ 6] = 0.8227650; aaWAG[17][ 6] = 0.1565570; aaWAG[18][ 6] = 0.1963030; aaWAG[19][ 6] = 0.5887310;
+ aaWAG[ 0][ 7] = 1.4167200; aaWAG[ 1][ 7] = 0.5846650; aaWAG[ 2][ 7] = 1.1255600; aaWAG[ 3][ 7] = 0.8655840; aaWAG[ 4][ 7] = 0.3066740;
+ aaWAG[ 5][ 7] = 0.3300520; aaWAG[ 6][ 7] = 0.5677170; aaWAG[ 7][ 7] = 0.0000000; aaWAG[ 8][ 7] = 0.2494100; aaWAG[ 9][ 7] = 0.0304501;
+ aaWAG[10][ 7] = 0.0613037; aaWAG[11][ 7] = 0.3735580; aaWAG[12][ 7] = 0.1741000; aaWAG[13][ 7] = 0.0499310; aaWAG[14][ 7] = 0.2435700;
+ aaWAG[15][ 7] = 1.3418200; aaWAG[16][ 7] = 0.2258330; aaWAG[17][ 7] = 0.3369830; aaWAG[18][ 7] = 0.1036040; aaWAG[19][ 7] = 0.1872470;
+ aaWAG[ 0][ 8] = 0.3169540; aaWAG[ 1][ 8] = 2.1371500; aaWAG[ 2][ 8] = 3.9562900; aaWAG[ 3][ 8] = 0.9306760; aaWAG[ 4][ 8] = 0.2489720;
+ aaWAG[ 5][ 8] = 4.2941100; aaWAG[ 6][ 8] = 0.5700250; aaWAG[ 7][ 8] = 0.2494100; aaWAG[ 8][ 8] = 0.0000000; aaWAG[ 9][ 8] = 0.1381900;
+ aaWAG[10][ 8] = 0.4994620; aaWAG[11][ 8] = 0.8904320; aaWAG[12][ 8] = 0.4041410; aaWAG[13][ 8] = 0.6793710; aaWAG[14][ 8] = 0.6961980;
+ aaWAG[15][ 8] = 0.7401690; aaWAG[16][ 8] = 0.4733070; aaWAG[17][ 8] = 0.2625690; aaWAG[18][ 8] = 3.8734400; aaWAG[19][ 8] = 0.1183580;
+ aaWAG[ 0][ 9] = 0.1933350; aaWAG[ 1][ 9] = 0.1869790; aaWAG[ 2][ 9] = 0.5542360; aaWAG[ 3][ 9] = 0.0394370; aaWAG[ 4][ 9] = 0.1701350;
+ aaWAG[ 5][ 9] = 0.1139170; aaWAG[ 6][ 9] = 0.1273950; aaWAG[ 7][ 9] = 0.0304501; aaWAG[ 8][ 9] = 0.1381900; aaWAG[ 9][ 9] = 0.0000000;
+ aaWAG[10][ 9] = 3.1709700; aaWAG[11][ 9] = 0.3238320; aaWAG[12][ 9] = 4.2574600; aaWAG[13][ 9] = 1.0594700; aaWAG[14][ 9] = 0.0999288;
+ aaWAG[15][ 9] = 0.3194400; aaWAG[16][ 9] = 1.4581600; aaWAG[17][ 9] = 0.2124830; aaWAG[18][ 9] = 0.4201700; aaWAG[19][ 9] = 7.8213000;
+ aaWAG[ 0][10] = 0.3979150; aaWAG[ 1][10] = 0.4976710; aaWAG[ 2][10] = 0.1315280; aaWAG[ 3][10] = 0.0848047; aaWAG[ 4][10] = 0.3842870;
+ aaWAG[ 5][10] = 0.8694890; aaWAG[ 6][10] = 0.1542630; aaWAG[ 7][10] = 0.0613037; aaWAG[ 8][10] = 0.4994620; aaWAG[ 9][10] = 3.1709700;
+ aaWAG[10][10] = 0.0000000; aaWAG[11][10] = 0.2575550; aaWAG[12][10] = 4.8540200; aaWAG[13][10] = 2.1151700; aaWAG[14][10] = 0.4158440;
+ aaWAG[15][10] = 0.3447390; aaWAG[16][10] = 0.3266220; aaWAG[17][10] = 0.6653090; aaWAG[18][10] = 0.3986180; aaWAG[19][10] = 1.8003400;
+ aaWAG[ 0][11] = 0.9062650; aaWAG[ 1][11] = 5.3514200; aaWAG[ 2][11] = 3.0120100; aaWAG[ 3][11] = 0.4798550; aaWAG[ 4][11] = 0.0740339;
+ aaWAG[ 5][11] = 3.8949000; aaWAG[ 6][11] = 2.5844300; aaWAG[ 7][11] = 0.3735580; aaWAG[ 8][11] = 0.8904320; aaWAG[ 9][11] = 0.3238320;
+ aaWAG[10][11] = 0.2575550; aaWAG[11][11] = 0.0000000; aaWAG[12][11] = 0.9342760; aaWAG[13][11] = 0.0888360; aaWAG[14][11] = 0.5568960;
+ aaWAG[15][11] = 0.9671300; aaWAG[16][11] = 1.3869800; aaWAG[17][11] = 0.1375050; aaWAG[18][11] = 0.1332640; aaWAG[19][11] = 0.3054340;
+ aaWAG[ 0][12] = 0.8934960; aaWAG[ 1][12] = 0.6831620; aaWAG[ 2][12] = 0.1982210; aaWAG[ 3][12] = 0.1037540; aaWAG[ 4][12] = 0.3904820;
+ aaWAG[ 5][12] = 1.5452600; aaWAG[ 6][12] = 0.3151240; aaWAG[ 7][12] = 0.1741000; aaWAG[ 8][12] = 0.4041410; aaWAG[ 9][12] = 4.2574600;
+ aaWAG[10][12] = 4.8540200; aaWAG[11][12] = 0.9342760; aaWAG[12][12] = 0.0000000; aaWAG[13][12] = 1.1906300; aaWAG[14][12] = 0.1713290;
+ aaWAG[15][12] = 0.4939050; aaWAG[16][12] = 1.5161200; aaWAG[17][12] = 0.5157060; aaWAG[18][12] = 0.4284370; aaWAG[19][12] = 2.0584500;
+ aaWAG[ 0][13] = 0.2104940; aaWAG[ 1][13] = 0.1027110; aaWAG[ 2][13] = 0.0961621; aaWAG[ 3][13] = 0.0467304; aaWAG[ 4][13] = 0.3980200;
+ aaWAG[ 5][13] = 0.0999208; aaWAG[ 6][13] = 0.0811339; aaWAG[ 7][13] = 0.0499310; aaWAG[ 8][13] = 0.6793710; aaWAG[ 9][13] = 1.0594700;
+ aaWAG[10][13] = 2.1151700; aaWAG[11][13] = 0.0888360; aaWAG[12][13] = 1.1906300; aaWAG[13][13] = 0.0000000; aaWAG[14][13] = 0.1614440;
+ aaWAG[15][13] = 0.5459310; aaWAG[16][13] = 0.1719030; aaWAG[17][13] = 1.5296400; aaWAG[18][13] = 6.4542800; aaWAG[19][13] = 0.6498920;
+ aaWAG[ 0][14] = 1.4385500; aaWAG[ 1][14] = 0.6794890; aaWAG[ 2][14] = 0.1950810; aaWAG[ 3][14] = 0.4239840; aaWAG[ 4][14] = 0.1094040;
+ aaWAG[ 5][14] = 0.9333720; aaWAG[ 6][14] = 0.6823550; aaWAG[ 7][14] = 0.2435700; aaWAG[ 8][14] = 0.6961980; aaWAG[ 9][14] = 0.0999288;
+ aaWAG[10][14] = 0.4158440; aaWAG[11][14] = 0.5568960; aaWAG[12][14] = 0.1713290; aaWAG[13][14] = 0.1614440; aaWAG[14][14] = 0.0000000;
+ aaWAG[15][14] = 1.6132800; aaWAG[16][14] = 0.7953840; aaWAG[17][14] = 0.1394050; aaWAG[18][14] = 0.2160460; aaWAG[19][14] = 0.3148870;
+ aaWAG[ 0][15] = 3.3707900; aaWAG[ 1][15] = 1.2241900; aaWAG[ 2][15] = 3.9742300; aaWAG[ 3][15] = 1.0717600; aaWAG[ 4][15] = 1.4076600;
+ aaWAG[ 5][15] = 1.0288700; aaWAG[ 6][15] = 0.7049390; aaWAG[ 7][15] = 1.3418200; aaWAG[ 8][15] = 0.7401690; aaWAG[ 9][15] = 0.3194400;
+ aaWAG[10][15] = 0.3447390; aaWAG[11][15] = 0.9671300; aaWAG[12][15] = 0.4939050; aaWAG[13][15] = 0.5459310; aaWAG[14][15] = 1.6132800;
+ aaWAG[15][15] = 0.0000000; aaWAG[16][15] = 4.3780200; aaWAG[17][15] = 0.5237420; aaWAG[18][15] = 0.7869930; aaWAG[19][15] = 0.2327390;
+ aaWAG[ 0][16] = 2.1211100; aaWAG[ 1][16] = 0.5544130; aaWAG[ 2][16] = 2.0300600; aaWAG[ 3][16] = 0.3748660; aaWAG[ 4][16] = 0.5129840;
+ aaWAG[ 5][16] = 0.8579280; aaWAG[ 6][16] = 0.8227650; aaWAG[ 7][16] = 0.2258330; aaWAG[ 8][16] = 0.4733070; aaWAG[ 9][16] = 1.4581600;
+ aaWAG[10][16] = 0.3266220; aaWAG[11][16] = 1.3869800; aaWAG[12][16] = 1.5161200; aaWAG[13][16] = 0.1719030; aaWAG[14][16] = 0.7953840;
+ aaWAG[15][16] = 4.3780200; aaWAG[16][16] = 0.0000000; aaWAG[17][16] = 0.1108640; aaWAG[18][16] = 0.2911480; aaWAG[19][16] = 1.3882300;
+ aaWAG[ 0][17] = 0.1131330; aaWAG[ 1][17] = 1.1639200; aaWAG[ 2][17] = 0.0719167; aaWAG[ 3][17] = 0.1297670; aaWAG[ 4][17] = 0.7170700;
+ aaWAG[ 5][17] = 0.2157370; aaWAG[ 6][17] = 0.1565570; aaWAG[ 7][17] = 0.3369830; aaWAG[ 8][17] = 0.2625690; aaWAG[ 9][17] = 0.2124830;
+ aaWAG[10][17] = 0.6653090; aaWAG[11][17] = 0.1375050; aaWAG[12][17] = 0.5157060; aaWAG[13][17] = 1.5296400; aaWAG[14][17] = 0.1394050;
+ aaWAG[15][17] = 0.5237420; aaWAG[16][17] = 0.1108640; aaWAG[17][17] = 0.0000000; aaWAG[18][17] = 2.4853900; aaWAG[19][17] = 0.3653690;
+ aaWAG[ 0][18] = 0.2407350; aaWAG[ 1][18] = 0.3815330; aaWAG[ 2][18] = 1.0860000; aaWAG[ 3][18] = 0.3257110; aaWAG[ 4][18] = 0.5438330;
+ aaWAG[ 5][18] = 0.2277100; aaWAG[ 6][18] = 0.1963030; aaWAG[ 7][18] = 0.1036040; aaWAG[ 8][18] = 3.8734400; aaWAG[ 9][18] = 0.4201700;
+ aaWAG[10][18] = 0.3986180; aaWAG[11][18] = 0.1332640; aaWAG[12][18] = 0.4284370; aaWAG[13][18] = 6.4542800; aaWAG[14][18] = 0.2160460;
+ aaWAG[15][18] = 0.7869930; aaWAG[16][18] = 0.2911480; aaWAG[17][18] = 2.4853900; aaWAG[18][18] = 0.0000000; aaWAG[19][18] = 0.3147300;
+ aaWAG[ 0][19] = 2.0060100; aaWAG[ 1][19] = 0.2518490; aaWAG[ 2][19] = 0.1962460; aaWAG[ 3][19] = 0.1523350; aaWAG[ 4][19] = 1.0021400;
+ aaWAG[ 5][19] = 0.3012810; aaWAG[ 6][19] = 0.5887310; aaWAG[ 7][19] = 0.1872470; aaWAG[ 8][19] = 0.1183580; aaWAG[ 9][19] = 7.8213000;
+ aaWAG[10][19] = 1.8003400; aaWAG[11][19] = 0.3054340; aaWAG[12][19] = 2.0584500; aaWAG[13][19] = 0.6498920; aaWAG[14][19] = 0.3148870;
+ aaWAG[15][19] = 0.2327390; aaWAG[16][19] = 1.3882300; aaWAG[17][19] = 0.3653690; aaWAG[18][19] = 0.3147300; aaWAG[19][19] = 0.0000000;
+ wagPi[ 0] = 0.08662790;
+ wagPi[ 1] = 0.04397200;
+ wagPi[ 2] = 0.03908940;
+ wagPi[ 3] = 0.05704510;
+ wagPi[ 4] = 0.01930780;
+ wagPi[ 5] = 0.03672810;
+ wagPi[ 6] = 0.05805890;
+ wagPi[ 7] = 0.08325180;
+ wagPi[ 8] = 0.02443130;
+ wagPi[ 9] = 0.04846600;
+ wagPi[10] = 0.08620970;
+ wagPi[11] = 0.06202860;
+ wagPi[12] = 0.01950273;
+ wagPi[13] = 0.03843190;
+ wagPi[14] = 0.04576310;
+ wagPi[15] = 0.06951790;
+ wagPi[16] = 0.06101270;
+ wagPi[17] = 0.01438590;
+ wagPi[18] = 0.03527420;
+ wagPi[19] = 0.07089560;
+
+ /* cpRev */
+ aacpREV[ 0][ 0] = 0; aacpREV[ 0][ 1] = 105; aacpREV[ 0][ 2] = 227; aacpREV[ 0][ 3] = 175; aacpREV[ 0][ 4] = 669;
+ aacpREV[ 0][ 5] = 157; aacpREV[ 0][ 6] = 499; aacpREV[ 0][ 7] = 665; aacpREV[ 0][ 8] = 66; aacpREV[ 0][ 9] = 145;
+ aacpREV[ 0][10] = 197; aacpREV[ 0][11] = 236; aacpREV[ 0][12] = 185; aacpREV[ 0][13] = 68; aacpREV[ 0][14] = 490;
+ aacpREV[ 0][15] = 2440; aacpREV[ 0][16] = 1340; aacpREV[ 0][17] = 14; aacpREV[ 0][18] = 56; aacpREV[ 0][19] = 968;
+ aacpREV[ 1][ 0] = 105; aacpREV[ 1][ 1] = 0; aacpREV[ 1][ 2] = 357; aacpREV[ 1][ 3] = 43; aacpREV[ 1][ 4] = 823;
+ aacpREV[ 1][ 5] = 1745; aacpREV[ 1][ 6] = 152; aacpREV[ 1][ 7] = 243; aacpREV[ 1][ 8] = 715; aacpREV[ 1][ 9] = 136;
+ aacpREV[ 1][10] = 203; aacpREV[ 1][11] = 4482; aacpREV[ 1][12] = 125; aacpREV[ 1][13] = 53; aacpREV[ 1][14] = 87;
+ aacpREV[ 1][15] = 385; aacpREV[ 1][16] = 314; aacpREV[ 1][17] = 230; aacpREV[ 1][18] = 323; aacpREV[ 1][19] = 92;
+ aacpREV[ 2][ 0] = 227; aacpREV[ 2][ 1] = 357; aacpREV[ 2][ 2] = 0; aacpREV[ 2][ 3] = 4435; aacpREV[ 2][ 4] = 538;
+ aacpREV[ 2][ 5] = 768; aacpREV[ 2][ 6] = 1055; aacpREV[ 2][ 7] = 653; aacpREV[ 2][ 8] = 1405; aacpREV[ 2][ 9] = 168;
+ aacpREV[ 2][10] = 113; aacpREV[ 2][11] = 2430; aacpREV[ 2][12] = 61; aacpREV[ 2][13] = 97; aacpREV[ 2][14] = 173;
+ aacpREV[ 2][15] = 2085; aacpREV[ 2][16] = 1393; aacpREV[ 2][17] = 40; aacpREV[ 2][18] = 754; aacpREV[ 2][19] = 83;
+ aacpREV[ 3][ 0] = 175; aacpREV[ 3][ 1] = 43; aacpREV[ 3][ 2] = 4435; aacpREV[ 3][ 3] = 0; aacpREV[ 3][ 4] = 10;
+ aacpREV[ 3][ 5] = 400; aacpREV[ 3][ 6] = 3691; aacpREV[ 3][ 7] = 431; aacpREV[ 3][ 8] = 331; aacpREV[ 3][ 9] = 10;
+ aacpREV[ 3][10] = 10; aacpREV[ 3][11] = 412; aacpREV[ 3][12] = 47; aacpREV[ 3][13] = 22; aacpREV[ 3][14] = 170;
+ aacpREV[ 3][15] = 590; aacpREV[ 3][16] = 266; aacpREV[ 3][17] = 18; aacpREV[ 3][18] = 281; aacpREV[ 3][19] = 75;
+ aacpREV[ 4][ 0] = 669; aacpREV[ 4][ 1] = 823; aacpREV[ 4][ 2] = 538; aacpREV[ 4][ 3] = 10; aacpREV[ 4][ 4] = 0;
+ aacpREV[ 4][ 5] = 10; aacpREV[ 4][ 6] = 10; aacpREV[ 4][ 7] = 303; aacpREV[ 4][ 8] = 441; aacpREV[ 4][ 9] = 280;
+ aacpREV[ 4][10] = 396; aacpREV[ 4][11] = 48; aacpREV[ 4][12] = 159; aacpREV[ 4][13] = 726; aacpREV[ 4][14] = 285;
+ aacpREV[ 4][15] = 2331; aacpREV[ 4][16] = 576; aacpREV[ 4][17] = 435; aacpREV[ 4][18] = 1466; aacpREV[ 4][19] = 592;
+ aacpREV[ 5][ 0] = 157; aacpREV[ 5][ 1] = 1745; aacpREV[ 5][ 2] = 768; aacpREV[ 5][ 3] = 400; aacpREV[ 5][ 4] = 10;
+ aacpREV[ 5][ 5] = 0; aacpREV[ 5][ 6] = 3122; aacpREV[ 5][ 7] = 133; aacpREV[ 5][ 8] = 1269; aacpREV[ 5][ 9] = 92;
+ aacpREV[ 5][10] = 286; aacpREV[ 5][11] = 3313; aacpREV[ 5][12] = 202; aacpREV[ 5][13] = 10; aacpREV[ 5][14] = 323;
+ aacpREV[ 5][15] = 396; aacpREV[ 5][16] = 241; aacpREV[ 5][17] = 53; aacpREV[ 5][18] = 391; aacpREV[ 5][19] = 54;
+ aacpREV[ 6][ 0] = 499; aacpREV[ 6][ 1] = 152; aacpREV[ 6][ 2] = 1055; aacpREV[ 6][ 3] = 3691; aacpREV[ 6][ 4] = 10;
+ aacpREV[ 6][ 5] = 3122; aacpREV[ 6][ 6] = 0; aacpREV[ 6][ 7] = 379; aacpREV[ 6][ 8] = 162; aacpREV[ 6][ 9] = 148;
+ aacpREV[ 6][10] = 82; aacpREV[ 6][11] = 2629; aacpREV[ 6][12] = 113; aacpREV[ 6][13] = 145; aacpREV[ 6][14] = 185;
+ aacpREV[ 6][15] = 568; aacpREV[ 6][16] = 369; aacpREV[ 6][17] = 63; aacpREV[ 6][18] = 142; aacpREV[ 6][19] = 200;
+ aacpREV[ 7][ 0] = 665; aacpREV[ 7][ 1] = 243; aacpREV[ 7][ 2] = 653; aacpREV[ 7][ 3] = 431; aacpREV[ 7][ 4] = 303;
+ aacpREV[ 7][ 5] = 133; aacpREV[ 7][ 6] = 379; aacpREV[ 7][ 7] = 0; aacpREV[ 7][ 8] = 19; aacpREV[ 7][ 9] = 40;
+ aacpREV[ 7][10] = 20; aacpREV[ 7][11] = 263; aacpREV[ 7][12] = 21; aacpREV[ 7][13] = 25; aacpREV[ 7][14] = 28;
+ aacpREV[ 7][15] = 691; aacpREV[ 7][16] = 92; aacpREV[ 7][17] = 82; aacpREV[ 7][18] = 10; aacpREV[ 7][19] = 91;
+ aacpREV[ 8][ 0] = 66; aacpREV[ 8][ 1] = 715; aacpREV[ 8][ 2] = 1405; aacpREV[ 8][ 3] = 331; aacpREV[ 8][ 4] = 441;
+ aacpREV[ 8][ 5] = 1269; aacpREV[ 8][ 6] = 162; aacpREV[ 8][ 7] = 19; aacpREV[ 8][ 8] = 0; aacpREV[ 8][ 9] = 29;
+ aacpREV[ 8][10] = 66; aacpREV[ 8][11] = 305; aacpREV[ 8][12] = 10; aacpREV[ 8][13] = 127; aacpREV[ 8][14] = 152;
+ aacpREV[ 8][15] = 303; aacpREV[ 8][16] = 32; aacpREV[ 8][17] = 69; aacpREV[ 8][18] = 1971; aacpREV[ 8][19] = 25;
+ aacpREV[ 9][ 0] = 145; aacpREV[ 9][ 1] = 136; aacpREV[ 9][ 2] = 168; aacpREV[ 9][ 3] = 10; aacpREV[ 9][ 4] = 280;
+ aacpREV[ 9][ 5] = 92; aacpREV[ 9][ 6] = 148; aacpREV[ 9][ 7] = 40; aacpREV[ 9][ 8] = 29; aacpREV[ 9][ 9] = 0;
+ aacpREV[ 9][10] = 1745; aacpREV[ 9][11] = 345; aacpREV[ 9][12] = 1772; aacpREV[ 9][13] = 454; aacpREV[ 9][14] = 117;
+ aacpREV[ 9][15] = 216; aacpREV[ 9][16] = 1040; aacpREV[ 9][17] = 42; aacpREV[ 9][18] = 89; aacpREV[ 9][19] = 4797;
+ aacpREV[10][ 0] = 197; aacpREV[10][ 1] = 203; aacpREV[10][ 2] = 113; aacpREV[10][ 3] = 10; aacpREV[10][ 4] = 396;
+ aacpREV[10][ 5] = 286; aacpREV[10][ 6] = 82; aacpREV[10][ 7] = 20; aacpREV[10][ 8] = 66; aacpREV[10][ 9] = 1745;
+ aacpREV[10][10] = 0; aacpREV[10][11] = 218; aacpREV[10][12] = 1351; aacpREV[10][13] = 1268; aacpREV[10][14] = 219;
+ aacpREV[10][15] = 516; aacpREV[10][16] = 156; aacpREV[10][17] = 159; aacpREV[10][18] = 189; aacpREV[10][19] = 865;
+ aacpREV[11][ 0] = 236; aacpREV[11][ 1] = 4482; aacpREV[11][ 2] = 2430; aacpREV[11][ 3] = 412; aacpREV[11][ 4] = 48;
+ aacpREV[11][ 5] = 3313; aacpREV[11][ 6] = 2629; aacpREV[11][ 7] = 263; aacpREV[11][ 8] = 305; aacpREV[11][ 9] = 345;
+ aacpREV[11][10] = 218; aacpREV[11][11] = 0; aacpREV[11][12] = 193; aacpREV[11][13] = 72; aacpREV[11][14] = 302;
+ aacpREV[11][15] = 868; aacpREV[11][16] = 918; aacpREV[11][17] = 10; aacpREV[11][18] = 247; aacpREV[11][19] = 249;
+ aacpREV[12][ 0] = 185; aacpREV[12][ 1] = 125; aacpREV[12][ 2] = 61; aacpREV[12][ 3] = 47; aacpREV[12][ 4] = 159;
+ aacpREV[12][ 5] = 202; aacpREV[12][ 6] = 113; aacpREV[12][ 7] = 21; aacpREV[12][ 8] = 10; aacpREV[12][ 9] = 1772;
+ aacpREV[12][10] = 1351; aacpREV[12][11] = 193; aacpREV[12][12] = 0; aacpREV[12][13] = 327; aacpREV[12][14] = 100;
+ aacpREV[12][15] = 93; aacpREV[12][16] = 645; aacpREV[12][17] = 86; aacpREV[12][18] = 215; aacpREV[12][19] = 475;
+ aacpREV[13][ 0] = 68; aacpREV[13][ 1] = 53; aacpREV[13][ 2] = 97; aacpREV[13][ 3] = 22; aacpREV[13][ 4] = 726;
+ aacpREV[13][ 5] = 10; aacpREV[13][ 6] = 145; aacpREV[13][ 7] = 25; aacpREV[13][ 8] = 127; aacpREV[13][ 9] = 454;
+ aacpREV[13][10] = 1268; aacpREV[13][11] = 72; aacpREV[13][12] = 327; aacpREV[13][13] = 0; aacpREV[13][14] = 43;
+ aacpREV[13][15] = 487; aacpREV[13][16] = 148; aacpREV[13][17] = 468; aacpREV[13][18] = 2370; aacpREV[13][19] = 317;
+ aacpREV[14][ 0] = 490; aacpREV[14][ 1] = 87; aacpREV[14][ 2] = 173; aacpREV[14][ 3] = 170; aacpREV[14][ 4] = 285;
+ aacpREV[14][ 5] = 323; aacpREV[14][ 6] = 185; aacpREV[14][ 7] = 28; aacpREV[14][ 8] = 152; aacpREV[14][ 9] = 117;
+ aacpREV[14][10] = 219; aacpREV[14][11] = 302; aacpREV[14][12] = 100; aacpREV[14][13] = 43; aacpREV[14][14] = 0;
+ aacpREV[14][15] = 1202; aacpREV[14][16] = 260; aacpREV[14][17] = 49; aacpREV[14][18] = 97; aacpREV[14][19] = 122;
+ aacpREV[15][ 0] = 2440; aacpREV[15][ 1] = 385; aacpREV[15][ 2] = 2085; aacpREV[15][ 3] = 590; aacpREV[15][ 4] = 2331;
+ aacpREV[15][ 5] = 396; aacpREV[15][ 6] = 568; aacpREV[15][ 7] = 691; aacpREV[15][ 8] = 303; aacpREV[15][ 9] = 216;
+ aacpREV[15][10] = 516; aacpREV[15][11] = 868; aacpREV[15][12] = 93; aacpREV[15][13] = 487; aacpREV[15][14] = 1202;
+ aacpREV[15][15] = 0; aacpREV[15][16] = 2151; aacpREV[15][17] = 73; aacpREV[15][18] = 522; aacpREV[15][19] = 167;
+ aacpREV[16][ 0] = 1340; aacpREV[16][ 1] = 314; aacpREV[16][ 2] = 1393; aacpREV[16][ 3] = 266; aacpREV[16][ 4] = 576;
+ aacpREV[16][ 5] = 241; aacpREV[16][ 6] = 369; aacpREV[16][ 7] = 92; aacpREV[16][ 8] = 32; aacpREV[16][ 9] = 1040;
+ aacpREV[16][10] = 156; aacpREV[16][11] = 918; aacpREV[16][12] = 645; aacpREV[16][13] = 148; aacpREV[16][14] = 260;
+ aacpREV[16][15] = 2151; aacpREV[16][16] = 0; aacpREV[16][17] = 29; aacpREV[16][18] = 71; aacpREV[16][19] = 760;
+ aacpREV[17][ 0] = 14; aacpREV[17][ 1] = 230; aacpREV[17][ 2] = 40; aacpREV[17][ 3] = 18; aacpREV[17][ 4] = 435;
+ aacpREV[17][ 5] = 53; aacpREV[17][ 6] = 63; aacpREV[17][ 7] = 82; aacpREV[17][ 8] = 69; aacpREV[17][ 9] = 42;
+ aacpREV[17][10] = 159; aacpREV[17][11] = 10; aacpREV[17][12] = 86; aacpREV[17][13] = 468; aacpREV[17][14] = 49;
+ aacpREV[17][15] = 73; aacpREV[17][16] = 29; aacpREV[17][17] = 0; aacpREV[17][18] = 346; aacpREV[17][19] = 10;
+ aacpREV[18][ 0] = 56; aacpREV[18][ 1] = 323; aacpREV[18][ 2] = 754; aacpREV[18][ 3] = 281; aacpREV[18][ 4] = 1466;
+ aacpREV[18][ 5] = 391; aacpREV[18][ 6] = 142; aacpREV[18][ 7] = 10; aacpREV[18][ 8] = 1971; aacpREV[18][ 9] = 89;
+ aacpREV[18][10] = 189; aacpREV[18][11] = 247; aacpREV[18][12] = 215; aacpREV[18][13] = 2370; aacpREV[18][14] = 97;
+ aacpREV[18][15] = 522; aacpREV[18][16] = 71; aacpREV[18][17] = 346; aacpREV[18][18] = 0; aacpREV[18][19] = 119;
+ aacpREV[19][ 0] = 968; aacpREV[19][ 1] = 92; aacpREV[19][ 2] = 83; aacpREV[19][ 3] = 75; aacpREV[19][ 4] = 592;
+ aacpREV[19][ 5] = 54; aacpREV[19][ 6] = 200; aacpREV[19][ 7] = 91; aacpREV[19][ 8] = 25; aacpREV[19][ 9] = 4797;
+ aacpREV[19][10] = 865; aacpREV[19][11] = 249; aacpREV[19][12] = 475; aacpREV[19][13] = 317; aacpREV[19][14] = 122;
+ aacpREV[19][15] = 167; aacpREV[19][16] = 760; aacpREV[19][17] = 10; aacpREV[19][18] = 119; aacpREV[19][19] = 0;
+
+ cprevPi[0] = 0.076;
+ cprevPi[1] = 0.062;
+ cprevPi[2] = 0.041;
+ cprevPi[3] = 0.037;
+ cprevPi[4] = 0.009;
+ cprevPi[5] = 0.038;
+ cprevPi[6] = 0.049;
+ cprevPi[7] = 0.084;
+ cprevPi[8] = 0.025;
+ cprevPi[9] = 0.081;
+ cprevPi[10] = 0.101;
+ cprevPi[11] = 0.050;
+ cprevPi[12] = 0.022;
+ cprevPi[13] = 0.051;
+ cprevPi[14] = 0.043;
+ cprevPi[15] = 0.062;
+ cprevPi[16] = 0.054;
+ cprevPi[17] = 0.018;
+ cprevPi[18] = 0.031;
+ cprevPi[19] = 0.066;
+
+ /* VT model */
+ aaVt[ 0][ 0] = 0.000000; aaVt[ 0][ 1] = 0.233108; aaVt[ 0][ 2] = 0.199097; aaVt[ 0][ 3] = 0.265145; aaVt[ 0][ 4] = 0.227333;
+ aaVt[ 0][ 5] = 0.310084; aaVt[ 0][ 6] = 0.567957; aaVt[ 0][ 7] = 0.876213; aaVt[ 0][ 8] = 0.078692; aaVt[ 0][ 9] = 0.222972;
+ aaVt[ 0][10] = 0.424630; aaVt[ 0][11] = 0.393245; aaVt[ 0][12] = 0.211550; aaVt[ 0][13] = 0.116646; aaVt[ 0][14] = 0.399143;
+ aaVt[ 0][15] = 1.817198; aaVt[ 0][16] = 0.877877; aaVt[ 0][17] = 0.030309; aaVt[ 0][18] = 0.087061; aaVt[ 0][19] = 1.230985;
+ aaVt[ 1][ 0] = 0.233108; aaVt[ 1][ 1] = 0.000000; aaVt[ 1][ 2] = 0.210797; aaVt[ 1][ 3] = 0.105191; aaVt[ 1][ 4] = 0.031726;
+ aaVt[ 1][ 5] = 0.493763; aaVt[ 1][ 6] = 0.255240; aaVt[ 1][ 7] = 0.156945; aaVt[ 1][ 8] = 0.213164; aaVt[ 1][ 9] = 0.081510;
+ aaVt[ 1][10] = 0.192364; aaVt[ 1][11] = 1.755838; aaVt[ 1][12] = 0.087930; aaVt[ 1][13] = 0.042569; aaVt[ 1][14] = 0.128480;
+ aaVt[ 1][15] = 0.292327; aaVt[ 1][16] = 0.204109; aaVt[ 1][17] = 0.046417; aaVt[ 1][18] = 0.097010; aaVt[ 1][19] = 0.113146;
+ aaVt[ 2][ 0] = 0.199097; aaVt[ 2][ 1] = 0.210797; aaVt[ 2][ 2] = 0.000000; aaVt[ 2][ 3] = 0.883422; aaVt[ 2][ 4] = 0.027495;
+ aaVt[ 2][ 5] = 0.275700; aaVt[ 2][ 6] = 0.270417; aaVt[ 2][ 7] = 0.362028; aaVt[ 2][ 8] = 0.290006; aaVt[ 2][ 9] = 0.087225;
+ aaVt[ 2][10] = 0.069245; aaVt[ 2][11] = 0.503060; aaVt[ 2][12] = 0.057420; aaVt[ 2][13] = 0.039769; aaVt[ 2][14] = 0.083956;
+ aaVt[ 2][15] = 0.847049; aaVt[ 2][16] = 0.471268; aaVt[ 2][17] = 0.010459; aaVt[ 2][18] = 0.093268; aaVt[ 2][19] = 0.049824;
+ aaVt[ 3][ 0] = 0.265145; aaVt[ 3][ 1] = 0.105191; aaVt[ 3][ 2] = 0.883422; aaVt[ 3][ 3] = 0.000000; aaVt[ 3][ 4] = 0.010313;
+ aaVt[ 3][ 5] = 0.205842; aaVt[ 3][ 6] = 1.599461; aaVt[ 3][ 7] = 0.311718; aaVt[ 3][ 8] = 0.134252; aaVt[ 3][ 9] = 0.011720;
+ aaVt[ 3][10] = 0.060863; aaVt[ 3][11] = 0.261101; aaVt[ 3][12] = 0.012182; aaVt[ 3][13] = 0.016577; aaVt[ 3][14] = 0.160063;
+ aaVt[ 3][15] = 0.461519; aaVt[ 3][16] = 0.178197; aaVt[ 3][17] = 0.011393; aaVt[ 3][18] = 0.051664; aaVt[ 3][19] = 0.048769;
+ aaVt[ 4][ 0] = 0.227333; aaVt[ 4][ 1] = 0.031726; aaVt[ 4][ 2] = 0.027495; aaVt[ 4][ 3] = 0.010313; aaVt[ 4][ 4] = 0.000000;
+ aaVt[ 4][ 5] = 0.004315; aaVt[ 4][ 6] = 0.005321; aaVt[ 4][ 7] = 0.050876; aaVt[ 4][ 8] = 0.016695; aaVt[ 4][ 9] = 0.046398;
+ aaVt[ 4][10] = 0.091709; aaVt[ 4][11] = 0.004067; aaVt[ 4][12] = 0.023690; aaVt[ 4][13] = 0.051127; aaVt[ 4][14] = 0.011137;
+ aaVt[ 4][15] = 0.175270; aaVt[ 4][16] = 0.079511; aaVt[ 4][17] = 0.007732; aaVt[ 4][18] = 0.042823; aaVt[ 4][19] = 0.163831;
+ aaVt[ 5][ 0] = 0.310084; aaVt[ 5][ 1] = 0.493763; aaVt[ 5][ 2] = 0.275700; aaVt[ 5][ 3] = 0.205842; aaVt[ 5][ 4] = 0.004315;
+ aaVt[ 5][ 5] = 0.000000; aaVt[ 5][ 6] = 0.960976; aaVt[ 5][ 7] = 0.128660; aaVt[ 5][ 8] = 0.315521; aaVt[ 5][ 9] = 0.054602;
+ aaVt[ 5][10] = 0.243530; aaVt[ 5][11] = 0.738208; aaVt[ 5][12] = 0.120801; aaVt[ 5][13] = 0.026235; aaVt[ 5][14] = 0.156570;
+ aaVt[ 5][15] = 0.358017; aaVt[ 5][16] = 0.248992; aaVt[ 5][17] = 0.021248; aaVt[ 5][18] = 0.062544; aaVt[ 5][19] = 0.112027;
+ aaVt[ 6][ 0] = 0.567957; aaVt[ 6][ 1] = 0.255240; aaVt[ 6][ 2] = 0.270417; aaVt[ 6][ 3] = 1.599461; aaVt[ 6][ 4] = 0.005321;
+ aaVt[ 6][ 5] = 0.960976; aaVt[ 6][ 6] = 0.000000; aaVt[ 6][ 7] = 0.250447; aaVt[ 6][ 8] = 0.104458; aaVt[ 6][ 9] = 0.046589;
+ aaVt[ 6][10] = 0.151924; aaVt[ 6][11] = 0.888630; aaVt[ 6][12] = 0.058643; aaVt[ 6][13] = 0.028168; aaVt[ 6][14] = 0.205134;
+ aaVt[ 6][15] = 0.406035; aaVt[ 6][16] = 0.321028; aaVt[ 6][17] = 0.018844; aaVt[ 6][18] = 0.055200; aaVt[ 6][19] = 0.205868;
+ aaVt[ 7][ 0] = 0.876213; aaVt[ 7][ 1] = 0.156945; aaVt[ 7][ 2] = 0.362028; aaVt[ 7][ 3] = 0.311718; aaVt[ 7][ 4] = 0.050876;
+ aaVt[ 7][ 5] = 0.128660; aaVt[ 7][ 6] = 0.250447; aaVt[ 7][ 7] = 0.000000; aaVt[ 7][ 8] = 0.058131; aaVt[ 7][ 9] = 0.051089;
+ aaVt[ 7][10] = 0.087056; aaVt[ 7][11] = 0.193243; aaVt[ 7][12] = 0.046560; aaVt[ 7][13] = 0.050143; aaVt[ 7][14] = 0.124492;
+ aaVt[ 7][15] = 0.612843; aaVt[ 7][16] = 0.136266; aaVt[ 7][17] = 0.023990; aaVt[ 7][18] = 0.037568; aaVt[ 7][19] = 0.082579;
+ aaVt[ 8][ 0] = 0.078692; aaVt[ 8][ 1] = 0.213164; aaVt[ 8][ 2] = 0.290006; aaVt[ 8][ 3] = 0.134252; aaVt[ 8][ 4] = 0.016695;
+ aaVt[ 8][ 5] = 0.315521; aaVt[ 8][ 6] = 0.104458; aaVt[ 8][ 7] = 0.058131; aaVt[ 8][ 8] = 0.000000; aaVt[ 8][ 9] = 0.020039;
+ aaVt[ 8][10] = 0.103552; aaVt[ 8][11] = 0.153323; aaVt[ 8][12] = 0.021157; aaVt[ 8][13] = 0.079807; aaVt[ 8][14] = 0.078892;
+ aaVt[ 8][15] = 0.167406; aaVt[ 8][16] = 0.101117; aaVt[ 8][17] = 0.020009; aaVt[ 8][18] = 0.286027; aaVt[ 8][19] = 0.068575;
+ aaVt[ 9][ 0] = 0.222972; aaVt[ 9][ 1] = 0.081510; aaVt[ 9][ 2] = 0.087225; aaVt[ 9][ 3] = 0.011720; aaVt[ 9][ 4] = 0.046398;
+ aaVt[ 9][ 5] = 0.054602; aaVt[ 9][ 6] = 0.046589; aaVt[ 9][ 7] = 0.051089; aaVt[ 9][ 8] = 0.020039; aaVt[ 9][ 9] = 0.000000;
+ aaVt[ 9][10] = 2.089890; aaVt[ 9][11] = 0.093181; aaVt[ 9][12] = 0.493845; aaVt[ 9][13] = 0.321020; aaVt[ 9][14] = 0.054797;
+ aaVt[ 9][15] = 0.081567; aaVt[ 9][16] = 0.376588; aaVt[ 9][17] = 0.034954; aaVt[ 9][18] = 0.086237; aaVt[ 9][19] = 3.654430;
+ aaVt[10][ 0] = 0.424630; aaVt[10][ 1] = 0.192364; aaVt[10][ 2] = 0.069245; aaVt[10][ 3] = 0.060863; aaVt[10][ 4] = 0.091709;
+ aaVt[10][ 5] = 0.243530; aaVt[10][ 6] = 0.151924; aaVt[10][ 7] = 0.087056; aaVt[10][ 8] = 0.103552; aaVt[10][ 9] = 2.089890;
+ aaVt[10][10] = 0.000000; aaVt[10][11] = 0.201204; aaVt[10][12] = 1.105667; aaVt[10][13] = 0.946499; aaVt[10][14] = 0.169784;
+ aaVt[10][15] = 0.214977; aaVt[10][16] = 0.243227; aaVt[10][17] = 0.083439; aaVt[10][18] = 0.189842; aaVt[10][19] = 1.337571;
+ aaVt[11][ 0] = 0.393245; aaVt[11][ 1] = 1.755838; aaVt[11][ 2] = 0.503060; aaVt[11][ 3] = 0.261101; aaVt[11][ 4] = 0.004067;
+ aaVt[11][ 5] = 0.738208; aaVt[11][ 6] = 0.888630; aaVt[11][ 7] = 0.193243; aaVt[11][ 8] = 0.153323; aaVt[11][ 9] = 0.093181;
+ aaVt[11][10] = 0.201204; aaVt[11][11] = 0.000000; aaVt[11][12] = 0.096474; aaVt[11][13] = 0.038261; aaVt[11][14] = 0.212302;
+ aaVt[11][15] = 0.400072; aaVt[11][16] = 0.446646; aaVt[11][17] = 0.023321; aaVt[11][18] = 0.068689; aaVt[11][19] = 0.144587;
+ aaVt[12][ 0] = 0.211550; aaVt[12][ 1] = 0.087930; aaVt[12][ 2] = 0.057420; aaVt[12][ 3] = 0.012182; aaVt[12][ 4] = 0.023690;
+ aaVt[12][ 5] = 0.120801; aaVt[12][ 6] = 0.058643; aaVt[12][ 7] = 0.046560; aaVt[12][ 8] = 0.021157; aaVt[12][ 9] = 0.493845;
+ aaVt[12][10] = 1.105667; aaVt[12][11] = 0.096474; aaVt[12][12] = 0.000000; aaVt[12][13] = 0.173052; aaVt[12][14] = 0.010363;
+ aaVt[12][15] = 0.090515; aaVt[12][16] = 0.184609; aaVt[12][17] = 0.022019; aaVt[12][18] = 0.073223; aaVt[12][19] = 0.307309;
+ aaVt[13][ 0] = 0.116646; aaVt[13][ 1] = 0.042569; aaVt[13][ 2] = 0.039769; aaVt[13][ 3] = 0.016577; aaVt[13][ 4] = 0.051127;
+ aaVt[13][ 5] = 0.026235; aaVt[13][ 6] = 0.028168; aaVt[13][ 7] = 0.050143; aaVt[13][ 8] = 0.079807; aaVt[13][ 9] = 0.321020;
+ aaVt[13][10] = 0.946499; aaVt[13][11] = 0.038261; aaVt[13][12] = 0.173052; aaVt[13][13] = 0.000000; aaVt[13][14] = 0.042564;
+ aaVt[13][15] = 0.138119; aaVt[13][16] = 0.085870; aaVt[13][17] = 0.128050; aaVt[13][18] = 0.898663; aaVt[13][19] = 0.247329;
+ aaVt[14][ 0] = 0.399143; aaVt[14][ 1] = 0.128480; aaVt[14][ 2] = 0.083956; aaVt[14][ 3] = 0.160063; aaVt[14][ 4] = 0.011137;
+ aaVt[14][ 5] = 0.156570; aaVt[14][ 6] = 0.205134; aaVt[14][ 7] = 0.124492; aaVt[14][ 8] = 0.078892; aaVt[14][ 9] = 0.054797;
+ aaVt[14][10] = 0.169784; aaVt[14][11] = 0.212302; aaVt[14][12] = 0.010363; aaVt[14][13] = 0.042564; aaVt[14][14] = 0.000000;
+ aaVt[14][15] = 0.430431; aaVt[14][16] = 0.207143; aaVt[14][17] = 0.014584; aaVt[14][18] = 0.032043; aaVt[14][19] = 0.129315;
+ aaVt[15][ 0] = 1.817198; aaVt[15][ 1] = 0.292327; aaVt[15][ 2] = 0.847049; aaVt[15][ 3] = 0.461519; aaVt[15][ 4] = 0.175270;
+ aaVt[15][ 5] = 0.358017; aaVt[15][ 6] = 0.406035; aaVt[15][ 7] = 0.612843; aaVt[15][ 8] = 0.167406; aaVt[15][ 9] = 0.081567;
+ aaVt[15][10] = 0.214977; aaVt[15][11] = 0.400072; aaVt[15][12] = 0.090515; aaVt[15][13] = 0.138119; aaVt[15][14] = 0.430431;
+ aaVt[15][15] = 0.000000; aaVt[15][16] = 1.767766; aaVt[15][17] = 0.035933; aaVt[15][18] = 0.121979; aaVt[15][19] = 0.127700;
+ aaVt[16][ 0] = 0.877877; aaVt[16][ 1] = 0.204109; aaVt[16][ 2] = 0.471268; aaVt[16][ 3] = 0.178197; aaVt[16][ 4] = 0.079511;
+ aaVt[16][ 5] = 0.248992; aaVt[16][ 6] = 0.321028; aaVt[16][ 7] = 0.136266; aaVt[16][ 8] = 0.101117; aaVt[16][ 9] = 0.376588;
+ aaVt[16][10] = 0.243227; aaVt[16][11] = 0.446646; aaVt[16][12] = 0.184609; aaVt[16][13] = 0.085870; aaVt[16][14] = 0.207143;
+ aaVt[16][15] = 1.767766; aaVt[16][16] = 0.000000; aaVt[16][17] = 0.020437; aaVt[16][18] = 0.094617; aaVt[16][19] = 0.740372;
+ aaVt[17][ 0] = 0.030309; aaVt[17][ 1] = 0.046417; aaVt[17][ 2] = 0.010459; aaVt[17][ 3] = 0.011393; aaVt[17][ 4] = 0.007732;
+ aaVt[17][ 5] = 0.021248; aaVt[17][ 6] = 0.018844; aaVt[17][ 7] = 0.023990; aaVt[17][ 8] = 0.020009; aaVt[17][ 9] = 0.034954;
+ aaVt[17][10] = 0.083439; aaVt[17][11] = 0.023321; aaVt[17][12] = 0.022019; aaVt[17][13] = 0.128050; aaVt[17][14] = 0.014584;
+ aaVt[17][15] = 0.035933; aaVt[17][16] = 0.020437; aaVt[17][17] = 0.000000; aaVt[17][18] = 0.124746; aaVt[17][19] = 0.022134;
+ aaVt[18][ 0] = 0.087061; aaVt[18][ 1] = 0.097010; aaVt[18][ 2] = 0.093268; aaVt[18][ 3] = 0.051664; aaVt[18][ 4] = 0.042823;
+ aaVt[18][ 5] = 0.062544; aaVt[18][ 6] = 0.055200; aaVt[18][ 7] = 0.037568; aaVt[18][ 8] = 0.286027; aaVt[18][ 9] = 0.086237;
+ aaVt[18][10] = 0.189842; aaVt[18][11] = 0.068689; aaVt[18][12] = 0.073223; aaVt[18][13] = 0.898663; aaVt[18][14] = 0.032043;
+ aaVt[18][15] = 0.121979; aaVt[18][16] = 0.094617; aaVt[18][17] = 0.124746; aaVt[18][18] = 0.000000; aaVt[18][19] = 0.125733;
+ aaVt[19][ 0] = 1.230985; aaVt[19][ 1] = 0.113146; aaVt[19][ 2] = 0.049824; aaVt[19][ 3] = 0.048769; aaVt[19][ 4] = 0.163831;
+ aaVt[19][ 5] = 0.112027; aaVt[19][ 6] = 0.205868; aaVt[19][ 7] = 0.082579; aaVt[19][ 8] = 0.068575; aaVt[19][ 9] = 3.654430;
+ aaVt[19][10] = 1.337571; aaVt[19][11] = 0.144587; aaVt[19][12] = 0.307309; aaVt[19][13] = 0.247329; aaVt[19][14] = 0.129315;
+ aaVt[19][15] = 0.127700; aaVt[19][16] = 0.740372; aaVt[19][17] = 0.022134; aaVt[19][18] = 0.125733; aaVt[19][19] = 0.000000;
+
+ vtPi[ 0] = 0.078837;
+ vtPi[ 1] = 0.051238;
+ vtPi[ 2] = 0.042313;
+ vtPi[ 3] = 0.053066;
+ vtPi[ 4] = 0.015175;
+ vtPi[ 5] = 0.036713;
+ vtPi[ 6] = 0.061924;
+ vtPi[ 7] = 0.070852;
+ vtPi[ 8] = 0.023082;
+ vtPi[ 9] = 0.062056;
+ vtPi[10] = 0.096371;
+ vtPi[11] = 0.057324;
+ vtPi[12] = 0.023771;
+ vtPi[13] = 0.043296;
+ vtPi[14] = 0.043911;
+ vtPi[15] = 0.063403;
+ vtPi[16] = 0.055897;
+ vtPi[17] = 0.013272;
+ vtPi[18] = 0.034399;
+ vtPi[19] = 0.073101;
+
+ /* Blosum62 */
+ aaBlosum[ 0][ 0] = 0.000000000000; aaBlosum[ 0][ 1] = 0.735790389698; aaBlosum[ 0][ 2] = 0.485391055466; aaBlosum[ 0][ 3] = 0.543161820899; aaBlosum[ 0][ 4] = 1.459995310470;
+ aaBlosum[ 0][ 5] = 1.199705704602; aaBlosum[ 0][ 6] = 1.170949042800; aaBlosum[ 0][ 7] = 1.955883574960; aaBlosum[ 0][ 8] = 0.716241444998; aaBlosum[ 0][ 9] = 0.605899003687;
+ aaBlosum[ 0][10] = 0.800016530518; aaBlosum[ 0][11] = 1.295201266783; aaBlosum[ 0][12] = 1.253758266664; aaBlosum[ 0][13] = 0.492964679748; aaBlosum[ 0][14] = 1.173275900924;
+ aaBlosum[ 0][15] = 4.325092687057; aaBlosum[ 0][16] = 1.729178019485; aaBlosum[ 0][17] = 0.465839367725; aaBlosum[ 0][18] = 0.718206697586; aaBlosum[ 0][19] = 2.187774522005;
+ aaBlosum[ 1][ 0] = 0.735790389698; aaBlosum[ 1][ 1] = 0.000000000000; aaBlosum[ 1][ 2] = 1.297446705134; aaBlosum[ 1][ 3] = 0.500964408555; aaBlosum[ 1][ 4] = 0.227826574209;
+ aaBlosum[ 1][ 5] = 3.020833610064; aaBlosum[ 1][ 6] = 1.360574190420; aaBlosum[ 1][ 7] = 0.418763308518; aaBlosum[ 1][ 8] = 1.456141166336; aaBlosum[ 1][ 9] = 0.232036445142;
+ aaBlosum[ 1][10] = 0.622711669692; aaBlosum[ 1][11] = 5.411115141489; aaBlosum[ 1][12] = 0.983692987457; aaBlosum[ 1][13] = 0.371644693209; aaBlosum[ 1][14] = 0.448133661718;
+ aaBlosum[ 1][15] = 1.122783104210; aaBlosum[ 1][16] = 0.914665954563; aaBlosum[ 1][17] = 0.426382310122; aaBlosum[ 1][18] = 0.720517441216; aaBlosum[ 1][19] = 0.438388343772;
+ aaBlosum[ 2][ 0] = 0.485391055466; aaBlosum[ 2][ 1] = 1.297446705134; aaBlosum[ 2][ 2] = 0.000000000000; aaBlosum[ 2][ 3] = 3.180100048216; aaBlosum[ 2][ 4] = 0.397358949897;
+ aaBlosum[ 2][ 5] = 1.839216146992; aaBlosum[ 2][ 6] = 1.240488508640; aaBlosum[ 2][ 7] = 1.355872344485; aaBlosum[ 2][ 8] = 2.414501434208; aaBlosum[ 2][ 9] = 0.283017326278;
+ aaBlosum[ 2][10] = 0.211888159615; aaBlosum[ 2][11] = 1.593137043457; aaBlosum[ 2][12] = 0.648441278787; aaBlosum[ 2][13] = 0.354861249223; aaBlosum[ 2][14] = 0.494887043702;
+ aaBlosum[ 2][15] = 2.904101656456; aaBlosum[ 2][16] = 1.898173634533; aaBlosum[ 2][17] = 0.191482046247; aaBlosum[ 2][18] = 0.538222519037; aaBlosum[ 2][19] = 0.312858797993;
+ aaBlosum[ 3][ 0] = 0.543161820899; aaBlosum[ 3][ 1] = 0.500964408555; aaBlosum[ 3][ 2] = 3.180100048216; aaBlosum[ 3][ 3] = 0.000000000000; aaBlosum[ 3][ 4] = 0.240836614802;
+ aaBlosum[ 3][ 5] = 1.190945703396; aaBlosum[ 3][ 6] = 3.761625208368; aaBlosum[ 3][ 7] = 0.798473248968; aaBlosum[ 3][ 8] = 0.778142664022; aaBlosum[ 3][ 9] = 0.418555732462;
+ aaBlosum[ 3][10] = 0.218131577594; aaBlosum[ 3][11] = 1.032447924952; aaBlosum[ 3][12] = 0.222621897958; aaBlosum[ 3][13] = 0.281730694207; aaBlosum[ 3][14] = 0.730628272998;
+ aaBlosum[ 3][15] = 1.582754142065; aaBlosum[ 3][16] = 0.934187509431; aaBlosum[ 3][17] = 0.145345046279; aaBlosum[ 3][18] = 0.261422208965; aaBlosum[ 3][19] = 0.258129289418;
+ aaBlosum[ 4][ 0] = 1.459995310470; aaBlosum[ 4][ 1] = 0.227826574209; aaBlosum[ 4][ 2] = 0.397358949897; aaBlosum[ 4][ 3] = 0.240836614802; aaBlosum[ 4][ 4] = 0.000000000000;
+ aaBlosum[ 4][ 5] = 0.329801504630; aaBlosum[ 4][ 6] = 0.140748891814; aaBlosum[ 4][ 7] = 0.418203192284; aaBlosum[ 4][ 8] = 0.354058109831; aaBlosum[ 4][ 9] = 0.774894022794;
+ aaBlosum[ 4][10] = 0.831842640142; aaBlosum[ 4][11] = 0.285078800906; aaBlosum[ 4][12] = 0.767688823480; aaBlosum[ 4][13] = 0.441337471187; aaBlosum[ 4][14] = 0.356008498769;
+ aaBlosum[ 4][15] = 1.197188415094; aaBlosum[ 4][16] = 1.119831358516; aaBlosum[ 4][17] = 0.527664418872; aaBlosum[ 4][18] = 0.470237733696; aaBlosum[ 4][19] = 1.116352478606;
+ aaBlosum[ 5][ 0] = 1.199705704602; aaBlosum[ 5][ 1] = 3.020833610064; aaBlosum[ 5][ 2] = 1.839216146992; aaBlosum[ 5][ 3] = 1.190945703396; aaBlosum[ 5][ 4] = 0.329801504630;
+ aaBlosum[ 5][ 5] = 0.000000000000; aaBlosum[ 5][ 6] = 5.528919177928; aaBlosum[ 5][ 7] = 0.609846305383; aaBlosum[ 5][ 8] = 2.435341131140; aaBlosum[ 5][ 9] = 0.236202451204;
+ aaBlosum[ 5][10] = 0.580737093181; aaBlosum[ 5][11] = 3.945277674515; aaBlosum[ 5][12] = 2.494896077113; aaBlosum[ 5][13] = 0.144356959750; aaBlosum[ 5][14] = 0.858570575674;
+ aaBlosum[ 5][15] = 1.934870924596; aaBlosum[ 5][16] = 1.277480294596; aaBlosum[ 5][17] = 0.758653808642; aaBlosum[ 5][18] = 0.958989742850; aaBlosum[ 5][19] = 0.530785790125;
+ aaBlosum[ 6][ 0] = 1.170949042800; aaBlosum[ 6][ 1] = 1.360574190420; aaBlosum[ 6][ 2] = 1.240488508640; aaBlosum[ 6][ 3] = 3.761625208368; aaBlosum[ 6][ 4] = 0.140748891814;
+ aaBlosum[ 6][ 5] = 5.528919177928; aaBlosum[ 6][ 6] = 0.000000000000; aaBlosum[ 6][ 7] = 0.423579992176; aaBlosum[ 6][ 8] = 1.626891056982; aaBlosum[ 6][ 9] = 0.186848046932;
+ aaBlosum[ 6][10] = 0.372625175087; aaBlosum[ 6][11] = 2.802427151679; aaBlosum[ 6][12] = 0.555415397470; aaBlosum[ 6][13] = 0.291409084165; aaBlosum[ 6][14] = 0.926563934846;
+ aaBlosum[ 6][15] = 1.769893238937; aaBlosum[ 6][16] = 1.071097236007; aaBlosum[ 6][17] = 0.407635648938; aaBlosum[ 6][18] = 0.596719300346; aaBlosum[ 6][19] = 0.524253846338;
+ aaBlosum[ 7][ 0] = 1.955883574960; aaBlosum[ 7][ 1] = 0.418763308518; aaBlosum[ 7][ 2] = 1.355872344485; aaBlosum[ 7][ 3] = 0.798473248968; aaBlosum[ 7][ 4] = 0.418203192284;
+ aaBlosum[ 7][ 5] = 0.609846305383; aaBlosum[ 7][ 6] = 0.423579992176; aaBlosum[ 7][ 7] = 0.000000000000; aaBlosum[ 7][ 8] = 0.539859124954; aaBlosum[ 7][ 9] = 0.189296292376;
+ aaBlosum[ 7][10] = 0.217721159236; aaBlosum[ 7][11] = 0.752042440303; aaBlosum[ 7][12] = 0.459436173579; aaBlosum[ 7][13] = 0.368166464453; aaBlosum[ 7][14] = 0.504086599527;
+ aaBlosum[ 7][15] = 1.509326253224; aaBlosum[ 7][16] = 0.641436011405; aaBlosum[ 7][17] = 0.508358924638; aaBlosum[ 7][18] = 0.308055737035; aaBlosum[ 7][19] = 0.253340790190;
+ aaBlosum[ 8][ 0] = 0.716241444998; aaBlosum[ 8][ 1] = 1.456141166336; aaBlosum[ 8][ 2] = 2.414501434208; aaBlosum[ 8][ 3] = 0.778142664022; aaBlosum[ 8][ 4] = 0.354058109831;
+ aaBlosum[ 8][ 5] = 2.435341131140; aaBlosum[ 8][ 6] = 1.626891056982; aaBlosum[ 8][ 7] = 0.539859124954; aaBlosum[ 8][ 8] = 0.000000000000; aaBlosum[ 8][ 9] = 0.252718447885;
+ aaBlosum[ 8][10] = 0.348072209797; aaBlosum[ 8][11] = 1.022507035889; aaBlosum[ 8][12] = 0.984311525359; aaBlosum[ 8][13] = 0.714533703928; aaBlosum[ 8][14] = 0.527007339151;
+ aaBlosum[ 8][15] = 1.117029762910; aaBlosum[ 8][16] = 0.585407090225; aaBlosum[ 8][17] = 0.301248600780; aaBlosum[ 8][18] = 4.218953969389; aaBlosum[ 8][19] = 0.201555971750;
+ aaBlosum[ 9][ 0] = 0.605899003687; aaBlosum[ 9][ 1] = 0.232036445142; aaBlosum[ 9][ 2] = 0.283017326278; aaBlosum[ 9][ 3] = 0.418555732462; aaBlosum[ 9][ 4] = 0.774894022794;
+ aaBlosum[ 9][ 5] = 0.236202451204; aaBlosum[ 9][ 6] = 0.186848046932; aaBlosum[ 9][ 7] = 0.189296292376; aaBlosum[ 9][ 8] = 0.252718447885; aaBlosum[ 9][ 9] = 0.000000000000;
+ aaBlosum[ 9][10] = 3.890963773304; aaBlosum[ 9][11] = 0.406193586642; aaBlosum[ 9][12] = 3.364797763104; aaBlosum[ 9][13] = 1.517359325954; aaBlosum[ 9][14] = 0.388355409206;
+ aaBlosum[ 9][15] = 0.357544412460; aaBlosum[ 9][16] = 1.179091197260; aaBlosum[ 9][17] = 0.341985787540; aaBlosum[ 9][18] = 0.674617093228; aaBlosum[ 9][19] = 8.311839405458;
+ aaBlosum[10][ 0] = 0.800016530518; aaBlosum[10][ 1] = 0.622711669692; aaBlosum[10][ 2] = 0.211888159615; aaBlosum[10][ 3] = 0.218131577594; aaBlosum[10][ 4] = 0.831842640142;
+ aaBlosum[10][ 5] = 0.580737093181; aaBlosum[10][ 6] = 0.372625175087; aaBlosum[10][ 7] = 0.217721159236; aaBlosum[10][ 8] = 0.348072209797; aaBlosum[10][ 9] = 3.890963773304;
+ aaBlosum[10][10] = 0.000000000000; aaBlosum[10][11] = 0.445570274261; aaBlosum[10][12] = 6.030559379572; aaBlosum[10][13] = 2.064839703237; aaBlosum[10][14] = 0.374555687471;
+ aaBlosum[10][15] = 0.352969184527; aaBlosum[10][16] = 0.915259857694; aaBlosum[10][17] = 0.691474634600; aaBlosum[10][18] = 0.811245856323; aaBlosum[10][19] = 2.231405688913;
+ aaBlosum[11][ 0] = 1.295201266783; aaBlosum[11][ 1] = 5.411115141489; aaBlosum[11][ 2] = 1.593137043457; aaBlosum[11][ 3] = 1.032447924952; aaBlosum[11][ 4] = 0.285078800906;
+ aaBlosum[11][ 5] = 3.945277674515; aaBlosum[11][ 6] = 2.802427151679; aaBlosum[11][ 7] = 0.752042440303; aaBlosum[11][ 8] = 1.022507035889; aaBlosum[11][ 9] = 0.406193586642;
+ aaBlosum[11][10] = 0.445570274261; aaBlosum[11][11] = 0.000000000000; aaBlosum[11][12] = 1.073061184332; aaBlosum[11][13] = 0.266924750511; aaBlosum[11][14] = 1.047383450722;
+ aaBlosum[11][15] = 1.752165917819; aaBlosum[11][16] = 1.303875200799; aaBlosum[11][17] = 0.332243040634; aaBlosum[11][18] = 0.717993486900; aaBlosum[11][19] = 0.498138475304;
+ aaBlosum[12][ 0] = 1.253758266664; aaBlosum[12][ 1] = 0.983692987457; aaBlosum[12][ 2] = 0.648441278787; aaBlosum[12][ 3] = 0.222621897958; aaBlosum[12][ 4] = 0.767688823480;
+ aaBlosum[12][ 5] = 2.494896077113; aaBlosum[12][ 6] = 0.555415397470; aaBlosum[12][ 7] = 0.459436173579; aaBlosum[12][ 8] = 0.984311525359; aaBlosum[12][ 9] = 3.364797763104;
+ aaBlosum[12][10] = 6.030559379572; aaBlosum[12][11] = 1.073061184332; aaBlosum[12][12] = 0.000000000000; aaBlosum[12][13] = 1.773855168830; aaBlosum[12][14] = 0.454123625103;
+ aaBlosum[12][15] = 0.918723415746; aaBlosum[12][16] = 1.488548053722; aaBlosum[12][17] = 0.888101098152; aaBlosum[12][18] = 0.951682162246; aaBlosum[12][19] = 2.575850755315;
+ aaBlosum[13][ 0] = 0.492964679748; aaBlosum[13][ 1] = 0.371644693209; aaBlosum[13][ 2] = 0.354861249223; aaBlosum[13][ 3] = 0.281730694207; aaBlosum[13][ 4] = 0.441337471187;
+ aaBlosum[13][ 5] = 0.144356959750; aaBlosum[13][ 6] = 0.291409084165; aaBlosum[13][ 7] = 0.368166464453; aaBlosum[13][ 8] = 0.714533703928; aaBlosum[13][ 9] = 1.517359325954;
+ aaBlosum[13][10] = 2.064839703237; aaBlosum[13][11] = 0.266924750511; aaBlosum[13][12] = 1.773855168830; aaBlosum[13][13] = 0.000000000000; aaBlosum[13][14] = 0.233597909629;
+ aaBlosum[13][15] = 0.540027644824; aaBlosum[13][16] = 0.488206118793; aaBlosum[13][17] = 2.074324893497; aaBlosum[13][18] = 6.747260430801; aaBlosum[13][19] = 0.838119610178;
+ aaBlosum[14][ 0] = 1.173275900924; aaBlosum[14][ 1] = 0.448133661718; aaBlosum[14][ 2] = 0.494887043702; aaBlosum[14][ 3] = 0.730628272998; aaBlosum[14][ 4] = 0.356008498769;
+ aaBlosum[14][ 5] = 0.858570575674; aaBlosum[14][ 6] = 0.926563934846; aaBlosum[14][ 7] = 0.504086599527; aaBlosum[14][ 8] = 0.527007339151; aaBlosum[14][ 9] = 0.388355409206;
+ aaBlosum[14][10] = 0.374555687471; aaBlosum[14][11] = 1.047383450722; aaBlosum[14][12] = 0.454123625103; aaBlosum[14][13] = 0.233597909629; aaBlosum[14][14] = 0.000000000000;
+ aaBlosum[14][15] = 1.169129577716; aaBlosum[14][16] = 1.005451683149; aaBlosum[14][17] = 0.252214830027; aaBlosum[14][18] = 0.369405319355; aaBlosum[14][19] = 0.496908410676;
+ aaBlosum[15][ 0] = 4.325092687057; aaBlosum[15][ 1] = 1.122783104210; aaBlosum[15][ 2] = 2.904101656456; aaBlosum[15][ 3] = 1.582754142065; aaBlosum[15][ 4] = 1.197188415094;
+ aaBlosum[15][ 5] = 1.934870924596; aaBlosum[15][ 6] = 1.769893238937; aaBlosum[15][ 7] = 1.509326253224; aaBlosum[15][ 8] = 1.117029762910; aaBlosum[15][ 9] = 0.357544412460;
+ aaBlosum[15][10] = 0.352969184527; aaBlosum[15][11] = 1.752165917819; aaBlosum[15][12] = 0.918723415746; aaBlosum[15][13] = 0.540027644824; aaBlosum[15][14] = 1.169129577716;
+ aaBlosum[15][15] = 0.000000000000; aaBlosum[15][16] = 5.151556292270; aaBlosum[15][17] = 0.387925622098; aaBlosum[15][18] = 0.796751520761; aaBlosum[15][19] = 0.561925457442;
+ aaBlosum[16][ 0] = 1.729178019485; aaBlosum[16][ 1] = 0.914665954563; aaBlosum[16][ 2] = 1.898173634533; aaBlosum[16][ 3] = 0.934187509431; aaBlosum[16][ 4] = 1.119831358516;
+ aaBlosum[16][ 5] = 1.277480294596; aaBlosum[16][ 6] = 1.071097236007; aaBlosum[16][ 7] = 0.641436011405; aaBlosum[16][ 8] = 0.585407090225; aaBlosum[16][ 9] = 1.179091197260;
+ aaBlosum[16][10] = 0.915259857694; aaBlosum[16][11] = 1.303875200799; aaBlosum[16][12] = 1.488548053722; aaBlosum[16][13] = 0.488206118793; aaBlosum[16][14] = 1.005451683149;
+ aaBlosum[16][15] = 5.151556292270; aaBlosum[16][16] = 0.000000000000; aaBlosum[16][17] = 0.513128126891; aaBlosum[16][18] = 0.801010243199; aaBlosum[16][19] = 2.253074051176;
+ aaBlosum[17][ 0] = 0.465839367725; aaBlosum[17][ 1] = 0.426382310122; aaBlosum[17][ 2] = 0.191482046247; aaBlosum[17][ 3] = 0.145345046279; aaBlosum[17][ 4] = 0.527664418872;
+ aaBlosum[17][ 5] = 0.758653808642; aaBlosum[17][ 6] = 0.407635648938; aaBlosum[17][ 7] = 0.508358924638; aaBlosum[17][ 8] = 0.301248600780; aaBlosum[17][ 9] = 0.341985787540;
+ aaBlosum[17][10] = 0.691474634600; aaBlosum[17][11] = 0.332243040634; aaBlosum[17][12] = 0.888101098152; aaBlosum[17][13] = 2.074324893497; aaBlosum[17][14] = 0.252214830027;
+ aaBlosum[17][15] = 0.387925622098; aaBlosum[17][16] = 0.513128126891; aaBlosum[17][17] = 0.000000000000; aaBlosum[17][18] = 4.054419006558; aaBlosum[17][19] = 0.266508731426;
+ aaBlosum[18][ 0] = 0.718206697586; aaBlosum[18][ 1] = 0.720517441216; aaBlosum[18][ 2] = 0.538222519037; aaBlosum[18][ 3] = 0.261422208965; aaBlosum[18][ 4] = 0.470237733696;
+ aaBlosum[18][ 5] = 0.958989742850; aaBlosum[18][ 6] = 0.596719300346; aaBlosum[18][ 7] = 0.308055737035; aaBlosum[18][ 8] = 4.218953969389; aaBlosum[18][ 9] = 0.674617093228;
+ aaBlosum[18][10] = 0.811245856323; aaBlosum[18][11] = 0.717993486900; aaBlosum[18][12] = 0.951682162246; aaBlosum[18][13] = 6.747260430801; aaBlosum[18][14] = 0.369405319355;
+ aaBlosum[18][15] = 0.796751520761; aaBlosum[18][16] = 0.801010243199; aaBlosum[18][17] = 4.054419006558; aaBlosum[18][18] = 0.000000000000; aaBlosum[18][19] = 1.000000000000;
+ aaBlosum[19][ 0] = 2.187774522005; aaBlosum[19][ 1] = 0.438388343772; aaBlosum[19][ 2] = 0.312858797993; aaBlosum[19][ 3] = 0.258129289418; aaBlosum[19][ 4] = 1.116352478606;
+ aaBlosum[19][ 5] = 0.530785790125; aaBlosum[19][ 6] = 0.524253846338; aaBlosum[19][ 7] = 0.253340790190; aaBlosum[19][ 8] = 0.201555971750; aaBlosum[19][ 9] = 8.311839405458;
+ aaBlosum[19][10] = 2.231405688913; aaBlosum[19][11] = 0.498138475304; aaBlosum[19][12] = 2.575850755315; aaBlosum[19][13] = 0.838119610178; aaBlosum[19][14] = 0.496908410676;
+ aaBlosum[19][15] = 0.561925457442; aaBlosum[19][16] = 2.253074051176; aaBlosum[19][17] = 0.266508731426; aaBlosum[19][18] = 1.000000000000; aaBlosum[19][19] = 0.000000000000;
+
+ blosPi[ 0] = 0.074;
+ blosPi[ 1] = 0.052;
+ blosPi[ 2] = 0.045;
+ blosPi[ 3] = 0.054;
+ blosPi[ 4] = 0.025;
+ blosPi[ 5] = 0.034;
+ blosPi[ 6] = 0.054;
+ blosPi[ 7] = 0.074;
+ blosPi[ 8] = 0.026;
+ blosPi[ 9] = 0.068;
+ blosPi[10] = 0.099;
+ blosPi[11] = 0.058;
+ blosPi[12] = 0.025;
+ blosPi[13] = 0.047;
+ blosPi[14] = 0.039;
+ blosPi[15] = 0.057;
+ blosPi[16] = 0.051;
+ blosPi[17] = 0.013;
+ blosPi[18] = 0.032;
+ blosPi[19] = 0.073;
+
+ /* LG */
+ aaLG[ 0][ 0] = 0.000000; aaLG[ 0][ 1] = 0.425093; aaLG[ 0][ 2] = 0.276818; aaLG[ 0][ 3] = 0.395144; aaLG[ 0][ 4] = 2.489084;
+ aaLG[ 0][ 5] = 0.969894; aaLG[ 0][ 6] = 1.038545; aaLG[ 0][ 7] = 2.066040; aaLG[ 0][ 8] = 0.358858; aaLG[ 0][ 9] = 0.149830;
+ aaLG[ 0][10] = 0.395337; aaLG[ 0][11] = 0.536518; aaLG[ 0][12] = 1.124035; aaLG[ 0][13] = 0.253701; aaLG[ 0][14] = 1.177651;
+ aaLG[ 0][15] = 4.727182; aaLG[ 0][16] = 2.139501; aaLG[ 0][17] = 0.180717; aaLG[ 0][18] = 0.218959; aaLG[ 0][19] = 2.547870;
+ aaLG[ 1][ 0] = 0.425093; aaLG[ 1][ 1] = 0.000000; aaLG[ 1][ 2] = 0.751878; aaLG[ 1][ 3] = 0.123954; aaLG[ 1][ 4] = 0.534551;
+ aaLG[ 1][ 5] = 2.807908; aaLG[ 1][ 6] = 0.363970; aaLG[ 1][ 7] = 0.390192; aaLG[ 1][ 8] = 2.426601; aaLG[ 1][ 9] = 0.126991;
+ aaLG[ 1][10] = 0.301848; aaLG[ 1][11] = 6.326067; aaLG[ 1][12] = 0.484133; aaLG[ 1][13] = 0.052722; aaLG[ 1][14] = 0.332533;
+ aaLG[ 1][15] = 0.858151; aaLG[ 1][16] = 0.578987; aaLG[ 1][17] = 0.593607; aaLG[ 1][18] = 0.314440; aaLG[ 1][19] = 0.170887;
+ aaLG[ 2][ 0] = 0.276818; aaLG[ 2][ 1] = 0.751878; aaLG[ 2][ 2] = 0.000000; aaLG[ 2][ 3] = 5.076149; aaLG[ 2][ 4] = 0.528768;
+ aaLG[ 2][ 5] = 1.695752; aaLG[ 2][ 6] = 0.541712; aaLG[ 2][ 7] = 1.437645; aaLG[ 2][ 8] = 4.509238; aaLG[ 2][ 9] = 0.191503;
+ aaLG[ 2][10] = 0.068427; aaLG[ 2][11] = 2.145078; aaLG[ 2][12] = 0.371004; aaLG[ 2][13] = 0.089525; aaLG[ 2][14] = 0.161787;
+ aaLG[ 2][15] = 4.008358; aaLG[ 2][16] = 2.000679; aaLG[ 2][17] = 0.045376; aaLG[ 2][18] = 0.612025; aaLG[ 2][19] = 0.083688;
+ aaLG[ 3][ 0] = 0.395144; aaLG[ 3][ 1] = 0.123954; aaLG[ 3][ 2] = 5.076149; aaLG[ 3][ 3] = 0.000000; aaLG[ 3][ 4] = 0.062556;
+ aaLG[ 3][ 5] = 0.523386; aaLG[ 3][ 6] = 5.243870; aaLG[ 3][ 7] = 0.844926; aaLG[ 3][ 8] = 0.927114; aaLG[ 3][ 9] = 0.010690;
+ aaLG[ 3][10] = 0.015076; aaLG[ 3][11] = 0.282959; aaLG[ 3][12] = 0.025548; aaLG[ 3][13] = 0.017416; aaLG[ 3][14] = 0.394456;
+ aaLG[ 3][15] = 1.240275; aaLG[ 3][16] = 0.425860; aaLG[ 3][17] = 0.029890; aaLG[ 3][18] = 0.135107; aaLG[ 3][19] = 0.037967;
+ aaLG[ 4][ 0] = 2.489084; aaLG[ 4][ 1] = 0.534551; aaLG[ 4][ 2] = 0.528768; aaLG[ 4][ 3] = 0.062556; aaLG[ 4][ 4] = 0.000000;
+ aaLG[ 4][ 5] = 0.084808; aaLG[ 4][ 6] = 0.003499; aaLG[ 4][ 7] = 0.569265; aaLG[ 4][ 8] = 0.640543; aaLG[ 4][ 9] = 0.320627;
+ aaLG[ 4][10] = 0.594007; aaLG[ 4][11] = 0.013266; aaLG[ 4][12] = 0.893680; aaLG[ 4][13] = 1.105251; aaLG[ 4][14] = 0.075382;
+ aaLG[ 4][15] = 2.784478; aaLG[ 4][16] = 1.143480; aaLG[ 4][17] = 0.670128; aaLG[ 4][18] = 1.165532; aaLG[ 4][19] = 1.959291;
+ aaLG[ 5][ 0] = 0.969894; aaLG[ 5][ 1] = 2.807908; aaLG[ 5][ 2] = 1.695752; aaLG[ 5][ 3] = 0.523386; aaLG[ 5][ 4] = 0.084808;
+ aaLG[ 5][ 5] = 0.000000; aaLG[ 5][ 6] = 4.128591; aaLG[ 5][ 7] = 0.267959; aaLG[ 5][ 8] = 4.813505; aaLG[ 5][ 9] = 0.072854;
+ aaLG[ 5][10] = 0.582457; aaLG[ 5][11] = 3.234294; aaLG[ 5][12] = 1.672569; aaLG[ 5][13] = 0.035855; aaLG[ 5][14] = 0.624294;
+ aaLG[ 5][15] = 1.223828; aaLG[ 5][16] = 1.080136; aaLG[ 5][17] = 0.236199; aaLG[ 5][18] = 0.257336; aaLG[ 5][19] = 0.210332;
+ aaLG[ 6][ 0] = 1.038545; aaLG[ 6][ 1] = 0.363970; aaLG[ 6][ 2] = 0.541712; aaLG[ 6][ 3] = 5.243870; aaLG[ 6][ 4] = 0.003499;
+ aaLG[ 6][ 5] = 4.128591; aaLG[ 6][ 6] = 0.000000; aaLG[ 6][ 7] = 0.348847; aaLG[ 6][ 8] = 0.423881; aaLG[ 6][ 9] = 0.044265;
+ aaLG[ 6][10] = 0.069673; aaLG[ 6][11] = 1.807177; aaLG[ 6][12] = 0.173735; aaLG[ 6][13] = 0.018811; aaLG[ 6][14] = 0.419409;
+ aaLG[ 6][15] = 0.611973; aaLG[ 6][16] = 0.604545; aaLG[ 6][17] = 0.077852; aaLG[ 6][18] = 0.120037; aaLG[ 6][19] = 0.245034;
+ aaLG[ 7][ 0] = 2.066040; aaLG[ 7][ 1] = 0.390192; aaLG[ 7][ 2] = 1.437645; aaLG[ 7][ 3] = 0.844926; aaLG[ 7][ 4] = 0.569265;
+ aaLG[ 7][ 5] = 0.267959; aaLG[ 7][ 6] = 0.348847; aaLG[ 7][ 7] = 0.000000; aaLG[ 7][ 8] = 0.311484; aaLG[ 7][ 9] = 0.008705;
+ aaLG[ 7][10] = 0.044261; aaLG[ 7][11] = 0.296636; aaLG[ 7][12] = 0.139538; aaLG[ 7][13] = 0.089586; aaLG[ 7][14] = 0.196961;
+ aaLG[ 7][15] = 1.739990; aaLG[ 7][16] = 0.129836; aaLG[ 7][17] = 0.268491; aaLG[ 7][18] = 0.054679; aaLG[ 7][19] = 0.076701;
+ aaLG[ 8][ 0] = 0.358858; aaLG[ 8][ 1] = 2.426601; aaLG[ 8][ 2] = 4.509238; aaLG[ 8][ 3] = 0.927114; aaLG[ 8][ 4] = 0.640543;
+ aaLG[ 8][ 5] = 4.813505; aaLG[ 8][ 6] = 0.423881; aaLG[ 8][ 7] = 0.311484; aaLG[ 8][ 8] = 0.000000; aaLG[ 8][ 9] = 0.108882;
+ aaLG[ 8][10] = 0.366317; aaLG[ 8][11] = 0.697264; aaLG[ 8][12] = 0.442472; aaLG[ 8][13] = 0.682139; aaLG[ 8][14] = 0.508851;
+ aaLG[ 8][15] = 0.990012; aaLG[ 8][16] = 0.584262; aaLG[ 8][17] = 0.597054; aaLG[ 8][18] = 5.306834; aaLG[ 8][19] = 0.119013;
+ aaLG[ 9][ 0] = 0.149830; aaLG[ 9][ 1] = 0.126991; aaLG[ 9][ 2] = 0.191503; aaLG[ 9][ 3] = 0.010690; aaLG[ 9][ 4] = 0.320627;
+ aaLG[ 9][ 5] = 0.072854; aaLG[ 9][ 6] = 0.044265; aaLG[ 9][ 7] = 0.008705; aaLG[ 9][ 8] = 0.108882; aaLG[ 9][ 9] = 0.000000;
+ aaLG[ 9][10] = 4.145067; aaLG[ 9][11] = 0.159069; aaLG[ 9][12] = 4.273607; aaLG[ 9][13] = 1.112727; aaLG[ 9][14] = 0.078281;
+ aaLG[ 9][15] = 0.064105; aaLG[ 9][16] = 1.033739; aaLG[ 9][17] = 0.111660; aaLG[ 9][18] = 0.232523; aaLG[ 9][19] = 10.649107;
+ aaLG[10][ 0] = 0.395337; aaLG[10][ 1] = 0.301848; aaLG[10][ 2] = 0.068427; aaLG[10][ 3] = 0.015076; aaLG[10][ 4] = 0.594007;
+ aaLG[10][ 5] = 0.582457; aaLG[10][ 6] = 0.069673; aaLG[10][ 7] = 0.044261; aaLG[10][ 8] = 0.366317; aaLG[10][ 9] = 4.145067;
+ aaLG[10][10] = 0.000000; aaLG[10][11] = 0.137500; aaLG[10][12] = 6.312358; aaLG[10][13] = 2.592692; aaLG[10][14] = 0.249060;
+ aaLG[10][15] = 0.182287; aaLG[10][16] = 0.302936; aaLG[10][17] = 0.619632; aaLG[10][18] = 0.299648; aaLG[10][19] = 1.702745;
+ aaLG[11][ 0] = 0.536518; aaLG[11][ 1] = 6.326067; aaLG[11][ 2] = 2.145078; aaLG[11][ 3] = 0.282959; aaLG[11][ 4] = 0.013266;
+ aaLG[11][ 5] = 3.234294; aaLG[11][ 6] = 1.807177; aaLG[11][ 7] = 0.296636; aaLG[11][ 8] = 0.697264; aaLG[11][ 9] = 0.159069;
+ aaLG[11][10] = 0.137500; aaLG[11][11] = 0.000000; aaLG[11][12] = 0.656604; aaLG[11][13] = 0.023918; aaLG[11][14] = 0.390322;
+ aaLG[11][15] = 0.748683; aaLG[11][16] = 1.136863; aaLG[11][17] = 0.049906; aaLG[11][18] = 0.131932; aaLG[11][19] = 0.185202;
+ aaLG[12][ 0] = 1.124035; aaLG[12][ 1] = 0.484133; aaLG[12][ 2] = 0.371004; aaLG[12][ 3] = 0.025548; aaLG[12][ 4] = 0.893680;
+ aaLG[12][ 5] = 1.672569; aaLG[12][ 6] = 0.173735; aaLG[12][ 7] = 0.139538; aaLG[12][ 8] = 0.442472; aaLG[12][ 9] = 4.273607;
+ aaLG[12][10] = 6.312358; aaLG[12][11] = 0.656604; aaLG[12][12] = 0.000000; aaLG[12][13] = 1.798853; aaLG[12][14] = 0.099849;
+ aaLG[12][15] = 0.346960; aaLG[12][16] = 2.020366; aaLG[12][17] = 0.696175; aaLG[12][18] = 0.481306; aaLG[12][19] = 1.898718;
+ aaLG[13][ 0] = 0.253701; aaLG[13][ 1] = 0.052722; aaLG[13][ 2] = 0.089525; aaLG[13][ 3] = 0.017416; aaLG[13][ 4] = 1.105251;
+ aaLG[13][ 5] = 0.035855; aaLG[13][ 6] = 0.018811; aaLG[13][ 7] = 0.089586; aaLG[13][ 8] = 0.682139; aaLG[13][ 9] = 1.112727;
+ aaLG[13][10] = 2.592692; aaLG[13][11] = 0.023918; aaLG[13][12] = 1.798853; aaLG[13][13] = 0.000000; aaLG[13][14] = 0.094464;
+ aaLG[13][15] = 0.361819; aaLG[13][16] = 0.165001; aaLG[13][17] = 2.457121; aaLG[13][18] = 7.803902; aaLG[13][19] = 0.654683;
+ aaLG[14][ 0] = 1.177651; aaLG[14][ 1] = 0.332533; aaLG[14][ 2] = 0.161787; aaLG[14][ 3] = 0.394456; aaLG[14][ 4] = 0.075382;
+ aaLG[14][ 5] = 0.624294; aaLG[14][ 6] = 0.419409; aaLG[14][ 7] = 0.196961; aaLG[14][ 8] = 0.508851; aaLG[14][ 9] = 0.078281;
+ aaLG[14][10] = 0.249060; aaLG[14][11] = 0.390322; aaLG[14][12] = 0.099849; aaLG[14][13] = 0.094464; aaLG[14][14] = 0.000000;
+ aaLG[14][15] = 1.338132; aaLG[14][16] = 0.571468; aaLG[14][17] = 0.095131; aaLG[14][18] = 0.089613; aaLG[14][19] = 0.296501;
+ aaLG[15][ 0] = 4.727182; aaLG[15][ 1] = 0.858151; aaLG[15][ 2] = 4.008358; aaLG[15][ 3] = 1.240275; aaLG[15][ 4] = 2.784478;
+ aaLG[15][ 5] = 1.223828; aaLG[15][ 6] = 0.611973; aaLG[15][ 7] = 1.739990; aaLG[15][ 8] = 0.990012; aaLG[15][ 9] = 0.064105;
+ aaLG[15][10] = 0.182287; aaLG[15][11] = 0.748683; aaLG[15][12] = 0.346960; aaLG[15][13] = 0.361819; aaLG[15][14] = 1.338132;
+ aaLG[15][15] = 0.000000; aaLG[15][16] = 6.472279; aaLG[15][17] = 0.248862; aaLG[15][18] = 0.400547; aaLG[15][19] = 0.098369;
+ aaLG[16][ 0] = 2.139501; aaLG[16][ 1] = 0.578987; aaLG[16][ 2] = 2.000679; aaLG[16][ 3] = 0.425860; aaLG[16][ 4] = 1.143480;
+ aaLG[16][ 5] = 1.080136; aaLG[16][ 6] = 0.604545; aaLG[16][ 7] = 0.129836; aaLG[16][ 8] = 0.584262; aaLG[16][ 9] = 1.033739;
+ aaLG[16][10] = 0.302936; aaLG[16][11] = 1.136863; aaLG[16][12] = 2.020366; aaLG[16][13] = 0.165001; aaLG[16][14] = 0.571468;
+ aaLG[16][15] = 6.472279; aaLG[16][16] = 0.000000; aaLG[16][17] = 0.140825; aaLG[16][18] = 0.245841; aaLG[16][19] = 2.188158;
+ aaLG[17][ 0] = 0.180717; aaLG[17][ 1] = 0.593607; aaLG[17][ 2] = 0.045376; aaLG[17][ 3] = 0.029890; aaLG[17][ 4] = 0.670128;
+ aaLG[17][ 5] = 0.236199; aaLG[17][ 6] = 0.077852; aaLG[17][ 7] = 0.268491; aaLG[17][ 8] = 0.597054; aaLG[17][ 9] = 0.111660;
+ aaLG[17][10] = 0.619632; aaLG[17][11] = 0.049906; aaLG[17][12] = 0.696175; aaLG[17][13] = 2.457121; aaLG[17][14] = 0.095131;
+ aaLG[17][15] = 0.248862; aaLG[17][16] = 0.140825; aaLG[17][17] = 0.000000; aaLG[17][18] = 3.151815; aaLG[17][19] = 0.189510;
+ aaLG[18][ 0] = 0.218959; aaLG[18][ 1] = 0.314440; aaLG[18][ 2] = 0.612025; aaLG[18][ 3] = 0.135107; aaLG[18][ 4] = 1.165532;
+ aaLG[18][ 5] = 0.257336; aaLG[18][ 6] = 0.120037; aaLG[18][ 7] = 0.054679; aaLG[18][ 8] = 5.306834; aaLG[18][ 9] = 0.232523;
+ aaLG[18][10] = 0.299648; aaLG[18][11] = 0.131932; aaLG[18][12] = 0.481306; aaLG[18][13] = 7.803902; aaLG[18][14] = 0.089613;
+ aaLG[18][15] = 0.400547; aaLG[18][16] = 0.245841; aaLG[18][17] = 3.151815; aaLG[18][18] = 0.000000; aaLG[18][19] = 0.249313;
+ aaLG[19][ 0] = 2.547870; aaLG[19][ 1] = 0.170887; aaLG[19][ 2] = 0.083688; aaLG[19][ 3] = 0.037967; aaLG[19][ 4] = 1.959291;
+ aaLG[19][ 5] = 0.210332; aaLG[19][ 6] = 0.245034; aaLG[19][ 7] = 0.076701; aaLG[19][ 8] = 0.119013; aaLG[19][ 9] = 10.649107;
+ aaLG[19][10] = 1.702745; aaLG[19][11] = 0.185202; aaLG[19][12] = 1.898718; aaLG[19][13] = 0.654683; aaLG[19][14] = 0.296501;
+ aaLG[19][15] = 0.098369; aaLG[19][16] = 2.188158; aaLG[19][17] = 0.189510; aaLG[19][18] = 0.249313; aaLG[19][19] = 0.000000;
+
+ lgPi[0] = 0.079066; lgPi[1] = 0.055941; lgPi[2] = 0.041977; lgPi[3] = 0.053052;
+ lgPi[4] = 0.012937; lgPi[5] = 0.040767; lgPi[6] = 0.071586; lgPi[7] = 0.057337;
+ lgPi[8] = 0.022355; lgPi[9] = 0.062157; lgPi[10] = 0.099081; lgPi[11] = 0.064600;
+ lgPi[12] = 0.022951; lgPi[13] = 0.042302; lgPi[14] = 0.044040; lgPi[15] = 0.061197;
+ lgPi[16] = 0.053287; lgPi[17] = 0.012066; lgPi[18] = 0.034155; lgPi[19] = 0.069147;
+
+ /* now, check that the matrices are symmetrical */
+ for (i=0; i<20; i++)
+ {
+ for (j=i+1; j<20; j++)
+ {
+ diff = aaJones[i][j] - aaJones[j][i];
+ if (diff < 0.0)
+ diff = -diff;
+ if (diff > 0.001)
+ {
+ MrBayesPrint ("%s ERROR: Jones model is not symmetrical.\n");
+ return (ERROR);
+ }
+ }
+ }
+ for (i=0; i<20; i++)
+ {
+ for (j=i+1; j<20; j++)
+ {
+ diff = aaDayhoff[i][j] - aaDayhoff[j][i];
+ if (diff < 0.0)
+ diff = -diff;
+ if (diff > 0.001)
+ {
+ MrBayesPrint ("%s ERROR: Dayhoff model is not symmetrical.\n");
+ return (ERROR);
+ }
+ }
+ }
+ for (i=0; i<20; i++)
+ {
+ for (j=i+1; j<20; j++)
+ {
+ diff = aaMtrev24[i][j] - aaMtrev24[j][i];
+ if (diff < 0.0)
+ diff = -diff;
+ if (diff > 0.001)
+ {
+ MrBayesPrint ("%s ERROR: mtrev24 model is not symmetrical.\n");
+ return (ERROR);
+ }
+ }
+ }
+ for (i=0; i<20; i++)
+ {
+ for (j=i+1; j<20; j++)
+ {
+ diff = aaMtmam[i][j] - aaMtmam[j][i];
+ if (diff < 0.0)
+ diff = -diff;
+ if (diff > 0.001)
+ {
+ MrBayesPrint ("%s ERROR: mtmam model is not symmetrical.\n");
+ return (ERROR);
+ }
+ }
+ }
+ for (i=0; i<20; i++)
+ {
+ for (j=i+1; j<20; j++)
+ {
+ diff = aartREV[i][j] - aartREV[j][i];
+ if (diff < 0.0)
+ diff = -diff;
+ if (diff > 0.001)
+ {
+ MrBayesPrint ("%s ERROR: aartREV model is not symmetrical.\n");
+ return (ERROR);
+ }
+ }
+ }
+ for (i=0; i<20; i++)
+ {
+ for (j=i+1; j<20; j++)
+ {
+ diff = aaWAG[i][j] - aaWAG[j][i];
+ if (diff < 0.0)
+ diff = -diff;
+ if (diff > 0.001)
+ {
+ MrBayesPrint ("%s ERROR: aaWAG model is not symmetrical.\n");
+ return (ERROR);
+ }
+ }
+ }
+ for (i=0; i<20; i++)
+ {
+ for (j=i+1; j<20; j++)
+ {
+ diff = aacpREV[i][j] - aacpREV[j][i];
+ if (diff < 0.0)
+ diff = -diff;
+ if (diff > 0.001)
+ {
+ MrBayesPrint ("%s ERROR: cpREV model is not symmetrical.\n");
+ return (ERROR);
+ }
+ }
+ }
+ for (i=0; i<20; i++)
+ {
+ for (j=i+1; j<20; j++)
+ {
+ diff = aaVt[i][j] - aaVt[j][i];
+ if (diff < 0.0)
+ diff = -diff;
+ if (diff > 0.001)
+ {
+ MrBayesPrint ("%s ERROR: Vt model is not symmetrical.\n");
+ return (ERROR);
+ }
+ }
+ }
+ for (i=0; i<20; i++)
+ {
+ for (j=i+1; j<20; j++)
+ {
+ diff = aaBlosum[i][j] - aaBlosum[j][i];
+ if (diff < 0.0)
+ diff = -diff;
+ if (diff > 0.001)
+ {
+ MrBayesPrint ("%s ERROR: Blosum model is not symmetrical.\n");
+ return (ERROR);
+ }
+ }
+ }
+ for (i=0; i<20; i++)
+ {
+ for (j=i+1; j<20; j++)
+ {
+ diff = aaLG[i][j] - aaLG[j][i];
+ if (diff < 0.0)
+ diff = -diff;
+ if (diff > 0.001)
+ {
+ MrBayesPrint ("%s ERROR: LG model is not symmetrical.\n");
+ return (ERROR);
+ }
+ }
+ }
+
+ /* rescale stationary frequencies, to make certain they sum to 1.0 */
+ sum = 0.0;
+ for (i=0; i<20; i++)
+ sum += jonesPi[i];
+ for (i=0; i<20; i++)
+ jonesPi[i] /= sum;
+ sum = 0.0;
+ for (i=0; i<20; i++)
+ sum += dayhoffPi[i];
+ for (i=0; i<20; i++)
+ dayhoffPi[i] /= sum;
+ sum = 0.0;
+ for (i=0; i<20; i++)
+ sum += mtrev24Pi[i];
+ for (i=0; i<20; i++)
+ mtrev24Pi[i] /= sum;
+ sum = 0.0;
+ for (i=0; i<20; i++)
+ sum += mtmamPi[i];
+ for (i=0; i<20; i++)
+ mtmamPi[i] /= sum;
+ sum = 0.0;
+ for (i=0; i<20; i++)
+ sum += rtrevPi[i];
+ for (i=0; i<20; i++)
+ rtrevPi[i] /= sum;
+ sum = 0.0;
+ for (i=0; i<20; i++)
+ sum += wagPi[i];
+ for (i=0; i<20; i++)
+ wagPi[i] /= sum;
+ sum = 0.0;
+ for (i=0; i<20; i++)
+ sum += cprevPi[i];
+ for (i=0; i<20; i++)
+ cprevPi[i] /= sum;
+ sum = 0.0;
+ for (i=0; i<20; i++)
+ sum += vtPi[i];
+ for (i=0; i<20; i++)
+ vtPi[i] /= sum;
+ sum = 0.0;
+ for (i=0; i<20; i++)
+ sum += blosPi[i];
+ for (i=0; i<20; i++)
+ blosPi[i] /= sum;
+ sum = 0.0;
+ for (i=0; i<20; i++)
+ sum += lgPi[i];
+ for (i=0; i<20; i++)
+ lgPi[i] /= sum;
+
+ /* multiply entries by amino acid frequencies */
+ for (i=0; i<20; i++)
+ {
+ for (j=0; j<20; j++)
+ {
+ aaJones[i][j] *= jonesPi[j];
+ aaDayhoff[i][j] *= dayhoffPi[j];
+ aaMtrev24[i][j] *= mtrev24Pi[j];
+ aaMtmam[i][j] *= mtmamPi[j];
+ aartREV[i][j] *= rtrevPi[j];
+ aaWAG[i][j] *= wagPi[j];
+ aacpREV[i][j] *= cprevPi[j];
+ aaVt[i][j] *= vtPi[j];
+ aaBlosum[i][j] *= blosPi[j];
+ aaLG[i][j] *= lgPi[j];
+ }
+ }
+
+ /* rescale, so branch lengths are in terms of expected number of
+ amino acid substitutions per site */
+ scaler = 0.0;
+ for (i=0; i<20; i++)
+ {
+ for (j=i+1; j<20; j++)
+ {
+ scaler += jonesPi[i] * aaJones[i][j];
+ scaler += jonesPi[j] * aaJones[j][i];
+ }
+ }
+ scaler = 1.0 / scaler;
+ for (i=0; i<20; i++)
+ for (j=0; j<20; j++)
+ aaJones[i][j] *= scaler;
+ scaler = 0.0;
+ for (i=0; i<20; i++)
+ {
+ for (j=i+1; j<20; j++)
+ {
+ scaler += dayhoffPi[i] * aaDayhoff[i][j];
+ scaler += dayhoffPi[j] * aaDayhoff[j][i];
+ }
+ }
+ scaler = 1.0 / scaler;
+ for (i=0; i<20; i++)
+ for (j=0; j<20; j++)
+ aaDayhoff[i][j] *= scaler;
+ scaler = 0.0;
+ for (i=0; i<20; i++)
+ {
+ for (j=i+1; j<20; j++)
+ {
+ scaler += mtrev24Pi[i] * aaMtrev24[i][j];
+ scaler += mtrev24Pi[j] * aaMtrev24[j][i];
+ }
+ }
+ scaler = 1.0 / scaler;
+ for (i=0; i<20; i++)
+ for (j=0; j<20; j++)
+ aaMtrev24[i][j] *= scaler;
+ scaler = 0.0;
+ for (i=0; i<20; i++)
+ {
+ for (j=i+1; j<20; j++)
+ {
+ scaler += mtmamPi[i] * aaMtmam[i][j];
+ scaler += mtmamPi[j] * aaMtmam[j][i];
+ }
+ }
+ scaler = 1.0 / scaler;
+ for (i=0; i<20; i++)
+ for (j=0; j<20; j++)
+ aaMtmam[i][j] *= scaler;
+ scaler = 0.0;
+ for (i=0; i<20; i++)
+ {
+ for (j=i+1; j<20; j++)
+ {
+ scaler += rtrevPi[i] * aartREV[i][j];
+ scaler += rtrevPi[j] * aartREV[j][i];
+ }
+ }
+ scaler = 1.0 / scaler;
+ for (i=0; i<20; i++)
+ for (j=0; j<20; j++)
+ aartREV[i][j] *= scaler;
+ scaler = 0.0;
+ for (i=0; i<20; i++)
+ {
+ for (j=i+1; j<20; j++)
+ {
+ scaler += wagPi[i] * aaWAG[i][j];
+ scaler += wagPi[j] * aaWAG[j][i];
+ }
+ }
+ scaler = 1.0 / scaler;
+ for (i=0; i<20; i++)
+ for (j=0; j<20; j++)
+ aaWAG[i][j] *= scaler;
+ scaler = 0.0;
+ for (i=0; i<20; i++)
+ {
+ for (j=i+1; j<20; j++)
+ {
+ scaler += cprevPi[i] * aacpREV[i][j];
+ scaler += cprevPi[j] * aacpREV[j][i];
+ }
+ }
+ scaler = 1.0 / scaler;
+ for (i=0; i<20; i++)
+ for (j=0; j<20; j++)
+ aacpREV[i][j] *= scaler;
+ scaler = 0.0;
+ for (i=0; i<20; i++)
+ {
+ for (j=i+1; j<20; j++)
+ {
+ scaler += vtPi[i] * aaVt[i][j];
+ scaler += vtPi[j] * aaVt[j][i];
+ }
+ }
+ scaler = 1.0 / scaler;
+ for (i=0; i<20; i++)
+ for (j=0; j<20; j++)
+ aaVt[i][j] *= scaler;
+ scaler = 0.0;
+ for (i=0; i<20; i++)
+ {
+ for (j=i+1; j<20; j++)
+ {
+ scaler += blosPi[i] * aaBlosum[i][j];
+ scaler += blosPi[j] * aaBlosum[j][i];
+ }
+ }
+ scaler = 1.0 / scaler;
+ for (i=0; i<20; i++)
+ for (j=0; j<20; j++)
+ aaBlosum[i][j] *= scaler;
+ scaler = 0.0;
+ for (i=0; i<20; i++)
+ {
+ for (j=i+1; j<20; j++)
+ {
+ scaler += lgPi[i] * aaLG[i][j];
+ scaler += lgPi[j] * aaLG[j][i];
+ }
+ }
+ scaler = 1.0 / scaler;
+ for (i=0; i<20; i++)
+ for (j=0; j<20; j++)
+ aaLG[i][j] *= scaler;
+
+ /* set diagonal of matrix */
+ for (i=0; i<20; i++)
+ {
+ sum = 0.0;
+ for (j=0; j<20; j++)
+ {
+ if (i != j)
+ sum += aaJones[i][j];
+ }
+ aaJones[i][i] = -sum;
+ }
+ for (i=0; i<20; i++)
+ {
+ sum = 0.0;
+ for (j=0; j<20; j++)
+ {
+ if (i != j)
+ sum += aaDayhoff[i][j];
+ }
+ aaDayhoff[i][i] = -sum;
+ }
+ for (i=0; i<20; i++)
+ {
+ sum = 0.0;
+ for (j=0; j<20; j++)
+ {
+ if (i != j)
+ sum += aaMtrev24[i][j];
+ }
+ aaMtrev24[i][i] = -sum;
+ }
+ for (i=0; i<20; i++)
+ {
+ sum = 0.0;
+ for (j=0; j<20; j++)
+ {
+ if (i != j)
+ sum += aaMtmam[i][j];
+ }
+ aaMtmam[i][i] = -sum;
+ }
+ for (i=0; i<20; i++)
+ {
+ sum = 0.0;
+ for (j=0; j<20; j++)
+ {
+ if (i != j)
+ sum += aartREV[i][j];
+ }
+ aartREV[i][i] = -sum;
+ }
+ for (i=0; i<20; i++)
+ {
+ sum = 0.0;
+ for (j=0; j<20; j++)
+ {
+ if (i != j)
+ sum += aaWAG[i][j];
+ }
+ aaWAG[i][i] = -sum;
+ }
+ for (i=0; i<20; i++)
+ {
+ sum = 0.0;
+ for (j=0; j<20; j++)
+ {
+ if (i != j)
+ sum += aacpREV[i][j];
+ }
+ aacpREV[i][i] = -sum;
+ }
+ for (i=0; i<20; i++)
+ {
+ sum = 0.0;
+ for (j=0; j<20; j++)
+ {
+ if (i != j)
+ sum += aaVt[i][j];
+ }
+ aaVt[i][i] = -sum;
+ }
+ for (i=0; i<20; i++)
+ {
+ sum = 0.0;
+ for (j=0; j<20; j++)
+ {
+ if (i != j)
+ sum += aaBlosum[i][j];
+ }
+ aaBlosum[i][i] = -sum;
+ }
+ for (i=0; i<20; i++)
+ {
+ sum = 0.0;
+ for (j=0; j<20; j++)
+ {
+ if (i != j)
+ sum += aaLG[i][j];
+ }
+ aaLG[i][i] = -sum;
+ }
+
+# if 0
+ for (i=0; i<20; i++)
+ {
+ MrBayesPrint ("%s ", spacer);
+ for (j=0; j<20; j++)
+ {
+ if (aaLG[i][j] < 0.0)
+ MrBayesPrint ("%1.3lf ", aaLG[i][j]);
+ else
+ MrBayesPrint (" %1.3lf ", aaLG[i][j]);
+ }
+ MrBayesPrint ("\n");
+ }
+# endif
+
+ return (NO_ERROR);
+}
+
+
+void SetCode (int part)
+{
+ int i, s, s1, s2, s3, ns;
+
+ modelParams[part].codon[ 0] = 12; /* AAA Lys */
+ modelParams[part].codon[ 1] = 3; /* AAC Asn */
+ modelParams[part].codon[ 2] = 12; /* AAG Lys */
+ modelParams[part].codon[ 3] = 3; /* AAT Asn */
+ modelParams[part].codon[ 4] = 17; /* ACA Thr */
+ modelParams[part].codon[ 5] = 17; /* ACC Thr */
+ modelParams[part].codon[ 6] = 17; /* ACG Thr */
+ modelParams[part].codon[ 7] = 17; /* ACT Thr */
+ modelParams[part].codon[ 8] = 2; /* AGA Arg */
+ modelParams[part].codon[ 9] = 16; /* AGC Ser */
+ modelParams[part].codon[10] = 2; /* AGG Arg */
+ modelParams[part].codon[11] = 16; /* AGT Ser */
+ modelParams[part].codon[12] = 10; /* ATA Ile */
+ modelParams[part].codon[13] = 10; /* ATC Ile */
+ modelParams[part].codon[14] = 13; /* ATG Met */
+ modelParams[part].codon[15] = 10; /* ATT Ile */
+ modelParams[part].codon[16] = 6; /* CAA Gln */
+ modelParams[part].codon[17] = 9; /* CAC His */
+ modelParams[part].codon[18] = 6; /* CAG Gln */
+ modelParams[part].codon[19] = 9; /* CAT His */
+ modelParams[part].codon[20] = 15; /* CCA Pro */
+ modelParams[part].codon[21] = 15; /* CCC Pro */
+ modelParams[part].codon[22] = 15; /* CCG Pro */
+ modelParams[part].codon[23] = 15; /* CCT Pro */
+ modelParams[part].codon[24] = 2; /* CGA Arg */
+ modelParams[part].codon[25] = 2; /* CGC Arg */
+ modelParams[part].codon[26] = 2; /* CGG Arg */
+ modelParams[part].codon[27] = 2; /* CGT Arg */
+ modelParams[part].codon[28] = 11; /* CTA Leu */
+ modelParams[part].codon[29] = 11; /* CTC Leu */
+ modelParams[part].codon[30] = 11; /* CTG Leu */
+ modelParams[part].codon[31] = 11; /* CTT Leu */
+ modelParams[part].codon[32] = 7; /* GAA Glu */
+ modelParams[part].codon[33] = 4; /* GAC Asp */
+ modelParams[part].codon[34] = 7; /* GAG Glu */
+ modelParams[part].codon[35] = 4; /* GAT Asp */
+ modelParams[part].codon[36] = 1; /* GCA Ala */
+ modelParams[part].codon[37] = 1; /* GCC Ala */
+ modelParams[part].codon[38] = 1; /* GCG Ala */
+ modelParams[part].codon[39] = 1; /* GCT Ala */
+ modelParams[part].codon[40] = 8; /* GGA Gly */
+ modelParams[part].codon[41] = 8; /* GGC Gly */
+ modelParams[part].codon[42] = 8; /* GGG Gly */
+ modelParams[part].codon[43] = 8; /* GGT Gly */
+ modelParams[part].codon[44] = 20; /* GTA Val */
+ modelParams[part].codon[45] = 20; /* GTC Val */
+ modelParams[part].codon[46] = 20; /* GTG Val */
+ modelParams[part].codon[47] = 20; /* GTT Val */
+ modelParams[part].codon[48] = 21; /* TAA Stop*/
+ modelParams[part].codon[49] = 19; /* TAC Tyr */
+ modelParams[part].codon[50] = 21; /* TAG Stop*/
+ modelParams[part].codon[51] = 19; /* TAT Tyr */
+ modelParams[part].codon[52] = 16; /* TCA Ser */
+ modelParams[part].codon[53] = 16; /* TCC Ser */
+ modelParams[part].codon[54] = 16; /* TCG Ser */
+ modelParams[part].codon[55] = 16; /* TCT Ser */
+ modelParams[part].codon[56] = 21; /* TGA Stop*/
+ modelParams[part].codon[57] = 5; /* TGC Cys */
+ modelParams[part].codon[58] = 18; /* TGG Trp */
+ modelParams[part].codon[59] = 5; /* TGT Cys */
+ modelParams[part].codon[60] = 11; /* TTA Leu */
+ modelParams[part].codon[61] = 14; /* TTC Phe */
+ modelParams[part].codon[62] = 11; /* TTG Leu */
+ modelParams[part].codon[63] = 14; /* TTT Phe */
+
+ if (!strcmp(modelParams[part].geneticCode, "Vertmt"))
+ {
+ /* UGA: Ter -> Trp
+ AUA: Ile -> Met
+ AGA: Arg -> Ter
+ AGG: Arg -> Ter */
+ modelParams[part].codon[ 8] = 21; /* AGA Stop */
+ modelParams[part].codon[10] = 21; /* AGG Stop */
+ modelParams[part].codon[12] = 13; /* ATA Met */
+ modelParams[part].codon[56] = 18; /* TGA Trp */
+ }
+ if (!strcmp(modelParams[part].geneticCode, "Invermt"))
+ {
+ /* UGA: Ter -> Trp
+ AUA: Ile -> Met
+ AGA: Arg -> Ser
+ AGG: Arg -> Ser */
+ modelParams[part].codon[ 8] = 16; /* AGA Ser */
+ modelParams[part].codon[10] = 16; /* AGG Ser */
+ modelParams[part].codon[12] = 13; /* ATA Met */
+ modelParams[part].codon[56] = 18; /* TGA Trp */
+ }
+ else if (!strcmp(modelParams[part].geneticCode, "Mycoplasma"))
+ {
+ /* UGA: Ter -> Trp */
+ modelParams[part].codon[56] = 18; /* TGA Trp */
+ }
+ else if (!strcmp(modelParams[part].geneticCode, "Yeast"))
+ {
+ /* UGA: Ter -> Trp
+ AUA: Ile -> Met
+ CUA: Leu -> Thr
+ CUC: Leu -> Thr
+ CUG: Leu -> Thr
+ CUU: Leu -> Thr */
+ modelParams[part].codon[12] = 13; /* ATA Met */
+ modelParams[part].codon[28] = 17; /* CTA Thr */
+ modelParams[part].codon[29] = 17; /* CTC Thr */
+ modelParams[part].codon[30] = 17; /* CTG Thr */
+ modelParams[part].codon[31] = 17; /* CTT Thr */
+ modelParams[part].codon[56] = 18; /* TGA Trp */
+ }
+ else if (!strcmp(modelParams[part].geneticCode, "Ciliate"))
+ {
+ /* UAA: Ter -> Gln
+ UAG: Ter -> Gln */
+ modelParams[part].codon[48] = 6; /* TAA Gln */
+ modelParams[part].codon[50] = 6; /* TAG Gln */
+ }
+ else if (!strcmp(modelParams[part].geneticCode, "Echinoderm"))
+ {
+ /* AAA: Lys -> Asn
+ AGA: Arg -> Ser
+ AGG: Arg -> Ser
+ UGA: Ter -> Trp */
+ modelParams[part].codon[ 0] = 3; /* AAA Asn */
+ modelParams[part].codon[ 8] = 16; /* AGA Ser */
+ modelParams[part].codon[10] = 16; /* AGG Ser */
+ modelParams[part].codon[56] = 18; /* TGA Trp */
+ }
+ else if (!strcmp(modelParams[part].geneticCode, "Euplotid"))
+ {
+ /* UGA: Ter -> Cys */
+ modelParams[part].codon[56] = 5; /* TGA Cys */
+ }
+ else if (!strcmp(modelParams[part].geneticCode, "Metmt"))
+ {
+ /* UGA: Ter -> Trp
+ AUA: Ile -> Met
+ AGA: Arg -> Ser
+ AGG: Arg -> Ser */
+ modelParams[part].codon[ 8] = 16; /* AGA Ser */
+ modelParams[part].codon[10] = 16; /* AGG Ser */
+ modelParams[part].codon[12] = 13; /* ATA Met */
+ modelParams[part].codon[56] = 18; /* TGA Trp */
+ }
+ else
+ {
+ }
+
+ ns = 0;
+ for (i=0; i<64; i++)
+ {
+ if (modelParams[part].codon[i] != 21)
+ ns++;
+ }
+ /* printf ("ns = %d\n", ns); */
+
+ s = 0;
+ for (s1=0; s1<4; s1++)
+ for (s2=0; s2<4; s2++)
+ for (s3=0; s3<4; s3++)
+ if (modelParams[part].codon[s1*16 + s2*4 + s3] != 21)
+ {
+ modelParams[part].codonNucs[s][0] = s1;
+ modelParams[part].codonNucs[s][1] = s2;
+ modelParams[part].codonNucs[s][2] = s3;
+ modelParams[part].codonAAs[s] = modelParams[part].codon[s1*16 + s2*4 + s3];
+ s++;
+ }
+}
+
+
+int SetLocalTaxa (void)
+{
+ int i, j;
+
+ /* free memory if allocated */
+ if (memAllocs[ALLOC_LOCTAXANAMES] == YES)
+ {
+ free (localTaxonNames);
+ localTaxonNames = NULL;
+ memAllocs[ALLOC_LOCTAXANAMES] = NO;
+ }
+ if (memAllocs[ALLOC_LOCALTAXONCALIBRATION] == YES)
+ {
+ free (localTaxonCalibration);
+ localTaxonCalibration = NULL;
+ memAllocs[ALLOC_LOCALTAXONCALIBRATION] = NO;
+ }
+
+ /* count number of non-excluded taxa */
+ numLocalTaxa = 0;
+ for (i=0; i<numTaxa; i++)
+ {
+ if (taxaInfo[i].isDeleted == NO)
+ numLocalTaxa++;
+ }
+
+ /* allocate memory */
+ localTaxonNames = (char **)SafeCalloc((size_t)numLocalTaxa, sizeof(char *));
+ if (!localTaxonNames)
+ return (ERROR);
+ memAllocs[ALLOC_LOCTAXANAMES] = YES;
+
+ localTaxonCalibration = (Calibration **)SafeCalloc((size_t)numLocalTaxa, sizeof(Calibration *));
+ if (!localTaxonCalibration)
+ return (ERROR);
+ memAllocs[ALLOC_LOCALTAXONCALIBRATION] = YES;
+
+ /* point to names and calibrations of non-excluded taxa */
+ localOutGroup = 0;
+ for (i=j=0; i<numTaxa; i++)
+ {
+ if (taxaInfo[i].isDeleted == NO)
+ {
+ localTaxonNames[j] = taxaNames[i];
+ localTaxonCalibration[j] = &tipCalibration[i];
+ if (i == outGroupNum)
+ localOutGroup = j;
+ j++;
+ }
+ }
+
+# if 0
+ /* show non-excluded taxa */
+ for (i=0; i<numLocalTaxa; i++)
+ MrBayesPrint ("%s %4d %s\n", spacer, i+1, localTaxonNames[i]);
+# endif
+
+ return (NO_ERROR);
+}
+
+
+/*----------------------------------------------------------------------------
+|
+| SetModelDefaults: This function will set up model defaults in modelParams.
+| It will also initialize parameters and moves by calling SetUpAnalysis.
+|
+-----------------------------------------------------------------------------*/
+int SetModelDefaults (void)
+{
+ int j;
+
+ MrBayesPrint ("%s Setting model defaults\n", spacer);
+ MrBayesPrint ("%s Seed (for generating default start values) = %d\n", spacer, globalSeed);
+
+ if (InitializeLinks () == ERROR)
+ {
+ MrBayesPrint ("%s Problem initializing link table\n", spacer);
+ return (ERROR);
+ }
+
+ /* Check that models are allocated */
+ if (memAllocs[ALLOC_MODEL] == NO)
+ {
+ MrBayesPrint ("%s Model not allocated in SetModelDefaults\n", spacer);
+ return (ERROR);
+ }
+
+ /* model parameters */
+ for (j=0; j<numCurrentDivisions; j++)
+ {
+ modelParams[j] = defaultModel; /* start with default settings */
+
+ modelParams[j].dataType = DataType (j); /* data type for partition */
+
+ if (modelParams[j].dataType == STANDARD)
+ { /* set default ascertainment bias for partition */
+ modelParams[j].coding = VARIABLE;
+ strcpy(modelParams[j].codingString, "Variable");
+ }
+ else if (modelParams[j].dataType == RESTRICTION)
+ {
+ modelParams[j].coding = NOABSENCESITES;
+ strcpy(modelParams[j].codingString, "Noabsencesites");
+ }
+ else
+ {
+ modelParams[j].coding = ALL;
+ strcpy(modelParams[j].codingString, "All");
+ }
+
+ SetCode (j);
+ modelParams[j].nStates = NumStates (j); /* number of states for partition */
+
+ modelParams[j].activeConstraints = (int *) SafeCalloc(numDefinedConstraints, sizeof(int)); /* allocate space for active constraints (yes/no) */
+ }
+
+ return (NO_ERROR);
+}
+
+
+/*----------------------------------------------------------------------------
+|
+| SetModelInfo: This function will set up model info using model
+| params
+|
+-----------------------------------------------------------------------------*/
+int SetModelInfo (void)
+{
+ int i, j, chn, ts;
+ ModelParams *mp;
+ ModelInfo *m;
+
+ /* wipe all model settings */
+ inferSiteRates = NO;
+ inferAncStates = NO;
+ inferSiteOmegas = NO;
+
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ m = &modelSettings[i];
+
+ /* make certain that we set this intentionally to "NO" so we
+ calculate cijk information and calculate cond likes when needed */
+ m->upDateCijk = YES;
+ m->upDateCl = YES;
+ m->upDateAll = YES;
+
+ /* make certain that we start with a parsimony branch length of zero */
+ for (j=0; j<MAX_CHAINS; j++)
+ m->parsTreeLength[j*2] = m->parsTreeLength[j*2+1] = 0.0;
+
+ m->tRatio = NULL;
+ m->revMat = NULL;
+ m->omega = NULL;
+ m->stateFreq = NULL;
+ m->shape = NULL;
+ m->pInvar = NULL;
+ m->correlation = NULL;
+ m->switchRates = NULL;
+ m->rateMult = NULL;
+ m->topology = NULL;
+ m->brlens = NULL;
+ m->speciationRates = NULL;
+ m->extinctionRates = NULL;
+ m->fossilizationRates = NULL;
+ m->popSize = NULL;
+ m->aaModel = NULL;
+ m->cppRate = NULL;
+ m->cppEvents = NULL;
+ m->cppMultDev = NULL;
+ m->tk02var = NULL;
+ m->tk02BranchRates = NULL;
+ m->igrvar = NULL;
+ m->igrBranchRates = NULL;
+ m->mixedvar = NULL;
+ m->mixedBrchRates = NULL;
+ m->clockRate = NULL;
+
+ m->CondLikeDown = NULL;
+ m->CondLikeRoot = NULL;
+ m->CondLikeScaler = NULL;
+ m->Likelihood = NULL;
+ m->TiProbs = NULL;
+
+ m->CondLikeUp = NULL;
+ m->StateCode = NULL;
+ m->PrintAncStates = NULL;
+ m->PrintSiteRates = NULL;
+
+ m->printPosSel = NO;
+ m->printAncStates = NO;
+ m->printSiteRates = NO;
+
+ m->nStates = NULL;
+ m->bsIndex = NULL;
+ m->cType = NULL;
+ m->tiIndex = NULL;
+
+ m->gibbsGamma = NO;
+ m->gibbsFreq = 0;
+
+ m->parsimonyBasedMove = NO;
+
+# if defined (BEAGLE_ENABLED)
+ m->beagleInstance = -1; /* beagle instance */
+ m->logLikelihoods = NULL; /* array of log likelihoods from Beagle */
+ m->inRates = NULL; /* array of category rates for Beagle */
+ m->branchLengths = NULL; /* array of branch lengths for Beagle */
+ m->tiProbIndices = NULL; /* array of trans prob indices for Beagle */
+ m->inWeights = NULL; /* array of weights for Beagle root likelihood */
+ m->bufferIndices = NULL; /* array of partial indices for root likelihood */
+ m->childBufferIndices = NULL; /* array of child partial indices (unrooted) */
+ m->childTiProbIndices = NULL; /* array of child ti prob indices (unrooted) */
+ m->cumulativeScaleIndices = NULL; /* array of cumulative scale indices */
+# endif
+
+ /* likelihood calculator flags */
+ m->useSSE = NO; /* use SSE code for this partition? */
+ m->useBeagle = NO; /* use Beagle for this partition? */
+
+ /* set all memory pointers to NULL */
+ m->parsSets = NULL;
+ m->numParsSets = 0;
+ m->parsNodeLens = NULL;
+ m->numParsNodeLens = 0;
+
+ m->condLikes = NULL;
+ m->tiProbs = NULL;
+ m->scalers = NULL;
+ m->numCondLikes = 0;
+ m->numTiProbs = 0;
+ m->numScalers = 0;
+
+ m->condLikeIndex = NULL;
+ m->condLikeScratchIndex = NULL;
+ m->tiProbsIndex = NULL;
+ m->tiProbsScratchIndex = NULL;
+ m->nodeScalerIndex = NULL;
+ m->nodeScalerScratchIndex = NULL;
+ m->siteScalerIndex = NULL;
+ m->siteScalerScratchIndex = -1;
+
+ m->cijks = NULL;
+ m->nCijkParts = 0;
+ m->cijkIndex = NULL;
+ m->cijkScratchIndex = -1;
+ }
+
+ /* set state of all chains to zero */
+ for (chn=0; chn<numGlobalChains; chn++)
+ state[chn] = 0;
+
+ /* fill in modelSettings info with some basic model characteristics */
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ mp = &modelParams[i];
+ m = &modelSettings[i];
+
+ if (!strcmp(mp->nucModel,"Protein") && (mp->dataType == DNA || mp->dataType == RNA))
+ m->dataType = PROTEIN;
+ else
+ m->dataType = mp->dataType;
+
+ /* nuc model structure */
+ if (!strcmp(mp->nucModel, "4by4"))
+ m->nucModelId = NUCMODEL_4BY4;
+ else if (!strcmp(mp->nucModel, "Doublet"))
+ m->nucModelId = NUCMODEL_DOUBLET;
+ else if (!strcmp(mp->nucModel, "Protein"))
+ m->nucModelId = NUCMODEL_AA;
+ else /* if (!strcmp(mp->nucModelId, "Codon")) */
+ m->nucModelId = NUCMODEL_CODON;
+
+ /* model nst */
+ if (!strcmp(mp->nst, "1"))
+ m->nst = 1;
+ else if (!strcmp(mp->nst, "2"))
+ m->nst = 2;
+ else if (!strcmp(mp->nst, "6"))
+ m->nst = 6;
+ else
+ m->nst = NST_MIXED;
+
+ /* We set the aa model here. We have two options. First, the model
+ could be fixed, in which case mp->aaModel has been set. We then
+ go ahead and also set the model settings. Second, the model
+ could be mixed. In this case, the amino acid matrix is considered
+ a parameter, and we will deal with it below. It doesn't hurt
+ to set it here anyway (it will be overwritten later). */
+ if (!strcmp(mp->aaModelPr, "Fixed"))
+ {
+ if (!strcmp(mp->aaModel, "Poisson"))
+ m->aaModelId = AAMODEL_POISSON;
+ else if (!strcmp(mp->aaModel, "Equalin"))
+ m->aaModelId = AAMODEL_EQ;
+ else if (!strcmp(mp->aaModel, "Jones"))
+ m->aaModelId = AAMODEL_JONES;
+ else if (!strcmp(mp->aaModel, "Dayhoff"))
+ m->aaModelId = AAMODEL_DAY;
+ else if (!strcmp(mp->aaModel, "Mtrev"))
+ m->aaModelId = AAMODEL_MTREV;
+ else if (!strcmp(mp->aaModel, "Mtmam"))
+ m->aaModelId = AAMODEL_MTMAM;
+ else if (!strcmp(mp->aaModel, "Wag"))
+ m->aaModelId = AAMODEL_WAG;
+ else if (!strcmp(mp->aaModel, "Rtrev"))
+ m->aaModelId = AAMODEL_RTREV;
+ else if (!strcmp(mp->aaModel, "Cprev"))
+ m->aaModelId = AAMODEL_CPREV;
+ else if (!strcmp(mp->aaModel, "Vt"))
+ m->aaModelId = AAMODEL_VT;
+ else if (!strcmp(mp->aaModel, "Blosum"))
+ m->aaModelId = AAMODEL_BLOSUM;
+ else if (!strcmp(mp->aaModel, "LG"))
+ m->aaModelId = AAMODEL_LG;
+ else if (!strcmp(mp->aaModel, "Gtr"))
+ m->aaModelId = AAMODEL_GTR;
+ else
+ {
+ MrBayesPrint ("%s Uncertain amino acid model\n", spacer);
+ return (ERROR);
+ }
+ }
+ else
+ m->aaModelId = -1;
+
+ /* parsimony model? */
+ if (!strcmp(mp->parsModel, "Yes"))
+ m->parsModelId = YES;
+ else
+ m->parsModelId = NO;
+
+ /* number of gamma categories */
+ if (activeParams[P_SHAPE][i] > 0)
+ m->numGammaCats = mp->numGammaCats;
+ else
+ m->numGammaCats = 1;
+
+ /* number of beta categories */
+ if (mp->dataType == STANDARD && !(AreDoublesEqual(mp->symBetaFix, -1.0, 0.00001) == YES && !strcmp(mp->symPiPr,"Fixed")))
+ m->numBetaCats = mp->numBetaCats;
+ else
+ m->numBetaCats = 1;
+
+ /* number of omega categories */
+ if ((mp->dataType == DNA || mp->dataType == RNA) && (!strcmp(mp->omegaVar, "Ny98") || !strcmp(mp->omegaVar, "M3")) && !strcmp(mp->nucModel, "Codon"))
+ {
+ m->numOmegaCats = 3;
+ m->numGammaCats = 1; /* if we are here, then we cannot have gamma or beta variation */
+ m->numBetaCats = 1;
+ }
+ else if ((mp->dataType == DNA || mp->dataType == RNA) && !strcmp(mp->omegaVar, "M10") && !strcmp(mp->nucModel, "Codon"))
+ {
+ m->numOmegaCats = mp->numM10BetaCats + mp->numM10GammaCats;
+ m->numGammaCats = 1; /* if we are here, then we cannot have gamma or beta variation */
+ m->numBetaCats = 1;
+ }
+ else
+ m->numOmegaCats = 1;
+
+ /* number of transition matrices depends on numGammaCats, numBetaCats, and numOmegaCats */
+ m->numTiCats = m->numGammaCats * m->numBetaCats * m->numOmegaCats;
+
+ /* TODO: check that numStates and numModelStates are set
+ appropriately for codon and doublet models */
+
+ /* number of observable states */
+ if (m->dataType == STANDARD)
+ m->numStates = 0; /* zero, meaining variable */
+ else if (!strcmp(mp->nucModel,"Protein") && (mp->dataType == DNA || mp->dataType == RNA))
+ m->numStates = 20;
+ else
+ m->numStates = mp->nStates;
+
+ /* number of model states including hidden ones */
+ if ((mp->dataType == DNA || mp->dataType == RNA) && !strcmp (mp->covarionModel, "Yes") && !strcmp(mp->nucModel, "4by4"))
+ m->numModelStates = mp->nStates * 2;
+ else if (m->dataType == PROTEIN && !strcmp (mp->covarionModel, "Yes"))
+ m->numModelStates = mp->nStates * 2;
+ else if ((mp->dataType == DNA || mp->dataType == RNA) && !strcmp(mp->nucModel,"Protein") && !strcmp (mp->covarionModel, "Yes"))
+ m->numModelStates = 20 * 2;
+ else if (mp->dataType == CONTINUOUS)
+ m->numModelStates = 0;
+ else if (mp->dataType == STANDARD)
+ {
+ /* use max possible for now; we don't know what chars will be included */
+ m->numModelStates = 10;
+ }
+ else
+ m->numModelStates = m->numStates;
+
+ /* Fill in some information for calculating cijk. We will use m->cijkLength to
+ figure out if we need to diagonalize Q to calculate transition probabilities.
+ If cijkLength = 0, then we won't bother. We use cijkLength later in this function. */
+ m->cijkLength = 0;
+ m->nCijkParts = 1;
+ if (m->dataType == PROTEIN)
+ {
+ ts = m->numModelStates;
+ m->cijkLength = (ts * ts * ts) + (2 * ts);
+ if (!strcmp (mp->covarionModel, "Yes"))
+ {
+ m->cijkLength *= m->numGammaCats;
+ m->nCijkParts = m->numGammaCats;
+ }
+ }
+ else if (m->dataType == STANDARD)
+ {
+ /* set to 0 for now, update in ProcessStdChars */
+ m->nCijkParts = 0;
+ }
+ else if (m->dataType == DNA || m->dataType == RNA)
+ {
+ if (m->nucModelId == NUCMODEL_4BY4)
+ {
+ if (!strcmp (mp->covarionModel, "No") && m->nst != 6 && m->nst != 203)
+ m->cijkLength = 0;
+ else
+ {
+ ts = m->numModelStates;
+ m->cijkLength = (ts * ts * ts) + (2 * ts);
+ }
+ if (!strcmp (mp->covarionModel, "Yes"))
+ {
+ m->cijkLength *= m->numGammaCats;
+ m->nCijkParts = m->numGammaCats;
+ }
+ }
+ else if (m->nucModelId == NUCMODEL_DOUBLET)
+ {
+ ts = m->numModelStates;
+ m->cijkLength = (ts * ts * ts) + (2 * ts);
+ }
+ else if (m->nucModelId == NUCMODEL_CODON)
+ {
+ ts = m->numModelStates;
+ m->cijkLength = (ts * ts * ts) + (2 * ts);
+ m->cijkLength *= m->numOmegaCats;
+ m->nCijkParts = m->numOmegaCats;
+ }
+ else
+ {
+ MrBayesPrint ("%s BUG: Inconsistent model. Please report this as a bug.\n");
+ return ERROR;
+ }
+ }
+
+ /* check if we should calculate ancestral states */
+ if (!strcmp(mp->inferAncStates,"Yes"))
+ {
+ if (m->dataType == PROTEIN && !strcmp(mp->covarionModel, "No"))
+ m->printAncStates = YES;
+ else if (m->dataType == DNA || m->dataType == RNA)
+ {
+ if (!strcmp(mp->nucModel,"4by4") && !strcmp(mp->covarionModel, "No"))
+ m->printAncStates = YES;
+ if (!strcmp(mp->nucModel,"Doublet"))
+ m->printAncStates = YES;
+ if (!strcmp(mp->nucModel,"Codon") && !strcmp(mp->omegaVar,"Equal"))
+ m->printAncStates = YES;
+ }
+ else if (m->dataType == STANDARD || m->dataType == RESTRICTION)
+ m->printAncStates = YES;
+ if (m->printAncStates == YES)
+ inferAncStates = YES;
+ else
+ MrBayesPrint ("%s Print out of ancestral states is not applicable for devision %d.\n",spacer,i);
+ }
+
+ /* check if we should calculate site rates */
+ if (!strcmp(mp->inferSiteRates,"Yes"))
+ {
+ if (m->numGammaCats > 1)
+ {
+ m->printSiteRates = YES;
+ inferSiteRates = YES;
+ }
+ }
+
+ /* check if we should calculate positive selection */
+ if (!strcmp(mp->inferPosSel, "Yes"))
+ {
+ if (m->numOmegaCats > 1)
+ {
+ m->printPosSel = YES;
+ inferPosSel = YES;
+ }
+ }
+
+ /* check if we should calculate site omegas */
+ if (!strcmp(mp->inferSiteOmegas, "Yes"))
+ {
+ if (m->numOmegaCats > 1)
+ {
+ m->printSiteOmegas = YES;
+ inferSiteOmegas = YES;
+ }
+ }
+ /* check if we should use gibbs sampling of gamma (don't use it with pinvar or invgamma) */
+ if (!strcmp(mp->useGibbs,"Yes") && (m->numGammaCats > 1))
+ {
+ if (m->dataType == DNA || m->dataType == RNA || m->dataType == PROTEIN)
+ {
+ if (activeParams[P_CORREL][i] <= 0 && m->printSiteRates == NO && activeParams[P_PINVAR][i] <= 0)
+ {
+ m->gibbsGamma = YES;
+ m->gibbsFreq = mp->gibbsFreq;
+ }
+ }
+ }
+ }
+
+ return (NO_ERROR);
+}
+
+
+/*-----------------------------------------------------------------
+|
+| SetModelParams: Set up parameter structs for all model
+| parameters, including trees
+|
+|----------------------------------------------------------------*/
+int SetModelParams (void)
+{
+ int c, i, j, k, n, n1, n2, *isPartTouched, numRelParts, nRelParts, areAllPartsParsimony,
+ nClockBrlens, nRelaxedBrlens, nCalibratedBrlens;
+ char tempCodon[15], tempMult[15], *tempStr,temp[30];
+ char static *partString=NULL; /* mad static to avoid posible memory leak on return ERROR if it would be introduced later */
+ Param *p;
+ ModelParams *mp;
+ ModelInfo *m;
+ int tempStrSize = 300;
+
+ tempStr = (char *) SafeMalloc((size_t)tempStrSize * sizeof(char));
+ isPartTouched = (int *) SafeMalloc ((size_t)numCurrentDivisions * sizeof (int));
+ if (!tempStr || !isPartTouched)
+ {
+ MrBayesPrint ("%s Problem allocating tempString (%d) or isPartTouched (%d)\n", spacer,
+ tempStrSize * sizeof(char), numCurrentDivisions * sizeof(int));
+ return (ERROR);
+ }
+
+# if defined DEBUG_SETCHAINPARAMS
+ /* only for debugging */
+ MrBFlt lnPriorRatio = 0.0, lnProposalRatio = 0.0;
+# endif
+
+ /* allocate space for parameters */
+ if (memAllocs[ALLOC_PARAMS] == YES)
+ {
+ for (i=0; i<numParams; i++)
+ {
+ SafeFree ((void **)¶ms[i].name);
+ if (params[i].paramHeader)
+ {
+ free (params[i].paramHeader);
+ params[i].paramHeader = NULL;
+ }
+ }
+ free (params);
+ free (relevantParts);
+ params = NULL;
+ relevantParts = NULL;
+ memAllocs[ALLOC_PARAMS] = NO;
+ }
+
+ /* wipe all chain parameter information */
+ numParams = 0;
+ numTrees = 0;
+ chainHasAdgamma = NO;
+
+ /* figure out number of parameters */
+ /* this relies on activeParams[j][i] being set to 1, 2, ..., numParams */
+ /* which is taken care of in SetUpLinkTable () */
+ nRelParts = 0;
+ for (j=0; j<NUM_LINKED; j++)
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParams[j][i] > numParams)
+ numParams = activeParams[j][i];
+ if (activeParams[j][i] > 0)
+ nRelParts++;
+ }
+ }
+
+ params = (Param *) SafeMalloc (numParams * sizeof(Param));
+ relevantParts = (int *) SafeMalloc (nRelParts * sizeof(int));
+ if (!params || !relevantParts)
+ {
+ MrBayesPrint ("%s Problem allocating params and relevantParts\n", spacer);
+ if (params)
+ free (params);
+ if (relevantParts)
+ free (relevantParts);
+ free (tempStr);
+ return ERROR;
+ }
+ else
+ memAllocs[ALLOC_PARAMS] = YES;
+
+ /* fill in info on each parameter */
+ nRelParts = 0; /* now cumulative number of relevant partitions */
+ for (k=0; k<numParams; k++)
+ {
+ p = ¶ms[k];
+
+ /* find affected partitions */
+ numRelParts = 0;
+ for (j=0; j<NUM_LINKED; j++)
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParams[j][i] == k + 1)
+ {
+ numRelParts++;
+ isPartTouched[i] = YES;
+ }
+ else
+ isPartTouched[i] = NO;
+ }
+ if (numRelParts > 0)
+ break;
+ }
+
+ /* find pointer to modelParams and modelSettings of first relevant partition */
+ /* this will be handy later on */
+ for (i=0; i<numCurrentDivisions; i++)
+ if (isPartTouched[i] == YES)
+ break;
+ mp = &modelParams[i];
+ m = &modelSettings[i];
+
+ /* Set default min and max */
+ p->min = p->max = NEG_INFINITY;
+
+ /* Parameter nValues and nSubValues, which are needed for memory allocation
+ are calculated for each case in the code below. nSympi, however, is
+ only used for one special type of parameter and it therefore makes
+ sense to initialize it to 0 here. The same applies to hasBinaryStd
+ and nIntValues. To be safe, we set all to 0 here. */
+ p->nValues = 0;
+ p->nSubValues = 0;
+ p->nIntValues = 0;
+ p->nSympi = 0;
+ p->hasBinaryStd = NO;
+
+ /* should this parameter be printed to a file? */
+ p->printParam = NO;
+
+ /* set print subparams to 0 */
+ p->nPrintSubParams = 0;
+
+ /* check constraints for tree parameter ? */
+ p->checkConstraints = NO;
+
+ /* set index number of parameter */
+ p->index = k;
+
+ /* set prior function to NULL */
+ p->LnPriorRatio = NULL;
+
+ /* set prior paramters to NULL */
+ p->priorParams = NULL;
+
+ /* set affectsLikelihood to NO */
+ p->affectsLikelihood = NO;
+
+ /* set cpp event pointers to NULL */
+ p->nEvents = NULL;
+ p->position = NULL;
+ p->rateMult = NULL;
+
+ /* set header and name to NULL */
+ p->paramHeader = NULL;
+ p->name = NULL;
+
+ /* set up relevant partitions */
+ p->nRelParts = numRelParts;
+ p->relParts = relevantParts + nRelParts;
+ nRelParts += numRelParts;
+ for (i=n=0; i<numCurrentDivisions; i++)
+ if (isPartTouched[i] == YES)
+ p->relParts[n++] = i;
+
+ /* get partition descriptor */
+ SafeStrcat(&partString,"");
+ FillRelPartsString (p, &partString);
+
+ /* set up information for parameter */
+ if (j == P_TRATIO)
+ {
+ /* Set up tratio ****************************************************************************************/
+ p->paramType = P_TRATIO;
+ p->nValues = 1; /* we store only the ratio */
+ p->nSubValues = 0;
+ p->min = 0.0;
+ p->max = POS_INFINITY;
+ for (i=0; i<numCurrentDivisions; i++)
+ if (isPartTouched[i] == YES)
+ modelSettings[i].tRatio = p;
+
+ p->paramTypeName = "Transition and transversion rates";
+ SafeStrcat(&p->name, "Tratio");
+ SafeStrcat(&p->name, partString);
+
+ /* find the parameter x prior type */
+ if (!strcmp(mp->tRatioPr,"Beta"))
+ {
+ p->paramId = TRATIO_DIR;
+ }
+ else
+ p->paramId = TRATIO_FIX;
+
+ if (p->paramId != TRATIO_FIX)
+ p->printParam = YES;
+ if (!strcmp(mp->tratioFormat,"Ratio"))
+ {
+ /* report ti/tv ratio */
+ SafeStrcat (&p->paramHeader,"kappa");
+ SafeStrcat (&p->paramHeader, partString);
+ }
+ else
+ {
+ /* report prop. of ratesum (Dirichlet) */
+ SafeStrcat (&p->paramHeader,"ti");
+ SafeStrcat (&p->paramHeader, partString);
+ SafeStrcat (&p->paramHeader, "\ttv");
+ SafeStrcat (&p->paramHeader, partString);
+ }
+ }
+ else if (j == P_REVMAT)
+ {
+ /* Set up revMat ****************************************************************************************/
+ p->paramType = P_REVMAT;
+ if (m->dataType == PROTEIN)
+ p->nValues = 190;
+ else
+ p->nValues = 6;
+ p->nSubValues = 0;
+ if (!strcmp(mp->nst, "Mixed"))
+ p->nIntValues = 6;
+ else
+ p->nIntValues = 0;
+ p->min = 0.0;
+ p->max = 1.0; /* adjust later for REVMAT_MIX, see a few lines below */
+ for (i=0; i<numCurrentDivisions; i++)
+ if (isPartTouched[i] == YES)
+ modelSettings[i].revMat = p;
+
+ p->paramTypeName = "Rates of reversible rate matrix";
+ SafeStrcat(&p->name, "Revmat");
+ SafeStrcat(&p->name, partString);
+
+ /* find the parameter x prior type */
+ if (m->dataType == PROTEIN)
+ {
+ if (!strcmp(mp->aaRevMatPr,"Dirichlet"))
+ p->paramId = REVMAT_DIR;
+ else
+ p->paramId = REVMAT_FIX;
+ if (p->paramId != REVMAT_FIX)
+ p->printParam = YES;
+
+ for (n1=0; n1<20; n1++)
+ {
+ for (n2=n1+1; n2<20; n2++)
+ {
+ if (n1==0 && n2==1)
+ {
+ sprintf (temp, "r(%c<->%c)", StateCode_AA(n1), StateCode_AA(n2));
+ SafeStrcat (&p->paramHeader, temp);
+ SafeStrcat (&p->paramHeader, partString);
+ }
+ else
+ {
+ sprintf (temp, "\tr(%c<->%c)", StateCode_AA(n1), StateCode_AA(n2));
+ SafeStrcat (&p->paramHeader, temp);
+ SafeStrcat (&p->paramHeader, partString);
+ }
+ }
+ }
+ }
+ else
+ {
+ if (!strcmp(mp->nst, "Mixed"))
+ {
+ p->paramId = REVMAT_MIX;
+ p->max = 1E6; /* some large value */
+ }
+ else if (!strcmp(mp->revMatPr,"Dirichlet"))
+ p->paramId = REVMAT_DIR;
+ else
+ p->paramId = REVMAT_FIX;
+ if (p->paramId != REVMAT_FIX)
+ p->printParam = YES;
+
+ for (n1=0; n1<4; n1++)
+ {
+ for (n2=n1+1; n2<4; n2++)
+ {
+ if (n1==0 && n2==1)
+ {
+ sprintf (temp, "r(%c<->%c)", StateCode_NUC4(n1), StateCode_NUC4(n2));
+ SafeStrcat (&p->paramHeader, temp);
+ SafeStrcat (&p->paramHeader, partString);
+ }
+ else
+ {
+ sprintf (temp, "\tr(%c<->%c)", StateCode_NUC4(n1), StateCode_NUC4(n2));
+ SafeStrcat (&p->paramHeader, temp);
+ SafeStrcat (&p->paramHeader, partString);
+ }
+ }
+ }
+ if (p->paramId == REVMAT_MIX)
+ {
+ sprintf (temp, "\tgtrsubmodel");
+ SafeStrcat (&p->paramHeader, temp);
+ SafeStrcat (&p->paramHeader, partString);
+ sprintf (temp, "\tk_revmat");
+ SafeStrcat (&p->paramHeader, temp);
+ SafeStrcat (&p->paramHeader, partString);
+ }
+ }
+ }
+ else if (j == P_OMEGA)
+ {
+ /* Set up omega *****************************************************************************************/
+ p->paramType = P_OMEGA;
+ p->min = 0.0;
+ p->max = POS_INFINITY;
+ if (!strcmp(mp->omegaVar, "M3"))
+ {
+ p->nValues = 3; /* omega values */
+ p->nSubValues = 6; /* category frequencies plus cache */
+ for (i=0; i<numCurrentDivisions; i++)
+ if (isPartTouched[i] == YES)
+ modelSettings[i].omega = p;
+
+ /* find the parameter x prior type */
+ if (!strcmp(mp->m3omegapr, "Exponential") && !strcmp(mp->codonCatFreqPr, "Fixed"))
+ p->paramId = OMEGA_EF;
+ else if (!strcmp(mp->m3omegapr, "Exponential") && !strcmp(mp->codonCatFreqPr, "Dirichlet"))
+ p->paramId = OMEGA_ED;
+ else if (!strcmp(mp->m3omegapr, "Fixed") && !strcmp(mp->codonCatFreqPr, "Fixed"))
+ p->paramId = OMEGA_FF;
+ else if (!strcmp(mp->m3omegapr, "Fixed") && !strcmp(mp->codonCatFreqPr, "Dirichlet"))
+ p->paramId = OMEGA_FD;
+
+ if (p->paramId != OMEGA_FF)
+ p->printParam = YES;
+
+ SafeStrcat (&p->paramHeader, "omega(1)");
+ SafeStrcat (&p->paramHeader, partString);
+ SafeStrcat (&p->paramHeader, "\tomega(2)");
+ SafeStrcat (&p->paramHeader, partString);
+ SafeStrcat (&p->paramHeader, "\tomega(3)");
+ SafeStrcat (&p->paramHeader, partString);
+
+ SafeStrcat (&p->paramHeader, "\tpi(1)");
+ SafeStrcat (&p->paramHeader, partString);
+ SafeStrcat (&p->paramHeader, "\tpi(2)");
+ SafeStrcat (&p->paramHeader, partString);
+ SafeStrcat (&p->paramHeader, "\tpi(3)");
+ SafeStrcat (&p->paramHeader, partString);
+ }
+ else if (!strcmp(mp->omegaVar, "M10"))
+ {
+ p->nValues = mp->numM10BetaCats + mp->numM10GammaCats;
+ p->nSubValues = mp->numM10BetaCats + mp->numM10GammaCats + 8;
+ for (i=0; i<numCurrentDivisions; i++)
+ if (isPartTouched[i] == YES)
+ modelSettings[i].omega = p;
+
+ /* find the parameter x prior type */
+ if (!strcmp(mp->m10betapr, "Uniform") && !strcmp(mp->m10gammapr, "Uniform") && !strcmp(mp->codonCatFreqPr, "Dirichlet"))
+ p->paramId = OMEGA_10UUB;
+ else if (!strcmp(mp->m10betapr, "Uniform") && !strcmp(mp->m10gammapr, "Uniform") && !strcmp(mp->codonCatFreqPr, "Fixed"))
+ p->paramId = OMEGA_10UUF;
+ else if (!strcmp(mp->m10betapr, "Uniform") && !strcmp(mp->m10gammapr, "Exponential") && !strcmp(mp->codonCatFreqPr, "Dirichlet"))
+ p->paramId = OMEGA_10UEB;
+ else if (!strcmp(mp->m10betapr, "Uniform") && !strcmp(mp->m10gammapr, "Exponential") && !strcmp(mp->codonCatFreqPr, "Fixed"))
+ p->paramId = OMEGA_10UEF;
+ else if (!strcmp(mp->m10betapr, "Uniform") && !strcmp(mp->m10gammapr, "Fixed") && !strcmp(mp->codonCatFreqPr, "Dirichlet"))
+ p->paramId = OMEGA_10UFB;
+ else if (!strcmp(mp->m10betapr, "Uniform") && !strcmp(mp->m10gammapr, "Fixed") && !strcmp(mp->codonCatFreqPr, "Fixed"))
+ p->paramId = OMEGA_10UFF;
+ else if (!strcmp(mp->m10betapr, "Exponential") && !strcmp(mp->m10gammapr, "Uniform") && !strcmp(mp->codonCatFreqPr, "Dirichlet"))
+ p->paramId = OMEGA_10EUB;
+ else if (!strcmp(mp->m10betapr, "Exponential") && !strcmp(mp->m10gammapr, "Uniform") && !strcmp(mp->codonCatFreqPr, "Fixed"))
+ p->paramId = OMEGA_10EUF;
+ else if (!strcmp(mp->m10betapr, "Exponential") && !strcmp(mp->m10gammapr, "Exponential") && !strcmp(mp->codonCatFreqPr, "Dirichlet"))
+ p->paramId = OMEGA_10EEB;
+ else if (!strcmp(mp->m10betapr, "Exponential") && !strcmp(mp->m10gammapr, "Exponential") && !strcmp(mp->codonCatFreqPr, "Fixed"))
+ p->paramId = OMEGA_10EEF;
+ else if (!strcmp(mp->m10betapr, "Exponential") && !strcmp(mp->m10gammapr, "Fixed") && !strcmp(mp->codonCatFreqPr, "Dirichlet"))
+ p->paramId = OMEGA_10EFB;
+ else if (!strcmp(mp->m10betapr, "Exponential") && !strcmp(mp->m10gammapr, "Fixed") && !strcmp(mp->codonCatFreqPr, "Fixed"))
+ p->paramId = OMEGA_10EFF;
+ else if (!strcmp(mp->m10betapr, "Fixed") && !strcmp(mp->m10gammapr, "Uniform") && !strcmp(mp->codonCatFreqPr, "Dirichlet"))
+ p->paramId = OMEGA_10FUB;
+ else if (!strcmp(mp->m10betapr, "Fixed") && !strcmp(mp->m10gammapr, "Uniform") && !strcmp(mp->codonCatFreqPr, "Fixed"))
+ p->paramId = OMEGA_10FUF;
+ else if (!strcmp(mp->m10betapr, "Fixed") && !strcmp(mp->m10gammapr, "Exponential") && !strcmp(mp->codonCatFreqPr, "Dirichlet"))
+ p->paramId = OMEGA_10FEB;
+ else if (!strcmp(mp->m10betapr, "Fixed") && !strcmp(mp->m10gammapr, "Exponential") && !strcmp(mp->codonCatFreqPr, "Fixed"))
+ p->paramId = OMEGA_10FEF;
+ else if (!strcmp(mp->m10betapr, "Fixed") && !strcmp(mp->m10gammapr, "Fixed") && !strcmp(mp->codonCatFreqPr, "Dirichlet"))
+ p->paramId = OMEGA_10FFB;
+ else if (!strcmp(mp->m10betapr, "Fixed") && !strcmp(mp->m10gammapr, "Fixed") && !strcmp(mp->codonCatFreqPr, "Fixed"))
+ p->paramId = OMEGA_10FFF;
+
+ if (p->paramId != OMEGA_10FFF)
+ p->printParam = YES;
+ for (i=0; i<p->nValues; i++)
+ {
+ if (i==0)
+ sprintf (temp, "omega(%d)", i+1);
+ else
+ sprintf (temp, "\tomega(%d)", i+1);
+ SafeStrcat (&p->paramHeader, temp);
+ SafeStrcat (&p->paramHeader, partString);
+ }
+ SafeStrcat (&p->paramHeader, "\tbeta(alpha)");
+ SafeStrcat (&p->paramHeader, partString);
+ SafeStrcat (&p->paramHeader, "\tbeta(beta)");
+ SafeStrcat (&p->paramHeader, partString);
+ SafeStrcat (&p->paramHeader, "\tgamma(alpha)");
+ SafeStrcat (&p->paramHeader, partString);
+ SafeStrcat (&p->paramHeader, "\tgamma(beta)");
+ SafeStrcat (&p->paramHeader, partString);
+ SafeStrcat (&p->paramHeader, "\tpi(1)");
+ SafeStrcat (&p->paramHeader, partString);
+ SafeStrcat (&p->paramHeader, "\tpi(2)");
+ SafeStrcat (&p->paramHeader, partString);
+ }
+ else if (!strcmp(mp->omegaVar, "Ny98"))
+ {
+ p->nValues = 3; /* omega values */
+ p->nSubValues = 6; /* omega category frequencies plus cache */
+ for (i=0; i<numCurrentDivisions; i++)
+ if (isPartTouched[i] == YES)
+ modelSettings[i].omega = p;
+
+ /* find the parameter x prior type */
+ if (!strcmp(mp->ny98omega1pr, "Beta") && !strcmp(mp->ny98omega3pr, "Uniform") && !strcmp(mp->codonCatFreqPr, "Dirichlet"))
+ p->paramId = OMEGA_BUD;
+ else if (!strcmp(mp->ny98omega1pr, "Beta") && !strcmp(mp->ny98omega3pr, "Uniform") && !strcmp(mp->codonCatFreqPr, "Fixed"))
+ p->paramId = OMEGA_BUF;
+ else if (!strcmp(mp->ny98omega1pr, "Beta") && !strcmp(mp->ny98omega3pr, "Exponential") && !strcmp(mp->codonCatFreqPr, "Dirichlet"))
+ p->paramId = OMEGA_BED;
+ else if (!strcmp(mp->ny98omega1pr, "Beta") && !strcmp(mp->ny98omega3pr, "Exponential") && !strcmp(mp->codonCatFreqPr, "Fixed"))
+ p->paramId = OMEGA_BEF;
+ else if (!strcmp(mp->ny98omega1pr, "Beta") && !strcmp(mp->ny98omega3pr, "Fixed") && !strcmp(mp->codonCatFreqPr, "Dirichlet"))
+ p->paramId = OMEGA_BFD;
+ else if (!strcmp(mp->ny98omega1pr, "Beta") && !strcmp(mp->ny98omega3pr, "Fixed") && !strcmp(mp->codonCatFreqPr, "Fixed"))
+ p->paramId = OMEGA_BFF;
+ else if (!strcmp(mp->ny98omega1pr, "Fixed") && !strcmp(mp->ny98omega3pr, "Uniform") && !strcmp(mp->codonCatFreqPr, "Dirichlet"))
+ p->paramId = OMEGA_FUD;
+ else if (!strcmp(mp->ny98omega1pr, "Fixed") && !strcmp(mp->ny98omega3pr, "Uniform") && !strcmp(mp->codonCatFreqPr, "Fixed"))
+ p->paramId = OMEGA_FUF;
+ else if (!strcmp(mp->ny98omega1pr, "Fixed") && !strcmp(mp->ny98omega3pr, "Exponential") && !strcmp(mp->codonCatFreqPr, "Dirichlet"))
+ p->paramId = OMEGA_FED;
+ else if (!strcmp(mp->ny98omega1pr, "Fixed") && !strcmp(mp->ny98omega3pr, "Exponential") && !strcmp(mp->codonCatFreqPr, "Fixed"))
+ p->paramId = OMEGA_FEF;
+ else if (!strcmp(mp->ny98omega1pr, "Fixed") && !strcmp(mp->ny98omega3pr, "Fixed") && !strcmp(mp->codonCatFreqPr, "Dirichlet"))
+ p->paramId = OMEGA_FFD;
+ else if (!strcmp(mp->ny98omega1pr, "Fixed") && !strcmp(mp->ny98omega3pr, "Fixed") && !strcmp(mp->codonCatFreqPr, "Fixed"))
+ p->paramId = OMEGA_FFF;
+
+ if (p->paramId != OMEGA_FFF)
+ p->printParam = YES;
+ SafeStrcat (&p->paramHeader, "omega(-)");
+ SafeStrcat (&p->paramHeader, partString);
+ SafeStrcat (&p->paramHeader, "\tomega(N)");
+ SafeStrcat (&p->paramHeader, partString);
+ SafeStrcat (&p->paramHeader, "\tomega(+)");
+ SafeStrcat (&p->paramHeader, partString);
+
+ SafeStrcat (&p->paramHeader, "\tpi(-)");
+ SafeStrcat (&p->paramHeader, partString);
+ SafeStrcat (&p->paramHeader, "\tpi(N)");
+ SafeStrcat (&p->paramHeader, partString);
+ SafeStrcat (&p->paramHeader, "\tpi(+)");
+ SafeStrcat (&p->paramHeader, partString);
+ }
+ else
+ {
+ p->nValues = 1;
+ p->nSubValues = 0;
+ for (i=0; i<numCurrentDivisions; i++)
+ if (isPartTouched[i] == YES)
+ modelSettings[i].omega = p;
+
+ /* find the parameter x prior type */
+ if (!strcmp(mp->omegaPr,"Dirichlet"))
+ p->paramId = OMEGA_DIR;
+ else
+ p->paramId = OMEGA_FIX;
+
+ if (p->paramId != OMEGA_FIX)
+ p->printParam = YES;
+ SafeStrcat (&p->paramHeader, "omega");
+ SafeStrcat (&p->paramHeader, partString);
+ }
+ p->paramTypeName = "Positive selection (omega) model";
+ SafeStrcat(&p->name, "Omega");
+ SafeStrcat(&p->name, partString);
+ }
+ else if (j == P_PI)
+ {
+ /* Set up state frequencies *****************************************************************************/
+ p->paramType = P_PI;
+ p->min = 0.0;
+ p->max = 1.0;
+ for (i=0; i<numCurrentDivisions; i++)
+ if (isPartTouched[i] == YES)
+ modelSettings[i].stateFreq = p;
+
+ if (mp->dataType == STANDARD)
+ {
+ p->paramTypeName = "Symmetric diricihlet/beta distribution alpha_i parameter";
+ SafeStrcat(&p->name, "Alpha_symdir");
+ /* boundaries for alpha_i */
+ p->min = ETA;
+ p->max = POS_INFINITY;
+ }
+ else
+ {
+ p->paramTypeName = "Stationary state frequencies";
+ SafeStrcat(&p->name, "Pi");
+ }
+ SafeStrcat(&p->name, partString);
+
+ /* find the parameter x prior type */
+ /* and the number of values and subvalues needed */
+ if (mp->dataType == STANDARD)
+ {
+ /* find number of model states */
+ m->numModelStates = 2;
+ for (c=0; c<numChar; c++)
+ {
+ for (i=0; i<p->nRelParts; i++)
+ {
+ if (partitionId[c][partitionNum] == p->relParts[i] + 1 && charInfo[c].numStates > m->numModelStates)
+ m->numModelStates = charInfo[c].numStates;
+ }
+ }
+ for (i=0; i<p->nRelParts; i++)
+ modelSettings[p->relParts[i]].numModelStates = m->numModelStates;
+
+ /* symmetric hyperprior with only one variable (0 if equal) */
+ p->nValues = 1; /* set to 0 below for the SYMPI_EQUAL model */
+ if (!strcmp(mp->symPiPr,"Uniform"))
+ {
+ if (m->numModelStates > 2)
+ p->paramId = SYMPI_UNI_MS;
+ else
+ p->paramId = SYMPI_UNI;
+ }
+ else if (!strcmp(mp->symPiPr,"Exponential"))
+ {
+ if (m->numModelStates > 2)
+ p->paramId = SYMPI_EXP_MS;
+ else
+ p->paramId = SYMPI_EXP;
+ }
+ else if (!strcmp(mp->symPiPr,"Fixed"))
+ {
+ if (AreDoublesEqual(mp->symBetaFix, -1.0, 0.00001) == YES)
+ {
+ p->paramId = SYMPI_EQUAL;
+ p->nValues = 0;
+ }
+ else
+ {
+ if (m->numModelStates > 2)
+ p->paramId = SYMPI_FIX_MS;
+ else
+ p->paramId = SYMPI_FIX;
+ }
+ }
+ p->nSubValues = 0; /* store state frequencies in p->stdStateFreqs */
+ if (p->paramId == SYMPI_EXP || p->paramId == SYMPI_EXP_MS || p->paramId == SYMPI_UNI || p->paramId == SYMPI_UNI_MS)
+ p->printParam = YES;
+ SafeStrcat (&p->paramHeader, "alpha_symdir");
+ SafeStrcat (&p->paramHeader, partString);
+ /* further processing done in ProcessStdChars */
+ }
+ else
+ {
+ /* deal with all models except standard */
+ /* no hyperprior or fixed to one value, set default to 0 */
+ p->nValues = 0;
+ /* one subvalue for each state */
+ p->nSubValues = mp->nStates; /* mp->nStates is set to 20 if DNA || RNA && nucmodel==PROTEIN */
+ if (!strcmp(mp->stateFreqPr, "Dirichlet"))
+ {
+ p->paramId = PI_DIR;
+ p->nValues = mp->nStates;
+ }
+ else if (!strcmp(mp->stateFreqPr, "Fixed") && !strcmp(mp->stateFreqsFixType,"User"))
+ p->paramId = PI_USER;
+ else if (!strcmp(mp->stateFreqPr, "Fixed") && !strcmp(mp->stateFreqsFixType,"Empirical"))
+ p->paramId = PI_EMPIRICAL;
+ else if (!strcmp(mp->stateFreqPr, "Fixed") && !strcmp(mp->stateFreqsFixType,"Equal"))
+ {
+ p->paramId = PI_EQUAL;
+ }
+
+ if (m->dataType == PROTEIN)
+ {
+ if (!strcmp(mp->aaModelPr, "Fixed"))
+ {
+ if (!strcmp(mp->aaModel, "Poisson"))
+ p->paramId = PI_EQUAL;
+ else if (!strcmp(mp->aaModel, "Equalin") || !strcmp(mp->aaModel, "Gtr"))
+ {
+ /* p->paramId stays to what it was set to above */
+ }
+ else
+ p->paramId = PI_FIXED;
+ }
+ else
+ p->paramId = PI_FIXED;
+ }
+
+ if (p->paramId == PI_DIR)
+ p->printParam = YES;
+ if (m->dataType == DNA || m->dataType == RNA)
+ {
+ if (!strcmp(mp->nucModel, "4by4"))
+ {
+ sprintf (temp, "pi(%c)", StateCode_NUC4(0));
+ SafeStrcat (&p->paramHeader,temp);
+ SafeStrcat (&p->paramHeader,partString);
+ for (n1=1; n1<4; n1++)
+ {
+ sprintf (temp, "\tpi(%c)", StateCode_NUC4(n1));
+ SafeStrcat (&p->paramHeader,temp);
+ SafeStrcat (&p->paramHeader,partString);
+ }
+ }
+ else if (!strcmp(mp->nucModel, "Doublet"))
+ {
+ State_DOUBLET(tempCodon,0);
+ sprintf (temp, "pi(%s)", tempCodon);
+ SafeStrcat (&p->paramHeader,temp);
+ SafeStrcat (&p->paramHeader,partString);
+ for (n1=1; n1<16; n1++)
+ {
+ State_DOUBLET(tempCodon,n1);
+ sprintf (temp, "\tpi(%s)", tempCodon);
+ SafeStrcat (&p->paramHeader,temp);
+ SafeStrcat (&p->paramHeader,partString);
+ }
+ }
+ else if (!strcmp(mp->nucModel, "Codon"))
+ {
+ for (c=0; c<p->nSubValues; c++)
+ {
+ if (mp->codonNucs[c][0] == 0)
+ strcpy (tempCodon, "pi(A");
+ else if (mp->codonNucs[c][0] == 1)
+ strcpy (tempCodon, "pi(C");
+ else if (mp->codonNucs[c][0] == 2)
+ strcpy (tempCodon, "pi(G");
+ else
+ strcpy (tempCodon, "pi(T");
+ if (mp->codonNucs[c][1] == 0)
+ strcat (tempCodon, "A");
+ else if (mp->codonNucs[c][1] == 1)
+ strcat (tempCodon, "C");
+ else if (mp->codonNucs[c][1] == 2)
+ strcat (tempCodon, "G");
+ else
+ strcat (tempCodon, "T");
+ if (mp->codonNucs[c][2] == 0)
+ strcat (tempCodon, "A)");
+ else if (mp->codonNucs[c][2] == 1)
+ strcat (tempCodon, "C)");
+ else if (mp->codonNucs[c][2] == 2)
+ strcat (tempCodon, "G)");
+ else
+ strcat (tempCodon, "T)");
+ if (c == 0)
+ {
+ SafeStrcat (&p->paramHeader, tempCodon);
+ SafeStrcat (&p->paramHeader, partString);
+ }
+ else
+ {
+ SafeStrcat (&p->paramHeader, "\t");
+ SafeStrcat (&p->paramHeader, tempCodon);
+ SafeStrcat (&p->paramHeader, partString);
+ }
+ }
+ }
+ }
+ else if (m->dataType == PROTEIN)
+ {
+ if (FillRelPartsString (p, &partString) == YES)
+ {
+ SafeSprintf (&tempStr, &tempStrSize, "pi(Ala)%s\tpi(Arg)%s\tpi(Asn)%s\tpi(Asp)%s\tpi(Cys)%s\tpi(Gln)%s\tpi(Glu)%s\tpi(Gly)%s\tpi(His)%s\tpi(Ile)%s\tpi(Leu)%s\tpi(Lys)%s\tpi(Met)%s\tpi(Phe)%s\tpi(Pro)%s\tpi(Ser)%s\tpi(Thr)%s\tpi(Trp)%s\tpi(Tyr)%s\tpi(Val)%s",
+ partString, partString, partString, partString, partString, partString, partString, partString, partString, partString,
+ partString, partString, partString, partString, partString, partString, partString, partString, partString, partString);
+ SafeStrcat (&p->paramHeader, tempStr);
+ }
+ else
+ SafeStrcat (&p->paramHeader, "pi(Ala)\tpi(Arg)\tpi(Asn)\tpi(Asp)\tpi(Cys)\tpi(Gln)\tpi(Glu)\tpi(Gly)\tpi(His)\tpi(Ile)\tpi(Leu)\tpi(Lys)\tpi(Met)\tpi(Phe)\tpi(Pro)\tpi(Ser)\tpi(Thr)\tpi(Trp)\tpi(Tyr)\tpi(Val)");
+ }
+ else if (mp->dataType == RESTRICTION)
+ {
+ if (FillRelPartsString (p, &partString) == YES)
+ {
+ SafeSprintf (&tempStr, &tempStrSize, "pi(0)%s\tpi(1)%s", partString, partString);
+ SafeStrcat (&p->paramHeader, tempStr);
+ }
+ else
+ SafeStrcat (&p->paramHeader, "pi(0)\tpi(1)");
+ }
+ else
+ {
+ MrBayesPrint ("%s Unknown data type in SetModelParams\n", spacer);
+ }
+ }
+ }
+ else if (j == P_SHAPE)
+ {
+ /* Set up shape parameter of gamma/lnorm *****************************************************************/
+ p->paramType = P_SHAPE;
+ p->nValues = 1;
+ p->nSubValues = mp->numGammaCats;
+ p->min = 1E-5;
+ p->max = 100;
+ for (i=0; i<numCurrentDivisions; i++)
+ if (isPartTouched[i] == YES)
+ modelSettings[i].shape = p;
+ if(!strcmp(mp->ratesModel, "LNorm"))
+ {
+ p->paramTypeName = "SD of scaled lognormal distribution of site rates";
+ SafeStrcat(&p->name, "Sigma");
+ SafeStrcat (&p->paramHeader, "sigma");
+ }
+ else
+ {
+ p->paramTypeName = "Shape of scaled gamma distribution of site rates";
+ SafeStrcat(&p->name, "Alpha");
+ SafeStrcat (&p->paramHeader, "alpha");
+ }
+ SafeStrcat(&p->name, partString);
+ SafeStrcat (&p->paramHeader, partString);
+
+ /* find the parameter x prior type */
+ mp = &modelParams[p->relParts[0]];
+ if (!strcmp(mp->shapePr,"Uniform"))
+ p->paramId = SHAPE_UNI;
+ else if (!strcmp(mp->shapePr,"Exponential"))
+ p->paramId = SHAPE_EXP;
+ else
+ p->paramId = SHAPE_FIX;
+
+ if (p->paramId != SHAPE_FIX)
+ p->printParam = YES;
+ }
+ else if (j == P_PINVAR)
+ {
+ /* Set up proportion of invariable sites ****************************************************************/
+ p->paramType = P_PINVAR;
+ p->nValues = 1;
+ p->nSubValues = 0;
+ p->min = 0.0;
+ p->max = 1.0;
+ for (i=0; i<numCurrentDivisions; i++)
+ if (isPartTouched[i] == YES)
+ modelSettings[i].pInvar = p;
+
+ p->paramTypeName = "Proportion of invariable sites";
+ SafeStrcat(&p->name, "Pinvar");
+ SafeStrcat(&p->name, partString);
+
+ /* find the parameter x prior type */
+ if (!strcmp(mp->pInvarPr,"Uniform"))
+ p->paramId = PINVAR_UNI;
+ else
+ p->paramId = PINVAR_FIX;
+
+ if (p->paramId != PINVAR_FIX)
+ p->printParam = YES;
+ SafeStrcat (&p->paramHeader, "pinvar");
+ SafeStrcat (&p->paramHeader, partString);
+ }
+ else if (j == P_CORREL)
+ {
+ /* Set up correlation parameter of adgamma model ********************************************************/
+ p->paramType = P_CORREL;
+ p->nValues = 1;
+ p->nSubValues = mp->numGammaCats * mp->numGammaCats;
+ p->min = -1.0;
+ p->max = 1.0;
+ for (i=0; i<numCurrentDivisions; i++)
+ if (isPartTouched[i] == YES)
+ modelSettings[i].correlation = p;
+
+ p->paramTypeName = "Autocorrelation of gamma distribution of site rates";
+ SafeStrcat(&p->name, "Rho");
+ SafeStrcat(&p->name, partString);
+ chainHasAdgamma = YES;
+
+ /* find the parameter x prior type */
+ if (!strcmp(mp->adGammaCorPr,"Uniform"))
+ p->paramId = CORREL_UNI;
+ else
+ p->paramId = CORREL_FIX;
+
+ if (p->paramId != CORREL_FIX)
+ p->printParam = YES;
+ SafeStrcat (&p->paramHeader, "rho");
+ SafeStrcat (&p->paramHeader, partString);
+ }
+ else if (j == P_SWITCH)
+ {
+ /* Set up switchRates for covarion model ****************************************************************/
+ p->paramType = P_SWITCH;
+ p->nValues = 2;
+ p->nSubValues = mp->numGammaCats * mp->numGammaCats;
+ p->min = 0.0;
+ p->max = POS_INFINITY;
+ for (i=0; i<numCurrentDivisions; i++)
+ if (isPartTouched[i] == YES)
+ modelSettings[i].switchRates = p;
+
+ p->paramTypeName = "Switch rates of covarion model";
+ SafeStrcat(&p->name, "s_cov");
+ SafeStrcat(&p->name, partString);
+
+ /* find the parameter x prior type */
+ if (!strcmp(mp->covSwitchPr,"Uniform"))
+ p->paramId = SWITCH_UNI;
+ else if (!strcmp(mp->covSwitchPr,"Exponential"))
+ p->paramId = SWITCH_EXP;
+ else
+ p->paramId = SWITCH_FIX;
+
+ if (p->paramId != SWITCH_FIX)
+ p->printParam = YES;
+
+ SafeStrcat (&p->paramHeader, "s(off->on)");
+ SafeStrcat (&p->paramHeader, partString);
+ SafeStrcat (&p->paramHeader, "\ts(on->off)");
+ SafeStrcat (&p->paramHeader, partString);
+ }
+ else if (j == P_RATEMULT)
+ {
+ /* Set up rateMult for partition specific rates ***********************************************************/
+ p->paramType = P_RATEMULT;
+ if (!strcmp(mp->ratePr,"Fixed"))
+ {
+ p->nValues = 1;
+ p->nSubValues = 0;
+ }
+ else
+ {
+ p->nValues = p->nRelParts = numRelParts; /* keep scaled division rates in value */
+ p->nSubValues = p->nValues * 2; /* keep number of uncompressed chars for scaling in subValue */
+ } /* also keep Dirichlet prior parameters here */
+ p->min = POS_MIN;
+ p->max = POS_INFINITY;
+ for (i=0; i<numCurrentDivisions; i++)
+ if (isPartTouched[i] == YES)
+ modelSettings[i].rateMult = p;
+
+ p->paramTypeName = "Partition-specific rate multiplier";
+ SafeStrcat(&p->name, "Ratemultiplier");
+ SafeStrcat(&p->name, partString);
+
+ /* find the parameter x prior type */
+ if (p->nSubValues == 0)
+ p->paramId = RATEMULT_FIX;
+ else
+ p->paramId = RATEMULT_DIR;
+
+ if (p->paramId != RATEMULT_FIX)
+ p->printParam = YES;
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (isPartTouched[i] == YES)
+ {
+ sprintf (tempMult, "m{%d}", i+1);
+ if (i == 0)
+ SafeStrcat (&p->paramHeader, tempMult);
+ else
+ {
+ SafeStrcat (&p->paramHeader, "\t");
+ SafeStrcat (&p->paramHeader, tempMult);
+ }
+ }
+ }
+ }
+ else if (j == P_GENETREERATE)
+ {
+ /* Set up rateMult for gene specific rates ****************************************************************/
+ p->paramType = P_GENETREERATE;
+ p->nValues = p->nRelParts = numRelParts; /* keep scaled division rates in value */
+ p->nSubValues = p->nValues * 2; /* keep number of uncompressed chars for scaling in subValue */
+ /* also keep Dirichlet prior parameters here */
+ p->min = POS_MIN;
+ p->max = POS_INFINITY;
+ for (i=0; i<numCurrentDivisions; i++)
+ if (isPartTouched[i] == YES)
+ modelSettings[i].geneTreeRateMult = p;
+
+ p->paramTypeName = "Gene-specific rate multiplier";
+ SafeStrcat(&p->name, "Generatemult");
+ SafeStrcat(&p->name, partString);
+
+ /* find the parameter x prior type */
+ if (strcmp(mp->generatePr,"Fixed") == 0)
+ p->paramId = GENETREERATEMULT_FIX;
+ else
+ p->paramId = GENETREERATEMULT_DIR;
+
+ if (p->paramId == GENETREERATEMULT_FIX)
+ p->printParam = NO;
+ else
+ p->printParam = YES;
+
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (isPartTouched[i] == YES)
+ {
+ sprintf (tempMult, "g_m{%d}", i+1);
+ if (i == 0)
+ SafeStrcat (&p->paramHeader, tempMult);
+ else
+ {
+ SafeStrcat (&p->paramHeader, "\t");
+ SafeStrcat (&p->paramHeader, tempMult);
+ }
+ }
+ }
+ }
+ else if (j == P_TOPOLOGY)
+ {
+ /* Set up topology **************************************************************************************/
+ p->paramType = P_TOPOLOGY;
+ p->nValues = 0;
+ p->nSubValues = 0;
+ p->min = NEG_INFINITY; /* NA */
+ p->max = NEG_INFINITY; /* NA */
+ for (i=0; i<numCurrentDivisions; i++)
+ if (isPartTouched[i] == YES)
+ modelSettings[i].topology = p;
+
+ p->paramTypeName = "Topology";
+ SafeStrcat(&p->name, "Tau");
+ SafeStrcat(&p->name, partString);
+
+ /* check that the model is not parsimony for all of the relevant partitions */
+ areAllPartsParsimony = YES;
+ for (i=0; i<p->nRelParts; i++)
+ {
+ if (modelSettings[p->relParts[i]].parsModelId == NO)
+ areAllPartsParsimony = NO;
+ }
+
+ /* check if topology is clock or nonclock */
+ nClockBrlens = 0;
+ nCalibratedBrlens = 0;
+ nRelaxedBrlens = 0;
+ if (areAllPartsParsimony == NO)
+ {
+ for (i=0; i<p->nRelParts; i++)
+ {
+ if (!strcmp(modelParams[p->relParts[i]].brlensPr, "Clock"))
+ {
+ nClockBrlens++;
+ if (strcmp(modelParams[p->relParts[i]].clockVarPr,"Strict") != 0) /* not strict */
+ nRelaxedBrlens++;
+ if (!strcmp(modelParams[p->relParts[i]].nodeAgePr,"Calibrated"))
+ nCalibratedBrlens++;
+ }
+ }
+ }
+
+ /* now find the parameter x prior type */
+ if (areAllPartsParsimony == YES)
+ {
+ if (!strcmp(mp->topologyPr, "Uniform"))
+ p->paramId = TOPOLOGY_PARSIMONY_UNIFORM;
+ else if (!strcmp(mp->topologyPr,"Constraints"))
+ p->paramId = TOPOLOGY_PARSIMONY_CONSTRAINED;
+ else
+ p->paramId = TOPOLOGY_PARSIMONY_FIXED;
+ /* For this case, we also need to set the brlens ptr of the relevant partitions
+ so that it points to the topology parameter, since the rest of the
+ program will try to access the tree through this pointer. In FillTreeParams,
+ we will make sure that a pure parsimony topology parameter contains a pointer
+ to the relevant tree (like a brlens parameter would normally) */
+ for (i=0; i<p->nRelParts; i++)
+ modelSettings[p->relParts[i]].brlens = p;
+ }
+ else
+ {
+ /* we assume for now that there is only one branch length; we will correct this
+ later in AllocateTreeParams if there are more than one set of branch lengths,
+ which is only possible for non-clock trees */
+ if (!strcmp(mp->topologyPr, "Speciestree"))
+ p->paramId = TOPOLOGY_SPECIESTREE;
+ else if (!strcmp(mp->topologyPr, "Uniform") && nClockBrlens == 0)
+ p->paramId = TOPOLOGY_NCL_UNIFORM_HOMO;
+ else if (!strcmp(mp->topologyPr,"Constraints") && nClockBrlens == 0)
+ p->paramId = TOPOLOGY_NCL_CONSTRAINED_HOMO;
+ else if (!strcmp(mp->topologyPr,"Fixed") && nClockBrlens == 0)
+ p->paramId = TOPOLOGY_NCL_FIXED_HOMO;
+ /* all below have clock branch lengths */
+ else if (!strcmp(mp->topologyPr, "Uniform") && nRelaxedBrlens == 0)
+ {
+ if (nCalibratedBrlens >= 1)
+ p->paramId = TOPOLOGY_CCL_UNIFORM;
+ else
+ p->paramId = TOPOLOGY_CL_UNIFORM;
+ }
+ else if (!strcmp(mp->topologyPr,"Constraints") && nRelaxedBrlens == 0)
+ {
+ if (nCalibratedBrlens >= 1)
+ p->paramId = TOPOLOGY_CCL_CONSTRAINED;
+ else
+ p->paramId = TOPOLOGY_CL_CONSTRAINED;
+ }
+ else if (!strcmp(mp->topologyPr,"Fixed") && nRelaxedBrlens == 0)
+ {
+ if (nCalibratedBrlens >= 1)
+ p->paramId = TOPOLOGY_CCL_FIXED;
+ else
+ p->paramId = TOPOLOGY_CL_FIXED;
+ }
+ /* all below have relaxed clock branch lengths */
+ else if (!strcmp(mp->topologyPr, "Uniform"))
+ {
+ if (nCalibratedBrlens >= 1)
+ p->paramId = TOPOLOGY_RCCL_UNIFORM;
+ else
+ p->paramId = TOPOLOGY_RCL_UNIFORM;
+ }
+ else if (!strcmp(mp->topologyPr,"Constraints"))
+ {
+ if (nCalibratedBrlens >= 1)
+ p->paramId = TOPOLOGY_RCCL_CONSTRAINED;
+ else
+ p->paramId = TOPOLOGY_RCL_CONSTRAINED;
+ }
+ else if (!strcmp(mp->topologyPr,"Fixed"))
+ {
+ if (nCalibratedBrlens >= 1)
+ p->paramId = TOPOLOGY_RCCL_FIXED;
+ else
+ p->paramId = TOPOLOGY_RCL_FIXED;
+ }
+ }
+
+ /* should we print the topology? */
+ for (i=0; i<p->nRelParts; i++)
+ if (strcmp(modelParams[p->relParts[i]].treeFormat,"Topology") != 0)
+ break;
+ if (i == p->nRelParts)
+ p->printParam = YES;
+ else
+ p->printParam = NO;
+ /* but always print parsimony topology */
+ if (areAllPartsParsimony == YES)
+ p->printParam = YES;
+ /* and never print fixed topologies */
+ if (p->paramId == TOPOLOGY_RCL_FIXED ||
+ p->paramId == TOPOLOGY_RCCL_FIXED ||
+ p->paramId == TOPOLOGY_CL_FIXED ||
+ p->paramId == TOPOLOGY_CCL_FIXED ||
+ p->paramId == TOPOLOGY_NCL_FIXED ||
+ p->paramId == TOPOLOGY_PARSIMONY_FIXED)
+ p->printParam = NO;
+ }
+ else if (j == P_BRLENS)
+ {
+ /* Set up branch lengths ********************************************************************************/
+ p->paramType = P_BRLENS;
+ p->nValues = 0;
+ p->nSubValues = 0;
+ p->min = 0.0;
+ p->max = POS_INFINITY;
+ for (i=0; i<numCurrentDivisions; i++)
+ if (isPartTouched[i] == YES)
+ modelSettings[i].brlens = p;
+
+ p->paramTypeName = "Branch lengths";
+ SafeStrcat(&p->name, "V");
+ SafeStrcat(&p->name, partString);
+
+ /* find the parameter x prior type */
+ if (modelSettings[p->relParts[0]].parsModelId == YES)
+ p->paramId = BRLENS_PARSIMONY;
+ else
+ {
+ if (!strcmp(mp->brlensPr, "Clock"))
+ {
+ if (!strcmp(mp->clockPr,"Uniform"))
+ p->paramId = BRLENS_CLOCK_UNI;
+ else if (!strcmp(mp->clockPr,"Coalescence"))
+ p->paramId = BRLENS_CLOCK_COAL;
+ else if (!strcmp(mp->clockPr,"Birthdeath"))
+ p->paramId = BRLENS_CLOCK_BD;
+ else if (!strcmp(mp->clockPr,"Speciestreecoalescence"))
+ p->paramId = BRLENS_CLOCK_SPCOAL;
+ else if (!strcmp(mp->clockPr,"Fossilization"))
+ p->paramId = BRLENS_CLOCK_FOSSIL;
+ else if (!strcmp(mp->clockPr,"Fixed"))
+ p->paramId = BRLENS_CLOCK_FIXED;
+ }
+ else if (!strcmp(mp->brlensPr, "Unconstrained"))
+ {
+ if (!strcmp(mp->unconstrainedPr,"Uniform"))
+ p->paramId = BRLENS_UNI;
+ else if (!strcmp(mp->unconstrainedPr,"Exponential"))
+ p->paramId = BRLENS_EXP;
+ else if (!strcmp(mp->unconstrainedPr,"GammaDir"))
+ p->paramId = BRLENS_GamDir;
+ else if (!strcmp(mp->unconstrainedPr,"invGamDir"))
+ p->paramId = BRLENS_iGmDir;
+ else if (!strcmp(mp->unconstrainedPr,"twoExp"))
+ p->paramId = BRLENS_twoExp;
+ }
+ else if (!strcmp(mp->brlensPr,"Fixed"))
+ {
+ p->paramId = BRLENS_FIXED;
+ }
+ }
+
+ /* should we print the branch lengths? */
+ for (i=0; i<p->nRelParts; i++)
+ if (strcmp(modelParams[p->relParts[i]].treeFormat,"Topology") != 0)
+ break;
+ if (i < p->nRelParts)
+ p->printParam = YES;
+ else
+ p->printParam = NO;
+ }
+ else if (j == P_SPECIESTREE)
+ {
+ /* Set up species tree **************************************************************************************/
+ p->paramType = P_SPECIESTREE;
+ p->nValues = 0;
+ p->nSubValues = 0;
+ p->min = NEG_INFINITY; /* NA */
+ p->max = NEG_INFINITY; /* NA */
+ for (i=0; i<numCurrentDivisions; i++)
+ if (isPartTouched[i] == YES)
+ modelSettings[i].speciesTree = p;
+
+ p->paramTypeName = "Species tree";
+ SafeStrcat(&p->name, "Spt");
+ SafeStrcat(&p->name, partString);
+
+ /* check that the model is not parsimony for all of the relevant partitions */
+ areAllPartsParsimony = YES;
+ for (i=0; i<p->nRelParts; i++)
+ {
+ if (modelSettings[p->relParts[i]].parsModelId == NO)
+ areAllPartsParsimony = NO;
+ }
+
+ /* find the parameter x prior type */
+ p->paramId = SPECIESTREE_UNIFORM;
+
+ /* should we print the tree? */
+ p->printParam = YES;
+ }
+ else if (j == P_SPECRATE)
+ {
+ /* Set up speciation rate ******************************************************************************/
+ p->paramType = P_SPECRATE;
+ if (!strcmp(mp->clockPr,"Fossilization"))
+ p->nValues = mp->sampleFSNum +1; // rate in each time interval
+ else
+ p->nValues = 1;
+ p->nSubValues = 0;
+ p->min = POS_MIN;
+ p->max = POS_INFINITY;
+ for (i=0; i<numCurrentDivisions; i++)
+ if (isPartTouched[i] == YES)
+ modelSettings[i].speciationRates = p;
+
+ p->paramTypeName = "Speciation rate";
+ SafeStrcat(&p->name, "Net_speciation");
+ SafeStrcat(&p->name, partString);
+
+ /* find the parameter x prior type */
+ if (!strcmp(mp->speciationPr,"Uniform"))
+ p->paramId = SPECRATE_UNI;
+ else if (!strcmp(mp->speciationPr,"Exponential"))
+ p->paramId = SPECRATE_EXP;
+ else
+ p->paramId = SPECRATE_FIX;
+
+ if (p->paramId != SPECRATE_FIX)
+ p->printParam = YES;
+
+ if (p->nValues == 1)
+ {
+ SafeStrcat (&p->paramHeader, "net_speciation");
+ SafeStrcat (&p->paramHeader, partString);
+ }
+ else for (i = 0; i < p->nValues; i++)
+ {
+ sprintf (tempStr, "\tnet_speciation_%d", i+1);
+ SafeStrcat (&p->paramHeader, tempStr);
+ SafeStrcat (&p->paramHeader, partString);
+ }
+ }
+ else if (j == P_EXTRATE)
+ {
+ /* Set up extinction rates ******************************************************************************/
+ p->paramType = P_EXTRATE;
+ if (!strcmp(mp->clockPr,"Fossilization"))
+ p->nValues = mp->sampleFSNum +1; // rate in each time interval
+ else
+ p->nValues = 1;
+ p->nSubValues = 0;
+ p->min = 0.0;
+ p->max = 1.0;
+ for (i=0; i<numCurrentDivisions; i++)
+ if (isPartTouched[i] == YES)
+ modelSettings[i].extinctionRates = p;
+
+ p->paramTypeName = "Extinction rate";
+ SafeStrcat(&p->name, "Relative_extinction");
+ SafeStrcat(&p->name, partString);
+
+ /* find the parameter x prior type */
+ if (!strcmp(mp->extinctionPr,"Beta"))
+ p->paramId = EXTRATE_BETA;
+ else
+ p->paramId = EXTRATE_FIX;
+
+ if (p->paramId != EXTRATE_FIX)
+ p->printParam = YES;
+
+ if (p->nValues == 1)
+ {
+ SafeStrcat (&p->paramHeader, "relative_extinction");
+ SafeStrcat (&p->paramHeader, partString);
+ }
+ else for (i = 0; i < p->nValues; i++)
+ {
+ sprintf (tempStr, "\trelative_extinction_%d", i+1);
+ SafeStrcat (&p->paramHeader, tempStr);
+ SafeStrcat (&p->paramHeader, partString);
+ }
+ }
+ else if (j == P_FOSLRATE)
+ {
+ /* Set up fossilization rates */
+ p->paramType = P_FOSLRATE;
+ p->nValues = mp->sampleFSNum +1; // rate in each time interval
+ p->nSubValues = 0;
+ p->min = 0.0;
+ p->max = 1.0;
+ for (i=0; i<numCurrentDivisions; i++)
+ if (isPartTouched[i] == YES)
+ modelSettings[i].fossilizationRates = p;
+
+ p->paramTypeName = "Fossilization rate";
+ SafeStrcat(&p->name, "Relative_fossilization");
+ SafeStrcat(&p->name, partString);
+
+ /* find the parameter x prior type */
+ if (!strcmp(mp->fossilizationPr,"Beta"))
+ p->paramId = FOSLRATE_BETA;
+ else
+ p->paramId = FOSLRATE_FIX;
+
+ if (p->paramId != FOSLRATE_FIX)
+ p->printParam = YES;
+
+ if (p->nValues == 1)
+ {
+ SafeStrcat (&p->paramHeader, "relative_fossilization");
+ SafeStrcat (&p->paramHeader, partString);
+ }
+ else for (i = 0; i < p->nValues; i++)
+ {
+ sprintf (tempStr, "\trelative_fossilization_%d", i+1);
+ SafeStrcat (&p->paramHeader, tempStr);
+ SafeStrcat (&p->paramHeader, partString);
+ }
+ }
+ else if (j == P_POPSIZE)
+ {
+ /* Set up population size *****************************************************************************************/
+ p->paramType = P_POPSIZE;
+ if (!strcmp(mp->topologyPr,"Speciestree") && !strcmp(mp->popVarPr, "Variable"))
+ p->nValues = 2 * numSpecies;
+ else
+ p->nValues = 1;
+ p->nSubValues = 0;
+ p->min = POS_MIN;
+ p->max = POS_INFINITY;
+ for (i=0; i<numCurrentDivisions; i++)
+ if (isPartTouched[i] == YES)
+ modelSettings[i].popSize = p;
+
+ p->paramTypeName = "Coalescent process population size parameter";
+ SafeStrcat(&p->name, "Popsize");
+ SafeStrcat(&p->name, partString);
+
+ /* find the parameter x prior type */
+ if (!strcmp(mp->popSizePr,"Uniform"))
+ {
+ p->paramId = POPSIZE_UNI;
+ p->LnPriorRatio = &LnProbRatioUniform;
+ p->priorParams = mp->popSizeUni;
+ p->LnPriorProb = &LnPriorProbUniform;
+ }
+ else if (!strcmp(mp->popSizePr,"Normal"))
+ {
+ p->paramId = POPSIZE_NORMAL;
+ p->LnPriorRatio = &LnProbRatioTruncatedNormal;
+ p->priorParams = mp->popSizeNormal;
+ p->LnPriorProb = &LnPriorProbTruncatedNormal;
+ }
+ else if (!strcmp(mp->popSizePr,"Lognormal"))
+ {
+ p->paramId = POPSIZE_LOGNORMAL;
+ p->LnPriorRatio = &LnProbRatioLognormal;
+ p->priorParams = mp->popSizeLognormal;
+ p->LnPriorProb = &LnPriorProbLognormal;
+ }
+ else if (!strcmp(mp->popSizePr,"Gamma"))
+ {
+ p->paramId = POPSIZE_GAMMA;
+ p->LnPriorRatio = &LnProbRatioGamma;
+ p->priorParams = mp->popSizeGamma;
+ p->LnPriorProb = &LnPriorProbGamma;
+ }
+ else
+ {
+ p->paramId = POPSIZE_FIX;
+ p->LnPriorRatio = NULL;
+ p->priorParams = &mp->popSizeFix;
+ p->LnPriorProb = &LnPriorProbFix;
+ }
+
+ if (p->paramId != POPSIZE_FIX && p->nValues == 1)
+ p->printParam = YES;
+ SafeStrcat (&p->paramHeader, "popsize");
+ SafeStrcat (&p->paramHeader, partString);
+ }
+ else if (j == P_GROWTH)
+ {
+ /* Set up growth rate ************************************************************************************/
+ p->paramType = P_GROWTH;
+ p->nValues = 1;
+ p->nSubValues = 0;
+ p->min = 0.0;
+ p->max = POS_INFINITY;
+ for (i=0; i<numCurrentDivisions; i++)
+ if (isPartTouched[i] == YES)
+ modelSettings[i].growthRate = p;
+
+ p->paramTypeName = "Population growth rate";
+ SafeStrcat(&p->name, "R_pop");
+ SafeStrcat(&p->name, partString);
+
+ /* find the parameter x prior type */
+ if (!strcmp(mp->growthPr,"Uniform"))
+ {
+ p->paramId = GROWTH_UNI;
+ p->priorParams = mp->growthUni;
+ p->min = mp->growthUni[0];
+ p->max = mp->growthUni[1];
+ p->LnPriorRatio = &LnProbRatioUniform;
+ p->LnPriorProb = &LnPriorProbUniform;
+ }
+ else if (!strcmp(mp->growthPr,"Exponential"))
+ {
+ p->paramId = GROWTH_EXP;
+ p->priorParams = &mp->growthExp;
+ p->min = GROWTH_MIN;
+ p->max = GROWTH_MAX;
+ p->LnPriorRatio = &LnProbRatioExponential;
+ p->LnPriorProb = &LnPriorProbExponential;
+ }
+ else if (!strcmp(mp->growthPr,"Normal"))
+ {
+ p->paramId = GROWTH_NORMAL;
+ p->priorParams = mp->growthNorm;
+ p->min = GROWTH_MIN;
+ p->max = GROWTH_MAX;
+ p->LnPriorRatio = &LnProbRatioTruncatedNormal;
+ p->LnPriorProb = &LnPriorProbTruncatedNormal;
+ }
+ else
+ p->paramId = GROWTH_FIX;
+ {
+ p->paramId = GROWTH_FIX;
+ p->priorParams = &mp->growthFix;
+ p->min = p->max = mp->growthFix;
+ p->LnPriorRatio = &LnProbRatioFix;
+ p->LnPriorProb = &LnPriorProbFix;
+ }
+
+ if (p->paramId != GROWTH_FIX)
+ p->printParam = YES;
+ SafeStrcat (&p->paramHeader, "growthRate");
+ SafeStrcat (&p->paramHeader, partString);
+ }
+ else if (j == P_AAMODEL)
+ {
+ /* Set up aamodel *****************************************************************************************/
+ p->paramType = P_AAMODEL;
+ p->nValues = 1;
+ p->nSubValues = 10;
+ p->min = 0;
+ p->max = 9;
+ for (i=0; i<numCurrentDivisions; i++)
+ if (isPartTouched[i] == YES)
+ modelSettings[i].aaModel = p;
+
+ p->paramTypeName = "Aminoacid model";
+ SafeStrcat(&p->name, "Aamodel");
+ SafeStrcat(&p->name, partString);
+
+ /* find the parameter x prior type */
+ if (!strcmp(mp->aaModelPr,"Mixed"))
+ p->paramId = AAMODEL_MIX;
+ else
+ p->paramId = AAMODEL_FIX;
+
+ if (p->paramId != AAMODEL_FIX)
+ p->printParam = YES;
+ SafeStrcat (&p->paramHeader, "aamodel");
+ SafeStrcat (&p->paramHeader, partString);
+ }
+ else if (j == P_CPPRATE)
+ {
+ /* Set up cpprate *****************************************************************************************/
+ p->paramType = P_CPPRATE;
+ p->nValues = 1;
+ p->nSubValues = 0;
+ p->min = 0.0;
+ p->max = POS_INFINITY;
+ for (i=0; i<numCurrentDivisions; i++)
+ if (isPartTouched[i] == YES)
+ modelSettings[i].cppRate = p;
+
+ p->paramTypeName = "Rate of rate-multiplying compound Poisson process";
+ SafeStrcat(&p->name, "Lambda_cpp");
+ SafeStrcat(&p->name, partString);
+
+ /* find the parameter x prior type */
+ if (!strcmp(mp->cppRatePr,"Exponential"))
+ p->paramId = CPPRATE_EXP;
+ else
+ p->paramId = CPPRATE_FIX;
+
+ if (p->paramId != CPPRATE_FIX)
+ p->printParam = YES;
+ SafeStrcat (&p->paramHeader, "cppRate");
+ SafeStrcat (&p->paramHeader, partString);
+ }
+ else if (j == P_CPPMULTDEV)
+ {
+ /* Set up sigma of cpp rate multipliers *****************************************************************************************/
+ p->paramType = P_CPPMULTDEV;
+ p->nValues = 1;
+ p->nSubValues = 0;
+ p->min = 0.0;
+ p->max = POS_INFINITY;
+ for (i=0; i<numCurrentDivisions; i++)
+ if (isPartTouched[i] == YES)
+ modelSettings[i].cppMultDev = p;
+
+ p->paramTypeName = "Standard deviation (log) of CPP rate multipliers";
+ SafeStrcat(&p->name, "Sigma_cpp");
+ SafeStrcat(&p->name, partString);
+
+ /* find the parameter x prior type */
+ if (!strcmp(mp->cppMultDevPr,"Fixed"))
+ p->paramId = CPPMULTDEV_FIX;
+
+ if (p->paramId != CPPMULTDEV_FIX)
+ p->printParam = YES;
+ SafeStrcat (&p->paramHeader, "sigma_cpp");
+ SafeStrcat (&p->paramHeader, partString);
+ }
+ else if (j == P_CPPEVENTS)
+ {
+ /* Set up cpp events parameter *****************************************************************************************/
+ p->paramType = P_CPPEVENTS;
+ p->nValues = 0;
+ p->nSubValues = 2*numLocalTaxa; /* keep effective branch lengths here (for all nodes to be on the safe side) */
+ p->min = 1E-6;
+ p->max = POS_INFINITY;
+ for (i=0; i<numCurrentDivisions; i++)
+ if (isPartTouched[i] == YES)
+ modelSettings[i].cppEvents = p;
+
+ p->paramTypeName = "Events of rate-multiplying compound Poisson process";
+ SafeStrcat(&p->name, "CppEvents");
+ SafeStrcat(&p->name, partString);
+
+ /* find the parameter x prior type */
+ p->paramId = CPPEVENTS;
+
+ /* should we print values to .p file? */
+ p->printParam = NO;
+
+ SafeStrcat (&p->paramHeader, "cppEvents");
+ SafeStrcat (&p->paramHeader, partString);
+ }
+ else if (j == P_TK02VAR)
+ {
+ /* Set up tk02 relaxed clock variance parameter *****************************************************************************************/
+ p->paramType = P_TK02VAR;
+ p->nValues = 1;
+ p->nSubValues = 0;
+ p->min = 1E-6;
+ p->max = POS_INFINITY;
+ for (i=0; i<numCurrentDivisions; i++)
+ if (isPartTouched[i] == YES)
+ modelSettings[i].tk02var = p;
+
+ p->paramTypeName = "Variance of lognormal distribution of branch rates";
+ SafeStrcat(&p->name, "TK02var");
+ SafeStrcat(&p->name, partString);
+
+ /* find the parameter x prior type */
+ if (!strcmp(mp->tk02varPr,"Uniform"))
+ p->paramId = TK02VAR_UNI;
+ else if (!strcmp(mp->tk02varPr,"Exponential"))
+ p->paramId = TK02VAR_EXP;
+ else
+ p->paramId = TK02VAR_FIX;
+
+ if (p->paramId != TK02VAR_FIX)
+ p->printParam = YES;
+ SafeStrcat (&p->paramHeader, "tk02var");
+ SafeStrcat (&p->paramHeader, partString);
+ }
+ else if (j == P_TK02BRANCHRATES)
+ {
+ /* Set up tk02 relaxed clock rates parameter *****************************************************************************************/
+ p->paramType = P_TK02BRANCHRATES;
+ p->nValues = 2*numLocalTaxa; /* use to hold the branch rates; we need one rate for the root */
+ p->nSubValues = 2*numLocalTaxa; /* use to hold the effective branch lengths */
+ p->min = RATE_MIN;
+ p->max = RATE_MAX;
+ for (i=0; i<numCurrentDivisions; i++)
+ if (isPartTouched[i] == YES)
+ modelSettings[i].tk02BranchRates = p;
+
+ p->paramTypeName = "Branch rates of TK02 relaxed clock";
+ SafeStrcat(&p->name, "TK02Brlens");
+ SafeStrcat(&p->name, partString);
+
+ /* find the parameter x prior type */
+ p->paramId = TK02BRANCHRATES;
+
+ /* should we print values to .p file? */
+ p->printParam = NO;
+
+ SafeStrcat (&p->paramHeader, "tk02_brlens");
+ SafeStrcat (&p->paramHeader, partString);
+ }
+ else if (j == P_IGRVAR)
+ {
+ /* Set up igr relaxed clock variance parameter *****************************************************************************************/
+ p->paramType = P_IGRVAR;
+ p->nValues = 1;
+ p->nSubValues = 0;
+ p->min = 1E-6;
+ p->max = POS_INFINITY;
+ for (i=0; i<numCurrentDivisions; i++)
+ if (isPartTouched[i] == YES)
+ modelSettings[i].igrvar = p;
+
+ p->paramTypeName = "Variance increase of igr model branch lenths";
+ SafeStrcat(&p->name, "Igrvar");
+ SafeStrcat(&p->name, partString);
+
+ /* find the parameter x prior type */
+ if (!strcmp(mp->igrvarPr,"Uniform"))
+ p->paramId = IGRVAR_UNI;
+ else if (!strcmp(mp->igrvarPr,"Exponential"))
+ p->paramId = IGRVAR_EXP;
+ else
+ p->paramId = IGRVAR_FIX;
+
+ if (p->paramId != IGRVAR_FIX)
+ p->printParam = YES;
+ SafeStrcat (&p->paramHeader, "igrvar");
+ SafeStrcat (&p->paramHeader, partString);
+ }
+ else if (j == P_IGRBRANCHRATES)
+ {
+ /* Set up igr relaxed clock rates parameter *****************************************************************************************/
+ p->paramType = P_IGRBRANCHRATES;
+ p->nValues = 2*numLocalTaxa; /* use to hold the branch rates; we need one rate for the root */
+ p->nSubValues = 2*numLocalTaxa; /* use to hold the effective branch lengths */
+ p->min = RATE_MIN;
+ p->max = RATE_MAX;
+ for (i=0; i<numCurrentDivisions; i++)
+ if (isPartTouched[i] == YES)
+ modelSettings[i].igrBranchRates = p;
+
+ p->paramTypeName = "Branch lengths of IGR relaxed clock";
+ SafeStrcat(&p->name, "IgrBrlens");
+ SafeStrcat(&p->name, partString);
+
+ /* find the parameter x prior type */
+ p->paramId = IGRBRANCHRATES;
+
+ /* should we print values to .p file? */
+ p->printParam = NO;
+
+ SafeStrcat (&p->paramHeader, "igr_brlens");
+ SafeStrcat (&p->paramHeader, partString);
+ }
+ else if (j == P_MIXEDVAR)
+ {
+ /* Set up mixed relaxed clock variance parameter *****************************************************************************************/
+ p->paramType = P_MIXEDVAR;
+ p->nValues = 1;
+ p->nSubValues = 0;
+ p->min = 1E-6;
+ p->max = POS_INFINITY;
+ for (i=0; i<numCurrentDivisions; i++)
+ if (isPartTouched[i] == YES)
+ modelSettings[i].mixedvar = p;
+
+ p->paramTypeName = "Variance shared for mixed relaxed clock moodel";
+ SafeStrcat(&p->name, "Mixedvar");
+ SafeStrcat(&p->name, partString);
+
+ /* find the parameter x prior type */
+ if (!strcmp(mp->mixedvarPr,"Uniform"))
+ p->paramId = MIXEDVAR_UNI;
+ else if (!strcmp(mp->mixedvarPr,"Exponential"))
+ p->paramId = MIXEDVAR_EXP;
+ else
+ p->paramId = MIXEDVAR_FIX;
+
+ if (p->paramId != MIXEDVAR_FIX)
+ p->printParam = YES;
+ SafeStrcat (&p->paramHeader, "mixedvar");
+ SafeStrcat (&p->paramHeader, partString);
+ }
+ else if (j == P_MIXEDBRCHRATES)
+ {
+ /* Set up mixed relaxed clock rates parameter *****************************************************************************************/
+ p->paramType = P_MIXEDBRCHRATES;
+ p->nValues = 2*numLocalTaxa; /* use to hold the branch rates; we need one rate for the root */
+ p->nSubValues = 2*numLocalTaxa; /* use to hold the effective branch lengths */
+ p->nIntValues = 1; /* use to hold the model indicator: TK02 or IGR */
+ p->min = RATE_MIN;
+ p->max = RATE_MAX;
+ for (i=0; i<numCurrentDivisions; i++)
+ if (isPartTouched[i] == YES)
+ modelSettings[i].mixedBrchRates = p;
+
+ p->paramTypeName = "Branch rates of mixed relaxed clock";
+ SafeStrcat(&p->name, "MixedBrlens");
+ SafeStrcat(&p->name, partString);
+
+ /* find the parameter x prior type */
+ p->paramId = MIXEDBRCHRATES;
+
+ /* how to print model indicator (0 or 1) to .p file? */
+ p->printParam = NO;
+
+ SafeStrcat (&p->paramHeader, "mixed_brlens");
+ SafeStrcat (&p->paramHeader, partString);
+ }
+ else if (j == P_CLOCKRATE)
+ {
+ /* Set up clockRate ****************************************************************************************/
+ p->paramType = P_CLOCKRATE;
+ p->nValues = 1;
+ p->nSubValues = 0;
+ p->min = POS_MIN;
+ p->max = POS_INFINITY;
+ for (i=0; i<numCurrentDivisions; i++)
+ if (isPartTouched[i] == YES)
+ modelSettings[i].clockRate = p;
+
+ p->paramTypeName = "Base rate of clock";
+ SafeStrcat(&p->name, "Clockrate");
+ SafeStrcat(&p->name, partString);
+
+ /* parameter does affect likelihoods */
+ p->affectsLikelihood = YES;
+
+ /* find the parameter x prior type */
+ if (!strcmp(mp->clockRatePr,"Normal"))
+ {
+ p->paramId = CLOCKRATE_NORMAL;
+ p->LnPriorRatio = &LnProbRatioTruncatedNormal;
+ p->priorParams = mp->clockRateNormal;
+ p->LnPriorProb = &LnPriorProbTruncatedNormal;
+ }
+ else if (!strcmp(mp->clockRatePr,"Lognormal"))
+ {
+ p->paramId = CLOCKRATE_LOGNORMAL;
+ p->LnPriorRatio = &LnProbRatioLognormal;
+ p->priorParams = mp->clockRateLognormal;
+ p->LnPriorProb = &LnPriorProbLognormal;
+ }
+ else if (!strcmp(mp->clockRatePr,"Exponential"))
+ {
+ p->paramId = CLOCKRATE_EXP;
+ p->LnPriorRatio = &LnProbRatioExponential;
+ p->priorParams = &mp->clockRateExp;
+ p->LnPriorProb = &LnPriorProbExponential;
+ }
+ else if (!strcmp(mp->clockRatePr,"Gamma"))
+ {
+ p->paramId = CLOCKRATE_GAMMA;
+ p->LnPriorRatio = &LnProbRatioGamma;
+ p->priorParams = mp->clockRateGamma;
+ p->LnPriorProb = &LnPriorProbGamma;
+ }
+ else
+ {
+ p->paramId = CLOCKRATE_FIX;
+ p->LnPriorRatio = NULL;
+ p->priorParams = &mp->clockRateFix;
+ p->LnPriorProb = &LnPriorProbFix;
+ }
+
+ SafeStrcat (&p->paramHeader, "clockrate");
+ SafeStrcat (&p->paramHeader, partString);
+ if (p->paramId != CLOCKRATE_FIX)
+ p->printParam = YES;
+ }
+ }
+ free (tempStr);
+ free (isPartTouched);
+ SafeFree ((void **)&partString);
+
+ return (NO_ERROR);
+}
+
+
+/*----------------------------------------------------------------------------
+|
+| SetMoves: This function will set up the applicable moves that could
+| potentially be used in updating the model parameters
+|
+-----------------------------------------------------------------------------*/
+int SetMoves (void)
+{
+ int i, j, k, moveIndex;
+ Param *param;
+
+ /* free up previous moves if any */
+ if (memAllocs[ALLOC_MOVES] == YES)
+ {
+ for (i=0; i<numApplicableMoves; i++)
+ FreeMove (moves[i]);
+ free (moves);
+ moves = NULL;
+ memAllocs[ALLOC_MOVES] = NO;
+ }
+
+ /* set up applicable moves */
+ /* each combination of moveType and param is a separate move */
+
+ /* first count applicable moves */
+ numApplicableMoves = 0;
+ for (k=0; k<numParams; k++)
+ {
+ param = ¶ms[k];
+ for (i=0; i<NUM_MOVE_TYPES; i++)
+ {
+ if (moveTypes[i].level > userLevel)
+ continue;
+ if (moveTypes[i].isApplicable(param) == NO)
+ continue;
+ for (j=0; j<moveTypes[i].nApplicable; j++)
+ if (moveTypes[i].applicableTo[j] == param->paramId)
+ {
+ numApplicableMoves++;
+ break;
+ }
+ }
+ }
+
+ /* then allocate space for move pointers */
+ moves = (MCMCMove **) SafeMalloc (numApplicableMoves * sizeof (MCMCMove *));
+ if (!moves)
+ {
+ MrBayesPrint ("%s Problem allocating moves\n", spacer);
+ return (ERROR);
+ }
+ memAllocs[ALLOC_MOVES] = YES;
+
+ /* finally allocate space for and set move defaults */
+ moveIndex = 0;
+ for (k=0; k<numParams; k++)
+ {
+ param = ¶ms[k];
+ for (i=0; i<NUM_MOVE_TYPES; i++)
+ {
+ if (moveTypes[i].level > userLevel)
+ continue;
+ if (moveTypes[i].isApplicable(param) == NO)
+ continue;
+ for (j=0; j<moveTypes[i].nApplicable; j++)
+ {
+ if (moveTypes[i].applicableTo[j] == param->paramId)
+ {
+ if ((moves[moveIndex] = AllocateMove (&moveTypes[i], param)) == NULL)
+ break;
+ else
+ {
+ moves[moveIndex]->parm = param;
+ moveIndex++;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (moveIndex < numApplicableMoves)
+ {
+ for (i=0; i<moveIndex; i++)
+ FreeMove (moves[i]);
+ free (moves);
+ memAllocs[ALLOC_MOVES] = NO;
+ MrBayesPrint ("%s Problem setting moves\n", spacer);
+ return (ERROR);
+ }
+
+ return (NO_ERROR);
+}
+
+
+/** SetPopSizeParam: Set population size values for a species tree from an input tree */
+int SetPopSizeParam (Param *param, int chn, int state, PolyTree *pt)
+{
+ int i, j, k, nLongsNeeded;
+ MrBFlt *values;
+ Tree *speciesTree;
+ PolyNode *pp;
+ TreeNode *p=NULL;
+
+ nLongsNeeded = 1 + (pt->nNodes - pt->nIntNodes - 1) / nBitsInALong;
+
+ /* Get pointer to values to be set */
+ values = GetParamVals (param, chn, state);
+
+ /* Get species tree */
+ speciesTree = GetTree (modelSettings[param->relParts[0]].speciesTree, chn, state);
+
+ /* Set them based on index of matching partitions */
+ AllocatePolyTreePartitions(pt);
+ AllocateTreePartitions(speciesTree);
+ for (i=0; i<pt->nNodes; i++)
+ {
+ pp = pt->allDownPass[i];
+ for (j=0; j<speciesTree->nNodes-1; j++)
+ {
+ p = speciesTree->allDownPass[j];
+ for (k=0; k<nLongsNeeded; k++)
+ {
+ if (pp->partition[k] != p->partition[k])
+ break;
+ }
+ if (k == nLongsNeeded)
+ break;
+ }
+ if (j == speciesTree->nNodes - 1)
+ {
+ MrBayesPrint ("%s Non-matching partitions when setting population size parameter", spacer);
+ FreePolyTreePartitions(pt);
+ FreeTreePartitions(speciesTree);
+ return (ERROR);
+ }
+ values[p->index] = pt->popSize[pp->index];
+ }
+
+ FreePolyTreePartitions(pt);
+ FreeTreePartitions(speciesTree);
+
+ return (NO_ERROR);
+}
+
+
+/* SetRelaxedClockParam: set values for a relaxed clock param from an input tree */
+int SetRelaxedClockParam (Param *param, int chn, int state, PolyTree *pt)
+{
+ int i, j, k, *nEvents=NULL, *nEventsP=NULL, nLongsNeeded, isEventSet;
+ MrBFlt *effectiveBranchLengthP=NULL, *branchRate=NULL,
+ **position=NULL, **rateMult=NULL, **positionP=NULL, **rateMultP=NULL,
+ baseRate;
+ Tree *t;
+ PolyNode *pp;
+ TreeNode *p=NULL, *q;
+
+ nLongsNeeded = 1 + (numLocalTaxa - 1) / nBitsInALong;
+
+ /* set pointers to the right set of values */
+ isEventSet = NO;
+ if (param->paramType == P_CPPEVENTS)
+ {
+ /* find the right event set */
+ for (i=0; i<pt->nESets; i++)
+ {
+ if (!strcmp(param->name,pt->eSetName[i]))
+ break;
+ }
+ if (i == pt->nESets)
+ {
+ for (i=0; i<pt->nBSets; i++)
+ if (!strcmp(param->name,pt->bSetName[i]))
+ break;
+
+ if (i == pt->nBSets)
+ return (NO_ERROR);
+ else
+ isEventSet = NO;
+ }
+ else
+ isEventSet = YES;
+
+ if (isEventSet == YES)
+ {
+ nEventsP = pt->nEvents[i];
+ positionP = pt->position[i];
+ rateMultP = pt->rateMult[i];
+ }
+ else
+ effectiveBranchLengthP = pt->effectiveBrLen[i];
+
+ nEvents = param->nEvents[2*chn+state];
+ position = param->position[2*chn+state];
+ rateMult = param->rateMult[2*chn+state];
+ }
+ else if (param->paramType == P_TK02BRANCHRATES || param->paramType == P_IGRBRANCHRATES || param->paramType == P_MIXEDBRCHRATES)
+ {
+ /* find the right effective branch length set */
+ for (i=0; i<pt->nBSets; i++)
+ if (!strcmp(param->name,pt->bSetName[i]))
+ break;
+ if (i == pt->nBSets)
+ return (NO_ERROR);
+
+ effectiveBranchLengthP = pt->effectiveBrLen[i];
+ branchRate = GetParamVals (param, chn, state);
+ }
+
+ t = GetTree (param, chn, state);
+ AllocatePolyTreePartitions (pt);
+ AllocateTreePartitions (t);
+
+ for (i=pt->nNodes-1; i>=0; i--)
+ {
+ pp = pt->allDownPass[i];
+ for (j=0; j<t->nNodes; j++)
+ {
+ p = t->allDownPass[j];
+ for (k=0; k<nLongsNeeded; k++)
+ if (p->partition[k] != pp->partition[k])
+ break;
+ if (k == nLongsNeeded)
+ break; /* match */
+ }
+ if (param->paramType == P_CPPEVENTS)
+ {
+ if (isEventSet == NO)
+ {
+ if (nEvents[p->index] != 1)
+ {
+ position[p->index] = (MrBFlt *) SafeRealloc ((void *) position[p->index], 1*sizeof(MrBFlt));
+ rateMult[p->index] = (MrBFlt *) SafeRealloc ((void *) rateMult[p->index], 1*sizeof(MrBFlt));
+ nEvents [p->index] = 1;
+ }
+ position[p->index][0] = 0.5;
+ if (p->anc->anc == NULL)
+ rateMult[p->index][0] = 1.0;
+ else
+ {
+ baseRate = 1.0;
+ q = p->anc;
+ while (q->anc != NULL)
+ {
+ baseRate *= rateMult[q->index][0];
+ q = q->anc;
+ }
+ rateMult[p->index][0] = 2.0 * effectiveBranchLengthP[pp->index] / (p->length * baseRate) - 1.0;
+ }
+ }
+ else
+ {
+ if (nEvents[p->index] != nEventsP[pp->index])
+ {
+ if (nEventsP[pp->index] == 0)
+ {
+ free (position[p->index]);
+ free (rateMult[p->index]);
+ }
+ else
+ {
+ position[p->index] = (MrBFlt *) SafeRealloc ((void *) position[p->index], nEventsP[pp->index]*sizeof(MrBFlt));
+ rateMult[p->index] = (MrBFlt *) SafeRealloc ((void *) rateMult[p->index], nEventsP[pp->index]*sizeof(MrBFlt));
+ }
+ nEvents[p->index] = nEventsP[pp->index];
+ }
+ for (j=0; j<nEventsP[pp->index]; j++)
+ {
+ position[p->index][j] = positionP[pp->index][j];
+ rateMult[p->index][j] = rateMultP[pp->index][j];
+ }
+ }
+ }
+ else if (param->paramType == P_TK02BRANCHRATES ||
+ (param->paramType == P_MIXEDBRCHRATES && *GetParamIntVals(param, chn, state) == RCL_TK02))
+ {
+ if (p->anc->anc == NULL)
+ branchRate[p->index] = 1.0;
+ else if (p->length > 0.0)
+ branchRate[p->index] = 2.0 * effectiveBranchLengthP[pp->index] / p->length - branchRate[p->anc->index];
+ else
+ branchRate[p->index] = branchRate[p->anc->index];
+ }
+ else if (param->paramType == P_IGRBRANCHRATES ||
+ (param->paramType == P_MIXEDBRCHRATES && *GetParamIntVals(param, chn, state) == RCL_IGR))
+ {
+ if (p->length > 0.0)
+ branchRate[p->index] = effectiveBranchLengthP[pp->index] / p->length;
+ else
+ branchRate[p->index] = branchRate[p->anc->index];
+ } // we are now reading effective branch length for TK02 and IGR
+ }
+
+ if (param->paramType == P_CPPEVENTS)
+ {
+ if (UpdateCppEvolLengths (param, t->root->left, chn) == ERROR)
+ return (ERROR);
+ }
+ else if (param->paramType == P_TK02BRANCHRATES ||
+ (param->paramType == P_MIXEDBRCHRATES && *GetParamIntVals(param, chn, state) == RCL_TK02))
+ {
+ if (UpdateTK02EvolLengths (param, t, chn) == ERROR)
+ return (ERROR);
+ }
+ else if (param->paramType == P_IGRBRANCHRATES ||
+ (param->paramType == P_MIXEDBRCHRATES && *GetParamIntVals(param, chn, state) == RCL_IGR))
+ {
+ if (UpdateIgrBrachLengths (param, t, chn) == ERROR)
+ return (ERROR);
+ }
+
+ FreePolyTreePartitions (pt);
+ FreeTreePartitions (t);
+
+ return (NO_ERROR);
+}
+
+
+/*------------------------------------------------------------------------
+|
+| SetUpAnalysis: Set parameters and moves
+|
+------------------------------------------------------------------------*/
+int SetUpAnalysis (RandLong *seed)
+{
+ setUpAnalysisSuccess=NO;
+
+ /* calculate number of characters and taxa */
+ numLocalChar = NumNonExcludedChar ();
+
+ /* we are checking later to make sure no partition is without characters */
+ SetLocalTaxa ();
+ if (numLocalTaxa <= 2)
+ {
+ MrBayesPrint ("%s There must be at least two included taxa, now there is %s\n", spacer,
+ numLocalTaxa == 0 ? "none" : "only one");
+ return (ERROR);
+ }
+
+ /* calculate number of global chains */
+ numGlobalChains = chainParams.numRuns * chainParams.numChains;
+
+ /* Set up link table */
+ if (SetUpLinkTable () == ERROR)
+ return (ERROR);
+
+ /* Check that the settings for doublet or codon models are correct. */
+ if (CheckExpandedModels() == ERROR)
+ return (ERROR);
+
+ /* Set up model info */
+ if (SetModelInfo() == ERROR)
+ return (ERROR);
+
+ /* Calculate number of (uncompressed) characters for each division */
+ if (GetNumDivisionChars() == ERROR)
+ return (ERROR);
+
+ /* Compress data and calculate some things needed for setting up params. */
+ if (CompressData() == ERROR)
+ return (ERROR);
+
+ /* Add dummy characters, if needed. */
+ if (AddDummyChars() == ERROR)
+ return (ERROR);
+
+ /* Set up parameters for the chain. */
+ if (SetModelParams () == ERROR)
+ return (ERROR);
+
+ /* Allocate normal params */
+ if (AllocateNormalParams () == ERROR)
+ return (ERROR);
+
+ /* Allocate tree params */
+ if (AllocateTreeParams () == ERROR)
+ return (ERROR);
+
+ /* Set default number of trees for sumt to appropriate number */
+ sumtParams.numTrees = numTrees;
+
+ /* Fill in normal parameters */
+ if (FillNormalParams (seed, 0, numGlobalChains) == ERROR)
+ return (ERROR);
+
+ /* Process standard characters (calculates bsIndex, tiIndex, and more). */
+ if (ProcessStdChars(seed) == ERROR)
+ return (ERROR);
+
+ /* Fill in trees */
+ if (FillTreeParams (seed, 0, numGlobalChains) == ERROR)
+ return (ERROR);
+
+ /* Set the applicable moves that could be used by the chain. */
+ if (SetMoves () == ERROR)
+ return (ERROR);
+
+ setUpAnalysisSuccess=YES;
+
+ return (NO_ERROR);
+}
+
+
+int SetUpLinkTable (void)
+{
+ int i, j, k, m, paramCount, isApplicable1, isApplicable2,
+ isFirst, isSame;
+ int *check, *modelId;
+
+ check = (int *) SafeMalloc (2 * (size_t)numCurrentDivisions * sizeof (int));
+ if (!check)
+ {
+ MrBayesPrint ("%s Problem allocating check (%d)\n", spacer, 2 * numCurrentDivisions * sizeof(int));
+ return (ERROR);
+ }
+ modelId = check + numCurrentDivisions;
+
+ for (j=0; j<NUM_LINKED; j++)
+ for (i=0; i<numCurrentDivisions; i++)
+ activeParams[j][i] = 0;
+
+ if (numCurrentDivisions > 1)
+ {
+ paramCount = 0;
+ for (j=0; j<NUM_LINKED; j++) /* loop over parameters */
+ {
+ isFirst = YES;
+ for (i=0; i<numCurrentDivisions; i++)
+ modelId[i] = 0;
+ for (i=0; i<numCurrentDivisions-1; i++) /* loop over partitions */
+ {
+ for (k=i+1; k<numCurrentDivisions; k++)
+ {
+ if (IsModelSame (j, i, k, &isApplicable1, &isApplicable2) == NO || linkTable[j][i] != linkTable[j][k])
+ {
+ /* we cannot link the parameters */
+ if (isApplicable1 == NO)
+ modelId[i] = -1;
+ if (isApplicable2 == NO)
+ modelId[k] = -1;
+ if (isApplicable1 == YES)
+ {
+ if (isFirst == YES && modelId[i] == 0)
+ {
+ modelId[i] = ++paramCount;
+ isFirst = NO;
+ }
+ else
+ {
+ if (modelId[i] == 0)
+ modelId[i] = ++paramCount;
+ }
+ }
+ if (modelId[k] == 0 && isApplicable2 == YES)
+ modelId[k] = ++paramCount;
+ }
+ else
+ {
+ /* we can link the parameters */
+ if (isFirst == YES)
+ {
+ if (modelId[i] == 0)
+ modelId[i] = ++paramCount;
+ isFirst = NO;
+ }
+ else
+ {
+ if (modelId[i] == 0)
+ modelId[i] = ++paramCount;
+ }
+ modelId[k] = modelId[i];
+ }
+ }
+ }
+ for (i=0; i<numCurrentDivisions; i++)
+ activeParams[j][i] = modelId[i];
+ }
+ }
+ else
+ {
+ /* if we have only one partition, then we do things a bit differently */
+ paramCount = 0;
+ for (j=0; j<NUM_LINKED; j++) /* loop over parameters */
+ {
+ IsModelSame (j, 0, 0, &isApplicable1, &isApplicable2);
+ if (isApplicable1 == YES)
+ activeParams[j][0] = ++paramCount;
+ else
+ activeParams[j][0] = -1;
+ }
+ }
+
+ /* Check that the same report format is specified for all partitions with the same rate multiplier */
+ for (i=0; i<numCurrentDivisions; i++)
+ check[i] = NO;
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ m = activeParams[P_RATEMULT][i];
+ if (m == -1 || check[i] == YES)
+ continue;
+ isSame = YES;
+ for (j=i+1; j<numCurrentDivisions; j++)
+ {
+ if (activeParams[P_RATEMULT][j] == m)
+ {
+ check[i] = YES;
+ if (strcmp(modelParams[i].ratemultFormat,modelParams[j].ratemultFormat)!= 0)
+ {
+ isSame = NO;
+ strcpy (modelParams[j].ratemultFormat, modelParams[i].ratemultFormat);
+ }
+ }
+ }
+ if (isSame == NO)
+ {
+ MrBayesPrint ("%s WARNING: Report format for ratemult (parameter %d) varies across partitions.\n", spacer);
+ MrBayesPrint ("%s MrBayes will use the format for the first partition, which is %s.\n", spacer, modelParams[i].ratemultFormat);
+ }
+ }
+
+ /* probably a good idea to clean up link table here */
+ paramCount = 0;
+ for (j=0; j<NUM_LINKED; j++)
+ {
+ for (i=0; i<numCurrentDivisions; i++)
+ check[i] = NO;
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (check[i] == NO && activeParams[j][i] > 0)
+ {
+ m = activeParams[j][i];
+ paramCount++;
+ for (k=i; k<numCurrentDivisions; k++)
+ {
+ if (check[k] == NO && activeParams[j][k] == m)
+ {
+ activeParams[j][k] = paramCount;
+ check[k] = YES;
+ }
+ }
+ }
+ }
+ }
+
+ free (check);
+
+ return (NO_ERROR);
+}
+
+
+/*------------------------------------------------------------------------
+|
+| SetUpMoveTypes: Set up structs holding info on each move type
+|
+------------------------------------------------------------------------*/
+void SetUpMoveTypes (void)
+{
+ /* Register the move type here when new move functions are added
+ Remember to check that the number of move types does not exceed NUM_MOVE_TYPES
+ defined in bayes.h. */
+ int i;
+ MoveType *mt;
+
+ /* reset move types */
+ for (i=0; i<NUM_MOVE_TYPES; i++)
+ {
+ mt = &moveTypes[i];
+ mt->level = DEVELOPER;
+ mt->numTuningParams = 0;
+ mt->minimum[0] = mt->minimum[1] = -1000000000.0;
+ mt->maximum[0] = mt->maximum[1] = 1000000000.0;
+ mt->tuningParam[0] = mt->tuningParam[1] = 0.0;
+ mt->nApplicable = 0;
+ mt->name = mt->tuningName[0] = mt->tuningName[1] = "";
+ mt->paramName = "";
+ mt->subParams = NO;
+ mt->relProposalProb = 0.0;
+ mt->parsimonyBased = NO;
+ mt->isApplicable = &IsApplicable;
+ mt->Autotune = NULL;
+ mt->targetRate = -1.0;
+ }
+
+ /* Moves are in alphabetic order after parameter name, which matches the name of a move function if
+ there is a separate move function for the parameter. See proposal.h for declaration of move functions.
+ Since 2010-10-04, some parameters use generalized move functions and do not have their own. */
+
+ i = 0;
+
+ /* Move_Aamodel */
+ mt = &moveTypes[i++];
+ mt->name = "Uniform random pick";
+ mt->shortName = "Uniform";
+ mt->applicableTo[0] = AAMODEL_MIX;
+ mt->nApplicable = 1;
+ mt->moveFxn = &Move_Aamodel;
+ mt->relProposalProb = 1.0;
+ mt->numTuningParams = 0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+
+ /* Move_Adgamma */
+ mt = &moveTypes[i++];
+ mt->name = "Sliding window";
+ mt->shortName = "Slider";
+ mt->tuningName[0] = "Sliding window size";
+ mt->shortTuningName[0] = "delta";
+ mt->applicableTo[0] = CORREL_UNI;
+ mt->nApplicable = 1;
+ mt->moveFxn = &Move_Adgamma;
+ mt->relProposalProb = 1.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 0.5; /* window size */
+ mt->minimum[0] = 0.001;
+ mt->maximum[0] = 1.999;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneSlider;
+ mt->targetRate = 0.25;
+
+ /* Move_Beta */
+ mt = &moveTypes[i++];
+ mt->name = "Multiplier";
+ mt->shortName = "Multiplier";
+ mt->tuningName[0] = "Multiplier tuning parameter";
+ mt->shortTuningName[0] = "lambda";
+ mt->applicableTo[0] = SYMPI_UNI;
+ mt->applicableTo[1] = SYMPI_EXP;
+ mt->applicableTo[2] = SYMPI_UNI_MS;
+ mt->applicableTo[3] = SYMPI_EXP_MS;
+ mt->nApplicable = 4;
+ mt->moveFxn = &Move_Beta;
+ mt->relProposalProb = 1.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 2.0 * log (1.5); /* so-called lambda */
+ mt->minimum[0] = 0.0001;
+ mt->maximum[0] = 20.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneMultiplier;
+ mt->targetRate = 0.25;
+
+ /* Move_BrLen */
+ mt = &moveTypes[i++];
+ mt->name = "Random brlen hit with multiplier";
+ mt->shortName = "Multiplier";
+ mt->tuningName[0] = "Multiplier tuning parameter";
+ mt->shortTuningName[0] = "lambda";
+ mt->applicableTo[0] = BRLENS_UNI;
+ mt->applicableTo[1] = BRLENS_EXP;
+ mt->applicableTo[2] = BRLENS_GamDir;
+ mt->applicableTo[3] = BRLENS_iGmDir;
+ mt->applicableTo[4] = BRLENS_twoExp;
+ mt->nApplicable = 5; // was 2
+ mt->moveFxn = &Move_BrLen;
+ mt->relProposalProb = 20.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 2.0 * log (2.0); /* lambda */
+ mt->minimum[0] = 0.0001;
+ mt->maximum[0] = 20.0; /* change it smaller to avoid overflow in the exp function, same for following "smaller" */
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneMultiplier;
+ mt->targetRate = 0.25;
+
+ /* Move_ClockRate_M */
+ mt = &moveTypes[i++];
+ mt->name = "Multiplier";
+ mt->shortName = "Multiplier";
+ mt->tuningName[0] = "Multiplier tuning parameter";
+ mt->shortTuningName[0] = "lambda";
+ mt->applicableTo[0] = CLOCKRATE_NORMAL;
+ mt->applicableTo[1] = CLOCKRATE_LOGNORMAL;
+ mt->applicableTo[2] = CLOCKRATE_GAMMA;
+ mt->applicableTo[3] = CLOCKRATE_EXP;
+ mt->nApplicable = 4;
+ mt->moveFxn = &Move_ClockRate_M;
+ mt->relProposalProb = 2.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 2.0 * log (1.5); /* lambda */
+ mt->minimum[0] = 0.0001;
+ mt->maximum[0] = 20.0; /* smaller */
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneMultiplier;
+ mt->targetRate = 0.25;
+
+ /* Move_Extinction */
+ mt = &moveTypes[i++];
+ mt->name = "Sliding window";
+ mt->shortName = "Slider";
+ mt->tuningName[0] = "Sliding window size";
+ mt->shortTuningName[0] = "delta";
+ mt->applicableTo[0] = EXTRATE_BETA;
+ mt->nApplicable = 1;
+ mt->moveFxn = &Move_Extinction;
+ mt->relProposalProb = 3.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 0.1; /* window size */
+ mt->minimum[0] = 0.00001;
+ mt->maximum[0] = 20.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneSlider;
+ mt->targetRate = 0.25;
+
+ /* Move_Fossilization */
+ mt = &moveTypes[i++];
+ mt->name = "Sliding window";
+ mt->shortName = "Slider";
+ mt->tuningName[0] = "Sliding window size";
+ mt->shortTuningName[0] = "delta";
+ mt->applicableTo[0] = FOSLRATE_BETA;
+ mt->nApplicable = 1;
+ mt->moveFxn = &Move_Fossilization;
+ mt->relProposalProb = 3.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 0.1; /* window size */
+ mt->minimum[0] = 0.00001;
+ mt->maximum[0] = 20.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneSlider;
+ mt->targetRate = 0.25;
+
+ /* Move_AddBranch, for fossilization prior */
+ mt = &moveTypes[i++];
+ mt->name = "Add branch for FossilizedBD";
+ mt->shortName = "AddBranch";
+ // mt->subParams = YES;
+ mt->applicableTo[0] = BRLENS_CLOCK_FOSSIL;
+ mt->nApplicable = 1;
+ mt->moveFxn = &Move_AddBranch;
+ mt->relProposalProb = 10.0;
+ mt->numTuningParams = 0;
+ mt->parsimonyBased = NO;
+ mt->level =STANDARD_USER;
+ mt->isApplicable = &IsApplicable_AncestralFossil;
+
+ /* Move_DelBranch, for fossilization prior */
+ mt = &moveTypes[i++];
+ mt->name = "Delete branch for FossilizedBD";
+ mt->shortName = "DelBranch";
+ // mt->subParams = YES;
+ mt->applicableTo[0] = BRLENS_CLOCK_FOSSIL;
+ mt->nApplicable = 1;
+ mt->moveFxn = &Move_DelBranch;
+ mt->relProposalProb = 10.0;
+ mt->numTuningParams = 0;
+ mt->parsimonyBased = NO;
+ mt->level =STANDARD_USER;
+ mt->isApplicable = &IsApplicable_AncestralFossil;
+
+ /* Move_ExtSPR */
+ mt = &moveTypes[i++];
+ mt->name = "Extending SPR";
+ mt->shortName = "ExtSPR";
+ mt->subParams = YES;
+ mt->tuningName[0] = "Extension probability";
+ mt->shortTuningName[0] = "p_ext";
+ mt->tuningName[1] = "Multiplier tuning parameter";
+ mt->shortTuningName[1] = "lambda";
+ mt->applicableTo[0] = TOPOLOGY_NCL_UNIFORM_HOMO;
+ mt->applicableTo[1] = TOPOLOGY_NCL_CONSTRAINED_HOMO;
+ mt->nApplicable = 2;
+ mt->moveFxn = &Move_ExtSPR;
+ mt->relProposalProb = 5.0;
+ mt->numTuningParams = 2;
+ mt->tuningParam[0] = 0.5; /* extension probability */
+ mt->tuningParam[1] = 2.0 * log (1.05); /* lambda */
+ mt->minimum[0] = 0.00001;
+ mt->maximum[0] = 0.99999;
+ mt->minimum[1] = 0.00001;
+ mt->maximum[1] = 100.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->isApplicable = &IsApplicable_FourTaxaOrMore;
+
+ /* Move_ExtSPR1 */
+ mt = &moveTypes[i++];
+ mt->name = "Extending SPR variant 1";
+ mt->shortName = "ExtSPR1";
+ mt->subParams = YES;
+ mt->tuningName[0] = "Extension probability";
+ mt->shortTuningName[0] = "p_ext";
+ mt->tuningName[1] = "Multiplier tuning parameter";
+ mt->shortTuningName[1] = "lambda";
+ mt->applicableTo[0] = TOPOLOGY_NCL_UNIFORM_HOMO;
+ mt->applicableTo[1] = TOPOLOGY_NCL_CONSTRAINED_HOMO;
+ mt->nApplicable = 2;
+ mt->moveFxn = &Move_ExtSPR1;
+ mt->relProposalProb = 0.0;
+ mt->numTuningParams = 2;
+ mt->tuningParam[0] = 0.5; /* extension probability */
+ mt->tuningParam[1] = 2.0 * log (1.05); /* lambda */
+ mt->minimum[0] = 0.00001;
+ mt->maximum[0] = 0.99999;
+ mt->minimum[1] = 0.00001;
+ mt->maximum[1] = 100.0;
+ mt->parsimonyBased = NO;
+ mt->level = DEVELOPER;
+ mt->isApplicable = &IsApplicable_FiveTaxaOrMore;
+
+ /* Move_ExtSPRClock */
+ mt = &moveTypes[i++];
+ mt->name = "Extending SPR for clock trees";
+ mt->shortName = "ExtSprClock";
+ mt->subParams = YES;
+ mt->tuningName[0] = "Extension probability";
+ mt->shortTuningName[0] = "p_ext";
+ mt->applicableTo[0] = TOPOLOGY_CL_UNIFORM;
+ mt->applicableTo[1] = TOPOLOGY_CCL_UNIFORM;
+ mt->applicableTo[2] = TOPOLOGY_CL_CONSTRAINED;
+ mt->applicableTo[3] = TOPOLOGY_CCL_CONSTRAINED;
+ mt->applicableTo[4] = TOPOLOGY_RCL_UNIFORM;
+ mt->applicableTo[5] = TOPOLOGY_RCL_CONSTRAINED;
+ mt->applicableTo[6] = TOPOLOGY_RCCL_UNIFORM;
+ mt->applicableTo[7] = TOPOLOGY_RCCL_CONSTRAINED;
+ mt->nApplicable = 8;
+ mt->moveFxn = &Move_ExtSPRClock;
+ mt->relProposalProb = 10.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 0.5; /* extension probability */
+ mt->minimum[0] = 0.00001;
+ mt->maximum[0] = 0.99999;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->isApplicable = &IsApplicable_ThreeTaxaOrMore;
+
+ /* Move_ExtSS */
+ mt = &moveTypes[i++];
+ mt->name = "Extending subtree swapper";
+ mt->shortName = "ExtSS";
+ mt->subParams = YES;
+ mt->tuningName[0] = "Extension probability";
+ mt->shortTuningName[0] = "p_ext";
+ mt->tuningName[1] = "Multiplier tuning parameter";
+ mt->shortTuningName[1] = "lambda";
+ mt->applicableTo[0] = TOPOLOGY_NCL_UNIFORM_HOMO;
+ mt->applicableTo[1] = TOPOLOGY_NCL_CONSTRAINED_HOMO;
+ mt->nApplicable = 2;
+ mt->moveFxn = &Move_ExtSS;
+ mt->relProposalProb = 0.0;
+ mt->numTuningParams = 2;
+ mt->tuningParam[0] = 0.5; /* extension probability */
+ mt->tuningParam[1] = 2.0 * log (1.05); /* lambda */
+ mt->minimum[0] = 0.00001;
+ mt->maximum[0] = 0.99999;
+ mt->minimum[1] = 0.00001;
+ mt->maximum[1] = 100.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->isApplicable = &IsApplicable_FourTaxaOrMore;
+
+ /* Move_ExtSSClock */
+ mt = &moveTypes[i++];
+ mt->name = "Extending subtree swapper";
+ mt->shortName = "ExtSsClock";
+ mt->subParams = YES;
+ mt->tuningName[0] = "Extension probability";
+ mt->shortTuningName[0] = "p_ext";
+ mt->applicableTo[0] = TOPOLOGY_CL_UNIFORM;
+ mt->applicableTo[1] = TOPOLOGY_CCL_UNIFORM;
+ mt->applicableTo[2] = TOPOLOGY_CL_CONSTRAINED;
+ mt->applicableTo[3] = TOPOLOGY_CCL_CONSTRAINED;
+ mt->applicableTo[4] = TOPOLOGY_RCL_UNIFORM;
+ mt->applicableTo[5] = TOPOLOGY_RCL_CONSTRAINED;
+ mt->applicableTo[6] = TOPOLOGY_RCCL_UNIFORM;
+ mt->applicableTo[7] = TOPOLOGY_RCCL_CONSTRAINED;
+ mt->nApplicable = 8;
+ mt->moveFxn = &Move_ExtSSClock;
+ mt->relProposalProb = 0.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 0.5; /* extension probability */
+ mt->minimum[0] = 0.00001;
+ mt->maximum[0] = 0.99999;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->isApplicable = &IsApplicable_ThreeTaxaOrMore;
+
+ /* Move_ExtTBR */
+ mt = &moveTypes[i++];
+ mt->name = "Extending TBR";
+ mt->shortName = "ExtTBR";
+ mt->subParams = YES;
+ mt->tuningName[0] = "Extension probability";
+ mt->shortTuningName[0] = "p_ext";
+ mt->tuningName[1] = "Multiplier tuning parameter";
+ mt->shortTuningName[1] = "lambda";
+ mt->applicableTo[0] = TOPOLOGY_NCL_UNIFORM_HOMO;
+ mt->applicableTo[1] = TOPOLOGY_NCL_CONSTRAINED_HOMO;
+ mt->nApplicable = 2;
+ mt->moveFxn = &Move_ExtTBR;
+ mt->relProposalProb = 5.0;
+ mt->numTuningParams = 2;
+ mt->tuningParam[0] = 0.5; /* extension probability */
+ mt->tuningParam[1] = 2.0 * log (1.05); /* lambda */
+ mt->minimum[0] = 0.00001;
+ mt->maximum[0] = 0.99999;
+ mt->minimum[1] = 0.00001;
+ mt->maximum[1] = 100.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->isApplicable = &IsApplicable_FiveTaxaOrMore;
+
+ /* Move_RateShape_M */
+ mt = &moveTypes[i++];
+ mt->name = "Multiplier";
+ mt->shortName = "Multiplier";
+ mt->tuningName[0] = "Multiplier tuning parameter";
+ mt->shortTuningName[0] = "lambda";
+ mt->applicableTo[0] = SHAPE_UNI;
+ mt->applicableTo[1] = SHAPE_EXP;
+ mt->nApplicable = 2;
+ mt->moveFxn = &Move_RateShape_M;
+ mt->relProposalProb = 1.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 2.0 * log (1.5); /* lambda */
+ mt->minimum[0] = 0.0001;
+ mt->maximum[0] = 10.0; /* smaller */
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneMultiplier;
+ mt->targetRate = 0.25;
+
+ /* Move_GeneRate_Dir */
+ mt = &moveTypes[i++];
+ mt->name = "Dirichlet proposal";
+ mt->shortName = "Dirichlet";
+ mt->tuningName[0] = "Dirichlet parameter";
+ mt->shortTuningName[0] = "alpha";
+ mt->applicableTo[0] = GENETREERATEMULT_DIR;
+ mt->nApplicable = 1;
+ mt->moveFxn = &Move_GeneRate_Dir;
+ mt->relProposalProb = 1.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 1000.0; /* alphaPi */
+ mt->minimum[0] = 0.001;
+ mt->maximum[0] = 1000000.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneDirichlet;
+ mt->targetRate = 0.25;
+
+ /* Move_GeneTree1 */
+ mt = &moveTypes[i++];
+ mt->name = "Extending SPR move for gene trees in species trees";
+ mt->shortName = "ExtSPRClockGS";
+ mt->tuningName[0] = "Extension probability";
+ mt->shortTuningName[0] = "prob";
+ mt->applicableTo[0] = TOPOLOGY_SPECIESTREE;
+ mt->nApplicable = 1;
+ mt->moveFxn = &Move_GeneTree1;
+ mt->relProposalProb = 10.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 0.5; /* Tuning parameter value */
+ mt->minimum[0] = 0.00001; /* Minimum value of tuning param */
+ mt->maximum[0] = 0.99999; /* Maximum value of tuning param */
+ mt->parsimonyBased = NO; /* It does not use parsimony scores */
+ mt->level = STANDARD_USER;
+
+ /* Move_GeneTree2 */
+ mt = &moveTypes[i++];
+ mt->name = "NNI move for gene trees in species trees";
+ mt->shortName = "NNIClockGS";
+ mt->applicableTo[0] = TOPOLOGY_SPECIESTREE;
+ mt->nApplicable = 1;
+ mt->moveFxn = &Move_GeneTree2;
+ mt->relProposalProb = 10.0;
+ mt->numTuningParams = 0; /* No tuning parameters */
+ mt->parsimonyBased = NO; /* It does not use parsimony scores */
+ mt->level = STANDARD_USER;
+
+ /* Move_GeneTree3 */
+ mt = &moveTypes[i++];
+ mt->name = "Parsimony-biased SPR for gene trees in species trees";
+ mt->shortName = "ParsSPRClockGS";
+ mt->subParams = YES;
+ mt->tuningName[0] = "parsimony warp factor";
+ mt->shortTuningName[0] = "warp";
+ mt->tuningName[1] = "reweighting probability";
+ mt->shortTuningName[1] = "r";
+ mt->tuningName[2] = "typical branch length";
+ mt->shortTuningName[2] = "v_t";
+ mt->applicableTo[0] = TOPOLOGY_SPECIESTREE;
+ mt->nApplicable = 1;
+ mt->moveFxn = &Move_GeneTree3;
+ mt->relProposalProb = 5.0;
+ mt->numTuningParams = 3;
+ mt->tuningParam[0] = 0.1; /* warp */
+ mt->tuningParam[1] = 0.05; /* upweight and downweight probability */
+ mt->tuningParam[2] = 0.05; /* typical branch length */
+ mt->minimum[0] = 0.0;
+ mt->maximum[0] = 1.0;
+ mt->minimum[1] = 0.0;
+ mt->maximum[1] = 0.3;
+ mt->minimum[2] = 0.0001;
+ mt->maximum[2] = 0.5;
+ mt->parsimonyBased = YES;
+ mt->level = STANDARD_USER;
+
+ /* Move_Growth_M */
+ mt = &moveTypes[i++];
+ mt->name = "Multiplier";
+ mt->shortName = "Multiplier";
+ mt->tuningName[0] = "Multiplier tuning parameter";
+ mt->shortTuningName[0] = "lambda";
+ mt->applicableTo[0] = GROWTH_UNI;
+ mt->applicableTo[1] = GROWTH_EXP;
+ mt->applicableTo[2] = GROWTH_NORMAL;
+ mt->nApplicable = 3;
+ mt->moveFxn = &Move_Growth_M;
+ mt->relProposalProb = 1.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 2.0 * log(1.5); /* lambda */
+ mt->minimum[0] = 0.0001;
+ mt->maximum[0] = 20.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneMultiplier;
+ mt->targetRate = 0.25;
+
+ /* Move_Local */
+ mt = &moveTypes[i++];
+ mt->name = "BAMBE's LOCAL";
+ mt->shortName = "Local";
+ mt->subParams = YES;
+ mt->tuningName[0] = "Multiplier tuning parameter";
+ mt->shortTuningName[0] = "lambda";
+ mt->applicableTo[0] = TOPOLOGY_NCL_UNIFORM_HOMO;
+ mt->applicableTo[1] = TOPOLOGY_NCL_CONSTRAINED_HOMO;
+ mt->nApplicable = 2;
+ mt->moveFxn = &Move_Local;
+ mt->relProposalProb = 0.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 2.0 * log (1.1); /* lambda */
+ mt->minimum[0] = 0.00001;
+ mt->maximum[0] = 100.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->isApplicable = &IsApplicable_FourTaxaOrMore;
+
+ /* Move_LocalClock */
+ mt = &moveTypes[i++];
+ mt->name = "Modified LOCAL for clock trees";
+ mt->shortName = "LocalClock";
+ mt->subParams = YES;
+ mt->tuningName[0] = "Multiplier tuning parameter";
+ mt->shortTuningName[0] = "lambda";
+ mt->applicableTo[0] = TOPOLOGY_CL_UNIFORM;
+ mt->applicableTo[1] = TOPOLOGY_CCL_UNIFORM;
+ mt->applicableTo[2] = TOPOLOGY_CL_CONSTRAINED;
+ mt->applicableTo[3] = TOPOLOGY_CCL_CONSTRAINED;
+ mt->nApplicable = 4;
+ mt->moveFxn = &Move_LocalClock;
+ mt->relProposalProb = 0.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 2.0 * log (2.0); /* lambda */
+ mt->minimum[0] = 0.00001;
+ mt->maximum[0] = 100.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->isApplicable = &IsApplicable_ThreeTaxaOrMore;
+
+ /* Move_NNI */
+ mt = &moveTypes[i++];
+ mt->name = "NNI move for parsimony trees";
+ mt->shortName = "ParsNNI";
+ mt->applicableTo[0] = TOPOLOGY_PARSIMONY_UNIFORM;
+ mt->applicableTo[1] = TOPOLOGY_PARSIMONY_CONSTRAINED;
+ mt->nApplicable = 2;
+ mt->moveFxn = &Move_NNI;
+ mt->relProposalProb = 10.0;
+ mt->numTuningParams = 0;
+ mt->parsimonyBased = NO; /* no extra parsimony scores are needed */
+ mt->level = STANDARD_USER;
+ mt->isApplicable = &IsApplicable_FourTaxaOrMore;
+
+ /* Move_NNIClock */
+ mt = &moveTypes[i++];
+ mt->name = "NNI move for clock trees";
+ mt->shortName = "NNIClock";
+ mt->subParams = YES;
+ mt->applicableTo[0] = TOPOLOGY_CL_UNIFORM;
+ mt->applicableTo[1] = TOPOLOGY_CCL_UNIFORM;
+ mt->applicableTo[2] = TOPOLOGY_CL_CONSTRAINED;
+ mt->applicableTo[3] = TOPOLOGY_CCL_CONSTRAINED;
+ mt->applicableTo[4] = TOPOLOGY_RCL_UNIFORM;
+ mt->applicableTo[5] = TOPOLOGY_RCL_CONSTRAINED;
+ mt->applicableTo[6] = TOPOLOGY_RCCL_UNIFORM;
+ mt->applicableTo[7] = TOPOLOGY_RCCL_CONSTRAINED;
+ mt->nApplicable = 8;
+ mt->moveFxn = &Move_NNIClock;
+ mt->relProposalProb = 12.0;
+ mt->numTuningParams = 0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->isApplicable = &IsApplicable_ThreeTaxaOrMore;
+
+ /* Move_NNI */
+ mt = &moveTypes[i++];
+ mt->name = "NNI move";
+ mt->shortName = "NNI";
+ mt->subParams = YES;
+ mt->applicableTo[0] = TOPOLOGY_NCL_UNIFORM_HOMO;
+ mt->applicableTo[1] = TOPOLOGY_NCL_CONSTRAINED_HOMO;
+ mt->nApplicable = 2;
+ mt->moveFxn = &Move_NNI;
+ mt->relProposalProb = 5.0;
+ mt->numTuningParams = 0;
+ mt->minimum[0] = 0.00001;
+ mt->maximum[0] = 100.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->isApplicable = &IsApplicable_FourTaxaOrMore;
+
+ /* Move_NNI_Hetero */
+ mt = &moveTypes[i++];
+ mt->name = "NNI move for trees with independent brlens";
+ mt->shortName = "MultNNI";
+ mt->subParams = YES;
+ mt->applicableTo[0] = TOPOLOGY_NCL_UNIFORM_HETERO;
+ mt->applicableTo[1] = TOPOLOGY_NCL_CONSTRAINED_HETERO;
+ mt->nApplicable = 2; /* 3; */
+ mt->moveFxn = &Move_NNI_Hetero;
+ mt->relProposalProb = 15.0;
+ mt->numTuningParams = 0;
+ mt->minimum[0] = 0.00001;
+ mt->maximum[0] = 100.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->isApplicable = &IsApplicable_FourTaxaOrMore;
+
+ /* Move_NodeSlider */
+ mt = &moveTypes[i++];
+ mt->name = "Node slider (uniform on possible positions)";
+ mt->shortName = "Nodeslider";
+ mt->tuningName[0] = "Multiplier tuning parameter";
+ mt->shortTuningName[0] = "lambda";
+ mt->applicableTo[0] = BRLENS_UNI;
+ mt->applicableTo[1] = BRLENS_EXP;
+ mt->applicableTo[2] = BRLENS_GamDir;
+ mt->applicableTo[3] = BRLENS_iGmDir;
+ mt->applicableTo[4] = BRLENS_twoExp;
+ mt->nApplicable = 5; // was 2
+ mt->moveFxn = &Move_NodeSlider;
+ mt->relProposalProb = 7.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 2.0 * log (1.1); /* lambda */
+ mt->minimum[0] = 0.00001;
+ mt->maximum[0] = 100.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+
+ /* Move_NodeSliderClock */
+ mt = &moveTypes[i++];
+ mt->name = "Node depth window slider (clock-constrained)";
+ mt->shortName = "NodesliderClock";
+ mt->tuningName[0] = "Window size";
+ mt->shortTuningName[0] = "delta";
+ mt->applicableTo[0] = BRLENS_CLOCK_UNI;
+ mt->applicableTo[1] = BRLENS_CLOCK_COAL;
+ mt->applicableTo[2] = BRLENS_CLOCK_BD;
+ mt->applicableTo[3] = BRLENS_CLOCK_FOSSIL;
+ mt->nApplicable = 4;
+ mt->moveFxn = &Move_NodeSliderClock;
+ mt->relProposalProb = 20.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 0.05; /* window size */
+ mt->minimum[0] = 0.000001;
+ mt->maximum[0] = 1.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneSlider;
+ mt->targetRate = 0.25;
+
+ /* Move_NodeSliderGeneTree */
+ mt = &moveTypes[i++];
+ mt->name = "Node depth slider for gene trees";
+ mt->shortName = "NodesliderGenetree";
+ mt->tuningName[0] = "Window size";
+ mt->shortTuningName[0] = "delta";
+ mt->applicableTo[0] = BRLENS_CLOCK_SPCOAL;
+ mt->nApplicable = 1;
+ mt->moveFxn = &Move_NodeSliderGeneTree;
+ mt->relProposalProb = 20.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 0.05; /* window size */
+ mt->minimum[0] = 0.000001;
+ mt->maximum[0] = 100.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneSlider;
+ mt->targetRate = 0.25;
+
+ /* Move_Omega */
+ mt = &moveTypes[i++];
+ mt->name = "Sliding window";
+ mt->shortName = "Slider";
+ mt->tuningName[0] = "Sliding window size";
+ mt->shortTuningName[0] = "delta";
+ mt->applicableTo[0] = OMEGA_DIR;
+ mt->nApplicable = 1;
+ mt->moveFxn = &Move_Omega;
+ mt->relProposalProb = 1.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 1.0; /* sliding window size */
+ mt->minimum[0] = 0.000001;
+ mt->maximum[0] = 100.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneSlider;
+ mt->targetRate = 0.25;
+
+ /* Move_Omega_M */
+ mt = &moveTypes[i++];
+ mt->name = "Multiplier";
+ mt->shortName = "Multiplier";
+ mt->tuningName[0] = "Multiplier tuning parameter";
+ mt->shortTuningName[0] = "lambda";
+ mt->applicableTo[0] = OMEGA_DIR;
+ mt->nApplicable = 1;
+ mt->moveFxn = &Move_Omega_M;
+ mt->relProposalProb = 0.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 2.0 * log (1.5); /* lambda */
+ mt->minimum[0] = 0.0001;
+ mt->maximum[0] = 20.0; /* smaller */
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneMultiplier;
+ mt->targetRate = 0.25;
+
+ /* Move_OmegaBeta_M */
+ mt = &moveTypes[i++];
+ mt->name = "Multiplier";
+ mt->shortName = "Multiplier";
+ mt->paramName = "Omega_beta_M10";
+ mt->tuningName[0] = "Multiplier tuning parameter";
+ mt->shortTuningName[0] = "lambda";
+ mt->applicableTo[0] = OMEGA_10UUB;
+ mt->applicableTo[1] = OMEGA_10UUF;
+ mt->applicableTo[2] = OMEGA_10UEB;
+ mt->applicableTo[3] = OMEGA_10UEF;
+ mt->applicableTo[4] = OMEGA_10UFB;
+ mt->applicableTo[5] = OMEGA_10UFF;
+ mt->applicableTo[6] = OMEGA_10EUB;
+ mt->applicableTo[7] = OMEGA_10EUF;
+ mt->applicableTo[8] = OMEGA_10EEB;
+ mt->applicableTo[9] = OMEGA_10EEF;
+ mt->applicableTo[10] = OMEGA_10EFB;
+ mt->applicableTo[11] = OMEGA_10EFF;
+ mt->nApplicable = 12;
+ mt->moveFxn = &Move_OmegaBeta_M;
+ mt->relProposalProb = 1.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 2.0 * log (1.1); /* lambda */
+ mt->minimum[0] = 0.0001;
+ mt->maximum[0] = 20.0; /* smaller */
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneMultiplier;
+ mt->targetRate = 0.25;
+
+ /* Move_OmegaCat */
+ mt = &moveTypes[i++];
+ mt->name = "Dirichlet proposal";
+ mt->shortName = "Dirichlet";
+ mt->paramName = "Omega_pi";
+ mt->tuningName[0] = "Dirichlet parameter";
+ mt->shortTuningName[0] = "alpha";
+ mt->applicableTo[0] = OMEGA_BUD;
+ mt->applicableTo[1] = OMEGA_BED;
+ mt->applicableTo[2] = OMEGA_BFD;
+ mt->applicableTo[3] = OMEGA_FUD;
+ mt->applicableTo[4] = OMEGA_FED;
+ mt->applicableTo[5] = OMEGA_FFD;
+ mt->applicableTo[6] = OMEGA_ED;
+ mt->applicableTo[7] = OMEGA_FD;
+ mt->applicableTo[8] = OMEGA_10UUB;
+ mt->applicableTo[9] = OMEGA_10UEB;
+ mt->applicableTo[10] = OMEGA_10UFB;
+ mt->applicableTo[11] = OMEGA_10EUB;
+ mt->applicableTo[12] = OMEGA_10EEB;
+ mt->applicableTo[13] = OMEGA_10EFB;
+ mt->applicableTo[14] = OMEGA_10FUB;
+ mt->applicableTo[15] = OMEGA_10FEB;
+ mt->applicableTo[16] = OMEGA_10FFB;
+ mt->nApplicable = 17;
+ mt->moveFxn = &Move_OmegaCat;
+ mt->relProposalProb = 1.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 300.0; /* alpha-pi */
+ mt->minimum[0] = 0.001;
+ mt->maximum[0] = 10000.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneDirichlet;
+ mt->targetRate = 0.25;
+
+ /* Move_OmegaGamma_M */
+ mt = &moveTypes[i++];
+ mt->name = "Multiplier";
+ mt->shortName = "Multiplier";
+ mt->paramName = "Omega_shape_M10";
+ mt->tuningName[0] = "Multiplier tuning parameter";
+ mt->shortTuningName[0] = "lambda";
+ mt->applicableTo[0] = OMEGA_10UUB;
+ mt->applicableTo[1] = OMEGA_10UUF;
+ mt->applicableTo[2] = OMEGA_10UEB;
+ mt->applicableTo[3] = OMEGA_10UEF;
+ mt->applicableTo[4] = OMEGA_10EUB;
+ mt->applicableTo[5] = OMEGA_10EUF;
+ mt->applicableTo[6] = OMEGA_10EEB;
+ mt->applicableTo[7] = OMEGA_10EEF;
+ mt->applicableTo[8] = OMEGA_10FUB;
+ mt->applicableTo[9] = OMEGA_10FUF;
+ mt->applicableTo[10] = OMEGA_10FEB;
+ mt->applicableTo[11] = OMEGA_10FEF;
+ mt->nApplicable = 12;
+ mt->moveFxn = &Move_OmegaGamma_M;
+ mt->relProposalProb = 1.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 2.0 * log (1.1); /* lambda */
+ mt->minimum[0] = 0.0001;
+ mt->maximum[0] = 20.0; /* smaller */
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneMultiplier;
+ mt->targetRate = 0.25;
+
+ /* Move_OmegaM3 */
+ mt = &moveTypes[i++];
+ mt->name = "Sliding window";
+ mt->shortName = "Slider";
+ mt->tuningName[0] = "Sliding window size";
+ mt->shortTuningName[0] = "delta";
+ mt->applicableTo[0] = OMEGA_ED;
+ mt->applicableTo[1] = OMEGA_EF;
+ mt->nApplicable = 2;
+ mt->moveFxn = &Move_OmegaM3;
+ mt->relProposalProb = 1.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 0.1; /* window size */
+ mt->minimum[0] = 0.00001;
+ mt->maximum[0] = 1.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneSlider;
+ mt->targetRate = 0.25;
+
+ /* Move_OmegaPur : Let it be here so that omega moves are listed in logical order! */
+ mt = &moveTypes[i++];
+ mt->name = "Sliding window";
+ mt->shortName = "Slider";
+ mt->paramName = "Omega_pur";
+ mt->tuningName[0] = "Sliding window size";
+ mt->shortTuningName[0] = "delta";
+ mt->applicableTo[0] = OMEGA_BUD;
+ mt->applicableTo[1] = OMEGA_BUF;
+ mt->applicableTo[2] = OMEGA_BED;
+ mt->applicableTo[3] = OMEGA_BEF;
+ mt->applicableTo[4] = OMEGA_BFD;
+ mt->applicableTo[5] = OMEGA_BFF;
+ mt->nApplicable = 6;
+ mt->moveFxn = &Move_OmegaPur;
+ mt->relProposalProb = 1.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 0.1; /* window size */
+ mt->minimum[0] = 0.00001;
+ mt->maximum[0] = 1.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneSlider;
+ mt->targetRate = 0.25;
+
+ /* Move_OmegaPos */
+ mt = &moveTypes[i++];
+ mt->name = "Sliding window";
+ mt->shortName = "Slider";
+ mt->paramName = "Omega_pos";
+ mt->tuningName[0] = "Sliding window size";
+ mt->shortTuningName[0] = "delta";
+ mt->applicableTo[0] = OMEGA_BUD;
+ mt->applicableTo[1] = OMEGA_BUF;
+ mt->applicableTo[2] = OMEGA_BED;
+ mt->applicableTo[3] = OMEGA_BEF;
+ mt->applicableTo[4] = OMEGA_FUD;
+ mt->applicableTo[5] = OMEGA_FUF;
+ mt->applicableTo[6] = OMEGA_FED;
+ mt->applicableTo[7] = OMEGA_FEF;
+ mt->nApplicable = 8;
+ mt->moveFxn = &Move_OmegaPos;
+ mt->relProposalProb = 1.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 1.0; /* window size */
+ mt->minimum[0] = 0.00001;
+ mt->maximum[0] = 100.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneSlider;
+ mt->targetRate = 0.25;
+
+ /* Move_ParsEraser1 */
+ mt = &moveTypes[i++];
+ mt->name = "Parsimony-biased eraser version 1";
+ mt->shortName = "pEraser1";
+ mt->subParams = YES;
+ mt->tuningName[0] = "Dirichlet parameter";
+ mt->shortTuningName[0] = "alpha";
+ mt->tuningName[1] = "parsimony warp factor";
+ mt->shortTuningName[1] = "warp";
+ mt->applicableTo[0] = TOPOLOGY_NCL_UNIFORM_HOMO;
+ mt->nApplicable = 1;
+ mt->moveFxn = &Move_ParsEraser1;
+ mt->relProposalProb = 0.0;
+ mt->numTuningParams = 2;
+ mt->tuningParam[0] = 0.5; /* alphaPi */
+ mt->tuningParam[1] = 0.1; /* warp */
+ mt->minimum[0] = 0.00001;
+ mt->maximum[0] = 10000.0;
+ mt->minimum[1] = 0.00001;
+ mt->maximum[1] = 0.99999;
+ mt->parsimonyBased = YES;
+ mt->level = DEVELOPER;
+ mt->isApplicable = &IsApplicable_FiveTaxaOrMore;
+
+ /* Move_ParsSPR asym */
+ mt = &moveTypes[i++];
+ mt->name = "Parsimony-biased SPR";
+ mt->shortName = "ParsSPR";
+ mt->subParams = YES;
+ mt->tuningName[0] = "parsimony warp factor";
+ mt->shortTuningName[0] = "warp";
+ mt->tuningName[1] = "reweighting probability";
+ mt->shortTuningName[1] = "r";
+ mt->tuningName[2] = "typical branch length";
+ mt->shortTuningName[2] = "v_t";
+ mt->tuningName[3] = "multiplier tuning parameter";
+ mt->shortTuningName[3] = "lambda";
+ mt->applicableTo[0] = TOPOLOGY_NCL_UNIFORM_HOMO;
+ mt->applicableTo[1] = TOPOLOGY_NCL_CONSTRAINED_HOMO;
+ mt->nApplicable = 2;
+ mt->moveFxn = &Move_ParsSPR;
+ mt->relProposalProb = 5.0;
+ mt->numTuningParams = 4;
+ mt->tuningParam[0] = 0.1; /* warp */
+ mt->tuningParam[1] = 0.05; /* upweight and downweight probability */
+ mt->tuningParam[2] = 0.03; /* typical branch length */
+ mt->tuningParam[3] = 2.0 * log (1.05); /* multiplier tuning parameter lambda */
+ mt->minimum[0] = 0.0;
+ mt->maximum[0] = 1.0;
+ mt->minimum[1] = 0.0;
+ mt->maximum[1] = 0.3;
+ mt->minimum[2] = 0.0001;
+ mt->maximum[2] = 0.5;
+ mt->minimum[3] = 2.0 * log (0.001);
+ mt->maximum[3] = 2.0 * log (1000.);
+ mt->parsimonyBased = YES;
+ mt->level = STANDARD_USER;
+ mt->isApplicable = &IsApplicable_FourTaxaOrMore;
+
+ /* Move_ParsSPR1 e^{-S} */
+ mt = &moveTypes[i++];
+ mt->name = "Parsimony-biased SPR variant 1";
+ mt->shortName = "ParsSPR1";
+ mt->subParams = YES;
+ mt->tuningName[0] = "parsimony warp factor";
+ mt->shortTuningName[0] = "warp";
+ mt->tuningName[1] = "reweighting probability";
+ mt->shortTuningName[1] = "r";
+ mt->tuningName[2] = "typical branch length";
+ mt->shortTuningName[2] = "v_t";
+ mt->tuningName[3] = "multiplier tuning parameter";
+ mt->shortTuningName[3] = "lambda";
+ mt->tuningName[4] = "moving distance";
+ mt->shortTuningName[4] = "d";
+ mt->applicableTo[0] = TOPOLOGY_NCL_UNIFORM_HOMO;
+ mt->applicableTo[1] = TOPOLOGY_NCL_CONSTRAINED_HOMO;
+ mt->nApplicable = 2;
+ mt->moveFxn = &Move_ParsSPR1;
+ mt->relProposalProb = 0.0;
+ mt->numTuningParams = 5;
+ mt->tuningParam[0] = 0.5; /* warp */
+ mt->tuningParam[1] = 0.05; /* upweight and downweight probability */
+ mt->tuningParam[2] = 0.03; /* typical branch length */
+ mt->tuningParam[3] = 2.0 * log (1.05); /* multiplier tuning parameter lambda */
+ mt->tuningParam[4] = 10.0; /* distance to move picked branch */
+ mt->minimum[0] = 0.0;
+ mt->maximum[0] = 5.0;
+ mt->minimum[1] = 0.0;
+ mt->maximum[1] = 0.3;
+ mt->minimum[2] = 0.0001;
+ mt->maximum[2] = 0.5;
+ mt->minimum[3] = 2.0 * log (0.001);
+ mt->maximum[3] = 2.0 * log (1000.);
+ mt->minimum[4] = 2.0;
+ mt->maximum[4] = 1000.0;
+ mt->parsimonyBased = YES;
+ mt->level = DEVELOPER;
+ mt->isApplicable = &IsApplicable_FourTaxaOrMore;
+
+ /* Move_ParsSPR2 S/N */
+ mt = &moveTypes[i++];
+ mt->name = "Parsimony-biased SPR variant 2";
+ mt->shortName = "ParsSPR2";
+ mt->subParams = YES;
+ mt->tuningName[0] = "parsimony warp factor";
+ mt->shortTuningName[0] = "warp";
+ mt->tuningName[1] = "reweighting probability";
+ mt->shortTuningName[1] = "r";
+ mt->tuningName[2] = "typical branch length";
+ mt->shortTuningName[2] = "v_t";
+ mt->tuningName[3] = "multiplier tuning parameter";
+ mt->shortTuningName[3] = "lambda";
+ mt->tuningName[4] = "moving distance";
+ mt->shortTuningName[4] = "d";
+ mt->applicableTo[0] = TOPOLOGY_NCL_UNIFORM_HOMO;
+ mt->applicableTo[1] = TOPOLOGY_NCL_CONSTRAINED_HOMO;
+ mt->nApplicable = 2;
+ mt->moveFxn = &Move_ParsSPR2;
+ mt->relProposalProb = 0.0;
+ mt->numTuningParams = 5;
+ mt->tuningParam[0] = 0.1; /* warp */
+ mt->tuningParam[1] = 0.05; /* upweight and downweight probability */
+ mt->tuningParam[2] = 0.03; /* typical branch length */
+ mt->tuningParam[3] = 2.0 * log (1.05); /* multiplier tuning parameter lambda */
+ mt->tuningParam[4] = 10.0; /* distance to move picked branch */
+ mt->minimum[0] = 0.0;
+ mt->maximum[0] = 1.0;
+ mt->minimum[1] = 0.0;
+ mt->maximum[1] = 0.3;
+ mt->minimum[2] = 0.0001;
+ mt->maximum[2] = 0.5;
+ mt->minimum[3] = 2.0 * log (0.001);
+ mt->maximum[3] = 2.0 * log (1000.);
+ mt->minimum[4] = 2.0;
+ mt->maximum[4] = 1000.0;
+ mt->parsimonyBased = YES;
+ mt->level = DEVELOPER;
+ mt->isApplicable = &IsApplicable_FourTaxaOrMore;
+
+ /* Move_ParsSPRClock */
+ mt = &moveTypes[i++];
+ mt->name = "Parsimony-biased SPR for clock trees";
+ mt->shortName = "ParsSPRClock";
+ mt->subParams = YES;
+ mt->tuningName[0] = "parsimony warp factor";
+ mt->shortTuningName[0] = "warp";
+ mt->tuningName[1] = "reweighting probability";
+ mt->shortTuningName[1] = "r";
+ mt->tuningName[2] = "typical branch length";
+ mt->shortTuningName[2] = "v_t";
+ mt->applicableTo[0] = TOPOLOGY_CL_UNIFORM;
+ mt->applicableTo[1] = TOPOLOGY_CCL_UNIFORM;
+ mt->applicableTo[2] = TOPOLOGY_CL_CONSTRAINED;
+ mt->applicableTo[3] = TOPOLOGY_CCL_CONSTRAINED;
+ mt->applicableTo[4] = TOPOLOGY_RCL_UNIFORM;
+ mt->applicableTo[5] = TOPOLOGY_RCL_CONSTRAINED;
+ mt->applicableTo[6] = TOPOLOGY_RCCL_UNIFORM;
+ mt->applicableTo[7] = TOPOLOGY_RCCL_CONSTRAINED;
+ mt->nApplicable = 8;
+ mt->moveFxn = &Move_ParsSPRClock;
+ mt->relProposalProb = 8.0;
+ mt->numTuningParams = 3;
+ mt->tuningParam[0] = 0.1; /* warp */
+ mt->tuningParam[1] = 0.05; /* upweight and downweight probability */
+ mt->tuningParam[2] = 0.03; /* typical branch length */
+ mt->minimum[0] = 0.0;
+ mt->maximum[0] = 1.0;
+ mt->minimum[1] = 0.0;
+ mt->maximum[1] = 0.3;
+ mt->minimum[2] = 0.0001;
+ mt->maximum[2] = 0.5;
+ mt->parsimonyBased = YES;
+ mt->level = STANDARD_USER;
+ mt->isApplicable = &IsApplicable_ThreeTaxaOrMore;
+
+ /* Move_ParsTBR1 e^{-S} */
+ mt = &moveTypes[i++];
+ mt->name = "Parsimony-biased TBR variant 1";
+ mt->shortName = "ParsTBR1";
+ mt->subParams = YES;
+ mt->tuningName[0] = "parsimony warp factor";
+ mt->shortTuningName[0] = "warp";
+ mt->tuningName[1] = "reweighting probability";
+ mt->shortTuningName[1] = "r";
+ mt->tuningName[2] = "typical branch length";
+ mt->shortTuningName[2] = "v_t";
+ mt->tuningName[3] = "multiplier tuning parameter";
+ mt->shortTuningName[3] = "lambda";
+ mt->tuningName[4] = "moving distance";
+ mt->shortTuningName[4] = "d";
+ mt->applicableTo[0] = TOPOLOGY_NCL_UNIFORM_HOMO;
+ mt->applicableTo[1] = TOPOLOGY_NCL_CONSTRAINED_HOMO;
+ mt->nApplicable = 2;
+ mt->moveFxn = &Move_ParsTBR1;
+ mt->relProposalProb = 0.0;
+ mt->numTuningParams = 5;
+ mt->tuningParam[0] = 0.5; /* warp */
+ mt->tuningParam[1] = 0.05; /* upweight and downweight probability */
+ mt->tuningParam[2] = 0.05; /* typical branch length */
+ mt->tuningParam[3] = 2.0 * log (1.05); /* multiplier tuning parameter lambda */
+ mt->tuningParam[4] = 5.0; /* distance to move picked branch */
+ mt->minimum[0] = 0.0;
+ mt->maximum[0] = 5.0;
+ mt->minimum[1] = 0.0;
+ mt->maximum[1] = 0.3;
+ mt->minimum[2] = 0.0001;
+ mt->maximum[2] = 0.5;
+ mt->minimum[3] = 2.0 * log (0.001);
+ mt->maximum[3] = 2.0 * log (1000.);
+ mt->minimum[4] = 2.0;
+ mt->maximum[4] = 1000.0;
+ mt->parsimonyBased = YES;
+ mt->level = DEVELOPER;
+ mt->isApplicable = &IsApplicable_FiveTaxaOrMore;
+
+ /* Move_ParsTBR2 S/N */
+ mt = &moveTypes[i++];
+ mt->name = "Parsimony-biased TBR variant 2";
+ mt->shortName = "ParsTBR2";
+ mt->subParams = YES;
+ mt->tuningName[0] = "parsimony warp factor";
+ mt->shortTuningName[0] = "warp";
+ mt->tuningName[1] = "reweighting probability";
+ mt->shortTuningName[1] = "r";
+ mt->tuningName[2] = "typical branch length";
+ mt->shortTuningName[2] = "v_t";
+ mt->tuningName[3] = "multiplier tuning parameter";
+ mt->shortTuningName[3] = "lambda";
+ mt->tuningName[4] = "moving distance";
+ mt->shortTuningName[4] = "d";
+ mt->applicableTo[0] = TOPOLOGY_NCL_UNIFORM_HOMO;
+ mt->applicableTo[1] = TOPOLOGY_NCL_CONSTRAINED_HOMO;
+ mt->nApplicable = 2;
+ mt->moveFxn = &Move_ParsTBR2;
+ mt->relProposalProb = 0.0;
+ mt->numTuningParams = 5;
+ mt->tuningParam[0] = 0.1; /* warp */
+ mt->tuningParam[1] = 0.05; /* upweight and downweight probability */
+ mt->tuningParam[2] = 0.05; /* typical branch length */
+ mt->tuningParam[3] = 2.0 * log (1.05); /* multiplier tuning parameter lambda */
+ mt->tuningParam[4] = 5.0; /* distance to move picked branch */
+ mt->minimum[0] = 0.0;
+ mt->maximum[0] = 1.0;
+ mt->minimum[1] = 0.0;
+ mt->maximum[1] = 0.3;
+ mt->minimum[2] = 0.0001;
+ mt->maximum[2] = 0.5;
+ mt->minimum[3] = 2.0 * log (0.001);
+ mt->maximum[3] = 2.0 * log (1000.);
+ mt->minimum[4] = 2.0;
+ mt->maximum[4] = 1000.0;
+ mt->parsimonyBased = YES;
+ mt->level = DEVELOPER;
+ mt->isApplicable = &IsApplicable_FiveTaxaOrMore;
+
+ /* Move_Pinvar */
+ mt = &moveTypes[i++];
+ mt->name = "Sliding window";
+ mt->shortName = "Slider";
+ mt->tuningName[0] = "Sliding window size";
+ mt->shortTuningName[0] = "delta";
+ mt->applicableTo[0] = PINVAR_UNI;
+ mt->nApplicable = 1;
+ mt->moveFxn = &Move_Pinvar;
+ mt->relProposalProb = 1.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 0.1; /* window size */
+ mt->minimum[0] = 0.001;
+ mt->maximum[0] = 0.999;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneSlider;
+ mt->targetRate = 0.25;
+
+ /* Move_Popsize_M */
+ mt = &moveTypes[i++];
+ mt->name = "Multiplier";
+ mt->shortName = "Multiplier";
+ mt->tuningName[0] = "Multiplier tuning parameter";
+ mt->shortTuningName[0] = "lambda";
+ mt->applicableTo[0] = POPSIZE_UNI;
+ mt->applicableTo[1] = POPSIZE_LOGNORMAL;
+ mt->applicableTo[2] = POPSIZE_NORMAL;
+ mt->applicableTo[3] = POPSIZE_GAMMA;
+ mt->nApplicable = 4;
+ mt->moveFxn = &Move_PopSize_M;
+ mt->relProposalProb = 1.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 2.0 * log(1.5); /* lambda */
+ mt->minimum[0] = 0.00001;
+ mt->maximum[0] = 100.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneSlider;
+ mt->targetRate = 0.25;
+
+ /* Move_RateMult_Dir */
+ mt = &moveTypes[i++];
+ mt->name = "Dirichlet proposal";
+ mt->shortName = "Dirichlet";
+ mt->tuningName[0] = "Dirichlet parameter";
+ mt->shortTuningName[0] = "alpha";
+ mt->applicableTo[0] = RATEMULT_DIR;
+ mt->nApplicable = 1;
+ mt->moveFxn = &Move_RateMult_Dir;
+ mt->relProposalProb = 0.75;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 50.0; /* alphaPi per site */
+ mt->minimum[0] = 0.001;
+ mt->maximum[0] = 10000.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneDirichlet;
+ mt->targetRate = 0.25;
+
+ /* Move_RateMult_Slider */
+ mt = &moveTypes[i++];
+ mt->name = "Sliding window";
+ mt->shortName = "Slider";
+ mt->tuningName[0] = "Sliding window size";
+ mt->shortTuningName[0] = "delta";
+ mt->applicableTo[0] = RATEMULT_DIR;
+ mt->nApplicable = 1;
+ mt->moveFxn = &Move_RateMult_Slider;
+ mt->relProposalProb = 0.75;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 0.05; /* window size */
+ mt->minimum[0] = 0.00001;
+ mt->maximum[0] = 1.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneSlider;
+ mt->targetRate = 0.25;
+
+ /* Move_Revmat_Dir */
+ mt = &moveTypes[i++];
+ mt->name = "Dirichlet proposal";
+ mt->shortName = "Dirichlet";
+ mt->tuningName[0] = "Dirichlet parameter";
+ mt->shortTuningName[0] = "alpha";
+ mt->applicableTo[0] = REVMAT_DIR;
+ mt->nApplicable = 1;
+ mt->moveFxn = &Move_Revmat_Dir;
+ mt->relProposalProb = 0.5;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 100.0; /* alphaPi per rate */
+ mt->minimum[0] = 0.001;
+ mt->maximum[0] = 10000.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneDirichlet;
+ mt->targetRate = 0.25;
+
+ /* Move_Revmat_Slider */
+ mt = &moveTypes[i++];
+ mt->name = "Sliding window";
+ mt->shortName = "Slider";
+ mt->tuningName[0] = "Sliding window size";
+ mt->shortTuningName[0] = "delta";
+ mt->applicableTo[0] = REVMAT_DIR;
+ mt->nApplicable = 1;
+ mt->moveFxn = &Move_Revmat_Slider;
+ mt->relProposalProb = 0.5;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 0.15; /* window size */
+ mt->minimum[0] = 0.00001;
+ mt->maximum[0] = 1.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneSlider;
+ mt->targetRate = 0.25;
+
+ /* Move_Revmat_DirMix */
+ mt = &moveTypes[i++];
+ mt->name = "Dirichlet proposal";
+ mt->shortName = "Dirichlet";
+ mt->tuningName[0] = "Dirichlet parameter";
+ mt->shortTuningName[0] = "alpha";
+ mt->applicableTo[0] = REVMAT_MIX;
+ mt->nApplicable = 1;
+ mt->moveFxn = &Move_Revmat_DirMix;
+ mt->relProposalProb = 1.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 100.0; /* alphaPi per rate */
+ mt->minimum[0] = 0.01;
+ mt->maximum[0] = 10000.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneDirichlet;
+ mt->targetRate = 0.25;
+
+ /* Move_Revmat_SplitMerge1 */
+ mt = &moveTypes[i++];
+ mt->name = "Split-merge move 1";
+ mt->shortName = "Splitmerge1";
+ mt->tuningName[0] = "Dirichlet parameter";
+ mt->shortTuningName[0] = "alpha";
+ mt->applicableTo[0] = REVMAT_MIX;
+ mt->nApplicable = 1;
+ mt->moveFxn = &Move_Revmat_SplitMerge1;
+ mt->relProposalProb = 1.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 10.0; /* alphaPi per rate */
+ mt->minimum[0] = 0.5;
+ mt->maximum[0] = 100.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneDirichlet;
+ mt->targetRate = 0.25;
+
+ /* Move_Revmat_SplitMerge2 */
+ mt = &moveTypes[i++];
+ mt->name = "Split-merge move 2";
+ mt->shortName = "Splitmerge2";
+ mt->tuningName[0] = "Dirichlet parameter";
+ mt->shortTuningName[0] = "alpha";
+ mt->applicableTo[0] = REVMAT_MIX;
+ mt->nApplicable = 1;
+ mt->moveFxn = &Move_Revmat_SplitMerge2;
+ mt->relProposalProb = 1.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 10.0; /* alphaPi per rate */
+ mt->minimum[0] = 0.5;
+ mt->maximum[0] = 100.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneDirichlet;
+ mt->targetRate = 0.25;
+
+ /* Move_Speciation */
+ mt = &moveTypes[i++];
+ mt->name = "Sliding window";
+ mt->shortName = "Slider";
+ mt->tuningName[0] = "Sliding window size";
+ mt->shortTuningName[0] = "delta";
+ mt->applicableTo[0] = SPECRATE_UNI;
+ mt->applicableTo[1] = SPECRATE_EXP;
+ mt->nApplicable = 2;
+ mt->moveFxn = &Move_Speciation;
+ mt->relProposalProb = 0.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 1.0; /* window size */
+ mt->minimum[0] = 0.00001;
+ mt->maximum[0] = 100.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneSlider;
+ mt->targetRate = 0.25;
+
+ /* Move_Speciation_M */
+ mt = &moveTypes[i++];
+ mt->name = "Multiplier";
+ mt->shortName = "Multiplier";
+ mt->tuningName[0] = "Multiplier tuning parameter";
+ mt->shortTuningName[0] = "lambda";
+ mt->applicableTo[0] = SPECRATE_UNI;
+ mt->applicableTo[1] = SPECRATE_EXP;
+ mt->nApplicable = 2;
+ mt->moveFxn = &Move_Speciation_M;
+ mt->relProposalProb = 3.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 2.0 * log (1.1); /* lambda */
+ mt->minimum[0] = 0.00001;
+ mt->maximum[0] = 20.0; /* smaller */
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneMultiplier;
+ mt->targetRate = 0.25;
+
+ /* Move_SpeciesTree */
+ mt = &moveTypes[i++];
+ mt->name = "Species tree move";
+ mt->shortName = "Distmatrixmove";
+ mt->tuningName[0] = "Divider of rate of truncated exponential";
+ mt->shortTuningName[0] = "lambdadiv";
+ mt->applicableTo[0] = SPECIESTREE_UNIFORM;
+ mt->nApplicable = 1;
+ mt->moveFxn = &Move_SpeciesTree;
+ mt->relProposalProb = 10.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 1.2; /* Default tuning parameter value */
+ mt->minimum[0] = 0.00001; /* Minimum value of tuning param */
+ mt->maximum[0] = 1000.0; /* Maximum value of tuning param */
+ mt->parsimonyBased = NO; /* It does not use parsimony scores */
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneMultiplier; /* Autotune this move as a mutliplier move (larger is more bold) */
+ mt->targetRate = 0.25; /* Target acceptance rate */
+
+ /* Move_Statefreqs */
+ mt = &moveTypes[i++];
+ mt->name = "Dirichlet proposal";
+ mt->shortName = "Dirichlet";
+ mt->tuningName[0] = "Dirichlet parameter";
+ mt->shortTuningName[0] = "alpha";
+ mt->applicableTo[0] = PI_DIR;
+ mt->nApplicable = 1;
+ mt->moveFxn = &Move_Statefreqs;
+ mt->relProposalProb = 0.5;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 100.0; /* alphaPi per state */
+ mt->minimum[0] = 0.001;
+ mt->maximum[0] = 10000.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneDirichlet;
+ mt->targetRate = 0.25;
+
+ /* Move_Statefreqs_Slider */
+ mt = &moveTypes[i++];
+ mt->name = "Sliding window";
+ mt->shortName = "Slider";
+ mt->tuningName[0] = "Sliding window size";
+ mt->shortTuningName[0] = "delta";
+ mt->applicableTo[0] = PI_DIR;
+ mt->nApplicable = 1;
+ mt->moveFxn = &Move_Statefreqs_Slider;
+ mt->relProposalProb = 0.5;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 0.20; /* window size (change in proportions) */
+ mt->minimum[0] = 0.00001;
+ mt->maximum[0] = 1.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneSlider;
+ mt->targetRate = 0.25;
+
+ /* Move_StatefreqsSymDirMultistate */
+ mt = &moveTypes[i++];
+ mt->name = "Dirichlet proposal";
+ mt->shortName = "Dirichlet";
+ mt->paramName = "Pi_symdir";
+ mt->tuningName[0] = "Dirichlet parameter";
+ mt->shortTuningName[0] = "alpha";
+ mt->applicableTo[0] = SYMPI_FIX_MS;
+ mt->applicableTo[1] = SYMPI_UNI_MS;
+ mt->applicableTo[2] = SYMPI_EXP_MS;
+ mt->nApplicable = 3;
+ mt->moveFxn = &Move_StatefreqsSymDirMultistate;
+ mt->relProposalProb = 5.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 50.0; /* alphaPi */
+ mt->minimum[0] = 0.001;
+ mt->maximum[0] = 10000.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneDirichlet;
+ mt->targetRate = 0.25;
+
+ /* Move_SwitchRate */
+ mt = &moveTypes[i++];
+ mt->name = "Sliding window";
+ mt->shortName = "Slider";
+ mt->tuningName[0] = "Sliding window size";
+ mt->shortTuningName[0] = "delta";
+ mt->applicableTo[0] = SWITCH_UNI;
+ mt->applicableTo[1] = SWITCH_EXP;
+ mt->nApplicable = 2;
+ mt->moveFxn = &Move_SwitchRate;
+ mt->relProposalProb = 1.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 1.0; /* window size */
+ mt->minimum[0] = 0.00001;
+ mt->maximum[0] = 100.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneSlider;
+ mt->targetRate = 0.25;
+
+ /* Move_SwitchRate_M */
+ mt = &moveTypes[i++];
+ mt->name = "Multiplier";
+ mt->shortName = "Multiplier";
+ mt->tuningName[0] = "Multiplier tuning parameter";
+ mt->shortTuningName[0] = "lambda";
+ mt->applicableTo[0] = SWITCH_UNI;
+ mt->applicableTo[1] = SWITCH_EXP;
+ mt->nApplicable = 2;
+ mt->moveFxn = &Move_SwitchRate_M;
+ mt->relProposalProb = 0.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 2.0 * log (1.5); /* lambda */
+ mt->minimum[0] = 0.0001;
+ mt->maximum[0] = 20.0; /* smaller */
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneMultiplier;
+ mt->targetRate = 0.25;
+
+ /* Move_Tratio_Dir */
+ mt = &moveTypes[i++];
+ mt->name = "Dirichlet proposal";
+ mt->shortName = "Dirichlet";
+ mt->tuningName[0] = "Dirichlet parameter";
+ mt->shortTuningName[0] = "alpha";
+ mt->applicableTo[0] = TRATIO_DIR;
+ mt->nApplicable = 1;
+ mt->moveFxn = &Move_Tratio_Dir;
+ mt->relProposalProb = 1.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 50.0; /* alphaPi */
+ mt->minimum[0] = 0.001;
+ mt->maximum[0] = 10000.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneDirichlet;
+ mt->targetRate = 0.25;
+
+ /* Move_TreeStretch */
+ mt = &moveTypes[i++];
+ mt->name = "Tree stretch";
+ mt->shortName = "TreeStretch";
+ mt->tuningName[0] = "Multiplier tuning parameter";
+ mt->shortTuningName[0] = "lambda";
+ mt->applicableTo[0] = BRLENS_CLOCK_UNI;
+ mt->applicableTo[1] = BRLENS_CLOCK_BD;
+ mt->applicableTo[2] = BRLENS_CLOCK_COAL;
+ mt->applicableTo[3] = BRLENS_CLOCK_FOSSIL;
+ mt->nApplicable = 4;
+ mt->moveFxn = &Move_TreeStretch;
+ mt->relProposalProb = 3.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 2.0 * log(1.01); /* lambda */
+ mt->minimum[0] = 0.0001;
+ mt->maximum[0] = 2.0 * log(2.0);
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneMultiplier;
+ mt->targetRate = 0.25;
+
+ /* Move_TreeLen, by Jeremy Brown */
+ mt = &moveTypes[i++];
+ mt->name = "Whole treelength hit with multiplier";
+ mt->shortName = "TLMultiplier";
+ mt->tuningName[0] = "Multiplier tuning parameter";
+ mt->shortTuningName[0] = "lambda";
+ mt->applicableTo[0] = BRLENS_UNI;
+ mt->applicableTo[1] = BRLENS_EXP;
+ mt->applicableTo[2] = BRLENS_GamDir;
+ mt->applicableTo[3] = BRLENS_iGmDir;
+ mt->applicableTo[4] = BRLENS_twoExp;
+ mt->nApplicable = 5; // was 2
+ mt->moveFxn = &Move_TreeLen;
+ mt->relProposalProb = 3.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 2.0 * log (2.0); /* lambda */
+ mt->minimum[0] = 0.0001;
+ mt->maximum[0] = 100.0; /* smaller */
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneMultiplier;
+ mt->targetRate = 0.25;
+
+ /* Move_AddDeleteCPPEvent */
+ mt = &moveTypes[i++];
+ mt->name = "Random addition/deletion of CPP event";
+ mt->shortName = "Add_delete";
+ mt->applicableTo[0] = CPPEVENTS;
+ mt->nApplicable = 1;
+ mt->moveFxn = &Move_AddDeleteCPPEvent;
+ mt->relProposalProb = 1.0;
+ mt->numTuningParams = 0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+
+ /* Move_CPPEventPosition */
+ mt = &moveTypes[i++];
+ mt->name = "Random draw of CPP event position from prior";
+ mt->shortName = "Prior_draw_pos";
+ mt->applicableTo[0] = CPPEVENTS;
+ mt->nApplicable = 1;
+ mt->moveFxn = &Move_CPPEventPosition;
+ mt->relProposalProb = 2.0;
+ mt->numTuningParams = 0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+
+ /* Move_CPPRate */
+ mt = &moveTypes[i++];
+ mt->name = "Multiplier";
+ mt->shortName = "Multiplier";
+ mt->tuningName[0] = "Multiplier tuning parameter";
+ mt->shortTuningName[0] = "lambda";
+ mt->applicableTo[0] = CPPRATE_EXP;
+ mt->nApplicable = 1;
+ mt->moveFxn = &Move_CPPRate;
+ mt->relProposalProb = 2.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 2.0 * log (1.1); /* lambda */
+ mt->minimum[0] = 0.0001;
+ mt->maximum[0] = 20.0; /* smaller */
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneMultiplier;
+ mt->targetRate = 0.25;
+
+ /* Move_CPPRateMultiplier_M */
+ mt = &moveTypes[i++];
+ mt->name = "Random CPP rate multiplier hit with multiplier";
+ mt->shortName = "Multiplier";
+ mt->tuningName[0] = "Multiplier tuning parameter";
+ mt->shortTuningName[0] = "lambda";
+ mt->applicableTo[0] = CPPEVENTS;
+ mt->nApplicable = 1;
+ mt->moveFxn = &Move_CPPRateMultiplier_M;
+ mt->relProposalProb = 0.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 2.0 * log (1.1); /* lambda */
+ mt->minimum[0] = 0.0001;
+ mt->maximum[0] = 20.0; /* smaller */
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneMultiplier;
+ mt->targetRate = 0.25;
+
+ /* Move_CPPRateMultiplierRnd */
+ mt = &moveTypes[i++];
+ mt->name = "Random draw of CPP rate multiplier from prior";
+ mt->shortName = "Prior_draw_mult";
+ mt->applicableTo[0] = CPPEVENTS;
+ mt->nApplicable = 1;
+ mt->moveFxn = &Move_CPPRateMultiplierRnd;
+ mt->relProposalProb = 2.0;
+ mt->numTuningParams = 0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+
+ /* Move_Nu */
+ mt = &moveTypes[i++];
+ mt->name = "Multiplier";
+ mt->shortName = "Multiplier";
+ mt->tuningName[0] = "Multiplier tuning parameter";
+ mt->shortTuningName[0] = "lambda";
+ mt->applicableTo[0] = TK02VAR_EXP;
+ mt->applicableTo[1] = TK02VAR_UNI;
+ mt->nApplicable = 2;
+ mt->moveFxn = &Move_Nu;
+ mt->relProposalProb = 2.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 2.0 * log (1.1); /* lambda */
+ mt->minimum[0] = 0.0001;
+ mt->maximum[0] = 20.0; /* smaller */
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneMultiplier;
+ mt->targetRate = 0.25;
+
+ /* Move_TK02BranchRate */
+ mt = &moveTypes[i++];
+ mt->name = "Multiplier";
+ mt->shortName = "Multiplier";
+ mt->tuningName[0] = "Multiplier tuning parameter";
+ mt->shortTuningName[0] = "lambda";
+ mt->applicableTo[0] = TK02BRANCHRATES;
+ mt->nApplicable = 1;
+ mt->moveFxn = &Move_TK02BranchRate;
+ mt->relProposalProb = 10.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 2.0 * log (1.1); /* lambda */
+ mt->minimum[0] = 0.0001;
+ mt->maximum[0] = 20.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneMultiplier;
+ mt->targetRate = 0.25;
+
+ /* Move_IgrVar */
+ mt = &moveTypes[i++];
+ mt->name = "Multiplier";
+ mt->shortName = "Multiplier";
+ mt->tuningName[0] = "Multiplier tuning parameter";
+ mt->shortTuningName[0] = "lambda";
+ mt->applicableTo[0] = IGRVAR_EXP;
+ mt->applicableTo[1] = IGRVAR_UNI;
+ mt->nApplicable = 2;
+ mt->moveFxn = &Move_IgrVar;
+ mt->relProposalProb = 2.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 2.0 * log (1.1); /* lambda */
+ mt->minimum[0] = 0.0001;
+ mt->maximum[0] = 20.0; /* smaller */
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneMultiplier;
+ mt->targetRate = 0.25;
+
+ /* Move_IgrBranchRate */
+ mt = &moveTypes[i++];
+ mt->name = "Multiplier";
+ mt->shortName = "Multiplier";
+ mt->tuningName[0] = "Multiplier tuning parameter";
+ mt->shortTuningName[0] = "lambda";
+ mt->applicableTo[0] = IGRBRANCHRATES;
+ mt->nApplicable = 1;
+ mt->moveFxn = &Move_IgrBranchRate;
+ mt->relProposalProb = 10.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 2.0 * log (1.1); /* lambda */
+ mt->minimum[0] = 0.0001;
+ mt->maximum[0] = 20.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneMultiplier;
+ mt->targetRate = 0.25;
+
+ /* Move_MixedVar */
+ mt = &moveTypes[i++];
+ mt->name = "Multiplier";
+ mt->shortName = "Multiplier";
+ mt->tuningName[0] = "Multiplier tuning parameter";
+ mt->shortTuningName[0] = "lambda";
+ mt->applicableTo[0] = MIXEDVAR_EXP;
+ mt->applicableTo[1] = MIXEDVAR_UNI;
+ mt->nApplicable = 2;
+ mt->moveFxn = &Move_MixedVar;
+ mt->relProposalProb = 2.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 2.0 * log (1.1); /* lambda */
+ mt->minimum[0] = 0.0001;
+ mt->maximum[0] = 20.0; /* smaller */
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneMultiplier;
+ mt->targetRate = 0.25;
+
+ /* Move_MixedBranchRate */
+ mt = &moveTypes[i++];
+ mt->name = "Multiplier";
+ mt->shortName = "Multiplier";
+ mt->tuningName[0] = "Multiplier tuning parameter";
+ mt->shortTuningName[0] = "lambda";
+ mt->applicableTo[0] = MIXEDBRCHRATES;
+ mt->nApplicable = 1;
+ mt->moveFxn = &Move_MixedBranchRate;
+ mt->relProposalProb = 10.0;
+ mt->numTuningParams = 1;
+ mt->tuningParam[0] = 2.0 * log (1.1); /* lambda */
+ mt->minimum[0] = 0.0001;
+ mt->maximum[0] = 20.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+ mt->Autotune = &AutotuneMultiplier;
+ mt->targetRate = 0.25;
+
+ /* Move_RelaxedClockModel */
+ mt = &moveTypes[i++];
+ mt->name = "rjMCMC among Relaxed Clock Models";
+ mt->shortName = "rjMCMC_RCL";
+ mt->tuningName[0] = "sigma_TK over sigma_IGR";
+ mt->shortTuningName[0] = "ratio";
+ mt->tuningName[1] = "Sliding window size";
+ mt->shortTuningName[1] = "delta";
+ mt->applicableTo[0] = MIXEDBRCHRATES;
+ mt->nApplicable = 1;
+ mt->moveFxn = &Move_RelaxedClockModel;
+ mt->relProposalProb = 5.0;
+ mt->numTuningParams = 2;
+ mt->tuningParam[0] = 100.0; /* TK/IGR var ratio */
+ mt->tuningParam[1] = 10.0; /* window size */
+ mt->minimum[0] = 0.0001;
+ mt->maximum[0] = 10000.0;
+ mt->minimum[1] = 0.0001;
+ mt->maximum[1] = 1000.0;
+ mt->parsimonyBased = NO;
+ mt->level = STANDARD_USER;
+
+ numMoveTypes = i;
+}
+
+
+/* ShowModel: Display model on screen */
+int ShowModel (void)
+{
+ int i, j, ns;
+
+ MrBayesPrint ("%s Model settings:\n\n", spacer);
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ ns = 0;
+
+ if (numCurrentDivisions > 1)
+ MrBayesPrint ("%s Settings for partition %d --\n", spacer, i+1);
+ else
+ MrBayesPrint ("%s Data not partitioned --\n", spacer);
+
+ if (modelParams[i].dataType == DNA)
+ {
+ MrBayesPrint ("%s Datatype = DNA\n", spacer);
+ ns = 4;
+ }
+ else if (modelParams[i].dataType == RNA)
+ {
+ MrBayesPrint ("%s Datatype = RNA\n", spacer);
+ ns = 4;
+ }
+ else if (modelParams[i].dataType == PROTEIN)
+ {
+ MrBayesPrint ("%s Datatype = Protein\n", spacer);
+ ns = 20;
+ }
+ else if (modelParams[i].dataType == RESTRICTION)
+ {
+ MrBayesPrint ("%s Datatype = Restriction\n", spacer);
+ ns = 2;
+ }
+ else if (modelParams[i].dataType == STANDARD)
+ {
+ MrBayesPrint ("%s Datatype = Standard\n", spacer);
+ ns = 10;
+ }
+ else if (modelParams[i].dataType == CONTINUOUS)
+ {
+ MrBayesPrint ("%s Datatype = Continuous\n", spacer);
+ }
+
+ if (modelSettings[i].dataType == CONTINUOUS)
+ {
+ /* begin description of continuous models */
+ if (!strcmp(modelParams[i].brownCorPr, "Fixed") && AreDoublesEqual(modelParams[i].brownCorrFix, 0.0, ETA)==YES)
+ MrBayesPrint ("%s Model = Independent Brownian motion\n", spacer);
+ else
+ MrBayesPrint ("%s Model = Correlated Brownian motion\n", spacer);
+ /* end description of continuous models */
+ }
+ else
+ {
+ /* begin description of discrete models */
+ if (!strcmp(modelParams[i].parsModel, "Yes"))
+ {
+ MrBayesPrint ("%s Parsmodel = %s\n", spacer, modelParams[i].parsModel);
+ }
+ else
+ {
+ /* dna characters in this partition */
+ if (modelSettings[i].dataType == DNA || modelSettings[i].dataType == RNA)
+ {
+ /* general form of the rate matrix */
+ MrBayesPrint ("%s Nucmodel = %s\n", spacer, modelParams[i].nucModel);
+
+ /* constraints on rates of substitution */
+ MrBayesPrint ("%s Nst = %s\n", spacer, modelParams[i].nst);
+ if (!strcmp(modelParams[i].nst, "2"))
+ {
+ if (!strcmp(modelParams[i].tRatioPr,"Beta"))
+ {
+ MrBayesPrint ("%s Transition and transversion rates, expressed\n", spacer);
+ MrBayesPrint ("%s as proportions of the rate sum, have a\n", spacer);
+ MrBayesPrint ("%s Beta(%1.2lf,%1.2lf) prior\n", spacer, modelParams[i].tRatioDir[0], modelParams[i].tRatioDir[1]);
+ }
+ else
+ {
+ MrBayesPrint ("%s Transition/transversion rate ratio is fixed to %1.2lf.\n", spacer, modelParams[i].tRatioFix);
+ }
+ }
+ else if (!strcmp(modelParams[i].nst, "6"))
+ {
+ if (!strcmp(modelParams[i].revMatPr,"Dirichlet"))
+ {
+ MrBayesPrint ("%s Substitution rates, expressed as proportions\n", spacer);
+ MrBayesPrint ("%s of the rate sum, have a Dirichlet prior\n", spacer);
+ MrBayesPrint ("%s (%1.2lf,%1.2lf,%1.2lf,%1.2lf,%1.2lf,%1.2lf)\n", spacer,
+ modelParams[i].revMatDir[0], modelParams[i].revMatDir[1], modelParams[i].revMatDir[2],
+ modelParams[i].revMatDir[3], modelParams[i].revMatDir[4], modelParams[i].revMatDir[5]);
+ }
+ else
+ {
+ MrBayesPrint ("%s Substitution rates are fixed to be \n", spacer);
+ MrBayesPrint ("%s (%1.2lf,%1.2lf,%1.2lf,%1.2lf,%1.2lf,%1.2lf).\n", spacer,
+ modelParams[i].revMatFix[0], modelParams[i].revMatFix[1], modelParams[i].revMatFix[2],
+ modelParams[i].revMatFix[3], modelParams[i].revMatFix[4], modelParams[i].revMatFix[5]);
+ }
+ }
+ else if (!strcmp(modelParams[i].nst, "Mixed"))
+ {
+ if (!strcmp(modelParams[i].revMatPr,"Dirichlet"))
+ {
+ MrBayesPrint ("%s Substitution rates, expressed as proportions\n", spacer);
+ MrBayesPrint ("%s of the rate sum, have a Dirichlet prior\n", spacer);
+ MrBayesPrint ("%s (%1.2lf,%1.2lf,%1.2lf,%1.2lf,%1.2lf,%1.2lf)\n", spacer,
+ modelParams[i].revMatDir[0], modelParams[i].revMatDir[1], modelParams[i].revMatDir[2],
+ modelParams[i].revMatDir[3], modelParams[i].revMatDir[4], modelParams[i].revMatDir[5]);
+ }
+ else
+ {
+ MrBayesPrint ("%s Substitution rates are fixed to be \n", spacer);
+ MrBayesPrint ("%s (%1.2lf,%1.2lf,%1.2lf,%1.2lf,%1.2lf,%1.2lf).\n", spacer,
+ modelParams[i].revMatFix[0], modelParams[i].revMatFix[1], modelParams[i].revMatFix[2],
+ modelParams[i].revMatFix[3], modelParams[i].revMatFix[4], modelParams[i].revMatFix[5]);
+ }
+ }
+
+ if (!strcmp(modelParams[i].nucModel,"Codon"))
+ {
+ /* what is the distribution on the nonsyn./syn. rate ratio */
+ if (!strcmp(modelParams[i].omegaVar, "Equal"))
+ {
+ if (!strcmp(modelParams[i].omegaPr,"Dirichlet"))
+ {
+ MrBayesPrint ("%s Nonsynonymous and synonymous rates, expressed\n", spacer);
+ MrBayesPrint ("%s as proportions of the rate sum, have a\n", spacer);
+ MrBayesPrint ("%s Dirichlet(%1.2lf,%1.2lf) prior\n", spacer, modelParams[i].omegaDir[0], modelParams[i].omegaDir[1]);
+ }
+ else
+ {
+ MrBayesPrint ("%s Nonsynonymous/synonymous rate ratio is fixed to %1.2lf.\n", spacer, modelParams[i].omegaFix);
+ }
+ }
+ else if (!strcmp(modelParams[i].omegaVar, "Ny98"))
+ {
+ if (!strcmp(modelParams[i].ny98omega1pr, "Beta"))
+ {
+ MrBayesPrint ("%s Nonsynonymous/synonymous rate ratio for purifying selection\n", spacer);
+ MrBayesPrint ("%s (class 1) has a Beta(%1.2lf,%1.2lf) on the interval (0,1).\n", spacer, modelParams[i].ny98omega1Beta[0], modelParams[i].ny98omega1Beta[1]);
+ }
+ else
+ {
+ MrBayesPrint ("%s Nonsynonymous/synonymous rate ratio for purifying selection\n", spacer);
+ MrBayesPrint ("%s (class 1) is fixed to %1.2lf.\n", spacer, modelParams[i].ny98omega1Fixed);
+ }
+ MrBayesPrint ("%s Nonsynonymous/synonymous rate ratio for neutral selection\n", spacer);
+ MrBayesPrint ("%s (class 2) is fixed to 1.0.\n", spacer);
+ if (!strcmp(modelParams[i].ny98omega3pr, "Uniform"))
+ {
+ MrBayesPrint ("%s Nonsynonymous/synonymous rate ratio for positive selection\n", spacer);
+ MrBayesPrint ("%s is uniformly distributed on the interval (%1.2lf,%1.2lf).\n", spacer, modelParams[i].ny98omega3Uni[0], modelParams[i].ny98omega3Uni[1]);
+ }
+ else if (!strcmp(modelParams[i].ny98omega3pr, "Exponential"))
+ {
+ MrBayesPrint ("%s Nonsynonymous/synonymous rate ratio for positive selection\n", spacer);
+ MrBayesPrint ("%s is exponentially distributed with parameter (%1.2lf).\n", spacer, modelParams[i].ny98omega3Exp);
+ }
+ else
+ {
+ MrBayesPrint ("%s Nonsynonymous/synonymous rate ratio for positive \n", spacer);
+ MrBayesPrint ("%s selection is fixed to %1.2lf.\n", spacer, modelParams[i].ny98omega3Fixed);
+ }
+ }
+ else if (!strcmp(modelParams[i].omegaVar, "M3"))
+ {
+ if (!strcmp(modelParams[i].m3omegapr, "Exponential"))
+ {
+ MrBayesPrint ("%s Nonsynonymous and synonymous rates for the tree classes of\n", spacer);
+ MrBayesPrint ("%s omega are exponentially distributed random variables.\n", spacer);
+ }
+ else if (!strcmp(modelParams[i].m3omegapr, "Fixed"))
+ {
+ MrBayesPrint ("%s Nonsynonymous/synonymous rate ratio for the three omega\n", spacer);
+ MrBayesPrint ("%s are fixed to %1.2lf, %1.2lf, and %1.2lf.\n", spacer, modelParams[i].m3omegaFixed[0], modelParams[i].m3omegaFixed[1], modelParams[i].m3omegaFixed[2]);
+ }
+ }
+ else if (!strcmp(modelParams[i].omegaVar, "M10"))
+ {
+ MrBayesPrint ("%s Nonsynonymous/synonymous rate ratio for purifying \n", spacer);
+ MrBayesPrint ("%s selection (class 1) has a Beta(alpha1,beta1) on the \n", spacer);
+ MrBayesPrint ("%s interval (0,1). Nonsynonymous/synonymous rate ratio \n", spacer);
+ MrBayesPrint ("%s for positive selection (class 2) has an offset \n", spacer);
+ MrBayesPrint ("%s Gamma(alpha2,beta2) on the interval (1,Infinity).\n", spacer);
+ }
+
+ /* genetic code that is used (if nucmodel=codon) */
+ MrBayesPrint ("%s Code = %s\n", spacer, modelParams[i].geneticCode);
+ }
+ }
+ /* amino acid characters in this partition */
+ else if (modelSettings[i].dataType == PROTEIN)
+ {
+ if (modelParams[i].dataType == DNA || modelParams[i].dataType == RNA)
+ MrBayesPrint ("%s Nucmodel = %s\n", spacer, modelParams[i].nucModel);
+ /* constraints on rates of substitution in 20 X 20 matrix */
+ if (!strcmp(modelParams[i].aaModelPr, "Mixed"))
+ MrBayesPrint ("%s Aamodel = Mixture of models with fixed rate matrices\n", spacer);
+ else
+ MrBayesPrint ("%s Aamodel = %s\n", spacer, modelParams[i].aaModel);
+ /* revmat rates */
+ if (!strcmp(modelParams[i].aaModelPr, "Mixed"))
+ MrBayesPrint ("%s Substitution rates come from the mixture of models\n", spacer);
+ else if (!strcmp(modelParams[i].aaModelPr, "Fixed") && (!strcmp(modelParams[i].aaModel, "Poisson") ||
+ !strcmp(modelParams[i].aaModel, "Equalin")))
+ MrBayesPrint ("%s Substitution rates are fixed to be equal\n", spacer);
+ else if (!strcmp(modelParams[i].aaModelPr, "Fixed") && strcmp(modelParams[i].aaModel, "Gtr")!=0)
+ MrBayesPrint ("%s Substitution rates are fixed to the %s rates\n", spacer, modelParams[i].aaModel);
+ else if (!strcmp(modelParams[i].aaModelPr, "Fixed") && !strcmp(modelParams[i].aaModel, "Gtr"))
+ {
+ if (!strcmp(modelParams[i].aaRevMatPr,"Dirichlet"))
+ {
+ for (j=0; j<190; j++)
+ if (AreDoublesEqual(modelParams[i].aaRevMatDir[0], modelParams[i].aaRevMatDir[j], 0.00001) == NO)
+ break;
+ if (j == 190)
+ {
+ MrBayesPrint ("%s Substitution rates have a Dirichlet(%1.2lf,%1.2lf,...) prior\n",
+ spacer, modelParams[i].aaRevMatDir[0], modelParams[i].aaRevMatDir[0]);
+ }
+ else
+ {
+ MrBayesPrint ("%s Substitution rates have a Dirichlet(\n", spacer);
+ for (j=0; j<190; j++)
+ {
+ if (j % 10 == 0)
+ MrBayesPrint ("%s ", spacer);
+ MrBayesPrint ("%1.2lf", modelParams[i].aaRevMatDir[j]);
+ if (j == 189)
+ MrBayesPrint (") prior\n");
+ else if ((j+1) % 10 == 0)
+ MrBayesPrint (",\n");
+ else
+ MrBayesPrint (",");
+ }
+ }
+ }
+ else /* if (!strcmp(modelParams[i].aaRevMatPr,"Fixed")) */
+ {
+ for (j=0; j<190; j++)
+ if (AreDoublesEqual(modelParams[i].aaRevMatFix[0], modelParams[i].aaRevMatFix[j], 0.00001) == NO)
+ break;
+ if (j == 190)
+ {
+ MrBayesPrint ("%s Substitution rates are fixed to (%1.1lf,%1.1lf,...)\n",
+ spacer, modelParams[i].aaRevMatFix[0], modelParams[i].aaRevMatFix[0]);
+ }
+ else
+ {
+ MrBayesPrint ("%s Substitution rates are fixed to (\n", spacer);
+ for (j=0; j<190; j++)
+ {
+ if (j % 10 == 0)
+ MrBayesPrint ("%s ", spacer);
+ MrBayesPrint ("%1.1lf", modelParams[i].aaRevMatFix[j]);
+ if (j == 189)
+ MrBayesPrint (") prior\n");
+ else if ((j+1) % 10 == 0)
+ MrBayesPrint (",\n");
+ else
+ MrBayesPrint (",");
+ }
+ }
+ }
+ }
+ }
+ /* restriction site or morphological characters in this partition */
+ else if (modelSettings[i].dataType == RESTRICTION || modelSettings[i].dataType == STANDARD)
+ {
+ /* what type of characters are sampled? */
+ MrBayesPrint ("%s Coding = %s\n", spacer, modelParams[i].codingString);
+ }
+
+ /* is there rate variation in a single site across the tree? */
+ if (((modelSettings[i].dataType == DNA || modelSettings[i].dataType == RNA) && !strcmp(modelParams[i].nucModel, "4by4")) || modelSettings[i].dataType == PROTEIN)
+ {
+ /* do rates change on tree accoding to covarion model? */
+ MrBayesPrint ("%s Covarion = %s\n", spacer, modelParams[i].covarionModel);
+ if (!strcmp(modelParams[i].covarionModel, "Yes"))
+ {
+ /* distribution on switching parameters, if appropriate */
+ if (!strcmp(modelParams[i].covSwitchPr,"Uniform"))
+ {
+ MrBayesPrint ("%s Switching rates have independent uniform dist-\n", spacer);
+ MrBayesPrint ("%s ributions on the interval (%1.2lf,%1.2lf).\n", spacer, modelParams[i].covswitchUni[0], modelParams[i].covswitchUni[1]);
+ }
+ else if (!strcmp(modelParams[i].covSwitchPr,"Exponential"))
+ {
+ MrBayesPrint ("%s Switching rates have independent exponential\n", spacer);
+ MrBayesPrint ("%s distributions with parameters (%1.2lf).\n", spacer, modelParams[i].covswitchExp);
+ }
+ else
+ {
+ MrBayesPrint ("%s Switching rates are fixed to %1.2lf and %1.2lf.\n", spacer, modelParams[i].covswitchFix[0], modelParams[i].covswitchFix[0]);
+ }
+ ns *= 2;
+ }
+ }
+
+ /* now, let's deal with variation in omega */
+ if ((modelParams[i].dataType == DNA || modelParams[i].dataType == RNA) && !strcmp(modelParams[i].nucModel,"Codon"))
+ {
+ MrBayesPrint ("%s Omegavar = %s\n", spacer, modelParams[i].omegaVar);
+ if (!strcmp(modelParams[i].geneticCode, "Universal"))
+ ns = 61;
+ else if (!strcmp(modelParams[i].geneticCode, "Vertmt"))
+ ns = 60;
+ else if (!strcmp(modelParams[i].geneticCode, "Invermt"))
+ ns = 62;
+ else if (!strcmp(modelParams[i].geneticCode, "Mycoplasma"))
+ ns = 62;
+ else if (!strcmp(modelParams[i].geneticCode, "Yeast"))
+ ns = 62;
+ else if (!strcmp(modelParams[i].geneticCode, "Ciliate"))
+ ns = 63;
+ else if (!strcmp(modelParams[i].geneticCode, "Echinoderm"))
+ ns = 62;
+ else if (!strcmp(modelParams[i].geneticCode, "Euplotid"))
+ ns = 62;
+ else if (!strcmp(modelParams[i].geneticCode, "Metmt"))
+ ns = 62;
+ }
+
+ /* what assumptions are made about the state frequencies? */
+ if (modelParams[i].dataType != CONTINUOUS)
+ {
+ if (modelParams[i].dataType == STANDARD)
+ MrBayesPrint ("%s # States = Variable, up to 10\n", spacer);
+ else if (modelSettings[i].numStates != modelSettings[i].numModelStates)
+ MrBayesPrint ("%s # States = %d (in the model)\n", spacer, modelSettings[i].numModelStates);
+ else
+ MrBayesPrint ("%s # States = %d\n", spacer, ns);
+ if (modelSettings[i].dataType == STANDARD)
+ {
+ if (!strcmp(modelParams[i].symPiPr,"Fixed"))
+ {
+ if (AreDoublesEqual(modelParams[i].symBetaFix, -1.0, ETA)==YES)
+ MrBayesPrint ("%s State frequencies are fixed to be equal\n", spacer);
+ else
+ MrBayesPrint ("%s Symmetric Dirichlet alpha is fixed to %1.2lf\n", spacer, modelParams[i].symBetaFix);
+ }
+ else if (!strcmp(modelParams[i].symPiPr,"Uniform"))
+ {
+ MrBayesPrint ("%s Symmetric Dirichlet alpha has a Uniform(%1.2lf,%1.2lf) prior\n", spacer, modelParams[i].symBetaUni[0], modelParams[i].symBetaUni[1]);
+ }
+ else
+ {
+ MrBayesPrint ("%s Symmetric Dirichlet alpha has a Exponential(%1.2lf) prior\n", spacer, modelParams[i].symBetaExp);
+ }
+ }
+ else if (modelSettings[i].dataType == RESTRICTION)
+ {
+ /* distribution on state frequencies for restriction site model */
+ if (!strcmp(modelParams[i].stateFreqPr,"Dirichlet"))
+ {
+ MrBayesPrint ("%s State frequencies have a Dirichlet (%1.2lf,%1.2lf) prior\n", spacer,
+ modelParams[i].stateFreqsDir[0], modelParams[i].stateFreqsDir[1]);
+ }
+ else if (!strcmp(modelParams[i].stateFreqPr,"Fixed") && !strcmp(modelParams[i].stateFreqsFixType,"Equal"))
+ {
+ MrBayesPrint ("%s State frequencies are fixed to be equal\n", spacer);
+ }
+ else if (!strcmp(modelParams[i].stateFreqPr,"Fixed") && !strcmp(modelParams[i].stateFreqsFixType,"User"))
+ {
+ MrBayesPrint ("%s State frequencies have been fixed by the user\n", spacer);
+ }
+ else if (!strcmp(modelParams[i].stateFreqPr,"Fixed") && !strcmp(modelParams[i].stateFreqsFixType,"Empirical"))
+ {
+ MrBayesPrint ("%s State frequencies have been fixed to the empirical frequencies in the data\n", spacer);
+ }
+ }
+ else if (modelSettings[i].dataType == PROTEIN)
+ {
+ /* distribution on state frequencies for aminoacid model */
+ if (!strcmp(modelParams[i].aaModelPr, "Fixed") && (strcmp(modelParams[i].aaModel, "Equalin")==0 ||
+ strcmp(modelParams[i].aaModel, "Gtr")==0))
+ {
+ if (!strcmp(modelParams[i].stateFreqPr,"Dirichlet"))
+ {
+ MrBayesPrint ("%s State frequencies have a Dirichlet prior\n", spacer);
+ MrBayesPrint ("%s (%1.2lf,%1.2lf,%1.2lf,%1.2lf,%1.2lf,", spacer,
+ modelParams[i].stateFreqsDir[0], modelParams[i].stateFreqsDir[1], modelParams[i].stateFreqsDir[2],
+ modelParams[i].stateFreqsDir[3], modelParams[i].stateFreqsDir[4]);
+ MrBayesPrint ("%1.2lf,%1.2lf,%1.2lf,%1.2lf,%1.2lf,\n",
+ modelParams[i].stateFreqsDir[5], modelParams[i].stateFreqsDir[6], modelParams[i].stateFreqsDir[7],
+ modelParams[i].stateFreqsDir[8], modelParams[i].stateFreqsDir[9]);
+ MrBayesPrint ("%s %1.2lf,%1.2lf,%1.2lf,%1.2lf,%1.2lf,", spacer,
+ modelParams[i].stateFreqsDir[10], modelParams[i].stateFreqsDir[11], modelParams[i].stateFreqsDir[12],
+ modelParams[i].stateFreqsDir[13], modelParams[i].stateFreqsDir[14]);
+ MrBayesPrint ("%1.2lf,%1.2lf,%1.2lf,%1.2lf,%1.2lf)\n",
+ modelParams[i].stateFreqsDir[15], modelParams[i].stateFreqsDir[16], modelParams[i].stateFreqsDir[17],
+ modelParams[i].stateFreqsDir[18], modelParams[i].stateFreqsDir[19]);
+ }
+ else if (!strcmp(modelParams[i].stateFreqPr,"Fixed") && !strcmp(modelParams[i].stateFreqsFixType,"Equal"))
+ {
+ MrBayesPrint ("%s State frequencies are fixed to be equal\n", spacer);
+ }
+ else if (!strcmp(modelParams[i].stateFreqPr,"Fixed") && !strcmp(modelParams[i].stateFreqsFixType,"User"))
+ {
+ MrBayesPrint ("%s State frequencies have been fixed by the user\n", spacer);
+ }
+ else if (!strcmp(modelParams[i].stateFreqPr,"Fixed") && !strcmp(modelParams[i].stateFreqsFixType,"Empirical"))
+ {
+ MrBayesPrint ("%s State frequencies have been fixed to the empirical frequencies in the data\n", spacer);
+ }
+ }
+ else if (!strcmp(modelParams[i].aaModelPr, "Fixed") && !strcmp(modelParams[i].aaModel, "Poisson"))
+ {
+ MrBayesPrint ("%s State frequencies are fixed to be equal\n", spacer);
+ }
+ else if (!strcmp(modelParams[i].aaModelPr, "Fixed") && strcmp(modelParams[i].aaModel, "Equalin") && strcmp(modelParams[i].aaModel, "Poisson"))
+ {
+ MrBayesPrint ("%s State frequencies are fixed to the %s frequencies\n", spacer, modelParams[i].aaModel);
+ }
+ else
+ {
+ MrBayesPrint ("%s State frequencies come from the mixture of models\n", spacer);
+ }
+ }
+ else
+ {
+ /* distribution on state frequencies for all other models */
+ if (!strcmp(modelParams[i].stateFreqPr,"Dirichlet"))
+ {
+ MrBayesPrint ("%s State frequencies have a Dirichlet prior\n", spacer);
+ if (!strcmp(modelParams[i].nucModel, "Doublet"))
+ {
+ MrBayesPrint ("%s (%1.2lf,%1.2lf,%1.2lf,%1.2lf,\n", spacer,
+ modelParams[i].stateFreqsDir[0], modelParams[i].stateFreqsDir[1], modelParams[i].stateFreqsDir[2],
+ modelParams[i].stateFreqsDir[3]);
+ MrBayesPrint ("%s %1.2lf,%1.2lf,%1.2lf,%1.2lf,\n", spacer,
+ modelParams[i].stateFreqsDir[4], modelParams[i].stateFreqsDir[5], modelParams[i].stateFreqsDir[6],
+ modelParams[i].stateFreqsDir[7]);
+ MrBayesPrint ("%s %1.2lf,%1.2lf,%1.2lf,%1.2lf,\n", spacer,
+ modelParams[i].stateFreqsDir[8], modelParams[i].stateFreqsDir[9], modelParams[i].stateFreqsDir[10],
+ modelParams[i].stateFreqsDir[11]);
+ MrBayesPrint ("%s %1.2lf,%1.2lf,%1.2lf,%1.2lf)\n", spacer,
+ modelParams[i].stateFreqsDir[12], modelParams[i].stateFreqsDir[13], modelParams[i].stateFreqsDir[14],
+ modelParams[i].stateFreqsDir[15]);
+ }
+ else if (!strcmp(modelParams[i].nucModel, "4by4"))
+ {
+ MrBayesPrint ("%s (%1.2lf,%1.2lf,%1.2lf,%1.2lf)\n", spacer,
+ modelParams[i].stateFreqsDir[0], modelParams[i].stateFreqsDir[1], modelParams[i].stateFreqsDir[2],
+ modelParams[i].stateFreqsDir[3]);
+ }
+ }
+ else if (!strcmp(modelParams[i].stateFreqPr,"Fixed") && !strcmp(modelParams[i].stateFreqsFixType,"Equal"))
+ {
+ MrBayesPrint ("%s State frequencies are fixed to be equal\n", spacer);
+ }
+ else if (!strcmp(modelParams[i].stateFreqPr,"Fixed") && !strcmp(modelParams[i].stateFreqsFixType,"User"))
+ {
+ MrBayesPrint ("%s State frequencies have been fixed by the user\n", spacer);
+ }
+ else if (!strcmp(modelParams[i].stateFreqPr,"Fixed") && !strcmp(modelParams[i].stateFreqsFixType,"Empirical"))
+ {
+ MrBayesPrint ("%s State frequencies have been fixed to the empirical frequencies in the data\n", spacer);
+ }
+ }
+ }
+ else
+ MrBayesPrint ("%s # States = Infinity\n", spacer);
+
+ /* now, let's deal with rate variation across sites */
+ if (modelSettings[i].dataType != CONTINUOUS)
+ {
+ if (((modelSettings[i].dataType == DNA || modelSettings[i].dataType == RNA) && strcmp(modelParams[i].nucModel,"Codon")) ||
+ modelSettings[i].dataType == PROTEIN || modelSettings[i].dataType == RESTRICTION || modelSettings[i].dataType == STANDARD)
+ {
+ if (!strcmp(modelParams[i].covarionModel, "No"))
+ MrBayesPrint ("%s Rates = %s\n", spacer, modelParams[i].ratesModel);
+ else
+ {
+ if (!strcmp(modelParams[i].ratesModel, "Propinv"))
+ MrBayesPrint ("%s Rates = Equal ", spacer);
+ else if (!strcmp(modelParams[i].ratesModel, "Invgamma"))
+ MrBayesPrint ("%s Rates = Gamma ", spacer);
+ else
+ MrBayesPrint ("%s Rates = %s ", spacer, modelParams[i].ratesModel);
+ MrBayesPrint ("(+ Propinv induced by covarion model)\n");
+ }
+
+ if ((modelParams[i].dataType == RESTRICTION || modelParams[i].dataType == STANDARD) && !strcmp(modelParams[i].ratesModel, "Adgamma"))
+ {
+
+ }
+ else
+ {
+ if (!strcmp(modelParams[i].ratesModel, "Gamma") || !strcmp(modelParams[i].ratesModel, "Invgamma") ||
+ !strcmp(modelParams[i].ratesModel, "LNorm") || !strcmp(modelParams[i].ratesModel, "Adgamma"))
+ {
+ /* how many categories is the continuous gamma approximated by? */
+ MrBayesPrint ("%s The distribution is approximated using %d categories.\n", spacer, modelParams[i].numGammaCats);
+ if (!strcmp(modelParams[i].useGibbs,"Yes"))
+ MrBayesPrint ("%s Rate categories sampled using Gibbs sampling.\n", spacer, modelParams[i].numGammaCats);
+ else
+ MrBayesPrint ("%s Likelihood summarized over all rate categories in each generation.\n", spacer, modelParams[i].numGammaCats);
+ /* distribution on shape parameter, if appropriate */
+ if (!strcmp(modelParams[i].shapePr,"Uniform"))
+ {
+ MrBayesPrint ("%s Shape parameter is uniformly distributed\n", spacer);
+ MrBayesPrint ("%s on the interval (%1.2lf,%1.2lf).\n", spacer, modelParams[i].shapeUni[0], modelParams[i].shapeUni[1]);
+ }
+ else if (!strcmp(modelParams[i].shapePr,"Exponential"))
+ {
+ MrBayesPrint ("%s Shape parameter is exponentially\n", spacer);
+ MrBayesPrint ("%s distributed with parameter (%1.2lf).\n", spacer, modelParams[i].shapeExp);
+ }
+ else
+ {
+ MrBayesPrint ("%s Shape parameter is fixed to %1.2lf.\n", spacer, modelParams[i].shapeFix);
+ }
+ }
+ if ((!strcmp(modelParams[i].ratesModel, "Propinv") || !strcmp(modelParams[i].ratesModel, "Invgamma")) && !strcmp(modelParams[i].covarionModel, "No"))
+ {
+ /* distribution on pInvar parameter, if appropriate */
+ if (!strcmp(modelParams[i].pInvarPr,"Uniform"))
+ {
+ MrBayesPrint ("%s Proportion of invariable sites is uniformly dist-\n", spacer);
+ MrBayesPrint ("%s ributed on the interval (%1.2lf,%1.2lf).\n", spacer, modelParams[i].pInvarUni[0], modelParams[i].pInvarUni[1]);
+ }
+ else
+ {
+ MrBayesPrint ("%s Proportion of invariable sites is fixed to %1.2lf.\n", spacer, modelParams[i].pInvarFix);
+ }
+ }
+ if (!strcmp(modelParams[i].ratesModel, "Adgamma"))
+ {
+ /* distribution on correlation parameter, if appropriate */
+ if (!strcmp(modelParams[i].adGammaCorPr,"Uniform"))
+ {
+ MrBayesPrint ("%s Rate correlation parameter is uniformly dist-\n", spacer);
+ MrBayesPrint ("%s ributed on the interval (%1.2lf,%1.2lf).\n", spacer, modelParams[i].corrUni[0], modelParams[i].corrUni[1]);
+ }
+ else
+ {
+ MrBayesPrint ("%s Rate correlation parameter is fixed to %1.2lf.\n", spacer, modelParams[i].corrFix);
+ }
+ }
+ }
+ }
+ }
+ }
+ /* end description of discrete models */
+ }
+
+ if (i != numCurrentDivisions - 1)
+ MrBayesPrint ("\n");
+
+ }
+
+ MrBayesPrint ("\n");
+ ShowParameters (NO, NO, NO);
+
+ return (NO_ERROR);
+}
+
+
+/*------------------------------------------------------------------------------
+|
+| ShowMoves: Show applicable moves
+|
+------------------------------------------------------------------------------*/
+int ShowMoves (int used)
+{
+ int i, k, run, chain, chainIndex, areRunsSame, areChainsSame, numPrintedMoves;
+ MCMCMove *mv;
+
+ chainIndex = 0;
+ numPrintedMoves = 0;
+ for (i=0; i<numApplicableMoves; i++)
+ {
+ mv = moves[i];
+
+ for (k=0; k<numGlobalChains; k++)
+ {
+ if (mv->relProposalProb[k] > 0.000001)
+ break;
+ }
+
+ if (k == numGlobalChains && used == YES)
+ continue;
+
+ if (k < numGlobalChains && used == NO)
+ continue;
+
+ numPrintedMoves++;
+
+ /* print move number and name */
+ MrBayesPrint ("%s %4d -- Move = %s\n", spacer, numPrintedMoves, mv->name);
+
+ /* print move type */
+ MrBayesPrint ("%s Type = %s\n", spacer, mv->moveType->name);
+
+ /* print parameter */
+ if (mv->parm->nSubParams > 0)
+ MrBayesPrint ("%s Parameters = %s [param. %d] (%s)\n", spacer, mv->parm->name,
+ mv->parm->index+1, mv->parm->paramTypeName);
+ else
+ MrBayesPrint ("%s Parameter = %s [param. %d] (%s)\n", spacer, mv->parm->name,
+ mv->parm->index+1, mv->parm->paramTypeName);
+ for (k=0; k<mv->parm->nSubParams; k++)
+ MrBayesPrint ("%s %s [param. %d] (%s)\n", spacer, mv->parm->subParams[k]->name,
+ mv->parm->subParams[k]->index+1, mv->parm->subParams[k]->paramTypeName);
+
+ /* print tuning parameters */
+ for (k=0; k<mv->moveType->numTuningParams; k++)
+ {
+ if (k==0)
+ MrBayesPrint ("%s Tuningparam = %s (%s)\n", spacer, mv->moveType->shortTuningName[k], mv->moveType->tuningName[k]);
+ else
+ MrBayesPrint ("%s %s (%s)\n", spacer, mv->moveType->shortTuningName[k], mv->moveType->tuningName[k]);
+ }
+
+ /* loop over tuning parameters */
+ for (k=0; k<mv->moveType->numTuningParams; k++)
+ {
+ /* find if tuning parameters are different for different runs */
+ areRunsSame = YES;
+ for (run=1; run<chainParams.numRuns; run++)
+ {
+ for (chain=0; chain<chainParams.numChains; chain++)
+ {
+ chainIndex = run*chainParams.numChains + chain;
+ if (AreDoublesEqual (mv->tuningParam[chainIndex][k], mv->tuningParam[chain][k], 0.000001) == NO)
+ {
+ areRunsSame = NO;
+ break;
+ }
+ }
+ if (areRunsSame == NO)
+ break;
+ }
+
+ /* now print values */
+ for (run=0; run<chainParams.numRuns; run++)
+ {
+ if (areRunsSame == YES && run >= 1)
+ break;
+
+ /* find out if chains are different within this run */
+ areChainsSame = YES;
+ for (chain=1; chain<chainParams.numChains; chain++)
+ {
+ chainIndex = run*chainParams.numChains + chain;
+ if (AreDoublesEqual (mv->tuningParam[chainIndex][k], mv->tuningParam[chainIndex-chain][k],0.000001) == NO)
+ {
+ areChainsSame = NO;
+ break;
+ }
+ }
+ /* now we can print the values */
+ for (chain=0; chain<chainParams.numChains; chain++)
+ {
+ chainIndex = run*chainParams.numChains + chain;
+ if (areChainsSame == YES && chain >= 1)
+ break;
+
+ if (run == 0 && chain == 0)
+ MrBayesPrint ("%s%22s = %1.3lf", spacer, mv->moveType->shortTuningName[k], mv->tuningParam[chainIndex][k]);
+ else
+ MrBayesPrint ("%s %1.3lf", spacer, mv->tuningParam[chainIndex][k]);
+
+ if (areChainsSame == NO && areRunsSame == YES)
+ MrBayesPrint (" [chain %d]\n", chain+1);
+ else if (areChainsSame == YES && areRunsSame == NO)
+ MrBayesPrint (" [run %d]\n", run+1);
+ else if (areChainsSame == NO && areRunsSame == NO)
+ MrBayesPrint (" [run %d, chain %d]\n", run+1, chain+1);
+ else
+ MrBayesPrint ("\n");
+ }
+ }
+ } /* next tuning parameter */
+
+ /* print target acceptance rate for autotuning */
+ if (mv->moveType->targetRate > 0.0 && mv->moveType->targetRate < 1.0)
+ {
+
+ /* first find out if the targets are different in different runs */
+ areRunsSame = YES;
+ for (run=1; run<chainParams.numRuns; run++)
+ {
+ for (chain=0; chain<chainParams.numChains; chain++)
+ {
+ chainIndex = run*chainParams.numChains + chain;
+ if (AreDoublesEqual (mv->targetRate[chainIndex], mv->targetRate[chain], 0.000001) == NO)
+ {
+ areRunsSame = NO;
+ break;
+ }
+ }
+ if (areRunsSame == NO)
+ break;
+ }
+
+ /* now print values */
+ for (run=0; run<chainParams.numRuns; run++)
+ {
+ if (areRunsSame == YES && run >= 1)
+ break;
+
+ /* find out if chains are different within this run */
+ areChainsSame = YES;
+ for (chain=1; chain<chainParams.numChains; chain++)
+ {
+ chainIndex = run*chainParams.numChains + chain;
+ if (AreDoublesEqual (mv->targetRate[chainIndex], mv->targetRate[chainIndex-chain], 0.000001) == NO)
+ {
+ areChainsSame = NO;
+ break;
+ }
+ }
+ /* now we can print the values */
+ for (chain=0; chain<chainParams.numChains; chain++)
+ {
+ chainIndex = run*chainParams.numChains + chain;
+ if (areChainsSame == YES && chain >= 1)
+ break;
+
+ if (run == 0 && chain == 0)
+ MrBayesPrint ("%s Targetrate = %1.3lf", spacer, mv->targetRate[chainIndex]);
+ else
+ MrBayesPrint ("%s %1.3lf", spacer, mv->targetRate[chainIndex]);
+
+ if (areChainsSame == NO && areRunsSame == YES)
+ MrBayesPrint (" [chain %d]\n", chain+1);
+ else if (areChainsSame == YES && areRunsSame == NO)
+ MrBayesPrint (" [run %d]\n", run+1);
+ else if (areChainsSame == NO && areRunsSame == NO)
+ MrBayesPrint (" [run %d, chain %d]\n", run+1, chain+1);
+ else
+ MrBayesPrint ("\n");
+ }
+ }
+ }
+
+
+ /* finally print the relative proposal probability */
+
+ /* first find out if the probabilities are different in different runs */
+ areRunsSame = YES;
+ for (run=1; run<chainParams.numRuns; run++)
+ {
+ for (chain=0; chain<chainParams.numChains; chain++)
+ {
+ chainIndex = run*chainParams.numChains + chain;
+ if (AreDoublesEqual (mv->relProposalProb[chainIndex], mv->relProposalProb[chain], 0.000001) == NO)
+ {
+ areRunsSame = NO;
+ break;
+ }
+ }
+ if (areRunsSame == NO)
+ break;
+ }
+
+ /* now print values */
+ for (run=0; run<chainParams.numRuns; run++)
+ {
+ if (areRunsSame == YES && run >= 1)
+ break;
+
+ /* find out if chains are different within this run */
+ areChainsSame = YES;
+ for (chain=1; chain<chainParams.numChains; chain++)
+ {
+ chainIndex = run*chainParams.numChains + chain;
+ if (AreDoublesEqual (mv->relProposalProb[chainIndex], mv->relProposalProb[chainIndex-chain], 0.000001) == NO)
+ {
+ areChainsSame = NO;
+ break;
+ }
+ }
+ /* now we can print the values */
+ for (chain=0; chain<chainParams.numChains; chain++)
+ {
+ chainIndex = run*chainParams.numChains + chain;
+ if (areChainsSame == YES && chain >= 1)
+ break;
+
+ if (run == 0 && chain == 0)
+ MrBayesPrint ("%s Rel. prob. = %1.1lf", spacer, mv->relProposalProb[chainIndex]);
+ else
+ MrBayesPrint ("%s %1.1lf", spacer, mv->relProposalProb[chainIndex]);
+
+ if (areChainsSame == NO && areRunsSame == YES)
+ MrBayesPrint (" [chain %d]\n", chain+1);
+ else if (areChainsSame == YES && areRunsSame == NO)
+ MrBayesPrint (" [run %d]\n", run+1);
+ else if (areChainsSame == NO && areRunsSame == NO)
+ MrBayesPrint (" [run %d, chain %d]\n", run+1, chain+1);
+ else
+ MrBayesPrint ("\n");
+ }
+ }
+ MrBayesPrint ("\n");
+ } /* next move */
+
+ if (numPrintedMoves == 0)
+ {
+ if (used == YES)
+ {
+ MrBayesPrint ("%s No moves currently used for this analysis. All parameters\n", spacer);
+ MrBayesPrint ("%s will be fixed to their starting values.\n\n", spacer);
+ }
+ else
+ {
+ MrBayesPrint ("%s No additional moves available for this model.\n\n", spacer);
+ }
+ }
+
+ return (NO_ERROR);
+}
+
+
+/*------------------------------------------------------------------------------
+|
+| ShowParameters: Show parameter table and parameter info
+|
+------------------------------------------------------------------------------*/
+int ShowParameters (int showStartVals, int showMoves, int showAllAvailable)
+{
+ int a, b, d, i, j, k, m, n, run, chain, shouldPrint, isSame, areRunsSame, areChainsSame, nValues,
+ chainIndex, refIndex, numPrinted, numMovedChains, printedCol, screenWidth=100;
+ Param *p;
+ Model *mp;
+ ModelInfo *ms;
+ MrBFlt *value, *refValue, *subValue;
+ MCMCMove *mv;
+
+ MrBayesPrint ("%s Active parameters: \n\n", spacer);
+ if (numCurrentDivisions > 1)
+ {
+ MrBayesPrint ("%s Partition(s)\n", spacer);
+ MrBayesPrint ("%s Parameters ", spacer);
+ for (i=0; i<numCurrentDivisions; i++)
+ MrBayesPrint (" %2d", i+1);
+ MrBayesPrint ("\n");
+ MrBayesPrint ("%s ------------------", spacer);
+ for (i=0; i<numCurrentDivisions; i++)
+ MrBayesPrint ("---");
+ MrBayesPrint ("\n");
+ }
+ else
+ {
+ MrBayesPrint ("%s Parameters\n", spacer);
+ MrBayesPrint ("%s ---------------------\n", spacer);
+ }
+ for (j=0; j<NUM_LINKED; j++)
+ {
+ shouldPrint = NO;
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParams[j][i] == -1)
+ {}
+ else
+ shouldPrint = YES;
+ }
+ if (shouldPrint == NO)
+ continue;
+
+ if (j == P_TRATIO)
+ {
+ MrBayesPrint ("%s Tratio ", spacer);
+ }
+ else if (j == P_REVMAT)
+ {
+ MrBayesPrint ("%s Revmat ", spacer);
+ }
+ else if (j == P_OMEGA)
+ {
+ MrBayesPrint ("%s Omega ", spacer);
+ }
+ else if (j == P_PI)
+ {
+ MrBayesPrint ("%s Statefreq ", spacer);
+ }
+ else if (j == P_SHAPE)
+ {
+ MrBayesPrint ("%s Shape ", spacer);
+ }
+ else if (j == P_PINVAR)
+ {
+ MrBayesPrint ("%s Pinvar ", spacer);
+ }
+ else if (j == P_CORREL)
+ {
+ MrBayesPrint ("%s Correlation ", spacer);
+ }
+ else if (j == P_SWITCH)
+ {
+ MrBayesPrint ("%s Switchrates ", spacer);
+ }
+ else if (j == P_RATEMULT)
+ {
+ MrBayesPrint ("%s Ratemultiplier ", spacer);
+ }
+ else if (j == P_GENETREERATE)
+ {
+ MrBayesPrint ("%s Generatemult ", spacer);
+ }
+ else if (j == P_TOPOLOGY)
+ {
+ MrBayesPrint ("%s Topology ", spacer);
+ }
+ else if (j == P_BRLENS)
+ {
+ MrBayesPrint ("%s Brlens ", spacer);
+ }
+ else if (j == P_SPECRATE)
+ {
+ MrBayesPrint ("%s Speciationrate ", spacer);
+ }
+ else if (j == P_EXTRATE)
+ {
+ MrBayesPrint ("%s Extinctionrate ", spacer);
+ }
+ else if (j == P_FOSLRATE)
+ {
+ MrBayesPrint ("%s Fossilizationrate ", spacer);
+ }
+ else if (j == P_POPSIZE)
+ {
+ MrBayesPrint ("%s Popsize ", spacer);
+ }
+ else if (j == P_GROWTH)
+ {
+ MrBayesPrint ("%s Growthrate ", spacer);
+ }
+ else if (j == P_AAMODEL)
+ {
+ MrBayesPrint ("%s Aamodel ", spacer);
+ }
+ else if (j == P_BRCORR)
+ {
+ MrBayesPrint ("%s Brownian corr. ", spacer);
+ }
+ else if (j == P_BRSIGMA)
+ {
+ MrBayesPrint ("%s Brownian sigma ", spacer);
+ }
+ else if (j == P_CPPRATE)
+ {
+ MrBayesPrint ("%s Cpprate ", spacer);
+ }
+ else if (j == P_CPPMULTDEV)
+ {
+ MrBayesPrint ("%s Cppmultdev ", spacer);
+ }
+ else if (j == P_CPPEVENTS)
+ {
+ MrBayesPrint ("%s Cppevents ", spacer);
+ }
+ else if (j == P_TK02VAR)
+ {
+ MrBayesPrint ("%s TK02var ", spacer);
+ }
+ else if (j == P_TK02BRANCHRATES)
+ {
+ MrBayesPrint ("%s TK02branchrates ", spacer);
+ }
+ else if (j == P_IGRVAR)
+ {
+ MrBayesPrint ("%s Igrvar ", spacer);
+ }
+ else if (j == P_IGRBRANCHRATES)
+ {
+ MrBayesPrint ("%s Igrbranchrates ", spacer);
+ }
+ else if (j == P_MIXEDVAR)
+ {
+ MrBayesPrint ("%s Mixedvar ", spacer);
+ }
+ else if (j == P_MIXEDBRCHRATES)
+ {
+ MrBayesPrint ("%s Mixedbranchrates ", spacer);
+ }
+ else if (j == P_CLOCKRATE)
+ {
+ MrBayesPrint ("%s Clockrate ", spacer);
+ }
+ else if (j == P_SPECIESTREE)
+ {
+ MrBayesPrint ("%s Speciestree ", spacer);
+ }
+ else
+ {
+ MrBayesPrint ("%s ERROR: Someone forgot to name parameter type %d", spacer, j);
+ return (ERROR);
+ }
+
+ for (i=0; i<numCurrentDivisions; i++)
+ {
+ if (activeParams[j][i] == -1)
+ MrBayesPrint (" .");
+ else
+ MrBayesPrint (" %2d", activeParams[j][i]);
+ }
+ MrBayesPrint ("\n");
+ }
+ if (numCurrentDivisions > 1)
+ {
+ MrBayesPrint ("%s ------------------", spacer);
+ for (i=0; i<numCurrentDivisions; i++)
+ MrBayesPrint ("---");
+ MrBayesPrint ("\n");
+ }
+ else
+ {
+ MrBayesPrint ("%s ---------------------\n", spacer);
+ }
+
+ MrBayesPrint ("\n");
+
+ if (numCurrentDivisions > 1)
+ MrBayesPrint ("%s Parameters can be linked or unlinked across partitions using 'link' and 'unlink'\n\n", spacer);
+
+ for (i=0; i<numParams; i++)
+ {
+ p = ¶ms[i];
+ j = p->paramType;
+
+ mp = &modelParams[p->relParts[0]];
+ ms = &modelSettings[p->relParts[0]];
+
+ /* print parameter number and name */
+ MrBayesPrint ("%s %4d -- Parameter = %s\n", spacer, i+1, p->name);
+ MrBayesPrint ("%s Type = %s\n", spacer, p->paramTypeName);
+ /* print prior */
+ if (j == P_TRATIO)
+ {
+ if (!strcmp(mp->tRatioPr,"Beta"))
+ MrBayesPrint ("%s Prior = Beta(%1.2lf,%1.2lf)\n", spacer, mp->tRatioDir[0], modelParams[i].tRatioDir[1]);
+ else
+ MrBayesPrint ("%s Prior = Fixed(%1.2lf)\n", spacer, mp->tRatioFix);
+ }
+ else if (j == P_REVMAT)
+ {
+ if (ms->numModelStates != 20)
+ {
+ if (!strcmp(mp->nst,"Mixed"))
+ {
+ MrBayesPrint ("%s Prior = All GTR submodels have equal probability\n", spacer);
+ MrBayesPrint ("%s All revmat rates have a Symmetric Dirichlet(%1.2lf) prior\n", spacer, mp->revMatSymDir);
+ }
+ else if (!strcmp(mp->revMatPr,"Dirichlet"))
+ {
+ MrBayesPrint ("%s Prior = Dirichlet(%1.2lf,%1.2lf,%1.2lf,%1.2lf,%1.2lf,%1.2lf)\n", spacer,
+ mp->revMatDir[0], mp->revMatDir[1], mp->revMatDir[2],
+ mp->revMatDir[3], mp->revMatDir[4], mp->revMatDir[5]);
+ }
+ else
+ MrBayesPrint ("%s Prior = Fixed(%1.2lf,%1.2lf,%1.2lf,%1.2lf,%1.2lf,%1.2lf)\n", spacer,
+ mp->revMatFix[0], mp->revMatFix[1], mp->revMatFix[2],
+ mp->revMatFix[3], mp->revMatFix[4], mp->revMatFix[5]);
+ }
+ else if (ms->numModelStates == 20)
+ {
+ if (!strcmp(mp->aaRevMatPr,"Dirichlet"))
+ MrBayesPrint ("%s Prior = Dirichlet\n", spacer);
+ else
+ MrBayesPrint ("%s Prior = Fixed(user-specified)\n", spacer);
+ }
+ }
+ else if (j == P_OMEGA)
+ {
+ if (!strcmp(mp->omegaVar,"Equal"))
+ {
+ if (!strcmp(mp->omegaPr,"Dirichlet"))
+ MrBayesPrint ("%s Prior = Dirichlet(%1.2lf,%1.2lf)\n", spacer, mp->omegaDir[0], mp->omegaDir[1]);
+ else
+ MrBayesPrint ("%s Prior = Fixed(%1.2lf)\n", spacer, mp->omegaFix);
+ }
+ else if (!strcmp(mp->omegaVar,"Ny98"))
+ {
+ if (!strcmp(mp->ny98omega1pr,"Beta"))
+ MrBayesPrint ("%s Prior = Beta(%1.2lf,%1.2lf) on omega(1)\n", spacer, mp->ny98omega1Beta[0], mp->ny98omega1Beta[1]);
+ else
+ MrBayesPrint ("%s Prior = Fixed(%1.2lf) on omega(1)\n", spacer, mp->ny98omega1Fixed);
+ MrBayesPrint ("%s Fixed(1.00) on omega(2)\n", spacer);
+ if (!strcmp(mp->ny98omega3pr,"Uniform"))
+ MrBayesPrint ("%s Uniform(%1.2lf,%1.2lf) on omega(3)\n", spacer, mp->ny98omega3Uni[0], mp->ny98omega3Uni[1]);
+ else if (!strcmp(mp->ny98omega3pr,"Exponential"))
+ MrBayesPrint ("%s Exponential(%1.2lf) on omega(3)\n", spacer, mp->ny98omega3Exp);
+ else
+ MrBayesPrint ("%s Fixed(%1.2lf) on omega(3)\n", spacer, mp->ny98omega3Fixed);
+ if (!strcmp(mp->codonCatFreqPr,"Dirichlet"))
+ MrBayesPrint ("%s Dirichlet(%1.2lf,%1.2lf,%1.2lf) on pi(-), pi(N), and pi(+)\n", spacer, mp->codonCatDir[0], mp->codonCatDir[1], mp->codonCatDir[2]);
+ else
+ MrBayesPrint ("%s Fixed(%1.2lf,%1.2lf,%1.2lf) on pi(-), pi(N), and pi(+)\n", spacer, mp->codonCatFreqFix[0], mp->codonCatFreqFix[1], mp->codonCatFreqFix[2]);
+ }
+ else if (!strcmp(mp->omegaVar,"M3"))
+ {
+ if (!strcmp(mp->m3omegapr,"Exponential"))
+ MrBayesPrint ("%s dN1, dN2, dN3, and dS are all exponential random variables\n", spacer);
+ else
+ MrBayesPrint ("%s Fixed(%1.2lf,%1.2lf,%1.2lf) for the three selection categories\n", spacer, mp->m3omegaFixed[0], mp->m3omegaFixed[1], mp->m3omegaFixed[2]);
+ if (!strcmp(mp->codonCatFreqPr,"Dirichlet"))
+ MrBayesPrint ("%s Dirichlet(%1.2lf,%1.2lf,%1.2lf) on pi(1), pi(2), and pi(3)\n", spacer, mp->codonCatDir[0], mp->codonCatDir[1], mp->codonCatDir[2]);
+ else
+ MrBayesPrint ("%s Fixed(%1.2lf,%1.2lf,%1.2lf) on pi(1), pi(2), and pi(3)\n", spacer, mp->codonCatFreqFix[0], mp->codonCatFreqFix[1], mp->codonCatFreqFix[2]);
+ }
+ else if (!strcmp(mp->omegaVar,"M10"))
+ {
+ MrBayesPrint ("%s With probability pi(1), omega is drawn from a Beta(alpha1,beta1) \n", spacer);
+ MrBayesPrint ("%s distribution and with probability pi(2), omega is drawn from\n", spacer);
+ MrBayesPrint ("%s a Gamma(alpha2,beta2) distribution.\n", spacer);
+ if (!strcmp(mp->m10betapr,"Uniform"))
+ {
+ MrBayesPrint ("%s The parameters of the beta distribution each follow \n", spacer);
+ MrBayesPrint ("%s independent Uniform(%1.2lf,%1.2lf) priors\n", spacer, mp->m10betaUni[0], mp->m10betaUni[1]);
+ }
+ else if (!strcmp(mp->m10betapr,"Exponential"))
+ {
+ MrBayesPrint ("%s The parameters of the beta distribution each follow \n", spacer);
+ MrBayesPrint ("%s independent Exponential(%1.2lf) priors\n", spacer, mp->m10betaExp);
+ }
+ else
+ {
+ MrBayesPrint ("%s The parameters of the beta distribution are fixed to \n", spacer);
+ MrBayesPrint ("%s %1.2lf and %1.2lf\n", spacer, mp->m10betaFix[0], mp->m10betaFix[0]);
+ }
+
+ if (!strcmp(mp->m10gammapr,"Uniform"))
+ {
+ MrBayesPrint ("%s The parameters of the gamma distribution each follow \n", spacer);
+ MrBayesPrint ("%s independent Uniform(%1.2lf,%1.2lf) priors\n", spacer, mp->m10gammaUni[0], mp->m10gammaUni[1]);
+ }
+ else if (!strcmp(mp->m10gammapr,"Exponential"))
+ {
+ MrBayesPrint ("%s The parameters of the gamma distribution each follow \n", spacer);
+ MrBayesPrint ("%s independent Exponential(%1.2lf) priors\n", spacer, mp->m10gammaExp);
+ }
+ else
+ {
+ MrBayesPrint ("%s The parameters of the gamma distribution are fixed to \n", spacer);
+ MrBayesPrint ("%s %1.2lf and %1.2lf\n", spacer, mp->m10gammaFix[0], mp->m10gammaFix[0]);
+ }
+
+ if (!strcmp(mp->codonCatFreqPr,"Dirichlet"))
+ MrBayesPrint ("%s Dirichlet(%1.2lf,%1.2lf) on pi(1) and pi(2)\n", spacer, mp->codonCatDir[0], mp->codonCatDir[1]);
+ else
+ MrBayesPrint ("%s Fixed(%1.2lf,%1.2lf) on pi(1) and pi(2)\n", spacer, mp->codonCatFreqFix[0], mp->codonCatFreqFix[1]);
+ }
+ }
+ else if (j == P_PI)
+ {
+ if (ms->dataType == STANDARD)
+ {
+ if (!strcmp(mp->symPiPr, "Uniform"))
+ MrBayesPrint ("%s Prior = Symmetric dirichlet with uniform(%1.2lf,%1.2lf) variance parameter\n", spacer, mp->symBetaUni[0], mp->symBetaUni[1]);
+ else if (!strcmp(mp->symPiPr, "Exponential"))
+ MrBayesPrint ("%s Prior = Symmetric dirichlet with exponential(%1.2lf) variance parameter\n", spacer, mp->symBetaExp);
+ else
+ { /* mp->symBetaFix == -1 */
+ if (AreDoublesEqual(mp->symBetaFix, -1.0, ETA)==YES)
+ MrBayesPrint ("%s Prior = Symmetric dirichlet with all parameters equal to infinity\n", spacer);
+ else
+ MrBayesPrint ("%s Prior = Symmetric dirichlet with all parameters equal to %1.2lf\n", spacer, mp->symBetaFix);
+ }
+ }
+ else if (ms->dataType == PROTEIN)
+ {
+ if (!strcmp(mp->aaModelPr, "Fixed") && (!strcmp(mp->aaModel, "Equalin") || !strcmp(mp->aaModel, "Gtr")))
+ {
+ if (!strcmp(mp->stateFreqPr,"Dirichlet"))
+ {
+ MrBayesPrint ("%s Prior = Dirichlet\n", spacer);
+ }
+ else if (!strcmp(mp->stateFreqPr,"Fixed") && !strcmp(mp->stateFreqsFixType,"Equal"))
+ {
+ MrBayesPrint ("%s Prior = Fixed (equal frequencies)\n", spacer);
+ }
+ else if (!strcmp(mp->stateFreqPr,"Fixed") && !strcmp(mp->stateFreqsFixType,"User"))
+ {
+ MrBayesPrint ("%s Prior = Fixed (user-specified)\n", spacer);
+ }
+ else if (!strcmp(mp->stateFreqPr,"Fixed") && !strcmp(mp->stateFreqsFixType,"Empirical"))
+ {
+ MrBayesPrint ("%s Prior = Fixed (empirical frequencies)\n", spacer);
+ }
+ }
+ else if (!strcmp(mp->aaModelPr, "Fixed") && !strcmp(mp->aaModel, "Poisson"))
+ {
+ MrBayesPrint ("%s Prior = Fixed (equal frequencies)\n", spacer);
+ }
+ else if (!strcmp(mp->aaModelPr, "Fixed") && strcmp(mp->aaModel, "Equalin") && strcmp(mp->aaModel, "Poisson"))
+ {
+ MrBayesPrint ("%s Prior = Fixed (%s frequencies)\n", spacer, mp->aaModel);
+ }
+ else
+ {
+ MrBayesPrint ("%s Prior = Fixed (from mixture of models)\n", spacer);
+ }
+ }
+ else
+ {
+ if (!strcmp(mp->stateFreqPr,"Dirichlet"))
+ MrBayesPrint ("%s Prior = Dirichlet\n", spacer);
+ else
+ MrBayesPrint ("%s Prior = Fixed\n", spacer);
+ }
+ }
+ else if (j == P_SHAPE)
+ {
+ if (!strcmp(mp->shapePr,"Uniform"))
+ MrBayesPrint ("%s Prior = Uniform(%1.2lf,%1.2lf)\n", spacer, mp->shapeUni[0], mp->shapeUni[1]);
+ else if (!strcmp(mp->shapePr,"Exponential"))
+ MrBayesPrint ("%s Prior = Exponential(%1.2lf)\n", spacer, mp->shapeExp);
+ else
+ MrBayesPrint ("%s Prior = Fixed(%1.2lf)\n", spacer, mp->shapeFix);
+ }
+ else if (j == P_PINVAR)
+ {
+ if (!strcmp(mp->pInvarPr,"Uniform"))
+ MrBayesPrint ("%s Prior = Uniform(%1.2lf,%1.2lf)\n", spacer, mp->pInvarUni[0], mp->pInvarUni[1]);
+ else
+ MrBayesPrint ("%s Prior = Fixed(%1.2lf)\n", spacer, mp->pInvarFix);
+ }
+ else if (j == P_CORREL)
+ {
+ if (!strcmp(mp->adGammaCorPr,"Uniform"))
+ MrBayesPrint ("%s Prior = Uniform(%1.2lf,%1.2lf)\n", spacer, mp->corrUni[0], mp->corrUni[1]);
+ else
+ MrBayesPrint ("%s Prior = Fixed(%1.2lf)\n", spacer, mp->corrFix);
+ }
+ else if (j == P_SWITCH)
+ {
+ if (!strcmp(mp->covSwitchPr,"Uniform"))
+ MrBayesPrint ("%s Prior = Uniform(%1.2lf,%1.2lf)\n", spacer, mp->covswitchUni[0], mp->covswitchUni[1]);
+ else if (!strcmp(mp->covSwitchPr,"Exponential"))
+ MrBayesPrint ("%s Prior = Exponential(%1.2lf)\n", spacer, mp->covswitchExp);
+ else
+ MrBayesPrint ("%s Prior = Fixed(%1.2lf,%1.2lf)\n", spacer, mp->covswitchFix[0], mp->covswitchFix[1]);
+ }
+ else if (j == P_RATEMULT)
+ {
+ if (!strcmp(mp->ratePr,"Fixed"))
+ MrBayesPrint ("%s Prior = Fixed(1.0)\n", spacer);
+ else
+ {
+ MrBayesPrint ("%s Prior = Dirichlet(", spacer);
+ for (d=n=0; d<numCurrentDivisions; d++)
+ {
+ if (activeParams[j][d] == i+1)
+ n++;
+ }
+ for (d=m=0; d<numCurrentDivisions; d++)
+ {
+ if (activeParams[j][d] == i+1)
+ {
+ m++;
+ if (m < n)
+ MrBayesPrint ("%1.2lf,", modelParams[d].ratePrDir);
+ else
+ MrBayesPrint ("%1.2lf)\n", modelParams[d].ratePrDir);
+ }
+ }
+ }
+ }
+ else if (j == P_GENETREERATE)
+ {
+ if (!strcmp(mp->generatePr,"Fixed"))
+ MrBayesPrint ("%s Prior = Fixed(1.0)\n", spacer);
+ else
+ {
+ MrBayesPrint ("%s Prior = Dirichlet(", spacer);
+ printedCol = (int)(strlen(spacer)) + 25 + 10;
+ for (n=0; n<numTrees-1; n++)
+ {
+ if (printedCol + 5 > screenWidth)
+ {
+ MrBayesPrint("\n%s ", spacer);
+ printedCol = (int)(strlen(spacer)) + 25 + 10;
+ }
+ if (n == numTrees-2)
+ MrBayesPrint ("1.00)\n");
+ else
+ MrBayesPrint ("1.00,");
+ printedCol += 5;
+ }
+ }
+ }
+ else if (j == P_TOPOLOGY)
+ {
+ if (!strcmp(mp->topologyPr,"Uniform"))
+ MrBayesPrint ("%s Prior = All topologies equally probable a priori\n", spacer);
+ else if (!strcmp(mp->topologyPr,"Speciestree"))
+ MrBayesPrint ("%s Prior = Topology constrained to fold within species tree\n", spacer);
+ else if (!strcmp(mp->topologyPr,"Constraints"))
+ MrBayesPrint ("%s Prior = Prior on topologies obeys constraints\n", spacer);
+ else
+ MrBayesPrint ("%s Prior = Prior is fixed to the topology of user tree '%s'\n", spacer,
+ userTree[mp->topologyFix]->name);
+ }
+ else if (j == P_BRLENS)
+ {
+ if (!strcmp(mp->parsModel, "Yes"))
+ MrBayesPrint ("%s Prior = Reconstructed using parsimony\n", spacer);
+ else
+ {
+ if (!strcmp(mp->brlensPr,"Unconstrained"))
+ {
+ MrBayesPrint ("%s Prior = Unconstrained:%s", spacer, mp->unconstrainedPr);
+ if (!strcmp(mp->unconstrainedPr, "Uniform"))
+ MrBayesPrint ("(%1.1lf,%1.1lf)\n", mp->brlensUni[0], mp->brlensUni[1]);
+ else if (!strcmp(mp->unconstrainedPr, "Exponential"))
+ MrBayesPrint ("(%1.1lf)\n", mp->brlensExp);
+ else if (!strcmp(mp->unconstrainedPr, "twoExp"))
+ MrBayesPrint ("(%1.1lf,%1.1lf)\n", mp->brlens2Exp[0], mp->brlens2Exp[1]);
+ else
+ MrBayesPrint ("(%1.1lf,%1.4lf,%1.1lf,%1.1lf)\n", mp->brlensDir[0], mp->brlensDir[1], mp->brlensDir[2], mp->brlensDir[3]);
+ }
+ else if (!strcmp(mp->brlensPr, "Clock"))
+ {
+ MrBayesPrint ("%s Prior = Clock:%s\n", spacer, mp->clockPr);
+ if ((!strcmp(mp->clockPr,"Uniform") || !strcmp(mp->clockPr,"Fossilization")) && !strcmp(mp->nodeAgePr,"Unconstrained"))
+ {
+ MrBayesPrint ("%s Tree age has a %s distribution\n", spacer, mp->treeAgePr.name);
+ }
+ else if (!strcmp(mp->clockPr, "Birthdeath") && !strcmp(mp->nodeAgePr,"Unconstrained"))
+ {
+ MrBayesPrint ("%s Tree age has a Uniform(0,infinity) distribution\n", spacer);
+ }
+ if (!strcmp(mp->nodeAgePr,"Calibrated"))
+ {
+ b = 0;
+ for (a=0; a<numTaxa; a++)
+ {
+ if (taxaInfo[a].isDeleted == NO && tipCalibration[a].prior != unconstrained)
+ b++;
+ }
+ for (a=0; a<numDefinedConstraints; a++)
+ {
+ if (mp->activeConstraints[a] == YES && nodeCalibration[a].prior != unconstrained)
+ b++;
+ }
+ if (b > 1)
+ MrBayesPrint ("%s Node depths are constrained by the following age constraints:\n", spacer);
+ else
+ MrBayesPrint ("%s Node depths are calibrated by the following age constraint:\n", spacer);
+ for (a=0; a<numTaxa; a++)
+ {
+ if (taxaInfo[a].isDeleted == NO && tipCalibration[a].prior != unconstrained)
+ {
+ MrBayesPrint ("%s -- The age of terminal \"%s\" is %s\n", spacer, taxaNames[a],
+ tipCalibration[a].name);
+ }
+ }
+ for (a=b=0; a<numDefinedConstraints; a++)
+ {
+ if (mp->activeConstraints[a] == YES && nodeCalibration[a].prior != unconstrained)
+ {
+ MrBayesPrint ("%s -- The age of node '%s' is %s\n", spacer,
+ constraintNames[a], nodeCalibration[a].name);
+ for (k=0; k<numTaxa; k++)
+ if (taxaInfo[k].isDeleted == NO && IsBitSet(k,definedConstraint[a]) == NO)
+ break;
+ if (k == numTaxa)
+ b = 1; /* root is calibrated */
+ }
+ }
+ if (b == 0) /* we need to use default calibration for root for uniform and birthdeath */
+ {
+ if (!strcmp(mp->clockPr,"Uniform") || !strcmp(mp->clockPr,"Fossilization"))
+ {
+ MrBayesPrint ("%s -- Tree age has a %s distribution\n", spacer, mp->treeAgePr.name);
+ }
+ else if (!strcmp(mp->clockPr,"Birthdeath"))
+ {
+ MrBayesPrint ("%s -- Tree age has a Uniform(0,infinity) distribution\n", spacer);
+ }
+ }
+ }
+ else
+ MrBayesPrint ("%s Node ages are not constrained\n", spacer);
+ }
+ else
+ {
+ assert (!strcmp(mp->brlensPr, "Fixed"));
+ MrBayesPrint ("%s Prior = Fixed, branch lengths are fixed to the ones of the user tree '%s'\n", spacer,
+ userTree[mp->topologyFix]->name);
+ }
+ }
+ }
+ else if (j == P_SPECRATE)
+ {
+ if (!strcmp(mp->speciationPr,"Uniform"))
+ MrBayesPrint ("%s Prior = Uniform(%1.2lf,%1.2lf)\n", spacer, mp->speciationUni[0], mp->speciationUni[1]);
+ else if (!strcmp(mp->speciationPr,"Exponential"))
+ MrBayesPrint ("%s Prior = Exponential(%1.2lf)\n", spacer, mp->speciationExp);
+ else
+ MrBayesPrint ("%s Prior = Fixed(%1.2lf)\n", spacer, mp->speciationFix);
+ }
+ else if (j == P_EXTRATE)
+ {
+ if (!strcmp(mp->extinctionPr,"Beta"))
+ MrBayesPrint ("%s Prior = Beta(%1.2lf,%1.2lf)\n", spacer, mp->extinctionBeta[0], mp->extinctionBeta[1]);
+ else
+ MrBayesPrint ("%s Prior = Fixed(%1.2lf)\n", spacer, mp->extinctionFix);
+ }
+ else if (j == P_FOSLRATE)
+ {
+ if (!strcmp(mp->fossilizationPr,"Beta"))
+ MrBayesPrint ("%s Prior = Beta(%1.2lf,%1.2lf)\n", spacer, mp->fossilizationBeta[0], mp->fossilizationBeta[1]);
+ else
+ MrBayesPrint ("%s Prior = Fixed(%1.2lf)\n", spacer, mp->fossilizationFix);
+ }
+ else if (j == P_POPSIZE)
+ {
+ if (!strcmp(mp->popSizePr,"Uniform"))
+ MrBayesPrint ("%s Prior = Uniform(%1.2lf,%1.2lf)\n", spacer, mp->popSizeUni[0], mp->popSizeUni[1]);
+ else if (!strcmp(mp->popSizePr,"Lognormal"))
+ MrBayesPrint ("%s Prior = Lognormal(%1.2lf,%1.2lf)\n", spacer, mp->popSizeLognormal[0], mp->popSizeLognormal[1]);
+ else if (!strcmp(mp->popSizePr,"Normal"))
+ MrBayesPrint ("%s Prior = Truncated Normal(%1.2lf,%1.2lf)\n", spacer, mp->popSizeNormal[0], mp->popSizeNormal[1]);
+ else if (!strcmp(mp->popSizePr,"Gamma"))
+ MrBayesPrint ("%s Prior = Gamma(%1.2lf,%1.2lf)\n", spacer, mp->popSizeGamma[0], mp->popSizeGamma[1]);
+ else
+ MrBayesPrint ("%s Prior = Fixed(%1.5lf)\n", spacer, mp->popSizeFix);
+ if (!strcmp(mp->topologyPr,"Speciestree"))
+ {
+ if (!strcmp(mp->popVarPr,"Equal") || !strcmp(mp->popSizePr,"Fixed"))
+ MrBayesPrint ("%s Population size the same across species tree\n", spacer);
+ else
+ MrBayesPrint ("%s Population size varies across branches in species tree\n", spacer);
+ }
+ }
+ else if (j == P_GROWTH)
+ {
+ if (!strcmp(mp->growthPr,"Uniform"))
+ MrBayesPrint ("%s Prior = Uniform(%1.2lf,%1.2lf)\n", spacer, mp->growthUni[0], mp->growthUni[1]);
+ else if (!strcmp(mp->growthPr,"Exponential"))
+ MrBayesPrint ("%s Prior = Exponential(%1.2lf)\n", spacer, mp->growthExp);
+ else if (!strcmp(mp->growthPr,"Normal"))
+ MrBayesPrint ("%s Prior = Normal(%1.2lf,%1.2lf)\n", spacer, mp->growthNorm[0], mp->growthNorm[1]);
+ else
+ MrBayesPrint ("%s Prior = Fixed(%1.2lf)\n", spacer, mp->growthFix);
+ }
+ else if (j == P_AAMODEL)
+ {
+ if (!strcmp(mp->aaModelPr,"Mixed"))
+ {
+ /* check to see if you have a uniform prior */
+ isSame = YES;
+ for (a=0; a<9; a++)
+ for (b=a+1; b<10; b++)
+ /* mp->aaModelPrProbs[a] != mp->aaModelPrProbs[b] */
+ if (AreDoublesEqual(mp->aaModelPrProbs[a], mp->aaModelPrProbs[b], ETA)==FALSE)
+ isSame = NO;
+ MrBayesPrint ("%s Prior = Poisson, Jones, Dayhoff, Mtrev, Mtmam, Wag, Rtrev,\n", spacer);
+ if (isSame == YES)
+ MrBayesPrint ("%s Cprev, Vt, and Blosum models have equal prior probability\n", spacer);
+ else
+ MrBayesPrint ("%s Cprev, Vt, and Blosum models have unequal prior probability\n", spacer);
+ }
+ else
+ MrBayesPrint ("%s Prior = Fixed(%s)\n", spacer, mp->aaModel);
+ }
+ else if (j == P_BRCORR)
+ {
+ if (!strcmp(mp->brownCorPr,"Uniform"))
+ MrBayesPrint ("%s Prior = Uniform(%1.2lf,%1.2lf)\n", spacer, mp->brownCorrUni[0], mp->brownCorrUni[1]);
+ else
+ MrBayesPrint ("%s Prior = Fixed(%1.2lf)\n", spacer, mp->brownCorrFix);
+ }
+ else if (j == P_BRSIGMA)
+ {
+ if (!strcmp(mp->brownScalesPr,"Uniform"))
+ MrBayesPrint ("%s Prior = Uniform(%1.2lf,%1.2lf)\n", spacer, mp->brownScalesUni[0], mp->brownScalesUni[1]);
+ else if (!strcmp(mp->brownScalesPr,"Gammamean"))
+ MrBayesPrint ("%s Prior = Gamma Mean=<char. ave.> Var=%1.2lf\n", spacer, mp->brownScalesGammaMean);
+ else if (!strcmp(mp->brownScalesPr,"Gamma"))
+ MrBayesPrint ("%s Prior = Gamma Mean=%lf Var=%1.2lf\n", spacer, mp->brownScalesGamma[0], mp->brownScalesGamma[1]);
+ else
+ MrBayesPrint ("%s Prior = Fixed(%1.2lf)\n", spacer, mp->brownScalesFix);
+ }
+ else if (j == P_CPPRATE)
+ {
+ if (!strcmp(mp->cppRatePr,"Exponential"))
+ MrBayesPrint ("%s Prior = Exponential(%1.2lf)\n", spacer, mp->cppRateExp);
+ else
+ MrBayesPrint ("%s Prior = Fixed(%1.2lf)\n", spacer, mp->cppRateFix);
+ }
+ else if (j == P_CPPMULTDEV)
+ {
+ if (!strcmp(mp->cppMultDevPr,"Fixed"))
+ MrBayesPrint ("%s Prior = Fixed(%1.2lf)\n", spacer, mp->cppMultDevFix);
+ }
+ else if (j == P_CPPEVENTS)
+ {
+ MrBayesPrint ("%s Prior = Poisson (%s) [Events]\n", spacer, modelSettings[p->relParts[0]].cppRate->name);
+ MrBayesPrint ("%s Lognormal (0.00,%1.2lf) [Rate multipliers]\n", spacer, mp->cppMultDevFix);
+ }
+ else if (j == P_TK02VAR)
+ {
+ if (!strcmp(mp->tk02varPr,"Uniform"))
+ MrBayesPrint ("%s Prior = Uniform(%1.2lf,%1.2lf)\n", spacer, mp->tk02varUni[0], mp->tk02varUni[1]);
+ else if (!strcmp(mp->tk02varPr,"Exponential"))
+ MrBayesPrint ("%s Prior = Exponential(%1.2lf)\n", spacer, mp->tk02varExp);
+ else
+ MrBayesPrint ("%s Prior = Fixed(%1.2lf)\n", spacer, mp->tk02varFix);
+ }
+ else if (j == P_TK02BRANCHRATES)
+ {
+ MrBayesPrint ("%s Prior = LogNormal (expectation = r_0, variance = %s * v) \n", spacer, modelSettings[p->relParts[0]].tk02var->name);
+ MrBayesPrint ("%s [r_0 is beginning rate of branch, v is branch length]\n", spacer);
+ }
+ else if (j == P_IGRVAR)
+ {
+ if (!strcmp(mp->igrvarPr,"Uniform"))
+ MrBayesPrint ("%s Prior = Uniform(%1.2lf,%1.2lf)\n", spacer, mp->igrvarUni[0], mp->igrvarUni[1]);
+ else if (!strcmp(mp->igrvarPr,"Exponential"))
+ MrBayesPrint ("%s Prior = Exponential(%1.2lf)\n", spacer, mp->igrvarExp);
+ else
+ MrBayesPrint ("%s Prior = Fixed(%1.2lf)\n", spacer, mp->igrvarFix);
+ }
+ else if (j == P_IGRBRANCHRATES)
+ {
+ MrBayesPrint ("%s Prior = Gamma (expectation = v, variance = %s * v) \n", spacer, modelSettings[p->relParts[0]].igrvar->name);
+ MrBayesPrint ("%s [where v is branch length]\n", spacer);
+ }
+ else if (j == P_MIXEDVAR)
+ {
+ if (!strcmp(mp->mixedvarPr,"Uniform"))
+ MrBayesPrint ("%s Prior = Uniform(%1.2lf,%1.2lf)\n", spacer, mp->mixedvarUni[0], mp->mixedvarUni[1]);
+ else if (!strcmp(mp->mixedvarPr,"Exponential"))
+ MrBayesPrint ("%s Prior = Exponential(%1.2lf)\n", spacer, mp->mixedvarExp);
+ else
+ MrBayesPrint ("%s Prior = Fixed(%1.2lf)\n", spacer, mp->mixedvarFix);
+ }
+ else if (j == P_MIXEDBRCHRATES)
+ {
+ MrBayesPrint ("%s Prior = Mixed TK02 and IGR (variance = %s * v)\n", spacer, modelSettings[p->relParts[0]].mixedvar->name);
+ MrBayesPrint ("%s [where v is branch length]\n", spacer);
+ MrBayesPrint ("%s Uniform prior on relaxed clock models [Pr(TK02)=Pr(IGR)=1/2]\n", spacer);
+ }
+ else if (j == P_CLOCKRATE)
+ {
+ if (!strcmp(mp->clockRatePr,"Normal"))
+ MrBayesPrint ("%s Prior = Normal(%1.6lf,%1.6lf)\n", spacer, mp->clockRateNormal[0], mp->clockRateNormal[1]);
+ else if (!strcmp(mp->clockRatePr,"Lognormal"))
+ MrBayesPrint ("%s Prior = Lognormal(%1.2lf,%1.2lf)\n", spacer, mp->clockRateLognormal[0], mp->clockRateLognormal[1]);
+ else if (!strcmp(mp->clockRatePr,"Gamma"))
+ MrBayesPrint ("%s Prior = Gamma(%1.2lf,%1.2lf)\n", spacer, mp->clockRateGamma[0], mp->clockRateGamma[1]);
+ else if (!strcmp(mp->clockRatePr,"Exponential"))
+ MrBayesPrint ("%s Prior = Exponential(%1.2lf)\n", spacer, mp->clockRateExp);
+ else
+ MrBayesPrint ("%s Prior = Fixed(%1.6lf)\n", spacer, mp->clockRateFix);
+ if (!strcmp(mp->clockVarPr,"Strict"))
+ MrBayesPrint ("%s The clock rate is constant (strict clock)\n", spacer);
+ else if (!strcmp(mp->clockVarPr,"Cpp"))
+ MrBayesPrint ("%s The clock rate varies according to a CPP model\n", spacer);
+ else if (!strcmp(mp->clockVarPr,"TK02"))
+ MrBayesPrint ("%s The clock rate varies according to a Brownian motion model\n", spacer);
+ else if (!strcmp(mp->clockVarPr,"Igr"))
+ MrBayesPrint ("%s The clock rate varies according to an independent gamma (white noise) model\n", spacer);
+ else /* if (!strcmp(mp->clockVarPr,"Mixed")) */
+ MrBayesPrint ("%s The clock rate varies according to mixed TK02 and IGR models\n", spacer);
+ }
+ else if (j == P_SPECIESTREE)
+ {
+ MrBayesPrint ("%s Prior = Uniform on topologies and branch lengths\n", spacer);
+ }
+
+ /* print partitions */
+ if (numCurrentDivisions > 1)
+ {
+ if (p->nRelParts == 1)
+ MrBayesPrint ("%s Partition = %d\n", spacer, p->relParts[0]+1);
+ else if (p->nRelParts == 2)
+ {
+ MrBayesPrint ("%s Partitions = %d and %d\n", spacer, p->relParts[0]+1, p->relParts[1]+1);
+ }
+ else if (p->nRelParts == numCurrentDivisions)
+ {
+ MrBayesPrint ("%s Partitions = All\n", spacer);
+ }
+ else /* if (p->nRelParts > 2) */
+ {
+ MrBayesPrint ("%s Partitions = ", spacer);
+ for (j=0; j<p->nRelParts; j++)
+ {
+ if (j == p->nRelParts - 2)
+ MrBayesPrint ("%d, and ", p->relParts[j]+1);
+ else if (j == p->nRelParts - 1)
+ MrBayesPrint ("%d\n", p->relParts[j]+1);
+ else
+ MrBayesPrint ("%d, ", p->relParts[j]+1);
+ }
+ }
+ }
+
+ /* show subparams */
+ if (p->nSubParams > 0)
+ {
+ if (p->nSubParams == 1)
+ MrBayesPrint ("%s Subparam. = %s\n", spacer, p->subParams[0]->name);
+ else
+ {
+ printedCol = 0;
+ for (k=0; k<p->nSubParams; k++)
+ {
+ if (k == 0)
+ {
+ MrBayesPrint ("%s Subparams = %s", spacer, p->subParams[k]->name);
+ printedCol = (int)(strlen(spacer)) + 25 + (int)(strlen(p->subParams[k]->name));
+ }
+ else if (k == p->nSubParams - 1)
+ {
+ if (printedCol + 5 > screenWidth)
+ MrBayesPrint ("\n%s and ", spacer);
+ else if (printedCol + (int)(strlen(p->subParams[k]->name)) + 5 > screenWidth)
+ MrBayesPrint (" and \n%s ", spacer);
+ else
+ MrBayesPrint (" and ");
+ MrBayesPrint ("%s\n", p->subParams[k]->name);
+ }
+ else
+ {
+ if (printedCol + (int)(strlen(p->subParams[k]->name)) + 2 > screenWidth)
+ {
+ MrBayesPrint (", \n%s ", spacer);
+ printedCol = (int)(strlen(spacer)) + 25;
+ }
+ else
+ {
+ MrBayesPrint(", ");
+ printedCol += 2;
+ }
+ MrBayesPrint ("%s", p->subParams[k]->name);
+ printedCol += (int)strlen(p->subParams[k]->name);
+ }
+ }
+ }
+ }
+
+ /* show used moves */
+ if (showMoves == YES && (p->printParam == YES || p->paramType == P_TOPOLOGY || p->paramType == P_BRLENS))
+ {
+ /* check if runs are same */
+ areRunsSame = YES;
+ for (run=1; run<chainParams.numRuns; run++)
+ {
+ for (chain=0; chain<chainParams.numChains; chain++)
+ {
+ for (k=0; k<numApplicableMoves; k++)
+ {
+ mv = moves[k];
+ if (mv->parm != p)
+ continue;
+ chainIndex = run*chainParams.numChains + chain;
+ refIndex = chain;
+ if (AreDoublesEqual (mv->relProposalProb[chainIndex], mv->relProposalProb[refIndex], 0.000001) == NO)
+ areRunsSame = NO;
+ }
+ }
+ }
+
+ for (run=0; run<chainParams.numRuns; run++)
+ {
+ if (run > 0 && areRunsSame == YES)
+ continue;
+
+ /* check if chains are same */
+ areChainsSame = YES;
+ for (chain=1; chain<chainParams.numChains; chain++)
+ {
+ for (k=0; k<numApplicableMoves; k++)
+ {
+ mv = moves[k];
+ if (mv->parm != p)
+ continue;
+ chainIndex = run*chainParams.numChains + chain;
+ refIndex = run*chainParams.numChains;
+ if (AreDoublesEqual (mv->relProposalProb[chainIndex], mv->relProposalProb[refIndex], 0.000001) == NO)
+ areChainsSame = NO;
+ }
+ }
+
+ /* now print moves */
+ for (chain=0; chain<chainParams.numChains; chain++)
+ {
+ if (chain > 0 && areChainsSame == YES)
+ continue;
+ if (run==0 && chain==0)
+ MrBayesPrint ("%s Moves = ", spacer);
+ else
+ MrBayesPrint ("%s ", spacer);
+ numPrinted = 0;
+ printedCol = (int)(strlen(spacer)) + 25;
+ for (k=0; k<numApplicableMoves; k++)
+ {
+ mv = moves[k];
+ if (mv->parm != p)
+ continue;
+ chainIndex = run*chainParams.numChains + chain;
+ if (mv->relProposalProb[chainIndex] <= 0.000001)
+ continue;
+ if (numPrinted == 0)
+ {
+ MrBayesPrint ("%s <prob %.1f>", mv->name, mv->relProposalProb[chainIndex]);
+ printedCol += 9 + (int)strlen(mv->name) + (int)(log10(mv->relProposalProb[chainIndex])) + 3;
+ }
+ else
+ {
+ if (printedCol + 11 + (int)(strlen(mv->name)) + (int)(log10(mv->relProposalProb[chainIndex])) + 3 > screenWidth)
+ {
+ MrBayesPrint(", \n%s ", spacer);
+ printedCol = 25 + (int)(strlen(spacer));
+ }
+ else
+ {
+ MrBayesPrint(", ");
+ printedCol += 2;
+ }
+ MrBayesPrint ("%s <prob %.1f>", mv->name, mv->relProposalProb[chainIndex]);
+ printedCol += (9 + (int)(strlen(mv->name)) + (int)(log10(mv->relProposalProb[chainIndex])) + 3);
+ }
+ numPrinted++;
+ }
+
+ if (numPrinted == 0 && p->paramType == P_BRLENS)
+ {
+ for (k=0; k<numParams; k++)
+ if (params[k].tree == p->tree)
+ break;
+ MrBayesPrint ("For moves, see param. '%s'", params[k].name);
+ }
+ else if (numPrinted == 0)
+ MrBayesPrint ("WARNING! No moves -- param. fixed to startvals");
+
+ if (areRunsSame == YES && areChainsSame == YES)
+ MrBayesPrint ("\n");
+ else if (areRunsSame == YES && areChainsSame == NO)
+ MrBayesPrint (" [chain %d]\n", chain+1);
+ else if (areRunsSame == NO && areChainsSame == YES)
+ MrBayesPrint (" [run %d]\n", run+1);
+ else /* if (areRunsSame == NO && areChainsSame == NO) */
+ MrBayesPrint (" [run %d, chain %d]\n", run+1, chain+1);
+ }
+ }
+ }
+
+ /* show available moves */
+ if (showAllAvailable == YES && (p->printParam == YES || p->paramType == P_TOPOLOGY || p->paramType == P_BRLENS))
+ {
+ /* loop over moves */
+ numPrinted = 0;
+ printedCol = 0;
+ for (k=0; k<numApplicableMoves; k++)
+ {
+ mv = moves[k];
+ if (mv->parm != p)
+ continue;
+ numMovedChains = 0;
+ for (run=0; run<chainParams.numRuns; run++)
+ {
+ for (chain=0; chain<chainParams.numChains; chain++)
+ {
+ chainIndex = run*chainParams.numChains + chain;
+ if (mv->relProposalProb[chainIndex] > 0.000001)
+ numMovedChains++;
+ }
+ }
+ if (numMovedChains == 0)
+ {
+ if (numPrinted == 0)
+ {
+ MrBayesPrint ("%s Not used = ", spacer);
+ printedCol = (int)(strlen(spacer)) + 25;
+ }
+ else if (printedCol + 2 + (int)(strlen(mv->moveType->shortName)) > screenWidth)
+ {
+ MrBayesPrint (", \n%s ", spacer);
+ printedCol = (int)(strlen(spacer)) + 25;
+ }
+ else
+ {
+ MrBayesPrint (", ");
+ printedCol += 2;
+ }
+ MrBayesPrint("%s", mv->moveType->shortName);
+ printedCol += (int)strlen(mv->moveType->shortName);
+ numPrinted++;
+ }
+ }
+ if (numPrinted > 0)
+ MrBayesPrint ("\n");
+ }
+
+ /* show startvals */
+ if (showStartVals == YES && (p->printParam == YES || p->paramType == P_TOPOLOGY || p->paramType == P_BRLENS || p->paramType == P_SPECIESTREE || p->paramType == P_POPSIZE))
+ {
+ if (p->paramType == P_TOPOLOGY || p->paramType == P_BRLENS || p->paramType == P_SPECIESTREE)
+ {
+ /* check if they are the same */
+ areRunsSame = YES;
+ if (p->paramType == P_TOPOLOGY)
+ {
+ for (run=1; run<chainParams.numRuns; run++)
+ {
+ for (chain=0; chain<chainParams.numChains; chain++)
+ {
+ if (AreTopologiesSame (GetTree (p, run*chainParams.numChains + chain, 0), GetTree (p, chain, 0)) == NO)
+ {
+ areRunsSame = NO;
+ break;
+ }
+ }
+ }
+ }
+ else if (p->paramType == P_BRLENS)
+ {
+ for (run=1; run<chainParams.numRuns; run++)
+ {
+ for (chain=0; chain<chainParams.numChains; chain++)
+ {
+ if (AreTreesSame (GetTree (p, run*chainParams.numChains + chain, 0), GetTree (p, chain, 0)) == NO)
+ {
+ areRunsSame = NO;
+ break;
+ }
+ }
+ }
+ }
+ else if (p->paramType == P_SPECIESTREE)
+ {
+ for (run=1; run<chainParams.numRuns; run++)
+ {
+ for (chain=0; chain<chainParams.numChains; chain++)
+ {
+ if (AreTreesSame (GetTree (p, run*chainParams.numChains + chain, 0), GetTree (p, chain, 0)) == NO)
+ {
+ areRunsSame = NO;
+ break;
+ }
+ }
+ }
+ }
+
+ /* print trees */
+ for (run=0; run<chainParams.numRuns; run++)
+ {
+ if (run > 0 && areRunsSame == YES)
+ break;
+ for (chain=0; chain<chainParams.numChains; chain++)
+ {
+ if (run == 0 && chain == 0)
+ MrBayesPrint ("%s Startvals = tree '%s'", spacer, GetTree (p, run*chainParams.numChains+chain, 0)->name);
+ else
+ MrBayesPrint ("%s tree '%s'", spacer, GetTree (p, run*chainParams.numChains+chain, 0)->name);
+ if (chainParams.numChains > 1 && areRunsSame == YES)
+ MrBayesPrint (" [chain %d]", chain+1);
+ else if (chainParams.numChains == 1 && areRunsSame == NO)
+ MrBayesPrint (" [run %d]", run+1);
+ else if (areRunsSame == NO)
+ MrBayesPrint (" [run %d, chain %d]", run+1, chain+1);
+ MrBayesPrint ("\n");
+ }
+ }
+ } /* end topology and brlens parameters */
+
+ else if (p->paramType == P_OMEGA && p->paramId != OMEGA_DIR && p->paramId != OMEGA_FIX &&
+ p->paramId != OMEGA_FFF && p->paramId != OMEGA_FF && p->paramId != OMEGA_10FFF)
+ {
+ /* we need to print values and subvalues for the category frequencies in a NY98-like model. */
+ areRunsSame = YES;
+ for (run=1; run<chainParams.numRuns; run++)
+ {
+ for (chain=0; chain<chainParams.numChains; chain++)
+ {
+ value = GetParamVals (p, run*chainParams.numRuns+chain, 0);
+ refValue = GetParamVals (p, chain, 0);
+ nValues = p->nValues;
+ for (k=0; k<nValues; k++)
+ {
+ if (AreDoublesEqual (value[k], refValue[k], 0.000001) == NO)
+ {
+ areRunsSame = NO;
+ break;
+ }
+ }
+ value = GetParamSubVals (p, run*chainParams.numRuns+chain, 0);
+ refValue = GetParamSubVals (p, chain, 0);
+ if (!strcmp(modelParams[p->relParts[0]].omegaVar, "M10"))
+ {
+ value += (mp->numM10BetaCats + mp->numM10GammaCats);
+ refValue += (mp->numM10BetaCats + mp->numM10GammaCats);
+ for (k=0; k<4; k++)
+ {
+ if (AreDoublesEqual (value[k + 4], refValue[k + 4], 0.000001) == NO)
+ {
+ areRunsSame = NO;
+ break;
+ }
+ }
+ for (k=0; k<2; k++)
+ {
+ if (AreDoublesEqual (value[k], refValue[k], 0.000001) == NO)
+ {
+ areRunsSame = NO;
+ break;
+ }
+ }
+ }
+ else
+ {
+ for (k=0; k<3; k++)
+ {
+ if (AreDoublesEqual (value[k], refValue[k], 0.000001) == NO)
+ {
+ areRunsSame = NO;
+ break;
+ }
+ }
+ }
+ if (areRunsSame == NO)
+ break;
+ }
+ if (areRunsSame == NO)
+ break;
+ }
+
+ /* now print values */
+ for (run=0; run<chainParams.numRuns; run++)
+ {
+ for (chain=0; chain<chainParams.numChains; chain++)
+ {
+ value = GetParamVals (p, run*chainParams.numRuns+chain, 0);
+ subValue = GetParamSubVals (p, run*chainParams.numRuns+chain, 0);
+ nValues = p->nValues;
+ if (run == 0 && chain == 0)
+ MrBayesPrint ("%s Startvals = (%1.3lf", spacer, value[0]);
+ else
+ MrBayesPrint ("%s (%1.3lf", spacer, value[0]);
+ for (k=1; k<nValues; k++)
+ {
+ MrBayesPrint (",%1.3lf", value[k]);
+ }
+
+ if (!strcmp(modelParams[p->relParts[0]].omegaVar, "M10"))
+ {
+ for (k=0; k<4; k++)
+ {
+ MrBayesPrint (",%1.3lf", subValue[k + mp->numM10BetaCats+mp->numM10GammaCats+4]);
+ }
+ for (k=0; k<2; k++)
+ {
+ MrBayesPrint (",%1.3lf", subValue[k + mp->numM10BetaCats+mp->numM10GammaCats]);
+ }
+ }
+ else
+ {
+ for (k=0; k<3; k++)
+ {
+ MrBayesPrint (",%1.3lf", subValue[k]);
+ }
+ }
+ MrBayesPrint (")");
+ if (chainParams.numChains > 1 && areRunsSame == YES)
+ MrBayesPrint (" [chain %d]\n", chain+1);
+ else if (chainParams.numChains == 1 && areRunsSame == NO)
+ MrBayesPrint (" [run %d]\n", run+1);
+ else if (areRunsSame == NO)
+ MrBayesPrint (" [run %d, chain %d]\n", run+1, chain+1);
+ }
+ }
+ }
+ else
+ {
+ /* run of the mill parameter */
+ if (p->paramType == P_CLOCKRATE)
+ {
+ for (j=0; j<numGlobalChains; j++)
+ {
+ if (UpdateClockRate(-1.0, j) == ERROR)
+ {
+ MrBayesPrint ("%s Warning: There is no appropriate clock rate that would satisfy all calibrated trees for run:%d chain%d. Some of calibration, trees or clockprior needs to be changed. ", spacer, j/chainParams.numChains, j%chainParams.numChains);
+ }
+ }
+ }
+ areRunsSame = YES;
+ for (run=1; run<chainParams.numRuns; run++)
+ {
+ for (chain=0; chain<chainParams.numChains; chain++)
+ {
+ if ((p->paramType == P_PI && modelParams[p->relParts[0]].dataType != STANDARD))
+ {
+ nValues = p->nSubValues;
+ value = GetParamSubVals (p, run*chainParams.numChains+chain, 0);
+ refValue = GetParamSubVals (p, chain, 0);
+ }
+ else
+ {
+ nValues = p->nValues;
+ value = GetParamVals (p, run*chainParams.numChains+chain, 0);
+ refValue = GetParamVals (p, chain, 0);
+ }
+ for (k=0; k<nValues; k++)
+ {
+ if (AreDoublesEqual(value[k], refValue[k], 0.000001) == NO)
+ {
+ areRunsSame = NO;
+ break;
+ }
+ }
+ if (areRunsSame == NO)
+ break;
+ }
+ if (areRunsSame == NO)
+ break;
+ }
+
+ /* print values */
+ for (run=0; run<chainParams.numRuns; run++)
+ {
+ if (run > 0 && areRunsSame == YES)
+ break;
+ areChainsSame = YES;
+ for (chain=1; chain<chainParams.numChains; chain++)
+ {
+ if ((p->paramType == P_PI && modelParams[p->relParts[0]].dataType != STANDARD))
+ {
+ nValues = p->nSubValues;
+ value = GetParamSubVals (p, run*chainParams.numChains+chain, 0);
+ refValue = GetParamSubVals (p, run*chainParams.numChains, 0);
+ }
+ else
+ {
+ nValues = p->nValues;
+ value = GetParamVals (p, run*chainParams.numChains+chain, 0);
+ refValue = GetParamVals (p, run*chainParams.numChains, 0);
+ }
+ for (k=0; k<nValues; k++)
+ {
+ if (AreDoublesEqual(value[k], refValue[k], 0.000001) == NO)
+ {
+ areChainsSame = NO;
+ break;
+ }
+ }
+ }
+ for (chain=0; chain<chainParams.numChains; chain++)
+ {
+ if (areChainsSame == YES && chain > 0)
+ continue;
+
+ if ((p->paramType == P_PI && modelParams[p->relParts[0]].dataType != STANDARD))
+ {
+ nValues = p->nSubValues;
+ value = GetParamSubVals (p, run*chainParams.numChains+chain, 0);
+ }
+ else
+ {
+ nValues = p->nValues;
+ value = GetParamVals (p, run*chainParams.numChains+chain, 0);
+ }
+
+ if (run == 0 && chain == 0)
+ MrBayesPrint ("%s Startvals = (%1.3lf", spacer, value[0]);
+ else
+ MrBayesPrint ("%s (%1.3lf", spacer, value[0]);
+
+ for (k=1; k<nValues; k++)
+ {
+ if (k%10==0)
+ MrBayesPrint (",\n%s %1.3lf", spacer, value[k]);
+ else
+ MrBayesPrint (",%1.3lf", value[k]);
+ }
+ MrBayesPrint (")");
+
+ if (areChainsSame == YES && areRunsSame == NO)
+ MrBayesPrint (" [run %d]", run+1);
+ else if (areChainsSame == NO && areRunsSame == YES)
+ MrBayesPrint (" [chain %d]", chain+1);
+ else if (areChainsSame == NO && areRunsSame == NO)
+ MrBayesPrint (" [run %d, chain %d]", run+1, chain+1);
+ MrBayesPrint ("\n");
+ }
+ }
+ }
+ } /* end print start values */
+
+ MrBayesPrint ("\n");
+ } /* next parameter */
+
+ return (NO_ERROR);
+}
+
+
+int Unlink (void)
+{
+ return (NO_ERROR);
+}
+
+
+/*-------------------------------------------------
+|
+| UpdateClockRate: Update clockRate of the given chain. Above all it will enforce fixed clockrate prior if it is set.
+| Error will be returned if fixed clockrate prior may not be respected.
+| @param clockRate is the new clockRate to setup. Clock rate value could be set as positive, 0.0 or negative value.
+| The function does the fallowing depending on one of this three values:
+| positive - check that this 'positive' value is suitable rate. At the end re-enforce (update) the 'positive' value as clock rate on all trees.
+| 0.0 - check if current rate is suitable, if not update it with minimal suitable value. At the end re-enforce (update) the resulting clock rate on all trees.
+| negative - check if current rate is suitable, if not update it with minimal suitable value. At the end re-enforce (update) the resulting clock rate ONLY if clock rate was changed
+| @return ERROR if clockRate can not be set up, NO_ERROR otherwise.
+|
+--------------------------------------------------*/
+int UpdateClockRate (MrBFlt clockRate, int chain)
+{
+ int i, updateTrees;
+ MrBFlt *clockRatep;
+ Tree *t, *t_calibrated=NULL;
+ MrBFlt mintmp,maxtmp,minClockRate,maxClockRate;
+
+ clockRatep=NULL;
+ minClockRate = 0.0;
+ maxClockRate = MRBFLT_MAX;
+
+ for (i=0; i<numTrees; i++)
+ {
+ t = GetTreeFromIndex(i, chain, 0);
+ if (t->isCalibrated == NO)
+ continue;
+
+ if (clockRatep == NULL)
+ {
+ clockRatep = GetParamVals(modelSettings[t->relParts[0]].clockRate, chain, 0);
+ t_calibrated = t;
+ assert (clockRatep);
+ }
+
+ findAllowedClockrate (t, &mintmp, &maxtmp);
+
+ if (minClockRate < mintmp)
+ minClockRate = mintmp;
+
+ if (maxClockRate > maxtmp)
+ maxClockRate = maxtmp;
+
+ }
+ /* clock rate is the same for all trees of a given chain */
+ if (clockRatep != NULL)
+ {
+ if (minClockRate > maxClockRate)
+ {
+ MrBayesPrint ("%s ERROR: Calibrated trees require compatible clockrates but they are incompatible for run %d, chain %d.\n",
+ spacer, chain/chainParams.numChains + 1, chain%chainParams.numChains + 1);
+ *clockRatep=0;
+ return (ERROR);
+ }
+
+ if (!strcmp(modelParams[t_calibrated->relParts[0]].clockRatePr, "Fixed"))
+ {
+ if (clockRate < 0.0 && AreDoublesEqual (*clockRatep, modelParams[t_calibrated->relParts[0]].clockRateFix, 0.0001) == YES)
+ {
+ updateTrees = NO;
+ }
+ else
+ {
+ updateTrees = YES;
+ }
+ *clockRatep = modelParams[t_calibrated->relParts[0]].clockRateFix;
+ if ((*clockRatep < minClockRate && AreDoublesEqual (*clockRatep, minClockRate, 0.0001) == NO) ||
+ (*clockRatep > maxClockRate && AreDoublesEqual (*clockRatep, maxClockRate, 0.0001) == NO))
+ {
+ MrBayesPrint ("%s ERROR: Calibrated trees require clockrate in range from %f to %f, while clockrate prior is fixed to %f for run %d chain %d.\n",
+ spacer, minClockRate, maxClockRate, *clockRatep, chain/chainParams.numChains + 1, chain%chainParams.numChains + 1);
+ *clockRatep=0;
+ return (ERROR);
+ }
+ if (clockRate > 0.0)
+ {
+ if (AreDoublesEqual (*clockRatep, clockRate, 0.0001) == NO)
+ {
+ MrBayesPrint ("%s ERROR: Requested clockrate:%f does not match fixed clockrate prior:%f.\n", spacer, clockRate, *clockRatep);
+ *clockRatep=0;
+ return (ERROR);
+ }
+ }
+ }
+ else {
+ /* clock prior is not fixed */
+ updateTrees = YES;
+ if (clockRate > 0.0)
+ {
+ *clockRatep = clockRate;
+ if ((*clockRatep < minClockRate && AreDoublesEqual (*clockRatep, minClockRate, 0.0001) == NO) ||
+ (*clockRatep > maxClockRate && AreDoublesEqual (*clockRatep, maxClockRate, 0.0001) == NO))
+ {
+ MrBayesPrint ("%s ERROR: Calibrated trees require clockrate in range from %f to %f, while requested clockrate is %f for run %d chain %d.\n",
+ spacer, minClockRate, maxClockRate, clockRate, chain/chainParams.numChains + 1, chain%chainParams.numChains + 1);
+ *clockRatep=0;
+ return (ERROR);
+ }
+ }
+ else if (clockRate == 0.0)
+ {
+ if ((*clockRatep < minClockRate && AreDoublesEqual (*clockRatep, minClockRate, 0.0001) == NO) ||
+ (*clockRatep > maxClockRate && AreDoublesEqual (*clockRatep, maxClockRate, 0.0001) == NO))
+ {
+ *clockRatep = minClockRate;
+ }
+ }
+ else // if (clockRate < 0.0)
+ {
+ if ((*clockRatep < minClockRate && AreDoublesEqual (*clockRatep, minClockRate, 0.0001) == NO) ||
+ (*clockRatep > maxClockRate && AreDoublesEqual (*clockRatep, maxClockRate, 0.0001) == NO))
+ {
+ *clockRatep = minClockRate;
+ }
+ else
+ {
+ updateTrees = NO;
+ }
+ }
+ }
+
+
+ if (updateTrees == YES)
+ {
+ for (i=0; i<numTrees; i++)
+ {
+ t = GetTreeFromIndex(i, chain, 0);
+ if (t->isCalibrated == NO)
+ continue;
+ UpdateTreeWithClockrate (t,*clockRatep);
+ }
+ }
+ }
+
+ return (NO_ERROR);
+}
+
+
+/*----------------------------------------------
+|
+| UpdateCppEvolLength: Recursive function to
+| update evolLength of one node for Cpp
+| relaxed clock model
+|
+-----------------------------------------------*/
+int UpdateCppEvolLength (int *nEvents, MrBFlt **pos, MrBFlt **rateMult, MrBFlt *evolLength, TreeNode *p, MrBFlt baseRate)
+{
+ int i;
+ MrBFlt endRate;
+
+ if (p != NULL)
+ {
+# ifdef DEBUG_CPP
+ if (baseRate < POS_MIN || baseRate > POS_INFINITY)
+ {
+ printf ("baseRate out of bounds (%.15e for node %d\n", baseRate, p->index);
+ return (ERROR);
+ }
+# endif
+ p->upDateTi = YES;
+ p->upDateCl = YES;
+ if (nEvents[p->index] == 0)
+ {
+ evolLength[p->index] = p->length * baseRate;
+ }
+ else
+ {
+ /* note that event positions are from the top of the branch (more recent)
+ to the bottom of the branch (older) */
+ /* The algorithm below successively multiplies in the more basal rate multipliers,
+ starting from the top of the branch. The length of the branch is first assumed
+ to be 1.0; at the end we multiply the result with the true length of the branch. */
+ evolLength[p->index] = pos[p->index][0] * rateMult[p->index][0];
+ for (i=1; i<nEvents[p->index]; i++)
+ {
+ evolLength[p->index] += (pos[p->index][i] - pos[p->index][i-1]);
+ evolLength[p->index] *= rateMult[p->index][i];
+ }
+ evolLength[p->index] += (1.0 - pos[p->index][nEvents[p->index]-1]);
+ evolLength[p->index] *= baseRate;
+ evolLength[p->index] *= p->length;
+ }
+
+ /* calculate end rate; we can do this in any order */
+ endRate = baseRate;
+ for (i=0; i<nEvents[p->index]; i++)
+ endRate *= rateMult[p->index][i];
+
+# ifdef DEBUG_CPP
+ if (endRate < POS_MIN || endRate > POS_INFINITY)
+ {
+ printf ("endRate out of bounds (%.15e for node %d)\n", endRate, p->index);
+ return (ERROR);
+ }
+ if (p->anc != NULL && p->anc->anc != NULL && (evolLength[p->index] < POS_MIN || evolLength[p->index] > POS_INFINITY))
+ {
+ printf ("Effective branch length out of bounds (%.15e for node %d)\n", evolLength[p->index], p->index);
+ return (ERROR);
+ }
+# endif
+ /* call left and right descendants */
+ if (UpdateCppEvolLength (nEvents, pos, rateMult, evolLength, p->left, endRate)==ERROR)
+ return (ERROR);
+ if (UpdateCppEvolLength (nEvents, pos, rateMult, evolLength, p->right, endRate)==ERROR)
+ return (ERROR);
+ }
+
+ return (NO_ERROR);
+}
+
+
+/*-------------------------------------------------
+ |
+ | UpdateCppEvolLengths: Recalculate effective
+ | evolutionary lengths and set update flags
+ | for Cpp relaxed clock model
+ |
+ --------------------------------------------------*/
+int UpdateCppEvolLengths (Param *param, TreeNode *p, int chain)
+{
+ int i, *nEvents;
+ TreeNode *q;
+ MrBFlt baseRate = 1.0, **pos, **rateMult, *evolLength;
+
+ i = 2*chain + state[chain];
+ nEvents = param->nEvents[i];
+ pos = param->position[i];
+ rateMult = param->rateMult[i];
+ evolLength = GetParamSubVals (param, chain, state[chain]);
+
+ q = p->anc;
+ while (q->anc != NULL)
+ {
+ for (i=0; i<nEvents[q->index]; i++)
+ baseRate *= rateMult[q->index][i];
+ q = q->anc;
+ }
+
+ if (UpdateCppEvolLength (nEvents, pos, rateMult, evolLength, p, baseRate)==ERROR)
+ return (ERROR);
+
+ return(NO_ERROR);
+}
+
+
+/* UpdateTK02EvolLengths: update branch lengths for tk02 model */
+int UpdateTK02EvolLengths (Param *param, Tree *t, int chain)
+{
+ int i;
+ MrBFlt *tk02Rate, *brlens;
+ TreeNode *p;
+
+ tk02Rate = GetParamVals (param, chain, state[chain]);
+ brlens = GetParamSubVals (param, chain, state[chain]);
+ for (i=0; i<t->nNodes-2; i++)
+ {
+ p = t->allDownPass[i];
+ brlens[p->index] = p->length * (tk02Rate[p->index] + tk02Rate[p->anc->index]) / 2.0;
+ }
+
+ return (NO_ERROR);
+}
+
+
+/* UpdateIgrBranchLengths: update branch lengths for igr model */
+int UpdateIgrBrachLengths (Param *param, Tree *t, int chain)
+{
+ int i;
+ MrBFlt *igrRate, *brlens;
+ TreeNode *p;
+
+ igrRate = GetParamVals (param, chain, state[chain]);
+ brlens = GetParamSubVals (param, chain, state[chain]);
+ for (i=0; i<t->nNodes-2; i++)
+ {
+ p = t->allDownPass[i];
+ brlens[p->index] = p->length * igrRate[p->index];
+ }
+
+ return (NO_ERROR);
+}
+