#!/usr/bin/python-intelerad import sys ; sys.path.insert(0, '/usr/local/tools/PythonLib/supportUtilities.lib.zip') import sys, os, atexit from popen2 import popen3 from socket import gethostname from optparse import OptionParser from ims.cfile import ControlFile from ims.db import getDatabaseConfig, getConnectionFactory from ims.db.util import formatsql from ims.util import setupLogging class DicomImage: def __init__(self): hostname = gethostname().split('.')[0] dbconfig = getDatabaseConfig() self.conn = getConnectionFactory("DicomImage", dbconfig=dbconfig ).connect(host=hostname) atexit.register(self.conn.close) self.statedir = "/usr/local/PACS/state" def getRecentSeries(self,startdate=20070629): # PR Series never work, so we exclude them in our query query = formatsql ("SELECT SeriesPath FROM SeriesLevel WHERE InsertDate >= %s and Mod <> 'PR'", startdate) result = self.conn.executeQuery(query) if result: result = [path[0] for path in result] return result usage = "usage: %prog [options] [yyyymmdd]" parser = OptionParser(usage=usage) parser.add_option("-v","--verbose", action="store_true", dest="verbose", default=False, help="Enable verbose debugging") (options, args) = parser.parse_args() # Verify our start date if len(args) == 0: print "Error: You must specify a start date for the search!" print parser.print_help() sys.exit(1) elif len(args[0]) != 8: print "Error: Your start date must be in the format yyyymmdd" print parser.print_help() sys.exit(1) else: startdate = int(args[0]) # Set our verbosity level if options.verbose: level = 10 else: level = 20 # Set up some classes that we might need log = setupLogging(dirname='generateSeriesHeaders', add_stdout=False, level=level) # Instantiate our database connection try: log.info("Connecting to DicomImage on %s" % gethostname().split('.')[0]) db = DicomImage() except: log.error("Caught unhandled exception - exiting...") raise else: log.info("Connected to DicomImage") # Get our series list try: log.info("Getting series path list from DicomImage") seriesPathList = db.getRecentSeries(startdate) invalidSeriesPathList = [] except KeyboardInterrupt: log.warn("Caught SIGINT - exiting...") sys.exit(0) except: log.error("Caught unhandled exception - exiting...") raise else: log.info("Got %s series paths from DicomImage" % len(seriesPathList)) # Now we check to see which series have SeriesHeader.ish files log.info("Building worklist of broken series...") count = 0 for path in seriesPathList: count += 1 if count % 500 == 0 and not options.verbose: log.info("Processed %s series..." % count) try: log.debug("Processing series path %s" % path) if os.path.getsize(path + "/SeriesHeader.ish") == 0: log.debug("Found zero-byte SeriesHeader.ish for path %s" % path) invalidSeriesPathList.append(path) except OSError, e: log.debug("Caught OSError exception %s" % e) log.debug("Adding series path %s" % path) invalidSeriesPathList.append(path) except KeyboardInterrupt: log.warn("Caught SIGINT - exiting...") sys.exit(0) except: log.error("Caught unhandled exception while verifying path %s - exiting..." % path) raise else: log.debug("SUCCESS - %s" % path) if not options.verbose: log.info("Finished processing %s series" % count) if len(invalidSeriesPathList) == 0: log.info("No invalid series found") sys.exit() log.info("Built worklist of %s broken series" % len(invalidSeriesPathList)) log.info("Processing invalid series") seriesCount = [0,0] # Success/fail failedSeries = [] for path in invalidSeriesPathList: try: log.debug("Processing path %s" % path) if not os.path.isdir(path): log.error("Path not found: %s" % path) seriesCount[1] += 1 break log.info("Creating %s/SeriesHeader.ish" % path) open(path + "/SeriesHeader.ish","w").close() log.info("Executing \"regenerateSeriesHeader %s\"" % path) r,w,e = popen3('regenerateSeriesHeader ' + path) err = e.readlines() r.readlines() # Since regenerateSeriesHeader always prints to r.close() # stderr, we don't need to trap stdout w.close() e.close() i = 0 errors = False for line in err: if "ERROR" in line: errors = True error = ' '.join(err[i-2:i+2])[:-1] if ".dcm" in err[i-3]: filename = err[i-3].split()[-1] log.error("Caught error from subprocess while processing file %s:\n\n %s\n" % (filename,error)) else: log.error("Caught error from subprocess:\n\n %s\n" % error) i += 1 if errors: seriesCount[1] += 1 failedSeries.append(path) if os.path.getsize(path + "/SeriesHeader.ish") == 0: os.unlink(path + "/SeriesHeader.ish") log.info("Removing zero-byte SeriesHeader.ish file") log.error("regenerateSeriesHeader did not complete successfully for path %s\n" % path) else: log.info("regenerateSeriesHeader completed sucessfully\n") seriesCount[0] += 1 except OSError,e: log.error("Caught OS exception: %s" % e) except IOError,e: log.error("Caught IO Exception: %s" % e) if os.path.getsize(path + "/SeriesHeader.ish") == 0: os.unlink(path + "/SeriesHeader.ish") log.info("Removing zero-byte SeriesHeader.ish file") except KeyboardInterrupt: log.warn("Caught SIGINT - exiting...") sys.exit(0) except: log.error("Caught unhandled exception while processing %s - exiting..." % path) raise sys.exit(1) log.info("Processed %s series with %s successes and %s failures\n" % (sum(seriesCount),seriesCount[0],seriesCount[1])) if len(failedSeries) > 0: failedSeries.sort() log.error("Failed series list:\n %s\n" % '\n '.join(failedSeries)) log.info("Script execution completed successfully\n")