89#include "Math/SMatrix.h"
95#include <unordered_map>
100#include "TLorentzVector.h"
108#include <nlohmann/json.hpp>
129 uint64_t classMaskEMCAL = 0, classMaskTRD = 0, classMaskPHOSCPV = 0;
130 for (
const auto& trgclass : ctpcfg->getCTPClasses()) {
131 if (trgclass.cluster->getClusterDetNames().find(
"EMC") != std::string::npos) {
132 classMaskEMCAL = trgclass.classMask;
134 if (trgclass.cluster->getClusterDetNames().find(
"PHS") != std::string::npos) {
135 classMaskPHOSCPV = trgclass.classMask;
137 if (trgclass.cluster->getClusterDetNames().find(
"TRD") != std::string::npos) {
138 classMaskTRD = trgclass.classMask;
141 LOG(info) <<
"createCTPReadout: Class Mask EMCAL -> " << classMaskEMCAL;
142 LOG(info) <<
"createCTPReadout: Class Mask PHOS/CPV -> " << classMaskPHOSCPV;
143 LOG(info) <<
"createCTPReadout: Class Mask TRD -> " << classMaskTRD;
151 std::vector<o2::emcal::TriggerRecord> triggerRecordEMCALPhys;
152 for (
const auto& trg : triggerrecordEMCAL) {
156 triggerRecordEMCALPhys.push_back(trg);
162 std::set<uint64_t> bcsMapT0triggers;
164 for (
auto& ft0RecPoint : ft0RecPoints) {
165 auto t0triggers = ft0RecPoint.getTrigger();
166 if (t0triggers.getVertex()) {
167 uint64_t globalBC = ft0RecPoint.getInteractionRecord().toLong();
168 bcsMapT0triggers.insert(globalBC);
172 auto genericCTPDigitizer = [&bcsMapT0triggers, &ctpDigits](
auto triggerrecords, uint64_t classmask) ->
int {
176 uint32_t orbitPrev = 0;
178 for (
auto& trigger : triggerrecords) {
179 auto orbitPrevT = orbitPrev;
180 auto bcPrevT = bcPrev;
181 bcPrev = trigger.getBCData().bc;
182 orbitPrev = trigger.getBCData().orbit;
188 uint64_t globalBC = trigger.getBCData().toLong();
189 auto t0entry = bcsMapT0triggers.find(globalBC);
190 if (t0entry != bcsMapT0triggers.end()) {
191 auto ctpdig = std::find_if(ctpDigits.begin(), ctpDigits.end(), [globalBC](
const o2::ctp::CTPDigit& dig) { return static_cast<uint64_t>(dig.intRecord.toLong()) == globalBC; });
192 if (ctpdig != ctpDigits.end()) {
194 ctpdig->CTPClassMask |= std::bitset<64>(classmask);
195 LOG(
debug) <<
"createCTPReadout: Merging " << classmask <<
" CTP digits with existing digit, CTP mask " << ctpdig->CTPClassMask;
198 LOG(
debug) <<
"createCTPReadout: New CTP digit needed for class " << classmask << std::endl;
199 auto& ctpdigNew = ctpDigits.emplace_back();
200 ctpdigNew.intRecord.setFromLong(globalBC);
201 ctpdigNew.CTPClassMask = classmask;
204 LOG(warning) <<
"createCTPReadout: Found " << classmask <<
" and no MTVX:" << globalBC;
211 auto warningsTRD = genericCTPDigitizer(triggerrecordTRD, classMaskTRD);
212 auto warningsEMCAL = genericCTPDigitizer(triggerRecordEMCALPhys, classMaskEMCAL);
213 auto warningsPHOSCPV = genericCTPDigitizer(triggerrecordPHOSCPV, classMaskPHOSCPV);
215 LOG(info) <<
"createCTPReadout:# of TRD bogus triggers:" << warningsTRD;
216 LOG(info) <<
"createCTPReadout:# of EMCAL bogus triggers:" << warningsEMCAL;
217 LOG(info) <<
"createCTPReadout:# of PHOS/CPV bogus triggers:" << warningsPHOSCPV;
221 const std::vector<o2::InteractionTimeRecord>& mcRecords,
222 std::map<uint64_t, int>& bcsMap)
224 const auto& primVertices =
data.getPrimaryVertices();
225 const auto& fddRecPoints =
data.getFDDRecPoints();
226 const auto& ft0RecPoints =
data.getFT0RecPoints();
227 const auto& fv0RecPoints =
data.getFV0RecPoints();
228 const auto& caloEMCCellsTRGR =
data.getEMCALTriggers();
229 const auto& caloPHOSCellsTRGR =
data.getPHOSTriggers();
230 const auto& cpvTRGR =
data.getCPVTriggers();
231 const auto& ctpDigits =
data.getCTPDigits();
232 const auto& zdcBCRecData =
data.getZDCBCRecData();
234 bcsMap[mStartIR.
toLong()] = 1;
237 for (
auto&
rec : mcRecords) {
238 uint64_t globalBC =
rec.toLong();
239 bcsMap[globalBC] = 1;
242 for (
auto& fddRecPoint : fddRecPoints) {
243 uint64_t globalBC = fddRecPoint.getInteractionRecord().toLong();
244 bcsMap[globalBC] = 1;
247 for (
auto& ft0RecPoint : ft0RecPoints) {
248 uint64_t globalBC = ft0RecPoint.getInteractionRecord().toLong();
249 bcsMap[globalBC] = 1;
252 for (
auto& fv0RecPoint : fv0RecPoints) {
253 uint64_t globalBC = fv0RecPoint.getInteractionRecord().toLong();
254 bcsMap[globalBC] = 1;
257 for (
auto& zdcRecData : zdcBCRecData) {
258 uint64_t globalBC = zdcRecData.ir.toLong();
259 bcsMap[globalBC] = 1;
262 for (
auto&
vertex : primVertices) {
263 auto& timeStamp =
vertex.getTimeStamp();
264 double tsTimeStamp = timeStamp.getTimeStamp() * 1E3;
265 uint64_t globalBC = relativeTime_to_GlobalBC(tsTimeStamp);
266 bcsMap[globalBC] = 1;
269 for (
auto& emcaltrg : caloEMCCellsTRGR) {
270 uint64_t globalBC = emcaltrg.getBCData().toLong();
271 bcsMap[globalBC] = 1;
274 for (
auto& phostrg : caloPHOSCellsTRGR) {
275 uint64_t globalBC = phostrg.getBCData().toLong();
276 bcsMap[globalBC] = 1;
279 for (
auto& cpvtrg : cpvTRGR) {
280 uint64_t globalBC = cpvtrg.getBCData().toLong();
281 bcsMap[globalBC] = 1;
284 for (
auto& ctpDigit : ctpDigits) {
285 uint64_t globalBC = ctpDigit.intRecord.toLong();
286 bcsMap[globalBC] = 1;
290 for (
auto& item : bcsMap) {
296template <
typename TracksCursorType,
typename TracksCovCursorType>
297void AODProducerWorkflowDPL::addToTracksTable(TracksCursorType& tracksCursor, TracksCovCursorType& tracksCovCursor,
300 tracksCursor(collisionID,
302 truncateFloatFraction(track.getX(), mTrackX),
303 truncateFloatFraction(track.getAlpha(), mTrackAlpha),
306 truncateFloatFraction(track.getSnp(), mTrackSnp),
307 truncateFloatFraction(track.getTgl(), mTrackTgl),
308 truncateFloatFraction(track.getQ2Pt(), mTrack1Pt));
310 float sY = TMath::Sqrt(track.getSigmaY2()), sZ = TMath::Sqrt(track.getSigmaZ2()), sSnp = TMath::Sqrt(track.getSigmaSnp2()),
311 sTgl = TMath::Sqrt(track.getSigmaTgl2()), sQ2Pt = TMath::Sqrt(track.getSigma1Pt2());
312 tracksCovCursor(truncateFloatFraction(sY, mTrackCovDiag),
313 truncateFloatFraction(sZ, mTrackCovDiag),
314 truncateFloatFraction(sSnp, mTrackCovDiag),
315 truncateFloatFraction(sTgl, mTrackCovDiag),
316 truncateFloatFraction(sQ2Pt, mTrackCovDiag),
317 (Char_t)(128. * track.getSigmaZY() / (sZ * sY)),
318 (Char_t)(128. * track.getSigmaSnpY() / (sSnp * sY)),
319 (Char_t)(128. * track.getSigmaSnpZ() / (sSnp * sZ)),
320 (Char_t)(128. * track.getSigmaTglY() / (sTgl * sY)),
321 (Char_t)(128. * track.getSigmaTglZ() / (sTgl * sZ)),
322 (Char_t)(128. * track.getSigmaTglSnp() / (sTgl * sSnp)),
323 (Char_t)(128. * track.getSigma1PtY() / (sQ2Pt * sY)),
324 (Char_t)(128. * track.getSigma1PtZ() / (sQ2Pt * sZ)),
325 (Char_t)(128. * track.getSigma1PtSnp() / (sQ2Pt * sSnp)),
326 (Char_t)(128. * track.getSigma1PtTgl() / (sQ2Pt * sTgl)));
329template <
typename TracksExtraCursorType>
330void AODProducerWorkflowDPL::addToTracksExtraTable(TracksExtraCursorType& tracksExtraCursor, TrackExtraInfo& extraInfoHolder)
334 auto trackTimeRes = extraInfoHolder.trackTimeRes;
335 if (!extraInfoHolder.isTPConly) {
336 trackTimeRes = truncateFloatFraction(trackTimeRes, mTrackTimeError);
340 tracksExtraCursor(truncateFloatFraction(extraInfoHolder.tpcInnerParam, mTrack1Pt),
341 extraInfoHolder.flags,
342 extraInfoHolder.itsClusterSizes,
343 extraInfoHolder.tpcNClsFindable,
344 extraInfoHolder.tpcNClsFindableMinusFound,
345 extraInfoHolder.tpcNClsFindableMinusPID,
346 extraInfoHolder.tpcNClsFindableMinusCrossedRows,
347 extraInfoHolder.tpcNClsShared,
348 extraInfoHolder.trdPattern,
349 truncateFloatFraction(extraInfoHolder.itsChi2NCl, mTrackChi2),
350 truncateFloatFraction(extraInfoHolder.tpcChi2NCl, mTrackChi2),
351 truncateFloatFraction(extraInfoHolder.trdChi2, mTrackChi2),
352 truncateFloatFraction(extraInfoHolder.tofChi2, mTrackChi2),
353 truncateFloatFraction(extraInfoHolder.tpcSignal, mTrackSignal),
354 truncateFloatFraction(extraInfoHolder.trdSignal, mTrackSignal),
355 truncateFloatFraction(extraInfoHolder.length, mTrackSignal),
356 truncateFloatFraction(extraInfoHolder.tofExpMom, mTrack1Pt),
357 truncateFloatFraction(extraInfoHolder.trackEtaEMCAL, mTrackPosEMCAL),
358 truncateFloatFraction(extraInfoHolder.trackPhiEMCAL, mTrackPosEMCAL),
359 truncateFloatFraction(extraInfoHolder.trackTime, mTrackTime),
363template <
typename TracksQACursorType>
364void AODProducerWorkflowDPL::addToTracksQATable(TracksQACursorType& tracksQACursor,
TrackQA& trackQAInfoHolder)
367 trackQAInfoHolder.trackID,
368 mTrackQCRetainOnlydEdx ? 0.0f : truncateFloatFraction(trackQAInfoHolder.tpcTime0, mTPCTime0),
369 truncateFloatFraction(trackQAInfoHolder.tpcdEdxNorm, mTrackSignal),
370 mTrackQCRetainOnlydEdx ? std::numeric_limits<int16_t>::min() : trackQAInfoHolder.tpcdcaR,
371 mTrackQCRetainOnlydEdx ? std::numeric_limits<int16_t>::min() : trackQAInfoHolder.tpcdcaZ,
372 trackQAInfoHolder.tpcClusterByteMask,
373 trackQAInfoHolder.tpcdEdxMax0R,
374 trackQAInfoHolder.tpcdEdxMax1R,
375 trackQAInfoHolder.tpcdEdxMax2R,
376 trackQAInfoHolder.tpcdEdxMax3R,
377 trackQAInfoHolder.tpcdEdxTot0R,
378 trackQAInfoHolder.tpcdEdxTot1R,
379 trackQAInfoHolder.tpcdEdxTot2R,
380 trackQAInfoHolder.tpcdEdxTot3R,
381 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefContY,
382 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefContZ,
383 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefContSnp,
384 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefContTgl,
385 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefContQ2Pt,
386 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefGloY,
387 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefGloZ,
388 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefGloSnp,
389 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefGloTgl,
390 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefGloQ2Pt,
391 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dTofdX,
392 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dTofdZ);
395template <
typename TRDsExtraCursorType>
398 int q0s[6] = {-1}, q1s[6] = {-1}, q2s[6] = {-1};
399 float q0sCor[6] = {-1}, q1sCor[6] = {-1}, q2sCor[6] = {-1};
400 float ttgls[6] = {-999}, tphis[6] = {-999};
410 for (
int iLay{0}; iLay < 6; ++iLay) {
411 q0s[iLay] = q1s[iLay] = q2s[iLay] = -1;
412 q0sCor[iLay] = q1sCor[iLay] = q2sCor[iLay] = -1;
413 tphis[iLay] = ttgls[iLay] = -999;
414 auto trkltId = trk.getTrackletIndex(iLay);
418 const auto& tracklet = trklets[trkltId];
423 int trkltDet = tracklet.getDetector();
424 int trkltSec = trkltDet / 30;
434 auto tphi = trkC.getSnp() / std::sqrt((1.f - trkC.getSnp()) * (1.f + trkC.getSnp()));
435 auto trackletLength = std::sqrt(1.f + tphi * tphi + trkC.getTgl() * trkC.getTgl());
437 q0s[iLay] = tracklet.getQ0();
438 q1s[iLay] = tracklet.getQ1();
439 q2s[iLay] = tracklet.getQ2();
440 q0sCor[iLay] = (float)tracklet.getQ0() / cor;
441 q1sCor[iLay] = (float)tracklet.getQ1() / cor;
442 q2sCor[iLay] = (float)tracklet.getQ2() / cor;
443 ttgls[iLay] = trkC.getTgl();
447 if (trk.getIsCrossingNeighbor(iLay) && trk.getHasNeighbor()) {
450 size_t trdSelID = -1;
452 const auto& trig = trigsTRD[mCurrentTRDTrigID];
453 bool foundTRDTrigger =
false;
455 if (trkltId >= trig.getFirstTracklet() && trkltId < trig.getFirstTracklet() + trig.getNumberOfTracklets()) {
456 trdSelID = mCurrentTRDTrigID;
457 foundTRDTrigger =
true;
460 if (mCurrentTRDTrigID < trigsTRD.size() - 1) {
461 const auto& trig = trigsTRD[mCurrentTRDTrigID + 1];
462 if (trkltId >= trig.getFirstTracklet() && trkltId < trig.getFirstTracklet() + trig.getNumberOfTracklets()) {
463 trdSelID = mCurrentTRDTrigID + 1;
464 foundTRDTrigger =
true;
469 size_t low = 0, up = trigsTRD.size() - 1;
472 while (low <= up && !foundTRDTrigger) {
473 trdSelID = low + std::floor((up - low) / 2);
474 const auto& trig = trigsTRD[trdSelID];
475 if (trig.getFirstTracklet() > trkltId) {
478 if (trig.getFirstTracklet() + trig.getNumberOfTracklets() <= trkltId) {
481 foundTRDTrigger =
true;
486 mCurrentTRDTrigID = trdSelID;
487 const auto& trigSel = trigsTRD[trdSelID];
490 for (
const auto& trklt : trklets.subspan(trigSel.getFirstTracklet(), trigSel.getNumberOfTracklets())) {
491 if (tracklet.getTrackletWord() == trklt.getTrackletWord() || tracklet.getDetector() != trklt.getDetector()) {
494 if (std::abs(tracklet.getPadCol() - trklt.getPadCol()) <= 1 && std::abs(tracklet.getPadRow() - trklt.getPadRow()) == 1) {
496 q0s[iLay] += trklt.getQ0();
497 q1s[iLay] += trklt.getQ1();
498 q2s[iLay] += trklt.getQ2();
499 q0sCor[iLay] += (float)trklt.getQ0() / cor;
500 q1sCor[iLay] += (float)trklt.getQ1() / cor;
501 q2sCor[iLay] += (float)trklt.getQ2() / cor;
507 trdExtraCursor(trkTableIdx, q0s, q1s, q2s, q0sCor, q1sCor, q2sCor, ttgls, tphis);
510template <
typename mftTracksCursorType,
typename mftTracksCovCursorType,
typename AmbigMFTTracksCursorType>
511void AODProducerWorkflowDPL::addToMFTTracksTable(mftTracksCursorType& mftTracksCursor, mftTracksCovCursorType& mftTracksCovCursor, AmbigMFTTracksCursorType& ambigMFTTracksCursor,
513 std::uint64_t collisionBC,
const std::map<uint64_t, int>& bcsMap)
516 int bcSlice[2] = {-1, -1};
517 const auto& track =
data.getMFTTrack(trackID);
518 const auto& rof =
data.getMFTTracksROFRecords()[mMFTROFs[trackID.getIndex()]];
520 float trackTimeRes = mMFTROFrameHalfLengthNS;
521 bool needBCSlice = collisionID < 0;
522 std::uint64_t bcOfTimeRef;
524 double error = mTimeMarginTrackTime + trackTimeRes;
525 bcOfTimeRef = fillBCSlice(bcSlice, trackTime - error, trackTime + error, bcsMap);
527 bcOfTimeRef = collisionBC - mStartIR.
toLong();
532 uint64_t mftClusterSizesAndTrackFlags = track.getClusterSizes();
533 mftClusterSizesAndTrackFlags |= (track.isCA()) ? (1ULL << (60)) : 0;
535 mftTracksCursor(collisionID,
538 truncateFloatFraction(track.getZ(), mTrackX),
539 truncateFloatFraction(track.getPhi(), mTrackAlpha),
540 truncateFloatFraction(track.getTanl(), mTrackTgl),
541 truncateFloatFraction(track.getInvQPt(), mTrack1Pt),
542 mftClusterSizesAndTrackFlags,
543 truncateFloatFraction(track.getTrackChi2(), mTrackChi2),
544 truncateFloatFraction(trackTime, mTrackTime),
545 truncateFloatFraction(trackTimeRes, mTrackTimeError));
546 if (mStoreAllMFTCov) {
547 float sX = TMath::Sqrt(track.getSigma2X());
548 float sY = TMath::Sqrt(track.getSigma2Y());
549 float sPhi = TMath::Sqrt(track.getSigma2Phi());
550 float sTgl = TMath::Sqrt(track.getSigma2Tanl());
551 float sQ2Pt = TMath::Sqrt(track.getSigma2InvQPt());
553 mftTracksCovCursor(mTableTrMFTID,
554 truncateFloatFraction(sX, mTrackCovDiag),
555 truncateFloatFraction(sY, mTrackCovDiag),
556 truncateFloatFraction(sPhi, mTrackCovDiag),
557 truncateFloatFraction(sTgl, mTrackCovDiag),
558 truncateFloatFraction(sQ2Pt, mTrackCovDiag),
559 (Char_t)(128. * track.getCovariances()(0, 1) / (sX * sY)),
560 (Char_t)(128. * track.getCovariances()(0, 2) / (sPhi * sX)),
561 (Char_t)(128. * track.getCovariances()(1, 2) / (sPhi * sY)),
562 (Char_t)(128. * track.getCovariances()(0, 3) / (sTgl * sX)),
563 (Char_t)(128. * track.getCovariances()(1, 3) / (sTgl * sY)),
564 (Char_t)(128. * track.getCovariances()(2, 3) / (sTgl * sPhi)),
565 (Char_t)(128. * track.getCovariances()(0, 4) / (sQ2Pt * sX)),
566 (Char_t)(128. * track.getCovariances()(1, 4) / (sQ2Pt * sY)),
567 (Char_t)(128. * track.getCovariances()(2, 4) / (sQ2Pt * sPhi)),
568 (Char_t)(128. * track.getCovariances()(3, 4) / (sQ2Pt * sTgl)));
571 ambigMFTTracksCursor(mTableTrMFTID, bcSlice);
574template <
typename TracksCursorType,
typename TracksCovCursorType,
typename TracksExtraCursorType,
typename TracksQACursorType,
typename TRDsExtraCursor,
typename AmbigTracksCursorType,
575 typename MFTTracksCursorType,
typename MFTTracksCovCursorType,
typename AmbigMFTTracksCursorType,
576 typename FwdTracksCursorType,
typename FwdTracksCovCursorType,
typename AmbigFwdTracksCursorType,
typename FwdTrkClsCursorType>
577void AODProducerWorkflowDPL::fillTrackTablesPerCollision(
int collisionID,
578 std::uint64_t collisionBC,
580 const gsl::span<const GIndex>& GIndices,
582 TracksCursorType& tracksCursor,
583 TracksCovCursorType& tracksCovCursor,
584 TracksExtraCursorType& tracksExtraCursor,
585 TracksQACursorType& tracksQACursor,
586 TRDsExtraCursor& trdsExtraCursor,
587 AmbigTracksCursorType& ambigTracksCursor,
588 MFTTracksCursorType& mftTracksCursor,
589 MFTTracksCovCursorType& mftTracksCovCursor,
590 AmbigMFTTracksCursorType& ambigMFTTracksCursor,
591 FwdTracksCursorType& fwdTracksCursor,
592 FwdTracksCovCursorType& fwdTracksCovCursor,
593 AmbigFwdTracksCursorType& ambigFwdTracksCursor,
594 FwdTrkClsCursorType& fwdTrkClsCursor,
595 const std::map<uint64_t, int>& bcsMap)
598 if (!GIndex::isTrackSource(
src)) {
605 mftTracksCursor.reserve(nToReserve + mftTracksCursor.lastIndex());
606 if (mStoreAllMFTCov) {
607 mftTracksCovCursor.reserve(nToReserve + mftTracksCovCursor.lastIndex());
610 fwdTracksCursor.reserve(nToReserve + fwdTracksCursor.lastIndex());
611 fwdTracksCovCursor.reserve(nToReserve + fwdTracksCovCursor.lastIndex());
613 mftTracksCovCursor.reserve(nToReserve + mftTracksCovCursor.lastIndex());
616 tracksCursor.reserve(nToReserve + tracksCursor.lastIndex());
617 tracksCovCursor.reserve(nToReserve + tracksCovCursor.lastIndex());
618 tracksExtraCursor.reserve(nToReserve + tracksExtraCursor.lastIndex());
620 for (
int ti =
start; ti <
end; ti++) {
621 const auto& trackIndex = GIndices[ti];
622 if (GIndex::includesSource(
src, mInputSources)) {
624 if (trackIndex.isAmbiguous() && mGIDToTableMFTID.find(trackIndex) != mGIDToTableMFTID.end()) {
627 addToMFTTracksTable(mftTracksCursor, mftTracksCovCursor, ambigMFTTracksCursor, trackIndex,
data, collisionID, collisionBC, bcsMap);
628 mGIDToTableMFTID.emplace(trackIndex, mTableTrMFTID);
631 if (trackIndex.isAmbiguous() && mGIDToTableFwdID.find(trackIndex) != mGIDToTableFwdID.end()) {
634 addToFwdTracksTable(fwdTracksCursor, fwdTracksCovCursor, ambigFwdTracksCursor, mftTracksCovCursor, trackIndex,
data, collisionID, collisionBC, bcsMap);
635 mGIDToTableFwdID.emplace(trackIndex, mTableTrFwdID);
636 addClustersToFwdTrkClsTable(
data, fwdTrkClsCursor, trackIndex, mTableTrFwdID);
640 if (trackIndex.isAmbiguous() && mGIDToTableID.find(trackIndex) != mGIDToTableID.end()) {
645 static std::uniform_real_distribution<>
distr(0., 1.);
647 auto extraInfoHolder = processBarrelTrack(collisionID, collisionBC, trackIndex,
data, bcsMap);
650 auto trackQAInfoHolder = processBarrelTrackQA(collisionID, collisionBC, trackIndex,
data, bcsMap);
651 if (std::bitset<8>(trackQAInfoHolder.tpcClusterByteMask).count() >= mTrackQCNTrCut) {
652 trackQAInfoHolder.trackID = mTableTrID;
656 addToTracksQATable(tracksQACursor, trackQAInfoHolder);
663 if (mThinTracks && extraInfoHolder.isTPConly && !writeQAData) {
664 auto trk =
data.getTPCTrack(trackIndex);
665 if (trk.getNClusters() >= mTrackQCNCls && trk.getPt() >= mTrackQCPt) {
675 if (mThinTracks &&
src ==
GIndex::Source::TPC && mGIDUsedBySVtx.find(trackIndex) == mGIDUsedBySVtx.end() && mGIDUsedByStr.find(trackIndex) == mGIDUsedByStr.end() && !writeQAData) {
676 mGIDToTableID.emplace(trackIndex, -1);
680 if (!extraInfoHolder.isTPConly && extraInfoHolder.trackTimeRes < 0.f) {
681 LOG(warning) <<
"Barrel track " << trackIndex <<
" has no time set, rejection is not expected : time=" << extraInfoHolder.trackTime
682 <<
" timeErr=" << extraInfoHolder.trackTimeRes <<
" BCSlice: " << extraInfoHolder.bcSlice[0] <<
":" << extraInfoHolder.bcSlice[1];
685 const auto& trOrig =
data.getTrackParam(trackIndex);
687 if (mPropTracks && trOrig.getX() < mMaxPropXiu &&
688 mGIDUsedBySVtx.find(trackIndex) == mGIDUsedBySVtx.end() &&
689 mGIDUsedByStr.find(trackIndex) == mGIDUsedByStr.end()) {
690 auto trackPar(trOrig);
691 isProp = propagateTrackToPV(trackPar,
data, collisionID);
693 addToTracksTable(tracksCursor, tracksCovCursor, trackPar, collisionID,
aod::track::Track);
699 addToTracksExtraTable(tracksExtraCursor, extraInfoHolder);
701 addToTRDsExtra(
data, trdsExtraCursor, trackIndex, mTableTrID);
704 if (extraInfoHolder.bcSlice[0] >= 0 && collisionID < 0) {
705 ambigTracksCursor(mTableTrID, extraInfoHolder.bcSlice);
707 mGIDToTableID.emplace(trackIndex, mTableTrID);
713 if (collisionID < 0) {
717 auto sTracks =
data.getStrangeTracks();
718 tracksCursor.reserve(mVertexStrLUT[collisionID + 1] + tracksCursor.lastIndex());
719 tracksCovCursor.reserve(mVertexStrLUT[collisionID + 1] + tracksCovCursor.lastIndex());
720 tracksExtraCursor.reserve(mVertexStrLUT[collisionID + 1] + tracksExtraCursor.lastIndex());
721 for (
int iS{mVertexStrLUT[collisionID]}; iS < mVertexStrLUT[collisionID + 1]; ++iS) {
722 auto& collStrTrk = mCollisionStrTrk[iS];
723 auto& sTrk = sTracks[collStrTrk.second];
724 TrackExtraInfo extraInfo;
725 extraInfo.itsChi2NCl = sTrk.mTopoChi2;
726 extraInfo.itsClusterSizes = sTrk.getClusterSizes();
728 addToTracksExtraTable(tracksExtraCursor, extraInfo);
729 mStrTrkIndices[collStrTrk.second] = mTableTrID;
736 const auto& mchmidMatches =
data.getMCHMIDMatches();
741 for (
int ti =
start; ti <
end; ti++) {
742 auto& trackIndex = GIndices[ti];
743 if (GIndex::includesSource(
src, mInputSources)) {
745 if (trackIndex.isAmbiguous() && mGIDToTableMFTID.find(trackIndex) != mGIDToTableMFTID.end()) {
748 mGIDToTableMFTID.emplace(trackIndex, mIndexMFTID);
749 mIndexTableMFT[trackIndex.getIndex()] = mIndexMFTID;
752 if (trackIndex.isAmbiguous() && mGIDToTableFwdID.find(trackIndex) != mGIDToTableFwdID.end()) {
755 mGIDToTableFwdID.emplace(trackIndex, mIndexFwdID);
757 mIndexTableFwd[trackIndex.getIndex()] = mIndexFwdID;
759 const auto& mchmidMatch = mchmidMatches[trackIndex.getIndex()];
760 const auto mchTrackID = mchmidMatch.getMCHRef().getIndex();
761 mIndexTableFwd[mchTrackID] = mIndexFwdID;
770template <
typename FwdTracksCursorType,
typename FwdTracksCovCursorType,
typename AmbigFwdTracksCursorType,
typename mftTracksCovCursorType>
771void AODProducerWorkflowDPL::addToFwdTracksTable(FwdTracksCursorType& fwdTracksCursor, FwdTracksCovCursorType& fwdTracksCovCursor,
772 AmbigFwdTracksCursorType& ambigFwdTracksCursor, mftTracksCovCursorType& mftTracksCovCursor,
GIndex trackID,
774 const std::map<uint64_t, int>& bcsMap)
776 const auto& mchTracks =
data.getMCHTracks();
777 const auto& midTracks =
data.getMIDTracks();
778 const auto& mchmidMatches =
data.getMCHMIDMatches();
779 const auto& mchClusters =
data.getMCHTrackClusters();
781 FwdTrackInfo fwdInfo;
782 FwdTrackCovInfo fwdCovInfo;
783 int bcSlice[2] = {-1, -1};
786 auto getMCHBitMap = [&](
int mchTrackID) {
787 if (mchTrackID != -1) {
788 const auto& mchTrack = mchTracks[mchTrackID];
789 int first = mchTrack.getFirstClusterIdx();
790 int last = mchTrack.getLastClusterIdx();
791 for (
int i =
first;
i <= last;
i++) {
792 const auto& cluster = mchClusters[
i];
793 int chamberId = cluster.getChamberId();
794 fwdInfo.mchBitMap |= 1 << chamberId;
799 auto getMIDBitMapBoards = [&](
int midTrackID) {
800 if (midTrackID != -1) {
801 const auto& midTrack = midTracks[midTrackID];
802 fwdInfo.midBitMap = midTrack.getHitMap();
803 fwdInfo.midBoards = midTrack.getEfficiencyWord();
807 auto extrapMCHTrack = [&](
int mchTrackID) {
808 const auto& track = mchTracks[mchTrackID];
816 float vx = 0, vy = 0, vz = 0;
817 if (collisionID >= 0) {
818 const auto&
v =
data.getPrimaryVertex(collisionID);
824 o2::mch::TrackParam trackParamAtVertex(track.getZ(), track.getParameters(), track.getCovariances());
847 double dca = std::sqrt(dcaX * dcaX + dcaY * dcaY);
852 double dpdca = track.getP() * dca;
853 double dchi2 = track.getChi2OverNDF();
855 auto fwdmuon = mMatching.
MCHtoFwd(trackParamAtVertex);
857 fwdInfo.x = fwdmuon.
getX();
858 fwdInfo.y = fwdmuon.getY();
859 fwdInfo.z = fwdmuon.getZ();
860 fwdInfo.phi = fwdmuon.getPhi();
861 fwdInfo.tanl = fwdmuon.getTgl();
862 fwdInfo.invqpt = fwdmuon.getInvQPt();
863 fwdInfo.rabs = std::sqrt(xAbs * xAbs + yAbs * yAbs);
864 fwdInfo.chi2 = dchi2;
865 fwdInfo.pdca = dpdca;
866 fwdInfo.nClusters = track.getNClusters();
868 fwdCovInfo.sigX = TMath::Sqrt(fwdmuon.getCovariances()(0, 0));
869 fwdCovInfo.sigY = TMath::Sqrt(fwdmuon.getCovariances()(1, 1));
870 fwdCovInfo.sigPhi = TMath::Sqrt(fwdmuon.getCovariances()(2, 2));
871 fwdCovInfo.sigTgl = TMath::Sqrt(fwdmuon.getCovariances()(3, 3));
872 fwdCovInfo.sig1Pt = TMath::Sqrt(fwdmuon.getCovariances()(4, 4));
873 fwdCovInfo.rhoXY = (Char_t)(128. * fwdmuon.getCovariances()(0, 1) / (fwdCovInfo.sigX * fwdCovInfo.sigY));
874 fwdCovInfo.rhoPhiX = (Char_t)(128. * fwdmuon.getCovariances()(0, 2) / (fwdCovInfo.sigPhi * fwdCovInfo.sigX));
875 fwdCovInfo.rhoPhiY = (Char_t)(128. * fwdmuon.getCovariances()(1, 2) / (fwdCovInfo.sigPhi * fwdCovInfo.sigY));
876 fwdCovInfo.rhoTglX = (Char_t)(128. * fwdmuon.getCovariances()(0, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigX));
877 fwdCovInfo.rhoTglY = (Char_t)(128. * fwdmuon.getCovariances()(1, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigY));
878 fwdCovInfo.rhoTglPhi = (Char_t)(128. * fwdmuon.getCovariances()(2, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigPhi));
879 fwdCovInfo.rho1PtX = (Char_t)(128. * fwdmuon.getCovariances()(0, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigX));
880 fwdCovInfo.rho1PtY = (Char_t)(128. * fwdmuon.getCovariances()(1, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigY));
881 fwdCovInfo.rho1PtPhi = (Char_t)(128. * fwdmuon.getCovariances()(2, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigPhi));
882 fwdCovInfo.rho1PtTgl = (Char_t)(128. * fwdmuon.getCovariances()(3, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigTgl));
888 int mchTrackID = trackID.getIndex();
889 getMCHBitMap(mchTrackID);
890 if (!extrapMCHTrack(mchTrackID)) {
891 LOGF(warn,
"Unable to extrapolate MCH track with ID %d! Dummy parameters will be used", mchTrackID);
894 const auto& rof =
data.getMCHTracksROFRecords()[mMCHROFs[mchTrackID]];
895 auto time = rof.getTimeMUS(mStartIR).first;
896 fwdInfo.trackTime =
time.getTimeStamp() * 1.e3;
897 fwdInfo.trackTimeRes =
time.getTimeStampError() * 1.e3;
900 auto mchmidMatch = mchmidMatches[trackID.getIndex()];
901 auto mchTrackID = mchmidMatch.getMCHRef().getIndex();
902 if (!extrapMCHTrack(mchTrackID)) {
903 LOGF(warn,
"Unable to extrapolate MCH track with ID %d! Dummy parameters will be used", mchTrackID);
905 auto midTrackID = mchmidMatch.getMIDRef().getIndex();
906 fwdInfo.chi2matchmchmid = mchmidMatch.getMatchChi2OverNDF();
907 getMCHBitMap(mchTrackID);
908 getMIDBitMapBoards(midTrackID);
909 auto time = mchmidMatch.getTimeMUS(mStartIR).first;
910 fwdInfo.trackTime =
time.getTimeStamp() * 1.e3;
911 fwdInfo.trackTimeRes =
time.getTimeStampError() * 1.e3;
913 const auto& track =
data.getGlobalFwdTrack(trackID);
914 const auto& mftTracks =
data.getMFTTracks();
915 const auto& mfttrack = mftTracks[track.getMFTTrackID()];
916 if (!extrapMCHTrack(track.getMCHTrackID())) {
917 LOGF(warn,
"Unable to extrapolate MCH track with ID %d! Dummy parameters will be used", track.getMCHTrackID());
919 fwdInfo.x = track.getX();
920 fwdInfo.y = track.getY();
921 fwdInfo.z = track.getZ();
922 fwdInfo.phi = track.getPhi();
923 fwdInfo.tanl = track.getTanl();
924 fwdInfo.invqpt = track.getInvQPt();
925 fwdInfo.chi2 = track.getTrackChi2();
927 fwdInfo.chi2matchmchmid = track.getMIDMatchingChi2();
928 fwdInfo.chi2matchmchmft = track.getMFTMCHMatchingChi2();
929 fwdInfo.matchscoremchmft = track.getMFTMCHMatchingScore();
930 fwdInfo.matchmfttrackid = mIndexTableMFT[track.getMFTTrackID()];
931 fwdInfo.matchmchtrackid = mIndexTableFwd[track.getMCHTrackID()];
932 fwdInfo.trackTime = track.getTimeMUS().getTimeStamp() * 1.e3;
933 fwdInfo.trackTimeRes = track.getTimeMUS().getTimeStampError() * 1.e3;
935 getMCHBitMap(track.getMCHTrackID());
936 getMIDBitMapBoards(track.getMIDTrackID());
938 fwdCovInfo.sigX = TMath::Sqrt(track.getCovariances()(0, 0));
939 fwdCovInfo.sigY = TMath::Sqrt(track.getCovariances()(1, 1));
940 fwdCovInfo.sigPhi = TMath::Sqrt(track.getCovariances()(2, 2));
941 fwdCovInfo.sigTgl = TMath::Sqrt(track.getCovariances()(3, 3));
942 fwdCovInfo.sig1Pt = TMath::Sqrt(track.getCovariances()(4, 4));
943 fwdCovInfo.rhoXY = (Char_t)(128. * track.getCovariances()(0, 1) / (fwdCovInfo.sigX * fwdCovInfo.sigY));
944 fwdCovInfo.rhoPhiX = (Char_t)(128. * track.getCovariances()(0, 2) / (fwdCovInfo.sigPhi * fwdCovInfo.sigX));
945 fwdCovInfo.rhoPhiY = (Char_t)(128. * track.getCovariances()(1, 2) / (fwdCovInfo.sigPhi * fwdCovInfo.sigY));
946 fwdCovInfo.rhoTglX = (Char_t)(128. * track.getCovariances()(0, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigX));
947 fwdCovInfo.rhoTglY = (Char_t)(128. * track.getCovariances()(1, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigY));
948 fwdCovInfo.rhoTglPhi = (Char_t)(128. * track.getCovariances()(2, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigPhi));
949 fwdCovInfo.rho1PtX = (Char_t)(128. * track.getCovariances()(0, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigX));
950 fwdCovInfo.rho1PtY = (Char_t)(128. * track.getCovariances()(1, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigY));
951 fwdCovInfo.rho1PtPhi = (Char_t)(128. * track.getCovariances()(2, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigPhi));
952 fwdCovInfo.rho1PtTgl = (Char_t)(128. * track.getCovariances()(3, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigTgl));
956 float sX = TMath::Sqrt(mfttrack.getSigma2X()), sY = TMath::Sqrt(mfttrack.getSigma2Y()), sPhi = TMath::Sqrt(mfttrack.getSigma2Phi()),
957 sTgl = TMath::Sqrt(mfttrack.getSigma2Tanl()), sQ2Pt = TMath::Sqrt(mfttrack.getSigma2InvQPt());
959 if (!mStoreAllMFTCov) {
960 mftTracksCovCursor(fwdInfo.matchmfttrackid,
961 truncateFloatFraction(sX, mTrackCovDiag),
962 truncateFloatFraction(sY, mTrackCovDiag),
963 truncateFloatFraction(sPhi, mTrackCovDiag),
964 truncateFloatFraction(sTgl, mTrackCovDiag),
965 truncateFloatFraction(sQ2Pt, mTrackCovDiag),
966 (Char_t)(128. * mfttrack.getCovariances()(0, 1) / (sX * sY)),
967 (Char_t)(128. * mfttrack.getCovariances()(0, 2) / (sPhi * sX)),
968 (Char_t)(128. * mfttrack.getCovariances()(1, 2) / (sPhi * sY)),
969 (Char_t)(128. * mfttrack.getCovariances()(0, 3) / (sTgl * sX)),
970 (Char_t)(128. * mfttrack.getCovariances()(1, 3) / (sTgl * sY)),
971 (Char_t)(128. * mfttrack.getCovariances()(2, 3) / (sTgl * sPhi)),
972 (Char_t)(128. * mfttrack.getCovariances()(0, 4) / (sQ2Pt * sX)),
973 (Char_t)(128. * mfttrack.getCovariances()(1, 4) / (sQ2Pt * sY)),
974 (Char_t)(128. * mfttrack.getCovariances()(2, 4) / (sQ2Pt * sPhi)),
975 (Char_t)(128. * mfttrack.getCovariances()(3, 4) / (sQ2Pt * sTgl)));
979 std::uint64_t bcOfTimeRef;
980 bool needBCSlice = collisionID < 0;
982 float err = mTimeMarginTrackTime + fwdInfo.trackTimeRes;
983 bcOfTimeRef = fillBCSlice(bcSlice, fwdInfo.trackTime - err, fwdInfo.trackTime + err, bcsMap);
985 bcOfTimeRef = collisionBC - mStartIR.
toLong();
989 fwdTracksCursor(collisionID,
993 truncateFloatFraction(fwdInfo.z, mTrackX),
994 truncateFloatFraction(fwdInfo.phi, mTrackAlpha),
995 truncateFloatFraction(fwdInfo.tanl, mTrackTgl),
996 truncateFloatFraction(fwdInfo.invqpt, mTrack1Pt),
998 truncateFloatFraction(fwdInfo.pdca, mTrackX),
999 truncateFloatFraction(fwdInfo.rabs, mTrackX),
1000 truncateFloatFraction(fwdInfo.chi2, mTrackChi2),
1001 truncateFloatFraction(fwdInfo.chi2matchmchmid, mTrackChi2),
1002 truncateFloatFraction(fwdInfo.chi2matchmchmft, mTrackChi2),
1003 truncateFloatFraction(fwdInfo.matchscoremchmft, mTrackChi2),
1004 fwdInfo.matchmfttrackid,
1005 fwdInfo.matchmchtrackid,
1009 truncateFloatFraction(fwdInfo.trackTime, mTrackTime),
1010 truncateFloatFraction(fwdInfo.trackTimeRes, mTrackTimeError));
1012 fwdTracksCovCursor(truncateFloatFraction(fwdCovInfo.sigX, mTrackCovDiag),
1013 truncateFloatFraction(fwdCovInfo.sigY, mTrackCovDiag),
1014 truncateFloatFraction(fwdCovInfo.sigPhi, mTrackCovDiag),
1015 truncateFloatFraction(fwdCovInfo.sigTgl, mTrackCovDiag),
1016 truncateFloatFraction(fwdCovInfo.sig1Pt, mTrackCovDiag),
1022 fwdCovInfo.rhoTglPhi,
1025 fwdCovInfo.rho1PtPhi,
1026 fwdCovInfo.rho1PtTgl);
1029 ambigFwdTracksCursor(mTableTrFwdID, bcSlice);
1034void AODProducerWorkflowDPL::updateMCHeader(MCCollisionCursor& collisionCursor,
1035 XSectionCursor& xSectionCursor,
1036 PdfInfoCursor& pdfInfoCursor,
1037 HeavyIonCursor& heavyIonCursor,
1038 const MCEventHeader& header,
1050 auto genID = updateMCCollisions(collisionCursor,
1056 mCollisionPosition);
1057 mXSectionUpdate = (updateHepMCXSection(xSectionCursor,
1062 ? HepMCUpdate::always
1063 : HepMCUpdate::never);
1064 mPdfInfoUpdate = (updateHepMCPdfInfo(pdfInfoCursor,
1069 ? HepMCUpdate::always
1070 : HepMCUpdate::never);
1071 mHeavyIonUpdate = (updateHepMCHeavyIon(heavyIonCursor,
1076 ? HepMCUpdate::always
1077 : HepMCUpdate::never);
1082 store.resize(Nsources);
1083 for (
int s = 0;
s < Nsources; ++
s) {
1084 store[
s].resize(NEvents);
1090 for (
auto s = 0U;
s < store.size(); ++
s) {
1091 for (
auto e = 0U; e < store[
s].size(); ++e) {
1092 store[
s][e].clear();
1101 LOG(warn) <<
"trackID is smaller than 0. Neglecting";
1104 if (useSigFilt &&
source == 0) {
1112 MCParticlesCursor& mcParticlesCursor,
1113 const gsl::span<const o2::dataformats::VtxTrackRef>& primVer2TRefs,
1114 const gsl::span<const GIndex>& GIndices,
1116 const std::vector<MCColInfo>& mcColToEvSrc)
1120 for (
auto& p : mcColToEvSrc) {
1121 NSources = std::max(p.sourceID, NSources);
1122 NEvents = std::max(p.eventID, NEvents);
1126 LOG(info) <<
" number of events " << NEvents;
1127 LOG(info) <<
" number of sources " << NSources;
1130 std::vector<int> particleIDsToKeep;
1132 auto markMCTrackForSrc = [&](std::array<GID, GID::NSources>& contributorsGID, uint8_t
src) {
1133 auto mcLabel =
data.getTrackMCLabel(contributorsGID[
src]);
1134 if (!mcLabel.isValid()) {
1137 keepMCParticle(mToStore, mcLabel.getSourceID(), mcLabel.getEventID(), mcLabel.getTrackID(), 1, mUseSigFiltMC);
1141 for (
auto& trackRef : primVer2TRefs) {
1145 for (
int ti =
start; ti <
end; ti++) {
1146 auto& trackIndex = GIndices[ti];
1147 if (GIndex::includesSource(
src, mInputSources)) {
1148 auto mcTruth =
data.getTrackMCLabel(trackIndex);
1149 if (!mcTruth.isValid()) {
1152 keepMCParticle(mToStore, mcTruth.getSourceID(), mcTruth.getEventID(), mcTruth.getTrackID(), 1, mUseSigFiltMC);
1154 auto contributorsGID =
data.getSingleDetectorRefs(trackIndex);
1163 for (
auto& mcLabel : labelsTOF) {
1164 if (!mcLabel.isValid()) {
1167 keepMCParticle(mToStore, mcLabel.getSourceID(), mcLabel.getEventID(), mcLabel.getTrackID(), 1, mUseSigFiltMC);
1176 auto& mcCaloEMCCellLabels =
data.getEMCALCellsMCLabels()->getTruthArray();
1177 for (
auto& mcTruth : mcCaloEMCCellLabels) {
1178 if (!mcTruth.isValid()) {
1181 keepMCParticle(mToStore, mcTruth.getSourceID(), mcTruth.getEventID(), mcTruth.getTrackID(), 1, mUseSigFiltMC);
1185 auto& mcCaloPHOSCellLabels =
data.getPHOSCellsMCLabels()->getTruthArray();
1186 for (
auto& mcTruth : mcCaloPHOSCellLabels) {
1187 if (!mcTruth.isValid()) {
1190 keepMCParticle(mToStore, mcTruth.getSourceID(), mcTruth.getEventID(), mcTruth.getTrackID(), 1, mUseSigFiltMC);
1193 using namespace aodmchelpers;
1197 for (
auto& colInfo : mcColToEvSrc) {
1198 int event = colInfo.eventID;
1199 int source = colInfo.sourceID;
1200 int mcColId = colInfo.colIndex;
1202 LOG(
debug) <<
"Event=" <<
event <<
" source=" <<
source <<
" collision=" << mcColId;
1221template <
typename MCTrackLabelCursorType,
typename MCMFTTrackLabelCursorType,
typename MCFwdTrackLabelCursorType>
1222void AODProducerWorkflowDPL::fillMCTrackLabelsTable(MCTrackLabelCursorType& mcTrackLabelCursor,
1223 MCMFTTrackLabelCursorType& mcMFTTrackLabelCursor,
1224 MCFwdTrackLabelCursorType& mcFwdTrackLabelCursor,
1226 const gsl::span<const GIndex>& primVerGIs,
1239 mcMFTTrackLabelCursor.reserve(
end -
start + mcMFTTrackLabelCursor.lastIndex());
1240 mcFwdTrackLabelCursor.reserve(
end -
start + mcFwdTrackLabelCursor.lastIndex());
1241 mcTrackLabelCursor.reserve(
end -
start + mcTrackLabelCursor.lastIndex());
1242 for (
int ti =
start; ti <
end; ti++) {
1243 const auto trackIndex = primVerGIs[ti];
1246 auto needToStore = [trackIndex](std::unordered_map<GIndex, int>& mp) {
1247 auto entry = mp.find(trackIndex);
1248 if (
entry == mp.end() ||
entry->second == -1) {
1255 if (GIndex::includesSource(
src, mInputSources)) {
1256 auto mcTruth =
data.getTrackMCLabel(trackIndex);
1257 MCLabels labelHolder{};
1262 if (mcTruth.isValid()) {
1263 labelHolder.labelID = (mToStore[mcTruth.getSourceID()][mcTruth.getEventID()])[mcTruth.getTrackID()];
1265 if (mcTruth.isFake()) {
1266 labelHolder.fwdLabelMask |= (0x1 << 7);
1268 if (mcTruth.isNoise()) {
1269 labelHolder.fwdLabelMask |= (0x1 << 6);
1272 mcMFTTrackLabelCursor(labelHolder.labelID,
1273 labelHolder.fwdLabelMask);
1275 mcFwdTrackLabelCursor(labelHolder.labelID,
1276 labelHolder.fwdLabelMask);
1279 if (!needToStore(mGIDToTableID)) {
1282 if (mcTruth.isValid()) {
1283 labelHolder.labelID = (mToStore[mcTruth.getSourceID()][mcTruth.getEventID()])[mcTruth.getTrackID()];
1284 if (mcTruth.isFake()) {
1285 labelHolder.labelMask |= (0x1 << 15);
1288 auto contributorsGID =
data.getSingleDetectorRefs(trackIndex);
1291 labelHolder.labelMask |= (0x1 << 13);
1296 auto itsGID =
data.getITSContributorGID(trackIndex);
1297 auto itsSource = itsGID.getSource();
1299 auto& itsTrack =
data.getITSTrack(itsGID);
1300 for (
unsigned int iL = 0; iL < 7; ++iL) {
1301 if (itsTrack.isFakeOnLayer(iL)) {
1302 labelHolder.labelMask |= (0x1 << iL);
1306 labelHolder.labelMask |= (
data.getTrackMCLabel(itsGID).isFake() << 12);
1310 }
else if (mcTruth.isNoise()) {
1311 labelHolder.labelMask |= (0x1 << 14);
1313 mcTrackLabelCursor(labelHolder.labelID, labelHolder.labelMask);
1320 auto sTrackLabels =
data.getStrangeTracksMCLabels();
1322 if (!(vertexId < 0 || vertexId >= mVertexStrLUT.size() - 1)) {
1323 mcTrackLabelCursor.reserve(mVertexStrLUT[vertexId + 1] + mcTrackLabelCursor.lastIndex());
1324 for (
int iS{mVertexStrLUT[vertexId]}; iS < mVertexStrLUT[vertexId + 1]; ++iS) {
1325 auto& collStrTrk = mCollisionStrTrk[iS];
1326 auto&
label = sTrackLabels[collStrTrk.second];
1327 MCLabels labelHolder;
1328 labelHolder.labelID =
label.isValid() ? (mToStore[
label.getSourceID()][
label.getEventID()])[
label.getTrackID()] : -1;
1329 labelHolder.labelMask = (
label.isFake() << 15) | (
label.isNoise() << 14);
1330 mcTrackLabelCursor(labelHolder.labelID, labelHolder.labelMask);
1335template <
typename V0CursorType,
typename CascadeCursorType,
typename Decay3BodyCursorType>
1336void AODProducerWorkflowDPL::fillSecondaryVertices(
const o2::globaltracking::RecoContainer& recoData, V0CursorType& v0Cursor, CascadeCursorType& cascadeCursor, Decay3BodyCursorType& decay3BodyCursor)
1343 v0Cursor.reserve(v0s.size());
1345 for (
size_t iv0 = 0; iv0 < v0s.size(); iv0++) {
1346 const auto&
v0 = v0s[iv0];
1347 auto trPosID =
v0.getProngID(0);
1348 auto trNegID =
v0.getProngID(1);
1349 uint8_t v0flags =
v0.getBits();
1350 int posTableIdx = -1, negTableIdx = -1, collID = -1;
1351 auto item = mGIDToTableID.find(trPosID);
1352 if (item != mGIDToTableID.end()) {
1353 posTableIdx = item->second;
1355 LOG(warn) <<
"Could not find a positive track index for prong ID " << trPosID;
1357 item = mGIDToTableID.find(trNegID);
1358 if (item != mGIDToTableID.end()) {
1359 negTableIdx = item->second;
1361 LOG(warn) <<
"Could not find a negative track index for prong ID " << trNegID;
1363 auto itemV = mVtxToTableCollID.find(
v0.getVertexID());
1364 if (itemV == mVtxToTableCollID.end()) {
1365 LOG(warn) <<
"Could not find V0 collisionID for the vertex ID " <<
v0.getVertexID();
1367 collID = itemV->second;
1369 if (posTableIdx != -1 and negTableIdx != -1 and collID != -1) {
1370 v0Cursor(collID, posTableIdx, negTableIdx, v0flags);
1371 mV0ToTableID[
int(iv0)] = mTableV0ID++;
1376 cascadeCursor.reserve(cascades.size());
1377 for (
auto& cascade : cascades) {
1378 auto itemV0 = mV0ToTableID.find(cascade.getV0ID());
1379 if (itemV0 == mV0ToTableID.end()) {
1382 int v0tableID = itemV0->second, bachTableIdx = -1, collID = -1;
1383 auto bachelorID = cascade.getBachelorID();
1384 auto item = mGIDToTableID.find(bachelorID);
1385 if (item != mGIDToTableID.end()) {
1386 bachTableIdx = item->second;
1388 LOG(warn) <<
"Could not find a bachelor track index";
1391 auto itemV = mVtxToTableCollID.find(cascade.getVertexID());
1392 if (itemV != mVtxToTableCollID.end()) {
1393 collID = itemV->second;
1395 LOG(warn) <<
"Could not find cascade collisionID for the vertex ID " << cascade.getVertexID();
1398 cascadeCursor(collID, v0tableID, bachTableIdx);
1402 decay3BodyCursor.reserve(decays3Body.size());
1403 for (
size_t i3Body = 0; i3Body < decays3Body.size(); i3Body++) {
1404 const auto& decay3Body = decays3Body[i3Body];
1406 decay3Body.getProngID(0),
1407 decay3Body.getProngID(1),
1408 decay3Body.getProngID(2)};
1409 int tableIdx[3]{-1, -1, -1}, collID = -1;
1410 bool missing{
false};
1411 for (
int i{0};
i < 3; ++
i) {
1412 auto item = mGIDToTableID.find(trIDs[
i]);
1413 if (item != mGIDToTableID.end()) {
1414 tableIdx[
i] = item->second;
1416 LOG(warn) << fmt::format(
"Could not find a track index for prong ID {}", (
int)trIDs[
i]);
1420 auto itemV = mVtxToTableCollID.find(decay3Body.getVertexID());
1421 if (itemV == mVtxToTableCollID.end()) {
1422 LOG(warn) <<
"Could not find 3 body collisionID for the vertex ID " << decay3Body.getVertexID();
1425 collID = itemV->second;
1430 decay3BodyCursor(collID, tableIdx[0], tableIdx[1], tableIdx[2]);
1434template <
typename FwdTrkClsCursorType>
1441 int mchTrackID = -1;
1443 mchTrackID = trackID.getIndex();
1445 auto mchmidMatch = mchmidMatches[trackID.getIndex()];
1446 mchTrackID = mchmidMatch.getMCHRef().getIndex();
1449 if (mchTrackID > -1 && mchTrackID < mchTracks.size()) {
1450 const auto& mchTrack = mchTracks[mchTrackID];
1451 fwdTrkClsCursor.reserve(mchTrack.getNClusters() + fwdTrkClsCursor.lastIndex());
1452 int first = mchTrack.getFirstClusterIdx();
1453 int last = mchTrack.getLastClusterIdx();
1454 for (
int i =
first;
i <= last;
i++) {
1455 const auto& cluster = mchClusters[
i];
1456 fwdTrkClsCursor(fwdTrackId,
1457 truncateFloatFraction(cluster.x, mMuonCl),
1458 truncateFloatFraction(cluster.y, mMuonCl),
1459 truncateFloatFraction(cluster.z, mMuonCl),
1460 (((cluster.ey < 5.) & 0x1) << 12) | (((cluster.ex < 5.) & 0x1) << 11) | cluster.getDEId());
1465template <
typename HMPCursorType>
1470 hmpCursor.reserve(hmpMatches.size());
1473 for (
size_t iHmp = 0; iHmp < hmpMatches.size(); iHmp++) {
1475 const auto&
match = hmpMatches[iHmp];
1477 float xTrk, yTrk, theta,
phi;
1481 match.getHMPIDtrk(xTrk, yTrk, theta,
phi);
1484 auto photChargeVec =
match.getPhotCharge();
1486 float photChargeVec2[10];
1488 for (Int_t
i = 0;
i < 10;
i++) {
1489 photChargeVec2[
i] = photChargeVec[
i];
1491 auto tref = mGIDToTableID.find(
match.getTrackRef());
1492 if (tref != mGIDToTableID.end()) {
1493 hmpCursor(tref->second,
match.getHMPsignal(), xTrk, yTrk, xMip, yMip, nph,
charge,
match.getIdxHMPClus(),
match.getHmpMom(), photChargeVec2);
1495 LOG(error) <<
"Could not find AOD track table entry for HMP-matched track " <<
match.getTrackRef().asString();
1507 mCollisionStrTrk.clear();
1509 mVertexStrLUT.clear();
1511 for (
auto& sTrk : recoData.getStrangeTracks()) {
1515 vtxId = v0s[sTrk.mDecayRef].getVertexID();
1517 vtxId = cascades[sTrk.mDecayRef].getVertexID();
1519 vtxId = decays3Body[sTrk.mDecayRef].getVertexID();
1521 mCollisionStrTrk.emplace_back(vtxId, sTrkID++);
1522 mVertexStrLUT[vtxId]++;
1524 std::exclusive_scan(mVertexStrLUT.begin(), mVertexStrLUT.end(), mVertexStrLUT.begin(), 0);
1527 std::sort(mCollisionStrTrk.begin(), mCollisionStrTrk.end(), [](
const auto&
a,
const auto&
b) { return a.first < b.first; });
1528 mStrTrkIndices.clear();
1529 mStrTrkIndices.resize(mCollisionStrTrk.size(), -1);
1532template <
typename V0C,
typename CC,
typename D3BC>
1535 int itsTableIdx = -1;
1541 for (
const auto& sTrk : recoData.getStrangeTracks()) {
1551 v0Curs.reserve(nV0);
1552 cascCurs.reserve(nCasc);
1553 d3BodyCurs.reserve(nD3Body);
1555 for (
const auto& sTrk : recoData.getStrangeTracks()) {
1557 auto item = mGIDToTableID.find(ITSIndex);
1558 if (item != mGIDToTableID.end()) {
1559 itsTableIdx = item->second;
1561 LOG(warn) <<
"Could not find a ITS strange track index " << ITSIndex;
1565 v0Curs(mStrTrkIndices[sTrkID++],
1575 sTrk.getAverageClusterSize());
1577 cascCurs(mStrTrkIndices[sTrkID++],
1587 sTrk.getAverageClusterSize());
1589 d3BodyCurs(mStrTrkIndices[sTrkID++],
1599 sTrk.getAverageClusterSize());
1606 const auto& tpcTracks =
data.getTPCTracks();
1607 const auto& tpcClusRefs =
data.getTPCTracksClusterRefs();
1608 const auto& tpcClusShMap =
data.clusterShMapTPC;
1609 const auto& tpcClusAcc =
data.getTPCClusters();
1610 constexpr int maxRows = 152;
1611 constexpr int neighbour = 2;
1612 int ntr = tpcTracks.size();
1613 mTPCCounters.clear();
1614 mTPCCounters.resize(ntr);
1616 int ngroup = std::min(50, std::max(1, ntr / mNThreads));
1617#pragma omp parallel for schedule(dynamic, ngroup) num_threads(mNThreads)
1619 for (
int itr = 0; itr < ntr; itr++) {
1620 std::array<bool, maxRows> clMap{}, shMap{};
1621 uint8_t sectorIndex, rowIndex;
1622 uint32_t clusterIndex;
1623 auto&
counters = mTPCCounters[itr];
1624 const auto& track = tpcTracks[itr];
1625 for (
int i = 0;
i < track.getNClusterReferences();
i++) {
1626 o2::tpc::TrackTPC::getClusterReference(tpcClusRefs,
i, sectorIndex, rowIndex, clusterIndex, track.getClusterRef());
1627 unsigned int absoluteIndex = tpcClusAcc.clusterOffset[sectorIndex][rowIndex] + clusterIndex;
1628 clMap[rowIndex] =
true;
1630 if (!shMap[rowIndex]) {
1633 shMap[rowIndex] =
true;
1637 for (
int i = 0;
i < maxRows;
i++) {
1642 }
else if ((
i - last) <= neighbour) {
1645 int lim = std::min(
i + 1 + neighbour, maxRows);
1646 for (
int j =
i + 1;
j < lim;
j++) {
1661 if (track.getTrackletIndex(il) != -1) {
1665 if (track.getHasNeighbor()) {
1668 if (track.getHasPadrowCrossing()) {
1674template <
typename TCaloHandler,
typename TCaloCursor,
typename TCaloTRGCursor,
typename TMCCaloLabelCursor>
1675void AODProducerWorkflowDPL::addToCaloTable(TCaloHandler& caloHandler, TCaloCursor& caloCellCursor, TCaloTRGCursor& caloTRGCursor,
1676 TMCCaloLabelCursor& mcCaloCellLabelCursor,
int eventID,
int bcID, int8_t caloType)
1678 auto inputEvent = caloHandler.buildEvent(eventID);
1679 auto cellsInEvent = inputEvent.mCells;
1680 auto cellMClabels = inputEvent.mMCCellLabels;
1681 caloCellCursor.reserve(cellsInEvent.size() + caloCellCursor.lastIndex());
1682 caloTRGCursor.reserve(cellsInEvent.size() + caloTRGCursor.lastIndex());
1684 mcCaloCellLabelCursor.reserve(cellsInEvent.size() + mcCaloCellLabelCursor.lastIndex());
1686 for (
auto iCell = 0U; iCell < cellsInEvent.size(); iCell++) {
1687 caloCellCursor(bcID,
1691 cellsInEvent[iCell].
getType(),
1705 std::vector<int32_t> particleIds;
1706 std::vector<float> amplitudeFraction;
1707 if (!mEMCselectLeading) {
1708 particleIds.reserve(cellMClabels.size());
1709 amplitudeFraction.reserve(cellMClabels.size());
1711 float tmpMaxAmplitude = 0;
1712 int32_t tmpindex = 0;
1713 for (
auto& mclabel : cellMClabels[iCell]) {
1715 if (mclabel.isValid()) {
1716 if (mEMCselectLeading) {
1717 if (mclabel.getAmplitudeFraction() > tmpMaxAmplitude) {
1719 if (mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID()).find(mclabel.getTrackID()) !=
1720 mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID()).end()) {
1721 tmpMaxAmplitude = mclabel.getAmplitudeFraction();
1722 tmpindex = (mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID())).at(mclabel.getTrackID());
1726 auto trackStore = mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID());
1727 auto iter = trackStore.find(mclabel.getTrackID());
1728 if (iter != trackStore.end()) {
1729 amplitudeFraction.emplace_back(mclabel.getAmplitudeFraction());
1730 particleIds.emplace_back(iter->second);
1732 particleIds.emplace_back(-1);
1733 amplitudeFraction.emplace_back(0.f);
1734 LOG(warn) <<
"CaloTable: Could not find track for mclabel (" << mclabel.getSourceID() <<
"," << mclabel.getEventID() <<
"," << mclabel.getTrackID() <<
") in the AOD MC store";
1735 if (mMCKineReader) {
1736 auto mctrack = mMCKineReader->
getTrack(mclabel);
1739 LOG(warn) <<
" ... this track is of PDG " << mctrack->GetPdgCode() <<
" produced by " << mctrack->getProdProcessAsString() <<
" at (" <<
vec.X() <<
"," <<
vec.Y() <<
"," <<
vec.Z() <<
")";
1745 if (mEMCselectLeading) {
1746 amplitudeFraction.emplace_back(tmpMaxAmplitude);
1747 particleIds.emplace_back(tmpindex);
1749 if (particleIds.size() == 0) {
1750 particleIds.emplace_back(-1);
1751 amplitudeFraction.emplace_back(0.f);
1753 mcCaloCellLabelCursor(particleIds,
1760template <
typename TCaloCursor,
typename TCaloTRGCursor,
typename TMCCaloLabelCursor>
1761void AODProducerWorkflowDPL::fillCaloTable(TCaloCursor& caloCellCursor, TCaloTRGCursor& caloTRGCursor,
1762 TMCCaloLabelCursor& mcCaloCellLabelCursor,
const std::map<uint64_t, int>& bcsMap,
1766 auto caloEMCCells =
data.getEMCALCells();
1767 auto caloEMCCellsTRGR =
data.getEMCALTriggers();
1768 auto mcCaloEMCCellLabels =
data.getEMCALCellsMCLabels();
1770 auto caloPHOSCells =
data.getPHOSCells();
1771 auto caloPHOSCellsTRGR =
data.getPHOSTriggers();
1772 auto mcCaloPHOSCellLabels =
data.getPHOSCellsMCLabels();
1776 caloPHOSCellsTRGR = {};
1777 mcCaloPHOSCellLabels = {};
1782 caloEMCCellsTRGR = {};
1783 mcCaloEMCCellLabels = {};
1790 emcEventHandler.
reset();
1791 emcEventHandler.
setCellData(caloEMCCells, caloEMCCellsTRGR);
1794 phsEventHandler.
reset();
1795 phsEventHandler.
setCellData(caloPHOSCells, caloPHOSCellsTRGR);
1801 std::vector<std::tuple<uint64_t, int8_t, int>> caloEvents;
1803 caloEvents.reserve(emcNEvents + phsNEvents);
1805 for (
int iev = 0; iev < emcNEvents; ++iev) {
1807 caloEvents.emplace_back(std::make_tuple(
bc, 1, iev));
1810 for (
int iev = 0; iev < phsNEvents; ++iev) {
1812 caloEvents.emplace_back(std::make_tuple(
bc, 0, iev));
1815 std::sort(caloEvents.begin(), caloEvents.end(),
1816 [](
const auto&
left,
const auto&
right) { return std::get<0>(left) < std::get<0>(right); });
1819 for (
int i = 0;
i < emcNEvents + phsNEvents; ++
i) {
1820 uint64_t globalBC = std::get<0>(caloEvents[
i]);
1821 int8_t caloType = std::get<1>(caloEvents[
i]);
1822 int eventID = std::get<2>(caloEvents[
i]);
1823 auto item = bcsMap.find(globalBC);
1825 if (item != bcsMap.end()) {
1826 bcID = item->second;
1828 LOG(warn) <<
"Error: could not find a corresponding BC ID for a calo point; globalBC = " << globalBC <<
", caloType = " << (
int)caloType;
1830 if (caloType == 0) {
1831 addToCaloTable(phsEventHandler, caloCellCursor, caloTRGCursor, mcCaloCellLabelCursor, eventID, bcID, caloType);
1833 if (caloType == 1) {
1834 addToCaloTable(emcEventHandler, caloCellCursor, caloTRGCursor, mcCaloCellLabelCursor, eventID, bcID, caloType);
1845 mLPMProdTag = ic.
options().
get<std::string>(
"lpmp-prod-tag");
1846 mAnchorPass = ic.
options().
get<std::string>(
"anchor-pass");
1847 mAnchorProd = ic.
options().
get<std::string>(
"anchor-prod");
1848 mUser = ic.
options().
get<std::string>(
"created-by");
1849 mRecoPass = ic.
options().
get<std::string>(
"reco-pass");
1850 mAODParent = ic.
options().
get<std::string>(
"aod-parent");
1851 mTFNumber = ic.
options().
get<int64_t>(
"aod-timeframe-id");
1852 mRecoOnly = ic.
options().
get<
int>(
"reco-mctracks-only");
1853 mTruncate = ic.
options().
get<
int>(
"enable-truncation");
1854 mRunNumber = ic.
options().
get<
int>(
"run-number");
1855 mCTPReadout = ic.
options().
get<
int>(
"ctpreadout-create");
1856 mNThreads = std::max(1, ic.
options().
get<
int>(
"nthreads"));
1857 mEMCselectLeading = ic.
options().
get<
bool>(
"emc-select-leading");
1858 mThinTracks = ic.
options().
get<
bool>(
"thin-tracks");
1859 mPropTracks = ic.
options().
get<
bool>(
"propagate-tracks");
1860 mMaxPropXiu = ic.
options().
get<
float>(
"propagate-tracks-max-xiu");
1861 mPropMuons = ic.
options().
get<
bool>(
"propagate-muons");
1862 mStoreAllMFTCov = ic.
options().
get<
bool>(
"store-all-mft-cov");
1863 if (
auto s = ic.
options().
get<std::string>(
"with-streamers"); !
s.empty()) {
1864 mStreamerFlags.
set(
s);
1865 if (mStreamerFlags) {
1866 LOGP(info,
"Writing streamer data with mask:");
1867 LOG(info) << mStreamerFlags;
1869 LOGP(warn,
"Specified non-default empty streamer mask!");
1872 mTrackQCKeepGlobalTracks = ic.
options().
get<
bool>(
"trackqc-keepglobaltracks");
1873 mTrackQCRetainOnlydEdx = ic.
options().
get<
bool>(
"trackqc-retainonlydedx");
1874 mTrackQCFraction = ic.
options().
get<
float>(
"trackqc-fraction");
1875 mTrackQCNTrCut = ic.
options().
get<int64_t>(
"trackqc-NTrCut");
1876 mTrackQCDCAxy = ic.
options().
get<
float>(
"trackqc-tpc-dca");
1877 mTrackQCPt = ic.
options().
get<
float>(
"trackqc-tpc-pt");
1878 mTrackQCNCls = ic.
options().
get<
int>(
"trackqc-tpc-cls");
1879 if (
auto seed = ic.
options().
get<
int>(
"seed"); seed == 0) {
1880 LOGP(info,
"Using random device for seeding");
1881 std::random_device
rd;
1882 std::array<int, std::mt19937::state_size> seed_data{};
1883 std::generate(std::begin(seed_data), std::end(seed_data), std::ref(
rd));
1884 std::seed_seq seq(std::begin(seed_data), std::end(seed_data));
1885 mGenerator = std::mt19937(seq);
1887 LOGP(info,
"Using seed {} for sampling", seed);
1888 mGenerator.seed(seed);
1891 LOGP(info,
"Multi-threaded parts will run with {} OpenMP threads", mNThreads);
1894 LOG(info) <<
"OpenMP is disabled";
1896 if (mTFNumber == -1L) {
1897 LOG(info) <<
"TFNumber will be obtained from CCDB";
1899 if (mRunNumber == -1L) {
1900 LOG(info) <<
"The Run number will be obtained from DPL headers";
1903 mUseSigFiltMC = ic.
options().
get<
bool>(
"mc-signal-filt");
1906 if (mTruncate != 1) {
1907 LOG(info) <<
"Truncation is not used!";
1908 mCollisionPosition = 0xFFFFFFFF;
1909 mCollisionPositionCov = 0xFFFFFFFF;
1910 mTrackX = 0xFFFFFFFF;
1911 mTrackAlpha = 0xFFFFFFFF;
1912 mTrackSnp = 0xFFFFFFFF;
1913 mTrackTgl = 0xFFFFFFFF;
1914 mTrack1Pt = 0xFFFFFFFF;
1915 mTrackChi2 = 0xFFFFFFFF;
1916 mTrackCovDiag = 0xFFFFFFFF;
1917 mTrackCovOffDiag = 0xFFFFFFFF;
1918 mTrackSignal = 0xFFFFFFFF;
1919 mTrackTime = 0xFFFFFFFF;
1920 mTPCTime0 = 0xFFFFFFFF;
1921 mTrackTimeError = 0xFFFFFFFF;
1922 mTrackPosEMCAL = 0xFFFFFFFF;
1923 mTracklets = 0xFFFFFFFF;
1924 mMcParticleW = 0xFFFFFFFF;
1925 mMcParticlePos = 0xFFFFFFFF;
1926 mMcParticleMom = 0xFFFFFFFF;
1927 mCaloAmp = 0xFFFFFFFF;
1928 mCaloTime = 0xFFFFFFFF;
1929 mCPVPos = 0xFFFFFFFF;
1930 mCPVAmpl = 0xFFFFFFFF;
1931 mMuonTr1P = 0xFFFFFFFF;
1932 mMuonTrThetaX = 0xFFFFFFFF;
1933 mMuonTrThetaY = 0xFFFFFFFF;
1934 mMuonTrZmu = 0xFFFFFFFF;
1935 mMuonTrBend = 0xFFFFFFFF;
1936 mMuonTrNonBend = 0xFFFFFFFF;
1937 mMuonTrCov = 0xFFFFFFFF;
1938 mMuonCl = 0xFFFFFFFF;
1939 mMuonClErr = 0xFFFFFFFF;
1940 mV0Time = 0xFFFFFFFF;
1941 mV0ChannelTime = 0xFFFFFFFF;
1942 mFDDTime = 0xFFFFFFFF;
1943 mFDDChannelTime = 0xFFFFFFFF;
1944 mT0Time = 0xFFFFFFFF;
1945 mT0ChannelTime = 0xFFFFFFFF;
1946 mV0Amplitude = 0xFFFFFFFF;
1947 mFDDAmplitude = 0xFFFFFFFF;
1948 mT0Amplitude = 0xFFFFFFFF;
1952 mZDCEnergyMap[ic] = -std::numeric_limits<float>::infinity();
1955 mZDCTDCMap[ic] = -std::numeric_limits<float>::infinity();
1958 std::string hepmcUpdate = ic.
options().
get<std::string>(
"hepmc-update");
1959 HepMCUpdate when = (hepmcUpdate ==
"never" ? HepMCUpdate::never : hepmcUpdate ==
"always" ? HepMCUpdate::always
1960 : hepmcUpdate ==
"all" ? HepMCUpdate::allKeys
1961 : HepMCUpdate::anyKey);
1962 mXSectionUpdate = when;
1963 mPdfInfoUpdate = when;
1964 mHeavyIonUpdate = when;
1968 if (mStreamerFlags) {
1969 mStreamer = std::make_unique<o2::utils::TreeStreamRedirector>(
"AO2DStreamer.root",
"RECREATE");
1975void add_additional_meta_info(std::vector<TString>& keys, std::vector<TString>&
values)
1978 auto aod_external_meta_info_file = getenv(
"AOD_ADDITIONAL_METADATA_FILE");
1979 if (aod_external_meta_info_file !=
nullptr) {
1980 LOG(info) <<
"Trying to inject additional AOD meta-data from " << aod_external_meta_info_file;
1981 if (std::filesystem::exists(aod_external_meta_info_file)) {
1982 std::ifstream input_file(aod_external_meta_info_file);
1984 nlohmann::json json_data;
1986 input_file >> json_data;
1987 }
catch (nlohmann::json::parse_error& e) {
1988 std::cerr <<
"JSON Parse Error: " << e.what() <<
"\n";
1989 std::cerr <<
"Exception ID: " << e.id <<
"\n";
1990 std::cerr <<
"Byte position: " << e.byte <<
"\n";
1994 for (
const auto& [
key,
value] : json_data.items()) {
1995 LOG(info) <<
"Adding AOD MetaData" <<
key <<
" : " <<
value;
1996 keys.push_back(
key.c_str());
2007 mTimer.Start(
false);
2010 updateTimeDependentParams(pc);
2035 std::vector<o2::ctp::CTPDigit> ctpDigitsCreated;
2036 if (mCTPReadout == 1) {
2037 LOG(info) <<
"CTP : creating ctpreadout in AOD producer";
2038 createCTPReadout(recoData, ctpDigitsCreated, pc);
2039 LOG(info) <<
"CTP : ctpreadout created from AOD";
2040 ctpDigits = gsl::span<o2::ctp::CTPDigit>(ctpDigitsCreated);
2042 LOG(
debug) <<
"FOUND " << primVertices.size() <<
" primary vertices";
2043 LOG(
debug) <<
"FOUND " << ft0RecPoints.size() <<
" FT0 rec. points";
2044 LOG(
debug) <<
"FOUND " << fv0RecPoints.size() <<
" FV0 rec. points";
2045 LOG(
debug) <<
"FOUND " << fddRecPoints.size() <<
" FDD rec. points";
2046 LOG(
debug) <<
"FOUND " << cpvClusters.size() <<
" CPV clusters";
2047 LOG(
debug) <<
"FOUND " << cpvTrigRecs.size() <<
" CPV trigger records";
2049 LOG(info) <<
"FOUND " << primVertices.size() <<
" primary vertices";
2053 auto bcCursor = createTableCursor<o2::aod::BCs>(pc);
2054 auto bcFlagsCursor = createTableCursor<o2::aod::BCFlags>(pc);
2055 auto cascadesCursor = createTableCursor<o2::aod::Cascades>(pc);
2056 auto collisionsCursor = createTableCursor<o2::aod::Collisions>(pc);
2057 auto decay3BodyCursor = createTableCursor<o2::aod::Decay3Bodys>(pc);
2058 auto trackedCascadeCursor = createTableCursor<o2::aod::TrackedCascades>(pc);
2059 auto trackedV0Cursor = createTableCursor<o2::aod::TrackedV0s>(pc);
2060 auto tracked3BodyCurs = createTableCursor<o2::aod::Tracked3Bodys>(pc);
2061 auto fddCursor = createTableCursor<o2::aod::FDDs>(pc);
2062 auto fddExtraCursor = createTableCursor<o2::aod::FDDsExtra>(pc);
2063 auto ft0Cursor = createTableCursor<o2::aod::FT0s>(pc);
2064 auto ft0ExtraCursor = createTableCursor<o2::aod::FT0sExtra>(pc);
2065 auto fv0aCursor = createTableCursor<o2::aod::FV0As>(pc);
2066 auto fv0aExtraCursor = createTableCursor<o2::aod::FV0AsExtra>(pc);
2067 auto fwdTracksCursor = createTableCursor<o2::aod::StoredFwdTracks>(pc);
2068 auto fwdTracksCovCursor = createTableCursor<o2::aod::StoredFwdTracksCov>(pc);
2069 auto fwdTrkClsCursor = createTableCursor<o2::aod::FwdTrkCls>(pc);
2070 auto mftTracksCursor = createTableCursor<o2::aod::StoredMFTTracks>(pc);
2071 auto mftTracksCovCursor = createTableCursor<o2::aod::StoredMFTTracksCov>(pc);
2072 auto tracksCursor = createTableCursor<o2::aod::StoredTracksIU>(pc);
2073 auto tracksCovCursor = createTableCursor<o2::aod::StoredTracksCovIU>(pc);
2074 auto tracksExtraCursor = createTableCursor<o2::aod::StoredTracksExtra>(pc);
2075 auto tracksQACursor = createTableCursor<o2::aod::TracksQAVersion>(pc);
2076 auto ambigTracksCursor = createTableCursor<o2::aod::AmbiguousTracks>(pc);
2077 auto ambigMFTTracksCursor = createTableCursor<o2::aod::AmbiguousMFTTracks>(pc);
2078 auto ambigFwdTracksCursor = createTableCursor<o2::aod::AmbiguousFwdTracks>(pc);
2079 auto v0sCursor = createTableCursor<o2::aod::V0s>(pc);
2080 auto zdcCursor = createTableCursor<o2::aod::Zdcs>(pc);
2081 auto hmpCursor = createTableCursor<o2::aod::HMPIDs>(pc);
2082 auto caloCellsCursor = createTableCursor<o2::aod::Calos>(pc);
2083 auto caloCellsTRGTableCursor = createTableCursor<o2::aod::CaloTriggers>(pc);
2084 auto cpvClustersCursor = createTableCursor<o2::aod::CPVClusters>(pc);
2085 auto originCursor = createTableCursor<o2::aod::Origins>(pc);
2089 if (mEnableTRDextra) {
2090 trdExtraCursor = createTableCursor<o2::aod::TRDsExtra>(pc);
2105 mcColLabelsCursor = createTableCursor<o2::aod::McCollisionLabels>(pc);
2106 mcCollisionsCursor = createTableCursor<o2::aod::McCollisions>(pc);
2107 hepmcXSectionsCursor = createTableCursor<o2::aod::HepMCXSections>(pc);
2108 hepmcPdfInfosCursor = createTableCursor<o2::aod::HepMCPdfInfos>(pc);
2109 hepmcHeavyIonsCursor = createTableCursor<o2::aod::HepMCHeavyIons>(pc);
2110 mcMFTTrackLabelCursor = createTableCursor<o2::aod::McMFTTrackLabels>(pc);
2111 mcFwdTrackLabelCursor = createTableCursor<o2::aod::McFwdTrackLabels>(pc);
2112 mcParticlesCursor = createTableCursor<o2::aod::StoredMcParticles_001>(pc);
2113 mcTrackLabelCursor = createTableCursor<o2::aod::McTrackLabels>(pc);
2114 mcCaloLabelsCursor = createTableCursor<o2::aod::McCaloLabels_001>(pc);
2117 std::unique_ptr<o2::steer::MCKinematicsReader> mcReader;
2119 mcReader = std::make_unique<o2::steer::MCKinematicsReader>(
"collisioncontext.root");
2121 mMCKineReader = mcReader.get();
2122 std::map<uint64_t, int> bcsMap;
2123 collectBCs(recoData, mUseMC ? mcReader->getDigitizationContext()->getEventRecords() : std::vector<o2::InteractionTimeRecord>{}, bcsMap);
2124 if (!primVer2TRefs.empty()) {
2125 addRefGlobalBCsForTOF(primVer2TRefs.back(), primVerGIs, recoData, bcsMap);
2128 mBCLookup.
init(bcsMap);
2131 const int runNumber = (mRunNumber == -1) ?
int(tinfo.runNumber) : mRunNumber;
2132 if (mTFNumber == -1L) {
2134 tfNumber = uint64_t(tinfo.firstTForbit) + (uint64_t(tinfo.runNumber) << 32);
2136 tfNumber = mTFNumber;
2139 std::vector<float> aAmplitudes, aTimes;
2140 std::vector<uint8_t> aChannels;
2141 fv0aCursor.reserve(fv0RecPoints.size());
2142 for (
auto& fv0RecPoint : fv0RecPoints) {
2143 aAmplitudes.clear();
2146 const auto channelData = fv0RecPoint.getBunchChannelData(fv0ChData);
2147 for (
auto& channel : channelData) {
2148 if (channel.charge > 0) {
2149 aAmplitudes.push_back(truncateFloatFraction(channel.charge, mV0Amplitude));
2150 aTimes.push_back(truncateFloatFraction(channel.time * 1.E-3, mV0ChannelTime));
2151 aChannels.push_back(channel.channel);
2154 uint64_t
bc = fv0RecPoint.getInteractionRecord().toLong();
2155 auto item = bcsMap.find(
bc);
2157 if (item != bcsMap.end()) {
2158 bcID = item->second;
2160 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a FV0 rec. point; BC = " <<
bc;
2165 truncateFloatFraction(fv0RecPoint.getCollisionGlobalMeanTime() * 1E-3, mV0Time),
2166 fv0RecPoint.getTrigger().getTriggersignals());
2168 if (mEnableFITextra) {
2169 fv0aExtraCursor(bcID,
2174 std::vector<float> zdcEnergy, zdcAmplitudes, zdcTime;
2175 std::vector<uint8_t> zdcChannelsE, zdcChannelsT;
2176 zdcCursor.reserve(zdcBCRecData.size());
2177 for (
auto zdcRecData : zdcBCRecData) {
2178 uint64_t
bc = zdcRecData.ir.toLong();
2179 auto item = bcsMap.find(
bc);
2181 if (item != bcsMap.end()) {
2182 bcID = item->second;
2184 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a ZDC rec. point; BC = " <<
bc;
2186 int fe, ne, ft, nt, fi, ni;
2187 zdcRecData.getRef(fe, ne, ft, nt, fi, ni);
2189 zdcChannelsE.clear();
2190 zdcAmplitudes.clear();
2192 zdcChannelsT.clear();
2193 for (
int ie = 0; ie < ne; ie++) {
2194 auto& zdcEnergyData = zdcEnergies[fe + ie];
2195 zdcEnergy.emplace_back(zdcEnergyData.energy());
2196 zdcChannelsE.emplace_back(zdcEnergyData.ch());
2198 for (
int it = 0; it < nt; it++) {
2199 auto& tdc = zdcTDCData[ft + it];
2200 zdcAmplitudes.emplace_back(tdc.amplitude());
2201 zdcTime.emplace_back(tdc.value());
2213 std::vector<MCColInfo> mcColToEvSrc;
2219 int nMCCollisions = mcReader->getDigitizationContext()->getNCollisions();
2220 const auto& mcRecords = mcReader->getDigitizationContext()->getEventRecords();
2221 const auto& mcParts = mcReader->getDigitizationContext()->getEventParts();
2224 if (mUseSigFiltMC) {
2225 std::vector<int> sourceIDs{};
2226 for (
int iCol = 0; iCol < nMCCollisions; iCol++) {
2227 for (
auto const& colPart : mcParts[iCol]) {
2228 int sourceID = colPart.sourceID;
2229 if (std::find(sourceIDs.begin(), sourceIDs.end(), sourceID) == sourceIDs.end()) {
2230 sourceIDs.push_back(sourceID);
2232 if (sourceIDs.size() > 1) {
2236 if (sourceIDs.size() > 1) {
2240 if (sourceIDs.size() <= 1) {
2241 LOGP(fatal,
"Signal filtering cannot be enabled without embedding. Please fix the configuration either enabling the embedding, or turning off the signal filtering.");
2246 int totalNParts = 0;
2247 for (
int iCol = 0; iCol < nMCCollisions; iCol++) {
2248 totalNParts += mcParts[iCol].size();
2250 mcCollisionsCursor.
reserve(totalNParts);
2252 for (
int iCol = 0; iCol < nMCCollisions; iCol++) {
2253 const auto time = mcRecords[iCol].getTimeOffsetWrtBC();
2254 auto globalBC = mcRecords[iCol].toLong();
2255 auto item = bcsMap.find(globalBC);
2257 if (item != bcsMap.end()) {
2258 bcID = item->second;
2260 LOG(fatal) <<
"Error: could not find a corresponding BC ID "
2261 <<
"for MC collision; BC = " << globalBC
2262 <<
", mc collision = " << iCol;
2264 auto& colParts = mcParts[iCol];
2265 auto nParts = colParts.size();
2266 for (
auto colPart : colParts) {
2267 auto eventID = colPart.entryID;
2268 auto sourceID = colPart.sourceID;
2271 if (nParts == 1 || sourceID == 0) {
2274 auto& header = mcReader->getMCEventHeader(sourceID, eventID);
2275 updateMCHeader(mcCollisionsCursor.
cursor,
2276 hepmcXSectionsCursor.
cursor,
2277 hepmcPdfInfosCursor.
cursor,
2278 hepmcHeavyIonsCursor.
cursor,
2286 mcColToEvSrc.emplace_back(
MCColInfo{iCol, sourceID, eventID, globalBC});
2291 std::sort(mcColToEvSrc.begin(), mcColToEvSrc.end(),
2295 int16_t aFDDAmplitudesA[8] = {0u}, aFDDAmplitudesC[8] = {0u};
2296 float aFDDTimesA[8] = {0.f}, aFDDTimesC[8] = {0.f};
2298 fddCursor.reserve(fddRecPoints.size());
2299 for (
const auto& fddRecPoint : fddRecPoints) {
2300 for (
int i = 0;
i < 8;
i++) {
2301 aFDDAmplitudesA[
i] = 0;
2302 aFDDAmplitudesC[
i] = 0;
2303 aFDDTimesA[
i] = 0.f;
2304 aFDDTimesC[
i] = 0.f;
2306 uint64_t globalBC = fddRecPoint.getInteractionRecord().toLong();
2307 uint64_t
bc = globalBC;
2308 auto item = bcsMap.find(
bc);
2310 if (item != bcsMap.end()) {
2311 bcID = item->second;
2313 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a FDD rec. point; BC = " <<
bc;
2315 const auto channelData = fddRecPoint.getBunchChannelData(fddChData);
2316 for (
const auto& channel : channelData) {
2317 if (channel.mPMNumber < 8) {
2318 aFDDAmplitudesC[channel.mPMNumber] = channel.mChargeADC;
2319 aFDDTimesC[channel.mPMNumber] = truncateFloatFraction(channel.mTime * 1E-3, mFDDChannelTime);
2321 aFDDAmplitudesA[channel.mPMNumber - 8] = channel.mChargeADC;
2322 aFDDTimesA[channel.mPMNumber - 8] = truncateFloatFraction(channel.mTime * 1E-3, mFDDChannelTime);
2329 truncateFloatFraction(fddRecPoint.getCollisionTimeA() * 1E-3, mFDDTime),
2330 truncateFloatFraction(fddRecPoint.getCollisionTimeC() * 1E-3, mFDDTime),
2331 fddRecPoint.getTrigger().getTriggersignals());
2332 if (mEnableFITextra) {
2333 fddExtraCursor(bcID,
2340 std::vector<float> aAmplitudesA, aAmplitudesC, aTimesA, aTimesC;
2341 std::vector<uint8_t> aChannelsA, aChannelsC;
2342 ft0Cursor.reserve(ft0RecPoints.size());
2343 for (
auto& ft0RecPoint : ft0RecPoints) {
2344 aAmplitudesA.clear();
2345 aAmplitudesC.clear();
2350 const auto channelData = ft0RecPoint.getBunchChannelData(ft0ChData);
2351 for (
auto& channel : channelData) {
2353 if (channel.QTCAmpl > 0) {
2355 if (channel.ChId < nFT0ChannelsAside) {
2356 aChannelsA.push_back(channel.ChId);
2357 aAmplitudesA.push_back(truncateFloatFraction(channel.QTCAmpl, mT0Amplitude));
2358 aTimesA.push_back(truncateFloatFraction(channel.CFDTime * 1E-3, mT0ChannelTime));
2360 aChannelsC.push_back(channel.ChId - nFT0ChannelsAside);
2361 aAmplitudesC.push_back(truncateFloatFraction(channel.QTCAmpl, mT0Amplitude));
2362 aTimesC.push_back(truncateFloatFraction(channel.CFDTime * 1E-3, mT0ChannelTime));
2366 uint64_t globalBC = ft0RecPoint.getInteractionRecord().toLong();
2367 uint64_t
bc = globalBC;
2368 auto item = bcsMap.find(
bc);
2370 if (item != bcsMap.end()) {
2371 bcID = item->second;
2373 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a FT0 rec. point; BC = " <<
bc;
2380 truncateFloatFraction(ft0RecPoint.getCollisionTimeA() * 1E-3, mT0Time),
2381 truncateFloatFraction(ft0RecPoint.getCollisionTimeC() * 1E-3, mT0Time),
2382 ft0RecPoint.getTrigger().getTriggersignals());
2383 if (mEnableFITextra) {
2384 ft0ExtraCursor(bcID,
2392 mcColLabelsCursor.
reserve(primVerLabels.size());
2393 for (
size_t ivert = 0; ivert < primVerLabels.size(); ++ivert) {
2394 const auto&
label = primVerLabels[ivert];
2400 std::vector<std::pair<int32_t, int64_t>> candidates;
2401 for (
const auto& colInfo : mcColToEvSrc) {
2402 if (colInfo.sourceID ==
label.getSourceID() &&
2403 colInfo.eventID ==
label.getEventID()) {
2404 candidates.emplace_back(colInfo.colIndex, colInfo.bc);
2408 int32_t mcCollisionID = -1;
2409 if (candidates.size() == 1) {
2410 mcCollisionID = candidates[0].first;
2411 }
else if (candidates.size() > 1) {
2417 const auto& timeStamp = primVertices[ivert].getTimeStamp();
2418 const double interactionTime = timeStamp.getTimeStamp() * 1E3;
2419 const auto recoBC = relativeTime_to_GlobalBC(interactionTime);
2420 int64_t bestDiff = std::numeric_limits<int64_t>::max();
2421 for (
const auto& [colIndex,
bc] : candidates) {
2422 const auto bcDiff = std::abs(
static_cast<int64_t
>(
bc) -
static_cast<int64_t
>(recoBC));
2423 if (bcDiff < bestDiff) {
2425 mcCollisionID = colIndex;
2430 uint16_t mcMask = 0;
2431 mcColLabelsCursor(mcCollisionID, mcMask);
2435 cacheTriggers(recoData);
2436 countTPCClusters(recoData);
2438 int collisionID = 0;
2442 auto& trackReffwd = primVer2TRefs.back();
2443 fillIndexTablesPerCollision(trackReffwd, primVerGIs, recoData);
2445 for (
auto&
vertex : primVertices) {
2446 auto& trackReffwd = primVer2TRefs[collisionID];
2447 fillIndexTablesPerCollision(trackReffwd, primVerGIs, recoData);
2452 prepareStrangenessTracking(recoData);
2454 mGIDToTableFwdID.clear();
2455 mGIDToTableMFTID.clear();
2457 if (mPropTracks || mThinTracks) {
2461 mGIDUsedBySVtx.reserve(v0s.size() * 2 + cascades.size() + decays3Body.size() * 3);
2462 for (
const auto&
v0 : v0s) {
2463 mGIDUsedBySVtx.insert(
v0.getProngID(0));
2464 mGIDUsedBySVtx.insert(
v0.getProngID(1));
2466 for (
const auto& cascade : cascades) {
2467 mGIDUsedBySVtx.insert(cascade.getBachelorID());
2469 for (
const auto& id3Body : decays3Body) {
2470 mGIDUsedBySVtx.insert(id3Body.getProngID(0));
2471 mGIDUsedBySVtx.insert(id3Body.getProngID(1));
2472 mGIDUsedBySVtx.insert(id3Body.getProngID(2));
2481 mCurrentTRDTrigID = 0;
2484 auto& trackRef = primVer2TRefs.back();
2486 fillTrackTablesPerCollision(-1, std::uint64_t(-1), trackRef, primVerGIs, recoData, tracksCursor, tracksCovCursor, tracksExtraCursor, tracksQACursor, trdExtraCursor,
2487 ambigTracksCursor, mftTracksCursor, mftTracksCovCursor, ambigMFTTracksCursor,
2488 fwdTracksCursor, fwdTracksCovCursor, ambigFwdTracksCursor, fwdTrkClsCursor, bcsMap);
2490 mCurrentTRDTrigID = 0;
2493 collisionsCursor.reserve(primVertices.size());
2494 for (
auto&
vertex : primVertices) {
2495 auto& cov =
vertex.getCov();
2496 auto& timeStamp =
vertex.getTimeStamp();
2497 const double interactionTime = timeStamp.getTimeStamp() * 1E3;
2498 uint64_t globalBC = relativeTime_to_GlobalBC(interactionTime);
2499 uint64_t localBC = relativeTime_to_LocalBC(interactionTime);
2500 LOG(
debug) <<
"global BC " << globalBC <<
" local BC " << localBC <<
" relative interaction time " << interactionTime;
2503 auto item = bcsMap.find(globalBC);
2505 if (item != bcsMap.end()) {
2506 bcID = item->second;
2508 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a collision; BC = " << globalBC <<
", collisionID = " << collisionID;
2510 collisionsCursor(bcID,
2511 truncateFloatFraction(
vertex.getX(), mCollisionPosition),
2512 truncateFloatFraction(
vertex.getY(), mCollisionPosition),
2513 truncateFloatFraction(
vertex.getZ(), mCollisionPosition),
2514 truncateFloatFraction(cov[0], mCollisionPositionCov),
2515 truncateFloatFraction(cov[1], mCollisionPositionCov),
2516 truncateFloatFraction(cov[2], mCollisionPositionCov),
2517 truncateFloatFraction(cov[3], mCollisionPositionCov),
2518 truncateFloatFraction(cov[4], mCollisionPositionCov),
2519 truncateFloatFraction(cov[5], mCollisionPositionCov),
2521 truncateFloatFraction(
vertex.getChi2(), mCollisionPositionCov),
2522 vertex.getNContributors(),
2523 truncateFloatFraction(relInteractionTime, mCollisionPosition),
2524 truncateFloatFraction(timeStamp.getTimeStampError() * 1E3, mCollisionPositionCov));
2525 mVtxToTableCollID[collisionID] = mTableCollID++;
2527 auto& trackRef = primVer2TRefs[collisionID];
2529 fillTrackTablesPerCollision(collisionID, globalBC, trackRef, primVerGIs, recoData, tracksCursor, tracksCovCursor, tracksExtraCursor, tracksQACursor, trdExtraCursor, ambigTracksCursor,
2530 mftTracksCursor, mftTracksCovCursor, ambigMFTTracksCursor,
2531 fwdTracksCursor, fwdTracksCovCursor, ambigFwdTracksCursor, fwdTrkClsCursor, bcsMap);
2535 fillSecondaryVertices(recoData, v0sCursor, cascadesCursor, decay3BodyCursor);
2536 fillHMPID(recoData, hmpCursor);
2537 fillStrangenessTrackingTables(recoData, trackedV0Cursor, trackedCascadeCursor, tracked3BodyCurs);
2541 std::unordered_map<uint64_t, std::pair<uint64_t, uint64_t>> bcToClassMask;
2543 LOG(
debug) <<
"CTP input available";
2544 for (
auto& ctpDigit : ctpDigits) {
2545 uint64_t
bc = ctpDigit.intRecord.toLong();
2546 uint64_t classMask = ctpDigit.CTPClassMask.to_ulong();
2547 uint64_t inputMask = ctpDigit.CTPInputMask.to_ulong();
2548 if (emcalIncomplete.find(
bc) != emcalIncomplete.end()) {
2550 auto classMaskOrig = classMask;
2551 classMask = classMask & ~mEMCALTrgClassMask;
2552 LOG(
debug) <<
"Found EMCAL incomplete event, mask before " << std::bitset<64>(classMaskOrig) <<
", after " << std::bitset<64>(classMask);
2554 bcToClassMask[
bc] = {classMask, inputMask};
2560 bcCursor.reserve(bcsMap.size());
2561 for (
auto& item : bcsMap) {
2562 uint64_t
bc = item.first;
2563 std::pair<uint64_t, uint64_t> masks{0, 0};
2565 auto bcClassPair = bcToClassMask.find(
bc);
2566 if (bcClassPair != bcToClassMask.end()) {
2567 masks = bcClassPair->second;
2576 bcToClassMask.clear();
2579 auto bcFlags = fillBCFlags(recoData, bcsMap);
2580 bcFlagsCursor.reserve(bcFlags.size());
2581 for (
auto f : bcFlags) {
2588 cpvClustersCursor.reserve(cpvTrigRecs.size());
2589 for (
auto& cpvEvent : cpvTrigRecs) {
2590 uint64_t
bc = cpvEvent.getBCData().toLong();
2591 auto item = bcsMap.find(
bc);
2593 if (item != bcsMap.end()) {
2594 bcID = item->second;
2596 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a CPV Trigger Record; BC = " <<
bc;
2598 for (
int iClu = cpvEvent.getFirstEntry(); iClu < cpvEvent.getFirstEntry() + cpvEvent.getNumberOfObjects(); iClu++) {
2599 auto&
clu = cpvClusters[iClu];
2600 clu.getLocalPosition(posX, posZ);
2601 cpvClustersCursor(bcID,
2602 truncateFloatFraction(posX, mCPVPos),
2603 truncateFloatFraction(posZ, mCPVPos),
2604 truncateFloatFraction(
clu.getEnergy(), mCPVAmpl),
2605 clu.getPackedClusterStatus());
2614 fillMCParticlesTable(*mcReader,
2615 mcParticlesCursor.
cursor,
2621 LOG(info) <<
"FILL MC took " << timer.RealTime() <<
" s";
2622 mcColToEvSrc.clear();
2628 fillMCTrackLabelsTable(mcTrackLabelCursor, mcMFTTrackLabelCursor, mcFwdTrackLabelCursor, primVer2TRefs.back(), primVerGIs, recoData);
2629 for (
auto iref = 0U; iref < primVer2TRefs.size() - 1; iref++) {
2630 auto& trackRef = primVer2TRefs[iref];
2631 fillMCTrackLabelsTable(mcTrackLabelCursor, mcMFTTrackLabelCursor, mcFwdTrackLabelCursor, trackRef, primVerGIs, recoData, iref);
2637 fillCaloTable(caloCellsCursor, caloCellsTRGTableCursor, mcCaloLabelsCursor, bcsMap, recoData);
2642 mGIDToTableID.clear();
2644 mGIDToTableFwdID.clear();
2646 mGIDToTableMFTID.clear();
2648 mVtxToTableCollID.clear();
2650 mV0ToTableID.clear();
2653 mIndexTableFwd.clear();
2655 mIndexTableMFT.clear();
2660 mGIDUsedBySVtx.clear();
2661 mGIDUsedByStr.clear();
2663 originCursor(tfNumber);
2666 TString dataType = mUseMC ?
"MC" :
"RAW";
2668 TString ROOTVersion = ROOT_RELEASE;
2669 mMetaDataKeys = {
"DataType",
"Run",
"O2Version",
"ROOTVersion",
"RecoPassName",
"AnchorProduction",
"AnchorPassName",
"LPMProductionTag",
"CreatedBy"};
2670 mMetaDataVals = {dataType,
"3", O2Version, ROOTVersion, mRecoPass, mAnchorProd, mAnchorPass, mLPMProdTag, mUser};
2671 add_additional_meta_info(mMetaDataKeys, mMetaDataVals);
2689 for (
const auto& rof : rofs) {
2690 int first = rof.getFirstEntry(), last =
first + rof.getNEntries();
2691 for (
int i =
first;
i < last;
i++) {
2692 mITSROFs.push_back(
count);
2702 for (
const auto& rof : rofs) {
2703 int first = rof.getFirstEntry(),
last =
first + rof.getNEntries();
2705 mMFTROFs.push_back(
count);
2712 mITSTPCTRDTriggers.clear();
2715 for (
const auto& trig : itstpctrigs) {
2716 int first = trig.getFirstTrack(),
last =
first + trig.getNumberOfTracks();
2718 mITSTPCTRDTriggers.push_back(
count);
2725 mTPCTRDTriggers.clear();
2728 for (
const auto& trig : tpctrigs) {
2729 int first = trig.getFirstTrack(),
last =
first + trig.getNumberOfTracks();
2731 mTPCTRDTriggers.push_back(
count);
2741 for (
const auto& rof : rofs) {
2744 mMCHROFs.push_back(
count);
2751AODProducerWorkflowDPL::TrackExtraInfo AODProducerWorkflowDPL::processBarrelTrack(
int collisionID, std::uint64_t collisionBC,
GIndex trackIndex,
2754 TrackExtraInfo extraInfoHolder;
2755 if (collisionID < 0) {
2758 bool needBCSlice = collisionID < 0;
2759 uint64_t bcOfTimeRef = collisionBC - mStartIR.
toLong();
2761 auto setTrackTime = [&](
double t,
double terr,
bool gaussian) {
2767 extraInfoHolder.trackTimeRes = terr;
2769 double error = this->mTimeMarginTrackTime + (gaussian ? extraInfoHolder.trackTimeRes * this->mNSigmaTimeTrack : extraInfoHolder.trackTimeRes);
2770 bcOfTimeRef = fillBCSlice(extraInfoHolder.bcSlice, t - error, t + error, bcsMap);
2773 extraInfoHolder.diffBCRef =
int(bcOfTimeRef);
2775 truncateFloatFraction(extraInfoHolder.trackTime, mTrackTime), truncateFloatFraction(extraInfoHolder.trackTimeRes, mTrackTimeError),
2778 auto contributorsGID =
data.getSingleDetectorRefs(trackIndex);
2779 const auto& trackPar =
data.getTrackParam(trackIndex);
2780 extraInfoHolder.flags |= trackPar.getPID() << 28;
2781 auto src = trackIndex.getSource();
2783 const auto& tofMatch =
data.getTOFMatch(trackIndex);
2784 extraInfoHolder.tofChi2 = tofMatch.getChi2();
2785 const auto& tofInt = tofMatch.getLTIntegralOut();
2786 float intLen = tofInt.getL();
2787 extraInfoHolder.length = intLen;
2794 extraInfoHolder.tofExpMom = mass * expBeta / std::sqrt(1.f - expBeta * expBeta);
2797 const double massZ = o2::track::PID::getMass2Z(trackPar.getPID());
2798 const double energy = sqrt((massZ * massZ) + (extraInfoHolder.tofExpMom * extraInfoHolder.tofExpMom));
2799 const double exp = extraInfoHolder.length * energy / (cSpeed * extraInfoHolder.tofExpMom);
2800 auto tofSignal = (tofMatch.getSignal() -
exp) * 1e-3;
2801 setTrackTime(tofSignal, 0.2,
true);
2805 extraInfoHolder.trdChi2 = trdOrig.getChi2();
2806 extraInfoHolder.trdSignal = trdOrig.getSignal();
2807 extraInfoHolder.trdPattern = getTRDPattern(trdOrig);
2808 if (extraInfoHolder.trackTimeRes < 0.) {
2810 const auto& trdTrig = (
src ==
GIndex::Source::TPCTRD) ?
data.getTPCTRDTriggers()[mTPCTRDTriggers[trackIndex.getIndex()]] :
data.getITSTPCTRDTriggers()[mITSTPCTRDTriggers[trackIndex.getIndex()]];
2812 setTrackTime(ttrig, 1.,
true);
2816 const auto& itsTrack =
data.getITSTrack(contributorsGID[
GIndex::ITS]);
2817 int nClusters = itsTrack.getNClusters();
2818 float chi2 = itsTrack.getChi2();
2820 extraInfoHolder.itsClusterSizes = itsTrack.getClusterSizes();
2822 const auto& rof =
data.getITSTracksROFRecords()[mITSROFs[trackIndex.getIndex()]];
2824 setTrackTime(t, mITSROFrameHalfLengthNS,
false);
2827 extraInfoHolder.itsClusterSizes =
data.getITSABRefs()[contributorsGID[
GIndex::Source::ITSAB].getIndex()].getClusterSizes();
2831 const auto& tpcClData = mTPCCounters[contributorsGID[
GIndex::TPC]];
2832 const auto& dEdx = tpcOrig.getdEdx().dEdxTotTPC > 0 ? tpcOrig.getdEdx() : tpcOrig.getdEdxAlt();
2833 if (tpcOrig.getdEdx().dEdxTotTPC == 0) {
2836 if (tpcOrig.hasASideClusters()) {
2839 if (tpcOrig.hasCSideClusters()) {
2842 extraInfoHolder.tpcInnerParam = tpcOrig.getP() / tpcOrig.getAbsCharge();
2843 extraInfoHolder.tpcChi2NCl = tpcOrig.getNClusters() ? tpcOrig.getChi2() / tpcOrig.getNClusters() : 0;
2844 extraInfoHolder.tpcSignal = dEdx.dEdxTotTPC;
2845 extraInfoHolder.tpcNClsFindable = tpcOrig.getNClusters();
2846 extraInfoHolder.tpcNClsFindableMinusFound = tpcOrig.getNClusters() - tpcClData.found;
2847 extraInfoHolder.tpcNClsFindableMinusCrossedRows = tpcOrig.getNClusters() - tpcClData.crossed;
2848 extraInfoHolder.tpcNClsShared = tpcClData.shared;
2849 uint32_t clsUsedForPID = dEdx.NHitsIROC + dEdx.NHitsOROC1 + dEdx.NHitsOROC2 + dEdx.NHitsOROC3;
2850 extraInfoHolder.tpcNClsFindableMinusPID = tpcOrig.getNClusters() - clsUsedForPID;
2853 double t = (tpcOrig.getTime0() + 0.5 * (tpcOrig.getDeltaTFwd() - tpcOrig.getDeltaTBwd())) * mTPCBinNS;
2854 double terr = 0.5 * (tpcOrig.getDeltaTFwd() + tpcOrig.getDeltaTBwd()) * mTPCBinNS;
2855 double err = mTimeMarginTrackTime + terr;
2856 bcOfTimeRef = fillBCSlice(extraInfoHolder.bcSlice, t - err, t + err, bcsMap);
2859 p.setDeltaTFwd(tpcOrig.getDeltaTFwd());
2860 p.setDeltaTBwd(tpcOrig.getDeltaTBwd());
2861 extraInfoHolder.trackTimeRes =
p.getTimeErr();
2863 extraInfoHolder.diffBCRef =
int(bcOfTimeRef);
2864 extraInfoHolder.isTPConly =
true;
2867 const auto& trITSTPC =
data.getTPCITSTrack(trackIndex);
2868 auto ts = trITSTPC.getTimeMUS();
2869 setTrackTime(ts.getTimeStamp() * 1.e3, ts.getTimeStampError() * 1.e3,
true);
2873 extrapolateToCalorimeters(extraInfoHolder,
data.getTrackParamOut(trackIndex));
2878 return extraInfoHolder;
2881AODProducerWorkflowDPL::TrackQA AODProducerWorkflowDPL::processBarrelTrackQA(
int collisionID, std::uint64_t collisionBC,
GIndex trackIndex,
2885 auto contributorsGID =
data.getTPCContributorGID(trackIndex);
2886 const auto& trackPar =
data.getTrackParam(trackIndex);
2887 if (contributorsGID.isIndexSet()) {
2889 const auto& tpcOrig =
data.getTPCTrack(contributorsGID);
2894 std::array<float, 2> dcaInfo{-999., -999.};
2895 if (prop->propagateToDCABxByBz({v.getX(), v.getY(), v.getZ()}, tpcTMP, 2.f, mMatType, &dcaInfo)) {
2896 trackQAHolder.tpcdcaR = 100. * dcaInfo[0] / sqrt(1. + trackPar.getQ2Pt() * trackPar.getQ2Pt());
2897 trackQAHolder.tpcdcaZ = 100. * dcaInfo[1] / sqrt(1. + trackPar.getQ2Pt() * trackPar.getQ2Pt());
2901 auto safeInt8Clamp = [](
auto value) -> int8_t {
2902 using ValType =
decltype(
value);
2903 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()))));
2905 auto safeUInt8Clamp = [](
auto value) -> uint8_t {
2906 using ValType =
decltype(
value);
2907 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()))));
2911 uint8_t clusterCounters[8] = {0};
2913 uint8_t sectorIndex, rowIndex;
2914 uint32_t clusterIndex;
2915 const auto& tpcClusRefs =
data.getTPCTracksClusterRefs();
2916 for (
int i = 0;
i < tpcOrig.getNClusterReferences();
i++) {
2917 o2::tpc::TrackTPC::getClusterReference(tpcClusRefs,
i, sectorIndex, rowIndex, clusterIndex, tpcOrig.getClusterRef());
2918 char indexTracklet = (rowIndex % 152) / 19;
2919 clusterCounters[indexTracklet]++;
2923 for (
int i = 0;
i < 8;
i++) {
2924 if (clusterCounters[
i] > 5) {
2925 byteMask |= (1 <<
i);
2928 trackQAHolder.tpcTime0 = tpcOrig.getTime0();
2929 trackQAHolder.tpcClusterByteMask = byteMask;
2930 const auto& dEdxInfoAlt = tpcOrig.getdEdxAlt();
2931 const float dEdxNorm = (dEdxInfoAlt.dEdxTotTPC > 0) ? 100. / dEdxInfoAlt.dEdxTotTPC : 0;
2932 trackQAHolder.tpcdEdxNorm = dEdxInfoAlt.dEdxTotTPC;
2933 trackQAHolder.tpcdEdxMax0R = safeUInt8Clamp(dEdxInfoAlt.dEdxMaxIROC * dEdxNorm);
2934 trackQAHolder.tpcdEdxMax1R = safeUInt8Clamp(dEdxInfoAlt.dEdxMaxOROC1 * dEdxNorm);
2935 trackQAHolder.tpcdEdxMax2R = safeUInt8Clamp(dEdxInfoAlt.dEdxMaxOROC2 * dEdxNorm);
2936 trackQAHolder.tpcdEdxMax3R = safeUInt8Clamp(dEdxInfoAlt.dEdxMaxOROC3 * dEdxNorm);
2938 trackQAHolder.tpcdEdxTot0R = safeUInt8Clamp(dEdxInfoAlt.dEdxTotIROC * dEdxNorm);
2939 trackQAHolder.tpcdEdxTot1R = safeUInt8Clamp(dEdxInfoAlt.dEdxTotOROC1 * dEdxNorm);
2940 trackQAHolder.tpcdEdxTot2R = safeUInt8Clamp(dEdxInfoAlt.dEdxTotOROC2 * dEdxNorm);
2941 trackQAHolder.tpcdEdxTot3R = safeUInt8Clamp(dEdxInfoAlt.dEdxTotOROC3 * dEdxNorm);
2944 auto contributorsGIDA =
data.getSingleDetectorRefs(trackIndex);
2946 const auto& tofMatch =
data.getTOFMatch(trackIndex);
2947 const float qpt = trackPar.getQ2Pt();
2949 trackQAHolder.dTofdX = safeInt8Clamp(tofMatch.getDXatTOF() / scaleTOF);
2950 trackQAHolder.dTofdZ = safeInt8Clamp(tofMatch.getDZatTOF() / scaleTOF);
2956 if (
auto itsContGID =
data.getITSContributorGID(trackIndex); itsContGID.isIndexSet() && itsContGID.getSource() !=
GIndex::ITSAB) {
2957 const auto& itsOrig =
data.getITSTrack(itsContGID);
2966 const float beta0 = std::sqrt(std::min(50.f / tpcOrig.getdEdx().dEdxMaxTPC, 1.f));
2967 const float qpt = gloCopy.getQ2Pt();
2968 const float x = qpt / beta0;
2970 auto scaleCont = [&
x](
int i) ->
float {
2973 auto scaleGlo = [&
x](
int i) ->
float {
2978 trackQAHolder.dRefContY = safeInt8Clamp((itsCopy.getY() - tpcCopy.getY()) * scaleCont(0));
2979 trackQAHolder.dRefContZ = safeInt8Clamp((itsCopy.getZ() - tpcCopy.getZ()) * scaleCont(1));
2980 trackQAHolder.dRefContSnp = safeInt8Clamp((itsCopy.getSnp() - tpcCopy.getSnp()) * scaleCont(2));
2981 trackQAHolder.dRefContTgl = safeInt8Clamp((itsCopy.getTgl() - tpcCopy.getTgl()) * scaleCont(3));
2982 trackQAHolder.dRefContQ2Pt = safeInt8Clamp((itsCopy.getQ2Pt() - tpcCopy.getQ2Pt()) * scaleCont(4));
2984 trackQAHolder.dRefGloY = safeInt8Clamp(((itsCopy.getY() + tpcCopy.getY()) * 0.5f - gloCopy.getY()) * scaleGlo(0));
2985 trackQAHolder.dRefGloZ = safeInt8Clamp(((itsCopy.getZ() + tpcCopy.getZ()) * 0.5f - gloCopy.getZ()) * scaleGlo(1));
2986 trackQAHolder.dRefGloSnp = safeInt8Clamp(((itsCopy.getSnp() + tpcCopy.getSnp()) * 0.5f - gloCopy.getSnp()) * scaleGlo(2));
2987 trackQAHolder.dRefGloTgl = safeInt8Clamp(((itsCopy.getTgl() + tpcCopy.getTgl()) * 0.5f - gloCopy.getTgl()) * scaleGlo(3));
2988 trackQAHolder.dRefGloQ2Pt = safeInt8Clamp(((itsCopy.getQ2Pt() + tpcCopy.getQ2Pt()) * 0.5f - gloCopy.getQ2Pt()) * scaleGlo(4));
2992 (*mStreamer) <<
"trackQA"
2993 <<
"trackITSOrig=" << itsOrig
2994 <<
"trackTPCOrig=" << tpcOrig
2995 <<
"trackITSTPCOrig=" << trackPar
2996 <<
"trackITSProp=" << itsCopy
2997 <<
"trackTPCProp=" << tpcCopy
2998 <<
"trackITSTPCProp=" << gloCopy
3001 <<
"scaleCont0=" << scaleCont(0)
3002 <<
"scaleCont1=" << scaleCont(1)
3003 <<
"scaleCont2=" << scaleCont(2)
3004 <<
"scaleCont3=" << scaleCont(3)
3005 <<
"scaleCont4=" << scaleCont(4)
3006 <<
"scaleGlo0=" << scaleGlo(0)
3007 <<
"scaleGlo1=" << scaleGlo(1)
3008 <<
"scaleGlo2=" << scaleGlo(2)
3009 <<
"scaleGlo3=" << scaleGlo(3)
3010 <<
"scaleGlo4=" << scaleGlo(4)
3011 <<
"trackQAHolder.tpcTime0=" << trackQAHolder.tpcTime0
3012 <<
"trackQAHolder.tpcdEdxNorm=" << trackQAHolder.tpcdEdxNorm
3013 <<
"trackQAHolder.tpcdcaR=" << trackQAHolder.tpcdcaR
3014 <<
"trackQAHolder.tpcdcaZ=" << trackQAHolder.tpcdcaZ
3015 <<
"trackQAHolder.tpcdcaClusterByteMask=" << trackQAHolder.tpcClusterByteMask
3016 <<
"trackQAHolder.tpcdEdxMax0R=" << trackQAHolder.tpcdEdxMax0R
3017 <<
"trackQAHolder.tpcdEdxMax1R=" << trackQAHolder.tpcdEdxMax1R
3018 <<
"trackQAHolder.tpcdEdxMax2R=" << trackQAHolder.tpcdEdxMax2R
3019 <<
"trackQAHolder.tpcdEdxMax3R=" << trackQAHolder.tpcdEdxMax3R
3020 <<
"trackQAHolder.tpcdEdxTot0R=" << trackQAHolder.tpcdEdxTot0R
3021 <<
"trackQAHolder.tpcdEdxTot1R=" << trackQAHolder.tpcdEdxTot1R
3022 <<
"trackQAHolder.tpcdEdxTot2R=" << trackQAHolder.tpcdEdxTot2R
3023 <<
"trackQAHolder.tpcdEdxTot3R=" << trackQAHolder.tpcdEdxTot3R
3024 <<
"trackQAHolder.dRefContY=" << trackQAHolder.dRefContY
3025 <<
"trackQAHolder.dRefContZ=" << trackQAHolder.dRefContZ
3026 <<
"trackQAHolder.dRefContSnp=" << trackQAHolder.dRefContSnp
3027 <<
"trackQAHolder.dRefContTgl=" << trackQAHolder.dRefContTgl
3028 <<
"trackQAHolder.dRefContQ2Pt=" << trackQAHolder.dRefContQ2Pt
3029 <<
"trackQAHolder.dRefGloY=" << trackQAHolder.dRefGloY
3030 <<
"trackQAHolder.dRefGloZ=" << trackQAHolder.dRefGloZ
3031 <<
"trackQAHolder.dRefGloSnp=" << trackQAHolder.dRefGloSnp
3032 <<
"trackQAHolder.dRefGloTgl=" << trackQAHolder.dRefGloTgl
3033 <<
"trackQAHolder.dRefGloQ2Pt=" << trackQAHolder.dRefGloQ2Pt
3034 <<
"trackQAHolder.dTofdX=" << trackQAHolder.dTofdX
3035 <<
"trackQAHolder.dTofdZ=" << trackQAHolder.dTofdZ
3036 <<
"scaleTOF=" << scaleTOF
3043 return trackQAHolder;
3051 dcaInfo.set(999.f, 999.f, 999.f, 999.f, 999.f);
3056void AODProducerWorkflowDPL::extrapolateToCalorimeters(TrackExtraInfo& extraInfoHolder,
const o2::track::TrackPar& track)
3058 constexpr float XEMCAL = 440.f, XPHOS = 460.f, XEMCAL2 = XEMCAL * XEMCAL;
3059 constexpr float ETAEMCAL = 0.75;
3060 constexpr float ZEMCALFastCheck = 460.;
3061 constexpr float ETADCALINNER = 0.22;
3062 constexpr float ETAPHOS = 0.13653194;
3063 constexpr float ETAPHOSMARGIN = 0.17946979;
3064 constexpr float ETADCALPHOSSWITCH = (ETADCALINNER + ETAPHOS) / 2;
3065 constexpr short SNONE = 0, SEMCAL = 0x1, SPHOS = 0x2;
3066 constexpr short SECTORTYPE[18] = {
3067 SNONE, SNONE, SNONE, SNONE,
3068 SEMCAL, SEMCAL, SEMCAL, SEMCAL, SEMCAL, SEMCAL,
3071 SPHOS | SEMCAL, SPHOS | SEMCAL, SPHOS | SEMCAL,
3082 (std::abs(outTr.getZAt(xtrg, 0)) > ZEMCALFastCheck) ||
3083 !prop->PropagateToXBxByBz(outTr, xtrg, 0.95, 10, o2::base::Propagator::MatCorrType::USEMatCorrLUT)) {
3084 LOGP(
debug,
"preliminary step: does not reach R={} {}", XEMCAL, outTr.asString());
3088 if ((outTr.getX() * outTr.getX() + outTr.getY() * outTr.getY() < XEMCAL2) &&
3089 (!outTr.rotateParam(outTr.getPhi()) ||
3091 !prop->PropagateToXBxByBz(outTr, xtrg, 0.95, 10, o2::base::Propagator::MatCorrType::USEMatCorrLUT))) {
3092 LOGP(
debug,
"does not reach R={} {}", XEMCAL, outTr.asString());
3098 auto propExactSector = [&outTr, §or, prop](
float xprop) ->
bool {
3101 auto outTrTmp = outTr;
3103 if ((std::abs(outTr.getZ()) > ZEMCALFastCheck) || !outTrTmp.rotateParam(
alpha) ||
3104 !prop->PropagateToXBxByBz(outTrTmp, xprop, 0.95, 10, o2::base::Propagator::MatCorrType::USEMatCorrLUT)) {
3105 LOGP(
debug,
"failed on rotation to {} (sector {}) or propagation to X={} {}",
alpha, sector, xprop, outTrTmp.asString());
3110 if (sectorTmp == sector) {
3118 LOGP(
debug,
"failed to rotate to sector, {}", outTr.asString());
3125 if (!propExactSector(XEMCAL) || SECTORTYPE[sector] == SNONE) {
3130 float r = std::sqrt(outTr.getX() * outTr.getX() + outTr.getY() * outTr.getY()), tg = std::atan2(
r, outTr.getZ());
3131 float eta = -std::log(std::tan(0.5f * tg)), etaAbs = std::abs(eta);
3132 if (etaAbs > ETAEMCAL) {
3133 LOGP(
debug,
"eta = {} is off at EMCAL radius", eta, outTr.asString());
3137 if ((SECTORTYPE[sector] & SPHOS) && etaAbs < ETADCALPHOSSWITCH) {
3138 if (!propExactSector(XPHOS)) {
3141 r = std::sqrt(outTr.getX() * outTr.getX() + outTr.getY() * outTr.getY());
3142 tg = std::atan2(
r, outTr.getZ());
3143 eta = -std::log(std::tan(0.5f * tg));
3144 }
else if (!(SECTORTYPE[sector] & SEMCAL)) {
3147 extraInfoHolder.trackPhiEMCAL = outTr.getPhiPos();
3148 extraInfoHolder.trackEtaEMCAL = eta;
3149 LOGP(
debug,
"eta = {} phi = {} sector {} for {}", extraInfoHolder.trackEtaEMCAL, extraInfoHolder.trackPhiEMCAL, sector, outTr.asString());
3153std::set<uint64_t> AODProducerWorkflowDPL::filterEMCALIncomplete(
const gsl::span<const o2::emcal::TriggerRecord> triggers)
3155 std::set<uint64_t> emcalIncompletes;
3156 for (
const auto& trg : triggers) {
3157 if (trg.getTriggerBits() & o2::emcal::triggerbits::Inc) {
3159 emcalIncompletes.insert(trg.getBCData().toLong());
3162 return emcalIncompletes;
3168 static bool initOnceDone =
false;
3169 if (!initOnceDone) {
3170 initOnceDone =
true;
3177 for (
auto i = 0U;
i < bs.size();
i++) {
3192 mTPCBinNS = elParam.ZbinWidth * 1.e3;
3195 mNSigmaTimeTrack = pvParams.nSigmaTimeTrack;
3196 mTimeMarginTrackTime = pvParams.timeMarginTrackTime * 1.e3;
3200 if (mEnableTRDextra) {
3222 LOG(info) <<
"ITS Alpide param updated";
3224 par.printKeyValues();
3228 LOG(info) <<
"MFT Alpide param updated";
3230 par.printKeyValues();
3241 mEMCALTrgClassMask = 0;
3242 for (
const auto& trgclass : ctpconfig.getCTPClasses()) {
3244 mEMCALTrgClassMask |= trgclass.classMask;
3247 LOG(info) <<
"Loaded EMCAL trigger class mask: " << std::bitset<64>(mEMCALTrgClassMask);
3251void AODProducerWorkflowDPL::addRefGlobalBCsForTOF(
const o2::dataformats::VtxTrackRef& trackRef,
const gsl::span<const GIndex>& GIndices,
3262 int nbitsFrac = 24 - (32 - o2::math_utils::popcount(mTrackTime));
3263 int nbitsLoss = std::max(0,
int(std::log2(TOFTimePrecPS)));
3264 assert(nbitsFrac > 1);
3265 std::uint64_t maxRangePS = std::uint64_t(0x1) << (nbitsFrac + nbitsLoss);
3267 LOG(info) <<
"Max gap of " << maxGapBC <<
" BCs to closest globalBC reference is needed for TOF tracks to provide precision of "
3268 << TOFTimePrecPS <<
" ps";
3271 if (!trackRef.getEntries()) {
3275 std::uint64_t maxBC = mStartIR.
toLong();
3276 const auto& tofClus =
data.getTOFClusters();
3283 for (
int ti =
start; ti <
end; ti++) {
3284 auto& trackIndex = GIndices[ti];
3285 const auto& tofMatch =
data.getTOFMatch(trackIndex);
3286 const auto& tofInt = tofMatch.getLTIntegralOut();
3287 float intLen = tofInt.getL();
3288 float tofExpMom = 0.;
3298 double massZ = o2::track::PID::getMass2Z(
data.getTrackParam(trackIndex).getPID());
3299 double energy = sqrt((massZ * massZ) + (tofExpMom * tofExpMom));
3300 double exp = intLen * energy / (cSpeed * tofExpMom);
3301 auto tofSignal = (tofMatch.getSignal() -
exp) * 1e-3;
3302 auto bc = relativeTime_to_GlobalBC(tofSignal);
3304 auto it = bcsMap.lower_bound(
bc);
3305 if (it == bcsMap.end() || it->first >
bc + maxGapBC) {
3306 bcsMap.emplace_hint(it,
bc, 1);
3315 if ((--bcsMap.end())->first <= maxBC) {
3316 bcsMap.emplace_hint(bcsMap.end(), maxBC + 1, 1);
3320 for (
auto& item : bcsMap) {
3326std::uint64_t AODProducerWorkflowDPL::fillBCSlice(
int (&slice)[2],
double tmin,
double tmax,
const std::map<uint64_t, int>& bcsMap)
const
3338 uint64_t bcMin = relativeTime_to_GlobalBC(tmin), bcMax = relativeTime_to_GlobalBC(tmax);
3361 auto upperindex =
p.first;
3362 while (upperindex < bcvector.size() && bcvector[upperindex] <= bcMax) {
3365 if (upperindex !=
p.first) {
3369 slice[1] = upperindex;
3371 auto bcOfTimeRef =
p.second - this->mStartIR.
toLong();
3372 LOG(
debug) <<
"BC slice t:" << tmin <<
" " << slice[0]
3373 <<
" t: " << tmax <<
" " << slice[1]
3374 <<
" bcref: " << bcOfTimeRef;
3380 std::vector<uint8_t>
flags(bcsMap.size());
3383 auto bcIt = bcsMap.begin();
3384 auto itsrofs =
data.getITSTracksROFRecords();
3387 for (
auto& rof : itsrofs) {
3388 if (!rof.getFlag(o2::itsmft::ROFRecord::VtxUPCMode)) {
3391 uint64_t globalBC0 = rof.getBCData().toLong() + bROF, globalBC1 = globalBC0 + lROF - 1;
3393 while (bcIt != bcsMap.end()) {
3394 if (bcIt->first < globalBC0) {
3398 if (bcIt->first > globalBC1) {
3410 LOGF(info,
"aod producer dpl total timing: Cpu: %.3e Real: %.3e s in %d slots",
3411 mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1);
3418 auto dataRequest = std::make_shared<DataRequest>();
3419 dataRequest->inputs.emplace_back(
"ctpconfig",
"CTP",
"CTPCONFIG", 0, Lifetime::Condition,
ccdbParamSpec(
"CTP/Config/Config", CTPConfigPerRun));
3421 dataRequest->requestTracks(
src, useMC);
3422 dataRequest->requestPrimaryVertices(useMC);
3424 dataRequest->requestCTPDigits(useMC);
3427 dataRequest->requestSecondaryVertices(useMC);
3429 if (enableStrangenessTracking) {
3430 dataRequest->requestStrangeTracks(useMC);
3431 LOGF(info,
"requestStrangeTracks Finish");
3440 dataRequest->requestTOFClusters(useMC);
3443 dataRequest->requestPHOSCells(useMC);
3446 dataRequest->requestTRDTracklets(
false);
3449 dataRequest->requestEMCALCells(useMC);
3452 dataRequest->requestCPVClusters(useMC);
3455 auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(
true,
3461 dataRequest->inputs,
3464 dataRequest->inputs.emplace_back(
"meanvtx",
"GLO",
"MEANVERTEX", 0, Lifetime::Condition,
ccdbParamSpec(
"GLO/Calib/MeanVertex", {}, 1));
3469 std::vector<OutputSpec> outputs{
3508 if (enableTRDextra) {
3510 dataRequest->inputs.emplace_back(
"trdlocalgainfactors",
"TRD",
"LOCALGAINFACTORS", 0, Lifetime::Condition,
ccdbParamSpec(
"TRD/Calib/LocalGainFactor"));
3511 dataRequest->inputs.emplace_back(
"trdnoisemap",
"TRD",
"NOISEMAP", 0, Lifetime::Condition,
ccdbParamSpec(
"TRD/Calib/NoiseMapMCM"));
3512 dataRequest->inputs.emplace_back(
"trdgaincalib",
"TRD",
"CALGAIN", 0, Lifetime::Condition,
ccdbParamSpec(
"TRD/Calib/CalGain"));
3516 outputs.insert(outputs.end(),
3517 {OutputForTable<McCollisions>::spec(),
3518 OutputForTable<HepMCXSections>::spec(),
3519 OutputForTable<HepMCPdfInfos>::spec(),
3520 OutputForTable<HepMCHeavyIons>::spec(),
3521 OutputForTable<McMFTTrackLabels>::spec(),
3522 OutputForTable<McFwdTrackLabels>::spec(),
3523 OutputForTable<StoredMcParticles_001>::spec(),
3524 OutputForTable<McTrackLabels>::spec(),
3525 OutputForTable<McCaloLabels_001>::spec(),
3530 {OutputLabel{
"McCollisionLabels"},
"AOD",
"MCCOLLISIONLABEL", 0, Lifetime::Timeframe}});
3534 "aod-producer-workflow",
3537 AlgorithmSpec{adaptFromTask<AODProducerWorkflowDPL>(
src, dataRequest, ggRequest, enableSV, useMC, enableFITextra, enableTRDextra)},
3539 ConfigParamSpec{
"run-number", VariantType::Int64, -1L, {
"The run-number. If left default we try to get it from DPL header."}},
3540 ConfigParamSpec{
"aod-timeframe-id", VariantType::Int64, -1L, {
"Set timeframe number"}},
3541 ConfigParamSpec{
"fill-calo-cells", VariantType::Int, 1, {
"Fill calo cells into cell table"}},
3542 ConfigParamSpec{
"enable-truncation", VariantType::Int, 1, {
"Truncation parameter: 1 -- on, != 1 -- off"}},
3543 ConfigParamSpec{
"lpmp-prod-tag", VariantType::String,
"", {
"LPMProductionTag"}},
3544 ConfigParamSpec{
"anchor-pass", VariantType::String,
"", {
"AnchorPassName"}},
3545 ConfigParamSpec{
"anchor-prod", VariantType::String,
"", {
"AnchorProduction"}},
3546 ConfigParamSpec{
"reco-pass", VariantType::String,
"", {
"RecoPassName"}},
3547 ConfigParamSpec{
"aod-parent", VariantType::String,
"", {
"Parent AOD file name (if any)"}},
3548 ConfigParamSpec{
"created-by", VariantType::String,
"", {
"Who created this AO2D"}},
3549 ConfigParamSpec{
"nthreads", VariantType::Int, std::max(1,
int(std::thread::hardware_concurrency() / 2)), {
"Number of threads"}},
3550 ConfigParamSpec{
"reco-mctracks-only", VariantType::Int, 0, {
"Store only reconstructed MC tracks and their mothers/daughters. 0 -- off, != 0 -- on"}},
3551 ConfigParamSpec{
"ctpreadout-create", VariantType::Int, 0, {
"Create CTP digits from detector readout and CTP inputs. !=1 -- off, 1 -- on"}},
3552 ConfigParamSpec{
"emc-select-leading", VariantType::Bool,
false, {
"Flag to select if only the leading contributing particle for an EMCal cell should be stored"}},
3553 ConfigParamSpec{
"propagate-tracks", VariantType::Bool,
false, {
"Propagate tracks (not used for secondary vertices) to IP"}},
3554 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)"}},
3555 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)"}},
3556 ConfigParamSpec{
"propagate-muons", VariantType::Bool,
false, {
"Propagate muons to IP"}},
3557 ConfigParamSpec{
"store-all-mft-cov", VariantType::Bool,
false, {
"Store covariance matrices for all MFT tracks"}},
3558 ConfigParamSpec{
"thin-tracks", VariantType::Bool,
false, {
"Produce thinned track tables"}},
3559 ConfigParamSpec{
"trackqc-keepglobaltracks", VariantType::Bool,
false, {
"Always keep TrackQA for global tracks"}},
3560 ConfigParamSpec{
"trackqc-retainonlydedx", VariantType::Bool,
false, {
"Keep only dEdx information, zero out everything else"}},
3561 ConfigParamSpec{
"trackqc-fraction", VariantType::Float, float(0.1), {
"Fraction of tracks to QC"}},
3562 ConfigParamSpec{
"trackqc-NTrCut", VariantType::Int64, 4L, {
"Minimal length of the track - in amount of tracklets"}},
3563 ConfigParamSpec{
"trackqc-tpc-dca", VariantType::Float, 3.f, {
"Keep TPC standalone track with this DCAxy to the PV"}},
3564 ConfigParamSpec{
"trackqc-tpc-cls", VariantType::Int, 80, {
"Keep TPC standalone track with this #clusters"}},
3565 ConfigParamSpec{
"trackqc-tpc-pt", VariantType::Float, 0.2f, {
"Keep TPC standalone track with this pt"}},
3566 ConfigParamSpec{
"with-streamers", VariantType::String,
"", {
"Bit-mask to steer writing of intermediate streamer files"}},
3567 ConfigParamSpec{
"seed", VariantType::Int, 0, {
"Set seed for random generator used for sampling (0 (default) means using a random_device)"}},
3568 ConfigParamSpec{
"mc-signal-filt", VariantType::Bool,
false, {
"Enable usage of signal filtering (only for MC with embedding)"}}}};
Class to refer to the reconstructed information.
Definition of the 32 Central Trigger System (CTS) Trigger Types defined in https://twiki....
General auxilliary methods.
uint64_t exp(uint64_t base, uint8_t exp) noexcept
definition of CTPDigit, CTPInputDigit
Header of the AggregatedRunInfo struct.
Global Forward Muon tracks.
Global index for barrel track: provides provenance (detectors combination), index in respective array...
Definition of the MCTrack class.
Definition of a container to keep Monte Carlo truth external to simulation objects.
Utility functions for MC particles.
Class to perform MFT MCH (and MID) matching.
Class to store the output of the matching to HMPID.
Class to perform TOF matching to global tracks.
Definition of the parameter class for the detector electronics.
Header to collect physics constants.
Definition of the FDD RecPoint class.
Definition of the ITS track.
Definition of the MUON track.
Definition of the MCH track.
Definition of the MCH track parameters for internal use.
Result of refitting TPC-ITS matched track.
Extention of GlobalTrackID by flags relevant for verter-track association.
Referenc on track indices contributing to the vertex, with possibility chose tracks from specific sou...
Container class to store energy released in the ZDC.
Container class to store a TDC hit in a ZDC channel.
const auto & getBCPattern() const
void GetStartVertex(TVector3 &vertex) const
void endOfStream(framework::EndOfStreamContext &ec) final
This is invoked whenever we have an EndOfStream event.
void finaliseCCDB(ConcreteDataMatcher &matcher, void *obj) final
void run(ProcessingContext &pc) final
void init(InitContext &ic) final
std::pair< size_t, uint64_t > lower_bound(uint64_t timestamp) const
void init(std::map< uint64_t, int > const &bcs)
initialize this container (to be ready for lookup/search queries)
void clear()
clear/reset this container
std::vector< uint64_t > const & getBCTimeVector() const
return the sorted vector of increaing BC times
static float getAmplitude(const o2::emcal::Cell &cell)
static int16_t getLnAmplitude(const o2::emcal::Cell &)
static int8_t getTriggerBits(const o2::emcal::Cell &)
static int16_t getCellNumber(const o2::emcal::Cell &cell)
static int16_t getFastOrAbsID(const o2::emcal::Cell &)
static bool isTRU(const o2::emcal::Cell &cell)
static float getTimeStamp(const o2::emcal::Cell &cell)
void checkUpdates(o2::framework::ProcessingContext &pc)
static GRPGeomHelper & instance()
void setRequest(std::shared_ptr< GRPGeomRequest > req)
static constexpr float MAX_SIN_PHI
static constexpr float MAX_STEP
GPUd() value_type estimateLTFast(o2 static GPUd() float estimateLTIncrement(const o2 PropagatorImpl * Instance(bool uninitialized=false)
static const DPLAlpideParam< N > & Instance()
void printStream(std::ostream &stream) const
Static class with identifiers, bitmasks and names for ALICE detectors.
Handler for EMCAL event data.
void reset()
Reset containers with empty ranges.
void setCellData(CellRange cells, TriggerRange triggers)
Setting the data at cell level.
void setCellMCTruthContainer(const o2::dataformats::MCTruthContainer< o2::emcal::MCLabel > *mclabels)
Setting the pointer for the MCTruthContainer for cells.
InteractionRecord getInteractionRecordForEvent(int eventID) const
Get the interaction record for the given event.
int getNumberOfEvents() const
Get the number of events handled by the event handler.
T get(const char *key) const
void snapshot(const Output &spec, T const &object)
ConfigParamRegistry const & options()
DataAllocator & outputs()
The data allocator is used to allocate memory for the output data.
InputRecord & inputs()
The inputs associated with this processing context.
ServiceRegistryRef services()
The services registry associated with this processing context.
static constexpr int NCellsA
o2::dataformats::GlobalFwdTrack MCHtoFwd(const o2::mch::TrackParam &mchTrack)
Converts mchTrack parameters to Forward coordinate system.
track parameters for internal use
Double_t getNonBendingCoor() const
return non bending coordinate (cm)
Double_t getBendingCoor() const
return bending coordinate (cm)
void setCellMCTruthContainer(const o2::dataformats::MCTruthContainer< o2::phos::MCLabel > *mclabels)
Setting the pointer for the MCTruthContainer for cells.
void setCellData(CellRange cells, TriggerRange triggers)
Setting the data at cell level.
void reset()
Reset containers with empty ranges.
InteractionRecord getInteractionRecordForEvent(int eventID) const
int getNumberOfEvents() const
MCTrack const * getTrack(o2::MCCompLabel const &) const
void releaseTracksForSourceAndEvent(int source, int event)
API to ask releasing tracks (freeing memory) for source + event.
std::vector< MCTrack > const & getTracks(int source, int event) const
variant returning all tracks for source and event at once
static void addInteractionBC(int bc, bool fromCollisonCotext=false)
float getMPVdEdx(int iDet, bool defaultAvg=true) const
Simple noise status bit for each MCM of the TRD.
bool isTrackletFromNoisyMCM(const Tracklet64 &trklt) const
T getValue(int roc, int col, int row) const
void set(const std::string &s, int base=DefaultBase)
bool match(const std::vector< std::string > &queries, const char *pattern)
GLfloat GLfloat GLfloat alpha
GLint GLint GLsizei GLuint * counters
GLuint GLuint GLfloat weight
GLboolean GLboolean GLboolean b
GLsizei GLsizei GLchar * source
GLsizei const GLfloat * value
GLint GLint GLsizei GLint GLenum GLenum type
GLenum GLsizei GLsizei GLint * values
GLuint GLsizei const GLchar * label
GLboolean GLboolean GLboolean GLboolean a
constexpr std::array< float, 2 > trackQAScaledTOF
constexpr std::array< float, 5 > trackQAScaleContP1
uint8_t itsSharedClusterMap uint8_t
constexpr std::array< float, 5 > trackQAScaleContP0
constexpr std::array< float, 5 > trackQAScaleGloP0
constexpr std::array< float, 5 > trackQAScaleGloP1
constexpr float trackQAScaleBins
constexpr float trackQARefRadius
bool updateHepMCHeavyIon(const HeavyIonCursor &cursor, int collisionID, short generatorID, o2::dataformats::MCEventHeader const &header, HepMCUpdate when=HepMCUpdate::anyKey)
short updateMCCollisions(const CollisionCursor &cursor, int bcId, float time, o2::dataformats::MCEventHeader const &header, short generatorId=0, int sourceId=0, unsigned int mask=0xFFFFFFF0)
bool updateHepMCPdfInfo(const PdfInfoCursor &cursor, int collisionID, short generatorID, o2::dataformats::MCEventHeader const &header, HepMCUpdate when=HepMCUpdate::anyKey)
uint32_t updateParticles(const ParticleCursor &cursor, int collisionID, std::vector< MCTrack > const &tracks, TrackToIndex &preselect, uint32_t offset=0, bool filter=false, bool background=false, uint32_t weightMask=0xFFFFFFF0, uint32_t momentumMask=0xFFFFFFF0, uint32_t positionMask=0xFFFFFFF0, bool signalFilter=false)
bool updateHepMCXSection(const XSectionCursor &cursor, int collisionID, short generatorID, o2::dataformats::MCEventHeader const &header, HepMCUpdate when=HepMCUpdate::anyKey)
framework::DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool enableSV, bool enableST, bool useMC, bool CTPConfigPerRun, bool enableFITextra, bool enableTRDextra)
create a processor spec
void keepMCParticle(std::vector< std::vector< std::unordered_map< int, int > > > &store, int source, int event, int track, int value=1, bool useSigFilt=false)
void dimensionMCKeepStore(std::vector< std::vector< std::unordered_map< int, int > > > &store, int Nsources, int NEvents)
void clearMCKeepStore(std::vector< std::vector< std::unordered_map< int, int > > > &store)
constexpr int LHCMaxBunches
constexpr double LHCBunchSpacingNS
constexpr double MassPionCharged
Defining ITS Vertex 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)
constexpr float MPVDEDXDEFAULT
default Most Probable Value of TRD dEdx
const int TDCSignal[NTDCChannels]
constexpr int NTDCChannels
std::string fullVersion()
get full version information (official O2 release and git commit)
helper struct to keep mapping of colIndex to MC labels and bunch crossing
static constexpr auto 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
const U & getTrack(int src, int id) const
o2::InteractionRecord startIR
GlobalIDSet getSingleDetectorRefs(GTrackID gidx) const
auto getDecays3BodyIdx() const
const o2::tpc::TrackTPC & getTPCTrack(GTrackID id) const
gsl::span< const o2::trd::CalibratedTracklet > getTRDCalibratedTracklets() 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
const o2::dataformats::TrackTPCITS & getTPCITSTrack(GTrackID gid) 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
gsl::span< const o2::trd::Tracklet64 > getTRDTracklets() 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