#Marta Pla Diaz, May 26 (2021), for python2.7

# Using as input the files generated in the previous script: "sense_genes_pangenome.py", where the reading frame of each gene is obtained according to the gff files of each
# genome references used, with this script you will obtain 2 output files. In one file will be each gene besides of the number of stop codons that have each gene traslated separated by
# commaa, and in the other file will be the number of codons truncated by gene and by strain (also separated by comma). Then you should load this two files in excel,  
#indicating the separation of each cell by commas and then put the order of the strains as header according to the list below marked with ***

#inputs needed: the outputs of the script: "get_name_and_gene_sense.py" that have this ending: ".._genes_sense.txt"


#This function importa list of the files of the directory in which run you this script
from os import listdir


#This function get all the files that are in the path where you run this script
def ls(ruta = '.'):
    return listdir(ruta)


#This function get a python dictionary with the gene reading frame and its name
def pauta_lectura_de_gff(nomfichero_gff_Nichols):
    dicc_pauta_genes = {}
    fich = open(nomfichero_gff_Nichols, 'r')
    for line in fich:
        # con este if quitamos los retornos de carro
        if line.endswith('\n'):  # Alternativa a if line[-1] == "\n"
            line = line[:len(line) - 1]
        if line.endswith('\r'):  # Alternativa a if line[-1] == "\n"
            line = line[:len(line) - 1]
        line_div = line.split(" ")
        nombre_gen = line_div[0]
        dicc_pauta_genes[nombre_gen] = line_div[1]
    return dicc_pauta_genes

#function that loads a dictionary with the genetic code
def codigo_genetico():
   dicc_genetic_code =   {"ATA":"I", "ATC":"I", "ATT":"I", "ATG":"M",
"ACA":"T", "ACC":"T", "ACG":"T", "ACT":"T",
"AAC":"N", "AAT":"N", "AAA":"K", "AAG":"K",
"AGC":"S", "AGT":"S", "AGA":"R", "AGG":"R",
"CTA":"L", "CTC":"L", "CTG":"L", "CTT":"L",
"CCA":"P", "CCC":"P", "CCG":"P", "CCT":"P",
"CAC":"H", "CAT":"H", "CAA":"Q", "CAG":"Q",
"CGA":"R", "CGC":"R", "CGG":"R", "CGT":"R",
"GTA":"V", "GTC":"V", "GTG":"V", "GTT":"V",
"GCA":"A", "GCC":"A", "GCG":"A", "GCT":"A",
"GAC":"D", "GAT":"D", "GAA":"E", "GAG":"E",
"GGA":"G", "GGC":"G", "GGG":"G", "GGT":"G",
"TCA":"S", "TCC":"S", "TCG":"S", "TCT":"S",
"TTC":"F", "TTT":"F", "TTA":"L", "TTG":"L",
"TAC":"Y", "TAT":"Y", "TAA":"STOP", "TAG":"STOP",
"TGC":"C", "TGT":"C", "TGA":"STOP", "TGG":"W",}
   return dicc_genetic_code


#Function that opens the file with the alignment of complete genomes to be processed and from which we obtain the sequences
def abrir_fichero(nomfichero_align):
    secuencias = []
    fich =  open(nomfichero_align, 'r')
    seq = ""
    for line in fich:
        if line.endswith('\n'):  
            line = line[:len(line) - 1]
        if line.endswith('\r'): 
            line = line[:len(line) - 1]
        if line.startswith(">"):
            if seq != "":
                secuencias.append(seq)
                seq = ""
                secuencias.append(line)
            else:
                secuencias.append(line)
        else:
            seq = seq + line
    secuencias.append(seq)
    return secuencias


#This function create a python dictionary with the sequences in which the name of the genome is saved as a key and the genome
# sequence as the value
def crear_diccionario(lista):
    diccionario = {}
    contador = 0
    while contador < len(lista):
        if lista[contador].startswith(">"):
            new_clave = str(lista[contador].replace(">", ""))
            diccionario[new_clave] = ""
            clave = new_clave
            contador = contador + 1
        else:
            diccionario[clave] = lista[contador]
            contador = contador + 1
    return diccionario

