bpp-seq3  3.0.0
SequenceWithAnnotation.cpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: The Bio++ Development Group
2 //
3 // SPDX-License-Identifier: CECILL-2.1
4 
5 #include <Bpp/Text/TextTools.h>
6 
8 #include "SequenceWithAnnotation.h" // class's header file
9 #include "StringSequenceTools.h"
10 
11 using namespace bpp;
12 
13 // From the STL:
14 #include <iostream>
15 
16 using namespace std;
17 
18 /******************************************************************************/
19 
20 void SequenceWithAnnotation::setContent(const std::string& sequence)
21 {
22  IntSymbolListEditionEvent event(this);
23  fireBeforeSequenceChanged(event);
24  // Remove blanks in sequence
25  auto alphaPtr = getAlphabet();
26  setContent(StringSequenceTools::codeSequence(TextTools::removeWhiteSpaces(sequence), alphaPtr));
27  // Warning, an exception may be thrown here!
28  fireAfterSequenceChanged(event);
29 }
30 
31 /******************************************************************************/
32 
34 {
35  // Size verification
36  size_t seqSize = content_.size();
37  if (newSize == seqSize)
38  return;
39 
40  if (newSize < seqSize)
41  {
42  IntSymbolListDeletionEvent event(this, newSize, seqSize - newSize);
43  fireBeforeSequenceDeleted(event);
44  content_.resize(newSize);
45  fireAfterSequenceDeleted(event);
46  return;
47  }
48 
49  // Add gaps up to specified size
50  IntSymbolListInsertionEvent event(this, seqSize, newSize - seqSize);
51  fireBeforeSequenceInserted(event);
52  int gap = getAlphabet()->getGapCharacterCode();
53  while (content_.size() < newSize)
54  content_.push_back(gap);
55  fireAfterSequenceInserted(event);
56 }
57 
58 /******************************************************************************/
59 
61 {
62  // Size verification
63  size_t seqSize = content_.size();
64  if (newSize == seqSize)
65  return;
66 
67  if (newSize < seqSize)
68  {
69  // We must truncate sequence from the left.
70  IntSymbolListDeletionEvent event(this, 0, seqSize - newSize);
71  fireBeforeSequenceDeleted(event);
72  content_.erase(content_.begin(), content_.begin() + static_cast<ptrdiff_t>(seqSize - newSize));
73  fireAfterSequenceDeleted(event);
74  return;
75  }
76 
77  // Add gaps up to specified size
78  IntSymbolListInsertionEvent event(this, 0, newSize - seqSize);
79  fireBeforeSequenceInserted(event);
80  int gap = getAlphabet()->getGapCharacterCode();
81  content_.insert(content_.begin(), newSize - seqSize, gap);
82  fireAfterSequenceInserted(event);
83 }
84 
85 /******************************************************************************/
86 
88 {
89  if (seq.getAlphabet()->getAlphabetType() != getAlphabet()->getAlphabetType())
90  throw AlphabetMismatchException("SequenceWithAnnotation::append", getAlphabet(), seq.getAlphabet());
91  IntSymbolListInsertionEvent event(this, content_.size(), seq.size());
92  fireBeforeSequenceInserted(event);
93  for (size_t i = 0; i < seq.size(); ++i)
94  {
95  content_.push_back(seq[i]);
96  }
97 
98  fireAfterSequenceInserted(event);
99 }
100 
101 void SequenceWithAnnotation::append(const std::vector<int>& content)
102 {
103  IntSymbolListInsertionEvent event(this, content_.size(), content.size());
104  fireBeforeSequenceInserted(event);
105  // Check list for incorrect characters
106  for (auto i : content)
107  {
108  if (!getAlphabet()->isIntInAlphabet(i))
109  throw BadIntException(i, "SequenceWithAnnotation::append", getAlphabet());
110  }
111  // SequenceWithAnnotation is valid:
112  for (auto i : content)
113  {
114  content_.push_back(i);
115  }
116 
117  fireAfterSequenceInserted(event);
118 }
119 
120 void SequenceWithAnnotation::append(const std::vector<std::string>& content)
121 {
122  IntSymbolListInsertionEvent event(this, content_.size(), content.size());
123  fireBeforeSequenceInserted(event);
124  // Check list for incorrect characters
125  for (auto i : content)
126  {
127  if (!getAlphabet()->isCharInAlphabet(i))
128  throw BadCharException(i, "SequenceWithAnnotation::append", getAlphabet());
129  }
130 
131  // SequenceWithAnnotation is valid:
132  for (auto i : content)
133  {
134  content_.push_back(getAlphabet()->charToInt(i));
135  }
136 
137  fireAfterSequenceInserted(event);
138 }
139 
140 void SequenceWithAnnotation::append(const std::string& content)
141 {
142  auto alphaPtr = getAlphabet();
143  append(StringSequenceTools::codeSequence(content, alphaPtr));
144 }
145 
146 /******************************************************************************/
147 
149 {
150  vector<string> types;
151  for (unsigned int i = 0; i < getNumberOfListeners(); ++i)
152  {
153  try
154  {
155  const SequenceAnnotation& anno = dynamic_cast<const SequenceAnnotation&>(listener(i));
156  types.push_back(anno.getType());
157  }
158  catch (bad_cast&)
159  {}
160  }
161  return types;
162 }
163 
164 /******************************************************************************/
165 
167 {
168  // Sequence's alphabets matching verification
169  if ((swa.getAlphabet()->getAlphabetType()) != (getAlphabet()->getAlphabetType()))
170  throw AlphabetMismatchException("SequenceWithAnnotation::merge: Sequence's alphabets don't match ", swa.getAlphabet(), getAlphabet());
171 
172  // Sequence's names matching verification
173  if (swa.getName() != getName())
174  throw Exception ("SequenceWithAnnotation::merge: Sequence's names don't match");
175 
176  // Concatenate sequences and send result
177  propagateEvents(false);
178  append(swa.getContent());
179  propagateEvents(true);
180 
181  // Try to merge annotations.
182  // First start with annotations in this sequence:
183  vector<string> types = getAnnotationTypes();
184  vector<string> newTypes = swa.getAnnotationTypes();
185  for (unsigned int i = 0; i < types.size(); ++i)
186  {
187  vector<string>::iterator it = find(newTypes.begin(), newTypes.end(), types[i]);
188  if (it != newTypes.end())
189  {
190  // Merge annotations:
191  annotation(types[i]).merge(swa.annotation(types[i]));
192  // Remove annotation from the list:
193  newTypes.erase(it);
194  }
195  else
196  {
197  // Extend annotation to the right:
198  unique_ptr<SequenceAnnotation> anno(annotation(types[i]).clone());
199  anno->init(swa);
200  annotation(types[i]).merge(*anno);
201  }
202  }
203  // Now look for annotations in the input sequence:
204  for (unsigned int i = 0; i < newTypes.size(); ++i)
205  {
206  // Extend annotation from the left:
207  shared_ptr<SequenceAnnotation> anno(swa.annotation(newTypes[i]).clone());
208  anno->init(*this);
209  anno->merge(swa.annotation(newTypes[i]));
210  addAnnotation(anno);
211  }
212 }
213 
214 
215 /******************************************************************************/
const std::string & getName() const override
Get the name of this sequence.
Definition: CoreSequence.h:170
Exception thrown when two alphabets do not match.
An alphabet exception thrown when trying to specify a bad char to the alphabet.
An alphabet exception thrown when trying to specify a bad int to the alphabet.
virtual std::shared_ptr< const Alphabet > getAlphabet() const =0
Get the alphabet associated to the list.
virtual size_t size() const =0
Get the number of elements in the list.
virtual void setContent(const std::vector< T > &list)=0
Set the whole content of the list.
Interface for sequence annotations.
virtual const std::string & getType() const =0
virtual SequenceAnnotation * clone() const override=0
The sequence interface.
Definition: Sequence.h:34
An implementation of the Sequence interface that supports annotation.
void setToSizeL(size_t newSize) override
Set up the size of a sequence from the left side.
void append(const SequenceInterface &seq) override
Append the content of a sequence to the current one.
virtual const SequenceAnnotation & annotation(const std::string &type) const
virtual std::vector< std::string > getAnnotationTypes() const
void setToSizeR(size_t newSize) override
Set up the size of a sequence from the right side.
virtual void merge(const SequenceWithAnnotation &swa)
Merge a sequence with the current one.
static std::vector< int > codeSequence(const std::string &sequence, std::shared_ptr< const Alphabet > &alphabet)
Convert a string sequence to a vector of int.
virtual const std::vector< T > & getContent() const =0
std::string removeWhiteSpaces(const std::string &s)
This alphabet is used to deal NumericAlphabet.