CMS 3D CMS Logo

List of all members | Public Types | Public Member Functions | Private Attributes
HGCFEElectronics< DFr > Class Template Reference

models the behavior of the front-end electronics More...

#include <HGCFEElectronics.h>

Public Types

enum  HGCFEElectronicsFirmwareVersion { TRIVIAL, SIMPLE, WITHTOT }
 
enum  HGCFEElectronicsTOTMode { WEIGHTEDBYE, SIMPLETHRESHOLD }
 

Public Member Functions

void generateTimeOffset (CLHEP::HepRandomEngine *engine)
 
float getADClsb ()
 returns the LSB currently configured More...
 
float getADCThreshold ()
 
hgc_digi::FEADCPulseShapegetDefaultADCPulse ()
 getter for the default ADC pulse configured by python More...
 
float getMaxADC ()
 
float getMaxTDC ()
 
int getTargetMipValue ()
 
std::array< float, 3 > getTDCForToAOnset ()
 
float getTDClsb ()
 
float getTDCOnset ()
 
 HGCFEElectronics (const edm::ParameterSet &ps)
 CTOR. More...
 
void runShaper (DFr &dataFrame, hgc::HGCSimHitData &chargeColl, hgc::HGCSimHitData &toa, const hgc_digi::FEADCPulseShape &adcPulse, CLHEP::HepRandomEngine *engine, uint32_t thrADC=0, float lsbADC=-1, uint32_t gainIdx=0, float maxADC=-1, int thickness=1, float tdcOnsetAuto=-1, float noiseWidth=-1)
 switches according to the firmware version More...
 
void runShaper (DFr &dataFrame, hgc::HGCSimHitData &chargeColl, hgc::HGCSimHitData &toa, CLHEP::HepRandomEngine *engine, uint32_t thrADC=0, float lsbADC=-1, uint32_t gainIdx=0, float maxADC=-1, int thickness=1)
 
void runShaperWithToT (DFr &dataFrame, hgc::HGCSimHitData &chargeColl, hgc::HGCSimHitData &toa, CLHEP::HepRandomEngine *engine, uint32_t thrADC, float lsbADC, uint32_t gainIdx, float maxADC, int thickness, float tdcOnsetAuto, float noiseWidth, const hgc_digi::FEADCPulseShape &adcPulse)
 implements pulse shape and switch to time over threshold including deadtime More...
 
void runShaperWithToT (DFr &dataFrame, hgc::HGCSimHitData &chargeColl, hgc::HGCSimHitData &toa, CLHEP::HepRandomEngine *engine, uint32_t thrADC, float lsbADC, uint32_t gainIdx, float maxADC, int thickness, float tdcOnsetAuto, float noiseWidth)
 
void runSimpleShaper (DFr &dataFrame, hgc::HGCSimHitData &chargeColl, uint32_t thrADC, float lsbADC, uint32_t gainIdx, float maxADC, const hgc_digi::FEADCPulseShape &adcPulse)
 applies a shape to each time sample and propagates the tails to the subsequent time samples More...
 
void runSimpleShaper (DFr &dataFrame, hgc::HGCSimHitData &chargeColl, uint32_t thrADC, float lsbADC, uint32_t gainIdx, float maxADC)
 
void runTrivialShaper (DFr &dataFrame, hgc::HGCSimHitData &chargeColl, uint32_t thrADC, float lsbADC, uint32_t gainIdx, float maxADC)
 converts charge to digis without pulse shape More...
 
void setADClsb (float newLSB)
 
void SetNoiseValues (const std::vector< float > &noise_fC)
 
void setTDCfsc (float newTDCfsc)
 
uint32_t toaMode () const
 returns how ToT will be computed More...
 
 ~HGCFEElectronics ()
 DTOR. More...
 

Private Attributes

float adcLSB_fC_
 
hgc_digi::FEADCPulseShape adcPulse_
 
float adcSaturation_fC_
 
float adcThreshold_fC_
 
std::array< bool, hgc::nSamples > busyFlags
 
std::array< float, 3 > eventTimeOffset_ns_
 
uint32_t fwVersion_
 
std::array< float, 3 > jitterConstant_ns_
 
std::array< float, 3 > jitterNoise_ns_
 
hgc::HGCSimHitData newCharge
 
std::vector< float > noise_fC_
 
hgc_digi::FEADCPulseShape pulseAvgT_
 
uint32_t targetMIPvalue_ADC_
 
std::vector< float > tdcChargeDrainParameterisation_
 
std::array< float, 3 > tdcForToAOnset_fC_
 
float tdcLSB_fC_
 
uint32_t tdcNbits_
 
float tdcOnset_fC_
 
float tdcResolutionInNs_
 
float tdcSaturation_fC_
 
bool thresholdFollowsMIP_
 
std::array< bool, hgc::nSamples > toaFlags
 
hgc::HGCSimHitData toaFromToT
 
float toaLSB_ns_
 
uint32_t toaMode_
 
std::array< bool, hgc::nSamples > totFlags
 

Detailed Description

template<class DFr>
class HGCFEElectronics< DFr >

models the behavior of the front-end electronics

Definition at line 24 of file HGCFEElectronics.h.

Member Enumeration Documentation

◆ HGCFEElectronicsFirmwareVersion

Enumerator
TRIVIAL 
SIMPLE 
WITHTOT 

Definition at line 26 of file HGCFEElectronics.h.

◆ HGCFEElectronicsTOTMode

template<class DFr >
enum HGCFEElectronics::HGCFEElectronicsTOTMode
Enumerator
WEIGHTEDBYE 
SIMPLETHRESHOLD 

Definition at line 27 of file HGCFEElectronics.h.

Constructor & Destructor Documentation

◆ HGCFEElectronics()

template<class DFr >
HGCFEElectronics< DFr >::HGCFEElectronics ( const edm::ParameterSet ps)

CTOR.

Definition at line 12 of file HGCFEElectronics.cc.

References edm::ParameterSet::getParameter().

