CMS 3D CMS Logo

HGCHEbackDigitizer.cc
Go to the documentation of this file.
2 
3 #include "CLHEP/Random/RandPoissonQ.h"
4 #include "CLHEP/Random/RandGaussQ.h"
5 
8 
9 #include "vdt/vdtMath.h"
10 
11 using namespace hgc_digi;
12 using namespace hgc_digi_utils;
13 
14 //
17  algo_ = cfg.getParameter<uint32_t>("algo");
18  scaleByTileArea_ = cfg.getParameter<bool>("scaleByTileArea");
19  scaleBySipmArea_ = cfg.getParameter<bool>("scaleBySipmArea");
20  sipmMapFile_ = cfg.getParameter<std::string>("sipmMap");
21  scaleByDose_ = cfg.getParameter<edm::ParameterSet>("noise").getParameter<bool>("scaleByDose");
22  unsigned int scaleByDoseAlgo = cfg.getParameter<edm::ParameterSet>("noise").getParameter<uint32_t>("scaleByDoseAlgo");
23  doseMapFile_ = cfg.getParameter<edm::ParameterSet>("noise").getParameter<std::string>("doseMap");
24  noise_MIP_ = cfg.getParameter<edm::ParameterSet>("noise").getParameter<double>("noise_MIP");
25  thresholdFollowsMIP_ = cfg.getParameter<bool>("thresholdFollowsMIP");
26  keV2MIP_ = cfg.getParameter<double>("keV2MIP");
27  this->keV2fC_ = 1.0; //keV2MIP_; // hack for HEB
28  nPEperMIP_ = cfg.getParameter<double>("nPEperMIP");
29  nTotalPE_ = cfg.getParameter<double>("nTotalPE");
30  xTalk_ = cfg.getParameter<double>("xTalk");
31  sdPixels_ = cfg.getParameter<double>("sdPixels");
32 
35 }
36 
37 //
38 void HGCHEbackDigitizer::runDigitizer(std::unique_ptr<HGCalDigiCollection>& digiColl,
39  HGCSimHitDataAccumulator& simData,
40  const CaloSubdetectorGeometry* theGeom,
41  const std::unordered_set<DetId>& validIds,
42  uint32_t digitizationType,
43  CLHEP::HepRandomEngine* engine) {
44  if (algo_ == 0)
45  runEmptyDigitizer(digiColl, simData, theGeom, validIds, engine);
46  else if (algo_ == 1)
47  runCaliceLikeDigitizer(digiColl, simData, theGeom, validIds, engine);
48  else if (algo_ == 2)
49  runRealisticDigitizer(digiColl, simData, theGeom, validIds, engine);
50 }
51 
52 void HGCHEbackDigitizer::runEmptyDigitizer(std::unique_ptr<HGCalDigiCollection>& digiColl,
53  HGCSimHitDataAccumulator& simData,
54  const CaloSubdetectorGeometry* theGeom,
55  const std::unordered_set<DetId>& validIds,
56  CLHEP::HepRandomEngine* engine) {
57  HGCSimHitData chargeColl, toa;
58  // this represents a cell with no signal charge
59  HGCCellInfo zeroData;
60  zeroData.hit_info[0].fill(0.f); //accumulated energy
61  zeroData.hit_info[1].fill(0.f); //time-of-flight
62 
63  for (const auto& id : validIds) {
64  chargeColl.fill(0.f);
65  toa.fill(0.f);
66  HGCSimHitDataAccumulator::iterator it = simData.find(id);
67  HGCCellInfo& cell = (simData.end() == it ? zeroData : it->second);
68  addCellMetadata(cell, theGeom, id);
69 
70  for (size_t i = 0; i < cell.hit_info[0].size(); ++i) {
71  //convert total energy keV->MIP, since converted to keV in accumulator
72  const float totalIniMIPs(cell.hit_info[0][i] * keV2MIP_);
73 
74  //store
75  chargeColl[i] = totalIniMIPs;
76  }
77 
78  //init a new data frame and run shaper
79  HGCalDataFrame newDataFrame(id);
80  this->myFEelectronics_->runShaper(newDataFrame, chargeColl, toa, engine);
81 
82  //prepare the output
83  this->updateOutput(digiColl, newDataFrame);
84  }
85 }
86 
87 void HGCHEbackDigitizer::runRealisticDigitizer(std::unique_ptr<HGCalDigiCollection>& digiColl,
88  HGCSimHitDataAccumulator& simData,
89  const CaloSubdetectorGeometry* theGeom,
90  const std::unordered_set<DetId>& validIds,
91  CLHEP::HepRandomEngine* engine) {
92  //switch to true if you want to print some details
93  constexpr bool debug(false);
94 
95  HGCSimHitData chargeColl, toa;
96  // this represents a cell with no signal charge
97  HGCCellInfo zeroData;
98  zeroData.hit_info[0].fill(0.f); //accumulated energy
99  zeroData.hit_info[1].fill(0.f); //time-of-flight
100 
101  // needed to compute the radiation and geometry scale factors
102  scal_.setGeometry(theGeom);
103 
104  for (const auto& id : validIds) {
105  chargeColl.fill(0.f);
106  toa.fill(0.f);
107  HGCSimHitDataAccumulator::iterator it = simData.find(id);
108  HGCCellInfo& cell = (simData.end() == it ? zeroData : it->second);
109  addCellMetadata(cell, theGeom, id);
110 
111  float scaledPePerMip = nPEperMIP_; //needed to scale according to tile geometry
112  float tunedNoise = nPEperMIP_ * noise_MIP_; //flat noise case
113  float sipmFactor = 1.; //standard 2 mm^2 sipm
114 
115  if (id.det() == DetId::HGCalHSc) //skip those geometries that have HE used as BH
116  {
119  radius = scal_.computeRadius(id);
120 
121  //take into account the tile size
122  if (scaleByTileArea_)
123  scaledPePerMip *= scal_.scaleByTileArea(id, radius);
124 
125  //take into account the darkening of the scintillator and SiPM dark current
126  if (scaleByDose_) {
127  auto dosePair = scal_.scaleByDose(id, radius);
128  scaledPePerMip *= dosePair.first;
129  tunedNoise = dosePair.second;
130  }
131 
132  //take into account the sipm size
133  if (scaleBySipmArea_) {
134  sipmFactor = scal_.scaleBySipmArea(id, radius[0]);
135  scaledPePerMip *= sipmFactor;
136  tunedNoise *= sqrt(sipmFactor);
137  }
138  }
139 
140  //set mean for poissonian noise
141  float meanN = std::pow(tunedNoise, 2);
142 
143  for (size_t i = 0; i < cell.hit_info[0].size(); ++i) {
144  //convert total energy keV->MIP, since converted to keV in accumulator
145  float totalIniMIPs(cell.hit_info[0][i] * keV2MIP_);
146 
147  //generate the number of photo-electrons from the energy deposit
148  const uint32_t npeS = std::floor(CLHEP::RandPoissonQ::shoot(engine, totalIniMIPs * scaledPePerMip) + 0.5);
149 
150  //generate the noise associated to the dark current
151  const uint32_t npeN = std::floor(CLHEP::RandPoissonQ::shoot(engine, meanN) + 0.5);
152 
153  //total number of pe from signal + noise (not subtracting pedestal)
154  const uint32_t npe = npeS + npeN;
155 
156  //take into account SiPM saturation
157  float nTotalPixels = nTotalPE_ * sipmFactor;
158  const float x = vdt::fast_expf(-((float)npe) / nTotalPixels);
159  uint32_t nPixel(0);
160  if (xTalk_ * x != 1)
161  nPixel = (uint32_t)std::max(nTotalPixels * (1.f - x) / (1.f - xTalk_ * x), 0.f);
162 
163  //take into account the gain fluctuations of each pixel
164  //const float nPixelTot = nPixel + sqrt(nPixel) * CLHEP::RandGaussQ::shoot(engine, 0., 0.05); //FDG: just a note for now, par to be defined
165 
166  //scale to calibrated response depending on the thresholdFollowsMIP_ flag
167  float totalMIPs = thresholdFollowsMIP_ ? std::max((npe - meanN), 0.f) / nPEperMIP_ : nPixel / nPEperMIP_;
168 
169  if (debug && totalIniMIPs > 0) {
170  LogDebug("HGCHEbackDigitizer") << "npeS: " << npeS << " npeN: " << npeN << " npe: " << npe
171  << " meanN: " << meanN << " noise_MIP_: " << noise_MIP_
172  << " nPEperMIP_: " << nPEperMIP_ << " scaledPePerMip: " << scaledPePerMip
173  << " nPixel: " << nPixel;
174  LogDebug("HGCHEbackDigitizer") << "totalIniMIPs: " << totalIniMIPs << " totalMIPs: " << totalMIPs << std::endl;
175  }
176 
177  //store charge
178  chargeColl[i] = totalMIPs;
179 
180  //update time of arrival
181  toa[i] = cell.hit_info[1][i];
182  if (myFEelectronics_->toaMode() == HGCFEElectronics<HGCalDataFrame>::WEIGHTEDBYE && totalIniMIPs > 0)
183  toa[i] = cell.hit_info[1][i] / totalIniMIPs;
184  }
185 
186  //init a new data frame and run shaper
187  HGCalDataFrame newDataFrame(id);
188  float adcThr = this->myFEelectronics_->getADCThreshold(); //this is in MIPs
189  float adcLsb = this->myFEelectronics_->getADClsb();
190  uint32_t thrADC(thresholdFollowsMIP_ ? std::floor(adcThr / adcLsb * scaledPePerMip / nPEperMIP_)
191  : std::floor(adcThr / adcLsb));
192 
193  this->myFEelectronics_->runShaper(newDataFrame, chargeColl, toa, engine, thrADC);
194 
195  //prepare the output
196  this->updateOutput(digiColl, newDataFrame);
197  }
198 }
199 
200 //
201 void HGCHEbackDigitizer::runCaliceLikeDigitizer(std::unique_ptr<HGCalDigiCollection>& digiColl,
202  HGCSimHitDataAccumulator& simData,
203  const CaloSubdetectorGeometry* theGeom,
204  const std::unordered_set<DetId>& validIds,
205  CLHEP::HepRandomEngine* engine) {
206  //switch to true if you want to print some details
207  constexpr bool debug(false);
208 
209  HGCSimHitData chargeColl, toa;
210 
211  // this represents a cell with no signal charge
212  HGCCellInfo zeroData;
213  zeroData.hit_info[0].fill(0.f); //accumulated energy
214  zeroData.hit_info[1].fill(0.f); //time-of-flight
215 
216  for (const auto& id : validIds) {
217  chargeColl.fill(0.f);
218  HGCSimHitDataAccumulator::iterator it = simData.find(id);
219  HGCCellInfo& cell = (simData.end() == it ? zeroData : it->second);
220  addCellMetadata(cell, theGeom, id);
221 
222  for (size_t i = 0; i < cell.hit_info[0].size(); ++i) {
223  //convert total energy keV->MIP, since converted to keV in accumulator
224  const float totalIniMIPs(cell.hit_info[0][i] * keV2MIP_);
225 
226  //generate random number of photon electrons
227  const uint32_t npe = std::floor(CLHEP::RandPoissonQ::shoot(engine, totalIniMIPs * nPEperMIP_));
228 
229  //number of pixels
230  const float x = vdt::fast_expf(-((float)npe) / nTotalPE_);
231  uint32_t nPixel(0);
232  if (xTalk_ * x != 1)
233  nPixel = (uint32_t)std::max(nTotalPE_ * (1.f - x) / (1.f - xTalk_ * x), 0.f);
234 
235  //update signal
236  if (sdPixels_ != 0)
237  nPixel = (uint32_t)std::max(CLHEP::RandGaussQ::shoot(engine, (double)nPixel, sdPixels_), 0.);
238 
239  //convert to MIP again and saturate
240  float totalMIPs(0.f), xtalk = 0.f;
241  const float peDiff = nTotalPE_ - (float)nPixel;
242  if (peDiff != 0.f) {
243  xtalk = (nTotalPE_ - xTalk_ * ((float)nPixel)) / peDiff;
244  if (xtalk > 0.f && nPEperMIP_ != 0.f)
245  totalMIPs = (nTotalPE_ / nPEperMIP_) * vdt::fast_logf(xtalk);
246  }
247 
248  //add noise (in MIPs)
249  chargeColl[i] = totalMIPs;
250  if (noise_MIP_ != 0)
251  chargeColl[i] += std::max(CLHEP::RandGaussQ::shoot(engine, 0., noise_MIP_), 0.);
252  if (debug && cell.hit_info[0][i] > 0)
253  edm::LogVerbatim("HGCDigitizer") << "[runCaliceLikeDigitizer] xtalk=" << xtalk << " En=" << cell.hit_info[0][i]
254  << " keV -> " << totalIniMIPs << " raw-MIPs -> " << chargeColl[i]
255  << " digi-MIPs";
256  }
257 
258  //init a new data frame and run shaper
259  HGCalDataFrame newDataFrame(id);
260  this->myFEelectronics_->runShaper(newDataFrame, chargeColl, toa, engine);
261 
262  //prepare the output
263  this->updateOutput(digiColl, newDataFrame);
264  }
265 }
266 
267 //
HGCAL_noise_fC_cfi.scaleByDoseAlgo
scaleByDoseAlgo
Definition: HGCAL_noise_fC_cfi.py:6
HGCHEbackDigitizer::doseMapFile_
std::string doseMapFile_
Definition: HGCHEbackDigitizer.h:26
DigiToRawDM_cff.digiColl
digiColl
Definition: DigiToRawDM_cff.py:32
radiiVec
std::array< double, 8 > radiiVec
Definition: HGCalRadiationMap.h:10
mps_fire.i
i
Definition: mps_fire.py:355
dqmMemoryStats.float
float
Definition: dqmMemoryStats.py:127
HGCHEbackDigitizer::thresholdFollowsMIP_
bool thresholdFollowsMIP_
Definition: HGCHEbackDigitizer.h:23
HGCHEbackDigitizer::scaleBySipmArea_
bool scaleBySipmArea_
Definition: HGCHEbackDigitizer.h:23
HGCHEbackDigitizer::scal_
HGCalSciNoiseMap scal_
Definition: HGCHEbackDigitizer.h:27
f
double f[11][100]
Definition: MuScleFitUtils.cc:78
HGCalSciNoiseMap::scaleBySipmArea
double scaleBySipmArea(const HGCScintillatorDetId &, const double &)
Definition: HGCalSciNoiseMap.cc:76
HGCHEbackDigitizer::runRealisticDigitizer
void runRealisticDigitizer(std::unique_ptr< HGCalDigiCollection > &digiColl, hgc::HGCSimHitDataAccumulator &simData, const CaloSubdetectorGeometry *theGeom, const std::unordered_set< DetId > &validIds, CLHEP::HepRandomEngine *engine)
Definition: HGCHEbackDigitizer.cc:87
HGCHEbackDigitizer.h
HGCalRadiationMap::setGeometry
void setGeometry(const CaloSubdetectorGeometry *)
Definition: HGCalRadiationMap.cc:12
DDAxes::x
HGCHEbackDigitizer::noise_MIP_
float noise_MIP_
Definition: HGCHEbackDigitizer.h:24
hgc_digi_utils
Definition: HGCDigitizerBase.h:28
HcalGeometry.h
hgc_digi
Definition: HGCDigitizerTypes.h:10
HGCHEbackDigitizer::sdPixels_
float sdPixels_
Definition: HGCHEbackDigitizer.h:25
HGCHEbackDigitizer::runCaliceLikeDigitizer
void runCaliceLikeDigitizer(std::unique_ptr< HGCalDigiCollection > &digiColl, hgc::HGCSimHitDataAccumulator &simData, const CaloSubdetectorGeometry *theGeom, const std::unordered_set< DetId > &validIds, CLHEP::HepRandomEngine *engine)
Definition: HGCHEbackDigitizer.cc:201
debug
#define debug
Definition: HDRShower.cc:19
hgceeDigitizer_cfi.digitizationType
digitizationType
Definition: hgceeDigitizer_cfi.py:54
myMath::fast_expf
float fast_expf(float x)
Definition: EcalUncalibRecHitRatioMethodAlgo.h:27
hgc_digi_utils::addCellMetadata
void addCellMetadata(HGCCellInfo &info, const HcalGeometry *geom, const DetId &detid)
Definition: HGCDigitizerBase.h:31
HGCHEbackDigitizer::sipmMapFile_
std::string sipmMapFile_
Definition: HGCHEbackDigitizer.h:26
myMath::fast_logf
float fast_logf(float x)
Definition: EcalUncalibRecHitRatioMethodAlgo.h:28
mathSSE::sqrt
T sqrt(T t)
Definition: SSEVec.h:19
HGCHEbackDigitizer::runDigitizer
void runDigitizer(std::unique_ptr< HGCalDigiCollection > &digiColl, hgc::HGCSimHitDataAccumulator &simData, const CaloSubdetectorGeometry *theGeom, const std::unordered_set< DetId > &validIds, uint32_t digitizationType, CLHEP::HepRandomEngine *engine) override
to be specialized by top class
Definition: HGCHEbackDigitizer.cc:38
HGCHEbackDigitizer::algo_
uint32_t algo_
Definition: HGCHEbackDigitizer.h:22
hgc_digi::HGCSimHitData
std::array< HGCSimData_t, nSamples > HGCSimHitData
Definition: HGCDigitizerTypes.h:17
HGCDigitizerBase< HGCalDataFrame >::updateOutput
void updateOutput(std::unique_ptr< DColl > &coll, const HGCalDataFrame &rawDataFrame)
prepares the output according to the number of time samples to produce
Definition: HGCDigitizerBase.cc:179
HGCFEElectronics
models the behavior of the front-end electronics
Definition: HGCFEElectronics.h:20
HGCHEbackDigitizer::scaleByTileArea_
bool scaleByTileArea_
Definition: HGCHEbackDigitizer.h:23
HGCHEbackDigitizer::xTalk_
float xTalk_
Definition: HGCHEbackDigitizer.h:25
AlCaHLTBitMon_QueryRunRegistry.string
string
Definition: AlCaHLTBitMon_QueryRunRegistry.py:256
hgc_digi::HGCCellInfo
Definition: HGCDigitizerTypes.h:31
HGCDigitizerBase< HGCalDataFrame >::keV2fC_
float keV2fC_
Definition: HGCDigitizerBase.h:129
HGCalSciNoiseMap::setSipmMap
void setSipmMap(const std::string &)
Definition: HGCalSciNoiseMap.cc:9
HGCalSciNoiseMap::scaleByDose
std::pair< double, double > scaleByDose(const HGCScintillatorDetId &, const radiiVec &)
Definition: HGCalSciNoiseMap.cc:38
HGCalGeometry.h
LogDebug
#define LogDebug(id)
Definition: MessageLogger.h:670
HGCHEbackDigitizer::~HGCHEbackDigitizer
~HGCHEbackDigitizer() override
Definition: HGCHEbackDigitizer.cc:268
edm::ParameterSet
Definition: ParameterSet.h:36
SiStripPI::max
Definition: SiStripPayloadInspectorHelper.h:169
HGCHEbackDigitizer::HGCHEbackDigitizer
HGCHEbackDigitizer(const edm::ParameterSet &ps)
Definition: HGCHEbackDigitizer.cc:15
HGCalRadiationMap::setDoseMap
void setDoseMap(const std::string &, const unsigned int)
Definition: HGCalRadiationMap.cc:6
HGCDataFrame
Readout digi for HGC.
Definition: HGCDataFrame.h:14
hgc_digi::HGCCellInfo::hit_info
std::array< HGCSimHitData, 2 > hit_info
Definition: HGCDigitizerTypes.h:33
edm::LogVerbatim
Definition: MessageLogger.h:297
HGCalSciNoiseMap::computeRadius
radiiVec computeRadius(const HGCScintillatorDetId &)
Definition: HGCalSciNoiseMap.cc:87
hgc_digi::HGCSimHitDataAccumulator
std::unordered_map< uint32_t, HGCCellInfo > HGCSimHitDataAccumulator
Definition: HGCDigitizerTypes.h:38
looper.cfg
cfg
Definition: looper.py:297
edm::ParameterSet::getParameter
T getParameter(std::string const &) const
HGCalSciNoiseMap::scaleByTileArea
double scaleByTileArea(const HGCScintillatorDetId &, const radiiVec &)
returns the signal scaling and the noise
Definition: HGCalSciNoiseMap.cc:61
HGCHEbackDigitizer::nPEperMIP_
float nPEperMIP_
Definition: HGCHEbackDigitizer.h:25
HGCDigitizerBase
Definition: HGCDigitizerBase.h:61
DetId::HGCalHSc
Definition: DetId.h:34
HGCHEbackDigitizer::nTotalPE_
float nTotalPE_
Definition: HGCHEbackDigitizer.h:25
CosmicsPD_Skims.radius
radius
Definition: CosmicsPD_Skims.py:135
or
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
CaloSubdetectorGeometry
Definition: CaloSubdetectorGeometry.h:22
HGCHEbackDigitizer::scaleByDose_
bool scaleByDose_
Definition: HGCHEbackDigitizer.h:23
funct::pow
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:30
HGCHEbackDigitizer::keV2MIP_
float keV2MIP_
Definition: HGCHEbackDigitizer.h:24
HGCHEbackDigitizer::runEmptyDigitizer
void runEmptyDigitizer(std::unique_ptr< HGCalDigiCollection > &digiColl, hgc::HGCSimHitDataAccumulator &simData, const CaloSubdetectorGeometry *theGeom, const std::unordered_set< DetId > &validIds, CLHEP::HepRandomEngine *engine)
Definition: HGCHEbackDigitizer.cc:52
HGCDigitizerBase< HGCalDataFrame >::myFEelectronics_
std::unique_ptr< HGCFEElectronics< HGCalDataFrame > > myFEelectronics_
Definition: HGCDigitizerBase.h:147