def procesar_genes_traduccion(dicc_pauta_genes_Nichols,dicc_genetic_code,lista_genomas, dicc_seq, dicc_final_stops,
                              pauta_gen, dicc_final_truncados, nom_gen_cons):
    contador_genomas = 0
    while contador_genomas < len(lista_genomas):
        genoma = lista_genomas[contador_genomas]
        seq = dicc_seq[genoma]
        seq = seq.upper()
        if pauta_gen == "-":
            reverse_seq = reversa_complementaria(seq)
            contador_codon_base1 = 0
            contador_codon_base2 = 1
            contador_codon_base3 = 2
            contador_truncados = 0
            contador_stops = 0
            conta_codon = 0
            while contador_codon_base3 < len(reverse_seq):
                codon = str(reverse_seq[contador_codon_base1]) + str(reverse_seq[contador_codon_base2]) + str(reverse_seq[contador_codon_base3])
                contador_codon_base1 += 3
                contador_codon_base2 += 3
                contador_codon_base3 += 3
                if "N" in codon or "-" in codon or "Y" in codon or "B" in codon or "M" in codon or "R" in codon or "S" in codon:
                    contador_truncados += 1
                else:
                    aa_cons = dicc_genetic_code[codon]
                    if aa_cons == "STOP":
                        contador_stops += 1
                conta_codon += 1
            if nom_gen_cons in dicc_final_stops:
                dicc_final_stops[nom_gen_cons] = dicc_final_stops[nom_gen_cons] + "," + str(contador_stops)
            else:
                dicc_final_stops[nom_gen_cons] = str(contador_stops)
            if nom_gen_cons in dicc_final_truncados:
                dicc_final_truncados[nom_gen_cons] = dicc_final_truncados[nom_gen_cons] + "," + str(contador_truncados)
            else:
                dicc_final_truncados[nom_gen_cons] = str(contador_truncados)
        else:
            contador_codon_base1 = 0
            contador_codon_base2 = 1
            contador_codon_base3 = 2
            contador_truncados = 0
            contador_stops = 0
            conta_codon = 0
            while contador_codon_base3 < len(seq):
                codon = str(seq[contador_codon_base1]) + str(seq[contador_codon_base2]) + str(
                    seq[contador_codon_base3])
                contador_codon_base1 += 3
                contador_codon_base2 += 3
                contador_codon_base3 += 3
                if "N" in codon or "-" in codon or "Y" in codon or "B" in codon or "M" in codon or "R" in codon or "S" in codon:
                    contador_truncados += 1
                else:
                    aa_cons = dicc_genetic_code[codon]
                    if aa_cons == "STOP":
                        contador_stops += 1
                conta_codon += 1
            if nom_gen_cons in dicc_final_stops:
                dicc_final_stops[nom_gen_cons] = dicc_final_stops[nom_gen_cons] + "," + str(contador_stops)
            else:
                dicc_final_stops[nom_gen_cons] = str(contador_stops)
            if nom_gen_cons in dicc_final_truncados:
                dicc_final_truncados[nom_gen_cons] = dicc_final_truncados[nom_gen_cons] + "," + str(contador_truncados)
            else:
                dicc_final_truncados[nom_gen_cons] = str(contador_truncados)
        contador_truncados = 0
        contador_stops = 0
        contador_genomas+=1
    return dicc_final_truncados, dicc_final_stops

#This function generate the final file which contains all the genes annotated in each ref genome used
# and the numbers of stop codons or truncated codons per strain for each gene
def archivo_final(dicc_final_truncados, dicc_final_stops):
    nom_fichero_final_cod_stop = "num_codones_stop_per_gene"
    nom_fichero_final_cod_trunc = "num_codones_trunc_per_gene"
    print "\n---> Generando el fichero con el numero de codones de stop por gen y cepa...\n"
    fich = open(nom_fichero_final_cod_stop, "w")
    for gen in dicc_final_stops:
        fich.write(str(gen) + "," + str(dicc_final_stops[gen]) + "\n")
    print "\n---> Generando el fichero con el numero de codones truncados por gen y cepa...\n"
    fich = open(nom_fichero_final_cod_trunc, "w")
    for gen in dicc_final_truncados:
        fich.write(str(gen) + "," + str(dicc_final_truncados[gen]) + "\n")