13  : fwVersion_{ps.getParameter<uint32_t>("fwVersion")},
14  adcPulse_{},
15  pulseAvgT_{},
17  adcSaturation_fC_{-1.0},
18  adcLSB_fC_{},
19  tdcLSB_fC_{},
20  tdcSaturation_fC_{-1.0},
22  tdcOnset_fC_{},
23  toaLSB_ns_{},
24  tdcResolutionInNs_{1e-9}, // set time resolution very small by default
28  eventTimeOffset_ns_{{0.02, 0.02, 0.02}},
29  noise_fC_{},
31  edm::LogVerbatim("HGCFE") << "[HGCFEElectronics] running with version " << fwVersion_ << std::endl;
32  if (ps.exists("adcPulse")) {
33  auto temp = ps.getParameter<std::vector<double> >("adcPulse");
34  for (unsigned i = 0; i < temp.size(); ++i) {
35  adcPulse_[i] = (float)temp[i];
36  }
37  // normalize adc pulse
38  for (unsigned i = 0; i < adcPulse_.size(); ++i) {
39  adcPulse_[i] = adcPulse_[i] / adcPulse_[2];
40  }
41  temp = ps.getParameter<std::vector<double> >("pulseAvgT");
42  for (unsigned i = 0; i < temp.size(); ++i) {
43  pulseAvgT_[i] = (float)temp[i];
44  }
45  }
46  if (ps.exists("adcNbits")) {
47  uint32_t adcNbits = ps.getParameter<uint32_t>("adcNbits");
48  adcSaturation_fC_ = ps.getParameter<double>("adcSaturation_fC");
50  edm::LogVerbatim("HGCFE") << "[HGCFEElectronics] " << adcNbits << " bit ADC defined"
51  << " with LSB=" << adcLSB_fC_ << " saturation to occur @ " << adcSaturation_fC_
52  << std::endl;
53  }
54 
55  if (ps.exists("tdcNbits")) {
56  tdcNbits_ = ps.getParameter<uint32_t>("tdcNbits");
57  setTDCfsc(ps.getParameter<double>("tdcSaturation_fC"));
58  edm::LogVerbatim("HGCFE") << "[HGCFEElectronics] " << tdcNbits_ << " bit TDC defined with LSB=" << tdcLSB_fC_
59  << " saturation to occur @ " << tdcSaturation_fC_
60  << " (NB lowered by 1 part in a million)" << std::endl;
61  }
62  if (ps.exists("targetMIPvalue_ADC"))
63  targetMIPvalue_ADC_ = ps.getParameter<uint32_t>("targetMIPvalue_ADC");
64  if (ps.exists("adcThreshold_fC"))
65  adcThreshold_fC_ = ps.getParameter<double>("adcThreshold_fC");
66  if (ps.exists("tdcOnset_fC"))
67  tdcOnset_fC_ = ps.getParameter<double>("tdcOnset_fC");
68  if (ps.exists("tdcForToAOnset_fC")) {
69  auto temp = ps.getParameter<std::vector<double> >("tdcForToAOnset_fC");
70  if (temp.size() == tdcForToAOnset_fC_.size()) {
71  std::copy_n(temp.begin(), temp.size(), tdcForToAOnset_fC_.begin());
72  } else {
73  throw cms::Exception("BadConfiguration") << " HGCFEElectronics wrong size for ToA thresholds ";
74  }
75  }
76  if (ps.exists("toaLSB_ns"))
77  toaLSB_ns_ = ps.getParameter<double>("toaLSB_ns");
78  if (ps.exists("tdcChargeDrainParameterisation")) {
79  for (auto val : ps.getParameter<std::vector<double> >("tdcChargeDrainParameterisation")) {
80  tdcChargeDrainParameterisation_.push_back((float)val);
81  }
82  }
83  if (ps.exists("tdcResolutionInPs"))
84  tdcResolutionInNs_ = ps.getParameter<double>("tdcResolutionInPs") * 1e-3; // convert to ns
85  if (ps.exists("toaMode"))
86  toaMode_ = ps.getParameter<uint32_t>("toaMode");
87 
88  if (ps.exists("jitterNoise_ns")) {
89  auto temp = ps.getParameter<std::vector<double> >("jitterNoise_ns");
90  if (temp.size() == jitterNoise_ns_.size()) {
91  std::copy_n(temp.begin(), temp.size(), jitterNoise_ns_.begin());
92  } else {
93  throw cms::Exception("BadConfiguration") << " HGCFEElectronics wrong size for ToA jitterNoise ";
94  }
95  }
96  if (ps.exists("jitterConstant_ns")) {
97  auto temp = ps.getParameter<std::vector<double> >("jitterConstant_ns");
98  if (temp.size() == jitterConstant_ns_.size()) {
99  std::copy_n(temp.begin(), temp.size(), jitterConstant_ns_.begin());
100  } else {
101  throw cms::Exception("BadConfiguration") << " HGCFEElectronics wrong size for ToA jitterConstant ";
102  }
103  }
104 }
Log< level::Info, true > LogVerbatim
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
bool exists(std::string const &parameterName) const
checks if a parameter exists
std::array< float, 3 > jitterNoise_ns_
uint32_t targetMIPvalue_ADC_
hgc_digi::FEADCPulseShape adcPulse_
std::vector< float > noise_fC_
std::array< float, 3 > eventTimeOffset_ns_
hgc_digi::FEADCPulseShape pulseAvgT_
void setTDCfsc(float newTDCfsc)
std::vector< float > tdcChargeDrainParameterisation_
std::array< float, 3 > jitterConstant_ns_
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29
std::array< float, 3 > tdcForToAOnset_fC_

◆ ~HGCFEElectronics()

template<class DFr >
HGCFEElectronics< DFr >::~HGCFEElectronics ( )
inline

DTOR.

Definition at line 190 of file HGCFEElectronics.h.

190 {}

Member Function Documentation

◆ generateTimeOffset()

template<class DFr >
void HGCFEElectronics< DFr >::generateTimeOffset ( CLHEP::HepRandomEngine *  engine)
inline

Definition at line 91 of file HGCFEElectronics.h.

References HGCFEElectronics< DFr >::eventTimeOffset_ns_, mps_fire::i, and HGCFEElectronics< DFr >::jitterConstant_ns_.

91  {
92  for (int i = 0; i < 3; i++)
93  eventTimeOffset_ns_[i] = CLHEP::RandGaussQ::shoot(engine, 0, jitterConstant_ns_[i]);
94  };
std::array< float, 3 > eventTimeOffset_ns_
std::array< float, 3 > jitterConstant_ns_

◆ getADClsb()

template<class DFr >
float HGCFEElectronics< DFr >::getADClsb ( )
inline

returns the LSB currently configured

Definition at line 99 of file HGCFEElectronics.h.

