/* Print the data for chosen primer pairs to stdout in "boulderio" format. */ void print_boulder(int io_version, const p3_global_settings *pa, const seq_args *sa, const p3retval *retval, int explain_flag) { /* The pointers to warning tag */ char *warning; /* A place to put a string containing all error messages */ pr_append_str *combined_retval_err = NULL; /* A small spacer; WARNING this is a fixed size buffer, but plenty bigger than log(2^64, 10), the longest character string that is needed for a 64 bit integer. */ char suffix [100]; /* Pointers for the primer set just printing */ primer_rec *fwd, *rev, *intl; /* Variables only used for Primer Lists */ int num_fwd, num_rev, num_int, num_pair, num_print; int print_fwd = 0; int print_rev = 0; int print_int = 0; /* Switches for printing this primer */ int go_fwd = 0; int go_rev = 0; int go_int = 0; /* The number of loop cycles */ int loop_max; /* That links to the included region */ int i, incl_s = sa->incl_s; /* This deals with the renaming of the internal oligo */ const char *new_oligo_name = "INTERNAL"; const char *old_oligo_name = "INTERNAL_OLIGO"; char *int_oligo = (char*) new_oligo_name; /* Check: are all pointers linked to something*/ PR_ASSERT(NULL != pa); PR_ASSERT(NULL != sa); if (io_version == 3) { int_oligo = (char*) old_oligo_name; } /* Check if there are warnings and print them */ if ((warning = p3_get_rv_and_gs_warnings(retval, pa)) != NULL) { printf("PRIMER_WARNING=%s\n", warning); free(warning); } /* Check if a settings file was read an print its id * Not needed anymore, we do this when we read the setting file. */ /* if (pa->settings_file_id != NULL) { printf("P3_FILE_ID=%s\n", pa->settings_file_id); free(warning); } */ combined_retval_err = create_pr_append_str(); if (NULL == combined_retval_err) exit(-2); /* Out of memory */ if (pr_append_new_chunk_external(combined_retval_err, retval->glob_err.data)) exit(-2); if (pr_append_new_chunk_external(combined_retval_err, retval->per_sequence_err.data)) exit(-2); /* Check if there are errors, print and return */ if (!pr_is_empty(combined_retval_err)) { print_boulder_error(pr_append_str_chars(combined_retval_err)); destroy_pr_append_str(combined_retval_err); return; } destroy_pr_append_str(combined_retval_err); /* Get how many primers are in the array */ num_fwd = retval->fwd.num_elem; num_rev = retval->rev.num_elem; num_int = retval->intl.num_elem; num_pair = retval->best_pairs.num_pairs; /* Prints out statistics about the primers */ if (explain_flag) print_all_explain(pa, sa, retval, io_version); /* Print out the stop codon if a reading frame was specified */ if (!PR_START_CODON_POS_IS_NULL(sa)) printf("PRIMER_STOP_CODON_POSITION=%d\n", retval->stop_codon_pos); /* How often has the loop to be done? */ if (retval->output_type == primer_list) { /* For Primer Lists: Figure out how many primers are in * the array that can be printed. If more than needed, * set it to the number requested. */ /* Get how may primers should be printed */ num_print = pa->num_return; /* Set how many primers will be printed */ print_fwd = (num_print < num_fwd) ? num_print : num_fwd; print_rev = (num_print < num_rev) ? num_print : num_rev; print_int = (num_print < num_int) ? num_print : num_int; /* Get which list has to print most primers */ loop_max = 0; if (loop_max < print_fwd) { loop_max = print_fwd; } if (loop_max < print_rev) { loop_max = print_rev; } if (loop_max < print_int) { loop_max = print_int; } /* Now the vars are there how often we have to go * through the loop and how many of each primer can * be printed. */ num_pair = 0; } else { loop_max = num_pair; /* Set how many primers will be printed */ print_fwd = num_pair; print_rev = num_pair; if (num_int != 0) { print_int = num_pair; } } if (io_version == 4) { printf("PRIMER_LEFT_NUM_RETURNED=%d\n", print_fwd); printf("PRIMER_RIGHT_NUM_RETURNED=%d\n", print_rev); printf("PRIMER_%s_NUM_RETURNED=%d\n", int_oligo, print_int); printf("PRIMER_PAIR_NUM_RETURNED=%d\n", num_pair); } /* --------------------------------------- */ /* Start of the loop printing all pairs or primers or oligos */ for(i=0; i<loop_max; i++) { /* What needs to be printed */ /* The conditions for primer lists */ if (retval->output_type == primer_list) { /* Attach the selected primers to the pointers */ fwd = &retval->fwd.oligo[i]; rev = &retval->rev.oligo[i]; intl = &retval->intl.oligo[i]; /* Do fwd oligos have to be printed? */ if ((pa->pick_left_primer) && (i < print_fwd)) { go_fwd = 1; } else { go_fwd = 0; } /* Do rev oligos have to be printed? */ if ((pa->pick_right_primer) && (i < print_rev)) { go_rev = 1; } else { go_rev = 0; } /* Do int oligos have to be printed? */ if ((pa->pick_internal_oligo) && (i < print_int)) { go_int = 1; } else { go_int = 0; } } else { /* We will print primer pairs or pairs plus internal oligos */ /* Get pointers to the primer_rec's that we will print */ fwd = retval->best_pairs.pairs[i].left; rev = retval->best_pairs.pairs[i].right; intl = retval->best_pairs.pairs[i].intl; /* Pairs must have fwd and rev primers */ go_fwd = 1; go_rev = 1; /* Do hyb oligos have to be printed? */ if (pa->pick_internal_oligo == 1) { go_int = 1; } else { go_int = 0; } } /* Get the number for pimer counting in suffix[0] */ if ((i == 0) && (io_version == 3) ){ suffix[0] = '\0'; } else { sprintf(suffix, "_%d", i); } /* Print out the Pair Penalties */ if (retval->output_type == primer_pairs) { if (io_version == 3) { printf("PRIMER_PAIR_PENALTY%s=%.4f\n", suffix, retval->best_pairs.pairs[i].pair_quality); } else { printf("PRIMER_PAIR%s_PENALTY=%f\n", suffix, retval->best_pairs.pairs[i].pair_quality); } } /* Print single primer penalty */ if (go_fwd == 1) printf("PRIMER_LEFT%s_PENALTY=%f\n", suffix, fwd->quality); if (go_rev == 1) printf("PRIMER_RIGHT%s_PENALTY=%f\n", suffix, rev->quality); if (go_int == 1) printf("PRIMER_%s%s_PENALTY=%f\n", int_oligo, suffix, intl->quality); /* Print the oligo_problems */ if (io_version == 4) { if (go_fwd == 1 && p3_ol_has_any_problem(fwd)) printf("PRIMER_LEFT%s_PROBLEMS=%s\n", suffix, p3_get_ol_problem_string(fwd)); if (go_rev == 1 && p3_ol_has_any_problem(rev)) printf("PRIMER_RIGHT%s_PROBLEMS=%s\n", suffix, p3_get_ol_problem_string(rev)); if (go_int == 1 && p3_ol_has_any_problem(intl)) printf("PRIMER_%s%s_PROBLEMS=%s\n", int_oligo, suffix, p3_get_ol_problem_string(intl)); } /* Print primer sequences. */ if (go_fwd == 1) printf("PRIMER_LEFT%s_SEQUENCE=%s\n", suffix, pr_oligo_sequence(sa, fwd)); if (go_rev == 1) printf("PRIMER_RIGHT%s_SEQUENCE=%s\n", suffix, pr_oligo_rev_c_sequence(sa, rev)); if(go_int == 1) printf("PRIMER_%s%s_SEQUENCE=%s\n", int_oligo, suffix, pr_oligo_sequence(sa,intl)); /* Print primer start and length */ if (go_fwd == 1) printf("PRIMER_LEFT%s=%d,%d\n", suffix, fwd->start + incl_s + pa->first_base_index, fwd->length); if (go_rev == 1) printf("PRIMER_RIGHT%s=%d,%d\n", suffix, rev->start + incl_s + pa->first_base_index, rev->length); if (go_int == 1) printf("PRIMER_%s%s=%d,%d\n", int_oligo, suffix, intl->start + incl_s + pa->first_base_index, intl->length); /* Print primer Tm */ if (go_fwd == 1) printf("PRIMER_LEFT%s_TM=%.3f\n", suffix, fwd->temp); if (go_rev == 1) printf("PRIMER_RIGHT%s_TM=%.3f\n", suffix, rev->temp); if (go_int == 1) printf("PRIMER_%s%s_TM=%.3f\n", int_oligo, suffix, intl->temp); /* Print primer GC content */ if (go_fwd == 1) printf("PRIMER_LEFT%s_GC_PERCENT=%.3f\n", suffix, fwd->gc_content); if (go_rev == 1) printf("PRIMER_RIGHT%s_GC_PERCENT=%.3f\n", suffix, rev->gc_content); if (go_int == 1) printf("PRIMER_%s%s_GC_PERCENT=%.3f\n", int_oligo, suffix, intl->gc_content); /* Print primer self_any */ if (go_fwd == 1 && pa->thermodynamic_alignment==0) printf("PRIMER_LEFT%s_SELF_ANY=%.2f\n", suffix, fwd->self_any); if (go_rev == 1 && pa->thermodynamic_alignment==0) printf("PRIMER_RIGHT%s_SELF_ANY=%.2f\n", suffix, rev->self_any); if (go_int == 1 && pa->thermodynamic_alignment==0) printf("PRIMER_%s%s_SELF_ANY=%.2f\n", int_oligo, suffix, intl->self_any); if (go_int == 1 && pa->thermodynamic_alignment==1) printf("PRIMER_%s%s_SELF_ANY_TH=%.2f\n", int_oligo, suffix, intl->self_any); /* Print primer self_any thermodynamical approach */ if (go_fwd == 1 && pa->thermodynamic_alignment==1) printf("PRIMER_LEFT%s_SELF_ANY_TH=%.2f\n", suffix, fwd->self_any); if (go_rev == 1 && pa->thermodynamic_alignment==1) printf("PRIMER_RIGHT%s_SELF_ANY_TH=%.2f\n", suffix, rev->self_any); /* Print primer self_end*/ if (go_fwd == 1 && pa->thermodynamic_alignment==0) printf("PRIMER_LEFT%s_SELF_END=%.2f\n", suffix, fwd->self_end); if (go_rev == 1 && pa->thermodynamic_alignment==0) printf("PRIMER_RIGHT%s_SELF_END=%.2f\n", suffix, rev->self_end); if (go_int == 1 && pa->thermodynamic_alignment==0) printf("PRIMER_%s%s_SELF_END=%.2f\n", int_oligo, suffix, intl->self_end); if (go_int == 1 && pa->thermodynamic_alignment==1) printf("PRIMER_%s%s_SELF_END_TH=%.2f\n", int_oligo, suffix, intl->self_end); /* Print primer self_end thermodynamical approach */ if (go_fwd == 1 && pa->thermodynamic_alignment==1) printf("PRIMER_LEFT%s_SELF_END_TH=%.2f\n", suffix, fwd->self_end); if (go_rev == 1 && pa->thermodynamic_alignment==1) printf("PRIMER_RIGHT%s_SELF_END_TH=%.2f\n", suffix, rev->self_end); /* Print primer hairpin */ if (go_fwd == 1 && pa->thermodynamic_alignment==1) printf("PRIMER_LEFT%s_HAIRPIN_TH=%.2f\n", suffix, fwd->hairpin_th); if (go_rev == 1 && pa->thermodynamic_alignment==1) printf("PRIMER_RIGHT%s_HAIRPIN_TH=%.2f\n", suffix, rev->hairpin_th); if (go_int == 1 && pa->thermodynamic_alignment==1) printf("PRIMER_%s%s_HAIRPIN_TH=%.2f\n", int_oligo, suffix, intl->hairpin_th); /*Print out primer mispriming scores */ if (io_version == 3) { if (seq_lib_num_seq(pa->p_args.repeat_lib) > 0) { if (go_fwd == 1) printf("PRIMER_LEFT%s_MISPRIMING_SCORE=%.2f, %s\n", suffix, fwd->repeat_sim.score[fwd->repeat_sim.max], fwd->repeat_sim.name); if (go_rev == 1) printf("PRIMER_RIGHT%s_MISPRIMING_SCORE=%.2f, %s\n", suffix, rev->repeat_sim.score[rev->repeat_sim.max], rev->repeat_sim.name); if (retval->output_type == primer_pairs) printf("PRIMER_PAIR%s_MISPRIMING_SCORE=%.2f, %s\n", suffix, retval->best_pairs.pairs[i].repeat_sim, retval->best_pairs.pairs[i].rep_name); } /* Print out internal oligo mispriming scores */ if (go_int == 1 && seq_lib_num_seq(pa->o_args.repeat_lib) > 0) printf("PRIMER_%s%s_MISHYB_SCORE=%.2f, %s\n", int_oligo, suffix, intl->repeat_sim.score[intl->repeat_sim.max], intl->repeat_sim.name); } else { if (seq_lib_num_seq(pa->p_args.repeat_lib) > 0) { if (go_fwd == 1) printf("PRIMER_LEFT%s_LIBRARY_MISPRIMING=%.2f, %s\n", suffix, fwd->repeat_sim.score[fwd->repeat_sim.max], fwd->repeat_sim.name); if (go_rev == 1) printf("PRIMER_RIGHT%s_LIBRARY_MISPRIMING=%.2f, %s\n", suffix, rev->repeat_sim.score[rev->repeat_sim.max], rev->repeat_sim.name); if (retval->output_type == primer_pairs) printf("PRIMER_PAIR%s_LIBRARY_MISPRIMING=%.2f, %s\n", suffix, retval->best_pairs.pairs[i].repeat_sim, retval->best_pairs.pairs[i].rep_name); } /* Print out internal oligo mispriming scores */ if (go_int == 1 && seq_lib_num_seq(pa->o_args.repeat_lib) > 0) printf("PRIMER_%s%s_LIBRARY_MISHYB=%.2f, %s\n", int_oligo, suffix, intl->repeat_sim.score[intl->repeat_sim.max], intl->repeat_sim.name); } /* If a sequence quality was provided, print it*/ if (NULL != sa->quality){ if (go_fwd == 1) printf("PRIMER_LEFT%s_MIN_SEQ_QUALITY=%d\n", suffix, fwd->seq_quality); if (go_rev == 1) printf("PRIMER_RIGHT%s_MIN_SEQ_QUALITY=%d\n", suffix, rev->seq_quality); if (go_int == 1 && (retval->output_type == primer_list)) printf("PRIMER_%s%s_MIN_SEQ_QUALITY=%d\n", int_oligo, suffix, intl->seq_quality); /* Has to be here and in primer pairs for backward compatibility */ } /* Print position penalty, this is for backward compatibility */ if (!_PR_DEFAULT_POSITION_PENALTIES(pa) || !PR_START_CODON_POS_IS_NULL(sa)){ printf("PRIMER_LEFT%s_POSITION_PENALTY=%f\n", suffix, fwd->position_penalty); printf("PRIMER_RIGHT%s_POSITION_PENALTY=%f\n", suffix, rev->position_penalty); } /* Print primer end stability */ if (go_fwd == 1) printf("PRIMER_LEFT%s_END_STABILITY=%.4f\n", suffix, fwd->end_stability); if (go_rev == 1) printf("PRIMER_RIGHT%s_END_STABILITY=%.4f\n", suffix, rev->end_stability); /* Print primer template mispriming */ if ( (pa->thermodynamic_alignment == 0) && (go_fwd == 1) && (oligo_max_template_mispriming(fwd) != ALIGN_SCORE_UNDEF)) printf("PRIMER_LEFT%s_TEMPLATE_MISPRIMING=%.4f\n", suffix, oligo_max_template_mispriming(fwd)); if ( (pa->thermodynamic_alignment == 0) && (go_rev == 1) && (oligo_max_template_mispriming(rev) != ALIGN_SCORE_UNDEF)) printf("PRIMER_RIGHT%s_TEMPLATE_MISPRIMING=%.4f\n", suffix, oligo_max_template_mispriming(rev)); /* Print primer template mispriming thermodynamical approach*/ if ( (pa->thermodynamic_alignment == 1) && (go_fwd == 1) && (oligo_max_template_mispriming_thermod(fwd) != ALIGN_SCORE_UNDEF)) printf("PRIMER_LEFT%s_TEMPLATE_MISPRIMING_TH=%.4f\n", suffix, oligo_max_template_mispriming_thermod(fwd)); if ( (pa->thermodynamic_alignment == 1) && (go_rev == 1) && (oligo_max_template_mispriming_thermod(rev) != ALIGN_SCORE_UNDEF)) printf("PRIMER_RIGHT%s_TEMPLATE_MISPRIMING_TH=%.4f\n", suffix, oligo_max_template_mispriming_thermod(rev)); /************************************************************************************/ /* Print the pair parameters*/ if (retval->output_type == primer_pairs) { if (go_int == 1 && NULL != sa->quality) /* FIX ME - Uptate the tests */ printf("PRIMER_%s%s_MIN_SEQ_QUALITY=%d\n", int_oligo, suffix, intl->seq_quality); /* Print pair comp_any */ if(pa->thermodynamic_alignment==0) printf("PRIMER_PAIR%s_COMPL_ANY=%.2f\n", suffix, retval->best_pairs.pairs[i].compl_any); if(pa->thermodynamic_alignment==1) printf("PRIMER_PAIR%s_COMPL_ANY_TH=%.2f\n", suffix, retval->best_pairs.pairs[i].compl_any); /* Print pair comp_end */ if(pa->thermodynamic_alignment==0) printf("PRIMER_PAIR%s_COMPL_END=%.2f\n", suffix, retval->best_pairs.pairs[i].compl_end); if(pa->thermodynamic_alignment==1) printf("PRIMER_PAIR%s_COMPL_END_TH=%.2f\n", suffix, retval->best_pairs.pairs[i].compl_end); if (io_version == 3) { /* Print product size */ printf("PRIMER_PRODUCT_SIZE%s=%d\n", suffix, retval->best_pairs.pairs[i].product_size); /* Print the product Tm if a Tm range is defined */ if (pa->product_max_tm != PR_DEFAULT_PRODUCT_MAX_TM || pa->product_min_tm != PR_DEFAULT_PRODUCT_MIN_TM) { printf("PRIMER_PRODUCT_TM%s=%.4f\n", suffix, retval->best_pairs.pairs[i].product_tm); printf("PRIMER_PRODUCT_TM_OLIGO_TM_DIFF%s=%.4f\n", suffix, retval->best_pairs.pairs[i].product_tm_oligo_tm_diff); printf("PRIMER_PAIR%s_T_OPT_A=%.4f\n", suffix, retval->best_pairs.pairs[i].t_opt_a); } } else { /* Print product size */ printf("PRIMER_PAIR%s_PRODUCT_SIZE=%d\n", suffix, retval->best_pairs.pairs[i].product_size); /* Print the product Tm if a Tm range is defined */ if (pa->product_max_tm != PR_DEFAULT_PRODUCT_MAX_TM || pa->product_min_tm != PR_DEFAULT_PRODUCT_MIN_TM) { printf("PRIMER_PAIR%s_PRODUCT_TM=%.4f\n", suffix, retval->best_pairs.pairs[i].product_tm); printf("PRIMER_PAIR%s_PRODUCT_TM_OLIGO_TM_DIFF=%.4f\n", suffix, retval->best_pairs.pairs[i].product_tm_oligo_tm_diff); printf("PRIMER_PAIR%s_T_OPT_A=%.4f\n", suffix, retval->best_pairs.pairs[i].t_opt_a); } } /* Print the primer pair temlate mispriming */ if ((pa->thermodynamic_alignment == 0) && (retval->best_pairs.pairs[i].template_mispriming != ALIGN_SCORE_UNDEF)) printf("PRIMER_PAIR%s_TEMPLATE_MISPRIMING=%.2f\n", suffix, retval->best_pairs.pairs[i].template_mispriming); /* Print the primer pair temlate mispriming. Thermodynamic approach. */ if ((pa->thermodynamic_alignment == 1) && (retval->best_pairs.pairs[i].template_mispriming != ALIGN_SCORE_UNDEF)) printf("PRIMER_PAIR%s_TEMPLATE_MISPRIMING_TH=%.2f\n", suffix, retval->best_pairs.pairs[i].template_mispriming); } /* End of print parameters of primer pairs */ } /* End of the big loop printing all data */ /* End the print with newline and flush all buffers */ printf("=\n"); if (fflush(stdout) == EOF) { perror("fflush(stdout) failed"); exit(-1); } }
static void format_pairs(FILE *f, const p3_global_settings *pa, const seq_args *sa, const p3retval *retval, const pair_array_t *best_pairs, const char *pr_release, const pr_append_str *combined_retval_err, int explain_flag) { char *warning; int print_lib_sim = lib_sim_specified(pa); primer_rec *h = NULL; PR_ASSERT(NULL != f); PR_ASSERT(NULL != pa); PR_ASSERT(NULL != sa); /* If there are errors, print them and return */ if (!pr_is_empty(combined_retval_err)) { format_error(f, sa->sequence_name, pr_append_str_chars(combined_retval_err)); return; } /* Print the sequence name if it is provided */ if (NULL != sa->sequence_name) fprintf(f, "PRIMER PICKING RESULTS FOR %s\n\n", sa->sequence_name); /* Print if a mispriming libraby was used and which one */ if (pa->p_args.repeat_lib != NULL) fprintf(f, "Using mispriming library %s\n", pa->p_args.repeat_lib->repeat_file); else fprintf(f, "No mispriming library specified\n"); /* Print if a mispriming libraby for the internal oligo * was used and which one */ if ( pa->pick_internal_oligo == 1 ) { if (pa->o_args.repeat_lib != NULL) fprintf(f, "Using internal oligo mishyb library %s\n", pa->o_args.repeat_lib->repeat_file); else fprintf(f, "No internal oligo mishyb library specified\n"); } /* Does the sequence start at position 0 or 1 ? */ fprintf(f, "Using %d-based sequence positions\n", pa->first_base_index); /* Complain if no primers are in the array */ if (best_pairs->num_pairs == 0) fprintf(f, "NO PRIMERS FOUND\n\n"); /* Print out the warings */ if ((warning = p3_get_rv_and_gs_warnings(retval, pa)) != NULL) { fprintf(f, "WARNING: %s\n\n", warning); free(warning); } /* Print the results for the best pair */ print_summary(f, pa, sa, best_pairs, 0); fprintf(f, "\n"); /* Print nicely out the sequence with the best pair */ if (print_seq(f, pa, sa, retval, h, best_pairs, 0)) exit(-2); /* ENOMEM */ /* Print out the alternative pairs */ if (best_pairs->num_pairs > 1 ) print_rest(f, pa, sa, best_pairs); /* Print the primer picking statistics */ if (explain_flag) print_explain(f, pa, sa, retval, print_lib_sim, pr_release); /* Flush the buffers and return */ fprintf(f, "\n\n"); if (fflush(f) == EOF) { perror("fflush(f) failed"); exit(-1); } }
int main(int argc, char *argv[]) { /* Setup the input data structures handlers */ int format_output = 0; int strict_tags = 0; int dump_args = 0 ; /* set to 1 if dumping arguments to choose_primers */ int io_version = 4; /* Some space for file names */ char *tmp_file_name = NULL; char p3_all_file[FILE_NAME_SIZE]; char p3_settings_file[FILE_NAME_SIZE]; p3_global_settings *global_pa; seq_args *sarg; read_boulder_record_results read_boulder_record_res = {0,0}; pr_append_str fatal_parse_err; pr_append_str nonfatal_parse_err; /* Retval will point to the return value from choose_primers(). */ p3retval *retval = NULL; int input_found=0; p3_all_file[0] = '\0'; p3_settings_file[0] = '\0'; init_pr_append_str(&fatal_parse_err); init_pr_append_str(&nonfatal_parse_err); /* Get the program name for correct error messages */ pr_program_name = argv[0]; p3_set_program_name(pr_program_name); /* We set up some signal handlers in case someone starts up the program * from the command line, wonders why nothing is happening, and then kills * the program. */ signal(SIGINT, sig_handler); signal(SIGTERM, sig_handler); /* Allocate the space for global settings and fill in default parameters */ global_pa = p3_create_global_settings(); if (!global_pa) { exit(-2); /* Out of memory. */ } if (dump_args) global_pa->dump = 1 ; /* Read in the flags provided with the program call */ while (--argc > 0) { argv++; if (!strcmp(*argv, "-format_output")) { format_output = 1; } else if (!strcmp(*argv, "-about")) { printf( "%s\n", pr_release); exit (0); } else if (!strcmp(*argv, "-2x_compat")) { printf( "PRIMER_ERROR=flag -2x_compat is no longer supported\n=\n"); exit (-1); } else if (!strcmp(*argv, "-io_version=3")) { io_version = 3; } else if (!strcmp(*argv, "-io_version=4")) { io_version = 4; } else if (!strncmp(*argv, "-p3_settings_file=", 18)) { tmp_file_name = strchr(*argv,'=') + 1; strncpy (p3_settings_file,tmp_file_name,FILE_NAME_SIZE-1); } else if (!strcmp(*argv, "-strict_tags")) { strict_tags = 1; } else { print_usage(); exit(-1); } } /* Settings files have to be read in just below, and the functions need a temporary sarg */ if (!(sarg = create_seq_arg())) { exit(-2); } /* Read data from the settings file until a "=" line occurs. Assign parameter * values for primer picking to pa and sa. */ if (p3_settings_file[0] != '\0') { read_p3_file(p3_settings_file, settings, global_pa, sarg, &fatal_parse_err, &nonfatal_parse_err, &read_boulder_record_res); } /* We also need to print out errors here because the loop erases all * errors at start */ /* If there are fatal errors, write the proper message and exit */ if (fatal_parse_err.data != NULL) { if (format_output) { format_error(stdout, sarg->sequence_name, fatal_parse_err.data); } else { print_boulder_error(fatal_parse_err.data); } fprintf(stderr, "%s: %s\n", pr_program_name, fatal_parse_err.data); destroy_seq_args(sarg); exit(-4); } /* If there are nonfatal errors, write the proper message * and skip to the end of the loop */ if (!pr_is_empty(&nonfatal_parse_err)) { if (format_output) { format_error(stdout, sarg->sequence_name, nonfatal_parse_err.data); } else { print_boulder_error(nonfatal_parse_err.data); } } /* The temporary sarg is not needed any more */ destroy_seq_args(sarg); sarg = NULL; /* Read the data from input stream record by record and process it if * there are no errors. This is where the work is done. */ while (1) { /* Create and initialize a seq_args data structure. sa (seq_args *) is * initialized here because Values are _not_ retained across different * input records. */ if (!(sarg = create_seq_arg())) { exit(-2); } /* Reset all errors handlers and the return structure */ pr_set_empty(&fatal_parse_err); pr_set_empty(&nonfatal_parse_err); retval = NULL; /* See read_boulder.h for documentation on read_boulder_record().*/ if (!read_boulder_record(stdin, &strict_tags, &io_version, !format_output, all_parameters, global_pa, sarg, &fatal_parse_err, &nonfatal_parse_err, &read_boulder_record_res)) { break; /* There were no more boulder records */ } input_found = 1; if ((global_pa->primer_task == pick_detection_primers) && (global_pa->pick_internal_oligo == 1)){ PR_ASSERT(global_pa->pick_internal_oligo); } /* If there are fatal errors, write the proper message and exit */ if (fatal_parse_err.data != NULL) { if (format_output) { format_error(stdout, sarg->sequence_name, fatal_parse_err.data); } else { print_boulder_error(fatal_parse_err.data); } fprintf(stderr, "%s: %s\n", pr_program_name, fatal_parse_err.data); destroy_p3retval(retval); destroy_seq_args(sarg); exit(-4); } /* If there are nonfatal errors, write the proper message * and skip to the end of the loop */ if (!pr_is_empty(&nonfatal_parse_err)) { if (format_output) { format_error(stdout, sarg->sequence_name, nonfatal_parse_err.data); } else { print_boulder_error(nonfatal_parse_err.data); } goto loop_wrap_up; } if (read_boulder_record_res.file_flag && sarg->sequence_name == NULL) { /* We will not have a base name for the files */ if (format_output) { format_error(stdout, NULL, "Need PRIMER_SEQUENCE_ID if PRIMER_FILE_FLAG is not 0"); } else { print_boulder_error("Need PRIMER_SEQUENCE_ID if PRIMER_FILE_FLAG is not 0"); } goto loop_wrap_up; } /* Pick the primers - the central function */ p3_set_gs_primer_file_flag(global_pa, read_boulder_record_res.file_flag); retval = choose_primers(global_pa, sarg); if (NULL == retval) exit(-2); /* Out of memory. */ /* This is old code to make it compatible with version 3 input. In future versions it can be deleted! If it was necessary to use a left_input, right_input, or internal_oligo_input primer that was unacceptable, then add warnings. */ if (global_pa->pick_anyway && (io_version == 3 || format_output)) { if (sarg->left_input) { add_must_use_warnings(&retval->warnings, "Left primer", &retval->fwd.expl); } if (sarg->right_input) { add_must_use_warnings(&retval->warnings, "Right primer", &retval->rev.expl); } if (sarg->internal_input) { add_must_use_warnings(&retval->warnings, "Hybridization probe", &retval->intl.expl); } } /* End of the old code for compartibility. */ if (pr_is_empty(&retval->glob_err) && pr_is_empty(&retval->per_sequence_err)) { /* We need to test for errors before we call p3_print_oligo_lists. This function only works on retval as returned when there were no errors. */ if (read_boulder_record_res.file_flag) { /* Create files with left, right, and internal oligos. */ p3_print_oligo_lists(retval, sarg, global_pa, &retval->per_sequence_err, sarg->sequence_name); } } if (format_output) { print_format_output(stdout, &io_version, global_pa, sarg, retval, pr_release, read_boulder_record_res.explain_flag); } else { /* Use boulder output */ print_boulder(/* & */io_version, global_pa, sarg, retval, read_boulder_record_res.explain_flag); } loop_wrap_up: /* Here the failed loops join in again */ if (NULL != retval) { /* Check for errors and print them */ if (NULL != retval->glob_err.data) { fprintf(stderr, "%s: %s\n", pr_program_name, retval->glob_err.data); destroy_p3retval(retval); destroy_seq_args(sarg); exit(-4); } } destroy_p3retval(retval); /* This works even if retval is NULL */ retval = NULL; destroy_seq_args(sarg); sarg = NULL; } /* while (1) (processing boulder io records) ... End of the primary working loop */ /* To avoid being distracted when looking for leaks: */ p3_destroy_global_settings(global_pa); global_pa = NULL; destroy_seq_args(sarg); destroy_pr_append_str_data(&nonfatal_parse_err); destroy_pr_append_str_data(&fatal_parse_err); destroy_dpal_thal_arg_holder(); /* If it could not read input complain and die */ if (0 == input_found) { print_usage(); exit(-3); } return 0; }
int main(int argc, char *argv[]) { /* Setup the input data structures handlers */ int format_output = 0; int strict_tags = 0; int echo_settings = 0; int dump_args = 0 ; /* set to 1 if dumping arguments to choose_primers */ int io_version = 4; /* Some space for file names */ char p3_all_file[FILE_NAME_SIZE]; char p3_settings_file[FILE_NAME_SIZE]; p3_global_settings *global_pa; seq_args *sarg; read_boulder_record_results read_boulder_record_res = {0,0}; pr_append_str fatal_parse_err; pr_append_str nonfatal_parse_err; pr_append_str warnings; /* Some variables needed by getopt */ int opt, option_index = 0; struct option long_options[] = { {"about", no_argument, 0, 'a'}, {"format_output", no_argument, &format_output, 1}, {"strict_tags", no_argument, &strict_tags, 1}, {"p3_settings_file", required_argument, 0, 'p'}, {"echo_settings_file", no_argument, &echo_settings, 1}, {"io_version", required_argument, 0, 'i'}, {"2x_compat", no_argument, 0, '2'}, {"output", required_argument, 0, 'o'}, {"error", required_argument, 0, 'e'}, {0, 0, 0, 0} }; int about = 0, output = 0, error = 0, compat = 0, invalid_flag = 0; char output_file[FILE_NAME_SIZE], error_file[FILE_NAME_SIZE]; /* Retval will point to the return value from choose_primers(). */ p3retval *retval = NULL; int input_found=0; p3_all_file[0] = '\0'; p3_settings_file[0] = '\0'; init_pr_append_str(&fatal_parse_err); init_pr_append_str(&nonfatal_parse_err); init_pr_append_str(&warnings); /* Get the program name for correct error messages */ pr_release = libprimer3_release(); pr_program_name = argv[0]; p3_set_program_name(pr_program_name); /* We set up some signal handlers in case someone starts up the program * from the command line, wonders why nothing is happening, and then kills * the program. */ signal(SIGINT, sig_handler); signal(SIGTERM, sig_handler); /* Allocate the space for global settings and fill in default parameters */ global_pa = p3_create_global_settings(); if (!global_pa) { exit(-2); /* Out of memory. */ } if (dump_args) global_pa->dump = 1 ; /* Read in the flags provided with the program call */ opterr = 0; while ((opt = getopt_long_only(argc, argv, "", long_options, &option_index)) != -1) { switch (opt) { case 'a': about = 1; break; case 'p': strncpy(p3_settings_file, optarg, FILE_NAME_SIZE - 1); break; case 'i': if (!strcmp(optarg, "3")) io_version = 3; else if (!strcmp(optarg, "4")) io_version = 4; else io_version = -1; break; case '2': compat = 1; break; case 'o': output = 1; strncpy(output_file, optarg, FILE_NAME_SIZE - 1); break; case 'e': error = 1; strncpy(error_file, optarg, FILE_NAME_SIZE - 1); break; case '?': invalid_flag = 1; break; } } /* Open the output and error files specified */ if (error == 1) { /* reassign stderr */ if (freopen(error_file, "w", stderr) == NULL) { fprintf(stderr, "Error creating file %s\n", error_file); exit(-1); } } if (output == 1) { /* reassign stdout */ if (freopen(output_file, "w", stdout) == NULL) { fprintf(stderr, "Error creating file %s\n", output_file); exit(-1); } } /* We do any printing after redirecting stdout and stderr */ if (about == 1) { printf("%s\n", pr_release); exit(0); } if ((io_version == -1) || (invalid_flag == 1)) { print_usage(); exit(-1); } if (compat == 1) { printf("PRIMER_ERROR=flag -2x_compat is no longer supported\n=\n"); exit(-1); } /* Check if an input file has been specified */ if (optind < argc) { if (optind + 1 != argc) { print_usage(); exit(-1); } if (freopen(argv[optind], "r", stdin) == NULL) { fprintf(stderr, "Error opening file %s\n", argv[optind]); exit(-1); } } /* Settings files have to be read in just below, and the functions need a temporary sarg */ if (!(sarg = create_seq_arg())) { exit(-2); } /* Read data from the settings file until a "=" line occurs. Assign parameter * values for primer picking to pa and sa. */ if (p3_settings_file[0] != '\0') { read_p3_file(p3_settings_file, settings, echo_settings && !format_output, global_pa, sarg, &fatal_parse_err, &nonfatal_parse_err, &warnings, &read_boulder_record_res); /* Check if the thermodynamical alignment flag was given */ if (global_pa->thermodynamic_alignment == 1) read_thermodynamic_parameters(); } /* We also need to print out errors here because the loop erases all * errors at start */ /* If there are fatal errors, write the proper message and exit */ if (fatal_parse_err.data != NULL) { if (format_output) { format_error(stdout, sarg->sequence_name, fatal_parse_err.data); } else { print_boulder_error(fatal_parse_err.data); } fprintf(stderr, "%s: %s\n", pr_program_name, fatal_parse_err.data); destroy_seq_args(sarg); exit(-4); } /* If there are nonfatal errors, write the proper message * and skip to the end of the loop */ if (!pr_is_empty(&nonfatal_parse_err)) { if (format_output) { format_error(stdout, sarg->sequence_name, nonfatal_parse_err.data); } else { print_boulder_error(nonfatal_parse_err.data); } } /* The temporary sarg is not needed any more */ destroy_seq_args(sarg); sarg = NULL; /* Read the data from input stream record by record and process it if * there are no errors. This is where the work is done. */ while (1) { /* Create and initialize a seq_args data structure. sa (seq_args *) is * initialized here because Values are _not_ retained across different * input records. */ if (!(sarg = create_seq_arg())) { exit(-2); } /* Reset all errors handlers and the return structure */ pr_set_empty(&fatal_parse_err); pr_set_empty(&nonfatal_parse_err); pr_set_empty(&warnings); retval = NULL; /* See read_boulder.h for documentation on read_boulder_record().*/ if (!read_boulder_record(stdin, &strict_tags, &io_version, !format_output, all_parameters, global_pa, sarg, &fatal_parse_err, &nonfatal_parse_err, &warnings, &read_boulder_record_res)) { break; /* There were no more boulder records */ } /* Check if the thermodynamical alignment flag was given and the path to the parameter files changed - we need to reread them */ if ((global_pa->thermodynamic_alignment == 1) && (thermodynamic_path_changed == 1)) read_thermodynamic_parameters(); input_found = 1; if ((global_pa->primer_task == pick_detection_primers) && (global_pa->pick_internal_oligo == 1)){ PR_ASSERT(global_pa->pick_internal_oligo); } /* If there are fatal errors, write the proper message and exit */ if (fatal_parse_err.data != NULL) { if (format_output) { format_error(stdout, sarg->sequence_name, fatal_parse_err.data); } else { print_boulder_error(fatal_parse_err.data); } fprintf(stderr, "%s: %s\n", pr_program_name, fatal_parse_err.data); destroy_p3retval(retval); destroy_seq_args(sarg); exit(-4); } /* If there are nonfatal errors, write the proper message * and skip to the end of the loop */ if (!pr_is_empty(&nonfatal_parse_err)) { if (format_output) { format_error(stdout, sarg->sequence_name, nonfatal_parse_err.data); } else { print_boulder_error(nonfatal_parse_err.data); } goto loop_wrap_up; } /* Print any warnings and continue processing */ if (!pr_is_empty(&warnings)) { if (format_output) { format_warning(stdout, sarg->sequence_name, warnings.data); } else { print_boulder_warning(warnings.data); } } if (read_boulder_record_res.file_flag && sarg->sequence_name == NULL) { /* We will not have a base name for the files */ if (format_output) { format_error(stdout, NULL, "Need PRIMER_SEQUENCE_ID if PRIMER_FILE_FLAG is not 0"); } else { print_boulder_error("Need PRIMER_SEQUENCE_ID if PRIMER_FILE_FLAG is not 0"); } goto loop_wrap_up; } /* Pick the primers - the central function */ p3_set_gs_primer_file_flag(global_pa, read_boulder_record_res.file_flag); retval = choose_primers(global_pa, sarg); if (NULL == retval) exit(-2); /* Out of memory. */ /* This is old code to make it compatible with version 3 input. In future versions it can be deleted! If it was necessary to use a left_input, right_input, or internal_oligo_input primer that was unacceptable, then add warnings. */ if (global_pa->pick_anyway && (io_version == 3 || format_output)) { if (sarg->left_input) { add_must_use_warnings(&retval->warnings, "Left primer", &retval->fwd.expl); } if (sarg->right_input) { add_must_use_warnings(&retval->warnings, "Right primer", &retval->rev.expl); } if (sarg->internal_input) { add_must_use_warnings(&retval->warnings, "Hybridization probe", &retval->intl.expl); } } /* End of the old code for compartibility. */ if (pr_is_empty(&retval->glob_err) && pr_is_empty(&retval->per_sequence_err)) { /* We need to test for errors before we call p3_print_oligo_lists. This function only works on retval as returned when there were no errors. */ if (read_boulder_record_res.file_flag) { /* Create files with left, right, and internal oligos. */ p3_print_oligo_lists(retval, sarg, global_pa, &retval->per_sequence_err, sarg->sequence_name); } } if (format_output) { print_format_output(stdout, &io_version, global_pa, sarg, retval, pr_release, read_boulder_record_res.explain_flag); } else { /* Use boulder output */ print_boulder(/* & */io_version, global_pa, sarg, retval, read_boulder_record_res.explain_flag); } loop_wrap_up: /* Here the failed loops join in again */ if (NULL != retval) { /* Check for errors and print them */ if (NULL != retval->glob_err.data) { fprintf(stderr, "%s: %s\n", pr_program_name, retval->glob_err.data); destroy_p3retval(retval); destroy_seq_args(sarg); exit(-4); } } destroy_p3retval(retval); /* This works even if retval is NULL */ retval = NULL; destroy_seq_args(sarg); sarg = NULL; } /* while (1) (processing boulder io records) ... End of the primary working loop */ /* To avoid being distracted when looking for leaks: */ if (global_pa->thermodynamic_alignment == 1) destroy_thal_structures(); p3_destroy_global_settings(global_pa); global_pa = NULL; destroy_seq_args(sarg); destroy_pr_append_str_data(&nonfatal_parse_err); destroy_pr_append_str_data(&fatal_parse_err); destroy_pr_append_str_data(&warnings); destroy_dpal_thal_arg_holder(); if (thermodynamic_params_path) free(thermodynamic_params_path); /* If it could not read input complain and die */ if (0 == input_found) { print_usage(); exit(-3); } return 0; }
static void format_oligos(FILE *f, const p3_global_settings *pa, const seq_args *sa, const p3retval *retval, const char* pr_release, const pr_append_str *combined_retval_err, int explain_flag) { char *warning; int print_lib_sim = lib_sim_specified(pa); int i; int print_primers = 0; primer_rec *h = NULL; pair_array_t *best_pairs; primer_rec *p; int rest_count = 0; PR_ASSERT(NULL != f); PR_ASSERT(NULL != pa); PR_ASSERT(NULL != sa); best_pairs = NULL; if (!pr_is_empty(combined_retval_err)) { format_error(f, sa->sequence_name, pr_append_str_chars(combined_retval_err)); return; } if (NULL != sa->sequence_name) fprintf(f, "PRIMER PICKING RESULTS FOR %s\n\n", sa->sequence_name); if (pa->pick_left_primer || pa->pick_right_primer) { if (pa->p_args.repeat_lib != NULL) fprintf(f, "Using mispriming library %s\n", pa->p_args.repeat_lib->repeat_file); else fprintf(f, "No mispriming library specified\n"); } if (pa->pick_internal_oligo) { if (pa->o_args.repeat_lib != NULL) fprintf(f, "Using internal probe mishyb library %s\n", pa->o_args.repeat_lib->repeat_file); else fprintf(f, "No internal probe mishyb library specified\n"); } fprintf(f, "Using %d-based sequence positions\n", pa->first_base_index); if (pa->pick_left_primer) { if (retval->fwd.num_elem == 0) { fprintf(f, "NO LEFT PRIMER FOUND\n\n"); } else { print_primers = 1; } } if (pa->pick_internal_oligo) { if (retval->intl.num_elem == 0) { fprintf(f, "NO INTERNAL PROBE FOUND\n\n"); } else { print_primers = 1; } } if (pa->pick_right_primer) { if (retval->rev.num_elem == 0) { fprintf(f, "NO RIGHT PRIMER FOUND\n\n"); } else { print_primers = 1; } } if ((warning = p3_get_rv_and_gs_warnings(retval, pa)) != NULL) { fprintf(f, "\nWARNING: %s\n", warning); free(warning); } if ((pa->primer_task != pick_primer_list ) && (pa->primer_task != pick_sequencing_primers)) { if (print_primers == 1) { print_oligo_header(f, "OLIGO", print_lib_sim, pa->thermodynamic_alignment, sa->tar2.genotyping); } /* Print out the first line with the best primers */ if ((pa->pick_left_primer) && (&retval->fwd != NULL ) && (retval->fwd.num_elem > 0)) { if(pa->modify_left_primer==1) { print_oligo_Z(f, TITLE_MOD_LEFT, sa, retval->fwd.oligo, OT_LEFT, pa, pa->p_args.repeat_lib, print_lib_sim); } else { print_oligo_Z(f, TITLE_LEFT, sa, retval->fwd.oligo, OT_LEFT, pa, pa->p_args.repeat_lib, print_lib_sim); } h = retval->fwd.oligo; rest_count = 1; } if ((pa->pick_internal_oligo) && (&retval->intl != NULL ) && (retval->intl.num_elem > 0)) { if(pa->modify_internal_oligo==1) { if((retval->intl.oligo)->oligo_dir==0) { print_oligo_Z(f, TITLE_MOD_INTL_FW, sa, retval->intl.oligo, OT_INTL, pa, pa->p_args.repeat_lib, print_lib_sim); } else if((retval->intl.oligo)->oligo_dir==1) { print_oligo_Z(f, TITLE_MOD_INTL_RV, sa, retval->intl.oligo, OT_INTL, pa, pa->p_args.repeat_lib, print_lib_sim); } } else { if((retval->intl.oligo)->oligo_dir==0) { print_oligo_Z(f, TITLE_INTL_FW, sa, retval->intl.oligo, OT_INTL, pa, pa->p_args.repeat_lib, print_lib_sim); } else if((retval->intl.oligo)->oligo_dir==1) { print_oligo_Z(f, TITLE_INTL_RV, sa, retval->intl.oligo, OT_INTL, pa, pa->p_args.repeat_lib, print_lib_sim); } } h = retval->intl.oligo; rest_count = 1; } if ((pa->pick_right_primer) && (&retval->rev != NULL ) && (retval->rev.num_elem > 0)) { if(pa->modify_right_primer==1) { print_oligo_Z(f, TITLE_MOD_RIGHT, sa, retval->rev.oligo, OT_RIGHT, pa, pa->p_args.repeat_lib, print_lib_sim); } else { print_oligo_Z(f, TITLE_RIGHT, sa, retval->rev.oligo, OT_RIGHT, pa, pa->p_args.repeat_lib, print_lib_sim); } h = retval->rev.oligo; rest_count = 1; } } if(print_primers == 1) { fprintf(f, "SEQUENCE SIZE: %ld\n", (long int) strlen(sa->sequence)); fprintf(f, "INCLUDED REGION SIZE: %d\n\n", sa->incl_l); if(sa->tar2.genotyping==0) { print_pair_array(f, "TARGETS", sa->tar2.count, sa->tar2.pairs, pa, sa); } else if(sa->tar2.genotyping==1) { fprintf(f,"TARGET VARIANT * (position,size):"); if(sa->tar2.char_count==sa->tar2.VAR_sequence_number) { fprintf(f," %d,%d",sa->tar2.VAR_start[0],sa->tar2.char_num[sa->tar2.VAR_sequence_number]-1); } else { fprintf(f," %d,%d",sa->tar2.VAR_start[0],sa->tar2.char_num[sa->tar2.VAR_sequence_number]); } fprintf(f,"\n\n"); } print_pair_array(f, "EXCLUDED REGIONS", sa->excl2.count, sa->excl2.pairs, pa, sa); print_pair_array(f, "INTERNAL PROBE EXCLUDED REGIONS", sa->excl_internal2.count, sa->excl_internal2.pairs, pa, sa); print_2_pair_array(f, "PAIR_OK_REGIONS", sa->ok_regions.count, sa->ok_regions.left_pairs, sa->ok_regions.right_pairs, pa, sa); } if (pa->primer_task != pick_primer_list ) { if(pa->pick_internal_oligo==1) { if(print_seq(f,pa,sa,retval,retval->intl.oligo,best_pairs,0)) exit(-2); } else if(pa->pick_left_primer==1) { if(print_seq(f,pa,sa,retval,retval->fwd.oligo,best_pairs,0)) exit(-2); } else if(pa->pick_right_primer==1) { if(print_seq(f,pa,sa,retval,retval->rev.oligo,best_pairs,0)) exit(-2); } else if (print_seq(f, pa, sa, retval, h, best_pairs, 0)) exit(-2); /* ENOMEM */ } fprintf(f, "\n"); /* Print out the other primers */ if ((pa->pick_left_primer) && (&retval->fwd != NULL ) && (retval->fwd.num_elem > rest_count)) { int n = retval->fwd.num_elem; h = retval->fwd.oligo; if (rest_count == 1) { fprintf(f, "ADDITIONAL OLIGOS\n"); } fprintf(f, " "); print_oligo_header(f, "", print_lib_sim, pa->thermodynamic_alignment, sa->tar2.genotyping); for (i = rest_count; i < pa->num_return; i++) { if(i > n-1) break; p = h + i; fprintf(f, "%2d ", i + 1 - rest_count); if(pa->modify_left_primer==1) { print_oligo_Z(f, TITLE_MOD_LEFT, sa, p, OT_LEFT, pa, pa->p_args.repeat_lib, print_lib_sim); } else { print_oligo_Z(f, TITLE_LEFT, sa, p, OT_LEFT, pa, pa->p_args.repeat_lib, print_lib_sim); } } if (rest_count == 0) { fprintf(f, "\n "); } } if ((pa->pick_internal_oligo) && (&retval->intl != NULL ) && (retval->intl.num_elem > rest_count)) { int n = retval->intl.num_elem; h = retval->intl.oligo; if (rest_count == 1) { fprintf(f, "ADDITIONAL OLIGOS\n"); } fprintf(f, " "); print_oligo_header(f, "", print_lib_sim, pa->thermodynamic_alignment, sa->tar2.genotyping); for (i = rest_count; i < pa->num_return; i++) { if(i > n-1) break; p = h + i; fprintf(f, "%2d ", i + 1 - rest_count); if(pa->modify_internal_oligo==1) { if(p->oligo_dir==0) { print_oligo_Z(f, TITLE_MOD_INTL_FW, sa, p, OT_INTL, pa, pa->p_args.repeat_lib, print_lib_sim); } else if(p->oligo_dir==1) { print_oligo_Z(f, TITLE_MOD_INTL_RV, sa, p, OT_INTL, pa, pa->p_args.repeat_lib, print_lib_sim); } } else { if(p->oligo_dir==0) { print_oligo_Z(f, TITLE_INTL_FW, sa, p, OT_INTL, pa, pa->p_args.repeat_lib, print_lib_sim); } else if(p->oligo_dir==1) { print_oligo_Z(f, TITLE_INTL_RV, sa, p, OT_INTL, pa, pa->p_args.repeat_lib, print_lib_sim); } } } if (rest_count == 0) { fprintf(f, "\n "); } } if ((pa->pick_right_primer) && (&retval->rev != NULL ) && (retval->rev.num_elem > rest_count)) { int n = retval->rev.num_elem; h = retval->rev.oligo; if (rest_count == 1) { fprintf(f, "ADDITIONAL OLIGOS\n"); } fprintf(f, " "); print_oligo_header(f, "", print_lib_sim, pa->thermodynamic_alignment, sa->tar2.genotyping); for (i = rest_count; i < pa->num_return; i++) { if(i > n-1) break; p = h + i; fprintf(f, "%2d ", i + 1 - rest_count); if(pa->modify_right_primer==1) { print_oligo_Z(f, TITLE_MOD_RIGHT, sa, p, OT_RIGHT, pa, pa->p_args.repeat_lib, print_lib_sim); } else { print_oligo_Z(f, TITLE_RIGHT, sa, p, OT_RIGHT, pa, pa->p_args.repeat_lib, print_lib_sim); } } } if (explain_flag) print_explain(f, pa, sa, retval, print_lib_sim, pr_release); fprintf(f, "\n\n"); if (fflush(f) == EOF) { perror("fflush(f) failed"); exit(-1); } }