#This function calculate the complementary reverse sequence of a sequence
def reversa_complementaria(seq):
    complement = {'A': 'T', 'C': 'G', 'G': 'C', 'T': 'A', 'N': 'N', '-': '-', 'Y': 'Y', 'B': 'B', 'M': 'M', 'R': 'R',
                  'S': 'S' }
    return ''.join([complement[base] for base in seq[::-1]])

def main():
    #To change it each time:
    nomfichero_gensense_Nichols = "genes_pangenome_25_05_21_genes_sense.txt"
    #nomfichero_gensense_BosniaA = "BosniaA_NCBI_genes_sense.txt"
    #nomfichero_gensense_CDC2 = "CDC2_NCBI_genes_sense.txt"
    #nomfichero_gensense_SS14 = "SS14_NCBI_genes_sense.txt"
    dicc_pauta_genes_Nichols = pauta_lectura_de_gff(nomfichero_gensense_Nichols)
    lista_genomas = ["SamoaD_real", "94A_SS14_mapp","CZ34_SS14_mapp","CZ27_SS14_mapp","SW8_SS14_mapp","NKNP1_CDC2_map",
                     "R8-KOS-007_CDC2_map","IND1_CDC2_map","133_CDC2_map","C3_SS14_mapp","UZ1974_SS14_mapp",
                     "WP0022.7.scab_CDC2_map","GHA1_CDC2_map","NL11_SS14_mapp","UW824B_SS14_mapp","Nichols_real",
                     "AU16_SS14_mapp","PT_SIF1242_SS14_mapp","UW370B_SS14_mapp","CW59__Nichols_mapp","CDC2_real",
                     "MexicoA_real","AR2_SS14_mapp","WP0022.7.liq_CDC2_map","Chicago_real","SJ003_CDC2_map","K3_SS14_mapp",
                     "BAL73_Nichols_mapp","AGU007_CDC2_map","Fribourg_real","K363_real","PT_SIF1156_SS14_mapp",
                     "NE20_Nichols_mapp","OKA_2116_CDC2_map","HATO_CDC2_map","Gauthier_real","SS14_real","SEA86_Nichols_mapp",
                     "BAK_2117_CDC2_map","GRA2_SS14_mapp","CW82_Nichols_mapp","SHD-R_SS14_mapp","CZ33_SS14_mapp","NE17_SS14_mapp",
                     "CW85_SS14_mapp","94B_SS14_mapp","PT_SIF1196_SS14_mapp","PD28_SS14_mapp","BosniaA_real","W86_Nichols_mapp",
                     "SW1_SS14_mapp","W86_SS14_mapp","CW86_Nichols_mapp","NL10_SS14_mapp","Boe_92_CDC2_map","LMNP-1_real",
                     "NL16_SS14_mapp","AU17_SS14_mapp","NE15_SS14_mapp","SW4_SS14_mapp","SW6_SS14_mapp","NE19_SS14_mapp",
                     "AU15_SS14_mapp","CHS119_CDC2_map","K403_real","CW65__Nichols_mapp","CW84_SS14_mapp","Sea_81-4_real",
                     "BAL3_Nichols_mapp","SJ219_SS14_mapp","Iraq B_real","UW116B_SS14_mapp","P3_SS14_mapp","UW337B_SS14_mapp",
                     "CDC_2575_real","NIC2_Nichols_mapp","R3-SAL-007_CDC2_map","CW83_Nichols_mapp","NL14_Nichols_mapp",
                     "PT_SIF1020_SS14_mapp"]
    dicc_genetic_code = codigo_genetico()
    lista_archivos = ls()
    dicc_final_stops ={}
    dicc_final_truncados ={}
    for i in lista_archivos:
        if i.endswith(".fas"):
            nom_gen= str(i)
            nom_gen_cons = nom_gen[:len(nom_gen) - 4]
            pauta_gen = dicc_pauta_genes_Nichols[nom_gen]
            secuencias = abrir_fichero(nom_gen)
            dicc_seq = crear_diccionario(secuencias)
            dicc_final_truncados, dicc_final_stops =procesar_genes_traduccion(dicc_pauta_genes_Nichols,dicc_genetic_code,lista_genomas, dicc_seq, dicc_final_stops,pauta_gen, dicc_final_truncados, nom_gen_cons)
    archivo_final(dicc_final_truncados, dicc_final_stops)

if __name__ == '__main__':
    main()
