Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-05-03 02:53:27

0001 #include "CommonTools/PileupAlgos/interface/PuppiAlgo.h"
0002 #include "CommonTools/PileupAlgos/interface/PuppiContainer.h"
0003 #include "DataFormats/Candidate/interface/Candidate.h"
0004 #include "DataFormats/Candidate/interface/CandidateFwd.h"
0005 #include "DataFormats/Common/interface/Association.h"
0006 #include "DataFormats/Common/interface/ValueMap.h"
0007 #include "DataFormats/Common/interface/View.h"
0008 #include "DataFormats/GsfTrackReco/interface/GsfTrack.h"
0009 #include "DataFormats/GsfTrackReco/interface/GsfTrackFwd.h"
0010 #include "DataFormats/Math/interface/LorentzVector.h"
0011 #include "DataFormats/Math/interface/PtEtaPhiMass.h"
0012 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
0013 #include "DataFormats/PatCandidates/interface/PackedCandidate.h"
0014 #include "DataFormats/VertexReco/interface/VertexFwd.h"
0015 #include "FWCore/Framework/interface/Event.h"
0016 #include "FWCore/Framework/interface/EventSetup.h"
0017 #include "FWCore/Framework/interface/Frameworkfwd.h"
0018 #include "FWCore/Framework/interface/MakerMacros.h"
0019 #include "FWCore/Framework/interface/stream/EDProducer.h"
0020 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0021 
0022 #include <memory>
0023 
0024 // ------------------------------------------------------------------------------------------
0025 class PuppiProducer : public edm::stream::EDProducer<> {
0026 public:
0027   explicit PuppiProducer(const edm::ParameterSet&);
0028   ~PuppiProducer() override;
0029 
0030   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0031   typedef math::XYZTLorentzVector LorentzVector;
0032   typedef std::vector<LorentzVector> LorentzVectorCollection;
0033   typedef reco::VertexCollection VertexCollection;
0034   typedef edm::View<reco::Candidate> CandidateView;
0035   typedef std::vector<reco::PFCandidate> PFInputCollection;
0036   typedef std::vector<reco::PFCandidate> PFOutputCollection;
0037   typedef std::vector<pat::PackedCandidate> PackedOutputCollection;
0038   typedef edm::View<reco::PFCandidate> PFView;
0039   typedef edm::Association<reco::VertexCollection> CandToVertex;
0040 
0041 private:
0042   virtual void beginJob();
0043   void produce(edm::Event&, const edm::EventSetup&) override;
0044   virtual void endJob();
0045 
0046   edm::EDGetTokenT<CandidateView> tokenPFCandidates_;
0047   edm::EDGetTokenT<VertexCollection> tokenVertices_;
0048   edm::EDGetTokenT<CandToVertex> tokenVertexAssociation_;
0049   edm::EDGetTokenT<edm::ValueMap<int>> tokenVertexAssociationQuality_;
0050   edm::EDGetTokenT<PuppiContainer> tokenPuppiContainer_;
0051   edm::EDGetTokenT<PFOutputCollection> tokenPuppiCandidates_;
0052   edm::EDGetTokenT<PackedOutputCollection> tokenPackedPuppiCandidates_;
0053   edm::EDGetTokenT<double> puProxyValueToken_;
0054   edm::EDPutTokenT<edm::ValueMap<float>> ptokenPupOut_;
0055   edm::EDPutTokenT<edm::ValueMap<LorentzVector>> ptokenP4PupOut_;
0056   edm::EDPutTokenT<edm::ValueMap<reco::CandidatePtr>> ptokenValues_;
0057   edm::EDPutTokenT<pat::PackedCandidateCollection> ptokenPackedPuppiCandidates_;
0058   edm::EDPutTokenT<reco::PFCandidateCollection> ptokenPuppiCandidates_;
0059   edm::EDPutTokenT<double> ptokenNalgos_;
0060   edm::EDPutTokenT<std::vector<double>> ptokenRawAlphas_;
0061   edm::EDPutTokenT<std::vector<double>> ptokenAlphas_;
0062   edm::EDPutTokenT<std::vector<double>> ptokenAlphasMed_;
0063   edm::EDPutTokenT<std::vector<double>> ptokenAlphasRms_;
0064   std::string fPuppiName;
0065   std::string fPFName;
0066   std::string fPVName;
0067   bool fUseVertexAssociation;
0068   int vertexAssociationQuality_;
0069   bool fPuppiDiagnostics;
0070   bool fPuppiNoLep;
0071   bool fUseFromPVLooseTight;
0072   bool fUseDZ;
0073   bool fUseDZforPileup;
0074   double fDZCut;
0075   double fEtaMinUseDZ;
0076   double fPtMaxCharged;
0077   double fEtaMaxCharged;
0078   double fPtMaxPhotons;
0079   double fEtaMaxPhotons;
0080   uint fNumOfPUVtxsForCharged;
0081   double fDZCutForChargedFromPUVtxs;
0082   bool fUseExistingWeights;
0083   bool fClonePackedCands;
0084   int fVtxNdofCut;
0085   double fVtxZCut;
0086   bool fUsePUProxyValue;
0087   std::unique_ptr<PuppiContainer> fPuppiContainer;
0088   std::vector<RecoObj> fRecoObjCollection;
0089 };
0090 
0091 // ------------------------------------------------------------------------------------------
0092 PuppiProducer::PuppiProducer(const edm::ParameterSet& iConfig) {
0093   fPuppiDiagnostics = iConfig.getParameter<bool>("puppiDiagnostics");
0094   fPuppiNoLep = iConfig.getParameter<bool>("puppiNoLep");
0095   fUseFromPVLooseTight = iConfig.getParameter<bool>("UseFromPVLooseTight");
0096   fUseDZ = iConfig.getParameter<bool>("UseDeltaZCut");
0097   fUseDZforPileup = iConfig.getParameter<bool>("UseDeltaZCutForPileup");
0098   fDZCut = iConfig.getParameter<double>("DeltaZCut");
0099   fEtaMinUseDZ = iConfig.getParameter<double>("EtaMinUseDeltaZ");
0100   fPtMaxCharged = iConfig.getParameter<double>("PtMaxCharged");
0101   fEtaMaxCharged = iConfig.getParameter<double>("EtaMaxCharged");
0102   fPtMaxPhotons = iConfig.getParameter<double>("PtMaxPhotons");
0103   fEtaMaxPhotons = iConfig.getParameter<double>("EtaMaxPhotons");
0104   fNumOfPUVtxsForCharged = iConfig.getParameter<uint>("NumOfPUVtxsForCharged");
0105   fDZCutForChargedFromPUVtxs = iConfig.getParameter<double>("DeltaZCutForChargedFromPUVtxs");
0106   fUseExistingWeights = iConfig.getParameter<bool>("useExistingWeights");
0107   fClonePackedCands = iConfig.getParameter<bool>("clonePackedCands");
0108   fVtxNdofCut = iConfig.getParameter<int>("vtxNdofCut");
0109   fVtxZCut = iConfig.getParameter<double>("vtxZCut");
0110   fPuppiContainer = std::make_unique<PuppiContainer>(iConfig);
0111 
0112   tokenPFCandidates_ = consumes<CandidateView>(iConfig.getParameter<edm::InputTag>("candName"));
0113   tokenVertices_ = consumes<VertexCollection>(iConfig.getParameter<edm::InputTag>("vertexName"));
0114   fUseVertexAssociation = iConfig.getParameter<bool>("useVertexAssociation");
0115   vertexAssociationQuality_ = iConfig.getParameter<int>("vertexAssociationQuality");
0116   if (fUseVertexAssociation) {
0117     tokenVertexAssociation_ = consumes<CandToVertex>(iConfig.getParameter<edm::InputTag>("vertexAssociation"));
0118     tokenVertexAssociationQuality_ =
0119         consumes<edm::ValueMap<int>>(iConfig.getParameter<edm::InputTag>("vertexAssociation"));
0120   }
0121 
0122   fUsePUProxyValue = iConfig.getParameter<bool>("usePUProxyValue");
0123 
0124   if (fUsePUProxyValue) {
0125     puProxyValueToken_ = consumes<double>(iConfig.getParameter<edm::InputTag>("PUProxyValue"));
0126   }
0127 
0128   ptokenPupOut_ = produces<edm::ValueMap<float>>();
0129   ptokenP4PupOut_ = produces<edm::ValueMap<LorentzVector>>();
0130   ptokenValues_ = produces<edm::ValueMap<reco::CandidatePtr>>();
0131 
0132   if (fUseExistingWeights || fClonePackedCands)
0133     ptokenPackedPuppiCandidates_ = produces<pat::PackedCandidateCollection>();
0134   else {
0135     ptokenPuppiCandidates_ = produces<reco::PFCandidateCollection>();
0136   }
0137 
0138   if (fPuppiDiagnostics) {
0139     ptokenNalgos_ = produces<double>("PuppiNAlgos");
0140     ptokenRawAlphas_ = produces<std::vector<double>>("PuppiRawAlphas");
0141     ptokenAlphas_ = produces<std::vector<double>>("PuppiAlphas");
0142     ptokenAlphasMed_ = produces<std::vector<double>>("PuppiAlphasMed");
0143     ptokenAlphasRms_ = produces<std::vector<double>>("PuppiAlphasRms");
0144   }
0145 }
0146 // ------------------------------------------------------------------------------------------
0147 PuppiProducer::~PuppiProducer() {}
0148 // ------------------------------------------------------------------------------------------
0149 void PuppiProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0150   // Get PFCandidate Collection
0151   edm::Handle<CandidateView> hPFProduct;
0152   iEvent.getByToken(tokenPFCandidates_, hPFProduct);
0153   const CandidateView* pfCol = hPFProduct.product();
0154 
0155   // Get vertex collection w/PV as the first entry?
0156   edm::Handle<reco::VertexCollection> hVertexProduct;
0157   iEvent.getByToken(tokenVertices_, hVertexProduct);
0158   const reco::VertexCollection* pvCol = hVertexProduct.product();
0159 
0160   edm::Association<reco::VertexCollection> associatedPV;
0161   edm::ValueMap<int> associationQuality;
0162   if ((fUseVertexAssociation) && (!fUseExistingWeights)) {
0163     associatedPV = iEvent.get(tokenVertexAssociation_);
0164     associationQuality = iEvent.get(tokenVertexAssociationQuality_);
0165   }
0166 
0167   double puProxyValue = 0.;
0168   if (fUsePUProxyValue) {
0169     puProxyValue = iEvent.get(puProxyValueToken_);
0170   } else {
0171     for (auto const& vtx : *pvCol) {
0172       if (!vtx.isFake() && vtx.ndof() >= fVtxNdofCut && std::abs(vtx.z()) <= fVtxZCut)
0173         ++puProxyValue;
0174     }
0175   }
0176 
0177   std::vector<double> lWeights;
0178   if (!fUseExistingWeights) {
0179     //Fill the reco objects
0180     fRecoObjCollection.clear();
0181     fRecoObjCollection.reserve(pfCol->size());
0182     int iCand = 0;
0183     for (auto const& aPF : *pfCol) {
0184       RecoObj pReco;
0185       pReco.pt = aPF.pt();
0186       pReco.eta = aPF.eta();
0187       pReco.phi = aPF.phi();
0188       pReco.m = aPF.mass();
0189       pReco.rapidity = aPF.rapidity();
0190       pReco.charge = aPF.charge();
0191       pReco.pdgId = aPF.pdgId();
0192       const reco::Vertex* closestVtx = nullptr;
0193       double pDZ = -9999;
0194       double pD0 = -9999;
0195       uint pVtxId = 0;
0196       bool isLepton = ((std::abs(pReco.pdgId) == 11) || (std::abs(pReco.pdgId) == 13));
0197       const pat::PackedCandidate* lPack = dynamic_cast<const pat::PackedCandidate*>(&aPF);
0198 
0199       if (fUseVertexAssociation) {
0200         const reco::VertexRef& PVOrig = associatedPV[reco::CandidatePtr(hPFProduct, iCand)];
0201         int quality = associationQuality[reco::CandidatePtr(hPFProduct, iCand)];
0202         if (PVOrig.isNonnull() && (quality >= vertexAssociationQuality_)) {
0203           closestVtx = PVOrig.get();
0204           pVtxId = PVOrig.key();
0205         }
0206         if (std::abs(pReco.charge) == 0)
0207           pReco.id = 0;
0208         else if (fPuppiNoLep && isLepton)
0209           pReco.id = 3;
0210         else if (closestVtx != nullptr && pVtxId == 0)
0211           pReco.id = 1;  // Associated to main vertex
0212         else if (closestVtx != nullptr && pVtxId > 0)
0213           pReco.id = 2;  // Associated to PU
0214         else
0215           pReco.id = 0;  // Unassociated
0216       } else if (lPack == nullptr) {
0217         const reco::PFCandidate* pPF = dynamic_cast<const reco::PFCandidate*>(&aPF);
0218         double curdz = 9999;
0219         int closestVtxForUnassociateds = -9999;
0220         const reco::TrackRef aTrackRef = pPF->trackRef();
0221         bool lFirst = true;
0222         for (auto const& aV : *pvCol) {
0223           if (lFirst) {
0224             if (aTrackRef.isNonnull()) {
0225               pDZ = aTrackRef->dz(aV.position());
0226               pD0 = aTrackRef->d0();
0227             } else if (pPF->gsfTrackRef().isNonnull()) {
0228               pDZ = pPF->gsfTrackRef()->dz(aV.position());
0229               pD0 = pPF->gsfTrackRef()->d0();
0230             }
0231             lFirst = false;
0232             if (pDZ > -9999)
0233               pVtxId = 0;
0234           }
0235           if (aTrackRef.isNonnull() && aV.trackWeight(pPF->trackRef()) > 0) {
0236             closestVtx = &aV;
0237             break;
0238           }
0239           // in case it's unassocciated, keep more info
0240           double tmpdz = 99999;
0241           if (aTrackRef.isNonnull())
0242             tmpdz = aTrackRef->dz(aV.position());
0243           else if (pPF->gsfTrackRef().isNonnull())
0244             tmpdz = pPF->gsfTrackRef()->dz(aV.position());
0245           if (std::abs(tmpdz) < curdz) {
0246             curdz = std::abs(tmpdz);
0247             closestVtxForUnassociateds = pVtxId;
0248           }
0249           pVtxId++;
0250         }
0251         int tmpFromPV = 0;
0252         // mocking the miniAOD definitions
0253         if (std::abs(pReco.charge) > 0) {
0254           if (closestVtx != nullptr && pVtxId > 0)
0255             tmpFromPV = 0;
0256           if (closestVtx != nullptr && pVtxId == 0)
0257             tmpFromPV = 3;
0258           if (closestVtx == nullptr && closestVtxForUnassociateds == 0)
0259             tmpFromPV = 2;
0260           if (closestVtx == nullptr && closestVtxForUnassociateds != 0)
0261             tmpFromPV = 1;
0262         }
0263         pReco.dZ = pDZ;
0264         pReco.d0 = pD0;
0265         pReco.id = 0;
0266         if (std::abs(pReco.charge) == 0) {
0267           pReco.id = 0;
0268         } else {
0269           if (fPuppiNoLep && isLepton)
0270             pReco.id = 3;
0271           else if (tmpFromPV == 0) {
0272             pReco.id = 2;
0273             if (fNumOfPUVtxsForCharged > 0 and (pVtxId <= fNumOfPUVtxsForCharged) and
0274                 (std::abs(pDZ) < fDZCutForChargedFromPUVtxs))
0275               pReco.id = 1;
0276           } else if (tmpFromPV == 3)
0277             pReco.id = 1;
0278           else if (tmpFromPV == 1 || tmpFromPV == 2) {
0279             pReco.id = 0;
0280             if ((fPtMaxCharged > 0) and (pReco.pt > fPtMaxCharged))
0281               pReco.id = 1;
0282             else if (std::abs(pReco.eta) > fEtaMaxCharged)
0283               pReco.id = 1;
0284             else if ((fUseDZ) && (std::abs(pReco.eta) >= fEtaMinUseDZ) && (std::abs(pDZ) < fDZCut))
0285               pReco.id = 1;
0286             else if ((fUseDZforPileup) && (std::abs(pReco.eta) >= fEtaMinUseDZ) && (std::abs(pDZ) >= fDZCut))
0287               pReco.id = 2;
0288             else if (fUseFromPVLooseTight && tmpFromPV == 1)
0289               pReco.id = 2;
0290             else if (fUseFromPVLooseTight && tmpFromPV == 2)
0291               pReco.id = 1;
0292           }
0293         }
0294       } else if (lPack->vertexRef().isNonnull()) {
0295         pDZ = lPack->dz();
0296         pD0 = lPack->dxy();
0297         pReco.dZ = pDZ;
0298         pReco.d0 = pD0;
0299 
0300         pReco.id = 0;
0301         if (std::abs(pReco.charge) == 0) {
0302           pReco.id = 0;
0303         }
0304         if (std::abs(pReco.charge) > 0) {
0305           if (fPuppiNoLep && isLepton) {
0306             pReco.id = 3;
0307           } else if (lPack->fromPV() == 0) {
0308             pReco.id = 2;
0309             if ((fNumOfPUVtxsForCharged > 0) and (std::abs(pDZ) < fDZCutForChargedFromPUVtxs)) {
0310               for (size_t puVtx_idx = 1; puVtx_idx <= fNumOfPUVtxsForCharged && puVtx_idx < pvCol->size();
0311                    ++puVtx_idx) {
0312                 if (lPack->fromPV(puVtx_idx) >= 2) {
0313                   pReco.id = 1;
0314                   break;
0315                 }
0316               }
0317             }
0318           } else if (lPack->fromPV() == (pat::PackedCandidate::PVUsedInFit)) {
0319             pReco.id = 1;
0320           } else if (lPack->fromPV() == (pat::PackedCandidate::PVTight) ||
0321                      lPack->fromPV() == (pat::PackedCandidate::PVLoose)) {
0322             pReco.id = 0;
0323             if ((fPtMaxCharged > 0) and (pReco.pt > fPtMaxCharged))
0324               pReco.id = 1;
0325             else if (std::abs(pReco.eta) > fEtaMaxCharged)
0326               pReco.id = 1;
0327             else if ((fUseDZ) && (std::abs(pReco.eta) >= fEtaMinUseDZ) && (std::abs(pDZ) < fDZCut))
0328               pReco.id = 1;
0329             else if ((fUseDZforPileup) && (std::abs(pReco.eta) >= fEtaMinUseDZ) && (std::abs(pDZ) >= fDZCut))
0330               pReco.id = 2;
0331             else if (fUseFromPVLooseTight && lPack->fromPV() == (pat::PackedCandidate::PVLoose))
0332               pReco.id = 2;
0333             else if (fUseFromPVLooseTight && lPack->fromPV() == (pat::PackedCandidate::PVTight))
0334               pReco.id = 1;
0335           }
0336         }
0337       }
0338 
0339       fRecoObjCollection.push_back(pReco);
0340       iCand++;
0341     }
0342 
0343     fPuppiContainer->initialize(fRecoObjCollection);
0344     fPuppiContainer->setPUProxy(puProxyValue);
0345 
0346     //Compute the weights and get the particles
0347     lWeights = fPuppiContainer->puppiWeights();
0348   } else {
0349     //Use the existing weights
0350     int lPackCtr = 0;
0351     lWeights.reserve(pfCol->size());
0352     for (auto const& aPF : *pfCol) {
0353       const pat::PackedCandidate* lPack = dynamic_cast<const pat::PackedCandidate*>(&aPF);
0354       float curpupweight = -1.;
0355       if (lPack == nullptr) {
0356         // throw error
0357         throw edm::Exception(edm::errors::LogicError,
0358                              "PuppiProducer: cannot get weights since inputs are not PackedCandidates");
0359       } else {
0360         if (fPuppiNoLep) {
0361           curpupweight = lPack->puppiWeightNoLep();
0362         } else {
0363           curpupweight = lPack->puppiWeight();
0364         }
0365       }
0366       // Protect high pT photons (important for gamma to hadronic recoil balance)
0367       if ((fPtMaxPhotons > 0) && (lPack->pdgId() == 22) && (std::abs(lPack->eta()) < fEtaMaxPhotons) &&
0368           (lPack->pt() > fPtMaxPhotons))
0369         curpupweight = 1;
0370       lWeights.push_back(curpupweight);
0371       lPackCtr++;
0372     }
0373   }
0374 
0375   //Fill it into the event
0376   edm::ValueMap<float> lPupOut;
0377   edm::ValueMap<float>::Filler lPupFiller(lPupOut);
0378   lPupFiller.insert(hPFProduct, lWeights.begin(), lWeights.end());
0379   lPupFiller.fill();
0380 
0381   // This is a dummy to access the "translate" method which is a
0382   // non-static member function even though it doesn't need to be.
0383   // Will fix in the future.
0384   static const reco::PFCandidate dummySinceTranslateIsNotStatic;
0385 
0386   // Fill a new PF/Packed Candidate Collection and write out the ValueMap of the new p4s.
0387   // Since the size of the ValueMap must be equal to the input collection, we need
0388   // to search the "puppi" particles to find a match for each input. If none is found,
0389   // the input is set to have a four-vector of 0,0,0,0
0390   PFOutputCollection fPuppiCandidates;
0391   PackedOutputCollection fPackedPuppiCandidates;
0392 
0393   edm::ValueMap<LorentzVector> p4PupOut;
0394   LorentzVectorCollection puppiP4s;
0395   std::vector<reco::CandidatePtr> values(hPFProduct->size());
0396 
0397   int iCand = -1;
0398   puppiP4s.reserve(hPFProduct->size());
0399   if (fUseExistingWeights || fClonePackedCands)
0400     fPackedPuppiCandidates.reserve(hPFProduct->size());
0401   else
0402     fPuppiCandidates.reserve(hPFProduct->size());
0403   for (auto const& aCand : *hPFProduct) {
0404     ++iCand;
0405     std::unique_ptr<pat::PackedCandidate> pCand;
0406     std::unique_ptr<reco::PFCandidate> pfCand;
0407 
0408     if (fUseExistingWeights || fClonePackedCands) {
0409       const pat::PackedCandidate* cand = dynamic_cast<const pat::PackedCandidate*>(&aCand);
0410       if (!cand)
0411         throw edm::Exception(edm::errors::LogicError, "PuppiProducer: inputs are not PackedCandidates");
0412       pCand = std::make_unique<pat::PackedCandidate>(*cand);
0413     } else {
0414       auto id = dummySinceTranslateIsNotStatic.translatePdgIdToType(aCand.pdgId());
0415       const reco::PFCandidate* cand = dynamic_cast<const reco::PFCandidate*>(&aCand);
0416       pfCand = std::make_unique<reco::PFCandidate>(cand ? *cand : reco::PFCandidate(aCand.charge(), aCand.p4(), id));
0417     }
0418 
0419     // Here, we are using new weights computed and putting them in the packed candidates.
0420     if (fClonePackedCands && (!fUseExistingWeights)) {
0421       if (fPuppiNoLep)
0422         pCand->setPuppiWeight(pCand->puppiWeight(), lWeights[iCand]);
0423       else
0424         pCand->setPuppiWeight(lWeights[iCand], pCand->puppiWeightNoLep());
0425     }
0426 
0427     puppiP4s.emplace_back(lWeights[iCand] * aCand.px(),
0428                           lWeights[iCand] * aCand.py(),
0429                           lWeights[iCand] * aCand.pz(),
0430                           lWeights[iCand] * aCand.energy());
0431 
0432     // Here, we are using existing weights, or we're using packed candidates.
0433     // That is, whether or not we recomputed the weights, we store the
0434     // source candidate appropriately, and set the p4 of the packed candidate.
0435     if (fUseExistingWeights || fClonePackedCands) {
0436       pCand->setP4(puppiP4s.back());
0437       pCand->setSourceCandidatePtr(aCand.sourceCandidatePtr(0));
0438       fPackedPuppiCandidates.push_back(*pCand);
0439     } else {
0440       pfCand->setP4(puppiP4s.back());
0441       pfCand->setSourceCandidatePtr(aCand.sourceCandidatePtr(0));
0442       fPuppiCandidates.push_back(*pfCand);
0443     }
0444   }
0445 
0446   //Compute the modified p4s
0447   edm::ValueMap<LorentzVector>::Filler p4PupFiller(p4PupOut);
0448   p4PupFiller.insert(hPFProduct, puppiP4s.begin(), puppiP4s.end());
0449   p4PupFiller.fill();
0450 
0451   iEvent.emplace(ptokenPupOut_, lPupOut);
0452   iEvent.emplace(ptokenP4PupOut_, p4PupOut);
0453   if (fUseExistingWeights || fClonePackedCands) {
0454     edm::OrphanHandle<pat::PackedCandidateCollection> oh =
0455         iEvent.emplace(ptokenPackedPuppiCandidates_, fPackedPuppiCandidates);
0456     for (unsigned int ic = 0, nc = oh->size(); ic < nc; ++ic) {
0457       reco::CandidatePtr pkref(oh, ic);
0458       values[ic] = pkref;
0459     }
0460   } else {
0461     edm::OrphanHandle<reco::PFCandidateCollection> oh = iEvent.emplace(ptokenPuppiCandidates_, fPuppiCandidates);
0462     for (unsigned int ic = 0, nc = oh->size(); ic < nc; ++ic) {
0463       reco::CandidatePtr pkref(oh, ic);
0464       values[ic] = pkref;
0465     }
0466   }
0467   edm::ValueMap<reco::CandidatePtr> pfMap_p;
0468   edm::ValueMap<reco::CandidatePtr>::Filler filler(pfMap_p);
0469   filler.insert(hPFProduct, values.begin(), values.end());
0470   filler.fill();
0471   iEvent.emplace(ptokenValues_, pfMap_p);
0472 
0473   //////////////////////////////////////////////
0474   if (fPuppiDiagnostics && !fUseExistingWeights) {
0475     // all the different alphas per particle
0476     // THE alpha per particle
0477     std::vector<double> theAlphas(fPuppiContainer->puppiAlphas());
0478     std::vector<double> theAlphasMed(fPuppiContainer->puppiAlphasMed());
0479     std::vector<double> theAlphasRms(fPuppiContainer->puppiAlphasRMS());
0480     std::vector<double> alphas(fPuppiContainer->puppiRawAlphas());
0481     double nalgos(fPuppiContainer->puppiNAlgos());
0482 
0483     iEvent.emplace(ptokenRawAlphas_, alphas);
0484     iEvent.emplace(ptokenNalgos_, nalgos);
0485     iEvent.emplace(ptokenAlphas_, theAlphas);
0486     iEvent.emplace(ptokenAlphasMed_, theAlphasMed);
0487     iEvent.emplace(ptokenAlphasRms_, theAlphasRms);
0488   }
0489 }
0490 
0491 // ------------------------------------------------------------------------------------------
0492 void PuppiProducer::beginJob() {}
0493 // ------------------------------------------------------------------------------------------
0494 void PuppiProducer::endJob() {}
0495 // ------------------------------------------------------------------------------------------
0496 void PuppiProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0497   edm::ParameterSetDescription desc;
0498   desc.add<bool>("puppiDiagnostics", false);
0499   desc.add<bool>("puppiNoLep", false);
0500   desc.add<bool>("UseFromPVLooseTight", false);
0501   desc.add<bool>("UseDeltaZCut", true);
0502   desc.add<bool>("UseDeltaZCutForPileup", true);
0503   desc.add<double>("DeltaZCut", 0.3);
0504   desc.add<double>("EtaMinUseDeltaZ", 0.);
0505   desc.add<double>("PtMaxCharged", -1.);
0506   desc.add<double>("EtaMaxCharged", 99999.);
0507   desc.add<double>("PtMaxPhotons", -1.);
0508   desc.add<double>("EtaMaxPhotons", 2.5);
0509   desc.add<double>("PtMaxNeutrals", 200.);
0510   desc.add<double>("PtMaxNeutralsStartSlope", 0.);
0511   desc.add<uint>("NumOfPUVtxsForCharged", 0);
0512   desc.add<double>("DeltaZCutForChargedFromPUVtxs", 0.2);
0513   desc.add<bool>("useExistingWeights", false);
0514   desc.add<bool>("clonePackedCands", false);
0515   desc.add<int>("vtxNdofCut", 4);
0516   desc.add<double>("vtxZCut", 24);
0517   desc.add<edm::InputTag>("candName", edm::InputTag("particleFlow"));
0518   desc.add<edm::InputTag>("vertexName", edm::InputTag("offlinePrimaryVertices"));
0519   desc.add<bool>("useVertexAssociation", false);
0520   desc.add<int>("vertexAssociationQuality", 0);
0521   desc.add<edm::InputTag>("vertexAssociation", edm::InputTag(""));
0522   desc.add<bool>("applyCHS", true);
0523   desc.add<bool>("invertPuppi", false);
0524   desc.add<bool>("useExp", false);
0525   desc.add<double>("MinPuppiWeight", .01);
0526   desc.add<bool>("usePUProxyValue", false);
0527   desc.add<edm::InputTag>("PUProxyValue", edm::InputTag(""));
0528 
0529   PuppiAlgo::fillDescriptionsPuppiAlgo(desc);
0530 
0531   descriptions.add("PuppiProducer", desc);
0532 }
0533 //define this as a plug-in
0534 DEFINE_FWK_MODULE(PuppiProducer);