2121#include " DataFormatsITSMFT/Digit.h"
2222#include " SimulationDataFormat/ConstMCTruthContainer.h"
2323#include " DetectorsBase/BaseDPLDigitizer.h"
24+ #include " DetectorsRaw/HBFUtils.h"
2425#include " DetectorsCommonDataFormats/DetID.h"
2526#include " DetectorsCommonDataFormats/SimTraits.h"
2627#include " DataFormatsParameters/GRPObject.h"
3435#include < TChain.h>
3536#include < TStopwatch.h>
3637
38+ #include < algorithm>
3739#include < memory>
3840#include < string>
3941
@@ -77,6 +79,8 @@ class TRKDPLDigitizerTask : BaseDPLDigitizer
7779 if (mFinished ) {
7880 return ;
7981 }
82+ mFirstOrbitTF = pc.services ().get <o2::framework::TimingInfo>().firstTForbit ;
83+ const o2::InteractionRecord firstIR (0 , mFirstOrbitTF );
8084 updateTimeDependentParams (pc);
8185
8286 // read collision context from input
@@ -102,6 +106,11 @@ class TRKDPLDigitizerTask : BaseDPLDigitizer
102106 // digits are directly put into DPL owned resource
103107 auto & digitsAccum = pc.outputs ().make <std::vector<itsmft::Digit>>(Output{mOrigin , " DIGITS" , 0 });
104108
109+ const int roFrameLengthInBC = mDigitizer .getParams ().getROFrameLengthInBC ();
110+ const int nROFsPerOrbit = o2::constants::lhc::LHCMaxBunches / roFrameLengthInBC;
111+ const int nROFsTF = nROFsPerOrbit * raw::HBFUtils::Instance ().getNOrbitsPerTF ();
112+ mROFRecordsAccum .reserve (nROFsTF);
113+
105114 auto accumulate = [this , &digitsAccum]() {
106115 // accumulate result of single event processing, called after processing every event supplied
107116 // AND after the final flushing via digitizer::fillOutputContainer
@@ -180,10 +189,62 @@ class TRKDPLDigitizerTask : BaseDPLDigitizer
180189 accumulate ();
181190
182191 // here we have all digits and labels and we can send them to consumer (aka snapshot it onto output)
192+ std::vector<o2::itsmft::ROFRecord> expDigitRofVec (nROFsTF);
193+ for (int iROF = 0 ; iROF < nROFsTF; ++iROF) {
194+ auto & rof = expDigitRofVec[iROF];
195+ const int orb = iROF * roFrameLengthInBC / o2::constants::lhc::LHCMaxBunches + mFirstOrbitTF ;
196+ const int bc = iROF * roFrameLengthInBC % o2::constants::lhc::LHCMaxBunches;
197+ rof.setBCData (o2::InteractionRecord (bc, orb));
198+ rof.setROFrame (iROF);
199+ rof.setNEntries (0 );
200+ rof.setFirstEntry (-1 );
201+ }
202+
203+ for (const auto & rof : mROFRecordsAccum ) {
204+ const auto & ir = rof.getBCData ();
205+ const auto irToFirst = ir - firstIR;
206+ const auto irROF = irToFirst.toLong () / roFrameLengthInBC;
207+ if (irROF < 0 || irROF >= nROFsTF) {
208+ continue ;
209+ }
210+ auto & expROF = expDigitRofVec[irROF];
211+ expROF.setFirstEntry (rof.getFirstEntry ());
212+ expROF.setNEntries (rof.getNEntries ());
213+ if (expROF.getBCData () != rof.getBCData ()) {
214+ LOGP (fatal, " detected mismatch between expected {} and received {}" , expROF.asString (), rof.asString ());
215+ }
216+ }
183217
184- pc.outputs ().snapshot (Output{mOrigin , " DIGITSROF" , 0 }, mROFRecordsAccum );
218+ int prevFirst = 0 ;
219+ for (auto & rof : expDigitRofVec) {
220+ if (rof.getFirstEntry () < 0 ) {
221+ rof.setFirstEntry (prevFirst);
222+ }
223+ prevFirst = rof.getFirstEntry ();
224+ }
225+
226+ pc.outputs ().snapshot (Output{mOrigin , " DIGITSROF" , 0 }, expDigitRofVec);
185227 if (mWithMCTruth ) {
186- pc.outputs ().snapshot (Output{mOrigin , " DIGITSMC2ROF" , 0 }, mMC2ROFRecordsAccum );
228+ std::vector<o2::itsmft::MC2ROFRecord> clippedMC2ROFRecords;
229+ clippedMC2ROFRecords.reserve (mMC2ROFRecordsAccum .size ());
230+ for (auto mc2rof : mMC2ROFRecordsAccum ) {
231+ if (mc2rof.rofRecordID < 0 || mc2rof.minROF >= static_cast <uint32_t >(nROFsTF)) {
232+ mc2rof.rofRecordID = -1 ;
233+ mc2rof.minROF = 0 ;
234+ mc2rof.maxROF = 0 ;
235+ } else {
236+ mc2rof.maxROF = std::min<uint32_t >(mc2rof.maxROF , nROFsTF - 1 );
237+ if (mc2rof.minROF > mc2rof.maxROF ) {
238+ mc2rof.rofRecordID = -1 ;
239+ mc2rof.minROF = 0 ;
240+ mc2rof.maxROF = 0 ;
241+ } else {
242+ mc2rof.rofRecordID = mc2rof.minROF ;
243+ }
244+ }
245+ clippedMC2ROFRecords.push_back (mc2rof);
246+ }
247+ pc.outputs ().snapshot (Output{mOrigin , " DIGITSMC2ROF" , 0 }, clippedMC2ROFRecords);
187248 auto & sharedlabels = pc.outputs ().make <o2::dataformats::ConstMCTruthContainer<o2::MCCompLabel>>(Output{mOrigin , " DIGITSMCTR" , 0 });
188249 mLabelsAccum .flatten_to (sharedlabels);
189250 // free space of existing label containers
@@ -286,6 +347,7 @@ class TRKDPLDigitizerTask : BaseDPLDigitizer
286347 bool mWithMCTruth {true };
287348 bool mFinished {false };
288349 bool mDisableQED {false };
350+ unsigned long mFirstOrbitTF = 0x0 ;
289351 std::string mLocalRespFile {" " };
290352 const o2::detectors::DetID mID {o2::detectors::DetID::TRK};
291353 const o2::header::DataOrigin mOrigin {o2::header::gDataOriginTRK };
0 commit comments