<commit_before>/**   LICENSE
* Copyright (c) 2014-2018 Genome Research Ltd.
*
* Author: Cancer Genome Project <EMAIL>
*
* This file is part of CaVEMan.
*
* CaVEMan is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation; either version 3 of the License, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*    1. The usage of a range of years within a copyright statement contained within
*    this distribution should be interpreted as being equivalent to a list of years
*    including the first and last year specified and all consecutive years between
*    them. For example, a copyright statement that reads ‘Copyright (c) 2005, 2007-
*    2009, 2011-2012’ should be interpreted as being identical to a statement that
*    reads ‘Copyright (c) 2005, 2007, 2008, 2009, 2011, 2012’ and a copyright
*    statement that reads ‘Copyright (c) 2005-2012’ should be interpreted as being
*    identical to a statement that reads ‘Copyright (c) 2005, 2006, 2007, 2008,
*    2009, 2010, 2011, 2012’."
*
*/

#include <stdio.h>
#include <assert.h>
#include <output.h>
#include <string.h>
#include <bam_access.h>
#include <ignore_reg_access.h>
#include <genotype.h>
#include <stdio.h>
#include <time.h>
#include <dbg.h>

static const char *VCF_VERSION_KEY = "fileformat";
static const char *VCF_VERSION_VALUE = "VCFv4.1";
static const char *VCF_FILEDATE_KEY = "fileDate";
static const char *VCF_REF_SEQ_KEY = "reference";
static const char *VCF_SAMPLE_KEY = "SAMPLE";
static const char *VCF_NORMAL_NAME = "NORMAL";
static const char *VCF_DESCRIPTION_KEY = "Description";
static const char *VCF_ACCESSION_KEY = "Accession";
static const char *VCF_PLATFORM_KEY = "Platform";
static const char *VCF_PROTOCOL_KEY = "Protocol";
static const char *VCF_INDIVIDUAL_KEY = "SampleName";
static const char *VCF_SOURCE_KEY = "Source";
static const char *VCF_TUMOUR_NAME = "TUMOUR";
static const char *VCF_PROCESSLOG_KEY = "vcfProcessLog";
static const char *VCF_INPUTVCF_KEY = "InputVCF";
static const char *VCF_INPUTSOURCE_KEY = "InputVCFSource";
static const char *VCF_INPUT_SOURCE_VALUE = "CaVEMan";
static const char *VCF_INPUTVERSION_KEY = "InpuVCFVer";
static const char *VCF_INPUTPARAMS_KEY = "InputVCFParam";
static const char *VCF_FORMAT_KEY = "FORMAT";
static const char *VCF_INFO_KEY = "INFO";
static const char *VCF_VAR_FORMAT_LINE = "GT:FAZ:FCZ:FGZ:FTZ:RAZ:RCZ:RGZ:RTZ:PM";
static const char *VCF_FORMAT_A_FWD_COUNT = "ID=FAZ,Number=1,Type=Integer,Description=\"Reads presenting a A for this position, forward strand\"";
static const char *VCF_FORMAT_C_FWD_COUNT = "ID=FCZ,Number=1,Type=Integer,Description=\"Reads presenting a C for this position, forward strand\"";
static const char *VCF_FORMAT_G_FWD_COUNT = "ID=FGZ,Number=1,Type=Integer,Description=\"Reads presenting a G for this position, forward strand\"";
static const char *VCF_FORMAT_T_FWD_COUNT = "ID=FTZ,Number=1,Type=Integer,Description=\"Reads presenting a T for this position, forward strand\"";
static const char *VCF_FORMAT_A_REV_COUNT = "ID=RAZ,Number=1,Type=Integer,Description=\"Reads presenting a A for this position, reverse strand\"";
static const char *VCF_FORMAT_C_REV_COUNT = "ID=RCZ,Number=1,Type=Integer,Description=\"Reads presenting a C for this position, reverse strand\"";
static const char *VCF_FORMAT_G_REV_COUNT = "ID=RGZ,Number=1,Type=Integer,Description=\"Reads presenting a G for this position, reverse strand\"";
static const char *VCF_FORMAT_T_REV_COUNT = "ID=RTZ,Number=1,Type=Integer,Description=\"Reads presenting a T for this position, reverse strand\"";
static const char *VCF_FORMAT_MUT_ALL_PROP = "ID=PM,Number=1,Type=Float,Description=\"Proportion of mut allele\"";
static const char *VCF_FORMAT_GENOTYPE = "ID=GT,Number=1,Type=String,Description=\"Genotype\"";
static const char *VCF_INFO_TOTAL_DEPTH = "ID=DP,Number=1,Type=Integer,Description=\"Total Depth\"";
static const char *VCF_INFO_MUT_PROB_SUM = "ID=MP,Number=1,Type=Float,Description=\"Sum of CaVEMan somatic genotype probabilities\"";
static const char *VCF_INFO_SNP_PROB_SUM = "ID=GP,Number=1,Type=Float,Description=\"Sum of CaVEMan germline genotype probabilities\"";
static const char *VCF_INFO_TOP_GENO = "ID=TG,Number=1,Type=String,Description=\"Most probable genotype as called by CaVEMan\"";
static const char *VCF_INFO_TOP_GENO_PROB = "ID=TP,Number=1,Type=Float,Description=\"Probability of most probable genotype as called by CaVEMan\"";
static const char *VCF_INFO_SEC_GENO = "ID=SG,Number=1,Type=String,Description=\"2nd most probable genotype as called by CaVEMan\"";
static const char *VCF_INFO_SEC_GENO_PROB = "ID=SP,Number=1,Type=Float,Description=\"Probability of 2nd most probable genotype as called by CaVEMan\"";
static const char *VCF_INFO_DBNSP_ID = "ID=DS,Number=.,Type=String,Description=\"DBSnp ID of known SNP\"";

