LDMX Software
hcal::HcalDigiProducer Class Reference

Performs basic HCal digitization. More...

#include <HcalDigiProducer.h>

Public Member Functions

 HcalDigiProducer (const std::string &name, framework::Process &process)
 Constructor Makes unique noise generator and injector for this class.
 
virtual ~HcalDigiProducer ()=default
 Default destructor.
 
void configure (framework::config::Parameters &) override
 Configure this producer from the python configuration.
 
void produce (framework::Event &event) override
 Simulates measurement of pulse and creates digi collection for input event.
 
virtual void onNewRun (const ldmx::RunHeader &runHeader) override
 Random number generation.
 
- Public Member Functions inherited from framework::Producer
 Producer (const std::string &name, Process &process)
 Class constructor.
 
virtual void beforeNewRun (ldmx::RunHeader &header)
 Handle allowing producers to modify run headers before the run begins.
 
- Public Member Functions inherited from framework::EventProcessor
 EventProcessor (const std::string &name, Process &process)
 Class constructor.
 
virtual ~EventProcessor ()
 Class destructor.
 
virtual void onFileOpen (EventFile &eventFile)
 Callback for the EventProcessor to take any necessary action when a new event input ROOT file is opened.
 
virtual void onFileClose (EventFile &eventFile)
 Callback for the EventProcessor to take any necessary action when a event input ROOT file is closed.
 
virtual void onProcessStart ()
 Callback for the EventProcessor to take any necessary action when the processing of events starts, such as creating histograms.
 
virtual void onProcessEnd ()
 Callback for the EventProcessor to take any necessary action when the processing of events finishes, such as calculating job-summary quantities.
 
template<class T >
const T & getCondition (const std::string &condition_name)
 Access a conditions object for the current event.
 
TDirectory * getHistoDirectory ()
 Access/create a directory in the histogram file for this event processor to create histograms and analysis tuples.
 
void setStorageHint (framework::StorageControl::Hint hint)
 Mark the current event as having the given storage control hint from this module.
 
void setStorageHint (framework::StorageControl::Hint hint, const std::string &purposeString)
 Mark the current event as having the given storage control hint from this module and the given purpose string.
 
int getLogFrequency () const
 Get the current logging frequency from the process.
 
int getRunNumber () const
 Get the run number from the process.
 
std::string getName () const
 Get the processor name.
 
void createHistograms (const std::vector< framework::config::Parameters > &histos)
 Internal function which is used to create histograms passed from the python configuration @parma histos vector of Parameters that configure histograms to create.
 

Private Attributes

std::string inputCollName_
 input hit collection name
 
std::string inputPassName_
 input pass name
 
std::string digiCollName_
 output hit collection name
 
double clockCycle_
 Time interval for chip clock in ns.
 
int nADCs_
 Depth of ADC buffer.
 
int iSOI_
 Index for the Sample Of Interest in the list of digi samples.
 
double MeV_
 Conversion from energy in MeV to voltage in mV.
 
double attlength_
 Strip attenuation length [m].
 
bool noise_ {true}
 Put noise into empty channels, not configurable, only helpful in development.
 
bool zeroSuppression_ {true}
 If false, save digis from all channels, even pure noise in empty bars Helpful when comparing with test beam data.
 
std::unique_ptr< ldmx::HgcrocEmulatorhgcroc_
 Hgcroc Emulator to digitize analog voltage signals.
 
double ns_
 Conversion from time in ns to ticks of the internal clock.
 
double readoutThreshold_
 Read out threshold.
 
double pedestal_
 Read out pedestal.
 
double gain_
 Read out gain.
 
double noiseRMS_
 Noise RMS.
 
std::unique_ptr< ldmx::NoiseGeneratornoiseGenerator_
 Generates noise hits based off of number of cells that are not hit.
 
std::mt19937 rng_
 Generates Gaussian noise on top of real hits.
 

Additional Inherited Members

- Static Public Member Functions inherited from framework::EventProcessor
static void declare (const std::string &classname, int classtype, EventProcessorMaker *)
 Internal function which is part of the PluginFactory machinery.
 
