diff --git a/CommonTools/ParticleFlow/plugins/PFNoPileUpPacked.cc b/CommonTools/ParticleFlow/plugins/PFNoPileUpPacked.cc new file mode 100644 index 0000000000000..5a94c6cd3bb0b --- /dev/null +++ b/CommonTools/ParticleFlow/plugins/PFNoPileUpPacked.cc @@ -0,0 +1,91 @@ +// system include files +#include +#include + +// user include files +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" + +#include "DataFormats/Candidate/interface/Candidate.h" +#include "DataFormats/VertexReco/interface/VertexFwd.h" +#include "DataFormats/Common/interface/Association.h" + +#include "DataFormats/VertexReco/interface/Vertex.h" + +#include "FWCore/Utilities/interface/Exception.h" +#include "FWCore/Framework/interface/EventSetup.h" + +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" + +using namespace std; +using namespace edm; +using namespace reco; + +/**\class PFNoPileUpPacked +\brief Identifies pile-up candidates from a collection of Candidates, and +produces the corresponding collection of NoPileUpCandidates. + +\author Andreas Hinzmann +\date May 2021 + +*/ + +class PFNoPileUpPacked : public edm::stream::EDProducer<> { +public: + typedef edm::View CandidateView; + typedef edm::Association CandToVertex; + + explicit PFNoPileUpPacked(const edm::ParameterSet&); + + ~PFNoPileUpPacked() override = default; + + void produce(edm::Event&, const edm::EventSetup&) override; + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + +private: + edm::EDGetTokenT tokenCandidatesView_; + edm::EDGetTokenT tokenVertices_; + edm::EDGetTokenT tokenVertexAssociation_; + edm::EDGetTokenT> tokenVertexAssociationQuality_; + int vertexAssociationQuality_; +}; + +PFNoPileUpPacked::PFNoPileUpPacked(const edm::ParameterSet& iConfig) { + tokenCandidatesView_ = consumes(iConfig.getParameter("candidates")); + vertexAssociationQuality_ = iConfig.getParameter("vertexAssociationQuality"); + tokenVertexAssociation_ = consumes(iConfig.getParameter("vertexAssociation")); + tokenVertexAssociationQuality_ = + consumes>(iConfig.getParameter("vertexAssociation")); + produces>(); +} + +void PFNoPileUpPacked::produce(Event& iEvent, const EventSetup& iSetup) { + unique_ptr> pOutput(new edm::PtrVector); + Handle candidateView; + iEvent.getByToken(tokenCandidatesView_, candidateView); + const edm::Association& associatedPV = iEvent.get(tokenVertexAssociation_); + const edm::ValueMap& associationQuality = iEvent.get(tokenVertexAssociationQuality_); + for (const auto& p : candidateView->ptrs()) { + const reco::VertexRef& PVOrig = associatedPV[p]; + int quality = associationQuality[p]; + if (!(PVOrig.isNonnull() && (PVOrig.key() > 0) && (quality >= vertexAssociationQuality_))) + pOutput->push_back(p); + } + iEvent.put(std::move(pOutput)); +} + +void PFNoPileUpPacked::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("candidates", edm::InputTag("packedPFCandidates")); + desc.add("vertexAssociationQuality", 7); + desc.add("vertexAssociation", edm::InputTag("packedPrimaryVertexAssociationJME", "original")); + descriptions.addWithDefaultLabel(desc); +} + +DEFINE_FWK_MODULE(PFNoPileUpPacked); \ No newline at end of file diff --git a/CommonTools/ParticleFlow/plugins/PFPileUp.cc b/CommonTools/ParticleFlow/plugins/PFPileUp.cc index e3681db53e9c4..35b328035eda6 100644 --- a/CommonTools/ParticleFlow/plugins/PFPileUp.cc +++ b/CommonTools/ParticleFlow/plugins/PFPileUp.cc @@ -1,4 +1,20 @@ -#include "CommonTools/ParticleFlow/plugins/PFPileUp.h" +// system include files +#include +#include + +// user include files +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" + +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" + +#include "DataFormats/ParticleFlowCandidate/interface/PFCandidateFwd.h" +#include "DataFormats/VertexReco/interface/VertexFwd.h" +#include "DataFormats/Common/interface/Association.h" + +#include "CommonTools/ParticleFlow/interface/PFPileUpAlgo.h" #include "DataFormats/ParticleFlowCandidate/interface/PileUpPFCandidate.h" #include "DataFormats/ParticleFlowCandidate/interface/PileUpPFCandidateFwd.h" @@ -6,7 +22,6 @@ #include "FWCore/Framework/interface/ESHandle.h" -// #include "FWCore/MessageLogger/interface/MessageLogger.h" #include "FWCore/Utilities/interface/Exception.h" #include "FWCore/Framework/interface/EventSetup.h" @@ -14,12 +29,69 @@ using namespace std; using namespace edm; using namespace reco; +/**\class PFPileUp +\brief Identifies pile-up candidates from a collection of PFCandidates, and +produces the corresponding collection of PileUpCandidates. + +\author Colin Bernet +\date february 2008 +\updated Florian Beaudette 30/03/2012 + +*/ + +class PFPileUp : public edm::stream::EDProducer<> { +public: + typedef std::vector> PFCollection; + typedef edm::View PFView; + typedef std::vector PFCollectionByValue; + typedef edm::Association CandToVertex; + + explicit PFPileUp(const edm::ParameterSet&); + + ~PFPileUp() override; + + void produce(edm::Event&, const edm::EventSetup&) override; + +private: + PFPileUpAlgo pileUpAlgo_; + + /// PFCandidates to be analyzed + edm::EDGetTokenT tokenPFCandidates_; + /// fall-back token + edm::EDGetTokenT tokenPFCandidatesView_; + + /// vertices + edm::EDGetTokenT tokenVertices_; + + /// enable PFPileUp selection + bool enable_; + + /// verbose ? + bool verbose_; + + /// use the closest z vertex if a track is not in a vertex + bool checkClosestZVertex_; + + edm::EDGetTokenT tokenVertexAssociation_; + edm::EDGetTokenT> tokenVertexAssociationQuality_; + bool fUseVertexAssociation; + int vertexAssociationQuality_; +}; + PFPileUp::PFPileUp(const edm::ParameterSet& iConfig) { tokenPFCandidates_ = consumes(iConfig.getParameter("PFCandidates")); tokenPFCandidatesView_ = mayConsume(iConfig.getParameter("PFCandidates")); tokenVertices_ = consumes(iConfig.getParameter("Vertices")); + fUseVertexAssociation = iConfig.getParameter("useVertexAssociation"); + vertexAssociationQuality_ = iConfig.getParameter("vertexAssociationQuality"); + if (fUseVertexAssociation) { + tokenVertexAssociation_ = consumes(iConfig.getParameter("vertexAssociation")); + tokenVertexAssociationQuality_ = + consumes>(iConfig.getParameter("vertexAssociation")); + } + enable_ = iConfig.getParameter("Enable"); verbose_ = iConfig.getUntrackedParameter("verbose", false); @@ -93,10 +165,22 @@ void PFPileUp::produce(Event& iEvent, const EventSetup& iSetup) { "error."); } - pileUpAlgo_.process(*pfCandidatesRef, *vertices); - pOutput->insert( - pOutput->end(), pileUpAlgo_.getPFCandidatesFromPU().begin(), pileUpAlgo_.getPFCandidatesFromPU().end()); - + if (fUseVertexAssociation) { + const edm::Association& associatedPV = iEvent.get(tokenVertexAssociation_); + const edm::ValueMap& associationQuality = iEvent.get(tokenVertexAssociationQuality_); + PFCollection pfCandidatesFromPU; + for (auto& p : (*pfCandidatesRef)) { + const reco::VertexRef& PVOrig = associatedPV[p]; + int quality = associationQuality[p]; + if (PVOrig.isNonnull() && (PVOrig.key() > 0) && (quality >= vertexAssociationQuality_)) + pfCandidatesFromPU.push_back(p); + } + pOutput->insert(pOutput->end(), pfCandidatesFromPU.begin(), pfCandidatesFromPU.end()); + } else { + pileUpAlgo_.process(*pfCandidatesRef, *vertices); + pOutput->insert( + pOutput->end(), pileUpAlgo_.getPFCandidatesFromPU().begin(), pileUpAlgo_.getPFCandidatesFromPU().end()); + } // for ( PFCollection::const_iterator byValueBegin = pileUpAlgo_.getPFCandidatesFromPU().begin(), // byValueEnd = pileUpAlgo_.getPFCandidatesFromPU().end(), ibyValue = byValueBegin; // ibyValue != byValueEnd; ++ibyValue ) { @@ -108,3 +192,4 @@ void PFPileUp::produce(Event& iEvent, const EventSetup& iSetup) { iEvent.put(std::move(pOutput)); // iEvent.put(std::move(pOutputByValue)); } +DEFINE_FWK_MODULE(PFPileUp); diff --git a/CommonTools/ParticleFlow/plugins/PFPileUp.h b/CommonTools/ParticleFlow/plugins/PFPileUp.h deleted file mode 100644 index 6016386986150..0000000000000 --- a/CommonTools/ParticleFlow/plugins/PFPileUp.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef PhysicsTools_PFCandProducer_PFPileUp_ -#define PhysicsTools_PFCandProducer_PFPileUp_ - -// system include files -#include -#include - -// user include files -#include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/stream/EDProducer.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" - -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/MakerMacros.h" - -#include "DataFormats/ParticleFlowCandidate/interface/PFCandidateFwd.h" -#include "DataFormats/VertexReco/interface/VertexFwd.h" - -#include "CommonTools/ParticleFlow/interface/PFPileUpAlgo.h" - -/**\class PFPileUp -\brief Identifies pile-up candidates from a collection of PFCandidates, and -produces the corresponding collection of PileUpCandidates. - -\author Colin Bernet -\date february 2008 -\updated Florian Beaudette 30/03/2012 - -*/ - -class PFPileUp : public edm::stream::EDProducer<> { -public: - typedef std::vector > PFCollection; - typedef edm::View PFView; - typedef std::vector PFCollectionByValue; - - explicit PFPileUp(const edm::ParameterSet&); - - ~PFPileUp() override; - - void produce(edm::Event&, const edm::EventSetup&) override; - -private: - PFPileUpAlgo pileUpAlgo_; - - /// PFCandidates to be analyzed - edm::EDGetTokenT tokenPFCandidates_; - /// fall-back token - edm::EDGetTokenT tokenPFCandidatesView_; - - /// vertices - edm::EDGetTokenT tokenVertices_; - - /// enable PFPileUp selection - bool enable_; - - /// verbose ? - bool verbose_; - - /// use the closest z vertex if a track is not in a vertex - bool checkClosestZVertex_; -}; - -#endif diff --git a/CommonTools/ParticleFlow/plugins/SealModule.cc b/CommonTools/ParticleFlow/plugins/SealModule.cc index eb561b1381c31..134fee6951bf8 100644 --- a/CommonTools/ParticleFlow/plugins/SealModule.cc +++ b/CommonTools/ParticleFlow/plugins/SealModule.cc @@ -1,7 +1,6 @@ #include "FWCore/Framework/interface/MakerMacros.h" #include "CommonTools/ParticleFlow/plugins/PFMET.h" -#include "CommonTools/ParticleFlow/plugins/PFPileUp.h" #include "CommonTools/ParticleFlow/plugins/PFCandidateFwdPtrCollectionFilter.h" #include "CommonTools/ParticleFlow/plugins/PFJetFwdPtrProducer.h" #include "CommonTools/ParticleFlow/plugins/PFTauFwdPtrProducer.h" @@ -9,7 +8,6 @@ #include "CommonTools/ParticleFlow/plugins/DeltaBetaWeights.h" DEFINE_FWK_MODULE(PFMET); -DEFINE_FWK_MODULE(PFPileUp); DEFINE_FWK_MODULE(PFCandidateFwdPtrCollectionStringFilter); DEFINE_FWK_MODULE(PFCandidateFwdPtrCollectionPdgIdFilter); diff --git a/CommonTools/ParticleFlow/python/pfCHS_cff.py b/CommonTools/ParticleFlow/python/pfCHS_cff.py new file mode 100644 index 0000000000000..23dba83b7fa79 --- /dev/null +++ b/CommonTools/ParticleFlow/python/pfCHS_cff.py @@ -0,0 +1,15 @@ +import FWCore.ParameterSet.Config as cms +from CommonTools.ParticleFlow.pfNoPileUpJME_cff import adapt, pfPileUpJME +from CommonTools.RecoAlgos.sortedPackedPrimaryVertices_cfi import sortedPackedPrimaryVertices + +packedPrimaryVertexAssociationJME = sortedPackedPrimaryVertices.clone( + produceSortedVertices = False, + producePileUpCollection = False, + produceNoPileUpCollection = False +) +adapt(packedPrimaryVertexAssociationJME) + +from CommonTools.ParticleFlow.pfNoPileUpPacked_cfi import pfNoPileUpPacked as _pfNoPileUpPacked +pfCHS = _pfNoPileUpPacked.clone( + vertexAssociationQuality=pfPileUpJME.vertexAssociationQuality +) diff --git a/CommonTools/ParticleFlow/python/pfNoPileUpJME_cff.py b/CommonTools/ParticleFlow/python/pfNoPileUpJME_cff.py index 0907848fe1db6..caad529298bd3 100644 --- a/CommonTools/ParticleFlow/python/pfNoPileUpJME_cff.py +++ b/CommonTools/ParticleFlow/python/pfNoPileUpJME_cff.py @@ -2,16 +2,38 @@ from CommonTools.ParticleFlow.pfPileUp_cfi import pfPileUp as _pfPileUp from CommonTools.ParticleFlow.TopProjectors.pfNoPileUp_cfi import pfNoPileUp as _pfNoPileUp -from CommonTools.ParticleFlow.goodOfflinePrimaryVertices_cfi import * +from CommonTools.ParticleFlow.goodOfflinePrimaryVertices_cfi import goodOfflinePrimaryVertices +from CommonTools.RecoAlgos.primaryVertexAssociation_cfi import primaryVertexAssociation + +def adapt(primaryVertexAssociationJME): + # options for quality PrimaryDz = 6 (used in PUPPI) + primaryVertexAssociationJME.assignment.maxDzSigForPrimaryAssignment = 1e10 + primaryVertexAssociationJME.assignment.maxDzForPrimaryAssignment = 0.3 + primaryVertexAssociationJME.assignment.maxDzErrorForPrimaryAssignment = 1e10 + primaryVertexAssociationJME.assignment.NumOfPUVtxsForCharged = 2 + primaryVertexAssociationJME.assignment.PtMaxCharged = 20. + primaryVertexAssociationJME.assignment.EtaMinUseDz = 2.4 + primaryVertexAssociationJME.assignment.OnlyUseFirstDz = True + from Configuration.Eras.Modifier_phase2_common_cff import phase2_common + phase2_common.toModify( + primaryVertexAssociationJME.assignment, + maxDzForPrimaryAssignment=0.1, + EtaMinUseDz = 4.0 + ) +primaryVertexAssociationJME = primaryVertexAssociation.clone(vertices = 'goodOfflinePrimaryVertices') +adapt(primaryVertexAssociationJME) pfPileUpJME = _pfPileUp.clone(PFCandidates='particleFlowPtrs', - Vertices = 'goodOfflinePrimaryVertices', - checkClosestZVertex = False ) + useVertexAssociation = True, + vertexAssociationQuality = 7, + vertexAssociation = ('primaryVertexAssociationJME','original'), + ) pfNoPileUpJME = _pfNoPileUp.clone(topCollection = 'pfPileUpJME', bottomCollection = 'particleFlowPtrs' ) pfNoPileUpJMETask = cms.Task( goodOfflinePrimaryVertices, + primaryVertexAssociationJME, pfPileUpJME, pfNoPileUpJME ) diff --git a/CommonTools/ParticleFlow/python/pfPileUp_cfi.py b/CommonTools/ParticleFlow/python/pfPileUp_cfi.py index 4696123d18f91..025d6479ad2eb 100644 --- a/CommonTools/ParticleFlow/python/pfPileUp_cfi.py +++ b/CommonTools/ParticleFlow/python/pfPileUp_cfi.py @@ -8,5 +8,8 @@ # pile-up identification now enabled by default. To be studied for jets Enable = cms.bool(True), verbose = cms.untracked.bool(False), - checkClosestZVertex = cms.bool(True) + checkClosestZVertex = cms.bool(True), + useVertexAssociation = cms.bool(False), + vertexAssociationQuality = cms.int32(0), + vertexAssociation = cms.InputTag(''), ) diff --git a/CommonTools/PileupAlgos/plugins/PuppiProducer.cc b/CommonTools/PileupAlgos/plugins/PuppiProducer.cc index cfbeb0cc02ff9..a04967339319e 100644 --- a/CommonTools/PileupAlgos/plugins/PuppiProducer.cc +++ b/CommonTools/PileupAlgos/plugins/PuppiProducer.cc @@ -41,6 +41,13 @@ PuppiProducer::PuppiProducer(const edm::ParameterSet& iConfig) { tokenPFCandidates_ = consumes(iConfig.getParameter("candName")); tokenVertices_ = consumes(iConfig.getParameter("vertexName")); + fUseVertexAssociation = iConfig.getParameter("useVertexAssociation"); + vertexAssociationQuality_ = iConfig.getParameter("vertexAssociationQuality"); + if (fUseVertexAssociation) { + tokenVertexAssociation_ = consumes(iConfig.getParameter("vertexAssociation")); + tokenVertexAssociationQuality_ = + consumes>(iConfig.getParameter("vertexAssociation")); + } fUsePUProxyValue = iConfig.getParameter("usePUProxyValue"); @@ -80,6 +87,13 @@ void PuppiProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { iEvent.getByToken(tokenVertices_, hVertexProduct); const reco::VertexCollection* pvCol = hVertexProduct.product(); + edm::Association associatedPV; + edm::ValueMap associationQuality; + if ((fUseVertexAssociation) && (!fUseExistingWeights)) { + associatedPV = iEvent.get(tokenVertexAssociation_); + associationQuality = iEvent.get(tokenVertexAssociationQuality_); + } + double puProxyValue = 0.; if (fUsePUProxyValue) { puProxyValue = iEvent.get(puProxyValueToken_); @@ -95,6 +109,7 @@ void PuppiProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { //Fill the reco objects fRecoObjCollection.clear(); fRecoObjCollection.reserve(pfCol->size()); + int iCand = 0; for (auto const& aPF : *pfCol) { RecoObj pReco; pReco.pt = aPF.pt(); @@ -110,7 +125,25 @@ void PuppiProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { uint pVtxId = 0; bool isLepton = ((std::abs(pReco.pdgId) == 11) || (std::abs(pReco.pdgId) == 13)); const pat::PackedCandidate* lPack = dynamic_cast(&aPF); - if (lPack == nullptr) { + + if (fUseVertexAssociation) { + const reco::VertexRef& PVOrig = associatedPV[reco::CandidatePtr(hPFProduct, iCand)]; + int quality = associationQuality[reco::CandidatePtr(hPFProduct, iCand)]; + if (PVOrig.isNonnull() && (quality >= vertexAssociationQuality_)) { + closestVtx = PVOrig.get(); + pVtxId = PVOrig.key(); + } + if (std::abs(pReco.charge) == 0) + pReco.id = 0; + else if (fPuppiNoLep && isLepton) + pReco.id = 3; + else if (closestVtx != nullptr && pVtxId == 0) + pReco.id = 1; // Associated to main vertex + else if (closestVtx != nullptr && pVtxId > 0) + pReco.id = 2; // Associated to PU + else + pReco.id = 0; // Unassociated + } else if (lPack == nullptr) { const reco::PFCandidate* pPF = dynamic_cast(&aPF); double curdz = 9999; int closestVtxForUnassociateds = -9999; @@ -230,6 +263,7 @@ void PuppiProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { } fRecoObjCollection.push_back(pReco); + iCand++; } fPuppiContainer->initialize(fRecoObjCollection); @@ -401,6 +435,9 @@ void PuppiProducer::fillDescriptions(edm::ConfigurationDescriptions& description desc.add("vtxZCut", 24); desc.add("candName", edm::InputTag("particleFlow")); desc.add("vertexName", edm::InputTag("offlinePrimaryVertices")); + desc.add("useVertexAssociation", false); + desc.add("vertexAssociationQuality", 0); + desc.add("vertexAssociation", edm::InputTag("")); desc.add("applyCHS", true); desc.add("invertPuppi", false); desc.add("useExp", false); diff --git a/CommonTools/PileupAlgos/plugins/PuppiProducer.h b/CommonTools/PileupAlgos/plugins/PuppiProducer.h index befcf4c6a7f0a..bef5c7d797646 100644 --- a/CommonTools/PileupAlgos/plugins/PuppiProducer.h +++ b/CommonTools/PileupAlgos/plugins/PuppiProducer.h @@ -34,6 +34,7 @@ class PuppiProducer : public edm::stream::EDProducer<> { typedef std::vector PFOutputCollection; typedef std::vector PackedOutputCollection; typedef edm::View PFView; + typedef edm::Association CandToVertex; private: virtual void beginJob(); @@ -42,6 +43,8 @@ class PuppiProducer : public edm::stream::EDProducer<> { edm::EDGetTokenT tokenPFCandidates_; edm::EDGetTokenT tokenVertices_; + edm::EDGetTokenT tokenVertexAssociation_; + edm::EDGetTokenT> tokenVertexAssociationQuality_; edm::EDGetTokenT tokenPuppiContainer_; edm::EDGetTokenT tokenPuppiCandidates_; edm::EDGetTokenT tokenPackedPuppiCandidates_; @@ -59,6 +62,8 @@ class PuppiProducer : public edm::stream::EDProducer<> { std::string fPuppiName; std::string fPFName; std::string fPVName; + bool fUseVertexAssociation; + int vertexAssociationQuality_; bool fPuppiDiagnostics; bool fPuppiNoLep; bool fUseFromPVLooseTight; diff --git a/CommonTools/PileupAlgos/python/Puppi_cff.py b/CommonTools/PileupAlgos/python/Puppi_cff.py index 107aea9a49cab..9943d59afe49b 100644 --- a/CommonTools/PileupAlgos/python/Puppi_cff.py +++ b/CommonTools/PileupAlgos/python/Puppi_cff.py @@ -31,8 +31,9 @@ NumOfPUVtxsForCharged = 2, PtMaxCharged = 20., PtMaxNeutralsStartSlope = 20., - #candName = cms.string('packedPFCandidates'), - #vertexName = cms.string('offlineSlimmedPrimaryVertices'), + useVertexAssociation = True, + vertexAssociationQuality = 6, + vertexAssociation = ('primaryVertexAssociationJME','original'), clonePackedCands = False, # should only be set to True for MiniAOD algos = { 0: dict( @@ -96,10 +97,12 @@ ) ) +from Configuration.ProcessModifiers.pp_on_AA_cff import pp_on_AA +pp_on_AA.toModify(puppi, algos = []) +from Configuration.ProcessModifiers.run2_miniAOD_pp_on_AA_103X_cff import run2_miniAOD_pp_on_AA_103X +run2_miniAOD_pp_on_AA_103X.toModify(puppi,useVertexAssociation = False) # because the association is only run on cleanedParticleFlow + puppiNoLep = puppi.clone( puppiNoLep = True, PtMaxPhotons = 20. ) - -from Configuration.ProcessModifiers.pp_on_AA_cff import pp_on_AA -pp_on_AA.toModify(puppi, algos = []) diff --git a/CommonTools/PileupAlgos/test/recomputePuppiOnMiniAOD.py b/CommonTools/PileupAlgos/test/recomputePuppiOnMiniAOD.py new file mode 100644 index 0000000000000..8825604bf18c1 --- /dev/null +++ b/CommonTools/PileupAlgos/test/recomputePuppiOnMiniAOD.py @@ -0,0 +1,141 @@ +# Auto generated configuration file +# using: +# Revision: 1.19 +# Source: /local/reps/CMSSW/CMSSW/Configuration/Applications/python/ConfigBuilder.py,v +# with command line options: step5 --conditions auto:run2_mc --nThreads 2 -n 10 --era Run2_2016 --eventcontent MINIAODSIM --filein file:step3_inMINIAODSIM.root -s NANO --datatier NANOAODSIM --mc --fileout file:step5.root +import FWCore.ParameterSet.Config as cms + +from Configuration.Eras.Era_Run2_2016_cff import Run2_2016 + +process = cms.Process('NANO',Run2_2016) + +# import of standard configurations +process.load('Configuration.StandardSequences.Services_cff') +process.load('SimGeneral.HepPDTESSource.pythiapdt_cfi') +process.load('FWCore.MessageService.MessageLogger_cfi') +process.load('Configuration.EventContent.EventContent_cff') +process.load('SimGeneral.MixingModule.mixNoPU_cfi') +process.load('Configuration.StandardSequences.GeometryRecoDB_cff') +process.load('Configuration.StandardSequences.MagneticField_cff') +process.load('Configuration.StandardSequences.EndOfProcess_cff') +process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') + +process.maxEvents = cms.untracked.PSet( + input = cms.untracked.int32(10), + output = cms.optional.untracked.allowed(cms.int32,cms.PSet) +) + +# Input source +process.source = cms.Source("PoolSource", + fileNames = cms.untracked.vstring('file:/afs/cern.ch/user/h/hinzmann/stable_13TeV/jetmet/mtd/CMSSW_12_0_0_pre3/src/25202.0_TTbar_13+TTbar_13+DIGIUP15_PU25+RECOUP15_PU25+HARVESTUP15_PU25+NANOUP15_PU25/step3_inMINIAODSIM.root'), + secondaryFileNames = cms.untracked.vstring() +) + +process.options = cms.untracked.PSet( + FailPath = cms.untracked.vstring(), + IgnoreCompletely = cms.untracked.vstring(), + Rethrow = cms.untracked.vstring(), + SkipEvent = cms.untracked.vstring(), + allowUnscheduled = cms.obsolete.untracked.bool, + canDeleteEarly = cms.untracked.vstring(), + emptyRunLumiMode = cms.obsolete.untracked.string, + eventSetup = cms.untracked.PSet( + forceNumberOfConcurrentIOVs = cms.untracked.PSet( + + ), + numberOfConcurrentIOVs = cms.untracked.uint32(1) + ), + fileMode = cms.untracked.string('FULLMERGE'), + forceEventSetupCacheClearOnNewRun = cms.untracked.bool(False), + makeTriggerResults = cms.obsolete.untracked.bool, + numberOfConcurrentLuminosityBlocks = cms.untracked.uint32(1), + numberOfConcurrentRuns = cms.untracked.uint32(1), + numberOfStreams = cms.untracked.uint32(0), + numberOfThreads = cms.untracked.uint32(1), + printDependencies = cms.untracked.bool(False), + sizeOfStackForThreadsInKB = cms.optional.untracked.uint32, + throwIfIllegalParameter = cms.untracked.bool(True), + wantSummary = cms.untracked.bool(False) +) + +# Production Info +process.configurationMetadata = cms.untracked.PSet( + annotation = cms.untracked.string('step5 nevts:10'), + name = cms.untracked.string('Applications'), + version = cms.untracked.string('$Revision: 1.19 $') +) + +# Output definition + +process.MINIAODSIMoutput = cms.OutputModule("PoolOutputModule", + compressionAlgorithm = cms.untracked.string('LZMA'), + compressionLevel = cms.untracked.int32(9), + dataset = cms.untracked.PSet( + dataTier = cms.untracked.string('MINIAODSIM'), + filterName = cms.untracked.string('') + ), + fileName = cms.untracked.string('file:updatedMINIAODSIM.root'), + outputCommands = process.MINIAODSIMEventContent.outputCommands +) + +# Additional output definition + +# Other statements +from Configuration.AlCa.GlobalTag import GlobalTag +process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:run2_mc', '') + +# Rerun PUPPI MET and ak4 jets (but not ak8) +from PhysicsTools.PatAlgos.tools.helpers import getPatAlgosToolsTask, addToProcessAndTask +task = getPatAlgosToolsTask(process) +from PhysicsTools.PatAlgos.slimming.puppiForMET_cff import makePuppiesFromMiniAOD +makePuppiesFromMiniAOD(process,True) +process.puppi.useExistingWeights = False +process.puppiNoLep.useExistingWeights = False +from PhysicsTools.PatUtils.tools.runMETCorrectionsAndUncertainties import runMetCorAndUncFromMiniAOD +runMetCorAndUncFromMiniAOD(process,isData=False,metType="Puppi",postfix="Puppi",jetFlavor="AK4PFPuppi",recoMetFromPFCs=True) +from PhysicsTools.PatAlgos.patPuppiJetSpecificProducer_cfi import patPuppiJetSpecificProducer +addToProcessAndTask('patPuppiJetSpecificProducer', patPuppiJetSpecificProducer.clone(src=cms.InputTag("patJetsPuppi")), process, task) +from PhysicsTools.PatAlgos.tools.jetTools import updateJetCollection +updateJetCollection( + process, + labelName = 'PuppiJetSpecific', + jetSource = cms.InputTag('patJetsPuppi'), +) +process.updatedPatJetsPuppiJetSpecific.userData.userFloats.src = ['patPuppiJetSpecificProducer:puppiMultiplicity', 'patPuppiJetSpecificProducer:neutralPuppiMultiplicity', 'patPuppiJetSpecificProducer:neutralHadronPuppiMultiplicity', 'patPuppiJetSpecificProducer:photonPuppiMultiplicity', 'patPuppiJetSpecificProducer:HFHadronPuppiMultiplicity', 'patPuppiJetSpecificProducer:HFEMPuppiMultiplicity' ] +addToProcessAndTask('slimmedJetsPuppi', process.updatedPatJetsPuppiJetSpecific.clone(), process, task) +del process.updatedPatJetsPuppiJetSpecific +process.puppiSequence = cms.Sequence(process.puppiMETSequence+process.fullPatMetSequencePuppi+process.patPuppiJetSpecificProducer+process.slimmedJetsPuppi) + +# Example how to not use vertex fit for track-vertex-association, but only dz +#process.packedPrimaryVertexAssociationJME.assignment.useVertexFit = False +#process.packedPrimaryVertexAssociationJME.assignment.maxDzSigForPrimaryAssignment = 5.0 +#process.packedPrimaryVertexAssociationJME.assignment.maxDzForPrimaryAssignment = 0.1 +#process.packedPrimaryVertexAssociationJME.assignment.maxDzErrorForPrimaryAssignment = 0.05 +#process.packedPrimaryVertexAssociationJME.assignment.OnlyUseFirstDz = False +#process.pfCHS.vertexAssociationQuality = 6 + +# Path and EndPath definitions +process.puppi_step = cms.Path(process.puppiSequence) +process.endjob_step = cms.EndPath(process.endOfProcess) +process.MINIAODSIMoutput_step = cms.EndPath(process.MINIAODSIMoutput) + +# Schedule definition +process.schedule = cms.Schedule(process.puppi_step,process.endjob_step,process.MINIAODSIMoutput_step) +from PhysicsTools.PatAlgos.tools.helpers import associatePatAlgosToolsTask +associatePatAlgosToolsTask(process) + +#Setup FWK for multithreaded +process.options.numberOfThreads=cms.untracked.uint32(2) +process.options.numberOfStreams=cms.untracked.uint32(0) +process.options.numberOfConcurrentLuminosityBlocks=cms.untracked.uint32(1) + +# customisation of the process. + +# End of customisation functions + +# Customisation from command line + +# Add early deletion of temporary data products to reduce peak memory need +from Configuration.StandardSequences.earlyDeleteSettings_cff import customiseEarlyDelete +process = customiseEarlyDelete(process) +# End adding early deletion diff --git a/CommonTools/RecoAlgos/interface/PrimaryVertexAssignment.h b/CommonTools/RecoAlgos/interface/PrimaryVertexAssignment.h index da7626850313e..011ee2ecee2d2 100644 --- a/CommonTools/RecoAlgos/interface/PrimaryVertexAssignment.h +++ b/CommonTools/RecoAlgos/interface/PrimaryVertexAssignment.h @@ -12,6 +12,7 @@ #include "DataFormats/Candidate/interface/Candidate.h" #include "DataFormats/ParticleFlowCandidate/interface/PFCandidateFwd.h" #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h" +#include "DataFormats/PatCandidates/interface/PackedCandidate.h" #include "DataFormats/VertexReco/interface/VertexFwd.h" #include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h" @@ -41,7 +42,13 @@ class PrimaryVertexAssignment { maxDxySigForNotReconstructedPrimary_(iConfig.getParameter("maxDxySigForNotReconstructedPrimary")), maxDxyForNotReconstructedPrimary_(iConfig.getParameter("maxDxyForNotReconstructedPrimary")), useTiming_(iConfig.getParameter("useTiming")), - preferHighRanked_(iConfig.getParameter("preferHighRanked")) {} + useVertexFit_(iConfig.getParameter("useVertexFit")), + preferHighRanked_(iConfig.getParameter("preferHighRanked")), + fNumOfPUVtxsForCharged_(iConfig.getParameter("NumOfPUVtxsForCharged")), + fDzCutForChargedFromPUVtxs_(iConfig.getParameter("DzCutForChargedFromPUVtxs")), + fPtMaxCharged_(iConfig.getParameter("PtMaxCharged")), + fEtaMinUseDz_(iConfig.getParameter("EtaMinUseDz")), + fOnlyUseFirstDz_(iConfig.getParameter("OnlyUseFirstDz")) {} ~PrimaryVertexAssignment() {} @@ -54,6 +61,15 @@ class PrimaryVertexAssignment { const edm::View& jets, const TransientTrackBuilder& builder) const; + std::pair chargedHadronVertex( + const reco::VertexCollection& vertices, + int iVertex, + const reco::Track* track, + float trackTime, + float trackTimeResolution, // <0 if timing not available for this object + const edm::View& jets, + const TransientTrackBuilder& builder) const; + std::pair chargedHadronVertex( const reco::VertexCollection& vertices, const reco::TrackRef& trackRef, @@ -75,13 +91,38 @@ class PrimaryVertexAssignment { } if (pfcand.gsfTrackRef().isNull()) { if (pfcand.trackRef().isNull()) - return std::pair(-1, PrimaryVertexAssignment::Unassigned); + return {-1, PrimaryVertexAssignment::Unassigned}; else return chargedHadronVertex(vertices, pfcand.trackRef(), time, timeResolution, jets, builder); } return chargedHadronVertex( vertices, reco::TrackRef(), &(*pfcand.gsfTrackRef()), time, timeResolution, jets, builder); } + + std::pair chargedHadronVertex(const reco::VertexCollection& vertices, + const pat::PackedCandidate& pfcand, + const edm::View& jets, + const TransientTrackBuilder& builder) const { + float time = 0, timeResolution = -1; + if (useTiming_ && pfcand.timeError() > 0) { + time = pfcand.time(); + timeResolution = pfcand.timeError(); + } + if (!pfcand.hasTrackDetails()) + return {-1, PrimaryVertexAssignment::Unassigned}; + else + return chargedHadronVertex( + vertices, + (useVertexFit_ && (pfcand.pvAssociationQuality() >= pat::PackedCandidate::UsedInFitLoose)) + ? pfcand.vertexRef().key() + : -1, + &pfcand.pseudoTrack(), + time, + timeResolution, + jets, + builder); + } + std::pair chargedHadronVertex(const reco::VertexCollection& vertices, const reco::RecoChargedRefCandidate& chcand, const edm::ValueMap* trackTimeTag, @@ -94,7 +135,7 @@ class PrimaryVertexAssignment { timeResolution = (*trackTimeResoTag)[chcand.track()]; } if (chcand.track().isNull()) - return std::pair(-1, PrimaryVertexAssignment::Unassigned); + return {-1, PrimaryVertexAssignment::Unassigned}; return chargedHadronVertex(vertices, chcand.track(), time, timeResolution, jets, builder); } @@ -111,7 +152,13 @@ class PrimaryVertexAssignment { double maxDxySigForNotReconstructedPrimary_; double maxDxyForNotReconstructedPrimary_; bool useTiming_; + bool useVertexFit_; bool preferHighRanked_; + int fNumOfPUVtxsForCharged_; + double fDzCutForChargedFromPUVtxs_; + double fPtMaxCharged_; + double fEtaMinUseDz_; + bool fOnlyUseFirstDz_; }; #endif diff --git a/CommonTools/RecoAlgos/plugins/PrimaryVertexSorter.cc b/CommonTools/RecoAlgos/plugins/PrimaryVertexSorter.cc index c9dad79418207..b019100fa3e3b 100644 --- a/CommonTools/RecoAlgos/plugins/PrimaryVertexSorter.cc +++ b/CommonTools/RecoAlgos/plugins/PrimaryVertexSorter.cc @@ -6,3 +6,5 @@ typedef PrimaryVertexSorter > RecoCha DEFINE_FWK_MODULE(RecoChargedRefCandidatePrimaryVertexSorter); typedef PrimaryVertexSorter > PFCandidatePrimaryVertexSorter; DEFINE_FWK_MODULE(PFCandidatePrimaryVertexSorter); +typedef PrimaryVertexSorter > PackedCandidatePrimaryVertexSorter; +DEFINE_FWK_MODULE(PackedCandidatePrimaryVertexSorter); diff --git a/CommonTools/RecoAlgos/plugins/PrimaryVertexSorter.h b/CommonTools/RecoAlgos/plugins/PrimaryVertexSorter.h index 300ce6cb2c14b..e4e8e5b98cc4e 100644 --- a/CommonTools/RecoAlgos/plugins/PrimaryVertexSorter.h +++ b/CommonTools/RecoAlgos/plugins/PrimaryVertexSorter.h @@ -20,6 +20,7 @@ #include "CommonTools/RecoAlgos/interface/PrimaryVertexAssignment.h" #include "CommonTools/RecoAlgos/interface/PrimaryVertexSorting.h" +#include "DataFormats/PatCandidates/interface/PackedCandidate.h" /**\class PrimaryVertexSorter * \author Andrea Rizzi @@ -311,6 +312,10 @@ template <> inline void PrimaryVertexSorter>::doConsumesForTiming(const edm::ParameterSet& iConfig) { } +template <> +inline void PrimaryVertexSorter>::doConsumesForTiming( + const edm::ParameterSet& iConfig) {} + template <> inline bool PrimaryVertexSorter>::needsProductsForTiming() { return true; @@ -321,6 +326,11 @@ inline bool PrimaryVertexSorter>::needsProductsFo return false; } +template <> +inline bool PrimaryVertexSorter>::needsProductsForTiming() { + return false; +} + template <> inline std::pair PrimaryVertexSorter>::runAlgo(const reco::VertexCollection& vertices, @@ -343,4 +353,15 @@ inline std::pair PrimaryVertexSorter +inline std::pair PrimaryVertexSorter>::runAlgo( + const reco::VertexCollection& vertices, + const pat::PackedCandidate& pf, + const edm::ValueMap* trackTimeTag, + const edm::ValueMap* trackTimeResoTag, + const edm::View& jets, + const TransientTrackBuilder& builder) { + return assignmentAlgo_.chargedHadronVertex(vertices, pf, jets, builder); +} + #endif diff --git a/PhysicsTools/PatAlgos/python/slimming/primaryVertexAssociation_cfi.py b/CommonTools/RecoAlgos/python/primaryVertexAssociation_cfi.py similarity index 100% rename from PhysicsTools/PatAlgos/python/slimming/primaryVertexAssociation_cfi.py rename to CommonTools/RecoAlgos/python/primaryVertexAssociation_cfi.py diff --git a/CommonTools/RecoAlgos/python/sortedPFPrimaryVertices_cfi.py b/CommonTools/RecoAlgos/python/sortedPFPrimaryVertices_cfi.py index ef8876b177ebf..1e446422fb1e1 100644 --- a/CommonTools/RecoAlgos/python/sortedPFPrimaryVertices_cfi.py +++ b/CommonTools/RecoAlgos/python/sortedPFPrimaryVertices_cfi.py @@ -18,7 +18,15 @@ maxDxySigForNotReconstructedPrimary = cms.double(2), #in AND with next maxDxyForNotReconstructedPrimary = cms.double(0.01), #in AND with prev useTiming = cms.bool(False), - preferHighRanked = cms.bool(False) + useVertexFit = cms.bool(True), + preferHighRanked = cms.bool(False), + + #options used in PUPPI + NumOfPUVtxsForCharged = cms.int32(-1), + DzCutForChargedFromPUVtxs = cms.double(0.2), + PtMaxCharged = cms.double(-1), + EtaMinUseDz = cms.double(-1), + OnlyUseFirstDz = cms.bool(False), ), particles = cms.InputTag("particleFlow"), vertices= cms.InputTag("offlinePrimaryVertices"), @@ -31,4 +39,3 @@ produceNoPileUpCollection = cms.bool(True), ) - diff --git a/CommonTools/RecoAlgos/python/sortedPackedPrimaryVertices_cfi.py b/CommonTools/RecoAlgos/python/sortedPackedPrimaryVertices_cfi.py new file mode 100644 index 0000000000000..9a9b171db5bf4 --- /dev/null +++ b/CommonTools/RecoAlgos/python/sortedPackedPrimaryVertices_cfi.py @@ -0,0 +1,15 @@ +import FWCore.ParameterSet.Config as cms +from CommonTools.RecoAlgos.sortedPFPrimaryVertices_cfi import sortedPFPrimaryVertices +sortedPackedPrimaryVertices = cms.EDProducer("PackedCandidatePrimaryVertexSorter", + sorting = cms.PSet(), + assignment = sortedPFPrimaryVertices.assignment, + particles = cms.InputTag("packedPFCandidates"), + vertices= cms.InputTag("offlineSlimmedPrimaryVertices"), + jets= cms.InputTag("slimmedJets"), + qualityForPrimary = cms.int32(3), + usePVMET = cms.bool(True), + produceAssociationToOriginalVertices = cms.bool(True), + produceSortedVertices = cms.bool(True), + producePileUpCollection = cms.bool(True), + produceNoPileUpCollection = cms.bool(True), +) diff --git a/CommonTools/RecoAlgos/python/sortedPrimaryVertices_cfi.py b/CommonTools/RecoAlgos/python/sortedPrimaryVertices_cfi.py index e2d877bf93292..57be0713ca862 100644 --- a/CommonTools/RecoAlgos/python/sortedPrimaryVertices_cfi.py +++ b/CommonTools/RecoAlgos/python/sortedPrimaryVertices_cfi.py @@ -18,7 +18,15 @@ maxDxySigForNotReconstructedPrimary = cms.double(2), #in AND with next maxDxyForNotReconstructedPrimary = cms.double(0.01), #in AND with prev useTiming = cms.bool(False), + useVertexFit = cms.bool(True), preferHighRanked = cms.bool(False), + + #options used in PUPPI + NumOfPUVtxsForCharged = cms.int32(-1), + DzCutForChargedFromPUVtxs = cms.double(0.2), + PtMaxCharged = cms.double(-1), + EtaMinUseDz = cms.double(-1), + OnlyUseFirstDz = cms.bool(False), ), particles = cms.InputTag("trackRefsForJets"), trackTimeTag = cms.InputTag(""), diff --git a/CommonTools/RecoAlgos/src/PrimaryVertexAssignment.cc b/CommonTools/RecoAlgos/src/PrimaryVertexAssignment.cc index 83ca81b2679fe..230a336d4d4e3 100644 --- a/CommonTools/RecoAlgos/src/PrimaryVertexAssignment.cc +++ b/CommonTools/RecoAlgos/src/PrimaryVertexAssignment.cc @@ -28,6 +28,19 @@ std::pair PrimaryVertexAssignment::charge } index++; } + return chargedHadronVertex(vertices, iVertex, track, time, timeReso, jets, builder); +} + +std::pair PrimaryVertexAssignment::chargedHadronVertex( + const reco::VertexCollection& vertices, + int iVertex, + const reco::Track* track, + float time, + float timeReso, // <0 if timing not available for this object + const edm::View& jets, + const TransientTrackBuilder& builder) const { + typedef reco::VertexCollection::const_iterator IV; + typedef reco::Vertex::trackRef_iterator IT; bool useTime = useTiming_; if (edm::isNotFinite(time) || timeReso < 1e-6) { @@ -39,8 +52,8 @@ std::pair PrimaryVertexAssignment::charge if (preferHighRanked_) { for (IV iv = vertices.begin(); iv != vertices.end(); ++iv) { int ivtx = iv - vertices.begin(); - if (iVertex == ivtx) - return std::pair(ivtx, PrimaryVertexAssignment::UsedInFit); + if (useVertexFit_ && (iVertex == ivtx)) + return {ivtx, PrimaryVertexAssignment::UsedInFit}; double dz = std::abs(track->dz(iv->position())); double dt = std::abs(time - iv->t()); @@ -49,13 +62,21 @@ std::pair PrimaryVertexAssignment::charge if ((dz < maxDzForPrimaryAssignment_ or dz / track->dzError() < maxDzSigForPrimaryAssignment_) and (!useTimeVtx or dt / timeReso < maxDtSigForPrimaryAssignment_)) { - return std::pair(ivtx, PrimaryVertexAssignment::PrimaryDz); + return {ivtx, PrimaryVertexAssignment::PrimaryDz}; } } } - if (iVertex >= 0) - return std::pair(iVertex, PrimaryVertexAssignment::UsedInFit); + double firstVertexDz = std::numeric_limits::max(); + if (!vertices.empty()) + firstVertexDz = std::abs(track->dz(vertices.at(0).position())); + // recover cases where the primary vertex is split + if (useVertexFit_ && (iVertex > 0) && (iVertex <= fNumOfPUVtxsForCharged_) && + firstVertexDz < fDzCutForChargedFromPUVtxs_) + return {0, PrimaryVertexAssignment::PrimaryDz}; + + if (useVertexFit_ && (iVertex >= 0)) + return {iVertex, PrimaryVertexAssignment::UsedInFit}; double distmin = std::numeric_limits::max(); double dzmin = std::numeric_limits::max(); @@ -86,30 +107,45 @@ std::pair PrimaryVertexAssignment::charge } } - // first use "closest in Z" with tight cuts (targetting primary particles) - const float add_cov = vtxIdMinSignif >= 0 ? vertices[vtxIdMinSignif].covariance(2, 2) : 0.f; - const float dzE = sqrt(track->dzError() * track->dzError() + add_cov); - if (vtxIdMinSignif >= 0 and - (dzmin < maxDzForPrimaryAssignment_ and dzmin / dzE < maxDzSigForPrimaryAssignment_ and - track->dzError() < maxDzErrorForPrimaryAssignment_) and - (!useTime or dtmin / timeReso < maxDtSigForPrimaryAssignment_)) { - iVertex = vtxIdMinSignif; + // protect high pT particles from association to pileup vertices and assign them to the first vertex + if ((fPtMaxCharged_ > 0) && (vtxIdMinSignif >= 0) && (track->pt() > fPtMaxCharged_)) { + iVertex = 0; + } else { + // first use "closest in Z" with tight cuts (targetting primary particles) + const float add_cov = vtxIdMinSignif >= 0 ? vertices[vtxIdMinSignif].covariance(2, 2) : 0.f; + const float dzE = sqrt(track->dzError() * track->dzError() + add_cov); + if (!fOnlyUseFirstDz_) { + if (vtxIdMinSignif >= 0 and + (dzmin < maxDzForPrimaryAssignment_ and dzmin / dzE < maxDzSigForPrimaryAssignment_ and + track->dzError() < maxDzErrorForPrimaryAssignment_) and + (!useTime or dtmin / timeReso < maxDtSigForPrimaryAssignment_)) + iVertex = vtxIdMinSignif; + } else { + // consider only distances to first vertex for association of pileup vertices (originally used in PUPPI) + if ((vtxIdMinSignif >= 0) && (std::abs(track->eta()) > fEtaMinUseDz_)) + iVertex = + ((firstVertexDz < maxDzForPrimaryAssignment_ and firstVertexDz / dzE < maxDzSigForPrimaryAssignment_ and + track->dzError() < maxDzErrorForPrimaryAssignment_) and + (!useTime or std::abs(time - vertices.at(0).t()) / timeReso < maxDtSigForPrimaryAssignment_)) + ? 0 + : vtxIdMinSignif; + } } if (iVertex >= 0) - return std::pair(iVertex, PrimaryVertexAssignment::PrimaryDz); + return {iVertex, PrimaryVertexAssignment::PrimaryDz}; // if track not assigned yet, it could be a b-decay secondary , use jet axis dist criterion // first find the closest jet within maxJetDeltaR_ int jetIdx = -1; - double minDeltaR = maxJetDeltaR_; + double minDeltaR2 = maxJetDeltaR_ * maxJetDeltaR_; for (edm::View::const_iterator ij = jets.begin(); ij != jets.end(); ++ij) { if (ij->pt() < minJetPt_) continue; // skip jets below the jet Pt threshold - double deltaR = reco::deltaR(*ij, *track); - if (deltaR < minDeltaR and track->dzError() < maxDzErrorForPrimaryAssignment_) { - minDeltaR = deltaR; + double deltaR2 = reco::deltaR2(*ij, *track); + if (deltaR2 < minDeltaR2 and track->dzError() < maxDzErrorForPrimaryAssignment_) { + minDeltaR2 = deltaR2; jetIdx = std::distance(jets.begin(), ij); } } @@ -137,20 +173,19 @@ std::pair PrimaryVertexAssignment::charge } } if (iVertex >= 0) - return std::pair(iVertex, PrimaryVertexAssignment::BTrack); + return {iVertex, PrimaryVertexAssignment::BTrack}; // if the track is not compatible with other PVs but is compatible with the BeamSpot, we may simply have not reco'ed the PV! // we still point it to the closest in Z, but flag it as possible orphan-primary if (!vertices.empty() && std::abs(track->dxy(vertices[0].position())) < maxDxyForNotReconstructedPrimary_ && std::abs(track->dxy(vertices[0].position()) / track->dxyError()) < maxDxySigForNotReconstructedPrimary_) - return std::pair(vtxIdMinSignif, - PrimaryVertexAssignment::NotReconstructedPrimary); + return {vtxIdMinSignif, PrimaryVertexAssignment::NotReconstructedPrimary}; //FIXME: here we could better handle V0s and NucInt // all other tracks could be non-B secondaries and we just attach them with closest Z if (vtxIdMinSignif >= 0) - return std::pair(vtxIdMinSignif, PrimaryVertexAssignment::OtherDz); + return {vtxIdMinSignif, PrimaryVertexAssignment::OtherDz}; //If for some reason even the dz failed (when?) we consider the track not assigned - return std::pair(-1, PrimaryVertexAssignment::Unassigned); + return {-1, PrimaryVertexAssignment::Unassigned}; } diff --git a/PhysicsTools/PatAlgos/python/slimming/lostTracks_cfi.py b/PhysicsTools/PatAlgos/python/slimming/lostTracks_cfi.py index 93f75eb1cc3f8..2da39f09701e7 100644 --- a/PhysicsTools/PatAlgos/python/slimming/lostTracks_cfi.py +++ b/PhysicsTools/PatAlgos/python/slimming/lostTracks_cfi.py @@ -1,5 +1,5 @@ import FWCore.ParameterSet.Config as cms -from PhysicsTools.PatAlgos.slimming.primaryVertexAssociation_cfi import primaryVertexAssociation +from CommonTools.RecoAlgos.primaryVertexAssociation_cfi import primaryVertexAssociation from PhysicsTools.PatAlgos.slimming.packedPFCandidates_cfi import packedPFCandidates lostTracks = cms.EDProducer("PATLostTracks", diff --git a/PhysicsTools/PatAlgos/python/slimming/miniAOD_tools.py b/PhysicsTools/PatAlgos/python/slimming/miniAOD_tools.py index 7130afe2c1ad6..f4ee51a85d229 100644 --- a/PhysicsTools/PatAlgos/python/slimming/miniAOD_tools.py +++ b/PhysicsTools/PatAlgos/python/slimming/miniAOD_tools.py @@ -198,14 +198,12 @@ def _add_slimmedMETsNoHF(process): # ================== NoHF pfMET # ================== CHSMET - process.CHSCands = cms.EDFilter("CandPtrSelector", - src=cms.InputTag("packedPFCandidates"), - cut=cms.string("fromPV(0) > 0") - ) - task.add(process.CHSCands) + process.load("CommonTools.ParticleFlow.pfCHS_cff") + task.add(process.packedPrimaryVertexAssociationJME) + task.add(process.pfCHS) from RecoMET.METProducers.pfMet_cfi import pfMet - process.pfMetCHS = pfMet.clone(src = 'CHSCands') + process.pfMetCHS = pfMet.clone(src = 'pfCHS') task.add(process.pfMetCHS) addMETCollection(process, diff --git a/PhysicsTools/PatAlgos/python/slimming/puppiForMET_cff.py b/PhysicsTools/PatAlgos/python/slimming/puppiForMET_cff.py index 3d45ca91911fa..2d26c02350157 100644 --- a/PhysicsTools/PatAlgos/python/slimming/puppiForMET_cff.py +++ b/PhysicsTools/PatAlgos/python/slimming/puppiForMET_cff.py @@ -12,19 +12,26 @@ def makePuppies( process ): def makePuppiesFromMiniAOD( process, createScheduledSequence=False ): task = getPatAlgosToolsTask(process) + from CommonTools.ParticleFlow.pfCHS_cff import packedPrimaryVertexAssociationJME + setattr(process, "packedPrimaryVertexAssociationJME", packedPrimaryVertexAssociationJME.clone()) + task.add(process.packedPrimaryVertexAssociationJME) process.load('CommonTools.PileupAlgos.Puppi_cff') task.add(process.puppi) process.puppi.candName = 'packedPFCandidates' process.puppi.clonePackedCands = True process.puppi.vertexName = 'offlineSlimmedPrimaryVertices' process.puppi.useExistingWeights = True + process.puppi.vertexAssociation = 'packedPrimaryVertexAssociationJME:original' task.add(process.puppiNoLep) process.puppiNoLep.candName = 'packedPFCandidates' process.puppiNoLep.clonePackedCands = True process.puppiNoLep.vertexName = 'offlineSlimmedPrimaryVertices' process.puppiNoLep.useExistingWeights = True + process.puppiNoLep.vertexAssociation = 'packedPrimaryVertexAssociationJME:original' #making a sequence for people running the MET tool in scheduled mode if createScheduledSequence: - puppiMETSequence = cms.Sequence(process.puppi*process.puppiNoLep) + puppiMETTask = cms.Task(process.packedPrimaryVertexAssociationJME, process.puppi, process.puppiNoLep) + setattr(process, "puppiMETTask", puppiMETTask) + puppiMETSequence = cms.Sequence(puppiMETTask) setattr(process, "puppiMETSequence", puppiMETSequence) diff --git a/PhysicsTools/PatAlgos/python/slimming/slimming_cff.py b/PhysicsTools/PatAlgos/python/slimming/slimming_cff.py index b8963bd0e0f96..306efa71e690e 100644 --- a/PhysicsTools/PatAlgos/python/slimming/slimming_cff.py +++ b/PhysicsTools/PatAlgos/python/slimming/slimming_cff.py @@ -6,7 +6,7 @@ from PhysicsTools.PatAlgos.slimming.offlineSlimmedPrimaryVertices_cfi import * from PhysicsTools.PatAlgos.slimming.offlineSlimmedPrimaryVertices4D_cfi import * from PhysicsTools.PatAlgos.slimming.offlineSlimmedPrimaryVerticesWithBS_cfi import * -from PhysicsTools.PatAlgos.slimming.primaryVertexAssociation_cfi import * +from CommonTools.RecoAlgos.primaryVertexAssociation_cfi import * from PhysicsTools.PatAlgos.slimming.genParticles_cff import * from PhysicsTools.PatAlgos.slimming.genParticleAssociation_cff import * from PhysicsTools.PatAlgos.slimming.selectedPatTrigger_cfi import * diff --git a/PhysicsTools/PatAlgos/python/tools/jetCollectionTools.py b/PhysicsTools/PatAlgos/python/tools/jetCollectionTools.py index e327f3d46fb0d..01d00edfec39b 100644 --- a/PhysicsTools/PatAlgos/python/tools/jetCollectionTools.py +++ b/PhysicsTools/PatAlgos/python/tools/jetCollectionTools.py @@ -282,11 +282,10 @@ def addRecoJetCollection(self, # CHS # elif recoJetInfo.jetPUMethod == "chs": - self.addProcessAndTask(proc, pfCand, cms.EDFilter("CandPtrSelector", - src = cms.InputTag(self.pfLabel), - cut = cms.string("fromPV"), - ) - ) + from CommonTools.ParticleFlow.pfCHS_cff import pfCHS, packedPrimaryVertexAssociationJME + self.addProcessAndTask(proc, "packedPrimaryVertexAssociationJME", packedPrimaryVertexAssociationJME.clone()) + self.prerequisites.append("packedPrimaryVertexAssociationJME") + self.addProcessAndTask(proc, pfCand, pfCHS.clone()) self.prerequisites.append(pfCand) # # PUPPI diff --git a/PhysicsTools/PatAlgos/test/miniAOD/example_addJet.py b/PhysicsTools/PatAlgos/test/miniAOD/example_addJet.py index df1a5b96f7877..8e574b1ea1391 100644 --- a/PhysicsTools/PatAlgos/test/miniAOD/example_addJet.py +++ b/PhysicsTools/PatAlgos/test/miniAOD/example_addJet.py @@ -20,10 +20,10 @@ from RecoJets.JetProducers.ak4PFJets_cfi import ak4PFJets from RecoJets.JetProducers.ak4GenJets_cfi import ak4GenJets -process.chs = cms.EDFilter("CandPtrSelector", src = cms.InputTag("packedPFCandidates"), cut = cms.string("fromPV")) +process.load("CommonTools.ParticleFlow.pfCHS_cff") process.ak4PFJets = ak4PFJets.clone(src = 'packedPFCandidates', doAreaFastjet = True) # no idea while doArea is false by default, but it's True in RECO so we have to set it -process.ak4PFJetsCHS = ak4PFJets.clone(src = 'chs', doAreaFastjet = True) # no idea while doArea is false by default, but it's True in RECO so we have to set it +process.ak4PFJetsCHS = ak4PFJets.clone(src = 'pfCHS', doAreaFastjet = True) # no idea while doArea is false by default, but it's True in RECO so we have to set it process.ak4GenJets = ak4GenJets.clone(src = 'packedGenParticles') process.load("PhysicsTools.PatAlgos.producersLayer1.patCandidates_cff") diff --git a/PhysicsTools/PatAlgos/test/miniAOD/example_ei.py b/PhysicsTools/PatAlgos/test/miniAOD/example_ei.py index 6ca1deea96755..57b0f2d420e98 100644 --- a/PhysicsTools/PatAlgos/test/miniAOD/example_ei.py +++ b/PhysicsTools/PatAlgos/test/miniAOD/example_ei.py @@ -36,7 +36,7 @@ 0.5*pfIsolationVariables().sumPUPt))/pt < 0.15''')) #do projections -process.pfCHS = cms.EDFilter("CandPtrSelector", src = cms.InputTag("packedPFCandidates"), cut = cms.string("fromPV")) +process.load("CommonTools.ParticleFlow.pfCHS_cff") process.pfNoMuonCHS = cms.EDProducer("CandPtrProjector", src = cms.InputTag("pfCHS"), veto = cms.InputTag("selectedMuons")) process.pfNoElectronsCHS = cms.EDProducer("CandPtrProjector", src = cms.InputTag("pfNoMuonCHS"), veto = cms.InputTag("selectedElectrons")) diff --git a/PhysicsTools/PatAlgos/test/miniAOD/example_jet_and_met.py b/PhysicsTools/PatAlgos/test/miniAOD/example_jet_and_met.py index a91458a60a1fb..7aa247e8cf60b 100644 --- a/PhysicsTools/PatAlgos/test/miniAOD/example_jet_and_met.py +++ b/PhysicsTools/PatAlgos/test/miniAOD/example_jet_and_met.py @@ -19,10 +19,12 @@ from RecoJets.JetProducers.ak5GenJets_cfi import ak5GenJets from RecoMET.METProducers.pfMet_cfi import pfMet -process.chs = cms.EDFilter("CandPtrSelector", src = cms.InputTag("packedPFCandidates"), cut = cms.string("fromPV")) +process.load("CommonTools.ParticleFlow.pfCHS_cff") +task.add(process.packedPrimaryVertexAssociationJME) +task.add(process.pfCHS) process.ak5PFJets = ak5PFJets.clone(src = 'packedPFCandidates', doAreaFastjet = True) # no idea while doArea is false by default, but it's True in RECO so we have to set it -process.ak5PFJetsCHS = ak5PFJets.clone(src = 'chs', doAreaFastjet = True) # no idea while doArea is false by default, but it's True in RECO so we have to set it +process.ak5PFJetsCHS = ak5PFJets.clone(src = 'pfCHS', doAreaFastjet = True) # no idea while doArea is false by default, but it's True in RECO so we have to set it process.ak5GenJets = ak5GenJets.clone(src = 'packedGenParticles') process.pfMet = pfMet.clone(src = "packedPFCandidates") process.pfMet.calculateSignificance = False # this can't be easily implemented on packed PF candidates at the moment diff --git a/PhysicsTools/PatUtils/python/tools/runMETCorrectionsAndUncertainties.py b/PhysicsTools/PatUtils/python/tools/runMETCorrectionsAndUncertainties.py index 804dbff34d274..a37b20ba73048 100644 --- a/PhysicsTools/PatUtils/python/tools/runMETCorrectionsAndUncertainties.py +++ b/PhysicsTools/PatUtils/python/tools/runMETCorrectionsAndUncertainties.py @@ -914,20 +914,8 @@ def getMETUncertainties(self, process, metType, metModName, electronCollection, #--------------------------------------------------------------------- # PFPhotons : #------------ - if self._parameters["Puppi"].value or not self._parameters["onMiniAOD"].value: - cutforpfNoPileUp = cms.string("") - else: - cutforpfNoPileUp = cms.string("fromPV > 1") - - pfNoPileUp = cms.EDFilter("CandPtrSelector", - src = pfCandCollection, - cut = cutforpfNoPileUp - ) - addToProcessAndTask("pfNoPileUp"+postfix, pfNoPileUp, process, task) - metUncSequence += getattr(process, "pfNoPileUp"+postfix) - pfPhotons = cms.EDFilter("CandPtrSelector", - src = cms.InputTag("pfNoPileUp"+postfix), + src = pfCandCollection if self._parameters["Puppi"].value or not self._parameters["onMiniAOD"].value else cms.InputTag("pfCHS"), cut = cms.string("abs(pdgId) = 22") ) addToProcessAndTask("pfPhotons"+postfix, pfPhotons, process, task) @@ -1605,13 +1593,8 @@ def ak4JetReclustering(self,process, pfCandCollection, patMetModuleSequence, pos if chs: CHSname="chs" jetColName="ak4PFJetsCHS" - - pfCHS=None - if self._parameters["onMiniAOD"].value: - pfCHS = cms.EDFilter("CandPtrSelector", src = pfCandCollection, cut = cms.string("fromPV")) - pfCandColl = cms.InputTag("pfNoPileUpJME"+postfix) - addToProcessAndTask("pfNoPileUpJME"+postfix, pfCHS, process, task) - patMetModuleSequence += getattr(process, "pfNoPileUpJME"+postfix) + if self._parameters["onMiniAOD"].value: + pfCandColl = cms.InputTag("pfCHS") else: addToProcessAndTask("tmpPFCandCollPtr"+postfix, cms.EDProducer("PFCandidateFwdPtrProducer", @@ -1620,8 +1603,10 @@ def ak4JetReclustering(self,process, pfCandCollection, patMetModuleSequence, pos process.load("CommonTools.ParticleFlow.pfNoPileUpJME_cff") task.add(process.pfNoPileUpJMETask) configtools.cloneProcessingSnippet(process, getattr(process,"pfNoPileUpJMESequence"), postfix, addToTask = True ) + getattr(process, "primaryVertexAssociationJME"+postfix).particles = pfCandCollection getattr(process, "pfPileUpJME"+postfix).PFCandidates = "tmpPFCandCollPtr"+postfix getattr(process, "pfNoPileUpJME"+postfix).bottomCollection = "tmpPFCandCollPtr"+postfix + getattr(process, "pfPileUpJME"+postfix).vertexAssociation = 'primaryVertexAssociationJME'+postfix+':original' pfCandColl = "pfNoPileUpJME"+postfix patMetModuleSequence += getattr(process, "tmpPFCandCollPtr"+postfix) patMetModuleSequence += getattr(process, "pfNoPileUpJME"+postfix) @@ -1711,10 +1696,12 @@ def miniAODConfigurationPre(self, process, patMetModuleSequence, pfCandCollectio ##adding the necessary chs and track met configuration task = getPatAlgosToolsTask(process) - pfCHS = cms.EDFilter("CandPtrSelector", src = cms.InputTag("packedPFCandidates"), cut = cms.string("fromPV(0)>0")) - addToProcessAndTask("pfCHS", pfCHS, process, task) + from CommonTools.ParticleFlow.pfCHS_cff import pfCHS, packedPrimaryVertexAssociationJME + addToProcessAndTask("packedPrimaryVertexAssociationJME",packedPrimaryVertexAssociationJME.clone(), process, task) + patMetModuleSequence += getattr(process, "packedPrimaryVertexAssociationJME") + addToProcessAndTask("pfCHS", pfCHS.clone(), process, task) from RecoMET.METProducers.pfMet_cfi import pfMet - pfMetCHS = pfMet.clone(src = 'pfCHS') + pfMetCHS = pfMet.clone(src = "pfCHS") addToProcessAndTask("pfMetCHS", pfMetCHS, process, task) addMETCollection(process, diff --git a/RecoBTag/ONNXRuntime/python/pfDeepBoostedJet_cff.py b/RecoBTag/ONNXRuntime/python/pfDeepBoostedJet_cff.py index 8233fbd8c9288..cd07ad7088339 100644 --- a/RecoBTag/ONNXRuntime/python/pfDeepBoostedJet_cff.py +++ b/RecoBTag/ONNXRuntime/python/pfDeepBoostedJet_cff.py @@ -20,7 +20,7 @@ ) from CommonTools.PileupAlgos.Puppi_cff import puppi -from PhysicsTools.PatAlgos.slimming.primaryVertexAssociation_cfi import primaryVertexAssociation +from CommonTools.RecoAlgos.primaryVertexAssociation_cfi import primaryVertexAssociation # This task is not used, useful only if we run DeepFlavour from RECO # jets (RECO/AOD) diff --git a/RecoBTag/ONNXRuntime/python/pfDeepFlavour_cff.py b/RecoBTag/ONNXRuntime/python/pfDeepFlavour_cff.py index e4c446a178028..6786543ecfa9c 100644 --- a/RecoBTag/ONNXRuntime/python/pfDeepFlavour_cff.py +++ b/RecoBTag/ONNXRuntime/python/pfDeepFlavour_cff.py @@ -9,7 +9,7 @@ from RecoBTag.ONNXRuntime.pfDeepCombinedJetTags_cfi import pfDeepCombinedJetTags from RecoBTag.ONNXRuntime.pfNegativeDeepFlavourJetTags_cfi import pfNegativeDeepFlavourJetTags from CommonTools.PileupAlgos.Puppi_cff import puppi -from PhysicsTools.PatAlgos.slimming.primaryVertexAssociation_cfi import primaryVertexAssociation +from CommonTools.RecoAlgos.primaryVertexAssociation_cfi import primaryVertexAssociation # This task is not used, useful only if we run DeepFlavour from RECO # jets (RECO/AOD) diff --git a/RecoBTag/ONNXRuntime/python/pfParticleNetAK4_cff.py b/RecoBTag/ONNXRuntime/python/pfParticleNetAK4_cff.py index 8392793825a27..03c789b10f5eb 100644 --- a/RecoBTag/ONNXRuntime/python/pfParticleNetAK4_cff.py +++ b/RecoBTag/ONNXRuntime/python/pfParticleNetAK4_cff.py @@ -19,7 +19,7 @@ ) from CommonTools.PileupAlgos.Puppi_cff import puppi -from PhysicsTools.PatAlgos.slimming.primaryVertexAssociation_cfi import primaryVertexAssociation +from CommonTools.RecoAlgos.primaryVertexAssociation_cfi import primaryVertexAssociation # This task is not used, useful only if we run it from RECO jets (RECO/AOD) pfParticleNetAK4Task = cms.Task(puppi, primaryVertexAssociation, pfParticleNetAK4TagInfos, diff --git a/RecoBTag/ONNXRuntime/python/pfParticleNet_cff.py b/RecoBTag/ONNXRuntime/python/pfParticleNet_cff.py index d60b42b44c057..cad96af9c5a7c 100644 --- a/RecoBTag/ONNXRuntime/python/pfParticleNet_cff.py +++ b/RecoBTag/ONNXRuntime/python/pfParticleNet_cff.py @@ -34,7 +34,7 @@ ) from CommonTools.PileupAlgos.Puppi_cff import puppi -from PhysicsTools.PatAlgos.slimming.primaryVertexAssociation_cfi import primaryVertexAssociation +from CommonTools.RecoAlgos.primaryVertexAssociation_cfi import primaryVertexAssociation # This task is not used, useful only if we run it from RECO jets (RECO/AOD) pfParticleNetTask = cms.Task(puppi, primaryVertexAssociation, pfParticleNetTagInfos, diff --git a/RecoJets/JetProducers/python/hepTopTaggerV2_cff.py b/RecoJets/JetProducers/python/hepTopTaggerV2_cff.py index cbdaeec689b27..7f62bf9ddc676 100644 --- a/RecoJets/JetProducers/python/hepTopTaggerV2_cff.py +++ b/RecoJets/JetProducers/python/hepTopTaggerV2_cff.py @@ -5,7 +5,8 @@ from RecoJets.JetProducers.PFJetParameters_cfi import * # CHS -chsForHTT = cms.EDFilter("CandPtrSelector", src = cms.InputTag("packedPFCandidates"), cut = cms.string("fromPV")) +from CommonTools.ParticleFlow.pfCHS_cff import pfCHS +chsForHTT = pfCHS.clone() # Schedule HEPTopTagger hepTopTaggerV2 = cms.EDProducer( diff --git a/RecoMET/Configuration/python/RecoPFMET_cff.py b/RecoMET/Configuration/python/RecoPFMET_cff.py index 89b4afad19d63..22d0e7d178747 100644 --- a/RecoMET/Configuration/python/RecoPFMET_cff.py +++ b/RecoMET/Configuration/python/RecoPFMET_cff.py @@ -3,11 +3,12 @@ ##____________________________________________________________________________|| from RecoMET.METProducers.pfMet_cfi import * from RecoMET.METProducers.pfChMet_cfi import * +from CommonTools.ParticleFlow.pfNoPileUpJME_cff import goodOfflinePrimaryVertices, primaryVertexAssociationJME from CommonTools.PileupAlgos.Puppi_cff import puppiNoLep from RecoMET.METProducers.pfMetPuppi_cfi import * ##____________________________________________________________________________|| -recoPFMETTask = cms.Task(pfMet , particleFlowForChargedMET , pfChMet, puppiNoLep, pfMetPuppi) +recoPFMETTask = cms.Task(pfMet , particleFlowForChargedMET , goodOfflinePrimaryVertices, primaryVertexAssociationJME, pfChMet, puppiNoLep, pfMetPuppi) recoPFMET = cms.Sequence(recoPFMETTask) ##____________________________________________________________________________||