CMS 3D CMS Logo

HGCDigitizer.cc
Go to the documentation of this file.
21 #include <algorithm>
22 #include <boost/foreach.hpp>
24 
25 //#define EDM_ML_DEBUG
26 using namespace std;
27 using namespace hgc_digi;
28 
29 typedef std::unordered_map<uint32_t, std::vector<std::pair<float, float>>> IdHit_Map;
30 typedef std::tuple<float, float, float> hit_timeStamp;
31 typedef std::unordered_map<uint32_t, std::vector<hit_timeStamp>> hitRec_container;
32 
33 namespace {
34 
35  constexpr std::array<double, 4> occupancyGuesses = {{0.5, 0.2, 0.2, 0.8}};
36 
37  float getPositionDistance(const HGCalGeometry* geom, const DetId& id) { return geom->getPosition(id).mag(); }
38 
39  int getCellThickness(const HGCalGeometry* geom, const DetId& detid) {
40  const auto& dddConst = geom->topology().dddConstants();
41  return (1 + dddConst.waferType(detid));
42  }
43 
44  void getValidDetIds(const HGCalGeometry* geom, std::unordered_set<DetId>& valid) {
45  const std::vector<DetId>& ids = geom->getValidDetIds();
46  valid.reserve(ids.size());
47  valid.insert(ids.begin(), ids.end());
48  }
49 
50  DetId simToReco(const HGCalGeometry* geom, unsigned simId) {
51  DetId result(0);
52  const auto& topo = geom->topology();
53  const auto& dddConst = topo.dddConstants();
54 
55  if (dddConst.waferHexagon8() || dddConst.tileTrapezoid()) {
56  result = DetId(simId);
57  } else {
58  int subdet(DetId(simId).subdetId()), layer, cell, sec, subsec, zp;
59  HGCalTestNumbering::unpackHexagonIndex(simId, subdet, zp, layer, sec, subsec, cell);
60  //sec is wafer and subsec is celltyp
61  //skip this hit if after ganging it is not valid
62  auto recoLayerCell = dddConst.simToReco(cell, layer, sec, topo.detectorType());
63  cell = recoLayerCell.first;
64  layer = recoLayerCell.second;
65  if (layer < 0 || cell < 0) {
66  return result;
67  } else {
68  //assign the RECO DetId
69  result = HGCalDetId((ForwardSubdetector)subdet, zp, layer, subsec, sec, cell);
70  }
71  }
72  return result;
73  }
74 
75  void saveSimHitAccumulator_forPreMix(PHGCSimAccumulator& simResult,
76  const hgc::HGCPUSimHitDataAccumulator& simData,
77  const std::unordered_set<DetId>& validIds,
78  const float minCharge,
79  const float maxCharge) {
80  constexpr auto nEnergies = std::tuple_size<decltype(hgc_digi::HGCCellHitInfo().PUhit_info)>::value;
81  static_assert(nEnergies <= PHGCSimAccumulator::SimHitCollection::energyMask + 1,
82  "PHGCSimAccumulator bit pattern needs to updated");
84  "PHGCSimAccumulator bit pattern needs to updated");
85  const float minPackChargeLog = minCharge > 0.f ? std::log(minCharge) : -2;
86  const float maxPackChargeLog = std::log(maxCharge);
88 
89  simResult.reserve(simData.size());
90 
91  for (const auto& id : validIds) {
92  auto found = simData.find(id);
93  if (found == simData.end())
94  continue;
95 
96  const hgc_digi::PUSimHitData& accCharge_across_bxs = found->second.PUhit_info[0];
97  const hgc_digi::PUSimHitData& timing_across_bxs = found->second.PUhit_info[1];
98  for (size_t iSample = 0; iSample < hgc_digi::nSamples; ++iSample) {
99  const std::vector<float>& accCharge_inthis_bx = accCharge_across_bxs[iSample];
100  const std::vector<float>& timing_inthis_bx = timing_across_bxs[iSample];
101  std::vector<unsigned short> vc, vt;
102  size_t nhits = accCharge_inthis_bx.size();
103 
104  for (size_t ihit = 0; ihit < nhits; ++ihit) {
105  if (accCharge_inthis_bx[ihit] > minCharge) {
106  unsigned short c =
107  logintpack::pack16log(accCharge_inthis_bx[ihit], minPackChargeLog, maxPackChargeLog, base);
108  unsigned short t = logintpack::pack16log(timing_inthis_bx[ihit], minPackChargeLog, maxPackChargeLog, base);
109  vc.emplace_back(c);
110  vt.emplace_back(t);
111  }
112  }
113  simResult.emplace_back(id.rawId(), iSample, vc, vt);
114  }
115  }
116  simResult.shrink_to_fit();
117  }
118 
119  void loadSimHitAccumulator_forPreMix(hgc::HGCSimHitDataAccumulator& simData,
121  const HGCalGeometry* geom,
122  IdHit_Map& hitRefs_bx0,
123  const PHGCSimAccumulator& simAccumulator,
124  const float minCharge,
125  const float maxCharge,
126  bool setIfZero,
127  const std::array<float, 3>& tdcForToAOnset,
128  const bool minbiasFlag,
129  std::unordered_map<uint32_t, bool>& hitOrder_monitor,
130  const unsigned int thisBx) {
131  const float minPackChargeLog = minCharge > 0.f ? std::log(minCharge) : -2;
132  const float maxPackChargeLog = std::log(maxCharge);
134  for (const auto& detIdIndexHitInfo : simAccumulator) {
135  unsigned int detId = detIdIndexHitInfo.detId();
136 
137  auto simIt = simData.emplace(detId, HGCCellInfo()).first;
138  size_t nhits = detIdIndexHitInfo.nhits();
139 
140  hitOrder_monitor[detId] = false;
141  if (nhits > 0) {
142  unsigned short iSample = detIdIndexHitInfo.sampleIndex();
143 
144  const auto& unsigned_charge_array = detIdIndexHitInfo.chargeArray();
145  const auto& unsigned_time_array = detIdIndexHitInfo.timeArray();
146 
147  float p_charge, p_time;
148  unsigned short unsigned_charge, unsigned_time;
149 
150  for (size_t ihit = 0; ihit < nhits; ++ihit) {
151  unsigned_charge = (unsigned_charge_array[ihit] & PHGCSimAccumulator::SimHitCollection::dataMask);
152  unsigned_time = (unsigned_time_array[ihit] & PHGCSimAccumulator::SimHitCollection::dataMask);
153  p_time = logintpack::unpack16log(unsigned_time, minPackChargeLog, maxPackChargeLog, base);
154  p_charge = logintpack::unpack16log(unsigned_charge, minPackChargeLog, maxPackChargeLog, base);
155 
156  (simIt->second).hit_info[0][iSample] += p_charge;
157  if (iSample == (unsigned short)thisBx) {
158  if (hitRefs_bx0[detId].empty()) {
159  hitRefs_bx0[detId].emplace_back(p_charge, p_time);
160  } else {
161  if (p_time < hitRefs_bx0[detId].back().second) {
162  auto findPos = std::upper_bound(hitRefs_bx0[detId].begin(),
163  hitRefs_bx0[detId].end(),
164  std::make_pair(0.f, p_time),
165  [](const auto& i, const auto& j) { return i.second < j.second; });
166 
167  auto insertedPos = findPos;
168  if (findPos == hitRefs_bx0[detId].begin()) {
169  insertedPos = hitRefs_bx0[detId].emplace(insertedPos, p_charge, p_time);
170  } else {
171  auto prevPos = findPos - 1;
172  if (prevPos->second == p_time) {
173  prevPos->first = prevPos->first + p_charge;
174  insertedPos = prevPos;
175  } else if (prevPos->second < p_time) {
176  insertedPos = hitRefs_bx0[detId].emplace(findPos, (prevPos)->first + p_charge, p_time);
177  }
178  }
179 
180  for (auto step = insertedPos; step != hitRefs_bx0[detId].end(); ++step) {
181  if (step != insertedPos)
182  step->first += p_charge;
183  }
184 
185  hitOrder_monitor[detId] = true;
186 
187  } else if (p_time == hitRefs_bx0[detId].back().second) {
188  hitRefs_bx0[detId].back().first += p_charge;
189  } else if (p_time > hitRefs_bx0[detId].back().second) {
190  hitRefs_bx0[detId].emplace_back(hitRefs_bx0[detId].back().first + p_charge, p_time);
191  }
192  }
193  }
194  }
195  }
196  }
197 
198  if (minbiasFlag) {
199  for (const auto& hitmapIterator : hitRefs_bx0) {
200  unsigned int detectorId = hitmapIterator.first;
201  auto simIt = simData.emplace(detectorId, HGCCellInfo()).first;
202  const bool orderChanged = hitOrder_monitor[detectorId];
203  int waferThickness = getCellThickness(geom, detectorId);
204  float cell_threshold = tdcForToAOnset[waferThickness - 1];
205  const auto& hitRec = hitmapIterator.second;
206  float accChargeForToA(0.f), fireTDC(0.f);
207  const auto aboveThrPos = std::upper_bound(
208  hitRec.begin(), hitRec.end(), std::make_pair(cell_threshold, 0.f), [](const auto& i, const auto& j) {
209  return i.first < j.first;
210  });
211 
212  if (aboveThrPos == hitRec.end()) {
213  accChargeForToA = hitRec.back().first;
214  fireTDC = 0.f;
215  } else if (hitRec.end() - aboveThrPos > 0 || orderChanged) {
216  accChargeForToA = aboveThrPos->first;
217  fireTDC = aboveThrPos->second;
218  if (aboveThrPos - hitRec.begin() >= 1) {
219  const auto& belowThrPos = aboveThrPos - 1;
220  float chargeBeforeThr = belowThrPos->first;
221  float timeBeforeThr = belowThrPos->second;
222  float deltaQ = accChargeForToA - chargeBeforeThr;
223  float deltaTOF = fireTDC - timeBeforeThr;
224  fireTDC = (cell_threshold - chargeBeforeThr) * deltaTOF / deltaQ + timeBeforeThr;
225  }
226  }
227  (simIt->second).hit_info[1][9] = fireTDC;
228  }
229  }
230  }
231 } //namespace
232 
234  : simHitAccumulator_(new HGCSimHitDataAccumulator()),
235  pusimHitAccumulator_(new HGCPUSimHitDataAccumulator()),
236  refSpeed_(0.1 * CLHEP::c_light), //[CLHEP::c_light]=mm/ns convert to cm/ns
237  averageOccupancies_(occupancyGuesses),
238  nEvents_(1) {
239  //configure from cfg
240 
241  hitCollection_ = ps.getParameter<std::string>("hitCollection");
242  digiCollection_ = ps.getParameter<std::string>("digiCollection");
243  maxSimHitsAccTime_ = ps.getParameter<uint32_t>("maxSimHitsAccTime");
244  bxTime_ = ps.getParameter<double>("bxTime");
245  digitizationType_ = ps.getParameter<uint32_t>("digitizationType");
246  verbosity_ = ps.getUntrackedParameter<uint32_t>("verbosity", 0);
247  tofDelay_ = ps.getParameter<double>("tofDelay");
248  premixStage1_ = ps.getParameter<bool>("premixStage1");
249  premixStage1MinCharge_ = ps.getParameter<double>("premixStage1MinCharge");
250  premixStage1MaxCharge_ = ps.getParameter<double>("premixStage1MaxCharge");
251  std::unordered_set<DetId>().swap(validIds_);
252  iC.consumes<std::vector<PCaloHit>>(edm::InputTag("g4SimHits", hitCollection_));
253  const auto& myCfg_ = ps.getParameter<edm::ParameterSet>("digiCfg");
254 
255  if (myCfg_.existsAs<edm::ParameterSet>("chargeCollectionEfficiencies")) {
256  cce_.clear();
257  const auto& temp = myCfg_.getParameter<edm::ParameterSet>("chargeCollectionEfficiencies")
258  .getParameter<std::vector<double>>("values");
259  for (double cce : temp) {
260  cce_.emplace_back(cce);
261  }
262  } else {
263  std::vector<float>().swap(cce_);
264  }
265 
266  auto const& pluginName = ps.getParameter<std::string>("digitizer");
267  theDigitizer_ = HGCDigitizerPluginFactory::get()->create(pluginName, ps);
268 }
269 
270 //
272  // reserve memory for a full detector
273  unsigned idx = getType();
276 }
277 
278 //
279 void HGCDigitizer::finalizeEvent(edm::Event& e, edm::EventSetup const& es, CLHEP::HepRandomEngine* hre) {
280  hitRefs_bx0.clear();
281  PhitRefs_bx0.clear();
282  hitOrder_monitor.clear();
283 
284  const CaloSubdetectorGeometry* theGeom = static_cast<const CaloSubdetectorGeometry*>(gHGCal_);
285 
286  ++nEvents_;
287 
288  unsigned idx = getType();
289  // release memory for unfilled parts of hash table
290  if (validIds_.size() * averageOccupancies_[idx] > simHitAccumulator_->size()) {
291  simHitAccumulator_->reserve(simHitAccumulator_->size());
292  pusimHitAccumulator_->reserve(simHitAccumulator_->size());
293  }
294  //update occupancy guess
295  const double thisOcc = simHitAccumulator_->size() / ((double)validIds_.size());
297 
298  if (premixStage1_) {
299  auto simRecord = std::make_unique<PHGCSimAccumulator>();
300 
301  if (!pusimHitAccumulator_->empty()) {
302  saveSimHitAccumulator_forPreMix(
304  }
305 
306  e.put(std::move(simRecord), digiCollection());
307 
308  } else {
309  auto digiResult = std::make_unique<HGCalDigiCollection>();
310  theDigitizer_->run(digiResult, *simHitAccumulator_, theGeom, validIds_, digitizationType_, hre);
311  edm::LogVerbatim("HGCDigitizer") << "HGCDigitizer:: finalize event - produced " << digiResult->size()
312  << " hits in det/subdet " << theDigitizer_->det() << "/"
313  << theDigitizer_->subdet();
314 #ifdef EDM_ML_DEBUG
315  checkPosition(&(*digiResult));
316 #endif
317  e.put(std::move(digiResult), digiCollection());
318  }
319 
322 }
324  edm::EventSetup const& eventSetup,
325  CLHEP::HepRandomEngine* hre) {
326  //get inputs
327 
329  e.getByLabel(edm::InputTag("g4SimHits", hitCollection_), hits);
330  if (!hits.isValid()) {
331  edm::LogError("HGCDigitizer") << " @ accumulate_minbias : can't find " << hitCollection_
332  << " collection of g4SimHits";
333  return;
334  }
335 
336  //accumulate in-time the main event
337  if (nullptr != gHGCal_) {
339  } else {
340  throw cms::Exception("BadConfiguration") << "HGCDigitizer is not producing EE, FH, or BH digis!";
341  }
342 }
343 
344 //
345 void HGCDigitizer::accumulate(edm::Event const& e, edm::EventSetup const& eventSetup, CLHEP::HepRandomEngine* hre) {
346  //get inputs
348  e.getByLabel(edm::InputTag("g4SimHits", hitCollection_), hits);
349  if (!hits.isValid()) {
350  edm::LogError("HGCDigitizer") << " @ accumulate : can't find " << hitCollection_ << " collection of g4SimHits";
351  return;
352  }
353 
354  //accumulate in-time the main event
355  if (nullptr != gHGCal_) {
356  accumulate(hits, 0, gHGCal_, hre);
357  } else {
358  throw cms::Exception("BadConfiguration") << "HGCDigitizer is not producing EE, FH, or BH digis!";
359  }
360 }
361 
362 //
364  edm::EventSetup const& eventSetup,
365  CLHEP::HepRandomEngine* hre) {
367  e.getByLabel(edm::InputTag("g4SimHits", hitCollection_), hits);
368 
369  if (!hits.isValid()) {
370  edm::LogError("HGCDigitizer") << " @ accumulate : can't find " << hitCollection_ << " collection of g4SimHits";
371  return;
372  }
373 
374  if (nullptr != gHGCal_) {
375  accumulate_forPreMix(hits, e.bunchCrossing(), gHGCal_, hre);
376  } else {
377  throw cms::Exception("BadConfiguration") << "HGCDigitizer is not producing EE, FH, or BH digis!";
378  }
379 }
380 
381 //
383  edm::EventSetup const& eventSetup,
384  CLHEP::HepRandomEngine* hre) {
385  //get inputs
387  e.getByLabel(edm::InputTag("g4SimHits", hitCollection_), hits);
388 
389  if (!hits.isValid()) {
390  edm::LogError("HGCDigitizer") << " @ accumulate : can't find " << hitCollection_ << " collection of g4SimHits";
391  return;
392  }
393 
394  //accumulate for the simulated bunch crossing
395  if (nullptr != gHGCal_) {
396  accumulate(hits, e.bunchCrossing(), gHGCal_, hre);
397  } else {
398  throw cms::Exception("BadConfiguration") << "HGCDigitizer is not producing EE, FH, or BH digis!";
399  }
400 }
401 
402 //
404  int bxCrossing,
405  const HGCalGeometry* geom,
406  CLHEP::HepRandomEngine* hre) {
407  if (nullptr == geom)
408  return;
409 
410  auto keV2fC = theDigitizer_->keV2fC();
411  auto tdcForToAOnset = theDigitizer_->tdcForToAOnset();
412 
413  int nchits = (int)hits->size();
414  int count_thisbx = 0;
415  std::vector<HGCCaloHitTuple_t> hitRefs;
416  hitRefs.reserve(nchits);
417  for (int i = 0; i < nchits; ++i) {
418  const auto& the_hit = hits->at(i);
419  DetId id = simToReco(geom, the_hit.id());
420  // to be written the verbosity block
421  if (id.rawId() != 0) {
422  hitRefs.emplace_back(i, id.rawId(), (float)the_hit.time());
423  }
424  }
425  std::sort(hitRefs.begin(), hitRefs.end(), this->orderByDetIdThenTime);
426 
427  nchits = hitRefs.size();
428  for (int i = 0; i < nchits; ++i) {
429  const int hitidx = std::get<0>(hitRefs[i]);
430  const uint32_t id = std::get<1>(hitRefs[i]);
431  if (!validIds_.count(id))
432  continue;
433 
434  if (id == 0)
435  continue;
436 
437  const float toa = std::get<2>(hitRefs[i]);
438  const PCaloHit& hit = hits->at(hitidx);
439  const float charge = hit.energy() * 1e6 * keV2fC; // * getCCE(geom, id, cce_);
440 
441  const float dist2center(getPositionDistance(geom, id));
442  const float tof = toa - dist2center / refSpeed_ + tofDelay_;
443  const int itime = std::floor(tof / bxTime_) + 9;
444 
445  if (itime < 0 || itime > (int)maxBx_)
446  continue;
447 
448  if (itime >= (int)(maxBx_ + 1))
449  continue;
450 
451  int waferThickness = getCellThickness(geom, id);
452  if (itime == (int)thisBx_) {
453  ++count_thisbx;
454  if (PhitRefs_bx0[id].empty()) {
455  PhitRefs_bx0[id].emplace_back(charge, charge, tof);
456  } else if (tof > std::get<2>(PhitRefs_bx0[id].back())) {
457  PhitRefs_bx0[id].emplace_back(charge, charge + std::get<1>(PhitRefs_bx0[id].back()), tof);
458  } else if (tof == std::get<2>(PhitRefs_bx0[id].back())) {
459  std::get<0>(PhitRefs_bx0[id].back()) += charge;
460  std::get<1>(PhitRefs_bx0[id].back()) += charge;
461  } else {
462  //find position to insert new entry preserving time sorting
463  auto findPos = std::upper_bound(PhitRefs_bx0[id].begin(),
464  PhitRefs_bx0[id].end(),
465  hit_timeStamp(charge, 0.f, tof),
466  [](const auto& i, const auto& j) { return std::get<2>(i) <= std::get<2>(j); });
467 
468  auto insertedPos = findPos;
469 
470  if (tof == std::get<2>(*(findPos - 1))) {
471  std::get<0>(*(findPos - 1)) += charge;
472  std::get<1>(*(findPos - 1)) += charge;
473 
474  } else {
475  insertedPos = PhitRefs_bx0[id].insert(findPos,
476  (findPos == PhitRefs_bx0[id].begin())
477  ? hit_timeStamp(charge, charge, tof)
478  : hit_timeStamp(charge, charge + std::get<1>(*(findPos - 1)), tof));
479  }
480  //cumulate the charge of new entry for all elements that follow in the sorted list
481  //and resize list accounting for cases when the inserted element itself crosses the threshold
482 
483  for (auto step = insertedPos; step != PhitRefs_bx0[id].end(); ++step) {
484  if (step != insertedPos)
485  std::get<1>(*(step)) += charge;
486 
487  // resize the list stopping with the first timeStamp with cumulative charge above threshold
488  if (std::get<1>(*step) > tdcForToAOnset[waferThickness - 1] &&
489  std::get<2>(*step) != std::get<2>(PhitRefs_bx0[id].back())) {
490  PhitRefs_bx0[id].resize(
491  std::upper_bound(PhitRefs_bx0[id].begin(),
492  PhitRefs_bx0[id].end(),
493  hit_timeStamp(charge, 0.f, std::get<2>(*step)),
494  [](const auto& i, const auto& j) { return std::get<2>(i) < std::get<2>(j); }) -
495  PhitRefs_bx0[id].begin());
496  for (auto stepEnd = step + 1; stepEnd != PhitRefs_bx0[id].end(); ++stepEnd)
497  std::get<1>(*stepEnd) += charge;
498  break;
499  }
500  }
501  }
502  }
503  }
504 
505  for (const auto& hitCollection : PhitRefs_bx0) {
506  const uint32_t detectorId = hitCollection.first;
507  auto simHitIt = pusimHitAccumulator_->emplace(detectorId, HGCCellHitInfo()).first;
508 
509  for (const auto& hit_timestamp : PhitRefs_bx0[detectorId]) {
510  (simHitIt->second).PUhit_info[1][thisBx_].push_back(std::get<2>(hit_timestamp));
511  (simHitIt->second).PUhit_info[0][thisBx_].push_back(std::get<0>(hit_timestamp));
512  }
513  }
514 
515  if (nchits == 0) {
516  HGCPUSimHitDataAccumulator::iterator simHitIt = pusimHitAccumulator_->emplace(0, HGCCellHitInfo()).first;
517  (simHitIt->second).PUhit_info[1][9].push_back(0.0);
518  (simHitIt->second).PUhit_info[0][9].push_back(0.0);
519  }
520  hitRefs.clear();
521  PhitRefs_bx0.clear();
522 }
523 
524 //
526  int bxCrossing,
527  const HGCalGeometry* geom,
528  CLHEP::HepRandomEngine* hre) {
529  if (nullptr == geom)
530  return;
531 
532  //configuration to apply for the computation of time-of-flight
533  auto weightToAbyEnergy = theDigitizer_->toaModeByEnergy();
534  auto tdcForToAOnset = theDigitizer_->tdcForToAOnset();
535  auto keV2fC = theDigitizer_->keV2fC();
536 
537  //create list of tuples (pos in container, RECO DetId, time) to be sorted first
538  int nchits = (int)hits->size();
539 
540  std::vector<HGCCaloHitTuple_t> hitRefs;
541  hitRefs.reserve(nchits);
542  for (int i = 0; i < nchits; ++i) {
543  const auto& the_hit = hits->at(i);
544  DetId id = simToReco(geom, the_hit.id());
545 
546  if (verbosity_ > 0) {
547  edm::LogVerbatim("HGCDigitizer") << "HGCDigitizer::i/p " << std::hex << the_hit.id() << " o/p " << id.rawId()
548  << std::dec;
549  }
550 
551  if (0 != id.rawId()) {
552  hitRefs.emplace_back(i, id.rawId(), (float)the_hit.time());
553  }
554  }
555 
556  std::sort(hitRefs.begin(), hitRefs.end(), this->orderByDetIdThenTime);
557  //loop over sorted hits
558  nchits = hitRefs.size();
559  for (int i = 0; i < nchits; ++i) {
560  const int hitidx = std::get<0>(hitRefs[i]);
561  const uint32_t id = std::get<1>(hitRefs[i]);
562 
563  //get the data for this cell, if not available then we skip it
564 
565  if (!validIds_.count(id))
566  continue;
567  HGCSimHitDataAccumulator::iterator simHitIt = simHitAccumulator_->emplace(id, HGCCellInfo()).first;
568 
569  if (id == 0)
570  continue; // to be ignored at RECO level
571 
572  const float toa = std::get<2>(hitRefs[i]);
573  const PCaloHit& hit = hits->at(hitidx);
574  const float charge = hit.energy() * 1e6 * keV2fC;
575 
576  //distance to the center of the detector
577  const float dist2center(getPositionDistance(geom, id));
578 
579  //hit time: [time()]=ns [centerDist]=cm [refSpeed_]=cm/ns + delay by 1ns
580  //accumulate in 15 buckets of 25ns (9 pre-samples, 1 in-time, 5 post-samples)
581  const float tof = toa - dist2center / refSpeed_ + tofDelay_;
582  const int itime = std::floor(tof / bxTime_) + 9;
583 
584  //no need to add bx crossing - tof comes already corrected from the mixing module
585  //itime += bxCrossing;
586  //itime += 9;
587 
588  if (itime < 0 || itime > (int)maxBx_)
589  continue;
590 
591  //check if time index is ok and store energy
592  if (itime >= (int)simHitIt->second.hit_info[0].size())
593  continue;
594 
595  (simHitIt->second).hit_info[0][itime] += charge;
596 
597  //for time-of-arrival: save the time-sorted list of timestamps with cumulative charge just above threshold
598  //working version with pileup only for in-time hits
599  int waferThickness = getCellThickness(geom, id);
600  bool orderChanged = false;
601  if (itime == (int)thisBx_) {
602  //if start empty => just add charge and time
603  if (hitRefs_bx0[id].empty()) {
604  hitRefs_bx0[id].emplace_back(charge, tof);
605 
606  } else if (tof <= hitRefs_bx0[id].back().second) {
607  //find position to insert new entry preserving time sorting
608  std::vector<std::pair<float, float>>::iterator findPos =
609  std::upper_bound(hitRefs_bx0[id].begin(),
610  hitRefs_bx0[id].end(),
611  std::pair<float, float>(0.f, tof),
612  [](const auto& i, const auto& j) { return i.second <= j.second; });
613 
614  std::vector<std::pair<float, float>>::iterator insertedPos = findPos;
615  if (findPos->second == tof) {
616  //just merge timestamps with exact timing
617  findPos->first += charge;
618  } else {
619  //insert new element cumulating the charge
620  insertedPos = hitRefs_bx0[id].insert(findPos,
621  (findPos == hitRefs_bx0[id].begin())
622  ? std::pair<float, float>(charge, tof)
623  : std::pair<float, float>((findPos - 1)->first + charge, tof));
624  }
625 
626  //cumulate the charge of new entry for all elements that follow in the sorted list
627  //and resize list accounting for cases when the inserted element itself crosses the threshold
628  for (std::vector<std::pair<float, float>>::iterator step = insertedPos; step != hitRefs_bx0[id].end(); ++step) {
629  if (step != insertedPos)
630  step->first += charge;
631  // resize the list stopping with the first timeStamp with cumulative charge above threshold
632  if (step->first > tdcForToAOnset[waferThickness - 1] && step->second != hitRefs_bx0[id].back().second) {
633  hitRefs_bx0[id].resize(std::upper_bound(hitRefs_bx0[id].begin(),
634  hitRefs_bx0[id].end(),
635  std::pair<float, float>(0.f, step->second),
636  [](const auto& i, const auto& j) { return i.second < j.second; }) -
637  hitRefs_bx0[id].begin());
638  for (auto stepEnd = step + 1; stepEnd != hitRefs_bx0[id].end(); ++stepEnd)
639  stepEnd->first += charge;
640  break;
641  }
642  }
643 
644  orderChanged = true;
645  } else {
646  //add new entry at the end of the list
647  if (hitRefs_bx0[id].back().first <= tdcForToAOnset[waferThickness - 1]) {
648  hitRefs_bx0[id].emplace_back(hitRefs_bx0[id].back().first + charge, tof);
649  }
650  }
651  }
652  float accChargeForToA = hitRefs_bx0[id].empty() ? 0.f : hitRefs_bx0[id].back().first;
653  //now compute the firing ToA through the interpolation of the consecutive time-stamps at threshold
654  if (weightToAbyEnergy)
655  (simHitIt->second).hit_info[1][itime] += charge * tof;
656  else if (accChargeForToA > tdcForToAOnset[waferThickness - 1] &&
657  ((simHitIt->second).hit_info[1][itime] == 0 || orderChanged == true)) {
658  float fireTDC = hitRefs_bx0[id].back().second;
659  if (hitRefs_bx0[id].size() > 1) {
660  float chargeBeforeThr = (hitRefs_bx0[id].end() - 2)->first;
661  float tofchargeBeforeThr = (hitRefs_bx0[id].end() - 2)->second;
662 
663  float deltaQ = accChargeForToA - chargeBeforeThr;
664  float deltaTOF = fireTDC - tofchargeBeforeThr;
665  fireTDC = (tdcForToAOnset[waferThickness - 1] - chargeBeforeThr) * deltaTOF / deltaQ + tofchargeBeforeThr;
666  }
667  (simHitIt->second).hit_info[1][itime] = fireTDC;
668  }
669  }
670  hitRefs.clear();
671 }
672 void HGCDigitizer::accumulate_forPreMix(const PHGCSimAccumulator& simAccumulator, const bool minbiasFlag) {
673  //configuration to apply for the computation of time-of-flight
674  auto weightToAbyEnergy = theDigitizer_->toaModeByEnergy();
675  auto tdcForToAOnset = theDigitizer_->tdcForToAOnset();
676 
677  if (nullptr != gHGCal_) {
678  loadSimHitAccumulator_forPreMix(*simHitAccumulator_,
680  gHGCal_,
681  hitRefs_bx0,
682  simAccumulator,
685  !weightToAbyEnergy,
686  tdcForToAOnset,
687  minbiasFlag,
689  thisBx_);
690  }
691 }
692 
693 //
695  //get geometry
698 
699  gHGCal_ = nullptr;
700 
701  gHGCal_ =
702  dynamic_cast<const HGCalGeometry*>(geom->getSubdetectorGeometry(theDigitizer_->det(), theDigitizer_->subdet()));
703 
704  int nadded(0);
705  //valid ID lists
706  if (nullptr != gHGCal_) {
707  getValidDetIds(gHGCal_, validIds_);
708  } else {
709  throw cms::Exception("BadConfiguration") << "HGCDigitizer is not producing EE, FH, or BH digis!";
710  }
711 
712  if (verbosity_ > 0)
713  edm::LogInfo("HGCDigitizer") << "Added " << nadded << ":" << validIds_.size() << " detIds without "
714  << hitCollection_ << " in first event processed" << std::endl;
715 }
716 
717 //
718 void HGCDigitizer::endRun() { std::unordered_set<DetId>().swap(validIds_); }
719 
720 //
722  for (HGCSimHitDataAccumulator::iterator it = simHitAccumulator_->begin(); it != simHitAccumulator_->end(); it++) {
723  it->second.hit_info[0].fill(0.);
724  it->second.hit_info[1].fill(0.);
725  }
726 }
727 
728 uint32_t HGCDigitizer::getType() const {
730  switch (theDigitizer_->det()) {
731  case DetId::HGCalEE:
732  idx = 0;
733  break;
734  case DetId::HGCalHSi:
735  idx = 1;
736  break;
737  case DetId::HGCalHSc:
738  idx = 2;
739  break;
740  case DetId::Forward:
741  idx = 3;
742  break;
743  default:
744  break;
745  }
746  return idx;
747 }
748 
750  const double tol(0.5);
751  if (nullptr != gHGCal_) {
752  for (const auto& digi : *(digis)) {
753  const DetId& id = digi.id();
754  const GlobalPoint& global = gHGCal_->getPosition(id);
755  double r = global.perp();
756  double z = std::abs(global.z());
757  std::pair<double, double> zrange = gHGCal_->topology().dddConstants().rangeZ(true);
758  std::pair<double, double> rrange = gHGCal_->topology().dddConstants().rangeR(z, true);
759  bool ok = ((r >= rrange.first) && (r <= rrange.second) && (z >= zrange.first) && (z <= zrange.second));
760  std::string ck = (((r < rrange.first - tol) || (r > rrange.second + tol) || (z < zrange.first - tol) ||
761  (z > zrange.second + tol))
762  ? "***** ERROR *****"
763  : "");
764  bool val = gHGCal_->topology().valid(id);
765  if ((!ok) || (!val)) {
766  if (id.det() == DetId::HGCalEE || id.det() == DetId::HGCalHSi) {
767  edm::LogVerbatim("HGCDigitizer") << "Check " << HGCSiliconDetId(id) << " " << global << " R " << r << ":"
768  << rrange.first << ":" << rrange.second << " Z " << z << ":" << zrange.first
769  << ":" << zrange.second << " Flag " << ok << ":" << val << " " << ck;
770  } else if (id.det() == DetId::HGCalHSc) {
771  edm::LogVerbatim("HGCDigitizer") << "Check " << HGCScintillatorDetId(id) << " " << global << " R " << r << ":"
772  << rrange.first << ":" << rrange.second << " Z " << z << ":" << zrange.first
773  << ":" << zrange.second << " Flag " << ok << ":" << val << " " << ck;
774  } else if ((id.det() == DetId::Forward) && (id.subdetId() == static_cast<int>(HFNose))) {
775  edm::LogVerbatim("HGCDigitizer") << "Check " << HFNoseDetId(id) << " " << global << " R " << r << ":"
776  << rrange.first << ":" << rrange.second << " Z " << z << ":" << zrange.first
777  << ":" << zrange.second << " Flag " << ok << ":" << val << " " << ck;
778  } else {
779  edm::LogVerbatim("HGCDigitizer")
780  << "Check " << std::hex << id.rawId() << std::dec << " " << id.det() << ":" << id.subdetId() << " "
781  << global << " R " << r << ":" << rrange.first << ":" << rrange.second << " Z " << z << ":"
782  << zrange.first << ":" << zrange.second << " Flag " << ok << ":" << val << " " << ck;
783  }
784  }
785  }
786  }
787 }
logintpack::pack16log
int16_t pack16log(double x, double lmin, double lmax, uint16_t base=32768)
Definition: liblogintpack.h:27
HGCDigitizer::HGCDigitizer
HGCDigitizer(const edm::ParameterSet &ps, edm::ConsumesCollector &iC)
Definition: HGCDigitizer.cc:233
PHGCSimAccumulator
Definition: PHGCSimAccumulator.h:8
HGCDigitizer::thisBx_
static const unsigned int thisBx_
Definition: HGCDigitizer.h:129
pfDeepBoostedJetPreprocessParams_cfi.upper_bound
upper_bound
Definition: pfDeepBoostedJetPreprocessParams_cfi.py:16
mps_fire.i
i
Definition: mps_fire.py:428
hgc_digi::HGCCellHitInfo
Definition: HGCDigitizerTypes.h:25
HGCalTopology::dddConstants
const HGCalDDDConstants & dddConstants() const
Definition: HGCalTopology.h:98
TkClusParameters_cff.zrange
zrange
Definition: TkClusParameters_cff.py:7
PHGCSimAccumulator::shrink_to_fit
void shrink_to_fit()
Definition: PHGCSimAccumulator.h:72
hfClusterShapes_cfi.hits
hits
Definition: hfClusterShapes_cfi.py:5
HGCalDDDConstants::rangeZ
std::pair< double, double > rangeZ(bool reco) const
Definition: HGCalDDDConstants.cc:994
HGCDigitizer::premixStage1MinCharge_
double premixStage1MinCharge_
Definition: HGCDigitizer.h:93
HGCDigitizer::simHitAccumulator_
std::unique_ptr< hgc::HGCSimHitDataAccumulator > simHitAccumulator_
Definition: HGCDigitizer.h:100
HGCDigitizer::digiCollection
std::string digiCollection()
Definition: HGCDigitizer.h:74
HGCDigitizer::gHGCal_
const HGCalGeometry * gHGCal_
Definition: HGCDigitizer.h:112
step
step
Definition: StallMonitor.cc:94
f
double f[11][100]
Definition: MuScleFitUtils.cc:78
ForwardSubdetector
ForwardSubdetector
Definition: ForwardSubdetector.h:4
CaloGeometryRecord
Definition: CaloGeometryRecord.h:30
RandomNumberGenerator.h
HGCalGeometryMode.h
PHGCSimAccumulator::SimHitCollection::sampleOffset
constexpr static unsigned sampleOffset
Definition: PHGCSimAccumulator.h:27
HGCDigitizer::endRun
void endRun()
Definition: HGCDigitizer.cc:718
CrossingFrame.h
HGCalTestNumbering::unpackHexagonIndex
static void unpackHexagonIndex(const uint32_t &idx, int &subdet, int &z, int &lay, int &wafer, int &celltyp, int &cell)
Definition: HGCalTestNumbering.cc:46
HLT_FULL_cff.InputTag
InputTag
Definition: HLT_FULL_cff.py:89285
liblogintpack.h
HGCDigitizer::nEvents_
uint32_t nEvents_
Definition: HGCDigitizer.h:125
PHGCSimAccumulator::SimHitCollection::dataMask
constexpr static unsigned dataMask
Definition: PHGCSimAccumulator.h:30
edm::SortedCollection
Definition: SortedCollection.h:49
edm::second
U second(std::pair< T, U > const &p)
Definition: ParameterSet.cc:222
PileUpEventPrincipal
Definition: PileUpEventPrincipal.h:19
HGCDigitizer::maxBx_
static const unsigned int maxBx_
Definition: HGCDigitizer.h:128
edm::ParameterSet::getUntrackedParameter
T getUntrackedParameter(std::string const &, T const &) const
HGCDigitizer::beginRun
void beginRun(const edm::EventSetup &es)
actions at the start/end of run
Definition: HGCDigitizer.cc:694
HFNoseDetId.h
HGCDigitizer::refSpeed_
float refSpeed_
Definition: HGCDigitizer.h:118
PHGCSimAccumulator::SimHitCollection::energyMask
constexpr static unsigned energyMask
Definition: PHGCSimAccumulator.h:26
edm::LogInfo
Log< level::Info, false > LogInfo
Definition: MessageLogger.h:125
HGCDigitizer::theDigitizer_
std::unique_ptr< HGCDigitizerBase > theDigitizer_
Definition: HGCDigitizer.h:108
HGCDigitizer::premixStage1_
bool premixStage1_
Definition: HGCDigitizer.h:90
HFNoseDetId
Definition: HFNoseDetId.h:22
convertSQLiteXML.ok
bool ok
Definition: convertSQLiteXML.py:98
newFWLiteAna.found
found
Definition: newFWLiteAna.py:118
edm::Handle
Definition: AssociativeIterator.h:50
groupFilesInBlocks.temp
list temp
Definition: groupFilesInBlocks.py:142
HGCSiliconDetId
Definition: HGCSiliconDetId.h:22
ForwardSubdetector.h
PHGCSimAccumulator::SimHitCollection::sampleMask
constexpr static unsigned sampleMask
Definition: PHGCSimAccumulator.h:28
heavyIonCSV_trainingSettings.idx
idx
Definition: heavyIonCSV_trainingSettings.py:5
hgc_digi
Definition: HGCDigitizerTypes.h:10
PV3DBase::z
T z() const
Definition: PV3DBase.h:61
DetId
Definition: DetId.h:17
hitRec_container
std::unordered_map< uint32_t, std::vector< hit_timeStamp > > hitRec_container
Definition: HGCDigitizer.cc:31
DetId::HGCalHSi
Definition: DetId.h:33
DetId::HGCalEE
Definition: DetId.h:32
HGCDigitizer::accumulate_forPreMix
void accumulate_forPreMix(edm::Event const &e, edm::EventSetup const &c, CLHEP::HepRandomEngine *hre)
Definition: HGCDigitizer.cc:323
edm::EventSetup::get
T get() const
Definition: EventSetup.h:87
MixCollection.h
Service.h
PHGCSimAccumulator::reserve
void reserve(size_t size)
Definition: PHGCSimAccumulator.h:68
HFNose
Definition: ForwardSubdetector.h:11
mps_fire.end
end
Definition: mps_fire.py:242
DDAxes::z
edm::ESHandle< CaloGeometry >
PileUpEventPrincipal.h
relativeConstraints.geom
geom
Definition: relativeConstraints.py:72
edm::ConsumesCollector::consumes
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
Definition: ConsumesCollector.h:55
HGCDigitizer::pusimHitAccumulator_
std::unique_ptr< hgc::HGCPUSimHitDataAccumulator > pusimHitAccumulator_
Definition: HGCDigitizer.h:101
logintpack::unpack16log
double unpack16log(int16_t i, double lmin, double lmax, uint16_t base=32768)
Definition: liblogintpack.h:62
egammaRechitFilter_cfi.hitCollection
hitCollection
Definition: egammaRechitFilter_cfi.py:10
HGCDigitizer::orderByDetIdThenTime
static bool orderByDetIdThenTime(const HGCCaloHitTuple_t &a, const HGCCaloHitTuple_t &b)
Definition: HGCDigitizer.h:34
Point3DBase< float, GlobalTag >
nhits
Definition: HIMultiTrackSelector.h:42
HGCalGeometry
Definition: HGCalGeometry.h:29
HGCalGeometry::topology
const HGCalTopology & topology() const
Definition: HGCalGeometry.h:111
HGCalDDDConstants::rangeR
std::pair< double, double > rangeR(double z, bool reco) const
Definition: HGCalDDDConstants.cc:949
first
auto first
Definition: CAHitNtupletGeneratorKernelsImpl.h:112
CaloGeometryRecord.h
HGCDigitizerPluginFactory.h
phase1PixelTopology::layer
constexpr std::array< uint8_t, layerIndexSize > layer
Definition: phase1PixelTopology.h:99
CLHEP
Definition: CocoaGlobals.h:27
AlCaHLTBitMon_QueryRunRegistry.string
string
Definition: AlCaHLTBitMon_QueryRunRegistry.py:256
hgc_digi::HGCCellInfo
Definition: HGCDigitizerTypes.h:31
ALCARECOTkAlJpsiMuMu_cff.charge
charge
Definition: ALCARECOTkAlJpsiMuMu_cff.py:47
HGCDigitizer::hitCollection_
std::string hitCollection_
Definition: HGCDigitizer.h:84
edm::ParameterSet
Definition: ParameterSet.h:47
hgc_digi::nSamples
constexpr size_t nSamples
Definition: HGCDigitizerTypes.h:13
Event.h
SiStripPI::max
Definition: SiStripPayloadInspectorHelper.h:169
jetUpdater_cfi.sort
sort
Definition: jetUpdater_cfi.py:29
HGCDigitizer::accumulate
void accumulate(edm::Event const &e, edm::EventSetup const &c, CLHEP::HepRandomEngine *hre)
handle SimHit accumulation
Definition: HGCDigitizer.cc:345
HGCDigitizer::maxSimHitsAccTime_
int maxSimHitsAccTime_
Definition: HGCDigitizer.h:98
HGCDigitizer::finalizeEvent
void finalizeEvent(edm::Event &e, edm::EventSetup const &c, CLHEP::HepRandomEngine *hre)
Definition: HGCDigitizer.cc:279
PCaloHit.h
HGCDigitizer::resetSimHitDataAccumulator
void resetSimHitDataAccumulator()
Definition: HGCDigitizer.cc:721
HGCDigitizer::hitRefs_bx0
std::unordered_map< uint32_t, std::vector< std::pair< float, float > > > hitRefs_bx0
Definition: HGCDigitizer.h:131
createfilelist.int
int
Definition: createfilelist.py:10
trackerHitRTTI::vector
Definition: trackerHitRTTI.h:21
IdealGeometryRecord.h
HGCalGeometry::getPosition
GlobalPoint getPosition(const DetId &id) const
Definition: HGCalGeometry.cc:198
edm::EventSetup
Definition: EventSetup.h:58
HGCDigitizer::digitizationType_
int digitizationType_
Definition: HGCDigitizer.h:87
PCaloHit
Definition: PCaloHit.h:8
edm::LogError
Log< level::Error, false > LogError
Definition: MessageLogger.h:123
HGCDigitizer::PhitRefs_bx0
std::unordered_map< uint32_t, std::vector< std::tuple< float, float, float > > > PhitRefs_bx0
Definition: HGCDigitizer.h:132
get
#define get
IdHit_Map
std::unordered_map< uint32_t, std::vector< std::pair< float, float > > > IdHit_Map
Definition: HGCDigitizer.cc:29
hgc_digi::HGCSimHitDataAccumulator
std::unordered_map< uint32_t, HGCCellInfo > HGCSimHitDataAccumulator
Definition: HGCDigitizerTypes.h:38
fileinputsource_cfi.sec
sec
Definition: fileinputsource_cfi.py:94
HGCDigitizer::validIds_
std::unordered_set< DetId > validIds_
Definition: HGCDigitizer.h:111
HGCDigitizer::bxTime_
double bxTime_
Definition: HGCDigitizer.h:99
alignCSCRings.r
r
Definition: alignCSCRings.py:93
hit_timeStamp
std::tuple< float, float, float > hit_timeStamp
Definition: HGCDigitizer.cc:30
HGCDigitizer::tofDelay_
float tofDelay_
Definition: HGCDigitizer.h:121
HGCDigitizer::premixStage1MaxCharge_
double premixStage1MaxCharge_
Definition: HGCDigitizer.h:95
PHGCSimAccumulator::emplace_back
void emplace_back(unsigned int detId, unsigned short sampleIndex, const std::vector< unsigned short > &accCharge, const std::vector< unsigned short > &timing)
Definition: PHGCSimAccumulator.h:77
HGCalDetId
Definition: HGCalDetId.h:8
HGCDigitizer::initializeEvent
void initializeEvent(edm::Event const &e, edm::EventSetup const &c)
actions at the start/end of event
Definition: HGCDigitizer.cc:271
heppy_batch.val
val
Definition: heppy_batch.py:351
HGCalDetId.h
eostools.move
def move(src, dest)
Definition: eostools.py:511
std
Definition: JetResolutionObject.h:76
HGCDigitizer::verbosity_
uint32_t verbosity_
Definition: HGCDigitizer.h:115
hgc_digi::PUSimHitData
std::array< HGCSimDataCollection, nSamples > PUSimHitData
Definition: HGCDigitizerTypes.h:20
HGCDigitizer::digiCollection_
std::string digiCollection_
Definition: HGCDigitizer.h:84
hgc_digi::HGCPUSimHitDataAccumulator
std::unordered_map< uint32_t, HGCCellHitInfo > HGCPUSimHitDataAccumulator
Definition: HGCDigitizerTypes.h:39
HGCScintillatorDetId
Definition: HGCScintillatorDetId.h:23
edm::LogVerbatim
Log< level::Info, true > LogVerbatim
Definition: MessageLogger.h:128
triggerObjects_cff.id
id
Definition: triggerObjects_cff.py:29
DetId::HGCalHSc
Definition: DetId.h:34
HGCDigitizer.h
transform.h
relativeConstraints.value
value
Definition: relativeConstraints.py:53
relativeConstraints.empty
bool empty
Definition: relativeConstraints.py:46
Exception
Definition: hltDiff.cc:245
CaloGeometry.h
HGCDigitizer::checkPosition
void checkPosition(const HGCalDigiCollection *digis) const
Definition: HGCDigitizer.cc:749
EventSetup.h
CaloSubdetectorGeometry
Definition: CaloSubdetectorGeometry.h:22
edm::ParameterSet::getParameter
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
PCaloHitContainer.h
dqm-mbProfile.log
log
Definition: dqm-mbProfile.py:17
HGCDigitizer::cce_
std::vector< float > cce_
Definition: HGCDigitizer.h:130
HGCalTopology::valid
bool valid(const DetId &id) const override
Is this a valid cell id.
Definition: HGCalTopology.cc:464
mps_fire.result
result
Definition: mps_fire.py:311
funct::abs
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
RunInfoPI::valid
Definition: RunInfoPayloadInspectoHelper.h:16
c
auto & c
Definition: CAHitNtupletGeneratorKernelsImpl.h:46
DetId::Forward
Definition: DetId.h:30
dqmiolumiharvest.j
j
Definition: dqmiolumiharvest.py:66
edm::Event
Definition: Event.h:73
submitPVValidationJobs.t
string t
Definition: submitPVValidationJobs.py:644
newFWLiteAna.base
base
Definition: newFWLiteAna.py:92
HGCDigitizer::getType
uint32_t getType() const
Definition: HGCDigitizer.cc:728
TauDecayModes.dec
dec
Definition: TauDecayModes.py:143
PV3DBase::perp
T perp() const
Definition: PV3DBase.h:69
edm::InputTag
Definition: InputTag.h:15
edm::ConsumesCollector
Definition: ConsumesCollector.h:45
hit
Definition: SiStripHitEffFromCalibTree.cc:88
HGCDigitizer::hitOrder_monitor
std::unordered_map< uint32_t, bool > hitOrder_monitor
Definition: HGCDigitizer.h:133
hgcalTriggerNtuples_cfi.keV2fC
keV2fC
Definition: hgcalTriggerNtuples_cfi.py:11
findQualityFiles.size
size
Write out results.
Definition: findQualityFiles.py:443
MillePedeFileConverter_cfg.e
e
Definition: MillePedeFileConverter_cfg.py:37
HGCalTestNumbering.h
HGCDigitizer::averageOccupancies_
std::array< double, 4 > averageOccupancies_
Definition: HGCDigitizer.h:124