Example #1
0
 def __init__(self, filePath, maxRecords = 4):
     """ Constructor.
     """
     self.__WeatherStationRecord = None
     self.__GeometryRecord = None
     logger.info('Opening input binary file %s...' % filePath)
     file.__init__(self, filePath, 'rb')
     self.__LastByteRead = None
     self.readWord(self.HEADER_EEE_1)
     self.readWord(self.HEADER_EEE_2)
     for i in xrange(maxRecords):
         try:
             blockType, blockSize, data = self.readBlock()
         except:
             logger.error('Could not parse file content, giving up.')
             break
         if blockType == self.HEADER_GEO_RECORD:
             self.__GeometryRecord = E3GeometryRecord(*data)
             logger.info('Geometry record found!')
             logger.info(self.__GeometryRecord)
         elif blockType == self.HEADER_VWS_RECORD:
             self.__WeatherStationRecord = E3WeatherStationRecord(*data)
             logger.info('Weather station record found!')
             logger.info(self.__WeatherStationRecord)
             break
     if self.__WeatherStationRecord is None:
         logger.info('Could not find any weather station record.')
Example #2
0
 def __init__(self, filePath, maxRecords=4):
     """ Constructor.
     """
     self.__WeatherStationRecord = None
     self.__GeometryRecord = None
     logger.info('Opening input binary file %s...' % filePath)
     file.__init__(self, filePath, 'rb')
     self.__LastByteRead = None
     self.readWord(self.HEADER_EEE_1)
     self.readWord(self.HEADER_EEE_2)
     for i in xrange(maxRecords):
         try:
             blockType, blockSize, data = self.readBlock()
         except:
             logger.error('Could not parse file content, giving up.')
             break
         if blockType == self.HEADER_GEO_RECORD:
             self.__GeometryRecord = E3GeometryRecord(*data)
             logger.info('Geometry record found!')
             logger.info(self.__GeometryRecord)
         elif blockType == self.HEADER_VWS_RECORD:
             self.__WeatherStationRecord = E3WeatherStationRecord(*data)
             logger.info('Weather station record found!')
             logger.info(self.__WeatherStationRecord)
             break
     if self.__WeatherStationRecord is None:
         logger.info('Could not find any weather station record.')
Example #3
0
    def readWord(self, expected=None):
        """ Read a byte from the binary file.

        If the expected argument is not None, the value which is read out is
        checked against that.
        """
        self.__LastByteRead = struct.unpack('i', self.read(4))[0]
        if expected is not None and self.__LastByteRead != expected:
            logger.error('Data mismatch (expected %d, found %d)' %\
                         (expected, self.__LastByteRead))
        return self.__LastByteRead
Example #4
0
 def execute(self, query, commit=True):
     """ Execute a query.
     """
     logger.info('About to execute "%s"...' % query)
     if commit:
         try:
             self.__Cursor.execute(query)
             self.commit()
         except Exception, e:
             logger.error('%s, rolling back change...' % e)
             self.rollback()
Example #5
0
    def readWord(self, expected = None):
        """ Read a byte from the binary file.

        If the expected argument is not None, the value which is read out is
        checked against that.
        """
        self.__LastByteRead = struct.unpack('i', self.read(4))[0]
        if expected is not None and self.__LastByteRead != expected:
            logger.error('Data mismatch (expected %d, found %d)' %\
                         (expected, self.__LastByteRead))
        return self.__LastByteRead
Example #6
0
 def execute(self, query, commit = True):
     """ Execute a query.
     """
     logger.info('About to execute "%s"...' % query)
     if commit:
         try:
             self.__Cursor.execute(query)
             self.commit()
         except Exception, e:
             logger.error('%s, rolling back change...' % e)
             self.rollback()
Example #7
0
def rmdir(folderPath):
    """ Remove an entire (empty or non empty) folder.
    """
    logger.info('About to remove folder %s...' % folderPath)
    try:
        shutil.rmtree(folderPath)
        logger.info('Folder succesfully removed.')
        status = 0
    except Exception as e:
        logger.error('Could not remove folder (%s)' % e)
        status = 1
    return status
