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