Skip to content

Commit a83f743

Browse files
authored
Merge pull request #43957 from lathomas/L1Nano_master
Customized L1T NanoAOD
2 parents 35bbede + 8c7820d commit a83f743

File tree

10 files changed

+512
-18
lines changed

10 files changed

+512
-18
lines changed

Configuration/PyReleaseValidation/python/relval_nano.py

+6-4
Original file line numberDiff line numberDiff line change
@@ -157,17 +157,14 @@ def subnext(self):
157157
steps['NANO_data13.0']])
158158
steps['NANO_data13.0_prompt']['-s']=steps['NANO_data13.0_prompt']['-s'].replace('NANO','NANO:@PHYS+@L1')
159159

160-
161160
steps['muDPGNANO_data13.0']=merge([{'-s' : 'RAW2DIGI,NANO:@MUDPG',
162161
'-n' : '100',},
163162
steps['NANO_data13.0']])
164163

165-
166164
steps['muDPGNANOBkg_data13.0']=merge([{'-s' : 'RAW2DIGI,NANO:@MUDPGBKG',
167165
'-n' : '100',},
168166
steps['NANO_data13.0']])
169167

170-
171168
steps['hcalDPGNANO_data13.0']=merge([{'-s' : 'RAW2DIGI,RECO,NANO:@HCAL',
172169
'-n' : '100',
173170
'--processName': 'NANO',},
@@ -179,8 +176,12 @@ def subnext(self):
179176
steps['NANO_data13.0']])
180177

181178
steps['muPOGNANO_data13.0']=merge([{'-s' : 'NANO:@MUPOG,DQM:@nanoAODDQM', '-n' : '1000'},
182-
steps['NANO_data13.0']])
179+
steps['NANO_data13.0']])
183180

181+
steps['l1DPGNANO_data13.0']=merge([{'-s' : 'RAW2DIGI,NANO:@L1DPG',
182+
'-n' : '100'},
183+
steps['NANO_data13.0']])
184+
184185
steps['EGMNano_data13.0'] = merge([{'-s':'NANO:@EGM,DQM:@nanoAODDQM', '-n' : '1000'},
185186
steps['NANO_data13.0']])
186187

@@ -278,6 +279,7 @@ def subnext(self):
278279
workflows[_wfn()] = ['NANOdata130Xrun3', ['MuonEG2023MINIAOD13.0', 'NANO_data13.0', 'HRV_NANO_data']]
279280
workflows[_wfn()] = ['NANOdata130Xrun3', ['MuonEG2023MINIAOD13.0', 'NANO_data13.0_prompt', 'HRV_NANO_data']]
280281
workflows[_wfn()] = ['muPOGNANO130Xrun3', ['MuonEG2023MINIAOD13.0', 'muPOGNANO_data13.0']]
282+
workflows[_wfn()] = ['l1DPGNANO130Xrun3', ['ZMuSkim2023DRAWRECO13.0', 'l1DPGNANO_data13.0']]
281283
workflows[_wfn()] = ['EGMNANOdata130Xrun3', ['MuonEG2023MINIAOD13.0', 'EGMNano_data13.0']]
282284
workflows[_wfn()] = ['BTVNANO_data13.0', ['MuonEG2023MINIAOD13.0', 'BTVNANO_data13.0']]
283285
workflows[_wfn()] = ['jmeNANOdata130Xrun3', ['MuonEG2023MINIAOD13.0', 'jmeNano_data13.0']]

DPGAnalysis/L1TNanoAOD/BuildFile.xml

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<use name="boost"/>
2+
<export>
3+
<lib name="1"/>
4+
</export>