Example #8
0
def rmdir(folderPath):
    """ Remove an entire (empty or non empty) folder.
    """
    logger.info('About to remove folder %s...' % folderPath)
    try:
        shutil.rmtree(folderPath)
        logger.info('Folder succesfully removed.')
        status = 0
    except Exception as e:
        logger.error('Could not remove folder (%s)' %  e)
        status = 1
    return status
 def addFilePath(self, station, filePath):
     """ Add a file path for a specific station.
     """
     if not os.path.exists(filePath):
         logger.error('Could not find %s, file will not be added.' %\
                      filePath)
         return
     if station not in self.__Stations:
         self.__Stations.append(station)
         self.__FileDict[station] = []
     self.__FileDict[station].append(filePath)
     self.__FileList.append(filePath)
Example #10
0
 def scanGPS(self, maxRecords=10):
     """
     """
     numRecords = 0
     while numRecords < maxRecords:
         try:
             blockType, blockSize, data = self.readBlock()
         except:
             logger.error('Could not parse file content, giving up.')
             break
         if blockType == self.HEADER_GPS_RECORD:
             print numRecords, E3GpsRecord(*data)
             numRecords += 1
Example #11
0
 def scanGPS(self, maxRecords = 10):
     """
     """
     numRecords = 0
     while numRecords < maxRecords:
         try:
             blockType, blockSize, data = self.readBlock()
         except:
             logger.error('Could not parse file content, giving up.')
             break
         if blockType == self.HEADER_GPS_RECORD:
             print numRecords, E3GpsRecord(*data)
             numRecords += 1
Example #12
0
def mv(source, dest):
    """ Move a file.

    Return 0 upon succesfull operation, 1 otherwise.
    """
    logger.info('About to move %s to %s...' % (source, dest))
    try:
        shutil.move(source, dest)
        logger.info('File succesfully copied.')
        status = 0
    except Exception as e:
        logger.error('Could not move file (%s)' % e)
        status = 1
    return status
Example #13
0
def mv(source, dest):
    """ Move a file.

    Return 0 upon succesfull operation, 1 otherwise.
    """
    logger.info('About to move %s to %s...' % (source, dest))
    try:
        shutil.move(source, dest)
        logger.info('File succesfully copied.')
        status = 0
    except Exception as e:
        logger.error('Could not move file (%s)' % e)
        status = 1
    return status
Example #14
0
def createFolder(folderPath):
    """ Create a folder (unless it already exists).

    Return 0 upon succesfull operation, 1 otherwise.
    """
    if not os.path.exists(folderPath):
        logger.info('About to create folder %s...' % folderPath)
        try:
            os.makedirs(folderPath)
            logger.info('Folder succesfully created.')
            status = 0
        except Exception as e:
            logger.error('Could not create folder (%s)' % e)
            status = 1
        return status
Example #15
0
def createFolder(folderPath):
    """ Create a folder (unless it already exists).

    Return 0 upon succesfull operation, 1 otherwise.
    """
    if not os.path.exists(folderPath):
        logger.info('About to create folder %s...' % folderPath)
        try:
            os.makedirs(folderPath)
            logger.info('Folder succesfully created.')
            status = 0
        except Exception as e:
            logger.error('Could not create folder (%s)' % e)
            status = 1
        return status
Example #16
0
def rm(filePath):
    """ Remove a file.

    Return 0 upon succesfull operation, 1 otherwise.
    """
    logger.info('About to remove file %s...' % filePath)
    if not os.path.exists(filePath):
        logger.info('File is not there, giving up...')
        return 0
    try:
        os.remove(filePath)
        logger.info('File succesfully removed.')
        status = 0
    except Exception as e:
        logger.error('Could not remove file (%s)' % e)
        status = 1
    return status
Example #17
0
def rm(filePath):
    """ Remove a file.

    Return 0 upon succesfull operation, 1 otherwise.
    """
    logger.info('About to remove file %s...' % filePath)
    if not os.path.exists(filePath):
        logger.info('File is not there, giving up...')
        return 0
    try:
        os.remove(filePath)
        logger.info('File succesfully removed.')
        status = 0
    except Exception as e:
        logger.error('Could not remove file (%s)' %  e)
        status = 1
    return status
