Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PPS][NanoAOD] Generator-level proton information #36080

Merged
merged 22 commits into from
Feb 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
1b1b4dc
Added GEN-level proton table producer
forthommel Oct 5, 2021
9d1f397
Added the fillDescriptions member to our new EDProducer
forthommel Oct 5, 2021
c5d40ad
Added the genProtonTable collection to proton nanoAOD routine
forthommel Oct 5, 2021
76cc8bc
Added gen-level proton table producer for full sim
forthommel Oct 5, 2021
212ccbf
Set collection produced by proton flat table producer, renamed object…
forthommel Oct 5, 2021
dd9a44d
Added default values for input collection tags
forthommel Oct 28, 2021
c15df84
Cleanup of proton tables task
forthommel Nov 9, 2021
13ce68d
Adapting to column addition method signature in 12_2_X
forthommel Nov 9, 2021
ca50b42
Storing isPU attribute as boolean column
forthommel Nov 10, 2021
9590c54
Reverting genPUProtons input tag to its "factory setting"
forthommel Nov 10, 2021
f10e569
Added docstring to GEN proton table
forthommel Nov 10, 2021
c9f09eb
Disabling genProtons table building for 80X UL samples
forthommel Nov 11, 2021
ba920e1
Storing protons px and py instead of pt
forthommel Nov 17, 2021
1b321e9
Updated ConfigurationDescription
forthommel Nov 17, 2021
9b6310c
Modified PU protons source for 94X-produced MiniAOD samples
forthommel Nov 22, 2021
689b6ac
94XMiniAODv1 does not seem to have the extra collection name in its I…
forthommel Nov 24, 2021
40ba4b9
Disabling gen protons table for CMSSW_9_4_X samples
forthommel Nov 27, 2021
2462742
Using same modifier as standard proton nanoAOD part
forthommel Nov 29, 2021
1c06bbe
Added an alternative source for PU protons with premixing
forthommel Jan 10, 2022
31ea174
Try to fetch alternative token if main one is not found
forthommel Jan 10, 2022
be038f3
Disable the check of PU collection presence at every event
forthommel Jan 10, 2022
1f74f4b
Floating point precision set for kinematics variables
forthommel Jan 18, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions PhysicsTools/NanoAOD/plugins/GenProtonTableProducer.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/****************************************************************************
*
* This is a part of PPS offline software.
* Authors:
* Laurent Forthomme
* Michael Pitt
*
****************************************************************************/

#include <memory>

#include "FWCore/Framework/interface/Frameworkfwd.h"
#include "FWCore/Framework/interface/stream/EDProducer.h"
#include "FWCore/Framework/interface/Event.h"
#include "FWCore/Framework/interface/MakerMacros.h"
#include "FWCore/ParameterSet/interface/ParameterSet.h"
#include "FWCore/Utilities/interface/StreamID.h"

#include "CommonTools/Utils/interface/StringCutObjectSelector.h"

#include "DataFormats/HepMCCandidate/interface/GenParticle.h"
#include "DataFormats/HepMCCandidate/interface/GenParticleFwd.h"

#include "DataFormats/NanoAOD/interface/FlatTable.h"

class GenProtonTableProducer : public edm::stream::EDProducer<> {
public:
explicit GenProtonTableProducer(const edm::ParameterSet&);
~GenProtonTableProducer() override = default;

static void fillDescriptions(edm::ConfigurationDescriptions&);

private:
void produce(edm::Event&, const edm::EventSetup&) override;

const edm::EDGetTokenT<reco::GenParticleCollection> prunedCandsToken_;
const edm::EDGetTokenT<reco::GenParticleCollection> puCandsToken_, puAltCandsToken_;
const StringCutObjectSelector<reco::Candidate> protonsCut_;
const std::string table_name_;
const double tolerance_;
bool use_alt_coll_{false}; ///< Are we using premix/mix collection name for PU protons?
};

GenProtonTableProducer::GenProtonTableProducer(const edm::ParameterSet& iConfig)
: prunedCandsToken_(consumes<reco::GenParticleCollection>(iConfig.getParameter<edm::InputTag>("srcPruned"))),
puCandsToken_(mayConsume<reco::GenParticleCollection>(iConfig.getParameter<edm::InputTag>("srcPUProtons"))),
puAltCandsToken_(mayConsume<reco::GenParticleCollection>(iConfig.getParameter<edm::InputTag>("srcAltPUProtons"))),
protonsCut_(iConfig.getParameter<std::string>("cut")),
table_name_(iConfig.getParameter<std::string>("name")),
tolerance_(iConfig.getParameter<double>("tolerance")) {
produces<nanoaod::FlatTable>();
}

