21 #include <boost/foreach.hpp> 30 constexpr std::array<double,4> occupancyGuesses = { { 0.5,0.2,0.2,0.8 } };
50 void getValidDetIds(
const HGCalGeometry* geom, std::unordered_set<DetId>& valid) {
52 valid.reserve(ids.size());
53 valid.insert(ids.begin(),ids.end());
56 void getValidDetIds(
const HcalGeometry* geom, std::unordered_set<DetId>& valid) {
58 for(
const auto&
id : ids ) {
63 valid.reserve(valid.size());
89 int subdet(
DetId(simId).subdetId()), layer, cell, sec, subsec, zp;
93 auto recoLayerCell = dddConst.simToReco(cell,layer,sec,topo.detectorType());
94 cell = recoLayerCell.first;
95 layer = recoLayerCell.second;
96 if (layer<0 || cell<0) {
108 const std::vector<float>&cces) {
109 if ( cces.empty() )
return 1.
f;
113 const auto& topo = geom->
topology();
115 int waferTypeL = dddConst.
waferType(detid);
116 return cces[waferTypeL-1];
122 const std::vector<float>&cces) {
132 const float minPackChargeLog = minCharge > 0.f ?
std::log(minCharge) : -2;
133 const float maxPackChargeLog =
std::log(maxCharge);
136 simResult.
reserve(simData.size());
138 for(
const auto&
id: validIds) {
139 auto found = simData.find(
id);
140 if(
found == simData.end())
143 for(
size_t iEn = 0; iEn < nEnergies; ++iEn) {
146 if(
samples[iSample] > minCharge) {
148 simResult.
emplace_back(
id.rawId(), iEn, iSample, packed);
158 const float minPackChargeLog = minCharge > 0.f ?
std::log(minCharge) : -2;
159 const float maxPackChargeLog =
std::log(maxCharge);
162 for(
const auto& detIdIndexHitInfo: simAccumulator) {
163 auto simIt = simData.emplace(detIdIndexHitInfo.detId(),
HGCCellInfo()).
first;
164 auto& hit_info = simIt->second.hit_info;
166 size_t iEn = detIdIndexHitInfo.energyIndex();
167 size_t iSample = detIdIndexHitInfo.sampleIndex();
171 if(iEn == 0 || !setIfZero) {
172 hit_info[iEn][iSample] +=
value;
174 else if(hit_info[iEn][iSample] == 0) {
175 hit_info[iEn][iSample] =
value;
185 myDet_(
DetId::Forward),
187 refSpeed_(0.1*
CLHEP::c_light),
188 averageOccupancies_(occupancyGuesses),
211 const auto&
temp = myCfg_.getParameter<
edm::ParameterSet>(
"chargeCollectionEfficiencies").getParameter<std::vector<double>>(
"values");
212 for(
double cce :
temp ) {
213 cce_.emplace_back(cce);
220 if (geometryType_ == 0) {
228 if (geometryType_ == 0) {
235 if(
hitCollection_.find(
"HcalHits")!=std::string::npos and geometryType_ == 0) {
239 if(
hitCollection_.find(
"HitsHEback")!=std::string::npos and geometryType_ == 1) {
265 static_cast<const CaloSubdetectorGeometry*>(
gHGCal_) );
278 std::unique_ptr<PHGCSimAccumulator> simResult;
280 simResult = std::make_unique<PHGCSimAccumulator>();
286 auto digiResult = std::make_unique<HGCalDigiCollection>();
288 edm::LogInfo(
"HGCDigitizer") <<
" @ finalize event - produced " 289 << digiResult->size() <<
" EE hits";
296 auto digiResult = std::make_unique<HGCalDigiCollection>();
298 edm::LogInfo(
"HGCDigitizer") <<
" @ finalize event - produced " 299 << digiResult->size() <<
" HE front hits";
306 auto digiResult = std::make_unique<HGCalDigiCollection>();
308 edm::LogInfo(
"HGCDigitizer") <<
" @ finalize event - produced " 309 << digiResult->size() <<
" HE back hits";
316 auto digiResult = std::make_unique<HGCalDigiCollection>();
319 edm::LogInfo(
"HGCDigitizer") <<
" @ finalize event - produced " 320 << digiResult->size() <<
" HFNose hits";
345 }
else if(
nullptr !=
gHcal_ ) {
349 <<
"HGCDigitizer is not producing EE, FH, or BH digis!";
367 }
else if (
nullptr !=
gHcal_ ) {
371 <<
"HGCDigitizer is not producing EE, FH, or BH digis!";
376 template<
typename GEOM>
380 CLHEP::HepRandomEngine* hre) {
381 if(
nullptr == geom )
return;
386 std::array<float, 3> tdcForToAOnset{ {0.f, 0.f, 0.f} };
388 bool weightToAbyEnergy=
getWeight(tdcForToAOnset, keV2fC);
391 int nchits=(
int)hits->size();
392 std::vector< HGCCaloHitTuple_t > hitRefs;
393 hitRefs.reserve(nchits);
394 for(
int i=0;
i<nchits; ++
i) {
395 const auto& the_hit = hits->at(
i);
397 DetId id = simToReco(geom,the_hit.id());
401 edm::LogInfo(
"HGCDigitizer") <<
" i/p " << std::hex << the_hit.id() <<
" o/p " <<
id.rawId() <<
std::dec << std::endl;
403 edm::LogInfo(
"HGCDigitizer") <<
" i/p " << std::hex << the_hit.id() <<
" o/p " <<
id.rawId() <<
std::dec << std::endl;
406 if( 0 !=
id.rawId() ) {
407 hitRefs.emplace_back(
i,
id.rawId(), (
float)the_hit.time() );
413 nchits = hitRefs.size();
414 for(
int i=0;
i<nchits; ++
i) {
415 const int hitidx = std::get<0>(hitRefs[
i]);
416 const uint32_t
id = std::get<1>(hitRefs[
i]);
425 const float toa = std::get<2>(hitRefs[
i]);
427 const float charge = hit.energy()*1e6*keV2fC*getCCE(geom,
id,
cce_);
430 const float dist2center( getPositionDistance(geom,
id) );
435 const int itime= std::floor( tof/
bxTime_ ) + 9;
441 if(itime<0 || itime>14)
continue;
444 if(itime >= (
int)simHitIt->second.hit_info[0].size() )
continue;
446 (simHitIt->second).hit_info[0][itime] += charge;
450 int waferThickness = getCellThickness(geom,
id);
451 bool orderChanged =
false;
457 std::vector<std::pair<float, float> >::iterator findPos =
459 [](
const auto&
i,
const auto& j){
return i.second < j.second;});
461 std::vector<std::pair<float, float> >::iterator insertedPos =
463 std::pair<float, float>(charge,tof) : std::pair<float, float>((findPos-1)->
first+charge,tof));
467 if(
step->first > tdcForToAOnset[waferThickness-1] &&
step->second !=
hitRefs_bx0[
id].back().second){
469 [](
const auto&
i,
const auto& j){return i.second < j.second;}) -
hitRefs_bx0[
id].begin());
470 for(
auto stepEnd =
step+1; stepEnd !=
hitRefs_bx0[
id].end(); ++stepEnd) stepEnd->first += charge;
477 if(
hitRefs_bx0[
id].back().first <= tdcForToAOnset[waferThickness-1]){
486 if(weightToAbyEnergy) (simHitIt->second).hit_info[1][itime] += charge*tof;
487 else if(accChargeForToA > tdcForToAOnset[waferThickness-1] &&
488 ((simHitIt->second).hit_info[1][itime] == 0 || orderChanged ==
true) ){
491 float chargeBeforeThr = 0.f;
492 float tofchargeBeforeThr = 0.f;
494 if(
step.first + chargeBeforeThr <= tdcForToAOnset[waferThickness-1]){
495 chargeBeforeThr +=
step.first;
496 tofchargeBeforeThr =
step.second;
500 float deltaQ = accChargeForToA - chargeBeforeThr;
501 float deltaTOF = fireTDC - tofchargeBeforeThr;
502 fireTDC = (tdcForToAOnset[waferThickness-1] - chargeBeforeThr) * deltaTOF / deltaQ + tofchargeBeforeThr;
504 (simHitIt->second).hit_info[1][itime] = fireTDC;
513 std::array<float, 3> tdcForToAOnset{ {0.f, 0.f, 0.f} };
515 bool weightToAbyEnergy=
getWeight(tdcForToAOnset, keV2fC);
544 }
else if(
nullptr !=
gHcal_ ) {
548 <<
"HGCDigitizer is not producing EE, FH, or BH digis!";
553 <<
"Added " << nadded <<
":" <<
validIds_.size()
555 <<
" in first event processed" << std::endl;
569 it->second.hit_info[0].fill(0.);
570 it->second.hit_info[1].fill(0.);
618 bool weightToAbyEnergy(
false);
670 return weightToAbyEnergy;
675 const double tol(0.5);
677 for (
const auto & digi : *(digis)) {
678 const DetId&
id = digi.id();
680 double r = global.
perp();
684 bool ok = ((r >= rrange.first) && (r <= rrange.second) &&
685 (z >= zrange.first) && (z <= zrange.second));
686 std::string ck = (((r < rrange.first-tol) || (r > rrange.second+tol) ||
687 (z < zrange.first-tol) || (z > zrange.second+tol)) ?
688 "***** ERROR *****" :
"");
692 <<
" " << global <<
" R " << r
693 <<
":" << rrange.first <<
":" 694 << rrange.second <<
" Z " << z
695 <<
":" << zrange.first <<
":" 696 << zrange.second <<
" Flag " 700 <<
" " << global <<
" R " << r
701 <<
":" << rrange.first <<
":" 702 << rrange.second <<
" Z " << z
703 <<
":" << zrange.first <<
":" 704 << zrange.second <<
" Flag " 708 <<
" " << global <<
" R " << r
709 <<
":" << rrange.first <<
":" 710 << rrange.second <<
" Z " << z
711 <<
":" << zrange.first <<
":" 712 << zrange.second <<
" Flag "
int bunchCrossing() const
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
T getParameter(std::string const &) const
const CaloSubdetectorGeometry * getSubdetectorGeometry(const DetId &id) const
access the subdetector geometry for the given subdetector directly
T getUntrackedParameter(std::string const &, T const &) const
const HcalDDDRecConstants * dddConstants() const
std::shared_ptr< const CaloCellGeometry > getGeometry(const DetId &id) const override
Get the cell geometry of a given detector id. Should return false if not found.
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
std::vector< float > cce_
void finalizeEvent(edm::Event &e, edm::EventSetup const &c, CLHEP::HepRandomEngine *hre)
ForwardSubdetector mySubDet_
std::string hitCollection_
void resetSimHitDataAccumulator()
static constexpr unsigned sampleMask
void saveSimHitAccumulator(PMTDSimAccumulator &simResult, const MTDSimHitDataAccumulator &simData, const float minCharge, const float maxCharge)
const std::vector< DetId > & getValidDetIds(DetId::Detector det=DetId::Detector(0), int subdet=0) const override
Get a list of valid detector ids (for the given subdetector)
void emplace_back(unsigned int detId, unsigned short energyIndex, unsigned short sampleIndex, unsigned short data)
void initializeEvent(edm::Event const &e, edm::EventSetup const &c)
actions at the start/end of event
double unpack16log(int16_t i, double lmin, double lmax, uint16_t base=32768)
GlobalPoint getPosition(const DetId &id) const
std::unique_ptr< HFNoseDigitizer > theHFNoseDigitizer_
const HGCalGeometry * gHGCal_
void swap(Association< C > &lhs, Association< C > &rhs)
bool getWeight(std::array< float, 3 > &tdcForToAOnset, float &keV2fC) const
std::string digiCollection_
const HcalTopology & topology() const
static constexpr unsigned sampleOffset
static constexpr unsigned energyMask
U second(std::pair< T, U > const &p)
std::unordered_map< uint32_t, HGCCellInfo > HGCSimHitDataAccumulator
std::pair< double, double > rangeR(double z, bool reco) const
std::pair< double, double > rangeZ(bool reco) const
void beginRun(const edm::EventSetup &es)
actions at the start/end of run
const HGCalTopology & topology() const
Abs< T >::type abs(const T &t)
std::unordered_set< DetId > validIds_
base
Make Sure CMSSW is Setup ##.
constexpr size_t nSamples
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
std::array< double, 4 > averageOccupancies_
bool producesHFNoseDigis()
bool producesHEfrontDigis()
int waferType(DetId const &id) const
std::unique_ptr< HGCHEbackDigitizer > theHGCHEbackDigitizer_
const std::vector< DetId > & getValidDetIds(DetId::Detector det=DetId::Detector(0), int subdet=0) const override
Get a list of valid detector ids (for the given subdetector)
void reserve(size_t size)
double premixStage1MinCharge_
void checkPosition(const HGCalDigiCollection *digis) const
bool producesHEbackDigis()
const HGCalDDDConstants & dddConstants() const
std::unique_ptr< HGCHEfrontDigitizer > theHGCHEfrontDigitizer_
std::unique_ptr< HGCEEDigitizer > theHGCEEDigitizer_
void accumulate(edm::Event const &e, edm::EventSetup const &c, CLHEP::HepRandomEngine *hre)
handle SimHit accumulation
bool getByLabel(edm::InputTag const &tag, edm::Handle< T > &result) const
std::map< uint32_t, std::vector< std::pair< float, float > > > hitRefs_bx0
HGCDigitizer(const edm::ParameterSet &ps, edm::ConsumesCollector &iC)
DetId relabel(const uint32_t testId) const
std::unique_ptr< hgc::HGCSimHitDataAccumulator > simHitAccumulator_
static bool orderByDetIdThenTime(const HGCCaloHitTuple_t &a, const HGCCaloHitTuple_t &b)
int16_t pack16log(double x, double lmin, double lmax, uint16_t base=32768)
void loadSimHitAccumulator(MTDSimHitDataAccumulator &simData, const PMTDSimAccumulator &simAccumulator, const float minCharge, const float maxCharge)
double premixStage1MaxCharge_
std::string digiCollection()
const HcalGeometry * gHcal_
static void unpackHexagonIndex(const uint32_t &idx, int &subdet, int &z, int &lay, int &wafer, int &celltyp, int &cell)
constexpr Detector det() const
get the detector field from this detid