1 #ifndef OLIGOFAR_CSEQCODING__HPP
2 #define OLIGOFAR_CSEQCODING__HPP
3
4 #include "defs.hpp"
5 #include <cmath>
6
7 BEGIN_OLIGOFAR_SCOPES
8
9 class CIupacnaBase;
10 class CNcbipnaBase;
11 class CNcbiqnaBase;
12 class CNcbi8naBase;
13 class CNcbi4naBase;
14 class CNcbi2naBase;
15 class CColorTwoBase;
16
17 class CSeqCoding
18 {
19 public:
20 enum ECoding {
21 eCoding_iupacna,
22 eCoding_ncbipna,
23 eCoding_ncbi8na,
24 eCoding_ncbi4na,
25 eCoding_ncbi2na,
26 eCoding_ncbiqna,
27 eCoding_colorsp
28 };
29 enum EStrand {
30 eStrand_pos = 0,
31 eStrand_neg = 1
32 };
33 // NB: following function should be rewritten if values of EStrand constants are different from 0 (+) and 1 (-)
operator ^(EStrand a,EStrand b)34 friend EStrand operator ^ ( EStrand a, EStrand b ) { return EStrand( int(a) ^ int(b) ); }
35 };
36
37 class CIupacnaBase : public CSeqCoding
38 {
39 public:
CIupacnaBase(const char * c,EStrand strand)40 CIupacnaBase( const char * c, EStrand strand ) : m_base( *c ) { if( strand == eStrand_neg ) m_base = s_complement[(int)m_base]; }
CIupacnaBase(const char * c)41 CIupacnaBase( const char * c ) : m_base( *c ) {}
CIupacnaBase(char c)42 CIupacnaBase( char c ) : m_base( c ) {}
43 CIupacnaBase( const CNcbi8naBase& );
44 CIupacnaBase( const CNcbi4naBase& );
45 CIupacnaBase( const CNcbi2naBase& );
46 CIupacnaBase( const CNcbiqnaBase& , int cutoff = 5 );
47 CIupacnaBase( const CNcbipnaBase& , int score = 127 );
48 CIupacnaBase( const CColorTwoBase& b );
49 CIupacnaBase( const CIupacnaBase& b, const CColorTwoBase& c );
Complement() const50 CIupacnaBase Complement() const { return s_complement[(int)m_base]; }
Get(EStrand strand) const51 CIupacnaBase Get( EStrand strand ) const { return strand == eStrand_neg ? Complement() : *this; }
operator char() const52 operator char () const { return m_base; }
Any()53 static CIupacnaBase Any() { return CIupacnaBase('N'); }
BytesPerBase()54 static int BytesPerBase() { return 1; }
55 protected:
56 char m_base;
57 static char s_complement[];
58 };
59
60 class CNcbipnaBase : public CSeqCoding
61 {
62 public:
CNcbipnaBase(const char * base,EStrand strand)63 CNcbipnaBase( const char * base, EStrand strand ) { if( strand == eStrand_neg ) { copy( base + 4, base, m_base ); m_base[4] = base[4]; } else copy( base, base+5, m_base ); }
CNcbipnaBase(const char * base)64 CNcbipnaBase( const char * base ) { copy( base, base+5, m_base ); }
CNcbipnaBase(const unsigned char * base)65 CNcbipnaBase( const unsigned char * base ) { copy( base, base+5, m_base ); }
66 CNcbipnaBase( const CIupacnaBase& b );
CNcbipnaBase(const CNcbi8naBase & b)67 CNcbipnaBase( const CNcbi8naBase& b ) { x_Init( b ); }
68 CNcbipnaBase( const CNcbi4naBase& b );
69 CNcbipnaBase( const CNcbi2naBase& );
70 CNcbipnaBase( const CNcbiqnaBase& );
CNcbipnaBase(const CColorTwoBase & b)71 CNcbipnaBase( const CColorTwoBase& b ) { THROW( logic_error, "CNcbipnaBase( CColorTwoBase ) should not be called" ); }
operator char() const72 operator char () const { THROW( logic_error, "CNcbiqnaBase::operator char () should not be called!" ); }
operator const char*() const73 operator const char * () const { return m_base; }
operator [](int i) const74 unsigned char operator [] (int i) const { return m_base[i]; }
Complement() const75 CNcbipnaBase Complement() const { return CNcbipnaBase( m_base, eStrand_neg ); }
Get(EStrand strand) const76 CNcbipnaBase Get( EStrand strand ) const { return strand == eStrand_neg ? Complement() : *this; }
BytesPerBase()77 static int BytesPerBase() { return 5; }
78 protected:
79 void x_Init( const CNcbi8naBase& );
80 char m_base[5]; // pointer will take 4 bytes in 32-bit architecture - so would save almost nothing
81 };
82
83 class CNcbiqnaBase : public CSeqCoding
84 {
85 public:
CNcbiqnaBase(const char * base,EStrand strand)86 CNcbiqnaBase( const char * base, EStrand strand ): m_base( *base ) { if( strand == eStrand_neg ) m_base = m_base ^ '\x03'; }
CNcbiqnaBase(const char * c)87 CNcbiqnaBase( const char * c ) : m_base( *c ) {}
CNcbiqnaBase(char c)88 CNcbiqnaBase( char c ) : m_base( c ) {}
CNcbiqnaBase(int c)89 CNcbiqnaBase( int c ) : m_base( c ) {}
90 CNcbiqnaBase( const CNcbipnaBase& b );
91 CNcbiqnaBase( const CNcbi8naBase& b, unsigned score = 63 );
92 CNcbiqnaBase( const CNcbi4naBase& b, unsigned score = 63 );
93 CNcbiqnaBase( const CNcbi2naBase& b, unsigned score = 63 );
94 CNcbiqnaBase( const CIupacnaBase& b, unsigned score = 63 );
CNcbiqnaBase(const CColorTwoBase & b)95 CNcbiqnaBase( const CColorTwoBase& b ) { THROW( logic_error, "CNcbiqnaBase( CColorTwoBase ) should not be called" ); }
Complement() const96 CNcbiqnaBase Complement() const { return m_base ^ '\x03'; }
Get(EStrand strand) const97 CNcbiqnaBase Get( EStrand strand ) const { return ( strand == eStrand_neg ) ? Complement() : *this; }
operator char() const98 operator char () const { return m_base; }
GetPhrapScore() const99 int GetPhrapScore() const { return ((unsigned char)m_base) >> 2; }
100 static char AdjustScore( int score );
Any()101 static CNcbiqnaBase Any() { return CNcbiqnaBase( 0 ); }
BytesPerBase()102 static int BytesPerBase() { return 1; }
103 protected:
104 char m_base;
105 };
106
107 class CNcbi8naBase : public CSeqCoding
108 {
109 public:
110 enum EBase { fBase_A = 0x01, fBase_C = 0x02, fBase_G = 0x04, fBase_T = 0x08 };
CNcbi8naBase(const char * c,EStrand strand)111 CNcbi8naBase( const char * c, EStrand strand ) : m_base( *c ) { if( strand == eStrand_neg ) m_base = s_complement[(int)m_base]; }
CNcbi8naBase(const char * c)112 CNcbi8naBase( const char * c ) : m_base( *c ) {}
113 CNcbi8naBase( char c, EStrand strand = eStrand_pos );
114 CNcbi8naBase( int c, EStrand strand = eStrand_pos );
115 CNcbi8naBase( unsigned int c, EStrand strand = eStrand_pos );
116 CNcbi8naBase( const CIupacnaBase& b );
117 CNcbi8naBase( const CNcbipnaBase& b, int score = 127 );
118 CNcbi8naBase( const CNcbiqnaBase& b, int cutoff = 5 );
CNcbi8naBase(const CNcbi8naBase & b,int)119 CNcbi8naBase( const CNcbi8naBase& b, int ) : m_base( b ) {}
120 CNcbi8naBase( const CNcbi4naBase& b );
121 CNcbi8naBase( const CNcbi2naBase& b );
CNcbi8naBase(const CColorTwoBase & b)122 CNcbi8naBase( const CColorTwoBase& b ) { THROW( logic_error, "CNcbi8naBase( CColorTwoBase ) should not be called" ); }
123 CNcbi8naBase( const CNcbi8naBase& b, const CColorTwoBase& c );
124 CNcbi8naBase Complement() const;
Get(EStrand strand) const125 CNcbi8naBase Get( EStrand strand ) const { return ( strand == eStrand_neg ) ? Complement() : *this; }
IsAmbiguous() const126 bool IsAmbiguous() const { return GetAltCount() > 1; }
GetAltCount() const127 int GetAltCount() const { return s_altCount[(int)m_base]; }
operator char() const128 operator char () const { return m_base; }
Any()129 static CNcbi8naBase Any() { return CNcbi8naBase( '\x0f' ); }
BytesPerBase()130 static int BytesPerBase() { return 1; }
131 CNcbi2naBase GetSmallestNcbi2na() const;
132 protected:
133 char m_base;
134 static char s_fromIupacna[];
135 static char s_complement[];
136 static char s_altCount[];
137 static char s_smallestNcbi2na[];
138 };
139
140 class CNcbi4naBase : public CNcbi8naBase
141 {
142 public:
CNcbi4naBase(const CNcbi8naBase & b)143 CNcbi4naBase( const CNcbi8naBase& b ) : CNcbi8naBase( b ) {}
144 };
145
146 class CNcbi2naBase : public CSeqCoding
147 {
148 public:
CNcbi2naBase(const char * c,EStrand strand)149 CNcbi2naBase( const char * c, EStrand strand ) : m_base( *c ) { if( strand == eStrand_neg ) m_base = '\x03' ^ m_base; }
CNcbi2naBase(const char * c)150 CNcbi2naBase( const char * c ) : m_base( *c ) {}
CNcbi2naBase(char c)151 CNcbi2naBase( char c ) : m_base( c ) {}
CNcbi2naBase(int c)152 CNcbi2naBase( int c ) : m_base( c ) {}
CNcbi2naBase(unsigned int c)153 CNcbi2naBase( unsigned int c ) : m_base( c ) {}
154 CNcbi2naBase( const CNcbipnaBase& b, int score = 127 );
155 CNcbi2naBase( const CIupacnaBase& b );
156 CNcbi2naBase( const CNcbi8naBase& b );
157 CNcbi2naBase( const CNcbi4naBase& b );
158 CNcbi2naBase( const CNcbiqnaBase& b );
operator char() const159 operator char () const { return m_base; }
Complement() const160 CNcbi2naBase Complement() const { return '\x03' ^ m_base; }
Get(EStrand strand) const161 CNcbi2naBase Get( EStrand strand ) const { return ( strand == eStrand_neg ) ? Complement() : *this; }
162 protected:
163 char m_base;
164 static char s_iupacnaTable[];
165 static char s_ncbi8naTable[];
166 };
167
168 class CColorTwoBase : public CSeqCoding
169 {
170 public:
171 enum EColorHi { eColor_BLUE = 0x00, eColor_GREEN = 0x10, eColor_YELLOW = 0x20, eColor_RED = 30 };
172 enum EFromASCII { eFromASCII };
CColorTwoBase(char c)173 CColorTwoBase( char c ) : m_base( c ) {}
CColorTwoBase(char c,EStrand)174 CColorTwoBase( char c, EStrand ) : m_base( c ) {}
CColorTwoBase(const char * c)175 CColorTwoBase( const char * c ) : m_base( *c ) {}
CColorTwoBase(const char * c,EStrand)176 CColorTwoBase( const char * c, EStrand ) : m_base( *c ) {}
CColorTwoBase(EFromASCII,char c)177 CColorTwoBase( EFromASCII, char c ) { x_Init( c ); }
CColorTwoBase(CNcbi2naBase b)178 CColorTwoBase( CNcbi2naBase b ) : m_base( CNcbi8naBase( b ) ) {}
CColorTwoBase(CNcbiqnaBase b)179 CColorTwoBase( CNcbiqnaBase b ) : m_base( CNcbi8naBase( b ) ) {}
CColorTwoBase(CNcbi8naBase b)180 CColorTwoBase( CNcbi8naBase b ) : m_base( b ) {}
CColorTwoBase(CNcbipnaBase b)181 CColorTwoBase( CNcbipnaBase b ) : m_base( CNcbi8naBase(b) ) {}
CColorTwoBase(CNcbi2naBase prev,CNcbi2naBase b)182 CColorTwoBase( CNcbi2naBase prev, CNcbi2naBase b ) :
183 m_base( s_dibase2code[(prev << 2) | b] | CColorTwoBase(b) ) {}
CColorTwoBase(CNcbiqnaBase prev,CNcbiqnaBase b)184 CColorTwoBase( CNcbiqnaBase prev, CNcbiqnaBase b ) :
185 m_base( s_dibase2code[(prev&0x30 << 2) | b&0x30] | CColorTwoBase(b) ) {}
CColorTwoBase(CNcbi2naBase prev,CNcbi8naBase b)186 CColorTwoBase( CNcbi2naBase prev, CNcbi8naBase b ) :
187 m_base( s_dibase2code[(prev << 2) | b.GetSmallestNcbi2na()] | CColorTwoBase(b) ) {}
CColorTwoBase(CColorTwoBase prev,CColorTwoBase b)188 CColorTwoBase( CColorTwoBase prev, CColorTwoBase b ) { THROW( logic_error, "CColorTwoBase( CColorTwoBase, CColorTwoBase ) should never be called" ); }
CColorTwoBase(CNcbi8naBase prev,CNcbi8naBase b)189 CColorTwoBase( CNcbi8naBase prev, CNcbi8naBase b ) :
190 m_base( s_dibase2code[(prev.GetSmallestNcbi2na() << 2) | b.GetSmallestNcbi2na()] | CColorTwoBase(b) ) {}
CColorTwoBase(CNcbipnaBase prev,CNcbipnaBase b)191 CColorTwoBase( CNcbipnaBase prev, CNcbipnaBase b ) :
192 m_base( s_dibase2code[(CNcbi8naBase(prev).GetSmallestNcbi2na() << 2) | CNcbi8naBase(b).GetSmallestNcbi2na()] | CColorTwoBase(b) ) {}
193 // template<class base>
194 // CColorTwoBase( base a, base b ) : m_base( s_dibase2code[(CNcbi8naBase( a ).GetSmallestNcbi2na()<<2) | CNcbi8naBase( b ).GetSmallestNcbi2na()] ) {}
operator char() const195 operator char () const { return m_base; }
GetBaseCalls() const196 CNcbi8naBase GetBaseCalls() const { return m_base & 0xf; }
Complement() const197 CColorTwoBase Complement() const { return GetBaseCalls().Complement() | GetColor(); }
GetColor() const198 int GetColor() const { return m_base & 0x30; }
GetColorOrd() const199 int GetColorOrd() const { return GetColor() >> 4; }
AsAscii(bool tryBaseCalls=true) const200 char AsAscii( bool tryBaseCalls = true ) const { return tryBaseCalls && GetBaseCalls() ? (char)CIupacnaBase( GetBaseCalls() ) : ('0' + GetColorOrd()); }
BytesPerBase()201 static int BytesPerBase() { return 1; }
202 protected:
203 void x_Init( char c );
204 protected:
205 static char s_dibase2code[];
206 char m_base; // ..cc4444
207 };
208
209 ////////////////////////////////////////////////////////////////////////
210 template<class BaseA, class BaseB>
ComputeScore(const BaseA & a,const BaseB & b)211 inline int ComputeScore( const BaseA& a, const BaseB& b )
212 {
213 return bool( CNcbi8naBase( a ) & CNcbi8naBase( b ) );
214 }
215
ComputeScore(const CNcbi8naBase & a,const CNcbipnaBase & b)216 inline int ComputeScore( const CNcbi8naBase& a, const CNcbipnaBase& b )
217 {
218 return
219 (( a & 0x01 ? b[0] : 0 ) +
220 ( a & 0x02 ? b[1] : 0 ) +
221 ( a & 0x04 ? b[2] : 0 ) +
222 ( a & 0x08 ? b[3] : 0 )) / (b[0] + b[1] + b[2] + b[3]);
223 }
224
ComputeScore(const CNcbipnaBase & b,const CNcbi8naBase & a)225 inline int ComputeScore( const CNcbipnaBase& b, const CNcbi8naBase& a )
226 {
227 return
228 (( a & 0x01 ? b[0] : 0 ) +
229 ( a & 0x02 ? b[1] : 0 ) +
230 ( a & 0x04 ? b[2] : 0 ) +
231 ( a & 0x08 ? b[3] : 0 )) / (b[0] + b[1] + b[2] + b[3]);
232 }
233
operator *(const CNcbi2naBase & a,const CNcbi2naBase & b)234 inline int operator * ( const CNcbi2naBase& a, const CNcbi2naBase& b )
235 {
236 return a == b;
237 }
238
239 ////////////////////////////////////////////////////////////////////////
240
CIupacnaBase(const CNcbi8naBase & b)241 inline CIupacnaBase::CIupacnaBase( const CNcbi8naBase& b ) : m_base("-ACMGRSVTWYHKDBN"[b&0x0f]) {}
CIupacnaBase(const CNcbi4naBase & b)242 inline CIupacnaBase::CIupacnaBase( const CNcbi4naBase& b ) : m_base("-ACMGRSVTWYHKDBN"[b&0x0f]) {}
CIupacnaBase(const CNcbi2naBase & b)243 inline CIupacnaBase::CIupacnaBase( const CNcbi2naBase& b ) : m_base("ACGT"[b&0x03]) {}
CIupacnaBase(const CNcbipnaBase & b,int score)244 inline CIupacnaBase::CIupacnaBase( const CNcbipnaBase& b, int score ) : m_base(0) { m_base = CIupacnaBase( CNcbi8naBase( b, score ) ); }
CIupacnaBase(const CNcbiqnaBase & b,int cutoff)245 inline CIupacnaBase::CIupacnaBase( const CNcbiqnaBase& b, int cutoff ) : m_base( b.GetPhrapScore() > cutoff ? "ACGT"[b&3] : 'N' ) {}
CIupacnaBase(const CColorTwoBase & b)246 inline CIupacnaBase::CIupacnaBase( const CColorTwoBase& b ) { m_base = b.GetBaseCalls() ? char(CIupacnaBase( b.GetBaseCalls() )) : char(( b.GetColorOrd() + '0' )); }
CIupacnaBase(const CIupacnaBase & b,const CColorTwoBase & c)247 inline CIupacnaBase::CIupacnaBase( const CIupacnaBase& b, const CColorTwoBase& c )
248 { m_base = "ACGTCATGGTACTGCA"[(CNcbi2naBase(b) << 2)|c.GetColorOrd()]; }
249
250 ////////////////////////////////////////////////////////////////////////
251
CNcbipnaBase(const CIupacnaBase & b)252 inline CNcbipnaBase::CNcbipnaBase( const CIupacnaBase& b )
253 {
254 x_Init( CNcbi8naBase( b ) );
255 }
256
CNcbipnaBase(const CNcbi2naBase & b)257 inline CNcbipnaBase::CNcbipnaBase( const CNcbi2naBase& b )
258 {
259 fill( m_base, m_base + 5, 0 );
260 m_base[b] = m_base[4] = '\xff';
261 }
262
CNcbipnaBase(const CNcbi4naBase & b)263 inline CNcbipnaBase::CNcbipnaBase( const CNcbi4naBase& b )
264 {
265 x_Init( b );
266 }
267
x_Init(const CNcbi8naBase & b)268 inline void CNcbipnaBase::x_Init( const CNcbi8naBase& b )
269 {
270 fill( m_base, m_base + 5, 0 );
271 if( b & 0x01 ) m_base[0] = '\xff';
272 if( b & 0x02 ) m_base[1] = '\xff';
273 if( b & 0x03 ) m_base[2] = '\xff';
274 if( b & 0x04 ) m_base[3] = '\xff';
275 m_base[4] = b ? '\xff' : 0;
276 }
277
CNcbipnaBase(const CNcbiqnaBase & b)278 inline CNcbipnaBase::CNcbipnaBase( const CNcbiqnaBase& b )
279 {
280 Uint1 val = Uint1( 255 * ( std::pow(10.0, b.GetPhrapScore() / 10 ) ) );
281 int x = CNcbi2naBase( b );
282 m_base[0] = x-- ? val : '\xff';
283 m_base[1] = x-- ? val : '\xff';
284 m_base[2] = x-- ? val : '\xff';
285 m_base[3] = x-- ? val : '\xff';
286 m_base[4] = '\xff';
287 }
288
289 ////////////////////////////////////////////////////////////////////////
290
AdjustScore(int score)291 inline char CNcbiqnaBase::AdjustScore( int score )
292 {
293 if( score < 0 ) score = 0;
294 if( score > 63 ) score = 63;
295 return score;
296 }
297
CNcbiqnaBase(const CNcbipnaBase & b)298 inline CNcbiqnaBase::CNcbiqnaBase( const CNcbipnaBase& b ) : m_base(0)
299 {
300 int max = 0, next = 0;
301 for( int i = 0; i < 4; ++i ) {
302 if( b[i] > max ) {
303 m_base = i;
304 next = max;
305 max = b[i];
306 } else if( b[i] > next ) next = b[i];
307 }
308 if( next == 0 ) m_base |= 0xfc;
309 else {
310 double pscore = 10*std::log10( double( max ) / next );
311 m_base |= AdjustScore( int(pscore) ) << 2;
312 }
313 }
CNcbiqnaBase(const CNcbi8naBase & b,unsigned score)314 inline CNcbiqnaBase::CNcbiqnaBase( const CNcbi8naBase& b, unsigned score )
315 {
316 if( b.GetAltCount() > 1 ) m_base = 0;
317 else m_base = CNcbi2naBase( b ) | (AdjustScore(score) << 2);
318 }
319
CNcbiqnaBase(const CNcbi4naBase & b,unsigned score)320 inline CNcbiqnaBase::CNcbiqnaBase( const CNcbi4naBase& b, unsigned score )
321 {
322 if( b.GetAltCount() > 1 ) m_base = 0;
323 else m_base = CNcbi2naBase( b ) | (AdjustScore(score) << 2);
324 }
325
CNcbiqnaBase(const CNcbi2naBase & b,unsigned score)326 inline CNcbiqnaBase::CNcbiqnaBase( const CNcbi2naBase& b, unsigned score )
327 {
328 m_base = b | (AdjustScore(score) << 2);
329 }
330
CNcbiqnaBase(const CIupacnaBase & b,unsigned score)331 inline CNcbiqnaBase::CNcbiqnaBase( const CIupacnaBase& b, unsigned score )
332 {
333 CNcbi8naBase _b( b );
334 if( _b.GetAltCount() > 1 ) m_base = 0;
335 else m_base = CNcbi2naBase( b ) | (AdjustScore(score) << 2);
336 }
337
338 ////////////////////////////////////////////////////////////////////////
339
CNcbi8naBase(char c,EStrand strand)340 inline CNcbi8naBase::CNcbi8naBase( char c, EStrand strand ) : m_base( c )
341 {
342 if( strand == eStrand_neg ) m_base = s_complement[int(m_base)];
343 }
344
CNcbi8naBase(int c,EStrand strand)345 inline CNcbi8naBase::CNcbi8naBase( int c, EStrand strand ) : m_base( c )
346 {
347 if( strand == eStrand_neg ) m_base = s_complement[int(m_base)];
348 }
349
CNcbi8naBase(unsigned int c,EStrand strand)350 inline CNcbi8naBase::CNcbi8naBase( unsigned int c, EStrand strand ) : m_base( c )
351 {
352 if( strand == eStrand_neg ) m_base = s_complement[int(m_base)];
353 }
354
CNcbi8naBase(const CNcbi4naBase & b)355 inline CNcbi8naBase::CNcbi8naBase( const CNcbi4naBase& b ) : m_base( b ) {}
CNcbi8naBase(const CNcbi2naBase & b)356 inline CNcbi8naBase::CNcbi8naBase( const CNcbi2naBase& b ) : m_base( "\x01\x02\x04\x08"[(int)b] ) {}
357
CNcbi8naBase(const CNcbipnaBase & b,int score)358 inline CNcbi8naBase::CNcbi8naBase( const CNcbipnaBase& b, int score ) : m_base(0)
359 {
360 if( b[0] > score ) m_base |= 0x01;
361 if( b[1] > score ) m_base |= 0x02;
362 if( b[2] > score ) m_base |= 0x04;
363 if( b[3] > score ) m_base |= 0x08;
364 if( (!m_base) && ( b[4] > score ) ) m_base = 0x0f;
365 }
366
CNcbi8naBase(const CIupacnaBase & b)367 inline CNcbi8naBase::CNcbi8naBase( const CIupacnaBase& b ) : m_base( s_fromIupacna[b] )
368 {
369 if( m_base == '\xf0' ) THROW( runtime_error, "Invalid IUPACNA base ASCII[" << int(b) << "] " << b );
370 }
371
CNcbi8naBase(const CNcbi8naBase & b,const CColorTwoBase & c)372 inline CNcbi8naBase::CNcbi8naBase( const CNcbi8naBase& b, const CColorTwoBase& c )
373 { m_base = "\x1\x2\x4\x8\x2\x1\x8\x4\x4\x8\x1\x2\x8\x4\x2\x1"[(CNcbi2naBase(b) << 2)|c.GetColorOrd()]; }
374
CNcbi8naBase(const CNcbiqnaBase & b,int cutoff)375 inline CNcbi8naBase::CNcbi8naBase( const CNcbiqnaBase& b, int cutoff ) : m_base( b.GetPhrapScore() > cutoff ? CNcbi8naBase( CNcbi2naBase( b&3 ) ) : Any() ) {}
Complement() const376 inline CNcbi8naBase CNcbi8naBase::Complement() const { return s_complement[(int)(unsigned char)m_base]; }
GetSmallestNcbi2na() const377 inline CNcbi2naBase CNcbi8naBase::GetSmallestNcbi2na() const { return CNcbi2naBase( s_smallestNcbi2na[short((unsigned char)m_base)] ); }
378
379 ////////////////////////////////////////////////////////////////////////
380
CNcbi2naBase(const CIupacnaBase & b)381 inline CNcbi2naBase::CNcbi2naBase( const CIupacnaBase& b ) : m_base( s_iupacnaTable[b] )
382 {
383 if( m_base == '\xf0' ) THROW( runtime_error, "Invalid IUPACNA base ASCII[" << int(b) << "] " << b );
384 }
385
CNcbi2naBase(const CNcbi8naBase & b)386 inline CNcbi2naBase::CNcbi2naBase( const CNcbi8naBase& b ) : m_base( s_ncbi8naTable[b] )
387 {
388 if( m_base == '\xf0' ) THROW( runtime_error, "Invalid NCBI8NA base 0x" << setw(2) << hex << setfill('0') << int(b) << " IUPACNA " << CIupacnaBase(b) );
389 }
390
CNcbi2naBase(const CNcbi4naBase & b)391 inline CNcbi2naBase::CNcbi2naBase( const CNcbi4naBase& b ) : m_base( s_ncbi8naTable[b] )
392 {
393 if( m_base == '\xf0' ) THROW( runtime_error, "Invalid NCBI8NA base 0x" << setw(2) << hex << setfill('0') << int(b) << " IUPACNA " << CIupacnaBase(b) );
394 }
395
CNcbi2naBase(const CNcbiqnaBase & b)396 inline CNcbi2naBase::CNcbi2naBase( const CNcbiqnaBase& b ) : m_base( b & 3 ) {}
397
398 ////////////////////////////////////////////////////////////////////////
399
x_Init(char c)400 inline void CColorTwoBase::x_Init( char c )
401 {
402 static const char * t = "0123ACGT";
403 const char * x = strchr( t, toupper( c ) );
404 if( x == 0 || *x == 0 ) THROW( runtime_error, "Invalid colorspace base " << c );
405 m_base = x - t;
406 if( m_base < 4 ) (m_base <<= 4);
407 else m_base = CNcbi8naBase( CNcbi2naBase( m_base & 0x03 ) );
408 }
409
410 END_OLIGOFAR_SCOPES
411
412 #endif
413