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 truncateFloatFraction(trackQAInfoHolder.tpcTime0, mTPCTime0),
367 truncateFloatFraction(trackQAInfoHolder.tpcdEdxNorm, mTrackSignal),
368 trackQAInfoHolder.tpcdcaR,
369 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 trackQAInfoHolder.dRefContY,
380 trackQAInfoHolder.dRefContZ,
381 trackQAInfoHolder.dRefContSnp,
382 trackQAInfoHolder.dRefContTgl,
383 trackQAInfoHolder.dRefContQ2Pt,
384 trackQAInfoHolder.dRefGloY,
385 trackQAInfoHolder.dRefGloZ,
386 trackQAInfoHolder.dRefGloSnp,
387 trackQAInfoHolder.dRefGloTgl,
388 trackQAInfoHolder.dRefGloQ2Pt,
389 trackQAInfoHolder.dTofdX,
390 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;
1072template <
typename MCTrackLabelCursorType,
typename MCMFTTrackLabelCursorType,
typename MCFwdTrackLabelCursorType>
1073void AODProducerWorkflowDPL::fillMCTrackLabelsTable(MCTrackLabelCursorType& mcTrackLabelCursor,
1074 MCMFTTrackLabelCursorType& mcMFTTrackLabelCursor,
1075 MCFwdTrackLabelCursorType& mcFwdTrackLabelCursor,
1077 const gsl::span<const GIndex>& primVerGIs,
1090 mcMFTTrackLabelCursor.reserve(
end -
start + mcMFTTrackLabelCursor.lastIndex());
1091 mcFwdTrackLabelCursor.reserve(
end -
start + mcFwdTrackLabelCursor.lastIndex());
1092 mcTrackLabelCursor.reserve(
end -
start + mcTrackLabelCursor.lastIndex());
1093 for (
int ti =
start; ti <
end; ti++) {
1094 const auto trackIndex = primVerGIs[ti];
1097 auto needToStore = [trackIndex](std::unordered_map<GIndex, int>& mp) {
1098 auto entry = mp.find(trackIndex);
1099 if (
entry == mp.end() ||
entry->second == -1) {
1106 if (GIndex::includesSource(
src, mInputSources)) {
1107 auto mcTruth =
data.getTrackMCLabel(trackIndex);
1108 MCLabels labelHolder{};
1113 if (mcTruth.isValid()) {
1114 labelHolder.labelID = (mToStore[mcTruth.getSourceID()][mcTruth.getEventID()])[mcTruth.getTrackID()];
1116 if (mcTruth.isFake()) {
1117 labelHolder.fwdLabelMask |= (0x1 << 7);
1119 if (mcTruth.isNoise()) {
1120 labelHolder.fwdLabelMask |= (0x1 << 6);
1123 mcMFTTrackLabelCursor(labelHolder.labelID,
1124 labelHolder.fwdLabelMask);
1126 mcFwdTrackLabelCursor(labelHolder.labelID,
1127 labelHolder.fwdLabelMask);
1130 if (!needToStore(mGIDToTableID)) {
1133 if (mcTruth.isValid()) {
1134 labelHolder.labelID = (mToStore[mcTruth.getSourceID()][mcTruth.getEventID()])[mcTruth.getTrackID()];
1135 if (mcTruth.isFake()) {
1136 labelHolder.labelMask |= (0x1 << 15);
1139 auto contributorsGID =
data.getSingleDetectorRefs(trackIndex);
1142 labelHolder.labelMask |= (0x1 << 13);
1147 auto itsGID =
data.getITSContributorGID(trackIndex);
1148 auto itsSource = itsGID.getSource();
1150 auto& itsTrack =
data.getITSTrack(itsGID);
1151 for (
unsigned int iL = 0; iL < 7; ++iL) {
1152 if (itsTrack.isFakeOnLayer(iL)) {
1153 labelHolder.labelMask |= (0x1 << iL);
1157 labelHolder.labelMask |= (
data.getTrackMCLabel(itsGID).isFake() << 12);
1161 }
else if (mcTruth.isNoise()) {
1162 labelHolder.labelMask |= (0x1 << 14);
1164 mcTrackLabelCursor(labelHolder.labelID, labelHolder.labelMask);
1171 auto sTrackLabels =
data.getStrangeTracksMCLabels();
1173 if (!(vertexId < 0 || vertexId >= mVertexStrLUT.size() - 1)) {
1174 mcTrackLabelCursor.reserve(mVertexStrLUT[vertexId + 1] + mcTrackLabelCursor.lastIndex());
1175 for (
int iS{mVertexStrLUT[vertexId]}; iS < mVertexStrLUT[vertexId + 1]; ++iS) {
1176 auto& collStrTrk = mCollisionStrTrk[iS];
1177 auto&
label = sTrackLabels[collStrTrk.second];
1178 MCLabels labelHolder;
1179 labelHolder.labelID =
label.isValid() ? (mToStore[
label.getSourceID()][
label.getEventID()])[
label.getTrackID()] : -1;
1180 labelHolder.labelMask = (
label.isFake() << 15) | (
label.isNoise() << 14);
1181 mcTrackLabelCursor(labelHolder.labelID, labelHolder.labelMask);
1186template <
typename V0CursorType,
typename CascadeCursorType,
typename Decay3BodyCursorType>
1187void AODProducerWorkflowDPL::fillSecondaryVertices(
const o2::globaltracking::RecoContainer& recoData, V0CursorType& v0Cursor, CascadeCursorType& cascadeCursor, Decay3BodyCursorType& decay3BodyCursor)
1194 v0Cursor.reserve(v0s.size());
1196 for (
size_t iv0 = 0; iv0 < v0s.size(); iv0++) {
1197 const auto&
v0 = v0s[iv0];
1198 auto trPosID =
v0.getProngID(0);
1199 auto trNegID =
v0.getProngID(1);
1200 uint8_t v0flags =
v0.getBits();
1201 int posTableIdx = -1, negTableIdx = -1, collID = -1;
1202 auto item = mGIDToTableID.find(trPosID);
1203 if (item != mGIDToTableID.end()) {
1204 posTableIdx = item->second;
1206 LOG(warn) <<
"Could not find a positive track index for prong ID " << trPosID;
1208 item = mGIDToTableID.find(trNegID);
1209 if (item != mGIDToTableID.end()) {
1210 negTableIdx = item->second;
1212 LOG(warn) <<
"Could not find a negative track index for prong ID " << trNegID;
1214 auto itemV = mVtxToTableCollID.find(
v0.getVertexID());
1215 if (itemV == mVtxToTableCollID.end()) {
1216 LOG(warn) <<
"Could not find V0 collisionID for the vertex ID " <<
v0.getVertexID();
1218 collID = itemV->second;
1220 if (posTableIdx != -1 and negTableIdx != -1 and collID != -1) {
1221 v0Cursor(collID, posTableIdx, negTableIdx, v0flags);
1222 mV0ToTableID[
int(iv0)] = mTableV0ID++;
1227 cascadeCursor.reserve(cascades.size());
1228 for (
auto& cascade : cascades) {
1229 auto itemV0 = mV0ToTableID.find(cascade.getV0ID());
1230 if (itemV0 == mV0ToTableID.end()) {
1233 int v0tableID = itemV0->second, bachTableIdx = -1, collID = -1;
1234 auto bachelorID = cascade.getBachelorID();
1235 auto item = mGIDToTableID.find(bachelorID);
1236 if (item != mGIDToTableID.end()) {
1237 bachTableIdx = item->second;
1239 LOG(warn) <<
"Could not find a bachelor track index";
1242 auto itemV = mVtxToTableCollID.find(cascade.getVertexID());
1243 if (itemV != mVtxToTableCollID.end()) {
1244 collID = itemV->second;
1246 LOG(warn) <<
"Could not find cascade collisionID for the vertex ID " << cascade.getVertexID();
1249 cascadeCursor(collID, v0tableID, bachTableIdx);
1253 decay3BodyCursor.reserve(decays3Body.size());
1254 for (
size_t i3Body = 0; i3Body < decays3Body.size(); i3Body++) {
1255 const auto& decay3Body = decays3Body[i3Body];
1257 decay3Body.getProngID(0),
1258 decay3Body.getProngID(1),
1259 decay3Body.getProngID(2)};
1260 int tableIdx[3]{-1, -1, -1}, collID = -1;
1261 bool missing{
false};
1262 for (
int i{0};
i < 3; ++
i) {
1263 auto item = mGIDToTableID.find(trIDs[
i]);
1264 if (item != mGIDToTableID.end()) {
1265 tableIdx[
i] = item->second;
1267 LOG(warn) << fmt::format(
"Could not find a track index for prong ID {}", (
int)trIDs[
i]);
1271 auto itemV = mVtxToTableCollID.find(decay3Body.getVertexID());
1272 if (itemV == mVtxToTableCollID.end()) {
1273 LOG(warn) <<
"Could not find 3 body collisionID for the vertex ID " << decay3Body.getVertexID();
1276 collID = itemV->second;
1281 decay3BodyCursor(collID, tableIdx[0], tableIdx[1], tableIdx[2]);
1285template <
typename FwdTrkClsCursorType>
1292 int mchTrackID = -1;
1294 mchTrackID = trackID.getIndex();
1296 auto mchmidMatch = mchmidMatches[trackID.getIndex()];
1297 mchTrackID = mchmidMatch.getMCHRef().getIndex();
1300 if (mchTrackID > -1 && mchTrackID < mchTracks.size()) {
1301 const auto& mchTrack = mchTracks[mchTrackID];
1302 fwdTrkClsCursor.reserve(mchTrack.getNClusters() + fwdTrkClsCursor.lastIndex());
1303 int first = mchTrack.getFirstClusterIdx();
1304 int last = mchTrack.getLastClusterIdx();
1305 for (
int i =
first;
i <= last;
i++) {
1306 const auto& cluster = mchClusters[
i];
1307 fwdTrkClsCursor(fwdTrackId,
1308 truncateFloatFraction(cluster.x, mMuonCl),
1309 truncateFloatFraction(cluster.y, mMuonCl),
1310 truncateFloatFraction(cluster.z, mMuonCl),
1311 (((cluster.ey < 5.) & 0x1) << 12) | (((cluster.ex < 5.) & 0x1) << 11) | cluster.getDEId());
1316template <
typename HMPCursorType>
1321 hmpCursor.reserve(hmpMatches.size());
1324 for (
size_t iHmp = 0; iHmp < hmpMatches.size(); iHmp++) {
1326 const auto&
match = hmpMatches[iHmp];
1328 float xTrk, yTrk, theta,
phi;
1332 match.getHMPIDtrk(xTrk, yTrk, theta,
phi);
1335 auto photChargeVec =
match.getPhotCharge();
1337 float photChargeVec2[10];
1339 for (Int_t
i = 0;
i < 10;
i++) {
1340 photChargeVec2[
i] = photChargeVec[
i];
1342 auto tref = mGIDToTableID.find(
match.getTrackRef());
1343 if (tref != mGIDToTableID.end()) {
1344 hmpCursor(tref->second,
match.getHMPsignal(), xTrk, yTrk, xMip, yMip, nph,
charge,
match.getIdxHMPClus(),
match.getHmpMom(), photChargeVec2);
1346 LOG(error) <<
"Could not find AOD track table entry for HMP-matched track " <<
match.getTrackRef().asString();
1358 mCollisionStrTrk.clear();
1360 mVertexStrLUT.clear();
1362 for (
auto& sTrk : recoData.getStrangeTracks()) {
1366 vtxId = v0s[sTrk.mDecayRef].getVertexID();
1368 vtxId = cascades[sTrk.mDecayRef].getVertexID();
1370 vtxId = decays3Body[sTrk.mDecayRef].getVertexID();
1372 mCollisionStrTrk.emplace_back(vtxId, sTrkID++);
1373 mVertexStrLUT[vtxId]++;
1375 std::exclusive_scan(mVertexStrLUT.begin(), mVertexStrLUT.end(), mVertexStrLUT.begin(), 0);
1378 std::sort(mCollisionStrTrk.begin(), mCollisionStrTrk.end(), [](
const auto&
a,
const auto&
b) { return a.first < b.first; });
1379 mStrTrkIndices.clear();
1380 mStrTrkIndices.resize(mCollisionStrTrk.size(), -1);
1383template <
typename V0C,
typename CC,
typename D3BC>
1386 int itsTableIdx = -1;
1392 for (
const auto& sTrk : recoData.getStrangeTracks()) {
1402 v0Curs.reserve(nV0);
1403 cascCurs.reserve(nCasc);
1404 d3BodyCurs.reserve(nD3Body);
1406 for (
const auto& sTrk : recoData.getStrangeTracks()) {
1408 auto item = mGIDToTableID.find(ITSIndex);
1409 if (item != mGIDToTableID.end()) {
1410 itsTableIdx = item->second;
1412 LOG(warn) <<
"Could not find a ITS strange track index " << ITSIndex;
1416 v0Curs(mStrTrkIndices[sTrkID++],
1426 sTrk.getAverageClusterSize());
1428 cascCurs(mStrTrkIndices[sTrkID++],
1438 sTrk.getAverageClusterSize());
1440 d3BodyCurs(mStrTrkIndices[sTrkID++],
1450 sTrk.getAverageClusterSize());
1457 const auto& tpcTracks =
data.getTPCTracks();
1458 const auto& tpcClusRefs =
data.getTPCTracksClusterRefs();
1459 const auto& tpcClusShMap =
data.clusterShMapTPC;
1460 const auto& tpcClusAcc =
data.getTPCClusters();
1461 constexpr int maxRows = 152;
1462 constexpr int neighbour = 2;
1463 int ntr = tpcTracks.size();
1464 mTPCCounters.clear();
1465 mTPCCounters.resize(ntr);
1467 int ngroup = std::min(50, std::max(1, ntr / mNThreads));
1468#pragma omp parallel for schedule(dynamic, ngroup) num_threads(mNThreads)
1470 for (
int itr = 0; itr < ntr; itr++) {
1471 std::array<bool, maxRows> clMap{}, shMap{};
1472 uint8_t sectorIndex, rowIndex;
1473 uint32_t clusterIndex;
1474 auto&
counters = mTPCCounters[itr];
1475 const auto& track = tpcTracks[itr];
1476 for (
int i = 0;
i < track.getNClusterReferences();
i++) {
1477 o2::tpc::TrackTPC::getClusterReference(tpcClusRefs,
i, sectorIndex, rowIndex, clusterIndex, track.getClusterRef());
1478 unsigned int absoluteIndex = tpcClusAcc.clusterOffset[sectorIndex][rowIndex] + clusterIndex;
1479 clMap[rowIndex] =
true;
1481 if (!shMap[rowIndex]) {
1484 shMap[rowIndex] =
true;
1488 for (
int i = 0;
i < maxRows;
i++) {
1493 }
else if ((
i - last) <= neighbour) {
1496 int lim = std::min(
i + 1 + neighbour, maxRows);
1497 for (
int j =
i + 1;
j < lim;
j++) {
1512 if (track.getTrackletIndex(il) != -1) {
1516 if (track.getHasNeighbor()) {
1519 if (track.getHasPadrowCrossing()) {
1525template <
typename TCaloHandler,
typename TCaloCursor,
typename TCaloTRGCursor,
typename TMCCaloLabelCursor>
1526void AODProducerWorkflowDPL::addToCaloTable(TCaloHandler& caloHandler, TCaloCursor& caloCellCursor, TCaloTRGCursor& caloTRGCursor,
1527 TMCCaloLabelCursor& mcCaloCellLabelCursor,
int eventID,
int bcID, int8_t caloType)
1529 auto inputEvent = caloHandler.buildEvent(eventID);
1530 auto cellsInEvent = inputEvent.mCells;
1531 auto cellMClabels = inputEvent.mMCCellLabels;
1532 caloCellCursor.reserve(cellsInEvent.size() + caloCellCursor.lastIndex());
1533 caloTRGCursor.reserve(cellsInEvent.size() + caloTRGCursor.lastIndex());
1535 mcCaloCellLabelCursor.reserve(cellsInEvent.size() + mcCaloCellLabelCursor.lastIndex());
1537 for (
auto iCell = 0U; iCell < cellsInEvent.size(); iCell++) {
1538 caloCellCursor(bcID,
1542 cellsInEvent[iCell].
getType(),
1556 std::vector<int32_t> particleIds;
1557 std::vector<float> amplitudeFraction;
1558 if (!mEMCselectLeading) {
1559 particleIds.reserve(cellMClabels.size());
1560 amplitudeFraction.reserve(cellMClabels.size());
1562 float tmpMaxAmplitude = 0;
1563 int32_t tmpindex = 0;
1564 for (
auto& mclabel : cellMClabels[iCell]) {
1566 if (mclabel.isValid()) {
1567 if (mEMCselectLeading) {
1568 if (mclabel.getAmplitudeFraction() > tmpMaxAmplitude) {
1570 if (mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID()).find(mclabel.getTrackID()) !=
1571 mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID()).end()) {
1572 tmpMaxAmplitude = mclabel.getAmplitudeFraction();
1573 tmpindex = (mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID())).at(mclabel.getTrackID());
1577 auto trackStore = mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID());
1578 auto iter = trackStore.find(mclabel.getTrackID());
1579 if (iter != trackStore.end()) {
1580 amplitudeFraction.emplace_back(mclabel.getAmplitudeFraction());
1581 particleIds.emplace_back(iter->second);
1583 particleIds.emplace_back(-1);
1584 amplitudeFraction.emplace_back(0.f);
1585 LOG(warn) <<
"CaloTable: Could not find track for mclabel (" << mclabel.getSourceID() <<
"," << mclabel.getEventID() <<
"," << mclabel.getTrackID() <<
") in the AOD MC store";
1586 if (mMCKineReader) {
1587 auto mctrack = mMCKineReader->
getTrack(mclabel);
1590 LOG(warn) <<
" ... this track is of PDG " << mctrack->GetPdgCode() <<
" produced by " << mctrack->getProdProcessAsString() <<
" at (" <<
vec.X() <<
"," <<
vec.Y() <<
"," <<
vec.Z() <<
")";
1596 if (mEMCselectLeading) {
1597 amplitudeFraction.emplace_back(tmpMaxAmplitude);
1598 particleIds.emplace_back(tmpindex);
1600 if (particleIds.size() == 0) {
1601 particleIds.emplace_back(-1);
1602 amplitudeFraction.emplace_back(0.f);
1604 mcCaloCellLabelCursor(particleIds,
1611template <
typename TCaloCursor,
typename TCaloTRGCursor,
typename TMCCaloLabelCursor>
1612void AODProducerWorkflowDPL::fillCaloTable(TCaloCursor& caloCellCursor, TCaloTRGCursor& caloTRGCursor,
1613 TMCCaloLabelCursor& mcCaloCellLabelCursor,
const std::map<uint64_t, int>& bcsMap,
1617 auto caloEMCCells =
data.getEMCALCells();
1618 auto caloEMCCellsTRGR =
data.getEMCALTriggers();
1619 auto mcCaloEMCCellLabels =
data.getEMCALCellsMCLabels();
1621 auto caloPHOSCells =
data.getPHOSCells();
1622 auto caloPHOSCellsTRGR =
data.getPHOSTriggers();
1623 auto mcCaloPHOSCellLabels =
data.getPHOSCellsMCLabels();
1627 caloPHOSCellsTRGR = {};
1628 mcCaloPHOSCellLabels = {};
1633 caloEMCCellsTRGR = {};
1634 mcCaloEMCCellLabels = {};
1641 emcEventHandler.
reset();
1642 emcEventHandler.
setCellData(caloEMCCells, caloEMCCellsTRGR);
1645 phsEventHandler.
reset();
1646 phsEventHandler.
setCellData(caloPHOSCells, caloPHOSCellsTRGR);
1652 std::vector<std::tuple<uint64_t, int8_t, int>> caloEvents;
1654 caloEvents.reserve(emcNEvents + phsNEvents);
1656 for (
int iev = 0; iev < emcNEvents; ++iev) {
1658 caloEvents.emplace_back(std::make_tuple(
bc, 1, iev));
1661 for (
int iev = 0; iev < phsNEvents; ++iev) {
1663 caloEvents.emplace_back(std::make_tuple(
bc, 0, iev));
1666 std::sort(caloEvents.begin(), caloEvents.end(),
1667 [](
const auto&
left,
const auto&
right) { return std::get<0>(left) < std::get<0>(right); });
1670 for (
int i = 0;
i < emcNEvents + phsNEvents; ++
i) {
1671 uint64_t globalBC = std::get<0>(caloEvents[
i]);
1672 int8_t caloType = std::get<1>(caloEvents[
i]);
1673 int eventID = std::get<2>(caloEvents[
i]);
1674 auto item = bcsMap.find(globalBC);
1676 if (item != bcsMap.end()) {
1677 bcID = item->second;
1679 LOG(warn) <<
"Error: could not find a corresponding BC ID for a calo point; globalBC = " << globalBC <<
", caloType = " << (
int)caloType;
1681 if (caloType == 0) {
1682 addToCaloTable(phsEventHandler, caloCellCursor, caloTRGCursor, mcCaloCellLabelCursor, eventID, bcID, caloType);
1684 if (caloType == 1) {
1685 addToCaloTable(emcEventHandler, caloCellCursor, caloTRGCursor, mcCaloCellLabelCursor, eventID, bcID, caloType);
1696 mLPMProdTag = ic.
options().
get<std::string>(
"lpmp-prod-tag");
1697 mAnchorPass = ic.
options().
get<std::string>(
"anchor-pass");
1698 mAnchorProd = ic.
options().
get<std::string>(
"anchor-prod");
1699 mUser = ic.
options().
get<std::string>(
"created-by");
1700 mRecoPass = ic.
options().
get<std::string>(
"reco-pass");
1701 mTFNumber = ic.
options().
get<int64_t>(
"aod-timeframe-id");
1702 mRecoOnly = ic.
options().
get<
int>(
"reco-mctracks-only");
1703 mTruncate = ic.
options().
get<
int>(
"enable-truncation");
1704 mRunNumber = ic.
options().
get<
int>(
"run-number");
1705 mCTPReadout = ic.
options().
get<
int>(
"ctpreadout-create");
1706 mNThreads = std::max(1, ic.
options().
get<
int>(
"nthreads"));
1707 mEMCselectLeading = ic.
options().
get<
bool>(
"emc-select-leading");
1708 mThinTracks = ic.
options().
get<
bool>(
"thin-tracks");
1709 mPropTracks = ic.
options().
get<
bool>(
"propagate-tracks");
1710 mMaxPropXiu = ic.
options().
get<
float>(
"propagate-tracks-max-xiu");
1711 mPropMuons = ic.
options().
get<
bool>(
"propagate-muons");
1712 if (
auto s = ic.
options().
get<std::string>(
"with-streamers"); !
s.empty()) {
1713 mStreamerFlags.
set(
s);
1714 if (mStreamerFlags) {
1715 LOGP(info,
"Writing streamer data with mask:");
1716 LOG(info) << mStreamerFlags;
1718 LOGP(warn,
"Specified non-default empty streamer mask!");
1721 mTrackQCFraction = ic.
options().
get<
float>(
"trackqc-fraction");
1722 mTrackQCNTrCut = ic.
options().
get<int64_t>(
"trackqc-NTrCut");
1723 mTrackQCDCAxy = ic.
options().
get<
float>(
"trackqc-tpc-dca");
1724 mTrackQCPt = ic.
options().
get<
float>(
"trackqc-tpc-pt");
1725 mTrackQCNCls = ic.
options().
get<
int>(
"trackqc-tpc-cls");
1726 if (
auto seed = ic.
options().
get<
int>(
"seed"); seed == 0) {
1727 LOGP(info,
"Using random device for seeding");
1728 std::random_device
rd;
1729 std::array<int, std::mt19937::state_size> seed_data{};
1730 std::generate(std::begin(seed_data), std::end(seed_data), std::ref(
rd));
1731 std::seed_seq seq(std::begin(seed_data), std::end(seed_data));
1732 mGenerator = std::mt19937(seq);
1734 LOGP(info,
"Using seed {} for sampling", seed);
1735 mGenerator.seed(seed);
1738 LOGP(info,
"Multi-threaded parts will run with {} OpenMP threads", mNThreads);
1741 LOG(info) <<
"OpenMP is disabled";
1743 if (mTFNumber == -1L) {
1744 LOG(info) <<
"TFNumber will be obtained from CCDB";
1746 if (mRunNumber == -1L) {
1747 LOG(info) <<
"The Run number will be obtained from DPL headers";
1750 mUseSigFiltMC = ic.
options().
get<
bool>(
"mc-signal-filt");
1753 if (mTruncate != 1) {
1754 LOG(info) <<
"Truncation is not used!";
1755 mCollisionPosition = 0xFFFFFFFF;
1756 mCollisionPositionCov = 0xFFFFFFFF;
1757 mTrackX = 0xFFFFFFFF;
1758 mTrackAlpha = 0xFFFFFFFF;
1759 mTrackSnp = 0xFFFFFFFF;
1760 mTrackTgl = 0xFFFFFFFF;
1761 mTrack1Pt = 0xFFFFFFFF;
1762 mTrackChi2 = 0xFFFFFFFF;
1763 mTrackCovDiag = 0xFFFFFFFF;
1764 mTrackCovOffDiag = 0xFFFFFFFF;
1765 mTrackSignal = 0xFFFFFFFF;
1766 mTrackTime = 0xFFFFFFFF;
1767 mTPCTime0 = 0xFFFFFFFF;
1768 mTrackTimeError = 0xFFFFFFFF;
1769 mTrackPosEMCAL = 0xFFFFFFFF;
1770 mTracklets = 0xFFFFFFFF;
1771 mMcParticleW = 0xFFFFFFFF;
1772 mMcParticlePos = 0xFFFFFFFF;
1773 mMcParticleMom = 0xFFFFFFFF;
1774 mCaloAmp = 0xFFFFFFFF;
1775 mCaloTime = 0xFFFFFFFF;
1776 mCPVPos = 0xFFFFFFFF;
1777 mCPVAmpl = 0xFFFFFFFF;
1778 mMuonTr1P = 0xFFFFFFFF;
1779 mMuonTrThetaX = 0xFFFFFFFF;
1780 mMuonTrThetaY = 0xFFFFFFFF;
1781 mMuonTrZmu = 0xFFFFFFFF;
1782 mMuonTrBend = 0xFFFFFFFF;
1783 mMuonTrNonBend = 0xFFFFFFFF;
1784 mMuonTrCov = 0xFFFFFFFF;
1785 mMuonCl = 0xFFFFFFFF;
1786 mMuonClErr = 0xFFFFFFFF;
1787 mV0Time = 0xFFFFFFFF;
1788 mV0ChannelTime = 0xFFFFFFFF;
1789 mFDDTime = 0xFFFFFFFF;
1790 mFDDChannelTime = 0xFFFFFFFF;
1791 mT0Time = 0xFFFFFFFF;
1792 mT0ChannelTime = 0xFFFFFFFF;
1793 mV0Amplitude = 0xFFFFFFFF;
1794 mFDDAmplitude = 0xFFFFFFFF;
1795 mT0Amplitude = 0xFFFFFFFF;
1799 mZDCEnergyMap[ic] = -std::numeric_limits<float>::infinity();
1802 mZDCTDCMap[ic] = -std::numeric_limits<float>::infinity();
1805 std::string hepmcUpdate = ic.
options().
get<std::string>(
"hepmc-update");
1806 HepMCUpdate when = (hepmcUpdate ==
"never" ? HepMCUpdate::never : hepmcUpdate ==
"always" ? HepMCUpdate::always
1807 : hepmcUpdate ==
"all" ? HepMCUpdate::allKeys
1808 : HepMCUpdate::anyKey);
1809 mXSectionUpdate = when;
1810 mPdfInfoUpdate = when;
1811 mHeavyIonUpdate = when;
1815 if (mStreamerFlags) {
1816 mStreamer = std::make_unique<o2::utils::TreeStreamRedirector>(
"AO2DStreamer.root",
"RECREATE");
1822void add_additional_meta_info(std::vector<TString>& keys, std::vector<TString>&
values)
1825 auto aod_external_meta_info_file = getenv(
"AOD_ADDITIONAL_METADATA_FILE");
1826 if (aod_external_meta_info_file !=
nullptr) {
1827 LOG(info) <<
"Trying to inject additional AOD meta-data from " << aod_external_meta_info_file;
1828 if (std::filesystem::exists(aod_external_meta_info_file)) {
1829 std::ifstream input_file(aod_external_meta_info_file);
1831 nlohmann::json json_data;
1833 input_file >> json_data;
1834 }
catch (nlohmann::json::parse_error& e) {
1835 std::cerr <<
"JSON Parse Error: " << e.what() <<
"\n";
1836 std::cerr <<
"Exception ID: " << e.id <<
"\n";
1837 std::cerr <<
"Byte position: " << e.byte <<
"\n";
1841 for (
const auto& [
key,
value] : json_data.items()) {
1842 LOG(info) <<
"Adding AOD MetaData" <<
key <<
" : " <<
value;
1843 keys.push_back(
key.c_str());
1854 mTimer.Start(
false);
1857 updateTimeDependentParams(pc);
1882 std::vector<o2::ctp::CTPDigit> ctpDigitsCreated;
1883 if (mCTPReadout == 1) {
1884 LOG(info) <<
"CTP : creating ctpreadout in AOD producer";
1885 createCTPReadout(recoData, ctpDigitsCreated, pc);
1886 LOG(info) <<
"CTP : ctpreadout created from AOD";
1887 ctpDigits = gsl::span<o2::ctp::CTPDigit>(ctpDigitsCreated);
1889 LOG(
debug) <<
"FOUND " << primVertices.size() <<
" primary vertices";
1890 LOG(
debug) <<
"FOUND " << ft0RecPoints.size() <<
" FT0 rec. points";
1891 LOG(
debug) <<
"FOUND " << fv0RecPoints.size() <<
" FV0 rec. points";
1892 LOG(
debug) <<
"FOUND " << fddRecPoints.size() <<
" FDD rec. points";
1893 LOG(
debug) <<
"FOUND " << cpvClusters.size() <<
" CPV clusters";
1894 LOG(
debug) <<
"FOUND " << cpvTrigRecs.size() <<
" CPV trigger records";
1896 LOG(info) <<
"FOUND " << primVertices.size() <<
" primary vertices";
1900 auto bcCursor = createTableCursor<o2::aod::BCs>(pc);
1901 auto bcFlagsCursor = createTableCursor<o2::aod::BCFlags>(pc);
1902 auto cascadesCursor = createTableCursor<o2::aod::Cascades>(pc);
1903 auto collisionsCursor = createTableCursor<o2::aod::Collisions>(pc);
1904 auto decay3BodyCursor = createTableCursor<o2::aod::Decay3Bodys>(pc);
1905 auto trackedCascadeCursor = createTableCursor<o2::aod::TrackedCascades>(pc);
1906 auto trackedV0Cursor = createTableCursor<o2::aod::TrackedV0s>(pc);
1907 auto tracked3BodyCurs = createTableCursor<o2::aod::Tracked3Bodys>(pc);
1908 auto fddCursor = createTableCursor<o2::aod::FDDs>(pc);
1909 auto fddExtraCursor = createTableCursor<o2::aod::FDDsExtra>(pc);
1910 auto ft0Cursor = createTableCursor<o2::aod::FT0s>(pc);
1911 auto ft0ExtraCursor = createTableCursor<o2::aod::FT0sExtra>(pc);
1912 auto fv0aCursor = createTableCursor<o2::aod::FV0As>(pc);
1913 auto fv0aExtraCursor = createTableCursor<o2::aod::FV0AsExtra>(pc);
1914 auto fwdTracksCursor = createTableCursor<o2::aod::StoredFwdTracks>(pc);
1915 auto fwdTracksCovCursor = createTableCursor<o2::aod::StoredFwdTracksCov>(pc);
1916 auto fwdTrkClsCursor = createTableCursor<o2::aod::FwdTrkCls>(pc);
1917 auto mftTracksCursor = createTableCursor<o2::aod::StoredMFTTracks>(pc);
1918 auto mftTracksCovCursor = createTableCursor<o2::aod::StoredMFTTracksCov>(pc);
1919 auto tracksCursor = createTableCursor<o2::aod::StoredTracksIU>(pc);
1920 auto tracksCovCursor = createTableCursor<o2::aod::StoredTracksCovIU>(pc);
1921 auto tracksExtraCursor = createTableCursor<o2::aod::StoredTracksExtra>(pc);
1922 auto tracksQACursor = createTableCursor<o2::aod::TracksQAVersion>(pc);
1923 auto ambigTracksCursor = createTableCursor<o2::aod::AmbiguousTracks>(pc);
1924 auto ambigMFTTracksCursor = createTableCursor<o2::aod::AmbiguousMFTTracks>(pc);
1925 auto ambigFwdTracksCursor = createTableCursor<o2::aod::AmbiguousFwdTracks>(pc);
1926 auto v0sCursor = createTableCursor<o2::aod::V0s>(pc);
1927 auto zdcCursor = createTableCursor<o2::aod::Zdcs>(pc);
1928 auto hmpCursor = createTableCursor<o2::aod::HMPIDs>(pc);
1929 auto caloCellsCursor = createTableCursor<o2::aod::Calos>(pc);
1930 auto caloCellsTRGTableCursor = createTableCursor<o2::aod::CaloTriggers>(pc);
1931 auto cpvClustersCursor = createTableCursor<o2::aod::CPVClusters>(pc);
1932 auto originCursor = createTableCursor<o2::aod::Origins>(pc);
1946 mcColLabelsCursor = createTableCursor<o2::aod::McCollisionLabels>(pc);
1947 mcCollisionsCursor = createTableCursor<o2::aod::McCollisions>(pc);
1948 hepmcXSectionsCursor = createTableCursor<o2::aod::HepMCXSections>(pc);
1949 hepmcPdfInfosCursor = createTableCursor<o2::aod::HepMCPdfInfos>(pc);
1950 hepmcHeavyIonsCursor = createTableCursor<o2::aod::HepMCHeavyIons>(pc);
1951 mcMFTTrackLabelCursor = createTableCursor<o2::aod::McMFTTrackLabels>(pc);
1952 mcFwdTrackLabelCursor = createTableCursor<o2::aod::McFwdTrackLabels>(pc);
1953 mcParticlesCursor = createTableCursor<o2::aod::StoredMcParticles_001>(pc);
1954 mcTrackLabelCursor = createTableCursor<o2::aod::McTrackLabels>(pc);
1955 mcCaloLabelsCursor = createTableCursor<o2::aod::McCaloLabels_001>(pc);
1958 std::unique_ptr<o2::steer::MCKinematicsReader> mcReader;
1960 mcReader = std::make_unique<o2::steer::MCKinematicsReader>(
"collisioncontext.root");
1962 mMCKineReader = mcReader.get();
1963 std::map<uint64_t, int> bcsMap;
1964 collectBCs(recoData, mUseMC ? mcReader->getDigitizationContext()->getEventRecords() : std::vector<o2::InteractionTimeRecord>{}, bcsMap);
1965 if (!primVer2TRefs.empty()) {
1966 addRefGlobalBCsForTOF(primVer2TRefs.back(), primVerGIs, recoData, bcsMap);
1969 mBCLookup.
init(bcsMap);
1972 const int runNumber = (mRunNumber == -1) ?
int(tinfo.runNumber) : mRunNumber;
1973 if (mTFNumber == -1L) {
1975 tfNumber = uint64_t(tinfo.firstTForbit) + (uint64_t(tinfo.runNumber) << 32);
1977 tfNumber = mTFNumber;
1980 std::vector<float> aAmplitudes, aTimes;
1981 std::vector<uint8_t> aChannels;
1982 fv0aCursor.reserve(fv0RecPoints.size());
1983 for (
auto& fv0RecPoint : fv0RecPoints) {
1984 aAmplitudes.clear();
1987 const auto channelData = fv0RecPoint.getBunchChannelData(fv0ChData);
1988 for (
auto& channel : channelData) {
1989 if (channel.charge > 0) {
1990 aAmplitudes.push_back(truncateFloatFraction(channel.charge, mV0Amplitude));
1991 aTimes.push_back(truncateFloatFraction(channel.time * 1.E-3, mV0ChannelTime));
1992 aChannels.push_back(channel.channel);
1995 uint64_t
bc = fv0RecPoint.getInteractionRecord().toLong();
1996 auto item = bcsMap.find(
bc);
1998 if (item != bcsMap.end()) {
1999 bcID = item->second;
2001 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a FV0 rec. point; BC = " <<
bc;
2006 truncateFloatFraction(fv0RecPoint.getCollisionGlobalMeanTime() * 1E-3, mV0Time),
2007 fv0RecPoint.getTrigger().getTriggersignals());
2009 if (mEnableFITextra) {
2010 fv0aExtraCursor(bcID,
2015 std::vector<float> zdcEnergy, zdcAmplitudes, zdcTime;
2016 std::vector<uint8_t> zdcChannelsE, zdcChannelsT;
2017 zdcCursor.reserve(zdcBCRecData.size());
2018 for (
auto zdcRecData : zdcBCRecData) {
2019 uint64_t
bc = zdcRecData.ir.toLong();
2020 auto item = bcsMap.find(
bc);
2022 if (item != bcsMap.end()) {
2023 bcID = item->second;
2025 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a ZDC rec. point; BC = " <<
bc;
2027 int fe, ne, ft, nt, fi, ni;
2028 zdcRecData.getRef(fe, ne, ft, nt, fi, ni);
2030 zdcChannelsE.clear();
2031 zdcAmplitudes.clear();
2033 zdcChannelsT.clear();
2034 for (
int ie = 0; ie < ne; ie++) {
2035 auto& zdcEnergyData = zdcEnergies[fe + ie];
2036 zdcEnergy.emplace_back(zdcEnergyData.energy());
2037 zdcChannelsE.emplace_back(zdcEnergyData.ch());
2039 for (
int it = 0; it < nt; it++) {
2040 auto& tdc = zdcTDCData[ft + it];
2041 zdcAmplitudes.emplace_back(tdc.amplitude());
2042 zdcTime.emplace_back(tdc.value());
2056 std::vector<std::vector<int>> mcColToEvSrc;
2062 int nMCCollisions = mcReader->getDigitizationContext()->getNCollisions();
2063 const auto& mcRecords = mcReader->getDigitizationContext()->getEventRecords();
2064 const auto& mcParts = mcReader->getDigitizationContext()->getEventParts();
2067 if (mUseSigFiltMC) {
2068 std::vector<int> sourceIDs{};
2069 for (
int iCol = 0; iCol < nMCCollisions; iCol++) {
2070 for (
auto const& colPart : mcParts[iCol]) {
2071 int sourceID = colPart.sourceID;
2072 if (std::find(sourceIDs.begin(), sourceIDs.end(), sourceID) == sourceIDs.end()) {
2073 sourceIDs.push_back(sourceID);
2075 if (sourceIDs.size() > 1) {
2079 if (sourceIDs.size() > 1) {
2083 if (sourceIDs.size() <= 1) {
2084 LOGP(fatal,
"Signal filtering cannot be enabled without embedding. Please fix the configuration either enabling the embedding, or turning off the signal filtering.");
2089 int totalNParts = 0;
2090 for (
int iCol = 0; iCol < nMCCollisions; iCol++) {
2091 totalNParts += mcParts[iCol].size();
2093 mcCollisionsCursor.
reserve(totalNParts);
2095 for (
int iCol = 0; iCol < nMCCollisions; iCol++) {
2096 const auto time = mcRecords[iCol].getTimeOffsetWrtBC();
2097 auto globalBC = mcRecords[iCol].toLong();
2098 auto item = bcsMap.find(globalBC);
2100 if (item != bcsMap.end()) {
2101 bcID = item->second;
2103 LOG(fatal) <<
"Error: could not find a corresponding BC ID "
2104 <<
"for MC collision; BC = " << globalBC
2105 <<
", mc collision = " << iCol;
2107 auto& colParts = mcParts[iCol];
2108 auto nParts = colParts.size();
2109 for (
auto colPart : colParts) {
2110 auto eventID = colPart.entryID;
2111 auto sourceID = colPart.sourceID;
2114 if (nParts == 1 || sourceID == 0) {
2117 auto& header = mcReader->getMCEventHeader(sourceID, eventID);
2118 updateMCHeader(mcCollisionsCursor.
cursor,
2119 hepmcXSectionsCursor.
cursor,
2120 hepmcPdfInfosCursor.
cursor,
2121 hepmcHeavyIonsCursor.
cursor,
2129 mcColToEvSrc.emplace_back(std::vector<int>{iCol, sourceID, eventID});
2134 std::sort(mcColToEvSrc.begin(), mcColToEvSrc.end(),
2135 [](
const std::vector<int>&
left,
const std::vector<int>&
right) { return (left[0] < right[0]); });
2138 int16_t aFDDAmplitudesA[8] = {0u}, aFDDAmplitudesC[8] = {0u};
2139 float aFDDTimesA[8] = {0.f}, aFDDTimesC[8] = {0.f};
2141 fddCursor.reserve(fddRecPoints.size());
2142 for (
const auto& fddRecPoint : fddRecPoints) {
2143 for (
int i = 0;
i < 8;
i++) {
2144 aFDDAmplitudesA[
i] = 0;
2145 aFDDAmplitudesC[
i] = 0;
2146 aFDDTimesA[
i] = 0.f;
2147 aFDDTimesC[
i] = 0.f;
2149 uint64_t globalBC = fddRecPoint.getInteractionRecord().toLong();
2150 uint64_t
bc = globalBC;
2151 auto item = bcsMap.find(
bc);
2153 if (item != bcsMap.end()) {
2154 bcID = item->second;
2156 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a FDD rec. point; BC = " <<
bc;
2158 const auto channelData = fddRecPoint.getBunchChannelData(fddChData);
2159 for (
const auto& channel : channelData) {
2160 if (channel.mPMNumber < 8) {
2161 aFDDAmplitudesC[channel.mPMNumber] = channel.mChargeADC;
2162 aFDDTimesC[channel.mPMNumber] = truncateFloatFraction(channel.mTime * 1E-3, mFDDChannelTime);
2164 aFDDAmplitudesA[channel.mPMNumber - 8] = channel.mChargeADC;
2165 aFDDTimesA[channel.mPMNumber - 8] = truncateFloatFraction(channel.mTime * 1E-3, mFDDChannelTime);
2172 truncateFloatFraction(fddRecPoint.getCollisionTimeA() * 1E-3, mFDDTime),
2173 truncateFloatFraction(fddRecPoint.getCollisionTimeC() * 1E-3, mFDDTime),
2174 fddRecPoint.getTrigger().getTriggersignals());
2175 if (mEnableFITextra) {
2176 fddExtraCursor(bcID,
2183 std::vector<float> aAmplitudesA, aAmplitudesC, aTimesA, aTimesC;
2184 std::vector<uint8_t> aChannelsA, aChannelsC;
2185 ft0Cursor.reserve(ft0RecPoints.size());
2186 for (
auto& ft0RecPoint : ft0RecPoints) {
2187 aAmplitudesA.clear();
2188 aAmplitudesC.clear();
2193 const auto channelData = ft0RecPoint.getBunchChannelData(ft0ChData);
2194 for (
auto& channel : channelData) {
2196 if (channel.QTCAmpl > 0) {
2198 if (channel.ChId < nFT0ChannelsAside) {
2199 aChannelsA.push_back(channel.ChId);
2200 aAmplitudesA.push_back(truncateFloatFraction(channel.QTCAmpl, mT0Amplitude));
2201 aTimesA.push_back(truncateFloatFraction(channel.CFDTime * 1E-3, mT0ChannelTime));
2203 aChannelsC.push_back(channel.ChId - nFT0ChannelsAside);
2204 aAmplitudesC.push_back(truncateFloatFraction(channel.QTCAmpl, mT0Amplitude));
2205 aTimesC.push_back(truncateFloatFraction(channel.CFDTime * 1E-3, mT0ChannelTime));
2209 uint64_t globalBC = ft0RecPoint.getInteractionRecord().toLong();
2210 uint64_t
bc = globalBC;
2211 auto item = bcsMap.find(
bc);
2213 if (item != bcsMap.end()) {
2214 bcID = item->second;
2216 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a FT0 rec. point; BC = " <<
bc;
2223 truncateFloatFraction(ft0RecPoint.getCollisionTimeA() * 1E-3, mT0Time),
2224 truncateFloatFraction(ft0RecPoint.getCollisionTimeC() * 1E-3, mT0Time),
2225 ft0RecPoint.getTrigger().getTriggersignals());
2226 if (mEnableFITextra) {
2227 ft0ExtraCursor(bcID,
2235 mcColLabelsCursor.
reserve(primVerLabels.size());
2236 for (
auto&
label : primVerLabels) {
2237 auto it = std::find_if(mcColToEvSrc.begin(), mcColToEvSrc.end(),
2238 [&
label](
const auto& mcColInfo) { return mcColInfo[1] == label.getSourceID() && mcColInfo[2] == label.getEventID(); });
2239 int32_t mcCollisionID = -1;
2240 if (it != mcColToEvSrc.end()) {
2241 mcCollisionID = it->at(0);
2243 uint16_t mcMask = 0;
2244 mcColLabelsCursor(mcCollisionID, mcMask);
2248 cacheTriggers(recoData);
2249 countTPCClusters(recoData);
2251 int collisionID = 0;
2255 auto& trackReffwd = primVer2TRefs.back();
2256 fillIndexTablesPerCollision(trackReffwd, primVerGIs, recoData);
2258 for (
auto&
vertex : primVertices) {
2259 auto& trackReffwd = primVer2TRefs[collisionID];
2260 fillIndexTablesPerCollision(trackReffwd, primVerGIs, recoData);
2265 prepareStrangenessTracking(recoData);
2267 mGIDToTableFwdID.clear();
2268 mGIDToTableMFTID.clear();
2270 if (mPropTracks || mThinTracks) {
2274 mGIDUsedBySVtx.reserve(v0s.size() * 2 + cascades.size() + decays3Body.size() * 3);
2275 for (
const auto&
v0 : v0s) {
2276 mGIDUsedBySVtx.insert(
v0.getProngID(0));
2277 mGIDUsedBySVtx.insert(
v0.getProngID(1));
2279 for (
const auto& cascade : cascades) {
2280 mGIDUsedBySVtx.insert(cascade.getBachelorID());
2282 for (
const auto& id3Body : decays3Body) {
2283 mGIDUsedBySVtx.insert(id3Body.getProngID(0));
2284 mGIDUsedBySVtx.insert(id3Body.getProngID(1));
2285 mGIDUsedBySVtx.insert(id3Body.getProngID(2));
2296 auto& trackRef = primVer2TRefs.back();
2298 fillTrackTablesPerCollision(-1, std::uint64_t(-1), trackRef, primVerGIs, recoData, tracksCursor, tracksCovCursor, tracksExtraCursor, tracksQACursor,
2299 ambigTracksCursor, mftTracksCursor, mftTracksCovCursor, ambigMFTTracksCursor,
2300 fwdTracksCursor, fwdTracksCovCursor, ambigFwdTracksCursor, fwdTrkClsCursor, bcsMap);
2304 collisionsCursor.reserve(primVertices.size());
2305 for (
auto&
vertex : primVertices) {
2306 auto& cov =
vertex.getCov();
2307 auto& timeStamp =
vertex.getTimeStamp();
2308 const double interactionTime = timeStamp.getTimeStamp() * 1E3;
2309 uint64_t globalBC = relativeTime_to_GlobalBC(interactionTime);
2310 uint64_t localBC = relativeTime_to_LocalBC(interactionTime);
2311 LOG(
debug) <<
"global BC " << globalBC <<
" local BC " << localBC <<
" relative interaction time " << interactionTime;
2314 auto item = bcsMap.find(globalBC);
2316 if (item != bcsMap.end()) {
2317 bcID = item->second;
2319 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a collision; BC = " << globalBC <<
", collisionID = " << collisionID;
2321 collisionsCursor(bcID,
2322 truncateFloatFraction(
vertex.getX(), mCollisionPosition),
2323 truncateFloatFraction(
vertex.getY(), mCollisionPosition),
2324 truncateFloatFraction(
vertex.getZ(), mCollisionPosition),
2325 truncateFloatFraction(cov[0], mCollisionPositionCov),
2326 truncateFloatFraction(cov[1], mCollisionPositionCov),
2327 truncateFloatFraction(cov[2], mCollisionPositionCov),
2328 truncateFloatFraction(cov[3], mCollisionPositionCov),
2329 truncateFloatFraction(cov[4], mCollisionPositionCov),
2330 truncateFloatFraction(cov[5], mCollisionPositionCov),
2332 truncateFloatFraction(
vertex.getChi2(), mCollisionPositionCov),
2333 vertex.getNContributors(),
2334 truncateFloatFraction(relInteractionTime, mCollisionPosition),
2335 truncateFloatFraction(timeStamp.getTimeStampError() * 1E3, mCollisionPositionCov));
2336 mVtxToTableCollID[collisionID] = mTableCollID++;
2338 auto& trackRef = primVer2TRefs[collisionID];
2340 fillTrackTablesPerCollision(collisionID, globalBC, trackRef, primVerGIs, recoData, tracksCursor, tracksCovCursor, tracksExtraCursor, tracksQACursor, ambigTracksCursor,
2341 mftTracksCursor, mftTracksCovCursor, ambigMFTTracksCursor,
2342 fwdTracksCursor, fwdTracksCovCursor, ambigFwdTracksCursor, fwdTrkClsCursor, bcsMap);
2346 fillSecondaryVertices(recoData, v0sCursor, cascadesCursor, decay3BodyCursor);
2347 fillHMPID(recoData, hmpCursor);
2348 fillStrangenessTrackingTables(recoData, trackedV0Cursor, trackedCascadeCursor, tracked3BodyCurs);
2352 std::unordered_map<uint64_t, std::pair<uint64_t, uint64_t>> bcToClassMask;
2354 LOG(
debug) <<
"CTP input available";
2355 for (
auto& ctpDigit : ctpDigits) {
2356 uint64_t
bc = ctpDigit.intRecord.toLong();
2357 uint64_t classMask = ctpDigit.CTPClassMask.to_ulong();
2358 uint64_t inputMask = ctpDigit.CTPInputMask.to_ulong();
2359 if (emcalIncomplete.find(
bc) != emcalIncomplete.end()) {
2361 auto classMaskOrig = classMask;
2362 classMask = classMask & ~mEMCALTrgClassMask;
2363 LOG(
debug) <<
"Found EMCAL incomplete event, mask before " << std::bitset<64>(classMaskOrig) <<
", after " << std::bitset<64>(classMask);
2365 bcToClassMask[
bc] = {classMask, inputMask};
2371 bcCursor.reserve(bcsMap.size());
2372 for (
auto& item : bcsMap) {
2373 uint64_t
bc = item.first;
2374 std::pair<uint64_t, uint64_t> masks{0, 0};
2376 auto bcClassPair = bcToClassMask.find(
bc);
2377 if (bcClassPair != bcToClassMask.end()) {
2378 masks = bcClassPair->second;
2387 bcToClassMask.clear();
2390 auto bcFlags = fillBCFlags(recoData, bcsMap);
2391 bcFlagsCursor.reserve(bcFlags.size());
2392 for (
auto f : bcFlags) {
2399 cpvClustersCursor.reserve(cpvTrigRecs.size());
2400 for (
auto& cpvEvent : cpvTrigRecs) {
2401 uint64_t
bc = cpvEvent.getBCData().toLong();
2402 auto item = bcsMap.find(
bc);
2404 if (item != bcsMap.end()) {
2405 bcID = item->second;
2407 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a CPV Trigger Record; BC = " <<
bc;
2409 for (
int iClu = cpvEvent.getFirstEntry(); iClu < cpvEvent.getFirstEntry() + cpvEvent.getNumberOfObjects(); iClu++) {
2410 auto&
clu = cpvClusters[iClu];
2411 clu.getLocalPosition(posX, posZ);
2412 cpvClustersCursor(bcID,
2413 truncateFloatFraction(posX, mCPVPos),
2414 truncateFloatFraction(posZ, mCPVPos),
2415 truncateFloatFraction(
clu.getEnergy(), mCPVAmpl),
2416 clu.getPackedClusterStatus());
2425 fillMCParticlesTable(*mcReader,
2426 mcParticlesCursor.
cursor,
2432 LOG(info) <<
"FILL MC took " << timer.RealTime() <<
" s";
2433 mcColToEvSrc.clear();
2439 fillMCTrackLabelsTable(mcTrackLabelCursor, mcMFTTrackLabelCursor, mcFwdTrackLabelCursor, primVer2TRefs.back(), primVerGIs, recoData);
2440 for (
auto iref = 0U; iref < primVer2TRefs.size() - 1; iref++) {
2441 auto& trackRef = primVer2TRefs[iref];
2442 fillMCTrackLabelsTable(mcTrackLabelCursor, mcMFTTrackLabelCursor, mcFwdTrackLabelCursor, trackRef, primVerGIs, recoData, iref);
2448 fillCaloTable(caloCellsCursor, caloCellsTRGTableCursor, mcCaloLabelsCursor, bcsMap, recoData);
2453 mGIDToTableID.clear();
2455 mGIDToTableFwdID.clear();
2457 mGIDToTableMFTID.clear();
2459 mVtxToTableCollID.clear();
2461 mV0ToTableID.clear();
2464 mIndexTableFwd.clear();
2466 mIndexTableMFT.clear();
2471 mGIDUsedBySVtx.clear();
2472 mGIDUsedByStr.clear();
2474 originCursor(tfNumber);
2477 TString dataType = mUseMC ?
"MC" :
"RAW";
2479 TString ROOTVersion = ROOT_RELEASE;
2480 mMetaDataKeys = {
"DataType",
"Run",
"O2Version",
"ROOTVersion",
"RecoPassName",
"AnchorProduction",
"AnchorPassName",
"LPMProductionTag",
"CreatedBy"};
2481 mMetaDataVals = {dataType,
"3", O2Version, ROOTVersion, mRecoPass, mAnchorProd, mAnchorPass, mLPMProdTag, mUser};
2482 add_additional_meta_info(mMetaDataKeys, mMetaDataVals);
2500 for (
const auto& rof : rofs) {
2501 int first = rof.getFirstEntry(), last =
first + rof.getNEntries();
2502 for (
int i =
first;
i < last;
i++) {
2503 mITSROFs.push_back(
count);
2513 for (
const auto& rof : rofs) {
2514 int first = rof.getFirstEntry(),
last =
first + rof.getNEntries();
2516 mMFTROFs.push_back(
count);
2523 mITSTPCTRDTriggers.clear();
2526 for (
const auto& trig : itstpctrigs) {
2527 int first = trig.getFirstTrack(),
last =
first + trig.getNumberOfTracks();
2529 mITSTPCTRDTriggers.push_back(
count);
2536 mTPCTRDTriggers.clear();
2539 for (
const auto& trig : tpctrigs) {
2540 int first = trig.getFirstTrack(),
last =
first + trig.getNumberOfTracks();
2542 mTPCTRDTriggers.push_back(
count);
2552 for (
const auto& rof : rofs) {
2555 mMCHROFs.push_back(
count);
2562AODProducerWorkflowDPL::TrackExtraInfo AODProducerWorkflowDPL::processBarrelTrack(
int collisionID, std::uint64_t collisionBC,
GIndex trackIndex,
2565 TrackExtraInfo extraInfoHolder;
2566 if (collisionID < 0) {
2569 bool needBCSlice = collisionID < 0;
2570 uint64_t bcOfTimeRef = collisionBC - mStartIR.
toLong();
2572 auto setTrackTime = [&](
double t,
double terr,
bool gaussian) {
2578 extraInfoHolder.trackTimeRes = terr;
2580 double error = this->mTimeMarginTrackTime + (gaussian ? extraInfoHolder.trackTimeRes * this->mNSigmaTimeTrack : extraInfoHolder.trackTimeRes);
2581 bcOfTimeRef = fillBCSlice(extraInfoHolder.bcSlice, t - error, t + error, bcsMap);
2584 extraInfoHolder.diffBCRef =
int(bcOfTimeRef);
2586 truncateFloatFraction(extraInfoHolder.trackTime, mTrackTime), truncateFloatFraction(extraInfoHolder.trackTimeRes, mTrackTimeError),
2589 auto contributorsGID =
data.getSingleDetectorRefs(trackIndex);
2590 const auto& trackPar =
data.getTrackParam(trackIndex);
2591 extraInfoHolder.flags |= trackPar.getPID() << 28;
2592 auto src = trackIndex.getSource();
2594 const auto& tofMatch =
data.getTOFMatch(trackIndex);
2595 extraInfoHolder.tofChi2 = tofMatch.getChi2();
2596 const auto& tofInt = tofMatch.getLTIntegralOut();
2597 float intLen = tofInt.getL();
2598 extraInfoHolder.length = intLen;
2605 extraInfoHolder.tofExpMom = mass * expBeta / std::sqrt(1.f - expBeta * expBeta);
2608 const double massZ = o2::track::PID::getMass2Z(trackPar.getPID());
2609 const double energy = sqrt((massZ * massZ) + (extraInfoHolder.tofExpMom * extraInfoHolder.tofExpMom));
2610 const double exp = extraInfoHolder.length * energy / (cSpeed * extraInfoHolder.tofExpMom);
2611 auto tofSignal = (tofMatch.getSignal() -
exp) * 1e-3;
2612 setTrackTime(tofSignal, 0.2,
true);
2616 extraInfoHolder.trdChi2 = trdOrig.getChi2();
2617 extraInfoHolder.trdSignal = trdOrig.getSignal();
2618 extraInfoHolder.trdPattern = getTRDPattern(trdOrig);
2619 if (extraInfoHolder.trackTimeRes < 0.) {
2621 const auto& trdTrig = (
src ==
GIndex::Source::TPCTRD) ?
data.getTPCTRDTriggers()[mTPCTRDTriggers[trackIndex.getIndex()]] :
data.getITSTPCTRDTriggers()[mITSTPCTRDTriggers[trackIndex.getIndex()]];
2623 setTrackTime(ttrig, 1.,
true);
2627 const auto& itsTrack =
data.getITSTrack(contributorsGID[
GIndex::ITS]);
2628 int nClusters = itsTrack.getNClusters();
2629 float chi2 = itsTrack.getChi2();
2631 extraInfoHolder.itsClusterSizes = itsTrack.getClusterSizes();
2633 const auto& rof =
data.getITSTracksROFRecords()[mITSROFs[trackIndex.getIndex()]];
2635 setTrackTime(t, mITSROFrameHalfLengthNS,
false);
2638 extraInfoHolder.itsClusterSizes =
data.getITSABRefs()[contributorsGID[
GIndex::Source::ITSAB].getIndex()].getClusterSizes();
2642 const auto& tpcClData = mTPCCounters[contributorsGID[
GIndex::TPC]];
2643 const auto& dEdx = tpcOrig.getdEdx().dEdxTotTPC > 0 ? tpcOrig.getdEdx() : tpcOrig.getdEdxAlt();
2644 if (tpcOrig.getdEdx().dEdxTotTPC == 0) {
2647 extraInfoHolder.tpcInnerParam = tpcOrig.getP() / tpcOrig.getAbsCharge();
2648 extraInfoHolder.tpcChi2NCl = tpcOrig.getNClusters() ? tpcOrig.getChi2() / tpcOrig.getNClusters() : 0;
2649 extraInfoHolder.tpcSignal = dEdx.dEdxTotTPC;
2650 extraInfoHolder.tpcNClsFindable = tpcOrig.getNClusters();
2651 extraInfoHolder.tpcNClsFindableMinusFound = tpcOrig.getNClusters() - tpcClData.found;
2652 extraInfoHolder.tpcNClsFindableMinusCrossedRows = tpcOrig.getNClusters() - tpcClData.crossed;
2653 extraInfoHolder.tpcNClsShared = tpcClData.shared;
2654 uint32_t clsUsedForPID = dEdx.NHitsIROC + dEdx.NHitsOROC1 + dEdx.NHitsOROC2 + dEdx.NHitsOROC3;
2655 extraInfoHolder.tpcNClsFindableMinusPID = tpcOrig.getNClusters() - clsUsedForPID;
2658 double t = (tpcOrig.getTime0() + 0.5 * (tpcOrig.getDeltaTFwd() - tpcOrig.getDeltaTBwd())) * mTPCBinNS;
2659 double terr = 0.5 * (tpcOrig.getDeltaTFwd() + tpcOrig.getDeltaTBwd()) * mTPCBinNS;
2660 double err = mTimeMarginTrackTime + terr;
2661 bcOfTimeRef = fillBCSlice(extraInfoHolder.bcSlice, t - err, t + err, bcsMap);
2664 p.setDeltaTFwd(tpcOrig.getDeltaTFwd());
2665 p.setDeltaTBwd(tpcOrig.getDeltaTBwd());
2666 extraInfoHolder.trackTimeRes =
p.getTimeErr();
2668 extraInfoHolder.diffBCRef =
int(bcOfTimeRef);
2669 extraInfoHolder.isTPConly =
true;
2672 const auto& trITSTPC =
data.getTPCITSTrack(trackIndex);
2673 auto ts = trITSTPC.getTimeMUS();
2674 setTrackTime(ts.getTimeStamp() * 1.e3, ts.getTimeStampError() * 1.e3,
true);
2678 extrapolateToCalorimeters(extraInfoHolder,
data.getTrackParamOut(trackIndex));
2683 return extraInfoHolder;
2686AODProducerWorkflowDPL::TrackQA AODProducerWorkflowDPL::processBarrelTrackQA(
int collisionID, std::uint64_t collisionBC,
GIndex trackIndex,
2690 auto contributorsGID =
data.getTPCContributorGID(trackIndex);
2691 const auto& trackPar =
data.getTrackParam(trackIndex);
2692 if (contributorsGID.isIndexSet()) {
2694 const auto& tpcOrig =
data.getTPCTrack(contributorsGID);
2699 std::array<float, 2> dcaInfo{-999., -999.};
2700 if (prop->propagateToDCABxByBz({v.getX(), v.getY(), v.getZ()}, tpcTMP, 2.f, mMatType, &dcaInfo)) {
2701 trackQAHolder.tpcdcaR = 100. * dcaInfo[0] / sqrt(1. + trackPar.getQ2Pt() * trackPar.getQ2Pt());
2702 trackQAHolder.tpcdcaZ = 100. * dcaInfo[1] / sqrt(1. + trackPar.getQ2Pt() * trackPar.getQ2Pt());
2706 auto safeInt8Clamp = [](
auto value) -> int8_t {
2707 using ValType =
decltype(
value);
2708 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()))));
2710 auto safeUInt8Clamp = [](
auto value) -> uint8_t {
2711 using ValType =
decltype(
value);
2712 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()))));
2716 uint8_t clusterCounters[8] = {0};
2718 uint8_t sectorIndex, rowIndex;
2719 uint32_t clusterIndex;
2720 const auto& tpcClusRefs =
data.getTPCTracksClusterRefs();
2721 for (
int i = 0;
i < tpcOrig.getNClusterReferences();
i++) {
2722 o2::tpc::TrackTPC::getClusterReference(tpcClusRefs,
i, sectorIndex, rowIndex, clusterIndex, tpcOrig.getClusterRef());
2723 char indexTracklet = (rowIndex % 152) / 19;
2724 clusterCounters[indexTracklet]++;
2728 for (
int i = 0;
i < 8;
i++) {
2729 if (clusterCounters[
i] > 5) {
2730 byteMask |= (1 <<
i);
2733 trackQAHolder.tpcTime0 = tpcOrig.getTime0();
2734 trackQAHolder.tpcClusterByteMask = byteMask;
2735 const auto& dEdxInfoAlt = tpcOrig.getdEdxAlt();
2736 const float dEdxNorm = (dEdxInfoAlt.dEdxTotTPC > 0) ? 100. / dEdxInfoAlt.dEdxTotTPC : 0;
2737 trackQAHolder.tpcdEdxNorm = dEdxInfoAlt.dEdxTotTPC;
2738 trackQAHolder.tpcdEdxMax0R = safeUInt8Clamp(dEdxInfoAlt.dEdxMaxIROC * dEdxNorm);
2739 trackQAHolder.tpcdEdxMax1R = safeUInt8Clamp(dEdxInfoAlt.dEdxMaxOROC1 * dEdxNorm);
2740 trackQAHolder.tpcdEdxMax2R = safeUInt8Clamp(dEdxInfoAlt.dEdxMaxOROC2 * dEdxNorm);
2741 trackQAHolder.tpcdEdxMax3R = safeUInt8Clamp(dEdxInfoAlt.dEdxMaxOROC3 * dEdxNorm);
2743 trackQAHolder.tpcdEdxTot0R = safeUInt8Clamp(dEdxInfoAlt.dEdxTotIROC * dEdxNorm);
2744 trackQAHolder.tpcdEdxTot1R = safeUInt8Clamp(dEdxInfoAlt.dEdxTotOROC1 * dEdxNorm);
2745 trackQAHolder.tpcdEdxTot2R = safeUInt8Clamp(dEdxInfoAlt.dEdxTotOROC2 * dEdxNorm);
2746 trackQAHolder.tpcdEdxTot3R = safeUInt8Clamp(dEdxInfoAlt.dEdxTotOROC3 * dEdxNorm);
2749 auto contributorsGIDA =
data.getSingleDetectorRefs(trackIndex);
2751 const auto& tofMatch =
data.getTOFMatch(trackIndex);
2752 const float qpt = trackPar.getQ2Pt();
2754 trackQAHolder.dTofdX = safeInt8Clamp(tofMatch.getDXatTOF() / scaleTOF);
2755 trackQAHolder.dTofdZ = safeInt8Clamp(tofMatch.getDZatTOF() / scaleTOF);
2761 if (
auto itsContGID =
data.getITSContributorGID(trackIndex); itsContGID.isIndexSet() && itsContGID.getSource() !=
GIndex::ITSAB) {
2762 const auto& itsOrig =
data.getITSTrack(itsContGID);
2771 const float beta0 = std::sqrt(std::min(50.f / tpcOrig.getdEdx().dEdxMaxTPC, 1.f));
2772 const float qpt = gloCopy.getQ2Pt();
2773 const float x = qpt / beta0;
2775 auto scaleCont = [&
x](
int i) ->
float {
2778 auto scaleGlo = [&
x](
int i) ->
float {
2783 trackQAHolder.dRefContY = safeInt8Clamp((itsCopy.getY() - tpcCopy.getY()) * scaleCont(0));
2784 trackQAHolder.dRefContZ = safeInt8Clamp((itsCopy.getZ() - tpcCopy.getZ()) * scaleCont(1));
2785 trackQAHolder.dRefContSnp = safeInt8Clamp((itsCopy.getSnp() - tpcCopy.getSnp()) * scaleCont(2));
2786 trackQAHolder.dRefContTgl = safeInt8Clamp((itsCopy.getTgl() - tpcCopy.getTgl()) * scaleCont(3));
2787 trackQAHolder.dRefContQ2Pt = safeInt8Clamp((itsCopy.getQ2Pt() - tpcCopy.getQ2Pt()) * scaleCont(4));
2789 trackQAHolder.dRefGloY = safeInt8Clamp(((itsCopy.getY() + tpcCopy.getY()) * 0.5f - gloCopy.getY()) * scaleGlo(0));
2790 trackQAHolder.dRefGloZ = safeInt8Clamp(((itsCopy.getZ() + tpcCopy.getZ()) * 0.5f - gloCopy.getZ()) * scaleGlo(1));
2791 trackQAHolder.dRefGloSnp = safeInt8Clamp(((itsCopy.getSnp() + tpcCopy.getSnp()) * 0.5f - gloCopy.getSnp()) * scaleGlo(2));
2792 trackQAHolder.dRefGloTgl = safeInt8Clamp(((itsCopy.getTgl() + tpcCopy.getTgl()) * 0.5f - gloCopy.getTgl()) * scaleGlo(3));
2793 trackQAHolder.dRefGloQ2Pt = safeInt8Clamp(((itsCopy.getQ2Pt() + tpcCopy.getQ2Pt()) * 0.5f - gloCopy.getQ2Pt()) * scaleGlo(4));
2797 (*mStreamer) <<
"trackQA"
2798 <<
"trackITSOrig=" << itsOrig
2799 <<
"trackTPCOrig=" << tpcOrig
2800 <<
"trackITSTPCOrig=" << trackPar
2801 <<
"trackITSProp=" << itsCopy
2802 <<
"trackTPCProp=" << tpcCopy
2803 <<
"trackITSTPCProp=" << gloCopy
2806 <<
"scaleCont0=" << scaleCont(0)
2807 <<
"scaleCont1=" << scaleCont(1)
2808 <<
"scaleCont2=" << scaleCont(2)
2809 <<
"scaleCont3=" << scaleCont(3)
2810 <<
"scaleCont4=" << scaleCont(4)
2811 <<
"scaleGlo0=" << scaleGlo(0)
2812 <<
"scaleGlo1=" << scaleGlo(1)
2813 <<
"scaleGlo2=" << scaleGlo(2)
2814 <<
"scaleGlo3=" << scaleGlo(3)
2815 <<
"scaleGlo4=" << scaleGlo(4)
2816 <<
"trackQAHolder.tpcTime0=" << trackQAHolder.tpcTime0
2817 <<
"trackQAHolder.tpcdEdxNorm=" << trackQAHolder.tpcdEdxNorm
2818 <<
"trackQAHolder.tpcdcaR=" << trackQAHolder.tpcdcaR
2819 <<
"trackQAHolder.tpcdcaZ=" << trackQAHolder.tpcdcaZ
2820 <<
"trackQAHolder.tpcdcaClusterByteMask=" << trackQAHolder.tpcClusterByteMask
2821 <<
"trackQAHolder.tpcdEdxMax0R=" << trackQAHolder.tpcdEdxMax0R
2822 <<
"trackQAHolder.tpcdEdxMax1R=" << trackQAHolder.tpcdEdxMax1R
2823 <<
"trackQAHolder.tpcdEdxMax2R=" << trackQAHolder.tpcdEdxMax2R
2824 <<
"trackQAHolder.tpcdEdxMax3R=" << trackQAHolder.tpcdEdxMax3R
2825 <<
"trackQAHolder.tpcdEdxTot0R=" << trackQAHolder.tpcdEdxTot0R
2826 <<
"trackQAHolder.tpcdEdxTot1R=" << trackQAHolder.tpcdEdxTot1R
2827 <<
"trackQAHolder.tpcdEdxTot2R=" << trackQAHolder.tpcdEdxTot2R
2828 <<
"trackQAHolder.tpcdEdxTot3R=" << trackQAHolder.tpcdEdxTot3R
2829 <<
"trackQAHolder.dRefContY=" << trackQAHolder.dRefContY
2830 <<
"trackQAHolder.dRefContZ=" << trackQAHolder.dRefContZ
2831 <<
"trackQAHolder.dRefContSnp=" << trackQAHolder.dRefContSnp
2832 <<
"trackQAHolder.dRefContTgl=" << trackQAHolder.dRefContTgl
2833 <<
"trackQAHolder.dRefContQ2Pt=" << trackQAHolder.dRefContQ2Pt
2834 <<
"trackQAHolder.dRefGloY=" << trackQAHolder.dRefGloY
2835 <<
"trackQAHolder.dRefGloZ=" << trackQAHolder.dRefGloZ
2836 <<
"trackQAHolder.dRefGloSnp=" << trackQAHolder.dRefGloSnp
2837 <<
"trackQAHolder.dRefGloTgl=" << trackQAHolder.dRefGloTgl
2838 <<
"trackQAHolder.dRefGloQ2Pt=" << trackQAHolder.dRefGloQ2Pt
2839 <<
"trackQAHolder.dTofdX=" << trackQAHolder.dTofdX
2840 <<
"trackQAHolder.dTofdZ=" << trackQAHolder.dTofdZ
2841 <<
"scaleTOF=" << scaleTOF
2848 return trackQAHolder;
2856 dcaInfo.set(999.f, 999.f, 999.f, 999.f, 999.f);
2861void AODProducerWorkflowDPL::extrapolateToCalorimeters(TrackExtraInfo& extraInfoHolder,
const o2::track::TrackPar& track)
2863 constexpr float XEMCAL = 440.f, XPHOS = 460.f, XEMCAL2 = XEMCAL * XEMCAL;
2864 constexpr float ETAEMCAL = 0.75;
2865 constexpr float ZEMCALFastCheck = 460.;
2866 constexpr float ETADCALINNER = 0.22;
2867 constexpr float ETAPHOS = 0.13653194;
2868 constexpr float ETAPHOSMARGIN = 0.17946979;
2869 constexpr float ETADCALPHOSSWITCH = (ETADCALINNER + ETAPHOS) / 2;
2870 constexpr short SNONE = 0, SEMCAL = 0x1, SPHOS = 0x2;
2871 constexpr short SECTORTYPE[18] = {
2872 SNONE, SNONE, SNONE, SNONE,
2873 SEMCAL, SEMCAL, SEMCAL, SEMCAL, SEMCAL, SEMCAL,
2876 SPHOS | SEMCAL, SPHOS | SEMCAL, SPHOS | SEMCAL,
2887 (std::abs(outTr.getZAt(xtrg, 0)) > ZEMCALFastCheck) ||
2888 !prop->PropagateToXBxByBz(outTr, xtrg, 0.95, 10, o2::base::Propagator::MatCorrType::USEMatCorrLUT)) {
2889 LOGP(
debug,
"preliminary step: does not reach R={} {}", XEMCAL, outTr.asString());
2893 if ((outTr.getX() * outTr.getX() + outTr.getY() * outTr.getY() < XEMCAL2) &&
2894 (!outTr.rotateParam(outTr.getPhi()) ||
2896 !prop->PropagateToXBxByBz(outTr, xtrg, 0.95, 10, o2::base::Propagator::MatCorrType::USEMatCorrLUT))) {
2897 LOGP(
debug,
"does not reach R={} {}", XEMCAL, outTr.asString());
2903 auto propExactSector = [&outTr, §or, prop](
float xprop) ->
bool {
2906 auto outTrTmp = outTr;
2908 if ((std::abs(outTr.getZ()) > ZEMCALFastCheck) || !outTrTmp.rotateParam(
alpha) ||
2909 !prop->PropagateToXBxByBz(outTrTmp, xprop, 0.95, 10, o2::base::Propagator::MatCorrType::USEMatCorrLUT)) {
2910 LOGP(
debug,
"failed on rotation to {} (sector {}) or propagation to X={} {}",
alpha, sector, xprop, outTrTmp.asString());
2915 if (sectorTmp == sector) {
2923 LOGP(
debug,
"failed to rotate to sector, {}", outTr.asString());
2930 if (!propExactSector(XEMCAL) || SECTORTYPE[sector] == SNONE) {
2935 float r = std::sqrt(outTr.getX() * outTr.getX() + outTr.getY() * outTr.getY()), tg = std::atan2(
r, outTr.getZ());
2936 float eta = -std::log(std::tan(0.5f * tg)), etaAbs = std::abs(eta);
2937 if (etaAbs > ETAEMCAL) {
2938 LOGP(
debug,
"eta = {} is off at EMCAL radius", eta, outTr.asString());
2942 if ((SECTORTYPE[sector] & SPHOS) && etaAbs < ETADCALPHOSSWITCH) {
2943 if (!propExactSector(XPHOS)) {
2946 r = std::sqrt(outTr.getX() * outTr.getX() + outTr.getY() * outTr.getY());
2947 tg = std::atan2(
r, outTr.getZ());
2948 eta = -std::log(std::tan(0.5f * tg));
2949 }
else if (!(SECTORTYPE[sector] & SEMCAL)) {
2952 extraInfoHolder.trackPhiEMCAL = outTr.getPhiPos();
2953 extraInfoHolder.trackEtaEMCAL = eta;
2954 LOGP(
debug,
"eta = {} phi = {} sector {} for {}", extraInfoHolder.trackEtaEMCAL, extraInfoHolder.trackPhiEMCAL, sector, outTr.asString());
2958std::set<uint64_t> AODProducerWorkflowDPL::filterEMCALIncomplete(
const gsl::span<const o2::emcal::TriggerRecord> triggers)
2960 std::set<uint64_t> emcalIncompletes;
2961 for (
const auto& trg : triggers) {
2962 if (trg.getTriggerBits() & o2::emcal::triggerbits::Inc) {
2964 emcalIncompletes.insert(trg.getBCData().toLong());
2967 return emcalIncompletes;
2973 static bool initOnceDone =
false;
2974 if (!initOnceDone) {
2975 initOnceDone =
true;
2982 for (
auto i = 0U;
i < bs.size();
i++) {
2997 mTPCBinNS = elParam.ZbinWidth * 1.e3;
3000 mNSigmaTimeTrack = pvParams.nSigmaTimeTrack;
3001 mTimeMarginTrackTime = pvParams.timeMarginTrackTime * 1.e3;
3022 LOG(info) <<
"ITS Alpide param updated";
3024 par.printKeyValues();
3028 LOG(info) <<
"MFT Alpide param updated";
3030 par.printKeyValues();
3041 mEMCALTrgClassMask = 0;
3042 for (
const auto& trgclass : ctpconfig.getCTPClasses()) {
3044 mEMCALTrgClassMask |= trgclass.classMask;
3047 LOG(info) <<
"Loaded EMCAL trigger class mask: " << std::bitset<64>(mEMCALTrgClassMask);
3051void AODProducerWorkflowDPL::addRefGlobalBCsForTOF(
const o2::dataformats::VtxTrackRef& trackRef,
const gsl::span<const GIndex>& GIndices,
3062 int nbitsFrac = 24 - (32 - o2::math_utils::popcount(mTrackTime));
3063 int nbitsLoss = std::max(0,
int(std::log2(TOFTimePrecPS)));
3064 assert(nbitsFrac > 1);
3065 std::uint64_t maxRangePS = std::uint64_t(0x1) << (nbitsFrac + nbitsLoss);
3067 LOG(info) <<
"Max gap of " << maxGapBC <<
" BCs to closest globalBC reference is needed for TOF tracks to provide precision of "
3068 << TOFTimePrecPS <<
" ps";
3071 if (!trackRef.getEntries()) {
3075 std::uint64_t maxBC = mStartIR.
toLong();
3076 const auto& tofClus =
data.getTOFClusters();
3083 for (
int ti =
start; ti <
end; ti++) {
3084 auto& trackIndex = GIndices[ti];
3085 const auto& tofMatch =
data.getTOFMatch(trackIndex);
3086 const auto& tofInt = tofMatch.getLTIntegralOut();
3087 float intLen = tofInt.getL();
3088 float tofExpMom = 0.;
3098 double massZ = o2::track::PID::getMass2Z(
data.getTrackParam(trackIndex).getPID());
3099 double energy = sqrt((massZ * massZ) + (tofExpMom * tofExpMom));
3100 double exp = intLen * energy / (cSpeed * tofExpMom);
3101 auto tofSignal = (tofMatch.getSignal() -
exp) * 1e-3;
3102 auto bc = relativeTime_to_GlobalBC(tofSignal);
3104 auto it = bcsMap.lower_bound(
bc);
3105 if (it == bcsMap.end() || it->first >
bc + maxGapBC) {
3106 bcsMap.emplace_hint(it,
bc, 1);
3115 if ((--bcsMap.end())->first <= maxBC) {
3116 bcsMap.emplace_hint(bcsMap.end(), maxBC + 1, 1);
3120 for (
auto& item : bcsMap) {
3126std::uint64_t AODProducerWorkflowDPL::fillBCSlice(
int (&slice)[2],
double tmin,
double tmax,
const std::map<uint64_t, int>& bcsMap)
const
3138 uint64_t bcMin = relativeTime_to_GlobalBC(tmin), bcMax = relativeTime_to_GlobalBC(tmax);
3161 auto upperindex =
p.first;
3162 while (upperindex < bcvector.size() && bcvector[upperindex] <= bcMax) {
3165 if (upperindex !=
p.first) {
3169 slice[1] = upperindex;
3171 auto bcOfTimeRef =
p.second - this->mStartIR.
toLong();
3172 LOG(
debug) <<
"BC slice t:" << tmin <<
" " << slice[0]
3173 <<
" t: " << tmax <<
" " << slice[1]
3174 <<
" bcref: " << bcOfTimeRef;
3180 std::vector<uint8_t>
flags(bcsMap.size());
3183 auto bcIt = bcsMap.begin();
3184 auto itsrofs =
data.getITSTracksROFRecords();
3187 for (
auto& rof : itsrofs) {
3188 if (!rof.getFlag(o2::itsmft::ROFRecord::VtxUPCMode)) {
3191 uint64_t globalBC0 = rof.getBCData().toLong() + bROF, globalBC1 = globalBC0 + lROF - 1;
3193 while (bcIt != bcsMap.end()) {
3194 if (bcIt->first < globalBC0) {
3198 if (bcIt->first > globalBC1) {
3210 LOGF(info,
"aod producer dpl total timing: Cpu: %.3e Real: %.3e s in %d slots",
3211 mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1);
3218 auto dataRequest = std::make_shared<DataRequest>();
3219 dataRequest->inputs.emplace_back(
"ctpconfig",
"CTP",
"CTPCONFIG", 0, Lifetime::Condition,
ccdbParamSpec(
"CTP/Config/Config", CTPConfigPerRun));
3221 dataRequest->requestTracks(
src, useMC);
3222 dataRequest->requestPrimaryVertices(useMC);
3224 dataRequest->requestCTPDigits(useMC);
3227 dataRequest->requestSecondaryVertices(useMC);
3229 if (enableStrangenessTracking) {
3230 dataRequest->requestStrangeTracks(useMC);
3231 LOGF(info,
"requestStrangeTracks Finish");
3240 dataRequest->requestTOFClusters(useMC);
3243 dataRequest->requestPHOSCells(useMC);
3246 dataRequest->requestTRDTracklets(
false);
3249 dataRequest->requestEMCALCells(useMC);
3252 dataRequest->requestCPVClusters(useMC);
3255 auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(
true,
3261 dataRequest->inputs,
3264 dataRequest->inputs.emplace_back(
"meanvtx",
"GLO",
"MEANVERTEX", 0, Lifetime::Condition,
ccdbParamSpec(
"GLO/Calib/MeanVertex", {}, 1));
3269 std::vector<OutputSpec> outputs{
3309 outputs.insert(outputs.end(),
3310 {OutputForTable<McCollisions>::spec(),
3311 OutputForTable<HepMCXSections>::spec(),
3312 OutputForTable<HepMCPdfInfos>::spec(),
3313 OutputForTable<HepMCHeavyIons>::spec(),
3314 OutputForTable<McMFTTrackLabels>::spec(),
3315 OutputForTable<McFwdTrackLabels>::spec(),
3316 OutputForTable<StoredMcParticles_001>::spec(),
3317 OutputForTable<McTrackLabels>::spec(),
3318 OutputForTable<McCaloLabels_001>::spec(),
3323 {OutputLabel{
"McCollisionLabels"},
"AOD",
"MCCOLLISIONLABEL", 0, Lifetime::Timeframe}});
3327 "aod-producer-workflow",
3330 AlgorithmSpec{adaptFromTask<AODProducerWorkflowDPL>(
src, dataRequest, ggRequest, enableSV, useMC, enableFITextra)},
3332 ConfigParamSpec{
"run-number", VariantType::Int64, -1L, {
"The run-number. If left default we try to get it from DPL header."}},
3333 ConfigParamSpec{
"aod-timeframe-id", VariantType::Int64, -1L, {
"Set timeframe number"}},
3334 ConfigParamSpec{
"fill-calo-cells", VariantType::Int, 1, {
"Fill calo cells into cell table"}},
3335 ConfigParamSpec{
"enable-truncation", VariantType::Int, 1, {
"Truncation parameter: 1 -- on, != 1 -- off"}},
3336 ConfigParamSpec{
"lpmp-prod-tag", VariantType::String,
"", {
"LPMProductionTag"}},
3337 ConfigParamSpec{
"anchor-pass", VariantType::String,
"", {
"AnchorPassName"}},
3338 ConfigParamSpec{
"anchor-prod", VariantType::String,
"", {
"AnchorProduction"}},
3339 ConfigParamSpec{
"reco-pass", VariantType::String,
"", {
"RecoPassName"}},
3340 ConfigParamSpec{
"created-by", VariantType::String,
"", {
"Who created this AO2D"}},
3341 ConfigParamSpec{
"nthreads", VariantType::Int, std::max(1,
int(std::thread::hardware_concurrency() / 2)), {
"Number of threads"}},
3342 ConfigParamSpec{
"reco-mctracks-only", VariantType::Int, 0, {
"Store only reconstructed MC tracks and their mothers/daughters. 0 -- off, != 0 -- on"}},
3343 ConfigParamSpec{
"ctpreadout-create", VariantType::Int, 0, {
"Create CTP digits from detector readout and CTP inputs. !=1 -- off, 1 -- on"}},
3344 ConfigParamSpec{
"emc-select-leading", VariantType::Bool,
false, {
"Flag to select if only the leading contributing particle for an EMCal cell should be stored"}},
3345 ConfigParamSpec{
"propagate-tracks", VariantType::Bool,
false, {
"Propagate tracks (not used for secondary vertices) to IP"}},
3346 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)"}},
3347 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)"}},
3348 ConfigParamSpec{
"propagate-muons", VariantType::Bool,
false, {
"Propagate muons to IP"}},
3349 ConfigParamSpec{
"thin-tracks", VariantType::Bool,
false, {
"Produce thinned track tables"}},
3350 ConfigParamSpec{
"trackqc-fraction", VariantType::Float, float(0.1), {
"Fraction of tracks to QC"}},
3351 ConfigParamSpec{
"trackqc-NTrCut", VariantType::Int64, 4L, {
"Minimal length of the track - in amount of tracklets"}},
3352 ConfigParamSpec{
"trackqc-tpc-dca", VariantType::Float, 3.f, {
"Keep TPC standalone track with this DCAxy to the PV"}},
3353 ConfigParamSpec{
"trackqc-tpc-cls", VariantType::Int, 80, {
"Keep TPC standalone track with this #clusters"}},
3354 ConfigParamSpec{
"trackqc-tpc-pt", VariantType::Float, 0.2f, {
"Keep TPC standalone track with this pt"}},
3355 ConfigParamSpec{
"with-streamers", VariantType::String,
"", {
"Bit-mask to steer writing of intermediate streamer files"}},
3356 ConfigParamSpec{
"seed", VariantType::Int, 0, {
"Set seed for random generator used for sampling (0 (default) means using a random_device)"}},
3357 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=2)
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 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