Mercurial > repos > yating-l > jbrowsehubtoapollo
comparison util/subtools.py @ 1:2ae1e96a8380 draft
planemo upload for repository https://github.com/Yating-L/jbrowse-archive-creator.git commit a8c47ae0025953ef398bdc689dc5df5516edf686-dirty
author | yating-l |
---|---|
date | Tue, 24 Oct 2017 18:24:40 -0400 |
parents | bc00f5c4c59e |
children | 8ff4b84d709f |
comparison
equal
deleted
inserted
replaced
0:bc00f5c4c59e | 1:2ae1e96a8380 |
---|---|
61 else: | 61 else: |
62 logging.debug("\tOutput in file {0}".format(stdout.name)) | 62 logging.debug("\tOutput in file {0}".format(stdout.name)) |
63 # If we detect an error from the subprocess, then we raise an exception | 63 # If we detect an error from the subprocess, then we raise an exception |
64 # TODO: Manage if we raise an exception for everything, or use CRITICAL etc... but not stop process | 64 # TODO: Manage if we raise an exception for everything, or use CRITICAL etc... but not stop process |
65 # TODO: The responsability of returning a sys.exit() should not be there, but up in the app. | 65 # TODO: The responsability of returning a sys.exit() should not be there, but up in the app. |
66 #if p.returncode: | |
66 if p.returncode: | 67 if p.returncode: |
67 if stderr == subprocess.PIPE: | 68 if stderr == subprocess.PIPE: |
68 raise PopenError(cmd, error, p.returncode) | 69 raise PopenError(cmd, error, p.returncode) |
69 else: | 70 else: |
70 # TODO: To Handle properly with a design behind, if we received a option as a file for the error | 71 # TODO: To Handle properly with a design behind, if we received a option as a file for the error |
71 raise Exception("Error when calling {0}. Error as been logged in your file {1}. Error code: {2}" | 72 raise Exception("Error when calling {0}. Error as been logged in your file {1}. Error code: {2}".format(cmd, stderr.name, p.returncode)) |
72 .format(cmd, stderr.name, p.returncode)) | |
73 | 73 |
74 except OSError as e: | 74 except OSError as e: |
75 message = "The subprocess {0} has encountered an OSError: {1}".format( | 75 message = "The subprocess {0} has encountered an OSError: {1}".format( |
76 cmd, e.strerror) | 76 cmd, e.strerror) |
77 if e.filename: | 77 if e.filename: |
92 message = "The subprocess {0} has encountered an unknown error: {1}".format( | 92 message = "The subprocess {0} has encountered an unknown error: {1}".format( |
93 cmd, e) | 93 cmd, e) |
94 logging.exception(message) | 94 logging.exception(message) |
95 | 95 |
96 sys.exit(-1) | 96 sys.exit(-1) |
97 return p | 97 return output |
98 | |
99 | |
100 def write_features(field, attribute, gff3): | |
101 """ | |
102 The function write the features to gff3 format (defined in https://github.com/The-Sequence-Ontology/Specifications/blob/master/gff3.md) | |
103 field, attribute are ordered dictionary | |
104 gff3 is the file handler | |
105 """ | |
106 attr = [] | |
107 for v in field.values(): | |
108 gff3.write(str(v) + '\t') | |
109 for k, v in attribute.items(): | |
110 s = str(k) + '=' + str(v) | |
111 attr.append(s) | |
112 gff3.write(';'.join(attr)) | |
113 gff3.write('\n') | |
114 | |
115 def twoBitInfo(two_bit_file_name, two_bit_info_file): | |
116 """ | |
117 Call twoBitInfo and write the result into twoBit_info_file | |
118 :param two_bit_file_name: | |
119 :param two_bit_info_file: | |
120 :return the subprocess.check_call return object: | |
121 """ | |
122 array_call = ['twoBitInfo', two_bit_file_name, two_bit_info_file] | |
123 p = _handleExceptionAndCheckCall(array_call) | |
124 return p | |
125 | |
126 | |
127 def faToTwoBit(fasta_file_name, twoBitFile): | |
128 """ | |
129 This function call faToTwoBit UCSC tool, and return the twoBitFile | |
130 :param fasta_file_name: | |
131 :param mySpecieFolder: | |
132 :return: | |
133 """ | |
134 | |
135 array_call = ['faToTwoBit', fasta_file_name, twoBitFile] | |
136 _handleExceptionAndCheckCall(array_call) | |
137 | |
138 return twoBitFile | |
139 | |
140 def sortChromSizes(two_bit_info_file_name, chrom_sizes_file_name): | |
141 """ | |
142 Call sort with -k2rn on two_bit_info_file_name and write the result into chrom_sizes_file_name | |
143 :param two_bit_info_file_name: | |
144 :param chrom_sizes_file_name: | |
145 :return: | |
146 """ | |
147 array_call = ['sort', '-k2rn', two_bit_info_file_name, | |
148 '-o', chrom_sizes_file_name] | |
149 p = _handleExceptionAndCheckCall(array_call) | |
150 return p | |
151 | |
152 def getChromSizes(reference, tool_dir): | |
153 #TODO: find a better way instead of shipping the two exec files with the tool | |
154 faToTwoBit = os.path.join(tool_dir, 'faToTwoBit') | |
155 twoBitInfo = os.path.join(tool_dir, 'twoBitInfo') | |
156 try: | |
157 twoBitFile = tempfile.NamedTemporaryFile(bufsize=0) | |
158 chrom_sizes = tempfile.NamedTemporaryFile(bufsize=0, suffix='.chrom.sizes', delete=False) | |
159 except IOError as err: | |
160 print "Cannot create tempfile err({0}): {1}".format(err.errno, err.strerror) | |
161 try: | |
162 subprocess.call(['faToTwoBit', reference, twoBitFile.name]) | |
163 except OSError as err: | |
164 print "Cannot generate twoBitFile from faToTwoBit err({0}): {1}".format(err.errno, err.strerror) | |
165 try: | |
166 subprocess.call(['twoBitInfo', twoBitFile.name, chrom_sizes.name]) | |
167 except OSError as err: | |
168 print "Cannot generate chrom_sizes from twoBitInfo err({0}): {1}".format(err.errno, err.strerror) | |
169 return chrom_sizes | |
170 | |
171 def sequence_region(chrom_sizes): | |
172 """ | |
173 This function read from a chromatin size file generated by twoBitInfo and write the information to dict | |
174 return a dict | |
175 """ | |
176 f = open(chrom_sizes, 'r') | |
177 sizes = f.readlines() | |
178 sizes_dict = {} | |
179 for line in sizes: | |
180 chrom_info = line.rstrip().split('\t') | |
181 sizes_dict[chrom_info[0]] = chrom_info[1] | |
182 return sizes_dict | |
183 | |
184 def child_blocks(parent_field, parent_attr, gff3, child_type): | |
185 num = 0 | |
186 blockcount = int(parent_attr['blockcount']) | |
187 chromstart = parent_attr['chromstarts'].split(',') | |
188 blocksize = parent_attr['blocksizes'].split(',') | |
189 parent_start = parent_field['start'] | |
190 while num < blockcount: | |
191 child_attr = OrderedDict() | |
192 child_field = parent_field | |
193 child_field['type'] = child_type | |
194 child_field['start'] = int(chromstart[num]) + int(parent_start) | |
195 child_field['end'] = int(child_field['start']) + int(blocksize[num]) - 1 | |
196 child_attr['ID'] = parent_attr['ID'] + '_part_' + str(num+1) | |
197 child_attr['Parent'] = parent_attr['ID'] | |
198 write_features(child_field, child_attr, gff3) | |
199 num = num + 1 | |
200 | |
201 def add_tracks_to_json(trackList_json, new_tracks, modify_type): | |
202 """ | |
203 Add to track configuration (trackList.json) | |
204 # modify_type = 'add_tracks': add a new track like bam or bigwig, new_track = dict() | |
205 # modify_type = 'add_attr': add configuration to the existing track, new_track = dict(track_name: dict()) | |
206 """ | |
207 with open(trackList_json, 'r+') as f: | |
208 data = json.load(f) | |
209 if modify_type == 'add_tracks': | |
210 data['tracks'].append(new_tracks) | |
211 elif modify_type == 'add_attr': | |
212 for k in new_tracks: | |
213 for track in data['tracks']: | |
214 if k.lower() in track['urlTemplate'].lower(): | |
215 attr = new_tracks[k] | |
216 for k, v in attr.items(): | |
217 track[k] = v | |
218 f.seek(0, 0) | |
219 f.write(json.dumps(data, separators=(',' , ':'), indent=4)) | |
220 f.truncate() | |
221 f.close() | |
222 | |
223 | |
224 def createBamIndex(bamfile): | |
225 subprocess.call(['samtools', 'index', bamfile]) | |
226 filename = bamfile + '.bai' | |
227 if os.path.exists(filename): | |
228 return filename | |
229 else: | |
230 raise ValueError('Did not find bai file') | |
231 | |
232 def flatfile_to_json(inputFile, dataType, trackType, trackLabel, outputFolder, options=None, compress=False): | |
233 if "bed" in dataType: | |
234 fileType = "--bed" | |
235 elif "gff" in dataType: | |
236 fileType = "--gff" | |
237 else: | |
238 raise ValueError("%s is not a valid filetype for flatfile_to_json" % dataType) | |
239 | |
240 | |
241 array_call = ['flatfile-to-json.pl', | |
242 fileType, inputFile, | |
243 '--trackType', trackType, | |
244 '--trackLabel', trackLabel, | |
245 '--out', outputFolder] | |
246 if compress: | |
247 array_call.append('--compress') | |
248 if options: | |
249 config = options.get("config") | |
250 clientConfig = options.get("clientConfig") | |
251 renderClassName = options.get('renderClassName') | |
252 subfeatureClasses = options.get('subfeatureClasses') | |
253 load_type = options.get("type") | |
254 if clientConfig: | |
255 array_call.append('--clientConfig') | |
256 array_call.append(clientConfig) | |
257 if config: | |
258 array_call.append('--config') | |
259 array_call.append(config) | |
260 if load_type: | |
261 array_call.append('--type') | |
262 array_call.append(load_type) | |
263 if renderClassName: | |
264 array_call.append('--renderClassName') | |
265 array_call.append(renderClassName) | |
266 if subfeatureClasses: | |
267 array_call.append('--subfeatureClasses') | |
268 array_call.append(json.dumps(subfeatureClasses)) | |
269 | |
270 p = _handleExceptionAndCheckCall(array_call) | |
271 return p | |
272 | |
273 def bam_to_json(inputFile, trackLabel, outputFolder, options=None, compress=False): | |
274 | |
275 array_call = ['bam-to-json.pl', | |
276 '--bam', inputFile, | |
277 '--trackLabel', trackLabel, | |
278 '--out', outputFolder] | |
279 if compress: | |
280 array_call.append('--compress') | |
281 if options: | |
282 config = options.get('config') | |
283 clientConfig = options.get('clientConfig') | |
284 if clientConfig: | |
285 array_call.append('--clientConfig') | |
286 array_call.append(clientConfig) | |
287 if config: | |
288 array_call.append('--config') | |
289 array_call.append(config) | |
290 | |
291 p = _handleExceptionAndCheckCall(array_call) | |
292 return p | |
293 | |
294 def add_track_json(trackList, track_json): | |
295 track_json = json.dumps(track_json) | |
296 new_track = subprocess.Popen(['echo', track_json], stdout=subprocess.PIPE) | |
297 p = subprocess.call(['add-track-json.pl', trackList], stdin=new_track.stdout) | |
298 return p | |
299 | |
300 def prepare_refseqs(fasta_file_name, outputFolder): | |
301 array_call = ['prepare-refseqs.pl', '--fasta', fasta_file_name, '--out', outputFolder] | |
302 p = _handleExceptionAndCheckCall(array_call) | |
303 return p | |
304 | |
305 def generate_names(outputFolder): | |
306 array_call = ['generate-names.pl', '-v', '--out', outputFolder] | |
307 p = _handleExceptionAndCheckCall(array_call) | |
308 return p | |
309 | |
310 def validateFiles(input_file, chrom_sizes_file_name, file_type, options=None): | |
311 """ | |
312 Call validateFiles on input_file, using chrom_sizes_file_name and file_type | |
313 :param input_file: | |
314 :param chrom_sizes_file_name: | |
315 :param file_type: | |
316 :return: | |
317 """ | |
318 | |
319 array_call = ['validateFiles', '-chromInfo=' + chrom_sizes_file_name, '-type='+ file_type, input_file] | |
320 if options: | |
321 tab = options.get("tab") | |
322 autoSql = options.get("autoSql") | |
323 logging.debug("tab: {0}".format(tab)) | |
324 logging.debug("autoSql: {0}".format(autoSql)) | |
325 if autoSql: | |
326 autoSql = ''.join(['-as=', autoSql]) | |
327 array_call.append(autoSql) | |
328 if tab: | |
329 array_call.append('-tab') | |
330 p = _handleExceptionAndCheckCall(array_call) | |
331 return p | |
332 | 98 |
333 def arrow_add_organism(organism_name, organism_dir, public=False): | 99 def arrow_add_organism(organism_name, organism_dir, public=False): |
334 array_call = ['arrow', 'organisms', 'add_organism', organism_name, organism_dir] | 100 array_call = ['arrow', 'organisms', 'add_organism', organism_name, organism_dir] |
335 if public: | 101 if public: |
336 array_call.append('--public') | 102 array_call.append('--public') |
337 print array_call | 103 p = _handleExceptionAndCheckCall(array_call) |
338 p = subprocess.check_output(array_call) | 104 #p = subprocess.check_output(array_call) |
339 return p | 105 return p |
340 | 106 |
341 def arrow_create_user(user_email, firstname, lastname, password, admin=False): | 107 def arrow_create_user(user_email, firstname, lastname, password, admin=False): |
342 """ Create a new user of Apollo, the default user_role is "user" """ | 108 """ Create a new user of Apollo, the default user_role is "user" """ |
343 array_call = ['arrow', 'users', 'create_user', user_email, firstname, lastname, password] | 109 array_call = ['arrow', 'users', 'create_user', user_email, firstname, lastname, password] |
375 for d in all_users: | 141 for d in all_users: |
376 if d['username'] == user_email: | 142 if d['username'] == user_email: |
377 return d['userId'] | 143 return d['userId'] |
378 logging.error("Cannot find user %s", user_email) | 144 logging.error("Cannot find user %s", user_email) |
379 | 145 |
146 def verify_user_login(username, password): | |
147 user_info = {'username': username, 'password': password} | |
148 array_call = ['curl', | |
149 '-b', 'cookies.txt', | |
150 '-c', 'cookies.txt', | |
151 '-H', 'Content-Type:application/json', | |
152 '-d', json.dumps(user_info), | |
153 'http://localhost:8080/apollo/Login?operation=login' | |
154 ] | |
155 p = _handleExceptionAndCheckCall(array_call) | |
156 msg = json.loads(p) | |
157 if 'error' in msg: | |
158 logging.error("The Authentication for user %s failed. Get error message %s", username, msg['error']) | |
159 exit(-1) | |
160 | |
161 |