DPGAnalysis/L1TNanoAOD/README.md

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# L1T Nano
2+
3+
This package allows to save Level 1 Trigger information (unpacked or reemulated) in a standard NANOAOD format, after reemulating the L1 Trigger (except for the first section, where only unpacked objects are retrieved from MINIAOD). A few examples of cmsDriver commands are provided for Run 3 data and simulated samples.
4+
5+
## Naming conventions
6+
- Unpacked objects are the same as in central NANO and named `L1EG`, `L1Mu`,...
7+
- Reemulated objects are named `L1EmulEG`, `L1EmulMu`,...
8+
- Unpacked calo TPs/TTs/clusters are named `HcalUnpackedTPs`, `L1UnpackedCaloTower`, `L1UnpackedCaloCluster`,...
9+
- Reemulated calo TPs/TTs/clusters are named `HcalEmulTPs`, `L1EmulCaloTower`, `L1EmulCaloCluster`,...
10+
11+
## L1T NANO from MINIAOD
12+
13+
14+
### Add L1 objects to central NANO
15+
On can add all L1 objects on top of central NANO with the following command:
16+
17+
cmsDriver.py customL1toNANO --conditions auto:run3_data_prompt -s NANO:@PHYS+@L1FULL --datatier NANOAOD --eventcontent NANOAOD --data --process customl1nano --scenario pp --era Run3 --customise_unsch Configuration/DataProcessing/RecoTLR.customisePostEra_Run3 -n 100 --filein /store/data/Run2023D/Muon1/MINIAOD/22Sep2023_v2-v1/50000/daeae294-4d7c-4f36-8d50-33ef562cbf07.root --fileout file:out.root --python_filename=customl1nano.py
18+
19+
### Save unpacked objects only (data)
20+
If one wants to only keep L1 objects, and not offline information, use instead:
21+
22+
cmsDriver.py customL1toNANO --conditions auto:run3_data_prompt -s USER:DPGAnalysis/L1TNanoAOD/l1tNano_cff.l1tNanoTask --datatier NANOAOD --eventcontent NANOAOD --data --process customl1nano --scenario pp --era Run3 --customise Configuration/DataProcessing/RecoTLR.customisePostEra_Run3,PhysicsTools/NanoAOD/nano_cff.nanoL1TrigObjCustomizeFull -n 100 --filein /store/data/Run2023D/Muon1/MINIAOD/22Sep2023_v2-v1/50000/daeae294-4d7c-4f36-8d50-33ef562cbf07.root --fileout file:out.root --python_filename=customl1nano.py --fileout file:out.root --python_filename=customl1nano.py
23+
24+
25+
## L1T NANO standalone
26+
The following examples save L1T information (objects, TPs,...) in a standalone NANOAOD format, after reemulating the L1 trigger.
27+
28+
### Save all calo information (TPs, TT, CaloCluster) and L1T objects, both emulated and unpacked (data)
29+
30+
cmsDriver.py customL1toNANO --conditions auto:run3_data_prompt -s RAW2DIGI,NANO:@L1DPG --datatier NANOAOD --eventcontent NANOAOD --data --process customl1nano --scenario pp --era Run3 --customise Configuration/DataProcessing/RecoTLR.customisePostEra_Run3 -n 100 --filein /store/data/Run2022D/EGamma/RAW-RECO/ZElectron-27Jun2023-v2/2810003/06757985-055e-4c64-bbe3-187858ea2abf.root --fileout file:out.root --python_filename=customl1nano.py
31+
32+
### Save all calo information (TPs, TT, CaloCluster) and L1T objects, both emulated and unpacked (MC)
33+
34+
cmsDriver.py customL1toNANO --conditions auto:phase1_2024_realistic -s RAW2DIGI,NANO:@L1DPG --datatier NANOAOD --eventcontent NANOAOD --mc --process customl1nano --scenario pp --era Run3 --customise Configuration/DataProcessing/RecoTLR.customisePostEra_Run3 -n 100 --filein /store/mc/Run3Winter24Digi/WJetsToLNu_TuneCP5_13p6TeV-madgraphMLM-pythia8/GEN-SIM-RAW/133X_mcRun3_2024_realistic_v9-v2/2830000/756ef2a9-b60a-4ee1-a021-7219e48c6f4b.root --fileout file:out.root --python_filename=customl1nano.py
35+
36+
37+
## L1T + central NANO
38+
Also useful is running L1T NANO together with central NANO. Similar commands as above can be defined. A few options exist: one can start from RAW and run the whole RECO/PAT/NANO chain, or start from existing RAW-RECO to skip the time consuming re-RECO step.
39+
40+
### Run RECO, PAT, NANO and save all calo information (TPs, TT, CaloCluster) and L1T objects, both emulated and unpacked (data)
41+
42+
cmsDriver.py customL1toNANO --conditions auto:run3_data_prompt -s RAW2DIGI,L1Reco,RECO,PAT,NANO:@PHYS+@L1DPG --datatier NANOAOD --eventcontent NANOAOD --data --process customl1nano --scenario pp --era Run3 --customise Configuration/DataProcessing/RecoTLR.customisePostEra_Run3 -n 100 --filein /store/data/Run2023D/EphemeralZeroBias0/RAW/v1/000/370/560/00000/9273062a-1a69-4998-8ae1-c121323526e8.root --fileout file:out.root --python_filename=customl1nano.py
43+
44+
45+
### Run RECO, PAT, NANO and save all calo information (TPs, TT, CaloCluster) and L1T objects, both emulated and unpacked (MC)
46+
47+
cmsDriver.py customL1toNANO --conditions auto:phase1_2024_realistic -s RAW2DIGI,L1Reco,RECO,PAT,NANO:@PHYS+@L1DPG --datatier NANOAOD --eventcontent NANOAOD --mc --process customl1nano --scenario pp --era Run3 --customise Configuration/DataProcessing/RecoTLR.customisePostEra_Run3 -n 100 --filein /store/mc/Run3Winter24Digi/WJetsToLNu_TuneCP5_13p6TeV-madgraphMLM-pythia8/GEN-SIM-RAW/133X_mcRun3_2024_realistic_v9-v2/2830000/756ef2a9-b60a-4ee1-a021-7219e48c6f4b.root --python_filename=customl1nano.py
48+
49+
### Run PAT, NANO and save all calo information (TPs, TT, CaloCluster) and L1T objects, both emulated and unpacked (data)
50+
51+
52+
cmsDriver.py customL1toNANO --conditions auto:run3_data_prompt -s RAW2DIGI,L1Reco,PAT,NANO:@PHYS+@L1DPG --datatier NANOAOD --eventcontent NANOAOD --data --process customl1nano --scenario pp --era Run3 --customise Configuration/DataProcessing/RecoTLR.customisePostEra_Run3 -n 100 --filein /store/data/Run2022D/EGamma/RAW-RECO/ZElectron-27Jun2023-v2/2810003/06757985-055e-4c64-bbe3-187858ea2abf.root --fileout file:out.root --python_filename=customl1nano.py
53+
54+
55+
56+
## Notes on reemulation options
57+
There exist different options to reemulate the Level 1 Trigger. For calorimeters, one can for example use the original ECAL/HCAL trigger primitives ("unpacked") or reemulate these as well. The former option is the default one. In order to modify this, one can for example add the following customization:
58+
59+
--customise_unsch L1Trigger/Configuration/customiseReEmul.L1TReEmulFromRAWsimHcalTP
60+
61+
Mind that `--customise_unsch` (**and not** `--customise`) is to be used.
62+
63+
64+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<use name="FWCore/Framework"/>
2+
<use name="FWCore/ParameterSet"/>
3+
<use name="FWCore/PluginManager"/>
4+
<use name="FWCore/ServiceRegistry"/>
5+
<use name="FWCore/Utilities"/>
6+
<use name="CalibFormats/CaloTPG"/>
7+
<use name="DataFormats/L1TCalorimeter"/>
8+
<use name="PhysicsTools/NanoAOD"/>
9+
<use name="CommonTools/Utils"/>
10+
<library file="*.cc" name="DPGAnalysisL1TNanoAOD_plugins">
11+
<flags EDM_PLUGIN="1"/>
12+
</library>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
// -*- C++ -*-
2+
//
3+
// Package: PhysicsTools/NanoAOD
4+
// Class: CaloTPTableProducer
5+
//
6+
/**\class CaloTPTableProducer CaloTPTableProducer.cc PhysicsTools/NanoAOD/plugins/CaloTPTableProducer.cc
7+
8+
Description: [one line class summary]
9+
10+
Implementation:
11+
[Notes on implementation]
12+
*/
13+
//
14+
// Original Author: localusers user
15+
// Created: Wed, 08 Nov 2023 13:16:40 GMT
16+
//
17+
//
18+
19+
// system include files
20+
#include <memory>
21+
22+
// user include files
23+
#include "CalibFormats/CaloTPG/interface/CaloTPGTranscoder.h"
24+
#include "CalibFormats/CaloTPG/interface/CaloTPGRecord.h"
25+
26+
#include "FWCore/Framework/interface/Frameworkfwd.h"
27+
#include "FWCore/Framework/interface/stream/EDProducer.h"
28+
29+
#include "FWCore/Framework/interface/Event.h"
30+
#include "FWCore/Framework/interface/MakerMacros.h"
31+
32+
#include "FWCore/ParameterSet/interface/ParameterSet.h"
33+
#include "FWCore/Utilities/interface/StreamID.h"
34+
35+
#include "DataFormats/NanoAOD/interface/FlatTable.h"
36+
37+
#include "DataFormats/EcalDigi/interface/EcalDigiCollections.h"
38+
#include "DataFormats/HcalDigi/interface/HcalDigiCollections.h"
39+
40+
#include "DataFormats/L1TCalorimeter/interface/CaloTower.h"
41+
#include "DataFormats/L1TCalorimeter/interface/CaloCluster.h"
42+
43+
#include "Geometry/CaloGeometry/interface/CaloGeometry.h"
44+
#include "Geometry/Records/interface/CaloGeometryRecord.h"
45+
46+
//
47+
// class declaration
48+
//
49+
50+
class CaloTPTableProducer : public edm::stream::EDProducer<> {
51+
public:
52+
explicit CaloTPTableProducer(const edm::ParameterSet&);
53+
54+
static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
55+
56+
private:
57+
void beginStream(edm::StreamID) override;
58+
void produce(edm::Event&, const edm::EventSetup&) override;
59+
void endStream() override;
60+
61+
// ----------member data ---------------------------
62+
const double ecalLSB_;
63+
64+
const edm::EDGetTokenT<EcalTrigPrimDigiCollection> ecalTPsToken_;
65+
const std::string ecalTPsName_;
66+
67+
const edm::EDGetTokenT<HcalTrigPrimDigiCollection> hcalTPsToken_;
68+
const std::string hcalTPsName_;
69+
70+
const edm::ESGetToken<CaloTPGTranscoder, CaloTPGRecord> decoderToken_;
71+
};
72+
73+
CaloTPTableProducer::CaloTPTableProducer(const edm::ParameterSet& iConfig)
74+
: ecalLSB_(iConfig.getUntrackedParameter<double>("ecalLSB", 0.5)),
75+
ecalTPsToken_(consumes<EcalTrigPrimDigiCollection>(iConfig.getParameter<edm::InputTag>("ecalTPsSrc"))),
76+
ecalTPsName_(iConfig.getParameter<std::string>("ecalTPsName")),
77+
hcalTPsToken_(consumes<HcalTrigPrimDigiCollection>(iConfig.getParameter<edm::InputTag>("hcalTPsSrc"))),
78+
hcalTPsName_(iConfig.getParameter<std::string>("hcalTPsName")),
79+
decoderToken_(esConsumes<CaloTPGTranscoder, CaloTPGRecord>()) {
80+
produces<nanoaod::FlatTable>("EcalTP");
81+
produces<nanoaod::FlatTable>("HcalTP");
82+
83+
//now do what ever other initialization is needed
84+
}
85+
86+
//
87+
// member functions
88+
//
89+
90+
// ------------ method called to produce the data ------------
91+
void CaloTPTableProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
92+
using namespace edm;
93+
94+
edm::ESHandle<CaloTPGTranscoder> decoder;
95+
decoder = iSetup.getHandle(decoderToken_);
96+
97+
edm::Handle<EcalTrigPrimDigiCollection> ecalTPs;
98+
iEvent.getByToken(ecalTPsToken_, ecalTPs);
99+
100+
edm::Handle<HcalTrigPrimDigiCollection> hcalTPs;
101+
iEvent.getByToken(hcalTPsToken_, hcalTPs);
102+
103+
vector<int> ecalTPieta;
104+
vector<int> ecalTPCaliphi;
105+
vector<int> ecalTPiphi;
106+
vector<float> ecalTPet;
107+
vector<int> ecalTPcompEt;
108+
vector<int> ecalTPfineGrain;
109+
int nECALTP(0);
110+
if (ecalTPs.isValid()) {
111+
for (const auto& itr : *(ecalTPs.product())) {
112+
short ieta = (short)itr.id().ieta();
113+
114+
unsigned short cal_iphi = (unsigned short)itr.id().iphi();
115+
unsigned short iphi = (72 + 18 - cal_iphi) % 72;
116+
unsigned short compEt = itr.compressedEt();
117+
double et = ecalLSB_ * compEt;
118+
unsigned short fineGrain = (unsigned short)itr.fineGrain();
119+
120+
if (compEt > 0) {
121+
ecalTPieta.push_back(ieta);
122+
ecalTPCaliphi.push_back(cal_iphi);
123+
ecalTPiphi.push_back(iphi);
124+
ecalTPet.push_back(et);
125+
ecalTPcompEt.push_back(compEt);
126+
ecalTPfineGrain.push_back(fineGrain);
127+
nECALTP++;
128+
}
129+
}
130+
}
131+
auto ecalTPTable = std::make_unique<nanoaod::FlatTable>(nECALTP, ecalTPsName_, false);
132+
ecalTPTable->addColumn<int16_t>("ieta", ecalTPieta, "");
133+
ecalTPTable->addColumn<int16_t>("Caliphi", ecalTPCaliphi, "");
134+
ecalTPTable->addColumn<int16_t>("iphi", ecalTPiphi, "");
135+
ecalTPTable->addColumn<float>("et", ecalTPet, "", 12);
136+
ecalTPTable->addColumn<int16_t>("compEt", ecalTPcompEt, "");
137+
ecalTPTable->addColumn<int16_t>("fineGrain", ecalTPfineGrain, "");
138+
139+
vector<int> hcalTPieta;
140+
vector<int> hcalTPCaliphi;
141+
vector<int> hcalTPiphi;
142+
vector<float> hcalTPet;
143+
vector<int> hcalTPcompEt;
144+
vector<int> hcalTPfineGrain;
145+
int nHCALTP(0);
146+
if (hcalTPs.isValid()) {
147+
for (auto itr : (*hcalTPs.product())) {
148+
int ver = itr.id().version();
149+
short ieta = (short)itr.id().ieta();
150+
unsigned short absIeta = (unsigned short)abs(ieta);
151+
unsigned short cal_iphi = (unsigned short)itr.id().iphi();
152+
unsigned short iphi = (72 + 18 - cal_iphi) % 72;
153+
154+
unsigned short compEt = itr.SOI_compressedEt();
155+
double et = decoder->hcaletValue(itr.id(), itr.t0());
156+
unsigned short fineGrain = (unsigned short)itr.SOI_fineGrain();
157+
158+
if (compEt > 0 && (absIeta < 29 || ver == 1)) {
159+
hcalTPieta.push_back(ieta);
160+
hcalTPCaliphi.push_back(cal_iphi);
161+
hcalTPiphi.push_back(iphi);
162+
hcalTPet.push_back(et);
163+
hcalTPcompEt.push_back(compEt);
164+
hcalTPfineGrain.push_back(fineGrain);
165+
nHCALTP++;
166+
}
167+
}
168+
}
169+
170+
auto hcalTPTable = std::make_unique<nanoaod::FlatTable>(nHCALTP, hcalTPsName_, false);
171+
hcalTPTable->addColumn<int16_t>("ieta", hcalTPieta, "");
172+
hcalTPTable->addColumn<int16_t>("Caliphi", hcalTPCaliphi, "");
173+
hcalTPTable->addColumn<int16_t>("iphi", hcalTPiphi, "");
174+
hcalTPTable->addColumn<float>("et", hcalTPet, "", 12);
175+
hcalTPTable->addColumn<int16_t>("compEt", hcalTPcompEt, "");
176+
hcalTPTable->addColumn<int16_t>("fineGrain", hcalTPfineGrain, "");
177+
178+
iEvent.put(std::move(ecalTPTable), "HcalTP");
179+
iEvent.put(std::move(hcalTPTable), "EcalTP");
180+
}
181+
182+
// ------------ method called once each stream before processing any runs, lumis or events ------------
183+
void CaloTPTableProducer::beginStream(edm::StreamID) {
184+
// please remove this method if not needed
185+
}
186+
187+
// ------------ method called once each stream after processing all runs, lumis and events ------------
188+
void CaloTPTableProducer::endStream() {
189+
// please remove this method if not needed
190+
}
191+
192+
// ------------ method fills 'descriptions' with the allowed parameters for the module ------------
193+
void CaloTPTableProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
194+
edm::ParameterSetDescription desc;
195+
196+
desc.add<std::string>("name", "l1calotowerflattableproducer");
197+
desc.addUntracked<double>("ecalLSB", 0.5);
198+
desc.add<edm::InputTag>("ecalTPsSrc", edm::InputTag{"ecalDigis", "EcalTriggerPrimitives"});
199+
desc.add<string>("ecalTPsName", "EcalUnpackedTPs");
200+
desc.add<edm::InputTag>("hcalTPsSrc", edm::InputTag{"hcalDigis"});
201+
desc.add<string>("hcalTPsName", "HcalUnpackedTPs");
202+
203+
descriptions.addWithDefaultLabel(desc);
204+
}
205+
206+
//define this as a plug-in
207+
DEFINE_FWK_MODULE(CaloTPTableProducer);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#include "PhysicsTools/NanoAOD/interface/SimpleFlatTableProducer.h"
2+
3+
#include "DataFormats/L1TCalorimeter/interface/CaloTower.h"
4+
typedef BXVectorSimpleFlatTableProducer<l1t::CaloTower> SimpleTriggerL1CaloTowerFlatTableProducer;
5+
6+
#include "DataFormats/L1TCalorimeter/interface/CaloCluster.h"
7+
typedef BXVectorSimpleFlatTableProducer<l1t::CaloCluster> SimpleTriggerL1CaloClusterFlatTableProducer;
8+
9+
#include "FWCore/Framework/interface/MakerMacros.h"
10+
DEFINE_FWK_MODULE(SimpleTriggerL1CaloTowerFlatTableProducer);
11+
DEFINE_FWK_MODULE(SimpleTriggerL1CaloClusterFlatTableProducer);

0 commit comments

Comments
 (0)