1 /*
2 * MrBayes 3
3 *
4 * (c) 2002-2013
5 *
6 * John P. Huelsenbeck
7 * Dept. Integrative Biology
8 * University of California, Berkeley
9 * Berkeley, CA 94720-3140
10 * johnh@berkeley.edu
11 *
12 * Fredrik Ronquist
13 * Swedish Museum of Natural History
14 * Box 50007
15 * SE-10405 Stockholm, SWEDEN
16 * fredrik.ronquist@nrm.se
17 *
18 * With important contributions by
19 *
20 * Paul van der Mark (paulvdm@sc.fsu.edu)
21 * Maxim Teslenko (maxkth@gmail.com)
22 * Chi Zhang (zhangchicool@gmail.com)
23 *
24 * and by many users (run 'acknowledgments' to see more info)
25 *
26 * This program is free software; you can redistribute it and/or
27 * modify it under the terms of the GNU General Public License
28 * as published by the Free Software Foundation; either version 2
29 * of the License, or (at your option) any later version.
30 *
31 * This program is distributed in the hope that it will be useful,
32 * but WITHOUT ANY WARRANTY; without even the implied warranty of
33 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34 * GNU General Public License for more details (www.gnu.org).
35 *
36 */
37
38 #include "bayes.h"
39 #include "command.h"
40 #include "mcmc.h"
41 #include "sumpt.h"
42 #include "utils.h"
43 #if defined(__MWERKS__)
44 #include "SIOUX.h"
45 #endif
46
47 typedef struct partctr
48 {
49 struct partctr *left, *right;
50 BitsLong *partition;
51 int totCount;
52 int *count;
53 MrBFlt **length;
54 MrBFlt **height;
55 MrBFlt **age;
56 int ***nEvents; /* nEvents[0,nESets][0,numRuns][0,count[RunID]] */
57 MrBFlt ***bRate; /* bRate [0,nBSets][0,numRuns][0,count[RunID]] */
58 MrBFlt ***bLen; /* bLen [0,nBSets][0,numRuns][0,count[RunID]] */
59 MrBFlt **popSize; /* popSize[0,numRuns][0,count[RunID]] */
60 }
61 PartCtr;
62
63 typedef struct treectr
64 {
65 struct treectr *left, *right;
66 int count;
67 int *order;
68 }
69 TreeCtr;
70
71 typedef struct
72 {
73 int longestLineLength;
74 int numTreeBlocks;
75 int lastTreeBlockBegin;
76 int lastTreeBlockEnd;
77 int numTreesInLastBlock;
78 }
79 SumtFileInfo;
80
81 #define ALLOC_LEN 100 /* number of values to allocate each time in partition counter nodes */
82
83 #if defined (PRINT_RATEMUL_CPP)
84 FILE *rateMultfp=NULL;
85 #endif
86
87 #undef DEBUG_CONTREE
88
89 extern int inSumtCommand;
90 extern int inComparetreeCommand;
91 extern int DoUserTree (void);
92 extern int DoUserTreeParm (char *parmName, char *tkn);
93 extern int SafeFclose(FILE **);
94
95 extern int SetUpPartitionCounters (void);
96 extern int AddTreeToPartitionCounters (Tree *tree, int treeId, int runId);
97 extern void CalcTopoConvDiagn2 (int *nTrees);
98 extern void FreeChainMemory (void);
99
100 /* local prototypes */
101 int CompareModelProbs (const void *x, const void *y);
102 int PrintModelStats (char *fileName, char **headerNames, int nHeaders, ParameterSample *parameterSamples, int nRuns, int nSamples);
103 int PrintOverlayPlot (MrBFlt **xVals, MrBFlt **yVals, int nRows, int startingFrom, int nSamples);
104 int PrintParamStats (char *fileName, char **headerNames, int nHeaders, ParameterSample *parameterSamples, int nRuns, int nSamples);
105 void PrintPlotHeader (void);
106
107 PartCtr *AddSumtPartition (PartCtr *r, PolyTree *t, PolyNode *p, int runId);
108 TreeCtr *AddSumtTree (TreeCtr *r, int *order);
109 PartCtr *AllocPartCtr (void);
110 TreeCtr *AllocTreeCtr (void);
111 void CalculateTreeToTreeDistance (Tree *tree1, Tree *tree2, MrBFlt *d1, MrBFlt *d2, MrBFlt *d3);
112 int ConTree (PartCtr **treeParts, int numTreeParts);
113 MrBFlt CppEvolRate (PolyTree *t, PolyNode *p, int eSet);
114 int ExamineSumtFile (char *fileName, SumtFileInfo *sumtFileInfo, char *treeName, int *brlensDef);
115 void FreePartCtr (PartCtr *r);
116 void FreeSumtParams (void);
117 void FreeTreeCtr (TreeCtr *r);
118 int Label (PolyNode *p, int addIndex, char *label, int maxLength);
119 int OpenBrlensFile (int treeNo);
120 int OpenComptFiles (void);
121 int OpenSumtFiles (int treeNo);
122 void PartCtrUppass (PartCtr *r, PartCtr **uppass, int *index);
123 int PrintBrParamsToFile (PartCtr **treeParts, int numTreeParts, int treeNo, char *divString);
124 void PrintConTree (FILE *fp, PolyTree *t);
125 void PrintFigTreeConTree (FILE *fp, PolyTree *t, PartCtr **treeParts);
126 void PrintFigTreeNodeInfo (FILE *fp, PartCtr *x, MrBFlt length);
127 void PrintSumtTableLine (int numRuns, int *rowCount, Stat *theStats, MrBFlt *numPSRFSamples, MrBFlt *maxPSRF, MrBFlt *sumPSRF);
128 void PrintSumtTaxaInfo (void);
129 void Range (MrBFlt *vals, int nVals, MrBFlt *min, MrBFlt *max);
130 void ResetTaxonSet (void);
131 int ShowConPhylogram (FILE *fp, PolyTree *t, int screenWidth);
132 void ShowSomeParts (FILE *fp, BitsLong *p, int offset, int nTaxaToShow);
133 void SortPartCtr (PartCtr **item, int left, int right);
134 void SortTerminalPartCtr (PartCtr **item, int len);
135 void SortTreeCtr (TreeCtr **item, int left, int right);
136 int StoreSumtTree (PackedTree *treeList, int index, PolyTree *t);
137 void TreeCtrUppass (TreeCtr *r, TreeCtr **uppass, int *index);
138 int TreeProb (void);
139 void WriteConTree (PolyNode *p, FILE *fp, int showSupport);
140 void WriteFigTreeConTree (PolyNode *p, FILE *fp, PartCtr **treeParts);
141
142 /* local (to this file) */
143 static int numUniqueSplitsFound, numUniqueTreesFound, numPackedTrees[2], numAsterices; /* length of local to this file variables */
144 static FILE *fpParts=NULL, *fpTstat=NULL, *fpVstat, *fpCon=NULL, *fpTrees=NULL, *fpDists=NULL; /* file pointers */
145 static PartCtr *partCtrRoot = NULL; /* binary tree for holding splits info */
146 static TreeCtr *treeCtrRoot = NULL; /* binary tree for holding unique tree info */
147 static PackedTree *packedTreeList[2]; /* list of trees in packed format */
148
149
150 /* AllocateParameterSamples: Allocate space for parameter samples */
AllocateParameterSamples(ParameterSample ** parameterSamples,int numRuns,int numRows,int numColumns)151 int AllocateParameterSamples (ParameterSample **parameterSamples, int numRuns, int numRows, int numColumns)
152 {
153 int i, j;
154
155 (*parameterSamples) = (ParameterSample *) SafeCalloc (numColumns, sizeof(ParameterSample));
156 if (!(*parameterSamples))
157 return ERROR;
158 (*parameterSamples)[0].values = (MrBFlt **) SafeCalloc (numColumns * numRuns, sizeof (MrBFlt *));
159 if (!((*parameterSamples)[0].values))
160 {
161 FreeParameterSamples(*parameterSamples);
162 return ERROR;
163 }
164 (*parameterSamples)[0].values[0] = (MrBFlt *) SafeCalloc (numColumns * numRuns * numRows, sizeof (MrBFlt));
165 for (i=1; i<numColumns; i++)
166 (*parameterSamples)[i].values = (*parameterSamples)[0].values + i*numRuns;
167 for (i=1; i<numRuns; i++)
168 (*parameterSamples)[0].values[i] = (*parameterSamples)[0].values[0] + i*numRows;
169 for (i=1; i<numColumns; i++)
170 {
171 for (j=0; j<numRuns; j++)
172 {
173 (*parameterSamples)[i].values[j] = (*parameterSamples)[0].values[0] + i*numRuns*numRows + j*numRows;
174 }
175 }
176
177 return NO_ERROR;
178 }
179
180
181 /** Compare function (ModelProb) for qsort. Note reverse sort order (from larger to smaller probs) */
CompareModelProbs(const void * x,const void * y)182 int CompareModelProbs (const void *x, const void *y) {
183
184 if ((*((ModelProb *)(x))).prob > (*((ModelProb *)(y))).prob)
185 return -1;
186 else if ((*((ModelProb *)(x))).prob < (*((ModelProb *)(y))).prob)
187 return 1;
188 else
189 return 0;
190 }
191
192
DoSump(void)193 int DoSump (void)
194 {
195 int i, n, nHeaders=0, numRows, numColumns, numRuns, whichIsX, whichIsY,
196 unreliable, oneUnreliable, burnin, longestHeader, len;
197 MrBFlt mean, harm_mean;
198 char **headerNames=NULL, temp[120];
199 SumpFileInfo fileInfo, firstFileInfo;
200 ParameterSample *parameterSamples=NULL;
201 FILE *fpLstat=NULL;
202
203 # if defined (MPI_ENABLED)
204 if (proc_id != 0)
205 return NO_ERROR;
206 # endif
207
208 /* tell user we are ready to go */
209 if (sumpParams.numRuns == 1)
210 MrBayesPrint ("%s Summarizing parameters in file %s.p\n", spacer, sumpParams.sumpFileName);
211 else if (sumpParams.numRuns == 2)
212 MrBayesPrint ("%s Summarizing parameters in files %s.run1.p and %s.run2.p\n", spacer, sumpParams.sumpFileName, sumpParams.sumpFileName);
213 else /* if (sumpParams.numRuns > 2) */
214 {
215 MrBayesPrint ("%s Summarizing parameters in %d files (%s.run1.p,\n", spacer, sumpParams.numRuns, sumpParams.sumpFileName);
216 MrBayesPrint ("%s %s.run2.p, etc)\n", spacer, sumpParams.sumpFileName);
217 }
218 MrBayesPrint ("%s Writing summary statistics to file %s.pstat\n", spacer, sumpParams.sumpFileName);
219
220 if (chainParams.relativeBurnin == YES)
221 MrBayesPrint ("%s Using relative burnin ('relburnin=yes'), discarding the first %.0f %% of samples\n",
222 spacer, chainParams.burninFraction*100.0, chainParams.burninFraction);
223 else
224 MrBayesPrint ("%s Using absolute burnin ('relburnin=no'), discarding the first %d samples\n",
225 spacer, chainParams.chainBurnIn, chainParams.chainBurnIn);
226
227 /* Initialize to silence warning. */
228 firstFileInfo.numRows = 0;
229 firstFileInfo.numColumns = 0;
230
231 /* examine input file(s) */
232 for (i=0; i<sumpParams.numRuns; i++)
233 {
234 if (sumpParams.numRuns == 1)
235 sprintf (temp, "%s.p", sumpParams.sumpFileName);
236 else
237 sprintf (temp, "%s.run%d.p", sumpParams.sumpFileName, i+1);
238
239 if (ExamineSumpFile (temp, &fileInfo, &headerNames, &nHeaders) == ERROR)
240 goto errorExit;
241
242 if (i==0)
243 {
244 if (fileInfo.numRows == 0 || fileInfo.numColumns == 0)
245 {
246 MrBayesPrint ("%s The number of rows or columns in file %d is equal to zero\n", spacer, temp);
247 goto errorExit;
248 }
249 firstFileInfo = fileInfo;
250 }
251 else
252 {
253 if (firstFileInfo.numRows != fileInfo.numRows || firstFileInfo.numColumns != fileInfo.numColumns)
254 {
255 MrBayesPrint ("%s First file had %d rows and %d columns while file %s had %d rows and %d columns\n",
256 spacer, firstFileInfo.numRows, firstFileInfo.numColumns, temp, fileInfo.numRows, fileInfo.numColumns);
257 MrBayesPrint ("%s MrBayes expects the same number of rows and columns in all files\n", spacer);
258 goto errorExit;
259 }
260 }
261 }
262
263 numRows = fileInfo.numRows;
264 numColumns = fileInfo.numColumns;
265 numRuns = sumpParams.numRuns;
266
267 /* allocate space to hold parameter information */
268 if (AllocateParameterSamples (¶meterSamples, numRuns, numRows, numColumns) == ERROR)
269 return ERROR;
270
271 /* read samples */
272 for (i=0; i<sumpParams.numRuns; i++)
273 {
274 /* derive file name */
275 if (sumpParams.numRuns == 1)
276 sprintf (temp, "%s.p", sumpParams.sumpFileName);
277 else
278 sprintf (temp, "%s.run%d.p", sumpParams.sumpFileName, i+1);
279
280 /* read samples */
281 if (ReadParamSamples (temp, &fileInfo, parameterSamples, i) == ERROR)
282 goto errorExit;
283 }
284
285 /* get length of longest header */
286 longestHeader = 9; /* 9 is the length of the word "parameter" (for printing table) */
287 for (i=0; i<nHeaders; i++)
288 {
289 len = (int) strlen(headerNames[i]);
290 if (len > longestHeader)
291 longestHeader = len;
292 }
293
294 /* Print header */
295 PrintPlotHeader ();
296
297 /* Print trace plots */
298 if (FindHeader("Gen", headerNames, nHeaders, &whichIsX) == ERROR)
299 {
300 MrBayesPrint ("%s Could not find the 'Gen' column\n", spacer);
301 return ERROR;
302 }
303 if (FindHeader("LnL", headerNames, nHeaders, &whichIsY) == ERROR)
304 {
305 MrBayesPrint ("%s Could not find the 'LnL' column\n", spacer);
306 return ERROR;
307 }
308
309 if (sumpParams.numRuns > 1)
310 {
311 if (sumpParams.allRuns == YES)
312 {
313 for (i=0; i<sumpParams.numRuns; i++)
314 {
315 MrBayesPrint ("\n%s Samples from run %d:\n", spacer, i+1);
316 if (PrintPlot (parameterSamples[whichIsX].values[i], parameterSamples[whichIsY].values[i], numRows) == ERROR)
317 goto errorExit;
318 }
319 }
320 else
321 {
322 if (PrintOverlayPlot (parameterSamples[whichIsX].values, parameterSamples[whichIsY].values, numRuns, 0, numRows) == ERROR)
323 goto errorExit;
324 }
325 }
326 else
327 {
328 if (PrintPlot (parameterSamples[whichIsX].values[0], parameterSamples[whichIsY].values[0], numRows) == ERROR)
329 goto errorExit;
330 }
331
332 /* calculate arithmetic and harmonic means of likelihoods */
333
334 /* open output file */
335 strncpy (temp, sumpParams.sumpOutfile, 90);
336 strcat (temp, ".lstat");
337 fpLstat = OpenNewMBPrintFile (temp);
338 if (!fpLstat)
339 goto errorExit;
340
341 /* print unique identifier to the output file */
342 if (strlen(stamp) > 1)
343 MrBayesPrintf (fpLstat, "[ID: %s]\n", stamp);
344
345 /* print header */
346 if (sumpParams.numRuns == 1)
347 MrBayesPrintf (fpLstat, "arithmetic_mean\tharmonic_mean\tvalues_discarded\n");
348 else
349 MrBayesPrintf (fpLstat, "run\tarithmetic_mean\tharmonic_mean\tvalues_discarded\n");
350
351 oneUnreliable = NO;
352 for (n=0; n<sumpParams.numRuns; n++)
353 {
354 unreliable = NO;
355 if (HarmonicArithmeticMeanOnLogs (parameterSamples[whichIsY].values[n], numRows, &mean, &harm_mean) == ERROR)
356 {
357 unreliable = YES;
358 oneUnreliable = YES;
359 }
360 if (sumpParams.numRuns == 1)
361 {
362 MrBayesPrint ("\n");
363 MrBayesPrint ("%s Estimated marginal likelihoods for run sampled in file \"%s.p\":\n", spacer, sumpParams.sumpFileName);
364 MrBayesPrint ("%s (Use the harmonic mean for Bayes factor comparisons of models)\n", spacer, sumpParams.sumpFileName);
365 MrBayesPrint ("%s (Values are saved to the file %s.lstat)\n\n", spacer, sumpParams.sumpOutfile);
366 MrBayesPrint ("%s Arithmetic mean Harmonic mean\n", spacer);
367 MrBayesPrint ("%s --------------------------------\n", spacer);
368 if (unreliable == NO)
369 MrBayesPrint ("%s %9.2lf %9.2lf\n", spacer, mean, harm_mean);
370 else
371 MrBayesPrint ("%s %9.2lf * %9.2lf *\n", spacer, mean, harm_mean);
372
373 /* print to file */
374 MrBayesPrintf (fpLstat, "%s\t", MbPrintNum(mean));
375 MrBayesPrintf (fpLstat, "%s\t", MbPrintNum(harm_mean));
376 if (unreliable == YES)
377 MrBayesPrintf (fpLstat, "yes\n");
378 else
379 MrBayesPrintf (fpLstat, "no\n");
380 }
381 else
382 {
383 if (n == 0)
384 {
385 MrBayesPrint ("\n");
386 MrBayesPrint ("%s Estimated marginal likelihoods for runs sampled in files\n", spacer);
387 if (sumpParams.numRuns > 2)
388 MrBayesPrint ("%s \"%s.run1.p\", \"%s.run2.p\", etc:\n", spacer, sumpParams.sumpFileName, sumpParams.sumpFileName);
389 else /* if (sumpParams.numRuns == 2) */
390 MrBayesPrint ("%s \"%s.run1.p\" and \"%s.run2.p\":\n", spacer, sumpParams.sumpFileName, sumpParams.sumpFileName);
391 MrBayesPrint ("%s (Use the harmonic mean for Bayes factor comparisons of models)\n\n", spacer, sumpParams.sumpFileName);
392 MrBayesPrint ("%s (Values are saved to the file %s.lstat)\n\n", spacer, sumpParams.sumpOutfile);
393 MrBayesPrint ("%s Run Arithmetic mean Harmonic mean\n", spacer);
394 MrBayesPrint ("%s --------------------------------------\n", spacer);
395 }
396 if (unreliable == NO)
397 MrBayesPrint ("%s %3d %9.2lf %9.2lf\n", spacer, n+1, mean, harm_mean);
398 else
399 MrBayesPrint ("%s %3d %9.2lf * %9.2lf *\n", spacer, n+1, mean, harm_mean);
400
401 /* print to file */
402 MrBayesPrintf (fpLstat, "%d\t", n+1);
403 MrBayesPrintf (fpLstat, "%s\t", MbPrintNum(mean));
404 MrBayesPrintf (fpLstat, "%s\t", MbPrintNum(harm_mean));
405 if (unreliable == YES)
406 MrBayesPrintf (fpLstat, "yes\n");
407 else
408 MrBayesPrintf (fpLstat, "no\n");
409 }
410 } /* next run */
411 if (sumpParams.numRuns == 1)
412 {
413 MrBayesPrint ("%s --------------------------------\n", spacer);
414 }
415 else
416 {
417 if (HarmonicArithmeticMeanOnLogs (parameterSamples[whichIsY].values[0], sumpParams.numRuns*numRows, &mean, &harm_mean) == ERROR)
418 {
419 unreliable = YES;
420 oneUnreliable = YES;
421 }
422 else
423 unreliable = NO;
424 MrBayesPrint ("%s --------------------------------------\n", spacer);
425 if (unreliable == YES)
426 MrBayesPrint ("%s TOTAL %9.2lf * %9.2lf *\n", spacer, mean, harm_mean);
427 else
428 MrBayesPrint ("%s TOTAL %9.2lf %9.2lf\n", spacer, mean, harm_mean);
429 MrBayesPrint ("%s --------------------------------------\n", spacer);
430
431 /* print total to file */
432 MrBayesPrintf (fpLstat, "all\t");
433 MrBayesPrintf (fpLstat, "%s\t", MbPrintNum(mean));
434 MrBayesPrintf (fpLstat, "%s\t", MbPrintNum(harm_mean));
435 if (unreliable == YES)
436 MrBayesPrintf (fpLstat, "yes\n");
437 else
438 MrBayesPrintf (fpLstat, "no\n");
439 }
440 if (oneUnreliable == YES)
441 {
442 MrBayesPrint ("%s * These estimates may be unreliable because \n", spacer);
443 MrBayesPrint ("%s some extreme values were excluded\n\n", spacer);
444 }
445 else
446 {
447 MrBayesPrint ("\n");
448 }
449 SafeFclose(&fpLstat);
450
451 /* Calculate burnin */
452 burnin = fileInfo.firstParamLine - fileInfo.headerLine;
453
454 /* Print parameter information to screen and to file. */
455 if (sumpParams.numRuns > 1 && sumpParams.allRuns == YES)
456 {
457 for (i=0; i<sumpParams.numRuns; i++)
458 {
459 /* print table header */
460 MrBayesPrint ("\n");
461 MrBayesPrint ("%s Model parameter summaries for run sampled in file \"%s.run%d.p\":\n", spacer, sumpParams.sumpFileName, i+1);
462 MrBayesPrint ("%s (Based on %d samples out of a total of %d samples from this analysis)\n\n", spacer, numRows, numRows + burnin);
463 if (PrintParamStats (sumpParams.sumpOutfile, headerNames, nHeaders, parameterSamples, numRuns, numRows) == ERROR)
464 goto errorExit;
465 if (PrintModelStats (sumpParams.sumpOutfile, headerNames, nHeaders, parameterSamples, numRuns, numRows) == ERROR)
466 goto errorExit;
467 }
468 }
469
470 MrBayesPrint ("\n");
471 if (sumpParams.numRuns == 1)
472 MrBayesPrint ("%s Model parameter summaries for run sampled in file \"%s\":\n", spacer, sumpParams.sumpFileName);
473 else if (sumpParams.numRuns == 2)
474 {
475 MrBayesPrint ("%s Model parameter summaries over the runs sampled in files\n", spacer);
476 MrBayesPrint ("%s \"%s.run1.p\" and \"%s.run2.p\":\n", spacer, sumpParams.sumpFileName, sumpParams.sumpFileName);
477 }
478 else
479 {
480 MrBayesPrint ("%s Model parameter summaries over all %d runs sampled in files\n", spacer, sumpParams.numRuns);
481 MrBayesPrint ("%s \"%s.run1.p\", \"%s.run2.p\" etc:\n", spacer, sumpParams.sumpFileName, sumpParams.sumpFileName);
482 }
483
484 if (sumpParams.numRuns == 1)
485 {
486 MrBayesPrint ("%s Based on a total of %d samples out of a total of %d samples\n", spacer, numRows, numRows + burnin);
487 MrBayesPrint ("%s from this analysis.\n", spacer);
488 }
489 else
490 {
491 MrBayesPrint ("%s Summaries are based on a total of %d samples from %d runs.\n", spacer, sumpParams.numRuns*numRows, sumpParams.numRuns);
492 MrBayesPrint ("%s Each run produced %d samples of which %d samples were included.\n", spacer, numRows + burnin, numRows);
493 }
494 MrBayesPrint ("%s Parameter summaries saved to file \"%s.pstat\".\n", spacer, sumpParams.sumpOutfile);
495
496 if (PrintParamStats (sumpParams.sumpOutfile, headerNames, nHeaders, parameterSamples, numRuns, numRows) == ERROR)
497 goto errorExit;
498 if (PrintModelStats (sumpParams.sumpOutfile, headerNames, nHeaders, parameterSamples, numRuns, numRows) == ERROR)
499 goto errorExit;
500
501 /* free memory */
502 FreeParameterSamples(parameterSamples);
503 for (i=0; i<nHeaders; i++)
504 free (headerNames[i]);
505 free (headerNames);
506
507 expecting = Expecting(COMMAND);
508 strcpy (spacer, "");
509
510 return (NO_ERROR);
511
512 errorExit:
513
514 /* free memory */
515 FreeParameterSamples (parameterSamples);
516 for (i=0; i<nHeaders; i++)
517 free (headerNames[i]);
518 free (headerNames);
519
520 if (fpLstat)
521 SafeFclose (&fpLstat);
522
523 expecting = Expecting(COMMAND);
524 strcpy (spacer, "");
525
526 return (ERROR);
527 }
528
529
DoSumSs(void)530 int DoSumSs (void)
531 {
532 int i, nHeaders=0, numRows, numColumns, numRuns, whichIsX, whichIsY,
533 longestHeader, len;
534 char **headerNames=NULL, temp[120];
535 SumpFileInfo fileInfo, firstFileInfo;
536 ParameterSample *parameterSamples=NULL;
537 int stepIndexSS,numSamplesInStepSS, stepBeginSS, stepBurnin;
538 MrBFlt *lnlp, *nextSteplnlp, *firstlnlp;
539 MrBFlt *marginalLnLSS=NULL,stepScalerSS,stepAcumulatorSS, stepLengthSS, tmpMfl;
540 int beginPrint, countPrint;
541 float tmpf;
542 MrBFlt **plotArrayY=NULL,**plotArrayX=NULL;
543 int j, k, count;
544 MrBFlt sum;
545 int firstPass = YES;
546
547 # if defined (MPI_ENABLED)
548 if (proc_id != 0)
549 return NO_ERROR;
550 # endif
551
552 chainParams.isSS=YES;
553
554 /* tell user we are ready to go */
555 if (sumssParams.numRuns == 1)
556 MrBayesPrint ("%s Summarizing parameters in file %s.p\n", spacer, sumpParams.sumpFileName);
557 else if (sumssParams.numRuns == 2)
558 MrBayesPrint ("%s Summarizing parameters in files %s.run1.p and %s.run2.p\n", spacer, sumpParams.sumpFileName, sumpParams.sumpFileName);
559 else /* if (sumssParams.numRuns > 2) */
560 {
561 MrBayesPrint ("%s Summarizing parameters in %d files (%s.run1.p,\n", spacer, sumssParams.numRuns, sumpParams.sumpFileName);
562 MrBayesPrint ("%s %s.run2.p, etc)\n", spacer, sumpParams.sumpFileName);
563 }
564 //MrBayesPrint ("%s Writing summary statistics to file %s.pstat\n", spacer, sumpParams.sumpFileName);
565
566 if (chainParams.relativeBurnin == YES)
567 MrBayesPrint ("%s Using relative burnin ('relburnin=yes'), discarding the first %.0f %% of samples within each step.\n",
568 spacer, chainParams.burninFraction*100.0, chainParams.burninFraction);
569 else
570 MrBayesPrint ("%s Using absolute burnin ('relburnin=no'), discarding the first %d samples within each step.\n",
571 spacer, chainParams.chainBurnIn, chainParams.chainBurnIn);
572
573 /* Initialize to silence warning. */
574 firstFileInfo.numRows = 0;
575 firstFileInfo.numColumns = 0;
576
577 /* examine input file(s) */
578 for (i=0; i<sumssParams.numRuns; i++)
579 {
580 if (sumssParams.numRuns == 1)
581 sprintf (temp, "%s.p", sumpParams.sumpFileName);
582 else
583 sprintf (temp, "%s.run%d.p", sumpParams.sumpFileName, i+1);
584
585 if (ExamineSumpFile (temp, &fileInfo, &headerNames, &nHeaders) == ERROR)
586 goto errorExit;
587
588 if (i==0)
589 {
590 if (fileInfo.numRows == 0 || fileInfo.numColumns == 0)
591 {
592 MrBayesPrint ("%s The number of rows or columns in file %d is equal to zero\n", spacer, temp);
593 goto errorExit;
594 }
595 firstFileInfo = fileInfo;
596 }
597 else
598 {
599 if (firstFileInfo.numRows != fileInfo.numRows || firstFileInfo.numColumns != fileInfo.numColumns)
600 {
601 MrBayesPrint ("%s First file had %d rows and %d columns while file %s had %d rows and %d columns\n",
602 spacer, firstFileInfo.numRows, firstFileInfo.numColumns, temp, fileInfo.numRows, fileInfo.numColumns);
603 MrBayesPrint ("%s MrBayes expects the same number of rows and columns in all files\n", spacer);
604 goto errorExit;
605 }
606 }
607 }
608
609 numRows = fileInfo.numRows;
610 numColumns = fileInfo.numColumns;
611 numRuns = sumssParams.numRuns;
612
613 /* allocate space to hold parameter information */
614 if (AllocateParameterSamples (¶meterSamples, numRuns, numRows, numColumns) == ERROR)
615 goto errorExit;
616
617 /* read samples */
618 for (i=0; i<sumssParams.numRuns; i++)
619 {
620 /* derive file name */
621 if (sumssParams.numRuns == 1)
622 sprintf (temp, "%s.p", sumpParams.sumpFileName);
623 else
624 sprintf (temp, "%s.run%d.p", sumpParams.sumpFileName, i+1);
625
626 /* read samples */
627 if (ReadParamSamples (temp, &fileInfo, parameterSamples, i) == ERROR)
628 goto errorExit;
629 }
630
631 /* get length of longest header */
632 longestHeader = 9; /* 9 is the length of the word "parameter" (for printing table) */
633 for (i=0; i<nHeaders; i++)
634 {
635 len = (int) strlen(headerNames[i]);
636 if (len > longestHeader)
637 longestHeader = len;
638 }
639
640 /* Print trace plots */
641 if (FindHeader("Gen", headerNames, nHeaders, &whichIsX) == ERROR)
642 {
643 MrBayesPrint ("%s Could not find the 'Gen' column\n", spacer);
644 goto errorExit;
645 }
646 if (FindHeader("LnL", headerNames, nHeaders, &whichIsY) == ERROR)
647 {
648 MrBayesPrint ("%s Could not find the 'LnL' column\n", spacer);
649 goto errorExit;
650 }
651
652 if (chainParams.burninSS > 0)
653 {
654 stepBeginSS = chainParams.burninSS + 1;
655 }
656 else
657 {
658 numSamplesInStepSS = (numRows-1)/(chainParams.numStepsSS-chainParams.burninSS);
659 stepBeginSS = numSamplesInStepSS + 1;
660 }
661
662 numSamplesInStepSS = (numRows - stepBeginSS)/chainParams.numStepsSS;
663 if ((numRows - stepBeginSS)%chainParams.numStepsSS!=0)
664 {
665 MrBayesPrint ("%s Error: Number of samples could not be evenly divided among steps (%d samples among %d steps). \n", spacer,(numRows - stepBeginSS),chainParams.numStepsSS);
666 goto errorExit;
667 }
668
669 if (chainParams.relativeBurnin == YES)
670 {
671 stepBurnin = (int)(numSamplesInStepSS*chainParams.burninFraction);
672 }
673 else
674 {
675 stepBurnin = chainParams.chainBurnIn;
676 if (stepBurnin >= numSamplesInStepSS)
677 {
678 MrBayesPrint ("%s Error: Burnin in each step(%d) is longer then the step itself(%d). \n", spacer,stepBurnin, numSamplesInStepSS);
679 goto errorExit;
680 }
681 }
682
683 marginalLnLSS = (MrBFlt *) SafeCalloc (sumssParams.numRuns, sizeof(MrBFlt));
684 /*Preparing and printing joined plot.*/
685 plotArrayY = (MrBFlt **) SafeCalloc (sumssParams.numRuns+1, sizeof(MrBFlt*));
686 for (i=0; i<sumssParams.numRuns+1; i++)
687 plotArrayY[i] = (MrBFlt *) SafeCalloc (numSamplesInStepSS, sizeof(MrBFlt));
688
689 plotArrayX = (MrBFlt **) SafeCalloc (sumssParams.numRuns, sizeof(MrBFlt*));
690 for (i=0; i<sumssParams.numRuns; i++)
691 {
692 plotArrayX[i] = (MrBFlt *) SafeCalloc (numSamplesInStepSS, sizeof(MrBFlt));
693 for (j=0; j<numSamplesInStepSS; j++)
694 plotArrayX[i][j]=j+1;
695 }
696
697 MrBayesPrint ("%s In total %d sampls are red from .p files.\n", spacer, numRows);
698 MrBayesPrint ("\n");
699 MrBayesPrint ("%s Marginal likelihood (in natural log units) is estimated using stepping-stone sampling\n", spacer);
700 MrBayesPrint ("%s based on %d steps with %d samples within each step. \n", spacer, chainParams.numStepsSS, numSamplesInStepSS);
701 MrBayesPrint ("%s First %d samples (including generation 0) are discarded as initial burn-in.\n", spacer, stepBeginSS);
702 if (chainParams.startFromPriorSS==YES)
703 MrBayesPrint ("%s Sampling is assumed have being done from prior to posterior.\n", spacer);
704 else
705 {
706 MrBayesPrint ("%s Sampling is assumed have being done from posterior to prior.\n", spacer);
707 }
708
709 sumssTable:
710
711 MrBayesPrint ("\n\n%s Step contribution table.\n\n",spacer);
712 MrBayesPrint (" Columns in the table: \n");
713 MrBayesPrint (" Step -- Index of the step \n");
714 MrBayesPrint (" runX -- Contribution to the marginal log likelihood of run X, i.e. marginal \n");
715 MrBayesPrint (" log likelihood for run X is the sum across all steps in column runX.\n\n");
716
717 if (firstPass == YES && chainParams.relativeBurnin == YES)
718 MrBayesPrint ("%s The table entrances are based on samples excluding burn-in %d samples (%d%%) \n", spacer, stepBurnin,(int)(100*chainParams.burninFraction));
719 else
720 MrBayesPrint ("%s The table entrances are based on samples excluding burn-in %d samples \n", spacer, stepBurnin);
721 MrBayesPrint ("%s discarded at the beginning of each step. \n\n", spacer);
722
723 //MrBayesPrint ("%s Run Marginal likelihood (ln)\n",spacer);
724 //MrBayesPrint ("%s ------------------------------\n",spacer);
725 MrBayesPrint (" Step");
726 for (j=0; j<sumssParams.numRuns ; j++)
727 {
728 if (j<9)
729 MrBayesPrint (" ");
730 MrBayesPrint (" run%d", j+1);
731 }
732 MrBayesPrint ("\n");
733 for (i=0; i<sumssParams.numRuns; i++)
734 {
735 marginalLnLSS[i] = 0.0;
736 }
737 for (stepIndexSS = chainParams.numStepsSS-1; stepIndexSS>=0; stepIndexSS--)
738 {
739 if (chainParams.startFromPriorSS==YES)
740 {
741 stepLengthSS = BetaQuantile(chainParams.alphaSS, 1.0, (MrBFlt)(chainParams.numStepsSS-stepIndexSS)/(MrBFlt)chainParams.numStepsSS) - BetaQuantile(chainParams.alphaSS, 1.0, (MrBFlt)(chainParams.numStepsSS-1-stepIndexSS)/(MrBFlt)chainParams.numStepsSS);
742 }
743 else
744 {
745 stepLengthSS = BetaQuantile(chainParams.alphaSS, 1.0, (MrBFlt)(stepIndexSS+1)/(MrBFlt)chainParams.numStepsSS) - BetaQuantile(chainParams.alphaSS, 1.0, (MrBFlt)stepIndexSS/(MrBFlt)chainParams.numStepsSS);
746 }
747 MrBayesPrint (" %3d ", chainParams.numStepsSS-stepIndexSS);
748 for (i=0; i<sumssParams.numRuns; i++)
749 {
750 lnlp = parameterSamples[whichIsY].values[i] + stepBeginSS + (chainParams.numStepsSS-stepIndexSS-1)*numSamplesInStepSS;
751 nextSteplnlp = lnlp+numSamplesInStepSS;
752 lnlp+= stepBurnin;
753 stepAcumulatorSS = 0.0;
754 stepScalerSS = *lnlp*stepLengthSS;
755 while (lnlp < nextSteplnlp)
756 {
757 if (*lnlp*stepLengthSS > stepScalerSS + 200.0)
758 {
759 // adjust scaler;
760 stepAcumulatorSS /= exp(*lnlp*stepLengthSS - 100.0 - stepScalerSS);
761 stepScalerSS= *lnlp*stepLengthSS - 100.0;
762 }
763 stepAcumulatorSS += exp(*lnlp*stepLengthSS - stepScalerSS);
764 lnlp++;
765 }
766 tmpMfl = (log(stepAcumulatorSS/(numSamplesInStepSS-stepBurnin)) + stepScalerSS);
767 MrBayesPrint (" %10.3lf", tmpMfl);
768 marginalLnLSS[i] += tmpMfl;
769 }
770 MrBayesPrint ("\n");
771 //MrBayesPrint ("%s %3d %9.2f \n", spacer, i+1, marginalLnLSS);
772 }
773 MrBayesPrint (" ");
774 for (j=0; j<sumssParams.numRuns ; j++)
775 {
776 if (j<9)
777 MrBayesPrint ("-");
778 MrBayesPrint ("----------");
779 }
780 MrBayesPrint ("\n");
781 MrBayesPrint (" Sum: ");
782 for (j=0; j<sumssParams.numRuns ; j++)
783 MrBayesPrint (" %10.3lf", marginalLnLSS[j]);
784
785 MrBayesPrint ("\n");
786
787 /*
788 if (sumssParams.numRuns > 1)
789 {
790 MrBayesPrint ("%s Below are rough plots of the generations (x-axis) during burn in \n", spacer);
791 MrBayesPrint ("%s phase versus the log probability of observing the data (y-axis). \n", spacer);
792 MrBayesPrint ("%s You can use these graphs to determine if the burn in for your SS \n", spacer);
793 MrBayesPrint ("%s analysis was sufficiant. The log probability suppose to plateau \n", spacer);
794 MrBayesPrint ("%s indicating that you may be at stationarity by the time you finish \n", spacer);
795 MrBayesPrint ("%s burn in phase. This burn in, unlike burn in within each step, is \n", spacer);
796 MrBayesPrint ("%s fixed and can not be changed. \n", spacer);
797 }
798 else
799 {
800 MrBayesPrint ("%s Below is a rough plot of the generations (x-axis) during burn in \n", spacer);
801 MrBayesPrint ("%s phase versus the log probability of observing the data (y-axis). \n", spacer);
802 MrBayesPrint ("%s You can use these graph to determine if the burn in for your SS \n", spacer);
803 MrBayesPrint ("%s analysis was sufficiant. The log probability suppose to plateau \n", spacer);
804 MrBayesPrint ("%s indicating that you may be at stationarity by the time you finish \n", spacer);
805 MrBayesPrint ("%s burn in phase. This burn in, unlike burn in within each step, is \n", spacer);
806 MrBayesPrint ("%s fixed and can not be changed. \n", spacer);
807 }
808 */
809
810 if (firstPass == NO)
811 goto sumssExitOptions;
812
813 sumssStepPlot:
814
815 MrBayesPrint ("\n\n%s Step plot(s).\n",spacer);
816 while (1)
817 {
818 MrBayesPrint ("\n");
819 if (sumssParams.stepToPlot == 0)
820 {
821 beginPrint=(int)(sumssParams.discardFraction*stepBeginSS);
822 countPrint=stepBeginSS-beginPrint;
823 MrBayesPrint ("%s Plotting step 0, i.e initial burn-in phase consisting of %d samples.\n", spacer,stepBeginSS);
824 MrBayesPrint ("%s According to 'Discardfrac=%.2f', first %d samples are not ploted.\n", spacer,sumssParams.discardFraction,beginPrint);
825 }
826 else
827 {
828 if (sumssParams.stepToPlot > chainParams.numStepsSS)
829 {
830 MrBayesPrint ("%s Chosen index of step to print %d is out of range of step indices[0,...,%d].\n", spacer,sumssParams.stepToPlot,chainParams.numStepsSS);
831 goto errorExit;
832 }
833 beginPrint=stepBeginSS+(sumssParams.stepToPlot-1)*numSamplesInStepSS + (int)(sumssParams.discardFraction*numSamplesInStepSS);
834 countPrint=numSamplesInStepSS-(int)(sumssParams.discardFraction*numSamplesInStepSS);
835 MrBayesPrint ("%s Plotting step %d consisting of %d samples.\n", spacer,sumssParams.stepToPlot,numSamplesInStepSS);
836 MrBayesPrint ("%s According to 'Discardfrac=%.2f', first %d samples are not ploted.\n", spacer,sumssParams.discardFraction,(int)(sumssParams.discardFraction*numSamplesInStepSS));
837 }
838
839 if (sumssParams.numRuns > 1)
840 {
841 if (sumpParams.allRuns == YES)
842 {
843 for (i=0; i<sumssParams.numRuns; i++)
844 {
845 MrBayesPrint ("\n%s Samples from run %d:\n", spacer, i+1);
846 if (PrintPlot (parameterSamples[whichIsX].values[i]+beginPrint, parameterSamples[whichIsY].values[i]+beginPrint, countPrint) == ERROR)
847 goto errorExit;
848 }
849 }
850 else
851 {
852 if (PrintOverlayPlot (parameterSamples[whichIsX].values, parameterSamples[whichIsY].values, numRuns, beginPrint, countPrint) == ERROR)
853 goto errorExit;
854 }
855 }
856 else
857 {
858 if (PrintPlot (parameterSamples[whichIsX].values[0]+beginPrint, parameterSamples[whichIsY].values[0]+beginPrint, countPrint) == ERROR)
859 goto errorExit;
860 }
861
862 if (sumssParams.askForMorePlots == NO || firstPass == YES)
863 break;
864
865 MrBayesPrint (" You can choose to print new step plots for different steps or discard fractions.\n");
866 MrBayesPrint (" Allowed range of 'Steptoplot' are from 0 to %d.\n", chainParams.numStepsSS);
867 MrBayesPrint (" If the next entered value is negative, 'sumss' will stop printing step plots.\n");
868 MrBayesPrint (" If the next entered value is positive, but out of range, you will be offered\n");
869 MrBayesPrint (" to change parameter 'Discardfrac' of 'sumss'.\n");
870 MrBayesPrint (" Enter new step number 'Steptoplot':");
871 k = scanf("%d",&j);
872 if (j < 0)
873 break;
874 if (j > chainParams.numStepsSS)
875 {
876 do
877 {
878 MrBayesPrint (" Enter new value for 'Discardfrac', should be in range 0.0 to 1.0:");
879 k = scanf("%f",&tmpf);
880 sumssParams.discardFraction = (MrBFlt)tmpf;
881 }
882 while (sumssParams.discardFraction < 0.0 || sumssParams.discardFraction > 1.0);
883 }
884 else
885 sumssParams.stepToPlot=j;
886 }
887
888 if (firstPass == NO)
889 goto sumssExitOptions;
890
891 sumssJoinedPlot:
892
893 MrBayesPrint ("\n\n%s Joined plot(s).\n",spacer);
894 while (1)
895 {
896 MrBayesPrint ("\n");
897 MrBayesPrint ("%s Joined plot of %d samples of all steps together. 'smoothing' is set to:%d\n", spacer,numSamplesInStepSS,sumssParams.smoothing);
898 MrBayesPrint ("%s According to step burn-in, first %d samples are not ploted.\n", spacer,stepBurnin);
899
900 for (i=0; i<sumssParams.numRuns; i++)
901 {
902 for (j=stepBurnin;j<numSamplesInStepSS;j++)
903 plotArrayY[sumssParams.numRuns][j]=0.0;
904 lnlp= parameterSamples[whichIsY].values[i] + stepBeginSS;
905 nextSteplnlp=lnlp;
906 for (stepIndexSS = chainParams.numStepsSS-1; stepIndexSS>0; stepIndexSS--)
907 {
908 firstlnlp=plotArrayY[sumssParams.numRuns] + stepBurnin;
909 lnlp+=stepBurnin;
910 nextSteplnlp += numSamplesInStepSS;
911 while (lnlp < nextSteplnlp)
912 {
913 *firstlnlp+=*lnlp;
914 firstlnlp++;
915 lnlp++;
916 }
917 }
918 for (j=stepBurnin;j<numSamplesInStepSS;j++)
919 {
920 sum=0.0;
921 count=0;
922 for (k=j-sumssParams.smoothing;k<=j+sumssParams.smoothing;k++)
923 {
924 if (k>=stepBurnin && k<numSamplesInStepSS)
925 {
926 sum += plotArrayY[sumssParams.numRuns][k];
927 count++;
928 }
929 }
930 plotArrayY[i][j] = sum/count;
931 /*
932 if (max < plotArrayY[i][j])
933 max=plotArrayY[i][j];
934 */
935 }
936 /* for (j=stepBurnin;j<numSamplesInStepSS;j++)
937 {
938 plotArrayY[i][j] /= max;
939 }*/
940 }
941
942 beginPrint=stepBurnin;
943 countPrint=numSamplesInStepSS-stepBurnin;
944
945 if (sumssParams.numRuns > 1)
946 {
947 if (sumpParams.allRuns == YES)
948 {
949 for (i=0; i<sumssParams.numRuns; i++)
950 {
951 MrBayesPrint ("\n%s Samples from run %d:\n", spacer, i+1);
952 if (PrintPlot (plotArrayX[i]+beginPrint, plotArrayY[i]+beginPrint, countPrint) == ERROR)
953 goto errorExit;
954 }
955 }
956 else
957 {
958 if (PrintOverlayPlot (plotArrayX, plotArrayY, numRuns, beginPrint, countPrint) == ERROR)
959 goto errorExit;
960 }
961 }
962 else
963 {
964 if (PrintPlot (plotArrayX[0]+beginPrint, plotArrayY[0]+beginPrint, countPrint) == ERROR)
965 goto errorExit;
966 }
967
968 if (sumssParams.askForMorePlots == NO || firstPass == YES)
969 break;
970
971 MrBayesPrint (" You can choose to print new joined plots with different step burn-in or smoothing.\n");
972 MrBayesPrint (" Allowed range of step burn-in values are from 0 to %d.\n", numSamplesInStepSS-1);
973 MrBayesPrint (" If the next entered value is negative, 'sumss' will stop printing joined plots.\n");
974 MrBayesPrint (" If the next entered value is positive, but out of range, you will be offered\n");
975 MrBayesPrint (" to change 'Smoothing'.\n");
976 MrBayesPrint (" Enter new step burn-in:");
977 k = scanf("%d",&j);
978 if (j < 0)
979 break;
980 if (j >= numSamplesInStepSS)
981 {
982 MrBayesPrint (" Enter new value for 'Smoothing':");
983 k = scanf("%d",&j);
984 sumssParams.smoothing = abs(j);
985 }
986 else
987 stepBurnin=j;
988 }
989
990 firstPass = NO;
991
992 sumssExitOptions:
993
994 if (sumssParams.askForMorePlots == YES)
995 {
996 MrBayesPrint ("\n");
997 MrBayesPrint (" Sumss is interactive, because of parameter 'Askmore=YES' setting. \n");
998 MrBayesPrint (" What would you like to do next?\n");
999 MrBayesPrint (" 1) Print updated table according to new step burn-in.\n");
1000 MrBayesPrint (" 2) Print Step plot(s).\n");
1001 MrBayesPrint (" 3) Print Joined plot(s).\n");
1002 MrBayesPrint (" 4) Exit 'sumss'.\n");
1003 MrBayesPrint (" Enter a number that corresponds to one of the options:");
1004 do
1005 {
1006 k = scanf("%d",&j);
1007 }while (j<1 || j>4);
1008
1009 if (j == 1)
1010 {
1011 MrBayesPrint (" Allowed range of step burn-in values are from 0 to %d\n", numSamplesInStepSS-1);
1012 MrBayesPrint (" Current step burn-in value is:%d\n", stepBurnin);
1013 MrBayesPrint (" Enter new step burn-in:");
1014 do
1015 {
1016 k = scanf("%d",&stepBurnin);
1017 }
1018 while (stepBurnin < 0 || stepBurnin > numSamplesInStepSS-1);
1019 MrBayesPrint ("\n");
1020 goto sumssTable;
1021 }
1022 else if (j == 2)
1023 {
1024 goto sumssStepPlot;
1025 }
1026 else if (j == 3)
1027 goto sumssJoinedPlot;
1028 }
1029
1030 /* free memory */
1031 FreeParameterSamples(parameterSamples);
1032 for (i=0; i<nHeaders; i++)
1033 free (headerNames[i]);
1034 free (headerNames);
1035
1036 expecting = Expecting(COMMAND);
1037 strcpy (spacer, "");
1038 chainParams.isSS=NO;
1039 for (i=0; i<sumssParams.numRuns+1; i++)
1040 free(plotArrayY[i]);
1041 free(plotArrayY);
1042 for (i=0; i<sumssParams.numRuns; i++)
1043 free(plotArrayX[i]);
1044 free(plotArrayX);
1045 free(marginalLnLSS);
1046
1047 return (NO_ERROR);
1048
1049 errorExit:
1050
1051 /* free memory */
1052 FreeParameterSamples (parameterSamples);
1053 if (headerNames!=NULL)
1054 for (i=0; i<nHeaders; i++)
1055 free (headerNames[i]);
1056 free (headerNames);
1057
1058 expecting = Expecting(COMMAND);
1059 strcpy (spacer, "");
1060 chainParams.isSS=NO;
1061 if (plotArrayY!=NULL)
1062 for (i=0; i<sumssParams.numRuns+1; i++)
1063 free(plotArrayY[i]);
1064 free(plotArrayY);
1065 if (plotArrayX!=NULL)
1066 for (i=0; i<sumssParams.numRuns; i++)
1067 free(plotArrayX[i]);
1068 free(plotArrayX);
1069 free(marginalLnLSS);
1070
1071 return (ERROR);
1072 }
1073
1074
DoSumpParm(char * parmName,char * tkn)1075 int DoSumpParm (char *parmName, char *tkn)
1076 {
1077 int tempI;
1078 MrBFlt tempD;
1079 char tempStr[100];
1080
1081 if (expecting == Expecting(PARAMETER))
1082 {
1083 expecting = Expecting(EQUALSIGN);
1084 }
1085 else
1086 {
1087 if (!strcmp(parmName, "Xxxxxxxxxx"))
1088 {
1089 expecting = Expecting(PARAMETER);
1090 expecting |= Expecting(SEMICOLON);
1091 }
1092 /* set Filename (sumpParams.sumpFileName) ***************************************************/
1093 else if (!strcmp(parmName, "Filename"))
1094 {
1095 if (expecting == Expecting(EQUALSIGN))
1096 {
1097 expecting = Expecting(ALPHA);
1098 readWord = YES;
1099 }
1100 else if (expecting == Expecting(ALPHA))
1101 {
1102 if (strlen(tkn)>99 && (strchr(tkn,' ')-tkn) > 99)
1103 {
1104 MrBayesPrint ("%s Maximum allowed length of file name is 99 characters. The given name:\n", spacer);
1105 MrBayesPrint ("%s '%s'\n", spacer,tkn);
1106 return (ERROR);
1107 }
1108 sscanf (tkn, "%s", tempStr);
1109 strcpy (sumpParams.sumpFileName, tempStr);
1110 strcpy (sumpParams.sumpOutfile, tempStr);
1111 MrBayesPrint ("%s Setting sump filename and output file name to %s\n", spacer, sumpParams.sumpFileName);
1112 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
1113 }
1114 else
1115 return (ERROR);
1116 }
1117 /* set Outputname (sumpParams.sumpOutfile) *******************************************************/
1118 else if (!strcmp(parmName, "Outputname"))
1119 {
1120 if (expecting == Expecting(EQUALSIGN))
1121 {
1122 expecting = Expecting(ALPHA);
1123 readWord = YES;
1124 }
1125 else if (expecting == Expecting(ALPHA))
1126 {
1127 if (strlen(tkn)>99 && (strchr(tkn,' ')-tkn) > 99)
1128 {
1129 MrBayesPrint ("%s Maximum allowed length of file name is 99 characters. The given name:\n", spacer);
1130 MrBayesPrint ("%s '%s'\n", spacer,tkn);
1131 return (ERROR);
1132 }
1133 sscanf (tkn, "%s", tempStr);
1134 strcpy (sumpParams.sumpOutfile, tempStr);
1135 MrBayesPrint ("%s Setting sump output file name to \"%s\"\n", spacer, sumpParams.sumpOutfile);
1136 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
1137 }
1138 else
1139 return (ERROR);
1140 }
1141 /* set Relburnin (chainParams.relativeBurnin) ********************************************************/
1142 else if (!strcmp(parmName, "Relburnin"))
1143 {
1144 if (expecting == Expecting(EQUALSIGN))
1145 expecting = Expecting(ALPHA);
1146 else if (expecting == Expecting(ALPHA))
1147 {
1148 if (IsArgValid(tkn, tempStr) == NO_ERROR)
1149 {
1150 if (!strcmp(tempStr, "Yes"))
1151 chainParams.relativeBurnin = YES;
1152 else
1153 chainParams.relativeBurnin = NO;
1154 }
1155 else
1156 {
1157 MrBayesPrint ("%s Invalid argument for Relburnin\n", spacer);
1158 return (ERROR);
1159 }
1160 if (chainParams.relativeBurnin == YES)
1161 MrBayesPrint ("%s Using relative burnin (a fraction of samples discarded).\n", spacer);
1162 else
1163 MrBayesPrint ("%s Using absolute burnin (a fixed number of samples discarded).\n", spacer);
1164 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
1165 }
1166 else
1167 {
1168 return (ERROR);
1169 }
1170 }
1171 /* set Burnin (chainParams.chainBurnIn) ***********************************************************/
1172 else if (!strcmp(parmName, "Burnin"))
1173 {
1174 if (expecting == Expecting(EQUALSIGN))
1175 expecting = Expecting(NUMBER);
1176 else if (expecting == Expecting(NUMBER))
1177 {
1178 sscanf (tkn, "%d", &tempI);
1179 chainParams.chainBurnIn = tempI;
1180 MrBayesPrint ("%s Setting burn-in to %d\n", spacer, chainParams.chainBurnIn);
1181 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
1182 }
1183 else
1184 {
1185 return (ERROR);
1186 }
1187 }
1188 /* set Burninfrac (chainParams.burninFraction) ************************************************************/
1189 else if (!strcmp(parmName, "Burninfrac"))
1190 {
1191 if (expecting == Expecting(EQUALSIGN))
1192 expecting = Expecting(NUMBER);
1193 else if (expecting == Expecting(NUMBER))
1194 {
1195 sscanf (tkn, "%lf", &tempD);
1196 if (tempD < 0.01)
1197 {
1198 MrBayesPrint ("%s Burnin fraction too low (< 0.01)\n", spacer);
1199 return (ERROR);
1200 }
1201 if (tempD > 0.50)
1202 {
1203 MrBayesPrint ("%s Burnin fraction too high (> 0.50)\n", spacer);
1204 return (ERROR);
1205 }
1206 chainParams.burninFraction = tempD;
1207 MrBayesPrint ("%s Setting burnin fraction to %.2f\n", spacer, chainParams.burninFraction);
1208 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
1209 }
1210 else
1211 {
1212 return (ERROR);
1213 }
1214 }
1215 /* set Minprob (sumpParams.minProb) ************************************************************/
1216 else if (!strcmp(parmName, "Minprob"))
1217 {
1218 if (expecting == Expecting(EQUALSIGN))
1219 expecting = Expecting(NUMBER);
1220 else if (expecting == Expecting(NUMBER))
1221 {
1222 sscanf (tkn, "%lf", &tempD);
1223 if (tempD > 0.50)
1224 {
1225 MrBayesPrint ("%s Minprob too high (it should be smaller than 0.50)\n", spacer);
1226 return (ERROR);
1227 }
1228 sumpParams.minProb = tempD;
1229 MrBayesPrint ("%s Setting minprob to %1.3f\n", spacer, sumpParams.minProb);
1230 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
1231 }
1232 else
1233 {
1234 return (ERROR);
1235 }
1236 }
1237 /* set Nruns (sumpParams.numRuns) *******************************************************/
1238 else if (!strcmp(parmName, "Nruns"))
1239 {
1240 if (expecting == Expecting(EQUALSIGN))
1241 expecting = Expecting(NUMBER);
1242 else if (expecting == Expecting(NUMBER))
1243 {
1244 sscanf (tkn, "%d", &tempI);
1245 if (tempI < 1)
1246 {
1247 MrBayesPrint ("%s Nruns must be at least 1\n", spacer);
1248 return (ERROR);
1249 }
1250 else
1251 {
1252 sumpParams.numRuns = tempI;
1253 MrBayesPrint ("%s Setting sump nruns to %d\n", spacer, sumpParams.numRuns);
1254 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
1255 }
1256 }
1257 else
1258 return (ERROR);
1259 }
1260 /* set Hpd (sumpParams.HPD) ********************************************************/
1261 else if (!strcmp(parmName, "Hpd"))
1262 {
1263 if (expecting == Expecting(EQUALSIGN))
1264 expecting = Expecting(ALPHA);
1265 else if (expecting == Expecting(ALPHA))
1266 {
1267 if (IsArgValid(tkn, tempStr) == NO_ERROR)
1268 {
1269 if (!strcmp(tempStr, "Yes"))
1270 sumpParams.HPD = YES;
1271 else
1272 sumpParams.HPD = NO;
1273 }
1274 else
1275 {
1276 MrBayesPrint ("%s Invalid argument for Hpd\n", spacer);
1277 return (ERROR);
1278 }
1279 if (sumpParams.HPD == YES)
1280 MrBayesPrint ("%s Reporting 95 %% region of Highest Posterior Density (HPD).\n", spacer);
1281 else
1282 MrBayesPrint ("%s Reporting median interval containing 95 %% of values.\n", spacer);
1283 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
1284 }
1285 else
1286 {
1287 return (ERROR);
1288 }
1289 }
1290 /* set Allruns (sumpParams.allRuns) ********************************************************/
1291 else if (!strcmp(parmName, "Allruns"))
1292 {
1293 if (expecting == Expecting(EQUALSIGN))
1294 expecting = Expecting(ALPHA);
1295 else if (expecting == Expecting(ALPHA))
1296 {
1297 if (IsArgValid(tkn, tempStr) == NO_ERROR)
1298 {
1299 if (!strcmp(tempStr, "Yes"))
1300 sumpParams.allRuns = YES;
1301 else
1302 sumpParams.allRuns = NO;
1303 }
1304 else
1305 {
1306 MrBayesPrint ("%s Invalid argument for allruns (valid arguments are 'yes' and 'no')\n", spacer);
1307 return (ERROR);
1308 }
1309 if (sumpParams.allRuns == YES)
1310 MrBayesPrint ("%s Setting sump to print information for each run\n", spacer);
1311 else
1312 MrBayesPrint ("%s Setting sump to print only summary information for all runs\n", spacer);
1313 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
1314 }
1315 else
1316 return (ERROR);
1317 }
1318 else
1319 return (ERROR);
1320 }
1321
1322 return (NO_ERROR);
1323 }
1324
1325
DoSumSsParm(char * parmName,char * tkn)1326 int DoSumSsParm (char *parmName, char *tkn)
1327 {
1328 int tempI;
1329 MrBFlt tempD;
1330 char tempStr[100];
1331
1332 if (expecting == Expecting(PARAMETER))
1333 {
1334 expecting = Expecting(EQUALSIGN);
1335 }
1336 else
1337 {
1338 if (!strcmp(parmName, "Xxxxxxxxxx"))
1339 {
1340 expecting = Expecting(PARAMETER);
1341 expecting |= Expecting(SEMICOLON);
1342 }
1343 /* set Filename (sumpParams.sumpFileName) ***************************************************/
1344 else if (!strcmp(parmName, "Filename"))
1345 {
1346 if (expecting == Expecting(EQUALSIGN))
1347 {
1348 expecting = Expecting(ALPHA);
1349 readWord = YES;
1350 }
1351 else if (expecting == Expecting(ALPHA))
1352 {
1353 if (strlen(tkn)>99 && (strchr(tkn,' ')-tkn) > 99)
1354 {
1355 MrBayesPrint ("%s Maximum allowed length of file name is 99 characters. The given name:\n", spacer);
1356 MrBayesPrint ("%s '%s'\n", spacer,tkn);
1357 return (ERROR);
1358 }
1359 sscanf (tkn, "%s", tempStr);
1360 strcpy (sumpParams.sumpFileName, tempStr);
1361 strcpy (sumpParams.sumpOutfile, tempStr);
1362 MrBayesPrint ("%s Setting sump filename and output file name to %s\n", spacer, sumpParams.sumpFileName);
1363 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
1364 }
1365 else
1366 return (ERROR);
1367 }
1368 /* set Outputname (sumpParams.sumpOutfile) *******************************************************/
1369 /*else if (!strcmp(parmName, "Outputname"))
1370 {
1371 if (expecting == Expecting(EQUALSIGN))
1372 {
1373 expecting = Expecting(ALPHA);
1374 readWord = YES;
1375 }
1376 else if (expecting == Expecting(ALPHA))
1377 {
1378 if (strlen(tkn)>99 && (strchr(tkn,' ')-tkn) > 99)
1379 {
1380 MrBayesPrint ("%s Maximum allowed length of file name is 99 characters. The given name:\n", spacer);
1381 MrBayesPrint ("%s '%s'\n", spacer,tkn);
1382 return (ERROR);
1383 }
1384 sscanf (tkn, "%s", tempStr);
1385 strcpy (sumpParams.sumpOutfile, tempStr);
1386 MrBayesPrint ("%s Setting sump output file name to \"%s\"\n", spacer, sumpParams.sumpOutfile);
1387 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
1388 }
1389 else
1390 return (ERROR);
1391 }*/
1392 /* set Relburnin (chainParams.relativeBurnin) ********************************************************/
1393 else if (!strcmp(parmName, "Relburnin"))
1394 {
1395 if (expecting == Expecting(EQUALSIGN))
1396 expecting = Expecting(ALPHA);
1397 else if (expecting == Expecting(ALPHA))
1398 {
1399 if (IsArgValid(tkn, tempStr) == NO_ERROR)
1400 {
1401 if (!strcmp(tempStr, "Yes"))
1402 chainParams.relativeBurnin = YES;
1403 else
1404 chainParams.relativeBurnin = NO;
1405 }
1406 else
1407 {
1408 MrBayesPrint ("%s Invalid argument for Relburnin\n", spacer);
1409 return (ERROR);
1410 }
1411 if (chainParams.relativeBurnin == YES)
1412 MrBayesPrint ("%s Using relative burnin (a fraction of samples discarded).\n", spacer);
1413 else
1414 MrBayesPrint ("%s Using absolute burnin (a fixed number of samples discarded).\n", spacer);
1415 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
1416 }
1417 else
1418 {
1419 return (ERROR);
1420 }
1421 }
1422 /* set Burnin (chainParams.chainBurnIn) ***********************************************************/
1423 else if (!strcmp(parmName, "Burnin"))
1424 {
1425 if (expecting == Expecting(EQUALSIGN))
1426 expecting = Expecting(NUMBER);
1427 else if (expecting == Expecting(NUMBER))
1428 {
1429 sscanf (tkn, "%d", &tempI);
1430 chainParams.chainBurnIn = tempI;
1431 MrBayesPrint ("%s Setting burn-in to %d\n", spacer, chainParams.chainBurnIn);
1432 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
1433 }
1434 else
1435 {
1436 return (ERROR);
1437 }
1438 }
1439 /* set Burninfrac (chainParams.burninFraction) ************************************************************/
1440 else if (!strcmp(parmName, "Burninfrac"))
1441 {
1442 if (expecting == Expecting(EQUALSIGN))
1443 expecting = Expecting(NUMBER);
1444 else if (expecting == Expecting(NUMBER))
1445 {
1446 sscanf (tkn, "%lf", &tempD);
1447 if (tempD < 0.01)
1448 {
1449 MrBayesPrint ("%s Burnin fraction too low (< 0.01)\n", spacer);
1450 return (ERROR);
1451 }
1452 if (tempD > 0.50)
1453 {
1454 MrBayesPrint ("%s Burnin fraction too high (> 0.50)\n", spacer);
1455 return (ERROR);
1456 }
1457 chainParams.burninFraction = tempD;
1458 MrBayesPrint ("%s Setting burnin fraction to %.2f\n", spacer, chainParams.burninFraction);
1459 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
1460 }
1461 else
1462 {
1463 return (ERROR);
1464 }
1465 }
1466 /* set Nruns (sumssParams.numRuns) *******************************************************/
1467 else if (!strcmp(parmName, "Nruns"))
1468 {
1469 if (expecting == Expecting(EQUALSIGN))
1470 expecting = Expecting(NUMBER);
1471 else if (expecting == Expecting(NUMBER))
1472 {
1473 sscanf (tkn, "%d", &tempI);
1474 if (tempI < 1)
1475 {
1476 MrBayesPrint ("%s Nruns must be at least 1\n", spacer);
1477 return (ERROR);
1478 }
1479 else
1480 {
1481 sumssParams.numRuns = tempI;
1482 MrBayesPrint ("%s Setting sumss nruns to %d\n", spacer, sumssParams.numRuns);
1483 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
1484 }
1485 }
1486 else
1487 return (ERROR);
1488 }
1489 /* set Allruns (sumssParams.allRuns) ********************************************************/
1490 else if (!strcmp(parmName, "Allruns"))
1491 {
1492 if (expecting == Expecting(EQUALSIGN))
1493 expecting = Expecting(ALPHA);
1494 else if (expecting == Expecting(ALPHA))
1495 {
1496 if (IsArgValid(tkn, tempStr) == NO_ERROR)
1497 {
1498 if (!strcmp(tempStr, "Yes"))
1499 sumssParams.allRuns = YES;
1500 else
1501 sumssParams.allRuns = NO;
1502 }
1503 else
1504 {
1505 MrBayesPrint ("%s Invalid argument for allruns (valid arguments are 'yes' and 'no')\n", spacer);
1506 return (ERROR);
1507 }
1508 if (sumssParams.allRuns == YES)
1509 MrBayesPrint ("%s Setting sump to print information for each run\n", spacer);
1510 else
1511 MrBayesPrint ("%s Setting sump to print only summary information for all runs\n", spacer);
1512 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
1513 }
1514 else
1515 return (ERROR);
1516 }
1517 /* set Steptoplot (sumssParams.stepToPlot) *******************************************************/
1518 else if (!strcmp(parmName, "Steptoplot"))
1519 {
1520 if (expecting == Expecting(EQUALSIGN))
1521 expecting = Expecting(NUMBER);
1522 else if (expecting == Expecting(NUMBER))
1523 {
1524 sscanf (tkn, "%d", &tempI);
1525 if (tempI < 0)
1526 {
1527 MrBayesPrint ("%s Steptoplot must be at least 0\n", spacer);
1528 return (ERROR);
1529 }
1530 else
1531 {
1532 sumssParams.stepToPlot = tempI;
1533 MrBayesPrint ("%s Setting sumss steptoplot to %d\n", spacer, sumssParams.stepToPlot);
1534 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
1535 }
1536 }
1537 else
1538 return (ERROR);
1539 }
1540 /* set Smoothing (sumssParams.smoothing) *******************************************************/
1541 else if (!strcmp(parmName, "Smoothing"))
1542 {
1543 if (expecting == Expecting(EQUALSIGN))
1544 expecting = Expecting(NUMBER);
1545 else if (expecting == Expecting(NUMBER))
1546 {
1547 sscanf (tkn, "%d", &tempI);
1548 if (tempI < 0)
1549 {
1550 MrBayesPrint ("%s Smoothing must be at least 0\n", spacer);
1551 return (ERROR);
1552 }
1553 else
1554 {
1555 sumssParams.smoothing = tempI;
1556 MrBayesPrint ("%s Setting sumss smoothing to %d\n", spacer, sumssParams.smoothing);
1557 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
1558 }
1559 }
1560 else
1561 return (ERROR);
1562 }
1563 /* set Allruns (sumssParams.askForMorePlots) ********************************************************/
1564 else if (!strcmp(parmName, "Askmore"))
1565 {
1566 if (expecting == Expecting(EQUALSIGN))
1567 expecting = Expecting(ALPHA);
1568 else if (expecting == Expecting(ALPHA))
1569 {
1570 if (IsArgValid(tkn, tempStr) == NO_ERROR)
1571 {
1572 if (!strcmp(tempStr, "Yes"))
1573 sumssParams.askForMorePlots = YES;
1574 else
1575 sumssParams.askForMorePlots = NO;
1576 }
1577 else
1578 {
1579 MrBayesPrint ("%s Invalid argument for askmore (valid arguments are 'yes' and 'no')\n", spacer);
1580 return (ERROR);
1581 }
1582 if (sumssParams.askForMorePlots == YES)
1583 MrBayesPrint ("%s Setting sumss to be interactiva by asking for more plots of burn-in or individual steps.\n", spacer);
1584 else
1585 MrBayesPrint ("%s Setting sumss not to be interactive. It will not ask to print more plots.\n", spacer);
1586 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
1587 }
1588 else
1589 return (ERROR);
1590 }
1591 /* set Discardfrac (sumssParams.discardFraction) ************************************************************/
1592 else if (!strcmp(parmName, "Discardfrac"))
1593 {
1594 if (expecting == Expecting(EQUALSIGN))
1595 expecting = Expecting(NUMBER);
1596 else if (expecting == Expecting(NUMBER))
1597 {
1598 sscanf (tkn, "%lf", &tempD);
1599 if (tempD < 0.00)
1600 {
1601 MrBayesPrint ("%s Discard fraction too low (< 0.00)\n", spacer);
1602 return (ERROR);
1603 }
1604 if (tempD > 1.00)
1605 {
1606 MrBayesPrint ("%s Discard fraction too high (> 1.00)\n", spacer);
1607 return (ERROR);
1608 }
1609 sumssParams.discardFraction = tempD;
1610 MrBayesPrint ("%s Setting discard fraction to %.2f\n", spacer, sumssParams.discardFraction);
1611 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
1612 }
1613 else
1614 {
1615 return (ERROR);
1616 }
1617 }
1618 else
1619 return (ERROR);
1620 }
1621
1622 return (NO_ERROR);
1623 }
1624
1625
1626 /* ExamineSumpFile: Collect info on the parameter samples in the file */
ExamineSumpFile(char * fileName,SumpFileInfo * fileInfo,char *** headerNames,int * nHeaders)1627 int ExamineSumpFile (char *fileName, SumpFileInfo *fileInfo, char ***headerNames, int *nHeaders)
1628 {
1629 char *sumpTokenP, sumpToken[CMD_STRING_LENGTH], *s=NULL, *headerLine, *t;
1630 int i, lineTerm, inSumpComment, lineNum, lastNonDigitLine, numParamLines, allDigitLine,
1631 lastTokenWasDash, nNumbersOnThisLine, tokenType, burnin, nLines, firstNumCols;
1632 MrBFlt tempD;
1633 FILE *fp = NULL;
1634
1635 /* open binary file */
1636 if ((fp = OpenBinaryFileR(fileName)) == NULL)
1637 {
1638 /* test for some simple errors */
1639 if (strlen(sumpParams.sumpFileName) > 2)
1640 {
1641 s = sumpParams.sumpFileName + (int) strlen(sumpParams.sumpFileName) - 2;
1642 if (strcmp(s, ".p") == 0)
1643 {
1644 MrBayesPrint ("%s It appears that you need to remove '.p' from the 'Filename' parameter\n", spacer);
1645 MrBayesPrint ("%s Also make sure that 'Nruns' is set correctly\n", spacer);
1646 return ERROR;
1647 }
1648 }
1649 MrBayesPrint ("%s Make sure that 'Nruns' is set correctly\n", spacer);
1650 return ERROR;
1651 }
1652
1653 /* find out what type of line termination is used */
1654 lineTerm = LineTermType (fp);
1655 if (lineTerm != LINETERM_MAC && lineTerm != LINETERM_DOS && lineTerm != LINETERM_UNIX)
1656 {
1657 MrBayesPrint ("%s Unknown line termination\n", spacer);
1658 goto errorExit;
1659 }
1660
1661 /* find length of longest line */
1662 fileInfo->longestLineLength = LongestLine (fp);
1663 fileInfo->longestLineLength += 10; /* better safe than sorry; if you fgets with raw longestLineLength, you run into problems */
1664
1665 /* allocate string long enough to hold a line */
1666 s = (char *)SafeMalloc(2 * ((size_t)(fileInfo->longestLineLength) +10) * sizeof(char));
1667 if (!s)
1668 {
1669 MrBayesPrint ("%s Problem allocating string for reading sump file\n", spacer);
1670 goto errorExit;
1671 }
1672 headerLine = s + fileInfo->longestLineLength + 10;
1673
1674 /* close binary file */
1675 SafeFclose (&fp);
1676
1677 /* open text file */
1678 if ((fp = OpenTextFileR(fileName)) == NULL)
1679 goto errorExit;
1680
1681 /* Check file for appropriate blocks. We want to find the last block
1682 in the file and start from there. */
1683 inSumpComment = NO;
1684 lineNum = lastNonDigitLine = numParamLines = 0;
1685 while (fgets (s, fileInfo->longestLineLength + 2, fp) != NULL)
1686 {
1687 sumpTokenP = &s[0];
1688 allDigitLine = YES;
1689 lastTokenWasDash = NO;
1690 nNumbersOnThisLine = 0;
1691 do {
1692 if (GetToken (sumpToken, &tokenType, &sumpTokenP))
1693 goto errorExit;
1694 /* printf ("%s (%d)\n", sumpToken, tokenType); */
1695 if (IsSame("[", sumpToken) == SAME)
1696 inSumpComment = YES;
1697 if (IsSame("]", sumpToken) == SAME)
1698 inSumpComment = NO;
1699
1700 if (inSumpComment == NO)
1701 {
1702 if (tokenType == NUMBER)
1703 {
1704 sscanf (sumpToken, "%lf", &tempD);
1705 if (lastTokenWasDash == YES)
1706 tempD *= -1.0;
1707 nNumbersOnThisLine++;
1708 lastTokenWasDash = NO;
1709 }
1710 else if (tokenType == DASH)
1711 {
1712 lastTokenWasDash = YES;
1713 }
1714 else if (tokenType != UNKNOWN_TOKEN_TYPE)
1715 {
1716 allDigitLine = NO;
1717 lastTokenWasDash = NO;
1718 }
1719 }
1720 } while (*sumpToken);
1721 lineNum++;
1722
1723 if (allDigitLine == NO)
1724 {
1725 lastNonDigitLine = lineNum;
1726 numParamLines = 0;
1727 }
1728 else
1729 {
1730 if (nNumbersOnThisLine > 0)
1731 numParamLines++;
1732 }
1733 }
1734
1735 /* Now, check some aspects of the .p file. */
1736 if (inSumpComment == YES)
1737 {
1738 MrBayesPrint ("%s Unterminated comment in file \"%s\"\n", spacer, fileName);
1739 goto errorExit;
1740 }
1741 if (numParamLines <= 0)
1742 {
1743 MrBayesPrint ("%s No parameters were found in file or there characters not representing a number in last string of the file.\"%s\"\n", spacer, fileName);
1744 goto errorExit;
1745 }
1746
1747 /* calculate burnin */
1748 if (chainParams.isSS == YES)
1749 {
1750 burnin = 0;
1751 }
1752 else
1753 {
1754 if (chainParams.relativeBurnin == YES)
1755 burnin = (int) (chainParams.burninFraction * numParamLines);
1756 else
1757 burnin = chainParams.chainBurnIn;
1758 }
1759
1760 /* check against burnin */
1761 if (burnin > numParamLines)
1762 {
1763 MrBayesPrint ("%s No parameters can be sampled from file %s as the burnin (%d) exceeds the number of lines in last block (%d)\n",
1764 spacer, fileName, burnin, numParamLines);
1765 MrBayesPrint ("%s Try setting burnin to a number less than %d\n", spacer, numParamLines);
1766 goto errorExit;
1767 }
1768
1769 /* Set some info in fileInfo */
1770 fileInfo->firstParamLine = lastNonDigitLine + burnin;
1771 fileInfo->headerLine = lastNonDigitLine;
1772
1773 /* Calculate and check the number of columns and rows for the file; get header line at the same time */
1774 (void)fseek(fp, 0L, 0);
1775 for (lineNum=0; lineNum<lastNonDigitLine; lineNum++)
1776 if (fgets (s, fileInfo->longestLineLength + 2, fp)==NULL)
1777 goto errorExit;
1778 strcpy(headerLine, s);
1779 for (; lineNum < lastNonDigitLine+burnin; lineNum++)
1780 if (fgets (s, fileInfo->longestLineLength + 2, fp)==NULL)
1781 goto errorExit;
1782
1783 inSumpComment = NO;
1784 nLines = 0;
1785 firstNumCols = 0;
1786 while (fgets (s, fileInfo->longestLineLength + 2, fp) != NULL)
1787 {
1788 sumpTokenP = &s[0];
1789 allDigitLine = YES;
1790 lastTokenWasDash = NO;
1791 nNumbersOnThisLine = 0;
1792 do {
1793 if (GetToken (sumpToken, &tokenType, &sumpTokenP))
1794 goto errorExit;
1795 if (IsSame("[", sumpToken) == SAME)
1796 inSumpComment = YES;
1797 if (IsSame("]", sumpToken) == SAME)
1798 inSumpComment = NO;
1799 if (inSumpComment == NO)
1800 {
1801 if (tokenType == NUMBER)
1802 {
1803 nNumbersOnThisLine++;
1804 lastTokenWasDash = NO;
1805 }
1806 else if (tokenType == DASH)
1807 {
1808 lastTokenWasDash = YES;
1809 }
1810 else if (tokenType != UNKNOWN_TOKEN_TYPE)
1811 {
1812 allDigitLine = NO;
1813 lastTokenWasDash = NO;
1814 }
1815 }
1816 } while (*sumpToken);
1817 lineNum++;
1818 if (allDigitLine == NO)
1819 {
1820 MrBayesPrint ("%s Found a line with non-digit characters (line %d) in file %s\n", spacer, lineNum, fileName);
1821 goto errorExit;
1822 }
1823 else
1824 {
1825 if (nNumbersOnThisLine > 0)
1826 {
1827 nLines++;
1828 if (nLines == 1)
1829 firstNumCols = nNumbersOnThisLine;
1830 else
1831 {
1832 if (nNumbersOnThisLine != firstNumCols)
1833 {
1834 MrBayesPrint ("%s Number of columns is not even (%d in first line and %d in line %d of file %s)\n", spacer, firstNumCols, nNumbersOnThisLine, lineNum, fileName);
1835 goto errorExit;
1836 }
1837 }
1838 }
1839 }
1840 }
1841 fileInfo->numRows = nLines;
1842 fileInfo->numColumns = firstNumCols;
1843
1844 /* set or check headers */
1845 if ((*headerNames) == NULL)
1846 {
1847 GetHeaders (headerNames, headerLine, nHeaders);
1848 if (*nHeaders != fileInfo->numColumns)
1849 {
1850 MrBayesPrint ("%s Expected %d headers but found %d headers\n", spacer, fileInfo->numColumns, *nHeaders);
1851 for (i=0; i<*nHeaders; i++)
1852 SAFEFREE ((*headerNames)[i]);
1853 SAFEFREE (*headerNames);
1854 *nHeaders=0;
1855 goto errorExit;
1856 }
1857 }
1858 else
1859 {
1860 if (*nHeaders != fileInfo->numColumns)
1861 {
1862 MrBayesPrint ("%s Expected %d columns but found %d columns\n", spacer, *nHeaders, fileInfo->numColumns);
1863 goto errorExit;
1864 }
1865 for (i=0, t=strtok(headerLine,"\t\n\r"); t!=NULL; t=strtok(NULL,"\t\n\r"), i++)
1866 {
1867 if (i == *nHeaders)
1868 {
1869 MrBayesPrint ("%s Expected %d headers but found more headers.\n",
1870 spacer, fileInfo->numColumns);
1871 goto errorExit;
1872 }
1873 if (strcmp(t,(*headerNames)[i])!=0)
1874 {
1875 MrBayesPrint ("%s Expected header '%s' for column %d but the header for this column was '%s' in file '%s'\n", spacer, (*headerNames)[i], i+1, t, fileName);
1876 MrBayesPrint ("%s It could be that some parameter values are not numbers and the whole string containing \n",spacer);
1877 MrBayesPrint ("%s this wrongly formatted parameter is treated as a header.\n",spacer);
1878 goto errorExit;
1879 }
1880 }
1881 if (t != NULL)
1882 {
1883 MrBayesPrint ("%s Expected %d headers but found more headers.\n",spacer, fileInfo->numColumns);
1884 goto errorExit;
1885 }
1886 if (i < *nHeaders)
1887 {
1888 MrBayesPrint ("%s Expected header '%s' for column %d but the header for this column was '%s' in file '%s'\n",
1889 spacer, (*headerNames)[i], i+1, t, fileName);
1890 goto errorExit;
1891 }
1892 }
1893
1894 free (s);
1895 fclose(fp);
1896 return (NO_ERROR);
1897
1898 errorExit:
1899
1900 free(s);
1901 fclose(fp);
1902 return (ERROR);
1903 }
1904
1905
1906 /***************************************************
1907 |
1908 | FindHeader: Find token in list
1909 |
1910 ----------------------------------------------------*/
FindHeader(char * token,char ** headerNames,int nHeaders,int * index)1911 int FindHeader (char *token, char **headerNames, int nHeaders, int *index)
1912 {
1913 int i, match=0, nMatches;
1914
1915 *index = -1;
1916 nMatches = 0;
1917 for (i=0; i<nHeaders; i++)
1918 {
1919 if (!strcmp(token,headerNames[i]))
1920 {
1921 nMatches++;
1922 match = i;
1923 }
1924 }
1925
1926 if (nMatches != 1)
1927 return (ERROR);
1928
1929 *index = match;
1930 return (NO_ERROR);
1931 }
1932
1933
1934 /* FreeParameterSamples: Free parameter samples space */
FreeParameterSamples(ParameterSample * parameterSamples)1935 void FreeParameterSamples (ParameterSample *parameterSamples)
1936 {
1937 if (parameterSamples != NULL)
1938 {
1939 free (parameterSamples[0].values[0]);
1940 free (parameterSamples[0].values);
1941 free (parameterSamples);
1942 }
1943 }
1944
1945
1946 /***************************************************
1947 |
1948 | GetHeaders: Get headers from headerLine and put
1949 | them in list while updating nHeaders to reflect
1950 | the number of headers
1951 |
1952 ----------------------------------------------------*/
GetHeaders(char *** headerNames,char * headerLine,int * nHeaders)1953 int GetHeaders (char ***headerNames, char *headerLine, int *nHeaders)
1954 {
1955 char *s;
1956
1957 (*nHeaders) = 0;
1958 for (s=strtok(headerLine," \t\n\r"); s!=NULL; s=strtok(NULL," \t\n\r"))
1959 {
1960 if (AddString (headerNames, *nHeaders, s) == ERROR)
1961 {
1962 MrBayesPrint ("%s Error adding header to list of headers \n", spacer, s);
1963 return ERROR;
1964 }
1965 (*nHeaders)++;
1966 }
1967
1968 return (NO_ERROR);
1969 }
1970
1971
1972 /* PrintMargLikes: Print marginal likelihoods to screen and to .lstat file */
PrintMargLikes(char * fileName,char ** headerNames,int nHeaders,ParameterSample * parameterSamples,int nRuns,int nSamples)1973 int PrintMargLikes (char *fileName, char **headerNames, int nHeaders, ParameterSample *parameterSamples, int nRuns, int nSamples)
1974 {
1975 int i, j, len, longestHeader, *sampleCounts=NULL;
1976 char temp[100];
1977 Stat theStats;
1978 FILE *fp;
1979
1980 /* calculate longest header */
1981 longestHeader = 9; /* length of 'parameter' */
1982 for (i=0; i<nHeaders; i++)
1983 {
1984 strcpy (temp, headerNames[i]);
1985 len = (int) strlen(temp);
1986 for (j=0; modelIndicatorParams[j][0]!='\0'; j++)
1987 if (IsSame (temp,modelIndicatorParams[j]) != DIFFERENT)
1988 break;
1989 if (modelIndicatorParams[j][0]!='\0')
1990 continue;
1991 if (!strcmp (temp, "Gen") || !strcmp (temp, "LnL") || !strcmp (temp, "LnPr"))
1992 continue;
1993 if (len > longestHeader)
1994 longestHeader = len;
1995 }
1996
1997 /* open output file */
1998 strncpy (temp, fileName, 90);
1999 strcat (temp, ".pstat");
2000 fp = OpenNewMBPrintFile (temp);
2001 if (!fp)
2002 return ERROR;
2003
2004 /* print unique identifier to the output file */
2005 if (strlen(stamp) > 1)
2006 MrBayesPrintf (fp, "[ID: %s]\n", stamp);
2007
2008 /* allocate and set nSamples */
2009 sampleCounts = (int *) SafeCalloc (nRuns, sizeof(int));
2010 if (!sampleCounts)
2011 {
2012 fclose(fp);
2013 return ERROR;
2014 }
2015 for (i=0; i<nRuns; i++)
2016 sampleCounts[i] = nSamples;
2017
2018 /* print the header rows */
2019 MrBayesPrint ("\n");
2020 if (sumpParams.HPD == YES)
2021 MrBayesPrint ("%s %*c 95%% HPD Interval\n", spacer, longestHeader, ' ');
2022 else
2023 MrBayesPrint ("%s %*c 95%% Cred. Interval\n", spacer, longestHeader, ' ');
2024 MrBayesPrint ("%s %*c --------------------\n", spacer, longestHeader, ' ');
2025
2026 MrBayesPrint ("%s Parameter%*c Mean Variance Lower Upper Median", spacer, longestHeader-9, ' ');
2027 if (nRuns > 1)
2028 MrBayesPrint (" PSRF+ ");
2029 MrBayesPrint ("\n");
2030
2031 MrBayesPrint ("%s ", spacer);
2032 for (j=0; j<longestHeader+1; j++)
2033 MrBayesPrint ("-");
2034 MrBayesPrint ("-----------------------------------------------------------");
2035 if (nRuns > 1)
2036 MrBayesPrint ("----------");
2037 MrBayesPrint ("\n");
2038 if (nRuns > 1)
2039 MrBayesPrintf (fp, "Parameter\tMean\tVariance\tLower\tUpper\tMedian\tPSRF\n");
2040 else
2041 MrBayesPrintf (fp, "Parameter\tMean\tVariance\tLower\tUpper\tMedian\n");
2042
2043 /* print table values */
2044 for (i=0; i<nHeaders; i++)
2045 {
2046 strcpy (temp, headerNames[i]);
2047 for (j=0; modelIndicatorParams[j][0]!='\0'; j++)
2048 if (IsSame (temp,modelIndicatorParams[j]) != DIFFERENT)
2049 break;
2050 if (!strcmp (temp, "Gen") || !strcmp (temp, "LnL") || !strcmp (temp, "LnPr"))
2051 continue;
2052
2053 GetSummary (parameterSamples[i].values, nRuns, sampleCounts, &theStats, sumpParams.HPD);
2054
2055 MrBayesPrint ("%s %-*s ", spacer, longestHeader, temp);
2056 MrBayesPrint ("%10.6lf %10.6lf %10.6lf %10.6lf %10.6lf", theStats.mean, theStats.var, theStats.lower, theStats.upper, theStats.median);
2057 MrBayesPrintf (fp, "%s", temp);
2058 MrBayesPrintf (fp, "\t%s", MbPrintNum(theStats.mean));
2059 MrBayesPrintf (fp, "\t%s", MbPrintNum(theStats.var));
2060 MrBayesPrintf (fp, "\t%s", MbPrintNum(theStats.lower));
2061 MrBayesPrintf (fp, "\t%s", MbPrintNum(theStats.upper));
2062 MrBayesPrintf (fp, "\t%s", MbPrintNum(theStats.median));
2063 if (nRuns > 1)
2064 {
2065 if (theStats.PSRF < 0.0)
2066 {
2067 MrBayesPrint (" NA ");
2068 MrBayesPrintf (fp, "NA");
2069 }
2070 else
2071 {
2072 MrBayesPrint (" %7.3lf", theStats.PSRF);
2073 MrBayesPrintf (fp, "\t%s", MbPrintNum(theStats.PSRF));
2074 }
2075 }
2076 MrBayesPrint ("\n");
2077 MrBayesPrintf (fp, "\n");
2078 }
2079 MrBayesPrint ("%s ", spacer);
2080 for (j=0; j<longestHeader+1; j++)
2081 MrBayesPrint ("-");
2082 MrBayesPrint ("-----------------------------------------------------------");
2083 if (nRuns > 1)
2084 MrBayesPrint ("----------");
2085 MrBayesPrint ("\n");
2086 if (nRuns > 1)
2087 {
2088 MrBayesPrint ("%s + Convergence diagnostic (PSRF = Potential Scale Reduction Factor; Gelman\n", spacer);
2089 MrBayesPrint ("%s and Rubin, 1992) should approach 1.0 as runs converge.\n", spacer);
2090 }
2091
2092 fclose (fp);
2093 free (sampleCounts);
2094
2095 return (NO_ERROR);
2096 }
2097
2098
2099 /* PrintModelStats: Print model stats to screen and to .mstat file */
PrintModelStats(char * fileName,char ** headerNames,int nHeaders,ParameterSample * parameterSamples,int nRuns,int nSamples)2100 int PrintModelStats (char *fileName, char **headerNames, int nHeaders, ParameterSample *parameterSamples, int nRuns, int nSamples)
2101 {
2102 int i, j, j1, j2, k, longestName, nElements, *modelCounts=NULL;
2103 MrBFlt f, *prob=NULL, *sum=NULL, *ssq=NULL, *min=NULL, *max=NULL, *stddev=NULL;
2104 char temp[100];
2105 FILE *fp;
2106 ModelProb *elem = NULL;
2107
2108 /* nHeaders - is a convenient synonym for number of column headers */
2109
2110 /* check if we have any model indicator variables and also check for longest header */
2111 k = 0;
2112 longestName = 0;
2113 for (i=0; i<nHeaders; i++)
2114 {
2115 for (j=0; strcmp(modelIndicatorParams[j],"")!=0; j++)
2116 {
2117 if (IsSame (headerNames[i], modelIndicatorParams[j]) != DIFFERENT)
2118 {
2119 k++;
2120 for (j1=0; strcmp(modelElementNames[j][j1],"")!=0; j1++)
2121 {
2122 j2 = (int)(strlen(headerNames[i]) + 2 + strlen(modelElementNames[j][j1]));
2123 if (j2 > longestName)
2124 longestName = j2;
2125 }
2126 break;
2127 }
2128 }
2129 }
2130
2131 /* return if nothing to do */
2132 if (k==0)
2133 return NO_ERROR;
2134
2135 /* open output file */
2136 MrBayesPrint ("%s Model probabilities above %1.3lf\n", spacer, sumpParams.minProb);
2137 MrBayesPrint ("%s Estimates saved to file \"%s.mstat\".\n", spacer, sumpParams.sumpOutfile);
2138 strncpy (temp,fileName,90);
2139 strcat (temp, ".mstat");
2140 fp = OpenNewMBPrintFile(temp);
2141 if (!fp)
2142 return ERROR;
2143 MrBayesPrint ("\n");
2144
2145 /* print unique identifier to the output file */
2146 if (strlen(stamp) > 1)
2147 MrBayesPrintf (fp, "[ID: %s]\n", stamp);
2148
2149 /* print header */
2150 MrBayesPrintf (fp, "\n\n");
2151 if (nRuns == 1)
2152 {
2153 MrBayesPrint ("%s %*c Posterior\n", spacer, longestName-5, ' ');
2154 MrBayesPrint ("%s Model%*c Probability\n", spacer, longestName-5, ' ');
2155 MrBayesPrint ("%s -----", spacer);
2156 for (i=0; i<longestName-5; i++)
2157 MrBayesPrint ("-");
2158 MrBayesPrint ("------------------\n");
2159 MrBayesPrintf (fp, "Model\tProbability\n");
2160 }
2161 else
2162 {
2163 MrBayesPrint ("%s %*c Posterior Standard Min. Max. \n", spacer, longestName-5, ' ');
2164 MrBayesPrint ("%s Model%*c Probability Deviation Probability Probability\n", spacer, longestName-5, ' ');
2165 MrBayesPrint ("%s -----", spacer);
2166 for (i=0; i<longestName-5; i++)
2167 MrBayesPrint ("-");
2168 MrBayesPrint ("---------------------------------------------------------------\n");
2169 MrBayesPrintf (fp, "Model\tProbability\tStd_dev\tMin_prob\tMax_prob\n");
2170 }
2171
2172 /* calculate and print values */
2173 for (i=0; i<nHeaders; i++)
2174 {
2175 for (j=0; modelIndicatorParams[j][0]!='\0'; j++)
2176 if (IsSame (headerNames[i], modelIndicatorParams[j]) != DIFFERENT)
2177 break;
2178 if (modelIndicatorParams[j][0] == '\0')
2179 continue;
2180
2181 for (nElements=0; modelElementNames[j][nElements][0]!='\0'; nElements++)
2182 ;
2183
2184 modelCounts = (int *) SafeCalloc (nElements, sizeof(int));
2185 if (!modelCounts)
2186 {
2187 fclose(fp);
2188 return ERROR;
2189 }
2190 prob = (MrBFlt *) SafeCalloc (6*nElements, sizeof(MrBFlt));
2191 if (!prob)
2192 {
2193 free (modelCounts);
2194 fclose (fp);
2195 return ERROR;
2196 }
2197 sum = prob + nElements;
2198 ssq = prob + 2*nElements;
2199 stddev = prob + 3*nElements;
2200 min = prob + 4*nElements;
2201 max = prob + 5*nElements;
2202
2203 for (j1=0; j1<nElements; j1++)
2204 min[j1] = 1.0;
2205
2206 for (j1=0; j1<nRuns; j1++)
2207 {
2208 for (j2=0; j2<nElements; j2++)
2209 modelCounts[j2] = 0;
2210 for (j2=0; j2<nSamples; j2++)
2211 modelCounts[(int)(parameterSamples[i].values[j1][j2] + 0.1)]++;
2212 for (j2=0; j2<nElements; j2++)
2213 {
2214 f = (MrBFlt) modelCounts[j2] / (MrBFlt) nSamples;
2215 sum[j2] += f;
2216 ssq[j2] += f*f;
2217 if (f<min[j2])
2218 min[j2] = f;
2219 if (f > max[j2])
2220 max[j2] = f;
2221 }
2222 }
2223
2224 for (j1=0; j1<nElements; j1++)
2225 {
2226 prob[j1] = sum[j1] / (MrBFlt) nRuns;
2227 f = ssq[j1] - (sum[j1] * sum[j1] / (MrBFlt) nRuns);
2228 f /= (nRuns - 1);
2229 if (f <= 0.0)
2230 stddev[j1] = 0.0;
2231 else
2232 stddev[j1] = sqrt (f);
2233 }
2234
2235 elem = (ModelProb *) SafeCalloc (nElements, sizeof(ModelProb));
2236 for (j1=0; j1<nElements; j1++)
2237 {
2238 elem[j1].index = j1;
2239 elem[j1].prob = prob[j1];
2240 }
2241
2242 /* sort in terms of decreasing probabilities */
2243 qsort((void *)elem, (size_t)nElements, sizeof(ModelProb), CompareModelProbs);
2244
2245 for (j1=0; j1<nElements; j1++)
2246 {
2247 if (elem[j1].prob <= sumpParams.minProb)
2248 break;
2249
2250 if (nRuns == 1)
2251 {
2252 sprintf (temp, "%s[%s]", headerNames[i], modelElementNames[j][elem[j1].index]);
2253 MrBayesPrint ("%s %-*s %1.3lf\n", spacer, longestName, temp, prob[elem[j1].index]);
2254 MrBayesPrintf (fp, "%s\t%s\n", temp, MbPrintNum(prob[elem[j1].index]));
2255 }
2256 else /* if (nRuns > 1) */
2257 {
2258 sprintf (temp, "%s[%s]", headerNames[i], modelElementNames[j][elem[j1].index]);
2259 MrBayesPrint ("%s %-*s %1.3lf %1.3lf %1.3lf %1.3lf\n",
2260 spacer, longestName, temp, prob[elem[j1].index], stddev[elem[j1].index], min[elem[j1].index], max[elem[j1].index]);
2261 MrBayesPrintf (fp, "%s", temp);
2262 MrBayesPrintf (fp, "\t%s", MbPrintNum(prob[elem[j1].index]));
2263 MrBayesPrintf (fp, "\t%s", MbPrintNum(stddev[elem[j1].index]));
2264 MrBayesPrintf (fp, "\t%s", MbPrintNum(min[elem[j1].index]));
2265 MrBayesPrintf (fp, "\t%s", MbPrintNum(max[elem[j1].index]));
2266 MrBayesPrintf (fp, "\n");
2267 }
2268 }
2269 free(elem);
2270 elem = NULL;
2271 free(modelCounts);
2272 modelCounts = NULL;
2273 free (prob);
2274 prob = NULL;
2275 }
2276
2277 /* print footer */
2278 if (nRuns == 1)
2279 {
2280 MrBayesPrint ("%s -----", spacer);
2281 for (i=0; i<longestName-5; i++)
2282 MrBayesPrint ("-");
2283 MrBayesPrint ("------------------\n\n");
2284 }
2285 else
2286 {
2287 MrBayesPrint ("%s -----", spacer);
2288 for (i=0; i<longestName-5; i++)
2289 MrBayesPrint ("-");
2290 MrBayesPrint ("---------------------------------------------------------------\n\n");
2291 }
2292
2293 /* close output file */
2294 fclose (fp);
2295
2296 return (NO_ERROR);
2297 }
2298
2299
2300 /* PrintOverlayPlot: Print overlay x-y plot of log likelihood vs. generation for several runs */
PrintOverlayPlot(MrBFlt ** xVals,MrBFlt ** yVals,int nRuns,int startingFrom,int nSamples)2301 int PrintOverlayPlot (MrBFlt **xVals, MrBFlt **yVals, int nRuns, int startingFrom, int nSamples)
2302 {
2303 int i, j, k, k2, n, screenHeight, screenWidth, numY[60], width;
2304 char plotSymbol[15][60];
2305 MrBFlt x, y, minX, maxX, minY, maxY, meanY[60];
2306
2307 if (nRuns == 2)
2308 MrBayesPrint ("\n%s Overlay plot for both runs:\n", spacer);
2309 else
2310 MrBayesPrint ("\n%s Overlay plot for all %d runs:\n", spacer, sumpParams.numRuns);
2311 if (nRuns > 9)
2312 MrBayesPrint ("%s (1 = Run number 1; 2 = Run number 2 etc.; x = Run number 10 or above; * = Several runs)\n", spacer);
2313 else if (nRuns > 2)
2314 MrBayesPrint ("%s (1 = Run number 1; 2 = Run number 2 etc.; * = Several runs)\n", spacer);
2315 else
2316 MrBayesPrint ("%s (1 = Run number 1; 2 = Run number 2; * = Both runs)\n", spacer);
2317
2318 /* print overlay x-y plot of log likelihood vs. generation for all runs */
2319 screenWidth = 60; /* don't change this without changing numY, meanY, and plotSymbol declared above */
2320 screenHeight = 15;
2321
2322 /* find minX, minY, maxX, and maxY over all runs */
2323 minX = minY = 1000000000.0;
2324 maxX = maxY = -1000000000.0;
2325 for (n=0; n<nRuns; n++)
2326 {
2327 for (i=startingFrom; i<startingFrom+nSamples; i++)
2328 {
2329 x = xVals[n][i];
2330 if (x < minX)
2331 minX = x;
2332 if (x > maxX)
2333 maxX = x;
2334 }
2335 }
2336 for (n=0; n<nRuns; n++)
2337 {
2338 y = 0.0;
2339 j = 0;
2340 k2 = 0;
2341 for (i=startingFrom; i<startingFrom+nSamples; i++)
2342 {
2343 x = xVals[n][i];
2344 k = (int) (((x - minX) / (maxX - minX)) * screenWidth);
2345 if (k <= 0)
2346 k = 0;
2347 if (k >= screenWidth)
2348 k = screenWidth - 1;
2349 if (k == j)
2350 {
2351 y += yVals[n][i];
2352 k2 ++;
2353 }
2354 else
2355 {
2356 y /= k2;
2357 if (y < minY)
2358 minY = y;
2359 if (y > maxY)
2360 maxY = y;
2361 k2 = 1;
2362 y = yVals[n][i];
2363 j++;
2364 }
2365 }
2366 if (k2 > 0)
2367 {
2368 y /= k2;
2369 if (y < minY)
2370 minY = y;
2371 if (y > maxY)
2372 maxY = y;
2373 }
2374 }
2375
2376 /* initialize the plot symbols */
2377 for (i=0; i<screenHeight; i++)
2378 for (j=0; j<screenWidth; j++)
2379 plotSymbol[i][j] = ' ';
2380
2381 /* assemble the plot symbols */
2382 for (n=0; n<nRuns; n++)
2383 {
2384 /* find the plot points for this run */
2385 for (i=0; i<screenWidth; i++)
2386 {
2387 numY[i] = 0;
2388 meanY[i] = 0.0;
2389 }
2390 for (i=startingFrom; i<startingFrom+nSamples; i++)
2391 {
2392 x = xVals[n][i];
2393 y = yVals[n][i];
2394 k = (int)(((x - minX) / (maxX - minX)) * screenWidth);
2395 if (k >= screenWidth)
2396 k = screenWidth - 1;
2397 if (k <= 0)
2398 k = 0;
2399 meanY[k] += y;
2400 numY[k]++;
2401 }
2402
2403 /* transfer these points to the overlay */
2404 for (i=0; i<screenWidth; i++)
2405 {
2406 if (numY[i] > 0)
2407 {
2408 k = (int) ((((meanY[i] / numY[i]) - minY)/ (maxY - minY)) * screenHeight);
2409 if (k < 0)
2410 k = 0;
2411 else if (k >= screenHeight)
2412 k = screenHeight - 1;
2413 if (plotSymbol[k][i] == ' ')
2414 {
2415 if (n <= 8)
2416 plotSymbol[k][i] = '1' + n;
2417 else
2418 plotSymbol[k][i] = 'x';
2419 }
2420 else
2421 plotSymbol[k][i] = '*';
2422 }
2423 }
2424 } /* next run */
2425
2426 /* now print the overlay plot */
2427 MrBayesPrint ("\n%s +", spacer);
2428 for (i=0; i<screenWidth; i++)
2429 MrBayesPrint ("-");
2430 MrBayesPrint ("+ %1.2lf\n", maxY);
2431 for (i=screenHeight-1; i>=0; i--)
2432 {
2433 MrBayesPrint ("%s |", spacer);
2434 for (j=0; j<screenWidth; j++)
2435 {
2436 MrBayesPrint ("%c", plotSymbol[i][j]);
2437 }
2438 MrBayesPrint ("|\n");
2439 }
2440 MrBayesPrint ("%s +", spacer);
2441 for (i=0; i<screenWidth; i++)
2442 {
2443 if (i % (screenWidth/10) == 0 && i != 0)
2444 MrBayesPrint ("+");
2445 else
2446 MrBayesPrint ("-");
2447 }
2448 MrBayesPrint ("+ %1.2lf\n", minY);
2449 MrBayesPrint ("%s ^", spacer);
2450 for (i=0; i<screenWidth; i++)
2451 MrBayesPrint (" ");
2452 MrBayesPrint ("^\n");
2453 MrBayesPrint ("%s %1.0lf", spacer, minX);
2454 if ((int)minX>0)
2455 width=(int)(log10(minX));
2456 else if ((int)minX==0)
2457 width=1;
2458 else
2459 width=(int)(log10(-minX))+1;
2460 for (i=0; i<screenWidth-width; i++)
2461 MrBayesPrint (" ");
2462 MrBayesPrint ("%1.0lf\n\n", maxX);
2463
2464 return (NO_ERROR);
2465 }
2466
2467
2468 /* PrintParamStats: Print parameter table (not model indicator params) to screen and .pstat file */
PrintParamStats(char * fileName,char ** headerNames,int nHeaders,ParameterSample * parameterSamples,int nRuns,int nSamples)2469 int PrintParamStats (char *fileName, char **headerNames, int nHeaders, ParameterSample *parameterSamples, int nRuns, int nSamples)
2470 {
2471 int i, j, len, longestHeader, *sampleCounts=NULL;
2472 static char *temp=NULL;
2473 char tempf[100];
2474 Stat theStats;
2475 FILE *fp;
2476
2477 /* calculate longest header */
2478 longestHeader = 9; /* length of 'parameter' */
2479 for (i=0; i<nHeaders; i++)
2480 {
2481 SafeStrcpy (&temp, headerNames[i]);
2482 len = (int) strlen(temp);
2483 for (j=0; modelIndicatorParams[j][0]!='\0'; j++)
2484 if (IsSame (temp,modelIndicatorParams[j]) != DIFFERENT)
2485 break;
2486 if (modelIndicatorParams[j][0]!='\0')
2487 continue;
2488 if (!strcmp (temp, "Gen") || !strcmp (temp, "LnL") || !strcmp (temp, "LnPr"))
2489 continue;
2490 if (len > longestHeader)
2491 longestHeader = len;
2492 }
2493
2494 /* open output file */
2495 strncpy (tempf, fileName, 90);
2496 strcat (tempf, ".pstat");
2497 fp = OpenNewMBPrintFile (tempf);
2498 if (!fp)
2499 return ERROR;
2500
2501 /* print unique identifier to the output file */
2502 if (strlen(stamp) > 1)
2503 MrBayesPrintf (fp, "[ID: %s]\n", stamp);
2504
2505 /* allocate and set nSamples */
2506 sampleCounts = (int *) SafeCalloc (nRuns, sizeof(int));
2507 if (!sampleCounts)
2508 {
2509 fclose(fp);
2510 return ERROR;
2511 }
2512 for (i=0; i<nRuns; i++)
2513 sampleCounts[i] = nSamples;
2514
2515 /* print the header rows */
2516 MrBayesPrint ("\n");
2517 if (sumpParams.HPD == YES)
2518 MrBayesPrint ("%s %*c 95%% HPD Interval\n", spacer, longestHeader, ' ');
2519 else
2520 MrBayesPrint ("%s %*c 95%% Cred. Interval\n", spacer, longestHeader, ' ');
2521 MrBayesPrint ("%s %*c --------------------\n", spacer, longestHeader, ' ');
2522
2523 if (nRuns > 1)
2524 MrBayesPrint ("%s Parameter%*c Mean Variance Lower Upper Median min ESS* avg ESS PSRF+ ", spacer, longestHeader-9, ' ');
2525 else
2526 MrBayesPrint ("%s Parameter%*c Mean Variance Lower Upper Median ESS*", spacer, longestHeader-9, ' ');
2527 MrBayesPrint ("\n");
2528
2529 MrBayesPrint ("%s ", spacer);
2530 for (j=0; j<longestHeader+1; j++)
2531 MrBayesPrint ("-");
2532 MrBayesPrint ("---------------------------------------------------------------------");
2533 if (nRuns > 1)
2534 MrBayesPrint ("-------------------");
2535 MrBayesPrint ("\n");
2536 if (nRuns > 1)
2537 MrBayesPrintf (fp, "Parameter\tMean\tVariance\tLower\tUpper\tMedian\tminESS\tavgESS\tPSRF\n");
2538 else
2539 MrBayesPrintf (fp, "Parameter\tMean\tVariance\tLower\tUpper\tMedian\tESS\n");
2540
2541 /* print table values */
2542 for (i=0; i<nHeaders; i++)
2543 {
2544 SafeStrcpy(&temp, headerNames[i]);
2545 for (j=0; modelIndicatorParams[j][0]!='\0'; j++)
2546 if (IsSame (temp,modelIndicatorParams[j]) != DIFFERENT)
2547 break;
2548 if (modelIndicatorParams[j][0]!='\0')
2549 continue;
2550 if (!strcmp (temp, "Gen") || !strcmp (temp, "LnL") || !strcmp (temp, "LnPr"))
2551 continue;
2552
2553 GetSummary (parameterSamples[i].values, nRuns, sampleCounts, &theStats, sumpParams.HPD);
2554
2555 MrBayesPrint ("%s %-*s ", spacer, longestHeader, temp);
2556 MrBayesPrint ("%10.6lf %10.6lf %10.6lf %10.6lf %10.6lf", theStats.mean, theStats.var, theStats.lower, theStats.upper, theStats.median);
2557 MrBayesPrintf (fp, "%s", temp);
2558 MrBayesPrintf (fp, "\t%s", MbPrintNum(theStats.mean));
2559 MrBayesPrintf (fp, "\t%s", MbPrintNum(theStats.var));
2560 MrBayesPrintf (fp, "\t%s", MbPrintNum(theStats.lower));
2561 MrBayesPrintf (fp, "\t%s", MbPrintNum(theStats.upper));
2562 MrBayesPrintf (fp, "\t%s", MbPrintNum(theStats.median));
2563
2564 if (theStats.minESS == theStats.minESS)
2565 {
2566 MrBayesPrintf (fp, "\t%s", MbPrintNum(theStats.minESS));
2567 MrBayesPrint (" %8.2lf", theStats.minESS);
2568 }
2569 else
2570 {
2571 MrBayesPrint (" NA ");
2572 MrBayesPrintf (fp, "NA");
2573 }
2574 if (nRuns > 1)
2575 {
2576 if (theStats.minESS == theStats.minESS)
2577 {
2578 MrBayesPrint (" %8.2lf", theStats.avrESS);
2579 MrBayesPrintf (fp, "\t%s", MbPrintNum(theStats.avrESS));
2580 }
2581 else
2582 {
2583 MrBayesPrint (" NA ");
2584 MrBayesPrintf (fp, "NA");
2585 }
2586 if (theStats.PSRF < 0.0)
2587 {
2588 MrBayesPrint (" NA ");
2589 MrBayesPrintf (fp, "NA");
2590 }
2591 else
2592 {
2593 MrBayesPrint (" %7.3lf", theStats.PSRF);
2594 MrBayesPrintf (fp, "\t%s", MbPrintNum(theStats.PSRF));
2595 }
2596 }
2597 MrBayesPrint ("\n");
2598 MrBayesPrintf (fp, "\n");
2599 }
2600 MrBayesPrint ("%s ", spacer);
2601 for (j=0; j<longestHeader+1; j++)
2602 MrBayesPrint ("-");
2603 MrBayesPrint ("---------------------------------------------------------------------");
2604 if (nRuns > 1)
2605 MrBayesPrint ("-------------------");
2606 MrBayesPrint ("\n");
2607 if (nRuns > 1)
2608 {
2609 MrBayesPrint ("%s * Convergence diagnostic (ESS = Estimated Sample Size); min and avg values\n", spacer);
2610 MrBayesPrint ("%s correspond to minimal and average ESS among runs. \n", spacer);
2611 MrBayesPrint ("%s ESS value below 100 may indicate that the parameter is undersampled. \n", spacer);
2612 MrBayesPrint ("%s + Convergence diagnostic (PSRF = Potential Scale Reduction Factor; Gelman\n", spacer);
2613 MrBayesPrint ("%s and Rubin, 1992) should approach 1.0 as runs converge.\n", spacer);
2614 }
2615 else
2616 {
2617 MrBayesPrint ("%s * Convergence diagnostic (ESS = Estimated Sample Size); ESS value \n", spacer);
2618 MrBayesPrint ("%s below 100 may indicate that the parameter is undersampled. \n", spacer);
2619 }
2620 MrBayesPrint ("\n\n");
2621
2622 fclose (fp);
2623 free (sampleCounts);
2624 SAFEFREE (temp);
2625
2626 return (NO_ERROR);
2627 }
2628
2629
2630 /* PrintPlot: Print x-y plot of log likelihood vs. generation */
PrintPlot(MrBFlt * xVals,MrBFlt * yVals,int numVals)2631 int PrintPlot (MrBFlt *xVals, MrBFlt *yVals, int numVals)
2632 {
2633 int i, j, k, numY[60], screenWidth, screenHeight;
2634 MrBFlt x, y, minX, maxX, minY, maxY, meanY[60], diff;
2635
2636 /* print x-y plot of log likelihood vs. generation */
2637 screenWidth = 60; /* don't change this without changing numY and meanY, declared above */
2638 screenHeight = 15;
2639
2640 /* find minX and maxX */
2641 minX = xVals[0];
2642 maxX = xVals[0];
2643 for (i=0; i<numVals; i++)
2644 {
2645 x = xVals[i];
2646 if (x < minX)
2647 minX = x;
2648 if (x > maxX)
2649 maxX = x;
2650 }
2651
2652 /* collect Y data */
2653 for (i=0; i<screenWidth; i++)
2654 {
2655 numY[i] = 0;
2656 meanY[i] = 0.0;
2657 }
2658 for (i=0; i<numVals; i++)
2659 {
2660 x = xVals[i];
2661 y = yVals[i];
2662 k = (int)(((x - minX) / (maxX - minX)) * screenWidth);
2663 if (k >= screenWidth)
2664 k = screenWidth - 1;
2665 if (k < 0)
2666 k = 0;
2667 meanY[k] += y;
2668 numY[k]++;
2669 }
2670
2671 /* find minY and maxY */
2672 minY = maxY = meanY[0] / numY[0];
2673 for (i=0; i<screenWidth; i++)
2674 {
2675 if (meanY[i] == 0) /* with some compilers if (NaN < 1) is equal true !!! so we realy need this check*/
2676 continue;
2677 meanY[i] /= numY[i];
2678 if (meanY[i] < minY)
2679 minY = meanY[i];
2680 if (meanY[i] > maxY)
2681 maxY = meanY[i];
2682 }
2683
2684 /* find difference */
2685 diff = maxY - minY;
2686
2687 /* print plot */
2688 MrBayesPrint ("\n +");
2689 for (i=0; i<screenWidth; i++)
2690 MrBayesPrint ("-");
2691 MrBayesPrint ("+ %1.3lf\n", maxY);
2692 for (j=screenHeight-1; j>=0; j--)
2693 {
2694 MrBayesPrint (" |");
2695 for (i=0; i<screenWidth; i++)
2696 {
2697 if (numY[i] > 0)
2698 {
2699 if ((meanY[i] > ((diff/screenHeight)*j)+minY && meanY[i] <= ((diff/screenHeight)*(j+1))+minY) ||
2700 (j == 0 && meanY[i] <= minY))
2701 MrBayesPrint ("*");
2702 else
2703 MrBayesPrint (" ");
2704 }
2705 else
2706 {
2707 MrBayesPrint (" ");
2708 }
2709 }
2710 MrBayesPrint ("|\n");
2711 }
2712 MrBayesPrint (" +");
2713 for (i=0; i<screenWidth; i++)
2714 {
2715 if (i % (screenWidth/10) == 0 && i != 0)
2716 MrBayesPrint ("+");
2717 else
2718 MrBayesPrint ("-");
2719 }
2720 MrBayesPrint ("+ %1.3lf\n", minY);
2721 MrBayesPrint (" ^");
2722 for (i=0; i<screenWidth; i++)
2723 MrBayesPrint (" ");
2724 MrBayesPrint ("^\n");
2725 MrBayesPrint (" %1.0lf", minX);
2726 if (minX == 0)
2727 j = 1;
2728 else
2729 j = (int)(log10(minX)) + 1;
2730 for (i=0; i<screenWidth-j; i++)
2731 MrBayesPrint (" ");
2732 MrBayesPrint ("%1.0lf\n\n", maxX);
2733
2734 return (NO_ERROR);
2735 }
2736
2737
PrintPlotHeader(void)2738 void PrintPlotHeader (void)
2739 {
2740 MrBayesPrint ("\n");
2741 if (sumpParams.numRuns > 1)
2742 {
2743 MrBayesPrint ("%s Below are rough plots of the generation (x-axis) versus the log \n", spacer);
2744 MrBayesPrint ("%s probability of observing the data (y-axis). You can use these \n", spacer);
2745 MrBayesPrint ("%s graphs to determine what the burn in for your analysis should be. \n", spacer);
2746 MrBayesPrint ("%s When the log probability starts to plateau you may be at station- \n", spacer);
2747 MrBayesPrint ("%s arity. Sample trees and parameters after the log probability \n", spacer);
2748 MrBayesPrint ("%s plateaus. Of course, this is not a guarantee that you are at sta- \n", spacer);
2749 MrBayesPrint ("%s tionarity. Also examine the convergence diagnostics provided by \n", spacer);
2750 MrBayesPrint ("%s the 'sump' and 'sumt' commands for all the parameters in your \n", spacer);
2751 MrBayesPrint ("%s model. Remember that the burn in is the number of samples to dis- \n", spacer);
2752 MrBayesPrint ("%s card. There are a total of ngen / samplefreq samples taken during \n", spacer);
2753 MrBayesPrint ("%s a MCMC analysis. \n", spacer);
2754 }
2755 else
2756 {
2757 MrBayesPrint ("%s Below is a rough plot of the generation (x-axis) versus the log \n", spacer);
2758 MrBayesPrint ("%s probability of observing the data (y-axis). You can use this \n", spacer);
2759 MrBayesPrint ("%s graph to determine what the burn in for your analysis should be. \n", spacer);
2760 MrBayesPrint ("%s When the log probability starts to plateau you may be at station- \n", spacer);
2761 MrBayesPrint ("%s arity. Sample trees and parameters after the log probability \n", spacer);
2762 MrBayesPrint ("%s plateaus. Of course, this is not a guarantee that you are at sta- \n", spacer);
2763 MrBayesPrint ("%s analysis should be. When the log probability starts to plateau \n", spacer);
2764 MrBayesPrint ("%s tionarity. When possible, run multiple analyses starting from dif-\n", spacer);
2765 MrBayesPrint ("%s ferent random trees; if the inferences you make for independent \n", spacer);
2766 MrBayesPrint ("%s analyses are the same, this is reasonable evidence that the chains\n", spacer);
2767 MrBayesPrint ("%s have converged. You can use MrBayes to run several independent \n", spacer);
2768 MrBayesPrint ("%s analyses simultaneously. During such a run, MrBayes will monitor \n", spacer);
2769 MrBayesPrint ("%s the convergence of topologies. After the run has been completed, \n", spacer);
2770 MrBayesPrint ("%s the 'sumt' and 'sump' functions will provide additional conver- \n", spacer);
2771 MrBayesPrint ("%s gence diagnostics for all the parameters in your model. Remember \n", spacer);
2772 MrBayesPrint ("%s that the burn in is the number of samples to discard. There are \n", spacer);
2773 MrBayesPrint ("%s a total of ngen / samplefreq samples taken during a MCMC analysis.\n", spacer);
2774 }
2775 }
2776
2777
2778 /* ReadParamSamples: Read parameter samples from .p file */
ReadParamSamples(char * fileName,SumpFileInfo * fileInfo,ParameterSample * parameterSamples,int runNo)2779 int ReadParamSamples (char *fileName, SumpFileInfo *fileInfo, ParameterSample *parameterSamples, int runNo)
2780 {
2781 char sumpToken[CMD_STRING_LENGTH], *s=NULL, *p;
2782 int inSumpComment, lineNum, numLinesRead, numLinesToRead, column, lastTokenWasDash,
2783 tokenType;
2784 MrBFlt tempD;
2785 FILE *fp;
2786
2787 /* open file */
2788 if ((fp = OpenTextFileR (fileName)) == NULL)
2789 return ERROR;
2790
2791 /* allocate space for reading lines */
2792 s = (char *) SafeCalloc (fileInfo->longestLineLength + 10, sizeof(char));
2793
2794 /* fast forward to beginning of last unburned parameter line. */
2795 for (lineNum=0; lineNum<fileInfo->firstParamLine; lineNum++)
2796 if (fgets (s, fileInfo->longestLineLength + 5, fp) == 0)
2797 goto errorExit;
2798
2799 /* parse file, line-by-line. We are only parsing lines that have digits that should be read. */
2800 inSumpComment = NO;
2801 numLinesToRead = fileInfo->numRows;
2802 numLinesRead = 0;
2803 while (fgets (s, fileInfo->longestLineLength + 1, fp) != NULL)
2804 {
2805 lastTokenWasDash = NO;
2806 column = 0;
2807 p = s;
2808 do {
2809 if (GetToken (sumpToken, &tokenType, &p))
2810 goto errorExit;
2811 if (IsSame("[", sumpToken) == SAME)
2812 inSumpComment = YES;
2813 if (IsSame("]", sumpToken) == SAME)
2814 inSumpComment = NO;
2815 if (inSumpComment == NO)
2816 {
2817 if (tokenType == NUMBER)
2818 {
2819 /* read the number */
2820 if (column >= fileInfo->numColumns)
2821 {
2822 MrBayesPrint ("%s Too many values read on line %d of file %s\n", spacer, lineNum, fileName);
2823 goto errorExit;
2824 }
2825 sscanf (sumpToken, "%lf", &tempD);
2826 if (lastTokenWasDash == YES)
2827 tempD *= -1.0;
2828 parameterSamples[column].values[runNo][numLinesRead] = tempD;
2829 column++;
2830 lastTokenWasDash = NO;
2831 }
2832 else if (tokenType == DASH)
2833 {
2834 lastTokenWasDash = YES;
2835 }
2836 else if (tokenType != UNKNOWN_TOKEN_TYPE)
2837 {
2838 /* we have a problem */
2839 MrBayesPrint ("%s Line %d of file %s has non-digit characters\n", spacer, lineNum, fileName);
2840 goto errorExit;
2841 }
2842 }
2843 } while (*sumpToken);
2844
2845 lineNum++;
2846 if (column == fileInfo->numColumns)
2847 numLinesRead++;
2848 else if (column != 0)
2849 {
2850 MrBayesPrint ("%s Too few values on line %d of file %s\n", spacer, lineNum, fileName);
2851 goto errorExit;
2852 }
2853 }
2854
2855
2856 /* Check how many parameter line was read in. */
2857 if (numLinesRead != numLinesToRead)
2858 {
2859 MrBayesPrint ("%s Unable to read all lines that should contain parameter samples\n", spacer);
2860 goto errorExit;
2861 }
2862
2863 fclose (fp);
2864 free (s);
2865
2866 return (NO_ERROR);
2867
2868 errorExit:
2869
2870 fclose (fp);
2871 free (s);
2872
2873 return ERROR;
2874 }
2875
2876
2877 /* the following are moved from sumt.c to combine with sump.c */
AddSumtPartition(PartCtr * r,PolyTree * t,PolyNode * p,int runId)2878 PartCtr *AddSumtPartition (PartCtr *r, PolyTree *t, PolyNode *p, int runId)
2879 {
2880 int i, n, comp, nLongsNeeded = sumtParams.BitsLongsNeeded;
2881
2882 if (r == NULL)
2883 {
2884 /* new partition */
2885 /* create a new node */
2886 r = AllocPartCtr ();
2887 if (r == NULL)
2888 return NULL;
2889 numUniqueSplitsFound++;
2890 for (i=0; i<nLongsNeeded; i++)
2891 r->partition[i] = p->partition[i];
2892 for (i=0; i<sumtParams.numRuns; i++)
2893 r->count[i] = 0;
2894 r->left = r->right = NULL;
2895 /* record values */
2896 if (sumtParams.brlensDef == YES)
2897 r->length[runId][0]= p->length;
2898 if (sumtParams.isClock == YES)
2899 r->height[runId][0]= p->depth;
2900 if (sumtParams.isCalibrated == YES)
2901 r->age[runId][0]= p->age;
2902 for (i=0; i<sumtParams.nESets; i++)
2903 r->nEvents[i][runId][0] = t->nEvents[i][p->index];
2904 for (i=0; i<sumtParams.nBSets; i++)
2905 {
2906 r->bLen [i][runId][0] = t->effectiveBrLen[i][p->index];
2907 r->bRate[i][runId][0] = t->effectiveBrLen[i][p->index] / p->length;
2908 if (p->length == 0.0) r->bRate[i][runId][0] = 1.0; // deal with zero brl
2909 }
2910 if (t->popSizeSet == YES)
2911 r->popSize[runId][0] = t->popSize[p->index];
2912 r->count[runId] ++;
2913 r->totCount++;
2914 }
2915 else
2916 {
2917 for (i=0; i<nLongsNeeded; i++)
2918 {
2919 if (r->partition[i] != p->partition[i])
2920 break;
2921 }
2922
2923 if (i == nLongsNeeded)
2924 comp = 0;
2925 else if (r->partition[i] < p->partition[i])
2926 comp = -1;
2927 else
2928 comp = 1;
2929
2930 if (comp == 0) /* repeated partition */
2931 {
2932 n = r->count[runId];
2933 /* check if we need to allocate more space */
2934 if (n % ALLOC_LEN == 0)
2935 {
2936 /* allocate more space */
2937 if (sumtParams.brlensDef == YES)
2938 r->length[runId] = (MrBFlt *) SafeRealloc ((void *)r->length[runId], ((size_t)n+ALLOC_LEN)*sizeof(MrBFlt));
2939 if (sumtParams.isClock == YES)
2940 r->height[runId] = (MrBFlt *) SafeRealloc ((void *)r->height[runId], ((size_t)n+ALLOC_LEN)*sizeof(MrBFlt));
2941 if (sumtParams.isCalibrated == YES)
2942 r->age[runId] = (MrBFlt *) SafeRealloc ((void *)r->age[runId], ((size_t)n+ALLOC_LEN)*sizeof(MrBFlt));
2943 if (sumtParams.nESets > 0)
2944 {
2945 for (i=0; i<sumtParams.nESets; i++)
2946 r->nEvents[i][runId] = (int *) SafeRealloc ((void *)r->nEvents[i][runId], ((size_t)n+ALLOC_LEN)*sizeof(int));
2947 }
2948 if (sumtParams.nBSets > 0)
2949 {
2950 for (i=0; i<sumtParams.nBSets; i++)
2951 {
2952 r->bRate[i][runId] = (MrBFlt *) SafeRealloc ((void *)r->bRate[i][runId], ((size_t)n+ALLOC_LEN)*sizeof(MrBFlt));
2953 r->bLen [i][runId] = (MrBFlt *) SafeRealloc ((void *)r->bLen [i][runId], ((size_t)n+ALLOC_LEN)*sizeof(MrBFlt));
2954 }
2955 }
2956 if (sumtParams.popSizeSet == YES)
2957 r->popSize[runId] = (MrBFlt *) SafeRealloc ((void *)r->popSize[runId], ((size_t)n+ALLOC_LEN)*sizeof(MrBFlt));
2958 }
2959 /* record values */
2960 r->count[runId]++;
2961 r->totCount++;
2962 if (sumtParams.brlensDef == YES)
2963 r->length[runId][n]= p->length;
2964 if (sumtParams.isClock == YES)
2965 r->height[runId][n]= p->depth;
2966 if (sumtParams.isCalibrated == YES)
2967 r->age[runId][n]= p->age;
2968 if (sumtParams.nESets > 0)
2969 {
2970 for (i=0; i<sumtParams.nESets; i++)
2971 r->nEvents[i][runId][n] = t->nEvents[i][p->index];
2972 }
2973 if (sumtParams.nBSets > 0)
2974 {
2975 for (i=0; i<sumtParams.nBSets; i++)
2976 {
2977 r->bLen [i][runId][n] = t->effectiveBrLen[i][p->index];
2978 r->bRate[i][runId][n] = t->effectiveBrLen[i][p->index] / p->length;
2979 if (p->length == 0.0) r->bRate[i][runId][n] = 1.0; // deal with zero brl
2980 }
2981 }
2982 if (sumtParams.popSizeSet == YES)
2983 r->popSize[runId][n] = t->popSize[p->index];
2984 }
2985 else if (comp < 0) /* greater than -> into left subtree */
2986 {
2987 if ((r->left = AddSumtPartition (r->left, t, p, runId)) == NULL)
2988 {
2989 FreePartCtr (r);
2990 return NULL;
2991 }
2992 }
2993 else
2994 {
2995 /* smaller than -> into right subtree */
2996 if ((r->right = AddSumtPartition (r->right, t, p, runId)) == NULL)
2997 {
2998 FreePartCtr (r);
2999 return NULL;
3000 }
3001 }
3002 }
3003
3004 return r;
3005 }
3006
3007
AddSumtTree(TreeCtr * r,int * order)3008 TreeCtr *AddSumtTree (TreeCtr *r, int *order)
3009 {
3010 int i, comp;
3011
3012 if (r == NULL)
3013 {
3014 /* new tree */
3015 /* create a new node */
3016 r = AllocTreeCtr();
3017 if (!r)
3018 return NULL;
3019 numUniqueTreesFound++;
3020 for (i=0; i<sumtParams.orderLen; i++)
3021 r->order[i] = order[i];
3022 r->count = 1;
3023 }
3024 else
3025 {
3026 for (i=0; i<sumtParams.orderLen; i++)
3027 if (r->order[i] != order[i])
3028 break;
3029
3030 if (i==sumtParams.orderLen)
3031 comp = 0;
3032 else if (order[i] < r->order[i])
3033 comp = 1;
3034 else
3035 comp = -1;
3036
3037 if (comp == 0) /* repeated partition */
3038 r->count++;
3039 else if (comp < 0) /* greater than -> into left subtree */
3040 {
3041 if ((r->left = AddSumtTree (r->left, order)) == NULL)
3042 {
3043 FreeTreeCtr (r);
3044 return NULL;
3045 }
3046 }
3047 else
3048 {
3049 /* smaller than -> into right subtree */
3050 if ((r->right = AddSumtTree (r->right, order)) == NULL)
3051 {
3052 FreeTreeCtr (r);
3053 return NULL;
3054 }
3055 }
3056 }
3057
3058 return r;
3059 }
3060
3061
3062 /* AllocPartCtr: Allocate space for one partition counter node using info in sumtParams */
AllocPartCtr()3063 PartCtr *AllocPartCtr ()
3064 {
3065 int i, j;
3066 PartCtr *r;
3067
3068 /* allocate basic stuff */
3069 r = (PartCtr *) SafeCalloc (1, sizeof(PartCtr));
3070 r->left = r->right = NULL;
3071 r->partition = (BitsLong *) SafeCalloc ((size_t)(sumtParams.BitsLongsNeeded), sizeof(BitsLong));
3072 r->count = (int *) SafeCalloc ((size_t)(sumtParams.numRuns), sizeof (int));
3073 if (sumtParams.brlensDef)
3074 {
3075 r->length = (MrBFlt **) SafeCalloc ((size_t)(sumtParams.numRuns), sizeof (MrBFlt *));
3076 for (i=0; i<sumtParams.numRuns; i++)
3077 r->length[i] = (MrBFlt *) SafeCalloc ((size_t)ALLOC_LEN, sizeof(MrBFlt));
3078 }
3079 if (sumtParams.isClock)
3080 {
3081 r->height = (MrBFlt **) SafeCalloc ((size_t)(sumtParams.numRuns), sizeof (MrBFlt *));
3082 for (i=0; i<sumtParams.numRuns; i++)
3083 r->height[i] = (MrBFlt *) SafeCalloc ((size_t)ALLOC_LEN, sizeof(MrBFlt));
3084 r->age = (MrBFlt **) SafeCalloc ((size_t)(sumtParams.numRuns), sizeof (MrBFlt *));
3085 for (i=0; i<sumtParams.numRuns; i++)
3086 r->age[i] = (MrBFlt *) SafeCalloc ((size_t)ALLOC_LEN, sizeof(MrBFlt));
3087 }
3088
3089 /* allocate relaxed clock parameters: eRate, nEvents, bRate */
3090 if (sumtParams.nESets > 0)
3091 r->nEvents = (int ***) SafeCalloc ((size_t)(sumtParams.nESets), sizeof(int **));
3092 for (i=0; i<sumtParams.nESets; i++)
3093 {
3094 r->nEvents[i] = (int **) SafeCalloc ((size_t)(sumtParams.numRuns), sizeof(int *));
3095 for (j=0; j<sumtParams.numRuns; j++)
3096 r->nEvents[i][j] = (int *) SafeCalloc ((size_t) ALLOC_LEN, sizeof(int));
3097 }
3098 if (sumtParams.nBSets > 0)
3099 {
3100 r->bLen = (MrBFlt ***) SafeCalloc ((size_t)(sumtParams.nBSets), sizeof(MrBFlt **));
3101 r->bRate = (MrBFlt ***) SafeCalloc ((size_t)(sumtParams.nBSets), sizeof(MrBFlt **));
3102 }
3103 for (i=0; i<sumtParams.nBSets; i++)
3104 {
3105 r->bLen[i] = (MrBFlt **) SafeCalloc ((size_t)(sumtParams.numRuns), sizeof(MrBFlt *));
3106 r->bRate[i] = (MrBFlt **) SafeCalloc ((size_t)(sumtParams.numRuns), sizeof(MrBFlt *));
3107 for (j=0; j<sumtParams.numRuns; j++)
3108 {
3109 r->bLen[i][j] = (MrBFlt *) SafeCalloc ((size_t)ALLOC_LEN, sizeof(MrBFlt));
3110 r->bRate[i][j] = (MrBFlt *) SafeCalloc ((size_t)ALLOC_LEN, sizeof(MrBFlt));
3111 }
3112 }
3113 if (sumtParams.popSizeSet == YES)
3114 {
3115 r->popSize = (MrBFlt **) SafeCalloc ((size_t)(sumtParams.numRuns), sizeof (MrBFlt *));
3116 for (i=0; i<sumtParams.numRuns; i++)
3117 r->popSize[i] = (MrBFlt *) SafeCalloc ((size_t)ALLOC_LEN, sizeof(MrBFlt));
3118 }
3119
3120 return r;
3121 }
3122
3123
3124 /* AllocTreeCtr: Allocate space for a tree counter node using info in sumtParams struct*/
AllocTreeCtr()3125 TreeCtr *AllocTreeCtr ()
3126 {
3127 TreeCtr *r;
3128
3129 r = (TreeCtr *) SafeCalloc (1, sizeof(TreeCtr));
3130
3131 r->left = r->right = NULL;
3132
3133 r->order = (int *) SafeCalloc ((size_t)(sumtParams.orderLen), sizeof(int));
3134
3135 return r;
3136 }
3137
3138
CalculateTreeToTreeDistance(Tree * tree1,Tree * tree2,MrBFlt * d1,MrBFlt * d2,MrBFlt * d3)3139 void CalculateTreeToTreeDistance (Tree *tree1, Tree *tree2, MrBFlt *d1, MrBFlt *d2, MrBFlt *d3)
3140 {
3141 int i, j, k;
3142 MrBFlt treeLen1=0.0, treeLen2=0.0;
3143 TreeNode *p, *q=NULL;
3144
3145 (*d1) = (*d2) = (*d3) = 0.0;
3146
3147 /* set distance-based measures to max value */
3148 if (sumtParams.brlensDef == YES)
3149 {
3150 treeLen1 = TreeLen(tree1);
3151 treeLen2 = TreeLen(tree2);
3152 (*d2) = treeLen1 + treeLen2;
3153 (*d3) = 2.0;
3154 }
3155
3156 /* now we can get distances in a single pass */
3157 for (i=0; i<tree1->nNodes; i++)
3158 {
3159 p = tree1->allDownPass[i];
3160 for (j=0; j<tree2->nNodes; j++)
3161 {
3162 q = tree2->allDownPass[j];
3163 for (k=0; k<sumtParams.BitsLongsNeeded; k++)
3164 if (p->partition[k] != q->partition[k])
3165 break;
3166 if (k == sumtParams.BitsLongsNeeded)
3167 break;
3168 }
3169 if (j < tree2->nNodes)
3170 {
3171 /* match */
3172 if (sumtParams.brlensDef == YES)
3173 {
3174 (*d2) -= (p->length + q->length - fabs(p->length - q->length));
3175 (*d3) -= (p->length/treeLen1 + q->length/treeLen2 - fabs(p->length/treeLen1 - q->length/treeLen2));
3176 }
3177 }
3178 else /* if (k < sumtParams.BitsLongsNeeded) */
3179 {
3180 /* no match */
3181 (*d1) += 2.0;
3182 }
3183 }
3184
3185 # if 0
3186 printf ("DISTANCES: %lf %lf %lf (%lf %lf)\n", *d1, *d2, *d3, tl1, tl2);
3187 for (i=0; i<nnds; i++)
3188 {
3189 printf ("%4d -- %4d (%lf) %4d (%lf)\n", i, list1[i], lengths1[i], list2[i], lengths2[i]);
3190 }
3191 # endif
3192 }
3193
3194
3195 /* ConTree: Construct consensus tree FIXME: numTreeParts is not used*/
ConTree(PartCtr ** treeParts,int numTreeParts)3196 int ConTree (PartCtr **treeParts, int numTreeParts)
3197 {
3198 int i, j, targetNode, nBits, isCompat, numTerminalsEncountered;
3199 BitsLong x, *partition = NULL, bitsLongOne;
3200 MrBFlt freq, freqInterapted=0;
3201 PolyTree *t, *t2=NULL;
3202 PolyNode *p, *q, *r, *ql, *pl;
3203 PartCtr *part;
3204 Stat theStats;
3205 int isFirstLoop=1, isInterapted=0;
3206
3207 /* we use a BitsLong variable set to one to escape dependence on interpretation of constant (signed?) int/long '1L' */
3208 bitsLongOne = 1;
3209
3210 /* check that we have at least three species */
3211 if (sumtParams.numTaxa < 3)
3212 {
3213 MrBayesPrint ("%s Too few taxa included to show consensus trees\n", spacer);
3214 return ERROR;
3215 }
3216
3217 treeConstruction:
3218 /* now, make a consensus tree */
3219 /* first allocate and initialize consensus tree */
3220 t = AllocatePolyTree(sumtParams.numTaxa);
3221 if (!t)
3222 {
3223 MrBayesPrint ("%s Could not allocate consensus tree\n", spacer);
3224 return(ERROR);
3225 }
3226 t->isRooted = sumtParams.isRooted;
3227 t->isClock = sumtParams.isClock;
3228 t->isRelaxed = sumtParams.isRelaxed;
3229
3230 /* initialize consensus tree nodes */
3231 for (i=0; i<sumtParams.numTaxa; i++)
3232 {
3233 t->nodes[i].left = NULL;
3234 t->nodes[i].sib = NULL;
3235 t->nodes[i].index = i;
3236 t->nodes[i].partitionIndex = -1; /* partition ID */
3237 t->nodes[i].age = 0.0; /* temporally set to minimum value to allow any insertion in front of the terminal before actual
3238 values of age and depth are available */
3239 strcpy(t->nodes[i].label, sumtParams.taxaNames[i]);
3240 t->nodes[i].depth = 0.0;
3241 }
3242 for (; i<t->memNodes; i++)
3243 {
3244 t->nodes[i].left = NULL;
3245 t->nodes[i].sib = NULL;
3246 t->nodes[i].index = i;
3247 t->nodes[i].partitionIndex = -1; /* partition ID */
3248 strcpy (t->nodes[i].label, "");
3249 }
3250
3251 /* create bush
3252 ->x counts number of subtended terminals
3253 make sure t->root->left is in outgroup */
3254 p = t->root = &t->nodes[sumtParams.numTaxa];
3255 p->anc = p->sib = NULL;
3256 p->x = sumtParams.numTaxa;
3257 p->age = MRBFLT_MAX; /* temporarily set to maximum value to allow any insertion in front of the root before actual values of age and depth are available */
3258 p->depth = MRBFLT_MAX;
3259 j = localOutGroup;
3260 q = &t->nodes[j];
3261 p->left = q;
3262 q->anc = p;
3263 q->x = 1;
3264 for (i=0; i<sumtParams.numTaxa; i++)
3265 {
3266 if (i != j)
3267 {
3268 q->sib = &t->nodes[i];
3269 q = q->sib;
3270 q->anc = p;
3271 q->x = 1;
3272 }
3273 }
3274 q->sib = NULL;
3275
3276 /* Resolve bush according to partitions.
3277 Partitions may include incompatible ones.
3278 Partitions must be sorted from most frequent to least frequent
3279 for quit test to work when a 50% majority rule tree is requested
3280 and in general for consensus tree to be correct. */
3281 t->nNodes = sumtParams.numTaxa + 1;
3282 t->nIntNodes = 1;
3283 if (sumtParams.isRooted == YES)
3284 targetNode = 2 * sumtParams.numTaxa - 2;
3285 else
3286 targetNode = 2 * sumtParams.numTaxa - 3;
3287
3288 numTerminalsEncountered = 0;
3289 for (i=0; i<numUniqueSplitsFound; i++)
3290 {
3291 /* get partition */
3292 part = treeParts[i];
3293
3294 /* calculate frequency and test if time to quit */
3295 if (t->nNodes > targetNode && numTerminalsEncountered == sumtParams.numTaxa)
3296 break;
3297 freq = (MrBFlt)(part->totCount) / (MrBFlt)(sumtParams.numTreesSampled);
3298 if (freq < 0.50 && !strcmp(sumtParams.sumtConType, "Halfcompat"))
3299 break;
3300
3301 /* get partition */
3302 partition = part->partition;
3303
3304 /* count bits in this partition */
3305 for (j=nBits=0; j<sumtParams.BitsLongsNeeded; j++)
3306 {
3307 for (x = partition[j]; x != 0; x &= (x - 1))
3308 nBits++;
3309 }
3310
3311 /* find out if this is an informative partition */
3312 if (nBits == sumtParams.numTaxa || nBits == 0)
3313 {
3314 /* this is the root (for setting age of root node when tree is dated) */
3315 q = t->root;
3316 q->partitionIndex = i;
3317 if (sumtParams.isClock == YES)
3318 {
3319 GetSummary(part->height, sumtParams.numRuns, part->count, &theStats, sumtParams.HPD);
3320 q->depth = theStats.median;
3321 for (p = q->left; p!=NULL; p = p->sib)
3322 {
3323 if (q->depth <= p->depth)
3324 break;
3325 }
3326 assert (p==NULL); /* Root always has 100% freq and it should be older than any other node that has 100% freq. */
3327 }
3328 if (sumtParams.isCalibrated == YES)
3329 {
3330 GetSummary(part->age, sumtParams.numRuns, part->count, &theStats, sumtParams.HPD);
3331 q->age = theStats.median;
3332 for (p = q->left; p!=NULL; p = p->sib)
3333 {
3334 if (q->age <= p->age)
3335 break;
3336 }
3337 assert (p==NULL); /* Root always has 100% freq and it should be older than any other node that has 100% freq. */
3338 }
3339 }
3340 else if (nBits > 1 && !(nBits == sumtParams.numTaxa - 1 && sumtParams.isRooted == NO))
3341 {
3342 /* this is an informative partition */
3343 /* find anc of partition */
3344 j = FirstTaxonInPartition (partition, sumtParams.BitsLongsNeeded);
3345 for (p = &t->nodes[j]; p!=NULL; p = p->anc)
3346 if (p->x > nBits)
3347 break;
3348
3349 /* do not include if incompatible with ancestor or any of descendants
3350 do not check terminals or root because it is
3351 redundant and partitions have not necessarily been set for those */
3352 isCompat = YES;
3353 if (p->anc != NULL && IsPartNested(partition, p->partition, sumtParams.BitsLongsNeeded)==NO)
3354 isCompat = NO;
3355 else
3356 {
3357 for (q=p->left; q!=NULL; q=q->sib)
3358 {
3359 if (q->x > 1 && IsPartCompatible(q->partition, partition, sumtParams.BitsLongsNeeded)==NO)
3360 break;
3361 }
3362 if (q!=NULL)
3363 isCompat = NO;
3364 }
3365
3366 if (isCompat == NO)
3367 continue;
3368
3369 /* set new node */
3370 q = &t->nodes[t->nNodes];
3371 q->partitionIndex = i;
3372 q->x = nBits;
3373 q->partition = partition;
3374 GetSummary(part->length, sumtParams.numRuns, part->count, &theStats, sumtParams.HPD);
3375 q->support = freq;
3376 q->length = theStats.median;
3377 r=NULL;
3378 if (sumtParams.isClock == YES)
3379 {
3380 GetSummary(part->height, sumtParams.numRuns, part->count, &theStats, sumtParams.HPD);
3381 q->depth = theStats.median;
3382 if (freq < 1.00)
3383 {
3384 for (r = p->left; r!=NULL; r = r->sib)
3385 {
3386 if (IsPartNested(r->partition, partition, sumtParams.BitsLongsNeeded) && r->depth >= q->depth)
3387 break; /* child is older then the node we try to add. Not good.*/
3388 }
3389 if (p->depth <= q->depth)
3390 { /* New node older than the parent. Not good.*/
3391 r = p; /* Just to make r!=NULL*/
3392 }
3393 }
3394 }
3395 if (sumtParams.isCalibrated == YES)
3396 {
3397 GetSummary(part->age, sumtParams.numRuns, part->count, &theStats, sumtParams.HPD);
3398 q->age = theStats.median;
3399 if (freq < 1.00)
3400 {
3401 for (r = p->left; r!=NULL; r = r->sib)
3402 {
3403 if (freq < 1.00 && IsPartNested(r->partition, partition, sumtParams.BitsLongsNeeded) && r->age >= q->age)
3404 break; /* child is older then the node we try to add. Not good.*/
3405 }
3406 if (p->age <= q->age)
3407 { /* New node older than the parent. Not good.*/
3408 r = p; /* Just to make r!=NULL*/
3409 }
3410 }
3411 }
3412
3413 if (r!=NULL && isFirstLoop)
3414 {
3415 /* cancel the addition of the new node*/
3416 isInterapted =1;
3417 freqInterapted=freq;
3418 break; /* Finish creating the polytree */
3419 }
3420 t->nNodes++;
3421 t->nIntNodes++;
3422
3423 /* go through descendants of anc */
3424 ql = pl = NULL;
3425 for (r=p->left; r!=NULL; r=r ->sib)
3426 {
3427 /* test if r is in the new partition or not */
3428 if ((r->x > 1 && IsPartNested(r->partition, partition, sumtParams.BitsLongsNeeded)) || (r->x == 1 && (partition[r->index / nBitsInALong] & (bitsLongOne << (r->index % nBitsInALong))) != 0))
3429 {
3430 /* r is in the partition */
3431 if (ql == NULL)
3432 q->left = r;
3433 else
3434 ql->sib = r;
3435 ql = r;
3436 r->anc = q;
3437 }
3438 else
3439 {
3440 /* r is not in the partition */
3441 if (pl == NULL)
3442 p->left = r;
3443 else
3444 pl->sib = r;
3445 pl = r;
3446 }
3447 }
3448 /* terminate new sib-node chain */
3449 ql->sib = NULL;
3450 /* new node is last in old sib-node chain */
3451 pl->sib = q;
3452 q->sib = NULL;
3453 q->anc = p;
3454 }
3455 else
3456 /* singleton partition */
3457 {
3458 if (nBits == sumtParams.numTaxa - 1)
3459 j = localOutGroup;
3460 else
3461 j = FirstTaxonInPartition(partition, sumtParams.BitsLongsNeeded); /* nbits == 1 */
3462 q = &t->nodes[j];
3463 q->partitionIndex = i;
3464 q->partition = partition;
3465 numTerminalsEncountered++;
3466 GetSummary(part->length, sumtParams.numRuns, part->count, &theStats, sumtParams.HPD);
3467 q->length = theStats.median;
3468 if (sumtParams.isClock == YES)
3469 {
3470 GetSummary(part->height, sumtParams.numRuns, part->count, &theStats, sumtParams.HPD);
3471 q->depth = theStats.median;
3472 if (q->anc->depth < q->depth)
3473 {
3474 /* We never should get here because terminals always have 100% freq and they are younger than any other node that has 100% freq. */
3475 /* We should be careful with the trees with 0-brl generated under the fossilized birth-death prior! (<= is changed to <) */
3476 assert (0);
3477 }
3478 }
3479 if (sumtParams.isCalibrated == YES)
3480 {
3481 GetSummary(part->age, sumtParams.numRuns, part->count, &theStats, sumtParams.HPD);
3482 q->age = theStats.median;
3483 if (q->anc->age < q->age)
3484 {
3485 /* We never should get here because terminals always have 100% freq and they are younger than any other node that has 100% freq. */
3486 /* We should be careful with the trees with 0-brl generated under the fossilized birth-death prior! (<= is changed to <) */
3487 assert (0);
3488 }
3489 }
3490 }
3491 }
3492
3493 if (isFirstLoop)
3494 {
3495 t2 = t;
3496 if (isInterapted)
3497 {
3498 isFirstLoop = 0;
3499 goto treeConstruction;
3500 }
3501 }
3502
3503 /* get downpass arrays */
3504 GetPolyDownPass(t);
3505
3506 /* order tips */
3507 if (sumtParams.orderTaxa == YES)
3508 OrderTips (t);
3509
3510 if (t!=t2)
3511 {
3512 /* get downpass arrays */
3513 GetPolyDownPass(t2);
3514
3515 /* order tips */
3516 if (sumtParams.orderTaxa == YES)
3517 OrderTips (t2);
3518 }
3519
3520 /* draw tree to stdout and fp */
3521 MrBayesPrint ("\n%s Clade credibility values:\n\n", spacer);
3522 ShowConTree (stdout, t, 80, YES);
3523 if (logToFile == YES)
3524 ShowConTree (logFileFp, t, 80, YES);
3525 if (sumtParams.brlensDef == YES)
3526 {
3527 MrBayesPrint ("\n");
3528 if (sumtParams.isClock == YES)
3529 MrBayesPrint ("%s Phylogram (based on median node depths):\n", spacer);
3530 else
3531 MrBayesPrint ("%s Phylogram (based on average branch lengths):\n", spacer);
3532 if (isInterapted)
3533 {
3534 MrBayesPrint ("%s Warning. Phylogram containing all nodes with credibility values exceeding\n",spacer);
3535 MrBayesPrint ("%s the level set by Contype could not be constructed.\n",spacer);
3536 MrBayesPrint ("%s Only nodes with credibility values exceeding %.2f%% (percentage of trees\n", spacer, freqInterapted*100);
3537 MrBayesPrint ("%s where the node is present) were included in the phylogram.\n", spacer);
3538 }
3539 MrBayesPrint ("\n");
3540 ShowConPhylogram (stdout, t2, 80);
3541 if (logToFile == YES)
3542 ShowConPhylogram (logFileFp, t2, 80);
3543 }
3544
3545 /* print taxa block */
3546 MrBayesPrintf (fpCon, "begin taxa;\n");
3547 MrBayesPrintf (fpCon, "\tdimensions ntax=%d;\n", sumtParams.numTaxa);
3548 MrBayesPrintf (fpCon, "\ttaxlabels\n", sumtParams.numTaxa);
3549 for (i=0; i<sumtParams.numTaxa; i++)
3550 {
3551 for (j=0; j<t2->nNodes; j++)
3552 if (t2->nodes[j].index == i)
3553 break;
3554 MrBayesPrintf (fpCon, "\t\t%s\n", t2->nodes[j].label);
3555 }
3556 MrBayesPrintf (fpCon, "\t\t;\nend;\n");
3557
3558 MrBayesPrintf (fpCon, "begin trees;\n");
3559 MrBayesPrintf (fpCon, "\ttranslate\n");
3560 for (i=0; i<sumtParams.numTaxa; i++)
3561 {
3562 for (j=0; j<t2->nNodes; j++)
3563 if (t2->nodes[j].index == i)
3564 break;
3565 if (i == sumtParams.numTaxa-1)
3566 MrBayesPrintf (fpCon, "\t\t%d\t%s\n", t2->nodes[i].index+1, t2->nodes[i].label);
3567 else
3568 MrBayesPrintf (fpCon, "\t\t%d\t%s,\n", t2->nodes[i].index+1, t2->nodes[i].label);
3569 }
3570 MrBayesPrintf (fpCon, "\t\t;\n");
3571 if (sumtParams.consensusFormat == SIMPLE)
3572 PrintConTree(fpCon, t2);
3573 else if (sumtParams.consensusFormat == FIGTREE)
3574 PrintFigTreeConTree(fpCon, t2, treeParts);
3575 MrBayesPrintf (fpCon, "end;\n");
3576
3577 if (t!=t2)
3578 {
3579 FreePolyTree (t2);
3580 }
3581 /* free memory */
3582 FreePolyTree (t);
3583
3584 return (NO_ERROR);
3585 }
3586
3587
CppEvolRate(PolyTree * t,PolyNode * p,int eSet)3588 MrBFlt CppEvolRate (PolyTree *t, PolyNode *p, int eSet)
3589 {
3590 int i, nEvents;
3591 MrBFlt ancRate, branchRate, *rate, *pos;
3592 PolyNode *q;
3593
3594 nEvents = t->nEvents[eSet][p->index];
3595 pos = t->position[eSet][p->index];
3596 rate = t->rateMult[eSet][p->index];
3597
3598 /* note that event positions are from top of branch (more recent, descendant tip) */
3599 ancRate = 1.0;
3600 // if (t->eType[eSet] == CPPm)
3601 // {
3602 for (q=p; q->anc != NULL; q=q->anc)
3603 {
3604 for (i=0; i<t->nEvents[eSet][p->index]; i++)
3605 ancRate *= t->rateMult[eSet][p->index][i];
3606 }
3607 if (nEvents > 0)
3608 {
3609 branchRate = rate[0] * pos[0];
3610 for (i=1; i<nEvents; i++)
3611 {
3612 branchRate += (pos[i] - pos[i-1]);
3613 branchRate *= rate[i];
3614 }
3615 branchRate += 1.0 - pos[nEvents-1];
3616 branchRate *= ancRate;
3617 }
3618 else
3619 branchRate = ancRate;
3620 // }
3621 /*
3622 else if (t->eType[eSet] == CPPi)
3623 {
3624 for (q=p; q->anc != NULL; q=q->anc)
3625 {
3626 if (t->nEvents[eSet][p->index]>0)
3627 {
3628 ancRate = t->rateMult[eSet][p->index][0];
3629 break;
3630 }
3631 }
3632 if (nEvents > 0)
3633 {
3634 branchRate = ancRate * (1.0 - pos[nEvents-1]);
3635 for (i=nEvents-2; i>=0; i--)
3636 {
3637 branchRate += (rate[i+1] * (pos[i+1] - pos[i]));
3638 }
3639 branchRate += (rate[0] * pos[0]);
3640 }
3641 else
3642 branchRate = ancRate;
3643 }
3644 */
3645
3646 return branchRate;
3647 }
3648
3649
DoCompareTree(void)3650 int DoCompareTree (void)
3651 {
3652 int i, j, k, n, longestLineLength, brlensDef[2], numTreesInLastBlock[2],
3653 lastTreeBlockBegin[2], lastTreeBlockEnd[2], xaxis, yaxis, starHolder[80],
3654 minNumTrees, screenWidth, screenHeigth, numY[60], nSamples;
3655 RandLong temporarySeed;
3656 BitsLong *mask;
3657 PartCtr *x;
3658 MrBFlt xProb, yProb, xInc, yInc, xUpper, xLower, yUpper, yLower, *dT1=NULL, *dT2=NULL, *dT3=NULL, d1, d2, d3,
3659 meanY[60], xVal, yVal, minX, minY, maxX, maxY, sums[3];
3660 char *s=NULL, prCh, treeName[2][100];
3661 FILE *fp;
3662 time_t curTime;
3663 PartCtr **treeParts=NULL;
3664 Tree *tree1=NULL, *tree2=NULL;
3665 SumtFileInfo sumtFileInfo;
3666
3667 # if defined (MPI_ENABLED)
3668 if (proc_id == 0)
3669 {
3670 # endif
3671
3672 /* Make sure we read trees using DoSumtTree() code instead of with the user tree code */
3673 inComparetreeCommand = YES;
3674
3675 /* set file pointer to NULL */
3676 fp = NULL;
3677
3678 strcpy(treeName[0],"tree"); //in case if parameter is not specified in a .t file
3679 strcpy(treeName[1],"tree");
3680
3681 /* Check that a data set has been read in. We check taxon names against
3682 those read in. */
3683 if (isTaxsetDef == NO)
3684 {
3685 MrBayesPrint ("%s A matrix or set of taxon labels must be specified before comparetree can be used\n", spacer);
3686 goto errorExit;
3687 }
3688
3689 /* open output files for summary information (two files); check if we want to overwrite previous results */
3690 if (OpenComptFiles () == ERROR)
3691 goto errorExit;
3692
3693 MrBayesPrint ("%s Examining files ...\n", spacer);
3694
3695 /* Examine first file */
3696 if (ExamineSumtFile(comptreeParams.comptFileName1, &sumtFileInfo, treeName[0], &(brlensDef[0])) == ERROR)
3697 return ERROR;
3698
3699 /* Capture info */
3700 longestLineLength = sumtFileInfo.longestLineLength;
3701 numTreesInLastBlock[0] = sumtFileInfo.numTreesInLastBlock;
3702 lastTreeBlockBegin[0] = sumtFileInfo.lastTreeBlockBegin;
3703 lastTreeBlockEnd[0] = sumtFileInfo.lastTreeBlockEnd;
3704
3705 /* Examine second file */
3706 if (ExamineSumtFile(comptreeParams.comptFileName2, &sumtFileInfo, treeName[1], &brlensDef[1]) == ERROR)
3707 return ERROR;
3708
3709 /* Capture info */
3710 if (longestLineLength < sumtFileInfo.longestLineLength)
3711 longestLineLength = sumtFileInfo.longestLineLength;
3712 numTreesInLastBlock[1] = sumtFileInfo.numTreesInLastBlock;
3713 lastTreeBlockBegin[1] = sumtFileInfo.lastTreeBlockBegin;
3714 lastTreeBlockEnd[1] = sumtFileInfo.lastTreeBlockEnd;
3715
3716 /* Check whether we should work with brlens */
3717 if (brlensDef[0] == YES && brlensDef[1] == YES)
3718 sumtParams.brlensDef = YES;
3719 else
3720 sumtParams.brlensDef = NO;
3721
3722 /* Allocate space for command string */
3723 longestLineLength += 10;
3724 s = (char *)SafeMalloc((size_t)longestLineLength * sizeof(char));
3725 if (!s)
3726 {
3727 MrBayesPrint ("%s Problem allocating string for reading tree file\n", spacer);
3728 goto errorExit;
3729 }
3730
3731 /* Allocate space for packed trees */
3732 if (chainParams.relativeBurnin == YES)
3733 {
3734 numPackedTrees[0] = numTreesInLastBlock[0] - (int)(chainParams.burninFraction * numTreesInLastBlock[0]);
3735 numPackedTrees[1] = numTreesInLastBlock[1] - (int)(chainParams.burninFraction * numTreesInLastBlock[1]);
3736 }
3737 else
3738 {
3739 numPackedTrees[0] = numTreesInLastBlock[0] - chainParams.chainBurnIn;
3740 numPackedTrees[1] = numTreesInLastBlock[1] - chainParams.chainBurnIn;
3741 }
3742 if (memAllocs[ALLOC_PACKEDTREES] == YES)
3743 {
3744 MrBayesPrint ("%s packedTreeList is already allocated\n", spacer);
3745 goto errorExit;
3746 }
3747 packedTreeList[0] = (PackedTree *) SafeCalloc(numPackedTrees[0]+numPackedTrees[1], sizeof(PackedTree));
3748 packedTreeList[1] = packedTreeList[0] + numPackedTrees[0];
3749 if (!packedTreeList[0])
3750 {
3751 MrBayesPrint ("%s Problem allocating packed tree list\n", spacer);
3752 goto errorExit;
3753 }
3754 memAllocs[ALLOC_PACKEDTREES] = YES;
3755
3756 /* Tell user we are ready to go */
3757 MrBayesPrint ("%s Summarizing trees in files \"%s\" and \"%s\"\n", spacer,
3758 comptreeParams.comptFileName1,
3759 comptreeParams.comptFileName2);
3760
3761 if (chainParams.relativeBurnin == YES)
3762 MrBayesPrint ("%s Using relative burnin ('relburnin=yes'), discarding the first %.0f %% ('burninfrac=%1.2f') of sampled trees\n",
3763 spacer, chainParams.burninFraction*100.0, chainParams.burninFraction);
3764 else
3765 MrBayesPrint ("%s Using absolute burnin ('relburnin=no'), discarding the first %d ('burnin=%d') sampled trees\n",
3766 spacer, chainParams.chainBurnIn, chainParams.chainBurnIn);
3767
3768 MrBayesPrint ("%s Writing statistics to file %s.<dists|pairs>\n", spacer, comptreeParams.comptOutfile);
3769
3770 /* Set up cheap status bar. */
3771 MrBayesPrint ("\n%s Tree reading status:\n\n", spacer);
3772 MrBayesPrint ("%s 0 10 20 30 40 50 60 70 80 90 100\n", spacer);
3773 MrBayesPrint ("%s v-------v-------v-------v-------v-------v-------v-------v-------v-------v-------v\n", spacer);
3774 MrBayesPrint ("%s *", spacer);
3775 numAsterices = 0;
3776
3777 /* Read file 1 for real */
3778 if ((fp = OpenTextFileR(comptreeParams.comptFileName1)) == NULL)
3779 goto errorExit;
3780
3781 /* ...and fast forward to beginning of last tree block (skipping begin trees). */
3782 for (i=0; i<lastTreeBlockBegin[0] + 1; i++)
3783 {
3784 if (fgets (s, longestLineLength, fp) == NULL)
3785 {
3786 printf ("Error in function: %s at line: %d in file: %s", __func__, __LINE__, __FILE__);
3787 }
3788 }
3789
3790 /* Calculate burnin */
3791 if (chainParams.relativeBurnin == YES)
3792 comptreeParams.burnin = (int)(chainParams.burninFraction * numTreesInLastBlock[0]);
3793 else
3794 comptreeParams.burnin = chainParams.chainBurnIn;
3795
3796 /* Initialize sumtParams struct */
3797 numUniqueSplitsFound = numUniqueTreesFound = 0;
3798 sumtParams.runId = 0;
3799 strcpy(sumtParams.curFileName, comptreeParams.comptFileName1);
3800 sumtParams.tree = AllocatePolyTree (numTaxa);
3801 AllocatePolyTreePartitions (sumtParams.tree);
3802 sumtParams.numTreesEncountered = sumtParams.numTreesSampled = 0;
3803 sumtParams.numFileTrees = (int *) SafeCalloc (2*2+2*numTaxa, sizeof(int));
3804 sumtParams.numFileTreesSampled = sumtParams.numFileTrees + sumtParams.numRuns;
3805 sumtParams.order = sumtParams.numFileTrees + 2*sumtParams.numRuns;
3806 sumtParams.absentTaxa = sumtParams.numFileTrees + 2*sumtParams.numRuns + numTaxa;
3807 sumtParams.numTreesInLastBlock = numTreesInLastBlock[0];
3808 if (!sumtParams.numFileTrees)
3809 {
3810 MrBayesPrint ("%s Problems allocating sumtParams.numFileTrees in DoSumt()\n", spacer);
3811 goto errorExit;
3812 }
3813 else
3814 memAllocs[ALLOC_SUMTPARAMS] = YES;
3815
3816 /* ... and parse the file */
3817 expecting = Expecting(COMMAND);
3818 inTreesBlock = YES;
3819 ResetTranslateTable();
3820 for (i=0; i<lastTreeBlockEnd[0] - lastTreeBlockBegin[0] - 1; i++)
3821 {
3822 if (fgets (s, longestLineLength, fp) == NULL)
3823 {
3824 printf ("Error in function: %s at line: %d in file: %s", __func__, __LINE__, __FILE__);
3825 }
3826 /*MrBayesPrint ("%s", s);*/
3827 if (ParseCommand (s) == ERROR)
3828 goto errorExit;
3829 }
3830 inTreesBlock = NO;
3831 ResetTranslateTable();
3832
3833 /* Check that at least one tree was read in. */
3834 if (sumtParams.numFileTreesSampled[0] <= 0)
3835 {
3836 MrBayesPrint ("%s No trees read in\n", spacer);
3837 goto errorExit;
3838 }
3839
3840 /* ... and close file */
3841 SafeFclose (&fp);
3842
3843 /* Read file 2 for real */
3844 if ((fp = OpenTextFileR(comptreeParams.comptFileName2)) == NULL)
3845 goto errorExit;
3846
3847 /* ...and fast forward to beginning of last tree block. */
3848 for (i=0; i<lastTreeBlockBegin[1] + 1; i++)
3849 {
3850 if (fgets (s, longestLineLength, fp) == NULL)
3851 {
3852 printf ("Error in function: %s at line: %d in file: %s", __func__, __LINE__, __FILE__);
3853 }
3854 }
3855
3856 /* Renitialize sumtParams struct */
3857 sumtParams.runId = 1;
3858 strcpy (sumtParams.curFileName, comptreeParams.comptFileName2);
3859
3860 /* Calculate burnin */
3861 if (chainParams.relativeBurnin == YES)
3862 comptreeParams.burnin = (int)(chainParams.burninFraction * numTreesInLastBlock[1]);
3863 else
3864 comptreeParams.burnin = chainParams.chainBurnIn;
3865
3866 /* ... and parse the file */
3867 expecting = Expecting(COMMAND);
3868 inTreesBlock = YES;
3869 ResetTranslateTable();
3870 for (i=0; i<lastTreeBlockEnd[1] - lastTreeBlockBegin[1] - 1; i++)
3871 {
3872 if (fgets (s, longestLineLength, fp) == NULL)
3873 {
3874 printf ("Error in function: %s at line: %d in file: %s", __func__, __LINE__, __FILE__);
3875 }
3876 /*MrBayesPrint ("%s", s);*/
3877 if (ParseCommand (s) == ERROR)
3878 goto errorExit;
3879 }
3880 inTreesBlock = NO;
3881 ResetTranslateTable();
3882
3883 /* Check that at least one tree was read in. */
3884 if (sumtParams.numFileTreesSampled[1] <= 0)
3885 {
3886 MrBayesPrint ("%s No trees read in\n", spacer);
3887 goto errorExit;
3888 }
3889
3890 /* ... and close file */
3891 SafeFclose (&fp);
3892
3893 /* Now finish cheap status bar. */
3894 if (numAsterices < 80)
3895 for (i=0; i<80 - numAsterices; i++)
3896 MrBayesPrint ("*");
3897 MrBayesPrint ("\n\n");
3898
3899 /* tell user how many trees were successfully read */
3900 MrBayesPrint ("%s Read %d trees from last tree block of file \"%s\" (sampling %d of them)\n", spacer,
3901 sumtParams.numFileTrees[0],
3902 comptreeParams.comptFileName1,
3903 sumtParams.numFileTreesSampled[0]);
3904 MrBayesPrint ("%s Read %d trees from last tree block of file \"%s\" (sampling %d of them)\n", spacer,
3905 sumtParams.numFileTrees[1],
3906 comptreeParams.comptFileName2,
3907 sumtParams.numFileTreesSampled[1]);
3908
3909 /* Extract partition counter pointers */
3910 treeParts = (PartCtr **) SafeCalloc ((size_t)(numUniqueSplitsFound), sizeof(PartCtr *));
3911 i = 0;
3912 PartCtrUppass(partCtrRoot, treeParts, &i);
3913
3914 /* Sort taxon partitions (clades, splits) ... */
3915 SortPartCtr (treeParts, 0, numUniqueSplitsFound-1);
3916
3917 /* print to screen */
3918 MrBayesPrint (" \n");
3919 MrBayesPrint ("%s General explanation: \n", spacer);
3920 MrBayesPrint (" \n");
3921 MrBayesPrint ("%s In an unrooted tree, a taxon bipartition (split) is specified by removing a \n", spacer);
3922 MrBayesPrint ("%s branch, thereby dividing the species into those to the left and those to the \n", spacer);
3923 MrBayesPrint ("%s right of the branch. Here, taxa to one side of the removed branch are denoted \n", spacer);
3924 MrBayesPrint ("%s '.' and those to the other side are denoted '*'. Specifically, the '.' symbol \n", spacer);
3925 MrBayesPrint ("%s is used for the taxa on the same side as the outgroup. \n", spacer);
3926 MrBayesPrint (" \n");
3927 MrBayesPrint ("%s In a rooted or clock tree, the '*' symbol is simply used to denote the taxa \n", spacer);
3928 MrBayesPrint ("%s that are included in a particular group (clade), that is, all the descendants \n", spacer);
3929 MrBayesPrint ("%s of a particular branch in the tree. Taxa that are not included are denoted \n", spacer);
3930 MrBayesPrint ("%s using the '.' symbol. \n", spacer);
3931 MrBayesPrint (" \n");
3932 MrBayesPrint ("%s The output includes the ID of the encountered clades or splits (sorted from \n", spacer);
3933 MrBayesPrint ("%s highest to lowest probability), the bipartition or clade in '.*' format, \n", spacer);
3934 MrBayesPrint ("%s number of times the bipartition or clade was observed in the first tree file \n", spacer);
3935 MrBayesPrint ("%s served in the first tree file, the number of times the bipartition was, \n", spacer);
3936 MrBayesPrint ("%s observed in the second tree file, the proportion of the time the bipartition \n", spacer);
3937 MrBayesPrint ("%s was found in the first tree file, and the proportion of the time the bi- \n", spacer);
3938 MrBayesPrint ("%s partition was found in the second tree file. \n", spacer);
3939 MrBayesPrint (" \n");
3940 MrBayesPrint ("%s List of taxa in bipartitions: \n", spacer);
3941 MrBayesPrint (" \n");
3942 j = 1;
3943 for (k=0; k<numTaxa; k++)
3944 {
3945 if (sumtParams.absentTaxa[k] == NO && taxaInfo[k].isDeleted == NO)
3946 {
3947 MrBayesPrint ("%s %4d -- %s\n", spacer, j++, taxaNames[k]);
3948 }
3949 }
3950 MrBayesPrint (" \n");
3951 MrBayesPrint ("%s List of taxon bipartitions found in tree files: \n\n", spacer);
3952
3953 i = (int)(log10(sumtParams.numTreesSampled)) - 1;
3954 if (i<1)
3955 i = 1;
3956 j = sumtParams.numTaxa - 8;
3957 if (j < 1)
3958 j = 1;
3959 MrBayesPrint ("%s ID -- Partition%*c No1%*c No2%*c Freq1 Freq2\n",
3960 spacer, j, ' ', i, ' ', i, ' ');
3961
3962 mask = SafeCalloc (sumtParams.BitsLongsNeeded, sizeof(BitsLong));
3963 for (i=0; i<sumtParams.numTaxa; i++)
3964 SetBit (i, mask);
3965 for (i=0; i<numUniqueSplitsFound; i++)
3966 {
3967 x = treeParts[i];
3968 if (IsBitSet(localOutGroup, x->partition) == YES && sumtParams.isRooted == NO)
3969 FlipBits(x->partition, sumtParams.BitsLongsNeeded, mask);
3970 if ((MrBFlt)x->totCount/(MrBFlt)sumtParams.numTreesSampled >= comptreeParams.minPartFreq)
3971 {
3972 MrBayesPrint ("%s %4d -- ", spacer, i+1);
3973 ShowParts (stdout, x->partition, sumtParams.numTaxa);
3974
3975 j = (int)(log10(sumtParams.numTreesSampled)) + 1;
3976 if (j < 3)
3977 j = 3;
3978 MrBayesPrint (" %*d %*d %1.3lf %1.3lf\n",
3979 j, x->count[0], j, x->count[1],
3980 (MrBFlt)x->count[0]/(MrBFlt)sumtParams.numFileTreesSampled[0],
3981 (MrBFlt)x->count[1]/(MrBFlt)sumtParams.numFileTreesSampled[1]);
3982
3983 MrBayesPrintf (fpParts, "%d\t%d\t%d\t%1.3lf\t%1.3lf\n",
3984 i+1, x->count[0], x->count[1],
3985 (MrBFlt)x->count[0]/(MrBFlt)sumtParams.numFileTreesSampled[0],
3986 (MrBFlt)x->count[1]/(MrBFlt)sumtParams.numFileTreesSampled[1]);
3987 }
3988 }
3989 free (mask);
3990
3991 /* make a nifty graph plotting frequencies of clades found in the two tree files */
3992 MrBayesPrint (" \n");
3993 MrBayesPrint ("%s Bivariate plot of clade probabilities: \n", spacer);
3994 MrBayesPrint (" \n");
3995 MrBayesPrint ("%s This graph plots the probabilities of clades found in file 1 (the x-axis) \n", spacer);
3996 MrBayesPrint ("%s against the probabilities of the same clades found in file 2 (the y-axis). \n", spacer);
3997 MrBayesPrint (" \n");
3998 xInc = (MrBFlt) (1.0 / 80.0);
3999 yInc = (MrBFlt) (1.0 / 40.0);
4000 yUpper = 1.0;
4001 yLower = yUpper - yInc;
4002 for (yaxis=39; yaxis>=0; yaxis--)
4003 {
4004 xLower = 0.0;
4005 xUpper = xLower + xInc;
4006 for (xaxis=0; xaxis<80; xaxis++)
4007 {
4008 starHolder[xaxis] = 0;
4009 for (i=0; i<numUniqueSplitsFound; i++)
4010 {
4011 x = treeParts[i];
4012 xProb = (MrBFlt)x->count[0]/(MrBFlt)sumtParams.numFileTreesSampled[0];
4013 yProb = (MrBFlt)x->count[1]/(MrBFlt)sumtParams.numFileTreesSampled[1];
4014 if ((xProb > xLower || (xProb == 0.0 && xaxis == 0)) && (xProb <= xUpper || (xProb == 1.0 && xaxis == 79))
4015 && (yProb > yLower || (yProb == 0.0 && yaxis == 0)) && (yProb <= yUpper || (yProb == 1.0 && yaxis == 39)))
4016 starHolder[xaxis] = 1;
4017 }
4018 xLower += xInc;
4019 xUpper = xLower + xInc;
4020 }
4021
4022 MrBayesPrint ("%s ", spacer);
4023 for (xaxis=0; xaxis<80; xaxis++)
4024 {
4025 prCh = ' ';
4026 if ((xaxis == 0 && yaxis == 0) || (xaxis == 79 && yaxis == 39))
4027 prCh = '+';
4028 else if ((xaxis == 0 && yaxis == 39) || (xaxis == 79 && yaxis == 0))
4029 prCh = '+';
4030 else if ((yaxis == 0 || yaxis == 39) && xaxis > 0 && xaxis < 79)
4031 prCh = '-';
4032 else if ((xaxis == 0 || xaxis == 79) && yaxis > 0 && yaxis < 39)
4033 prCh = '|';
4034 if (starHolder[xaxis] == 1)
4035 prCh = '*';
4036 MrBayesPrint ("%c", prCh);
4037 }
4038 if (yaxis == 39)
4039 MrBayesPrint (" 1.00\n");
4040 else if (yaxis == 0)
4041 MrBayesPrint (" 0.00\n");
4042 else
4043 MrBayesPrint ("\n");
4044
4045 yUpper -= yInc;
4046 yLower = yUpper - yInc;
4047 }
4048
4049 MrBayesPrint ("%s ^ ^\n", spacer);
4050 MrBayesPrint ("%s 0.00 1.00\n", spacer);
4051
4052 /* get tree-to-tree distances: first allocate some space */
4053 minNumTrees = sumtParams.numFileTreesSampled[0];
4054 if (sumtParams.numFileTreesSampled[1] < minNumTrees)
4055 minNumTrees = sumtParams.numFileTreesSampled[1];
4056 dT1 = (MrBFlt *) SafeMalloc (3 * (size_t)minNumTrees * sizeof(MrBFlt));
4057 tree1 = AllocateFixedTree (sumtParams.numTaxa, sumtParams.isRooted);
4058 tree2 = AllocateFixedTree (sumtParams.numTaxa, sumtParams.isRooted);
4059 if (!dT1 || !tree1 || !tree2)
4060 {
4061 MrBayesPrint ("%s Problem allocating topological distances\n", spacer);
4062 goto errorExit;
4063 }
4064 dT2 = dT1 + minNumTrees;
4065 dT3 = dT2 + minNumTrees;
4066
4067 for (i=0; i<minNumTrees; i++)
4068 {
4069 if (sumtParams.isRooted == NO)
4070 {
4071 RetrieveUTree (tree1, packedTreeList[0][i].order, packedTreeList[0][i].brlens);
4072 RetrieveUTree (tree2, packedTreeList[1][i].order, packedTreeList[1][i].brlens);
4073 }
4074 else
4075 {
4076 RetrieveRTree (tree1, packedTreeList[0][i].order, packedTreeList[0][i].brlens);
4077 RetrieveRTree (tree2, packedTreeList[1][i].order, packedTreeList[1][i].brlens);
4078 }
4079 /* Allocate and set partitions now that we have a tree */
4080 if (i == 0)
4081 {
4082 AllocateTreePartitions(tree1);
4083 AllocateTreePartitions(tree2);
4084 }
4085 else
4086 {
4087 ResetTreePartitions(tree1);
4088 ResetTreePartitions(tree2);
4089 }
4090 CalculateTreeToTreeDistance (tree1, tree2, &d1, &d2, &d3);
4091 dT1[i] = d1;
4092 dT2[i] = d2;
4093 dT3[i] = d3;
4094 }
4095
4096 for (i=0; i<minNumTrees; i++)
4097 {
4098 /*MrBayesPrint ("%s %4d -- %lf %lf %lf\n", spacer, i+1, dT1[i], dT2[i], dT3[i]);*/
4099 if (sumtParams.brlensDef == YES)
4100 MrBayesPrintf (fpDists, "%d\t%lf\t%lf\t%lf\n", i+1, dT1[i], dT2[i], dT3[i]);
4101 else
4102 MrBayesPrintf (fpDists, "%d\t%lf\n", i+1, dT1[i]);
4103 }
4104
4105 /* print x-y plot of log likelihood vs. generation */
4106 MrBayesPrint ("\n");
4107 MrBayesPrint ("%s Rough plots of generation (x-axis) versus the measures of tree- \n", spacer);
4108 MrBayesPrint ("%s to-tree distances (y-axis). \n", spacer);
4109 MrBayesPrint ("\n");
4110 MrBayesPrint ("%s Distance(Robinson-Foulds):\n", spacer);
4111 MrBayesPrint ("\n");
4112 screenWidth = 60; /* don't change this without changing numY and meanY, declared above */
4113 screenHeigth = 15;
4114 minX = minY = 1000000000.0;
4115 maxX = maxY = -1000000000.0;
4116 for (i=0; i<minNumTrees; i++)
4117 {
4118 xVal = (MrBFlt) (i + comptreeParams.burnin);
4119 yVal = dT1[i];
4120 if (xVal < minX)
4121 minX = xVal;
4122 if (yVal < minY)
4123 minY = yVal;
4124 if (xVal > maxX)
4125 maxX = xVal;
4126 if (yVal > maxY)
4127 maxY = yVal;
4128 }
4129 for (i=0; i<screenWidth; i++)
4130 {
4131 numY[i] = 0;
4132 meanY[i] = 0.0;
4133 }
4134 for (i=0; i<minNumTrees; i++)
4135 {
4136 xVal = (MrBFlt) (i + comptreeParams.burnin);
4137 yVal = dT1[i];
4138 k = (int)(((xVal - minX) / (maxX - minX)) * screenWidth);
4139 if (k >= screenWidth)
4140 k = screenWidth - 1;
4141 meanY[k] += yVal;
4142 numY[k]++;
4143 }
4144 MrBayesPrint ("\n%s +", spacer);
4145 for (i=0; i<screenWidth; i++)
4146 MrBayesPrint ("-");
4147 MrBayesPrint ("+ %1.2lf\n", maxY);
4148 for (j=screenHeigth-1; j>=0; j--)
4149 {
4150 MrBayesPrint ("%s |", spacer);
4151 for (i=0; i<screenWidth; i++)
4152 {
4153 if (numY[i] > 0)
4154 {
4155 if (meanY[i] / numY[i] > (((maxY - minY)/screenHeigth)*j)+minY && meanY[i] / numY[i] <= (((maxY - minY)/screenHeigth)*(j+1))+minY)
4156 MrBayesPrint ("*");
4157 else
4158 MrBayesPrint (" ");
4159 }
4160 else
4161 {
4162 MrBayesPrint (" ");
4163 }
4164 }
4165 MrBayesPrint ("|\n");
4166 }
4167 MrBayesPrint ("%s +", spacer);
4168 for (i=0; i<screenWidth; i++)
4169 {
4170 if (numY[i] > 0 && meanY[i] / numY[i] <= minY)
4171 MrBayesPrint ("*");
4172 else if (i % (screenWidth/10) == 0 && i != 0)
4173 MrBayesPrint ("+");
4174 else
4175 MrBayesPrint ("-");
4176 }
4177 MrBayesPrint ("+ %1.2lf\n", minY);
4178 MrBayesPrint ("%s ^", spacer);
4179 for (i=0; i<screenWidth; i++)
4180 MrBayesPrint (" ");
4181 MrBayesPrint ("^\n");
4182 MrBayesPrint ("%s %1.0lf", spacer, minX);
4183 for (i=0; i<screenWidth; i++)
4184 MrBayesPrint (" ");
4185 MrBayesPrint ("%1.0lf\n\n", maxX);
4186
4187 if (sumtParams.brlensDef == YES)
4188 {
4189 for (n=0; n<2; n++)
4190 {
4191 MrBayesPrint ("\n");
4192 if (n == 0)
4193 MrBayesPrint ("%s Distance(Robinson-Foulds with branch lengths):\n", spacer);
4194 else
4195 MrBayesPrint ("%s Distance(Robinson-Foulds with scaled branch lengths):\n", spacer);
4196 MrBayesPrint ("\n");
4197 screenWidth = 60; /* don't change this without changing numY and meanY, declared above */
4198 screenHeigth = 15;
4199 minX = minY = 1000000000.0;
4200 maxX = maxY = -1000000000.0;
4201 for (i=0; i<minNumTrees; i++)
4202 {
4203 xVal = (MrBFlt) (i + comptreeParams.burnin);
4204 if (n == 0)
4205 yVal = dT2[i];
4206 else
4207 yVal = dT3[i];
4208 if (xVal < minX)
4209 minX = xVal;
4210 if (yVal < minY)
4211 minY = yVal;
4212 if (xVal > maxX)
4213 maxX = xVal;
4214 if (yVal > maxY)
4215 maxY = yVal;
4216 }
4217 for (i=0; i<screenWidth; i++)
4218 {
4219 numY[i] = 0;
4220 meanY[i] = 0.0;
4221 }
4222 for (i=0; i<minNumTrees; i++)
4223 {
4224 xVal = (MrBFlt) (i + comptreeParams.burnin);
4225 if (n == 0)
4226 yVal = dT2[i];
4227 else
4228 yVal = dT3[i];
4229 k = (int)(((xVal - minX) / (maxX - minX)) * screenWidth);
4230 if (k >= screenWidth)
4231 k = screenWidth - 1;
4232 meanY[k] += yVal;
4233 numY[k]++;
4234 }
4235 MrBayesPrint ("\n%s +", spacer);
4236 for (i=0; i<screenWidth; i++)
4237 MrBayesPrint ("-");
4238 MrBayesPrint ("+ %1.2lf\n", maxY);
4239 for (j=screenHeigth-1; j>=0; j--)
4240 {
4241 MrBayesPrint ("%s |", spacer);
4242 for (i=0; i<screenWidth; i++)
4243 {
4244 if (numY[i] > 0)
4245 {
4246 if (meanY[i] / numY[i] > (((maxY - minY)/screenHeigth)*j)+minY && meanY[i] / numY[i] <= (((maxY - minY)/screenHeigth)*(j+1))+minY)
4247 MrBayesPrint ("*");
4248 else
4249 MrBayesPrint (" ");
4250 }
4251 else
4252 {
4253 MrBayesPrint (" ");
4254 }
4255 }
4256 MrBayesPrint ("|\n");
4257 }
4258 MrBayesPrint ("%s +", spacer);
4259 for (i=0; i<screenWidth; i++)
4260 {
4261 if (numY[i] > 0 && meanY[i] / numY[i] <= minY)
4262 MrBayesPrint ("*");
4263 else if (i % (screenWidth/10) == 0 && i != 0)
4264 MrBayesPrint ("+");
4265 else
4266 MrBayesPrint ("-");
4267 }
4268 MrBayesPrint ("+ %1.2lf\n", minY);
4269 MrBayesPrint ("%s ^", spacer);
4270 for (i=0; i<screenWidth; i++)
4271 MrBayesPrint (" ");
4272 MrBayesPrint ("^\n");
4273 MrBayesPrint ("%s %1.0lf", spacer, minX);
4274 for (i=0; i<screenWidth; i++)
4275 MrBayesPrint (" ");
4276 MrBayesPrint ("%1.0lf\n\n", maxX);
4277 }
4278 }
4279
4280 /* calculate average tree-to-tree distances */
4281 curTime = time(NULL);
4282 temporarySeed = (RandLong)curTime;
4283 if (temporarySeed < 0)
4284 temporarySeed = -temporarySeed;
4285 sums[0] = sums[1] = sums[2] = 0.0;
4286 nSamples = 1000;
4287 for (n=0; n<nSamples; n++)
4288 {
4289 i = (int) RandomNumber(&temporarySeed) * minNumTrees;
4290 j = (int) RandomNumber(&temporarySeed) * minNumTrees;
4291 if (sumtParams.isRooted == NO)
4292 {
4293 RetrieveUTree (tree1, packedTreeList[0][i].order, packedTreeList[0][i].brlens);
4294 RetrieveUTree (tree2, packedTreeList[1][j].order, packedTreeList[1][j].brlens);
4295 }
4296 else /* if (sumtParams.isRooted == YES) */
4297 {
4298 RetrieveRTree (tree1, packedTreeList[0][i].order, packedTreeList[0][i].brlens);
4299 RetrieveRTree (tree2, packedTreeList[1][j].order, packedTreeList[1][j].brlens);
4300 }
4301 CalculateTreeToTreeDistance (tree1, tree2, &d1, &d2, &d3);
4302 sums[0] += d1;
4303 sums[1] += d2;
4304 sums[2] += d3;
4305 }
4306 MrBayesPrint ("%s Mean tree-to-tree distances, based on %d trees randomly sampled from both files:\n\n", spacer, nSamples);
4307 MrBayesPrint ("%s Mean(Robinson-Foulds) = %1.3lf\n", spacer, sums[0]/nSamples);
4308 if (sumtParams.brlensDef == YES)
4309 {
4310 MrBayesPrint ("%s Mean(Robinson-Foulds with branch lengths) = %1.3lf\n", spacer, sums[1]/nSamples);
4311 MrBayesPrint ("%s Mean(Robinson-Foulds with scaled branch lengths) = %1.3lf\n", spacer, sums[2]/nSamples);
4312 }
4313 MrBayesPrint ("\n");
4314
4315 /* free memory and file pointers */
4316 free(s);
4317 free (dT1);
4318 FreeTree (tree1);
4319 FreeTree (tree2);
4320 if (memAllocs[ALLOC_PACKEDTREES] == YES)
4321 {
4322 for (i=0; i<numPackedTrees[0]+numPackedTrees[1]; i++)
4323 {
4324 free(packedTreeList[0][i].order);
4325 free(packedTreeList[0][i].brlens);
4326 }
4327 free(packedTreeList[0]);
4328 memAllocs[ALLOC_PACKEDTREES] = NO;
4329 }
4330
4331 /* free sumtParams */
4332 FreeSumtParams();
4333
4334 /* close files */
4335 SafeFclose (&fp);
4336 SafeFclose (&fpParts);
4337 SafeFclose (&fpDists);
4338
4339 /* free pointer array to partitions, part and tree counters */
4340 free (treeParts);
4341 FreePartCtr (partCtrRoot);
4342 FreeTreeCtr (treeCtrRoot);
4343 partCtrRoot = NULL;
4344 treeCtrRoot = NULL;
4345
4346 /* reset taxon set */
4347 ResetTaxonSet();
4348
4349 # if defined (MPI_ENABLED)
4350 }
4351 # endif
4352
4353 expecting = Expecting(COMMAND);
4354 inComparetreeCommand = NO;
4355 return (NO_ERROR);
4356
4357 /* error exit */
4358 errorExit:
4359 if (s) free(s);
4360
4361 /* free sumtParams */
4362 FreeSumtParams();
4363
4364 free (dT1);
4365 FreeTree (tree1);
4366 FreeTree (tree2);
4367 if (memAllocs[ALLOC_PACKEDTREES] == YES)
4368 {
4369 for (i=0; i<numPackedTrees[0]+numPackedTrees[1]; i++)
4370 {
4371 free(packedTreeList[0][i].order);
4372 free(packedTreeList[0][i].brlens);
4373 }
4374 free(packedTreeList[0]);
4375 memAllocs[ALLOC_PACKEDTREES] = NO;
4376 }
4377
4378 /* reset taxon set */
4379 ResetTaxonSet();
4380
4381 /* free pointer array to partitions, part and tree counters */
4382 free (treeParts);
4383 FreePartCtr (partCtrRoot);
4384 FreeTreeCtr (treeCtrRoot);
4385 partCtrRoot = NULL;
4386 treeCtrRoot = NULL;
4387
4388 SafeFclose (&fp);
4389 SafeFclose (&fpParts);
4390 SafeFclose (&fpDists);
4391 strcpy (spacer, "");
4392
4393 expecting = Expecting(COMMAND);
4394 inComparetreeCommand = NO;
4395
4396 return (ERROR);
4397 }
4398
4399
DoCompareTreeParm(char * parmName,char * tkn)4400 int DoCompareTreeParm (char *parmName, char *tkn)
4401 {
4402 int tempI;
4403 MrBFlt tempD;
4404 char tempStr[100];
4405
4406 if (expecting == Expecting(PARAMETER))
4407 {
4408 expecting = Expecting(EQUALSIGN);
4409 }
4410 else
4411 {
4412 if (!strcmp(parmName, "Xxxxxxxxxx"))
4413 {
4414 expecting = Expecting(PARAMETER);
4415 expecting |= Expecting(SEMICOLON);
4416 }
4417 /* set Filename (comptreeParams.comptFileName1) *************************************************/
4418 else if (!strcmp(parmName, "Filename1"))
4419 {
4420 if (expecting == Expecting(EQUALSIGN))
4421 {
4422 expecting = Expecting(ALPHA);
4423 readWord = YES;
4424 }
4425 else if (expecting == Expecting(ALPHA))
4426 {
4427 strcpy (comptreeParams.comptFileName1, tkn);
4428 MrBayesPrint ("%s Setting comparetree filename 1 to %s\n", spacer, comptreeParams.comptFileName1);
4429 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
4430 }
4431 else
4432 return (ERROR);
4433 }
4434 /* set Filename (comptreeParams.comptFileName2) *************************************************/
4435 else if (!strcmp(parmName, "Filename2"))
4436 {
4437 if (expecting == Expecting(EQUALSIGN))
4438 {
4439 expecting = Expecting(ALPHA);
4440 readWord = YES;
4441 }
4442 else if (expecting == Expecting(ALPHA))
4443 {
4444 strcpy (comptreeParams.comptFileName2, tkn);
4445 MrBayesPrint ("%s Setting comparetree filename 2 to %s\n", spacer, comptreeParams.comptFileName2);
4446 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
4447 }
4448 else
4449 return (ERROR);
4450 }
4451 /* set Filename (comptreeParams.comptOutfile) ***************************************************/
4452 else if (!strcmp(parmName, "Outputname"))
4453 {
4454 if (expecting == Expecting(EQUALSIGN))
4455 {
4456 expecting = Expecting(ALPHA);
4457 readWord = YES;
4458 }
4459 else if (expecting == Expecting(ALPHA))
4460 {
4461 strcpy (comptreeParams.comptOutfile, tkn);
4462 MrBayesPrint ("%s Setting comparetree output file to %s\n", spacer, comptreeParams.comptOutfile);
4463 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
4464 }
4465 else
4466 return (ERROR);
4467 }
4468 /* set Relburnin (chainParams.relativeBurnin) ********************************************************/
4469 else if (!strcmp(parmName, "Relburnin"))
4470 {
4471 if (expecting == Expecting(EQUALSIGN))
4472 expecting = Expecting(ALPHA);
4473 else if (expecting == Expecting(ALPHA))
4474 {
4475 if (IsArgValid(tkn, tempStr) == NO_ERROR)
4476 {
4477 if (!strcmp(tempStr, "Yes"))
4478 chainParams.relativeBurnin = YES;
4479 else
4480 chainParams.relativeBurnin = NO;
4481 }
4482 else
4483 {
4484 MrBayesPrint ("%s Invalid argument for Relburnin\n", spacer);
4485 return (ERROR);
4486 }
4487 if (chainParams.relativeBurnin == YES)
4488 MrBayesPrint ("%s Using relative burnin (a fraction of samples discarded).\n", spacer);
4489 else
4490 MrBayesPrint ("%s Using absolute burnin (a fixed number of samples discarded).\n", spacer);
4491 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
4492 }
4493 else
4494 {
4495 //free (tempStr);
4496 return (ERROR);
4497 }
4498 }
4499 /* set Burnin (chainParams.chainBurnIn) *******************************************************/
4500 else if (!strcmp(parmName, "Burnin"))
4501 {
4502 if (expecting == Expecting(EQUALSIGN))
4503 expecting = Expecting(NUMBER);
4504 else if (expecting == Expecting(NUMBER))
4505 {
4506 sscanf (tkn, "%d", &tempI);
4507 chainParams.chainBurnIn = tempI;
4508 MrBayesPrint ("%s Setting burnin to %d\n", spacer, chainParams.chainBurnIn);
4509 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
4510 }
4511 else
4512 return (ERROR);
4513 }
4514 /* set Burninfrac (chainParams.burninFraction) ************************************************************/
4515 else if (!strcmp(parmName, "Burninfrac"))
4516 {
4517 if (expecting == Expecting(EQUALSIGN))
4518 expecting = Expecting(NUMBER);
4519 else if (expecting == Expecting(NUMBER))
4520 {
4521 sscanf (tkn, "%lf", &tempD);
4522 if (tempD < 0.01)
4523 {
4524 MrBayesPrint ("%s Burnin fraction too low (< 0.01)\n", spacer);
4525 return (ERROR);
4526 }
4527 if (tempD > 0.50)
4528 {
4529 MrBayesPrint ("%s Burnin fraction too high (> 0.50)\n", spacer);
4530 return (ERROR);
4531 }
4532 chainParams.burninFraction = tempD;
4533 MrBayesPrint ("%s Setting burnin fraction to %.2f\n", spacer, chainParams.burninFraction);
4534 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
4535 }
4536 else
4537 {
4538 return (ERROR);
4539 }
4540 }
4541 /* set Minpartfreq (comptreeParams.minPartFreq) *******************************************************/
4542 else if (!strcmp(parmName, "Minpartfreq"))
4543 {
4544 if (expecting == Expecting(EQUALSIGN))
4545 expecting = Expecting(NUMBER);
4546 else if (expecting == Expecting(NUMBER))
4547 {
4548 sscanf (tkn, "%lf", &tempD);
4549 comptreeParams.minPartFreq = tempD;
4550 MrBayesPrint ("%s Including partitions with probability greater than or equal to %lf in summary statistics\n", spacer, comptreeParams.minPartFreq);
4551 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
4552 }
4553 else
4554 return (ERROR);
4555 }
4556 else
4557 return (ERROR);
4558 }
4559
4560 return (NO_ERROR);
4561 }
4562
4563
DoCompRefTree(void)4564 int DoCompRefTree (void)
4565 {
4566 /* Compare a tree file with the reference tree files to generate the SDSFs.
4567 Use parameters in CompareTree and MCMCP (lazy option) */
4568
4569 char outName[130], inName[130], inRefName[130], treeName[100], *lineBuf=NULL, *s;
4570 FILE *fpTre=NULL, *fpOut=NULL;
4571 int i, n, longestL=0, burnin, gen, nRefRun, nTre[2]={0}, skip;
4572 SumtFileInfo tFileInfo;
4573 Tree *t;
4574
4575 # if defined (MPI_ENABLED)
4576 if (proc_id != 0)
4577 return NO_ERROR;
4578 # endif
4579
4580 /* Check that a data set has been read in. We check taxon names against those read in. */
4581 if (isTaxsetDef == NO)
4582 {
4583 MrBayesPrint ("%s A matrix or set of taxon labels must be specified before compareref can be used\n", spacer);
4584 return (ERROR);
4585 }
4586
4587 /* this is a hack to account for the comparing (0) and the reference (1) tree samples
4588 chainParams.numRuns is used in AddTreeToPartitionCounters to alloc mem correctly */
4589 nRefRun = chainParams.numRuns;
4590 chainParams.numRuns = 2;
4591
4592 /* initialize */
4593 if ((t = AllocateTree (numLocalTaxa)) == NULL)
4594 {
4595 MrBayesPrint ("%s Problem allocating diagn tree\n", spacer);
4596 goto errorExit;
4597 }
4598 if (SetUpPartitionCounters () == ERROR)
4599 goto errorExit;
4600 if ((chainParams.stat = (STATS *) SafeCalloc (numTopologies, sizeof (STATS))) == NULL)
4601 goto errorExit;
4602 else
4603 memAllocs[ALLOC_STATS] = YES;
4604
4605 /* deal with the reference tree files */
4606 // for (k=0; k<numTopologies; k++)
4607 for (n=0; n<nRefRun; n++)
4608 {
4609 if (nRefRun == 1)
4610 sprintf (inRefName, "%s.t", comptreeParams.comptFileName2);
4611 else
4612 sprintf (inRefName, "%s.run%d.t", comptreeParams.comptFileName2, n+1);
4613 MrBayesPrint ("%s Processing run %d in the reference trees\n", spacer, n+1);
4614
4615 /* Examine each ref tree file, save info to tFileInfo */
4616 if (ExamineSumtFile(inRefName, &tFileInfo, treeName, &sumtParams.brlensDef) == ERROR)
4617 goto errorExit;
4618 if (longestL < tFileInfo.longestLineLength)
4619 {
4620 longestL = tFileInfo.longestLineLength;
4621 lineBuf = (char *) SafeRealloc (lineBuf, (size_t)longestL * sizeof(char));
4622 if (!lineBuf)
4623 {
4624 MrBayesPrint ("%s Problem allocating string for reading tree file\n", spacer);
4625 goto errorExit;
4626 }
4627 }
4628
4629 /* calculate burnin */
4630 if (chainParams.relativeBurnin == YES)
4631 burnin = (int)(chainParams.burninFraction * tFileInfo.numTreesInLastBlock);
4632 else
4633 burnin = chainParams.chainBurnIn;
4634 if (burnin >= tFileInfo.numTreesInLastBlock)
4635 {
4636 MrBayesPrint ("%s Burnin should be smaller than the total number of trees\n", spacer);
4637 goto errorExit;
4638 }
4639
4640 /* open the ref tree file */
4641 if ((fpTre = OpenTextFileR (inRefName)) == NULL)
4642 goto errorExit;
4643 /* ...and fast forward to beginning in last tree block */
4644 for (i=0; i <= tFileInfo.lastTreeBlockBegin; i++)
4645 {
4646 if (fgets(lineBuf, longestL-2, fpTre) == NULL)
4647 goto errorExit;
4648 }
4649
4650 /* process each ref tree */
4651 for (i=0; i < tFileInfo.numTreesInLastBlock; i++)
4652 {
4653 do {
4654 if (fgets (lineBuf, longestL-2, fpTre) == NULL)
4655 goto errorExit;
4656 s = strtok (lineBuf, " ");
4657 }
4658 while (strcmp (s, "tree") != 0);
4659
4660 /* add reference trees to partition counters, discarding burnin */
4661 if (i < burnin) continue;
4662
4663 s = strtok (NULL, ";");
4664 while (*s != '(')
4665 s++;
4666 StripComments(s);
4667
4668 if (ResetTopology (t, s) == ERROR)
4669 goto errorExit;
4670 if (AddTreeToPartitionCounters (t, 0, 0) == ERROR)
4671 goto errorExit;
4672 nTre[0]++;
4673 }
4674 MrBayesPrint ("%s \t%d trees processed, %d trees discarded as burnin\n", spacer, tFileInfo.numTreesInLastBlock, burnin);
4675
4676 /* close the tree file */
4677 SafeFclose (&fpTre);
4678 }
4679 /* end reference tree files */
4680 MrBayesPrint ("%s \t%d reference trees in total from %d runs\n", spacer, nTre[0], nRefRun);
4681
4682 MrBayesPrint ("%s Processing the test run ...\n", spacer, n+1);
4683 /* open output file */
4684 strcpy (outName, comptreeParams.comptOutfile);
4685 strcat (outName, ".sdsf");
4686 if ((fpOut = OpenNewMBPrintFile (outName)) == NULL)
4687 goto errorExit;
4688 /* print stamp and header */
4689 if ((int)strlen(stamp) > 1)
4690 MrBayesPrintf (fpOut, "[ID: %s]\n", stamp);
4691 if (chainParams.diagnStat == AVGSTDDEV)
4692 MrBayesPrintf (fpOut, "Gen\tASDSF\n");
4693 else // MAXSTDDEV
4694 MrBayesPrintf (fpOut, "Gen\tMSDSF\n");
4695
4696 /* Examine the tree file to be compared, save info to tFileInfo */
4697 strcpy(inName, comptreeParams.comptFileName1);
4698 if (ExamineSumtFile(inName, &tFileInfo, treeName, &sumtParams.brlensDef) == ERROR)
4699 goto errorExit;
4700 if (longestL < tFileInfo.longestLineLength)
4701 {
4702 longestL = tFileInfo.longestLineLength;
4703 lineBuf = (char *) SafeRealloc (lineBuf, (size_t)longestL * sizeof(char));
4704 if (!lineBuf)
4705 {
4706 MrBayesPrint ("%s Problem allocating string for reading tree file\n", spacer);
4707 goto errorExit;
4708 }
4709 }
4710
4711 /* open the tree file to be compared */
4712 if ((fpTre = OpenTextFileR (inName)) == NULL)
4713 goto errorExit;
4714 /* ...and fast forward to beginning in last tree block */
4715 for (i=0; i <= tFileInfo.lastTreeBlockBegin; i++)
4716 {
4717 if (fgets(lineBuf, longestL-2, fpTre) == NULL)
4718 goto errorExit;
4719 }
4720
4721 /* process each tree to be compared and print SDSF to file */
4722 skip = 1; // skip the first few trees (default 1)
4723 // skip = (int) (0.5 * tFileInfo.numTreesInLastBlock);
4724 for (i=0; i < tFileInfo.numTreesInLastBlock; i++)
4725 {
4726 do {
4727 if (fgets (lineBuf, longestL-2, fpTre) == NULL)
4728 goto errorExit;
4729 s = strtok (lineBuf, " ");
4730 }
4731 while (strcmp (s, "tree") != 0);
4732
4733 if (i < skip) continue;
4734
4735 s = strtok (NULL, ";");
4736 gen = atoi(s+4); // 4 is offset to get rid of "rep." in tree name
4737 while (*s != '(')
4738 s++;
4739 StripComments(s);
4740
4741 /* add the tree to partition counters */
4742 if (ResetTopology (t, s) == ERROR)
4743 goto errorExit;
4744 if (AddTreeToPartitionCounters (t, 0, 1) == ERROR)
4745 goto errorExit;
4746 nTre[1]++;
4747
4748 /* calculate and write stdev of split freq */
4749 CalcTopoConvDiagn2 (nTre);
4750 if (chainParams.stat[0].numPartitions == 0)
4751 {
4752 MrBayesPrintf (fpOut, "%d\tNA\n", gen);
4753 }
4754 else if (chainParams.diagnStat == AVGSTDDEV)
4755 {
4756 MrBayesPrintf (fpOut, "%d\t%lf\n", gen, chainParams.stat[0].avgStdDev);
4757 }
4758 else // MAXSTDDEV
4759 {
4760 MrBayesPrintf (fpOut, "%d\t%lf\n", gen, chainParams.stat[0].max);
4761 }
4762 }
4763 MrBayesPrint ("%s \t%d trees discarded, the last %d trees compared to the reference\n", spacer, skip, nTre[1]);
4764
4765 /* change back to the actual numRuns, end of hack */
4766 chainParams.numRuns = nRefRun;
4767
4768 /* close tree file */
4769 SafeFclose (&fpTre);
4770 /* close output file */
4771 SafeFclose (&fpOut);
4772 /* free memory */
4773 free(lineBuf);
4774 FreeTree (t);
4775 FreeChainMemory();
4776
4777 return (NO_ERROR);
4778
4779 /* error exit */
4780 errorExit:
4781 MrBayesPrint ("%s Error in DoCompRefTree\n", spacer);
4782
4783 chainParams.numRuns = nRefRun;
4784 SafeFclose (&fpTre);
4785 SafeFclose (&fpOut);
4786
4787 FreeTree (t);
4788 FreeChainMemory();
4789 free(lineBuf);
4790
4791 return (ERROR);
4792 }
4793
4794
4795 #if defined (PRINT_RATEMUL_CPP)
DELETE_ME_count_taxa(PolyNode * p)4796 int DELETE_ME_count_taxa(PolyNode *p)
4797 {
4798 int sum=0;
4799
4800 if (p->left==NULL) {
4801 if (p->depth > 0.1)
4802 return 1;
4803 else
4804 return 0;
4805 }
4806
4807 p=p->left;
4808 while (p != NULL) {
4809 sum+=DELETE_ME_count_taxa(p);
4810 p=p->sib;
4811 }
4812 return sum;
4813 }
4814
4815
DELETE_ME_dump_depth(PolyNode * p)4816 void DELETE_ME_dump_depth(PolyNode *p)
4817 {
4818 /*print depth of two taxa clade*/
4819 /*
4820 if (p->left != NULL && p->left->left == NULL && p->left->sib != NULL && p->left->sib->left == NULL){
4821 fprintf (rateMultfp,"%f\n",p->depth);
4822 }
4823 if (p->left != NULL && p->left->left == NULL && p->left->sib != NULL && p->left->sib->left == NULL){
4824 if (p->left->depth > 0.1 && p->left->sib->depth > 0.1)
4825 fprintf (rateMultfp,"%f\n",p->depth);
4826 }
4827 */
4828 /* print depth of three taxa clade */
4829 if (((p->left != NULL && p->left->left == NULL) && p->left->sib != NULL && p->left->sib->left != NULL && p->left->sib->left->left == NULL && p->left->sib->left->sib->left == NULL) ||
4830 (p->left != NULL && p->left->left != NULL && p->left->left->left == NULL && p->left->left->sib->left == NULL && (p->left->sib->left == NULL))) {
4831 if (DELETE_ME_count_taxa(p)==2)
4832 fprintf (rateMultfp,"%f\n",p->depth);
4833 }
4834
4835 p=p->left;
4836 while (p != NULL) {
4837 DELETE_ME_dump_depth(p);
4838 p=p->sib;
4839 }
4840 }
4841 #endif
4842
4843
DoSumt(void)4844 int DoSumt (void)
4845 {
4846 int i, j=0, k, n, len, longestName, treeNo, numTreePartsToPrint,
4847 maxWidthID, maxWidthNumberPartitions, maxNumTaxa, tableWidth=0, unreliable, oneUnreliable,
4848 longestHeader;
4849 MrBFlt f, var_s, sum_s, stddev_s=0.0, sumsq_s, sumStdDev=0.0, maxStdDev=0.0, sumPSRF=0.0,
4850 maxPSRF=0.0, avgStdDev=0.0, avgPSRF=0.0, min_s=0.0, max_s=0.0, numPSRFSamples=0, min;
4851 PartCtr *x;
4852 char *s=NULL, tempName[120], fileName[120], treeName[100], divString[100];
4853 char *tempStr=NULL; /*not static because error ext is handeled*/
4854 int tempStrLength;
4855 FILE *fp=NULL;
4856 PartCtr **treeParts=NULL,*tmp;
4857 SumtFileInfo sumtFileInfo;
4858 Stat theStats;
4859 BitsLong *mask;
4860
4861 #define SCREEN_WIDTH 80
4862
4863 # if defined (MPI_ENABLED)
4864 if (proc_id == 0)
4865 {
4866 # endif
4867
4868 /* Ensure that we read trees with sumt code and not user tree code */
4869 inSumtCommand = YES;
4870
4871 /* set file pointers to NULL */
4872 fp = fpParts = fpTstat = fpVstat = fpCon = fpTrees = NULL;
4873
4874 strcpy(treeName,"tree"); //in case if parameter is not specified in a .t file
4875
4876 /* Check if there is anything to do */
4877 if (sumtParams.table == NO && sumtParams.summary == NO && sumtParams.showConsensus == NO)
4878 {
4879 MrBayesPrint ("%s Nothing to do, all output parameters (Table, Summary, Consensus) set to 'NO'\n", spacer);
4880 goto errorExit;
4881 }
4882
4883 SafeStrcpy(&tempStr, " ");
4884
4885 /* Initialize sumtParams struct */
4886 sumtParams.numTaxa = 0;
4887 sumtParams.taxaNames = NULL;
4888 sumtParams.BitsLongsNeeded = 0;
4889 sumtParams.tree = AllocatePolyTree (numTaxa);
4890 sumtParams.nESets = 0;
4891 sumtParams.nBSets = 0;
4892 sumtParams.eSetName = NULL;
4893 sumtParams.bSetName = NULL;
4894 sumtParams.popSizeSet = NO;
4895 sumtParams.popSizeSetName = NULL;
4896 AllocatePolyTreePartitions (sumtParams.tree);
4897 sumtParams.numFileTrees = (int *) SafeCalloc (2*sumtParams.numRuns+2*numTaxa, sizeof(int));
4898 sumtParams.numFileTreesSampled = sumtParams.numFileTrees + sumtParams.numRuns;
4899 sumtParams.order = sumtParams.numFileTrees + 2*sumtParams.numRuns;
4900 sumtParams.absentTaxa = sumtParams.numFileTrees + 2*sumtParams.numRuns + numTaxa;
4901 if (!sumtParams.numFileTrees)
4902 {
4903 MrBayesPrint ("%s Problems allocating sumtParams.numFileTrees in DoSumt()\n", spacer);
4904 goto errorExit;
4905 }
4906 else
4907 memAllocs[ALLOC_SUMTPARAMS] = YES;
4908
4909 /* Make sure outgroup is set correctly */
4910
4911 for (treeNo = 0; treeNo < sumtParams.numTrees; treeNo++)
4912 {
4913 /* initialize across-file tree and partition counters */
4914 sumtParams.numTreesSampled = sumtParams.numTreesEncountered = 0;
4915 numUniqueSplitsFound = numUniqueTreesFound = 0;
4916
4917 /* initialize oneUnreliable && unreliable */
4918 oneUnreliable = unreliable = NO;
4919
4920 /* initialize summary statistics */
4921 sumStdDev = 0.0;
4922 sumPSRF = 0.0;
4923 numPSRFSamples = 0;
4924 maxStdDev = 0.0;
4925 maxPSRF = 0.0;
4926
4927 /* tell user we are ready to go */
4928 if (sumtParams.numTrees > 1)
4929 sprintf (fileName,"%s.tree%d", sumtParams.sumtFileName, treeNo+1);
4930 else
4931 strcpy (fileName, sumtParams.sumtFileName);
4932
4933 if (sumtParams.numRuns == 1)
4934 MrBayesPrint ("%s Summarizing trees in file \"%s.t\"\n", spacer, fileName);
4935 else if (sumtParams.numRuns == 2)
4936 MrBayesPrint ("%s Summarizing trees in files \"%s.run1.t\" and \"%s.run2.t\"\n", spacer, fileName, fileName);
4937 else if (sumtParams.numRuns > 2)
4938 MrBayesPrint ("%s Summarizing trees in files \"%s.run1.t\", \"%s.run2.t\",...,\"%s.run%d.t\"\n", spacer, fileName, fileName,fileName,sumtParams.numRuns);
4939
4940 if (chainParams.relativeBurnin == YES)
4941 MrBayesPrint ("%s Using relative burnin ('relburnin=yes'), discarding the first %.0f %% of sampled trees\n",
4942 spacer, chainParams.burninFraction*100.0, chainParams.burninFraction);
4943 else
4944 MrBayesPrint ("%s Using absolute burnin ('relburnin=no'), discarding the first %d sampled trees\n",
4945 spacer, chainParams.chainBurnIn, chainParams.chainBurnIn);
4946
4947 MrBayesPrint ("%s Writing statistics to files %s.<parts|tstat|vstat|trprobs|con>\n", spacer, sumtParams.sumtOutfile);
4948
4949 for (sumtParams.runId=0; sumtParams.runId < sumtParams.numRuns; sumtParams.runId++)
4950 {
4951 /* initialize tree counters */
4952 sumtParams.numFileTrees[sumtParams.runId] = sumtParams.numFileTreesSampled[sumtParams.runId] = 0;
4953
4954 /* open binary file */
4955 if (sumtParams.numRuns == 1)
4956 sprintf (tempName, "%s.t", fileName);
4957 else
4958 sprintf (tempName, "%s.run%d.t", fileName, sumtParams.runId+1);
4959 strcpy(sumtParams.curFileName, tempName);
4960
4961 /* tell user we are examining files if for the first run */
4962 if (sumtParams.runId == 0)
4963 {
4964 if (sumtParams.numRuns > 1 && sumtParams.numTrees > 1)
4965 MrBayesPrint ("%s Examining first file for tree %d ...\n", spacer, treeNo);
4966 else if (sumtParams.numRuns > 1 && sumtParams.numTrees == 1)
4967 MrBayesPrint ("%s Examining first file ...\n", spacer);
4968 else if (sumtParams.numRuns == 1 && sumtParams.numTrees > 1)
4969 MrBayesPrint ("%s Examining file for tree %d ...\n", spacer, treeNo);
4970 else
4971 MrBayesPrint ("%s Examining file ...\n", spacer);
4972 }
4973
4974 /* examine file */
4975 if (ExamineSumtFile(tempName, &sumtFileInfo, treeName, &sumtParams.brlensDef) == ERROR)
4976 goto errorExit;
4977
4978 /* capture values */
4979 if (sumtParams.runId == 0)
4980
4981 /* catch lack of sampled trees */
4982 if (chainParams.relativeBurnin == NO && chainParams.chainBurnIn > sumtFileInfo.numTreesInLastBlock)
4983 {
4984 MrBayesPrint ("%s No trees are sampled as the burnin exceeds the number of trees in last block\n", spacer);
4985 MrBayesPrint ("%s Try setting burnin to a number less than %d\n", spacer, sumtFileInfo.numTreesInLastBlock);
4986 goto errorExit;
4987 }
4988
4989 /* tell the user that everything is fine */
4990 if (sumtParams.runId == 0)
4991 {
4992 if (sumtFileInfo.numTreeBlocks == 1)
4993 MrBayesPrint ("%s Found one tree block in file \"%s\" with %d trees in last block\n",
4994 spacer, tempName, sumtFileInfo.numTreesInLastBlock);
4995 else
4996 {
4997 MrBayesPrint ("%s Found %d tree blocks in file \"%s\" with %d trees in last block\n",
4998 spacer, sumtFileInfo.numTreeBlocks, tempName, sumtFileInfo.numTreesInLastBlock);
4999 MrBayesPrint ("%s Only the %d trees in last tree block will be summarized\n", spacer, sumtFileInfo.numTreesInLastBlock);
5000 }
5001 sumtParams.numTreesInLastBlock = sumtFileInfo.numTreesInLastBlock;
5002 if (sumtParams.numRuns > 1)
5003 MrBayesPrint ("%s Expecting the same number of trees in the last tree block of all files\n", spacer);
5004 if (chainParams.relativeBurnin == NO)
5005 sumtParams.burnin = chainParams.chainBurnIn;
5006 else
5007 sumtParams.burnin = (int) (sumtFileInfo.numTreesInLastBlock * chainParams.burninFraction);
5008 }
5009 else
5010 {
5011 if (sumtFileInfo.numTreesInLastBlock != sumtParams.numFileTrees[0])
5012 {
5013 MrBayesPrint ("%s Found %d trees in first file but %d trees in file \"%s\"\n", spacer,
5014 sumtParams.numFileTrees[0],
5015 sumtFileInfo.numTreesInLastBlock,
5016 tempName);
5017 goto errorExit;
5018 }
5019 }
5020
5021 /* Now we read the file for real. First, allocate a string for reading the file... */
5022 if (sumtParams.runId == 0 && treeNo == 0)
5023 {
5024 s = (char *) SafeMalloc ((size_t)(sumtFileInfo.longestLineLength) * sizeof(char));
5025 if (!s)
5026 {
5027 MrBayesPrint ("%s Problem allocating string for reading sumt file\n", spacer);
5028 goto errorExit;
5029 }
5030 }
5031 else
5032 {
5033 free (s);
5034 s = (char *) SafeMalloc ((size_t)(sumtFileInfo.longestLineLength) * sizeof (char));
5035 if (!s)
5036 {
5037 MrBayesPrint ("%s Problem reallocating string for reading sumt file\n", spacer);
5038 goto errorExit;
5039 }
5040 }
5041
5042 /* ... open the file ... */
5043 if ((fp = OpenTextFileR(tempName)) == NULL)
5044 goto errorExit;
5045
5046 /* ...and fast forward to beginning of last tree block. */
5047 for (i=0; i<sumtFileInfo.lastTreeBlockBegin+1; i++)
5048 {
5049 if (fgets (s, sumtFileInfo.longestLineLength-2, fp) == NULL)
5050 {
5051 printf ("Error in function: %s at line: %d in file: %s", __func__, __LINE__, __FILE__);
5052 }
5053 }
5054
5055 # if defined (PRINT_RATEMUL_CPP)
5056 sprintf (tempName, "%s.ratemult", chainParams.chainFileName);
5057 if ((rateMultfp=OpenNewMBPrintFile (tempName)) == NULL)
5058 {
5059 printf ("Error oppening file: %s to write", tempName);
5060 goto errorExit;
5061 }
5062 fprintf (rateMultfp,"rateMult_CPP\n");
5063 # endif
5064
5065 /* Set up cheap status bar. */
5066 if (sumtParams.runId == 0)
5067 {
5068 if (sumtParams.numTrees > 1)
5069 MrBayesPrint ("\n%s Tree reading status for tree %d:\n\n", spacer, treeNo+1);
5070 else
5071 MrBayesPrint ("\n%s Tree reading status:\n\n", spacer);
5072 MrBayesPrint ("%s 0 10 20 30 40 50 60 70 80 90 100\n", spacer);
5073 MrBayesPrint ("%s v-------v-------v-------v-------v-------v-------v-------v-------v-------v-------v\n", spacer);
5074 MrBayesPrint ("%s *", spacer);
5075 numAsterices = 0;
5076 }
5077
5078 /* ...and parse file, tree-by-tree. We are only parsing lines between the "begin trees" and "end" statements.
5079 We don't actually get those lines, however, but rather the lines between those statements. */
5080 expecting = Expecting(COMMAND);
5081 /* We skip the begin trees statement so we need to set up some variables here */
5082 inTreesBlock = YES;
5083 ResetTranslateTable();
5084 for (i=0; i<sumtFileInfo.lastTreeBlockEnd - sumtFileInfo.lastTreeBlockBegin - 1; i++)
5085 {
5086 if (fgets (s, sumtFileInfo.longestLineLength-2, fp) == NULL)
5087 {
5088 printf ("Error in function: %s at line: %d in file: %s", __func__, __LINE__, __FILE__);
5089 }
5090 /*MrBayesPrint ("%s", s);*/
5091 if (ParseCommand (s) == ERROR)
5092 goto errorExit;
5093 }
5094 inTreesBlock = NO;
5095 ResetTranslateTable();
5096
5097 /* Finish cheap status bar. */
5098 if (sumtParams.runId == sumtParams.numRuns - 1)
5099 {
5100 if (numAsterices < 80)
5101 {
5102 for (i=0; i<80 - numAsterices; i++)
5103 MrBayesPrint ("*");
5104 }
5105 MrBayesPrint ("\n\n");
5106 }
5107
5108 /* print out information on absent and pruned taxa */
5109 if (sumtParams.runId == sumtParams.numRuns - 1 && treeNo == 0)
5110 PrintSumtTaxaInfo ();
5111
5112 /* tell user how many trees were successfully read */
5113 if (sumtParams.numRuns == 1)
5114 MrBayesPrint ("%s Read %d trees from last tree block (sampling %d of them)\n", spacer,
5115 sumtParams.numTreesEncountered, sumtParams.numTreesSampled);
5116 else if (sumtParams.numRuns > 1)
5117 {
5118 if (sumtParams.runId != 0 && sumtParams.numFileTreesSampled[sumtParams.runId]!=sumtParams.numFileTreesSampled[0])
5119 {
5120 if (sumtParams.runId == sumtParams.numRuns - 1)
5121 MrBayesPrint ("\n\n");
5122 MrBayesPrint ("%s Found %d post-burnin trees in the first file but %d post-burnin trees in file %d\n",
5123 spacer,
5124 sumtParams.numFileTreesSampled[0],
5125 sumtParams.numFileTreesSampled[sumtParams.runId],
5126 sumtParams.runId+1);
5127 goto errorExit;
5128 }
5129 if (sumtParams.runId == sumtParams.numRuns - 1)
5130 {
5131 MrBayesPrint ("%s Read a total of %d trees in %d files (sampling %d of them)\n", spacer,
5132 sumtParams.numTreesEncountered,
5133 sumtParams.numRuns, sumtParams.numTreesSampled);
5134 MrBayesPrint ("%s (Each file contained %d trees of which %d were sampled)\n", spacer,
5135 sumtParams.numFileTrees[0],
5136 sumtParams.numFileTreesSampled[0]);
5137 }
5138 }
5139
5140 /* Check that at least one tree was read in. */
5141 if (sumtParams.numTreesSampled <= 0)
5142 {
5143 MrBayesPrint ("%s No trees read in\n", spacer);
5144 goto errorExit;
5145 }
5146
5147 SafeFclose (&fp);
5148 } /* next run for this tree */
5149
5150 /* Extract partition counter pointers */
5151 treeParts = (PartCtr **) SafeCalloc ((size_t)numUniqueSplitsFound, sizeof(PartCtr *));
5152 i = 0;
5153 PartCtrUppass(partCtrRoot, treeParts, &i);
5154
5155 min = (sumtParams.minPartFreq * (sumtParams.numTreesSampled/sumtParams.numRuns));
5156 numTreePartsToPrint=numUniqueSplitsFound;
5157 for (i=0; i<numTreePartsToPrint;)
5158 {
5159 for (j=0; j<sumtParams.numRuns;j++)
5160 {
5161 if (treeParts[i]->count[j]>=min)
5162 break;
5163 }
5164 if (j==sumtParams.numRuns)
5165 {
5166 numTreePartsToPrint--;
5167 tmp=treeParts[numTreePartsToPrint];
5168 treeParts[numTreePartsToPrint]=treeParts[i];
5169 treeParts[i]=tmp;
5170 }
5171 else
5172 {
5173 i++;
5174 }
5175 }
5176
5177 /* Sort taxon partitions (clades, splits) ... */
5178 SortPartCtr (treeParts, 0, numTreePartsToPrint-1);
5179
5180 /* Sort root and tips among those splits always present */
5181 SortTerminalPartCtr (treeParts, numUniqueSplitsFound);
5182
5183 /* open output files for summary information (three files) */
5184 if (OpenSumtFiles (treeNo) == ERROR)
5185 goto errorExit;
5186
5187 /* Print partitions to screen. */
5188 if (treeNo == 0)
5189 {
5190 longestName = 0;
5191 for (k=0; k<numTaxa; k++)
5192 {
5193 if (taxaInfo[k].isDeleted == NO && sumtParams.absentTaxa[k] == NO)
5194 continue;
5195 len = (int) strlen (taxaNames[k]);
5196 if (len > longestName)
5197 longestName = len;
5198 }
5199 if (sumtParams.table == YES)
5200 {
5201 MrBayesPrint (" \n");
5202 MrBayesPrint ("%s General explanation: \n", spacer);
5203 MrBayesPrint (" \n");
5204 MrBayesPrint ("%s In an unrooted tree, a taxon bipartition (split) is specified by removing a \n", spacer);
5205 MrBayesPrint ("%s branch, thereby dividing the species into those to the left and those to the \n", spacer);
5206 MrBayesPrint ("%s right of the branch. Here, taxa to one side of the removed branch are denoted \n", spacer);
5207 MrBayesPrint ("%s '.' and those to the other side are denoted '*'. Specifically, the '.' symbol \n", spacer);
5208 MrBayesPrint ("%s is used for the taxa on the same side as the outgroup. \n", spacer);
5209 MrBayesPrint (" \n");
5210 MrBayesPrint ("%s In a rooted or clock tree, the tree is rooted using the model and not by \n", spacer);
5211 MrBayesPrint ("%s reference to an outgroup. Each bipartition therefore corresponds to a clade, \n", spacer);
5212 MrBayesPrint ("%s that is, a group that includes all the descendants of a particular branch in \n", spacer);
5213 MrBayesPrint ("%s the tree. Taxa that are included in each clade are denoted using '*', and \n", spacer);
5214 MrBayesPrint ("%s taxa that are not included are denoted using the '.' symbol. \n", spacer);
5215 MrBayesPrint (" \n");
5216 MrBayesPrint ("%s The output first includes a key to all the bipartitions with frequency larger \n", spacer);
5217 MrBayesPrint ("%s or equual to (Minpartfreq) in at least one run. Minpartfreq is a parameter to \n", spacer);
5218 MrBayesPrint ("%s sumt command and currently it is set to %1.2lf. This is followed by a table \n", spacer, sumtParams.minPartFreq);
5219 MrBayesPrint ("%s with statistics for the informative bipartitions (those including at least \n", spacer);
5220 MrBayesPrint ("%s two taxa), sorted from highest to lowest probability. For each bipartition, \n", spacer);
5221 MrBayesPrint ("%s the table gives the number of times the partition or split was observed in all\n", spacer);
5222 MrBayesPrint ("%s runs (#obs) and the posterior probability of the bipartition (Probab.), which \n", spacer);
5223 MrBayesPrint ("%s is the same as the split frequency. If several runs are summarized, this is \n", spacer);
5224 MrBayesPrint ("%s followed by the minimum split frequency (Min(s)), the maximum frequency \n", spacer);
5225 MrBayesPrint ("%s (Max(s)), and the standard deviation of frequencies (Stddev(s)) across runs. \n", spacer);
5226 MrBayesPrint ("%s The latter value should approach 0 for all bipartitions as MCMC runs converge.\n", spacer);
5227 MrBayesPrint (" \n");
5228 MrBayesPrint ("%s This is followed by a table summarizing branch lengths, node heights (if a \n", spacer);
5229 MrBayesPrint ("%s clock model was used) and relaxed clock parameters (if a relaxed clock model \n", spacer);
5230 MrBayesPrint ("%s was used). The mean, variance, and 95 %% credible interval are given for each \n", spacer);
5231 MrBayesPrint ("%s of these parameters. If several runs are summarized, the potential scale \n", spacer);
5232 MrBayesPrint ("%s reduction factor (PSRF) is also given; it should approach 1 as runs converge. \n", spacer);
5233 MrBayesPrint ("%s Node heights will take calibration points into account, if such points were \n", spacer);
5234 MrBayesPrint ("%s used in the analysis. \n", spacer);
5235 MrBayesPrint ("%s \n", spacer);
5236 MrBayesPrint ("%s Note that Stddev may be unreliable if the partition is not present in all \n", spacer);
5237 MrBayesPrint ("%s runs (the last column indicates the number of runs that sampled the partition \n", spacer);
5238 MrBayesPrint ("%s if more than one run is summarized). The PSRF is not calculated at all if \n", spacer);
5239 MrBayesPrint ("%s the partition is not present in all runs.The PSRF is also sensitive to small \n", spacer);
5240 MrBayesPrint ("%s sample sizes and it should only be considered a rough guide to convergence \n", spacer);
5241 MrBayesPrint ("%s since some of the assumptions allowing one to interpret it as a true potential\n", spacer);
5242 MrBayesPrint ("%s scale reduction factor are violated in MrBayes. \n", spacer);
5243 MrBayesPrint ("%s \n", spacer);
5244 MrBayesPrint ("%s List of taxa in bipartitions: \n", spacer);
5245 MrBayesPrint (" \n");
5246 j = 1;
5247 for (k=0; k<numTaxa; k++)
5248 {
5249 if (taxaInfo[k].isDeleted == NO && sumtParams.absentTaxa[k] == NO)
5250 {
5251 MrBayesPrint ("%s %4d -- %s\n", spacer, j++, taxaNames[k]);
5252 }
5253 }
5254 }
5255 }
5256
5257 if (sumtParams.numTrees > 1 && (sumtParams.table == YES || sumtParams.summary == YES))
5258 {
5259 MrBayesPrint ("\n\n");
5260 MrBayesPrint ("%s Results for tree number %d\n", spacer, treeNo+1);
5261 MrBayesPrint ("%s ==========================\n\n", spacer);
5262 }
5263
5264 /* First print key to taxon bipartitions */
5265 if (sumtParams.table == YES)
5266 {
5267 MrBayesPrint ("\n");
5268 if (sumtParams.numTrees == 1)
5269 MrBayesPrint ("%s Key to taxon bipartitions (saved to file \"%s.parts\"):\n\n", spacer, sumtParams.sumtOutfile);
5270 else
5271 MrBayesPrint ("%s Key to taxon bipartitions (saved to file \"%s.tree%d.parts\"):\n\n", spacer, sumtParams.sumtOutfile, treeNo+1);
5272 }
5273
5274 /* calculate a couple of numbers that are handy to have */
5275 /*numTreePartsToPrint = 0;
5276 for (i=0; i<numUniqueSplitsFound; i++)
5277 {
5278 if ((MrBFlt)treeParts[i]->totCount/(MrBFlt)sumtParams.numTreesSampled >= sumtParams.minPartFreq)
5279 numTreePartsToPrint++;
5280 }
5281 */
5282 maxWidthID = (int) (log10 (numTreePartsToPrint)) + 1;
5283 if (maxWidthID < 2)
5284 maxWidthID = 2;
5285 maxNumTaxa = SCREEN_WIDTH - 9;
5286
5287 for (j=0; j<sumtParams.numTaxa; j+=maxNumTaxa)
5288 {
5289 /* print header to screen and to parts file simultaneously */
5290
5291 /* first print header to screen */
5292 MrBayesPrint ("%s ", spacer);
5293 if (j == 0)
5294 MrBayesPrint ("%*s -- Partition\n", maxWidthID, "ID");
5295 else
5296 MrBayesPrint ("%*s -- Partition (continued)\n", maxWidthID, "ID");
5297 tableWidth = maxWidthID + 4 + sumtParams.numTaxa;
5298 if (tableWidth > SCREEN_WIDTH)
5299 tableWidth = SCREEN_WIDTH;
5300 MrBayesPrint ("%s ", spacer);
5301 for (i=0; i<tableWidth; i++)
5302 MrBayesPrint ("-");
5303 MrBayesPrint ("\n");
5304
5305 /* now print header to file */
5306 MrBayesPrintf (fpParts, "ID\tPartition\n");
5307
5308 /* now, show partitions that were found on screen; print to .parts file simultaneously */
5309 mask = SafeCalloc (sumtParams.BitsLongsNeeded, sizeof(BitsLong));
5310 for (i=0; i<sumtParams.numTaxa; i++)
5311 SetBit (i, mask);
5312 for (i=0; i<numTreePartsToPrint; i++)
5313 {
5314 x = treeParts[i];
5315 if (IsBitSet(localOutGroup, x->partition) == YES && sumtParams.isRooted == NO)
5316 FlipBits(x->partition, sumtParams.BitsLongsNeeded, mask);
5317
5318 if ((NumBits(x->partition, sumtParams.BitsLongsNeeded) == numLocalTaxa || NumBits(x->partition, sumtParams.BitsLongsNeeded) == 0) && sumtParams.isClock == NO)
5319 continue;
5320
5321 MrBayesPrint ("%s %*d -- ", spacer, maxWidthID, i);
5322 if (sumtParams.numTaxa <= maxNumTaxa)
5323 ShowParts (stdout, x->partition, sumtParams.numTaxa);
5324 else
5325 {
5326 if (sumtParams.numTaxa - j > maxNumTaxa)
5327 ShowSomeParts (stdout, x->partition, j, maxNumTaxa);
5328 else
5329 ShowSomeParts (stdout, x->partition, j, sumtParams.numTaxa - j);
5330 }
5331 fflush(stdout);
5332 MrBayesPrint ("\n");
5333
5334 MrBayesPrintf (fpParts, "%d\t", i);
5335 ShowParts (fpParts, x->partition, sumtParams.numTaxa);
5336 MrBayesPrintf (fpParts, "\n");
5337 }
5338 free (mask);
5339
5340 /* finish screen table */
5341 if (sumtParams.table == YES)
5342 {
5343 MrBayesPrint ("%s ", spacer);
5344 for (i=0; i<tableWidth; i++)
5345 {
5346 MrBayesPrint ("-");
5347 }
5348 MrBayesPrint ("\n");
5349 if (oneUnreliable == YES)
5350 {
5351 MrBayesPrint ("%s * The partition was not found in all runs so the values are unreliable\n\n", spacer);
5352 }
5353 else
5354 {
5355 MrBayesPrint ("\n");
5356 }
5357 }
5358 }
5359
5360 /* Second, print statitistics for taxon bipartitions */
5361 if (sumtParams.table == YES)
5362 {
5363 if (sumtParams.isRooted == NO)
5364 MrBayesPrint ("%s Summary statistics for informative taxon bipartitions\n", spacer);
5365 else
5366 MrBayesPrint ("%s Summary statistics for informative taxon bipartitions (clades)\n", spacer);
5367 MrBayesPrint ("%s (saved to file \"%s.tstat\"):\n\n", spacer, sumtParams.sumtOutfile);
5368 }
5369
5370 /* calculate a couple of numbers that are handy to have */
5371 /*numTreePartsToPrint = 0;
5372 for (i=0; i<numUniqueSplitsFound; i++)
5373 {
5374 if ((MrBFlt)treeParts[i]->totCount/(MrBFlt)sumtParams.numTreesSampled >= sumtParams.minPartFreq)
5375 numTreePartsToPrint++;
5376 }
5377 */
5378 maxWidthID = (int) (log10 (numTreePartsToPrint)) + 1;
5379 if (maxWidthID < 2)
5380 maxWidthID = 2;
5381 maxWidthNumberPartitions = (int) (log10 (treeParts[0]->totCount)) + 1;
5382 if (maxWidthNumberPartitions < 4)
5383 maxWidthNumberPartitions = 4;
5384
5385 /* print header to screen and to parts file simultaneously */
5386 if (sumtParams.table == YES)
5387 {
5388 /* first print header to screen */
5389 MrBayesPrint ("%s ", spacer);
5390 MrBayesPrint ("%*s ", maxWidthID, "ID");
5391 tableWidth = maxWidthID + 3;
5392 MrBayesPrint ("#obs");
5393 tableWidth += 4;
5394 for (i=4; i<maxWidthNumberPartitions; i++)
5395 {
5396 MrBayesPrint (" ");
5397 tableWidth++;
5398 }
5399 MrBayesPrint (" Probab.");
5400 tableWidth += 11;
5401 if (sumtParams.numRuns > 1)
5402 {
5403 MrBayesPrint (" Sd(s)+ ");
5404 MrBayesPrint (" Min(s) Max(s) ");
5405 tableWidth += 36;
5406 MrBayesPrint (" Nruns ");
5407 tableWidth += 8;
5408 }
5409 MrBayesPrint ("\n%s ", spacer);
5410 for (i=0; i<tableWidth; i++)
5411 {
5412 MrBayesPrint ("-");
5413 }
5414 MrBayesPrint ("\n");
5415
5416 /* now print header to file */
5417 if (sumtParams.numRuns > 1)
5418 MrBayesPrintf (fpTstat, "ID\t#obs\tProbability(=s)\tStddev(s)\tMin(s)\tMax(s)\tNruns\n");
5419 else
5420 MrBayesPrintf (fpTstat, "ID\t#obs\tProbability(=s)\n");
5421 }
5422
5423 /* now, show informative partitions that were found on screen; print to .tstat file simultaneously */
5424 for (i=0; i<numTreePartsToPrint; i++)
5425 {
5426 x = treeParts[i];
5427
5428 /* skip uninformative partitions */
5429 if (NumBits(x->partition, sumtParams.BitsLongsNeeded) <= 1 || NumBits(x->partition, sumtParams.BitsLongsNeeded) == sumtParams.numTaxa)
5430 continue;
5431 if (NumBits(x->partition, sumtParams.BitsLongsNeeded) == sumtParams.numTaxa - 1 && sumtParams.isRooted == NO)
5432 continue;
5433
5434 if (sumtParams.table == YES)
5435 {
5436 MrBayesPrint ("%s %*d", spacer, maxWidthID, i);
5437 fflush(stdout);
5438 MrBayesPrintf (fpTstat, "%d\t", i);
5439 }
5440 if (sumtParams.numRuns > 1)
5441 {
5442 sum_s = 0.0;
5443 sumsq_s = 0.0;
5444 min_s = 1.0;
5445 max_s = 0.0;
5446 for (n=j=0; n<sumtParams.numRuns; n++)
5447 {
5448 if (x->count[n] > 0)
5449 j++;
5450 f = (MrBFlt) x->count[n] / (MrBFlt) sumtParams.numFileTreesSampled[n];
5451 sum_s += f;
5452 sumsq_s += f * f;
5453 if (f < min_s)
5454 min_s = f;
5455 if (f > max_s)
5456 max_s = f;
5457 }
5458 var_s = sumsq_s - sum_s * sum_s / (MrBFlt) sumtParams.numRuns;
5459 var_s /= (sumtParams.numRuns - 1);
5460 if (var_s > 0.0)
5461 stddev_s = sqrt (var_s);
5462 else
5463 stddev_s = 0.0;
5464 if (j == sumtParams.numRuns)
5465 unreliable = NO;
5466 else
5467 {
5468 unreliable = YES;
5469 oneUnreliable = YES;
5470 }
5471 }
5472 if (sumtParams.table == YES)
5473 {
5474 f = (MrBFlt) x->totCount / (MrBFlt) sumtParams.numTreesSampled;
5475 MrBayesPrint (" %*d %1.6lf", maxWidthNumberPartitions, x->totCount, f);
5476 MrBayesPrintf (fpTstat, "\t%d\t%s", x->totCount, MbPrintNum(f));
5477 if (sumtParams.numRuns > 1)
5478 {
5479 MrBayesPrint (" %1.6lf %1.6lf %1.6lf", stddev_s, min_s, max_s);
5480 MrBayesPrint (" %3d", j);
5481 MrBayesPrintf (fpTstat, "\t%s", MbPrintNum(stddev_s));
5482 MrBayesPrintf (fpTstat, "\t%s", MbPrintNum(min_s));
5483 MrBayesPrintf (fpTstat, "\t%s", MbPrintNum(max_s));
5484 MrBayesPrintf (fpTstat, "\t%d", j);
5485 }
5486 MrBayesPrintf (fpTstat, "\n");
5487 if (unreliable == YES)
5488 MrBayesPrint (" *\n");
5489 else
5490 MrBayesPrint ("\n");
5491 sumStdDev += stddev_s;
5492 if (stddev_s > maxStdDev)
5493 maxStdDev = stddev_s;
5494 }
5495 }
5496
5497 /* finish screen table */
5498 if (sumtParams.table == YES)
5499 {
5500 MrBayesPrint ("%s ", spacer);
5501 for (i=0; i<tableWidth; i++)
5502 {
5503 MrBayesPrint ("-");
5504 }
5505 MrBayesPrint ("\n");
5506 if (sumtParams.numRuns > 1)
5507 {
5508 MrBayesPrint ("%s + Convergence diagnostic (standard deviation of split frequencies)\n", spacer);
5509 MrBayesPrint ("%s should approach 0.0 as runs converge.\n\n", spacer);
5510 }
5511 if (oneUnreliable == YES)
5512 MrBayesPrint ("%s * The partition was not found in all runs so the values are unreliable\n", spacer);
5513 }
5514
5515 /* Third, print statitistics for branch and node parameters */
5516 if (sumtParams.table == YES)
5517 {
5518 MrBayesPrint ("\n");
5519 MrBayesPrint ("%s Summary statistics for branch and node parameters\n", spacer);
5520 MrBayesPrint ("%s (saved to file \"%s.vstat\"):\n", spacer, sumtParams.sumtOutfile);
5521 }
5522
5523 if (sumtParams.table == YES)
5524 {
5525 /* calculate longest header */
5526 longestHeader = 9; /* length of 'parameter' */
5527 i = (int)(log10(numTreePartsToPrint)) + 3; /* length of partition specifier including [] */
5528 len = i + (int)(strlen(treeName)) + 2; /* length of length{m}[n] or height{m}[n] */
5529 if (len > longestHeader)
5530 longestHeader = len;
5531 for (j=0; j<sumtParams.nBSets; j++)
5532 {
5533 len = (int) strlen(sumtParams.tree->bSetName[j]) + 7 + i;
5534 if (len > longestHeader)
5535 longestHeader = len;
5536 }
5537 for (j=0; j<sumtParams.nESets; j++)
5538 {
5539 len = (int) strlen(sumtParams.tree->eSetName[j]) + 8 + i;
5540 if (len > longestHeader)
5541 longestHeader = len;
5542 }
5543 if (sumtParams.popSizeSet == YES)
5544 {
5545 len = (int) strlen(sumtParams.tree->popSizeSetName) + i;
5546 if (len > longestHeader)
5547 longestHeader = len;
5548 }
5549
5550 /* print the header rows */
5551 MrBayesPrint ("\n");
5552 if (sumtParams.HPD == NO)
5553 MrBayesPrint ("%s %*c 95%% Cred. Interval\n", spacer, longestHeader, ' ');
5554 else
5555 MrBayesPrint ("%s %*c 95%% HPD Interval\n", spacer, longestHeader, ' ');
5556 MrBayesPrint ("%s %*c --------------------\n", spacer, longestHeader, ' ');
5557
5558 MrBayesPrint ("%s Parameter%*c Mean Variance Lower Upper Median", spacer, longestHeader-9, ' ');
5559 tableWidth = 68 + longestHeader - 9;
5560 if (sumtParams.HPD == YES)
5561 MrBayesPrintf (fpVstat, "Parameter\tMean\tVariance\tCredInt_Lower\tCredInt_Upper\tMedian", spacer, longestHeader-9, ' ');
5562 else
5563 MrBayesPrintf (fpVstat, "Parameter\tMean\tVariance\tHPD_Lower\tHPD_Upper\tMedian", spacer, longestHeader-9, ' ');
5564 if (sumtParams.numRuns > 1)
5565 {
5566 MrBayesPrint (" PSRF+ Nruns");
5567 tableWidth += 17;
5568 MrBayesPrintf (fpVstat, "\tPSRF\tNruns");
5569 }
5570 MrBayesPrint ("\n");
5571 MrBayesPrintf (fpVstat, "\n");
5572
5573 MrBayesPrint ("%s ", spacer);
5574 for (j=0; j<tableWidth; j++)
5575 {
5576 MrBayesPrint ("-");
5577 }
5578 MrBayesPrint ("\n");
5579
5580 /* print lengths */
5581 strcpy (divString, treeName+4);
5582 for (i=1; i<numTreePartsToPrint; i++)
5583 {
5584 x = treeParts[i];
5585 tempStrLength=(int)strlen(tempStr);
5586 SafeSprintf (&tempStr,&tempStrLength, "length%s[%d]", divString, i);
5587
5588 GetSummary (x->length, sumtParams.numRuns, x->count, &theStats, sumtParams.HPD);
5589
5590 MrBayesPrint ("%s %-*s ", spacer, longestHeader, tempStr);
5591 MrBayesPrintf (fpVstat, "%s", tempStr);
5592
5593 PrintSumtTableLine(sumtParams.numRuns, x->count, &theStats, &numPSRFSamples, &maxPSRF, &sumPSRF);
5594
5595 }
5596
5597 /* print heights */
5598 if (sumtParams.isClock == YES)
5599 {
5600 strcpy (divString, treeName+4);
5601 for (i=0; i<numTreePartsToPrint; i++)
5602 {
5603 x = treeParts[i];
5604 tempStrLength=(int)strlen(tempStr);
5605 SafeSprintf (&tempStr,&tempStrLength, "height%s[%d]", divString, i);
5606
5607 GetSummary (x->height, sumtParams.numRuns, x->count, &theStats, sumtParams.HPD);
5608
5609 MrBayesPrint ("%s %-*s ", spacer, longestHeader, tempStr);
5610 MrBayesPrintf (fpVstat, "%s", tempStr);
5611
5612 PrintSumtTableLine(sumtParams.numRuns, x->count, &theStats, &numPSRFSamples, &maxPSRF, &sumPSRF);
5613 }
5614 }
5615
5616 /* print ages */
5617 if (sumtParams.isCalibrated == YES)
5618 {
5619 strcpy (divString, treeName+4);
5620 for (i=0; i<numTreePartsToPrint; i++)
5621 {
5622 x = treeParts[i];
5623 tempStrLength=(int)strlen(tempStr);
5624 SafeSprintf (&tempStr,&tempStrLength, "age%s[%d]", divString, i);
5625
5626 GetSummary (x->age, sumtParams.numRuns, x->count, &theStats, sumtParams.HPD);
5627
5628 MrBayesPrint ("%s %-*s ", spacer, longestHeader, tempStr);
5629 MrBayesPrintf (fpVstat, "%s", tempStr);
5630
5631 PrintSumtTableLine(sumtParams.numRuns, x->count, &theStats, &numPSRFSamples, &maxPSRF, &sumPSRF);
5632 }
5633 }
5634
5635 /* print effective branch lengths */
5636 if (sumtParams.isRelaxed == YES)
5637 {
5638 for (i=0; i<sumtParams.nBSets; i++)
5639 {
5640 for (j=1; j<numTreePartsToPrint; j++)
5641 {
5642 x = treeParts[j];
5643 tempStrLength=(int)strlen(tempStr);
5644 SafeSprintf (&tempStr,&tempStrLength, "%s_length[%d]", sumtParams.bSetName[i], j);
5645
5646 GetSummary (x->bLen[i], sumtParams.numRuns, x->count, &theStats, sumtParams.HPD);
5647
5648 MrBayesPrint ("%s %-*s ", spacer, longestHeader, tempStr);
5649 MrBayesPrintf (fpVstat, "%s", tempStr);
5650
5651 PrintSumtTableLine(sumtParams.numRuns, x->count, &theStats, &numPSRFSamples, &maxPSRF, &sumPSRF);
5652 }
5653 for (j=1; j<numTreePartsToPrint; j++)
5654 {
5655 x = treeParts[j];
5656 tempStrLength=(int)strlen(tempStr);
5657 SafeSprintf (&tempStr,&tempStrLength, "%s_rate[%d]", sumtParams.bSetName[i], j);
5658
5659 GetSummary (x->bRate[i], sumtParams.numRuns, x->count, &theStats, sumtParams.HPD);
5660
5661 MrBayesPrint ("%s %-*s ", spacer, longestHeader, tempStr);
5662 MrBayesPrintf (fpVstat, "%s", tempStr);
5663
5664 PrintSumtTableLine(sumtParams.numRuns, x->count, &theStats, &numPSRFSamples, &maxPSRF, &sumPSRF);
5665 }
5666 }
5667 for (i=0; i<sumtParams.nESets; i++)
5668 {
5669 for (j=1; j<numTreePartsToPrint; j++)
5670 {
5671 x = treeParts[j];
5672 tempStrLength=(int)strlen(tempStr);
5673 SafeSprintf (&tempStr,&tempStrLength, "%s_nEvents[%d]", sumtParams.eSetName[i], j);
5674
5675 GetIntSummary (x->nEvents[i], sumtParams.numRuns, x->count, &theStats, sumtParams.HPD);
5676
5677 MrBayesPrint ("%s %-*s ", spacer, longestHeader, tempStr);
5678 MrBayesPrintf (fpVstat, "%s", tempStr);
5679
5680 PrintSumtTableLine(sumtParams.numRuns, x->count, &theStats, &numPSRFSamples, &maxPSRF, &sumPSRF);
5681 }
5682 }
5683 }
5684
5685 /* print population size sets */
5686 if (sumtParams.popSizeSet == YES)
5687 {
5688 for (j=1; j<numTreePartsToPrint; j++)
5689 {
5690 x = treeParts[j];
5691 tempStrLength=(int)strlen(tempStr);
5692 SafeSprintf (&tempStr,&tempStrLength, "%s[%d]", sumtParams.popSizeSetName, j);
5693
5694 GetSummary (x->popSize, sumtParams.numRuns, x->count, &theStats, sumtParams.HPD);
5695
5696 MrBayesPrint ("%s %-*s ", spacer, longestHeader, tempStr);
5697 MrBayesPrintf (fpVstat, "%s", tempStr);
5698
5699 PrintSumtTableLine(sumtParams.numRuns, x->count, &theStats, &numPSRFSamples, &maxPSRF, &sumPSRF);
5700 }
5701 }
5702
5703 /* finish table */
5704 MrBayesPrint ("%s ", spacer);
5705 for (j=0; j<tableWidth; j++)
5706 MrBayesPrint ("-");
5707 MrBayesPrint ("\n");
5708
5709 if (sumtParams.numRuns > 1)
5710 {
5711 MrBayesPrint ("%s + Convergence diagnostic (PSRF = Potential Scale Reduction Factor; Gelman\n", spacer);
5712 MrBayesPrint ("%s and Rubin, 1992) should approach 1.0 as runs converge. NA is reported when\n", spacer);
5713 MrBayesPrint ("%s deviation of parameter values within all runs is 0 or when a parameter\n", spacer);
5714 MrBayesPrint ("%s value (a branch length, for instance) is not sampled in all runs.\n", spacer);
5715 }
5716
5717 if (oneUnreliable == YES)
5718 {
5719 MrBayesPrint ("%s * The partition was not found in all runs so the values are unreliable.\n", spacer);
5720 }
5721 MrBayesPrint ("\n\n");
5722 }
5723
5724 /* Print branch parameters to file if requested */
5725 strcpy( divString, treeName+4);
5726 if (sumtParams.saveBrParams == YES && PrintBrParamsToFile (treeParts, numUniqueSplitsFound, treeNo, divString) == ERROR)
5727 goto errorExit;
5728
5729 /* Exclude trivial splits when calculating average standard deviation of split frequencies. */
5730 avgStdDev = sumStdDev / (numTreePartsToPrint-sumtParams.numTaxa-1);
5731 avgPSRF = sumPSRF / numPSRFSamples;
5732
5733 if (sumtParams.numRuns > 1 && sumtParams.summary == YES)
5734 {
5735 MrBayesPrint ("%s Summary statistics for partitions with frequency >= %1.2lf in at least one run:\n", spacer, sumtParams.minPartFreq);
5736 MrBayesPrint ("%s Average standard deviation of split frequencies = %1.6lf\n", spacer, avgStdDev);
5737 MrBayesPrint ("%s Maximum standard deviation of split frequencies = %1.6lf\n", spacer, maxStdDev);
5738 }
5739 if (sumtParams.brlensDef == YES && sumtParams.numRuns > 1 && sumtParams.summary == YES)
5740 {
5741 MrBayesPrint ("%s Average PSRF for parameter values (excluding NA and >10.0) = %1.3lf\n", spacer, avgPSRF);
5742 if (maxPSRF == 10)
5743 MrBayesPrint ("%s Maximum PSRF for parameter values = NA\n", spacer);
5744 else
5745 MrBayesPrint ("%s Maximum PSRF for parameter values = %1.3lf\n", spacer, maxPSRF);
5746 }
5747 MrBayesPrint ("\n");
5748
5749 SortPartCtr (treeParts, 0, numUniqueSplitsFound-1); /* We sort again but this time we sort all partitions instead of just first numTreePartsToPrintNow */
5750 /* make the majority rule consensus tree */
5751 if (sumtParams.showConsensus == YES && ConTree (treeParts, numUniqueSplitsFound) == ERROR)
5752 goto errorExit;
5753
5754 /* get probabilities of individual trees */
5755 if (TreeProb () == ERROR)
5756 goto errorExit;
5757
5758 /* close files */
5759 SafeFclose (&fpParts);
5760 SafeFclose (&fpTstat);
5761 SafeFclose (&fpVstat);
5762 SafeFclose (&fpCon);
5763 SafeFclose (&fpTrees);
5764
5765 # if defined (PRINT_RATEMUL_CPP)
5766 SafeFclose (&rateMultfp);
5767 # endif
5768
5769 /* free pointer array to partitions */
5770 free (treeParts);
5771 treeParts = NULL;
5772 FreePartCtr (partCtrRoot);
5773 partCtrRoot = NULL;
5774 FreeTreeCtr (treeCtrRoot);
5775 treeCtrRoot = NULL;
5776 } /* next tree */
5777
5778 /* free memory and file pointers */
5779 if (s) free(s);
5780 FreeSumtParams();
5781
5782 /* reset numLocalTaxa and localOutGroup */
5783 ResetTaxonSet();
5784
5785 # if defined (MPI_ENABLED)
5786 }
5787 # endif
5788
5789 expecting = Expecting(COMMAND);
5790 inSumtCommand = NO;
5791 SAFEFREE (tempStr);
5792
5793 return (NO_ERROR);
5794
5795 /* error exit */
5796 errorExit:
5797 /* free sumtParams */
5798 if (s) free(s);
5799 FreeSumtParams();
5800
5801 /* close files in case they are open*/
5802 SafeFclose (&fp);
5803 SafeFclose (&fpParts);
5804 SafeFclose (&fpTstat);
5805 SafeFclose (&fpVstat);
5806 SafeFclose (&fpCon);
5807 SafeFclose (&fpTrees);
5808
5809 # if defined (PRINT_RATEMUL_CPP)
5810 SafeFclose (&rateMultfp);
5811 # endif
5812
5813 /* free pointer array to partitions, part and tree counters */
5814 free (treeParts);
5815 FreePartCtr (partCtrRoot);
5816 FreeTreeCtr (treeCtrRoot);
5817 partCtrRoot = NULL;
5818 treeCtrRoot = NULL;
5819
5820 /* reset taxon set */
5821 ResetTaxonSet();
5822
5823 expecting = Expecting(COMMAND);
5824 inSumtCommand = NO;
5825 SAFEFREE (tempStr);
5826
5827 return (ERROR);
5828 }
5829
5830
DoSumtParm(char * parmName,char * tkn)5831 int DoSumtParm (char *parmName, char *tkn)
5832 {
5833 int tempI;
5834 MrBFlt tempD;
5835 char tempStr[100];
5836
5837 if (defMatrix == NO)
5838 {
5839 MrBayesPrint ("%s A matrix must be specified before sumt can be used\n", spacer);
5840 return (ERROR);
5841 }
5842
5843 if (expecting == Expecting(PARAMETER))
5844 {
5845 expecting = Expecting(EQUALSIGN);
5846 }
5847 else
5848 {
5849 if (!strcmp(parmName, "Xxxxxxxxxx"))
5850 {
5851 expecting = Expecting(PARAMETER);
5852 expecting |= Expecting(SEMICOLON);
5853 }
5854 /* set Filename (sumtParams.sumtFileName) ***************************************************/
5855 else if (!strcmp(parmName, "Filename"))
5856 {
5857 if (expecting == Expecting(EQUALSIGN))
5858 {
5859 expecting = Expecting(ALPHA);
5860 readWord = YES;
5861 }
5862 else if (expecting == Expecting(ALPHA))
5863 {
5864 if (strlen(tkn)>99)
5865 {
5866 MrBayesPrint ("%s Maximum allowed length of file name is 99 characters. The given name:\n", spacer);
5867 MrBayesPrint ("%s '%s'\n", spacer,tkn);
5868 MrBayesPrint ("%s has %d characters.\n", spacer,strlen(tkn));
5869 return (ERROR);
5870 }
5871 strcpy (sumtParams.sumtFileName, tkn);
5872 strcpy(sumtParams.sumtOutfile, tkn);
5873 MrBayesPrint ("%s Setting sumt filename and outputname to %s\n", spacer, sumtParams.sumtFileName);
5874 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
5875 }
5876 else
5877 return (ERROR);
5878 }
5879 /* set Relburnin (chainParams.relativeBurnin) ********************************************************/
5880 else if (!strcmp(parmName, "Relburnin"))
5881 {
5882 if (expecting == Expecting(EQUALSIGN))
5883 expecting = Expecting(ALPHA);
5884 else if (expecting == Expecting(ALPHA))
5885 {
5886 if (IsArgValid(tkn, tempStr) == NO_ERROR)
5887 {
5888 if (!strcmp(tempStr, "Yes"))
5889 chainParams.relativeBurnin = YES;
5890 else
5891 chainParams.relativeBurnin = NO;
5892 }
5893 else
5894 {
5895 MrBayesPrint ("%s Invalid argument for Relburnin\n", spacer);
5896 return (ERROR);
5897 }
5898 if (chainParams.relativeBurnin == YES)
5899 MrBayesPrint ("%s Using relative burnin (a fraction of samples discarded).\n", spacer);
5900 else
5901 MrBayesPrint ("%s Using absolute burnin (a fixed number of samples discarded).\n", spacer);
5902 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
5903 }
5904 else
5905 {
5906 return (ERROR);
5907 }
5908 }
5909 /* set Burnin (chainParams.chainBurnIn) ***********************************************************/
5910 else if (!strcmp(parmName, "Burnin"))
5911 {
5912 if (expecting == Expecting(EQUALSIGN))
5913 expecting = Expecting(NUMBER);
5914 else if (expecting == Expecting(NUMBER))
5915 {
5916 sscanf (tkn, "%d", &tempI);
5917 chainParams.chainBurnIn = tempI;
5918 MrBayesPrint ("%s Setting urn-in to %d\n", spacer, chainParams.chainBurnIn);
5919 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
5920 }
5921 else
5922 {
5923 return (ERROR);
5924 }
5925 }
5926 /* set Burninfrac (chainParams.burninFraction) ************************************************************/
5927 else if (!strcmp(parmName, "Burninfrac"))
5928 {
5929 if (expecting == Expecting(EQUALSIGN))
5930 expecting = Expecting(NUMBER);
5931 else if (expecting == Expecting(NUMBER))
5932 {
5933 sscanf (tkn, "%lf", &tempD);
5934 if (tempD < 0.01)
5935 {
5936 MrBayesPrint ("%s Burnin fraction too low (< 0.01)\n", spacer);
5937 return (ERROR);
5938 }
5939 if (tempD > 0.50)
5940 {
5941 MrBayesPrint ("%s Burnin fraction too high (> 0.50)\n", spacer);
5942 return (ERROR);
5943 }
5944 chainParams.burninFraction = tempD;
5945 MrBayesPrint ("%s Setting burnin fraction to %.2f\n", spacer, chainParams.burninFraction);
5946 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
5947 }
5948 else
5949 {
5950 return (ERROR);
5951 }
5952 }
5953 /* set Nruns (sumtParams.numRuns) *******************************************************/
5954 else if (!strcmp(parmName, "Nruns"))
5955 {
5956 if (expecting == Expecting(EQUALSIGN))
5957 expecting = Expecting(NUMBER);
5958 else if (expecting == Expecting(NUMBER))
5959 {
5960 sscanf (tkn, "%d", &tempI);
5961 if (tempI < 1)
5962 {
5963 MrBayesPrint ("%s Nruns must be at least 1\n", spacer);
5964 return (ERROR);
5965 }
5966 else
5967 {
5968 sumtParams.numRuns = tempI;
5969 MrBayesPrint ("%s Setting sumt nruns to %d\n", spacer, sumtParams.numRuns);
5970 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
5971 }
5972 }
5973 else
5974 return (ERROR);
5975 }
5976 /* set Ntrees (sumtParams.numTrees) *******************************************************/
5977 else if (!strcmp(parmName, "Ntrees"))
5978 {
5979 if (expecting == Expecting(EQUALSIGN))
5980 expecting = Expecting(NUMBER);
5981 else if (expecting == Expecting(NUMBER))
5982 {
5983 sscanf (tkn, "%d", &tempI);
5984 if (tempI < 1)
5985 {
5986 MrBayesPrint ("%s Ntrees must be at least 1\n", spacer);
5987 return (ERROR);
5988 }
5989 else
5990 {
5991 sumtParams.numTrees = tempI;
5992 MrBayesPrint ("%s Setting sumt ntrees to %d\n", spacer, sumtParams.numTrees);
5993 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
5994 }
5995 }
5996 else
5997 return (ERROR);
5998 }
5999 /* set Contype (sumtParams.sumtConType) *****************************************************/
6000 else if (!strcmp(parmName, "Contype"))
6001 {
6002 if (expecting == Expecting(EQUALSIGN))
6003 expecting = Expecting(ALPHA);
6004 else if (expecting == Expecting(ALPHA))
6005 {
6006 if (IsArgValid(tkn, tempStr) == NO_ERROR)
6007 {
6008 strcpy (sumtParams.sumtConType, tempStr);
6009 MrBayesPrint ("%s Setting sumt contype to %s\n", spacer, sumtParams.sumtConType);
6010 }
6011 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
6012 }
6013 else
6014 return (ERROR);
6015 }
6016 /* set Conformat (sumtParams.consensusFormat) *****************************************************/
6017 else if (!strcmp(parmName, "Conformat"))
6018 {
6019 if (expecting == Expecting(EQUALSIGN))
6020 expecting = Expecting(ALPHA);
6021 else if (expecting == Expecting(ALPHA))
6022 {
6023 if (IsArgValid(tkn, tempStr) == NO_ERROR)
6024 {
6025 if (!strcmp(tempStr,"Figtree"))
6026 {
6027 MrBayesPrint ("%s Setting sumt conformat to Figtree\n", spacer);
6028 sumtParams.consensusFormat = FIGTREE;
6029 }
6030 else
6031 {
6032 MrBayesPrint ("%s Setting sumt conformat to Simple\n", spacer);
6033 sumtParams.consensusFormat = SIMPLE;
6034 }
6035 }
6036 else
6037 {
6038 MrBayesPrint ("%s Invalid argument for calctreeprobs\n", spacer);
6039 return (ERROR);
6040 }
6041 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
6042 }
6043 else
6044 return (ERROR);
6045 }
6046 /* set Calctreeprobs (sumtParams.calcTreeprobs) *********************************************/
6047 else if (!strcmp(parmName, "Calctreeprobs"))
6048 {
6049 if (expecting == Expecting(EQUALSIGN))
6050 expecting = Expecting(ALPHA);
6051 else if (expecting == Expecting(ALPHA))
6052 {
6053 if (IsArgValid(tkn, tempStr) == NO_ERROR)
6054 {
6055 if (!strcmp(tempStr, "Yes"))
6056 sumtParams.calcTreeprobs = YES;
6057 else
6058 sumtParams.calcTreeprobs = NO;
6059 }
6060 else
6061 {
6062 MrBayesPrint ("%s Invalid argument for calctreeprobs\n", spacer);
6063 return (ERROR);
6064 }
6065 if (sumtParams.calcTreeprobs == YES)
6066 MrBayesPrint ("%s Setting calctreeprobs to yes\n", spacer);
6067 else
6068 MrBayesPrint ("%s Setting calctreeprobs to no\n", spacer);
6069 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
6070 }
6071 else
6072 return (ERROR);
6073 }
6074 /* set Showtreeprobs (sumtParams.showSumtTrees) *********************************************/
6075 else if (!strcmp(parmName, "Showtreeprobs"))
6076 {
6077 if (expecting == Expecting(EQUALSIGN))
6078 expecting = Expecting(ALPHA);
6079 else if (expecting == Expecting(ALPHA))
6080 {
6081 if (IsArgValid(tkn, tempStr) == NO_ERROR)
6082 {
6083 if (!strcmp(tempStr, "Yes"))
6084 sumtParams.showSumtTrees = YES;
6085 else
6086 sumtParams.showSumtTrees = NO;
6087 }
6088 else
6089 {
6090 MrBayesPrint ("%s Invalid argument for showtreeprobs\n", spacer);
6091 return (ERROR);
6092 }
6093 if (sumtParams.showSumtTrees == YES)
6094 MrBayesPrint ("%s Setting showtreeprobs to yes\n", spacer);
6095 else
6096 MrBayesPrint ("%s Setting showtreeprobs to no\n", spacer);
6097 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
6098 }
6099 else
6100 return (ERROR);
6101 }
6102 /* set Hpd (sumpParams.HPD) ********************************************************/
6103 else if (!strcmp(parmName, "Hpd"))
6104 {
6105 if (expecting == Expecting(EQUALSIGN))
6106 expecting = Expecting(ALPHA);
6107 else if (expecting == Expecting(ALPHA))
6108 {
6109 if (IsArgValid(tkn, tempStr) == NO_ERROR)
6110 {
6111 if (!strcmp(tempStr, "Yes"))
6112 sumtParams.HPD = YES;
6113 else
6114 sumtParams.HPD = NO;
6115 }
6116 else
6117 {
6118 MrBayesPrint ("%s Invalid argument for Hpd\n", spacer);
6119 return (ERROR);
6120 }
6121 if (sumtParams.HPD == YES)
6122 MrBayesPrint ("%s Reporting 95 %% region of Highest Posterior Density (HPD).\n", spacer);
6123 else
6124 MrBayesPrint ("%s Reporting median interval containing 95 %% of values.\n", spacer);
6125 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
6126 }
6127 else
6128 return (ERROR);
6129 }
6130 /* set Savebrparams (sumtParams.saveBrParams) *********************************************/
6131 else if (!strcmp(parmName, "Savebrparams"))
6132 {
6133 if (expecting == Expecting(EQUALSIGN))
6134 expecting = Expecting(ALPHA);
6135 else if (expecting == Expecting(ALPHA))
6136 {
6137 if (IsArgValid(tkn, tempStr) == NO_ERROR)
6138 {
6139 if (!strcmp(tempStr, "Yes"))
6140 sumtParams.saveBrParams = YES;
6141 else
6142 sumtParams.saveBrParams = NO;
6143 }
6144 else
6145 {
6146 MrBayesPrint ("%s Invalid argument for savebrparams\n", spacer);
6147 return (ERROR);
6148 }
6149 if (sumtParams.saveBrParams == YES)
6150 MrBayesPrint ("%s Setting savebrparams to yes\n", spacer);
6151 else
6152 MrBayesPrint ("%s Setting savebrparams to no\n", spacer);
6153 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
6154 }
6155 else
6156 return (ERROR);
6157 }
6158 /* set Minbrparamfreq (sumtParams.minBrParamFreq) *******************************************************/
6159 else if (!strcmp(parmName, "Minbrparamfreq"))
6160 {
6161 if (expecting == Expecting(EQUALSIGN))
6162 expecting = Expecting(NUMBER);
6163 else if (expecting == Expecting(NUMBER))
6164 {
6165 sscanf (tkn, "%lf", &tempD);
6166 sumtParams.minBrParamFreq = tempD;
6167 MrBayesPrint ("%s Printing branch parameters to file for partitions with probability >= %lf\n", spacer, sumtParams.minBrParamFreq);
6168 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
6169 }
6170 else
6171 return (ERROR);
6172 }
6173 /* set Ordertaxa (sumtParams.orderTaxa) *********************************************/
6174 else if (!strcmp(parmName, "Ordertaxa"))
6175 {
6176 if (expecting == Expecting(EQUALSIGN))
6177 expecting = Expecting(ALPHA);
6178 else if (expecting == Expecting(ALPHA))
6179 {
6180 if (IsArgValid(tkn, tempStr) == NO_ERROR)
6181 {
6182 if (!strcmp(tempStr, "Yes"))
6183 sumtParams.orderTaxa = YES;
6184 else
6185 sumtParams.orderTaxa = NO;
6186 }
6187 else
6188 {
6189 MrBayesPrint ("%s Invalid argument for ordertaxa\n", spacer);
6190 return (ERROR);
6191 }
6192 if (sumtParams.orderTaxa == YES)
6193 MrBayesPrint ("%s Setting ordertaxa to yes\n", spacer);
6194 else
6195 MrBayesPrint ("%s Setting ordertaxa to no\n", spacer);
6196 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
6197 }
6198 else
6199 return (ERROR);
6200 }
6201 /* set Outputname (sumtParams.sumtOutfile) *******************************************************/
6202 else if (!strcmp(parmName, "Outputname"))
6203 {
6204 if (expecting == Expecting(EQUALSIGN))
6205 {
6206 expecting = Expecting(ALPHA);
6207 readWord = YES;
6208 }
6209 else if (expecting == Expecting(ALPHA))
6210 {
6211 sscanf (tkn, "%s", tempStr);
6212 strcpy (sumtParams.sumtOutfile, tempStr);
6213 MrBayesPrint ("%s Setting sumt output file name to \"%s\"\n", spacer, sumtParams.sumtOutfile);
6214 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
6215 }
6216 else
6217 return (ERROR);
6218 }
6219 /* set Table (sumtParams.table) ********************************************************/
6220 else if (!strcmp(parmName, "Table"))
6221 {
6222 if (expecting == Expecting(EQUALSIGN))
6223 expecting = Expecting(ALPHA);
6224 else if (expecting == Expecting(ALPHA))
6225 {
6226 if (IsArgValid(tkn, tempStr) == NO_ERROR)
6227 {
6228 if (!strcmp(tempStr, "Yes"))
6229 sumtParams.table = YES;
6230 else
6231 sumtParams.table = NO;
6232 }
6233 else
6234 {
6235 MrBayesPrint ("%s Invalid argument for Table (valid arguments are 'yes' and 'no')\n", spacer);
6236 return (ERROR);
6237 }
6238 if (sumtParams.table == YES)
6239 MrBayesPrint ("%s Setting sumt to compute table of partition frequencies\n", spacer);
6240 else
6241 MrBayesPrint ("%s Setting sumt not to compute table of partition frequencies\n", spacer);
6242 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
6243 }
6244 else
6245 return (ERROR);
6246 }
6247 /* set Summary (sumtParams.summary) ********************************************************/
6248 else if (!strcmp(parmName, "Summary"))
6249 {
6250 if (expecting == Expecting(EQUALSIGN))
6251 expecting = Expecting(ALPHA);
6252 else if (expecting == Expecting(ALPHA))
6253 {
6254 if (IsArgValid(tkn, tempStr) == NO_ERROR)
6255 {
6256 if (!strcmp(tempStr, "Yes"))
6257 sumtParams.summary = YES;
6258 else
6259 sumtParams.summary = NO;
6260 }
6261 else
6262 {
6263 MrBayesPrint ("%s Invalid argument for 'Summary' (valid arguments are 'yes' and 'no')\n", spacer);
6264 return (ERROR);
6265 }
6266 if (sumtParams.summary == YES)
6267 MrBayesPrint ("%s Setting sumt to summary statistics\n", spacer);
6268 else
6269 MrBayesPrint ("%s Setting sumt not to compute summary statistics\n", spacer);
6270 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
6271 }
6272 else
6273 return (ERROR);
6274 }
6275 /* set Consensus (sumtParams.showConsensus) ********************************************************/
6276 else if (!strcmp(parmName, "Consensus"))
6277 {
6278 if (expecting == Expecting(EQUALSIGN))
6279 expecting = Expecting(ALPHA);
6280 else if (expecting == Expecting(ALPHA))
6281 {
6282 if (IsArgValid(tkn, tempStr) == NO_ERROR)
6283 {
6284 if (!strcmp(tempStr, "Yes"))
6285 sumtParams.showConsensus = YES;
6286 else
6287 sumtParams.showConsensus = NO;
6288 }
6289 else
6290 {
6291 MrBayesPrint ("%s Invalid argument for Consensus (valid arguments are 'yes' and 'no')\n", spacer);
6292 return (ERROR);
6293 }
6294 if (sumtParams.showConsensus == YES)
6295 MrBayesPrint ("%s Setting sumt to show consensus trees\n", spacer);
6296 else
6297 MrBayesPrint ("%s Setting sumt not to show consensus trees\n", spacer);
6298 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
6299 }
6300 else
6301 return (ERROR);
6302 }
6303 /* set Minpartfreq (sumtParams.minPartFreq) *******************************************************/
6304 else if (!strcmp(parmName, "Minpartfreq"))
6305 {
6306 if (expecting == Expecting(EQUALSIGN))
6307 expecting = Expecting(NUMBER);
6308 else if (expecting == Expecting(NUMBER))
6309 {
6310 sscanf (tkn, "%lf", &tempD);
6311 sumtParams.minPartFreq = tempD;
6312 MrBayesPrint ("%s Including partitions with probability greater than or equal to %lf in summary statistics\n", spacer, sumtParams.minPartFreq);
6313 expecting = Expecting(PARAMETER) | Expecting(SEMICOLON);
6314 }
6315 else
6316 return (ERROR);
6317 }
6318 else
6319 return (ERROR);
6320 }
6321
6322 return (NO_ERROR);
6323 }
6324
6325
DoSumtTree(void)6326 int DoSumtTree (void)
6327 {
6328 int i, j, z, printEvery, nAstPerPrint, burnin;
6329 MrBFlt x, y;
6330 PolyTree *t;
6331 PolyNode *p;
6332
6333 # if defined (PRINT_RATEMUL_CPP)
6334 /* get depths if relevant */
6335 if (sumtParams.tree->isClock)
6336 GetPolyDepths (sumtParams.tree);
6337 if (rateMultfp !=NULL && sumtParams.tree->root !=NULL)
6338 DELETE_ME_dump_depth(sumtParams.tree->root);
6339 # endif
6340
6341 /* increment number of trees read in */
6342 sumtParams.numFileTrees[sumtParams.runId]++;
6343 sumtParams.numTreesEncountered++;
6344
6345 /* update status bar */
6346 if (sumtParams.numTreesInLastBlock * sumtParams.numRuns < 80)
6347 {
6348 printEvery = 1;
6349 nAstPerPrint = 80 / (sumtParams.numTreesInLastBlock * sumtParams.numRuns);
6350 if (sumtParams.numTreesEncountered % printEvery == 0)
6351 {
6352 for (i=0; i<nAstPerPrint; i++)
6353 {
6354 MrBayesPrint ("*");
6355 numAsterices++;
6356 }
6357 }
6358 }
6359 else
6360 {
6361 x = (MrBFlt)(sumtParams.numTreesInLastBlock * sumtParams.numRuns) / (MrBFlt) (80);
6362 y = (MrBFlt)(sumtParams.numFileTrees[sumtParams.runId] + sumtParams.numTreesInLastBlock * sumtParams.runId) / x;
6363 z = (int)y;
6364 if (numAsterices < z)
6365 {
6366 MrBayesPrint ("*");
6367 numAsterices++;
6368 }
6369 }
6370
6371 /* get burnin */
6372 if (inComparetreeCommand == YES)
6373 burnin = comptreeParams.burnin;
6374 else
6375 burnin = sumtParams.burnin;
6376
6377 if (sumtParams.numFileTrees[sumtParams.runId] > burnin)
6378 {
6379 /* increment the number of trees sampled */
6380 sumtParams.numFileTreesSampled[sumtParams.runId]++;
6381 sumtParams.numTreesSampled++;
6382
6383 /* get the tree we just read in */
6384 t = sumtParams.tree;
6385
6386 /* move calculation root for nonrooted trees if necessary */
6387 MovePolyCalculationRoot (t, localOutGroup);
6388
6389 /* check taxon set and outgroup */
6390 if (sumtParams.runId == 0 && sumtParams.numFileTreesSampled[0] == 1)
6391 {
6392 if (isTranslateDef == YES && isTranslateDiff == YES)
6393 {
6394 /* we are using a translate block with different taxa set (not all taxa) */
6395 if (t->nNodes - t->nIntNodes != numTranslates)
6396 {
6397 MrBayesPrint ("%s ERROR: Expected %d taxa; found %d taxa\n", spacer, numTranslates, sumtParams.numTaxa);
6398 return (ERROR);
6399 }
6400 /* figure out which taxa are absent */
6401 for (i=0; i<numTaxa; i++)
6402 sumtParams.absentTaxa[i] = YES;
6403 for (i=0; i<numTranslates; i++)
6404 {
6405 for (j=0; j<numTaxa; j++)
6406 {
6407 if (strcmp(transFrom[i], taxaNames[j]) == 0)
6408 break;
6409 }
6410 if (j < numTaxa)
6411 sumtParams.absentTaxa[j] = NO;
6412 }
6413 /* find local outgroup */
6414 for (i=0; i<numTranslates; i++)
6415 if (strcmp(transFrom[i], taxaNames[outGroupNum]) == 0)
6416 break;
6417 if (i == numTranslates)
6418 localOutGroup = 0; /* no previous outgroup assignment is valid */
6419 else
6420 localOutGroup = i;
6421 }
6422 else
6423 {
6424 /* we are using the current taxa set */
6425 for (i=0; i<numTaxa; i++)
6426 sumtParams.absentTaxa[i] = YES;
6427 for (i=0; i<t->nNodes; i++)
6428 {
6429 p = t->allDownPass[i];
6430 if (p->left == NULL)
6431 sumtParams.absentTaxa[p->index] = NO;
6432 }
6433 localOutGroup = 0;
6434 for (i=j=0; i<numTaxa; i++)
6435 {
6436 if (sumtParams.absentTaxa[i] == NO && taxaInfo[i].isDeleted == NO)
6437 {
6438 if (i == outGroupNum)
6439 localOutGroup = j;
6440 j++;
6441 }
6442 }
6443 }
6444
6445 /* now we can safely prune the tree based on taxaInfo[].isDeleted */
6446 /* note that PrunePolyTree relies on labels to recognize tips */
6447 PrunePolyTree(t);
6448
6449 /* reset tip and int node indices in case some taxa deleted */
6450 ResetTipIndices (t);
6451 ResetIntNodeIndices(t);
6452
6453 /* set basic parameters */
6454 sumtParams.numTaxa = t->nNodes - t->nIntNodes;
6455 numLocalTaxa = sumtParams.numTaxa;
6456 sumtParams.BitsLongsNeeded = ((numLocalTaxa-1) / nBitsInALong) + 1;
6457 if (t->isRooted == YES)
6458 sumtParams.orderLen = numLocalTaxa - 2;
6459 else
6460 sumtParams.orderLen = numLocalTaxa - 3;
6461 }
6462 else
6463 {
6464 /* check whether we have some taxa that should not be in the tree */
6465 for (i=0; i<t->nNodes; i++)
6466 {
6467 p = t->allDownPass[i];
6468 if (p->left == NULL && taxaInfo[p->index].isDeleted == NO && sumtParams.absentTaxa[p->index] == YES)
6469 {
6470 MrBayesPrint ("%s Taxon %d should not be in sampled tree\n", spacer, p->index + 1);
6471 return (ERROR);
6472 }
6473 }
6474
6475 /* now we can safely prune the tree based on taxaInfo[].isDeleted */
6476 PrunePolyTree (t);
6477
6478 /* reset tip and int node indices in case some taxa deleted */
6479 ResetTipIndices (t);
6480 ResetIntNodeIndices(t);
6481
6482 /* check that all taxa are included */
6483 if (t->nNodes - t->nIntNodes != sumtParams.numTaxa)
6484 {
6485 MrBayesPrint ("%s Expecting %d taxa but tree '%s' in file '%s' has %d taxa\n",
6486 spacer, sumtParams.numTaxa, t->name, sumtParams.curFileName, t->nNodes-t->nIntNodes);
6487 return ERROR;
6488 }
6489 }
6490
6491 if (sumtParams.runId == 0 && sumtParams.numFileTreesSampled[0] == 1)
6492 {
6493 /* harvest labels (can only be done safely after pruning) */
6494 for (i=0; i<sumtParams.numTaxa; i++)
6495 {
6496 for (j=0; j<t->nNodes; j++)
6497 {
6498 p = t->allDownPass[j];
6499 if (p->index == i) {
6500 if (strlen(p->label)>99)
6501 {
6502 MrBayesPrint ("%s Taxon name %s is too long. Maximun 99 characters is allowed.\n", spacer, p->label);
6503 return (ERROR);
6504 }
6505 AddString(&sumtParams.taxaNames, i, p->label);
6506 }
6507 }
6508 }
6509 }
6510
6511 /* check that tree agrees with template */
6512 if (sumtParams.numTreesSampled == 1)
6513 {
6514 sumtParams.brlensDef = t->brlensDef;
6515 sumtParams.isRooted = t->isRooted;
6516 sumtParams.isClock = t->isClock;
6517 sumtParams.isCalibrated = t->isCalibrated;
6518 sumtParams.isRelaxed = t->isRelaxed;
6519 sumtParams.nBSets = 0;
6520 sumtParams.nESets = 0;
6521 for (i=0; i<t->nBSets; i++)
6522 AddString(&sumtParams.bSetName,sumtParams.nBSets++,t->bSetName[i]);
6523 for (i=0; i<t->nESets; i++)
6524 AddString(&sumtParams.eSetName,sumtParams.nESets++,t->eSetName[i]);
6525 if (t->popSizeSet == YES)
6526 {
6527 sumtParams.popSizeSet = YES;
6528 sumtParams.popSizeSetName = (char *) SafeCalloc (strlen(t->popSizeSetName)+1, sizeof(char));
6529 strcpy(sumtParams.popSizeSetName, t->popSizeSetName);
6530 }
6531 else
6532 sumtParams.popSizeSet = NO;
6533 }
6534 else /* if (sumtParams.numTreesSampled > 1) */
6535 {
6536 if (sumtParams.brlensDef != t->brlensDef)
6537 {
6538 MrBayesPrint ("%s Trees with and without branch lengths mixed\n", spacer);
6539 return ERROR;
6540 }
6541 if (sumtParams.isRooted != t->isRooted)
6542 {
6543 if (sumtParams.isRooted == YES)
6544 MrBayesPrint ("%s Expected rooted tree but tree '%s' in file '%s' is not rooted\n",
6545 spacer, t->name, sumtParams.curFileName);
6546 else if (sumtParams.isRooted == NO)
6547 MrBayesPrint ("%s Expected unrooted tree but tree '%s' in file '%s' is rooted\n",
6548 spacer, t->name, sumtParams.curFileName);
6549 return ERROR;
6550 }
6551 if (sumtParams.isClock != t->isClock)
6552 {
6553 if (sumtParams.isClock == YES)
6554 MrBayesPrint ("%s Expected clock tree but tree '%s' in file '%s' is not clock\n",
6555 spacer, t->name, sumtParams.curFileName);
6556 else if (sumtParams.isClock == NO)
6557 MrBayesPrint ("%s Expected nonclock tree but tree '%s' in file '%s' is clock\n",
6558 spacer, t->name, sumtParams.curFileName);
6559 return ERROR;
6560 }
6561 if (sumtParams.isCalibrated != t->isCalibrated)
6562 {
6563 if (sumtParams.isCalibrated == YES)
6564 MrBayesPrint ("%s Expected calibrated tree but tree '%s' in file '%s' is not calibrated\n",
6565 spacer, t->name, sumtParams.curFileName);
6566 else if (sumtParams.isCalibrated == NO)
6567 MrBayesPrint ("%s Expected noncalibrated tree but tree '%s' in file '%s' is calibrated\n",
6568 spacer, t->name, sumtParams.curFileName);
6569 return ERROR;
6570 }
6571 if (inComparetreeCommand == NO && sumtParams.isRelaxed != t->isRelaxed)
6572 {
6573 if (sumtParams.isRelaxed == YES)
6574 MrBayesPrint ("%s Expected relaxed clock tree but tree '%s' in file '%s' is not relaxed\n",
6575 spacer, t->name, sumtParams.curFileName);
6576 else if (sumtParams.isRelaxed == NO)
6577 MrBayesPrint ("%s Expected unrooted tree but tree '%s' in file '%s' is rooted\n",
6578 spacer, t->name, sumtParams.curFileName);
6579 return ERROR;
6580 }
6581 if (inComparetreeCommand == NO && (sumtParams.nESets != t->nESets || sumtParams.nBSets != t->nBSets))
6582 {
6583 MrBayesPrint ("%s Tree '%s' in file '%s' does not have the expected relaxed clock parameters\n",
6584 spacer, t->name, sumtParams.curFileName);
6585 return ERROR;
6586 }
6587 }
6588
6589 /* set partitions for tree */
6590 ResetPolyTreePartitions(t);
6591
6592 /* get depths if relevant */
6593 if (t->isClock)
6594 GetPolyDepths (t);
6595
6596 /* get ages if relevant */
6597 if (t->isCalibrated)
6598 GetPolyAges (t);
6599
6600 /* add partitions to counters */
6601 for (i=0; i<t->nNodes; i++)
6602 {
6603 p = t->allDownPass[i];
6604 partCtrRoot = AddSumtPartition (partCtrRoot, t, p, sumtParams.runId);
6605 }
6606
6607 /* add the tree to relevant tree list */
6608 if (inSumtCommand == YES)
6609 {
6610 if (t->isRooted == YES)
6611 StoreRPolyTopology (t, sumtParams.order);
6612 else /* if (sumtParams.isRooted == NO) */
6613 StoreUPolyTopology (t, sumtParams.order);
6614 treeCtrRoot = AddSumtTree (treeCtrRoot, sumtParams.order);
6615 }
6616 else
6617 {
6618 i = sumtParams.numFileTreesSampled[sumtParams.runId] - 1;
6619 if (StoreSumtTree (packedTreeList[sumtParams.runId], i, t) == ERROR)
6620 return (ERROR);
6621 }
6622
6623 /* Display the tree nodes. */
6624 # if 0
6625 ShowPolyNodes(t);
6626 # endif
6627 }
6628
6629 return (NO_ERROR);
6630 }
6631
6632
ExamineSumtFile(char * fileName,SumtFileInfo * sumtFileInfo,char * treeName,int * brlensDef)6633 int ExamineSumtFile (char *fileName, SumtFileInfo *sumtFileInfo, char *treeName, int *brlensDef)
6634 {
6635 int i, foundBegin, lineTerm, inTreeBlock, blockErrors, inSumtComment, lineNum, numTreesInBlock,
6636 tokenType;
6637 char sumtToken[100], *s, *sumtTokenP;
6638 FILE *fp;
6639
6640 /* open binary file */
6641 if ((fp = OpenBinaryFileR(fileName)) == NULL)
6642 return ERROR;
6643
6644 /* find out what type of line termination is used for file 1 */
6645 lineTerm = LineTermType (fp);
6646 if (lineTerm != LINETERM_MAC && lineTerm != LINETERM_DOS && lineTerm != LINETERM_UNIX)
6647 {
6648 MrBayesPrint ("%s Unknown line termination for file \"%s\"\n", spacer, fileName);
6649 return ERROR;
6650 }
6651
6652 /* find length of longest line in either file */
6653 sumtFileInfo->longestLineLength = LongestLine (fp);
6654 sumtFileInfo->longestLineLength += 10;
6655
6656 /* allocate a string long enough to hold a line */
6657 s = (char *)SafeMalloc((size_t)(sumtFileInfo->longestLineLength) * sizeof(char));
6658 if (!s)
6659 {
6660 MrBayesPrint ("%s Problem allocating string for examining file \"%s\"\n", spacer, fileName);
6661 return (ERROR);
6662 }
6663
6664 /* close binary file */
6665 SafeFclose (&fp);
6666
6667 foundBegin = inTreeBlock = blockErrors = inSumtComment = NO;
6668 lineNum = numTreesInBlock = 0;
6669 sumtFileInfo->numTreeBlocks = 0;
6670 sumtFileInfo->lastTreeBlockBegin = 0;
6671 sumtFileInfo->lastTreeBlockEnd = 0;
6672 sumtFileInfo->numTreesInLastBlock = 0;
6673
6674 /* open text file */
6675 if ((fp = OpenTextFileR(fileName))==NULL)
6676 {
6677 MrBayesPrint ("%s Could not read file \"%s\" in text mode \n", spacer, fileName);
6678 return (ERROR);
6679 }
6680
6681 /* read file */
6682 while (fgets (s, sumtFileInfo->longestLineLength-2, fp) != NULL)
6683 {
6684 sumtTokenP = &s[0];
6685 do
6686 {
6687 if (GetToken (sumtToken, &tokenType, &sumtTokenP))
6688 goto errorExit;
6689 if (IsSame("[", sumtToken) == SAME)
6690 inSumtComment = YES;
6691 if (IsSame("]", sumtToken) == SAME)
6692 inSumtComment = NO;
6693
6694 if (inSumtComment == YES)
6695 {
6696 if (IsSame ("Param", sumtToken) == SAME)
6697 {
6698 /* extract the tree name */
6699 if (GetToken (sumtToken, &tokenType, &sumtTokenP)) /* get the colon */
6700 goto errorExit;
6701 if (GetToken (sumtToken, &tokenType, &sumtTokenP)) /* get the tree name */
6702 goto errorExit;
6703 strcpy (treeName, sumtToken);
6704 if (GetToken (sumtToken, &tokenType, &sumtTokenP))
6705 goto errorExit;
6706 while (IsSame("]", sumtToken) != SAME)
6707 {
6708 strcat (treeName, sumtToken);
6709 if (GetToken (sumtToken, &tokenType, &sumtTokenP))
6710 goto errorExit;
6711 }
6712 inSumtComment = NO;
6713 }
6714 }
6715 else /* if (inSumtComment == NO) */
6716 {
6717 if (foundBegin == YES)
6718 {
6719 if (IsSame("Trees", sumtToken) == SAME)
6720 {
6721 numTreesInBlock = 0;
6722 inTreeBlock = YES;
6723 foundBegin = NO;
6724 sumtFileInfo->lastTreeBlockBegin = lineNum;
6725 }
6726 }
6727 else
6728 {
6729 if (IsSame("Begin", sumtToken) == SAME)
6730 {
6731 if (foundBegin == YES)
6732 {
6733 MrBayesPrint ("%s Found inappropriate \"Begin\" statement in file\n", spacer);
6734 blockErrors = YES;
6735 }
6736 foundBegin = YES;
6737 }
6738 else if (IsSame("End", sumtToken) == SAME)
6739 {
6740 if (inTreeBlock == YES)
6741 {
6742 sumtFileInfo->numTreeBlocks++;
6743 inTreeBlock = NO;
6744 sumtFileInfo->lastTreeBlockEnd = lineNum;
6745 }
6746 else
6747 {
6748 MrBayesPrint ("%s Found inappropriate \"End\" statement in file\n", spacer);
6749 blockErrors = YES;
6750 }
6751 sumtFileInfo->numTreesInLastBlock = numTreesInBlock;
6752 }
6753 else if (IsSame("Tree", sumtToken) == SAME)
6754 {
6755 if (inTreeBlock == YES)
6756 {
6757 numTreesInBlock++;
6758 if (numTreesInBlock == 1)
6759 {
6760 *brlensDef = NO;
6761 for (i=0; s[i]!='\0'; i++)
6762 {
6763 if (s[i] == ':')
6764 {
6765 *brlensDef = YES;
6766 break;
6767 }
6768 }
6769 }
6770 }
6771 else
6772 {
6773 MrBayesPrint ("%s Found a \"Tree\" statement that is not in a tree block\n", spacer);
6774 blockErrors = YES;
6775 }
6776 }
6777 }
6778 }
6779
6780 } while (*sumtToken);
6781 lineNum++;
6782 }
6783
6784 /* Now, check some aspects of the tree file, such as the number of tree blocks and whether they are properly terminated. */
6785 if (inTreeBlock == YES)
6786 {
6787 MrBayesPrint ("%s Unterminated tree block in file %s. You probably need to\n", spacer, fileName);
6788 MrBayesPrint ("%s add a new line to the end of the file with \"End;\" on it.\n", spacer);
6789 goto errorExit;
6790 }
6791 if (inSumtComment == YES)
6792 {
6793 MrBayesPrint ("%s Unterminated comment in file %s\n", spacer, fileName);
6794 goto errorExit;
6795 }
6796 if (blockErrors == YES)
6797 {
6798 MrBayesPrint ("%s Found formatting errors in file %s\n", spacer, fileName);
6799 goto errorExit;
6800 }
6801 if (sumtFileInfo->lastTreeBlockEnd < sumtFileInfo->lastTreeBlockBegin)
6802 {
6803 MrBayesPrint ("%s Problem reading tree file %s\n", spacer, fileName);
6804 goto errorExit;
6805 }
6806 if (sumtFileInfo->numTreesInLastBlock <= 0)
6807 {
6808 MrBayesPrint ("%s No trees were found in last tree block of file %s\n", spacer, fileName);
6809 goto errorExit;
6810 }
6811 free (s);
6812 return (NO_ERROR);
6813
6814 errorExit:
6815 free (s);
6816 return (ERROR);
6817 }
6818
6819
6820 /* FreePartCtr: Recursively free partition counter nodes */
FreePartCtr(PartCtr * r)6821 void FreePartCtr (PartCtr *r)
6822 {
6823 int i, j;
6824
6825 if (r==NULL)
6826 return;
6827
6828 FreePartCtr (r->left);
6829 FreePartCtr (r->right);
6830
6831 /* free relaxed clock parameters: eRate, nEvents, bRate */
6832 if (sumtParams.nESets > 0)
6833 {
6834 for (i=0; i<sumtParams.nESets; i++)
6835 {
6836 for (j=0; j<sumtParams.numRuns; j++)
6837 free (r->nEvents[i][j]);
6838 free (r->nEvents[i]);
6839 }
6840 free (r->nEvents);
6841 }
6842 if (sumtParams.nBSets > 0)
6843 {
6844 for (i=0; i<sumtParams.nBSets; i++)
6845 {
6846 for (j=0; j<sumtParams.numRuns; j++)
6847 {
6848 free (r->bLen [i][j]);
6849 free (r->bRate[i][j]);
6850 }
6851 free (r->bLen [i]);
6852 free (r->bRate[i]);
6853 }
6854 free (r->bLen);
6855 free (r->bRate);
6856 }
6857
6858 /* free basic parameters */
6859 for (i=0; i<sumtParams.numRuns; i++)
6860 free (r->length[i]);
6861
6862 free (r->length);
6863 free (r->count);
6864 free (r->partition);
6865 free (r);
6866 numUniqueSplitsFound--;
6867 r = NULL;
6868 }
6869
6870
6871 /* FreeSumtParams: Free parameters allocated in sumtParams struct */
FreeSumtParams(void)6872 void FreeSumtParams(void)
6873 {
6874 int i;
6875
6876 if (memAllocs[ALLOC_SUMTPARAMS] == YES)
6877 {
6878 for (i=0; i<sumtParams.numTaxa; i++)
6879 free(sumtParams.taxaNames[i]);
6880 free (sumtParams.taxaNames);
6881 sumtParams.taxaNames = NULL;
6882 if (sumtParams.numFileTrees) free (sumtParams.numFileTrees);
6883 sumtParams.numFileTrees = NULL;
6884 FreePolyTree (sumtParams.tree);
6885 sumtParams.tree = NULL;
6886 if (sumtParams.nBSets > 0)
6887 {
6888 for (i=0; i<sumtParams.nBSets; i++)
6889 free(sumtParams.bSetName[i]);
6890 free (sumtParams.bSetName);
6891 sumtParams.bSetName = NULL;
6892 sumtParams.nBSets = 0;
6893 }
6894 if (sumtParams.nESets > 0)
6895 {
6896 for (i=0; i<sumtParams.nESets; i++)
6897 free(sumtParams.eSetName[i]);
6898 free (sumtParams.eSetName);
6899 sumtParams.eSetName = NULL;
6900 sumtParams.nESets = 0;
6901 }
6902 if (sumtParams.popSizeSet == YES)
6903 {
6904 free (sumtParams.popSizeSetName);
6905 sumtParams.popSizeSetName = NULL;
6906 sumtParams.popSizeSet = NO;
6907 }
6908 memAllocs[ALLOC_SUMTPARAMS] = NO;
6909 }
6910 }
6911
6912
6913 /* FreeTreeCtr: Recursively free tree counter nodes */
FreeTreeCtr(TreeCtr * r)6914 void FreeTreeCtr (TreeCtr *r)
6915 {
6916 if (r==NULL)
6917 return;
6918
6919 FreeTreeCtr (r->left);
6920 FreeTreeCtr (r->right);
6921
6922 free (r->order);
6923 free (r);
6924 numUniqueTreesFound--;
6925 r = NULL;
6926 }
6927
6928
6929 /* Label: Calculate length of label and fill in char *label if not NULL */
Label(PolyNode * p,int addIndex,char * label,int maxLength)6930 int Label (PolyNode *p, int addIndex, char *label, int maxLength)
6931 {
6932 int i, j0, j1, k, n, length, nameLength, index;
6933
6934 if (p == NULL)
6935 return 0;
6936
6937 /* first calculate length */
6938 if (inSumtCommand == YES && isTranslateDiff == NO)
6939 {
6940 for (index=i=0; index<numTaxa; index++)
6941 {
6942 if (sumtParams.absentTaxa[index] == YES || taxaInfo[index].isDeleted == YES)
6943 continue;
6944 if (p->index == i)
6945 break;
6946 else
6947 i++;
6948 }
6949 }
6950 else
6951 index = p->index;
6952
6953 if (addIndex != NO)
6954 length = (int)(strlen(p->label)) + 4 + (int)(log10(index+1));
6955 else
6956 length = (int)(strlen(p->label));
6957 length = (length > maxLength ? maxLength : length);
6958
6959 /* fill in label if label != NULL */
6960 if (label != NULL)
6961 {
6962 if (addIndex != NO)
6963 nameLength = length - 4 - (int)(log10(index+1));
6964 else
6965 nameLength = length;
6966
6967 for (i=0; i<nameLength-1; i++)
6968 label[i] = p->label[i];
6969 if ((int)strlen(p->label) > nameLength)
6970 label[i] = '~';
6971 else
6972 label[i] = p->label[i];
6973
6974 if (addIndex != NO)
6975 {
6976 label[++i] = ' ';
6977 label[++i] = '(';
6978 n = index + 1;
6979 k = (int)(log10(n)) + 1;
6980 while (n != 0)
6981 {
6982 j0 = (int)(log10(n));
6983 j1 = (int)(pow(10,j0));
6984 label[++i] = '0' + n/j1;
6985 n = n % j1;
6986 k--;
6987 }
6988 while (k!=0)
6989 {
6990 label[++i] = '0';
6991 k--;
6992 }
6993 label[++i] = ')';
6994 }
6995 label[++i] = '\0';
6996 }
6997
6998 return length;
6999 }
7000
7001
OpenComptFiles(void)7002 int OpenComptFiles (void)
7003 {
7004 int len, previousFiles, oldNoWarn, oldAutoOverwrite;
7005 char pFilename[120], dFilename[120];
7006 FILE *fpTemp;
7007
7008 oldNoWarn = noWarn;
7009 oldAutoOverwrite = autoOverwrite;
7010
7011 /* set file names */
7012 strcpy (pFilename, comptreeParams.comptOutfile);
7013 strcpy (dFilename, comptreeParams.comptOutfile);
7014 strcat (pFilename, ".pairs");
7015 strcat (dFilename, ".dists");
7016
7017 /* one overwrite check for both files */
7018 previousFiles = NO;
7019 if (noWarn == NO)
7020 {
7021 if ((fpTemp = OpenTextFileR(pFilename)) != NULL)
7022 {
7023 previousFiles = YES;
7024 fclose(fpTemp);
7025 }
7026 if ((fpTemp = OpenTextFileR(dFilename)) != NULL)
7027 {
7028 previousFiles = YES;
7029 fclose(fpTemp);
7030 }
7031 if (previousFiles == YES)
7032 {
7033 MrBayesPrint("%s There are previous compare results saved using the same filenames.\n", spacer);
7034 if (WantTo("Do you want to overwrite these results") == YES)
7035 {
7036 MrBayesPrint("\n");
7037 noWarn = YES;
7038 autoOverwrite = YES;
7039 }
7040 else
7041 {
7042 MrBayesPrint("\n");
7043 MrBayesPrint("%s Please specify a different output file name before running the comparetree command.\n", spacer);
7044 MrBayesPrint("%s You can do that using 'comparetree outputfile=<name>'. You can also move or\n", spacer);
7045 MrBayesPrint("%s rename the old result files.\n", spacer);
7046 return ERROR;
7047 }
7048 }
7049 }
7050
7051 if ((fpParts = OpenNewMBPrintFile (pFilename)) == NULL)
7052 {
7053 noWarn = oldNoWarn;
7054 autoOverwrite = oldAutoOverwrite;
7055 return ERROR;
7056 }
7057 if ((fpDists = OpenNewMBPrintFile (dFilename)) == NULL)
7058 {
7059 noWarn = oldNoWarn;
7060 autoOverwrite = oldAutoOverwrite;
7061 return ERROR;
7062 }
7063
7064 /* Reset file flags */
7065 noWarn = oldNoWarn;
7066 autoOverwrite = oldAutoOverwrite;
7067
7068 /* print unique identifiers to each file */
7069 len = (int) strlen (stamp);
7070 if (len > 1)
7071 {
7072 MrBayesPrintf (fpParts, "[ID: %s]\n", stamp);
7073 MrBayesPrintf (fpDists, "[ID: %s]\n", stamp);
7074 }
7075
7076 return (NO_ERROR);
7077 }
7078
7079
OpenSumtFiles(int treeNo)7080 int OpenSumtFiles (int treeNo)
7081 {
7082 int i, len, oldNoWarn, oldAutoOverwrite, previousFiles;
7083 char pFilename[145], sFilename[145], vFilename[145], cFilename[145], tFilename[145];
7084 FILE *fpTemp;
7085
7086 oldNoWarn = noWarn;
7087 oldAutoOverwrite = autoOverwrite;
7088
7089 /* one overwrite check for all files */
7090 if (noWarn == NO && treeNo == 0)
7091 {
7092 previousFiles = NO;
7093 for (i=0; i<sumtParams.numTrees; i++)
7094 {
7095 if (sumtParams.numTrees > 1)
7096 {
7097 sprintf (pFilename, "%s.tree%d.parts", sumtParams.sumtOutfile, i+1);
7098 sprintf (sFilename, "%s.tree%d.tstat", sumtParams.sumtOutfile, i+1);
7099 sprintf (vFilename, "%s.tree%d.vstat", sumtParams.sumtOutfile, i+1);
7100 sprintf (cFilename, "%s.tree%d.con.tre", sumtParams.sumtOutfile, i+1);
7101 sprintf (tFilename, "%s.tree%d.trprobs", sumtParams.sumtOutfile, i+1);
7102 }
7103 else
7104 {
7105 sprintf (pFilename, "%s.parts", sumtParams.sumtOutfile);
7106 sprintf (sFilename, "%s.tstat", sumtParams.sumtOutfile);
7107 sprintf (vFilename, "%s.vstat", sumtParams.sumtOutfile);
7108 sprintf (cFilename, "%s.con.tre", sumtParams.sumtOutfile);
7109 sprintf (tFilename, "%s.trprobs", sumtParams.sumtOutfile);
7110 }
7111 if ((fpTemp = TestOpenTextFileR(pFilename)) != NULL)
7112 {
7113 previousFiles = YES;
7114 fclose(fpTemp);
7115 }
7116 if ((fpTemp = TestOpenTextFileR(sFilename)) != NULL)
7117 {
7118 previousFiles = YES;
7119 fclose(fpTemp);
7120 }
7121 if ((fpTemp = TestOpenTextFileR(vFilename)) != NULL)
7122 {
7123 previousFiles = YES;
7124 fclose(fpTemp);
7125 }
7126 if ((fpTemp = TestOpenTextFileR(cFilename)) != NULL)
7127 {
7128 previousFiles = YES;
7129 fclose(fpTemp);
7130 }
7131 if ((fpTemp = TestOpenTextFileR(tFilename)) != NULL)
7132 {
7133 previousFiles = YES;
7134 fclose(fpTemp);
7135 }
7136 if (previousFiles == YES)
7137 {
7138 MrBayesPrint("\n");
7139 MrBayesPrint("%s There are previous tree sample summaries saved using the same filenames.\n", spacer);
7140 if (WantTo("Do you want to overwrite these results") == YES)
7141 {
7142 MrBayesPrint("\n");
7143 noWarn = YES;
7144 autoOverwrite = YES;
7145 }
7146 else
7147 {
7148 MrBayesPrint("\n");
7149 MrBayesPrint("%s Please specify a different output file name before running the sumt command.\n", spacer);
7150 MrBayesPrint("%s You can do that using 'sumt outputfile=<name>'. You can also move or\n", spacer);
7151 MrBayesPrint("%s rename the old result files.\n", spacer);
7152 return ERROR;
7153 }
7154 }
7155 }
7156 }
7157
7158 /* set file names */
7159 if (sumtParams.numTrees > 1)
7160 {
7161 sprintf (pFilename, "%s.tree%d.parts", sumtParams.sumtOutfile, treeNo+1);
7162 sprintf (sFilename, "%s.tree%d.tstat", sumtParams.sumtOutfile, treeNo+1);
7163 sprintf (vFilename, "%s.tree%d.vstat", sumtParams.sumtOutfile, treeNo+1);
7164 sprintf (cFilename, "%s.tree%d.con.tre", sumtParams.sumtOutfile, treeNo+1);
7165 sprintf (tFilename, "%s.tree%d.trprobs", sumtParams.sumtOutfile, treeNo+1);
7166 }
7167 else
7168 {
7169 sprintf (pFilename, "%s.parts", sumtParams.sumtOutfile);
7170 sprintf (sFilename, "%s.tstat", sumtParams.sumtOutfile);
7171 sprintf (vFilename, "%s.vstat", sumtParams.sumtOutfile);
7172 sprintf (cFilename, "%s.con.tre", sumtParams.sumtOutfile);
7173 sprintf (tFilename, "%s.trprobs", sumtParams.sumtOutfile);
7174 }
7175
7176 /* open files checking for over-write as appropriate */
7177 if ((fpParts = OpenNewMBPrintFile(pFilename)) == NULL)
7178 return ERROR;
7179 if ((fpTstat = OpenNewMBPrintFile(sFilename)) == NULL)
7180 {
7181 SafeFclose (&fpParts);
7182 return ERROR;
7183 }
7184 if ((fpVstat = OpenNewMBPrintFile(vFilename)) == NULL)
7185 {
7186 SafeFclose (&fpParts);
7187 SafeFclose (&fpTstat);
7188 return ERROR;
7189 }
7190 if ((fpCon = OpenNewMBPrintFile(cFilename)) == NULL)
7191 {
7192 SafeFclose (&fpParts);
7193 SafeFclose (&fpTstat);
7194 SafeFclose (&fpVstat);
7195 return ERROR;
7196 }
7197 if (sumtParams.calcTreeprobs == YES)
7198 {
7199 if ((fpTrees = OpenNewMBPrintFile(tFilename)) == NULL)
7200 {
7201 SafeFclose (&fpParts);
7202 SafeFclose (&fpTstat);
7203 SafeFclose (&fpVstat);
7204 SafeFclose (&fpCon);
7205 return ERROR;
7206 }
7207 }
7208
7209 /* print #NEXUS if appropriate */
7210 MrBayesPrintf (fpCon, "#NEXUS\n");
7211 if (sumtParams.calcTreeprobs == YES)
7212 MrBayesPrintf (fpTrees, "#NEXUS\n");
7213
7214 /* print unique identifiers to each file */
7215 len = (int) strlen (stamp);
7216 if (len > 1)
7217 {
7218 MrBayesPrintf (fpParts, "[ID: %s]\n", stamp);
7219 MrBayesPrintf (fpTstat, "[ID: %s]\n", stamp);
7220 MrBayesPrintf (fpVstat, "[ID: %s]\n", stamp);
7221 MrBayesPrintf (fpCon, "[ID: %s]\n", stamp);
7222 if (sumtParams.calcTreeprobs == YES)
7223 MrBayesPrintf (fpTrees, "[ID: %s]\n", stamp);
7224 }
7225
7226 /* Reset noWarn and autoOverwrite */
7227 if (treeNo == sumtParams.numTrees - 1)
7228 {
7229 noWarn = oldNoWarn;
7230 autoOverwrite = oldAutoOverwrite;
7231 }
7232
7233 return (NO_ERROR);
7234 }
7235
7236
PartCtrUppass(PartCtr * r,PartCtr ** uppass,int * index)7237 void PartCtrUppass (PartCtr *r, PartCtr **uppass, int *index)
7238 {
7239 if (r != NULL)
7240 {
7241 uppass[(*index)++] = r;
7242
7243 PartCtrUppass (r->left, uppass, index);
7244 PartCtrUppass (r->right, uppass, index);
7245 }
7246 }
7247
7248
7249 /* PrintBrParamsToFile: Print branach parameters to file */
PrintBrParamsToFile(PartCtr ** treeParts,int numTreeParts,int treeNo,char * divString)7250 int PrintBrParamsToFile (PartCtr **treeParts, int numTreeParts, int treeNo, char *divString)
7251 {
7252 int i, j, numPartitions, min, treeSample, runNo;
7253 char filename[145];
7254 PartCtr *x;
7255 FILE *fp;
7256
7257 /* set file name */
7258 if (sumtParams.numTrees > 1)
7259 sprintf (filename, "%s.tree%d.brparams", sumtParams.sumtOutfile, treeNo+1);
7260 else
7261 sprintf (filename, "%s.brparams", sumtParams.sumtOutfile);
7262 MrBayesPrint( "%s Saving branch parameters to file \"%s\"\n", spacer, filename);
7263
7264 /* Open file checking for over-write as appropriate */
7265 if ((fp = OpenNewMBPrintFile(filename)) == NULL)
7266 {
7267 MrBayesPrint ("\n");
7268 return ERROR;
7269 }
7270
7271 /* count number of branch params to print */
7272 min = (sumtParams.minBrParamFreq * (sumtParams.numTreesSampled/sumtParams.numRuns));
7273 for (i=0; i<numTreeParts; i++)
7274 {
7275 if (treeParts[i]->totCount < min)
7276 break;
7277 }
7278 numPartitions = i;
7279
7280 /* print header */
7281
7282 /* -- header for branch lengths; NB! We skip the root branch length (i starts at 1) */
7283 for (i=1; i<numPartitions; ++i)
7284 {
7285 MrBayesPrintf (fp, "length%s[%d]", divString, i);
7286 if (i!=numPartitions-1)
7287 MrBayesPrintf (fp, "\t");
7288 }
7289
7290 /* -- header for node heights */
7291 if (sumtParams.isClock == YES )
7292 {
7293 MrBayesPrintf (fp, "\t");
7294 for (i=0; i<numPartitions; i++)
7295 {
7296 MrBayesPrintf (fp, "height%s[%d]", divString, i);
7297 if (i!=numPartitions-1)
7298 MrBayesPrintf (fp, "\t");
7299 }
7300 }
7301
7302 /* -- header for node ages */
7303 if (sumtParams.isCalibrated == YES )
7304 {
7305 MrBayesPrintf (fp, "\t");
7306 for (i=0; i<numPartitions; i++)
7307 {
7308 MrBayesPrintf (fp, "age%s[%d]", divString, i);
7309 if (i!=numPartitions-1)
7310 MrBayesPrintf (fp, "\t");
7311 }
7312 }
7313
7314 /* -- header for effective branch lengths and branch rates; NB! We skip the root branch (j starts at 1) */
7315 if (sumtParams.isRelaxed == YES)
7316 {
7317 for (i=0; i<sumtParams.nBSets; i++)
7318 {
7319 MrBayesPrintf (fp, "\t");
7320 for (j=1; j<numPartitions; j++)
7321 {
7322 MrBayesPrintf (fp, "%s_length[%d]", sumtParams.bSetName[i], j);
7323 MrBayesPrintf (fp, "\t");
7324 }
7325 for (j=1; j<numPartitions; j++)
7326 {
7327 MrBayesPrintf (fp, "%s_rate[%d]", sumtParams.bSetName[i], j);
7328 if (j!=numPartitions-1)
7329 MrBayesPrintf (fp, "\t");
7330 }
7331 }
7332 for (i=0; i<sumtParams.nESets; i++)
7333 {
7334 MrBayesPrintf (fp, "\t");
7335 for (j=1; j<numPartitions; j++)
7336 {
7337 MrBayesPrintf (fp, "%s_nEvents[%d]", sumtParams.eSetName[i], j);
7338 if (j!=numPartitions-1)
7339 MrBayesPrintf (fp, "\t");
7340 }
7341 }
7342 }
7343
7344 /* finalize header line */
7345 MrBayesPrintf (fp, "\n");
7346
7347 /* print values */
7348 for (runNo=0; runNo<sumtParams.numRuns; runNo++)
7349 {
7350 for (treeSample=0; treeSample<sumtParams.numTreesSampled/sumtParams.numRuns; treeSample++)
7351 {
7352 /* print branch lengths */
7353 for (i=1; i<numPartitions; i++)
7354 {
7355 x = treeParts[i];
7356 if (x->count[runNo] > treeSample)
7357 MrBayesPrintf (fp, "%s", MbPrintNum (x->length[runNo][treeSample]));
7358 else
7359 MrBayesPrintf (fp, "NA");
7360 if (i!=numPartitions-1)
7361 MrBayesPrintf (fp, "\t");
7362 }
7363 /* print node heights */
7364 if (sumtParams.isClock == YES)
7365 {
7366 MrBayesPrintf (fp, "\t");
7367 for (i=0; i<numPartitions; i++)
7368 {
7369 x = treeParts[i];
7370 if ( x->count[runNo] > treeSample )
7371 MrBayesPrintf (fp, "%s", MbPrintNum (x->height[runNo][treeSample]));
7372 else
7373 MrBayesPrintf (fp, "NA");
7374 if (i!=numPartitions-1)
7375 MrBayesPrintf (fp, "\t");
7376 }
7377 }
7378 /* print node ages */
7379 if (sumtParams.isCalibrated == YES)
7380 {
7381 MrBayesPrintf (fp, "\t");
7382 for (i=0; i<numPartitions; i++)
7383 {
7384 x = treeParts[i];
7385 if ( x->count[runNo] > treeSample )
7386 MrBayesPrintf (fp, "%s", MbPrintNum (x->age[runNo][treeSample]));
7387 else
7388 MrBayesPrintf (fp, "NA");
7389 if (i!=numPartitions-1)
7390 MrBayesPrintf (fp, "\t");
7391 }
7392 }
7393 /* print effective branch lengths */
7394 if (sumtParams.isRelaxed)
7395 {
7396 for (i=0; i<sumtParams.nBSets; i++)
7397 {
7398 MrBayesPrintf (fp, "\t");
7399 for (j=1; j<numPartitions; j++)
7400 {
7401 x = treeParts[j];
7402 if ( x->count[runNo] > treeSample )
7403 MrBayesPrintf (fp, "%s", MbPrintNum (x->bLen[i][runNo][treeSample]));
7404 else
7405 MrBayesPrintf (fp, "NA");
7406 MrBayesPrintf (fp, "\t");
7407 }
7408 for (j=1; j<numPartitions; j++)
7409 {
7410 x = treeParts[j];
7411 if ( x->count[runNo] > treeSample )
7412 MrBayesPrintf (fp, "%s", MbPrintNum (x->bRate[i][runNo][treeSample]));
7413 else
7414 MrBayesPrintf (fp, "NA");
7415 if (j!=numPartitions-1)
7416 MrBayesPrintf (fp, "\t");
7417 }
7418 }
7419 for (i=0; i<sumtParams.nESets; i++)
7420 {
7421 MrBayesPrintf (fp, "\t");
7422 for (j=1; j<numPartitions; j++)
7423 {
7424 x = treeParts[j];
7425 if ( x->count[runNo] > treeSample )
7426 MrBayesPrintf (fp, "%d", x->nEvents[i][runNo][treeSample]);
7427 else
7428 MrBayesPrintf (fp, "NA");
7429 if (j!=numPartitions-1)
7430 MrBayesPrintf (fp, "\t");
7431 }
7432 }
7433 }
7434 MrBayesPrintf (fp, "\n");
7435 } // next tree sample
7436 } // next run
7437
7438 MrBayesPrint("\n");
7439 return NO_ERROR;
7440 }
7441
7442
7443 /* PrintConTree: Print consensus tree in standard format readable by TreeView, Paup etc */
PrintConTree(FILE * fp,PolyTree * t)7444 void PrintConTree (FILE *fp, PolyTree *t)
7445 {
7446 MrBayesPrintf (fp, " [Note: This tree contains information on the topology, \n");
7447 MrBayesPrintf (fp, " branch lengths (if present), and the probability\n");
7448 MrBayesPrintf (fp, " of the partition indicated by the branch.]\n");
7449 if (!strcmp(sumtParams.sumtConType, "Halfcompat"))
7450 MrBayesPrintf (fp, " tree con_50_majrule = ");
7451 else
7452 MrBayesPrintf (fp, " tree con_all_compat = ");
7453 WriteConTree (t->root, fp, YES);
7454 MrBayesPrintf (fp, ";\n");
7455 if (sumtParams.brlensDef == YES)
7456 {
7457 MrBayesPrintf (fp, "\n");
7458 MrBayesPrintf (fp, " [Note: This tree contains information only on the topology\n");
7459 MrBayesPrintf (fp, " and branch lengths (median of the posterior probability density).]\n");
7460 if (!strcmp(sumtParams.sumtConType, "Halfcompat"))
7461 MrBayesPrintf (fp, " tree con_50_majrule = ");
7462 else
7463 MrBayesPrintf (fp, " tree con_all_compat = ");
7464 WriteConTree (t->root, fp, NO);
7465 MrBayesPrintf (fp, ";\n");
7466 }
7467 }
7468
7469
7470 /* PrintFigTreeConTree: Print consensus tree in rich format for FigTree */
PrintFigTreeConTree(FILE * fp,PolyTree * t,PartCtr ** treeParts)7471 void PrintFigTreeConTree (FILE *fp, PolyTree *t, PartCtr **treeParts)
7472 {
7473 if (!strcmp(sumtParams.sumtConType, "Halfcompat"))
7474 MrBayesPrintf (fp, " tree con_50_majrule = ");
7475 else
7476 MrBayesPrintf (fp, " tree con_all_compat = ");
7477 if (t->isRooted == YES)
7478 MrBayesPrintf (fp, "[&R] ");
7479 else
7480 MrBayesPrintf (fp, "[&U] ");
7481
7482 WriteFigTreeConTree (t->root, fp, treeParts);
7483 MrBayesPrintf (fp, ";\n");
7484 }
7485
7486
PrintFigTreeNodeInfo(FILE * fp,PartCtr * x,MrBFlt length)7487 void PrintFigTreeNodeInfo (FILE *fp, PartCtr *x, MrBFlt length)
7488 {
7489 int i, postProbPercent, postProbSdPercent;
7490 MrBFlt *support, mean, var, min, max;
7491 Stat theStats;
7492
7493 support = SafeCalloc (sumtParams.numRuns, sizeof(MrBFlt));
7494 for (i=0; i<sumtParams.numRuns; i++)
7495 {
7496 support[i] = (MrBFlt) x->count[i] / (MrBFlt) sumtParams.numFileTreesSampled[i];
7497 }
7498 if (sumtParams.numRuns > 1)
7499 {
7500 MeanVariance (support, sumtParams.numRuns, &mean, &var);
7501 Range (support, sumtParams.numRuns, &min, &max);
7502 postProbPercent = (int) (100.0*mean + 0.5);
7503 postProbSdPercent = (int) (100.0 * sqrt(var) + 0.5);
7504 fprintf (fp, "[&prob=%.8le,prob_stddev=%.8le,prob_range={%.8le,%.8le},prob(percent)=\"%d\",prob+-sd=\"%d+-%d\"",
7505 mean, sqrt(var), min, max, postProbPercent, postProbPercent, postProbSdPercent);
7506 }
7507 else
7508 {
7509 postProbPercent = (int) (100.0*support[0] + 0.5);
7510 fprintf (fp, "[&prob=%.8le,prob(percent)=\"%d\"", support[0], postProbPercent);
7511 }
7512 if (sumtParams.isClock == YES)
7513 {
7514 GetSummary (x->height, sumtParams.numRuns, x->count, &theStats, sumtParams.HPD);
7515 if (sumtParams.HPD == YES)
7516 fprintf (fp, ",height_mean=%.8le,height_median=%.8le,height_95%%HPD={%.8le,%.8le}", theStats.mean, theStats.median, theStats.lower, theStats.upper);
7517 else
7518 fprintf (fp, ",height_mean=%.8le,height_median=%.8le,height_95%%CredInt={%.8le,%.8le}", theStats.mean, theStats.median, theStats.lower, theStats.upper);
7519 }
7520 if (sumtParams.isCalibrated == YES)
7521 {
7522 GetSummary (x->age, sumtParams.numRuns, x->count, &theStats, sumtParams.HPD);
7523 if (sumtParams.HPD == YES)
7524 fprintf (fp, ",age_mean=%.8le,age_median=%.8le,age_95%%HPD={%.8le,%.8le}", theStats.mean, theStats.median, theStats.lower, theStats.upper);
7525 else
7526 fprintf (fp, ",age_mean=%.8le,age_median=%.8le,age_95%%CredInt={%.8le,%.8le}", theStats.mean, theStats.median, theStats.lower, theStats.upper);
7527 }
7528 fprintf (fp, "]");
7529 if (length >= 0.0)
7530 fprintf (fp, ":%s", MbPrintNum(length));
7531 if (sumtParams.brlensDef == YES)
7532 {
7533 GetSummary (x->length, sumtParams.numRuns, x->count, &theStats, sumtParams.HPD);
7534 if (sumtParams.HPD == YES)
7535 fprintf (fp, "[&length_mean=%.8le,length_median=%.8le,length_95%%HPD={%.8le,%.8le}", theStats.mean, theStats.median, theStats.lower, theStats.upper);
7536 else
7537 fprintf (fp, "[&length_mean=%.8le,length_median=%.8le,length_95%%CredInt={%.8le,%.8le}", theStats.mean, theStats.median, theStats.lower, theStats.upper);
7538 }
7539 if (sumtParams.isClock == YES && sumtParams.isRelaxed == YES)
7540 {
7541 for (i=0; i<sumtParams.nBSets; i++)
7542 {
7543 GetSummary (x->bLen[i], sumtParams.numRuns, x->count, &theStats, sumtParams.HPD);
7544 if (sumtParams.HPD == YES)
7545 fprintf (fp, ",effectivebrlen%s_mean=%lf,effectivebrlen%s_median=%lf,effectivebrlen%s_95%%HPD={%lf,%lf}",
7546 sumtParams.tree->bSetName[i], theStats.mean,
7547 sumtParams.tree->bSetName[i], theStats.median,
7548 sumtParams.tree->bSetName[i], theStats.lower,
7549 theStats.upper);
7550 else
7551 fprintf (fp, ",effectivebrlen%s_mean=%lf,effectivebrlen%s_median=%lf,effectivebrlen%s_95%%CredInt={%lf,%lf}",
7552 sumtParams.tree->bSetName[i], theStats.mean,
7553 sumtParams.tree->bSetName[i], theStats.median,
7554 sumtParams.tree->bSetName[i], theStats.lower,
7555 theStats.upper);
7556 GetSummary (x->bRate[i], sumtParams.numRuns, x->count, &theStats, sumtParams.HPD);
7557 if (sumtParams.HPD == YES)
7558 fprintf (fp, ",rate%s_mean=%lf,rate%s_median=%lf,rate%s_95%%HPD={%lf,%lf}",
7559 sumtParams.tree->bSetName[i], theStats.mean,
7560 sumtParams.tree->bSetName[i], theStats.median,
7561 sumtParams.tree->bSetName[i], theStats.lower,
7562 theStats.upper);
7563 else
7564 fprintf (fp, ",rate%s_mean=%lf,rate%s_median=%lf,rate%s_95%%CredInt={%lf,%lf}",
7565 sumtParams.tree->bSetName[i], theStats.mean,
7566 sumtParams.tree->bSetName[i], theStats.median,
7567 sumtParams.tree->bSetName[i], theStats.lower,
7568 theStats.upper);
7569 }
7570 for (i=0; i<sumtParams.nESets; i++)
7571 {
7572 GetIntSummary (x->nEvents[i], sumtParams.numRuns, x->count, &theStats, sumtParams.HPD);
7573 if (sumtParams.HPD == YES)
7574 fprintf (fp, ",nEvents%s_mean=%lf,nEvents%s_median=%lf,nEvents%s_95%%HPD={%lf,%lf}",
7575 sumtParams.tree->eSetName[i], theStats.mean,
7576 sumtParams.tree->eSetName[i], theStats.median,
7577 sumtParams.tree->eSetName[i], theStats.lower,
7578 theStats.upper);
7579 else
7580 fprintf (fp, ",nEvents%s_mean=%lf,nEvents%s_median=%lf,nEvents%s_95%%CredInt={%lf,%lf}",
7581 sumtParams.tree->eSetName[i], theStats.mean,
7582 sumtParams.tree->eSetName[i], theStats.median,
7583 sumtParams.tree->eSetName[i], theStats.lower,
7584 theStats.upper);
7585 }
7586 }
7587 if (sumtParams.brlensDef == YES)
7588 fprintf (fp, "]");
7589
7590 free (support);
7591 }
7592
7593
PrintSumtTableLine(int numRuns,int * rowCount,Stat * theStats,MrBFlt * numPSRFSamples,MrBFlt * maxPSRF,MrBFlt * sumPSRF)7594 void PrintSumtTableLine(int numRuns, int *rowCount, Stat *theStats, MrBFlt *numPSRFSamples, MrBFlt *maxPSRF, MrBFlt *sumPSRF)
7595 {
7596 int j,k;
7597
7598 MrBayesPrint ("%10.6lf %10.6lf %10.6lf %10.6lf %10.6lf", theStats->mean, theStats->var, theStats->lower, theStats->upper, theStats->median);
7599
7600 MrBayesPrintf (fpVstat, "\t%s", MbPrintNum(theStats->mean));
7601 MrBayesPrintf (fpVstat, "\t%s", MbPrintNum(theStats->var));
7602 MrBayesPrintf (fpVstat, "\t%s", MbPrintNum(theStats->lower));
7603 MrBayesPrintf (fpVstat, "\t%s", MbPrintNum(theStats->upper));
7604 MrBayesPrintf (fpVstat, "\t%s", MbPrintNum(theStats->median));
7605
7606 if (numRuns > 1)
7607 {
7608 for (j=k=0; j<numRuns; j++)
7609 if (rowCount[j] > 0)
7610 k++;
7611
7612 if (theStats->PSRF < 0.0)
7613 {
7614 MrBayesPrint (" NA %3d", k);
7615 MrBayesPrintf (fpVstat, "\tNA\t%d", k);
7616 }
7617 else
7618 {
7619 if (theStats->PSRF > 10.0)
7620 {
7621 MrBayesPrint (" >10.0 %3d", k);
7622 MrBayesPrintf (fpVstat, "\tNA\t%d", k);
7623 (*maxPSRF) = 10.0;
7624 }
7625 else
7626 {
7627 MrBayesPrint (" %7.3lf %3d", theStats->PSRF, k);
7628 MrBayesPrintf (fpVstat, "\t%s\t%d", MbPrintNum(theStats->PSRF), k);
7629 (*sumPSRF) += theStats->PSRF;
7630 (*numPSRFSamples)++;
7631 if (theStats->PSRF > *maxPSRF)
7632 (*maxPSRF) = theStats->PSRF;
7633 }
7634 }
7635
7636 if (k != numRuns)
7637 MrBayesPrint (" *");
7638 }
7639
7640 MrBayesPrint ("\n");
7641 MrBayesPrintf (fpVstat, "\n");
7642 }
7643
7644
7645 /* PrintSumtTaxaInfo: Print information on pruned and absent taxa */
PrintSumtTaxaInfo(void)7646 void PrintSumtTaxaInfo (void)
7647 {
7648 int i, j, lineWidth, numExcludedTaxa, len;
7649 char tempStr[100];
7650
7651 /* print out information on absent taxa */
7652 numExcludedTaxa = 0;
7653 for (i=0; i<numTaxa; i++)
7654 if (sumtParams.absentTaxa[i] == YES)
7655 numExcludedTaxa++;
7656
7657 if (numExcludedTaxa > 0)
7658 {
7659 if (numExcludedTaxa == 1)
7660 MrBayesPrint ("%s The following taxon was absent from trees:\n", spacer);
7661 else
7662 MrBayesPrint ("%s The following %d taxa were absent from trees:\n", spacer, numExcludedTaxa);
7663 MrBayesPrint ("%s ", spacer);
7664 j = lineWidth = 0;
7665 for (i=0; i<numTaxa; i++)
7666 {
7667 if (sumtParams.absentTaxa[i] == YES)
7668 {
7669 j++;
7670 strcpy (tempStr, taxaNames[i]);
7671 len = (int) strlen(tempStr);
7672 lineWidth += len+2;
7673 if (lineWidth > 60)
7674 {
7675 MrBayesPrint ("\n%s ", spacer);
7676 lineWidth = 0;
7677 }
7678 if (numExcludedTaxa == 1)
7679 MrBayesPrint ("%s\n", tempStr);
7680 else if (numExcludedTaxa == 2 && j == 1)
7681 MrBayesPrint ("%s ", tempStr);
7682 else if (j == numExcludedTaxa)
7683 MrBayesPrint ("and %s\n", tempStr);
7684 else
7685 MrBayesPrint ("%s, ", tempStr);
7686 }
7687 }
7688 MrBayesPrint ("\n");
7689 }
7690
7691 /* print out information on pruned taxa */
7692 numExcludedTaxa = 0;
7693 for (i=0; i<numTaxa; i++)
7694 if (taxaInfo[i].isDeleted == YES && sumtParams.absentTaxa[i] == NO)
7695 numExcludedTaxa++;
7696
7697 if (numExcludedTaxa > 0)
7698 {
7699 if (numExcludedTaxa == 1)
7700 MrBayesPrint ("%s The following taxon was pruned from trees:\n", spacer);
7701 else
7702 MrBayesPrint ("%s The following %d taxa were pruned from trees:\n", spacer, numExcludedTaxa);
7703 MrBayesPrint ("%s ", spacer);
7704 j = lineWidth = 0;
7705 for (i=0; i<numTaxa; i++)
7706 {
7707 if (taxaInfo[i].isDeleted == YES && sumtParams.absentTaxa[i] == NO)
7708 {
7709 j++;
7710 strcpy (tempStr, taxaNames[i]);
7711 len = (int) strlen(tempStr);
7712 lineWidth += len+2;
7713 if (lineWidth > 60)
7714 {
7715 MrBayesPrint ("\n%s ", spacer);
7716 lineWidth = 0;
7717 }
7718 if (numExcludedTaxa == 1)
7719 MrBayesPrint ("%s\n", tempStr);
7720 else if (numExcludedTaxa == 2 && j == 1)
7721 MrBayesPrint ("%s ", tempStr);
7722 else if (j == numExcludedTaxa)
7723 MrBayesPrint ("and %s\n", tempStr);
7724 else
7725 MrBayesPrint ("%s, ", tempStr);
7726 }
7727 }
7728 MrBayesPrint ("\n");
7729 }
7730 }
7731
7732
7733 /* Range: Determine range for a vector of MrBFlt values */
Range(MrBFlt * vals,int nVals,MrBFlt * min,MrBFlt * max)7734 void Range (MrBFlt *vals, int nVals, MrBFlt *min, MrBFlt *max)
7735 {
7736 SortMrBFlt (vals, 0, nVals-1);
7737
7738 *min = vals[0];
7739 *max = vals[nVals-1];
7740 }
7741
7742
7743 /* ResetTaxonSet: Reset included taxa and local outgroup number */
ResetTaxonSet(void)7744 void ResetTaxonSet (void)
7745 {
7746 int i, j;
7747
7748 /* reset numLocalTaxa and localOutGroup */
7749 localOutGroup = 0;
7750 numLocalTaxa = 0;
7751 for (i=j=0; i<numTaxa; i++)
7752 {
7753 if (taxaInfo[i].isDeleted == NO)
7754 {
7755 if (i == outGroupNum)
7756 localOutGroup = numLocalTaxa;
7757 numLocalTaxa++;
7758 }
7759 }
7760 }
7761
7762
ResetTranslateTable(void)7763 void ResetTranslateTable (void)
7764 {
7765 int i;
7766
7767 for (i=0; i<numTranslates; i++)
7768 {
7769 free (transFrom[i]);
7770 free (transTo[i]);
7771 }
7772 free (transFrom);
7773 free (transTo);
7774 transFrom = NULL;
7775 transTo = NULL;
7776 numTranslates = 0;
7777 isTranslateDef = NO;
7778 isTranslateDiff = NO;
7779 }
7780
7781
ShowConPhylogram(FILE * fp,PolyTree * t,int screenWidth)7782 int ShowConPhylogram (FILE *fp, PolyTree *t, int screenWidth)
7783 {
7784 int i, j, k, nLines, from, to, treeWidth=0, barLength, printExponential,
7785 precision, width, newPos, curPos, nTimes, numSpaces, maxLabelLength;
7786 char *printLine, *markLine, temp[30], *label;
7787 MrBFlt scale, f, scaleBar;
7788 PolyNode *p, *q;
7789
7790 /* set max label length */
7791 maxLabelLength = 20;
7792
7793 /* allocate space for label, printLine and markLine */
7794 printLine = (char *) SafeCalloc ((2*screenWidth+2),sizeof(char));
7795 label = (char *) SafeCalloc (maxLabelLength+1, sizeof(char));
7796 if (!printLine || !label)
7797 return ERROR;
7798 markLine = printLine + screenWidth + 1;
7799
7800 /* calculate scale */
7801 scale = 0.0;
7802 t->root->f = 0.0;
7803 for (i=t->nNodes-2; i>=0; i--)
7804 {
7805 p = t->allDownPass[i];
7806 /* find distance to root in relevant units */
7807 if (sumtParams.isClock == YES && sumtParams.isCalibrated == NO)
7808 p->f = t->root->depth - p->depth;
7809 else if (sumtParams.isClock == YES && sumtParams.isCalibrated == YES)
7810 p->f = t->root->age - p->age;
7811 else
7812 p->f = p->anc->f + p->length;
7813 if (p->left == NULL)
7814 {
7815 f = p->f / (screenWidth - Label(p,YES,NULL,maxLabelLength) - 2);
7816 if (f > scale)
7817 {
7818 scale = f;
7819 treeWidth = screenWidth - Label(p,YES,NULL,maxLabelLength) - 2;
7820 }
7821 }
7822 }
7823
7824 /* calculate x coordinates */
7825 for (i=0; i<t->nNodes; i++)
7826 {
7827 p = t->allDownPass[i];
7828 p->x = (int) (0.5 + (p->f / scale));
7829 }
7830
7831 /* calculate y coordinates and lines to print */
7832 for (i=nLines=0; i<t->nNodes; i++)
7833 {
7834 p = t->allDownPass[i];
7835 if (p->left != NULL)
7836 {
7837 /* internal node */
7838 for (q=p->left->sib; q->sib!=NULL; q=q->sib)
7839 ;
7840 p->y = (int) (0.5 + ((p->left->y + q->y) / 2.0));
7841 }
7842 else
7843 {
7844 /* terminal node */
7845 p->y = nLines;
7846 nLines += 2;
7847 }
7848 }
7849
7850 /* print tree line by line */
7851
7852 for (i=0; i<nLines; i++)
7853 {
7854 MrBayesPrint ("%s ", spacer);
7855 /* empty printLine */
7856 for (j=0; j<screenWidth; j++)
7857 {
7858 printLine[j] = ' ';
7859 }
7860 printLine[j]='\0';
7861
7862 for (j=0; j<t->nNodes; j++)
7863 {
7864 p = t->allDownPass[j];
7865 if (p->y != i)
7866 continue;
7867
7868 /* this branch should be printed */
7869 /* add branch */
7870 if (p->anc == NULL)
7871 {
7872 /* this is the root of the whole tree */
7873 printLine[p->x] = '+';
7874 }
7875 else
7876 {
7877 /* this is an ordinary branch */
7878 to = p->x;
7879 from = p->anc->x;
7880 for (k=from+1; k<=to; k++)
7881 printLine[k] = '-';
7882 if (p == p->anc->left)
7883 {
7884 if (markLine[from] == 0)
7885 printLine[from] = '/';
7886 else
7887 printLine[from] = '|';
7888 markLine[from] ++;
7889 }
7890 else if (p->sib == NULL)
7891 {
7892 if (markLine[from] == 1)
7893 printLine[from] = '\\';
7894 else
7895 printLine[from] = '|';
7896 markLine[from] --;
7897 }
7898 if (p->left!=NULL)
7899 {
7900 if (from != to)
7901 printLine[to] = '+';
7902 else
7903 printLine[to] = '|';
7904 }
7905 else
7906 {
7907 /* add label if the branch is terminal */
7908 Label(p,YES,label,maxLabelLength);
7909 sprintf (printLine+to+2,"%s", label);
7910 }
7911 }
7912 }
7913
7914 /* check for cross branches */
7915 for (j=0; j<screenWidth; j++)
7916 {
7917 if (markLine[j] >= 1 && printLine[j] == ' ')
7918 printLine[j] = '|';
7919 }
7920 MrBayesPrintf (fp, "%s\n",printLine);
7921 }
7922
7923 /* print scale */
7924 k = (int) (floor (log10 (scale * 80)));
7925 scaleBar = pow (10, k);
7926 barLength = (int) (scaleBar / scale);
7927 if (barLength > 80)
7928 {
7929 barLength /= 10;
7930 scaleBar /= 10.0;
7931 }
7932 else if (barLength > 40)
7933 {
7934 barLength /= 5;
7935 scaleBar /= 5.0;
7936 }
7937 else if (barLength > 16)
7938 {
7939 barLength /= 2;
7940 scaleBar /= 2.0;
7941 }
7942
7943 if (t->isClock == YES)
7944 {
7945 MrBayesPrint ("%s ", spacer);
7946 for (i=0; i<treeWidth; i++)
7947 printLine[i] = '-';
7948 nTimes = (int) (treeWidth / (scaleBar / scale));
7949 for (i=0; i<=nTimes; i++)
7950 printLine[treeWidth - (int)(i*scaleBar/scale)] = '|';
7951 MrBayesPrint ("%s\n", printLine);
7952
7953 MrBayesPrint ("%s ", spacer);
7954 f = treeWidth * scale;
7955 if (f >= 1000.0 || f < 0.10)
7956 {
7957 printExponential = YES;
7958 precision = 0;
7959 }
7960 else
7961 {
7962 printExponential = NO;
7963 precision = 2 - (int) (log10 (f));
7964 }
7965
7966 curPos = 0;
7967 f = nTimes * scaleBar;
7968 while (curPos < treeWidth)
7969 {
7970 /* print the number */
7971 if (printExponential == YES)
7972 sprintf (temp, "%.2e", f);
7973 else
7974 sprintf (temp, "%.*lf", precision, f);
7975
7976 /* room to print ? if so, print */
7977 width = (int) strlen (temp);
7978 newPos = treeWidth - (int) (nTimes * (scaleBar / scale));
7979 numSpaces = newPos - width / 2 - curPos;
7980 if (numSpaces >= 0 || (numSpaces >= -2 && curPos == 0))
7981 {
7982 while (numSpaces > 0)
7983 {
7984 printLine[curPos++] = ' ';
7985 numSpaces--;
7986 }
7987 for (i=0; temp[i]!='\0'; i++)
7988 printLine[curPos++] = temp[i];
7989 }
7990
7991 /* get new number */
7992 f -= scaleBar;
7993 nTimes--;
7994 }
7995
7996 MrBayesPrint ("%s\n", printLine);
7997
7998 if (sumtParams.isCalibrated == YES)
7999 MrBayesPrint ("\n%s [User-defined time units]\n\n", spacer);
8000 else
8001 MrBayesPrint ("\n%s [Expected changes per site]\n\n", spacer);
8002 }
8003 else
8004 {
8005 MrBayesPrintf (fp, "%s |", spacer);
8006 for (i=0; i<barLength-1; i++)
8007 MrBayesPrintf (fp, "-");
8008 MrBayesPrintf (fp, "| %1.3lf expected changes per site\n\n", scaleBar);
8009 }
8010
8011 free (printLine);
8012
8013 return NO_ERROR;
8014 }
8015
8016
ShowConTree(FILE * fp,PolyTree * t,int screenWidth,int showSupport)8017 int ShowConTree (FILE *fp, PolyTree *t, int screenWidth, int showSupport)
8018 {
8019 int i, j, k, treeWidth, minBranchLength, maxWidth, isTreeDivided,
8020 printWidth, nLines, nodesToBePrinted, from, to, maxLabelLength,
8021 maxLength;
8022 char *printLine, *markLine, temp[20], *label;
8023 PolyNode *p=NULL, *q;
8024
8025 maxLength = 20; /* max length of label */
8026 minBranchLength = 5; /* min length of branch in tree */
8027 isTreeDivided = NO;
8028
8029 /* allocate space for printLine, markLine and label */
8030 printLine = (char *) SafeCalloc (maxLength+1+(2*screenWidth+2),sizeof(char));
8031 if (!printLine)
8032 return ERROR;
8033 markLine = printLine + screenWidth + 1;
8034 label = markLine + screenWidth + 1;
8035
8036 /* get fresh internal node indices */
8037 k = t->nNodes - t->nIntNodes;
8038 for (i=0; i<t->nIntNodes; i++)
8039 {
8040 p = t->intDownPass[i];
8041 p->index = k++;
8042 }
8043
8044 /* calculate max length of labels including taxon index number */
8045 maxLabelLength = 0;
8046 for (i=0; i<t->nNodes; i++)
8047 {
8048 p = t->allDownPass[i];
8049 if (p->left == NULL)
8050 {
8051 j = Label(p,YES,NULL,maxLength);
8052 if (j > maxLabelLength)
8053 maxLabelLength = j;
8054 }
8055 }
8056
8057 /* make sure label can hold an interior node index number */
8058 j = (int) (3.0 + log10((MrBFlt)t->nNodes));
8059 maxLabelLength = (maxLabelLength > j ? maxLabelLength : j);
8060
8061 /* calculate remaining screen width for tree
8062 and maxWidth in terms of branches */
8063 treeWidth = screenWidth - maxLabelLength - 1;
8064 maxWidth = treeWidth / minBranchLength;
8065
8066 /* unmark whole tree */
8067 for (i=0; i<t->nNodes; i++)
8068 t->allDownPass[i]->mark = 0;
8069 nodesToBePrinted = t->nNodes;
8070
8071 while (nodesToBePrinted > 0)
8072 {
8073 /* count depth of nodes in unprinted tree */
8074 for (i=0; i<t->nNodes; i++)
8075 {
8076 p = t->allDownPass[i];
8077 if (p->mark == 0) /* the node has not been printed yet */
8078 {
8079 p->x = 0;
8080 /* if it is an interior node in the tree that will be printed
8081 compute the depth of the node */
8082 if (p->left != NULL && p->left->mark == 0)
8083 {
8084 for (q = p->left; q!=NULL; q=q->sib)
8085 {
8086 if (q->x > p->x)
8087 p->x = q->x;
8088 }
8089 p->x++;
8090 /* break when root of print subtree has been found */
8091 if (p->x >= maxWidth)
8092 break;
8093 }
8094 }
8095 }
8096
8097 /* if internal node then find largest nonprinted subtree among descendant nodes */
8098 if (p->anc != NULL)
8099 {
8100 for (q=p->left; q!=NULL; q=q->sib)
8101 {
8102 if (q->x == p->x - 1 && q->mark == 0)
8103 p = q;
8104 }
8105 MrBayesPrintf (fp, "%s Subtree rooted at node %d:\n\n", spacer, p->index);
8106 isTreeDivided = YES;
8107 }
8108 else if (isTreeDivided == YES)
8109 MrBayesPrintf (fp, "%s Root part of tree:\n\n", spacer);
8110
8111 /* mark subtree for printing and
8112 translate x coordinates from depth to position */
8113 if (p->anc == NULL)
8114 printWidth = p->x;
8115 else
8116 printWidth = p->x + 1;
8117 p->mark = 1;
8118 p->x = (int) (treeWidth - 0.5 - ((treeWidth - 1) * (p->x / (MrBFlt) printWidth)));
8119 for (i=t->nNodes-2; i>=0; i--)
8120 {
8121 p = t->allDownPass[i];
8122 if (p->mark == 0 && p->anc->mark == 1)
8123 {
8124 p->mark = 1;
8125 p->x = (int) (treeWidth - 0.5 - ((treeWidth - 1) * (p->x / (MrBFlt) printWidth)));
8126 }
8127 }
8128
8129 /* calculate y coordinates of nodes to be printed and lines to print */
8130 for (i=nLines=0; i<t->nNodes; i++)
8131 {
8132 p = t->allDownPass[i];
8133 if (p->mark == 1)
8134 {
8135 if (p->left != NULL && p->left->mark == 1)
8136 {
8137 /* internal node */
8138 for (q=p->left->sib; q->sib!=NULL; q=q->sib)
8139 ;
8140 p->y = (int) (0.5 + ((p->left->y + q->y) / 2.0));
8141 }
8142 else
8143 {
8144 /* terminal node */
8145 p->y = nLines;
8146 nLines += 2;
8147 }
8148 }
8149 }
8150
8151 /* print subtree line by line */
8152 for (i=0; i<nLines; i++)
8153 {
8154 MrBayesPrintf (fp, "%s ", spacer);
8155 /* empty printLine */
8156 for (j=0; j<screenWidth; j++)
8157 {
8158 printLine[j] = ' ';
8159 }
8160 printLine[j]='\0';
8161
8162 for (j=0; j<t->nNodes; j++)
8163 {
8164 p = t->allDownPass[j];
8165 if (p->mark != 1 || p->y != i)
8166 continue;
8167
8168 /* this branch should be printed
8169 add label if the branch is terminal in tree to be printed */
8170 if (p->left == NULL)
8171 {
8172 Label (p,YES,label,maxLength);
8173 sprintf (printLine+treeWidth+1,"%s", label);
8174 }
8175 else if (p->left->mark == 2)
8176 sprintf (printLine+treeWidth+1,"(%d)", p->index);
8177
8178 /* add branch */
8179 if (p->anc == NULL)
8180 {
8181 /* this is the root of the whole tree */
8182 printLine[p->x] = '+';
8183 nodesToBePrinted--;
8184 }
8185 else if (p->anc->mark == 0)
8186 {
8187 /* this is a root of a subtree
8188 this branch will have to be printed again so do
8189 not decrease nodesToBePrinted */
8190 to = p->x;
8191 from = 0;
8192 for (k=from; k<to; k++)
8193 printLine[k] = '-';
8194 printLine[to] = '+';
8195 if (showSupport == YES)
8196 sprintf (temp, "%d", (int) (p->support*100.0 + 0.5));
8197 else
8198 *temp='\0';
8199 from = (int)(from + 1.5 + ((to - from - 1 - strlen(temp)) / 2.0));
8200 for (k=0; temp[k]!='\0'; k++)
8201 printLine[from++] = temp[k];
8202 }
8203 else
8204 {
8205 /* this is an ordinary branch */
8206 to = p->x;
8207 from = p->anc->x;
8208 for (k=from+1; k<=to; k++)
8209 printLine[k] = '-';
8210 if (p == p->anc->left)
8211 {
8212 printLine[from] = '/';
8213 markLine[from] = 1;
8214 }
8215 else if (p->sib == NULL)
8216 {
8217 printLine[from] = '\\';
8218 markLine[from] = 0;
8219 }
8220 if (p->left!=NULL && p->left->mark!=2)
8221 {
8222 printLine[to] = '+';
8223 if (showSupport == YES)
8224 sprintf (temp, "%d", (int) (p->support*100.0 + 0.5));
8225 else
8226 *temp='\0';
8227 from = (int)(from + 1.5 + ((to - from - 1 - strlen(temp)) / 2.0));
8228 for (k=0; temp[k]!='\0'; k++)
8229 printLine[from++] = temp[k];
8230 }
8231 nodesToBePrinted--;
8232 }
8233 }
8234
8235 /* check for cross branches */
8236 for (j=0; j<treeWidth; j++)
8237 {
8238 if (markLine[j] == 1 && printLine[j] == ' ')
8239 printLine[j] = '|';
8240 }
8241
8242 MrBayesPrintf (fp, "%s\n",printLine);
8243 }
8244
8245 /* mark printed branches */
8246 for (i=0; i<t->nNodes; i++)
8247 {
8248 p = t->allDownPass[i];
8249 if (p->mark == 1)
8250 {
8251 if (p->anc == NULL)
8252 p->mark = 2;
8253 else if (p->anc->mark == 0)
8254 p->mark = 0; /* this branch will have to be printed again */
8255 else
8256 p->mark = 2;
8257 }
8258 }
8259
8260 } /* next subtree */
8261
8262 free (printLine);
8263
8264 return NO_ERROR;
8265 }
8266
8267
ShowParts(FILE * fp,BitsLong * p,int nTaxaToShow)8268 void ShowParts (FILE *fp, BitsLong *p, int nTaxaToShow)
8269 {
8270 int i;
8271 BitsLong x, y, bitsLongOne;
8272
8273 bitsLongOne = 1;
8274
8275 for (i=0; i<nTaxaToShow; i++)
8276 {
8277 y = p[i / nBitsInALong];
8278 x = bitsLongOne << (i % nBitsInALong);
8279 if ((x & y) == 0)
8280 MrBayesPrintf (fp, ".");
8281 else
8282 MrBayesPrintf (fp, "*");
8283 }
8284 }
8285
8286
ShowSomeParts(FILE * fp,BitsLong * p,int offset,int nTaxaToShow)8287 void ShowSomeParts (FILE *fp, BitsLong *p, int offset, int nTaxaToShow)
8288 {
8289 int i;
8290 BitsLong x, y, bitsLongOne;
8291
8292 bitsLongOne = 1;
8293
8294 for (i=offset; i<offset+nTaxaToShow; i++)
8295 {
8296 y = p[i / nBitsInALong];
8297 x = bitsLongOne << (i % nBitsInALong);
8298 if ((x & y) == 0)
8299 MrBayesPrintf (fp, ".");
8300 else
8301 MrBayesPrintf (fp, "*");
8302 }
8303 }
8304
8305
SortPartCtr(PartCtr ** item,int left,int right)8306 void SortPartCtr (PartCtr **item, int left, int right)
8307 {
8308 register int i, j;
8309 PartCtr *tempPartCtr;
8310 int x;
8311
8312 assert (left >= 0);
8313 assert (right >= 0);
8314
8315 i = left;
8316 j = right;
8317 x = item[(left+right)/2]->totCount;
8318 do
8319 {
8320 while (item[i]->totCount > x && i < right)
8321 i++;
8322 while (x > item[j]->totCount && j > left)
8323 j--;
8324 if (i <= j)
8325 {
8326 tempPartCtr = item[i];
8327 item[i] = item[j];
8328 item[j] = tempPartCtr;
8329
8330 i++;
8331 j--;
8332 }
8333 } while (i <= j);
8334 if (left < j)
8335 SortPartCtr (item, left, j);
8336 if (i < right)
8337 SortPartCtr (item, i, right);
8338 }
8339
8340
SortTerminalPartCtr(PartCtr ** item,int len)8341 void SortTerminalPartCtr (PartCtr **item, int len)
8342 {
8343 register int i, j, maxCount;
8344 PartCtr *temp;
8345
8346 maxCount = item[0]->totCount;
8347
8348 /* put root first */
8349 for (i=0; item[i]->totCount == maxCount; i++)
8350 if (NumBits(item[i]->partition, sumtParams.BitsLongsNeeded) == sumtParams.numTaxa)
8351 break;
8352
8353 if (i!=0)
8354 {
8355 temp = item[0];
8356 item[0] = item[i];
8357 item[i] = temp;
8358 }
8359
8360 /* then find terminals in index order */
8361 for (i=1; i<=sumtParams.numTaxa; i++)
8362 {
8363 for (j=i; item[j]->totCount == maxCount && j<len; j++)
8364 if (NumBits(item[j]->partition, sumtParams.BitsLongsNeeded) == 1 &&
8365 FirstTaxonInPartition(item[j]->partition, sumtParams.BitsLongsNeeded) == i-1)
8366 break;
8367
8368 if (j!=i)
8369 {
8370 temp = item[i];
8371 item[i] = item[j];
8372 item[j] = temp;
8373 }
8374 }
8375 }
8376
8377
SortTreeCtr(TreeCtr ** item,int left,int right)8378 void SortTreeCtr (TreeCtr **item, int left, int right)
8379 {
8380 register int i, j;
8381 TreeCtr *tempTreeCtr;
8382 int x;
8383
8384 i = left;
8385 j = right;
8386 x = item[(left+right)/2]->count;
8387 do
8388 {
8389 while (item[i]->count > x && i < right)
8390 i++;
8391 while (x > item[j]->count && j > left)
8392 j--;
8393 if (i <= j)
8394 {
8395 tempTreeCtr = item[i];
8396 item[i] = item[j];
8397 item[j] = tempTreeCtr;
8398
8399 i++;
8400 j--;
8401 }
8402 } while (i <= j);
8403 if (left < j)
8404 SortTreeCtr (item, left, j);
8405 if (i < right)
8406 SortTreeCtr (item, i, right);
8407 }
8408
8409
8410 /* StoreSumtTree: Store tree in treeList in packed format */
StoreSumtTree(PackedTree * treeList,int index,PolyTree * t)8411 int StoreSumtTree (PackedTree *treeList, int index, PolyTree *t)
8412 {
8413 int orderLen, numBrlens;
8414
8415 assert (treeList[index].brlens == NULL);
8416 assert (treeList[index].order == NULL);
8417
8418 /* get tree dimensions */
8419 numBrlens = t->nNodes - 1;
8420 orderLen = t->nIntNodes - 1;
8421
8422 /* allocate space */
8423 treeList[index].brlens = (MrBFlt *) SafeCalloc (numBrlens, sizeof(MrBFlt));
8424 treeList[index].order = (int *) SafeCalloc (orderLen, sizeof(MrBFlt));
8425 if (!treeList[index].order || !treeList[index].brlens)
8426 {
8427 MrBayesPrint ("%s Could not store packed representation of tree '%s'\n", spacer, t->name);
8428 return (ERROR);
8429 }
8430
8431 /* store tree */
8432 if (t->isRooted == YES)
8433 StoreRPolyTree (t, treeList[index].order, treeList[index].brlens);
8434 else
8435 StoreUPolyTree (t, treeList[index].order, treeList[index].brlens);
8436
8437 return (NO_ERROR);
8438 }
8439
8440
8441 /* TreeCtrUppass: extract TreeCtr nodes in uppass sequence */
TreeCtrUppass(TreeCtr * r,TreeCtr ** uppass,int * index)8442 void TreeCtrUppass (TreeCtr *r, TreeCtr **uppass, int *index)
8443 {
8444 if (r != NULL)
8445 {
8446 uppass[(*index)++] = r;
8447
8448 TreeCtrUppass (r->left, uppass, index);
8449 TreeCtrUppass (r->right, uppass, index);
8450 }
8451 }
8452
8453
TreeProb(void)8454 int TreeProb (void)
8455 {
8456 int i, num, nInSets[5];
8457 MrBFlt treeProb, cumTreeProb;
8458 TreeCtr **trees;
8459 Tree *theTree;
8460
8461 /* check if we need to do this */
8462 if (sumtParams.calcTreeprobs == NO)
8463 return (NO_ERROR);
8464
8465 MrBayesPrint ("%s Calculating tree probabilities...\n\n", spacer);
8466
8467 /* allocate space for tree counters and trees */
8468 trees = (TreeCtr **) SafeCalloc ((size_t)numUniqueTreesFound, sizeof(TreeCtr *));
8469 theTree = AllocateTree (sumtParams.numTaxa);
8470 if (!trees || !theTree)
8471 {
8472 MrBayesPrint ("%s Problem allocating trees or theTree in TreeProb\n", spacer);
8473 return (ERROR);
8474 }
8475
8476 /* extract trees */
8477 i = 0;
8478 TreeCtrUppass (treeCtrRoot, trees, &i);
8479
8480 /* sort trees */
8481 SortTreeCtr (trees, 0, numUniqueTreesFound-1);
8482
8483 /* set basic params in receiving tree */
8484 theTree->isRooted = sumtParams.isRooted;
8485 if (theTree->isRooted)
8486 {
8487 theTree->nNodes = 2 * sumtParams.numTaxa;
8488 theTree->nIntNodes = sumtParams.numTaxa - 1;
8489 }
8490 else
8491 {
8492 theTree->nNodes = 2 * sumtParams.numTaxa - 2;
8493 theTree->nIntNodes = sumtParams.numTaxa - 2;
8494 }
8495
8496 /* show tree data */
8497 cumTreeProb = 0.0;
8498 nInSets[0] = nInSets[1] = nInSets[2] = nInSets[3] = nInSets[4] = 0;
8499 for (num=0; num<numUniqueTreesFound; num++) /* loop over all of the trees that were found */
8500 {
8501 /* get probability of tree */
8502 treeProb = (MrBFlt)trees[num]->count / (MrBFlt)sumtParams.numTreesSampled;
8503 cumTreeProb += treeProb;
8504 if (cumTreeProb >= 0.0 && cumTreeProb < 0.5)
8505 nInSets[0]++;
8506 else if (cumTreeProb >= 0.5 && cumTreeProb < 0.9)
8507 nInSets[1]++;
8508 else if (cumTreeProb >= 0.9 && cumTreeProb < 0.95)
8509 nInSets[2]++;
8510 else if (cumTreeProb >= 0.95 && cumTreeProb < 0.99)
8511 nInSets[3]++;
8512 else
8513 nInSets[4]++;
8514
8515 /* draw tree to stdout */
8516 if (theTree->isRooted == YES)
8517 RetrieveRTopology (theTree, trees[num]->order);
8518 else
8519 RetrieveUTopology (theTree, trees[num]->order);
8520 if (sumtParams.showSumtTrees == YES)
8521 {
8522 MrBayesPrint ("\n%s Tree %d (p = %1.3lf, P = %1.3lf):\n\n", spacer, num+1, treeProb, cumTreeProb);
8523 ShowTree (theTree);
8524 }
8525
8526 /* draw tree to file */
8527 if (num == 0)
8528 {
8529 MrBayesPrintf (fpTrees, "[This file contains the trees that were found during the MCMC\n");
8530 MrBayesPrintf (fpTrees, "search, sorted by posterior probability. \"p\" indicates the\n");
8531 MrBayesPrintf (fpTrees, "posterior probability of the tree whereas \"P\" indicates the\n");
8532 MrBayesPrintf (fpTrees, "cumulative posterior probability.]\n\n");
8533 MrBayesPrintf (fpTrees, "begin trees;\n");
8534 MrBayesPrintf (fpTrees, " translate\n");
8535 for (i=0; i<sumtParams.numTaxa; i++)
8536 {
8537 if (i == sumtParams.numTaxa - 1)
8538 MrBayesPrintf (fpTrees, " %2d %s;\n", i+1, sumtParams.taxaNames[i]);
8539 else
8540 MrBayesPrintf (fpTrees, " %2d %s,\n", i+1, sumtParams.taxaNames[i]);
8541 }
8542 }
8543 MrBayesPrintf (fpTrees, " tree tree_%d [p = %1.3lf, P = %1.3lf] = [&W %1.6lf] ", num+1, treeProb, cumTreeProb, treeProb);
8544 WriteTopologyToFile (fpTrees, theTree->root->left, theTree->isRooted);
8545 MrBayesPrintf (fpTrees, ";\n");
8546 if (num == numUniqueTreesFound - 1)
8547 MrBayesPrintf (fpTrees, "end;\n");
8548 }
8549
8550 /* print out general information on credible sets of trees */
8551 i = nInSets[0] + nInSets[1] + nInSets[2] + nInSets[3] + nInSets[4];
8552 MrBayesPrint ("%s Credible sets of trees (%d tree%s sampled):\n", spacer, i, i > 1 ? "s" : "");
8553 i = nInSets[0] + 1;
8554 if (i > 1)
8555 MrBayesPrint ("%s 50 %% credible set contains %d trees\n", spacer, i);
8556 i += nInSets[1];
8557 if (i > 1)
8558 MrBayesPrint ("%s 90 %% credible set contains %d trees\n", spacer, i);
8559 i += nInSets[2];
8560 if (i > 1)
8561 MrBayesPrint ("%s 95 %% credible set contains %d trees\n", spacer, i);
8562 i += nInSets[3];
8563 MrBayesPrint ("%s 99 %% credible set contains %d tree%s\n\n", spacer, i, i > 1 ? "s" : "");
8564
8565 /* free memory */
8566 free (trees);
8567
8568 return (NO_ERROR);
8569 }
8570
8571
WriteConTree(PolyNode * p,FILE * fp,int showSupport)8572 void WriteConTree (PolyNode *p, FILE *fp, int showSupport)
8573 {
8574 PolyNode *q;
8575
8576 if (p->anc != NULL)
8577 if (p->anc->left == p)
8578 fprintf (fp, "(");
8579
8580 for (q = p->left; q != NULL; q = q->sib)
8581 {
8582 if (q->anc->left != q) /* Note that q->anc always exists (it is p) */
8583 fprintf (fp, ",");
8584 WriteConTree (q, fp, showSupport);
8585 }
8586 if (p->left == NULL)
8587 {
8588 if (sumtParams.brlensDef == YES)
8589 {
8590 if (sumtParams.isClock == NO)
8591 fprintf (fp, "%d:%s", p->index+1, MbPrintNum(p->length));
8592 else
8593 fprintf (fp, "%d:%s", p->index+1, MbPrintNum(p->anc->depth - p->depth));
8594 }
8595 else
8596 fprintf (fp, "%d", p->index+1);
8597 }
8598
8599 if (p->sib == NULL && p->anc != NULL)
8600 {
8601 if (p->anc->anc != NULL)
8602 {
8603 if (sumtParams.brlensDef == YES && showSupport == NO)
8604 {
8605 if (sumtParams.isClock == NO)
8606 fprintf (fp, "):%s", MbPrintNum(p->anc->length));
8607 else
8608 fprintf (fp, "):%s", MbPrintNum(p->anc->anc->depth - p->anc->depth));
8609 }
8610 else if (sumtParams.brlensDef == NO && showSupport == YES)
8611 fprintf (fp, ")%1.3lf", p->anc->support);
8612 else if (sumtParams.brlensDef == YES && showSupport == YES)
8613 {
8614 if (sumtParams.isClock == NO)
8615 fprintf (fp, ")%1.3lf:%s", p->anc->support, MbPrintNum(p->anc->length));
8616 else
8617 fprintf (fp, ")%1.3lf:%s", p->anc->support, MbPrintNum(p->anc->anc->depth - p->anc->depth));
8618 }
8619 else
8620 fprintf (fp, ")");
8621 }
8622 else
8623 fprintf (fp, ")");
8624 }
8625 }
8626
8627
8628 /* WriteFigTreeConTree: Include rich information for each node in a consensus tree */
WriteFigTreeConTree(PolyNode * p,FILE * fp,PartCtr ** treeParts)8629 void WriteFigTreeConTree (PolyNode *p, FILE *fp, PartCtr **treeParts)
8630 {
8631 PolyNode *q;
8632
8633 if (p->left == NULL)
8634 {
8635 fprintf (fp, "%d", p->index+1);
8636 if (sumtParams.isClock == NO)
8637 PrintFigTreeNodeInfo(fp, treeParts[p->partitionIndex], p->length);
8638 else if (sumtParams.isCalibrated == YES)
8639 PrintFigTreeNodeInfo(fp, treeParts[p->partitionIndex], p->anc->age - p->age);
8640 else
8641 PrintFigTreeNodeInfo(fp, treeParts[p->partitionIndex], p->anc->depth - p->depth);
8642 }
8643 else
8644 {
8645 fprintf (fp, "(");
8646 for (q = p->left; q != NULL; q = q->sib)
8647 {
8648 WriteFigTreeConTree (q, fp, treeParts);
8649 if (q->sib != NULL)
8650 fprintf (fp, ",");
8651 }
8652 fprintf (fp, ")");
8653 if (p->partitionIndex >= 0 && p->partitionIndex < numUniqueSplitsFound)
8654 {
8655 if (p->anc == NULL)
8656 {
8657 if (sumtParams.isClock == YES)
8658 PrintFigTreeNodeInfo(fp,treeParts[p->partitionIndex], -1.0);
8659 }
8660 else if (sumtParams.isClock == NO)
8661 PrintFigTreeNodeInfo(fp, treeParts[p->partitionIndex], p->length);
8662 else if (sumtParams.isCalibrated == YES)
8663 PrintFigTreeNodeInfo(fp, treeParts[p->partitionIndex], p->anc->age - p->age);
8664 else
8665 PrintFigTreeNodeInfo(fp, treeParts[p->partitionIndex], p->anc->depth - p->depth);
8666 }
8667 }
8668 }
8669
8670