References HGCFEElectronics< DFr >::adcLSB_fC_.

99 { return adcLSB_fC_; }

◆ getADCThreshold()

template<class DFr >
float HGCFEElectronics< DFr >::getADCThreshold ( )
inline

Definition at line 102 of file HGCFEElectronics.h.

References HGCFEElectronics< DFr >::adcThreshold_fC_.

102 { return adcThreshold_fC_; }

◆ getDefaultADCPulse()

template<class DFr >
hgc_digi::FEADCPulseShape& HGCFEElectronics< DFr >::getDefaultADCPulse ( )
inline

getter for the default ADC pulse configured by python

Definition at line 185 of file HGCFEElectronics.h.

References HGCFEElectronics< DFr >::adcPulse_.

185 { return adcPulse_; }
hgc_digi::FEADCPulseShape adcPulse_

◆ getMaxADC()

template<class DFr >
float HGCFEElectronics< DFr >::getMaxADC ( )
inline

Definition at line 103 of file HGCFEElectronics.h.

References HGCFEElectronics< DFr >::adcSaturation_fC_.

103 { return adcSaturation_fC_; }

◆ getMaxTDC()

template<class DFr >
float HGCFEElectronics< DFr >::getMaxTDC ( )
inline

Definition at line 104 of file HGCFEElectronics.h.

References HGCFEElectronics< DFr >::tdcSaturation_fC_.

104 { return tdcSaturation_fC_; }

◆ getTargetMipValue()

template<class DFr >
int HGCFEElectronics< DFr >::getTargetMipValue ( )
inline

Definition at line 101 of file HGCFEElectronics.h.

References HGCFEElectronics< DFr >::targetMIPvalue_ADC_.

101 { return targetMIPvalue_ADC_; }
uint32_t targetMIPvalue_ADC_

◆ getTDCForToAOnset()

template<class DFr >
std::array<float, 3> HGCFEElectronics< DFr >::getTDCForToAOnset ( )
inline

Definition at line 106 of file HGCFEElectronics.h.

References HGCFEElectronics< DFr >::tdcForToAOnset_fC_.

106 { return tdcForToAOnset_fC_; }
std::array< float, 3 > tdcForToAOnset_fC_

◆ getTDClsb()

template<class DFr >
float HGCFEElectronics< DFr >::getTDClsb ( )
inline

Definition at line 100 of file HGCFEElectronics.h.

References HGCFEElectronics< DFr >::tdcLSB_fC_.

100 { return tdcLSB_fC_; }

◆ getTDCOnset()

template<class DFr >
float HGCFEElectronics< DFr >::getTDCOnset ( )
inline

Definition at line 105 of file HGCFEElectronics.h.

References HGCFEElectronics< DFr >::tdcOnset_fC_.

105 { return tdcOnset_fC_; }

◆ runShaper() [1/2]

template<class DFr >
void HGCFEElectronics< DFr >::runShaper ( DFr &  dataFrame,
hgc::HGCSimHitData chargeColl,
hgc::HGCSimHitData toa,
const hgc_digi::FEADCPulseShape adcPulse,
CLHEP::HepRandomEngine *  engine,
uint32_t  thrADC = 0,
float  lsbADC = -1,
uint32_t  gainIdx = 0,
float  maxADC = -1,
int  thickness = 1,
float  tdcOnsetAuto = -1,
float  noiseWidth = -1 
)
inline

switches according to the firmware version

Definition at line 37 of file HGCFEElectronics.h.

References hgceeDigitizer_cfi::adcPulse, HGCFEElectronics< DFr >::fwVersion_, HGCFEElectronics< DFr >::runShaperWithToT(), HGCFEElectronics< DFr >::runSimpleShaper(), HGCFEElectronics< DFr >::runTrivialShaper(), HGCFEElectronics< DFr >::SIMPLE, Calorimetry_cff::thickness, and HGCFEElectronics< DFr >::WITHTOT.

Referenced by HGCFEElectronics< DFr >::runShaper().

48  {
49  switch (fwVersion_) {
50  case SIMPLE: {
51  runSimpleShaper(dataFrame, chargeColl, thrADC, lsbADC, gainIdx, maxADC, adcPulse);
52  break;
53  }
54  case WITHTOT: {
55  runShaperWithToT(dataFrame,
56  chargeColl,
57  toa,
58  engine,
59  thrADC,
60  lsbADC,
61  gainIdx,
62  maxADC,
63  thickness,
64  tdcOnsetAuto,
65  noiseWidth,
66  adcPulse);
67  break;
68  }
69  default: {
70  runTrivialShaper(dataFrame, chargeColl, thrADC, lsbADC, gainIdx, maxADC);
71  break;
72  }
73  }
74  }
void runShaperWithToT(DFr &dataFrame, hgc::HGCSimHitData &chargeColl, hgc::HGCSimHitData &toa, CLHEP::HepRandomEngine *engine, uint32_t thrADC, float lsbADC, uint32_t gainIdx, float maxADC, int thickness, float tdcOnsetAuto, float noiseWidth, const hgc_digi::FEADCPulseShape &adcPulse)
implements pulse shape and switch to time over threshold including deadtime
void runSimpleShaper(DFr &dataFrame, hgc::HGCSimHitData &chargeColl, uint32_t thrADC, float lsbADC, uint32_t gainIdx, float maxADC, const hgc_digi::FEADCPulseShape &adcPulse)
applies a shape to each time sample and propagates the tails to the subsequent time samples ...
void runTrivialShaper(DFr &dataFrame, hgc::HGCSimHitData &chargeColl, uint32_t thrADC, float lsbADC, uint32_t gainIdx, float maxADC)
converts charge to digis without pulse shape

◆ runShaper() [2/2]

template<class DFr >
void HGCFEElectronics< DFr >::runShaper ( DFr &  dataFrame,
hgc::HGCSimHitData chargeColl,
hgc::HGCSimHitData toa,
CLHEP::HepRandomEngine *  engine,
uint32_t  thrADC = 0,
float  lsbADC = -1,
uint32_t  gainIdx = 0,
float  maxADC = -1,
int  thickness = 1 
)
inline

Definition at line 75 of file HGCFEElectronics.h.

References HGCFEElectronics< DFr >::adcPulse_, HGCFEElectronics< DFr >::runShaper(), and Calorimetry_cff::thickness.

