'''
DECoNT source code.
DECoNT is a deep learning based WES CNV polisher tool.
This script, DECoNT_polish.py, is only used to load trained weights of DECoNT models
and use them to polish calls from XHMM, CoNIFER or CODEX2.
'''
import sys
import argparse
import numpy as np
import pdb
import os
import datetime
import subprocess
from os import listdir
from multiprocessing.pool import Pool
from tqdm import tqdm
import pandas as pd
import warnings
import tensorflow as tf
import statistics
from csv import reader
tf.compat.v1.logging.set_verbosity(tf.compat.v1.logging.ERROR)
warnings.filterwarnings("ignore", category=FutureWarning)
def warn(*args, **kwargs):
    pass
warnings.warn = warn
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
from tensorflow.python.util import deprecation
deprecation._PRINT_DEPRECATION_WARNINGS = False
'''
Helper function to print informative messages to the user.
'''
def message(message):
    print("[",datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),"]\t", "DECoNT:\t", message)

try:
    os.mkdir("../tmp/")
    os.mkdir("../tmp2/")
    os.mkdir("../tmp3/")
except OSError:
    print ("Creation of the directory failed")
else:
    print ("Successfully created the directory")

''' 
Perform I/O operations.
'''

description = "DECoNT is a deep learning based WES CNV polisher tool. \
            For academic research the software is completely free, although for \
            commercial usage the software is licensed. \n \
            please see ciceklab.cs.bilkent.edu.tr/DECoNTlicenceblablabla."

parser = argparse.ArgumentParser(description=description)

'''
Required arguments group:
(i) -cn, to-polish caller name one of the following for version 0.1: XHMM, CoNIFER, CODEX2, Control-FREEC
(ii) -i, to-polish data path obtained from above WES based CNV callers.
(iii) -m, model pretrained or model path to be used for polishing (.h5)
(iv) -o, relative or direct output directory path to write DECoNT output file.
(v) -s, relative or direct directory path to WES .bam files of samples in the analysis (i.e. samples used in WES CNV calling).
'''

required_args = parser.add_argument_group('Required Arguments')
opt_args = parser.add_argument_group("Optional Arguments")
required_args.add_argument("-m", "--model", help="If you want to use pretrained DECoNT weights for polishing set to one of the following: \n \
                   (i) XHMM \n (ii) CoNIFER \n (iii) CODEX2 (iv) Control-FREEC. \n \
                   If you do not want to use pretrained DECoNT weights for polishing, provide relative or direct path to .h5 model weights. \
                   Note that, if you choose pretrained option, appropriate pretrained DECoNT model will be automatically chosen by the program \
                   according to the -cn argument (e.g, program will chose XHMM specific weights of DECoNT if -cn XHMM is given).", required=True)

required_args.add_argument("-cn", "--callername", help="WES based CNV caller selection for polishing. This can only be one of the following\
                          XHMM, CoNIFER, CODEX2 or Control-FREEC", required=True)

required_args.add_argument("-i", "--input", help="Relative or direct path to output file of selected WES based CNV caller.", required=True)

required_args.add_argument("-o", "--output", help="Relative or direct output directory path to write DECoNT output file.", required=True)

required_args.add_argument("-s", "--samples", help="Relative or direct directory path to read depth files of samples in the analysis (i.e samples used in WES CNV calling)\
                           Note: All read depth files must be in the format specified in instructions manual. \
                           Read depth files generated by sambamba tool are directly accepted.", required=True)

opt_args.add_argument("-g", "--gpu", help="Specify gpu", required=False)

'''
Optional arguments group:
-v or --version, version check
-h or --help, help
-g or --gpu, specify gpu
-
'''

parser.add_argument("-V", "--version", help="show program version", action="store_true")
args = parser.parse_args()

if args.version:
    print("DECoNT version 0.1")

if args.model in ['pretrained', 'PRETRAINED', 'Pretrained']:
    pretrained_flag = True
elif not os.path.isfile(args.model):
    parser.error('Provided model path {} does not exist or can not be readable!'.format(args.model))
    pretrained_flag = False

if not os.path.isfile(args.input) and not args.callername in ["Control-FREEC", "control-freec"]:
    parser.error('Provided input path {} does not exist or can not be readable!'.format(args.input))

if not os.path.isdir(args.output):
    parser.error('Provided directory {} does not exist or can not be writable!'.format(args.output))

if args.callername not in ['CODEX2', 'XHMM', 'CoNIFER', 'codex2', 'xhmm', 'CONIFER', 'conifer', 'Conifer', 'Xhmm', 'Codex2', "Control-FREEC", "control-freec"]:
    parser.error('Provided caller name {} should be one of the following: (i) XHMM, (ii) CoNIFER, (iii) CODEX2!'.format(args.callername))



'''
Argument parsing and I/O operations are performed. According to those
perform requested operations and write to the desired output location.
'''

