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