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";
960 MCParticlesCursor& mcParticlesCursor,
961 const gsl::span<const o2::dataformats::VtxTrackRef>& primVer2TRefs,
962 const gsl::span<const GIndex>& GIndices,
964 const std::vector<std::vector<int>>& mcColToEvSrc)
968 for (
auto& p : mcColToEvSrc) {
969 NSources = std::max(p[1], NSources);
970 NEvents = std::max(p[2], NEvents);
974 LOG(info) <<
" number of events " << NEvents;
975 LOG(info) <<
" number of sources " << NSources;
978 std::vector<int> particleIDsToKeep;
980 auto markMCTrackForSrc = [&](std::array<GID, GID::NSources>& contributorsGID, uint8_t
src) {
981 auto mcLabel =
data.getTrackMCLabel(contributorsGID[
src]);
982 if (!mcLabel.isValid()) {
985 keepMCParticle(mToStore, mcLabel.getSourceID(), mcLabel.getEventID(), mcLabel.getTrackID());
989 for (
auto& trackRef : primVer2TRefs) {
993 for (
int ti =
start; ti <
end; ti++) {
994 auto& trackIndex = GIndices[ti];
995 if (GIndex::includesSource(
src, mInputSources)) {
996 auto mcTruth =
data.getTrackMCLabel(trackIndex);
997 if (!mcTruth.isValid()) {
1000 keepMCParticle(mToStore, mcTruth.getSourceID(), mcTruth.getEventID(), mcTruth.getTrackID());
1002 auto contributorsGID =
data.getSingleDetectorRefs(trackIndex);
1011 for (
auto& mcLabel : labelsTOF) {
1012 if (!mcLabel.isValid()) {
1015 keepMCParticle(mToStore, mcLabel.getSourceID(), mcLabel.getEventID(), mcLabel.getTrackID());
1024 auto& mcCaloEMCCellLabels =
data.getEMCALCellsMCLabels()->getTruthArray();
1025 for (
auto& mcTruth : mcCaloEMCCellLabels) {
1026 if (!mcTruth.isValid()) {
1029 keepMCParticle(mToStore, mcTruth.getSourceID(), mcTruth.getEventID(), mcTruth.getTrackID());
1033 auto& mcCaloPHOSCellLabels =
data.getPHOSCellsMCLabels()->getTruthArray();
1034 for (
auto& mcTruth : mcCaloPHOSCellLabels) {
1035 if (!mcTruth.isValid()) {
1038 keepMCParticle(mToStore, mcTruth.getSourceID(), mcTruth.getEventID(), mcTruth.getTrackID());
1041 using namespace aodmchelpers;
1045 for (
auto& colInfo : mcColToEvSrc) {
1046 int event = colInfo[2];
1048 int mcColId = colInfo[0];
1050 LOG(
debug) <<
"Event=" <<
event <<
" source=" <<
source <<
" collision=" << mcColId;
1068template <
typename MCTrackLabelCursorType,
typename MCMFTTrackLabelCursorType,
typename MCFwdTrackLabelCursorType>
1069void AODProducerWorkflowDPL::fillMCTrackLabelsTable(MCTrackLabelCursorType& mcTrackLabelCursor,
1070 MCMFTTrackLabelCursorType& mcMFTTrackLabelCursor,
1071 MCFwdTrackLabelCursorType& mcFwdTrackLabelCursor,
1073 const gsl::span<const GIndex>& primVerGIs,
1086 mcMFTTrackLabelCursor.reserve(
end -
start + mcMFTTrackLabelCursor.lastIndex());
1087 mcFwdTrackLabelCursor.reserve(
end -
start + mcFwdTrackLabelCursor.lastIndex());
1088 mcTrackLabelCursor.reserve(
end -
start + mcTrackLabelCursor.lastIndex());
1089 for (
int ti =
start; ti <
end; ti++) {
1090 const auto trackIndex = primVerGIs[ti];
1093 auto needToStore = [trackIndex](std::unordered_map<GIndex, int>& mp) {
1094 auto entry = mp.find(trackIndex);
1095 if (
entry == mp.end() ||
entry->second == -1) {
1102 if (GIndex::includesSource(
src, mInputSources)) {
1103 auto mcTruth =
data.getTrackMCLabel(trackIndex);
1104 MCLabels labelHolder{};
1109 if (mcTruth.isValid()) {
1110 labelHolder.labelID = (mToStore[mcTruth.getSourceID()][mcTruth.getEventID()])[mcTruth.getTrackID()];
1112 if (mcTruth.isFake()) {
1113 labelHolder.fwdLabelMask |= (0x1 << 7);
1115 if (mcTruth.isNoise()) {
1116 labelHolder.fwdLabelMask |= (0x1 << 6);
1119 mcMFTTrackLabelCursor(labelHolder.labelID,
1120 labelHolder.fwdLabelMask);
1122 mcFwdTrackLabelCursor(labelHolder.labelID,
1123 labelHolder.fwdLabelMask);
1126 if (!needToStore(mGIDToTableID)) {
1129 if (mcTruth.isValid()) {
1130 labelHolder.labelID = (mToStore[mcTruth.getSourceID()][mcTruth.getEventID()])[mcTruth.getTrackID()];
1131 if (mcTruth.isFake()) {
1132 labelHolder.labelMask |= (0x1 << 15);
1135 auto contributorsGID =
data.getSingleDetectorRefs(trackIndex);
1138 labelHolder.labelMask |= (0x1 << 13);
1142 }
else if (mcTruth.isNoise()) {
1143 labelHolder.labelMask |= (0x1 << 14);
1145 mcTrackLabelCursor(labelHolder.labelID, labelHolder.labelMask);
1152 auto sTrackLabels =
data.getStrangeTracksMCLabels();
1154 if (!(vertexId < 0 || vertexId >= mVertexStrLUT.size() - 1)) {
1155 mcTrackLabelCursor.reserve(mVertexStrLUT[vertexId + 1] + mcTrackLabelCursor.lastIndex());
1156 for (
int iS{mVertexStrLUT[vertexId]}; iS < mVertexStrLUT[vertexId + 1]; ++iS) {
1157 auto& collStrTrk = mCollisionStrTrk[iS];
1158 auto&
label = sTrackLabels[collStrTrk.second];
1159 MCLabels labelHolder;
1160 labelHolder.labelID =
label.isValid() ? (mToStore[
label.getSourceID()][
label.getEventID()])[
label.getTrackID()] : -1;
1161 labelHolder.labelMask = (
label.isFake() << 15) | (
label.isNoise() << 14);
1162 mcTrackLabelCursor(labelHolder.labelID, labelHolder.labelMask);
1167template <
typename V0CursorType,
typename CascadeCursorType,
typename Decay3BodyCursorType>
1168void AODProducerWorkflowDPL::fillSecondaryVertices(
const o2::globaltracking::RecoContainer& recoData, V0CursorType& v0Cursor, CascadeCursorType& cascadeCursor, Decay3BodyCursorType& decay3BodyCursor)
1175 v0Cursor.reserve(v0s.size());
1177 for (
size_t iv0 = 0; iv0 < v0s.size(); iv0++) {
1178 const auto&
v0 = v0s[iv0];
1179 auto trPosID =
v0.getProngID(0);
1180 auto trNegID =
v0.getProngID(1);
1181 uint8_t v0flags =
v0.getBits();
1182 int posTableIdx = -1, negTableIdx = -1, collID = -1;
1183 auto item = mGIDToTableID.find(trPosID);
1184 if (item != mGIDToTableID.end()) {
1185 posTableIdx = item->second;
1187 LOG(warn) <<
"Could not find a positive track index for prong ID " << trPosID;
1189 item = mGIDToTableID.find(trNegID);
1190 if (item != mGIDToTableID.end()) {
1191 negTableIdx = item->second;
1193 LOG(warn) <<
"Could not find a negative track index for prong ID " << trNegID;
1195 auto itemV = mVtxToTableCollID.find(
v0.getVertexID());
1196 if (itemV == mVtxToTableCollID.end()) {
1197 LOG(warn) <<
"Could not find V0 collisionID for the vertex ID " <<
v0.getVertexID();
1199 collID = itemV->second;
1201 if (posTableIdx != -1 and negTableIdx != -1 and collID != -1) {
1202 v0Cursor(collID, posTableIdx, negTableIdx, v0flags);
1203 mV0ToTableID[
int(iv0)] = mTableV0ID++;
1208 cascadeCursor.reserve(cascades.size());
1209 for (
auto& cascade : cascades) {
1210 auto itemV0 = mV0ToTableID.find(cascade.getV0ID());
1211 if (itemV0 == mV0ToTableID.end()) {
1214 int v0tableID = itemV0->second, bachTableIdx = -1, collID = -1;
1215 auto bachelorID = cascade.getBachelorID();
1216 auto item = mGIDToTableID.find(bachelorID);
1217 if (item != mGIDToTableID.end()) {
1218 bachTableIdx = item->second;
1220 LOG(warn) <<
"Could not find a bachelor track index";
1223 auto itemV = mVtxToTableCollID.find(cascade.getVertexID());
1224 if (itemV != mVtxToTableCollID.end()) {
1225 collID = itemV->second;
1227 LOG(warn) <<
"Could not find cascade collisionID for the vertex ID " << cascade.getVertexID();
1230 cascadeCursor(collID, v0tableID, bachTableIdx);
1234 decay3BodyCursor.reserve(decays3Body.size());
1235 for (
size_t i3Body = 0; i3Body < decays3Body.size(); i3Body++) {
1236 const auto& decay3Body = decays3Body[i3Body];
1238 decay3Body.getProngID(0),
1239 decay3Body.getProngID(1),
1240 decay3Body.getProngID(2)};
1241 int tableIdx[3]{-1, -1, -1}, collID = -1;
1242 bool missing{
false};
1243 for (
int i{0};
i < 3; ++
i) {
1244 auto item = mGIDToTableID.find(trIDs[
i]);
1245 if (item != mGIDToTableID.end()) {
1246 tableIdx[
i] = item->second;
1248 LOG(warn) << fmt::format(
"Could not find a track index for prong ID {}", (
int)trIDs[
i]);
1252 auto itemV = mVtxToTableCollID.find(decay3Body.getVertexID());
1253 if (itemV == mVtxToTableCollID.end()) {
1254 LOG(warn) <<
"Could not find 3 body collisionID for the vertex ID " << decay3Body.getVertexID();
1257 collID = itemV->second;
1262 decay3BodyCursor(collID, tableIdx[0], tableIdx[1], tableIdx[2]);
1266template <
typename FwdTrkClsCursorType>
1273 int mchTrackID = -1;
1275 mchTrackID = trackID.getIndex();
1277 auto mchmidMatch = mchmidMatches[trackID.getIndex()];
1278 mchTrackID = mchmidMatch.getMCHRef().getIndex();
1281 if (mchTrackID > -1 && mchTrackID < mchTracks.size()) {
1282 const auto& mchTrack = mchTracks[mchTrackID];
1283 fwdTrkClsCursor.reserve(mchTrack.getNClusters() + fwdTrkClsCursor.lastIndex());
1284 int first = mchTrack.getFirstClusterIdx();
1285 int last = mchTrack.getLastClusterIdx();
1286 for (
int i =
first;
i <= last;
i++) {
1287 const auto& cluster = mchClusters[
i];
1288 fwdTrkClsCursor(fwdTrackId,
1289 truncateFloatFraction(cluster.x, mMuonCl),
1290 truncateFloatFraction(cluster.y, mMuonCl),
1291 truncateFloatFraction(cluster.z, mMuonCl),
1292 (((cluster.ey < 5.) & 0x1) << 12) | (((cluster.ex < 5.) & 0x1) << 11) | cluster.getDEId());
1297template <
typename HMPCursorType>
1302 hmpCursor.reserve(hmpMatches.size());
1305 for (
size_t iHmp = 0; iHmp < hmpMatches.size(); iHmp++) {
1307 const auto&
match = hmpMatches[iHmp];
1309 float xTrk, yTrk, theta,
phi;
1313 match.getHMPIDtrk(xTrk, yTrk, theta,
phi);
1316 auto photChargeVec =
match.getPhotCharge();
1318 float photChargeVec2[10];
1320 for (Int_t
i = 0;
i < 10;
i++) {
1321 photChargeVec2[
i] = photChargeVec[
i];
1323 auto tref = mGIDToTableID.find(
match.getTrackRef());
1324 if (tref != mGIDToTableID.end()) {
1325 hmpCursor(tref->second,
match.getHMPsignal(), xTrk, yTrk, xMip, yMip, nph,
charge,
match.getIdxHMPClus(),
match.getHmpMom(), photChargeVec2);
1327 LOG(error) <<
"Could not find AOD track table entry for HMP-matched track " <<
match.getTrackRef().asString();
1339 mCollisionStrTrk.clear();
1341 mVertexStrLUT.clear();
1343 for (
auto& sTrk : recoData.getStrangeTracks()) {
1347 vtxId = v0s[sTrk.mDecayRef].getVertexID();
1349 vtxId = cascades[sTrk.mDecayRef].getVertexID();
1351 vtxId = decays3Body[sTrk.mDecayRef].getVertexID();
1353 mCollisionStrTrk.emplace_back(vtxId, sTrkID++);
1354 mVertexStrLUT[vtxId]++;
1356 std::exclusive_scan(mVertexStrLUT.begin(), mVertexStrLUT.end(), mVertexStrLUT.begin(), 0);
1359 std::sort(mCollisionStrTrk.begin(), mCollisionStrTrk.end(), [](
const auto&
a,
const auto&
b) { return a.first < b.first; });
1360 mStrTrkIndices.clear();
1361 mStrTrkIndices.resize(mCollisionStrTrk.size(), -1);
1364template <
typename V0C,
typename CC,
typename D3BC>
1367 int itsTableIdx = -1;
1373 for (
const auto& sTrk : recoData.getStrangeTracks()) {
1383 v0Curs.reserve(nV0);
1384 cascCurs.reserve(nCasc);
1385 d3BodyCurs.reserve(nD3Body);
1387 for (
const auto& sTrk : recoData.getStrangeTracks()) {
1389 auto item = mGIDToTableID.find(ITSIndex);
1390 if (item != mGIDToTableID.end()) {
1391 itsTableIdx = item->second;
1393 LOG(warn) <<
"Could not find a ITS strange track index " << ITSIndex;
1397 v0Curs(mStrTrkIndices[sTrkID++],
1407 sTrk.getAverageClusterSize());
1409 cascCurs(mStrTrkIndices[sTrkID++],
1419 sTrk.getAverageClusterSize());
1421 d3BodyCurs(mStrTrkIndices[sTrkID++],
1431 sTrk.getAverageClusterSize());
1438 const auto& tpcTracks =
data.getTPCTracks();
1439 const auto& tpcClusRefs =
data.getTPCTracksClusterRefs();
1440 const auto& tpcClusShMap =
data.clusterShMapTPC;
1441 const auto& tpcClusAcc =
data.getTPCClusters();
1442 constexpr int maxRows = 152;
1443 constexpr int neighbour = 2;
1444 int ntr = tpcTracks.size();
1445 mTPCCounters.clear();
1446 mTPCCounters.resize(ntr);
1448 int ngroup = std::min(50, std::max(1, ntr / mNThreads));
1449#pragma omp parallel for schedule(dynamic, ngroup) num_threads(mNThreads)
1451 for (
int itr = 0; itr < ntr; itr++) {
1452 std::array<bool, maxRows> clMap{}, shMap{};
1453 uint8_t sectorIndex, rowIndex;
1454 uint32_t clusterIndex;
1455 auto&
counters = mTPCCounters[itr];
1456 const auto& track = tpcTracks[itr];
1457 for (
int i = 0;
i < track.getNClusterReferences();
i++) {
1458 o2::tpc::TrackTPC::getClusterReference(tpcClusRefs,
i, sectorIndex, rowIndex, clusterIndex, track.getClusterRef());
1459 unsigned int absoluteIndex = tpcClusAcc.clusterOffset[sectorIndex][rowIndex] + clusterIndex;
1460 clMap[rowIndex] =
true;
1462 if (!shMap[rowIndex]) {
1465 shMap[rowIndex] =
true;
1469 for (
int i = 0;
i < maxRows;
i++) {
1474 }
else if ((
i - last) <= neighbour) {
1477 int lim = std::min(
i + 1 + neighbour, maxRows);
1478 for (
int j =
i + 1;
j < lim;
j++) {
1493 if (track.getTrackletIndex(il) != -1) {
1497 if (track.getHasNeighbor()) {
1500 if (track.getHasPadrowCrossing()) {
1506template <
typename TCaloHandler,
typename TCaloCursor,
typename TCaloTRGCursor,
typename TMCCaloLabelCursor>
1507void AODProducerWorkflowDPL::addToCaloTable(TCaloHandler& caloHandler, TCaloCursor& caloCellCursor, TCaloTRGCursor& caloTRGCursor,
1508 TMCCaloLabelCursor& mcCaloCellLabelCursor,
int eventID,
int bcID, int8_t caloType)
1510 auto inputEvent = caloHandler.buildEvent(eventID);
1511 auto cellsInEvent = inputEvent.mCells;
1512 auto cellMClabels = inputEvent.mMCCellLabels;
1513 caloCellCursor.reserve(cellsInEvent.size() + caloCellCursor.lastIndex());
1514 caloTRGCursor.reserve(cellsInEvent.size() + caloTRGCursor.lastIndex());
1516 mcCaloCellLabelCursor.reserve(cellsInEvent.size() + mcCaloCellLabelCursor.lastIndex());
1518 for (
auto iCell = 0U; iCell < cellsInEvent.size(); iCell++) {
1519 caloCellCursor(bcID,
1523 cellsInEvent[iCell].
getType(),
1537 std::vector<int32_t> particleIds;
1538 std::vector<float> amplitudeFraction;
1539 if (!mEMCselectLeading) {
1540 particleIds.reserve(cellMClabels.size());
1541 amplitudeFraction.reserve(cellMClabels.size());
1543 float tmpMaxAmplitude = 0;
1544 int32_t tmpindex = 0;
1545 for (
auto& mclabel : cellMClabels[iCell]) {
1547 if (mclabel.isValid()) {
1548 if (mEMCselectLeading) {
1549 if (mclabel.getAmplitudeFraction() > tmpMaxAmplitude) {
1551 if (mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID()).find(mclabel.getTrackID()) !=
1552 mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID()).end()) {
1553 tmpMaxAmplitude = mclabel.getAmplitudeFraction();
1554 tmpindex = (mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID())).at(mclabel.getTrackID());
1558 auto trackStore = mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID());
1559 auto iter = trackStore.find(mclabel.getTrackID());
1560 if (iter != trackStore.end()) {
1561 amplitudeFraction.emplace_back(mclabel.getAmplitudeFraction());
1562 particleIds.emplace_back(iter->second);
1564 particleIds.emplace_back(-1);
1565 amplitudeFraction.emplace_back(0.f);
1566 LOG(warn) <<
"CaloTable: Could not find track for mclabel (" << mclabel.getSourceID() <<
"," << mclabel.getEventID() <<
"," << mclabel.getTrackID() <<
") in the AOD MC store";
1567 if (mMCKineReader) {
1568 auto mctrack = mMCKineReader->
getTrack(mclabel);
1571 LOG(warn) <<
" ... this track is of PDG " << mctrack->GetPdgCode() <<
" produced by " << mctrack->getProdProcessAsString() <<
" at (" <<
vec.X() <<
"," <<
vec.Y() <<
"," <<
vec.Z() <<
")";
1577 if (mEMCselectLeading) {
1578 amplitudeFraction.emplace_back(tmpMaxAmplitude);
1579 particleIds.emplace_back(tmpindex);
1581 if (particleIds.size() == 0) {
1582 particleIds.emplace_back(-1);
1583 amplitudeFraction.emplace_back(0.f);
1585 mcCaloCellLabelCursor(particleIds,
1592template <
typename TCaloCursor,
typename TCaloTRGCursor,
typename TMCCaloLabelCursor>
1593void AODProducerWorkflowDPL::fillCaloTable(TCaloCursor& caloCellCursor, TCaloTRGCursor& caloTRGCursor,
1594 TMCCaloLabelCursor& mcCaloCellLabelCursor,
const std::map<uint64_t, int>& bcsMap,
1598 auto caloEMCCells =
data.getEMCALCells();
1599 auto caloEMCCellsTRGR =
data.getEMCALTriggers();
1600 auto mcCaloEMCCellLabels =
data.getEMCALCellsMCLabels();
1602 auto caloPHOSCells =
data.getPHOSCells();
1603 auto caloPHOSCellsTRGR =
data.getPHOSTriggers();
1604 auto mcCaloPHOSCellLabels =
data.getPHOSCellsMCLabels();
1608 caloPHOSCellsTRGR = {};
1609 mcCaloPHOSCellLabels = {};
1614 caloEMCCellsTRGR = {};
1615 mcCaloEMCCellLabels = {};
1622 emcEventHandler.
reset();
1623 emcEventHandler.
setCellData(caloEMCCells, caloEMCCellsTRGR);
1626 phsEventHandler.
reset();
1627 phsEventHandler.
setCellData(caloPHOSCells, caloPHOSCellsTRGR);
1633 std::vector<std::tuple<uint64_t, int8_t, int>> caloEvents;
1635 caloEvents.reserve(emcNEvents + phsNEvents);
1637 for (
int iev = 0; iev < emcNEvents; ++iev) {
1639 caloEvents.emplace_back(std::make_tuple(
bc, 1, iev));
1642 for (
int iev = 0; iev < phsNEvents; ++iev) {
1644 caloEvents.emplace_back(std::make_tuple(
bc, 0, iev));
1647 std::sort(caloEvents.begin(), caloEvents.end(),
1648 [](
const auto&
left,
const auto&
right) { return std::get<0>(left) < std::get<0>(right); });
1651 for (
int i = 0;
i < emcNEvents + phsNEvents; ++
i) {
1652 uint64_t globalBC = std::get<0>(caloEvents[
i]);
1653 int8_t caloType = std::get<1>(caloEvents[
i]);
1654 int eventID = std::get<2>(caloEvents[
i]);
1655 auto item = bcsMap.find(globalBC);
1657 if (item != bcsMap.end()) {
1658 bcID = item->second;
1660 LOG(warn) <<
"Error: could not find a corresponding BC ID for a calo point; globalBC = " << globalBC <<
", caloType = " << (
int)caloType;
1662 if (caloType == 0) {
1663 addToCaloTable(phsEventHandler, caloCellCursor, caloTRGCursor, mcCaloCellLabelCursor, eventID, bcID, caloType);
1665 if (caloType == 1) {
1666 addToCaloTable(emcEventHandler, caloCellCursor, caloTRGCursor, mcCaloCellLabelCursor, eventID, bcID, caloType);
1677 mLPMProdTag = ic.
options().
get<std::string>(
"lpmp-prod-tag");
1678 mAnchorPass = ic.
options().
get<std::string>(
"anchor-pass");
1679 mAnchorProd = ic.
options().
get<std::string>(
"anchor-prod");
1680 mUser = ic.
options().
get<std::string>(
"created-by");
1681 mRecoPass = ic.
options().
get<std::string>(
"reco-pass");
1682 mTFNumber = ic.
options().
get<int64_t>(
"aod-timeframe-id");
1683 mRecoOnly = ic.
options().
get<
int>(
"reco-mctracks-only");
1684 mTruncate = ic.
options().
get<
int>(
"enable-truncation");
1685 mRunNumber = ic.
options().
get<
int>(
"run-number");
1686 mCTPReadout = ic.
options().
get<
int>(
"ctpreadout-create");
1687 mNThreads = std::max(1, ic.
options().
get<
int>(
"nthreads"));
1688 mEMCselectLeading = ic.
options().
get<
bool>(
"emc-select-leading");
1689 mThinTracks = ic.
options().
get<
bool>(
"thin-tracks");
1690 mPropTracks = ic.
options().
get<
bool>(
"propagate-tracks");
1691 mMaxPropXiu = ic.
options().
get<
float>(
"propagate-tracks-max-xiu");
1692 mPropMuons = ic.
options().
get<
bool>(
"propagate-muons");
1693 if (
auto s = ic.
options().
get<std::string>(
"with-streamers"); !
s.empty()) {
1694 mStreamerFlags.
set(
s);
1695 if (mStreamerFlags) {
1696 LOGP(info,
"Writing streamer data with mask:");
1697 LOG(info) << mStreamerFlags;
1699 LOGP(warn,
"Specified non-default empty streamer mask!");
1702 mTrackQCFraction = ic.
options().
get<
float>(
"trackqc-fraction");
1703 mTrackQCNTrCut = ic.
options().
get<int64_t>(
"trackqc-NTrCut");
1704 mTrackQCDCAxy = ic.
options().
get<
float>(
"trackqc-tpc-dca");
1705 mTrackQCPt = ic.
options().
get<
float>(
"trackqc-tpc-pt");
1706 mTrackQCNCls = ic.
options().
get<
int>(
"trackqc-tpc-cls");
1707 if (
auto seed = ic.
options().
get<
int>(
"seed"); seed == 0) {
1708 LOGP(info,
"Using random device for seeding");
1709 std::random_device
rd;
1710 std::array<int, std::mt19937::state_size> seed_data{};
1711 std::generate(std::begin(seed_data), std::end(seed_data), std::ref(
rd));
1712 std::seed_seq seq(std::begin(seed_data), std::end(seed_data));
1713 mGenerator = std::mt19937(seq);
1715 LOGP(info,
"Using seed {} for sampling", seed);
1716 mGenerator.seed(seed);
1719 LOGP(info,
"Multi-threaded parts will run with {} OpenMP threads", mNThreads);
1722 LOG(info) <<
"OpenMP is disabled";
1724 if (mTFNumber == -1L) {
1725 LOG(info) <<
"TFNumber will be obtained from CCDB";
1727 if (mRunNumber == -1L) {
1728 LOG(info) <<
"The Run number will be obtained from DPL headers";
1732 if (mTruncate != 1) {
1733 LOG(info) <<
"Truncation is not used!";
1734 mCollisionPosition = 0xFFFFFFFF;
1735 mCollisionPositionCov = 0xFFFFFFFF;
1736 mTrackX = 0xFFFFFFFF;
1737 mTrackAlpha = 0xFFFFFFFF;
1738 mTrackSnp = 0xFFFFFFFF;
1739 mTrackTgl = 0xFFFFFFFF;
1740 mTrack1Pt = 0xFFFFFFFF;
1741 mTrackChi2 = 0xFFFFFFFF;
1742 mTrackCovDiag = 0xFFFFFFFF;
1743 mTrackCovOffDiag = 0xFFFFFFFF;
1744 mTrackSignal = 0xFFFFFFFF;
1745 mTrackTime = 0xFFFFFFFF;
1746 mTPCTime0 = 0xFFFFFFFF;
1747 mTrackTimeError = 0xFFFFFFFF;
1748 mTrackPosEMCAL = 0xFFFFFFFF;
1749 mTracklets = 0xFFFFFFFF;
1750 mMcParticleW = 0xFFFFFFFF;
1751 mMcParticlePos = 0xFFFFFFFF;
1752 mMcParticleMom = 0xFFFFFFFF;
1753 mCaloAmp = 0xFFFFFFFF;
1754 mCaloTime = 0xFFFFFFFF;
1755 mCPVPos = 0xFFFFFFFF;
1756 mCPVAmpl = 0xFFFFFFFF;
1757 mMuonTr1P = 0xFFFFFFFF;
1758 mMuonTrThetaX = 0xFFFFFFFF;
1759 mMuonTrThetaY = 0xFFFFFFFF;
1760 mMuonTrZmu = 0xFFFFFFFF;
1761 mMuonTrBend = 0xFFFFFFFF;
1762 mMuonTrNonBend = 0xFFFFFFFF;
1763 mMuonTrCov = 0xFFFFFFFF;
1764 mMuonCl = 0xFFFFFFFF;
1765 mMuonClErr = 0xFFFFFFFF;
1766 mV0Time = 0xFFFFFFFF;
1767 mV0ChannelTime = 0xFFFFFFFF;
1768 mFDDTime = 0xFFFFFFFF;
1769 mFDDChannelTime = 0xFFFFFFFF;
1770 mT0Time = 0xFFFFFFFF;
1771 mT0ChannelTime = 0xFFFFFFFF;
1772 mV0Amplitude = 0xFFFFFFFF;
1773 mFDDAmplitude = 0xFFFFFFFF;
1774 mT0Amplitude = 0xFFFFFFFF;
1778 mZDCEnergyMap[ic] = -std::numeric_limits<float>::infinity();
1781 mZDCTDCMap[ic] = -std::numeric_limits<float>::infinity();
1784 std::string hepmcUpdate = ic.
options().
get<std::string>(
"hepmc-update");
1785 HepMCUpdate when = (hepmcUpdate ==
"never" ? HepMCUpdate::never : hepmcUpdate ==
"always" ? HepMCUpdate::always
1786 : hepmcUpdate ==
"all" ? HepMCUpdate::allKeys
1787 : HepMCUpdate::anyKey);
1788 mXSectionUpdate = when;
1789 mPdfInfoUpdate = when;
1790 mHeavyIonUpdate = when;
1794 if (mStreamerFlags) {
1795 mStreamer = std::make_unique<o2::utils::TreeStreamRedirector>(
"AO2DStreamer.root",
"RECREATE");
1801void add_additional_meta_info(std::vector<TString>& keys, std::vector<TString>&
values)
1804 auto aod_external_meta_info_file = getenv(
"AOD_ADDITIONAL_METADATA_FILE");
1805 if (aod_external_meta_info_file !=
nullptr) {
1806 LOG(info) <<
"Trying to inject additional AOD meta-data from " << aod_external_meta_info_file;
1807 if (std::filesystem::exists(aod_external_meta_info_file)) {
1808 std::ifstream input_file(aod_external_meta_info_file);
1810 nlohmann::json json_data;
1812 input_file >> json_data;
1813 }
catch (nlohmann::json::parse_error& e) {
1814 std::cerr <<
"JSON Parse Error: " << e.what() <<
"\n";
1815 std::cerr <<
"Exception ID: " << e.id <<
"\n";
1816 std::cerr <<
"Byte position: " << e.byte <<
"\n";
1820 for (
const auto& [
key,
value] : json_data.items()) {
1821 LOG(info) <<
"Adding AOD MetaData" <<
key <<
" : " <<
value;
1822 keys.push_back(
key.c_str());
1833 mTimer.Start(
false);
1836 updateTimeDependentParams(pc);
1861 std::vector<o2::ctp::CTPDigit> ctpDigitsCreated;
1862 if (mCTPReadout == 1) {
1863 LOG(info) <<
"CTP : creating ctpreadout in AOD producer";
1864 createCTPReadout(recoData, ctpDigitsCreated, pc);
1865 LOG(info) <<
"CTP : ctpreadout created from AOD";
1866 ctpDigits = gsl::span<o2::ctp::CTPDigit>(ctpDigitsCreated);
1868 LOG(
debug) <<
"FOUND " << primVertices.size() <<
" primary vertices";
1869 LOG(
debug) <<
"FOUND " << ft0RecPoints.size() <<
" FT0 rec. points";
1870 LOG(
debug) <<
"FOUND " << fv0RecPoints.size() <<
" FV0 rec. points";
1871 LOG(
debug) <<
"FOUND " << fddRecPoints.size() <<
" FDD rec. points";
1872 LOG(
debug) <<
"FOUND " << cpvClusters.size() <<
" CPV clusters";
1873 LOG(
debug) <<
"FOUND " << cpvTrigRecs.size() <<
" CPV trigger records";
1875 LOG(info) <<
"FOUND " << primVertices.size() <<
" primary vertices";
1879 auto bcCursor = createTableCursor<o2::aod::BCs>(pc);
1880 auto bcFlagsCursor = createTableCursor<o2::aod::BCFlags>(pc);
1881 auto cascadesCursor = createTableCursor<o2::aod::Cascades>(pc);
1882 auto collisionsCursor = createTableCursor<o2::aod::Collisions>(pc);
1883 auto decay3BodyCursor = createTableCursor<o2::aod::Decay3Bodys>(pc);
1884 auto trackedCascadeCursor = createTableCursor<o2::aod::TrackedCascades>(pc);
1885 auto trackedV0Cursor = createTableCursor<o2::aod::TrackedV0s>(pc);
1886 auto tracked3BodyCurs = createTableCursor<o2::aod::Tracked3Bodys>(pc);
1887 auto fddCursor = createTableCursor<o2::aod::FDDs>(pc);
1888 auto fddExtraCursor = createTableCursor<o2::aod::FDDsExtra>(pc);
1889 auto ft0Cursor = createTableCursor<o2::aod::FT0s>(pc);
1890 auto ft0ExtraCursor = createTableCursor<o2::aod::FT0sExtra>(pc);
1891 auto fv0aCursor = createTableCursor<o2::aod::FV0As>(pc);
1892 auto fv0aExtraCursor = createTableCursor<o2::aod::FV0AsExtra>(pc);
1893 auto fwdTracksCursor = createTableCursor<o2::aod::StoredFwdTracks>(pc);
1894 auto fwdTracksCovCursor = createTableCursor<o2::aod::StoredFwdTracksCov>(pc);
1895 auto fwdTrkClsCursor = createTableCursor<o2::aod::FwdTrkCls>(pc);
1896 auto mftTracksCursor = createTableCursor<o2::aod::StoredMFTTracks>(pc);
1897 auto mftTracksCovCursor = createTableCursor<o2::aod::StoredMFTTracksCov>(pc);
1898 auto tracksCursor = createTableCursor<o2::aod::StoredTracksIU>(pc);
1899 auto tracksCovCursor = createTableCursor<o2::aod::StoredTracksCovIU>(pc);
1900 auto tracksExtraCursor = createTableCursor<o2::aod::StoredTracksExtra>(pc);
1901 auto tracksQACursor = createTableCursor<o2::aod::TracksQAVersion>(pc);
1902 auto ambigTracksCursor = createTableCursor<o2::aod::AmbiguousTracks>(pc);
1903 auto ambigMFTTracksCursor = createTableCursor<o2::aod::AmbiguousMFTTracks>(pc);
1904 auto ambigFwdTracksCursor = createTableCursor<o2::aod::AmbiguousFwdTracks>(pc);
1905 auto v0sCursor = createTableCursor<o2::aod::V0s>(pc);
1906 auto zdcCursor = createTableCursor<o2::aod::Zdcs>(pc);
1907 auto hmpCursor = createTableCursor<o2::aod::HMPIDs>(pc);
1908 auto caloCellsCursor = createTableCursor<o2::aod::Calos>(pc);
1909 auto caloCellsTRGTableCursor = createTableCursor<o2::aod::CaloTriggers>(pc);
1910 auto cpvClustersCursor = createTableCursor<o2::aod::CPVClusters>(pc);
1911 auto originCursor = createTableCursor<o2::aod::Origins>(pc);
1925 mcColLabelsCursor = createTableCursor<o2::aod::McCollisionLabels>(pc);
1926 mcCollisionsCursor = createTableCursor<o2::aod::McCollisions>(pc);
1927 hepmcXSectionsCursor = createTableCursor<o2::aod::HepMCXSections>(pc);
1928 hepmcPdfInfosCursor = createTableCursor<o2::aod::HepMCPdfInfos>(pc);
1929 hepmcHeavyIonsCursor = createTableCursor<o2::aod::HepMCHeavyIons>(pc);
1930 mcMFTTrackLabelCursor = createTableCursor<o2::aod::McMFTTrackLabels>(pc);
1931 mcFwdTrackLabelCursor = createTableCursor<o2::aod::McFwdTrackLabels>(pc);
1932 mcParticlesCursor = createTableCursor<o2::aod::StoredMcParticles_001>(pc);
1933 mcTrackLabelCursor = createTableCursor<o2::aod::McTrackLabels>(pc);
1934 mcCaloLabelsCursor = createTableCursor<o2::aod::McCaloLabels_001>(pc);
1937 std::unique_ptr<o2::steer::MCKinematicsReader> mcReader;
1939 mcReader = std::make_unique<o2::steer::MCKinematicsReader>(
"collisioncontext.root");
1941 mMCKineReader = mcReader.get();
1942 std::map<uint64_t, int> bcsMap;
1943 collectBCs(recoData, mUseMC ? mcReader->getDigitizationContext()->getEventRecords() : std::vector<o2::InteractionTimeRecord>{}, bcsMap);
1944 if (!primVer2TRefs.empty()) {
1945 addRefGlobalBCsForTOF(primVer2TRefs.back(), primVerGIs, recoData, bcsMap);
1948 mBCLookup.
init(bcsMap);
1951 const int runNumber = (mRunNumber == -1) ?
int(tinfo.runNumber) : mRunNumber;
1952 if (mTFNumber == -1L) {
1954 tfNumber = uint64_t(tinfo.firstTForbit) + (uint64_t(tinfo.runNumber) << 32);
1956 tfNumber = mTFNumber;
1959 std::vector<float> aAmplitudes, aTimes;
1960 std::vector<uint8_t> aChannels;
1961 fv0aCursor.reserve(fv0RecPoints.size());
1962 for (
auto& fv0RecPoint : fv0RecPoints) {
1963 aAmplitudes.clear();
1966 const auto channelData = fv0RecPoint.getBunchChannelData(fv0ChData);
1967 for (
auto& channel : channelData) {
1968 if (channel.charge > 0) {
1969 aAmplitudes.push_back(truncateFloatFraction(channel.charge, mV0Amplitude));
1970 aTimes.push_back(truncateFloatFraction(channel.time * 1.E-3, mV0ChannelTime));
1971 aChannels.push_back(channel.channel);
1974 uint64_t
bc = fv0RecPoint.getInteractionRecord().toLong();
1975 auto item = bcsMap.find(
bc);
1977 if (item != bcsMap.end()) {
1978 bcID = item->second;
1980 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a FV0 rec. point; BC = " <<
bc;
1985 truncateFloatFraction(fv0RecPoint.getCollisionGlobalMeanTime() * 1E-3, mV0Time),
1986 fv0RecPoint.getTrigger().getTriggersignals());
1988 if (mEnableFITextra) {
1989 fv0aExtraCursor(bcID,
1994 std::vector<float> zdcEnergy, zdcAmplitudes, zdcTime;
1995 std::vector<uint8_t> zdcChannelsE, zdcChannelsT;
1996 zdcCursor.reserve(zdcBCRecData.size());
1997 for (
auto zdcRecData : zdcBCRecData) {
1998 uint64_t
bc = zdcRecData.ir.toLong();
1999 auto item = bcsMap.find(
bc);
2001 if (item != bcsMap.end()) {
2002 bcID = item->second;
2004 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a ZDC rec. point; BC = " <<
bc;
2006 int fe, ne, ft, nt, fi, ni;
2007 zdcRecData.getRef(fe, ne, ft, nt, fi, ni);
2009 zdcChannelsE.clear();
2010 zdcAmplitudes.clear();
2012 zdcChannelsT.clear();
2013 for (
int ie = 0; ie < ne; ie++) {
2014 auto& zdcEnergyData = zdcEnergies[fe + ie];
2015 zdcEnergy.emplace_back(zdcEnergyData.energy());
2016 zdcChannelsE.emplace_back(zdcEnergyData.ch());
2018 for (
int it = 0; it < nt; it++) {
2019 auto& tdc = zdcTDCData[ft + it];
2020 zdcAmplitudes.emplace_back(tdc.amplitude());
2021 zdcTime.emplace_back(tdc.value());
2035 std::vector<std::vector<int>> mcColToEvSrc;
2041 int nMCCollisions = mcReader->getDigitizationContext()->getNCollisions();
2042 const auto& mcRecords = mcReader->getDigitizationContext()->getEventRecords();
2043 const auto& mcParts = mcReader->getDigitizationContext()->getEventParts();
2046 int totalNParts = 0;
2047 for (
int iCol = 0; iCol < nMCCollisions; iCol++) {
2048 totalNParts += mcParts[iCol].size();
2050 mcCollisionsCursor.
reserve(totalNParts);
2052 for (
int iCol = 0; iCol < nMCCollisions; iCol++) {
2053 const auto time = mcRecords[iCol].getTimeOffsetWrtBC();
2054 auto globalBC = mcRecords[iCol].toLong();
2055 auto item = bcsMap.find(globalBC);
2057 if (item != bcsMap.end()) {
2058 bcID = item->second;
2060 LOG(fatal) <<
"Error: could not find a corresponding BC ID "
2061 <<
"for MC collision; BC = " << globalBC
2062 <<
", mc collision = " << iCol;
2064 auto& colParts = mcParts[iCol];
2065 auto nParts = colParts.size();
2066 for (
auto colPart : colParts) {
2067 auto eventID = colPart.entryID;
2068 auto sourceID = colPart.sourceID;
2071 if (nParts == 1 || sourceID == 0) {
2074 auto& header = mcReader->getMCEventHeader(sourceID, eventID);
2075 updateMCHeader(mcCollisionsCursor.
cursor,
2076 hepmcXSectionsCursor.
cursor,
2077 hepmcPdfInfosCursor.
cursor,
2078 hepmcHeavyIonsCursor.
cursor,
2086 mcColToEvSrc.emplace_back(std::vector<int>{iCol, sourceID, eventID});
2091 std::sort(mcColToEvSrc.begin(), mcColToEvSrc.end(),
2092 [](
const std::vector<int>&
left,
const std::vector<int>&
right) { return (left[0] < right[0]); });
2095 int16_t aFDDAmplitudesA[8] = {0u}, aFDDAmplitudesC[8] = {0u};
2096 float aFDDTimesA[8] = {0.f}, aFDDTimesC[8] = {0.f};
2098 fddCursor.reserve(fddRecPoints.size());
2099 for (
const auto& fddRecPoint : fddRecPoints) {
2100 for (
int i = 0;
i < 8;
i++) {
2101 aFDDAmplitudesA[
i] = 0;
2102 aFDDAmplitudesC[
i] = 0;
2103 aFDDTimesA[
i] = 0.f;
2104 aFDDTimesC[
i] = 0.f;
2106 uint64_t globalBC = fddRecPoint.getInteractionRecord().toLong();
2107 uint64_t
bc = globalBC;
2108 auto item = bcsMap.find(
bc);
2110 if (item != bcsMap.end()) {
2111 bcID = item->second;
2113 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a FDD rec. point; BC = " <<
bc;
2115 const auto channelData = fddRecPoint.getBunchChannelData(fddChData);
2116 for (
const auto& channel : channelData) {
2117 if (channel.mPMNumber < 8) {
2118 aFDDAmplitudesC[channel.mPMNumber] = channel.mChargeADC;
2119 aFDDTimesC[channel.mPMNumber] = truncateFloatFraction(channel.mTime * 1E-3, mFDDChannelTime);
2121 aFDDAmplitudesA[channel.mPMNumber - 8] = channel.mChargeADC;
2122 aFDDTimesA[channel.mPMNumber - 8] = truncateFloatFraction(channel.mTime * 1E-3, mFDDChannelTime);
2129 truncateFloatFraction(fddRecPoint.getCollisionTimeA() * 1E-3, mFDDTime),
2130 truncateFloatFraction(fddRecPoint.getCollisionTimeC() * 1E-3, mFDDTime),
2131 fddRecPoint.getTrigger().getTriggersignals());
2132 if (mEnableFITextra) {
2133 fddExtraCursor(bcID,
2140 std::vector<float> aAmplitudesA, aAmplitudesC, aTimesA, aTimesC;
2141 std::vector<uint8_t> aChannelsA, aChannelsC;
2142 ft0Cursor.reserve(ft0RecPoints.size());
2143 for (
auto& ft0RecPoint : ft0RecPoints) {
2144 aAmplitudesA.clear();
2145 aAmplitudesC.clear();
2150 const auto channelData = ft0RecPoint.getBunchChannelData(ft0ChData);
2151 for (
auto& channel : channelData) {
2153 if (channel.QTCAmpl > 0) {
2155 if (channel.ChId < nFT0ChannelsAside) {
2156 aChannelsA.push_back(channel.ChId);
2157 aAmplitudesA.push_back(truncateFloatFraction(channel.QTCAmpl, mT0Amplitude));
2158 aTimesA.push_back(truncateFloatFraction(channel.CFDTime * 1E-3, mT0ChannelTime));
2160 aChannelsC.push_back(channel.ChId - nFT0ChannelsAside);
2161 aAmplitudesC.push_back(truncateFloatFraction(channel.QTCAmpl, mT0Amplitude));
2162 aTimesC.push_back(truncateFloatFraction(channel.CFDTime * 1E-3, mT0ChannelTime));
2166 uint64_t globalBC = ft0RecPoint.getInteractionRecord().toLong();
2167 uint64_t
bc = globalBC;
2168 auto item = bcsMap.find(
bc);
2170 if (item != bcsMap.end()) {
2171 bcID = item->second;
2173 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a FT0 rec. point; BC = " <<
bc;
2180 truncateFloatFraction(ft0RecPoint.getCollisionTimeA() * 1E-3, mT0Time),
2181 truncateFloatFraction(ft0RecPoint.getCollisionTimeC() * 1E-3, mT0Time),
2182 ft0RecPoint.getTrigger().getTriggersignals());
2183 if (mEnableFITextra) {
2184 ft0ExtraCursor(bcID,
2192 mcColLabelsCursor.
reserve(primVerLabels.size());
2193 for (
auto&
label : primVerLabels) {
2194 auto it = std::find_if(mcColToEvSrc.begin(), mcColToEvSrc.end(),
2195 [&
label](
const auto& mcColInfo) { return mcColInfo[1] == label.getSourceID() && mcColInfo[2] == label.getEventID(); });
2196 int32_t mcCollisionID = -1;
2197 if (it != mcColToEvSrc.end()) {
2198 mcCollisionID = it->at(0);
2200 uint16_t mcMask = 0;
2201 mcColLabelsCursor(mcCollisionID, mcMask);
2205 cacheTriggers(recoData);
2206 countTPCClusters(recoData);
2208 int collisionID = 0;
2212 auto& trackReffwd = primVer2TRefs.back();
2213 fillIndexTablesPerCollision(trackReffwd, primVerGIs, recoData);
2215 for (
auto&
vertex : primVertices) {
2216 auto& trackReffwd = primVer2TRefs[collisionID];
2217 fillIndexTablesPerCollision(trackReffwd, primVerGIs, recoData);
2222 prepareStrangenessTracking(recoData);
2224 mGIDToTableFwdID.clear();
2225 mGIDToTableMFTID.clear();
2227 if (mPropTracks || mThinTracks) {
2231 mGIDUsedBySVtx.reserve(v0s.size() * 2 + cascades.size() + decays3Body.size() * 3);
2232 for (
const auto&
v0 : v0s) {
2233 mGIDUsedBySVtx.insert(
v0.getProngID(0));
2234 mGIDUsedBySVtx.insert(
v0.getProngID(1));
2236 for (
const auto& cascade : cascades) {
2237 mGIDUsedBySVtx.insert(cascade.getBachelorID());
2239 for (
const auto& id3Body : decays3Body) {
2240 mGIDUsedBySVtx.insert(id3Body.getProngID(0));
2241 mGIDUsedBySVtx.insert(id3Body.getProngID(1));
2242 mGIDUsedBySVtx.insert(id3Body.getProngID(2));
2253 auto& trackRef = primVer2TRefs.back();
2255 fillTrackTablesPerCollision(-1, std::uint64_t(-1), trackRef, primVerGIs, recoData, tracksCursor, tracksCovCursor, tracksExtraCursor, tracksQACursor,
2256 ambigTracksCursor, mftTracksCursor, mftTracksCovCursor, ambigMFTTracksCursor,
2257 fwdTracksCursor, fwdTracksCovCursor, ambigFwdTracksCursor, fwdTrkClsCursor, bcsMap);
2261 collisionsCursor.reserve(primVertices.size());
2262 for (
auto&
vertex : primVertices) {
2263 auto& cov =
vertex.getCov();
2264 auto& timeStamp =
vertex.getTimeStamp();
2265 const double interactionTime = timeStamp.getTimeStamp() * 1E3;
2266 uint64_t globalBC = relativeTime_to_GlobalBC(interactionTime);
2267 uint64_t localBC = relativeTime_to_LocalBC(interactionTime);
2268 LOG(
debug) <<
"global BC " << globalBC <<
" local BC " << localBC <<
" relative interaction time " << interactionTime;
2271 auto item = bcsMap.find(globalBC);
2273 if (item != bcsMap.end()) {
2274 bcID = item->second;
2276 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a collision; BC = " << globalBC <<
", collisionID = " << collisionID;
2278 collisionsCursor(bcID,
2279 truncateFloatFraction(
vertex.getX(), mCollisionPosition),
2280 truncateFloatFraction(
vertex.getY(), mCollisionPosition),
2281 truncateFloatFraction(
vertex.getZ(), mCollisionPosition),
2282 truncateFloatFraction(cov[0], mCollisionPositionCov),
2283 truncateFloatFraction(cov[1], mCollisionPositionCov),
2284 truncateFloatFraction(cov[2], mCollisionPositionCov),
2285 truncateFloatFraction(cov[3], mCollisionPositionCov),
2286 truncateFloatFraction(cov[4], mCollisionPositionCov),
2287 truncateFloatFraction(cov[5], mCollisionPositionCov),
2289 truncateFloatFraction(
vertex.getChi2(), mCollisionPositionCov),
2290 vertex.getNContributors(),
2291 truncateFloatFraction(relInteractionTime, mCollisionPosition),
2292 truncateFloatFraction(timeStamp.getTimeStampError() * 1E3, mCollisionPositionCov));
2293 mVtxToTableCollID[collisionID] = mTableCollID++;
2295 auto& trackRef = primVer2TRefs[collisionID];
2297 fillTrackTablesPerCollision(collisionID, globalBC, trackRef, primVerGIs, recoData, tracksCursor, tracksCovCursor, tracksExtraCursor, tracksQACursor, ambigTracksCursor,
2298 mftTracksCursor, mftTracksCovCursor, ambigMFTTracksCursor,
2299 fwdTracksCursor, fwdTracksCovCursor, ambigFwdTracksCursor, fwdTrkClsCursor, bcsMap);
2303 fillSecondaryVertices(recoData, v0sCursor, cascadesCursor, decay3BodyCursor);
2304 fillHMPID(recoData, hmpCursor);
2305 fillStrangenessTrackingTables(recoData, trackedV0Cursor, trackedCascadeCursor, tracked3BodyCurs);
2309 std::unordered_map<uint64_t, std::pair<uint64_t, uint64_t>> bcToClassMask;
2311 LOG(
debug) <<
"CTP input available";
2312 for (
auto& ctpDigit : ctpDigits) {
2313 uint64_t
bc = ctpDigit.intRecord.toLong();
2314 uint64_t classMask = ctpDigit.CTPClassMask.to_ulong();
2315 uint64_t inputMask = ctpDigit.CTPInputMask.to_ulong();
2316 if (emcalIncomplete.find(
bc) != emcalIncomplete.end()) {
2318 auto classMaskOrig = classMask;
2319 classMask = classMask & ~mEMCALTrgClassMask;
2320 LOG(
debug) <<
"Found EMCAL incomplete event, mask before " << std::bitset<64>(classMaskOrig) <<
", after " << std::bitset<64>(classMask);
2322 bcToClassMask[
bc] = {classMask, inputMask};
2328 bcCursor.reserve(bcsMap.size());
2329 for (
auto& item : bcsMap) {
2330 uint64_t
bc = item.first;
2331 std::pair<uint64_t, uint64_t> masks{0, 0};
2333 auto bcClassPair = bcToClassMask.find(
bc);
2334 if (bcClassPair != bcToClassMask.end()) {
2335 masks = bcClassPair->second;
2344 bcToClassMask.clear();
2347 auto bcFlags = fillBCFlags(recoData, bcsMap);
2348 bcFlagsCursor.reserve(bcFlags.size());
2349 for (
auto f : bcFlags) {
2356 cpvClustersCursor.reserve(cpvTrigRecs.size());
2357 for (
auto& cpvEvent : cpvTrigRecs) {
2358 uint64_t
bc = cpvEvent.getBCData().toLong();
2359 auto item = bcsMap.find(
bc);
2361 if (item != bcsMap.end()) {
2362 bcID = item->second;
2364 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a CPV Trigger Record; BC = " <<
bc;
2366 for (
int iClu = cpvEvent.getFirstEntry(); iClu < cpvEvent.getFirstEntry() + cpvEvent.getNumberOfObjects(); iClu++) {
2367 auto&
clu = cpvClusters[iClu];
2368 clu.getLocalPosition(posX, posZ);
2369 cpvClustersCursor(bcID,
2370 truncateFloatFraction(posX, mCPVPos),
2371 truncateFloatFraction(posZ, mCPVPos),
2372 truncateFloatFraction(
clu.getEnergy(), mCPVAmpl),
2373 clu.getPackedClusterStatus());
2382 fillMCParticlesTable(*mcReader,
2383 mcParticlesCursor.
cursor,
2389 LOG(info) <<
"FILL MC took " << timer.RealTime() <<
" s";
2390 mcColToEvSrc.clear();
2396 fillMCTrackLabelsTable(mcTrackLabelCursor, mcMFTTrackLabelCursor, mcFwdTrackLabelCursor, primVer2TRefs.back(), primVerGIs, recoData);
2397 for (
auto iref = 0U; iref < primVer2TRefs.size() - 1; iref++) {
2398 auto& trackRef = primVer2TRefs[iref];
2399 fillMCTrackLabelsTable(mcTrackLabelCursor, mcMFTTrackLabelCursor, mcFwdTrackLabelCursor, trackRef, primVerGIs, recoData, iref);
2405 fillCaloTable(caloCellsCursor, caloCellsTRGTableCursor, mcCaloLabelsCursor, bcsMap, recoData);
2410 mGIDToTableID.clear();
2412 mGIDToTableFwdID.clear();
2414 mGIDToTableMFTID.clear();
2416 mVtxToTableCollID.clear();
2418 mV0ToTableID.clear();
2421 mIndexTableFwd.clear();
2423 mIndexTableMFT.clear();
2428 mGIDUsedBySVtx.clear();
2429 mGIDUsedByStr.clear();
2431 originCursor(tfNumber);
2434 TString dataType = mUseMC ?
"MC" :
"RAW";
2436 TString ROOTVersion = ROOT_RELEASE;
2437 mMetaDataKeys = {
"DataType",
"Run",
"O2Version",
"ROOTVersion",
"RecoPassName",
"AnchorProduction",
"AnchorPassName",
"LPMProductionTag",
"CreatedBy"};
2438 mMetaDataVals = {dataType,
"3", O2Version, ROOTVersion, mRecoPass, mAnchorProd, mAnchorPass, mLPMProdTag, mUser};
2439 add_additional_meta_info(mMetaDataKeys, mMetaDataVals);
2457 for (
const auto& rof : rofs) {
2458 int first = rof.getFirstEntry(), last =
first + rof.getNEntries();
2459 for (
int i =
first;
i < last;
i++) {
2460 mITSROFs.push_back(
count);
2470 for (
const auto& rof : rofs) {
2471 int first = rof.getFirstEntry(),
last =
first + rof.getNEntries();
2473 mMFTROFs.push_back(
count);
2480 mITSTPCTRDTriggers.clear();
2483 for (
const auto& trig : itstpctrigs) {
2484 int first = trig.getFirstTrack(),
last =
first + trig.getNumberOfTracks();
2486 mITSTPCTRDTriggers.push_back(
count);
2493 mTPCTRDTriggers.clear();
2496 for (
const auto& trig : tpctrigs) {
2497 int first = trig.getFirstTrack(),
last =
first + trig.getNumberOfTracks();
2499 mTPCTRDTriggers.push_back(
count);
2509 for (
const auto& rof : rofs) {
2512 mMCHROFs.push_back(
count);
2519AODProducerWorkflowDPL::TrackExtraInfo AODProducerWorkflowDPL::processBarrelTrack(
int collisionID, std::uint64_t collisionBC,
GIndex trackIndex,
2522 TrackExtraInfo extraInfoHolder;
2523 if (collisionID < 0) {
2526 bool needBCSlice = collisionID < 0;
2527 uint64_t bcOfTimeRef = collisionBC - mStartIR.
toLong();
2529 auto setTrackTime = [&](
double t,
double terr,
bool gaussian) {
2535 extraInfoHolder.trackTimeRes = terr;
2537 double error = this->mTimeMarginTrackTime + (gaussian ? extraInfoHolder.trackTimeRes * this->mNSigmaTimeTrack : extraInfoHolder.trackTimeRes);
2538 bcOfTimeRef = fillBCSlice(extraInfoHolder.bcSlice, t - error, t + error, bcsMap);
2541 extraInfoHolder.diffBCRef =
int(bcOfTimeRef);
2543 truncateFloatFraction(extraInfoHolder.trackTime, mTrackTime), truncateFloatFraction(extraInfoHolder.trackTimeRes, mTrackTimeError),
2546 auto contributorsGID =
data.getSingleDetectorRefs(trackIndex);
2547 const auto& trackPar =
data.getTrackParam(trackIndex);
2548 extraInfoHolder.flags |= trackPar.getPID() << 28;
2549 auto src = trackIndex.getSource();
2551 const auto& tofMatch =
data.getTOFMatch(trackIndex);
2552 extraInfoHolder.tofChi2 = tofMatch.getChi2();
2553 const auto& tofInt = tofMatch.getLTIntegralOut();
2554 float intLen = tofInt.getL();
2555 extraInfoHolder.length = intLen;
2562 extraInfoHolder.tofExpMom = mass * expBeta / std::sqrt(1.f - expBeta * expBeta);
2565 const double massZ = o2::track::PID::getMass2Z(trackPar.getPID());
2566 const double energy = sqrt((massZ * massZ) + (extraInfoHolder.tofExpMom * extraInfoHolder.tofExpMom));
2567 const double exp = extraInfoHolder.length * energy / (cSpeed * extraInfoHolder.tofExpMom);
2568 auto tofSignal = (tofMatch.getSignal() -
exp) * 1e-3;
2569 setTrackTime(tofSignal, 0.2,
true);
2573 extraInfoHolder.trdChi2 = trdOrig.getChi2();
2574 extraInfoHolder.trdSignal = trdOrig.getSignal();
2575 extraInfoHolder.trdPattern = getTRDPattern(trdOrig);
2576 if (extraInfoHolder.trackTimeRes < 0.) {
2578 const auto& trdTrig = (
src ==
GIndex::Source::TPCTRD) ?
data.getTPCTRDTriggers()[mTPCTRDTriggers[trackIndex.getIndex()]] :
data.getITSTPCTRDTriggers()[mITSTPCTRDTriggers[trackIndex.getIndex()]];
2580 setTrackTime(ttrig, 1.,
true);
2584 const auto& itsTrack =
data.getITSTrack(contributorsGID[
GIndex::ITS]);
2585 int nClusters = itsTrack.getNClusters();
2586 float chi2 = itsTrack.getChi2();
2588 extraInfoHolder.itsClusterSizes = itsTrack.getClusterSizes();
2590 const auto& rof =
data.getITSTracksROFRecords()[mITSROFs[trackIndex.getIndex()]];
2592 setTrackTime(t, mITSROFrameHalfLengthNS,
false);
2595 extraInfoHolder.itsClusterSizes =
data.getITSABRefs()[contributorsGID[
GIndex::Source::ITSAB].getIndex()].getClusterSizes();
2599 const auto& tpcClData = mTPCCounters[contributorsGID[
GIndex::TPC]];
2600 const auto& dEdx = tpcOrig.getdEdx().dEdxTotTPC > 0 ? tpcOrig.getdEdx() : tpcOrig.getdEdxAlt();
2601 if (tpcOrig.getdEdx().dEdxTotTPC == 0) {
2604 extraInfoHolder.tpcInnerParam = tpcOrig.getP() / tpcOrig.getAbsCharge();
2605 extraInfoHolder.tpcChi2NCl = tpcOrig.getNClusters() ? tpcOrig.getChi2() / tpcOrig.getNClusters() : 0;
2606 extraInfoHolder.tpcSignal = dEdx.dEdxTotTPC;
2607 extraInfoHolder.tpcNClsFindable = tpcOrig.getNClusters();
2608 extraInfoHolder.tpcNClsFindableMinusFound = tpcOrig.getNClusters() - tpcClData.found;
2609 extraInfoHolder.tpcNClsFindableMinusCrossedRows = tpcOrig.getNClusters() - tpcClData.crossed;
2610 extraInfoHolder.tpcNClsShared = tpcClData.shared;
2611 uint32_t clsUsedForPID = dEdx.NHitsIROC + dEdx.NHitsOROC1 + dEdx.NHitsOROC2 + dEdx.NHitsOROC3;
2612 extraInfoHolder.tpcNClsFindableMinusPID = tpcOrig.getNClusters() - clsUsedForPID;
2615 double t = (tpcOrig.getTime0() + 0.5 * (tpcOrig.getDeltaTFwd() - tpcOrig.getDeltaTBwd())) * mTPCBinNS;
2616 double terr = 0.5 * (tpcOrig.getDeltaTFwd() + tpcOrig.getDeltaTBwd()) * mTPCBinNS;
2617 double err = mTimeMarginTrackTime + terr;
2618 bcOfTimeRef = fillBCSlice(extraInfoHolder.bcSlice, t - err, t + err, bcsMap);
2621 p.setDeltaTFwd(tpcOrig.getDeltaTFwd());
2622 p.setDeltaTBwd(tpcOrig.getDeltaTBwd());
2623 extraInfoHolder.trackTimeRes =
p.getTimeErr();
2625 extraInfoHolder.diffBCRef =
int(bcOfTimeRef);
2626 extraInfoHolder.isTPConly =
true;
2629 const auto& trITSTPC =
data.getTPCITSTrack(trackIndex);
2630 auto ts = trITSTPC.getTimeMUS();
2631 setTrackTime(ts.getTimeStamp() * 1.e3, ts.getTimeStampError() * 1.e3,
true);
2635 extrapolateToCalorimeters(extraInfoHolder,
data.getTrackParamOut(trackIndex));
2640 return extraInfoHolder;
2643AODProducerWorkflowDPL::TrackQA AODProducerWorkflowDPL::processBarrelTrackQA(
int collisionID, std::uint64_t collisionBC,
GIndex trackIndex,
2647 auto contributorsGID =
data.getTPCContributorGID(trackIndex);
2648 const auto& trackPar =
data.getTrackParam(trackIndex);
2649 if (contributorsGID.isIndexSet()) {
2651 const auto& tpcOrig =
data.getTPCTrack(contributorsGID);
2656 std::array<float, 2> dcaInfo{-999., -999.};
2657 if (prop->propagateToDCABxByBz({v.getX(), v.getY(), v.getZ()}, tpcTMP, 2.f, mMatType, &dcaInfo)) {
2658 trackQAHolder.tpcdcaR = 100. * dcaInfo[0] / sqrt(1. + trackPar.getQ2Pt() * trackPar.getQ2Pt());
2659 trackQAHolder.tpcdcaZ = 100. * dcaInfo[1] / sqrt(1. + trackPar.getQ2Pt() * trackPar.getQ2Pt());
2663 auto safeInt8Clamp = [](
auto value) -> int8_t {
2664 using ValType =
decltype(
value);
2665 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()))));
2667 auto safeUInt8Clamp = [](
auto value) -> uint8_t {
2668 using ValType =
decltype(
value);
2669 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()))));
2673 uint8_t clusterCounters[8] = {0};
2675 uint8_t sectorIndex, rowIndex;
2676 uint32_t clusterIndex;
2677 const auto& tpcClusRefs =
data.getTPCTracksClusterRefs();
2678 for (
int i = 0;
i < tpcOrig.getNClusterReferences();
i++) {
2679 o2::tpc::TrackTPC::getClusterReference(tpcClusRefs,
i, sectorIndex, rowIndex, clusterIndex, tpcOrig.getClusterRef());
2680 char indexTracklet = (rowIndex % 152) / 19;
2681 clusterCounters[indexTracklet]++;
2685 for (
int i = 0;
i < 8;
i++) {
2686 if (clusterCounters[
i] > 5) {
2687 byteMask |= (1 <<
i);
2690 trackQAHolder.tpcTime0 = tpcOrig.getTime0();
2691 trackQAHolder.tpcClusterByteMask = byteMask;
2692 const auto& dEdxInfoAlt = tpcOrig.getdEdxAlt();
2693 const float dEdxNorm = (dEdxInfoAlt.dEdxTotTPC > 0) ? 100. / dEdxInfoAlt.dEdxTotTPC : 0;
2694 trackQAHolder.tpcdEdxNorm = dEdxInfoAlt.dEdxTotTPC;
2695 trackQAHolder.tpcdEdxMax0R = safeUInt8Clamp(dEdxInfoAlt.dEdxMaxIROC * dEdxNorm);
2696 trackQAHolder.tpcdEdxMax1R = safeUInt8Clamp(dEdxInfoAlt.dEdxMaxOROC1 * dEdxNorm);
2697 trackQAHolder.tpcdEdxMax2R = safeUInt8Clamp(dEdxInfoAlt.dEdxMaxOROC2 * dEdxNorm);
2698 trackQAHolder.tpcdEdxMax3R = safeUInt8Clamp(dEdxInfoAlt.dEdxMaxOROC3 * dEdxNorm);
2700 trackQAHolder.tpcdEdxTot0R = safeUInt8Clamp(dEdxInfoAlt.dEdxTotIROC * dEdxNorm);
2701 trackQAHolder.tpcdEdxTot1R = safeUInt8Clamp(dEdxInfoAlt.dEdxTotOROC1 * dEdxNorm);
2702 trackQAHolder.tpcdEdxTot2R = safeUInt8Clamp(dEdxInfoAlt.dEdxTotOROC2 * dEdxNorm);
2703 trackQAHolder.tpcdEdxTot3R = safeUInt8Clamp(dEdxInfoAlt.dEdxTotOROC3 * dEdxNorm);
2706 auto contributorsGIDA =
data.getSingleDetectorRefs(trackIndex);
2708 const auto& tofMatch =
data.getTOFMatch(trackIndex);
2709 const float qpt = trackPar.getQ2Pt();
2711 trackQAHolder.dTofdX = safeInt8Clamp(tofMatch.getDXatTOF() / scaleTOF);
2712 trackQAHolder.dTofdZ = safeInt8Clamp(tofMatch.getDZatTOF() / scaleTOF);
2718 if (
auto itsContGID =
data.getITSContributorGID(trackIndex); itsContGID.isIndexSet() && itsContGID.getSource() !=
GIndex::ITSAB) {
2719 const auto& itsOrig =
data.getITSTrack(itsContGID);
2728 const float beta0 = std::sqrt(std::min(50.f / tpcOrig.getdEdx().dEdxMaxTPC, 1.f));
2729 const float qpt = gloCopy.getQ2Pt();
2730 const float x = qpt / beta0;
2732 auto scaleCont = [&
x](
int i) ->
float {
2735 auto scaleGlo = [&
x](
int i) ->
float {
2740 trackQAHolder.dRefContY = safeInt8Clamp((itsCopy.getY() - tpcCopy.getY()) * scaleCont(0));
2741 trackQAHolder.dRefContZ = safeInt8Clamp((itsCopy.getZ() - tpcCopy.getZ()) * scaleCont(1));
2742 trackQAHolder.dRefContSnp = safeInt8Clamp((itsCopy.getSnp() - tpcCopy.getSnp()) * scaleCont(2));
2743 trackQAHolder.dRefContTgl = safeInt8Clamp((itsCopy.getTgl() - tpcCopy.getTgl()) * scaleCont(3));
2744 trackQAHolder.dRefContQ2Pt = safeInt8Clamp((itsCopy.getQ2Pt() - tpcCopy.getQ2Pt()) * scaleCont(4));
2746 trackQAHolder.dRefGloY = safeInt8Clamp(((itsCopy.getY() + tpcCopy.getY()) * 0.5f - gloCopy.getY()) * scaleGlo(0));
2747 trackQAHolder.dRefGloZ = safeInt8Clamp(((itsCopy.getZ() + tpcCopy.getZ()) * 0.5f - gloCopy.getZ()) * scaleGlo(1));
2748 trackQAHolder.dRefGloSnp = safeInt8Clamp(((itsCopy.getSnp() + tpcCopy.getSnp()) * 0.5f - gloCopy.getSnp()) * scaleGlo(2));
2749 trackQAHolder.dRefGloTgl = safeInt8Clamp(((itsCopy.getTgl() + tpcCopy.getTgl()) * 0.5f - gloCopy.getTgl()) * scaleGlo(3));
2750 trackQAHolder.dRefGloQ2Pt = safeInt8Clamp(((itsCopy.getQ2Pt() + tpcCopy.getQ2Pt()) * 0.5f - gloCopy.getQ2Pt()) * scaleGlo(4));
2754 (*mStreamer) <<
"trackQA"
2755 <<
"trackITSOrig=" << itsOrig
2756 <<
"trackTPCOrig=" << tpcOrig
2757 <<
"trackITSTPCOrig=" << trackPar
2758 <<
"trackITSProp=" << itsCopy
2759 <<
"trackTPCProp=" << tpcCopy
2760 <<
"trackITSTPCProp=" << gloCopy
2763 <<
"scaleCont0=" << scaleCont(0)
2764 <<
"scaleCont1=" << scaleCont(1)
2765 <<
"scaleCont2=" << scaleCont(2)
2766 <<
"scaleCont3=" << scaleCont(3)
2767 <<
"scaleCont4=" << scaleCont(4)
2768 <<
"scaleGlo0=" << scaleGlo(0)
2769 <<
"scaleGlo1=" << scaleGlo(1)
2770 <<
"scaleGlo2=" << scaleGlo(2)
2771 <<
"scaleGlo3=" << scaleGlo(3)
2772 <<
"scaleGlo4=" << scaleGlo(4)
2773 <<
"trackQAHolder.tpcTime0=" << trackQAHolder.tpcTime0
2774 <<
"trackQAHolder.tpcdEdxNorm=" << trackQAHolder.tpcdEdxNorm
2775 <<
"trackQAHolder.tpcdcaR=" << trackQAHolder.tpcdcaR
2776 <<
"trackQAHolder.tpcdcaZ=" << trackQAHolder.tpcdcaZ
2777 <<
"trackQAHolder.tpcdcaClusterByteMask=" << trackQAHolder.tpcClusterByteMask
2778 <<
"trackQAHolder.tpcdEdxMax0R=" << trackQAHolder.tpcdEdxMax0R
2779 <<
"trackQAHolder.tpcdEdxMax1R=" << trackQAHolder.tpcdEdxMax1R
2780 <<
"trackQAHolder.tpcdEdxMax2R=" << trackQAHolder.tpcdEdxMax2R
2781 <<
"trackQAHolder.tpcdEdxMax3R=" << trackQAHolder.tpcdEdxMax3R
2782 <<
"trackQAHolder.tpcdEdxTot0R=" << trackQAHolder.tpcdEdxTot0R
2783 <<
"trackQAHolder.tpcdEdxTot1R=" << trackQAHolder.tpcdEdxTot1R
2784 <<
"trackQAHolder.tpcdEdxTot2R=" << trackQAHolder.tpcdEdxTot2R
2785 <<
"trackQAHolder.tpcdEdxTot3R=" << trackQAHolder.tpcdEdxTot3R
2786 <<
"trackQAHolder.dRefContY=" << trackQAHolder.dRefContY
2787 <<
"trackQAHolder.dRefContZ=" << trackQAHolder.dRefContZ
2788 <<
"trackQAHolder.dRefContSnp=" << trackQAHolder.dRefContSnp
2789 <<
"trackQAHolder.dRefContTgl=" << trackQAHolder.dRefContTgl
2790 <<
"trackQAHolder.dRefContQ2Pt=" << trackQAHolder.dRefContQ2Pt
2791 <<
"trackQAHolder.dRefGloY=" << trackQAHolder.dRefGloY
2792 <<
"trackQAHolder.dRefGloZ=" << trackQAHolder.dRefGloZ
2793 <<
"trackQAHolder.dRefGloSnp=" << trackQAHolder.dRefGloSnp
2794 <<
"trackQAHolder.dRefGloTgl=" << trackQAHolder.dRefGloTgl
2795 <<
"trackQAHolder.dRefGloQ2Pt=" << trackQAHolder.dRefGloQ2Pt
2796 <<
"trackQAHolder.dTofdX=" << trackQAHolder.dTofdX
2797 <<
"trackQAHolder.dTofdZ=" << trackQAHolder.dTofdZ
2798 <<
"scaleTOF=" << scaleTOF
2805 return trackQAHolder;
2813 dcaInfo.set(999.f, 999.f, 999.f, 999.f, 999.f);
2818void AODProducerWorkflowDPL::extrapolateToCalorimeters(TrackExtraInfo& extraInfoHolder,
const o2::track::TrackPar& track)
2820 constexpr float XEMCAL = 440.f, XPHOS = 460.f, XEMCAL2 = XEMCAL * XEMCAL;
2821 constexpr float ETAEMCAL = 0.75;
2822 constexpr float ZEMCALFastCheck = 460.;
2823 constexpr float ETADCALINNER = 0.22;
2824 constexpr float ETAPHOS = 0.13653194;
2825 constexpr float ETAPHOSMARGIN = 0.17946979;
2826 constexpr float ETADCALPHOSSWITCH = (ETADCALINNER + ETAPHOS) / 2;
2827 constexpr short SNONE = 0, SEMCAL = 0x1, SPHOS = 0x2;
2828 constexpr short SECTORTYPE[18] = {
2829 SNONE, SNONE, SNONE, SNONE,
2830 SEMCAL, SEMCAL, SEMCAL, SEMCAL, SEMCAL, SEMCAL,
2833 SPHOS | SEMCAL, SPHOS | SEMCAL, SPHOS | SEMCAL,
2844 (std::abs(outTr.getZAt(xtrg, 0)) > ZEMCALFastCheck) ||
2845 !prop->PropagateToXBxByBz(outTr, xtrg, 0.95, 10, o2::base::Propagator::MatCorrType::USEMatCorrLUT)) {
2846 LOGP(
debug,
"preliminary step: does not reach R={} {}", XEMCAL, outTr.asString());
2850 if ((outTr.getX() * outTr.getX() + outTr.getY() * outTr.getY() < XEMCAL2) &&
2851 (!outTr.rotateParam(outTr.getPhi()) ||
2853 !prop->PropagateToXBxByBz(outTr, xtrg, 0.95, 10, o2::base::Propagator::MatCorrType::USEMatCorrLUT))) {
2854 LOGP(
debug,
"does not reach R={} {}", XEMCAL, outTr.asString());
2860 auto propExactSector = [&outTr, §or, prop](
float xprop) ->
bool {
2863 auto outTrTmp = outTr;
2865 if ((std::abs(outTr.getZ()) > ZEMCALFastCheck) || !outTrTmp.rotateParam(
alpha) ||
2866 !prop->PropagateToXBxByBz(outTrTmp, xprop, 0.95, 10, o2::base::Propagator::MatCorrType::USEMatCorrLUT)) {
2867 LOGP(
debug,
"failed on rotation to {} (sector {}) or propagation to X={} {}",
alpha, sector, xprop, outTrTmp.asString());
2872 if (sectorTmp == sector) {
2880 LOGP(
debug,
"failed to rotate to sector, {}", outTr.asString());
2887 if (!propExactSector(XEMCAL) || SECTORTYPE[sector] == SNONE) {
2892 float r = std::sqrt(outTr.getX() * outTr.getX() + outTr.getY() * outTr.getY()), tg = std::atan2(
r, outTr.getZ());
2893 float eta = -std::log(std::tan(0.5f * tg)), etaAbs = std::abs(eta);
2894 if (etaAbs > ETAEMCAL) {
2895 LOGP(
debug,
"eta = {} is off at EMCAL radius", eta, outTr.asString());
2899 if ((SECTORTYPE[sector] & SPHOS) && etaAbs < ETADCALPHOSSWITCH) {
2900 if (!propExactSector(XPHOS)) {
2903 r = std::sqrt(outTr.getX() * outTr.getX() + outTr.getY() * outTr.getY());
2904 tg = std::atan2(
r, outTr.getZ());
2905 eta = -std::log(std::tan(0.5f * tg));
2906 }
else if (!(SECTORTYPE[sector] & SEMCAL)) {
2909 extraInfoHolder.trackPhiEMCAL = outTr.getPhiPos();
2910 extraInfoHolder.trackEtaEMCAL = eta;
2911 LOGP(
debug,
"eta = {} phi = {} sector {} for {}", extraInfoHolder.trackEtaEMCAL, extraInfoHolder.trackPhiEMCAL, sector, outTr.asString());
2915std::set<uint64_t> AODProducerWorkflowDPL::filterEMCALIncomplete(
const gsl::span<const o2::emcal::TriggerRecord> triggers)
2917 std::set<uint64_t> emcalIncompletes;
2918 for (
const auto& trg : triggers) {
2919 if (trg.getTriggerBits() & o2::emcal::triggerbits::Inc) {
2921 emcalIncompletes.insert(trg.getBCData().toLong());
2924 return emcalIncompletes;
2930 static bool initOnceDone =
false;
2931 if (!initOnceDone) {
2932 initOnceDone =
true;
2939 for (
auto i = 0U;
i < bs.size();
i++) {
2954 mTPCBinNS = elParam.ZbinWidth * 1.e3;
2957 mNSigmaTimeTrack = pvParams.nSigmaTimeTrack;
2958 mTimeMarginTrackTime = pvParams.timeMarginTrackTime * 1.e3;
2979 LOG(info) <<
"ITS Alpide param updated";
2981 par.printKeyValues();
2985 LOG(info) <<
"MFT Alpide param updated";
2987 par.printKeyValues();
2998 mEMCALTrgClassMask = 0;
2999 for (
const auto& trgclass : ctpconfig.getCTPClasses()) {
3001 mEMCALTrgClassMask |= trgclass.classMask;
3004 LOG(info) <<
"Loaded EMCAL trigger class mask: " << std::bitset<64>(mEMCALTrgClassMask);
3008void AODProducerWorkflowDPL::addRefGlobalBCsForTOF(
const o2::dataformats::VtxTrackRef& trackRef,
const gsl::span<const GIndex>& GIndices,
3019 int nbitsFrac = 24 - (32 - o2::math_utils::popcount(mTrackTime));
3020 int nbitsLoss = std::max(0,
int(std::log2(TOFTimePrecPS)));
3021 assert(nbitsFrac > 1);
3022 std::uint64_t maxRangePS = std::uint64_t(0x1) << (nbitsFrac + nbitsLoss);
3024 LOG(info) <<
"Max gap of " << maxGapBC <<
" BCs to closest globalBC reference is needed for TOF tracks to provide precision of "
3025 << TOFTimePrecPS <<
" ps";
3028 if (!trackRef.getEntries()) {
3032 std::uint64_t maxBC = mStartIR.
toLong();
3033 const auto& tofClus =
data.getTOFClusters();
3040 for (
int ti =
start; ti <
end; ti++) {
3041 auto& trackIndex = GIndices[ti];
3042 const auto& tofMatch =
data.getTOFMatch(trackIndex);
3043 const auto& tofInt = tofMatch.getLTIntegralOut();
3044 float intLen = tofInt.getL();
3045 float tofExpMom = 0.;
3055 double massZ = o2::track::PID::getMass2Z(
data.getTrackParam(trackIndex).getPID());
3056 double energy = sqrt((massZ * massZ) + (tofExpMom * tofExpMom));
3057 double exp = intLen * energy / (cSpeed * tofExpMom);
3058 auto tofSignal = (tofMatch.getSignal() -
exp) * 1e-3;
3059 auto bc = relativeTime_to_GlobalBC(tofSignal);
3061 auto it = bcsMap.lower_bound(
bc);
3062 if (it == bcsMap.end() || it->first >
bc + maxGapBC) {
3063 bcsMap.emplace_hint(it,
bc, 1);
3072 if ((--bcsMap.end())->first <= maxBC) {
3073 bcsMap.emplace_hint(bcsMap.end(), maxBC + 1, 1);
3077 for (
auto& item : bcsMap) {
3083std::uint64_t AODProducerWorkflowDPL::fillBCSlice(
int (&slice)[2],
double tmin,
double tmax,
const std::map<uint64_t, int>& bcsMap)
const
3095 uint64_t bcMin = relativeTime_to_GlobalBC(tmin), bcMax = relativeTime_to_GlobalBC(tmax);
3118 auto upperindex =
p.first;
3119 while (upperindex < bcvector.size() && bcvector[upperindex] <= bcMax) {
3122 if (upperindex !=
p.first) {
3126 slice[1] = upperindex;
3128 auto bcOfTimeRef =
p.second - this->mStartIR.
toLong();
3129 LOG(
debug) <<
"BC slice t:" << tmin <<
" " << slice[0]
3130 <<
" t: " << tmax <<
" " << slice[1]
3131 <<
" bcref: " << bcOfTimeRef;
3137 std::vector<uint8_t>
flags(bcsMap.size());
3140 auto bcIt = bcsMap.begin();
3141 auto itsrofs =
data.getITSTracksROFRecords();
3144 for (
auto& rof : itsrofs) {
3145 if (!rof.getFlag(o2::itsmft::ROFRecord::VtxUPCMode)) {
3148 uint64_t globalBC0 = rof.getBCData().toLong() + bROF, globalBC1 = globalBC0 + lROF - 1;
3150 while (bcIt != bcsMap.end()) {
3151 if (bcIt->first < globalBC0) {
3155 if (bcIt->first > globalBC1) {
3167 LOGF(info,
"aod producer dpl total timing: Cpu: %.3e Real: %.3e s in %d slots",
3168 mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1);
3175 auto dataRequest = std::make_shared<DataRequest>();
3176 dataRequest->inputs.emplace_back(
"ctpconfig",
"CTP",
"CTPCONFIG", 0, Lifetime::Condition,
ccdbParamSpec(
"CTP/Config/Config", CTPConfigPerRun));
3178 dataRequest->requestTracks(
src, useMC);
3179 dataRequest->requestPrimaryVertices(useMC);
3181 dataRequest->requestCTPDigits(useMC);
3184 dataRequest->requestSecondaryVertices(useMC);
3186 if (enableStrangenessTracking) {
3187 dataRequest->requestStrangeTracks(useMC);
3188 LOGF(info,
"requestStrangeTracks Finish");
3197 dataRequest->requestTOFClusters(useMC);
3200 dataRequest->requestPHOSCells(useMC);
3203 dataRequest->requestTRDTracklets(
false);
3206 dataRequest->requestEMCALCells(useMC);
3209 dataRequest->requestCPVClusters(useMC);
3212 auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(
true,
3218 dataRequest->inputs,
3221 dataRequest->inputs.emplace_back(
"meanvtx",
"GLO",
"MEANVERTEX", 0, Lifetime::Condition,
ccdbParamSpec(
"GLO/Calib/MeanVertex", {}, 1));
3226 std::vector<OutputSpec> outputs{
3266 outputs.insert(outputs.end(),
3267 {OutputForTable<McCollisions>::spec(),
3268 OutputForTable<HepMCXSections>::spec(),
3269 OutputForTable<HepMCPdfInfos>::spec(),
3270 OutputForTable<HepMCHeavyIons>::spec(),
3271 OutputForTable<McMFTTrackLabels>::spec(),
3272 OutputForTable<McFwdTrackLabels>::spec(),
3273 OutputForTable<StoredMcParticles_001>::spec(),
3274 OutputForTable<McTrackLabels>::spec(),
3275 OutputForTable<McCaloLabels_001>::spec(),
3280 {OutputLabel{
"McCollisionLabels"},
"AOD",
"MCCOLLISIONLABEL", 0, Lifetime::Timeframe}});
3284 "aod-producer-workflow",
3287 AlgorithmSpec{adaptFromTask<AODProducerWorkflowDPL>(
src, dataRequest, ggRequest, enableSV, useMC, enableFITextra)},
3289 ConfigParamSpec{
"run-number", VariantType::Int64, -1L, {
"The run-number. If left default we try to get it from DPL header."}},
3290 ConfigParamSpec{
"aod-timeframe-id", VariantType::Int64, -1L, {
"Set timeframe number"}},
3291 ConfigParamSpec{
"fill-calo-cells", VariantType::Int, 1, {
"Fill calo cells into cell table"}},
3292 ConfigParamSpec{
"enable-truncation", VariantType::Int, 1, {
"Truncation parameter: 1 -- on, != 1 -- off"}},
3293 ConfigParamSpec{
"lpmp-prod-tag", VariantType::String,
"", {
"LPMProductionTag"}},
3294 ConfigParamSpec{
"anchor-pass", VariantType::String,
"", {
"AnchorPassName"}},
3295 ConfigParamSpec{
"anchor-prod", VariantType::String,
"", {
"AnchorProduction"}},
3296 ConfigParamSpec{
"reco-pass", VariantType::String,
"", {
"RecoPassName"}},
3297 ConfigParamSpec{
"created-by", VariantType::String,
"", {
"Who created this AO2D"}},
3298 ConfigParamSpec{
"nthreads", VariantType::Int, std::max(1,
int(std::thread::hardware_concurrency() / 2)), {
"Number of threads"}},
3299 ConfigParamSpec{
"reco-mctracks-only", VariantType::Int, 0, {
"Store only reconstructed MC tracks and their mothers/daughters. 0 -- off, != 0 -- on"}},
3300 ConfigParamSpec{
"ctpreadout-create", VariantType::Int, 0, {
"Create CTP digits from detector readout and CTP inputs. !=1 -- off, 1 -- on"}},
3301 ConfigParamSpec{
"emc-select-leading", VariantType::Bool,
false, {
"Flag to select if only the leading contributing particle for an EMCal cell should be stored"}},
3302 ConfigParamSpec{
"propagate-tracks", VariantType::Bool,
false, {
"Propagate tracks (not used for secondary vertices) to IP"}},
3303 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)"}},
3304 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)"}},
3305 ConfigParamSpec{
"propagate-muons", VariantType::Bool,
false, {
"Propagate muons to IP"}},
3306 ConfigParamSpec{
"thin-tracks", VariantType::Bool,
false, {
"Produce thinned track tables"}},
3307 ConfigParamSpec{
"trackqc-fraction", VariantType::Float, float(0.1), {
"Fraction of tracks to QC"}},
3308 ConfigParamSpec{
"trackqc-NTrCut", VariantType::Int64, 4L, {
"Minimal length of the track - in amount of tracklets"}},
3309 ConfigParamSpec{
"trackqc-tpc-dca", VariantType::Float, 3.f, {
"Keep TPC standalone track with this DCAxy to the PV"}},
3310 ConfigParamSpec{
"trackqc-tpc-cls", VariantType::Int, 80, {
"Keep TPC standalone track with this #clusters"}},
3311 ConfigParamSpec{
"trackqc-tpc-pt", VariantType::Float, 0.2f, {
"Keep TPC standalone track with this pt"}},
3312 ConfigParamSpec{
"with-streamers", VariantType::String,
"", {
"Bit-mask to steer writing of intermediate streamer files"}},
3313 ConfigParamSpec{
"seed", VariantType::Int, 0, {
"Set seed for random generator used for sampling (0 (default) means using a random_device)"}},
Class to refer to the reconstructed information.
Definition of the 32 Central Trigger System (CTS) Trigger Types defined in https://twiki....
General auxilliary methods.
uint64_t exp(uint64_t base, uint8_t exp) noexcept
definition of CTPDigit, CTPInputDigit
Header of the AggregatedRunInfo struct.
Global Forward Muon tracks.
Global index for barrel track: provides provenance (detectors combination), index in respective array...
Definition of the MCTrack class.
Definition of a container to keep Monte Carlo truth external to simulation objects.
Utility functions for MC particles.
Class to perform MFT MCH (and MID) matching.
Class to store the output of the matching to HMPID.
Class to perform TOF matching to global tracks.
Definition of the parameter class for the detector electronics.
Header to collect physics constants.
Definition of the FDD RecPoint class.
Definition of the ITS track.
Definition of the MUON track.
Definition of the MCH track.
Definition of the MCH track parameters for internal use.
Result of refitting TPC-ITS matched track.
Extention of GlobalTrackID by flags relevant for verter-track association.
Referenc on track indices contributing to the vertex, with possibility chose tracks from specific sou...
Container class to store energy released in the ZDC.
Container class to store a TDC hit in a ZDC channel.
const auto & getBCPattern() const
void GetStartVertex(TVector3 &vertex) const
void endOfStream(framework::EndOfStreamContext &ec) final
This is invoked whenever we have an EndOfStream event.
void finaliseCCDB(ConcreteDataMatcher &matcher, void *obj) final
void run(ProcessingContext &pc) final
void init(InitContext &ic) final
std::pair< size_t, uint64_t > lower_bound(uint64_t timestamp) const
void init(std::map< uint64_t, int > const &bcs)
initialize this container (to be ready for lookup/search queries)
void clear()
clear/reset this container
std::vector< uint64_t > const & getBCTimeVector() const
return the sorted vector of increaing BC times
static float getAmplitude(const o2::emcal::Cell &cell)
static int16_t getLnAmplitude(const o2::emcal::Cell &)
static int8_t getTriggerBits(const o2::emcal::Cell &)
static int16_t getCellNumber(const o2::emcal::Cell &cell)
static int16_t getFastOrAbsID(const o2::emcal::Cell &)
static bool isTRU(const o2::emcal::Cell &cell)
static float getTimeStamp(const o2::emcal::Cell &cell)
void checkUpdates(o2::framework::ProcessingContext &pc)
static GRPGeomHelper & instance()
void setRequest(std::shared_ptr< GRPGeomRequest > req)
static constexpr float MAX_SIN_PHI
static constexpr float MAX_STEP
GPUd() value_type estimateLTFast(o2 static GPUd() float estimateLTIncrement(const o2 PropagatorImpl * Instance(bool uninitialized=false)
static const DPLAlpideParam< N > & Instance()
void printStream(std::ostream &stream) const
Static class with identifiers, bitmasks and names for ALICE detectors.
Handler for EMCAL event data.
void reset()
Reset containers with empty ranges.
void setCellData(CellRange cells, TriggerRange triggers)
Setting the data at cell level.
void setCellMCTruthContainer(const o2::dataformats::MCTruthContainer< o2::emcal::MCLabel > *mclabels)
Setting the pointer for the MCTruthContainer for cells.
InteractionRecord getInteractionRecordForEvent(int eventID) const
Get the interaction record for the given event.
int getNumberOfEvents() const
Get the number of events handled by the event handler.
T get(const char *key) const
void snapshot(const Output &spec, T const &object)
ConfigParamRegistry const & options()
DataAllocator & outputs()
The data allocator is used to allocate memory for the output data.
InputRecord & inputs()
The inputs associated with this processing context.
ServiceRegistryRef services()
The services registry associated with this processing context.
static constexpr int NCellsA
o2::dataformats::GlobalFwdTrack MCHtoFwd(const o2::mch::TrackParam &mchTrack)
Converts mchTrack parameters to Forward coordinate system.
track parameters for internal use
Double_t getNonBendingCoor() const
return non bending coordinate (cm)
Double_t getBendingCoor() const
return bending coordinate (cm)
void setCellMCTruthContainer(const o2::dataformats::MCTruthContainer< o2::phos::MCLabel > *mclabels)
Setting the pointer for the MCTruthContainer for cells.
void setCellData(CellRange cells, TriggerRange triggers)
Setting the data at cell level.
void reset()
Reset containers with empty ranges.
InteractionRecord getInteractionRecordForEvent(int eventID) const
int getNumberOfEvents() const
MCTrack const * getTrack(o2::MCCompLabel const &) const
void releaseTracksForSourceAndEvent(int source, int event)
API to ask releasing tracks (freeing memory) for source + event.
std::vector< MCTrack > const & getTracks(int source, int event) const
variant returning all tracks for source and event at once
static void addInteractionBC(int bc, bool fromCollisonCotext=false)
void set(const std::string &s="", int base=2)
bool match(const std::vector< std::string > &queries, const char *pattern)
GLfloat GLfloat GLfloat alpha
GLint GLint GLsizei GLuint * counters
GLuint GLuint GLfloat weight
GLboolean GLboolean GLboolean b
GLsizei GLsizei GLchar * source
GLsizei const GLfloat * value
GLint GLint GLsizei GLint GLenum GLenum type
GLenum GLsizei GLsizei GLint * values
GLuint GLsizei const GLchar * label
GLboolean GLboolean GLboolean GLboolean a
constexpr std::array< float, 2 > trackQAScaledTOF
constexpr std::array< float, 5 > trackQAScaleContP1
uint8_t itsSharedClusterMap uint8_t
constexpr std::array< float, 5 > trackQAScaleContP0
constexpr std::array< float, 5 > trackQAScaleGloP0
constexpr std::array< float, 5 > trackQAScaleGloP1
constexpr float trackQAScaleBins
constexpr float trackQARefRadius
bool updateHepMCHeavyIon(const HeavyIonCursor &cursor, int collisionID, short generatorID, o2::dataformats::MCEventHeader const &header, HepMCUpdate when=HepMCUpdate::anyKey)
short updateMCCollisions(const CollisionCursor &cursor, int bcId, float time, o2::dataformats::MCEventHeader const &header, short generatorId=0, int sourceId=0, unsigned int mask=0xFFFFFFF0)
bool updateHepMCPdfInfo(const PdfInfoCursor &cursor, int collisionID, short generatorID, o2::dataformats::MCEventHeader const &header, HepMCUpdate when=HepMCUpdate::anyKey)
uint32_t updateParticles(const ParticleCursor &cursor, int collisionID, std::vector< MCTrack > const &tracks, TrackToIndex &preselect, uint32_t offset=0, bool filter=false, bool background=false, uint32_t weightMask=0xFFFFFFF0, uint32_t momentumMask=0xFFFFFFF0, uint32_t positionMask=0xFFFFFFF0)
bool updateHepMCXSection(const XSectionCursor &cursor, int collisionID, short generatorID, o2::dataformats::MCEventHeader const &header, HepMCUpdate when=HepMCUpdate::anyKey)
void keepMCParticle(std::vector< std::vector< std::unordered_map< int, int > > > &store, int source, int event, int track, int value=1)
framework::DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool enableSV, bool enableST, bool useMC, bool CTPConfigPerRun, bool enableFITextra)
create a processor spec
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