Skip to content

Commit

Permalink
Custom L1 NanoAOD
Browse files Browse the repository at this point in the history
  • Loading branch information
lathomas committed Feb 13, 2024
1 parent 695ed78 commit e5d3ea1
Show file tree
Hide file tree
Showing 10 changed files with 725 additions and 0 deletions.
4 changes: 4 additions & 0 deletions DPGAnalysis/L1TNanoAOD/BuildFile.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<use name="boost"/>
<export>
<lib name="1"/>
</export>
45 changes: 45 additions & 0 deletions DPGAnalysis/L1TNanoAOD/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# L1T Nano

This package allows to save Level 1 Trigger information (unpacked or reemulated) in a standard NANOAOD format. A few examples of cmsDriver commands are provided for Run 3 data and simulated samples.

## Naming conventions
- Unpacked objects are the same as in central NANO and named `L1EG`, `L1Mu`,...
- Reemulated objects are named `L1EmulEG`, `L1EmulMu`,...
- Unpacked calo TPs/TTs/clusters are named `HcalUnpackedTPs`, `L1UnpackedCaloTower`, `L1UnpackedCaloCluster`,...
- Reemulated calo TPs/TTs/clusters are named `HcalEmulTPs`, `L1EmulCaloTower`, `L1EmulCaloCluster`,...

## L1T NANO standalone
The following examples save L1T information (objects, TPs,...) in a standalone NANOAOD format.

### Save unpacked objects only (data)
This relies on central customization code (in `PhysicsToos/NanoAOD`) that allows you to store all unpacked L1T objects.

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


### Save all calo information (TPs, TT, CaloCluster) and L1T objects, both emulated and unpacked (data)

cmsDriver.py customL1toNANO --conditions auto:run3_data_prompt -s RAW2DIGI,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,DPGAnalysis/L1TNanoAOD/l1tNano_cff.addCaloFull,L1Trigger/Configuration/customiseReEmul.L1TReEmulFromRAWsimHcalTP -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

### Save all calo information (TPs, TT, CaloCluster) and L1T objects, both emulated and unpacked (MC)

cmsDriver.py customL1toNANO --conditions auto:phase1_2023_realistic -s RAW2DIGI,USER:DPGAnalysis/L1TNanoAOD/l1tNano_cff.l1tNanoTask --datatier NANOAOD --eventcontent NANOAOD --mc --process customl1nano --scenario pp --era Run3 --customise Configuration/DataProcessing/RecoTLR.customisePostEra_Run3,PhysicsTools/NanoAOD/nano_cff.nanoL1TrigObjCustomizeFull,DPGAnalysis/L1TNanoAOD/l1tNano_cff.addCaloFull,L1Trigger/Configuration/customiseReEmul.L1TReEmulFromRAWsimHcalTP -n 100 --filein /store/mc/Run3Winter23Digi/DYto2L-4Jets_MLL-50_TuneCP5_13p6TeV_madgraphMLM-pythia8/GEN-SIM-RAW/126X_mcRun3_2023_forPU65_v1-v2/70000/66b76d59-de20-4465-af3d-1a7fd296dbc8.root --fileout file:out.root --python_filename=customl1nano.py


## L1T + central NANO
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.

### Run RECO, PAT, NANO and save all calo information (TPs, TT, CaloCluster) and L1T objects, both emulated and unpacked (data)

cmsDriver.py customL1toNANO --conditions auto:run3_data_prompt -s RAW2DIGI,L1Reco,RECO,PAT,NANO,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,DPGAnalysis/L1TNanoAOD/l1tNano_cff.addCaloFull,L1Trigger/Configuration/customiseReEmul.L1TReEmulFromRAWsimHcalTP -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


### Run RECO, PAT, NANO and save all calo information (TPs, TT, CaloCluster) and L1T objects, both emulated and unpacked (MC)

