forked from kishori82/MetaPathways_Python.3.0
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMetaPathways.py
More file actions
executable file
·506 lines (379 loc) · 19.2 KB
/
Copy pathMetaPathways.py
File metadata and controls
executable file
·506 lines (379 loc) · 19.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
#!/usr/bin/env python
from __future__ import division
__author__ = "Kishori M Konwar Niels W Hanson"
__copyright__ = "Copyright 2014, MetaPathways"
__credits__ = [""]
__version__ = "1.0"
__maintainer__ = "Kishori M Konwar Niels W Hanson"
__status__ = "Release"
#from libs.starcluster.test import teststarcluster as sctest
#import sys
try:
import sys, traceback, re, inspect, signal, shutil
from os import makedirs, sys, listdir, environ, path, _exit
#from commands import getstatusoutput
from optparse import OptionParser
from libs.python_modules.utils import metapathways_utils
from libs.python_modules.utils.utils import *
from libs.python_modules.utils.metapathways_utils import eprintf, halt_process, exit_process, WorkflowLogger, generate_log_fp
from libs.python_modules.parsers.parse import parse_metapaths_parameters
from libs.python_modules.pipeline.metapathways_pipeline import print_commands, print_to_stdout, no_status_updates
from libs.python_modules.utils.sysutil import pathDelim
from libs.python_modules.pipeline.metapathways import run_metapathways, get_parameter, read_pipeline_configuration
from libs.python_modules.annotate import *
from libs.python_modules.diagnostics.parameters import *
from libs.python_modules.diagnostics.diagnoze import *
from libs.python_modules.pipeline.sampledata import *
except:
print(""" Could not load some user defined module functions""")
print(""" Make sure your typed \"source MetaPathwaysrc\" """)
print(traceback.print_exc(10))
sys.exit(3)
cmd_folder = path.abspath(path.split(inspect.getfile( inspect.currentframe() ))[0])
PATHDELIM = str(pathDelim())
#print cmd_folder
#if not sys.platform.startswith('win'):
# res =getstatusoutput('source '+ cmd_folder +'/'+'.metapathsrc')
# if( int(res[0])==0 ):
# print 'Ran ' + cmd_folder +'/'+'.metapathsrc ' + ' file successfully!'
# else:
# print 'Error : ' + res[1]
# print 'while running ' + cmd_folder +'/'+'.metapathsrc ' + ' file!'
#sys.path.insert(0,cmd_folder + "/libs/python_modules/")
#sys.path.insert(1, cmd_folder + "/libs/")
#print sys.path
#config = load_config()
metapaths_config = """config/template_config.txt""";
metapaths_param = """config/template_param.txt""";
script_info={}
script_info['brief_description'] = """A workflow script for making PGDBs from metagenomic sequences"""
script_info['script_description'] = \
""" This script starts a MetaPathways pipeline run. It requires an input directory of fasta or genbank files
containing sequences to process, an output directory for results to be placed. It also requires the
configuration files, template_config.txt and template_param.txt in the config/ directory, to be updated with the
location of resources on your system.
"""
script_info['script_usage'] = []
usage= sys.argv[0] + """ -i input_dir -o output_dir -p parameters.txt
For more options: ./MetaPathways.py -h"""
parser = None
def createParser():
global parser
parser = OptionParser(usage)
parser.add_option("-i", "--input_file", dest="input_fp",
help='the input fasta file/input dir [REQUIRED]')
parser.add_option("-o", "--output_dir", dest="output_dir",
help='the input fasta file/input dir [REQUIRED]')
parser.add_option('-p','--parameter_fp', dest="parameter_fp",
help='path to the parameter file [REQUIRED]')
parser.add_option("-c", "--config_filer", dest="config_file",
help='pipeline_configuratin file [example : \"MetaPathways/template_config.txt\"]')
parser.add_option('-r','--run-type', dest="run_type", default='safe',
choices=['safe', 'overlay', 'overwrite','dry-run'],
help= '\n(a) \'overwrite\' -- wipes out the previous runs with the same name\n'+
'\n(b)\'overlay\' -- recomputes the steps that are not present \n' +
'\n(d)\'safe\' -- safe mode does not run on an existing run folder\n')
#ith out of order completion \ time-stamps in the \'workflow_log.txt\'
parser.add_option("-v", "--verbose",
action="store_true", dest="verbose", default=False,
help="print lots of information on the stdout [default]")
parser.add_option("-b", "--block-mode",
action="store_true", dest="block_mode", default=True,
help="processes the samples by blocking the stages before and after functional search [default off]")
parser.add_option("-d", "--delay", dest="delay", type='int', default=0,
help="number of seconds to sleep once the run is done")
parser.add_option("-P", "--print-only",
action="store_true", dest="print_only", default=False,
help="print only the commands [default False]")
parser.add_option("-s", "--subset", dest="sample_subset", action="append", default=[],
help="Processes only samples in the list subset specified [ -s sample1 -s sample2 ]" )
parser.add_option("--runid", dest="runid", default="",
help="Any string to represent the runid [ default Empty string ]" )
def valid_arguments(opts, args):
""" checks if the supplied arguments are adequate """
if (opts.input_fp == None and opts.output_dir ==None ) or\
opts.output_dir == None:
return True
else:
return False
def derive_sample_name(filename):
basename = path.basename(filename)
shortname = re.sub('[.]gbk$','',basename, re.IGNORECASE)
shortname = re.sub('[.](fasta|fas|fna|faa|fa)$','',shortname, re.IGNORECASE)
return shortname
def remove_unspecified_samples(input_output_list, sample_subset, globalerrorlogger = None):
""" keep only the samples that are specified before processing """
shortened_names = {}
input_sample_list = input_output_list.keys()
for sample_name in input_sample_list:
short_sample_name = derive_sample_name(sample_name)
# print short_sample_name, len(short_sample_name)
if len(short_sample_name) > 35:
eprintf("ERROR\tSample name %s must not be longer than 35 characters!\n",short_sample_name)
if globalerrorlogger:
globalerrorlogger.printf("ERROR\tSample name %s must not be longer than 35 characters!\n",short_sample_name)
if not derive_sample_name(sample_name) in sample_subset and sample_subset:
del input_output_list[sample_name]
def check_for_error_in_input_file_name(shortname, globalerrorlogger=None):
""" creates a list of input output pairs if input is an input dir """
clean = True
if not re.search(r'^[a-zA-Z]',shortname):
eprintf("ERROR\tSample name %s must begin with an alphabet!\n",shortname)
if globalerrorlogger:
globalerrorlogger.printf("ERROR\tSample name %s must begin with an alphabet!\tConsider prefixing an alphabet to the front\n",shortname)
clean = False
if re.search(r'[.]',shortname):
eprintf("ERROR\tSample name %s contains a '.' in its name!\n",shortname)
if globalerrorlogger:
globalerrorlogger.printf("ERROR\tSample name %s contains a '.' in its name!\n",shortname)
clean = False
if len(shortname)<2:
eprintf("ERROR\tSample name %s is too short!\n",shortname)
if globalerrorlogger:
globalerrorlogger.printf("ERROR\tSample name %s is too short1\n",shortname)
clean = False
if clean:
return clean
errmessage = """Sample names before the suffixes .fasta, .fas, .fna, .faa or .gbk, must consist only of alphabets, digits and _; and should consist of at least two characters """
eprintf("ERROR\t%s\n",errmessage)
if globalerrorlogger:
globalerrorlogger.printf("ERROR\t%s\n",errmessage)
# exit_process(errmessage + "Exiting!" + "\n", logger=globalerrorlogger)
return False
def create_an_input_output_pair(input_file, output_dir, globalerrorlogger=None):
""" creates an input output pair if input is just an input file """
input_output = {}
if not re.search(r'.(fasta|fas|fna|faa|gbk|gff|fa)$',input_file, re.IGNORECASE):
return input_output
shortname = None
shortname = re.sub('[.]gbk$','',input_file, re.IGNORECASE)
shortname = re.sub('[.](fasta|fas|fna|faa|fa)$','',input_file, re.IGNORECASE)
# shortname = re.sub('[.]gff$','',input_file, re.IGNORECASE)
shortname = re.sub(r'.*' + PATHDELIM ,'',shortname)
if check_for_error_in_input_file_name(shortname, globalerrorlogger=globalerrorlogger):
input_output[input_file] = path.abspath(output_dir) + PATHDELIM + shortname
return input_output
def create_input_output_pairs(input_dir, output_dir, globalerrorlogger=None):
""" creates a list of input output pairs if input is an input dir """
fileslist = listdir(input_dir)
gbkPatt = re.compile('[.]gbk$',re.IGNORECASE)
fastaPatt = re.compile('[.](fasta|fas|fna|faa|fa)$',re.IGNORECASE)
gffPatt = re.compile('[.]gff$',re.IGNORECASE)
input_files = {}
for input_file in fileslist:
shortname = None
result = None
result = gbkPatt.search(input_file)
if result:
shortname = re.sub('[.]gbk$','',input_file, re.IGNORECASE)
if result==None:
result = fastaPatt.search(input_file)
if result:
shortname = re.sub('[.](fasta|fas|fna|faa|fa)$','',input_file, re.IGNORECASE)
if shortname == None:
continue
if re.search('.(fasta|fas|fna|faa|gff|gbk|fa)$',input_file, re.IGNORECASE):
if check_for_error_in_input_file_name(shortname, globalerrorlogger=globalerrorlogger):
input_files[input_file] = shortname
paired_input = {}
for key, value in input_files.items():
paired_input[input_dir + PATHDELIM + key] = path.abspath(output_dir) + PATHDELIM + value
return paired_input
def removeSuffix(sample_subset_in):
sample_subset_out = []
for sample_name in sample_subset_in:
mod_name = re.sub('.(fasta|fas|fna|faa|gff|gbk|fa)$','',sample_name)
sample_subset_out.append(mod_name)
return sample_subset_out
def openGrades():
pass
def openRank():
pass
def halt_on_invalid_input(input_output_list, filetypes, sample_subset):
for samplePath in input_output_list.keys():
sampleName = path.basename(input_output_list[samplePath])
if filetypes[samplePath][0]=='UNKNOWN':
eprintf("ERROR\tIncorrect input sample %s. Check for bad characters or format\n!", samplePath)
return False
''' in the selected list'''
if not sampleName in sample_subset:
continue
return True
def report_missing_filenames(input_output_list, sample_subset, logger=None):
foundFiles = {}
for samplePath in input_output_list.keys():
sampleName = path.basename(input_output_list[samplePath])
foundFiles[sampleName] =True
for sample_in_subset in sample_subset:
if not sample_in_subset in foundFiles:
eprintf("ERROR\tCannot find input file for sample %s\n!", sample_in_subset)
if logger:
logger.printf("ERROR\tCannot file input for sample %s!\n", sample_in_subset)
# main function
def sigint_handler(signum, frame):
eprintf("Received TERMINATION signal\n")
exit_process()
def environment_variables_defined():
variables = ['METAPATHWAYS_DB']
status =True
for variable in variables:
if not variable in os.environ:
eprintf("%-10s:Environment variable %s not defined! Please set %s as \'export %s=<value>\'\n" %('ERROR', variable, variable,variable))
if variables in ['METAPATHWAYS_DB']:
status=False
return status
def main(argv):
global parser
(opts, args) = parser.parse_args()
if valid_arguments(opts, args):
print(usage)
sys.exit(0)
signal.signal(signal.SIGINT, sigint_handler)
signal.signal(signal.SIGTERM, sigint_handler)
eprintf("%-10s:%s\n" %('COMMAND', sys.argv[0] + ' ' + ' '.join(argv)) )
# initialize the input directory or file
input_fp = opts.input_fp
output_dir = path.abspath(opts.output_dir)
verbose = opts.verbose
print_only = opts.print_only
sample_subset = removeSuffix(opts.sample_subset)
run_type = opts.run_type.strip()
'''no need to remove the whole directory'''
# if run_type == 'overwrite':
# force_remove_dir=True
# else:
# force_remove_dir=False
if opts.config_file:
config_file= opts.config_file
else:
config_file = cmd_folder + PATHDELIM + metapaths_config
# try to load the parameter file
try:
if opts.parameter_fp:
parameter_fp= opts.parameter_fp
else:
parameter_fp = cmd_folder + PATHDELIM + metapaths_param
except IOError:
raise IOError( "Can't open parameters file (%s). Does it exist? Do you have read access?" % opts.parameter_fp )
try:
if run_type in ['overlay', 'safe'] and not path.exists(output_dir):
makedirs(output_dir)
except OSError:
print("")
print("ERROR: Cannot create output directory \"" + output_dir + "\"\n"+\
" Perhaps directory \"" + output_dir + "\" already exists.\n" +\
" Please choose a different directory, or \n" +\
" run with the option \"-r overwrite\" to force overwrite it." )
sys.exit(2)
print("metapathways0")
if verbose:
status_update_callback = print_to_stdout
else:
status_update_callback = no_status_updates
command_line_params={}
command_line_params['verbose']= opts.verbose
if not path.exists(parameter_fp):
eprintf("%-10s: No parameters file %s found!\n" %('WARNING', parameter_fp))
eprintf("%-10s: Creating a parameters file %s found!\n" %('INFO', parameter_fp))
create_metapaths_parameters(parameter_fp, cmd_folder)
params=parse_metapaths_parameters(parameter_fp)
""" load the sample inputs it expects either a fasta
file or a directory containing fasta and yaml file pairs
"""
globalerrorlogger = WorkflowLogger(generate_log_fp(output_dir, basefile_name= 'global_errors_warnings'), open_mode='w')
input_output_list = {}
if path.isfile(input_fp):
""" check if it is a file """
input_output_list = create_an_input_output_pair(input_fp, output_dir, globalerrorlogger=globalerrorlogger)
else:
if path.exists(input_fp):
""" check if dir exists """
input_output_list = create_input_output_pairs(input_fp, output_dir, globalerrorlogger=globalerrorlogger)
else:
""" must be an error """
eprintf("ERROR\tNo valid input sample file or directory containing samples exists .!")
eprintf("ERROR\tAs provided as arguments in the -in option.!\n")
exit_process("ERROR\tAs provided as arguments in the -in option.!\n")
""" these are the subset of sample to process if specified
in case of an empty subset process all the sample """
# remove all samples that are not specifed unless sample_subset is empty
remove_unspecified_samples(input_output_list, sample_subset, globalerrorlogger = globalerrorlogger)
# add check the config parameters
sorted_input_output_list = sorted(input_output_list.keys())
filetypes = check_file_types(sorted_input_output_list)
#stop on in valid samples
if not halt_on_invalid_input(input_output_list, filetypes, sample_subset):
globalerrorlogger.printf("ERROR\tInvalid inputs found. Check for file with bad format or characters!\n")
halt_process(opts.delay)
# make sure the sample files are found
report_missing_filenames(input_output_list, sample_subset, logger=globalerrorlogger)
#check the pipeline configuration
if not path.exists(config_file):
eprintf("%-10s: No config file %s found!\n" %('WARNING', config_file))
eprintf("%-10s: Creating a config file %s!\n" %('INFO', config_file))
if not environment_variables_defined():
sys.exit(0)
create_metapaths_configuration(config_file, cmd_folder)
config_settings = read_pipeline_configuration(config_file, globalerrorlogger)
parameter = Parameters()
if not staticDiagnose(config_settings, params, logger = globalerrorlogger):
eprintf("ERROR\tFailed to pass the test for required scripts and inputs before run\n")
globalerrorlogger.printf("ERROR\tFailed to pass the test for required scripts and inputs before run\n")
return
samplesData = {}
# PART1 before the blast
block_mode = opts.block_mode
runid = opts.runid
try:
# load the sample information
print("RUNNING MetaPathways version 3.5")
if len(input_output_list):
for input_file in sorted_input_output_list:
sample_output_dir = input_output_list[input_file]
algorithm = get_parameter(params, 'annotation', 'algorithm', default='LAST').upper()
s = SampleData()
s.setInputOutput(inputFile = input_file, sample_output_dir = sample_output_dir)
s.setParameter('algorithm', algorithm)
s.setParameter('FILE_TYPE', filetypes[input_file][0])
s.setParameter('SEQ_TYPE', filetypes[input_file][1])
s.clearJobs()
if run_type=='overwrite' and path.exists(sample_output_dir):
shutil.rmtree(sample_output_dir)
makedirs(sample_output_dir)
if not path.exists(sample_output_dir):
makedirs(sample_output_dir)
s.prepareToRun()
samplesData[input_file] = s
# load the sample information
run_metapathways(
samplesData,
sample_output_dir,
output_dir,
globallogger = globalerrorlogger,
command_line_params=command_line_params,
params=params,
metapaths_config=metapaths_config,
status_update_callback=status_update_callback,
config_file=config_file,
run_type = run_type,
config_settings = config_settings,
block_mode = block_mode,
runid = runid
)
else:
eprintf("ERROR\tNo valid input files/Or no files specified to process in folder %s!\n",sQuote(input_fp) )
globalerrorlogger.printf("ERROR\tNo valid input files to process in folder %s!\n",sQuote(input_fp) )
except:
exit_process(str(traceback.format_exc(10)), logger= globalerrorlogger )
eprintf(" *********** \n")
eprintf("INFO : FINISHED PROCESSING THE SAMPLES \n")
eprintf(" THE END \n")
eprintf(" *********** \n")
#halt_process(opts.delay)
#halt_process(3, verbose=opts.verbose)
# the main function of metapaths
if __name__ == "__main__":
createParser()
main(sys.argv[1:])
sys.exit(get_recent_error())
halt_process(1)