- Static Public Attributes inherited from framework::Producer
static const int CLASSTYPE {1}
 Constant used to track EventProcessor types by the PluginFactory.
 
- Protected Member Functions inherited from framework::EventProcessor
void abortEvent ()
 Abort the event immediately.
 
- Protected Attributes inherited from framework::EventProcessor
HistogramHelper histograms_
 Interface class for making and filling histograms.
 
NtupleManagerntuple_ {NtupleManager::getInstance()}
 Manager for any ntuples.
 
logging::logger theLog_
 The logger for this EventProcessor.
 

Detailed Description

Performs basic HCal digitization.

Definition at line 31 of file HcalDigiProducer.h.

Constructor & Destructor Documentation

◆ HcalDigiProducer()

hcal::HcalDigiProducer::HcalDigiProducer ( const std::string & name,
framework::Process & process )

Constructor Makes unique noise generator and injector for this class.

Definition at line 14 of file HcalDigiProducer.cxx.

16 : Producer(name, process) {
17 /*
18 * Noise generator by default uses a Gausian model for noise
19 * i.e. It assumes the noise is distributed around a mean (setPedestal)
20 * with a certain RMS (setNoise) and then calculates
21 * how many hits should be generated for a given number of empty
22 * channels and a minimum readout value (setNoiseThreshold)
23 */
24 noiseGenerator_ = std::make_unique<ldmx::NoiseGenerator>();
25}
Producer(const std::string &name, Process &process)
Class constructor.
std::unique_ptr< ldmx::NoiseGenerator > noiseGenerator_
Generates noise hits based off of number of cells that are not hit.

References noiseGenerator_.

Member Function Documentation

◆ configure()

void hcal::HcalDigiProducer::configure ( framework::config::Parameters & ps)
overridevirtual

Configure this producer from the python configuration.

Sets event constants and configures the noise generator, noise injector, and pulse function. Creates digi collection

Reimplemented from framework::EventProcessor.

Definition at line 27 of file HcalDigiProducer.cxx.

27 {
28 // settings of readout chip
29 // used in actual digitization
30 auto hgcrocParams = ps.getParameter<framework::config::Parameters>("hgcroc");
31 hgcroc_ = std::make_unique<ldmx::HgcrocEmulator>(hgcrocParams);
32 clockCycle_ = hgcrocParams.getParameter<double>("clockCycle");
33 nADCs_ = hgcrocParams.getParameter<int>("nADCs");
34 iSOI_ = hgcrocParams.getParameter<int>("iSOI");
35 noise_ = hgcrocParams.getParameter<bool>("noise");
36
37 // If true, ignore readout threshold
38 // and generate pedestal noise digis in every empty channel
39 zeroSuppression_ = ps.getParameter<bool>("zeroSuppression");
40
41 // collection names
42 inputCollName_ = ps.getParameter<std::string>("inputCollName");
43 inputPassName_ = ps.getParameter<std::string>("inputPassName");
44 digiCollName_ = ps.getParameter<std::string>("digiCollName");
45
46 // physical constants
47 // used to calculate unit conversions
48 MeV_ = ps.getParameter<double>("MeV");
49 attlength_ = ps.getParameter<double>("attenuationLength");
50
51 // Time -> clock counts conversion
52 // time [ns] * ( 2^10 / max time in ns ) = clock counts
53 ns_ = 1024. / clockCycle_;
54
55 // Configure generator that will produce noise hits in empty channels
56 gain_ = ps.getParameter<double>("avgGain");
57 readoutThreshold_ = ps.getParameter<double>("avgReadoutThreshold");
58 pedestal_ = ps.getParameter<double>("avgPedestal");
59 noiseRMS_ = ps.getParameter<double>("avgNoiseRMS");
60}
Class encapsulating parameters for configuring a processor.
Definition Parameters.h:29
bool noise_
Put noise into empty channels, not configurable, only helpful in development.
double gain_
Read out gain.
double attlength_
Strip attenuation length [m].
std::string digiCollName_
output hit collection name
bool zeroSuppression_
If false, save digis from all channels, even pure noise in empty bars Helpful when comparing with tes...
double ns_
Conversion from time in ns to ticks of the internal clock.
int nADCs_
Depth of ADC buffer.
double MeV_
Conversion from energy in MeV to voltage in mV.
std::unique_ptr< ldmx::HgcrocEmulator > hgcroc_
Hgcroc Emulator to digitize analog voltage signals.
std::string inputCollName_
input hit collection name
double readoutThreshold_
Read out threshold.
double clockCycle_
Time interval for chip clock in ns.
std::string inputPassName_
input pass name
int iSOI_
Index for the Sample Of Interest in the list of digi samples.
double pedestal_
Read out pedestal.
double noiseRMS_
Noise RMS.