message("Execution started successfully!")
callername=args.callername
'''
Different tools outputs require different procesing steps. Thus we check.
'''
if callername in ["XHMM", "xhmm", "Xhmm"]: 
    output_path = "../tmp/"
    xncv_path = args.input
    with open(xncv_path) as f:
        content = f.readlines()
    
    rows_for_sample = []
    for i in range(1,len(content)):
        splitted_line = content[i].split("\t")
        sample_name = splitted_line[0]
        detected_cnv = splitted_line[1]
        interval_info = splitted_line[2]
        chr = interval_info.split(":")[0]
        start_index = interval_info.split(":")[1].split("-")[0]
        end_index = interval_info.split(":")[1].split("-")[1]
        line_to_write = chr + "," + start_index + "," + end_index + "," +detected_cnv

        if i == len(content)-1:
            next_name = "end_of_file"
        else:
            next_name = content[i+1].split("\t")[0]

        if next_name == sample_name:
            rows_for_sample.append(line_to_write)
        else:
            with open(output_path+sample_name+'.xhmm_data.txt', 'w') as f:
                for line in rows_for_sample:
                    f.write("%s\n" % line)
            rows_for_sample = []
    '''
    Directory ../tmp/ contains sample wise CNV information now.
    '''
    message("All calls in provided cnv file are successfully obtained!")
    def match_vectors(chrn_xhmm, chrn_cnvnator):
        mapping_list = []

        for index_xhmm in range(len(chrn_xhmm)):
            for index_cnvnator in range(len(chrn_cnvnator)):
                #continue if start base of xhmm entry is greater than end base of cnvnator entry
                #print(int(chrn_xhmm[index_xhmm].split(",")[1]), int(chrn_cnvnator[index_cnvnator].split("\t")[7].split(";")[0].split("=")[1]))
                end_chaisson = chrn_cnvnator[index_cnvnator].split("\t")[7].split(";")
                end_str = [i for i in end_chaisson if i[:4]=="END="][0].split("=")[1]
                if(int(chrn_xhmm[index_xhmm].split(",")[1]) >= int(end_str)):
                    continue
                #add to list if regions are overlapping

                if(int(chrn_xhmm[index_xhmm].split(",")[2]) >= int(chrn_cnvnator[index_cnvnator].split("\t")[1])):
                    mapping_list.append((index_xhmm,index_cnvnator))
        
        current_xhmm_index = 0
        current_cnvnator_index = 0

        if not mapping_list:
            return chrn_xhmm

        last_xhmm_index = mapping_list[0][0]
        temp_cnv_list = []

        for i in range(0, len(mapping_list)):

            current_xhmm_index = mapping_list[i][0]
            current_cnvnator_index = mapping_list[i][1]

            if(current_xhmm_index == last_xhmm_index):
                temp_cnv_list.append(chrn_cnvnator[current_cnvnator_index].split("\t")[4])
                
            
            else:
                if not temp_cnv_list:
                    temp_cnv_list.append("NAN")
                resulting_vote = max(set(temp_cnv_list), key=temp_cnv_list.count)
                temp_cnv_list = []
                temp_cnv_list.append(chrn_cnvnator[current_cnvnator_index].split("\t")[4])
                chrn_xhmm[last_xhmm_index] = chrn_xhmm[last_xhmm_index].rstrip() + "," + resulting_vote + "\n"
                last_xhmm_index = current_xhmm_index

                if i == len(mapping_list) - 1:
                    if not temp_cnv_list:
                        temp_cnv_list.append("NAN")
                    resulting_vote = max(set(temp_cnv_list), key=temp_cnv_list.count)
                    chrn_xhmm[last_xhmm_index] = chrn_xhmm[last_xhmm_index].rstrip() + "," + resulting_vote + "\n"

                continue

            if i == len(mapping_list) - 1:
                if not temp_cnv_list:
                    temp_cnv_list.append("NAN")
                resulting_vote = max(set(temp_cnv_list), key=temp_cnv_list.count)
                chrn_xhmm[last_xhmm_index] = chrn_xhmm[last_xhmm_index].rstrip() + "," + resulting_vote + "\n"

            last_xhmm_index = current_xhmm_index
        
        return chrn_xhmm

    chr_wise_data_path = "../tmp2/"
    path_to_cnvnator = "../utils/"
    path_to_xhmm = "../tmp/"
    files_in_xhmm = listdir(path_to_xhmm)
    files_in_cnvnator = listdir(path_to_cnvnator)

    for i in range(len(files_in_xhmm)):
        sample_name = files_in_xhmm[i].split(".")[0]
        #print(sample_name, i)

        #read xhmm data line-by-line
        with open(path_to_xhmm+files_in_xhmm[i]) as f:
            xhmm_data = f.readlines()

        #read cnvnator data line-by-line
        with open(path_to_cnvnator+"HG00732"+".chaissonetal.groundtruths.wgs.deldup.vcf") as f:
            cnvnator_data = f.readlines()

        chrwise_xhmm_data = [[] for i in range(24)]
        chrwise_cnvnator_data = [[] for i in range(24)]

        for i in range(24):
            if i == 22:
                chrname= "chrX"
                chrwise_cnvnator_data[i] = [x for x in cnvnator_data if x.split("\t")[0]==chrname]
                chrwise_xhmm_data[i] = [x for x in xhmm_data if x.split(",")[0]==chrname]

            elif i == 23:
                chrname= "chrY"
                chrwise_cnvnator_data[i] = [x for x in cnvnator_data if x.split("\t")[0]==chrname]
                chrwise_xhmm_data[i] = [x for x in xhmm_data if x.split(",")[0]==chrname]

            else:
                chrname= "chr"+str(i+1)
                chrwise_cnvnator_data[i] = [x for x in cnvnator_data if x.split("\t")[0]==chrname]
                chrwise_xhmm_data[i] = [x for x in xhmm_data if x.split(",")[0]==chrname]
        #print(chrwise_xhmm_data[4])
        #print(match_vectors(chrwise_xhmm_data[4], chrwise_cnvnator_data[4]))


        for i in range(24):
            if i == 22:
                chrname= "chrX"
                labeled = match_vectors(chrwise_xhmm_data[i], chrwise_cnvnator_data[i])
                with open(chr_wise_data_path + chrname + "_" + sample_name + ".txt", "a") as myfile:
                    for row in labeled:
                        myfile.write(row)

            elif i == 23:
                chrname= "chrY"
                labeled = match_vectors(chrwise_xhmm_data[i], chrwise_cnvnator_data[i])
                with open(chr_wise_data_path + chrname + "_" + sample_name + ".txt", "a") as myfile:
                    for row in labeled:
                        myfile.write(row)

            else:
                chrname= "chr"+str(i+1)
                labeled = match_vectors(chrwise_xhmm_data[i], chrwise_cnvnator_data[i])
                with open(chr_wise_data_path + chrname + "_" + sample_name + ".txt", "a") as myfile:
                    for row in labeled:
                        myfile.write(row)  
    '''
    Directory ../tmp2/ contains chr-wise splitted samples.
    '''
    chr_splitted_xhmm_data_path = "../tmp2/"
    sambamba_read_depths_path = args.samples
    output_path = "../tmp3/"

    files_xhmm = os.listdir(chr_splitted_xhmm_data_path)
    def run(chrfile):
        #print(chrfile)
        xhmm_data = pd.read_csv(chr_splitted_xhmm_data_path+chrfile, low_memory=False,header=None, names=list(range(0,5))).values.tolist()
        chrmsm = chrfile.split(".")[0].split("_")[0] # i.e, chr1
        samplename = chrfile.split(".")[0].split("_")[1] # i.e, HG01893
        
        #read corresponding read-depth file
        read_depth_file_name = samplename+".read_depths.txt"
        read_depth_data = pd.read_csv(sambamba_read_depths_path+read_depth_file_name, sep='\t',header=None,low_memory=False, names=list(range(0,6))).values[1:].tolist()

        for i in range(len(xhmm_data)):
            xhmm_line = xhmm_data[i]
            start_index_xhmm = xhmm_line[1]
            end_index_xhmm = xhmm_line[2]
            read_depth_sequence = []
            for depth_line in read_depth_data:

                chr_read_depth = depth_line[0] # i.e, chr1
                if chr_read_depth != chrmsm:
                    continue

                start_index_depth = int(depth_line[1])
                if start_index_xhmm > start_index_depth:
                    continue

                end_index_depth = int(depth_line[2])
                if end_index_xhmm > end_index_depth:
                    read_depth = int(depth_line[3])
                    read_depth_sequence.append(read_depth)
                    continue
                xhmm_data[i].append(read_depth_sequence)
                break
        #write generated chr seperated sample to a new file
        generated_filename = chrfile+"generated_sample.txt"
        with open(output_path+generated_filename, 'w') as f:
            for item in xhmm_data:
                f.write("%s\n" % item)
    with Pool(20) as p:
        p.map(run, files_xhmm)

    '''
    Directory ../tmp3/ now contains the read depth extracted and generated ready samples.
    '''
    message("Provided read depth files are succesfully processed, samples are ready for polishing with corresponding RD signals!")