void GenProtonTableProducer::produce(edm::Event& iEvent, const edm::EventSetup&) {
// define the variables
std::vector<float> pxs, pys, pzs, vzs;
std::vector<bool> isPUs;
// first loop over signal protons
for (const auto& pruned_cand : iEvent.get(prunedCandsToken_)) {
if (!protonsCut_(pruned_cand))
continue;
pxs.emplace_back(pruned_cand.px());
pys.emplace_back(pruned_cand.py());
pzs.emplace_back(pruned_cand.pz());
vzs.emplace_back(pruned_cand.vz());
isPUs.emplace_back(false);
}
// then loop over pruned candidates ; if already in signal protons, discard
edm::Handle<reco::GenParticleCollection> hPUCands;
if (use_alt_coll_ || !iEvent.getByToken(puCandsToken_, hPUCands))
use_alt_coll_ = iEvent.getByToken(puAltCandsToken_, hPUCands);
for (const auto& pu_cand : *hPUCands) {
if (!protonsCut_(pu_cand))
continue;
bool associated{false};
for (size_t i = 0; i < pzs.size(); ++i) {
if (fabs(1. - pxs.at(i) / pu_cand.px()) < tolerance_ && fabs(1. - pys.at(i) / pu_cand.py()) < tolerance_ &&
fabs(1. - pzs.at(i) / pu_cand.pz()) < tolerance_) {
associated = true;
break;
}
}
if (associated)
continue;
pxs.emplace_back(pu_cand.px());
pys.emplace_back(pu_cand.py());
pzs.emplace_back(pu_cand.pz());
vzs.emplace_back(pu_cand.vz());
isPUs.emplace_back(true);
}

auto protons_table = std::make_unique<nanoaod::FlatTable>(isPUs.size(), table_name_, false);
protons_table->addColumn<float>("px", pxs, "proton horizontal momentum", 8);
protons_table->addColumn<float>("py", pys, "proton vertical momentum", 8);
protons_table->addColumn<float>("pz", pzs, "proton longitudinal momentum", 8);
protons_table->addColumn<float>("vz", vzs, "proton vertex longitudinal coordinate", 8);
protons_table->addColumn<bool>("isPU", isPUs, "pileup proton?");
iEvent.put(std::move(protons_table));
}

void GenProtonTableProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
edm::ParameterSetDescription desc;
desc.add<edm::InputTag>("srcPruned", edm::InputTag("prunedGenParticles"))
->setComment("input source for pruned gen-level particle candidates");
desc.add<edm::InputTag>("srcPUProtons", edm::InputTag("genPUProtons"))
->setComment("input source for pileup protons collection");
desc.add<edm::InputTag>("srcAltPUProtons", edm::InputTag("genPUProtons", "genPUProtons"))
->setComment("alternative input source for pileup protons collection (for premix-mix backward compatibility)");
desc.add<std::string>("cut", "")->setComment("proton kinematic selection");
desc.add<std::string>("name", "GenProton")->setComment("flat table name");
desc.add<std::string>("doc", "generator level information on (signal+PU) protons")
->setComment("flat table description");
desc.add<double>("tolerance", 1.e-3)->setComment("relative difference between the signal and pileup protons momenta");
descriptions.add("genProtonTable", desc);
}

DEFINE_FWK_MODULE(GenProtonTableProducer);
12 changes: 6 additions & 6 deletions PhysicsTools/NanoAOD/python/nano_cff.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
nanoTableTaskFS = cms.Task(genParticleTask, particleLevelTask, jetMCTask, muonMCTask, electronMCTask, lowPtElectronMCTask, photonMCTask,
tauMCTask, boostedTauMCTask,
metMCTable, ttbarCatMCProducersTask, globalTablesMCTask, cms.Task(btagWeightTable), ttbarCategoryTableTask,
genWeightsTableTask, genVertexTablesTask, genParticleTablesTask, particleLevelTablesTask)
genWeightsTableTask, genVertexTablesTask, genParticleTablesTask, genProtonTablesTask, particleLevelTablesTask)

nanoSequenceFS = cms.Sequence(nanoSequenceCommon + cms.Sequence(nanoTableTaskFS))

