22 #include <boost/foreach.hpp>
29 typedef std::vector<std::pair<float, float>>::iterator
itr;
30 typedef std::unordered_map<uint32_t, std::vector<std::pair<float, float>>>
IdHit_Map;
37 constexpr std::array<double, 4> occupancyGuesses = {{0.5, 0.2, 0.2, 0.8}};
42 return geom->getGeometry(
id)->getPosition().mag();
46 const auto& dddConst =
geom->topology().dddConstants();
47 return (1 + dddConst.waferType(detid));
53 const std::vector<DetId>& ids =
geom->getValidDetIds();
54 valid.reserve(ids.size());
55 valid.insert(ids.begin(), ids.end());
59 const std::vector<DetId>& ids =
geom->getValidDetIds();
60 for (
const auto&
id : ids) {
69 const auto& topo =
geom->topology();
70 const auto* dddConst = topo.dddConstants();
82 const auto& topo =
geom->topology();
83 const auto& dddConst = topo.dddConstants();
85 if (dddConst.waferHexagon8() || dddConst.tileTrapezoid()) {
88 int subdet(
DetId(simId).subdetId()), layer, cell,
sec, subsec, zp;
92 auto recoLayerCell = dddConst.simToReco(cell, layer,
sec, topo.detectorType());
93 cell = recoLayerCell.first;
94 layer = recoLayerCell.second;
95 if (layer < 0 || cell < 0) {
107 const std::unordered_set<DetId>& validIds,
108 const float minCharge,
109 const float maxCharge) {
112 "PHGCSimAccumulator bit pattern needs to updated");
114 "PHGCSimAccumulator bit pattern needs to updated");
115 const float minPackChargeLog = minCharge > 0.f ?
std::log(minCharge) : -2;
116 const float maxPackChargeLog =
std::log(maxCharge);
119 simResult.
reserve(simData.size());
121 for (
const auto&
id : validIds) {
122 auto found = simData.find(
id);
123 if (
found == simData.end())
129 const std::vector<float>& accCharge_inthis_bx = accCharge_across_bxs[iSample];
130 const std::vector<float>& timing_inthis_bx = timing_across_bxs[iSample];
131 std::vector<unsigned short> vc, vt;
132 size_t nhits = accCharge_inthis_bx.size();
134 for (
size_t ihit = 0; ihit <
nhits; ++ihit) {
135 if (accCharge_inthis_bx[ihit] > minCharge) {
149 template <
typename GEOM>
155 const float minCharge,
156 const float maxCharge,
158 const std::array<float, 3>& tdcForToAOnset,
159 const bool minbiasFlag,
160 std::unordered_map<uint32_t, bool>& hitOrder_monitor,
161 const unsigned int thisBx) {
162 const float minPackChargeLog = minCharge > 0.f ?
std::log(minCharge) : -2;
163 const float maxPackChargeLog =
std::log(maxCharge);
165 for (
const auto& detIdIndexHitInfo : simAccumulator) {
166 unsigned int detId = detIdIndexHitInfo.detId();
168 auto simIt = simData.emplace(detId,
HGCCellInfo()).first;
169 size_t nhits = detIdIndexHitInfo.nhits();
171 hitOrder_monitor[detId] =
false;
173 unsigned short iSample = detIdIndexHitInfo.sampleIndex();
175 const auto& unsigned_charge_array = detIdIndexHitInfo.chargeArray();
176 const auto& unsigned_time_array = detIdIndexHitInfo.timeArray();
178 float p_charge, p_time;
179 unsigned short unsigned_charge, unsigned_time;
181 for (
size_t ihit = 0; ihit <
nhits; ++ihit) {
187 (simIt->second).hit_info[0][iSample] += p_charge;
188 if (iSample == (
unsigned short)thisBx) {
189 if (hitRefs_bx0[detId].
empty()) {
190 hitRefs_bx0[detId].emplace_back(p_charge, p_time);
192 if (p_time < hitRefs_bx0[detId].back().
second) {
194 hitRefs_bx0[detId].
end(),
195 std::make_pair(0.
f, p_time),
196 [](
const auto&
i,
const auto&
j) {
return i.second <
j.second; });
198 auto insertedPos = findPos;
199 if (findPos == hitRefs_bx0[detId].begin()) {
200 insertedPos = hitRefs_bx0[detId].emplace(insertedPos, p_charge, p_time);
202 itr prevPos = findPos - 1;
203 if (prevPos->second == p_time) {
204 prevPos->first = prevPos->first + p_charge;
205 insertedPos = prevPos;
206 }
else if (prevPos->second < p_time) {
207 insertedPos = hitRefs_bx0[detId].emplace(findPos, (prevPos)->
first + p_charge, p_time);
211 for (
itr step = insertedPos;
step != hitRefs_bx0[detId].end(); ++
step) {
212 if (
step != insertedPos)
213 step->first += p_charge;
216 hitOrder_monitor[detId] =
true;
218 }
else if (p_time == hitRefs_bx0[detId].back().second) {
219 hitRefs_bx0[detId].back().first += p_charge;
220 }
else if (p_time > hitRefs_bx0[detId].back().
second) {
221 hitRefs_bx0[detId].emplace_back(hitRefs_bx0[detId].back().
first + p_charge, p_time);
230 for (
const auto& hitmapIterator : hitRefs_bx0) {
231 unsigned int detectorId = hitmapIterator.first;
232 auto simIt = simData.emplace(detectorId,
HGCCellInfo()).first;
233 const bool orderChanged = hitOrder_monitor[detectorId];
234 int waferThickness = getCellThickness(
geom, detectorId);
235 float cell_threshold = tdcForToAOnset[waferThickness - 1];
236 const auto& hitRec = hitmapIterator.second;
237 float accChargeForToA(0.
f), fireTDC(0.
f);
239 hitRec.begin(), hitRec.end(), std::make_pair(cell_threshold, 0.
f), [](
const auto&
i,
const auto&
j) {
240 return i.first <
j.first;
243 if (aboveThrPos == hitRec.end()) {
244 accChargeForToA = hitRec.back().first;
246 }
else if (hitRec.end() - aboveThrPos > 0 || orderChanged) {
247 accChargeForToA = aboveThrPos->first;
248 fireTDC = aboveThrPos->second;
249 if (aboveThrPos - hitRec.begin() >= 1) {
250 const auto& belowThrPos = aboveThrPos - 1;
251 float chargeBeforeThr = belowThrPos->first;
252 float timeBeforeThr = belowThrPos->second;
253 float deltaQ = accChargeForToA - chargeBeforeThr;
254 float deltaTOF = fireTDC - timeBeforeThr;
255 fireTDC = (cell_threshold - chargeBeforeThr) * deltaTOF / deltaQ + timeBeforeThr;
258 (simIt->second).hit_info[1][9] = fireTDC;
267 myDet_(
DetId::Forward),
269 refSpeed_(0.1 *
CLHEP::c_light),
270 averageOccupancies_(occupancyGuesses),
285 std::unordered_set<DetId>().swap(
validIds_);
292 .getParameter<std::vector<double>>(
"values");
293 for (
double cce :
temp) {
294 cce_.emplace_back(cce);
297 std::vector<float>().swap(
cce_);
346 : static_cast<const CaloSubdetectorGeometry*>(
gHGCal_));
361 auto simRecord = std::make_unique<PHGCSimAccumulator>();
364 saveSimHitAccumulator_forPreMix(
372 auto digiResult = std::make_unique<HGCalDigiCollection>();
376 edm::LogVerbatim(
"HGCDigitizer") <<
"HGCDigitizer:: finalize event - produced " << digiResult->size()
384 auto digiResult = std::make_unique<HGCalDigiCollection>();
386 edm::LogVerbatim(
"HGCDigitizer") <<
"HGCDigitizer:: finalize event - produced " << digiResult->size()
387 <<
" HE silicon hits";
394 auto digiResult = std::make_unique<HGCalDigiCollection>();
396 edm::LogVerbatim(
"HGCDigitizer") <<
"HGCDigitizer:: finalize event - produced " << digiResult->size()
397 <<
" HE Scintillator hits";
404 auto digiResult = std::make_unique<HGCalDigiCollection>();
406 edm::LogVerbatim(
"HGCDigitizer") <<
"HGCDigitizer:: finalize event - produced " << digiResult->size()
420 CLHEP::HepRandomEngine* hre) {
425 if (!
hits.isValid()) {
427 <<
" collection of g4SimHits";
434 }
else if (
nullptr !=
gHcal_) {
437 throw cms::Exception(
"BadConfiguration") <<
"HGCDigitizer is not producing EE, FH, or BH digis!";
446 if (!
hits.isValid()) {
454 }
else if (
nullptr !=
gHcal_) {
457 throw cms::Exception(
"BadConfiguration") <<
"HGCDigitizer is not producing EE, FH, or BH digis!";
464 CLHEP::HepRandomEngine* hre) {
468 if (!
hits.isValid()) {
475 }
else if (
nullptr !=
gHcal_) {
478 throw cms::Exception(
"BadConfiguration") <<
"HGCDigitizer is not producing EE, FH, or BH digis!";
485 CLHEP::HepRandomEngine* hre) {
490 if (!
hits.isValid()) {
498 }
else if (
nullptr !=
gHcal_) {
501 throw cms::Exception(
"BadConfiguration") <<
"HGCDigitizer is not producing EE, FH, or BH digis!";
506 template <
typename GEOM>
510 CLHEP::HepRandomEngine* hre) {
516 std::array<float, 3> tdcForToAOnset{{0.f, 0.f, 0.f}};
518 int nchits = (
int)
hits->size();
519 int count_thisbx = 0;
520 std::vector<HGCCaloHitTuple_t> hitRefs;
521 hitRefs.reserve(nchits);
522 for (
int i = 0;
i < nchits; ++
i) {
523 const auto& the_hit =
hits->at(
i);
524 DetId id = simToReco(
geom, the_hit.id());
526 if (
id.rawId() != 0) {
527 hitRefs.emplace_back(
i,
id.rawId(), (
float)the_hit.time());
532 nchits = hitRefs.size();
533 for (
int i = 0;
i < nchits; ++
i) {
534 const int hitidx = std::get<0>(hitRefs[
i]);
535 const uint32_t
id = std::get<1>(hitRefs[
i]);
542 const float toa = std::get<2>(hitRefs[
i]);
546 const float dist2center(getPositionDistance(
geom,
id));
548 const int itime = std::floor(tof /
bxTime_) + 9;
550 if (itime < 0 || itime > (
int)
maxBx_)
553 if (itime >= (
int)(
maxBx_ + 1))
556 int waferThickness = getCellThickness(
geom,
id);
561 }
else if (tof > std::get<2>(
PhitRefs_bx0[
id].back())) {
563 }
else if (tof == std::get<2>(
PhitRefs_bx0[
id].back())) {
572 [](
const auto&
i,
const auto&
j) {
return std::get<2>(
i) <= std::get<2>(
j); });
576 if (tof == std::get<2>(*(findPos - 1))) {
577 std::get<0>(*(findPos - 1)) +=
charge;
578 std::get<1>(*(findPos - 1)) +=
charge;
590 if (
step != insertedPos)
594 if (std::get<1>(*
step) > tdcForToAOnset[waferThickness - 1] &&
600 [](
const auto&
i,
const auto&
j) {
return std::get<2>(
i) < std::get<2>(
j); }) -
603 std::get<1>(*stepEnd) +=
charge;
615 for (
const auto& hit_timestamp :
PhitRefs_bx0[detectorId]) {
616 (simHitIt->second).PUhit_info[1][
thisBx_].push_back(std::get<2>(hit_timestamp));
617 (simHitIt->second).PUhit_info[0][
thisBx_].push_back(std::get<0>(hit_timestamp));
623 (simHitIt->second).PUhit_info[1][9].push_back(0.0);
624 (simHitIt->second).PUhit_info[0][9].push_back(0.0);
631 template <
typename GEOM>
635 CLHEP::HepRandomEngine* hre) {
640 std::array<float, 3> tdcForToAOnset{{0.f, 0.f, 0.f}};
645 int nchits = (
int)
hits->size();
647 std::vector<HGCCaloHitTuple_t> hitRefs;
648 hitRefs.reserve(nchits);
649 for (
int i = 0;
i < nchits; ++
i) {
650 const auto& the_hit =
hits->at(
i);
651 DetId id = simToReco(
geom, the_hit.id());
655 edm::LogVerbatim(
"HGCDigitizer") <<
"HGCDigitizer::i/p " << std::hex << the_hit.id() <<
" o/p " <<
id.rawId()
658 edm::LogVerbatim(
"HGCDigitizer") <<
"HGCDigitizer::i/p " << std::hex << the_hit.id() <<
" o/p " <<
id.rawId()
662 if (0 !=
id.rawId()) {
663 hitRefs.emplace_back(
i,
id.rawId(), (
float)the_hit.time());
669 nchits = hitRefs.size();
670 for (
int i = 0;
i < nchits; ++
i) {
671 const int hitidx = std::get<0>(hitRefs[
i]);
672 const uint32_t
id = std::get<1>(hitRefs[
i]);
683 const float toa = std::get<2>(hitRefs[
i]);
688 const float dist2center(getPositionDistance(
geom,
id));
693 const int itime = std::floor(tof /
bxTime_) + 9;
699 if (itime < 0 || itime > (
int)
maxBx_)
703 if (itime >= (
int)simHitIt->second.hit_info[0].size())
706 (simHitIt->second).hit_info[0][itime] +=
charge;
710 int waferThickness = getCellThickness(
geom,
id);
711 bool orderChanged =
false;
719 std::vector<std::pair<float, float>>::iterator findPos =
722 std::pair<float, float>(0.
f, tof),
723 [](
const auto&
i,
const auto&
j) {
return i.second <=
j.second; });
725 std::vector<std::pair<float, float>>::iterator insertedPos = findPos;
726 if (findPos->second == tof) {
733 ? std::pair<float, float>(
charge, tof)
734 : std::pair<float, float>((findPos - 1)->
first +
charge, tof));
740 if (
step != insertedPos)
743 if (
step->first > tdcForToAOnset[waferThickness - 1] &&
step->second !=
hitRefs_bx0[
id].back().second) {
746 std::pair<float, float>(0.
f,
step->second),
747 [](
const auto&
i,
const auto&
j) { return i.second < j.second; }) -
758 if (
hitRefs_bx0[
id].back().first <= tdcForToAOnset[waferThickness - 1]) {
765 if (weightToAbyEnergy)
766 (simHitIt->second).hit_info[1][itime] +=
charge * tof;
767 else if (accChargeForToA > tdcForToAOnset[waferThickness - 1] &&
768 ((simHitIt->second).hit_info[1][itime] == 0 || orderChanged ==
true)) {
774 float deltaQ = accChargeForToA - chargeBeforeThr;
775 float deltaTOF = fireTDC - tofchargeBeforeThr;
776 fireTDC = (tdcForToAOnset[waferThickness - 1] - chargeBeforeThr) * deltaTOF / deltaQ + tofchargeBeforeThr;
778 (simHitIt->second).hit_info[1][itime] = fireTDC;
785 std::array<float, 3> tdcForToAOnset{{0.f, 0.f, 0.f}};
802 }
else if (
nullptr !=
gHcal_) {
846 }
else if (
nullptr !=
gHcal_) {
849 throw cms::Exception(
"BadConfiguration") <<
"HGCDigitizer is not producing EE, FH, or BH digis!";
863 it->second.hit_info[0].fill(0.);
864 it->second.hit_info[1].fill(0.);
909 bool weightToAbyEnergy(
false);
961 return weightToAbyEnergy;
965 const double tol(0.5);
967 for (
const auto& digi : *(digis)) {
968 const DetId&
id = digi.id();
970 double r = global.
perp();
974 bool ok = ((
r >= rrange.first) && (
r <= rrange.second) && (
z >=
zrange.first) && (
z <=
zrange.second));
975 std::string ck = (((
r < rrange.first - tol) || (
r > rrange.second + tol) || (
z <
zrange.first - tol) ||
977 ?
"***** ERROR *****"
980 if ((!
ok) || (!
val)) {
983 << rrange.first <<
":" << rrange.second <<
" Z " <<
z <<
":" <<
zrange.first
984 <<
":" <<
zrange.second <<
" Flag " <<
ok <<
":" <<
val <<
" " << ck;
987 << rrange.first <<
":" << rrange.second <<
" Z " <<
z <<
":" <<
zrange.first
988 <<
":" <<
zrange.second <<
" Flag " <<
ok <<
":" <<
val <<
" " << ck;
991 << rrange.first <<
":" << rrange.second <<
" Z " <<
z <<
":" <<
zrange.first
992 <<
":" <<
zrange.second <<
" Flag " <<
ok <<
":" <<
val <<
" " << ck;
995 <<
"Check " << std::hex <<
id.rawId() <<
std::dec <<
" " <<
id.det() <<
":" <<
id.subdetId() <<
" "
996 << global <<
" R " <<
r <<
":" << rrange.first <<
":" << rrange.second <<
" Z " <<
z <<
":"
997 <<
zrange.first <<
":" <<
zrange.second <<
" Flag " <<
ok <<
":" <<
val <<
" " << ck;
1007 CLHEP::HepRandomEngine* hre);
1012 CLHEP::HepRandomEngine* hre);
1017 CLHEP::HepRandomEngine* hre);
1021 CLHEP::HepRandomEngine* hre);