bpp-seq  2.1.0
 All Classes Namespaces Files Functions Variables Friends Pages
AlignedSequenceContainer.cpp
Go to the documentation of this file.
1 //
2 // File: AlignedSequenceContainer.cpp
3 // Created by: Guillaume Deuchst
4 // Julien Dutheil
5 // Created on: Friday August 22 2003
6 //
7 
8 /*
9  Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
10 
11  This software is a computer program whose purpose is to provide classes
12  for sequences analysis.
13 
14  This software is governed by the CeCILL license under French law and
15  abiding by the rules of distribution of free software. You can use,
16  modify and/ or redistribute the software under the terms of the CeCILL
17  license as circulated by CEA, CNRS and INRIA at the following URL
18  "http://www.cecill.info".
19 
20  As a counterpart to the access to the source code and rights to copy,
21  modify and redistribute granted by the license, users are provided only
22  with a limited warranty and the software's author, the holder of the
23  economic rights, and the successive licensors have only limited
24  liability.
25 
26  In this respect, the user's attention is drawn to the risks associated
27  with loading, using, modifying and/or developing or reproducing the
28  software by the user in light of its specific status of free software,
29  that may mean that it is complicated to manipulate, and that also
30  therefore means that it is reserved for developers and experienced
31  professionals having in-depth computer knowledge. Users are therefore
32  encouraged to load and test the software's suitability as regards their
33  requirements in conditions enabling the security of their systems and/or
34  data to be ensured and, more generally, to use and operate it in the
35  same conditions as regards security.
36 
37  The fact that you are presently reading this means that you have had
38  knowledge of the CeCILL license and that you accept its terms.
39  */
40 
42 
43 #include <Bpp/Text/TextTools.h>
44 
45 using namespace bpp;
46 
47 // From the STL:
48 #include <iostream>
49 
50 using namespace std;
51 
52 /***************************************************************************/
53 
55  VectorSequenceContainer(osc.getAlphabet()),
56  // We can't call the copy constructor because we want to use the overloaded addSequence method !!!
57  positions_(),
58  length_(),
59  sites_()
60 {
61  // Initializing
62  for (unsigned int i = 0; i < osc.getNumberOfSequences(); i++)
63  {
64  addSequence(osc.getSequence(i), true);
65  }
66 
67  if (osc.getNumberOfSequences() > 0)
68  length_ = getSequence(0).size(); // the overloaded
69  else
70  length_ = 0;
71 
72  reindexSites();
73  sites_.resize(length_);
74  setGeneralComments(osc.getGeneralComments());
75 }
76 
77 /***************************************************************************/
78 
80 {
82 
83  // Initializing
84  length_ = asc.getNumberOfSites();
85  positions_ = asc.getSitePositions();
86  sites_.resize(length_);
87 
88  return *this;
89 }
90 
91 /***************************************************************************/
92 
94 {
96 
97  // Initializing
98  length_ = sc.getNumberOfSites();
99  positions_ = sc.getSitePositions();
100  sites_.resize(length_);
101 
102  return *this;
103 }
104 
105 /***************************************************************************/
106 
108 {
110 
111  // Initializing
112  length_ = 0;
113  reindexSites();
114  sites_.resize(length_);
115 
116  return *this;
117 }
118 
122 {
123  // delete all sites:
124  for (unsigned int i = 0; i < sites_.size(); i++)
125  {
126  if (sites_[i])
127  delete sites_[i];
128  }
129 }
130 
131 /***************************************************************************/
132 
134 {
135  if (i >= length_)
136  throw IndexOutOfBoundsException("AlignedSequenceContainer::getSite", i, 0, getNumberOfSites() - 1);
137 
138  // Main loop : for all sequences
139  size_t n = getNumberOfSequences();
140  std::vector<int> site(n);
141  for (size_t j = 0; j < n; j++)
142  {
143  site[j] = getSequence(j)[i];
144  }
145 
146  if (sites_[i])
147  delete sites_[i];
148  sites_[i] = new Site(site, getAlphabet(), positions_[i]);
149  return *sites_[i];
150 }
151 
152 /******************************************************************************/
153 
154 void AlignedSequenceContainer::setSite(size_t pos, const Site& site, bool checkPositions) throw (Exception)
155 {
156  // New site's alphabet and site container's alphabet matching verification
157  if (pos >= getNumberOfSites())
158  throw IndexOutOfBoundsException("AlignedSequenceContainer::setSite", pos, 0, getNumberOfSites() - 1);
159  if (site.getAlphabet()->getAlphabetType() != getAlphabet()->getAlphabetType())
160  throw AlphabetMismatchException("AlignedSequenceContainer::setSite", getAlphabet(), site.getAlphabet());
161 
162  std::vector<int> s = site.getContent();
163 
164  // Check size:
165  if (s.size() != getNumberOfSequences())
166  throw SiteException("AlignedSequenceContainer::setSite, site does not have the appropriate length", &site);
167 
168  // Check position:
169  int position = site.getPosition();
170  if (checkPositions)
171  {
172  // For all positions in vector : throw exception if position already exists
173  for (size_t i = 0; i < positions_.size(); i++)
174  {
175  if (positions_[i] == position)
176  throw SiteException("AlignedSequenceContainer::setSite: Site position already exists in container", &site);
177  }
178  }
179 
180  // For all sequences
181  for (size_t j = 0; j < getNumberOfSequences(); j++)
182  {
183  getSequence_(j).setElement(pos, s[j]);
184  }
185  positions_[pos] = site.getPosition();
186 }
187 
188 /******************************************************************************/
189 
191 {
192  if (pos >= getNumberOfSites())
193  throw IndexOutOfBoundsException("AlignedSequenceContainer::removeSite", pos, 0, getNumberOfSites() - 1);
194 
195  // Get old site
196  getSite(pos); // Creates the site!
197  Site* old = sites_[pos];
198 
199  // For all sequences
200  for (size_t j = 0; j < getNumberOfSequences(); j++)
201  {
202  getSequence_(j).deleteElement(pos);
203  }
204 
205  // Delete site's position
206  positions_.erase(positions_.begin() + pos);
207  length_--;
208 
209  // Actualizes the 'sites' vector:
210  if (sites_[pos])
211  delete sites_[pos];
212  sites_.erase(sites_.begin() + pos);
213 
214  // Send result
215  return old;
216 }
217 
218 /******************************************************************************/
219 
221 {
222  if (pos >= getNumberOfSites())
223  throw IndexOutOfBoundsException("AlignedSequenceContainer::deleteSite", pos, 0, getNumberOfSites() - 1);
224 
225  // For all sequences
226  for (size_t j = 0; j < getNumberOfSequences(); j++)
227  {
228  getSequence_(j).deleteElement(pos);
229  }
230 
231  // Delete site's position
232  positions_.erase(positions_.begin() + pos);
233  length_--;
234 
235  // Actualizes the 'sites' vector:
236  if (sites_[pos])
237  delete sites_[pos];
238  sites_.erase(sites_.begin() + pos);
239 }
240 
241 /******************************************************************************/
242 
243 void AlignedSequenceContainer::deleteSites(size_t siteIndex, size_t length) throw (IndexOutOfBoundsException, Exception)
244 {
245  if (siteIndex + length > getNumberOfSites())
246  throw IndexOutOfBoundsException("AlignedSequenceContainer::deleteSites", siteIndex + length, 0, getNumberOfSites() - 1);
247 
248  // For all sequences
249  for (size_t j = 0; j < getNumberOfSequences(); j++)
250  {
251  getSequence_(j).deleteElements(siteIndex, length);
252  }
253 
254  // Delete site's siteIndexition
255  positions_.erase(positions_.begin() + siteIndex, positions_.begin() + siteIndex + length);
256  length_ -= length;
257 
258  // Actualizes the 'sites' vector:
259  for (size_t i = siteIndex; i < siteIndex + length; ++i)
260  {
261  if (sites_[i])
262  delete sites_[i];
263  }
264  sites_.erase(sites_.begin() + siteIndex, sites_.begin() + siteIndex + length);
265 }
266 
267 /******************************************************************************/
268 
269 void AlignedSequenceContainer::addSite(const Site& site, bool checkPositions) throw (Exception)
270 {
271  // New site's alphabet and site container's alphabet matching verification
272  if (site.getAlphabet()->getAlphabetType() != getAlphabet()->getAlphabetType())
273  throw AlphabetMismatchException("AlignedSequenceContainer::addSite");
274 
275  // Initializing
276  std::vector<int> s = site.getContent();
277 
278  // Check size:
279  if (s.size() != getNumberOfSequences())
280  throw SiteException("AlignedSequenceContainer::addSite, site does not have the appropriate length", &site);
281 
282  // Check position:
283 
284  int position = site.getPosition();
285  if (checkPositions)
286  {
287  // For all positions in vector : throw exception if position already exists
288  for (unsigned int i = 0; i < positions_.size(); i++)
289  {
290  if (positions_[i] == position)
291  throw SiteException("AlignedSequenceContainer::addSite: Site position already exists in container", &site);
292  }
293  }
294 
295  // For all sequences
296  for (unsigned int j = 0; j < getNumberOfSequences(); j++)
297  {
298  getSequence_(j).addElement(s[j]);
299  }
300 
301  length_++;
302  positions_.push_back(position);
303 
304  // Actualizes the 'sites' vector:
305  sites_.push_back(0);
306 }
307 
308 /******************************************************************************/
309 
310 void AlignedSequenceContainer::addSite(const Site& site, int position, bool checkPositions) throw (Exception)
311 {
312  // New site's alphabet and site container's alphabet matching verification
313  if (site.getAlphabet()->getAlphabetType() != getAlphabet()->getAlphabetType())
314  throw AlphabetMismatchException("AlignedSequenceContainer::addSite");
315 
316  // Initializing
317  std::vector<int> s = site.getContent();
318 
319  // Check size:
320  if (s.size() != getNumberOfSequences())
321  throw SiteException("AlignedSequenceContainer::addSite, site does not have the appropriate length", &site);
322 
323  // Check position:
324 
325  if (checkPositions)
326  {
327  // For all positions in vector : throw exception if position already exists
328  for (unsigned int i = 0; i < positions_.size(); i++)
329  {
330  if (positions_[i] == position)
331  throw SiteException("AlignedSequenceContainer::addSite: Site position already exists in container", &site);
332  }
333  }
334 
335  // For all sequences
336  for (unsigned int j = 0; j < getNumberOfSequences(); j++)
337  {
338  getSequence_(j).addElement(s[j]);
339  }
340 
341  length_++;
342  positions_.push_back(position);
343 
344  // Actualizes the 'sites' vector:
345  sites_.push_back(0);
346 }
347 
348 /******************************************************************************/
349 
350 void AlignedSequenceContainer::addSite(const Site& site, size_t siteIndex, bool checkPositions) throw (Exception)
351 {
352  if (siteIndex >= getNumberOfSites())
353  throw IndexOutOfBoundsException("AlignedSequenceContainer::addSite", siteIndex, 0, getNumberOfSites() - 1);
354 
355  // New site's alphabet and site container's alphabet matching verification
356  if (site.getAlphabet()->getAlphabetType() != getAlphabet()->getAlphabetType())
357  throw AlphabetMismatchException("AlignedSequenceContainer::addSite", getAlphabet(), site.getAlphabet());
358 
359  std::vector<int> s = site.getContent();
360 
361  // Check size:
362  if (s.size() != getNumberOfSequences())
363  throw SiteException("AlignedSequenceContainer::addSite, site does not have the appropriate length", &site);
364 
365  // Check position:
366  int position = site.getPosition();
367  if (checkPositions)
368  {
369  // For all positions in vector : throw exception if position already exists
370  for (size_t i = 0; i < positions_.size(); i++)
371  {
372  if (positions_[i] == position)
373  throw SiteException("AlignedSequenceContainer::addSite: Site position already exists in container", &site);
374  }
375  }
376 
377  // For all sequences
378  for (size_t j = 0; j < getNumberOfSequences(); j++)
379  {
380  getSequence_(j).addElement(siteIndex, site[j]);
381  }
382 
383  length_++;
384  positions_.insert(positions_.begin() + siteIndex, position);
385 
386  // Actualizes the 'sites' vector:
387  sites_.insert(sites_.begin() + siteIndex, 0);
388 }
389 
390 /******************************************************************************/
391 
392 void AlignedSequenceContainer::addSite(const Site& site, size_t siteIndex, int position, bool checkPositions) throw (Exception)
393 {
394  if (siteIndex >= getNumberOfSites())
395  throw IndexOutOfBoundsException("AlignedSequenceContainer::addSite", siteIndex, 0, getNumberOfSites() - 1);
396 
397  // New site's alphabet and site container's alphabet matching verification
398  if (site.getAlphabet()->getAlphabetType() != getAlphabet()->getAlphabetType())
399  throw AlphabetMismatchException("AlignedSequenceContainer::addSite", getAlphabet(), site.getAlphabet());
400 
401  std::vector<int> s = site.getContent();
402 
403  // Check size:
404  if (s.size() != getNumberOfSequences())
405  throw SiteException("AlignedSequenceContainer::addSite, site does not have the appropriate length", &site);
406 
407  // Check position:
408  if (checkPositions)
409  {
410  // For all positions in vector : throw exception if position already exists
411  for (size_t i = 0; i < positions_.size(); i++)
412  {
413  if (positions_[i] == position)
414  throw SiteException("AlignedSequenceContainer::addSite: Site position already exists in container", &site);
415  }
416  }
417 
418  // For all sequences
419  for (size_t j = 0; j < getNumberOfSequences(); j++)
420  {
421  getSequence_(j).addElement(siteIndex, site[j]);
422  }
423 
424  length_++;
425  positions_.insert(positions_.begin() + siteIndex, position);
426 
427  // Actualizes the 'sites' vector:
428  sites_.insert(sites_.begin() + siteIndex, 0);
429 }
430 
431 /******************************************************************************/
432 
434 {
435  positions_.resize(length_);
436  for (size_t i = 0; i < length_; i++)
437  {
438  positions_[i] = static_cast<int>(i + 1); // start with 1.
439  }
440 }
441 
442 /******************************************************************************/
443 
444 void AlignedSequenceContainer::setSequence(size_t i, const Sequence& sequence, bool checkName) throw (Exception)
445 {
446  if (i >= getNumberOfSequences())
447  throw IndexOutOfBoundsException("AlignedSequenceContainer::setSequence", i, 0, getNumberOfSequences() - 1);
448  // if container has only one sequence
449  if (getNumberOfSequences() == 1)
450  length_ = sequence.size();
451  if (checkSize_(sequence))
452  VectorSequenceContainer::setSequence(i, sequence, checkName);
453  else
454  throw SequenceNotAlignedException("AlignedSequenceContainer::setSequence", &sequence);
455 }
456 
457 /******************************************************************************/
458 
459 void AlignedSequenceContainer::setSequence(const string& name, const Sequence& sequence, bool checkName) throw (Exception)
460 {
461  // if container has only one sequence
462  if (getNumberOfSequences() == 1)
463  length_ = sequence.size();
464  if (checkSize_(sequence))
465  VectorSequenceContainer::setSequence(name, sequence, checkName);
466  else
467  throw SequenceNotAlignedException("AlignedSequenceContainer::setSequence", &sequence);
468 }
469 
470 /******************************************************************************/
471 
472 void AlignedSequenceContainer::addSequence(const Sequence& sequence, bool checkName) throw (Exception)
473 {
474  // if container has only one sequence
475  if (length_ == 0)
476  {
477  length_ = sequence.size();
478  sites_.resize(length_);
479  reindexSites();
480  }
481  if (checkSize_(sequence))
482  VectorSequenceContainer::addSequence(sequence, checkName);
483  else
484  throw SequenceNotAlignedException("AlignedSequenceContainer::addSequence", &sequence);
485 }
486 
487 /******************************************************************************/
488 
489 void AlignedSequenceContainer::addSequence(const Sequence& sequence, size_t i, bool checkName) throw (Exception)
490 {
491  if (i >= getNumberOfSequences())
492  throw IndexOutOfBoundsException("AlignedSequenceContainer::addSequence", i, 0, getNumberOfSequences() - 1);
493  // if container has only one sequence
494  if (length_ == 0)
495  length_ = sequence.size();
496  if (checkSize_(sequence))
497  VectorSequenceContainer::addSequence(sequence, i, checkName);
498  else
499  throw SequenceNotAlignedException("AlignedSequenceContainer::addSequence", &sequence);
500 }
501 
502 /******************************************************************************/
503 
505 {
506  length_ = 0;
508 }
509 
510 /******************************************************************************/
511 
513 {
514  AlignedSequenceContainer* asc = new AlignedSequenceContainer(getAlphabet());
515  asc->setGeneralComments(getGeneralComments());
516  return asc;
517 }
518 
519 /******************************************************************************/
520 
521