elif callername in ["CoNIFER", "CONIFER", "conifer", "Conifer"]: 
    output_path = "../tmp/"
    xncv_path = args.input
    with open(xncv_path) as f:
        content = f.readlines()
    
    rows_for_sample = []
    for i in range(1,len(content)):
        splitted_line = content[i].split("\t")
        sample_name = splitted_line[0]
        detected_cnv = splitted_line[1]
        interval_info = splitted_line[2]
        chr = interval_info.split(":")[0]
        start_index = interval_info.split(":")[1].split("-")[0]
        end_index = interval_info.split(":")[1].split("-")[1]
        line_to_write = chr + "," + start_index + "," + end_index + "," +detected_cnv

        if i == len(content)-1:
            next_name = "end_of_file"
        else:
            next_name = content[i+1].split("\t")[0]

        if next_name == sample_name:
            rows_for_sample.append(line_to_write)
        else:
            with open(output_path+sample_name+'.xhmm_data.txt', 'w') as f:
                for line in rows_for_sample:
                    f.write("%s\n" % line)
            rows_for_sample = []
    '''
    Directory ../tmp/ contains sample wise CNV information now.
    '''
    message("All calls in provided cnv file are successfully obtained!")
    def match_vectors(chrn_xhmm, chrn_cnvnator):
        mapping_list = []

        for index_xhmm in range(len(chrn_xhmm)):
            for index_cnvnator in range(len(chrn_cnvnator)):
                #continue if start base of xhmm entry is greater than end base of cnvnator entry
                #print(int(chrn_xhmm[index_xhmm].split(",")[1]), int(chrn_cnvnator[index_cnvnator].split("\t")[7].split(";")[0].split("=")[1]))
                end_chaisson = chrn_cnvnator[index_cnvnator].split("\t")[7].split(";")
                end_str = [i for i in end_chaisson if i[:4]=="END="][0].split("=")[1]
                if(int(chrn_xhmm[index_xhmm].split(",")[1]) >= int(end_str)):
                    continue
                #add to list if regions are overlapping

                if(int(chrn_xhmm[index_xhmm].split(",")[2]) >= int(chrn_cnvnator[index_cnvnator].split("\t")[1])):
                    mapping_list.append((index_xhmm,index_cnvnator))
        
        current_xhmm_index = 0
        current_cnvnator_index = 0

        if not mapping_list:
            return chrn_xhmm

        last_xhmm_index = mapping_list[0][0]
        temp_cnv_list = []

        for i in range(0, len(mapping_list)):

            current_xhmm_index = mapping_list[i][0]
            current_cnvnator_index = mapping_list[i][1]

            if(current_xhmm_index == last_xhmm_index):
                temp_cnv_list.append(chrn_cnvnator[current_cnvnator_index].split("\t")[4])
                
            
            else:
                if not temp_cnv_list:
                    temp_cnv_list.append("NAN")
                resulting_vote = max(set(temp_cnv_list), key=temp_cnv_list.count)
                temp_cnv_list = []
                temp_cnv_list.append(chrn_cnvnator[current_cnvnator_index].split("\t")[4])
                chrn_xhmm[last_xhmm_index] = chrn_xhmm[last_xhmm_index].rstrip() + "," + resulting_vote + "\n"
                last_xhmm_index = current_xhmm_index

                if i == len(mapping_list) - 1:
                    if not temp_cnv_list:
                        temp_cnv_list.append("NAN")
                    resulting_vote = max(set(temp_cnv_list), key=temp_cnv_list.count)
                    chrn_xhmm[last_xhmm_index] = chrn_xhmm[last_xhmm_index].rstrip() + "," + resulting_vote + "\n"

                continue

            if i == len(mapping_list) - 1:
                if not temp_cnv_list:
                    temp_cnv_list.append("NAN")
                resulting_vote = max(set(temp_cnv_list), key=temp_cnv_list.count)
                chrn_xhmm[last_xhmm_index] = chrn_xhmm[last_xhmm_index].rstrip() + "," + resulting_vote + "\n"

            last_xhmm_index = current_xhmm_index
        
        return chrn_xhmm

    chr_wise_data_path = "../tmp2/"
    path_to_cnvnator = "../utils/"
    path_to_xhmm = "../tmp/"
    files_in_xhmm = listdir(path_to_xhmm)
    files_in_cnvnator = listdir(path_to_cnvnator)

    for i in range(len(files_in_xhmm)):
        sample_name = files_in_xhmm[i].split(".")[0]
        #print(sample_name, i)

        #read xhmm data line-by-line
        with open(path_to_xhmm+files_in_xhmm[i]) as f:
            xhmm_data = f.readlines()

        #read cnvnator data line-by-line
        with open(path_to_cnvnator+"HG00732"+".chaissonetal.groundtruths.wgs.deldup.vcf") as f:
            cnvnator_data = f.readlines()

        chrwise_xhmm_data = [[] for i in range(24)]
        chrwise_cnvnator_data = [[] for i in range(24)]

        for i in range(24):
            if i == 22:
                chrname= "chrX"
                chrwise_cnvnator_data[i] = [x for x in cnvnator_data if x.split("\t")[0]==chrname]
                chrwise_xhmm_data[i] = [x for x in xhmm_data if x.split(",")[0]==chrname]

            elif i == 23:
                chrname= "chrY"
                chrwise_cnvnator_data[i] = [x for x in cnvnator_data if x.split("\t")[0]==chrname]
                chrwise_xhmm_data[i] = [x for x in xhmm_data if x.split(",")[0]==chrname]

            else:
                chrname= "chr"+str(i+1)
                chrwise_cnvnator_data[i] = [x for x in cnvnator_data if x.split("\t")[0]==chrname]
                chrwise_xhmm_data[i] = [x for x in xhmm_data if x.split(",")[0]==chrname]
        #print(chrwise_xhmm_data[4])
        #print(match_vectors(chrwise_xhmm_data[4], chrwise_cnvnator_data[4]))


        for i in range(24):
            if i == 22:
                chrname= "chrX"
                labeled = match_vectors(chrwise_xhmm_data[i], chrwise_cnvnator_data[i])
                with open(chr_wise_data_path + chrname + "_" + sample_name + ".txt", "a") as myfile:
                    for row in labeled:
                        myfile.write(row)

            elif i == 23:
                chrname= "chrY"
                labeled = match_vectors(chrwise_xhmm_data[i], chrwise_cnvnator_data[i])
                with open(chr_wise_data_path + chrname + "_" + sample_name + ".txt", "a") as myfile:
                    for row in labeled:
                        myfile.write(row)

            else:
                chrname= "chr"+str(i+1)
                labeled = match_vectors(chrwise_xhmm_data[i], chrwise_cnvnator_data[i])
                with open(chr_wise_data_path + chrname + "_" + sample_name + ".txt", "a") as myfile:
                    for row in labeled:
                        myfile.write(row)  
    '''
    Directory ../tmp2/ contains chr-wise splitted samples.
    '''
    chr_splitted_xhmm_data_path = "../tmp2/"
    sambamba_read_depths_path = args.samples
    output_path = "../tmp3/"

    files_xhmm = os.listdir(chr_splitted_xhmm_data_path)
    def run(chrfile):
        #print(chrfile)
        xhmm_data = pd.read_csv(chr_splitted_xhmm_data_path+chrfile, low_memory=False,header=None, names=list(range(0,5))).values.tolist()
        chrmsm = chrfile.split(".")[0].split("_")[0] # i.e, chr1
        samplename = chrfile.split(".")[0].split("_")[1] # i.e, HG01893
        
        #read corresponding read-depth file
        read_depth_file_name = samplename+".read_depths.txt"
        read_depth_data = pd.read_csv(sambamba_read_depths_path+read_depth_file_name, sep='\t',header=None,low_memory=False, names=list(range(0,6))).values[1:].tolist()

        for i in range(len(xhmm_data)):
            xhmm_line = xhmm_data[i]
            start_index_xhmm = xhmm_line[1]
            end_index_xhmm = xhmm_line[2]
            read_depth_sequence = []
            for depth_line in read_depth_data:

                chr_read_depth = depth_line[0] # i.e, chr1
                if chr_read_depth != chrmsm:
                    continue

                start_index_depth = int(depth_line[1])
                if start_index_xhmm > start_index_depth:
                    continue

                end_index_depth = int(depth_line[2])
                if end_index_xhmm > end_index_depth:
                    read_depth = int(depth_line[3])
                    read_depth_sequence.append(read_depth)
                    continue
                xhmm_data[i].append(read_depth_sequence)
                break
        #write generated chr seperated sample to a new file
        generated_filename = chrfile+"generated_sample.txt"
        with open(output_path+generated_filename, 'w') as f:
            for item in xhmm_data:
                f.write("%s\n" % item)
    with Pool(20) as p:
        p.map(run, files_xhmm)

    '''
    Directory ../tmp3/ now contains the read depth extracted and generated ready samples.
    '''
    message("Provided read depth files are succesfully processed, samples are ready for polishing with corresponding RD signals!")
