26 typedef std::unordered_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}};
35 const auto& dddConst =
geom->topology().dddConstants();
36 return (1 + dddConst.waferType(detid,
false));
40 const std::vector<DetId>& ids =
geom->getValidDetIds();
41 valid.reserve(ids.size());
42 valid.insert(ids.begin(), ids.end());
47 const auto& topo =
geom->topology();
48 const auto& dddConst = topo.dddConstants();
50 if (dddConst.waferHexagon8() || dddConst.tileTrapezoid()) {
53 int subdet(
DetId(simId).subdetId()), layer, cell,
sec, subsec, zp;
57 auto recoLayerCell = dddConst.simToReco(cell, layer,
sec, topo.detectorType());
58 cell = recoLayerCell.first;
59 layer = recoLayerCell.second;
60 if (layer < 0 || cell < 0) {
72 const std::unordered_set<DetId>& validIds,
73 const float minCharge,
74 const float maxCharge) {
77 "PHGCSimAccumulator bit pattern needs to updated");
79 "PHGCSimAccumulator bit pattern needs to updated");
80 const float minPackChargeLog = minCharge > 0.f ?
std::log(minCharge) : -2;
81 const float maxPackChargeLog =
std::log(maxCharge);
84 simResult.
reserve(simData.size());
86 for (
const auto&
id : validIds) {
87 auto found = simData.find(
id);
88 if (
found == simData.end())
94 const std::vector<float>& accCharge_inthis_bx = accCharge_across_bxs[iSample];
95 const std::vector<float>& timing_inthis_bx = timing_across_bxs[iSample];
96 std::vector<unsigned short> vc, vt;
97 size_t nhits = accCharge_inthis_bx.size();
99 for (
size_t ihit = 0; ihit <
nhits; ++ihit) {
100 if (accCharge_inthis_bx[ihit] > minCharge) {
119 const float minCharge,
120 const float maxCharge,
122 const std::array<float, 3>& tdcForToAOnset,
123 const bool minbiasFlag,
124 std::unordered_map<uint32_t, bool>& hitOrder_monitor,
125 const unsigned int thisBx) {
126 const float minPackChargeLog = minCharge > 0.f ?
std::log(minCharge) : -2;
127 const float maxPackChargeLog =
std::log(maxCharge);
129 for (
const auto& detIdIndexHitInfo : simAccumulator) {
130 unsigned int detId = detIdIndexHitInfo.detId();
132 auto simIt = simData.emplace(detId,
HGCCellInfo()).first;
133 size_t nhits = detIdIndexHitInfo.nhits();
135 hitOrder_monitor[detId] =
false;
137 unsigned short iSample = detIdIndexHitInfo.sampleIndex();
139 const auto& unsigned_charge_array = detIdIndexHitInfo.chargeArray();
140 const auto& unsigned_time_array = detIdIndexHitInfo.timeArray();
142 float p_charge, p_time;
143 unsigned short unsigned_charge, unsigned_time;
145 for (
size_t ihit = 0; ihit <
nhits; ++ihit) {
151 (simIt->second).hit_info[0][iSample] += p_charge;
152 if (iSample == (
unsigned short)thisBx) {
153 if (hitRefs_bx0[detId].
empty()) {
154 hitRefs_bx0[detId].emplace_back(p_charge, p_time);
156 if (p_time < hitRefs_bx0[detId].back().
second) {
158 hitRefs_bx0[detId].end(),
159 std::make_pair(0.
f, p_time),
160 [](
const auto&
i,
const auto&
j) {
return i.second <
j.second; });
162 auto insertedPos = findPos;
163 if (findPos == hitRefs_bx0[detId].begin()) {
164 insertedPos = hitRefs_bx0[detId].emplace(insertedPos, p_charge, p_time);
166 auto prevPos = findPos - 1;
167 if (prevPos->second == p_time) {
168 prevPos->first = prevPos->first + p_charge;
169 insertedPos = prevPos;
170 }
else if (prevPos->second < p_time) {
171 insertedPos = hitRefs_bx0[detId].emplace(findPos, (prevPos)->
first + p_charge, p_time);
175 for (
auto step = insertedPos;
step != hitRefs_bx0[detId].end(); ++
step) {
176 if (
step != insertedPos)
177 step->first += p_charge;
180 hitOrder_monitor[detId] =
true;
182 }
else if (p_time == hitRefs_bx0[detId].back().second) {
183 hitRefs_bx0[detId].back().first += p_charge;
184 }
else if (p_time > hitRefs_bx0[detId].back().
second) {
185 hitRefs_bx0[detId].emplace_back(hitRefs_bx0[detId].back().
first + p_charge, p_time);
194 for (
const auto& hitmapIterator : hitRefs_bx0) {
195 unsigned int detectorId = hitmapIterator.first;
196 auto simIt = simData.emplace(detectorId,
HGCCellInfo()).first;
197 const bool orderChanged = hitOrder_monitor[detectorId];
198 int waferThickness = getCellThickness(
geom, detectorId);
199 float cell_threshold = tdcForToAOnset[waferThickness - 1];
200 const auto& hitRec = hitmapIterator.second;
203 hitRec.begin(), hitRec.end(), std::make_pair(cell_threshold, 0.
f), [](
const auto&
i,
const auto&
j) {
204 return i.first <
j.first;
207 if (aboveThrPos != hitRec.end()) {
208 if (hitRec.end() - aboveThrPos > 0 || orderChanged) {
209 fireTDC = aboveThrPos->second;
210 if (aboveThrPos - hitRec.begin() >= 1) {
211 float accChargeForToA = aboveThrPos->first;
212 const auto& belowThrPos = aboveThrPos - 1;
213 float chargeBeforeThr = belowThrPos->first;
214 float timeBeforeThr = belowThrPos->second;
215 float deltaQ = accChargeForToA - chargeBeforeThr;
216 float deltaTOF = fireTDC - timeBeforeThr;
217 fireTDC = (cell_threshold - chargeBeforeThr) * deltaTOF / deltaQ + timeBeforeThr;
221 (simIt->second).hit_info[1][9] = fireTDC;
230 digiCollection_(ps.getParameter<
std::
string>(
"digiCollection")),
231 digitizationType_(ps.getParameter<uint32_t>(
"digitizationType")),
232 premixStage1_(ps.getParameter<
bool>(
"premixStage1")),
233 premixStage1MinCharge_(ps.getParameter<double>(
"premixStage1MinCharge")),
234 premixStage1MaxCharge_(ps.getParameter<double>(
"premixStage1MaxCharge")),
235 maxSimHitsAccTime_(ps.getParameter<uint32_t>(
"maxSimHitsAccTime")),
236 bxTime_(ps.getParameter<double>(
"bxTime")),
237 hitsProducer_(ps.getParameter<
std::
string>(
"hitsProducer")),
238 hitCollection_(ps.getParameter<
std::
string>(
"hitCollection")),
241 verbosity_(ps.getUntrackedParameter<uint32_t>(
"verbosity", 0)),
242 tofDelay_(ps.getParameter<double>(
"tofDelay")),
243 averageOccupancies_(occupancyGuesses),
252 .getParameter<std::vector<double>>(
"values");
253 for (
double cce :
temp) {
254 cce_.emplace_back(cce);
280 throw cms::Exception(
"BadConfiguration") <<
"HGCDigitizer is not producing EE, FH, or BH digis!";
315 auto simRecord = std::make_unique<PHGCSimAccumulator>();
318 saveSimHitAccumulator_forPreMix(
325 auto digiResult = std::make_unique<HGCalDigiCollection>();
327 edm::LogVerbatim(
"HGCDigitizer") <<
"HGCDigitizer:: finalize event - produced " << digiResult->size()
341 CLHEP::HepRandomEngine* hre) {
345 if (!
hits.isValid()) {
355 throw cms::Exception(
"BadConfiguration") <<
"HGCDigitizer is not producing EE, FH, or BH digis!";
363 if (!
hits.isValid()) {
373 throw cms::Exception(
"BadConfiguration") <<
"HGCDigitizer is not producing EE, FH, or BH digis!";
380 CLHEP::HepRandomEngine* hre) {
383 e.getByLabel(hitTag,
hits);
385 if (!
hits.isValid()) {
394 throw cms::Exception(
"BadConfiguration") <<
"HGCDigitizer is not producing EE, FH, or BH digis!";
401 CLHEP::HepRandomEngine* hre) {
405 e.getByLabel(hitTag,
hits);
407 if (!
hits.isValid()) {
417 throw cms::Exception(
"BadConfiguration") <<
"HGCDigitizer is not producing EE, FH, or BH digis!";
425 CLHEP::HepRandomEngine* hre) {
432 int nchits = (
int)
hits->size();
433 int count_thisbx = 0;
434 std::vector<HGCCaloHitTuple_t> hitRefs;
435 hitRefs.reserve(nchits);
436 for (
int i = 0;
i < nchits; ++
i) {
437 const auto& the_hit =
hits->at(
i);
438 DetId id = simToReco(
geom, the_hit.id());
440 if (
id.rawId() != 0) {
441 hitRefs.emplace_back(
i,
id.rawId(), (
float)the_hit.time());
446 nchits = hitRefs.size();
447 for (
int i = 0;
i < nchits; ++
i) {
448 const int hitidx = std::get<0>(hitRefs[
i]);
449 const uint32_t
id = std::get<1>(hitRefs[
i]);
456 const float toa = std::get<2>(hitRefs[
i]);
461 const int itime = std::floor(tof /
bxTime_) + 9;
463 if (itime < 0 || itime > (
int)
maxBx_)
466 if (itime >= (
int)(
maxBx_ + 1))
469 int waferThickness = getCellThickness(
geom,
id);
474 }
else if (tof > std::get<2>(
PhitRefs_bx0[
id].back())) {
476 }
else if (tof == std::get<2>(
PhitRefs_bx0[
id].back())) {
484 [](
const auto&
i,
const auto&
j) {
return std::get<2>(
i) <= std::get<2>(
j); });
486 auto insertedPos = findPos;
488 if (tof == std::get<2>(*(findPos - 1))) {
489 std::get<0>(*(findPos - 1)) +=
charge;
490 std::get<1>(*(findPos - 1)) +=
charge;
502 if (
step != insertedPos)
506 if (std::get<1>(*
step) > tdcForToAOnset[waferThickness - 1] &&
512 [](
const auto&
i,
const auto&
j) {
return std::get<2>(
i) < std::get<2>(
j); }) -
515 std::get<1>(*stepEnd) +=
charge;
527 for (
const auto& hit_timestamp :
PhitRefs_bx0[detectorId]) {
528 (simHitIt->second).PUhit_info[1][
thisBx_].
push_back(std::get<2>(hit_timestamp));
529 (simHitIt->second).PUhit_info[0][
thisBx_].
push_back(std::get<0>(hit_timestamp));
535 (simHitIt->second).PUhit_info[1][9].
push_back(0.0);
536 (simHitIt->second).PUhit_info[0][9].
push_back(0.0);
546 CLHEP::HepRandomEngine* hre) {
556 int nchits = (
int)
hits->size();
558 std::vector<HGCCaloHitTuple_t> hitRefs;
559 hitRefs.reserve(nchits);
560 for (
int i = 0;
i < nchits; ++
i) {
561 const auto& the_hit =
hits->at(
i);
562 DetId id = simToReco(
geom, the_hit.id());
565 edm::LogVerbatim(
"HGCDigitizer") <<
"HGCDigitizer::i/p " << std::hex << the_hit.id() <<
" o/p " <<
id.rawId()
569 if (0 !=
id.rawId()) {
570 hitRefs.emplace_back(
i,
id.rawId(), (
float)the_hit.time());
576 nchits = hitRefs.size();
577 for (
int i = 0;
i < nchits; ++
i) {
578 const int hitidx = std::get<0>(hitRefs[
i]);
579 const uint32_t
id = std::get<1>(hitRefs[
i]);
590 const float toa = std::get<2>(hitRefs[
i]);
597 const int itime = std::floor(tof /
bxTime_) + 9;
603 if (itime < 0 || itime > (
int)
maxBx_)
607 if (itime >= (
int)simHitIt->second.hit_info[0].size())
610 (simHitIt->second).hit_info[0][itime] +=
charge;
614 int waferThickness = getCellThickness(
geom,
id);
615 bool orderChanged =
false;
623 std::vector<std::pair<float, float>>::iterator findPos =
626 std::pair<float, float>(0.
f, tof),
627 [](
const auto&
i,
const auto&
j) {
return i.second <=
j.second; });
629 std::vector<std::pair<float, float>>::iterator insertedPos = findPos;
630 if (findPos->second == tof) {
637 ? std::pair<float, float>(
charge, tof)
638 : std::pair<float, float>((findPos - 1)->
first +
charge, tof));
644 if (
step != insertedPos)
647 if (
step->first > tdcForToAOnset[waferThickness - 1] &&
step->second !=
hitRefs_bx0[
id].back().second) {
650 std::pair<float, float>(0.
f,
step->second),
651 [](
const auto&
i,
const auto&
j) { return i.second < j.second; }) -
662 if (
hitRefs_bx0[
id].back().first <= tdcForToAOnset[waferThickness - 1]) {
669 if (weightToAbyEnergy)
670 (simHitIt->second).hit_info[1][itime] +=
charge * tof;
671 else if (accChargeForToA > tdcForToAOnset[waferThickness - 1] &&
672 ((simHitIt->second).hit_info[1][itime] == 0 || orderChanged ==
true)) {
678 float deltaQ = accChargeForToA - chargeBeforeThr;
679 float deltaTOF = fireTDC - tofchargeBeforeThr;
680 fireTDC = (tdcForToAOnset[waferThickness - 1] - chargeBeforeThr) * deltaTOF / deltaQ + tofchargeBeforeThr;
682 (simHitIt->second).hit_info[1][itime] = fireTDC;
711 it->second.hit_info[0].fill(0.);
712 it->second.hit_info[1].fill(0.);
738 const double tol(0.5);
740 for (
const auto& digi : *(digis)) {
741 const DetId&
id = digi.id();
743 double r = global.
perp();
747 bool ok = ((
r >= rrange.first) && (
r <= rrange.second) && (
z >=
zrange.first) && (
z <=
zrange.second));
748 std::string ck = (((
r < rrange.first - tol) || (
r > rrange.second + tol) || (
z <
zrange.first - tol) ||
750 ?
"***** ERROR *****" 753 if ((!
ok) || (!
val)) {
756 << rrange.first <<
":" << rrange.second <<
" Z " <<
z <<
":" <<
zrange.first
757 <<
":" <<
zrange.second <<
" Flag " <<
ok <<
":" <<
val <<
" " << ck;
760 << rrange.first <<
":" << rrange.second <<
" Z " <<
z <<
":" <<
zrange.first
761 <<
":" <<
zrange.second <<
" Flag " <<
ok <<
":" <<
val <<
" " << ck;
764 << rrange.first <<
":" << rrange.second <<
" Z " <<
z <<
":" <<
zrange.first
765 <<
":" <<
zrange.second <<
" Flag " <<
ok <<
":" <<
val <<
" " << ck;
768 <<
"Check " << std::hex <<
id.rawId() <<
std::dec <<
" " <<
id.det() <<
":" <<
id.subdetId() <<
" " 769 << global <<
" R " <<
r <<
":" << rrange.first <<
":" << rrange.second <<
" Z " <<
z <<
":" 770 <<
zrange.first <<
":" <<
zrange.second <<
" Flag " <<
ok <<
":" <<
val <<
" " << ck;
const std::string hitsProducer_
Log< level::Info, true > LogVerbatim
void emplace_back(unsigned int detId, unsigned short sampleIndex, const std::vector< unsigned short > &accCharge, const std::vector< unsigned short > &timing)
void checkPosition(const HGCalDigiCollection *digis) const
std::pair< double, double > rangeZ(bool reco) const
T getParameter(std::string const &) const
std::vector< float > cce_
void finalizeEvent(edm::Event &e, edm::EventSetup const &c, CLHEP::HepRandomEngine *hre)
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
std::unique_ptr< HGCDigitizerBase > theDigitizer_
void resetSimHitDataAccumulator()
const edm::ESGetToken< CaloGeometry, CaloGeometryRecord > geomToken_
bool valid(const DetId &id) const override
Is this a valid cell id.
std::unordered_map< uint32_t, HGCCellInfo > HGCSimHitDataAccumulator
void initializeEvent(edm::Event const &e, edm::EventSetup const &c)
actions at the start/end of event
static constexpr unsigned dataMask
double unpack16log(int16_t i, double lmin, double lmax, uint16_t base=32768)
Log< level::Error, false > LogError
const double premixStage1MaxCharge_
const HGCalGeometry * gHGCal_
void swap(Association< C > &lhs, Association< C > &rhs)
U second(std::pair< T, U > const &p)
const double premixStage1MinCharge_
static const unsigned int maxBx_
edm::ESWatcher< CaloGeometryRecord > geomWatcher_
std::unordered_map< uint32_t, std::vector< hit_timeStamp > > hitRec_container
const uint32_t verbosity_
static constexpr unsigned sampleOffset
std::unordered_map< uint32_t, std::vector< std::tuple< float, float, float > > > PhitRefs_bx0
std::unordered_map< uint32_t, bool > hitOrder_monitor
Abs< T >::type abs(const T &t)
std::array< HGCSimDataCollection, nSamples > PUSimHitData
std::unordered_set< DetId > validIds_
constexpr size_t nSamples
const HGCalTopology & topology() const
static const unsigned int thisBx_
std::unordered_map< uint32_t, std::vector< std::pair< float, float > > > IdHit_Map
std::pair< double, double > rangeR(double z, bool reco) const
Log< level::Info, false > LogInfo
void reserve(size_t size)
bool check(const edm::EventSetup &iSetup)
deadvectors [0] push_back({0.0175431, 0.538005, 6.80997, 13.29})
const edm::EDGetTokenT< std::vector< PCaloHit > > hitToken_
GlobalPoint getPosition(const DetId &id, bool debug=false) const
std::array< double, 4 > averageOccupancies_
void accumulate(edm::Event const &e, edm::EventSetup const &c, CLHEP::HepRandomEngine *hre)
handle SimHit accumulation
std::unordered_map< uint32_t, std::vector< std::pair< float, float > > > hitRefs_bx0
HGCDigitizer(const edm::ParameterSet &ps, edm::ConsumesCollector &iC)
std::tuple< float, float, float > hit_timeStamp
std::unique_ptr< hgc::HGCSimHitDataAccumulator > simHitAccumulator_
static bool orderByDetIdThenTime(const HGCCaloHitTuple_t &a, const HGCCaloHitTuple_t &b)
void accumulate_forPreMix(edm::Event const &e, edm::EventSetup const &c, CLHEP::HepRandomEngine *hre)
static constexpr unsigned energyMask
int16_t pack16log(double x, double lmin, double lmax, uint16_t base=32768)
std::unique_ptr< hgc::HGCPUSimHitDataAccumulator > pusimHitAccumulator_
std::string digiCollection()
const HGCalDDDConstants & dddConstants() const
static void unpackHexagonIndex(const uint32_t &idx, int &subdet, int &z, int &lay, int &wafer, int &celltyp, int &cell)
const int digitizationType_
const std::string hitCollection_
static constexpr unsigned sampleMask
std::unordered_map< uint32_t, HGCCellHitInfo > HGCPUSimHitDataAccumulator