Exemple #1
0
// Set the initial state
static state_t* init(parsed_opts_t* opts)
{
    state_t* retval = calloc(sizeof(state_t), 1);
    if (!retval) {
        fprintf(pysamerr, "Out of memory");
        return NULL;
    }

    retval->merged_input_file = sam_open(opts->merged_input_name, "rb");
    if (!retval->merged_input_file) {
        fprintf(pysamerr, "Could not open input file (%s)\n", opts->merged_input_name);
        free(retval);
        return NULL;
    }
    retval->merged_input_header = sam_hdr_read(retval->merged_input_file);

    if (opts->unaccounted_name) {
        if (opts->unaccounted_header_name) {
            samFile* hdr_load = sam_open(opts->unaccounted_header_name, "r");
            if (!hdr_load) {
                fprintf(pysamerr, "Could not open unaccounted header file (%s)\n", opts->unaccounted_header_name);
                cleanup_state(retval);
                return NULL;
            }
            retval->unaccounted_header = sam_hdr_read(hdr_load);
            sam_close(hdr_load);
        } else {
            retval->unaccounted_header = bam_hdr_dup(retval->merged_input_header);
        }

        retval->unaccounted_file = sam_open(opts->unaccounted_name, "wb");
        if (retval->unaccounted_file == NULL) {
            fprintf(pysamerr, "Could not open unaccounted output file: %s\n", opts->unaccounted_name);
            cleanup_state(retval);
            return NULL;
        }
    }

    // Open output files for RGs
    if (!count_RG(retval->merged_input_header, &retval->output_count, &retval->rg_id)) return NULL;
    if (opts->verbose) fprintf(pysamerr, "@RG's found %zu\n",retval->output_count);

    retval->rg_output_file = (samFile**)calloc(retval->output_count, sizeof(samFile*));
    retval->rg_output_header = (bam_hdr_t**)calloc(retval->output_count, sizeof(bam_hdr_t*));
    retval->rg_hash = kh_init_c2i();
    if (!retval->rg_output_file || !retval->rg_output_header) {
        fprintf(pysamerr, "Could not allocate memory for output file array. Out of memory?");
        cleanup_state(retval);
        return NULL;
    }

    char* dirsep = strrchr(opts->merged_input_name, '/');
    char* input_base_name = strdup(dirsep? dirsep+1 : opts->merged_input_name);
    if (!input_base_name) {
        fprintf(pysamerr, "Out of memory\n");
        cleanup_state(retval);
        return NULL;
    }
    char* extension = strrchr(input_base_name, '.');
    if (extension) *extension = '\0';

    size_t i;
    for (i = 0; i < retval->output_count; i++) {
        char* output_filename = NULL;

        if ( ( output_filename = expand_format_string(opts->output_format_string, input_base_name, retval->rg_id[i], i) ) == NULL) {
            fprintf(pysamerr, "Error expanding output filename format string.\r\n");
            cleanup_state(retval);
            free(input_base_name);
            return NULL;
        }

        retval->rg_output_file[i] = sam_open(output_filename, "wb");
        if (retval->rg_output_file[i] == NULL) {
            fprintf(pysamerr, "Could not open output file: %s\r\n", output_filename);
            cleanup_state(retval);
            free(input_base_name);
            return NULL;
        }

        // Record index in hash
        int ret;
        khiter_t iter = kh_put_c2i(retval->rg_hash, retval->rg_id[i], &ret);
        kh_val(retval->rg_hash,iter) = i;

        // Set and edit header
        retval->rg_output_header[i] = bam_hdr_dup(retval->merged_input_header);
        if ( !filter_header_rg(retval->rg_output_header[i], retval->rg_id[i]) ) {
            fprintf(pysamerr, "Could not rewrite header for file: %s\r\n", output_filename);
            cleanup_state(retval);
            free(output_filename);
            free(input_base_name);
            return NULL;
        }
        free(output_filename);
    }

    free(input_base_name);

    return retval;
}
int main(int argc, char**argv)
{
    // test state
    const int NUM_TESTS = 2;
    int verbose = 0;
    int success = 0;
    int failure = 0;

    int getopt_char;
    while ((getopt_char = getopt(argc, argv, "v")) != -1) {
        switch (getopt_char) {
            case 'v':
                ++verbose;
                break;
            default:
                printf(
                       "usage: test_filter_header_rg [-v]\n\n"
                       " -v verbose output\n"
                       );
                break;
        }
    }


    // Setup pysamerr redirect
    kstring_t res = { 0, 0, NULL };
    FILE* orig_pysamerr = fdopen(dup(STDERR_FILENO), "a"); // Save pysamerr
    char* tempfname = (optind < argc)? argv[optind] : "test_count_rg.tmp";
    FILE* check = NULL;

    // setup
    if (verbose) printf("BEGIN test 1\n");  // test eliminating a tag that isn't there
    bam_hdr_t* hdr1;
    const char* id_to_keep_1 = "1#2.3";
    setup_test_1(&hdr1);
    if (verbose > 1) {
        printf("hdr1\n");
        dump_hdr(hdr1);
    }
    if (verbose) printf("RUN test 1\n");

    // test
    xfreopen(tempfname, "w", pysamerr); // Redirect pysamerr to pipe
    bool result_1 = filter_header_rg(hdr1, id_to_keep_1);
    fclose(pysamerr);

    if (verbose) printf("END RUN test 1\n");
    if (verbose > 1) {
        printf("hdr1\n");
        dump_hdr(hdr1);
    }

    // check result
    res.l = 0;
    check = fopen(tempfname, "r");
    if ( result_1
        && check_test_1(hdr1)
        && kgetline(&res, (kgets_func *)fgets, check) < 0
        && (feof(check) || res.l == 0)) {
        ++success;
    } else {
        ++failure;
        if (verbose) printf("FAIL test 1\n");
    }
    fclose(check);

    // teardown
    bam_hdr_destroy(hdr1);
    if (verbose) printf("END test 1\n");

    if (verbose) printf("BEGIN test 2\n");  // test eliminating a tag that is there
    bam_hdr_t* hdr2;
    const char* id_to_keep_2 = "fish";
    setup_test_2(&hdr2);
    if (verbose > 1) {
        printf("hdr2\n");
        dump_hdr(hdr2);
    }
    if (verbose) printf("RUN test 2\n");

    // test
    xfreopen(tempfname, "w", pysamerr); // Redirect pysamerr to pipe
    bool result_2 = filter_header_rg(hdr2, id_to_keep_2);
    fclose(pysamerr);

    if (verbose) printf("END RUN test 2\n");
    if (verbose > 1) {
        printf("hdr2\n");
        dump_hdr(hdr2);
    }

    // check result
    res.l = 0;
    check = fopen(tempfname, "r");
    if ( result_2
        && check_test_2(hdr2)
        && kgetline(&res, (kgets_func *)fgets, check) < 0
        && (feof(check) || res.l == 0)) {
        ++success;
    } else {
        ++failure;
        if (verbose) printf("FAIL test 2\n");
    }
    fclose(check);

    // teardown
    bam_hdr_destroy(hdr2);
    if (verbose) printf("END test 2\n");


    // Cleanup
    free(res.s);
    remove(tempfname);
    if (failure > 0)
        fprintf(orig_pysamerr, "%d failures %d successes\n", failure, success);
    fclose(orig_pysamerr);

    return (success == NUM_TESTS)? EXIT_SUCCESS : EXIT_FAILURE;
}