Example #18
0
def cmd(cmd, verbose = False, logFilePath = None, logFileMode = 'w',
        dryRun = False):
    """ Exec a command.

    This uses subprocess internally and returns the subprocess status code
    (if the dryRun option is true the function will just print the command out
    through the logger and returns happily).

    By default the stdout and the stderr are redirected into subprocess pipes
    so that the output can be effectively used by the logger. It the logFilePath
    parameter is different from None the stdout is redirected to file instead.
    The rules are:
    (*) if verbose is True the command output is logged onto the terminal one
    line at a time;
    (*) if the status code is zero we just aknowledge that before returning it;
    (*) upon error we try and log out both the error code and the error message.
    """
    logger.info('About to execute "%s"...' % cmd)
    if dryRun:
        logger.info('Just kidding (dry run).')
        return 0
    err = subprocess.PIPE
    if logFilePath is not None:
        out = open(logFilePath, logFileMode)
    else:
        out = subprocess.PIPE
    process = subprocess.Popen(cmd, stdout = out, stderr = err, shell = True)
    errorCode = process.wait()
    if verbose:
        if logFilePath is None:
            output = process.stdout.read().strip('\n')
        else:
            output = open(logFilePath).read().strip('\n')
        for line in output.split('\n'):
            logger.info(line)
    if not errorCode:
        logger.info('Command executed with status code %d.' % errorCode)
    else:
        logger.error('Command returned status code %d.' % errorCode)
        logger.error('Full error message following...\n%s' %\
                         process.stderr.read().strip('\n'))
    return errorCode
Example #19
0
def cp(source, dest, createTree=False):
    """ Copy a file.

    Return 0 upon succesfull operation, 1 otherwise.
    """
    logger.info('About to copy %s to %s...' % (source, dest))
    destFolder = os.path.dirname(dest)
    if not os.path.exists(destFolder) and createTree:
        createFolder(destFolder)
    try:
        if os.path.isdir(source):
            shutil.copytree(source, dest)
        else:
            shutil.copy(source, dest)
        logger.info('File succesfully copied.')
        status = 0
    except Exception as e:
        logger.error('Could not copy file (%s)' % e)
        status = 1
    return status
Example #20
0
def cp(source, dest, createTree = False):
    """ Copy a file.

    Return 0 upon succesfull operation, 1 otherwise.
    """
    logger.info('About to copy %s to %s...' % (source, dest))
    destFolder = os.path.dirname(dest)
    if not os.path.exists(destFolder) and createTree:
        createFolder(destFolder)
    try:
        if os.path.isdir(source):
            shutil.copytree(source, dest)
        else:
            shutil.copy(source, dest)
        logger.info('File succesfully copied.')
        status = 0
    except Exception as e:
        logger.error('Could not copy file (%s)' % e)
        status = 1
    return status
Example #21
0
def cmd(cmd, verbose=False, logFilePath=None, logFileMode='w', dryRun=False):
    """ Exec a command.

    This uses subprocess internally and returns the subprocess status code
    (if the dryRun option is true the function will just print the command out
    through the logger and returns happily).

    By default the stdout and the stderr are redirected into subprocess pipes
    so that the output can be effectively used by the logger. It the logFilePath
    parameter is different from None the stdout is redirected to file instead.
    The rules are:
    (*) if verbose is True the command output is logged onto the terminal one
    line at a time;
    (*) if the status code is zero we just aknowledge that before returning it;
    (*) upon error we try and log out both the error code and the error message.
    """
    logger.info('About to execute "%s"...' % cmd)
    if dryRun:
        logger.info('Just kidding (dry run).')
        return 0
    err = subprocess.PIPE
    if logFilePath is not None:
        out = open(logFilePath, logFileMode)
    else:
        out = subprocess.PIPE
    process = subprocess.Popen(cmd, stdout=out, stderr=err, shell=True)
    errorCode = process.wait()
    if verbose:
        if logFilePath is None:
            output = process.stdout.read().strip('\n')
        else:
            output = open(logFilePath).read().strip('\n')
        for line in output.split('\n'):
            logger.info(line)
    if not errorCode:
        logger.info('Command executed with status code %d.' % errorCode)
    else:
        logger.error('Command returned status code %d.' % errorCode)
        logger.error('Full error message following...\n%s' %\
                         process.stderr.read().strip('\n'))
    return errorCode
Example #22
0
def e3failureStats(exitCode):
    """
    """
    db = E3RunDbInterface()
    query = 'SELECT station_name, run_date, run_id from runs WHERE processing_status_code = %d' % exitCode
    db.execute(query, commit = False)
    outputFilePath = 'failures_%d.dat' % exitCode
    logger.info('Opening output file %s...' % outputFilePath)
    outputFile = open(outputFilePath, 'w')
    n = 0
    for station, date, runId in db.fetchall():
        filePath = binFilePath(station, date, runId)
        if os.path.exists(filePath):
            outputFile.write('%s\t%d\n' %\
                                 (filePath, os.stat(filePath).st_size))
            n += 1
        else:
            logger.error('Could not find %s!' % filePath)
    outputFile.close()
    logger.info('Done, %d rows written.' % n)
    db.close()
