LDMX Software
Public Member Functions | Private Attributes | List of all members
ecal::EcalDigiProducer Class Reference

Performs basic ECal digitization. More...

#include <EcalDigiProducer.h>

Public Member Functions

 EcalDigiProducer (const std::string &name, framework::Process &process)
 Constructor Makes unique noise generator and injector for this class.
 
virtual ~EcalDigiProducer ()
 Destructor Deletes digi collection if it has been created.
 
virtual void configure (framework::config::Parameters &)
 Configure this producer from the python configuration.
 
virtual void produce (framework::Event &event)
 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.
 
bool zero_suppression_
 When emulating noise in empty channels, do we zero suppress?
 
bool noise_ {true}
 Put noise into empty channels, not configurable, only helpful in development.
 
std::unique_ptr< ldmx::HgcrocEmulatorhgcroc_
 Hgcroc Emulator to digitize analog voltage signals.
 
double ns_
 Total number of channels in the ECal.
 
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 ECal digitization.

Definition at line 36 of file EcalDigiProducer.h.

Constructor & Destructor Documentation

◆ EcalDigiProducer()

ecal::EcalDigiProducer::EcalDigiProducer ( const std::string &  name,
framework::Process process 
)

Constructor Makes unique noise generator and injector for this class.

Definition at line 15 of file EcalDigiProducer.cxx.

17 : Producer(name, process) {
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 noiseGenerator_ = std::make_unique<ldmx::NoiseGenerator>();
24}
std::unique_ptr< ldmx::NoiseGenerator > noiseGenerator_
Generates noise hits based off of number of cells that are not hit.
Producer(const std::string &name, Process &process)
Class constructor.

References noiseGenerator_.

◆ ~EcalDigiProducer()

ecal::EcalDigiProducer::~EcalDigiProducer ( )
virtual

Destructor Deletes digi collection if it has been created.

Definition at line 26 of file EcalDigiProducer.cxx.

26{}

Member Function Documentation

◆ configure()

void ecal::EcalDigiProducer::configure ( framework::config::Parameters ps)
virtual

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 EcalDigiProducer.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 // collection names
39 inputCollName_ = ps.getParameter<std::string>("inputCollName");
40 inputPassName_ = ps.getParameter<std::string>("inputPassName");
41 digiCollName_ = ps.getParameter<std::string>("digiCollName");
42
43 zero_suppression_ = ps.getParameter<bool>("zero_suppression");
44
45 // physical constants
46 // used to calculate unit conversions
47 MeV_ = ps.getParameter<double>("MeV");
48
49 // Time -> clock counts conversion
50 // time [ns] * ( 2^10 / max time in ns ) = clock counts
51 ns_ = 1024. / clockCycle_;
52
53 // Configure generator that will produce noise hits in empty channels
54 double readoutThreshold = ps.getParameter<double>("avgReadoutThreshold");
55 double pedestal = ps.getParameter<double>("avgPedestal");
56 double noiseRMS = ps.getParameter<double>("avgNoiseRMS");
57 // rms noise in mV
58 noiseGenerator_->setNoise(noiseRMS);
59 // mean noise amplitude (if using Gaussian Model for the noise) in mV
60 noiseGenerator_->setPedestal(pedestal);
61 // threshold for readout in mV
62 noiseGenerator_->setNoiseThreshold(readoutThreshold);
63}
int iSOI_
Index for the Sample Of Interest in the list of digi samples.
bool noise_
Put noise into empty channels, not configurable, only helpful in development.
std::string inputCollName_
input hit collection name
double clockCycle_
Time interval for chip clock in ns.
int nADCs_
Depth of ADC buffer.
double ns_
Total number of channels in the ECal.
std::string digiCollName_
output hit collection name
double MeV_
Conversion from energy in MeV to voltage in mV.
std::string inputPassName_
input pass name
std::unique_ptr< ldmx::HgcrocEmulator > hgcroc_
Hgcroc Emulator to digitize analog voltage signals.
bool zero_suppression_
When emulating noise in empty channels, do we zero suppress?
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

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

◆ produce()

void ecal::EcalDigiProducer::produce ( framework::Event event)
virtual

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

HACK ALERT The shifting of the time should not be done this sloppily. In reality, each chip has a set time phase that it samples at (relative to target), so the time shifting should be at the emulator level.

Implements framework::Producer.

Definition at line 65 of file EcalDigiProducer.cxx.

