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

Modify CaloLayer1 emulator to properly handle saturation in all cases #20000

Merged
merged 4 commits into from Oct 5, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
19 changes: 10 additions & 9 deletions L1Trigger/L1TCaloLayer1/plugins/L1TCaloLayer1.cc
Expand Up @@ -59,16 +59,16 @@ using namespace l1tcalo;
class L1TCaloLayer1 : public edm::EDProducer {
public:
explicit L1TCaloLayer1(const edm::ParameterSet&);
~L1TCaloLayer1();
~L1TCaloLayer1() override;

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

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

virtual void beginRun(edm::Run const&, edm::EventSetup const&) override;
void beginRun(edm::Run const&, edm::EventSetup const&) override;

//virtual void endRun(edm::Run const&, edm::EventSetup const&) override;
//virtual void beginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override;
Expand Down Expand Up @@ -99,6 +99,7 @@ class L1TCaloLayer1 : public edm::EDProducer {
bool verbose;
bool unpackHcalMask;
bool unpackEcalMask;
int fwVersion;

UCTLayer1 *layer1;

Expand Down Expand Up @@ -131,13 +132,13 @@ L1TCaloLayer1::L1TCaloLayer1(const edm::ParameterSet& iConfig) :
useHFLUT(iConfig.getParameter<bool>("useHFLUT")),
verbose(iConfig.getParameter<bool>("verbose")),
unpackHcalMask(iConfig.getParameter<bool>("unpackHcalMask")),
unpackEcalMask(iConfig.getParameter<bool>("unpackEcalMask"))
unpackEcalMask(iConfig.getParameter<bool>("unpackEcalMask")),
fwVersion(iConfig.getParameter<int>("firmwareVersion"))
{
produces<CaloTowerBxCollection>();
produces<L1CaloRegionCollection>();

// See UCTLayer1.hh for firmware version definitions
int fwVersion = iConfig.getParameter<int>("firmwareVersion");
layer1 = new UCTLayer1(fwVersion);

vector<UCTCrate*> crates = layer1->getCrates();
Expand All @@ -162,7 +163,7 @@ L1TCaloLayer1::L1TCaloLayer1(const edm::ParameterSet& iConfig) :
}

L1TCaloLayer1::~L1TCaloLayer1() {
if(layer1 != 0) delete layer1;
if(layer1 != nullptr) delete layer1;
}

//
Expand Down Expand Up @@ -309,7 +310,7 @@ L1TCaloLayer1::endJob() {
void
L1TCaloLayer1::beginRun(const edm::Run& iRun, const edm::EventSetup& iSetup)
{
if(!L1TCaloLayer1FetchLUTs(iSetup, ecalLUT, hcalLUT, hfLUT, ePhiMap, hPhiMap, hfPhiMap, useLSB, useCalib, useECALLUT, useHCALLUT, useHFLUT)) {
if(!L1TCaloLayer1FetchLUTs(iSetup, ecalLUT, hcalLUT, hfLUT, ePhiMap, hPhiMap, hfPhiMap, useLSB, useCalib, useECALLUT, useHCALLUT, useHFLUT, fwVersion)) {
LOG_ERROR << "L1TCaloLayer1::beginRun: failed to fetch LUTS - using unity" << std::endl;
std::array< std::array< std::array<uint32_t, nEtBins>, nCalSideBins >, nCalEtaBins> eCalLayer1EtaSideEtArray;
std::array< std::array< std::array<uint32_t, nEtBins>, nCalSideBins >, nCalEtaBins> hCalLayer1EtaSideEtArray;
Expand Down
Expand Up @@ -20,3 +20,6 @@
# See UCTLayer1.hh for firmware version
firmwareVersion = cms.int32(1),
)

from Configuration.Eras.Modifier_stage2L1Trigger_2017_cff import stage2L1Trigger_2017
stage2L1Trigger_2017.toModify( simCaloStage2Layer1Digis, firmwareVersion = cms.int32(3) )
56 changes: 46 additions & 10 deletions L1Trigger/L1TCaloLayer1/src/L1TCaloLayer1FetchLUTs.cc
Expand Up @@ -37,7 +37,8 @@ bool L1TCaloLayer1FetchLUTs(const edm::EventSetup& iSetup,
bool useCalib,
bool useECALLUT,
bool useHCALLUT,
bool useHFLUT) {
bool useHFLUT,
int fwVersion) {

int hfValid = 1;
edm::ESHandle<HcalTrigTowerGeometry> pG;
Expand Down Expand Up @@ -122,7 +123,7 @@ bool L1TCaloLayer1FetchLUTs(const edm::EventSetup& iSetup,
}

// Sanity check scale factors exist
if ( useCalib && (ecalSF.size()==0 || hcalSF.size()==0 || hfSF.size()==0) ) {
if ( useCalib && (ecalSF.empty() || hcalSF.empty() || hfSF.empty()) ) {
edm::LogError("L1TCaloLayer1FetchLUTs") << "Layer 1 calibrations requested (useCalib = True) but there are missing scale factors in CaloParams! Please check conditions setup.";
return false;
}
Expand Down Expand Up @@ -171,9 +172,18 @@ bool L1TCaloLayer1FetchLUTs(const edm::EventSetup& iSetup,
if (useLSB) calibratedECalInput /= caloLSB;

value = calibratedECalInput;
if(value > 0xFF) {
value = 0xFF;
}
if ( fwVersion > 2 ) {
// Saturate if either decompressed value is over 127.5 GeV or input saturated
// (meaningless for ecal, since ecalLSB == caloLSB)
if(value > 0xFF || ecalInput == 0xFF) {
value = 0xFF;
}
}
else {
if(value > 0xFF) {
value = 0xFF;
}
}
}
if(value == 0) {
value = (1 << 11);
Expand Down Expand Up @@ -226,8 +236,16 @@ bool L1TCaloLayer1FetchLUTs(const edm::EventSetup& iSetup,
if(useLSB) calibratedHcalInput /= caloLSB;

value = calibratedHcalInput;
if(value > 0xFF) {
value = 0xFF;
if ( fwVersion > 2 ) {
// Saturate if either decompressed value is over 127.5 GeV or input saturated
if(value > 0xFF || hcalInput == 0xFF) {
value = 0xFF;
}
}
else {
if(value > 0xFF) {
value = 0xFF;
}
}
}
if(value == 0) {
Expand Down Expand Up @@ -282,9 +300,27 @@ bool L1TCaloLayer1FetchLUTs(const edm::EventSetup& iSetup,
if(useCalib) calibratedHFInput *= hfSF.at(phiBin*hfScalePhiBins.size()*12+etBin*12+etaBin);
if(useLSB) calibratedHFInput /= caloLSB;

value = calibratedHFInput;
if(value > 0xFF) {
value = 0xFF;
if ( fwVersion > 2 ) {
uint32_t absCaloEta = std::abs(caloEta);
if(absCaloEta > 29 && absCaloEta < 40) {
// Divide by two (since two duplicate towers are sent)
calibratedHFInput *= 0.5;
}
else if(absCaloEta == 40 || absCaloEta == 41) {
// Divide by four
calibratedHFInput *= 0.25;
}
value = calibratedHFInput;
// Saturate if either decompressed value is over 127.5 GeV or input saturated
if(value >= 0xFF || etCode == 0xFF) {
value = 0x1FD;
}
}
else {
value = calibratedHFInput;
if(value > 0xFF) {
value = 0xFF;
}
}
}
hfLUT[phiBin][etaBin][etCode] = value;
Expand Down
3 changes: 2 additions & 1 deletion L1Trigger/L1TCaloLayer1/src/L1TCaloLayer1FetchLUTs.hh
Expand Up @@ -18,6 +18,7 @@ bool L1TCaloLayer1FetchLUTs(const edm::EventSetup& iSetup,
bool useCalib = true,
bool useECALLUT = true,
bool useHCALLUT = true,
bool useHFLUT = true);
bool useHFLUT = true,
int fwVersion = 0);

#endif
4 changes: 4 additions & 0 deletions L1Trigger/L1TCaloLayer1/src/UCTLayer1.hh
Expand Up @@ -16,6 +16,10 @@ public:
// Default (0): initial version for 2016 running
// 1: Update to include saturated tower codes to layer 2
// (put online at run >= 275908: http://cmsonline.cern.ch/cms-elog/931059)
// 2: Update for all-LUT processing, initially no change in behavior
// (put online at run >= 291173: http://cmsonline.cern.ch/cms-elog/973914)
// 3: Update to handle saturation codes HF (and do division in LUT, and consider HBHE saturation before decompression)
// (put online at run >= 299756: http://cmsonline.cern.ch/cms-elog/999604)
//
UCTLayer1(int fwv=0);

Expand Down
55 changes: 34 additions & 21 deletions L1Trigger/L1TCaloLayer1/src/UCTTower.cc
Expand Up @@ -2,9 +2,9 @@
#include <iomanip>
#include <string>
#include <vector>
#include <math.h>
#include <stdlib.h>
#include <stdint.h>
#include <cmath>
#include <cstdlib>
#include <cstdint>

#include "UCTTower.hh"
#include "UCTLogging.hh"
Expand All @@ -20,7 +20,7 @@ bool UCTTower::process() {
uint32_t calibratedECALET = ecalET;
uint32_t logECALET = (uint32_t) log2((double) ecalET);
if(logECALET > erMaxV) logECALET = erMaxV;
if(ecalLUT != 0) {
if(ecalLUT != nullptr) {
uint32_t etaAddress = region * NEtaInRegion + iEta;
uint32_t fbAddress = 0;
if(ecalFG) fbAddress = 1;
Expand All @@ -31,7 +31,7 @@ bool UCTTower::process() {
uint32_t calibratedHCALET = hcalET;
uint32_t logHCALET = (uint32_t) log2((double) hcalET);
if(logHCALET > erMaxV) logHCALET = erMaxV;
if(hcalLUT != 0) {
if(hcalLUT != nullptr) {
uint32_t etaAddress = region * NEtaInRegion + iEta;
uint32_t fbAddress = 0;
if((hcalFB & 0x1) != 0) fbAddress = 1;
Expand Down Expand Up @@ -90,24 +90,37 @@ bool UCTTower::process() {
}

bool UCTTower::processHFTower() {
uint32_t calibratedET = hcalET;
if(hfLUT != 0) {
uint32_t etaAddress = (region - NRegionsInCard) * NHFEtaInRegion + iEta;
const std::array< uint32_t, 256> a = hfLUT->at(etaAddress);
calibratedET = a[hcalET] & 0xFF;
if ( fwVersion > 2 ) {
uint32_t calibratedET = hcalET;
if(hfLUT != nullptr) {
uint32_t etaAddress = (region - NRegionsInCard) * NHFEtaInRegion + iEta;
const std::array< uint32_t, 256>& a = hfLUT->at(etaAddress);
calibratedET = a[hcalET] & 0x1FF;
}
towerData = calibratedET | zeroFlagMask;
if((hcalFB & 0x1) == 0x1) towerData |= ecalFlagMask; // LSB defines short over long fiber ratio
if((hcalFB & 0x2) == 0x2) towerData |= hcalFlagMask; // MSB defines minbias flag
}
uint32_t absCaloEta = abs(caloEta());
if(absCaloEta > 29 && absCaloEta < 40) {
// Divide by two (since two duplicate towers are sent)
calibratedET /= 2;
}
else if(absCaloEta == 40 || absCaloEta == 41) {
// Divide by four
calibratedET /= 4;
else {
uint32_t calibratedET = hcalET;
if(hfLUT != nullptr) {
uint32_t etaAddress = (region - NRegionsInCard) * NHFEtaInRegion + iEta;
const std::array< uint32_t, 256>& a = hfLUT->at(etaAddress);
calibratedET = a[hcalET] & 0xFF;
}
uint32_t absCaloEta = abs(caloEta());
if(absCaloEta > 29 && absCaloEta < 40) {
// Divide by two (since two duplicate towers are sent)
calibratedET /= 2;
}
else if(absCaloEta == 40 || absCaloEta == 41) {
// Divide by four
calibratedET /= 4;
}
towerData = calibratedET | zeroFlagMask;
if((hcalFB & 0x1) == 0x1) towerData |= ecalFlagMask; // LSB defines short over long fiber ratio
if((hcalFB & 0x2) == 0x2) towerData |= hcalFlagMask; // MSB defines minbias flag
}
towerData = calibratedET | zeroFlagMask;
if((hcalFB & 0x1) == 0x1) towerData |= ecalFlagMask; // LSB defines short over long fiber ratio
if((hcalFB & 0x2) == 0x2) towerData |= hcalFlagMask; // MSB defines minbias flag
return true;
}

Expand Down
12 changes: 6 additions & 6 deletions L1Trigger/L1TCaloLayer1/src/UCTTower.hh
Expand Up @@ -42,9 +42,9 @@ public:
ecalET(0),
hcalET(0),
hcalFB(0),
ecalLUT(0),
hcalLUT(0),
hfLUT(0),
ecalLUT(nullptr),
hcalLUT(nullptr),
hfLUT(nullptr),
towerData(0),
fwVersion(fwv)
{}
Expand Down Expand Up @@ -135,15 +135,15 @@ private:

// No default constructor is needed

UCTTower();
UCTTower() = delete;

// No copy constructor is needed

UCTTower(const UCTTower&);
UCTTower(const UCTTower&) = delete;

// No equality operator is needed

const UCTTower& operator=(const UCTTower&);
const UCTTower& operator=(const UCTTower&) = delete;

// Tower location definition

Expand Down