Beispiel #1
0
void Alignment::set_parameter(string name, double value) {
    ParameterList pl;
    enum class THING{LIKELIHOOD, RATES, MODEL};  // The 'thing' to update after setting parameter
    THING thing;
    if (likelihood) {
        pl = likelihood->getParameters();
        thing = THING::LIKELIHOOD;
    }
    else if (rates) {
        pl = rates->getIndependentParameters();
        thing = THING::RATES;
    }
    else if (model) {
        pl = model->getIndependentParameters();
        thing = THING::MODEL;
    }
    else {
        throw Exception("Could not retrieve parameter list");
    }
    if (pl.hasParameter(name)) {
        pl.setParameterValue(name, value);
        switch (thing) {
        case THING::LIKELIHOOD:
            likelihood->setParametersValues(pl);
            break;

        case THING::RATES:
            rates->setParametersValues(pl);
            rates->fireParameterChanged(pl);
            break;

        case THING::MODEL:
            model->setParametersValues(pl);
            model->fireParameterChanged(pl);
            break;
        }
    }
    else {
        throw Exception("Could not find that parameter");
    }
}
Beispiel #2
0
double Alignment::get_parameter(string name) {
    ParameterList pl;
    if (likelihood) {
        pl = likelihood->getParameters();
    }
    else if (rates) {
        pl = rates->getIndependentParameters();
    }
    else if (model) {
        pl = model->getIndependentParameters();
    }
    else {
        throw Exception("Could not retrieve parameter list");
    }
    if (pl.hasParameter(name)) {
        return pl.getParameterValue(name);
    }
    else {
        throw Exception("Could not find that parameter");
    }
}
void ThreePointsNumericalDerivative::updateDerivatives(const ParameterList & parameters)
throw (ParameterNotFoundException, ConstraintException)
{
  if(computeD1_ && variables_.size() > 0)
  {
    if(function1_) function1_->enableFirstOrderDerivatives(false);
    if(function2_) function2_->enableSecondOrderDerivatives(false);
    function_->setParameters(parameters);
    f2_ = function_->getValue();
    string lastVar;
    ParameterList p;
    for(unsigned int i = 0; i < variables_.size(); i++)
    {
      string var = variables_[i];
      if (!parameters.hasParameter(var)) continue;
      if(i > 0)
      {
        vector<string> vars(2);
        vars[0] = var;
        vars[1] = lastVar;
        p = parameters.subList(vars);
      }
      else
      {
        p = parameters.subList(var);
      }
      lastVar = var;
      double value = function_->getParameterValue(var);
      double h = (1. + std::abs(value)) * h_; 
      //Compute one other point:
      try
      {
        p[0]->setValue(value - h);
        function_->setParameters(p); //also reset previous parameter...
        p = p.subList(0);
        f1_ = function_->getValue();
        try
        {
          p[0]->setValue(value + h);
          function_->setParameters(p);
          f3_ = function_->getValue();
          //No limit raised, use central approximation:
          der1_[i] = (-f1_ + f3_) / (2.*h);
          der2_[i] = (f1_ -2*f2_ + f3_) / (h*h);
        }
        catch(ConstraintException & ce)
        {
          //Right limit raised, use backward approximation:
          p[0]->setValue(value - h);
          function_->setParameters(p);
          f1_ = function_->getValue();
          p[0]->setValue(value - 2*h);
          function_->setParameters(p);
          f3_ = function_->getValue();
          der1_[i] = (f2_ - f1_) / h;
          der2_[i] = (f2_ - 2.*f1_ + f3_) / (h*h);        
        }
      }
      catch(ConstraintException & ce)
      {
        //Left limit raised, use forward approximation:
        p[0]->setValue(value + h);
        function_->setParameters(p);
        f3_ = function_->getValue();
        p[0]->setValue(value + 2*h);
        function_->setParameters(p);
        f1_ = function_->getValue();
        der1_[i] = (f3_ - f2_) / h;
        der2_[i] = (f1_ - 2.*f3_ + f2_) / (h*h);
      }
    }

    if(computeCrossD2_)
    {
      string lastVar1, lastVar2;
      for(unsigned int i = 0; i < variables_.size(); i++)
      {
        string var1 = variables_[i];
        if(!parameters.hasParameter(var1)) continue;
        for(unsigned int j = 0; j < variables_.size(); j++)
        {
          if(j==i)
          {
            crossDer2_(i,j) = der2_[i];
            continue;
          }
          string var2 = variables_[j];
          if (!parameters.hasParameter(var2)) continue;
        
          vector<string> vars(2);
          vars[0] = var1;
          vars[1] = var2;
          if(i > 0 && j > 0)
          {
            if(lastVar1 != var1 && lastVar1 != var2) vars.push_back(lastVar1);
            if(lastVar2 != var1 && lastVar2 != var2) vars.push_back(lastVar2);
          }
          p = parameters.subList(vars);
        
          double value1 = function_->getParameterValue(var1);
          double value2 = function_->getParameterValue(var2);
          double h1 = (1. + std::abs(value1)) * h_; 
          double h2 = (1. + std::abs(value2)) * h_; 
        
          //Compute 4 additional points:
          try
          {
            p[0]->setValue(value1 - h1);
            p[1]->setValue(value2 - h2);
            function_->setParameters(p); //also reset previous parameter...
            vector<unsigned int> tmp(2);
            tmp[0] = 0;
            tmp[1] = 1;
            p = p.subList(tmp); //removed the previous parameters.
            f11_ = function_->getValue();

            p[1]->setValue(value2 + h2);
            function_->setParameters(p.subList(1));
            f12_ = function_->getValue();

            p[0]->setValue(value1 + h1);
            function_->setParameters(p.subList(0));
            f22_ = function_->getValue();

            p[1]->setValue(value2 - h2);
            function_->setParameters(p.subList(1));
            f21_ = function_->getValue();

            crossDer2_(i,j) = ((f22_ - f21_) - (f12_ - f11_)) / (4 * h1 * h2);
          }
          catch(ConstraintException & ce)
          {
            throw Exception("ThreePointsNumericalDerivative::setParameters. Could not compute cross derivatives at limit.");
          }

          lastVar1 = var1;
          lastVar2 = var2;
        }
      }
    }
   
    //Reset last parameter and compute analytical derivatives if any.
    if(function1_) function1_->enableFirstOrderDerivatives(computeD1_);
    if(function2_) function2_->enableSecondOrderDerivatives(computeD2_);
    function_->setParameters(parameters.subList(lastVar));
  }
  else
  {
    //Reset initial value and compute analytical derivatives if any.
    if(function1_) function1_->enableFirstOrderDerivatives(computeD1_);
    if(function2_) function2_->enableSecondOrderDerivatives(computeD2_);
    function_->setParameters(parameters);
    //Just in case derivatives are not computed:
    f2_ = function_->getValue();
  }
}
void ThreePointsNumericalDerivative::updateDerivatives(const ParameterList parameters)
throw (ParameterNotFoundException, ConstraintException)
{
  if (computeD1_ && variables_.size() > 0)
  {
    if (function1_)
      function1_->enableFirstOrderDerivatives(false);
    if (function2_)
      function2_->enableSecondOrderDerivatives(false);
    function_->setParameters(parameters);
    f2_ = function_->getValue();
    if ((abs(f2_) >= NumConstants::VERY_BIG()) || std::isnan(f2_))
    {
      for (size_t i = 0; i < variables_.size(); ++i)
      {
        der1_[i] = log(-1);
        der2_[i] = log(-1);
      }
      return;
    }

    string lastVar;
    bool functionChanged = false;
    ParameterList p;
    bool start = true;
    for (size_t i = 0; i < variables_.size(); ++i)
    {
      string var = variables_[i];
      if (!parameters.hasParameter(var))
        continue;
      if (!start)
      {
        vector<string> vars(2);
        vars[0] = var;
        vars[1] = lastVar;
        p = parameters.subList(vars);
      }
      else
      {
        p = parameters.subList(var);
        start = false;
      }
      lastVar = var;
      functionChanged = true;
      double value = function_->getParameterValue(var);
      double h = -(1. + std::abs(value)) * h_;
      if (abs(h) < p[0].getPrecision())
        h = h < 0 ? -p[0].getPrecision() : p[0].getPrecision();
      double hf1(0), hf3(0);
      unsigned int nbtry = 0;

      // Compute f1_
      while (hf1 == 0)
      {
        try
        {
          p[0].setValue(value + h);
          function_->setParameters(p); // also reset previous parameter...

          p = p.subList(0);
          f1_ = function_->getValue();
          if ((abs(f1_) >= NumConstants::VERY_BIG()) || std::isnan(f1_))
            throw ConstraintException("f1_ too large", &p[0], f1_);
          else
            hf1 = h;
        }
        catch (ConstraintException& ce)
        {
          if (++nbtry == 10) // no possibility to compute derivatives
            break;
          else if (h < 0)
            h = -h;  // try on the right
          else
            h /= -2;  // try again on the left with smaller interval
        }
      }

      if (hf1 != 0)
      {
        // Compute f3_
        if (h < 0)
          h = -h;  // on the right
        else
          h /= 2;  //  on the left with smaller interval

        nbtry = 0;
        while (hf3 == 0)
        {
          try
          {
            p[0].setValue(value + h);
            function_->setParameters(p); // also reset previous parameter...

            p = p.subList(0);
            f3_ = function_->getValue();
            if ((abs(f3_) >= NumConstants::VERY_BIG()) || std::isnan(f3_))
              throw ConstraintException("f3_ too large", &p[0], f3_);
            else
              hf3 = h;
          }
          catch (ConstraintException& ce)
          {
            if (++nbtry == 10) // no possibility to compute derivatives
              break;
            else if (h < 0)
              h = -h;  // try on the right
            else
              h /= -2;  // try again on the left with smaller interval
          }
        }
      }

      if (hf3 == 0)
      {
        der1_[i] = log(-1);
        der2_[i] = log(-1);
      }
      else
      {
        der1_[i] = (f1_ - f3_) / (hf1 - hf3);
        der2_[i] = ((f1_ - f2_) / hf1 - (f3_ - f2_) / hf3) * 2 / (hf1 - hf3);
      }
    }


    if (computeCrossD2_)
    {
      string lastVar1, lastVar2;
      for (unsigned int i = 0; i < variables_.size(); i++)
      {
        string var1 = variables_[i];
        if (!parameters.hasParameter(var1))
          continue;
        for (unsigned int j = 0; j < variables_.size(); j++)
        {
          if (j == i)
          {
            crossDer2_(i, j) = der2_[i];
            continue;
          }
          string var2 = variables_[j];
          if (!parameters.hasParameter(var2))
            continue;

          vector<string> vars(2);
          vars[0] = var1;
          vars[1] = var2;
          if (i > 0 && j > 0)
          {
            if (lastVar1 != var1 && lastVar1 != var2)
              vars.push_back(lastVar1);
            if (lastVar2 != var1 && lastVar2 != var2)
              vars.push_back(lastVar2);
          }
          p = parameters.subList(vars);

          double value1 = function_->getParameterValue(var1);
          double value2 = function_->getParameterValue(var2);
          double h1 = (1. + std::abs(value1)) * h_;
          double h2 = (1. + std::abs(value2)) * h_;

          // Compute 4 additional points:
          try
          {
            p[0].setValue(value1 - h1);
            p[1].setValue(value2 - h2);
            function_->setParameters(p); // also reset previous parameter...
            vector<size_t> tmp(2);
            tmp[0] = 0;
            tmp[1] = 1;
            p = p.subList(tmp); // removed the previous parameters.
            f11_ = function_->getValue();

            p[1].setValue(value2 + h2);
            function_->setParameters(p.subList(1));
            f12_ = function_->getValue();

            p[0].setValue(value1 + h1);
            function_->setParameters(p.subList(0));
            f22_ = function_->getValue();

            p[1].setValue(value2 - h2);
            function_->setParameters(p.subList(1));
            f21_ = function_->getValue();

            crossDer2_(i, j) = ((f22_ - f21_) - (f12_ - f11_)) / (4 * h1 * h2);
          }
          catch (ConstraintException& ce)
          {
            throw Exception("ThreePointsNumericalDerivative::setParameters. Could not compute cross derivatives at limit.");
          }

          lastVar1 = var1;
          lastVar2 = var2;
        }
      }
    }

    // Reset last parameter and compute analytical derivatives if any.
    if (function1_)
      function1_->enableFirstOrderDerivatives(computeD1_);
    if (function2_)
      function2_->enableSecondOrderDerivatives(computeD2_);
    if (functionChanged)
      function_->setParameters(parameters.subList(lastVar));
  }
  else
  {
    // Reset initial value and compute analytical derivatives if any.
    if (function1_)
      function1_->enableFirstOrderDerivatives(computeD1_);
    if (function2_)
      function2_->enableSecondOrderDerivatives(computeD2_);
    function_->setParameters(parameters);
    // Just in case derivatives are not computed:
    f2_ = function_->getValue();
  }
}
void TwoPointsNumericalDerivative::updateDerivatives(const ParameterList parameters)
throw (ParameterNotFoundException, ConstraintException)
{
  if (computeD1_ && variables_.size() > 0)
  {
    if (function1_)
      function1_->enableFirstOrderDerivatives(false);
    if (function2_)
      function2_->enableSecondOrderDerivatives(false);
    function_->setParameters(parameters);
    f1_ = function_->getValue();
    string lastVar;
    bool functionChanged = false;
    bool start = true;
    for (unsigned int i = 0; i < variables_.size(); i++)
    {
      string var = variables_[i];
      if (!parameters.hasParameter(var))
        continue;
      ParameterList p;
      if (!start)
      {
        vector<string> vars(2);
        vars[0] = var;
        vars[1] = lastVar;
        lastVar = var;
        functionChanged = true;
        p = parameters.subList(vars);
      }
      else
      {
        p = parameters.subList(var);
        lastVar = var;
        functionChanged = true;
        start = false;
      }
      double value = function_->getParameterValue(var);
      double h = (1 + std::abs(value)) * h_;
      // Compute one other point:
      try
      {
        p[0].setValue(value + h);
        function_->setParameters(p);
        f2_ = function_->getValue();
      }
      catch (ConstraintException& ce1)
      {
        // Right limit raised, use backward approximation:
        try
        {
          p[0].setValue(value - h);
          function_->setParameters(p);
          f2_ = function_->getValue();
          der1_[i] = (f1_ - f2_) / h;
        }
        catch (ConstraintException& ce2)
        {
          // PB: can't compute derivative, because of a two narrow interval (lower than h)
          throw ce2;
        }
      }
      // No limit raised, use forward approximation:
      der1_[i] = (f2_ - f1_) / h;
    }
    // Reset last parameter and compute analytical derivatives if any:
    if (function1_)
      function1_->enableFirstOrderDerivatives(computeD1_);
    if (functionChanged)
      function_->setParameters(parameters.subList(lastVar));
  }
  else
  {
    // Reset initial value and compute analytical derivatives if any.
    if (function1_)
      function1_->enableFirstOrderDerivatives(computeD1_);
    if (function2_)
      function2_->enableSecondOrderDerivatives(computeD2_);
    // Just in case derivatives are not computed:
    function_->setParameters(parameters);
    f1_ = function_->getValue();
  }
}
Beispiel #6
0
int main(int args, char ** argv)
{
  cout << "******************************************************************" << endl;
  cout << "*              Bio++ Distance Methods, version 2.2.0             *" << endl;
  cout << "* Author: J. Dutheil                        Created     05/05/07 *" << endl;
  cout << "*                                           Last Modif. 04/02/15 *" << endl;
  cout << "******************************************************************" << endl;
  cout << endl;

  if(args == 1)
  {
    help();
    return 0;
  }
  
  try {

  BppApplication bppdist(args, argv, "BppDist");
  bppdist.startTimer();

  Alphabet* alphabet = SequenceApplicationTools::getAlphabet(bppdist.getParams(), "", false);
  auto_ptr<GeneticCode> gCode;
  CodonAlphabet* codonAlphabet = dynamic_cast<CodonAlphabet*>(alphabet);
  if (codonAlphabet) {
    string codeDesc = ApplicationTools::getStringParameter("genetic_code", bppdist.getParams(), "Standard", "", true, true);
    ApplicationTools::displayResult("Genetic Code", codeDesc);

    gCode.reset(SequenceApplicationTools::getGeneticCode(codonAlphabet->getNucleicAlphabet(), codeDesc));
  }

  VectorSiteContainer* allSites = SequenceApplicationTools::getSiteContainer(alphabet, bppdist.getParams());
  
  VectorSiteContainer* sites = SequenceApplicationTools::getSitesToAnalyse(* allSites, bppdist.getParams());
  delete allSites;

  ApplicationTools::displayResult("Number of sequences", TextTools::toString(sites->getNumberOfSequences()));
  ApplicationTools::displayResult("Number of sites", TextTools::toString(sites->getNumberOfSites()));
  
  SubstitutionModel* model = PhylogeneticsApplicationTools::getSubstitutionModel(alphabet, gCode.get(), sites, bppdist.getParams());
  
	DiscreteDistribution* rDist = 0;
  if (model->getNumberOfStates() > model->getAlphabet()->getSize())
  {
    //Markov-modulated Markov model!
    rDist = new ConstantRateDistribution();
  }
  else
  {
	  rDist = PhylogeneticsApplicationTools::getRateDistribution(bppdist.getParams());
  }
   
  DistanceEstimation distEstimation(model, rDist, sites, 1, false);
 
  string method = ApplicationTools::getStringParameter("method", bppdist.getParams(), "nj");
  ApplicationTools::displayResult("Tree reconstruction method", method);
  TreeTemplate<Node>* tree;
  AgglomerativeDistanceMethod* distMethod = 0;
  if(method == "wpgma")
  {
    PGMA* wpgma = new PGMA(true);
    distMethod = wpgma;
  }
  else if(method == "upgma")
  {
    PGMA* upgma = new PGMA(false);
    distMethod = upgma;
  }
  else if(method == "nj")
  {
    NeighborJoining* nj = new NeighborJoining();
    nj->outputPositiveLengths(true);
    distMethod = nj;
  }
  else if(method == "bionj")
  {
    BioNJ* bionj = new BioNJ();
    bionj->outputPositiveLengths(true);
    distMethod = bionj;
  }
  else throw Exception("Unknown tree reconstruction method.");
  
  string type = ApplicationTools::getStringParameter("optimization.method", bppdist.getParams(), "init");
  ApplicationTools::displayResult("Model parameters estimation method", type);
  if (type == "init") type = OptimizationTools::DISTANCEMETHOD_INIT;
  else if (type == "pairwise") type = OptimizationTools::DISTANCEMETHOD_PAIRWISE;
  else if (type == "iterations") type = OptimizationTools::DISTANCEMETHOD_ITERATIONS;
  else throw Exception("Unknown parameter estimation procedure '" + type + "'.");
  
	unsigned int optVerbose = ApplicationTools::getParameter<unsigned int>("optimization.verbose", bppdist.getParams(), 2);
	
	string mhPath = ApplicationTools::getAFilePath("optimization.message_handler", bppdist.getParams(), false, false);
	OutputStream* messenger = 
		(mhPath == "none") ? 0 :
			(mhPath == "std") ? ApplicationTools::message :
				new StlOutputStream(new ofstream(mhPath.c_str(), ios::out));
	ApplicationTools::displayResult("Message handler", mhPath);

	string prPath = ApplicationTools::getAFilePath("optimization.profiler", bppdist.getParams(), false, false);
	OutputStream* profiler = 
		(prPath == "none") ? 0 :
			(prPath == "std") ? ApplicationTools::message :
				new StlOutputStream(new ofstream(prPath.c_str(), ios::out));
	if(profiler) profiler->setPrecision(20);
	ApplicationTools::displayResult("Profiler", prPath);

	// Should I ignore some parameters?
  ParameterList allParameters = model->getParameters();
  allParameters.addParameters(rDist->getParameters());
	ParameterList parametersToIgnore;
  string paramListDesc = ApplicationTools::getStringParameter("optimization.ignore_parameter", bppdist.getParams(), "", "", true, false);
	bool ignoreBrLen = false;
  StringTokenizer st(paramListDesc, ",");
	while (st.hasMoreToken())
  {
		try
    {
      string param = st.nextToken();
      if (param == "BrLen")
        ignoreBrLen = true;
      else
      {
        if (allParameters.hasParameter(param))
        {
          Parameter* p = &allParameters.getParameter(param);
          parametersToIgnore.addParameter(*p);
        }
        else ApplicationTools::displayWarning("Parameter '" + param + "' not found."); 
      }
		} 
    catch (ParameterNotFoundException& pnfe)
    {
			ApplicationTools::displayError("Parameter '" + pnfe.getParameter() + "' not found, and so can't be ignored!");
		}
	}
	
	unsigned int nbEvalMax = ApplicationTools::getParameter<unsigned int>("optimization.max_number_f_eval", bppdist.getParams(), 1000000);
	ApplicationTools::displayResult("Max # ML evaluations", TextTools::toString(nbEvalMax));
	
	double tolerance = ApplicationTools::getDoubleParameter("optimization.tolerance", bppdist.getParams(), .000001);
	ApplicationTools::displayResult("Tolerance", TextTools::toString(tolerance));
	
  //Here it is:
  ofstream warn("warnings", ios::out);
  ApplicationTools::warning = new StlOutputStreamWrapper(&warn);
  tree = OptimizationTools::buildDistanceTree(distEstimation, *distMethod, parametersToIgnore, !ignoreBrLen, type, tolerance, nbEvalMax, profiler, messenger, optVerbose);
  warn.close();
  delete ApplicationTools::warning;
  ApplicationTools::warning = ApplicationTools::message;

  string matrixPath = ApplicationTools::getAFilePath("output.matrix.file", bppdist.getParams(), false, false, "", false);
  if (matrixPath != "none")
  {
    ApplicationTools::displayResult("Output matrix file", matrixPath);
    string matrixFormat = ApplicationTools::getAFilePath("output.matrix.format", bppdist.getParams(), false, false, "", false);
    string format = "";
    bool extended = false;
    std::map<std::string, std::string> unparsedArguments_;
    KeyvalTools::parseProcedure(matrixFormat, format, unparsedArguments_);
    if (unparsedArguments_.find("type") != unparsedArguments_.end())
    {
      if (unparsedArguments_["type"] == "extended")
      {
        extended = true;
      }     
      else if (unparsedArguments_["type"] == "classic")
        extended = false;
      else
        ApplicationTools::displayWarning("Argument '" +
                                         unparsedArguments_["type"] + "' for parameter 'Phylip#type' is unknown. " +
                                         "Default used instead: not extended.");
    }    
    else
      ApplicationTools::displayWarning("Argument 'Phylip#type' not found. Default used instead: not extended.");
    

    ODistanceMatrix* odm = IODistanceMatrixFactory().createWriter(IODistanceMatrixFactory::PHYLIP_FORMAT, extended);
    odm->write(*distEstimation.getMatrix(), matrixPath, true);
    delete odm;
  }
  PhylogeneticsApplicationTools::writeTree(*tree, bppdist.getParams());
  
  //Output some parameters:
  if (type == OptimizationTools::DISTANCEMETHOD_ITERATIONS)
  {
    // Write parameters to screen:
    ParameterList parameters = model->getParameters();
    for (unsigned int i = 0; i < parameters.size(); i++)
    {
		  ApplicationTools::displayResult(parameters[i].getName(), TextTools::toString(parameters[i].getValue()));
    }
    parameters = rDist->getParameters();
    for (unsigned int i = 0; i < parameters.size(); i++)
    {
		  ApplicationTools::displayResult(parameters[i].getName(), TextTools::toString(parameters[i].getValue()));
    }
    // Write parameters to file:
	  string parametersFile = ApplicationTools::getAFilePath("output.estimates", bppdist.getParams(), false, false);
    if (parametersFile != "none")
    {
		  ofstream out(parametersFile.c_str(), ios::out);
      parameters = model->getParameters();
      for (unsigned int i = 0; i < parameters.size(); i++)
      {
        out << parameters[i].getName() << " = " << parameters[i].getValue() << endl;
      }
      parameters = rDist->getParameters();
      for (unsigned int i = 0; i < parameters.size(); i++)
      {
        out << parameters[i].getName() << " = " << parameters[i].getValue() << endl;
      }
      out.close();
    }
  }
 
  //Bootstrap:
  unsigned int nbBS = ApplicationTools::getParameter<unsigned int>("bootstrap.number", bppdist.getParams(), 0);
  if(nbBS > 0)
  {
    ApplicationTools::displayResult("Number of bootstrap samples", TextTools::toString(nbBS));
    bool approx = ApplicationTools::getBooleanParameter("bootstrap.approximate", bppdist.getParams(), true);
    ApplicationTools::displayResult("Use approximate bootstrap", TextTools::toString(approx ? "yes" : "no"));
    if(approx)
    {
      type = OptimizationTools::DISTANCEMETHOD_INIT;
      parametersToIgnore = allParameters;
      ignoreBrLen = true;
    }
    bool bootstrapVerbose = ApplicationTools::getBooleanParameter("bootstrap.verbose", bppdist.getParams(), false, "", true, false);
 
    string bsTreesPath = ApplicationTools::getAFilePath("bootstrap.output.file", bppdist.getParams(), false, false);
    ofstream *out = NULL;
    if(bsTreesPath != "none")
    {
      ApplicationTools::displayResult("Bootstrap trees stored in file", bsTreesPath);
      out = new ofstream(bsTreesPath.c_str(), ios::out);
    }
    Newick newick;
    
    vector<Tree *> bsTrees(nbBS);
    ApplicationTools::displayTask("Bootstrapping", true);
    for(unsigned int i = 0; i < nbBS; i++)
    {
      ApplicationTools::displayGauge(i, nbBS-1, '=');
      VectorSiteContainer * sample = SiteContainerTools::bootstrapSites(*sites);
      if(approx) model->setFreqFromData(*sample);
      distEstimation.setData(sample);
      bsTrees[i] = OptimizationTools::buildDistanceTree(
          distEstimation,
          *distMethod,
          parametersToIgnore,
          ignoreBrLen,
          type,
          tolerance,
          nbEvalMax,
          NULL,
          NULL,
          (bootstrapVerbose ? 1 : 0)
        );
      if(out && i == 0) newick.write(*bsTrees[i], bsTreesPath, true);
      if(out && i >  0) newick.write(*bsTrees[i], bsTreesPath, false);
      delete sample;
    }
    if(out) out->close();
    if(out) delete out;
    ApplicationTools::displayTaskDone();
    ApplicationTools::displayTask("Compute bootstrap values");
    TreeTools::computeBootstrapValues(*tree, bsTrees);
    ApplicationTools::displayTaskDone();
    for(unsigned int i = 0; i < nbBS; i++) delete bsTrees[i];

    //Write resulting tree:
    PhylogeneticsApplicationTools::writeTree(*tree, bppdist.getParams());
  }
    
  delete alphabet;
  delete sites;
  delete distMethod;
  delete tree;

  bppdist.done();}
  
      
  catch(exception & e)
  {
    cout << e.what() << endl;
    return 1;
  }

  return 0;
}