65 {
66 // Need to handle seeding on the first event
67 if (!noiseGenerator_->hasSeed()) {
68 const auto& rseed = getCondition<framework::RandomNumberSeedService>(
70 noiseGenerator_->seedGenerator(
71 rseed.getSeed("EcalDigiProducer::NoiseGenerator"));
72 }
73 if (noiseInjector_.get() == nullptr) {
74 const auto& rseed = getCondition<framework::RandomNumberSeedService>(
76 noiseInjector_ = std::make_unique<TRandom3>(
77 rseed.getSeed("EcalDigiProducer::NoiseInjector"));
78 }
79 if (!hgcroc_->hasSeed()) {
80 const auto& rseed = getCondition<framework::RandomNumberSeedService>(
82 hgcroc_->seedGenerator(rseed.getSeed("EcalDigiProducer::HgcrocEmulator"));
83 }
84
85 hgcroc_->condition(
86 getCondition<conditions::DoubleTableCondition>("EcalHgcrocConditions"));
87
88 // Empty collection to be filled
92
93 std::set<unsigned int>
94 filledDetIDs; // detector IDs that already have a hit in them
95
96 /******************************************************************************************
97 * HGCROC Emulation on Simulated Hits
98 *****************************************************************************************/
99 // std::cout << "Sim Hits" << std::endl;
100 // get simulated ecal hits from Geant4
101 // the class EcalHitIO in the SimApplication module handles the translation
102 // from G4CalorimeterHits to SimCalorimeterHits this class ensures that only
103 // one SimCalorimeterHit is generated per cell, but multiple "contributions"
104 // are still handled within SimCalorimeterHit
105 auto ecalSimHits{event.getCollection<ldmx::SimCalorimeterHit>(
107
108 /* debug printout
109 std::cout << "Energy to Voltage Conversion: " << MeV_ << " mV/MeV" <<
110 std::endl;
111 */
112
113 for (auto const& simHit : ecalSimHits) {
114 std::vector<std::pair<double, double>> pulses_at_chip;
115 for (int iContrib = 0; iContrib < simHit.getNumberOfContribs();
116 iContrib++) {
117 /* debug printout
118 std::cout << simHit.getContrib(iContrib).edep << " MeV" << std::endl;
119 */
126 pulses_at_chip.emplace_back(
127 simHit.getContrib(iContrib).edep * MeV_,
128 simHit.getContrib(iContrib).time // global time (t=0ns at target)
129 - simHit.getPosition().at(2) /
130 299.702547 // shift light-speed particle traveling along z
131 );
132 }
133
134 unsigned int hitID = simHit.getID();
135 filledDetIDs.insert(hitID);
136
137 /* debug printout
138 std::cout << hitID << " "
139 << simHit.getEdep()
140 << " MeV at "
141 << simHit.getTime() - simHit.getPosition().at(2)/299.702547
142 << std::endl;
143 */
144 // container emulator uses to write out samples and
145 // transfer samples into the digi collection
146 std::vector<ldmx::HgcrocDigiCollection::Sample> digiToAdd;
147 if (hgcroc_->digitize(hitID, pulses_at_chip, digiToAdd)) {
148 ecalDigis.addDigi(hitID, digiToAdd);
149 }
150 }
151
152 /******************************************************************************************
153 * Noise Simulation on Empty Channels
154 *****************************************************************************************/
155 if (noise_) {
156 // std::cout << "Noise Hits" << std::endl;
157 // put noise into some empty channels
158
159 // geometry constants
160 // These are used in the noise generation so that we can randomly
161 // distribute the noise uniformly throughout the ECal channels.
162 const auto& geom = getCondition<ldmx::EcalGeometry>(
163 ldmx::EcalGeometry::CONDITIONS_OBJECT_NAME);
164 int nEcalLayers = geom.getNumLayers();
165 int nModulesPerLayer = geom.getNumModulesPerLayer();
166 int nCellsPerModule = geom.getNumCellsPerModule();
167 int numEmptyChannels = nEcalLayers * nModulesPerLayer * nCellsPerModule -
168 ecalDigis.getNumDigis();
169
170 if (zero_suppression_) {
171 // noise generator gives us a list of noise amplitudes [mV] that randomly
172 // populate the empty channels and are above the readout threshold
173 auto noiseHitAmplitudes{
174 noiseGenerator_->generateNoiseHits(numEmptyChannels)};
175 std::vector<std::pair<double, double>> fake_pulse(1, {0., 0.});
176 for (double noiseHit : noiseHitAmplitudes) {
177 // generate detector ID for noise hit
178 // making sure that it is in an empty channel
179 unsigned int noiseID;
180 do {
181 int layerID = noiseInjector_->Integer(nEcalLayers);
182 int moduleID = noiseInjector_->Integer(nModulesPerLayer);
183 int cellID = noiseInjector_->Integer(nCellsPerModule);
184 auto detID = ldmx::EcalID(layerID, moduleID, cellID);
185 noiseID = detID.raw();
186 } while (filledDetIDs.find(noiseID) != filledDetIDs.end());
187 filledDetIDs.insert(noiseID);
188
189 // noise generator gives the amplitude above the readout threshold
190 // we need to convert it to the amplitude above the pedestal
191 noiseHit +=
192 hgcroc_->gain(noiseID) *
193 (hgcroc_->readoutThreshold(noiseID) - hgcroc_->pedestal(noiseID));
194
195 // create a digi as put it into the collection
196 ecalDigis.addDigi(noiseID, hgcroc_->noiseDigi(noiseID, noiseHit));
197 } // loop over noise amplitudes
198 } else {
199 // no zero suppression, put some noise emulation in **all** empty channels
200 // loop through all channels
201 for (int layer{0}; layer < nEcalLayers; layer++) {
202 for (int module{0}; module < nModulesPerLayer; module++) {
203 for (int cell{0}; cell < nCellsPerModule; cell++) {
204 unsigned int channel{ldmx::EcalID(layer, module, cell).raw()};
205 // check if channel already has a (real) hit in it
206 if (filledDetIDs.find(channel) != filledDetIDs.end()) continue;
207 // create a digi as put it into the collection
208 ecalDigis.addDigi(channel, hgcroc_->noiseDigi(channel));
209 } // cells in each module
210 } // modules in each layer
211 } // layers in ECal
212 } // yes or no zero suppression
213 } // if we should do the noise
214
215 event.add(digiCollName_, ecalDigis);
216
217 return;
218} // produce
std::unique_ptr< TRandom3 > noiseInjector_
Generates Gaussian noise on top of real hits.
static const std::string CONDITIONS_OBJECT_NAME
Conditions object name.
RawValue raw() const
Definition DetectorID.h:68
Extension of DetectorID providing access to ECal layers and cell numbers in a hex grid.
Definition EcalID.h:20
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.
int getID() const
Get the detector ID.

References ldmx::HgcrocDigiCollection::addDigi(), framework::RandomNumberSeedService::CONDITIONS_OBJECT_NAME, ldmx::SimCalorimeterHit::getID(), ldmx::HgcrocDigiCollection::getNumDigis(), hgcroc_, inputCollName_, inputPassName_, iSOI_, MeV_, nADCs_, noise_, noiseGenerator_, noiseInjector_, ldmx::DetectorID::raw(), ldmx::HgcrocDigiCollection::setNumSamplesPerDigi(), ldmx::HgcrocDigiCollection::setSampleOfInterestIndex(), and zero_suppression_.

Member Data Documentation

◆ clockCycle_

double ecal::EcalDigiProducer::clockCycle_
private

Time interval for chip clock in ns.

Definition at line 76 of file EcalDigiProducer.h.

Referenced by configure().

◆ digiCollName_

std::string ecal::EcalDigiProducer::digiCollName_
private

output hit collection name

Definition at line 73 of file EcalDigiProducer.h.

Referenced by configure().

◆ hgcroc_

std::unique_ptr<ldmx::HgcrocEmulator> ecal::EcalDigiProducer::hgcroc_
private

Hgcroc Emulator to digitize analog voltage signals.

Definition at line 109 of file EcalDigiProducer.h.

Referenced by configure(), and produce().

◆ inputCollName_

std::string ecal::EcalDigiProducer::inputCollName_
private

input hit collection name

Definition at line 67 of file EcalDigiProducer.h.

Referenced by configure(), and produce().

◆ inputPassName_

std::string ecal::EcalDigiProducer::inputPassName_
private

input pass name

Definition at line 70 of file EcalDigiProducer.h.

Referenced by configure(), and produce().

◆ iSOI_

int ecal::EcalDigiProducer::iSOI_
private

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

Definition at line 82 of file EcalDigiProducer.h.

Referenced by configure(), and produce().

◆ MeV_

double ecal::EcalDigiProducer::MeV_
private

Conversion from energy in MeV to voltage in mV.

Definition at line 85 of file EcalDigiProducer.h.

Referenced by configure(), and produce().

◆ nADCs_

int ecal::EcalDigiProducer::nADCs_
private

Depth of ADC buffer.

Definition at line 79 of file EcalDigiProducer.h.

Referenced by configure(), and produce().

◆ noise_

bool ecal::EcalDigiProducer::noise_ {true}
private

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

Definition at line 106 of file EcalDigiProducer.h.

106{true};

Referenced by configure(), and produce().

◆ noiseGenerator_

std::unique_ptr<ldmx::NoiseGenerator> ecal::EcalDigiProducer::noiseGenerator_
private

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

Definition at line 119 of file EcalDigiProducer.h.

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

◆ noiseInjector_

std::unique_ptr<TRandom3> ecal::EcalDigiProducer::noiseInjector_
private

Generates Gaussian noise on top of real hits.

Definition at line 122 of file EcalDigiProducer.h.

Referenced by produce().

◆ ns_

double ecal::EcalDigiProducer::ns_
private

Total number of channels in the ECal.

Conversion from time in ns to ticks of the internal clock

Definition at line 116 of file EcalDigiProducer.h.

Referenced by configure().

◆ zero_suppression_

bool ecal::EcalDigiProducer::zero_suppression_
private

When emulating noise in empty channels, do we zero suppress?

There are two ways to emulate the noise in the chip: 1) (with zero suppression) Use the NoiseGenerator to get a list of amplitudes (about 3-5 on avg) and put those noise hits which are above the readout threshold in random empty channels. 2) (without zero suppresion) Go through all channels and put noise in each channel that doesn't have a real hit in it. This will mean many channels with have a DIGI below readout threshold.

Definition at line 99 of file EcalDigiProducer.h.

Referenced by configure(), and produce().


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