20 #include <boost/foreach.hpp> 27 typedef std::unordered_map<uint32_t, std::vector<std::pair<float, float>>>
IdHit_Map;
33 constexpr std::array<double, 4> occupancyGuesses = {{0.5, 0.2, 0.2, 0.8}};
36 const auto& dddConst =
geom->topology().dddConstants();
37 return (1 + dddConst.waferType(detid));
41 const std::vector<DetId>& ids =
geom->getValidDetIds();
42 valid.reserve(ids.size());
43 valid.insert(ids.begin(), ids.end());
48 const auto& topo =
geom->topology();
49 const auto& dddConst = topo.dddConstants();
51 if (dddConst.waferHexagon8() || dddConst.tileTrapezoid()) {
54 int subdet(
DetId(simId).subdetId()), layer, cell,
sec, subsec, zp;
58 auto recoLayerCell = dddConst.simToReco(cell, layer,
sec, topo.detectorType());
59 cell = recoLayerCell.first;
60 layer = recoLayerCell.second;
61 if (layer < 0 || cell < 0) {
73 const std::unordered_set<DetId>& validIds,
74 const float minCharge,
75 const float maxCharge) {
78 "PHGCSimAccumulator bit pattern needs to updated");
80 "PHGCSimAccumulator bit pattern needs to updated");
81 const float minPackChargeLog = minCharge > 0.f ?
std::log(minCharge) : -2;
82 const float maxPackChargeLog =
std::log(maxCharge);
85 simResult.
reserve(simData.size());
87 for (
const auto&
id : validIds) {
88 auto found = simData.find(
id);
89 if (
found == simData.end())
95 const std::vector<float>& accCharge_inthis_bx = accCharge_across_bxs[iSample];
96 const std::vector<float>& timing_inthis_bx = timing_across_bxs[iSample];
97 std::vector<unsigned short> vc, vt;
98 size_t nhits = accCharge_inthis_bx.size();
100 for (
size_t ihit = 0; ihit <
nhits; ++ihit) {
101 if (accCharge_inthis_bx[ihit] > minCharge) {
120 const float minCharge,
121 const float maxCharge,
123 const std::array<float, 3>& tdcForToAOnset,
124 const bool minbiasFlag,
125 std::unordered_map<uint32_t, bool>& hitOrder_monitor,
126 const unsigned int thisBx) {
127 const float minPackChargeLog = minCharge > 0.f ?
std::log(minCharge) : -2;
128 const float maxPackChargeLog =
std::log(maxCharge);
130 for (
const auto& detIdIndexHitInfo : simAccumulator) {
131 unsigned int detId = detIdIndexHitInfo.detId();
133 auto simIt = simData.emplace(detId,
HGCCellInfo()).first;
134 size_t nhits = detIdIndexHitInfo.nhits();
136 hitOrder_monitor[detId] =
false;
138 unsigned short iSample = detIdIndexHitInfo.sampleIndex();
140 const auto& unsigned_charge_array = detIdIndexHitInfo.chargeArray();
141 const auto& unsigned_time_array = detIdIndexHitInfo.timeArray();
143 float p_charge, p_time;
144 unsigned short unsigned_charge, unsigned_time;
146 for (
size_t ihit = 0; ihit <
nhits; ++ihit) {
152 (simIt->second).hit_info[0][iSample] += p_charge;
153 if (iSample == (
unsigned short)thisBx) {
154 if (hitRefs_bx0[detId].
empty()) {
155 hitRefs_bx0[detId].emplace_back(p_charge, p_time);
157 if (p_time < hitRefs_bx0[detId].back().
second) {
159 hitRefs_bx0[detId].end(),
160 std::make_pair(0.
f, p_time),
161 [](
const auto&
i,
const auto&
j) {
return i.second <
j.second; });
163 auto insertedPos = findPos;
164 if (findPos == hitRefs_bx0[detId].begin()) {
165 insertedPos = hitRefs_bx0[detId].emplace(insertedPos, p_charge, p_time);
167 auto prevPos = findPos - 1;
168 if (prevPos->second == p_time) {
169 prevPos->first = prevPos->first + p_charge;
170 insertedPos = prevPos;
171 }
else if (prevPos->second < p_time) {
172 insertedPos = hitRefs_bx0[detId].emplace(findPos, (prevPos)->
first + p_charge, p_time);
176 for (
auto step = insertedPos;
step != hitRefs_bx0[detId].end(); ++
step) {
177 if (
step != insertedPos)
178 step->first += p_charge;
181 hitOrder_monitor[detId] =
true;
183 }
else if (p_time == hitRefs_bx0[detId].back().second) {
184 hitRefs_bx0[detId].back().first += p_charge;
185 }
else if (p_time > hitRefs_bx0[detId].back().
second) {
186 hitRefs_bx0[detId].emplace_back(hitRefs_bx0[detId].back().
first + p_charge, p_time);
195 for (
const auto& hitmapIterator : hitRefs_bx0) {
196 unsigned int detectorId = hitmapIterator.first;
197 auto simIt = simData.emplace(detectorId,
HGCCellInfo()).first;
198 const bool orderChanged = hitOrder_monitor[detectorId];
199 int waferThickness = getCellThickness(
geom, detectorId);
200 float cell_threshold = tdcForToAOnset[waferThickness - 1];
201 const auto& hitRec = hitmapIterator.second;
202 float accChargeForToA(0.
f), fireTDC(0.
f);
204 hitRec.begin(), hitRec.end(), std::make_pair(cell_threshold, 0.
f), [](
const auto&
i,
const auto&
j) {
205 return i.first <
j.first;
208 if (aboveThrPos == hitRec.end()) {
209 accChargeForToA = hitRec.back().first;
211 }
else if (hitRec.end() - aboveThrPos > 0 || orderChanged) {
212 accChargeForToA = aboveThrPos->first;
213 fireTDC = aboveThrPos->second;
214 if (aboveThrPos - hitRec.begin() >= 1) {
215 const auto& belowThrPos = aboveThrPos - 1;
216 float chargeBeforeThr = belowThrPos->first;
217 float timeBeforeThr = belowThrPos->second;
218 float deltaQ = accChargeForToA - chargeBeforeThr;
219 float deltaTOF = fireTDC - timeBeforeThr;
220 fireTDC = (cell_threshold - chargeBeforeThr) * deltaTOF / deltaQ + timeBeforeThr;
223 (simIt->second).hit_info[1][9] = fireTDC;
232 digiCollection_(ps.getParameter<
std::
string>(
"digiCollection")),
233 digitizationType_(ps.getParameter<uint32_t>(
"digitizationType")),
234 premixStage1_(ps.getParameter<
bool>(
"premixStage1")),
235 premixStage1MinCharge_(ps.getParameter<double>(
"premixStage1MinCharge")),
236 premixStage1MaxCharge_(ps.getParameter<double>(
"premixStage1MaxCharge")),
237 maxSimHitsAccTime_(ps.getParameter<uint32_t>(
"maxSimHitsAccTime")),
238 bxTime_(ps.getParameter<double>(
"bxTime")),
239 hitsProducer_(ps.getParameter<
std::
string>(
"hitsProducer")),
240 hitCollection_(ps.getParameter<
std::
string>(
"hitCollection")),
243 verbosity_(ps.getUntrackedParameter<uint32_t>(
"verbosity", 0)),
244 tofDelay_(ps.getParameter<double>(
"tofDelay")),
245 averageOccupancies_(occupancyGuesses),
254 .getParameter<std::vector<double>>(
"values");
255 for (
double cce :
temp) {
256 cce_.emplace_back(cce);
282 throw cms::Exception(
"BadConfiguration") <<
"HGCDigitizer is not producing EE, FH, or BH digis!";
317 auto simRecord = std::make_unique<PHGCSimAccumulator>();
320 saveSimHitAccumulator_forPreMix(
327 auto digiResult = std::make_unique<HGCalDigiCollection>();
329 edm::LogVerbatim(
"HGCDigitizer") <<
"HGCDigitizer:: finalize event - produced " << digiResult->size()
343 CLHEP::HepRandomEngine* hre) {
347 if (!
hits.isValid()) {
357 throw cms::Exception(
"BadConfiguration") <<
"HGCDigitizer is not producing EE, FH, or BH digis!";
365 if (!
hits.isValid()) {
375 throw cms::Exception(
"BadConfiguration") <<
"HGCDigitizer is not producing EE, FH, or BH digis!";
382 CLHEP::HepRandomEngine* hre) {
385 e.getByLabel(hitTag,
hits);
387 if (!
hits.isValid()) {
396 throw cms::Exception(
"BadConfiguration") <<
"HGCDigitizer is not producing EE, FH, or BH digis!";
403 CLHEP::HepRandomEngine* hre) {
407 e.getByLabel(hitTag,
hits);
409 if (!
hits.isValid()) {
419 throw cms::Exception(
"BadConfiguration") <<
"HGCDigitizer is not producing EE, FH, or BH digis!";
427 CLHEP::HepRandomEngine* hre) {
434 int nchits = (
int)
hits->size();
435 int count_thisbx = 0;
436 std::vector<HGCCaloHitTuple_t> hitRefs;
437 hitRefs.reserve(nchits);
438 for (
int i = 0;
i < nchits; ++
i) {
439 const auto& the_hit =
hits->at(
i);
440 DetId id = simToReco(
geom, the_hit.id());
442 if (
id.rawId() != 0) {
443 hitRefs.emplace_back(
i,
id.rawId(), (
float)the_hit.time());
448 nchits = hitRefs.size();
449 for (
int i = 0;
i < nchits; ++
i) {
450 const int hitidx = std::get<0>(hitRefs[
i]);
451 const uint32_t
id = std::get<1>(hitRefs[
i]);
458 const float toa = std::get<2>(hitRefs[
i]);
463 const int itime = std::floor(tof /
bxTime_) + 9;
465 if (itime < 0 || itime > (
int)
maxBx_)
468 if (itime >= (
int)(
maxBx_ + 1))
471 int waferThickness = getCellThickness(
geom,
id);
476 }
else if (tof > std::get<2>(
PhitRefs_bx0[
id].back())) {
478 }
else if (tof == std::get<2>(
PhitRefs_bx0[
id].back())) {
486 [](
const auto&
i,
const auto&
j) {
return std::get<2>(
i) <= std::get<2>(
j); });
488 auto insertedPos = findPos;
490 if (tof == std::get<2>(*(findPos - 1))) {
491 std::get<0>(*(findPos - 1)) +=
charge;
492 std::get<1>(*(findPos - 1)) +=
charge;
504 if (
step != insertedPos)
508 if (std::get<1>(*
step) > tdcForToAOnset[waferThickness - 1] &&
514 [](
const auto&
i,
const auto&
j) {
return std::get<2>(
i) < std::get<2>(
j); }) -
517 std::get<1>(*stepEnd) +=
charge;
529 for (
const auto& hit_timestamp :
PhitRefs_bx0[detectorId]) {
530 (simHitIt->second).PUhit_info[1][
thisBx_].
push_back(std::get<2>(hit_timestamp));
531 (simHitIt->second).PUhit_info[0][
thisBx_].
push_back(std::get<0>(hit_timestamp));
537 (simHitIt->second).PUhit_info[1][9].
push_back(0.0);
538 (simHitIt->second).PUhit_info[0][9].
push_back(0.0);
548 CLHEP::HepRandomEngine* hre) {
558 int nchits = (
int)
hits->size();
560 std::vector<HGCCaloHitTuple_t> hitRefs;
561 hitRefs.reserve(nchits);
562 for (
int i = 0;
i < nchits; ++
i) {
563 const auto& the_hit =
hits->at(
i);
564 DetId id = simToReco(
geom, the_hit.id());
567 edm::LogVerbatim(
"HGCDigitizer") <<
"HGCDigitizer::i/p " << std::hex << the_hit.id() <<
" o/p " <<
id.rawId()
571 if (0 !=
id.rawId()) {
572 hitRefs.emplace_back(
i,
id.rawId(), (
float)the_hit.time());
578 nchits = hitRefs.size();
579 for (
int i = 0;
i < nchits; ++
i) {
580 const int hitidx = std::get<0>(hitRefs[
i]);
581 const uint32_t
id = std::get<1>(hitRefs[
i]);
592 const float toa = std::get<2>(hitRefs[
i]);
599 const int itime = std::floor(tof /
bxTime_) + 9;
605 if (itime < 0 || itime > (
int)
maxBx_)
609 if (itime >= (
int)simHitIt->second.hit_info[0].size())
612 (simHitIt->second).hit_info[0][itime] +=
charge;
616 int waferThickness = getCellThickness(
geom,
id);
617 bool orderChanged =
false;
625 std::vector<std::pair<float, float>>::iterator findPos =
628 std::pair<float, float>(0.
f, tof),
629 [](
const auto&
i,
const auto&
j) {
return i.second <=
j.second; });
631 std::vector<std::pair<float, float>>::iterator insertedPos = findPos;
632 if (findPos->second == tof) {
639 ? std::pair<float, float>(
charge, tof)
640 : std::pair<float, float>((findPos - 1)->
first +
charge, tof));
646 if (
step != insertedPos)
649 if (
step->first > tdcForToAOnset[waferThickness - 1] &&
step->second !=
hitRefs_bx0[
id].back().second) {
652 std::pair<float, float>(0.
f,
step->second),
653 [](
const auto&
i,
const auto&
j) { return i.second < j.second; }) -
664 if (
hitRefs_bx0[
id].back().first <= tdcForToAOnset[waferThickness - 1]) {
671 if (weightToAbyEnergy)
672 (simHitIt->second).hit_info[1][itime] +=
charge * tof;
673 else if (accChargeForToA > tdcForToAOnset[waferThickness - 1] &&
674 ((simHitIt->second).hit_info[1][itime] == 0 || orderChanged ==
true)) {
680 float deltaQ = accChargeForToA - chargeBeforeThr;
681 float deltaTOF = fireTDC - tofchargeBeforeThr;
682 fireTDC = (tdcForToAOnset[waferThickness - 1] - chargeBeforeThr) * deltaTOF / deltaQ + tofchargeBeforeThr;
684 (simHitIt->second).hit_info[1][itime] = fireTDC;
713 it->second.hit_info[0].fill(0.);
714 it->second.hit_info[1].fill(0.);
740 const double tol(0.5);
742 for (
const auto& digi : *(digis)) {
743 const DetId&
id = digi.id();
745 double r = global.
perp();
749 bool ok = ((
r >= rrange.first) && (
r <= rrange.second) && (
z >=
zrange.first) && (
z <=
zrange.second));
750 std::string ck = (((
r < rrange.first - tol) || (
r > rrange.second + tol) || (
z <
zrange.first - tol) ||
752 ?
"***** ERROR *****" 755 if ((!
ok) || (!
val)) {
758 << rrange.first <<
":" << rrange.second <<
" Z " <<
z <<
":" <<
zrange.first
759 <<
":" <<
zrange.second <<
" Flag " <<
ok <<
":" <<
val <<
" " << ck;
762 << rrange.first <<
":" << rrange.second <<
" Z " <<
z <<
":" <<
zrange.first
763 <<
":" <<
zrange.second <<
" Flag " <<
ok <<
":" <<
val <<
" " << ck;
766 << rrange.first <<
":" << rrange.second <<
" Z " <<
z <<
":" <<
zrange.first
767 <<
":" <<
zrange.second <<
" Flag " <<
ok <<
":" <<
val <<
" " << ck;
770 <<
"Check " << std::hex <<
id.rawId() <<
std::dec <<
" " <<
id.det() <<
":" <<
id.subdetId() <<
" " 771 << global <<
" R " <<
r <<
":" << rrange.first <<
":" << rrange.second <<
" Z " <<
z <<
":" 772 <<
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)
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_
bool getData(T &iHolder) const
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