Skip to content

Commit

Permalink
Merge pull request #7470 from cbernet/heppy_7_3_1
Browse files Browse the repository at this point in the history
Integration of Heppy in 74X
  • Loading branch information
cmsbuild committed Feb 3, 2015
2 parents bb1adf2 + 29f2a74 commit 2773aeb
Show file tree
Hide file tree
Showing 78 changed files with 2,675 additions and 1,098 deletions.
77 changes: 0 additions & 77 deletions PhysicsTools/Heppy/interface/HemisphereViaKt.h

This file was deleted.

53 changes: 53 additions & 0 deletions PhysicsTools/Heppy/interface/ReclusterJets.h
@@ -0,0 +1,53 @@
#ifndef PhysicsTools_Heppy_ReclusterJets_h
#define PhysicsTools_Heppy_ReclusterJets_h

#include <vector>
#include <iostream>
#include <cmath>
#include <TLorentzVector.h>
#include <TMath.h>
#include "DataFormats/Math/interface/LorentzVector.h"

#include <boost/shared_ptr.hpp>
#include <fastjet/internal/base.hh>
#include "fastjet/PseudoJet.hh"
#include "fastjet/JetDefinition.hh"
#include "fastjet/ClusterSequence.hh"
#include "fastjet/Selector.hh"
#include "fastjet/PseudoJet.hh"

namespace heppy{
class ReclusterJets {

public:
typedef math::XYZTLorentzVector LorentzVector;

ReclusterJets(const std::vector<LorentzVector> & objects, double ktpower, double rparam);

/// get grouping (inclusive jets)
std::vector<LorentzVector> getGrouping(double ptMin = 0.0);

/// get grouping (exclusive jets, until n are left)
std::vector<LorentzVector> getGroupingExclusive(int njets);
/// get grouping (exclusive jets, up to cut dcut)
std::vector<LorentzVector> getGroupingExclusive(double dcut);

private:
// pack the returns in a fwlite-friendly way
std::vector<LorentzVector> makeP4s(const std::vector<fastjet::PseudoJet> &jets) ;

// used to handle the inputs
std::vector<fastjet::PseudoJet> fjInputs_; // fastjet inputs

double ktpower_;
double rparam_;

/// fastjet outputs
typedef boost::shared_ptr<fastjet::ClusterSequence> ClusterSequencePtr;
ClusterSequencePtr fjClusterSeq_;
std::vector<fastjet::PseudoJet> inclusiveJets_;
std::vector<fastjet::PseudoJet> exclusiveJets_;
};
}
#endif

10 changes: 5 additions & 5 deletions PhysicsTools/Heppy/python/analyzers/core/Analyzer.py
Expand Up @@ -10,25 +10,25 @@ def declareHandles(self):
self.handles = {}
self.mchandles = {}

def beginLoop(self):
def beginLoop(self, setup):
'''Automatically called by Looper, for all analyzers.'''
super(Analyzer, self).beginLoop()
super(Analyzer, self).beginLoop(setup)
self.declareHandles()


def process(self, iEvent, event ):
def process(self, event ):
'''Automatically called by Looper, for all analyzers.
each analyzer in the sequence will be passed the same event instance.
each analyzer can access, modify, and store event information, of any type.'''
print self.cfg_ana.name
self.readCollections( iEvent )
self.readCollections( event.input )

def readCollections(self, iEvent ):
'''You must call this function at the beginning of the process
function of your child analyzer.'''
# if not self.beginLoopCalled:
# # necessary in case the user calls process to go straight to a given event, before looping
# self.beginLoop()
# self.beginLoop(setup)
for str,handle in self.handles.iteritems():
handle.Load( iEvent )
if self.cfg_comp.isMC:
Expand Down
52 changes: 33 additions & 19 deletions PhysicsTools/Heppy/python/analyzers/core/AutoFillTreeProducer.py
Expand Up @@ -20,18 +20,19 @@ def __init__(self, cfg_ana, cfg_comp, looperName):
if not getattr(self.cfg_ana, 'saveTLorentzVectors', False):
fourVectorType.removeVariable("p4")

## Declare how we store floats by default
self.tree.setDefaultFloatType("F"); # otherwise it's "D"

self.collections = {}
self.collections = {}
self.globalObjects = {}
self.globalVariables = {}
if hasattr(cfg_ana,"collections"):
self.collections=cfg_ana.collections
if hasattr(cfg_ana,"globalObjects"):
self.globalObjects=cfg_ana.globalObjects
if hasattr(cfg_ana,"globalVariables"):
self.globalVariables=cfg_ana.globalVariables
self.globalVariables = []
if hasattr(cfg_ana,"collections"):
self.collections=cfg_ana.collections
if hasattr(cfg_ana,"globalObjects"):
self.globalObjects=cfg_ana.globalObjects
if hasattr(cfg_ana,"globalVariables"):
self.globalVariables=cfg_ana.globalVariables