83  {
84  runShaper(dataFrame, chargeColl, toa, adcPulse_, engine, thrADC, lsbADC, gainIdx, maxADC, thickness);
85  }
hgc_digi::FEADCPulseShape adcPulse_
void runShaper(DFr &dataFrame, hgc::HGCSimHitData &chargeColl, hgc::HGCSimHitData &toa, const hgc_digi::FEADCPulseShape &adcPulse, CLHEP::HepRandomEngine *engine, uint32_t thrADC=0, float lsbADC=-1, uint32_t gainIdx=0, float maxADC=-1, int thickness=1, float tdcOnsetAuto=-1, float noiseWidth=-1)
switches according to the firmware version

◆ runShaperWithToT() [1/2]

template<class DFr >
void HGCFEElectronics< DFr >::runShaperWithToT ( DFr &  dataFrame,
hgc::HGCSimHitData chargeColl,
hgc::HGCSimHitData toa,
CLHEP::HepRandomEngine *  engine,
uint32_t  thrADC,
float  lsbADC,
uint32_t  gainIdx,
float  maxADC,
int  thickness,
float  tdcOnsetAuto,
float  noiseWidth,
const hgc_digi::FEADCPulseShape adcPulse 
)

implements pulse shape and switch to time over threshold including deadtime

Definition at line 205 of file HGCFEElectronics.cc.

References gpuClustering::adc, hgceeDigitizer_cfi::adcPulse, ALCARECOTkAlJpsiMuMu_cff::charge, debug, MillePedeFileConverter_cfg::e, f, myMath::fast_expf(), createfilelist::int, SiStripPI::max, SiStripPI::min, mps_check::msg, hgchebackDigitizer_cfi::noise, HGCSample::set(), HGCSample::setToAValid(), HGCalUncalibRecHit_cfi::tdcOnset, and Calorimetry_cff::thickness.

Referenced by HGCFEElectronics< DFr >::runShaper(), and HGCFEElectronics< DFr >::runShaperWithToT().