Example #23
0
def e3failureStats(exitCode):
    """
    """
    db = E3RunDbInterface()
    query = 'SELECT station_name, run_date, run_id from runs WHERE processing_status_code = %d' % exitCode
    db.execute(query, commit=False)
    outputFilePath = 'failures_%d.dat' % exitCode
    logger.info('Opening output file %s...' % outputFilePath)
    outputFile = open(outputFilePath, 'w')
    n = 0
    for station, date, runId in db.fetchall():
        filePath = binFilePath(station, date, runId)
        if os.path.exists(filePath):
            outputFile.write('%s\t%d\n' %\
                                 (filePath, os.stat(filePath).st_size))
            n += 1
        else:
            logger.error('Could not find %s!' % filePath)
    outputFile.close()
    logger.info('Done, %d rows written.' % n)
    db.close()
Example #24
0
def e3dst(baseFilePath):
    """ Parse all the output text files from the analyzer and build the
    actual DST in ROOT format.
    """
    chrono = E3Chrono()
    logger.info('Collecting input files for the DST...')
    outFile = E3AnalyzerOutFile('%s.out' % baseFilePath)
    sumFile = E3AnalyzerSumFile('%s.sum' % baseFilePath)
    dstFilePath = '%s_dst.root' % baseFilePath
    uniqueId = uniqueRunIdFromFilePath(baseFilePath)
    station, year, month, day, runId = splitFilePath(baseFilePath)
    date = datetime.date(int(year), int(month), int(day))
    logger.info('Unique run ID is %s.' % uniqueId)
    logger.info('Opening output ROOT file %s...' % dstFilePath)
    rootFile = E3OutputRootFile(dstFilePath, 'e3dst', date2str(date), station)
    logger.info('Initializing event tree...')
    eventTree = E3DstEventTree()
    eventTree.setUniqueRunId(uniqueId)
    logger.info('Filling event tree...')
    for row in outFile:
        eventTree.fillRow(row)
    eventStat = outFile.eventStat()
    tmin = outFile.minTimestamp()
    tmax = outFile.maxTimestamp()
    # If we have less than two good events there is nothing we could
    # possibly do, here.
    # Close all files and remove the output dst ROOT file so that
    # we know the run has not been processed.
    if eventStat['hits'] < 2:
        logger.info('Closing all files...')
        rootFile.Close()
        outFile.close()
        sumFile.close()
        __utils__.rm(dstFilePath)
        logger.info('No events with hits, processing terminated after %.3f s.' %\
                    chrono.stop())
        sys.exit(E3PIPE_EXIT_CODE_NO_HITS_EVENTS)
    logger.info('Event stats: %s' % eventStat)
    logger.info('Range of timestamps in the output files: %.3f--%.3f' %\
                (tmin, tmax))
    duration = tmax - tmin
    logger.info('Corresponding run duration: %.3f s' % duration)
    if duration > MAX_RUN_DURATION:
        logger.error('Run looks way too long, something must be wrong.')
        sys.exit(E3PIPE_EXIT_CODE_RUN_TOO_LONG)
    eventTree.Write()
    logger.info('Done, %d event(s) filled in.' % eventTree.GetEntries())
    if eventTree.GetEntries() == 0:
        abort('No events found (maybe an issue with eee_calib.txt?)')
    logger.info('Creating monitoring plots...')
    eventTree.doMonitoring()
    logger.info('Initializing weather tree...')
    weatherTree = E3DstWeatherTree()
    weatherTree.setUniqueRunId(uniqueId)
    binFile = E3BinFile('%s.bin' % baseFilePath)
    weatherRecord = binFile.weatherStationRecord()
    if weatherRecord is not None:
        logger.info('Filling weather tree...')
        weatherTree.fillRow(weatherRecord.data())
    weatherTree.Write()
    logger.info('Creating trending data products...')
    trendingTree = eventTree.doTrending(TRENDING_TIME_BIN, tmin, tmax,
                                        weatherRecord)
    logger.info('Writing trending tree...')
    trendingTree.Write()
    logger.info('Writing monitoring/trending plots...')
    for plot in eventTree.plots():
        plot.Write()
    logger.info('Initializing header tree...')
    headerTree = E3DstHeaderTree()
    headerTree.setUniqueRunId(uniqueId)
    logger.info('Filling header tree...')
    data = sumFile.data()
    # Mind we need to add a few things "by hand", here, as not all the
    # information that we want in the header is really coming from the
    # sum file.
    data['RunNumber'] = row['RunNumber']
    data['RunStart'] = tmin
    data['RunStop'] = tmax
    data['RunDuration'] = tmax - tmin
    data['NumHitEvents'] = eventStat['hits']
    data['NumTrackEvents'] = eventStat['track']
    data['NumNoHitsEvents'] = eventStat['no_hits']
    data['NumNoHitEvents'] = eventStat['no_hit']
    data['NumMalformedEvents'] = eventStat['malformed']
    data['NumBackwardEvents'] = eventStat['backward']
    headerTree.fillRow(data)
    headerTree.Write()

    logger.info('Creating histograms...')
    for key in [
            'HitMultBot', 'HitMultMid', 'HitMultTop', 'ClusterMultBot',
            'ClusterMultMid', 'ClusterMultTop'
    ]:
        h = data2hist(data, key, xmax=15.5)
        h.Write()
    for key in ['HitMultTotal', 'ClusterMultTotal']:
        h = data2hist(data, key, xmax=35.5)
        h.Write()
    logger.info('Closing all files...')
    rootFile.Close()
    outFile.close()
    sumFile.close()
    logger.info('DST created in %.3f s.' % chrono.stop())
    listTemp()
    logger.info('Returning DST path: %s...' % dstFilePath)
    return dstFilePath
