Mercurial > repos > iuc > extract_genomic_dna
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) |