@dxpy.entry_point('main')
def importGTF(**args):

    if len(args) == 0:
        command_line_args = parser.parse_args(sys.argv[1:])
        fileName = command_line_args.fileName
        reference = command_line_args.reference
        outputName = command_line_args.outputName
        tag = command_line_args.tag
        property_key = command_line_args.property_key
        property_value = command_line_args.property_value
        additional_type = command_line_args.additional_type
        file_id = command_line_args.file_id
    else:
        fileName = args['fileName']
        reference = args['reference']
        outputName = ''
        if args.get('outputName') != None:
            outputName = args['outputName']
        tag = []
        if args.get('tag'):
            tag = args['tag']
        if args.get('property_key') != None:
            property_key = args['property_key']
        if args.get('property_value') != None:
            property_value = args['property_value']
        if args.get('additional_type') != None:
            additional_type = args['additional_type']
        if args.get('file_id') != None:
            file_id = args['file_id']

    inputFileName = unpack(fileName)

    capturedTypes = {"5UTR": "5' UTR", "3UTR": "3' UTR", "CDS": "CDS", "inter": "intergenic", "inter_CNS": "intergenic_conserved", "intron_CNS": "intron_conserved", "exon": "exon", "transcript": "transcript", "gene":"gene", "stop_codon": "stop_codon", "start_codon":"start_codon"}
    
    #Rows of this type will not be written to the gtable as their information is fully encompassed by the rest of the data

    ##Isolate the attribute tags from the file and check integrity
    spansTable, additionalColumns = constructTable(inputFileName)
    spansTable.add_tags(tag)

    types = ["Genes", "gri"]
    for x in additional_type:
        types.append(x)
    spansTable.add_types(types)
    details = {'original_contigset': dxpy.dxlink(reference)}

    if len(property_key) != len(property_value):
        raise dxpy.AppError("Expected each provided property to have a corresponding value")
    for i in range(len(property_key)):
        details[property_key[i]] = property_value[i]
    for x in additional_type:
        types.append(x)

    if file_id != None:
        details['original_file'] = dxpy.dxlink(file_id)
    spansTable.set_details(details)
    if outputName == '':
        spansTable.rename(fileName)
    else:
        spansTable.rename(outputName)

    #This passes through the file calculates the gene and transcript models 
    genes = {}
    transcripts = {}
    spanId = 0
    frames = {}
    stopCodons = {}
    

    inputFile = open(inputFileName, 'r')
    for line in inputFile:
        if line[0] != "#":
            values = parseLine(line, capturedTypes)

            if values["type"] == "CDS":
                if frames.get(values["transcriptId"]) == None:
                    frames[values["transcriptId"]] = {}
                frames[values["transcriptId"]][values["lo"]] = values["frame"]
                
            for [element, hashId, elementType] in [[genes, values["geneId"], "geneName"], [transcripts, values["transcriptId"], "transcriptName"]]:   

                if element.get(hashId) == None:
                    element[hashId] = {values["chromosome"]: {"lo":values["lo"], "hi":values["hi"], "codingLo": -1, "codingHi": -1, "strand":values["strand"], "score":values["score"], "geneId":values["geneId"], "coding":False, "spanId": spanId, "name":values[elementType], "originalGeneId": values["attributes"]["gene_id"], "originalTranscriptId": values["attributes"]["transcript_id"]}}
                    spanId += 1
                elif element[hashId].get(values["chromosome"]) == None:
                    element[hashId][values["chromosome"]] = {"lo":values["lo"], "hi":values["hi"], "codingLo": -1, "codingHi": -1, "strand":values["strand"], "score":values["score"], "geneId":values["geneId"], "coding":False, "spanId": spanId, "name":values[elementType], "originalGeneId": values["attributes"]["gene_id"], "originalTranscriptId": values["attributes"]["transcript_id"]}
                    spanId += 1
                else:
                    if values["lo"] < element[hashId][values["chromosome"]]["lo"]:
                        element[hashId][values["chromosome"]]["lo"] = values["lo"]
                    if values["hi"] > element[hashId][values["chromosome"]]["hi"]:
                        element[hashId][values["chromosome"]]["hi"] = values["hi"]

            if values["type"] == "stop_codon":
                if stopCodons.get(values["transcriptId"]) == None:
                    stopCodons[values["transcriptId"]] = [[values["lo"], values["hi"]]]
                else:
                    stopCodons[values["transcriptId"]].append([values["lo"], values["hi"]])

            if values["type"] == "CDS" or values["type"] == "start_codon" or values["type"] == "stop_codon":
                if values["hi"] > transcripts[values["transcriptId"]][values["chromosome"]]["codingHi"]:
                    transcripts[values["transcriptId"]][values["chromosome"]]["codingHi"] = values["hi"]
                if values["lo"] < transcripts[values["transcriptId"]][values["chromosome"]]["codingLo"] or transcripts[values["transcriptId"]][values["chromosome"]]["codingLo"] == -1:
                    transcripts[values["transcriptId"]][values["chromosome"]]["codingLo"] = values["lo"]
                genes[values["geneId"]][values["chromosome"]]["coding"] = True
                transcripts[values["transcriptId"]][values["chromosome"]]["coding"] = True

    for gId, chrList in genes.iteritems():
        for k, v in chrList.iteritems():
            entry = [k, v["lo"], v["hi"], v["name"], v["spanId"], "gene", v["strand"], v["score"], v["coding"], -1, -1, '', '', v["originalGeneId"], '']
            for x in additionalColumns:
                if x != "gene_id" and x != "transcript_id":
                    entry.append('')
            spansTable.add_rows([entry])
    for gId, chrList in transcripts.iteritems():
        for k, v in chrList.iteritems():
            entry = [k, v["lo"], v["hi"], v["name"], v["spanId"], "transcript", v["strand"], v["score"], genes[v["geneId"]][k]["coding"], genes[v["geneId"]][k]["spanId"], -1, '', '', v["originalGeneId"], v["originalTranscriptId"]]
            for x in additionalColumns:
                if x != "gene_id" and x != "transcript_id":
                    entry.append('')
            spansTable.add_rows([entry])

    exons = {}
    inputFile = open(inputFileName, 'r')
    
    for line in inputFile:
        if line[0] != "#":
            values = parseLine(line, capturedTypes)

            if exons.get(values["transcriptId"]) != None:
                if exons[values["transcriptId"]].get(values["chromosome"]) == None:
                    exons[values["transcriptId"]][values["chromosome"]] = []
            else:
                exons[values["transcriptId"]] = {values["chromosome"] : []}

            if capturedTypes.get(values["type"]) != None:
                #If type is 5'UTR, 3'UTR, intergenic, or conserved intron, type is always noncoding
                if values["type"] == "5UTR" or values["type"] == "3UTR" or values["type"] == "inter" or values["type"] == "inter_CNS" or values["type"] == "intron_CNS":
                    writeEntry(spansTable, spanId, exons[values["transcriptId"]], additionalColumns, values["chromosome"], values["lo"], values["hi"], values["attributes"], [values["chromosome"], values["lo"], values["hi"], values["name"], spanId, capturedTypes[values["type"]], values["strand"], values["score"], False, transcripts[values["transcriptId"]]["spanId"], values["frame"], '', values["source"]])

                if "exon_number" in values["attributes"]:
                    values["transcriptName"] += "." + values["attributes"]["exon_number"]

                #If type is CDS, always of type coding
                if values["type"] == "CDS":
                    if stopCodons.get(values["transcriptId"]) != None:
                        for x in stopCodons[values["transcriptId"]]:
                            if values["hi"] == x[0]:
                                values["hi"] = x[1]
                                break                            
                    if [values["lo"], values["hi"]] not in exons[values["transcriptId"]][values["chromosome"]]:
                        spanId = writeEntry(spansTable, spanId, exons[values["transcriptId"]], additionalColumns, values["chromosome"], values["lo"], values["hi"], values["attributes"], [values["chromosome"], values["lo"], values["hi"], values["transcriptName"], spanId, capturedTypes[values["type"]], values["strand"], values["score"], True, transcripts[values["transcriptId"]][values["chromosome"]]["spanId"], values["frame"], '', values["source"]])

                #If type is exon do calculation as to whether coding or non-coding
                if values["type"] == "stop_codon":
                    values["type"] = "exon"
                    values["frame"] = 3 - (values["hi"] - values["lo"])
                    #if values["strand"] == "-":
                    #    values["lo"] = transcripts[values["transcriptId"]][values["chromosome"]]["lo"]
                    #else:
                    #    values["hi"] = transcripts[values["transcriptId"]][values["chromosome"]]["hi"]
                    
                if values["type"] == "exon":
                    if (transcripts[values["transcriptId"]][values["chromosome"]]["codingLo"] != -1 and transcripts[values["transcriptId"]][values["chromosome"]]["codingHi"] != -1):
                        if frames.get(values["transcriptId"]) != None:
                            if frames[values["transcriptId"]].get(values["lo"]) != None:
                                values["frame"] = frames[values["transcriptId"]][values["lo"]]

                        for x in splitExons(transcripts[values["transcriptId"]], values["chromosome"], values["lo"], values["hi"], values["strand"]):
                            spanId = writeEntry(spansTable, spanId, exons[values["transcriptId"]], additionalColumns, values["chromosome"], x[1], x[2], values["attributes"], [values["chromosome"], x[1], x[2], values["transcriptName"], spanId, x[0], values["strand"], values["score"], x[3], transcripts[values["transcriptId"]][values["chromosome"]]["spanId"], values["frame"], '', values["source"]])
                    else:
                        spanId = writeEntry(spansTable, spanId, exons[values["transcriptId"]], additionalColumns, values["chromosome"], values["lo"], values["hi"], values["attributes"],  [values["chromosome"], values["lo"], values["hi"], values["transcriptName"], spanId, capturedTypes[values["type"]], values["strand"], values["score"], False, transcripts[values["transcriptId"]][values["chromosome"]]["spanId"], values["frame"], '', values["source"]])

    spansTable.flush()
    spansTable.close()
    outputFile = open("result.txt", 'w')
    outputFile.write(spansTable.get_id())
    outputFile.close()
    print(spansTable.get_id())
    return spansTable.get_id()
dataset/ETHPy150Open dnanexus/dx-toolkit/src/python/dxpy/scripts/dx_gtf_to_genes.py/importGTF/original