FILE *no_analysis = NULL;
int no_analysis_cache_size = 500;
List *no_analysis_sects = NULL;

char algos_bases[4] = {'A','C','G','T'};

void output_set_genotype_representations_for_genotype_t(genotype_t *geno,char ref_base, int *norm, int *tum){
	if(genotype_get_base_count(geno,ref_base) == 0){
		*norm = 1;
		*tum = 1;
		return;
	}else{
		*norm = 0;
		*tum = 0;
		int i=0;
		for(i=0;i<4;i++){
			if(algos_bases[i]!=ref_base && genotype_get_base_count(geno, algos_bases[i]) > 0){
				*tum = 1;
				return;
			}
		}
		return;
	}
}

int output_vcf_variant_position(estep_position_t *pos, gzFile out, char *chrom){
	assert(pos != NULL);
	assert(out != NULL);
	assert(chrom != NULL);

	char *top_ref = NULL;
	char *top_tum = NULL;
	char *sec_ref = NULL;
	char *sec_tum = NULL;

	int write = gzprintf(out,"%s\t%d\t.\t%s\t%c\t.\t.\t",chrom,pos->ref_pos,pos->ref_base,pos->top_geno->tum_geno->var_base);
	check(write>0,"Error writing initial vcf variant line, top mutant genotype.");
	//total depth seen by CaVEMan
	write = gzprintf(out,"DP=%d;",(genotype_get_total_base_count(pos->norm_fwd_cvg)+genotype_get_total_base_count(pos->norm_rev_cvg)
								+genotype_get_total_base_count(pos->tum_fwd_cvg)+genotype_get_total_base_count(pos->tum_rev_cvg)));
	check(write>0,"Error writing info line.");
	//Total somatic prob
	write = gzprintf(out,"MP=%5.1Le;",pos->total_mut_prob);
	check(write>0,"Error writing info line, mut_prob.");
	//total germline prob
	write = gzprintf(out,"GP=%5.1Le;",pos->total_snp_prob);
	check(write>0,"Error writing info line snp_prob.");
	//Top genotype and second genotype info
	top_ref = genotype_get_genotype_t_as_string(pos->top_geno->norm_geno);
	top_tum = genotype_get_genotype_t_as_string(pos->top_geno->tum_geno);
	sec_ref = genotype_get_genotype_t_as_string(pos->sec_geno->norm_geno);
	sec_tum = genotype_get_genotype_t_as_string(pos->sec_geno->tum_geno);
	write = gzprintf(out,"TG=%s/%s;TP=%5.1Le;SG=%s/%s;SP=%5.1Le\t",
						top_ref,top_tum,pos->top_geno->prob,
						sec_ref,sec_tum,pos->sec_geno->prob);

	check(write>0,"Error writing info line extra probs.");
	//FORMAT line
	write = gzprintf(out,"%s\t",VCF_VAR_FORMAT_LINE);
	check(write>0,"Error writing vcf variant format line.");
	//NORMAL FORMAT
	int norm_geno_rep = 0;
	int tum_geno_rep = 0;
	int mut_count = genotype_get_base_count(pos->norm_fwd_cvg,pos->top_geno->tum_geno->var_base)+genotype_get_base_count(pos->norm_rev_cvg,pos->top_geno->tum_geno->var_base);
	double mut_prop = 0.0;
	if(mut_count > 0){
		mut_prop = (double) mut_count / (double)(genotype_get_total_base_count(pos->norm_fwd_cvg)+genotype_get_total_base_count(pos->norm_rev_cvg));
	}
	output_set_genotype_representations_for_genotype_t(pos->top_geno->norm_geno,pos->ref_base[0], &norm_geno_rep, &tum_geno_rep);
	write = gzprintf(out,"%d|%d:%d:%d:%d:%d:%d:%d:%d:%d:%5.1e\t",
						norm_geno_rep,tum_geno_rep,
						pos->norm_fwd_cvg->a_count,pos->norm_fwd_cvg->c_count,pos->norm_fwd_cvg->g_count,pos->norm_fwd_cvg->t_count,
						pos->norm_rev_cvg->a_count,pos->norm_rev_cvg->c_count,pos->norm_rev_cvg->g_count,pos->norm_rev_cvg->t_count,
						mut_prop);
	check(write>0,"Error writing normal format for VCF variant line.");
	//TUMOUR FORMAT
	norm_geno_rep = 0;
	tum_geno_rep = 0;
	mut_count = 0;
	mut_count = genotype_get_base_count(pos->tum_fwd_cvg,pos->top_geno->tum_geno->var_base)+genotype_get_base_count(pos->tum_rev_cvg,pos->top_geno->tum_geno->var_base);
	mut_prop = 0.0;
	if(mut_count > 0){
		mut_prop = (double) mut_count / (double)(genotype_get_total_base_count(pos->tum_fwd_cvg)+genotype_get_total_base_count(pos->tum_rev_cvg));
	}
	output_set_genotype_representations_for_genotype_t(pos->top_geno->tum_geno,pos->ref_base[0], &norm_geno_rep, &tum_geno_rep);
	write = gzprintf(out,"%d|%d:%d:%d:%d:%d:%d:%d:%d:%d:%5.1e\n",
						norm_geno_rep,tum_geno_rep,
						pos->tum_fwd_cvg->a_count,pos->tum_fwd_cvg->c_count,pos->tum_fwd_cvg->g_count,pos->tum_fwd_cvg->t_count,
						pos->tum_rev_cvg->a_count,pos->tum_rev_cvg->c_count,pos->tum_rev_cvg->g_count,pos->tum_rev_cvg->t_count,
						mut_prop);
	check(write>0,"Error writing tumour format for VCF variant line.");
	free(top_ref);
	free(top_tum);
	free(sec_ref);
	free(sec_tum);
	return 0;
error:
	if(top_ref) free(top_ref);
	if(top_tum) free(top_tum);
	if(sec_ref) free(sec_ref);
	if(sec_tum) free(sec_tum);
	return -1;
}

