From 34d075041dcc8f247e11867995295e971423435c Mon Sep 17 00:00:00 2001
From: Pedro <psilva@cern.ch>
Date: Fri, 13 Jan 2023 14:54:08 +0100
Subject: [PATCH 1/2] adding first version of electronics id class

---
 .../interface/HGCalDigiCollections.h          |  4 ++
 .../HGCalDigi/interface/HGCalElectronicsId.h  | 60 +++++++++++++++++++
 .../HGCalDigi/src/HGCalElectronicsId.cc       | 35 +++++++++++
 DataFormats/HGCalDigi/src/classes_def.xml     |  8 +++
 DataFormats/HGCalDigi/test/BuildFile.xml      |  5 ++
 .../HGCalDigi/test/HGCalElectronicsIdTest.cc  | 58 ++++++++++++++++++
 6 files changed, 170 insertions(+)
 create mode 100644 DataFormats/HGCalDigi/interface/HGCalElectronicsId.h
 create mode 100644 DataFormats/HGCalDigi/src/HGCalElectronicsId.cc
 create mode 100644 DataFormats/HGCalDigi/test/HGCalElectronicsIdTest.cc

diff --git a/DataFormats/HGCalDigi/interface/HGCalDigiCollections.h b/DataFormats/HGCalDigi/interface/HGCalDigiCollections.h
index e8f7ac2fc397e..cc136d1ff7903 100644
--- a/DataFormats/HGCalDigi/interface/HGCalDigiCollections.h
+++ b/DataFormats/HGCalDigi/interface/HGCalDigiCollections.h
@@ -5,8 +5,12 @@
 #include "DataFormats/DetId/interface/DetId.h"
 #include "DataFormats/ForwardDetId/interface/HGCalDetId.h"
 #include "DataFormats/HGCalDigi/interface/HGCROCChannelDataFrame.h"
+#include "DataFormats/HGCalDigi/interface/HGCalElectronicsId.h"
 
 typedef HGCROCChannelDataFrame<HGCalDetId> HGCROCChannelDataFrameSpec;
 typedef edm::SortedCollection<HGCROCChannelDataFrameSpec> HGCalDigiCollection;
 
+typedef HGCROCChannelDataFrame<HGCalElectronicsId> HGCROCChannelDataFrameElecSpec;
+typedef edm::SortedCollection<HGCROCChannelDataFrameElecSpec> HGCalElecDigiCollection;
+
 #endif
