10#include <top/modules/TOPRawDigitConverter/TOPRawDigitConverterModule.h>
13#include <framework/datastore/StoreArray.h>
14#include <framework/datastore/StoreObjPtr.h>
17#include <framework/logging/Logger.h>
20#include <top/dataobjects/TOPRawDigit.h>
21#include <top/dataobjects/TOPRawWaveform.h>
22#include <top/dataobjects/TOPDigit.h>
23#include <framework/dataobjects/EventMetaData.h>
25#include <top/geometry/TOPGeometryPar.h>
52 setDescription(
"Converts row digits to digits and applies time calibration");
57 "name of TOPRawDigit store array",
string(
""));
59 "name of TOPDigit store array",
string(
""));
61 "if true, use sample time calibration",
true);
63 "if true, use ASIC shifts calibration",
true);
65 "if true, use channel T0 calibration",
true);
67 "if true, use module T0 calibration",
true);
69 "if true, use common T0 calibration",
true);
71 "if true, use time-walk calibration",
true);
73 "r.m.s of pedestals [ADC counts], "
74 "if positive, timeError will be estimated from FE data. "
75 "This is the default value used if r.m.s is not available from DB.", 9.7);
77 "minimal pulse width [ns] to flag digit as good", 1.0);
79 "maximal pulse width [ns] to flag digit as good", 10.0);
81 "minimal product of width and height [ns * ADC counts]", 100.0);
83 "ASIC analog storage depth of Interim FE format (ignored in other formats)",
86 "number of look back windows, if positive override the number from database",
89 "if true, set (override) phase in TOPRawDigits",
true);
91 "calpulse selection: ASIC channel (use -1 to turn off the selection)", -1);
93 "calpulse selection: minimal width [ns]", 0.0);
95 "calpulse selection: maximal width [ns]", 0.0);
97 "calpulse selection: minimal height [ADC counts]", 0);
99 "calpulse selection: maximal height [ADC counts]", 0);
101 "calpulse selection (ON if max > min): minimal time [ns]", 0.0);
103 "calpulse selection (ON if max > min): maximal time [ns]", 0.0);
141 B2FATAL(
"Sample time calibration requested but not available for run "
142 << evtMetaData->getRun()
143 <<
" of experiment " << evtMetaData->getExperiment());
148 B2FATAL(
"Channel T0 calibration requested but not available for run "
149 << evtMetaData->getRun()
150 <<
" of experiment " << evtMetaData->getExperiment());
155 B2FATAL(
"ASIC shifts calibration requested but not available for run "
156 << evtMetaData->getRun()
157 <<
" of experiment " << evtMetaData->getExperiment());
162 B2FATAL(
"Module T0 calibration requested but not available for run "
163 << evtMetaData->getRun()
164 <<
" of experiment " << evtMetaData->getExperiment());
169 B2FATAL(
"Common T0 calibration requested but not available for run "
170 << evtMetaData->getRun()
171 <<
" of experiment " << evtMetaData->getExperiment());
176 B2WARNING(
"Time-walk calibration is not available for run "
177 << evtMetaData->getRun()
178 <<
" of experiment " << evtMetaData->getExperiment());
181 B2FATAL(
"Channel noise levels are not available for run "
182 << evtMetaData->getRun()
183 <<
" of experiment " << evtMetaData->getExperiment());
187 B2FATAL(
"Front-end settings are not available for run "
188 << evtMetaData->getRun()
189 <<
" of experiment " << evtMetaData->getExperiment());
212 if (waveform and rawDigit.getStorageWindows().empty()) {
221 std::vector<unsigned short> masks(64, 0xFFFF);
223 auto scrodID = eventDebug.getScrodID();
224 const auto* feemap = feMapper.getMap(scrodID);
226 B2WARNING(
"TOPRawDigitConverter: No front-end map available."
227 <<
LogVar(
"scrodID", scrodID));
230 auto moduleID = feemap->getModuleID();
231 auto boardstack = feemap->getBoardstackNumber();
232 unsigned bs = (moduleID - 1) * 4 + boardstack;
234 masks[bs] = eventDebug.getAsicMask();
236 B2ERROR(
"TOPRawDigitConverter: Invalid global boardstack number."
247 if (rawDigit.getErrorFlags() != 0)
continue;
251 auto scrodID = rawDigit.getScrodID();
252 const auto* feemap = feMapper.getMap(scrodID);
254 B2WARNING(
"TOPRawDigitConverter: No front-end map available."
255 <<
LogVar(
"scrodID", scrodID));
258 auto moduleID = feemap->getModuleID();
259 auto boardstack = feemap->getBoardstackNumber();
260 auto channel = chMapper.getChannel(boardstack,
261 rawDigit.getCarrierNumber(),
262 rawDigit.getASICNumber(),
263 rawDigit.getASICChannel());
264 auto pixelID = chMapper.getPixelID(channel);
268 double rawTimeLeading = rawDigit.getCFDLeadingTime();
269 double rawTimeFalling = rawDigit.getCFDFallingTime();
273 int window = rawDigit.getASICWindow();
277 double timeOffset = 0;
282 rawTimeLeading = rawDigit.correctTime(rawTimeLeading,
m_storageDepth);
283 rawTimeFalling = rawDigit.correctTime(rawTimeFalling,
m_storageDepth);
286 int lastWriteAddr = rawDigit.getLastWriteAddr();
287 int nback = lastWriteAddr - window;
289 int lookBackWindows =
m_feSetting->getLookbackWindows();
291 int nwin = lookBackWindows - nback;
302 int revo9cnt = rawDigit.getRevo9Counter();
303 int SSTcnt = revo9cnt / 6;
304 double SSTfrac = (revo9cnt % 6) / 6.0;
309 int refWindow = SSTcnt * 2;
310 const auto& writeDepths =
m_feSetting->getWriteDepths();
311 if (writeDepths.empty()) {
312 B2ERROR(
"TOPRawDigitConverter: vector of write depths is empty. Return!");
315 int lastDepth = writeDepths.back();
317 for (
auto depth : writeDepths) {
319 if (SSTcnt < 0)
break;
321 refWindow = SSTcnt * 2;
325 storageDepth = lastDepth * 2;
327 if (window >= storageDepth) {
328 B2WARNING(
"TOPRawDigitConverter: window number greater than storage depth."
329 <<
LogVar(
"window number", window)
330 <<
LogVar(
"storage depth", storageDepth)
331 <<
LogVar(
"refWindow", refWindow)
332 <<
LogVar(
"phase", phase));
337 int deltaWindow = window - refWindow;
338 if (deltaWindow > 0) deltaWindow -= storageDepth;
339 int lookBackWindows =
m_feSetting->getLookbackWindows();
343 int nwin = lookBackWindows + deltaWindow;
344 int startWindow = refWindow - lookBackWindows;
345 if (startWindow < 0) startWindow += storageDepth;
346 window = startWindow;
355 unsigned short statusBits = 0;
358 sampleTimes =
m_timebase->getSampleTimes(scrodID, channel % 128);
359 if (sampleTimes->isCalibrated()) {
360 statusBits |= TOPDigit::c_TimeBaseCalibrated;
364 double time = sampleTimes->getTime(window, rawTimeLeading) - timeOffset;
365 double width = sampleTimes->getDeltaTime(window, rawTimeFalling, rawTimeLeading);
368 double timeError = geo->getNominalTDC().getTimeJitter();
372 time -= geo->getNominalTDC().getOffset();
373 statusBits |= TOPDigit::c_OffsetSubtracted;
378 if (
m_noises->isCalibrated(moduleID, channel)) {
379 rmsNoise =
m_noises->getNoise(moduleID, channel);
381 double rawErr = rawDigit.getCFDLeadingTimeError(rmsNoise);
382 int sample =
static_cast<int>(rawTimeLeading);
383 if (rawTimeLeading < 0) sample--;
384 timeError = rawErr * sampleTimes->getTimeBin(window, sample);
387 auto pulseHeight = rawDigit.getValuePeak();
388 double timeErrorSq = timeError * timeError;
398 if (cal->isCalibrated(moduleID, channel)) {
399 time -= cal->getT0(moduleID, channel);
400 double err = cal->getT0Error(moduleID, channel);
401 timeErrorSq += err * err;
402 statusBits |= TOPDigit::c_ChannelT0Calibrated;
406 auto asic = channel / 8;
413 if (cal->isCalibrated(moduleID)) {
414 time -= cal->getT0(moduleID);
415 double err = cal->getT0Error(moduleID);
416 timeErrorSq += err * err;
417 statusBits |= TOPDigit::c_ModuleT0Calibrated;
422 if (cal->isCalibrated()) {
423 time -= cal->getT0();
424 double err = cal->getT0Error();
425 timeErrorSq += err * err;
426 statusBits |= TOPDigit::c_CommonT0Calibrated;
429 timeError =
sqrt(timeErrorSq);
434 auto* digit =
m_digits.appendNew(moduleID, pixelID, rawTimeLeading);
435 digit->setTime(time);
436 digit->setTimeError(timeError);
437 digit->setPulseHeight(rawDigit.getValuePeak());
438 digit->setIntegral(rawDigit.getIntegral());
439 digit->setPulseWidth(width);
440 digit->setChannel(channel);
441 digit->setFirstWindow(window);
442 digit->setStatus(statusBits);
445 if (not rawDigit.isFEValid() or rawDigit.isPedestalJump())
446 digit->setHitQuality(TOPDigit::c_Junk);
447 if (rawDigit.isAtWindowDiscontinuity(storageDepth))
448 digit->setHitQuality(TOPDigit::c_Junk);
452 digit->setHitQuality(TOPDigit::c_Junk);
458 if (calibrationChannel < 8) {
460 if (digit.getHitQuality() != TOPDigit::c_Good)
continue;
461 if (digit.getASICChannel() != calibrationChannel)
continue;
470 digit.setHitQuality(TOPDigit::c_CalPulse);
void setDescription(const std::string &description)
Sets the description of the module.
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Type-safe access to single objects in the data store.
double m_pedestalRMS
r.m.s of pedestals [ADC counts]
StoreArray< TOPRawDigit > m_rawDigits
collection of raw digits
DBObjPtr< TOPCalTimebase > m_timebase
sample time calibration constants
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_maxPulseWidth
max pulse width to set digit as good [ns]
int m_calpulseHeightMax
maximal height of calibration pulse
double m_calpulseWidthMax
maximal width of calibration pulse
DBObjPtr< TOPCalCommonT0 > m_commonT0
common T0 calibration constants
bool m_useAsicShiftCalibration
if true, use asic shifts calibration
double m_minPulseWidth
min pulse width to set digit as good [ns]
bool m_useSampleTimeCalibration
if true, use sample time calibration
DBObjPtr< TOPCalChannelT0 > m_channelT0
channel T0 calibration constants
bool m_useTimeWalkCalibration
if true, use time-walk calibration
DBObjPtr< TOPCalChannelNoise > m_noises
r.m.s.
double m_syncTimeBase
SSTin period.
StoreArray< TOPProductionEventDebug > m_eventDebugs
collection of debug data
double m_calpulseTimeMin
minimal time of calibration pulse
int m_calpulseHeightMin
minimal height of calibration pulse
std::string m_outputDigitsName
name of TOPDigit store array
std::string m_inputRawDigitsName
name of TOPRawDigit store array
OptionalDBObjPtr< TOPCalTimeWalk > m_timeWalk
time-walk calibration constants
bool m_useChannelT0Calibration
if true, use channel T0 calibration
bool m_useCommonT0Calibration
if true, use common T0 calibration
bool m_useModuleT0Calibration
if true, use module T0 calibration
StoreArray< TOPDigit > m_digits
collection of digits
DBObjPtr< TOPCalModuleT0 > m_moduleT0
module T0 calibration constants
int m_calibrationChannel
ASIC channel number with calibration pulse.
double m_calpulseWidthMin
minimal width of calibration pulse
double m_minWidthXheight
minimal width * height [ns * ADC counts]
StoreObjPtr< TOPAsicMask > m_asicMask
masked asics in firmware
bool m_setPhase
if true, set phase in TOPRawDigits
double m_calpulseTimeMax
maximal time of calibration pulse
bool m_addRelations
switch ON/OFF relations to TOPRawDigits
TOPSampleTimes m_sampleTimes
equidistant in case no calibration required
unsigned m_storageDepth
ASIC analog storage depth.
Class to store unpacked raw data (hits in feature-extraction format) It provides also calculation of ...
@ c_Interim
from interim feature extraction
@ c_ProductionDebug
from production debugging format
@ c_MC
from MC digitization
@ c_WindowSize
number of samples per window
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)
Class to store variables with their name which were sent to the logging service.
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
double sqrt(double a)
sqrt for double
virtual void initialize() override
Initialize the Module.
virtual void event() override
Event processor.
virtual ~TOPRawDigitConverterModule()
Destructor.
virtual void endRun() override
End-of-run action.
virtual void terminate() override
Termination action.
virtual void beginRun() override
Called when entering a new run.
TOPRawDigitConverterModule()
Constructor.
void setTimeAxis(double syncTimeBase)
Sets equidistant time axis (uncalibrated).
Abstract base class for different kinds of events.