216  {
217  busyFlags.fill(false);
218  totFlags.fill(false);
219  toaFlags.fill(false);
220  newCharge.fill(0.f);
221  toaFromToT.fill(0.f);
222 
223 #ifdef EDM_ML_DEBUG
224  constexpr bool debug_state(true);
225 #else
226  constexpr bool debug_state(false);
227 #endif
228 
229  bool debug = debug_state;
230 
231  float timeToA = 0.f;
232 
233  //configure the ADC <-> TDC transition depending on the value passed as argument
234  double tdcOnset(maxADC);
235  if (maxADC < 0) {
236  maxADC = adcSaturation_fC_;
238  }
239 
240  //configure the ADC LSB depending on the value passed as argument
241  if (lsbADC < 0)
242  lsbADC = adcLSB_fC_;
243 
244  //first look at time
245  //for pileup look only at intime signals
246  //ToA is in central BX if fired -- std::floor(BX/25.)+9;
247  int fireBX = 9;
248  //noise fluctuation on charge is added after ToA computation
249  //do not recheck the ToA firing threshold tdcForToAOnset_fC_[thickness-1] not to bias the efficiency
250  //to be done properly with realistic ToA shaper and jitter for the moment accounted in the smearing
251  if (toaColl[fireBX] != 0.f) {
252  timeToA = toaColl[fireBX];
253  float sensor_noise = noiseWidth <= 0 ? noise_fC_[thickness - 1] : noiseWidth;
254  float noise = jitterNoise_ns_[thickness - 1] * sensor_noise;
255  float jitter = chargeColl[fireBX] == 0 ? 0 : (noise / chargeColl[fireBX]);
256  if (jitter != 0)
257  timeToA = CLHEP::RandGaussQ::shoot(engine, timeToA, jitter);
258  else if (tdcResolutionInNs_ != 0)
259  timeToA = CLHEP::RandGaussQ::shoot(engine, timeToA, tdcResolutionInNs_);
260  timeToA += eventTimeOffset_ns_[thickness - 1];
261  if (timeToA >= 0.f && timeToA <= 25.f)
262  toaFlags[fireBX] = true;
263  }
264 
265  //now look at charge
266  //first identify bunches which will trigger ToT
267  //if(debug_state) edm::LogVerbatim("HGCFE") << "[runShaperWithToT]" << std::endl;
268  for (int it = 0; it < (int)(chargeColl.size()); ++it) {
269  debug = debug_state;
270  //if already flagged as busy it can't be re-used to trigger the ToT
271  if (busyFlags[it])
272  continue;
273 
274  if (tdcOnsetAuto < 0) {
275  tdcOnsetAuto = tdcOnset_fC_;
276  }
277  //if below TDC onset will be handled by SARS ADC later
278  float charge = chargeColl[it];
279  if (charge < tdcOnset) {
280  debug = false;
281  continue;
282  }
283 
284  //raise TDC mode for charge computation
285  //ToA anyway fired independently will be sorted out with realistic ToA dedicated shaper
286  float toa = timeToA;
287  totFlags[it] = true;
288 
289  if (debug)
290  edm::LogVerbatim("HGCFE") << "\t q=" << charge << " fC with <toa>=" << toa << " ns, triggers ToT @ " << it
291  << std::endl;
292 
293  //compute total charge to be integrated and integration time
294  //needs a loop as ToT will last as long as there is charge to dissipate
295  int busyBxs(0);
296  float totalCharge(charge), finalToA(toa), integTime(0);
297  while (true) {
298  //compute integration time in ns and # bunches
299  //float newIntegTime(0);
300  int poffset = 0;
301  float charge_offset = 0.f;
302  const float charge_kfC(totalCharge * 1e-3);
303  if (charge_kfC < tdcChargeDrainParameterisation_[3]) {
304  //newIntegTime=tdcChargeDrainParameterisation_[0]*pow(charge_kfC,2)+tdcChargeDrainParameterisation_[1]*charge_kfC+tdcChargeDrainParameterisation_[2];
305  } else if (charge_kfC < tdcChargeDrainParameterisation_[7]) {
306  poffset = 4;
307  charge_offset = tdcChargeDrainParameterisation_[3];
308  //newIntegTime=tdcChargeDrainParameterisation_[4]*pow(charge_kfC-tdcChargeDrainParameterisation_[3],2)+tdcChargeDrainParameterisation_[5]*(charge_kfC-tdcChargeDrainParameterisation_[3])+tdcChargeDrainParameterisation_[6];
309  } else {
310  poffset = 8;
311  charge_offset = tdcChargeDrainParameterisation_[7];
312  //newIntegTime=tdcChargeDrainParameterisation_[8]*pow(charge_kfC-tdcChargeDrainParameterisation_[7],2)+tdcChargeDrainParameterisation_[9]*(charge_kfC-tdcChargeDrainParameterisation_[7])+tdcChargeDrainParameterisation_[10];
313  }
314  const float charge_mod = charge_kfC - charge_offset;
315  const float newIntegTime =
316  ((tdcChargeDrainParameterisation_[poffset] * charge_mod + tdcChargeDrainParameterisation_[poffset + 1]) *
317  charge_mod +
318  tdcChargeDrainParameterisation_[poffset + 2]);
319 
320  const int newBusyBxs = std::floor(newIntegTime / 25.f) + 1;
321 
322  //if no update is needed regarding the number of bunches,
323  //then the ToT integration time has converged
324  integTime = newIntegTime;
325  if (newBusyBxs == busyBxs)
326  break;
327 
328  //update charge integrated during ToT
329  if (debug) {
330  if (busyBxs == 0)
331  edm::LogVerbatim("HGCFE") << "\t Intial busy estimate=" << integTime << " ns = " << newBusyBxs << " bxs"
332  << std::endl;
333  else
334  edm::LogVerbatim("HGCFE") << "\t ...integrated charge overflows initial busy estimate, interating again"
335  << std::endl;
336  }
337 
338  //update number of busy bunches
339  busyBxs = newBusyBxs;
340 
341  //reset charge to be integrated
342  totalCharge = charge;
343  if (toaMode_ == WEIGHTEDBYE)
344  finalToA = toa * charge;
345 
346  //add leakage from previous bunches in SARS ADC mode
347  for (int jt = 0; jt < it; ++jt) {
348  const unsigned int deltaT = (it - jt);
349  if ((deltaT + 2) >= adcPulse.size() || chargeColl[jt] == 0.f || totFlags[jt] || busyFlags[jt])
350  continue;
351 
352  const float leakCharge = chargeColl[jt] * adcPulse[deltaT + 2];
353  totalCharge += leakCharge;
354  if (toaMode_ == WEIGHTEDBYE)
355  finalToA += leakCharge * pulseAvgT_[deltaT + 2];
356 
357  if (debug)
358  edm::LogVerbatim("HGCFE") << "\t\t leaking " << chargeColl[jt] << " fC @ deltaT=-" << deltaT << " -> +"
359  << leakCharge << " with avgT=" << pulseAvgT_[deltaT + 2] << std::endl;
360  }
361 
362  //add contamination from posterior bunches
363  for (int jt = it + 1; jt < it + busyBxs && jt < dataFrame.size(); ++jt) {
364  //this charge will be integrated in TDC mode
365  //disable for SARS ADC
366  busyFlags[jt] = true;
367 
368  const float extraCharge = chargeColl[jt];
369  if (extraCharge == 0.f)
370  continue;
371  if (debug)
372  edm::LogVerbatim("HGCFE") << "\t\t adding " << extraCharge << " fC @ deltaT=+" << (jt - it) << std::endl;
373 
374  totalCharge += extraCharge;
375  if (toaMode_ == WEIGHTEDBYE)
376  finalToA += extraCharge * toaColl[jt];
377  }
378 
379  //finalize ToA contamination
380  if (toaMode_ == WEIGHTEDBYE)
381  finalToA /= totalCharge;
382  }
383 
384  newCharge[it] = (totalCharge - tdcOnset);
385 
386  if (debug)
387  edm::LogVerbatim("HGCFE") << "\t Final busy estimate=" << integTime << " ns = " << busyBxs << " bxs" << std::endl
388  << "\t Total integrated=" << totalCharge << " fC <toa>=" << toaFromToT[it]
389  << " (raw=" << finalToA << ") ns " << std::endl;
390 
391  //last fC (tdcOnset) are dissipated trough pulse
392  if (it + busyBxs < (int)(newCharge.size())) {
393  const float deltaT2nextBx((busyBxs * 25 - integTime));
394  const float tdcOnsetLeakage(tdcOnset * vdt::fast_expf(-deltaT2nextBx / tdcChargeDrainParameterisation_[11]));
395  if (debug)
396  edm::LogVerbatim("HGCFE") << "\t Leaking remainder of TDC onset " << tdcOnset << " fC, to be dissipated in "
397  << deltaT2nextBx << " DeltaT/tau=" << deltaT2nextBx << " / "
398  << tdcChargeDrainParameterisation_[11] << " ns, adds " << tdcOnsetLeakage << " fC @ "
399  << it + busyBxs << " bx (first free bx)" << std::endl;
400  newCharge[it + busyBxs] += tdcOnsetLeakage;
401  }
402  }
403 
404  //including the leakage from bunches in SARS ADC when not declared busy or in ToT
405  auto runChargeSharing = [&]() {
406  int ipulse = 0;
407  for (int it = 0; it < (int)(chargeColl.size()); ++it) {
408  //if busy, charge has been already integrated
409  //if(debug) edm::LogVerbatim("HGCFE") << "\t SARS ADC pulse activated @ " << it << " : ";
410  if (!totFlags[it] & !busyFlags[it]) {
411  const int start = std::max(0, 2 - it);
412  const int stop = std::min((int)adcPulse.size(), (int)newCharge.size() - it + 2);
413  for (ipulse = start; ipulse < stop; ++ipulse) {
414  const int itoffset = it + ipulse - 2;
415  //notice that if the channel is already busy,
416  //it has already been affected by the leakage of the SARS ADC
417  //if(totFlags[itoffset] || busyFlags[itoffset]) continue;
418  if (!totFlags[itoffset] & !busyFlags[itoffset]) {
419  newCharge[itoffset] += chargeColl[it] * adcPulse[ipulse];
420  }
421  //if(debug) edm::LogVerbatim("HGCFE") << " | " << itoffset << " " << chargeColl[it]*adcPulse[ipulse] << "( " << chargeColl[it] << "->";
422  //if(debug) edm::LogVerbatim("HGCFE") << newCharge[itoffset] << ") ";
423  }
424  }
425 
426  if (debug)
427  edm::LogVerbatim("HGCFE") << std::endl;
428  }
429  };
430  runChargeSharing();
431 
432  //For the future need to understand how to deal with toa for out of time signals
433  //and for that should keep track of the BX firing the ToA somewhere (also to restore the use of finalToA)
434  /*
435  float finalToA(0.);
436  for(int it=0; it<(int)(newCharge.size()); it++){
437  if(toaFlags[it]){
438  finalToA = toaFromToT[it];
439  //to avoid +=25 for small negative time taken as 0
440  while(finalToA < -1.e-5) finalToA+=25.f;
441  while(finalToA > 25.f) finalToA-=25.f;
442  toaFromToT[it] = finalToA;
443  }
444  }
445  */
446  //timeToA is already in 0-25ns range by construction
447 
448  //set new ADCs and ToA
449  if (debug)
450  edm::LogVerbatim("HGCFE") << "\t final result : ";
451  for (int it = 0; it < (int)(newCharge.size()); it++) {
452  if (debug)
453  edm::LogVerbatim("HGCFE") << chargeColl[it] << " -> " << newCharge[it] << " ";
454 
455  HGCSample newSample;
456  if (totFlags[it] || busyFlags[it]) {
457  if (totFlags[it]) {
458  //brute force saturation, maybe could to better with an exponential like saturation
459  const float saturatedCharge(std::min(newCharge[it], tdcSaturation_fC_));
460  //working version for in-time PU and signal
461  newSample.set(
462  true, true, gainIdx, (uint16_t)(timeToA / toaLSB_ns_), (uint16_t)(std::floor(saturatedCharge / tdcLSB_fC_)));
463  if (toaFlags[it])
464  newSample.setToAValid(true);
465  } else {
466  newSample.set(false, true, gainIdx, 0, 0);
467  }
468  } else {
469  //brute force saturation, maybe could to better with an exponential like saturation
470  const uint16_t adc = std::floor(std::min(newCharge[it], maxADC) / lsbADC);
471  //working version for in-time PU and signal
472  newSample.set(adc > thrADC, false, gainIdx, (uint16_t)(timeToA / toaLSB_ns_), adc);
473  if (toaFlags[it])
474  newSample.setToAValid(true);
475  }
476  dataFrame.setSample(it, newSample);
477  }
478 
479  if (debug) {
480  std::ostringstream msg;
481  dataFrame.print(msg);
482  edm::LogVerbatim("HGCFE") << msg.str() << std::endl;
483  }
484 }
Definition: start.py:1
std::array< bool, hgc::nSamples > busyFlags
Log< level::Info, true > LogVerbatim
hgc::HGCSimHitData toaFromToT
wrapper for a data word
Definition: HGCSample.h:13
std::array< float, 3 > jitterNoise_ns_
std::vector< float > noise_fC_
double f[11][100]
std::array< float, 3 > eventTimeOffset_ns_
void setToAValid(bool toaFired)
Definition: HGCSample.h:47
#define debug
Definition: HDRShower.cc:19
std::array< bool, hgc::nSamples > totFlags
tuple msg
Definition: mps_check.py:286
hgc_digi::FEADCPulseShape pulseAvgT_
float fast_expf(float x)
std::vector< float > tdcChargeDrainParameterisation_
void set(bool thr, bool mode, uint16_t gain, uint16_t toa, uint16_t data)
Definition: HGCSample.h:49
hgc::HGCSimHitData newCharge
uint16_t *__restrict__ uint16_t const *__restrict__ adc
std::array< bool, hgc::nSamples > toaFlags

