コード例 #1
0
static PyObject*
setGlobals(PyObject *self, PyObject *args){
    /* Sets the Primer3 global settings from a Python dictionary containing
    ** key: value pairs that correspond to the documented Primer3
    ** global parameters. Also accepts a mispriming or mishybridization library
    ** organized as `seq_name`:`seq_value` key:value pairs.
    */

    PyObject        *global_args=NULL, *misprime_lib=NULL;
    PyObject        *mishyb_lib=NULL;
    seq_lib         *mp_lib, *mh_lib;


    if (pa != NULL) {
        // Free memory for previous global settings
        p3_destroy_global_settings(pa);
        pa = NULL;
    }

    // Allocate memory for global settings
    if ((pa = p3_create_global_settings()) == NULL) {
        PyErr_SetString(PyExc_IOError, 
                        "Could not allocate memory for p3 globals");
        return NULL;
    }

    if (!PyArg_ParseTuple(args, "O!OO", &PyDict_Type, &global_args,
                          &misprime_lib, &mishyb_lib)) {
        goto err_set_global;
    }


    if ((pdh_setGlobals(pa, global_args)) != 0) {
        goto err_set_global;
    }

    if ((misprime_lib != NULL) && (misprime_lib != Py_None)) {
        if ((mp_lib = pdh_createSeqLib(misprime_lib)) == NULL) {
            goto err_set_global;
        }
        pa->p_args.repeat_lib = mp_lib;
    }
    if ((mishyb_lib != NULL) && (mishyb_lib != Py_None)) {
        if ((mh_lib = pdh_createSeqLib(mishyb_lib))==NULL) {
            goto err_set_global;
        }
        pa->o_args.repeat_lib = mh_lib;
    }

    Py_RETURN_NONE;

err_set_global:
    p3_destroy_global_settings(pa);
    pa = NULL;
    return NULL;
}
コード例 #2
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;
}
コード例 #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;
}