elif callername in ["CODEX2", "Codex2", "codex2"]: 
    output_path = "../tmp/"
    xncv_path = args.input
    #read all data line-by-line
    with open(xncv_path) as f:
        content = f.readlines()

    #SAMPLE  CNV     INTERVAL        KB      CHR     MID_BP  TARGETS NUM_TARG        Q_EXACT Q_SOME  Q_NON_DIPLOID   Q_START Q_STOP  MEAN_RD MEAN_ORIG_RD
    print(content[1].split("\t"))
    #
    #traverse .xcnv file line-by-line to parse cnv data
    rows_for_sample = []
    for i in tqdm(range(1,len(content))):
        splitted_line = content[i].split("\t")
        sample_name = splitted_line[0]
        detected_cnv = splitted_line[2]
        chr = splitted_line[1]
        start_index = splitted_line[3]
        end_index = splitted_line[4]
        line_to_write = chr + "," + start_index + "," + end_index + "," +detected_cnv

        if i == len(content)-1:
            next_name = "end_of_file"
        else:
            next_name = content[i+1].split("\t")[0]

        if next_name == sample_name:
            rows_for_sample.append(line_to_write)
        else:
            with open(output_path+sample_name+'.codex2_data.txt', 'w') as f:
                for line in rows_for_sample:
                    f.write("%s\n" % line)
            rows_for_sample = []


    '''
    Directory ../tmp/ contains sample wise CNV information now.
    '''
    message("All calls in provided cnv file are successfully obtained!")

    def match_vectors(chrn_xhmm, chrn_cnvnator):
        mapping_list = []

        for index_xhmm in range(len(chrn_xhmm)):
            for index_cnvnator in range(len(chrn_cnvnator)):
                #continue if start base of xhmm entry is greater than end base of cnvnator entry
                #print(int(chrn_xhmm[index_xhmm].split(",")[1]), int(chrn_cnvnator[index_cnvnator].split("\t")[7].split(";")[0].split("=")[1]))
                if(int(chrn_xhmm[index_xhmm].split(",")[1]) >= int(chrn_cnvnator[index_cnvnator].split("\t")[7].split(";")[0].split("=")[1])):
                    continue
                #add to list if regions are overlapping

                if(int(chrn_xhmm[index_xhmm].split(",")[2]) >= int(chrn_cnvnator[index_cnvnator].split("\t")[1])):
                    mapping_list.append((index_xhmm,index_cnvnator))
                
        current_xhmm_index = 0
        current_cnvnator_index = 0

        if not mapping_list:
            return chrn_xhmm

        last_xhmm_index = mapping_list[0][0]
        temp_cnv_list = []

        for i in range(0, len(mapping_list)):

            current_xhmm_index = mapping_list[i][0]
            current_cnvnator_index = mapping_list[i][1]

            if(current_xhmm_index == last_xhmm_index):
                temp_cnv_list.append(chrn_cnvnator[current_cnvnator_index].split("\t")[4])
                
            
            else:
                if not temp_cnv_list:
                    temp_cnv_list.append("NAN")
                resulting_vote = max(set(temp_cnv_list), key=temp_cnv_list.count)
                temp_cnv_list = []
                temp_cnv_list.append(chrn_cnvnator[current_cnvnator_index].split("\t")[4])
                chrn_xhmm[last_xhmm_index] = chrn_xhmm[last_xhmm_index].rstrip() + "," + resulting_vote + "\n"
                last_xhmm_index = current_xhmm_index

                if i == len(mapping_list) - 1:
                    if not temp_cnv_list:
                        temp_cnv_list.append("NAN")
                    resulting_vote = max(set(temp_cnv_list), key=temp_cnv_list.count)
                    chrn_xhmm[last_xhmm_index] = chrn_xhmm[last_xhmm_index].rstrip() + "," + resulting_vote + "\n"

                continue

            if i == len(mapping_list) - 1:
                if not temp_cnv_list:
                    temp_cnv_list.append("NAN")
                resulting_vote = max(set(temp_cnv_list), key=temp_cnv_list.count)
                chrn_xhmm[last_xhmm_index] = chrn_xhmm[last_xhmm_index].rstrip() + "," + resulting_vote + "\n"

            last_xhmm_index = current_xhmm_index
        
        return chrn_xhmm
            


    chr_wise_data_path = "../tmp2/"
    path_to_cnvnator = "../utils/"
    path_to_xhmm = "../tmp/"


    files_in_xhmm = listdir(path_to_xhmm)
    files_in_cnvnator = listdir(path_to_cnvnator)



    for i in tqdm(range(len(files_in_xhmm))):
        sample_name = files_in_xhmm[i].split(".")[0]
        print(sample_name, i)

        #read xhmm data line-by-line
        with open(path_to_xhmm+files_in_xhmm[i]) as f:
            xhmm_data = f.readlines()

        #read cnvnator data line-by-line
        with open(path_to_cnvnator+"HG00732"+".chaissonetal.groundtruths.wgs.deldup.vcf") as f:
            cnvnator_data = f.readlines()

        chrwise_xhmm_data = [[] for i in range(24)]
        chrwise_cnvnator_data = [[] for i in range(24)]

        for i in range(24):
            if i == 22:
                chrname= "chrX"
                chrwise_cnvnator_data[i] = [x for x in cnvnator_data if x.split("\t")[0]==chrname]
                chrwise_xhmm_data[i] = [x for x in xhmm_data if x.split(",")[0]==chrname]

            elif i == 23:
                chrname= "chrY"
                chrwise_cnvnator_data[i] = [x for x in cnvnator_data if x.split("\t")[0]==chrname]
                chrwise_xhmm_data[i] = [x for x in xhmm_data if x.split(",")[0]==chrname]

            else:
                chrname= "chr"+str(i+1)
                chrwise_cnvnator_data[i] = [x for x in cnvnator_data if x.split("\t")[0]==chrname]
                chrwise_xhmm_data[i] = [x for x in xhmm_data if x.split(",")[0]==chrname]
        #print(chrwise_xhmm_data[4])
        #print(match_vectors(chrwise_xhmm_data[4], chrwise_cnvnator_data[4]))


        for i in range(24):
            if i == 22:
                chrname= "chrX"
                labeled = match_vectors(chrwise_xhmm_data[i], chrwise_cnvnator_data[i])
                with open(chr_wise_data_path + chrname + "_" + sample_name + ".txt", "a") as myfile:
                    for row in labeled:
                        myfile.write(row)

            elif i == 23:
                chrname= "chrY"
                labeled = match_vectors(chrwise_xhmm_data[i], chrwise_cnvnator_data[i])
                with open(chr_wise_data_path + chrname + "_" + sample_name + ".txt", "a") as myfile:
                    for row in labeled:
                        myfile.write(row)

            else:
                chrname= "chr"+str(i+1)
                labeled = match_vectors(chrwise_xhmm_data[i], chrwise_cnvnator_data[i])
                with open(chr_wise_data_path + chrname + "_" + sample_name + ".txt", "a") as myfile:
                    for row in labeled:
                        myfile.write(row)
    '''
    Directory ../tmp2/ contains chr-wise splitted samples.
    '''
    chr_splitted_xhmm_data_path = "../tmp2/"
    sambamba_read_depths_path = args.samples
    output_path = "../tmp3/"

    files_xhmm = os.listdir(chr_splitted_xhmm_data_path)
    def run(chrfile):
        print(chrfile)
        xhmm_data = pd.read_csv(chr_splitted_xhmm_data_path+chrfile, header=None, names=list(range(0,5))).values.tolist()
        chrmsm = chrfile.split(".")[0].split("_")[0] # i.e, chr1
        samplename = chrfile.split(".")[0].split("_")[1] # i.e, HG01893
        
        #read corresponding read-depth file
        read_depth_file_name = samplename+".read_depths.txt"
        read_depth_data = pd.read_csv(sambamba_read_depths_path+read_depth_file_name, sep='\t',header=None, names=list(range(0,6))).values[1:].tolist()

        for i in tqdm(range(len(xhmm_data))):
            xhmm_line = xhmm_data[i]
            start_index_xhmm = xhmm_line[1]
            end_index_xhmm = xhmm_line[2]
            read_depth_sequence = []
            for depth_line in read_depth_data:

                chr_read_depth = depth_line[0] # i.e, chr1
                if chr_read_depth != chrmsm:
                    continue

                start_index_depth = int(depth_line[1])
                if start_index_xhmm > start_index_depth:
                    continue

                end_index_depth = int(depth_line[2])
                if end_index_xhmm > end_index_depth:
                    read_depth = int(depth_line[3])
                    read_depth_sequence.append(read_depth)
                    continue
                xhmm_data[i].append(read_depth_sequence)
                break
        #write generated chr seperated sample to a new file
        generated_filename = chrfile+"generated_sample.txt"
        with open(output_path+generated_filename, 'w') as f:
            for item in xhmm_data:
                f.write("%s\n" % item)

    with Pool(20) as p:
        p.map(run, files_xhmm)


    '''
    Directory ../tmp3/ now contains the read depth extracted and generated ready samples.
    '''
    message("Provided read depth files are succesfully processed, samples are ready for polishing with corresponding RD signals!")