◆ runShaperWithToT() [2/2]

template<class DFr >
void HGCFEElectronics< DFr >::runShaperWithToT ( DFr &  dataFrame,
hgc::HGCSimHitData chargeColl,
hgc::HGCSimHitData toa,
CLHEP::HepRandomEngine *  engine,
uint32_t  thrADC,
float  lsbADC,
uint32_t  gainIdx,
float  maxADC,
int  thickness,
float  tdcOnsetAuto,
float  noiseWidth 
)
inline

Definition at line 152 of file HGCFEElectronics.h.

References HGCFEElectronics< DFr >::adcPulse_, HGCFEElectronics< DFr >::runShaperWithToT(), and Calorimetry_cff::thickness.

162  {
163  runShaperWithToT(dataFrame,
164  chargeColl,
165  toa,
166  engine,
167  thrADC,
168  lsbADC,
169  gainIdx,
170  maxADC,
171  thickness,
172  tdcOnsetAuto,
173  noiseWidth,
174  adcPulse_);
175  }
void runShaperWithToT(DFr &dataFrame, hgc::HGCSimHitData &chargeColl, hgc::HGCSimHitData &toa, CLHEP::HepRandomEngine *engine, uint32_t thrADC, float lsbADC, uint32_t gainIdx, float maxADC, int thickness, float tdcOnsetAuto, float noiseWidth, const hgc_digi::FEADCPulseShape &adcPulse)
implements pulse shape and switch to time over threshold including deadtime
hgc_digi::FEADCPulseShape adcPulse_

◆ runSimpleShaper() [1/2]

template<class DFr >
void HGCFEElectronics< DFr >::runSimpleShaper ( DFr &  dataFrame,
hgc::HGCSimHitData chargeColl,
uint32_t  thrADC,
float  lsbADC,
uint32_t  gainIdx,
float  maxADC,
const hgc_digi::FEADCPulseShape adcPulse 
)

applies a shape to each time sample and propagates the tails to the subsequent time samples

Definition at line 147 of file HGCFEElectronics.cc.

References gpuClustering::adc, hgceeDigitizer_cfi::adcPulse, ALCARECOTkAlJpsiMuMu_cff::charge, debug, f, createfilelist::int, SiStripPI::min, mps_check::msg, and HGCSample::set().

Referenced by HGCFEElectronics< DFr >::runShaper(), and HGCFEElectronics< DFr >::runSimpleShaper().

