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