References attlength_, clockCycle_, digiCollName_, gain_, hgcroc_, inputCollName_, inputPassName_, iSOI_, MeV_, nADCs_, noise_, noiseRMS_, ns_, pedestal_, readoutThreshold_, and zeroSuppression_.

◆ onNewRun()

void hcal::HcalDigiProducer::onNewRun ( const ldmx::RunHeader & runHeader)
overridevirtual

Random number generation.

Reimplemented from framework::EventProcessor.

Definition at line 62 of file HcalDigiProducer.cxx.

62 {
63 // rms noise in mV
64 noiseGenerator_->setNoise(gain_ * noiseRMS_);
65 // mean noise amplitude (if using Gaussian Model for the noise) in mV
66 noiseGenerator_->setPedestal(gain_ * pedestal_);
67 // threshold for readout in mV
68 noiseGenerator_->setNoiseThreshold(gain_ * readoutThreshold_);
69
70 // Set up seeds
73 noiseGenerator_->seedGenerator(
74 rseed.getSeed("HcalDigiProducer::NoiseGenerator"));
75
76 // Random number generator for layer / module / cell
77 rng_.seed(rseed.getSeed("HcalDigiProducer"));
78 // Setting up the read-out chip
79 hgcroc_->seedGenerator(rseed.getSeed("HcalDigiProducer::HgcrocEmulator"));
80}
const T & getCondition(const std::string &condition_name)
Access a conditions object for the current event.
static const std::string CONDITIONS_OBJECT_NAME
Conditions object name.
std::mt19937 rng_
Generates Gaussian noise on top of real hits.

References framework::RandomNumberSeedService::CONDITIONS_OBJECT_NAME, gain_, framework::EventProcessor::getCondition(), hgcroc_, noiseGenerator_, noiseRMS_, pedestal_, readoutThreshold_, and rng_.

◆ produce()

void hcal::HcalDigiProducer::produce ( framework::Event & event)
overridevirtual

Simulates measurement of pulse and creates digi collection for input event.

Define two pulses: with positive and negative ends. For this we need to: (1) Find the position along the bar: For back Hcal: x (y) for horizontal (vertical) layers. For side Hcal: x (top,bottom) and y (left,right).

(2) Define the end of the bar: The end of an HcalDigiID is based on its distance (x,y) along the bar.

  • A positive end (endID=0), corresponds to top,left.
  • A negative end (endID=1), corresponds to bottom,right. For back Hcal:
  • if the position along the bar > 0, the close pulse's end is 0, else 1. For side Hcal:
  • if the position along the bar > half_width point of the bar, the close pulse's end is 0, else 1. The far pulse's end will be opposite to the close pulse's end.

(3) Find the distance to each end (positive and negative) from the origin. For the back Hcal, the half point of the bar coincides with the coordinates of the origin. For the side Hcal, the length of the bar from the origin is:

  • 2 *(half_width) - Ecal_dx(y)/2 away from the positive end, and,
  • Ecal_dx(y) away from the negative end.

Now we have all the sub-hits from all the simhits Digitize: For back Hcal return two digis. For side Hcal we choose which pulse to readout based on the position of the hit and the sub-section. For Top and Left we read the positive end digi. For Bottom and Right we read the negative end digi.

Implements framework::Producer.

Definition at line 82 of file HcalDigiProducer.cxx.

