bpp-phyl3 3.0.0
SubstitutionModelSetTools.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: The Bio++ Development Group
2//
3// SPDX-License-Identifier: CECILL-2.1
4
5#include "../../Model/MixedTransitionModel.h"
8
9using namespace bpp;
10
11using namespace std;
12
13unique_ptr<SubstitutionModelSet> SubstitutionModelSetTools::createHomogeneousModelSet(
14 shared_ptr<TransitionModelInterface> model,
15 shared_ptr<FrequencySetInterface> rootFreqs,
16 const Tree& tree
17 )
18{
19 // Check alphabet:
20 if (model->getAlphabet()->getAlphabetType() != rootFreqs->getAlphabet()->getAlphabetType())
21 throw AlphabetMismatchException("SubstitutionModelSetTools::createHomogeneousModelSet()", model->getAlphabet(), rootFreqs->getAlphabet());
22 if (dynamic_cast<MixedTransitionModelInterface*>(model.get()) != nullptr)
23 throw Exception("createHomogeneousModelSet non yet programmed for mixture models.");
24
25 auto modelSet = make_unique<SubstitutionModelSet>(model->getAlphabet());
26
27 modelSet->setRootFrequencies(rootFreqs);
28 // We assign this model to all nodes in the tree (excepted root node), and link all parameters with it.
29 vector<int> ids = tree.getNodesId();
30 int rootId = tree.getRootId();
31 unsigned int pos = 0;
32 for (unsigned int i = 0; i < ids.size(); ++i)
33 {
34 if (ids[i] == rootId)
35 {
36 pos = i;
37 break;
38 }
39 }
40 ids.erase(ids.begin() + pos);
41 modelSet->addModel(model, ids);
42
43 return modelSet;
44}
45
47 shared_ptr<TransitionModelInterface> model,
48 shared_ptr<FrequencySetInterface> rootFreqs,
49 const Tree& tree,
50 const map<string, string>& aliasFreqNames,
51 const map<string, vector<Vint>>& globalParameterNames
52 )
53{
54 // Check alphabet:
55 if (rootFreqs && model->alphabet().getAlphabetType() != rootFreqs->alphabet().getAlphabetType())
56 throw AlphabetMismatchException("SubstitutionModelSetTools::createNonHomogeneousModelSet()", model->getAlphabet(), rootFreqs->getAlphabet());
57 ParameterList globalParameters;
58 globalParameters = model->getParameters();
59
60 vector<string> modelParamNames = globalParameters.getParameterNames();
61
62 map<string, vector<Vint>> globalParameterNames2;
63
64 // First get correct parameter names
65
66 for (const auto& name : globalParameterNames)
67 {
68 vector<string> complName = ApplicationTools::matchingParameters(name.first, modelParamNames);
69
70 if (complName.size() == 0)
71 throw Exception("SubstitutionModelSetTools::createNonHomogeneousModelSet. Parameter '" + name.first + "' is not valid.");
72 else
73 for (auto& cni : complName)
74 {
75 globalParameterNames2[cni] = name.second;
76 }
77 }
78
79 auto modelSet = make_unique<SubstitutionModelSet>(model->getAlphabet());
80
81 if (rootFreqs)
82 modelSet->setRootFrequencies(rootFreqs);
83
84 // We assign a copy of this model to all nodes in the tree (excepted root node), and link all parameters with it.
85 vector<int> ids = tree.getNodesId();
86 int rootId = tree.getRootId();
87 size_t pos = 0;
88 for (size_t i = 0; i < ids.size(); ++i)
89 {
90 if (ids[i] == rootId)
91 {
92 pos = i;
93 break;
94 }
95 }
96
97 ids.erase(ids.begin() + static_cast<ptrdiff_t>(pos));
98 for (size_t i = 0; i < ids.size(); ++i)
99 {
100 modelSet->addModel(shared_ptr<TransitionModelInterface>(model->clone()), vector<int>(1, ids[i]));
101 }
102
103 // Now alias all global parameters on all nodes:
104 for (size_t nn = 0; nn < globalParameters.size(); ++nn)
105 {
106 const Parameter& param = globalParameters[nn];
107
108 string pname = param.getName();
109
110 if (globalParameterNames2.find(pname) != globalParameterNames2.end())
111 {
112 const vector<Vint>& vvids(globalParameterNames2[pname]);
113
114 if (vvids.size() == 0)
115 {
116 size_t fmid = modelSet->getModelIndexForNode(ids[0]) + 1;
117 for (size_t i = 1; i < ids.size(); ++i)
118 {
119 modelSet->aliasParameters(pname + "_" + TextTools::toString(fmid), pname + "_" + TextTools::toString(modelSet->getModelIndexForNode(ids[i]) + 1));
120 }
121 }
122 else
123 for (const auto& vids : vvids)
124 {
125 size_t fmid = modelSet->getModelIndexForNode(vids[0] + 1);
126 for (size_t i = 1; i < vids.size(); i++)
127 {
128 modelSet->aliasParameters(pname + "_" + TextTools::toString(fmid), pname + "_" + TextTools::toString(modelSet->getModelIndexForNode(vids[i]) + 1));
129 }
130 }
131 }
132 }
133
134 // and alias on the root
135 for (auto& it : aliasFreqNames)
136 {
137 if (globalParameterNames2.find(it.second) != globalParameterNames2.end())
138 modelSet->aliasParameters(it.second + "_1", it.first);
139 }
140
141 return modelSet;
142}
static std::vector< std::string > matchingParameters(const std::string &pattern, const std::map< std::string, std::string > &params)
Interface for Transition models, defined as a mixture of "simple" transition models.
size_t size() const
virtual std::vector< std::string > getParameterNames() const
virtual const std::string & getName() const
static std::unique_ptr< SubstitutionModelSet > createNonHomogeneousModelSet(std::shared_ptr< TransitionModelInterface > model, std::shared_ptr< FrequencySetInterface > rootFreqs, const Tree &tree, const std::map< std::string, std::string > &aliasFreqNames, const std::map< std::string, std::vector< Vint > > &globalParameterNames)
Create a SubstitutionModelSet object, with one model per branch.
Interface for phylogenetic tree objects.
Definition: Tree.h:115
virtual std::vector< int > getNodesId() const =0
virtual int getRootId() const =0
std::string toString(T t)
Defines the basic types of data flow nodes.