def beginLoop(self, setup) :
super(AutoFillTreeProducer, self).beginLoop(setup)

def declareHandles(self):
super(AutoFillTreeProducer, self).declareHandles()
Expand All @@ -58,6 +59,8 @@ def declareCoreVariables(self, tr, isMC):
# self.triggerBitCheckers.append( (T, TriggerBitChecker(trigVec)) )

if isMC:
## cross section
tr.var('xsec', float)
## PU weights
tr.var("puWeight")
## number of true interactions
Expand All @@ -74,11 +77,20 @@ def declareCoreVariables(self, tr, isMC):
else:
tr.vector('pdfWeight_%s' % pdf, nvals)

def declareVariables(self):
def declareVariables(self,setup):
isMC = self.cfg_comp.isMC
tree = self.tree
self.declareCoreVariables(tree, isMC)

if not hasattr(self.cfg_ana,"ignoreAnalyzerBookings") or not self.cfg_ana.ignoreAnalyzerBooking :
#import variables declared by the analyzers
if hasattr(setup,"globalVariables"):
self.globalVariables+=setup.globalVariables
if hasattr(setup,"globalObjects"):
self.globalObjects.update(setup.globalObjects)
if hasattr(setup,"collections"):
self.collections.update(setup.collections)

for v in self.globalVariables:
v.makeBranch(tree, isMC)
for o in self.globalObjects.itervalues():
Expand All @@ -102,19 +114,21 @@ def fillCoreVariables(self, tr, event, isMC):
# tr.fill("HLT_"+T, TC.check(event.object(), triggerResults))

if isMC:
## xsection, if available
tr.fill('xsec', getattr(self.cfg_comp,'xSection',1.0))
## PU weights, check if a PU analyzer actually filled it
if event.hasattr("nPU"):
tr.fill("nTrueInt", event.nPU)
tr.fill("puWeight", event.eventWeight)
else :
if hasattr(event,"nPU"):
tr.fill("nTrueInt", event.nPU)
tr.fill("puWeight", event.eventWeight)
else :
tr.fill("nTrueInt", -1)
tr.fill("puWeight", 1.0)
tr.fill("puWeight", 1.0)
tr.fill("genWeight", self.mchandles['GenInfo'].product().weight())
## PDF weights
if event.hasattr("pdfWeights") :
if hasattr(event,"pdfWeights") :
for (pdf,nvals) in self.pdfWeights:
if len(event.pdfWeights[pdf]) != nvals:
if len(event.pdfWeights[pdf]) != nvals:
raise RuntimeError, "PDF lenght mismatch for %s, declared %d but the event has %d" % (pdf,nvals,event.pdfWeights[pdf])
if self.scalar:
for i,w in enumerate(event.pdfWeights[pdf]):
Expand Down
11 changes: 10 additions & 1 deletion PhysicsTools/Heppy/python/analyzers/core/AutoHandle.py
Expand Up @@ -14,8 +14,17 @@ def __init__(self, label, type, mayFail=False, fallbackLabel=None):
self.type = type
self.mayFail = mayFail
Handle.__init__(self, self.type)
def product(self):
if not self.isLoaded :
self.ReallyLoad(self.event)
self.isLoaded=True
return super(AutoHandle,self).product()

def Load(self, event):
def Load(self, event): #is actually a reset state
self.event=event
self.isLoaded=False

