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

src/ell/rna/RNAFreeEnergy.cc

Go to the documentation of this file.
00001 #include <biu/assertbiu.hh>
00002 #include "ell/rna/RNAFreeEnergy.hh"
00003 
00004 //#include <ViennaRNA/fold.h>
00005 extern "C" {
00006     #include <ViennaRNA/fold_vars.h>
00007 }
00008 extern "C"  float energy_of_struct(const char *string, const char *structure);
00009 extern "C"  void update_fold_params ();
00010 
00011 
00012 #include <cstring>  //For the string functions
00013 #include <limits.h>
00014 
00015 namespace ell
00016 {
00017 
00018     const biu::Alphabet RNAFreeEnergy::COMMON_ALPHABET("ACGU", 1);
00019     const biu::AllowedBasePairs RNAFreeEnergy::COMMON_BPAIRS(
00020                                 &COMMON_ALPHABET, "AU,CG,GU");
00021     const double RNAFreeEnergy::ENERGY_INF((double)UINT_MAX);
00023 // RNAFreeEnergy
00025 
00026     RNAFreeEnergy::RNAFreeEnergy(const std::string& rnaSeqStr,
00027                                  const std::string& rnaStructBracketDotStr)
00028      :  biu::RNAStructure(rnaSeqStr, rnaStructBracketDotStr, &COMMON_BPAIRS),
00029         energy(ENERGY_INF)
00030     {
00031           // ViennaRNA package parameter for dangling ends
00032         dangles = 2;
00033         update_fold_params();
00034           // inform that molecule was initialised
00035         moleculeChanged();
00036     }
00037     
00038     RNAFreeEnergy::RNAFreeEnergy(biu::Sequence* rnaSeq,
00039                                  const biu::Structure* const rnaStructBracketDot,
00040                                  const bool seqIsShared)
00041      :  biu::RNAStructure(rnaSeq, rnaStructBracketDot, &COMMON_BPAIRS, seqIsShared),
00042         energy(ENERGY_INF)
00043     {
00044           // ViennaRNA package parameter for dangling ends
00045         dangles = 2;
00046         update_fold_params();
00047           // inform that molecule was initialised
00048         moleculeChanged();
00049     }
00050     
00051     RNAFreeEnergy::RNAFreeEnergy(const RNAFreeEnergy& rnaFreeEnerg)
00052      : biu::RNAStructure(rnaFreeEnerg), energy(rnaFreeEnerg.energy)
00053     {
00054     }
00055 
00056     RNAFreeEnergy::~RNAFreeEnergy() {
00057     }
00058 
00059     size_t  
00060     RNAFreeEnergy::nextCompatibleSingleMovePos(const size_t pos) const {
00061         for (   size_t p = pos+1; 
00062                 p < rnaStructBracketDot->size() && (*rnaStructBracketDot)[p] != STRUCT_BND_CLOSE; 
00063                 (p = rnaBonds[p])++) 
00064         {
00065             if ((*rnaStructBracketDot)[p] == STRUCT_UNBOUND) {
00066                 return p;
00067             }
00068         }
00069         return biu::RNAStructure::INVALID_INDEX;
00070     }
00071 
00072     void        
00073     RNAFreeEnergy::applySingleMoveInPlace(const SingleMove& move) {
00074         // open bond between move.first and move.second
00075         if (rnaBonds[move.first] == move.second) {
00076             (*rnaStructBracketDot)[move.first] = STRUCT_UNBOUND;
00077             (*rnaStructBracketDot)[move.second] = STRUCT_UNBOUND;
00078             rnaBonds[move.first] = biu::RNAStructure::INVALID_INDEX;
00079         }
00080         // close bond between pos1 and pos2
00081         else {
00082             assertbiu(isValidSingleMove(move),
00083                 "can't close bond with single move, because it is not valid");
00084             (*rnaStructBracketDot)[move.first] = STRUCT_BND_OPEN;
00085             (*rnaStructBracketDot)[move.second] = STRUCT_BND_CLOSE;
00086             rnaBonds[move.first] = move.second;
00087         }
00088           // inform that structure has changed
00089         moleculeChanged();
00090     }
00091 
00092     void 
00093     RNAFreeEnergy::setStructure(const biu::Structure& str) {
00094         assertbiu(str.size() == rnaSeq->size(),
00095                 "given structure is not of sequence size");
00096           // set structure
00097         RNAStructure::setStructure(str);
00098           // update possible bond settings
00099         initBonds();
00100           // inform that molecule has changed and e.g. energy has to be 
00101           // recalculated
00102         moleculeChanged();
00103     }
00104 
00105     bool        
00106     RNAFreeEnergy::isValidSingleMove(const SingleMove& move)
00107              const {
00108                 
00109         assertbiu(move.first < move.second && move.second < rnaStructBracketDot->size(),
00110                 "first move pos has to be smaller than second");
00111                 
00112         // bond between move.first and move.second
00113         if (rnaBonds[move.first] == move.second) {
00114             return true;
00115         }
00116 
00117         // check if both unpaired and not destroying nestedness
00118         if (    (*rnaStructBracketDot)[move.first] == STRUCT_UNBOUND &&
00119                 (*rnaStructBracketDot)[move.second] == STRUCT_UNBOUND &&
00120                     // distance between move.first and move.second has to be 
00121                     // at least biu::RNAStructure::MIN_LOOP_LENGTH
00122                 (move.second-move.first) > biu::RNAStructure::MIN_LOOP_LENGTH &&
00123                   // check if bases are compatible
00124                 isAllowedBasePair(move.first, move.second) ) 
00125         {
00126             size_t i = move.first; 
00127             while (i < move.second ) {
00128                 if((*rnaStructBracketDot)[i] == STRUCT_BND_CLOSE) {
00129                     return false;
00130                 } else if((*rnaStructBracketDot)[i] == STRUCT_BND_OPEN) {
00131                     i = rnaBonds[i]; 
00132                     i++;
00133                 } else {
00134                     i++; 
00135                 }
00136             }
00137             return i==move.second;
00138         }
00139         
00140         // else no valid structure
00141         return false;
00142     }
00143 
00144     double  
00145     RNAFreeEnergy::getEnergy() const {
00146         if (energy == ENERGY_INF) {
00147               // generate input for Vienna package function
00148 //          char * seqStr = new char[rnaSeq->size()+1];
00149 //          strcpy( seqStr, COMMON_ALPHABET.getString(*rnaSeq).c_str()); 
00150 //          char * structStr = new char[rnaStructBracketDot->size()+1];
00151 //          strcpy( structStr, STRUCT_ALPH.getString(*rnaStructBracketDot).c_str()); 
00152               // calculate energy via Vienna package
00153 //          energy = energy_of_struct( seqStr, structStr );
00154             energy = energy_of_struct( 
00155                         COMMON_ALPHABET.getString(*rnaSeq).c_str()
00156                         , STRUCT_ALPH.getString(*rnaStructBracketDot).c_str() );
00157               // garbage collection
00158 //          delete seqStr;
00159 //          delete structStr;
00160         }
00161         return energy;
00162     }
00163 
00164 
00165     RNAFreeEnergy&  
00166     RNAFreeEnergy::operator= (const RNAFreeEnergy& rnaStruct2) {
00167         
00168         if (this != &rnaStruct2) {
00169               // call assignment operator of super class
00170             biu::RNAStructure::operator=(rnaStruct2);
00171             
00172               // apply assignments for this class
00173             energy = rnaStruct2.energy;
00174         }
00175         return *this;
00176     }
00177 
00178     void
00179     RNAFreeEnergy::moleculeChanged() {
00180           // force recalculation of energy
00181         energy = ENERGY_INF;
00182     }
00183 
00184     
00185 } // namespace ell