bpp-popgen3  3.0.0
PolymorphismMultiGContainer.cpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: The Bio++ Development Group
2 //
3 // SPDX-License-Identifier: CECILL-2.1
4 
6 
7 using namespace bpp;
8 using namespace std;
9 
10 // ** Constructors : **********************************************************/
11 
13  multilocusGenotypes_(pmgc.size()),
14  groups_(pmgc.size()),
15  groupsNames_()
16 {
17  for (size_t i = 0; i < pmgc.size(); ++i)
18  {
19  multilocusGenotypes_[i].reset(pmgc.multilocusGenotype(i).clone());
20  groups_[i] = pmgc.getGroupId(i);
21  }
22  for (auto& id : pmgc.getAllGroupsIds())
23  {
24  string name = pmgc.getGroupName(id);
25  groupsNames_[id] = name;
26  }
27 }
28 
29 // ** Other methods: ********************************************************/
30 
32 {
33  clear();
34  for (size_t i = 0; i < pmgc.size(); ++i)
35  {
36  multilocusGenotypes_.push_back(make_unique<MultilocusGenotype>(pmgc.multilocusGenotype(i)));
37  groups_.push_back(pmgc.getGroupId(i));
38  }
39  for (auto& id : pmgc.getAllGroupsIds())
40  {
41  string name = pmgc.getGroupName(id);
42  groupsNames_[id] = name;
43  }
44 
45  return *this;
46 }
47 
48 /******************************************************************************/
49 
50 void PolymorphismMultiGContainer::addMultilocusGenotype(unique_ptr<MultilocusGenotype>& mg, size_t group)
51 {
52  multilocusGenotypes_.push_back(std::move(mg));
53  groups_.push_back(group);
54  auto it = groupsNames_.find(group);
55  if (!(it != groupsNames_.end()) )
56  {
57  // Add group with empty name
58  groupsNames_[group] = "";
59  }
60 }
61 
62 /******************************************************************************/
63 
65 {
66  if (position >= size())
67  throw IndexOutOfBoundsException("PolymorphismMultiGContainer::getMultilocusGenotype: position out of bounds.", position, 0, size() - 1);
68  return *multilocusGenotypes_[position];
69 }
70 
71 /******************************************************************************/
72 
73 unique_ptr<MultilocusGenotype> PolymorphismMultiGContainer::removeMultilocusGenotype(size_t position)
74 {
75  if (position >= size())
76  throw IndexOutOfBoundsException("PolymorphismMultiGContainer::removeMultilocusGenotype: position out of bounds.", position, 0, size() - 1);
77  unique_ptr<MultilocusGenotype> tmpMg = std::move(multilocusGenotypes_[position]);
78  multilocusGenotypes_.erase(multilocusGenotypes_.begin() + static_cast<ptrdiff_t>(position));
79  groups_.erase(groups_.begin() + static_cast<ptrdiff_t>(position));
80  return tmpMg;
81 }
82 
83 /******************************************************************************/
84 
86 {
87  if (position >= size())
88  throw IndexOutOfBoundsException("PolymorphismMultiGContainer::deleteMultilocusGenotype: position out of bounds.", position, 0, size() - 1);
89  multilocusGenotypes_.erase(multilocusGenotypes_.begin() + static_cast<ptrdiff_t>(position));
90  groups_.erase(groups_.begin() + static_cast<ptrdiff_t>(position));
91 }
92 
93 /******************************************************************************/
94 
96 {
97  size_t value = 0;
98  for (size_t i = 0; i < size(); i++)
99  {
100  if (i == 0)
101  value = multilocusGenotypes_[i]->size();
102  else if (multilocusGenotypes_[i]->size() != value)
103  return false;
104  }
105  return true;
106 }
107 
108 /******************************************************************************/
109 
111 {
112  if (!isAligned())
113  throw Exception("MultilocusGenotypes are not aligned.");
114  if (size() < 1)
115  return 0;
116  return multilocusGenotypes_[0]->size();
117 }
118 
119 /******************************************************************************/
120 
121 size_t PolymorphismMultiGContainer::getGroupId(size_t position) const
122 {
123  if (position >= size())
124  throw IndexOutOfBoundsException("PolymorphismMultiGContainer::getGroupId: position out of bounds.", position, 0, size() - 1);
125  return groups_[position];
126 }
127 
128 /******************************************************************************/
129 
130 void PolymorphismMultiGContainer::setGroupId(size_t position, size_t group_id)
131 {
132  if (position >= size())
133  throw IndexOutOfBoundsException("PolymorphismMultiGContainer::setGroupId: position out of bounds.", position, 0, size() - 1);
134  groups_[position] = group_id;
135 }
136 
137 /******************************************************************************/
138 
140 {
141  set<size_t> groups_ids;
142  for (size_t i = 0; i < size(); i++)
143  {
144  groups_ids.insert(groups_[i]);
145  }
146  return groups_ids;
147 }
148 
149 /******************************************************************************/
150 
151 std::vector<std::string> PolymorphismMultiGContainer::getAllGroupsNames() const
152 {
153  vector<string> grpsNames;
154  for (auto& it : groupsNames_)
155  {
156  string name = it.second;
157  if (!name.empty())
158  grpsNames.push_back(name);
159  else
160  grpsNames.push_back(TextTools::toString(it.first) );
161  }
162 
163  return grpsNames;
164 }
165 
166 /******************************************************************************/
167 
169 {
170  for (auto& g : groups_)
171  {
172  if (g == group)
173  return true;
174  }
175  return false;
176 }
177 
178 /******************************************************************************/
179 
181 {
182  size_t counter = 0;
183  for (auto& g : groups_)
184  {
185  if (g == group)
186  counter++;
187  }
188  return counter;
189 }
190 
191 /******************************************************************************/
192 
193 std::string PolymorphismMultiGContainer::getGroupName(size_t groupId) const
194 {
195  string name = TextTools::toString(groupId); // return group id per default.
196  auto it = groupsNames_.find(groupId);
197  if (it != groupsNames_.end() )
198  name = it->second;
199  else
200  throw GroupNotFoundException("PolymorphismMultiGContainer::getGroupName: group not found.", groupId);
201  return name;
202 }
203 
204 /******************************************************************************/
205 
206 void PolymorphismMultiGContainer::setGroupName(size_t groupId, const string& name)
207 {
208  auto it = groupsNames_.find(groupId);
209  if (it != groupsNames_.end() )
210  it->second = name;
211  else
212  throw GroupNotFoundException("PolymorphismMultiGContainer::getGroupName: group not found.", groupId);
213 }
214 
215 /******************************************************************************/
216 
217 void PolymorphismMultiGContainer::addGroupName(size_t groupId, const string& name)
218 {
219  groupsNames_[groupId] = name;
220 }
221 
222 /******************************************************************************/
223 
224 size_t PolymorphismMultiGContainer::getLocusGroupSize(size_t group, size_t locusPosition) const
225 {
226  size_t counter = 0;
227  for (size_t i = 0; i < size(); ++i)
228  {
229  try
230  {
231  if (groups_[i] == group && !multilocusGenotypes_[i]->isMonolocusGenotypeMissing(locusPosition))
232  counter++;
233  }
234  catch (IndexOutOfBoundsException& ioobe)
235  {
236  throw IndexOutOfBoundsException("PolymorphismMultiGContainer::getGroupSize: locusPosition out of bounds.", ioobe.getBadIndex(), ioobe.getBounds()[0], ioobe.getBounds()[1]);
237  }
238  }
239  return counter;
240 }
241 
242 /******************************************************************************/
243 
245 {
246  return multilocusGenotypes_.size();
247 }
248 
249 /******************************************************************************/
250 
252 {
253  multilocusGenotypes_.clear();
254  groups_.clear();
255  groupsNames_.clear();
256 }
257 
258 /******************************************************************************/
The GroupNotFoundException class.
std::size_t getBadIndex() const
const std::array< std::size_t, 2 > & getBounds() const
The MultilocusGenotype class.
MultilocusGenotype * clone() const override
The PolymorphismMultiGContainer class.
void addMultilocusGenotype(std::unique_ptr< MultilocusGenotype > &mg, size_t group)
Add a MultilocusGenotype to the container.
void deleteMultilocusGenotype(size_t position)
Delete a MultilocusGenotype.
size_t getGroupId(size_t position) const
Get the Group id of a MultilocusGenotype.
std::map< size_t, std::string > groupsNames_
void setGroupName(size_t groupId, const std::string &name)
Set the name for the given group id.
PolymorphismMultiGContainer & operator=(const PolymorphismMultiGContainer &pmgc)
The assignation operator=.
bool groupExists(size_t group) const
Tell if a group exists.
PolymorphismMultiGContainer()
Build a new PolymorphismMultilocusGenotypeContainer.
size_t getLocusGroupSize(size_t group, size_t locusPosition) const
Get the size of a group for a given locus.
size_t getNumberOfLoci() const
Get the number of loci if the MultilocusGenotypes are aligned.
const MultilocusGenotype & multilocusGenotype(size_t position) const
Get a MultilocusGenotype at a position.
std::vector< std::string > getAllGroupsNames() const
Get the groups names or ids if not available.
void addGroupName(size_t groupId, const std::string &name)
Inserts a name for the given group id.
std::string getGroupName(size_t groupId) const
Get the group name for a given group id or just the id if not available juste return it's id.
std::set< size_t > getAllGroupsIds() const
Get the groups' ids.
bool isAligned() const
Tell if the MultilocusGenotypes are aligned (i.e. same size).
size_t size() const
Get the number of MultilocusGenotype.
std::vector< std::unique_ptr< MultilocusGenotype > > multilocusGenotypes_
size_t getGroupSize(size_t group) const
Get group size.
std::unique_ptr< MultilocusGenotype > removeMultilocusGenotype(size_t position)
Remove a MultilocusGenotype.
void setGroupId(size_t position, size_t groupId)
Set the Group id of a MultilocusGenotype.
std::string toString(T t)