source: tags/arb-6.0/GDE/RAxML/multiple.c

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

Updated raxml to current version

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