void vcf_misc_hdr_add_cmd(bcf_hdr_t *hdr, const char *cmdline, const char *cwd) { char keystr[8], timestr[100]; time_t tnow; time(&tnow); strftime(timestr, sizeof(timestr), "%Y%m%d-%H:%M:%S", localtime(&tnow)); StrBuf sbuf; strbuf_alloc(&sbuf, 1024); strbuf_sprintf(&sbuf, "##mccortex_%s=<prev=\"NULL\",cmd=\"%s\",cwd=\"%s\"," "datetime=\"%s\",version="CTX_VERSION">\n", hex_rand_str(keystr, sizeof(keystr)), cmdline, cwd, timestr); bcf_hdr_append(hdr, sbuf.b); strbuf_dealloc(&sbuf); }
static bcf_hdr_t* make_vcf_hdr(cJSON *json, const char *in_path, bool is_breakpoint, size_t kmer_size, char const*const* ref_paths, size_t nref_paths, read_t *chroms, size_t nchroms) { ctx_assert(json != NULL); StrBuf hdrbuf; strbuf_alloc(&hdrbuf, 1024); char datestr[9]; time_t date = time(NULL); strftime(datestr, 9, "%Y%m%d", localtime(&date)); strbuf_append_str(&hdrbuf, "##fileformat=VCFv4.2\n##fileDate="); strbuf_append_str(&hdrbuf, datestr); strbuf_append_str(&hdrbuf, "\n"); // Print commands used to generate header cJSON *commands = json_hdr_get(json, "commands", cJSON_Array, in_path); cJSON *command = commands->child; // Print this command char keystr[8]; char *prevstr = NULL; size_t i; if(command) { cJSON *key = json_hdr_get(command, "key", cJSON_String, in_path); prevstr = key->valuestring; } // Print command entry for this command strbuf_append_str(&hdrbuf, "##mccortex_"); strbuf_append_str(&hdrbuf, hex_rand_str(keystr, sizeof(keystr))); strbuf_append_str(&hdrbuf, "=<prev=\""); strbuf_append_str(&hdrbuf, prevstr ? prevstr : "NULL"); strbuf_append_str(&hdrbuf, "\",cmd=\""); strbuf_append_str(&hdrbuf, cmd_get_cmdline()); strbuf_append_str(&hdrbuf, "\",cwd=\""); strbuf_append_str(&hdrbuf, cmd_get_cwd()); strbuf_append_str(&hdrbuf, "\",version="CTX_VERSION">\n"); // Print previous commands vcf_hdrtxt_append_commands(command, &hdrbuf, in_path); // Print field definitions if(is_breakpoint) strbuf_append_str(&hdrbuf, "##INFO=<ID=BRKPNT,Number=1,Type=String,Description=\"Breakpoint call\">\n"); else strbuf_append_str(&hdrbuf, "##INFO=<ID=BUBBLE,Number=1,Type=String,Description=\"Bubble call\">\n"); strbuf_sprintf(&hdrbuf, "##INFO=<ID=K%zu,Number=0,Type=Flag,Description=\"Found at k=%zu\">\n", kmer_size, kmer_size); strbuf_append_str(&hdrbuf, "##FORMAT=<ID=GT,Number=1,Type=String,Description=\"Genotype\">\n"); strbuf_append_str(&hdrbuf, "##FILTER=<ID=PASS,Description=\"All filters passed\">\n"); // Print reference paths strbuf_append_str(&hdrbuf, "##reference="); strbuf_append_str(&hdrbuf, ref_paths[0]); for(i = 1; i < nref_paths; i++) { strbuf_append_char(&hdrbuf, ','); strbuf_append_str(&hdrbuf, ref_paths[i]); } strbuf_append_str(&hdrbuf, "\n"); // Print contigs lengths for(i = 0; i < nchroms; i++) { strbuf_sprintf(&hdrbuf, "##contig=<ID=%s,length=%zu>\n", chroms[i].name.b, chroms[i].seq.end); } // Print VCF column header strbuf_append_str(&hdrbuf, "#CHROM\tPOS\tID\tREF\tALT\tQUAL\tFILTER\tINFO\tFORMAT"); if(is_breakpoint) { // Print a column for each sample cJSON *graph_json = json_hdr_get(json, "graph", cJSON_Object, in_path); cJSON *colours_json = json_hdr_get(graph_json, "colours", cJSON_Array, in_path); cJSON *colour_json = colours_json->child; if(colour_json == NULL) die("Missing colours"); for(; colour_json; colour_json = colour_json->next) { if(!json_hdr_colour_is_ref(colour_json)) { cJSON *sample_json = json_hdr_get(colour_json, "sample", cJSON_String, in_path); strbuf_append_str(&hdrbuf, "\t"); strbuf_append_str(&hdrbuf, sample_json->valuestring); } } } strbuf_append_char(&hdrbuf, '\n'); bcf_hdr_t *hdr = bcf_hdr_init("w"); if(bcf_hdr_parse(hdr, hdrbuf.b) != 0) die("Cannot construct VCF header"); strbuf_dealloc(&hdrbuf); return hdr; }
static void print_vcf_header(cJSON *json, bool is_breakpoint, FILE *fout) { ctx_assert(json != NULL); char datestr[9]; time_t date = time(NULL); strftime(datestr, 9, "%Y%m%d", localtime(&date)); fprintf(fout, "##fileformat=VCFv4.1\n##fileDate=%s\n", datestr); // Print commands used to generate header cJSON *commands = json_hdr_get(json, "commands", cJSON_Array, input_path); cJSON *command = commands->child; // Print this command char keystr[8]; char *prevstr = NULL; size_t i; if(command) { cJSON *key = json_hdr_get(command, "key", cJSON_String, input_path); prevstr = key->valuestring; } // Print command entry for this command fprintf(fout, "##mccortex_%s=<prev=\"%s\",cmd=\"%s\",cwd=\"%s\",version="CTX_VERSION">\n", hex_rand_str(keystr, sizeof(keystr)), prevstr ? prevstr : "NULL", cmd_get_cmdline(), cmd_get_cwd()); // Print previous commands for(; command != NULL; command = command->next) { cJSON *key = json_hdr_get(command, "key", cJSON_String, input_path); cJSON *cmd = json_hdr_get(command, "cmd", cJSON_Array, input_path); cJSON *cwd = json_hdr_get(command, "cwd", cJSON_String, input_path); cJSON *prev = json_hdr_get(command, "prev", cJSON_Array, input_path); cJSON *ver = json_hdr_try(command, "mccortex",cJSON_String, input_path); prev = prev->child; // result could be NULL if(prev && prev->type != cJSON_String) die("Invalid 'prev' field"); fprintf(fout, "##mccortex_%s=<prev=\"%s", key->valuestring, prev ? prev->valuestring : "NULL"); if(prev) { while((prev = prev->next) != NULL) fprintf(fout, ";%s", prev->valuestring); } fprintf(fout, "\",cmd=\""); for(i = 0, cmd = cmd->child; cmd; cmd = cmd->next, i++) { if(i > 0) fputc(' ', fout); fputs(cmd->valuestring, fout); } fprintf(fout, "\",cwd=\"%s\"", cwd->valuestring); if(ver) { fprintf(fout, ",version=\"%s\"", ver->valuestring); } fprintf(fout, ">\n"); } // Print field definitions if(is_breakpoint) fprintf(fout, "##INFO=<ID=BRKPNT,Number=1,Type=String,Description=\"Breakpoint call\">\n"); else fprintf(fout, "##INFO=<ID=BUBBLE,Number=1,Type=String,Description=\"Bubble call\">\n"); fprintf(fout, "##INFO=<ID=K%zu,Number=0,Type=Flag,Description=\"Found at k=%zu\">\n", kmer_size, kmer_size); fprintf(fout, "##FORMAT=<ID=GT,Number=1,Type=String,Description=\"Genotype\">\n"); fprintf(fout, "##FILTER=<ID=PASS,Description=\"All filters passed\">\n"); // Print reference paths fprintf(fout, "##reference=%s", ref_paths[0]); for(i = 1; i < num_ref_paths; i++) printf(",%s", ref_paths[i]); fprintf(fout, "\n"); // Print contigs lengths for(i = 0; i < chroms.len; i++) { fprintf(fout, "##contig=<ID=%s,length=%zu>\n", chroms.b[i].name.b, chroms.b[i].seq.end); } // Print VCF column header fputs("#CHROM\tPOS\tID\tREF\tALT\tQUAL\tFILTER\tINFO\tFORMAT", fout); if(is_breakpoint) { // Print a column for each sample cJSON *graph_json = json_hdr_get(json, "graph", cJSON_Object, input_path); cJSON *colours_json = json_hdr_get(graph_json, "colours", cJSON_Array, input_path); cJSON *colour_json = colours_json->child; if(colour_json == NULL) die("Missing colours"); for(; colour_json; colour_json = colour_json->next) { if(!json_hdr_colour_is_ref(colour_json)) { cJSON *sample_json = json_hdr_get(colour_json, "sample", cJSON_String, input_path); fputc('\t', fout); fputs(sample_json->valuestring, fout); } } } fputc('\n', fout); }