Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:01:08

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