Skip to content

Commit

Permalink
(Un)packing of hadronic showers at the uGMT output
Browse files Browse the repository at this point in the history
  • Loading branch information
dinyar committed Sep 27, 2021
1 parent 76d060a commit 7df3854
Show file tree
Hide file tree
Showing 4 changed files with 163 additions and 85 deletions.
142 changes: 92 additions & 50 deletions EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonPacker.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@
namespace l1t {
namespace stage2 {
Blocks MuonPacker::pack(const edm::Event& event, const PackerTokens* toks) {
edm::Handle<MuonBxCollection> muons;
event.getByToken(static_cast<const CommonTokens*>(toks)->getMuonToken(), muons);
GMTOutputObjectMap gmtObjMap;
std::pair<int, int> muonBx = getMuons(gmtObjMap, event, static_cast<const CommonTokens*>(toks)->getMuonToken());
std::pair<int, int> muonShowerBx{0, 0};
if (fedId_ == 1402 && fwId_ >= 0x7000000) {
muonShowerBx = getMuonShowers(gmtObjMap, event, static_cast<const CommonTokens*>(toks)->getMuonShowerToken());
}

PayloadMap payloadMap;

for (int bx = muons->getFirstBX(); bx <= muons->getLastBX(); ++bx) {
packBx(payloadMap, muons, bx);
}
packBx(gmtObjMap, muonBx.first, muonBx.second, muonShowerBx.first, muonShowerBx.second, payloadMap);

Blocks blocks;
// push everything in the blocks vector
Expand All @@ -23,58 +25,98 @@ namespace l1t {
return blocks;
}

void MuonPacker::packBx(PayloadMap& payloadMap, const edm::Handle<MuonBxCollection>& muons, int bx) {
// the first word in every BX and every block id is 0
for (unsigned int blkId = b1_; blkId < b1_ + 7; blkId += 2) {
payloadMap[blkId].push_back(0);
std::pair<int, int> MuonPacker::getMuonShowers(GMTOutputObjectMap& objMap,
const edm::Event& event,
const edm::EDGetTokenT<MuonShowerBxCollection>& showerToken) {
edm::Handle<MuonShowerBxCollection> muonShowers;
event.getByToken(showerToken, muonShowers);
for (int bx = muonShowers->getFirstBX(); bx <= muonShowers->getLastBX(); ++bx) {
if (muonShowers->size(bx) > 0) {
objMap[bx].shower = muonShowers->at(bx, 0); // At most one shower per BX.
}
}
return std::make_pair(muonShowers->getFirstBX(), muonShowers->getLastBX());
}

std::pair<int, int> MuonPacker::getMuons(GMTOutputObjectMap& objMap,
const edm::Event& event,
const edm::EDGetTokenT<MuonBxCollection>& muonToken) {
edm::Handle<MuonBxCollection> muons;
event.getByToken(muonToken, muons);
for (int bx = muons->getFirstBX(); bx <= muons->getLastBX(); ++bx) {
for (auto mu = muons->begin(bx); mu != muons->end(bx); ++mu) {
objMap[bx].mus.push_back(*mu);
}
}
return std::make_pair(muons->getFirstBX(), muons->getLastBX());
}

void MuonPacker::packBx(const GMTOutputObjectMap& objMap,
const int firstMuonBx,
const int lastMuonBx,
const int firstMuonShowerBx,
const int lastMuonShowerBx,
PayloadMap& payloadMap) {
const auto firstBx{std::min(firstMuonShowerBx, firstMuonBx)};
const auto lastBx{std::max(lastMuonShowerBx, lastMuonBx)};
const auto nBx{lastBx - firstBx + 1};

unsigned int blkId = b1_;
auto mu{muons->begin(bx)};
uint32_t mu1_shared_word{0};
uint32_t mu2_shared_word{0};
uint32_t mu1_msw{0};
uint32_t mu2_msw{0};
uint32_t mu1_lsw{0};
uint32_t mu2_lsw{0};
// Slightly convoluted logic to account for the Run-3 muon readout record:
// To make space for displacement information we moved the raw
// (i.e. non-extrapolated) eta value to the second "spare" word
// in the block which we call "shared word". So the logic below
// needs to be aware if it is operating on the first or second
// muon in the block in order to place the eta value in the right
// place in the shared word. Additionally the logic needs to
// wait for the second muon in the block before filling the
// payload map because the shared word goes in first.
for (int muCtr = 1; muCtr <= 8; ++muCtr) {
if (mu != muons->end(bx)) {
MuonRawDigiTranslator::generatePackedDataWords(
*mu, mu2_shared_word, mu2_lsw, mu2_msw, fedId_, fwId_, 2 - (muCtr % 2));
++mu;
for (int bx{firstBx}; bx < lastBx; ++bx) {
// the first word in every BX and every block id is 0
for (unsigned int blkId = b1_; blkId < b1_ + 7; blkId += 2) {
payloadMap[blkId].push_back(0);
}

// If we're remaining in the current block the muon we just packed is the first one in the block.
// If not we add both muons to the payload map and go to the next block.
if (muCtr % 2 == 1) {
mu1_shared_word = mu2_shared_word;
mu1_lsw = mu2_lsw;
mu1_msw = mu2_msw;
} else {
payloadMap[blkId].push_back(mu1_shared_word | mu2_shared_word);
payloadMap[blkId].push_back(mu1_lsw);
payloadMap[blkId].push_back(mu1_msw);
payloadMap[blkId].push_back(mu2_lsw);
payloadMap[blkId].push_back(mu2_msw);
unsigned int blkId = b1_;
auto mu{objMap.at(bx).mus.begin()}; // Need to get the first muon of that bx from the object map
uint32_t mu1_shared_word{0};
uint32_t mu2_shared_word{0};
uint32_t mu1_msw{0};
uint32_t mu2_msw{0};
uint32_t mu1_lsw{0};
uint32_t mu2_lsw{0};
std::array<uint32_t, 4> showerWords{
MuonRawDigiTranslator::getPackedShowerDataWords(objMap.at(bx).shower, fedId_, fwId_)};
// Slightly convoluted logic to account for the Run-3 muon readout record:
// To make space for displacement information we moved the raw
// (i.e. non-extrapolated) eta value to the second "spare" word
// in the block which we call "shared word". So the logic below
// needs to be aware if it is operating on the first or second
// muon in the block in order to place the eta value in the right
// place in the shared word. Additionally the logic needs to
// wait for the second muon in the block before filling the
// payload map because the shared word goes in first.
for (int muCtr = 1; muCtr <= 8; ++muCtr) {
if (mu != objMap.at(bx).mus.end()) {
MuonRawDigiTranslator::generatePackedMuonDataWords(
*mu, mu2_shared_word, mu2_lsw, mu2_msw, fedId_, fwId_, 2 - (muCtr % 2));
++mu;
}

// If we're remaining in the current block the muon we just packed is the first one in the block.
// If not we add both muons to the payload map and go to the next block.
if (muCtr % 2 == 1) {
mu1_shared_word = mu2_shared_word;
mu1_lsw = mu2_lsw;
mu1_msw = mu2_msw;
mu1_msw |= showerWords.at(muCtr / 2); // Shower bits are added only to the first muon of the link.
} else {
payloadMap[blkId].push_back(mu1_shared_word | mu2_shared_word);
payloadMap[blkId].push_back(mu1_lsw);
payloadMap[blkId].push_back(mu1_msw);
payloadMap[blkId].push_back(mu2_lsw);
payloadMap[blkId].push_back(mu2_msw);

blkId += 2;
blkId += 2;

mu1_shared_word = 0;
mu1_lsw = 0;
mu1_msw = 0;
mu1_shared_word = 0;
mu1_lsw = 0;
mu1_msw = 0;
}
mu2_shared_word = 0;
mu2_lsw = 0;
mu2_msw = 0;
}
mu2_shared_word = 0;
mu2_lsw = 0;
mu2_msw = 0;
}
}
} // namespace stage2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,25 @@ namespace l1t {
inline void setFed(unsigned fedId) { fedId_ = fedId; };

private:
struct GMTObjects {
std::vector<Muon> mus;
MuonShower shower;
};
typedef std::map<size_t, GMTObjects> GMTOutputObjectMap; // Map of BX --> objects
typedef std::map<unsigned int, std::vector<uint32_t>> PayloadMap;

void packBx(PayloadMap& payloadMap, const edm::Handle<MuonBxCollection>& muons, int bx);
std::pair<int, int> getMuonShowers(GMTOutputObjectMap& objMap,
const edm::Event& event,
const edm::EDGetTokenT<MuonShowerBxCollection>& showerToken);
std::pair<int, int> getMuons(GMTOutputObjectMap& objMap,
const edm::Event& event,
const edm::EDGetTokenT<MuonBxCollection>& muonToken);
void packBx(const GMTOutputObjectMap& objMap,
int firstMuonBx,
int lastMuonBx,
int firstMuonShowerBx,
int lastMuonShowerBx,
PayloadMap& payloadMap);

unsigned fwId_{0};
unsigned fedId_{0};
Expand Down
37 changes: 21 additions & 16 deletions L1Trigger/L1TMuon/interface/MuonRawDigiTranslator.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
#define MuonRawDigiTranslator_h

#include "DataFormats/L1Trigger/interface/Muon.h"
#include "DataFormats/L1Trigger/interface/MuonShower.h"

#include <array>

namespace l1t {
class MuonRawDigiTranslator {
Expand All @@ -15,16 +18,17 @@ namespace l1t {
int muInBx);
static void fillMuon(Muon& mu, uint32_t raw_data_spare, uint64_t dataword, int fed, unsigned int fw, int muInBx);
static void fillIntermediateMuon(Muon& mu, uint32_t raw_data_00_31, uint32_t raw_data_32_63, unsigned int fw);
static void generatePackedDataWords(const Muon& mu,
uint32_t& raw_data_spare,
uint32_t& raw_data_00_31,
uint32_t& raw_data_32_63,
int fedId,
int fwId,
int muInBx);
static void generatePackedMuonDataWords(const Muon& mu,
uint32_t& raw_data_spare,
uint32_t& raw_data_00_31,
uint32_t& raw_data_32_63,
int fedId,
int fwId,
int muInBx);
static void generate64bitDataWord(
const Muon& mu, uint32_t& raw_data_spare, uint64_t& dataword, int fedId, int fwId, int muInBx);
static int calcHwEta(const uint32_t& raw, const unsigned absEtaShift, const unsigned etaSignShift);
static std::array<uint32_t, 4> getPackedShowerDataWords(const MuonShower& shower, int fedId, unsigned int fwId);
static int calcHwEta(const uint32_t& raw, unsigned absEtaShift, unsigned etaSignShift);

static constexpr unsigned ptMask_ = 0x1FF;
static constexpr unsigned ptShift_ = 10;
Expand All @@ -49,6 +53,7 @@ namespace l1t {
static constexpr unsigned ptUnconstrainedMask_ = 0xFF;
static constexpr unsigned ptUnconstrainedShift_ = 21;
static constexpr unsigned ptUnconstrainedIntermedidateShift_ = 0;
static constexpr unsigned showerShift_ = 29; // For Run-3
static constexpr unsigned absEtaMu1Shift_ = 13; // For Run-3
static constexpr unsigned etaMu1SignShift_ = 21; // For Run-3
static constexpr unsigned absEtaMu2Shift_ = 22; // For Run-3
Expand All @@ -65,14 +70,14 @@ namespace l1t {
int muInBx,
bool wasSpecialMWGR = false);
static void fillIntermediateMuonQuantitiesRun3(Muon& mu, uint32_t raw_data_00_31, uint32_t raw_data_32_63);
static void generatePackedDataWordsRun3(const Muon& mu,
int abs_eta,
int abs_eta_at_vtx,
uint32_t& raw_data_spare,
uint32_t& raw_data_00_31,
uint32_t& raw_data_32_63,
int muInBx,
bool wasSpecialMWGR = false);
static void generatePackedMuonDataWordsRun3(const Muon& mu,
int abs_eta,
int abs_eta_at_vtx,
uint32_t& raw_data_spare,
uint32_t& raw_data_00_31,
uint32_t& raw_data_32_63,
int muInBx,
bool wasSpecialMWGR = false);
};
} // namespace l1t

Expand Down
51 changes: 33 additions & 18 deletions L1Trigger/L1TMuon/src/MuonRawDigiTranslator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -177,13 +177,13 @@ void l1t::MuonRawDigiTranslator::fillIntermediateMuonQuantitiesRun3(Muon& mu,
mu.setHwPtUnconstrained((raw_data_00_31 >> ptUnconstrainedIntermedidateShift_) & ptUnconstrainedMask_);
}

void l1t::MuonRawDigiTranslator::generatePackedDataWords(const Muon& mu,
uint32_t& raw_data_spare,
uint32_t& raw_data_00_31,
uint32_t& raw_data_32_63,
const int fedID,
const int fwID,
const int muInBx) {
void l1t::MuonRawDigiTranslator::generatePackedMuonDataWords(const Muon& mu,
uint32_t& raw_data_spare,
uint32_t& raw_data_00_31,
uint32_t& raw_data_32_63,
const int fedID,
const int fwID,
const int muInBx) {
int abs_eta = mu.hwEta();
if (abs_eta < 0) {
abs_eta += (1 << (etaSignShift_ - absEtaShift_));
Expand Down Expand Up @@ -212,22 +212,22 @@ void l1t::MuonRawDigiTranslator::generatePackedDataWords(const Muon& mu,
(mu.hwPhi() & phiMask_) << phiShift_;
} else if ((fedID == 1402 && fwID == 0x6000001) ||
(fedID == 1404 && fwID < 0x1130)) { // This allows us to unpack data taken in the November 2020 MWGR.
generatePackedDataWordsRun3(
generatePackedMuonDataWordsRun3(
mu, abs_eta, abs_eta_at_vtx, raw_data_spare, raw_data_00_31, raw_data_32_63, muInBx, true);
} else {
generatePackedDataWordsRun3(
generatePackedMuonDataWordsRun3(
mu, abs_eta, abs_eta_at_vtx, raw_data_spare, raw_data_00_31, raw_data_32_63, muInBx, false);
}
}

void l1t::MuonRawDigiTranslator::generatePackedDataWordsRun3(const Muon& mu,
const int abs_eta,
const int abs_eta_at_vtx,
uint32_t& raw_data_spare,
uint32_t& raw_data_00_31,
uint32_t& raw_data_32_63,
const int muInBx,
const bool wasSpecialMWGR /*= false*/) {
void l1t::MuonRawDigiTranslator::generatePackedMuonDataWordsRun3(const Muon& mu,
const int abs_eta,
const int abs_eta_at_vtx,
uint32_t& raw_data_spare,
uint32_t& raw_data_00_31,
uint32_t& raw_data_32_63,
const int muInBx,
const bool wasSpecialMWGR /*= false*/) {
int absEtaShiftRun3{0}, etaSignShiftRun3{0};
if (muInBx == 1) {
absEtaShiftRun3 = absEtaMu1Shift_;
Expand Down Expand Up @@ -259,10 +259,25 @@ void l1t::MuonRawDigiTranslator::generate64bitDataWord(
uint32_t lsw;
uint32_t msw;

generatePackedDataWords(mu, raw_data_spare, lsw, msw, fedId, fwId, muInBx);
generatePackedMuonDataWords(mu, raw_data_spare, lsw, msw, fedId, fwId, muInBx);
dataword = (((uint64_t)msw) << 32) + lsw;
}

std::array<uint32_t, 4> l1t::MuonRawDigiTranslator::getPackedShowerDataWords(const MuonShower& shower,
const int fedId,
const unsigned int fwId) {
std::array<uint32_t, 4> res{};
if (fedId == 1402 && fwId < 0x7000000) {
return res;
} else {
res.at(0) = shower.isOneNominalInTime() ? (1 << showerShift_) : 0;
res.at(1) = shower.isOneNominalOutOfTime() ? (1 << showerShift_) : 0;
res.at(2) = shower.isTwoLooseInTime() ? (1 << showerShift_) : 0;
res.at(3) = shower.isTwoLooseOutOfTime() ? (1 << showerShift_) : 0;
}
return res;
}

int l1t::MuonRawDigiTranslator::calcHwEta(const uint32_t& raw,
const unsigned absEtaShift,
const unsigned etaSignShift) {
Expand Down

0 comments on commit 7df3854

Please sign in to comment.