/* for a given ringlist, generate all structures (canonical) with one less base pair (BUT WITHOUT ISOLATED BASE PAIRS) */ static void dnb_nolp(baum *rli) { int EoT = 0; baum *rlj; baum *rlin = NULL; /* pointers to following pair in helix, if any */ baum *rljn = NULL; baum *rlip = NULL; /* pointers to preceding pair in helix, if any */ baum *rljp = NULL; rlj = rli->down; /* immediate interior base pair ? */ if (rlj->next == rlj->prev) { rlin = rlj->next; rljn = rlin->down; } /* immediate exterior base pair and not virtualroot ? */ if (rli->prev == rli->next && rli->next->typ != 'x') { rlip = rli->next->up; rljp = rli->next; } /* double delete ? */ if (rlip==NULL && rlin && rljn->next != rljn->prev ) { /* open the two base pairs ... */ open_bp(rli); open_bp(rlin); /* ... evaluate energy of the structure ... */ EoT = energy_of_struct_pt(GAV.farbe, pairList, typeList, aliasList); /* ... and put the move and the enegy of the structure into the neighbour list ... */ update_nbList(-(1+rli->nummer+GSV.len+1),-(1+rlj->nummer+GSV.len+1), EoT); /* ... and close the two base pairs again */ close_bp(rlin, rljn); close_bp(rli, rlj); } else { /* single delete */ /* the following will work only if boolean expr are shortcicuited */ if (rlip==NULL || (rlip->prev == rlip->next && rlip->prev->typ != 'x')) if (rlin ==NULL || (rljn->next == rljn->prev)) { /* open the base pair ... */ open_bp(rli); /* ... evaluate energy of the structure ... */ EoT = energy_of_struct_pt(GAV.farbe, pairList, typeList, aliasList); /* ... and put the move and the enegy of the structure into the neighbour list ... */ update_nbList(-(1 + rli->nummer),-(1 + rlj->nummer), EoT); /* and close the base pair again */ close_bp(rli, rlj); } } }
/* for a given ringlist, generate all structures (canonical) with one additional base pair (BUT WITHOUT ISOLATED BASE PAIRS) */ static void inb_nolp(baum *root) { int EoT = 0; baum *stop, *rli, *rlj; stop = root->down; /* loop ringlist over all possible i positions */ for (rli=stop->next;rli!=stop;rli=rli->next) { /* potential i-position is already paired */ if (rli->typ=='p') continue; /* loop ringlist over all possible j positions */ for (rlj=rli->next;rlj!=stop;rlj=rlj->next) { /* base pair must enclose at least 3 bases */ if (rlj->nummer - rli->nummer < MYTURN) continue; /* potential j-position is already paired */ if (rlj->typ=='p') continue; /* if i-j can form a base pair ... */ if (ptype[rli->nummer][rlj->nummer]) { /* ... and extends a helix ... */ if (((rli->prev==stop && rlj->next==stop) && stop->typ != 'x') || (rli->next == rlj->prev)) { /* ... close the base bair and ... */ close_bp(rli,rlj); /* ... evaluate energy of the structure */ EoT = energy_of_struct_pt(GAV.farbe, pairList, typeList, aliasList); /* open the base pair again... */ open_bp(rli); /* ... and put the move and the enegy of the structure into the neighbour list */ update_nbList(1 + rli->nummer, 1 + rlj->nummer, EoT); } /* if double insertion is possible ... */ else if ((rlj->nummer - rli->nummer >= MYTURN+2)&& (rli->next->typ != 'p' && rlj->prev->typ != 'p') && (rli->next->next != rlj->prev->prev) && (ptype[rli->next->nummer][rlj->prev->nummer])) { /* close the two base bair and ... */ close_bp(rli->next, rlj->prev); close_bp(rli, rlj); /* ... evaluate energy of the structure */ EoT = energy_of_struct_pt(GAV.farbe, pairList, typeList, aliasList); /* open the two base pair again ... */ open_bp(rli); open_bp(rli->next); /* ... and put the move and the enegy of the structure into the neighbour list */ update_nbList(1+rli->nummer+GSV.len+1, 1+rlj->nummer+GSV.len+1, EoT); } } } } }
/* for a given tree (structure), generate all neighbours according to moveset */ void move_it (void) { int i; GSV.currE = energy_of_struct_pt(GAV.farbe, pairList, typeList, aliasList)/100.; if ( GTV.noLP ) { /* canonical neighbours only */ inb_nolp(wurzl); for (i = 0; i < GSV.len; i++) { if (pairList[i+1]>i+1) { inb_nolp(rl+i); /* insert pair neighbours */ dnb_nolp(rl+i); /* delete pair neighbour */ } } } else { /* all neighbours */ inb(wurzl); for (i = 0; i < GSV.len; i++) { if (pairList[i+1]>i+1) { inb(rl+i); /* insert pair neighbours */ dnb(rl+i); /* delete pair neighbour */ if ( GTV.noShift == 0 ) fnb(rl+i); } } } }
static int try_moves(intermediate_t c, int maxE, intermediate_t *next, int dist) { int *loopidx, len, num_next=0, en, oldE; move_t *mv; short *pt; len = c.pt[0]; loopidx = pair_table_to_loop_index(c.pt); oldE = c.Sen; for (mv=c.moves; mv->i!=0; mv++) { int i,j; if (mv->when>0) continue; i = mv->i; j = mv->j; pt = (short *) space(sizeof(short)*(len+1)); memcpy(pt, c.pt,(len+1)*sizeof(short)); if (j<0) { /*it's a delete move */ pt[-i]=0; pt[-j]=0; } else { /* insert move */ if ((loopidx[i] == loopidx[j]) && /* i and j belong to same loop */ (pt[i] == 0) && (pt[j]==0) /* ... and are unpaired */ ) { pt[i]=j; pt[j]=i; } else { free(pt); continue; /* llegal move, try next; */ } } en = energy_of_struct_pt(seq, pt, S, S1); if (en<maxE) { next[num_next].Sen = (en>oldE)?en:oldE; next[num_next].curr_en = en; next[num_next].pt = pt; mv->when=dist; mv->E = en; next[num_next++].moves = copy_moves(c.moves); mv->when=0; } else free(pt); } free(loopidx); return num_next; }
/* convert structure in bracked-dot-notation to a ringlist-tree */ static void struc2tree(char *struc) { char* struc_copy; int ipos, jpos, balance = 0; baum *rli, *rlj; struc_copy = (char *)calloc(GSV.len+1, sizeof(char)); assert(struc_copy); strcpy(struc_copy,struc); for (ipos = 0; ipos < GSV.len; ipos++) { if (struc_copy[ipos] == ')') { jpos = ipos; struc_copy[ipos] = '.'; balance++; while (struc_copy[--ipos] != '('); struc_copy[ipos] = '.'; balance--; rli = &rl[ipos]; rlj = &rl[jpos]; close_bp(rli, rlj); } } if (balance) { fprintf(stderr, "struc2tree(): start structure is not balanced !\n%s\n%s\n", GAV.farbe, struc); exit(1); } GSV.currE = GSV.startE = (float )energy_of_struct_pt(GAV.farbe, pairList, typeList, aliasList) / 100.0; { int i; for(i = 0; i < GSV.len; i++) { if (pairList[i+1]>i+1) rl[i].loop_energy = loop_energy(pairList, typeList, aliasList,i+1); } wurzl->loop_energy = loop_energy(pairList, typeList, aliasList,0); } free(struc_copy); }
int find_path_once(char *struc1, char *struc2, int maxE, int maxl) { short *pt1, *pt2; move_t *mlist; int i, len, d, dist=0, result; intermediate_t *current, *next; pt1 = make_pair_table(struc1); pt2 = make_pair_table(struc2); len = (int) strlen(struc1); mlist = (move_t *) space(sizeof(move_t)*len); /* bp_dist < n */ for (i=1; i<=len; i++) { if (pt1[i] != pt2[i]) { if (i<pt1[i]) { /* need to delete this pair */ mlist[dist].i = -i; mlist[dist].j = -pt1[i]; mlist[dist++].when = 0; } if (i<pt2[i]) { /* need to insert this pair */ mlist[dist].i = i; mlist[dist].j = pt2[i]; mlist[dist++].when = 0; } } } free(pt2); BP_dist = dist; current = (intermediate_t *) space(sizeof(intermediate_t)*(maxl+1)); current[0].pt = pt1; current[0].Sen = energy_of_struct_pt(seq, pt1, S, S1); current[0].moves = mlist; next = (intermediate_t *) space(sizeof(intermediate_t)*(dist*maxl+1)); for (d=1; d<=dist; d++) { /* go through the distance classes */ int c, u, num_next=0; intermediate_t *cc; for (c=0; current[c].pt != NULL; c++) { num_next += try_moves(current[c], maxE, next+num_next, d); } if (num_next==0) { for (cc=current; cc->pt != NULL; cc++) free_intermediate(cc); current[0].Sen=INT_MAX; break; } /* remove duplicats via sort|uniq if this becomes a bottleneck we can use a hash instead */ qsort(next, num_next, sizeof(intermediate_t),compare_ptable); for (u=0,c=1; c<num_next; c++) { if (memcmp(next[u].pt,next[c].pt,sizeof(short)*len)!=0) { next[++u] = next[c]; } else { free_intermediate(next+c); } } num_next = u+1; qsort(next, num_next, sizeof(intermediate_t),compare_energy); /* free the old stuff */ for (cc=current; cc->pt != NULL; cc++) free_intermediate(cc); for (u=0; u<maxl && u<num_next; u++) { current[u] = next[u]; } for (; u<num_next; u++) free_intermediate(next+u); num_next=0; } free(next); path = current[0].moves; result = current[0].Sen; free(current[0].pt); free(current); return(result); }
/* for a given ringlist, generate all structures with one shifted base pair */ static void fnb(baum *rli) { int EoT = 0, x; baum *rlj, *stop, *help_rli, *help_rlj; stop = rli->down; /* examin interior loop of bp(ij); (.......) i of j move -> <- */ for (rlj = stop->next; rlj != stop; rlj = rlj->next) { /* prevent shifting to paired position */ if ((rlj->typ=='p')||(rlj->typ=='q')) continue; /* j-position of base pair shifts to k position (ij)->(ik) i<k<j */ if ( (rlj->nummer-rli->nummer >= MYTURN) && (ptype[rli->nummer][rlj->nummer]) ) { /* open original basepair */ open_bp(rli); /* close shifted version of original basepair */ close_bp(rli, rlj); /* evaluate energy of the structure */ EoT = energy_of_struct_pt(GAV.farbe, pairList, typeList, aliasList); /* put the move and the enegy of the structure into the neighbour list */ update_nbList(1+rli->nummer, -(1+rlj->nummer), EoT); /* open shifted basepair */ open_bp(rli); /* restore original basepair */ close_bp(rli, stop); } /* i-position of base pair shifts to position k (ij)->(kj) i<k<j */ if ( (stop->nummer-rlj->nummer >= MYTURN) && (ptype[stop->nummer][rlj->nummer]) ) { /* open original basepair */ open_bp(rli); /* close shifted version of original basepair */ close_bp(rlj, stop); /* evaluate energy of the structure */ EoT = energy_of_struct_pt(GAV.farbe, pairList, typeList, aliasList); /* put the move and the enegy of the structure into the neighbour list */ update_nbList(-(1 + rlj->nummer), 1 + stop->nummer, EoT); /* open shifted basepair */ open_bp(rlj); /* restore original basepair */ close_bp(rli, stop); } } /* examin exterior loop of bp(ij); (.......) i or j moves <- -> */ for (rlj=rli->next;rlj!=rli;rlj=rlj->next) { if ((rlj->typ=='p') || (rlj->typ=='q' ) || (rlj->typ=='x')) continue; x=rlj->nummer-rli->nummer; if (x<0) x=-x; /* j-position of base pair shifts to position k */ if ((x >= MYTURN) && (ptype[rli->nummer][rlj->nummer])) { if (rli->nummer<rlj->nummer) { help_rli=rli; help_rlj=rlj; } else { help_rli=rlj; help_rlj=rli; } /* open original basepair */ open_bp(rli); /* close shifted version of original basepair */ close_bp(help_rli,help_rlj); /* evaluate energy of the structure */ EoT = energy_of_struct_pt(GAV.farbe, pairList, typeList, aliasList); /* put the move and the enegy of the structure into the neighbour list */ update_nbList(1 + rli->nummer, -(1 + rlj->nummer), EoT); /* open shifted base pair */ open_bp(help_rli); /* restore original basepair */ close_bp(rli,stop); } x = rlj->nummer-stop->nummer; if (x < 0) x = -x; /* i-position of base pair shifts to position k */ if ((x >= MYTURN) && (ptype[stop->nummer][rlj->nummer])) { if (stop->nummer < rlj->nummer) { help_rli = stop; help_rlj = rlj; } else { help_rli = rlj; help_rlj = stop; } /* open original basepair */ open_bp(rli); /* close shifted version of original basepair */ close_bp(help_rli, help_rlj); /* evaluate energy of the structure */ EoT = energy_of_struct_pt(GAV.farbe, pairList, typeList, aliasList); /* put the move and the enegy of the structure into the neighbour list */ update_nbList(-(1 + rlj->nummer), 1 + stop->nummer, EoT); /* open shifted basepair */ open_bp(help_rli); /* restore original basepair */ close_bp(rli,stop); } } }