cmsDriver.py customL1toNANO --conditions auto:phase1_2023_realistic -s RAW2DIGI,L1Reco,RECO,PAT,NANO,USER:DPGAnalysis/L1TNanoAOD/l1tNano_cff.l1tNanoTask --datatier NANOAOD --eventcontent NANOAOD --mc --process customl1nano --scenario pp --era Run3 --customise Configuration/DataProcessing/RecoTLR.customisePostEra_Run3,PhysicsTools/NanoAOD/nano_cff.nanoL1TrigObjCustomizeFull,DPGAnalysis/L1TNanoAOD/l1tNano_cff.addCaloFull,L1Trigger/Configuration/customiseReEmul.L1TReEmulFromRAWsimHcalTP -n 100 --filein /store/mc/Run3Winter23Digi/DYto2L-4Jets_MLL-50_TuneCP5_13p6TeV_madgraphMLM-pythia8/GEN-SIM-RAW/126X_mcRun3_2023_forPU65_v1-v2/70000/66b76d59-de20-4465-af3d-1a7fd296dbc8.root --fileout file:out.root --python_filename=customl1nano.py

### Run PAT, NANO and save all calo information (TPs, TT, CaloCluster) and L1T objects, both emulated and unpacked (data)


cmsDriver.py customL1toNANO --conditions auto:run3_data_prompt -s RAW2DIGI,L1Reco,PAT,NANO,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,DPGAnalysis/L1TNanoAOD/l1tNano_cff.addCaloFull,L1Trigger/Configuration/customiseReEmul.L1TReEmulFromRAWsimHcalTP -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

12 changes: 12 additions & 0 deletions DPGAnalysis/L1TNanoAOD/plugins/BuildFile.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<use name="FWCore/Framework"/>
<use name="FWCore/ParameterSet"/>
<use name="FWCore/PluginManager"/>
<use name="FWCore/ServiceRegistry"/>
<use name="FWCore/Utilities"/>
<use name="CalibFormats/CaloTPG"/>
<use name="DataFormats/L1TCalorimeter"/>
<use name="PhysicsTools/NanoAOD"/>
<use name="CommonTools/Utils"/>
<library file="*.cc" name="DPGAnalysisL1TNanoAOD_plugins">
<flags EDM_PLUGIN="1"/>
</library>
267 changes: 267 additions & 0 deletions DPGAnalysis/L1TNanoAOD/plugins/CaloTPTableProducer.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,267 @@
// -*- C++ -*-
//
// Package: PhysicsTools/NanoAOD
// Class: CaloTPTableProducer
//
/**\class CaloTPTableProducer CaloTPTableProducer.cc PhysicsTools/NanoAOD/plugins/CaloTPTableProducer.cc
Description: [one line class summary]
Implementation:
[Notes on implementation]
*/
//
// Original Author: localusers user
// Created: Wed, 08 Nov 2023 13:16:40 GMT
//
//

// system include files
#include <memory>

// user include files
#include "CalibFormats/CaloTPG/interface/CaloTPGTranscoder.h"
#include "CalibFormats/CaloTPG/interface/CaloTPGRecord.h"

#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 "DataFormats/NanoAOD/interface/FlatTable.h"

#include "DataFormats/EcalDigi/interface/EcalDigiCollections.h"
#include "DataFormats/HcalDigi/interface/HcalDigiCollections.h"

#include "DataFormats/L1TCalorimeter/interface/CaloTower.h"
#include "DataFormats/L1TCalorimeter/interface/CaloCluster.h"

#include "Geometry/CaloGeometry/interface/CaloGeometry.h"
#include "Geometry/Records/interface/CaloGeometryRecord.h"

//
// class declaration
//

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

static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);

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

//void beginRun(edm::Run const&, edm::EventSetup const&) override;
//void endRun(edm::Run const&, edm::EventSetup const&) override;
//void beginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override;
//void endLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override;

// ----------member data ---------------------------
const double ecalLSB_;

const edm::EDGetTokenT<EcalTrigPrimDigiCollection> ecalTPsToken_;
const std::string ecalTPsName_;

const edm::EDGetTokenT<HcalTrigPrimDigiCollection> hcalTPsToken_;
const std::string hcalTPsName_;

