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