Source code for ensembl.tools.anno.transcriptomic_annotation.augustus

# pylint: skip-file
# start gene g1 #pylint: disable=line-too-long
# 1       AUGUSTUS        gene    1       33908   1       +       .       g1
# 1       AUGUSTUS        transcript      1       33908   .       +       .       g1.t1
# 1       AUGUSTUS        CDS     3291    3585    .       +       2       transcript_id "g1.t1"; gene_id "g1";
# 1       AUGUSTUS        exon    3291    3585    .       +       .       transcript_id "g1.t1"; gene_id "g1";
# 1       AUGUSTUS        CDS     11377   11510   .       +       1       transcript_id "g1.t1"; gene_id "g1";
# 1       AUGUSTUS        exon    11377   11510   .       +       .       transcript_id "g1.t1"; gene_id "g1";
# 1       AUGUSTUS        CDS     30726   30871   .       +       2       transcript_id "g1.t1"; gene_id "g1";
# 1       AUGUSTUS        exon    30726   30871   .       +       .       transcript_id "g1.t1"; gene_id "g1";
# 1       AUGUSTUS        CDS     32975   33502   .       +       0       transcript_id "g1.t1"; gene_id "g1";
# 1       AUGUSTUS        exon    32975   33908   .       +       .       transcript_id "g1.t1"; gene_id "g1";
# 1       AUGUSTUS        stop_codon      33500   33502   .       +       0       transcript_id "g1.t1"; gene_id "g1";
# 1       AUGUSTUS        tts     33908   33908   .       +       .       transcript_id "g1.t1"; gene_id "g1";
# protein sequence = [GGRGEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEKKEKKEEEEEEEEEEEEEEEK
# EEGEGMEGRDIMGIRGKQKQPRKQPELSSSFPTFLLTQKTPYCPESIKLLLILRNNIQTIVFYKGPKGVINDWRKFKLESEDGDSIPPSKKEILRQMS
# SPQSRDDSKERMSRKMSIQEYELIHQDKEDESCLRKYRRQCMQDMHQKLSFGPRYGFVYELETGEQFLETIEKEQKVTTIVVNIYEDGVRGCDALNSS
# LACLAVEYPMVKFCKIKASNTGAGDRFSTDVLPTLLVYKGGELISNFISVAEQFAEEFFAVDVESFLNEYGLLPEREIHDLEQTNMEDEDIE]
# Evidence for and against this transcript:
# % of transcript supported by hints (any source): 0
# CDS exons: 0/4
# CDS introns: 0/4
# 5'UTR exons and introns: 0/0
# 3'UTR exons and introns: 0/1
# hint groups fully obeyed: 0
# incompatible hint groups: 0
# end gene g1
###


