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