source: branches/items/GDE/MrBAYES/mrbayes_3.2.1/utils.c

Last change on this file was 10416, checked in by aboeckma, 11 years ago

Added mr bayes (no menu yet)

File size: 36.2 KB
Line 
1/*
2 *  MrBayes 3
3 *
4 *  (c) 2002-2010
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 (maxim.teslenko@nrm.se)
22 *
23 *  and by many users (run 'acknowledgements' to see more info)
24 *
25 * This program is free software; you can redistribute it and/or
26 * modify it under the terms of the GNU General Public License
27 * as published by the Free Software Foundation; either version 2
28 * of the License, or (at your option) any later version.
29 *
30 * This program is distributed in the hope that it will be useful,
31 * but WITHOUT ANY WARRANTY; without even the implied warranty of
32 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
33 * GNU General Public License for more details (www.gnu.org).
34 *
35 */
36
37#include <stdlib.h>
38#include <string.h>
39#include <stdio.h>
40#include <ctype.h>
41#include <math.h>
42
43#include "mb.h"
44#include "globals.h"
45#include "utils.h"
46
47const char* const svnRevisionUtilsC="$Rev: 492 $";   /* Revision keyword which is expended/updated by svn on each commit/update*/
48
49/* AddBitfield: Add bitfield to list of bitfields */
50int AddBitfield (SafeLong ***list, int listLen, int *set, int setLen)
51{
52    int     i, nLongsNeeded;
53
54    nLongsNeeded = (setLen - 1) / nBitsInALong + 1;
55
56    (*list) = (SafeLong **) SafeRealloc ((void *)(*list), (size_t)((listLen+1)*sizeof(SafeLong *)));
57    if (!(*list))
58        return ERROR;
59   
60    (*list)[listLen] = (SafeLong *) SafeMalloc ((size_t)(nLongsNeeded*sizeof(SafeLong)));
61    if (!(*list)[listLen])
62        return ERROR;
63
64    ClearBits ((*list)[listLen], nLongsNeeded);
65    for (i=0; i<setLen; i++)
66        if (set[i] == YES)
67            SetBit(i, (*list)[listLen]);
68
69    return NO_ERROR;
70}
71
72
73
74
75
76#if defined (SSE_ENABLED)
77/* Aligned safe free */
78void AlignedSafeFree (void **ptr)
79{
80
81    ALIGNED_FREE (*ptr);
82
83    (*ptr) = NULL;
84}
85#endif
86
87
88
89
90
91/* ClearBit: Clear one bit in a bitfield */
92void ClearBit (int i, SafeLong *bits)
93{
94        SafeLong                x;
95
96        bits += i / nBitsInALong;
97
98        x = 1 << (i % nBitsInALong);
99    x ^= safeLongWithAllBitsSet;
100
101        (*bits) &= x;
102}
103
104
105
106
107
108/* ClearBits: Clear all bits in a bitfield */
109void ClearBits (SafeLong *bits, int nLongs)
110{
111        int     i;
112   
113    for (i=0; i<nLongs; i++)
114        bits[i] = 0;
115}
116
117
118
119
120
121/* CopyResults: copy results from one file to another up to lastGen*/
122int CopyResults (FILE *toFile, char *fromFileName, int lastGen)
123{
124    int     longestLine;
125    char    *strBuf, *strCpy, *word;
126    FILE    *fromFile;
127
128    if ((fromFile = OpenBinaryFileR(fromFileName)) == NULL)
129        return ERROR;
130
131    longestLine = LongestLine(fromFile)+10;
132    SafeFclose(&fromFile);
133    strBuf = (char *) SafeCalloc (2*(longestLine+2),sizeof(char));
134    strCpy = strBuf + longestLine + 2;
135
136    if ((fromFile = OpenTextFileR(fromFileName)) == NULL)
137        return ERROR;
138   
139    while (fgets(strBuf,longestLine,fromFile)!=NULL)
140        {
141        strncpy(strCpy,strBuf,longestLine);
142        word = strtok(strCpy," ");
143        /* atoi returns 0 when word is not integer number */
144        if (atoi(word)>lastGen)
145            break;
146        fprintf (toFile,"%s",strBuf);
147        fflush (toFile);
148        }
149   
150    SafeFclose(&fromFile);
151    free(strBuf);
152    return (NO_ERROR);
153}
154
155
156/* CopyProcessSsFile: copy results from one file to another up to lastStep. Also marginalLnLSS is collected for processed steps*/
157int CopyProcessSsFile (FILE *toFile, char *fromFileName, int lastStep, MrBFlt *marginalLnLSS, MrBFlt * splitfreqSS)
158{
159    int     longestLine, run, curStep, i;
160    double  tmp;
161    char    *strBuf, *strCpy, *word, *tmpcp;
162    FILE    *fromFile;
163
164    if ((fromFile = OpenBinaryFileR(fromFileName)) == NULL)
165        return ERROR;
166
167    longestLine = LongestLine(fromFile)+10;
168    SafeFclose(&fromFile);
169    strBuf = (char *) SafeCalloc (2*(longestLine+2),sizeof(char));
170    strCpy = strBuf + longestLine + 2;
171
172    if ((fromFile = OpenTextFileR(fromFileName)) == NULL)
173        return ERROR;
174   
175    while (fgets(strBuf,longestLine,fromFile)!=NULL)
176        {
177        strncpy(strCpy,strBuf,longestLine);
178        word = strtok(strCpy," \t\n");
179        /* atoi returns 0 when word is not integer number */
180        if (atoi(word)>lastStep)
181            break;
182        fprintf (toFile,"%s",strBuf);
183        fflush (toFile);
184        curStep = atoi(word);
185        if ( curStep > 0 )
186            {
187            strtok(NULL,"\t\n"); /*skip power*/
188            for (run=0; run<chainParams.numRuns; run++)
189                {
190                tmpcp = strtok(NULL,"\t\n");
191                if(tmpcp == NULL )
192                    {
193                    MrBayesPrint ("%s   Error: In .ss file not enough ellements on the string :%s        \n", spacer, strBuf);
194                    return ERROR;
195                    }
196                tmp = atof(tmpcp);
197                if(tmp == 0.0 )
198                    {
199                    MrBayesPrint ("%s   Error: Value of some step contribution is 0.0 or not a number in .ss file. Sting:%s        \n", spacer, strBuf);
200                    return ERROR;
201                    }
202                marginalLnLSS[run]+=tmp;
203                }
204                        for (i=0; i<numTopologies; i++)
205                                {
206                tmpcp = strtok(NULL,"\t\n");
207                if(tmpcp == NULL )
208                    {
209                    MrBayesPrint ("%s   Error: In .ss file not enough ellements on the string :%s        \n", spacer, strBuf);
210                    return ERROR;
211                    }
212                tmp = atof(tmpcp);
213                splitfreqSS[i*chainParams.numStepsSS + curStep-1] = tmp;               
214                        }
215            }
216        }
217   
218    SafeFclose(&fromFile);
219    free(strBuf);
220    return (NO_ERROR);
221}
222
223
224
225/* CopyTreeResults: copy tree results upto lastGen from one file to another. numTrees is return containing number of trees that were copied. */
226int CopyTreeResults (FILE *toFile, char *fromFileName, int lastGen, int *numTrees)
227{
228    int     longestLine;
229    char    *strBuf, *strCpy, *word;
230    FILE    *fromFile;
231   
232    (*numTrees) = 0;
233
234    if ((fromFile = OpenBinaryFileR(fromFileName)) == NULL)
235        return ERROR;
236
237    longestLine = LongestLine(fromFile)+10;
238    SafeFclose(&fromFile);
239    strBuf = (char *) SafeCalloc (2*(longestLine+2),sizeof(char));
240    strCpy = strBuf + longestLine + 2;
241
242    if ((fromFile = OpenTextFileR(fromFileName)) == NULL)
243        return ERROR;
244   
245    while (fgets(strBuf,longestLine,fromFile)!=NULL)
246        {
247        strncpy(strCpy,strBuf,longestLine);
248        word = strtok(strCpy," ");
249        if (strcmp(word,"tree")==0)
250            {
251            word = strtok(NULL," ");
252            /* atoi returns 0 when word is not integer number,
253               4 is offset to get rid of "rep." in tree name */
254            if (atoi(word+4)>lastGen)
255                break;
256            (*numTrees)++;
257            fprintf (toFile,"%s",strBuf);
258            }
259        else if (*numTrees == 0)   /* do not print the end statement */
260            fprintf (toFile,"%s",strBuf);
261        fflush (toFile);
262        }
263       
264    SafeFclose(&fromFile);
265    free(strBuf);
266    return (NO_ERROR);
267}
268
269
270
271
272
273/* FirstTaxonInPartition: Find index of first taxon in partition */
274int FirstTaxonInPartition (SafeLong *partition, int length)
275
276{
277
278    int         i, j, nBits, taxon;
279    SafeLong    x;
280
281    nBits = sizeof(SafeLong) * 8;
282
283    taxon = 0;
284    for (i=0; i<length; i++)
285                {
286                x = 1;
287                for (j=0; j<nBits; j++)
288                        {
289                        if (partition[i] & x)
290                                return taxon;
291                        taxon++;
292                        x <<= 1;
293                        }
294                }
295
296        return taxon;
297
298}
299
300
301
302
303
304/* FirstTree: Return file position of first tree after current position */
305SafeLong FirstTree (FILE *fp, char *lineBuf, int longestLine)
306{
307        SafeLong        firstTree;
308        char            *word;
309       
310        do {
311                firstTree = (int) ftell(fp);
312                if ((fgets (lineBuf, longestLine, fp)) == NULL)
313                        return 0;
314                word = strtok (lineBuf, " ");
315                } while (strcmp(word,"tree")!=0);
316
317        return (firstTree);
318}
319
320
321
322
323
324int Flip01 (int x)
325
326{
327
328        if (x == 0)
329                return (1);
330        else
331                return (0);
332               
333}
334
335
336
337
338
339void FlipBits (SafeLong *partition, int length, SafeLong *mask)
340
341{
342
343        int                     i;
344       
345        for (i=0; i<length; i++)
346                {
347                partition[i] ^= mask[i];
348                }
349}
350
351
352
353
354
355/*-----------------------------------------------------------------
356|
357|       FlipOneBit: flip bit n in SafeLong *p
358|
359------------------------------------------------------------------*/
360void FlipOneBit (int n, SafeLong *p)
361
362{
363
364        SafeLong                x;
365
366        p += n/nBitsInALong;
367        x = 1 << (n % nBitsInALong);
368        (*p) ^= x;
369
370}
371
372
373
374
375
376/* Convert from 0-based growth function over six states to model index */
377int FromGrowthFxnToIndex(int *growthFxn)
378{
379    int     i, j, k, max, fxn[6];
380
381    /* set local growth fxn to lexicographical max */
382    for (i=0; i<6; i++)
383        fxn[i] = i;
384
385    /* decrease until we reach growthFxn */
386    for (k=202; k>=0; k--)
387        {
388        for (i=0; i<6; i++)
389            {
390            if (fxn[i] != growthFxn[i])
391                break;
392            }
393        if (i == 6)
394            break;
395
396        /* get next growth fxn */
397        for (i=5; i>=0; i--)
398            {
399            fxn[i]--;
400            if (fxn[i] >= 0)
401                break;
402            }
403
404        if (i < 0)
405            return -1;  /* error */
406        else if (i < 5)
407            {
408            max = 0;
409            for (j=0; j<=i; j++)
410                {
411                if (fxn[j] > max)
412                    max = fxn[j];
413                }
414            fxn[++i] = max + 1;
415            for (++i; i<6; i++)
416                fxn[i] = fxn[i-1] + 1;
417            }
418        }
419
420    return k;
421}
422
423
424
425
426
427/* Convert from model index to 0-based growth function over six states */
428void FromIndexToGrowthFxn(int index, int *growthFxn)
429{
430    int     i, j, max, k;
431
432    /* set growth fxn to lexicographical max */
433    for (i=0; i<6; i++)
434        growthFxn[i] = i;
435
436    /* decrease until we reach index */
437    for (k=202; k>index; k--)
438        {
439        for (i=5; i>=0; i--)
440            {
441            growthFxn[i]--;
442            if (growthFxn[i] >= 0)
443                break;
444            }
445
446        if (i < 0)
447            return; /* ERROR */
448        else if (i < 5)
449            {
450            max = 0;
451            for (j=0; j<=i; j++)
452                {
453                if (growthFxn[j] > max)
454                    max = growthFxn[j];
455                }
456            growthFxn[++i] = max + 1;
457            for (++i; i<6; i++)
458                growthFxn[i] = growthFxn[i-1] + 1;
459            }
460        }
461}
462
463
464
465
466
467/* GetIntSummary: Get summary statistics for a number of runs (int version) */
468void GetIntSummary (int **vals, int nRows, int *rowCount, Stat *theStats, int HPD)
469
470{
471
472    int     i, j, nVals;
473    MrBFlt  *theValues, *p;
474
475    nVals = 0;
476    for (i=0; i<nRows; i++)
477        nVals += rowCount[i];
478
479    theValues = (MrBFlt *) SafeCalloc (nVals, sizeof(MrBFlt));
480
481    /* extract values */
482    p = theValues;
483    for (i=0; i<nRows; i++)
484        {
485        for (j=0; j<rowCount[i]; j++)
486            {
487            (*p++) = (MrBFlt) (vals[i][j]);
488            }
489        }
490   
491    /* get statistics */
492    MeanVariance (theValues, nVals, &(theStats->mean), &(theStats->var));
493    if (HPD == YES)
494        LowerUpperMedian (theValues, nVals, &(theStats->lower), &(theStats->upper), &(theStats->median));
495    else
496        LowerUpperMedian (theValues, nVals, &(theStats->lower), &(theStats->upper), &(theStats->median));
497
498    free (theValues);
499}
500
501
502
503
504
505/* Get k from 0-based growth function */
506int GetKFromGrowthFxn(int *growthFxn)
507{
508    int i, k=0;
509
510    for (i=0; i<6; i++)
511        if (growthFxn[i] > k)
512            k = growthFxn[i];
513   
514    return k+1;
515}
516
517
518
519
520
521/* GetSummary: Get summary statistics for a number of runs */
522void GetSummary (MrBFlt **vals, int nRows, int *rowCount, Stat *theStats, int HPD)
523
524{
525
526    int     i, nVals;
527    MrBFlt  *theValues, *p, *ESS;
528
529    nVals = 0;
530    for (i=0; i<nRows; i++)
531        nVals += rowCount[i];
532
533    theValues = (MrBFlt *) SafeMalloc ( (size_t) nVals* sizeof(MrBFlt));
534
535    /* extract values */
536    p = theValues;
537    for (i=0; i<nRows; i++)
538        {
539        memcpy((void *)(p),(void *)(vals[i]),(size_t)(rowCount[i]*sizeof(MrBFlt)));
540        p += rowCount[i];
541        }
542   
543    /* get statistics */
544    MeanVariance (theValues, nVals, &(theStats->mean), &(theStats->var));
545    if (HPD == YES)
546        LowerUpperMedianHPD (theValues, nVals, &(theStats->lower), &(theStats->upper), &(theStats->median));
547    else
548        LowerUpperMedian (theValues, nVals, &(theStats->lower), &(theStats->upper), &(theStats->median));
549    if (nRows > 1)
550        theStats->PSRF = PotentialScaleReduction (vals, nRows, rowCount);
551
552    ESS =   (MrBFlt *) SafeMalloc ((size_t) nRows * sizeof(MrBFlt));
553
554    EstimatedSampleSize (vals, nRows, rowCount, ESS);
555    theStats->avrESS = theStats->minESS = ESS[0];
556    for(i=1; i<nRows; i++)
557        {
558        theStats->avrESS += ESS[i];
559        if(theStats->minESS > ESS[i] )
560            {
561            theStats->minESS = ESS[i];
562            }
563        }
564    theStats->avrESS /=nRows;
565
566    free (ESS);
567    free (theValues);
568}
569
570
571
572
573
574/* HarmonicArithmeticMean: Calculate harmonic and arithmetic mean from log values */
575int HarmonicArithmeticMeanOnLogs (MrBFlt *vals, int nVals, MrBFlt *mean, MrBFlt *harm_mean)
576{
577        int                             i, reliable;
578        MrBFlt                  a, x, y, scaler, n;
579
580        reliable = YES;
581       
582        scaler = vals[nVals-1];
583        a  = n = 0.0;
584        for (i=0; i<nVals; i++)
585                {
586                y = vals[i];
587                y -= scaler;
588                if (y > 400.0)
589                        {
590            if (y > 5000.0)
591                {
592                            reliable = NO;
593                            continue;
594                }
595            a /= exp( y - 100.0 ); 
596            scaler += y - 100.0;
597            y = 100.0;
598                        }
599               
600            x = (MrBFlt) exp(y);
601                       
602                if (n < 0.5)
603                        a = x;
604                else
605                        {
606            a += x;
607                        }
608                n += 1.0;
609                }
610
611        /* arithmetic mean */
612        (*mean) = (MrBFlt) log(a/n) + scaler;
613       
614        scaler = (MrBFlt) (0.0 - vals[nVals-1]);
615        a  = n = 0.0;
616        for (i=0; i<nVals; i++)
617                {
618                y = (MrBFlt) (0.0 - vals[i]);
619                y -= scaler;
620                if (y > 400.0)
621                        {
622            if (y > 5000.0)
623                {
624                            reliable = NO;
625                            continue;
626                }
627            a /= exp( y - 100.0 ); 
628            scaler += y - 100.0;
629            y = 100.0;
630                        }
631               
632            x = (MrBFlt) exp(y);
633                       
634                if (n < 0.5)
635                        a = x;
636                else
637                        {
638            a += x;
639                        }
640                n += (MrBFlt) 1.0;
641                }
642
643        /* harmonic mean */
644        (*harm_mean) = - (MrBFlt) log(a/n) - scaler;
645
646        if (reliable == YES)
647                return (NO_ERROR);
648        else
649                return (ERROR);
650       
651}
652
653
654
655
656
657/* IsBitSet: Is bit i set in SafeLong *bits ? */
658int IsBitSet (int i, SafeLong *bits)
659
660{
661
662        SafeLong                x;
663
664        bits += i / nBitsInALong;
665
666        x = 1 << (i % nBitsInALong);
667
668        if ((*bits) & x)
669                return (YES);
670        else
671                return (NO);
672               
673}
674
675
676
677
678
679/* IsConsistentWith: Is token consistent with expected word, case insensitive ? */
680int IsConsistentWith (const char *token, const char *expected)
681{
682    int     i, len;
683
684    if (strlen(token) > strlen(expected))
685        return NO;
686
687    len = (int) strlen (token);
688
689    for (i=0; i<len; i++)
690        {
691        if (tolower(token[i]) != tolower(expected[i]))
692            return NO;
693        }
694
695    return YES;
696}
697
698
699
700
701
702/* IsPartCompatible: Determine whether two partitions are nonoverlapping or nested (compatible) or
703        incompatible (partially overlapping) */
704int IsPartCompatible (SafeLong *smaller, SafeLong *larger, int length)
705{
706        int i;
707
708    /* test first if they overlap */
709        for (i=0; i<length; i++)
710                if ((smaller[i]&larger[i]) != 0)
711                        break;
712
713        /* if they overlap, they must be nested */
714    if (i != length)    /* potentially incompatible */
715                {
716                for (i=0; i<length; i++)
717                        if ((smaller[i]|larger[i]) != larger[i])
718                                break;
719                }
720               
721        if (i == length)        /* passed either one of the tests */
722                return YES;
723        else
724                return NO;
725}
726
727
728
729
730/* IsPartNested: Test whether smaller partition is nested in larger partition */
731int IsPartNested (SafeLong *smaller, SafeLong *larger, int length)
732
733{
734
735        int i;
736
737        for (i=0; i<length; i++)
738                if ((smaller[i] | larger[i]) != larger[i])
739                        break;
740               
741        if (i == length)
742                return YES;
743        else
744                return NO;
745
746}
747
748
749
750
751
752/* IsSectionEmpty: Test whether section of two bitfields is empty */
753int IsSectionEmpty (SafeLong *bitField1, SafeLong *bitField2, int length)
754{
755        int i;
756
757        for (i=0; i<length; i++)
758                if ((bitField1[i] & bitField2[i]) != 0)
759                        return NO;
760               
761        return YES;
762}
763
764
765
766
767
768/* IsSectionEmpty: Test whether union of bitField1 and bitField2 equal to bitField3*/
769int IsUnionEqThird (SafeLong *bitField1, SafeLong *bitField2, SafeLong *bitField3, int length)
770{
771        int i;
772
773        for (i=0; i<length; i++)
774                if ((bitField1[i] | bitField2[i]) != bitField3[i] )
775                        return NO;
776               
777        return YES;
778}
779
780
781
782
783
784/* LastBlock: Return file position of last block in file */
785SafeLong LastBlock (FILE *fp, char *lineBuf, int longestLine)
786{
787        SafeLong        lastBlock;
788        char    *word;
789       
790        lastBlock = 0L;
791        rewind (fp);
792
793        while ((fgets (lineBuf, longestLine, fp)) != NULL)
794                {
795                word = strtok (lineBuf, " ");
796                if (strcmp (word, "begin") == 0)
797                        lastBlock = (int) ftell (fp);
798                }
799
800        return lastBlock;
801}
802
803
804
805
806
807int LineTermType (FILE *fp)
808
809{
810
811        int                     ch, nextCh, term;
812
813        term = LINETERM_UNIX;   /* default if no line endings are found */
814        while ((ch = getc(fp)) != EOF)
815                {
816                if ((ch == '\n') || (ch == '\r'))
817                        {
818                        if (ch == '\n')
819                                term = LINETERM_UNIX;
820                        else /* ch = '\r' */
821                                {
822                                /* First test below handles one-line MAC file */
823                                if (((nextCh = getc(fp)) == EOF) || (nextCh != '\n'))
824                                        term = LINETERM_MAC;
825                                else
826                                        term = LINETERM_DOS;
827                                }
828                        break;
829                        }
830                }
831        (void)fseek(fp, 0L, 0);         /* rewind */
832       
833        return (term);
834
835}
836
837
838
839
840/*The longest line in a file including line terminating characters present in binary mode.*/
841int LongestLine (FILE *fp)
842
843{
844
845        int                     ch, lineLength, longest;
846       
847        longest = 0;
848        lineLength = 0;
849        ch = fgetc(fp);
850        while ( ch != EOF)
851                {
852                if((ch != '\n') && (ch != '\r'))
853                        {
854                        ch = fgetc(fp);
855                        lineLength++;
856                        continue;
857                        }
858                if (ch == '\r')
859                        {
860                        if( (ch = fgetc(fp)) == '\n' )
861                                {
862                                /* windows \r\n */
863                                lineLength++;
864                                ch = fgetc(fp);
865                                }
866                        else
867                                {
868                                /* old mac \r */
869                                }
870                        }
871                else  /*unix, linux,new mac or text mode read \n*/
872                        {
873                                ch = fgetc(fp);
874                        }
875
876                if (lineLength > longest)
877                                longest = lineLength;
878                        lineLength = 0;
879                /*
880                if ((ch == '\n') || (ch == '\r'))
881                        {
882                        if (lineLength > longest)
883                                longest = lineLength;
884                        lineLength = 0;
885                        }
886                else
887                        lineLength++;
888                        */
889                }
890        rewind (fp);            /* rewind */
891       
892        return (longest+1); /*+1 to accommodate last character*/
893
894}
895
896
897
898
899
900/* LowerUpperMedian: Determine median and 95 % credible interval */
901void LowerUpperMedian (MrBFlt *vals, int nVals, MrBFlt *lower, MrBFlt *upper, MrBFlt *median)
902
903{   
904    SortMrBFlt (vals, 0, nVals-1);
905   
906    *lower  = vals[(int)(0.025*nVals)];
907    *upper  = vals[(int)(0.975*nVals)];
908    *median = vals[nVals/2];
909
910}
911
912
913
914
915/* LowerUpperMedianHPD: Use a simple way to determine HPD */
916void LowerUpperMedianHPD (MrBFlt *vals, int nVals, MrBFlt *lower, MrBFlt *upper, MrBFlt *median)
917{
918    int     i, width, theStart;
919    MrBFlt  f, g, interval;
920
921        SortMrBFlt (vals, 0, nVals-1);
922   
923    width = (int)(nVals * 0.95 + 0.5);
924    theStart = 0;
925    interval = vals[width-1] - vals[0];
926    for (i=1; i<nVals-width; i++)
927    {
928        f = vals[i];
929        g = vals[i+width];
930        if (g - f < interval)
931        {
932            interval = g - f;
933            theStart = i;
934        }
935    }
936
937    *lower  = vals[theStart];
938    *upper  = vals[theStart+width-1];
939    *median = vals[nVals/2];
940}
941
942
943
944
945
946/*NOTE!!!! The result of this function should be used before consequtive call to it again. It means NEVER use it like this:  printf( "%s %s", MbPrintNum (a),MbPrintNum (b) ) */
947char *MbPrintNum (MrBFlt num)
948{
949    static char s[40];
950
951    if (scientific == YES)
952        sprintf(s,"%.*le", precision, num);
953    else
954        sprintf(s,"%.*lf", precision, num);
955
956    return s;
957}
958
959
960
961
962
963void MeanVariance (MrBFlt *vals, int nVals, MrBFlt *mean, MrBFlt *var)
964
965{
966
967        int                             i;
968        MrBFlt                  a, aOld, s, x;
969
970        a = s = 0.0;
971        for (i=0; i<nVals; i++)
972                {
973                x = vals[i];
974                aOld = a;
975                a += (x - a) / (MrBFlt) (i + 1);
976                s += (x - a) * (x - aOld);
977                }
978
979        /* mean */
980        (*mean) = a;
981       
982        /* variance */
983        if (nVals <= 1)
984                (*var) = 0.0;
985        else
986                (*var) = s / (nVals - 1);
987                       
988}
989
990
991
992
993
994/*  Compute mean and variance of log scaled values.
995
996@param vals    pointer to values in log scale
997@param nVals   number of "vals", minimum 1
998@param mean    adress of variable where computed mean is returned by the function
999@param var     adress of variable where computed variance is returned by the function. Could be set to NULL if this value need not to be returened.
1000@param varEst  adress of variable where computed estimate of the population variance is returned, could be set to NULL if this value need not to be returened.
1001               Could be set to NULL if this value need not to be returened.
1002
1003Note: We devide by nVals or by (nVals-1) when var and varEst is calculated from the sum of square differences.
1004    */
1005void MeanVarianceLog (MrBFlt *vals, int nVals, MrBFlt *mean, MrBFlt *var, MrBFlt *varEst )
1006
1007{
1008
1009        int                             i;
1010        MrBFlt                  a, aOld, s, x, y, scaler;
1011
1012        a = s = 0.0;
1013    scaler = vals[nVals-1];
1014        for (i=0; i<nVals; i++)
1015                {
1016                y = vals[i];
1017                y -= scaler;
1018                if (y > 200.0)
1019                        {
1020            a /= exp( y - 100.0 );
1021            s /= exp( 2*(y - 100));
1022            scaler += y - 100.0;
1023            y = 100.0;
1024                        }
1025
1026        x=(MrBFlt)exp(y);
1027
1028                aOld = a;
1029                a += (x - a) / (MrBFlt) (i + 1);
1030                s += (x - a) * (x - aOld);
1031                }
1032
1033        /* mean */
1034        (*mean) = log(a) + scaler;
1035       
1036        /* variance */
1037    if( var!=NULL )
1038        {
1039            if (nVals <= 1)
1040                    (*var) = 0.0;
1041            else
1042                    (*var) = log( s / (nVals)) + 2*scaler;
1043        }
1044
1045        /* variance */
1046    if( varEst!=NULL )
1047        {
1048            if (nVals <= 1)
1049                    (*varEst) = 0.0;
1050            else
1051                    (*varEst) = log( s / (nVals+1)) + 2*scaler;
1052        }
1053                       
1054}
1055
1056
1057
1058
1059
1060void MrBayesPrint (char *format, ...)
1061
1062{
1063        va_list ptr;
1064
1065#       if defined (MPI_ENABLED)
1066        if (proc_id == 0)
1067                {
1068                if (echoMB == YES)
1069                        {
1070                        va_start (ptr, format);
1071                        vprintf (format, ptr);
1072                        va_end(ptr);
1073                        fflush (stdout);
1074                        }
1075                if (logToFile == YES)
1076                        {
1077                        if (logFileFp == NULL)
1078                                printf ("%s   Could not print log output to file\n", spacer);
1079                        else
1080                                {
1081                                va_start (ptr, format);
1082                                vfprintf (logFileFp, format, ptr);
1083                                va_end(ptr);
1084                                fflush (logFileFp);
1085                                }
1086                        }
1087                }
1088#       else
1089        if (chainParams.redirect == NO)
1090                {
1091                if (echoMB == YES)
1092                        {
1093                        va_start (ptr, format);
1094                        vprintf (format, ptr);
1095                        va_end(ptr);
1096                        fflush (stdout);
1097                        }
1098                if (logToFile == YES)
1099                        {
1100                        if (logFileFp == NULL)
1101                                {
1102                                printf ("%s   Could not print log output to file\n", spacer);
1103                                logToFile = NO;
1104                                }
1105                        else
1106                                {
1107                                va_start (ptr, format);
1108                                vfprintf (logFileFp, format, ptr);
1109                                va_end(ptr);
1110                                fflush (logFileFp);
1111                                }
1112                        }
1113                }
1114#       endif
1115}
1116
1117
1118
1119
1120void MrBayesPrintf (FILE *f, char *format, ...)
1121
1122{
1123        va_list                 ptr;
1124
1125#       if defined (MPI_ENABLED)
1126        if (proc_id == 0)
1127                {
1128                va_start (ptr, format);
1129                vfprintf (f, format, ptr);
1130                va_end(ptr);
1131                fflush(f);
1132                }
1133#       else
1134        va_start (ptr, format);
1135        vfprintf (f, format, ptr);
1136        va_end(ptr);
1137        fflush(f);
1138#       endif
1139}
1140
1141
1142
1143
1144
1145/** Next taxon in partition, for cycling over set bits in bit fields */
1146int NextTaxonInPartition(int currentTaxon, SafeLong *partition, int length)
1147{
1148    int         i, j, taxon;
1149    SafeLong    x;
1150
1151    taxon = currentTaxon + 1;
1152    i = taxon / nBitsInALong;
1153    x = (1 << taxon % nBitsInALong);
1154    for (j=taxon%nBitsInALong; j<nBitsInALong; j++)
1155        {
1156        if (partition[i] & x)
1157            return taxon;
1158        taxon++;
1159        x <<= 1;
1160        }
1161
1162    for (i++; i<length; i++)
1163                {
1164                x = 1;
1165                for (j=0; j<nBitsInALong; j++)
1166                        {
1167                        if (partition[i] & x)
1168                                return taxon;
1169                        taxon++;
1170                        x <<= 1;
1171                        }
1172                }   
1173
1174    return taxon;
1175}
1176
1177
1178
1179
1180
1181/* NumBits: Count bits in a bitfield */
1182int NumBits (SafeLong *x, int len)
1183{
1184        int         i, n=0;
1185    SafeLong    y;
1186
1187        for (i=0; i<len; i++)
1188        {
1189        y = x[i];
1190        while (y != 0)
1191            {
1192                    y &= (y-1);
1193            n++;
1194            }
1195        }
1196        return n;
1197}
1198
1199
1200
1201
1202
1203FILE *OpenBinaryFileR (char *name)
1204
1205{
1206
1207        FILE            *fp;
1208    char        fileName[200];
1209
1210    strcpy(fileName, workingDir);
1211    strncat(fileName, name, 199 - strlen(fileName));
1212
1213    if ((fp = fopen (fileName, "rb")) == NULL) 
1214                {   
1215                MrBayesPrint ("%s   Could not open file \"%s\"\n", spacer, name);
1216                return (NULL);
1217                }
1218        else
1219                return (fp);
1220       
1221}
1222
1223
1224
1225
1226
1227FILE *OpenTextFileR (char *name)
1228{
1229
1230        FILE            *fp;
1231    char        fileName[200];
1232
1233    strcpy(fileName, workingDir);
1234    strncat(fileName, name, 199 - strlen(fileName));
1235
1236    if ((fp = fopen (fileName, "r")) == NULL) 
1237                {   
1238                MrBayesPrint ("%s   Could not open file \"%s\"\n", spacer, fileName);
1239                return (NULL);
1240                }
1241        else
1242                return (fp);
1243       
1244}
1245
1246
1247
1248
1249FILE *OpenTextFileRQuait (char *name)
1250{
1251
1252        FILE            *fp;
1253    char        fileName[200];
1254
1255    strcpy(fileName, workingDir);
1256    strncat(fileName, name, 199 - strlen(fileName));
1257
1258    if ((fp = fopen (fileName, "r")) == NULL) 
1259                {   
1260                return (NULL);
1261                }
1262        else
1263                return (fp);
1264       
1265}
1266
1267
1268
1269
1270
1271FILE *OpenTextFileA (char *name)
1272
1273{
1274
1275        FILE            *fp;
1276    char        fileName[200];
1277
1278    strcpy(fileName, workingDir);
1279    strncat(fileName, name, 199 - strlen(fileName));
1280
1281    if ((fp = fopen (fileName, "a+")) == NULL) 
1282                {   
1283                MrBayesPrint ("%s   Could not open file \"%s\"\n", spacer, name);
1284                return (NULL);
1285                }
1286        else
1287                return (fp);
1288       
1289}
1290
1291
1292
1293
1294
1295FILE *OpenTextFileW (char *name)
1296
1297{
1298
1299        FILE            *fp;
1300    char        fileName[200];
1301
1302    strcpy(fileName, workingDir);
1303    strncat(fileName, name, 199 - strlen(fileName));
1304
1305        if ((fp = fopen (fileName, "w+")) == NULL) 
1306                {   
1307                MrBayesPrint ("%s   Could not open file \"%s\"\n", spacer, name);
1308                return (NULL);
1309                }
1310        else
1311                return (fp);
1312       
1313}
1314
1315
1316
1317
1318
1319/*!
1320\param vals[0..nRuns][count[]]   All records for all runs
1321\param nRuns                     Number of runs
1322\param count[0..nRuns]           Number of records in each run
1323\return PSRF
1324*/
1325MrBFlt PotentialScaleReduction (MrBFlt **vals, int nRuns, int *count)
1326
1327{
1328
1329        int                             i, j, nVals;
1330        MrBFlt                  aW, aOldW, sW, sWj, aB, aOldB, sB, x, R2, weight;
1331
1332        aB = sB = sW = sWj = 0.0;
1333    nVals = 0;
1334        for (j=0; j<nRuns; j++)
1335                {
1336                if(count[j]==0)
1337                        {
1338                        return -1.0;
1339                        }
1340                nVals += count[j];
1341                aW = vals[j][0];
1342                for (i=1; i<count[j]; i++)
1343                        {
1344                        x = vals[j][i];
1345                        aOldW = aW;
1346                        aW += (x - aW) / (MrBFlt) (i + 1);
1347                        sWj += (x - aW) * (x - aOldW);
1348                        }
1349        sW += sWj / (MrBFlt)(count[j] - 1);
1350                x = aW;
1351                aOldB = aB;
1352                aB += (x - aB) / (MrBFlt) (j + 1);
1353                if (j!=0)
1354                        sB += (x - aB) * (x - aOldB);
1355                }
1356
1357        sB = sB / (MrBFlt) (nRuns - 1);
1358        sW = sW / (MrBFlt) (nRuns);
1359
1360        weight = (MrBFlt) nVals / (MrBFlt) nRuns;
1361    if (sW > 0.0)
1362                {
1363                R2 = ((weight - 1.0) / weight) + ((MrBFlt)(nRuns + 1) / (MrBFlt) (nRuns)) * (sB / sW);
1364                return sqrt(R2);
1365                }
1366        else
1367                return -1.0;
1368}
1369
1370
1371
1372
1373
1374/*!
1375\param vals[0..nRuns][count[]]   All records for all runs
1376\param nRuns                     Number of runs
1377\param count[0..nRuns]           Number of records in each run
1378\param returnESS[0..nRuns]       Is an arry in which the routine returns ESS values for each run.
1379*/
1380void EstimatedSampleSize (MrBFlt **vals, int nRuns, int *count, MrBFlt *returnESS)
1381{
1382
1383        int                 i, j, lag, maxLag, samples;
1384    MrBFlt      *values, mean, del1, del2, varStat=0.0;
1385    MrBFlt      gammaStat[2000];
1386       
1387    for( i=0; i<nRuns; i++)
1388        {
1389        samples=count[i];
1390        values=vals[i];
1391        mean=0.0;
1392        for(j=0; j<samples; j++ )
1393            {
1394            mean+=values[j];
1395            }
1396        mean /=samples;
1397
1398        maxLag = ((samples - 1) > 2000)?2000:(samples - 1);
1399
1400        for (lag = 0; lag < maxLag; lag++)
1401            {
1402            gammaStat[lag]=0;
1403            for (j = 0; j < samples - lag; j++) 
1404                {
1405                del1 = values[j] - mean;
1406                del2 = values[j + lag] - mean;
1407                gammaStat[lag] += (del1 * del2);
1408                }
1409
1410            gammaStat[lag] /= ((MrBFlt) (samples - lag));
1411
1412            if (lag == 0) 
1413                {
1414                varStat = gammaStat[0];
1415                } 
1416            else if (lag % 2 == 0) 
1417                {
1418                if (gammaStat[lag - 1] + gammaStat[lag] > 0) 
1419                    {
1420                    varStat += 2.0 * (gammaStat[lag - 1] + gammaStat[lag]);
1421                    }
1422                else
1423                    maxLag = lag;
1424                }
1425            }
1426        returnESS[i] = (gammaStat[0] * samples) / varStat;
1427        }
1428
1429}
1430
1431
1432
1433
1434
1435/* SafeCalloc: Print error if out of memory */
1436void *SafeCalloc(size_t n, size_t s) {
1437
1438    void *ptr;
1439   
1440    if( s*n == 0 )
1441        {
1442        //return NULL;
1443        }
1444
1445    ptr= calloc(n, s);
1446
1447    if(ptr==NULL)
1448        {
1449        MrBayesPrint ("%s   Out of memory. Most probable course for the problem is that MrBayes reached\n", spacer);
1450        MrBayesPrint ("%s   the limit of allowed memory for a process in your Operating System. Consult\n", spacer);
1451        MrBayesPrint ("%s   documentation of your OS how to extend the limit, or use 64 bit version OS \n", spacer);
1452        MrBayesPrint ("%s   and compile 64 bit version of MrBayes.                                     \n", spacer);
1453        MrBayesPrint ("%s   Segmentation fault may follow.                                             \n", spacer);
1454        return NULL;
1455        }
1456
1457    return ptr;
1458}
1459
1460
1461
1462
1463
1464int SafeFclose(FILE **fp) {
1465        int retval=-1;
1466#if defined MPI_ENABLED
1467        if (proc_id == 0) {
1468#endif
1469        if( fp!=NULL && (*fp)!=NULL ) 
1470                retval=fclose(*fp);
1471        *fp = NULL;
1472#if defined MPI_ENABLED
1473        }
1474#endif
1475        return retval; 
1476}
1477
1478
1479
1480
1481
1482/* SafeFree: Set pointer to freed space to NULL */
1483void SafeFree (void **ptr)
1484{
1485    free (*ptr);
1486
1487    (*ptr) = NULL;
1488}
1489
1490
1491
1492
1493
1494/* SafeMalloc: Print error if out of memory; clear memory */
1495void *SafeMalloc(size_t s) {
1496
1497    void *ptr;
1498
1499    if( s==0 )
1500        {
1501        return NULL;
1502        }
1503
1504    ptr= malloc(s);
1505
1506    if(ptr==NULL)
1507        {
1508        MrBayesPrint ("%s   Out of memory. Most probable course for the problem is that MrBayes reached\n", spacer);
1509        MrBayesPrint ("%s   the limit of allowed memory for a process in your Operating System. Consult\n", spacer);
1510        MrBayesPrint ("%s   documentation of your OS how to extend the limit, or use 64 bit version OS \n", spacer);
1511        MrBayesPrint ("%s   and compile 64 bit version of MrBayes.                                     \n", spacer);
1512        MrBayesPrint ("%s   Segmentation fault may follow.                                             \n", spacer);
1513        return NULL;
1514        }
1515
1516    return memset(ptr,0,s);
1517}
1518
1519
1520
1521
1522
1523/* SafeRealloc: Print error if out of memory */
1524void *SafeRealloc(void *ptr, size_t s) {
1525
1526    if( s==0 )
1527        {
1528        free(ptr);
1529        return NULL;
1530        }
1531
1532    if (ptr == NULL)
1533        {
1534        ptr = malloc (s);
1535        memset(ptr, 0, s);
1536        }
1537    else
1538        ptr = realloc (ptr, s);
1539
1540    if(ptr==NULL)
1541        {
1542        MrBayesPrint ("%s   Out of memory. Most probable course for the problem is that MrBayes reached\n", spacer);
1543        MrBayesPrint ("%s   the limit of allowed memory for a process in your Operating System. Consult\n", spacer);
1544        MrBayesPrint ("%s   documentation of your OS how to extend the limit, or use 64 bit version OS \n", spacer);
1545        MrBayesPrint ("%s   and compile 64 bit version of MrBayes.                                     \n", spacer);
1546        MrBayesPrint ("%s   Segmentation fault may follow.                                             \n", spacer);
1547        return NULL;
1548        }
1549
1550    return ptr;
1551}
1552
1553
1554
1555
1556
1557/* SafeStrcat: Allocate or reallocate target to fit result; assumes ptr is NULL if not allocated */
1558char *SafeStrcat (char **target, const char *source)
1559{
1560    if (*target == NULL)
1561        *target = (char *) SafeCalloc (strlen(source)+1, sizeof(char));
1562    else
1563        *target = (char *) SafeRealloc ((void *)*target, (size_t)(strlen(source)+strlen(*target)+1)*sizeof(char));
1564
1565    if (*target)
1566        strcat(*target,source);
1567
1568    return (*target);
1569}
1570
1571
1572
1573
1574/* SafeStrcpy: Allocate or reallocate target to fit result; assumes ptr is NULL if not allocated */
1575char *SafeStrcpy (char **target, const char *source)
1576{
1577
1578    *target = (char *) SafeRealloc ((void *)*target, (size_t)(strlen(source)+1)*sizeof(char));
1579
1580    if (*target)
1581        strcpy(*target,source);
1582
1583    return (*target);
1584}
1585
1586
1587
1588
1589
1590/* SetBit: Set a particular bit in a series of longs */
1591void SetBit (int i, SafeLong *bits)
1592{
1593        SafeLong                x;
1594
1595        bits += i / nBitsInALong;
1596
1597        x = 1 << (i % nBitsInALong);
1598
1599        (*bits) |= x;
1600}
1601
1602
1603
1604
1605
1606void SortInts (int *item, int *assoc, int count, int descendingOrder)
1607
1608{
1609
1610        SortInts2 (item, assoc, 0, count-1, descendingOrder);
1611
1612}
1613
1614
1615
1616
1617
1618void SortInts2 (int *item, int *assoc, int left, int right, int descendingOrder)
1619
1620{
1621
1622        register int    i, j, x, y;
1623
1624        if (descendingOrder == YES)
1625                {
1626                i = left;
1627                j = right;
1628                x = item[(left+right)/2];
1629                do 
1630                        {
1631                        while (item[i] > x && i < right)
1632                                i++;
1633                        while (x > item[j] && j > left)
1634                                j--;
1635                        if (i <= j)
1636                                {
1637                                y = item[i];
1638                                item[i] = item[j];
1639                                item[j] = y;
1640                               
1641                                if (assoc)
1642                                        {
1643                                        y = assoc[i];
1644                                        assoc[i] = assoc[j];
1645                                        assoc[j] = y;
1646                                        }                               
1647                                i++;
1648                                j--;
1649                                }
1650                        } while (i <= j);
1651                if (left < j)
1652                        SortInts2 (item, assoc, left, j, descendingOrder);
1653                if (i < right)
1654                        SortInts2 (item, assoc, i, right, descendingOrder);
1655                }
1656        else
1657                {
1658                i = left;
1659                j = right;
1660                x = item[(left+right)/2];
1661                do 
1662                        {
1663                        while (item[i] < x && i < right)
1664                                i++;
1665                        while (x < item[j] && j > left)
1666                                j--;
1667                        if (i <= j)
1668                                {
1669                                y = item[i];
1670                                item[i] = item[j];
1671                                item[j] = y;
1672                               
1673                                if (assoc)
1674                                        {
1675                                        y = assoc[i];
1676                                        assoc[i] = assoc[j];
1677                                        assoc[j] = y;
1678                                        }                               
1679                                i++;
1680                                j--;
1681                                }
1682                        } while (i <= j);
1683                if (left < j)
1684                        SortInts2 (item, assoc, left, j, descendingOrder);
1685                if (i < right)
1686                        SortInts2 (item, assoc, i, right, descendingOrder);
1687                }
1688
1689}
1690
1691
1692
1693
1694
1695/* SortMrBFlt: Sort in increasing order */
1696void SortMrBFlt (MrBFlt *item, int left, int right)
1697
1698{
1699
1700        register int    i, j;
1701        MrBFlt                  x, temp;
1702
1703        i = left;
1704        j = right;
1705        x = item[(left+right)/2];
1706        do 
1707                {
1708                while (item[i] < x && i < right)
1709                        i++;
1710                while (x < item[j] && j > left)
1711                        j--;
1712                if (i <= j)
1713                        {
1714                        temp = item[i];
1715                        item[i] = item[j];
1716                        item[j] = temp;
1717                               
1718                        i++;
1719                        j--;
1720                        }
1721                } while (i <= j);
1722        if (left < j)
1723                SortMrBFlt (item, left, j);
1724        if (i < right)
1725                SortMrBFlt (item, i, right);
1726}
1727
1728
1729
1730
1731
1732/* StrCmpCaseInsensitive: Case insensitive string comparison */
1733int StrCmpCaseInsensitive (char *s, char *t)
1734{
1735    int i, minLen;
1736
1737    if (strlen(s) < strlen(t))
1738        minLen = (int) strlen(s);
1739    else
1740        minLen = (int) strlen(t);
1741
1742    for (i=0; i<minLen; i++)
1743        if (tolower(s[i])!= tolower(t[i]))
1744            break;
1745
1746    if (s[i] == '\0' && t[i] == '\0')
1747        return 0;
1748    else if (tolower(s[i]) > tolower(t[i]))
1749        return 1;
1750    else
1751        return -1;
1752}
1753
1754
1755
1756
1757
1758/* StripComments: Strip possibly nested comments from the string s.
1759        Example: s="text1[text2[text3]]"-> s="text1" */
1760void StripComments (char *s)
1761{
1762        char    *t;
1763        int             inComment;
1764
1765        inComment = 0;
1766        for (t=s; *s != '\0'; s++)
1767                {
1768                if (inComment == 0)
1769                        {
1770                        if (*s == '[')
1771                                inComment++;
1772                        else
1773                                *t++ = *s;
1774                        }
1775                else
1776                        {
1777                        if (*s == ']')
1778                                inComment--;
1779            else if (*s == '[')
1780                inComment++;
1781                        }
1782                }
1783    *t = '\0';
1784}
1785
1786
1787
1788
1789
1790FILE *TestOpenTextFileR (char *name)
1791
1792{
1793    char        fileName[100];
1794
1795    strcpy(fileName, workingDir);
1796    strncat(fileName, name, 99 - strlen(fileName));
1797
1798    return fopen (fileName, "r");       
1799}
1800
1801
1802
1803
1804
1805/*---------
1806|
1807|   UpdateGrowthFxn: We expect a set of unique indexes from 0 to 5
1808|      indicating a partition of 6 rates into sets. We make sure
1809|      the indices correspond to a restricted growth function here.
1810|
1811-----------------------*/
1812void UpdateGrowthFxn(int *growthFxn)
1813{
1814    int     i, j, max, fxn[6];
1815
1816    for (i=0; i<6; i++)
1817        fxn[i] = -1;
1818
1819    max = 0;
1820    for (i=0; i<6; i++)
1821        {
1822        if (fxn[i] != -1)
1823            continue;
1824        for (j=i; j<6; j++)
1825            {
1826            if (growthFxn[j] == growthFxn[i])
1827                fxn[j] = max;
1828            }
1829        max++;
1830        }
1831
1832    for (i=0; i<6; i++)
1833        growthFxn[i] = fxn[i];   
1834}
1835
1836
1837
1838
1839
1840int UpperTriangIndex(int i, int j, int size)
1841{
1842    if (i < j)
1843        return (2*size - i - 3) * i / 2 + j - 1;
1844    else
1845        return (2*size - j - 3) * j / 2 + i - 1;
1846}
1847
1848
1849
1850
1851
1852int WantTo (const char *msg)
1853{
1854    char    s[100];
1855    int     i;
1856
1857    MrBayesPrint ("%s   %s? (yes/no): ", spacer, msg);
1858
1859        for (i=0; i<10; i++)
1860            {
1861            if (fgets (s, 98, stdin) == NULL)
1862                    {
1863                    MrBayesPrint ("%s   Failed to retrieve answer; will take that as a no\n", spacer);
1864                    return NO;
1865                    }
1866
1867        /* Strip away the newline */
1868        s[strlen(s)-1] = '\0';
1869
1870        /* Check answer */
1871        if (IsConsistentWith (s, "yes") == YES)
1872            return YES;
1873        else if (IsConsistentWith (s, "no") == YES)
1874            return NO;
1875
1876        MrBayesPrint ("%s   Enter yes or no: ", spacer);
1877            }
1878
1879    MrBayesPrint ("%s   MrBayes does not understand; will take that as a no\n", spacer);
1880
1881    return NO;
1882}
1883
1884
1885
Note: See TracBrowser for help on using the repository browser.