libMems/HybridAbstractMatch.h

Go to the documentation of this file.
00001 /*******************************************************************************
00002  * $Id: HybridAbstractMatch.h,v 1.8 2004/02/27 23:08:55 darling Exp $
00003  * This file is copyright 2002-2007 Aaron Darling and authors listed in the AUTHORS file.
00004  * This file is licensed under the GPL.
00005  * Please see the file called COPYING for licensing details.
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         // use compiler-generated copy constructor, assignment operator, and destructor
00049 
00050         // see AbstractMatch base class documentation for these functions
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         // these functions manipulate the start coordinates quickly
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         // storage for a fixed number of seqs
00087         uint fixed_seq_ids[FIXED_SEQ_COUNT];
00088         int64 fixed_starts[FIXED_SEQ_COUNT];
00089 
00090         // storage for any number of seqs
00091         std::vector<uint, uintAlloc > seq_ids;
00092         std::vector<int64, int64Alloc > starts;
00093 
00094         uint SeqToIndex( uint seqI ) const;
00095 
00096         // for use by derived classes in order to swap contents
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__

Generated on Fri Mar 14 06:01:03 2008 for libMems by doxygen 1.3.6