bpp-phyl  2.2.0
PhylogeneticsApplicationTools.cpp
Go to the documentation of this file.
1 //
2 // File: PhylogeneticsApplicationTools.cpp
3 // Created by: Julien Dutheil
4 // Created on: Fri Oct 21 16:49 2005
5 // from old file ApplicationTools.cpp created on Sun Dec 14 09:36:26 2003
6 //
7 
8 /*
9  Copyright or © or Copr. Bio++ Development Team, (November 16, 2004)
10 
11  This software is a computer program whose purpose is to provide classes
12  for phylogenetic data analysis.
13 
14  This software is governed by the CeCILL license under French law and
15  abiding by the rules of distribution of free software. You can use,
16  modify and/ or redistribute the software under the terms of the CeCILL
17  license as circulated by CEA, CNRS and INRIA at the following URL
18  "http://www.cecill.info".
19 
20  As a counterpart to the access to the source code and rights to copy,
21  modify and redistribute granted by the license, users are provided only
22  with a limited warranty and the software's author, the holder of the
23  economic rights, and the successive licensors have only limited
24  liability.
25 
26  In this respect, the user's attention is drawn to the risks associated
27  with loading, using, modifying and/or developing or reproducing the
28  software by the user in light of its specific status of free software,
29  that may mean that it is complicated to manipulate, and that also
30  therefore means that it is reserved for developers and experienced
31  professionals having in-depth computer knowledge. Users are therefore
32  encouraged to load and test the software's suitability as regards their
33  requirements in conditions enabling the security of their systems and/or
34  data to be ensured and, more generally, to use and operate it in the
35  same conditions as regards security.
36 
37  The fact that you are presently reading this means that you have had
38  knowledge of the CeCILL license and that you accept its terms.
39  */
40 
42 #include "../Model/SubstitutionModel.h"
43 #include "../Model/Protein/Coala.h"
44 #include "../Model/FrequenciesSet/MvaFrequenciesSet.h"
45 #include "../Likelihood/TreeLikelihood.h"
46 #include "../Mapping/LaplaceSubstitutionCount.h"
47 #include "../Mapping/UniformizationSubstitutionCount.h"
48 #include "../Mapping/DecompositionSubstitutionCount.h"
49 #include "../Mapping/NaiveSubstitutionCount.h"
50 #include "../Mapping/OneJumpSubstitutionCount.h"
51 #include "../OptimizationTools.h"
52 #include "../Tree.h"
53 #include "../Io/Newick.h"
54 #include "../Io/NexusIoTree.h"
55 #include "../Io/Nhx.h"
56 #include "../Io/BppOSubstitutionModelFormat.h"
57 #include "../Io/BppOFrequenciesSetFormat.h"
58 #include "../Io/BppORateDistributionFormat.h"
59 
60 // From bpp-core
61 #include <Bpp/Io/BppODiscreteDistributionFormat.h>
62 #include <Bpp/Io/BppOParametrizableFormat.h>
63 #include <Bpp/Io/FileTools.h>
64 #include <Bpp/Text/TextTools.h>
65 #include <Bpp/App/ApplicationTools.h>
66 #include <Bpp/Text/StringTokenizer.h>
67 #include <Bpp/Text/KeyvalTools.h>
68 #include <Bpp/Numeric/AutoParameter.h>
69 #include <Bpp/Numeric/Prob/DirichletDiscreteDistribution.h>
70 #include <Bpp/Numeric/Function/DownhillSimplexMethod.h>
71 #include <Bpp/Numeric/Function/PowellMultiDimensions.h>
72 
73 // From bpp-seq:
74 #include <Bpp/Seq/Alphabet/AlphabetTools.h>
75 #include <Bpp/Seq/Container/SequenceContainerTools.h>
76 #include <Bpp/Seq/App/SequenceApplicationTools.h>
77 
78 using namespace bpp;
79 
80 // From the STL:
81 #include <fstream>
82 #include <memory>
83 #include <set>
84 #include <vector>
85 
86 using namespace std;
87 
88 
89 /*************************************************************/
90 /***************** TREES ************************************/
91 /*************************************************************/
92 
93 
94 /******************************************************************************/
95 
97  map<string, string>& params,
98  const string& prefix,
99  const string& suffix,
100  bool suffixIsOptional,
101  bool verbose,
102  int warn) throw (Exception)
103 {
104  string format = ApplicationTools::getStringParameter(prefix + "tree.format", params, "Newick", suffix, suffixIsOptional, warn);
105  string treeFilePath = ApplicationTools::getAFilePath(prefix + "tree.file", params, true, true, suffix, suffixIsOptional, "none", warn);
106 
107  ITree* treeReader;
108  if (format == "Newick")
109  treeReader = new Newick(true);
110  else if (format == "Nexus")
111  treeReader = new NexusIOTree();
112  else if (format == "NHX")
113  treeReader = new Nhx();
114  else
115  throw Exception("Unknow format for tree reading: " + format);
116  Tree* tree = treeReader->read(treeFilePath);
117  delete treeReader;
118 
119  if (verbose)
120  ApplicationTools::displayResult("Tree file", treeFilePath);
121  return tree;
122 }
123 
124 /******************************************************************************/
125 
127  map<string, string>& params,
128  const string& prefix,
129  const string& suffix,
130  bool suffixIsOptional,
131  bool verbose,
132  int warn) throw (Exception)
133 {
134  string format = ApplicationTools::getStringParameter(prefix + "trees.format", params, "Newick", suffix, suffixIsOptional, warn);
135  string treeFilePath = ApplicationTools::getAFilePath(prefix + "trees.file", params, true, true, suffix, suffixIsOptional, "none", warn);
136 
137  IMultiTree* treeReader;
138  if (format == "Newick")
139  treeReader = new Newick(true);
140  else if (format == "Nexus")
141  treeReader = new NexusIOTree();
142  else if (format == "NHX")
143  treeReader = new Nhx();
144  else
145  throw Exception("Unknow format for tree reading: " + format);
146  vector<Tree*> trees;
147  treeReader->read(treeFilePath, trees);
148  delete treeReader;
149 
150  if (verbose)
151  {
152  ApplicationTools::displayResult("Tree file", treeFilePath);
153  ApplicationTools::displayResult("Number of trees in file", trees.size());
154  }
155  return trees;
156 }
157 
158 
159 /*************************************************************/
160 /******* MODELS **********************************************/
161 /*************************************************************/
162 
163 /******************************************************************************/
164 
166  const Alphabet* alphabet,
167  const GeneticCode* gCode,
168  const SiteContainer* data,
169  std::map<std::string, std::string>& params,
170  const string& suffix,
171  bool suffixIsOptional,
172  bool verbose,
173  int warn) throw (Exception)
174 {
175  BppOSubstitutionModelFormat bIO(BppOSubstitutionModelFormat::ALL, true, true, true, verbose, warn + 1);
176  string modelDescription;
177  const CodonAlphabet* ca = dynamic_cast<const CodonAlphabet*>(alphabet);
178  if (ca) {
179  modelDescription = ApplicationTools::getStringParameter("model", params, "CodonRate(model=JC69)", suffix, suffixIsOptional, warn);
180  if (!gCode)
181  throw Exception("PhylogeneticsApplicationTools::getSubstitutionModel(): a GeneticCode instance is required for instanciating a codon model.");
182  bIO.setGeneticCode(gCode);
183  } else if (AlphabetTools::isWordAlphabet(alphabet))
184  modelDescription = ApplicationTools::getStringParameter("model", params, "Word(model=JC69)", suffix, suffixIsOptional, warn);
185  else
186  modelDescription = ApplicationTools::getStringParameter("model", params, "JC69", suffix, suffixIsOptional, warn);
187 
188  SubstitutionModel* model = bIO.read(alphabet, modelDescription, data, true);
189  return model;
190 }
191 
192 /******************************************************************************/
193 
195  SubstitutionModel& model,
196  std::map<std::string, std::string>& unparsedParameterValues,
197  size_t modelNumber,
198  const SiteContainer* data,
199  std::map<std::string, double>& existingParams,
200  std::map<std::string, std::string>& sharedParams,
201  bool verbose) throw (Exception)
202 {
203  string initFreqs = ApplicationTools::getStringParameter(model.getNamespace() + "initFreqs", unparsedParameterValues, "", "", true, false);
204 
205  if (verbose)
206  ApplicationTools::displayResult("Frequencies Initialization for model", (initFreqs == "") ? "None" : initFreqs);
207 
208  if (initFreqs != "")
209  {
210  if (initFreqs == "observed")
211  {
212  if (!data)
213  throw Exception("Missing data for observed frequencies");
214  unsigned int psi = ApplicationTools::getParameter<unsigned int>(model.getNamespace() + "initFreqs.observedPseudoCount", unparsedParameterValues, 0);
215  model.setFreqFromData(*data, psi);
216  }
217  else if (initFreqs.substr(0, 6) == "values")
218  {
219  // Initialization using the "values" argument
220  map<int, double> frequencies;
221 
222  string rf = initFreqs.substr(6);
223  StringTokenizer strtok(rf.substr(1, rf.length() - 2), ",");
224  int i = 0;
225  while (strtok.hasMoreToken())
226  frequencies[i++] = TextTools::toDouble(strtok.nextToken());
227  model.setFreq(frequencies);
228  }
229  else
230  throw Exception("Unknown initFreqs argument");
231  }
232 
233 
234 
235  ParameterList pl = model.getIndependentParameters();
236  for (size_t i = 0; i < pl.size(); ++i)
237  {
238  AutoParameter ap(pl[i]);
239  ap.setMessageHandler(ApplicationTools::warning);
240  pl.setParameter(i, ap);
241  }
242 
243  for (size_t i = 0; i < pl.size(); ++i)
244  {
245  const string pName = pl[i].getName();
246  size_t posp = model.getParameterNameWithoutNamespace(pName).rfind(".");
247  string value;
248  bool test1 = (initFreqs == "");
249  bool test2 = (model.getParameterNameWithoutNamespace(pName).substr(posp + 1, 5) != "theta");
250  bool test3 = (unparsedParameterValues.find(pName) != unparsedParameterValues.end());
251  if (test1 || test2 || test3)
252  {
253  if (!test1 && !test2 && test3)
254  ApplicationTools::displayWarning("Warning, initFreqs argument is set and a value is set for parameter " + pName);
255  value = ApplicationTools::getStringParameter(pName, unparsedParameterValues, TextTools::toString(pl[i].getValue()));
256  if (value.rfind("_")!=string::npos)
257  {
258  if (existingParams.find(value) != existingParams.end())
259  {
260  pl[i].setValue(existingParams[value]);
261  sharedParams[pl[i].getName()+"_"+TextTools::toString(modelNumber)]=value;
262  }
263  else
264  throw Exception("Error, unknown parameter " + value);
265  }
266  else
267  pl[i].setValue(TextTools::toDouble(value));
268  }
269 
270  existingParams[pName+"_"+TextTools::toString(modelNumber)] = pl[i].getValue();
271 
272  if (verbose)
273  ApplicationTools::displayResult("Parameter found", pName + +"_"+TextTools::toString(modelNumber) + "=" + TextTools::toString(pl[i].getValue()));
274  }
275 
276  model.matchParametersValues(pl);
277 }
278 
279 
280 /******************************************************/
281 /**** FREQUENCIES SET *********************************/
282 /******************************************************/
283 
284 /******************************************************************************/
285 
287  const Alphabet* alphabet,
288  const GeneticCode* gCode,
289  const SiteContainer* data,
290  std::map<std::string, std::string>& params,
291  const std::vector<double>& rateFreqs,
292  const std::string& suffix,
293  bool suffixIsOptional,
294  bool verbose,
295  int warn) throw (Exception)
296 {
297  string freqDescription = ApplicationTools::getStringParameter("nonhomogeneous.root_freq", params, "Full(init=observed)", suffix, suffixIsOptional, warn);
298  if (freqDescription == "None")
299  {
300  return 0;
301  }
302  else
303  {
304  FrequenciesSet* freq = getFrequenciesSet(alphabet, gCode, freqDescription, data, rateFreqs, verbose, warn + 1);
305  if (verbose)
306  ApplicationTools::displayResult("Root frequencies ", freq->getName());
307  return freq;
308  }
309 }
310 
311 /******************************************************************************/
312 
314  const Alphabet* alphabet,
315  const GeneticCode* gCode,
316  const std::string& freqDescription,
317  const SiteContainer* data,
318  const std::vector<double>& rateFreqs,
319  bool verbose,
320  int warn) throw (Exception)
321 {
322  map<string, string> unparsedParameterValues;
324  if (AlphabetTools::isCodonAlphabet(alphabet)) {
325  if (!gCode)
326  throw Exception("PhylogeneticsApplicationTools::getFrequenciesSet(): a GeneticCode instance is required for instanciating a codon frequencies set.");
327  bIO.setGeneticCode(gCode);
328  }
329  auto_ptr<FrequenciesSet> pFS(bIO.read(alphabet, freqDescription, data, true));
330 
331  // /////// To be changed for input normalization
332  if (rateFreqs.size() > 0)
333  {
334  pFS.reset(new MarkovModulatedFrequenciesSet(pFS.release(), rateFreqs));
335  }
336 
337  return pFS.release();
338 }
339 
340 /******************************************************/
341 /**** SUBSTITUTION MODEL SET **************************/
342 /******************************************************/
343 
344 /******************************************************************************/
345 
347  const Alphabet* alphabet,
348  const GeneticCode* gCode,
349  const SiteContainer* data,
350  std::map<std::string, std::string>& params,
351  const std::string& suffix,
352  bool suffixIsOptional,
353  bool verbose,
354  int warn)
355 {
356  if (!ApplicationTools::parameterExists("nonhomogeneous.number_of_models", params))
357  throw Exception("A value is needed for this parameter: nonhomogeneous.number_of_models .");
358  size_t nbModels = ApplicationTools::getParameter<size_t>("nonhomogeneous.number_of_models", params, 1, suffix, suffixIsOptional, warn);
359  if (nbModels == 0)
360  throw Exception("The number of models can't be 0 !");
361 
362  bool nomix = true;
363  for (size_t i = 0; nomix &(i < nbModels); i++)
364  {
365  string prefix = "model" + TextTools::toString(i + 1);
366  string modelDesc;
367  modelDesc = ApplicationTools::getStringParameter(prefix, params, "", suffix, suffixIsOptional, warn);
368 
369  if (modelDesc.find("Mixed") != string::npos)
370  nomix = false;
371  }
372 
373  SubstitutionModelSet* modelSet, * modelSet1 = 0;
374  modelSet1 = new SubstitutionModelSet(alphabet);
375  setSubstitutionModelSet(*modelSet1, alphabet, gCode, data, params, suffix, suffixIsOptional, verbose, warn);
376 
377  if (modelSet1->hasMixedSubstitutionModel())
378  {
379  modelSet = new MixedSubstitutionModelSet(*modelSet1);
380  completeMixedSubstitutionModelSet(*dynamic_cast<MixedSubstitutionModelSet*>(modelSet), alphabet, data, params, suffix, suffixIsOptional, verbose);
381  }
382  else
383  modelSet = modelSet1;
384 
385  return modelSet;
386 }
387 
388 /******************************************************************************/
389 
391  SubstitutionModelSet& modelSet,
392  const Alphabet* alphabet,
393  const GeneticCode* gCode,
394  const SiteContainer* data,
395  map<string, string>& params,
396  const string& suffix,
397  bool suffixIsOptional,
398  bool verbose,
399  int warn)
400 {
401  modelSet.clear();
402  if (!ApplicationTools::parameterExists("nonhomogeneous.number_of_models", params))
403  throw Exception("You must specify this parameter: 'nonhomogeneous.number_of_models'.");
404  size_t nbModels = ApplicationTools::getParameter<size_t>("nonhomogeneous.number_of_models", params, 1, suffix, suffixIsOptional, warn);
405  if (nbModels == 0)
406  throw Exception("The number of models can't be 0 !");
407 
408  if (verbose)
409  ApplicationTools::displayResult("Number of distinct models", TextTools::toString(nbModels));
410 
411  BppOSubstitutionModelFormat bIO(BppOSubstitutionModelFormat::ALL, true, true, true, false, warn);
412 
413  // ///////////////////////////////////////////
414  // Build a new model set object:
415 
416  vector<double> rateFreqs;
417  string tmpDesc;
418  if (AlphabetTools::isCodonAlphabet(alphabet)) {
419  if (!gCode)
420  throw Exception("PhylogeneticsApplicationTools::setSubstitutionModelSet(): a GeneticCode instance is required for instanciating a codon model.");
421  bIO.setGeneticCode(gCode);
422  tmpDesc = ApplicationTools::getStringParameter("model1", params, "CodonRate(model=JC69)", suffix, suffixIsOptional, warn);
423  } else if (AlphabetTools::isWordAlphabet(alphabet))
424  tmpDesc = ApplicationTools::getStringParameter("model1", params, "Word(model=JC69)", suffix, suffixIsOptional, warn);
425  else
426  tmpDesc = ApplicationTools::getStringParameter("model1", params, "JC69", suffix, suffixIsOptional, warn);
427 
428  auto_ptr<SubstitutionModel> tmp(bIO.read(alphabet, tmpDesc, data, false));
429  // map<string, string> tmpUnparsedParameterValues(bIO.getUnparsedArguments());
430 
431  if (tmp->getNumberOfStates() != alphabet->getSize())
432  {
433  // Markov-Modulated Markov Model...
434  size_t n = static_cast<size_t>(tmp->getNumberOfStates() / alphabet->getSize());
435  rateFreqs = vector<double>(n, 1. / static_cast<double>(n)); // Equal rates assumed for now, may be changed later (actually, in the most general case,
436  }
437 
438  // ////////////////////////////////////
439  // Deal with root frequencies
440 
441  bool stationarity = ApplicationTools::getBooleanParameter("nonhomogeneous.stationarity", params, false, "", true, warn);
442  FrequenciesSet* rootFrequencies = 0;
443  if (!stationarity)
444  {
445  rootFrequencies = getRootFrequenciesSet(alphabet, gCode, data, params, rateFreqs, suffix, suffixIsOptional, verbose);
446  stationarity = !rootFrequencies;
447  string freqDescription = ApplicationTools::getStringParameter("nonhomogeneous.root_freq", params, "", suffix, suffixIsOptional, warn);
448  if (freqDescription.substr(0, 10) == "MVAprotein")
449  {
450  if (dynamic_cast<Coala*>(tmp.get()))
451  dynamic_cast<MvaFrequenciesSet*>(rootFrequencies)->initSet(dynamic_cast<CoalaCore*>(tmp.get()));
452  else
453  throw Exception("The MVAprotein frequencies set at the root can only be used if a Coala model is used on branches.");
454  }
455  }
456  ApplicationTools::displayBooleanResult("Stationarity assumed", stationarity);
457 
458  if (!stationarity)
459  modelSet.setRootFrequencies(rootFrequencies);
460 
461  // //////////////////////////////////////
462  // Now parse all models:
463 
464  bIO.setVerbose(true);
465 
466  map<string, double> existingParameters;
467 
468  for (size_t i = 0; i < nbModels; i++)
469  {
470  string prefix = "model" + TextTools::toString(i + 1);
471  string modelDesc;
472  if (AlphabetTools::isCodonAlphabet(alphabet))
473  modelDesc = ApplicationTools::getStringParameter(prefix, params, "CodonRate(model=JC69)", suffix, suffixIsOptional, warn);
474  else if (AlphabetTools::isWordAlphabet(alphabet))
475  modelDesc = ApplicationTools::getStringParameter(prefix, params, "Word(model=JC69)", suffix, suffixIsOptional, warn);
476  else
477  modelDesc = ApplicationTools::getStringParameter(prefix, params, "JC69", suffix, suffixIsOptional, warn);
478 
479  auto_ptr<SubstitutionModel> model(bIO.read(alphabet, modelDesc, data, false));
480  map<string, string> unparsedParameterValues(bIO.getUnparsedArguments());
481 
482  map<string, string> sharedParameters;
483  setSubstitutionModelParametersInitialValuesWithAliases(
484  *model,
485  unparsedParameterValues, i+1, data,
486  existingParameters, sharedParameters,
487  verbose);
488 
489  vector<int> nodesId = ApplicationTools::getVectorParameter<int>(prefix + ".nodes_id", params, ',', ':', TextTools::toString(i), suffix, suffixIsOptional, warn);
490 
491  if (verbose)
492  ApplicationTools::displayResult("Model" + TextTools::toString(i + 1) + " is associated to", TextTools::toString(nodesId.size()) + " node(s).");
493 
494  modelSet.addModel(model.get(), nodesId);
495 
496  // Now set shared parameters:
497  map<string, string>::const_iterator it;
498  for (it=sharedParameters.begin(); it!=sharedParameters.end(); it++)
499  modelSet.aliasParameters(it->second, it->first);
500 
501  model.release();
502  }
503 
504  // Finally check parameter aliasing:
505  string aliasDesc = ApplicationTools::getStringParameter("nonhomogeneous.alias", params, "", suffix, suffixIsOptional, warn);
506  StringTokenizer st(aliasDesc, ",");
507  while (st.hasMoreToken())
508  {
509  string alias = st.nextToken();
510  string::size_type index = alias.find("->");
511  if (index == string::npos)
512  throw Exception("PhylogeneticsApplicationTools::getSubstitutionModelSet. Bad alias syntax, should contain `->' symbol: " + alias);
513  string p1 = alias.substr(0, index);
514  string p2 = alias.substr(index + 2);
515  ApplicationTools::displayResult("Parameter alias found", p1 + "->" + p2);
516  modelSet.aliasParameters(p1, p2);
517  }
518 }
519 
520 /******************************************************************************/
522  MixedSubstitutionModelSet& mixedModelSet,
523  const Alphabet* alphabet,
524  const SiteContainer* data,
525  map<string, string>& params,
526  const string& suffix,
527  bool suffixIsOptional,
528  bool verbose,
529  int warn)
530 {
531  // /////////////////////////////////////////
532  // Looks for the allowed paths
533 
534  size_t numd;
535  if (!ApplicationTools::parameterExists("site.number_of_paths", params))
536  numd = 0;
537  else
538  numd = ApplicationTools::getParameter<size_t>("site.number_of_paths", params, 1, suffix, suffixIsOptional, warn);
539 
540  if (verbose)
541  ApplicationTools::displayResult("Number of distinct paths", TextTools::toString(numd));
542 
543  vector<string> vdesc;
544  while (numd)
545  {
546  string desc = ApplicationTools::getStringParameter("site.path" + TextTools::toString(numd), params, "", suffix, suffixIsOptional, warn);
547  if (desc.size() == 0)
548  break;
549  else
550  vdesc.push_back(desc);
551  numd--;
552  }
553 
554  if (vdesc.size() == 0)
555  {
556  mixedModelSet.complete();
557  mixedModelSet.computeHyperNodesProbabilities();
558  return;
559  }
560 
561  for (vector<string>::iterator it(vdesc.begin()); it != vdesc.end(); it++)
562  {
563  mixedModelSet.addEmptyHyperNode();
564  StringTokenizer st(*it, "&");
565  while (st.hasMoreToken())
566  {
567  string submodel = st.nextToken();
568  string::size_type indexo = submodel.find("[");
569  string::size_type indexf = submodel.find("]");
570  if ((indexo == string::npos) | (indexf == string::npos))
571  throw Exception("PhylogeneticsApplicationTools::setMixedSubstitutionModelSet. Bad path syntax, should contain `[]' symbols: " + submodel);
572  size_t num = TextTools::to<size_t>(submodel.substr(5, indexo - 5));
573  string p2 = submodel.substr(indexo + 1, indexf - indexo - 1);
574 
575  const MixedSubstitutionModel* pSM = dynamic_cast<const MixedSubstitutionModel*>(mixedModelSet.getModel(num - 1));
576  if (!pSM)
577  throw BadIntegerException("PhylogeneticsApplicationTools::setMixedSubstitutionModelSet: Wrong model for number", static_cast<int>(num - 1));
578  Vint submodnb = pSM->getSubmodelNumbers(p2);
579 
580  mixedModelSet.addToHyperNode(num - 1, submodnb);
581  }
582 
583  if (!mixedModelSet.getHyperNode(mixedModelSet.getNumberOfHyperNodes() - 1).isComplete())
584  throw Exception("A path should own at least a submodel of each mixed model: " + *it);
585 
586  if (verbose)
587  ApplicationTools::displayResult("Site Path", *it);
588  }
589 
590  // / Checks if the paths are separate
591  if (!mixedModelSet.hasExclusivePaths())
592  throw Exception("All paths must be disjoint.");
593 
594  // / Puts all the remaining models in a new path
595  string st;
596  st = (mixedModelSet.complete()) ? "Yes" : "No";
597 
598  if (verbose)
599  ApplicationTools::displayResult("Site Path Completion", st);
600 
601  mixedModelSet.computeHyperNodesProbabilities();
602 
603  if (!mixedModelSet.getHyperNode(mixedModelSet.getNumberOfHyperNodes() - 1).isComplete())
604  throw Exception("The remaining submodels can not create a complete path.");
605 }
606 
607 
608 /******************************************************/
609 /*** DISTRIBUTIONS ********************************/
610 /******************************************************/
611 
612 
613 /******************************************************************************/
614 
616  const std::string& distDescription,
617  std::map<std::string, std::string>& unparsedParameterValues,
618  bool verbose)
619 {
620  string distName;
621  MultipleDiscreteDistribution* pMDD = 0;
622  map<string, string> args;
623  KeyvalTools::parseProcedure(distDescription, distName, args);
624 
625  if (distName == "Dirichlet")
626  {
627  if (args.find("classes") == args.end())
628  throw Exception("Missing argument 'classes' (vector of number of classes) in " + distName
629  + " distribution");
630  if (args.find("alphas") == args.end())
631  throw Exception("Missing argument 'alphas' (vector of Dirichlet shape parameters) in Dirichlet distribution");
632  vector<double> alphas;
633  vector<size_t> classes;
634 
635  string rf = args["alphas"];
636  StringTokenizer strtok(rf.substr(1, rf.length() - 2), ",");
637  while (strtok.hasMoreToken())
638  alphas.push_back(TextTools::toDouble(strtok.nextToken()));
639 
640  rf = args["classes"];
641  StringTokenizer strtok2(rf.substr(1, rf.length() - 2), ",");
642  while (strtok2.hasMoreToken())
643  classes.push_back(TextTools::to<size_t>(strtok2.nextToken()));
644 
645  pMDD = new DirichletDiscreteDistribution(classes, alphas);
646  vector<string> v = pMDD->getParameters().getParameterNames();
647 
648  for (size_t i = 0; i < v.size(); i++)
649  {
650  unparsedParameterValues[v[i]] = TextTools::toString(pMDD->getParameterValue(pMDD->getParameterNameWithoutNamespace(v[i])));
651  }
652  }
653  else
654  throw Exception("Unknown multiple distribution name: " + distName);
655 
656  return pMDD;
657 }
658 
659 /******************************************************************************/
660 
662  map<string, string>& params,
663  const string& suffix,
664  bool suffixIsOptional,
665  bool verbose) throw (Exception)
666 {
667  string distDescription = ApplicationTools::getStringParameter("rate_distribution", params, "Constant()", suffix, suffixIsOptional);
668 
669  string distName;
670  map<string, string> args;
671  KeyvalTools::parseProcedure(distDescription, distName, args);
672 
673  BppORateDistributionFormat bIO(true);
674  auto_ptr<DiscreteDistribution> rDist(bIO.read(distDescription, true));
675 
676  if (verbose)
677  {
678  ApplicationTools::displayResult("Rate distribution", distName);
679  ApplicationTools::displayResult("Number of classes", TextTools::toString(rDist->getNumberOfCategories()));
680  }
681 
682  return rDist.release();
683 }
684 
685 
686 /*************************************************************/
687 /***** OPTIMIZATORS *****************************************/
688 /*************************************************************/
689 
690 /******************************************************************************/
691 
693  TreeLikelihood* tl,
694  const ParameterList& parameters,
695  std::map<std::string, std::string>& params,
696  const std::string& suffix,
697  bool suffixIsOptional,
698  bool verbose,
699  int warn)
700 throw (Exception)
701 {
702  string optimization = ApplicationTools::getStringParameter("optimization", params, "FullD(derivatives=Newton)", suffix, suffixIsOptional, warn);
703  if (optimization == "None")
704  return tl;
705  string optName;
706  map<string, string> optArgs;
707  KeyvalTools::parseProcedure(optimization, optName, optArgs);
708 
709  unsigned int optVerbose = ApplicationTools::getParameter<unsigned int>("optimization.verbose", params, 2, suffix, suffixIsOptional, warn + 1);
710 
711  string mhPath = ApplicationTools::getAFilePath("optimization.message_handler", params, false, false, suffix, suffixIsOptional, "none", warn + 1);
712  OutputStream* messageHandler =
713  (mhPath == "none") ? 0 :
714  (mhPath == "std") ? ApplicationTools::message :
715  new StlOutputStream(new ofstream(mhPath.c_str(), ios::out));
716  if (verbose)
717  ApplicationTools::displayResult("Message handler", mhPath);
718 
719  string prPath = ApplicationTools::getAFilePath("optimization.profiler", params, false, false, suffix, suffixIsOptional, "none", warn + 1);
720  OutputStream* profiler =
721  (prPath == "none") ? 0 :
722  (prPath == "std") ? ApplicationTools::message :
723  new StlOutputStream(new ofstream(prPath.c_str(), ios::out));
724  if (profiler)
725  profiler->setPrecision(20);
726  if (verbose)
727  ApplicationTools::displayResult("Profiler", prPath);
728 
729  bool scaleFirst = ApplicationTools::getBooleanParameter("optimization.scale_first", params, false, suffix, suffixIsOptional, warn + 1);
730  if (scaleFirst)
731  {
732  // We scale the tree before optimizing each branch length separately:
733  if (verbose)
734  ApplicationTools::displayMessage("Scaling the tree before optimizing each branch length separately.");
735  double tolerance = ApplicationTools::getDoubleParameter("optimization.scale_first.tolerance", params, .0001, suffix, suffixIsOptional, warn + 1);
736  if (verbose)
737  ApplicationTools::displayResult("Scaling tolerance", TextTools::toString(tolerance));
738  unsigned int nbEvalMax = ApplicationTools::getParameter<unsigned int>("optimization.scale_first.max_number_f_eval", params, 1000000, suffix, suffixIsOptional, warn + 1);
739  if (verbose)
740  ApplicationTools::displayResult("Scaling max # f eval", TextTools::toString(nbEvalMax));
742  tl,
743  tolerance,
744  nbEvalMax,
745  messageHandler,
746  profiler);
747  if (verbose)
748  ApplicationTools::displayResult("New tree likelihood", -tl->getValue());
749  }
750 
751  // Should I ignore some parameters?
752  ParameterList parametersToEstimate = parameters;
753  vector<string> parNames = parametersToEstimate.getParameterNames();
754 
755  if (params.find("optimization.ignore_parameter") != params.end())
756  throw Exception("optimization.ignore_parameter is deprecated, use optimization.ignore_parameters instead!");
757  string paramListDesc = ApplicationTools::getStringParameter("optimization.ignore_parameters", params, "", suffix, suffixIsOptional, warn + 1);
758  StringTokenizer st(paramListDesc, ",");
759  while (st.hasMoreToken())
760  {
761  try
762  {
763  string param = st.nextToken();
764  if (param == "BrLen")
765  {
766  vector<string> vs = tl->getBranchLengthsParameters().getParameterNames();
767  parametersToEstimate.deleteParameters(vs);
768  if (verbose)
769  ApplicationTools::displayResult("Parameter ignored", string("Branch lengths"));
770  }
771  else if (param == "Ancient")
772  {
774  if (!nhtl)
775  ApplicationTools::displayWarning("The 'Ancient' parameters do not exist in homogeneous models, and will be ignored.");
776  else
777  {
778  vector<string> vs = nhtl->getRootFrequenciesParameters().getParameterNames();
779  parametersToEstimate.deleteParameters(vs);
780  }
781  if (verbose)
782  ApplicationTools::displayResult("Parameter ignored", string("Root frequencies"));
783  }
784  else if (param == "Model")
785  {
786  vector<string> vs;
787  vector<string> vs1 = tl->getSubstitutionModelParameters().getParameterNames();
789  if (nhtl!=NULL){
790  vector<string> vs2 = nhtl->getRootFrequenciesParameters().getParameterNames();
791  VectorTools::diff(vs1,vs2,vs);
792  }
793  else
794  vs=vs1;
795 
796  parametersToEstimate.deleteParameters(vs);
797  if (verbose)
798  ApplicationTools::displayResult("Parameter ignored", string("Model"));
799  }
800  else if (param.find("*") != string::npos)
801  {
802  vector<string> vs=ApplicationTools::matchingParameters(param,parNames);
803 
804  for (vector<string>::iterator it = vs.begin(); it != vs.end(); it++)
805  {
806  parametersToEstimate.deleteParameter(*it);
807  if (verbose)
808  ApplicationTools::displayResult("Parameter ignored", *it);
809  }
810  }
811  else
812  {
813  parametersToEstimate.deleteParameter(param);
814  if (verbose)
815  ApplicationTools::displayResult("Parameter ignored", param);
816  }
817  }
818  catch (ParameterNotFoundException& pnfe)
819  {
820  ApplicationTools::displayWarning("Parameter '" + pnfe.getParameter() + "' not found, and so can't be ignored!");
821  }
822  }
823 
824  // Should I constrain some parameters?
825  vector<string> parToEstNames = parametersToEstimate.getParameterNames();
826 
827  if (params.find("optimization.constrain_parameter") != params.end())
828  throw Exception("optimization.constrain_parameter is deprecated, use optimization.constrain_parameters instead!");
829  paramListDesc = ApplicationTools::getStringParameter("optimization.constrain_parameters", params, "", suffix, suffixIsOptional, warn + 1);
830 
831  string constraint="";
832  string pc, param="";
833 
834  StringTokenizer st2(paramListDesc, ",");
835  while (st2.hasMoreToken())
836  {
837  try
838  {
839  pc = st2.nextToken();
840  string::size_type index = pc.find("=");
841  if (index == string::npos)
842  throw Exception("PhylogeneticsApplicationTools::optimizeParamaters. Bad constrain syntax, should contain `=' symbol: " + pc);
843  param = pc.substr(0, index);
844  constraint = pc.substr(index + 1);
845  IntervalConstraint ic(constraint);
846 
847  vector<string> parNames2;
848 
849  if (param == "BrLen")
850  parNames2 = tl->getBranchLengthsParameters().getParameterNames();
851  else if (param == "Ancient"){
853  if (!nhtl)
854  ApplicationTools::displayWarning("The 'Ancient' parameters do not exist in homogeneous models, and will be ignored.");
855  else
856  {
857  parNames2 = nhtl->getRootFrequenciesParameters().getParameterNames();
858  ApplicationTools::displayResult("Parameter ignored", string("Root frequencies"));
859  }
860  }
861  else if (param == "Model")
862  {
863  vector<string> vs1 = tl->getSubstitutionModelParameters().getParameterNames();
865  if (nhtl!=NULL){
866  vector<string> vs2 = nhtl->getRootFrequenciesParameters().getParameterNames();
867  VectorTools::diff(vs1,vs2,parNames2);
868  }
869  else
870  parNames2=vs1;
871  }
872  else if (param.find("*") != string::npos)
873  parNames2=ApplicationTools::matchingParameters(param,parToEstNames);
874  else
875  parNames2.push_back(param);
876 
877 
878  for (size_t i=0; i<parNames2.size(); i++)
879  {
880  Parameter& par=parametersToEstimate.getParameter(parNames2[i]);
881  if (par.hasConstraint()){
882  par.setConstraint(ic & (*par.getConstraint()), true);
883  if (par.getConstraint()->isEmpty())
884  throw Exception("Empty interval for parameter " + parNames[i] + par.getConstraint()->getDescription());
885  }
886  else
887  par.setConstraint(ic.clone(), true);
888 
889  if (verbose)
890  ApplicationTools::displayResult("Parameter constrained " + par.getName(), par.getConstraint()->getDescription());
891  }
892  }
893  catch (ParameterNotFoundException& pnfe)
894  {
895  ApplicationTools::displayWarning("Parameter '" + pnfe.getParameter() + "' not found, and so can't be constrained!");
896  }
897  catch (ConstraintException& pnfe)
898  {
899  throw Exception("Parameter '" + param + "' does not fit the constraint " + constraint);
900  }
901  }
902 
903 
906 
907  unsigned int nbEvalMax = ApplicationTools::getParameter<unsigned int>("optimization.max_number_f_eval", params, 1000000, suffix, suffixIsOptional, warn + 1);
908  if (verbose)
909  ApplicationTools::displayResult("Max # ML evaluations", TextTools::toString(nbEvalMax));
910 
911  double tolerance = ApplicationTools::getDoubleParameter("optimization.tolerance", params, .000001, suffix, suffixIsOptional, warn + 1);
912  if (verbose)
913  ApplicationTools::displayResult("Tolerance", TextTools::toString(tolerance));
914 
915  // Backing up or restoring?
916  auto_ptr<BackupListener> backupListener;
917  string backupFile = ApplicationTools::getAFilePath("optimization.backup.file", params, false, false, suffix, suffixIsOptional, "none", warn + 1);
918  if (backupFile != "none")
919  {
920  ApplicationTools::displayResult("Parameters will be backup to", backupFile);
921  backupListener.reset(new BackupListener(backupFile));
922  if (FileTools::fileExists(backupFile))
923  {
924  ApplicationTools::displayMessage("A backup file was found! Try to restore parameters from previous run...");
925  ifstream bck(backupFile.c_str(), ios::in);
926  vector<string> lines = FileTools::putStreamIntoVectorOfStrings(bck);
927  double fval = TextTools::toDouble(lines[0].substr(5));
928  ParameterList pl = tl->getParameters();
929  for (size_t l = 1; l < lines.size(); ++l)
930  {
931  if (!TextTools::isEmpty(lines[l]))
932  {
933  StringTokenizer stp(lines[l], "=");
934  if (stp.numberOfRemainingTokens() != 2)
935  {
936  cerr << "Corrupted backup file!!!" << endl;
937  cerr << "at line " << l << ": " << lines[l] << endl;
938  }
939  string pname = stp.nextToken();
940  string pvalue = stp.nextToken();
941  size_t p = pl.whichParameterHasName(pname);
942  pl.setParameter(p, AutoParameter(pl[p]));
943  pl[p].setValue(TextTools::toDouble(pvalue));
944  }
945  }
946  bck.close();
947  tl->setParameters(pl);
948  if (abs(tl->getValue() - fval) > 0.000001)
949  throw Exception("Incorrect likelihood value after restoring, from backup file. Remove backup file and start from scratch :s");
950  ApplicationTools::displayResult("Restoring log-likelihood", -fval);
951  }
952  }
953 
954  // There it goes...
955  bool optimizeTopo = ApplicationTools::getBooleanParameter("optimization.topology", params, false, suffix, suffixIsOptional, warn + 1);
956  if (verbose)
957  ApplicationTools::displayResult("Optimize topology", optimizeTopo ? "yes" : "no");
958  string nniMethod = ApplicationTools::getStringParameter("optimization.topology.algorithm_nni.method", params, "phyml", suffix, suffixIsOptional, warn + 1);
959  string nniAlgo;
960  if (nniMethod == "fast")
961  {
962  nniAlgo = NNITopologySearch::FAST;
963  }
964  else if (nniMethod == "better")
965  {
966  nniAlgo = NNITopologySearch::BETTER;
967  }
968  else if (nniMethod == "phyml")
969  {
970  nniAlgo = NNITopologySearch::PHYML;
971  }
972  else
973  throw Exception("Unknown NNI algorithm: '" + nniMethod + "'.");
974 
975 
976  string order = ApplicationTools::getStringParameter("derivatives", optArgs, "Newton", "", true, warn + 1);
977  string optMethodDeriv;
978  if (order == "Gradient")
979  {
981  }
982  else if (order == "Newton")
983  {
985  }
986  else if (order == "BFGS")
987  {
988  optMethodDeriv = OptimizationTools::OPTIMIZATION_BFGS;
989  }
990  else
991  throw Exception("Unknown derivatives algorithm: '" + order + "'.");
992  if (verbose)
993  ApplicationTools::displayResult("Optimization method", optName);
994  if (verbose)
995  ApplicationTools::displayResult("Algorithm used for derivable parameters", order);
996 
997  // See if we should reparametrize:
998  bool reparam = ApplicationTools::getBooleanParameter("optimization.reparametrization", params, false, suffix, suffixIsOptional, warn + 1);
999  if (verbose)
1000  ApplicationTools::displayResult("Reparametrization", (reparam ? "yes" : "no"));
1001 
1002  // See if we should use a molecular clock constraint:
1003  string clock = ApplicationTools::getStringParameter("optimization.clock", params, "None", suffix, suffixIsOptional, warn + 1);
1004  if (clock != "None" && clock != "Global")
1005  throw Exception("Molecular clock option not recognized, should be one of 'Global' or 'None'.");
1006  bool useClock = (clock == "Global");
1007  if (useClock && optimizeTopo)
1008  throw Exception("PhylogeneticsApplicationTools::optimizeParameters. Cannot optimize topology with a molecular clock.");
1009  if (verbose)
1010  ApplicationTools::displayResult("Molecular clock", clock);
1011 
1012  unsigned int n = 0;
1013  if ((optName == "D-Brent") || (optName == "D-BFGS"))
1014  {
1015  // Uses Newton-Brent method or Newton-BFGS method
1016  string optMethodModel;
1017  if (optName == "D-Brent")
1018  optMethodModel = OptimizationTools::OPTIMIZATION_BRENT;
1019  else
1020  optMethodModel = OptimizationTools::OPTIMIZATION_BFGS;
1021 
1022  unsigned int nstep = ApplicationTools::getParameter<unsigned int>("nstep", optArgs, 1, "", true, warn + 1);
1023 
1024  if (optimizeTopo)
1025  {
1026  bool optNumFirst = ApplicationTools::getBooleanParameter("optimization.topology.numfirst", params, true, suffix, suffixIsOptional, warn + 1);
1027  unsigned int topoNbStep = ApplicationTools::getParameter<unsigned int>("optimization.topology.nstep", params, 1, suffix, suffixIsOptional, warn + 1);
1028  double tolBefore = ApplicationTools::getDoubleParameter("optimization.topology.tolerance.before", params, 100, suffix, suffixIsOptional, warn + 1);
1029  double tolDuring = ApplicationTools::getDoubleParameter("optimization.topology.tolerance.during", params, 100, suffix, suffixIsOptional, warn + 1);
1031  dynamic_cast<NNIHomogeneousTreeLikelihood*>(tl), parametersToEstimate,
1032  optNumFirst, tolBefore, tolDuring, nbEvalMax, topoNbStep, messageHandler, profiler,
1033  reparam, optVerbose, optMethodDeriv, nstep, nniAlgo);
1034  }
1035 
1036  if (verbose && nstep > 1)
1037  ApplicationTools::displayResult("# of precision steps", TextTools::toString(nstep));
1038  parametersToEstimate.matchParametersValues(tl->getParameters());
1040  dynamic_cast<DiscreteRatesAcrossSitesTreeLikelihood*>(tl), parametersToEstimate,
1041  backupListener.get(), nstep, tolerance, nbEvalMax, messageHandler, profiler, reparam, optVerbose, optMethodDeriv, optMethodModel);
1042  }
1043  else if (optName == "FullD")
1044  {
1045  // Uses Newton-raphson algorithm with numerical derivatives when required.
1046 
1047  if (optimizeTopo)
1048  {
1049  bool optNumFirst = ApplicationTools::getBooleanParameter("optimization.topology.numfirst", params, true, suffix, suffixIsOptional, warn + 1);
1050  unsigned int topoNbStep = ApplicationTools::getParameter<unsigned int>("optimization.topology.nstep", params, 1, suffix, suffixIsOptional, warn + 1);
1051  double tolBefore = ApplicationTools::getDoubleParameter("optimization.topology.tolerance.before", params, 100, suffix, suffixIsOptional, warn + 1);
1052  double tolDuring = ApplicationTools::getDoubleParameter("optimization.topology.tolerance.during", params, 100, suffix, suffixIsOptional, warn + 1);
1054  dynamic_cast<NNIHomogeneousTreeLikelihood*>(tl), parametersToEstimate,
1055  optNumFirst, tolBefore, tolDuring, nbEvalMax, topoNbStep, messageHandler, profiler,
1056  reparam, optVerbose, optMethodDeriv, nniAlgo);
1057  }
1058 
1059  parametersToEstimate.matchParametersValues(tl->getParameters());
1061  dynamic_cast<DiscreteRatesAcrossSitesTreeLikelihood*>(tl), parametersToEstimate,
1062  backupListener.get(), tolerance, nbEvalMax, messageHandler, profiler, reparam, useClock, optVerbose, optMethodDeriv);
1063  }
1064  else
1065  throw Exception("Unknown optimization method: " + optName);
1066 
1067  string finalMethod = ApplicationTools::getStringParameter("optimization.final", params, "none", suffix, suffixIsOptional, warn + 1);
1068  Optimizer* finalOptimizer = 0;
1069  if (finalMethod == "none")
1070  {}
1071  else if (finalMethod == "simplex")
1072  {
1073  finalOptimizer = new DownhillSimplexMethod(tl);
1074  }
1075  else if (finalMethod == "powell")
1076  {
1077  finalOptimizer = new PowellMultiDimensions(tl);
1078  }
1079  else
1080  throw Exception("Unknown final optimization method: " + finalMethod);
1081 
1082  if (finalOptimizer)
1083  {
1084  parametersToEstimate.matchParametersValues(tl->getParameters());
1085  if (verbose)
1086  ApplicationTools::displayResult("Final optimization step", finalMethod);
1087  finalOptimizer->setProfiler(profiler);
1088  finalOptimizer->setMessageHandler(messageHandler);
1089  finalOptimizer->setMaximumNumberOfEvaluations(nbEvalMax);
1090  finalOptimizer->getStopCondition()->setTolerance(tolerance);
1091  finalOptimizer->setVerbose(verbose);
1092  finalOptimizer->setConstraintPolicy(AutoParameter::CONSTRAINTS_AUTO);
1093  finalOptimizer->init(parametersToEstimate);
1094  finalOptimizer->optimize();
1095  n += finalOptimizer->getNumberOfEvaluations();
1096  delete finalOptimizer;
1097  }
1098 
1099  if (verbose)
1100  ApplicationTools::displayResult("Performed", TextTools::toString(n) + " function evaluations.");
1101  if (backupFile != "none")
1102  {
1103  remove(backupFile.c_str());
1104  }
1105  return tl;
1106 }
1107 
1108 /******************************************************************************/
1109 
1112  const ParameterList& parameters,
1113  map<string, string>& params,
1114  const string& suffix,
1115  bool suffixIsOptional,
1116  bool verbose,
1117  int warn)
1118 throw (Exception)
1119 {
1120  string optimization = ApplicationTools::getStringParameter("optimization", params, "FullD(derivatives=Newton)", suffix, suffixIsOptional, warn);
1121  if (optimization == "None")
1122  return;
1123  string optName;
1124  map<string, string> optArgs;
1125  KeyvalTools::parseProcedure(optimization, optName, optArgs);
1126 
1127  unsigned int optVerbose = ApplicationTools::getParameter<unsigned int>("optimization.verbose", params, 2, suffix, suffixIsOptional, warn + 1);
1128 
1129  string mhPath = ApplicationTools::getAFilePath("optimization.message_handler", params, false, false, suffix, suffixIsOptional, "none", warn + 1);
1130  OutputStream* messageHandler =
1131  (mhPath == "none") ? 0 :
1132  (mhPath == "std") ? ApplicationTools::message :
1133  new StlOutputStream(new ofstream(mhPath.c_str(), ios::out));
1134  if (verbose)
1135  ApplicationTools::displayResult("Message handler", mhPath);
1136 
1137  string prPath = ApplicationTools::getAFilePath("optimization.profiler", params, false, false, suffix, suffixIsOptional, "none", warn + 1);
1138  OutputStream* profiler =
1139  (prPath == "none") ? 0 :
1140  (prPath == "std") ? ApplicationTools::message :
1141  new StlOutputStream(new ofstream(prPath.c_str(), ios::out));
1142  if (profiler)
1143  profiler->setPrecision(20);
1144  if (verbose)
1145  ApplicationTools::displayResult("Profiler", prPath);
1146 
1147  ParameterList parametersToEstimate = parameters;
1148 
1149  // Should I ignore some parameters?
1150  if (params.find("optimization.ignore_parameter") != params.end())
1151  throw Exception("optimization.ignore_parameter is deprecated, use optimization.ignore_parameters instead!");
1152  string paramListDesc = ApplicationTools::getStringParameter("optimization.ignore_parameters", params, "", suffix, suffixIsOptional, warn + 1);
1153  StringTokenizer st(paramListDesc, ",");
1154  while (st.hasMoreToken())
1155  {
1156  try
1157  {
1158  string param = st.nextToken();
1159  if (param == "BrLen")
1160  {
1161  vector<string> vs = tl->getBranchLengthsParameters().getParameterNames();
1162  parametersToEstimate.deleteParameters(vs);
1163  if (verbose)
1164  ApplicationTools::displayResult("Parameter ignored", string("Branch lengths"));
1165  }
1166  else if (param == "Ancient")
1167  {
1169  if (!nhtl)
1170  ApplicationTools::displayWarning("The 'Ancient' parameters do not exist in homogeneous models, and will be ignored.");
1171  else
1172  {
1173  vector<string> vs = nhtl->getRootFrequenciesParameters().getParameterNames();
1174  parametersToEstimate.deleteParameters(vs);
1175  }
1176  if (verbose)
1177  ApplicationTools::displayResult("Parameter ignored", string("Root frequencies"));
1178  }
1179  else
1180  {
1181  parametersToEstimate.deleteParameter(param);
1182  if (verbose)
1183  ApplicationTools::displayResult("Parameter ignored", param);
1184  }
1185  }
1186  catch (ParameterNotFoundException& pnfe)
1187  {
1188  ApplicationTools::displayError("Parameter '" + pnfe.getParameter() + "' not found, and so can't be ignored!");
1189  }
1190  }
1191 
1192  unsigned int nbEvalMax = ApplicationTools::getParameter<unsigned int>("optimization.max_number_f_eval", params, 1000000, suffix, suffixIsOptional, warn + 1);
1193  if (verbose)
1194  ApplicationTools::displayResult("Max # ML evaluations", TextTools::toString(nbEvalMax));
1195 
1196  double tolerance = ApplicationTools::getDoubleParameter("optimization.tolerance", params, .000001, suffix, suffixIsOptional, warn + 1);
1197  if (verbose)
1198  ApplicationTools::displayResult("Tolerance", TextTools::toString(tolerance));
1199 
1200  string order = ApplicationTools::getStringParameter("derivatives", optArgs, "Gradient", "", true, warn + 1);
1201  string optMethod, derMethod;
1202  if (order == "Gradient")
1203  {
1205  }
1206  else if (order == "Newton")
1207  {
1209  }
1210  else
1211  throw Exception("Option '" + order + "' is not known for 'optimization.method.derivatives'.");
1212  if (verbose)
1213  ApplicationTools::displayResult("Optimization method", optName);
1214  if (verbose)
1215  ApplicationTools::displayResult("Algorithm used for derivable parameters", order);
1216 
1217  // Backing up or restoring?
1218  auto_ptr<BackupListener> backupListener;
1219  string backupFile = ApplicationTools::getAFilePath("optimization.backup.file", params, false, false, suffix, suffixIsOptional, "none", warn + 1);
1220  if (backupFile != "none")
1221  {
1222  ApplicationTools::displayResult("Parameters will be backup to", backupFile);
1223  backupListener.reset(new BackupListener(backupFile));
1224  if (FileTools::fileExists(backupFile))
1225  {
1226  ApplicationTools::displayMessage("A backup file was found! Try to restore parameters from previous run...");
1227  ifstream bck(backupFile.c_str(), ios::in);
1228  vector<string> lines = FileTools::putStreamIntoVectorOfStrings(bck);
1229  double fval = TextTools::toDouble(lines[0].substr(5));
1230  ParameterList pl = tl->getParameters();
1231  for (size_t l = 1; l < lines.size(); ++l)
1232  {
1233  if (!TextTools::isEmpty(lines[l]))
1234  {
1235  StringTokenizer stp(lines[l], "=");
1236  if (stp.numberOfRemainingTokens() != 2)
1237  {
1238  cerr << "Corrupted backup file!!!" << endl;
1239  cerr << "at line " << l << ": " << lines[l] << endl;
1240  }
1241  string pname = stp.nextToken();
1242  string pvalue = stp.nextToken();
1243  size_t p = pl.whichParameterHasName(pname);
1244  pl.setParameter(p, AutoParameter(pl[p]));
1245  pl[p].setValue(TextTools::toDouble(pvalue));
1246  }
1247  }
1248  bck.close();
1249  tl->setParameters(pl);
1250  if (abs(tl->getValue() - fval) > 0.000001)
1251  throw Exception("Incorrect likelihood value after restoring, from backup file. Remove backup file and start from scratch :s");
1252  ApplicationTools::displayResult("Restoring log-likelihood", -fval);
1253  }
1254  }
1255 
1256  size_t n = 0;
1257  if (optName == "D-Brent")
1258  {
1259  // Uses Newton-Brent method:
1260  unsigned int nstep = ApplicationTools::getParameter<unsigned int>("nstep", optArgs, 1, "", true, warn + 1);
1261  if (verbose && nstep > 1)
1262  ApplicationTools::displayResult("# of precision steps", TextTools::toString(nstep));
1264  tl,
1265  parametersToEstimate,
1266  backupListener.get(),
1267  nstep,
1268  tolerance,
1269  nbEvalMax,
1270  messageHandler,
1271  profiler,
1272  optVerbose,
1273  optMethod);
1274  }
1275  else if (optName == "FullD")
1276  {
1277  // Uses Newton-raphson alogrithm with numerical derivatives when required.
1279  tl,
1280  parametersToEstimate,
1281  backupListener.get(),
1282  tolerance,
1283  nbEvalMax,
1284  messageHandler,
1285  profiler,
1286  optVerbose,
1287  optMethod);
1288  }
1289  else
1290  throw Exception("Unknown optimization method: " + optName);
1291 
1292  string finalMethod = ApplicationTools::getStringParameter("optimization.final", params, "none", suffix, suffixIsOptional, warn + 1);
1293  Optimizer* finalOptimizer = 0;
1294  if (finalMethod == "none")
1295  {}
1296  else if (finalMethod == "simplex")
1297  {
1298  finalOptimizer = new DownhillSimplexMethod(tl);
1299  }
1300  else if (finalMethod == "powell")
1301  {
1302  finalOptimizer = new PowellMultiDimensions(tl);
1303  }
1304  else
1305  throw Exception("Unknown final optimization method: " + finalMethod);
1306 
1307  if (finalOptimizer)
1308  {
1309  parametersToEstimate.matchParametersValues(tl->getParameters());
1310  ApplicationTools::displayResult("Final optimization step", finalMethod);
1311  finalOptimizer->setProfiler(profiler);
1312  finalOptimizer->setMessageHandler(messageHandler);
1313  finalOptimizer->setMaximumNumberOfEvaluations(nbEvalMax);
1314  finalOptimizer->getStopCondition()->setTolerance(tolerance);
1315  finalOptimizer->setVerbose(verbose);
1316  finalOptimizer->setConstraintPolicy(AutoParameter::CONSTRAINTS_AUTO);
1317  finalOptimizer->init(parametersToEstimate);
1318  finalOptimizer->optimize();
1319  n += finalOptimizer->getNumberOfEvaluations();
1320  delete finalOptimizer;
1321  }
1322 
1323  if (verbose)
1324  ApplicationTools::displayResult("Performed", TextTools::toString(n) + " function evaluations.");
1325  if (backupFile != "none")
1326  {
1327  remove(backupFile.c_str());
1328  }
1329 }
1330 
1331 /******************************************************************************/
1332 
1334 {
1335  for (size_t i = 0; i < pl.size(); ++i)
1336  {
1337  const Constraint* constraint = pl[i].getConstraint();
1338  if (constraint)
1339  {
1340  double value = pl[i].getValue();
1341  if (!constraint->isCorrect(value - 1e-6) || !constraint->isCorrect(value + 1e-6))
1342  {
1343  ApplicationTools::displayWarning("This parameter has a value close to the boundary: " + pl[i].getName() + "(" + TextTools::toString(value) + ").");
1344  }
1345  }
1346  }
1347 }
1348 
1349 /******************************************************************************/
1350 
1352  const TreeTemplate<Node>& tree,
1353  map<string, string>& params,
1354  const string& prefix,
1355  const string& suffix,
1356  bool suffixIsOptional,
1357  bool verbose,
1358  bool checkOnly,
1359  int warn) throw (Exception)
1360 {
1361  string format = ApplicationTools::getStringParameter(prefix + "tree.format", params, "Newick", suffix, suffixIsOptional, warn);
1362  string file = ApplicationTools::getAFilePath(prefix + "tree.file", params, true, false, suffix, suffixIsOptional, "none", warn);
1363  OTree* treeWriter;
1364  if (format == "Newick")
1365  treeWriter = new Newick();
1366  else if (format == "Nexus")
1367  treeWriter = new NexusIOTree();
1368  else if (format == "NHX")
1369  treeWriter = new Nhx(false);
1370  else
1371  throw Exception("Unknown format for tree writing: " + format);
1372  if (!checkOnly)
1373  treeWriter->write(tree, file, true);
1374  delete treeWriter;
1375  if (verbose)
1376  ApplicationTools::displayResult("Wrote tree to file ", file);
1377 }
1378 
1379 /******************************************************************************/
1380 
1382  const vector<Tree*>& trees,
1383  map<string, string>& params,
1384  const string& prefix,
1385  const string& suffix,
1386  bool suffixIsOptional,
1387  bool verbose,
1388  bool checkOnly,
1389  int warn) throw (Exception)
1390 {
1391  string format = ApplicationTools::getStringParameter(prefix + "trees.format", params, "Newick", suffix, suffixIsOptional, warn);
1392  string file = ApplicationTools::getAFilePath(prefix + "trees.file", params, true, false, suffix, suffixIsOptional, "none", warn);
1393  OMultiTree* treeWriter;
1394  if (format == "Newick")
1395  treeWriter = new Newick();
1396  else if (format == "Nexus")
1397  treeWriter = new NexusIOTree();
1398  else if (format == "NHX")
1399  treeWriter = new Nhx();
1400  else
1401  throw Exception("Unknow format for tree writing: " + format);
1402  if (!checkOnly)
1403  treeWriter->write(trees, file, true);
1404  delete treeWriter;
1405  if (verbose)
1406  ApplicationTools::displayResult("Wrote trees to file ", file);
1407 }
1408 
1409 /******************************************************************************/
1410 
1411 void PhylogeneticsApplicationTools::printParameters(const SubstitutionModel* model, OutputStream& out, int warn)
1412 {
1413  out << "model=";
1414  map<string, string> globalAliases;
1415  vector<string> writtenNames;
1416  BppOSubstitutionModelFormat bIO(BppOSubstitutionModelFormat::ALL, true, true, true, false, warn);
1417  bIO.write(*model, out, globalAliases, writtenNames);
1418  out.endLine();
1419 }
1420 
1421 /******************************************************************************/
1422 
1423 void PhylogeneticsApplicationTools::printParameters(const SubstitutionModelSet* modelSet, OutputStream& out, int warn)
1424 {
1425  (out << "nonhomogeneous=general").endLine();
1426  (out << "nonhomogeneous.number_of_models=" << modelSet->getNumberOfModels()).endLine();
1427 
1428  // Get the parameter links:
1429  map< size_t, vector<string> > modelLinks; // for each model index, stores the list of global parameters.
1430  map< string, set<size_t> > parameterLinks; // for each parameter name, stores the list of model indices, wich should be sorted.
1431  vector<string> writtenNames;
1432 
1433  // Loop over all models:
1434  for (size_t i = 0; i < modelSet->getNumberOfModels(); i++)
1435  {
1436  const SubstitutionModel* model = modelSet->getModel(i);
1437 
1438  // First get the aliases for this model:
1439  map<string, string> aliases;
1440 
1441  ParameterList pl=model->getParameters();
1442 
1443  for (size_t np = 0 ; np< pl.size() ; np++)
1444  {
1445  string nfrom = modelSet->getFrom(pl[np].getName() + "_" + TextTools::toString(i + 1));
1446  if (nfrom != "")
1447  aliases[pl[np].getName()] = nfrom;
1448  }
1449 
1450  // Now print it:
1451  writtenNames.clear();
1452  out.endLine() << "model" << (i + 1) << "=";
1453  BppOSubstitutionModelFormat bIOsm(BppOSubstitutionModelFormat::ALL, true, true, true, false, warn);
1454  map<string, string>::iterator it;
1455  bIOsm.write(*model, out, aliases, writtenNames);
1456  out.endLine();
1457  vector<int> ids = modelSet->getNodesWithModel(i);
1458  out << "model" << (i + 1) << ".nodes_id=" << ids[0];
1459  for (size_t j = 1; j < ids.size(); ++j)
1460  {
1461  out << "," << ids[j];
1462  }
1463  out.endLine();
1464  }
1465 
1466  // Root frequencies:
1467  out.endLine();
1468  (out << "# Root frequencies:").endLine();
1469  out << "nonhomogeneous.root_freq=";
1470 
1472  bIO.write(modelSet->getRootFrequenciesSet(), out, writtenNames);
1473 }
1474 
1475 /******************************************************************************/
1476 
1477 void PhylogeneticsApplicationTools::printParameters(const DiscreteDistribution* rDist, OutputStream& out)
1478 {
1479  out << "rate_distribution=";
1480  map<string, string> globalAliases;
1481  vector<string> writtenNames;
1483 
1484  bIO->write(*rDist, out, globalAliases, writtenNames);
1485  delete bIO;
1486  out.endLine();
1487 }
1488 
1489 /************************
1490  * Substitution Mapping *
1491  ************************/
1492 
1494  const Alphabet* alphabet,
1495  const SubstitutionModel* model,
1496  map<string, string>& params,
1497  string suffix,
1498  bool verbose,
1499  int warn)
1500 {
1501  SubstitutionCount* substitutionCount = 0;
1502  string nijtOption;
1503  map<string, string> nijtParams;
1504  string nijtText = ApplicationTools::getStringParameter("nijt", params, "Uniformization", suffix, true, warn);
1505  KeyvalTools::parseProcedure(nijtText, nijtOption, nijtParams);
1506 
1507  if (nijtOption == "Laplace")
1508  {
1509  size_t trunc = ApplicationTools::getParameter<size_t>("trunc", nijtParams, 10, suffix, true, warn + 1);
1510  substitutionCount = new LaplaceSubstitutionCount(model, trunc);
1511  }
1512  else if (nijtOption == "Uniformization")
1513  {
1514  string weightOption = ApplicationTools::getStringParameter("weight", nijtParams, "None", "", true, warn + 1);
1515  AlphabetIndex2* weights = SequenceApplicationTools::getAlphabetIndex2(alphabet, weightOption, "Substitution weight scheme:");
1516  substitutionCount = new UniformizationSubstitutionCount(model, new TotalSubstitutionRegister(model), weights);
1517  }
1518  else if (nijtOption == "Decomposition")
1519  {
1520  string weightOption = ApplicationTools::getStringParameter("weight", nijtParams, "None", "", true, warn + 1);
1521  AlphabetIndex2* weights = SequenceApplicationTools::getAlphabetIndex2(alphabet, weightOption, "Substitution weight scheme:");
1522  const ReversibleSubstitutionModel* revModel = dynamic_cast<const ReversibleSubstitutionModel*>(model);
1523  if (revModel)
1524  substitutionCount = new DecompositionSubstitutionCount(revModel, new TotalSubstitutionRegister(model), weights);
1525  else
1526  throw Exception("Decomposition method can only be used with reversible substitution models.");
1527  }
1528  else if (nijtOption == "Naive")
1529  {
1530  string weightOption = ApplicationTools::getStringParameter("weight", nijtParams, "None", "", true, warn + 1);
1531  AlphabetIndex2* weights = SequenceApplicationTools::getAlphabetIndex2(alphabet, weightOption, "Substitution weight scheme:");
1532  substitutionCount = new NaiveSubstitutionCount(model, new TotalSubstitutionRegister(model), false, weights);
1533  }
1534  else if (nijtOption == "Label")
1535  {
1536  substitutionCount = new LabelSubstitutionCount(model);
1537  }
1538  else if (nijtOption == "ProbOneJump")
1539  {
1540  substitutionCount = new OneJumpSubstitutionCount(model);
1541  }
1542  else
1543  {
1544  ApplicationTools::displayError("Invalid option '" + nijtOption + ", in 'nijt' parameter.");
1545  exit(-1);
1546  }
1547  ApplicationTools::displayResult("Substitution count procedure", nijtOption);
1548 
1549  // Send results:
1550  return substitutionCount;
1551 }
1552 
1553 /******************************************************************************/
1554 
static Tree * getTree(std::map< std::string, std::string > &params, const std::string &prefix="input.", const std::string &suffix="", bool suffixIsOptional=true, bool verbose=true, int warn=1)
Build a Tree object according to options.
static NNIHomogeneousTreeLikelihood * optimizeTreeNNI(NNIHomogeneousTreeLikelihood *tl, const ParameterList &parameters, bool optimizeNumFirst=true, double tolBefore=100, double tolDuring=100, unsigned int tlEvalMax=1000000, unsigned int numStep=1, OutputStream *messageHandler=ApplicationTools::message, OutputStream *profiler=ApplicationTools::message, bool reparametrization=false, unsigned int verbose=1, const std::string &optMethod=OptimizationTools::OPTIMIZATION_NEWTON, unsigned int nStep=1, const std::string &nniMethod=NNITopologySearch::PHYML)
Optimize all parameters from a TreeLikelihood object, including tree topology using Nearest Neighbor ...
Substitution models manager for non-homogeneous / non-reversible models of evolution.
Interface for all substitution models.
static unsigned int optimizeNumericalParametersWithGlobalClock2(DiscreteRatesAcrossSitesClockTreeLikelihood *cl, const ParameterList &parameters, OptimizationListener *listener=0, double tolerance=0.000001, unsigned int tlEvalMax=1000000, OutputStream *messageHandler=ApplicationTools::message, OutputStream *profiler=ApplicationTools::message, unsigned int verbose=1, const std::string &optMethodDeriv=OPTIMIZATION_GRADIENT)
Optimize numerical parameters assuming a global clock (branch heights, substitution model & rate dist...
a simple parser for reading trees from a Nexus file.
Definition: NexusIoTree.h:61
virtual Vint getSubmodelNumbers(std::string &desc) const =0
static const std::string FAST
Analytical substitution count using the eigen decomposition method.
const SubstitutionModel * getModel(size_t i) const
Get one model from the set knowing its index.
static void writeTree(const TreeTemplate< Node > &tree, std::map< std::string, std::string > &params, const std::string &prefix="output.", const std::string &suffix="", bool suffixIsOptional=true, bool verbose=true, bool checkOnly=false, int warn=1)
Write a tree according to options.
Frequencies set I/O in BppO format.
static SubstitutionModelSet * getSubstitutionModelSet(const Alphabet *alphabet, const GeneticCode *gcode, const SiteContainer *data, std::map< std::string, std::string > &params, const std::string &suffix="", bool suffixIsOptional=true, bool verbose=true, int warn=1)
Gets a SubstitutionModelSet object according to options.
void setRootFrequencies(FrequenciesSet *rootFreqs)
Sets a given FrequenciesSet for root frequencies.
static FrequenciesSet * getFrequenciesSet(const Alphabet *alphabet, const GeneticCode *gCode, const std::string &freqDescription, const SiteContainer *data, const std::vector< double > &rateFreqs, bool verbose=true, int warn=1)
Get A FrequenciesSet object according to options.
virtual ParameterList getRootFrequenciesParameters() const =0
The so-called &#39;Nhx - New Hampshire eXtended&#39; parenthetic format.
Definition: Nhx.h:87
void write(const SubstitutionModel &model, OutputStream &out, std::map< std::string, std::string > &globalAliases, std::vector< std::string > &writtenNames) const
Write a substitution model to a stream.
The TreeLikelihood interface.
STL namespace.
static SubstitutionModel * getSubstitutionModel(const Alphabet *alphabet, const GeneticCode *gCode, const SiteContainer *data, std::map< std::string, std::string > &params, const std::string &suffix="", bool suffixIsOptional=true, bool verbose=true, int warn=1)
Build a SubstitutionModel object according to options.
General interface for tree writers.
Definition: IoTree.h:103
General interface for tree readers.
Definition: IoTree.h:74
The phylogenetic tree class.
static std::string OPTIMIZATION_GRADIENT
const std::map< std::string, std::string > & getUnparsedArguments() const
Interface for phylogenetic tree objects.
Definition: Tree.h:148
Parametrize a set of state frequencies.
FrequenciesSet to be used with a Markov-modulated substitution model.
void write(const FrequenciesSet *pfreqset, OutputStream &out, std::vector< std::string > &writtenNames) const
Write a substitution model to a stream.
void addModel(SubstitutionModel *model, const std::vector< int > &nodesId)
Add a new model to the set, and set relationships with nodes and params.
static MultipleDiscreteDistribution * getMultipleDistributionDefaultInstance(const std::string &distDescription, std::map< std::string, std::string > &unparsedParameterValues, bool verbose=true)
Build a multi-dimension distribution as a MultipleDiscreteDistribution object with default parameter ...
static std::vector< Tree * > getTrees(std::map< std::string, std::string > &params, const std::string &prefix="input.", const std::string &suffix="", bool suffixIsOptional=true, bool verbose=true, int warn=1)
Build a list ofTree objects according to options.
const FrequenciesSet * getRootFrequenciesSet() const
virtual Tree * read(const std::string &path) const =0
Read a tree from a file.
void clear()
Resets all the information contained in this object.
virtual void read(const std::string &path, std::vector< Tree *> &trees) const =0
Read trees from a file.
Interface for reversible substitution models.
void addToHyperNode(size_t nM, const Vint &vnS, int nH=-1)
static void completeMixedSubstitutionModelSet(MixedSubstitutionModelSet &mixedModelSet, const Alphabet *alphabet, const SiteContainer *data, std::map< std::string, std::string > &params, const std::string &suffix="", bool suffixIsOptional=true, bool verbose=true, int warn=1)
Complete a MixedSubstitutionModelSet object according to options, given this model has already been f...
static unsigned int optimizeNumericalParameters(DiscreteRatesAcrossSitesTreeLikelihood *tl, const ParameterList &parameters, OptimizationListener *listener=0, unsigned int nstep=1, double tolerance=0.000001, unsigned int tlEvalMax=1000000, OutputStream *messageHandler=ApplicationTools::message, OutputStream *profiler=ApplicationTools::message, bool reparametrization=false, unsigned int verbose=1, const std::string &optMethodDeriv=OPTIMIZATION_NEWTON, const std::string &optMethodModel=OPTIMIZATION_BRENT)
Optimize numerical parameters (branch length, substitution model & rate distribution) of a TreeLikeli...
The so-called &#39;newick&#39; parenthetic format.
Definition: Newick.h:83
DiscreteDistribution * read(const std::string &distDescription, bool parseArguments)
virtual std::string getName() const =0
Computes the probability that at least one jump occured on a branch, given the initial and final stat...
General interface for tree writers.
Definition: IoTree.h:222
virtual void write(const Tree &tree, const std::string &path, bool overwrite) const =0
Write a tree to a file.
static std::string OPTIMIZATION_BRENT
Substitution models manager for Mixed Substitution Models. This class inherits from SubstitutionModel...
static void printParameters(const SubstitutionModel *model, OutputStream &out, int warn=1)
Output a SubstitutionModel description to a file.
static unsigned int optimizeNumericalParameters2(DiscreteRatesAcrossSitesTreeLikelihood *tl, const ParameterList &parameters, OptimizationListener *listener=0, double tolerance=0.000001, unsigned int tlEvalMax=1000000, OutputStream *messageHandler=ApplicationTools::message, OutputStream *profiler=ApplicationTools::message, bool reparametrization=false, bool useClock=false, unsigned int verbose=1, const std::string &optMethodDeriv=OPTIMIZATION_NEWTON)
Optimize numerical parameters (branch length, substitution model & rate distribution) of a TreeLikeli...
FrequenciesSet * read(const Alphabet *alphabet, const std::string &freqDescription, const SiteContainer *data, bool parseArguments=true)
Read a frequencies set from a string.
Interface for likelihood computation with a global clock and rate across sites variation.
Rate Distribution I/O in BppO format.
General interface for multiple trees readers.
Definition: IoTree.h:193
static TreeLikelihood * optimizeParameters(TreeLikelihood *tl, const ParameterList &parameters, std::map< std::string, std::string > &params, const std::string &suffix="", bool suffixIsOptional=true, bool verbose=true, int warn=1)
Optimize parameters according to options.
void write(const DiscreteDistribution &dist, OutputStream &out, std::map< std::string, std::string > &globalAliases, std::vector< std::string > &writtenNames) const
Analytical (weighted) substitution count using the uniformization method.
virtual void write(const std::vector< Tree *> &trees, const std::string &path, bool overwrite) const =0
Write trees to a file.
Labelling substitution count.
The SubstitutionsCount interface.
static void writeTrees(const std::vector< Tree *> &trees, std::map< std::string, std::string > &params, const std::string &prefix="output.", const std::string &suffix="", bool suffixIsOptional=true, bool verbose=true, bool checkOnly=false, int warn=1)
Write a tree according to options.
Substitution model I/O in BppO format.
static const std::string BETTER
static const std::string PHYML
void setGeneticCode(const GeneticCode *gCode)
Set the genetic code to use in case a codon frequencies set should be built.
static void setSubstitutionModelSet(SubstitutionModelSet &modelSet, const Alphabet *alphabet, const GeneticCode *gcode, const SiteContainer *data, std::map< std::string, std::string > &params, const std::string &suffix="", bool suffixIsOptional=true, bool verbose=true, int warn=1)
Sets a SubstitutionModelSet object according to options.
Specialization of the TreeLikelihood interface for the branch non-homogeneous and non-stationary mode...
static NNIHomogeneousTreeLikelihood * optimizeTreeNNI2(NNIHomogeneousTreeLikelihood *tl, const ParameterList &parameters, bool optimizeNumFirst=true, double tolBefore=100, double tolDuring=100, unsigned int tlEvalMax=1000000, unsigned int numStep=1, OutputStream *messageHandler=ApplicationTools::message, OutputStream *profiler=ApplicationTools::message, bool reparametrization=false, unsigned int verbose=1, const std::string &optMethod=OptimizationTools::OPTIMIZATION_NEWTON, const std::string &nniMethod=NNITopologySearch::PHYML)
Optimize all parameters from a TreeLikelihood object, including tree topology using Nearest Neighbor ...
static FrequenciesSet * getRootFrequenciesSet(const Alphabet *alphabet, const GeneticCode *gCode, const SiteContainer *data, std::map< std::string, std::string > &params, const std::vector< double > &rateFreqs, const std::string &suffix="", bool suffixIsOptional=true, bool verbose=true, int warn=1)
Get A FrequenciesSet object for root frequencies (NH models) according to options.
static void setSubstitutionModelParametersInitialValuesWithAliases(SubstitutionModel &model, std::map< std::string, std::string > &unparsedParameterValues, size_t modelNumber, const SiteContainer *data, std::map< std::string, double > &existingParams, std::map< std::string, std::string > &sharedParams, bool verbose)
Set parameter initial values of a given model in a set according to options.
SubstitutionModel * read(const Alphabet *alphabet, const std::string &modelDescription, const SiteContainer *data=0, bool parseArguments=true)
Read a substitution model from a string.
const std::vector< int > & getNodesWithModel(size_t i) const
Get a list of nodes id for which the given model is associated.
static void checkEstimatedParameters(const ParameterList &pl)
Check if parameter values are close to their definition boundary.
void setGeneticCode(const GeneticCode *gCode)
Set the genetic code to use in case a codon frequencies set should be built.
Naive substitution count.
A frequencies set used to estimate frequencies at the root with the COaLA model. Frequencies at the r...
static std::string OPTIMIZATION_BFGS
Laplace estimate of the substitution count.
static DiscreteDistribution * getRateDistribution(std::map< std::string, std::string > &params, const std::string &suffix="", bool suffixIsOptional=true, bool verbose=true)
Build a DiscreteDistribution object according to options.
static unsigned int optimizeTreeScale(TreeLikelihood *tl, double tolerance=0.000001, unsigned int tlEvalMax=1000000, OutputStream *messageHandler=ApplicationTools::message, OutputStream *profiler=ApplicationTools::message, unsigned int verbose=1)
Optimize the scale of a TreeLikelihood.
static SubstitutionCount * getSubstitutionCount(const Alphabet *alphabet, const SubstitutionModel *model, map< string, string > &params, string suffix="", bool verbose=true, int warn=1)
Get a SubstitutionCount instance.
static std::string OPTIMIZATION_NEWTON
static unsigned int optimizeNumericalParametersWithGlobalClock(DiscreteRatesAcrossSitesClockTreeLikelihood *cl, const ParameterList &parameters, OptimizationListener *listener=0, unsigned int nstep=1, double tolerance=0.000001, unsigned int tlEvalMax=1000000, OutputStream *messageHandler=ApplicationTools::message, OutputStream *profiler=ApplicationTools::message, unsigned int verbose=1, const std::string &optMethodDeriv=OPTIMIZATION_GRADIENT)
Optimize numerical parameters assuming a global clock (branch heights, substitution model & rate dist...
Interface for Substitution models, defined as a mixture of "simple" substitution models.