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

src/ell/rna/RNAFreeEnergy_TB.cc

Go to the documentation of this file.
00001 #include <biu/assertbiu.hh>
00002 #include "ell/rna/RNAFreeEnergy_TB.hh"
00003 
00004 extern "C" {
00005     #include <ViennaRNA/fold_vars.h> // for dangles parameter
00006     #include <ViennaRNA/pair_mat.h>  // for encode_char function
00007 //  #include <ViennaRNA/fold.h>
00008 //  #include <ViennaRNA/utils.h>
00009 }
00010 extern "C"  float energy_of_struct(const char *string, const char *structure);
00011 extern "C"  void update_fold_params ();
00012 extern "C"  int encode_char(char c);
00013 extern "C"  short* make_pair_table(const char *structure);
00014 extern "C"  int loop_energy(short * ptable, short *s, short *s1, int i);
00015 
00016 void dummyCall() {
00017     make_pair_matrix(); // needed to avoid warning due to <ViennaRNA/pair_mat.h>
00018 }
00019 
00020 #include <cstring>  //For the string functions
00021 #include <limits.h>
00022 
00023 namespace ell
00024 {
00025 
00026     const biu::Alphabet RNAFreeEnergy_TB::COMMON_ALPHABET("ACGU", 1);
00027     const biu::AllowedBasePairs RNAFreeEnergy_TB::COMMON_BPAIRS(
00028                                 &COMMON_ALPHABET, "AU,CG,GU");
00029     const double RNAFreeEnergy_TB::ENERGY_INF((double)UINT_MAX);
00030     
00031     bool RNAFreeEnergy_TB::calculateEnergyChanges = true;
00032     
00033       // whether or not the fold parameters of the Vienna package are 
00034       // already set or not
00035     bool ViennaFoldParamsSet = false;
00036 
00037     
00039 // RNAFreeEnergy_TB
00041 
00042     RNAFreeEnergy_TB::RNAFreeEnergy_TB(const std::string& rnaSeqStr
00043                             , const std::string& rnaStructBracketDotStr
00044                             , const double energy_ )
00045      :  biu::RNAStructure_TB(rnaSeqStr, rnaStructBracketDotStr, &COMMON_BPAIRS)
00046         , energy(ENERGY_INF)
00047         , seqVienna(NULL)
00048         , pairTable(NULL)
00049     {
00050           // ViennaRNA package parameter for dangling ends
00051         setViennaFoldParams();
00052           // inform that molecule was initialised
00053         moleculeChanged();
00054           // set energy if given
00055         if (energy_ != ENERGY_INF) {
00056             setEnergy(energy_);
00057         }
00058     }
00059     
00060     RNAFreeEnergy_TB::RNAFreeEnergy_TB(biu::Sequence* rnaSeq
00061                                 , const biu::Structure* const rnaStructBracketDot
00062                                 , const bool seqIsShared
00063                                 , const double energy_ )
00064      :  biu::RNAStructure_TB(rnaSeq, rnaStructBracketDot, &COMMON_BPAIRS, seqIsShared)
00065         , energy(ENERGY_INF)
00066         , seqVienna(NULL)
00067         , pairTable(NULL)
00068     {
00069           // ViennaRNA package parameter for dangling ends
00070         setViennaFoldParams();
00071           // inform that molecule was initialised
00072         moleculeChanged();
00073           // set energy if given
00074         if (energy_ != ENERGY_INF) {
00075             setEnergy(energy_);
00076         }
00077     }
00078     
00079     RNAFreeEnergy_TB::RNAFreeEnergy_TB(const RNAFreeEnergy_TB& rnaFreeEnerg)
00080      :  biu::RNAStructure_TB(rnaFreeEnerg)
00081         , energy(rnaFreeEnerg.energy)
00082         , seqVienna(NULL)
00083         , pairTable(NULL)
00084     {
00085     }
00086 
00087     RNAFreeEnergy_TB::~RNAFreeEnergy_TB()   
00088     {
00089         if (seqVienna != NULL) delete seqVienna;
00090         if (pairTable != NULL) delete pairTable;
00091     }
00092 
00093     void        
00094     RNAFreeEnergy_TB::applySingleMoveInPlace(const SingleMove& move) {
00095         
00096           // check if energy should be updated
00097         if (calculateEnergyChanges && energy != ENERGY_INF) {
00098             
00099             size_t around = move.first;
00100             while (around > 0) {
00101                 around--;
00102                 if ( validTreeStruc->at(around).pair != INVALID_INDEX ) {
00103                     if ( validTreeStruc->at(around).pair > move.first ) {
00104                         break;
00105                     } else {
00106                           // jump over base pair
00107                         around = validTreeStruc->at(around).pair;
00108                     }
00109                 }
00110             }
00111             const bool nothingAround = move.first == 0 || (around == 0 && validTreeStruc->at(around).pair == INVALID_INDEX);
00112               // create temporary data structure
00113             if (seqVienna == NULL || pairTable == NULL) {
00114                 updateSeqVienna();
00115             }
00116             
00117               // temp vars for energy contributions
00118             double aroundE = 0.0;
00119             double moveE = 0.0;
00120             double stackE = 0.0;
00121             
00122 //std::cerr <<" E before = " <<energy 
00123 //          <<" eosPT = "
00124 //          <<energy_of_struct_pt(COMMON_ALPHABET.getString(*rnaSeq).c_str(),pairTable, seqVienna, seqVienna)
00125 //          <<"  eos = "
00126 //          <<energy_of_struct(COMMON_ALPHABET.getString(*rnaSeq).c_str(),bracketStructStr.c_str());
00127 //std::cerr <<"\n";
00128             // remove bond between move.first and move.second
00129             if (validTreeStruc->at(move.first).pair == move.second) {
00130 if (around == 0)
00131 //std::cerr <<"\n###  DELETION\n";
00132                 stackE = loop_energy(pairTable, seqVienna, seqVienna, (nothingAround?0:around+1)); // around
00133                 
00134 
00135                 
00136 
00137                 moveE = loop_energy(pairTable, seqVienna, seqVienna, (move.first+1));  // move
00138                 deleteBond( move.first, move.second );
00139                   // update pair table if necessary
00140                 pairTable[move.first+1] = 0;
00141                 pairTable[move.second+1] = 0;
00142                 aroundE = loop_energy(pairTable, seqVienna, seqVienna, (nothingAround?0:around+1)); // around
00143                   // calculate new energy
00144                 energy += double(aroundE - stackE - moveE) / 100.0;
00145             } 
00146             // add bond
00147             else {
00148 //std::cerr <<"\n###  INSERTION\n";
00149                 assertbiu(isValidInsertMove( move.first, move.second ),
00150                     "can't close bond with single move, because it is not valid");
00151                 aroundE = loop_energy(pairTable, seqVienna, seqVienna, (nothingAround?0:around+1)); // around
00152                 insertBond( move.first, move.second );
00153                   // update pair table if necessary
00154                 pairTable[move.first+1] = (short)move.second+1;
00155                 pairTable[move.second+1] = (short)move.first+1;
00156                 moveE = loop_energy(pairTable, seqVienna, seqVienna, (move.first+1)); // move
00157                 stackE = loop_energy(pairTable, seqVienna, seqVienna, (nothingAround?0:around+1)); // around
00158                   // calculate new energy
00159                 energy += double(moveE + stackE - aroundE) / 100.0;
00160             }
00161 //std::cerr <<" E after = " <<energy 
00162 //          <<" eosPT = "
00163 //          <<energy_of_struct_pt(COMMON_ALPHABET.getString(*rnaSeq).c_str(),pairTable, seqVienna, seqVienna)
00164 //          <<"  eos = "
00165 //          <<energy_of_struct(COMMON_ALPHABET.getString(*rnaSeq).c_str(),bracketStructStr.c_str());
00166 
00167             assertbiu( energy_of_struct( 
00168                             COMMON_ALPHABET.getString(*rnaSeq).c_str()
00169                             , bracketStructStr.c_str() ) - energy < 0.0001
00170                 , "updated energy differs from direct calculation with Vienna RNA package");
00171 
00172         }
00173           // energy should be recalculated
00174         else {
00175             // remove bond between move.first and move.second
00176             if (validTreeStruc->at(move.first).pair == move.second) {
00177                 deleteBond( move.first, move.second );
00178                   // update pair table if necessary
00179                 if (pairTable != NULL) {
00180                     pairTable[move.first+1] = 0;
00181                     pairTable[move.second+1] = 0;
00182                 }
00183             } 
00184             // add bond
00185             else {
00186                 assertbiu(isValidInsertMove( move.first, move.second ),
00187                     "can't close bond with single move, because it is not valid");
00188                 insertBond( move.first, move.second );
00189                   // update pair table if necessary
00190                 if (pairTable != NULL) {
00191                     pairTable[move.first+1] = (short)move.second+1;
00192                     pairTable[move.second+1] = (short)move.first+1;
00193                 }
00194             }
00195             
00196               // inform that structure has changed
00197             moleculeChanged();
00198         }
00199     }
00200 
00201     RNAFreeEnergy_TB&   
00202     RNAFreeEnergy_TB::operator= (const RNAFreeEnergy_TB& rnaStruct2) {
00203         
00204         if (this != &rnaStruct2) {
00205               // call assignment operator of super class
00206             biu::RNAStructure_TB::operator=(rnaStruct2);
00207             
00208               // apply assignments for this class
00209             energy = rnaStruct2.energy;
00210             if (seqVienna != NULL) delete seqVienna;
00211             seqVienna = NULL;
00212             if (pairTable != NULL) delete pairTable;
00213             pairTable = NULL;
00214         }
00215         return *this;
00216     }
00217     
00218     void 
00219     RNAFreeEnergy_TB
00220 	::updateSeqVienna() 
00221     {
00222         const size_t length = bracketStructStr.size();
00223         if (seqVienna == NULL) {
00224             seqVienna = new short[length+2];
00225 //          S1= (short *) space(sizeof(short)*(l+2));
00226             /* S1 exists only for the special X K and I bases and energy_set!=0 */
00227             seqVienna[0] = (short) length;
00228 
00229             const std::string seq(COMMON_ALPHABET.getString(*rnaSeq));
00230             for (size_t i=1; i<=length; i++) { /* make numerical encoding of sequence */
00231                 seqVienna[i] = (short) encode_char(seq.at(i-1));
00232 //              S1[i] = alias[seqVienna[i]];   /* for mismatches of nostandard bases */
00233             }
00234             /* for circular folding add first base at position n+1 and last base at
00235             position 0 in S1    */
00236             seqVienna[length+1] = seqVienna[1]; 
00237 //          S1[l+1]=S1[1]; S1[0] = S1[l];
00238             
00239 
00240         }
00241         if (pairTable == NULL) {
00242               // create pair_table
00243 //          pairTable = new short[length+2];
00244 //          pairTable[0] = (short)length;
00245 //          for (size_t i=1; i<=length; i++) {
00246 //              if (validTreeStruc->at(i-1).pair != INVALID_INDEX) {
00247 //                  pairTable[i] = (short)validTreeStruc->at(i-1).pair +1;
00248 //              } else {
00249 //                  pairTable[i] = 0;
00250 //              }
00251 //          }
00252             pairTable = make_pair_table(bracketStructStr.c_str());
00253         }
00254 
00255 //std::cerr <<"\n#### cur seqVienna: l = " <<seqVienna[0] <<"\n";
00256 //for (short i=0; i < seqVienna[0]; i++) {
00257 //  std::cerr <<seqVienna[i] <<" ";
00258 //}
00259 //std::cerr <<"\n#### cur pairTable: l = " <<pairTable[0] <<"\n";
00260 //for (short i=0; i < pairTable[0]; i++) {
00261 //  std::cerr <<pairTable[i] <<" ";
00262 //}
00263 //std::cerr <<"\n";
00264 
00265     }
00266 
00267     
00270     void 
00271     RNAFreeEnergy_TB
00272 	::setViennaFoldParams(void) {
00273           // set dangling end handling
00274         dangles = 2;
00275           // force the update in the vienna lib
00276         update_fold_params();
00277     }
00278 
00279     
00280 } // namespace ell