diff --git a/DataFormats/FEDRawData/interface/FEDRawData.h b/DataFormats/FEDRawData/interface/FEDRawData.h index 8def41c8e270b..104ff42026621 100644 --- a/DataFormats/FEDRawData/interface/FEDRawData.h +++ b/DataFormats/FEDRawData/interface/FEDRawData.h @@ -26,8 +26,8 @@ class FEDRawData { /// Ctor specifying the size to be preallocated, in bytes. /// It is required that the size is a multiple of the size of a FED - /// word (8 bytes) - FEDRawData(size_t newsize); + /// word (8 bytes default) + FEDRawData(size_t newsize, size_t wordsize = 8); /// Copy constructor FEDRawData(const FEDRawData &); @@ -45,8 +45,8 @@ class FEDRawData { size_t size() const { return data_.size(); } /// Resize to the specified size in bytes. It is required that - /// the size is a multiple of the size of a FED word (8 bytes) - void resize(size_t newsize); + /// the size is a multiple of the size of a FED word (8 bytes default) + void resize(size_t newsize, size_t wordsize = 8); private: Data data_; diff --git a/DataFormats/FEDRawData/src/FEDRawData.cc b/DataFormats/FEDRawData/src/FEDRawData.cc index 28bbaa55bd19f..4f617d1e2a46a 100644 --- a/DataFormats/FEDRawData/src/FEDRawData.cc +++ b/DataFormats/FEDRawData/src/FEDRawData.cc @@ -13,10 +13,10 @@ using namespace std; FEDRawData::FEDRawData() {} -FEDRawData::FEDRawData(size_t newsize) : data_(newsize) { - if (newsize % 8 != 0) - throw cms::Exception("DataCorrupt") << "FEDRawData::resize: " << newsize << " is not a multiple of 8 bytes." - << endl; +FEDRawData::FEDRawData(size_t newsize, size_t wordsize) : data_(newsize) { + if (newsize % wordsize != 0) + throw cms::Exception("DataCorrupt") << "FEDRawData::resize: " << newsize << " is not a multiple of " << wordsize + << " bytes." << endl; } FEDRawData::FEDRawData(const FEDRawData &in) : data_(in.data_) {} @@ -25,13 +25,13 @@ const unsigned char *FEDRawData::data() const { return data_.data(); } unsigned char *FEDRawData::data() { return data_.data(); } -void FEDRawData::resize(size_t newsize) { +void FEDRawData::resize(size_t newsize, size_t wordsize) { if (size() == newsize) return; data_.resize(newsize); - if (newsize % 8 != 0) - throw cms::Exception("DataCorrupt") << "FEDRawData::resize: " << newsize << " is not a multiple of 8 bytes." - << endl; + if (newsize % wordsize != 0) + throw cms::Exception("DataCorrupt") << "FEDRawData::resize: " << newsize << " is not a multiple of " << wordsize + << " bytes." << endl; } diff --git a/DataFormats/L1Scouting/BuildFile.xml b/DataFormats/L1Scouting/BuildFile.xml new file mode 100644 index 0000000000000..0f37f92979ed5 --- /dev/null +++ b/DataFormats/L1Scouting/BuildFile.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/DataFormats/L1Scouting/README.md b/DataFormats/L1Scouting/README.md new file mode 100644 index 0000000000000..c25fbf3387ee8 --- /dev/null +++ b/DataFormats/L1Scouting/README.md @@ -0,0 +1,8 @@ +# DataFormats/L1Scouting + +## L1 Trigger Scouting data formats + +Any changes to the L1 scouting data formats must be backwards compatible. +In order to ensure the L1 Scouting formats can be read by future CMSSW releases, +there is a `TestWriteL1ScoutingDataFormats` unit test, which makes use of the `TestReadL1Scouting` analyzer and the `TestWriteL1Scouting` producer. +The unit test checks that objects can be written and read properly. \ No newline at end of file diff --git a/DataFormats/L1Scouting/interface/L1ScoutingCalo.h b/DataFormats/L1Scouting/interface/L1ScoutingCalo.h new file mode 100644 index 0000000000000..53913fe840b0b --- /dev/null +++ b/DataFormats/L1Scouting/interface/L1ScoutingCalo.h @@ -0,0 +1,198 @@ +#ifndef DataFormats_L1Scouting_L1ScoutingCalo_h +#define DataFormats_L1Scouting_L1ScoutingCalo_h + +#include "DataFormats/L1Scouting/interface/OrbitCollection.h" + +namespace l1ScoutingRun3 { + + class CaloObject { + public: + CaloObject() : hwEt_(0), hwEta_(0), hwPhi_(0), hwIso_(0) {} + + CaloObject(int hwEt, int hwEta, int hwPhi, int iso) : hwEt_(hwEt), hwEta_(hwEta), hwPhi_(hwPhi), hwIso_(iso) {} + + void setHwEt(int hwEt) { hwEt_ = hwEt; } + void setHwEta(int hwEta) { hwEta_ = hwEta; } + void setHwPhi(int hwPhi) { hwPhi_ = hwPhi; } + void setHwIso(int hwIso) { hwIso_ = hwIso; } + + int hwEt() const { return hwEt_; } + int hwEta() const { return hwEta_; } + int hwPhi() const { return hwPhi_; } + int hwIso() const { return hwIso_; } + + private: + int hwEt_; + int hwEta_; + int hwPhi_; + int hwIso_; + }; + + class Jet : public CaloObject { + public: + Jet() : CaloObject(0, 0, 0, 0) {} + + Jet(int hwEt, int hwEta, int hwPhi, int hwQual) : CaloObject(hwEt, hwEta, hwPhi, hwQual) {} + + // store quality instead of iso + void setHwQual(int hwQual) { setHwIso(hwQual); } + int hwQual() const { return hwIso(); } + }; + + class EGamma : public CaloObject { + public: + EGamma() : CaloObject(0, 0, 0, 0) {} + + EGamma(int hwEt, int hwEta, int hwPhi, int iso) : CaloObject(hwEt, hwEta, hwPhi, iso) {} + }; + + class Tau : public CaloObject { + public: + Tau() : CaloObject(0, 0, 0, 0) {} + + Tau(int hwEt, int hwEta, int hwPhi, int iso) : CaloObject(hwEt, hwEta, hwPhi, iso) {} + }; + + class BxSums { + public: + BxSums() + : hwTotalEt_(0), + hwTotalEtEm_(0), + hwTotalHt_(0), + hwMissEt_(0), + hwMissEtPhi_(0), + hwMissHt_(0), + hwMissHtPhi_(0), + hwMissEtHF_(0), + hwMissEtHFPhi_(0), + hwMissHtHF_(0), + hwMissHtHFPhi_(0), + hwAsymEt_(0), + hwAsymHt_(0), + hwAsymEtHF_(0), + hwAsymHtHF_(0), + minBiasHFP0_(0), + minBiasHFM0_(0), + minBiasHFP1_(0), + minBiasHFM1_(0), + towerCount_(0), + centrality_(0) {} + + BxSums(int hwTotalEt, + int hwTotalEtEm, + int hwTotalHt, + int hwMissEt, + int hwMissEtPhi, + int hwMissHt, + int hwMissHtPhi, + int hwMissEtHF, + int hwMissEtHFPhi, + int hwMissHtHF, + int hwMissHtHFPhi, + int hwAsymEt, + int hwAsymHt, + int hwAsymEtHF, + int hwAsymHtHF, + int minBiasHFP0, + int minBiasHFM0, + int minBiasHFP1, + int minBiasHFM1, + int towerCount, + int centrality) + : hwTotalEt_(hwTotalEt), + hwTotalEtEm_(hwTotalEtEm), + hwTotalHt_(hwTotalHt), + hwMissEt_(hwMissEt), + hwMissEtPhi_(hwMissEtPhi), + hwMissHt_(hwMissHt), + hwMissHtPhi_(hwMissHtPhi), + hwMissEtHF_(hwMissEtHF), + hwMissEtHFPhi_(hwMissEtHFPhi), + hwMissHtHF_(hwMissHtHF), + hwMissHtHFPhi_(hwMissHtHFPhi), + hwAsymEt_(hwAsymEt), + hwAsymHt_(hwAsymHt), + hwAsymEtHF_(hwAsymEtHF), + hwAsymHtHF_(hwAsymHtHF), + minBiasHFP0_(minBiasHFP0), + minBiasHFM0_(minBiasHFM0), + minBiasHFP1_(minBiasHFP1), + minBiasHFM1_(minBiasHFM1), + towerCount_(towerCount), + centrality_(centrality) {} + + void setHwTotalEt(int hwTotalEt) { hwTotalEt_ = hwTotalEt; } + void setHwTotalEtEm(int hwTotalEtEm) { hwTotalEtEm_ = hwTotalEtEm; } + void setMinBiasHFP0(int minBiasHFP0) { minBiasHFP0_ = minBiasHFP0; } + void setHwTotalHt(int hwTotalHt) { hwTotalHt_ = hwTotalHt; } + void setTowerCount(int towerCount) { towerCount_ = towerCount; } + void setMinBiasHFM0(int minBiasHFM0) { minBiasHFM0_ = minBiasHFM0; } + void setHwMissEt(int hwMissEt) { hwMissEt_ = hwMissEt; } + void setHwMissEtPhi(int hwMissEtPhi) { hwMissEtPhi_ = hwMissEtPhi; } + void setHwAsymEt(int hwAsymEt) { hwAsymEt_ = hwAsymEt; } + void setMinBiasHFP1(int minBiasHFP1) { minBiasHFP1_ = minBiasHFP1; } + void setHwMissHt(int hwMissHt) { hwMissHt_ = hwMissHt; } + void setHwMissHtPhi(int hwMissHtPhi) { hwMissHtPhi_ = hwMissHtPhi; } + void setHwAsymHt(int hwAsymHt) { hwAsymHt_ = hwAsymHt; } + void setMinBiasHFM1(int minBiasHFM1) { minBiasHFM1_ = minBiasHFM1; } + void setHwMissEtHF(int hwMissEtHF) { hwMissEtHF_ = hwMissEtHF; } + void setHwMissEtHFPhi(int hwMissEtHFPhi) { hwMissEtHFPhi_ = hwMissEtHFPhi; } + void setHwAsymEtHF(int hwAsymEtHF) { hwAsymEtHF_ = hwAsymEtHF; } + void setHwMissHtHF(int hwMissHtHF) { hwMissHtHF_ = hwMissHtHF; } + void setHwMissHtHFPhi(int hwMissHtHFPhi) { hwMissHtHFPhi_ = hwMissHtHFPhi; } + void setHwAsymHtHF(int hwAsymHtHF) { hwAsymHtHF_ = hwAsymHtHF; } + void setCentrality(int centrality) { centrality_ = centrality; } + + const int hwTotalEt() const { return hwTotalEt_; } + const int hwTotalEtEm() const { return hwTotalEtEm_; } + const int minBiasHFP0() const { return minBiasHFP0_; } + const int hwTotalHt() const { return hwTotalHt_; } + const int towerCount() const { return towerCount_; } + const int minBiasHFM0() const { return minBiasHFM0_; } + const int hwMissEt() const { return hwMissEt_; } + const int hwMissEtPhi() const { return hwMissEtPhi_; } + const int hwAsymEt() const { return hwAsymEt_; } + const int minBiasHFP1() const { return minBiasHFP1_; } + const int hwMissHt() const { return hwMissHt_; } + const int hwMissHtPhi() const { return hwMissHtPhi_; } + const int hwAsymHt() const { return hwAsymHt_; } + const int minBiasHFM1() const { return minBiasHFM1_; } + const int hwMissEtHF() const { return hwMissEtHF_; } + const int hwMissEtHFPhi() const { return hwMissEtHFPhi_; } + const int hwAsymEtHF() const { return hwAsymEtHF_; } + const int hwMissHtHF() const { return hwMissHtHF_; } + const int hwMissHtHFPhi() const { return hwMissHtHFPhi_; } + const int hwAsymHtHF() const { return hwAsymHtHF_; } + const int centrality() const { return centrality_; } + + private: + int hwTotalEt_; + int hwTotalEtEm_; + int hwTotalHt_; + int hwMissEt_; + int hwMissEtPhi_; + int hwMissHt_; + int hwMissHtPhi_; + int hwMissEtHF_; + int hwMissEtHFPhi_; + int hwMissHtHF_; + int hwMissHtHFPhi_; + int hwAsymEt_; + int hwAsymHt_; + int hwAsymEtHF_; + int hwAsymHtHF_; + int minBiasHFP0_; + int minBiasHFM0_; + int minBiasHFP1_; + int minBiasHFM1_; + int towerCount_; + int centrality_; + }; + + typedef OrbitCollection JetOrbitCollection; + typedef OrbitCollection EGammaOrbitCollection; + typedef OrbitCollection TauOrbitCollection; + typedef OrbitCollection BxSumsOrbitCollection; + +} // namespace l1ScoutingRun3 +#endif // DataFormats_L1Scouting_L1ScoutingCalo_h \ No newline at end of file diff --git a/DataFormats/L1Scouting/interface/L1ScoutingMuon.h b/DataFormats/L1Scouting/interface/L1ScoutingMuon.h new file mode 100644 index 0000000000000..59882addb1b6a --- /dev/null +++ b/DataFormats/L1Scouting/interface/L1ScoutingMuon.h @@ -0,0 +1,95 @@ +#ifndef DataFormats_L1Scouting_L1ScoutingMuon_h +#define DataFormats_L1Scouting_L1ScoutingMuon_h + +#include "DataFormats/L1Scouting/interface/OrbitCollection.h" + +namespace l1ScoutingRun3 { + + class Muon { + public: + Muon() + : hwPt_(0), + hwEta_(0), + hwPhi_(0), + hwQual_(0), + hwChrg_(0), + hwChrgv_(0), + hwIso_(0), + tfIndex_(0), + hwEtaAtVtx_(0), + hwPhiAtVtx_(0), + hwPtUnconstrained_(0), + hwDXY_(0) {} + + Muon(int hwPt, + int hwEta, + int hwPhi, + int hwQual, + int hwChrg, + int hwChrgv, + int hwIso, + int tfIndex, + int hwEtaAtVtx, + int hwPhiAtVtx, + int hwPtUnconstrained, + int hwDXY) + : hwPt_(hwPt), + hwEta_(hwEta), + hwPhi_(hwPhi), + hwQual_(hwQual), + hwChrg_(hwChrg), + hwChrgv_(hwChrgv), + hwIso_(hwIso), + tfIndex_(tfIndex), + hwEtaAtVtx_(hwEtaAtVtx), + hwPhiAtVtx_(hwPhiAtVtx), + hwPtUnconstrained_(hwPtUnconstrained), + hwDXY_(hwDXY) {} + + void setHwPt(int hwPt) { hwPt_ = hwPt; } + void setHwEta(int hwEta) { hwEta_ = hwEta; } + void setHwPhi(int hwPhi) { hwPhi_ = hwPhi; } + void setHwQual(int hwQual) { hwQual_ = hwQual; } + void setHwChrg(int hwChrg) { hwChrg_ = hwChrg; } + void setHwChrgv(int hwChrgv) { hwChrgv_ = hwChrgv; } + void setHwIso(int hwIso) { hwIso_ = hwIso; } + void setTfIndex(int tfIndex) { tfIndex_ = tfIndex; } + void setHwEtaAtVtx(int hwEtaAtVtx) { hwEtaAtVtx_ = hwEtaAtVtx; } + void setHwPhiAtVtx(int hwPhiAtVtx) { hwPhiAtVtx_ = hwPhiAtVtx; } + void setHwPtUnconstrained(int hwPtUnconstrained) { hwPtUnconstrained_ = hwPtUnconstrained; } + void setHwDXY(int hwDXY) { hwDXY_ = hwDXY; } + + int hwPt() const { return hwPt_; } + int hwEta() const { return hwEta_; } + int hwPhi() const { return hwPhi_; } + int hwQual() const { return hwQual_; } + int hwCharge() const { return hwChrg_; } + int hwChargeValid() const { return hwChrgv_; } + int hwIso() const { return hwIso_; } + int hwIndex() const { return tfIndex_; } + int hwEtaAtVtx() const { return hwEtaAtVtx_; } + int hwPhiAtVtx() const { return hwPhiAtVtx_; } + int hwPtUnconstrained() const { return hwPtUnconstrained_; } + int hwDXY() const { return hwDXY_; } + int tfMuonIndex() const { return tfIndex_; } + + private: + int hwPt_; + int hwEta_; + int hwPhi_; + int hwQual_; + int hwChrg_; + int hwChrgv_; + int hwIso_; + int tfIndex_; + int hwEtaAtVtx_; + int hwPhiAtVtx_; + int hwPtUnconstrained_; + int hwDXY_; + }; + + typedef OrbitCollection MuonOrbitCollection; + +} // namespace l1ScoutingRun3 + +#endif // DataFormats_L1Scouting_L1ScoutingMuon_h \ No newline at end of file diff --git a/DataFormats/L1Scouting/interface/OrbitCollection.h b/DataFormats/L1Scouting/interface/OrbitCollection.h new file mode 100644 index 0000000000000..d9d2c34ca75a9 --- /dev/null +++ b/DataFormats/L1Scouting/interface/OrbitCollection.h @@ -0,0 +1,135 @@ +#ifndef DataFormats_L1Scouting_OrbitCollection_h +#define DataFormats_L1Scouting_OrbitCollection_h + +#include "DataFormats/Common/interface/CMS_CLASS_VERSION.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/Span.h" + +#include +#include + +template +class OrbitCollection { +public: + typedef typename std::vector::iterator iterator; + typedef typename std::vector::const_iterator const_iterator; + typedef T value_type; + typedef typename std::vector::size_type size_type; + + // Initialize the offset vector with 0s from 0 to 3565. + // BX range is [1,3564], an extra entry is needed for the offserts of the last BX + OrbitCollection() : bxOffsets_(orbitBufferSize_ + 1, 0), data_(0) {} + // Construct the flat orbit collection starting from an OrbitBuffer. + // The method fillAndClear will be used, meaning that, after copying the objects, + // orbitBuffer's vectors will be cleared. + OrbitCollection(std::vector>& orbitBuffer, unsigned nObjects = 0) + : bxOffsets_(orbitBufferSize_ + 1, 0), data_(nObjects) { + fillAndClear(orbitBuffer, nObjects); + } + + OrbitCollection(const OrbitCollection& other) = default; + OrbitCollection(OrbitCollection&& other) = default; + OrbitCollection& operator=(const OrbitCollection& other) = default; + OrbitCollection& operator=(OrbitCollection&& other) = default; + + // Fill the orbit collection starting from a vector of vectors, one per BX. + // Objects are copied into a flat data vector, and a second vector is used to keep track + // of the starting index in the data vector for every BX. + // After the copy, the original input buffer is cleared. + // Input vector must be sorted with increasing BX and contain 3565 elements (BX in [1,3564]) + void fillAndClear(std::vector>& orbitBuffer, unsigned nObjects = 0) { + if (orbitBuffer.size() != orbitBufferSize_) + throw cms::Exception("OrbitCollection::fillAndClear") + << "Trying to fill the collection by passing an orbit buffer with incorrect size. " + << "Passed " << orbitBuffer.size() << ", expected 3565"; + data_.reserve(nObjects); + bxOffsets_[0] = 0; + unsigned bxIdx = 1; + for (auto& bxVec : orbitBuffer) { + // increase offset by the currect vec size + bxOffsets_[bxIdx] = bxOffsets_[bxIdx - 1] + bxVec.size(); + + // if bxVec contains something, copy it into the data_ vector + // and clear original bxVec objects + if (bxVec.size() > 0) { + data_.insert(data_.end(), bxVec.begin(), bxVec.end()); + bxVec.clear(); + } + + // increment bx index + bxIdx++; + } + } + + // iterate over all elements contained in data + const_iterator begin() const { return data_.begin(); } + const_iterator end() const { return data_.end(); } + + // iterate over elements of a bx + edm::Span bxIterator(unsigned bx) const { + if (bx >= orbitBufferSize_) + throw cms::Exception("OrbitCollection::bxIterator") << "Trying to access and object outside the orbit range. " + << " BX = " << bx; + if (getBxSize(bx) > 0) { + return edm::Span(data_.begin() + bxOffsets_[bx], data_.begin() + bxOffsets_[bx + 1]); + } else { + return edm::Span(end(), end()); + } + } + + // get number of objects stored in a BX + int getBxSize(unsigned bx) const { + if (bx >= orbitBufferSize_) { + cms::Exception("OrbitCollection") << "Called getBxSize() of a bx out of the orbit range." + << " BX = " << bx; + return 0; + } + return bxOffsets_[bx + 1] - bxOffsets_[bx]; + } + + // get i-th object from BX + const T& getBxObject(unsigned bx, unsigned i) const { + if (bx >= orbitBufferSize_) + throw cms::Exception("OrbitCollection::getBxObject") << "Trying to access and object outside the orbit range. " + << " BX = " << bx; + if (i >= getBxSize(bx)) + throw cms::Exception("OrbitCollection::getBxObject") + << "Trying to get element " << i << " but for" + << " BX = " << bx << " there are " << getBxSize(bx) << " elements."; + + return data_[bxOffsets_[bx] + i]; + } + + // get the list of non empty BXs + std::vector getFilledBxs() const { + std::vector filledBxVec; + if (!data_.empty()) { + for (unsigned bx = 0; bx < orbitBufferSize_; bx++) { + if ((bxOffsets_[bx + 1] - bxOffsets_[bx]) > 0) + filledBxVec.push_back(bx); + } + } + return filledBxVec; + } + + int size() const { return data_.size(); } + + T& operator[](std::size_t i) { return data_[i]; } + const T& operator[](std::size_t i) const { return data_[i]; } + + // used by ROOT storage + CMS_CLASS_VERSION(3) + +private: + // store data vector and BX offsets as flat vectors. + // offset contains one entry per BX, indicating the starting index + // of the objects for that BX. + std::vector bxOffsets_; + std::vector data_; + + // there are 3564 BX in one orbtit [1,3564], one extra + // count added to keep first entry of the vector + static constexpr int orbitBufferSize_ = 3565; +}; + +#endif // DataFormats_L1Scouting_OrbitCollection_h diff --git a/DataFormats/L1Scouting/src/classes.h b/DataFormats/L1Scouting/src/classes.h new file mode 100644 index 0000000000000..e9c045dd13f21 --- /dev/null +++ b/DataFormats/L1Scouting/src/classes.h @@ -0,0 +1,6 @@ +#include "DataFormats/Common/interface/RefProd.h" +#include "DataFormats/Common/interface/Wrapper.h" + +#include "DataFormats/L1Scouting/interface/OrbitCollection.h" +#include "DataFormats/L1Scouting/interface/L1ScoutingMuon.h" +#include "DataFormats/L1Scouting/interface/L1ScoutingCalo.h" \ No newline at end of file diff --git a/DataFormats/L1Scouting/src/classes_def.xml b/DataFormats/L1Scouting/src/classes_def.xml new file mode 100644 index 0000000000000..994fe65b0d442 --- /dev/null +++ b/DataFormats/L1Scouting/src/classes_def.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/DataFormats/L1Scouting/test/BuildFile.xml b/DataFormats/L1Scouting/test/BuildFile.xml new file mode 100644 index 0000000000000..2448764be48d5 --- /dev/null +++ b/DataFormats/L1Scouting/test/BuildFile.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/DataFormats/L1Scouting/test/TestL1ScoutingFormat.sh b/DataFormats/L1Scouting/test/TestL1ScoutingFormat.sh new file mode 100755 index 0000000000000..3ef6057274e9a --- /dev/null +++ b/DataFormats/L1Scouting/test/TestL1ScoutingFormat.sh @@ -0,0 +1,11 @@ +#!/bin/sh -ex + +function die { echo $1: status $2 ; exit $2; } + +LOCAL_TEST_DIR=${SCRAM_TEST_PATH} + +cmsRun ${LOCAL_TEST_DIR}/create_L1Scouting_test_file_cfg.py || die 'Failure using create_L1Scouting_test_file_cfg.py' $? + +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 diff --git a/DataFormats/L1Scouting/test/TestReadL1Scouting.cc b/DataFormats/L1Scouting/test/TestReadL1Scouting.cc new file mode 100644 index 0000000000000..b39f5f8b7547c --- /dev/null +++ b/DataFormats/L1Scouting/test/TestReadL1Scouting.cc @@ -0,0 +1,333 @@ +#include "DataFormats/L1Scouting/interface/L1ScoutingMuon.h" +#include "DataFormats/L1Scouting/interface/L1ScoutingCalo.h" +#include "DataFormats/L1Scouting/interface/OrbitCollection.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/global/EDAnalyzer.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" +#include "FWCore/Utilities/interface/EDGetToken.h" +#include "FWCore/Utilities/interface/Exception.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include "FWCore/Utilities/interface/StreamID.h" + +#include +#include +#include + +namespace edmtest { + using namespace l1ScoutingRun3; + class TestReadL1Scouting : public edm::global::EDAnalyzer<> { + public: + TestReadL1Scouting(edm::ParameterSet const&); + void analyze(edm::StreamID, edm::Event const&, edm::EventSetup const&) const override; + static void fillDescriptions(edm::ConfigurationDescriptions&); + + private: + void analyzeMuons(edm::Event const& iEvent) const; + void analyzeJets(edm::Event const& iEvent) const; + void analyzeEGammas(edm::Event const& iEvent) const; + void analyzeTaus(edm::Event const& iEvent) const; + void analyzeBxSums(edm::Event const& iEvent) const; + + void throwWithMessageFromConstructor(const char*) const; + void throwWithMessage(const char*) const; + + const std::vector bxValues_; + + const std::vector expectedMuonValues_; + const edm::EDGetTokenT> muonsToken_; + + const std::vector expectedJetValues_; + const edm::EDGetTokenT> jetsToken_; + + const std::vector expectedEGammaValues_; + const edm::EDGetTokenT> eGammasToken_; + + const std::vector expectedTauValues_; + const edm::EDGetTokenT> tausToken_; + + const std::vector expectedBxSumsValues_; + const edm::EDGetTokenT> bxSumsToken_; + }; + + TestReadL1Scouting::TestReadL1Scouting(edm::ParameterSet const& iPSet) + : bxValues_(iPSet.getParameter>("bxValues")), + expectedMuonValues_(iPSet.getParameter>("expectedMuonValues")), + muonsToken_(consumes(iPSet.getParameter("muonsTag"))), + expectedJetValues_(iPSet.getParameter>("expectedJetValues")), + jetsToken_(consumes(iPSet.getParameter("jetsTag"))), + expectedEGammaValues_(iPSet.getParameter>("expectedEGammaValues")), + eGammasToken_(consumes(iPSet.getParameter("eGammasTag"))), + expectedTauValues_(iPSet.getParameter>("expectedTauValues")), + tausToken_(consumes(iPSet.getParameter("tausTag"))), + expectedBxSumsValues_(iPSet.getParameter>("expectedBxSumsValues")), + bxSumsToken_(consumes(iPSet.getParameter("bxSumsTag"))) { + if (bxValues_.size() != 2) { + throwWithMessageFromConstructor("bxValues must have 2 elements and it does not"); + } + if (expectedMuonValues_.size() != 3) { + throwWithMessageFromConstructor("muonValues must have 3 elements and it does not"); + } + if (expectedJetValues_.size() != 4) { + throwWithMessageFromConstructor("jetValues must have 4 elements and it does not"); + } + if (expectedEGammaValues_.size() != 3) { + throwWithMessageFromConstructor("eGammaValues must have 3 elements and it does not"); + } + if (expectedTauValues_.size() != 2) { + throwWithMessageFromConstructor("tauValues must have 2 elements and it does not"); + } + if (expectedBxSumsValues_.size() != 1) { + throwWithMessageFromConstructor("bxSumsValues_ must have 1 elements and it does not"); + } + } + + void TestReadL1Scouting::analyze(edm::StreamID, edm::Event const& iEvent, edm::EventSetup const&) const { + analyzeMuons(iEvent); + analyzeJets(iEvent); + analyzeEGammas(iEvent); + analyzeTaus(iEvent); + analyzeBxSums(iEvent); + } + + void TestReadL1Scouting::analyzeMuons(edm::Event const& iEvent) const { + auto const& muonsCollection = iEvent.get(muonsToken_); + + for (const unsigned& bx : bxValues_) { + unsigned nMuons = muonsCollection.getBxSize(bx); + if (nMuons != expectedMuonValues_.size()) { + throwWithMessage("analyzeMuons, muons do not have the expected bx size"); + } + + const auto& muons = muonsCollection.bxIterator(bx); + for (unsigned i = 0; i < nMuons; i++) { + if (muons[i].hwPt() != expectedMuonValues_[i]) { + throwWithMessage("analyzeMuons, hwPt does not match the expected value"); + } + if (muons[i].hwEta() != expectedMuonValues_[i]) { + throwWithMessage("analyzeMuons, hwEta does not match the expected value"); + } + if (muons[i].hwPhi() != expectedMuonValues_[i]) { + throwWithMessage("analyzeMuons, hwPhi does not match the expected value"); + } + if (muons[i].hwQual() != expectedMuonValues_[i]) { + throwWithMessage("analyzeMuons, hwQual does not match the expected value"); + } + if (muons[i].hwCharge() != expectedMuonValues_[i]) { + throwWithMessage("analyzeMuons, hwCharge does not match the expected value"); + } + if (muons[i].hwChargeValid() != expectedMuonValues_[i]) { + throwWithMessage("analyzeMuons, hwChargeValid does not match the expected value"); + } + if (muons[i].hwIso() != expectedMuonValues_[i]) { + throwWithMessage("analyzeMuons, hwIso does not match the expected value"); + } + if (muons[i].hwIndex() != expectedMuonValues_[i]) { + throwWithMessage("analyzeMuons, hwIndex does not match the expected value"); + } + if (muons[i].hwEtaAtVtx() != expectedMuonValues_[i]) { + throwWithMessage("analyzeMuons, hwEtaAtVtx does not match the expected value"); + } + if (muons[i].hwPhiAtVtx() != expectedMuonValues_[i]) { + throwWithMessage("analyzeMuons, hwPhiAtVtx does not match the expected value"); + } + if (muons[i].hwPtUnconstrained() != expectedMuonValues_[i]) { + throwWithMessage("analyzeMuons, hwPtUnconstrained does not match the expected value"); + } + if (muons[i].hwDXY() != expectedMuonValues_[i]) { + throwWithMessage("analyzeMuons, hwDXY does not match the expected value"); + } + if (muons[i].tfMuonIndex() != expectedMuonValues_[i]) { + throwWithMessage("analyzeMuons, tfMuonIndex does not match the expected value"); + } + } + } + } + + void TestReadL1Scouting::analyzeJets(edm::Event const& iEvent) const { + auto const& jetsCollection = iEvent.get(jetsToken_); + + for (const unsigned& bx : bxValues_) { + unsigned nJets = jetsCollection.getBxSize(bx); + if (nJets != expectedJetValues_.size()) { + throwWithMessage("analyzeJets, jets do not have the expected bx size"); + } + + const auto& jets = jetsCollection.bxIterator(bx); + for (unsigned i = 0; i < nJets; i++) { + if (jets[i].hwEt() != expectedJetValues_[i]) { + throwWithMessage("analyzeJets, hwEt does not match the expected value"); + } + if (jets[i].hwEta() != expectedJetValues_[i]) { + throwWithMessage("analyzeJets, hwEta does not match the expected value"); + } + if (jets[i].hwPhi() != expectedJetValues_[i]) { + throwWithMessage("analyzeJets, hwPhi does not match the expected value"); + } + if (jets[i].hwIso() != expectedJetValues_[i]) { + throwWithMessage("analyzeJets, hwIso does not match the expected value"); + } + } + } + } + + void TestReadL1Scouting::analyzeEGammas(edm::Event const& iEvent) const { + auto const& eGammasCollection = iEvent.get(eGammasToken_); + + for (const unsigned& bx : bxValues_) { + unsigned nEGammas = eGammasCollection.getBxSize(bx); + if (nEGammas != expectedEGammaValues_.size()) { + throwWithMessage("analyzeEGammas, egammas do not have the expected bx size"); + } + + const auto& eGammas = eGammasCollection.bxIterator(bx); + for (unsigned i = 0; i < nEGammas; i++) { + if (eGammas[i].hwEt() != expectedEGammaValues_[i]) { + throwWithMessage("analyzeEGammas, hwEt does not match the expected value"); + } + if (eGammas[i].hwEta() != expectedEGammaValues_[i]) { + throwWithMessage("analyzeEGammas, hwEta does not match the expected value"); + } + if (eGammas[i].hwPhi() != expectedEGammaValues_[i]) { + throwWithMessage("analyzeEGammas, hwPhi does not match the expected value"); + } + if (eGammas[i].hwIso() != expectedEGammaValues_[i]) { + throwWithMessage("analyzeEGammas, hwIso does not match the expected value"); + } + } + } + } + + void TestReadL1Scouting::analyzeTaus(edm::Event const& iEvent) const { + auto const& tausCollection = iEvent.get(tausToken_); + + for (const unsigned& bx : bxValues_) { + unsigned nTaus = tausCollection.getBxSize(bx); + if (nTaus != expectedTauValues_.size()) { + throwWithMessage("analyzeTaus, taus do not have the expected bx size"); + } + + const auto& taus = tausCollection.bxIterator(bx); + for (unsigned i = 0; i < nTaus; i++) { + if (taus[i].hwEt() != expectedTauValues_[i]) { + throwWithMessage("analyzeTaus, hwEt does not match the expected value"); + } + if (taus[i].hwEta() != expectedTauValues_[i]) { + throwWithMessage("analyzeTaus, hwEta does not match the expected value"); + } + if (taus[i].hwPhi() != expectedTauValues_[i]) { + throwWithMessage("analyzeTaus, hwPhi does not match the expected value"); + } + if (taus[i].hwIso() != expectedTauValues_[i]) { + throwWithMessage("analyzeTaus, hwIso does not match the expected value"); + } + } + } + } + + void TestReadL1Scouting::analyzeBxSums(edm::Event const& iEvent) const { + auto const& bxSumsCollection = iEvent.get(bxSumsToken_); + + for (const unsigned& bx : bxValues_) { + unsigned nSums = bxSumsCollection.getBxSize(bx); + if (nSums != expectedBxSumsValues_.size()) { + throwWithMessage("analyzeBxSums, sums do not have the expected bx size"); + } + + const auto& sums = bxSumsCollection.bxIterator(bx); + for (unsigned i = 0; i < nSums; i++) { + if (sums[i].hwTotalEt() != expectedBxSumsValues_[i]) { + throwWithMessage("analyzeBxSums, hwTotalEt does not match the expected value"); + } + if (sums[i].hwTotalEtEm() != expectedBxSumsValues_[i]) { + throwWithMessage("analyzeBxSums, hwTotalEtEm does not match the expected value"); + } + if (sums[i].hwTotalHt() != expectedBxSumsValues_[i]) { + throwWithMessage("analyzeBxSums, hwTotalHt does not match the expected value"); + } + if (sums[i].hwMissEt() != expectedBxSumsValues_[i]) { + throwWithMessage("analyzeBxSums, hwMissEt does not match the expected value"); + } + if (sums[i].hwMissEtPhi() != expectedBxSumsValues_[i]) { + throwWithMessage("analyzeBxSums, hwMissEtPhi does not match the expected value"); + } + if (sums[i].hwMissHt() != expectedBxSumsValues_[i]) { + throwWithMessage("analyzeBxSums, hwMissHt does not match the expected value"); + } + if (sums[i].hwMissHtPhi() != expectedBxSumsValues_[i]) { + throwWithMessage("analyzeBxSums, hwMissHtPhi does not match the expected value"); + } + if (sums[i].hwMissEtHF() != expectedBxSumsValues_[i]) { + throwWithMessage("analyzeBxSums, hwMissEtHF does not match the expected value"); + } + if (sums[i].hwMissEtHFPhi() != expectedBxSumsValues_[i]) { + throwWithMessage("analyzeBxSums, hwMissEtHFPhi does not match the expected value"); + } + if (sums[i].hwMissHtHF() != expectedBxSumsValues_[i]) { + throwWithMessage("analyzeBxSums, hwMissHtHFPhi does not match the expected value"); + } + if (sums[i].hwAsymEt() != expectedBxSumsValues_[i]) { + throwWithMessage("analyzeBxSums, hwAsymEt does not match the expected value"); + } + if (sums[i].hwAsymHt() != expectedBxSumsValues_[i]) { + throwWithMessage("analyzeBxSums, hwAsymHt does not match the expected value"); + } + if (sums[i].hwAsymEtHF() != expectedBxSumsValues_[i]) { + throwWithMessage("analyzeBxSums, hwAsymEtHF does not match the expected value"); + } + if (sums[i].hwAsymHtHF() != expectedBxSumsValues_[i]) { + throwWithMessage("analyzeBxSums, hwAsymHtHF does not match the expected value"); + } + if (sums[i].minBiasHFP0() != expectedBxSumsValues_[i]) { + throwWithMessage("analyzeBxSums, minBiasHFP0 does not match the expected value"); + } + if (sums[i].minBiasHFM0() != expectedBxSumsValues_[i]) { + throwWithMessage("analyzeBxSums, minBiasHFM0 does not match the expected value"); + } + if (sums[i].minBiasHFP1() != expectedBxSumsValues_[i]) { + throwWithMessage("analyzeBxSums, minBiasHFP1 does not match the expected value"); + } + if (sums[i].minBiasHFM1() != expectedBxSumsValues_[i]) { + throwWithMessage("analyzeBxSums, minBiasHFM1 does not match the expected value"); + } + if (sums[i].towerCount() != expectedBxSumsValues_[i]) { + throwWithMessage("analyzeBxSums, towerCount does not match the expected value"); + } + if (sums[i].centrality() != expectedBxSumsValues_[i]) { + throwWithMessage("analyzeBxSums, centrality does not match the expected value"); + } + } + } + } + + void TestReadL1Scouting::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add>("bxValues"); + desc.add>("expectedMuonValues"); + desc.add("muonsTag"); + desc.add>("expectedJetValues"); + desc.add("jetsTag"); + desc.add>("expectedEGammaValues"); + desc.add("eGammasTag"); + desc.add>("expectedTauValues"); + desc.add("tausTag"); + desc.add>("expectedBxSumsValues"); + desc.add("bxSumsTag"); + descriptions.addDefault(desc); + } + + void TestReadL1Scouting::throwWithMessageFromConstructor(const char* msg) const { + throw cms::Exception("TestFailure") << "TestReadL1Scouting constructor, test configuration error, " << msg; + } + + void TestReadL1Scouting::throwWithMessage(const char* msg) const { + throw cms::Exception("TestFailure") << "TestReadL1Scouting analyzer, " << msg; + } + +} // namespace edmtest + +using edmtest::TestReadL1Scouting; +DEFINE_FWK_MODULE(TestReadL1Scouting); \ No newline at end of file diff --git a/DataFormats/L1Scouting/test/TestWriteL1Scouting.cc b/DataFormats/L1Scouting/test/TestWriteL1Scouting.cc new file mode 100644 index 0000000000000..62a807b4b5b18 --- /dev/null +++ b/DataFormats/L1Scouting/test/TestWriteL1Scouting.cc @@ -0,0 +1,192 @@ +#include "DataFormats/L1Scouting/interface/L1ScoutingMuon.h" +#include "DataFormats/L1Scouting/interface/L1ScoutingCalo.h" +#include "DataFormats/L1Scouting/interface/OrbitCollection.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/global/EDProducer.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" +#include "FWCore/Utilities/interface/EDPutToken.h" +#include "FWCore/Utilities/interface/StreamID.h" + +#include +#include +#include + +namespace edmtest { + using namespace l1ScoutingRun3; + class TestWriteL1Scouting : public edm::global::EDProducer<> { + public: + TestWriteL1Scouting(edm::ParameterSet const&); + void produce(edm::StreamID, edm::Event&, edm::EventSetup const&) const override; + static void fillDescriptions(edm::ConfigurationDescriptions&); + + private: + void produceMuons(edm::Event& iEvent) const; + void produceJets(edm::Event& iEvent) const; + void produceEGammas(edm::Event& iEvent) const; + void produceTaus(edm::Event& iEvent) const; + void produceBxSums(edm::Event& iEvent) const; + + void throwWithMessage(const char*) const; + + const std::vector bxValues_; + + const std::vector muonValues_; + const edm::EDPutTokenT> muonsPutToken_; + + const std::vector jetValues_; + const edm::EDPutTokenT> jetsPutToken_; + + const std::vector eGammaValues_; + const edm::EDPutTokenT> eGammasPutToken_; + + const std::vector tauValues_; + const edm::EDPutTokenT> tausPutToken_; + + const std::vector bxSumsValues_; + const edm::EDPutTokenT> bxSumsPutToken_; + }; + + TestWriteL1Scouting::TestWriteL1Scouting(edm::ParameterSet const& iPSet) + : bxValues_(iPSet.getParameter>("bxValues")), + muonValues_(iPSet.getParameter>("muonValues")), + muonsPutToken_(produces()), + jetValues_(iPSet.getParameter>("jetValues")), + jetsPutToken_(produces()), + eGammaValues_(iPSet.getParameter>("eGammaValues")), + eGammasPutToken_(produces()), + tauValues_(iPSet.getParameter>("tauValues")), + tausPutToken_(produces()), + bxSumsValues_(iPSet.getParameter>("bxSumsValues")), + bxSumsPutToken_(produces()) { + if (bxValues_.size() != 2) { + throwWithMessage("bxValues must have 2 elements and it does not"); + } + if (muonValues_.size() != 3) { + throwWithMessage("muonValues must have 3 elements and it does not"); + } + if (jetValues_.size() != 4) { + throwWithMessage("jetValues must have 4 elements and it does not"); + } + if (eGammaValues_.size() != 3) { + throwWithMessage("eGammaValues must have 3 elements and it does not"); + } + if (tauValues_.size() != 2) { + throwWithMessage("tauValues must have 2 elements and it does not"); + } + if (bxSumsValues_.size() != 1) { + throwWithMessage("bxSumsValues_ must have 1 elements and it does not"); + } + } + + void TestWriteL1Scouting::produce(edm::StreamID, edm::Event& iEvent, edm::EventSetup const&) const { + produceMuons(iEvent); + produceJets(iEvent); + produceEGammas(iEvent); + produceTaus(iEvent); + produceBxSums(iEvent); + } + + void TestWriteL1Scouting::produceMuons(edm::Event& iEvent) const { + std::unique_ptr muons(new l1ScoutingRun3::MuonOrbitCollection); + + std::vector> orbitBufferMuons(3565); + int nMuons = 0; + for (const unsigned& bx : bxValues_) { + for (const int& val : muonValues_) { + orbitBufferMuons[bx].emplace_back(val, val, val, val, val, val, val, val, val, val, val, val); + nMuons++; + } + } + + muons->fillAndClear(orbitBufferMuons, nMuons); + iEvent.put(muonsPutToken_, std::move(muons)); + } + + void TestWriteL1Scouting::produceJets(edm::Event& iEvent) const { + std::unique_ptr jets(new l1ScoutingRun3::JetOrbitCollection); + + std::vector> orbitBufferJets(3565); + int nJets = 0; + for (const unsigned& bx : bxValues_) { + for (const int& val : jetValues_) { + orbitBufferJets[bx].emplace_back(val, val, val, val); + nJets++; + } + } + + jets->fillAndClear(orbitBufferJets, nJets); + iEvent.put(jetsPutToken_, std::move(jets)); + } + + void TestWriteL1Scouting::produceEGammas(edm::Event& iEvent) const { + std::unique_ptr eGammas(new l1ScoutingRun3::EGammaOrbitCollection); + + std::vector> orbitBufferEGammas(3565); + int nEGammas = 0; + for (const unsigned& bx : bxValues_) { + for (const int& val : eGammaValues_) { + orbitBufferEGammas[bx].emplace_back(val, val, val, val); + nEGammas++; + } + } + + eGammas->fillAndClear(orbitBufferEGammas, nEGammas); + iEvent.put(eGammasPutToken_, std::move(eGammas)); + } + + void TestWriteL1Scouting::produceTaus(edm::Event& iEvent) const { + std::unique_ptr taus(new l1ScoutingRun3::TauOrbitCollection); + + std::vector> orbitBufferTaus(3565); + int nTaus = 0; + for (const unsigned& bx : bxValues_) { + for (const int& val : tauValues_) { + orbitBufferTaus[bx].emplace_back(val, val, val, val); + nTaus++; + } + } + + taus->fillAndClear(orbitBufferTaus, nTaus); + iEvent.put(tausPutToken_, std::move(taus)); + } + + void TestWriteL1Scouting::produceBxSums(edm::Event& iEvent) const { + std::unique_ptr bxSums(new l1ScoutingRun3::BxSumsOrbitCollection); + + std::vector> orbitBufferBxSums(3565); + int nBxSums = 0; + for (const unsigned& bx : bxValues_) { + for (const int& val : bxSumsValues_) { + orbitBufferBxSums[bx].emplace_back( + val, val, val, val, val, val, val, val, val, val, val, val, val, val, val, val, val, val, val, val, val); + nBxSums++; + } + } + + bxSums->fillAndClear(orbitBufferBxSums, nBxSums); + iEvent.put(bxSumsPutToken_, std::move(bxSums)); + } + + void TestWriteL1Scouting::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add>("bxValues"); + desc.add>("muonValues"); + desc.add>("jetValues"); + desc.add>("eGammaValues"); + desc.add>("tauValues"); + desc.add>("bxSumsValues"); + descriptions.addDefault(desc); + } + + void TestWriteL1Scouting::throwWithMessage(const char* msg) const { + throw cms::Exception("TestFailure") << "TestWriteL1Scouting constructor, test configuration error, " << msg; + } + +} // namespace edmtest + +using edmtest::TestWriteL1Scouting; +DEFINE_FWK_MODULE(TestWriteL1Scouting); \ No newline at end of file diff --git a/DataFormats/L1Scouting/test/create_L1Scouting_test_file_cfg.py b/DataFormats/L1Scouting/test/create_L1Scouting_test_file_cfg.py new file mode 100644 index 0000000000000..1f03c455497ff --- /dev/null +++ b/DataFormats/L1Scouting/test/create_L1Scouting_test_file_cfg.py @@ -0,0 +1,24 @@ +import FWCore.ParameterSet.Config as cms + +process = cms.Process("PROD") + +process.load("FWCore.MessageService.MessageLogger_cfi") + +process.source = cms.Source("EmptySource") +process.maxEvents.input = 1 + +process.l1ScoutingTestProducer = cms.EDProducer("TestWriteL1Scouting", + bxValues = cms.vuint32(42, 512), + muonValues = cms.vint32(1, 2, 3), + jetValues = cms.vint32(4, 5, 6, 7), + eGammaValues = cms.vint32(8, 9, 10), + tauValues = cms.vint32(11, 12), + bxSumsValues = cms.vint32(13) +) + +process.out = cms.OutputModule("PoolOutputModule", + fileName = cms.untracked.string('testL1Scouting.root') +) + +process.path = cms.Path(process.l1ScoutingTestProducer) +process.endPath = cms.EndPath(process.out) \ No newline at end of file diff --git a/DataFormats/L1Scouting/test/read_L1Scouting_cfg.py b/DataFormats/L1Scouting/test/read_L1Scouting_cfg.py new file mode 100644 index 0000000000000..3153934b8106a --- /dev/null +++ b/DataFormats/L1Scouting/test/read_L1Scouting_cfg.py @@ -0,0 +1,30 @@ +import FWCore.ParameterSet.Config as cms +import sys + +process = cms.Process("READ") + +process.load("FWCore.MessageService.MessageLogger_cfi") + +process.source = cms.Source("PoolSource", fileNames = cms.untracked.vstring("file:"+sys.argv[1])) +process.maxEvents.input = 1 + +process.l1ScoutingTestAnalyzer = cms.EDAnalyzer("TestReadL1Scouting", + bxValues = cms.vuint32(42, 512), + muonsTag = cms.InputTag("l1ScoutingTestProducer", "", "PROD"), + expectedMuonValues = cms.vint32(1, 2, 3), + jetsTag = cms.InputTag("l1ScoutingTestProducer", "", "PROD"), + expectedJetValues = cms.vint32(4, 5, 6, 7), + eGammasTag = cms.InputTag("l1ScoutingTestProducer", "", "PROD"), + expectedEGammaValues = cms.vint32(8, 9, 10), + tausTag = cms.InputTag("l1ScoutingTestProducer", "", "PROD"), + expectedTauValues = cms.vint32(11, 12), + bxSumsTag = cms.InputTag("l1ScoutingTestProducer", "", "PROD"), + expectedBxSumsValues = cms.vint32(13) +) + +process.out = cms.OutputModule("PoolOutputModule", + fileName = cms.untracked.string('testL1Scouting2.root') +) + +process.path = cms.Path(process.l1ScoutingTestAnalyzer) +process.endPath = cms.EndPath(process.out) \ No newline at end of file diff --git a/DataFormats/L1ScoutingRawData/BuildFile.xml b/DataFormats/L1ScoutingRawData/BuildFile.xml new file mode 100644 index 0000000000000..736e6ca08a199 --- /dev/null +++ b/DataFormats/L1ScoutingRawData/BuildFile.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/DataFormats/L1ScoutingRawData/README.md b/DataFormats/L1ScoutingRawData/README.md new file mode 100644 index 0000000000000..4c610acbe176e --- /dev/null +++ b/DataFormats/L1ScoutingRawData/README.md @@ -0,0 +1,8 @@ +# DataFormats/L1ScoutingRawData + +## L1 Trigger Scouting raw data formats + +Any changes to the L1 scouting raw data `SDSRawDataCollection` must be backwards compatible. +In order to ensure the L1 Scouting raw data formats can be read by future CMSSW releases, +there is a `TestSDSRawDataCollectionFormat` unit test, which makes use of the `TestReadSDSRawDataCollection` analyzer and the `TestWriteSDSRawDataCollection` producer. +The unit test checks that objects can be written and read properly. \ No newline at end of file diff --git a/DataFormats/L1ScoutingRawData/interface/SDSNumbering.h b/DataFormats/L1ScoutingRawData/interface/SDSNumbering.h new file mode 100644 index 0000000000000..354131e56e4ed --- /dev/null +++ b/DataFormats/L1ScoutingRawData/interface/SDSNumbering.h @@ -0,0 +1,24 @@ +#ifndef L1ScoutingRawData_SDSNumbering_h +#define L1ScoutingRawData_SDSNumbering_h + +/** + * + * This class holds the Scouting Data Source (SDS) + * numbering scheme for the Level 1 scouting system + * + */ + +class SDSNumbering { +public: + static constexpr int lastSDSId() { return MAXSDSID; } + + static constexpr int NOT_A_SDSID = -1; + static constexpr int MAXSDSID = 32; + static constexpr int GmtSDSID = 1; + static constexpr int CaloSDSID = 2; + static constexpr int GtSDSID = 4; + static constexpr int BmtfMinSDSID = 10; + static constexpr int BmtfMaxSDSID = 21; +}; + +#endif // L1ScoutingRawData_SDSNumbering_h \ No newline at end of file diff --git a/DataFormats/L1ScoutingRawData/interface/SDSRawDataCollection.h b/DataFormats/L1ScoutingRawData/interface/SDSRawDataCollection.h new file mode 100644 index 0000000000000..fe301ac437644 --- /dev/null +++ b/DataFormats/L1ScoutingRawData/interface/SDSRawDataCollection.h @@ -0,0 +1,34 @@ +#ifndef L1ScoutingRawData_SDSRawDataCollection_h +#define L1ScoutingRawData_SDSRawDataCollection_h + +#include "DataFormats/FEDRawData/interface/FEDRawData.h" +#include "DataFormats/Common/interface/traits.h" + +/** + * + * This collection holds the raw data for all the + * scouting data sources. It is a collection of FEDRawData + * + */ + +class SDSRawDataCollection : public edm::DoNotRecordParents { +public: + SDSRawDataCollection(); + + // retrive data for the scouting source at sourceId + const FEDRawData& FEDData(int sourceId) const; + + // retrive data for the scouting source at sourceId + FEDRawData& FEDData(int sourceId); + + SDSRawDataCollection(const SDSRawDataCollection&); + + void swap(SDSRawDataCollection& other) { data_.swap(other.data_); } + +private: + std::vector data_; // vector of raw data +}; + +inline void swap(SDSRawDataCollection& a, SDSRawDataCollection& b) { a.swap(b); } + +#endif // L1ScoutingRawData_SDSRawDataCollection_h \ No newline at end of file diff --git a/DataFormats/L1ScoutingRawData/src/SDSRawDataCollection.cc b/DataFormats/L1ScoutingRawData/src/SDSRawDataCollection.cc new file mode 100644 index 0000000000000..e663d30c86626 --- /dev/null +++ b/DataFormats/L1ScoutingRawData/src/SDSRawDataCollection.cc @@ -0,0 +1,10 @@ +#include "DataFormats/L1ScoutingRawData/interface/SDSRawDataCollection.h" +#include "DataFormats/L1ScoutingRawData/interface/SDSNumbering.h" + +SDSRawDataCollection::SDSRawDataCollection() : data_(SDSNumbering::lastSDSId() + 1) {} + +SDSRawDataCollection::SDSRawDataCollection(const SDSRawDataCollection& in) : data_(in.data_) {} + +const FEDRawData& SDSRawDataCollection::FEDData(int sourceId) const { return data_[sourceId]; } + +FEDRawData& SDSRawDataCollection::FEDData(int sourceId) { return data_[sourceId]; } \ No newline at end of file diff --git a/DataFormats/L1ScoutingRawData/src/classes.h b/DataFormats/L1ScoutingRawData/src/classes.h new file mode 100644 index 0000000000000..98c4a6b676b25 --- /dev/null +++ b/DataFormats/L1ScoutingRawData/src/classes.h @@ -0,0 +1,4 @@ +#include "DataFormats/Common/interface/Wrapper.h" +// #include "DataFormats/Common/interface/RefProd.h" + +#include "DataFormats/L1ScoutingRawData/interface/SDSRawDataCollection.h" \ No newline at end of file diff --git a/DataFormats/L1ScoutingRawData/src/classes_def.xml b/DataFormats/L1ScoutingRawData/src/classes_def.xml new file mode 100644 index 0000000000000..f62cced686169 --- /dev/null +++ b/DataFormats/L1ScoutingRawData/src/classes_def.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/DataFormats/L1ScoutingRawData/test/BuildFile.xml b/DataFormats/L1ScoutingRawData/test/BuildFile.xml new file mode 100644 index 0000000000000..6529e327073ec --- /dev/null +++ b/DataFormats/L1ScoutingRawData/test/BuildFile.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/DataFormats/L1ScoutingRawData/test/TestReadSDSRawDataCollection.cc b/DataFormats/L1ScoutingRawData/test/TestReadSDSRawDataCollection.cc new file mode 100644 index 0000000000000..275488fe1842e --- /dev/null +++ b/DataFormats/L1ScoutingRawData/test/TestReadSDSRawDataCollection.cc @@ -0,0 +1,73 @@ +#include "DataFormats/FEDRawData/interface/FEDRawData.h" +#include "DataFormats/L1ScoutingRawData/interface/SDSRawDataCollection.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/global/EDAnalyzer.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" +#include "FWCore/Utilities/interface/EDGetToken.h" +#include "FWCore/Utilities/interface/Exception.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include "FWCore/Utilities/interface/StreamID.h" + +#include + +namespace edmtest { + + class TestReadSDSRawDataCollection : public edm::global::EDAnalyzer<> { + public: + TestReadSDSRawDataCollection(edm::ParameterSet const&); + void analyze(edm::StreamID, edm::Event const&, edm::EventSetup const&) const override; + void throwWithMessage(const char*) const; + static void fillDescriptions(edm::ConfigurationDescriptions&); + + private: + std::vector expectedSDSData1_; + std::vector expectedSDSData2_; + edm::EDGetTokenT sdsRawDataCollectionToken_; + }; + + TestReadSDSRawDataCollection::TestReadSDSRawDataCollection(edm::ParameterSet const& iPSet) + : expectedSDSData1_(iPSet.getParameter>("expectedSDSData1")), + expectedSDSData2_(iPSet.getParameter>("expectedSDSData2")), + sdsRawDataCollectionToken_(consumes(iPSet.getParameter("sdsRawDataCollectionTag"))) {} + + void TestReadSDSRawDataCollection::analyze(edm::StreamID, edm::Event const& iEvent, edm::EventSetup const&) const { + auto const& sdsRawDataCollection = iEvent.get(sdsRawDataCollectionToken_); + auto const& sdsData1 = sdsRawDataCollection.FEDData(1); + if (sdsData1.size() != expectedSDSData1_.size()) { + throwWithMessage("sdsData1 does not have expected size"); + } + for (unsigned int i = 0; i < sdsData1.size(); ++i) { + if (sdsData1.data()[i] != expectedSDSData1_[i]) { + throwWithMessage("sdsData1 does not have expected contents"); + } + } + auto const& sdsData2 = sdsRawDataCollection.FEDData(2); + if (sdsData2.size() != expectedSDSData2_.size()) { + throwWithMessage("sdsData2 does not have expected size"); + } + for (unsigned int i = 0; i < sdsData2.size(); ++i) { + if (sdsData2.data()[i] != expectedSDSData2_[i]) { + throwWithMessage("sdsData2 does not have expected contents"); + } + } + } + + void TestReadSDSRawDataCollection::throwWithMessage(const char* msg) const { + throw cms::Exception("TestFailure") << "TestReadSDSRawDataCollection::analyze, " << msg; + } + + void TestReadSDSRawDataCollection::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add>("expectedSDSData1"); + desc.add>("expectedSDSData2"); + desc.add("sdsRawDataCollectionTag"); + descriptions.addDefault(desc); + } +} // namespace edmtest + +using edmtest::TestReadSDSRawDataCollection; +DEFINE_FWK_MODULE(TestReadSDSRawDataCollection); \ No newline at end of file diff --git a/DataFormats/L1ScoutingRawData/test/TestSDSRawDataCollectionFormat.sh b/DataFormats/L1ScoutingRawData/test/TestSDSRawDataCollectionFormat.sh new file mode 100755 index 0000000000000..2b8cf681d377f --- /dev/null +++ b/DataFormats/L1ScoutingRawData/test/TestSDSRawDataCollectionFormat.sh @@ -0,0 +1,11 @@ +#!/bin/sh -ex + +function die { echo $1: status $2 ; exit $2; } + +LOCAL_TEST_DIR=${SCRAM_TEST_PATH} + +cmsRun ${LOCAL_TEST_DIR}/create_SDSRawDataCollection_test_file_cfg.py || die 'Failure using create_SDSRawDataCollection_test_file_cfg.py' $? + +file=testSDSRawDataCollection.root + +cmsRun ${LOCAL_TEST_DIR}/read_SDSRawDataCollection_cfg.py "$file" || die "Failure using read_SDSRawDataCollection_cfg.py $file" $? \ No newline at end of file diff --git a/DataFormats/L1ScoutingRawData/test/TestWriteSDSRawDataCollection.cc b/DataFormats/L1ScoutingRawData/test/TestWriteSDSRawDataCollection.cc new file mode 100644 index 0000000000000..355958331c254 --- /dev/null +++ b/DataFormats/L1ScoutingRawData/test/TestWriteSDSRawDataCollection.cc @@ -0,0 +1,63 @@ +#include "DataFormats/FEDRawData/interface/FEDRawData.h" +#include "DataFormats/L1ScoutingRawData/interface/SDSRawDataCollection.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/global/EDProducer.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" +#include "FWCore/Utilities/interface/EDPutToken.h" +#include "FWCore/Utilities/interface/StreamID.h" + +#include +#include +#include + +namespace edmtest { + + class TestWriteSDSRawDataCollection : public edm::global::EDProducer<> { + public: + TestWriteSDSRawDataCollection(edm::ParameterSet const&); + void produce(edm::StreamID, edm::Event&, edm::EventSetup const&) const override; + static void fillDescriptions(edm::ConfigurationDescriptions&); + + private: + std::vector sdsData1_; + std::vector sdsData2_; + edm::EDPutTokenT sdsRawDataCollectionPutToken_; + }; + + TestWriteSDSRawDataCollection::TestWriteSDSRawDataCollection(edm::ParameterSet const& iPSet) + : sdsData1_(iPSet.getParameter>("SDSData1")), + sdsData2_(iPSet.getParameter>("SDSData2")), + sdsRawDataCollectionPutToken_(produces()) {} + + void TestWriteSDSRawDataCollection::produce(edm::StreamID, edm::Event& iEvent, edm::EventSetup const&) const { + auto sdsRawDataCollection = std::make_unique(); + FEDRawData& fedData1 = sdsRawDataCollection->FEDData(1); + FEDRawData& fedData2 = sdsRawDataCollection->FEDData(2); + + fedData1.resize(sdsData1_.size(), 4); + unsigned char* dataPtr1 = fedData1.data(); + for (unsigned int i = 0; i < sdsData1_.size(); ++i) { + dataPtr1[i] = sdsData1_[i]; + } + fedData2.resize(sdsData2_.size(), 4); + unsigned char* dataPtr2 = fedData2.data(); + for (unsigned int i = 0; i < sdsData2_.size(); ++i) { + dataPtr2[i] = sdsData2_[i]; + } + iEvent.put(sdsRawDataCollectionPutToken_, std::move(sdsRawDataCollection)); + } + + void TestWriteSDSRawDataCollection::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add>("SDSData1"); + desc.add>("SDSData2"); + descriptions.addDefault(desc); + } +} // namespace edmtest + +using edmtest::TestWriteSDSRawDataCollection; +DEFINE_FWK_MODULE(TestWriteSDSRawDataCollection); \ No newline at end of file diff --git a/DataFormats/L1ScoutingRawData/test/create_SDSRawDataCollection_test_file_cfg.py b/DataFormats/L1ScoutingRawData/test/create_SDSRawDataCollection_test_file_cfg.py new file mode 100644 index 0000000000000..f8dd0d6204f03 --- /dev/null +++ b/DataFormats/L1ScoutingRawData/test/create_SDSRawDataCollection_test_file_cfg.py @@ -0,0 +1,22 @@ +import FWCore.ParameterSet.Config as cms + +process = cms.Process("PROD") + +process.load("FWCore.MessageService.MessageLogger_cfi") + +process.source = cms.Source("EmptySource") +process.maxEvents.input = 1 + +process.sdsRawDataCollectionProducer = cms.EDProducer("TestWriteSDSRawDataCollection", + # Test values below are meaningless. We just make sure when we read + # we get the same values. + SDSData1 = cms.vuint32(0, 1, 2, 3), + SDSData2 = cms.vuint32(42, 43, 44, 45) +) + +process.out = cms.OutputModule("PoolOutputModule", + fileName = cms.untracked.string('testSDSRawDataCollection.root') +) + +process.path = cms.Path(process.sdsRawDataCollectionProducer) +process.endPath = cms.EndPath(process.out) \ No newline at end of file diff --git a/DataFormats/L1ScoutingRawData/test/read_SDSRawDataCollection_cfg.py b/DataFormats/L1ScoutingRawData/test/read_SDSRawDataCollection_cfg.py new file mode 100644 index 0000000000000..95e3e23d18142 --- /dev/null +++ b/DataFormats/L1ScoutingRawData/test/read_SDSRawDataCollection_cfg.py @@ -0,0 +1,21 @@ +import FWCore.ParameterSet.Config as cms +import sys + +process = cms.Process("READ") + +process.source = cms.Source("PoolSource", fileNames = cms.untracked.vstring("file:"+sys.argv[1])) +process.maxEvents.input = 1 + +process.testReadSDSDRawDataCollection = cms.EDAnalyzer("TestReadSDSRawDataCollection", + sdsRawDataCollectionTag = cms.InputTag("sdsRawDataCollectionProducer", "", "PROD"), + expectedSDSData1 = cms.vuint32(0, 1, 2, 3), + expectedSDSData2 = cms.vuint32(42, 43, 44, 45) +) + +process.out = cms.OutputModule("PoolOutputModule", + fileName = cms.untracked.string('testSDSRawDataCollection2.root') +) + +process.path = cms.Path(process.testReadSDSDRawDataCollection) + +process.endPath = cms.EndPath(process.out) \ No newline at end of file diff --git a/EventFilter/L1ScoutingRawToDigi/BuildFile.xml b/EventFilter/L1ScoutingRawToDigi/BuildFile.xml new file mode 100644 index 0000000000000..04bc54b4991df --- /dev/null +++ b/EventFilter/L1ScoutingRawToDigi/BuildFile.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/EventFilter/L1ScoutingRawToDigi/interface/blocks.h b/EventFilter/L1ScoutingRawToDigi/interface/blocks.h new file mode 100644 index 0000000000000..bb614e82e875a --- /dev/null +++ b/EventFilter/L1ScoutingRawToDigi/interface/blocks.h @@ -0,0 +1,50 @@ +#ifndef L1ScoutingRawToDigi_blocks_h +#define L1ScoutingRawToDigi_blocks_h + +#include + +namespace l1ScoutingRun3 { + + namespace ugmt { + + struct muon { + uint32_t f; + uint32_t s; + uint32_t extra; + }; + + struct block { + uint32_t bx; + uint32_t orbit; + muon mu[16]; + }; + } // namespace ugmt + + namespace demux { + + // unrolled frame block + struct block { + uint32_t header; + uint32_t bx; + uint32_t orbit; + uint32_t link0; + uint32_t jet2[6]; + uint32_t link1; + uint32_t jet1[6]; + uint32_t link2; + uint32_t egamma2[6]; + uint32_t link3; + uint32_t egamma1[6]; + uint32_t link4; + uint32_t empty[6]; + uint32_t link5; + uint32_t sum[6]; + uint32_t link6; + uint32_t tau2[6]; + uint32_t link7; + uint32_t tau1[6]; + }; + } // namespace demux + +} // namespace l1ScoutingRun3 +#endif // L1ScoutingRawToDigi_blocks_h diff --git a/EventFilter/L1ScoutingRawToDigi/interface/masks.h b/EventFilter/L1ScoutingRawToDigi/interface/masks.h new file mode 100644 index 0000000000000..349c8a8bb4ddd --- /dev/null +++ b/EventFilter/L1ScoutingRawToDigi/interface/masks.h @@ -0,0 +1,102 @@ +#ifndef L1ScoutingRawToDigi_masks_h +#define L1ScoutingRawToDigi_masks_h + +#include +#include "shifts.h" + +namespace l1ScoutingRun3 { + + namespace ugmt { + struct masksMuon { + // bx word: 16 bits used for actual bx, MS 4 bits are muon type + // 0xf intermediate, + // 0x0 final + // following 4 bits for link id + static constexpr uint32_t bx = 0x1fff; + static constexpr uint32_t interm = 0x0001; + //masks for muon 64 bits + static constexpr uint32_t phiext = 0x03ff; + static constexpr uint32_t pt = 0x01ff; + static constexpr uint32_t ptuncon = 0x00ff; // 8 bits + static constexpr uint32_t qual = 0x000f; + static constexpr uint32_t etaext = 0x01ff; + static constexpr uint32_t etaextv = 0x00ff; + static constexpr uint32_t etaexts = 0x0100; + static constexpr uint32_t iso = 0x0003; + static constexpr uint32_t chrg = 0x0001; + static constexpr uint32_t chrgv = 0x0001; + static constexpr uint32_t index = 0x007f; + static constexpr uint32_t phi = 0x03ff; + static constexpr uint32_t eta = 0x01ff; + static constexpr uint32_t etav = 0x00ff; + static constexpr uint32_t etas = 0x0100; + static constexpr uint32_t dxy = 0x0003; + }; + } // namespace ugmt + + namespace demux { + + struct masksJet { + static constexpr uint32_t ET = 0x07ff; + static constexpr uint32_t eta = 0x00ff; + static constexpr uint32_t phi = 0x00ff; + static constexpr uint32_t disp = 0x0001; + static constexpr uint32_t qual = 0x0003; + }; + + struct masksEGamma { + static constexpr uint32_t ET = 0x01ff; + static constexpr uint32_t eta = 0x00ff; + static constexpr uint32_t phi = 0x00ff; + static constexpr uint32_t iso = 0x0003; + }; + + struct masksTau { + static constexpr uint32_t ET = 0x01ff; + static constexpr uint32_t eta = 0x00ff; + static constexpr uint32_t phi = 0x00ff; + static constexpr uint32_t iso = 0x0003; + }; + + struct masksESums { + static constexpr uint32_t ETEt = 0x0fff; // Et of ET object + static constexpr uint32_t ETEttem = 0x0fff; + static constexpr uint32_t ETMinBiasHF = 0x000f; + + static constexpr uint32_t HTEt = 0x0fff; // Et of HT object + static constexpr uint32_t HTtowerCount = 0x1fff; + static constexpr uint32_t HTMinBiasHF = 0x000f; + + static constexpr uint32_t ETmissEt = 0x0fff; + static constexpr uint32_t ETmissPhi = 0x00ff; + static constexpr uint32_t ETmissASYMET = 0x00ff; + static constexpr uint32_t ETmissMinBiasHF = 0x000f; + + static constexpr uint32_t HTmissEt = 0x0fff; + static constexpr uint32_t HTmissPhi = 0x00ff; + static constexpr uint32_t HTmissASYMHT = 0x00ff; + static constexpr uint32_t HTmissMinBiasHF = 0x000f; + + static constexpr uint32_t ETHFmissEt = 0x0fff; + static constexpr uint32_t ETHFmissPhi = 0x00ff; + static constexpr uint32_t ETHFmissASYMETHF = 0x00ff; + static constexpr uint32_t ETHFmissCENT = 0x0003; + + static constexpr uint32_t HTHFmissEt = 0x0fff; + static constexpr uint32_t HTHFmissPhi = 0x00ff; + static constexpr uint32_t HTHFmissASYMHTHF = 0x00ff; + static constexpr uint32_t HTHFmissCENT = 0x0003; + }; + } // namespace demux + + struct header_masks { + static constexpr uint32_t bxmatch = 0x00ff << header_shifts::bxmatch; + static constexpr uint32_t mAcount = 0x000f << header_shifts::mAcount; + static constexpr uint32_t orbitmatch = 0x00ff << header_shifts::orbitmatch; + static constexpr uint32_t warningTestEnabled = 0x0001 << header_shifts::warningTestEnabled; + static constexpr uint32_t mBcount = 0x000f << header_shifts::mBcount; + static constexpr uint32_t sBmtfCount = 0x000f << header_shifts::sBmtfCount; + }; + +} // namespace l1ScoutingRun3 +#endif // L1ScoutingRawToDigi_masks_h diff --git a/EventFilter/L1ScoutingRawToDigi/interface/shifts.h b/EventFilter/L1ScoutingRawToDigi/interface/shifts.h new file mode 100644 index 0000000000000..5f0788c9a7a47 --- /dev/null +++ b/EventFilter/L1ScoutingRawToDigi/interface/shifts.h @@ -0,0 +1,102 @@ +#ifndef L1ScoutingRawToDigi_shifts_h +#define L1ScoutingRawToDigi_shifts_h + +#include + +namespace l1ScoutingRun3 { + + namespace ugmt { + // struct shifts{ + struct shiftsMuon { + // bx word: 16 bits used for actual bx, MS 4 bits are muon type + // 0xf intermediate, + // 0x0 final + // following 4 bits for link id + static constexpr uint32_t bx = 0; + static constexpr uint32_t interm = 31; // updated for new run3 format (tj) + // shifts for muon 64 bits + static constexpr uint32_t phiext = 0; + static constexpr uint32_t pt = 10; + static constexpr uint32_t qual = 19; + static constexpr uint32_t etaext = 23; + static constexpr uint32_t iso = 0; + static constexpr uint32_t chrg = 2; + static constexpr uint32_t chrgv = 3; + static constexpr uint32_t index = 4; + static constexpr uint32_t phi = 11; + static constexpr uint32_t eta1 = 13; + static constexpr uint32_t eta2 = 22; + static constexpr uint32_t ptuncon = 21; + static constexpr uint32_t dxy = 30; + }; + } // namespace ugmt + + namespace demux { + // struct shiftsCaloJet{ + struct shiftsJet { + static constexpr uint32_t ET = 0; + static constexpr uint32_t eta = 11; + static constexpr uint32_t phi = 19; + static constexpr uint32_t disp = 27; + static constexpr uint32_t qual = 28; + }; + + // struct shiftsCaloEGamma{ + struct shiftsEGamma { + static constexpr uint32_t ET = 0; + static constexpr uint32_t eta = 9; + static constexpr uint32_t phi = 17; + static constexpr uint32_t iso = 25; + }; + + // struct shiftsCaloTau{ + struct shiftsTau { + static constexpr uint32_t ET = 0; + static constexpr uint32_t eta = 9; + static constexpr uint32_t phi = 17; + static constexpr uint32_t iso = 25; + }; + + // struct shiftsCaloESums{ + struct shiftsESums { + static constexpr uint32_t ETEt = 0; // Et of ET object + static constexpr uint32_t ETEttem = 12; + static constexpr uint32_t ETMinBiasHF = 28; + + static constexpr uint32_t HTEt = 0; // Et of HT object + static constexpr uint32_t HTtowerCount = 12; + static constexpr uint32_t HTMinBiasHF = 28; + + static constexpr uint32_t ETmissEt = 0; + static constexpr uint32_t ETmissPhi = 12; + static constexpr uint32_t ETmissASYMET = 20; + static constexpr uint32_t ETmissMinBiasHF = 28; + + static constexpr uint32_t HTmissEt = 0; + static constexpr uint32_t HTmissPhi = 12; + static constexpr uint32_t HTmissASYMHT = 20; + static constexpr uint32_t HTmissMinBiasHF = 28; + + static constexpr uint32_t ETHFmissEt = 0; + static constexpr uint32_t ETHFmissPhi = 12; + static constexpr uint32_t ETHFmissASYMETHF = 20; + static constexpr uint32_t ETHFmissCENT = 28; + + static constexpr uint32_t HTHFmissEt = 0; + static constexpr uint32_t HTHFmissPhi = 12; + static constexpr uint32_t HTHFmissASYMHTHF = 20; + static constexpr uint32_t HTHFmissCENT = 28; + }; + } // namespace demux + + struct header_shifts { + static constexpr uint32_t bxmatch = 24; + static constexpr uint32_t mAcount = 16; + static constexpr uint32_t orbitmatch = 8; + static constexpr uint32_t warningTestEnabled = 8; + static constexpr uint32_t mBcount = 0; + static constexpr uint32_t sBmtfCount = 0; + }; + +} // namespace l1ScoutingRun3 +#endif // L1ScoutingRawToDigi_shifts_h diff --git a/EventFilter/L1ScoutingRawToDigi/plugins/BuildFile.xml b/EventFilter/L1ScoutingRawToDigi/plugins/BuildFile.xml new file mode 100644 index 0000000000000..dbb651083a6fb --- /dev/null +++ b/EventFilter/L1ScoutingRawToDigi/plugins/BuildFile.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/EventFilter/L1ScoutingRawToDigi/plugins/ScCALORawToDigi.cc b/EventFilter/L1ScoutingRawToDigi/plugins/ScCALORawToDigi.cc new file mode 100644 index 0000000000000..b635d82c66375 --- /dev/null +++ b/EventFilter/L1ScoutingRawToDigi/plugins/ScCALORawToDigi.cc @@ -0,0 +1,328 @@ +#include "EventFilter/L1ScoutingRawToDigi/plugins/ScCALORawToDigi.h" + +ScCaloRawToDigi::ScCaloRawToDigi(const edm::ParameterSet& iConfig) { + using namespace edm; + using namespace l1ScoutingRun3; + srcInputTag = iConfig.getParameter("srcInputTag"); + enableAllSums_ = iConfig.getUntrackedParameter("enableAllSums", false); + debug_ = iConfig.getUntrackedParameter("debug", false); + + orbitBufferJets_ = std::vector>(3565); + orbitBufferEGammas_ = std::vector>(3565); + orbitBufferTaus_ = std::vector>(3565); + orbitBufferEtSums_ = std::vector>(3565); + + nJetsOrbit_ = 0; + nEGammasOrbit_ = 0; + nTausOrbit_ = 0; + nEtSumsOrbit_ = 0; + + produces().setBranchAlias("JetOrbitCollection"); + produces().setBranchAlias("TauOrbitCollection"); + produces().setBranchAlias("EGammaOrbitCollection"); + produces().setBranchAlias("BxSumsOrbitCollection"); + + rawToken = consumes(srcInputTag); +} + +ScCaloRawToDigi::~ScCaloRawToDigi(){}; + +void ScCaloRawToDigi::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + using namespace edm; + using namespace l1ScoutingRun3; + + Handle ScoutingRawDataCollection; + iEvent.getByToken(rawToken, ScoutingRawDataCollection); + + const FEDRawData& sourceRawData = ScoutingRawDataCollection->FEDData(SDSNumbering::CaloSDSID); + size_t orbitSize = sourceRawData.size(); + + std::unique_ptr unpackedJets(new JetOrbitCollection); + std::unique_ptr unpackedTaus(new TauOrbitCollection); + std::unique_ptr unpackedEGammas(new EGammaOrbitCollection); + std::unique_ptr unpackedEtSums(new BxSumsOrbitCollection); + + if ((sourceRawData.size() == 0) && debug_) { + std::cout << "No raw data for CALO source\n"; + } + + // unpack current orbit and store data into the orbitBufferr + unpackOrbit(sourceRawData.data(), orbitSize); + + // fill orbit collection and clear the Bx buffer vector + unpackedJets->fillAndClear(orbitBufferJets_, nJetsOrbit_); + unpackedEGammas->fillAndClear(orbitBufferEGammas_, nEGammasOrbit_); + unpackedTaus->fillAndClear(orbitBufferTaus_, nTausOrbit_); + unpackedEtSums->fillAndClear(orbitBufferEtSums_, nEtSumsOrbit_); + + // store collections in the event + iEvent.put(std::move(unpackedJets)); + iEvent.put(std::move(unpackedTaus)); + iEvent.put(std::move(unpackedEGammas)); + iEvent.put(std::move(unpackedEtSums)); +} + +void ScCaloRawToDigi::unpackOrbit(const unsigned char* buf, size_t len) { + using namespace l1ScoutingRun3; + + // reset counters + nJetsOrbit_ = 0; + nEGammasOrbit_ = 0; + nTausOrbit_ = 0; + nEtSumsOrbit_ = 0; + + size_t pos = 0; + + while (pos < len) { + assert(pos + sizeof(demux::block) <= len); + + demux::block* bl = (demux::block*)(buf + pos); + pos += sizeof(demux::block); + + assert(pos <= len); + uint32_t orbit = bl->orbit & 0x7FFFFFFF; + uint32_t bx = bl->bx; + + if (debug_) { + std::cout << "CALO Orbit " << orbit << ", BX -> " << bx << std::endl; + } + + // unpack jets from first link + if (debug_) + std::cout << "--- Jets link 1 ---\n"; + unpackLinkJets(bl->jet1, bx); + + // unpack jets from second link + if (debug_) + std::cout << "--- Jets link 2 ---\n"; + unpackLinkJets(bl->jet2, bx); + + // unpack eg from first link + if (debug_) + std::cout << "--- E/g link 1 ---\n"; + unpackLinkEGammas(bl->egamma1, bx); + + // unpack eg from second link link + if (debug_) + std::cout << "--- E/g link 2 ---\n"; + unpackLinkEGammas(bl->egamma2, bx); + + // unpack taus from first link + if (debug_) + std::cout << "--- Taus link 1 ---\n"; + unpackLinkTaus(bl->tau1, bx); + + // unpack taus from second link + if (debug_) + std::cout << "--- Taus link 2 ---\n"; + unpackLinkTaus(bl->tau2, bx); + + // unpack et sums + if (debug_) + std::cout << "--- Sums ---\n"; + unpackEtSums(bl->sum, bx); + + } // end of bx objects +} + +void ScCaloRawToDigi::unpackLinkJets(uint32_t* dataBlock, int bx) { + using namespace l1ScoutingRun3; + + int32_t ET(0), Eta(0), Phi(0), Qual(0); + for (uint32_t i = 0; i < 6; i++) { + ET = ((dataBlock[i] >> demux::shiftsJet::ET) & demux::masksJet::ET); + + if (ET != 0) { + Eta = ((dataBlock[i] >> demux::shiftsJet::eta) & demux::masksJet::eta); + Phi = ((dataBlock[i] >> demux::shiftsJet::phi) & demux::masksJet::phi); + Qual = ((dataBlock[i] >> demux::shiftsJet::qual) & demux::masksJet::qual); + + if (Eta > 127) + Eta = Eta - 256; + + Jet jet(ET, Eta, Phi, Qual); + orbitBufferJets_[bx].push_back(jet); + nJetsOrbit_++; + + if (debug_) { + std::cout << "Jet " << i << std::endl; + std::cout << " Raw: 0x" << std::hex << dataBlock[i] << std::dec << std::endl; + printJet(jet); + } + } + } // end link jets unpacking loop +} + +void ScCaloRawToDigi::unpackLinkEGammas(uint32_t* dataBlock, int bx) { + using namespace l1ScoutingRun3; + + int32_t ET(0), Eta(0), Phi(0), Iso(0); + for (uint32_t i = 0; i < 6; i++) { + ET = ((dataBlock[i] >> demux::shiftsEGamma::ET) & demux::masksEGamma::ET); + if (ET != 0) { + Eta = ((dataBlock[i] >> demux::shiftsEGamma::eta) & demux::masksEGamma::eta); + Phi = ((dataBlock[i] >> demux::shiftsEGamma::phi) & demux::masksEGamma::phi); + Iso = ((dataBlock[i] >> demux::shiftsEGamma::iso) & demux::masksEGamma::iso); + + if (Eta > 127) + Eta = Eta - 256; + + EGamma eGamma(ET, Eta, Phi, Iso); + orbitBufferEGammas_[bx].push_back(eGamma); + nEGammasOrbit_++; + + if (debug_) { + std::cout << "E/g " << i << std::endl; + std::cout << " Raw: 0x" << std::hex << dataBlock[i] << std::dec << std::endl; + printEGamma(eGamma); + } + } + } // end link e/gammas unpacking loop +} + +void ScCaloRawToDigi::unpackLinkTaus(uint32_t* dataBlock, int bx) { + using namespace l1ScoutingRun3; + + int32_t ET(0), Eta(0), Phi(0), Iso(0); + for (uint32_t i = 0; i < 6; i++) { + ET = ((dataBlock[i] >> demux::shiftsTau::ET) & demux::masksTau::ET); + if (ET != 0) { + Eta = ((dataBlock[i] >> demux::shiftsTau::eta) & demux::masksTau::eta); + Phi = ((dataBlock[i] >> demux::shiftsTau::phi) & demux::masksTau::phi); + Iso = ((dataBlock[i] >> demux::shiftsTau::iso) & demux::masksTau::iso); + + if (Eta > 127) + Eta = Eta - 256; + + Tau tau(ET, Eta, Phi, Iso); + orbitBufferTaus_[bx].push_back(tau); + nTausOrbit_++; + + if (debug_) { + std::cout << "Tau " << i << std::endl; + std::cout << " Raw: 0x" << std::hex << dataBlock[i] << std::dec << std::endl; + printTau(tau); + } + } + } // end link taus unpacking loop +} + +void ScCaloRawToDigi::unpackEtSums(uint32_t* dataBlock, int bx) { + using namespace l1ScoutingRun3; + + BxSums bxSums; + + int32_t ETEt(0), ETEttem(0), ETMinBiasHFP0(0); // ET + int32_t HTEt(0), HTtowerCount(0), HTMinBiasHFM0(0); // HT + int32_t ETmissEt(0), ETmissPhi(0), ETmissASYMET(0), ETmissMinBiasHFP1(0); //ETMiss + int32_t HTmissEt(0), HTmissPhi(0), HTmissASYMHT(0), HTmissMinBiasHFM1(0); // HTMiss + int32_t ETHFmissEt(0), ETHFmissPhi(0), ETHFmissASYMETHF(0), ETHFmissCENT(0); // ETHFMiss + int32_t HTHFmissEt(0), HTHFmissPhi(0), HTHFmissASYMHTHF(0), HTHFmissCENT(0); // HTHFMiss + + // ET block + ETEt = ((dataBlock[0] >> demux::shiftsESums::ETEt) & demux::masksESums::ETEt); + ETEttem = ((dataBlock[0] >> demux::shiftsESums::ETEttem) & demux::masksESums::ETEttem); + + bxSums.setHwTotalEt(ETEt); + bxSums.setHwTotalEtEm(ETEttem); + + // HT block + HTEt = ((dataBlock[1] >> demux::shiftsESums::HTEt) & demux::masksESums::HTEt); + + bxSums.setHwTotalHt(HTEt); + + // ETMiss block + ETmissEt = ((dataBlock[2] >> demux::shiftsESums::ETmissEt) & demux::masksESums::ETmissEt); + ETmissPhi = ((dataBlock[2] >> demux::shiftsESums::ETmissPhi) & demux::masksESums::ETmissPhi); + + if (ETmissEt > 0) { + bxSums.setHwMissEt(ETmissEt); + bxSums.setHwMissEtPhi(ETmissPhi); + } + + // HTMiss block + HTmissEt = ((dataBlock[3] >> demux::shiftsESums::HTmissEt) & demux::masksESums::HTmissEt); + HTmissPhi = ((dataBlock[3] >> demux::shiftsESums::HTmissPhi) & demux::masksESums::HTmissPhi); + + if (HTmissEt > 0) { + bxSums.setHwMissHt(HTmissEt); + bxSums.setHwMissHtPhi(HTmissPhi); + } + + // ETHFMiss block + ETHFmissEt = ((dataBlock[4] >> demux::shiftsESums::ETHFmissEt) & demux::masksESums::ETHFmissEt); + ETHFmissPhi = ((dataBlock[4] >> demux::shiftsESums::ETHFmissPhi) & demux::masksESums::ETHFmissPhi); + + if (ETHFmissEt > 0) { + bxSums.setHwMissEtHF(ETHFmissEt); + bxSums.setHwMissEtHFPhi(ETHFmissPhi); + } + + // HTHFMiss block + HTHFmissEt = ((dataBlock[5] >> demux::shiftsESums::ETHFmissEt) & demux::masksESums::ETHFmissEt); + HTHFmissPhi = ((dataBlock[5] >> demux::shiftsESums::ETHFmissPhi) & demux::masksESums::ETHFmissPhi); + + if (HTHFmissEt > 0) { + bxSums.setHwMissHtHF(HTHFmissEt); + bxSums.setHwMissHtHFPhi(HTHFmissPhi); + } + + // Insert additional sums + if (enableAllSums_) { + // ET block + ETMinBiasHFP0 = ((dataBlock[0] >> demux::shiftsESums::ETMinBiasHF) & demux::masksESums::ETMinBiasHF); + bxSums.setMinBiasHFP0(ETMinBiasHFP0); + + // HT block + HTtowerCount = ((dataBlock[1] >> demux::shiftsESums::HTtowerCount) & demux::masksESums::HTtowerCount); + HTMinBiasHFM0 = ((dataBlock[1] >> demux::shiftsESums::HTMinBiasHF) & demux::masksESums::HTMinBiasHF); + + bxSums.setTowerCount(HTtowerCount); + bxSums.setMinBiasHFM0(HTMinBiasHFM0); + + // ET Miss block + ETmissASYMET = ((dataBlock[2] >> demux::shiftsESums::ETmissASYMET) & demux::masksESums::ETmissASYMET); + ETmissMinBiasHFP1 = ((dataBlock[2] >> demux::shiftsESums::ETmissMinBiasHF) & demux::masksESums::ETmissMinBiasHF); + bxSums.setHwAsymEt(ETmissASYMET); + bxSums.setMinBiasHFP1(ETmissMinBiasHFP1); + + // HT Miss block + HTmissASYMHT = ((dataBlock[3] >> demux::shiftsESums::HTmissASYMHT) & demux::masksESums::HTmissASYMHT); + HTmissMinBiasHFM1 = ((dataBlock[3] >> demux::shiftsESums::HTmissMinBiasHF) & demux::masksESums::HTmissMinBiasHF); + + bxSums.setHwAsymHt(HTmissASYMHT); + bxSums.setMinBiasHFM1(HTmissMinBiasHFM1); + + // ETHFMiss + ETHFmissASYMETHF = ((dataBlock[4] >> demux::shiftsESums::ETHFmissASYMETHF) & demux::masksESums::ETHFmissASYMETHF); + ETHFmissCENT = ((dataBlock[4] >> demux::shiftsESums::ETHFmissCENT) & demux::masksESums::ETHFmissCENT); + + bxSums.setHwAsymEtHF(ETHFmissASYMETHF); + + // HTHFMiss + HTHFmissASYMHTHF = ((dataBlock[5] >> demux::shiftsESums::ETHFmissASYMETHF) & demux::masksESums::ETHFmissASYMETHF); + HTHFmissCENT = ((dataBlock[5] >> demux::shiftsESums::ETHFmissCENT) & demux::masksESums::ETHFmissCENT); + + bxSums.setHwAsymHtHF(HTHFmissASYMHTHF); + bxSums.setCentrality((HTHFmissCENT << 4) + ETHFmissCENT); + } + + orbitBufferEtSums_[bx].push_back(bxSums); + nEtSumsOrbit_ += 1; + + if (debug_) { + std::cout << "Raw frames:\n"; + for (int frame = 0; frame < 6; frame++) { + std::cout << " frame " << frame << ": 0x" << std::hex << dataBlock[frame] << std::dec << std::endl; + } + printBxSums(bxSums); + } +} + +void ScCaloRawToDigi::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.setUnknown(); + descriptions.addDefault(desc); +} + +DEFINE_FWK_MODULE(ScCaloRawToDigi); diff --git a/EventFilter/L1ScoutingRawToDigi/plugins/ScCALORawToDigi.h b/EventFilter/L1ScoutingRawToDigi/plugins/ScCALORawToDigi.h new file mode 100644 index 0000000000000..ca1bcd34e1ea3 --- /dev/null +++ b/EventFilter/L1ScoutingRawToDigi/plugins/ScCALORawToDigi.h @@ -0,0 +1,53 @@ +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/MessageLogger/interface/MessageLogger.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/L1ScoutingCalo.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 + +class ScCaloRawToDigi : public edm::stream::EDProducer<> { +public: + explicit ScCaloRawToDigi(const edm::ParameterSet&); + ~ScCaloRawToDigi() 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); + + void unpackLinkJets(uint32_t* dataBlock, int bx); + void unpackLinkEGammas(uint32_t* dataBlock, int bx); + void unpackLinkTaus(uint32_t* dataBlock, int bx); + void unpackEtSums(uint32_t* dataBlock, int bx); + + int nJetsOrbit_, nEGammasOrbit_, nTausOrbit_, nEtSumsOrbit_; + // vectors holding data for every bunch crossing + // before filling the orbit collection + std::vector> orbitBufferJets_; + std::vector> orbitBufferEGammas_; + std::vector> orbitBufferTaus_; + std::vector> orbitBufferEtSums_; + + bool debug_ = false; + bool enableAllSums_ = false; + edm::InputTag srcInputTag; + edm::EDGetToken rawToken; +}; diff --git a/EventFilter/L1ScoutingRawToDigi/plugins/ScGMTRawToDigi.cc b/EventFilter/L1ScoutingRawToDigi/plugins/ScGMTRawToDigi.cc new file mode 100644 index 0000000000000..349c250d4bba2 --- /dev/null +++ b/EventFilter/L1ScoutingRawToDigi/plugins/ScGMTRawToDigi.cc @@ -0,0 +1,169 @@ +#include "EventFilter/L1ScoutingRawToDigi/plugins/ScGMTRawToDigi.h" + +ScGMTRawToDigi::ScGMTRawToDigi(const edm::ParameterSet& iConfig) { + using namespace edm; + srcInputTag = iConfig.getParameter("srcInputTag"); + debug_ = iConfig.getUntrackedParameter("debug", false); + + // initialize orbit buffer for BX 1->3564; + orbitBuffer_ = std::vector>(3565); + for (auto& bxVec : orbitBuffer_) { + bxVec.reserve(8); + } + nMuonsOrbit_ = 0; + + produces().setBranchAlias("MuonOrbitCollection"); + rawToken = consumes(srcInputTag); +} + +ScGMTRawToDigi::~ScGMTRawToDigi(){}; + +void ScGMTRawToDigi::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + using namespace edm; + + Handle ScoutingRawDataCollection; + iEvent.getByToken(rawToken, ScoutingRawDataCollection); + + const FEDRawData& sourceRawData = ScoutingRawDataCollection->FEDData(SDSNumbering::GmtSDSID); + size_t orbitSize = sourceRawData.size(); + + std::unique_ptr unpackedMuons(new l1ScoutingRun3::MuonOrbitCollection); + + if ((sourceRawData.size() == 0) && debug_) { + std::cout << "No raw data for GMT FED\n"; + } + + // unpack current orbit and store data into the orbitBufferr + unpackOrbit(sourceRawData.data(), orbitSize); + + // fill orbit collection and clear the Bx buffer vector + unpackedMuons->fillAndClear(orbitBuffer_, nMuonsOrbit_); + + // store collection in the event + iEvent.put(std::move(unpackedMuons)); +} + +void ScGMTRawToDigi::unpackOrbit(const unsigned char* buf, size_t len) { + using namespace l1ScoutingRun3; + + // reset counters + nMuonsOrbit_ = 0; + + size_t pos = 0; + + while (pos < len) { + assert(pos + 4 <= len); + + // get BX header + uint32_t header = *((uint32_t*)(buf + pos)); + pos += 4; + // count mA and mB + uint32_t mAcount = (header & header_masks::mAcount) >> header_shifts::mAcount; + uint32_t mBcount = (header & header_masks::mBcount) >> header_shifts::mBcount; + + // declare block to read + ugmt::block* bl = (ugmt::block*)(buf + pos); + pos += 4 + 4 + (mAcount + mBcount) * 12; + assert(pos <= len); + + uint32_t orbit = bl->orbit & 0x7FFFFFFF; + uint32_t bx = bl->bx; + + if (debug_) { + std::cout << "GMT Orbit " << orbit << ", BX -> " << bx << ", nMuons -> " << mAcount + mBcount << std::endl; + } + + // Unpack muons for this BX + orbitBuffer_[bx].reserve(mAcount + mBcount); + + for (unsigned int i = 0; i < mAcount + mBcount; i++) { + uint32_t interm = (bl->mu[i].extra >> ugmt::shiftsMuon::interm) & ugmt::masksMuon::interm; + if (interm == 1) { + if (debug_) { + std::cout << " -> Excluding intermediate muon\n"; + } + continue; + } + + uint32_t index = (bl->mu[i].s >> ugmt::shiftsMuon::index) & ugmt::masksMuon::index; + uint32_t ietaextu = (bl->mu[i].f >> ugmt::shiftsMuon::etaext) & ugmt::masksMuon::etaextv; + int32_t ietaext; + if (((bl->mu[i].f >> ugmt::shiftsMuon::etaext) & ugmt::masksMuon::etaexts) != 0) { + ietaext = ietaextu -= 256; + } else { + ietaext = ietaextu; + } + + // extract pt and quality and apply cut if required + int32_t iptuncon = (bl->mu[i].s >> ugmt::shiftsMuon::ptuncon) & ugmt::masksMuon::ptuncon; + int32_t ipt = (bl->mu[i].f >> ugmt::shiftsMuon::pt) & ugmt::masksMuon::pt; + if ((ipt - 1) < 0) { + continue; + } + uint32_t qual = (bl->mu[i].f >> ugmt::shiftsMuon::qual) & ugmt::masksMuon::qual; + if (qual == 0) { + continue; + } + + // extract integer value for extrapolated phi + int32_t iphiext = ((bl->mu[i].f >> ugmt::shiftsMuon::phiext) & ugmt::masksMuon::phiext); + + // extract integer value for extrapolated phi + int32_t idxy = ((bl->mu[i].s >> ugmt::shiftsMuon::dxy) & ugmt::masksMuon::dxy); + + // extract iso bits and charge + uint32_t iso = (bl->mu[i].s >> ugmt::shiftsMuon::iso) & ugmt::masksMuon::iso; + int32_t chrg = 0; + if (((bl->mu[i].s >> ugmt::shiftsMuon::chrgv) & ugmt::masksMuon::chrgv) == 1) + chrg = ((bl->mu[i].s >> ugmt::shiftsMuon::chrg) & ugmt::masksMuon::chrg) == 1 ? -1 : 1; + + // extract eta and phi at muon station + int32_t iphi = (bl->mu[i].s >> ugmt::shiftsMuon::phi) & ugmt::masksMuon::phi; + uint32_t ieta1 = (bl->mu[i].extra >> ugmt::shiftsMuon::eta1) & ugmt::masksMuon::eta; + uint32_t ieta2 = (bl->mu[i].extra >> ugmt::shiftsMuon::eta2) & ugmt::masksMuon::eta; + + uint32_t ieta_u; + int32_t ieta; + // checking if raw eta should be taken from muon 1 or muon 2 + if ((bl->mu[i].extra & 0x1) == 0) { + ieta_u = ieta1; + } else { + ieta_u = ieta2; + } + + // two's complement + if (ieta_u > 256) { + ieta = ieta_u - 512; + } else { + ieta = ieta_u; + } + + // increment muon counter + nMuonsOrbit_++; + + l1ScoutingRun3::Muon muon(ipt, ieta, iphi, qual, chrg, chrg != 0, iso, index, ietaext, iphiext, iptuncon, idxy); + + orbitBuffer_[bx].push_back(muon); + + if (debug_) { + std::cout << "--- Muon " << i << " ---\n"; + std::cout << " Raw f: 0x" << std::hex << bl->mu[i].f << std::dec << "\n"; + std::cout << " Raw s: 0x" << std::hex << bl->mu[i].s << std::dec << "\n"; + std::cout << " Raw extra: 0x" << std::hex << bl->mu[i].extra << std::dec << "\n"; + printMuon(muon); + } + + } // end of bx + + } // end orbit while loop + + //muons->flatten(); +} + +void ScGMTRawToDigi::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.setUnknown(); + descriptions.addDefault(desc); +} + +DEFINE_FWK_MODULE(ScGMTRawToDigi); diff --git a/EventFilter/L1ScoutingRawToDigi/plugins/ScGMTRawToDigi.h b/EventFilter/L1ScoutingRawToDigi/plugins/ScGMTRawToDigi.h new file mode 100644 index 0000000000000..8b1622d327304 --- /dev/null +++ b/EventFilter/L1ScoutingRawToDigi/plugins/ScGMTRawToDigi.h @@ -0,0 +1,44 @@ +#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/L1ScoutingMuon.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 ScGMTRawToDigi : public edm::stream::EDProducer<> { +public: + explicit ScGMTRawToDigi(const edm::ParameterSet&); + ~ScGMTRawToDigi() 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); + + // vector holding data for every bunch crossing + // before filling the orbit collection + std::vector> orbitBuffer_; + int nMuonsOrbit_; + + bool debug_ = false; + edm::InputTag srcInputTag; + edm::EDGetToken rawToken; +}; diff --git a/EventFilter/Utilities/BuildFile.xml b/EventFilter/Utilities/BuildFile.xml index 6a69ee301bfe8..2270817d5ce0a 100644 --- a/EventFilter/Utilities/BuildFile.xml +++ b/EventFilter/Utilities/BuildFile.xml @@ -2,6 +2,7 @@ + diff --git a/EventFilter/Utilities/interface/DAQSourceModels.h b/EventFilter/Utilities/interface/DAQSourceModels.h index d886aaf1c26a4..5727dc7aa2164 100644 --- a/EventFilter/Utilities/interface/DAQSourceModels.h +++ b/EventFilter/Utilities/interface/DAQSourceModels.h @@ -61,7 +61,9 @@ class DataMode { bool fileListMode) const = 0; virtual bool isMultiDir() { return false; } - virtual void makeDirectoryEntries(std::vector const& baseDirs, std::string const& runDir) = 0; + virtual void makeDirectoryEntries(std::vector const& baseDirs, + std::vector const& numSources, + std::string const& runDir) = 0; void setTesting(bool testing) { testing_ = testing; } protected: diff --git a/EventFilter/Utilities/interface/DAQSourceModelsFRD.h b/EventFilter/Utilities/interface/DAQSourceModelsFRD.h index bdf770836c3aa..c3e1c896ab623 100644 --- a/EventFilter/Utilities/interface/DAQSourceModelsFRD.h +++ b/EventFilter/Utilities/interface/DAQSourceModelsFRD.h @@ -64,7 +64,9 @@ class DataModeFRD : public DataMode { MAXTCDSuTCAFEDID_ = MAXTCDSuTCAFEDID; } - void makeDirectoryEntries(std::vector const& baseDirs, std::string const& runDir) override {} + void makeDirectoryEntries(std::vector const& baseDirs, + std::vector const& numSources, + std::string const& runDir) override {} std::pair> defineAdditionalFiles(std::string const& primaryName, bool) const override { return std::make_pair(true, std::vector()); @@ -171,7 +173,9 @@ class DataModeFRDStriped : public DataMode { MAXTCDSuTCAFEDID_ = MAXTCDSuTCAFEDID; } - void makeDirectoryEntries(std::vector const& baseDirs, std::string const& runDir) override; + void makeDirectoryEntries(std::vector const& baseDirs, + std::vector const& numSources, + std::string const& runDir) override; std::pair> defineAdditionalFiles(std::string const& primaryName, bool fileListMode) const override; diff --git a/EventFilter/Utilities/interface/DAQSourceModelsScouting.h b/EventFilter/Utilities/interface/DAQSourceModelsScouting.h deleted file mode 100644 index 430fdfdefd34b..0000000000000 --- a/EventFilter/Utilities/interface/DAQSourceModelsScouting.h +++ /dev/null @@ -1,268 +0,0 @@ -#ifndef EventFilter_Utilities_DAQSourceModelsScouting_h -#define EventFilter_Utilities_DAQSourceModelsScouting_h - -#include - -#include "EventFilter/Utilities/interface/DAQSourceModels.h" -#include "DataFormats/L1Trigger/interface/Muon.h" -#include "DataFormats/L1Trigger/interface/BXVector.h" - -namespace scouting { - struct muon { - uint32_t f; - uint32_t s; - }; - - struct block { - uint32_t bx; - uint32_t orbit; - muon mu[16]; - }; - - struct masks { - static constexpr uint32_t phiext = 0x3ff; - static constexpr uint32_t pt = 0x1ff; - static constexpr uint32_t qual = 0xf; - static constexpr uint32_t etaext = 0x1ff; - static constexpr uint32_t etaextv = 0xff; - static constexpr uint32_t etaexts = 0x100; - static constexpr uint32_t iso = 0x3; - static constexpr uint32_t chrg = 0x1; - static constexpr uint32_t chrgv = 0x1; - static constexpr uint32_t index = 0x7f; - static constexpr uint32_t phi = 0x3ff; - static constexpr uint32_t eta = 0x1ff; - static constexpr uint32_t etav = 0xff; - static constexpr uint32_t etas = 0x100; - static constexpr uint32_t phiv = 0x1ff; - static constexpr uint32_t phis = 0x200; - static constexpr uint32_t sv = 0x3; - }; - - struct shifts { - static constexpr uint32_t phiext = 0; - static constexpr uint32_t pt = 10; - static constexpr uint32_t qual = 19; - static constexpr uint32_t etaext = 23; - static constexpr uint32_t iso = 0; - static constexpr uint32_t chrg = 2; - static constexpr uint32_t chrgv = 3; - static constexpr uint32_t index = 4; - static constexpr uint32_t phi = 11; - static constexpr uint32_t eta = 21; - static constexpr uint32_t rsv = 30; - }; - - struct gmt_scales { - static constexpr float pt_scale = 0.5; - static constexpr float phi_scale = 2. * M_PI / 576.; - static constexpr float eta_scale = 0.0870 / 8; //9th MS bit is sign - static constexpr float phi_range = M_PI; - }; - - struct header_shifts { - static constexpr uint32_t bxmatch = 24; - static constexpr uint32_t mAcount = 16; - static constexpr uint32_t orbitmatch = 8; - static constexpr uint32_t mBcount = 0; - }; - - struct header_masks { - static constexpr uint32_t bxmatch = 0xff << header_shifts::bxmatch; - static constexpr uint32_t mAcount = 0xf << header_shifts::mAcount; - static constexpr uint32_t orbitmatch = 0xff << header_shifts::orbitmatch; - static constexpr uint32_t mBcount = 0xf; - }; - -} //namespace scouting - -class DataModeScoutingRun2Muon : public DataMode { -public: - DataModeScoutingRun2Muon(DAQSource* daqSource) : DataMode(daqSource) { - dummyLVec_ = std::make_unique>>(); - } - - ~DataModeScoutingRun2Muon() override{}; - - std::vector>& makeDaqProvenanceHelpers() override; - void readEvent(edm::EventPrincipal& eventPrincipal) override; - - int dataVersion() const override { return detectedFRDversion_; } - void detectVersion(unsigned char* fileBuf, uint32_t fileHeaderOffset) override { - detectedFRDversion_ = *((uint16_t*)(fileBuf + fileHeaderOffset)); - } - - uint32_t headerSize() const override { return FRDHeaderVersionSize[detectedFRDversion_]; } - - bool versionCheck() const override { return detectedFRDversion_ <= FRDHeaderMaxVersion; } - - uint64_t dataBlockSize() const override { return event_->size(); } - - void makeDataBlockView(unsigned char* addr, - size_t maxSize, - std::vector const& fileSizes, - size_t fileHeaderSize) override { - dataBlockAddr_ = addr; - dataBlockMax_ = maxSize; - eventCached_ = false; - nextEventView(); - eventCached_ = true; - } - - bool nextEventView() override; - bool checksumValid() override; - std::string getChecksumError() const override; - - bool isRealData() const override { return event_->isRealData(); } - - uint32_t run() const override { return event_->run(); } - - //true for scouting muon - bool dataBlockCompleted() const override { return true; } - - bool requireHeader() const override { return true; } - - bool fitToBuffer() const override { return true; } - - bool dataBlockInitialized() const override { return true; } - - void setDataBlockInitialized(bool) override{}; - - void setTCDSSearchRange(uint16_t MINTCDSuTCAFEDID, uint16_t MAXTCDSuTCAFEDID) override { return; } - - void makeDirectoryEntries(std::vector const& baseDirs, std::string const& runDir) override {} - - std::pair> defineAdditionalFiles(std::string const& primaryName, bool) const override { - return std::make_pair(true, std::vector()); - } - - char* readPayloadPos() { return (char*)event_->payload(); } - -private: - void unpackOrbit(BXVector* muons, char* buf, size_t len); - - std::vector> daqProvenanceHelpers_; - uint16_t detectedFRDversion_ = 0; - size_t headerSize_ = 0; - std::unique_ptr event_; - - std::unique_ptr>> dummyLVec_; - - unsigned char* dataBlockAddr_ = nullptr; - size_t dataBlockMax_ = 0; - bool eventCached_ = false; -}; - -class DataModeScoutingRun2Multi : public DataMode { -public: - DataModeScoutingRun2Multi(DAQSource* daqSource) : DataMode(daqSource) { - dummyLVec_ = std::make_unique>>(); - } - - ~DataModeScoutingRun2Multi() override{}; - - std::vector>& makeDaqProvenanceHelpers() override; - void readEvent(edm::EventPrincipal& eventPrincipal) override; - - int dataVersion() const override { return detectedFRDversion_; } - void detectVersion(unsigned char* fileBuf, uint32_t fileHeaderOffset) override { - detectedFRDversion_ = *((uint16_t*)(fileBuf + fileHeaderOffset)); - } - - uint32_t headerSize() const override { return FRDHeaderVersionSize[detectedFRDversion_]; } - - bool versionCheck() const override { return detectedFRDversion_ <= FRDHeaderMaxVersion; } - - uint64_t dataBlockSize() const override { - //TODO: adjust to multiple objects - return events_[0]->size(); - } - - void makeDataBlockView(unsigned char* addr, - size_t maxSize, - std::vector const& fileSizes, - size_t fileHeaderSize) override { - fileHeaderSize_ = fileHeaderSize; - numFiles_ = fileSizes.size(); - //add offset address for each file payload - startAddrs_.clear(); - startAddrs_.push_back(addr); - dataBlockAddrs_.clear(); - dataBlockAddrs_.push_back(addr); - dataBlockMaxAddrs_.clear(); - dataBlockMaxAddrs_.push_back(addr + fileSizes[0] - fileHeaderSize); - auto fileAddr = addr; - for (unsigned int i = 1; i < fileSizes.size(); i++) { - fileAddr += fileSizes[i - 1]; - startAddrs_.push_back(fileAddr); - dataBlockAddrs_.push_back(fileAddr); - dataBlockMaxAddrs_.push_back(fileAddr + fileSizes[i] - fileHeaderSize); - } - - dataBlockMax_ = maxSize; - blockCompleted_ = false; - //set event cached as we set initial address here - bool result = makeEvents(); - assert(result); - eventCached_ = true; - setDataBlockInitialized(true); - } - - bool nextEventView() override; - bool checksumValid() override; - std::string getChecksumError() const override; - - bool isRealData() const override { - assert(!events_.empty()); - return events_[0]->isRealData(); - } - - uint32_t run() const override { - assert(!events_.empty()); - return events_[0]->run(); - } - - //true for DAQ3 FRD - bool dataBlockCompleted() const override { return blockCompleted_; } - - bool requireHeader() const override { return true; } - - bool dataBlockInitialized() const override { return dataBlockInitialized_; } - - void setDataBlockInitialized(bool val) override { dataBlockInitialized_ = val; }; - - void setTCDSSearchRange(uint16_t MINTCDSuTCAFEDID, uint16_t MAXTCDSuTCAFEDID) override { return; } - - void makeDirectoryEntries(std::vector const& baseDirs, std::string const& runDir) override { - //receive directory paths for multiple input files ('striped') - } - - std::pair> defineAdditionalFiles(std::string const& primaryName, - bool fileListMode) const override; - -private: - bool makeEvents(); - void unpackMuonOrbit(BXVector* muons, char* buf, size_t len); - - std::vector> daqProvenanceHelpers_; - uint16_t detectedFRDversion_ = 0; - size_t headerSize_ = 0; - std::vector> events_; - - std::unique_ptr>> dummyLVec_; - - unsigned char* dataBlockAddr_ = nullptr; - - //debugging - std::vector startAddrs_; - std::vector dataBlockAddrs_; - std::vector dataBlockMaxAddrs_; - size_t dataBlockMax_ = 0; - size_t fileHeaderSize_ = 0; - short numFiles_ = 0; - bool eventCached_ = false; - bool dataBlockInitialized_ = false; - bool blockCompleted_ = true; -}; - -#endif // EventFilter_Utilities_DAQSourceModelsScouting_h diff --git a/EventFilter/Utilities/interface/DAQSourceModelsScoutingRun3.h b/EventFilter/Utilities/interface/DAQSourceModelsScoutingRun3.h new file mode 100644 index 0000000000000..8692df494c738 --- /dev/null +++ b/EventFilter/Utilities/interface/DAQSourceModelsScoutingRun3.h @@ -0,0 +1,135 @@ +#ifndef EventFilter_Utilities_DAQSourceModelsScoutingRun3_h +#define EventFilter_Utilities_DAQSourceModelsScoutingRun3_h + +#include "EventFilter/Utilities/interface/DAQSource.h" +#include "EventFilter/Utilities/interface/DAQSourceModels.h" +#include "DataFormats/L1ScoutingRawData/interface/SDSRawDataCollection.h" +#include "DataFormats/L1ScoutingRawData/interface/SDSNumbering.h" + +#include "FWCore/Framework/interface/Event.h" +#include "DataFormats/Provenance/interface/EventAuxiliary.h" +#include "DataFormats/Provenance/interface/EventID.h" + +#include +#include +#include +#include +#include +#include + +class DataModeScoutingRun3 : public DataMode { +public: + DataModeScoutingRun3(DAQSource* daqSource) : DataMode(daqSource) {} + ~DataModeScoutingRun3() override{}; + std::vector>& makeDaqProvenanceHelpers() override; + void readEvent(edm::EventPrincipal& eventPrincipal) override; + + void fillSDSRawDataCollection(SDSRawDataCollection& rawData, char* buff, size_t len); + + //reuse FRD file and event headers + int dataVersion() const override { return detectedFRDversion_; } + void detectVersion(unsigned char* fileBuf, uint32_t fileHeaderOffset) override { + detectedFRDversion_ = *((uint16_t*)(fileBuf + fileHeaderOffset)); + } + uint32_t headerSize() const override { return FRDHeaderVersionSize[detectedFRDversion_]; } + bool versionCheck() const override { return detectedFRDversion_ <= FRDHeaderMaxVersion; } + + uint64_t dataBlockSize() const override { + // get event size from the first data source (main) + return events_[0]->size(); + } + + void makeDataBlockView(unsigned char* addr, + size_t maxSize, + std::vector const& fileSizes, + size_t fileHeaderSize) override { + fileHeaderSize_ = fileHeaderSize; + numFiles_ = fileSizes.size(); + + // initalize vectors keeping tracks of valid orbits and completed blocks + sourceValidOrbitPair_.clear(); + completedBlocks_.clear(); + for (unsigned int i = 0; i < fileSizes.size(); i++) { + completedBlocks_.push_back(false); + } + + //add offset address for each file payload + dataBlockAddrs_.clear(); + dataBlockAddrs_.push_back(addr); + dataBlockMaxAddrs_.clear(); + dataBlockMaxAddrs_.push_back(addr + fileSizes[0] - fileHeaderSize); + auto fileAddr = addr; + for (unsigned int i = 1; i < fileSizes.size(); i++) { + fileAddr += fileSizes[i - 1]; + dataBlockAddrs_.push_back(fileAddr); + dataBlockMaxAddrs_.push_back(fileAddr + fileSizes[i] - fileHeaderSize); + } + + dataBlockMax_ = maxSize; + blockCompleted_ = false; + //set event cached as we set initial address here + bool result = makeEvents(); + assert(result); + eventCached_ = true; + setDataBlockInitialized(true); + } + + bool nextEventView() override; + bool checksumValid() override; + std::string getChecksumError() const override; + + bool isRealData() const override { + assert(!events_.empty()); + return events_[0]->isRealData(); + } + + uint32_t run() const override { + assert(!events_.empty()); + return events_[0]->run(); + } + + bool dataBlockCompleted() const override { return blockCompleted_; } + + bool requireHeader() const override { return true; } + + bool fitToBuffer() const override { return true; } + + bool dataBlockInitialized() const override { return dataBlockInitialized_; } + + void setDataBlockInitialized(bool val) override { dataBlockInitialized_ = val; }; + + void setTCDSSearchRange(uint16_t MINTCDSuTCAFEDID, uint16_t MAXTCDSuTCAFEDID) override { return; } + + void makeDirectoryEntries(std::vector const& baseDirs, + std::vector const& numSources, + std::string const& runDir) override; + + std::pair> defineAdditionalFiles(std::string const& primaryName, + bool fileListMode) const override; + +private: + bool makeEvents(); + std::vector> daqProvenanceHelpers_; // + uint16_t detectedFRDversion_ = 0; + size_t fileHeaderSize_ = 0; + size_t headerSize_ = 0; + std::vector> events_; + unsigned char* dataBlockAddr_ = nullptr; + std::vector dataBlockAddrs_; + std::vector dataBlockMaxAddrs_; + size_t dataBlockMax_ = 0; + short numFiles_ = 0; + bool dataBlockInitialized_ = false; + bool blockCompleted_ = true; + bool eventCached_ = false; + std::vector buPaths_; + std::vector buNumSources_; + + // keep track of valid (=aligned) orbits from different data sources + std::vector> sourceValidOrbitPair_; + unsigned int currOrbit_ = 0xFFFFFFFF; + + std::vector completedBlocks_; +}; + +#endif // EventFilter_Utilities_DAQSourceModelsScoutingRun3_h \ No newline at end of file diff --git a/EventFilter/Utilities/interface/EvFDaqDirector.h b/EventFilter/Utilities/interface/EvFDaqDirector.h index 45886d16b0f83..1cbe71014a824 100644 --- a/EventFilter/Utilities/interface/EvFDaqDirector.h +++ b/EventFilter/Utilities/interface/EvFDaqDirector.h @@ -194,6 +194,7 @@ namespace evf { bool inputThrottled(); bool lumisectionDiscarded(unsigned int ls); std::vector const& getBUBaseDirs() const { return bu_base_dirs_all_; } + std::vector const& getBUBaseDirsNSources() const { return bu_base_dirs_nSources_; } private: bool bumpFile(unsigned int& ls, @@ -216,6 +217,7 @@ namespace evf { std::string base_dir_; std::string bu_base_dir_; std::vector bu_base_dirs_all_; + std::vector bu_base_dirs_nSources_; unsigned int run_; bool useFileBroker_; bool fileBrokerHostFromCfg_; diff --git a/EventFilter/Utilities/plugins/DumpMuonScouting.cc b/EventFilter/Utilities/plugins/DumpMuonScouting.cc deleted file mode 100644 index 4f1b37b030b4c..0000000000000 --- a/EventFilter/Utilities/plugins/DumpMuonScouting.cc +++ /dev/null @@ -1,112 +0,0 @@ -/// -/// \class l1t::DumpMuonScouting.cc -/// -/// Description: Dump/Analyze Moun Scouting stored in BXVector -/// -/// Implementation: -/// Based off of Michael Mulhearn's YellowParamTester -/// -/// \author: Brian Winer Ohio State -/// - -// -// This simple module simply retreives the YellowParams object from the event -// setup, and sends its payload as an INFO message, for debugging purposes. -// - -#include "FWCore/Framework/interface/MakerMacros.h" - -// system include files -#include -#include -#include - -// user include files -// base class -#include "FWCore/Framework/interface/stream/EDAnalyzer.h" - -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "FWCore/Utilities/interface/EDGetToken.h" -#include "FWCore/Utilities/interface/InputTag.h" -#include "FWCore/Framework/interface/EventSetup.h" -#include "FWCore/Framework/interface/Frameworkfwd.h" - -#include "DataFormats/L1Trigger/interface/Muon.h" - -#include "FWCore/MessageLogger/interface/MessageLogger.h" -#include "FWCore/MessageLogger/interface/MessageDrop.h" - -using namespace edm; -using namespace std; - -// class declaration -class DumpMuonScouting : public edm::stream::EDAnalyzer<> { -public: - explicit DumpMuonScouting(const edm::ParameterSet&); - ~DumpMuonScouting() override{}; - void analyze(const edm::Event&, const edm::EventSetup&) override; - - EDGetTokenT> muToken; - - int m_minBx; - int m_maxBx; - -private: - int m_tvVersion; -}; - -DumpMuonScouting::DumpMuonScouting(const edm::ParameterSet& iConfig) { - muToken = consumes(iConfig.getParameter("muInputTag")); - - m_minBx = iConfig.getParameter("minBx"); - m_maxBx = iConfig.getParameter("maxBx"); -} - -// loop over events -void DumpMuonScouting::analyze(const edm::Event& iEvent, const edm::EventSetup& evSetup) { - //input - Handle> muons = iEvent.getHandle(muToken); - - { - cout << " ----------------------------------------------------- " << endl; - cout << " *********** Run " << std::dec << iEvent.id().run() << " Event " << iEvent.id().event() - << " ************** " << endl; - cout << " ----------------------------------------------------- " << endl; - - //Loop over BX - for (int i = m_minBx; i <= m_maxBx; ++i) { - //Loop over Muons - //cout << " ------ Muons --------" << endl; - if (muons.isValid()) { - if (i >= muons->getFirstBX() && i <= muons->getLastBX()) { - for (std::vector::const_iterator mu = muons->begin(i); mu != muons->end(i); ++mu) { - cout << " " << std::dec << std::setw(2) << std::setfill(' ') << std::setfill('0') << ")"; - cout << " Pt " << std::dec << std::setw(3) << mu->hwPt() << " (0x" << std::hex << std::setw(3) - << std::setfill('0') << mu->hwPt() << ")"; - cout << " EtaAtVtx " << std::dec << std::setw(3) << mu->hwEtaAtVtx() << " (0x" << std::hex << std::setw(3) - << std::setfill('0') << (mu->hwEtaAtVtx() & 0x1ff) << ")"; - cout << " Eta " << std::dec << std::setw(3) << mu->hwEta() << " (0x" << std::hex << std::setw(3) - << std::setfill('0') << (mu->hwEta() & 0x1ff) << ")"; - cout << " PhiAtVtx " << std::dec << std::setw(3) << mu->hwPhiAtVtx() << " (0x" << std::hex << std::setw(3) - << std::setfill('0') << mu->hwPhiAtVtx() << ")"; - cout << " Phi " << std::dec << std::setw(3) << mu->hwPhi() << " (0x" << std::hex << std::setw(3) - << std::setfill('0') << mu->hwPhi() << ")"; - cout << " Iso " << std::dec << std::setw(1) << mu->hwIso(); - cout << " Qual " << std::dec << std::setw(1) << mu->hwQual(); - cout << " Chrg " << std::dec << std::setw(1) << mu->hwCharge(); - cout << endl; - } - } else { - cout << "No Muons stored for this bx " << i << endl; - } - } else { - cout << "No Muon Data in this event " << endl; - } - - } //loop over Bx - cout << std::dec << endl; - } //if dumpGtRecord -} - -DEFINE_FWK_MODULE(DumpMuonScouting); diff --git a/EventFilter/Utilities/scripts/scoutingToRaw.py b/EventFilter/Utilities/scripts/scoutingToRaw.py deleted file mode 100755 index d6ce51feae7ad..0000000000000 --- a/EventFilter/Utilities/scripts/scoutingToRaw.py +++ /dev/null @@ -1,259 +0,0 @@ -#!/bin/env python3 - -import struct -import os,sys -import json -import shutil - -os.umask(0) - -#struct muon{ -# uint32_t f; -# uint32_t s; -#}; - -#struct block{ -# uint32_t bx; -# uint32_t orbit; -# muon mu[16]; -#}; - -#class masks: -# phiext = 0x3ff -# pt = 0x1ff -# qual = 0xf -# etaext = 0x1ff -# etaextv = 0xff -# etaexts = 0x100 -# iso = 0x3 -# chrg = 0x1 -# chrgv = 0x1 -# index = 0x7f -# phi = 0x3ff -# eta = 0x1ff -# etav = 0xff -# etas = 0x100 -# phiv = 0x1ff -# phis = 0x200 -# sv = 0x3 - -#class shifts: -# phiext = 0 -# pt = 10 -# qual = 19 -# etaext = 23 -# iso = 0 -# chrg = 2 -# chrgv = 3 -# index = 4 -# phi = 11 -# eta = 21 -# rsv = 30 - -#class gmt_scales: -# pt_scale = 0.5 -# phi_scale = 2.*M_PI/576. -# eta_scale = 0.0870/8 #9th MS bit is sign -# phi_range = M_PI - - -#need to read this to find orbit ("event") boundary and calculate size per orbit -class header_shifts: - bxmatch = 32; - mAcount = 16; - orbitmatch = 8; - mBcount = 0; - -class header_masks: - bxmatch = 0xff << header_shifts.bxmatch; - mAcount = 0xf << header_shifts.mAcount; - orbitmatch = 0xff << header_shifts.orbitmatch; - mBcount = 0xf - - -#new V2 FRD file header (32 bytes) -class frd_file_header_v2: - ver_id = "RAW_0002".encode() # 64 (offset 0B) - header_size = 32 #16 (offset 8B) - data_type = 20 #16 (offset 10) - event_count = 0 #32 (offset 12B) - run_number = 0 #32 (offset 16B) - lumisection = 0 #32 (offset 20B) - file_size = 0 #64 (offset 24B) - - -def parseMuonScoutingRawFile(infilepath, outdir, rn_override, maxorbits): - - if infilepath != 'stdin': - fin = open(infilepath,'rb') - else: - fin = sys.stdin.buffer - - #sys.stdout.flush() - - #orbit count per file - orbitcount=0 - #total - orbitcount_total=0 - - last_ls = 0 - - orbit_data = bytes() - orbit_nr = 0 - orbit_size = 0 - flags = 0 - c_crc32c = 0 - - #ls = 1 - #event header (FRD format) const - version = 6 - - #files - fout = None - if infilepath != 'stdin': - fin = open(infilepath,'rb') - else: - fin = sys.stdin.buffer - - - #write header before closing the file - def update_header(): - nonlocal orbitcount - nonlocal last_ls - h = frd_file_header_v2() - h.event_count = orbitcount - h.run_number = rn_override - h.lumisection = last_ls - h.file_size = fout.tell() - fout.seek(0, 0) - fout.write(frd_file_header_v2.ver_id) - fout.write(struct.pack('H',h.header_size)) - fout.write(struct.pack('H',h.data_type)) - fout.write(struct.pack('I',h.event_count)) - fout.write(struct.pack('I',h.run_number)) - fout.write(struct.pack('I',h.lumisection)) - fout.write(struct.pack('Q',h.file_size)) - - orbitcount = 0 - print(h.ver_id, h.header_size, h.data_type, h.event_count, h.lumisection, h.file_size) - - - #write orbit when next one is detected or file is closed - def write_orbit(): - nonlocal orbit_size - nonlocal orbit_data - if not orbit_size: - return - - #print(fout.tell(), struct.pack('H',version)) - fout.write(struct.pack('H',version)) #could be 8 bytes - fout.write(struct.pack('H',flags)) #could be 8 bytes - fout.write(struct.pack('I',rn_override)) #run - #fout.write(struct.pack('I',ls)) #ls - fout.write(struct.pack('I',last_ls)) #ls - fout.write(struct.pack('I',orbit_nr)) #eid (orbit number, 32-bit) - fout.write(struct.pack('I',orbit_size)) #payload size - fout.write(struct.pack('I',c_crc32c)) #payload checksum (not used) - fout.write(orbit_data) - - orbit_data = bytes() - orbit_size = 0 - - def writeout_close(): - write_orbit() - update_header() - fout.close() - orbit_nr = 0 - - #read loop - while True: - - #check if exceeded max orbits specified - if orbitcount_total > maxorbits: - print(f"finish: {orbitcount_total-1}/{maxorbits} orbits") - writeout_close() - - if infilepath != 'stdin': - fin.close() - sys.exit(0) - - try: - h_raw = fin.read(4) - bxmatch = struct.unpack('B', h_raw[3:4])[0] - mAcount = struct.unpack('B', h_raw[2:3])[0] - orbitmatch = struct.unpack('B', h_raw[1:2])[0] - mBcount = struct.unpack('B', h_raw[0:1])[0] - - #print("bxmatch", bxmatch, "mA", mAcount, "orbitmatch", orbitmatch, "mB", mBcount) - - bx_raw = fin.read(4) - bx = struct.unpack('i', bx_raw)[0] - #print("bx",bx) - orbit_raw = fin.read(4) - orbit = struct.unpack('i', orbit_raw)[0] - - new_ls = orbit >> 18 - - if new_ls > last_ls: - #open a new output file if crossing LS boundary or on first orbit - if last_ls: - write_orbit() - update_header() - fout.close() - orbitcount = 0 - - last_ls = new_ls - fout = open(os.path.join(outdir, f'run{rn_override}_ls{str(new_ls).zfill(4)}_index000000.raw') ,'wb') - #empty file header, will be updated later - fout.write(frd_file_header_v2.ver_id) -# fout.write(bytes(16)) - fout.write(bytes(24)) - - read_len = 8*(mAcount+mBcount) - mu_blk = fin.read(8*(mAcount+mBcount)) - if len(mu_blk) != read_len: - print('incomplete read') - sys.exit(1) - - if not orbit_nr or orbit != orbit_nr: - #received new orbit, write previous one - if orbit_nr: - write_orbit() - - #should not decrease: - if orbit < orbit_nr: - orbit_count = -1 - print("got smaller orbit than earlier!") - sys.exit(1) - - print("new orbit", orbit) - orbit_nr = orbit - - #per LS file counter: - orbitcount += 1 - #total counter: - orbitcount_total += 1 - - #update orbit size and data variables - orbit_size += 12 + read_len - orbit_data += (h_raw + bx_raw + orbit_raw) + mu_blk - - except Exception as ex: - #reached premature end of the file? - print(f"exception: {ex}") - #writeout_close() - #if infilepath != 'stdin': - # fin.close() - sys.exit(1) - - #print count," : ",version,run,lumi,eid,esize,crc32c,"override id/ls/run:",count,1,rn_override - #lumi=1 - -if len(sys.argv) < 5: - print("parameters: input file (or stdin), output directory, run number (use same as input file), orbits to write") -else: - parseMuonScoutingRawFile(sys.argv[1], sys.argv[2], int(sys.argv[3]), int(sys.argv[4])) - - - - diff --git a/EventFilter/Utilities/src/DAQSource.cc b/EventFilter/Utilities/src/DAQSource.cc index b607b13ca1dd0..266d043300b9a 100644 --- a/EventFilter/Utilities/src/DAQSource.cc +++ b/EventFilter/Utilities/src/DAQSource.cc @@ -7,7 +7,7 @@ #include "EventFilter/Utilities/interface/DAQSource.h" #include "EventFilter/Utilities/interface/DAQSourceModels.h" #include "EventFilter/Utilities/interface/DAQSourceModelsFRD.h" -#include "EventFilter/Utilities/interface/DAQSourceModelsScouting.h" +#include "EventFilter/Utilities/interface/DAQSourceModelsScoutingRun3.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/InputSourceDescription.h" @@ -81,6 +81,8 @@ DAQSource::DAQSource(edm::ParameterSet const& pset, edm::InputSourceDescription dataMode_.reset(new DataModeFRD(this)); } else if (dataModeConfig_ == "FRDStriped") { dataMode_.reset(new DataModeFRDStriped(this)); + } else if (dataModeConfig_ == "ScoutingRun3") { + dataMode_.reset(new DataModeScoutingRun3(this)); } else throw cms::Exception("DAQSource::DAQSource") << "Unknown data mode " << dataModeConfig_; @@ -101,7 +103,8 @@ DAQSource::DAQSource(edm::ParameterSet const& pset, edm::InputSourceDescription } } - dataMode_->makeDirectoryEntries(daqDirector_->getBUBaseDirs(), daqDirector_->runString()); + dataMode_->makeDirectoryEntries( + daqDirector_->getBUBaseDirs(), daqDirector_->getBUBaseDirsNSources(), daqDirector_->runString()); auto& daqProvenanceHelpers = dataMode_->makeDaqProvenanceHelpers(); for (const auto& daqProvenanceHelper : daqProvenanceHelpers) diff --git a/EventFilter/Utilities/src/DAQSourceModelsFRD.cc b/EventFilter/Utilities/src/DAQSourceModelsFRD.cc index c0dc23cdedeab..2784cef60ec55 100644 --- a/EventFilter/Utilities/src/DAQSourceModelsFRD.cc +++ b/EventFilter/Utilities/src/DAQSourceModelsFRD.cc @@ -153,7 +153,9 @@ std::string DataModeFRD::getChecksumError() const { * FRD Multi Test */ -void DataModeFRDStriped::makeDirectoryEntries(std::vector const& baseDirs, std::string const& runDir) { +void DataModeFRDStriped::makeDirectoryEntries(std::vector const& baseDirs, + std::vector const& numSources, + std::string const& runDir) { std::filesystem::path runDirP(runDir); for (auto& baseDir : baseDirs) { std::filesystem::path baseDirP(baseDir); diff --git a/EventFilter/Utilities/src/DAQSourceModelsScouting.cc b/EventFilter/Utilities/src/DAQSourceModelsScouting.cc deleted file mode 100644 index 4626975e6014e..0000000000000 --- a/EventFilter/Utilities/src/DAQSourceModelsScouting.cc +++ /dev/null @@ -1,312 +0,0 @@ -#include "EventFilter/Utilities/interface/DAQSource.h" -#include "EventFilter/Utilities/interface/DAQSourceModelsScouting.h" - -#include -#include -#include -#include - -#include "FWCore/Framework/interface/Event.h" -#include "DataFormats/Provenance/interface/EventAuxiliary.h" -#include "DataFormats/Provenance/interface/EventID.h" - -using namespace scouting; - -void DataModeScoutingRun2Muon::readEvent(edm::EventPrincipal& eventPrincipal) { - edm::TimeValue_t time; - timeval stv; - gettimeofday(&stv, nullptr); - time = stv.tv_sec; - time = (time << 32) + stv.tv_usec; - edm::Timestamp tstamp(time); - - std::unique_ptr> rawData(new BXVector); - //allow any bx - rawData->setBXRange(0, 4000); - - unpackOrbit(rawData.get(), (char*)event_->payload(), event_->eventSize()); - - uint32_t hdrEventID = event_->event(); - edm::EventID eventID = edm::EventID(daqSource_->eventRunNumber(), daqSource_->currentLumiSection(), hdrEventID); - edm::EventAuxiliary aux( - eventID, daqSource_->processGUID(), tstamp, event_->isRealData(), edm::EventAuxiliary::PhysicsTrigger); - - aux.setProcessHistoryID(daqSource_->processHistoryID()); - daqSource_->makeEventWrapper(eventPrincipal, aux); - - std::unique_ptr edp(new edm::Wrapper>(std::move(rawData))); - eventPrincipal.put( - daqProvenanceHelpers_[0]->branchDescription(), std::move(edp), daqProvenanceHelpers_[0]->dummyProvenance()); -} - -void DataModeScoutingRun2Muon::unpackOrbit(BXVector* muons, char* buf, size_t len) { - using namespace scouting; - size_t pos = 0; - uint32_t o_test = 0; - while (pos < len) { - assert(pos + 4 <= len); - uint32_t header = *((uint32*)(buf + pos)); - uint32_t mAcount = (header & header_masks::mAcount) >> header_shifts::mAcount; - uint32_t mBcount = (header & header_masks::mBcount) >> header_shifts::mBcount; - - block* bl = (block*)(buf + pos + 4); - - pos += 12 + (mAcount + mBcount) * 8; - assert(pos <= len); - - uint32_t bx = bl->bx; - - uint32_t orbit = bl->orbit; - o_test = orbit; - - //should cuts should be applied - bool excludeIntermediate = true; - - for (size_t i = 0; i < (mAcount + mBcount); i++) { - //unpack new muon - //variables: index, ietaext, ipt, qual, iphiext, iso, chrg, iphi, ieta - - // remove intermediate if required - // index==0 and ietaext==0 are a necessary and sufficient condition - uint32_t index = (bl->mu[i].s >> shifts::index) & masks::index; - int32_t ietaext = ((bl->mu[i].f >> shifts::etaext) & masks::etaextv); - if (((bl->mu[i].f >> shifts::etaext) & masks::etaexts) != 0) - ietaext -= 256; - - if (excludeIntermediate && index == 0 && ietaext == 0) - continue; - - //extract pt and quality and apply cut if required - uint32_t ipt = (bl->mu[i].f >> shifts::pt) & masks::pt; - //cuts?? - // if((ipt-1)mu[i].f >> shifts::qual) & masks::qual; - // if(qual < qualcut) {discarded++; continue;} - - //extract integer value for extrapolated phi - int32_t iphiext = ((bl->mu[i].f >> shifts::phiext) & masks::phiext); - - // extract iso bits and charge - uint32_t iso = (bl->mu[i].s >> shifts::iso) & masks::iso; - int32_t chrg = 0; - if (((bl->mu[i].s >> shifts::chrgv) & masks::chrgv) == 1) { - chrg = ((bl->mu[i].s >> shifts::chrg) & masks::chrg) == 1 ? -1 : 1; - } - - // extract eta and phi at muon station - int32_t iphi = ((bl->mu[i].s >> shifts::phi) & masks::phi); - int32_t ieta = (bl->mu[i].s >> shifts::eta) & masks::etav; - if (((bl->mu[i].s >> shifts::eta) & masks::etas) != 0) - ieta -= 256; - - l1t::Muon muon( - *dummyLVec_, ipt, ieta, iphi, qual, chrg, chrg != 0, iso, -1, 0, false, 0, 0, 0, 0, ietaext, iphiext); - muons->push_back(bx, muon); - } - } - std::cout << "end read ... " << o_test << std::endl << std::flush; -} //unpackOrbit - -std::vector>& DataModeScoutingRun2Muon::makeDaqProvenanceHelpers() { - //set FRD data collection - daqProvenanceHelpers_.clear(); - daqProvenanceHelpers_.emplace_back(std::make_shared( - edm::TypeID(typeid(l1t::MuonBxCollection)), "l1t::MuonBxCollection", "l1tMuonBxCollection", "DAQSource")); - return daqProvenanceHelpers_; -} - -bool DataModeScoutingRun2Muon::nextEventView() { - if (eventCached_) - return true; - event_ = std::make_unique(dataBlockAddr_); - if (event_->size() > dataBlockMax_) { - throw cms::Exception("DAQSource::getNextEvent") - << " event id:" << event_->event() << " lumi:" << event_->lumi() << " run:" << event_->run() - << " of size:" << event_->size() << " bytes does not fit into a chunk of size:" << dataBlockMax_ << " bytes"; - } - return true; -} - -bool DataModeScoutingRun2Muon::checksumValid() { return true; } - -std::string DataModeScoutingRun2Muon::getChecksumError() const { return std::string(); } - -// -//2nd model: read multiple input files with different data type -// - -std::pair> DataModeScoutingRun2Multi::defineAdditionalFiles( - std::string const& primaryName, bool fileListMode) const { - std::vector additionalFiles; - - auto fullpath = std::filesystem::path(primaryName); - auto fullname = fullpath.filename(); - std::string stem = fullname.stem().string(); - std::string ext = fullname.extension().string(); - std::regex regexz("_"); - std::vector nameTokens = {std::sregex_token_iterator(stem.begin(), stem.end(), regexz, -1), - std::sregex_token_iterator()}; - - if (nameTokens.size() < 3) { - throw cms::Exception("DAQSource::getNextEvent") - << primaryName << " name doesn't start with run#_ls#_index#_*.ext syntax"; - } - - //Can also filter out non-matching primary files (if detected by DaqDirector). false will tell source to skip the primary file. - if (nameTokens.size() > 3 && nameTokens[3].rfind("secondary", 0) == 0) - return std::make_pair(false, additionalFiles); - - //TODO: provisional, name syntax should be better defined - - additionalFiles.push_back(fullpath.parent_path().string() + "/" + nameTokens[0] + "_" + nameTokens[1] + "_" + - nameTokens[2] + "_secondary" + ext); - //additionalFiles.push_back(fullpath.parent_path.string() + "/" + nameTokens[0] + "_" + nameTokens[1] + "_" + nameTokens[2] + "_tertiary" + ".raw"); - - return std::make_pair(true, additionalFiles); -} - -void DataModeScoutingRun2Multi::readEvent(edm::EventPrincipal& eventPrincipal) { - edm::TimeValue_t time; - timeval stv; - gettimeofday(&stv, nullptr); - time = stv.tv_sec; - time = (time << 32) + stv.tv_usec; - edm::Timestamp tstamp(time); - - std::unique_ptr> rawData(new BXVector); - //allow any bx - rawData->setBXRange(0, 4000); - - unpackMuonOrbit(rawData.get(), (char*)events_[0]->payload(), events_[0]->eventSize()); - - //TODO: implement here other object type (e.g. unpackCaloOrbit) - // - std::unique_ptr> rawDataSec(new BXVector); - //allow any bx - rawDataSec->setBXRange(0, 4000); - - unpackMuonOrbit(rawDataSec.get(), (char*)events_[1]->payload(), events_[1]->eventSize()); - - uint32_t hdrEventID = events_[0]->event(); //take from 1st file - edm::EventID eventID = edm::EventID(daqSource_->eventRunNumber(), daqSource_->currentLumiSection(), hdrEventID); - edm::EventAuxiliary aux( - eventID, daqSource_->processGUID(), tstamp, events_[0]->isRealData(), edm::EventAuxiliary::PhysicsTrigger); - - aux.setProcessHistoryID(daqSource_->processHistoryID()); - daqSource_->makeEventWrapper(eventPrincipal, aux); - - std::unique_ptr edp(new edm::Wrapper>(std::move(rawData))); - eventPrincipal.put( - daqProvenanceHelpers_[0]->branchDescription(), std::move(edp), daqProvenanceHelpers_[0]->dummyProvenance()); - - //TODO: use other object and provenance helper (duplicate is just for demonstration) - // std::unique_ptr edpSec(new edm::Wrapper>(std::move(rawDataSec))); - // eventPrincipal.put(daqProvenanceHelpers_[1]->branchDescription(), std::move(edpSec), daqProvenanceHelpers_[1]->dummyProvenance()); - - eventCached_ = false; -} - -void DataModeScoutingRun2Multi::unpackMuonOrbit(BXVector* muons, char* buf, size_t len) { - using namespace scouting; - size_t pos = 0; - //uint32_t o_test = 0; - while (pos < len) { - assert(pos + 4 <= len); - uint32_t header = *((uint32*)(buf + pos)); - uint32_t mAcount = (header & header_masks::mAcount) >> header_shifts::mAcount; - uint32_t mBcount = (header & header_masks::mBcount) >> header_shifts::mBcount; - - block* bl = (block*)(buf + pos + 4); - - pos += 12 + (mAcount + mBcount) * 8; - assert(pos <= len); - - uint32_t bx = bl->bx; - - //uint32_t orbit = bl->orbit; - //o_test = orbit; - - //should cuts should be applied - bool excludeIntermediate = true; - - for (size_t i = 0; i < (mAcount + mBcount); i++) { - //unpack new muon - //variables: index, ietaext, ipt, qual, iphiext, iso, chrg, iphi, ieta - - // remove intermediate if required - // index==0 and ietaext==0 are a necessary and sufficient condition - uint32_t index = (bl->mu[i].s >> shifts::index) & masks::index; - int32_t ietaext = ((bl->mu[i].f >> shifts::etaext) & masks::etaextv); - if (((bl->mu[i].f >> shifts::etaext) & masks::etaexts) != 0) - ietaext -= 256; - - if (excludeIntermediate && index == 0 && ietaext == 0) - continue; - - //extract pt and quality and apply cut if required - uint32_t ipt = (bl->mu[i].f >> shifts::pt) & masks::pt; - //cuts?? - // if((ipt-1)mu[i].f >> shifts::qual) & masks::qual; - // if(qual < qualcut) {discarded++; continue;} - - //extract integer value for extrapolated phi - int32_t iphiext = ((bl->mu[i].f >> shifts::phiext) & masks::phiext); - - // extract iso bits and charge - uint32_t iso = (bl->mu[i].s >> shifts::iso) & masks::iso; - int32_t chrg = 0; - if (((bl->mu[i].s >> shifts::chrgv) & masks::chrgv) == 1) { - chrg = ((bl->mu[i].s >> shifts::chrg) & masks::chrg) == 1 ? -1 : 1; - } - - // extract eta and phi at muon station - int32_t iphi = ((bl->mu[i].s >> shifts::phi) & masks::phi); - int32_t ieta = (bl->mu[i].s >> shifts::eta) & masks::etav; - if (((bl->mu[i].s >> shifts::eta) & masks::etas) != 0) - ieta -= 256; - - l1t::Muon muon( - *dummyLVec_, ipt, ieta, iphi, qual, chrg, chrg != 0, iso, -1, 0, false, 0, 0, 0, 0, ietaext, iphiext); - muons->push_back(bx, muon); - } - } -} //unpackOrbit - -std::vector>& DataModeScoutingRun2Multi::makeDaqProvenanceHelpers() { - //set FRD data collection - daqProvenanceHelpers_.clear(); - daqProvenanceHelpers_.emplace_back(std::make_shared( - edm::TypeID(typeid(l1t::MuonBxCollection)), "l1t::MuonBxCollection", "l1tMuonBxCollection", "DAQSource")); - //Note: two same kind of objects can not be put in the event from the source, so this example will be changed - daqProvenanceHelpers_.emplace_back(std::make_shared( - edm::TypeID(typeid(l1t::MuonBxCollection)), "l1t::MuonBxCollection", "l1tMuonBxCollection", "DAQSource")); - return daqProvenanceHelpers_; -} - -bool DataModeScoutingRun2Multi::nextEventView() { - blockCompleted_ = false; - if (eventCached_) - return true; - for (unsigned int i = 0; i < events_.size(); i++) { - //add last event length.. - dataBlockAddrs_[i] += events_[i]->size(); - } - return makeEvents(); -} - -bool DataModeScoutingRun2Multi::makeEvents() { - events_.clear(); - for (int i = 0; i < numFiles_; i++) { - if (dataBlockAddrs_[i] >= dataBlockMaxAddrs_[i]) { - blockCompleted_ = true; - return false; - } - events_.emplace_back(std::make_unique(dataBlockAddrs_[i])); - } - return true; -} - -bool DataModeScoutingRun2Multi::checksumValid() { return true; } - -std::string DataModeScoutingRun2Multi::getChecksumError() const { return std::string(); } diff --git a/EventFilter/Utilities/src/DAQSourceModelsScoutingRun3.cc b/EventFilter/Utilities/src/DAQSourceModelsScoutingRun3.cc new file mode 100644 index 0000000000000..f856fdbed66ef --- /dev/null +++ b/EventFilter/Utilities/src/DAQSourceModelsScoutingRun3.cc @@ -0,0 +1,184 @@ +#include "EventFilter//Utilities/interface/DAQSourceModelsScoutingRun3.h" + +void DataModeScoutingRun3::makeDirectoryEntries(std::vector const& baseDirs, + std::vector const& numSources, + std::string const& runDir) { + std::filesystem::path runDirP(runDir); + for (auto& baseDir : baseDirs) { + std::filesystem::path baseDirP(baseDir); + buPaths_.emplace_back(baseDirP / runDirP); + } + + // store the number of sources in each BU + buNumSources_ = numSources; +} + +std::pair> DataModeScoutingRun3::defineAdditionalFiles(std::string const& primaryName, + bool fileListMode) const { + std::vector additionalFiles; + + if (fileListMode) { + // Expected file naming when working in file list mode + for (int j = 1; j < buNumSources_[0]; j++) { + additionalFiles.push_back(primaryName + "_" + std::to_string(j)); + } + return std::make_pair(true, additionalFiles); + } + + auto fullpath = std::filesystem::path(primaryName); + auto fullname = fullpath.filename(); + + for (size_t i = 0; i < buPaths_.size(); i++) { + std::filesystem::path newPath = buPaths_[i] / fullname; + + if (i != 0) { + // secondary files from other ramdisks + additionalFiles.push_back(newPath.generic_string()); + } + + // add extra sources from the same ramdisk + for (int j = 1; j < buNumSources_[i]; j++) { + additionalFiles.push_back(newPath.generic_string() + "_" + std::to_string(j)); + } + } + return std::make_pair(true, additionalFiles); +} + +void DataModeScoutingRun3::readEvent(edm::EventPrincipal& eventPrincipal) { + assert(!events_.empty()); + + edm::TimeValue_t time; + timeval stv; + gettimeofday(&stv, nullptr); + time = stv.tv_sec; + time = (time << 32) + stv.tv_usec; + edm::Timestamp tstamp(time); + + // set provenance helpers + uint32_t hdrEventID = currOrbit_; + edm::EventID eventID = edm::EventID(daqSource_->eventRunNumber(), daqSource_->currentLumiSection(), hdrEventID); + edm::EventAuxiliary aux( + eventID, daqSource_->processGUID(), tstamp, events_[0]->isRealData(), edm::EventAuxiliary::PhysicsTrigger); + + aux.setProcessHistoryID(daqSource_->processHistoryID()); + daqSource_->makeEventWrapper(eventPrincipal, aux); + + // create scouting raw data collection + std::unique_ptr rawData(new SDSRawDataCollection); + + // Fill the ScoutingRawDataCollection with valid orbit data from the multiple sources + for (const auto& pair : sourceValidOrbitPair_) { + fillSDSRawDataCollection(*rawData, (char*)events_[pair.second]->payload(), events_[pair.second]->eventSize()); + } + + std::unique_ptr edp(new edm::Wrapper(std::move(rawData))); + eventPrincipal.put( + daqProvenanceHelpers_[0]->branchDescription(), std::move(edp), daqProvenanceHelpers_[0]->dummyProvenance()); + + eventCached_ = false; +} + +void DataModeScoutingRun3::fillSDSRawDataCollection(SDSRawDataCollection& rawData, char* buff, size_t len) { + size_t pos = 0; + + // get the source ID + int sourceId = *((uint32_t*)(buff + pos)); + pos += 4; + + // size of the orbit paylod + size_t orbitSize = len - pos; + + // set the size (=orbit size) in the SRDColletion of the current source. + // FRD size is expecting 8 bytes words, while scouting is using 4 bytes + // words. This could be different for some future sources. + FEDRawData& fedData = rawData.FEDData(sourceId); + fedData.resize(orbitSize, 4); + + memcpy(fedData.data(), buff + pos, orbitSize); + + return; +} + +std::vector>& DataModeScoutingRun3::makeDaqProvenanceHelpers() { + //set SRD data collection + daqProvenanceHelpers_.clear(); + daqProvenanceHelpers_.emplace_back(std::make_shared( + edm::TypeID(typeid(SDSRawDataCollection)), "SDSRawDataCollection", "SDSRawDataCollection", "DAQSource")); + return daqProvenanceHelpers_; +} + +bool DataModeScoutingRun3::nextEventView() { + blockCompleted_ = false; + if (eventCached_) + return true; + + // move the data block address only for the sources processed + // un the previous event by adding the last event size + for (const auto& pair : sourceValidOrbitPair_) { + dataBlockAddrs_[pair.first] += events_[pair.second]->size(); + } + + return makeEvents(); +} + +bool DataModeScoutingRun3::makeEvents() { + // clear events and reset current orbit + events_.clear(); + sourceValidOrbitPair_.clear(); + currOrbit_ = 0xFFFFFFFF; // max uint + assert(!blockCompleted_); + + // create current "events" (= orbits) list from each data source, + // check if one dataBlock terminated earlier than others. + for (int i = 0; i < numFiles_; i++) { + if (dataBlockAddrs_[i] >= dataBlockMaxAddrs_[i]) { + completedBlocks_[i] = true; + continue; + } + + // event contains data, add it to the events list + events_.emplace_back(std::make_unique(dataBlockAddrs_[i])); + if (dataBlockAddrs_[i] + events_.back()->size() > dataBlockMaxAddrs_[i]) + throw cms::Exception("DAQSource::getNextEvent") + << " event id:" << events_.back()->event() << " lumi:" << events_.back()->lumi() + << " run:" << events_.back()->run() << " of size:" << events_.back()->size() + << " bytes does not fit into the buffer or has corrupted header"; + + // find the minimum orbit for the current event between all files + if ((events_.back()->event() < currOrbit_) && (!completedBlocks_[i])) { + currOrbit_ = events_.back()->event(); + } + } + + // mark valid orbits from each data source + // e.g. find when orbit is missing from one source + bool allBlocksCompleted = true; + int evt_idx = 0; + for (int i = 0; i < numFiles_; i++) { + if (completedBlocks_[i]) { + continue; + } + + if (events_[evt_idx]->event() != currOrbit_) { + // current source (=i-th source) doesn't contain the expected orbit. + // skip it, and move to the next orbit + } else { + // add a pair + // evt_idx can be different from variable i, as some data blocks can be + // completed before others + sourceValidOrbitPair_.emplace_back(std::make_pair(i, evt_idx)); + allBlocksCompleted = false; + } + + evt_idx++; + } + + if (allBlocksCompleted) { + blockCompleted_ = true; + } + return !allBlocksCompleted; +} + +bool DataModeScoutingRun3::checksumValid() { return true; } + +std::string DataModeScoutingRun3::getChecksumError() const { return std::string(); } diff --git a/EventFilter/Utilities/src/EvFDaqDirector.cc b/EventFilter/Utilities/src/EvFDaqDirector.cc index b89a2e4b032ce..05c6ecc92fc39 100644 --- a/EventFilter/Utilities/src/EvFDaqDirector.cc +++ b/EventFilter/Utilities/src/EvFDaqDirector.cc @@ -40,6 +40,7 @@ namespace evf { : base_dir_(pset.getUntrackedParameter("baseDir")), bu_base_dir_(pset.getUntrackedParameter("buBaseDir")), bu_base_dirs_all_(pset.getUntrackedParameter>("buBaseDirsAll")), + bu_base_dirs_nSources_(pset.getUntrackedParameter>("buBaseDirsNumStreams")), run_(pset.getUntrackedParameter("runNumber")), useFileBroker_(pset.getUntrackedParameter("useFileBroker")), fileBrokerHostFromCfg_(pset.getUntrackedParameter("fileBrokerHostFromCfg", true)), @@ -146,6 +147,23 @@ namespace evf { } } + // set number of streams in each BU's ramdisk + if (bu_base_dirs_nSources_.empty()) { + // default is 1 stream per ramdisk + for (unsigned int i = 0; i < bu_base_dirs_all_.size(); i++) { + bu_base_dirs_nSources_.push_back(1); + } + } else if (bu_base_dirs_nSources_.size() != bu_base_dirs_all_.size()) { + throw cms::Exception("DaqDirector") + << " Error while setting number of sources: size mismatch with BU base directory vector"; + } else { + for (unsigned int i = 0; i < bu_base_dirs_all_.size(); i++) { + bu_base_dirs_nSources_.push_back(bu_base_dirs_nSources_[i]); + edm::LogInfo("EvFDaqDirector") << "Setting " << bu_base_dirs_nSources_[i] << " sources" + << " for ramdisk " << bu_base_dirs_all_[i]; + } + } + std::stringstream ss; ss << "run" << std::setfill('0') << std::setw(6) << run_; run_string_ = ss.str(); @@ -365,6 +383,8 @@ namespace evf { desc.addUntracked("buBaseDir", ".")->setComment("BU base ramdisk directory "); desc.addUntracked>("buBaseDirsAll", std::vector()) ->setComment("BU base ramdisk directories for multi-file DAQSource models"); + desc.addUntracked>("buBaseDirsNumStreams", std::vector()) + ->setComment("Number of streams for each BU base ramdisk directories for multi-file DAQSource models"); desc.addUntracked("runNumber", 0)->setComment("Run Number in ramdisk to open"); desc.addUntracked("useFileBroker", false) ->setComment("Use BU file service to grab input data instead of NFS file locking"); diff --git a/EventFilter/Utilities/test/FU_scouting.py b/EventFilter/Utilities/test/FU_scouting.py deleted file mode 100644 index 96f1af7d0a436..0000000000000 --- a/EventFilter/Utilities/test/FU_scouting.py +++ /dev/null @@ -1,114 +0,0 @@ -from __future__ import print_function -import FWCore.ParameterSet.Config as cms -import FWCore.ParameterSet.VarParsing as VarParsing -import os - -options = VarParsing.VarParsing ('analysis') - -options.register ('runNumber', -# 325175, # default value - 325172, # default value - VarParsing.VarParsing.multiplicity.singleton, - VarParsing.VarParsing.varType.int, # string, int, or float - "Run Number") - -options.register ('buBaseDir', - 'ramdisk', # default value - VarParsing.VarParsing.multiplicity.singleton, - VarParsing.VarParsing.varType.string, # string, int, or float - "BU base directory") - -options.register ('fuBaseDir', - 'data', # default value - VarParsing.VarParsing.multiplicity.singleton, - VarParsing.VarParsing.varType.string, # string, int, or float - "BU base directory") - -options.register ('fffBaseDir', - '.', # default value - VarParsing.VarParsing.multiplicity.singleton, - VarParsing.VarParsing.varType.string, # string, int, or float - "FFF base directory") - -options.register ('numThreads', - 4, # default value - VarParsing.VarParsing.multiplicity.singleton, - VarParsing.VarParsing.varType.int, # string, int, or float - "Number of CMSSW threads") - -options.register ('numFwkStreams', - 4, # default value - VarParsing.VarParsing.multiplicity.singleton, - VarParsing.VarParsing.varType.int, # string, int, or float - "Number of CMSSW streams") - - -options.parseArguments() - -cmsswbase = os.path.expandvars("$CMSSW_BASE/") - -process = cms.Process("TESTFU") -process.maxEvents.input - -1 - -process.options = dict( - numberOfThreads = options.numThreads, - numberOfStreams = options.numFwkStreams, -# numberOfConcurrentLuminosityBlocks = 1 -) - -process.MessageLogger = cms.Service("MessageLogger", - cout = cms.untracked.PSet(threshold = cms.untracked.string( "ERROR" )), - destinations = cms.untracked.vstring( 'cout' ) -) - -process.FastMonitoringService = cms.Service("FastMonitoringService", - sleepTime = cms.untracked.int32(1) -) - -process.EvFDaqDirector = cms.Service("EvFDaqDirector", - useFileBroker = cms.untracked.bool(False), - fileBrokerHostFromCfg = cms.untracked.bool(True), - fileBrokerHost = cms.untracked.string("htcp40.cern.ch"), - runNumber = cms.untracked.uint32(options.runNumber), - baseDir = cms.untracked.string(options.fffBaseDir+"/"+options.fuBaseDir), - buBaseDir = cms.untracked.string(options.fffBaseDir+"/"+options.buBaseDir), - directorIsBU = cms.untracked.bool(False), -) - -try: - os.makedirs(options.fffBaseDir+"/"+options.fuBaseDir+"/run"+str(options.runNumber).zfill(6)) -except Exception as ex: - print(str(ex)) - pass - -ram_dir_path=options.buBaseDir+"/run"+str(options.runNumber).zfill(6)+"/" - -process.source = cms.Source("DAQSource", - dataMode = cms.untracked.string("ScoutingRun2"), - verifyChecksum = cms.untracked.bool(True), - useL1EventID = cms.untracked.bool(False), - eventChunkSize = cms.untracked.uint32(8), - eventChunkBlock = cms.untracked.uint32(8), - numBuffers = cms.untracked.uint32(2), - maxBufferedFiles = cms.untracked.uint32(2), - fileListMode = cms.untracked.bool(True), - fileNames = cms.untracked.vstring( -# ram_dir_path+"run325175_ls0001_index000001.raw" - ram_dir_path+"run325172_ls0455_index000000.raw" - ) - -) - -process.output = cms.OutputModule("PoolOutputModule", - fileName = cms.untracked.string('file:PoolOutputTest.root'), - outputCommands = cms.untracked.vstring("drop *","keep *_rawDataCollector_*_*") - ) - - -process.ep = cms.EndPath( -# process.streamA -# + process.streamB -# + process.streamC -# + process.streamD - process.output -) diff --git a/EventFilter/Utilities/test/FU_scouting_2.py b/EventFilter/Utilities/test/FU_scouting_2.py deleted file mode 100644 index a45fb4194babc..0000000000000 --- a/EventFilter/Utilities/test/FU_scouting_2.py +++ /dev/null @@ -1,117 +0,0 @@ -from __future__ import print_function -import FWCore.ParameterSet.Config as cms -import FWCore.ParameterSet.VarParsing as VarParsing -import os - -options = VarParsing.VarParsing ('analysis') - -options.register ('runNumber', -# 325175, # default value - 325172, # default value - VarParsing.VarParsing.multiplicity.singleton, - VarParsing.VarParsing.varType.int, # string, int, or float - "Run Number") - -options.register ('buBaseDir', - 'ramdisk', # default value - VarParsing.VarParsing.multiplicity.singleton, - VarParsing.VarParsing.varType.string, # string, int, or float - "BU base directory") - -options.register ('fuBaseDir', - 'data', # default value - VarParsing.VarParsing.multiplicity.singleton, - VarParsing.VarParsing.varType.string, # string, int, or float - "BU base directory") - -options.register ('fffBaseDir', - '.', # default value - VarParsing.VarParsing.multiplicity.singleton, - VarParsing.VarParsing.varType.string, # string, int, or float - "FFF base directory") - -options.register ('numThreads', - 1, # default value - VarParsing.VarParsing.multiplicity.singleton, - VarParsing.VarParsing.varType.int, # string, int, or float - "Number of CMSSW threads") - -options.register ('numFwkStreams', - 1, # default value - VarParsing.VarParsing.multiplicity.singleton, - VarParsing.VarParsing.varType.int, # string, int, or float - "Number of CMSSW streams") - - -options.parseArguments() - -cmsswbase = os.path.expandvars("$CMSSW_BASE/") - -process = cms.Process("TESTFU") -process.maxEvents = cms.untracked.PSet( - input = cms.untracked.int32(-1) -) - -process.options = cms.untracked.PSet( - numberOfThreads = cms.untracked.uint32(options.numThreads), - numberOfStreams = cms.untracked.uint32(options.numFwkStreams), - numberOfConcurrentLuminosityBlocks = cms.untracked.uint32(1) # ShmStreamConsumer requires synchronization at LuminosityBlock boundaries -) -process.MessageLogger = cms.Service("MessageLogger", - cout = cms.untracked.PSet(threshold = cms.untracked.string( "INFO" )), - destinations = cms.untracked.vstring( 'cout' ) -) - -process.FastMonitoringService = cms.Service("FastMonitoringService", - sleepTime = cms.untracked.int32(1) -) - -process.EvFDaqDirector = cms.Service("EvFDaqDirector", - useFileBroker = cms.untracked.bool(False), - fileBrokerHostFromCfg = cms.untracked.bool(True), - fileBrokerHost = cms.untracked.string("htcp40.cern.ch"), - runNumber = cms.untracked.uint32(options.runNumber), - baseDir = cms.untracked.string(options.fffBaseDir+"/"+options.fuBaseDir), - buBaseDir = cms.untracked.string(options.fffBaseDir+"/"+options.buBaseDir), - directorIsBU = cms.untracked.bool(False), -) - -try: - os.makedirs(options.fffBaseDir+"/"+options.fuBaseDir+"/run"+str(options.runNumber).zfill(6)) -except Exception as ex: - print(str(ex)) - pass - -ram_dir_path=options.buBaseDir+"/run"+str(options.runNumber).zfill(6)+"/" - -process.source = cms.Source("DAQSource", -# dataMode = cms.untracked.string("ScoutingRun2Muon"), - dataMode = cms.untracked.string("ScoutingRun2Multi"), - verifyChecksum = cms.untracked.bool(True), - useL1EventID = cms.untracked.bool(False), - eventChunkSize = cms.untracked.uint32(8), - eventChunkBlock = cms.untracked.uint32(8), - numBuffers = cms.untracked.uint32(2), - maxBufferedFiles = cms.untracked.uint32(2), - fileListMode = cms.untracked.bool(True), - fileNames = cms.untracked.vstring( -# ram_dir_path+"run325175_ls0001_index000001.raw" - ram_dir_path+"run325172_ls0010_index000000.raw", - ram_dir_path+"run325172_ls0380_index000000.raw" - ) - -) - -process.output = cms.OutputModule("PoolOutputModule", - fileName = cms.untracked.string('file:PoolOutputTest.root'), - outputCommands = cms.untracked.vstring("drop *","keep *_rawDataCollector_*_*") - ) - - -process.ep = cms.EndPath( -# process.streamA -# + process.streamB -# + process.streamC -# + process.streamD - process.output -) diff --git a/EventFilter/Utilities/test/dumpMuonScouting.py b/EventFilter/Utilities/test/dumpMuonScouting.py deleted file mode 100644 index f09081855f5ab..0000000000000 --- a/EventFilter/Utilities/test/dumpMuonScouting.py +++ /dev/null @@ -1,30 +0,0 @@ -import FWCore.ParameterSet.Config as cms - -process = cms.Process( "DUMP" ) - -process.MessageLogger = cms.Service("MessageLogger", - cerr = cms.untracked.PSet( - enable = cms.untracked.bool(False) - ), - cout = cms.untracked.PSet( - enable = cms.untracked.bool(True), - threshold = cms.untracked.string('INFO') - ) -) - - -process.source = cms.Source("PoolSource", - fileNames = cms.untracked.vstring("file:PoolOutputTest.root") -) - -process.dump = cms.EDAnalyzer("DumpMuonScouting", - muInputTag = cms.InputTag("rawDataCollector"), - minBx = cms.int32(0), - maxBx = cms.int32(4000) -) - - -process.p = cms.Path( - process.dump -) - diff --git a/EventFilter/Utilities/test/testScoutingRun3_unpackers.py b/EventFilter/Utilities/test/testScoutingRun3_unpackers.py new file mode 100644 index 0000000000000..b5e961df12de3 --- /dev/null +++ b/EventFilter/Utilities/test/testScoutingRun3_unpackers.py @@ -0,0 +1,160 @@ +from __future__ import print_function +import FWCore.ParameterSet.Config as cms +import FWCore.ParameterSet.VarParsing as VarParsing +import os, sys + +options = VarParsing.VarParsing ("analysis") + +options.register ("runNumber", + 368636, + VarParsing.VarParsing.multiplicity.singleton, + VarParsing.VarParsing.varType.int, + "Run Number") + +options.register ("daqSourceMode", + "ScoutingRun3", + VarParsing.VarParsing.multiplicity.singleton, + VarParsing.VarParsing.varType.string, + "DAQ source data mode") + +options.register ("buBaseDir", + "/dev/shm", + VarParsing.VarParsing.multiplicity.singleton, + VarParsing.VarParsing.varType.string, + "BU base directory") + +options.register ("fuBaseDir", + "/tmp/", + VarParsing.VarParsing.multiplicity.singleton, + VarParsing.VarParsing.varType.string, + "BU base directory") + +options.register ("fffBaseDir", + "/dev/shm", + VarParsing.VarParsing.multiplicity.singleton, + VarParsing.VarParsing.varType.string, + "FFF base directory") + +options.register ("numThreads", + 8, + VarParsing.VarParsing.multiplicity.singleton, + VarParsing.VarParsing.varType.int, + "Number of CMSSW threads") + +options.register ("numFwkStreams", + 8, + VarParsing.VarParsing.multiplicity.singleton, + VarParsing.VarParsing.varType.int, + "Number of CMSSW streams") + +options.parseArguments() + +cmsswbase = os.path.expandvars("$CMSSW_BASE/") + +process = cms.Process("SCPU") +process.maxEvents = cms.untracked.PSet( + input = cms.untracked.int32(-1) +) + +process.options = cms.untracked.PSet( + wantSummary = cms.untracked.bool(True), + numberOfThreads = cms.untracked.uint32(options.numThreads), + numberOfStreams = cms.untracked.uint32(options.numFwkStreams), + numberOfConcurrentLuminosityBlocks = cms.untracked.uint32(1) +) +process.MessageLogger = cms.Service("MessageLogger", + cout = cms.untracked.PSet( + threshold = cms.untracked.string( "WARNING" ) + ), + destinations = cms.untracked.vstring( "cout" ), +) + +process.FastMonitoringService = cms.Service("FastMonitoringService", + sleepTime = cms.untracked.int32(1) +) + +process.Timing = cms.Service("Timing", + summaryOnly = cms.untracked.bool(True), + useJobReport = cms.untracked.bool(True) +) + +process.EvFDaqDirector = cms.Service("EvFDaqDirector", + useFileBroker = cms.untracked.bool(False), + buBaseDirsAll = cms.untracked.vstring( + options.buBaseDir + ), + buBaseDirsNumStreams = cms.untracked.vint32( + 2 + ), + fileBrokerHostFromCfg = cms.untracked.bool(True), + fileBrokerHost = cms.untracked.string("htcp40.cern.ch"), + runNumber = cms.untracked.uint32(options.runNumber), + baseDir = cms.untracked.string(options.fffBaseDir+"/"+options.fuBaseDir), + buBaseDir = cms.untracked.string(options.fffBaseDir+"/"+options.buBaseDir), + directorIsBU = cms.untracked.bool(False), +) + +try: + os.makedirs(options.fffBaseDir+"/"+options.fuBaseDir+"/run"+str(options.runNumber).zfill(6)) +except Exception as ex: + print(str(ex)) + pass + +ram_dir_path=options.buBaseDir+"/run"+str(options.runNumber).zfill(6)+"/" +flist = [ + ram_dir_path + "run" + str(options.runNumber) + "_ls0340_index000028.raw" +] + +process.source = cms.Source("DAQSource", + testing = cms.untracked.bool(True), + dataMode = cms.untracked.string(options.daqSourceMode), + verifyChecksum = cms.untracked.bool(False), + useL1EventID = cms.untracked.bool(False), + eventChunkBlock = cms.untracked.uint32(64), + eventChunkSize = cms.untracked.uint32(128), + maxChunkSize = cms.untracked.uint32(256), + numBuffers = cms.untracked.uint32(2), + maxBufferedFiles = cms.untracked.uint32(2), + fileListMode = cms.untracked.bool(True), + fileNames = cms.untracked.vstring(*flist) + +) + +fuDir = options.fuBaseDir+("/run%06d" % options.runNumber) +buDir = options.buBaseDir+("/run%06d" % options.runNumber) +for d in fuDir, buDir, options.fuBaseDir, options.buBaseDir: + if not os.path.isdir(d): + os.makedirs(d) +os.system("touch " + buDir + "/" + "fu.lock") + +process.GmtUnpacker = cms.EDProducer('ScGMTRawToDigi', + srcInputTag = cms.InputTag('rawDataCollector'), + debug = cms.untracked.bool(False) +) + +process.CaloUnpacker = cms.EDProducer('ScCaloRawToDigi', + srcInputTag = cms.InputTag('rawDataCollector'), + enableAllSums = cms.untracked.bool(True), + debug = cms.untracked.bool(False) +) + +process.outputZB = cms.OutputModule("PoolOutputModule", + fileName = cms.untracked.string('file:/dev/shm/PoolOutputTest.root'), + outputCommands = cms.untracked.vstring( + "drop *", + "keep *_GmtUnpacker_*_*", + "keep *_CaloUnpacker_*_*" + ), + #compressionAlgorithm = cms.untracked.string("ZSTD"), + #compressionLevel = cms.untracked.int32(4) +) + +rawToDigiTask = cms.Task( + process.GmtUnpacker,process.CaloUnpacker +) + +process.p = cms.Path(rawToDigiTask) + +process.ep = cms.EndPath( + process.outputZB +) diff --git a/L1TriggerScouting/Utilities/BuildFile.xml b/L1TriggerScouting/Utilities/BuildFile.xml new file mode 100644 index 0000000000000..3cf482ccd33ff --- /dev/null +++ b/L1TriggerScouting/Utilities/BuildFile.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/L1TriggerScouting/Utilities/interface/conversion.h b/L1TriggerScouting/Utilities/interface/conversion.h new file mode 100644 index 0000000000000..45b233cbb07b9 --- /dev/null +++ b/L1TriggerScouting/Utilities/interface/conversion.h @@ -0,0 +1,37 @@ +#ifndef L1TriggerScouting_Utilities_conversion_h +#define L1TriggerScouting_Utilities_conversion_h + +#include "L1TriggerScouting/Utilities/interface/scales.h" +#include + +namespace l1ScoutingRun3 { + + inline float _setPhiRange(float phi) { + phi = phi >= M_PI ? phi - 2. * M_PI : phi; + return phi; + } + + namespace ugmt { + + inline float fPt(int hwPt) { return scales::pt_scale * (hwPt - 1); }; + inline float fEta(int hwEta) { return scales::eta_scale * hwEta; }; + inline float fPhi(int hwPhi) { return _setPhiRange(scales::phi_scale * hwPhi); }; + inline float fPtUnconstrained(int hwPtUnconstrained) { + return scales::ptunconstrained_scale * (hwPtUnconstrained - 1); + }; + inline float fEtaAtVtx(int hwEtaAtVtx) { return scales::eta_scale * hwEtaAtVtx; }; + inline float fPhiAtVtx(int hwPhiAtVtx) { return _setPhiRange(scales::phi_scale * hwPhiAtVtx); }; + + } // namespace ugmt + + namespace demux { + + inline float fEt(int hwEt) { return scales::et_scale * hwEt; }; + inline float fEta(int hwEta) { return scales::eta_scale * hwEta; }; + inline float fPhi(int hwPhi) { return _setPhiRange(scales::phi_scale * hwPhi); }; + + } // namespace demux + +} // namespace l1ScoutingRun3 + +#endif \ No newline at end of file diff --git a/L1TriggerScouting/Utilities/interface/convertToL1TFormat.h b/L1TriggerScouting/Utilities/interface/convertToL1TFormat.h new file mode 100644 index 0000000000000..93914e4afea23 --- /dev/null +++ b/L1TriggerScouting/Utilities/interface/convertToL1TFormat.h @@ -0,0 +1,26 @@ +#ifndef L1TriggerScouting_Utilities_convertToL1TFormat_h +#define L1TriggerScouting_Utilities_convertToL1TFormat_h + +#include "DataFormats/L1Scouting/interface/L1ScoutingMuon.h" +#include "DataFormats/L1Scouting/interface/L1ScoutingCalo.h" +#include "DataFormats/L1Trigger/interface/Muon.h" +#include "DataFormats/L1Trigger/interface/Jet.h" +#include "DataFormats/L1Trigger/interface/EGamma.h" +#include "DataFormats/L1Trigger/interface/Tau.h" +#include "DataFormats/L1Trigger/interface/EtSum.h" + +#include "L1TriggerScouting/Utilities/interface/conversion.h" + +#include "iostream" + +namespace l1ScoutingRun3 { + + l1t::Muon getL1TMuon(const Muon& muon); + l1t::Jet getL1TJet(const Jet& jet); + l1t::EGamma getL1TEGamma(const EGamma& eGamma); + l1t::Tau getL1TTau(const Tau& scTau); + l1t::EtSum getL1TEtSum(const BxSums& sums, l1t::EtSum::EtSumType); + +} // namespace l1ScoutingRun3 + +#endif // L1TriggerScouting_Utilities_convertToL1TFormat_h \ No newline at end of file diff --git a/L1TriggerScouting/Utilities/interface/printScObjects.h b/L1TriggerScouting/Utilities/interface/printScObjects.h new file mode 100644 index 0000000000000..c2a6257811de5 --- /dev/null +++ b/L1TriggerScouting/Utilities/interface/printScObjects.h @@ -0,0 +1,22 @@ +#ifndef L1TriggerScouting_Utilities_printScObjects_h +#define L1TriggerScouting_Utilities_printScObjects_h + +#include "DataFormats/L1Scouting/interface/L1ScoutingMuon.h" +#include "DataFormats/L1Scouting/interface/L1ScoutingCalo.h" +#include "L1TriggerScouting/Utilities/interface/conversion.h" + +#include "iostream" + +namespace l1ScoutingRun3 { + + void printMuon(const Muon& muon, std::ostream& outs = std::cout); + template + void printCaloObject(const T& obj, std::ostream& outs = std::cout); + void printJet(const Jet& jet, std::ostream& outs = std::cout); + void printEGamma(const EGamma& eGamma, std::ostream& outs = std::cout); + void printTau(const Tau& tau, std::ostream& outs = std::cout); + void printBxSums(const BxSums& sums, std::ostream& outs = std::cout); + +} // namespace l1ScoutingRun3 + +#endif // L1TriggerScouting_Utilities_printScObjects_h \ No newline at end of file diff --git a/L1TriggerScouting/Utilities/interface/scales.h b/L1TriggerScouting/Utilities/interface/scales.h new file mode 100644 index 0000000000000..45995518619ff --- /dev/null +++ b/L1TriggerScouting/Utilities/interface/scales.h @@ -0,0 +1,30 @@ +#ifndef L1TriggerScouting_Utilities_scales_h +#define L1TriggerScouting_Utilities_scales_h + +#include +#include + +namespace l1ScoutingRun3 { + + // Scaled used to convert scouting hw values to physical quantities + + namespace ugmt { + struct scales { + static constexpr float pt_scale = 0.5; + static constexpr float ptunconstrained_scale = 1.0; + static constexpr float phi_scale = 2. * M_PI / 576.; + static constexpr float eta_scale = 0.0870 / 8; + static constexpr float phi_range = M_PI; + }; + } // namespace ugmt + + namespace demux { + struct scales { + static constexpr float phi_scale = 2. * M_PI / 144.; + static constexpr float eta_scale = 0.0435; + static constexpr float et_scale = 0.5; + }; + } // namespace demux + +} // namespace l1ScoutingRun3 +#endif // L1TriggerScouting_Utilities_scales_h diff --git a/L1TriggerScouting/Utilities/plugins/BuildFile.xml b/L1TriggerScouting/Utilities/plugins/BuildFile.xml new file mode 100644 index 0000000000000..2e16c87937d04 --- /dev/null +++ b/L1TriggerScouting/Utilities/plugins/BuildFile.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/L1TriggerScouting/Utilities/plugins/DumpScObjects.cc b/L1TriggerScouting/Utilities/plugins/DumpScObjects.cc new file mode 100644 index 0000000000000..bb57a7ed37da6 --- /dev/null +++ b/L1TriggerScouting/Utilities/plugins/DumpScObjects.cc @@ -0,0 +1,235 @@ +#include "FWCore/Framework/interface/MakerMacros.h" + +#include +#include +#include +#include +#include + +#include "FWCore/Framework/interface/stream/EDAnalyzer.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/EDGetToken.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/MessageLogger/interface/MessageDrop.h" + +#include "DataFormats/L1Scouting/interface/OrbitCollection.h" +#include "DataFormats/L1Scouting/interface/L1ScoutingMuon.h" +#include "DataFormats/L1Scouting/interface/L1ScoutingCalo.h" +#include "L1TriggerScouting/Utilities/interface/printScObjects.h" +#include "L1TriggerScouting/Utilities/interface/convertToL1TFormat.h" + +using namespace l1ScoutingRun3; + +// ----------------------------- CLASS DECLARATION ---------------------------- +class DumpScObjects : public edm::stream::EDAnalyzer<> { +public: + // constructor and destructor + explicit DumpScObjects(const edm::ParameterSet&); + ~DumpScObjects() override{}; + + // method for analyzing the events + void analyze(const edm::Event&, const edm::EventSetup&) override; + +private: + // dump contenct of BX + void printBx(unsigned bx); + + // the tokens to access the data + edm::EDGetTokenT gmtMuonsToken_; + edm::EDGetTokenT caloJetsToken_; + edm::EDGetTokenT caloEGammasToken_; + edm::EDGetTokenT caloTausToken_; + edm::EDGetTokenT caloEtSumsToken_; + + edm::Handle muonHandle_; + edm::Handle jetHandle_; + edm::Handle eGammaHandle_; + edm::Handle tauHandle_; + edm::Handle etSumHandle_; + + // the min and max BX to be analyzed + unsigned minBx_; + unsigned maxBx_; + + // select collection to be printed + bool checkMuons_; + bool checkJets_; + bool checkEGammas_; + bool checkTaus_; + bool checkEtSums_; + + // dump a specific (ORBIT, BX RANGE) + bool searchEvent_; + unsigned orbitNum_; + unsigned searchStartBx_; + unsigned searchStopBx_; + + // utils + bool skipEmptyBx_; +}; +// ----------------------------------------------------------------------------- + +// -------------------------------- constructor ------------------------------- + +DumpScObjects::DumpScObjects(const edm::ParameterSet& iConfig) + : minBx_(iConfig.getUntrackedParameter("minBx", 0)), + maxBx_(iConfig.getUntrackedParameter("maxBx", 3564)), + + checkMuons_(iConfig.getUntrackedParameter("checkMuons", true)), + checkJets_(iConfig.getUntrackedParameter("checkJets", true)), + checkEGammas_(iConfig.getUntrackedParameter("checkEGammas", true)), + checkTaus_(iConfig.getUntrackedParameter("checkTaus", true)), + checkEtSums_(iConfig.getUntrackedParameter("checkEtSums", true)), + + searchEvent_(iConfig.getUntrackedParameter("searchEvent", false)), + orbitNum_(iConfig.getUntrackedParameter("orbitNumber", 0)), + searchStartBx_(iConfig.getUntrackedParameter("searchStartBx", 0)), + searchStopBx_(iConfig.getUntrackedParameter("searchStopBx", 0)), + + skipEmptyBx_(iConfig.getUntrackedParameter("skipEmptyBx", true)) { + if (checkMuons_) + gmtMuonsToken_ = consumes(iConfig.getParameter("gmtMuonsTag")); + if (checkJets_) + caloJetsToken_ = consumes(iConfig.getParameter("caloJetsTag")); + if (checkEGammas_) + caloEGammasToken_ = consumes(iConfig.getParameter("caloEGammasTag")); + if (checkTaus_) + caloTausToken_ = consumes(iConfig.getParameter("caloTausTag")); + if (checkEtSums_) + caloEtSumsToken_ = consumes(iConfig.getParameter("caloEtSumsTag")); +} +// ----------------------------------------------------------------------------- + +// ----------------------- method called for each orbit ----------------------- +void DumpScObjects::analyze(const edm::Event& iEvent, const edm::EventSetup& evSetup) { + if (checkMuons_) + iEvent.getByToken(gmtMuonsToken_, muonHandle_); + if (checkJets_) + iEvent.getByToken(caloJetsToken_, jetHandle_); + if (checkEGammas_) + iEvent.getByToken(caloEGammasToken_, eGammaHandle_); + if (checkTaus_) + iEvent.getByToken(caloTausToken_, tauHandle_); + if (checkEtSums_) + iEvent.getByToken(caloEtSumsToken_, etSumHandle_); + + // get the orbit number + unsigned currOrbit = iEvent.id().event(); + + // if we are looking for a specific orbit + if (searchEvent_) { + if (currOrbit != orbitNum_) + return; + + // found the orbit + for (unsigned bx = searchStartBx_; bx <= searchStopBx_; bx++) { + printBx(bx); + } + } else { + if (skipEmptyBx_) { + // create a set of non empty BXs + std::set uniqueBx; + + if (checkMuons_) { + for (const unsigned& bx : muonHandle_->getFilledBxs()) { + if ((bx >= minBx_) || (bx <= maxBx_)) + uniqueBx.insert(bx); + } + } + if (checkJets_) { + for (const unsigned& bx : jetHandle_->getFilledBxs()) { + if ((bx >= minBx_) || (bx <= maxBx_)) + uniqueBx.insert(bx); + } + } + if (checkEGammas_) { + for (const unsigned& bx : eGammaHandle_->getFilledBxs()) { + if ((bx >= minBx_) || (bx <= maxBx_)) + uniqueBx.insert(bx); + } + } + if (checkTaus_) { + for (const unsigned& bx : tauHandle_->getFilledBxs()) { + if ((bx >= minBx_) || (bx <= maxBx_)) + uniqueBx.insert(bx); + } + } + if (checkEtSums_) { + for (const unsigned& bx : etSumHandle_->getFilledBxs()) { + if ((bx >= minBx_) || (bx <= maxBx_)) + uniqueBx.insert(bx); + } + } + + // process bx + for (const unsigned& bx : uniqueBx) { + printBx(bx); + } + + } else { + // dump all objects + for (unsigned bx = minBx_; bx <= maxBx_; bx++) { + printBx(bx); + } + } + } +} +// ----------------------------------------------------------------------------- + +void DumpScObjects::printBx(unsigned bx) { + std::cout << "BX = " << bx << " ****" << std::endl; + + if (checkMuons_ && muonHandle_.isValid()) { + int i = 0; + const auto& muons = muonHandle_->bxIterator(bx); + for (const auto& muon : muons) { + std::cout << "--- Muon " << i << " ---\n"; + printMuon(muon); + i++; + } + } + + if (checkJets_ && jetHandle_.isValid()) { + int i = 0; + const auto& jets = jetHandle_->bxIterator(bx); + for (const auto& jet : jets) { + std::cout << "--- Jet " << i << " ---\n"; + printJet(jet); + i++; + } + } + + if (checkEGammas_ && jetHandle_.isValid()) { + int i = 0; + const auto& eGammas = eGammaHandle_->bxIterator(bx); + for (const auto& egamma : eGammas) { + std::cout << "--- E/Gamma " << i << " ---\n"; + printEGamma(egamma); + i++; + } + } + + if (checkTaus_ && tauHandle_.isValid()) { + int i = 0; + const auto& taus = tauHandle_->bxIterator(bx); + for (const auto& tau : taus) { + std::cout << "--- Tau " << i << " ---\n"; + printTau(tau); + i++; + } + } + + if (checkEtSums_ && etSumHandle_.isValid()) { + const auto& sums = etSumHandle_->bxIterator(bx); + for (const auto& sum : sums) { + std::cout << "--- Calo Sums ---\n"; + printBxSums(sum); + } + } +} + +DEFINE_FWK_MODULE(DumpScObjects); diff --git a/L1TriggerScouting/Utilities/src/convertToL1TFormat.cc b/L1TriggerScouting/Utilities/src/convertToL1TFormat.cc new file mode 100644 index 0000000000000..bb2ffda7440ba --- /dev/null +++ b/L1TriggerScouting/Utilities/src/convertToL1TFormat.cc @@ -0,0 +1,144 @@ +#include "L1TriggerScouting/Utilities/interface/convertToL1TFormat.h" + +namespace l1ScoutingRun3 { + + l1t::Muon getL1TMuon(const Muon& muon) { + return l1t::Muon( + math::PtEtaPhiMLorentzVector(ugmt::fPt(muon.hwPt()), ugmt::fEta(muon.hwEta()), ugmt::fPhi(muon.hwPhi()), 0.), + muon.hwPt(), + muon.hwEta(), + muon.hwPhi(), + muon.hwQual(), + muon.hwCharge(), + muon.hwChargeValid(), + 0, + muon.tfMuonIndex(), + 0, + false, + 0, + 0, + 0, + 0, + muon.hwEtaAtVtx(), + muon.hwPhiAtVtx(), + ugmt::fEtaAtVtx(muon.hwEtaAtVtx()), + ugmt::fPhiAtVtx(muon.hwPhiAtVtx()), + muon.hwPtUnconstrained(), + ugmt::fPtUnconstrained(muon.hwPtUnconstrained()), + muon.hwDXY()); + } + + l1t::Jet getL1TJet(const Jet& jet) { + return l1t::Jet( + math::PtEtaPhiMLorentzVector(demux::fEt(jet.hwEt()), demux::fEta(jet.hwEta()), demux::fPhi(jet.hwPhi()), 0.), + jet.hwEt(), + jet.hwEta(), + jet.hwPhi(), + jet.hwIso()); + } + + l1t::EGamma getL1TEGamma(const EGamma& eGamma) { + return l1t::EGamma(math::PtEtaPhiMLorentzVector( + demux::fEt(eGamma.hwEt()), demux::fEta(eGamma.hwEta()), demux::fPhi(eGamma.hwPhi()), 0.), + eGamma.hwEt(), + eGamma.hwEta(), + eGamma.hwPhi(), + 0, + eGamma.hwIso()); + } + + l1t::Tau getL1TTau(const Tau& tau) { + return l1t::Tau( + math::PtEtaPhiMLorentzVector(demux::fEt(tau.hwEt()), demux::fEta(tau.hwEta()), demux::fPhi(tau.hwPhi()), 0.), + tau.hwEt(), + tau.hwEta(), + tau.hwPhi(), + 0, + tau.hwIso()); + } + + l1t::EtSum getL1TEtSum(const BxSums& sums, l1t::EtSum::EtSumType sumType) { + switch (sumType) { + case l1t::EtSum::kTotalEt: + return l1t::EtSum( + math::PtEtaPhiMLorentzVector(demux::fEt(sums.hwTotalEt()), 0., 0., 0.), sumType, sums.hwTotalEt(), 0, 0, 0); + case l1t::EtSum::kTotalEtEm: + return l1t::EtSum(math::PtEtaPhiMLorentzVector(demux::fEt(sums.hwTotalEtEm()), 0., 0., 0.), + sumType, + sums.hwTotalEtEm(), + 0, + 0, + 0); + case l1t::EtSum::kTotalHt: + return l1t::EtSum( + math::PtEtaPhiMLorentzVector(demux::fEt(sums.hwTotalHt()), 0., 0., 0.), sumType, sums.hwTotalHt(), 0, 0, 0); + case l1t::EtSum::kMissingEt: + return l1t::EtSum( + math::PtEtaPhiMLorentzVector(demux::fEt(sums.hwMissEt()), 0., demux::fPhi(sums.hwMissEtPhi()), 0.), + sumType, + sums.hwMissEt(), + 0, + sums.hwMissEtPhi(), + 0); + case l1t::EtSum::kMissingHt: + return l1t::EtSum( + math::PtEtaPhiMLorentzVector(demux::fEt(sums.hwMissHt()), 0., demux::fPhi(sums.hwMissHtPhi()), 0.), + sumType, + sums.hwMissHt(), + 0, + sums.hwMissHtPhi(), + 0); + case l1t::EtSum::kMissingEtHF: + return l1t::EtSum( + math::PtEtaPhiMLorentzVector(demux::fEt(sums.hwMissEtHF()), 0., demux::fPhi(sums.hwMissEtHFPhi()), 0.), + sumType, + sums.hwMissEtHF(), + 0, + sums.hwMissEtHFPhi(), + 0); + case l1t::EtSum::kMissingHtHF: + return l1t::EtSum( + math::PtEtaPhiMLorentzVector(demux::fEt(sums.hwMissHtHF()), 0., demux::fPhi(sums.hwMissHtHFPhi()), 0.), + sumType, + sums.hwMissHtHF(), + 0, + sums.hwMissHtHFPhi(), + 0); + case l1t::EtSum::kAsymEt: + return l1t::EtSum( + math::PtEtaPhiMLorentzVector(demux::fEt(sums.hwAsymEt()), 0., 0., 0.), sumType, sums.hwAsymEt(), 0, 0, 0); + case l1t::EtSum::kAsymHt: + return l1t::EtSum( + math::PtEtaPhiMLorentzVector(demux::fEt(sums.hwAsymHt()), 0., 0., 0.), sumType, sums.hwAsymHt(), 0, 0, 0); + case l1t::EtSum::kAsymEtHF: + return l1t::EtSum(math::PtEtaPhiMLorentzVector(demux::fEt(sums.hwAsymEtHF()), 0., 0., 0.), + sumType, + sums.hwAsymEtHF(), + 0, + 0, + 0); + case l1t::EtSum::kAsymHtHF: + return l1t::EtSum(math::PtEtaPhiMLorentzVector(demux::fEt(sums.hwAsymHtHF()), 0., 0., 0.), + sumType, + sums.hwAsymHtHF(), + 0, + 0, + 0); + case l1t::EtSum::kMinBiasHFP0: + return l1t::EtSum(math::PtEtaPhiMLorentzVector(0., 0., 0., 0.), sumType, sums.minBiasHFP0(), 0, 0, 0); + case l1t::EtSum::kMinBiasHFP1: + return l1t::EtSum(math::PtEtaPhiMLorentzVector(0., 0., 0., 0.), sumType, sums.minBiasHFP1(), 0, 0, 0); + case l1t::EtSum::kMinBiasHFM0: + return l1t::EtSum(math::PtEtaPhiMLorentzVector(0., 0., 0., 0.), sumType, sums.minBiasHFM0(), 0, 0, 0); + case l1t::EtSum::kMinBiasHFM1: + return l1t::EtSum(math::PtEtaPhiMLorentzVector(0., 0., 0., 0.), sumType, sums.minBiasHFM1(), 0, 0, 0); + case l1t::EtSum::kCentrality: + return l1t::EtSum(math::PtEtaPhiMLorentzVector(0., 0., 0., 0.), sumType, sums.centrality(), 0, 0, 0); + case l1t::EtSum::kTowerCount: + return l1t::EtSum(math::PtEtaPhiMLorentzVector(0., 0., 0., 0.), sumType, sums.towerCount(), 0, 0, 0); + default: + return l1t::EtSum(math::PtEtaPhiMLorentzVector(0., 0., 0., 0.), l1t::EtSum::kUninitialized, 0, 0, 0, 0); + } + } + +} // namespace l1ScoutingRun3 \ No newline at end of file diff --git a/L1TriggerScouting/Utilities/src/printScObjects.cc b/L1TriggerScouting/Utilities/src/printScObjects.cc new file mode 100644 index 0000000000000..42a9e8e27bb3b --- /dev/null +++ b/L1TriggerScouting/Utilities/src/printScObjects.cc @@ -0,0 +1,71 @@ +#include "L1TriggerScouting/Utilities/interface/printScObjects.h" + +namespace l1ScoutingRun3 { + + void printMuon(const Muon& muon, std::ostream& outs) { + outs << " Pt [GeV/Hw]: " << ugmt::fPt(muon.hwPt()) << "/" << muon.hwPt() << "\n" + << " Eta [rad/Hw]: " << ugmt::fEta(muon.hwEta()) << "/" << muon.hwEta() << "\n" + << " Phi [rad/Hw]: " << ugmt::fPhi(muon.hwPhi()) << "/" << muon.hwPhi() << "\n" + << " Charge/valid: " << muon.hwCharge() << "/" << muon.hwChargeValid() << "\n" + << " PhiVtx [rad/Hw]: " << ugmt::fPhiAtVtx(muon.hwPhiAtVtx()) << "/" << muon.hwPhiAtVtx() << "\n" + << " EtaVtx [rad/Hw]: " << ugmt::fEtaAtVtx(muon.hwEtaAtVtx()) << "/" << muon.hwEtaAtVtx() << "\n" + << " Pt uncon[GeV/Hw]: " << ugmt::fPtUnconstrained(muon.hwPtUnconstrained()) << "/" + << muon.hwPtUnconstrained() << "\n" + << " Dxy: " << muon.hwDXY() << "\n" + << " Qual: " << muon.hwQual() << "\n" + << " TF index: " << muon.tfMuonIndex() << "\n"; + } + + template + void printCaloObject(const T& obj, std::ostream& outs) { + outs << " Et [GeV/Hw]: " << demux::fEt(obj.hwEt()) << "/" << obj.hwEt() << "\n" + << " Eta [rad/Hw]: " << demux::fEta(obj.hwEta()) << "/" << obj.hwEta() << "\n" + << " Phi [rad/Hw]: " << demux::fPhi(obj.hwPhi()) << "/" << obj.hwPhi() << "\n" + << " Iso [Hw]: " << obj.hwIso() << "\n"; + } + + void printJet(const Jet& jet, std::ostream& outs) { printCaloObject(jet, outs); } + void printEGamma(const EGamma& eGamma, std::ostream& outs) { printCaloObject(eGamma, outs); } + void printTau(const Tau& tau, std::ostream& outs) { printCaloObject(tau, outs); } + + void printBxSums(const BxSums& sums, std::ostream& outs) { + outs << "Total ET\n" + << " Et [GeV/Hw]: " << demux::fEt(sums.hwTotalEt()) << "/" << sums.hwTotalEt() << "\n" + << "Total ETEm\n" + << " Et [GeV/Hw]: " << demux::fEt(sums.hwTotalEtEm()) << "/" << sums.hwTotalEtEm() << "\n" + << "Total HT\n" + << " Et [GeV/Hw]: " << demux::fEt(sums.hwTotalHt()) << "/" << sums.hwTotalHt() << "\n" + << "Missing ET\n" + << " Et [GeV/Hw] : " << demux::fEt(sums.hwMissEt()) << "/" << sums.hwMissEt() << "\n" + << " Phi [Rad/Hw]: " << demux::fPhi(sums.hwMissEtPhi()) << "/" << sums.hwMissEtPhi() << "\n" + << "Missing HT\n" + << " Et [GeV/Hw] : " << demux::fEt(sums.hwMissHt()) << "/" << sums.hwMissHt() << "\n" + << " Phi [Rad/Hw]: " << demux::fPhi(sums.hwMissHtPhi()) << "/" << sums.hwMissHtPhi() << "\n" + << "Missing ETHF\n" + << " Et [GeV/Hw] : " << demux::fEt(sums.hwMissEtHF()) << "/" << sums.hwMissEtHF() << "\n" + << " Phi [Rad/Hw]: " << demux::fPhi(sums.hwMissEtHFPhi()) << "/" << sums.hwMissEtHFPhi() << "\n" + << "Missing HTHF\n" + << " Et [GeV/Hw] : " << demux::fEt(sums.hwMissHtHF()) << "/" << sums.hwMissHtHF() << "\n" + << " Phi [Rad/Hw]: " << demux::fPhi(sums.hwMissHtHFPhi()) << "/" << sums.hwMissHtHFPhi() << "\n" + << "AsymEt\n" + << " Et [GeV/Hw] : " << demux::fEt(sums.hwAsymEt()) << "/" << sums.hwAsymEt() << "\n" + << "AsymHt\n" + << " Et [GeV/Hw] : " << demux::fEt(sums.hwAsymHt()) << "/" << sums.hwAsymHt() << "\n" + << "AsymEtHF\n" + << " Et [GeV/Hw] : " << demux::fEt(sums.hwAsymEtHF()) << "/" << sums.hwAsymEtHF() << "\n" + << "AsymHtHF\n" + << " Et [GeV/Hw] : " << demux::fEt(sums.hwAsymHtHF()) << "/" << sums.hwAsymHtHF() << "\n" + << "MinBiasHFP0\n" + << " Hw: " << sums.minBiasHFP0() << "\n" + << "MinBiasHFM0\n" + << " Hw: " << sums.minBiasHFM0() << "\n" + << "MinBiasHFP1\n" + << " Hw: " << sums.minBiasHFP1() << "\n" + << "MinBiasHFM1\n" + << " Hw: " << sums.minBiasHFM1() << "\n" + << "Centrality\n" + << " Hw: " << sums.centrality() << "\n" + << "Tower Count\n" + << " Hw: " << sums.towerCount() << "\n"; + } +} // namespace l1ScoutingRun3 \ No newline at end of file diff --git a/L1TriggerScouting/Utilities/test/dumpScObjects.py b/L1TriggerScouting/Utilities/test/dumpScObjects.py new file mode 100644 index 0000000000000..957ac3d77e7a2 --- /dev/null +++ b/L1TriggerScouting/Utilities/test/dumpScObjects.py @@ -0,0 +1,54 @@ +import FWCore.ParameterSet.Config as cms +import FWCore.ParameterSet.VarParsing as VarParsing + +options = VarParsing.VarParsing ('analysis') + +options.register ('numOrbits', + -1, + VarParsing.VarParsing.multiplicity.singleton, + VarParsing.VarParsing.varType.int, + "Number of orbits to process") + +options.register ('filePath', + "file:/dev/shm/PoolOutputTest.root", + VarParsing.VarParsing.multiplicity.singleton, + VarParsing.VarParsing.varType.string, + "Sub lumisection number to process") + +options.parseArguments() + +process = cms.Process( "DUMP" ) + + +process.maxEvents = cms.untracked.PSet( + input = cms.untracked.int32(options.numOrbits) +) + +process.load("FWCore.MessageService.MessageLogger_cfi") + +process.source = cms.Source("PoolSource", + fileNames = cms.untracked.vstring(options.filePath) +) + +process.dump = cms.EDAnalyzer("DumpScObjects", + gmtMuonsTag = cms.InputTag("GmtUnpacker", "", "SCPU"), + caloJetsTag = cms.InputTag("CaloUnpacker", "", "SCPU"), + caloEGammasTag = cms.InputTag("CaloUnpacker", "", "SCPU"), + caloTausTag = cms.InputTag("CaloUnpacker", "", "SCPU"), + caloEtSumsTag = cms.InputTag("CaloUnpacker", "", "SCPU"), + minBx = cms.untracked.uint32(0), + maxBx = cms.untracked.uint32(3564), + + skipEmptyBx = cms.untracked.bool(True), # don't show empty BX + + #checkMuons = cms.untracked.bool(False), # test removing a collection + + searchEvent = cms.untracked.bool(True), + orbitNumber = cms.untracked.uint32(88981531), + searchStartBx = cms.untracked.uint32(1027-2), + searchStopBx = cms.untracked.uint32(1027+2), +) + +process.p = cms.Path( + process.dump +) \ No newline at end of file