@@ -48,6 +48,13 @@ class ITSMFTDPLDigitizerTask : BaseDPLDigitizer
4848 using BaseDPLDigitizer::init;
4949 void initDigitizerTask (framework::InitContext& ic) override
5050 {
51+ // init optional QED chain
52+ auto qedfilename = ic.options ().get <std::string>(" simFileQED" );
53+ if (qedfilename.size () > 0 ) {
54+ mQEDChain .AddFile (qedfilename.c_str ());
55+ LOG (INFO ) << " Attach QED Tree: " << mQEDChain .GetEntries ();
56+ }
57+
5158 setDigitizationOptions (); // set options provided via configKeyValues mechanism
5259 auto & digipar = mDigitizer .getParams ();
5360
@@ -81,11 +88,8 @@ class ITSMFTDPLDigitizerTask : BaseDPLDigitizer
8188 // read collision context from input
8289 auto context = pc.inputs ().get <o2::steer::DigitizationContext*>(" collisioncontext" );
8390 context->initSimChains (mID , mSimChains );
84- const bool withQED = context->isQEDProvided ();
85- auto & timesview = context->getEventRecords (withQED);
86- LOG (INFO ) << " GOT " << timesview.size () << " COLLISSION TIMES" ;
87- LOG (INFO ) << " SIMCHAINS " << mSimChains .size ();
88-
91+ auto & timesview = context->getEventRecords ();
92+ LOG (DEBUG ) << " GOT " << timesview.size () << " COLLISSION TIMES" ;
8993 // if there is nothing to do ... return
9094 if (timesview.size () == 0 ) {
9195 return ;
@@ -98,11 +102,18 @@ class ITSMFTDPLDigitizerTask : BaseDPLDigitizer
98102 mDigitizer .setROFRecords (&mROFRecords );
99103 mDigitizer .setMCLabels (&mLabels );
100104
101- auto & eventParts = context->getEventParts (withQED);
105+ // attach optional QED digits branch
106+ setupQEDChain ();
107+
108+ auto & eventParts = context->getEventParts ();
102109 // loop over all composite collisions given from context (aka loop over all the interaction records)
103110 for (int collID = 0 ; collID < timesview.size (); ++collID) {
104111 const auto & irt = timesview[collID];
105112
113+ if (mQEDChain .GetEntries ()) { // QED must be processed before other inputs since done in small time steps
114+ processQED (irt);
115+ }
116+
106117 mDigitizer .setEventTime (irt);
107118 mDigitizer .resetEventROFrames (); // to estimate min/max ROF for this collID
108119 // for each collision, loop over the constituents event and source IDs
@@ -113,15 +124,19 @@ class ITSMFTDPLDigitizerTask : BaseDPLDigitizer
113124 mHits .clear ();
114125 context->retrieveHits (mSimChains , o2::detectors::SimTraits::DETECTORBRANCHNAMES [mID ][0 ].c_str (), part.sourceID , part.entryID , &mHits );
115126
116- if (mHits .size () > 0 ) {
117- LOG (INFO ) << " For collision " << collID << " eventID " << part.entryID
118- << " found " << mHits .size () << " hits " ;
119- mDigitizer .process (&mHits , part.entryID , part.sourceID ); // call actual digitization procedure
120- }
127+ LOG (INFO ) << " For collision " << collID << " eventID " << part.entryID
128+ << " found " << mHits .size () << " hits " ;
129+
130+ mDigitizer .process (&mHits , part.entryID , part.sourceID ); // call actual digitization procedure
121131 }
122132 mMC2ROFRecordsAccum .emplace_back (collID, -1 , mDigitizer .getEventROFrameMin (), mDigitizer .getEventROFrameMax ());
123133 accumulate ();
124134 }
135+ // finish digitization ... stream any remaining digits/labels
136+ if (mQEDChain .GetEntries ()) { // fill last slots from QED input
137+ processQED (mDigitizer .getEndTimeOfROFMax ());
138+ }
139+
125140 mDigitizer .fillOutputContainer ();
126141 accumulate ();
127142
@@ -147,6 +162,42 @@ class ITSMFTDPLDigitizerTask : BaseDPLDigitizer
147162 protected:
148163 ITSMFTDPLDigitizerTask (bool mctruth = true ) : BaseDPLDigitizer(InitServices::FIELD | InitServices::GEOM ), mWithMCTruth (mctruth) {}
149164
165+ void processQED (const o2::InteractionTimeRecord& irt)
166+ {
167+
168+ auto tQEDNext = mLastQEDTime .getTimeNS () + mQEDEntryTimeBinNS ; // timeslice to retrieve
169+ std::string detStr = mID .getName ();
170+ auto br = mQEDChain .GetBranch ((detStr + " Hit" ).c_str ());
171+ while (tQEDNext < irt.getTimeNS ()) {
172+ mLastQEDTime .setFromNS (tQEDNext); // time used for current QED slot
173+ tQEDNext += mQEDEntryTimeBinNS ; // prepare time for next QED slot
174+ if (++mLastQEDEntry >= mQEDChain .GetEntries ()) {
175+ mLastQEDEntry = 0 ; // wrapp if needed
176+ }
177+ br->GetEntry (mLastQEDEntry );
178+ mDigitizer .setEventTime (mLastQEDTime );
179+ mDigitizer .process (&mHits , mLastQEDEntry , QEDSourceID);
180+ //
181+ }
182+ }
183+
184+ void setupQEDChain ()
185+ {
186+ if (!mQEDChain .GetEntries ()) {
187+ return ;
188+ }
189+ mLastQEDTime .setFromNS (0 .);
190+ std::string detStr = mID .getName ();
191+ auto qedBranch = mQEDChain .GetBranch ((detStr + " Hit" ).c_str ());
192+ assert (qedBranch != nullptr );
193+ assert (mQEDEntryTimeBinNS >= 1.0 );
194+ assert (QEDSourceID < o2::MCCompLabel::maxSourceID ());
195+ mLastQEDTimeNS = -mQEDEntryTimeBinNS / 2 ; // time will be assigned to the middle of the bin
196+ qedBranch->SetAddress (&mHitsP );
197+ LOG (INFO ) << " Attaching QED ITS hits as sourceID=" << int (QEDSourceID) << " , entry integrates "
198+ << mQEDEntryTimeBinNS << " ns" ;
199+ }
200+
150201 void accumulate ()
151202 {
152203 // accumulate result of single event processing, called after processing every event supplied
@@ -204,9 +255,16 @@ class ITSMFTDPLDigitizerTask : BaseDPLDigitizer
204255 o2::dataformats::MCTruthContainer<o2::MCCompLabel> mLabelsAccum ;
205256 std::vector<o2::itsmft::MC2ROFRecord> mMC2ROFRecordsAccum ;
206257 std::vector<TChain*> mSimChains ;
258+ TChain mQEDChain = {" o2sim" };
207259
260+ double mQEDEntryTimeBinNS = 1000 ; // time-coverage of single QED tree entry in ns (TODO: make it settable)
261+ o2::InteractionTimeRecord mLastQEDTime ;
262+ double mLastQEDTimeNS = 0 ; // time assingned to last QED entry
263+ int mLastQEDEntry = -1 ; // last used QED entry
208264 int mFixMC2ROF = 0 ; // 1st entry in mc2rofRecordsAccum to be fixed for ROFRecordID
209265 o2::parameters::GRPObject::ROMode mROMode = o2::parameters::GRPObject::PRESENT ; // readout mode
266+
267+ const int QEDSourceID = 99 ; // unique source ID for the QED (TODO: move it as a const to general class?)
210268};
211269
212270// _______________________________________________
@@ -322,6 +380,7 @@ DataProcessorSpec getITSDigitizerSpec(int channel, bool mctruth)
322380 makeOutChannels (detOrig, mctruth),
323381 AlgorithmSpec{adaptFromTask<ITSDPLDigitizerTask>(mctruth)},
324382 Options{
383+ {" simFileQED" , VariantType::String, " " , {" Sim (QED) input filename" }},
325384 // { "configKeyValues", VariantType::String, "", { parHelper.str().c_str() } }
326385 }};
327386}
@@ -341,7 +400,8 @@ DataProcessorSpec getMFTDigitizerSpec(int channel, bool mctruth)
341400 static_cast <SubSpecificationType>(channel), Lifetime::Timeframe}},
342401 makeOutChannels (detOrig, mctruth),
343402 AlgorithmSpec{adaptFromTask<MFTDPLDigitizerTask>(mctruth)},
344- Options{}};
403+ Options{
404+ {" simFileQED" , VariantType::String, " " , {" Sim (QED) input filename" }}}};
345405}
346406
347407} // end namespace itsmft
0 commit comments