mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-10-25 10:24:38 +08:00
232 lines
8.7 KiB
Python
232 lines
8.7 KiB
Python
#!/usr/bin/env python
|
|
"""
|
|
Reads an interval or gene BED and a MAF Source.
|
|
Produces a FASTA file containing the aligned intervals/gene sequences, based upon the provided coordinates
|
|
|
|
Alignment blocks are layered ontop of each other based upon score.
|
|
|
|
usage: %prog maf_file [options]
|
|
-d, --dbkey=d: Database key, ie hg17
|
|
-c, --chromCol=c: Column of Chr
|
|
-s, --startCol=s: Column of Start
|
|
-e, --endCol=e: Column of End
|
|
-S, --strandCol=S: Column of Strand
|
|
-G, --geneBED: Input is a Gene BED file, process and join exons as one region
|
|
-t, --mafSourceType=t: Type of MAF source to use
|
|
-m, --mafSource=m: Path of source MAF file, if not using cached version
|
|
-I, --mafIndex=I: Path of precomputed source MAF file index, if not using cached version
|
|
-i, --interval_file=i: Input interval file
|
|
-o, --output_file=o: Output MAF file
|
|
-p, --species=p: Species to include in output
|
|
-O, --overwrite_with_gaps=O: Overwrite bases found in a lower-scoring block with gaps interior to the sequence for a species.
|
|
-z, --mafIndexFileDir=z: Directory of local maf_index.loc file
|
|
|
|
usage: %prog dbkey_of_BED comma_separated_list_of_additional_dbkeys_to_extract comma_separated_list_of_indexed_maf_files input_gene_bed_file output_fasta_file cached|user GALAXY_DATA_INDEX_DIR
|
|
"""
|
|
# Dan Blankenberg
|
|
from __future__ import print_function
|
|
|
|
import sys
|
|
|
|
import bx.intervals.io
|
|
from bx.cookbook import doc_optparse
|
|
|
|
from galaxy.tools.util import maf_utilities
|
|
|
|
|
|
def stop_err(msg):
|
|
sys.exit(msg)
|
|
|
|
|
|
def __main__():
|
|
# Parse Command Line
|
|
options, args = doc_optparse.parse(__doc__)
|
|
mincols = 0
|
|
strand_col = -1
|
|
|
|
if options.dbkey:
|
|
primary_species = options.dbkey
|
|
else:
|
|
primary_species = None
|
|
if primary_species in [None, "?", "None"]:
|
|
stop_err(
|
|
"You must specify a proper build in order to extract alignments. You can specify your genome build by clicking on the pencil icon associated with your interval file."
|
|
)
|
|
|
|
include_primary = True
|
|
secondary_species = maf_utilities.parse_species_option(options.species)
|
|
if secondary_species:
|
|
species = list(secondary_species) # make copy of species list
|
|
if primary_species in secondary_species:
|
|
secondary_species.remove(primary_species)
|
|
else:
|
|
include_primary = False
|
|
else:
|
|
species = None
|
|
|
|
if options.interval_file:
|
|
interval_file = options.interval_file
|
|
else:
|
|
stop_err("Input interval file has not been specified.")
|
|
|
|
if options.output_file:
|
|
output_file = options.output_file
|
|
else:
|
|
stop_err("Output file has not been specified.")
|
|
|
|
if not options.geneBED:
|
|
if options.chromCol:
|
|
chr_col = int(options.chromCol) - 1
|
|
else:
|
|
stop_err(
|
|
"Chromosome column not set, click the pencil icon in the history item to set the metadata attributes."
|
|
)
|
|
|
|
if options.startCol:
|
|
start_col = int(options.startCol) - 1
|
|
else:
|
|
stop_err("Start column not set, click the pencil icon in the history item to set the metadata attributes.")
|
|
|
|
if options.endCol:
|
|
end_col = int(options.endCol) - 1
|
|
else:
|
|
stop_err("End column not set, click the pencil icon in the history item to set the metadata attributes.")
|
|
|
|
if options.strandCol:
|
|
strand_col = int(options.strandCol) - 1
|
|
|
|
mafIndexFile = "%s/maf_index.loc" % options.mafIndexFileDir
|
|
|
|
overwrite_with_gaps = True
|
|
if options.overwrite_with_gaps and options.overwrite_with_gaps.lower() == "false":
|
|
overwrite_with_gaps = False
|
|
|
|
# Finish parsing command line
|
|
|
|
# get index for mafs based on type
|
|
index = index_filename = None
|
|
# using specified uid for locally cached
|
|
if options.mafSourceType.lower() in ["cached"]:
|
|
index = maf_utilities.maf_index_by_uid(options.mafSource, mafIndexFile)
|
|
if index is None:
|
|
stop_err("The MAF source specified (%s) appears to be invalid." % (options.mafSource))
|
|
elif options.mafSourceType.lower() in ["user"]:
|
|
# index maf for use here, need to remove index_file when finished
|
|
index, index_filename = maf_utilities.open_or_build_maf_index(
|
|
options.mafSource, options.mafIndex, species=[primary_species]
|
|
)
|
|
if index is None:
|
|
stop_err("Your MAF file appears to be malformed.")
|
|
else:
|
|
stop_err("Invalid MAF source type specified.")
|
|
|
|
# open output file
|
|
output = open(output_file, "w")
|
|
|
|
if options.geneBED:
|
|
region_enumerator = maf_utilities.line_enumerator(open(interval_file).readlines())
|
|
else:
|
|
region_enumerator = enumerate(
|
|
bx.intervals.io.NiceReaderWrapper(
|
|
open(interval_file),
|
|
chrom_col=chr_col,
|
|
start_col=start_col,
|
|
end_col=end_col,
|
|
strand_col=strand_col,
|
|
fix_strand=True,
|
|
return_header=False,
|
|
return_comments=False,
|
|
)
|
|
)
|
|
|
|
# Step through intervals
|
|
regions_extracted = 0
|
|
line_count = 0
|
|
for line_count, line in region_enumerator:
|
|
try:
|
|
if options.geneBED: # Process as Gene BED
|
|
try:
|
|
starts, ends, fields = maf_utilities.get_starts_ends_fields_from_gene_bed(line)
|
|
# create spliced alignment object
|
|
alignment = maf_utilities.get_spliced_region_alignment(
|
|
index,
|
|
primary_species,
|
|
fields[0],
|
|
starts,
|
|
ends,
|
|
strand="+",
|
|
species=species,
|
|
mincols=mincols,
|
|
overwrite_with_gaps=overwrite_with_gaps,
|
|
)
|
|
primary_name = secondary_name = fields[3]
|
|
alignment_strand = fields[5]
|
|
except Exception as e:
|
|
print("Error loading exon positions from input line %i: %s" % (line_count, e))
|
|
continue
|
|
else: # Process as standard intervals
|
|
try:
|
|
# create spliced alignment object
|
|
alignment = maf_utilities.get_region_alignment(
|
|
index,
|
|
primary_species,
|
|
line.chrom,
|
|
line.start,
|
|
line.end,
|
|
strand="+",
|
|
species=species,
|
|
mincols=mincols,
|
|
overwrite_with_gaps=overwrite_with_gaps,
|
|
)
|
|
primary_name = "%s(%s):%s-%s" % (line.chrom, line.strand, line.start, line.end)
|
|
secondary_name = ""
|
|
alignment_strand = line.strand
|
|
except Exception as e:
|
|
print("Error loading region positions from input line %i: %s" % (line_count, e))
|
|
continue
|
|
|
|
# Write alignment to output file
|
|
# Output primary species first, if requested
|
|
if include_primary:
|
|
output.write(">%s.%s\n" % (primary_species, primary_name))
|
|
if alignment_strand == "-":
|
|
output.write(alignment.get_sequence_reverse_complement(primary_species))
|
|
else:
|
|
output.write(alignment.get_sequence(primary_species))
|
|
output.write("\n")
|
|
# Output all remainging species
|
|
for spec in secondary_species or alignment.get_species_names(skip=primary_species):
|
|
if secondary_name:
|
|
output.write(">%s.%s\n" % (spec, secondary_name))
|
|
else:
|
|
output.write(">%s\n" % (spec))
|
|
if alignment_strand == "-":
|
|
output.write(alignment.get_sequence_reverse_complement(spec))
|
|
else:
|
|
output.write(alignment.get_sequence(spec))
|
|
output.write("\n")
|
|
|
|
output.write("\n")
|
|
regions_extracted += 1
|
|
except Exception as e:
|
|
print("Unexpected error from input line %i: %s" % (line_count, e))
|
|
continue
|
|
|
|
# close output file
|
|
output.close()
|
|
|
|
# remove index file if created during run
|
|
maf_utilities.remove_temp_index_file(index_filename)
|
|
|
|
# Print message about success for user
|
|
if regions_extracted > 0:
|
|
print("%i regions were processed successfully." % (regions_extracted))
|
|
else:
|
|
print("No regions were processed successfully.")
|
|
if line_count > 0 and options.geneBED:
|
|
print("This tool requires your input file to conform to the 12 column BED standard.")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
__main__()
|