bpp-popgen3  3.0.0
Individual.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 #include "Individual.h"
7 
8 using namespace bpp;
9 using namespace std;
10 
11 // ** Class constructor: *******************************************************/
13  id_(""),
14  sex_(0),
15  date_(),
16  coord_(),
17  locality_(0),
18  sequences_(),
19  genotype_() {}
20 
21 Individual::Individual(const std::string& id) : id_(id),
22  sex_(0),
23  date_(),
24  coord_(),
25  locality_(0),
26  sequences_(),
27  genotype_() {}
28 
29 Individual::Individual(const string& id,
30  const Date& date,
31  const Point2D<double>& coord,
32  shared_ptr<Locality<double>> locality,
33  const unsigned short sex) :
34  id_(id),
35  sex_(sex),
36  date_(new Date(date)),
37  coord_(new Point2D<double>(coord)),
38  locality_(locality),
39  sequences_(),
40  genotype_() {}
41 
43  id_(ind.id_),
44  sex_(ind.sex_),
45  date_(),
46  coord_(),
47  locality_(ind.locality_),
48  sequences_(),
49  genotype_()
50 {
51  try
52  {
53  setDate(ind.date());
54  }
55  catch (...)
56  {}
57  try
58  {
59  setCoord(ind.coord());
60  }
61  catch (...)
62  {}
63  try
64  {
65  setSequences(ind.sequences());
66  }
67  catch (...)
68  {}
69  if (ind.hasGenotype())
70  genotype_.reset(new MultilocusGenotype(ind.getGenotype()));
71 }
72 
73 // ** Class destructor: *******************************************************/
75 
76 // ** Other methodes: *********************************************************/
77 
79 {
80  setId(ind.getId());
81  setSex(ind.getSex());
82  try
83  {
84  setDate(ind.date());
85  }
86  catch (NullPointerException&)
87  {
88  date_.reset();
89  }
90  try
91  {
92  setCoord(ind.coord());
93  }
94  catch (NullPointerException&)
95  {
96  coord_.reset();
97  }
98  try
99  {
100  setLocality(ind.getLocality());
101  }
102  catch (NullPointerException&)
103  {
104  locality_ = 0;
105  }
106  try
107  {
108  setSequences(ind.sequences());
109  }
110  catch (NullPointerException&)
111  {
112  sequences_.reset();
113  }
114  genotype_.reset(ind.hasGenotype() ? new MultilocusGenotype(ind.getGenotype()) : 0);
115  return *this;
116 }
117 
118 /******************************************************************************/
119 
120 // Id
121 void Individual::setId(const std::string& id)
122 {
123  id_ = id;
124 }
125 
126 /******************************************************************************/
127 
128 // Sex
129 void Individual::setSex(const unsigned short sex)
130 {
131  sex_ = sex;
132 }
133 
134 /******************************************************************************/
135 
136 // Date
137 void Individual::setDate(const Date& date)
138 {
139  date_.reset(new Date(date));
140 }
141 
142 /******************************************************************************/
143 
144 const Date& Individual::date() const
145 {
146  if (hasDate())
147  return *date_;
148  else
149  throw (NullPointerException("Individual::getDate: no date associated to this individual."));
150 }
151 
152 /******************************************************************************/
153 
155 {
156  return date_ != nullptr;
157 }
158 
159 /******************************************************************************/
160 
161 // Coord
163 {
164  coord_.reset(new Point2D<double>(coord));
165 }
166 
167 /******************************************************************************/
168 
169 void Individual::setCoord(const double x, const double y)
170 {
171  coord_.reset(new Point2D<double>(x, y));
172 }
173 
174 /******************************************************************************/
175 
177 {
178  if (hasCoord())
179  return *coord_;
180  else
181  throw (NullPointerException("Individual::getCoord: no coord associated to this individual."));
182 }
183 
184 /******************************************************************************/
185 
187 {
188  return coord_ != nullptr;
189 }
190 
191 /******************************************************************************/
192 
193 void Individual::setX(const double x)
194 {
195  if (hasCoord())
196  coord_->setX(x);
197  else
198  throw (NullPointerException("Individual::setX: no coord associated to this individual."));
199 }
200 
201 /******************************************************************************/
202 
203 void Individual::setY(const double y)
204 {
205  if (hasCoord())
206  coord_->setY(y);
207  else
208  throw (NullPointerException("Individual::setY: no coord associated to this individual."));
209 }
210 
211 /******************************************************************************/
212 
213 double Individual::getX() const
214 {
215  if (hasCoord())
216  return coord_->getX();
217  else
218  throw (NullPointerException("Individual::getX: no coord associated to this individual."));
219 }
220 
221 /******************************************************************************/
222 
223 double Individual::getY() const
224 {
225  if (hasCoord())
226  return coord_->getY();
227  else
228  throw (NullPointerException("Individual::getY: no coord associated to this individual."));
229 }
230 
231 /******************************************************************************/
232 
233 shared_ptr<const Locality<double>> Individual::getLocality() const
234 {
235  if (hasLocality())
236  return locality_;
237  else
238  throw (NullPointerException("Individual::getLocality: no locality associated to this individual."));
239 }
240 
241 /******************************************************************************/
242 
244 {
245  if (hasLocality())
246  return *locality_;
247  else
248  throw (NullPointerException("Individual::locality: no locality associated to this individual."));
249 }
250 
251 /******************************************************************************/
252 
253 // Sequences
254 void Individual::addSequence(size_t sequenceKey, unique_ptr<Sequence>& sequence)
255 {
256  if (!sequences_)
257  sequences_ = make_unique<VectorSequenceContainer>(sequence->getAlphabet());
258  try
259  {
260  sequences_->addSequence(TextTools::toString(sequenceKey), sequence);
261  }
262  catch (AlphabetMismatchException& ame)
263  {
264  throw (AlphabetMismatchException("Individual::addSequence: alphabets don't match.", ame.getFirstAlphabet(), ame.getSecondAlphabet()));
265  }
266  catch (Exception& e)
267  {
268  if (string(e.what()).find("name") < string(e.what()).size())
269  throw (BadIdentifierException("Individual::addSequence: sequence's name already in use.", sequence->getName()));
270  // if (string(e.what()).find("key") < string(e.what()).size())
271  else
272  throw (Exception("Individual::addSequence: sequence_key already in use:" + TextTools::toString(sequenceKey)));
273  }
274 }
275 
276 /******************************************************************************/
277 
278 const Sequence& Individual::sequenceByName(const std::string& sequenceName) const
279 {
280  if (!sequences_)
281  throw NullPointerException("Individual::getSequenceByName: no sequence data.");
282  try
283  {
284  size_t pos = VectorTools::which(sequences_->getSequenceNames(), sequenceName);
285  return sequences_->sequence(pos);
286  }
287  catch (SequenceNotFoundException& snfe)
288  {
289  throw SequenceNotFoundException("Individual::getSequenceByName: sequence_name not found.", snfe.getSequenceId());
290  }
291 }
292 
293 /******************************************************************************/
294 
295 const Sequence& Individual::sequenceAtPosition(size_t sequencePosition) const
296 {
297  if (!sequences_)
298  throw NullPointerException("Individual::getSequenceAtPosition: no sequence data.");
299  try
300  {
301  return sequences_->sequence(TextTools::toString(sequencePosition));
302  }
303  catch (SequenceNotFoundException& snfe)
304  {
305  throw SequenceNotFoundException("Individual::getSequenceAtPosition: sequence_position not found", snfe.getSequenceId());
306  }
307 }
308 
309 /******************************************************************************/
310 
311 void Individual::deleteSequenceByName(const std::string& sequenceName)
312 {
313  if (!sequences_)
314  throw NullPointerException("Individual::deleteSequenceByName: no sequence data.");
315  try
316  {
317  size_t pos = VectorTools::which(sequences_->getSequenceNames(), sequenceName);
318  sequences_->deleteSequence(pos);
319  }
320  catch (SequenceNotFoundException& snfe)
321  {
322  throw SequenceNotFoundException("Individual::deleteSequenceByName: sequence_name not found.", snfe.getSequenceId());
323  }
324 }
325 
326 /******************************************************************************/
327 
328 void Individual::deleteSequenceAtPosition(size_t sequence_position)
329 {
330  if (!sequences_)
331  throw NullPointerException("Individual::deleteSequenceAtPosition: no sequence data.");
332  try
333  {
334  sequences_->removeSequence(TextTools::toString(sequence_position));
335  }
336  catch (SequenceNotFoundException& snfe)
337  {
338  throw SequenceNotFoundException("Individual::deleteSequenceAtPosition: sequence_position not found.", snfe.getSequenceId());
339  }
340 }
341 
342 /******************************************************************************/
343 
344 std::vector<size_t> Individual::getSequencePositions() const
345 {
346  if (!sequences_)
347  throw NullPointerException("Individual::getSequencesPositions: no sequence data.");
348  vector<size_t> seqpos;
349  vector<string> seqkeys = sequences_->getSequenceKeys();
350  for (size_t i = 0; i < seqkeys.size(); i++)
351  {
352  seqpos.push_back((size_t) TextTools::toInt(seqkeys[i]));
353  }
354  return seqpos;
355 }
356 
357 /******************************************************************************/
358 
359 size_t Individual::getSequencePosition(const std::string& sequenceName) const
360 {
361  if (sequences_.get() == 0)
362  throw NullPointerException("Individual::getSequencePosition: no sequence data.");
363  try
364  {
365  return TextTools::to<size_t>(sequences_->sequenceKey(getSequencePosition(sequenceName)));
366  }
367  catch (SequenceNotFoundException& snfe)
368  {
369  throw SequenceNotFoundException("Individual::getSequencePosition: sequence_name not found.", snfe.getSequenceId());
370  }
371 }
372 
373 /******************************************************************************/
374 
376 {
377  return !(getNumberOfSequences() == 0);
378 }
379 
380 /******************************************************************************/
381 
382 bool Individual::hasSequenceAtPosition(size_t position) const
383 {
384  if (hasSequences())
385  {
386  vector<size_t> pos = getSequencePositions();
387  for (size_t i = 0; i < pos.size(); ++i)
388  {
389  if (pos[i] == position)
390  return true;
391  }
392  }
393  return false;
394 }
395 
396 /******************************************************************************/
397 
398 shared_ptr<const Alphabet> Individual::getSequenceAlphabet() const
399 {
400  if (!sequences_)
401  throw NullPointerException("Individual::getSequenceAlphabet: no sequence data.");
402  return sequences_->getAlphabet();
403 }
404 
405 /******************************************************************************/
406 
408 {
409  if (!sequences_)
410  throw NullPointerException("Individual::getSequenceAlphabet: no sequence data.");
411  return sequences_->alphabet();
412 }
413 
414 /******************************************************************************/
415 
416 // MultilocusGenotype
417 
419 {
420  genotype_.reset(new MultilocusGenotype(genotype));
421 }
422 
423 /******************************************************************************/
424 
425 void Individual::initGenotype(size_t loci_number)
426 {
427  if (hasGenotype())
428  throw Exception("Individual::initGenotype: individual already has a genotype.");
429  try
430  {
431  genotype_.reset(new MultilocusGenotype(loci_number));
432  }
433  catch (BadIntegerException& bie)
434  {
435  throw BadIntegerException("Individual::initGenotype: loci_number must be > 0.", bie.getBadInteger());
436  }
437 }
438 
439 /******************************************************************************/
440 
442 {
443  if (!hasGenotype())
444  throw NullPointerException("Individual::getGenotype: individual has no genotype.");
445  return *genotype_;
446 }
447 
448 /******************************************************************************/
449 
451 {
452  genotype_.reset();
453 }
454 
455 /******************************************************************************/
456 
458 {
459  return genotype_.get() != 0;
460 }
461 
462 /******************************************************************************/
463 
465  size_t locusPosition,
466  const MonolocusGenotypeInterface& monogen)
467 {
468  if (!hasGenotype())
469  throw NullPointerException("Individual::setMonolocusGenotype: individual has no genotype.");
470  try
471  {
472  genotype_->setMonolocusGenotype(locusPosition, monogen);
473  }
474  catch (IndexOutOfBoundsException& ioobe)
475  {
476  throw IndexOutOfBoundsException("Individual::setMonolocusGenotype: locus_position out of boubds.", ioobe.getBadIndex(), ioobe.getBounds()[0], ioobe.getBounds()[1]);
477  }
478 }
479 
480 /******************************************************************************/
481 
482 void Individual::setMonolocusGenotypeByAlleleKey(size_t locus_position, const std::vector<size_t> allele_keys)
483 {
484  if (!hasGenotype())
485  throw NullPointerException("Individual::setMonolocusGenotypeByAlleleKey: individual has no genotype.");
486  try
487  {
488  genotype_->setMonolocusGenotypeByAlleleKey(locus_position, allele_keys);
489  }
490  catch (IndexOutOfBoundsException& ioobe)
491  {
492  throw IndexOutOfBoundsException("Individual::setMonolocusGenotypeByAlleleKey: locus_position out of bounds.", ioobe.getBadIndex(), ioobe.getBounds()[0], ioobe.getBounds()[1]);
493  }
494  catch (Exception&)
495  {
496  throw Exception("Individual::setMonolocusGenotypeByAlleleKey: no key in allele_keys.");
497  }
498 }
499 
500 /******************************************************************************/
501 
502 void Individual::setMonolocusGenotypeByAlleleId(size_t locus_position, const std::vector<std::string> allele_id, const LocusInfo& locus_info)
503 {
504  if (!hasGenotype())
505  throw NullPointerException("Individual::setMonolocusGenotypeByAlleleId: individual has no genotype.");
506  try
507  {
508  genotype_->setMonolocusGenotypeByAlleleId(locus_position, allele_id, locus_info);
509  }
510  catch (IndexOutOfBoundsException& ioobe)
511  {
512  throw IndexOutOfBoundsException("Individual::setMonolocusGenotypeByAlleleId: locus_position out of bounds.", ioobe.getBadIndex(), ioobe.getBounds()[0], ioobe.getBounds()[1]);
513  }
514  catch (AlleleNotFoundException& anfe)
515  {
516  throw AlleleNotFoundException("Individual::setMonolocusGenotypeByAlleleId: id not found.", anfe.getIdentifier());
517  }
518 }
519 
520 /******************************************************************************/
521 
523 {
524  if (!hasGenotype())
525  throw NullPointerException("Individual::getMonolocusGenotype: individual has no genotype.");
526  try
527  {
528  return genotype_->monolocusGenotype(locusPosition);
529  }
530  catch (IndexOutOfBoundsException& ioobe)
531  {
532  throw IndexOutOfBoundsException("Individual::getMonolocusGenotype: locus_position out of bounds.", ioobe.getBadIndex(), ioobe.getBounds()[0], ioobe.getBounds()[1]);
533  }
534 }
535 
536 /******************************************************************************/
537 
539 {
540  if (!hasGenotype())
541  throw NullPointerException("Individual::countNonMissingLoci: individual has no genotype.");
542  return genotype_->countNonMissingLoci();
543 }
544 
545 /******************************************************************************/
546 
548 {
549  if (!hasGenotype())
550  throw NullPointerException("Individual::countHomozygousLoci: individual has no genotype.");
551  return genotype_->countHomozygousLoci();
552 }
553 
554 /******************************************************************************/
555 
557 {
558  if (!hasGenotype())
559  throw NullPointerException("Individual::countHeterozygousLoci: individual has no genotype.");
560  return genotype_->countHeterozygousLoci();
561 }
562 
563 /******************************************************************************/
The AlleleNotFoundException class.
virtual const std::string getIdentifier() const
Return the value of the identifier as a string.
const Alphabet * getSecondAlphabet() const
const Alphabet * getFirstAlphabet() const
The BadIdentifierException class.
The Date class.
Definition: Date.h:21
const char * what() const noexcept override
std::size_t getBadIndex() const
const std::array< std::size_t, 2 > & getBounds() const
The Individual class.
Definition: Individual.h:40
double getY() const
Get the Y coordinate of the Individual.
Definition: Individual.cpp:223
const MonolocusGenotypeInterface & getMonolocusGenotype(size_t locusPosition)
Get a MonolocusGenotype.
Definition: Individual.cpp:522
bool hasCoord() const
Tell if this Individual has coordinates.
Definition: Individual.cpp:186
std::shared_ptr< const Alphabet > getSequenceAlphabet() const
Return the alphabet of the sequences.
Definition: Individual.cpp:398
size_t getNumberOfSequences() const
Get the number of sequences.
Definition: Individual.h:353
bool hasSequences() const
Tell if the Individual has some sequences.
Definition: Individual.cpp:375
virtual ~Individual()
Destroy an Individual.
Definition: Individual.cpp:74
const Sequence & sequenceByName(const std::string &sequenceName) const
Get a sequence from its name.
Definition: Individual.cpp:278
Individual()
Build a void new Individual.
Definition: Individual.cpp:12
unsigned short getSex() const
Get the sex of the Individual.
Definition: Individual.h:124
const Locality< double > & locality() const
Get the locality of the Individual.
Definition: Individual.cpp:243
void setSex(const unsigned short sex)
Set the sex of the Individual.
Definition: Individual.cpp:129
std::unique_ptr< Date > date_
Definition: Individual.h:44
size_t getSequencePosition(const std::string &sequenceKey) const
Get the position of a sequence.
Definition: Individual.cpp:359
size_t countNonMissingLoci() const
Count the number of non missing MonolocusGenotype.
Definition: Individual.cpp:538
void addSequence(size_t sequenceKey, std::unique_ptr< Sequence > &sequence)
Add a sequence to the Individual.
Definition: Individual.cpp:254
std::string id_
Definition: Individual.h:42
void setGenotype(const MultilocusGenotype &genotype)
Set a genotype.
Definition: Individual.cpp:418
void setMonolocusGenotype(size_t locusPosition, const MonolocusGenotypeInterface &monogen)
Set a MonolocusGenotype.
Definition: Individual.cpp:464
void deleteSequenceAtPosition(size_t sequencePosition)
Delete a sequence.
Definition: Individual.cpp:328
const std::string & getId() const
Get the id of the Individual.
Definition: Individual.h:110
std::unique_ptr< VectorSequenceContainer > sequences_
Definition: Individual.h:47
void setCoord(const Point2D< double > &coord)
Set the coordinates of the Individual.
Definition: Individual.cpp:162
void setY(const double y)
Set the Y coordinate of th Individual.
Definition: Individual.cpp:203
std::shared_ptr< const Locality< double > > getLocality() const
Get the locality of the Individual.
Definition: Individual.cpp:233
void setId(const std::string &id)
Set the id of the Individual.
Definition: Individual.cpp:121
void setLocality(std::shared_ptr< const Locality< double >> locality)
Set the locality of the Individual.
Definition: Individual.h:215
bool hasGenotype() const
Tell if the Individual has a MultilocusGenotype.
Definition: Individual.cpp:457
Individual & operator=(const Individual &ind)
The Individual copy operator.
Definition: Individual.cpp:78
void deleteSequenceByName(const std::string &sequenceName)
Delete a sequence.
Definition: Individual.cpp:311
void setMonolocusGenotypeByAlleleKey(size_t locusPosition, const std::vector< size_t > alleleKeys)
Set a MonolocusGenotype.
Definition: Individual.cpp:482
void setDate(const Date &date)
Set the date of the Individual.
Definition: Individual.cpp:137
void initGenotype(size_t lociNumber)
Init the genotype.
Definition: Individual.cpp:425
const MultilocusGenotype & getGenotype() const
Get the genotype.
Definition: Individual.cpp:441
bool hasLocality() const
Tell if this Individual has a locality.
Definition: Individual.h:237
std::vector< size_t > getSequencePositions() const
Get the sequences' positions.
Definition: Individual.cpp:344
bool hasSequenceAtPosition(size_t position) const
Tell if the Individual has a sequence at a given position.
Definition: Individual.cpp:382
size_t countHomozygousLoci() const
Count the number of homozygous MonolocusGenotype.
Definition: Individual.cpp:547
void setX(const double x)
Set the X coordinate of the Individual.
Definition: Individual.cpp:193
const Point2D< double > & coord() const
Get the coordinates of the Induvidual.
Definition: Individual.cpp:176
bool hasDate() const
Tell if this Individual has a date.
Definition: Individual.cpp:154
const SequenceContainerInterface & sequences() const
Get a reference to the sequence container.
Definition: Individual.h:372
std::unique_ptr< Point2D< double > > coord_
Definition: Individual.h:45
const Sequence & sequenceAtPosition(size_t sequencePosition) const
Get a sequence by its position.
Definition: Individual.cpp:295
void deleteGenotype()
Delete the genotype of the individual.
Definition: Individual.cpp:450
std::unique_ptr< MultilocusGenotype > genotype_
Definition: Individual.h:48
std::shared_ptr< const Locality< double > > locality_
Definition: Individual.h:46
unsigned short sex_
Definition: Individual.h:43
void setMonolocusGenotypeByAlleleId(size_t locusPosition, const std::vector< std::string > alleleId, const LocusInfo &locusInfo)
Set a MonolocusGenotype.
Definition: Individual.cpp:502
size_t countHeterozygousLoci() const
Count the number of heterozygous MonolocusGenotype.
Definition: Individual.cpp:556
double getX() const
Get the X coordinate of the Individual.
Definition: Individual.cpp:213
const Date & date() const
Get the date of the Individual.
Definition: Individual.cpp:144
void setSequences(const SequenceContainerInterface &sc)
Set all the sequences with a SequenceContainer. The container will be copied.
Definition: Individual.h:362
const Alphabet & sequenceAlphabet() const
Return the alphabet of the sequences.
Definition: Individual.cpp:407
The Locality class.
Definition: Locality.h:25
The LocusInfo class.
Definition: LocusInfo.h:31
The MonolocusGenotype virtual class.
The MultilocusGenotype class.
virtual const std::string getSequenceId() const
static size_t which(const std::vector< T > &v, const T &which)
int toInt(const std::string &s, char scientificNotation='e')
std::string toString(T t)