Generated on Tue Dec 16 12:49:16 2008 for BIU-2.2.0 by doxygen 1.5.1

src/biu/RNAStructure_TB.cc

Go to the documentation of this file.
00001 
00002 #include "biu/RNAStructure_TB.hh"
00003 
00004 #include <biu/assertbiu.hh>
00005 
00006 #include <stack>
00007 #include <cmath>
00008 #include <iostream>
00009 #include <limits>
00010 
00011 #include "biu/Matrix.hh"
00012 
00013 
00014 #include <inttypes.h>
00015 
00016 #include "biu/RandomNumberFactory.hh"
00017 
00018 
00019 namespace biu
00020 {
00021 
00022 
00023 
00024     const size_t RNAStructure_TB::MIN_LOOP_LENGTH = 3;
00025     const Alphabet RNAStructure_TB::STRUCT_ALPH("().", 1);
00026     const Alphabet::AlphElem    RNAStructure_TB::STRUCT_BND_OPEN = RNAStructure_TB::STRUCT_ALPH.getElement("(");
00027     const Alphabet::AlphElem    RNAStructure_TB::STRUCT_BND_CLOSE = RNAStructure_TB::STRUCT_ALPH.getElement(")");
00028     const Alphabet::AlphElem    RNAStructure_TB::STRUCT_UNBOUND = RNAStructure_TB::STRUCT_ALPH.getElement(".");
00029     const size_t RNAStructure_TB::INVALID_INDEX = std::numeric_limits<size_t>::max();
00030 
00031     const size_t RNAStructure_TB::BASEPAIRS_VALIDITY = 1;
00032     const size_t RNAStructure_TB::BASEPAIRS_VALIDITY_CALCULATED = 2;
00033     const size_t RNAStructure_TB::LOOPSIZE_VALIDITY = 4;
00034     const size_t RNAStructure_TB::LOOPSIZE_VALIDITY_CALCULATED = 8;
00035     const size_t RNAStructure_TB::STRUCTURE_VALIDITY = 16;
00036     const size_t RNAStructure_TB::STRUCTURE_VALIDITY_CALCULATED = 32;
00037 
00038 
00039     //  Do not change the following values without checking
00040     //size_t RNAStructure_TB::moveType(size_t i, size_t j) const;
00041     const size_t RNAStructure_TB::INSERT_MOVE=0;
00042     const size_t RNAStructure_TB::SHIFT_MOVE=2;
00043     const size_t RNAStructure_TB::REVERSE_SHIFT_MOVE=4;
00044     const size_t RNAStructure_TB::INVALID_DELETE_MOVE=6;
00045     const size_t RNAStructure_TB::DELETE_MOVE=7;
00046 
00047 
00048 
00049 
00050 
00051     RNAStructure_TB::RNAStructure_TB(   const std::string& rnaSeqStr,
00052                                 const std::string& rnaStructBracketDotStr,
00053                                 const AllowedBasePairs* const _bPair)
00054      :  
00055         seqShared(false),
00056         bPair(_bPair),
00057         strucStatus(0),
00058         rnaSeq(NULL),
00059         bracketStructStr(rnaStructBracketDotStr),
00060         validTreeStruc(NULL)
00061         {
00062 
00063         assertbiu(bPair != NULL, "bPair is not allowed to be NULL.");
00064         assertbiu(bPair->getAlphabet()->isAlphabetString(rnaSeqStr),
00065          "RNA sequence contains characters which are not in the alphabet.");
00066         assertbiu(STRUCT_ALPH.isAlphabetString(rnaStructBracketDotStr),
00067          "RNA structure contains characters which are not in the alphabet.");
00068 
00069 
00070         rnaSeq = new Sequence(bPair->getAlphabet()->getSequence(rnaSeqStr));
00071 
00072 
00073         assertbiu(rnaSeq->size() == rnaStructBracketDotStr.size(),
00074          "RNA sequence and structure have to have the same length.");
00075 
00076 
00077         Structure* tempStruct = new Structure(
00078                                     STRUCT_ALPH.getSequence(rnaStructBracketDotStr));
00079 
00080 
00081         assertbiu(bPair->getAlphabet()->isAlphabetSequence(*rnaSeq),
00082          "RNA sequence contains characters which are not in the alphabet.");
00083         assertbiu(STRUCT_ALPH.isAlphabetSequence(*tempStruct),
00084          "RNA structure contains characters which are not in the alphabet.");
00085 
00086 
00087         setStructure(*tempStruct);
00088 
00089         delete tempStruct;
00090         tempStruct = NULL;
00091 
00092     }
00093 
00094     RNAStructure_TB::RNAStructure_TB(   Sequence* rnaSeq_,
00095                                 const Structure* const rnaStructBracketDot_,
00096                                 const AllowedBasePairs* const bPair_,
00097                                 const bool seqIsShared)
00098      :  
00099         seqShared(seqIsShared),
00100         bPair(bPair_),
00101         strucStatus(0),
00102         rnaSeq(NULL),
00103         bracketStructStr(STRUCT_ALPH.getString(*rnaStructBracketDot_)),
00104         validTreeStruc(NULL)
00105     {
00106 
00107         assertbiu(rnaSeq_ != NULL, "no RNA sequence given.");
00108         assertbiu(rnaStructBracketDot_ != NULL, "no RNA structure given.");
00109         assertbiu(bPair != NULL, "bPair is not allowed to be NULL.");
00110         assertbiu(bPair->getAlphabet()->isAlphabetSequence(*rnaSeq_),
00111          "RNA sequence contains characters which are not in the alphabet.");
00112         assertbiu(STRUCT_ALPH.isAlphabetSequence(*rnaStructBracketDot_),
00113          "RNA structure contains characters which are not in the alphabet.");
00114         assertbiu(rnaSeq_->size() == rnaStructBracketDot_->size(),
00115          "RNA sequence and structure have to have the same length.");
00116 
00117 
00118           // init sequence
00119         if (seqShared) {
00120             rnaSeq = rnaSeq_;
00121         } else {
00122             rnaSeq = new Sequence(*rnaSeq_);
00123         };
00124 
00125         setStructure(*rnaStructBracketDot_);
00126     }
00127 
00128     RNAStructure_TB::RNAStructure_TB(const RNAStructure_TB& rnaStruct)
00129      :  
00130         seqShared(rnaStruct.seqShared),
00131         bPair(rnaStruct.bPair),
00132         strucStatus(rnaStruct.strucStatus),
00133         rnaSeq(rnaStruct.rnaSeq),
00134         bracketStructStr(rnaStruct.bracketStructStr),
00135         validTreeStruc(NULL)
00136     { 
00137         assertbiu(bPair != NULL, "bPair is not allowed to be NULL.");
00138         assertbiu(bracketStructStr.size() != 0, "bracketStructStr should not be an empty string");
00139         assertbiu(rnaSeq->size() == bracketStructStr.size(),
00140          "RNA sequence and structure have to have the same length.");
00141         assertbiu(rnaSeq != NULL, "no RNA sequence given.");
00142         assertbiu(bPair->getAlphabet()->isAlphabetSequence(*rnaSeq),
00143          "RNA sequence contains characters which are not in the alphabet.");
00144         
00145         if (rnaStruct.validTreeStruc != NULL) {
00146             validTreeStruc = new std::vector<TreeItem>(*(rnaStruct.validTreeStruc));
00147         }
00148 
00149         if (!seqShared ) {
00150             rnaSeq = new Sequence(*(rnaStruct.rnaSeq));
00151         }
00152 
00153 
00154     }
00155 
00156     RNAStructure_TB::~RNAStructure_TB() {
00157         if(!seqShared && rnaSeq != NULL) {
00158             delete rnaSeq;
00159             rnaSeq = NULL;
00160         }
00161         if(validTreeStruc != NULL){
00162             delete validTreeStruc;
00163             validTreeStruc = NULL;
00164         }
00165 
00166     }
00167 
00168 
00169 
00170     RNAStructure_TB& RNAStructure_TB::operator= (const RNAStructure_TB& rnaStruct2) {
00171         assertbiu(  seqShared == rnaStruct2.seqShared,
00172                     "sequence of both has to be shared or not");
00173         if (this != &rnaStruct2) {
00174               // copy seq
00175             if (seqShared) { // copy only pointer
00176                 rnaSeq = rnaStruct2.rnaSeq;
00177             } else { // copy
00178                 rnaSeq->resize(rnaStruct2.rnaSeq->size());
00179                 std::copy(  rnaStruct2.rnaSeq->begin(),
00180                             rnaStruct2.rnaSeq->end(),
00181                             rnaSeq->begin());
00182             }
00183               // copy remaining data
00184             bPair = rnaStruct2.bPair;
00185             strucStatus = rnaStruct2.strucStatus;
00186 
00187             if (rnaStruct2.validTreeStruc != NULL){
00188                 if (validTreeStruc == NULL)
00189                     validTreeStruc = new std::vector<TreeItem>(rnaStruct2.validTreeStruc->size());
00190                 else
00191                     validTreeStruc->resize(rnaStruct2.validTreeStruc->size());
00192 
00193                 std::copy(  rnaStruct2.validTreeStruc->begin(),
00194                                 rnaStruct2.validTreeStruc->end(),
00195                                 validTreeStruc->begin());
00196 
00197             } else if (validTreeStruc != NULL) {
00198                 delete validTreeStruc;
00199                 validTreeStruc = NULL;
00200             }
00201 
00202             bracketStructStr = rnaStruct2.bracketStructStr;
00203         }
00204         return *this;
00205     }
00206 
00207 
00208 
00209 
00210     bool RNAStructure_TB::operator== (const RNAStructure_TB& rnaStruct2)
00211              const {
00212         assertbiu(bPair != NULL, "bPair should not be NULL");
00213         assertbiu(rnaSeq != NULL, "rnaSeq should not be NULL");
00214         assertbiu(bracketStructStr.size() != 0, "bracketStructStr should not be an empty string");
00215         bool res =
00216             (
00217             (rnaSeq == rnaStruct2.rnaSeq )
00218             && *bPair == *(rnaStruct2.bPair)
00219             && bracketStructStr == rnaStruct2.bracketStructStr
00220             )||(
00221             !(rnaSeq == rnaStruct2.rnaSeq )
00222             &&*rnaSeq == *(rnaStruct2.rnaSeq)
00223             && *bPair == *(rnaStruct2.bPair)
00224             && bracketStructStr == rnaStruct2.bracketStructStr
00225             );
00226 
00227 //This is "the best" optimized form of:
00228 //      res= (a) rnaSeq == rnaStruct2.rnaSeq || (b) *rnaSeq == *(rnaStruct2.rnaSeq)
00229 //          (c) && *bPair == *(rnaStruct2.bPair)
00230 //              && bracketStructStr == rnaStruct2.bracketStructStr
00231 //              ;
00232 //      (a|b)&c <==>(a&c)|(!a&b&c) a is cheap, b & c are expensive
00233 
00234 
00235         return res && (
00236                 validTreeStruc==rnaStruct2.validTreeStruc       //If equal, they would be NULL
00237                 ||  *validTreeStruc==*(rnaStruct2.validTreeStruc)
00238                 );
00239     }
00240 
00241 
00242 //  bool RNAStructure_TB::operator!= (const RNAStructure_TB& rnaStruct2) const {
00243 //      return !operator==(rnaStruct2);
00244 //  }
00245 
00246 
00247     void RNAStructure_TB::setStructure(const Structure& str) {
00248         assertbiu(rnaSeq->size() == str.size(), "structure has wrong length");
00249 
00250         strucStatus = 0;// i.e. All status-valvulated bits are 0
00251         if (validTreeStruc==NULL) {
00252             validTreeStruc = new std::vector<TreeItem>(str.size());
00253         } else {
00254             validTreeStruc->resize(str.size());
00255         }
00256         if (! initTree(str)) {
00257             delete validTreeStruc;
00258             validTreeStruc = NULL;
00259             bracketStructStr.resize(0);
00260             strucStatus = 0;
00261         } else {
00262             bracketStructStr = STRUCT_ALPH.getString(str);
00263         }
00264         return;
00265 
00266     }
00267 
00268 
00269     bool RNAStructure_TB::hasValidStructure() const {
00270         if (strucStatus & STRUCTURE_VALIDITY_CALCULATED) // If calculated, no need to recalculate
00271             return (strucStatus & STRUCTURE_VALIDITY);
00272 
00273         //Assume validity, then change if not
00274         strucStatus |=  STRUCTURE_VALIDITY_CALCULATED | STRUCTURE_VALIDITY;
00275 
00276         size_t bondOpenings = 0;
00277 
00278         const char open = STRUCT_ALPH.getString(STRUCT_BND_OPEN).at(0);
00279         const char close = STRUCT_ALPH.getString(STRUCT_BND_CLOSE).at(0);
00280 
00281         for (size_t j=0; j < bracketStructStr.size(); j++) {
00282 
00283             if ( bracketStructStr[j] == open )  {
00284                 bondOpenings++;
00285             }
00286             else if ( bracketStructStr[j] == close ) {
00287                 if ( bondOpenings == 0 ) {
00288                     strucStatus &=  ~STRUCTURE_VALIDITY;
00289                     return false;
00290                 }
00291                 bondOpenings--;
00292             }
00293         }
00294 
00295 
00296         // check if no open brackets without closing
00297         if ( bondOpenings == 0) {
00298             return true;
00299         } else {
00300             strucStatus &=  ~STRUCTURE_VALIDITY;
00301             return false;
00302         }
00303     }
00304 
00305     bool RNAStructure_TB::hasValidBasePairs() const {
00306 
00307         if (strucStatus & BASEPAIRS_VALIDITY_CALCULATED) // If calclated, no need to recalculate
00308             return (strucStatus & BASEPAIRS_VALIDITY);
00309 
00310         //Assume validity, then change if not
00311         strucStatus |=  BASEPAIRS_VALIDITY_CALCULATED | BASEPAIRS_VALIDITY;
00312 
00313         std::stack<size_t>  openingBonds;
00314 
00315         const char open = STRUCT_ALPH.getString(STRUCT_BND_OPEN).at(0);
00316         const char close = STRUCT_ALPH.getString(STRUCT_BND_CLOSE).at(0);
00317 
00318         for (size_t j=0; j < bracketStructStr.size(); j++) {
00319 
00320             if ( bracketStructStr[j] == open ) {
00321                 openingBonds.push(j);
00322             } else if ( bracketStructStr[j] == close ) {
00323                 if (!openingBonds.empty()) {
00324                     if ( !isAllowedBasePair( j, openingBonds.top()) ) {
00325                         strucStatus &=  ~BASEPAIRS_VALIDITY;
00326                         return false;
00327                     }
00328                     openingBonds.pop();
00329                 } else {    // A chance to detect structure invalidity
00330                     strucStatus |=  STRUCTURE_VALIDITY_CALCULATED;
00331                     strucStatus &= ~STRUCTURE_VALIDITY;
00332                 }
00333             }
00334         }
00335 
00336         //we are able to determine stuctural validity
00337         if (!(strucStatus & STRUCTURE_VALIDITY_CALCULATED)) {   // if not calculated
00338             strucStatus |= STRUCTURE_VALIDITY_CALCULATED;
00339             if (!openingBonds.empty())
00340                 strucStatus &= ~STRUCTURE_VALIDITY;
00341             else
00342                 strucStatus |= STRUCTURE_VALIDITY;
00343         }
00344 
00345         return true;
00346     }
00347 
00348 
00349 
00350     bool RNAStructure_TB::hasValidLoopSize() const {
00351         if (strucStatus & LOOPSIZE_VALIDITY_CALCULATED) // If calclated, no need to recalculate
00352             return (strucStatus & LOOPSIZE_VALIDITY);
00353         //Assume validity, then change if not
00354         strucStatus |=  LOOPSIZE_VALIDITY_CALCULATED | LOOPSIZE_VALIDITY;
00355 
00356         size_t lastOpen = std::string::npos;
00357 
00358         const char open = STRUCT_ALPH.getString(STRUCT_BND_OPEN).at(0);
00359         const char close = STRUCT_ALPH.getString(STRUCT_BND_CLOSE).at(0);
00360 
00361         for (size_t j=0; j < bracketStructStr.size(); j++) {
00362 
00363             if ( bracketStructStr[j] == open ) {
00364                 lastOpen = j;
00365                 continue;
00366             } else if (lastOpen != std::string::npos && bracketStructStr[j] == close) {
00367                 if ( (j - lastOpen) <= MIN_LOOP_LENGTH) {
00368                     strucStatus &= ~LOOPSIZE_VALIDITY;
00369                     return false;
00370                 }
00371                 lastOpen = std::string::npos;
00372             }
00373         }
00374 
00375         return true;
00376     }
00377 
00378 
00379 
00380     bool RNAStructure_TB::isValidInsertMove(const size_t i, const size_t j) const{
00381         assertbiu(validTreeStruc != NULL, "no valid structure present");
00382         assertbiu(i<validTreeStruc->size(),"i index should be smaller than the structure size");
00383         assertbiu(j<validTreeStruc->size(),"j index should be smaller than the structure size");
00384         assertbiu(i!=j,"i and j should not be equal");
00385 
00386         return (
00387                 isAllowedBasePair(i, j)                         //Match (More probable to fail)
00388             && (*validTreeStruc)[i].pair == INVALID_INDEX       //Free
00389             && (*validTreeStruc)[j].pair == INVALID_INDEX       //Free
00390             && abs(j-i) > RNAStructure_TB::MIN_LOOP_LENGTH      //Loop size
00391             && areOnSameLevel(i,j)
00392             );                                                  //Nested  (On the same level) (High cost)
00393     }
00394 
00395     int
00396     RNAStructure_TB
00397 	::isValidSingleMove( const size_t i, const size_t j) const {
00398         assertbiu(validTreeStruc != NULL, "no valid structure present");
00399         assertbiu(i<validTreeStruc->size(),"i index should be smaller than the structure size");
00400         assertbiu(j<validTreeStruc->size(),"j index should be smaller than the structure size");
00401         assertbiu(i!=j,"i and j should not be equal");
00402 
00403           // check for valid deletion
00404         if (validTreeStruc->at(i).pair == j) {
00405             return -1;
00406         }
00407           // check for valid insertion
00408         if (isValidInsertMove(i,j)) {
00409             return +1;
00410         }
00411 
00412           // no valid indel
00413         return 0;
00414     }
00415 
00416 
00417     bool RNAStructure_TB::isValidLeftShiftMove(const size_t i, const size_t j, const size_t k) const{
00418         assertbiu(validTreeStruc != NULL, "no valid structure present");
00419         assertbiu(i<validTreeStruc->size(),"i index should be smaller than the structure size");
00420         assertbiu(j<validTreeStruc->size(),"j index should be smaller than the structure size");
00421         assertbiu(k<validTreeStruc->size(),"k index should be smaller than the structure size");
00422         assertbiu(i!=j,"i and j should not be equal");
00423         assertbiu(i!=k,"i and k should not be equal");
00424         assertbiu(k!=j,"k and j should not be equal");
00425 
00426         return(
00427                     isAllowedBasePair(k, j)                         //Match (More probable to fail)
00428                 && (*validTreeStruc)[j].pair == i                   //Paired (More probable to fail than free)
00429                 && (*validTreeStruc)[k].pair == INVALID_INDEX       //Free
00430                 && abs(j-k) > RNAStructure_TB::MIN_LOOP_LENGTH      //Loop size (Less probable to fail)
00431                 && (areOnSameLevel(i,k) || areOnSameLevel(k,j))     //k on one of the levels (High cost)
00432                 );
00433     }
00434 
00435     bool RNAStructure_TB::isValidRightShiftMove(const size_t i, const size_t j, const size_t k) const{
00436         assertbiu(i<validTreeStruc->size(),"i index should be smaller than the structure size");
00437         assertbiu(j<validTreeStruc->size(),"j index should be smaller than the structure size");
00438         assertbiu(k<validTreeStruc->size(),"k index should be smaller than the structure size");
00439         assertbiu(i!=j,"i and j should not be equal");
00440         assertbiu(i!=k,"i and k should not be equal");
00441         assertbiu(k!=j,"k and j should not be equal");
00442 
00443         return(
00444                     isAllowedBasePair(k, i)                         //Match (More probable to fail)
00445                 && (*validTreeStruc)[i].pair == j                   //Paired (More probable to fail than free)
00446                 && (*validTreeStruc)[k].pair == INVALID_INDEX       //Free
00447                 && abs(i-k) > RNAStructure_TB::MIN_LOOP_LENGTH      //Loop size (Less probable to fail)
00448                 && (areOnSameLevel(i,k) || areOnSameLevel(k,j))     //k on one of the levels (High cost)
00449                 );
00450     }
00451 
00452 
00453 
00454     void RNAStructure_TB::insertBond(const size_t i, const size_t j){
00455 
00456         assertbiu(isValidInsertMove(i,j),"i,j must be a valid insert move to be inserted!");
00457 
00458         setStringBrackets(i,j);         // Adjust string representation
00459 
00460         //Pair them
00461         (*validTreeStruc)[i].pair = j;
00462         (*validTreeStruc)[j].pair = i;
00463 
00464         //Push the structure between them down
00465         int in = (*validTreeStruc)[i].next;
00466         (*validTreeStruc)[i].next = (*validTreeStruc)[j].next;
00467         (*validTreeStruc)[j].next = in;
00468     }
00469     void RNAStructure_TB::deleteBond(const size_t i, const size_t j){
00470         assertbiu(isValidDeleteMove(i,j),"i,j must be a valid delete move to be deleted!");
00471 
00472         // Adjust string representation
00473         bracketStructStr[i]=bracketStructStr[j]='.';
00474 
00475         // Unpair them
00476         (*validTreeStruc)[i].pair = (*validTreeStruc)[j].pair = RNAStructure_TB::INVALID_INDEX;
00477 
00478         // Pull up the structure between them to the same level back
00479         int in = (*validTreeStruc)[i].next;
00480         (*validTreeStruc)[i].next = (*validTreeStruc)[j].next;
00481         (*validTreeStruc)[j].next = in;
00482 
00483 
00484     }
00485 
00486 
00487 
00488 
00489     void RNAStructure_TB::leftShift(const size_t i, const size_t j, const size_t k){
00490 
00491         assertbiu(isValidLeftShiftMove(i,j,k),"i,j,k must be a valid leftshift move to be shifted!");
00492         // Assertionsss
00493 
00494         shiftToBond(j,i,k);
00495 
00496     }
00497 
00498     void RNAStructure_TB::rightShift(const size_t i, const size_t j, const size_t k){
00499 
00500         assertbiu(isValidRightShiftMove(i,j,k),"i,j,k must be a valid rightshift move to be shifted!");
00501 
00502         shiftToBond(i,j,k);
00503     }
00504 
00505 
00506 
00507     bool RNAStructure_TB::initTree(const Structure& str) {
00508         assertbiu(str.size()>0,"str shouldn't be an empty structure");
00509 
00510           // std::stack openingBonds contains opening bonds to create
00511           // vector rnaBonds during intitialisation
00512         std::stack<size_t>  openingBonds;
00513         size_t i,j;
00514           // do update for real initialisation
00515 
00516         //-1 the step will be done seperatly after that for efficiency
00517         for (j=0; j < str.size()-1; j++) {
00518             (*validTreeStruc)[j].next = j+1;    //Building the default unfolded next structure
00519 
00520             if ( str[j] == STRUCT_BND_OPEN )
00521                 openingBonds.push(j);
00522             else if ( str[j] == STRUCT_BND_CLOSE ) {
00523                 if (    openingBonds.empty()
00524                     ||  j-(i = openingBonds.top()) <= RNAStructure_TB::MIN_LOOP_LENGTH
00525                     ||  !isAllowedBasePair(i, j)
00526                         ) return false;         // Break but still uncertain why
00527                 openingBonds.pop();
00528 
00529                 //Pair them
00530                 (*validTreeStruc)[j].pair = i;
00531                 (*validTreeStruc)[i].pair = j;
00532                 //Level down
00533                 size_t in = (*validTreeStruc)[i].next;
00534                 (*validTreeStruc)[i].next = (*validTreeStruc)[j].next;
00535                 (*validTreeStruc)[j].next = in;
00536             }else (*validTreeStruc)[j].pair = INVALID_INDEX;
00537         }
00538 
00539         (*validTreeStruc)[j].next = 0; // Block was repeated to avoid an extra if
00540         (*validTreeStruc)[j].pair = INVALID_INDEX;
00541         if ( str[j] == STRUCT_BND_OPEN ) // Loop block specialized for last step
00542             return false;
00543         else if ( str[j] == STRUCT_BND_CLOSE ) {
00544             if (    openingBonds.empty()
00545                 ||  j-(i = openingBonds.top()) <= RNAStructure_TB::MIN_LOOP_LENGTH
00546                 ||  !isAllowedBasePair(i, j)
00547                     ) return false;
00548             openingBonds.pop();
00549 
00550 
00551             (*validTreeStruc)[j].pair = i;
00552             (*validTreeStruc)[i].pair = j;
00553             size_t in = (*validTreeStruc)[i].next;
00554             (*validTreeStruc)[i].next = (*validTreeStruc)[j].next;
00555             (*validTreeStruc)[j].next = in;
00556         }else (*validTreeStruc)[j].pair = INVALID_INDEX;
00557 
00558         if (openingBonds.empty()) {
00559             strucStatus =       // All calculated & valid
00560                                 BASEPAIRS_VALIDITY
00561                             |   BASEPAIRS_VALIDITY_CALCULATED
00562                             |   LOOPSIZE_VALIDITY
00563                             |   LOOPSIZE_VALIDITY_CALCULATED
00564                             |   STRUCTURE_VALIDITY
00565                             |   STRUCTURE_VALIDITY_CALCULATED;
00566             return true;
00567         }else {                 // All calculated, all valid except for structure
00568             strucStatus =       BASEPAIRS_VALIDITY
00569                             |   BASEPAIRS_VALIDITY_CALCULATED
00570                             |   LOOPSIZE_VALIDITY
00571                             |   LOOPSIZE_VALIDITY_CALCULATED
00572                             |   !STRUCTURE_VALIDITY
00573                             |   STRUCTURE_VALIDITY_CALCULATED;
00574             return false;
00575         }
00576 
00577     }
00578 
00579 
00580 
00581     std::string RNAStructure_TB::decodedStatus() const{
00582         std::string x =   (strucStatus&BASEPAIRS_VALIDITY)!=0?"BP| ":"";
00583         x+= (strucStatus&BASEPAIRS_VALIDITY_CALCULATED)!=0?"BPC ":"";
00584         x+="\n";
00585         x+= (strucStatus&LOOPSIZE_VALIDITY)!=0?"L| ":"";
00586         x+= (strucStatus&LOOPSIZE_VALIDITY_CALCULATED)!=0?"LC ":"";
00587         x+="\n";
00588         x+= (strucStatus&STRUCTURE_VALIDITY)!=0?"S| ":"";
00589         x+= (strucStatus&STRUCTURE_VALIDITY_CALCULATED)!=0?"SC ":"";
00590 
00591         return x;
00592 
00593     }
00594 
00595 
00596 
00597     bool RNAStructure_TB::isValidUnorderedShift(const size_t i, const size_t j) const{
00598         assertbiu(i!=j,"i and j should not be equal");
00599         assertbiu(  (*validTreeStruc)[i].pair== INVALID_INDEX ||
00600                     (*validTreeStruc)[j].pair== INVALID_INDEX ||
00601                     (*validTreeStruc)[i].pair!=(*validTreeStruc)[j].pair
00602                     ,"i and j chouldn't be paired to the same base, invalid structure");
00603 
00604         if (!isAllowedBasePair(i,j)) return false;
00605         if ((*validTreeStruc)[i].pair!=INVALID_INDEX){ //i is the paired one
00606             return
00607                     (*validTreeStruc)[j].pair==INVALID_INDEX
00608                 &&  abs(i-j) > RNAStructure_TB::MIN_LOOP_LENGTH         //Loop size (Less probable to fail)
00609                 &&  (areOnSameLevel(i,j) || areOnSameLevel(j,(*validTreeStruc)[i].pair));
00610 
00611         }else if ((*validTreeStruc)[j].pair!=INVALID_INDEX){//j is the paired one
00612             return
00613                     (*validTreeStruc)[i].pair==INVALID_INDEX
00614                 &&  abs(i-j) > RNAStructure_TB::MIN_LOOP_LENGTH         //Loop size (Less probable to fail)
00615                 &&  (areOnSameLevel(i,j) || areOnSameLevel(i,(*validTreeStruc)[j].pair));
00616 
00617         }else return false;//both unpaired
00618     }
00619 
00620 
00621     bool RNAStructure_TB::isValidShift(const size_t i, const size_t j) const{
00622         assertbiu(i!=j,"i and j should not be equal");
00623         assertbiu(  (*validTreeStruc)[i].pair== INVALID_INDEX ||
00624                     (*validTreeStruc)[j].pair== INVALID_INDEX ||
00625                     (*validTreeStruc)[i].pair!=(*validTreeStruc)[j].pair
00626                     ,"i and j chouldn't be paired to the same base, Invalid structure!!");
00627 
00628 
00629             return
00630                 isAllowedBasePair(i, j)                         //Match (More probable to fail)
00631                 && (*validTreeStruc)[j].pair!=INVALID_INDEX
00632                 && (*validTreeStruc)[i].pair==INVALID_INDEX
00633                 && abs(i-j) > RNAStructure_TB::MIN_LOOP_LENGTH      //Loop size (Less probable to fail)
00634                 && (areOnSameLevel(i,j) || areOnSameLevel(j,(*validTreeStruc)[i].pair));
00635 
00636     }
00637 
00638 
00639 
00640     void RNAStructure_TB::shiftUnordered(const size_t i, const size_t j){
00641 <<<<<<< RNAStructure_TB.cc
00642         assertbiu(isValidShift(i,j),"i,j must be a valid shift move to be shifted!");
00643         
00644 =======
00645         assertbiu(isValidShiftMove(i,j),"i,j must be a valid shift move to be shifted!");
00646 
00647 >>>>>>> 1.5
00648         if ((*validTreeStruc)[i].pair!=INVALID_INDEX)//i is paired
00649             shiftToBond(i,j);
00650         else// j is paired
00651             shiftToBond(j,i);
00652     }
00653 
00654     void RNAStructure_TB::shiftToBond(const size_t i, const size_t k){
00655         assertbiu( (*validTreeStruc)[i].pair!=k
00656                 ,"Warning: rearrangeWith(i,k) should be called before changing the .pair of i into k");
00657         // Assert every thing
00658 
00659         size_t j = (*validTreeStruc)[i].pair;
00660         size_t jn = (*validTreeStruc)[j].next;
00661         (*validTreeStruc)[j].next = (*validTreeStruc)[i].next;
00662         (*validTreeStruc)[i].next = (*validTreeStruc)[k].next;
00663         (*validTreeStruc)[k].next = jn;
00664 
00665 
00666         (*validTreeStruc)[i].pair = k;
00667         (*validTreeStruc)[k].pair = i;
00668         (*validTreeStruc)[j].pair =  RNAStructure_TB::INVALID_INDEX;
00669 
00670         setStringBrackets(i,k);
00671         bracketStructStr[j]='.';
00672 
00673     }
00674 
00675     void RNAStructure_TB::shiftToBond(const size_t i, const size_t j, const size_t k){
00676         // Assert i,j are pairs
00677         // Assert every thing
00678 
00679 
00680         size_t jn = (*validTreeStruc)[j].next;
00681         (*validTreeStruc)[j].next = (*validTreeStruc)[i].next;
00682         (*validTreeStruc)[i].next = (*validTreeStruc)[k].next;
00683         (*validTreeStruc)[k].next = jn;
00684 
00685 
00686         (*validTreeStruc)[i].pair = k;
00687         (*validTreeStruc)[k].pair = i;
00688         (*validTreeStruc)[j].pair =  RNAStructure_TB::INVALID_INDEX;
00689 
00690         setStringBrackets(i,k);
00691         bracketStructStr[j]='.';
00692     }
00693 
00694 
00695 
00696     size_t RNAStructure_TB::moveType(size_t i, size_t j) const {
00697         //000   <=> both unpaired               <=> insert; //Order not important
00698         //010   <=> i is paired                 <=> shiftToBond (i,j)
00699         //100   <=> j is paired                 <=> shiftToBond (j,i)
00700         //110   <=> both paired                 <=> invalid delete(i,j)
00701         //111   <=> both paired to each other   <=> valid delete(i,j)   //Order not important
00702         size_t res = 0;
00703 
00704           // direct return if paired with each other == valid delete
00705         if ((*validTreeStruc)[i].pair==j) return 7;
00706 
00707           // check which is bound
00708         if ((*validTreeStruc)[i].pair!=INVALID_INDEX) res|=2;
00709         if ((*validTreeStruc)[j].pair!=INVALID_INDEX) res|=4;
00710 
00711         return res;
00712 
00713     }
00714 
00715     void RNAStructure_TB::executeOrderedMove(size_t i, size_t j){
00716 
00717         if ((*validTreeStruc)[i].pair==INVALID_INDEX){
00718             if ((*validTreeStruc)[j].pair==INVALID_INDEX){
00719                 insertBond(i,j);
00720             }
00721             else{
00722                 shiftToBond(j,i);
00723             }
00724         }
00725         else if ((*validTreeStruc)[j].pair==INVALID_INDEX){
00726             shiftToBond(i,j);
00727         }else{
00728             if ((*validTreeStruc)[j].pair==i) deleteBond(i,j);
00729             assertbiu((*validTreeStruc)[j].pair==i,"executing an move that is decoded into an invalid delete move!!");
00730         }
00731     }
00732 
00733     bool RNAStructure_TB::executeOrderedMoveTry(size_t i, size_t j){
00734         if ((*validTreeStruc)[i].pair==INVALID_INDEX){
00735             if ((*validTreeStruc)[j].pair==INVALID_INDEX){
00736                 if (isValidInsertMove(i,j)){
00737                     insertBond(i,j);
00738                     return true;
00739                 }
00740             }
00741             else{
00742                 if (isValidShift(j,i)){
00743                     shiftToBond(j,i);
00744                     return true;
00745                 }
00746             }
00747         }
00748         else if ((*validTreeStruc)[j].pair==INVALID_INDEX){
00749             if (isValidShift(i,j)){
00750                 shiftToBond(i,j);
00751                 return true;
00752             }
00753         }else{
00754             if (isValidDeleteMove(i,j)){
00755                 deleteBond(i,j);
00756                 return true;
00757             }
00758         }
00759 
00760         return false;
00761     }
00762 
00763 
00764     bool
00765     RNAStructure_TB
00766 	::getNextSingleMove( size_t& i, size_t& j ) const
00767     {
00768         assertbiu(validTreeStruc != NULL, "no valid structure present");
00769         assertbiu(i<=j, "index i is greater than j");
00770         assertbiu(&i!=&j, "referenced variable i and j are the same !!!");
00771           // check if first single move is to find
00772         if ( i == INVALID_INDEX ) {
00773             i = 0;
00774             j = 0;
00775         } else {
00776               // last move was a base pair
00777             if (validTreeStruc->at(i).pair == j ) {
00778                 i++;
00779                 j = (size_t)i;
00780             }
00781               // was no base pair deletion .. maybe an insertion
00782             else {
00783                 j = (size_t)validTreeStruc->at(j).next;
00784                   // check if j out of bound
00785                 if (j <= i || j >= validTreeStruc->size()) {
00786                     i++;
00787                     j = (size_t)i;
00788                 }
00789             }
00790         }
00791 
00792         size_t minJpos = i+MIN_LOOP_LENGTH+1;
00793 
00794         while ( minJpos < validTreeStruc->size() ) {
00795 
00796               // check if j was not set yet
00797             if (i==j) {
00798                 if (validTreeStruc->at(i).pair != INVALID_INDEX
00799                         && validTreeStruc->at(i).pair > i )
00800                 {
00801                     j = (size_t)validTreeStruc->at(i).pair;
00802                     return true;
00803                 }
00804                 j = (size_t)validTreeStruc->at(i).next;
00805                   // set j to minimal distance allowed for a base pair
00806                 while (i<j && j < validTreeStruc->size() && j < minJpos) {
00807                     j = (size_t)validTreeStruc->at(j).next;
00808                 }
00809             }
00810               // otherwise assure that j has min-loop-distance from i
00811             else if (j < minJpos) {
00812                 j = (size_t)validTreeStruc->at(i).next;
00813                   // set j to minimal distance allowed for a base pair
00814                 while (i<j && j < validTreeStruc->size() && j < minJpos) {
00815                     j = (size_t)validTreeStruc->at(j).next;
00816                 }
00817             }
00818 
00819               // check if j is a valid index
00820             if ( i < j && j < validTreeStruc->size()) {
00821                   // check if i and j are paired or can form a base pair
00822                 if (validTreeStruc->at(i).pair == j
00823                     || (validTreeStruc->at(j).pair
00824                             == INVALID_INDEX && isAllowedBasePair(i,j)))
00825                 {
00826                     return true;
00827                 }
00828 
00829                   // update j to next possible pairing partner of i
00830                 j = (size_t)validTreeStruc->at(j).next;
00831                 if (i>=j || j > validTreeStruc->size()) {
00832                     i++;
00833                     j = (size_t)i;
00834                 }
00835             } else {
00836                 i++;
00837                 j = (size_t)i;
00838             }
00839               // minimal position of j to allow for a base pair
00840             minJpos = i+MIN_LOOP_LENGTH+1;
00841         }
00842         return false;
00843     }
00844 
00845 
00846     void RNAStructure_TB::decodeMoveIndex(size_t const index,  size_t&  i,  size_t&  j) const
00847     {
00848 
00849         assertbiu(index<getMoveIndexCount(),"Index should be in [0 .. n.(n-1)/2[ ");
00850 
00851         size_t n =  rnaSeq->size();
00852 
00853         if ((n & 1)==0){    //even
00854 
00855             j = index % (n-1);
00856             i = index / (n-1);
00857             if (i>j) {
00858                 i=n-i-1;
00859                 j=n-j-1;
00860 
00861             } else {
00862                 //  i = i;
00863                 j=j+1;
00864             }
00865 
00866         } else {            //odd
00867             j = index % n;
00868             i = index / n;
00869             if (i>=j) {
00870                 i=n-i-2;
00871                 j=n-j-1;
00872 
00873             } else {
00874                 //Same! i and j
00875             }
00876         }
00877     }
00878 
00879                     //The previous code is a compact form of the following sample:
00880 //                  ----------------------------------------------------------
00881 //                  int i,j,n;
00882 //                  n=4;
00883 //                      for (i=0; i < n/2; ++i){
00884 //                  for (j = 0; j < n-1; ++j) {
00885 //                          if (i>j){
00886 //                              std::cout <<n-i-1<<"-"<<n-j-1<<"\n";
00887 //                          }else{
00888 //                              std::cout <<i<<" "<<j+1<<"\n";
00889 //                          }
00890 //                      }
00891 //                  }
00892 //                  std::cout << "------\n";
00893 //                  n=5;
00894 //                  //
00895 //                      for (i=0; i < (n-1)/2; ++i){
00896 //                  for (j = 0; j < n; ++j) {
00897 //                          if (i>=j){
00898 //                              std::cout <<n-i-2<<"-"<<n-j-1<<"\n";
00899 //                          }else{
00900 //                              std::cout <<i<<" "<<j<<"\n";
00901 //                          }
00902 //                      }
00903 //                  }
00904 
00905 //                  Output:
00906 //                  0 1
00907 //                  2-3
00908 //                  0 2
00909 //                  1 2
00910 //                  0 3
00911 //                  1 3
00912 //                  -----
00913 //                  3-4
00914 //                  2-4
00915 //                  0 1
00916 //                  2-3
00917 //                  0 2
00918 //                  1 2
00919 //                  0 3
00920 //                  1 3
00921 //                  0 4
00922 //                  1 4
00923 
00924 
00925 
00926 
00927 
00928     bool RNAStructure_TB::executeOrderedMoveTry(size_t const index){
00929         size_t i,j;
00930         decodeMoveIndex(index,i,j);
00931         return  executeOrderedMoveTry(i,j);
00932     }
00933 
00934     inline size_t RNAStructure_TB::getMoveIndexCount() const{
00935         return rnaSeq->size()*(rnaSeq->size()-1)/2;
00936     }
00937 
00938 
00939 } // namespace biu
00940