37#include <TStopwatch.h>
56 mDisableQED = ic.
options().
get<
bool>(
"disable-qed");
70 LOG(info) <<
" CALLING ITS3 DIGITIZATION ";
75 const bool withQED = context->isQEDProvided() && !mDisableQED;
76 auto& timesview = context->getEventRecords(withQED);
78 LOG(info) <<
"GOT " << timesview.size() <<
" COLLISSION TIMES";
79 LOG(info) <<
"SIMCHAINS " << mSimChains.size();
82 if (timesview.empty()) {
87 for (uint32_t iLayer = 0; iLayer < (mDoStaggering ? 7 : 1); ++iLayer) {
88 const int layer = (mDoStaggering) ? iLayer : -1;
94 auto& digitsAccum = pc.
outputs().
make<std::vector<itsmft::Digit>>(
Output{mOrigin,
"DIGITS", iLayer});
99 mROFRecordsAccum[iLayer].reserve(nROFsTF);
101 auto accumulate = [
this, &digitsAccum, &iLayer]() {
104 if (!mDigits[iLayer].
size()) {
107 auto ndigAcc = digitsAccum.size();
108 std::copy(mDigits[iLayer].begin(), mDigits[iLayer].
end(), std::back_inserter(digitsAccum));
111 auto nROFRecsOld = mROFRecordsAccum[iLayer].size();
113 for (
int i = 0;
i < mROFRecords[iLayer].size();
i++) {
114 auto& rof = mROFRecords[iLayer][
i];
115 rof.setFirstEntry(ndigAcc + rof.getFirstEntry());
119 std::copy(mROFRecords[iLayer].begin(), mROFRecords[iLayer].
end(), std::back_inserter(mROFRecordsAccum[iLayer]));
121 mLabelsAccum[iLayer].mergeAtBack(mLabels[iLayer]);
123 LOG(info) <<
"Added " << mDigits[iLayer].size() <<
" digits" << ((mDoStaggering) ? std::format(
" on layer {}", iLayer) :
"");
125 mLabels[iLayer].clear();
126 mDigits[iLayer].clear();
127 mROFRecords[iLayer].clear();
130 const auto& eventParts = context->getEventParts(withQED);
133 for (
int collID = 0; collID < timesview.size(); ++collID) {
134 auto irt = timesview[collID];
135 if (irt.toLong() < bcShift) {
144 for (
const auto& part : eventParts[collID]) {
150 if (mHits.size() > 0) {
151 LOG(
debug) <<
"For collision " << collID <<
" eventID " << part.entryID <<
" found " << mHits.size() <<
" hits ";
152 mDigitizer.
process(&mHits, part.entryID, part.sourceID,
layer);
159 nDigits += digitsAccum.size();
163 if (nROFsTF != mROFRecordsAccum[iLayer].
size()) {
168 const size_t nROFsLayer = std::max((
size_t)nROFsTF, mROFRecordsAccum[iLayer].
size());
169 std::vector<o2::itsmft::ROFRecord> expDigitRofVec(nROFsLayer);
170 for (
int iROF{0}; iROF < nROFsLayer; ++iROF) {
171 auto& rof = expDigitRofVec[iROF];
176 rof.setROFrame(iROF);
178 rof.setFirstEntry(-1);
180 uint32_t prevEntry{0};
181 for (
const auto& rof : mROFRecordsAccum[iLayer]) {
182 const auto&
ir = rof.getBCData();
184 LOGP(warn,
"Discard ROF {} preceding TF 1st orbit {}{}",
ir.
asString(), mFirstOrbitTF, ((mDoStaggering) ? std::format(
" on layer {}", iLayer) :
""));
187 auto irToFirst =
ir - firstIR;
188 if (irToFirst.toLong() - par.getROFDelayInBC(iLayer) < 0) {
189 LOGP(warn,
"Discard ROF {} preceding TF 1st orbit {} due to imposed ROF delay{}",
ir.
asString(), mFirstOrbitTF, ((mDoStaggering) ? std::format(
" on layer {}", iLayer) :
""));
192 irToFirst -= par.getROFDelayInBC(iLayer);
193 const int irROF = irToFirst.toLong() / par.getROFLengthInBC(iLayer);
194 auto& expROF = expDigitRofVec[irROF];
195 expROF.setFirstEntry(rof.getFirstEntry());
196 expROF.setNEntries(rof.getNEntries());
197 if (expROF.getBCData() != rof.getBCData()) {
198 LOGP(fatal,
"detected mismatch between expected {} and received {}", expROF.asString(), rof.asString());
202 for (
auto& rof : expDigitRofVec) {
203 if (rof.getFirstEntry() < 0) {
204 rof.setFirstEntry(prevFirst);
206 prevFirst = rof.getFirstEntry();
210 expDigitRofVec.resize(nROFsTF);
217 mLabelsAccum[iLayer].flatten_to(sharedlabels);
219 mLabels[iLayer].clear_andfreememory();
220 mLabelsAccum[iLayer].clear_andfreememory();
224 LOG(info) <<
"IT3: Sending ROMode= " << mROMode <<
" to GRPUpdater";
228 LOG(info) <<
"Digitization took " << timer.CpuTime() <<
"s";
229 LOG(info) <<
"Produced " << nDigits <<
" digits";
239 static bool initOnce{
false};
253 digipar.setContinuous(dopt.continuous);
255 if (dopt.continuous) {
258 digipar.setROFrameLength(frameNS);
267 digipar.getSignalShape().setParameters(dopt.strobeFlatTop, dopt.strobeMaxRiseTime, dopt.strobeQRiseTime0);
268 digipar.setChargeThreshold(dopt.chargeThreshold);
269 digipar.setNoisePerPixel(dopt.noisePerPixel);
270 digipar.setTimeOffset(dopt.timeOffset);
271 digipar.setNSimSteps(dopt.nSimSteps);
274 digipar.setIBChargeThreshold(doptIB.IBChargeThreshold);
275 digipar.setIBNSimSteps(doptIB.nIBSimSteps);
276 digipar.setIBNoisePerPixel(doptIB.IBNoisePerPixel);
280 for (
int iLayer{0}; iLayer < 7; ++iLayer) {
292 LOG(info) << mID.
getName() <<
" simulated in "
314 LOG(info) << mID.
getName() <<
" Alpide param updated";
316 par.printKeyValues();
320 LOG(info) << mID.
getName() <<
" static dead map updated";
325 LOG(info) << mID.
getName() <<
" loaded AlpideResponseData for Vbb=0V";
329 LOG(info) << mID.
getName() <<
" loaded APTSResponseData";
335 bool mWithMCTruth{
true};
336 bool mFinished{
false};
337 bool mDisableQED{
false};
338 unsigned long mFirstOrbitTF = 0x0;
342 std::array<std::vector<o2::itsmft::Digit>, 7> mDigits{};
343 std::array<std::vector<o2::itsmft::ROFRecord>, 7> mROFRecords{};
344 std::array<std::vector<o2::itsmft::ROFRecord>, 7> mROFRecordsAccum{};
345 std::vector<o2::itsmft::Hit> mHits;
346 std::vector<o2::itsmft::Hit>* mHitsP{&mHits};
347 std::array<o2::dataformats::MCTruthContainer<o2::MCCompLabel>, 7> mLabels;
348 std::array<o2::dataformats::MCTruthContainer<o2::MCCompLabel>, 7> mLabelsAccum;
349 std::vector<TChain*> mSimChains{};
351 bool mDoStaggering =
false;
358 std::vector<OutputSpec> outputs;
359 for (
int iLayer{0}; iLayer < (doStag ? 7 : 1); ++iLayer) {
360 outputs.emplace_back(detOrig,
"DIGITS", iLayer, Lifetime::Timeframe);
361 outputs.emplace_back(detOrig,
"DIGITSROF", iLayer, Lifetime::Timeframe);
363 outputs.emplace_back(detOrig,
"DIGITSMCTR", iLayer, Lifetime::Timeframe);
366 outputs.emplace_back(detOrig,
"ROMode", 0, Lifetime::Timeframe);
374 std::vector<InputSpec> inputs;
375 inputs.emplace_back(
"collisioncontext",
"SIM",
"COLLISIONCONTEXT",
static_cast<SubSpecificationType>(channel), Lifetime::Timeframe);
376 inputs.emplace_back(
"ITS_alppar",
"ITS",
"ALPIDEPARAM", 0, Lifetime::Condition,
ccdbParamSpec(
"ITS/Config/AlpideParam"));
378 inputs.emplace_back(
"IT3_dead",
"IT3",
"DEADMAP", 0, Lifetime::Condition,
ccdbParamSpec(
"IT3/Calib/DeadMap"));
380 inputs.emplace_back(
"IT3_alpiderespvbb0",
"IT3",
"ALPIDERESPVbb0", 0, Lifetime::Condition,
ccdbParamSpec(
"ITSMFT/Calib/ALPIDEResponseVbb0"));
381 inputs.emplace_back(
"IT3_aptsresp",
"IT3",
"APTSRESP", 0, Lifetime::Condition,
ccdbParamSpec(
"IT3/Calib/APTSResponse"));
385 .outputs = makeOutChannels(detOrig, mctruth, doStag),
386 .algorithm =
AlgorithmSpec{adaptFromTask<ITS3DPLDigitizerTask>(mctruth)},
Definition of the base digitizer task class.
A const (ready only) version of MCTruthContainer.
o2::framework::DataAllocator::SubSpecificationType SubSpecificationType
Header of the General Run Parameters object.
Definition of the GeometryTGeo class.
Definition of the ITS digitizer.
virtual void init(o2::framework::InitContext &) final
static const DPLAlpideParam< N > & Instance()
Static class with identifiers, bitmasks and names for ALICE detectors.
static constexpr const char * getName(ID id)
names of defined detectors
static const std::array< std::vector< std::string >, DetID::nDetectors > DETECTORBRANCHNAMES
T get(const char *key) const
void snapshot(const Output &spec, T const &object)
o2::header::DataHeader::SubSpecificationType SubSpecificationType
decltype(auto) make(const Output &spec, Args... args)
ConfigParamRegistry const & options()
DataAllocator & outputs()
The data allocator is used to allocate memory for the output data.
InputRecord & inputs()
The inputs associated with this processing context.
ServiceRegistryRef services()
The services registry associated with this processing context.
void setOBSimResponse(const o2::itsmft::AlpideSimResponse *response)
void setIBSimResponse(const o2::itsmft::AlpideSimResponse *resp)
void fillOutputContainer(uint32_t maxFrame=0xffffffff, int layer=-1)
void setDeadChannelsMap(const o2::itsmft::NoiseMap *mp)
void setROFRecords(std::vector< o2::itsmft::ROFRecord > *rec)
void setDigits(std::vector< o2::itsmft::Digit > *dig)
void setGeometry(const o2::its::GeometryTGeo *gm)
o2::its3::DigiParams & getParams()
void resetROFrameBounds()
void resetEventROFrames()
void process(const std::vector< itsmft::Hit > *hits, int evID, int srcID, int layer)
Steer conversion of hits to digits.
void setMCLabels(o2::dataformats::MCTruthContainer< o2::MCCompLabel > *mclb)
void setEventTime(const o2::InteractionTimeRecord &irt, int layer)
ITS3DPLDigitizerTask(bool mctruth=true, bool doStag=false)
void run(framework::ProcessingContext &pc)
void finaliseCCDB(ConcreteDataMatcher &matcher, void *obj)
void initDigitizerTask(framework::InitContext &ic) override
void updateTimeDependentParams(ProcessingContext &pc)
static GeometryTGeo * Instance()
void fillMatrixCache(int mask) override
int getROFrameBiasInBC(int layer=-1) const
NoiseMap class for the ITS and MFT.
bool initSimChains(o2::detectors::DetID detid, std::vector< TChain * > &simchains) const
GLenum GLuint GLint GLint layer
constexpr o2::header::DataOrigin gDataOriginIT3
constexpr int LHCMaxBunches
constexpr double LHCBunchSpacingNS
Defining ITS Vertex explicitly as messageable.
std::vector< ConfigParamSpec > ccdbParamSpec(std::string const &path, int runDependent, std::vector< CCDBMetadata > metadata={}, int qrate=0)
std::vector< ConfigParamSpec > Options
header::DataHeader::SubSpecificationType SubSpecificationType
DataProcessorSpec getITS3DigitizerSpec(int channel, bool mctruth, bool doStag)
std::string asString() const
class listing possible services
int roFrameBiasInBC
bias of the start of ROF wrt orbit start: t_irof = (irof*roFrameLengthInBC + roFrameBiasInBC)*BClengt...
float strobeDelay
strobe start (in ns) wrt ROF start
int getROFLengthInBC(int layer) const noexcept
int roFrameLengthInBC
ROF length in BC for continuous mode.
float strobeLengthCont
if < 0, full ROF length - delay
int getROFDelayInBC(int layer) const noexcept
float strobeLengthTrig
length of the strobe in ns (sig. over threshold checked in this window only)
float roFrameLengthTrig
length of RO frame in ns for triggered mode
int getROFBiasInBC(int layer) const noexcept
int getNOrbitsPerTF() const
get IR corresponding to start of the HBF
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
o2::InteractionRecord ir(0, 0)