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
00040
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
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
00175 if (seqShared) {
00176 rnaSeq = rnaStruct2.rnaSeq;
00177 } else {
00178 rnaSeq->resize(rnaStruct2.rnaSeq->size());
00179 std::copy( rnaStruct2.rnaSeq->begin(),
00180 rnaStruct2.rnaSeq->end(),
00181 rnaSeq->begin());
00182 }
00183
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
00228
00229
00230
00231
00232
00233
00234
00235 return res && (
00236 validTreeStruc==rnaStruct2.validTreeStruc
00237 || *validTreeStruc==*(rnaStruct2.validTreeStruc)
00238 );
00239 }
00240
00241
00242
00243
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;
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)
00271 return (strucStatus & STRUCTURE_VALIDITY);
00272
00273
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
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)
00308 return (strucStatus & BASEPAIRS_VALIDITY);
00309
00310
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 {
00330 strucStatus |= STRUCTURE_VALIDITY_CALCULATED;
00331 strucStatus &= ~STRUCTURE_VALIDITY;
00332 }
00333 }
00334 }
00335
00336
00337 if (!(strucStatus & STRUCTURE_VALIDITY_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)
00352 return (strucStatus & LOOPSIZE_VALIDITY);
00353
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)
00388 && (*validTreeStruc)[i].pair == INVALID_INDEX
00389 && (*validTreeStruc)[j].pair == INVALID_INDEX
00390 && abs(j-i) > RNAStructure_TB::MIN_LOOP_LENGTH
00391 && areOnSameLevel(i,j)
00392 );
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
00404 if (validTreeStruc->at(i).pair == j) {
00405 return -1;
00406 }
00407
00408 if (isValidInsertMove(i,j)) {
00409 return +1;
00410 }
00411
00412
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)
00428 && (*validTreeStruc)[j].pair == i
00429 && (*validTreeStruc)[k].pair == INVALID_INDEX
00430 && abs(j-k) > RNAStructure_TB::MIN_LOOP_LENGTH
00431 && (areOnSameLevel(i,k) || areOnSameLevel(k,j))
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)
00445 && (*validTreeStruc)[i].pair == j
00446 && (*validTreeStruc)[k].pair == INVALID_INDEX
00447 && abs(i-k) > RNAStructure_TB::MIN_LOOP_LENGTH
00448 && (areOnSameLevel(i,k) || areOnSameLevel(k,j))
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);
00459
00460
00461 (*validTreeStruc)[i].pair = j;
00462 (*validTreeStruc)[j].pair = i;
00463
00464
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
00473 bracketStructStr[i]=bracketStructStr[j]='.';
00474
00475
00476 (*validTreeStruc)[i].pair = (*validTreeStruc)[j].pair = RNAStructure_TB::INVALID_INDEX;
00477
00478
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
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
00511
00512 std::stack<size_t> openingBonds;
00513 size_t i,j;
00514
00515
00516
00517 for (j=0; j < str.size()-1; j++) {
00518 (*validTreeStruc)[j].next = j+1;
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;
00527 openingBonds.pop();
00528
00529
00530 (*validTreeStruc)[j].pair = i;
00531 (*validTreeStruc)[i].pair = j;
00532
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;
00540 (*validTreeStruc)[j].pair = INVALID_INDEX;
00541 if ( str[j] == STRUCT_BND_OPEN )
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 =
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 {
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){
00606 return
00607 (*validTreeStruc)[j].pair==INVALID_INDEX
00608 && abs(i-j) > RNAStructure_TB::MIN_LOOP_LENGTH
00609 && (areOnSameLevel(i,j) || areOnSameLevel(j,(*validTreeStruc)[i].pair));
00610
00611 }else if ((*validTreeStruc)[j].pair!=INVALID_INDEX){
00612 return
00613 (*validTreeStruc)[i].pair==INVALID_INDEX
00614 && abs(i-j) > RNAStructure_TB::MIN_LOOP_LENGTH
00615 && (areOnSameLevel(i,j) || areOnSameLevel(i,(*validTreeStruc)[j].pair));
00616
00617 }else return false;
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)
00631 && (*validTreeStruc)[j].pair!=INVALID_INDEX
00632 && (*validTreeStruc)[i].pair==INVALID_INDEX
00633 && abs(i-j) > RNAStructure_TB::MIN_LOOP_LENGTH
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)
00649 shiftToBond(i,j);
00650 else
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
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
00677
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
00698
00699
00700
00701
00702 size_t res = 0;
00703
00704
00705 if ((*validTreeStruc)[i].pair==j) return 7;
00706
00707
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
00772 if ( i == INVALID_INDEX ) {
00773 i = 0;
00774 j = 0;
00775 } else {
00776
00777 if (validTreeStruc->at(i).pair == j ) {
00778 i++;
00779 j = (size_t)i;
00780 }
00781
00782 else {
00783 j = (size_t)validTreeStruc->at(j).next;
00784
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
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
00806 while (i<j && j < validTreeStruc->size() && j < minJpos) {
00807 j = (size_t)validTreeStruc->at(j).next;
00808 }
00809 }
00810
00811 else if (j < minJpos) {
00812 j = (size_t)validTreeStruc->at(i).next;
00813
00814 while (i<j && j < validTreeStruc->size() && j < minJpos) {
00815 j = (size_t)validTreeStruc->at(j).next;
00816 }
00817 }
00818
00819
00820 if ( i < j && j < validTreeStruc->size()) {
00821
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
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
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){
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
00863 j=j+1;
00864 }
00865
00866 } else {
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
00875 }
00876 }
00877 }
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
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 }
00940