const edm::ESGetToken<CaloTPGTranscoder, CaloTPGRecord> decoderToken_;
};

//
// constants, enums and typedefs
//

//
// static data member definitions
//

//
// constructors and destructor
//
CaloTPTableProducer::CaloTPTableProducer(const edm::ParameterSet& iConfig)
:
ecalLSB_(iConfig.getUntrackedParameter<double>("ecalLSB", 0.5)),
ecalTPsToken_(consumes<EcalTrigPrimDigiCollection>(iConfig.getParameter<edm::InputTag>("ecalTPsSrc"))),
ecalTPsName_(iConfig.getParameter<std::string>("ecalTPsName")),
hcalTPsToken_(consumes<HcalTrigPrimDigiCollection>(iConfig.getParameter<edm::InputTag>("hcalTPsSrc"))),
hcalTPsName_(iConfig.getParameter<std::string>("hcalTPsName")),
decoderToken_(esConsumes<CaloTPGTranscoder, CaloTPGRecord>())
{

produces<nanoaod::FlatTable>("EcalTP");
produces<nanoaod::FlatTable>("HcalTP");

//now do what ever other initialization is needed
}

CaloTPTableProducer::~CaloTPTableProducer() {
// do anything here that needs to be done at destruction time
// (e.g. close files, deallocate resources etc.)
//
// please remove this method altogether if it would be left empty
}

//
// member functions
//

// ------------ method called to produce the data ------------
void CaloTPTableProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
using namespace edm;

edm::ESHandle<CaloTPGTranscoder> decoder;
decoder = iSetup.getHandle(decoderToken_);

edm::Handle<EcalTrigPrimDigiCollection> ecalTPs;
iEvent.getByToken(ecalTPsToken_, ecalTPs);

edm::Handle<HcalTrigPrimDigiCollection> hcalTPs;
iEvent.getByToken(hcalTPsToken_, hcalTPs);

vector<int>ecalTPieta;
vector<int>ecalTPCaliphi;
vector<int>ecalTPiphi;
vector<float>ecalTPet;
vector<int>ecalTPcompEt;
vector<int>ecalTPfineGrain;
int nECALTP(0);
if (ecalTPs.isValid()) {
for (const auto& itr : *(ecalTPs.product())) {
short ieta = (short)itr.id().ieta();

unsigned short cal_iphi = (unsigned short)itr.id().iphi();
unsigned short iphi = (72 + 18 - cal_iphi) % 72;
unsigned short compEt = itr.compressedEt();
double et = ecalLSB_ * compEt;
unsigned short fineGrain = (unsigned short)itr.fineGrain();

if (compEt > 0) {
ecalTPieta.push_back(ieta);
ecalTPCaliphi.push_back(cal_iphi);
ecalTPiphi.push_back(iphi);
ecalTPet.push_back(et);
ecalTPcompEt.push_back(compEt);
ecalTPfineGrain.push_back(fineGrain);
nECALTP++;
}
}
}
auto ecalTPTable = std::make_unique<nanoaod::FlatTable>(nECALTP, ecalTPsName_, false);
ecalTPTable->addColumn<int16_t>("ieta", ecalTPieta, "");
ecalTPTable->addColumn<int16_t>("Caliphi", ecalTPCaliphi, "");
ecalTPTable->addColumn<int16_t>("iphi", ecalTPiphi, "");
ecalTPTable->addColumn<float>("et", ecalTPet, "", 12);
ecalTPTable->addColumn<int16_t>("compEt", ecalTPcompEt, "");
ecalTPTable->addColumn<int16_t>("fineGrain", ecalTPfineGrain, "");



