/* Reads the thermodynamic parameters if the thermodynamic alignment tag was set to 1 */ static void read_thermodynamic_parameters() { thal_results o; /* if the path to the parameter files did not change, we do not want to read again */ if (thermodynamic_path_changed == 0) return; /* check that the path to the parameters folder was given */ if (thermodynamic_params_path == NULL) { #ifdef OS_WIN /* in windows check for .\\primer3_config */ struct stat st; if ((stat(".\\primer3_config", &st) == 0) && S_ISDIR(st.st_mode)) { thermodynamic_params_path = (char*) malloc(strlen(".\\primer3_config\\") * sizeof(char) + 1); if (NULL == thermodynamic_params_path) exit (-2); /* Out of memory */ strcpy(thermodynamic_params_path, ".\\primer3_config\\"); } else { /* no default directory found */ return; } #else /* in linux, check for ./primer3_config and /opt/primer3_config */ struct stat st; if ((stat("./primer3_config", &st) == 0) && S_ISDIR(st.st_mode)) { thermodynamic_params_path = (char*) malloc(strlen("./primer3_config/") * sizeof(char) + 1); if (NULL == thermodynamic_params_path) exit (-2); /* Out of memory */ strcpy(thermodynamic_params_path, "./primer3_config/"); } else if ((stat("/opt/primer3_config", &st) == 0) && S_ISDIR(st.st_mode)) { thermodynamic_params_path = (char*) malloc(strlen("/opt/primer3_config/") * sizeof(char) + 1); if (NULL == thermodynamic_params_path) exit (-2); /* Out of memory */ strcpy(thermodynamic_params_path, "/opt/primer3_config/"); } else { /* no default directory found */ return; } #endif } /* read in the thermodynamic parameters */ if (get_thermodynamic_values(thermodynamic_params_path, &o)) { fprintf(stderr, "%s\n", o.msg); exit(-1); } /* mark that the last given path was used for reading the parameters */ thermodynamic_path_changed = 0; }
static PyObject* loadThermoParams(PyObject *self, PyObject *args) { /* This loads the thermodynamic parameters from the parameter files * found at the provided path and should only need to be called once * prior to running thermodynamic calculations. Returns boolean indicating * success. */ char *param_path=NULL; thal_results thalres; if (!PyArg_ParseTuple(args, "s", ¶m_path)) { return NULL; } if (get_thermodynamic_values(param_path, &thalres)){ PyErr_SetString(PyExc_IOError, thalres.msg); return NULL; } else { Py_RETURN_TRUE; } }
/* Beginning of main */ int main(int argc, char** argv) { const char* usage; int tmp_ret; thal_args a; thal_results o; set_thal_default_args(&a); a.temponly=0; /* by default print only melting temperature, do not draw structure or print any additional parameters */ if(a.debug == 0) { #undef DEBUG } else { #define DEBUG } usage = "USAGE: %s OPTIONS oligo\n" "-mv monovalent_conc - concentration of monovalent cations in mM, by default 50 mM\n" "\n" "-dv divalent_conc - concentration of divalent cations in mM, by default 0 mM\n" "\n" "-n dNTP_conc - concentration of deoxynycleotide triphosphate in mM, by default 0 mM\n" "\n" "-d dna_conc - concentration of DNA strands in nM, by default 50 nM\n" "\n" "-a mode - alignment type, END1, END2, ANY and HAIRPIN, by default ANY (when duplex)\n" "\n" "-t temp - temperature at which duplex is calculated, by default 37C\n" "\n" "-r - causes the alignment NOT to be displayed on stderr, _only_ Tm is printed\n" "\n" "-maxloop size - the maximum size of secondary structures loops.\n" " Default is 30 (this is maximum allowed length, currently).\n" "\n" "-path <path> - the path to the thermodynamic parameter files\n" "\n" "-s1 DNA_oligomer\n" "\n" "-s2 DNA_oligomer\n" "\n"; if(argc < 2) { #ifdef DEBUG fprintf(stderr, usage, argv[0]); #endif return -1; } /* BEGIN: READ the INPUT */ for(i = 1; i < argc; ++i) { if (!strncmp("-mv", argv[i], 3)) { /* conc of monovalent cations */ if(argv[i+1]==NULL) { #ifdef DEBUG fprintf(stderr, usage, argv[0]); #endif exit(-1); } a.mv = strtod(argv[i+1], &endptr); if ('\0' != *endptr || a.mv < 0.0) { #ifdef DEBUG fprintf(stderr, usage, argv[0]); #endif exit(-1); } i++; } else if (!strncmp("-dv", argv[i], 3)) { /* conc of divalent cations */ if(argv[i+1]==NULL) { #ifdef DEBUG fprintf(stderr, usage, argv[0]); #endif exit(-1); } a.dv = strtod(argv[i+1], &endptr); if('\0' != *endptr || a.dv < 0.0) { #ifdef DEBUG fprintf(stderr, usage, argv[0]); #endif exit(-1); } i++; } else if (!strcmp("-path", argv[i])) { if(argv[i+1]==NULL) { #ifdef DEBUG fprintf(stderr, usage, argv[0]); #endif exit(-1); } path = (char*)argv[i+1]; i++; } else if (!strncmp("-s1", argv[i], 3)) { /* first sequence in 5'->3' direction */ if(argv[i+1]==NULL) { #ifdef DEBUG fprintf(stderr, usage, argv[0]); #endif exit(-1); } oligo1 = (const unsigned char*)argv[i+1]; i++; } else if (!strncmp("-s2", argv[i], 3)) { /* second sequence in 5'->3' direction */ if(argv[i+1]==NULL) { #ifdef DEBUG fprintf(stderr, usage, argv[0]); #endif exit(-1); } oligo2 = (const unsigned char*)argv[i+1]; i++; } else if (!strncmp("-a", argv[i], 2)) { /* annealing type END1, END2, ANY, considered only when duplexis; by default ANY */ if(argv[i+1]==NULL) { #ifdef DEBUG fprintf(stderr, usage, argv[0]); #endif exit(-1); } if(strcmp(argv[i+1],"END1")==0) { a.type = thal_end1; } else if(strcmp(argv[i+1],"END2")==0) { a.type = thal_end2; } else if(strcmp(argv[i+1],"HAIRPIN")==0) { a.type = thal_hairpin; a.dimer = 0; } else { a.type = thal_any; /* ANY */ } i++; } else if (!strncmp("-d", argv[i], 2)) { /* dna conc */ if(argv[i+1]==NULL) { #ifdef DEBUG fprintf(stderr, usage, argv[0]); #endif exit(-1); } a.dna_conc = strtod(argv[i+1], &endptr); if('\0' != *endptr || a.dna_conc < 0 || a.dna_conc == 0) { #ifdef DEBUG fprintf(stderr, usage, argv[0]); #endif exit(-1); } i++; } else if (!strncmp("-r", argv[i], 2)) { /* only temp is calculated */ a.temponly = 1; } else if (!strncmp("-t", argv[i], 2)) { /* temperature at which sec str are calculated */ if(argv[i+1]==NULL) { #ifdef DEBUG fprintf(stderr, usage, argv[0]); #endif exit(-1); } a.temp = strtod(argv[i+1], &endptr) + ABSOLUTE_ZERO; if('\0' != *endptr) { #ifdef DEBUG fprintf(stderr, usage, argv[0]); #endif exit(-1); } i++; } else if (!strncmp("-n", argv[i], 2)) { /* concentration of dNTPs */ if(argv[i+1]==NULL) { #ifdef DEBUG fprintf(stderr, usage, argv[0]); #endif exit(-1); } a.dntp = strtod(argv[i+1], &endptr); if('\0' != *endptr || a.dntp < 0.0) { #ifdef DEBUG fprintf(stderr, usage, argv[0]); #endif exit(-1); } i++; } else if (!strncmp("-maxloop", argv[i], 8)) { /* maximum size of loop calculated; this value can not be larger than 30 */ if(argv[i+1]==NULL) { #ifdef DEBUG fprintf(stderr, usage, argv[0]); #endif exit(-1); } a.maxLoop = (int) (strtod(argv[i+1], &endptr)); if(a.maxLoop > MAX_LOOP ) { a.maxLoop = MAX_LOOP; #ifdef DEBUG fputs("Warning: the maximum size of secondary structures loop is set to default (30)\n", stderr); #endif } else if(a.maxLoop < MIN_LOOP) { a.maxLoop = MIN_LOOP; #ifdef DEBUG fputs("Warning: the maximum size of secondary structures loop was set to minimum size of allowed loop length (0)\n", stderr); #endif } if('\0' != *endptr || a.maxLoop < 0) { #ifdef DEBUG fprintf(stderr, usage, argv[0]); #endif exit(-1); } i++; } else if(!strncmp("-", argv[i], 1)) { /* Unknown option. */ #ifdef DEBUG fprintf(stderr, usage, argv[0]); #endif exit(-1); } else { break; } } /* END reading INPUT */ /* check the input correctness */ if(a.dimer!=0 && (oligo2==NULL || oligo1==NULL)) { /* if user wants to calculate structure of dimer then two sequences must be defined*/ fprintf(stderr, usage, argv[0]); exit(-1); } if(a.dimer==0 && (oligo2==NULL && oligo1==NULL)) { /* if user wants to calculate structure of monomer then only one sequence must be defined */ fprintf(stderr, usage, argv[0]); exit(-1); } /* read thermodynamic parameters */ if (path == NULL) { /* check for the default paths */ struct stat st; #ifdef OS_WIN if ((stat(".\\primer3_config", &st) == 0) && S_ISDIR(st.st_mode)) { tmp_ret = get_thermodynamic_values(".\\primer3_config\\", &o); } else { /* no default directory found, error */ fprintf(stderr, "Error: thermodynamic approach chosen, but path to thermodynamic parameters not specified\n"); exit(-1); } #else if ((stat("./primer3_config", &st) == 0) && S_ISDIR(st.st_mode)) { tmp_ret = get_thermodynamic_values("./primer3_config/", &o); } else if ((stat("/opt/primer3_config", &st) == 0) && S_ISDIR(st.st_mode)) { tmp_ret = get_thermodynamic_values("/opt/primer3_config/", &o); } else { /* no default directory found, error */ fprintf(stderr, "Error: thermodynamic approach chosen, but path to thermodynamic parameters not specified\n"); exit(-1); } #endif } else tmp_ret = get_thermodynamic_values(path, &o); if (tmp_ret) { fprintf(stderr, "%s\n", o.msg); exit(-1); } /* execute thermodynamical alignemnt */ if(a.dimer==0 && oligo1!=NULL){ thal(oligo1,oligo1,&a,&o); } else if(a.dimer==0 && oligo1==NULL && oligo2!=NULL) { thal(oligo2,oligo2,&a,&o); } else { thal(oligo1,oligo2,&a,&o); } /* encountered error during thermodynamical calc */ if (o.temp == THAL_ERROR_SCORE) { tmp_ret = fprintf(stderr, "Error: %s\n", o.msg); exit(-1); } if(a.temponly==1) printf("%f\n",o.temp); /* cleanup */ destroy_thal_structures(); return EXIT_SUCCESS; }