bpp-seq3  3.0.0
MapSequenceContainer.cpp
Go to the documentation of this file.
1 //
2 // File: MapSequenceContainer.cpp
3 // Authors:
4 // Guillaume Deuchst
5 // Julien Dutheil
6 // Sylvain Gaillard
7 // Last modified: 2004-07-19 00:00:00
8 //
9 
10 /*
11  Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
12 
13  This software is a computer program whose purpose is to provide classes
14  for sequences analysis.
15 
16  This software is governed by the CeCILL license under French law and
17  abiding by the rules of distribution of free software. You can use,
18  modify and/ or redistribute the software under the terms of the CeCILL
19  license as circulated by CEA, CNRS and INRIA at the following URL
20  "http://www.cecill.info".
21 
22  As a counterpart to the access to the source code and rights to copy,
23  modify and redistribute granted by the license, users are provided only
24  with a limited warranty and the software's author, the holder of the
25  economic rights, and the successive licensors have only limited
26  liability.
27 
28  In this respect, the user's attention is drawn to the risks associated
29  with loading, using, modifying and/or developing or reproducing the
30  software by the user in light of its specific status of free software,
31  that may mean that it is complicated to manipulate, and that also
32  therefore means that it is reserved for developers and experienced
33  professionals having in-depth computer knowledge. Users are therefore
34  encouraged to load and test the software's suitability as regards their
35  requirements in conditions enabling the security of their systems and/or
36  data to be ensured and, more generally, to use and operate it in the
37  same conditions as regards security.
38 
39  The fact that you are presently reading this means that you have had
40  knowledge of the CeCILL license and that you accept its terms.
41 */
42 
43 #include <Bpp/Text/TextTools.h>
44 
45 #include "MapSequenceContainer.h"
46 
47 using namespace bpp;
48 using namespace std;
49 
50 /******************************************************************************/
51 
52 MapSequenceContainer::MapSequenceContainer(const map<string, Sequence*>& ms, const Alphabet* alpha) :
53  AbstractSequenceContainer(alpha), sequences_()
54 {
55  for (map<string, Sequence*>::const_iterator it = ms.begin(); it != ms.end(); it++)
56  {
57  addSequence(it->first, *it->second);
58  }
59 }
60 
61 /******************************************************************************/
62 
64  AbstractSequenceContainer(msc.getAlphabet()), sequences_()
65 {
66  for (unsigned int i = 0; i < msc.getNumberOfSequences(); i++)
67  {
68  addSequence(msc.getKey(i), msc.getSequence(i), false);
69  }
70 }
71 
72 /******************************************************************************/
73 
75 {
76  clear();
78 
79  // Sequences insertion
80  vector<string> keys = msc.getKeys();
81  for (unsigned int i = 0; i < getNumberOfSequences(); i++)
82  {
83  addSequence(keys[i], msc.getSequence(i), false);
84  }
85 
86  return *this;
87 }
88 
89 /******************************************************************************/
90 
92 {
93  clear();
94 }
95 
96 /******************************************************************************/
97 
99 {
100  // Specified sequence existence verification
101  if (i < sequences_.size())
102  {
103  map<string, Sequence*>::const_iterator it = sequences_.begin();
104  for (unsigned int j = 0; j < i; j++)
105  {
106  it++;
107  }
108  return *it->second;
109  }
110  throw IndexOutOfBoundsException("MapSequenceContainer::getSequence", i, 0, sequences_.size() - 1);
111 }
112 
113 /******************************************************************************/
114 
115 const Sequence& MapSequenceContainer::getSequence(const string& name) const
116 {
117  // Specified sequence name research into all sequences
118  for (map<string, Sequence*>::const_iterator it = sequences_.begin(); it != sequences_.end(); it++)
119  {
120  if (it->second->getName() == name)
121  return *it->second;
122  }
123  throw SequenceNotFoundException("MapSequenceContainer::getSequence", name);
124 }
125 
126 /******************************************************************************/
127 
128 bool MapSequenceContainer::hasSequence(const string& name) const
129 {
130  // Specified sequence name research into all sequences
131  for (map<string, Sequence*>::const_iterator it = sequences_.begin(); it != sequences_.end(); it++)
132  {
133  if (it->second->getName() == name)
134  return true;
135  }
136  return false;
137 }
138 
139 /******************************************************************************/
140 
142 {
143  if (i >= sequences_.size())
144  throw IndexOutOfBoundsException("MapSequenceContainer::getSequence", i, 0, sequences_.size() - 1);
145  map<string, Sequence*>::iterator it = sequences_.begin();
146  for (size_t j = 0; j < i; j++)
147  {
148  it++;
149  }
150  return *it->second;
151 }
152 
153 /******************************************************************************/
154 
156 {
157  // Specified sequence name research into all sequences
158  for (map<string, Sequence*>::iterator it = sequences_.begin(); it != sequences_.end(); it++)
159  {
160  if (it->second->getName() == name)
161  return *it->second;
162  }
163  throw SequenceNotFoundException("MapSequenceContainer::getSequence", name);
164 }
165 
166 /******************************************************************************/
167 
168 const Sequence& MapSequenceContainer::getSequenceByKey(const string& key) const
169 {
170  map<string, Sequence*>::const_iterator it = sequences_.find(key);
171  if (it == sequences_.end())
172  throw SequenceNotFoundException("MapSequenceContainer::getSequenceByKey", key);
173  return *it->second;
174 }
175 
176 /******************************************************************************/
177 
178 size_t MapSequenceContainer::getSequencePosition(const string& name) const
179 {
180  // Specified sequence name research into all sequences
181  size_t pos = 0;
182  for (map<string, Sequence*>::const_iterator it = sequences_.begin(); it != sequences_.end(); it++)
183  {
184  if (it->second->getName() == name)
185  return pos;
186  pos++;
187  }
188 
189  throw SequenceNotFoundException("MapSequenceContainer::getSequencePosition", name);
190 }
191 
192 /******************************************************************************/
193 
194 void MapSequenceContainer::setSequence(size_t i, const Sequence& sequence, bool checkNames)
195 {
196  // Sequence's name existence checking
197  if (checkNames)
198  {
199  size_t j = 0;
200  // For all names in map : throw exception if name already exists
201  for (map<string, Sequence*>::const_iterator it = sequences_.begin(); it != sequences_.end(); it++)
202  {
203  if (it->second->getName() == sequence.getName())
204  if (j != i)
205  throw Exception("MapSequenceContainer::setSequence : Sequence's name already exists in container");
206  j++;
207  }
208  }
209 
210  // New sequence's alphabet and sequence container's alphabet matching verification
211  if (sequence.getAlphabet()->getAlphabetType() == getAlphabet()->getAlphabetType())
212  {
213  // Delete old sequence
214  delete sequences_[getKey(i)];
215  // New sequence insertion in sequence container
216  sequences_[getKey(i)] = dynamic_cast<Sequence*>(sequence.clone());
217  }
218  else
219  throw AlphabetMismatchException("MapSequenceContainer::setSequence", getAlphabet(), sequence.getAlphabet());
220 }
221 
222 /******************************************************************************/
223 
224 void MapSequenceContainer::setSequence(const string& name, const Sequence& sequence, bool checkNames)
225 {
226  // Sequence's name existence checking
227  if (checkNames)
228  {
229  // For all names in map : throw exception if name already exists
230  for (map<string, Sequence*>::const_iterator it = sequences_.begin(); it != sequences_.end(); it++)
231  {
232  if (it->second->getName() == name)
233  if (it->second->getName() != name)
234  throw Exception("MapSequenceContainer::setSequence : Sequence's name already exists in container");
235  }
236  }
237 
238  // New sequence's alphabet and sequence container's alphabet matching verification
239  if (sequence.getAlphabet()->getAlphabetType() == getAlphabet()->getAlphabetType())
240  {
241  // Delete old sequence
242  delete sequences_[name];
243  // New sequence insertion in sequence container
244  sequences_[name] = dynamic_cast<Sequence*>(sequence.clone());
245  }
246  else
247  throw AlphabetMismatchException("MapSequenceContainer::setSequence", getAlphabet(), sequence.getAlphabet());
248 }
249 
250 /******************************************************************************/
251 
252 void MapSequenceContainer::setSequenceByKey(const string& key, const Sequence& sequence, bool checkNames)
253 {
254  // Sequence's name existence checking
255  if (checkNames)
256  {
257  // For all names in map : throw exception if name already exists
258  for (map<string, Sequence*>::const_iterator it = sequences_.begin(); it != sequences_.end(); it++)
259  {
260  if (it->second->getName() == sequence.getName())
261  if (it->first != key)
262  throw Exception("MapSequenceContainer::setSequenceByKey : Sequence's name already exists in container");
263  }
264  }
265 
266  // New sequence's alphabet and sequence container's alphabet matching verification
267  if (sequence.getAlphabet()->getAlphabetType() == getAlphabet()->getAlphabetType())
268  {
269  // Delete old sequence
270  delete sequences_[key];
271  // New sequence insertion in sequence container
272  sequences_[key] = dynamic_cast<Sequence*>(sequence.clone());
273  }
274  else
275  throw AlphabetMismatchException("MapSequenceContainer::setSequenceByKey", getAlphabet(), sequence.getAlphabet());
276 }
277 
278 /******************************************************************************/
279 
281 {
282  if (i >= sequences_.size())
283  throw IndexOutOfBoundsException("MapSequenceContainer::removeSequence", i, 0, sequences_.size() - 1);
284  map<string, Sequence*>::iterator it = sequences_.begin();
285  for (size_t j = 0; j < i; j++)
286  {
287  it++;
288  }
289  Sequence* old = it->second;
290  sequences_.erase(it);
291  return old;
292 }
293 
294 /******************************************************************************/
295 
297 {
298  for (map<string, Sequence*>::iterator it = sequences_.begin(); it != sequences_.end(); it++)
299  {
300  if (it->second->getName() == name)
301  {
302  Sequence* old = it->second;
303  sequences_.erase(it);
304  return old;
305  }
306  }
307  throw SequenceNotFoundException("MapSequenceContainer::removeSequence", name);
308 }
309 
310 /******************************************************************************/
311 
313 {
314  map<string, Sequence*>::iterator it = sequences_.find(key);
315  if (it == sequences_.end())
316  throw SequenceNotFoundException("MapSequenceContainer::removeSequenceByKey", key);
317 
318  Sequence* old = it->second;
319  sequences_.erase(key);
320  return old;
321 }
322 
323 /******************************************************************************/
324 
326 {
327  if (i >= sequences_.size())
328  throw IndexOutOfBoundsException("MapSequenceContainer::deleteSequence", i, 0, sequences_.size() - 1);
329  map<string, Sequence*>::iterator it = sequences_.begin();
330  for (size_t j = 0; j < i; j++)
331  {
332  it++;
333  }
334  delete it->second;
335  sequences_.erase(it);
336 }
337 
338 /******************************************************************************/
339 
340 void MapSequenceContainer::deleteSequence(const string& name)
341 {
342  for (map<string, Sequence*>::iterator it = sequences_.begin(); it != sequences_.end(); it++)
343  {
344  if (it->second->getName() == name)
345  {
346  delete it->second;
347  sequences_.erase(it);
348  return;
349  }
350  }
351  throw SequenceNotFoundException("MapSequenceContainer::deleteSequence", name);
352 }
353 
354 /******************************************************************************/
355 
357 {
358  map<string, Sequence*>::iterator it = sequences_.find(key);
359  if (it == sequences_.end())
360  throw SequenceNotFoundException("MapSequenceContainer::deleteSequenceByKey", key);
361  delete it->second;
362  sequences_.erase(key);
363 }
364 
365 /******************************************************************************/
366 
367 void MapSequenceContainer::addSequence(const string& key, const Sequence& sequence, bool checkNames)
368 {
369  // Sequence's name existence checking
370  if (checkNames)
371  {
372  // For all names in map : throw exception if name already exists
373  for (map<string, Sequence*>::const_iterator it = sequences_.begin(); it != sequences_.end(); it++)
374  {
375  if (it->second->getName() == sequence.getName())
376  throw Exception("MapSequenceContainer::addSequence: Sequence '" + sequence.getName() + ", already exists in container");
377  }
378  }
379 
380  // Check if the key is not used
381  for (map<string, Sequence*>::const_iterator it = sequences_.begin(); it != sequences_.end(); it++)
382  {
383  if (key == it->first)
384  throw Exception("MapSequenceContainer::addSequence: key already in use. (" + key + ")");
385  }
386 
387  // New sequence's alphabet and sequence container's alphabet matching verification
388  if (sequence.getAlphabet()->getAlphabetType() == getAlphabet()->getAlphabetType())
389  sequences_.insert(make_pair(key, dynamic_cast<Sequence*>(sequence.clone())));
390  else
391  throw AlphabetMismatchException("MapSequenceContainer::addSequence", getAlphabet(), sequence.getAlphabet());
392 }
393 
394 /******************************************************************************/
395 
396 vector<string> MapSequenceContainer::getKeys() const
397 {
398  vector<string> keys;
399  for (map<string, Sequence*>::const_iterator it = sequences_.begin(); it != sequences_.end(); it++)
400  {
401  keys.push_back(it->first);
402  }
403  return keys;
404 }
405 
406 /******************************************************************************/
407 
408 string MapSequenceContainer::getKey(size_t pos) const
409 {
410  if (pos >= getNumberOfSequences())
411  throw IndexOutOfBoundsException("MapSequenceContainer::getKey", pos, 0, sequences_.size() - 1);
412  map<string, Sequence*>::const_iterator it = sequences_.begin();
413  for (size_t i = 0; i < pos; i++)
414  {
415  it++;
416  }
417  return it->first;
418 }
419 
420 /******************************************************************************/
421 
422 string MapSequenceContainer::getKey(const string& name) const
423 {
424  try
425  {
426  return getKey(getSequencePosition(name));
427  }
428  catch (SequenceNotFoundException& snfe)
429  {
430  throw SequenceNotFoundException("MapSequenceContainer::getKey", snfe.getSequenceId());
431  }
432 }
433 
434 /******************************************************************************/
435 
436 void MapSequenceContainer::setComments(size_t pos, const Comments& comments)
437 {
438  if (pos >= getNumberOfSequences())
439  throw IndexOutOfBoundsException("MapSequenceContainer::setComments", pos, 0, sequences_.size() - 1);
440  map<string, Sequence*>::iterator it = sequences_.begin();
441  for (size_t i = 0; i < pos; i++)
442  {
443  it++;
444  }
445  it->second->setComments(comments);
446 }
447 
448 /******************************************************************************/
449 
451 {
452  vector<string> names;
453  for (map<string, Sequence*>::const_iterator it = sequences_.begin(); it != sequences_.end(); it++)
454  {
455  names.push_back(it->second->getName());
456  }
457  return names;
458 }
459 
460 /******************************************************************************/
461 
462 void MapSequenceContainer::setSequencesNames(const vector<string>& names, bool checkNames)
463 {
464  if (names.size() != getNumberOfSequences())
465  throw IndexOutOfBoundsException("MapSequenceContainer::setSequenceNames : bad number of names", names.size(), getNumberOfSequences(), getNumberOfSequences());
466  if (checkNames)
467  {
468  // check if there is no repeat names in teh vector
469  for (size_t i = 0; i < names.size(); i++)
470  {
471  for (unsigned int j = 0; j < i; j++)
472  {
473  if (names[j] == names[i])
474  throw Exception("MapSequenceContainer::setSequencesNames: Sequence's name already exists in container");
475  }
476  }
477  }
478  map<string, Sequence*>::iterator it = sequences_.begin();
479  for (size_t i = 0; i < names.size(); i++)
480  {
481  it->second->setName(names[i]);
482  it++;
483  }
484 }
485 
486 /******************************************************************************/
487 
489 {
490  // Delete sequences
491  for (map<string, Sequence*>::iterator it = sequences_.begin(); it != sequences_.end(); it++)
492  {
493  delete it->second;
494  }
495  // Delete all sequence pointers
496  sequences_.clear();
497 }
498 
499 /******************************************************************************/
500 
502 {
504  return msc;
505 }
506 
507 /******************************************************************************/
Partial implementation of the OrderedSequenceContainer interface.
AbstractSequenceContainer & operator=(const AbstractSequenceContainer &sc)
const Alphabet * getAlphabet() const
Get container's alphabet.
Exception thrown when two alphabets do not match.
The Alphabet interface.
Definition: Alphabet.h:131
virtual std::string getAlphabetType() const =0
Identification method.
virtual const Alphabet * getAlphabet() const =0
Get the alphabet associated to the list.
MapSequenceContainer class.
MapSequenceContainer * createEmptyContainer() const
Return a copy of this container, but with no data inside.
void deleteSequence(const std::string &name)
void clear()
Delete all data in the container.
void addSequence(const std::string &key, const Sequence &sequence, bool checkNames=true)
Add a sequence and key.
MapSequenceContainer(const std::map< std::string, Sequence * > &ms, const Alphabet *alpha)
void setSequenceByKey(const std::string &key, const Sequence &sequence, bool checkNames=true)
Set a sequence.
MapSequenceContainer & operator=(const MapSequenceContainer &msc)
Sequence * removeSequence(const std::string &name)
Extract (and remove) a sequence from the container.
size_t getSequencePosition(const std::string &name) const
Get the position of a sequence in sequence container from its name.
Sequence * removeSequenceByKey(const std::string &key)
Remove a sequence.
bool hasSequence(const std::string &name) const
Check if a sequence with a given name is present in the container.
size_t getNumberOfSequences() const
Get the number of sequences in the container.
const Sequence & getSequenceByKey(const std::string &key) const
Get a sequence.
std::vector< std::string > getKeys() const
std::map< std::string, Sequence * > sequences_
std::vector< std::string > getSequencesNames() const
Get all the names of the sequences in the container.
const Sequence & getSequence(const std::string &name) const
Retrieve a sequence object from the container.
void setSequencesNames(const std::vector< std::string > &names, bool checkNames)
Set all sequence names.
Sequence & getSequence_(size_t i)
void deleteSequenceByKey(const std::string &key)
Delete a sequence.
std::string getKey(size_t pos) const
void setSequence(const std::string &name, const Sequence &sequence, bool checkName=true)
Replace a sequence in the container.
virtual void setComments(size_t sequenceIndex, const Comments &comments)=0
Exception thrown when a sequence is not found The sequence not found exception base class.
virtual const std::string getSequenceId() const
Get the id of the sequence that was to be found.
The sequence interface.
Definition: Sequence.h:71
Sequence * clone() const =0
virtual const std::string & getName() const =0
Get the name of this sequence.
This alphabet is used to deal NumericAlphabet.
std::vector< std::string > Comments
Declaration of Comments type.
Definition: Commentable.h:57