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

[12_6_X] TriggerObjectTableProducer configuration and bug fixes #40173

Merged
merged 14 commits into from
Nov 30, 2022
71 changes: 57 additions & 14 deletions PhysicsTools/NanoAOD/plugins/TriggerObjectTableProducer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,38 @@ class TriggerObjectTableProducer : public edm::stream::EDProducer<> {
l1DR2_2(-1),
l2DR2(-1),
skipObjectsNotPassingQualityBits(pset.getParameter<bool>("skipObjectsNotPassingQualityBits")),
qualityBits(pset.getParameter<std::string>("qualityBits")),
qualityBitsDoc(pset.getParameter<std::string>("qualityBitsDoc")) {
qualityBits("0"), //will be overwritten from configuration
qualityBitsDoc("") //will be created from configuration
{
if (pset.existsAs<std::string>("qualityBits")) {
qualityBits = StringObjectFunction<pat::TriggerObjectStandAlone>(pset.getParameter<std::string>("qualityBits"));
qualityBitsDoc = pset.getParameter<std::string>("qualityBitsDoc");
} else {
std::vector<edm::ParameterSet> qualityBitsConfig =
pset.getParameter<std::vector<edm::ParameterSet>>("qualityBits");
std::stringstream qualityBitsFunc;
std::vector<bool> bits(qualityBitsConfig.size(), false);
for (size_t i = 0; i != qualityBitsConfig.size(); ++i) {
if (i != 0) {
qualityBitsFunc << " + ";
qualityBitsDoc += ", ";
}
unsigned int bit = i;
if (qualityBitsConfig[i].existsAs<unsigned int>("bit"))
bit = qualityBitsConfig[i].getParameter<unsigned int>("bit");
assert(!bits[bit] && "a quality bit was inserted twice"); // the bit should not have been set already
assert(bit < 31 && "quality bits are store on 32 bit");
bits[bit] = true;
qualityBitsFunc << std::to_string(int(pow(2, bit))) << "*("
<< qualityBitsConfig[i].getParameter<std::string>("selection") << ")";
qualityBitsDoc += std::to_string(bit) + " => " + qualityBitsConfig[i].getParameter<std::string>("doc");
}
if (!qualityBitsFunc.str().empty()) {
//std::cout << "The quality bit string is :" << qualityBitsFunc.str() << std::endl;
//std::cout << "The quality bit documentation is :" << qualityBitsDoc << std::endl;
qualityBits = StringObjectFunction<pat::TriggerObjectStandAlone>(qualityBitsFunc.str());
}
}
if (pset.existsAs<std::string>("l1seed")) {
l1cut = StringCutObjectSelector<pat::TriggerObjectStandAlone>(pset.getParameter<std::string>("l1seed"));
l1DR2 = std::pow(pset.getParameter<double>("l1deltaR"), 2);
Expand All @@ -118,29 +148,28 @@ void TriggerObjectTableProducer::produce(edm::Event &iEvent, const edm::EventSet
const auto &trigObjs = iEvent.get(src_);

std::vector<std::pair<const pat::TriggerObjectStandAlone *, const SelectedObject *>> selected;
std::map<int, std::map<const pat::TriggerObjectStandAlone *, int>> selected_bits;
for (const auto &obj : trigObjs) {
for (const auto &sel : sels_) {
if (sel.match(obj) && (sel.skipObjectsNotPassingQualityBits ? (int(sel.qualityBits(obj)) > 0) : true)) {
selected.emplace_back(&obj, &sel);
// cave canem: the object will be taken by whichever selection it matches first, so it
// depends on the order of the selections in the VPSet
break;
if (sel.match(obj)) {
selected_bits[sel.id][&obj] = int(sel.qualityBits(obj));
if (sel.skipObjectsNotPassingQualityBits ? (selected_bits[sel.id][&obj] > 0) : true) {
selected.emplace_back(&obj, &sel);
}
}
}
}

// Self-cleaning
std::map<const pat::TriggerObjectStandAlone *, int> selected_bits;
for (unsigned int i = 0; i < selected.size(); ++i) {
const auto &obj = *selected[i].first;
const auto &sel = *selected[i].second;
selected_bits[&obj] = int(sel.qualityBits(obj));

for (unsigned int j = 0; j < i; ++j) {
const auto &obj2 = *selected[j].first;
const auto &sel2 = *selected[j].second;
if (sel.id == sel2.id && abs(obj.pt() - obj2.pt()) < 1e-6 && deltaR2(obj, obj2) < 1e-6) {
selected_bits[&obj2] |= selected_bits[&obj]; //Keep filters from all the objects
selected_bits[sel.id][&obj2] |= selected_bits[sel.id][&obj]; //Keep filters from all the objects
selected.erase(selected.begin() + i);
i--;
}
Expand Down Expand Up @@ -247,7 +276,7 @@ void TriggerObjectTableProducer::produce(edm::Event &iEvent, const edm::EventSet
eta[i] = obj.eta();
phi[i] = obj.phi();
id[i] = sel.id;
bits[i] = selected_bits[&obj];
bits[i] = selected_bits[sel.id][&obj];
if (sel.l1DR2 > 0) {
float best = sel.l1DR2;
for (const auto &l1obj : l1Objects) {
Expand Down Expand Up @@ -314,9 +343,23 @@ void TriggerObjectTableProducer::fillDescriptions(edm::ConfigurationDescriptions
selection.add<int>("id")->setComment("identifier of the trigger collection in the flat table");
selection.add<std::string>("sel")->setComment("function to selection on pat::TriggerObjectStandAlone");
selection.add<bool>("skipObjectsNotPassingQualityBits")->setComment("flag to skip object on quality bit");
selection.add<std::string>("qualityBits")
->setComment("function on pat::TriggerObjectStandAlone to define quality bit");
selection.add<std::string>("qualityBitsDoc")->setComment("description of qualityBits");

edm::ParameterDescription<std::string> oldSelection(
"qualityBits", "0", true, edm::Comment("function on pat::TriggerObjectStandAlone to define quality bits"));
edm::ParameterDescription<std::string> oldDoc(
"qualityBitsDoc", "", true, edm::Comment("documentation of the quality bits"));
edm::ParameterSetDescription bit;
bit.add<std::string>("selection")->setComment("function on pat::TriggerObjectStandAlone to define quality bit");
bit.add<std::string>("doc")->setComment("definition of the quality bit");
bit.addOptional<uint>("bit")->setComment("value of the bit, if not the order in the VPset");
bit.setComment("parameter set to define quality bit of matching object");

//selection.addVPSet("qualityBits", bit); // non-backqard compatible
edm::ParameterDescription<std::vector<edm::ParameterSet>> bits(
"qualityBits", bit, true, std::vector<edm::ParameterSet>());
//allow for backward compatible configuration with qualityBits and qualityBitsDoc as strings
selection.addNode(bits xor (oldSelection and oldDoc));

selection.ifExists(edm::ParameterDescription<std::string>("l1seed", "selection on pat::TriggerObjectStandAlone"),
edm::ParameterDescription<double>(
"l1deltaR", "deltaR criteria to match pat::TriggerObjectStandAlone to L1 primitive"));
Expand Down
2 changes: 1 addition & 1 deletion PhysicsTools/NanoAOD/python/nanoDQM_cfi.py
Original file line number Diff line number Diff line change
Expand Up @@ -840,7 +840,7 @@
plots = cms.VPSet(
Count1D('_size', 28, -0.5, 27.5),
Plot1D('eta', 'eta', 20, -5, 5, 'eta'),
Plot1D('filterBits', 'filterBits', 1024, -0.5, 1023.5, 'extra bits of associated information: 1 = CaloIdL_TrackIdL_IsoVL, 2 = WPLoose, 4 = WPTight, 8 = OverlapFilter PFTau for Electron (PixelMatched e/gamma); 1 = TrkIsoVVL, 2 = Iso, 4 = OverlapFilter PFTau for Muon; 1 = LooseChargedIso, 2 = MediumChargedIso, 4 = TightChargedIso, 8 = TightID OOSC photons, 16 = L2p5 pixel iso, 32 = OverlapFilter IsoMu, 64 = OverlapFilter IsoEle, 128 = L1-HLT matched, 256 = Dz for Tau; 1 = VBF cross-cleaned from loose iso PFTau for Jet'),
Plot1D('filterBits', 'filterBits', 1024, -0.5, 16000, 'extra bits of associated information: see branch documentation'),
Plot1D('id', 'id', 20, 0, 30, 'ID of the object: 11 = Electron (PixelMatched e/gamma), 22 = Photon (PixelMatch-vetoed e/gamma), 13 = Muon, 14 = Tau, 1 = Jet, 2 = MET, 3 = HT, 4 = MHT'),
Plot1D('l1charge', 'l1charge', 3, -1.5, 1.5, 'charge of associated L1 seed'),
Plot1D('l1iso', 'l1iso', 4, -0.5, 3.5, 'iso of associated L1 seed'),
Expand Down
Loading