PUBLIC int move_standard(char *seq, char *struc, enum MOVE_TYPE type, int verbosity_level, int shifts, int noLP){ make_pair_matrix(); short int *s0 = encode_sequence(seq, 0); short int *s1 = encode_sequence(seq, 1); short int *str = vrna_ptable(struc); int energy = 0; switch (type){ case GRADIENT: energy = move_gradient(seq, str, s0, s1, verbosity_level, shifts, noLP); break; case FIRST: energy = move_first(seq, str, s0, s1, verbosity_level, shifts, noLP); break; case ADAPTIVE: energy = move_adaptive(seq, str, s0, s1, verbosity_level); break; } int i=1; for (; i<=str[0]; i++) { if (str[i]==0) struc[i-1]='.'; else if (str[i]>str[str[i]]) struc[i-1]='('; else struc[i-1]=')'; } free(s0); free(s1); free(str); return energy; }
int main(int argc, char *argv[]){ char sequence[MAXSIZE], structure[MAXSIZE]; int i, j; if (argc == 9) { i = 1; while (i < argc) { if (!strcmp(argv[i], "-s")) { sequence[0] = '@'; strncpy(sequence + 1, argv[i + 1], strlen(argv[i + 1])); // The sequence starts from index 1 sequence[strlen(argv[i + 1]) + 1] = '\0'; // Remember to end the sequence i += 2; } else if (!strcmp(argv[i], "-r")) { strncpy(structure, argv[i + 1], strlen(argv[i + 1])); // The structure starts from index 0 structure[strlen(argv[i + 1])] = '\0'; // Remember to end the structure i += 2; } else if (!strcmp(argv[i], "-c")) { SCALING_FACTOR = atof(argv[i + 1]); i += 2; } else if (!strcmp(argv[i], "-p")) { PRECISION = atoi(argv[i + 1]); i += 2; } else { printf("Error: Unrecognizable Flag!\n"); printf("Usage:"); printf("%s -s SEQUENCE -r STRUCTURE -c SCALING -p PRECISION\n", argv[0]); printf("SEQUENCE is the RNA sequence.\n"); printf("STRUCTURE is the RNA structure.\n"); printf("SCALING is used internally as the scaling factor for the recursions.\n"); printf("PRECISION dictates the number of signigicant digits in the resulting distribution.\n"); printf("The length of RNA sequence should be less than %d and larger than or equal to 5.\n", MAXSIZE); exit(1); } } CheckSequenceAndStructure(sequence, structure); S0 = encode_seq(sequence + 1); seqlen = strlen(sequence) - 1; Initialize_Params(); make_pair_matrix(); // Needed for pair matching. kT = (temperature + K0) * GASCONST / 1000.0; ML_base = (double)P -> MLbase / 100; ML_close = (double)P -> MLclosing / 100; std::complex<double>** McCaskillZ; McCaskillZ = runMcCaskill(sequence, structure); } else { printf("Usage:"); printf("%s -s SEQUENCE -r STRUCTURE -c SCALING -p PRECISION\n", argv[0]); printf("SEQUENCE is the RNA sequence.\n"); printf("STRUCTURE is the RNA structure.\n"); printf("SCALING is used internally as the scaling factor for the recursions.\n"); printf("PRECISION dictates the number of signigicant digits in the resulting distribution.\n"); printf("The length of RNA sequence should be less than %d and larger than or equal to 5.\n", MAXSIZE); exit(1); } return 0; }
PRIVATE void update_dfold_params(void){ vrna_md_t md; if(P) free(P); set_model_details(&md); P = vrna_params(&md); make_pair_matrix(); }
PUBLIC void init_maxmat(int length, int minls, int minss) { if ( minls > -1 ) minimum_loopsize = minls; if ( minss > -1 ) minimum_stacksize = minss; make_pair_matrix(); get_mm_arrays(length); }
/* unsafe function that will be replaced by a threadsafe companion in the future */ PRIVATE void init_alifold(int length){ unsigned int n; if (length<1) nrerror("initialize_fold: argument must be greater 0"); if (init_length>0) free_alifold_arrays(); get_arrays((unsigned) length); make_pair_matrix(); init_length=length; for (n = 1; n <= (unsigned) length; n++) indx[n] = (n*(n-1)) >> 1; /* n(n-1)/2 */ update_fold_params(); }
PUBLIC int find_saddle(const char *sequence, const char *struc1, const char *struc2, int max) { int maxl, maxE, i; const char *tmp; move_t *bestpath=NULL; int dir; path_fwd = 0; maxE = INT_MAX - 1; seq = sequence; update_fold_params(); make_pair_matrix(); /* nummerically encode sequence */ S = encode_sequence(seq, 0); S1 = encode_sequence(seq, 1); maxl=1; do { int saddleE; path_fwd = !path_fwd; if (maxl>max) maxl=max; if(path) free(path); saddleE = find_path_once(struc1, struc2, maxE, maxl); if (saddleE<maxE) { maxE = saddleE; if (bestpath) free(bestpath); bestpath = path; path = NULL; dir = path_fwd; } else{ free(path);path=NULL; } tmp=struc1; struc1=struc2; struc2=tmp; maxl *=2; } while (maxl<2*max); free(S); free(S1); /* (re)set some globals */ path=bestpath; path_fwd = dir; return maxE; }
int find_saddle(char *sequence, char *struc1, char *struc2, int max) { int maxl, maxE, i; char *tmp; move_t *bestpath=NULL; int dir; maxE = INT_MAX - 1; seq = sequence; update_fold_params(); make_pair_matrix(); /* nummerically encode sequence */ S = (short *) space(sizeof(short)*(strlen(seq)+1)); S1 = (short *) space(sizeof(short)*(strlen(seq)+1)); S[0] = S1[0] = (short) strlen(seq); for (i=0; i< strlen(seq); i++) { S[i+1] = encode_char(seq[i]); S1[i+1] = alias[S[i+1]]; } maxl=1; do { int saddleE; path_fwd = !path_fwd; if (maxl>max) maxl=max; saddleE = find_path_once(struc1, struc2, maxE, maxl); if (saddleE<maxE) { maxE = saddleE; if (bestpath) free(bestpath); bestpath = path; dir = path_fwd; } else free(path); tmp=struc1; struc1=struc2; struc2=tmp; maxl *=2; } while (maxl<2*max); free(S); free(S1); path=bestpath; path_fwd = dir; return maxE; }
PRIVATE void make_pairset(void) { int i,j; int sym[MAXALPHA]; make_pair_matrix(); base = strlen(symbolset); for (i=0; i< base; i++) sym[i] = encode_char(symbolset[i]); for (i=npairs=0; i< base; i++) for (j=0; j<base; j++) if (pair[sym[i]][sym[j]]) { pairset[npairs++] = symbolset[i]; pairset[npairs++] = symbolset[j]; } npairs /= 2; if (npairs==0) nrerror("No pairs in this alphabet!"); }
PRIVATE char *annote(const char *structure, const char *AS[]) { char *ps; int i, n, s, maxl; short *ptable; make_pair_matrix(); n = strlen(AS[0]); maxl = 1024; ps = (char *) space(maxl); ptable = make_pair_table(structure); for (i=1; i<=n; i++) { char pps[64], ci='\0', cj='\0'; int j, type, pfreq[8] = {0,0,0,0,0,0,0,0}, vi=0, vj=0; if ((j=ptable[i])<i) continue; for (s=0; AS[s]!=NULL; s++) { type = pair[encode_char(AS[s][i-1])][encode_char(AS[s][j-1])]; pfreq[type]++; if (type) { if (AS[s][i-1] != ci) { ci = AS[s][i-1]; vi++;} if (AS[s][j-1] != cj) { cj = AS[s][j-1]; vj++;} } } if (maxl - strlen(ps) < 128) { maxl *= 2; ps = realloc(ps, maxl); if (ps==NULL) nrerror("out of memory in realloc"); } if (pfreq[0]>0) { snprintf(pps, 64, "%d %d %d gmark\n", i, j, pfreq[0]); strcat(ps, pps); } if (vi>1) { snprintf(pps, 64, "%d cmark\n", i); strcat(ps, pps); } if (vj>1) { snprintf(pps, 64, "%d cmark\n", j); strcat(ps, pps); } } free(ptable); return ps; }
// create encoded structure encoded *encode_seq(const char* seq) { encoded *res; res = (encoded*) space(sizeof(encoded)); // inicialize encode_sequence make_pair_matrix(); res->seq = seq; res->pt = NULL; res->s0 = encode_sequence(seq, 0); res->s1 = encode_sequence(seq, 1); res->bp_left = 0; res->bp_right = 0; res->bp_left2 = 0; res->bp_right2 = 0; return res; }
PUBLIC int browse_neighs(char *seq, char *struc, int verbosity_level, int shifts, int noLP, int (*funct) (struct_en*, struct_en*)){ make_pair_matrix(); short int *s0 = encode_sequence(seq, 0); short int *s1 = encode_sequence(seq, 1); short int *str = vrna_ptable(struc); int res = browse_neighs_pt(seq, str, s0, s1, verbosity_level, shifts, noLP, funct); free(s0); free(s1); free(str); return res; }
PUBLIC void update_mm_params(void) { make_pair_matrix(); }
/*--------------------------------------------------------------------------*/ int main(int argc, char *argv[]){ struct RNAalifold_args_info args_info; unsigned int input_type; char ffname[FILENAME_MAX_LENGTH], gfname[FILENAME_MAX_LENGTH], fname[FILENAME_MAX_LENGTH]; char *input_string, *string, *structure, *cstruc, *ParamFile, *ns_bases, *c; int n_seq, i, length, sym, r, noPS, with_sci; int endgaps, mis, circular, doAlnPS, doColor, doMEA, n_back, eval_energy, pf, istty; double min_en, real_en, sfact, MEAgamma, bppmThreshold, betaScale; char *AS[MAX_NUM_NAMES]; /* aligned sequences */ char *names[MAX_NUM_NAMES]; /* sequence names */ FILE *clust_file = stdin; pf_paramT *pf_parameters; model_detailsT md; fname[0] = ffname[0] = gfname[0] = '\0'; string = structure = cstruc = ParamFile = ns_bases = NULL; pf_parameters = NULL; endgaps = mis = pf = circular = doAlnPS = doColor = n_back = eval_energy = oldAliEn = doMEA = ribo = noPS = 0; do_backtrack = 1; dangles = 2; gquad = 0; sfact = 1.07; bppmThreshold = 1e-6; MEAgamma = 1.0; betaScale = 1.; with_sci = 0; set_model_details(&md); /* ############################################# # check the command line prameters ############################################# */ if(RNAalifold_cmdline_parser (argc, argv, &args_info) != 0) exit(1); /* temperature */ if(args_info.temp_given) temperature = args_info.temp_arg; /* structure constraint */ if(args_info.constraint_given) fold_constrained=1; /* do not take special tetra loop energies into account */ if(args_info.noTetra_given) md.special_hp = tetra_loop=0; /* set dangle model */ if(args_info.dangles_given){ if((args_info.dangles_arg != 0) && (args_info.dangles_arg != 2)) warn_user("required dangle model not implemented, falling back to default dangles=2"); else md.dangles = dangles=args_info.dangles_arg; } /* do not allow weak pairs */ if(args_info.noLP_given) md.noLP = noLonelyPairs = 1; /* do not allow wobble pairs (GU) */ if(args_info.noGU_given) md.noGU = noGU = 1; /* do not allow weak closing pairs (AU,GU) */ if(args_info.noClosingGU_given) md.noGUclosure = no_closingGU = 1; /* gquadruplex support */ if(args_info.gquad_given) md.gquad = gquad = 1; /* sci computation */ if(args_info.sci_given) with_sci = 1; /* do not convert DNA nucleotide "T" to appropriate RNA "U" */ /* set energy model */ if(args_info.energyModel_given) energy_set = args_info.energyModel_arg; /* take another energy parameter set */ if(args_info.paramFile_given) ParamFile = strdup(args_info.paramFile_arg); /* Allow other pairs in addition to the usual AU,GC,and GU pairs */ if(args_info.nsp_given) ns_bases = strdup(args_info.nsp_arg); /* set pf scaling factor */ if(args_info.pfScale_given) sfact = args_info.pfScale_arg; /* assume RNA sequence to be circular */ if(args_info.circ_given) circular=1; /* do not produce postscript output */ if(args_info.noPS_given) noPS = 1; /* partition function settings */ if(args_info.partfunc_given){ pf = 1; if(args_info.partfunc_arg != -1) do_backtrack = args_info.partfunc_arg; } /* MEA (maximum expected accuracy) settings */ if(args_info.MEA_given){ pf = doMEA = 1; if(args_info.MEA_arg != -1) MEAgamma = args_info.MEA_arg; } if(args_info.betaScale_given) betaScale = args_info.betaScale_arg; /* set the bppm threshold for the dotplot */ if(args_info.bppmThreshold_given) bppmThreshold = MIN2(1., MAX2(0.,args_info.bppmThreshold_arg)); /* set cfactor */ if(args_info.cfactor_given) cv_fact = args_info.cfactor_arg; /* set nfactor */ if(args_info.nfactor_given) nc_fact = args_info.nfactor_arg; if(args_info.endgaps_given) endgaps = 1; if(args_info.mis_given) mis = 1; if(args_info.color_given) doColor=1; if(args_info.aln_given) doAlnPS=1; if(args_info.old_given) oldAliEn = 1; if(args_info.stochBT_given){ n_back = args_info.stochBT_arg; do_backtrack = 0; pf = 1; init_rand(); } if(args_info.stochBT_en_given){ n_back = args_info.stochBT_en_arg; do_backtrack = 0; pf = 1; eval_energy = 1; init_rand(); } if(args_info.ribosum_file_given){ RibosumFile = strdup(args_info.ribosum_file_arg); ribo = 1; } if(args_info.ribosum_scoring_given){ RibosumFile = NULL; ribo = 1; } if(args_info.layout_type_given) rna_plot_type = args_info.layout_type_arg; /* alignment file name given as unnamed option? */ if(args_info.inputs_num == 1){ clust_file = fopen(args_info.inputs[0], "r"); if (clust_file == NULL) { fprintf(stderr, "can't open %s\n", args_info.inputs[0]); } } /* free allocated memory of command line data structure */ RNAalifold_cmdline_parser_free (&args_info); /* ############################################# # begin initializing ############################################# */ if(circular && gquad){ nrerror("G-Quadruplex support is currently not available for circular RNA structures"); } make_pair_matrix(); if (circular && noLonelyPairs) warn_user("depending on the origin of the circular sequence, " "some structures may be missed when using --noLP\n" "Try rotating your sequence a few times\n"); if (ParamFile != NULL) read_parameter_file(ParamFile); if (ns_bases != NULL) { nonstandards = space(33); c=ns_bases; i=sym=0; if (*c=='-') { sym=1; c++; } while (*c!='\0') { if (*c!=',') { nonstandards[i++]=*c++; nonstandards[i++]=*c; if ((sym)&&(*c!=*(c-1))) { nonstandards[i++]=*c; nonstandards[i++]=*(c-1); } } c++; } } istty = isatty(fileno(stdout))&&isatty(fileno(stdin)); /* ######################################################## # handle user input from 'stdin' if necessary ######################################################## */ if(fold_constrained){ if(istty){ print_tty_constraint_full(); print_tty_input_seq_str(""); } input_type = get_input_line(&input_string, VRNA_INPUT_NOSKIP_COMMENTS); if(input_type & VRNA_INPUT_QUIT){ return 0;} else if((input_type & VRNA_INPUT_MISC) && (strlen(input_string) > 0)){ cstruc = strdup(input_string); free(input_string); } else warn_user("constraints missing"); } if (istty && (clust_file == stdin)) print_tty_input_seq_str("Input aligned sequences in clustalw or stockholm format\n(enter a line starting with \"//\" to indicate the end of your input)"); n_seq = read_clustal(clust_file, AS, names); if (n_seq==0) nrerror("no sequences found"); if (clust_file != stdin) fclose(clust_file); /* ######################################################## # done with 'stdin' handling, now init everything properly ######################################################## */ length = (int) strlen(AS[0]); structure = (char *)space((unsigned) length+1); if(fold_constrained && cstruc != NULL) strncpy(structure, cstruc, length); if (endgaps) for (i=0; i<n_seq; i++) mark_endgaps(AS[i], '~'); /* ######################################################## # begin actual calculations ######################################################## */ if (circular) { int i; double s = 0; min_en = circalifold((const char **)AS, structure); for (i=0; AS[i]!=NULL; i++) s += energy_of_circ_structure(AS[i], structure, -1); real_en = s/i; } else { float *ens = (float *)space(2*sizeof(float)); min_en = alifold((const char **)AS, structure); if(md.gquad) energy_of_ali_gquad_structure((const char **)AS, structure, n_seq, ens); else energy_of_alistruct((const char **)AS, structure, n_seq, ens); real_en = ens[0]; free(ens); } string = (mis) ? consens_mis((const char **) AS) : consensus((const char **) AS); printf("%s\n%s", string, structure); if(istty){ if(with_sci){ float sci = min_en; float e_mean = 0; for (i=0; AS[i]!=NULL; i++){ char *seq = get_ungapped_sequence(AS[i]); char *str = (char *)space(sizeof(char) * (strlen(seq) + 1)); e_mean += fold(seq, str); free(seq); free(str); } e_mean /= i; sci /= e_mean; printf( "\n minimum free energy = %6.2f kcal/mol (%6.2f + %6.2f)" "\n SCI = %2.4f\n", min_en, real_en, min_en-real_en, sci); } else printf("\n minimum free energy = %6.2f kcal/mol (%6.2f + %6.2f)\n", min_en, real_en, min_en - real_en); } else { if(with_sci){ float sci = min_en; float e_mean = 0; for (i=0; AS[i]!=NULL; i++){ char *seq = get_ungapped_sequence(AS[i]); char *str = (char *)space(sizeof(char) * (strlen(seq) + 1)); e_mean += fold(seq, str); free(seq); free(str); } e_mean /= i; sci /= e_mean; printf(" (%6.2f = %6.2f + %6.2f) [%2.4f]\n", min_en, real_en, min_en-real_en, sci); } else printf(" (%6.2f = %6.2f + %6.2f) \n", min_en, real_en, min_en-real_en ); } strcpy(ffname, "alirna.ps"); strcpy(gfname, "alirna.g"); if (!noPS) { char **A; A = annote(structure, (const char**) AS); if(md.gquad){ if (doColor) (void) PS_rna_plot_a_gquad(string, structure, ffname, A[0], A[1]); else (void) PS_rna_plot_a_gquad(string, structure, ffname, NULL, A[1]); } else { if (doColor) (void) PS_rna_plot_a(string, structure, ffname, A[0], A[1]); else (void) PS_rna_plot_a(string, structure, ffname, NULL, A[1]); } free(A[0]); free(A[1]); free(A); } if (doAlnPS) PS_color_aln(structure, "aln.ps", (const char const **) AS, (const char const **) names); /* free mfe arrays */ free_alifold_arrays(); if (pf) { float energy, kT; char * mfe_struc; mfe_struc = strdup(structure); kT = (betaScale*((temperature+K0)*GASCONST))/1000.; /* in Kcal */ pf_scale = exp(-(sfact*min_en)/kT/length); if (length>2000) fprintf(stderr, "scaling factor %f\n", pf_scale); fflush(stdout); if (cstruc!=NULL) strncpy(structure, cstruc, length+1); pf_parameters = get_boltzmann_factors_ali(n_seq, temperature, betaScale, md, pf_scale); energy = alipf_fold_par((const char **)AS, structure, NULL, pf_parameters, do_backtrack, fold_constrained, circular); if (n_back>0) { /*stochastic sampling*/ for (i=0; i<n_back; i++) { char *s; double prob=1.; s = alipbacktrack(&prob); printf("%s ", s); if (eval_energy ) printf("%6g %.2f ",prob, -1*(kT*log(prob)-energy)); printf("\n"); free(s); } } if (do_backtrack) { printf("%s", structure); if (!istty) printf(" [%6.2f]\n", energy); else printf("\n"); } if ((istty)||(!do_backtrack)) printf(" free energy of ensemble = %6.2f kcal/mol\n", energy); printf(" frequency of mfe structure in ensemble %g\n", exp((energy-min_en)/kT)); if (do_backtrack) { FILE *aliout; cpair *cp; char *cent; double dist; FLT_OR_DBL *probs = export_ali_bppm(); plist *pl, *mfel; assign_plist_from_pr(&pl, probs, length, bppmThreshold); assign_plist_from_db(&mfel, mfe_struc, 0.95*0.95); if (!circular){ float *ens; cent = get_centroid_struct_pr(length, &dist, probs); ens=(float *)space(2*sizeof(float)); energy_of_alistruct((const char **)AS, cent, n_seq, ens); /*cent_en = energy_of_struct(string, cent);*/ /*ali*/ printf("%s %6.2f {%6.2f + %6.2f}\n",cent,ens[0]-ens[1],ens[0],(-1)*ens[1]); free(cent); free(ens); } if(doMEA){ float mea, *ens; plist *pl2; assign_plist_from_pr(&pl2, probs, length, 1e-4/(1+MEAgamma)); mea = MEA(pl2, structure, MEAgamma); ens = (float *)space(2*sizeof(float)); if(circular) energy_of_alistruct((const char **)AS, structure, n_seq, ens); else ens[0] = energy_of_structure(string, structure, 0); printf("%s {%6.2f MEA=%.2f}\n", structure, ens[0], mea); free(ens); free(pl2); } if (fname[0]!='\0') { strcpy(ffname, fname); strcat(ffname, "_ali.out"); } else strcpy(ffname, "alifold.out"); aliout = fopen(ffname, "w"); if (!aliout) { fprintf(stderr, "can't open %s skipping output\n", ffname); } else { print_aliout(AS, pl, bppmThreshold, n_seq, mfe_struc, aliout); } fclose(aliout); if (fname[0]!='\0') { strcpy(ffname, fname); strcat(ffname, "_dp.ps"); } else strcpy(ffname, "alidot.ps"); cp = make_color_pinfo(AS,pl, bppmThreshold, n_seq, mfel); (void) PS_color_dot_plot(string, cp, ffname); free(cp); free(pl); free(mfel); } free(mfe_struc); free_alipf_arrays(); free(pf_parameters); } if (cstruc!=NULL) free(cstruc); (void) fflush(stdout); free(string); free(structure); for (i=0; AS[i]; i++) { free(AS[i]); free(names[i]); } return 0; }
PUBLIC void update_alifold_params(void){ if(P) free(P); P = scale_parameters(); make_pair_matrix(); if (init_length < 0) init_length=0; }
static void ini_ringlist(void) { int i; /* needed by function energy_of_struct_pt() from Vienna-RNA-1.4 */ pairList = (short *)calloc(GSV.len + 2, sizeof(short)); assert(pairList != NULL); typeList = (short *)calloc(GSV.len + 2, sizeof(short)); assert(typeList != NULL); aliasList = (short *)calloc(GSV.len + 2, sizeof(short)); assert(aliasList != NULL); pairList[0] = typeList[0] = aliasList[0] = GSV.len; ptype = (char **)calloc(GSV.len + 2, sizeof(char *)); assert(ptype != NULL); for (i=0; i<=GSV.len; i++) { ptype[i] = (char*)calloc(GSV.len + 2, sizeof(char)); assert(ptype[i] != NULL); } /* allocate virtual root */ wurzl = (baum *)calloc(1, sizeof(baum)); assert(wurzl != NULL); /* allocate ringList */ rl = (baum *)calloc(GSV.len+1, sizeof(baum)); assert(rl != NULL); /* allocate PostOrderList */ /* initialize virtualroot */ wurzl->typ = 'r'; wurzl->nummer = -1; /* connect virtualroot to ringlist-tree in down direction */ wurzl->down = &rl[GSV.len]; /* initialize post-order list */ make_pair_matrix(); /* initialize rest of ringlist-tree */ for(i = 0; i < GSV.len; i++) { int c; GAV.currform[i] = '.'; GAV.prevform[i] = 'x'; pairList[i+1] = 0; rl[i].typ = 'u'; /* decode base to numeric value */ c = encode_char(GAV.farbe[i]); rl[i].base = typeList[i+1] = c; aliasList[i+1] = alias[typeList[i+1]]; /* astablish links for node of the ringlist-tree */ rl[i].nummer = i; rl[i].next = &rl[i+1]; rl[i].prev = ((i == 0) ? &rl[GSV.len] : &rl[i-1]); rl[i].up = rl[i].down = NULL; } GAV.currform[GSV.len] = GAV.prevform[GSV.len] = '\0'; make_ptypes(aliasList); rl[i].nummer = i; rl[i].base = 0; /* make ringlist circular in next, prev direction */ rl[i].next = &rl[0]; rl[i].prev = &rl[i-1]; /* make virtual basepair for virtualroot */ rl[i].up = wurzl; rl[i].typ = 'x'; }
duplexT duplexfold(const char *s1, const char *s2) { int i, j, l1, Emin=INF, i_min=0, j_min=0; char *struc; duplexT mfe; n1 = (int) strlen(s1); n2 = (int) strlen(s2); if ((!P) || (fabs(P->temperature - temperature)>1e-6)) { update_fold_params(); P = scale_parameters(); make_pair_matrix(); } c = (int **) space(sizeof(int *) * (n1+1)); for (i=1; i<=n1; i++) c[i] = (int *) space(sizeof(int) * (n2+1)); encode_seq(s1, s2); for (i=1; i<=n1; i++) { for (j=n2; j>0; j--) { int type, type2, E, k,l; type = pair[S1[i]][S2[j]]; c[i][j] = type ? P->DuplexInit : INF; if (!type) continue; if (i>1) c[i][j] += P->dangle5[type][SS1[i-1]]; if (j<n2) c[i][j] += P->dangle3[type][SS2[j+1]]; if (type>2) c[i][j] += P->TerminalAU; for (k=i-1; k>0 && k>i-MAXLOOP-2; k--) { for (l=j+1; l<=n2; l++) { if (i-k+l-j-2>MAXLOOP) break; type2 = pair[S1[k]][S2[l]]; if (!type2) continue; E = LoopEnergy(i-k-1, l-j-1, type2, rtype[type], SS1[k+1], SS2[l-1], SS1[i-1], SS2[j+1]); c[i][j] = MIN2(c[i][j], c[k][l]+E); } } E = c[i][j]; if (i<n1) E += P->dangle3[rtype[type]][SS1[i+1]]; if (j>1) E += P->dangle5[rtype[type]][SS2[j-1]]; if (type>2) E += P->TerminalAU; if (E<Emin) { Emin=E; i_min=i; j_min=j; } } } struc = backtrack(i_min, j_min); if (i_min<n1) i_min++; if (j_min>1 ) j_min--; l1 = strchr(struc, '&')-struc; /* printf("%s %3d,%-3d : %3d,%-3d (%5.2f)\n", struc, i_min+1-l1, i_min, j_min, j_min+strlen(struc)-l1-2, Emin*0.01); */ mfe.i = i_min; mfe.j = j_min; mfe.energy = (float) Emin/100.; mfe.structure = struc; if (!delay_free) { for (i=1; i<=n1; i++) free(c[i]); free(c); free(S1); free(S2); free(SS1); free(SS2); } return mfe; }