87#include "Math/SMatrix.h"
93#include <unordered_map>
98#include "TLorentzVector.h"
106#include <nlohmann/json.hpp>
127 uint64_t classMaskEMCAL = 0, classMaskTRD = 0, classMaskPHOSCPV = 0;
128 for (
const auto& trgclass : ctpcfg->getCTPClasses()) {
129 if (trgclass.cluster->getClusterDetNames().find(
"EMC") != std::string::npos) {
130 classMaskEMCAL = trgclass.classMask;
132 if (trgclass.cluster->getClusterDetNames().find(
"PHS") != std::string::npos) {
133 classMaskPHOSCPV = trgclass.classMask;
135 if (trgclass.cluster->getClusterDetNames().find(
"TRD") != std::string::npos) {
136 classMaskTRD = trgclass.classMask;
139 LOG(info) <<
"createCTPReadout: Class Mask EMCAL -> " << classMaskEMCAL;
140 LOG(info) <<
"createCTPReadout: Class Mask PHOS/CPV -> " << classMaskPHOSCPV;
141 LOG(info) <<
"createCTPReadout: Class Mask TRD -> " << classMaskTRD;
149 std::vector<o2::emcal::TriggerRecord> triggerRecordEMCALPhys;
150 for (
const auto& trg : triggerrecordEMCAL) {
154 triggerRecordEMCALPhys.push_back(trg);
160 std::set<uint64_t> bcsMapT0triggers;
162 for (
auto& ft0RecPoint : ft0RecPoints) {
163 auto t0triggers = ft0RecPoint.getTrigger();
164 if (t0triggers.getVertex()) {
165 uint64_t globalBC = ft0RecPoint.getInteractionRecord().toLong();
166 bcsMapT0triggers.insert(globalBC);
170 auto genericCTPDigitizer = [&bcsMapT0triggers, &ctpDigits](
auto triggerrecords, uint64_t classmask) ->
int {
174 uint32_t orbitPrev = 0;
176 for (
auto& trigger : triggerrecords) {
177 auto orbitPrevT = orbitPrev;
178 auto bcPrevT = bcPrev;
179 bcPrev = trigger.getBCData().bc;
180 orbitPrev = trigger.getBCData().orbit;
186 uint64_t globalBC = trigger.getBCData().toLong();
187 auto t0entry = bcsMapT0triggers.find(globalBC);
188 if (t0entry != bcsMapT0triggers.end()) {
189 auto ctpdig = std::find_if(ctpDigits.begin(), ctpDigits.end(), [globalBC](
const o2::ctp::CTPDigit& dig) { return static_cast<uint64_t>(dig.intRecord.toLong()) == globalBC; });
190 if (ctpdig != ctpDigits.end()) {
192 ctpdig->CTPClassMask |= std::bitset<64>(classmask);
193 LOG(
debug) <<
"createCTPReadout: Merging " << classmask <<
" CTP digits with existing digit, CTP mask " << ctpdig->CTPClassMask;
196 LOG(
debug) <<
"createCTPReadout: New CTP digit needed for class " << classmask << std::endl;
197 auto& ctpdigNew = ctpDigits.emplace_back();
198 ctpdigNew.intRecord.setFromLong(globalBC);
199 ctpdigNew.CTPClassMask = classmask;
202 LOG(warning) <<
"createCTPReadout: Found " << classmask <<
" and no MTVX:" << globalBC;
209 auto warningsTRD = genericCTPDigitizer(triggerrecordTRD, classMaskTRD);
210 auto warningsEMCAL = genericCTPDigitizer(triggerRecordEMCALPhys, classMaskEMCAL);
211 auto warningsPHOSCPV = genericCTPDigitizer(triggerrecordPHOSCPV, classMaskPHOSCPV);
213 LOG(info) <<
"createCTPReadout:# of TRD bogus triggers:" << warningsTRD;
214 LOG(info) <<
"createCTPReadout:# of EMCAL bogus triggers:" << warningsEMCAL;
215 LOG(info) <<
"createCTPReadout:# of PHOS/CPV bogus triggers:" << warningsPHOSCPV;
219 const std::vector<o2::InteractionTimeRecord>& mcRecords,
220 std::map<uint64_t, int>& bcsMap)
222 const auto& primVertices =
data.getPrimaryVertices();
223 const auto& fddRecPoints =
data.getFDDRecPoints();
224 const auto& ft0RecPoints =
data.getFT0RecPoints();
225 const auto& fv0RecPoints =
data.getFV0RecPoints();
226 const auto& caloEMCCellsTRGR =
data.getEMCALTriggers();
227 const auto& caloPHOSCellsTRGR =
data.getPHOSTriggers();
228 const auto& cpvTRGR =
data.getCPVTriggers();
229 const auto& ctpDigits =
data.getCTPDigits();
230 const auto& zdcBCRecData =
data.getZDCBCRecData();
232 bcsMap[mStartIR.
toLong()] = 1;
235 for (
auto&
rec : mcRecords) {
236 uint64_t globalBC =
rec.toLong();
237 bcsMap[globalBC] = 1;
240 for (
auto& fddRecPoint : fddRecPoints) {
241 uint64_t globalBC = fddRecPoint.getInteractionRecord().toLong();
242 bcsMap[globalBC] = 1;
245 for (
auto& ft0RecPoint : ft0RecPoints) {
246 uint64_t globalBC = ft0RecPoint.getInteractionRecord().toLong();
247 bcsMap[globalBC] = 1;
250 for (
auto& fv0RecPoint : fv0RecPoints) {
251 uint64_t globalBC = fv0RecPoint.getInteractionRecord().toLong();
252 bcsMap[globalBC] = 1;
255 for (
auto& zdcRecData : zdcBCRecData) {
256 uint64_t globalBC = zdcRecData.ir.toLong();
257 bcsMap[globalBC] = 1;
260 for (
auto&
vertex : primVertices) {
261 auto& timeStamp =
vertex.getTimeStamp();
262 double tsTimeStamp = timeStamp.getTimeStamp() * 1E3;
263 uint64_t globalBC = relativeTime_to_GlobalBC(tsTimeStamp);
264 bcsMap[globalBC] = 1;
267 for (
auto& emcaltrg : caloEMCCellsTRGR) {
268 uint64_t globalBC = emcaltrg.getBCData().toLong();
269 bcsMap[globalBC] = 1;
272 for (
auto& phostrg : caloPHOSCellsTRGR) {
273 uint64_t globalBC = phostrg.getBCData().toLong();
274 bcsMap[globalBC] = 1;
277 for (
auto& cpvtrg : cpvTRGR) {
278 uint64_t globalBC = cpvtrg.getBCData().toLong();
279 bcsMap[globalBC] = 1;
282 for (
auto& ctpDigit : ctpDigits) {
283 uint64_t globalBC = ctpDigit.intRecord.toLong();
284 bcsMap[globalBC] = 1;
288 for (
auto& item : bcsMap) {
294template <
typename TracksCursorType,
typename TracksCovCursorType>
295void AODProducerWorkflowDPL::addToTracksTable(TracksCursorType& tracksCursor, TracksCovCursorType& tracksCovCursor,
298 tracksCursor(collisionID,
300 truncateFloatFraction(track.getX(), mTrackX),
301 truncateFloatFraction(track.getAlpha(), mTrackAlpha),
304 truncateFloatFraction(track.getSnp(), mTrackSnp),
305 truncateFloatFraction(track.getTgl(), mTrackTgl),
306 truncateFloatFraction(track.getQ2Pt(), mTrack1Pt));
308 float sY = TMath::Sqrt(track.getSigmaY2()), sZ = TMath::Sqrt(track.getSigmaZ2()), sSnp = TMath::Sqrt(track.getSigmaSnp2()),
309 sTgl = TMath::Sqrt(track.getSigmaTgl2()), sQ2Pt = TMath::Sqrt(track.getSigma1Pt2());
310 tracksCovCursor(truncateFloatFraction(sY, mTrackCovDiag),
311 truncateFloatFraction(sZ, mTrackCovDiag),
312 truncateFloatFraction(sSnp, mTrackCovDiag),
313 truncateFloatFraction(sTgl, mTrackCovDiag),
314 truncateFloatFraction(sQ2Pt, mTrackCovDiag),
315 (Char_t)(128. * track.getSigmaZY() / (sZ * sY)),
316 (Char_t)(128. * track.getSigmaSnpY() / (sSnp * sY)),
317 (Char_t)(128. * track.getSigmaSnpZ() / (sSnp * sZ)),
318 (Char_t)(128. * track.getSigmaTglY() / (sTgl * sY)),
319 (Char_t)(128. * track.getSigmaTglZ() / (sTgl * sZ)),
320 (Char_t)(128. * track.getSigmaTglSnp() / (sTgl * sSnp)),
321 (Char_t)(128. * track.getSigma1PtY() / (sQ2Pt * sY)),
322 (Char_t)(128. * track.getSigma1PtZ() / (sQ2Pt * sZ)),
323 (Char_t)(128. * track.getSigma1PtSnp() / (sQ2Pt * sSnp)),
324 (Char_t)(128. * track.getSigma1PtTgl() / (sQ2Pt * sTgl)));
327template <
typename TracksExtraCursorType>
328void AODProducerWorkflowDPL::addToTracksExtraTable(TracksExtraCursorType& tracksExtraCursor, TrackExtraInfo& extraInfoHolder)
332 auto trackTimeRes = extraInfoHolder.trackTimeRes;
333 if (!extraInfoHolder.isTPConly) {
334 trackTimeRes = truncateFloatFraction(trackTimeRes, mTrackTimeError);
338 tracksExtraCursor(truncateFloatFraction(extraInfoHolder.tpcInnerParam, mTrack1Pt),
339 extraInfoHolder.flags,
340 extraInfoHolder.itsClusterSizes,
341 extraInfoHolder.tpcNClsFindable,
342 extraInfoHolder.tpcNClsFindableMinusFound,
343 extraInfoHolder.tpcNClsFindableMinusPID,
344 extraInfoHolder.tpcNClsFindableMinusCrossedRows,
345 extraInfoHolder.tpcNClsShared,
346 extraInfoHolder.trdPattern,
347 truncateFloatFraction(extraInfoHolder.itsChi2NCl, mTrackChi2),
348 truncateFloatFraction(extraInfoHolder.tpcChi2NCl, mTrackChi2),
349 truncateFloatFraction(extraInfoHolder.trdChi2, mTrackChi2),
350 truncateFloatFraction(extraInfoHolder.tofChi2, mTrackChi2),
351 truncateFloatFraction(extraInfoHolder.tpcSignal, mTrackSignal),
352 truncateFloatFraction(extraInfoHolder.trdSignal, mTrackSignal),
353 truncateFloatFraction(extraInfoHolder.length, mTrackSignal),
354 truncateFloatFraction(extraInfoHolder.tofExpMom, mTrack1Pt),
355 truncateFloatFraction(extraInfoHolder.trackEtaEMCAL, mTrackPosEMCAL),
356 truncateFloatFraction(extraInfoHolder.trackPhiEMCAL, mTrackPosEMCAL),
357 truncateFloatFraction(extraInfoHolder.trackTime, mTrackTime),
361template <
typename TracksQACursorType>
362void AODProducerWorkflowDPL::addToTracksQATable(TracksQACursorType& tracksQACursor,
TrackQA& trackQAInfoHolder)
365 trackQAInfoHolder.trackID,
366 mTrackQCRetainOnlydEdx ? 0.0f : truncateFloatFraction(trackQAInfoHolder.tpcTime0, mTPCTime0),
367 truncateFloatFraction(trackQAInfoHolder.tpcdEdxNorm, mTrackSignal),
368 mTrackQCRetainOnlydEdx ? std::numeric_limits<int16_t>::min() : trackQAInfoHolder.tpcdcaR,
369 mTrackQCRetainOnlydEdx ? std::numeric_limits<int16_t>::min() : trackQAInfoHolder.tpcdcaZ,
370 trackQAInfoHolder.tpcClusterByteMask,
371 trackQAInfoHolder.tpcdEdxMax0R,
372 trackQAInfoHolder.tpcdEdxMax1R,
373 trackQAInfoHolder.tpcdEdxMax2R,
374 trackQAInfoHolder.tpcdEdxMax3R,
375 trackQAInfoHolder.tpcdEdxTot0R,
376 trackQAInfoHolder.tpcdEdxTot1R,
377 trackQAInfoHolder.tpcdEdxTot2R,
378 trackQAInfoHolder.tpcdEdxTot3R,
379 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefContY,
380 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefContZ,
381 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefContSnp,
382 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefContTgl,
383 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefContQ2Pt,
384 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefGloY,
385 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefGloZ,
386 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefGloSnp,
387 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefGloTgl,
388 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefGloQ2Pt,
389 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dTofdX,
390 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dTofdZ);
393template <
typename mftTracksCursorType,
typename AmbigMFTTracksCursorType>
394void AODProducerWorkflowDPL::addToMFTTracksTable(mftTracksCursorType& mftTracksCursor, AmbigMFTTracksCursorType& ambigMFTTracksCursor,
396 std::uint64_t collisionBC,
const std::map<uint64_t, int>& bcsMap)
399 int bcSlice[2] = {-1, -1};
400 const auto& track =
data.getMFTTrack(trackID);
401 const auto& rof =
data.getMFTTracksROFRecords()[mMFTROFs[trackID.getIndex()]];
403 float trackTimeRes = mMFTROFrameHalfLengthNS;
404 bool needBCSlice = collisionID < 0;
405 std::uint64_t bcOfTimeRef;
407 double error = mTimeMarginTrackTime + trackTimeRes;
408 bcOfTimeRef = fillBCSlice(bcSlice, trackTime - error, trackTime + error, bcsMap);
410 bcOfTimeRef = collisionBC - mStartIR.
toLong();
415 uint64_t mftClusterSizesAndTrackFlags = track.getClusterSizes();
416 mftClusterSizesAndTrackFlags |= (track.isCA()) ? (1ULL << (60)) : 0;
418 mftTracksCursor(collisionID,
421 truncateFloatFraction(track.getZ(), mTrackX),
422 truncateFloatFraction(track.getPhi(), mTrackAlpha),
423 truncateFloatFraction(track.getTanl(), mTrackTgl),
424 truncateFloatFraction(track.getInvQPt(), mTrack1Pt),
425 mftClusterSizesAndTrackFlags,
426 truncateFloatFraction(track.getTrackChi2(), mTrackChi2),
427 truncateFloatFraction(trackTime, mTrackTime),
428 truncateFloatFraction(trackTimeRes, mTrackTimeError));
430 ambigMFTTracksCursor(mTableTrMFTID, bcSlice);
434template <
typename TracksCursorType,
typename TracksCovCursorType,
typename TracksExtraCursorType,
typename TracksQACursorType,
typename AmbigTracksCursorType,
435 typename MFTTracksCursorType,
typename MFTTracksCovCursorType,
typename AmbigMFTTracksCursorType,
436 typename FwdTracksCursorType,
typename FwdTracksCovCursorType,
typename AmbigFwdTracksCursorType,
typename FwdTrkClsCursorType>
437void AODProducerWorkflowDPL::fillTrackTablesPerCollision(
int collisionID,
438 std::uint64_t collisionBC,
440 const gsl::span<const GIndex>& GIndices,
442 TracksCursorType& tracksCursor,
443 TracksCovCursorType& tracksCovCursor,
444 TracksExtraCursorType& tracksExtraCursor,
445 TracksQACursorType& tracksQACursor,
446 AmbigTracksCursorType& ambigTracksCursor,
447 MFTTracksCursorType& mftTracksCursor,
448 MFTTracksCovCursorType& mftTracksCovCursor,
449 AmbigMFTTracksCursorType& ambigMFTTracksCursor,
450 FwdTracksCursorType& fwdTracksCursor,
451 FwdTracksCovCursorType& fwdTracksCovCursor,
452 AmbigFwdTracksCursorType& ambigFwdTracksCursor,
453 FwdTrkClsCursorType& fwdTrkClsCursor,
454 const std::map<uint64_t, int>& bcsMap)
457 if (!GIndex::isTrackSource(
src)) {
464 mftTracksCursor.reserve(nToReserve + mftTracksCursor.lastIndex());
466 fwdTracksCursor.reserve(nToReserve + fwdTracksCursor.lastIndex());
467 fwdTracksCovCursor.reserve(nToReserve + fwdTracksCovCursor.lastIndex());
469 mftTracksCovCursor.reserve(nToReserve + mftTracksCovCursor.lastIndex());
472 tracksCursor.reserve(nToReserve + tracksCursor.lastIndex());
473 tracksCovCursor.reserve(nToReserve + tracksCovCursor.lastIndex());
474 tracksExtraCursor.reserve(nToReserve + tracksExtraCursor.lastIndex());
476 for (
int ti =
start; ti <
end; ti++) {
477 const auto& trackIndex = GIndices[ti];
478 if (GIndex::includesSource(
src, mInputSources)) {
480 if (trackIndex.isAmbiguous() && mGIDToTableMFTID.find(trackIndex) != mGIDToTableMFTID.end()) {
483 addToMFTTracksTable(mftTracksCursor, ambigMFTTracksCursor, trackIndex,
data, collisionID, collisionBC, bcsMap);
484 mGIDToTableMFTID.emplace(trackIndex, mTableTrMFTID);
487 if (trackIndex.isAmbiguous() && mGIDToTableFwdID.find(trackIndex) != mGIDToTableFwdID.end()) {
490 addToFwdTracksTable(fwdTracksCursor, fwdTracksCovCursor, ambigFwdTracksCursor, mftTracksCovCursor, trackIndex,
data, collisionID, collisionBC, bcsMap);
491 mGIDToTableFwdID.emplace(trackIndex, mTableTrFwdID);
492 addClustersToFwdTrkClsTable(
data, fwdTrkClsCursor, trackIndex, mTableTrFwdID);
496 if (trackIndex.isAmbiguous() && mGIDToTableID.find(trackIndex) != mGIDToTableID.end()) {
501 static std::uniform_real_distribution<>
distr(0., 1.);
503 auto extraInfoHolder = processBarrelTrack(collisionID, collisionBC, trackIndex,
data, bcsMap);
506 auto trackQAInfoHolder = processBarrelTrackQA(collisionID, collisionBC, trackIndex,
data, bcsMap);
507 if (std::bitset<8>(trackQAInfoHolder.tpcClusterByteMask).count() >= mTrackQCNTrCut) {
508 trackQAInfoHolder.trackID = mTableTrID;
512 addToTracksQATable(tracksQACursor, trackQAInfoHolder);
519 if (mThinTracks && extraInfoHolder.isTPConly && !writeQAData) {
520 auto trk =
data.getTPCTrack(trackIndex);
521 if (trk.getNClusters() >= mTrackQCNCls && trk.getPt() >= mTrackQCPt) {
531 if (mThinTracks &&
src ==
GIndex::Source::TPC && mGIDUsedBySVtx.find(trackIndex) == mGIDUsedBySVtx.end() && mGIDUsedByStr.find(trackIndex) == mGIDUsedByStr.end() && !writeQAData) {
532 mGIDToTableID.emplace(trackIndex, -1);
536 if (!extraInfoHolder.isTPConly && extraInfoHolder.trackTimeRes < 0.f) {
537 LOG(warning) <<
"Barrel track " << trackIndex <<
" has no time set, rejection is not expected : time=" << extraInfoHolder.trackTime
538 <<
" timeErr=" << extraInfoHolder.trackTimeRes <<
" BCSlice: " << extraInfoHolder.bcSlice[0] <<
":" << extraInfoHolder.bcSlice[1];
541 const auto& trOrig =
data.getTrackParam(trackIndex);
543 if (mPropTracks && trOrig.getX() < mMaxPropXiu &&
544 mGIDUsedBySVtx.find(trackIndex) == mGIDUsedBySVtx.end() &&
545 mGIDUsedByStr.find(trackIndex) == mGIDUsedByStr.end()) {
546 auto trackPar(trOrig);
547 isProp = propagateTrackToPV(trackPar,
data, collisionID);
549 addToTracksTable(tracksCursor, tracksCovCursor, trackPar, collisionID,
aod::track::Track);
555 addToTracksExtraTable(tracksExtraCursor, extraInfoHolder);
558 if (extraInfoHolder.bcSlice[0] >= 0 && collisionID < 0) {
559 ambigTracksCursor(mTableTrID, extraInfoHolder.bcSlice);
561 mGIDToTableID.emplace(trackIndex, mTableTrID);
567 if (collisionID < 0) {
571 auto sTracks =
data.getStrangeTracks();
572 tracksCursor.reserve(mVertexStrLUT[collisionID + 1] + tracksCursor.lastIndex());
573 tracksCovCursor.reserve(mVertexStrLUT[collisionID + 1] + tracksCovCursor.lastIndex());
574 tracksExtraCursor.reserve(mVertexStrLUT[collisionID + 1] + tracksExtraCursor.lastIndex());
575 for (
int iS{mVertexStrLUT[collisionID]}; iS < mVertexStrLUT[collisionID + 1]; ++iS) {
576 auto& collStrTrk = mCollisionStrTrk[iS];
577 auto& sTrk = sTracks[collStrTrk.second];
578 TrackExtraInfo extraInfo;
579 extraInfo.itsChi2NCl = sTrk.mTopoChi2;
580 extraInfo.itsClusterSizes = sTrk.getClusterSizes();
582 addToTracksExtraTable(tracksExtraCursor, extraInfo);
583 mStrTrkIndices[collStrTrk.second] = mTableTrID;
590 const auto& mchmidMatches =
data.getMCHMIDMatches();
595 for (
int ti =
start; ti <
end; ti++) {
596 auto& trackIndex = GIndices[ti];
597 if (GIndex::includesSource(
src, mInputSources)) {
599 if (trackIndex.isAmbiguous() && mGIDToTableMFTID.find(trackIndex) != mGIDToTableMFTID.end()) {
602 mGIDToTableMFTID.emplace(trackIndex, mIndexMFTID);
603 mIndexTableMFT[trackIndex.getIndex()] = mIndexMFTID;
606 if (trackIndex.isAmbiguous() && mGIDToTableFwdID.find(trackIndex) != mGIDToTableFwdID.end()) {
609 mGIDToTableFwdID.emplace(trackIndex, mIndexFwdID);
611 mIndexTableFwd[trackIndex.getIndex()] = mIndexFwdID;
613 const auto& mchmidMatch = mchmidMatches[trackIndex.getIndex()];
614 const auto mchTrackID = mchmidMatch.getMCHRef().getIndex();
615 mIndexTableFwd[mchTrackID] = mIndexFwdID;
624template <
typename FwdTracksCursorType,
typename FwdTracksCovCursorType,
typename AmbigFwdTracksCursorType,
typename mftTracksCovCursorType>
625void AODProducerWorkflowDPL::addToFwdTracksTable(FwdTracksCursorType& fwdTracksCursor, FwdTracksCovCursorType& fwdTracksCovCursor,
626 AmbigFwdTracksCursorType& ambigFwdTracksCursor, mftTracksCovCursorType& mftTracksCovCursor,
GIndex trackID,
628 const std::map<uint64_t, int>& bcsMap)
630 const auto& mchTracks =
data.getMCHTracks();
631 const auto& midTracks =
data.getMIDTracks();
632 const auto& mchmidMatches =
data.getMCHMIDMatches();
633 const auto& mchClusters =
data.getMCHTrackClusters();
635 FwdTrackInfo fwdInfo;
636 FwdTrackCovInfo fwdCovInfo;
637 int bcSlice[2] = {-1, -1};
640 auto getMCHBitMap = [&](
int mchTrackID) {
641 if (mchTrackID != -1) {
642 const auto& mchTrack = mchTracks[mchTrackID];
643 int first = mchTrack.getFirstClusterIdx();
644 int last = mchTrack.getLastClusterIdx();
645 for (
int i =
first;
i <= last;
i++) {
646 const auto& cluster = mchClusters[
i];
647 int chamberId = cluster.getChamberId();
648 fwdInfo.mchBitMap |= 1 << chamberId;
653 auto getMIDBitMapBoards = [&](
int midTrackID) {
654 if (midTrackID != -1) {
655 const auto& midTrack = midTracks[midTrackID];
656 fwdInfo.midBitMap = midTrack.getHitMap();
657 fwdInfo.midBoards = midTrack.getEfficiencyWord();
661 auto extrapMCHTrack = [&](
int mchTrackID) {
662 const auto& track = mchTracks[mchTrackID];
670 float vx = 0, vy = 0, vz = 0;
671 if (collisionID >= 0) {
672 const auto&
v =
data.getPrimaryVertex(collisionID);
678 o2::mch::TrackParam trackParamAtVertex(track.getZ(), track.getParameters(), track.getCovariances());
701 double dca = std::sqrt(dcaX * dcaX + dcaY * dcaY);
706 double dpdca = track.getP() * dca;
707 double dchi2 = track.getChi2OverNDF();
709 auto fwdmuon = mMatching.
MCHtoFwd(trackParamAtVertex);
711 fwdInfo.x = fwdmuon.
getX();
712 fwdInfo.y = fwdmuon.getY();
713 fwdInfo.z = fwdmuon.getZ();
714 fwdInfo.phi = fwdmuon.getPhi();
715 fwdInfo.tanl = fwdmuon.getTgl();
716 fwdInfo.invqpt = fwdmuon.getInvQPt();
717 fwdInfo.rabs = std::sqrt(xAbs * xAbs + yAbs * yAbs);
718 fwdInfo.chi2 = dchi2;
719 fwdInfo.pdca = dpdca;
720 fwdInfo.nClusters = track.getNClusters();
722 fwdCovInfo.sigX = TMath::Sqrt(fwdmuon.getCovariances()(0, 0));
723 fwdCovInfo.sigY = TMath::Sqrt(fwdmuon.getCovariances()(1, 1));
724 fwdCovInfo.sigPhi = TMath::Sqrt(fwdmuon.getCovariances()(2, 2));
725 fwdCovInfo.sigTgl = TMath::Sqrt(fwdmuon.getCovariances()(3, 3));
726 fwdCovInfo.sig1Pt = TMath::Sqrt(fwdmuon.getCovariances()(4, 4));
727 fwdCovInfo.rhoXY = (Char_t)(128. * fwdmuon.getCovariances()(0, 1) / (fwdCovInfo.sigX * fwdCovInfo.sigY));
728 fwdCovInfo.rhoPhiX = (Char_t)(128. * fwdmuon.getCovariances()(0, 2) / (fwdCovInfo.sigPhi * fwdCovInfo.sigX));
729 fwdCovInfo.rhoPhiY = (Char_t)(128. * fwdmuon.getCovariances()(1, 2) / (fwdCovInfo.sigPhi * fwdCovInfo.sigY));
730 fwdCovInfo.rhoTglX = (Char_t)(128. * fwdmuon.getCovariances()(0, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigX));
731 fwdCovInfo.rhoTglY = (Char_t)(128. * fwdmuon.getCovariances()(1, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigY));
732 fwdCovInfo.rhoTglPhi = (Char_t)(128. * fwdmuon.getCovariances()(2, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigPhi));
733 fwdCovInfo.rho1PtX = (Char_t)(128. * fwdmuon.getCovariances()(0, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigX));
734 fwdCovInfo.rho1PtY = (Char_t)(128. * fwdmuon.getCovariances()(1, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigY));
735 fwdCovInfo.rho1PtPhi = (Char_t)(128. * fwdmuon.getCovariances()(2, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigPhi));
736 fwdCovInfo.rho1PtTgl = (Char_t)(128. * fwdmuon.getCovariances()(3, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigTgl));
742 int mchTrackID = trackID.getIndex();
743 getMCHBitMap(mchTrackID);
744 if (!extrapMCHTrack(mchTrackID)) {
745 LOGF(warn,
"Unable to extrapolate MCH track with ID %d! Dummy parameters will be used", mchTrackID);
748 const auto& rof =
data.getMCHTracksROFRecords()[mMCHROFs[mchTrackID]];
749 auto time = rof.getTimeMUS(mStartIR).first;
750 fwdInfo.trackTime =
time.getTimeStamp() * 1.e3;
751 fwdInfo.trackTimeRes =
time.getTimeStampError() * 1.e3;
754 auto mchmidMatch = mchmidMatches[trackID.getIndex()];
755 auto mchTrackID = mchmidMatch.getMCHRef().getIndex();
756 if (!extrapMCHTrack(mchTrackID)) {
757 LOGF(warn,
"Unable to extrapolate MCH track with ID %d! Dummy parameters will be used", mchTrackID);
759 auto midTrackID = mchmidMatch.getMIDRef().getIndex();
760 fwdInfo.chi2matchmchmid = mchmidMatch.getMatchChi2OverNDF();
761 getMCHBitMap(mchTrackID);
762 getMIDBitMapBoards(midTrackID);
763 auto time = mchmidMatch.getTimeMUS(mStartIR).first;
764 fwdInfo.trackTime =
time.getTimeStamp() * 1.e3;
765 fwdInfo.trackTimeRes =
time.getTimeStampError() * 1.e3;
767 const auto& track =
data.getGlobalFwdTrack(trackID);
768 const auto& mftTracks =
data.getMFTTracks();
769 const auto& mfttrack = mftTracks[track.getMFTTrackID()];
770 if (!extrapMCHTrack(track.getMCHTrackID())) {
771 LOGF(warn,
"Unable to extrapolate MCH track with ID %d! Dummy parameters will be used", track.getMCHTrackID());
773 fwdInfo.x = track.getX();
774 fwdInfo.y = track.getY();
775 fwdInfo.z = track.getZ();
776 fwdInfo.phi = track.getPhi();
777 fwdInfo.tanl = track.getTanl();
778 fwdInfo.invqpt = track.getInvQPt();
779 fwdInfo.chi2 = track.getTrackChi2();
781 fwdInfo.chi2matchmchmid = track.getMIDMatchingChi2();
782 fwdInfo.chi2matchmchmft = track.getMFTMCHMatchingChi2();
783 fwdInfo.matchscoremchmft = track.getMFTMCHMatchingScore();
784 fwdInfo.matchmfttrackid = mIndexTableMFT[track.getMFTTrackID()];
785 fwdInfo.matchmchtrackid = mIndexTableFwd[track.getMCHTrackID()];
786 fwdInfo.trackTime = track.getTimeMUS().getTimeStamp() * 1.e3;
787 fwdInfo.trackTimeRes = track.getTimeMUS().getTimeStampError() * 1.e3;
789 getMCHBitMap(track.getMCHTrackID());
790 getMIDBitMapBoards(track.getMIDTrackID());
792 fwdCovInfo.sigX = TMath::Sqrt(track.getCovariances()(0, 0));
793 fwdCovInfo.sigY = TMath::Sqrt(track.getCovariances()(1, 1));
794 fwdCovInfo.sigPhi = TMath::Sqrt(track.getCovariances()(2, 2));
795 fwdCovInfo.sigTgl = TMath::Sqrt(track.getCovariances()(3, 3));
796 fwdCovInfo.sig1Pt = TMath::Sqrt(track.getCovariances()(4, 4));
797 fwdCovInfo.rhoXY = (Char_t)(128. * track.getCovariances()(0, 1) / (fwdCovInfo.sigX * fwdCovInfo.sigY));
798 fwdCovInfo.rhoPhiX = (Char_t)(128. * track.getCovariances()(0, 2) / (fwdCovInfo.sigPhi * fwdCovInfo.sigX));
799 fwdCovInfo.rhoPhiY = (Char_t)(128. * track.getCovariances()(1, 2) / (fwdCovInfo.sigPhi * fwdCovInfo.sigY));
800 fwdCovInfo.rhoTglX = (Char_t)(128. * track.getCovariances()(0, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigX));
801 fwdCovInfo.rhoTglY = (Char_t)(128. * track.getCovariances()(1, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigY));
802 fwdCovInfo.rhoTglPhi = (Char_t)(128. * track.getCovariances()(2, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigPhi));
803 fwdCovInfo.rho1PtX = (Char_t)(128. * track.getCovariances()(0, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigX));
804 fwdCovInfo.rho1PtY = (Char_t)(128. * track.getCovariances()(1, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigY));
805 fwdCovInfo.rho1PtPhi = (Char_t)(128. * track.getCovariances()(2, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigPhi));
806 fwdCovInfo.rho1PtTgl = (Char_t)(128. * track.getCovariances()(3, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigTgl));
810 float sX = TMath::Sqrt(mfttrack.getSigma2X()), sY = TMath::Sqrt(mfttrack.getSigma2Y()), sPhi = TMath::Sqrt(mfttrack.getSigma2Phi()),
811 sTgl = TMath::Sqrt(mfttrack.getSigma2Tanl()), sQ2Pt = TMath::Sqrt(mfttrack.getSigma2InvQPt());
813 mftTracksCovCursor(fwdInfo.matchmfttrackid,
814 truncateFloatFraction(sX, mTrackCovDiag),
815 truncateFloatFraction(sY, mTrackCovDiag),
816 truncateFloatFraction(sPhi, mTrackCovDiag),
817 truncateFloatFraction(sTgl, mTrackCovDiag),
818 truncateFloatFraction(sQ2Pt, mTrackCovDiag),
819 (Char_t)(128. * mfttrack.getCovariances()(0, 1) / (sX * sY)),
820 (Char_t)(128. * mfttrack.getCovariances()(0, 2) / (sPhi * sX)),
821 (Char_t)(128. * mfttrack.getCovariances()(1, 2) / (sPhi * sY)),
822 (Char_t)(128. * mfttrack.getCovariances()(0, 3) / (sTgl * sX)),
823 (Char_t)(128. * mfttrack.getCovariances()(1, 3) / (sTgl * sY)),
824 (Char_t)(128. * mfttrack.getCovariances()(2, 3) / (sTgl * sPhi)),
825 (Char_t)(128. * mfttrack.getCovariances()(0, 4) / (sQ2Pt * sX)),
826 (Char_t)(128. * mfttrack.getCovariances()(1, 4) / (sQ2Pt * sY)),
827 (Char_t)(128. * mfttrack.getCovariances()(2, 4) / (sQ2Pt * sPhi)),
828 (Char_t)(128. * mfttrack.getCovariances()(3, 4) / (sQ2Pt * sTgl)));
831 std::uint64_t bcOfTimeRef;
832 bool needBCSlice = collisionID < 0;
834 float err = mTimeMarginTrackTime + fwdInfo.trackTimeRes;
835 bcOfTimeRef = fillBCSlice(bcSlice, fwdInfo.trackTime - err, fwdInfo.trackTime + err, bcsMap);
837 bcOfTimeRef = collisionBC - mStartIR.
toLong();
841 fwdTracksCursor(collisionID,
845 truncateFloatFraction(fwdInfo.z, mTrackX),
846 truncateFloatFraction(fwdInfo.phi, mTrackAlpha),
847 truncateFloatFraction(fwdInfo.tanl, mTrackTgl),
848 truncateFloatFraction(fwdInfo.invqpt, mTrack1Pt),
850 truncateFloatFraction(fwdInfo.pdca, mTrackX),
851 truncateFloatFraction(fwdInfo.rabs, mTrackX),
852 truncateFloatFraction(fwdInfo.chi2, mTrackChi2),
853 truncateFloatFraction(fwdInfo.chi2matchmchmid, mTrackChi2),
854 truncateFloatFraction(fwdInfo.chi2matchmchmft, mTrackChi2),
855 truncateFloatFraction(fwdInfo.matchscoremchmft, mTrackChi2),
856 fwdInfo.matchmfttrackid,
857 fwdInfo.matchmchtrackid,
861 truncateFloatFraction(fwdInfo.trackTime, mTrackTime),
862 truncateFloatFraction(fwdInfo.trackTimeRes, mTrackTimeError));
864 fwdTracksCovCursor(truncateFloatFraction(fwdCovInfo.sigX, mTrackCovDiag),
865 truncateFloatFraction(fwdCovInfo.sigY, mTrackCovDiag),
866 truncateFloatFraction(fwdCovInfo.sigPhi, mTrackCovDiag),
867 truncateFloatFraction(fwdCovInfo.sigTgl, mTrackCovDiag),
868 truncateFloatFraction(fwdCovInfo.sig1Pt, mTrackCovDiag),
874 fwdCovInfo.rhoTglPhi,
877 fwdCovInfo.rho1PtPhi,
878 fwdCovInfo.rho1PtTgl);
881 ambigFwdTracksCursor(mTableTrFwdID, bcSlice);
886void AODProducerWorkflowDPL::updateMCHeader(MCCollisionCursor& collisionCursor,
887 XSectionCursor& xSectionCursor,
888 PdfInfoCursor& pdfInfoCursor,
889 HeavyIonCursor& heavyIonCursor,
890 const MCEventHeader& header,
902 auto genID = updateMCCollisions(collisionCursor,
909 mXSectionUpdate = (updateHepMCXSection(xSectionCursor,
914 ? HepMCUpdate::always
915 : HepMCUpdate::never);
916 mPdfInfoUpdate = (updateHepMCPdfInfo(pdfInfoCursor,
921 ? HepMCUpdate::always
922 : HepMCUpdate::never);
923 mHeavyIonUpdate = (updateHepMCHeavyIon(heavyIonCursor,
928 ? HepMCUpdate::always
929 : HepMCUpdate::never);
932void dimensionMCKeepStore(std::vector<std::vector<std::unordered_map<int, int>>>& store,
int Nsources,
int NEvents)
934 store.resize(Nsources);
935 for (
int s = 0;
s < Nsources; ++
s) {
936 store[
s].resize(NEvents);
942 for (
auto s = 0U;
s < store.size(); ++
s) {
943 for (
auto e = 0U; e < store[
s].size(); ++e) {
953 LOG(warn) <<
"trackID is smaller than 0. Neglecting";
956 if (useSigFilt &&
source == 0) {
964 MCParticlesCursor& mcParticlesCursor,
965 const gsl::span<const o2::dataformats::VtxTrackRef>& primVer2TRefs,
966 const gsl::span<const GIndex>& GIndices,
968 const std::vector<std::vector<int>>& mcColToEvSrc)
972 for (
auto& p : mcColToEvSrc) {
973 NSources = std::max(p[1], NSources);
974 NEvents = std::max(p[2], NEvents);
978 LOG(info) <<
" number of events " << NEvents;
979 LOG(info) <<
" number of sources " << NSources;
982 std::vector<int> particleIDsToKeep;
984 auto markMCTrackForSrc = [&](std::array<GID, GID::NSources>& contributorsGID, uint8_t
src) {
985 auto mcLabel =
data.getTrackMCLabel(contributorsGID[
src]);
986 if (!mcLabel.isValid()) {
989 keepMCParticle(mToStore, mcLabel.getSourceID(), mcLabel.getEventID(), mcLabel.getTrackID(), 1, mUseSigFiltMC);
993 for (
auto& trackRef : primVer2TRefs) {
997 for (
int ti =
start; ti <
end; ti++) {
998 auto& trackIndex = GIndices[ti];
999 if (GIndex::includesSource(
src, mInputSources)) {
1000 auto mcTruth =
data.getTrackMCLabel(trackIndex);
1001 if (!mcTruth.isValid()) {
1004 keepMCParticle(mToStore, mcTruth.getSourceID(), mcTruth.getEventID(), mcTruth.getTrackID(), 1, mUseSigFiltMC);
1006 auto contributorsGID =
data.getSingleDetectorRefs(trackIndex);
1015 for (
auto& mcLabel : labelsTOF) {
1016 if (!mcLabel.isValid()) {
1019 keepMCParticle(mToStore, mcLabel.getSourceID(), mcLabel.getEventID(), mcLabel.getTrackID(), 1, mUseSigFiltMC);
1028 auto& mcCaloEMCCellLabels =
data.getEMCALCellsMCLabels()->getTruthArray();
1029 for (
auto& mcTruth : mcCaloEMCCellLabels) {
1030 if (!mcTruth.isValid()) {
1033 keepMCParticle(mToStore, mcTruth.getSourceID(), mcTruth.getEventID(), mcTruth.getTrackID(), 1, mUseSigFiltMC);
1037 auto& mcCaloPHOSCellLabels =
data.getPHOSCellsMCLabels()->getTruthArray();
1038 for (
auto& mcTruth : mcCaloPHOSCellLabels) {
1039 if (!mcTruth.isValid()) {
1042 keepMCParticle(mToStore, mcTruth.getSourceID(), mcTruth.getEventID(), mcTruth.getTrackID(), 1, mUseSigFiltMC);
1045 using namespace aodmchelpers;
1049 for (
auto& colInfo : mcColToEvSrc) {
1050 int event = colInfo[2];
1052 int mcColId = colInfo[0];
1054 LOG(
debug) <<
"Event=" <<
event <<
" source=" <<
source <<
" collision=" << mcColId;
1073template <
typename MCTrackLabelCursorType,
typename MCMFTTrackLabelCursorType,
typename MCFwdTrackLabelCursorType>
1074void AODProducerWorkflowDPL::fillMCTrackLabelsTable(MCTrackLabelCursorType& mcTrackLabelCursor,
1075 MCMFTTrackLabelCursorType& mcMFTTrackLabelCursor,
1076 MCFwdTrackLabelCursorType& mcFwdTrackLabelCursor,
1078 const gsl::span<const GIndex>& primVerGIs,
1091 mcMFTTrackLabelCursor.reserve(
end -
start + mcMFTTrackLabelCursor.lastIndex());
1092 mcFwdTrackLabelCursor.reserve(
end -
start + mcFwdTrackLabelCursor.lastIndex());
1093 mcTrackLabelCursor.reserve(
end -
start + mcTrackLabelCursor.lastIndex());
1094 for (
int ti =
start; ti <
end; ti++) {
1095 const auto trackIndex = primVerGIs[ti];
1098 auto needToStore = [trackIndex](std::unordered_map<GIndex, int>& mp) {
1099 auto entry = mp.find(trackIndex);
1100 if (
entry == mp.end() ||
entry->second == -1) {
1107 if (GIndex::includesSource(
src, mInputSources)) {
1108 auto mcTruth =
data.getTrackMCLabel(trackIndex);
1109 MCLabels labelHolder{};
1114 if (mcTruth.isValid()) {
1115 labelHolder.labelID = (mToStore[mcTruth.getSourceID()][mcTruth.getEventID()])[mcTruth.getTrackID()];
1117 if (mcTruth.isFake()) {
1118 labelHolder.fwdLabelMask |= (0x1 << 7);
1120 if (mcTruth.isNoise()) {
1121 labelHolder.fwdLabelMask |= (0x1 << 6);
1124 mcMFTTrackLabelCursor(labelHolder.labelID,
1125 labelHolder.fwdLabelMask);
1127 mcFwdTrackLabelCursor(labelHolder.labelID,
1128 labelHolder.fwdLabelMask);
1131 if (!needToStore(mGIDToTableID)) {
1134 if (mcTruth.isValid()) {
1135 labelHolder.labelID = (mToStore[mcTruth.getSourceID()][mcTruth.getEventID()])[mcTruth.getTrackID()];
1136 if (mcTruth.isFake()) {
1137 labelHolder.labelMask |= (0x1 << 15);
1140 auto contributorsGID =
data.getSingleDetectorRefs(trackIndex);
1143 labelHolder.labelMask |= (0x1 << 13);
1148 auto itsGID =
data.getITSContributorGID(trackIndex);
1149 auto itsSource = itsGID.getSource();
1151 auto& itsTrack =
data.getITSTrack(itsGID);
1152 for (
unsigned int iL = 0; iL < 7; ++iL) {
1153 if (itsTrack.isFakeOnLayer(iL)) {
1154 labelHolder.labelMask |= (0x1 << iL);
1158 labelHolder.labelMask |= (
data.getTrackMCLabel(itsGID).isFake() << 12);
1162 }
else if (mcTruth.isNoise()) {
1163 labelHolder.labelMask |= (0x1 << 14);
1165 mcTrackLabelCursor(labelHolder.labelID, labelHolder.labelMask);
1172 auto sTrackLabels =
data.getStrangeTracksMCLabels();
1174 if (!(vertexId < 0 || vertexId >= mVertexStrLUT.size() - 1)) {
1175 mcTrackLabelCursor.reserve(mVertexStrLUT[vertexId + 1] + mcTrackLabelCursor.lastIndex());
1176 for (
int iS{mVertexStrLUT[vertexId]}; iS < mVertexStrLUT[vertexId + 1]; ++iS) {
1177 auto& collStrTrk = mCollisionStrTrk[iS];
1178 auto&
label = sTrackLabels[collStrTrk.second];
1179 MCLabels labelHolder;
1180 labelHolder.labelID =
label.isValid() ? (mToStore[
label.getSourceID()][
label.getEventID()])[
label.getTrackID()] : -1;
1181 labelHolder.labelMask = (
label.isFake() << 15) | (
label.isNoise() << 14);
1182 mcTrackLabelCursor(labelHolder.labelID, labelHolder.labelMask);
1187template <
typename V0CursorType,
typename CascadeCursorType,
typename Decay3BodyCursorType>
1188void AODProducerWorkflowDPL::fillSecondaryVertices(
const o2::globaltracking::RecoContainer& recoData, V0CursorType& v0Cursor, CascadeCursorType& cascadeCursor, Decay3BodyCursorType& decay3BodyCursor)
1195 v0Cursor.reserve(v0s.size());
1197 for (
size_t iv0 = 0; iv0 < v0s.size(); iv0++) {
1198 const auto&
v0 = v0s[iv0];
1199 auto trPosID =
v0.getProngID(0);
1200 auto trNegID =
v0.getProngID(1);
1201 uint8_t v0flags =
v0.getBits();
1202 int posTableIdx = -1, negTableIdx = -1, collID = -1;
1203 auto item = mGIDToTableID.find(trPosID);
1204 if (item != mGIDToTableID.end()) {
1205 posTableIdx = item->second;
1207 LOG(warn) <<
"Could not find a positive track index for prong ID " << trPosID;
1209 item = mGIDToTableID.find(trNegID);
1210 if (item != mGIDToTableID.end()) {
1211 negTableIdx = item->second;
1213 LOG(warn) <<
"Could not find a negative track index for prong ID " << trNegID;
1215 auto itemV = mVtxToTableCollID.find(
v0.getVertexID());
1216 if (itemV == mVtxToTableCollID.end()) {
1217 LOG(warn) <<
"Could not find V0 collisionID for the vertex ID " <<
v0.getVertexID();
1219 collID = itemV->second;
1221 if (posTableIdx != -1 and negTableIdx != -1 and collID != -1) {
1222 v0Cursor(collID, posTableIdx, negTableIdx, v0flags);
1223 mV0ToTableID[
int(iv0)] = mTableV0ID++;
1228 cascadeCursor.reserve(cascades.size());
1229 for (
auto& cascade : cascades) {
1230 auto itemV0 = mV0ToTableID.find(cascade.getV0ID());
1231 if (itemV0 == mV0ToTableID.end()) {
1234 int v0tableID = itemV0->second, bachTableIdx = -1, collID = -1;
1235 auto bachelorID = cascade.getBachelorID();
1236 auto item = mGIDToTableID.find(bachelorID);
1237 if (item != mGIDToTableID.end()) {
1238 bachTableIdx = item->second;
1240 LOG(warn) <<
"Could not find a bachelor track index";
1243 auto itemV = mVtxToTableCollID.find(cascade.getVertexID());
1244 if (itemV != mVtxToTableCollID.end()) {
1245 collID = itemV->second;
1247 LOG(warn) <<
"Could not find cascade collisionID for the vertex ID " << cascade.getVertexID();
1250 cascadeCursor(collID, v0tableID, bachTableIdx);
1254 decay3BodyCursor.reserve(decays3Body.size());
1255 for (
size_t i3Body = 0; i3Body < decays3Body.size(); i3Body++) {
1256 const auto& decay3Body = decays3Body[i3Body];
1258 decay3Body.getProngID(0),
1259 decay3Body.getProngID(1),
1260 decay3Body.getProngID(2)};
1261 int tableIdx[3]{-1, -1, -1}, collID = -1;
1262 bool missing{
false};
1263 for (
int i{0};
i < 3; ++
i) {
1264 auto item = mGIDToTableID.find(trIDs[
i]);
1265 if (item != mGIDToTableID.end()) {
1266 tableIdx[
i] = item->second;
1268 LOG(warn) << fmt::format(
"Could not find a track index for prong ID {}", (
int)trIDs[
i]);
1272 auto itemV = mVtxToTableCollID.find(decay3Body.getVertexID());
1273 if (itemV == mVtxToTableCollID.end()) {
1274 LOG(warn) <<
"Could not find 3 body collisionID for the vertex ID " << decay3Body.getVertexID();
1277 collID = itemV->second;
1282 decay3BodyCursor(collID, tableIdx[0], tableIdx[1], tableIdx[2]);
1286template <
typename FwdTrkClsCursorType>
1293 int mchTrackID = -1;
1295 mchTrackID = trackID.getIndex();
1297 auto mchmidMatch = mchmidMatches[trackID.getIndex()];
1298 mchTrackID = mchmidMatch.getMCHRef().getIndex();
1301 if (mchTrackID > -1 && mchTrackID < mchTracks.size()) {
1302 const auto& mchTrack = mchTracks[mchTrackID];
1303 fwdTrkClsCursor.reserve(mchTrack.getNClusters() + fwdTrkClsCursor.lastIndex());
1304 int first = mchTrack.getFirstClusterIdx();
1305 int last = mchTrack.getLastClusterIdx();
1306 for (
int i =
first;
i <= last;
i++) {
1307 const auto& cluster = mchClusters[
i];
1308 fwdTrkClsCursor(fwdTrackId,
1309 truncateFloatFraction(cluster.x, mMuonCl),
1310 truncateFloatFraction(cluster.y, mMuonCl),
1311 truncateFloatFraction(cluster.z, mMuonCl),
1312 (((cluster.ey < 5.) & 0x1) << 12) | (((cluster.ex < 5.) & 0x1) << 11) | cluster.getDEId());
1317template <
typename HMPCursorType>
1322 hmpCursor.reserve(hmpMatches.size());
1325 for (
size_t iHmp = 0; iHmp < hmpMatches.size(); iHmp++) {
1327 const auto&
match = hmpMatches[iHmp];
1329 float xTrk, yTrk, theta,
phi;
1333 match.getHMPIDtrk(xTrk, yTrk, theta,
phi);
1336 auto photChargeVec =
match.getPhotCharge();
1338 float photChargeVec2[10];
1340 for (Int_t
i = 0;
i < 10;
i++) {
1341 photChargeVec2[
i] = photChargeVec[
i];
1343 auto tref = mGIDToTableID.find(
match.getTrackRef());
1344 if (tref != mGIDToTableID.end()) {
1345 hmpCursor(tref->second,
match.getHMPsignal(), xTrk, yTrk, xMip, yMip, nph,
charge,
match.getIdxHMPClus(),
match.getHmpMom(), photChargeVec2);
1347 LOG(error) <<
"Could not find AOD track table entry for HMP-matched track " <<
match.getTrackRef().asString();
1359 mCollisionStrTrk.clear();
1361 mVertexStrLUT.clear();
1363 for (
auto& sTrk : recoData.getStrangeTracks()) {
1367 vtxId = v0s[sTrk.mDecayRef].getVertexID();
1369 vtxId = cascades[sTrk.mDecayRef].getVertexID();
1371 vtxId = decays3Body[sTrk.mDecayRef].getVertexID();
1373 mCollisionStrTrk.emplace_back(vtxId, sTrkID++);
1374 mVertexStrLUT[vtxId]++;
1376 std::exclusive_scan(mVertexStrLUT.begin(), mVertexStrLUT.end(), mVertexStrLUT.begin(), 0);
1379 std::sort(mCollisionStrTrk.begin(), mCollisionStrTrk.end(), [](
const auto&
a,
const auto&
b) { return a.first < b.first; });
1380 mStrTrkIndices.clear();
1381 mStrTrkIndices.resize(mCollisionStrTrk.size(), -1);
1384template <
typename V0C,
typename CC,
typename D3BC>
1387 int itsTableIdx = -1;
1393 for (
const auto& sTrk : recoData.getStrangeTracks()) {
1403 v0Curs.reserve(nV0);
1404 cascCurs.reserve(nCasc);
1405 d3BodyCurs.reserve(nD3Body);
1407 for (
const auto& sTrk : recoData.getStrangeTracks()) {
1409 auto item = mGIDToTableID.find(ITSIndex);
1410 if (item != mGIDToTableID.end()) {
1411 itsTableIdx = item->second;
1413 LOG(warn) <<
"Could not find a ITS strange track index " << ITSIndex;
1417 v0Curs(mStrTrkIndices[sTrkID++],
1427 sTrk.getAverageClusterSize());
1429 cascCurs(mStrTrkIndices[sTrkID++],
1439 sTrk.getAverageClusterSize());
1441 d3BodyCurs(mStrTrkIndices[sTrkID++],
1451 sTrk.getAverageClusterSize());
1458 const auto& tpcTracks =
data.getTPCTracks();
1459 const auto& tpcClusRefs =
data.getTPCTracksClusterRefs();
1460 const auto& tpcClusShMap =
data.clusterShMapTPC;
1461 const auto& tpcClusAcc =
data.getTPCClusters();
1462 constexpr int maxRows = 152;
1463 constexpr int neighbour = 2;
1464 int ntr = tpcTracks.size();
1465 mTPCCounters.clear();
1466 mTPCCounters.resize(ntr);
1468 int ngroup = std::min(50, std::max(1, ntr / mNThreads));
1469#pragma omp parallel for schedule(dynamic, ngroup) num_threads(mNThreads)
1471 for (
int itr = 0; itr < ntr; itr++) {
1472 std::array<bool, maxRows> clMap{}, shMap{};
1473 uint8_t sectorIndex, rowIndex;
1474 uint32_t clusterIndex;
1475 auto&
counters = mTPCCounters[itr];
1476 const auto& track = tpcTracks[itr];
1477 for (
int i = 0;
i < track.getNClusterReferences();
i++) {
1478 o2::tpc::TrackTPC::getClusterReference(tpcClusRefs,
i, sectorIndex, rowIndex, clusterIndex, track.getClusterRef());
1479 unsigned int absoluteIndex = tpcClusAcc.clusterOffset[sectorIndex][rowIndex] + clusterIndex;
1480 clMap[rowIndex] =
true;
1482 if (!shMap[rowIndex]) {
1485 shMap[rowIndex] =
true;
1489 for (
int i = 0;
i < maxRows;
i++) {
1494 }
else if ((
i - last) <= neighbour) {
1497 int lim = std::min(
i + 1 + neighbour, maxRows);
1498 for (
int j =
i + 1;
j < lim;
j++) {
1513 if (track.getTrackletIndex(il) != -1) {
1517 if (track.getHasNeighbor()) {
1520 if (track.getHasPadrowCrossing()) {
1526template <
typename TCaloHandler,
typename TCaloCursor,
typename TCaloTRGCursor,
typename TMCCaloLabelCursor>
1527void AODProducerWorkflowDPL::addToCaloTable(TCaloHandler& caloHandler, TCaloCursor& caloCellCursor, TCaloTRGCursor& caloTRGCursor,
1528 TMCCaloLabelCursor& mcCaloCellLabelCursor,
int eventID,
int bcID, int8_t caloType)
1530 auto inputEvent = caloHandler.buildEvent(eventID);
1531 auto cellsInEvent = inputEvent.mCells;
1532 auto cellMClabels = inputEvent.mMCCellLabels;
1533 caloCellCursor.reserve(cellsInEvent.size() + caloCellCursor.lastIndex());
1534 caloTRGCursor.reserve(cellsInEvent.size() + caloTRGCursor.lastIndex());
1536 mcCaloCellLabelCursor.reserve(cellsInEvent.size() + mcCaloCellLabelCursor.lastIndex());
1538 for (
auto iCell = 0U; iCell < cellsInEvent.size(); iCell++) {
1539 caloCellCursor(bcID,
1543 cellsInEvent[iCell].
getType(),
1557 std::vector<int32_t> particleIds;
1558 std::vector<float> amplitudeFraction;
1559 if (!mEMCselectLeading) {
1560 particleIds.reserve(cellMClabels.size());
1561 amplitudeFraction.reserve(cellMClabels.size());
1563 float tmpMaxAmplitude = 0;
1564 int32_t tmpindex = 0;
1565 for (
auto& mclabel : cellMClabels[iCell]) {
1567 if (mclabel.isValid()) {
1568 if (mEMCselectLeading) {
1569 if (mclabel.getAmplitudeFraction() > tmpMaxAmplitude) {
1571 if (mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID()).find(mclabel.getTrackID()) !=
1572 mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID()).end()) {
1573 tmpMaxAmplitude = mclabel.getAmplitudeFraction();
1574 tmpindex = (mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID())).at(mclabel.getTrackID());
1578 auto trackStore = mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID());
1579 auto iter = trackStore.find(mclabel.getTrackID());
1580 if (iter != trackStore.end()) {
1581 amplitudeFraction.emplace_back(mclabel.getAmplitudeFraction());
1582 particleIds.emplace_back(iter->second);
1584 particleIds.emplace_back(-1);
1585 amplitudeFraction.emplace_back(0.f);
1586 LOG(warn) <<
"CaloTable: Could not find track for mclabel (" << mclabel.getSourceID() <<
"," << mclabel.getEventID() <<
"," << mclabel.getTrackID() <<
") in the AOD MC store";
1587 if (mMCKineReader) {
1588 auto mctrack = mMCKineReader->
getTrack(mclabel);
1591 LOG(warn) <<
" ... this track is of PDG " << mctrack->GetPdgCode() <<
" produced by " << mctrack->getProdProcessAsString() <<
" at (" <<
vec.X() <<
"," <<
vec.Y() <<
"," <<
vec.Z() <<
")";
1597 if (mEMCselectLeading) {
1598 amplitudeFraction.emplace_back(tmpMaxAmplitude);
1599 particleIds.emplace_back(tmpindex);
1601 if (particleIds.size() == 0) {
1602 particleIds.emplace_back(-1);
1603 amplitudeFraction.emplace_back(0.f);
1605 mcCaloCellLabelCursor(particleIds,
1612template <
typename TCaloCursor,
typename TCaloTRGCursor,
typename TMCCaloLabelCursor>
1613void AODProducerWorkflowDPL::fillCaloTable(TCaloCursor& caloCellCursor, TCaloTRGCursor& caloTRGCursor,
1614 TMCCaloLabelCursor& mcCaloCellLabelCursor,
const std::map<uint64_t, int>& bcsMap,
1618 auto caloEMCCells =
data.getEMCALCells();
1619 auto caloEMCCellsTRGR =
data.getEMCALTriggers();
1620 auto mcCaloEMCCellLabels =
data.getEMCALCellsMCLabels();
1622 auto caloPHOSCells =
data.getPHOSCells();
1623 auto caloPHOSCellsTRGR =
data.getPHOSTriggers();
1624 auto mcCaloPHOSCellLabels =
data.getPHOSCellsMCLabels();
1628 caloPHOSCellsTRGR = {};
1629 mcCaloPHOSCellLabels = {};
1634 caloEMCCellsTRGR = {};
1635 mcCaloEMCCellLabels = {};
1642 emcEventHandler.
reset();
1643 emcEventHandler.
setCellData(caloEMCCells, caloEMCCellsTRGR);
1646 phsEventHandler.
reset();
1647 phsEventHandler.
setCellData(caloPHOSCells, caloPHOSCellsTRGR);
1653 std::vector<std::tuple<uint64_t, int8_t, int>> caloEvents;
1655 caloEvents.reserve(emcNEvents + phsNEvents);
1657 for (
int iev = 0; iev < emcNEvents; ++iev) {
1659 caloEvents.emplace_back(std::make_tuple(
bc, 1, iev));
1662 for (
int iev = 0; iev < phsNEvents; ++iev) {
1664 caloEvents.emplace_back(std::make_tuple(
bc, 0, iev));
1667 std::sort(caloEvents.begin(), caloEvents.end(),
1668 [](
const auto&
left,
const auto&
right) { return std::get<0>(left) < std::get<0>(right); });
1671 for (
int i = 0;
i < emcNEvents + phsNEvents; ++
i) {
1672 uint64_t globalBC = std::get<0>(caloEvents[
i]);
1673 int8_t caloType = std::get<1>(caloEvents[
i]);
1674 int eventID = std::get<2>(caloEvents[
i]);
1675 auto item = bcsMap.find(globalBC);
1677 if (item != bcsMap.end()) {
1678 bcID = item->second;
1680 LOG(warn) <<
"Error: could not find a corresponding BC ID for a calo point; globalBC = " << globalBC <<
", caloType = " << (
int)caloType;
1682 if (caloType == 0) {
1683 addToCaloTable(phsEventHandler, caloCellCursor, caloTRGCursor, mcCaloCellLabelCursor, eventID, bcID, caloType);
1685 if (caloType == 1) {
1686 addToCaloTable(emcEventHandler, caloCellCursor, caloTRGCursor, mcCaloCellLabelCursor, eventID, bcID, caloType);
1697 mLPMProdTag = ic.
options().
get<std::string>(
"lpmp-prod-tag");
1698 mAnchorPass = ic.
options().
get<std::string>(
"anchor-pass");
1699 mAnchorProd = ic.
options().
get<std::string>(
"anchor-prod");
1700 mUser = ic.
options().
get<std::string>(
"created-by");
1701 mRecoPass = ic.
options().
get<std::string>(
"reco-pass");
1702 mTFNumber = ic.
options().
get<int64_t>(
"aod-timeframe-id");
1703 mRecoOnly = ic.
options().
get<
int>(
"reco-mctracks-only");
1704 mTruncate = ic.
options().
get<
int>(
"enable-truncation");
1705 mRunNumber = ic.
options().
get<
int>(
"run-number");
1706 mCTPReadout = ic.
options().
get<
int>(
"ctpreadout-create");
1707 mNThreads = std::max(1, ic.
options().
get<
int>(
"nthreads"));
1708 mEMCselectLeading = ic.
options().
get<
bool>(
"emc-select-leading");
1709 mThinTracks = ic.
options().
get<
bool>(
"thin-tracks");
1710 mPropTracks = ic.
options().
get<
bool>(
"propagate-tracks");
1711 mMaxPropXiu = ic.
options().
get<
float>(
"propagate-tracks-max-xiu");
1712 mPropMuons = ic.
options().
get<
bool>(
"propagate-muons");
1713 if (
auto s = ic.
options().
get<std::string>(
"with-streamers"); !
s.empty()) {
1714 mStreamerFlags.
set(
s);
1715 if (mStreamerFlags) {
1716 LOGP(info,
"Writing streamer data with mask:");
1717 LOG(info) << mStreamerFlags;
1719 LOGP(warn,
"Specified non-default empty streamer mask!");
1722 mTrackQCKeepGlobalTracks = ic.
options().
get<
bool>(
"trackqc-keepglobaltracks");
1723 mTrackQCRetainOnlydEdx = ic.
options().
get<
bool>(
"trackqc-retainonlydedx");
1724 mTrackQCFraction = ic.
options().
get<
float>(
"trackqc-fraction");
1725 mTrackQCNTrCut = ic.
options().
get<int64_t>(
"trackqc-NTrCut");
1726 mTrackQCDCAxy = ic.
options().
get<
float>(
"trackqc-tpc-dca");
1727 mTrackQCPt = ic.
options().
get<
float>(
"trackqc-tpc-pt");
1728 mTrackQCNCls = ic.
options().
get<
int>(
"trackqc-tpc-cls");
1729 if (
auto seed = ic.
options().
get<
int>(
"seed"); seed == 0) {
1730 LOGP(info,
"Using random device for seeding");
1731 std::random_device
rd;
1732 std::array<int, std::mt19937::state_size> seed_data{};
1733 std::generate(std::begin(seed_data), std::end(seed_data), std::ref(
rd));
1734 std::seed_seq seq(std::begin(seed_data), std::end(seed_data));
1735 mGenerator = std::mt19937(seq);
1737 LOGP(info,
"Using seed {} for sampling", seed);
1738 mGenerator.seed(seed);
1741 LOGP(info,
"Multi-threaded parts will run with {} OpenMP threads", mNThreads);
1744 LOG(info) <<
"OpenMP is disabled";
1746 if (mTFNumber == -1L) {
1747 LOG(info) <<
"TFNumber will be obtained from CCDB";
1749 if (mRunNumber == -1L) {
1750 LOG(info) <<
"The Run number will be obtained from DPL headers";
1753 mUseSigFiltMC = ic.
options().
get<
bool>(
"mc-signal-filt");
1756 if (mTruncate != 1) {
1757 LOG(info) <<
"Truncation is not used!";
1758 mCollisionPosition = 0xFFFFFFFF;
1759 mCollisionPositionCov = 0xFFFFFFFF;
1760 mTrackX = 0xFFFFFFFF;
1761 mTrackAlpha = 0xFFFFFFFF;
1762 mTrackSnp = 0xFFFFFFFF;
1763 mTrackTgl = 0xFFFFFFFF;
1764 mTrack1Pt = 0xFFFFFFFF;
1765 mTrackChi2 = 0xFFFFFFFF;
1766 mTrackCovDiag = 0xFFFFFFFF;
1767 mTrackCovOffDiag = 0xFFFFFFFF;
1768 mTrackSignal = 0xFFFFFFFF;
1769 mTrackTime = 0xFFFFFFFF;
1770 mTPCTime0 = 0xFFFFFFFF;
1771 mTrackTimeError = 0xFFFFFFFF;
1772 mTrackPosEMCAL = 0xFFFFFFFF;
1773 mTracklets = 0xFFFFFFFF;
1774 mMcParticleW = 0xFFFFFFFF;
1775 mMcParticlePos = 0xFFFFFFFF;
1776 mMcParticleMom = 0xFFFFFFFF;
1777 mCaloAmp = 0xFFFFFFFF;
1778 mCaloTime = 0xFFFFFFFF;
1779 mCPVPos = 0xFFFFFFFF;
1780 mCPVAmpl = 0xFFFFFFFF;
1781 mMuonTr1P = 0xFFFFFFFF;
1782 mMuonTrThetaX = 0xFFFFFFFF;
1783 mMuonTrThetaY = 0xFFFFFFFF;
1784 mMuonTrZmu = 0xFFFFFFFF;
1785 mMuonTrBend = 0xFFFFFFFF;
1786 mMuonTrNonBend = 0xFFFFFFFF;
1787 mMuonTrCov = 0xFFFFFFFF;
1788 mMuonCl = 0xFFFFFFFF;
1789 mMuonClErr = 0xFFFFFFFF;
1790 mV0Time = 0xFFFFFFFF;
1791 mV0ChannelTime = 0xFFFFFFFF;
1792 mFDDTime = 0xFFFFFFFF;
1793 mFDDChannelTime = 0xFFFFFFFF;
1794 mT0Time = 0xFFFFFFFF;
1795 mT0ChannelTime = 0xFFFFFFFF;
1796 mV0Amplitude = 0xFFFFFFFF;
1797 mFDDAmplitude = 0xFFFFFFFF;
1798 mT0Amplitude = 0xFFFFFFFF;
1802 mZDCEnergyMap[ic] = -std::numeric_limits<float>::infinity();
1805 mZDCTDCMap[ic] = -std::numeric_limits<float>::infinity();
1808 std::string hepmcUpdate = ic.
options().
get<std::string>(
"hepmc-update");
1809 HepMCUpdate when = (hepmcUpdate ==
"never" ? HepMCUpdate::never : hepmcUpdate ==
"always" ? HepMCUpdate::always
1810 : hepmcUpdate ==
"all" ? HepMCUpdate::allKeys
1811 : HepMCUpdate::anyKey);
1812 mXSectionUpdate = when;
1813 mPdfInfoUpdate = when;
1814 mHeavyIonUpdate = when;
1818 if (mStreamerFlags) {
1819 mStreamer = std::make_unique<o2::utils::TreeStreamRedirector>(
"AO2DStreamer.root",
"RECREATE");
1825void add_additional_meta_info(std::vector<TString>& keys, std::vector<TString>&
values)
1828 auto aod_external_meta_info_file = getenv(
"AOD_ADDITIONAL_METADATA_FILE");
1829 if (aod_external_meta_info_file !=
nullptr) {
1830 LOG(info) <<
"Trying to inject additional AOD meta-data from " << aod_external_meta_info_file;
1831 if (std::filesystem::exists(aod_external_meta_info_file)) {
1832 std::ifstream input_file(aod_external_meta_info_file);
1834 nlohmann::json json_data;
1836 input_file >> json_data;
1837 }
catch (nlohmann::json::parse_error& e) {
1838 std::cerr <<
"JSON Parse Error: " << e.what() <<
"\n";
1839 std::cerr <<
"Exception ID: " << e.id <<
"\n";
1840 std::cerr <<
"Byte position: " << e.byte <<
"\n";
1844 for (
const auto& [
key,
value] : json_data.items()) {
1845 LOG(info) <<
"Adding AOD MetaData" <<
key <<
" : " <<
value;
1846 keys.push_back(
key.c_str());
1857 mTimer.Start(
false);
1860 updateTimeDependentParams(pc);
1885 std::vector<o2::ctp::CTPDigit> ctpDigitsCreated;
1886 if (mCTPReadout == 1) {
1887 LOG(info) <<
"CTP : creating ctpreadout in AOD producer";
1888 createCTPReadout(recoData, ctpDigitsCreated, pc);
1889 LOG(info) <<
"CTP : ctpreadout created from AOD";
1890 ctpDigits = gsl::span<o2::ctp::CTPDigit>(ctpDigitsCreated);
1892 LOG(
debug) <<
"FOUND " << primVertices.size() <<
" primary vertices";
1893 LOG(
debug) <<
"FOUND " << ft0RecPoints.size() <<
" FT0 rec. points";
1894 LOG(
debug) <<
"FOUND " << fv0RecPoints.size() <<
" FV0 rec. points";
1895 LOG(
debug) <<
"FOUND " << fddRecPoints.size() <<
" FDD rec. points";
1896 LOG(
debug) <<
"FOUND " << cpvClusters.size() <<
" CPV clusters";
1897 LOG(
debug) <<
"FOUND " << cpvTrigRecs.size() <<
" CPV trigger records";
1899 LOG(info) <<
"FOUND " << primVertices.size() <<
" primary vertices";
1903 auto bcCursor = createTableCursor<o2::aod::BCs>(pc);
1904 auto bcFlagsCursor = createTableCursor<o2::aod::BCFlags>(pc);
1905 auto cascadesCursor = createTableCursor<o2::aod::Cascades>(pc);
1906 auto collisionsCursor = createTableCursor<o2::aod::Collisions>(pc);
1907 auto decay3BodyCursor = createTableCursor<o2::aod::Decay3Bodys>(pc);
1908 auto trackedCascadeCursor = createTableCursor<o2::aod::TrackedCascades>(pc);
1909 auto trackedV0Cursor = createTableCursor<o2::aod::TrackedV0s>(pc);
1910 auto tracked3BodyCurs = createTableCursor<o2::aod::Tracked3Bodys>(pc);
1911 auto fddCursor = createTableCursor<o2::aod::FDDs>(pc);
1912 auto fddExtraCursor = createTableCursor<o2::aod::FDDsExtra>(pc);
1913 auto ft0Cursor = createTableCursor<o2::aod::FT0s>(pc);
1914 auto ft0ExtraCursor = createTableCursor<o2::aod::FT0sExtra>(pc);
1915 auto fv0aCursor = createTableCursor<o2::aod::FV0As>(pc);
1916 auto fv0aExtraCursor = createTableCursor<o2::aod::FV0AsExtra>(pc);
1917 auto fwdTracksCursor = createTableCursor<o2::aod::StoredFwdTracks>(pc);
1918 auto fwdTracksCovCursor = createTableCursor<o2::aod::StoredFwdTracksCov>(pc);
1919 auto fwdTrkClsCursor = createTableCursor<o2::aod::FwdTrkCls>(pc);
1920 auto mftTracksCursor = createTableCursor<o2::aod::StoredMFTTracks>(pc);
1921 auto mftTracksCovCursor = createTableCursor<o2::aod::StoredMFTTracksCov>(pc);
1922 auto tracksCursor = createTableCursor<o2::aod::StoredTracksIU>(pc);
1923 auto tracksCovCursor = createTableCursor<o2::aod::StoredTracksCovIU>(pc);
1924 auto tracksExtraCursor = createTableCursor<o2::aod::StoredTracksExtra>(pc);
1925 auto tracksQACursor = createTableCursor<o2::aod::TracksQAVersion>(pc);
1926 auto ambigTracksCursor = createTableCursor<o2::aod::AmbiguousTracks>(pc);
1927 auto ambigMFTTracksCursor = createTableCursor<o2::aod::AmbiguousMFTTracks>(pc);
1928 auto ambigFwdTracksCursor = createTableCursor<o2::aod::AmbiguousFwdTracks>(pc);
1929 auto v0sCursor = createTableCursor<o2::aod::V0s>(pc);
1930 auto zdcCursor = createTableCursor<o2::aod::Zdcs>(pc);
1931 auto hmpCursor = createTableCursor<o2::aod::HMPIDs>(pc);
1932 auto caloCellsCursor = createTableCursor<o2::aod::Calos>(pc);
1933 auto caloCellsTRGTableCursor = createTableCursor<o2::aod::CaloTriggers>(pc);
1934 auto cpvClustersCursor = createTableCursor<o2::aod::CPVClusters>(pc);
1935 auto originCursor = createTableCursor<o2::aod::Origins>(pc);
1949 mcColLabelsCursor = createTableCursor<o2::aod::McCollisionLabels>(pc);
1950 mcCollisionsCursor = createTableCursor<o2::aod::McCollisions>(pc);
1951 hepmcXSectionsCursor = createTableCursor<o2::aod::HepMCXSections>(pc);
1952 hepmcPdfInfosCursor = createTableCursor<o2::aod::HepMCPdfInfos>(pc);
1953 hepmcHeavyIonsCursor = createTableCursor<o2::aod::HepMCHeavyIons>(pc);
1954 mcMFTTrackLabelCursor = createTableCursor<o2::aod::McMFTTrackLabels>(pc);
1955 mcFwdTrackLabelCursor = createTableCursor<o2::aod::McFwdTrackLabels>(pc);
1956 mcParticlesCursor = createTableCursor<o2::aod::StoredMcParticles_001>(pc);
1957 mcTrackLabelCursor = createTableCursor<o2::aod::McTrackLabels>(pc);
1958 mcCaloLabelsCursor = createTableCursor<o2::aod::McCaloLabels_001>(pc);
1961 std::unique_ptr<o2::steer::MCKinematicsReader> mcReader;
1963 mcReader = std::make_unique<o2::steer::MCKinematicsReader>(
"collisioncontext.root");
1965 mMCKineReader = mcReader.get();
1966 std::map<uint64_t, int> bcsMap;
1967 collectBCs(recoData, mUseMC ? mcReader->getDigitizationContext()->getEventRecords() : std::vector<o2::InteractionTimeRecord>{}, bcsMap);
1968 if (!primVer2TRefs.empty()) {
1969 addRefGlobalBCsForTOF(primVer2TRefs.back(), primVerGIs, recoData, bcsMap);
1972 mBCLookup.
init(bcsMap);
1975 const int runNumber = (mRunNumber == -1) ?
int(tinfo.runNumber) : mRunNumber;
1976 if (mTFNumber == -1L) {
1978 tfNumber = uint64_t(tinfo.firstTForbit) + (uint64_t(tinfo.runNumber) << 32);
1980 tfNumber = mTFNumber;
1983 std::vector<float> aAmplitudes, aTimes;
1984 std::vector<uint8_t> aChannels;
1985 fv0aCursor.reserve(fv0RecPoints.size());
1986 for (
auto& fv0RecPoint : fv0RecPoints) {
1987 aAmplitudes.clear();
1990 const auto channelData = fv0RecPoint.getBunchChannelData(fv0ChData);
1991 for (
auto& channel : channelData) {
1992 if (channel.charge > 0) {
1993 aAmplitudes.push_back(truncateFloatFraction(channel.charge, mV0Amplitude));
1994 aTimes.push_back(truncateFloatFraction(channel.time * 1.E-3, mV0ChannelTime));
1995 aChannels.push_back(channel.channel);
1998 uint64_t
bc = fv0RecPoint.getInteractionRecord().toLong();
1999 auto item = bcsMap.find(
bc);
2001 if (item != bcsMap.end()) {
2002 bcID = item->second;
2004 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a FV0 rec. point; BC = " <<
bc;
2009 truncateFloatFraction(fv0RecPoint.getCollisionGlobalMeanTime() * 1E-3, mV0Time),
2010 fv0RecPoint.getTrigger().getTriggersignals());
2012 if (mEnableFITextra) {
2013 fv0aExtraCursor(bcID,
2018 std::vector<float> zdcEnergy, zdcAmplitudes, zdcTime;
2019 std::vector<uint8_t> zdcChannelsE, zdcChannelsT;
2020 zdcCursor.reserve(zdcBCRecData.size());
2021 for (
auto zdcRecData : zdcBCRecData) {
2022 uint64_t
bc = zdcRecData.ir.toLong();
2023 auto item = bcsMap.find(
bc);
2025 if (item != bcsMap.end()) {
2026 bcID = item->second;
2028 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a ZDC rec. point; BC = " <<
bc;
2030 int fe, ne, ft, nt, fi, ni;
2031 zdcRecData.getRef(fe, ne, ft, nt, fi, ni);
2033 zdcChannelsE.clear();
2034 zdcAmplitudes.clear();
2036 zdcChannelsT.clear();
2037 for (
int ie = 0; ie < ne; ie++) {
2038 auto& zdcEnergyData = zdcEnergies[fe + ie];
2039 zdcEnergy.emplace_back(zdcEnergyData.energy());
2040 zdcChannelsE.emplace_back(zdcEnergyData.ch());
2042 for (
int it = 0; it < nt; it++) {
2043 auto& tdc = zdcTDCData[ft + it];
2044 zdcAmplitudes.emplace_back(tdc.amplitude());
2045 zdcTime.emplace_back(tdc.value());
2059 std::vector<std::vector<int>> mcColToEvSrc;
2065 int nMCCollisions = mcReader->getDigitizationContext()->getNCollisions();
2066 const auto& mcRecords = mcReader->getDigitizationContext()->getEventRecords();
2067 const auto& mcParts = mcReader->getDigitizationContext()->getEventParts();
2070 if (mUseSigFiltMC) {
2071 std::vector<int> sourceIDs{};
2072 for (
int iCol = 0; iCol < nMCCollisions; iCol++) {
2073 for (
auto const& colPart : mcParts[iCol]) {
2074 int sourceID = colPart.sourceID;
2075 if (std::find(sourceIDs.begin(), sourceIDs.end(), sourceID) == sourceIDs.end()) {
2076 sourceIDs.push_back(sourceID);
2078 if (sourceIDs.size() > 1) {
2082 if (sourceIDs.size() > 1) {
2086 if (sourceIDs.size() <= 1) {
2087 LOGP(fatal,
"Signal filtering cannot be enabled without embedding. Please fix the configuration either enabling the embedding, or turning off the signal filtering.");
2092 int totalNParts = 0;
2093 for (
int iCol = 0; iCol < nMCCollisions; iCol++) {
2094 totalNParts += mcParts[iCol].size();
2096 mcCollisionsCursor.
reserve(totalNParts);
2098 for (
int iCol = 0; iCol < nMCCollisions; iCol++) {
2099 const auto time = mcRecords[iCol].getTimeOffsetWrtBC();
2100 auto globalBC = mcRecords[iCol].toLong();
2101 auto item = bcsMap.find(globalBC);
2103 if (item != bcsMap.end()) {
2104 bcID = item->second;
2106 LOG(fatal) <<
"Error: could not find a corresponding BC ID "
2107 <<
"for MC collision; BC = " << globalBC
2108 <<
", mc collision = " << iCol;
2110 auto& colParts = mcParts[iCol];
2111 auto nParts = colParts.size();
2112 for (
auto colPart : colParts) {
2113 auto eventID = colPart.entryID;
2114 auto sourceID = colPart.sourceID;
2117 if (nParts == 1 || sourceID == 0) {
2120 auto& header = mcReader->getMCEventHeader(sourceID, eventID);
2121 updateMCHeader(mcCollisionsCursor.
cursor,
2122 hepmcXSectionsCursor.
cursor,
2123 hepmcPdfInfosCursor.
cursor,
2124 hepmcHeavyIonsCursor.
cursor,
2132 mcColToEvSrc.emplace_back(std::vector<int>{iCol, sourceID, eventID});
2137 std::sort(mcColToEvSrc.begin(), mcColToEvSrc.end(),
2138 [](
const std::vector<int>&
left,
const std::vector<int>&
right) { return (left[0] < right[0]); });
2141 int16_t aFDDAmplitudesA[8] = {0u}, aFDDAmplitudesC[8] = {0u};
2142 float aFDDTimesA[8] = {0.f}, aFDDTimesC[8] = {0.f};
2144 fddCursor.reserve(fddRecPoints.size());
2145 for (
const auto& fddRecPoint : fddRecPoints) {
2146 for (
int i = 0;
i < 8;
i++) {
2147 aFDDAmplitudesA[
i] = 0;
2148 aFDDAmplitudesC[
i] = 0;
2149 aFDDTimesA[
i] = 0.f;
2150 aFDDTimesC[
i] = 0.f;
2152 uint64_t globalBC = fddRecPoint.getInteractionRecord().toLong();
2153 uint64_t
bc = globalBC;
2154 auto item = bcsMap.find(
bc);
2156 if (item != bcsMap.end()) {
2157 bcID = item->second;
2159 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a FDD rec. point; BC = " <<
bc;
2161 const auto channelData = fddRecPoint.getBunchChannelData(fddChData);
2162 for (
const auto& channel : channelData) {
2163 if (channel.mPMNumber < 8) {
2164 aFDDAmplitudesC[channel.mPMNumber] = channel.mChargeADC;
2165 aFDDTimesC[channel.mPMNumber] = truncateFloatFraction(channel.mTime * 1E-3, mFDDChannelTime);
2167 aFDDAmplitudesA[channel.mPMNumber - 8] = channel.mChargeADC;
2168 aFDDTimesA[channel.mPMNumber - 8] = truncateFloatFraction(channel.mTime * 1E-3, mFDDChannelTime);
2175 truncateFloatFraction(fddRecPoint.getCollisionTimeA() * 1E-3, mFDDTime),
2176 truncateFloatFraction(fddRecPoint.getCollisionTimeC() * 1E-3, mFDDTime),
2177 fddRecPoint.getTrigger().getTriggersignals());
2178 if (mEnableFITextra) {
2179 fddExtraCursor(bcID,
2186 std::vector<float> aAmplitudesA, aAmplitudesC, aTimesA, aTimesC;
2187 std::vector<uint8_t> aChannelsA, aChannelsC;
2188 ft0Cursor.reserve(ft0RecPoints.size());
2189 for (
auto& ft0RecPoint : ft0RecPoints) {
2190 aAmplitudesA.clear();
2191 aAmplitudesC.clear();
2196 const auto channelData = ft0RecPoint.getBunchChannelData(ft0ChData);
2197 for (
auto& channel : channelData) {
2199 if (channel.QTCAmpl > 0) {
2201 if (channel.ChId < nFT0ChannelsAside) {
2202 aChannelsA.push_back(channel.ChId);
2203 aAmplitudesA.push_back(truncateFloatFraction(channel.QTCAmpl, mT0Amplitude));
2204 aTimesA.push_back(truncateFloatFraction(channel.CFDTime * 1E-3, mT0ChannelTime));
2206 aChannelsC.push_back(channel.ChId - nFT0ChannelsAside);
2207 aAmplitudesC.push_back(truncateFloatFraction(channel.QTCAmpl, mT0Amplitude));
2208 aTimesC.push_back(truncateFloatFraction(channel.CFDTime * 1E-3, mT0ChannelTime));
2212 uint64_t globalBC = ft0RecPoint.getInteractionRecord().toLong();
2213 uint64_t
bc = globalBC;
2214 auto item = bcsMap.find(
bc);
2216 if (item != bcsMap.end()) {
2217 bcID = item->second;
2219 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a FT0 rec. point; BC = " <<
bc;
2226 truncateFloatFraction(ft0RecPoint.getCollisionTimeA() * 1E-3, mT0Time),
2227 truncateFloatFraction(ft0RecPoint.getCollisionTimeC() * 1E-3, mT0Time),
2228 ft0RecPoint.getTrigger().getTriggersignals());
2229 if (mEnableFITextra) {
2230 ft0ExtraCursor(bcID,
2238 mcColLabelsCursor.
reserve(primVerLabels.size());
2239 for (
auto&
label : primVerLabels) {
2240 auto it = std::find_if(mcColToEvSrc.begin(), mcColToEvSrc.end(),
2241 [&
label](
const auto& mcColInfo) { return mcColInfo[1] == label.getSourceID() && mcColInfo[2] == label.getEventID(); });
2242 int32_t mcCollisionID = -1;
2243 if (it != mcColToEvSrc.end()) {
2244 mcCollisionID = it->at(0);
2246 uint16_t mcMask = 0;
2247 mcColLabelsCursor(mcCollisionID, mcMask);
2251 cacheTriggers(recoData);
2252 countTPCClusters(recoData);
2254 int collisionID = 0;
2258 auto& trackReffwd = primVer2TRefs.back();
2259 fillIndexTablesPerCollision(trackReffwd, primVerGIs, recoData);
2261 for (
auto&
vertex : primVertices) {
2262 auto& trackReffwd = primVer2TRefs[collisionID];
2263 fillIndexTablesPerCollision(trackReffwd, primVerGIs, recoData);
2268 prepareStrangenessTracking(recoData);
2270 mGIDToTableFwdID.clear();
2271 mGIDToTableMFTID.clear();
2273 if (mPropTracks || mThinTracks) {
2277 mGIDUsedBySVtx.reserve(v0s.size() * 2 + cascades.size() + decays3Body.size() * 3);
2278 for (
const auto&
v0 : v0s) {
2279 mGIDUsedBySVtx.insert(
v0.getProngID(0));
2280 mGIDUsedBySVtx.insert(
v0.getProngID(1));
2282 for (
const auto& cascade : cascades) {
2283 mGIDUsedBySVtx.insert(cascade.getBachelorID());
2285 for (
const auto& id3Body : decays3Body) {
2286 mGIDUsedBySVtx.insert(id3Body.getProngID(0));
2287 mGIDUsedBySVtx.insert(id3Body.getProngID(1));
2288 mGIDUsedBySVtx.insert(id3Body.getProngID(2));
2299 auto& trackRef = primVer2TRefs.back();
2301 fillTrackTablesPerCollision(-1, std::uint64_t(-1), trackRef, primVerGIs, recoData, tracksCursor, tracksCovCursor, tracksExtraCursor, tracksQACursor,
2302 ambigTracksCursor, mftTracksCursor, mftTracksCovCursor, ambigMFTTracksCursor,
2303 fwdTracksCursor, fwdTracksCovCursor, ambigFwdTracksCursor, fwdTrkClsCursor, bcsMap);
2307 collisionsCursor.reserve(primVertices.size());
2308 for (
auto&
vertex : primVertices) {
2309 auto& cov =
vertex.getCov();
2310 auto& timeStamp =
vertex.getTimeStamp();
2311 const double interactionTime = timeStamp.getTimeStamp() * 1E3;
2312 uint64_t globalBC = relativeTime_to_GlobalBC(interactionTime);
2313 uint64_t localBC = relativeTime_to_LocalBC(interactionTime);
2314 LOG(
debug) <<
"global BC " << globalBC <<
" local BC " << localBC <<
" relative interaction time " << interactionTime;
2317 auto item = bcsMap.find(globalBC);
2319 if (item != bcsMap.end()) {
2320 bcID = item->second;
2322 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a collision; BC = " << globalBC <<
", collisionID = " << collisionID;
2324 collisionsCursor(bcID,
2325 truncateFloatFraction(
vertex.getX(), mCollisionPosition),
2326 truncateFloatFraction(
vertex.getY(), mCollisionPosition),
2327 truncateFloatFraction(
vertex.getZ(), mCollisionPosition),
2328 truncateFloatFraction(cov[0], mCollisionPositionCov),
2329 truncateFloatFraction(cov[1], mCollisionPositionCov),
2330 truncateFloatFraction(cov[2], mCollisionPositionCov),
2331 truncateFloatFraction(cov[3], mCollisionPositionCov),
2332 truncateFloatFraction(cov[4], mCollisionPositionCov),
2333 truncateFloatFraction(cov[5], mCollisionPositionCov),
2335 truncateFloatFraction(
vertex.getChi2(), mCollisionPositionCov),
2336 vertex.getNContributors(),
2337 truncateFloatFraction(relInteractionTime, mCollisionPosition),
2338 truncateFloatFraction(timeStamp.getTimeStampError() * 1E3, mCollisionPositionCov));
2339 mVtxToTableCollID[collisionID] = mTableCollID++;
2341 auto& trackRef = primVer2TRefs[collisionID];
2343 fillTrackTablesPerCollision(collisionID, globalBC, trackRef, primVerGIs, recoData, tracksCursor, tracksCovCursor, tracksExtraCursor, tracksQACursor, ambigTracksCursor,
2344 mftTracksCursor, mftTracksCovCursor, ambigMFTTracksCursor,
2345 fwdTracksCursor, fwdTracksCovCursor, ambigFwdTracksCursor, fwdTrkClsCursor, bcsMap);
2349 fillSecondaryVertices(recoData, v0sCursor, cascadesCursor, decay3BodyCursor);
2350 fillHMPID(recoData, hmpCursor);
2351 fillStrangenessTrackingTables(recoData, trackedV0Cursor, trackedCascadeCursor, tracked3BodyCurs);
2355 std::unordered_map<uint64_t, std::pair<uint64_t, uint64_t>> bcToClassMask;
2357 LOG(
debug) <<
"CTP input available";
2358 for (
auto& ctpDigit : ctpDigits) {
2359 uint64_t
bc = ctpDigit.intRecord.toLong();
2360 uint64_t classMask = ctpDigit.CTPClassMask.to_ulong();
2361 uint64_t inputMask = ctpDigit.CTPInputMask.to_ulong();
2362 if (emcalIncomplete.find(
bc) != emcalIncomplete.end()) {
2364 auto classMaskOrig = classMask;
2365 classMask = classMask & ~mEMCALTrgClassMask;
2366 LOG(
debug) <<
"Found EMCAL incomplete event, mask before " << std::bitset<64>(classMaskOrig) <<
", after " << std::bitset<64>(classMask);
2368 bcToClassMask[
bc] = {classMask, inputMask};
2374 bcCursor.reserve(bcsMap.size());
2375 for (
auto& item : bcsMap) {
2376 uint64_t
bc = item.first;
2377 std::pair<uint64_t, uint64_t> masks{0, 0};
2379 auto bcClassPair = bcToClassMask.find(
bc);
2380 if (bcClassPair != bcToClassMask.end()) {
2381 masks = bcClassPair->second;
2390 bcToClassMask.clear();
2393 auto bcFlags = fillBCFlags(recoData, bcsMap);
2394 bcFlagsCursor.reserve(bcFlags.size());
2395 for (
auto f : bcFlags) {
2402 cpvClustersCursor.reserve(cpvTrigRecs.size());
2403 for (
auto& cpvEvent : cpvTrigRecs) {
2404 uint64_t
bc = cpvEvent.getBCData().toLong();
2405 auto item = bcsMap.find(
bc);
2407 if (item != bcsMap.end()) {
2408 bcID = item->second;
2410 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a CPV Trigger Record; BC = " <<
bc;
2412 for (
int iClu = cpvEvent.getFirstEntry(); iClu < cpvEvent.getFirstEntry() + cpvEvent.getNumberOfObjects(); iClu++) {
2413 auto&
clu = cpvClusters[iClu];
2414 clu.getLocalPosition(posX, posZ);
2415 cpvClustersCursor(bcID,
2416 truncateFloatFraction(posX, mCPVPos),
2417 truncateFloatFraction(posZ, mCPVPos),
2418 truncateFloatFraction(
clu.getEnergy(), mCPVAmpl),
2419 clu.getPackedClusterStatus());
2428 fillMCParticlesTable(*mcReader,
2429 mcParticlesCursor.
cursor,
2435 LOG(info) <<
"FILL MC took " << timer.RealTime() <<
" s";
2436 mcColToEvSrc.clear();
2442 fillMCTrackLabelsTable(mcTrackLabelCursor, mcMFTTrackLabelCursor, mcFwdTrackLabelCursor, primVer2TRefs.back(), primVerGIs, recoData);
2443 for (
auto iref = 0U; iref < primVer2TRefs.size() - 1; iref++) {
2444 auto& trackRef = primVer2TRefs[iref];
2445 fillMCTrackLabelsTable(mcTrackLabelCursor, mcMFTTrackLabelCursor, mcFwdTrackLabelCursor, trackRef, primVerGIs, recoData, iref);
2451 fillCaloTable(caloCellsCursor, caloCellsTRGTableCursor, mcCaloLabelsCursor, bcsMap, recoData);
2456 mGIDToTableID.clear();
2458 mGIDToTableFwdID.clear();
2460 mGIDToTableMFTID.clear();
2462 mVtxToTableCollID.clear();
2464 mV0ToTableID.clear();
2467 mIndexTableFwd.clear();
2469 mIndexTableMFT.clear();
2474 mGIDUsedBySVtx.clear();
2475 mGIDUsedByStr.clear();
2477 originCursor(tfNumber);
2480 TString dataType = mUseMC ?
"MC" :
"RAW";
2482 TString ROOTVersion = ROOT_RELEASE;
2483 mMetaDataKeys = {
"DataType",
"Run",
"O2Version",
"ROOTVersion",
"RecoPassName",
"AnchorProduction",
"AnchorPassName",
"LPMProductionTag",
"CreatedBy"};
2484 mMetaDataVals = {dataType,
"3", O2Version, ROOTVersion, mRecoPass, mAnchorProd, mAnchorPass, mLPMProdTag, mUser};
2485 add_additional_meta_info(mMetaDataKeys, mMetaDataVals);
2503 for (
const auto& rof : rofs) {
2504 int first = rof.getFirstEntry(), last =
first + rof.getNEntries();
2505 for (
int i =
first;
i < last;
i++) {
2506 mITSROFs.push_back(
count);
2516 for (
const auto& rof : rofs) {
2517 int first = rof.getFirstEntry(),
last =
first + rof.getNEntries();
2519 mMFTROFs.push_back(
count);
2526 mITSTPCTRDTriggers.clear();
2529 for (
const auto& trig : itstpctrigs) {
2530 int first = trig.getFirstTrack(),
last =
first + trig.getNumberOfTracks();
2532 mITSTPCTRDTriggers.push_back(
count);
2539 mTPCTRDTriggers.clear();
2542 for (
const auto& trig : tpctrigs) {
2543 int first = trig.getFirstTrack(),
last =
first + trig.getNumberOfTracks();
2545 mTPCTRDTriggers.push_back(
count);
2555 for (
const auto& rof : rofs) {
2558 mMCHROFs.push_back(
count);
2565AODProducerWorkflowDPL::TrackExtraInfo AODProducerWorkflowDPL::processBarrelTrack(
int collisionID, std::uint64_t collisionBC,
GIndex trackIndex,
2568 TrackExtraInfo extraInfoHolder;
2569 if (collisionID < 0) {
2572 bool needBCSlice = collisionID < 0;
2573 uint64_t bcOfTimeRef = collisionBC - mStartIR.
toLong();
2575 auto setTrackTime = [&](
double t,
double terr,
bool gaussian) {
2581 extraInfoHolder.trackTimeRes = terr;
2583 double error = this->mTimeMarginTrackTime + (gaussian ? extraInfoHolder.trackTimeRes * this->mNSigmaTimeTrack : extraInfoHolder.trackTimeRes);
2584 bcOfTimeRef = fillBCSlice(extraInfoHolder.bcSlice, t - error, t + error, bcsMap);
2587 extraInfoHolder.diffBCRef =
int(bcOfTimeRef);
2589 truncateFloatFraction(extraInfoHolder.trackTime, mTrackTime), truncateFloatFraction(extraInfoHolder.trackTimeRes, mTrackTimeError),
2592 auto contributorsGID =
data.getSingleDetectorRefs(trackIndex);
2593 const auto& trackPar =
data.getTrackParam(trackIndex);
2594 extraInfoHolder.flags |= trackPar.getPID() << 28;
2595 auto src = trackIndex.getSource();
2597 const auto& tofMatch =
data.getTOFMatch(trackIndex);
2598 extraInfoHolder.tofChi2 = tofMatch.getChi2();
2599 const auto& tofInt = tofMatch.getLTIntegralOut();
2600 float intLen = tofInt.getL();
2601 extraInfoHolder.length = intLen;
2608 extraInfoHolder.tofExpMom = mass * expBeta / std::sqrt(1.f - expBeta * expBeta);
2611 const double massZ = o2::track::PID::getMass2Z(trackPar.getPID());
2612 const double energy = sqrt((massZ * massZ) + (extraInfoHolder.tofExpMom * extraInfoHolder.tofExpMom));
2613 const double exp = extraInfoHolder.length * energy / (cSpeed * extraInfoHolder.tofExpMom);
2614 auto tofSignal = (tofMatch.getSignal() -
exp) * 1e-3;
2615 setTrackTime(tofSignal, 0.2,
true);
2619 extraInfoHolder.trdChi2 = trdOrig.getChi2();
2620 extraInfoHolder.trdSignal = trdOrig.getSignal();
2621 extraInfoHolder.trdPattern = getTRDPattern(trdOrig);
2622 if (extraInfoHolder.trackTimeRes < 0.) {
2624 const auto& trdTrig = (
src ==
GIndex::Source::TPCTRD) ?
data.getTPCTRDTriggers()[mTPCTRDTriggers[trackIndex.getIndex()]] :
data.getITSTPCTRDTriggers()[mITSTPCTRDTriggers[trackIndex.getIndex()]];
2626 setTrackTime(ttrig, 1.,
true);
2630 const auto& itsTrack =
data.getITSTrack(contributorsGID[
GIndex::ITS]);
2631 int nClusters = itsTrack.getNClusters();
2632 float chi2 = itsTrack.getChi2();
2634 extraInfoHolder.itsClusterSizes = itsTrack.getClusterSizes();
2636 const auto& rof =
data.getITSTracksROFRecords()[mITSROFs[trackIndex.getIndex()]];
2638 setTrackTime(t, mITSROFrameHalfLengthNS,
false);
2641 extraInfoHolder.itsClusterSizes =
data.getITSABRefs()[contributorsGID[
GIndex::Source::ITSAB].getIndex()].getClusterSizes();
2645 const auto& tpcClData = mTPCCounters[contributorsGID[
GIndex::TPC]];
2646 const auto& dEdx = tpcOrig.getdEdx().dEdxTotTPC > 0 ? tpcOrig.getdEdx() : tpcOrig.getdEdxAlt();
2647 if (tpcOrig.getdEdx().dEdxTotTPC == 0) {
2650 if (tpcOrig.hasASideClusters()) {
2653 if (tpcOrig.hasCSideClusters()) {
2656 extraInfoHolder.tpcInnerParam = tpcOrig.getP() / tpcOrig.getAbsCharge();
2657 extraInfoHolder.tpcChi2NCl = tpcOrig.getNClusters() ? tpcOrig.getChi2() / tpcOrig.getNClusters() : 0;
2658 extraInfoHolder.tpcSignal = dEdx.dEdxTotTPC;
2659 extraInfoHolder.tpcNClsFindable = tpcOrig.getNClusters();
2660 extraInfoHolder.tpcNClsFindableMinusFound = tpcOrig.getNClusters() - tpcClData.found;
2661 extraInfoHolder.tpcNClsFindableMinusCrossedRows = tpcOrig.getNClusters() - tpcClData.crossed;
2662 extraInfoHolder.tpcNClsShared = tpcClData.shared;
2663 uint32_t clsUsedForPID = dEdx.NHitsIROC + dEdx.NHitsOROC1 + dEdx.NHitsOROC2 + dEdx.NHitsOROC3;
2664 extraInfoHolder.tpcNClsFindableMinusPID = tpcOrig.getNClusters() - clsUsedForPID;
2667 double t = (tpcOrig.getTime0() + 0.5 * (tpcOrig.getDeltaTFwd() - tpcOrig.getDeltaTBwd())) * mTPCBinNS;
2668 double terr = 0.5 * (tpcOrig.getDeltaTFwd() + tpcOrig.getDeltaTBwd()) * mTPCBinNS;
2669 double err = mTimeMarginTrackTime + terr;
2670 bcOfTimeRef = fillBCSlice(extraInfoHolder.bcSlice, t - err, t + err, bcsMap);
2673 p.setDeltaTFwd(tpcOrig.getDeltaTFwd());
2674 p.setDeltaTBwd(tpcOrig.getDeltaTBwd());
2675 extraInfoHolder.trackTimeRes =
p.getTimeErr();
2677 extraInfoHolder.diffBCRef =
int(bcOfTimeRef);
2678 extraInfoHolder.isTPConly =
true;
2681 const auto& trITSTPC =
data.getTPCITSTrack(trackIndex);
2682 auto ts = trITSTPC.getTimeMUS();
2683 setTrackTime(ts.getTimeStamp() * 1.e3, ts.getTimeStampError() * 1.e3,
true);
2687 extrapolateToCalorimeters(extraInfoHolder,
data.getTrackParamOut(trackIndex));
2692 return extraInfoHolder;
2695AODProducerWorkflowDPL::TrackQA AODProducerWorkflowDPL::processBarrelTrackQA(
int collisionID, std::uint64_t collisionBC,
GIndex trackIndex,
2699 auto contributorsGID =
data.getTPCContributorGID(trackIndex);
2700 const auto& trackPar =
data.getTrackParam(trackIndex);
2701 if (contributorsGID.isIndexSet()) {
2703 const auto& tpcOrig =
data.getTPCTrack(contributorsGID);
2708 std::array<float, 2> dcaInfo{-999., -999.};
2709 if (prop->propagateToDCABxByBz({v.getX(), v.getY(), v.getZ()}, tpcTMP, 2.f, mMatType, &dcaInfo)) {
2710 trackQAHolder.tpcdcaR = 100. * dcaInfo[0] / sqrt(1. + trackPar.getQ2Pt() * trackPar.getQ2Pt());
2711 trackQAHolder.tpcdcaZ = 100. * dcaInfo[1] / sqrt(1. + trackPar.getQ2Pt() * trackPar.getQ2Pt());
2715 auto safeInt8Clamp = [](
auto value) -> int8_t {
2716 using ValType =
decltype(
value);
2717 return static_cast<int8_t
>(TMath::Nint(std::clamp(
value,
static_cast<ValType
>(std::numeric_limits<int8_t>::min()),
static_cast<ValType
>(std::numeric_limits<int8_t>::max()))));
2719 auto safeUInt8Clamp = [](
auto value) -> uint8_t {
2720 using ValType =
decltype(
value);
2721 return static_cast<uint8_t>(TMath::Nint(std::clamp(
value,
static_cast<ValType
>(std::numeric_limits<uint8_t>::min()),
static_cast<ValType
>(std::numeric_limits<uint8_t>::max()))));
2725 uint8_t clusterCounters[8] = {0};
2727 uint8_t sectorIndex, rowIndex;
2728 uint32_t clusterIndex;
2729 const auto& tpcClusRefs =
data.getTPCTracksClusterRefs();
2730 for (
int i = 0;
i < tpcOrig.getNClusterReferences();
i++) {
2731 o2::tpc::TrackTPC::getClusterReference(tpcClusRefs,
i, sectorIndex, rowIndex, clusterIndex, tpcOrig.getClusterRef());
2732 char indexTracklet = (rowIndex % 152) / 19;
2733 clusterCounters[indexTracklet]++;
2737 for (
int i = 0;
i < 8;
i++) {
2738 if (clusterCounters[
i] > 5) {
2739 byteMask |= (1 <<
i);
2742 trackQAHolder.tpcTime0 = tpcOrig.getTime0();
2743 trackQAHolder.tpcClusterByteMask = byteMask;
2744 const auto& dEdxInfoAlt = tpcOrig.getdEdxAlt();
2745 const float dEdxNorm = (dEdxInfoAlt.dEdxTotTPC > 0) ? 100. / dEdxInfoAlt.dEdxTotTPC : 0;
2746 trackQAHolder.tpcdEdxNorm = dEdxInfoAlt.dEdxTotTPC;
2747 trackQAHolder.tpcdEdxMax0R = safeUInt8Clamp(dEdxInfoAlt.dEdxMaxIROC * dEdxNorm);
2748 trackQAHolder.tpcdEdxMax1R = safeUInt8Clamp(dEdxInfoAlt.dEdxMaxOROC1 * dEdxNorm);
2749 trackQAHolder.tpcdEdxMax2R = safeUInt8Clamp(dEdxInfoAlt.dEdxMaxOROC2 * dEdxNorm);
2750 trackQAHolder.tpcdEdxMax3R = safeUInt8Clamp(dEdxInfoAlt.dEdxMaxOROC3 * dEdxNorm);
2752 trackQAHolder.tpcdEdxTot0R = safeUInt8Clamp(dEdxInfoAlt.dEdxTotIROC * dEdxNorm);
2753 trackQAHolder.tpcdEdxTot1R = safeUInt8Clamp(dEdxInfoAlt.dEdxTotOROC1 * dEdxNorm);
2754 trackQAHolder.tpcdEdxTot2R = safeUInt8Clamp(dEdxInfoAlt.dEdxTotOROC2 * dEdxNorm);
2755 trackQAHolder.tpcdEdxTot3R = safeUInt8Clamp(dEdxInfoAlt.dEdxTotOROC3 * dEdxNorm);
2758 auto contributorsGIDA =
data.getSingleDetectorRefs(trackIndex);
2760 const auto& tofMatch =
data.getTOFMatch(trackIndex);
2761 const float qpt = trackPar.getQ2Pt();
2763 trackQAHolder.dTofdX = safeInt8Clamp(tofMatch.getDXatTOF() / scaleTOF);
2764 trackQAHolder.dTofdZ = safeInt8Clamp(tofMatch.getDZatTOF() / scaleTOF);
2770 if (
auto itsContGID =
data.getITSContributorGID(trackIndex); itsContGID.isIndexSet() && itsContGID.getSource() !=
GIndex::ITSAB) {
2771 const auto& itsOrig =
data.getITSTrack(itsContGID);
2780 const float beta0 = std::sqrt(std::min(50.f / tpcOrig.getdEdx().dEdxMaxTPC, 1.f));
2781 const float qpt = gloCopy.getQ2Pt();
2782 const float x = qpt / beta0;
2784 auto scaleCont = [&
x](
int i) ->
float {
2787 auto scaleGlo = [&
x](
int i) ->
float {
2792 trackQAHolder.dRefContY = safeInt8Clamp((itsCopy.getY() - tpcCopy.getY()) * scaleCont(0));
2793 trackQAHolder.dRefContZ = safeInt8Clamp((itsCopy.getZ() - tpcCopy.getZ()) * scaleCont(1));
2794 trackQAHolder.dRefContSnp = safeInt8Clamp((itsCopy.getSnp() - tpcCopy.getSnp()) * scaleCont(2));
2795 trackQAHolder.dRefContTgl = safeInt8Clamp((itsCopy.getTgl() - tpcCopy.getTgl()) * scaleCont(3));
2796 trackQAHolder.dRefContQ2Pt = safeInt8Clamp((itsCopy.getQ2Pt() - tpcCopy.getQ2Pt()) * scaleCont(4));
2798 trackQAHolder.dRefGloY = safeInt8Clamp(((itsCopy.getY() + tpcCopy.getY()) * 0.5f - gloCopy.getY()) * scaleGlo(0));
2799 trackQAHolder.dRefGloZ = safeInt8Clamp(((itsCopy.getZ() + tpcCopy.getZ()) * 0.5f - gloCopy.getZ()) * scaleGlo(1));
2800 trackQAHolder.dRefGloSnp = safeInt8Clamp(((itsCopy.getSnp() + tpcCopy.getSnp()) * 0.5f - gloCopy.getSnp()) * scaleGlo(2));
2801 trackQAHolder.dRefGloTgl = safeInt8Clamp(((itsCopy.getTgl() + tpcCopy.getTgl()) * 0.5f - gloCopy.getTgl()) * scaleGlo(3));
2802 trackQAHolder.dRefGloQ2Pt = safeInt8Clamp(((itsCopy.getQ2Pt() + tpcCopy.getQ2Pt()) * 0.5f - gloCopy.getQ2Pt()) * scaleGlo(4));
2806 (*mStreamer) <<
"trackQA"
2807 <<
"trackITSOrig=" << itsOrig
2808 <<
"trackTPCOrig=" << tpcOrig
2809 <<
"trackITSTPCOrig=" << trackPar
2810 <<
"trackITSProp=" << itsCopy
2811 <<
"trackTPCProp=" << tpcCopy
2812 <<
"trackITSTPCProp=" << gloCopy
2815 <<
"scaleCont0=" << scaleCont(0)
2816 <<
"scaleCont1=" << scaleCont(1)
2817 <<
"scaleCont2=" << scaleCont(2)
2818 <<
"scaleCont3=" << scaleCont(3)
2819 <<
"scaleCont4=" << scaleCont(4)
2820 <<
"scaleGlo0=" << scaleGlo(0)
2821 <<
"scaleGlo1=" << scaleGlo(1)
2822 <<
"scaleGlo2=" << scaleGlo(2)
2823 <<
"scaleGlo3=" << scaleGlo(3)
2824 <<
"scaleGlo4=" << scaleGlo(4)
2825 <<
"trackQAHolder.tpcTime0=" << trackQAHolder.tpcTime0
2826 <<
"trackQAHolder.tpcdEdxNorm=" << trackQAHolder.tpcdEdxNorm
2827 <<
"trackQAHolder.tpcdcaR=" << trackQAHolder.tpcdcaR
2828 <<
"trackQAHolder.tpcdcaZ=" << trackQAHolder.tpcdcaZ
2829 <<
"trackQAHolder.tpcdcaClusterByteMask=" << trackQAHolder.tpcClusterByteMask
2830 <<
"trackQAHolder.tpcdEdxMax0R=" << trackQAHolder.tpcdEdxMax0R
2831 <<
"trackQAHolder.tpcdEdxMax1R=" << trackQAHolder.tpcdEdxMax1R
2832 <<
"trackQAHolder.tpcdEdxMax2R=" << trackQAHolder.tpcdEdxMax2R
2833 <<
"trackQAHolder.tpcdEdxMax3R=" << trackQAHolder.tpcdEdxMax3R
2834 <<
"trackQAHolder.tpcdEdxTot0R=" << trackQAHolder.tpcdEdxTot0R
2835 <<
"trackQAHolder.tpcdEdxTot1R=" << trackQAHolder.tpcdEdxTot1R
2836 <<
"trackQAHolder.tpcdEdxTot2R=" << trackQAHolder.tpcdEdxTot2R
2837 <<
"trackQAHolder.tpcdEdxTot3R=" << trackQAHolder.tpcdEdxTot3R
2838 <<
"trackQAHolder.dRefContY=" << trackQAHolder.dRefContY
2839 <<
"trackQAHolder.dRefContZ=" << trackQAHolder.dRefContZ
2840 <<
"trackQAHolder.dRefContSnp=" << trackQAHolder.dRefContSnp
2841 <<
"trackQAHolder.dRefContTgl=" << trackQAHolder.dRefContTgl
2842 <<
"trackQAHolder.dRefContQ2Pt=" << trackQAHolder.dRefContQ2Pt
2843 <<
"trackQAHolder.dRefGloY=" << trackQAHolder.dRefGloY
2844 <<
"trackQAHolder.dRefGloZ=" << trackQAHolder.dRefGloZ
2845 <<
"trackQAHolder.dRefGloSnp=" << trackQAHolder.dRefGloSnp
2846 <<
"trackQAHolder.dRefGloTgl=" << trackQAHolder.dRefGloTgl
2847 <<
"trackQAHolder.dRefGloQ2Pt=" << trackQAHolder.dRefGloQ2Pt
2848 <<
"trackQAHolder.dTofdX=" << trackQAHolder.dTofdX
2849 <<
"trackQAHolder.dTofdZ=" << trackQAHolder.dTofdZ
2850 <<
"scaleTOF=" << scaleTOF
2857 return trackQAHolder;
2865 dcaInfo.set(999.f, 999.f, 999.f, 999.f, 999.f);
2870void AODProducerWorkflowDPL::extrapolateToCalorimeters(TrackExtraInfo& extraInfoHolder,
const o2::track::TrackPar& track)
2872 constexpr float XEMCAL = 440.f, XPHOS = 460.f, XEMCAL2 = XEMCAL * XEMCAL;
2873 constexpr float ETAEMCAL = 0.75;
2874 constexpr float ZEMCALFastCheck = 460.;
2875 constexpr float ETADCALINNER = 0.22;
2876 constexpr float ETAPHOS = 0.13653194;
2877 constexpr float ETAPHOSMARGIN = 0.17946979;
2878 constexpr float ETADCALPHOSSWITCH = (ETADCALINNER + ETAPHOS) / 2;
2879 constexpr short SNONE = 0, SEMCAL = 0x1, SPHOS = 0x2;
2880 constexpr short SECTORTYPE[18] = {
2881 SNONE, SNONE, SNONE, SNONE,
2882 SEMCAL, SEMCAL, SEMCAL, SEMCAL, SEMCAL, SEMCAL,
2885 SPHOS | SEMCAL, SPHOS | SEMCAL, SPHOS | SEMCAL,
2896 (std::abs(outTr.getZAt(xtrg, 0)) > ZEMCALFastCheck) ||
2897 !prop->PropagateToXBxByBz(outTr, xtrg, 0.95, 10, o2::base::Propagator::MatCorrType::USEMatCorrLUT)) {
2898 LOGP(
debug,
"preliminary step: does not reach R={} {}", XEMCAL, outTr.asString());
2902 if ((outTr.getX() * outTr.getX() + outTr.getY() * outTr.getY() < XEMCAL2) &&
2903 (!outTr.rotateParam(outTr.getPhi()) ||
2905 !prop->PropagateToXBxByBz(outTr, xtrg, 0.95, 10, o2::base::Propagator::MatCorrType::USEMatCorrLUT))) {
2906 LOGP(
debug,
"does not reach R={} {}", XEMCAL, outTr.asString());
2912 auto propExactSector = [&outTr, §or, prop](
float xprop) ->
bool {
2915 auto outTrTmp = outTr;
2917 if ((std::abs(outTr.getZ()) > ZEMCALFastCheck) || !outTrTmp.rotateParam(
alpha) ||
2918 !prop->PropagateToXBxByBz(outTrTmp, xprop, 0.95, 10, o2::base::Propagator::MatCorrType::USEMatCorrLUT)) {
2919 LOGP(
debug,
"failed on rotation to {} (sector {}) or propagation to X={} {}",
alpha, sector, xprop, outTrTmp.asString());
2924 if (sectorTmp == sector) {
2932 LOGP(
debug,
"failed to rotate to sector, {}", outTr.asString());
2939 if (!propExactSector(XEMCAL) || SECTORTYPE[sector] == SNONE) {
2944 float r = std::sqrt(outTr.getX() * outTr.getX() + outTr.getY() * outTr.getY()), tg = std::atan2(
r, outTr.getZ());
2945 float eta = -std::log(std::tan(0.5f * tg)), etaAbs = std::abs(eta);
2946 if (etaAbs > ETAEMCAL) {
2947 LOGP(
debug,
"eta = {} is off at EMCAL radius", eta, outTr.asString());
2951 if ((SECTORTYPE[sector] & SPHOS) && etaAbs < ETADCALPHOSSWITCH) {
2952 if (!propExactSector(XPHOS)) {
2955 r = std::sqrt(outTr.getX() * outTr.getX() + outTr.getY() * outTr.getY());
2956 tg = std::atan2(
r, outTr.getZ());
2957 eta = -std::log(std::tan(0.5f * tg));
2958 }
else if (!(SECTORTYPE[sector] & SEMCAL)) {
2961 extraInfoHolder.trackPhiEMCAL = outTr.getPhiPos();
2962 extraInfoHolder.trackEtaEMCAL = eta;
2963 LOGP(
debug,
"eta = {} phi = {} sector {} for {}", extraInfoHolder.trackEtaEMCAL, extraInfoHolder.trackPhiEMCAL, sector, outTr.asString());
2967std::set<uint64_t> AODProducerWorkflowDPL::filterEMCALIncomplete(
const gsl::span<const o2::emcal::TriggerRecord> triggers)
2969 std::set<uint64_t> emcalIncompletes;
2970 for (
const auto& trg : triggers) {
2971 if (trg.getTriggerBits() & o2::emcal::triggerbits::Inc) {
2973 emcalIncompletes.insert(trg.getBCData().toLong());
2976 return emcalIncompletes;
2982 static bool initOnceDone =
false;
2983 if (!initOnceDone) {
2984 initOnceDone =
true;
2991 for (
auto i = 0U;
i < bs.size();
i++) {
3006 mTPCBinNS = elParam.ZbinWidth * 1.e3;
3009 mNSigmaTimeTrack = pvParams.nSigmaTimeTrack;
3010 mTimeMarginTrackTime = pvParams.timeMarginTrackTime * 1.e3;
3031 LOG(info) <<
"ITS Alpide param updated";
3033 par.printKeyValues();
3037 LOG(info) <<
"MFT Alpide param updated";
3039 par.printKeyValues();
3050 mEMCALTrgClassMask = 0;
3051 for (
const auto& trgclass : ctpconfig.getCTPClasses()) {
3053 mEMCALTrgClassMask |= trgclass.classMask;
3056 LOG(info) <<
"Loaded EMCAL trigger class mask: " << std::bitset<64>(mEMCALTrgClassMask);
3060void AODProducerWorkflowDPL::addRefGlobalBCsForTOF(
const o2::dataformats::VtxTrackRef& trackRef,
const gsl::span<const GIndex>& GIndices,
3071 int nbitsFrac = 24 - (32 - o2::math_utils::popcount(mTrackTime));
3072 int nbitsLoss = std::max(0,
int(std::log2(TOFTimePrecPS)));
3073 assert(nbitsFrac > 1);
3074 std::uint64_t maxRangePS = std::uint64_t(0x1) << (nbitsFrac + nbitsLoss);
3076 LOG(info) <<
"Max gap of " << maxGapBC <<
" BCs to closest globalBC reference is needed for TOF tracks to provide precision of "
3077 << TOFTimePrecPS <<
" ps";
3080 if (!trackRef.getEntries()) {
3084 std::uint64_t maxBC = mStartIR.
toLong();
3085 const auto& tofClus =
data.getTOFClusters();
3092 for (
int ti =
start; ti <
end; ti++) {
3093 auto& trackIndex = GIndices[ti];
3094 const auto& tofMatch =
data.getTOFMatch(trackIndex);
3095 const auto& tofInt = tofMatch.getLTIntegralOut();
3096 float intLen = tofInt.getL();
3097 float tofExpMom = 0.;
3107 double massZ = o2::track::PID::getMass2Z(
data.getTrackParam(trackIndex).getPID());
3108 double energy = sqrt((massZ * massZ) + (tofExpMom * tofExpMom));
3109 double exp = intLen * energy / (cSpeed * tofExpMom);
3110 auto tofSignal = (tofMatch.getSignal() -
exp) * 1e-3;
3111 auto bc = relativeTime_to_GlobalBC(tofSignal);
3113 auto it = bcsMap.lower_bound(
bc);
3114 if (it == bcsMap.end() || it->first >
bc + maxGapBC) {
3115 bcsMap.emplace_hint(it,
bc, 1);
3124 if ((--bcsMap.end())->first <= maxBC) {
3125 bcsMap.emplace_hint(bcsMap.end(), maxBC + 1, 1);
3129 for (
auto& item : bcsMap) {
3135std::uint64_t AODProducerWorkflowDPL::fillBCSlice(
int (&slice)[2],
double tmin,
double tmax,
const std::map<uint64_t, int>& bcsMap)
const
3147 uint64_t bcMin = relativeTime_to_GlobalBC(tmin), bcMax = relativeTime_to_GlobalBC(tmax);
3170 auto upperindex =
p.first;
3171 while (upperindex < bcvector.size() && bcvector[upperindex] <= bcMax) {
3174 if (upperindex !=
p.first) {
3178 slice[1] = upperindex;
3180 auto bcOfTimeRef =
p.second - this->mStartIR.
toLong();
3181 LOG(
debug) <<
"BC slice t:" << tmin <<
" " << slice[0]
3182 <<
" t: " << tmax <<
" " << slice[1]
3183 <<
" bcref: " << bcOfTimeRef;
3189 std::vector<uint8_t>
flags(bcsMap.size());
3192 auto bcIt = bcsMap.begin();
3193 auto itsrofs =
data.getITSTracksROFRecords();
3196 for (
auto& rof : itsrofs) {
3197 if (!rof.getFlag(o2::itsmft::ROFRecord::VtxUPCMode)) {
3200 uint64_t globalBC0 = rof.getBCData().toLong() + bROF, globalBC1 = globalBC0 + lROF - 1;
3202 while (bcIt != bcsMap.end()) {
3203 if (bcIt->first < globalBC0) {
3207 if (bcIt->first > globalBC1) {
3219 LOGF(info,
"aod producer dpl total timing: Cpu: %.3e Real: %.3e s in %d slots",
3220 mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1);
3227 auto dataRequest = std::make_shared<DataRequest>();
3228 dataRequest->inputs.emplace_back(
"ctpconfig",
"CTP",
"CTPCONFIG", 0, Lifetime::Condition,
ccdbParamSpec(
"CTP/Config/Config", CTPConfigPerRun));
3230 dataRequest->requestTracks(
src, useMC);
3231 dataRequest->requestPrimaryVertices(useMC);
3233 dataRequest->requestCTPDigits(useMC);
3236 dataRequest->requestSecondaryVertices(useMC);
3238 if (enableStrangenessTracking) {
3239 dataRequest->requestStrangeTracks(useMC);
3240 LOGF(info,
"requestStrangeTracks Finish");
3249 dataRequest->requestTOFClusters(useMC);
3252 dataRequest->requestPHOSCells(useMC);
3255 dataRequest->requestTRDTracklets(
false);
3258 dataRequest->requestEMCALCells(useMC);
3261 dataRequest->requestCPVClusters(useMC);
3264 auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(
true,
3270 dataRequest->inputs,
3273 dataRequest->inputs.emplace_back(
"meanvtx",
"GLO",
"MEANVERTEX", 0, Lifetime::Condition,
ccdbParamSpec(
"GLO/Calib/MeanVertex", {}, 1));
3278 std::vector<OutputSpec> outputs{
3318 outputs.insert(outputs.end(),
3319 {OutputForTable<McCollisions>::spec(),
3320 OutputForTable<HepMCXSections>::spec(),
3321 OutputForTable<HepMCPdfInfos>::spec(),
3322 OutputForTable<HepMCHeavyIons>::spec(),
3323 OutputForTable<McMFTTrackLabels>::spec(),
3324 OutputForTable<McFwdTrackLabels>::spec(),
3325 OutputForTable<StoredMcParticles_001>::spec(),
3326 OutputForTable<McTrackLabels>::spec(),
3327 OutputForTable<McCaloLabels_001>::spec(),
3332 {OutputLabel{
"McCollisionLabels"},
"AOD",
"MCCOLLISIONLABEL", 0, Lifetime::Timeframe}});
3336 "aod-producer-workflow",
3339 AlgorithmSpec{adaptFromTask<AODProducerWorkflowDPL>(
src, dataRequest, ggRequest, enableSV, useMC, enableFITextra)},
3341 ConfigParamSpec{
"run-number", VariantType::Int64, -1L, {
"The run-number. If left default we try to get it from DPL header."}},
3342 ConfigParamSpec{
"aod-timeframe-id", VariantType::Int64, -1L, {
"Set timeframe number"}},
3343 ConfigParamSpec{
"fill-calo-cells", VariantType::Int, 1, {
"Fill calo cells into cell table"}},
3344 ConfigParamSpec{
"enable-truncation", VariantType::Int, 1, {
"Truncation parameter: 1 -- on, != 1 -- off"}},
3345 ConfigParamSpec{
"lpmp-prod-tag", VariantType::String,
"", {
"LPMProductionTag"}},
3346 ConfigParamSpec{
"anchor-pass", VariantType::String,
"", {
"AnchorPassName"}},
3347 ConfigParamSpec{
"anchor-prod", VariantType::String,
"", {
"AnchorProduction"}},
3348 ConfigParamSpec{
"reco-pass", VariantType::String,
"", {
"RecoPassName"}},
3349 ConfigParamSpec{
"created-by", VariantType::String,
"", {
"Who created this AO2D"}},
3350 ConfigParamSpec{
"nthreads", VariantType::Int, std::max(1,
int(std::thread::hardware_concurrency() / 2)), {
"Number of threads"}},
3351 ConfigParamSpec{
"reco-mctracks-only", VariantType::Int, 0, {
"Store only reconstructed MC tracks and their mothers/daughters. 0 -- off, != 0 -- on"}},
3352 ConfigParamSpec{
"ctpreadout-create", VariantType::Int, 0, {
"Create CTP digits from detector readout and CTP inputs. !=1 -- off, 1 -- on"}},
3353 ConfigParamSpec{
"emc-select-leading", VariantType::Bool,
false, {
"Flag to select if only the leading contributing particle for an EMCal cell should be stored"}},
3354 ConfigParamSpec{
"propagate-tracks", VariantType::Bool,
false, {
"Propagate tracks (not used for secondary vertices) to IP"}},
3355 ConfigParamSpec{
"propagate-tracks-max-xiu", VariantType::Float, 5.0f, {
"Propagate tracks to IP if X_IU smaller than this value (and if propagate tracks enabled)"}},
3356 ConfigParamSpec{
"hepmc-update", VariantType::String,
"always", {
"When to update HepMC Aux tables: always - force update, never - never update, all - if all keys are present, any - when any key is present (not valid yet)"}},
3357 ConfigParamSpec{
"propagate-muons", VariantType::Bool,
false, {
"Propagate muons to IP"}},
3358 ConfigParamSpec{
"thin-tracks", VariantType::Bool,
false, {
"Produce thinned track tables"}},
3359 ConfigParamSpec{
"trackqc-keepglobaltracks", VariantType::Bool,
false, {
"Always keep TrackQA for global tracks"}},
3360 ConfigParamSpec{
"trackqc-retainonlydedx", VariantType::Bool,
false, {
"Keep only dEdx information, zero out everything else"}},
3361 ConfigParamSpec{
"trackqc-fraction", VariantType::Float, float(0.1), {
"Fraction of tracks to QC"}},
3362 ConfigParamSpec{
"trackqc-NTrCut", VariantType::Int64, 4L, {
"Minimal length of the track - in amount of tracklets"}},
3363 ConfigParamSpec{
"trackqc-tpc-dca", VariantType::Float, 3.f, {
"Keep TPC standalone track with this DCAxy to the PV"}},
3364 ConfigParamSpec{
"trackqc-tpc-cls", VariantType::Int, 80, {
"Keep TPC standalone track with this #clusters"}},
3365 ConfigParamSpec{
"trackqc-tpc-pt", VariantType::Float, 0.2f, {
"Keep TPC standalone track with this pt"}},
3366 ConfigParamSpec{
"with-streamers", VariantType::String,
"", {
"Bit-mask to steer writing of intermediate streamer files"}},
3367 ConfigParamSpec{
"seed", VariantType::Int, 0, {
"Set seed for random generator used for sampling (0 (default) means using a random_device)"}},
3368 ConfigParamSpec{
"mc-signal-filt", VariantType::Bool,
false, {
"Enable usage of signal filtering (only for MC with embedding)"}}}};
Class to refer to the reconstructed information.
Definition of the 32 Central Trigger System (CTS) Trigger Types defined in https://twiki....
General auxilliary methods.
uint64_t exp(uint64_t base, uint8_t exp) noexcept
definition of CTPDigit, CTPInputDigit
Header of the AggregatedRunInfo struct.
Global Forward Muon tracks.
Global index for barrel track: provides provenance (detectors combination), index in respective array...
Definition of the MCTrack class.
Definition of a container to keep Monte Carlo truth external to simulation objects.
Utility functions for MC particles.
Class to perform MFT MCH (and MID) matching.
Class to store the output of the matching to HMPID.
Class to perform TOF matching to global tracks.
Definition of the parameter class for the detector electronics.
Header to collect physics constants.
Definition of the FDD RecPoint class.
Definition of the ITS track.
Definition of the MUON track.
Definition of the MCH track.
Definition of the MCH track parameters for internal use.
Result of refitting TPC-ITS matched track.
Extention of GlobalTrackID by flags relevant for verter-track association.
Referenc on track indices contributing to the vertex, with possibility chose tracks from specific sou...
Container class to store energy released in the ZDC.
Container class to store a TDC hit in a ZDC channel.
const auto & getBCPattern() const
void GetStartVertex(TVector3 &vertex) const
void endOfStream(framework::EndOfStreamContext &ec) final
This is invoked whenever we have an EndOfStream event.
void finaliseCCDB(ConcreteDataMatcher &matcher, void *obj) final
void run(ProcessingContext &pc) final
void init(InitContext &ic) final
std::pair< size_t, uint64_t > lower_bound(uint64_t timestamp) const
void init(std::map< uint64_t, int > const &bcs)
initialize this container (to be ready for lookup/search queries)
void clear()
clear/reset this container
std::vector< uint64_t > const & getBCTimeVector() const
return the sorted vector of increaing BC times
static float getAmplitude(const o2::emcal::Cell &cell)
static int16_t getLnAmplitude(const o2::emcal::Cell &)
static int8_t getTriggerBits(const o2::emcal::Cell &)
static int16_t getCellNumber(const o2::emcal::Cell &cell)
static int16_t getFastOrAbsID(const o2::emcal::Cell &)
static bool isTRU(const o2::emcal::Cell &cell)
static float getTimeStamp(const o2::emcal::Cell &cell)
void checkUpdates(o2::framework::ProcessingContext &pc)
static GRPGeomHelper & instance()
void setRequest(std::shared_ptr< GRPGeomRequest > req)
static constexpr float MAX_SIN_PHI
static constexpr float MAX_STEP
GPUd() value_type estimateLTFast(o2 static GPUd() float estimateLTIncrement(const o2 PropagatorImpl * Instance(bool uninitialized=false)
static const DPLAlpideParam< N > & Instance()
void printStream(std::ostream &stream) const
Static class with identifiers, bitmasks and names for ALICE detectors.
Handler for EMCAL event data.
void reset()
Reset containers with empty ranges.
void setCellData(CellRange cells, TriggerRange triggers)
Setting the data at cell level.
void setCellMCTruthContainer(const o2::dataformats::MCTruthContainer< o2::emcal::MCLabel > *mclabels)
Setting the pointer for the MCTruthContainer for cells.
InteractionRecord getInteractionRecordForEvent(int eventID) const
Get the interaction record for the given event.
int getNumberOfEvents() const
Get the number of events handled by the event handler.
T get(const char *key) const
void snapshot(const Output &spec, T const &object)
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.
static constexpr int NCellsA
o2::dataformats::GlobalFwdTrack MCHtoFwd(const o2::mch::TrackParam &mchTrack)
Converts mchTrack parameters to Forward coordinate system.
track parameters for internal use
Double_t getNonBendingCoor() const
return non bending coordinate (cm)
Double_t getBendingCoor() const
return bending coordinate (cm)
void setCellMCTruthContainer(const o2::dataformats::MCTruthContainer< o2::phos::MCLabel > *mclabels)
Setting the pointer for the MCTruthContainer for cells.
void setCellData(CellRange cells, TriggerRange triggers)
Setting the data at cell level.
void reset()
Reset containers with empty ranges.
InteractionRecord getInteractionRecordForEvent(int eventID) const
int getNumberOfEvents() const
MCTrack const * getTrack(o2::MCCompLabel const &) const
void releaseTracksForSourceAndEvent(int source, int event)
API to ask releasing tracks (freeing memory) for source + event.
std::vector< MCTrack > const & getTracks(int source, int event) const
variant returning all tracks for source and event at once
static void addInteractionBC(int bc, bool fromCollisonCotext=false)
void set(const std::string &s, int base=DefaultBase)
bool match(const std::vector< std::string > &queries, const char *pattern)
GLfloat GLfloat GLfloat alpha
GLint GLint GLsizei GLuint * counters
GLuint GLuint GLfloat weight
GLboolean GLboolean GLboolean b
GLsizei GLsizei GLchar * source
GLsizei const GLfloat * value
GLint GLint GLsizei GLint GLenum GLenum type
GLenum GLsizei GLsizei GLint * values
GLuint GLsizei const GLchar * label
GLboolean GLboolean GLboolean GLboolean a
constexpr std::array< float, 2 > trackQAScaledTOF
constexpr std::array< float, 5 > trackQAScaleContP1
uint8_t itsSharedClusterMap uint8_t
constexpr std::array< float, 5 > trackQAScaleContP0
constexpr std::array< float, 5 > trackQAScaleGloP0
constexpr std::array< float, 5 > trackQAScaleGloP1
constexpr float trackQAScaleBins
constexpr float trackQARefRadius
bool updateHepMCHeavyIon(const HeavyIonCursor &cursor, int collisionID, short generatorID, o2::dataformats::MCEventHeader const &header, HepMCUpdate when=HepMCUpdate::anyKey)
short updateMCCollisions(const CollisionCursor &cursor, int bcId, float time, o2::dataformats::MCEventHeader const &header, short generatorId=0, int sourceId=0, unsigned int mask=0xFFFFFFF0)
bool updateHepMCPdfInfo(const PdfInfoCursor &cursor, int collisionID, short generatorID, o2::dataformats::MCEventHeader const &header, HepMCUpdate when=HepMCUpdate::anyKey)
uint32_t updateParticles(const ParticleCursor &cursor, int collisionID, std::vector< MCTrack > const &tracks, TrackToIndex &preselect, uint32_t offset=0, bool filter=false, bool background=false, uint32_t weightMask=0xFFFFFFF0, uint32_t momentumMask=0xFFFFFFF0, uint32_t positionMask=0xFFFFFFF0, bool signalFilter=false)
bool updateHepMCXSection(const XSectionCursor &cursor, int collisionID, short generatorID, o2::dataformats::MCEventHeader const &header, HepMCUpdate when=HepMCUpdate::anyKey)
framework::DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool enableSV, bool enableST, bool useMC, bool CTPConfigPerRun, bool enableFITextra)
create a processor spec
void keepMCParticle(std::vector< std::vector< std::unordered_map< int, int > > > &store, int source, int event, int track, int value=1, bool useSigFilt=false)
void dimensionMCKeepStore(std::vector< std::vector< std::unordered_map< int, int > > > &store, int Nsources, int NEvents)
void clearMCKeepStore(std::vector< std::vector< std::unordered_map< int, int > > > &store)
constexpr int LHCMaxBunches
constexpr double LHCBunchSpacingNS
constexpr double MassPionCharged
Defining PrimaryVertex explicitly as messageable.
std::vector< ConfigParamSpec > ccdbParamSpec(std::string const &path, int runDependent, std::vector< CCDBMetadata > metadata={}, int qrate=0)
int angle2Sector(float phi)
float sector2Angle(int sect)
const int TDCSignal[NTDCChannels]
constexpr int NTDCChannels
std::string fullVersion()
get full version information (official O2 release and git commit)
static OutputSpec const spec()
decltype(FFL(std::declval< cursor_t >())) cursor
void reserve(int64_t size)
auto getZDCTDCData() const
auto getStrangeTracks() const
auto getFDDRecPoints() const
auto getMCHMIDMatches() const
o2::InteractionRecord startIR
auto getDecays3BodyIdx() const
auto getTPCTRDTriggers() const
auto getPrimaryVertices() const
auto getPrimaryVertexMatchedTracks() const
auto getMCHTrackClusters() const
auto getMCHTracksROFRecords() const
auto getCTPDigits() const
auto getCascadesIdx() const
auto getPrimaryVertexMatchedTrackRefs() const
gsl::span< const o2::trd::TriggerRecord > getTRDTriggerRecords() const
auto getCPVClusters() const
auto getFV0ChannelsData() const
auto getMFTTracksROFRecords() const
auto getCPVTriggers() const
void collectData(o2::framework::ProcessingContext &pc, const DataRequest &request)
auto getPrimaryVertexMCLabels() const
auto getZDCEnergy() const
auto getFT0RecPoints() const
auto getITSTracksROFRecords() const
auto getMCHTracks() const
auto getFV0RecPoints() const
auto getHMPMatches() const
auto getITSTPCTRDTriggers() const
auto getFT0ChannelsData() const
auto getFDDChannelsData() const
auto getZDCBCRecData() const
auto getEMCALTriggers() const
auto getMFTTracks() const
auto getPHOSTriggers() const
static bool downsampleTsallisCharged(float pt, float factorPt, float sqrts, float &weight, float rnd, float mass=0.13957)
std::vector< o2::ctf::BufferType > vec
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::uniform_int_distribution< unsigned long long > distr
std::array< uint16_t, 5 > pattern