diff --git a/DataFormats/HGCalDigi/interface/HGCalElectronicsId.h b/DataFormats/HGCalDigi/interface/HGCalElectronicsId.h
new file mode 100644
index 0000000000000..d6a33ff3ae82b
--- /dev/null
+++ b/DataFormats/HGCalDigi/interface/HGCalElectronicsId.h
@@ -0,0 +1,60 @@
+#ifndef DataFormats_HGCalDigis_HGCalElectronicsId_h
+#define DataFormats_HGCalDigis_HGCalElectronicsId_h
+
+#include <iostream>
+#include <ostream>
+#include <cstdint>
+
+/**
+   @class HGCalElectronicsId
+   @short wrapper for a 32b data word identifying a readout channel in the raw data
+   The format is the following:
+   Reserved: b'[28,31]
+   FED ID: b'[18,27]
+   Capture Block ID: b'[14,17]
+   ECON-D idx: b'[10,13]
+   ECON-D eRx: b'[6,9]
+   1/2 ROC channel number: b'[0-5]   
+ */
+
+class HGCalElectronicsId {
+public:
+  
+  enum HGCalElectronicsIdMask { kFEDIDMask = 0x3ff, kCaptureBlockMask=0xf, kECONDIdxMask=0xf, kECONDeRxMask=0xf, kHalfROCChannelMask=0x3f };
+  enum HGCalElectronicsIdShift { kFEDIDShift = 18, kCaptureBlockShift=14, kECONDIdxShift=10, kECONDeRxShift=6, kHalfROCChannelShift=0 };
+
+  /**
+     @short CTOR
+  */
+  HGCalElectronicsId() : value_(0) {}
+  HGCalElectronicsId(uint16_t fedid, uint8_t captureblock, uint8_t econdidx, uint8_t econderx, uint8_t halfrocch);
+  HGCalElectronicsId(uint32_t value) : value_(value) {}
+  HGCalElectronicsId(const HGCalElectronicsId& o) : value_(o.value_) {}
+  
+  /**
+     @short getters
+  */
+  uint32_t operator()() { return value_; }
+  uint32_t raw() { return value_; }
+  uint16_t fedId();
+  uint8_t captureBlock();
+  uint8_t econdIdx();
+  uint8_t econdeRx();
+  uint8_t halfrocChannel();
+  
+  void print(std::ostream& out = std::cout) {
+    out << "Raw=0x" << std::hex << raw() << std::dec << std::endl
+        << "\tFED-ID: " << (uint32_t)fedId()
+        << " Capture Block: " << (uint32_t)captureBlock()
+        << " ECON-D idx: " << (uint32_t)econdIdx()
+        << " eRx: " << (uint32_t)econdeRx()
+        << " 1/2 ROC ch.: " << (uint32_t)halfrocChannel() << std::endl;
+  }
+
+private:
+
+  // a 32-bit word
+  uint32_t value_;
+};
+
+#endif
diff --git a/DataFormats/HGCalDigi/src/HGCalElectronicsId.cc b/DataFormats/HGCalDigi/src/HGCalElectronicsId.cc
new file mode 100644
index 0000000000000..896862fa503d9
--- /dev/null
+++ b/DataFormats/HGCalDigi/src/HGCalElectronicsId.cc
@@ -0,0 +1,35 @@
+#include "DataFormats/HGCalDigi/interface/HGCalElectronicsId.h"
+
+//
+HGCalElectronicsId::HGCalElectronicsId(uint16_t fedid, uint8_t captureblock, uint8_t econdidx, uint8_t econderx, uint8_t halfrocch) {
+  value_ = ((fedid & kFEDIDMask) << kFEDIDShift)
+    | ((captureblock & kCaptureBlockMask) << kCaptureBlockShift)
+    | ((econdidx & kECONDIdxMask) << kECONDIdxShift)
+    | ((econderx & kECONDeRxMask) << kECONDeRxShift)
+    | ((halfrocch & kHalfROCChannelMask) << kHalfROCChannelShift);
+}
+
+//
+uint16_t HGCalElectronicsId::fedId(){
+  return (value_ >> kFEDIDShift) & kFEDIDMask;
+}
+
+//
+uint8_t HGCalElectronicsId::captureBlock(){
+  return (value_ >> kCaptureBlockShift) & kCaptureBlockMask;
+}
+
+//
+uint8_t HGCalElectronicsId::econdIdx(){
+  return (value_ >> kECONDIdxShift) & kECONDIdxMask; 
+}
+
+//
+uint8_t HGCalElectronicsId::econdeRx(){
+  return (value_ >> kECONDeRxShift) & kECONDeRxMask;
+}
+
+//
+uint8_t HGCalElectronicsId::halfrocChannel(){
+  return (value_ >> kHalfROCChannelShift) & kHalfROCChannelMask;
+}
diff --git a/DataFormats/HGCalDigi/src/classes_def.xml b/DataFormats/HGCalDigi/src/classes_def.xml
index 4d2bbce0ffb39..d1d35d1efc9c8 100644
--- a/DataFormats/HGCalDigi/src/classes_def.xml
+++ b/DataFormats/HGCalDigi/src/classes_def.xml
@@ -4,11 +4,19 @@
    <version ClassVersion="3" checksum="2026905296"/>
    </class>
 
+   <class name="HGCROCChannelDataFrame<HGCalElectronicsId>" ClassVersion="3">
+   <version ClassVersion="3" checksum="2054618736"/>
+   </class>
+
    <class name="std::vector<HGCROCChannelDataFrame<HGCalDetId> >"/>
+   <class name="std::vector<HGCROCChannelDataFrame<HGCalElectronicsId> >"/>
 
    <class name="edm::SortedCollection<HGCROCChannelDataFrame<HGCalDetId>, edm::StrictWeakOrdering<HGCROCChannelDataFrame<HGCalDetId> > >"/>
    <class name="edm::Wrapper<edm::SortedCollection<HGCROCChannelDataFrame<HGCalDetId>, edm::StrictWeakOrdering<HGCROCChannelDataFrame<HGCalDetId> > > >" />
 