char *output_generate_CaVEMan_process_log(char *cave_version){
	char *process = malloc(sizeof(char) * 1000);
	sprintf(process,"##%s=<%s=<.>,%s=<%s>,%s=<\"%s\">,%s=<NORMAL_CONTAMINATION=%g,REF_BIAS=%g,PRIOR_MUT_RATE=%g,PRIOR_SNP_RATE=%g,SNP_CUTOFF=%g,MUT_CUTOFF=%g>>\n##cavemanVersion=%s\n",
						VCF_PROCESSLOG_KEY,VCF_INPUTVCF_KEY,VCF_INPUTSOURCE_KEY,VCF_INPUT_SOURCE_VALUE,
						VCF_INPUTVERSION_KEY,cave_version,
						VCF_INPUTPARAMS_KEY,get_norm_contam(),get_ref_bias(),get_prior_mut_prob(),get_prior_snp_prob(),get_min_snp_prob(),get_min_mut_prob(),
						cave_version);
	return process;
}

char *output_generate_reference_contig_lines(char *bam_file, char *assembly, char *species){
	assert(bam_file != NULL);<commit_msg>Update genotype output to be unphased in VCF<commit_after>/**   LICENSE
* Copyright (c) 2014-2018 Genome Research Ltd.
*
* Author: Cancer Genome Project <EMAIL>
*
* This file is part of CaVEMan.
*
* CaVEMan is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation; either version 3 of the License, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*    1. The usage of a range of years within a copyright statement contained within
*    this distribution should be interpreted as being equivalent to a list of years
*    including the first and last year specified and all consecutive years between
*    them. For example, a copyright statement that reads ‘Copyright (c) 2005, 2007-
*    2009, 2011-2012’ should be interpreted as being identical to a statement that
*    reads ‘Copyright (c) 2005, 2007, 2008, 2009, 2011, 2012’ and a copyright
*    statement that reads ‘Copyright (c) 2005-2012’ should be interpreted as being
*    identical to a statement that reads ‘Copyright (c) 2005, 2006, 2007, 2008,
*    2009, 2010, 2011, 2012’."
*
*/

#include <stdio.h>
#include <assert.h>
#include <output.h>
#include <string.h>
#include <bam_access.h>
#include <ignore_reg_access.h>
#include <genotype.h>
#include <stdio.h>
#include <time.h>
#include <dbg.h>

static const char *VCF_VERSION_KEY = "fileformat";
static const char *VCF_VERSION_VALUE = "VCFv4.1";
static const char *VCF_FILEDATE_KEY = "fileDate";
static const char *VCF_REF_SEQ_KEY = "reference";
static const char *VCF_SAMPLE_KEY = "SAMPLE";
static const char *VCF_NORMAL_NAME = "NORMAL";
static const char *VCF_DESCRIPTION_KEY = "Description";
static const char *VCF_ACCESSION_KEY = "Accession";
static const char *VCF_PLATFORM_KEY = "Platform";
static const char *VCF_PROTOCOL_KEY = "Protocol";
static const char *VCF_INDIVIDUAL_KEY = "SampleName";
static const char *VCF_SOURCE_KEY = "Source";
static const char *VCF_TUMOUR_NAME = "TUMOUR";
static const char *VCF_PROCESSLOG_KEY = "vcfProcessLog";
static const char *VCF_INPUTVCF_KEY = "InputVCF";
static const char *VCF_INPUTSOURCE_KEY = "InputVCFSource";
static const char *VCF_INPUT_SOURCE_VALUE = "CaVEMan";
static const char *VCF_INPUTVERSION_KEY = "InpuVCFVer";
static const char *VCF_INPUTPARAMS_KEY = "InputVCFParam";
static const char *VCF_FORMAT_KEY = "FORMAT";
static const char *VCF_INFO_KEY = "INFO";
static const char *VCF_VAR_FORMAT_LINE = "GT:FAZ:FCZ:FGZ:FTZ:RAZ:RCZ:RGZ:RTZ:PM";
static const char *VCF_FORMAT_A_FWD_COUNT = "ID=FAZ,Number=1,Type=Integer,Description=\"Reads presenting a A for this position, forward strand\"";
static const char *VCF_FORMAT_C_FWD_COUNT = "ID=FCZ,Number=1,Type=Integer,Description=\"Reads presenting a C for this position, forward strand\"";
static const char *VCF_FORMAT_G_FWD_COUNT = "ID=FGZ,Number=1,Type=Integer,Description=\"Reads presenting a G for this position, forward strand\"";
static const char *VCF_FORMAT_T_FWD_COUNT = "ID=FTZ,Number=1,Type=Integer,Description=\"Reads presenting a T for this position, forward strand\"";
static const char *VCF_FORMAT_A_REV_COUNT = "ID=RAZ,Number=1,Type=Integer,Description=\"Reads presenting a A for this position, reverse strand\"";
static const char *VCF_FORMAT_C_REV_COUNT = "ID=RCZ,Number=1,Type=Integer,Description=\"Reads presenting a C for this position, reverse strand\"";
static const char *VCF_FORMAT_G_REV_COUNT = "ID=RGZ,Number=1,Type=Integer,Description=\"Reads presenting a G for this position, reverse strand\"";
static const char *VCF_FORMAT_T_REV_COUNT = "ID=RTZ,Number=1,Type=Integer,Description=\"Reads presenting a T for this position, reverse strand\"";
static const char *VCF_FORMAT_MUT_ALL_PROP = "ID=PM,Number=1,Type=Float,Description=\"Proportion of mut allele\"";
static const char *VCF_FORMAT_GENOTYPE = "ID=GT,Number=1,Type=String,Description=\"Genotype\"";
static const char *VCF_INFO_TOTAL_DEPTH = "ID=DP,Number=1,Type=Integer,Description=\"Total Depth\"";
static const char *VCF_INFO_MUT_PROB_SUM = "ID=MP,Number=1,Type=Float,Description=\"Sum of CaVEMan somatic genotype probabilities\"";
static const char *VCF_INFO_SNP_PROB_SUM = "ID=GP,Number=1,Type=Float,Description=\"Sum of CaVEMan germline genotype probabilities\"";
static const char *VCF_INFO_TOP_GENO = "ID=TG,Number=1,Type=String,Description=\"Most probable genotype as called by CaVEMan\"";
static const char *VCF_INFO_TOP_GENO_PROB = "ID=TP,Number=1,Type=Float,Description=\"Probability of most probable genotype as called by CaVEMan\"";
static const char *VCF_INFO_SEC_GENO = "ID=SG,Number=1,Type=String,Description=\"2nd most probable genotype as called by CaVEMan\"";
static const char *VCF_INFO_SEC_GENO_PROB = "ID=SP,Number=1,Type=Float,Description=\"Probability of 2nd most probable genotype as called by CaVEMan\"";
static const char *VCF_INFO_DBNSP_ID = "ID=DS,Number=.,Type=String,Description=\"DBSnp ID of known SNP\"";

FILE *no_analysis = NULL;
int no_analysis_cache_size = 500;
List *no_analysis_sects = NULL;

char algos_bases[4] = {'A','C','G','T'};

void output_set_genotype_representations_for_genotype_t(genotype_t *geno,char ref_base, int *norm, int *tum){
	if(genotype_get_base_count(geno,ref_base) == 0){
		*norm = 1;
		*tum = 1;
		return;
	}else{
		*norm = 0;
		*tum = 0;
		int i=0;
		for(i=0;i<4;i++){
			if(algos_bases[i]!=ref_base && genotype_get_base_count(geno, algos_bases[i]) > 0){
				*tum = 1;
				return;
			}
		}
		return;
	}
}

int output_vcf_variant_position(estep_position_t *pos, gzFile out, char *chrom){
	assert(pos != NULL);
	assert(out != NULL);
	assert(chrom != NULL);

	char *top_ref = NULL;
	char *top_tum = NULL;
	char *sec_ref = NULL;
	char *sec_tum = NULL;

	int write = gzprintf(out,"%s\t%d\t.\t%s\t%c\t.\t.\t",chrom,pos->ref_pos,pos->ref_base,pos->top_geno->tum_geno->var_base);
	check(write>0,"Error writing initial vcf variant line, top mutant genotype.");
	//total depth seen by CaVEMan
	write = gzprintf(out,"DP=%d;",(genotype_get_total_base_count(pos->norm_fwd_cvg)+genotype_get_total_base_count(pos->norm_rev_cvg)
								+genotype_get_total_base_count(pos->tum_fwd_cvg)+genotype_get_total_base_count(pos->tum_rev_cvg)));
	check(write>0,"Error writing info line.");
	//Total somatic prob
	write = gzprintf(out,"MP=%5.1Le;",pos->total_mut_prob);
	check(write>0,"Error writing info line, mut_prob.");
	//total germline prob
	write = gzprintf(out,"GP=%5.1Le;",pos->total_snp_prob);
	check(write>0,"Error writing info line snp_prob.");
	//Top genotype and second genotype info
	top_ref = genotype_get_genotype_t_as_string(pos->top_geno->norm_geno);
	top_tum = genotype_get_genotype_t_as_string(pos->top_geno->tum_geno);
	sec_ref = genotype_get_genotype_t_as_string(pos->sec_geno->norm_geno);
	sec_tum = genotype_get_genotype_t_as_string(pos->sec_geno->tum_geno);
	write = gzprintf(out,"TG=%s/%s;TP=%5.1Le;SG=%s/%s;SP=%5.1Le\t",
						top_ref,top_tum,pos->top_geno->prob,
						sec_ref,sec_tum,pos->sec_geno->prob);

	check(write>0,"Error writing info line extra probs.");
	//FORMAT line
	write = gzprintf(out,"%s\t",VCF_VAR_FORMAT_LINE);
	check(write>0,"Error writing vcf variant format line.");
	//NORMAL FORMAT
	int norm_geno_rep = 0;
	int tum_geno_rep = 0;
	int mut_count = genotype_get_base_count(pos->norm_fwd_cvg,pos->top_geno->tum_geno->var_base)+genotype_get_base_count(pos->norm_rev_cvg,pos->top_geno->tum_geno->var_base);
	double mut_prop = 0.0;
	if(mut_count > 0){
		mut_prop = (double) mut_count / (double)(genotype_get_total_base_count(pos->norm_fwd_cvg)+genotype_get_total_base_count(pos->norm_rev_cvg));
	}
	output_set_genotype_representations_for_genotype_t(pos->top_geno->norm_geno,pos->ref_base[0], &norm_geno_rep, &tum_geno_rep);
	write = gzprintf(out,"%d/%d:%d:%d:%d:%d:%d:%d:%d:%d:%5.1e\t",
						norm_geno_rep,tum_geno_rep,
						pos->norm_fwd_cvg->a_count,pos->norm_fwd_cvg->c_count,pos->norm_fwd_cvg->g_count,pos->norm_fwd_cvg->t_count,
						pos->norm_rev_cvg->a_count,pos->norm_rev_cvg->c_count,pos->norm_rev_cvg->g_count,pos->norm_rev_cvg->t_count,
						mut_prop);
	check(write>0,"Error writing normal format for VCF variant line.");
	//TUMOUR FORMAT
	norm_geno_rep = 0;
	tum_geno_rep = 0;
	mut_count = 0;
	mut_count = genotype_get_base_count(pos->tum_fwd_cvg,pos->top_geno->tum_geno->var_base)+genotype_get_base_count(pos->tum_rev_cvg,pos->top_geno->tum_geno->var_base);
	mut_prop = 0.0;
	if(mut_count > 0){
		mut_prop = (double) mut_count / (double)(genotype_get_total_base_count(pos->tum_fwd_cvg)+genotype_get_total_base_count(pos->tum_rev_cvg));
	}
	output_set_genotype_representations_for_genotype_t(pos->top_geno->tum_geno,pos->ref_base[0], &norm_geno_rep, &tum_geno_rep);
	write = gzprintf(out,"%d/%d:%d:%d:%d:%d:%d:%d:%d:%d:%5.1e\n",
						norm_geno_rep,tum_geno_rep,
						pos->tum_fwd_cvg->a_count,pos->tum_fwd_cvg->c_count,pos->tum_fwd_cvg->g_count,pos->tum_fwd_cvg->t_count,
						pos->tum_rev_cvg->a_count,pos->tum_rev_cvg->c_count,pos->tum_rev_cvg->g_count,pos->tum_rev_cvg->t_count,
						mut_prop);
	check(write>0,"Error writing tumour format for VCF variant line.");
	free(top_ref);
	free(top_tum);
	free(sec_ref);
	free(sec_tum);
	return 0;
error:
	if(top_ref) free(top_ref);
	if(top_tum) free(top_tum);
	if(sec_ref) free(sec_ref);
	if(sec_tum) free(sec_tum);
	return -1;
}

char *output_generate_CaVEMan_process_log(char *cave_version){
	char *process = malloc(sizeof(char) * 1000);
	sprintf(process,"##%s=<%s=<.>,%s=<%s>,%s=<\"%s\">,%s=<NORMAL_CONTAMINATION=%g,REF_BIAS=%g,PRIOR_MUT_RATE=%g,PRIOR_SNP_RATE=%g,SNP_CUTOFF=%g,MUT_CUTOFF=%g>>\n##cavemanVersion=%s\n",
						VCF_PROCESSLOG_KEY,VCF_INPUTVCF_KEY,VCF_INPUTSOURCE_KEY,VCF_INPUT_SOURCE_VALUE,
						VCF_INPUTVERSION_KEY,cave_version,
						VCF_INPUTPARAMS_KEY,get_norm_contam(),get_ref_bias(),get_prior_mut_prob(),get_prior_snp_prob(),get_min_snp_prob(),get_min_mut_prob(),
						cave_version);
	return process;
}

char *output_generate_reference_contig_lines(char *bam_file, char *assembly, char *species){
	assert(bam_file != NULL);
{'fraction_non_alphanumeric': 0.13373801609095726, 'fraction_numerical': 0.016187310304957365, 'mean_word_length': 6.50469992769342, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 221, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5951971', 'n_tokens_mistral': 8368, 'n_tokens_neox': 7750, 'n_words': 1630}