22 #include <boost/foreach.hpp>
28 typedef std::vector<std::pair<float, float>>::iterator
itr;
29 typedef std::map<uint32_t, std::vector<std::pair<float, float>>>
IdHit_Map;
32 constexpr std::array<double, 4> occupancyGuesses = {{0.5, 0.2, 0.2, 0.8}};
37 return geom->getGeometry(
id)->getPosition().mag();
41 const auto& dddConst =
geom->topology().dddConstants();
42 return (1 + dddConst.waferType(detid));
48 const std::vector<DetId>& ids =
geom->getValidDetIds();
49 valid.reserve(ids.size());
50 valid.insert(ids.begin(), ids.end());
54 const std::vector<DetId>& ids =
geom->getValidDetIds();
55 for (
const auto&
id : ids) {
64 const auto& topo =
geom->topology();
65 const auto* dddConst = topo.dddConstants();
77 const auto& topo =
geom->topology();
78 const auto& dddConst = topo.dddConstants();
85 int subdet(
DetId(simId).subdetId()), layer, cell,
sec, subsec, zp;
89 auto recoLayerCell = dddConst.simToReco(cell, layer,
sec, topo.detectorType());
90 cell = recoLayerCell.first;
91 layer = recoLayerCell.second;
92 if (layer < 0 || cell < 0) {
104 const std::unordered_set<DetId>& validIds,
105 const float minCharge,
106 const float maxCharge) {
109 "PHGCSimAccumulator bit pattern needs to updated");
111 "PHGCSimAccumulator bit pattern needs to updated");
112 const float minPackChargeLog = minCharge > 0.f ?
std::log(minCharge) : -2;
113 const float maxPackChargeLog =
std::log(maxCharge);
116 simResult.
reserve(simData.size());
118 for (
const auto&
id : validIds) {
119 auto found = simData.find(
id);
120 if (
found == simData.end())
126 const std::vector<float>& accCharge_inthis_bx = accCharge_across_bxs[iSample];
127 const std::vector<float>& timing_inthis_bx = timing_across_bxs[iSample];
128 std::vector<unsigned short> vc, vt;
129 size_t nhits = accCharge_inthis_bx.size();
131 for (
size_t ihit = 0; ihit <
nhits; ++ihit) {
132 if (accCharge_inthis_bx[ihit] > minCharge) {
146 typedef std::vector<std::pair<float, float>>::iterator
itr;
147 typedef std::unordered_map<uint32_t, std::vector<std::pair<float, float>>>
IdHit_Map;
148 template <
typename GEOM>
154 const float minCharge,
155 const float maxCharge,
157 const std::array<float, 3>& tdcForToAOnset,
158 const bool minbiasFlag,
159 std::unordered_map<uint32_t, bool>& hitOrder_monitor,
160 const unsigned int thisBx) {
161 const float minPackChargeLog = minCharge > 0.f ?
std::log(minCharge) : -2;
162 const float maxPackChargeLog =
std::log(maxCharge);
164 for (
const auto& detIdIndexHitInfo : simAccumulator) {
165 unsigned int detId = detIdIndexHitInfo.detId();
167 auto simIt = simData.emplace(detId,
HGCCellInfo()).first;
168 size_t nhits = detIdIndexHitInfo.nhits();
170 hitOrder_monitor[detId] =
false;
172 unsigned short iSample = detIdIndexHitInfo.sampleIndex();
174 const auto& unsigned_charge_array = detIdIndexHitInfo.chargeArray();
175 const auto& unsigned_time_array = detIdIndexHitInfo.timeArray();
177 float p_charge, p_time;
178 unsigned short unsigned_charge, unsigned_time;
180 for (
size_t ihit = 0; ihit <
nhits; ++ihit) {
186 (simIt->second).hit_info[0][iSample] += p_charge;
187 if (iSample == (
unsigned short)thisBx) {
188 if (hitRefs_bx0[detId].
empty()) {
189 hitRefs_bx0[detId].emplace_back(p_charge, p_time);
191 if (p_time < hitRefs_bx0[detId].back().
second) {
193 hitRefs_bx0[detId].
end(),
194 std::make_pair(0.
f, p_time),
195 [](
const auto&
i,
const auto&
j) {
return i.second <
j.second; });
197 auto insertedPos = findPos;
198 if (findPos == hitRefs_bx0[detId].
begin()) {
199 insertedPos = hitRefs_bx0[detId].emplace(insertedPos, p_charge, p_time);
201 itr prevPos = findPos - 1;
202 if (prevPos->second == p_time) {
203 prevPos->first = prevPos->first + p_charge;
204 insertedPos = prevPos;
205 }
else if (prevPos->second < p_time) {
206 insertedPos = hitRefs_bx0[detId].emplace(findPos, (prevPos)->
first + p_charge, p_time);
210 for (
itr step = insertedPos;
step != hitRefs_bx0[detId].end(); ++
step) {
211 if (
step != insertedPos)
212 step->first += p_charge;
215 hitOrder_monitor[detId] =
true;
217 }
else if (p_time == hitRefs_bx0[detId].back().second) {
218 hitRefs_bx0[detId].back().first += p_charge;
219 }
else if (p_time > hitRefs_bx0[detId].back().
second) {
220 hitRefs_bx0[detId].emplace_back(hitRefs_bx0[detId].back().
first + p_charge, p_time);
229 for (
const auto& hitmapIterator : hitRefs_bx0) {
230 unsigned int detectorId = hitmapIterator.first;
231 auto simIt = simData.emplace(detectorId,
HGCCellInfo()).first;
232 const bool orderChanged = hitOrder_monitor[detectorId];
233 int waferThickness = getCellThickness(
geom, detectorId);
234 float cell_threshold = tdcForToAOnset[waferThickness - 1];
235 const auto& hitRec = hitmapIterator.second;
236 float accChargeForToA(0.
f), fireTDC(0.
f);
238 hitRec.begin(), hitRec.end(), std::make_pair(cell_threshold, 0.
f), [](
const auto&
i,
const auto&
j) {
239 return i.first <
j.first;
242 if (aboveThrPos == hitRec.end()) {
243 accChargeForToA = hitRec.back().first;
245 }
else if (hitRec.end() - aboveThrPos > 0 || orderChanged) {
246 accChargeForToA = aboveThrPos->first;
247 fireTDC = aboveThrPos->second;
248 if (aboveThrPos - hitRec.begin() >= 1) {
249 const auto& belowThrPos = aboveThrPos - 1;
250 float chargeBeforeThr = belowThrPos->first;
251 float timeBeforeThr = belowThrPos->second;
252 float deltaQ = accChargeForToA - chargeBeforeThr;
253 float deltaTOF = fireTDC - timeBeforeThr;
254 fireTDC = (cell_threshold - chargeBeforeThr) * deltaTOF / deltaQ + timeBeforeThr;
257 (simIt->second).hit_info[1][9] = fireTDC;
266 myDet_(
DetId::Forward),
268 refSpeed_(0.1 *
CLHEP::c_light),
269 averageOccupancies_(occupancyGuesses),
284 std::unordered_set<DetId>().swap(
validIds_);
291 .getParameter<std::vector<double>>(
"values");
292 for (
double cce :
temp) {
293 cce_.emplace_back(cce);
296 std::vector<float>().swap(
cce_);
343 : static_cast<const CaloSubdetectorGeometry*>(
gHGCal_));
358 auto simRecord = std::make_unique<PHGCSimAccumulator>();
361 saveSimHitAccumulator_forPreMix(
369 auto digiResult = std::make_unique<HGCalDigiCollection>();
373 edm::LogVerbatim(
"HGCDigitizer") <<
"HGCDigitizer:: finalize event - produced " << digiResult->size()
381 auto digiResult = std::make_unique<HGCalDigiCollection>();
383 edm::LogVerbatim(
"HGCDigitizer") <<
"HGCDigitizer:: finalize event - produced " << digiResult->size()
384 <<
" HE silicon hits";
391 auto digiResult = std::make_unique<HGCalDigiCollection>();
393 edm::LogVerbatim(
"HGCDigitizer") <<
"HGCDigitizer:: finalize event - produced " << digiResult->size()
394 <<
" HE Scintillator hits";
401 auto digiResult = std::make_unique<HGCalDigiCollection>();
403 edm::LogVerbatim(
"HGCDigitizer") <<
"HGCDigitizer:: finalize event - produced " << digiResult->size()
417 CLHEP::HepRandomEngine* hre) {
421 if (!
hits.isValid()) {
423 <<
" collection of g4SimHits";
430 }
else if (
nullptr !=
gHcal_) {
433 throw cms::Exception(
"BadConfiguration") <<
"HGCDigitizer is not producing EE, FH, or BH digis!";
442 if (!
hits.isValid()) {
450 }
else if (
nullptr !=
gHcal_) {
453 throw cms::Exception(
"BadConfiguration") <<
"HGCDigitizer is not producing EE, FH, or BH digis!";
460 CLHEP::HepRandomEngine* hre) {
464 if (!
hits.isValid()) {
471 }
else if (
nullptr !=
gHcal_) {
474 throw cms::Exception(
"BadConfiguration") <<
"HGCDigitizer is not producing EE, FH, or BH digis!";
481 CLHEP::HepRandomEngine* hre) {
486 if (!
hits.isValid()) {
494 }
else if (
nullptr !=
gHcal_) {
497 throw cms::Exception(
"BadConfiguration") <<
"HGCDigitizer is not producing EE, FH, or BH digis!";
502 template <
typename GEOM>
506 CLHEP::HepRandomEngine* hre) {
512 int nchits = (
int)
hits->size();
514 std::vector<HGCCaloHitTuple_t> hitRefs;
515 hitRefs.reserve(nchits);
516 for (
int i = 0;
i < nchits; ++
i) {
517 const auto& the_hit =
hits->at(
i);
518 DetId id = simToReco(
geom, the_hit.id());
520 if (
id.rawId() != 0) {
521 hitRefs.emplace_back(
i,
id.rawId(), (
float)the_hit.time());
526 nchits = hitRefs.size();
527 for (
int i = 0;
i < nchits; ++
i) {
528 const int hitidx = std::get<0>(hitRefs[
i]);
529 const uint32_t
id = std::get<1>(hitRefs[
i]);
537 const float toa = std::get<2>(hitRefs[
i]);
541 const float dist2center(getPositionDistance(
geom,
id));
543 const int itime = std::floor(tof /
bxTime_) + 9;
545 if (itime < 0 || itime > (
int)
maxBx_)
548 if (itime >= (
int)simHitIt->second.PUhit_info[0].size())
550 (simHitIt->second).PUhit_info[1][itime].push_back(tof);
551 (simHitIt->second).PUhit_info[0][itime].push_back(
charge);
555 (simHitIt->second).PUhit_info[1][9].push_back(0.0);
556 (simHitIt->second).PUhit_info[0][9].push_back(0.0);
562 template <
typename GEOM>
566 CLHEP::HepRandomEngine* hre) {
571 std::array<float, 3> tdcForToAOnset{{0.f, 0.f, 0.f}};
576 int nchits = (
int)
hits->size();
578 std::vector<HGCCaloHitTuple_t> hitRefs;
579 hitRefs.reserve(nchits);
580 for (
int i = 0;
i < nchits; ++
i) {
581 const auto& the_hit =
hits->at(
i);
582 DetId id = simToReco(
geom, the_hit.id());
586 edm::LogVerbatim(
"HGCDigitizer") <<
"HGCDigitizer::i/p " << std::hex << the_hit.id() <<
" o/p " <<
id.rawId()
589 edm::LogVerbatim(
"HGCDigitizer") <<
"HGCDigitizer::i/p " << std::hex << the_hit.id() <<
" o/p " <<
id.rawId()
593 if (0 !=
id.rawId()) {
594 hitRefs.emplace_back(
i,
id.rawId(), (
float)the_hit.time());
600 nchits = hitRefs.size();
601 for (
int i = 0;
i < nchits; ++
i) {
602 const int hitidx = std::get<0>(hitRefs[
i]);
603 const uint32_t
id = std::get<1>(hitRefs[
i]);
614 const float toa = std::get<2>(hitRefs[
i]);
619 const float dist2center(getPositionDistance(
geom,
id));
624 const int itime = std::floor(tof /
bxTime_) + 9;
630 if (itime < 0 || itime > (
int)
maxBx_)
634 if (itime >= (
int)simHitIt->second.hit_info[0].size())
637 (simHitIt->second).hit_info[0][itime] +=
charge;
641 int waferThickness = getCellThickness(
geom,
id);
642 bool orderChanged =
false;
650 std::vector<std::pair<float, float>>::iterator findPos =
653 std::pair<float, float>(0.
f, tof),
654 [](
const auto&
i,
const auto&
j) {
return i.second <=
j.second; });
656 std::vector<std::pair<float, float>>::iterator insertedPos = findPos;
657 if (findPos->second == tof) {
664 ? std::pair<float, float>(
charge, tof)
665 : std::pair<float, float>((findPos - 1)->
first +
charge, tof));
671 if (
step != insertedPos)
674 if (
step->first > tdcForToAOnset[waferThickness - 1] &&
step->second !=
hitRefs_bx0[
id].back().second) {
677 std::pair<float, float>(0.
f,
step->second),
678 [](
const auto&
i,
const auto&
j) { return i.second < j.second; }) -
689 if (
hitRefs_bx0[
id].back().first <= tdcForToAOnset[waferThickness - 1]) {
696 if (weightToAbyEnergy)
697 (simHitIt->second).hit_info[1][itime] +=
charge * tof;
698 else if (accChargeForToA > tdcForToAOnset[waferThickness - 1] &&
699 ((simHitIt->second).hit_info[1][itime] == 0 || orderChanged ==
true)) {
705 float deltaQ = accChargeForToA - chargeBeforeThr;
706 float deltaTOF = fireTDC - tofchargeBeforeThr;
707 fireTDC = (tdcForToAOnset[waferThickness - 1] - chargeBeforeThr) * deltaTOF / deltaQ + tofchargeBeforeThr;
709 (simHitIt->second).hit_info[1][itime] = fireTDC;
716 std::array<float, 3> tdcForToAOnset{{0.f, 0.f, 0.f}};
733 }
else if (
nullptr !=
gHcal_) {
777 }
else if (
nullptr !=
gHcal_) {
780 throw cms::Exception(
"BadConfiguration") <<
"HGCDigitizer is not producing EE, FH, or BH digis!";
794 it->second.hit_info[0].fill(0.);
795 it->second.hit_info[1].fill(0.);
840 bool weightToAbyEnergy(
false);
892 return weightToAbyEnergy;
896 const double tol(0.5);
898 for (
const auto& digi : *(digis)) {
899 const DetId&
id = digi.id();
901 double r = global.
perp();
905 bool ok = ((
r >= rrange.first) && (
r <= rrange.second) && (
z >=
zrange.first) && (
z <=
zrange.second));
906 std::string ck = (((
r < rrange.first - tol) || (
r > rrange.second + tol) || (
z <
zrange.first - tol) ||
908 ?
"***** ERROR *****"
911 if ((!
ok) || (!
val)) {
914 << rrange.first <<
":" << rrange.second <<
" Z " <<
z <<
":" <<
zrange.first
915 <<
":" <<
zrange.second <<
" Flag " <<
ok <<
":" <<
val <<
" " << ck;
918 << rrange.first <<
":" << rrange.second <<
" Z " <<
z <<
":" <<
zrange.first
919 <<
":" <<
zrange.second <<
" Flag " <<
ok <<
":" <<
val <<
" " << ck;
922 << rrange.first <<
":" << rrange.second <<
" Z " <<
z <<
":" <<
zrange.first
923 <<
":" <<
zrange.second <<
" Flag " <<
ok <<
":" <<
val <<
" " << ck;
926 <<
"Check " << std::hex <<
id.rawId() <<
std::dec <<
" " <<
id.det() <<
":" <<
id.subdetId() <<
" "
927 << global <<
" R " <<
r <<
":" << rrange.first <<
":" << rrange.second <<
" Z " <<
z <<
":"
928 <<
zrange.first <<
":" <<
zrange.second <<
" Flag " <<
ok <<
":" <<
val <<
" " << ck;
938 CLHEP::HepRandomEngine* hre);
943 CLHEP::HepRandomEngine* hre);
948 CLHEP::HepRandomEngine* hre);
952 CLHEP::HepRandomEngine* hre);