[docs] def augustus_output_to_gtf(augustus_output_dir, augustus_genome_dir): gtf_file_path = os.path.join(augustus_output_dir, "annotation.gtf") gtf_out = open(gtf_file_path, "w+") record_count = 1 for gff_file_path in glob.glob(augustus_genome_dir + "/*.aug"): gff_file_name = os.path.basename(gff_file_path) match = re.search(r"\.rs(\d+)\.re(\d+)\.", gff_file_name) start_offset = int(match.group(1)) exon_number = 1 current_exon_hints_total = 0 current_exon_hints_match = 0 current_intron_hints_total = 0 current_intron_hints_match = 0 current_record = [] gff_in = open(gff_file_path, "r") line = gff_in.readline() while line: match = re.search(r"# CDS exons\: (\d+)\/(\d+)", line) if match: current_exon_hints_match = match.group(1) current_exon_hints_total = match.group(2) match = re.search(r"# CDS introns\: (\d+)\/(\d+)", line) if match: current_introns_hints_match = match.group(1) current_introns_hints_total = match.group(2) if re.search(r"# end gene", line): for output_line in current_record: gtf_out.write(output_line) current_record = [] current_exon_hints_total = 0 current_exon_hints_match = 0 current_intron_hints_total = 0 current_intron_hints_match = 0 record_count += 1 exon_number = 1 values = line.split("\t") if ( len(values) == 9 and values[1] == "AUGUSTUS" and (values[2] == "transcript" or values[2] == "exon") ): values[3] = str(int(values[3]) + (start_offset - 1)) values[4] = str(int(values[4]) + (start_offset - 1)) values[8] = ( 'gene_id "aug' + str(record_count) + '"; transcript_id "aug' + str(record_count) + '";' ) if values[2] == "exon": values[8] = values[8] + ' exon_number "' + str(exon_number) + '";' exon_number += 1 values[8] = values[8] + "\n" current_record.append("\t".join(values)) line = gff_in.readline() gff_in.close() gtf_out.close()
[docs] def run_augustus_predict(augustus_path, main_output_dir, masked_genome_file, num_threads): min_seq_length = 1000 if not augustus_path: augustus_path = config["augustus"]["software"] bam2hints_path = config["augustus"]["bam2hints_path"] bam2wig_path = config["augustus"]["bam2wig_path"] wig2hints_path = config["augustus"]["wig2hints_path"] utils.check_exe(augustus_path) # Run bam2hints, bam2wig, wig2hints, then combine the hints into a single file # Multiprocess with all three steps in the MP as that would be fastest augustus_dir = utils.create_dir(main_output_dir, "augustus_output") augustus_hints_dir = utils.create_dir(augustus_dir, "hints") augustus_genome_dir = utils.create_dir(augustus_dir, "genome_dir") augustus_evidence_dir = utils.create_dir(augustus_dir, "evidence") augustus_hints_file = os.path.join(augustus_evidence_dir, "augustus_hints.gff") star_dir = os.path.join(main_output_dir, "star_output") minimap2_output_dir = os.path.join(main_output_dir, "minimap2_output") if os.path.exists(star_dir): logger.info("Found a Star output dir, generating hints from any .sj.tab files") generate_hints( bam2hints_path, bam2wig_path, wig2hints_path, augustus_hints_dir, star_dir, num_threads, ) hints_out = open(augustus_hints_file, "w+") for gff_file in glob.glob(augustus_hints_dir + "/*.bam.hints.gff"): gff_in = open(gff_file, "r") line = gff_in.readline() while line: hints_out.write(line) line = gff_in.readline() gff_in.close() hints_out.close() seq_region_lengths = utils.get_seq_region_lengths(genome_file, 5000) slice_ids = utils.create_slice_ids(seq_region_lengths, 1000000, 100000, 5000) generic_augustus_cmd = [ augustus_path, "--species=human", "--UTR=on", ( "--extrinsicCfgFile=" + "/hps/nobackup2/production/ensembl/jma/src/Augustus/" "config/extrinsic/extrinsic.M.RM.E.W.P.cfg" ), ] pool = multiprocessing.Pool(int(num_threads)) tasks = [] for slice_id in slice_ids: pool.apply_async( multiprocess_augustus_id, args=( generic_augustus_cmd, slice_id, masked_genome_file, augustus_hints_file, augustus_genome_dir, ), ) pool.close() pool.join() augustus_output_to_gtf(augustus_dir, augustus_genome_dir)
[docs] def generate_hints( bam2hints_path, bam2wig_path, wig2hints_path, augustus_hints_dir, star_dir, num_threads, ): pool = multiprocessing.Pool(int(num_threads)) for bam_file in glob.glob(star_dir + "/*.bam"): pool.apply_async( multiprocess_augustus_hints, args=( bam2hints_path, bam2wig_path, wig2hints_path, bam_file, augustus_hints_dir, ), ) pool.close() pool.join()
[docs] def multiprocess_augustus_hints(bam2hints_path, bam2wig_path, wig2hints_path, bam_file, augustus_hints_dir): bam_file_name = os.path.basename(bam_file) logger.info("Processing " + bam_file_name + " for Augustus hints") bam2hints_file_name = bam_file_name + ".hints.gff" bam2hints_file_path = os.path.join(augustus_hints_dir, bam2hints_file_name) bam2hints_cmd = [ bam2hints_path, ("--in=" + bam_file), ("--out=" + bam2hints_file_path), "--maxintronlen=100000", ] logger.info("bam2hints command:\n" + " ".join(bam2hints_cmd)) subprocess.run(bam2hints_cmd)
# bam2wig_cmd = [bam2wig_path,'-D',augustus_hints_dir,bam_file] # print("bam2wig command:\n" + ' '.join(bam2wig_cmd)) # subprocess.run(bam2wig_cmd) # wig2hints is odd in that it runs directly off STDIN and then just prints to STDOUT, # so the code below is implemented in steps as it's not good practice to use pipes and # redirects in a subprocess command # wig_file_name = re.sub('.bam','.wig',bam_file_name) # wig_file_path = os.path.join(augustus_hints_dir,wig_file_name) # wig_hints_file_name = (wig_file_name + '.hints.gff') # wig_hints_file_path = os.path.join(augustus_hints_dir,wig_hints_file_name) # print("Writing wig file info to hints file:\n" + wig_hints_file_name) # wig2hints_out = open(wig_hints_file_path,'w+') # wigcat = subprocess.Popen(('cat',wig_file_path), stdout=subprocess.PIPE) # subprocess.run(wig2hints_path, stdin=wigcat.stdout, stdout=wig2hints_out) # wig2hints_out.close()
[docs] def multiprocess_augustus_id(cmd, slice_id, genome_file, hints_file, output_dir): region = slice_id[0] start = slice_id[1] end = slice_id[2] seq = utils.get_sequence(region, start, end, 1, genome_file, output_dir) region_fasta_file_name = region + ".rs" + str(start) + ".re" + str(end) + ".fa" region_fasta_file_path = os.path.join(output_dir, region_fasta_file_name) region_augustus_file_path = os.path.join(output_dir, (region_fasta_file_name + ".aug")) region_fasta_out = open(region_fasta_file_path, "w+") region_fasta_out.write(">" + region + "\n" + seq + "\n") region_fasta_out.close() region_hints_file = create_slice_hints_file(region, start, end, hints_file, region_fasta_file_path) aug_out = open(region_augustus_file_path, "w+") augustus_forward = cmd.copy() augustus_forward.append(("--hintsfile=" + region_hints_file)) augustus_forward.append("--strand=forward") augustus_forward.append(region_fasta_file_path) subprocess.run(augustus_forward, stdout=aug_out) augustus_backward = cmd.copy() augustus_backward.append(("--hintsfile=" + region_hints_file)) augustus_backward.append("--strand=backward") augustus_backward.append(region_fasta_file_path) subprocess.run(augustus_backward, stdout=aug_out) aug_out.close()
[docs] def create_slice_hints_file(region, start, end, hints_file, region_fasta_file_path): # Note this is trying to be memory and file efficient at the cost of speed # So files are only created as needed and the hints are # being read line by line as written as needed # This comes with the downside of being slow, but it's # only a very small amount of time relative # to how slow the step is in total. Given that this step # in general eats up a low of memory, saving as much # as possible here is not a bad thing even if it's adding # in an overhead by continuously reading the hints file region_hints_file_path = region_fasta_file_path + ".gff" hints_in = open(hints_file) hints_out = open(region_hints_file_path, "w+") hint_line = hints_in.readline() while hint_line: hint_line_values = hint_line.split("\t") if not len(hint_line_values) == 9: hint_line = hints_in.readline() continue hint_region = hint_line_values[0] hint_region_start = int(hint_line_values[3]) hint_region_end = int(hint_line_values[4]) if hint_region == region and hint_region_start >= start and hint_region_end <= end: hint_line_values[3] = str(int(hint_line_values[3]) - (start - 1)) hint_line_values[4] = str(int(hint_line_values[4]) - (start - 1)) hints_out.write("\t".join(hint_line_values)) hint_line = hints_in.readline() hints_in.close() hints_out.close() return region_hints_file_path