CMS 3D CMS Logo

PuppiProducer.cc
Go to the documentation of this file.
1 // system include files
2 #include <memory>
3 
4 // user include files
19 //Main File
22 
23 
24 // ------------------------------------------------------------------------------------------
26  fPuppiDiagnostics = iConfig.getParameter<bool>("puppiDiagnostics");
27  fPuppiForLeptons = iConfig.getParameter<bool>("puppiForLeptons");
28  fUseFromPVLooseTight = iConfig.getParameter<bool>("UseFromPVLooseTight");
29  fUseDZ = iConfig.getParameter<bool>("UseDeltaZCut");
30  fDZCut = iConfig.getParameter<double>("DeltaZCut");
31  fEtaMinUseDZ = iConfig.getParameter<double>("EtaMinUseDeltaZ");
32  fPtMaxCharged = iConfig.getParameter<double>("PtMaxCharged");
33  fEtaMaxCharged = iConfig.getParameter<double>("EtaMaxCharged");
34  fNumOfPUVtxsForCharged = iConfig.getParameter<uint>("NumOfPUVtxsForCharged");
35  fDZCutForChargedFromPUVtxs = iConfig.getParameter<double>("DeltaZCutForChargedFromPUVtxs");
36  fUseExistingWeights = iConfig.getParameter<bool>("useExistingWeights");
37  fUseWeightsNoLep = iConfig.getParameter<bool>("useWeightsNoLep");
38  fClonePackedCands = iConfig.getParameter<bool>("clonePackedCands");
39  fVtxNdofCut = iConfig.getParameter<int>("vtxNdofCut");
40  fVtxZCut = iConfig.getParameter<double>("vtxZCut");
41  fPuppiContainer = std::unique_ptr<PuppiContainer> ( new PuppiContainer(iConfig) );
42 
44  = consumes<CandidateView>(iConfig.getParameter<edm::InputTag>("candName"));
46  = consumes<VertexCollection>(iConfig.getParameter<edm::InputTag>("vertexName"));
47 
48 
49  produces<edm::ValueMap<float> > ();
50  produces<edm::ValueMap<LorentzVector> > ();
51  produces< edm::ValueMap<reco::CandidatePtr> >();
52 
53  if (fUseExistingWeights || fClonePackedCands)
54  produces<pat::PackedCandidateCollection>();
55  else
56  produces<reco::PFCandidateCollection>();
57 
58  if (fPuppiDiagnostics){
59  produces<double> ("PuppiNAlgos");
60  produces<std::vector<double>> ("PuppiRawAlphas");
61  produces<std::vector<double>> ("PuppiAlphas");
62  produces<std::vector<double>> ("PuppiAlphasMed");
63  produces<std::vector<double>> ("PuppiAlphasRms");
64  }
65 }
66 // ------------------------------------------------------------------------------------------
68 }
69 // ------------------------------------------------------------------------------------------
71 
72  // Get PFCandidate Collection
73  edm::Handle<CandidateView> hPFProduct;
74  iEvent.getByToken(tokenPFCandidates_,hPFProduct);
75  const CandidateView *pfCol = hPFProduct.product();
76 
77  // Get vertex collection w/PV as the first entry?
79  iEvent.getByToken(tokenVertices_,hVertexProduct);
80  const reco::VertexCollection *pvCol = hVertexProduct.product();
81 
82  int npv = 0;
83  const reco::VertexCollection::const_iterator vtxEnd = pvCol->end();
84  for (reco::VertexCollection::const_iterator vtxIter = pvCol->begin(); vtxEnd != vtxIter; ++vtxIter) {
85  if (!vtxIter->isFake() && vtxIter->ndof()>=fVtxNdofCut && std::abs(vtxIter->z())<=fVtxZCut)
86  npv++;
87  }
88 
89  std::vector<double> lWeights;
90  std::vector<PuppiCandidate> lCandidates;
91  if (!fUseExistingWeights){
92  //Fill the reco objects
93  fRecoObjCollection.clear();
94  fRecoObjCollection.reserve(pfCol->size());
95  for(auto const& aPF : *pfCol) {
96  RecoObj pReco;
97  pReco.pt = aPF.pt();
98  pReco.eta = aPF.eta();
99  pReco.phi = aPF.phi();
100  pReco.m = aPF.mass();
101  pReco.rapidity = aPF.rapidity();
102  pReco.charge = aPF.charge();
103  const reco::Vertex *closestVtx = nullptr;
104  double pDZ = -9999;
105  double pD0 = -9999;
106  uint pVtxId = 0;
107  const pat::PackedCandidate *lPack = dynamic_cast<const pat::PackedCandidate*>(&aPF);
108  if(lPack == nullptr ) {
109 
110  const reco::PFCandidate *pPF = dynamic_cast<const reco::PFCandidate*>(&aPF);
111  double curdz = 9999;
112  int closestVtxForUnassociateds = -9999;
113  const reco::TrackRef aTrackRef = pPF->trackRef();
114  bool lFirst = true;
115  for(auto const& aV : *pvCol) {
116  if(lFirst) {
117  if ( aTrackRef.isNonnull()) {
118  pDZ = aTrackRef->dz(aV.position());
119  pD0 = aTrackRef->d0();
120  } else if (pPF->gsfTrackRef().isNonnull()) {
121  pDZ = pPF->gsfTrackRef()->dz(aV.position());
122  pD0 = pPF->gsfTrackRef()->d0();
123  }
124  lFirst = false;
125  if(pDZ > -9999) pVtxId = 0;
126  }
127  if(aTrackRef.isNonnull() && aV.trackWeight(pPF->trackRef())>0) {
128  closestVtx = &aV;
129  break;
130  }
131  // in case it's unassocciated, keep more info
132  double tmpdz = 99999;
133  if ( aTrackRef.isNonnull() ) tmpdz = aTrackRef ->dz(aV.position());
134  else if ( pPF->gsfTrackRef().isNonnull() ) tmpdz = pPF->gsfTrackRef()->dz(aV.position());
135  if (std::abs(tmpdz) < curdz){
136  curdz = std::abs(tmpdz);
137  closestVtxForUnassociateds = pVtxId;
138  }
139  pVtxId++;
140 
141  }
142  int tmpFromPV = 0;
143  // mocking the miniAOD definitions
144  if (std::abs(pReco.charge) > 0){
145  if (closestVtx != nullptr && pVtxId > 0) tmpFromPV = 0;
146  if (closestVtx != nullptr && pVtxId == 0) tmpFromPV = 3;
147  if (closestVtx == nullptr && closestVtxForUnassociateds == 0) tmpFromPV = 2;
148  if (closestVtx == nullptr && closestVtxForUnassociateds != 0) tmpFromPV = 1;
149  }
150  pReco.dZ = pDZ;
151  pReco.d0 = pD0;
152  pReco.id = 0;
153  if (std::abs(pReco.charge) == 0){ pReco.id = 0; }
154  else{
155  if (tmpFromPV == 0) {
156  pReco.id = 2;
157  if (fNumOfPUVtxsForCharged > 0 and (pVtxId <= fNumOfPUVtxsForCharged) and
159  pReco.id = 1;
160  } else if (tmpFromPV == 3){ pReco.id = 1; }
161  else if (tmpFromPV == 1 || tmpFromPV == 2){
162  pReco.id = 0;
163  if ((fPtMaxCharged > 0) and (pReco.pt > fPtMaxCharged))
164  pReco.id = 1;
165  else if (std::abs(pReco.eta) > fEtaMaxCharged)
166  pReco.id = 1;
167  else if ((fUseDZ) && (std::abs(pReco.eta) >= fEtaMinUseDZ))
168  pReco.id = (std::abs(pDZ) < fDZCut) ? 1 : 2;
169  else if (fUseFromPVLooseTight && tmpFromPV == 1)
170  pReco.id = 2;
171  else if (fUseFromPVLooseTight && tmpFromPV == 2)
172  pReco.id = 1;
173  }
174  }
175  }
176  else if(lPack->vertexRef().isNonnull() ) {
177  pDZ = lPack->dz();
178  pD0 = lPack->dxy();
179  pReco.dZ = pDZ;
180  pReco.d0 = pD0;
181 
182  pReco.id = 0;
183  if (std::abs(pReco.charge) == 0){ pReco.id = 0; }
184  if (std::abs(pReco.charge) > 0){
185  if (lPack->fromPV() == 0){
186  pReco.id = 2;
188  for (size_t puVtx_idx = 1; puVtx_idx <= fNumOfPUVtxsForCharged && puVtx_idx < pvCol->size();
189  ++puVtx_idx) {
190  if (lPack->fromPV(puVtx_idx) >= 2) {
191  pReco.id = 1;
192  break;
193  }
194  }
195  }
196  } else if (lPack->fromPV() == (pat::PackedCandidate::PVUsedInFit)){ pReco.id = 1; }
197  else if (lPack->fromPV() == (pat::PackedCandidate::PVTight) || lPack->fromPV() == (pat::PackedCandidate::PVLoose)){
198  pReco.id = 0;
199  if ((fPtMaxCharged > 0) and (pReco.pt > fPtMaxCharged))
200  pReco.id = 1;
201  else if (std::abs(pReco.eta) > fEtaMaxCharged)
202  pReco.id = 1;
203  else if ((fUseDZ) && (std::abs(pReco.eta) >= fEtaMinUseDZ))
204  pReco.id = (std::abs(pDZ) < fDZCut) ? 1 : 2;
206  pReco.id = 2;
208  pReco.id = 1;
209  }
210  }
211  }
212 
213  fRecoObjCollection.push_back(pReco);
214 
215  }
216 
217  fPuppiContainer->initialize(fRecoObjCollection);
218  fPuppiContainer->setNPV( npv );
219 
220  //Compute the weights and get the particles
221  lWeights = fPuppiContainer->puppiWeights();
222  lCandidates = fPuppiContainer->puppiParticles();
223  }
224  else{
225  //Use the existing weights
226  int lPackCtr = 0;
227  lWeights.reserve(pfCol->size());
228  for(auto const& aPF : *pfCol) {
229  const pat::PackedCandidate *lPack = dynamic_cast<const pat::PackedCandidate*>(&aPF);
230  float curpupweight = -1.;
231  if(lPack == nullptr ) {
232  // throw error
233  throw edm::Exception(edm::errors::LogicError,"PuppiProducer: cannot get weights since inputs are not PackedCandidates");
234  }
235  else{
236  if (fUseWeightsNoLep){ curpupweight = lPack->puppiWeightNoLep(); }
237  else{ curpupweight = lPack->puppiWeight(); }
238  }
239  lWeights.push_back(curpupweight);
240  lPackCtr++;
241  }
242  }
243 
244  //Fill it into the event
245  std::unique_ptr<edm::ValueMap<float> > lPupOut(new edm::ValueMap<float>());
246  edm::ValueMap<float>::Filler lPupFiller(*lPupOut);
247  lPupFiller.insert(hPFProduct,lWeights.begin(),lWeights.end());
248  lPupFiller.fill();
249 
250  // This is a dummy to access the "translate" method which is a
251  // non-static member function even though it doesn't need to be.
252  // Will fix in the future.
253  static const reco::PFCandidate dummySinceTranslateIsNotStatic;
254 
255  // Fill a new PF/Packed Candidate Collection and write out the ValueMap of the new p4s.
256  // Since the size of the ValueMap must be equal to the input collection, we need
257  // to search the "puppi" particles to find a match for each input. If none is found,
258  // the input is set to have a four-vector of 0,0,0,0
261  std::unique_ptr<edm::ValueMap<LorentzVector> > p4PupOut(new edm::ValueMap<LorentzVector>());
262  LorentzVectorCollection puppiP4s;
263  std::vector<reco::CandidatePtr> values(hPFProduct->size());
264 
265  int val = -1;
266  puppiP4s.reserve(hPFProduct->size());
268  fPackedPuppiCandidates->reserve(hPFProduct->size());
269  else
270  fPuppiCandidates->reserve(hPFProduct->size());
271  for ( auto const& aCand : *hPFProduct) {
272  val++;
273  std::unique_ptr<pat::PackedCandidate> pCand;
274  std::unique_ptr<reco::PFCandidate> pfCand;
276  const pat::PackedCandidate *cand = dynamic_cast<const pat::PackedCandidate*>(&aCand);
277  if(!cand)
278  throw edm::Exception(edm::errors::LogicError,"PuppiProducer: inputs are not PackedCandidates");
279  pCand.reset( new pat::PackedCandidate(*cand) );
280  } else {
281  auto id = dummySinceTranslateIsNotStatic.translatePdgIdToType(aCand.pdgId());
282  const reco::PFCandidate *cand = dynamic_cast<const reco::PFCandidate*>(&aCand);
283  pfCand.reset( new reco::PFCandidate( cand ? *cand : reco::PFCandidate(aCand.charge(), aCand.p4(), id) ) );
284  }
285 
286  //get an index to a pup in lCandidates: either fUseExistingWeights with no skips or get from fPuppiContainer
287  if ( fUseExistingWeights ) {
288  puppiP4s.emplace_back(lWeights[val]*aCand.px(), lWeights[val]*aCand.py(), lWeights[val]*aCand.pz(), lWeights[val]*aCand.energy());
289  }
290  else {
291  int iPuppiMatched = fPuppiContainer->recoToPup()[val];
292  if ( iPuppiMatched >= 0 ) {
293  auto const& puppiMatched = lCandidates[iPuppiMatched];
294  puppiP4s.emplace_back(puppiMatched.px,puppiMatched.py,puppiMatched.pz,puppiMatched.e);
295  if(fClonePackedCands) {
296  if(fPuppiForLeptons)
297  pCand->setPuppiWeight(pCand->puppiWeight(),lWeights[val]);
298  else
299  pCand->setPuppiWeight(lWeights[val],pCand->puppiWeightNoLep());
300  }
301  } else {
302  puppiP4s.emplace_back( 0, 0, 0, 0);
303  if(fClonePackedCands) {
304  pCand->setPuppiWeight(0,0);
305  }
306  }
307  }
308 
310  pCand->setP4(puppiP4s.back());
311  pCand->setSourceCandidatePtr( aCand.sourceCandidatePtr(0) );
312  fPackedPuppiCandidates->push_back(*pCand);
313  } else {
314  pfCand->setP4(puppiP4s.back());
315  pfCand->setSourceCandidatePtr( aCand.sourceCandidatePtr(0) );
316  fPuppiCandidates->push_back(*pfCand);
317  }
318  }
319 
320  //Compute the modified p4s
321  edm::ValueMap<LorentzVector>::Filler p4PupFiller(*p4PupOut);
322  p4PupFiller.insert(hPFProduct,puppiP4s.begin(), puppiP4s.end() );
323  p4PupFiller.fill();
324 
325  iEvent.put(std::move(lPupOut));
326  iEvent.put(std::move(p4PupOut));
329  for(unsigned int ic=0, nc = oh->size(); ic < nc; ++ic) {
330  reco::CandidatePtr pkref( oh, ic );
331  values[ic] = pkref;
332  }
333  } else {
335  for(unsigned int ic=0, nc = oh->size(); ic < nc; ++ic) {
336  reco::CandidatePtr pkref( oh, ic );
337  values[ic] = pkref;
338  }
339  }
340  std::unique_ptr<edm::ValueMap<reco::CandidatePtr> > pfMap_p(new edm::ValueMap<reco::CandidatePtr>());
342  filler.insert(hPFProduct, values.begin(), values.end());
343  filler.fill();
344  iEvent.put(std::move(pfMap_p));
345 
346 
349 
350  // all the different alphas per particle
351  // THE alpha per particle
352  std::unique_ptr<std::vector<double> > theAlphas(new std::vector<double>(fPuppiContainer->puppiAlphas()));
353  std::unique_ptr<std::vector<double> > theAlphasMed(new std::vector<double>(fPuppiContainer->puppiAlphasMed()));
354  std::unique_ptr<std::vector<double> > theAlphasRms(new std::vector<double>(fPuppiContainer->puppiAlphasRMS()));
355  std::unique_ptr<std::vector<double> > alphas(new std::vector<double>(fPuppiContainer->puppiRawAlphas()));
356  std::unique_ptr<double> nalgos(new double(fPuppiContainer->puppiNAlgos()));
357 
358  iEvent.put(std::move(alphas),"PuppiRawAlphas");
359  iEvent.put(std::move(nalgos),"PuppiNAlgos");
360  iEvent.put(std::move(theAlphas),"PuppiAlphas");
361  iEvent.put(std::move(theAlphasMed),"PuppiAlphasMed");
362  iEvent.put(std::move(theAlphasRms),"PuppiAlphasRms");
363  }
364 
365 }
366 
367 // ------------------------------------------------------------------------------------------
369 }
370 // ------------------------------------------------------------------------------------------
372 }
373 // ------------------------------------------------------------------------------------------
376  desc.add<bool>("puppiDiagnostics", false);
377  desc.add<bool>("puppiForLeptons", false);
378  desc.add<bool>("UseFromPVLooseTight", false);
379  desc.add<bool>("UseDeltaZCut", true);
380  desc.add<double>("DeltaZCut", 0.3);
381  desc.add<double>("EtaMinUseDeltaZ", 0.);
382  desc.add<double>("PtMaxCharged", 0.);
383  desc.add<double>("EtaMaxCharged", 99999.);
384  desc.add<double>("PtMaxNeutrals", 200.);
385  desc.add<double>("PtMaxNeutralsStartSlope", 0.);
386  desc.add<uint>("NumOfPUVtxsForCharged", 0);
387  desc.add<double>("DeltaZCutForChargedFromPUVtxs", 0.2);
388  desc.add<bool>("useExistingWeights", false);
389  desc.add<bool>("useWeightsNoLep", false);
390  desc.add<bool>("clonePackedCands", false);
391  desc.add<int>("vtxNdofCut", 4);
392  desc.add<double>("vtxZCut", 24);
393  desc.add<edm::InputTag>("candName", edm::InputTag("particleFlow"));
394  desc.add<edm::InputTag>("vertexName", edm::InputTag("offlinePrimaryVertices"));
395  desc.add<bool>("applyCHS", true);
396  desc.add<bool>("invertPuppi", false);
397  desc.add<bool>("useExp", false);
398  desc.add<double>("MinPuppiWeight", .01);
399 
401 
402  descriptions.add("PuppiProducer", desc);
403 }
404 //define this as a plug-in
float puppiWeight() const
virtual float dz(size_t ipv=0) const
dz with respect to the PV[ipv]
T getParameter(std::string const &) const
bool fUseFromPVLooseTight
Definition: PuppiProducer.h:51
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:125
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:251
float puppiWeightNoLep() const
Weight from full PUPPI.
float d0
Definition: RecoObj.h:28
double fDZCutForChargedFromPUVtxs
Definition: PuppiProducer.h:58
virtual void endJob()
bool fUseWeightsNoLep
Definition: PuppiProducer.h:60
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:517
std::vector< reco::PFCandidate > PFOutputCollection
Definition: PuppiProducer.h:35
static void fillDescriptionsPuppiAlgo(edm::ParameterSetDescription &desc)
Definition: PuppiAlgo.cc:216
Definition: RecoObj.h:4
bool fPuppiDiagnostics
Definition: PuppiProducer.h:49
void insert(const H &h, I begin, I end)
Definition: ValueMap.h:53
std::vector< pat::PackedCandidate > PackedOutputCollection
Definition: PuppiProducer.h:36
std::vector< RecoObj > fRecoObjCollection
Definition: PuppiProducer.h:65
size_type size() const
std::vector< Vertex > VertexCollection
collection of Vertex objects
Definition: VertexFwd.h:9
std::vector< LorentzVector > LorentzVectorCollection
Definition: PuppiProducer.h:31
virtual void beginJob()
const reco::VertexRef vertexRef() const
double fEtaMaxCharged
Definition: PuppiProducer.h:56
std::unique_ptr< PuppiContainer > fPuppiContainer
Definition: PuppiProducer.h:64
int charge
Definition: RecoObj.h:29
edm::EDGetTokenT< VertexCollection > tokenVertices_
Definition: PuppiProducer.h:45
float dZ
Definition: RecoObj.h:27
reco::TrackRef trackRef() const
Definition: PFCandidate.cc:442
float rapidity
Definition: RecoObj.h:17
float pt
Definition: RecoObj.h:17
int iEvent
Definition: GenABIO.cc:224
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
int id
Definition: RecoObj.h:18
float phi
Definition: RecoObj.h:17
const PVAssoc fromPV(size_t ipv=0) const
std::unique_ptr< PackedOutputCollection > fPackedPuppiCandidates
Definition: PuppiProducer.h:67
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
bool fClonePackedCands
Definition: PuppiProducer.h:61
void produce(edm::Event &, const edm::EventSetup &) override
bool fPuppiForLeptons
Definition: PuppiProducer.h:50
ParameterDescriptionBase * add(U const &iLabel, T const &value)
PuppiProducer(const edm::ParameterSet &)
float m
Definition: RecoObj.h:17
T const * product() const
Definition: Handle.h:74
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
double fPtMaxCharged
Definition: PuppiProducer.h:55
def uint(string)
void add(std::string const &label, ParameterSetDescription const &psetDescription)
ParticleType translatePdgIdToType(int pdgid) const
Definition: PFCandidate.cc:233
float eta
Definition: RecoObj.h:17
uint fNumOfPUVtxsForCharged
Definition: PuppiProducer.h:57
bool fUseExistingWeights
Definition: PuppiProducer.h:59
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:40
reco::GsfTrackRef gsfTrackRef() const
Definition: PFCandidate.cc:480
edm::EDGetTokenT< CandidateView > tokenPFCandidates_
Definition: PuppiProducer.h:44
virtual float dxy() const
dxy with respect to the PV ref
~PuppiProducer() override
std::unique_ptr< PFOutputCollection > fPuppiCandidates
Definition: PuppiProducer.h:66
def move(src, dest)
Definition: eostools.py:511
double fEtaMinUseDZ
Definition: PuppiProducer.h:54