std::string Interaction:: dotBracket( const Interaction & i, const char symOpen, const char symClose, const bool fullLength ) { #if INTARNA_IN_DEBUG_MODE if (!i.isValid()) throw std::runtime_error("Interaction::dotBracket("+toString(i)+") not valid!"); #endif if (fullLength) { // compile dot-bracket representation for full sequence lengths return std::string(i.basePairs.begin()->first, '.' ) // leading unpaired s1 + dotSomething(i.basePairs.begin(), i.basePairs.end(), true, symOpen) // s1 structure + std::string(i.s1->size() - i.basePairs.rbegin()->first -1, '.' ) // trailing unpaired s1 +"&" + std::string(i.s2->size() - i.basePairs.rbegin()->second -1, '.' ) // leading unpaired s2 + dotSomething(i.basePairs.rbegin(), i.basePairs.rend(), false, symClose) // s2 structure + std::string(i.basePairs.rbegin()->second, '.' ) // trailing unpaired s2 ; } else { // compile dot-bracket representation for interacting subsequences only return dotSomething(i.basePairs.begin(), i.basePairs.end(), true, symOpen) +"&" + dotSomething(i.basePairs.rbegin(), i.basePairs.rend(), false, symClose) ; } }
std::string Interaction:: dotBar( const Interaction & i, const bool fullLength ) { #if INTARNA_IN_DEBUG_MODE if (!i.isValid()) throw std::runtime_error("Interaction::dotBar("+toString(i)+") not valid!"); #endif // check whether to do full length output if (fullLength) { // compile dot-bar representation for full sequences return "1" + std::string(i.basePairs.begin()->first, '.' ) // leading unpaired s1 + dotSomething(i.basePairs.begin(), i.basePairs.end(), true, '|') // s1 structure + std::string(i.s1->size() - i.basePairs.rbegin()->first -1, '.' ) // trailing unpaired s1 + "&" + "1" + std::string(i.basePairs.rbegin()->second, '.' ) // trailing unpaired s2 + dotSomething(i.basePairs.rbegin(), i.basePairs.rend(), false, '|') // s2 structure + std::string( i.s2->size() - i.basePairs.begin()->second -1, '.' ) // leading unpaired s2 ; } else { // compile dot-bar representation for interacting subsequences only return toString(i.basePairs.begin()->first +1) + dotSomething(i.basePairs.begin(), i.basePairs.end(), true, '|') +"&" +toString(i.basePairs.rbegin()->second +1) + dotSomething(i.basePairs.rbegin(), i.basePairs.rend(), false, '|') ; } }
void PredictorMfe2dHeuristic:: traceBack( Interaction & interaction, const OutputConstraint & outConstraint ) { // check if something to trace if (interaction.basePairs.size() < 2) { return; } #if INTARNA_IN_DEBUG_MODE // sanity checks if ( interaction.basePairs.size() != 2 ) { throw std::runtime_error("PredictorMfe2dHeuristic::traceBack() : given interaction does not contain boundaries only"); } #endif // check for single interaction if (interaction.basePairs.at(0).first == interaction.basePairs.at(1).first) { // delete second boundary (identical to first) interaction.basePairs.resize(1); // update done return; } #if INTARNA_IN_DEBUG_MODE // sanity checks if ( ! interaction.isValid() ) { throw std::runtime_error("PredictorMfe2dHeuristic::traceBack() : given interaction not valid : "+toString(interaction)); } #endif // ensure sorting interaction.sort(); // get indices in hybridE for boundary base pairs size_t i1 = energy.getIndex1(interaction.basePairs.at(0)), i2 = energy.getIndex2(interaction.basePairs.at(0)); const size_t j1 = energy.getIndex1(interaction.basePairs.at(1)); const size_t j2 = energy.getIndex2(interaction.basePairs.at(1)); // the currently traced value for i1-j1, i2-j2 E_type curE = hybridE(i1,i2).E; assert( hybridE(i1,i2).j1 == j1 ); assert( hybridE(i1,i2).j2 == j2 ); assert( i1 <= j1 ); assert( i2 <= j2 ); assert( j1 < hybridE.size1() ); assert( j2 < hybridE.size2() ); // trace back // temp variables size_t k1,k2; // check all possible splits of the interval (i1,i2)-(j1,j2) // only reasonable, if there is an enclosed position k1 between i1-j1 while( (j1-i1) > 1 ) { const BestInteraction * curCell = NULL; bool traceNotFound = true; // check all combinations of decompositions into (i1,i2)..(k1,k2)-(j1,j2) for (k1=std::min(j1,i1+energy.getMaxInternalLoopSize1()+1); traceNotFound && k1>i1; k1--) { for (k2=std::min(j2,i2+energy.getMaxInternalLoopSize2()+1); traceNotFound && k2>i2; k2--) { // temp access to current cell curCell = &(hybridE(k1,k2)); // check if right boundary is equal (part of the heuristic) if ( curCell->j1 == j1 && curCell->j2 == j2 && // and energy is the source of curE E_equal( curE, (energy.getE_interLeft(i1,k1,i2,k2) + curCell->E ) ) ) { // stop searching traceNotFound = false; // store splitting base pair if not last one of interaction range if ( k1 < j1 ) { interaction.basePairs.push_back( energy.getBasePair(k1,k2) ); } // trace right part of split i1=k1; i2=k2; curE = curCell->E; } } } assert( !traceNotFound ); } // sort final interaction (to make valid) (faster than calling sort()) if (interaction.basePairs.size() > 2) { Interaction::PairingVec & bps = interaction.basePairs; // shift all added base pairs to the front for (size_t i=2; i<bps.size(); i++) { bps.at(i-1).first = bps.at(i).first; bps.at(i-1).second = bps.at(i).second; } // set last to j1-j2 (*bps.rbegin()) = energy.getBasePair( j1, j2 ); } }