10#include <top/modules/TOPDoublePulseGenerator/TOPDoublePulseGeneratorModule.h>
13#include <top/geometry/TOPGeometryPar.h>
16#include <framework/datastore/StoreArray.h>
17#include <framework/datastore/StoreObjPtr.h>
20#include <framework/logging/Logger.h>
23#include <framework/dataobjects/EventMetaData.h>
24#include <top/dataobjects/TOPDigit.h>
61 "list of slots for which to generate cal pulse, empty list means all slots.",
65 "ASIC calibration channels (0 - 7), empty list means all channels.",
68 "time difference between first and second pulse [ns].", 21.87);
70 "sigma of time difference [ns].", 40.0e-3);
72 "vector of 256 sample time intervals to construct sample times. "
75 "if true, use sample times from database instead of sampleTimeIntervals.",
78 "number of storage windows (old FW used 64 out of 512)", (
unsigned) 512);
80 "if given, sample times will be saved as root histograms in this file",
90 digits.registerInDataStore();
97 for (
const auto& module : geo->getModules()) {
102 if (!geo->isModuleIDValid(moduleID))
103 B2ERROR(
"Invalid module ID found in input list: " << moduleID);
112 B2ERROR(
"Invalid ASIC channel found in input list: " << ch);
123 B2INFO(
"TOPDoublePulseGenerator: using sample times from database");
125 B2INFO(
"TOPDoublePulseGenerator: using equidistant sample times");
127 std::vector<double> timeAxis;
128 timeAxis.push_back(0);
130 double rescale = 2 * syncTimeBase / timeAxis.back();
131 for (
auto& t : timeAxis) t *= rescale;
133 B2INFO(
"TOPDoublePulseGenerator: using sample times from steering");
135 B2ERROR(
"sampleTimeIntervals: size must be 256 or empty");
148 B2FATAL(
"Sample time calibration requested but not available for run "
149 << evtMetaData->getRun()
150 <<
" of experiment " << evtMetaData->getExperiment());
168 for (
unsigned asic = 0; asic < 64; asic++) {
171 auto pixelID = chMapper.getPixelID(channel);
176 unsigned scrodID = 0;
178 const auto* feMap = feMapper.getMap(moduleID, bs);
179 if (feMap) scrodID = feMap->getScrodID();
180 sampleTimes =
m_timebase->getSampleTimes(scrodID, channel % 128);
182 B2WARNING(
"No sample time calibration available for SCROD " << scrodID
183 <<
" channel " << channel % 128 <<
" - equidistant will be used");
188 double time = gRandom->Rndm() * sampleTimes->
getTimeRange();
190 double sample = sampleTimes->
getSample(window, time);
191 auto* digit = digits.appendNew(moduleID, pixelID, sample);
192 digit->setFirstWindow(window);
193 digit->setTime(time);
194 digit->setTimeError(timeError);
195 digit->setChannel(channel);
196 digit->setHitQuality(TOPDigit::c_CalPulse);
200 sample = sampleTimes->
getSample(window, time);
201 digit = digits.appendNew(moduleID, pixelID, sample);
202 digit->setFirstWindow(window);
203 digit->setTime(time);
204 digit->setTimeError(timeError);
205 digit->setChannel(channel);
206 digit->setHitQuality(TOPDigit::c_CalPulse);
216 if (fileName.empty())
return;
218 TFile* fout = TFile::Open(fileName.c_str(),
"recreate");
220 B2ERROR(
"Can't open the output file " << fileName);
226 TH1F scrods(
"scrodID",
"scrod ID's mapped to slots/boardstacks", 64, -0.5, 63.5);
227 scrods.SetXTitle(
"(slot - 1) * 4 + boardstack");
228 scrods.SetYTitle(
"scrod ID");
231 for (
int bs = 0; bs < 4; bs++) {
232 const auto* feMap = feMapper.getMap(moduleID, bs);
234 B2ERROR(
"No front-end mapping available for slot " << moduleID
235 <<
" boardstack " << bs);
238 unsigned scrodID = feMap->getScrodID();
239 std::string subdir =
"scrod" + std::to_string(scrodID);
240 int i = (moduleID - 1) * 4 + bs;
241 scrods.SetBinContent(i + 1, scrodID);
242 fout->mkdir(subdir.c_str());
248 for (
unsigned asic = 0; asic < 64; asic++) {
250 const auto* feMap = feMapper.getMap(moduleID, bs);
251 if (!feMap)
continue;
252 unsigned scrodID = feMap->getScrodID();
253 std::string subdir =
"scrod" + std::to_string(scrodID);
254 fout->cd(subdir.c_str());
259 sampleTimes =
m_timebase->getSampleTimes(scrodID, channel);
261 string forWhat =
"scrod " + to_string(scrodID) +
262 " channel " + to_string(channel) +
263 " (slot" + to_string(moduleID) +
", as" + to_string(asic) +
267 "Generator input: sample times for " + forWhat,
268 "sample number",
"t [ns]");
269 std::vector<double> dt;
270 for (
unsigned i = 1; i < timeAxis.size(); i++) {
271 dt.push_back(timeAxis[i] - timeAxis[i - 1]);
274 "Generator input: sample time bins for " + forWhat,
275 "sample number",
"#Delta t [ns]");
286 const std::string& name,
287 const std::string& title,
288 const std::string& xTitle,
289 const std::string& yTitle)
291 if (vec.empty())
return;
293 TH1F h(name.c_str(), title.c_str(), vec.size(), 0, vec.size());
294 h.SetXTitle(xTitle.c_str());
295 h.SetYTitle(yTitle.c_str());
296 if (name.find(
"Fit") != string::npos) h.SetLineColor(2);
298 for (
unsigned i = 0; i < vec.size(); i++) h.SetBinContent(i + 1, vec[i]);
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...
Accessor to arrays stored in the data store.
Type-safe access to single objects in the data store.
double m_timeDifference
time difference between first and second pulse
std::vector< unsigned > m_asicChannels
ASIC calibration channels.
DBObjPtr< TOPCalTimebase > m_timebase
sample times from database
std::vector< double > m_sampleTimeIntervals
sample time intervals
unsigned m_storageWindows
number of storage windows
std::vector< int > m_moduleIDs
slot ID's to generate for
bool m_useDatabase
if true, use sample times from database
int m_sampleDivisions
number of sample divisions (from NominalTDC)
double m_timeResolution
sigma of time difference
std::string m_outputFileName
if given, store sample times as root histograms
TOPSampleTimes m_sampleTimes
sample times from steering input
const TOPNominalTDC & getNominalTDC() const
Returns nominal time-to-digit conversion parameters.
double getSyncTimeBase() const
Returns synchronization time base (time width of c_syncWindows)
Calibration constants of a single ASIC channel: time axis (sample times)
double getTimeRange() const
Returns time axis range (time interval corresponding to 4 asic windows)
bool isCalibrated() const
Returns calibration status.
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)
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.
TOPDoublePulseGeneratorModule()
Constructor.
virtual void beginRun() override
Called when entering a new run.
void storeSampleTimes(const std::string &fileName)
Optionally store sample times used by the generator as root histograms fileName root output file name...
static void saveAsHistogram(const std::vector< double > &vec, const std::string &name, const std::string &title, const std::string &xTitle="", const std::string &yTitle="")
Save vector to histogram and write it out.
double getSample(int window, double time) const
Returns sample with respect to sample 0 of the specified ASIC window (inverse of getTime).
std::vector< double > getTimeAxis() const
Returns time axis (sample times)
Abstract base class for different kinds of events.
record to be used to store ASIC info