elif callername in ["Control-FREEC", "control-freec", "controlfreec","CONTROLFREEC"]: 

    filepath_freec = args.input
    if filepath_freec[-1] != '/':
        filepath_freec = filepath_freec + '/'

    outpath = "../tmp/"

    filelist = listdir(filepath_freec)

    for i in range(len(filelist)):
        curfile = filelist[i]
        sampname= curfile.split('.')[0]

        data_freec = []
        with open(filepath_freec+curfile, newline='') as f:
            for row in reader(f, delimiter=','):
                data_freec.append(row)

        #pdb.set_trace()

        for line in data_freec:
            line= line[0].split('\t')
            file_to_append = outpath+'chr'+line[0]+'_'+sampname+'_augmented_data.txt'
            hs = open(file_to_append,"a")
            hs.write(','.join(line[:4]+line[5:])+',0'+'\n')
            hs.close() 
    '''
    Now ../tmp/ directory includes chr-wise splitted versions of CNVs generated by FREEC
    '''
    chr_splitted_freec_data_path = "../tmp/"
    sambamba_read_depths_path = args.samples
    output_path = "../tmp3/"

    files_freec = os.listdir(chr_splitted_freec_data_path)



    def run(chrfile):
        freec_data = pd.read_csv(chr_splitted_freec_data_path+chrfile, header=None, names=list(range(0,5))).values.tolist()
        chrmsm = chrfile.split(".")[0].split("_")[0] # i.e, chr1
        samplename = chrfile.split(".")[0].split("_")[1] # i.e, HG01893
        
        #read corresponding read-depth file
        read_depth_file_name = samplename+".read_depths.txt"
        read_depth_data = pd.read_csv(sambamba_read_depths_path+read_depth_file_name, sep='\t',header=None, names=list(range(0,6))).values[1:].tolist()

        for i in range(len(freec_data)):
            freec_line = freec_data[i]
            start_index_freec = freec_line[1]
            end_index_freec = freec_line[2]
            read_depth_sequence = []
            for depth_line in read_depth_data:

                chr_read_depth = depth_line[0] # i.e, chr1
                if chr_read_depth != chrmsm:
                    continue

                start_index_depth = int(depth_line[1])
                if start_index_freec > start_index_depth:
                    continue

                end_index_depth = int(depth_line[2])
                if end_index_freec > end_index_depth:
                    read_depth = int(depth_line[3])
                    read_depth_sequence.append(read_depth)
                    continue
                freec_data[i].append(read_depth_sequence)
                break
        #write generated chr seperated sample to a new file
        generated_filename = chrfile+"generated_sample.txt"
        with open(output_path+generated_filename, 'w') as f:
            for item in freec_data:
                f.write("%s\n" % item)

    with Pool(20) as p:
        p.map(run, files_freec)

else:
    message("ERROR: You did not provide an appropriate caller name. Please choose an available caller name. Exiting now.")
    sys.exit()


'''
Main polishing function. Requires keras and sklearn
'''

os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"   # see issue #152
os.environ["CUDA_VISIBLE_DEVICES"] = ""

import time
import keras.backend as K
from tqdm import tqdm
import keras_metrics
from keras_metrics import categorical_precision, categorical_recall
from keras.layers import Input
from keras.preprocessing import sequence
from keras.layers import LSTM, Dense, Masking, Concatenate, concatenate, Bidirectional, BatchNormalization, Dropout
from keras.utils import to_categorical
from sklearn.preprocessing import LabelEncoder
from keras.models import Sequential, Model, load_model
from keras.utils import multi_gpu_model
from sklearn.metrics import precision_score, recall_score, accuracy_score

if args.gpu:
    os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
    os.environ["CUDA_VISIBLE_DEVICES"]= args.gpu
    message("Using GPU!")
else:
    message("Using CPU!")