+   <class name="edm::SortedCollection<HGCROCChannelDataFrame<HGCalElectronicsId>, edm::StrictWeakOrdering<HGCROCChannelDataFrame<HGCalElectronicsId> > >"/>
+   <class name="edm::Wrapper<edm::SortedCollection<HGCROCChannelDataFrame<HGCalElectronicsId>, edm::StrictWeakOrdering<HGCROCChannelDataFrame<HGCalElectronicsId> > > >" />
+
    <class name="PHGCSimAccumulator"/>
    <class name="PHGCSimAccumulator::DetIdSize"/>
    <class name="PHGCSimAccumulator::SimHitCollection"/>
diff --git a/DataFormats/HGCalDigi/test/BuildFile.xml b/DataFormats/HGCalDigi/test/BuildFile.xml
index e3920da58e7df..9e7d4b542dc33 100644
--- a/DataFormats/HGCalDigi/test/BuildFile.xml
+++ b/DataFormats/HGCalDigi/test/BuildFile.xml
@@ -2,3 +2,8 @@
   <flags TEST_RUNNER_ARGS=" 200000000 y"/>
   <use name="DataFormats/HGCalDigi"/>
 </bin>
+
+<bin file="HGCalElectronicsIdTest.cc" name="HGCalElectronicsId">
+  <flags TEST_RUNNER_ARGS=" 200000000"/>
+  <use name="DataFormats/HGCalDigi"/>
+</bin>
diff --git a/DataFormats/HGCalDigi/test/HGCalElectronicsIdTest.cc b/DataFormats/HGCalDigi/test/HGCalElectronicsIdTest.cc
new file mode 100644
index 0000000000000..4489c5dcc2137
--- /dev/null
+++ b/DataFormats/HGCalDigi/test/HGCalElectronicsIdTest.cc
@@ -0,0 +1,58 @@
+#include "DataFormats/HGCalDigi/interface/HGCalElectronicsId.h"
+#include <iostream>
+#include <cassert>
+#include <string>
+#include <chrono>
+#include <random>
+
+// run for instance with:
+//
+//                         time HGCalElectronicsId 10000000000 => 8 sec
+// for a measureble amount of time taken
+// acceptas an additional argument for verbosity level
+
+int main(int argc, char** argv) {
+  std::cout << "Basic check of HGCalElectronicsId class" << std::endl;
+
+  // first command line argument is the number of trials
+  unsigned long int repetitions = 100;
+  if (argc > 1)
+    repetitions = std::stoul(argv[1], nullptr, 0);
+  std::cout << "\t + repetitions [int]: " << repetitions << std::endl;
+
+  unsigned long int verbosity = 0;
+  if (argc > 2)
+    verbosity =  std::stoul(argv[2], nullptr, 0);
+  
+  // init static values
+  uint16_t fedid(0);
+  uint8_t captureblock(0), econdidx(0), econderx(0), halfrocch(0);
+
+  // http://www.cplusplus.com/reference/random/linear_congruential_engine/
+  unsigned seed1 = std::chrono::system_clock::now().time_since_epoch().count();
+  std::minstd_rand0 myrand(seed1);
+
+  // do the trials: time/performance test and exploit randomisation to check
+  unsigned long int u = 0;
+  for (; u < repetitions; u++) {
+
+      fedid = myrand() % 576;
+      captureblock = myrand() % 10;
+      econdidx = myrand() % 12;
+      econderx = myrand() % 12;
+      halfrocch = myrand() % 39;
+ 
+      HGCalElectronicsId eid(fedid,captureblock,econdidx,econderx,halfrocch);
+      assert(fedid==eid.fedId());
+      assert(captureblock==eid.captureBlock());
+      assert(econdidx==eid.econdIdx());
+      assert(econderx==eid.econdeRx());
+      assert(halfrocch==eid.halfrocChannel());
+
+      if(verbosity>0) eid.print(std::cout);
+  }
+  
+  std::cout << "\nDone " << repetitions << "\t" << u << std::endl;
+  
+  return 0;
+}

From fba0a438e87d84e7407a7b68301a9da169fc57f6 Mon Sep 17 00:00:00 2001
From: Pedro <psilva@cern.ch>
Date: Fri, 13 Jan 2023 15:17:33 +0100
Subject: [PATCH 2/2] apply code checks

---
 .../HGCalDigi/interface/HGCalElectronicsId.h  | 28 +++++++++-----
 .../HGCalDigi/src/HGCalElectronicsId.cc       | 31 +++++----------
 .../HGCalDigi/test/HGCalElectronicsIdTest.cc  | 38 +++++++++----------
 3 files changed, 47 insertions(+), 50 deletions(-)