82 {
83 // Get the Hgcroc Conditions
84 hgcroc_->condition(
86
87 // Get the Hcal Geometry
88 const auto& hcalGeometry = getCondition<ldmx::HcalGeometry>(
90
91 // Empty collection to be filled
95
96 std::map<unsigned int, std::vector<const ldmx::SimCalorimeterHit*>> hitsByID;
97
98 // get simulated hcal hits from Geant4 and group them by id
99 auto hcalSimHits{event.getCollection<ldmx::SimCalorimeterHit>(
101
102 for (auto const& simHit : hcalSimHits) {
103 // get ID
104 unsigned int hitID = simHit.getID();
105
106 auto idh = hitsByID.find(hitID);
107 if (idh == hitsByID.end()) {
108 hitsByID[hitID] = std::vector<const ldmx::SimCalorimeterHit*>(1, &simHit);
109 } else {
110 idh->second.push_back(&simHit);
111 }
112 }
113
114 /******************************************************************************************
115 * HGCROC Emulation on Simulated Hits (grouped by HcalID)
116 ******************************************************************************************/
117 for (auto const& simBar : hitsByID) {
118 ldmx::HcalID detID(simBar.first);
119 int section = detID.section();
120 int layer = detID.layer();
121 int strip = detID.strip();
122
123 // get position
124 double half_total_width = hcalGeometry.getHalfTotalWidth(section, layer);
125 double ecal_dx = hcalGeometry.getEcalDx();
126 double ecal_dy = hcalGeometry.getEcalDy();
127
128 // contributions
129 std::vector<std::pair<double, double>> pulses_posend;
130 std::vector<std::pair<double, double>> pulses_negend;
131
132 for (auto psimHit : simBar.second) {
133 const ldmx::SimCalorimeterHit& simHit = *psimHit;
134
135 std::vector<float> position = simHit.getPosition();
136
165 float distance_along_bar, distance_ecal;
166 float distance_close, distance_far;
167 int end_close;
168 const auto orientation{hcalGeometry.getScintillatorOrientation(detID)};
169 if (section == ldmx::HcalID::HcalSection::BACK) {
170 distance_along_bar =
171 (orientation ==
172 ldmx::HcalGeometry::ScintillatorOrientation::horizontal)
173 ? position[0]
174 : position[1];
175 end_close = (distance_along_bar > 0) ? 0 : 1;
176 distance_close = half_total_width;
177 distance_far = half_total_width;
178 } else {
179 if ((section == ldmx::HcalID::HcalSection::TOP) ||
180 ((section == ldmx::HcalID::HcalSection::BOTTOM))) {
181 distance_along_bar = position[0];
182 distance_ecal = ecal_dx;
183 } else if ((section == ldmx::HcalID::HcalSection::LEFT) ||
184 (section == ldmx::HcalID::HcalSection::RIGHT)) {
185 distance_along_bar = position[1];
186 distance_ecal = ecal_dy;
187 } else {
188 distance_along_bar = -9999.;
189 EXCEPTION_RAISE(
190 "BadCode",
191 "We should never end up here "
192 "All cases of HCAL considered, end_close is meaningless");
193 }
194 end_close = (distance_along_bar > half_total_width) ? 0 : 1;
195 distance_close = (end_close == 0)
196 ? 2 * half_total_width - distance_ecal / 2
197 : distance_ecal / 2;
198 distance_far = (end_close == 0)
199 ? distance_ecal / 2
200 : 2 * half_total_width - distance_ecal / 2;
201 }
202
203 // Calculate voltage attenuation and time shift for the close and far
204 // pulse.
205 // velocity of light in Polystyrene, n = 1.6 = c/v mm/ns
206 float v = 299.792 / 1.6;
207 double att_close =
208 exp(-1. * ((distance_close - fabs(distance_along_bar)) / 1000.) /
209 attlength_);
210 double att_far =
211 exp(-1. * ((distance_far + fabs(distance_along_bar)) / 1000.) /
212 attlength_);
213 double shift_close =
214 fabs((distance_close - fabs(distance_along_bar)) / v);
215 double shift_far = fabs((distance_far + fabs(distance_along_bar)) / v);
216
217 // Get voltages and times.
218 for (int iContrib = 0; iContrib < simHit.getNumberOfContribs();
219 iContrib++) {
220 double voltage = simHit.getContrib(iContrib).edep * MeV_;
221 // global time (t=0ns at target)
222 double time = simHit.getContrib(iContrib).time;
223 // shift light-speed particle traveling along z
224 time -= position.at(2) / 299.702547;
225
226 if (end_close == 0) {
227 pulses_posend.emplace_back(voltage * att_close, time + shift_close);
228 pulses_negend.emplace_back(voltage * att_far, time + shift_far);
229 } else {
230 pulses_posend.emplace_back(voltage * att_far, time + shift_far);
231 pulses_negend.emplace_back(voltage * att_close, time + shift_close);
232 }
233 }
234 }
235
245 if (section == ldmx::HcalID::HcalSection::BACK) {
246 std::vector<ldmx::HgcrocDigiCollection::Sample> digiToAddPosend,
247 digiToAddNegend;
248 ldmx::HcalDigiID posendID(section, layer, strip, 0);
249 ldmx::HcalDigiID negendID(section, layer, strip, 1);
250
251 bool posEndActivity =
252 hgcroc_->digitize(posendID.raw(), pulses_posend, digiToAddPosend);
253 bool negEndActivity =
254 hgcroc_->digitize(negendID.raw(), pulses_negend, digiToAddNegend);
255
256 if (posEndActivity && negEndActivity && zeroSuppression_) {
257 hcalDigis.addDigi(posendID.raw(), digiToAddPosend);
258 hcalDigis.addDigi(negendID.raw(), digiToAddNegend);
259 } // If zeroSuppression == true, Back Hcal needs to digitize both
260 // pulses or none
261
262 if (!zeroSuppression_) {
263 if (posEndActivity) {
264 hcalDigis.addDigi(posendID.raw(), digiToAddPosend);
265 } else {
266 std::vector<ldmx::HgcrocDigiCollection::Sample> digi =
267 hgcroc_->noiseDigi(posendID.raw(), 0.0);
268 hcalDigis.addDigi(posendID.raw(), digi);
269 }
270 if (negEndActivity) {
271 hcalDigis.addDigi(negendID.raw(), digiToAddNegend);
272 } else {
273 std::vector<ldmx::HgcrocDigiCollection::Sample> digi =
274 hgcroc_->noiseDigi(negendID.raw(), 0.0);
275 hcalDigis.addDigi(negendID.raw(), digi);
276 }
277 }
278
279 } else {
280 bool is_posend = false;
281 std::vector<ldmx::HgcrocDigiCollection::Sample> digiToAdd;
282 if ((section == ldmx::HcalID::HcalSection::TOP) ||
283 (section == ldmx::HcalID::HcalSection::LEFT)) {
284 is_posend = true;
285 } else if ((section == ldmx::HcalID::HcalSection::BOTTOM) ||
286 (section == ldmx::HcalID::HcalSection::RIGHT)) {
287 is_posend = false;
288 }
289 if (is_posend) {
290 ldmx::HcalDigiID digiID(section, layer, strip, 0);
291 if (hgcroc_->digitize(digiID.raw(), pulses_posend, digiToAdd)) {
292 hcalDigis.addDigi(digiID.raw(), digiToAdd);
293 } else if (!zeroSuppression_) {
294 std::vector<ldmx::HgcrocDigiCollection::Sample> digi =
295 hgcroc_->noiseDigi(digiID.raw(), 0.0);
296 hcalDigis.addDigi(digiID.raw(), digi);
297 }
298 } else {
299 ldmx::HcalDigiID digiID(section, layer, strip, 1);
300 if (hgcroc_->digitize(digiID.raw(), pulses_negend, digiToAdd)) {
301 hcalDigis.addDigi(digiID.raw(), digiToAdd);
302 } else if (!zeroSuppression_) {
303 std::vector<ldmx::HgcrocDigiCollection::Sample> digi =
304 hgcroc_->noiseDigi(digiID.raw(), 0.0);
305 hcalDigis.addDigi(digiID.raw(), digi);
306 }
307 }
308 }
309 }
310
311 /******************************************************************************************
312 * Noise Simulation on Empty Channels
313 *****************************************************************************************/
314 if (noise_) {
315 std::vector<ldmx::HcalDigiID> channelMap;
316 int numChannels = 0;
317 for (int section = 0; section < hcalGeometry.getNumSections(); section++) {
318 for (int layer = 1; layer <= hcalGeometry.getNumLayers(section);
319 layer++) {
320 // Note zero-indexed strip numbering...
321 for (int strip = 0; strip < hcalGeometry.getNumStrips(section, layer);
322 strip++) {
323 if (section == ldmx::HcalID::HcalSection::BACK) {
324 auto digiIDend0 = ldmx::HcalDigiID(section, layer, strip, 0);
325 auto digiIDend1 = ldmx::HcalDigiID(section, layer, strip, 1);
326 channelMap.push_back(digiIDend0);
327 channelMap.push_back(digiIDend1);
328 numChannels += 2;
329 } else {
330 auto digiID = ldmx::HcalDigiID(section, layer, strip, 0);
331 channelMap.push_back(digiID);
332 numChannels++;
333 }
334 }
335 }
336 }
337
338 // Uniform distributions for integer generation
339 std::uniform_int_distribution<int> section_dist(
340 0, hcalGeometry.getNumSections() - 1);
341 std::uniform_int_distribution<int> end_dist(0, 1);
342 std::uniform_int_distribution<int> clock_dist(0, clockCycle_);
343
344 // Fast noise sim
345 if (zeroSuppression_) {
346 int numEmptyChannels = numChannels - hcalDigis.getNumDigis();
347 // noise generator gives us a list of noise amplitudes [mV] that randomly
348 // populate the empty channels and are above the readout threshold
349 auto noiseHitAmplitudes{
350 noiseGenerator_->generateNoiseHits(numEmptyChannels)};
351 std::vector<std::pair<double, double>> fake_pulse(1, {0., 0.});
352
353 for (double noiseHit : noiseHitAmplitudes) {
354 // generate detector ID for noise hit
355 // making sure that it is in an empty channel
356 unsigned int noiseID;
357 int sectionID, layerID, stripID, endID;
358 do {
359 // Get a random section value
360 sectionID = section_dist(rng_);
361
362 // Get a random value for the layer
363 std::uniform_int_distribution<int> layer_dist(
364 0, hcalGeometry.getNumLayers(sectionID) - 1);
365 layerID = layer_dist(rng_);
366 // set layer to 1 if the generator says it is 0 (geometry map starts
367 // from 1)
368 if (layerID == 0) layerID = 1;
369
370 // Get a random value for the strip
371 std::uniform_int_distribution<int> strips_dist(
372 0, hcalGeometry.getNumStrips(sectionID, layerID) - 1);
373 stripID = strips_dist(rng_);
374
375 // Get a random value for the end
376 if ((sectionID == ldmx::HcalID::HcalSection::TOP) ||
377 (sectionID == ldmx::HcalID::HcalSection::LEFT)) {
378 endID = 0;
379 } else if ((sectionID == ldmx::HcalID::HcalSection::BOTTOM) ||
380 (sectionID == ldmx::HcalID::HcalSection::RIGHT)) {
381 endID = 1;
382 } else {
383 endID = end_dist(rng_);
384 }
385 auto detID = ldmx::HcalDigiID(sectionID, layerID, stripID, endID);
386 noiseID = detID.raw();
387 } while (hitsByID.find(noiseID) != hitsByID.end());
388 hitsByID[noiseID] =
389 std::vector<const ldmx::SimCalorimeterHit*>(); // mark this as used
390
391 // get a time for this noise hit
392 fake_pulse[0].second = clock_dist(rng_);
393
394 // noise generator gives the amplitude above the readout threshold
395 // we need to convert it to the amplitude above the pedestal
396 double gain = hgcroc_->gain(noiseID);
397 fake_pulse[0].first = noiseHit +
398 gain * hgcroc_->readoutThreshold(noiseID) -
399 gain * hgcroc_->pedestal(noiseID);
400
401 if (sectionID == ldmx::HcalID::HcalSection::BACK) {
402 std::vector<ldmx::HgcrocDigiCollection::Sample> digiToAddPosend,
403 digiToAddNegend;
404 ldmx::HcalDigiID posendID(sectionID, layerID, stripID, 0);
405 ldmx::HcalDigiID negendID(sectionID, layerID, stripID, 1);
406 if (hgcroc_->digitize(posendID.raw(), fake_pulse, digiToAddPosend) &&
407 hgcroc_->digitize(negendID.raw(), fake_pulse, digiToAddNegend)) {
408 hcalDigis.addDigi(posendID.raw(), digiToAddPosend);
409 hcalDigis.addDigi(negendID.raw(), digiToAddNegend);
410 }
411 } else {
412 std::vector<ldmx::HgcrocDigiCollection::Sample> digiToAdd;
413 if (hgcroc_->digitize(noiseID, fake_pulse, digiToAdd)) {
414 hcalDigis.addDigi(noiseID, digiToAdd);
415 }
416 }
417 } // loop over noise amplitudes
418 } else { // If zeroSuppression_ == false, add noise digis for all bars
419 // without simhits
420 for (auto digiID : channelMap) {
421 // Convert from digi ID to det ID (since simhits don't know about
422 // different ends of the bar)
423 ldmx::HcalID detid(digiID.section(), digiID.layer(), digiID.strip());
424 unsigned int rawdetID = detid.raw();
425 if (hitsByID.find(rawdetID) == hitsByID.end()) {
426 std::vector<ldmx::HgcrocDigiCollection::Sample> digi =
427 hgcroc_->noiseDigi(digiID.raw(), 0.0);
428 hcalDigis.addDigi(digiID.raw(), digi);
429 }
430 }
431 }
432 } // if we should add noise
433
434 event.add(digiCollName_, hcalDigis);
435
436 return;
437} // produce
Extension of HcalAbstractID providing access to HCal digi information.
Definition HcalDigiID.h:13
static constexpr const char * CONDITIONS_OBJECT_NAME
Conditions object: The name of the python configuration calling this class (Hcal/python/HcalGeometry....
Implements detector ids for HCal subdetector.
Definition HcalID.h:19
Represents a collection of the digi hits readout by an HGCROC.
void setNumSamplesPerDigi(unsigned int n)
Set number of samples for each digi.
void setSampleOfInterestIndex(unsigned int n)
Set index of sample of interest.
void addDigi(unsigned int id, const std::vector< Sample > &digi)
Add samples to collection.
unsigned int getNumDigis() const
Get total number of digis.
Stores simulated calorimeter hit information.
unsigned getNumberOfContribs() const
Get the number of hit contributions.
Contrib getContrib(int i) const
Get a hit contribution by index.
std::vector< float > getPosition() const
Get the XYZ position of the hit [mm].
float time
Time this contributor made the hit (global Geant4 time)
float edep
Energy depostied by this contributor.

References ldmx::HgcrocDigiCollection::addDigi(), attlength_, clockCycle_, ldmx::HcalGeometry::CONDITIONS_OBJECT_NAME, digiCollName_, ldmx::SimCalorimeterHit::Contrib::edep, framework::EventProcessor::getCondition(), ldmx::SimCalorimeterHit::getContrib(), ldmx::SimCalorimeterHit::getNumberOfContribs(), ldmx::HgcrocDigiCollection::getNumDigis(), ldmx::SimCalorimeterHit::getPosition(), hgcroc_, inputCollName_, inputPassName_, iSOI_, ldmx::HcalID::layer(), MeV_, nADCs_, noise_, noiseGenerator_, ldmx::DetectorID::raw(), rng_, ldmx::HgcrocDigiCollection::setNumSamplesPerDigi(), ldmx::HgcrocDigiCollection::setSampleOfInterestIndex(), ldmx::HcalID::strip(), ldmx::SimCalorimeterHit::Contrib::time, and zeroSuppression_.

Member Data Documentation

◆ attlength_

double hcal::HcalDigiProducer::attlength_
private

Strip attenuation length [m].

Definition at line 85 of file HcalDigiProducer.h.

Referenced by configure(), and produce().

◆ clockCycle_

double hcal::HcalDigiProducer::clockCycle_
private

Time interval for chip clock in ns.

Definition at line 73 of file HcalDigiProducer.h.

Referenced by configure(), and produce().

◆ digiCollName_

std::string hcal::HcalDigiProducer::digiCollName_
private

output hit collection name

Definition at line 70 of file HcalDigiProducer.h.

Referenced by configure(), and produce().

◆ gain_

double hcal::HcalDigiProducer::gain_
private

Read out gain.

Definition at line 109 of file HcalDigiProducer.h.

Referenced by configure(), and onNewRun().

◆ hgcroc_

std::unique_ptr<ldmx::HgcrocEmulator> hcal::HcalDigiProducer::hgcroc_
private

Hgcroc Emulator to digitize analog voltage signals.

Definition at line 99 of file HcalDigiProducer.h.

Referenced by configure(), onNewRun(), and produce().

◆ inputCollName_

std::string hcal::HcalDigiProducer::inputCollName_
private

input hit collection name

Definition at line 64 of file HcalDigiProducer.h.

Referenced by configure(), and produce().

◆ inputPassName_

std::string hcal::HcalDigiProducer::inputPassName_
private

input pass name

Definition at line 67 of file HcalDigiProducer.h.

Referenced by configure(), and produce().

◆ iSOI_

int hcal::HcalDigiProducer::iSOI_
private

Index for the Sample Of Interest in the list of digi samples.

Definition at line 79 of file HcalDigiProducer.h.

Referenced by configure(), and produce().

◆ MeV_

double hcal::HcalDigiProducer::MeV_
private

Conversion from energy in MeV to voltage in mV.

Definition at line 82 of file HcalDigiProducer.h.

Referenced by configure(), and produce().

◆ nADCs_

int hcal::HcalDigiProducer::nADCs_
private

Depth of ADC buffer.

Definition at line 76 of file HcalDigiProducer.h.

Referenced by configure(), and produce().

◆ noise_

bool hcal::HcalDigiProducer::noise_ {true}
private

Put noise into empty channels, not configurable, only helpful in development.

Definition at line 92 of file HcalDigiProducer.h.

92{true};

Referenced by configure(), and produce().

◆ noiseGenerator_

std::unique_ptr<ldmx::NoiseGenerator> hcal::HcalDigiProducer::noiseGenerator_
private

Generates noise hits based off of number of cells that are not hit.

Definition at line 114 of file HcalDigiProducer.h.

Referenced by HcalDigiProducer(), onNewRun(), and produce().

◆ noiseRMS_

double hcal::HcalDigiProducer::noiseRMS_
private

Noise RMS.

Definition at line 111 of file HcalDigiProducer.h.

Referenced by configure(), and onNewRun().

◆ ns_

double hcal::HcalDigiProducer::ns_
private

Conversion from time in ns to ticks of the internal clock.

Definition at line 102 of file HcalDigiProducer.h.

Referenced by configure().

◆ pedestal_

double hcal::HcalDigiProducer::pedestal_
private

Read out pedestal.

Definition at line 107 of file HcalDigiProducer.h.

Referenced by configure(), and onNewRun().

◆ readoutThreshold_

double hcal::HcalDigiProducer::readoutThreshold_
private

Read out threshold.

Definition at line 105 of file HcalDigiProducer.h.

Referenced by configure(), and onNewRun().

◆ rng_

std::mt19937 hcal::HcalDigiProducer::rng_
private

Generates Gaussian noise on top of real hits.

Definition at line 117 of file HcalDigiProducer.h.

Referenced by onNewRun(), and produce().

◆ zeroSuppression_

bool hcal::HcalDigiProducer::zeroSuppression_ {true}
private

If false, save digis from all channels, even pure noise in empty bars Helpful when comparing with test beam data.

Definition at line 96 of file HcalDigiProducer.h.

96{true};

Referenced by configure(), and produce().


The documentation for this class was generated from the following files: