00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef __HybridAbstractMatch_h__
00010 #define __HybridAbstractMatch_h__
00011
00012 #ifdef HAVE_CONFIG_H
00013 #include "config.h"
00014 #endif
00015
00016 #include "libGenome/gnClone.h"
00017 #include "libGenome/gnDefs.h"
00018 #include "libMems/AbstractMatch.h"
00019 #include <vector>
00020 #include <limits>
00021
00022 namespace mems {
00023
00028 template< unsigned FIXED_SEQ_COUNT=2, class int64Alloc=std::allocator<int64>, class uintAlloc=std::allocator<uint> >
00029 class HybridAbstractMatch : public AbstractMatch {
00030 public:
00031 HybridAbstractMatch() : m_seq_count(0)
00032 {
00033 memset(fixed_seq_ids, 0xFF, sizeof(fixed_seq_ids));
00034 memset(fixed_starts, 0, sizeof(fixed_starts));
00035 }
00040 HybridAbstractMatch(const uint seq_count )
00041 : m_seq_count(seq_count)
00042 {
00043 memset(fixed_seq_ids, 0xFF, sizeof(fixed_seq_ids));
00044 memset(fixed_starts, 0, sizeof(fixed_starts));
00045 }
00046
00047
00048
00049
00050
00051
00052 int64 Start(uint seqI) const;
00053 void SetStart(uint seqI, int64 startI);
00054 uint Multiplicity() const
00055 {
00056 uint mult = 0;
00057 for( size_t fI = 0; fI < FIXED_SEQ_COUNT; ++fI )
00058 mult += fixed_seq_ids[fI] != NO_SEQ ? 1 : 0;
00059 return mult + (uint)seq_ids.size();
00060 }
00061 uint SeqCount() const{return m_seq_count;}
00062 uint FirstStart() const;
00063 virtual void Invert();
00064
00065 gnSeqI LeftEnd(uint seqI) const;
00066 orientation Orientation(uint seqI) const;
00067 void SetLeftEnd(uint seqI, gnSeqI position);
00068 void SetOrientation(uint seqI, orientation o);
00069
00070
00071 virtual void MoveStart(int64 move_amount);
00072 virtual void MoveEnd(int64 move_amount);
00073
00074 virtual boolean operator==( const HybridAbstractMatch& ham ) const;
00075
00076 virtual uint UsedSeq( uint seqI ) const {
00077 if(seqI < FIXED_SEQ_COUNT) return fixed_seq_ids[seqI];
00078 return seq_ids[seqI];
00079 }
00080
00081 protected:
00082 uint m_seq_count;
00083
00084 static const uint NO_SEQ = UINT_MAX;
00085
00086
00087 uint fixed_seq_ids[FIXED_SEQ_COUNT];
00088 int64 fixed_starts[FIXED_SEQ_COUNT];
00089
00090
00091 std::vector<uint, uintAlloc > seq_ids;
00092 std::vector<int64, int64Alloc > starts;
00093
00094 uint SeqToIndex( uint seqI ) const;
00095
00096
00097 void swap( HybridAbstractMatch* other );
00098 };
00099
00100
00101 template< unsigned FIXED_SEQ_COUNT, class gnSeqIAlloc, class uintAlloc >
00102 void HybridAbstractMatch< FIXED_SEQ_COUNT, gnSeqIAlloc, uintAlloc >::swap( HybridAbstractMatch* other )
00103 {
00104 std::swap( m_seq_count, other->m_seq_count );
00105
00106 uint tmp_ids[FIXED_SEQ_COUNT];
00107 for( int i = 0; i < FIXED_SEQ_COUNT; i++ ) tmp_ids[i] = other->fixed_seq_ids[i];
00108 for( int i = 0; i < FIXED_SEQ_COUNT; i++ ) other->fixed_seq_ids[i] = fixed_seq_ids[i];
00109 for( int i = 0; i < FIXED_SEQ_COUNT; i++ ) fixed_seq_ids[i] = tmp_ids[i];
00110
00111 int64 tmp_starts[FIXED_SEQ_COUNT];
00112 for( int i = 0; i < FIXED_SEQ_COUNT; i++ ) tmp_starts[i] = other->fixed_starts[i];
00113 for( int i = 0; i < FIXED_SEQ_COUNT; i++ ) other->fixed_starts[i] = fixed_starts[i];
00114 for( int i = 0; i < FIXED_SEQ_COUNT; i++ ) fixed_starts[i] = tmp_starts[i];
00115
00116 std::swap( seq_ids, other->seq_ids );
00117 std::swap( starts, other->starts );
00118 }
00119
00120 template< unsigned FIXED_SEQ_COUNT, class gnSeqIAlloc, class uintAlloc >
00121 uint HybridAbstractMatch< FIXED_SEQ_COUNT, gnSeqIAlloc, uintAlloc >::FirstStart() const
00122 {
00123 uint minI = NO_SEQ;
00124 std::size_t i = 0;
00125 for( ; i < FIXED_SEQ_COUNT; ++i )
00126 minI = fixed_seq_ids[i] < minI ? fixed_seq_ids[i] : minI;
00127 for( i = 0; i < seq_ids.size(); ++i )
00128 minI = seq_ids[i] < minI ? seq_ids[i] : minI;
00129 return minI;
00130 }
00131
00132 template< unsigned FIXED_SEQ_COUNT, class gnSeqIAlloc, class uintAlloc >
00133 uint HybridAbstractMatch< FIXED_SEQ_COUNT, gnSeqIAlloc, uintAlloc >::SeqToIndex( uint seqI ) const
00134 {
00135 uint posI = 0;
00136 for( ; posI < FIXED_SEQ_COUNT; ++posI )
00137 if( fixed_seq_ids[posI] == seqI )
00138 break;
00139 if(posI < FIXED_SEQ_COUNT)
00140 return posI;
00141 for( posI = 0; posI < seq_ids.size(); ++posI )
00142 if( seq_ids[posI] == seqI )
00143 break;
00144 if( posI == seq_ids.size() )
00145 return NO_SEQ;
00146 return posI + FIXED_SEQ_COUNT;
00147 }
00148
00149
00150 template< unsigned FIXED_SEQ_COUNT, class gnSeqIAlloc, class uintAlloc >
00151 int64 HybridAbstractMatch< FIXED_SEQ_COUNT, gnSeqIAlloc, uintAlloc >::Start(uint seqI) const
00152 {
00153 uint posI = SeqToIndex( seqI );
00154 if( posI == NO_SEQ )
00155 return NO_MATCH;
00156 if( posI < FIXED_SEQ_COUNT )
00157 return fixed_starts[posI];
00158 return starts[posI-FIXED_SEQ_COUNT];
00159 }
00160
00161
00162 template< unsigned FIXED_SEQ_COUNT, class gnSeqIAlloc, class uintAlloc >
00163 void HybridAbstractMatch< FIXED_SEQ_COUNT, gnSeqIAlloc, uintAlloc >::SetStart(uint seqI, int64 startI)
00164 {
00165 uint posI = SeqToIndex( seqI );
00166 if( startI == NO_MATCH && posI == NO_SEQ )
00167 return;
00168 if( posI == NO_SEQ )
00169 {
00170 for( size_t i = 0; i < FIXED_SEQ_COUNT; ++i )
00171 if( fixed_seq_ids[i] == NO_SEQ )
00172 {
00173 posI = i;
00174 break;
00175 }
00176 }
00177 if( posI < FIXED_SEQ_COUNT )
00178 {
00179 if( startI == NO_MATCH )
00180 fixed_seq_ids[posI] = NO_SEQ;
00181 else
00182 fixed_seq_ids[posI] = seqI;
00183 fixed_starts[posI] = startI;
00184 }
00185 else
00186 {
00187 posI -= FIXED_SEQ_COUNT;
00188 if( startI == NO_MATCH )
00189 {
00190 seq_ids.erase( seq_ids.begin() + posI );
00191 starts.erase( starts.begin() + posI );
00192 return;
00193 }
00194 if( posI >= seq_ids.size() )
00195 {
00196 seq_ids.push_back(seqI);
00197 starts.push_back(startI);
00198 }else{
00199 starts[posI] = startI;
00200 }
00201 }
00202 }
00203
00204
00205 template< unsigned FIXED_SEQ_COUNT, class gnSeqIAlloc, class uintAlloc >
00206 void HybridAbstractMatch< FIXED_SEQ_COUNT, gnSeqIAlloc, uintAlloc >::Invert()
00207 {
00208 for( size_t i = 0; i < FIXED_SEQ_COUNT; ++i )
00209 fixed_starts[i] = -fixed_starts[i];
00210 for( size_t i = 0; i < starts.size(); ++i )
00211 starts[i] = -starts[i];
00212 }
00213
00214
00215
00216 template< unsigned FIXED_SEQ_COUNT, class gnSeqIAlloc, class uintAlloc >
00217 gnSeqI HybridAbstractMatch< FIXED_SEQ_COUNT, gnSeqIAlloc, uintAlloc >::LeftEnd(uint seqI) const
00218 {
00219 uint posI = SeqToIndex( seqI );
00220 if( posI == NO_SEQ )
00221 return NO_MATCH;
00222 if( posI < FIXED_SEQ_COUNT )
00223 return genome::absolut(fixed_starts[posI]);
00224 return genome::absolut(starts[posI-FIXED_SEQ_COUNT]);
00225 }
00226
00227
00228 template< unsigned FIXED_SEQ_COUNT, class gnSeqIAlloc, class uintAlloc >
00229 AbstractMatch::orientation HybridAbstractMatch< FIXED_SEQ_COUNT, gnSeqIAlloc, uintAlloc >::Orientation(uint seqI) const
00230 {
00231 uint posI = SeqToIndex( seqI );
00232 if( posI == NO_SEQ )
00233 return undefined;
00234 if( posI < FIXED_SEQ_COUNT )
00235 return fixed_starts[posI] < 0 ? reverse : forward;
00236 return starts[posI-FIXED_SEQ_COUNT] < 0 ? reverse : forward;
00237 }
00238
00239
00240 template< unsigned FIXED_SEQ_COUNT, class gnSeqIAlloc, class uintAlloc >
00241 void HybridAbstractMatch< FIXED_SEQ_COUNT, gnSeqIAlloc, uintAlloc >::SetLeftEnd(uint seqI, gnSeqI position)
00242 {
00243 uint posI = SeqToIndex( seqI );
00244 orientation o = posI == NO_SEQ || position == NO_MATCH ? undefined : Orientation( seqI );
00245 SetStart(seqI,position);
00246 if( o != undefined )
00247 SetOrientation(seqI, o);
00248 }
00249
00250 template< unsigned FIXED_SEQ_COUNT, class gnSeqIAlloc, class uintAlloc >
00251 void HybridAbstractMatch< FIXED_SEQ_COUNT, gnSeqIAlloc, uintAlloc >::SetOrientation(uint seqI, orientation o)
00252 {
00253 if( o == undefined )
00254 {
00255 SetStart(seqI, NO_MATCH);
00256 return;
00257 }
00258 uint posI = SeqToIndex( seqI );
00259 if( posI == NO_SEQ )
00260 throw "ArrayIndexOutOfBounds!\n";
00261 int oi = o == reverse ? -1 : 1;
00262 if( posI < FIXED_SEQ_COUNT )
00263 {
00264 fixed_starts[posI] = genome::absolut(fixed_starts[posI]) * oi;
00265 return;
00266 }
00267 starts[posI-FIXED_SEQ_COUNT] = genome::absolut(starts[posI-FIXED_SEQ_COUNT]) * oi;
00268 }
00269
00270 template< unsigned FIXED_SEQ_COUNT, class gnSeqIAlloc, class uintAlloc >
00271 void HybridAbstractMatch< FIXED_SEQ_COUNT, gnSeqIAlloc, uintAlloc >::MoveStart(int64 move_amount)
00272 {
00273 for( size_t i=0; i < FIXED_SEQ_COUNT; ++i )
00274 if( fixed_starts[i] > 0 )
00275 fixed_starts[i] += move_amount;
00276 for( size_t i=0; i < starts.size(); ++i )
00277 if( starts[i] > 0 )
00278 starts[i] += move_amount;
00279 }
00280
00281 template< unsigned FIXED_SEQ_COUNT, class gnSeqIAlloc, class uintAlloc >
00282 void HybridAbstractMatch< FIXED_SEQ_COUNT, gnSeqIAlloc, uintAlloc >::MoveEnd(int64 move_amount)
00283 {
00284 for( size_t i=0; i < FIXED_SEQ_COUNT; ++i )
00285 if( fixed_starts[i] < 0 )
00286 fixed_starts[i] -= move_amount;
00287 for( size_t i=0; i < starts.size(); ++i )
00288 if( starts[i] < 0 )
00289 starts[i] -= move_amount;
00290 }
00291
00292 template< unsigned FIXED_SEQ_COUNT, class gnSeqIAlloc, class uintAlloc >
00293 boolean HybridAbstractMatch< FIXED_SEQ_COUNT, gnSeqIAlloc, uintAlloc >::operator==( const HybridAbstractMatch< FIXED_SEQ_COUNT, gnSeqIAlloc, uintAlloc >& sam ) const
00294 {
00295 for( size_t i = 0; i < FIXED_SEQ_COUNT; ++i )
00296 {
00297 if( fixed_seq_ids[i] == NO_SEQ )
00298 continue;
00299 if( Start(fixed_seq_ids[i]) != sam.Start(fixed_seq_ids[i]) )
00300 return false;
00301 }
00302 for( size_t i = 0; i < seq_ids.size(); ++i )
00303 {
00304 if( seq_ids[i] == NO_SEQ )
00305 continue;
00306 if( Start(seq_ids[i]) != sam.Start(seq_ids[i]) )
00307 return false;
00308 }
00309 return Multiplicity() == sam.Multiplicity();
00310 }
00311
00312
00313 }
00314
00315 #endif // __HybridAbstractMatch_h__