comparison extract_genomic_dna.py @ 0:8dd8e89c0603 draft

planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/extract_genomic_dna commit b'67cff25a50ba173b0468819204d0999496f68ea9'
author iuc
date Tue, 19 Jan 2016 09:34:23 -0500
parents
children 702970e4a134
comparison
equal deleted inserted replaced
-1:000000000000 0:8dd8e89c0603
1 #!/usr/bin/env python
2 import argparse
3 import os
4
5 import extract_genomic_dna_utils as egdu
6 import bx.seq.nib
7 import bx.seq.twobit
8 from bx.intervals.io import Header, Comment
9
10
11 parser = argparse.ArgumentParser()
12 parser.add_argument('--input_format', dest='input_format', help="Input dataset format")
13 parser.add_argument('--input', dest='input', help="Input dataset")
14 parser.add_argument('--genome', dest='genome', help="Input dataset genome build")
15 parser.add_argument('--interpret_features', dest='interpret_features', default=None, help="Interpret features if input format is gff")
16 parser.add_argument('--columns', dest='columns', help="Columns to use in input file")
17 parser.add_argument('--reference_genome_source', dest='reference_genome_source', help="Source of reference genome file")
18 parser.add_argument('--reference_genome', dest='reference_genome', help="Reference genome file")
19 parser.add_argument('--output_format', dest='output_format', help="Output format")
20 parser.add_argument('--output', dest='output', help="Output dataset")
21 args = parser.parse_args()
22
23 input_is_gff = args.input_format == 'gff'
24 interpret_features = input_is_gff and args.interpret_features == "yes"
25 if len(args.columns.split(',')) == 5:
26 # Bed file.
27 chrom_col, start_col, end_col, strand_col, name_col = egdu.parse_cols_arg(args.columns)
28 else:
29 # Gff file.
30 chrom_col, start_col, end_col, strand_col = egdu.parse_cols_arg(args.columns)
31 name_col = False
32
33 if args.reference_genome_source == "history":
34 seq_path = egdu.convert_to_twobit(args.reference_genome)
35 else:
36 seq_path = args.reference_genome
37 seq_dir = os.path.split(seq_path)[0]
38
39 includes_strand_col = strand_col >= 0
40 strand = None
41 nibs = {}
42 skipped_lines = 0
43 first_invalid_line = 0
44 invalid_lines = []
45 warnings = []
46 warning = ''
47 twobitfile = None
48 line_count = 1
49 file_iterator = open(args.input)
50 if interpret_features:
51 file_iterator = egdu.GFFReaderWrapper(file_iterator, fix_strand=False)
52 out = open(args.output, 'wt')
53
54 for feature in file_iterator:
55 # Ignore comments, headers.
56 if isinstance(feature, (Header, Comment)):
57 line_count += 1
58 continue
59 name = ""
60 if interpret_features:
61 # Processing features.
62 egdu.convert_gff_coords_to_bed(feature)
63 chrom = feature.chrom
64 start = feature.start
65 end = feature.end
66 strand = feature.strand
67 else:
68 # Processing lines, either interval or GFF format.
69 line = feature.rstrip('\r\n')
70 if line and not line.startswith("#"):
71 fields = line.split('\t')
72 try:
73 chrom = fields[chrom_col]
74 start = int(fields[start_col])
75 end = int(fields[end_col])
76 if name_col:
77 name = fields[name_col]
78 if input_is_gff:
79 start, end = egdu.convert_gff_coords_to_bed([start, end])
80 if includes_strand_col:
81 strand = fields[strand_col]
82 except:
83 warning = "Invalid chrom, start or end column values. "
84 warnings.append(warning)
85 if not invalid_lines:
86 invalid_lines = egdu.get_lines(feature)
87 first_invalid_line = line_count
88 skipped_lines += len(invalid_lines)
89 continue
90 if start > end:
91 warning = "Invalid interval, start '%d' > end '%d'. " % (start, end)
92 warnings.append(warning)
93 if not invalid_lines:
94 invalid_lines = egdu.get_lines(feature)
95 first_invalid_line = line_count
96 skipped_lines += len(invalid_lines)
97 continue
98 if strand not in ['+', '-']:
99 strand = '+'
100 sequence = ''
101 else:
102 continue
103 # Open sequence file and get sequence for feature/interval.
104 if os.path.exists("%s/%s.nib" % (seq_dir, chrom)):
105 if chrom in nibs:
106 nib = nibs[chrom]
107 else:
108 nibs[chrom] = nib = bx.seq.nib.NibFile(open("%s/%s.nib" % (seq_path, chrom)))
109 try:
110 sequence = nib.get(start, end - start)
111 except Exception, e:
112 warning = "Unable to fetch the sequence from '%d' to '%d' for build '%s'. " % (start, end - start, args.genome)
113 warnings.append(warning)
114 if not invalid_lines:
115 invalid_lines = egdu.get_lines(feature)
116 first_invalid_line = line_count
117 skipped_lines += len(invalid_lines)
118 continue
119 elif os.path.isfile(seq_path):
120 if not(twobitfile):
121 twobitfile = bx.seq.twobit.TwoBitFile(open(seq_path))
122 try:
123 if interpret_features:
124 # Create sequence from intervals within a feature.
125 sequence = ''
126 for interval in feature.intervals:
127 sequence += twobitfile[interval.chrom][interval.start:interval.end]
128 else:
129 sequence = twobitfile[chrom][start:end]
130 except:
131 warning = "Unable to fetch the sequence from '%d' to '%d' for chrom '%s'. " % (start, end - start, chrom)
132 warnings.append(warning)
133 if not invalid_lines:
134 invalid_lines = egdu.get_lines(feature)
135 first_invalid_line = line_count
136 skipped_lines += len(invalid_lines)
137 continue
138 else:
139 warning = "Chromosome by name '%s' was not found for build '%s'. " % (chrom, args.genome)
140 warnings.append(warning)
141 if not invalid_lines:
142 invalid_lines = egdu.get_lines(feature)
143 first_invalid_line = line_count
144 skipped_lines += len(invalid_lines)
145 continue
146 if sequence == '':
147 warning = "Chrom: '%s', start: '%d', end: '%d' is either invalid or not present in build '%s'. " % (chrom, start, end, args.genome)
148 warnings.append(warning)
149 if not invalid_lines:
150 invalid_lines = egdu.get_lines(feature)
151 first_invalid_line = line_count
152 skipped_lines += len(invalid_lines)
153 continue
154 if includes_strand_col and strand == "-":
155 sequence = egdu.reverse_complement(sequence)
156 if args.output_format == "fasta":
157 l = len(sequence)
158 c = 0
159 if input_is_gff:
160 start, end = egdu.convert_bed_coords_to_gff([start, end])
161 fields = [args.genome, str(chrom), str(start), str(end), strand]
162 meta_data = "_".join(fields)
163 if name.strip():
164 out.write(">%s %s\n" % (meta_data, name))
165 else:
166 out.write(">%s\n" % meta_data)
167 while c < l:
168 b = min(c + 50, l)
169 out.write("%s\n" % str(sequence[c:b]))
170 c = b
171 else:
172 # output_format == "interval".
173 if interpret_features:
174 meta_data = "\t".join([feature.chrom,
175 "galaxy_extract_genomic_dna",
176 "interval",
177 str(feature.start),
178 str(feature.end),
179 feature.score,
180 feature.strand,
181 ".",
182 egdu.gff_attributes_to_str(feature.attributes, "GTF")])
183 else:
184 # Where is fields being set here?
185 meta_data = "\t".join(fields)
186 if input_is_gff:
187 format_str = "%s seq \"%s\";\n"
188 else:
189 format_str = "%s\t%s\n"
190 out.write(format_str % (meta_data, str(sequence)))
191 # Update line count.
192 if isinstance(feature, egdu.GFFFeature):
193 line_count += len(feature.intervals)
194 else:
195 line_count += 1
196 out.close()
197
198 if warnings:
199 warn_msg = "%d warnings, 1st is: " % len(warnings)
200 warn_msg += warnings[0]
201 print warn_msg
202 if skipped_lines:
203 # Error message includes up to the first 10 skipped lines.
204 print 'Skipped %d invalid lines, 1st is #%d, "%s"' % (skipped_lines, first_invalid_line, '\n'.join(invalid_lines[:10]))
205
206 if args.reference_genome_source == "history":
207 os.remove(seq_path)