From 0a9b396a9535df3779569b57e1af087cf4d1924b Mon Sep 17 00:00:00 2001 From: Matteo Migliorini Date: Thu, 20 Jun 2024 11:19:08 +0200 Subject: [PATCH] Backport of #45262 - Removed test files from data format tests as they are not available for older releases --- .../L1Scouting/interface/L1ScoutingBMTFStub.h | 60 ++++++++ DataFormats/L1Scouting/src/classes.h | 3 +- DataFormats/L1Scouting/src/classes_def.xml | 54 ++++--- .../L1Scouting/test/TestL1ScoutingFormat.sh | 4 +- .../L1Scouting/test/TestReadL1Scouting.cc | 66 ++++++++- .../L1Scouting/test/TestWriteL1Scouting.cc | 32 +++- .../test/create_L1Scouting_test_file_cfg.py | 5 +- .../L1Scouting/test/read_L1Scouting_cfg.py | 14 +- .../L1ScoutingRawToDigi/interface/blocks.h | 3 + .../L1ScoutingRawToDigi/interface/masks.h | 15 ++ .../L1ScoutingRawToDigi/interface/shifts.h | 15 ++ .../plugins/ScBMTFRawToDigi.cc | 137 ++++++++++++++++++ .../plugins/ScBMTFRawToDigi.h | 45 ++++++ .../python/ScBMTFRawToDigi_cfi.py | 9 ++ 14 files changed, 430 insertions(+), 32 deletions(-) create mode 100644 DataFormats/L1Scouting/interface/L1ScoutingBMTFStub.h create mode 100644 EventFilter/L1ScoutingRawToDigi/plugins/ScBMTFRawToDigi.cc create mode 100644 EventFilter/L1ScoutingRawToDigi/plugins/ScBMTFRawToDigi.h create mode 100644 EventFilter/L1ScoutingRawToDigi/python/ScBMTFRawToDigi_cfi.py diff --git a/DataFormats/L1Scouting/interface/L1ScoutingBMTFStub.h b/DataFormats/L1Scouting/interface/L1ScoutingBMTFStub.h new file mode 100644 index 0000000000000..5e56dbda130a1 --- /dev/null +++ b/DataFormats/L1Scouting/interface/L1ScoutingBMTFStub.h @@ -0,0 +1,60 @@ +#ifndef DataFormats_L1Scouting_L1ScoutingBMTFStub_h +#define DataFormats_L1Scouting_L1ScoutingBMTFStub_h + +#include "DataFormats/L1Scouting/interface/OrbitCollection.h" + +namespace l1ScoutingRun3 { + + class BMTFStub { + public: + BMTFStub() + : hwPhi_(0), hwPhiB_(0), hwQual_(0), hwEta_(0), hwQEta_(0), station_(0), wheel_(0), sector_(0), tag_(0) {} + + BMTFStub(int hwPhi, int hwPhiB, int hwQual, int hwEta, int hwQEta, int station, int wheel, int sector, int tag) + : hwPhi_(hwPhi), + hwPhiB_(hwPhiB), + hwQual_(hwQual), + hwEta_(hwEta), + hwQEta_(hwQEta), + station_(station), + wheel_(wheel), + sector_(sector), + tag_(tag) {} + + void setHwPhi(int hwPhi) { hwPhi_ = hwPhi; } + void setHwPhiB(int hwPhiB) { hwPhiB_ = hwPhiB; } + void setHwQual(int hwQual) { hwQual_ = hwQual; } + void setHwEta(int hwEta) { hwEta_ = hwEta; } + void setHwQEta(int hwQEta) { hwQEta_ = hwQEta; } + void setStation(int station) { station_ = station; } + void setWheel(int wheel) { wheel_ = wheel; } + void setSector(int sector) { sector_ = sector; } + void setTag(int tag) { tag_ = tag; } + + int hwPhi() const { return hwPhi_; } + int hwPhiB() const { return hwPhiB_; } + int hwQual() const { return hwQual_; } + int hwEta() const { return hwEta_; } + int hwQEta() const { return hwQEta_; } + int station() const { return station_; } + int wheel() const { return wheel_; } + int sector() const { return sector_; } + int tag() const { return tag_; } + + private: + int hwPhi_; + int hwPhiB_; + int hwQual_; + int hwEta_; + int hwQEta_; + int station_; + int wheel_; + int sector_; + int tag_; + }; + + typedef OrbitCollection BMTFStubOrbitCollection; + +} // namespace l1ScoutingRun3 + +#endif //DataFormats_L1Scouting_L1ScoutingBMTFStub_h diff --git a/DataFormats/L1Scouting/src/classes.h b/DataFormats/L1Scouting/src/classes.h index e9c045dd13f21..fcda6a1aafd66 100644 --- a/DataFormats/L1Scouting/src/classes.h +++ b/DataFormats/L1Scouting/src/classes.h @@ -3,4 +3,5 @@ #include "DataFormats/L1Scouting/interface/OrbitCollection.h" #include "DataFormats/L1Scouting/interface/L1ScoutingMuon.h" -#include "DataFormats/L1Scouting/interface/L1ScoutingCalo.h" \ No newline at end of file +#include "DataFormats/L1Scouting/interface/L1ScoutingCalo.h" +#include "DataFormats/L1Scouting/interface/L1ScoutingBMTFStub.h" diff --git a/DataFormats/L1Scouting/src/classes_def.xml b/DataFormats/L1Scouting/src/classes_def.xml index 994fe65b0d442..a81f921621cd7 100644 --- a/DataFormats/L1Scouting/src/classes_def.xml +++ b/DataFormats/L1Scouting/src/classes_def.xml @@ -1,40 +1,50 @@ - - + + + + + + + - - - - + + + + - - - - - + + - - - - + + + + + + + + + + + + + - - - - - - + + + + + - \ No newline at end of file + diff --git a/DataFormats/L1Scouting/test/TestL1ScoutingFormat.sh b/DataFormats/L1Scouting/test/TestL1ScoutingFormat.sh index 3ef6057274e9a..3a6162267f1bc 100755 --- a/DataFormats/L1Scouting/test/TestL1ScoutingFormat.sh +++ b/DataFormats/L1Scouting/test/TestL1ScoutingFormat.sh @@ -8,4 +8,6 @@ cmsRun ${LOCAL_TEST_DIR}/create_L1Scouting_test_file_cfg.py || die 'Failure usin file=testL1Scouting.root -cmsRun ${LOCAL_TEST_DIR}/read_L1Scouting_cfg.py "$file" || die "Failure using read_L1Scouting_cfg.py $file" $? \ No newline at end of file +cmsRun ${LOCAL_TEST_DIR}/read_L1Scouting_cfg.py --inputFile "$file" || die "Failure using read_L1Scouting_cfg.py $file" $? + +exit 0 diff --git a/DataFormats/L1Scouting/test/TestReadL1Scouting.cc b/DataFormats/L1Scouting/test/TestReadL1Scouting.cc index b39f5f8b7547c..b0354df200b16 100644 --- a/DataFormats/L1Scouting/test/TestReadL1Scouting.cc +++ b/DataFormats/L1Scouting/test/TestReadL1Scouting.cc @@ -1,3 +1,4 @@ +#include "DataFormats/L1Scouting/interface/L1ScoutingBMTFStub.h" #include "DataFormats/L1Scouting/interface/L1ScoutingMuon.h" #include "DataFormats/L1Scouting/interface/L1ScoutingCalo.h" #include "DataFormats/L1Scouting/interface/OrbitCollection.h" @@ -31,6 +32,7 @@ namespace edmtest { void analyzeEGammas(edm::Event const& iEvent) const; void analyzeTaus(edm::Event const& iEvent) const; void analyzeBxSums(edm::Event const& iEvent) const; + void analyzeBmtfStubs(edm::Event const& iEvent) const; void throwWithMessageFromConstructor(const char*) const; void throwWithMessage(const char*) const; @@ -51,6 +53,10 @@ namespace edmtest { const std::vector expectedBxSumsValues_; const edm::EDGetTokenT> bxSumsToken_; + + const int bmtfStubClassVersion_; + const std::vector expectedBmtfStubValues_; + const edm::EDGetTokenT> bmtfStubToken_; }; TestReadL1Scouting::TestReadL1Scouting(edm::ParameterSet const& iPSet) @@ -64,7 +70,10 @@ namespace edmtest { expectedTauValues_(iPSet.getParameter>("expectedTauValues")), tausToken_(consumes(iPSet.getParameter("tausTag"))), expectedBxSumsValues_(iPSet.getParameter>("expectedBxSumsValues")), - bxSumsToken_(consumes(iPSet.getParameter("bxSumsTag"))) { + bxSumsToken_(consumes(iPSet.getParameter("bxSumsTag"))), + bmtfStubClassVersion_(iPSet.getParameter("bmtfStubClassVersion")), + expectedBmtfStubValues_(iPSet.getParameter>("expectedBmtfStubValues")), + bmtfStubToken_(consumes(iPSet.getParameter("bmtfStubTag"))) { if (bxValues_.size() != 2) { throwWithMessageFromConstructor("bxValues must have 2 elements and it does not"); } @@ -83,6 +92,9 @@ namespace edmtest { if (expectedBxSumsValues_.size() != 1) { throwWithMessageFromConstructor("bxSumsValues_ must have 1 elements and it does not"); } + if (expectedBmtfStubValues_.size() != 2) { + throwWithMessageFromConstructor("bmtfStubValues_ must have 2 elements and it does not"); + } } void TestReadL1Scouting::analyze(edm::StreamID, edm::Event const& iEvent, edm::EventSetup const&) const { @@ -91,6 +103,7 @@ namespace edmtest { analyzeEGammas(iEvent); analyzeTaus(iEvent); analyzeBxSums(iEvent); + analyzeBmtfStubs(iEvent); } void TestReadL1Scouting::analyzeMuons(edm::Event const& iEvent) const { @@ -303,6 +316,51 @@ namespace edmtest { } } + void TestReadL1Scouting::analyzeBmtfStubs(edm::Event const& iEvent) const { + if (bmtfStubClassVersion_ < 3) { + return; + } + auto const& stubsCollection = iEvent.get(bmtfStubToken_); + + for (const unsigned& bx : bxValues_) { + unsigned nStubs = stubsCollection.getBxSize(bx); + if (nStubs != expectedBmtfStubValues_.size()) { + throwWithMessage("analyzeBmtfStubs, stubs do not have the expected bx size"); + } + + const auto& stubs = stubsCollection.bxIterator(bx); + for (unsigned i = 0; i < nStubs; i++) { + if (stubs[i].hwPhi() != (expectedBmtfStubValues_[i] + 8)) { + throwWithMessage("analyzeBmtfStubs, hwPhi does not match the expected value"); + } + if (stubs[i].hwPhiB() != (expectedBmtfStubValues_[i] + 7)) { + throwWithMessage("analyzeBmtfStubs, hwPhiB does not match the expected value"); + } + if (stubs[i].hwQual() != (expectedBmtfStubValues_[i] + 6)) { + throwWithMessage("analyzeBmtfStubs, hwQual does not match the expected value"); + } + if (stubs[i].hwEta() != (expectedBmtfStubValues_[i] + 5)) { + throwWithMessage("analyzeBmtfStubs, hwEta does not match the expected value"); + } + if (stubs[i].hwQEta() != (expectedBmtfStubValues_[i] + 4)) { + throwWithMessage("analyzeBmtfStubs, hwQEta does not match the expected value"); + } + if (stubs[i].station() != (expectedBmtfStubValues_[i] + 3)) { + throwWithMessage("analyzeBmtfStubs, station does not match the expected value"); + } + if (stubs[i].wheel() != (expectedBmtfStubValues_[i] + 2)) { + throwWithMessage("analyzeBmtfStubs, wheel does not match the expected value"); + } + if (stubs[i].sector() != (expectedBmtfStubValues_[i] + 1)) { + throwWithMessage("analyzeBmtfStubs, sector does not match the expected value"); + } + if (stubs[i].tag() != (expectedBmtfStubValues_[i])) { + throwWithMessage("analyzeBmtfStubs, tag does not match the expected value"); + } + } + } + } + void TestReadL1Scouting::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { edm::ParameterSetDescription desc; desc.add>("bxValues"); @@ -316,6 +374,10 @@ namespace edmtest { desc.add("tausTag"); desc.add>("expectedBxSumsValues"); desc.add("bxSumsTag"); + desc.add("bmtfStubClassVersion"); + desc.add>("expectedBmtfStubValues"); + desc.add("bmtfStubTag"); + descriptions.addDefault(desc); } @@ -330,4 +392,4 @@ namespace edmtest { } // namespace edmtest using edmtest::TestReadL1Scouting; -DEFINE_FWK_MODULE(TestReadL1Scouting); \ No newline at end of file +DEFINE_FWK_MODULE(TestReadL1Scouting); diff --git a/DataFormats/L1Scouting/test/TestWriteL1Scouting.cc b/DataFormats/L1Scouting/test/TestWriteL1Scouting.cc index 62a807b4b5b18..160d4c7262c21 100644 --- a/DataFormats/L1Scouting/test/TestWriteL1Scouting.cc +++ b/DataFormats/L1Scouting/test/TestWriteL1Scouting.cc @@ -1,3 +1,4 @@ +#include "DataFormats/L1Scouting/interface/L1ScoutingBMTFStub.h" #include "DataFormats/L1Scouting/interface/L1ScoutingMuon.h" #include "DataFormats/L1Scouting/interface/L1ScoutingCalo.h" #include "DataFormats/L1Scouting/interface/OrbitCollection.h" @@ -29,6 +30,7 @@ namespace edmtest { void produceEGammas(edm::Event& iEvent) const; void produceTaus(edm::Event& iEvent) const; void produceBxSums(edm::Event& iEvent) const; + void produceBmtfStubs(edm::Event& iEvent) const; void throwWithMessage(const char*) const; @@ -48,6 +50,9 @@ namespace edmtest { const std::vector bxSumsValues_; const edm::EDPutTokenT> bxSumsPutToken_; + + const std::vector bmtfStubsValues_; + const edm::EDPutTokenT> bmtfStubsPutToken_; }; TestWriteL1Scouting::TestWriteL1Scouting(edm::ParameterSet const& iPSet) @@ -61,7 +66,9 @@ namespace edmtest { tauValues_(iPSet.getParameter>("tauValues")), tausPutToken_(produces()), bxSumsValues_(iPSet.getParameter>("bxSumsValues")), - bxSumsPutToken_(produces()) { + bxSumsPutToken_(produces()), + bmtfStubsValues_(iPSet.getParameter>("bmtfStubValues")), + bmtfStubsPutToken_(produces()) { if (bxValues_.size() != 2) { throwWithMessage("bxValues must have 2 elements and it does not"); } @@ -80,6 +87,9 @@ namespace edmtest { if (bxSumsValues_.size() != 1) { throwWithMessage("bxSumsValues_ must have 1 elements and it does not"); } + if (bmtfStubsValues_.size() != 2) { + throwWithMessage("bmtfStubsValues_ must have 2 elements and it does not"); + } } void TestWriteL1Scouting::produce(edm::StreamID, edm::Event& iEvent, edm::EventSetup const&) const { @@ -88,6 +98,7 @@ namespace edmtest { produceEGammas(iEvent); produceTaus(iEvent); produceBxSums(iEvent); + produceBmtfStubs(iEvent); } void TestWriteL1Scouting::produceMuons(edm::Event& iEvent) const { @@ -171,6 +182,22 @@ namespace edmtest { iEvent.put(bxSumsPutToken_, std::move(bxSums)); } + void TestWriteL1Scouting::produceBmtfStubs(edm::Event& iEvent) const { + std::unique_ptr stubs(new l1ScoutingRun3::BMTFStubOrbitCollection); + + std::vector> orbitBufferStubs(3565); + int nStubs = 0; + for (const unsigned& bx : bxValues_) { + for (const int& val : bmtfStubsValues_) { + orbitBufferStubs[bx].emplace_back(val + 8, val + 7, val + 6, val + 5, val + 4, val + 3, val + 2, val + 1, val); + nStubs++; + } + } + + stubs->fillAndClear(orbitBufferStubs, nStubs); + iEvent.put(bmtfStubsPutToken_, std::move(stubs)); + } + void TestWriteL1Scouting::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { edm::ParameterSetDescription desc; desc.add>("bxValues"); @@ -179,6 +206,7 @@ namespace edmtest { desc.add>("eGammaValues"); desc.add>("tauValues"); desc.add>("bxSumsValues"); + desc.add>("bmtfStubValues"); descriptions.addDefault(desc); } @@ -189,4 +217,4 @@ namespace edmtest { } // namespace edmtest using edmtest::TestWriteL1Scouting; -DEFINE_FWK_MODULE(TestWriteL1Scouting); \ No newline at end of file +DEFINE_FWK_MODULE(TestWriteL1Scouting); diff --git a/DataFormats/L1Scouting/test/create_L1Scouting_test_file_cfg.py b/DataFormats/L1Scouting/test/create_L1Scouting_test_file_cfg.py index 1f03c455497ff..772bf3c798814 100644 --- a/DataFormats/L1Scouting/test/create_L1Scouting_test_file_cfg.py +++ b/DataFormats/L1Scouting/test/create_L1Scouting_test_file_cfg.py @@ -13,7 +13,8 @@ jetValues = cms.vint32(4, 5, 6, 7), eGammaValues = cms.vint32(8, 9, 10), tauValues = cms.vint32(11, 12), - bxSumsValues = cms.vint32(13) + bxSumsValues = cms.vint32(13), + bmtfStubValues = cms.vint32(1, 2), ) process.out = cms.OutputModule("PoolOutputModule", @@ -21,4 +22,4 @@ ) process.path = cms.Path(process.l1ScoutingTestProducer) -process.endPath = cms.EndPath(process.out) \ No newline at end of file +process.endPath = cms.EndPath(process.out) diff --git a/DataFormats/L1Scouting/test/read_L1Scouting_cfg.py b/DataFormats/L1Scouting/test/read_L1Scouting_cfg.py index feb57aaa26ae5..1c24d2631bb05 100644 --- a/DataFormats/L1Scouting/test/read_L1Scouting_cfg.py +++ b/DataFormats/L1Scouting/test/read_L1Scouting_cfg.py @@ -1,11 +1,18 @@ import FWCore.ParameterSet.Config as cms import sys +import argparse + +parser = argparse.ArgumentParser(prog=sys.argv[0], description='Test L1 Scouting data formats') + +parser.add_argument("--inputFile", type=str, help="Input file name (default: testL1Scouting.root)", default="testL1Scouting.root") +parser.add_argument("--bmtfStubVersion", type=int, help="track data format version (default: 3)", default=3) +args = parser.parse_args() process = cms.Process("READ") process.load("FWCore.MessageService.MessageLogger_cfi") -process.source = cms.Source("PoolSource", fileNames = cms.untracked.vstring("file:"+sys.argv[1])) +process.source = cms.Source("PoolSource", fileNames = cms.untracked.vstring("file:"+args.inputFile)) process.maxEvents.input = 1 process.l1ScoutingTestAnalyzer = cms.EDAnalyzer("TestReadL1Scouting", @@ -19,7 +26,10 @@ tausTag = cms.InputTag("l1ScoutingTestProducer", "", "PROD"), expectedTauValues = cms.vint32(11, 12), bxSumsTag = cms.InputTag("l1ScoutingTestProducer", "", "PROD"), - expectedBxSumsValues = cms.vint32(13) + expectedBxSumsValues = cms.vint32(13), + bmtfStubClassVersion = cms.int32(args.bmtfStubVersion), + bmtfStubTag = cms.InputTag("l1ScoutingTestProducer", "", "PROD"), + expectedBmtfStubValues = cms.vint32(1, 2) ) process.out = cms.OutputModule("PoolOutputModule", diff --git a/EventFilter/L1ScoutingRawToDigi/interface/blocks.h b/EventFilter/L1ScoutingRawToDigi/interface/blocks.h index 940131fc8f942..a054969a206e2 100644 --- a/EventFilter/L1ScoutingRawToDigi/interface/blocks.h +++ b/EventFilter/L1ScoutingRawToDigi/interface/blocks.h @@ -62,6 +62,9 @@ namespace l1ScoutingRun3 { namespace bmtf { struct block { + uint32_t header; + uint32_t bx; + uint32_t orbit; uint64_t stub[8]; }; } // namespace bmtf diff --git a/EventFilter/L1ScoutingRawToDigi/interface/masks.h b/EventFilter/L1ScoutingRawToDigi/interface/masks.h index 349c8a8bb4ddd..53b9947abb794 100644 --- a/EventFilter/L1ScoutingRawToDigi/interface/masks.h +++ b/EventFilter/L1ScoutingRawToDigi/interface/masks.h @@ -89,6 +89,21 @@ namespace l1ScoutingRun3 { }; } // namespace demux + namespace bmtf { + struct masksStubs { + static constexpr uint64_t valid = 0x0001; + static constexpr uint64_t phi = 0x0fff; + static constexpr uint64_t phiB = 0x03ff; + static constexpr uint64_t qual = 0x0007; + static constexpr uint64_t eta = 0x007f; + static constexpr uint64_t qeta = 0x007f; + static constexpr uint64_t station = 0x0003; + static constexpr uint64_t wheel = 0x0007; + static constexpr uint64_t reserved = 0x0007; + static constexpr uint64_t bx = 0xffff; + }; + } // namespace bmtf + struct header_masks { static constexpr uint32_t bxmatch = 0x00ff << header_shifts::bxmatch; static constexpr uint32_t mAcount = 0x000f << header_shifts::mAcount; diff --git a/EventFilter/L1ScoutingRawToDigi/interface/shifts.h b/EventFilter/L1ScoutingRawToDigi/interface/shifts.h index 5f0788c9a7a47..3075216e9e5a8 100644 --- a/EventFilter/L1ScoutingRawToDigi/interface/shifts.h +++ b/EventFilter/L1ScoutingRawToDigi/interface/shifts.h @@ -89,6 +89,21 @@ namespace l1ScoutingRun3 { }; } // namespace demux + namespace bmtf { + struct shiftsStubs { + static constexpr uint32_t valid = 0; + static constexpr uint32_t phi = 1; + static constexpr uint32_t phiB = 13; + static constexpr uint32_t qual = 23; + static constexpr uint32_t eta = 26; + static constexpr uint32_t qeta = 33; + static constexpr uint32_t station = 40; + static constexpr uint32_t wheel = 42; + static constexpr uint32_t reserved = 45; + static constexpr uint32_t bx = 48; + }; + } // namespace bmtf + struct header_shifts { static constexpr uint32_t bxmatch = 24; static constexpr uint32_t mAcount = 16; diff --git a/EventFilter/L1ScoutingRawToDigi/plugins/ScBMTFRawToDigi.cc b/EventFilter/L1ScoutingRawToDigi/plugins/ScBMTFRawToDigi.cc new file mode 100644 index 0000000000000..684193a5086d4 --- /dev/null +++ b/EventFilter/L1ScoutingRawToDigi/plugins/ScBMTFRawToDigi.cc @@ -0,0 +1,137 @@ +#include "EventFilter/L1ScoutingRawToDigi/plugins/ScBMTFRawToDigi.h" + +ScBMTFRawToDigi::ScBMTFRawToDigi(const edm::ParameterSet& iConfig) { + using namespace edm; + srcInputTag_ = iConfig.getParameter("srcInputTag"); + sourceIdList_ = iConfig.getParameter>("sourceIdList"); + debug_ = iConfig.getUntrackedParameter("debug", false); + + // initialize orbit buffer for BX 1->3564; + orbitBuffer_ = std::vector>(3565); + for (auto& bxVec : orbitBuffer_) { + bxVec.reserve(32); + } + nStubsOrbit_ = 0; + + produces().setBranchAlias("BMTFStubOrbitCollection"); + rawToken_ = consumes(srcInputTag_); +} + +ScBMTFRawToDigi::~ScBMTFRawToDigi(){}; + +void ScBMTFRawToDigi::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + using namespace edm; + + Handle ScoutingRawDataCollection; + iEvent.getByToken(rawToken_, ScoutingRawDataCollection); + + std::unique_ptr unpackedStubs(new l1ScoutingRun3::BMTFStubOrbitCollection); + + for (const auto& sdsId : sourceIdList_) { + if ((sdsId < SDSNumbering::BmtfMinSDSID) || (sdsId > SDSNumbering::BmtfMaxSDSID)) + edm::LogError("ScBMTFRawToDigi::produce") + << "Provided a source ID outside the expected range: " << sdsId << ", expected range [" + << SDSNumbering::BmtfMinSDSID << ", " << SDSNumbering::BmtfMaxSDSID; + const FEDRawData& sourceRawData = ScoutingRawDataCollection->FEDData(sdsId); + size_t orbitSize = sourceRawData.size(); + + if ((sourceRawData.size() == 0) && debug_) { + std::cout << "No raw data for BMTF FED " << sdsId << std::endl; + } + + // unpack current orbit and store data into the orbitBufferr + unpackOrbit(sourceRawData.data(), orbitSize, sdsId); + } + + // fill orbit collection and clear the Bx buffer vector + unpackedStubs->fillAndClear(orbitBuffer_, nStubsOrbit_); + + // store collection in the event + iEvent.put(std::move(unpackedStubs)); +} + +void ScBMTFRawToDigi::unpackOrbit(const unsigned char* buf, size_t len, int sdsId) { + using namespace l1ScoutingRun3; + + // reset counters + nStubsOrbit_ = 0; + + size_t pos = 0; + + while (pos < len) { + assert(pos + 4 <= len); + + bmtf::block* bl = (bmtf::block*)(buf + pos); + + unsigned bx = bl->bx; + unsigned orbit = (bl->orbit) & 0x7FFFFFFF; + unsigned sCount = (bl->header) & 0xff; + + size_t pos_increment = 12 + sCount * 8; + + assert(pos_increment <= len); + + pos += 12; // header + + if (debug_) { + std::cout << " BMTF #" << sdsId << " Orbit " << orbit << ", BX -> " << bx << ", nStubs -> " << sCount + << std::endl; + } + + // Unpack stubs for the current pair (BX, sector) + int32_t phi, phiB, tag, qual, eta, qeta, station, wheel, sector; + + // map for station and wheel, to find chambers with 2 stubs + std::vector> stwh_matrix(4, std::vector(5, false)); + for (unsigned int i = 0; i < sCount; i++) { + uint64_t stub_raw = *(uint64_t*)(buf + pos); + pos += 8; + + phi = ((stub_raw >> bmtf::shiftsStubs::phi) & bmtf::masksStubs::phi); + phiB = ((stub_raw >> bmtf::shiftsStubs::phiB) & bmtf::masksStubs::phiB); + qual = ((stub_raw >> bmtf::shiftsStubs::qual) & bmtf::masksStubs::qual); + eta = ((stub_raw >> bmtf::shiftsStubs::eta) & bmtf::masksStubs::eta); + qeta = ((stub_raw >> bmtf::shiftsStubs::qeta) & bmtf::masksStubs::qeta); + station = ((stub_raw >> bmtf::shiftsStubs::station) & bmtf::masksStubs::station) + 1; + wheel = ((stub_raw >> bmtf::shiftsStubs::wheel) & bmtf::masksStubs::wheel); + sector = sdsId - SDSNumbering::BmtfMinSDSID; + + if (stwh_matrix[station - 1][wheel + 2] == false) { + tag = 1; + } else { + tag = 0; + } + stwh_matrix[station - 1][wheel + 2] = true; + + phi = phi >= 2048 ? phi - 4096 : phi; + phiB = phiB >= 512 ? phiB - 1024 : phiB; + wheel = wheel >= 4 ? wheel - 8 : wheel; + + BMTFStub stub(phi, phiB, qual, eta, qeta, station, wheel, sector, tag); + orbitBuffer_[bx].push_back(stub); + nStubsOrbit_++; + + if (debug_) { + std::cout << "Stub " << i << ", raw: 0x" << std::hex << stub_raw << std::dec << std::endl; + std::cout << "\tPhi: " << phi << std::endl; + std::cout << "\tPhiB: " << phiB << std::endl; + std::cout << "\tQuality: " << qual << std::endl; + std::cout << "\tEta: " << eta << std::endl; + std::cout << "\tQEta: " << qeta << std::endl; + std::cout << "\tStation: " << station << std::endl; + std::cout << "\tWheel: " << wheel << std::endl; + std::cout << "\tSector: " << sector << std::endl; + std::cout << "\tTag: " << tag << std::endl; + } + } + + } // end orbit while loop +} + +void ScBMTFRawToDigi::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.setUnknown(); + descriptions.addDefault(desc); +} + +DEFINE_FWK_MODULE(ScBMTFRawToDigi); diff --git a/EventFilter/L1ScoutingRawToDigi/plugins/ScBMTFRawToDigi.h b/EventFilter/L1ScoutingRawToDigi/plugins/ScBMTFRawToDigi.h new file mode 100644 index 0000000000000..556d38b527d40 --- /dev/null +++ b/EventFilter/L1ScoutingRawToDigi/plugins/ScBMTFRawToDigi.h @@ -0,0 +1,45 @@ +#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/FEDRawData/interface/FEDRawData.h" +#include "DataFormats/L1ScoutingRawData/interface/SDSNumbering.h" +#include "DataFormats/L1ScoutingRawData/interface/SDSRawDataCollection.h" +#include "DataFormats/L1Scouting/interface/OrbitCollection.h" + +#include "DataFormats/L1Scouting/interface/L1ScoutingBMTFStub.h" + +#include "EventFilter/L1ScoutingRawToDigi/interface/shifts.h" +#include "EventFilter/L1ScoutingRawToDigi/interface/masks.h" +#include "EventFilter/L1ScoutingRawToDigi/interface/blocks.h" +#include "L1TriggerScouting/Utilities/interface/printScObjects.h" + +#include +#include +#include + +class ScBMTFRawToDigi : public edm::stream::EDProducer<> { +public: + explicit ScBMTFRawToDigi(const edm::ParameterSet&); + ~ScBMTFRawToDigi() override; + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + +private: + void produce(edm::Event&, const edm::EventSetup&) override; + + void unpackOrbit(const unsigned char* buf, size_t len, int sdsId); + + // vector holding data for every bunch crossing + // before filling the orbit collection + std::vector> orbitBuffer_; + int nStubsOrbit_; + + bool debug_ = false; + std::vector sourceIdList_; + edm::InputTag srcInputTag_; + edm::EDGetToken rawToken_; +}; diff --git a/EventFilter/L1ScoutingRawToDigi/python/ScBMTFRawToDigi_cfi.py b/EventFilter/L1ScoutingRawToDigi/python/ScBMTFRawToDigi_cfi.py new file mode 100644 index 0000000000000..3ed829b0eadc3 --- /dev/null +++ b/EventFilter/L1ScoutingRawToDigi/python/ScBMTFRawToDigi_cfi.py @@ -0,0 +1,9 @@ +import FWCore.ParameterSet.Config as cms + +ScBMTFUnpacker = cms.EDProducer('ScBMTFRawToDigi', + srcInputTag = cms.InputTag('rawDataCollector'), + sourceIdList = cms.vint32(10,11,12,13,14,15,16,17,18,19,20,21), + # print all objects + debug = cms.untracked.bool(False) +) +