File indexing completed on 2024-11-25 02:29:50
0001 import os
0002 import sys
0003 import re
0004 import imp
0005 import timeit
0006 import subprocess
0007 from math import ceil
0008 from PhysicsTools.HeppyCore.framework.config import CFG
0009 from PhysicsTools.Heppy.utils.edmUtils import edmFileLs
0010 class CmsswPreprocessor :
0011 def __init__(self,configFile,command="cmsRun", addOrigAsSecondary=True, prefetch=False, options={}) :
0012 self.configFile=configFile
0013 self.command=command
0014 self.addOrigAsSecondary=addOrigAsSecondary
0015 self.prefetch=prefetch
0016 self.garbageFiles=[]
0017 self.options=options
0018
0019 def prefetchOneXrootdFile(self,fname):
0020 tmpdir = os.environ['TMPDIR'] if 'TMPDIR' in os.environ else "/tmp"
0021 rndchars = "".join([hex(ord(i))[2:] for i in os.urandom(8)])
0022 localfile = "%s/%s-%s.root" % (tmpdir, os.path.basename(fname).replace(".root",""), rndchars)
0023 try:
0024 print("Fetching %s to local path %s " % (fname,localfile))
0025 start = timeit.default_timer()
0026 subprocess.check_output(["xrdcp","-f","-N",fname,localfile])
0027 print("Time used for transferring the file locally: %s s" % (timeit.default_timer() - start))
0028 return (localfile,True)
0029 except:
0030 print("Could not save file locally, will run from remote")
0031 if os.path.exists(localfile): os.remove(localfile)
0032 return (fname,False)
0033 def maybePrefetchFiles(self,component):
0034 newfiles = []
0035 component._preprocessor_tempFiles = []
0036 for fn in component.files:
0037 if self.prefetch and fn.startswith("root://"):
0038 (newfile,istemp) = self.prefetchOneXrootdFile(fn)
0039 newfiles.append(newfile)
0040 if istemp:
0041 component._preprocessor_tempFiles.append(newfile)
0042 else:
0043 newfiles.append(fn)
0044 component.files = newfiles
0045 def endLoop(self,component):
0046 for fname in component._preprocessor_tempFiles:
0047 print("Removing local cache file ",fname)
0048 os.remove(fname)
0049 component._preprocessor_tempFiles = []
0050 def run(self,component,wd,firstEvent,nEvents):
0051 if firstEvent != 0: raise RuntimeError("The preprocessor can't skip events at the moment")
0052 fineSplitIndex, fineSplitFactor = getattr(component, 'fineSplit', (1,1))
0053 if fineSplitFactor > 1:
0054 if len(component.files) != 1:
0055 raise RuntimeError("Any component with fineSplit > 1 is supposed to have just a single file, while %s has %s" % (component.name, component.files))
0056 evtsInFile = edmFileLs(component.files[0])['events']
0057 if nEvents in (None, -1) or nEvents > evtsInFile: nEvents = evtsInFile
0058 nEvents = int(ceil(nEvents/float(fineSplitFactor)))
0059 firstEvent = fineSplitIndex * nEvents
0060
0061
0062 component.fineSplit = (1,1)
0063 if nEvents is None:
0064 nEvents = -1
0065 self.maybePrefetchFiles(component)
0066 cmsswConfig = imp.load_source("cmsRunProcess",os.path.expandvars(self.configFile))
0067 inputfiles= []
0068 for fn in component.files :
0069 if not re.match("file:.*",fn) and not re.match("root:.*",fn) :
0070 fn="file:"+fn
0071 inputfiles.append(fn)
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083 if hasattr(cmsswConfig, "initialize"):
0084 if len(self.options) == 0:
0085 cmsswConfig.process = cmsswConfig.initialize()
0086 else:
0087 cmsswConfig.process = cmsswConfig.initialize(**self.options)
0088 else:
0089 if len(self.options) == 0:
0090 pass
0091 else:
0092 print("WARNING: cmsswPreprocessor received options but can't pass on to cmsswConfig")
0093
0094 cmsswConfig.process.source.fileNames = inputfiles
0095
0096
0097 cmsswConfig.process.maxEvents.input = 1 if (fineSplitFactor>1 and nEvents==0) else nEvents
0098 cmsswConfig.process.source.skipEvents = cmsswConfig.cms.untracked.uint32(0 if (fineSplitFactor>1 and nEvents==0) else firstEvent)
0099
0100
0101 outfilename=wd+"/cmsswPreProcessing.root"
0102
0103 for module in cmsswConfig.process.endpaths.viewvalues():
0104 for outName in module.moduleNames():
0105 out = getattr(cmsswConfig.process,outName)
0106 if not hasattr(out,"fileName"): continue
0107 out.fileName = outfilename
0108
0109 if not hasattr(component,"options"):
0110 component.options = CFG(name="postCmsrunOptions")
0111
0112
0113
0114
0115
0116 if self.addOrigAsSecondary:
0117 component.options.secondaryInputFiles= component.files
0118 component.options.inputFiles=[outfilename]
0119 component.files=[outfilename]
0120
0121 configfile=wd+"/cmsRun_config.py"
0122 f = open(configfile, 'w')
0123 f.write(cmsswConfig.process.dumpPython())
0124 f.close()
0125 runstring="%s %s >& %s/cmsRun.log" % (self.command,configfile,wd)
0126 print("Running pre-processor: %s " %runstring)
0127 ret=os.system(runstring)
0128 if ret != 0:
0129 print("CMSRUN failed")
0130 exit(ret)
0131 return component