diff --git a/DataFormats/HGCalDigi/interface/HGCalElectronicsId.h b/DataFormats/HGCalDigi/interface/HGCalElectronicsId.h
index d6a33ff3ae82b..b1b289e92c11f 100644
--- a/DataFormats/HGCalDigi/interface/HGCalElectronicsId.h
+++ b/DataFormats/HGCalDigi/interface/HGCalElectronicsId.h
@@ -19,9 +19,20 @@
 
 class HGCalElectronicsId {
 public:
-  
-  enum HGCalElectronicsIdMask { kFEDIDMask = 0x3ff, kCaptureBlockMask=0xf, kECONDIdxMask=0xf, kECONDeRxMask=0xf, kHalfROCChannelMask=0x3f };
-  enum HGCalElectronicsIdShift { kFEDIDShift = 18, kCaptureBlockShift=14, kECONDIdxShift=10, kECONDeRxShift=6, kHalfROCChannelShift=0 };
+  enum HGCalElectronicsIdMask {
+    kFEDIDMask = 0x3ff,
+    kCaptureBlockMask = 0xf,
+    kECONDIdxMask = 0xf,
+    kECONDeRxMask = 0xf,
+    kHalfROCChannelMask = 0x3f
+  };
+  enum HGCalElectronicsIdShift {
+    kFEDIDShift = 18,
+    kCaptureBlockShift = 14,
+    kECONDIdxShift = 10,
+    kECONDeRxShift = 6,
+    kHalfROCChannelShift = 0
+  };
 
   /**
      @short CTOR
@@ -30,7 +41,7 @@ class HGCalElectronicsId {
   HGCalElectronicsId(uint16_t fedid, uint8_t captureblock, uint8_t econdidx, uint8_t econderx, uint8_t halfrocch);
   HGCalElectronicsId(uint32_t value) : value_(value) {}
   HGCalElectronicsId(const HGCalElectronicsId& o) : value_(o.value_) {}
-  
+
   /**
      @short getters
   */
@@ -41,18 +52,15 @@ class HGCalElectronicsId {
   uint8_t econdIdx();
   uint8_t econdeRx();
   uint8_t halfrocChannel();
-  
+
   void print(std::ostream& out = std::cout) {
     out << "Raw=0x" << std::hex << raw() << std::dec << std::endl
-        << "\tFED-ID: " << (uint32_t)fedId()
-        << " Capture Block: " << (uint32_t)captureBlock()
-        << " ECON-D idx: " << (uint32_t)econdIdx()
-        << " eRx: " << (uint32_t)econdeRx()
+        << "\tFED-ID: " << (uint32_t)fedId() << " Capture Block: " << (uint32_t)captureBlock()
+        << " ECON-D idx: " << (uint32_t)econdIdx() << " eRx: " << (uint32_t)econdeRx()
         << " 1/2 ROC ch.: " << (uint32_t)halfrocChannel() << std::endl;
   }
 
 private:
-
   // a 32-bit word
   uint32_t value_;
 };
diff --git a/DataFormats/HGCalDigi/src/HGCalElectronicsId.cc b/DataFormats/HGCalDigi/src/HGCalElectronicsId.cc
index 896862fa503d9..32844b6dee9fc 100644
--- a/DataFormats/HGCalDigi/src/HGCalElectronicsId.cc
+++ b/DataFormats/HGCalDigi/src/HGCalElectronicsId.cc
@@ -1,35 +1,24 @@
 #include "DataFormats/HGCalDigi/interface/HGCalElectronicsId.h"
 
 //
-HGCalElectronicsId::HGCalElectronicsId(uint16_t fedid, uint8_t captureblock, uint8_t econdidx, uint8_t econderx, uint8_t halfrocch) {
-  value_ = ((fedid & kFEDIDMask) << kFEDIDShift)
-    | ((captureblock & kCaptureBlockMask) << kCaptureBlockShift)
-    | ((econdidx & kECONDIdxMask) << kECONDIdxShift)
-    | ((econderx & kECONDeRxMask) << kECONDeRxShift)
-    | ((halfrocch & kHalfROCChannelMask) << kHalfROCChannelShift);
+HGCalElectronicsId::HGCalElectronicsId(
+    uint16_t fedid, uint8_t captureblock, uint8_t econdidx, uint8_t econderx, uint8_t halfrocch) {
+  value_ = ((fedid & kFEDIDMask) << kFEDIDShift) | ((captureblock & kCaptureBlockMask) << kCaptureBlockShift) |
+           ((econdidx & kECONDIdxMask) << kECONDIdxShift) | ((econderx & kECONDeRxMask) << kECONDeRxShift) |
+           ((halfrocch & kHalfROCChannelMask) << kHalfROCChannelShift);
 }
 
 //
-uint16_t HGCalElectronicsId::fedId(){
-  return (value_ >> kFEDIDShift) & kFEDIDMask;
-}
+uint16_t HGCalElectronicsId::fedId() { return (value_ >> kFEDIDShift) & kFEDIDMask; }
 
 //
-uint8_t HGCalElectronicsId::captureBlock(){
-  return (value_ >> kCaptureBlockShift) & kCaptureBlockMask;
-}
+uint8_t HGCalElectronicsId::captureBlock() { return (value_ >> kCaptureBlockShift) & kCaptureBlockMask; }
 
 //
-uint8_t HGCalElectronicsId::econdIdx(){
-  return (value_ >> kECONDIdxShift) & kECONDIdxMask; 
-}
+uint8_t HGCalElectronicsId::econdIdx() { return (value_ >> kECONDIdxShift) & kECONDIdxMask; }
 
 //
-uint8_t HGCalElectronicsId::econdeRx(){
-  return (value_ >> kECONDeRxShift) & kECONDeRxMask;
-}
+uint8_t HGCalElectronicsId::econdeRx() { return (value_ >> kECONDeRxShift) & kECONDeRxMask; }
 
 //
-uint8_t HGCalElectronicsId::halfrocChannel(){
-  return (value_ >> kHalfROCChannelShift) & kHalfROCChannelMask;
-}
+uint8_t HGCalElectronicsId::halfrocChannel() { return (value_ >> kHalfROCChannelShift) & kHalfROCChannelMask; }
diff --git a/DataFormats/HGCalDigi/test/HGCalElectronicsIdTest.cc b/DataFormats/HGCalDigi/test/HGCalElectronicsIdTest.cc
index 4489c5dcc2137..c3f4c7b3c4930 100644
--- a/DataFormats/HGCalDigi/test/HGCalElectronicsIdTest.cc
+++ b/DataFormats/HGCalDigi/test/HGCalElectronicsIdTest.cc
@@ -22,8 +22,8 @@ int main(int argc, char** argv) {
 
   unsigned long int verbosity = 0;
   if (argc > 2)
-    verbosity =  std::stoul(argv[2], nullptr, 0);
-  
+    verbosity = std::stoul(argv[2], nullptr, 0);
+
   // init static values
   uint16_t fedid(0);
   uint8_t captureblock(0), econdidx(0), econderx(0), halfrocch(0);
@@ -35,24 +35,24 @@ int main(int argc, char** argv) {
   // do the trials: time/performance test and exploit randomisation to check
   unsigned long int u = 0;
   for (; u < repetitions; u++) {
-
-      fedid = myrand() % 576;
-      captureblock = myrand() % 10;
-      econdidx = myrand() % 12;
-      econderx = myrand() % 12;
-      halfrocch = myrand() % 39;
- 
-      HGCalElectronicsId eid(fedid,captureblock,econdidx,econderx,halfrocch);
-      assert(fedid==eid.fedId());
-      assert(captureblock==eid.captureBlock());
-      assert(econdidx==eid.econdIdx());
-      assert(econderx==eid.econdeRx());
-      assert(halfrocch==eid.halfrocChannel());
-
-      if(verbosity>0) eid.print(std::cout);
+    fedid = myrand() % 576;
+    captureblock = myrand() % 10;
+    econdidx = myrand() % 12;
+    econderx = myrand() % 12;
+    halfrocch = myrand() % 39;
+
+    HGCalElectronicsId eid(fedid, captureblock, econdidx, econderx, halfrocch);
+    assert(fedid == eid.fedId());
+    assert(captureblock == eid.captureBlock());
+    assert(econdidx == eid.econdIdx());
+    assert(econderx == eid.econdeRx());
+    assert(halfrocch == eid.halfrocChannel());
+
+    if (verbosity > 0)
+      eid.print(std::cout);
   }
-  
+
   std::cout << "\nDone " << repetitions << "\t" << u << std::endl;
-  
+
   return 0;
 }