dependencies={"categorical_precision" : categorical_precision(),"categorical_recall" : categorical_recall()}



if callername in ["XHMM", "xhmm", "Xhmm"]:
    if pretrained_flag:
        '''
        User has chosen to use pretrained DECoNT models for polishing. 
        Pretrained DECoNT models are stored in ../outputs/ directory.
        '''
        xhmm_polisher = load_model("../outputs/deepXCNV_batchnorm_bilstm128_batchnorm_dense100_dense3_bs256_padding-1_30epochs_traintestsplitted_weightedcrossent_xhmm.h5",
                        custom_objects=dependencies)
    else:
        xhmm_polisher = load_model(args.model, custom_objects = dependencies)

    data_path = "../tmp3/"

    data_list_readdepths = []
    data_list_indexes = []
    data_list_cnvnator_preds = []
    data_list_xhmm_preds = []
    data_list_sample_names = []
    data_list_chr_names = []

    files_list = os.listdir(data_path)

    for filename in files_list:
        with open(data_path+filename) as f:
            data = f.readlines()
            data = [x.strip() for x in data]
        sampname = [filename.split('.')[0].split('_')[1] for x in data] 
        chrname = [filename.split('.')[0].split('_')[0] for x in data]
        indexes = [(int(x.split(',')[1][1:]),int(x.split(',')[2][1:])) for x in data]
        xhmm_preds = [x.split(',')[3][1:] for x in data]
        cnvnator_preds = [x.split(',')[4][1:] for x in data]
        read_depth_seqs = [x.split(',')[5:] for x in data]
        read_depth_seqs = [[y.replace('[','',1).replace(']','').replace(' ','') for y in x] for x in read_depth_seqs]
        read_depth_seqs = [[0 if not y else int(str(y)) for y in x] for x in read_depth_seqs]
        data_list_indexes.extend(indexes)
        data_list_cnvnator_preds.extend(cnvnator_preds)
        data_list_xhmm_preds.extend(xhmm_preds)
        data_list_readdepths.extend(read_depth_seqs)
        data_list_sample_names.extend(sampname)
        data_list_chr_names.extend(chrname)

    #convert data lists to numpy arrays
    data_list_readdepths = np.asarray(data_list_readdepths)
    data_list_indexes = np.asarray(data_list_indexes)
    data_list_cnvnator_preds = np.asarray(data_list_cnvnator_preds)
    data_list_xhmm_preds = np.asarray(data_list_xhmm_preds)


    data_list_readdepths = sequence.pad_sequences(data_list_readdepths, value=-1, maxlen=8501)

    data_list_cnvnator_preds[data_list_cnvnator_preds == 'nan'] = 0
    data_list_cnvnator_preds[data_list_cnvnator_preds == "'<DUP>'"] = 1
    data_list_cnvnator_preds[data_list_cnvnator_preds == "'<DEL>'"] = 2


    data_list_xhmm_preds[data_list_xhmm_preds == "'DEL'"] = 0
    data_list_xhmm_preds[data_list_xhmm_preds == "'DUP'"] = 1


    data_list_xhmm_preds = to_categorical(data_list_xhmm_preds, num_classes =2)
    data_list_cnvnator_preds = to_categorical(data_list_cnvnator_preds, num_classes =3)

    data_list_readdepths = np.expand_dims(data_list_readdepths, axis=2)
    message("Polishing the samples, this may take time. For further information regarding working time, please check the paper.")

    polished = xhmm_polisher.predict([data_list_xhmm_preds, data_list_readdepths], verbose=1)

    notpolished = np.argmax(data_list_xhmm_preds, axis=1)
    notpolished[notpolished == 0] = 2
    pollabels = np.argmax(polished, axis=1)
    #truth = np.argmax(data_list_cnvnator_preds, axis=1)

    polished_versions = ['DUP' if v == 1 else 'DEL' if v == 2 else 'NO-CALL' for v in pollabels]
    not_polished_versions = ['DUP' if v == 1 else 'DEL' if v == 2 else 'NO-CALL' for v in notpolished]
    message("All given samples are polished. Writing corresponding output file for the polishing process to the output directory...")
    '''
    Prepare output file of DECoNT
    '''

    output_file_lines = []
    output_file_lines.append("Sample Name" + "\t" +"Chromosome" + "\t" + "CNV Start Index" + "\t" + "CNV End Index" + "\t" + "XHMM Prediction" + "\t" + "DECoNT Polished Prediction" + "\n")

    for i in range(len(data_list_sample_names)):
        sample_name = str(data_list_sample_names[i])
        chr_name = str(data_list_chr_names[i])
        start_ind = str(data_list_indexes[i][0])
        end_ind = str(data_list_indexes[i][1])
        xhmm_pred = str(not_polished_versions[i])
        decont_pred = str(polished_versions[i])
        line_to_write = sample_name + "\t" +chr_name + "\t" + start_ind + "\t" + end_ind + "\t" + xhmm_pred + "\t" + decont_pred + "\n"
        output_file_lines.append(line_to_write)

    decont_output_path = args.output
    if decont_output_path[-1] != '/':
        decont_output_path = decont_output_path + '/'

    decont_output_path = decont_output_path + "DECoNT_XHMM_polished_cnvs.txt"

    with open(decont_output_path, "a") as myfile:
        for row in output_file_lines:
            myfile.write(row)

    filelisttmp1 = os.listdir("../tmp/")
    filelisttmp2 = os.listdir("../tmp2/")
    filelisttmp3 = os.listdir("../tmp3/")

    for f in filelisttmp1:
        os.remove(os.path.join("../tmp/", f))
    for f in filelisttmp2:
        os.remove(os.path.join("../tmp2/", f))
    for f in filelisttmp3:
        os.remove(os.path.join("../tmp3/", f))

