diff --git a/DQM/L1TMonitor/src/L1TStage2Shower.cc b/DQM/L1TMonitor/src/L1TStage2Shower.cc
index 94fc93e959377..505bdef9fa7a6 100644
--- a/DQM/L1TMonitor/src/L1TStage2Shower.cc
+++ b/DQM/L1TMonitor/src/L1TStage2Shower.cc
@@ -166,8 +166,8 @@ void L1TStage2Shower::analyze(const edm::Event& e, const edm::EventSetup& c) {
if (not Shower.isValid())
continue;
if (Shower.isOneNominalInTime() or Shower.isTwoLooseInTime() or Shower.isOneTightInTime()) {
- int endcap = Shower.endcap();
- int sector = Shower.sector();
+ int endcap = Shower.trackFinderType() == l1t::tftype::emtf_pos ? 1 : -1;
+ int sector = Shower.processor() + 1;
if (Shower.isOneTightInTime())
emtfShowerTypeOccupancy->Fill(sector, (endcap == 1) ? 7.5 : 0.5);
if (Shower.isTwoLooseInTime())
diff --git a/DataFormats/L1TMuon/interface/RegionalMuonShower.h b/DataFormats/L1TMuon/interface/RegionalMuonShower.h
index 230dc49d12664..0e02146c8ae22 100644
--- a/DataFormats/L1TMuon/interface/RegionalMuonShower.h
+++ b/DataFormats/L1TMuon/interface/RegionalMuonShower.h
@@ -5,6 +5,8 @@
#include "DataFormats/L1Trigger/interface/BXVector.h"
#include "DataFormats/L1Trigger/interface/L1TObjComparison.h"
+#include "RegionalMuonCandFwd.h" // For tftype.
+
namespace l1t {
class RegionalMuonShower;
@@ -31,9 +33,8 @@ namespace l1t {
void setTwoLooseOutOfTime(const bool bit) { isTwoLooseOutOfTime_ = bit; }
void setTwoLooseInTime(const bool bit) { isTwoLooseInTime_ = bit; }
- void setEndcap(const int endcap) { endcap_ = endcap; }
- void setSector(const unsigned sector) { sector_ = sector; }
- void setLink(const int link) { link_ = link; };
+ /// Set the processor ID, track-finder type. From these two, the link is set
+ void setTFIdentifiers(int processor, tftype trackFinder);
bool isValid() const;
bool isOneNominalInTime() const { return isOneNominalInTime_; }
@@ -43,10 +44,12 @@ namespace l1t {
bool isTwoLooseInTime() const { return isTwoLooseInTime_; }
bool isTwoLooseOutOfTime() const { return isTwoLooseOutOfTime_; }
- int endcap() const { return endcap_; }
- int sector() const { return sector_; }
/// Get link on which the MicroGMT receives the candidate
- int link() const { return link_; }
+ const int link() const { return link_; };
+ /// Get processor ID on which the candidate was found (0..5 for OMTF/EMTF; 0..11 for BMTF)
+ const int processor() const { return processor_; };
+ /// Get track-finder which found the muon (bmtf, emtf_pos/emtf_neg or omtf_pos/omtf_neg)
+ const tftype trackFinderType() const { return trackFinder_; };
bool operator==(const l1t::RegionalMuonShower& rhs) const;
inline bool operator!=(const l1t::RegionalMuonShower& rhs) const { return !(operator==(rhs)); };
@@ -60,9 +63,9 @@ namespace l1t {
bool isOneTightOutOfTime_;
bool isTwoLooseInTime_;
bool isTwoLooseOutOfTime_;
- int endcap_; // +/-1. For ME+ and ME-.
- unsigned sector_; // 1 - 6.
int link_;
+ int processor_;
+ tftype trackFinder_;
};
} // namespace l1t
diff --git a/DataFormats/L1TMuon/src/RegionalMuonShower.cc b/DataFormats/L1TMuon/src/RegionalMuonShower.cc
index ce73da8584331..ba4c68832686b 100644
--- a/DataFormats/L1TMuon/src/RegionalMuonShower.cc
+++ b/DataFormats/L1TMuon/src/RegionalMuonShower.cc
@@ -12,12 +12,33 @@ l1t::RegionalMuonShower::RegionalMuonShower(bool oneNominalInTime,
isOneTightOutOfTime_(oneTightOutOfTime),
isTwoLooseInTime_(twoLooseInTime),
isTwoLooseOutOfTime_(twoLooseOutOfTime),
- endcap_(0),
- sector_(0),
- link_(0) {}
+ link_(0),
+ processor_(0) {}
l1t::RegionalMuonShower::~RegionalMuonShower() {}
+void l1t::RegionalMuonShower::setTFIdentifiers(int processor, tftype trackFinder) {
+ trackFinder_ = trackFinder;
+ processor_ = processor;
+
+ switch (trackFinder_) {
+ case tftype::emtf_pos:
+ link_ = processor_ + 36; // range 36...41
+ break;
+ case tftype::omtf_pos:
+ link_ = processor_ + 42; // range 42...47
+ break;
+ case tftype::bmtf:
+ link_ = processor_ + 48; // range 48...59
+ break;
+ case tftype::omtf_neg:
+ link_ = processor_ + 60; // range 60...65
+ break;
+ case tftype::emtf_neg:
+ link_ = processor_ + 66; // range 66...71
+ }
+}
+
bool l1t::RegionalMuonShower::isValid() const {
return (isOneNominalInTime_ or isTwoLooseInTime_ or isOneTightInTime_);
}
diff --git a/DataFormats/L1TMuon/src/classes_def.xml b/DataFormats/L1TMuon/src/classes_def.xml
index d045b4388ab55..07cb26f030624 100644
--- a/DataFormats/L1TMuon/src/classes_def.xml
+++ b/DataFormats/L1TMuon/src/classes_def.xml
@@ -13,7 +13,8 @@
-
+
+
diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/CommonTokens.h b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/CommonTokens.h
index 5e10377235b2a..a78e7323ad3d3 100644
--- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/CommonTokens.h
+++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/CommonTokens.h
@@ -6,6 +6,7 @@
#include "DataFormats/L1Trigger/interface/Jet.h"
#include "DataFormats/L1Trigger/interface/Tau.h"
#include "DataFormats/L1Trigger/interface/Muon.h"
+#include "DataFormats/L1Trigger/interface/MuonShower.h"
#include "FWCore/Utilities/interface/EDGetToken.h"
#include "EventFilter/L1TRawToDigi/interface/PackerTokens.h"
@@ -19,6 +20,7 @@ namespace l1t {
inline const edm::EDGetTokenT& getJetToken() const { return jetToken_; };
inline const edm::EDGetTokenT& getTauToken() const { return tauToken_; };
inline const edm::EDGetTokenT& getMuonToken() const { return muonToken_; };
+ inline const edm::EDGetTokenT& getMuonShowerToken() const { return muonShowerToken_; };
protected:
edm::EDGetTokenT egammaToken_;
@@ -26,6 +28,7 @@ namespace l1t {
edm::EDGetTokenT jetToken_;
edm::EDGetTokenT tauToken_;
edm::EDGetTokenT muonToken_;
+ edm::EDGetTokenT muonShowerToken_;
};
} // namespace stage2
} // namespace l1t
diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTCollections.cc b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTCollections.cc
index 6ba0a8ebcb1d9..8f998e86820a7 100644
--- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTCollections.cc
+++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTCollections.cc
@@ -11,7 +11,7 @@ namespace l1t {
event_.put(std::move(regionalMuonCandsOMTF_), "OMTF");
event_.put(std::move(regionalMuonCandsEMTF_), "EMTF");
event_.put(std::move(muons_[0]), "Muon");
- for (int i = 1; i < 6; ++i) {
+ for (size_t i = 1; i < NUM_OUTPUT_COPIES; ++i) {
event_.put(std::move(muons_[i]), "MuonCopy" + std::to_string(i));
}
event_.put(std::move(imdMuonsBMTF_), "imdMuonsBMTF");
@@ -19,6 +19,12 @@ namespace l1t {
event_.put(std::move(imdMuonsEMTFPos_), "imdMuonsEMTFPos");
event_.put(std::move(imdMuonsOMTFNeg_), "imdMuonsOMTFNeg");
event_.put(std::move(imdMuonsOMTFPos_), "imdMuonsOMTFPos");
+
+ event_.put(std::move(regionalMuonShowersEMTF_), "EMTF");
+ event_.put(std::move(muonShowers_[0]), "MuonShower");
+ for (size_t i = 1; i < NUM_OUTPUT_COPIES; ++i) {
+ event_.put(std::move(muonShowers_[i]), "MuonShowerCopy" + std::to_string(i));
+ }
}
} // namespace stage2
} // namespace l1t
diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTCollections.h b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTCollections.h
index 281b2ba92a2a8..a02b15d107cc7 100644
--- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTCollections.h
+++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTCollections.h
@@ -4,6 +4,9 @@
#include "DataFormats/L1TMuon/interface/RegionalMuonCand.h"
#include "DataFormats/L1Trigger/interface/Muon.h"
+#include "DataFormats/L1TMuon/interface/RegionalMuonShower.h"
+#include "DataFormats/L1Trigger/interface/MuonShower.h"
+
#include "L1TObjectCollections.h"
#include
@@ -27,10 +30,16 @@ namespace l1t {
imdMuonsEMTFNeg_(std::make_unique(0, oFirstBx, oLastBx)),
imdMuonsEMTFPos_(std::make_unique(0, oFirstBx, oLastBx)),
imdMuonsOMTFNeg_(std::make_unique(0, oFirstBx, oLastBx)),
- imdMuonsOMTFPos_(std::make_unique(0, oFirstBx, oLastBx)) {
+ imdMuonsOMTFPos_(std::make_unique(0, oFirstBx, oLastBx)),
+
+ regionalMuonShowersEMTF_(std::make_unique(0, iFirstBx, iLastBx)),
+ muonShowers_() {
std::generate(muons_.begin(), muons_.end(), [&oFirstBx, &oLastBx] {
return std::make_unique(0, oFirstBx, oLastBx);
});
+ std::generate(muonShowers_.begin(), muonShowers_.end(), [&oFirstBx, &oLastBx] {
+ return std::make_unique(0, oFirstBx, oLastBx);
+ });
};
~GMTCollections() override;
@@ -45,6 +54,13 @@ namespace l1t {
inline MuonBxCollection* getImdMuonsOMTFNeg() { return imdMuonsOMTFNeg_.get(); };
inline MuonBxCollection* getImdMuonsOMTFPos() { return imdMuonsOMTFPos_.get(); };
+ inline RegionalMuonShowerBxCollection* getRegionalMuonShowersEMTF() { return regionalMuonShowersEMTF_.get(); };
+ inline MuonShowerBxCollection* getMuonShowers(const unsigned int copy) override {
+ return muonShowers_[copy].get();
+ };
+
+ static constexpr size_t NUM_OUTPUT_COPIES{6};
+
private:
std::unique_ptr regionalMuonCandsBMTF_;
std::unique_ptr regionalMuonCandsOMTF_;
@@ -55,6 +71,9 @@ namespace l1t {
std::unique_ptr imdMuonsEMTFPos_;
std::unique_ptr imdMuonsOMTFNeg_;
std::unique_ptr imdMuonsOMTFPos_;
+
+ std::unique_ptr regionalMuonShowersEMTF_;
+ std::array, 6> muonShowers_;
};
} // namespace stage2
} // namespace l1t
diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTSetup.cc b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTSetup.cc
index c4508e7763388..c0846fcddc101 100644
--- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTSetup.cc
+++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTSetup.cc
@@ -5,11 +5,11 @@
#include "EventFilter/L1TRawToDigi/plugins/PackingSetupFactory.h"
#include "EventFilter/L1TRawToDigi/plugins/UnpackerFactory.h"
-#include "EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTUnpacker.h"
#include "EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTPacker.h"
+#include "EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTUnpacker.h"
#include "EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonPacker.h"
-#include "EventFilter/L1TRawToDigi/plugins/implementations_stage2/IntermediateMuonUnpacker.h"
#include "EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonUnpacker.h"
+#include "EventFilter/L1TRawToDigi/plugins/implementations_stage2/IntermediateMuonUnpacker.h"
#include "GMTSetup.h"
@@ -36,6 +36,8 @@ namespace l1t {
->setComment("uGMT intermediate muon from neg. OMTF side after first sorting stage");
desc.addOptional("ImdInputLabelOMTFPos")
->setComment("uGMT intermediate muon from pos. OMTF side after first sorting stage");
+ desc.addOptional("ShowerInputLabel")->setComment("for Run3");
+ desc.addOptional("EMTFShowerInputLabel")->setComment("for Run3");
}
PackerMap GMTSetup::getPackers(int fed, unsigned int fw) {
@@ -43,6 +45,9 @@ namespace l1t {
if (fed == 1402) {
auto gmt_in_packer = static_pointer_cast(
PackerFactory::get()->make("stage2::RegionalMuonGMTPacker"));
+ if (fw >= 0x7000000) {
+ gmt_in_packer->setUseEmtfShowers();
+ }
if (fw >= 0x6010000) {
gmt_in_packer->setUseEmtfDisplacementInfo();
}
@@ -68,7 +73,7 @@ namespace l1t {
prod.produces("OMTF");
prod.produces("EMTF");
prod.produces("Muon");
- for (int i = 1; i < 6; ++i) {
+ for (size_t i = 1; i < GMTCollections::NUM_OUTPUT_COPIES; ++i) {
prod.produces("MuonCopy" + std::to_string(i));
}
prod.produces("imdMuonsBMTF");
@@ -76,6 +81,12 @@ namespace l1t {
prod.produces("imdMuonsEMTFPos");
prod.produces("imdMuonsOMTFNeg");
prod.produces("imdMuonsOMTFPos");
+
+ prod.produces("EMTF");
+ prod.produces("MuonShower");
+ for (size_t i = 1; i < GMTCollections::NUM_OUTPUT_COPIES; ++i) {
+ prod.produces("MuonShowerCopy" + std::to_string(i));
+ }
}
std::unique_ptr GMTSetup::getCollections(edm::Event& e) {
@@ -89,6 +100,9 @@ namespace l1t {
// input muons on links 36-71
auto gmt_in_unp = static_pointer_cast(
UnpackerFactory::get()->make("stage2::RegionalMuonGMTUnpacker"));
+ if (fw >= 0x7000000) {
+ gmt_in_unp->setUseEmtfShowers();
+ }
if (fw >= 0x6010000) {
gmt_in_unp->setUseEmtfDisplacementInfo();
}
diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTTokens.cc b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTTokens.cc
index 39269759ccd0b..2c992a9742c8a 100644
--- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTTokens.cc
+++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTTokens.cc
@@ -26,6 +26,12 @@ namespace l1t {
imdMuonTokenEMTFPos_ = cc.consumes(imdEmtfPosTag);
imdMuonTokenOMTFNeg_ = cc.consumes(imdOmtfNegTag);
imdMuonTokenOMTFPos_ = cc.consumes(imdOmtfPosTag);
+
+ auto emtfShowerTag = cfg.getParameter("EMTFShowerInputLabel");
+ auto showerTag = cfg.getParameter("ShowerInputLabel");
+
+ regionalMuonShowerTokenEMTF_ = cc.consumes(emtfShowerTag);
+ muonShowerToken_ = cc.consumes(showerTag);
}
} // namespace stage2
} // namespace l1t
diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTTokens.h b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTTokens.h
index 9838e11fed804..6089529a9d47d 100644
--- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTTokens.h
+++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTTokens.h
@@ -2,6 +2,7 @@
#define GMTTokens_h
#include "DataFormats/L1TMuon/interface/RegionalMuonCand.h"
+#include "DataFormats/L1TMuon/interface/RegionalMuonShower.h"
#include "DataFormats/L1Trigger/interface/Muon.h"
#include "CommonTokens.h"
@@ -27,6 +28,10 @@ namespace l1t {
inline const edm::EDGetTokenT& getImdMuonTokenOMTFNeg() const { return imdMuonTokenOMTFNeg_; };
inline const edm::EDGetTokenT& getImdMuonTokenOMTFPos() const { return imdMuonTokenOMTFPos_; };
+ inline const edm::EDGetTokenT& getRegionalMuonShowerTokenEMTF() const {
+ return regionalMuonShowerTokenEMTF_;
+ };
+
private:
edm::EDGetTokenT regionalMuonCandTokenBMTF_;
edm::EDGetTokenT regionalMuonCandTokenOMTF_;
@@ -36,6 +41,8 @@ namespace l1t {
edm::EDGetTokenT imdMuonTokenEMTFPos_;
edm::EDGetTokenT imdMuonTokenOMTFNeg_;
edm::EDGetTokenT imdMuonTokenOMTFPos_;
+
+ edm::EDGetTokenT regionalMuonShowerTokenEMTF_;
};
} // namespace stage2
} // namespace l1t
diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/L1TObjectCollections.h b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/L1TObjectCollections.h
index f543f9ce0ff98..1650face93738 100644
--- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/L1TObjectCollections.h
+++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/L1TObjectCollections.h
@@ -6,6 +6,7 @@
#include "DataFormats/L1Trigger/interface/Jet.h"
#include "DataFormats/L1Trigger/interface/Tau.h"
#include "DataFormats/L1Trigger/interface/Muon.h"
+#include "DataFormats/L1Trigger/interface/MuonShower.h"
#include "DataFormats/EcalDigi/interface/EcalDigiCollections.h"
@@ -19,6 +20,7 @@ namespace l1t {
~L1TObjectCollections() override;
virtual MuonBxCollection* getMuons(const unsigned int copy) { return nullptr; }
+ virtual MuonShowerBxCollection* getMuonShowers(const unsigned int copy) { return nullptr; }
virtual EGammaBxCollection* getEGammas(const unsigned int copy) { return nullptr; } //= 0;
virtual EtSumBxCollection* getEtSums(const unsigned int copy) { return nullptr; }
virtual JetBxCollection* getJets(const unsigned int copy) { return nullptr; }
diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonPacker.cc b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonPacker.cc
index f2d62ae8f8470..25c949d9b4c9f 100644
--- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonPacker.cc
+++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonPacker.cc
@@ -6,14 +6,16 @@
namespace l1t {
namespace stage2 {
Blocks MuonPacker::pack(const edm::Event& event, const PackerTokens* toks) {
- edm::Handle muons;
- event.getByToken(static_cast(toks)->getMuonToken(), muons);
+ GMTOutputObjectMap gmtObjMap;
+ std::pair muonBx = getMuons(gmtObjMap, event, static_cast(toks)->getMuonToken());
+ std::pair muonShowerBx{0, 0};
+ if (fedId_ == 1402 && fwId_ >= 0x7000000) {
+ muonShowerBx = getMuonShowers(gmtObjMap, event, static_cast(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
@@ -23,58 +25,98 @@ namespace l1t {
return blocks;
}
- void MuonPacker::packBx(PayloadMap& payloadMap, const edm::Handle& 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 MuonPacker::getMuonShowers(GMTOutputObjectMap& objMap,
+ const edm::Event& event,
+ const edm::EDGetTokenT& showerToken) {
+ edm::Handle 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 MuonPacker::getMuons(GMTOutputObjectMap& objMap,
+ const edm::Event& event,
+ const edm::EDGetTokenT& muonToken) {
+ edm::Handle muons;
+ event.getByToken(muonToken, muons);
+ for (int bx = muons->getFirstBX(); bx <= muons->getLastBX(); ++bx) {
+ objMap[bx] = GMTObjects();
+ 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)};
- 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 + 1; ++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_;
+ 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};
+ auto mu{objMap.at(bx).mus.begin()}; // Need to get the first muon of that bx from the object map
+ std::array 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
diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonPacker.h b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonPacker.h
index 7cb46c12845bb..fe7be55e6421d 100644
--- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonPacker.h
+++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonPacker.h
@@ -18,9 +18,25 @@ namespace l1t {
inline void setFed(unsigned fedId) { fedId_ = fedId; };
private:
+ struct GMTObjects {
+ std::vector mus;
+ MuonShower shower;
+ };
+ typedef std::map GMTOutputObjectMap; // Map of BX --> objects
typedef std::map> PayloadMap;
- void packBx(PayloadMap& payloadMap, const edm::Handle& muons, int bx);
+ std::pair getMuonShowers(GMTOutputObjectMap& objMap,
+ const edm::Event& event,
+ const edm::EDGetTokenT& showerToken);
+ std::pair getMuons(GMTOutputObjectMap& objMap,
+ const edm::Event& event,
+ const edm::EDGetTokenT& muonToken);
+ void packBx(const GMTOutputObjectMap& objMap,
+ int firstMuonBx,
+ int lastMuonBx,
+ int firstMuonShowerBx,
+ int lastMuonShowerBx,
+ PayloadMap& payloadMap);
unsigned fwId_{0};
unsigned fedId_{0};
diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTPacker.cc b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTPacker.cc
index 36301c3037568..281edd581d460 100644
--- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTPacker.cc
+++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTPacker.cc
@@ -1,3 +1,4 @@
+#include "FWCore/MessageLogger/interface/MessageLogger.h"
#include "FWCore/Framework/interface/Event.h"
#include "EventFilter/L1TRawToDigi/plugins/PackerFactory.h"
@@ -8,62 +9,121 @@
namespace l1t {
namespace stage2 {
Blocks RegionalMuonGMTPacker::pack(const edm::Event& event, const PackerTokens* toks) {
+ GMTObjectMap bmtfObjMap;
+ GMTObjectMap omtfObjMap;
+ GMTObjectMap emtfObjMap;
auto bmtfToken = static_cast(toks)->getRegionalMuonCandTokenBMTF();
auto omtfToken = static_cast(toks)->getRegionalMuonCandTokenOMTF();
auto emtfToken = static_cast(toks)->getRegionalMuonCandTokenEMTF();
+ // First we put the muons in our object map.
+ std::pair bmtfMuonBx = getMuons(bmtfObjMap, event, bmtfToken);
+ std::pair omtfMuonBx = getMuons(omtfObjMap, event, omtfToken);
+ std::pair emtfMuonBx = getMuons(emtfObjMap, event, emtfToken);
+
+ // Then the showers (We don't expect to have shower data from BMTF and OMTF -- at the moment, at least)
+ std::pair emtfMuonShowerBx{0, 0};
+ if (useEmtfShowers_) {
+ auto emtfShowerToken = static_cast(toks)->getRegionalMuonShowerTokenEMTF();
+ emtfMuonShowerBx = getMuonShowers(emtfObjMap, event, emtfShowerToken);
+ }
+
Blocks blocks;
- // pack the muons for each TF in blocks
- packTF(event, bmtfToken, blocks);
- packTF(event, omtfToken, blocks);
- packTF(event, emtfToken, blocks);
+ // Pack the muons and showers for each TF in blocks
+ packTF(bmtfObjMap, bmtfMuonBx.first, bmtfMuonBx.second, 0, 0, blocks);
+ packTF(omtfObjMap, omtfMuonBx.first, omtfMuonBx.second, 0, 0, blocks);
+ packTF(emtfObjMap, emtfMuonBx.first, emtfMuonBx.second, emtfMuonShowerBx.first, emtfMuonShowerBx.second, blocks);
return blocks;
}
- void RegionalMuonGMTPacker::packTF(const edm::Event& event,
- const edm::EDGetTokenT& tfToken,
- Blocks& blocks) {
+ std::pair RegionalMuonGMTPacker::getMuonShowers(
+ GMTObjectMap& objMap,
+ const edm::Event& event,
+ const edm::EDGetTokenT& tfShowerToken) {
+ edm::Handle muonShowers;
+ event.getByToken(tfShowerToken, muonShowers);
+ for (int bx = muonShowers->getFirstBX(); bx <= muonShowers->getLastBX(); ++bx) {
+ for (auto muShower = muonShowers->begin(bx); muShower != muonShowers->end(bx); ++muShower) {
+ objMap[bx][muShower->link()].shower = *muShower;
+ }
+ }
+ return std::make_pair(muonShowers->getFirstBX(), muonShowers->getLastBX());
+ }
+
+ std::pair RegionalMuonGMTPacker::getMuons(GMTObjectMap& objMap,
+ const edm::Event& event,
+ const edm::EDGetTokenT& tfToken) {
edm::Handle muons;
event.getByToken(tfToken, muons);
+ for (int bx = muons->getFirstBX(); bx <= muons->getLastBX(); ++bx) {
+ for (auto mu = muons->begin(bx); mu != muons->end(bx); ++mu) {
+ objMap[bx][mu->link()].mus.push_back(*mu);
+ }
+ }
+ return std::make_pair(muons->getFirstBX(), muons->getLastBX());
+ }
- constexpr unsigned wordsPerBx = 6; // number of 32 bit words per BX
+ void RegionalMuonGMTPacker::packTF(const GMTObjectMap& objMap,
+ const int firstMuonBx,
+ const int lastMuonBx,
+ const int firstMuonShowerBx,
+ const int lastMuonShowerBx,
+ Blocks& blocks) {
+ const auto firstBx{std::min(firstMuonShowerBx, firstMuonBx)};
+ const auto lastBx{std::max(lastMuonShowerBx, lastMuonBx)};
+ const auto nBx{lastBx - firstBx + 1};
PayloadMap payloadMap;
- const auto nBx = muons->getLastBX() - muons->getFirstBX() + 1;
unsigned bxCtr = 0;
- for (int i = muons->getFirstBX(); i <= muons->getLastBX(); ++i, ++bxCtr) {
- for (auto mu = muons->begin(i); mu != muons->end(i); ++mu) {
- const auto linkTimes2 = mu->link() * 2;
-
- // If the map key is new reserve the payload size.
- if (payloadMap.count(linkTimes2) == 0) {
- payloadMap[linkTimes2].reserve(wordsPerBx * nBx);
- // If there was no muon on the link of this muon in previous
- // BX the payload up to this BX must be filled with zeros.
- if (bxCtr > 0) {
- while (payloadMap[linkTimes2].size() < bxCtr * wordsPerBx) {
- payloadMap[linkTimes2].push_back(0);
+ for (int bx{firstBx}; bx < lastBx + 1; ++bx, ++bxCtr) {
+ if (objMap.count(bx) > 0) {
+ for (const auto& linkMap : objMap.at(bx)) {
+ const auto linkTimes2{linkMap.first * 2};
+ const auto gmtObjects{linkMap.second};
+
+ // If the payload map key is new reserve the payload size.
+ if (payloadMap.count(linkTimes2) == 0) {
+ payloadMap[linkTimes2].reserve(wordsPerBx_ * nBx);
+ // If there was no muon on the link of this muon in previous
+ // BX the payload up to this BX must be filled with zeros.
+ if (bxCtr > 0) {
+ while (payloadMap[linkTimes2].size() < bxCtr * wordsPerBx_) {
+ payloadMap[linkTimes2].push_back(0);
+ }
}
}
- }
- // Fill the muon in the payload for this link.
- uint32_t msw = 0;
- uint32_t lsw = 0;
+ if (gmtObjects.mus.size() > 3) {
+ edm::LogError("L1T") << "Muon collection for link " << linkMap.first << " has " << gmtObjects.mus.size()
+ << " entries, but 3 is the maximum!";
+ }
- RegionalMuonRawDigiTranslator::generatePackedDataWords(*mu, lsw, msw, isKbmtf_, useEmtfDisplacementInfo_);
+ std::array buf{}; // Making sure contents of buf are initialised to 0.
+ size_t frameIdx{0};
+ for (const auto& mu : gmtObjects.mus) {
+ // Fill the muon in the payload for this link.
+ uint32_t msw{0};
+ uint32_t lsw{0};
- payloadMap[linkTimes2].push_back(lsw);
- payloadMap[linkTimes2].push_back(msw);
- }
+ RegionalMuonRawDigiTranslator::generatePackedDataWords(mu, lsw, msw, isKbmtf_, useEmtfDisplacementInfo_);
- // padding to 3 muons per block id (link) per BX
- // This can be empty muons as well.
+ buf.at(frameIdx++) = lsw;
+ buf.at(frameIdx++) = msw;
+ }
+ // Add shower bits to the payload buffer.
+ RegionalMuonRawDigiTranslator::generatePackedShowerPayload(gmtObjects.shower, buf, useEmtfShowers_);
+
+ payloadMap[linkTimes2].insert(
+ payloadMap[linkTimes2].end(), std::move_iterator(buf.begin()), std::move_iterator(buf.end()));
+ }
+ }
+ // We now loop over all channels in the payload map and make sure that they are filled up to the current BX
+ // If they are not, we fill them with zeros
for (auto& kv : payloadMap) {
- while (kv.second.size() < (bxCtr + 1) * wordsPerBx) {
+ while (kv.second.size() < (bxCtr + 1) * wordsPerBx_) {
kv.second.push_back(0);
}
}
@@ -74,6 +134,7 @@ namespace l1t {
blocks.push_back(Block(kv.first, kv.second));
}
}
+
} // namespace stage2
} // namespace l1t
diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTPacker.h b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTPacker.h
index e3feb1bce562b..fa356b1812256 100644
--- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTPacker.h
+++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTPacker.h
@@ -6,6 +6,7 @@
#include "EventFilter/L1TRawToDigi/interface/PackerTokens.h"
#include "EventFilter/L1TRawToDigi/interface/Block.h"
#include "DataFormats/L1TMuon/interface/RegionalMuonCand.h"
+#include "DataFormats/L1TMuon/interface/RegionalMuonShower.h"
#include "FWCore/Framework/interface/Event.h"
namespace l1t {
@@ -15,13 +16,33 @@ namespace l1t {
Blocks pack(const edm::Event&, const PackerTokens*) override;
void setIsKbmtf() { isKbmtf_ = true; };
void setUseEmtfDisplacementInfo() { useEmtfDisplacementInfo_ = true; };
+ void setUseEmtfShowers() { useEmtfShowers_ = true; };
private:
+ struct GMTObjects {
+ std::vector mus;
+ RegionalMuonShower shower;
+ };
+ typedef std::map> GMTObjectMap; // Map of BX --> linkID --> objects
typedef std::map> PayloadMap;
- void packTF(const edm::Event&, const edm::EDGetTokenT&, Blocks&);
+ void packTF(const GMTObjectMap& objMap,
+ int firstMuonBx,
+ int lastMuonBx,
+ int firstMuonShowerBx,
+ int lastMuonShowerBx,
+ Blocks&);
+ std::pair getMuons(GMTObjectMap& objMap,
+ const edm::Event& event,
+ const edm::EDGetTokenT& tfToken);
+ std::pair getMuonShowers(GMTObjectMap& objMap,
+ const edm::Event& event,
+ const edm::EDGetTokenT& tfShowerToken);
+
+ static constexpr size_t wordsPerBx_ = 6; // number of 32 bit words per BX
bool isKbmtf_{false};
bool useEmtfDisplacementInfo_{false};
+ bool useEmtfShowers_{false};
};
} // namespace stage2
} // namespace l1t
diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTUnpacker.cc b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTUnpacker.cc
index 57a603a82294e..7f498ef48abe4 100644
--- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTUnpacker.cc
+++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTUnpacker.cc
@@ -33,14 +33,19 @@ namespace l1t {
// decide which collection to use according to the link ID
unsigned int linkId = blockId / 2;
int processor;
- RegionalMuonCandBxCollection* res;
+ RegionalMuonCandBxCollection* regionalMuonCollection;
+ RegionalMuonShowerBxCollection* regionalMuonShowerCollection;
tftype trackFinder;
if (linkId > 47 && linkId < 60) {
- res = static_cast(coll)->getRegionalMuonCandsBMTF();
+ regionalMuonCollection = static_cast(coll)->getRegionalMuonCandsBMTF();
+ regionalMuonShowerCollection =
+ new RegionalMuonShowerBxCollection(); // To avoid warning re uninitialised collection
trackFinder = tftype::bmtf;
processor = linkId - 48;
} else if (linkId > 41 && linkId < 66) {
- res = static_cast(coll)->getRegionalMuonCandsOMTF();
+ regionalMuonCollection = static_cast(coll)->getRegionalMuonCandsOMTF();
+ regionalMuonShowerCollection =
+ new RegionalMuonShowerBxCollection(); // To avoid warning re uninitialised collection
if (linkId < 48) {
trackFinder = tftype::omtf_pos;
processor = linkId - 42;
@@ -49,7 +54,8 @@ namespace l1t {
processor = linkId - 60;
}
} else if (linkId > 35 && linkId < 72) {
- res = static_cast(coll)->getRegionalMuonCandsEMTF();
+ regionalMuonCollection = static_cast(coll)->getRegionalMuonCandsEMTF();
+ regionalMuonShowerCollection = static_cast(coll)->getRegionalMuonShowersEMTF();
if (linkId < 42) {
trackFinder = tftype::emtf_pos;
processor = linkId - 36;
@@ -61,7 +67,8 @@ namespace l1t {
edm::LogError("L1T") << "No TF muon expected for link " << linkId;
return false;
}
- res->setBXRange(firstBX, lastBX);
+ regionalMuonCollection->setBXRange(firstBX, lastBX);
+ regionalMuonShowerCollection->setBXRange(firstBX, lastBX);
LogDebug("L1T") << "nBX = " << nBX << " first BX = " << firstBX << " lastBX = " << lastBX;
@@ -108,7 +115,13 @@ namespace l1t {
<< mu.hwPt() << " qual " << mu.hwQual() << " sign " << mu.hwSign() << " sign valid "
<< mu.hwSignValid() << " unconstrained pT " << mu.hwPtUnconstrained();
- res->push_back(bx, mu);
+ regionalMuonCollection->push_back(bx, mu);
+ }
+ // Fill RegionalMuonShower objects. For this we need to look at all six words together.
+ RegionalMuonShower muShower;
+ if (RegionalMuonRawDigiTranslator::fillRegionalMuonShower(
+ muShower, bxPayload, processor, trackFinder, useEmtfShowers_)) {
+ regionalMuonShowerCollection->push_back(bx, muShower);
}
} else {
unsigned int nWords =
diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTUnpacker.h b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTUnpacker.h
index f991d1cffdca1..53bf86047dddb 100644
--- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTUnpacker.h
+++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTUnpacker.h
@@ -12,6 +12,7 @@ namespace l1t {
bool unpack(const Block& block, UnpackerCollections* coll) override;
void setIsKbmtf() { isKbmtf_ = true; }
void setUseEmtfDisplacementInfo() { useEmtfDisplacementInfo_ = true; }
+ void setUseEmtfShowers() { useEmtfShowers_ = true; }
private:
static constexpr unsigned nWords_ = 6; // every link transmits 6 words (3 muons) per bx
@@ -19,6 +20,7 @@ namespace l1t {
bool isKbmtf_{false};
bool useEmtfDisplacementInfo_{false};
+ bool useEmtfShowers_{false};
};
} // namespace stage2
} // namespace l1t
diff --git a/EventFilter/L1TRawToDigi/python/gmtStage2Raw_cfi.py b/EventFilter/L1TRawToDigi/python/gmtStage2Raw_cfi.py
index eb031df1e82fd..d581e48f957e5 100644
--- a/EventFilter/L1TRawToDigi/python/gmtStage2Raw_cfi.py
+++ b/EventFilter/L1TRawToDigi/python/gmtStage2Raw_cfi.py
@@ -12,6 +12,8 @@
ImdInputLabelEMTFPos = cms.InputTag("simGmtStage2Digis", "imdMuonsEMTFPos"),
ImdInputLabelOMTFNeg = cms.InputTag("simGmtStage2Digis", "imdMuonsOMTFNeg"),
ImdInputLabelOMTFPos = cms.InputTag("simGmtStage2Digis", "imdMuonsOMTFPos"),
+ EMTFShowerInputLabel = cms.InputTag("simEmtfShowers", "EMTF"),
+ ShowerInputLabel = cms.InputTag("simGmtShowerDigis"),
FedId = cms.int32(1402),
FWId = cms.uint32(0x3000000), # First used uGMT firmware version
lenSlinkHeader = cms.untracked.int32(8),
@@ -32,4 +34,4 @@
### Era: Run3_2021
from Configuration.Eras.Modifier_stage2L1Trigger_2021_cff import stage2L1Trigger_2021
-stage2L1Trigger_2021.toModify(gmtStage2Raw, BMTFInputLabel = cms.InputTag("simKBmtfDigis", "BMTF"), FWId = cms.uint32(0x6010000))
+stage2L1Trigger_2021.toModify(gmtStage2Raw, BMTFInputLabel = cms.InputTag("simKBmtfDigis", "BMTF"), FWId = cms.uint32(0x7000000))
diff --git a/L1Trigger/L1TMuon/interface/MuonRawDigiTranslator.h b/L1Trigger/L1TMuon/interface/MuonRawDigiTranslator.h
index cd4ee201a89a6..ab7a387019000 100644
--- a/L1Trigger/L1TMuon/interface/MuonRawDigiTranslator.h
+++ b/L1Trigger/L1TMuon/interface/MuonRawDigiTranslator.h
@@ -2,6 +2,9 @@
#define MuonRawDigiTranslator_h
#include "DataFormats/L1Trigger/interface/Muon.h"
+#include "DataFormats/L1Trigger/interface/MuonShower.h"
+
+#include
namespace l1t {
class MuonRawDigiTranslator {
@@ -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 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;
@@ -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
@@ -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
diff --git a/L1Trigger/L1TMuon/interface/RegionalMuonRawDigiTranslator.h b/L1Trigger/L1TMuon/interface/RegionalMuonRawDigiTranslator.h
index 3032b3971a240..5336d34903503 100644
--- a/L1Trigger/L1TMuon/interface/RegionalMuonRawDigiTranslator.h
+++ b/L1Trigger/L1TMuon/interface/RegionalMuonRawDigiTranslator.h
@@ -2,6 +2,7 @@
#define RegionalMuonRawDigiTranslator_h
#include "DataFormats/L1TMuon/interface/RegionalMuonCand.h"
+#include "DataFormats/L1TMuon/interface/RegionalMuonShower.h"
namespace l1t {
class RegionalMuonRawDigiTranslator {
@@ -15,11 +16,16 @@ namespace l1t {
bool useEmtfDisplacementInfo);
static void fillRegionalMuonCand(
RegionalMuonCand& mu, uint64_t dataword, int proc, tftype tf, bool isKbmtf, bool useEmtfDisplacementInfo);
+ static bool fillRegionalMuonShower(
+ RegionalMuonShower& muShower, std::vector bxPayload, int proc, tftype tf, bool useEmtfShowers);
static void generatePackedDataWords(const RegionalMuonCand& mu,
uint32_t& raw_data_00_31,
uint32_t& raw_data_32_63,
bool isKbmtf,
bool useEmtfDisplacementInfo);
+ static void generatePackedShowerPayload(const RegionalMuonShower& shower,
+ std::array& payload,
+ bool useEmtfShowers);
static uint64_t generate64bitDataWord(const RegionalMuonCand& mu, bool isKbmtf, bool useEmtfDisplacementInfo);
static int generateRawTrkAddress(const RegionalMuonCand&, bool isKalman);
@@ -45,6 +51,15 @@ namespace l1t {
static constexpr unsigned emtfPtUnconstrainedShift_ = 20;
static constexpr unsigned trackAddressMask_ = 0x1FFFFFFF;
static constexpr unsigned trackAddressShift_ = 2;
+ static constexpr unsigned emtfShowerOneNominalFrame_ = 0;
+ static constexpr unsigned emtfShowerOneNominalMask_ = 0x3;
+ static constexpr unsigned emtfShowerOneNominalInTimeShift_ = 18;
+ static constexpr unsigned emtfShowerOneNominalOutOfTimeShift_ = 19;
+ static constexpr unsigned emtfShowerTwoLooseFrame_ = 2;
+ static constexpr unsigned emtfShowerTwoLooseMask_ = 0x3;
+ static constexpr unsigned emtfShowerTwoLooseInTimeShift_ = 18;
+ static constexpr unsigned emtfShowerTwoLooseOutOfTimeShift_ = 19;
+
// relative shifts within track address
static constexpr unsigned bmtfTrAddrSegSelMask_ = 0xF;
static constexpr unsigned bmtfTrAddrSegSelShift_ = 21;
diff --git a/L1Trigger/L1TMuon/python/simDigis_cff.py b/L1Trigger/L1TMuon/python/simDigis_cff.py
index 134a832412a95..521660d4717fd 100644
--- a/L1Trigger/L1TMuon/python/simDigis_cff.py
+++ b/L1Trigger/L1TMuon/python/simDigis_cff.py
@@ -108,7 +108,7 @@
from L1Trigger.L1TMuonBarrel.simKBmtfStubs_cfi import *
from L1Trigger.L1TMuonBarrel.simKBmtfDigis_cfi import *
from Configuration.Eras.Modifier_phase2_trigger_cff import phase2_trigger
-phase2_trigger.toReplaceWith(SimL1TMuonTask, cms.Task(SimL1TMuonCommonTask, simTwinMuxDigis, simBmtfDigis, simKBmtfStubs, simKBmtfDigis, simEmtfDigis, simOmtfDigis, simGmtCaloSumDigis, simGmtStage2Digis))
+phase2_trigger.toReplaceWith(SimL1TMuonTask, cms.Task(SimL1TMuonCommonTask, simTwinMuxDigis, simBmtfDigis, simKBmtfStubs, simKBmtfDigis, simEmtfDigis, simOmtfDigis, simGmtCaloSumDigis, simGmtStage2Digis, simEmtfShowers, simGmtShowerDigis))
## GEM TPs
from L1Trigger.L1TGEM.simGEMDigis_cff import *
diff --git a/L1Trigger/L1TMuon/src/MuonRawDigiTranslator.cc b/L1Trigger/L1TMuon/src/MuonRawDigiTranslator.cc
index 79becf8ea8016..b5ed16c019fc1 100644
--- a/L1Trigger/L1TMuon/src/MuonRawDigiTranslator.cc
+++ b/L1Trigger/L1TMuon/src/MuonRawDigiTranslator.cc
@@ -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_));
@@ -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_;
@@ -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 l1t::MuonRawDigiTranslator::getPackedShowerDataWords(const MuonShower& shower,
+ const int fedId,
+ const unsigned int fwId) {
+ std::array 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) {
diff --git a/L1Trigger/L1TMuon/src/RegionalMuonRawDigiTranslator.cc b/L1Trigger/L1TMuon/src/RegionalMuonRawDigiTranslator.cc
index d144a84ca0df5..f5faf6008093d 100644
--- a/L1Trigger/L1TMuon/src/RegionalMuonRawDigiTranslator.cc
+++ b/L1Trigger/L1TMuon/src/RegionalMuonRawDigiTranslator.cc
@@ -114,6 +114,44 @@ void l1t::RegionalMuonRawDigiTranslator::fillRegionalMuonCand(RegionalMuonCand&
useEmtfDisplacementInfo);
}
+bool l1t::RegionalMuonRawDigiTranslator::fillRegionalMuonShower(
+ RegionalMuonShower& muShower, std::vector bxPayload, int proc, tftype tf, bool useEmtfShowers) {
+ if (useEmtfShowers && (tf == emtf_pos || tf == emtf_neg)) {
+ muShower.setTFIdentifiers(proc, tf);
+
+ muShower.setOneNominalInTime(((bxPayload[emtfShowerOneNominalFrame_] >> emtfShowerOneNominalInTimeShift_) & 1) ==
+ 1);
+ muShower.setOneNominalOutOfTime(
+ ((bxPayload[emtfShowerOneNominalFrame_] >> emtfShowerOneNominalOutOfTimeShift_) & 1) == 1);
+ muShower.setTwoLooseInTime(((bxPayload[emtfShowerTwoLooseFrame_] >> emtfShowerTwoLooseInTimeShift_) & 1) == 1);
+ muShower.setTwoLooseOutOfTime(((bxPayload[emtfShowerTwoLooseFrame_] >> emtfShowerTwoLooseOutOfTimeShift_) & 1) ==
+ 1);
+
+ return true;
+ } else {
+ return false;
+ }
+}
+
+void l1t::RegionalMuonRawDigiTranslator::generatePackedShowerPayload(const RegionalMuonShower& shower,
+ std::array& payload,
+ const bool useEmtfShowers) {
+ if (!useEmtfShowers) {
+ return;
+ }
+ // First we check whether we're going to overwrite something in the payload.
+ if (((payload.at(emtfShowerOneNominalFrame_) & emtfShowerOneNominalMask_) != 0) ||
+ ((payload.at(emtfShowerTwoLooseFrame_) & emtfShowerTwoLooseMask_) != 0)) {
+ edm::LogError("L1T") << "Check constants for RegionalMuonShower fields! It looks like we're in danger of "
+ "overwriting muon data in the packer!";
+ return;
+ }
+ payload.at(emtfShowerOneNominalFrame_) |= (shower.isOneNominalInTime() & 1) << emtfShowerOneNominalInTimeShift_ |
+ (shower.isOneNominalOutOfTime() & 1) << emtfShowerOneNominalOutOfTimeShift_;
+ payload.at(emtfShowerTwoLooseFrame_) |= (shower.isTwoLooseInTime() & 1) << emtfShowerTwoLooseInTimeShift_ |
+ (shower.isTwoLooseOutOfTime() & 1) << emtfShowerTwoLooseOutOfTimeShift_;
+}
+
void l1t::RegionalMuonRawDigiTranslator::generatePackedDataWords(const RegionalMuonCand& mu,
uint32_t& raw_data_00_31,
uint32_t& raw_data_32_63,
diff --git a/L1Trigger/L1TMuonEndCap/interface/SectorProcessorShower.h b/L1Trigger/L1TMuonEndCap/interface/SectorProcessorShower.h
index f48f93ef154e0..bfe1c00688b34 100644
--- a/L1Trigger/L1TMuonEndCap/interface/SectorProcessorShower.h
+++ b/L1Trigger/L1TMuonEndCap/interface/SectorProcessorShower.h
@@ -15,6 +15,8 @@
#include "DataFormats/CSCDigi/interface/CSCShowerDigiCollection.h"
#include "L1Trigger/L1TMuonEndCap/interface/Common.h"
+#include "DataFormats/L1TMuon/interface/RegionalMuonCandFwd.h"
+
#include
class SectorProcessorShower {
diff --git a/L1Trigger/L1TMuonEndCap/src/SectorProcessorShower.cc b/L1Trigger/L1TMuonEndCap/src/SectorProcessorShower.cc
index f271cfea93549..671310fb30218 100644
--- a/L1Trigger/L1TMuonEndCap/src/SectorProcessorShower.cc
+++ b/L1Trigger/L1TMuonEndCap/src/SectorProcessorShower.cc
@@ -67,10 +67,8 @@ void SectorProcessorShower::process(const CSCShowerDigiCollection& in_showers,
if (accept) {
// shower output
l1t::RegionalMuonShower out_shower(hasOneNominalInTime, false, hasTwoLooseInTime, false, hasOneTightInTime, false);
- // convert [1,2] to [1, -1]
- const int endcap(endcap_ == 1 ? 1 : -1);
- out_shower.setEndcap(endcap);
- out_shower.setSector(sector_);
+ l1t::tftype tftype = (endcap_ == 1) ? l1t::tftype::emtf_pos : l1t::tftype::emtf_neg;
+ out_shower.setTFIdentifiers(sector_, tftype);
out_showers.push_back(0, out_shower);
}
}