Example #25
0
def e3dst(baseFilePath):
    """ Parse all the output text files from the analyzer and build the
    actual DST in ROOT format.
    """
    chrono = E3Chrono()
    logger.info('Collecting input files for the DST...')
    outFile = E3AnalyzerOutFile('%s.out' % baseFilePath)
    sumFile = E3AnalyzerSumFile('%s.sum' % baseFilePath)
    dstFilePath = '%s_dst.root' % baseFilePath
    uniqueId = uniqueRunIdFromFilePath(baseFilePath)
    station, year, month, day, runId = splitFilePath(baseFilePath)
    date = datetime.date(int(year), int(month), int(day))
    logger.info('Unique run ID is %s.' % uniqueId)
    logger.info('Opening output ROOT file %s...' % dstFilePath)
    rootFile = E3OutputRootFile(dstFilePath, 'e3dst', date2str(date), station)
    logger.info('Initializing event tree...')
    eventTree = E3DstEventTree()
    eventTree.setUniqueRunId(uniqueId)
    logger.info('Filling event tree...')
    for row in outFile:
        eventTree.fillRow(row)
    eventStat = outFile.eventStat()
    tmin = outFile.minTimestamp()
    tmax = outFile.maxTimestamp()
    # If we have less than two good events there is nothing we could
    # possibly do, here.
    # Close all files and remove the output dst ROOT file so that
    # we know the run has not been processed.
    if eventStat['hits'] < 2:
        logger.info('Closing all files...')
        rootFile.Close()
        outFile.close()
        sumFile.close()
        __utils__.rm(dstFilePath)
        logger.info('No events with hits, processing terminated after %.3f s.' %\
                    chrono.stop())
        sys.exit(E3PIPE_EXIT_CODE_NO_HITS_EVENTS)
    logger.info('Event stats: %s' % eventStat)
    logger.info('Range of timestamps in the output files: %.3f--%.3f' %\
                (tmin, tmax))
    duration = tmax - tmin
    logger.info('Corresponding run duration: %.3f s' % duration)
    if duration > MAX_RUN_DURATION:
        logger.error('Run looks way too long, something must be wrong.')
        sys.exit(E3PIPE_EXIT_CODE_RUN_TOO_LONG)
    eventTree.Write()
    logger.info('Done, %d event(s) filled in.' % eventTree.GetEntries())
    if eventTree.GetEntries() == 0:
        abort('No events found (maybe an issue with eee_calib.txt?)')
    logger.info('Creating monitoring plots...')
    eventTree.doMonitoring()
    logger.info('Initializing weather tree...')
    weatherTree = E3DstWeatherTree()
    weatherTree.setUniqueRunId(uniqueId)
    binFile = E3BinFile('%s.bin' % baseFilePath)
    weatherRecord = binFile.weatherStationRecord()
    if weatherRecord is not None:
        logger.info('Filling weather tree...')
        weatherTree.fillRow(weatherRecord.data())
    weatherTree.Write()
    logger.info('Creating trending data products...')
    trendingTree = eventTree.doTrending(TRENDING_TIME_BIN, tmin, tmax,
                                        weatherRecord)
    logger.info('Writing trending tree...')
    trendingTree.Write()
    logger.info('Writing monitoring/trending plots...')
    for plot in eventTree.plots():
        plot.Write()
    logger.info('Initializing header tree...')
    headerTree = E3DstHeaderTree()
    headerTree.setUniqueRunId(uniqueId)
    logger.info('Filling header tree...')
    data = sumFile.data()
    # Mind we need to add a few things "by hand", here, as not all the
    # information that we want in the header is really coming from the
    # sum file.
    data['RunNumber'] = row['RunNumber']
    data['RunStart'] = tmin
    data['RunStop'] = tmax
    data['RunDuration'] = tmax - tmin
    data['NumHitEvents'] = eventStat['hits']
    data['NumTrackEvents'] = eventStat['track']
    data['NumNoHitsEvents'] = eventStat['no_hits']
    data['NumNoHitEvents'] = eventStat['no_hit']
    data['NumMalformedEvents'] = eventStat['malformed']
    data['NumBackwardEvents'] = eventStat['backward']
    headerTree.fillRow(data)
    headerTree.Write()
    
    logger.info('Creating histograms...')
    for key in ['HitMultBot', 'HitMultMid', 'HitMultTop',
                'ClusterMultBot', 'ClusterMultMid', 'ClusterMultTop']:
        h = data2hist(data, key, xmax = 15.5)
        h.Write()
    for key in ['HitMultTotal', 'ClusterMultTotal']:
        h = data2hist(data, key, xmax = 35.5)
        h.Write()
    logger.info('Closing all files...')
    rootFile.Close()
    outFile.close()
    sumFile.close()
    logger.info('DST created in %.3f s.' % chrono.stop())
    listTemp()
    logger.info('Returning DST path: %s...' % dstFilePath)
    return dstFilePath