elif callername in ["CoNIFER", "CONIFER", "conifer", "Conifer"]: 
    if pretrained_flag:
        '''
        User has chosen to use pretrained DECoNT models for polishing. 
        Pretrained DECoNT models are stored in ../outputs/ directory.
        '''
        xhmm_polisher = load_model("../outputs/deepXCNV_batchnorm_bilstm128_batchnorm_dense100_dense3_bs256_padding-1_30epochs_traintestsplitted_weightedcrossent_xhmm.h5",
                        custom_objects=dependencies)
    else:
        xhmm_polisher = load_model(args.model, custom_objects = dependencies)

    data_path = "../tmp3/"

    data_list_readdepths = []
    data_list_indexes = []
    data_list_cnvnator_preds = []
    data_list_xhmm_preds = []
    data_list_sample_names = []
    data_list_chr_names = []

    files_list = os.listdir(data_path)

    for filename in files_list:
        with open(data_path+filename) as f:
            data = f.readlines()
            data = [x.strip() for x in data]
        sampname = [filename.split('.')[0].split('_')[1] for x in data] 
        chrname = [filename.split('.')[0].split('_')[0] for x in data]
        indexes = [(int(x.split(',')[1][1:]),int(x.split(',')[2][1:])) for x in data]
        xhmm_preds = [x.split(',')[3][1:] for x in data]
        cnvnator_preds = [x.split(',')[4][1:] for x in data]
        read_depth_seqs = [x.split(',')[5:] for x in data]
        read_depth_seqs = [[y.replace('[','',1).replace(']','').replace(' ','') for y in x] for x in read_depth_seqs]
        read_depth_seqs = [[0 if not y else int(str(y)) for y in x] for x in read_depth_seqs]
        data_list_indexes.extend(indexes)
        data_list_cnvnator_preds.extend(cnvnator_preds)
        data_list_xhmm_preds.extend(xhmm_preds)
        data_list_readdepths.extend(read_depth_seqs)
        data_list_sample_names.extend(sampname)
        data_list_chr_names.extend(chrname)

    #convert data lists to numpy arrays
    data_list_readdepths = np.asarray(data_list_readdepths)
    data_list_indexes = np.asarray(data_list_indexes)
    data_list_cnvnator_preds = np.asarray(data_list_cnvnator_preds)
    data_list_xhmm_preds = np.asarray(data_list_xhmm_preds)


    data_list_readdepths = sequence.pad_sequences(data_list_readdepths, value=-1, maxlen=8501)

    data_list_cnvnator_preds[data_list_cnvnator_preds == 'nan'] = 0
    data_list_cnvnator_preds[data_list_cnvnator_preds == "'<DUP>'"] = 1
    data_list_cnvnator_preds[data_list_cnvnator_preds == "'<DEL>'"] = 2


    data_list_xhmm_preds[data_list_xhmm_preds == "'DEL'"] = 0
    data_list_xhmm_preds[data_list_xhmm_preds == "'DUP'"] = 1


    data_list_xhmm_preds = to_categorical(data_list_xhmm_preds, num_classes =2)
    data_list_cnvnator_preds = to_categorical(data_list_cnvnator_preds, num_classes =3)

    data_list_readdepths = np.expand_dims(data_list_readdepths, axis=2)
    message("Polishing the samples, this may take time. For further information regarding working time, please check the paper.")

    polished = xhmm_polisher.predict([data_list_xhmm_preds, data_list_readdepths], verbose=1)

    notpolished = np.argmax(data_list_xhmm_preds, axis=1)
    notpolished[notpolished == 0] = 2
    pollabels = np.argmax(polished, axis=1)
    #truth = np.argmax(data_list_cnvnator_preds, axis=1)

    polished_versions = ['DUP' if v == 1 else 'DEL' if v == 2 else 'NO-CALL' for v in pollabels]
    not_polished_versions = ['DUP' if v == 1 else 'DEL' if v == 2 else 'NO-CALL' for v in notpolished]
    message("All given samples are polished. Writing corresponding output file for the polishing process to the output directory...")
    '''
    Prepare output file of DECoNT
    '''

    output_file_lines = []
    output_file_lines.append("Sample Name" + "\t" +"Chromosome" + "\t" + "CNV Start Index" + "\t" + "CNV End Index" + "\t" + "XHMM Prediction" + "\t" + "DECoNT Polished Prediction" + "\n")

    for i in range(len(data_list_sample_names)):
        sample_name = str(data_list_sample_names[i])
        chr_name = str(data_list_chr_names[i])
        start_ind = str(data_list_indexes[i][0])
        end_ind = str(data_list_indexes[i][1])
        xhmm_pred = str(not_polished_versions[i])
        decont_pred = str(polished_versions[i])
        line_to_write = sample_name + "\t" +chr_name + "\t" + start_ind + "\t" + end_ind + "\t" + xhmm_pred + "\t" + decont_pred + "\n"
        output_file_lines.append(line_to_write)

    decont_output_path = args.output
    if decont_output_path[-1] != '/':
        decont_output_path = decont_output_path + '/'

    decont_output_path = decont_output_path + "DECoNT_polished_cnvs.txt"

    with open(decont_output_path, "a") as myfile:
        for row in output_file_lines:
            myfile.write(row)

    filelisttmp1 = os.listdir("../tmp/")
    filelisttmp2 = os.listdir("../tmp2/")
    filelisttmp3 = os.listdir("../tmp3/")

    for f in filelisttmp1:
        os.remove(os.path.join("../tmp/", f))
    for f in filelisttmp2:
        os.remove(os.path.join("../tmp2/", f))
    for f in filelisttmp3:
        os.remove(os.path.join("../tmp3/", f))

elif callername in ["CODEX2", "Codex2", "codex2"]:  
    if pretrained_flag:
        '''
        User has chosen to use pretrained DECoNT models for polishing. 
        Pretrained DECoNT models are stored in ../outputs/ directory.
        '''
        xhmm_polisher = load_model("../outputs/deepXCNV_batchnorm_bilstm128_batchnorm_dense100_dense3_bs256_padding-1_30epochs_traintestsplitted_weightedcrossent_xhmm.h5",
                        custom_objects=dependencies)
    else:
        xhmm_polisher = load_model(args.model, custom_objects = dependencies)

    data_path = "../tmp3/"

    data_list_readdepths = []
    data_list_indexes = []
    data_list_cnvnator_preds = []
    data_list_xhmm_preds = []
    data_list_sample_names = []
    data_list_chr_names = []

    files_list = os.listdir(data_path)

    for filename in files_list:
        with open(data_path+filename) as f:
            data = f.readlines()
            data = [x.strip() for x in data]
        sampname = [filename.split('.')[0].split('_')[1] for x in data] 
        chrname = [filename.split('.')[0].split('_')[0] for x in data]
        indexes = [(int(x.split(',')[1][1:]),int(x.split(',')[2][1:])) for x in data]
        xhmm_preds = [x.split(',')[3][1:] for x in data]
        cnvnator_preds = [x.split(',')[4][1:] for x in data]
        read_depth_seqs = [x.split(',')[5:] for x in data]
        read_depth_seqs = [[y.replace('[','',1).replace(']','').replace(' ','') for y in x] for x in read_depth_seqs]
        read_depth_seqs = [[0 if not y else int(str(y)) for y in x] for x in read_depth_seqs]
        data_list_indexes.extend(indexes)
        data_list_cnvnator_preds.extend(cnvnator_preds)
        data_list_xhmm_preds.extend(xhmm_preds)
        data_list_readdepths.extend(read_depth_seqs)
        data_list_sample_names.extend(sampname)
        data_list_chr_names.extend(chrname)

    #convert data lists to numpy arrays
    data_list_readdepths = np.asarray(data_list_readdepths)
    data_list_indexes = np.asarray(data_list_indexes)
    data_list_cnvnator_preds = np.asarray(data_list_cnvnator_preds)
    data_list_xhmm_preds = np.asarray(data_list_xhmm_preds)


    data_list_readdepths = sequence.pad_sequences(data_list_readdepths, value=-1, maxlen=8501)

    data_list_cnvnator_preds[data_list_cnvnator_preds == 'nan'] = 0
    data_list_cnvnator_preds[data_list_cnvnator_preds == "'<DUP>'"] = 1
    data_list_cnvnator_preds[data_list_cnvnator_preds == "'<DEL>'"] = 2


    data_list_xhmm_preds[data_list_xhmm_preds == "'DEL'"] = 0
    data_list_xhmm_preds[data_list_xhmm_preds == "'DUP'"] = 1


    data_list_xhmm_preds = to_categorical(data_list_xhmm_preds, num_classes =2)
    data_list_cnvnator_preds = to_categorical(data_list_cnvnator_preds, num_classes =3)

    data_list_readdepths = np.expand_dims(data_list_readdepths, axis=2)
    message("Polishing the samples, this may take time. For further information regarding working time, please check the paper.")

    polished = xhmm_polisher.predict([data_list_xhmm_preds, data_list_readdepths], verbose=1)

    notpolished = np.argmax(data_list_xhmm_preds, axis=1)
    notpolished[notpolished == 0] = 2
    pollabels = np.argmax(polished, axis=1)
    #truth = np.argmax(data_list_cnvnator_preds, axis=1)

    polished_versions = ['DUP' if v == 1 else 'DEL' if v == 2 else 'NO-CALL' for v in pollabels]
    not_polished_versions = ['DUP' if v == 1 else 'DEL' if v == 2 else 'NO-CALL' for v in notpolished]
    message("All given samples are polished. Writing corresponding output file for the polishing process to the output directory...")
    '''
    Prepare output file of DECoNT
    '''

    output_file_lines = []
    output_file_lines.append("Sample Name" + "\t" +"Chromosome" + "\t" + "CNV Start Index" + "\t" + "CNV End Index" + "\t" + "XHMM Prediction" + "\t" + "DECoNT Polished Prediction" + "\n")

    for i in range(len(data_list_sample_names)):
        sample_name = str(data_list_sample_names[i])
        chr_name = str(data_list_chr_names[i])
        start_ind = str(data_list_indexes[i][0])
        end_ind = str(data_list_indexes[i][1])
        xhmm_pred = str(not_polished_versions[i])
        decont_pred = str(polished_versions[i])
        line_to_write = sample_name + "\t" +chr_name + "\t" + start_ind + "\t" + end_ind + "\t" + xhmm_pred + "\t" + decont_pred + "\n"
        output_file_lines.append(line_to_write)

    decont_output_path = args.output
    if decont_output_path[-1] != '/':
        decont_output_path = decont_output_path + '/'

    decont_output_path = decont_output_path + "DECoNT_polished_cnvs.txt"

    with open(decont_output_path, "a") as myfile:
        for row in output_file_lines:
            myfile.write(row)

    filelisttmp1 = os.listdir("../tmp/")
    filelisttmp2 = os.listdir("../tmp2/")
    filelisttmp3 = os.listdir("../tmp3/")

    for f in filelisttmp1:
        os.remove(os.path.join("../tmp/", f))
    for f in filelisttmp2:
        os.remove(os.path.join("../tmp2/", f))
    for f in filelisttmp3:
        os.remove(os.path.join("../tmp3/", f))