def ReallyLoad(self, event):
'''Load self from a given event.
Call this function, and then just call self.product() to get the collection'''
Expand Down
10 changes: 5 additions & 5 deletions PhysicsTools/Heppy/python/analyzers/core/EventSelector.py
Expand Up @@ -18,7 +18,7 @@ class EventSelector( Analyzer ):
The process function of this analyzer returns False if the event number
is not in the toSelect list.
In this list, put actual CMS event numbers obtained by doing:
iEvent.eventAuxiliary().id().event()
event.input.eventAuxiliary().id().event()
not event processing number
in this python framework.
Expand All @@ -34,10 +34,10 @@ class EventSelector( Analyzer ):
with an other person at the event level.
"""

def process(self, iEvent, event):
run = iEvent.eventAuxiliary().id().run()
lumi = iEvent.eventAuxiliary().id().luminosityBlock()
eId = iEvent.eventAuxiliary().id().event()
def process(self, event):
run = event.input.eventAuxiliary().id().run()
lumi = event.input.eventAuxiliary().id().luminosityBlock()
eId = event.input.eventAuxiliary().id().event()
if eId in self.cfg_ana.toSelect:
# raise ValueError('found')
print 'Selecting', run, lumi, eId
Expand Down
8 changes: 4 additions & 4 deletions PhysicsTools/Heppy/python/analyzers/core/JSONAnalyzer.py
Expand Up @@ -38,8 +38,8 @@ def __init__(self, cfg_ana, cfg_comp, looperName):

self.rltInfo = RLTInfo()

def beginLoop(self):
super(JSONAnalyzer,self).beginLoop()
def beginLoop(self, setup):
super(JSONAnalyzer,self).beginLoop(setup)
self.counters.addCounter('JSON')
self.count = self.counters.counter('JSON')
self.count.register('All Lumis')
Expand Down Expand Up @@ -71,7 +71,7 @@ def process(self, event):
return False


def write(self):
super(JSONAnalyzer, self).write()
def write(self, setup):
super(JSONAnalyzer, self).write(setup)
self.rltInfo.write( self.dirName )

12 changes: 6 additions & 6 deletions PhysicsTools/Heppy/python/analyzers/core/PileUpAnalyzer.py
Expand Up @@ -89,13 +89,13 @@ def declareHandles(self):
else:
self.handles['vertices'] = AutoHandle( self.allVertices, 'std::vector<reco::Vertex>' )

def beginLoop(self):
super(PileUpAnalyzer,self).beginLoop()
def beginLoop(self, setup):
super(PileUpAnalyzer,self).beginLoop(setup)
self.averages.add('vertexWeight', Average('vertexWeight') )


def process(self, iEvent, event):
self.readCollections( iEvent )
def process(self, event):
self.readCollections( event.input )
## if component is embed return (has no trigger obj)
if self.cfg_comp.isEmbed :
return True
Expand Down Expand Up @@ -141,7 +141,7 @@ def process(self, iEvent, event):
self.averages['vertexWeight'].add( event.vertexWeight )
return True

def write(self):
super(PileUpAnalyzer, self).write()
def write(self, setup):
super(PileUpAnalyzer, self).write(setup)
if self.cfg_comp.isMC and self.doHists:
self.rawmcpileup.write()
21 changes: 12 additions & 9 deletions PhysicsTools/Heppy/python/analyzers/core/SkimAnalyzerCount.py
Expand Up @@ -14,23 +14,24 @@ class SkimAnalyzerCount( Analyzer ):

def __init__(self, cfg_ana, cfg_comp, looperName):
super(SkimAnalyzerCount, self).__init__(cfg_ana, cfg_comp, looperName)
self.useLumiBlocks = self.cfg_ana.useLumiBlocks if (hasattr(self.cfg_ana,'useLumiBlocks')) else True
self.useLumiBlocks = self.cfg_ana.useLumiBlocks if (hasattr(self.cfg_ana,'useLumiBlocks')) else False

def declareHandles(self):
super(SkimAnalyzerCount, self).declareHandles()
self.counterHandle = Handle("edm::MergeableCounter")
self.mchandles['GenInfo'] = AutoHandle( ('generator','',''), 'GenEventInfoProduct' )

def beginLoop(self):
super(SkimAnalyzerCount,self).beginLoop()
def beginLoop(self, setup):
super(SkimAnalyzerCount,self).beginLoop(setup)

self.counters.addCounter('SkimReport')
self.count = self.counters.counter('SkimReport')
self.count.register('All Events')
self.count.register('Sum Weights')
if self.cfg_comp.isMC:
self.count.register('Sum Weights')

if not self.useLumiBlocks:
print 'Will actually count events instead of accessing lumi blocks'
#print 'Will actually count events instead of accessing lumi blocks'
return True

print 'Counting the total events before the skim by accessing luminosity blocks'
Expand All @@ -47,16 +48,18 @@ def beginLoop(self):

if self.useLumiBlocks:
self.count.inc('All Events',totalEvents)
self.count.inc('Sum Weights',totalEvents)
if self.cfg_comp.isMC:
self.count.inc('Sum Weights',totalEvents)
print 'Done -> proceeding with the analysis'
else:
print 'Failed -> will have to actually count events (this can happen if the input dataset is not a CMG one)'



def process(self, iEvent, event):
def process(self, event):
if not self.useLumiBlocks:
self.readCollections( iEvent )
self.readCollections( event.input )
self.count.inc('All Events')
self.count.inc('Sum Weights', self.mchandles['GenInfo'].product().weight())
if self.cfg_comp.isMC:
self.count.inc('Sum Weights', self.mchandles['GenInfo'].product().weight())
return True

0 comments on commit 2773aeb

Please sign in to comment.