9 logging.basicConfig(level=logging.DEBUG,
10 format='%(asctime)s %(levelname)-8s %(message)s',
11 datefmt='%a, %d %b %Y %H:%M:%S',
12 filename='pipeline_main.log',
19 self.bustard_path = None
20 self.config_filepath = None
27 #####################################
28 # Configure Step (goat_pipeline.py)
30 s_start = re.compile('Starting Genome Analyzer Pipeline')
31 s_gerald = re.compile("[\S\s]+--GERALD[\S\s]+--make[\S\s]+")
32 s_generating = re.compile('Generating journals, Makefiles and parameter files')
33 s_seq_folder = re.compile('^Sequence folder: ')
34 s_seq_folder_sub = re.compile('want to make ')
35 s_stderr_taskcomplete = re.compile('^Task complete, exiting')
38 s_invalid_cmdline = re.compile('Usage:[\S\s]*goat_pipeline.py')
39 s_species_dir_err = re.compile('Error: Lane [1-8]:')
40 s_goat_traceb = re.compile("^Traceback \(most recent call last\):")
43 ##Ignore - Example of out above each ignore regex.
44 #NOTE: Commenting out an ignore will cause it to be
45 # logged as DEBUG with the logging module.
46 #CF_STDERR_IGNORE_LIST = []
47 s_skip = re.compile('s_[0-8]_[0-9]+')
50 ##########################################
51 # Pipeline Run Step (make -j8 recursive)
57 s_make_error = re.compile('^make[\S\s]+Error')
58 s_no_gnuplot = re.compile('gnuplot: command not found')
59 s_no_convert = re.compile('^Can\'t exec "convert"')
60 s_no_ghostscript = re.compile('gs: command not found')
62 ##Ignore - Example of out above each ignore regex.
63 #NOTE: Commenting out an ignore will cause it to be
64 # logged as DEBUG with the logging module.
66 PL_STDERR_IGNORE_LIST = []
68 PL_STDERR_IGNORE_LIST.append( re.compile('^Info: PF') )
69 # About to analyse intensity file s_4_0101_sig2.txt
70 PL_STDERR_IGNORE_LIST.append( re.compile('^About to analyse intensity file') )
71 # Will send output to standard output
72 PL_STDERR_IGNORE_LIST.append( re.compile('^Will send output to standard output') )
73 # Found 31877 clusters
74 PL_STDERR_IGNORE_LIST.append( re.compile('^Found [0-9]+ clusters') )
75 # Will use quality criterion ((CHASTITY>=0.6)
76 PL_STDERR_IGNORE_LIST.append( re.compile('^Will use quality criterion') )
77 # Quality criterion translated to (($F[5]>=0.6))
78 PL_STDERR_IGNORE_LIST.append( re.compile('^Quality criterion translated to') )
79 # opened /woldlab/trog/data1/king/070924_USI-EAS44_0022_FC12150/Data/C1-36_Firecrest1.9.1_14-11-2007_king.4/Bustard1.9.1_14-11-2007_king/s_4_0101_qhg.txt
81 # opened s_4_0103_qhg.txt
82 PL_STDERR_IGNORE_LIST.append( re.compile('^opened[\S\s]+qhg.txt') )
83 # 81129 sequences out of 157651 passed filter criteria
84 PL_STDERR_IGNORE_LIST.append( re.compile('^[0-9]+ sequences out of [0-9]+ passed filter criteria') )
87 def pl_stderr_ignore(line):
89 Searches lines for lines to ignore (i.e. not to log)
91 returns True if line should be ignored
92 returns False if line should NOT be ignored
94 for s in PL_STDERR_IGNORE_LIST:
100 def config_stdout_handler(line, conf_info):
102 Processes each line of output from GOAT
103 and stores useful information using the logging module
105 Loads useful information into conf_info as well, for future
106 use outside the function.
108 returns True if found condition that signifies success.
111 # Skip irrelevant line (without logging)
112 if s_skip.search(line):
115 # Detect invalid command-line arguments
116 elif s_invalid_cmdline.search(line):
117 logging.error("Invalid commandline options!")
119 # Detect starting of configuration
120 elif s_start.search(line):
121 logging.info('START: Configuring pipeline')
123 # Detect it made it past invalid arguments
124 elif s_gerald.search(line):
125 logging.info('Running make now')
127 # Detect that make files have been generated (based on output)
128 elif s_generating.search(line):
129 logging.info('Make files generted')
132 # Capture run directory
133 elif s_seq_folder.search(line):
134 mo = s_seq_folder_sub.search(line)
135 #Output changed when using --tiles=<tiles>
136 # at least in pipeline v0.3.0b2
138 firecrest_bustard_gerald_makefile = line[mo.end():]
139 firecrest_bustard_gerald, junk = \
140 os.path.split(firecrest_bustard_gerald_makefile)
141 firecrest_bustard, junk = os.path.split(firecrest_bustard_gerald)
142 firecrest, junk = os.path.split(firecrest_bustard)
144 conf_info.bustard_path = firecrest_bustard
145 conf_info.run_path = firecrest
147 #Standard output handling
149 print 'Sequence line:', line
150 mo = s_seq_folder.search(line)
151 conf_info.bustard_path = line[mo.end():]
152 conf_info.run_path, temp = os.path.split(conf_info.bustard_path)
154 # Log all other output for debugging purposes
156 logging.warning('CONF:?: %s' % (line))
162 def config_stderr_handler(line, conf_info):
164 Processes each line of output from GOAT
165 and stores useful information using the logging module
167 Loads useful information into conf_info as well, for future
168 use outside the function.
170 returns RUN_ABORT upon detecting failure;
171 True on success message;
172 False if neutral message
173 (i.e. doesn't signify failure or success)
176 # Detect invalid species directory error
177 if s_species_dir_err.search(line):
180 # Detect goat_pipeline.py traceback
181 elif s_goat_traceb.search(line):
182 logging.error("Goat config script died, traceback in debug output")
184 # Detect indication of successful configuration (from stderr; odd, but ok)
185 elif s_stderr_taskcomplete.search(line):
186 logging.info('Configure step successful (from: stderr)')
188 # Log all other output as debug output
190 logging.debug('CONF:STDERR:?: %s' % (line))
192 # Neutral (not failure; nor success)
196 #FIXME: Temperary hack
197 f = open('pipeline_run.log', 'w')
198 #ferr = open('pipeline_err.log', 'w')
202 def pipeline_stdout_handler(line, conf_info):
204 Processes each line of output from running the pipeline
205 and stores useful information using the logging module
207 Loads useful information into conf_info as well, for future
208 use outside the function.
210 returns True if found condition that signifies success.
219 def pipeline_stderr_handler(line, conf_info):
223 if pl_stderr_ignore(line):
225 elif s_make_error.search(line):
226 logging.error("make error detected; run failed")
228 elif s_no_gnuplot.search(line):
229 logging.error("gnuplot not found")
231 elif s_no_convert.search(line):
232 logging.error("imagemagick's convert command not found")
234 elif s_no_ghostscript.search(line):
235 logging.error("ghostscript not found")
238 logging.debug('PIPE:STDERR:?: %s' % (line))
243 def configure(conf_info):
245 Attempts to configure the GA pipeline using goat.
247 Uses logging module to store information about status.
249 returns True if configuration successful, otherwise False.
252 #pipe = subprocess.Popen(['goat_pipeline.py',
253 # '--GERALD=config32bk.txt',
256 # stdout=subprocess.PIPE,
257 # stderr=subprocess.PIPE)
259 #ERROR Test (2), causes goat_pipeline.py traceback
260 #pipe = subprocess.Popen(['goat_pipeline.py',
261 # '--GERALD=%s' % (conf_info.config_filepath),
262 # '--tiles=s_4_100,s_4_101,s_4_102,s_4_103,s_4_104',
265 # stdout=subprocess.PIPE,
266 # stderr=subprocess.PIPE)
268 ##########################
269 # Run configuration step
270 # Not a test; actual configure attempt.
271 #pipe = subprocess.Popen(['goat_pipeline.py',
272 # '--GERALD=%s' % (conf_info.config_filepath),
275 # stdout=subprocess.PIPE,
276 # stderr=subprocess.PIPE)
279 #FIXME: this only does a run on 5 tiles on lane 4
280 pipe = subprocess.Popen(['goat_pipeline.py',
281 '--GERALD=%s' % (conf_info.config_filepath),
282 '--tiles=s_4_0100,s_4_0101,s_4_0102,s_4_0103,s_4_0104',
285 stdout=subprocess.PIPE,
286 stderr=subprocess.PIPE)
289 stdout_line = pipe.stdout.readline()
292 while stdout_line != '':
294 if config_stdout_handler(stdout_line, conf_info):
296 stdout_line = pipe.stdout.readline()
299 error_code = pipe.wait()
301 logging.error('Recieved error_code: %s' % (error_code))
303 logging.info('We are go for launch!')
306 stderr_line = pipe.stderr.readline()
309 stderr_success = False
310 while stderr_line != '':
311 stderr_status = config_stderr_handler(stderr_line, conf_info)
312 if stderr_status == RUN_ABORT:
314 elif stderr_status is True:
315 stderr_success = True
316 stderr_line = pipe.stderr.readline()
319 #Success requirements:
320 # 1) The stdout completed without error
321 # 2) The program exited with status 0
322 # 3) No errors found in stdout
323 print '#Expect: True, False, True, True'
324 print complete, bool(error_code), abort != RUN_ABORT, stderr_success is True
325 status = complete is True and \
326 bool(error_code) is False and \
327 abort != RUN_ABORT and \
328 stderr_success is True
330 # If everything was successful, but for some reason
331 # we didn't retrieve the path info, log it.
333 if conf_info.bustard_path is None or conf_info.run_path is None:
334 logging.error("Failed to retrieve run_path")
340 def run_pipeline(conf_info):
342 Run the pipeline and monitor status.
344 # Fail if the run_path doesn't actually exist
345 if not os.path.exists(conf_info.run_path):
346 logging.error('Run path does not exist: %s' \
347 % (conf_info.run_path))
350 # Change cwd to run_path
351 os.chdir(conf_info.run_path)
353 # Log pipeline starting
354 logging.info('STARTING PIPELINE @ %s' % (time.ctime()))
356 # Start the pipeline (and hide!)
357 pipe = subprocess.Popen(['make',
360 stdout=subprocess.PIPE,
361 stderr=subprocess.PIPE)
363 line = pipe.stdout.readline()
367 if pipeline_stdout_handler(line, conf_info):
369 line = pipe.stdout.readline()
371 error_code = pipe.wait()
373 #ferr.write(pipe.stderr.read())
376 stderr_line = pipe.stderr.readline()
380 while stderr_line != '':
381 stderr_status = pipeline_stderr_handler(stderr_line, conf_info)
382 if stderr_status is True:
384 if stderr_status == RUN_FAILED:
386 stderr_line = pipe.stderr.readline()
389 print 'RUN STATUS: expect: True, True, True, True'
391 print complete is True, error_code == 0,
392 print run_succeded is True, run_failed is False
395 status = complete is True and \
396 error_code == 0 and \
397 run_succeded is True and \
404 if __name__ == '__main__':
406 ci.config_filepath = 'config32bk.txt'
408 status = configure(ci)
410 print "Configure success"
412 print "Configure failed"
414 print 'Run Dir:', ci.run_path
415 print 'Bustard Dir:', ci.bustard_path
418 print 'Running pipeline now!'
419 run_status = run_pipeline(ci)
420 if run_status is True:
421 print 'Pipeline ran successfully.'
423 print 'Pipeline run failed.'
425 #FIXME: Temperary hack