elif callername in ["Control-FREEC", "control-freec", "controlfreec","CONTROLFREEC"]:

    if pretrained_flag:
        '''
        User has chosen to use pretrained DECoNT models for polishing. 
        Pretrained DECoNT models are stored in ../outputs/ directory.
        '''
        freec_polisher = load_model("../outputs/deepXCNVfreec_batchnorm_bilstm128_batchnorm_dense100_dense1_bs256_padding-1_60epochs_traintestsplitted_mae.h5")
    else:
        freec_polisher = load_model(args.model, custom_objects = dependencies)

    data_path = "../tmp3/"

    data_list_readdepths = []
    data_list_indexes = []
    data_list_canavar_preds = []
    data_list_freec_preds = []
    data_list_sample_names = []
    data_list_chr_names = []

    files_list = os.listdir(data_path)

    for filename in tqdm(files_list):
        with open(data_path+filename) as f:
            data = f.readlines()
            data = [x.strip() for x in data]
        sampname = [filename.split('.')[0].split('_')[1] for x in data] 
        chrname = [filename.split('.')[0].split('_')[0] for x in data]
        indexes = [(int(x.split(',')[1][1:]),int(x.split(',')[2][1:])) for x in data]
        freec_preds = [x.split(',')[3][1:] for x in data]
        canavar_preds = [x.split(',')[4][1:] for x in data]
        read_depth_seqs = [x.split(',')[5:] for x in data]
        read_depth_seqs = [[y.replace('[','',1).replace(']','').replace(' ','') for y in x] for x in read_depth_seqs]
        read_depth_seqs = [[0 if not y else int(str(y)) for y in x] for x in read_depth_seqs]
        data_list_indexes.extend(indexes)
        data_list_canavar_preds.extend(canavar_preds)
        data_list_freec_preds.extend(freec_preds)
        data_list_readdepths.extend(read_depth_seqs)
        data_list_sample_names.extend(sampname)
        data_list_chr_names.extend(chrname)

    data_list_canavar_preds = [x.replace(']','') for x in data_list_canavar_preds]


    #convert data lists to numpy arrays
    data_list_readdepths = np.asarray(data_list_readdepths)
    data_list_indexes = np.asarray(data_list_indexes)
    data_list_canavar_preds = np.asarray(data_list_canavar_preds)
    data_list_freec_preds = np.asarray(data_list_freec_preds)


    data_list_readdepths = sequence.pad_sequences(data_list_readdepths, maxlen= 192000, value = -1)
    data_list_readdepths = [np.mean(x.reshape(-1, 100), axis=1) for x in data_list_readdepths]
    data_list_readdepths = np.asarray(data_list_readdepths)
    data_list_readdepths = np.expand_dims(data_list_readdepths, axis=2)
    polished_preds = freec_polisher.predict([data_list_freec_preds, data_list_readdepths], verbose=1)
    message("All given samples are polished. Writing corresponding output file for the polishing process to the output directory...")
    '''
    Prepare output file of DECoNT
    '''

    output_file_lines = []
    output_file_lines.append("Sample Name" + "\t" +"Chromosome" + "\t" + "CNV Start Index" + "\t" + "CNV End Index" + "\t" + "Control-FREEC Prediction" + "\t" + "DECoNT Polished Prediction" + "\n")
    for i in range(len(data_list_sample_names)):
        sample_name = str(data_list_sample_names[i])
        chr_name = str(data_list_chr_names[i])
        start_ind = str(data_list_indexes[i][0])
        end_ind = str(data_list_indexes[i][1])
        xhmm_pred = str(data_list_freec_preds[i])
        decont_pred = str(np.ceil(polished_preds[i]))
        line_to_write = sample_name + "\t" +chr_name + "\t" + start_ind + "\t" + end_ind + "\t" + xhmm_pred + "\t" + decont_pred + "\n"
        output_file_lines.append(line_to_write)

    decont_output_path = args.output
    if decont_output_path[-1] != '/':
        decont_output_path = decont_output_path + '/'

    decont_output_path = decont_output_path + "DECoNT_ControlFREEC_polished_cnvs.txt"

    with open(decont_output_path, "a") as myfile:
        for row in output_file_lines:
            myfile.write(row)

    filelisttmp1 = os.listdir("../tmp/")
    filelisttmp2 = os.listdir("../tmp2/")
    filelisttmp3 = os.listdir("../tmp3/")

    for f in filelisttmp1:
        os.remove(os.path.join("../tmp/", f))
    for f in filelisttmp2:
        os.remove(os.path.join("../tmp2/", f))
    for f in filelisttmp3:
        os.remove(os.path.join("../tmp3/", f))