vector<int>hcalTPieta;
vector<int>hcalTPCaliphi;
vector<int>hcalTPiphi;
vector<float>hcalTPet;
vector<int>hcalTPcompEt;
vector<int>hcalTPfineGrain;
int nHCALTP(0);
if (hcalTPs.isValid()) {
for (auto itr : (*hcalTPs.product())) {

int ver = itr.id().version();
short ieta = (short)itr.id().ieta();
unsigned short absIeta = (unsigned short)abs(ieta);
unsigned short cal_iphi = (unsigned short)itr.id().iphi();
unsigned short iphi = (72 + 18 - cal_iphi) % 72;

unsigned short compEt = itr.SOI_compressedEt();
double et = decoder->hcaletValue(itr.id(), itr.t0());
unsigned short fineGrain = (unsigned short)itr.SOI_fineGrain();

if (compEt > 0 && (absIeta < 29 || ver == 1)) {
hcalTPieta.push_back(ieta);
hcalTPCaliphi.push_back(cal_iphi);
hcalTPiphi.push_back(iphi);
hcalTPet.push_back(et);
hcalTPcompEt.push_back(compEt);
hcalTPfineGrain.push_back(fineGrain);
nHCALTP++;
}
}
}

auto hcalTPTable = std::make_unique<nanoaod::FlatTable>(nHCALTP, hcalTPsName_, false);
hcalTPTable->addColumn<int16_t>("ieta", hcalTPieta, "");
hcalTPTable->addColumn<int16_t>("Caliphi", hcalTPCaliphi, "");
hcalTPTable->addColumn<int16_t>("iphi", hcalTPiphi, "");
hcalTPTable->addColumn<float>("et", hcalTPet, "", 12);
hcalTPTable->addColumn<int16_t>("compEt", hcalTPcompEt, "");
hcalTPTable->addColumn<int16_t>("fineGrain", hcalTPfineGrain, "");


iEvent.put(std::move(ecalTPTable), "HcalTP");
iEvent.put(std::move(hcalTPTable), "EcalTP");


}

// ------------ method called once each stream before processing any runs, lumis or events ------------
void CaloTPTableProducer::beginStream(edm::StreamID) {
// please remove this method if not needed
}

// ------------ method called once each stream after processing all runs, lumis and events ------------
void CaloTPTableProducer::endStream() {
// please remove this method if not needed
}

// ------------ method called when starting to processes a run ------------
/*
void
CaloTPTableProducer::beginRun(edm::Run const&, edm::EventSetup const&)
{
}
*/

// ------------ method called when ending the processing of a run ------------
/*
void
CaloTPTableProducer::endRun(edm::Run const&, edm::EventSetup const&)
{
}
*/

// ------------ method called when starting to processes a luminosity block ------------
/*
void
CaloTPTableProducer::beginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&)
{
}
*/

// ------------ method called when ending the processing of a luminosity block ------------
/*
void
CaloTPTableProducer::endLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&)
{
}
*/

// ------------ method fills 'descriptions' with the allowed parameters for the module ------------
void CaloTPTableProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
//The following says we do not know what parameters are allowed so do no validation
// Please change this to state exactly what you do use, even if it is no parameters
edm::ParameterSetDescription desc;
desc.setUnknown();
descriptions.addDefault(desc);
}

//define this as a plug-in
DEFINE_FWK_MODULE(CaloTPTableProducer);
11 changes: 11 additions & 0 deletions DPGAnalysis/L1TNanoAOD/plugins/SimpleFlatTableProducerPlugins.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include "PhysicsTools/NanoAOD/interface/SimpleFlatTableProducer.h"

#include "DataFormats/L1TCalorimeter/interface/CaloTower.h"
typedef BXVectorSimpleFlatTableProducer<l1t::CaloTower> SimpleTriggerL1CaloTowerFlatTableProducer;

#include "DataFormats/L1TCalorimeter/interface/CaloCluster.h"
typedef BXVectorSimpleFlatTableProducer<l1t::CaloCluster> SimpleTriggerL1CaloClusterFlatTableProducer;

#include "FWCore/Framework/interface/MakerMacros.h"
DEFINE_FWK_MODULE(SimpleTriggerL1CaloTowerFlatTableProducer);
DEFINE_FWK_MODULE(SimpleTriggerL1CaloClusterFlatTableProducer);
Loading

0 comments on commit e5d3ea1

Please sign in to comment.