CMS 3D CMS Logo

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