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;
1073template <
typename MCTrackLabelCursorType,
typename MCMFTTrackLabelCursorType,
typename MCFwdTrackLabelCursorType>
1074void AODProducerWorkflowDPL::fillMCTrackLabelsTable(MCTrackLabelCursorType& mcTrackLabelCursor,
1075 MCMFTTrackLabelCursorType& mcMFTTrackLabelCursor,
1076 MCFwdTrackLabelCursorType& mcFwdTrackLabelCursor,
1078 const gsl::span<const GIndex>& primVerGIs,
1091 mcMFTTrackLabelCursor.reserve(
end -
start + mcMFTTrackLabelCursor.lastIndex());
1092 mcFwdTrackLabelCursor.reserve(
end -
start + mcFwdTrackLabelCursor.lastIndex());
1093 mcTrackLabelCursor.reserve(
end -
start + mcTrackLabelCursor.lastIndex());
1094 for (
int ti =
start; ti <
end; ti++) {
1095 const auto trackIndex = primVerGIs[ti];
1098 auto needToStore = [trackIndex](std::unordered_map<GIndex, int>& mp) {
1099 auto entry = mp.find(trackIndex);
1100 if (
entry == mp.end() ||
entry->second == -1) {
1107 if (GIndex::includesSource(
src, mInputSources)) {
1108 auto mcTruth =
data.getTrackMCLabel(trackIndex);
1109 MCLabels labelHolder{};
1114 if (mcTruth.isValid()) {
1115 labelHolder.labelID = (mToStore[mcTruth.getSourceID()][mcTruth.getEventID()])[mcTruth.getTrackID()];
1117 if (mcTruth.isFake()) {
1118 labelHolder.fwdLabelMask |= (0x1 << 7);
1120 if (mcTruth.isNoise()) {
1121 labelHolder.fwdLabelMask |= (0x1 << 6);
1124 mcMFTTrackLabelCursor(labelHolder.labelID,
1125 labelHolder.fwdLabelMask);
1127 mcFwdTrackLabelCursor(labelHolder.labelID,
1128 labelHolder.fwdLabelMask);
1131 if (!needToStore(mGIDToTableID)) {
1134 if (mcTruth.isValid()) {
1135 labelHolder.labelID = (mToStore[mcTruth.getSourceID()][mcTruth.getEventID()])[mcTruth.getTrackID()];
1136 if (mcTruth.isFake()) {
1137 labelHolder.labelMask |= (0x1 << 15);
1140 auto contributorsGID =
data.getSingleDetectorRefs(trackIndex);
1143 labelHolder.labelMask |= (0x1 << 13);
1148 auto itsGID =
data.getITSContributorGID(trackIndex);
1149 auto itsSource = itsGID.getSource();
1151 auto& itsTrack =
data.getITSTrack(itsGID);
1152 for (
unsigned int iL = 0; iL < 7; ++iL) {
1153 if (itsTrack.isFakeOnLayer(iL)) {
1154 labelHolder.labelMask |= (0x1 << iL);
1158 labelHolder.labelMask |= (
data.getTrackMCLabel(itsGID).isFake() << 12);
1162 }
else if (mcTruth.isNoise()) {
1163 labelHolder.labelMask |= (0x1 << 14);
1165 mcTrackLabelCursor(labelHolder.labelID, labelHolder.labelMask);
1172 auto sTrackLabels =
data.getStrangeTracksMCLabels();
1174 if (!(vertexId < 0 || vertexId >= mVertexStrLUT.size() - 1)) {
1175 mcTrackLabelCursor.reserve(mVertexStrLUT[vertexId + 1] + mcTrackLabelCursor.lastIndex());
1176 for (
int iS{mVertexStrLUT[vertexId]}; iS < mVertexStrLUT[vertexId + 1]; ++iS) {
1177 auto& collStrTrk = mCollisionStrTrk[iS];
1178 auto&
label = sTrackLabels[collStrTrk.second];
1179 MCLabels labelHolder;
1180 labelHolder.labelID =
label.isValid() ? (mToStore[
label.getSourceID()][
label.getEventID()])[
label.getTrackID()] : -1;
1181 labelHolder.labelMask = (
label.isFake() << 15) | (
label.isNoise() << 14);
1182 mcTrackLabelCursor(labelHolder.labelID, labelHolder.labelMask);
1187template <
typename V0CursorType,
typename CascadeCursorType,
typename Decay3BodyCursorType>
1188void AODProducerWorkflowDPL::fillSecondaryVertices(
const o2::globaltracking::RecoContainer& recoData, V0CursorType& v0Cursor, CascadeCursorType& cascadeCursor, Decay3BodyCursorType& decay3BodyCursor)
1195 v0Cursor.reserve(v0s.size());
1197 for (
size_t iv0 = 0; iv0 < v0s.size(); iv0++) {
1198 const auto&
v0 = v0s[iv0];
1199 auto trPosID =
v0.getProngID(0);
1200 auto trNegID =
v0.getProngID(1);
1201 uint8_t v0flags =
v0.getBits();
1202 int posTableIdx = -1, negTableIdx = -1, collID = -1;
1203 auto item = mGIDToTableID.find(trPosID);
1204 if (item != mGIDToTableID.end()) {
1205 posTableIdx = item->second;
1207 LOG(warn) <<
"Could not find a positive track index for prong ID " << trPosID;
1209 item = mGIDToTableID.find(trNegID);
1210 if (item != mGIDToTableID.end()) {
1211 negTableIdx = item->second;
1213 LOG(warn) <<
"Could not find a negative track index for prong ID " << trNegID;
1215 auto itemV = mVtxToTableCollID.find(
v0.getVertexID());
1216 if (itemV == mVtxToTableCollID.end()) {
1217 LOG(warn) <<
"Could not find V0 collisionID for the vertex ID " <<
v0.getVertexID();
1219 collID = itemV->second;
1221 if (posTableIdx != -1 and negTableIdx != -1 and collID != -1) {
1222 v0Cursor(collID, posTableIdx, negTableIdx, v0flags);
1223 mV0ToTableID[
int(iv0)] = mTableV0ID++;
1228 cascadeCursor.reserve(cascades.size());
1229 for (
auto& cascade : cascades) {
1230 auto itemV0 = mV0ToTableID.find(cascade.getV0ID());
1231 if (itemV0 == mV0ToTableID.end()) {
1234 int v0tableID = itemV0->second, bachTableIdx = -1, collID = -1;
1235 auto bachelorID = cascade.getBachelorID();
1236 auto item = mGIDToTableID.find(bachelorID);
1237 if (item != mGIDToTableID.end()) {
1238 bachTableIdx = item->second;
1240 LOG(warn) <<
"Could not find a bachelor track index";
1243 auto itemV = mVtxToTableCollID.find(cascade.getVertexID());
1244 if (itemV != mVtxToTableCollID.end()) {
1245 collID = itemV->second;
1247 LOG(warn) <<
"Could not find cascade collisionID for the vertex ID " << cascade.getVertexID();
1250 cascadeCursor(collID, v0tableID, bachTableIdx);
1254 decay3BodyCursor.reserve(decays3Body.size());
1255 for (
size_t i3Body = 0; i3Body < decays3Body.size(); i3Body++) {
1256 const auto& decay3Body = decays3Body[i3Body];
1258 decay3Body.getProngID(0),
1259 decay3Body.getProngID(1),
1260 decay3Body.getProngID(2)};
1261 int tableIdx[3]{-1, -1, -1}, collID = -1;
1262 bool missing{
false};
1263 for (
int i{0};
i < 3; ++
i) {
1264 auto item = mGIDToTableID.find(trIDs[
i]);
1265 if (item != mGIDToTableID.end()) {
1266 tableIdx[
i] = item->second;
1268 LOG(warn) << fmt::format(
"Could not find a track index for prong ID {}", (
int)trIDs[
i]);
1272 auto itemV = mVtxToTableCollID.find(decay3Body.getVertexID());
1273 if (itemV == mVtxToTableCollID.end()) {
1274 LOG(warn) <<
"Could not find 3 body collisionID for the vertex ID " << decay3Body.getVertexID();
1277 collID = itemV->second;
1282 decay3BodyCursor(collID, tableIdx[0], tableIdx[1], tableIdx[2]);
1286template <
typename FwdTrkClsCursorType>
1293 int mchTrackID = -1;
1295 mchTrackID = trackID.getIndex();
1297 auto mchmidMatch = mchmidMatches[trackID.getIndex()];
1298 mchTrackID = mchmidMatch.getMCHRef().getIndex();
1301 if (mchTrackID > -1 && mchTrackID < mchTracks.size()) {
1302 const auto& mchTrack = mchTracks[mchTrackID];
1303 fwdTrkClsCursor.reserve(mchTrack.getNClusters() + fwdTrkClsCursor.lastIndex());
1304 int first = mchTrack.getFirstClusterIdx();
1305 int last = mchTrack.getLastClusterIdx();
1306 for (
int i =
first;
i <= last;
i++) {
1307 const auto& cluster = mchClusters[
i];
1308 fwdTrkClsCursor(fwdTrackId,
1309 truncateFloatFraction(cluster.x, mMuonCl),
1310 truncateFloatFraction(cluster.y, mMuonCl),
1311 truncateFloatFraction(cluster.z, mMuonCl),
1312 (((cluster.ey < 5.) & 0x1) << 12) | (((cluster.ex < 5.) & 0x1) << 11) | cluster.getDEId());
1317template <
typename HMPCursorType>
1322 hmpCursor.reserve(hmpMatches.size());
1325 for (
size_t iHmp = 0; iHmp < hmpMatches.size(); iHmp++) {
1327 const auto&
match = hmpMatches[iHmp];
1329 float xTrk, yTrk, theta,
phi;
1333 match.getHMPIDtrk(xTrk, yTrk, theta,
phi);
1336 auto photChargeVec =
match.getPhotCharge();
1338 float photChargeVec2[10];
1340 for (Int_t
i = 0;
i < 10;
i++) {
1341 photChargeVec2[
i] = photChargeVec[
i];
1343 auto tref = mGIDToTableID.find(
match.getTrackRef());
1344 if (tref != mGIDToTableID.end()) {
1345 hmpCursor(tref->second,
match.getHMPsignal(), xTrk, yTrk, xMip, yMip, nph,
charge,
match.getIdxHMPClus(),
match.getHmpMom(), photChargeVec2);
1347 LOG(error) <<
"Could not find AOD track table entry for HMP-matched track " <<
match.getTrackRef().asString();
1359 mCollisionStrTrk.clear();
1361 mVertexStrLUT.clear();
1363 for (
auto& sTrk : recoData.getStrangeTracks()) {
1367 vtxId = v0s[sTrk.mDecayRef].getVertexID();
1369 vtxId = cascades[sTrk.mDecayRef].getVertexID();
1371 vtxId = decays3Body[sTrk.mDecayRef].getVertexID();
1373 mCollisionStrTrk.emplace_back(vtxId, sTrkID++);
1374 mVertexStrLUT[vtxId]++;
1376 std::exclusive_scan(mVertexStrLUT.begin(), mVertexStrLUT.end(), mVertexStrLUT.begin(), 0);
1379 std::sort(mCollisionStrTrk.begin(), mCollisionStrTrk.end(), [](
const auto&
a,
const auto&
b) { return a.first < b.first; });
1380 mStrTrkIndices.clear();
1381 mStrTrkIndices.resize(mCollisionStrTrk.size(), -1);
1384template <
typename V0C,
typename CC,
typename D3BC>
1387 int itsTableIdx = -1;
1393 for (
const auto& sTrk : recoData.getStrangeTracks()) {
1403 v0Curs.reserve(nV0);
1404 cascCurs.reserve(nCasc);
1405 d3BodyCurs.reserve(nD3Body);
1407 for (
const auto& sTrk : recoData.getStrangeTracks()) {
1409 auto item = mGIDToTableID.find(ITSIndex);
1410 if (item != mGIDToTableID.end()) {
1411 itsTableIdx = item->second;
1413 LOG(warn) <<
"Could not find a ITS strange track index " << ITSIndex;
1417 v0Curs(mStrTrkIndices[sTrkID++],
1427 sTrk.getAverageClusterSize());
1429 cascCurs(mStrTrkIndices[sTrkID++],
1439 sTrk.getAverageClusterSize());
1441 d3BodyCurs(mStrTrkIndices[sTrkID++],
1451 sTrk.getAverageClusterSize());
1458 const auto& tpcTracks =
data.getTPCTracks();
1459 const auto& tpcClusRefs =
data.getTPCTracksClusterRefs();
1460 const auto& tpcClusShMap =
data.clusterShMapTPC;
1461 const auto& tpcClusAcc =
data.getTPCClusters();
1462 constexpr int maxRows = 152;
1463 constexpr int neighbour = 2;
1464 int ntr = tpcTracks.size();
1465 mTPCCounters.clear();
1466 mTPCCounters.resize(ntr);
1468 int ngroup = std::min(50, std::max(1, ntr / mNThreads));
1469#pragma omp parallel for schedule(dynamic, ngroup) num_threads(mNThreads)
1471 for (
int itr = 0; itr < ntr; itr++) {
1472 std::array<bool, maxRows> clMap{}, shMap{};
1473 uint8_t sectorIndex, rowIndex;
1474 uint32_t clusterIndex;
1475 auto&
counters = mTPCCounters[itr];
1476 const auto& track = tpcTracks[itr];
1477 for (
int i = 0;
i < track.getNClusterReferences();
i++) {
1478 o2::tpc::TrackTPC::getClusterReference(tpcClusRefs,
i, sectorIndex, rowIndex, clusterIndex, track.getClusterRef());
1479 unsigned int absoluteIndex = tpcClusAcc.clusterOffset[sectorIndex][rowIndex] + clusterIndex;
1480 clMap[rowIndex] =
true;
1482 if (!shMap[rowIndex]) {
1485 shMap[rowIndex] =
true;
1489 for (
int i = 0;
i < maxRows;
i++) {
1494 }
else if ((
i - last) <= neighbour) {
1497 int lim = std::min(
i + 1 + neighbour, maxRows);
1498 for (
int j =
i + 1;
j < lim;
j++) {
1513 if (track.getTrackletIndex(il) != -1) {
1517 if (track.getHasNeighbor()) {
1520 if (track.getHasPadrowCrossing()) {
1526template <
typename TCaloHandler,
typename TCaloCursor,
typename TCaloTRGCursor,
typename TMCCaloLabelCursor>
1527void AODProducerWorkflowDPL::addToCaloTable(TCaloHandler& caloHandler, TCaloCursor& caloCellCursor, TCaloTRGCursor& caloTRGCursor,
1528 TMCCaloLabelCursor& mcCaloCellLabelCursor,
int eventID,
int bcID, int8_t caloType)
1530 auto inputEvent = caloHandler.buildEvent(eventID);
1531 auto cellsInEvent = inputEvent.mCells;
1532 auto cellMClabels = inputEvent.mMCCellLabels;
1533 caloCellCursor.reserve(cellsInEvent.size() + caloCellCursor.lastIndex());
1534 caloTRGCursor.reserve(cellsInEvent.size() + caloTRGCursor.lastIndex());
1536 mcCaloCellLabelCursor.reserve(cellsInEvent.size() + mcCaloCellLabelCursor.lastIndex());
1538 for (
auto iCell = 0U; iCell < cellsInEvent.size(); iCell++) {
1539 caloCellCursor(bcID,
1543 cellsInEvent[iCell].
getType(),
1557 std::vector<int32_t> particleIds;
1558 std::vector<float> amplitudeFraction;
1559 if (!mEMCselectLeading) {
1560 particleIds.reserve(cellMClabels.size());
1561 amplitudeFraction.reserve(cellMClabels.size());
1563 float tmpMaxAmplitude = 0;
1564 int32_t tmpindex = 0;
1565 for (
auto& mclabel : cellMClabels[iCell]) {
1567 if (mclabel.isValid()) {
1568 if (mEMCselectLeading) {
1569 if (mclabel.getAmplitudeFraction() > tmpMaxAmplitude) {
1571 if (mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID()).find(mclabel.getTrackID()) !=
1572 mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID()).end()) {
1573 tmpMaxAmplitude = mclabel.getAmplitudeFraction();
1574 tmpindex = (mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID())).at(mclabel.getTrackID());
1578 auto trackStore = mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID());
1579 auto iter = trackStore.find(mclabel.getTrackID());
1580 if (iter != trackStore.end()) {
1581 amplitudeFraction.emplace_back(mclabel.getAmplitudeFraction());
1582 particleIds.emplace_back(iter->second);
1584 particleIds.emplace_back(-1);
1585 amplitudeFraction.emplace_back(0.f);
1586 LOG(warn) <<
"CaloTable: Could not find track for mclabel (" << mclabel.getSourceID() <<
"," << mclabel.getEventID() <<
"," << mclabel.getTrackID() <<
") in the AOD MC store";
1587 if (mMCKineReader) {
1588 auto mctrack = mMCKineReader->
getTrack(mclabel);
1591 LOG(warn) <<
" ... this track is of PDG " << mctrack->GetPdgCode() <<
" produced by " << mctrack->getProdProcessAsString() <<
" at (" <<
vec.X() <<
"," <<
vec.Y() <<
"," <<
vec.Z() <<
")";
1597 if (mEMCselectLeading) {
1598 amplitudeFraction.emplace_back(tmpMaxAmplitude);
1599 particleIds.emplace_back(tmpindex);
1601 if (particleIds.size() == 0) {
1602 particleIds.emplace_back(-1);
1603 amplitudeFraction.emplace_back(0.f);
1605 mcCaloCellLabelCursor(particleIds,
1612template <
typename TCaloCursor,
typename TCaloTRGCursor,
typename TMCCaloLabelCursor>
1613void AODProducerWorkflowDPL::fillCaloTable(TCaloCursor& caloCellCursor, TCaloTRGCursor& caloTRGCursor,
1614 TMCCaloLabelCursor& mcCaloCellLabelCursor,
const std::map<uint64_t, int>& bcsMap,
1618 auto caloEMCCells =
data.getEMCALCells();
1619 auto caloEMCCellsTRGR =
data.getEMCALTriggers();
1620 auto mcCaloEMCCellLabels =
data.getEMCALCellsMCLabels();
1622 auto caloPHOSCells =
data.getPHOSCells();
1623 auto caloPHOSCellsTRGR =
data.getPHOSTriggers();
1624 auto mcCaloPHOSCellLabels =
data.getPHOSCellsMCLabels();
1628 caloPHOSCellsTRGR = {};
1629 mcCaloPHOSCellLabels = {};
1634 caloEMCCellsTRGR = {};
1635 mcCaloEMCCellLabels = {};
1642 emcEventHandler.
reset();
1643 emcEventHandler.
setCellData(caloEMCCells, caloEMCCellsTRGR);
1646 phsEventHandler.
reset();
1647 phsEventHandler.
setCellData(caloPHOSCells, caloPHOSCellsTRGR);
1653 std::vector<std::tuple<uint64_t, int8_t, int>> caloEvents;
1655 caloEvents.reserve(emcNEvents + phsNEvents);
1657 for (
int iev = 0; iev < emcNEvents; ++iev) {
1659 caloEvents.emplace_back(std::make_tuple(
bc, 1, iev));
1662 for (
int iev = 0; iev < phsNEvents; ++iev) {
1664 caloEvents.emplace_back(std::make_tuple(
bc, 0, iev));
1667 std::sort(caloEvents.begin(), caloEvents.end(),
1668 [](
const auto&
left,
const auto&
right) { return std::get<0>(left) < std::get<0>(right); });
1671 for (
int i = 0;
i < emcNEvents + phsNEvents; ++
i) {
1672 uint64_t globalBC = std::get<0>(caloEvents[
i]);
1673 int8_t caloType = std::get<1>(caloEvents[
i]);
1674 int eventID = std::get<2>(caloEvents[
i]);
1675 auto item = bcsMap.find(globalBC);
1677 if (item != bcsMap.end()) {
1678 bcID = item->second;
1680 LOG(warn) <<
"Error: could not find a corresponding BC ID for a calo point; globalBC = " << globalBC <<
", caloType = " << (
int)caloType;
1682 if (caloType == 0) {
1683 addToCaloTable(phsEventHandler, caloCellCursor, caloTRGCursor, mcCaloCellLabelCursor, eventID, bcID, caloType);
1685 if (caloType == 1) {
1686 addToCaloTable(emcEventHandler, caloCellCursor, caloTRGCursor, mcCaloCellLabelCursor, eventID, bcID, caloType);
1697 mLPMProdTag = ic.
options().
get<std::string>(
"lpmp-prod-tag");
1698 mAnchorPass = ic.
options().
get<std::string>(
"anchor-pass");
1699 mAnchorProd = ic.
options().
get<std::string>(
"anchor-prod");
1700 mUser = ic.
options().
get<std::string>(
"created-by");
1701 mRecoPass = ic.
options().
get<std::string>(
"reco-pass");
1702 mTFNumber = ic.
options().
get<int64_t>(
"aod-timeframe-id");
1703 mRecoOnly = ic.
options().
get<
int>(
"reco-mctracks-only");
1704 mTruncate = ic.
options().
get<
int>(
"enable-truncation");
1705 mRunNumber = ic.
options().
get<
int>(
"run-number");
1706 mCTPReadout = ic.
options().
get<
int>(
"ctpreadout-create");
1707 mNThreads = std::max(1, ic.
options().
get<
int>(
"nthreads"));
1708 mEMCselectLeading = ic.
options().
get<
bool>(
"emc-select-leading");
1709 mThinTracks = ic.
options().
get<
bool>(
"thin-tracks");
1710 mPropTracks = ic.
options().
get<
bool>(
"propagate-tracks");
1711 mMaxPropXiu = ic.
options().
get<
float>(
"propagate-tracks-max-xiu");
1712 mPropMuons = ic.
options().
get<
bool>(
"propagate-muons");
1713 if (
auto s = ic.
options().
get<std::string>(
"with-streamers"); !
s.empty()) {
1714 mStreamerFlags.
set(
s);
1715 if (mStreamerFlags) {
1716 LOGP(info,
"Writing streamer data with mask:");
1717 LOG(info) << mStreamerFlags;
1719 LOGP(warn,
"Specified non-default empty streamer mask!");
1722 mTrackQCFraction = ic.
options().
get<
float>(
"trackqc-fraction");
1723 mTrackQCNTrCut = ic.
options().
get<int64_t>(
"trackqc-NTrCut");
1724 mTrackQCDCAxy = ic.
options().
get<
float>(
"trackqc-tpc-dca");
1725 mTrackQCPt = ic.
options().
get<
float>(
"trackqc-tpc-pt");
1726 mTrackQCNCls = ic.
options().
get<
int>(
"trackqc-tpc-cls");
1727 if (
auto seed = ic.
options().
get<
int>(
"seed"); seed == 0) {
1728 LOGP(info,
"Using random device for seeding");
1729 std::random_device
rd;
1730 std::array<int, std::mt19937::state_size> seed_data{};
1731 std::generate(std::begin(seed_data), std::end(seed_data), std::ref(
rd));
1732 std::seed_seq seq(std::begin(seed_data), std::end(seed_data));
1733 mGenerator = std::mt19937(seq);
1735 LOGP(info,
"Using seed {} for sampling", seed);
1736 mGenerator.seed(seed);
1739 LOGP(info,
"Multi-threaded parts will run with {} OpenMP threads", mNThreads);
1742 LOG(info) <<
"OpenMP is disabled";
1744 if (mTFNumber == -1L) {
1745 LOG(info) <<
"TFNumber will be obtained from CCDB";
1747 if (mRunNumber == -1L) {
1748 LOG(info) <<
"The Run number will be obtained from DPL headers";
1751 mUseSigFiltMC = ic.
options().
get<
bool>(
"mc-signal-filt");
1754 if (mTruncate != 1) {
1755 LOG(info) <<
"Truncation is not used!";
1756 mCollisionPosition = 0xFFFFFFFF;
1757 mCollisionPositionCov = 0xFFFFFFFF;
1758 mTrackX = 0xFFFFFFFF;
1759 mTrackAlpha = 0xFFFFFFFF;
1760 mTrackSnp = 0xFFFFFFFF;
1761 mTrackTgl = 0xFFFFFFFF;
1762 mTrack1Pt = 0xFFFFFFFF;
1763 mTrackChi2 = 0xFFFFFFFF;
1764 mTrackCovDiag = 0xFFFFFFFF;
1765 mTrackCovOffDiag = 0xFFFFFFFF;
1766 mTrackSignal = 0xFFFFFFFF;
1767 mTrackTime = 0xFFFFFFFF;
1768 mTPCTime0 = 0xFFFFFFFF;
1769 mTrackTimeError = 0xFFFFFFFF;
1770 mTrackPosEMCAL = 0xFFFFFFFF;
1771 mTracklets = 0xFFFFFFFF;
1772 mMcParticleW = 0xFFFFFFFF;
1773 mMcParticlePos = 0xFFFFFFFF;
1774 mMcParticleMom = 0xFFFFFFFF;
1775 mCaloAmp = 0xFFFFFFFF;
1776 mCaloTime = 0xFFFFFFFF;
1777 mCPVPos = 0xFFFFFFFF;
1778 mCPVAmpl = 0xFFFFFFFF;
1779 mMuonTr1P = 0xFFFFFFFF;
1780 mMuonTrThetaX = 0xFFFFFFFF;
1781 mMuonTrThetaY = 0xFFFFFFFF;
1782 mMuonTrZmu = 0xFFFFFFFF;
1783 mMuonTrBend = 0xFFFFFFFF;
1784 mMuonTrNonBend = 0xFFFFFFFF;
1785 mMuonTrCov = 0xFFFFFFFF;
1786 mMuonCl = 0xFFFFFFFF;
1787 mMuonClErr = 0xFFFFFFFF;
1788 mV0Time = 0xFFFFFFFF;
1789 mV0ChannelTime = 0xFFFFFFFF;
1790 mFDDTime = 0xFFFFFFFF;
1791 mFDDChannelTime = 0xFFFFFFFF;
1792 mT0Time = 0xFFFFFFFF;
1793 mT0ChannelTime = 0xFFFFFFFF;
1794 mV0Amplitude = 0xFFFFFFFF;
1795 mFDDAmplitude = 0xFFFFFFFF;
1796 mT0Amplitude = 0xFFFFFFFF;
1800 mZDCEnergyMap[ic] = -std::numeric_limits<float>::infinity();
1803 mZDCTDCMap[ic] = -std::numeric_limits<float>::infinity();
1806 std::string hepmcUpdate = ic.
options().
get<std::string>(
"hepmc-update");
1807 HepMCUpdate when = (hepmcUpdate ==
"never" ? HepMCUpdate::never : hepmcUpdate ==
"always" ? HepMCUpdate::always
1808 : hepmcUpdate ==
"all" ? HepMCUpdate::allKeys
1809 : HepMCUpdate::anyKey);
1810 mXSectionUpdate = when;
1811 mPdfInfoUpdate = when;
1812 mHeavyIonUpdate = when;
1816 if (mStreamerFlags) {
1817 mStreamer = std::make_unique<o2::utils::TreeStreamRedirector>(
"AO2DStreamer.root",
"RECREATE");
1823void add_additional_meta_info(std::vector<TString>& keys, std::vector<TString>&
values)
1826 auto aod_external_meta_info_file = getenv(
"AOD_ADDITIONAL_METADATA_FILE");
1827 if (aod_external_meta_info_file !=
nullptr) {
1828 LOG(info) <<
"Trying to inject additional AOD meta-data from " << aod_external_meta_info_file;
1829 if (std::filesystem::exists(aod_external_meta_info_file)) {
1830 std::ifstream input_file(aod_external_meta_info_file);
1832 nlohmann::json json_data;
1834 input_file >> json_data;
1835 }
catch (nlohmann::json::parse_error& e) {
1836 std::cerr <<
"JSON Parse Error: " << e.what() <<
"\n";
1837 std::cerr <<
"Exception ID: " << e.id <<
"\n";
1838 std::cerr <<
"Byte position: " << e.byte <<
"\n";
1842 for (
const auto& [
key,
value] : json_data.items()) {
1843 LOG(info) <<
"Adding AOD MetaData" <<
key <<
" : " <<
value;
1844 keys.push_back(
key.c_str());
1855 mTimer.Start(
false);
1858 updateTimeDependentParams(pc);
1883 std::vector<o2::ctp::CTPDigit> ctpDigitsCreated;
1884 if (mCTPReadout == 1) {
1885 LOG(info) <<
"CTP : creating ctpreadout in AOD producer";
1886 createCTPReadout(recoData, ctpDigitsCreated, pc);
1887 LOG(info) <<
"CTP : ctpreadout created from AOD";
1888 ctpDigits = gsl::span<o2::ctp::CTPDigit>(ctpDigitsCreated);
1890 LOG(
debug) <<
"FOUND " << primVertices.size() <<
" primary vertices";
1891 LOG(
debug) <<
"FOUND " << ft0RecPoints.size() <<
" FT0 rec. points";
1892 LOG(
debug) <<
"FOUND " << fv0RecPoints.size() <<
" FV0 rec. points";
1893 LOG(
debug) <<
"FOUND " << fddRecPoints.size() <<
" FDD rec. points";
1894 LOG(
debug) <<
"FOUND " << cpvClusters.size() <<
" CPV clusters";
1895 LOG(
debug) <<
"FOUND " << cpvTrigRecs.size() <<
" CPV trigger records";
1897 LOG(info) <<
"FOUND " << primVertices.size() <<
" primary vertices";
1901 auto bcCursor = createTableCursor<o2::aod::BCs>(pc);
1902 auto bcFlagsCursor = createTableCursor<o2::aod::BCFlags>(pc);
1903 auto cascadesCursor = createTableCursor<o2::aod::Cascades>(pc);
1904 auto collisionsCursor = createTableCursor<o2::aod::Collisions>(pc);
1905 auto decay3BodyCursor = createTableCursor<o2::aod::Decay3Bodys>(pc);
1906 auto trackedCascadeCursor = createTableCursor<o2::aod::TrackedCascades>(pc);
1907 auto trackedV0Cursor = createTableCursor<o2::aod::TrackedV0s>(pc);
1908 auto tracked3BodyCurs = createTableCursor<o2::aod::Tracked3Bodys>(pc);
1909 auto fddCursor = createTableCursor<o2::aod::FDDs>(pc);
1910 auto fddExtraCursor = createTableCursor<o2::aod::FDDsExtra>(pc);
1911 auto ft0Cursor = createTableCursor<o2::aod::FT0s>(pc);
1912 auto ft0ExtraCursor = createTableCursor<o2::aod::FT0sExtra>(pc);
1913 auto fv0aCursor = createTableCursor<o2::aod::FV0As>(pc);
1914 auto fv0aExtraCursor = createTableCursor<o2::aod::FV0AsExtra>(pc);
1915 auto fwdTracksCursor = createTableCursor<o2::aod::StoredFwdTracks>(pc);
1916 auto fwdTracksCovCursor = createTableCursor<o2::aod::StoredFwdTracksCov>(pc);
1917 auto fwdTrkClsCursor = createTableCursor<o2::aod::FwdTrkCls>(pc);
1918 auto mftTracksCursor = createTableCursor<o2::aod::StoredMFTTracks>(pc);
1919 auto mftTracksCovCursor = createTableCursor<o2::aod::StoredMFTTracksCov>(pc);
1920 auto tracksCursor = createTableCursor<o2::aod::StoredTracksIU>(pc);
1921 auto tracksCovCursor = createTableCursor<o2::aod::StoredTracksCovIU>(pc);
1922 auto tracksExtraCursor = createTableCursor<o2::aod::StoredTracksExtra>(pc);
1923 auto tracksQACursor = createTableCursor<o2::aod::TracksQAVersion>(pc);
1924 auto ambigTracksCursor = createTableCursor<o2::aod::AmbiguousTracks>(pc);
1925 auto ambigMFTTracksCursor = createTableCursor<o2::aod::AmbiguousMFTTracks>(pc);
1926 auto ambigFwdTracksCursor = createTableCursor<o2::aod::AmbiguousFwdTracks>(pc);
1927 auto v0sCursor = createTableCursor<o2::aod::V0s>(pc);
1928 auto zdcCursor = createTableCursor<o2::aod::Zdcs>(pc);
1929 auto hmpCursor = createTableCursor<o2::aod::HMPIDs>(pc);
1930 auto caloCellsCursor = createTableCursor<o2::aod::Calos>(pc);
1931 auto caloCellsTRGTableCursor = createTableCursor<o2::aod::CaloTriggers>(pc);
1932 auto cpvClustersCursor = createTableCursor<o2::aod::CPVClusters>(pc);
1933 auto originCursor = createTableCursor<o2::aod::Origins>(pc);
1947 mcColLabelsCursor = createTableCursor<o2::aod::McCollisionLabels>(pc);
1948 mcCollisionsCursor = createTableCursor<o2::aod::McCollisions>(pc);
1949 hepmcXSectionsCursor = createTableCursor<o2::aod::HepMCXSections>(pc);
1950 hepmcPdfInfosCursor = createTableCursor<o2::aod::HepMCPdfInfos>(pc);
1951 hepmcHeavyIonsCursor = createTableCursor<o2::aod::HepMCHeavyIons>(pc);
1952 mcMFTTrackLabelCursor = createTableCursor<o2::aod::McMFTTrackLabels>(pc);
1953 mcFwdTrackLabelCursor = createTableCursor<o2::aod::McFwdTrackLabels>(pc);
1954 mcParticlesCursor = createTableCursor<o2::aod::StoredMcParticles_001>(pc);
1955 mcTrackLabelCursor = createTableCursor<o2::aod::McTrackLabels>(pc);
1956 mcCaloLabelsCursor = createTableCursor<o2::aod::McCaloLabels_001>(pc);
1959 std::unique_ptr<o2::steer::MCKinematicsReader> mcReader;
1961 mcReader = std::make_unique<o2::steer::MCKinematicsReader>(
"collisioncontext.root");
1963 mMCKineReader = mcReader.get();
1964 std::map<uint64_t, int> bcsMap;
1965 collectBCs(recoData, mUseMC ? mcReader->getDigitizationContext()->getEventRecords() : std::vector<o2::InteractionTimeRecord>{}, bcsMap);
1966 if (!primVer2TRefs.empty()) {
1967 addRefGlobalBCsForTOF(primVer2TRefs.back(), primVerGIs, recoData, bcsMap);
1970 mBCLookup.
init(bcsMap);
1973 const int runNumber = (mRunNumber == -1) ?
int(tinfo.runNumber) : mRunNumber;
1974 if (mTFNumber == -1L) {
1976 tfNumber = uint64_t(tinfo.firstTForbit) + (uint64_t(tinfo.runNumber) << 32);
1978 tfNumber = mTFNumber;
1981 std::vector<float> aAmplitudes, aTimes;
1982 std::vector<uint8_t> aChannels;
1983 fv0aCursor.reserve(fv0RecPoints.size());
1984 for (
auto& fv0RecPoint : fv0RecPoints) {
1985 aAmplitudes.clear();
1988 const auto channelData = fv0RecPoint.getBunchChannelData(fv0ChData);
1989 for (
auto& channel : channelData) {
1990 if (channel.charge > 0) {
1991 aAmplitudes.push_back(truncateFloatFraction(channel.charge, mV0Amplitude));
1992 aTimes.push_back(truncateFloatFraction(channel.time * 1.E-3, mV0ChannelTime));
1993 aChannels.push_back(channel.channel);
1996 uint64_t
bc = fv0RecPoint.getInteractionRecord().toLong();
1997 auto item = bcsMap.find(
bc);
1999 if (item != bcsMap.end()) {
2000 bcID = item->second;
2002 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a FV0 rec. point; BC = " <<
bc;
2007 truncateFloatFraction(fv0RecPoint.getCollisionGlobalMeanTime() * 1E-3, mV0Time),
2008 fv0RecPoint.getTrigger().getTriggersignals());
2010 if (mEnableFITextra) {
2011 fv0aExtraCursor(bcID,
2016 std::vector<float> zdcEnergy, zdcAmplitudes, zdcTime;
2017 std::vector<uint8_t> zdcChannelsE, zdcChannelsT;
2018 zdcCursor.reserve(zdcBCRecData.size());
2019 for (
auto zdcRecData : zdcBCRecData) {
2020 uint64_t
bc = zdcRecData.ir.toLong();
2021 auto item = bcsMap.find(
bc);
2023 if (item != bcsMap.end()) {
2024 bcID = item->second;
2026 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a ZDC rec. point; BC = " <<
bc;
2028 int fe, ne, ft, nt, fi, ni;
2029 zdcRecData.getRef(fe, ne, ft, nt, fi, ni);
2031 zdcChannelsE.clear();
2032 zdcAmplitudes.clear();
2034 zdcChannelsT.clear();
2035 for (
int ie = 0; ie < ne; ie++) {
2036 auto& zdcEnergyData = zdcEnergies[fe + ie];
2037 zdcEnergy.emplace_back(zdcEnergyData.energy());
2038 zdcChannelsE.emplace_back(zdcEnergyData.ch());
2040 for (
int it = 0; it < nt; it++) {
2041 auto& tdc = zdcTDCData[ft + it];
2042 zdcAmplitudes.emplace_back(tdc.amplitude());
2043 zdcTime.emplace_back(tdc.value());
2057 std::vector<std::vector<int>> mcColToEvSrc;
2063 int nMCCollisions = mcReader->getDigitizationContext()->getNCollisions();
2064 const auto& mcRecords = mcReader->getDigitizationContext()->getEventRecords();
2065 const auto& mcParts = mcReader->getDigitizationContext()->getEventParts();
2068 if (mUseSigFiltMC) {
2069 std::vector<int> sourceIDs{};
2070 for (
int iCol = 0; iCol < nMCCollisions; iCol++) {
2071 for (
auto const& colPart : mcParts[iCol]) {
2072 int sourceID = colPart.sourceID;
2073 if (std::find(sourceIDs.begin(), sourceIDs.end(), sourceID) == sourceIDs.end()) {
2074 sourceIDs.push_back(sourceID);
2076 if (sourceIDs.size() > 1) {
2080 if (sourceIDs.size() > 1) {
2084 if (sourceIDs.size() <= 1) {
2085 LOGP(fatal,
"Signal filtering cannot be enabled without embedding. Please fix the configuration either enabling the embedding, or turning off the signal filtering.");
2090 int totalNParts = 0;
2091 for (
int iCol = 0; iCol < nMCCollisions; iCol++) {
2092 totalNParts += mcParts[iCol].size();
2094 mcCollisionsCursor.
reserve(totalNParts);
2096 for (
int iCol = 0; iCol < nMCCollisions; iCol++) {
2097 const auto time = mcRecords[iCol].getTimeOffsetWrtBC();
2098 auto globalBC = mcRecords[iCol].toLong();
2099 auto item = bcsMap.find(globalBC);
2101 if (item != bcsMap.end()) {
2102 bcID = item->second;
2104 LOG(fatal) <<
"Error: could not find a corresponding BC ID "
2105 <<
"for MC collision; BC = " << globalBC
2106 <<
", mc collision = " << iCol;
2108 auto& colParts = mcParts[iCol];
2109 auto nParts = colParts.size();
2110 for (
auto colPart : colParts) {
2111 auto eventID = colPart.entryID;
2112 auto sourceID = colPart.sourceID;
2115 if (nParts == 1 || sourceID == 0) {
2118 auto& header = mcReader->getMCEventHeader(sourceID, eventID);
2119 updateMCHeader(mcCollisionsCursor.
cursor,
2120 hepmcXSectionsCursor.
cursor,
2121 hepmcPdfInfosCursor.
cursor,
2122 hepmcHeavyIonsCursor.
cursor,
2130 mcColToEvSrc.emplace_back(std::vector<int>{iCol, sourceID, eventID});
2135 std::sort(mcColToEvSrc.begin(), mcColToEvSrc.end(),
2136 [](
const std::vector<int>&
left,
const std::vector<int>&
right) { return (left[0] < right[0]); });
2139 int16_t aFDDAmplitudesA[8] = {0u}, aFDDAmplitudesC[8] = {0u};
2140 float aFDDTimesA[8] = {0.f}, aFDDTimesC[8] = {0.f};
2142 fddCursor.reserve(fddRecPoints.size());
2143 for (
const auto& fddRecPoint : fddRecPoints) {
2144 for (
int i = 0;
i < 8;
i++) {
2145 aFDDAmplitudesA[
i] = 0;
2146 aFDDAmplitudesC[
i] = 0;
2147 aFDDTimesA[
i] = 0.f;
2148 aFDDTimesC[
i] = 0.f;
2150 uint64_t globalBC = fddRecPoint.getInteractionRecord().toLong();
2151 uint64_t
bc = globalBC;
2152 auto item = bcsMap.find(
bc);
2154 if (item != bcsMap.end()) {
2155 bcID = item->second;
2157 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a FDD rec. point; BC = " <<
bc;
2159 const auto channelData = fddRecPoint.getBunchChannelData(fddChData);
2160 for (
const auto& channel : channelData) {
2161 if (channel.mPMNumber < 8) {
2162 aFDDAmplitudesC[channel.mPMNumber] = channel.mChargeADC;
2163 aFDDTimesC[channel.mPMNumber] = truncateFloatFraction(channel.mTime * 1E-3, mFDDChannelTime);
2165 aFDDAmplitudesA[channel.mPMNumber - 8] = channel.mChargeADC;
2166 aFDDTimesA[channel.mPMNumber - 8] = truncateFloatFraction(channel.mTime * 1E-3, mFDDChannelTime);
2173 truncateFloatFraction(fddRecPoint.getCollisionTimeA() * 1E-3, mFDDTime),
2174 truncateFloatFraction(fddRecPoint.getCollisionTimeC() * 1E-3, mFDDTime),
2175 fddRecPoint.getTrigger().getTriggersignals());
2176 if (mEnableFITextra) {
2177 fddExtraCursor(bcID,
2184 std::vector<float> aAmplitudesA, aAmplitudesC, aTimesA, aTimesC;
2185 std::vector<uint8_t> aChannelsA, aChannelsC;
2186 ft0Cursor.reserve(ft0RecPoints.size());
2187 for (
auto& ft0RecPoint : ft0RecPoints) {
2188 aAmplitudesA.clear();
2189 aAmplitudesC.clear();
2194 const auto channelData = ft0RecPoint.getBunchChannelData(ft0ChData);
2195 for (
auto& channel : channelData) {
2197 if (channel.QTCAmpl > 0) {
2199 if (channel.ChId < nFT0ChannelsAside) {
2200 aChannelsA.push_back(channel.ChId);
2201 aAmplitudesA.push_back(truncateFloatFraction(channel.QTCAmpl, mT0Amplitude));
2202 aTimesA.push_back(truncateFloatFraction(channel.CFDTime * 1E-3, mT0ChannelTime));
2204 aChannelsC.push_back(channel.ChId - nFT0ChannelsAside);
2205 aAmplitudesC.push_back(truncateFloatFraction(channel.QTCAmpl, mT0Amplitude));
2206 aTimesC.push_back(truncateFloatFraction(channel.CFDTime * 1E-3, mT0ChannelTime));
2210 uint64_t globalBC = ft0RecPoint.getInteractionRecord().toLong();
2211 uint64_t
bc = globalBC;
2212 auto item = bcsMap.find(
bc);
2214 if (item != bcsMap.end()) {
2215 bcID = item->second;
2217 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a FT0 rec. point; BC = " <<
bc;
2224 truncateFloatFraction(ft0RecPoint.getCollisionTimeA() * 1E-3, mT0Time),
2225 truncateFloatFraction(ft0RecPoint.getCollisionTimeC() * 1E-3, mT0Time),
2226 ft0RecPoint.getTrigger().getTriggersignals());
2227 if (mEnableFITextra) {
2228 ft0ExtraCursor(bcID,
2236 mcColLabelsCursor.
reserve(primVerLabels.size());
2237 for (
auto&
label : primVerLabels) {
2238 auto it = std::find_if(mcColToEvSrc.begin(), mcColToEvSrc.end(),
2239 [&
label](
const auto& mcColInfo) { return mcColInfo[1] == label.getSourceID() && mcColInfo[2] == label.getEventID(); });
2240 int32_t mcCollisionID = -1;
2241 if (it != mcColToEvSrc.end()) {
2242 mcCollisionID = it->at(0);
2244 uint16_t mcMask = 0;
2245 mcColLabelsCursor(mcCollisionID, mcMask);
2249 cacheTriggers(recoData);
2250 countTPCClusters(recoData);
2252 int collisionID = 0;
2256 auto& trackReffwd = primVer2TRefs.back();
2257 fillIndexTablesPerCollision(trackReffwd, primVerGIs, recoData);
2259 for (
auto&
vertex : primVertices) {
2260 auto& trackReffwd = primVer2TRefs[collisionID];
2261 fillIndexTablesPerCollision(trackReffwd, primVerGIs, recoData);
2266 prepareStrangenessTracking(recoData);
2268 mGIDToTableFwdID.clear();
2269 mGIDToTableMFTID.clear();
2271 if (mPropTracks || mThinTracks) {
2275 mGIDUsedBySVtx.reserve(v0s.size() * 2 + cascades.size() + decays3Body.size() * 3);
2276 for (
const auto&
v0 : v0s) {
2277 mGIDUsedBySVtx.insert(
v0.getProngID(0));
2278 mGIDUsedBySVtx.insert(
v0.getProngID(1));
2280 for (
const auto& cascade : cascades) {
2281 mGIDUsedBySVtx.insert(cascade.getBachelorID());
2283 for (
const auto& id3Body : decays3Body) {
2284 mGIDUsedBySVtx.insert(id3Body.getProngID(0));
2285 mGIDUsedBySVtx.insert(id3Body.getProngID(1));
2286 mGIDUsedBySVtx.insert(id3Body.getProngID(2));
2297 auto& trackRef = primVer2TRefs.back();
2299 fillTrackTablesPerCollision(-1, std::uint64_t(-1), trackRef, primVerGIs, recoData, tracksCursor, tracksCovCursor, tracksExtraCursor, tracksQACursor,
2300 ambigTracksCursor, mftTracksCursor, mftTracksCovCursor, ambigMFTTracksCursor,
2301 fwdTracksCursor, fwdTracksCovCursor, ambigFwdTracksCursor, fwdTrkClsCursor, bcsMap);
2305 collisionsCursor.reserve(primVertices.size());
2306 for (
auto&
vertex : primVertices) {
2307 auto& cov =
vertex.getCov();
2308 auto& timeStamp =
vertex.getTimeStamp();
2309 const double interactionTime = timeStamp.getTimeStamp() * 1E3;
2310 uint64_t globalBC = relativeTime_to_GlobalBC(interactionTime);
2311 uint64_t localBC = relativeTime_to_LocalBC(interactionTime);
2312 LOG(
debug) <<
"global BC " << globalBC <<
" local BC " << localBC <<
" relative interaction time " << interactionTime;
2315 auto item = bcsMap.find(globalBC);
2317 if (item != bcsMap.end()) {
2318 bcID = item->second;
2320 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a collision; BC = " << globalBC <<
", collisionID = " << collisionID;
2322 collisionsCursor(bcID,
2323 truncateFloatFraction(
vertex.getX(), mCollisionPosition),
2324 truncateFloatFraction(
vertex.getY(), mCollisionPosition),
2325 truncateFloatFraction(
vertex.getZ(), mCollisionPosition),
2326 truncateFloatFraction(cov[0], mCollisionPositionCov),
2327 truncateFloatFraction(cov[1], mCollisionPositionCov),
2328 truncateFloatFraction(cov[2], mCollisionPositionCov),
2329 truncateFloatFraction(cov[3], mCollisionPositionCov),
2330 truncateFloatFraction(cov[4], mCollisionPositionCov),
2331 truncateFloatFraction(cov[5], mCollisionPositionCov),
2333 truncateFloatFraction(
vertex.getChi2(), mCollisionPositionCov),
2334 vertex.getNContributors(),
2335 truncateFloatFraction(relInteractionTime, mCollisionPosition),
2336 truncateFloatFraction(timeStamp.getTimeStampError() * 1E3, mCollisionPositionCov));
2337 mVtxToTableCollID[collisionID] = mTableCollID++;
2339 auto& trackRef = primVer2TRefs[collisionID];
2341 fillTrackTablesPerCollision(collisionID, globalBC, trackRef, primVerGIs, recoData, tracksCursor, tracksCovCursor, tracksExtraCursor, tracksQACursor, ambigTracksCursor,
2342 mftTracksCursor, mftTracksCovCursor, ambigMFTTracksCursor,
2343 fwdTracksCursor, fwdTracksCovCursor, ambigFwdTracksCursor, fwdTrkClsCursor, bcsMap);
2347 fillSecondaryVertices(recoData, v0sCursor, cascadesCursor, decay3BodyCursor);
2348 fillHMPID(recoData, hmpCursor);
2349 fillStrangenessTrackingTables(recoData, trackedV0Cursor, trackedCascadeCursor, tracked3BodyCurs);
2353 std::unordered_map<uint64_t, std::pair<uint64_t, uint64_t>> bcToClassMask;
2355 LOG(
debug) <<
"CTP input available";
2356 for (
auto& ctpDigit : ctpDigits) {
2357 uint64_t
bc = ctpDigit.intRecord.toLong();
2358 uint64_t classMask = ctpDigit.CTPClassMask.to_ulong();
2359 uint64_t inputMask = ctpDigit.CTPInputMask.to_ulong();
2360 if (emcalIncomplete.find(
bc) != emcalIncomplete.end()) {
2362 auto classMaskOrig = classMask;
2363 classMask = classMask & ~mEMCALTrgClassMask;
2364 LOG(
debug) <<
"Found EMCAL incomplete event, mask before " << std::bitset<64>(classMaskOrig) <<
", after " << std::bitset<64>(classMask);
2366 bcToClassMask[
bc] = {classMask, inputMask};
2372 bcCursor.reserve(bcsMap.size());
2373 for (
auto& item : bcsMap) {
2374 uint64_t
bc = item.first;
2375 std::pair<uint64_t, uint64_t> masks{0, 0};
2377 auto bcClassPair = bcToClassMask.find(
bc);
2378 if (bcClassPair != bcToClassMask.end()) {
2379 masks = bcClassPair->second;
2388 bcToClassMask.clear();
2391 auto bcFlags = fillBCFlags(recoData, bcsMap);
2392 bcFlagsCursor.reserve(bcFlags.size());
2393 for (
auto f : bcFlags) {
2400 cpvClustersCursor.reserve(cpvTrigRecs.size());
2401 for (
auto& cpvEvent : cpvTrigRecs) {
2402 uint64_t
bc = cpvEvent.getBCData().toLong();
2403 auto item = bcsMap.find(
bc);
2405 if (item != bcsMap.end()) {
2406 bcID = item->second;
2408 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a CPV Trigger Record; BC = " <<
bc;
2410 for (
int iClu = cpvEvent.getFirstEntry(); iClu < cpvEvent.getFirstEntry() + cpvEvent.getNumberOfObjects(); iClu++) {
2411 auto&
clu = cpvClusters[iClu];
2412 clu.getLocalPosition(posX, posZ);
2413 cpvClustersCursor(bcID,
2414 truncateFloatFraction(posX, mCPVPos),
2415 truncateFloatFraction(posZ, mCPVPos),
2416 truncateFloatFraction(
clu.getEnergy(), mCPVAmpl),
2417 clu.getPackedClusterStatus());
2426 fillMCParticlesTable(*mcReader,
2427 mcParticlesCursor.
cursor,
2433 LOG(info) <<
"FILL MC took " << timer.RealTime() <<
" s";
2434 mcColToEvSrc.clear();
2440 fillMCTrackLabelsTable(mcTrackLabelCursor, mcMFTTrackLabelCursor, mcFwdTrackLabelCursor, primVer2TRefs.back(), primVerGIs, recoData);
2441 for (
auto iref = 0U; iref < primVer2TRefs.size() - 1; iref++) {
2442 auto& trackRef = primVer2TRefs[iref];
2443 fillMCTrackLabelsTable(mcTrackLabelCursor, mcMFTTrackLabelCursor, mcFwdTrackLabelCursor, trackRef, primVerGIs, recoData, iref);
2449 fillCaloTable(caloCellsCursor, caloCellsTRGTableCursor, mcCaloLabelsCursor, bcsMap, recoData);
2454 mGIDToTableID.clear();
2456 mGIDToTableFwdID.clear();
2458 mGIDToTableMFTID.clear();
2460 mVtxToTableCollID.clear();
2462 mV0ToTableID.clear();
2465 mIndexTableFwd.clear();
2467 mIndexTableMFT.clear();
2472 mGIDUsedBySVtx.clear();
2473 mGIDUsedByStr.clear();
2475 originCursor(tfNumber);
2478 TString dataType = mUseMC ?
"MC" :
"RAW";
2480 TString ROOTVersion = ROOT_RELEASE;
2481 mMetaDataKeys = {
"DataType",
"Run",
"O2Version",
"ROOTVersion",
"RecoPassName",
"AnchorProduction",
"AnchorPassName",
"LPMProductionTag",
"CreatedBy"};
2482 mMetaDataVals = {dataType,
"3", O2Version, ROOTVersion, mRecoPass, mAnchorProd, mAnchorPass, mLPMProdTag, mUser};
2483 add_additional_meta_info(mMetaDataKeys, mMetaDataVals);
2501 for (
const auto& rof : rofs) {
2502 int first = rof.getFirstEntry(), last =
first + rof.getNEntries();
2503 for (
int i =
first;
i < last;
i++) {
2504 mITSROFs.push_back(
count);
2514 for (
const auto& rof : rofs) {
2515 int first = rof.getFirstEntry(),
last =
first + rof.getNEntries();
2517 mMFTROFs.push_back(
count);
2524 mITSTPCTRDTriggers.clear();
2527 for (
const auto& trig : itstpctrigs) {
2528 int first = trig.getFirstTrack(),
last =
first + trig.getNumberOfTracks();
2530 mITSTPCTRDTriggers.push_back(
count);
2537 mTPCTRDTriggers.clear();
2540 for (
const auto& trig : tpctrigs) {
2541 int first = trig.getFirstTrack(),
last =
first + trig.getNumberOfTracks();
2543 mTPCTRDTriggers.push_back(
count);
2553 for (
const auto& rof : rofs) {
2556 mMCHROFs.push_back(
count);
2563AODProducerWorkflowDPL::TrackExtraInfo AODProducerWorkflowDPL::processBarrelTrack(
int collisionID, std::uint64_t collisionBC,
GIndex trackIndex,
2566 TrackExtraInfo extraInfoHolder;
2567 if (collisionID < 0) {
2570 bool needBCSlice = collisionID < 0;
2571 uint64_t bcOfTimeRef = collisionBC - mStartIR.
toLong();
2573 auto setTrackTime = [&](
double t,
double terr,
bool gaussian) {
2579 extraInfoHolder.trackTimeRes = terr;
2581 double error = this->mTimeMarginTrackTime + (gaussian ? extraInfoHolder.trackTimeRes * this->mNSigmaTimeTrack : extraInfoHolder.trackTimeRes);
2582 bcOfTimeRef = fillBCSlice(extraInfoHolder.bcSlice, t - error, t + error, bcsMap);
2585 extraInfoHolder.diffBCRef =
int(bcOfTimeRef);
2587 truncateFloatFraction(extraInfoHolder.trackTime, mTrackTime), truncateFloatFraction(extraInfoHolder.trackTimeRes, mTrackTimeError),
2590 auto contributorsGID =
data.getSingleDetectorRefs(trackIndex);
2591 const auto& trackPar =
data.getTrackParam(trackIndex);
2592 extraInfoHolder.flags |= trackPar.getPID() << 28;
2593 auto src = trackIndex.getSource();
2595 const auto& tofMatch =
data.getTOFMatch(trackIndex);
2596 extraInfoHolder.tofChi2 = tofMatch.getChi2();
2597 const auto& tofInt = tofMatch.getLTIntegralOut();
2598 float intLen = tofInt.getL();
2599 extraInfoHolder.length = intLen;
2606 extraInfoHolder.tofExpMom = mass * expBeta / std::sqrt(1.f - expBeta * expBeta);
2609 const double massZ = o2::track::PID::getMass2Z(trackPar.getPID());
2610 const double energy = sqrt((massZ * massZ) + (extraInfoHolder.tofExpMom * extraInfoHolder.tofExpMom));
2611 const double exp = extraInfoHolder.length * energy / (cSpeed * extraInfoHolder.tofExpMom);
2612 auto tofSignal = (tofMatch.getSignal() -
exp) * 1e-3;
2613 setTrackTime(tofSignal, 0.2,
true);
2617 extraInfoHolder.trdChi2 = trdOrig.getChi2();
2618 extraInfoHolder.trdSignal = trdOrig.getSignal();
2619 extraInfoHolder.trdPattern = getTRDPattern(trdOrig);
2620 if (extraInfoHolder.trackTimeRes < 0.) {
2622 const auto& trdTrig = (
src ==
GIndex::Source::TPCTRD) ?
data.getTPCTRDTriggers()[mTPCTRDTriggers[trackIndex.getIndex()]] :
data.getITSTPCTRDTriggers()[mITSTPCTRDTriggers[trackIndex.getIndex()]];
2624 setTrackTime(ttrig, 1.,
true);
2628 const auto& itsTrack =
data.getITSTrack(contributorsGID[
GIndex::ITS]);
2629 int nClusters = itsTrack.getNClusters();
2630 float chi2 = itsTrack.getChi2();
2632 extraInfoHolder.itsClusterSizes = itsTrack.getClusterSizes();
2634 const auto& rof =
data.getITSTracksROFRecords()[mITSROFs[trackIndex.getIndex()]];
2636 setTrackTime(t, mITSROFrameHalfLengthNS,
false);
2639 extraInfoHolder.itsClusterSizes =
data.getITSABRefs()[contributorsGID[
GIndex::Source::ITSAB].getIndex()].getClusterSizes();
2643 const auto& tpcClData = mTPCCounters[contributorsGID[
GIndex::TPC]];
2644 const auto& dEdx = tpcOrig.getdEdx().dEdxTotTPC > 0 ? tpcOrig.getdEdx() : tpcOrig.getdEdxAlt();
2645 if (tpcOrig.getdEdx().dEdxTotTPC == 0) {
2648 extraInfoHolder.tpcInnerParam = tpcOrig.getP() / tpcOrig.getAbsCharge();
2649 extraInfoHolder.tpcChi2NCl = tpcOrig.getNClusters() ? tpcOrig.getChi2() / tpcOrig.getNClusters() : 0;
2650 extraInfoHolder.tpcSignal = dEdx.dEdxTotTPC;
2651 extraInfoHolder.tpcNClsFindable = tpcOrig.getNClusters();
2652 extraInfoHolder.tpcNClsFindableMinusFound = tpcOrig.getNClusters() - tpcClData.found;
2653 extraInfoHolder.tpcNClsFindableMinusCrossedRows = tpcOrig.getNClusters() - tpcClData.crossed;
2654 extraInfoHolder.tpcNClsShared = tpcClData.shared;
2655 uint32_t clsUsedForPID = dEdx.NHitsIROC + dEdx.NHitsOROC1 + dEdx.NHitsOROC2 + dEdx.NHitsOROC3;
2656 extraInfoHolder.tpcNClsFindableMinusPID = tpcOrig.getNClusters() - clsUsedForPID;
2659 double t = (tpcOrig.getTime0() + 0.5 * (tpcOrig.getDeltaTFwd() - tpcOrig.getDeltaTBwd())) * mTPCBinNS;
2660 double terr = 0.5 * (tpcOrig.getDeltaTFwd() + tpcOrig.getDeltaTBwd()) * mTPCBinNS;
2661 double err = mTimeMarginTrackTime + terr;
2662 bcOfTimeRef = fillBCSlice(extraInfoHolder.bcSlice, t - err, t + err, bcsMap);
2665 p.setDeltaTFwd(tpcOrig.getDeltaTFwd());
2666 p.setDeltaTBwd(tpcOrig.getDeltaTBwd());
2667 extraInfoHolder.trackTimeRes =
p.getTimeErr();
2669 extraInfoHolder.diffBCRef =
int(bcOfTimeRef);
2670 extraInfoHolder.isTPConly =
true;
2673 const auto& trITSTPC =
data.getTPCITSTrack(trackIndex);
2674 auto ts = trITSTPC.getTimeMUS();
2675 setTrackTime(ts.getTimeStamp() * 1.e3, ts.getTimeStampError() * 1.e3,
true);
2679 extrapolateToCalorimeters(extraInfoHolder,
data.getTrackParamOut(trackIndex));
2684 return extraInfoHolder;
2687AODProducerWorkflowDPL::TrackQA AODProducerWorkflowDPL::processBarrelTrackQA(
int collisionID, std::uint64_t collisionBC,
GIndex trackIndex,
2691 auto contributorsGID =
data.getTPCContributorGID(trackIndex);
2692 const auto& trackPar =
data.getTrackParam(trackIndex);
2693 if (contributorsGID.isIndexSet()) {
2695 const auto& tpcOrig =
data.getTPCTrack(contributorsGID);
2700 std::array<float, 2> dcaInfo{-999., -999.};
2701 if (prop->propagateToDCABxByBz({v.getX(), v.getY(), v.getZ()}, tpcTMP, 2.f, mMatType, &dcaInfo)) {
2702 trackQAHolder.tpcdcaR = 100. * dcaInfo[0] / sqrt(1. + trackPar.getQ2Pt() * trackPar.getQ2Pt());
2703 trackQAHolder.tpcdcaZ = 100. * dcaInfo[1] / sqrt(1. + trackPar.getQ2Pt() * trackPar.getQ2Pt());
2707 auto safeInt8Clamp = [](
auto value) -> int8_t {
2708 using ValType =
decltype(
value);
2709 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()))));
2711 auto safeUInt8Clamp = [](
auto value) -> uint8_t {
2712 using ValType =
decltype(
value);
2713 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()))));
2717 uint8_t clusterCounters[8] = {0};
2719 uint8_t sectorIndex, rowIndex;
2720 uint32_t clusterIndex;
2721 const auto& tpcClusRefs =
data.getTPCTracksClusterRefs();
2722 for (
int i = 0;
i < tpcOrig.getNClusterReferences();
i++) {
2723 o2::tpc::TrackTPC::getClusterReference(tpcClusRefs,
i, sectorIndex, rowIndex, clusterIndex, tpcOrig.getClusterRef());
2724 char indexTracklet = (rowIndex % 152) / 19;
2725 clusterCounters[indexTracklet]++;
2729 for (
int i = 0;
i < 8;
i++) {
2730 if (clusterCounters[
i] > 5) {
2731 byteMask |= (1 <<
i);
2734 trackQAHolder.tpcTime0 = tpcOrig.getTime0();
2735 trackQAHolder.tpcClusterByteMask = byteMask;
2736 const auto& dEdxInfoAlt = tpcOrig.getdEdxAlt();
2737 const float dEdxNorm = (dEdxInfoAlt.dEdxTotTPC > 0) ? 100. / dEdxInfoAlt.dEdxTotTPC : 0;
2738 trackQAHolder.tpcdEdxNorm = dEdxInfoAlt.dEdxTotTPC;
2739 trackQAHolder.tpcdEdxMax0R = safeUInt8Clamp(dEdxInfoAlt.dEdxMaxIROC * dEdxNorm);
2740 trackQAHolder.tpcdEdxMax1R = safeUInt8Clamp(dEdxInfoAlt.dEdxMaxOROC1 * dEdxNorm);
2741 trackQAHolder.tpcdEdxMax2R = safeUInt8Clamp(dEdxInfoAlt.dEdxMaxOROC2 * dEdxNorm);
2742 trackQAHolder.tpcdEdxMax3R = safeUInt8Clamp(dEdxInfoAlt.dEdxMaxOROC3 * dEdxNorm);
2744 trackQAHolder.tpcdEdxTot0R = safeUInt8Clamp(dEdxInfoAlt.dEdxTotIROC * dEdxNorm);
2745 trackQAHolder.tpcdEdxTot1R = safeUInt8Clamp(dEdxInfoAlt.dEdxTotOROC1 * dEdxNorm);
2746 trackQAHolder.tpcdEdxTot2R = safeUInt8Clamp(dEdxInfoAlt.dEdxTotOROC2 * dEdxNorm);
2747 trackQAHolder.tpcdEdxTot3R = safeUInt8Clamp(dEdxInfoAlt.dEdxTotOROC3 * dEdxNorm);
2750 auto contributorsGIDA =
data.getSingleDetectorRefs(trackIndex);
2752 const auto& tofMatch =
data.getTOFMatch(trackIndex);
2753 const float qpt = trackPar.getQ2Pt();
2755 trackQAHolder.dTofdX = safeInt8Clamp(tofMatch.getDXatTOF() / scaleTOF);
2756 trackQAHolder.dTofdZ = safeInt8Clamp(tofMatch.getDZatTOF() / scaleTOF);
2762 if (
auto itsContGID =
data.getITSContributorGID(trackIndex); itsContGID.isIndexSet() && itsContGID.getSource() !=
GIndex::ITSAB) {
2763 const auto& itsOrig =
data.getITSTrack(itsContGID);
2772 const float beta0 = std::sqrt(std::min(50.f / tpcOrig.getdEdx().dEdxMaxTPC, 1.f));
2773 const float qpt = gloCopy.getQ2Pt();
2774 const float x = qpt / beta0;
2776 auto scaleCont = [&
x](
int i) ->
float {
2779 auto scaleGlo = [&
x](
int i) ->
float {
2784 trackQAHolder.dRefContY = safeInt8Clamp((itsCopy.getY() - tpcCopy.getY()) * scaleCont(0));
2785 trackQAHolder.dRefContZ = safeInt8Clamp((itsCopy.getZ() - tpcCopy.getZ()) * scaleCont(1));
2786 trackQAHolder.dRefContSnp = safeInt8Clamp((itsCopy.getSnp() - tpcCopy.getSnp()) * scaleCont(2));
2787 trackQAHolder.dRefContTgl = safeInt8Clamp((itsCopy.getTgl() - tpcCopy.getTgl()) * scaleCont(3));
2788 trackQAHolder.dRefContQ2Pt = safeInt8Clamp((itsCopy.getQ2Pt() - tpcCopy.getQ2Pt()) * scaleCont(4));
2790 trackQAHolder.dRefGloY = safeInt8Clamp(((itsCopy.getY() + tpcCopy.getY()) * 0.5f - gloCopy.getY()) * scaleGlo(0));
2791 trackQAHolder.dRefGloZ = safeInt8Clamp(((itsCopy.getZ() + tpcCopy.getZ()) * 0.5f - gloCopy.getZ()) * scaleGlo(1));
2792 trackQAHolder.dRefGloSnp = safeInt8Clamp(((itsCopy.getSnp() + tpcCopy.getSnp()) * 0.5f - gloCopy.getSnp()) * scaleGlo(2));
2793 trackQAHolder.dRefGloTgl = safeInt8Clamp(((itsCopy.getTgl() + tpcCopy.getTgl()) * 0.5f - gloCopy.getTgl()) * scaleGlo(3));
2794 trackQAHolder.dRefGloQ2Pt = safeInt8Clamp(((itsCopy.getQ2Pt() + tpcCopy.getQ2Pt()) * 0.5f - gloCopy.getQ2Pt()) * scaleGlo(4));
2798 (*mStreamer) <<
"trackQA"
2799 <<
"trackITSOrig=" << itsOrig
2800 <<
"trackTPCOrig=" << tpcOrig
2801 <<
"trackITSTPCOrig=" << trackPar
2802 <<
"trackITSProp=" << itsCopy
2803 <<
"trackTPCProp=" << tpcCopy
2804 <<
"trackITSTPCProp=" << gloCopy
2807 <<
"scaleCont0=" << scaleCont(0)
2808 <<
"scaleCont1=" << scaleCont(1)
2809 <<
"scaleCont2=" << scaleCont(2)
2810 <<
"scaleCont3=" << scaleCont(3)
2811 <<
"scaleCont4=" << scaleCont(4)
2812 <<
"scaleGlo0=" << scaleGlo(0)
2813 <<
"scaleGlo1=" << scaleGlo(1)
2814 <<
"scaleGlo2=" << scaleGlo(2)
2815 <<
"scaleGlo3=" << scaleGlo(3)
2816 <<
"scaleGlo4=" << scaleGlo(4)
2817 <<
"trackQAHolder.tpcTime0=" << trackQAHolder.tpcTime0
2818 <<
"trackQAHolder.tpcdEdxNorm=" << trackQAHolder.tpcdEdxNorm
2819 <<
"trackQAHolder.tpcdcaR=" << trackQAHolder.tpcdcaR
2820 <<
"trackQAHolder.tpcdcaZ=" << trackQAHolder.tpcdcaZ
2821 <<
"trackQAHolder.tpcdcaClusterByteMask=" << trackQAHolder.tpcClusterByteMask
2822 <<
"trackQAHolder.tpcdEdxMax0R=" << trackQAHolder.tpcdEdxMax0R
2823 <<
"trackQAHolder.tpcdEdxMax1R=" << trackQAHolder.tpcdEdxMax1R
2824 <<
"trackQAHolder.tpcdEdxMax2R=" << trackQAHolder.tpcdEdxMax2R
2825 <<
"trackQAHolder.tpcdEdxMax3R=" << trackQAHolder.tpcdEdxMax3R
2826 <<
"trackQAHolder.tpcdEdxTot0R=" << trackQAHolder.tpcdEdxTot0R
2827 <<
"trackQAHolder.tpcdEdxTot1R=" << trackQAHolder.tpcdEdxTot1R
2828 <<
"trackQAHolder.tpcdEdxTot2R=" << trackQAHolder.tpcdEdxTot2R
2829 <<
"trackQAHolder.tpcdEdxTot3R=" << trackQAHolder.tpcdEdxTot3R
2830 <<
"trackQAHolder.dRefContY=" << trackQAHolder.dRefContY
2831 <<
"trackQAHolder.dRefContZ=" << trackQAHolder.dRefContZ
2832 <<
"trackQAHolder.dRefContSnp=" << trackQAHolder.dRefContSnp
2833 <<
"trackQAHolder.dRefContTgl=" << trackQAHolder.dRefContTgl
2834 <<
"trackQAHolder.dRefContQ2Pt=" << trackQAHolder.dRefContQ2Pt
2835 <<
"trackQAHolder.dRefGloY=" << trackQAHolder.dRefGloY
2836 <<
"trackQAHolder.dRefGloZ=" << trackQAHolder.dRefGloZ
2837 <<
"trackQAHolder.dRefGloSnp=" << trackQAHolder.dRefGloSnp
2838 <<
"trackQAHolder.dRefGloTgl=" << trackQAHolder.dRefGloTgl
2839 <<
"trackQAHolder.dRefGloQ2Pt=" << trackQAHolder.dRefGloQ2Pt
2840 <<
"trackQAHolder.dTofdX=" << trackQAHolder.dTofdX
2841 <<
"trackQAHolder.dTofdZ=" << trackQAHolder.dTofdZ
2842 <<
"scaleTOF=" << scaleTOF
2849 return trackQAHolder;
2857 dcaInfo.set(999.f, 999.f, 999.f, 999.f, 999.f);
2862void AODProducerWorkflowDPL::extrapolateToCalorimeters(TrackExtraInfo& extraInfoHolder,
const o2::track::TrackPar& track)
2864 constexpr float XEMCAL = 440.f, XPHOS = 460.f, XEMCAL2 = XEMCAL * XEMCAL;
2865 constexpr float ETAEMCAL = 0.75;
2866 constexpr float ZEMCALFastCheck = 460.;
2867 constexpr float ETADCALINNER = 0.22;
2868 constexpr float ETAPHOS = 0.13653194;
2869 constexpr float ETAPHOSMARGIN = 0.17946979;
2870 constexpr float ETADCALPHOSSWITCH = (ETADCALINNER + ETAPHOS) / 2;
2871 constexpr short SNONE = 0, SEMCAL = 0x1, SPHOS = 0x2;
2872 constexpr short SECTORTYPE[18] = {
2873 SNONE, SNONE, SNONE, SNONE,
2874 SEMCAL, SEMCAL, SEMCAL, SEMCAL, SEMCAL, SEMCAL,
2877 SPHOS | SEMCAL, SPHOS | SEMCAL, SPHOS | SEMCAL,
2888 (std::abs(outTr.getZAt(xtrg, 0)) > ZEMCALFastCheck) ||
2889 !prop->PropagateToXBxByBz(outTr, xtrg, 0.95, 10, o2::base::Propagator::MatCorrType::USEMatCorrLUT)) {
2890 LOGP(
debug,
"preliminary step: does not reach R={} {}", XEMCAL, outTr.asString());
2894 if ((outTr.getX() * outTr.getX() + outTr.getY() * outTr.getY() < XEMCAL2) &&
2895 (!outTr.rotateParam(outTr.getPhi()) ||
2897 !prop->PropagateToXBxByBz(outTr, xtrg, 0.95, 10, o2::base::Propagator::MatCorrType::USEMatCorrLUT))) {
2898 LOGP(
debug,
"does not reach R={} {}", XEMCAL, outTr.asString());
2904 auto propExactSector = [&outTr, §or, prop](
float xprop) ->
bool {
2907 auto outTrTmp = outTr;
2909 if ((std::abs(outTr.getZ()) > ZEMCALFastCheck) || !outTrTmp.rotateParam(
alpha) ||
2910 !prop->PropagateToXBxByBz(outTrTmp, xprop, 0.95, 10, o2::base::Propagator::MatCorrType::USEMatCorrLUT)) {
2911 LOGP(
debug,
"failed on rotation to {} (sector {}) or propagation to X={} {}",
alpha, sector, xprop, outTrTmp.asString());
2916 if (sectorTmp == sector) {
2924 LOGP(
debug,
"failed to rotate to sector, {}", outTr.asString());
2931 if (!propExactSector(XEMCAL) || SECTORTYPE[sector] == SNONE) {
2936 float r = std::sqrt(outTr.getX() * outTr.getX() + outTr.getY() * outTr.getY()), tg = std::atan2(
r, outTr.getZ());
2937 float eta = -std::log(std::tan(0.5f * tg)), etaAbs = std::abs(eta);
2938 if (etaAbs > ETAEMCAL) {
2939 LOGP(
debug,
"eta = {} is off at EMCAL radius", eta, outTr.asString());
2943 if ((SECTORTYPE[sector] & SPHOS) && etaAbs < ETADCALPHOSSWITCH) {
2944 if (!propExactSector(XPHOS)) {
2947 r = std::sqrt(outTr.getX() * outTr.getX() + outTr.getY() * outTr.getY());
2948 tg = std::atan2(
r, outTr.getZ());
2949 eta = -std::log(std::tan(0.5f * tg));
2950 }
else if (!(SECTORTYPE[sector] & SEMCAL)) {
2953 extraInfoHolder.trackPhiEMCAL = outTr.getPhiPos();
2954 extraInfoHolder.trackEtaEMCAL = eta;
2955 LOGP(
debug,
"eta = {} phi = {} sector {} for {}", extraInfoHolder.trackEtaEMCAL, extraInfoHolder.trackPhiEMCAL, sector, outTr.asString());
2959std::set<uint64_t> AODProducerWorkflowDPL::filterEMCALIncomplete(
const gsl::span<const o2::emcal::TriggerRecord> triggers)
2961 std::set<uint64_t> emcalIncompletes;
2962 for (
const auto& trg : triggers) {
2963 if (trg.getTriggerBits() & o2::emcal::triggerbits::Inc) {
2965 emcalIncompletes.insert(trg.getBCData().toLong());
2968 return emcalIncompletes;
2974 static bool initOnceDone =
false;
2975 if (!initOnceDone) {
2976 initOnceDone =
true;
2983 for (
auto i = 0U;
i < bs.size();
i++) {
2998 mTPCBinNS = elParam.ZbinWidth * 1.e3;
3001 mNSigmaTimeTrack = pvParams.nSigmaTimeTrack;
3002 mTimeMarginTrackTime = pvParams.timeMarginTrackTime * 1.e3;
3023 LOG(info) <<
"ITS Alpide param updated";
3025 par.printKeyValues();
3029 LOG(info) <<
"MFT Alpide param updated";
3031 par.printKeyValues();
3042 mEMCALTrgClassMask = 0;
3043 for (
const auto& trgclass : ctpconfig.getCTPClasses()) {
3045 mEMCALTrgClassMask |= trgclass.classMask;
3048 LOG(info) <<
"Loaded EMCAL trigger class mask: " << std::bitset<64>(mEMCALTrgClassMask);
3052void AODProducerWorkflowDPL::addRefGlobalBCsForTOF(
const o2::dataformats::VtxTrackRef& trackRef,
const gsl::span<const GIndex>& GIndices,
3063 int nbitsFrac = 24 - (32 - o2::math_utils::popcount(mTrackTime));
3064 int nbitsLoss = std::max(0,
int(std::log2(TOFTimePrecPS)));
3065 assert(nbitsFrac > 1);
3066 std::uint64_t maxRangePS = std::uint64_t(0x1) << (nbitsFrac + nbitsLoss);
3068 LOG(info) <<
"Max gap of " << maxGapBC <<
" BCs to closest globalBC reference is needed for TOF tracks to provide precision of "
3069 << TOFTimePrecPS <<
" ps";
3072 if (!trackRef.getEntries()) {
3076 std::uint64_t maxBC = mStartIR.
toLong();
3077 const auto& tofClus =
data.getTOFClusters();
3084 for (
int ti =
start; ti <
end; ti++) {
3085 auto& trackIndex = GIndices[ti];
3086 const auto& tofMatch =
data.getTOFMatch(trackIndex);
3087 const auto& tofInt = tofMatch.getLTIntegralOut();
3088 float intLen = tofInt.getL();
3089 float tofExpMom = 0.;
3099 double massZ = o2::track::PID::getMass2Z(
data.getTrackParam(trackIndex).getPID());
3100 double energy = sqrt((massZ * massZ) + (tofExpMom * tofExpMom));
3101 double exp = intLen * energy / (cSpeed * tofExpMom);
3102 auto tofSignal = (tofMatch.getSignal() -
exp) * 1e-3;
3103 auto bc = relativeTime_to_GlobalBC(tofSignal);
3105 auto it = bcsMap.lower_bound(
bc);
3106 if (it == bcsMap.end() || it->first >
bc + maxGapBC) {
3107 bcsMap.emplace_hint(it,
bc, 1);
3116 if ((--bcsMap.end())->first <= maxBC) {
3117 bcsMap.emplace_hint(bcsMap.end(), maxBC + 1, 1);
3121 for (
auto& item : bcsMap) {
3127std::uint64_t AODProducerWorkflowDPL::fillBCSlice(
int (&slice)[2],
double tmin,
double tmax,
const std::map<uint64_t, int>& bcsMap)
const
3139 uint64_t bcMin = relativeTime_to_GlobalBC(tmin), bcMax = relativeTime_to_GlobalBC(tmax);
3162 auto upperindex =
p.first;
3163 while (upperindex < bcvector.size() && bcvector[upperindex] <= bcMax) {
3166 if (upperindex !=
p.first) {
3170 slice[1] = upperindex;
3172 auto bcOfTimeRef =
p.second - this->mStartIR.
toLong();
3173 LOG(
debug) <<
"BC slice t:" << tmin <<
" " << slice[0]
3174 <<
" t: " << tmax <<
" " << slice[1]
3175 <<
" bcref: " << bcOfTimeRef;
3181 std::vector<uint8_t>
flags(bcsMap.size());
3184 auto bcIt = bcsMap.begin();
3185 auto itsrofs =
data.getITSTracksROFRecords();
3188 for (
auto& rof : itsrofs) {
3189 if (!rof.getFlag(o2::itsmft::ROFRecord::VtxUPCMode)) {
3192 uint64_t globalBC0 = rof.getBCData().toLong() + bROF, globalBC1 = globalBC0 + lROF - 1;
3194 while (bcIt != bcsMap.end()) {
3195 if (bcIt->first < globalBC0) {
3199 if (bcIt->first > globalBC1) {
3211 LOGF(info,
"aod producer dpl total timing: Cpu: %.3e Real: %.3e s in %d slots",
3212 mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1);
3219 auto dataRequest = std::make_shared<DataRequest>();
3220 dataRequest->inputs.emplace_back(
"ctpconfig",
"CTP",
"CTPCONFIG", 0, Lifetime::Condition,
ccdbParamSpec(
"CTP/Config/Config", CTPConfigPerRun));
3222 dataRequest->requestTracks(
src, useMC);
3223 dataRequest->requestPrimaryVertices(useMC);
3225 dataRequest->requestCTPDigits(useMC);
3228 dataRequest->requestSecondaryVertices(useMC);
3230 if (enableStrangenessTracking) {
3231 dataRequest->requestStrangeTracks(useMC);
3232 LOGF(info,
"requestStrangeTracks Finish");
3241 dataRequest->requestTOFClusters(useMC);
3244 dataRequest->requestPHOSCells(useMC);
3247 dataRequest->requestTRDTracklets(
false);
3250 dataRequest->requestEMCALCells(useMC);
3253 dataRequest->requestCPVClusters(useMC);
3256 auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(
true,
3262 dataRequest->inputs,
3265 dataRequest->inputs.emplace_back(
"meanvtx",
"GLO",
"MEANVERTEX", 0, Lifetime::Condition,
ccdbParamSpec(
"GLO/Calib/MeanVertex", {}, 1));
3270 std::vector<OutputSpec> outputs{
3310 outputs.insert(outputs.end(),
3311 {OutputForTable<McCollisions>::spec(),
3312 OutputForTable<HepMCXSections>::spec(),
3313 OutputForTable<HepMCPdfInfos>::spec(),
3314 OutputForTable<HepMCHeavyIons>::spec(),
3315 OutputForTable<McMFTTrackLabels>::spec(),
3316 OutputForTable<McFwdTrackLabels>::spec(),
3317 OutputForTable<StoredMcParticles_001>::spec(),
3318 OutputForTable<McTrackLabels>::spec(),
3319 OutputForTable<McCaloLabels_001>::spec(),
3324 {OutputLabel{
"McCollisionLabels"},
"AOD",
"MCCOLLISIONLABEL", 0, Lifetime::Timeframe}});
3328 "aod-producer-workflow",
3331 AlgorithmSpec{adaptFromTask<AODProducerWorkflowDPL>(
src, dataRequest, ggRequest, enableSV, useMC, enableFITextra)},
3333 ConfigParamSpec{
"run-number", VariantType::Int64, -1L, {
"The run-number. If left default we try to get it from DPL header."}},
3334 ConfigParamSpec{
"aod-timeframe-id", VariantType::Int64, -1L, {
"Set timeframe number"}},
3335 ConfigParamSpec{
"fill-calo-cells", VariantType::Int, 1, {
"Fill calo cells into cell table"}},
3336 ConfigParamSpec{
"enable-truncation", VariantType::Int, 1, {
"Truncation parameter: 1 -- on, != 1 -- off"}},
3337 ConfigParamSpec{
"lpmp-prod-tag", VariantType::String,
"", {
"LPMProductionTag"}},
3338 ConfigParamSpec{
"anchor-pass", VariantType::String,
"", {
"AnchorPassName"}},
3339 ConfigParamSpec{
"anchor-prod", VariantType::String,
"", {
"AnchorProduction"}},
3340 ConfigParamSpec{
"reco-pass", VariantType::String,
"", {
"RecoPassName"}},
3341 ConfigParamSpec{
"created-by", VariantType::String,
"", {
"Who created this AO2D"}},
3342 ConfigParamSpec{
"nthreads", VariantType::Int, std::max(1,
int(std::thread::hardware_concurrency() / 2)), {
"Number of threads"}},
3343 ConfigParamSpec{
"reco-mctracks-only", VariantType::Int, 0, {
"Store only reconstructed MC tracks and their mothers/daughters. 0 -- off, != 0 -- on"}},
3344 ConfigParamSpec{
"ctpreadout-create", VariantType::Int, 0, {
"Create CTP digits from detector readout and CTP inputs. !=1 -- off, 1 -- on"}},
3345 ConfigParamSpec{
"emc-select-leading", VariantType::Bool,
false, {
"Flag to select if only the leading contributing particle for an EMCal cell should be stored"}},
3346 ConfigParamSpec{
"propagate-tracks", VariantType::Bool,
false, {
"Propagate tracks (not used for secondary vertices) to IP"}},
3347 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)"}},
3348 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)"}},
3349 ConfigParamSpec{
"propagate-muons", VariantType::Bool,
false, {
"Propagate muons to IP"}},
3350 ConfigParamSpec{
"thin-tracks", VariantType::Bool,
false, {
"Produce thinned track tables"}},
3351 ConfigParamSpec{
"trackqc-fraction", VariantType::Float, float(0.1), {
"Fraction of tracks to QC"}},
3352 ConfigParamSpec{
"trackqc-NTrCut", VariantType::Int64, 4L, {
"Minimal length of the track - in amount of tracklets"}},
3353 ConfigParamSpec{
"trackqc-tpc-dca", VariantType::Float, 3.f, {
"Keep TPC standalone track with this DCAxy to the PV"}},
3354 ConfigParamSpec{
"trackqc-tpc-cls", VariantType::Int, 80, {
"Keep TPC standalone track with this #clusters"}},
3355 ConfigParamSpec{
"trackqc-tpc-pt", VariantType::Float, 0.2f, {
"Keep TPC standalone track with this pt"}},
3356 ConfigParamSpec{
"with-streamers", VariantType::String,
"", {
"Bit-mask to steer writing of intermediate streamer files"}},
3357 ConfigParamSpec{
"seed", VariantType::Int, 0, {
"Set seed for random generator used for sampling (0 (default) means using a random_device)"}},
3358 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 signalFilter=false)
bool updateHepMCXSection(const XSectionCursor &cursor, int collisionID, short generatorID, o2::dataformats::MCEventHeader const &header, HepMCUpdate when=HepMCUpdate::anyKey)
framework::DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool enableSV, bool enableST, bool useMC, bool CTPConfigPerRun, bool enableFITextra)
create a processor spec
void keepMCParticle(std::vector< std::vector< std::unordered_map< int, int > > > &store, int source, int event, int track, int value=1, bool useSigFilt=false)
void dimensionMCKeepStore(std::vector< std::vector< std::unordered_map< int, int > > > &store, int Nsources, int NEvents)
void clearMCKeepStore(std::vector< std::vector< std::unordered_map< int, int > > > &store)
constexpr int LHCMaxBunches
constexpr double LHCBunchSpacingNS
constexpr double MassPionCharged
Defining PrimaryVertex explicitly as messageable.
std::vector< ConfigParamSpec > ccdbParamSpec(std::string const &path, int runDependent, std::vector< CCDBMetadata > metadata={}, int qrate=0)
int angle2Sector(float phi)
float sector2Angle(int sect)
const int TDCSignal[NTDCChannels]
constexpr int NTDCChannels
std::string fullVersion()
get full version information (official O2 release and git commit)
static OutputSpec const spec()
decltype(FFL(std::declval< cursor_t >())) cursor
void reserve(int64_t size)
auto getZDCTDCData() const
auto getStrangeTracks() const
auto getFDDRecPoints() const
auto getMCHMIDMatches() const
o2::InteractionRecord startIR
auto getDecays3BodyIdx() const
auto getTPCTRDTriggers() const
auto getPrimaryVertices() const
auto getPrimaryVertexMatchedTracks() const
auto getMCHTrackClusters() const
auto getMCHTracksROFRecords() const
auto getCTPDigits() const
auto getCascadesIdx() const
auto getPrimaryVertexMatchedTrackRefs() const
gsl::span< const o2::trd::TriggerRecord > getTRDTriggerRecords() const
auto getCPVClusters() const
auto getFV0ChannelsData() const
auto getMFTTracksROFRecords() const
auto getCPVTriggers() const
void collectData(o2::framework::ProcessingContext &pc, const DataRequest &request)
auto getPrimaryVertexMCLabels() const
auto getZDCEnergy() const
auto getFT0RecPoints() const
auto getITSTracksROFRecords() const
auto getMCHTracks() const
auto getFV0RecPoints() const
auto getHMPMatches() const
auto getITSTPCTRDTriggers() const
auto getFT0ChannelsData() const
auto getFDDChannelsData() const
auto getZDCBCRecData() const
auto getEMCALTriggers() const
auto getMFTTracks() const
auto getPHOSTriggers() const
static bool downsampleTsallisCharged(float pt, float factorPt, float sqrts, float &weight, float rnd, float mass=0.13957)
std::vector< o2::ctf::BufferType > vec
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::uniform_int_distribution< unsigned long long > distr
std::array< uint16_t, 5 > pattern