Example #26
0
 def hist2d(self, expression, cut = '', **kwargs):
     """ Create a 2-dimensional histogram.
     """
     logger.error('Two-dimensional histograms not implemented, yet.')
Example #27
0
_usage = 'usage: %prog [options] binfile'
_synopsis = 'Run the full e3recon in a shell and, if needed, register the results in the database'

# Set up the command-line switches.
from e3pipe.misc.E3OptionParser import E3OptionParser
parser = E3OptionParser(_usage, _synopsis)
(opts, args) = parser.parse_args()

# Make sure we are passing some argument.
if not len(args) == 1:
    parser.print_help()
    parser.error('Please provide a single input file.')
rawFilePath = args[0]

# Print the start message.
from e3pipe.__logging__ import startmsg
startmsg()

# Run e3recon
chrono = E3Chrono()
_cmd = 'e3recon.py %s' % rawFilePath
exitCode = __utils__.cmd(_cmd)
if exitCode == 0:
    logger.info('Run processed in %.3f s.' % chrono.stop())
else:
    logger.error('Processing terminated with exit code %d after %.3f s.' %\
                 (exitCode, chrono.stop()))
if doDbRegister():
    runInfo = E3RawDataInfo(rawFilePath)
    registerRun(runInfo, exitCode)
Example #28
0
 def hist2d(self, expression, cut='', **kwargs):
     """ Create a 2-dimensional histogram.
     """
     logger.error('Two-dimensional histograms not implemented, yet.')
Example #29
0
_usage = 'usage: %prog [options] binfile'
_synopsis = 'Run the full e3recon in a shell and, if needed, register the results in the database'

# Set up the command-line switches.
from e3pipe.misc.E3OptionParser import E3OptionParser
parser = E3OptionParser(_usage, _synopsis)
(opts, args) = parser.parse_args()

# Make sure we are passing some argument.
if not len(args) == 1:
    parser.print_help()
    parser.error('Please provide a single input file.')
rawFilePath = args[0]

# Print the start message.
from e3pipe.__logging__ import startmsg
startmsg()

# Run e3recon
chrono = E3Chrono()
_cmd = 'e3recon2.py %s' % rawFilePath
exitCode = __utils__.cmd(_cmd)
if exitCode == 0:
    logger.info('Run processed in %.3f s.' % chrono.stop())
else:
    logger.error('Processing terminated with exit code %d after %.3f s.' %\
                 (exitCode, chrono.stop()))
if doDbRegister():
    runInfo = E3RawDataInfo(rawFilePath)
    registerRun(runInfo, exitCode)