LDMX Software
Public Member Functions | Private Attributes | List of all members
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.
 
- 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 onNewRun (const ldmx::RunHeader &runHeader)
 Callback for the EventProcessor to take any necessary action when the run being processed changes.
 
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.
 
std::unique_ptr< ldmx::NoiseGeneratornoiseGenerator_
 Generates noise hits based off of number of cells that are not hit.
 
std::unique_ptr< TRandom3 > noiseInjector_
 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 29 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 15 of file HcalDigiProducer.cxx.

17 : Producer(name, process) {
18 /*
19 * Noise generator by default uses a Gausian model for noise
20 * i.e. It assumes the noise is distributed around a mean (setPedestal)
21 * with a certain RMS (setNoise) and then calculates
22 * how many hits should be generated for a given number of empty
23 * channels and a minimum readout value (setNoiseThreshold)
24 */
25 noiseGenerator_ = std::make_unique<ldmx::NoiseGenerator>();
26}
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 28 of file HcalDigiProducer.cxx.

28 {
29 // settings of readout chip
30 // used in actual digitization
31 auto hgcrocParams = ps.getParameter<framework::config::Parameters>("hgcroc");
32 hgcroc_ = std::make_unique<ldmx::HgcrocEmulator>(hgcrocParams);
33 clockCycle_ = hgcrocParams.getParameter<double>("clockCycle");
34 nADCs_ = hgcrocParams.getParameter<int>("nADCs");
35 iSOI_ = hgcrocParams.getParameter<int>("iSOI");
36 noise_ = hgcrocParams.getParameter<bool>("noise");
37
38 // If true, ignore readout threshold
39 // and generate pedestal noise digis in every empty channel
40 zeroSuppression_ = ps.getParameter<bool>("zeroSuppression");
41
42 // collection names
43 inputCollName_ = ps.getParameter<std::string>("inputCollName");
44 inputPassName_ = ps.getParameter<std::string>("inputPassName");
45 digiCollName_ = ps.getParameter<std::string>("digiCollName");
46
47 // physical constants
48 // used to calculate unit conversions
49 MeV_ = ps.getParameter<double>("MeV");
50 attlength_ = ps.getParameter<double>("attenuationLength");
51
52 // Time -> clock counts conversion
53 // time [ns] * ( 2^10 / max time in ns ) = clock counts
54 ns_ = 1024. / clockCycle_;
55
56 // Configure generator that will produce noise hits in empty channels
57 double readoutThreshold = ps.getParameter<double>("avgReadoutThreshold");
58 double gain = ps.getParameter<double>("avgGain");
59 double pedestal = ps.getParameter<double>("avgPedestal");
60 // rms noise in mV
61 noiseGenerator_->setNoise(gain * ps.getParameter<double>("avgNoiseRMS"));
62 // mean noise amplitude (if using Gaussian Model for the noise) in mV
63 noiseGenerator_->setPedestal(gain * pedestal);
64 // threshold for readout in mV
65 noiseGenerator_->setNoiseThreshold(gain * readoutThreshold);
66}
Class encapsulating parameters for configuring a processor.
Definition Parameters.h:27
T getParameter(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:89
bool noise_
Put noise into empty channels, not configurable, only helpful in development.
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 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.

References attlength_, clockCycle_, digiCollName_, framework::config::Parameters::getParameter(), hgcroc_, inputCollName_, inputPassName_, iSOI_, MeV_, nADCs_, noise_, noiseGenerator_, ns_, and zeroSuppression_.

◆ 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 68 of file HcalDigiProducer.cxx.

68 {
69 // Handle seeding on the first event
70 if (!noiseGenerator_->hasSeed()) {
71 const auto& rseed = getCondition<framework::RandomNumberSeedService>(
73 noiseGenerator_->seedGenerator(
74 rseed.getSeed("HcalDigiProducer::NoiseGenerator"));
75 }
76 if (noiseInjector_.get() == nullptr) {
77 const auto& rseed = getCondition<framework::RandomNumberSeedService>(
79 noiseInjector_ = std::make_unique<TRandom3>(
80 rseed.getSeed("HcalDigiProducer::NoiseInjector"));
81 }
82 if (!hgcroc_->hasSeed()) {
83 const auto& rseed = getCondition<framework::RandomNumberSeedService>(
85 hgcroc_->seedGenerator(rseed.getSeed("HcalDigiProducer::HgcrocEmulator"));
86 }
87
88 // Get the Hgcroc Conditions
89 hgcroc_->condition(
90 getCondition<conditions::DoubleTableCondition>("HcalHgcrocConditions"));
91
92 // Get the Hcal Geometry
93 const auto& hcalGeometry = getCondition<ldmx::HcalGeometry>(
95
96 // Empty collection to be filled
100
101 std::map<unsigned int, std::vector<const ldmx::SimCalorimeterHit*>> hitsByID;
102
103 // get simulated hcal hits from Geant4 and group them by id
104 auto hcalSimHits{event.getCollection<ldmx::SimCalorimeterHit>(
106
107 for (auto const& simHit : hcalSimHits) {
108 // get ID
109 unsigned int hitID = simHit.getID();
110
111 auto idh = hitsByID.find(hitID);
112 if (idh == hitsByID.end()) {
113 hitsByID[hitID] = std::vector<const ldmx::SimCalorimeterHit*>(1, &simHit);
114 } else {
115 idh->second.push_back(&simHit);
116 }
117 }
118
119 /******************************************************************************************
120 * HGCROC Emulation on Simulated Hits (grouped by HcalID)
121 ******************************************************************************************/
122 for (auto const& simBar : hitsByID) {
123 ldmx::HcalID detID(simBar.first);
124 int section = detID.section();
125 int layer = detID.layer();
126 int strip = detID.strip();
127
128 // get position
129 double half_total_width = hcalGeometry.getHalfTotalWidth(section, layer);
130 double ecal_dx = hcalGeometry.getEcalDx();
131 double ecal_dy = hcalGeometry.getEcalDy();
132
133 // contributions
134 std::vector<std::pair<double, double>> pulses_posend;
135 std::vector<std::pair<double, double>> pulses_negend;
136
137 for (auto psimHit : simBar.second) {
138 const ldmx::SimCalorimeterHit& simHit = *psimHit;
139
140 std::vector<float> position = simHit.getPosition();
141
170 float distance_along_bar, distance_ecal;
171 float distance_close, distance_far;
172 int end_close;
173 const auto orientation{hcalGeometry.getScintillatorOrientation(detID)};
174 if (section == ldmx::HcalID::HcalSection::BACK) {
175 distance_along_bar =
176 (orientation ==
177 ldmx::HcalGeometry::ScintillatorOrientation::horizontal)
178 ? position[0]
179 : position[1];
180 end_close = (distance_along_bar > 0) ? 0 : 1;
181 distance_close = half_total_width;
182 distance_far = half_total_width;
183 } else {
184 if ((section == ldmx::HcalID::HcalSection::TOP) ||
185 ((section == ldmx::HcalID::HcalSection::BOTTOM))) {
186 distance_along_bar = position[0];
187 distance_ecal = ecal_dx;
188 } else if ((section == ldmx::HcalID::HcalSection::LEFT) ||
189 (section == ldmx::HcalID::HcalSection::RIGHT)) {
190 distance_along_bar = position[1];
191 distance_ecal = ecal_dy;
192 } else {
193 distance_along_bar = -9999.;
194 EXCEPTION_RAISE(
195 "BadCode",
196 "We should never end up here "
197 "All cases of HCAL considered, end_close is meaningless");
198 }
199 end_close = (distance_along_bar > half_total_width) ? 0 : 1;
200 distance_close = (end_close == 0)
201 ? 2 * half_total_width - distance_ecal / 2
202 : distance_ecal / 2;
203 distance_far = (end_close == 0)
204 ? distance_ecal / 2
205 : 2 * half_total_width - distance_ecal / 2;
206 }
207
208 // Calculate voltage attenuation and time shift for the close and far
209 // pulse.
210 float v = 299.792 /
211 1.6; // velocity of light in Polystyrene, n = 1.6 = c/v mm/ns
212 double att_close =
213 exp(-1. * ((distance_close - fabs(distance_along_bar)) / 1000.) /
214 attlength_);
215 double att_far =
216 exp(-1. * ((distance_far + fabs(distance_along_bar)) / 1000.) /
217 attlength_);
218 double shift_close =
219 fabs((distance_close - fabs(distance_along_bar)) / v);
220 double shift_far = fabs((distance_far + fabs(distance_along_bar)) / v);
221
222 // Get voltages and times.
223 for (int iContrib = 0; iContrib < simHit.getNumberOfContribs();
224 iContrib++) {
225 double voltage = simHit.getContrib(iContrib).edep * MeV_;
226 double time =
227 simHit.getContrib(iContrib).time; // global time (t=0ns at target)
228 time -= position.at(2) /
229 299.702547; // shift light-speed particle traveling along z
230
231 if (end_close == 0) {
232 pulses_posend.emplace_back(voltage * att_close, time + shift_close);
233 pulses_negend.emplace_back(voltage * att_far, time + shift_far);
234 } else {
235 pulses_posend.emplace_back(voltage * att_far, time + shift_far);
236 pulses_negend.emplace_back(voltage * att_close, time + shift_close);
237 }
238 }
239 }
240
250 if (section == ldmx::HcalID::HcalSection::BACK) {
251 std::vector<ldmx::HgcrocDigiCollection::Sample> digiToAddPosend,
252 digiToAddNegend;
253 ldmx::HcalDigiID posendID(section, layer, strip, 0);
254 ldmx::HcalDigiID negendID(section, layer, strip, 1);
255
256 bool posEndActivity =
257 hgcroc_->digitize(posendID.raw(), pulses_posend, digiToAddPosend);
258 bool negEndActivity =
259 hgcroc_->digitize(negendID.raw(), pulses_negend, digiToAddNegend);
260
261 if (posEndActivity && negEndActivity && zeroSuppression_) {
262 hcalDigis.addDigi(posendID.raw(), digiToAddPosend);
263 hcalDigis.addDigi(negendID.raw(), digiToAddNegend);
264 } // If zeroSuppression == true, Back Hcal needs to digitize both
265 // pulses or none
266
267 if (!zeroSuppression_) {
268 if (posEndActivity) {
269 hcalDigis.addDigi(posendID.raw(), digiToAddPosend);
270 } else {
271 std::vector<ldmx::HgcrocDigiCollection::Sample> digi =
272 hgcroc_->noiseDigi(posendID.raw(), 0.0);
273 hcalDigis.addDigi(posendID.raw(), digi);
274 }
275 if (negEndActivity) {
276 hcalDigis.addDigi(posendID.raw(), digiToAddPosend);
277 } else {
278 std::vector<ldmx::HgcrocDigiCollection::Sample> digi =
279 hgcroc_->noiseDigi(negendID.raw(), 0.0);
280 hcalDigis.addDigi(negendID.raw(), digi);
281 }
282 }
283
284 } else {
285 bool is_posend = false;
286 std::vector<ldmx::HgcrocDigiCollection::Sample> digiToAdd;
287 if ((section == ldmx::HcalID::HcalSection::TOP) ||
288 (section == ldmx::HcalID::HcalSection::LEFT)) {
289 is_posend = true;
290 } else if ((section == ldmx::HcalID::HcalSection::BOTTOM) ||
291 (section == ldmx::HcalID::HcalSection::RIGHT)) {
292 is_posend = false;
293 }
294 if (is_posend) {
295 ldmx::HcalDigiID digiID(section, layer, strip, 0);
296 if (hgcroc_->digitize(digiID.raw(), pulses_posend, digiToAdd)) {
297 hcalDigis.addDigi(digiID.raw(), digiToAdd);
298 } else if (!zeroSuppression_) {
299 std::vector<ldmx::HgcrocDigiCollection::Sample> digi =
300 hgcroc_->noiseDigi(digiID.raw(), 0.0);
301 hcalDigis.addDigi(digiID.raw(), digi);
302 }
303 } else {
304 ldmx::HcalDigiID digiID(section, layer, strip, 1);
305 if (hgcroc_->digitize(digiID.raw(), pulses_negend, digiToAdd)) {
306 hcalDigis.addDigi(digiID.raw(), digiToAdd);
307 } else if (!zeroSuppression_) {
308 std::vector<ldmx::HgcrocDigiCollection::Sample> digi =
309 hgcroc_->noiseDigi(digiID.raw(), 0.0);
310 hcalDigis.addDigi(digiID.raw(), digi);
311 }
312 }
313 }
314 }
315
316 /******************************************************************************************
317 * Noise Simulation on Empty Channels
318 *****************************************************************************************/
319 if (noise_) {
320 std::vector<ldmx::HcalDigiID> channelMap;
321 int numChannels = 0;
322 for (int section = 0; section < hcalGeometry.getNumSections(); section++) {
323 int numChannelsInSection = 0;
324 for (int layer = 1; layer <= hcalGeometry.getNumLayers(section);
325 layer++) {
326 numChannelsInSection += hcalGeometry.getNumStrips(section, layer);
327 // Note zero-indexed strip numbering...
328 for (int strip = 0; strip < hcalGeometry.getNumStrips(section, layer);
329 strip++) {
330 if (section == ldmx::HcalID::HcalSection::BACK) {
331 auto digiIDend0 = ldmx::HcalDigiID(section, layer, strip, 0);
332 auto digiIDend1 = ldmx::HcalDigiID(section, layer, strip, 1);
333 channelMap.push_back(digiIDend0);
334 channelMap.push_back(digiIDend1);
335 numChannels += 2;
336 } else {
337 auto digiID = ldmx::HcalDigiID(section, layer, strip, 0);
338 channelMap.push_back(digiID);
339 numChannels++;
340 }
341 }
342 }
343 }
344
345 if (zeroSuppression_) { // Fast noise sim
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 for (double noiseHit : noiseHitAmplitudes) {
353 // generate detector ID for noise hit
354 // making sure that it is in an empty channel
355 unsigned int noiseID;
356 int sectionID, layerID, stripID, endID;
357 do {
358 sectionID = noiseInjector_->Integer(hcalGeometry.getNumSections());
359 layerID =
360 noiseInjector_->Integer(hcalGeometry.getNumLayers(sectionID));
361 // set layer to 1 if the generator says it is 0 (geometry map starts
362 // from 1)
363 if (layerID == 0) layerID = 1;
364 stripID = noiseInjector_->Integer(
365 hcalGeometry.getNumStrips(sectionID, layerID));
366 endID = noiseInjector_->Integer(2);
367 if ((sectionID == ldmx::HcalID::HcalSection::TOP) ||
368 (sectionID == ldmx::HcalID::HcalSection::LEFT)) {
369 endID = 0;
370 } else if ((sectionID == ldmx::HcalID::HcalSection::BOTTOM) ||
371 (sectionID == ldmx::HcalID::HcalSection::RIGHT)) {
372 endID = 1;
373 }
374 auto detID = ldmx::HcalDigiID(sectionID, layerID, stripID, endID);
375 noiseID = detID.raw();
376 } while (hitsByID.find(noiseID) != hitsByID.end());
377 hitsByID[noiseID] =
378 std::vector<const ldmx::SimCalorimeterHit*>(); // mark this as used
379
380 // get a time for this noise hit
381 fake_pulse[0].second = noiseInjector_->Uniform(clockCycle_);
382
383 // noise generator gives the amplitude above the readout threshold
384 // we need to convert it to the amplitude above the pedestal
385 double gain = hgcroc_->gain(noiseID);
386 fake_pulse[0].first = noiseHit +
387 gain * hgcroc_->readoutThreshold(noiseID) -
388 gain * hgcroc_->pedestal(noiseID);
389
390 if (sectionID == ldmx::HcalID::HcalSection::BACK) {
391 std::vector<ldmx::HgcrocDigiCollection::Sample> digiToAddPosend,
392 digiToAddNegend;
393 ldmx::HcalDigiID posendID(sectionID, layerID, stripID, 0);
394 ldmx::HcalDigiID negendID(sectionID, layerID, stripID, 1);
395 if (hgcroc_->digitize(posendID.raw(), fake_pulse, digiToAddPosend) &&
396 hgcroc_->digitize(negendID.raw(), fake_pulse, digiToAddNegend)) {
397 hcalDigis.addDigi(posendID.raw(), digiToAddPosend);
398 hcalDigis.addDigi(negendID.raw(), digiToAddNegend);
399 }
400 } else {
401 std::vector<ldmx::HgcrocDigiCollection::Sample> digiToAdd;
402 if (hgcroc_->digitize(noiseID, fake_pulse, digiToAdd)) {
403 hcalDigis.addDigi(noiseID, digiToAdd);
404 }
405 }
406 } // loop over noise amplitudes
407 } else { // If zeroSuppression_ == false, add noise digis for all bars
408 // without simhits
409 for (auto digiID : channelMap) {
410 // Convert from digi ID to det ID (since simhits don't know about
411 // different ends of the bar)
412 ldmx::HcalID detid(digiID.section(), digiID.layer(), digiID.strip());
413 unsigned int rawdetID = detid.raw();
414 if (hitsByID.find(rawdetID) == hitsByID.end()) {
415 std::vector<ldmx::HgcrocDigiCollection::Sample> digi =
416 hgcroc_->noiseDigi(digiID.raw(), 0.0);
417 hcalDigis.addDigi(digiID.raw(), digi);
418 }
419 }
420 }
421 } // if we should add noise
422
423 event.add(digiCollName_, hcalDigis);
424
425 return;
426} // produce
static const std::string CONDITIONS_OBJECT_NAME
Conditions object name.
std::unique_ptr< TRandom3 > noiseInjector_
Generates Gaussian noise on top of real hits.
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].
int getID() const
Get the detector ID.
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, framework::RandomNumberSeedService::CONDITIONS_OBJECT_NAME, digiCollName_, ldmx::SimCalorimeterHit::Contrib::edep, ldmx::SimCalorimeterHit::getContrib(), ldmx::SimCalorimeterHit::getID(), ldmx::SimCalorimeterHit::getNumberOfContribs(), ldmx::HgcrocDigiCollection::getNumDigis(), ldmx::SimCalorimeterHit::getPosition(), hgcroc_, inputCollName_, inputPassName_, iSOI_, ldmx::HcalID::layer(), MeV_, nADCs_, noise_, noiseGenerator_, noiseInjector_, ldmx::DetectorID::raw(), 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 78 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 66 of file HcalDigiProducer.h.

Referenced by configure(), and produce().

◆ digiCollName_

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

output hit collection name

Definition at line 63 of file HcalDigiProducer.h.

Referenced by configure(), and produce().

◆ hgcroc_

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

Hgcroc Emulator to digitize analog voltage signals.

Definition at line 92 of file HcalDigiProducer.h.

Referenced by configure(), and produce().

◆ inputCollName_

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

input hit collection name

Definition at line 57 of file HcalDigiProducer.h.

Referenced by configure(), and produce().

◆ inputPassName_

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

input pass name

Definition at line 60 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 72 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 75 of file HcalDigiProducer.h.

Referenced by configure(), and produce().

◆ nADCs_

int hcal::HcalDigiProducer::nADCs_
private

Depth of ADC buffer.

Definition at line 69 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 85 of file HcalDigiProducer.h.

85{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 98 of file HcalDigiProducer.h.

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

◆ noiseInjector_

std::unique_ptr<TRandom3> hcal::HcalDigiProducer::noiseInjector_
private

Generates Gaussian noise on top of real hits.

Definition at line 101 of file HcalDigiProducer.h.

Referenced by produce().

◆ ns_

double hcal::HcalDigiProducer::ns_
private

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

Definition at line 95 of file HcalDigiProducer.h.

Referenced by configure().

◆ 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 89 of file HcalDigiProducer.h.

89{true};

Referenced by configure(), and produce().


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