153  {
154  //convolute with pulse shape to compute new ADCs
155  newCharge.fill(0.f);
156  bool debug(false);
157  for (int it = 0; it < (int)(chargeColl.size()); it++) {
158  const float charge(chargeColl[it]);
159  if (charge == 0.f)
160  continue;
161 
162 #ifdef EDM_ML_DEBUG
164 #endif
165 
166  if (debug)
167  edm::LogVerbatim("HGCFE") << "\t Redistributing SARS ADC" << charge << " @ " << it;
168 
169  for (int ipulse = -2; ipulse < (int)(adcPulse.size()) - 2; ipulse++) {
170  if (it + ipulse < 0)
171  continue;
172  if (it + ipulse >= (int)(dataFrame.size()))
173  continue;
174  const float chargeLeak = charge * adcPulse[(ipulse + 2)];
175  newCharge[it + ipulse] += chargeLeak;
176 
177  if (debug)
178  edm::LogVerbatim("HGCFE") << " | " << it + ipulse << " " << chargeLeak;
179  }
180 
181  if (debug)
182  edm::LogVerbatim("HGCFE") << std::endl;
183  }
184 
185  for (int it = 0; it < (int)(newCharge.size()); it++) {
186  //brute force saturation, maybe could to better with an exponential like saturation
187  const uint32_t adc = std::floor(std::min(newCharge[it], maxADC) / lsbADC);
188  HGCSample newSample;
189  newSample.set(adc > thrADC, false, gainIdx, 0, adc);
190  dataFrame.setSample(it, newSample);
191 
192  if (debug)
193  edm::LogVerbatim("HGCFE") << adc << " (" << std::min(newCharge[it], maxADC) << "/" << lsbADC << " ) ";
194  }
195 
196  if (debug) {
197  std::ostringstream msg;
198  dataFrame.print(msg);
199  edm::LogVerbatim("HGCFE") << msg.str() << std::endl;
200  }
201 }
Log< level::Info, true > LogVerbatim
wrapper for a data word
Definition: HGCSample.h:13
double f[11][100]
#define debug
Definition: HDRShower.cc:19
tuple msg
Definition: mps_check.py:286
void set(bool thr, bool mode, uint16_t gain, uint16_t toa, uint16_t data)
Definition: HGCSample.h:49
hgc::HGCSimHitData newCharge
uint16_t *__restrict__ uint16_t const *__restrict__ adc

◆ runSimpleShaper() [2/2]

template<class DFr >
void HGCFEElectronics< DFr >::runSimpleShaper ( DFr &  dataFrame,
hgc::HGCSimHitData chargeColl,
uint32_t  thrADC,
float  lsbADC,
uint32_t  gainIdx,
float  maxADC 
)
inline

Definition at line 132 of file HGCFEElectronics.h.

References HGCFEElectronics< DFr >::adcPulse_, and HGCFEElectronics< DFr >::runSimpleShaper().

133  {
134  runSimpleShaper(dataFrame, chargeColl, thrADC, lsbADC, gainIdx, maxADC, adcPulse_);
135  }
hgc_digi::FEADCPulseShape adcPulse_
void runSimpleShaper(DFr &dataFrame, hgc::HGCSimHitData &chargeColl, uint32_t thrADC, float lsbADC, uint32_t gainIdx, float maxADC, const hgc_digi::FEADCPulseShape &adcPulse)
applies a shape to each time sample and propagates the tails to the subsequent time samples ...

◆ runTrivialShaper()

template<class DFr >
void HGCFEElectronics< DFr >::runTrivialShaper ( DFr &  dataFrame,
hgc::HGCSimHitData chargeColl,
uint32_t  thrADC,
float  lsbADC,
uint32_t  gainIdx,
float  maxADC 
)

converts charge to digis without pulse shape

Definition at line 108 of file HGCFEElectronics.cc.

References gpuClustering::adc, debug, MillePedeFileConverter_cfg::e, createfilelist::int, SiStripPI::min, mps_check::msg, and HGCSample::set().

Referenced by HGCFEElectronics< DFr >::runShaper().

109  {
110  bool debug(false);
111 
112 #ifdef EDM_ML_DEBUG
113  for (int it = 0; it < (int)(chargeColl.size()); it++)
114  debug |= (chargeColl[it] > adcThreshold_fC_);
115 #endif
116 
117  if (debug)
118  edm::LogVerbatim("HGCFE") << "[runTrivialShaper]" << std::endl;
119 
120  if (lsbADC < 0)
121  lsbADC = adcLSB_fC_;
122  if (maxADC < 0)
123  // lower adcSaturation_fC_ by one part in a million
124  // to ensure largest charge converted in bits is 0xfff==4095, not 0x1000
125  // no effect on charges loewer than; no impact on cpu time, only done once
126  maxADC = adcSaturation_fC_ * (1 - 1e-6);
127  for (int it = 0; it < (int)(chargeColl.size()); it++) {
128  //brute force saturation, maybe could to better with an exponential like saturation
129  const uint32_t adc = std::floor(std::min(chargeColl[it], maxADC) / lsbADC);
130  HGCSample newSample;
131  newSample.set(adc > thrADC, false, gainIdx, 0, adc);
132  dataFrame.setSample(it, newSample);
133 
134  if (debug)
135  edm::LogVerbatim("HGCFE") << adc << " (" << chargeColl[it] << "/" << adcLSB_fC_ << ") ";
136  }
137 
138  if (debug) {
139  std::ostringstream msg;
140  dataFrame.print(msg);
141  edm::LogVerbatim("HGCFE") << msg.str() << std::endl;
142  }
143 }
Log< level::Info, true > LogVerbatim
wrapper for a data word
Definition: HGCSample.h:13
#define debug
Definition: HDRShower.cc:19
tuple msg
Definition: mps_check.py:286
void set(bool thr, bool mode, uint16_t gain, uint16_t toa, uint16_t data)
Definition: HGCSample.h:49
uint16_t *__restrict__ uint16_t const *__restrict__ adc

◆ setADClsb()

template<class DFr >
void HGCFEElectronics< DFr >::setADClsb ( float  newLSB)
inline

Definition at line 107 of file HGCFEElectronics.h.

References HGCFEElectronics< DFr >::adcLSB_fC_.

107 { adcLSB_fC_ = newLSB; }

◆ SetNoiseValues()

template<class DFr >
void HGCFEElectronics< DFr >::SetNoiseValues ( const std::vector< float > &  noise_fC)
inline

Definition at line 87 of file HGCFEElectronics.h.

References hgceeDigitizer_cfi::noise_fC, and HGCFEElectronics< DFr >::noise_fC_.

87  {
88  noise_fC_.insert(noise_fC_.end(), noise_fC.begin(), noise_fC.end());
89  };
std::vector< float > noise_fC_

◆ setTDCfsc()

template<class DFr >
void HGCFEElectronics< DFr >::setTDCfsc ( float  newTDCfsc)
inline

Definition at line 108 of file HGCFEElectronics.h.