Expand All @@ -105,7 +105,7 @@ def nanoAOD_addTauIds(process):

def nanoAOD_addBoostedTauIds(process):
updatedBoostedTauName = "slimmedTausBoostedNewID"
boostedTauIdEmbedder = tauIdConfig.TauIDEmbedder(process, debug=False,
boostedTauIdEmbedder = tauIdConfig.TauIDEmbedder(process, debug=False,
originalTauName = "slimmedTausBoosted",
updatedTauName = updatedBoostedTauName,
postfix="Boosted",
Expand All @@ -118,7 +118,7 @@ def nanoAOD_addBoostedTauIds(process):
process.boostedTauTask = _boostedTauTask.copy()

return process


from PhysicsTools.PatAlgos.tools.jetTools import updateJetCollection
def nanoAOD_addDeepInfo(process,addDeepBTag,addDeepFlavour):
Expand Down Expand Up @@ -202,7 +202,7 @@ def nanoAOD_recalibrateMETs(process,isData):
process.patJetsPuppi.addGenJetMatch = cms.bool(False)

print("nanoAOD_PuppiV15_switch.reclusterJets is true")

runMetCorAndUncFromMiniAOD(process,isData=isData,metType="Puppi",postfix="Puppi",jetFlavor="AK4PFPuppi", recoMetFromPFCs=bool(nanoAOD_PuppiV15_switch.recoMetFromPFCs), reclusterJets=bool(nanoAOD_PuppiV15_switch.reclusterJets))
process.nanoSequenceCommon.insert(2,cms.Sequence(process.puppiMETSequence+process.fullPatMetSequencePuppi))

Expand Down Expand Up @@ -393,10 +393,10 @@ def nanoAOD_customizeMC(process):
modifier.toModify(process, lambda p: nanoAOD_runMETfixEE2017(p,isData=False))
return process

###increasing the precision of selected GenParticles.
###increasing the precision of selected GenParticles.
def nanoWmassGenCustomize(process):
pdgSelection="?(abs(pdgId) == 11|| abs(pdgId)==13 || abs(pdgId)==15 ||abs(pdgId)== 12 || abs(pdgId)== 14 || abs(pdgId)== 16|| abs(pdgId)== 24|| pdgId== 23)"
# Keep precision same as default RECO for selected particles
# Keep precision same as default RECO for selected particles
ptPrecision="{}?{}:{}".format(pdgSelection, CandVars.pt.precision.value(),genParticleTable.variables.pt.precision.value())
process.genParticleTable.variables.pt.precision=cms.string(ptPrecision)
phiPrecision="{} ? {} : {}".format(pdgSelection, CandVars.phi.precision.value(), genParticleTable.variables.phi.precision.value())
Expand Down
12 changes: 11 additions & 1 deletion PhysicsTools/NanoAOD/python/protons_cff.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import FWCore.ParameterSet.Config as cms
from PhysicsTools.NanoAOD.common_cff import *
from PhysicsTools.NanoAOD.genProtonTable_cfi import genProtonTable as _genproton
from PhysicsTools.NanoAOD.nano_eras_cff import *
from RecoPPS.ProtonReconstruction.ppsFilteredProtonProducer_cfi import *

Expand Down Expand Up @@ -53,12 +54,21 @@
thetaY = Var("thetaY",float,doc="th y",precision=10),
),
externalVariables = cms.PSet(
decRPId = ExtVar("protonTable:protonRPId",int,doc="Detector ID",precision=8),
decRPId = ExtVar("protonTable:protonRPId",int,doc="Detector ID",precision=8),
),
)

protonTablesTask = cms.Task(filteredProtons,protonTable,multiRPTable)
if singleRPProtons: protonTablesTask.add(singleRPTable)

# GEN-level signal/PU protons collection
genProtonTable = _genproton.clone(
cut = cms.string('(pdgId == 2212) && (abs(pz) > 5200) && (abs(pz) < 6467.5)') # xi in [0.015, 0.2]
)

genProtonTablesTask = cms.Task(genProtonTable)

for modifier in run2_miniAOD_80XLegacy, run2_nanoAOD_94XMiniAODv1, run2_nanoAOD_94XMiniAODv2, run2_nanoAOD_94X2016, run2_nanoAOD_102Xv1:
modifier.toReplaceWith(protonTablesTask, cms.Task())
# input GEN-level PU protons collection only introduced for UL and 12_X_Y
modifier.toReplaceWith(genProtonTablesTask, cms.Task())