File indexing completed on 2024-11-15 08:59:38
0001
0002
0003 """Script for building ROOT trees.
0004
0005 Thomas Burton, BNL, 5th September 2013, tpb@bnl.gov
0006
0007 For usage run
0008 build.py --help
0009
0010 Prerequisites:
0011
0012 -- ROOT installed with Python support (active by default for recent versions)
0013 -- ROOT.py should be accessible via $PYTHONPATH
0014 -- libeicsmear should be accessible vi $LD_LIBRARY_PATH
0015
0016 If in doubt, adding the ROOT library directory (e.g. $ROOTSYS/lib)
0017 to both LD_LIBRARY_PATH and PYTHONPATH should suffice.
0018
0019 """
0020
0021 import os
0022 import Queue
0023
0024
0025 ZIP = {'.gz': 'gzip', '.bz2': 'bzip2'}
0026 UNZIP = {'.gz': 'gunzip', '.bz2': 'bunzip2'}
0027
0028 class File:
0029 """Processes an input file into a ROOT tree file."""
0030
0031
0032
0033 queue = Queue.Queue()
0034
0035
0036 supported_extensions = {'.txt', '.dat'}
0037
0038 def __init__(self, filename, outdir, nevents, rezip):
0039 """Constructor.
0040
0041 Initialise with the input file and output information.
0042 Determines whether the input file is zipped.
0043
0044 """
0045 name, extension = os.path.splitext(filename)
0046
0047
0048 if extension in ZIP:
0049 self.zipext = extension
0050 self.rezip = rezip
0051
0052 name, extension = os.path.splitext(name)
0053 else:
0054 self.zipext = None
0055 self.rezip = False
0056 self.name = name
0057 self.ext = extension
0058 self.outdir = outdir
0059 self.nevents = nevents
0060
0061 def process(self):
0062 """Build the tree for the input the File was initialised with.
0063
0064 If the file is zipped, unzip it first and rezip it after making
0065 the ROOT tree (unless requested not to rezip).
0066
0067 """
0068 import subprocess
0069 if self.ext not in File.supported_extensions:
0070 return
0071 fullname = ''.join([self.name, self.ext])
0072
0073 if self.zipext:
0074 zipped_name = ''.join([fullname, self.zipext])
0075
0076 unzipped = not subprocess.call(
0077 [UNZIP[self.zipext], '-v', zipped_name])
0078 else:
0079 unzipped = False
0080
0081 try:
0082
0083 ROOT.BuildTree(fullname, self.outdir, self.nevents)
0084 except:
0085 print 'Error encountered building tree'
0086 if unzipped and self.rezip and self.zipext:
0087 print 'Rezipping', fullname
0088 subprocess.call([ZIP[self.zipext], '-v', fullname])
0089
0090
0091 def processor():
0092 """Function run by each thread.
0093
0094 Pops Files from the queue and processes them until there are no files
0095 remaining.
0096
0097 """
0098 while True:
0099 file = File.queue.get()
0100 file.process()
0101 File.queue.task_done()
0102
0103 def build_list(filelist, outdir='.', nevents=-1, nthreads = 1, rezip=True):
0104 """Build ROOT tree files from all the listed files.
0105
0106 Arguments:
0107 filelist -- a list of file names
0108 outdir -- the directory to which to write ROOT files [current directory]
0109 nevents -- the maximum number of events per file to process [all]
0110 nthreads -- the maximum number of threads permitted to run [1]
0111
0112 Zipped files (either gzip or bzip2) are unzipped then rezipped
0113 after the ROOT file has been made.
0114
0115 """
0116 import threading
0117
0118 for i in range(nthreads):
0119 t = threading.Thread(target=processor)
0120 t.daemon = True
0121 t.start()
0122
0123 for i in filelist:
0124 File.queue.put(File(i, outdir, nevents, rezip))
0125
0126 File.queue.join()
0127
0128 def parse():
0129 """Process command line arguments and return argparse Namespace."""
0130 from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
0131 parser = ArgumentParser(formatter_class=ArgumentDefaultsHelpFormatter,
0132 description='build trees from files in a list or directory')
0133 parser.add_argument('source', help='name of file list or directory')
0134 parser.add_argument('-o', '--outdir', default='.', help='output directory')
0135 parser.add_argument('-e', '--events', type=int, default=-1,
0136 help='number of events per file')
0137 parser.add_argument('-p', '--processes', type=int, default=1,
0138 help='number of parallel processes')
0139 parser.add_argument('--norezip', action='store_true',
0140 help='do not rezip files')
0141 return parser.parse_args()
0142
0143
0144
0145 if __name__ == "__main__":
0146 """Executes buildlist on all the files in a list or directory."""
0147
0148 options = parse()
0149
0150
0151 try:
0152 import ROOT
0153
0154
0155
0156
0157 try:
0158 ROOT.PyConfig.IgnoreCommandLineOptions = True
0159 except AttributeError:
0160 pass
0161
0162 if ROOT.gSystem.Load('libeicsmear') < 0:
0163 raise IOError('libeicsmear could not be located')
0164
0165 except Exception as error:
0166 print 'Error:', error
0167 quit()
0168
0169 if os.path.isfile(options.source):
0170 with open(options.source) as file:
0171 files = file.read().splitlines()
0172
0173 elif os.path.isdir(options.source):
0174 files = [os.path.join(options.source, file)
0175 for file in os.listdir(options.source)]
0176
0177 else:
0178 print options.source, 'not recognized... quitting'
0179 quit()
0180
0181 build_list(files, options.outdir, options.events, options.processes,
0182 not options.norezip)