References MillePedeFileConverter_cfg::e, funct::pow(), HGCFEElectronics< DFr >::tdcLSB_fC_, HGCFEElectronics< DFr >::tdcNbits_, and HGCFEElectronics< DFr >::tdcSaturation_fC_.

108  {
109  tdcSaturation_fC_ = newTDCfsc;
111  // lower tdcSaturation_fC_ by one part in a million
112  // to ensure largest charge converted in bits is 0xfff and not 0x000
113  tdcSaturation_fC_ *= (1. - 1e-6);
114  }
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29

◆ toaMode()

template<class DFr >
uint32_t HGCFEElectronics< DFr >::toaMode ( ) const
inline

returns how ToT will be computed

Definition at line 180 of file HGCFEElectronics.h.

References HGCFEElectronics< DFr >::toaMode_.

180 { return toaMode_; }

Member Data Documentation

◆ adcLSB_fC_

template<class DFr >
float HGCFEElectronics< DFr >::adcLSB_fC_
private

◆ adcPulse_

template<class DFr >
hgc_digi::FEADCPulseShape HGCFEElectronics< DFr >::adcPulse_
private

◆ adcSaturation_fC_

template<class DFr >
float HGCFEElectronics< DFr >::adcSaturation_fC_
private

Definition at line 198 of file HGCFEElectronics.h.

Referenced by HGCFEElectronics< DFr >::getMaxADC().

◆ adcThreshold_fC_

template<class DFr >
float HGCFEElectronics< DFr >::adcThreshold_fC_
private

Definition at line 198 of file HGCFEElectronics.h.

Referenced by HGCFEElectronics< DFr >::getADCThreshold().

◆ busyFlags

template<class DFr >
std::array<bool, hgc::nSamples> HGCFEElectronics< DFr >::busyFlags
private

Definition at line 207 of file HGCFEElectronics.h.

◆ eventTimeOffset_ns_

template<class DFr >
std::array<float, 3> HGCFEElectronics< DFr >::eventTimeOffset_ns_
private

Definition at line 201 of file HGCFEElectronics.h.

Referenced by HGCFEElectronics< DFr >::generateTimeOffset().

◆ fwVersion_

template<class DFr >
uint32_t HGCFEElectronics< DFr >::fwVersion_
private

Definition at line 194 of file HGCFEElectronics.h.

Referenced by HGCFEElectronics< DFr >::runShaper().

◆ jitterConstant_ns_

template<class DFr >
std::array<float, 3> HGCFEElectronics< DFr >::jitterConstant_ns_
private

Definition at line 201 of file HGCFEElectronics.h.

Referenced by HGCFEElectronics< DFr >::generateTimeOffset().

◆ jitterNoise_ns_

template<class DFr >
std::array<float, 3> HGCFEElectronics< DFr >::jitterNoise_ns_
private

Definition at line 201 of file HGCFEElectronics.h.

◆ newCharge

template<class DFr >
hgc::HGCSimHitData HGCFEElectronics< DFr >::newCharge
private

Definition at line 208 of file HGCFEElectronics.h.

◆ noise_fC_

template<class DFr >
std::vector<float> HGCFEElectronics< DFr >::noise_fC_
private

Definition at line 202 of file HGCFEElectronics.h.

Referenced by HGCFEElectronics< DFr >::SetNoiseValues().

◆ pulseAvgT_

template<class DFr >
hgc_digi::FEADCPulseShape HGCFEElectronics< DFr >::pulseAvgT_
private

Definition at line 195 of file HGCFEElectronics.h.

◆ targetMIPvalue_ADC_

template<class DFr >
uint32_t HGCFEElectronics< DFr >::targetMIPvalue_ADC_
private

Definition at line 200 of file HGCFEElectronics.h.

Referenced by HGCFEElectronics< DFr >::getTargetMipValue().

◆ tdcChargeDrainParameterisation_

template<class DFr >
std::vector<float> HGCFEElectronics< DFr >::tdcChargeDrainParameterisation_
private

Definition at line 197 of file HGCFEElectronics.h.

◆ tdcForToAOnset_fC_

template<class DFr >
std::array<float, 3> HGCFEElectronics< DFr >::tdcForToAOnset_fC_
private

Definition at line 196 of file HGCFEElectronics.h.

Referenced by HGCFEElectronics< DFr >::getTDCForToAOnset().

◆ tdcLSB_fC_

template<class DFr >
float HGCFEElectronics< DFr >::tdcLSB_fC_
private

◆ tdcNbits_

template<class DFr >
uint32_t HGCFEElectronics< DFr >::tdcNbits_
private

Definition at line 204 of file HGCFEElectronics.h.

Referenced by HGCFEElectronics< DFr >::setTDCfsc().

◆ tdcOnset_fC_

template<class DFr >
float HGCFEElectronics< DFr >::tdcOnset_fC_
private

Definition at line 198 of file HGCFEElectronics.h.

Referenced by HGCFEElectronics< DFr >::getTDCOnset().

◆ tdcResolutionInNs_

template<class DFr >
float HGCFEElectronics< DFr >::tdcResolutionInNs_
private

Definition at line 198 of file HGCFEElectronics.h.

◆ tdcSaturation_fC_

template<class DFr >
float HGCFEElectronics< DFr >::tdcSaturation_fC_
private

◆ thresholdFollowsMIP_

template<class DFr >
bool HGCFEElectronics< DFr >::thresholdFollowsMIP_
private

Definition at line 205 of file HGCFEElectronics.h.

◆ toaFlags

template<class DFr >
std::array<bool, hgc::nSamples> HGCFEElectronics< DFr >::toaFlags
private

Definition at line 207 of file HGCFEElectronics.h.

◆ toaFromToT

template<class DFr >
hgc::HGCSimHitData HGCFEElectronics< DFr >::toaFromToT
private

Definition at line 208 of file HGCFEElectronics.h.

◆ toaLSB_ns_

template<class DFr >
float HGCFEElectronics< DFr >::toaLSB_ns_
private

Definition at line 198 of file HGCFEElectronics.h.

◆ toaMode_

template<class DFr >
uint32_t HGCFEElectronics< DFr >::toaMode_
private

Definition at line 203 of file HGCFEElectronics.h.

Referenced by HGCFEElectronics< DFr >::toaMode().

◆ totFlags

template<class DFr >
std::array<bool, hgc::nSamples> HGCFEElectronics< DFr >::totFlags
private

Definition at line 207 of file HGCFEElectronics.h.