Belle II Software development
TOPDigitizerModule.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9// Own header.
10#include <top/modules/TOPDigitizer/TOPDigitizerModule.h>
11
12// TOP headers.
13#include <top/geometry/TOPGeometryPar.h>
14#include <top/modules/TOPDigitizer/TimeDigitizer.h>
15
16// framework - DataStore
17#include <framework/datastore/DataStore.h>
18#include <framework/datastore/StoreArray.h>
19#include <framework/datastore/StoreObjPtr.h>
20
21// framework aux
22#include <framework/logging/Logger.h>
23
24// ROOT
25#include <TRandom.h>
26
27#include <map>
28
29using namespace std;
30
31namespace Belle2 {
37 using namespace TOP;
38
39 //-----------------------------------------------------------------
41 //-----------------------------------------------------------------
42
43 REG_MODULE(TOPDigitizer);
44
45
46 //-----------------------------------------------------------------
47 // Implementation
48 //-----------------------------------------------------------------
49
51 {
52 // Set description()
53 setDescription("Digitize TOPSimHits");
55
56 // Add parameters
57 addParam("timeZeroJitter", m_timeZeroJitter,
58 "r.m.s of T0 jitter [ns]", 15e-3);
59 addParam("electronicJitter", m_electronicJitter,
60 "r.m.s of electronic jitter [ns], "
61 "if negative the one from TOPNominalTDC is used. "
62 "This parameter is ignored in the full waveform digitization.", -1.0);
63 addParam("darkNoise", m_darkNoise,
64 "uniformly distributed dark noise (hits per module)", 0.0);
65 addParam("ADCx0", m_ADCx0,
66 "pulse height distribution parameter [ADC counts]", 204.1);
67 addParam("ADCp1", m_ADCp1,
68 "pulse height distribution parameter (must be non-negative)", 1.0);
69 addParam("ADCp2", m_ADCp2,
70 "pulse height distribution parameter (must be non-negative)", 1.025);
71 addParam("ADCmax", m_ADCmax,
72 "pulse height distribution upper bound [ADC counts]", 2000.0);
73 addParam("rmsNoise", m_rmsNoise,
74 "r.m.s of noise [ADC counts]", 9.7);
75 addParam("threshold", m_threshold,
76 "pulse height threshold [ADC counts]", 40);
77 addParam("hysteresis", m_hysteresis,
78 "pulse height threshold hysteresis [ADC counts]", 10);
79 addParam("thresholdCount", m_thresholdCount,
80 "minimal number of samples above threshold", 3);
81 addParam("useWaveforms", m_useWaveforms,
82 "if true, use full waveform digitization", true);
83 addParam("allChannels", m_allChannels,
84 "if true, make waveforms for all 8192 channels "
85 "(note: this will slow-down digitization)", false);
86 addParam("useDatabase", m_useDatabase,
87 "if true, use channel dependent constants from database (incl. time base)",
88 true);
89 addParam("useSampleTimeCalibration", m_useSampleTimeCalibration,
90 "if true, use only time base calibration from database "
91 "(has no effect if useDatabase = True)", false);
92 addParam("simulateTTS", m_simulateTTS,
93 "if true, simulate time transition spread. "
94 "Should be always switched ON, except for some dedicated timing studies.",
95 true);
96 addParam("minWidthXheight", m_minWidthXheight,
97 "minimal product of width and height [ns * ADC counts]", 100.0);
98 addParam("lookBackWindows", m_lookBackWindows,
99 "number of look back windows, if positive override the number from database", 0);
100 }
101
102
104 {
105 // input from datastore
106 m_simHits.isRequired();
107 m_simCalPulses.isOptional();
109 m_simClockState.isOptional();
110
111 // output to datastore
112 m_rawDigits.registerInDataStore();
113 m_digits.registerInDataStore();
114 m_digits.registerRelationTo(m_simHits);
115 m_digits.registerRelationTo(m_mcParticles);
116 m_digits.registerRelationTo(m_rawDigits);
117 m_waveforms.registerInDataStore(DataStore::c_DontWriteOut);
118 m_rawDigits.registerRelationTo(m_waveforms, DataStore::c_Event,
120
121 // geometry and nominal data
122 const auto* geo = TOPGeometryPar::Instance()->getGeometry();
123
124 if (m_electronicJitter < 0) {
125 m_electronicJitter = geo->getNominalTDC().getTimeJitter();
126 }
127
128 // set pile-up and double hit resolution times (needed for BG overlay)
129 TOPDigit::setDoubleHitResolution(geo->getNominalTDC().getDoubleHitResolution());
130 TOPDigit::setPileupTime(geo->getNominalTDC().getPileupTime());
131
132 // default sample times (equidistant)
133 m_syncTimeBase = geo->getNominalTDC().getSyncTimeBase();
134 m_sampleTimes.setTimeAxis(m_syncTimeBase); // equidistant time base
135
136 // default pulse height generator
138
139 }
140
141
143 {
144 StoreObjPtr<EventMetaData> evtMetaData;
145
146 // check availability of mappers
147 const auto& channelMapper = TOPGeometryPar::Instance()->getChannelMapper();
148 if (not channelMapper.isValid()) {
149 B2FATAL("No valid channel mapper found for run "
150 << evtMetaData->getRun()
151 << " of experiment " << evtMetaData->getExperiment());
152 }
153 const auto& frontEndMapper = TOPGeometryPar::Instance()->getFrontEndMapper();
154 if (not frontEndMapper.isValid()) {
155 B2FATAL("No valid front-end mapper found for run "
156 << evtMetaData->getRun()
157 << " of experiment " << evtMetaData->getExperiment());
158 }
159
160 // check availability of constants in database
161 if (m_useDatabase) {
162 if (not m_timebases.isValid()) {
163 B2FATAL("Sample time calibration constants requested but not available for run "
164 << evtMetaData->getRun()
165 << " of experiment " << evtMetaData->getExperiment());
166 }
167 if (not m_channelT0.isValid()) {
168 B2FATAL("Channel T0 calibration constants requested but not available for run "
169 << evtMetaData->getRun()
170 << " of experiment " << evtMetaData->getExperiment());
171 }
172 if (not m_asicShift.isValid()) {
173 B2FATAL("ASIC shifts calibration requested but not available for run "
174 << evtMetaData->getRun()
175 << " of experiment " << evtMetaData->getExperiment());
176 }
177 if (not m_moduleT0.isValid()) {
178 B2FATAL("Module T0 calibration constants requested but not available for run "
179 << evtMetaData->getRun()
180 << " of experiment " << evtMetaData->getExperiment());
181 }
182 if (not m_commonT0.isValid()) {
183 B2FATAL("Common T0 calibration constants requested but not available for run "
184 << evtMetaData->getRun()
185 << " of experiment " << evtMetaData->getExperiment());
186 }
187 if (not m_pulseHeights.isValid()) {
188 B2FATAL("Pulse height calibration constants requested but not available for run "
189 << evtMetaData->getRun()
190 << " of experiment " << evtMetaData->getExperiment());
191 }
192 if (not m_thresholds.isValid()) {
193 B2FATAL("Channel thresholds requested but not available for run "
194 << evtMetaData->getRun()
195 << " of experiment " << evtMetaData->getExperiment());
196 }
197 if (not m_noises.isValid()) {
198 B2FATAL("Channel noise levels requested but not available for run "
199 << evtMetaData->getRun()
200 << " of experiment " << evtMetaData->getExperiment());
201 }
202 if (m_timeWalk.isValid()) {
204 } else {
206 // B2FATAL("Time-walk parameters requested but not available for run "
207 B2WARNING("Time-walk parameters not available for run "
208 << evtMetaData->getRun()
209 << " of experiment " << evtMetaData->getExperiment());
210 }
211 } else if (m_useSampleTimeCalibration) {
212 if (not m_timebases.isValid()) {
213 B2FATAL("Sample time calibration constants requested but not available for run "
214 << evtMetaData->getRun()
215 << " of experiment " << evtMetaData->getExperiment());
216 }
217 }
218
219 // check availability of front-end settings
220 if (not m_feSetting.isValid()) {
221 B2FATAL("Front-end settings are not available for run "
222 << evtMetaData->getRun()
223 << " of experiment " << evtMetaData->getExperiment());
224 }
225
226 // pass a parameter to TimeDigitizer
227 TimeDigitizer::setReadoutWindows(m_feSetting->getReadoutWindows());
228 if ((evtMetaData->getExperiment() > 0 and evtMetaData->getExperiment() < 5) or
229 evtMetaData->getExperiment() == 1002) {
230 TimeDigitizer::maskSamples(true); // phase-2: mask samples at window boundaries
231 } else {
232 TimeDigitizer::maskSamples(false); // phase-3: no masking
233 }
234
235 }
236
238 {
239
240 // get or generate revo9 count
241 unsigned revo9cnt = 0;
242 if (m_simClockState.isValid()) {
243 revo9cnt = m_simClockState->getRevo9Count();
244 } else {
245 revo9cnt = gRandom->Integer(11520);
246 }
247
248 // from revo9 count determine trigger time offset and the number of offset windows
249 double SSTfrac = (revo9cnt % 6) / 6.0;
250 double offset = m_feSetting->getOffset() / 24.0;
251 double trgTimeOffset = (SSTfrac + offset) * m_syncTimeBase; // in [ns]
252 int offsetWindows = m_feSetting->getWindowShift(revo9cnt);
253 TimeDigitizer::setOffsetWindows(offsetWindows);
254
255 // from revo9 and write depths determine reference window, phase and storage depth
256 int SSTcnt = revo9cnt / 6;
257 int refWindow = SSTcnt * 2; // same as lastWriteAddr
258 const auto& writeDepths = m_feSetting->getWriteDepths();
259 if (writeDepths.empty()) {
260 B2ERROR("TOPDigitzer: vector of write depths is empty. No digitization possible");
261 return;
262 }
263 int lastDepth = writeDepths.back();
264 unsigned phase = 0;
265 for (auto depth : writeDepths) {
266 SSTcnt -= depth;
267 if (SSTcnt < 0) break;
268 phase++;
269 refWindow = SSTcnt * 2;
270 lastDepth = depth;
271 }
272 unsigned storageDepth = lastDepth * 2;
273 TimeDigitizer::setStorageDepth(storageDepth);
274
275 // from reference window and lookback determine first of the readout windows
276 int lookBackWindows = m_feSetting->getLookbackWindows();
277 if (m_lookBackWindows > 0) lookBackWindows = m_lookBackWindows;
278 lookBackWindows -= m_feSetting->getExtraWindows();
279 int window = refWindow - lookBackWindows;
280 if (window < 0) window += storageDepth;
282
283 // geometry and nominal data
284 const auto* geo = TOPGeometryPar::Instance()->getGeometry();
285
286 // time range for digitization
287 double timeMin = geo->getSignalShape().getTMin() + offsetWindows * m_syncTimeBase / 2;
288 double timeMax = geo->getSignalShape().getTMax() +
289 (m_feSetting->getReadoutWindows() + offsetWindows) * m_syncTimeBase / 2;
290
291 // simulate start time jitter
292 double startTimeJitter = gRandom->Gaus(0, m_timeZeroJitter);
293
294 // get electronic efficiency
295 double electronicEfficiency = geo->getNominalTDC().getEfficiency();
296
297 // define pixels with time digitizers
298 std::map<unsigned, TimeDigitizer> pixels;
299 typedef std::map<unsigned, TimeDigitizer>::iterator Iterator;
300
301 // add simulated hits to time digitizers
302
303 for (const auto& simHit : m_simHits) {
304 if (not m_useWaveforms) {
305 // simulate electronic efficiency
306 if (gRandom->Rndm() > electronicEfficiency) continue;
307 }
308 // do spatial digitization
309 double x = simHit.getX();
310 double y = simHit.getY();
311 int pmtID = simHit.getPmtID();
312 int moduleID = simHit.getModuleID();
313 if (not geo->isModuleIDValid(moduleID)) continue;
314 int pixelID = geo->getModule(moduleID).getPMTArray().getPixelID(x, y, pmtID);
315 if (pixelID == 0) continue;
316
317 // add start time jitter and generated TTS to photon time
318 double time = simHit.getTime() + startTimeJitter;
319 if (m_simulateTTS) {
320 const auto& tts = TOPGeometryPar::Instance()->getTTS(moduleID, pmtID);
321 time += tts.generateTTS();
322 }
323
324 // get time offset for a given pixel
325 auto timeOffset = getTimeOffset(trgTimeOffset, moduleID, pixelID);
326
327 // time range cut (to speed up digitization)
328 if (time + timeOffset.value < timeMin + timeOffset.timeShift) continue;
329 if (time + timeOffset.value > timeMax + timeOffset.timeShift) continue;
330
331 // generate pulse height
332 double pulseHeight = generatePulseHeight(moduleID, pixelID);
333 auto hitType = TimeDigitizer::c_Hit;
334
335 // add time and pulse height to digitizer of a given pixel
336 TimeDigitizer digitizer(moduleID, pixelID, timeOffset.value, timeOffset.error,
337 timeOffset.windowShift, m_rmsNoise, m_sampleTimes);
338 if (not digitizer.isValid()) continue;
339 unsigned id = digitizer.getUniqueID();
340 Iterator it = pixels.insert(pair<unsigned, TimeDigitizer>(id, digitizer)).first;
341 it->second.addTimeOfHit(time, pulseHeight, hitType, &simHit);
342 }
343
344 // add calibration pulses
345
346 for (const auto& simCalPulses : m_simCalPulses) {
347 auto moduleID = simCalPulses.getModuleID();
348 auto pixelID = simCalPulses.getPixelID();
349 auto pulseHeight = simCalPulses.getAmplitude();
350 auto time = simCalPulses.getTime();
351 auto hitType = TimeDigitizer::c_CalPulse;
352
353 // get time offset for a given pixel
354 auto timeOffset = getTimeOffset(trgTimeOffset, moduleID, pixelID);
355
356 // time range cut (to speed up digitization)
357 if (time + timeOffset.value < timeMin + timeOffset.timeShift) continue;
358 if (time + timeOffset.value > timeMax + timeOffset.timeShift) continue;
359
360 // add time and pulse height to digitizer of a given pixel
361 TimeDigitizer digitizer(moduleID, pixelID, timeOffset.value, timeOffset.error,
362 timeOffset.windowShift, m_rmsNoise, m_sampleTimes);
363 if (not digitizer.isValid()) continue;
364 unsigned id = digitizer.getUniqueID();
365 Iterator it = pixels.insert(pair<unsigned, TimeDigitizer>(id, digitizer)).first;
366 it->second.addTimeOfHit(time, pulseHeight, hitType);
367 }
368
369 // add randomly distributed dark noise (maybe not needed anymore?)
370
371 if (m_darkNoise > 0) {
372 int numModules = geo->getNumModules();
373 for (int moduleID = 1; moduleID <= numModules; moduleID++) {
374 int numPixels = geo->getModule(moduleID).getPMTArray().getNumPixels();
375 int numHits = gRandom->Poisson(m_darkNoise);
376 for (int i = 0; i < numHits; i++) {
377 int pixelID = int(gRandom->Rndm() * numPixels) + 1;
378 double time = (timeMax - timeMin) * gRandom->Rndm() + timeMin;
379 double pulseHeight = generatePulseHeight(moduleID, pixelID);
380 auto hitType = TimeDigitizer::c_Hit;
381 auto timeOffset = getTimeOffset(trgTimeOffset, moduleID, pixelID);
382 time += timeOffset.timeShift;
383 time -= timeOffset.value;
384 TimeDigitizer digitizer(moduleID, pixelID, timeOffset.value, timeOffset.error,
385 timeOffset.windowShift, m_rmsNoise, m_sampleTimes);
386 if (not digitizer.isValid()) continue;
387 unsigned id = digitizer.getUniqueID();
388 Iterator it = pixels.insert(pair<unsigned, TimeDigitizer>(id, digitizer)).first;
389 it->second.addTimeOfHit(time, pulseHeight, hitType);
390 }
391 }
392 }
393
394 // if making waveforms for all channels, add missing digitizers.
395
396 if (m_allChannels) {
397 int numModules = geo->getNumModules();
398 for (int moduleID = 1; moduleID <= numModules; moduleID++) {
399 int numPixels = geo->getModule(moduleID).getPMTArray().getNumPixels();
400 for (int pixelID = 1; pixelID <= numPixels; pixelID++) {
401 auto timeOffset = getTimeOffset(trgTimeOffset, moduleID, pixelID);
402 TimeDigitizer digitizer(moduleID, pixelID, timeOffset.value, timeOffset.error,
403 timeOffset.windowShift, m_rmsNoise, m_sampleTimes);
404 if (not digitizer.isValid()) continue;
405 unsigned id = digitizer.getUniqueID();
406 pixels.insert(pair<unsigned, TimeDigitizer>(id, digitizer));
407 }
408 }
409 }
410
411 // replace equidistant time base with calibrated one if available
412
414 for (auto& pixel : pixels) {
415 auto& digitizer = pixel.second;
416 const auto* sampleTimes = m_timebases->getSampleTimes(digitizer.getScrodID(),
417 digitizer.getChannel());
418 if (not sampleTimes) continue;
419 if (sampleTimes->isCalibrated()) digitizer.setSampleTimes(sampleTimes);
420 }
421 }
422
423 // replace default noise level with channel dependent one if available,
424
425 if (m_useDatabase) {
426 for (auto& pixel : pixels) {
427 auto& digitizer = pixel.second;
428 auto moduleID = digitizer.getModuleID();
429 auto channel = digitizer.getChannel();
430 auto rmsNoise = m_noises->getNoise(moduleID, channel);
431 if (rmsNoise > 0) {
432 digitizer.setNoise(rmsNoise);
433 }
434 }
435 }
436
437 // digitize in time
438
439 for (auto& pixel : pixels) {
440 const auto& digitizer = pixel.second;
441 int threshold = m_threshold;
442 if (m_useDatabase) { // use channel dependent ones
443 threshold = m_thresholds->getThr(digitizer.getModuleID(), digitizer.getChannel());
444 if (threshold <= 0) threshold = m_threshold; // not available, use the default
445 }
446 if (m_useWaveforms) {
447 digitizer.digitize(m_waveforms, m_rawDigits, m_digits,
448 threshold, m_hysteresis, m_thresholdCount);
449 } else {
450 digitizer.digitize(m_rawDigits, m_digits,
452 }
453 }
454
455 // set additional info
456
457 for (auto& rawDigit : m_rawDigits) {
458 rawDigit.setRevo9Counter(revo9cnt);
459 rawDigit.setPhase(phase);
460 rawDigit.setLastWriteAddr(refWindow);
461 rawDigit.setLookBackWindows(lookBackWindows);
462 rawDigit.setOfflineFlag();
463 }
464
465 for (auto& waveform : m_waveforms) {
466 waveform.setRevo9Counter(revo9cnt);
467 waveform.setOffsetWindows(offsetWindows);
468 }
469
470 // set calibration flags
471
472 if (m_useDatabase) {
473 for (auto& digit : m_digits) {
474 if (m_channelT0->isCalibrated(digit.getModuleID(), digit.getChannel())) {
475 digit.addStatus(TOPDigit::c_ChannelT0Calibrated);
476 }
477 if (m_moduleT0->isCalibrated(digit.getModuleID())) {
478 digit.addStatus(TOPDigit::c_ModuleT0Calibrated);
479 }
480 if (m_commonT0->isCalibrated()) {
481 digit.addStatus(TOPDigit::c_CommonT0Calibrated);
482 }
483 }
484 }
485
486 // cut on product of pulse width and height, as for data in TOPRawDigitConverter
487
488 for (auto& digit : m_digits) {
489 if (digit.getPulseWidth() * digit.getPulseHeight() < m_minWidthXheight)
490 digit.setHitQuality(TOPDigit::c_Junk);
491 }
492
493 }
494
495
497 int moduleID,
498 int pixelID)
499 {
500 double timeOffset = trgOffset;
501 double calErrorSq = 0;
502 int winShift = 0;
503 double timeShift = 0;
504 if (m_useDatabase) {
505 const auto& channelMapper = TOPGeometryPar::Instance()->getChannelMapper();
506 auto channel = channelMapper.getChannel(pixelID);
507 if (m_channelT0->isCalibrated(moduleID, channel)) {
508 timeOffset += m_channelT0->getT0(moduleID, channel);
509 double err = m_channelT0->getT0Error(moduleID, channel);
510 calErrorSq += err * err;
511 }
512 auto asic = channel / 8;
513 if (m_asicShift->isCalibrated(moduleID, asic)) {
514 timeOffset += m_asicShift->getT0(moduleID, asic);
515 winShift = lround(m_asicShift->getT0(moduleID, asic) / m_syncTimeBase * 2);
516 timeShift = winShift * m_syncTimeBase / 2;
517 }
518 if (m_moduleT0->isCalibrated(moduleID)) {
519 timeOffset += m_moduleT0->getT0(moduleID);
520 double err = m_moduleT0->getT0Error(moduleID);
521 calErrorSq += err * err;
522 }
523 if (m_commonT0->isCalibrated()) {
524 timeOffset += m_commonT0->getT0();
525 double err = m_commonT0->getT0Error();
526 calErrorSq += err * err;
527 }
528 }
529 return TimeOffset(timeOffset, calErrorSq, winShift, timeShift);
530 }
531
532
533 double TOPDigitizerModule::generatePulseHeight(int moduleID, int pixelID) const
534 {
535 if (m_useDatabase) {
536 const auto& channelMapper = TOPGeometryPar::Instance()->getChannelMapper();
537 auto channel = channelMapper.getChannel(pixelID);
538 if (m_pulseHeights->isCalibrated(moduleID, channel)) {
539 const auto& par = m_pulseHeights->getParameters(moduleID, channel);
540 PulseHeightGenerator generator(par.x0, par.p1, par.p2, m_ADCmax);
541 return generator.generate();
542 }
543 }
544
546 }
547
549} // end Belle2 namespace
550
@ c_DontWriteOut
Object/array should be NOT saved by output modules.
Definition: DataStore.h:71
@ c_Event
Different object in each event, all objects/arrays are invalidated after event() function has been ca...
Definition: DataStore.h:59
Base class for Modules.
Definition: Module.h:72
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition: Module.cc:208
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Definition: Module.h:80
bool isOptional(const std::string &name="")
Tell the DataStore about an optional input.
Type-safe access to single objects in the data store.
Definition: StoreObjPtr.h:96
static void setDoubleHitResolution(double time)
Sets double hit resolution.
Definition: TOPDigit.h:87
static void setPileupTime(double time)
Sets pile-up time.
Definition: TOPDigit.h:93
double m_ADCx0
pulse height distribution parameter [ADC counts]
StoreArray< TOPRawWaveform > m_waveforms
collection of waveforms
double m_electronicJitter
r.m.s of electronic jitter
StoreArray< TOPRawDigit > m_rawDigits
collection of raw digits
int m_lookBackWindows
number of "look back" windows
DBObjPtr< TOPCalAsicShift > m_asicShift
ASIC shifts calibration constants.
DBObjPtr< TOPFrontEndSetting > m_feSetting
front-end settings
double m_rmsNoise
r.m.s of noise [ADC counts]
int m_hysteresis
pulse height threshold hysteresis [ADC counts]
DBObjPtr< TOPCalCommonT0 > m_commonT0
common T0 calibration constants
TOP::PulseHeightGenerator m_pulseHeightGenerator
default generator
bool m_useSampleTimeCalibration
if true, use time base calibration
StoreArray< TOPSimCalPulse > m_simCalPulses
collection of simuated cal pulses
double m_timeZeroJitter
r.m.s of T0 jitter
double m_ADCmax
pulse height upper bound of range [ADC counts]
bool m_simulateTTS
if true, add TTS to simulated hits
double m_ADCp2
pulse height distribution parameter, must be positive
DBObjPtr< TOPCalChannelT0 > m_channelT0
channel T0 calibration constants
bool m_allChannels
if true, always make waveforms for all channels
int m_threshold
pulse height threshold [ADC counts]
DBObjPtr< TOPCalChannelNoise > m_noises
channel noise levels (r.m.s)
double m_ADCp1
pulse height distribution parameter, must be non-negative
double m_syncTimeBase
SSTin period.
bool m_useWaveforms
if true, use full waveform digitization
OptionalDBObjPtr< TOPCalTimeWalk > m_timeWalk
time-walk calibration constants
DBObjPtr< TOPCalChannelThreshold > m_thresholds
channel thresholds
DBObjPtr< TOPCalTimebase > m_timebases
sample times from database
StoreArray< TOPDigit > m_digits
collection of digits
DBObjPtr< TOPCalModuleT0 > m_moduleT0
module T0 calibration constants
int m_thresholdCount
minimal number of samples above threshold
StoreArray< MCParticle > m_mcParticles
collection of MC particles
bool m_useDatabase
if true, use calibration constants from database
double m_minWidthXheight
minimal width * height [ns * ADC counts]
DBObjPtr< TOPCalChannelPulseHeight > m_pulseHeights
pulse height param.
double m_darkNoise
uniform dark noise (hits per bar)
StoreObjPtr< SimClockState > m_simClockState
generated hardware clock state
StoreArray< TOPSimHit > m_simHits
collection of simuated hits
TOPSampleTimes m_sampleTimes
equidistant sample times
const TOPSignalShape & getSignalShape() const
Returns single photon signal shape.
Definition: TOPGeometry.h:224
double getTMin() const
Returns time of the first waveform sample.
Generates pulse height according to distribution: P(x) = (x/x0)^p1 * exp(-(x/x0)^p2),...
double generate() const
Returns generated pulse height.
const TOPGeometry * getGeometry() const
Returns pointer to geometry object using basf2 units.
const ChannelMapper & getChannelMapper() const
Returns default channel mapper (mapping of channels to pixels)
static TOPGeometryPar * Instance()
Static method to obtain the pointer to its instance.
const FrontEndMapper & getFrontEndMapper() const
Returns front-end mapper (mapping of SCROD's to positions within TOP modules)
const TOPNominalTTS & getTTS(int moduleID, int pmtID) const
Returns TTS of a PMT at given position.
Time digitization of simulated hits in a single electronic channel.
Definition: TimeDigitizer.h:33
static void setReadoutWindows(unsigned numWin)
Sets the number of readout windows.
Definition: TimeDigitizer.h:80
static void maskSamples(bool maskThem)
Mask samples at the end of a window to emulate phase-2 data.
Definition: TimeDigitizer.h:98
static void setStorageDepth(unsigned storageDepth)
Sets storage depth.
Definition: TimeDigitizer.h:74
static void setTimeWalk(DBObjPtr< TOPCalTimeWalk > *timeWalk)
Stores pointer to time walk DB object defined in TOPDigitizerModule.
static void setOffsetWindows(int offsetWin)
Sets the number of windows before the first ASIC window.
Definition: TimeDigitizer.h:86
static void setFirstWindow(unsigned window)
Sets first ASIC window.
Definition: TimeDigitizer.h:92
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition: Module.h:560
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
double generatePulseHeight(int moduleID, int pixelID) const
Generates and returns pulse height.
virtual void initialize() override
Initialize the Module.
virtual void event() override
Event processor.
TimeOffset getTimeOffset(double trgOffset, int moduleID, int pixelID)
Returns a complete time offset by adding time mis-calibration to trgOffset.
virtual void beginRun() override
Called when entering a new run.
map< unsigned, size_t >::const_iterator Iterator
Iteratior for m_map.
void setTimeAxis(double syncTimeBase)
Sets equidistant time axis (uncalibrated).
Abstract base class for different kinds of events.
STL namespace.
Utility structure for time offset.