1 #ifndef OLIGOFAR_CTRANSCRIPT__HPP
2 #define OLIGOFAR_CTRANSCRIPT__HPP
3
4 #include "debug.hpp"
5 #include "defs.hpp"
6
7 BEGIN_OLIGOFAR_SCOPES
8
9 class CTrBase
10 {
11 public:
12 enum EEvent {
13 eEvent_Match = 0x01, // bases match
14 eEvent_Replaced = 0x02, // replacement
15 eEvent_Insertion = 0x03, // query has extra base
16 eEvent_Deletion = 0x04, // subject ahs an extra base
17 eEvent_Splice = 0x05, // few subject bases are skiped with no penalty
18 eEvent_Overlap = 0x06, // same subject bases are mathed twice by different bases of the read
19 eEvent_Padding = 0x07, // CIGAR - for multisequence alignment, no action
20 eEvent_SoftMask = 0x08, // end of the query is not aligned, but is present in SAM/BAM
21 eEvent_HardMask = 0x09, // end of the query is not aligned and is not present in SAM/BAM
22 eEvent_Changed = 0x0a, // allowed replacement (C->T with bisulfite treatment)
23 eEvent_NULL = 0,
24 };
25 static EEvent Char2Event( char x );
Event2Char(EEvent x)26 static char Event2Char( EEvent x ) { return ":MRIDNBPSHC....."[x]; }
27 protected:
28 static char s_char2event[];
29 };
30
Char2Event(char x)31 inline CTrBase::EEvent CTrBase::Char2Event( char x ) {
32 EEvent y = (EEvent)
33 "\x0\x0\x0\x0\x0\x0\x0\x0""\x0\x0\x0\x0\x0\x0\x0\x0" "\x0\x0\x0\x0\x0\x0\x0\x0""\x0\x0\x0\x0\x0\x0\x0\x0"
34 "\x0\x0\x0\x0\x0\x0\x0\x0""\x0\x0\x0\x0\x0\x0\x0\x0" "\x0\x0\x0\x0\x0\x0\x0\x0""\x0\x0\x0\x0\x0\x0\x0\x0"
35 // A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
36 "\x0\x0\x6\xa\x4\x0\x0\x0""\x9\x3\x0\x0\x0\x1\x5\x0" "\x7\x0\x2\x8\x0\x0\x0\x0""\x0\x0\x0\x0\x0\x0\x0\x0"
37 "\x0\x0\x6\xa\x4\x0\x0\x0""\x9\x3\x0\x0\x0\x1\x5\x0" "\x7\x0\x2\x8\x0\x0\x0\x0""\x0\x0\x0\x0\x0\x0\x0\x0"
38 "\x0\x0\x0\x0\x0\x0\x0\x0""\x0\x0\x0\x0\x0\x0\x0\x0" "\x0\x0\x0\x0\x0\x0\x0\x0""\x0\x0\x0\x0\x0\x0\x0\x0"
39 "\x0\x0\x0\x0\x0\x0\x0\x0""\x0\x0\x0\x0\x0\x0\x0\x0" "\x0\x0\x0\x0\x0\x0\x0\x0""\x0\x0\x0\x0\x0\x0\x0\x0"
40 "\x0\x0\x0\x0\x0\x0\x0\x0""\x0\x0\x0\x0\x0\x0\x0\x0" "\x0\x0\x0\x0\x0\x0\x0\x0""\x0\x0\x0\x0\x0\x0\x0\x0"
41 "\x0\x0\x0\x0\x0\x0\x0\x0""\x0\x0\x0\x0\x0\x0\x0\x0" "\x0\x0\x0\x0\x0\x0\x0\x0""\x0\x0\x0\x0\x0\x0\x0\x0"
42 [int( (unsigned char)x)];
43 if( y == eEvent_NULL ) THROW( logic_error, "Unknown CIGAR event char ascii" << int(x) );
44 return y;
45 }
46
47
48 template<int bitst = 4, int bitsc = 12>
49 class CTrItemPacked : public CTrBase
50 {
51 public:
CTrItemPacked()52 CTrItemPacked() : m_event(0), m_count(0) {}
CTrItemPacked(EEvent t,unsigned c=1)53 CTrItemPacked( EEvent t, unsigned c = 1 ) : m_event( t ), m_count( c ) { ASSERT( c <= GetMaxCount() ); }
CTrItemPacked(const CTrItemPacked & other,unsigned cnt)54 CTrItemPacked( const CTrItemPacked& other, unsigned cnt ) : m_event( other.GetEvent() ), m_count( cnt ) { ASSERT( cnt <= GetMaxCount() ); }
CTrItemPacked(const CTrItemPacked & other)55 CTrItemPacked( const CTrItemPacked& other ) : m_event( other.GetEvent() ), m_count( other.GetCount() ) {}
56 template<class TOther>
CTrItemPacked(const TOther & other)57 CTrItemPacked( const TOther& other ) : m_event( other.GetEvent() ), m_count( other.GetCount() ) {
58 if( other.GetCount() > (int)GetMaxCount() ) { THROW( logic_error, "Event count limit exceeded: " << other.GetCount() << " > " << (int)GetMaxCount() << " for event " << Event2Char( other.GetEvent() ) ); } }
AddCount(int count)59 int AddCount( int count ) {
60 unsigned ncnt = count + GetCount();
61 if( ncnt > GetMaxCount() ) {
62 m_count = GetMaxCount();
63 return ncnt - GetMaxCount();
64 } else {
65 m_count = ncnt;
66 return 0;
67 }
68 }
69 template<class TOtherItem>
Add(const TOtherItem & o)70 TOtherItem Add( const TOtherItem& o ) {
71 if( GetCount() == 0 ) m_event = o.GetEvent();
72 else if( o.GetEvent() != GetEvent() ) return o;
73 return TOtherItem( o, AddCount( o.GetCount() ) );
74 }
SetEvent(EEvent ev)75 void SetEvent( EEvent ev ) { m_event = ev; }
GetEvent() const76 EEvent GetEvent() const { return EEvent( m_event ); }
GetCount() const77 int GetCount() const { return m_count; }
GetMaxCount()78 static size_t GetMaxCount() { return ~((~size_t(0)) << bitsc); }
GetCigar(EEvent t)79 static char GetCigar( EEvent t ) { return Event2Char( t ); } // considering that NULL can be at the end only
GetCigar() const80 char GetCigar() const { return GetCigar( GetEvent() ); }
DecrCount()81 CTrItemPacked<bitst,bitsc>& DecrCount() { if( m_count == 0 ) THROW( logic_error, "Attempt to decrement count below 0" ); --m_count; return *this; }
IncrCount()82 CTrItemPacked<bitst,bitsc>& IncrCount() { if( m_count == GetMaxCount() ) THROW( logic_error, "Attempt to increment count above max" ); ++m_count; return *this; }
operator ==(const CTrItemPacked<bitst,bitsc> & other) const83 bool operator == ( const CTrItemPacked<bitst,bitsc>& other ) const { return m_event == other.m_event && m_count == other.m_count; }
operator !=(const CTrItemPacked<bitst,bitsc> & other) const84 bool operator != ( const CTrItemPacked<bitst,bitsc>& other ) const { return m_event != other.m_event || m_count != other.m_count; }
85 protected:
86 unsigned int m_event:bitst;
87 unsigned int m_count:bitsc;
88 };
89
90 template<unsigned bbits, unsigned cbits>
operator <<(std::ostream & out,const CTrItemPacked<bbits,cbits> & ti)91 inline std::ostream& operator << ( std::ostream& out, const CTrItemPacked<bbits,cbits>& ti )
92 {
93 return out << ti.GetCount() << ti.GetCigar();
94 }
95
96 template<class T>
97 class CTrVector : public CTrBase, public vector<T>
98 {
99 public:
100 typedef T value_type;
101 typedef CTrVector<T> self_type;
102
GetMaxItemCount()103 static size_t GetMaxItemCount() { return value_type::GetMaxCount(); }
104
105 template<class TT>
Assign(const TT & tt)106 self_type& Assign( const TT& tt ) { self_type::clear(); return AppendFwd( tt ); }
Reverse()107 self_type& Reverse() { reverse( self_type::begin(), self_type::end() ); return *this; }
108
AppendItem(EEvent t,unsigned cnt)109 self_type& AppendItem( EEvent t, unsigned cnt ) {
110 if( cnt == 0 ) return *this;
111 //ASSERT( t != eEvent_NULL );
112 if( (!self_type::empty()) && self_type::back().GetEvent() == t ) cnt = self_type::back().AddCount( cnt );
113 for( ; cnt > GetMaxItemCount() ; cnt -= GetMaxItemCount() ) push_back( T( t, GetMaxItemCount() ) );
114 if( cnt ) push_back( T( t, cnt ) );
115 return *this;
116 }
117
118 template<class TT>
AppendItem(TT tt)119 self_type& AppendItem( TT tt ) {
120 if( tt.GetCount() == 0 ) return *this;
121 //ASSERT( tt.GetEvent() != eEvent_NULL );
122 if( (!self_type::empty()) && self_type::back().GetEvent() == tt.GetEvent() ) tt = self_type::back().Add( tt );
123 for( ; (unsigned)tt.GetCount() > GetMaxItemCount() ; tt = TT( tt, tt.GetCount() - GetMaxItemCount() ) )
124 push_back( T( tt, GetMaxItemCount() ) );
125 if( tt.GetCount() ) push_back( T( tt ) );
126 return *this;
127 }
128
129 template<class TT>
AppendFwd(const TT & tt)130 self_type& AppendFwd( const TT& tt ) { return Append( tt.begin(), tt.end() ); }
131 template<class TT>
AppendRev(const TT & tt)132 self_type& AppendRev( const TT& tt ) { return Append( tt.rbegin(), tt.rend() ); }
133
134 template<class Iter>
Append(Iter begin,Iter end)135 self_type& Append( Iter begin, Iter end ) {
136 for( ; begin != end ; ++begin ) AppendItem( *begin );
137 return *this;
138 }
139
CTrVector()140 CTrVector() {}
CTrVector(const char * cigar)141 CTrVector( const char * cigar ) { Assign( cigar ); }
CTrVector(const string & cigar)142 CTrVector( const string& cigar ) { Assign( cigar ); }
143 template<class Other>
CTrVector(const Other & other)144 CTrVector( const Other& other ) { AppendFwd( other ); }
145
Assign(const string & cigar)146 self_type& Assign( const string& cigar ) { return Assign( cigar.c_str() ); }
Assign(const char * cigar)147 self_type& Assign( const char * cigar ) {
148 self_type::clear();
149 if( cigar == 0 ) return *this;
150 for( const char * x = cigar; *x; ++x ) {
151 int count = isdigit( *x ) ? strtol( x, const_cast<char**>(&x), 10 ) : 1;
152 EEvent event = Char2Event(*x);
153 if( count > 0 ) AppendItem( event, count );
154 }
155 return *this;
156 }
ComputeLengths() const157 pair<int,int> ComputeLengths() const {
158 int qlen = 0, slen = 0;
159 for( typename self_type::const_iterator iter = self_type::begin(); iter != self_type::end(); ++iter ) {
160 switch( iter->GetEvent() ) {
161 case eEvent_NULL:
162 case eEvent_Padding:
163 case eEvent_SoftMask:
164 case eEvent_HardMask: break;
165 case eEvent_Insertion: qlen += iter->GetCount(); break;
166 case eEvent_Overlap: slen -= iter->GetCount(); break;
167 case eEvent_Splice:
168 case eEvent_Deletion: slen += iter->GetCount(); break;
169 case eEvent_Match:
170 case eEvent_Changed:
171 case eEvent_Replaced: qlen += iter->GetCount(); slen += iter->GetCount(); break;
172 }
173 }
174 return make_pair( qlen, slen );
175 }
ComputeSubjectLength() const176 unsigned ComputeSubjectLength() const {
177 int len = 0;
178 for( typename self_type::const_iterator iter = self_type::begin(); iter != self_type::end(); ++iter ) {
179 switch( iter->GetEvent() ) {
180 case eEvent_NULL:
181 case eEvent_Padding:
182 case eEvent_SoftMask:
183 case eEvent_HardMask:
184 case eEvent_Insertion: break;
185 case eEvent_Overlap: len -= iter->GetCount(); break;
186 case eEvent_Splice:
187 case eEvent_Deletion:
188 case eEvent_Match:
189 case eEvent_Changed:
190 case eEvent_Replaced: len += iter->GetCount(); break;
191 }
192 }
193 ASSERT( len >= 0 );
194 return len;
195 }
196
197 template<class Iter>
Print(ostream & o,Iter begin,Iter end)198 static ostream& Print( ostream& o, Iter begin, Iter end ) {
199 for( Iter i = begin; i != end; ++i ) {
200 if( i->GetCount() ) o << i->GetCount() << i->GetCigar();
201 }
202 return o;
203 }
PrintFwd(ostream & o) const204 ostream& PrintFwd( ostream& o ) const { return Print( o, self_type::begin(), self_type::end() ); }
PrintRev(ostream & o) const205 ostream& PrintRev( ostream& o ) const { return Print( o, self_type::rbegin(), self_type::rend() ); }
ToString() const206 string ToString() const { ostringstream o; PrintFwd( o ); return o.str(); }
207 };
208
209 template<unsigned bbits, unsigned cbits>
operator <<(std::ostream & out,const CTrVector<CTrItemPacked<bbits,cbits>> & tr)210 inline std::ostream& operator << ( std::ostream& out, const CTrVector<CTrItemPacked<bbits,cbits> >& tr )
211 {
212 return tr.PrintFwd( out );
213 }
214
215 template<int bitst = 4, int bitsc = 12>
216 class CTrSequence : public CTrBase
217 {
218 public:
219 // TODO: optimize allocation/deallocation to minimize dry rest
220 typedef CTrSequence<bitst,bitsc> self_type;
221
222 typedef CTrItemPacked<bitst,bitsc> value_type;
223 typedef CTrItemPacked<bitst,bitsc> data_type;
224
225 typedef CTrItemPacked<bitst,bitsc> * self_pointer_type;
226 typedef CTrItemPacked<bitst,bitsc> & self_reference_type;
227
228 typedef const CTrItemPacked<bitst,bitsc> * self_const_pointer_type;
229 typedef const CTrItemPacked<bitst,bitsc> & self_const_reference_type;
230
231 typedef value_type * pointer_type;
232 typedef value_type & reference_type;
233 typedef const value_type * const_pointer_type;
234 typedef const value_type & const_reference_type;
235
236 typedef pointer_type iterator;
237 typedef const_pointer_type const_iterator;
238
239 enum { kSizeIncrement = 4 };
240
241 template<class Item>
242 class C_ReverseIterator
243 {
244 public:
245 typedef Item value_type;
246 typedef Item * pointer_type;
247 typedef Item & reference_type;
248 typedef C_ReverseIterator<Item> self_type;
249
C_ReverseIterator(Item * i=0)250 C_ReverseIterator( Item * i = 0 ) : m_item( i ) {}
C_ReverseIterator(const self_type * i)251 C_ReverseIterator( const self_type* i ) : m_item( i->m_item ) {}
C_ReverseIterator(const self_type & i)252 C_ReverseIterator( const self_type& i ) : m_item( i.m_item ) {}
operator pointer_type() const253 operator pointer_type () const { return m_item; }
operator ->() const254 pointer_type operator -> () const { return m_item; }
operator *() const255 reference_type operator * () const { return *m_item; }
operator ++()256 self_type& operator ++ () { --m_item; return *this; }
operator --()257 self_type& operator -- () { ++m_item; return *this; }
operator ++(int)258 self_type operator ++ ( int ) { self_type ret( *this ); --m_item; return ret; }
operator --(int)259 self_type operator -- ( int ) { self_type ret( *this ); ++m_item; return ret; }
operator +=(int i)260 self_type& operator += ( int i ) { m_item -= i; return *this; }
operator -=(int i)261 self_type& operator -= ( int i ) { m_item += i; return *this; }
operator ==(const self_type & other) const262 bool operator == ( const self_type& other ) const { return m_item == other.m_item; }
operator !=(const self_type & other) const263 bool operator != ( const self_type& other ) const { return m_item != other.m_item; }
operator <(const self_type & other) const264 bool operator < ( const self_type& other ) const { return m_item > other.m_item; }
operator >(const self_type & other) const265 bool operator > ( const self_type& other ) const { return m_item < other.m_item; }
operator <=(const self_type & other) const266 bool operator <= ( const self_type& other ) const { return m_item >= other.m_item; }
operator >=(const self_type & other) const267 bool operator >= ( const self_type& other ) const { return m_item <= other.m_item; }
operator -(const self_type & a,const self_type & b)268 friend int operator - ( const self_type& a, const self_type& b ) { return b.m_item - a.m_item; }
operator -(const self_type & a,int b)269 friend self_type operator - ( const self_type& a, int b ) { return self_type(a.m_item + b); }
operator +(const self_type & a,int b)270 friend self_type operator + ( const self_type& a, int b ) { return self_type(a.m_item - b); }
operator +(int b,const self_type & a)271 friend self_type operator + ( int b, const self_type& a ) { return self_type(a.m_item - b); }
272 protected:
273 Item * m_item;
274 };
275
276 typedef C_ReverseIterator<value_type> reverse_iterator;
277 typedef C_ReverseIterator<const value_type> const_reverse_iterator;
278
~CTrSequence()279 ~CTrSequence() { free( m_data ); }
CTrSequence()280 CTrSequence() : m_data(0) {}
CTrSequence(const self_type & other)281 CTrSequence( const self_type& other ) : m_data(0) { Assign( other ); }
CTrSequence(const char * trans)282 CTrSequence( const char * trans ) : m_data(0) { Assign( trans ); }
CTrSequence(const string & trans)283 CTrSequence( const string& trans ) : m_data(0) { Assign( trans ); }
284
size() const285 size_t size() const { return m_data ? m_data->GetCount() : 0; }
capacity() const286 size_t capacity() const { return size(); } //m_data ? m_data->GetCount() | (kSizeIncrement - 1) : 0; }
287
front()288 reference_type front() { return m_data[1]; }
back()289 reference_type back() { return m_data[size()]; } // since size() is always 1 less then allocated, and first element contains size
front() const290 const_reference_type front() const { return m_data[1]; }
back() const291 const_reference_type back() const { return m_data[size()]; }
292
begin()293 iterator begin() { return m_data ? m_data + 1 : 0; }
end()294 iterator end() { return m_data ? m_data + size() + 1 : 0; }
begin() const295 const_iterator begin() const { return m_data ? m_data + 1 : 0; }
end() const296 const_iterator end() const { return m_data ? m_data + size() + 1 : 0; }
297
rbegin()298 reverse_iterator rbegin() { return m_data ? m_data + size() : 0; }
rend()299 reverse_iterator rend() { return m_data ? m_data : 0; }
rbegin() const300 const_reverse_iterator rbegin() const { return m_data ? m_data + size() : 0; }
rend() const301 const_reverse_iterator rend() const { return m_data ? m_data : 0; }
302
clear()303 void clear() { free( m_data ); m_data = 0; } //delete[] m_data; m_data = 0; }
resize(unsigned long x)304 void resize( unsigned long x ) {
305 ASSERT( x <= size() );
306 ASSERT( x >= 0 );
307 if( x == size() ) return;
308 if( x == 0 ) clear();
309 else m_data[0] = value_type( eEvent_NULL, x );
310 }
reserve(unsigned long)311 void reserve( unsigned long ) {}
erase(iterator from,iterator to)312 void erase( iterator from, iterator to ) {
313 copy( to, end(), from );
314 resize( size() - ( to - from ) );
315 }
316
operator !=(const self_type & other) const317 bool operator != ( const self_type& other ) const { return !operator == ( other ); }
operator ==(const self_type & other) const318 bool operator == ( const self_type& other ) const {
319 const_iterator a = begin(), b = other.begin();
320 const_iterator A = end(), B = other.end();
321 while( a != A && b != B ) if( *a++ != *b++ ) return false;
322 return( a == A && b == B );
323 }
324
operator =(const self_type & other)325 self_type& operator = ( const self_type& other ) { return Assign( other ); }
326
operator [](int i)327 reference_type operator [] ( int i ) { return m_data[i + 1]; }
operator [](int i) const328 const_reference_type operator [] ( int i ) const { return m_data[i + 1]; }
329
AppendItem(const value_type & value)330 self_type& AppendItem( const value_type& value ) {
331 if( value.GetCount() == 0 ) return *this;
332 if( value.GetEvent() == eEvent_NULL ) return *this;
333 if( m_data == 0 ) {
334 m_data = (pointer_type)malloc( sizeof( value_type ) * 2 ); // allocate two items at once - for metadata and for first element
335 //m_data = new value_type[kSizeIncrement];
336 m_data[0] = value_type( eEvent_NULL, 1 );
337 m_data[1] = value;
338 } else {
339 ASSERT( size() > 0 );
340 reference_type b = back();
341 value_type v = b.Add( value );
342 if( v.GetCount() ) {
343 size_t s = size();
344 m_data = (pointer_type)realloc( m_data, (s + 2)*sizeof( value_type ) );
345 m_data[s + 1] = v;
346 ASSERT( m_data[0].GetCount() == (int)s );
347 m_data[0].IncrCount();
348 }
349 }
350 return *this;
351 }
AppendItem(EEvent ev,unsigned cnt)352 self_type& AppendItem( EEvent ev, unsigned cnt ) {
353 if( ev == eEvent_NULL ) return *this;
354 if( cnt <= 0 ) return *this;
355 while( cnt > value_type::GetMaxCount() ) {
356 AppendItem( value_type( ev, value_type::GetMaxCount() ) );
357 cnt -= value_type::GetMaxCount();
358 }
359 return AppendItem( value_type( ev, cnt ) );
360 }
361 template<class Iter>
Append(const Iter & begin,const Iter & end)362 self_type& Append( const Iter& begin, const Iter& end ) {
363 for( Iter x = begin, X = end; x != X; ++x ) AppendItem( *x );
364 return *this;
365 }
AppendFwd(const self_type & other)366 self_type& AppendFwd( const self_type& other ) {
367 Append( other.begin(), other.end() );
368 return *this;
369 }
AppendRev(const self_type & other)370 self_type& AppendRev( const self_type& other ) {
371 Append( other.rbegin(), other.rend() );
372 return *this;
373 }
Assign(const string & other)374 self_type& Assign( const string& other ) { return Assign( other.c_str() ); }
Assign(const self_type & other)375 self_type& Assign( const self_type& other ) {
376 if( &other == this ) return *this;
377 //delete[] m_data;
378 if( m_data ) { free( m_data ); m_data = 0; }
379 if( int sz = other.size() ) {
380 m_data = (pointer_type)malloc( (1 + sz) * sizeof( value_type ) );
381 // m_data = new value_type[(sz | (kSizeIncrement - 1)) + 1];
382 copy( other.m_data, other.m_data + sz + 1, m_data );
383 }
384 else m_data = 0;
385 return *this;
386 }
Assign(const CTrVector<value_type> & other)387 self_type& Assign( const CTrVector<value_type>& other ) {
388 if( m_data ) { free( m_data ); m_data = 0; }
389 for( typename CTrVector<value_type>::const_iterator o = other.begin(); o != other.end(); ++o ) AppendItem( *o );
390 return *this;
391 }
Assign(const char * other)392 self_type& Assign( const char * other ) {
393 //delete[] m_data;
394 if( m_data ) { free( m_data ); m_data = 0; }
395 if( !other ) return *this;
396 for( const char * x = other; *x; ++x ) {
397 unsigned cnt = isdigit( *x ) ? strtol( x, const_cast<char**>( &x ), 10 ) : 1;
398 EEvent e = Char2Event( *x );
399 if( e == eEvent_NULL ) THROW( runtime_error, "Undefined CIGAR char " << (isprint( *x ) ? *x : ' ') << " (ascii" << int(*x) << ") in [" << other << "]" );
400 while( cnt > value_type::GetMaxCount() ) AppendItem( value_type( e, value_type::GetMaxCount() ) );
401 if( cnt > 0 ) AppendItem( value_type( e, cnt ) );
402 }
403 return *this;
404 }
Reverse()405 self_type& Reverse() {
406 if( m_data ) reverse( m_data + 1, m_data + 1 + m_data->GetCount() );
407 return *this;
408 }
409 template<class Iter>
Print(ostream & o,Iter begin,Iter end)410 static ostream& Print( ostream& o, Iter begin, Iter end ) {
411 for( Iter i = begin; i != end; ++i ) {
412 if( i->GetCount() ) o << i->GetCount() << i->GetCigar();
413 }
414 return o;
415 }
ComputeSubjectLength() const416 unsigned ComputeSubjectLength() const {
417 int len = 0;
418 for( typename self_type::const_iterator iter = self_type::begin(); iter != self_type::end(); ++iter ) {
419 switch( iter->GetEvent() ) {
420 case eEvent_NULL:
421 case eEvent_Padding:
422 case eEvent_SoftMask:
423 case eEvent_HardMask:
424 case eEvent_Insertion: break;
425 case eEvent_Overlap: len -= iter->GetCount(); break;
426 case eEvent_Splice:
427 case eEvent_Deletion:
428 case eEvent_Match:
429 case eEvent_Changed:
430 case eEvent_Replaced: len += iter->GetCount(); break;
431 }
432 }
433 ASSERT( len >= 0 );
434 return len;
435 }
ComputeLengths() const436 pair<int,int> ComputeLengths() const {
437 int qlen = 0, slen = 0;
438 for( typename self_type::const_iterator iter = self_type::begin(); iter != self_type::end(); ++iter ) {
439 switch( iter->GetEvent() ) {
440 case eEvent_NULL:
441 case eEvent_Padding:
442 case eEvent_SoftMask:
443 case eEvent_HardMask: break;
444 case eEvent_Insertion: qlen += iter->GetCount(); break;
445 case eEvent_Overlap: slen -= iter->GetCount(); break;
446 case eEvent_Splice:
447 case eEvent_Deletion: slen += iter->GetCount(); break;
448 case eEvent_Match:
449 case eEvent_Changed:
450 case eEvent_Replaced: qlen += iter->GetCount(); slen += iter->GetCount(); break;
451 }
452 }
453 return make_pair( qlen, slen );
454 }
PrintFwd(ostream & o) const455 ostream& PrintFwd( ostream& o ) const { return Print( o, self_type::begin(), self_type::end() ); }
PrintRev(ostream & o) const456 ostream& PrintRev( ostream& o ) const { return Print( o, self_type::rbegin(), self_type::rend() ); }
457
ToString() const458 string ToString() const { ostringstream o; PrintFwd( o ); return o.str(); }
459 protected:
460 // data structure: first item should be NULL with count equal to number of items in list
461 pointer_type m_data;
462 };
463
464 template<unsigned bbits, unsigned cbits>
operator <<(std::ostream & out,const CTrSequence<bbits,cbits> & tr)465 inline std::ostream& operator << ( std::ostream& out, const CTrSequence<bbits,cbits>& tr )
466 {
467 return tr.PrintFwd( out );
468 }
469
470 template<class Iter>
ComputeDistance(Iter begin,Iter end)471 int ComputeDistance( Iter begin, Iter end )
472 {
473 int ret = 0;
474 for( ; begin != end; ++begin )
475 switch( begin->GetEvent() ) {
476 case CTrBase::eEvent_Insertion:
477 case CTrBase::eEvent_Deletion:
478 case CTrBase::eEvent_Replaced: ret += begin-> GetCount();
479 default: ;
480 }
481 return ret;
482 }
483
484 template<class Container>
ComputeDistance(const Container & cont)485 int ComputeDistance( const Container& cont )
486 {
487 return ComputeDistance( cont.begin(), cont.end() );
488 }
489
490 typedef CTrItemPacked<4,12> TTrItem;
491 typedef CTrVector<TTrItem> TTrVector;
492 //typedef CTrVector<TTrItem> TTrSequence;
493 typedef CTrSequence<4,12> TTrSequence;
494
495 END_OLIGOFAR_SCOPES
496
497 #endif
498