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 {
36
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();
108 m_mcParticles.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 {
205 B2FATAL("Time-walk parameters requested but not available for run "
206 << evtMetaData->getRun()
207 << " of experiment " << evtMetaData->getExperiment());
208 }
209 if (not m_calPrecision.isValid()) {
210 B2FATAL("Calibration precision requested but not available for run "
211 << evtMetaData->getRun()
212 << " of experiment " << evtMetaData->getExperiment());
213 }
214 } else if (m_useSampleTimeCalibration) {
215 if (not m_timebases.isValid()) {
216 B2FATAL("Sample time calibration constants requested but not available for run "
217 << evtMetaData->getRun()
218 << " of experiment " << evtMetaData->getExperiment());
219 }
220 }
221
222 // check availability of front-end settings
223 if (not m_feSetting.isValid()) {
224 B2FATAL("Front-end settings are not available for run "
225 << evtMetaData->getRun()
226 << " of experiment " << evtMetaData->getExperiment());
227 }
228
229 // pass a parameter to TimeDigitizer
230 TimeDigitizer::setReadoutWindows(m_feSetting->getReadoutWindows());
231 if ((evtMetaData->getExperiment() > 0 and evtMetaData->getExperiment() < 5) or
232 evtMetaData->getExperiment() == 1002) {
233 TimeDigitizer::maskSamples(true); // phase-2: mask samples at window boundaries
234 } else {
235 TimeDigitizer::maskSamples(false); // phase-3: no masking
236 }
237
238 }
239
241 {
242
243 // get or generate revo9 count
244 unsigned revo9cnt = 0;
245 if (m_simClockState.isValid()) {
246 revo9cnt = m_simClockState->getRevo9Count();
247 } else {
248 revo9cnt = gRandom->Integer(11520);
249 }
250
251 // from revo9 count determine trigger time offset and the number of offset windows
252 double SSTfrac = (revo9cnt % 6) / 6.0;
253 double offset = m_feSetting->getOffset() / 24.0;
254 double trgTimeOffset = (SSTfrac + offset) * m_syncTimeBase; // in [ns]
255 int offsetWindows = m_feSetting->getWindowShift(revo9cnt);
256 TimeDigitizer::setOffsetWindows(offsetWindows);
257
258 // from revo9 and write depths determine reference window, phase and storage depth
259 int SSTcnt = revo9cnt / 6;
260 int refWindow = SSTcnt * 2; // same as lastWriteAddr
261 const auto& writeDepths = m_feSetting->getWriteDepths();
262 if (writeDepths.empty()) {
263 B2ERROR("TOPDigitzer: vector of write depths is empty. No digitization possible");
264 return;
265 }
266 int lastDepth = writeDepths.back();
267 unsigned phase = 0;
268 for (auto depth : writeDepths) {
269 SSTcnt -= depth;
270 if (SSTcnt < 0) break;
271 phase++;
272 refWindow = SSTcnt * 2;
273 lastDepth = depth;
274 }
275 unsigned storageDepth = lastDepth * 2;
276 TimeDigitizer::setStorageDepth(storageDepth);
277
278 // from reference window and lookback determine first of the readout windows
279 int lookBackWindows = m_feSetting->getLookbackWindows();
280 if (m_lookBackWindows > 0) lookBackWindows = m_lookBackWindows;
281 lookBackWindows -= m_feSetting->getExtraWindows();
282 int window = refWindow - lookBackWindows;
283 if (window < 0) window += storageDepth;
285
286 // geometry and nominal data
287 const auto* geo = TOPGeometryPar::Instance()->getGeometry();
288
289 // time range for digitization
290 double timeMin = geo->getSignalShape().getTMin() + offsetWindows * m_syncTimeBase / 2;
291 double timeMax = geo->getSignalShape().getTMax() +
292 (m_feSetting->getReadoutWindows() + offsetWindows) * m_syncTimeBase / 2;
293
294 // simulate start time jitter
295 double startTimeJitter = gRandom->Gaus(0, m_timeZeroJitter);
296
297 // get electronic efficiency
298 double electronicEfficiency = geo->getNominalTDC().getEfficiency();
299
300 // define pixels with time digitizers
301 std::map<unsigned, TimeDigitizer> pixels;
302 typedef std::map<unsigned, TimeDigitizer>::iterator Iterator;
303
304 // add simulated hits to time digitizers
305
306 for (const auto& simHit : m_simHits) {
307 if (not m_useWaveforms) {
308 // simulate electronic efficiency
309 if (gRandom->Rndm() > electronicEfficiency) continue;
310 }
311 // do spatial digitization
312 double x = simHit.getX();
313 double y = simHit.getY();
314 int pmtID = simHit.getPmtID();
315 int moduleID = simHit.getModuleID();
316 if (not geo->isModuleIDValid(moduleID)) continue;
317 int pixelID = geo->getModule(moduleID).getPMTArray().getPixelID(x, y, pmtID);
318 if (pixelID == 0) continue;
319
320 // add start time jitter and generated TTS to photon time
321 double time = simHit.getTime() + startTimeJitter;
322 if (m_simulateTTS) {
323 const auto& tts = TOPGeometryPar::Instance()->getTTS(moduleID, pmtID);
324 time += tts.generateTTS();
325 }
326
327 // get time offset for a given pixel
328 auto timeOffset = getTimeOffset(trgTimeOffset, moduleID, pixelID, true);
329
330 // time range cut (to speed up digitization)
331 if (time + timeOffset.value < timeMin + timeOffset.timeShift) continue;
332 if (time + timeOffset.value > timeMax + timeOffset.timeShift) continue;
333
334 // generate pulse height
335 double pulseHeight = generatePulseHeight(moduleID, pixelID);
336 auto hitType = TimeDigitizer::c_Hit;
337
338 // add time and pulse height to digitizer of a given pixel
339 TimeDigitizer digitizer(moduleID, pixelID, timeOffset.value, timeOffset.error,
340 timeOffset.windowShift, m_rmsNoise, m_sampleTimes);
341 if (not digitizer.isValid()) continue;
342 unsigned id = digitizer.getUniqueID();
343 Iterator it = pixels.insert(pair<unsigned, TimeDigitizer>(id, digitizer)).first;
344 it->second.addTimeOfHit(time, pulseHeight, hitType, &simHit);
345 }
346
347 // add calibration pulses
348
349 for (const auto& simCalPulses : m_simCalPulses) {
350 auto moduleID = simCalPulses.getModuleID();
351 auto pixelID = simCalPulses.getPixelID();
352 auto pulseHeight = simCalPulses.getAmplitude();
353 auto time = simCalPulses.getTime();
354 auto hitType = TimeDigitizer::c_CalPulse;
355
356 // get time offset for a given pixel
357 auto timeOffset = getTimeOffset(trgTimeOffset, moduleID, pixelID);
358
359 // time range cut (to speed up digitization)
360 if (time + timeOffset.value < timeMin + timeOffset.timeShift) continue;
361 if (time + timeOffset.value > timeMax + timeOffset.timeShift) continue;
362
363 // add time and pulse height to digitizer of a given pixel
364 TimeDigitizer digitizer(moduleID, pixelID, timeOffset.value, timeOffset.error,
365 timeOffset.windowShift, m_rmsNoise, m_sampleTimes);
366 if (not digitizer.isValid()) continue;
367 unsigned id = digitizer.getUniqueID();
368 Iterator it = pixels.insert(pair<unsigned, TimeDigitizer>(id, digitizer)).first;
369 it->second.addTimeOfHit(time, pulseHeight, hitType);
370 }
371
372 // add randomly distributed dark noise (maybe not needed anymore?)
373
374 if (m_darkNoise > 0) {
375 int numModules = geo->getNumModules();
376 for (int moduleID = 1; moduleID <= numModules; moduleID++) {
377 int numPixels = geo->getModule(moduleID).getPMTArray().getNumPixels();
378 int numHits = gRandom->Poisson(m_darkNoise);
379 for (int i = 0; i < numHits; i++) {
380 int pixelID = int(gRandom->Rndm() * numPixels) + 1;
381 double time = (timeMax - timeMin) * gRandom->Rndm() + timeMin;
382 double pulseHeight = generatePulseHeight(moduleID, pixelID);
383 auto hitType = TimeDigitizer::c_Hit;
384 auto timeOffset = getTimeOffset(trgTimeOffset, moduleID, pixelID);
385 time += timeOffset.timeShift;
386 time -= timeOffset.value;
387 TimeDigitizer digitizer(moduleID, pixelID, timeOffset.value, timeOffset.error,
388 timeOffset.windowShift, m_rmsNoise, m_sampleTimes);
389 if (not digitizer.isValid()) continue;
390 unsigned id = digitizer.getUniqueID();
391 Iterator it = pixels.insert(pair<unsigned, TimeDigitizer>(id, digitizer)).first;
392 it->second.addTimeOfHit(time, pulseHeight, hitType);
393 }
394 }
395 }
396
397 // if making waveforms for all channels, add missing digitizers.
398
399 if (m_allChannels) {
400 int numModules = geo->getNumModules();
401 for (int moduleID = 1; moduleID <= numModules; moduleID++) {
402 int numPixels = geo->getModule(moduleID).getPMTArray().getNumPixels();
403 for (int pixelID = 1; pixelID <= numPixels; pixelID++) {
404 auto timeOffset = getTimeOffset(trgTimeOffset, moduleID, pixelID);
405 TimeDigitizer digitizer(moduleID, pixelID, timeOffset.value, timeOffset.error,
406 timeOffset.windowShift, m_rmsNoise, m_sampleTimes);
407 if (not digitizer.isValid()) continue;
408 unsigned id = digitizer.getUniqueID();
409 pixels.insert(pair<unsigned, TimeDigitizer>(id, digitizer));
410 }
411 }
412 }
413
414 // replace equidistant time base with calibrated one if available
415
417 for (auto& pixel : pixels) {
418 auto& digitizer = pixel.second;
419 const auto* sampleTimes = m_timebases->getSampleTimes(digitizer.getScrodID(),
420 digitizer.getChannel());
421 if (not sampleTimes) continue;
422 if (sampleTimes->isCalibrated()) digitizer.setSampleTimes(sampleTimes);
423 }
424 }
425
426 // replace default noise level with channel dependent one if available,
427
428 if (m_useDatabase) {
429 for (auto& pixel : pixels) {
430 auto& digitizer = pixel.second;
431 auto moduleID = digitizer.getModuleID();
432 auto channel = digitizer.getChannel();
433 auto rmsNoise = m_noises->getNoise(moduleID, channel);
434 if (rmsNoise > 0) {
435 digitizer.setNoise(rmsNoise);
436 }
437 }
438 }
439
440 // digitize in time
441
442 for (const auto& pixel : pixels) {
443 const auto& digitizer = pixel.second;
444 int threshold = m_threshold;
445 if (m_useDatabase) { // use channel dependent ones
446 threshold = m_thresholds->getThr(digitizer.getModuleID(), digitizer.getChannel());
447 if (threshold <= 0) threshold = m_threshold; // not available, use the default
448 }
449 if (m_useWaveforms) {
450 digitizer.digitize(m_waveforms, m_rawDigits, m_digits,
451 threshold, m_hysteresis, m_thresholdCount);
452 } else {
453 digitizer.digitize(m_rawDigits, m_digits,
455 }
456 }
457
458 // set additional info
459
460 for (auto& rawDigit : m_rawDigits) {
461 rawDigit.setRevo9Counter(revo9cnt);
462 rawDigit.setPhase(phase);
463 rawDigit.setLastWriteAddr(refWindow);
464 rawDigit.setLookBackWindows(lookBackWindows);
465 rawDigit.setOfflineFlag();
466 }
467
468 for (auto& waveform : m_waveforms) {
469 waveform.setRevo9Counter(revo9cnt);
470 waveform.setOffsetWindows(offsetWindows);
471 }
472
473 // set calibration flags
474
475 if (m_useDatabase) {
476 for (auto& digit : m_digits) {
477 if (m_channelT0->isCalibrated(digit.getModuleID(), digit.getChannel())) {
478 digit.addStatus(TOPDigit::c_ChannelT0Calibrated);
479 }
480 if (m_moduleT0->isCalibrated(digit.getModuleID())) {
481 digit.addStatus(TOPDigit::c_ModuleT0Calibrated);
482 }
483 if (m_commonT0->isCalibrated()) {
484 digit.addStatus(TOPDigit::c_CommonT0Calibrated);
485 }
486 }
487 }
488
489 // cut on product of pulse width and height, as for data in TOPRawDigitConverter
490
491 for (auto& digit : m_digits) {
492 if (digit.getPulseWidth() * digit.getPulseHeight() < m_minWidthXheight)
493 digit.setHitQuality(TOPDigit::c_Junk);
494 }
495
496 }
497
498
499 TOPDigitizerModule::TimeOffset TOPDigitizerModule::getTimeOffset(double trgOffset, int moduleID, int pixelID, bool generate)
500 {
501 double timeOffset = trgOffset;
502 double calErrorSq = 0;
503 int winShift = 0;
504 double timeShift = 0;
505 if (m_useDatabase) {
506 const auto& channelMapper = TOPGeometryPar::Instance()->getChannelMapper();
507 auto channel = channelMapper.getChannel(pixelID);
508 if (m_channelT0->isCalibrated(moduleID, channel)) {
509 timeOffset += m_channelT0->getT0(moduleID, channel);
510 double err = m_channelT0->getT0Error(moduleID, channel); // statistics from laser data fit
511 double sys = m_calPrecision->get(moduleID); // systematics from di-muon events (this is dominant)
512 if (generate and sys > 0) timeOffset += gRandom->Gaus(0, sys);
513 calErrorSq += err * err + sys * sys;
514 }
515 auto asic = channel / 8;
516 if (m_asicShift->isCalibrated(moduleID, asic)) {
517 timeOffset += m_asicShift->getT0(moduleID, asic);
518 winShift = lround(m_asicShift->getT0(moduleID, asic) / m_syncTimeBase * 2);
519 timeShift = winShift * m_syncTimeBase / 2;
520 }
521 if (m_moduleT0->isCalibrated(moduleID)) {
522 timeOffset += m_moduleT0->getT0(moduleID);
523 double err = m_moduleT0->getT0Error(moduleID);
524 calErrorSq += err * err;
525 }
526 if (m_commonT0->isCalibrated()) {
527 timeOffset += m_commonT0->getT0();
528 double err = m_commonT0->getT0Error();
529 calErrorSq += err * err;
530 }
531 }
532 return TimeOffset(timeOffset, calErrorSq, winShift, timeShift);
533 }
534
535
536 double TOPDigitizerModule::generatePulseHeight(int moduleID, int pixelID) const
537 {
538 if (m_useDatabase) {
539 const auto& channelMapper = TOPGeometryPar::Instance()->getChannelMapper();
540 auto channel = channelMapper.getChannel(pixelID);
541 if (m_pulseHeights->isCalibrated(moduleID, channel)) {
542 const auto& par = m_pulseHeights->getParameters(moduleID, channel);
543 PulseHeightGenerator generator(par.x0, par.p1, par.p2, m_ADCmax);
544 return generator.generate();
545 }
546 }
547
548 return m_pulseHeightGenerator.generate();
549 }
550
552} // end Belle2 namespace
553
@ 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
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
Module()
Constructor.
Definition Module.cc:30
@ 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
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 simulated 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.
DBObjPtr< TOPCalPrecision > m_calPrecision
calibration precision constants (systematics of channel T0)
DBObjPtr< TOPCalTimeWalk > m_timeWalk
time-walk calibration constants
bool m_useWaveforms
if true, use full waveform digitization
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 simulated hits
TOPSampleTimes m_sampleTimes
equidistant sample times
const TOPSignalShape & getSignalShape() const
Returns single photon signal shape.
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),...
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.
static void setReadoutWindows(unsigned numWin)
Sets the number of readout windows.
static void maskSamples(bool maskThem)
Mask samples at the end of a window to emulate phase-2 data.
static void setStorageDepth(unsigned storageDepth)
Sets storage depth.
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.
static void setFirstWindow(unsigned window)
Sets first ASIC window.
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:559
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition Module.h:649
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, bool generate=false)
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
Iterator for m_map.
Abstract base class for different kinds of events.
STL namespace.
Utility structure for time offset.