bpp-phyl  2.2.0
SubstitutionModelSetTools.cpp
Go to the documentation of this file.
1 //
2 // File: SubstitutionModelSetTools.cpp
3 // Created by: Julien Dutheil
4 // Created on: tue Sep 17 16:57 2007
5 //
6 
7 /*
8  Copyright or © or Copr. CNRS, (November 16, 2004)
9 
10  This software is a computer program whose purpose is to provide classes
11  for phylogenetic data analysis.
12 
13  This software is governed by the CeCILL license under French law and
14  abiding by the rules of distribution of free software. You can use,
15  modify and/ or redistribute the software under the terms of the CeCILL
16  license as circulated by CEA, CNRS and INRIA at the following URL
17  "http://www.cecill.info".
18 
19  As a counterpart to the access to the source code and rights to copy,
20  modify and redistribute granted by the license, users are provided only
21  with a limited warranty and the software's author, the holder of the
22  economic rights, and the successive licensors have only limited
23  liability.
24 
25  In this respect, the user's attention is drawn to the risks associated
26  with loading, using, modifying and/or developing or reproducing the
27  software by the user in light of its specific status of free software,
28  that may mean that it is complicated to manipulate, and that also
29  therefore means that it is reserved for developers and experienced
30  professionals having in-depth computer knowledge. Users are therefore
31  encouraged to load and test the software's suitability as regards their
32  requirements in conditions enabling the security of their systems and/or
33  data to be ensured and, more generally, to use and operate it in the
34  same conditions as regards security.
35 
36  The fact that you are presently reading this means that you have had
37  knowledge of the CeCILL license and that you accept its terms.
38  */
39 
42 #include "MixedSubstitutionModel.h"
43 
44 using namespace bpp;
45 
46 using namespace std;
47 
49  SubstitutionModel* model,
50  FrequenciesSet* rootFreqs,
51  const Tree* tree
52  ) throw (AlphabetException, Exception)
53 {
54  // Check alphabet:
55  if (model->getAlphabet()->getAlphabetType() != rootFreqs->getAlphabet()->getAlphabetType())
56  throw AlphabetMismatchException("SubstitutionModelSetTools::createHomogeneousModelSet()", model->getAlphabet(), rootFreqs->getAlphabet());
57  if (dynamic_cast<MixedSubstitutionModel*>(model) != NULL)
58  throw Exception("createHomogeneousModelSet non yet programmed for mixture models.");
59 
60  SubstitutionModelSet* modelSet = new SubstitutionModelSet(model->getAlphabet());
61 
62  modelSet->setRootFrequencies(rootFreqs);
63  // We assign this model to all nodes in the tree (excepted root node), and link all parameters with it.
64  vector<int> ids = tree->getNodesId();
65  int rootId = tree->getRootId();
66  unsigned int pos = 0;
67  for (unsigned int i = 0; i < ids.size(); i++)
68  {
69  if (ids[i] == rootId)
70  {
71  pos = i;
72  break;
73  }
74  }
75  ids.erase(ids.begin() + pos);
76  modelSet->addModel(model, ids);
77 
78  return modelSet;
79 }
80 
82  SubstitutionModel* model,
83  FrequenciesSet* rootFreqs,
84  const Tree* tree,
85  const vector<string>& globalParameterNames
86  ) throw (AlphabetException, Exception)
87 {
88  // Check alphabet:
89  if (rootFreqs && model->getAlphabet()->getAlphabetType() != rootFreqs->getAlphabet()->getAlphabetType())
90  throw AlphabetMismatchException("SubstitutionModelSetTools::createNonHomogeneousModelSet()", model->getAlphabet(), rootFreqs->getAlphabet());
91  ParameterList globalParameters, branchParameters;
92  globalParameters = model->getParameters();
93 
94  vector<string> globalParameterNames2; // vector of the complete names of global parameters
95 
96  // First get correct parameter names
97  size_t i, j;
98 
99  for (i = 0; i < globalParameterNames.size(); i++)
100  {
101  if (globalParameterNames[i].find("*") != string::npos)
102  {
103  for (j = 0; j < globalParameters.size(); j++)
104  {
105  StringTokenizer stj(globalParameterNames[i], "*", true, false);
106  size_t pos1, pos2;
107  string parn = globalParameters[j].getName();
108  bool flag(true);
109  string g = stj.nextToken();
110  pos1 = parn.find(g);
111  if (pos1 != 0)
112  flag = false;
113  pos1 += g.length();
114  while (flag && stj.hasMoreToken())
115  {
116  g = stj.nextToken();
117  pos2 = parn.find(g, pos1);
118  if (pos2 == string::npos)
119  {
120  flag = false;
121  break;
122  }
123  pos1 = pos2 + g.length();
124  }
125  if (flag &&
126  ((g.length() == 0) || (pos1 == parn.length()) || (parn.rfind(g) == parn.length() - g.length())))
127  globalParameterNames2.push_back(parn);
128  }
129  }
130  else if (!globalParameters.hasParameter(globalParameterNames[i]))
131  throw Exception("SubstitutionModelSetTools::createNonHomogeneousModelSet. Parameter '" + globalParameterNames[i] + "' is not valid.");
132  else
133  globalParameterNames2.push_back(globalParameterNames[i]);
134  }
135 
136  // remove non global parameters
137  for (i = globalParameters.size(); i > 0; i--)
138  {
139  if (find(globalParameterNames2.begin(), globalParameterNames2.end(), globalParameters[i - 1].getName()) == globalParameterNames2.end())
140  {
141  // not a global parameter:
142  branchParameters.addParameter(globalParameters[i - 1]);
143  globalParameters.deleteParameter(i - 1);
144  }
145  }
146 
147  bool mixed = (dynamic_cast<MixedSubstitutionModel*>(model) != NULL);
148  SubstitutionModelSet* modelSet;
149  if (mixed)
150  {
151  modelSet = new MixedSubstitutionModelSet(model->getAlphabet());
152  // Remove the "relproba" parameters from the branch parameters and put them in the global parameters, for the hypernodes
153  for (i = branchParameters.size(); i > 0; i--)
154  {
155  if (branchParameters[i - 1].getName().find("relproba") != string::npos)
156  {
157  globalParameters.addParameter(branchParameters[i - 1]);
158  branchParameters.deleteParameter(i - 1);
159  }
160  }
161  }
162  else
163  modelSet = new SubstitutionModelSet(model->getAlphabet());
164 
165  if (rootFreqs)
166  modelSet->setRootFrequencies(rootFreqs);
167 
168  // We assign a copy of this model to all nodes in the tree (excepted root node), and link all parameters with it.
169  vector<int> ids = tree->getNodesId();
170  int rootId = tree->getRootId();
171  size_t pos = 0;
172  for (i = 0; i < ids.size(); i++)
173  {
174  if (ids[i] == rootId)
175  {
176  pos = i;
177  break;
178  }
179  }
180 
181  ids.erase(ids.begin() + static_cast<ptrdiff_t>(pos));
182  for (i = 0; i < ids.size(); i++)
183  {
184  modelSet->addModel(dynamic_cast<SubstitutionModel*>(model->clone()), vector<int>(1, ids[i]));
185  }
186 
187  // Now alias all global parameters on all nodes:
188  for (i=0; i < globalParameters.size(); i++)
189  {
190  string pname=globalParameters[i].getName();
191 
192  for (size_t nn = 1; nn < ids.size(); nn++)
193  modelSet->aliasParameters(pname+"_1",pname+"_"+TextTools::toString(nn+1));
194  }
195 
196  // Defines the hypernodes if mixed
197  if (mixed)
198  {
199  MixedSubstitutionModelSet* pMSMS = dynamic_cast<MixedSubstitutionModelSet*>(modelSet);
200  MixedSubstitutionModel* pMSM = dynamic_cast<MixedSubstitutionModel*>(model);
201 
202  size_t nbm = pMSM->getNumberOfModels();
203  for (i = 0; i < nbm; i++)
204  {
205  pMSMS->addEmptyHyperNode();
206  for (j = 0; j < ids.size(); j++)
207  {
208  pMSMS->addToHyperNode(j, vector<int>(1, static_cast<int>(i)));
209  }
210  }
212  }
213 
214  delete model; // delete template model.
215  return modelSet;
216 }
217 
Substitution models manager for non-homogeneous / non-reversible models of evolution.
Interface for all substitution models.
void setRootFrequencies(FrequenciesSet *rootFreqs)
Sets a given FrequenciesSet for root frequencies.
STL namespace.
Interface for phylogenetic tree objects.
Definition: Tree.h:148
Parametrize a set of state frequencies.
static SubstitutionModelSet * createNonHomogeneousModelSet(SubstitutionModel *model, FrequenciesSet *rootFreqs, const Tree *tree, const std::vector< std::string > &globalParameterNames)
Create a SubstitutionModelSet object, with one model per branch.
void addModel(SubstitutionModel *model, const std::vector< int > &nodesId)
Add a new model to the set, and set relationships with nodes and params.
void addToHyperNode(size_t nM, const Vint &vnS, int nH=-1)
Substitution models manager for Mixed Substitution Models. This class inherits from SubstitutionModel...
virtual size_t getNumberOfModels() const =0
static SubstitutionModelSet * createHomogeneousModelSet(SubstitutionModel *model, FrequenciesSet *rootFreqs, const Tree *tree)
Create a SubstitutionModelSet object, corresponding to the homogeneous case.
Interface for Substitution models, defined as a mixture of "simple" substitution models.