source: trunk/GDE/RAxML/multiple.c

Last change on this file was 19480, checked in by westram, 17 months ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 46.4 KB
Line 
1/*  RAxML-VI-HPC (version 2.2) a program for sequential and parallel estimation of phylogenetic trees
2 *  Copyright August 2006 by Alexandros Stamatakis
3 *
4 *  Partially derived from
5 *  fastDNAml, a program for estimation of phylogenetic trees from sequences by Gary J. Olsen
6 * 
7 *  and
8 *
9 *  Programs of the PHYLIP package by Joe Felsenstein.
10 *
11 *  This program is free software; you may redistribute it and/or modify its
12 *  under the terms of the GNU General Public License as published by the Free
13 *  Software Foundation; either version 2 of the License, or (at your option)
14 *  any later version.
15 *
16 *  This program is distributed in the hope that it will be useful, but
17 *  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18 *  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19 *  for more details.
20 *
21 *
22 *  For any other enquiries send an Email to Alexandros Stamatakis
23 *  Alexandros.Stamatakis@epfl.ch
24 *
25 *  When publishing work that is based on the results from RAxML-VI-HPC please cite:
26 *
27 *  Alexandros Stamatakis:"RAxML-VI-HPC: maximum likelihood-based phylogenetic analyses with thousands of taxa and mixed models".
28 *  Bioinformatics 2006; doi: 10.1093/bioinformatics/btl446
29 */
30
31
32#ifndef WIN32
33#include <unistd.h>
34#endif
35
36#include <math.h>
37#include <time.h>
38#include <stdlib.h>
39#include <stdio.h>
40#include <ctype.h>
41#include <string.h>
42#include "axml.h"
43
44#ifdef _WAYNE_MPI
45#include <mpi.h>
46extern int processID;
47extern int processes;
48#endif
49
50extern int  optimizeRatesInvocations;
51extern int  optimizeRateCategoryInvocations;
52extern int  optimizeAlphaInvocations;
53extern int  optimizeInvarInvocations;
54extern int  checkPointCounter;
55extern int  Thorough;
56extern int  partCount;
57extern char tree_file[1024];
58extern const unsigned int mask32[32];
59extern double masterTime;
60
61extern FILE   *INFILE, *permutationFile, *logFile, *infoFile;
62
63extern char seq_file[1024];
64extern char permFileName[1024], resultFileName[1024], 
65  logFileName[1024], checkpointFileName[1024], infoFileName[1024], run_id[128], workdir[1024], bootStrapFile[1024], bootstrapFileName[1024], 
66  bipartitionsFileName[1024],bipartitionsFileNameBranchLabels[1024]; 
67
68
69
70
71void catToGamma(tree *tr, analdef *adef)
72{
73  assert(tr->rateHetModel == CAT); 
74 
75  if(adef->useInvariant)
76    tr->rateHetModel = GAMMA_I;
77  else
78    tr->rateHetModel = GAMMA;
79
80 
81#ifdef _USE_PTHREADS
82  masterBarrier(THREAD_CAT_TO_GAMMA, tr); 
83#endif
84}
85
86void gammaToCat(tree *tr)
87{
88
89  assert(tr->rateHetModel == GAMMA || tr->rateHetModel == GAMMA_I);
90   
91  tr->rateHetModel = CAT;
92
93 
94#ifdef _USE_PTHREADS
95  masterBarrier(THREAD_GAMMA_TO_CAT, tr); 
96#endif 
97}
98
99
100static void singleBootstrap(tree *tr, int i, analdef *adef, rawdata *rdta, cruncheddata *cdta)
101{
102  tr->treeID = i;
103  tr->checkPointCounter = 0;
104     
105  computeNextReplicate(tr, &adef->boot, (int*)NULL, (int*)NULL, FALSE, FALSE);
106 
107  initModel(tr, rdta, cdta, adef);                                   
108         
109  getStartingTree(tr, adef);
110
111  computeBIGRAPID(tr, adef, TRUE);
112
113  if(adef->bootstrapBranchLengths)
114    {
115      switch(tr->rateHetModel)
116        {
117        case GAMMA:       
118        case GAMMA_I:     
119          modOpt(tr, adef, TRUE, adef->likelihoodEpsilon);                                 
120          break;
121        case CAT:                                 
122          tr->likelihood = unlikely;           
123          catToGamma(tr, adef);   
124          initModel(tr, rdta, cdta, adef);
125          if(i == 0)
126            modOpt(tr, adef, TRUE, adef->likelihoodEpsilon);     
127          else
128            modOpt(tr, adef, TRUE, adef->likelihoodEpsilon);
129          gammaToCat(tr);                                               
130          break;
131        default:
132          assert(0);
133        }
134    } 
135
136
137   printBootstrapResult(tr, adef, TRUE);   
138}
139
140
141
142
143
144/***************************** EXPERIMENTAL FUNCTIONS ********************************************************/
145
146
147
148
149static int compareTopolRell(const void *p1, const void *p2)
150{
151  topolRELL **rc1 = (topolRELL **)p1;
152  topolRELL **rc2 = (topolRELL **)p2;
153 
154  double i = (*rc1)->likelihood;
155  double j = (*rc2)->likelihood;
156 
157  if (i > j)
158    return (-1);
159  if (i < j)
160    return (1);
161  return (0);
162}
163
164
165void fixModelIndices(tree *tr, int endsite, boolean fixRates)
166{
167  int model, i;
168
169  assert(tr->NumberOfModels > 0);   
170
171  tr->partitionData[0].lower = 0;
172     
173  model = tr->model[0];
174  i = 1;
175
176  while(i < endsite)
177    {
178      if(tr->model[i] != model)
179        {             
180          tr->partitionData[model].upper = i;
181          tr->partitionData[model + 1].lower = i;
182          model = tr->model[i];
183        }
184      i++;
185    }       
186 
187  tr->partitionData[tr->NumberOfModels - 1].upper = endsite;
188 
189  for(model = 0; model < tr->NumberOfModels; model++)   
190    tr->partitionData[model].width = tr->partitionData[model].upper -  tr->partitionData[model].lower;
191 
192 
193#ifndef _USE_PTHREADS
194  for(model = 0; model < tr->NumberOfModels; model++)
195    {
196      int 
197        lower =  tr->partitionData[model].lower;
198     
199      /* SOS what about sumBuffer? */
200      /* tr->partitionData[model].sumBuffer    = &tr->sumBuffer[offset]; */
201      tr->partitionData[model].perSiteLL    = &tr->perSiteLL[lower];     
202      tr->partitionData[model].wgt          = &tr->cdta->aliaswgt[lower];
203     
204
205      tr->partitionData[model].invariant    = &tr->invariant[lower];
206      tr->partitionData[model].rateCategory = &tr->cdta->rateCategory[lower];
207     
208
209      for(int j = 1; j <= tr->mxtips; j++)
210        tr->partitionData[model].yVector[j] = &(tr->yVector[j][tr->partitionData[model].lower]);
211
212     
213      {
214        int 
215          width =  tr->partitionData[model].width,
216          undetermined = getUndetermined(tr->partitionData[model].dataType),
217          j;                                         
218       
219        tr->partitionData[model].gapVectorLength = ((int)width / 32) + 1;
220
221        memset(tr->partitionData[model].gapVector, 0, tr->partitionData[model].initialGapVectorSize);
222
223        for(j = 1; j <= tr->mxtips; j++)
224          for(i = 0; i < width; i++)
225            if(tr->partitionData[model].yVector[j][i] == undetermined)
226              tr->partitionData[model].gapVector[tr->partitionData[model].gapVectorLength * j + i / 32] |= mask32[i % 32];
227      }
228
229    }
230#else
231  masterBarrier(THREAD_FIX_MODEL_INDICES, tr);
232#endif
233
234 
235  if(fixRates) 
236    updatePerSiteRates(tr, TRUE);
237}
238
239void reductionCleanup(tree *tr, int *originalRateCategories, int *originalInvariant)
240{
241  tr->cdta->endsite = tr->originalCrunchedLength;
242
243  memcpy(tr->cdta->aliaswgt, tr->originalWeights, sizeof(int) * tr->cdta->endsite);
244  memcpy(tr->model, tr->originalModel, sizeof(int) * tr->cdta->endsite);
245  memcpy(tr->dataVector, tr->originalDataVector,  sizeof(int) * tr->cdta->endsite);
246
247  memcpy(tr->cdta->rateCategory, originalRateCategories, sizeof(int) * tr->cdta->endsite);
248  memcpy(tr->invariant,          originalInvariant,      sizeof(int) * tr->cdta->endsite);                     
249 
250 
251
252  memcpy(tr->rdta->y0, tr->rdta->yBUF, ((size_t)tr->rdta->numsp) * ((size_t)tr->cdta->endsite) * sizeof(char)); 
253     
254  tr->cdta->endsite = tr->originalCrunchedLength;
255  fixModelIndices(tr, tr->originalCrunchedLength, TRUE);     
256}
257
258
259
260
261/* old problematic code by Andre
262
263void computeNextReplicate(tree *tr, long *randomSeed, int *originalRateCategories, int *originalInvariant, boolean isRapid, boolean fixRates)
264{
265  int
266    j,
267    count = 0,
268    model,
269    *weightBuffer,
270    endsite,
271    *weights,
272    i,
273    l; 
274
275  for(j = 0; j < tr->originalCrunchedLength; j++)
276    tr->cdta->aliaswgt[j] = 0;
277
278  for(model = 0; model < tr->NumberOfModels; ++model)
279    {
280      int
281        maxWeight = 0,
282        ctr = 0,
283        //      totalWeight = 0,
284        realNumSites = tr->origNumSitePerModel[model], 
285        *wgtVirtualAln = (int*) rax_calloc(realNumSites, sizeof(int));
286
287      for(j = 0; j < tr->originalCrunchedLength; ++j)
288        {
289          if(tr->originalModel[j] == model)
290            {
291              wgtVirtualAln[ctr++] = tr->originalWeights[j];
292              //totalWeight += tr->originalWeights[j] ;
293              if(maxWeight < tr->originalWeights[j])
294                maxWeight = tr->originalWeights[j];
295            }
296        }
297
298      weightBuffer = (int *)rax_calloc(realNumSites, sizeof(int));
299     
300      j = 0;
301     
302      while( j < realNumSites )
303        {
304          int
305            pos = (int) (realNumSites * randum(randomSeed));
306         
307          //if((int) (totalWeight * randum(randomSeed)) < wgtVirtualAln[pos] )
308          if((int) (maxWeight * randum(randomSeed)) < wgtVirtualAln[pos] )
309            {
310              weightBuffer[pos]++;
311              j++;
312            }
313        }
314
315      ctr = 0;
316      for(j = 0; j < tr->originalCrunchedLength; ++j)
317        {
318          if(model == tr->originalModel[j])
319            {
320              tr->cdta->aliaswgt[j] = weightBuffer[ctr];
321              ctr++;
322            }
323        }
324
325       rax_free(weightBuffer);
326       rax_free(wgtVirtualAln);
327    }
328
329   endsite = 0;
330
331   for (j = 0; j < tr->originalCrunchedLength; j++)     
332     if(tr->cdta->aliaswgt[j] > 0)
333       endsite++;
334
335   weights = tr->cdta->aliaswgt;
336
337   for(i = 0; i < tr->rdta->numsp; i++)
338     {     
339       unsigned char
340         *yPos    = &(tr->rdta->y0[((size_t)tr->originalCrunchedLength) * ((size_t)i)]),
341         *origSeq = &(tr->rdta->yBUF[((size_t)tr->originalCrunchedLength) * ((size_t)i)]);
342       int
343         l,
344         j;
345
346       for(j = 0, l = 0; j < tr->originalCrunchedLength; j++)     
347         if(tr->cdta->aliaswgt[j] > 0)             
348           yPos[l++] = origSeq[j];                       
349    }
350
351  for(j = 0, l = 0; j < tr->originalCrunchedLength; j++)
352    {     
353      if(weights[j])   
354        {
355          tr->cdta->aliaswgt[l]     = tr->cdta->aliaswgt[j];
356          tr->dataVector[l]         = tr->originalDataVector[j];
357          tr->model[l]              = tr->originalModel[j];
358
359          if(isRapid)
360            {         
361              tr->cdta->rateCategory[l] = originalRateCategories[j];
362              tr->invariant[l]          = originalInvariant[j];
363            }
364          l++;
365        }
366    }
367
368  tr->cdta->endsite = endsite;
369  fixModelIndices(tr, endsite, fixRates);
370
371  count = 0;
372  for(j = 0; j < tr->cdta->endsite; j++)
373    count += tr->cdta->aliaswgt[j]; 
374
375  if(count != tr->rdta->sites)
376    printf("count=%d\ttr->rdta->sites=%d\n",count, tr->rdta->sites );
377  assert(count == tr->rdta->sites);
378}
379*/
380
381 
382
383void computeNextReplicate(tree *tr, long *randomSeed, int *originalRateCategories, int *originalInvariant, boolean isRapid, boolean fixRates)
384{ 
385  int 
386    j, 
387    model, 
388    w,
389    *weightBuffer, 
390    endsite,
391    *weights, 
392    i, 
393    l; 
394
395  for(j = 0; j < tr->originalCrunchedLength; j++)
396    tr->cdta->aliaswgt[j] = 0;
397
398         
399  for(model = 0; model < tr->NumberOfModels; model++)
400    {
401      int
402        nonzero = 0,
403        pos = 0;                 
404     
405      for (j = 0; j < tr->originalCrunchedLength; j++) 
406        {
407          if(tr->originalModel[j] == model)
408            nonzero += tr->originalWeights[j];
409        }                                         
410     
411      weightBuffer = (int *)rax_calloc(nonzero, sizeof(int));   
412     
413      for (j = 0; j < nonzero; j++)
414        weightBuffer[(int) (nonzero*randum(randomSeed))]++;                                   
415     
416      for(j = 0; j < tr->originalCrunchedLength; j++) 
417        {
418          if(model == tr->originalModel[j])
419            {
420              for(w = 0; w < tr->originalWeights[j]; w++)                       
421                {
422                  tr->cdta->aliaswgt[j] += weightBuffer[pos];
423                  pos++;                     
424                }                                 
425            }
426        } 
427
428      rax_free(weightBuffer);           
429    }       
430
431  endsite = 0;
432 
433  for (j = 0; j < tr->originalCrunchedLength; j++) 
434    {         
435      if(tr->cdta->aliaswgt[j] > 0)
436        endsite++;     
437    }         
438 
439  weights = tr->cdta->aliaswgt;
440
441  for(i = 0; i < tr->rdta->numsp; i++)
442    {     
443      unsigned char 
444        *yPos    = &(tr->rdta->y0[((size_t)tr->originalCrunchedLength) * ((size_t)i)]),
445        *origSeq = &(tr->rdta->yBUF[((size_t)tr->originalCrunchedLength) * ((size_t)i)]);
446     
447      for(j = 0, l = 0; j < tr->originalCrunchedLength; j++)     
448        if(tr->cdta->aliaswgt[j] > 0)               
449          yPos[l++] = origSeq[j];                         
450    }
451
452  for(j = 0, l = 0; j < tr->originalCrunchedLength; j++)
453    {     
454      if(weights[j])   
455        {
456          tr->cdta->aliaswgt[l]     = tr->cdta->aliaswgt[j];
457          tr->dataVector[l]         = tr->originalDataVector[j];
458          tr->model[l]              = tr->originalModel[j];
459
460          if(isRapid)
461            {       
462              tr->cdta->rateCategory[l] = originalRateCategories[j];
463              tr->invariant[l]          = originalInvariant[j];
464            }
465         
466          l++;
467        }
468    }
469
470  tr->cdta->endsite = endsite;
471  fixModelIndices(tr, endsite, fixRates);
472
473  {
474    int
475      count = 0;
476   
477    for(j = 0; j < tr->cdta->endsite; j++)
478      count += tr->cdta->aliaswgt[j]; 
479
480    if(count != tr->rdta->sites)
481      printf("count=%d\ttr->rdta->sites=%d\n",count, tr->rdta->sites );
482    assert(count == tr->rdta->sites);
483  }
484}
485
486
487
488static pInfo *allocParams(tree *tr)
489{
490  int i;
491  pInfo *partBuffer = (pInfo*)rax_malloc(sizeof(pInfo) * tr->NumberOfModels);
492
493  for(i = 0; i < tr->NumberOfModels; i++)
494    {
495      const partitionLengths *pl = getPartitionLengths(&(tr->partitionData[i]));
496
497      partBuffer[i].EIGN = (double*)rax_malloc(pl->eignLength * sizeof(double));
498      partBuffer[i].EV   = (double*)rax_malloc(pl->evLength * sizeof(double));
499      partBuffer[i].EI   = (double*)rax_malloc(pl->eiLength * sizeof(double));   
500      partBuffer[i].substRates = (double *)rax_malloc(pl->substRatesLength * sizeof(double));     
501      partBuffer[i].frequencies =  (double*)rax_malloc(pl->frequenciesLength * sizeof(double));   
502      partBuffer[i].tipVector   = (double *)rax_malloc(pl->tipVectorLength * sizeof(double));
503     
504     
505    }
506
507  return partBuffer;     
508}
509
510static void rax_freeParams(int numberOfModels, pInfo *partBuffer)
511{
512  int i;
513
514  for(i = 0; i < numberOfModels; i++)
515    {
516      rax_free(partBuffer[i].EIGN); 
517      rax_free(partBuffer[i].EV);   
518      rax_free(partBuffer[i].EI);   
519      rax_free(partBuffer[i].substRates);
520      rax_free(partBuffer[i].frequencies); 
521      rax_free(partBuffer[i].tipVector); 
522    }
523     
524}
525
526static void copyParams(int numberOfModels, pInfo *dst, pInfo *src, tree *tr)
527{
528  int i;
529
530  assert(src != dst);
531
532  for(i = 0; i < numberOfModels; i++)
533    {
534      const partitionLengths *pl = getPartitionLengths(&src[i]);
535     
536      dst[i].dataType = src[i].dataType;
537
538       memcpy(dst[i].EIGN,        src[i].EIGN,        pl->eignLength * sizeof(double));
539       memcpy(dst[i].EV,          src[i].EV,          pl->evLength * sizeof(double));
540       memcpy(dst[i].EI,          src[i].EI,          pl->eiLength * sizeof(double));     
541       memcpy(dst[i].substRates,  src[i].substRates,  pl->substRatesLength * sizeof(double));     
542       memcpy(dst[i].frequencies, src[i].frequencies, pl->frequenciesLength * sizeof(double));   
543       memcpy(dst[i].tipVector,   src[i].tipVector,   pl->tipVectorLength * sizeof(double));
544       
545
546    }
547
548#ifdef _USE_PTHREADS
549  masterBarrier(THREAD_COPY_PARAMS, tr);
550#else
551  (void)tr; // silence warning
552#endif
553}
554
555
556#ifdef _WAYNE_MPI
557
558static void copyFiles(FILE *source, FILE *destination)
559{
560  size_t 
561    c;
562 
563  char 
564    buf[1024];
565 
566  assert(processID == 0);
567
568  while((c = fread(buf, sizeof(char), 1024, source)) > 0)
569    fwrite(buf, sizeof(char), c, destination);         
570}
571
572static void concatenateBSFiles(int processes)
573{
574  if(processID == 0)
575    {
576      int i;
577     
578      FILE 
579        *destination = myfopen(bootstrapFileName, "w"),
580        *source = (FILE*)NULL;
581     
582      char 
583        sourceName[1024];         
584     
585      strcpy(sourceName, bootstrapFileName);
586      strcat(sourceName, ".PID.");
587     
588      for(i = 0; i < processes; i++)
589        {
590          char 
591            buf[64],
592            temporary[1024];
593         
594          sprintf(buf, "%d", i);
595          strcpy(temporary, sourceName);
596          strcat(temporary, buf);
597         
598          source = myfopen(temporary, "r");
599         
600          copyFiles(source, destination);
601         
602          fclose(source);
603        }
604     
605      fclose(destination);
606    }
607}
608
609static void removeBSFiles(int processes)
610{
611  if(processID == 0)
612    {
613      int 
614        i;
615     
616      char 
617        sourceName[1024];           
618     
619      strcpy(sourceName, bootstrapFileName);
620      strcat(sourceName, ".PID.");
621     
622      for(i = 0; i < processes; i++)
623        {
624          char 
625            buf[64],
626            temporary[1024];
627         
628          sprintf(buf, "%d", i);
629          strcpy(temporary, sourceName);
630          strcat(temporary, buf);
631         
632          remove(temporary);
633        }
634    }
635}
636
637#endif
638
639
640void doAllInOne(tree *tr, analdef *adef)
641{
642  int i, n, bestIndex, bootstrapsPerformed;
643
644#ifdef _WAYNE_MPI
645  int 
646    bootStopTests = 1,
647    j,
648    bootStrapsPerProcess = 0;
649#endif
650
651  double loopTime; 
652  int      *originalRateCategories;
653  int      *originalInvariant;
654#ifdef _WAYNE_MPI
655  int      slowSearches, fastEvery;
656#else
657  int      slowSearches, fastEvery = 5;
658#endif
659  int treeVectorLength = -1;
660  topolRELL_LIST *rl; 
661  double bestLH, mlTime, overallTime; 
662  long radiusSeed = adef->rapidBoot;
663  char bestTreeFileName[1024]; 
664  hashtable *h = (hashtable*)NULL;
665  unsigned int **bitVectors = (unsigned int**)NULL;
666  boolean bootStopIt = FALSE;
667  double pearsonAverage = 0.0;
668  pInfo *catParams         = allocParams(tr);
669  pInfo *gammaParams = allocParams(tr);
670  unsigned int vLength;
671
672  n = adef->multipleRuns; 
673
674#ifdef _WAYNE_MPI
675  if(n % processes != 0)
676    n = processes * ((n / processes) + 1);
677#endif
678
679  if(adef->bootStopping)
680    {   
681      h = initHashTable(tr->mxtips * 100);
682
683      treeVectorLength = adef->multipleRuns;
684     
685      bitVectors = initBitVector(tr, &vLength);         
686    }
687
688  rl = (topolRELL_LIST *)rax_malloc(sizeof(topolRELL_LIST));
689  initTL(rl, tr, n);
690     
691  originalRateCategories = (int*)rax_malloc(tr->cdta->endsite * sizeof(int));     
692  originalInvariant      = (int*)rax_malloc(tr->cdta->endsite * sizeof(int));
693
694             
695
696  initModel(tr, tr->rdta, tr->cdta, adef);
697
698  if(adef->grouping)
699    printBothOpen("\n\nThe topologies of all Bootstrap and ML trees will adhere to the constraint tree specified in %s\n", tree_file);
700  if(adef->constraint)
701    printBothOpen("\n\nThe topologies of all Bootstrap and ML trees will adhere to the bifurcating backbone constraint tree specified in %s\n", tree_file);
702 
703
704#ifdef _WAYNE_MPI
705  long parsimonySeed0 = adef->parsimonySeed;
706  long replicateSeed0 = adef->rapidBoot;
707  n = n / processes;
708#endif
709 
710  for(i = 0; i < n && !bootStopIt; i++)
711    { 
712#ifdef _WAYNE_MPI
713      j = i + n * processID;
714      tr->treeID = j;
715#else             
716      tr->treeID = i;
717#endif
718
719      tr->checkPointCounter = 0;
720       
721      loopTime = gettime(); 
722
723#ifdef _WAYNE_MPI
724      if(i == 0)
725        {
726          if(parsimonySeed0 != 0)
727            adef->parsimonySeed = parsimonySeed0 + 10000 * processID;
728          adef->rapidBoot = replicateSeed0 + 10000 * processID;
729          radiusSeed = adef->rapidBoot;
730        }
731#endif         
732     
733      if(i % 10 == 0)
734        {
735          if(i > 0)                 
736            reductionCleanup(tr, originalRateCategories, originalInvariant);             
737
738          if(adef->grouping || adef->constraint)
739            {
740              FILE *f = myfopen(tree_file, "rb");       
741
742              assert(adef->restart);
743              partCount = 0;
744              if (! treeReadLenMULT(f, tr, adef))
745                exit(-1);
746             
747              fclose(f);
748            }
749          else
750            makeParsimonyTree(tr, adef);
751         
752          tr->likelihood = unlikely;
753          if(i == 0)
754            {
755              double t;
756                 
757              onlyInitrav(tr, tr->start);
758              treeEvaluate(tr, 1);             
759                     
760              t = gettime();                 
761
762              modOpt(tr, adef, FALSE, 5.0);         
763#ifdef _WAYNE_MPI
764              printBothOpen("\nTime for BS model parameter optimization on Process %d: %f seconds\n", processID, gettime() - t);             
765#else
766              printBothOpen("\nTime for BS model parameter optimization %f\n", gettime() - t);
767#endif
768             
769              memcpy(originalRateCategories, tr->cdta->rateCategory, sizeof(int) * tr->cdta->endsite);
770              memcpy(originalInvariant,      tr->invariant,          sizeof(int) * tr->cdta->endsite);
771
772              if(adef->bootstrapBranchLengths)
773                {
774                  if(tr->rateHetModel == CAT)
775                    {
776                      copyParams(tr->NumberOfModels, catParams, tr->partitionData, tr);               
777                      assert(tr->cdta->endsite == tr->originalCrunchedLength);           
778                      catToGamma(tr, adef);                   
779                      modOpt(tr, adef, TRUE, adef->likelihoodEpsilon);
780                      copyParams(tr->NumberOfModels, gammaParams, tr->partitionData, tr);                     
781                      gammaToCat(tr);
782                      copyParams(tr->NumberOfModels, tr->partitionData, catParams, tr);               
783                    }
784                  else
785                    {             
786                      assert(tr->cdta->endsite == tr->originalCrunchedLength);                                                                               
787                    }
788                }
789            }             
790        }
791
792      computeNextReplicate(tr, &adef->rapidBoot, originalRateCategories, originalInvariant, TRUE, TRUE); 
793      resetBranches(tr);
794
795     
796
797      evaluateGenericInitrav(tr, tr->start);
798   
799      treeEvaluate(tr, 1);                   
800     
801      computeBOOTRAPID(tr, adef, &radiusSeed); 
802#ifdef _WAYNE_MPI
803      saveTL(rl, tr, j);
804#else                             
805      saveTL(rl, tr, i);
806#endif
807
808      if(adef->bootstrapBranchLengths)
809        {
810          double 
811            lh = tr->likelihood;
812                 
813          if(tr->rateHetModel == CAT)
814            {
815              copyParams(tr->NumberOfModels, tr->partitionData, gammaParams, tr);             
816             
817              catToGamma(tr, adef);
818             
819             
820              resetBranches(tr);
821              onlyInitrav(tr, tr->start);
822              treeEvaluate(tr, 2.0);
823         
824             
825              gammaToCat(tr);
826             
827       
828              copyParams(tr->NumberOfModels, tr->partitionData, catParams, tr);       
829              tr->likelihood = lh;
830            }
831          else
832            {       
833              treeEvaluate(tr, 2.0);
834              tr->likelihood = lh;
835            }
836        }
837     
838      printBootstrapResult(tr, adef, TRUE); 
839
840      loopTime = gettime() - loopTime; 
841      writeInfoFile(adef, tr, loopTime); 
842     
843      if(adef->bootStopping)
844#ifdef _WAYNE_MPI
845        {
846          int 
847            nn = (i + 1) * processes;
848
849          if((nn > START_BSTOP_TEST) && 
850             (i * processes < FC_SPACING * bootStopTests) &&
851             ((i + 1) * processes >= FC_SPACING * bootStopTests)
852             )       
853            {
854              MPI_Barrier(MPI_COMM_WORLD);
855                           
856              concatenateBSFiles(processes);               
857             
858              MPI_Barrier(MPI_COMM_WORLD);           
859             
860              bootStopIt = computeBootStopMPI(tr, bootstrapFileName, adef, &pearsonAverage);
861              bootStopTests++;
862            }
863        }       
864#else   
865        bootStopIt = bootStop(tr, h, i, &pearsonAverage, bitVectors, treeVectorLength, vLength);
866#endif
867
868
869    } 
870 
871#ifdef _WAYNE_MPI     
872  MPI_Barrier(MPI_COMM_WORLD);
873 
874  bootstrapsPerformed = i * processes; 
875  bootStrapsPerProcess = i;   
876     
877  concatenateBSFiles(processes);
878  removeBSFiles(processes); 
879 
880  MPI_Barrier(MPI_COMM_WORLD); 
881#else
882  bootstrapsPerformed = i;
883#endif
884
885  rax_freeParams(tr->NumberOfModels, catParams);
886  rax_free(catParams);
887
888  rax_freeParams(tr->NumberOfModels, gammaParams);
889  rax_free(gammaParams);
890
891  if(adef->bootStopping)
892    {
893      freeBitVectors(bitVectors, 2 * tr->mxtips);
894      rax_free(bitVectors);
895      freeHashTable(h);
896      rax_free(h);     
897    }
898
899 
900  {     
901    double t;
902
903    printBothOpenMPI("\n\n");
904   
905    if(adef->bootStopping)
906      {
907        if(bootStopIt)
908          {
909            switch(tr->bootStopCriterion)
910              {
911              case FREQUENCY_STOP:
912                printBothOpenMPI("Stopped Rapid BS search after %d replicates with FC Bootstopping criterion\n", bootstrapsPerformed);
913                printBothOpenMPI("Pearson Average of %d random splits: %f\n",BOOTSTOP_PERMUTATIONS , pearsonAverage);         
914                break;
915              case MR_STOP:
916                printBothOpenMPI("Stopped Rapid BS search after %d replicates with MR-based Bootstopping criterion\n", bootstrapsPerformed);
917                printBothOpenMPI("WRF Average of %d random splits: %f\n", BOOTSTOP_PERMUTATIONS, pearsonAverage);           
918                break;
919              case MRE_STOP:
920                printBothOpenMPI("Stopped Rapid BS search after %d replicates with MRE-based Bootstopping criterion\n", bootstrapsPerformed);
921                printBothOpenMPI("WRF Average of %d random splits: %f\n", BOOTSTOP_PERMUTATIONS, pearsonAverage);           
922                break;
923              case MRE_IGN_STOP:
924                printBothOpenMPI("Stopped Rapid BS search after %d replicates with MRE_IGN-based Bootstopping criterion\n", bootstrapsPerformed);
925                printBothOpenMPI("WRF Average of %d random splits: %f\n", BOOTSTOP_PERMUTATIONS, pearsonAverage);           
926                break;
927              default:
928                assert(0);
929              }
930          }
931        else
932          { 
933            switch(tr->bootStopCriterion)           
934              {
935              case FREQUENCY_STOP:
936                printBothOpenMPI("Rapid BS search did not converge after %d replicates with FC Bootstopping criterion\n", bootstrapsPerformed);
937                printBothOpenMPI("Pearson Average of %d random splits: %f\n",BOOTSTOP_PERMUTATIONS , pearsonAverage);
938                break;
939              case MR_STOP:
940                printBothOpenMPI("Rapid BS search did not converge after %d replicates with MR-based Bootstopping criterion\n", bootstrapsPerformed);
941                printBothOpenMPI("WRF Average of %d random splits: %f\n", BOOTSTOP_PERMUTATIONS, pearsonAverage);
942                break;
943              case MRE_STOP:
944                printBothOpenMPI("Rapid BS search did not converge after %d replicates with MRE-based Bootstopping criterion\n", bootstrapsPerformed);
945                printBothOpenMPI("WRF Average of %d random splits: %f\n", BOOTSTOP_PERMUTATIONS, pearsonAverage);
946                break;
947              case MRE_IGN_STOP:
948                printBothOpenMPI("Rapid BS search did not converge after %d replicates with MR_IGN-based Bootstopping criterion\n", bootstrapsPerformed);
949                printBothOpenMPI("WRF Average of %d random splits: %f\n", BOOTSTOP_PERMUTATIONS, pearsonAverage);
950                break;
951              default:
952                assert(0);
953              }
954          }
955      }
956   
957
958    t = gettime() - masterTime;
959
960    printBothOpenMPI("Overall Time for %d Rapid Bootstraps %f seconds\n", bootstrapsPerformed, t);     
961    printBothOpenMPI("Average Time per Rapid Bootstrap %f seconds\n", (double)(t/((double)bootstrapsPerformed))); 
962       
963    if(!adef->allInOne)     
964      {
965        printBothOpenMPI("All %d bootstrapped trees written to: %s\n", bootstrapsPerformed, bootstrapFileName);
966
967#ifdef _WAYNE_MPI       
968        MPI_Finalize();
969#endif
970        exit(0);
971      }
972  }
973 
974 
975  /* ML-search */ 
976
977  mlTime = gettime();
978  double t = mlTime;
979 
980  printBothOpenMPI("\nStarting ML Search ...\n\n"); 
981
982  /***CLEAN UP reduction stuff */ 
983
984  reductionCleanup(tr, originalRateCategories, originalInvariant); 
985
986  /****/           
987 
988#ifdef _WAYNE_MPI
989  restoreTL(rl, tr, n * processID); 
990#else
991  restoreTL(rl, tr, 0);
992#endif
993
994  resetBranches(tr);
995
996 
997
998  evaluateGenericInitrav(tr, tr->start);   
999
1000 
1001
1002  modOpt(tr, adef, TRUE, adef->likelihoodEpsilon); 
1003
1004#ifdef _WAYNE_MPI
1005 
1006  if(bootstrapsPerformed <= 100)
1007    fastEvery = 5;
1008  else
1009    fastEvery = bootstrapsPerformed / 20;
1010
1011  for(i = 0; i < bootstrapsPerformed; i++)
1012    rl->t[i]->likelihood = unlikely;
1013
1014  for(i = 0; i < bootStrapsPerProcess; i++)
1015    {           
1016      j = i + n * processID;
1017   
1018      if(i % fastEvery == 0)
1019        {       
1020          restoreTL(rl, tr, j);                                 
1021         
1022          resetBranches(tr);     
1023
1024          evaluateGenericInitrav(tr, tr->start);
1025                 
1026          treeEvaluate(tr, 1);           
1027                 
1028          optimizeRAPID(tr, adef);                                               
1029         
1030          saveTL(rl, tr, j); 
1031        }   
1032    }     
1033#else
1034  for(i = 0; i < bootstrapsPerformed; i++)
1035    {           
1036      rl->t[i]->likelihood = unlikely;
1037   
1038      if(i % fastEvery == 0)
1039        {
1040         
1041         
1042          restoreTL(rl, tr, i);                                 
1043         
1044          resetBranches(tr);     
1045
1046          evaluateGenericInitrav(tr, tr->start);
1047                 
1048          treeEvaluate(tr, 1);           
1049                 
1050          optimizeRAPID(tr, adef);                                               
1051         
1052         
1053
1054          saveTL(rl, tr, i);     
1055        }   
1056    }     
1057#endif
1058 
1059  printBothOpenMPI("Fast ML optimization finished\n\n"); 
1060  t = gettime() - t;
1061 
1062#ifdef _WAYNE_MPI
1063  printBothOpen("Fast ML search on Process %d: Time %f seconds\n\n", processID, t);
1064  j = n * processID;
1065
1066  qsort(&(rl->t[j]), n, sizeof(topolRELL*), compareTopolRell);
1067
1068  restoreTL(rl, tr, j);
1069#else
1070  printBothOpen("Fast ML search Time: %f seconds\n\n", t);
1071  qsort(&(rl->t[0]), bootstrapsPerformed, sizeof(topolRELL*), compareTopolRell);
1072       
1073  restoreTL(rl, tr, 0);
1074#endif
1075  t = gettime();
1076 
1077  resetBranches(tr);
1078
1079  evaluateGenericInitrav(tr, tr->start);
1080
1081  modOpt(tr, adef, TRUE, adef->likelihoodEpsilon);     
1082 
1083  slowSearches = bootstrapsPerformed / 5;
1084  if(bootstrapsPerformed % 5 != 0)
1085    slowSearches++;
1086
1087  slowSearches  = MIN(slowSearches, 10); 
1088
1089#ifdef _WAYNE_MPI
1090   if(processes > 1)
1091    {
1092      if(slowSearches % processes == 0)
1093        slowSearches = slowSearches / processes;
1094      else
1095        slowSearches = (slowSearches / processes) + 1;
1096    }
1097   
1098   for(i = 0; i < slowSearches; i++)
1099    {           
1100      j = i + n * processID;
1101      restoreTL(rl, tr, j);     
1102      rl->t[j]->likelihood = unlikely; 
1103     
1104      evaluateGenericInitrav(tr, tr->start);
1105
1106      treeEvaluate(tr, 1.0);   
1107     
1108      thoroughOptimization(tr, adef, rl, j); 
1109   }   
1110#else
1111  for(i = 0; i < slowSearches; i++)
1112    {           
1113      restoreTL(rl, tr, i);     
1114      rl->t[i]->likelihood = unlikely; 
1115     
1116      evaluateGenericInitrav(tr, tr->start);
1117
1118      treeEvaluate(tr, 1.0);   
1119     
1120      thoroughOptimization(tr, adef, rl, i);     
1121
1122   }
1123#endif
1124 
1125 
1126
1127  /*************************************************************************************************************/ 
1128 
1129  if(tr->rateHetModel == CAT) 
1130    {     
1131      catToGamma(tr, adef);   
1132      modOpt(tr, adef, TRUE, adef->likelihoodEpsilon); 
1133    }
1134
1135  bestIndex = -1;
1136  bestLH = unlikely;
1137   
1138#ifdef _WAYNE_MPI
1139  for(i = 0; i < slowSearches; i++)
1140    { 
1141      j = i + n * processID;
1142      restoreTL(rl, tr, j);
1143      resetBranches(tr);
1144
1145      evaluateGenericInitrav(tr, tr->start);
1146
1147      treeEvaluate(tr, 2);
1148     
1149      printBothOpen("Slow ML Search %d Likelihood: %f\n", j, tr->likelihood);
1150     
1151      if(tr->likelihood > bestLH)
1152        {
1153          bestLH = tr->likelihood;
1154          bestIndex = j;
1155        }
1156    }
1157  /*printf("processID = %d, bestIndex = %d; bestLH = %f\n", processID, bestIndex, bestLH);*/
1158#else
1159  for(i = 0; i < slowSearches; i++)
1160    { 
1161      restoreTL(rl, tr, i);
1162      resetBranches(tr);
1163
1164      evaluateGenericInitrav(tr, tr->start);
1165
1166      treeEvaluate(tr, 2);
1167     
1168      printBothOpen("Slow ML Search %d Likelihood: %f\n", i, tr->likelihood);
1169     
1170      if(tr->likelihood > bestLH)
1171        {
1172          bestLH = tr->likelihood;
1173          bestIndex = i;
1174        }
1175    }
1176#endif
1177 
1178  printBothOpenMPI("Slow ML optimization finished\n\n");
1179
1180  t = gettime() - t;
1181
1182#ifdef _WAYNE_MPI
1183  printBothOpen("Slow ML search on Process %d: Time %f seconds\n", processID, t);
1184#else
1185  printBothOpen("Slow ML search Time: %f seconds\n", t);
1186#endif
1187 
1188  t = gettime();
1189 
1190  restoreTL(rl, tr, bestIndex);
1191  resetBranches(tr);
1192
1193  evaluateGenericInitrav(tr, tr->start);
1194 
1195  treeEvaluate(tr, 2); 
1196         
1197  Thorough = 1;
1198  tr->doCutoff = FALSE; 
1199         
1200  treeOptimizeThorough(tr, 1, 10);
1201  evaluateGenericInitrav(tr, tr->start);
1202 
1203  modOpt(tr, adef, TRUE, adef->likelihoodEpsilon);
1204  t = gettime() - t;
1205
1206#ifdef _WAYNE_MPI
1207  printBothOpen("Thorough ML search on Process %d: Time %f seconds\n", processID, t);
1208#else
1209  printBothOpen("Thorough ML search Time: %f seconds\n", t);
1210#endif
1211
1212#ifdef _WAYNE_MPI
1213  bestLH = tr->likelihood;
1214
1215  printf("\nprocessID = %d, bestLH = %f\n", processID,  bestLH);
1216
1217  if(processes > 1)
1218    {
1219      double *buffer;
1220      int bestProcess;
1221
1222      buffer = (double *)rax_malloc(sizeof(double) * processes);
1223      for(i = 0; i < processes; i++)
1224        buffer[i] = unlikely;
1225      buffer[processID] = bestLH;
1226      for(i = 0; i < processes; i++)
1227        MPI_Bcast(&buffer[i], 1, MPI_DOUBLE, i, MPI_COMM_WORLD);
1228      bestLH = buffer[0];
1229      bestProcess = 0;
1230      for(i = 1; i < processes; i++)
1231        if(buffer[i] > bestLH)
1232          {
1233             bestLH = buffer[i];
1234             bestProcess = i;
1235          }
1236      rax_free(buffer);
1237
1238      if(processID != bestProcess)
1239        {
1240          MPI_Finalize();
1241          exit(0);
1242        }
1243    }
1244#endif
1245
1246  printBothOpen("\nFinal ML Optimization Likelihood: %f\n", tr->likelihood);   
1247  printBothOpen("\nModel Information:\n\n");
1248 
1249  printModelParams(tr, adef);   
1250 
1251  strcpy(bestTreeFileName, workdir); 
1252  strcat(bestTreeFileName, "RAxML_bestTree.");
1253  strcat(bestTreeFileName,         run_id);
1254   
1255  Tree2String(tr->tree_string, tr, tr->start->back, TRUE, TRUE, FALSE, FALSE, TRUE, adef, SUMMARIZE_LH, FALSE, FALSE, FALSE, FALSE);
1256  FILE *f;
1257  f = myfopen(bestTreeFileName, "wb");
1258  fprintf(f, "%s", tr->tree_string);
1259  fclose(f);
1260
1261  if(adef->perGeneBranchLengths)
1262    printTreePerGene(tr, adef, bestTreeFileName, "w");
1263
1264 
1265  overallTime = gettime() - masterTime;
1266  mlTime    = gettime() - mlTime;
1267
1268  printBothOpen("\nML search took %f secs or %f hours\n", mlTime, mlTime / 3600.0); 
1269  printBothOpen("\nCombined Bootstrap and ML search took %f secs or %f hours\n", overallTime, overallTime / 3600.0);   
1270  printBothOpen("\nDrawing Bootstrap Support Values on best-scoring ML tree ...\n\n");
1271     
1272 
1273  freeTL(rl);   
1274  rax_free(rl);       
1275 
1276  calcBipartitions(tr, adef, bestTreeFileName, bootstrapFileName);   
1277 
1278
1279  overallTime = gettime() - masterTime;
1280
1281  printBothOpen("Program execution info written to %s\n", infoFileName);
1282  printBothOpen("All %d bootstrapped trees written to: %s\n\n", bootstrapsPerformed, bootstrapFileName);
1283  printBothOpen("Best-scoring ML tree written to: %s\n\n", bestTreeFileName);
1284  if(adef->perGeneBranchLengths && tr->NumberOfModels > 1)   
1285    printBothOpen("Per-Partition branch lengths of best-scoring ML tree written to %s.PARTITION.0 to  %s.PARTITION.%d\n\n", bestTreeFileName,  bestTreeFileName, 
1286                  tr->NumberOfModels - 1);   
1287  printBothOpen("Best-scoring ML tree with support values written to: %s\n\n", bipartitionsFileName);
1288  printBothOpen("Best-scoring ML tree with support values as branch labels written to: %s\n\n", bipartitionsFileNameBranchLabels);
1289  printBothOpen("Overall execution time for full ML analysis: %f secs or %f hours or %f days\n\n", overallTime, overallTime/3600.0, overallTime/86400.0);
1290
1291#ifdef _WAYNE_MPI
1292  MPI_Finalize();
1293#endif     
1294
1295  exit(0); 
1296}
1297
1298
1299/*******************************************EXPERIMENTAL FUNCTIONS END *****************************************************/
1300
1301
1302
1303
1304
1305void doBootstrap(tree *tr, analdef *adef, rawdata *rdta, cruncheddata *cdta)
1306{
1307  int 
1308    bootstrapsPerformed,
1309    i, 
1310    n, 
1311    treeVectorLength = -1;
1312  unsigned int
1313    vLength = 0;
1314
1315#ifdef _WAYNE_MPI
1316  int 
1317    j,
1318    bootStopTests = 1;
1319#endif
1320
1321  double loopTime, pearsonAverage;
1322  hashtable *h = (hashtable*)NULL;
1323  unsigned int **bitVectors = (unsigned int **)NULL;
1324  boolean bootStopIt = FALSE; 
1325 
1326
1327  n = adef->multipleRuns; 
1328
1329#ifdef _WAYNE_MPI
1330  if(n % processes != 0)
1331    n = processes * ((n / processes) + 1);
1332  adef->multipleRuns = n;
1333#endif
1334
1335  if(adef->bootStopping)
1336    {   
1337      h = initHashTable(tr->mxtips * 100);
1338      bitVectors = initBitVector(tr, &vLength);   
1339
1340      treeVectorLength = adef->multipleRuns;       
1341    }           
1342
1343#ifdef _WAYNE_MPI
1344  long parsimonySeed0 = adef->parsimonySeed;
1345  long replicateSeed0 = adef->rapidBoot;
1346  long bootstrapSeed0  = adef->boot;
1347  n = n / processes;
1348#endif
1349
1350  for(i = 0; i < n && !bootStopIt; i++)
1351    {   
1352      loopTime = gettime();
1353                   
1354#ifdef _WAYNE_MPI
1355      if(i == 0)
1356        {
1357          if(parsimonySeed0 != 0)
1358            adef->parsimonySeed = parsimonySeed0 + 10000 * processID;
1359         
1360          adef->rapidBoot = replicateSeed0 + 10000 * processID;
1361          adef->boot = bootstrapSeed0 + 10000 * processID;
1362        }
1363      j  = i + n*processID;
1364      singleBootstrap(tr, j, adef, rdta, cdta);
1365#else     
1366      singleBootstrap(tr, i, adef, rdta, cdta);             
1367#endif
1368      loopTime = gettime() - loopTime;     
1369      writeInfoFile(adef, tr, loopTime); 
1370
1371      if(adef->bootStopping)
1372#ifdef _WAYNE_MPI
1373        {
1374          int 
1375            nn = (i + 1) * processes;
1376
1377          if((nn > START_BSTOP_TEST) && 
1378             (i * processes < FC_SPACING * bootStopTests) &&
1379             ((i + 1) * processes >= FC_SPACING * bootStopTests)
1380             )       
1381            {
1382              MPI_Barrier(MPI_COMM_WORLD);
1383                           
1384              concatenateBSFiles(processes);               
1385             
1386              MPI_Barrier(MPI_COMM_WORLD);
1387             
1388              bootStopIt = computeBootStopMPI(tr, bootstrapFileName, adef, &pearsonAverage);
1389              bootStopTests++;
1390            }
1391        }
1392#else           
1393      bootStopIt = bootStop(tr, h, i, &pearsonAverage, bitVectors, treeVectorLength, vLength);
1394#endif
1395    }     
1396
1397#ifdef _WAYNE_MPI
1398  MPI_Barrier(MPI_COMM_WORLD);
1399 
1400  bootstrapsPerformed = i * processes;
1401 
1402  if(processID == 0)
1403    {     
1404      if(!adef->bootStopping)
1405        concatenateBSFiles(processes);
1406
1407      removeBSFiles(processes);     
1408    }
1409 
1410  MPI_Barrier(MPI_COMM_WORLD); 
1411#else
1412  bootstrapsPerformed = i;
1413#endif
1414 
1415  adef->multipleRuns = bootstrapsPerformed;
1416 
1417  if(adef->bootStopping)
1418    {
1419      freeBitVectors(bitVectors, 2 * tr->mxtips);
1420      rax_free(bitVectors);
1421      freeHashTable(h);
1422      rax_free(h);
1423     
1424       
1425      if(bootStopIt)
1426        {
1427          switch(tr->bootStopCriterion)
1428            {
1429            case FREQUENCY_STOP:
1430              printBothOpenMPI("Stopped Standard BS search after %d replicates with FC Bootstopping criterion\n", bootstrapsPerformed);
1431              printBothOpenMPI("Pearson Average of %d random splits: %f\n",BOOTSTOP_PERMUTATIONS , pearsonAverage);           
1432              break;
1433            case MR_STOP:
1434              printBothOpenMPI("Stopped Standard BS search after %d replicates with MR-based Bootstopping criterion\n", bootstrapsPerformed);
1435              printBothOpenMPI("WRF Average of %d random splits: %f\n", BOOTSTOP_PERMUTATIONS, pearsonAverage);     
1436              break;
1437            case MRE_STOP:
1438              printBothOpenMPI("Stopped Standard BS search after %d replicates with MRE-based Bootstopping criterion\n", bootstrapsPerformed);
1439              printBothOpenMPI("WRF Average of %d random splits: %f\n", BOOTSTOP_PERMUTATIONS, pearsonAverage);     
1440              break;
1441            case MRE_IGN_STOP:
1442              printBothOpenMPI("Stopped Standard BS search after %d replicates with MRE_IGN-based Bootstopping criterion\n", bootstrapsPerformed);
1443              printBothOpenMPI("WRF Average of %d random splits: %f\n", BOOTSTOP_PERMUTATIONS, pearsonAverage);     
1444              break;
1445            default:
1446              assert(0);
1447            }
1448        }
1449      else
1450        {
1451          switch(tr->bootStopCriterion)
1452            {
1453            case FREQUENCY_STOP:
1454              printBothOpenMPI("Standard BS search did not converge after %d replicates with FC Bootstopping criterion\n", bootstrapsPerformed);
1455              printBothOpenMPI("Pearson Average of %d random splits: %f\n",BOOTSTOP_PERMUTATIONS , pearsonAverage);
1456              break;
1457            case MR_STOP:
1458              printBothOpenMPI("Standard BS search did not converge after %d replicates with MR-based Bootstopping criterion\n", bootstrapsPerformed);
1459              printBothOpenMPI("WRF Average of %d random splits: %f\n", BOOTSTOP_PERMUTATIONS, pearsonAverage);
1460              break;
1461            case MRE_STOP:
1462              printBothOpenMPI("Standard BS search did not converge after %d replicates with MRE-based Bootstopping criterion\n", bootstrapsPerformed);
1463              printBothOpenMPI("WRF Average of %d random splits: %f\n", BOOTSTOP_PERMUTATIONS, pearsonAverage);
1464              break;
1465            case MRE_IGN_STOP:
1466              printBothOpenMPI("Standard BS search did not converge after %d replicates with MR_IGN-based Bootstopping criterion\n", bootstrapsPerformed);
1467              printBothOpenMPI("WRF Average of %d random splits: %f\n", BOOTSTOP_PERMUTATIONS, pearsonAverage);
1468              break;
1469            default:
1470              assert(0);
1471            }
1472        }     
1473    }
1474}
1475
1476void doInference(tree *tr, analdef *adef, rawdata *rdta, cruncheddata *cdta)
1477{
1478  int i, n;
1479
1480#ifdef _WAYNE_MPI
1481  int j;
1482#endif
1483
1484  double loopTime;
1485  topolRELL_LIST *rl = (topolRELL_LIST *)NULL; 
1486  int 
1487    best = -1,
1488    newBest = -1;
1489  double 
1490    bestLH = unlikely; 
1491  FILE *f;
1492  char bestTreeFileName[1024]; 
1493  double overallTime;
1494
1495  n = adef->multipleRuns;
1496     
1497#ifdef _WAYNE_MPI
1498  if(n % processes != 0)
1499    n = processes * ((n / processes) + 1);
1500#endif
1501
1502  if(!tr->catOnly)
1503    {
1504      rl = (topolRELL_LIST *)rax_malloc(sizeof(topolRELL_LIST));
1505      initTL(rl, tr, n);
1506    }
1507
1508#ifdef _WAYNE_MPI
1509  long parsimonySeed0 = adef->parsimonySeed;
1510  n = n / processes;
1511#endif
1512
1513  for(i = 0; i < n; i++)
1514    { 
1515#ifdef _WAYNE_MPI
1516      if(i == 0)
1517        { 
1518          if(parsimonySeed0 != 0) 
1519            adef->parsimonySeed = parsimonySeed0 + 10000 * processID;
1520        }
1521      j = i + n * processID;
1522      tr->treeID = j;
1523#else   
1524      tr->treeID = i;
1525#endif
1526
1527      tr->checkPointCounter = 0;
1528         
1529      loopTime = gettime();
1530                                             
1531      initModel(tr, rdta, cdta, adef); 
1532
1533      if(i == 0)
1534        printBaseFrequencies(tr);
1535     
1536      getStartingTree(tr, adef); 
1537                       
1538      computeBIGRAPID(tr, adef, TRUE); 
1539
1540#ifdef _WAYNE_MPI
1541      if(tr->likelihood > bestLH)
1542        {
1543          best = j;
1544          bestLH = tr->likelihood;
1545        }
1546
1547      if(!tr->catOnly)
1548        saveTL(rl, tr, j);
1549#else
1550      if(tr->likelihood > bestLH)
1551        {
1552          best = i;
1553          bestLH = tr->likelihood;
1554        }
1555
1556      if(!tr->catOnly)
1557        saveTL(rl, tr, i);
1558#endif
1559
1560      loopTime = gettime() - loopTime; 
1561      writeInfoFile(adef, tr, loopTime);
1562     
1563    }     
1564 
1565  assert(best >= 0);
1566
1567#ifdef _WAYNE_MPI
1568  MPI_Barrier(MPI_COMM_WORLD);
1569  n = n * processes;
1570#endif
1571
1572  if(tr->catOnly)
1573    {
1574      printBothOpenMPI("\n\nNOT conducting any final model optimizations on all %d trees under CAT-based model ....\n", n);
1575      printBothOpenMPI("\nREMEMBER that CAT-based likelihood scores are meaningless!\n\n", n);       
1576#ifdef _WAYNE_MPI
1577      if(processID != 0)
1578        {
1579          MPI_Finalize();
1580          exit(0);
1581        }
1582#endif
1583    }
1584  else
1585    {
1586      printBothOpenMPI("\n\nConducting final model optimizations on all %d trees under GAMMA-based models ....\n\n", n);
1587 
1588#ifdef _WAYNE_MPI
1589      n = n / processes;
1590#endif
1591
1592      if(tr->rateHetModel == GAMMA ||  tr->rateHetModel == GAMMA_I)
1593        {
1594          restoreTL(rl, tr, best);
1595          evaluateGenericInitrav(tr, tr->start);
1596          if(!adef->useBinaryModelFile)
1597            modOpt(tr, adef, FALSE, adef->likelihoodEpsilon); 
1598          else
1599            {
1600              readBinaryModel(tr);
1601              evaluateGenericInitrav(tr, tr->start);
1602              treeEvaluate(tr, 2);
1603            }
1604          bestLH = tr->likelihood;
1605          tr->likelihoods[best] = tr->likelihood;
1606          saveTL(rl, tr, best);
1607          tr->treeID = best; 
1608          printResult(tr, adef, TRUE);
1609          newBest = best;     
1610         
1611          for(i = 0; i < n; i++)
1612            {
1613#ifdef _WAYNE_MPI
1614              j = i + n * processID;
1615              if(j != best)
1616                {
1617                  restoreTL(rl, tr, j);
1618                  evaluateGenericInitrav(tr, tr->start);
1619                  treeEvaluate(tr, 1);
1620                  tr->likelihoods[j] = tr->likelihood;
1621                 
1622                  if(tr->likelihood > bestLH)
1623                    {
1624                      newBest = j;
1625                      bestLH = tr->likelihood;           
1626                      saveTL(rl, tr, j);
1627                    }
1628                  tr->treeID = j;
1629                  printResult(tr, adef, TRUE);
1630                }
1631              if(n == 1 && processes == 1)
1632                printBothOpen("Inference[%d] final GAMMA-based Likelihood: %f tree written to file %s\n", i, tr->likelihoods[i], resultFileName);         
1633              else         
1634                printBothOpen("Inference[%d] final GAMMA-based Likelihood: %f tree written to file %s.RUN.%d\n", j, tr->likelihoods[j], resultFileName, j);
1635#else     
1636              if(i != best)
1637                {
1638                  restoreTL(rl, tr, i);
1639                  evaluateGenericInitrav(tr, tr->start);
1640                  treeEvaluate(tr, 1);
1641                  tr->likelihoods[i] = tr->likelihood;
1642                 
1643                  if(tr->likelihood > bestLH)
1644                    {
1645                      newBest = i;
1646                      bestLH = tr->likelihood;           
1647                      saveTL(rl, tr, i);
1648                    }
1649                  tr->treeID = i;
1650                  printResult(tr, adef, TRUE);
1651                }
1652
1653             
1654              if(n == 1)
1655                printBothOpen("Inference[%d] final GAMMA-based Likelihood: %f tree written to file %s\n", i, tr->likelihoods[i], resultFileName);         
1656              else         
1657                printBothOpen("Inference[%d] final GAMMA-based Likelihood: %f tree written to file %s.RUN.%d\n", i, tr->likelihoods[i], resultFileName, i);
1658#endif           
1659            }   
1660        }
1661      else
1662        {     
1663          catToGamma(tr, adef);
1664         
1665#ifdef _WAYNE_MPI
1666          for(i = 0; i < n; i++)
1667            {
1668              j = i + n*processID;
1669              rl->t[j]->likelihood = unlikely;
1670            } 
1671#else
1672          for(i = 0; i < n; i++)
1673            rl->t[i]->likelihood = unlikely;
1674#endif
1675         
1676          initModel(tr, rdta, cdta, adef);
1677         
1678          restoreTL(rl, tr, best);     
1679         
1680          resetBranches(tr);
1681          evaluateGenericInitrav(tr, tr->start);
1682          modOpt(tr, adef, TRUE, adef->likelihoodEpsilon);     
1683          tr->likelihoods[best] = tr->likelihood;
1684          bestLH = tr->likelihood;     
1685          saveTL(rl, tr, best);
1686          tr->treeID = best;
1687          printResult(tr, adef, TRUE);
1688          newBest = best;
1689         
1690          for(i = 0; i < n; i++)
1691            {
1692#ifdef _WAYNE_MPI
1693              j = i + n*processID;
1694              if(j != best)
1695                {
1696                  restoreTL(rl, tr, j);     
1697                  resetBranches(tr);
1698                  evaluateGenericInitrav(tr, tr->start);
1699                  treeEvaluate(tr, 2);
1700                  tr->likelihoods[j] = tr->likelihood;
1701                 
1702                  if(tr->likelihood > bestLH)
1703                    { 
1704                      newBest = j;
1705                      bestLH = tr->likelihood;         
1706                      saveTL(rl, tr, j);         
1707                    }
1708                  tr->treeID = j;
1709                  printResult(tr, adef, TRUE);
1710                } 
1711             
1712              if(n == 1 && processes == 1)         
1713                printBothOpen("Inference[%d] final GAMMA-based Likelihood: %f tree written to file %s\n", i, tr->likelihoods[i], resultFileName);
1714              else
1715                printBothOpen("Inference[%d] final GAMMA-based Likelihood: %f tree written to file %s.RUN.%d\n", j, tr->likelihoods[j], resultFileName, j);
1716#else
1717              if(i != best)
1718                {
1719                  restoreTL(rl, tr, i);     
1720                  resetBranches(tr);
1721                  evaluateGenericInitrav(tr, tr->start);
1722                  treeEvaluate(tr, 2);
1723                  tr->likelihoods[i] = tr->likelihood;
1724                 
1725                  if(tr->likelihood > bestLH)
1726                    { 
1727                      newBest = i;
1728                      bestLH = tr->likelihood;         
1729                      saveTL(rl, tr, i);         
1730                    }
1731                  tr->treeID = i;
1732                  printResult(tr, adef, TRUE);
1733                } 
1734             
1735              if(n == 1)           
1736                printBothOpen("Inference[%d] final GAMMA-based Likelihood: %f tree written to file %s\n", i, tr->likelihoods[i], resultFileName);
1737              else
1738                printBothOpen("Inference[%d] final GAMMA-based Likelihood: %f tree written to file %s.RUN.%d\n", i, tr->likelihoods[i], resultFileName, i);               
1739#endif
1740            }
1741        }     
1742   
1743      assert(newBest >= 0);
1744
1745#ifdef _WAYNE_MPI
1746      if(processes > 1)
1747        {
1748          double *buffer;
1749          int bestProcess;
1750         
1751          buffer = (double *)rax_malloc(sizeof(double) * processes);
1752          for(i = 0; i < processes; i++)
1753            buffer[i] = unlikely;
1754          buffer[processID] = bestLH;
1755          for(i = 0; i < processes; i++)
1756            MPI_Bcast(&buffer[i], 1, MPI_DOUBLE, i, MPI_COMM_WORLD);
1757          bestLH = buffer[0];
1758          bestProcess = 0;
1759          for(i = 1; i < processes; i++)
1760            if(buffer[i] > bestLH)
1761              {
1762                bestLH = buffer[i];
1763                bestProcess = i;
1764              }
1765          rax_free(buffer);
1766         
1767          if(processID != bestProcess)
1768            {
1769              MPI_Finalize();
1770              exit(0);
1771            }
1772        }
1773#endif
1774
1775      restoreTL(rl, tr, newBest);
1776      evaluateGenericInitrav(tr, tr->start);
1777     
1778      printBothOpen("\n\nStarting final GAMMA-based thorough Optimization on tree %d likelihood %f .... \n\n", newBest, tr->likelihoods[newBest]);
1779
1780      Thorough = 1;
1781      tr->doCutoff = FALSE; 
1782      treeOptimizeThorough(tr, 1, 10); 
1783      evaluateGenericInitrav(tr, tr->start);
1784 
1785      printBothOpen("Final GAMMA-based Score of best tree %f\n\n", tr->likelihood); 
1786   
1787
1788      strcpy(bestTreeFileName, workdir); 
1789      strcat(bestTreeFileName, "RAxML_bestTree.");
1790      strcat(bestTreeFileName,         run_id);
1791     
1792     
1793      Tree2String(tr->tree_string, tr, tr->start->back, TRUE, TRUE, FALSE, FALSE, TRUE, adef, SUMMARIZE_LH, FALSE, FALSE, FALSE, FALSE);
1794     
1795      f = myfopen(bestTreeFileName, "wb");
1796      fprintf(f, "%s", tr->tree_string);
1797      fclose(f);
1798
1799      if(adef->perGeneBranchLengths)
1800        printTreePerGene(tr, adef, bestTreeFileName, "w");
1801    }
1802 
1803  overallTime = gettime() - masterTime;
1804
1805  printBothOpen("Program execution info written to %s\n", infoFileName);
1806 
1807  if(!tr->catOnly)
1808    {
1809      printBothOpen("Best-scoring ML tree written to: %s\n\n", bestTreeFileName);
1810
1811      if(adef->perGeneBranchLengths && tr->NumberOfModels > 1)   
1812        printBothOpen("Per-Partition branch lengths of best-scoring ML tree written to %s.PARTITION.0 to  %s.PARTITION.%d\n\n", bestTreeFileName,  bestTreeFileName, 
1813                      tr->NumberOfModels - 1); 
1814    }
1815   
1816  printBothOpen("Overall execution time: %f secs or %f hours or %f days\n\n", overallTime, overallTime/3600.0, overallTime/86400.0);   
1817
1818  if(!tr->catOnly)
1819    {
1820      freeTL(rl);   
1821      rax_free(rl); 
1822    }
1823 
1824#ifdef _WAYNE_MPI
1825  MPI_Finalize();
1826#endif
1827  exit(0);
1828}
1829
Note: See TracBrowser for help on using the repository browser.