|
| 1 | +import ROOT |
| 2 | +import os |
| 3 | +ROOT.PyConfig.IgnoreCommandLineOptions = True |
| 4 | + |
| 5 | +from PhysicsTools.NanoAODTools.postprocessing.framework.eventloop import Module |
| 6 | + |
| 7 | +class htProducerCpp(Module): # HT producer, unclean jets only (no lepton overlap cleaning, no jet selection) |
| 8 | + def __init__(self): |
| 9 | + if "/htProducerCppWorker_cc.so" not in ROOT.gSystem.GetLibraries(): |
| 10 | + print "Load C++ htProducerCppWorker worker module" |
| 11 | + base = os.getenv("NANOAODTOOLS_BASE") |
| 12 | + if base: |
| 13 | + ROOT.gROOT.ProcessLine(".L %s/src/htProducerCppWorker.cc+O"%base) |
| 14 | + else: |
| 15 | + base = "%s/src/PhysicsTools/NanoAODTools"%os.getenv("CMSSW_BASE") |
| 16 | + ROOT.gSystem.Load("libPhysicsToolsNanoAODTools.so") |
| 17 | + ROOT.gROOT.ProcessLine(".L %s/interface/htProducerCppWorker.h"%base) |
| 18 | + self.worker = ROOT.htProducerCppWorker() |
| 19 | + pass |
| 20 | + def beginJob(self): |
| 21 | + pass |
| 22 | + def endJob(self): |
| 23 | + pass |
| 24 | + def beginFile(self, inputFile, outputFile, inputTree, wrappedOutputTree): |
| 25 | + self.initReaders(inputTree) # initReaders must be called in beginFile |
| 26 | + self.out = wrappedOutputTree |
| 27 | + self.out.branch("HT_pt", "F"); |
| 28 | + def endFile(self, inputFile, outputFile, inputTree, wrappedOutputTree): |
| 29 | + pass |
| 30 | + |
| 31 | + def initReaders(self,tree): # this function gets the pointers to Value and ArrayReaders and sets them in the C++ worker class |
| 32 | + self.nJet = tree.valueReader("nJet") |
| 33 | + self.Jet_pt = tree.arrayReader("Jet_pt") |
| 34 | + self.worker.setJets(self.nJet,self.Jet_pt) |
| 35 | + self._ttreereaderversion = tree._ttreereaderversion # self._ttreereaderversion must be set AFTER all calls to tree.valueReader or tree.arrayReader |
| 36 | + |
| 37 | + def analyze(self, event): |
| 38 | + """process event, return True (go to next module) or False (fail, go to next event)""" |
| 39 | + |
| 40 | + if event._tree._ttreereaderversion > self._ttreereaderversion: # do this check at every event, as other modules might have read further branches |
| 41 | + self.initReaders(event._tree) |
| 42 | + # do NOT access other branches in python between the check/call to initReaders and the call to C++ worker code |
| 43 | + output = self.worker.getHT() |
| 44 | + |
| 45 | + self.out.fillBranch("HT_pt", output) |
| 46 | + return True |
| 47 | + |
| 48 | + |
| 49 | +# define modules using the syntax 'name = lambda : constructor' to avoid having them loaded when not needed |
| 50 | + |
| 51 | +ht = lambda : htProducerCpp() |
0 commit comments