static bool parse_args(int argc, char** argv, parsed_opts_t** opts) { *opts = NULL; int n; if (argc == 1) { usage(stdout); return true; } parsed_opts_t* retval = calloc(1, sizeof(parsed_opts_t)); if (! retval ) { fprintf(stderr, "[%s] Out of memory allocating parsed_opts_t\n", __func__); return false; } // Set defaults retval->mode = overwrite_all; sam_global_args_init(&retval->ga); static const struct option lopts[] = { SAM_OPT_GLOBAL_OPTIONS(0, 0, 'O', 0, 0), { NULL, 0, NULL, 0 } }; kstring_t rg_line = {0,0,NULL}; while ((n = getopt_long(argc, argv, "r:R:m:o:O:l:h", lopts, NULL)) >= 0) { switch (n) { case 'r': // Are we adding to existing rg line? if (ks_len(&rg_line) == 0) { if (strlen(optarg)<3 || (optarg[0] != '@' && optarg[1] != 'R' && optarg[2] != 'G')) { kputs("@RG\t", &rg_line); } } else { kputs("\t", &rg_line); } kputs(optarg, &rg_line); break; case 'R': retval->rg_id = strdup(optarg); break; case 'm': { if (strcmp(optarg, "overwrite_all") == 0) { retval->mode = overwrite_all; } else if (strcmp(optarg, "orphan_only") == 0) { retval->mode = orphan_only; } else { usage(stderr); return false; } break; } case 'o': retval->output_name = strdup(optarg); break; case 'h': usage(stdout); free(retval); return true; case '?': usage(stderr); free(retval); return false; case 'O': default: if (parse_sam_global_opt(n, optarg, lopts, &retval->ga) == 0) break; usage(stderr); free(retval); return false; } } retval->rg_line = ks_release(&rg_line); if (argc-optind < 1) { fprintf(stderr, "You must specify an input file.\n"); usage(stderr); cleanup_opts(retval); return false; } if (retval->rg_id && retval->rg_line) { fprintf(stderr, "The options -r and -R are mutually exclusive.\n"); cleanup_opts(retval); return false; } if (retval->rg_line) { char* tmp = basic_unescape(retval->rg_line); if ((retval->rg_id = get_rg_id(tmp)) == NULL) { fprintf(stderr, "[%s] The supplied RG line lacks an ID tag.\n", __func__); free(tmp); cleanup_opts(retval); return false; } retval->rg_line = tmp; } retval->input_name = strdup(argv[optind+0]); *opts = retval; return true; }
int bam_mpileup(int argc, char *argv[]) { int c; const char *file_list = NULL; char **fn = NULL; int nfiles = 0, use_orphan = 0; mplp_conf_t mplp; memset(&mplp, 0, sizeof(mplp_conf_t)); mplp.min_baseQ = 13; mplp.capQ_thres = 0; mplp.max_depth = 250; mplp.max_indel_depth = 250; mplp.openQ = 40; mplp.extQ = 20; mplp.tandemQ = 100; mplp.min_frac = 0.002; mplp.min_support = 1; mplp.flag = MPLP_NO_ORPHAN | MPLP_REALN | MPLP_SMART_OVERLAPS; mplp.argc = argc; mplp.argv = argv; mplp.rflag_filter = BAM_FUNMAP | BAM_FSECONDARY | BAM_FQCFAIL | BAM_FDUP; mplp.output_fname = NULL; sam_global_args_init(&mplp.ga); static const struct option lopts[] = { SAM_OPT_GLOBAL_OPTIONS('-', 0, '-', '-', 0), {"rf", required_argument, NULL, 1}, // require flag {"ff", required_argument, NULL, 2}, // filter flag {"incl-flags", required_argument, NULL, 1}, {"excl-flags", required_argument, NULL, 2}, {"output", required_argument, NULL, 3}, {"open-prob", required_argument, NULL, 4}, {"illumina1.3+", no_argument, NULL, '6'}, {"count-orphans", no_argument, NULL, 'A'}, {"bam-list", required_argument, NULL, 'b'}, {"no-BAQ", no_argument, NULL, 'B'}, {"no-baq", no_argument, NULL, 'B'}, {"adjust-MQ", required_argument, NULL, 'C'}, {"adjust-mq", required_argument, NULL, 'C'}, {"max-depth", required_argument, NULL, 'd'}, {"redo-BAQ", no_argument, NULL, 'E'}, {"redo-baq", no_argument, NULL, 'E'}, {"fasta-ref", required_argument, NULL, 'f'}, {"exclude-RG", required_argument, NULL, 'G'}, {"exclude-rg", required_argument, NULL, 'G'}, {"positions", required_argument, NULL, 'l'}, {"region", required_argument, NULL, 'r'}, {"ignore-RG", no_argument, NULL, 'R'}, {"ignore-rg", no_argument, NULL, 'R'}, {"min-MQ", required_argument, NULL, 'q'}, {"min-mq", required_argument, NULL, 'q'}, {"min-BQ", required_argument, NULL, 'Q'}, {"min-bq", required_argument, NULL, 'Q'}, {"ignore-overlaps", no_argument, NULL, 'x'}, {"BCF", no_argument, NULL, 'g'}, {"bcf", no_argument, NULL, 'g'}, {"VCF", no_argument, NULL, 'v'}, {"vcf", no_argument, NULL, 'v'}, {"output-BP", no_argument, NULL, 'O'}, {"output-bp", no_argument, NULL, 'O'}, {"output-MQ", no_argument, NULL, 's'}, {"output-mq", no_argument, NULL, 's'}, {"output-tags", required_argument, NULL, 't'}, {"uncompressed", no_argument, NULL, 'u'}, {"ext-prob", required_argument, NULL, 'e'}, {"gap-frac", required_argument, NULL, 'F'}, {"tandem-qual", required_argument, NULL, 'h'}, {"skip-indels", no_argument, NULL, 'I'}, {"max-idepth", required_argument, NULL, 'L'}, {"min-ireads ", required_argument, NULL, 'm'}, {"per-sample-mF", no_argument, NULL, 'p'}, {"per-sample-mf", no_argument, NULL, 'p'}, {"platforms", required_argument, NULL, 'P'}, {NULL, 0, NULL, 0} }; while ((c = getopt_long(argc, argv, "Agf:r:l:q:Q:uRC:BDSd:L:b:P:po:e:h:Im:F:EG:6OsVvxt:",lopts,NULL)) >= 0) { switch (c) { case 'x': mplp.flag &= ~MPLP_SMART_OVERLAPS; break; case 1 : mplp.rflag_require = bam_str2flag(optarg); if ( mplp.rflag_require<0 ) { fprintf(pysam_stderr,"Could not parse --rf %s\n", optarg); return 1; } break; case 2 : mplp.rflag_filter = bam_str2flag(optarg); if ( mplp.rflag_filter<0 ) { fprintf(pysam_stderr,"Could not parse --ff %s\n", optarg); return 1; } break; case 3 : mplp.output_fname = optarg; break; case 4 : mplp.openQ = atoi(optarg); break; case 'f': mplp.fai = fai_load(optarg); if (mplp.fai == NULL) return 1; mplp.fai_fname = optarg; break; case 'd': mplp.max_depth = atoi(optarg); break; case 'r': mplp.reg = strdup(optarg); break; case 'l': // In the original version the whole BAM was streamed which is inefficient // with few BED intervals and big BAMs. Todo: devise a heuristic to determine // best strategy, that is streaming or jumping. mplp.bed = bed_read(optarg); if (!mplp.bed) { print_error_errno("mpileup", "Could not read file \"%s\"", optarg); return 1; } break; case 'P': mplp.pl_list = strdup(optarg); break; case 'p': mplp.flag |= MPLP_PER_SAMPLE; break; case 'g': mplp.flag |= MPLP_BCF; break; case 'v': mplp.flag |= MPLP_BCF | MPLP_VCF; break; case 'u': mplp.flag |= MPLP_NO_COMP | MPLP_BCF; break; case 'B': mplp.flag &= ~MPLP_REALN; break; case 'D': mplp.fmt_flag |= B2B_FMT_DP; fprintf(pysam_stderr, "[warning] samtools mpileup option `-D` is functional, but deprecated. Please switch to `-t DP` in future.\n"); break; case 'S': mplp.fmt_flag |= B2B_FMT_SP; fprintf(pysam_stderr, "[warning] samtools mpileup option `-S` is functional, but deprecated. Please switch to `-t SP` in future.\n"); break; case 'V': mplp.fmt_flag |= B2B_FMT_DV; fprintf(pysam_stderr, "[warning] samtools mpileup option `-V` is functional, but deprecated. Please switch to `-t DV` in future.\n"); break; case 'I': mplp.flag |= MPLP_NO_INDEL; break; case 'E': mplp.flag |= MPLP_REDO_BAQ; break; case '6': mplp.flag |= MPLP_ILLUMINA13; break; case 'R': mplp.flag |= MPLP_IGNORE_RG; break; case 's': mplp.flag |= MPLP_PRINT_MAPQ; break; case 'O': mplp.flag |= MPLP_PRINT_POS; break; case 'C': mplp.capQ_thres = atoi(optarg); break; case 'q': mplp.min_mq = atoi(optarg); break; case 'Q': mplp.min_baseQ = atoi(optarg); break; case 'b': file_list = optarg; break; case 'o': { char *end; long value = strtol(optarg, &end, 10); // Distinguish between -o INT and -o FILE (a bit of a hack!) if (*end == '\0') mplp.openQ = value; else mplp.output_fname = optarg; } break; case 'e': mplp.extQ = atoi(optarg); break; case 'h': mplp.tandemQ = atoi(optarg); break; case 'A': use_orphan = 1; break; case 'F': mplp.min_frac = atof(optarg); break; case 'm': mplp.min_support = atoi(optarg); break; case 'L': mplp.max_indel_depth = atoi(optarg); break; case 'G': { FILE *fp_rg; char buf[1024]; mplp.rghash = khash_str2int_init(); if ((fp_rg = fopen(optarg, "r")) == NULL) fprintf(pysam_stderr, "(%s) Fail to open file %s. Continue anyway.\n", __func__, optarg); while (!feof(fp_rg) && fscanf(fp_rg, "%s", buf) > 0) // this is not a good style, but forgive me... khash_str2int_inc(mplp.rghash, strdup(buf)); fclose(fp_rg); } break; case 't': mplp.fmt_flag |= parse_format_flag(optarg); break; default: if (parse_sam_global_opt(c, optarg, lopts, &mplp.ga) == 0) break; /* else fall-through */ case '?': print_usage(pysam_stderr, &mplp); return 1; } } if (!mplp.fai && mplp.ga.reference) { mplp.fai_fname = mplp.ga.reference; mplp.fai = fai_load(mplp.fai_fname); if (mplp.fai == NULL) return 1; } if ( !(mplp.flag&MPLP_REALN) && mplp.flag&MPLP_REDO_BAQ ) { fprintf(pysam_stderr,"Error: The -B option cannot be combined with -E\n"); return 1; } if (use_orphan) mplp.flag &= ~MPLP_NO_ORPHAN; if (argc == 1) { print_usage(pysam_stderr, &mplp); return 1; } int ret; if (file_list) { if ( read_file_list(file_list,&nfiles,&fn) ) return 1; ret = mpileup(&mplp,nfiles,fn); for (c=0; c<nfiles; c++) free(fn[c]); free(fn); } else ret = mpileup(&mplp, argc - optind, argv + optind); if (mplp.rghash) khash_str2int_destroy_free(mplp.rghash); free(mplp.reg); free(mplp.pl_list); if (mplp.fai) fai_destroy(mplp.fai); if (mplp.bed) bed_destroy(mplp.bed); return ret; }
// return true if valid static bool parse_opts(int argc, char *argv[], bam2fq_opts_t** opts_out) { // Parse args bam2fq_opts_t* opts = calloc(1, sizeof(bam2fq_opts_t)); opts->has12 = true; opts->filetype = FASTQ; opts->def_qual = 1; int c; sam_global_args_init(&opts->ga); static const struct option lopts[] = { SAM_OPT_GLOBAL_OPTIONS('-', 0, '-', '-', 0), { NULL, 0, NULL, 0 } }; while ((c = getopt_long(argc, argv, "0:1:2:f:F:nOs:tv:", lopts, NULL)) > 0) { switch (c) { case '0': opts->fnr[0] = optarg; break; case '1': opts->fnr[1] = optarg; break; case '2': opts->fnr[2] = optarg; break; case 'f': opts->flag_on |= strtol(optarg, 0, 0); break; case 'F': opts->flag_off |= strtol(optarg, 0, 0); break; case 'n': opts->has12 = false; break; case 'O': opts->use_oq = true; break; case 's': opts->fnse = optarg; break; case 't': opts->copy_tags = true; break; case 'v': opts->def_qual = atoi(optarg); break; case '?': bam2fq_usage(stderr, argv[0]); free(opts); return false; default: if (parse_sam_global_opt(c, optarg, lopts, &opts->ga) != 0) { bam2fq_usage(stderr, argv[0]); free(opts); return false; } break; } } if (opts->fnr[1] || opts->fnr[2]) opts->has12 = false; if (opts->def_qual < 0 || 93 < opts->def_qual) { fprintf(stderr, "Invalid -v default quality %i, allowed range 0 to 93\n", opts->def_qual); bam2fq_usage(stderr, argv[0]); free(opts); return true; } const char* type_str = argv[0]; if (strcasecmp("fastq", type_str) == 0 || strcasecmp("bam2fq", type_str) == 0) { opts->filetype = FASTQ; } else if (strcasecmp("fasta", type_str) == 0) { opts->filetype = FASTA; } else { print_error("bam2fq", "Unrecognised type call \"%s\", this should be impossible... but you managed it!", type_str); bam2fq_usage(stderr, argv[0]); free(opts); return false; } if ((argc - (optind)) == 0) { bam2fq_usage(stdout, argv[0]); free(opts); return false; } if ((argc - (optind)) != 1) { fprintf(stderr, "Too many arguments.\n"); bam2fq_usage(stderr, argv[0]); free(opts); return false; } opts->fn_input = argv[optind]; *opts_out = opts; return true; }
// Takes the command line options and turns them into something we can understand static parsed_opts_t* parse_args(int argc, char** argv) { if (argc == 1) { usage(pysam_stdout); return NULL; } const char* optstring = "vf:u:"; char* delim; static const struct option lopts[] = { SAM_OPT_GLOBAL_OPTIONS('-', 0, 0, 0, 0), { NULL, 0, NULL, 0 } }; parsed_opts_t* retval = calloc(sizeof(parsed_opts_t), 1); if (! retval ) { perror("cannot allocate option parsing memory"); return NULL; } sam_global_args_init(&retval->ga); int opt; while ((opt = getopt_long(argc, argv, optstring, lopts, NULL)) != -1) { switch (opt) { case 'f': retval->output_format_string = strdup(optarg); if (! retval->output_format_string ) { perror("cannot allocate output format string memory"); return NULL; } break; case 'v': retval->verbose = true; break; case 'u': retval->unaccounted_name = strdup(optarg); if (! retval->unaccounted_name ) { perror("cannot allocate string memory"); return NULL; } if ((delim = strchr(retval->unaccounted_name, ':')) != NULL) { *delim = '\0'; retval->unaccounted_header_name = strdup(delim+1); if (! retval->unaccounted_header_name ) { perror("cannot allocate string memory"); return NULL; } } break; default: if (parse_sam_global_opt(opt, optarg, lopts, &retval->ga) == 0) break; /* else fall-through */ case '?': usage(pysam_stdout); free(retval); return NULL; } } if (retval->output_format_string == NULL) retval->output_format_string = strdup("%*_%#.%."); argc -= optind; argv += optind; if (argc != 1) { fprintf(pysam_stderr, "Invalid number of arguments: %d\n", argc); usage(pysam_stderr); free(retval); return NULL; } retval->merged_input_name = strdup(argv[0]); if (! retval->merged_input_name ) { perror("cannot allocate string memory"); return NULL; } return retval; }