Exemplo n.º 1
0
/* 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);
  }
}
Exemplo n.º 2
0
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);
  }

}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
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;
}
Exemplo n.º 5
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);
    }
}