/***************************************************************************** # Copyright (C) 1994-2008 by David Gordon. # All rights reserved. # # This software is part of a beta-test version of the Consed/Autofinish # package. It should not be redistributed or # used for any commercial purpose, including commercially funded # sequencing, without written permission from the author and the # University of Washington. # # This software is provided ``AS IS'' and any express or implied # warranties, including, but not limited to, the implied warranties of # merchantability and fitness for a particular purpose, are disclaimed. # In no event shall the authors or the University of Washington be # liable for any direct, indirect, incidental, special, exemplary, or # consequential damages (including, but not limited to, procurement of # substitute goods or services; loss of use, data, or profits; or # business interruption) however caused and on any theory of liability, # whether in contract, strict liability, or tort (including negligence # or otherwise) arising in any way out of the use of this software, even # if advised of the possibility of such damage. # # Building Consed from source is error prone and not simple which is # why I provide executables. Due to time limitations I cannot # provide any assistance in building Consed. Even if you do not # modify the source, you may introduce errors due to using a # different version of the compiler, a different version of motif, # different versions of other libraries than I used, etc. For this # reason, if you discover Consed bugs, I can only offer help with # those bugs if you first reproduce those bugs with an executable # provided by me--not an executable you have built. # # Modifying Consed is also difficult. Although Consed is modular, # some modules are used by many other modules. Thus making a change # in one place can have unforeseen effects on many other features. # It may takes months for you to notice these other side-effects # which may not seen connected at all. It is not feasable for me to # provide help with modifying Consed sources because of the # potentially huge amount of time involved. # #*****************************************************************************/ #ifndef fwdRevPair_included #define fwdRevPair_included #include using namespace std; #include "subcloneTTemplate.h" #include "contig.h" class fwdRevPair { public: fwdRevPair( LocatedFragment* pFwdRead, LocatedFragment* pRevRead, const char cProblem ) : cProblem_( cProblem ), bInsertIntoFilteredArray_( false ) { int nFwdUnpadded = pFwdRead->nGetConsPosOfBeginningOfReadUnpadded(); int nRevUnpadded = pRevRead->nGetConsPosOfBeginningOfReadUnpadded(); if ( pFwdRead->pContig_ == pRevRead->pContig_ ) { // then sort by whichever is leftmost if ( nFwdUnpadded < nRevUnpadded ) { pLocFrag1_ = pFwdRead; pLocFrag2_ = pRevRead; nUnpaddedStartOfRead1_ = nFwdUnpadded; nUnpaddedStartOfRead2_ = nRevUnpadded; } else { pLocFrag1_ = pRevRead; pLocFrag2_ = pFwdRead; nUnpaddedStartOfRead1_ = nRevUnpadded; nUnpaddedStartOfRead2_ = nFwdUnpadded; } } else { // reads are in different contigs if ( pFwdRead->pContig_->soGetName() < pRevRead->pContig_->soGetName() ) { pLocFrag1_ = pFwdRead; pLocFrag2_ = pRevRead; nUnpaddedStartOfRead1_ = nFwdUnpadded; nUnpaddedStartOfRead2_ = nRevUnpadded; } else { pLocFrag1_ = pRevRead; pLocFrag2_ = pFwdRead; nUnpaddedStartOfRead1_ = nRevUnpadded; nUnpaddedStartOfRead2_ = nFwdUnpadded; } } pContigOfRead1_ = pLocFrag1_->pContig_; pContigOfRead2_ = pLocFrag2_->pContig_; } bool operator==( const fwdRevPair& pair ) const { if ( this == &pair ) return( true ); else return( false ); } public: LocatedFragment* pLocFrag1_; LocatedFragment* pLocFrag2_; // these two reads are sorted by contig name and then // contig position Contig* pContigOfRead1_; int nUnpaddedStartOfRead1_; // in direction of sequencing, so is // end of complemented read Contig* pContigOfRead2_; int nUnpaddedStartOfRead2_; // in direction of sequencing char cProblem_; // from fwdRevPair2 bool bInsertIntoFilteredArray_; }; class arrayOfFwdRevPairs : public RWTPtrOrderedVector { public: arrayOfFwdRevPairs( const size_t nInitialSize ) : RWTPtrOrderedVector( nInitialSize, "arrayOfFwdRevPairs" ) {} static int cmpFwdRevPairs( const fwdRevPair** ppFwdRevPair1, const fwdRevPair** ppFwdRevPair2 ) { if ( (*ppFwdRevPair1)->pContigOfRead1_ == (*ppFwdRevPair2)->pContigOfRead1_ ) { // sort them by the position of the leftmost read, read1 if ( (*ppFwdRevPair1)->nUnpaddedStartOfRead1_ < (*ppFwdRevPair2)->nUnpaddedStartOfRead1_ ) return( -1 ); else if ( (*ppFwdRevPair1)->nUnpaddedStartOfRead1_ > (*ppFwdRevPair2)->nUnpaddedStartOfRead1_ ) return( 1 ); else { if ( (*ppFwdRevPair1)->pLocFrag1_->soGetName() < (*ppFwdRevPair2)->pLocFrag1_->soGetName() ) return( -1 ); else if ( (*ppFwdRevPair1)->pLocFrag1_->soGetName() > (*ppFwdRevPair2)->pLocFrag1_->soGetName() ) return( 1 ); else return( 0 ); } } else { if ( (*ppFwdRevPair1)->pContigOfRead1_->soGetName() < (*ppFwdRevPair2)->pContigOfRead1_->soGetName() ) return( -1 ); else if ( (*ppFwdRevPair1)->pContigOfRead1_->soGetName() > (*ppFwdRevPair2)->pContigOfRead1_->soGetName() ) return( 1 ); else return( 0 ); } } void resort() { void* pArray = (void*) data(); size_t nNumberOfElements = entries(); size_t nSizeOfAnElement = sizeof( fwdRevPair* ); qsort( pArray, nNumberOfElements, nSizeOfAnElement, ( ( int(*) ( const void*, const void* ) ) cmpFwdRevPairs ) ); // check that they are sorted bool bOutOfOrder = false; for( int nPair = 0; nPair < entries() - 1; ++nPair ) { fwdRevPair* pFwdRevPair1 = operator[]( nPair ); fwdRevPair* pFwdRevPair2 = operator[]( nPair + 1 ); if ( pFwdRevPair1->pContigOfRead1_ == pFwdRevPair2->pContigOfRead1_ ) { if ( pFwdRevPair1->nUnpaddedStartOfRead1_ > pFwdRevPair2->nUnpaddedStartOfRead1_ ) { cerr << "pairs out of order. Reads at: " << pFwdRevPair1->nUnpaddedStartOfRead1_ << " and " << pFwdRevPair2->nUnpaddedStartOfRead1_ << endl; bOutOfOrder = true; } } else if ( pFwdRevPair1->pContigOfRead1_->soGetName() > pFwdRevPair2->pContigOfRead1_->soGetName() ) { cerr << "pairs out of order. reads " << pFwdRevPair1->pLocFrag1_->soGetName() << " and " << pFwdRevPair2->pLocFrag1_->soGetName() << endl; bOutOfOrder = true; } } if ( bOutOfOrder ) { RWCString soError = "qsort failed for arrayOfFwdRevPairs::resort"; THROW_ERROR2( soError ); } } }; #endif