Generated on Tue Dec 16 13:34:01 2008 for ell-3.0.0 by doxygen 1.5.1

src/ell/rna/S_RNAfe_SingleM_TB.cc

Go to the documentation of this file.
00001 #include "ell/rna/S_RNAfe_SingleM_TB.hh"
00002 #include <cmath>    // for getFitness()
00003 #include <biu/assertbiu.hh>
00004 #include "biu/RandomNumberFactory.hh"
00005 
00006 
00007 namespace ell
00008 {
00009 
00010     // the specific ID string of this class
00011     const std::string S_RNAfe_SingleM_TB::ID = std::string("ell::S_RNAfe_SingleM_TB");
00012 
00013 
00014     const size_t 
00015         S_RNAfe_SingleM_TB::RandomNeighborList::ItState::SWITCH_MODE_THRESHOLD = 20;
00016         
00018 // S_RNAfe_SingleM_TB
00020 
00021     S_RNAfe_SingleM_TB::S_RNAfe_SingleM_TB(
00022                 const std::string& rnaSeqStr, 
00023                 const std::string& rnaStructBracketNotStr)
00024      :  rnaFreeEnergy(rnaSeqStr, rnaStructBracketNotStr)
00025     {
00026         assertbiu(rnaFreeEnergy.isValid(),
00027          "S_RNAfe_SingleM_TB has to be a valid state.");
00028          
00029     }
00030 
00031     S_RNAfe_SingleM_TB::S_RNAfe_SingleM_TB(const RNAFreeEnergy_TB& rna)
00032      :  rnaFreeEnergy(rna)
00033     {
00034         assertbiu(rnaFreeEnergy.isValid(),
00035          "S_RNAfe_SingleM_TB has to be a valid state.");
00036          
00037     }
00038     
00039     S_RNAfe_SingleM_TB::S_RNAfe_SingleM_TB(
00040                 const S_RNAfe_SingleM_TB& rnaFESMS)
00041      : rnaFreeEnergy(rnaFESMS.rnaFreeEnergy)
00042     {
00043     }
00044 
00045     S_RNAfe_SingleM_TB::~S_RNAfe_SingleM_TB() 
00046     {
00047     }
00048 
00049     /* Access to a State subclass specific ID string to identify 
00050      * instances of this class.
00051      * @return the subclass specific ID string
00052      */
00053     const std::string& 
00054     S_RNAfe_SingleM_TB::getID( void ) const {
00055         return S_RNAfe_SingleM_TB::ID;
00056     }
00057 
00058     
00059     S_RNAfe_SingleM_TB::SingleMove 
00060     S_RNAfe_SingleM_TB::firstValidSingleMove() const {
00061         SingleMove m(   biu::RNAStructure_TB::INVALID_INDEX
00062                         , biu::RNAStructure_TB::INVALID_INDEX );
00063         if (rnaFreeEnergy.getNextSingleMove(m.first, m.second)) {
00064             return m;
00065         } else {
00066             return SingleMove(0,biu::RNAStructure_TB::INVALID_INDEX);
00067         }
00068     }
00069 
00070     S_RNAfe_SingleM_TB::SingleMove 
00071     S_RNAfe_SingleM_TB::nextValidSingleMove( 
00072             const SingleMove lastSingleMove) const 
00073     {
00074         SingleMove ret(lastSingleMove);
00075         if (rnaFreeEnergy.getNextSingleMove( ret.first, ret.second ))
00076         {
00077             return ret;
00078         } else {
00079             return SingleMove(0,biu::RNAStructure_TB::INVALID_INDEX);
00080         }
00081 //      // if lastSingleMove.first is an opening bond, this bond was already
00082 //      // modified in the last move
00083 //      // closing bonds at lastSingleMove.first are not for interest
00084 //      if (rnaFreeEnergy.getCorrespondingBase(lastSingleMove.first) != biu::RNAStructure_TB::INVALID_INDEX ) {
00085 //          return searchForNextValidSingleMove(lastSingleMove.first+1,
00086 //              lastSingleMove.first+2);
00087 //      }
00088 //      else {
00089 //          return searchForNextValidSingleMove(lastSingleMove.first,
00090 //              lastSingleMove.second+1);
00091 //      }
00092     }
00093 
00094 //  S_RNAfe_SingleM_TB::SingleMove 
00095 //  S_RNAfe_SingleM_TB:: searchForNextValidSingleMove(  size_t pos1, 
00096 //                              size_t pos2) const 
00097 //  {
00098 //      assertbiu(pos1 < pos2,
00099 //       "RNA single move search pos 1 has to be less than pos 2");
00100 //      
00101 //
00102 //  if (pos2>=rnaFreeEnergy.getLength() ) {
00103 //      pos1++;
00104 //      pos2 = pos1+1;
00105 //  }
00108 //
00109 //      
00110 //      // distance between pos1 and pos2 has to be at least
00111 //      //  MIN_LOOP_LENGTH
00112 //      while ( (pos1+rnaFreeEnergy.getMinLoopLength())
00113 //               < rnaFreeEnergy.getLength()) 
00114 //      {
00115 //          if ( rnaFreeEnergy.getCorrespondingBase(pos1) == biu::RNAStructure_TB::INVALID_INDEX )
00116 //          {
00117 //              for(pos2 = rnaFreeEnergy.nextCompatibleSingleMovePos(pos2-1);
00118 //                  pos2 < rnaFreeEnergy.getLength();
00119 //                  pos2 = rnaFreeEnergy.nextCompatibleSingleMovePos(pos2))
00120 //              {
00121 //                  if ((pos2 - pos1) > rnaFreeEnergy.getMinLoopLength() &&
00122 //                       rnaFreeEnergy.isAllowedBasePair(pos1, pos2)) {
00123 //                          // found bases which are able to pair
00124 //                          // -> exit loop
00125 //                      return SingleMove(pos1,pos2);
00126 //                      break;
00127 //                  }
00128 //              }
00129 //          }
00130 //          else if ( rnaFreeEnergy.getCorrespondingBase(pos1) > pos1 )
00131 //          {
00132 //                  // existing bond found -> exit loop
00133 //              return SingleMove(pos1,rnaFreeEnergy.getCorrespondingBase(pos1));
00134 //          }
00135 //              // loop wasn't exited since no next valid single move was found
00136 //          pos1++;
00137 //          pos2 = pos1 + 1;
00138 //      }
00139 //      // no next valid single move found
00140 //      return SingleMove(0,biu::RNAStructure_TB::INVALID_INDEX);
00141 //  }
00142 
00143     bool    
00144     S_RNAfe_SingleM_TB::operator== (const State& state2) const {
00145           // check if convertable
00146         const S_RNAfe_SingleM_TB * tmp 
00147             = dynamic_cast< const S_RNAfe_SingleM_TB*>(&state2);
00148         return (tmp==NULL? false : rnaFreeEnergy == tmp->rnaFreeEnergy);
00149     }
00150 
00151     bool
00152     S_RNAfe_SingleM_TB::operator!= (const State& state2) const {
00153         return !(this->operator==(state2));
00154     }
00155 
00156     bool
00157     S_RNAfe_SingleM_TB::operator< (const State& rna2) const
00158     {
00159         if (this == &rna2) {
00160             return false;
00161         }
00162         assertbiu(dynamic_cast<const S_RNAfe_SingleM_TB*>(&rna2)!=NULL
00163                     , "rna2 is no S_RNAfe_SingleM_TB object");
00164         const S_RNAfe_SingleM_TB* s2 = static_cast<const S_RNAfe_SingleM_TB*>(&rna2);
00165         assertbiu(rnaFreeEnergy.getLength() == s2->rnaFreeEnergy.getLength()
00166                     , "the two RNA molecules differ in length");
00167         
00168         return (this->getEnergy() < s2->getEnergy())
00169                 || 
00170                 (this->getEnergy() == s2->getEnergy()
00171                 && rnaFreeEnergy.getStructureStringRef().compare(
00172                         s2->rnaFreeEnergy.getStructureStringRef() ) < 0 ) ;
00173     }
00174     
00175     double  
00176     S_RNAfe_SingleM_TB::getEnergy(void) const {
00177         return rnaFreeEnergy.getEnergy();
00178     }
00179 
00180     unsigned int    
00181     S_RNAfe_SingleM_TB::getMinimalDistance( const State& _state2) const 
00182     {
00183         assertbiu(dynamic_cast<const S_RNAfe_SingleM_TB*>(&_state2) != NULL
00184                 , "state to calculate distance to is no S_RNAfe_SingleM_TB");
00185         const S_RNAfe_SingleM_TB* state2 = 
00186          static_cast<const S_RNAfe_SingleM_TB*>(&_state2);
00187 
00188         const std::string& state1Struct = this->rnaFreeEnergy.getStructureStringRef();
00189         const std::string& state2Struct = state2->rnaFreeEnergy.getStructureStringRef();
00190 
00191         assertbiu(state2Struct.size() == state1Struct.size(),
00192         "Length of both RNA has to be equal to compute the distance.");
00193             
00194         unsigned int distance = 0;
00195         
00196         const char BOND_OPEN = this->rnaFreeEnergy.getStructureAlphabet()->getString(biu::RNAStructure_TB::STRUCT_BND_OPEN).at(0); 
00197         
00198         for (size_t i = 0; i < state1Struct.size(); i++){
00199             // bond maintained or bond opened and replaced by another one
00200             if (    BOND_OPEN == state1Struct[i] 
00201                     && BOND_OPEN == state2Struct[i] ) 
00202             {
00203                 // check if bond opened and replaced by another one
00204                 if (    this->rnaFreeEnergy.getCorrespondingBase(i) 
00205                         != state2->rnaFreeEnergy.getCorrespondingBase(i)) 
00206                 {
00207                     distance += 2;
00208                 }
00209             }
00210             // one bond opened or closed
00211             else if (   BOND_OPEN == state1Struct[i]  
00212                         || BOND_OPEN == state2Struct[i] ) 
00213             {
00214                 distance += 1;
00215             }
00216         }
00217         return distance;
00218     }
00219 
00220     S_RNAfe_SingleM_TB* 
00221     S_RNAfe_SingleM_TB::clone(State* toFill) const {
00222         if (toFill == NULL) {
00223             return new S_RNAfe_SingleM_TB(*this);
00224         }
00225           // cast toFill
00226         assertbiu( dynamic_cast<S_RNAfe_SingleM_TB*>(toFill) != NULL
00227                     , "given State is no S_RNAfe_SingleM_TB instance");
00228         S_RNAfe_SingleM_TB* s = static_cast<S_RNAfe_SingleM_TB*>(toFill);
00229         
00230           // copy data
00231         s->rnaFreeEnergy = this->rnaFreeEnergy; 
00232         
00233         return s;
00234     }
00235     
00236     
00237     State*
00238     S_RNAfe_SingleM_TB::fromString(const std::string& stringRep) const {
00239           // parse structure
00240         std::string backboneRep = ".()";
00241         size_t pos = stringRep.find_first_not_of(backboneRep);
00242         const std::string rnaStructBracketDotStr = stringRep.substr(0, pos-1);
00243         assertbiu(rnaStructBracketDotStr.size() != 0, "string does not contain a dot-bracket structure encoding");
00244         assertbiu(rnaStructBracketDotStr.size() == this->rnaFreeEnergy.getLength(), "string is too short for this RNA molecule");
00245           // create new copy of this
00246         S_RNAfe_SingleM_TB* ret = this->clone();
00247           // set structure
00248         ret->rnaFreeEnergy.setStructure(
00249                 ret->rnaFreeEnergy.getStructureAlphabet()->getSequence(
00250                         rnaStructBracketDotStr));
00251         return ret;
00252     }
00253     
00254     State*
00255     S_RNAfe_SingleM_TB::fromString(const std::string& stringRep, const double energy) const {
00256           // create state from string
00257         State* ret = this->fromString(stringRep);
00258           // set energy
00259         static_cast<S_RNAfe_SingleM_TB*>(ret)->rnaFreeEnergy.setEnergy(energy);
00260           // return updated state
00261         return ret;
00262     }
00263     
00264     std::string 
00265     S_RNAfe_SingleM_TB::toString() const{
00266         return rnaFreeEnergy.getStructureString();
00267     }
00268     
00269     std::string& 
00270     S_RNAfe_SingleM_TB::toString( std::string & toFill ) const {
00271           // nothing better so far
00272         toFill = rnaFreeEnergy.getStructureStringRef();
00273         return toFill;
00274     }
00275     
00276     std::string 
00277     S_RNAfe_SingleM_TB::getSequence() const {
00278         return rnaFreeEnergy.getSequenceString();
00279     }
00280     
00281     std::string 
00282     S_RNAfe_SingleM_TB::getStructure() const {
00283         return rnaFreeEnergy.getStructureString();
00284     }
00285 
00286     State::NeighborListPtr 
00287     S_RNAfe_SingleM_TB::getNeighborList() const {
00288         return NeighborListPtr(new NeighborList(this));
00289     }
00290 
00291     State::NeighborListPtr
00292     S_RNAfe_SingleM_TB::getRandomNeighborList() const 
00293     {
00294         return NeighborListPtr(new RandomNeighborList(this));
00295     }
00296 
00297     // NeighborList
00298     S_RNAfe_SingleM_TB::NeighborList::NeighborList(
00299                 const S_RNAfe_SingleM_TB* _origin) 
00300      : origin(_origin) 
00301     {
00302     }
00303 
00304     S_RNAfe_SingleM_TB::NeighborList::~NeighborList() {
00305     }
00306 
00307     State* 
00308     S_RNAfe_SingleM_TB::NeighborList::first(
00309               State::NeighborList::ItState** itstate) const {
00310         if (*itstate != NULL) delete *itstate;
00311 
00312         ItState* myitstate = new ItState();
00313         *itstate = myitstate;
00314         
00315         S_RNAfe_SingleM_TB* rnaState = NULL;
00316 
00317         SingleMove firstMove = origin->firstValidSingleMove();
00318         
00319 
00320         if (firstMove != SingleMove(0,biu::RNAStructure_TB::INVALID_INDEX)) {
00321             rnaState = new S_RNAfe_SingleM_TB(*origin);
00322             rnaState->rnaFreeEnergy.applySingleMoveInPlace(firstMove);
00323             myitstate->lastMove = firstMove;
00324         }
00325         return rnaState;
00326     }
00327 
00328     State* 
00329     S_RNAfe_SingleM_TB::NeighborList::next(
00330               State::NeighborList::ItState* itstate, State* elem) const {
00331         assertbiu(elem != NULL, "elem is not allowed to be NULL");
00332         assertbiu(dynamic_cast<S_RNAfe_SingleM_TB*>(elem) != NULL
00333                 , "elem is no instance of S_RNAfe_SingleM_TB");
00334 
00335         ItState* myitstate = static_cast<ItState*>(itstate);
00336 
00337         // find next move
00338         SingleMove nextMove = origin->nextValidSingleMove(myitstate->lastMove);
00339         // no more moves possible
00340         if (nextMove == SingleMove(0,biu::RNAStructure_TB::INVALID_INDEX)) {
00341             return NULL;
00342         }
00343         else {
00344             S_RNAfe_SingleM_TB* rnaState 
00345                     = static_cast<S_RNAfe_SingleM_TB*>(elem);
00346             // undo last move
00347             rnaState->rnaFreeEnergy.applySingleMoveInPlace(myitstate->lastMove);
00348             // perform next move
00349             rnaState->rnaFreeEnergy.applySingleMoveInPlace(nextMove);
00350             myitstate->lastMove = nextMove;
00351             return rnaState;
00352         }
00353     }
00354 
00355     // RandomNeighborList
00356     S_RNAfe_SingleM_TB::RandomNeighborList::RandomNeighborList(
00357             const S_RNAfe_SingleM_TB* _origin)
00358      :  origin(_origin)
00359     {
00360     }
00361 
00362     S_RNAfe_SingleM_TB::RandomNeighborList::~RandomNeighborList() {
00363     }
00364 
00365     void 
00366     S_RNAfe_SingleM_TB::RandomNeighborList::switchMode(
00367             ItState* itstate) const 
00368     {
00369 
00370         ItState* myitstate = static_cast<ItState*>(itstate);
00371 
00372         SingleMove nextMove = origin->firstValidSingleMove();
00373 
00374         // loop while valid moves exist
00375         while (nextMove != SingleMove(0,biu::RNAStructure_TB::INVALID_INDEX)) {
00376             // add all valid and unchosen moves to unchosenValidMoves
00377             if (myitstate->chosenMoves.find(nextMove) == 
00378                  myitstate->chosenMoves.end()) {
00379                 myitstate->unchosenValidMoves.push_back(nextMove);
00380             }
00381             nextMove = origin->nextValidSingleMove(nextMove);
00382         }
00383     }
00384 
00385     State* 
00386     S_RNAfe_SingleM_TB::RandomNeighborList::first(
00387               State::NeighborList::ItState** itstate) const 
00388     {
00389         if (*itstate != NULL) delete *itstate;
00390 
00391         *itstate = new ItState();
00392         S_RNAfe_SingleM_TB* rnaState = 
00393          new S_RNAfe_SingleM_TB(*origin);
00394 
00395         return next(*itstate, rnaState);
00396     }
00397 
00398     State* 
00399     S_RNAfe_SingleM_TB::RandomNeighborList::next(
00400               State::NeighborList::ItState* itstate, State* elem) const 
00401     {
00402         assertbiu(elem != NULL, "Elem is not allowed to be NULL");
00403         assertbiu(dynamic_cast<S_RNAfe_SingleM_TB*>(elem) != NULL
00404                 , "elem is no instance of S_RNAfe_SingleM_TB");
00405 
00406         ItState* myitstate = static_cast<ItState*>(itstate);
00407         S_RNAfe_SingleM_TB* rnaState = static_cast<S_RNAfe_SingleM_TB*>(elem);
00408 
00409         if (myitstate->switchModeValue > 0) {
00410             // positions the move will be applied to
00411             size_t pos1, pos2;
00412             SingleMove nextMove;
00413             bool foundValidMove = false;
00414 
00415             while (!foundValidMove) {
00416                 pos1 = biu::RNF::getRN() % origin->rnaFreeEnergy.getLength();
00417                 pos2 = biu::RNF::getRN() % origin->rnaFreeEnergy.getLength();
00418                 if (pos1 == pos2) {
00419                     continue;
00420                 }
00421                 nextMove = (pos1 < pos2) ? SingleMove(pos1, pos2) : SingleMove(pos2, pos1);
00422         
00423                 if (origin->rnaFreeEnergy.isValidSingleMove(nextMove)) {
00424                     if (!(myitstate->chosenMoves.insert(nextMove).second)) {
00425                         // move has already been chosen --> try next
00426                         myitstate->switchModeValue--;
00427                         if (myitstate->switchModeValue == 0) {
00428                             switchMode(myitstate);
00429                             break;
00430                         }
00431                     }
00432                         // move hasn't been chosen yet and is valid
00433                         // set rnaState to the state of origin of the neighbors
00434                     rnaState->rnaFreeEnergy = origin->rnaFreeEnergy;
00435                     rnaState->rnaFreeEnergy.applySingleMoveInPlace(
00436                      nextMove);
00437                     foundValidMove = true;
00438                 }   
00439             }
00440         } 
00441         if (myitstate->switchModeValue == 0) {
00442             size_t n = myitstate->unchosenValidMoves.size();
00443             if (n == 0) {
00444                 return NULL;
00445             }
00446             else {
00447                 size_t i = biu::RNF::getRN() % n;
00448                     // set rnaState to the state of origin of the neighbors
00449                 rnaState->rnaFreeEnergy = origin->rnaFreeEnergy;
00450                 rnaState->rnaFreeEnergy.applySingleMoveInPlace(
00451                  myitstate->unchosenValidMoves[i]);
00452                 myitstate->unchosenValidMoves[i] =
00453                  myitstate->unchosenValidMoves[n-1];
00454                 myitstate->unchosenValidMoves.resize(n-1);
00455             }
00456         }
00457         return rnaState;
00458     }
00459     
00460     State*  
00461     S_RNAfe_SingleM_TB::getRandomNeighbor(State* inPlaceNeigh) const 
00462     {
00463         assertbiu(dynamic_cast<S_RNAfe_SingleM_TB*>(inPlaceNeigh) != NULL
00464                     , "inPlaceNeigh is no S_RNAfe_SingleM_TB"); 
00465         S_RNAfe_SingleM_TB* neigh = NULL;
00466             // copy this state
00467         if (inPlaceNeigh != NULL) {
00468             neigh = static_cast<S_RNAfe_SingleM_TB*>(inPlaceNeigh);
00469             (*neigh) = (*this); 
00470         } else {
00471             neigh = new S_RNAfe_SingleM_TB(*this);
00472         }
00473         
00474         size_t pos1, pos2;
00475         SingleMove nextMove;
00476 
00477         while (true) {
00478             pos1 = biu::RNF::getRN() % rnaFreeEnergy.getLength();
00479             pos2 = biu::RNF::getRN() % rnaFreeEnergy.getLength();
00480             if (pos1 == pos2) {
00481                 continue;
00482             }
00483             nextMove = (pos1 < pos2) ? SingleMove(pos1, pos2) : SingleMove(pos2, pos1);
00484             // move has already been chosen
00485             if (rnaFreeEnergy.isValidSingleMove(nextMove)) {
00486                     // set rnaState to the state of origin of the neighbors
00487                 neigh->rnaFreeEnergy.applySingleMoveInPlace( nextMove );
00488                 break;
00489             }   
00490         }
00491         return neigh;
00492     }
00493 
00494     
00495 
00497     
00498         /* Access to a compressed sequence representation of the state.
00499          * @return the compressed sequence representation
00500          */
00501     CSequence  
00502     S_RNAfe_SingleM_TB::compress(void) const {
00503         return rnaFreeEnergy.getStructureAlphabet()->compressS(rnaFreeEnergy.getStructureStringRef());
00504     }
00505     
00506         /* Access to a compressed sequence representation of the state.
00507          * @param toFill a data structure to write the compressed 
00508          *               representation too
00509          * @return the compressed sequence representation
00510          */
00511     CSequence&  
00512     S_RNAfe_SingleM_TB::compress(CSequence& toFill) const {
00513         toFill = rnaFreeEnergy.getStructureAlphabet()->compressS(rnaFreeEnergy.getStructureStringRef());
00514         return toFill;
00515     }
00516     
00517         /* Uncompresses a compressed sequencce representation into a new
00518          * State object.
00519          * @param cseq the compressed sequence representation of a state
00520          * @param toFill a state object to uncompress too or NULL if a new 
00521          *               object has to be created
00522          * @return new State object that is encoded in cseq or NULL in error
00523          *         case.
00524          */
00525     State*  
00526     S_RNAfe_SingleM_TB::uncompress(const CSequence& cseq, State* toFill) const {
00527 
00528         assertbiu(toFill == NULL || dynamic_cast<S_RNAfe_SingleM_TB*>(toFill) != NULL
00529                     , "toFill is no S_RNAfe_SingleM_TB"); 
00530 
00531         biu::Structure str = rnaFreeEnergy.getStructureAlphabet()->decompress(cseq,rnaFreeEnergy.getStructureStringRef().size());
00532           // error case
00533         if (str.size() != rnaFreeEnergy.getStructureStringRef().size())
00534             return NULL;
00535 
00536         S_RNAfe_SingleM_TB* ret = NULL;
00537             // use second function
00538         if (toFill == NULL) {
00539             ret = this->clone();
00540         } else {
00541             ret = static_cast<S_RNAfe_SingleM_TB*>(toFill);
00542             assertbiu(ret!=NULL, "given State toFill is no S_RNAfe_SingleM_TB instance");
00543         }
00544             
00545         ret->rnaFreeEnergy.setStructure(str);
00546         
00547         return ret;
00548     }
00549     
00550         /* Uncompresses a compressed sequencce representation into a this
00551          * State object.
00552          * @param cseq the compressed sequence representation of a state
00553          * @return this or NULL in error case
00554          */
00555     State*  
00556     S_RNAfe_SingleM_TB::uncompress(const CSequence& cseq) {
00557         
00558         biu::Structure str = rnaFreeEnergy.getStructureAlphabet()->decompress(cseq,rnaFreeEnergy.getStructureStringRef().size());
00559         
00560         if (str.size() != rnaFreeEnergy.getStructureStringRef().size())
00561             return NULL;
00562         
00563         rnaFreeEnergy.setStructure(str);
00564         
00565         return this;
00566     }
00567     
00568 
00569 } // namespace ell