91#include "Math/SMatrix.h"
98#include <unordered_map>
103#include "TLorentzVector.h"
111#include <nlohmann/json.hpp>
132 uint64_t classMaskEMCAL = 0, classMaskTRD = 0, classMaskPHOSCPV = 0;
133 for (
const auto& trgclass : ctpcfg->getCTPClasses()) {
134 if (trgclass.cluster->getClusterDetNames().find(
"EMC") != std::string::npos) {
135 classMaskEMCAL = trgclass.classMask;
137 if (trgclass.cluster->getClusterDetNames().find(
"PHS") != std::string::npos) {
138 classMaskPHOSCPV = trgclass.classMask;
140 if (trgclass.cluster->getClusterDetNames().find(
"TRD") != std::string::npos) {
141 classMaskTRD = trgclass.classMask;
144 LOG(info) <<
"createCTPReadout: Class Mask EMCAL -> " << classMaskEMCAL;
145 LOG(info) <<
"createCTPReadout: Class Mask PHOS/CPV -> " << classMaskPHOSCPV;
146 LOG(info) <<
"createCTPReadout: Class Mask TRD -> " << classMaskTRD;
154 std::vector<o2::emcal::TriggerRecord> triggerRecordEMCALPhys;
155 for (
const auto& trg : triggerrecordEMCAL) {
159 triggerRecordEMCALPhys.push_back(trg);
165 std::set<uint64_t> bcsMapT0triggers;
167 for (
auto& ft0RecPoint : ft0RecPoints) {
168 auto t0triggers = ft0RecPoint.getTrigger();
169 if (t0triggers.getVertex()) {
170 uint64_t globalBC = ft0RecPoint.getInteractionRecord().toLong();
171 bcsMapT0triggers.insert(globalBC);
175 auto genericCTPDigitizer = [&bcsMapT0triggers, &ctpDigits](
auto triggerrecords, uint64_t classmask) ->
int {
179 uint32_t orbitPrev = 0;
181 for (
auto& trigger : triggerrecords) {
182 auto orbitPrevT = orbitPrev;
183 auto bcPrevT = bcPrev;
184 bcPrev = trigger.getBCData().bc;
185 orbitPrev = trigger.getBCData().orbit;
187 if (orbitPrev < orbitPrevT || bcPrev >= o2::constants::lhc::LHCMaxBunches || (orbitPrev == orbitPrevT && bcPrev < bcPrevT)) {
191 uint64_t globalBC = trigger.getBCData().toLong();
192 auto t0entry = bcsMapT0triggers.find(globalBC);
193 if (t0entry != bcsMapT0triggers.end()) {
194 auto ctpdig = std::find_if(ctpDigits.begin(), ctpDigits.end(), [globalBC](
const o2::ctp::CTPDigit& dig) { return static_cast<uint64_t>(dig.intRecord.toLong()) == globalBC; });
195 if (ctpdig != ctpDigits.end()) {
197 ctpdig->CTPClassMask |= std::bitset<64>(classmask);
198 LOG(
debug) <<
"createCTPReadout: Merging " << classmask <<
" CTP digits with existing digit, CTP mask " << ctpdig->CTPClassMask;
201 LOG(
debug) <<
"createCTPReadout: New CTP digit needed for class " << classmask << std::endl;
202 auto& ctpdigNew = ctpDigits.emplace_back();
203 ctpdigNew.intRecord.setFromLong(globalBC);
204 ctpdigNew.CTPClassMask = classmask;
207 LOG(warning) <<
"createCTPReadout: Found " << classmask <<
" and no MTVX:" << globalBC;
214 auto warningsTRD = genericCTPDigitizer(triggerrecordTRD, classMaskTRD);
215 auto warningsEMCAL = genericCTPDigitizer(triggerRecordEMCALPhys, classMaskEMCAL);
216 auto warningsPHOSCPV = genericCTPDigitizer(triggerrecordPHOSCPV, classMaskPHOSCPV);
218 LOG(info) <<
"createCTPReadout:# of TRD bogus triggers:" << warningsTRD;
219 LOG(info) <<
"createCTPReadout:# of EMCAL bogus triggers:" << warningsEMCAL;
220 LOG(info) <<
"createCTPReadout:# of PHOS/CPV bogus triggers:" << warningsPHOSCPV;
224 const std::vector<o2::InteractionTimeRecord>& mcRecords,
225 std::map<uint64_t, int>& bcsMap)
227 const auto& primVertices =
data.getPrimaryVertices();
228 const auto& fddRecPoints =
data.getFDDRecPoints();
229 const auto& ft0RecPoints =
data.getFT0RecPoints();
230 const auto& fv0RecPoints =
data.getFV0RecPoints();
231 const auto& caloEMCCellsTRGR =
data.getEMCALTriggers();
232 const auto& caloPHOSCellsTRGR =
data.getPHOSTriggers();
233 const auto& cpvTRGR =
data.getCPVTriggers();
234 const auto& ctpDigits =
data.getCTPDigits();
235 const auto& zdcBCRecData =
data.getZDCBCRecData();
237 bcsMap[mStartIR.
toLong()] = 1;
240 for (
auto&
rec : mcRecords) {
241 uint64_t globalBC =
rec.toLong();
242 bcsMap[globalBC] = 1;
245 for (
auto& fddRecPoint : fddRecPoints) {
246 uint64_t globalBC = fddRecPoint.getInteractionRecord().toLong();
247 bcsMap[globalBC] = 1;
250 for (
auto& ft0RecPoint : ft0RecPoints) {
251 uint64_t globalBC = ft0RecPoint.getInteractionRecord().toLong();
252 bcsMap[globalBC] = 1;
255 for (
auto& fv0RecPoint : fv0RecPoints) {
256 uint64_t globalBC = fv0RecPoint.getInteractionRecord().toLong();
257 bcsMap[globalBC] = 1;
260 for (
auto& zdcRecData : zdcBCRecData) {
261 uint64_t globalBC = zdcRecData.ir.toLong();
262 bcsMap[globalBC] = 1;
265 for (
auto&
vertex : primVertices) {
266 auto& timeStamp =
vertex.getTimeStamp();
267 double tsTimeStamp = timeStamp.getTimeStamp() * 1E3;
268 uint64_t globalBC = relativeTime_to_GlobalBC(tsTimeStamp);
269 bcsMap[globalBC] = 1;
272 for (
auto& emcaltrg : caloEMCCellsTRGR) {
273 uint64_t globalBC = emcaltrg.getBCData().toLong();
274 bcsMap[globalBC] = 1;
277 for (
auto& phostrg : caloPHOSCellsTRGR) {
278 uint64_t globalBC = phostrg.getBCData().toLong();
279 bcsMap[globalBC] = 1;
282 for (
auto& cpvtrg : cpvTRGR) {
283 uint64_t globalBC = cpvtrg.getBCData().toLong();
284 bcsMap[globalBC] = 1;
287 for (
auto& ctpDigit : ctpDigits) {
288 uint64_t globalBC = ctpDigit.intRecord.toLong();
289 bcsMap[globalBC] = 1;
293 for (
auto& item : bcsMap) {
299template <
typename TracksCursorType,
typename TracksCovCursorType>
300void AODProducerWorkflowDPL::addToTracksTable(TracksCursorType& tracksCursor, TracksCovCursorType& tracksCovCursor,
303 tracksCursor(collisionID,
305 truncateFloatFraction(track.getX(), mTrackX),
306 truncateFloatFraction(track.getAlpha(), mTrackAlpha),
309 truncateFloatFraction(track.getSnp(), mTrackSnp),
310 truncateFloatFraction(track.getTgl(), mTrackTgl),
311 truncateFloatFraction(track.getQ2Pt(), mTrack1Pt));
313 float sY = TMath::Sqrt(track.getSigmaY2()), sZ = TMath::Sqrt(track.getSigmaZ2()), sSnp = TMath::Sqrt(track.getSigmaSnp2()),
314 sTgl = TMath::Sqrt(track.getSigmaTgl2()), sQ2Pt = TMath::Sqrt(track.getSigma1Pt2());
315 tracksCovCursor(truncateFloatFraction(sY, mTrackCovDiag),
316 truncateFloatFraction(sZ, mTrackCovDiag),
317 truncateFloatFraction(sSnp, mTrackCovDiag),
318 truncateFloatFraction(sTgl, mTrackCovDiag),
319 truncateFloatFraction(sQ2Pt, mTrackCovDiag),
320 (Char_t)(128. * track.getSigmaZY() / (sZ * sY)),
321 (Char_t)(128. * track.getSigmaSnpY() / (sSnp * sY)),
322 (Char_t)(128. * track.getSigmaSnpZ() / (sSnp * sZ)),
323 (Char_t)(128. * track.getSigmaTglY() / (sTgl * sY)),
324 (Char_t)(128. * track.getSigmaTglZ() / (sTgl * sZ)),
325 (Char_t)(128. * track.getSigmaTglSnp() / (sTgl * sSnp)),
326 (Char_t)(128. * track.getSigma1PtY() / (sQ2Pt * sY)),
327 (Char_t)(128. * track.getSigma1PtZ() / (sQ2Pt * sZ)),
328 (Char_t)(128. * track.getSigma1PtSnp() / (sQ2Pt * sSnp)),
329 (Char_t)(128. * track.getSigma1PtTgl() / (sQ2Pt * sTgl)));
332template <
typename TracksExtraCursorType>
333void AODProducerWorkflowDPL::addToTracksExtraTable(TracksExtraCursorType& tracksExtraCursor, TrackExtraInfo& extraInfoHolder)
337 auto trackTimeRes = extraInfoHolder.trackTimeRes;
338 if (!extraInfoHolder.isTPConly) {
339 trackTimeRes = truncateFloatFraction(trackTimeRes, mTrackTimeError);
343 tracksExtraCursor(truncateFloatFraction(extraInfoHolder.tpcInnerParam, mTrack1Pt),
344 extraInfoHolder.flags,
345 extraInfoHolder.itsClusterSizes,
346 extraInfoHolder.tpcNClsFindable,
347 extraInfoHolder.tpcNClsFindableMinusFound,
348 extraInfoHolder.tpcNClsFindableMinusPID,
349 extraInfoHolder.tpcNClsFindableMinusCrossedRows,
350 extraInfoHolder.tpcNClsShared,
351 extraInfoHolder.trdPattern,
352 truncateFloatFraction(extraInfoHolder.itsChi2NCl, mTrackChi2),
353 truncateFloatFraction(extraInfoHolder.tpcChi2NCl, mTrackChi2),
354 truncateFloatFraction(extraInfoHolder.trdChi2, mTrackChi2),
355 truncateFloatFraction(extraInfoHolder.tofChi2, mTrackChi2),
356 truncateFloatFraction(extraInfoHolder.tpcSignal, mTrackSignal),
357 truncateFloatFraction(extraInfoHolder.trdSignal, mTrackSignal),
358 truncateFloatFraction(extraInfoHolder.length, mTrackSignal),
359 truncateFloatFraction(extraInfoHolder.tofExpMom, mTrack1Pt),
360 truncateFloatFraction(extraInfoHolder.trackEtaEMCAL, mTrackPosEMCAL),
361 truncateFloatFraction(extraInfoHolder.trackPhiEMCAL, mTrackPosEMCAL),
362 truncateFloatFraction(extraInfoHolder.trackTime, mTrackTime),
366template <
typename TracksQACursorType>
367void AODProducerWorkflowDPL::addToTracksQATable(TracksQACursorType& tracksQACursor,
TrackQA& trackQAInfoHolder)
370 trackQAInfoHolder.trackID,
371 mTrackQCRetainOnlydEdx ? 0.0f : truncateFloatFraction(trackQAInfoHolder.tpcTime0, mTPCTime0),
372 truncateFloatFraction(trackQAInfoHolder.tpcdEdxNorm, mTrackSignal),
373 mTrackQCRetainOnlydEdx ? std::numeric_limits<int16_t>::min() : trackQAInfoHolder.tpcdcaR,
374 mTrackQCRetainOnlydEdx ? std::numeric_limits<int16_t>::min() : trackQAInfoHolder.tpcdcaZ,
375 trackQAInfoHolder.tpcClusterByteMask,
376 trackQAInfoHolder.tpcdEdxMax0R,
377 trackQAInfoHolder.tpcdEdxMax1R,
378 trackQAInfoHolder.tpcdEdxMax2R,
379 trackQAInfoHolder.tpcdEdxMax3R,
380 trackQAInfoHolder.tpcdEdxTot0R,
381 trackQAInfoHolder.tpcdEdxTot1R,
382 trackQAInfoHolder.tpcdEdxTot2R,
383 trackQAInfoHolder.tpcdEdxTot3R,
384 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefContY,
385 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefContZ,
386 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefContSnp,
387 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefContTgl,
388 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefContQ2Pt,
389 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefGloY,
390 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefGloZ,
391 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefGloSnp,
392 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefGloTgl,
393 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dRefGloQ2Pt,
394 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dTofdX,
395 mTrackQCRetainOnlydEdx ? std::numeric_limits<int8_t>::min() : trackQAInfoHolder.dTofdZ);
398template <
typename TRDsExtraCursorType>
401 int q0s[6] = {-1}, q1s[6] = {-1}, q2s[6] = {-1};
402 float q0sCor[6] = {-1}, q1sCor[6] = {-1}, q2sCor[6] = {-1};
403 float ttgls[6] = {-999}, tphis[6] = {-999};
413 for (
int iLay{0}; iLay < 6; ++iLay) {
414 q0s[iLay] = q1s[iLay] = q2s[iLay] = -1;
415 q0sCor[iLay] = q1sCor[iLay] = q2sCor[iLay] = -1;
416 tphis[iLay] = ttgls[iLay] = -999;
417 auto trkltId = trk.getTrackletIndex(iLay);
421 const auto& tracklet = trklets[trkltId];
426 int trkltDet = tracklet.getDetector();
427 int trkltSec = trkltDet / 30;
433 if (!
o2::base::Propagator::Instance()->PropagateToXBxByBz(trkC, ctrklets[trkltId].getX(), o2::base::Propagator::MAX_SIN_PHI, o2::base::Propagator::MAX_STEP, mMatCorr)) {
437 auto tphi = trkC.getSnp() / std::sqrt((1.f - trkC.getSnp()) * (1.f + trkC.getSnp()));
438 auto trackletLength = std::sqrt(1.f + tphi * tphi + trkC.getTgl() * trkC.getTgl());
439 float cor = mTRDLocalGain->
getValue(tracklet.getHCID() / 2, tracklet.getPadCol(), tracklet.getPadRow()) * mTRDGainCalib->
getMPVdEdx(tracklet.getDetector()) / o2::trd::constants::MPVDEDXDEFAULT * trackletLength;
440 q0s[iLay] = tracklet.getQ0();
441 q1s[iLay] = tracklet.getQ1();
442 q2s[iLay] = tracklet.getQ2();
443 q0sCor[iLay] = (float)tracklet.getQ0() / cor;
444 q1sCor[iLay] = (float)tracklet.getQ1() / cor;
445 q2sCor[iLay] = (float)tracklet.getQ2() / cor;
446 ttgls[iLay] = trkC.getTgl();
450 if (trk.getIsCrossingNeighbor(iLay) && trk.getHasNeighbor()) {
453 size_t trdSelID = -1;
455 const auto& trig = trigsTRD[mCurrentTRDTrigID];
456 bool foundTRDTrigger =
false;
458 if (trkltId >= trig.getFirstTracklet() && trkltId < trig.getFirstTracklet() + trig.getNumberOfTracklets()) {
459 trdSelID = mCurrentTRDTrigID;
460 foundTRDTrigger =
true;
463 if (mCurrentTRDTrigID < trigsTRD.size() - 1) {
464 const auto& trig = trigsTRD[mCurrentTRDTrigID + 1];
465 if (trkltId >= trig.getFirstTracklet() && trkltId < trig.getFirstTracklet() + trig.getNumberOfTracklets()) {
466 trdSelID = mCurrentTRDTrigID + 1;
467 foundTRDTrigger =
true;
472 size_t low = 0, up = trigsTRD.size() - 1;
475 while (low <= up && !foundTRDTrigger) {
476 trdSelID = low + std::floor((up - low) / 2);
477 const auto& trig = trigsTRD[trdSelID];
478 if (trig.getFirstTracklet() > trkltId) {
481 if (trig.getFirstTracklet() + trig.getNumberOfTracklets() <= trkltId) {
484 foundTRDTrigger =
true;
489 mCurrentTRDTrigID = trdSelID;
490 const auto& trigSel = trigsTRD[trdSelID];
493 for (
const auto& trklt : trklets.subspan(trigSel.getFirstTracklet(), trigSel.getNumberOfTracklets())) {
494 if (tracklet.getTrackletWord() == trklt.getTrackletWord() || tracklet.getDetector() != trklt.getDetector()) {
497 if (std::abs(tracklet.getPadCol() - trklt.getPadCol()) <= 1 && std::abs(tracklet.getPadRow() - trklt.getPadRow()) == 1) {
498 cor = mTRDLocalGain->
getValue(trklt.getHCID() / 2, trklt.getPadCol(), trklt.getPadRow()) * mTRDGainCalib->
getMPVdEdx(tracklet.getDetector()) / o2::trd::constants::MPVDEDXDEFAULT * trackletLength;
499 q0s[iLay] += trklt.getQ0();
500 q1s[iLay] += trklt.getQ1();
501 q2s[iLay] += trklt.getQ2();
502 q0sCor[iLay] += (float)trklt.getQ0() / cor;
503 q1sCor[iLay] += (float)trklt.getQ1() / cor;
504 q2sCor[iLay] += (float)trklt.getQ2() / cor;
510 trdExtraCursor(trkTableIdx, q0s, q1s, q2s, q0sCor, q1sCor, q2sCor, ttgls, tphis);
513template <
typename mftTracksCursorType,
typename mftTracksCovCursorType,
typename AmbigMFTTracksCursorType>
514void AODProducerWorkflowDPL::addToMFTTracksTable(mftTracksCursorType& mftTracksCursor, mftTracksCovCursorType& mftTracksCovCursor, AmbigMFTTracksCursorType& ambigMFTTracksCursor,
516 std::uint64_t collisionBC,
const std::map<uint64_t, int>& bcsMap)
519 int bcSlice[2] = {-1, -1};
520 const auto& track =
data.getMFTTrack(trackID);
521 const auto& rof =
data.getMFTTracksROFRecords()[mMFTROFs[trackID.getIndex()]];
522 float trackTime = rof.getBCData().differenceInBC(mStartIR) * o2::constants::lhc::LHCBunchSpacingNS + mMFTROFrameHalfLengthNS + mMFTROFBiasNS;
523 float trackTimeRes = mMFTROFrameHalfLengthNS;
524 bool needBCSlice = collisionID < 0;
525 std::uint64_t bcOfTimeRef;
527 double error = mTimeMarginTrackTime + trackTimeRes;
528 bcOfTimeRef = fillBCSlice(bcSlice, trackTime - error, trackTime + error, bcsMap);
530 bcOfTimeRef = collisionBC - mStartIR.
toLong();
532 trackTime -= bcOfTimeRef * o2::constants::lhc::LHCBunchSpacingNS;
535 uint64_t mftClusterSizesAndTrackFlags = track.getClusterSizes();
536 mftClusterSizesAndTrackFlags |= (track.isCA()) ? (1ULL << (60)) : 0;
538 mftTracksCursor(collisionID,
541 truncateFloatFraction(track.getZ(), mTrackX),
542 truncateFloatFraction(track.getPhi(), mTrackAlpha),
543 truncateFloatFraction(track.getTanl(), mTrackTgl),
544 truncateFloatFraction(track.getInvQPt(), mTrack1Pt),
545 mftClusterSizesAndTrackFlags,
546 truncateFloatFraction(track.getTrackChi2(), mTrackChi2),
547 truncateFloatFraction(trackTime, mTrackTime),
548 truncateFloatFraction(trackTimeRes, mTrackTimeError));
549 if (mStoreAllMFTCov) {
550 float sX = TMath::Sqrt(track.getSigma2X());
551 float sY = TMath::Sqrt(track.getSigma2Y());
552 float sPhi = TMath::Sqrt(track.getSigma2Phi());
553 float sTgl = TMath::Sqrt(track.getSigma2Tanl());
554 float sQ2Pt = TMath::Sqrt(track.getSigma2InvQPt());
556 mftTracksCovCursor(mTableTrMFTID,
557 truncateFloatFraction(sX, mTrackCovDiag),
558 truncateFloatFraction(sY, mTrackCovDiag),
559 truncateFloatFraction(sPhi, mTrackCovDiag),
560 truncateFloatFraction(sTgl, mTrackCovDiag),
561 truncateFloatFraction(sQ2Pt, mTrackCovDiag),
562 (Char_t)(128. * track.getCovariances()(0, 1) / (sX * sY)),
563 (Char_t)(128. * track.getCovariances()(0, 2) / (sPhi * sX)),
564 (Char_t)(128. * track.getCovariances()(1, 2) / (sPhi * sY)),
565 (Char_t)(128. * track.getCovariances()(0, 3) / (sTgl * sX)),
566 (Char_t)(128. * track.getCovariances()(1, 3) / (sTgl * sY)),
567 (Char_t)(128. * track.getCovariances()(2, 3) / (sTgl * sPhi)),
568 (Char_t)(128. * track.getCovariances()(0, 4) / (sQ2Pt * sX)),
569 (Char_t)(128. * track.getCovariances()(1, 4) / (sQ2Pt * sY)),
570 (Char_t)(128. * track.getCovariances()(2, 4) / (sQ2Pt * sPhi)),
571 (Char_t)(128. * track.getCovariances()(3, 4) / (sQ2Pt * sTgl)));
574 ambigMFTTracksCursor(mTableTrMFTID, bcSlice);
577template <
typename TracksCursorType,
typename TracksCovCursorType,
typename TracksExtraCursorType,
typename TracksQACursorType,
typename TRDsExtraCursor,
typename AmbigTracksCursorType,
578 typename MFTTracksCursorType,
typename MFTTracksCovCursorType,
typename AmbigMFTTracksCursorType,
579 typename FwdTracksCursorType,
typename FwdTracksCovCursorType,
typename AmbigFwdTracksCursorType,
typename FwdTrkClsCursorType>
580void AODProducerWorkflowDPL::fillTrackTablesPerCollision(
int collisionID,
581 std::uint64_t collisionBC,
583 const gsl::span<const GIndex>& GIndices,
585 TracksCursorType& tracksCursor,
586 TracksCovCursorType& tracksCovCursor,
587 TracksExtraCursorType& tracksExtraCursor,
588 TracksQACursorType& tracksQACursor,
589 TRDsExtraCursor& trdsExtraCursor,
590 AmbigTracksCursorType& ambigTracksCursor,
591 MFTTracksCursorType& mftTracksCursor,
592 MFTTracksCovCursorType& mftTracksCovCursor,
593 AmbigMFTTracksCursorType& ambigMFTTracksCursor,
594 FwdTracksCursorType& fwdTracksCursor,
595 FwdTracksCovCursorType& fwdTracksCovCursor,
596 AmbigFwdTracksCursorType& ambigFwdTracksCursor,
597 FwdTrkClsCursorType& fwdTrkClsCursor,
598 const std::map<uint64_t, int>& bcsMap)
601 if (!GIndex::isTrackSource(
src)) {
608 mftTracksCursor.reserve(nToReserve + mftTracksCursor.lastIndex() + 1);
609 if (mStoreAllMFTCov) {
610 mftTracksCovCursor.reserve(nToReserve + mftTracksCovCursor.lastIndex() + 1);
613 fwdTracksCursor.reserve(nToReserve + fwdTracksCursor.lastIndex() + 1);
614 fwdTracksCovCursor.reserve(nToReserve + fwdTracksCovCursor.lastIndex() + 1);
616 mftTracksCovCursor.reserve(nToReserve + mftTracksCovCursor.lastIndex() + 1);
619 tracksCursor.reserve(nToReserve + tracksCursor.lastIndex() + 1);
620 tracksCovCursor.reserve(nToReserve + tracksCovCursor.lastIndex() + 1);
621 tracksExtraCursor.reserve(nToReserve + tracksExtraCursor.lastIndex() + 1);
623 for (
int ti =
start; ti <
end; ti++) {
624 const auto& trackIndex = GIndices[ti];
625 if (GIndex::includesSource(
src, mInputSources)) {
627 if (trackIndex.isAmbiguous() && mGIDToTableMFTID.find(trackIndex) != mGIDToTableMFTID.end()) {
630 addToMFTTracksTable(mftTracksCursor, mftTracksCovCursor, ambigMFTTracksCursor, trackIndex,
data, collisionID, collisionBC, bcsMap);
631 mGIDToTableMFTID.emplace(trackIndex, mTableTrMFTID);
634 if (trackIndex.isAmbiguous() && mGIDToTableFwdID.find(trackIndex) != mGIDToTableFwdID.end()) {
637 addToFwdTracksTable(fwdTracksCursor, fwdTracksCovCursor, ambigFwdTracksCursor, mftTracksCovCursor, trackIndex,
data, collisionID, collisionBC, bcsMap);
638 mGIDToTableFwdID.emplace(trackIndex, mTableTrFwdID);
639 addClustersToFwdTrkClsTable(
data, fwdTrkClsCursor, trackIndex, mTableTrFwdID);
643 if (trackIndex.isAmbiguous() && mGIDToTableID.find(trackIndex) != mGIDToTableID.end()) {
648 static std::uniform_real_distribution<>
distr(0., 1.);
650 auto extraInfoHolder = processBarrelTrack(collisionID, collisionBC, trackIndex,
data, bcsMap);
653 auto trackQAInfoHolder = processBarrelTrackQA(collisionID, collisionBC, trackIndex,
data, bcsMap);
654 if (std::bitset<8>(trackQAInfoHolder.tpcClusterByteMask).count() >= mTrackQCNTrCut) {
655 trackQAInfoHolder.trackID = mTableTrID;
657 trackQAInfoHolder.tpcTime0 = (trackQAInfoHolder.tpcTime0 * 8 - extraInfoHolder.diffBCRef) * o2::constants::lhc::LHCBunchSpacingNS - extraInfoHolder.trackTime;
659 addToTracksQATable(tracksQACursor, trackQAInfoHolder);
666 if (mThinTracks && extraInfoHolder.isTPConly && !writeQAData) {
667 auto trk =
data.getTPCTrack(trackIndex);
668 if (trk.getNClusters() >= mTrackQCNCls && trk.getPt() >= mTrackQCPt) {
678 if (mThinTracks &&
src ==
GIndex::Source::TPC && mGIDUsedBySVtx.find(trackIndex) == mGIDUsedBySVtx.end() && mGIDUsedByStr.find(trackIndex) == mGIDUsedByStr.end() && !writeQAData) {
679 mGIDToTableID.emplace(trackIndex, -1);
683 if (!extraInfoHolder.isTPConly && extraInfoHolder.trackTimeRes < 0.f) {
684 LOG(warning) <<
"Barrel track " << trackIndex <<
" has no time set, rejection is not expected : time=" << extraInfoHolder.trackTime
685 <<
" timeErr=" << extraInfoHolder.trackTimeRes <<
" BCSlice: " << extraInfoHolder.bcSlice[0] <<
":" << extraInfoHolder.bcSlice[1];
688 const auto& trOrig =
data.getTrackParam(trackIndex);
690 if (mPropTracks && trOrig.getX() < mMaxPropXiu &&
691 mGIDUsedBySVtx.find(trackIndex) == mGIDUsedBySVtx.end() &&
692 mGIDUsedByStr.find(trackIndex) == mGIDUsedByStr.end()) {
693 auto trackPar(trOrig);
694 isProp = propagateTrackToPV(trackPar,
data, collisionID);
696 addToTracksTable(tracksCursor, tracksCovCursor, trackPar, collisionID,
aod::track::Track);
702 addToTracksExtraTable(tracksExtraCursor, extraInfoHolder);
704 addToTRDsExtra(
data, trdsExtraCursor, trackIndex, mTableTrID);
707 if (extraInfoHolder.bcSlice[0] >= 0 && collisionID < 0) {
708 ambigTracksCursor(mTableTrID, extraInfoHolder.bcSlice);
710 mGIDToTableID.emplace(trackIndex, mTableTrID);
716 if (collisionID < 0) {
720 auto sTracks =
data.getStrangeTracks();
721 tracksCursor.reserve(mVertexStrLUT[collisionID + 1] + tracksCursor.lastIndex() + 1);
722 tracksCovCursor.reserve(mVertexStrLUT[collisionID + 1] + tracksCovCursor.lastIndex() + 1);
723 tracksExtraCursor.reserve(mVertexStrLUT[collisionID + 1] + tracksExtraCursor.lastIndex() + 1);
724 for (
int iS{mVertexStrLUT[collisionID]}; iS < mVertexStrLUT[collisionID + 1]; ++iS) {
725 auto& collStrTrk = mCollisionStrTrk[iS];
726 auto& sTrk = sTracks[collStrTrk.second];
727 TrackExtraInfo extraInfo;
728 extraInfo.itsChi2NCl = sTrk.mTopoChi2;
729 extraInfo.itsClusterSizes = sTrk.getClusterSizes();
731 addToTracksExtraTable(tracksExtraCursor, extraInfo);
732 mStrTrkIndices[collStrTrk.second] = mTableTrID;
739 const auto& mchmidMatches =
data.getMCHMIDMatches();
744 for (
int ti =
start; ti <
end; ti++) {
745 auto& trackIndex = GIndices[ti];
746 if (GIndex::includesSource(
src, mInputSources)) {
748 if (trackIndex.isAmbiguous() && mGIDToTableMFTID.find(trackIndex) != mGIDToTableMFTID.end()) {
751 mGIDToTableMFTID.emplace(trackIndex, mIndexMFTID);
752 mIndexTableMFT[trackIndex.getIndex()] = mIndexMFTID;
755 if (trackIndex.isAmbiguous() && mGIDToTableFwdID.find(trackIndex) != mGIDToTableFwdID.end()) {
758 mGIDToTableFwdID.emplace(trackIndex, mIndexFwdID);
760 mIndexTableFwd[trackIndex.getIndex()] = mIndexFwdID;
762 const auto& mchmidMatch = mchmidMatches[trackIndex.getIndex()];
763 const auto mchTrackID = mchmidMatch.getMCHRef().getIndex();
764 mIndexTableFwd[mchTrackID] = mIndexFwdID;
773template <
typename FwdTracksCursorType,
typename FwdTracksCovCursorType,
typename AmbigFwdTracksCursorType,
typename mftTracksCovCursorType>
774void AODProducerWorkflowDPL::addToFwdTracksTable(FwdTracksCursorType& fwdTracksCursor, FwdTracksCovCursorType& fwdTracksCovCursor,
775 AmbigFwdTracksCursorType& ambigFwdTracksCursor, mftTracksCovCursorType& mftTracksCovCursor,
GIndex trackID,
777 const std::map<uint64_t, int>& bcsMap)
779 const auto& mchTracks =
data.getMCHTracks();
780 const auto& midTracks =
data.getMIDTracks();
781 const auto& mchmidMatches =
data.getMCHMIDMatches();
782 const auto& mchClusters =
data.getMCHTrackClusters();
784 FwdTrackInfo fwdInfo;
785 FwdTrackCovInfo fwdCovInfo;
786 int bcSlice[2] = {-1, -1};
789 auto getMCHBitMap = [&](
int mchTrackID) {
790 if (mchTrackID != -1) {
791 const auto& mchTrack = mchTracks[mchTrackID];
792 int first = mchTrack.getFirstClusterIdx();
793 int last = mchTrack.getLastClusterIdx();
794 for (
int i =
first;
i <= last;
i++) {
795 const auto& cluster = mchClusters[
i];
796 int chamberId = cluster.getChamberId();
797 fwdInfo.mchBitMap |= 1 << chamberId;
802 auto getMIDBitMapBoards = [&](
int midTrackID) {
803 if (midTrackID != -1) {
804 const auto& midTrack = midTracks[midTrackID];
805 fwdInfo.midBitMap = midTrack.getHitMap();
806 fwdInfo.midBoards = midTrack.getEfficiencyWord();
810 auto extrapMCHTrack = [&](
int mchTrackID) {
811 const auto& track = mchTracks[mchTrackID];
819 float vx = 0, vy = 0, vz = 0;
820 if (collisionID >= 0) {
821 const auto&
v =
data.getPrimaryVertex(collisionID);
827 o2::mch::TrackParam trackParamAtVertex(track.getZ(), track.getParameters(), track.getCovariances());
850 double dca = std::sqrt(dcaX * dcaX + dcaY * dcaY);
855 double dpdca = track.getP() * dca;
856 double dchi2 = track.getChi2OverNDF();
858 auto fwdmuon = mMatching.
MCHtoFwd(trackParamAtVertex);
860 fwdInfo.x = fwdmuon.
getX();
861 fwdInfo.y = fwdmuon.getY();
862 fwdInfo.z = fwdmuon.getZ();
863 fwdInfo.phi = fwdmuon.getPhi();
864 fwdInfo.tanl = fwdmuon.getTgl();
865 fwdInfo.invqpt = fwdmuon.getInvQPt();
866 fwdInfo.rabs = std::sqrt(xAbs * xAbs + yAbs * yAbs);
867 fwdInfo.chi2 = dchi2;
868 fwdInfo.pdca = dpdca;
869 fwdInfo.nClusters = track.getNClusters();
871 fwdCovInfo.sigX = TMath::Sqrt(fwdmuon.getCovariances()(0, 0));
872 fwdCovInfo.sigY = TMath::Sqrt(fwdmuon.getCovariances()(1, 1));
873 fwdCovInfo.sigPhi = TMath::Sqrt(fwdmuon.getCovariances()(2, 2));
874 fwdCovInfo.sigTgl = TMath::Sqrt(fwdmuon.getCovariances()(3, 3));
875 fwdCovInfo.sig1Pt = TMath::Sqrt(fwdmuon.getCovariances()(4, 4));
876 fwdCovInfo.rhoXY = (Char_t)(128. * fwdmuon.getCovariances()(0, 1) / (fwdCovInfo.sigX * fwdCovInfo.sigY));
877 fwdCovInfo.rhoPhiX = (Char_t)(128. * fwdmuon.getCovariances()(0, 2) / (fwdCovInfo.sigPhi * fwdCovInfo.sigX));
878 fwdCovInfo.rhoPhiY = (Char_t)(128. * fwdmuon.getCovariances()(1, 2) / (fwdCovInfo.sigPhi * fwdCovInfo.sigY));
879 fwdCovInfo.rhoTglX = (Char_t)(128. * fwdmuon.getCovariances()(0, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigX));
880 fwdCovInfo.rhoTglY = (Char_t)(128. * fwdmuon.getCovariances()(1, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigY));
881 fwdCovInfo.rhoTglPhi = (Char_t)(128. * fwdmuon.getCovariances()(2, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigPhi));
882 fwdCovInfo.rho1PtX = (Char_t)(128. * fwdmuon.getCovariances()(0, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigX));
883 fwdCovInfo.rho1PtY = (Char_t)(128. * fwdmuon.getCovariances()(1, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigY));
884 fwdCovInfo.rho1PtPhi = (Char_t)(128. * fwdmuon.getCovariances()(2, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigPhi));
885 fwdCovInfo.rho1PtTgl = (Char_t)(128. * fwdmuon.getCovariances()(3, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigTgl));
891 int mchTrackID = trackID.getIndex();
892 getMCHBitMap(mchTrackID);
893 if (!extrapMCHTrack(mchTrackID)) {
894 LOGF(warn,
"Unable to extrapolate MCH track with ID %d! Dummy parameters will be used", mchTrackID);
897 const auto& rof =
data.getMCHTracksROFRecords()[mMCHROFs[mchTrackID]];
898 auto time = rof.getTimeMUS(mStartIR).first;
899 fwdInfo.trackTime =
time.getTimeStamp() * 1.e3;
900 fwdInfo.trackTimeRes =
time.getTimeStampError() * 1.e3;
903 auto mchmidMatch = mchmidMatches[trackID.getIndex()];
904 auto mchTrackID = mchmidMatch.getMCHRef().getIndex();
905 if (!extrapMCHTrack(mchTrackID)) {
906 LOGF(warn,
"Unable to extrapolate MCH track with ID %d! Dummy parameters will be used", mchTrackID);
908 auto midTrackID = mchmidMatch.getMIDRef().getIndex();
909 fwdInfo.chi2matchmchmid = mchmidMatch.getMatchChi2OverNDF();
910 getMCHBitMap(mchTrackID);
911 getMIDBitMapBoards(midTrackID);
912 auto time = mchmidMatch.getTimeMUS(mStartIR).first;
913 fwdInfo.trackTime =
time.getTimeStamp() * 1.e3;
914 fwdInfo.trackTimeRes =
time.getTimeStampError() * 1.e3;
916 const auto& track =
data.getGlobalFwdTrack(trackID);
917 const auto& mftTracks =
data.getMFTTracks();
918 const auto& mfttrack = mftTracks[track.getMFTTrackID()];
919 if (!extrapMCHTrack(track.getMCHTrackID())) {
920 LOGF(warn,
"Unable to extrapolate MCH track with ID %d! Dummy parameters will be used", track.getMCHTrackID());
922 fwdInfo.x = track.getX();
923 fwdInfo.y = track.getY();
924 fwdInfo.z = track.getZ();
925 fwdInfo.phi = track.getPhi();
926 fwdInfo.tanl = track.getTanl();
927 fwdInfo.invqpt = track.getInvQPt();
928 fwdInfo.chi2 = track.getTrackChi2();
930 fwdInfo.chi2matchmchmid = track.getMIDMatchingChi2();
931 fwdInfo.chi2matchmchmft = track.getMFTMCHMatchingChi2();
932 fwdInfo.matchscoremchmft = track.getMFTMCHMatchingScore();
933 fwdInfo.matchmfttrackid = mIndexTableMFT[track.getMFTTrackID()];
934 fwdInfo.matchmchtrackid = mIndexTableFwd[track.getMCHTrackID()];
935 fwdInfo.trackTime = track.getTimeMUS().getTimeStamp() * 1.e3;
936 fwdInfo.trackTimeRes = track.getTimeMUS().getTimeStampError() * 1.e3;
938 getMCHBitMap(track.getMCHTrackID());
939 getMIDBitMapBoards(track.getMIDTrackID());
941 fwdCovInfo.sigX = TMath::Sqrt(track.getCovariances()(0, 0));
942 fwdCovInfo.sigY = TMath::Sqrt(track.getCovariances()(1, 1));
943 fwdCovInfo.sigPhi = TMath::Sqrt(track.getCovariances()(2, 2));
944 fwdCovInfo.sigTgl = TMath::Sqrt(track.getCovariances()(3, 3));
945 fwdCovInfo.sig1Pt = TMath::Sqrt(track.getCovariances()(4, 4));
946 fwdCovInfo.rhoXY = (Char_t)(128. * track.getCovariances()(0, 1) / (fwdCovInfo.sigX * fwdCovInfo.sigY));
947 fwdCovInfo.rhoPhiX = (Char_t)(128. * track.getCovariances()(0, 2) / (fwdCovInfo.sigPhi * fwdCovInfo.sigX));
948 fwdCovInfo.rhoPhiY = (Char_t)(128. * track.getCovariances()(1, 2) / (fwdCovInfo.sigPhi * fwdCovInfo.sigY));
949 fwdCovInfo.rhoTglX = (Char_t)(128. * track.getCovariances()(0, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigX));
950 fwdCovInfo.rhoTglY = (Char_t)(128. * track.getCovariances()(1, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigY));
951 fwdCovInfo.rhoTglPhi = (Char_t)(128. * track.getCovariances()(2, 3) / (fwdCovInfo.sigTgl * fwdCovInfo.sigPhi));
952 fwdCovInfo.rho1PtX = (Char_t)(128. * track.getCovariances()(0, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigX));
953 fwdCovInfo.rho1PtY = (Char_t)(128. * track.getCovariances()(1, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigY));
954 fwdCovInfo.rho1PtPhi = (Char_t)(128. * track.getCovariances()(2, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigPhi));
955 fwdCovInfo.rho1PtTgl = (Char_t)(128. * track.getCovariances()(3, 4) / (fwdCovInfo.sig1Pt * fwdCovInfo.sigTgl));
959 float sX = TMath::Sqrt(mfttrack.getSigma2X()), sY = TMath::Sqrt(mfttrack.getSigma2Y()), sPhi = TMath::Sqrt(mfttrack.getSigma2Phi()),
960 sTgl = TMath::Sqrt(mfttrack.getSigma2Tanl()), sQ2Pt = TMath::Sqrt(mfttrack.getSigma2InvQPt());
962 if (!mStoreAllMFTCov) {
963 mftTracksCovCursor(fwdInfo.matchmfttrackid,
964 truncateFloatFraction(sX, mTrackCovDiag),
965 truncateFloatFraction(sY, mTrackCovDiag),
966 truncateFloatFraction(sPhi, mTrackCovDiag),
967 truncateFloatFraction(sTgl, mTrackCovDiag),
968 truncateFloatFraction(sQ2Pt, mTrackCovDiag),
969 (Char_t)(128. * mfttrack.getCovariances()(0, 1) / (sX * sY)),
970 (Char_t)(128. * mfttrack.getCovariances()(0, 2) / (sPhi * sX)),
971 (Char_t)(128. * mfttrack.getCovariances()(1, 2) / (sPhi * sY)),
972 (Char_t)(128. * mfttrack.getCovariances()(0, 3) / (sTgl * sX)),
973 (Char_t)(128. * mfttrack.getCovariances()(1, 3) / (sTgl * sY)),
974 (Char_t)(128. * mfttrack.getCovariances()(2, 3) / (sTgl * sPhi)),
975 (Char_t)(128. * mfttrack.getCovariances()(0, 4) / (sQ2Pt * sX)),
976 (Char_t)(128. * mfttrack.getCovariances()(1, 4) / (sQ2Pt * sY)),
977 (Char_t)(128. * mfttrack.getCovariances()(2, 4) / (sQ2Pt * sPhi)),
978 (Char_t)(128. * mfttrack.getCovariances()(3, 4) / (sQ2Pt * sTgl)));
982 std::uint64_t bcOfTimeRef;
983 bool needBCSlice = collisionID < 0;
985 float err = mTimeMarginTrackTime + fwdInfo.trackTimeRes;
986 bcOfTimeRef = fillBCSlice(bcSlice, fwdInfo.trackTime - err, fwdInfo.trackTime + err, bcsMap);
988 bcOfTimeRef = collisionBC - mStartIR.
toLong();
990 fwdInfo.trackTime -= bcOfTimeRef * o2::constants::lhc::LHCBunchSpacingNS;
992 fwdTracksCursor(collisionID,
996 truncateFloatFraction(fwdInfo.z, mTrackX),
997 truncateFloatFraction(fwdInfo.phi, mTrackAlpha),
998 truncateFloatFraction(fwdInfo.tanl, mTrackTgl),
999 truncateFloatFraction(fwdInfo.invqpt, mTrack1Pt),
1001 truncateFloatFraction(fwdInfo.pdca, mTrackX),
1002 truncateFloatFraction(fwdInfo.rabs, mTrackX),
1003 truncateFloatFraction(fwdInfo.chi2, mTrackChi2),
1004 truncateFloatFraction(fwdInfo.chi2matchmchmid, mTrackChi2),
1005 truncateFloatFraction(fwdInfo.chi2matchmchmft, mTrackChi2),
1006 truncateFloatFraction(fwdInfo.matchscoremchmft, mTrackChi2),
1007 fwdInfo.matchmfttrackid,
1008 fwdInfo.matchmchtrackid,
1012 truncateFloatFraction(fwdInfo.trackTime, mTrackTime),
1013 truncateFloatFraction(fwdInfo.trackTimeRes, mTrackTimeError));
1015 fwdTracksCovCursor(truncateFloatFraction(fwdCovInfo.sigX, mTrackCovDiag),
1016 truncateFloatFraction(fwdCovInfo.sigY, mTrackCovDiag),
1017 truncateFloatFraction(fwdCovInfo.sigPhi, mTrackCovDiag),
1018 truncateFloatFraction(fwdCovInfo.sigTgl, mTrackCovDiag),
1019 truncateFloatFraction(fwdCovInfo.sig1Pt, mTrackCovDiag),
1025 fwdCovInfo.rhoTglPhi,
1028 fwdCovInfo.rho1PtPhi,
1029 fwdCovInfo.rho1PtTgl);
1032 ambigFwdTracksCursor(mTableTrFwdID, bcSlice);
1037void AODProducerWorkflowDPL::updateMCHeader(MCCollisionCursor& collisionCursor,
1038 XSectionCursor& xSectionCursor,
1039 PdfInfoCursor& pdfInfoCursor,
1040 HeavyIonCursor& heavyIonCursor,
1041 const MCEventHeader& header,
1053 auto genID = updateMCCollisions(collisionCursor,
1059 mCollisionPosition);
1060 mXSectionUpdate = (updateHepMCXSection(xSectionCursor,
1065 ? HepMCUpdate::always
1066 : HepMCUpdate::never);
1067 mPdfInfoUpdate = (updateHepMCPdfInfo(pdfInfoCursor,
1072 ? HepMCUpdate::always
1073 : HepMCUpdate::never);
1074 mHeavyIonUpdate = (updateHepMCHeavyIon(heavyIonCursor,
1079 ? HepMCUpdate::always
1080 : HepMCUpdate::never);
1085 store.resize(Nsources);
1086 for (
int s = 0;
s < Nsources; ++
s) {
1087 store[
s].resize(NEvents);
1093 for (
auto s = 0U;
s < store.size(); ++
s) {
1094 for (
auto e = 0U; e < store[
s].size(); ++e) {
1095 store[
s][e].clear();
1104 LOG(warn) <<
"trackID is smaller than 0. Neglecting";
1107 if (useSigFilt &&
source == 0) {
1115 MCParticlesCursor& mcParticlesCursor,
1116 const gsl::span<const o2::dataformats::VtxTrackRef>& primVer2TRefs,
1117 const gsl::span<const GIndex>& GIndices,
1119 const std::vector<MCColInfo>& mcColToEvSrc)
1123 for (
auto& p : mcColToEvSrc) {
1124 NSources = std::max(p.sourceID, NSources);
1125 NEvents = std::max(p.eventID, NEvents);
1129 LOG(info) <<
" number of events " << NEvents;
1130 LOG(info) <<
" number of sources " << NSources;
1133 std::vector<int> particleIDsToKeep;
1135 auto markMCTrackForSrc = [&](std::array<GID, GID::NSources>& contributorsGID, uint8_t
src) {
1136 auto mcLabel =
data.getTrackMCLabel(contributorsGID[
src]);
1137 if (!mcLabel.isValid()) {
1140 keepMCParticle(mToStore, mcLabel.getSourceID(), mcLabel.getEventID(), mcLabel.getTrackID(), 1, mUseSigFiltMC);
1144 for (
auto& trackRef : primVer2TRefs) {
1148 for (
int ti =
start; ti <
end; ti++) {
1149 auto& trackIndex = GIndices[ti];
1150 if (GIndex::includesSource(
src, mInputSources)) {
1151 auto mcTruth =
data.getTrackMCLabel(trackIndex);
1152 if (!mcTruth.isValid()) {
1155 keepMCParticle(mToStore, mcTruth.getSourceID(), mcTruth.getEventID(), mcTruth.getTrackID(), 1, mUseSigFiltMC);
1157 auto contributorsGID =
data.getSingleDetectorRefs(trackIndex);
1166 for (
auto& mcLabel : labelsTOF) {
1167 if (!mcLabel.isValid()) {
1170 keepMCParticle(mToStore, mcLabel.getSourceID(), mcLabel.getEventID(), mcLabel.getTrackID(), 1, mUseSigFiltMC);
1179 auto& mcCaloEMCCellLabels =
data.getEMCALCellsMCLabels()->getTruthArray();
1180 for (
auto& mcTruth : mcCaloEMCCellLabels) {
1181 if (!mcTruth.isValid()) {
1184 keepMCParticle(mToStore, mcTruth.getSourceID(), mcTruth.getEventID(), mcTruth.getTrackID(), 1, mUseSigFiltMC);
1188 auto& mcCaloPHOSCellLabels =
data.getPHOSCellsMCLabels()->getTruthArray();
1189 for (
auto& mcTruth : mcCaloPHOSCellLabels) {
1190 if (!mcTruth.isValid()) {
1193 keepMCParticle(mToStore, mcTruth.getSourceID(), mcTruth.getEventID(), mcTruth.getTrackID(), 1, mUseSigFiltMC);
1196 using namespace aodmchelpers;
1200 for (
auto& colInfo : mcColToEvSrc) {
1201 int event = colInfo.eventID;
1202 int source = colInfo.sourceID;
1203 int mcColId = colInfo.colIndex;
1205 LOG(
debug) <<
"Event=" <<
event <<
" source=" <<
source <<
" collision=" << mcColId;
1224template <
typename MCTrackLabelCursorType,
typename MCMFTTrackLabelCursorType,
typename MCFwdTrackLabelCursorType>
1225void AODProducerWorkflowDPL::fillMCTrackLabelsTable(MCTrackLabelCursorType& mcTrackLabelCursor,
1226 MCMFTTrackLabelCursorType& mcMFTTrackLabelCursor,
1227 MCFwdTrackLabelCursorType& mcFwdTrackLabelCursor,
1229 const gsl::span<const GIndex>& primVerGIs,
1242 mcMFTTrackLabelCursor.reserve(
end -
start + mcMFTTrackLabelCursor.lastIndex() + 1);
1243 mcFwdTrackLabelCursor.reserve(
end -
start + mcFwdTrackLabelCursor.lastIndex() + 1);
1244 mcTrackLabelCursor.reserve(
end -
start + mcTrackLabelCursor.lastIndex() + 1);
1245 for (
int ti =
start; ti <
end; ti++) {
1246 const auto trackIndex = primVerGIs[ti];
1249 auto needToStore = [trackIndex](std::unordered_map<GIndex, int>& mp) {
1250 auto entry = mp.find(trackIndex);
1251 if (
entry == mp.end() ||
entry->second == -1) {
1258 if (GIndex::includesSource(
src, mInputSources)) {
1259 auto mcTruth =
data.getTrackMCLabel(trackIndex);
1260 MCLabels labelHolder{};
1265 if (mcTruth.isValid()) {
1266 labelHolder.labelID = (mToStore[mcTruth.getSourceID()][mcTruth.getEventID()])[mcTruth.getTrackID()];
1268 if (mcTruth.isFake()) {
1269 labelHolder.fwdLabelMask |= (0x1 << 7);
1271 if (mcTruth.isNoise()) {
1272 labelHolder.fwdLabelMask |= (0x1 << 6);
1275 mcMFTTrackLabelCursor(labelHolder.labelID,
1276 labelHolder.fwdLabelMask);
1278 mcFwdTrackLabelCursor(labelHolder.labelID,
1279 labelHolder.fwdLabelMask);
1282 if (!needToStore(mGIDToTableID)) {
1285 if (mcTruth.isValid()) {
1286 labelHolder.labelID = (mToStore[mcTruth.getSourceID()][mcTruth.getEventID()])[mcTruth.getTrackID()];
1287 if (mcTruth.isFake()) {
1288 labelHolder.labelMask |= (0x1 << 15);
1290 if (trackIndex.includesDet(DetID::TPC) && trackIndex.getSource() !=
GIndex::Source::TPC) {
1291 auto contributorsGID =
data.getSingleDetectorRefs(trackIndex);
1294 labelHolder.labelMask |= (0x1 << 13);
1298 if (trackIndex.includesDet(DetID::ITS)) {
1299 auto itsGID =
data.getITSContributorGID(trackIndex);
1300 auto itsSource = itsGID.getSource();
1302 auto& itsTrack =
data.getITSTrack(itsGID);
1303 for (
unsigned int iL = 0; iL < 7; ++iL) {
1304 if (itsTrack.isFakeOnLayer(iL)) {
1305 labelHolder.labelMask |= (0x1 << iL);
1309 labelHolder.labelMask |= (
data.getTrackMCLabel(itsGID).isFake() << 12);
1313 }
else if (mcTruth.isNoise()) {
1314 labelHolder.labelMask |= (0x1 << 14);
1316 mcTrackLabelCursor(labelHolder.labelID, labelHolder.labelMask);
1323 auto sTrackLabels =
data.getStrangeTracksMCLabels();
1325 if (!(vertexId < 0 || vertexId >= mVertexStrLUT.size() - 1)) {
1326 mcTrackLabelCursor.reserve(mVertexStrLUT[vertexId + 1] + mcTrackLabelCursor.lastIndex() + 1);
1327 for (
int iS{mVertexStrLUT[vertexId]}; iS < mVertexStrLUT[vertexId + 1]; ++iS) {
1328 auto& collStrTrk = mCollisionStrTrk[iS];
1329 auto&
label = sTrackLabels[collStrTrk.second];
1330 MCLabels labelHolder;
1331 labelHolder.labelID =
label.isValid() ? (mToStore[
label.getSourceID()][
label.getEventID()])[
label.getTrackID()] : -1;
1332 labelHolder.labelMask = (
label.isFake() << 15) | (
label.isNoise() << 14);
1333 mcTrackLabelCursor(labelHolder.labelID, labelHolder.labelMask);
1338template <
typename V0CursorType,
typename CascadeCursorType,
typename Decay3BodyCursorType>
1339void AODProducerWorkflowDPL::fillSecondaryVertices(
const o2::globaltracking::RecoContainer& recoData, V0CursorType& v0Cursor, CascadeCursorType& cascadeCursor, Decay3BodyCursorType& decay3BodyCursor)
1346 v0Cursor.reserve(v0s.size());
1348 for (
size_t iv0 = 0; iv0 < v0s.size(); iv0++) {
1349 const auto&
v0 = v0s[iv0];
1350 auto trPosID =
v0.getProngID(0);
1351 auto trNegID =
v0.getProngID(1);
1352 uint8_t v0flags =
v0.getBits();
1353 int posTableIdx = -1, negTableIdx = -1, collID = -1;
1354 auto item = mGIDToTableID.find(trPosID);
1355 if (item != mGIDToTableID.end()) {
1356 posTableIdx = item->second;
1358 LOG(warn) <<
"Could not find a positive track index for prong ID " << trPosID;
1360 item = mGIDToTableID.find(trNegID);
1361 if (item != mGIDToTableID.end()) {
1362 negTableIdx = item->second;
1364 LOG(warn) <<
"Could not find a negative track index for prong ID " << trNegID;
1366 auto itemV = mVtxToTableCollID.find(
v0.getVertexID());
1367 if (itemV == mVtxToTableCollID.end()) {
1368 LOG(warn) <<
"Could not find V0 collisionID for the vertex ID " <<
v0.getVertexID();
1370 collID = itemV->second;
1372 if (posTableIdx != -1 and negTableIdx != -1 and collID != -1) {
1373 v0Cursor(collID, posTableIdx, negTableIdx, v0flags);
1374 mV0ToTableID[int(iv0)] = mTableV0ID++;
1379 cascadeCursor.reserve(cascades.size());
1380 for (
auto& cascade : cascades) {
1381 auto itemV0 = mV0ToTableID.find(cascade.getV0ID());
1382 if (itemV0 == mV0ToTableID.end()) {
1385 int v0tableID = itemV0->second, bachTableIdx = -1, collID = -1;
1386 auto bachelorID = cascade.getBachelorID();
1387 auto item = mGIDToTableID.find(bachelorID);
1388 if (item != mGIDToTableID.end()) {
1389 bachTableIdx = item->second;
1391 LOG(warn) <<
"Could not find a bachelor track index";
1394 auto itemV = mVtxToTableCollID.find(cascade.getVertexID());
1395 if (itemV != mVtxToTableCollID.end()) {
1396 collID = itemV->second;
1398 LOG(warn) <<
"Could not find cascade collisionID for the vertex ID " << cascade.getVertexID();
1401 cascadeCursor(collID, v0tableID, bachTableIdx);
1405 decay3BodyCursor.reserve(decays3Body.size());
1406 for (
size_t i3Body = 0; i3Body < decays3Body.size(); i3Body++) {
1407 const auto& decay3Body = decays3Body[i3Body];
1409 decay3Body.getProngID(0),
1410 decay3Body.getProngID(1),
1411 decay3Body.getProngID(2)};
1412 int tableIdx[3]{-1, -1, -1}, collID = -1;
1413 bool missing{
false};
1414 for (
int i{0};
i < 3; ++
i) {
1415 auto item = mGIDToTableID.find(trIDs[
i]);
1416 if (item != mGIDToTableID.end()) {
1417 tableIdx[
i] = item->second;
1419 LOG(warn) << fmt::format(
"Could not find a track index for prong ID {}", (
int)trIDs[
i]);
1423 auto itemV = mVtxToTableCollID.find(decay3Body.getVertexID());
1424 if (itemV == mVtxToTableCollID.end()) {
1425 LOG(warn) <<
"Could not find 3 body collisionID for the vertex ID " << decay3Body.getVertexID();
1428 collID = itemV->second;
1433 decay3BodyCursor(collID, tableIdx[0], tableIdx[1], tableIdx[2]);
1437template <
typename FwdTrkClsCursorType>
1444 int mchTrackID = -1;
1446 mchTrackID = trackID.getIndex();
1448 auto mchmidMatch = mchmidMatches[trackID.getIndex()];
1449 mchTrackID = mchmidMatch.getMCHRef().getIndex();
1452 if (mchTrackID > -1 && mchTrackID < mchTracks.size()) {
1453 const auto& mchTrack = mchTracks[mchTrackID];
1454 int first = mchTrack.getFirstClusterIdx();
1455 int last = mchTrack.getLastClusterIdx();
1456 fwdTrkClsCursor.reserve(last -
first + 1 + fwdTrkClsCursor.lastIndex() + 1);
1457 for (
int i =
first;
i <= last;
i++) {
1458 const auto& cluster = mchClusters[
i];
1459 fwdTrkClsCursor(fwdTrackId,
1460 truncateFloatFraction(cluster.x, mMuonCl),
1461 truncateFloatFraction(cluster.y, mMuonCl),
1462 truncateFloatFraction(cluster.z, mMuonCl),
1463 (((cluster.ey < 5.) & 0x1) << 12) | (((cluster.ex < 5.) & 0x1) << 11) | cluster.getDEId());
1468template <
typename HMPCursorType>
1473 hmpCursor.reserve(hmpMatches.size());
1476 for (
size_t iHmp = 0; iHmp < hmpMatches.size(); iHmp++) {
1478 const auto&
match = hmpMatches[iHmp];
1480 float xTrk, yTrk, theta,
phi;
1484 match.getHMPIDtrk(xTrk, yTrk, theta,
phi);
1487 auto photChargeVec =
match.getPhotCharge();
1489 float photChargeVec2[10];
1491 for (Int_t
i = 0;
i < 10;
i++) {
1492 photChargeVec2[
i] = photChargeVec[
i];
1494 auto tref = mGIDToTableID.find(
match.getTrackRef());
1495 if (tref != mGIDToTableID.end()) {
1496 hmpCursor(tref->second,
match.getHMPsignal(), xTrk, yTrk, xMip, yMip, nph,
charge,
match.getIdxHMPClus(),
match.getHmpMom(), photChargeVec2);
1498 LOG(error) <<
"Could not find AOD track table entry for HMP-matched track " <<
match.getTrackRef().asString();
1510 mCollisionStrTrk.clear();
1512 mVertexStrLUT.clear();
1514 for (
auto& sTrk : recoData.getStrangeTracks()) {
1518 vtxId = v0s[sTrk.mDecayRef].getVertexID();
1520 vtxId = cascades[sTrk.mDecayRef].getVertexID();
1522 vtxId = decays3Body[sTrk.mDecayRef].getVertexID();
1524 mCollisionStrTrk.emplace_back(vtxId, sTrkID++);
1525 mVertexStrLUT[vtxId]++;
1527 std::exclusive_scan(mVertexStrLUT.begin(), mVertexStrLUT.end(), mVertexStrLUT.begin(), 0);
1530 std::stable_sort(mCollisionStrTrk.begin(), mCollisionStrTrk.end(), [](
const auto&
a,
const auto&
b) { return a.first < b.first; });
1531 mStrTrkIndices.clear();
1532 mStrTrkIndices.resize(mCollisionStrTrk.size(), -1);
1535template <
typename V0C,
typename CC,
typename D3BC>
1538 int itsTableIdx = -1;
1543 for (
const auto& sTrk : recoData.getStrangeTracks()) {
1553 v0Curs.reserve(nV0);
1554 cascCurs.reserve(nCasc);
1555 d3BodyCurs.reserve(nD3Body);
1559 for (
const auto& collStrTrk : mCollisionStrTrk) {
1560 const auto& sTrk = sTracks[collStrTrk.second];
1562 auto item = mGIDToTableID.find(ITSIndex);
1563 if (item != mGIDToTableID.end()) {
1564 itsTableIdx = item->second;
1566 LOG(warn) <<
"Could not find a ITS strange track index " << ITSIndex;
1570 v0Curs(mStrTrkIndices[collStrTrk.second],
1580 sTrk.getAverageClusterSize());
1582 cascCurs(mStrTrkIndices[collStrTrk.second],
1592 sTrk.getAverageClusterSize());
1594 d3BodyCurs(mStrTrkIndices[collStrTrk.second],
1604 sTrk.getAverageClusterSize());
1611 const auto& tpcTracks =
data.getTPCTracks();
1612 const auto& tpcClusRefs =
data.getTPCTracksClusterRefs();
1613 const auto& tpcClusShMap =
data.clusterShMapTPC;
1614 const auto& tpcClusAcc =
data.getTPCClusters();
1615 constexpr int maxRows = 152;
1616 constexpr int neighbour = 2;
1617 int ntr = tpcTracks.size();
1618 mTPCCounters.clear();
1619 mTPCCounters.resize(ntr);
1621 int ngroup = std::min(50, std::max(1, ntr / mNThreads));
1622#pragma omp parallel for schedule(dynamic, ngroup) num_threads(mNThreads)
1624 for (
int itr = 0; itr < ntr; itr++) {
1625 std::array<bool, maxRows> clMap{}, shMap{};
1626 uint8_t sectorIndex, rowIndex;
1627 uint32_t clusterIndex;
1628 auto&
counters = mTPCCounters[itr];
1629 const auto&
track = tpcTracks[itr];
1630 for (
int i = 0;
i <
track.getNClusterReferences();
i++) {
1631 o2::tpc::TrackTPC::getClusterReference(tpcClusRefs,
i, sectorIndex, rowIndex, clusterIndex,
track.getClusterRef());
1632 unsigned int absoluteIndex = tpcClusAcc.clusterOffset[sectorIndex][rowIndex] + clusterIndex;
1633 clMap[rowIndex] =
true;
1635 if (!shMap[rowIndex]) {
1638 shMap[rowIndex] =
true;
1642 for (
int i = 0;
i < maxRows;
i++) {
1647 }
else if ((
i - last) <= neighbour) {
1650 int lim = std::min(
i + 1 + neighbour, maxRows);
1651 for (
int j =
i + 1;
j < lim;
j++) {
1666 if (
track.getTrackletIndex(il) != -1) {
1670 if (
track.getHasNeighbor()) {
1673 if (
track.getHasPadrowCrossing()) {
1679template <
typename TCaloHandler,
typename TCaloCursor,
typename TCaloTRGCursor,
typename TMCCaloLabelCursor>
1680void AODProducerWorkflowDPL::addToCaloTable(TCaloHandler& caloHandler, TCaloCursor& caloCellCursor, TCaloTRGCursor& caloTRGCursor,
1681 TMCCaloLabelCursor& mcCaloCellLabelCursor,
int eventID,
int bcID, int8_t caloType)
1683 auto inputEvent = caloHandler.buildEvent(eventID);
1684 auto cellsInEvent = inputEvent.mCells;
1685 auto cellMClabels = inputEvent.mMCCellLabels;
1686 caloCellCursor.reserve(cellsInEvent.size() + caloCellCursor.lastIndex() + 1);
1687 caloTRGCursor.reserve(cellsInEvent.size() + caloTRGCursor.lastIndex() + 1);
1689 mcCaloCellLabelCursor.reserve(cellsInEvent.size() + mcCaloCellLabelCursor.lastIndex() + 1);
1691 for (
auto iCell = 0U; iCell < cellsInEvent.size(); iCell++) {
1692 caloCellCursor(bcID,
1696 cellsInEvent[iCell].
getType(),
1710 std::vector<int32_t> particleIds;
1711 std::vector<float> amplitudeFraction;
1712 if (!mEMCselectLeading) {
1713 particleIds.reserve(cellMClabels.size());
1714 amplitudeFraction.reserve(cellMClabels.size());
1716 float tmpMaxAmplitude = 0;
1717 int32_t tmpindex = 0;
1718 for (
auto& mclabel : cellMClabels[iCell]) {
1720 if (mclabel.isValid()) {
1721 if (mEMCselectLeading) {
1722 if (mclabel.getAmplitudeFraction() > tmpMaxAmplitude) {
1724 if (mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID()).find(mclabel.getTrackID()) !=
1725 mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID()).end()) {
1726 tmpMaxAmplitude = mclabel.getAmplitudeFraction();
1727 tmpindex = (mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID())).at(mclabel.getTrackID());
1731 auto trackStore = mToStore.at(mclabel.getSourceID()).at(mclabel.getEventID());
1732 auto iter = trackStore.find(mclabel.getTrackID());
1733 if (iter != trackStore.end()) {
1734 amplitudeFraction.emplace_back(mclabel.getAmplitudeFraction());
1735 particleIds.emplace_back(iter->second);
1737 particleIds.emplace_back(-1);
1738 amplitudeFraction.emplace_back(0.f);
1739 LOG(warn) <<
"CaloTable: Could not find track for mclabel (" << mclabel.getSourceID() <<
"," << mclabel.getEventID() <<
"," << mclabel.getTrackID() <<
") in the AOD MC store";
1740 if (mMCKineReader) {
1741 auto mctrack = mMCKineReader->
getTrack(mclabel);
1744 LOG(warn) <<
" ... this track is of PDG " << mctrack->GetPdgCode() <<
" produced by " << mctrack->getProdProcessAsString() <<
" at (" <<
vec.X() <<
"," <<
vec.Y() <<
"," <<
vec.Z() <<
")";
1750 if (mEMCselectLeading) {
1751 amplitudeFraction.emplace_back(tmpMaxAmplitude);
1752 particleIds.emplace_back(tmpindex);
1754 if (particleIds.size() == 0) {
1755 particleIds.emplace_back(-1);
1756 amplitudeFraction.emplace_back(0.f);
1758 mcCaloCellLabelCursor(particleIds,
1765template <
typename TCaloCursor,
typename TCaloTRGCursor,
typename TMCCaloLabelCursor>
1766void AODProducerWorkflowDPL::fillCaloTable(TCaloCursor& caloCellCursor, TCaloTRGCursor& caloTRGCursor,
1767 TMCCaloLabelCursor& mcCaloCellLabelCursor,
const std::map<uint64_t, int>& bcsMap,
1771 auto caloEMCCells =
data.getEMCALCells();
1772 auto caloEMCCellsTRGR =
data.getEMCALTriggers();
1773 auto mcCaloEMCCellLabels =
data.getEMCALCellsMCLabels();
1775 auto caloPHOSCells =
data.getPHOSCells();
1776 auto caloPHOSCellsTRGR =
data.getPHOSTriggers();
1777 auto mcCaloPHOSCellLabels =
data.getPHOSCellsMCLabels();
1781 caloPHOSCellsTRGR = {};
1782 mcCaloPHOSCellLabels = {};
1787 caloEMCCellsTRGR = {};
1788 mcCaloEMCCellLabels = {};
1795 emcEventHandler.
reset();
1796 emcEventHandler.
setCellData(caloEMCCells, caloEMCCellsTRGR);
1799 phsEventHandler.
reset();
1800 phsEventHandler.
setCellData(caloPHOSCells, caloPHOSCellsTRGR);
1806 std::vector<std::tuple<uint64_t, int8_t, int>> caloEvents;
1808 caloEvents.reserve(emcNEvents + phsNEvents);
1810 for (
int iev = 0; iev < emcNEvents; ++iev) {
1812 caloEvents.emplace_back(std::make_tuple(
bc, 1, iev));
1815 for (
int iev = 0; iev < phsNEvents; ++iev) {
1817 caloEvents.emplace_back(std::make_tuple(
bc, 0, iev));
1820 std::sort(caloEvents.begin(), caloEvents.end(),
1821 [](
const auto&
left,
const auto&
right) { return std::get<0>(left) < std::get<0>(right); });
1824 for (
int i = 0;
i < emcNEvents + phsNEvents; ++
i) {
1825 uint64_t globalBC = std::get<0>(caloEvents[
i]);
1826 int8_t caloType = std::get<1>(caloEvents[
i]);
1827 int eventID = std::get<2>(caloEvents[
i]);
1828 auto item = bcsMap.find(globalBC);
1830 if (item != bcsMap.end()) {
1831 bcID = item->second;
1833 LOG(warn) <<
"Error: could not find a corresponding BC ID for a calo point; globalBC = " << globalBC <<
", caloType = " << (
int)caloType;
1835 if (caloType == 0) {
1836 addToCaloTable(phsEventHandler, caloCellCursor, caloTRGCursor, mcCaloCellLabelCursor, eventID, bcID, caloType);
1838 if (caloType == 1) {
1839 addToCaloTable(emcEventHandler, caloCellCursor, caloTRGCursor, mcCaloCellLabelCursor, eventID, bcID, caloType);
1850 mLPMProdTag = ic.
options().
get<std::string>(
"lpmp-prod-tag");
1851 mAnchorPass = ic.
options().
get<std::string>(
"anchor-pass");
1852 mAnchorProd = ic.
options().
get<std::string>(
"anchor-prod");
1853 mUser = ic.
options().
get<std::string>(
"created-by");
1854 mRecoPass = ic.
options().
get<std::string>(
"reco-pass");
1855 mAODParent = ic.
options().
get<std::string>(
"aod-parent");
1856 mTFNumber = ic.
options().
get<int64_t>(
"aod-timeframe-id");
1857 mRecoOnly = ic.
options().
get<
int>(
"reco-mctracks-only");
1858 mTruncate = ic.
options().
get<
int>(
"enable-truncation");
1859 mRunNumber = ic.
options().
get<
int>(
"run-number");
1860 mCTPReadout = ic.
options().
get<
int>(
"ctpreadout-create");
1861 mNThreads = std::max(1, ic.
options().
get<
int>(
"nthreads"));
1862 mEMCselectLeading = ic.
options().
get<
bool>(
"emc-select-leading");
1863 mThinTracks = ic.
options().
get<
bool>(
"thin-tracks");
1864 mPropTracks = ic.
options().
get<
bool>(
"propagate-tracks");
1865 mMaxPropXiu = ic.
options().
get<
float>(
"propagate-tracks-max-xiu");
1866 mPropMuons = ic.
options().
get<
bool>(
"propagate-muons");
1867 mStoreAllMFTCov = ic.
options().
get<
bool>(
"store-all-mft-cov");
1868 if (
auto s = ic.
options().
get<std::string>(
"with-streamers"); !
s.empty()) {
1869 mStreamerFlags.
set(
s);
1870 if (mStreamerFlags) {
1871 LOGP(info,
"Writing streamer data with mask:");
1872 LOG(info) << mStreamerFlags;
1874 LOGP(warn,
"Specified non-default empty streamer mask!");
1877 mTrackQCKeepGlobalTracks = ic.
options().
get<
bool>(
"trackqc-keepglobaltracks");
1878 mTrackQCRetainOnlydEdx = ic.
options().
get<
bool>(
"trackqc-retainonlydedx");
1879 mTrackQCFraction = ic.
options().
get<
float>(
"trackqc-fraction");
1880 mTrackQCNTrCut = ic.
options().
get<int64_t>(
"trackqc-NTrCut");
1881 mTrackQCDCAxy = ic.
options().
get<
float>(
"trackqc-tpc-dca");
1882 mTrackQCPt = ic.
options().
get<
float>(
"trackqc-tpc-pt");
1883 mTrackQCNCls = ic.
options().
get<
int>(
"trackqc-tpc-cls");
1884 if (
auto seed = ic.
options().
get<
int>(
"seed"); seed == 0) {
1885 LOGP(info,
"Using random device for seeding");
1886 std::random_device
rd;
1887 std::array<int, std::mt19937::state_size> seed_data{};
1888 std::generate(std::begin(seed_data), std::end(seed_data), std::ref(
rd));
1889 std::seed_seq seq(std::begin(seed_data), std::end(seed_data));
1890 mGenerator = std::mt19937(seq);
1892 LOGP(info,
"Using seed {} for sampling", seed);
1893 mGenerator.seed(seed);
1896 LOGP(info,
"Multi-threaded parts will run with {} OpenMP threads", mNThreads);
1899 LOG(info) <<
"OpenMP is disabled";
1901 if (mTFNumber == -1L) {
1902 LOG(info) <<
"TFNumber will be obtained from CCDB";
1904 if (mRunNumber == -1L) {
1905 LOG(info) <<
"The Run number will be obtained from DPL headers";
1908 mUseSigFiltMC = ic.
options().
get<
bool>(
"mc-signal-filt");
1910 mCollectConfigFiles = ic.
options().
get<
bool>(
"collect-config-files");
1913 if (mTruncate != 1) {
1914 LOG(info) <<
"Truncation is not used!";
1915 mCollisionPosition = 0xFFFFFFFF;
1916 mCollisionPositionCov = 0xFFFFFFFF;
1917 mTrackX = 0xFFFFFFFF;
1918 mTrackAlpha = 0xFFFFFFFF;
1919 mTrackSnp = 0xFFFFFFFF;
1920 mTrackTgl = 0xFFFFFFFF;
1921 mTrack1Pt = 0xFFFFFFFF;
1922 mTrackChi2 = 0xFFFFFFFF;
1923 mTrackCovDiag = 0xFFFFFFFF;
1924 mTrackCovOffDiag = 0xFFFFFFFF;
1925 mTrackSignal = 0xFFFFFFFF;
1926 mTrackTime = 0xFFFFFFFF;
1927 mTPCTime0 = 0xFFFFFFFF;
1928 mTrackTimeError = 0xFFFFFFFF;
1929 mTrackPosEMCAL = 0xFFFFFFFF;
1930 mTracklets = 0xFFFFFFFF;
1931 mMcParticleW = 0xFFFFFFFF;
1932 mMcParticlePos = 0xFFFFFFFF;
1933 mMcParticleMom = 0xFFFFFFFF;
1934 mCaloAmp = 0xFFFFFFFF;
1935 mCaloTime = 0xFFFFFFFF;
1936 mCPVPos = 0xFFFFFFFF;
1937 mCPVAmpl = 0xFFFFFFFF;
1938 mMuonTr1P = 0xFFFFFFFF;
1939 mMuonTrThetaX = 0xFFFFFFFF;
1940 mMuonTrThetaY = 0xFFFFFFFF;
1941 mMuonTrZmu = 0xFFFFFFFF;
1942 mMuonTrBend = 0xFFFFFFFF;
1943 mMuonTrNonBend = 0xFFFFFFFF;
1944 mMuonTrCov = 0xFFFFFFFF;
1945 mMuonCl = 0xFFFFFFFF;
1946 mMuonClErr = 0xFFFFFFFF;
1947 mV0Time = 0xFFFFFFFF;
1948 mV0ChannelTime = 0xFFFFFFFF;
1949 mFDDTime = 0xFFFFFFFF;
1950 mFDDChannelTime = 0xFFFFFFFF;
1951 mT0Time = 0xFFFFFFFF;
1952 mT0ChannelTime = 0xFFFFFFFF;
1953 mV0Amplitude = 0xFFFFFFFF;
1954 mFDDAmplitude = 0xFFFFFFFF;
1955 mT0Amplitude = 0xFFFFFFFF;
1959 mZDCEnergyMap[ic] = -std::numeric_limits<float>::infinity();
1962 mZDCTDCMap[ic] = -std::numeric_limits<float>::infinity();
1965 std::string hepmcUpdate = ic.
options().
get<std::string>(
"hepmc-update");
1966 HepMCUpdate when = (hepmcUpdate ==
"never" ? HepMCUpdate::never : hepmcUpdate ==
"always" ? HepMCUpdate::always
1967 : hepmcUpdate ==
"all" ? HepMCUpdate::allKeys
1968 : HepMCUpdate::anyKey);
1969 mXSectionUpdate = when;
1970 mPdfInfoUpdate = when;
1971 mHeavyIonUpdate = when;
1975 if (mStreamerFlags) {
1976 mStreamer = std::make_unique<o2::utils::TreeStreamRedirector>(
"AO2DStreamer.root",
"RECREATE");
1982void add_additional_meta_info(std::vector<TString>&
keys, std::vector<TString>&
values)
1985 auto aod_external_meta_info_file = getenv(
"AOD_ADDITIONAL_METADATA_FILE");
1986 if (aod_external_meta_info_file !=
nullptr) {
1987 LOG(info) <<
"Trying to inject additional AOD meta-data from " << aod_external_meta_info_file;
1988 if (std::filesystem::exists(aod_external_meta_info_file)) {
1989 std::ifstream input_file(aod_external_meta_info_file);
1991 nlohmann::json json_data;
1993 input_file >> json_data;
1994 }
catch (nlohmann::json::parse_error& e) {
1995 std::cerr <<
"JSON Parse Error: " << e.what() <<
"\n";
1996 std::cerr <<
"Exception ID: " << e.id <<
"\n";
1997 std::cerr <<
"Byte position: " << e.byte <<
"\n";
2001 for (
const auto& [
key,
value] : json_data.items()) {
2002 LOG(info) <<
"Adding AOD MetaData" <<
key <<
" : " <<
value;
2014 mTimer.Start(
false);
2017 updateTimeDependentParams(pc);
2042 std::vector<o2::ctp::CTPDigit> ctpDigitsCreated;
2043 if (mCTPReadout == 1) {
2044 LOG(info) <<
"CTP : creating ctpreadout in AOD producer";
2045 createCTPReadout(recoData, ctpDigitsCreated, pc);
2046 LOG(info) <<
"CTP : ctpreadout created from AOD";
2047 ctpDigits = gsl::span<o2::ctp::CTPDigit>(ctpDigitsCreated);
2049 LOG(
debug) <<
"FOUND " << primVertices.size() <<
" primary vertices";
2050 LOG(
debug) <<
"FOUND " << ft0RecPoints.size() <<
" FT0 rec. points";
2051 LOG(
debug) <<
"FOUND " << fv0RecPoints.size() <<
" FV0 rec. points";
2052 LOG(
debug) <<
"FOUND " << fddRecPoints.size() <<
" FDD rec. points";
2053 LOG(
debug) <<
"FOUND " << cpvClusters.size() <<
" CPV clusters";
2054 LOG(
debug) <<
"FOUND " << cpvTrigRecs.size() <<
" CPV trigger records";
2056 LOG(info) <<
"FOUND " << primVertices.size() <<
" primary vertices";
2060 auto bcCursor = createTableCursor<o2::aod::BCs>(pc);
2061 auto bcFlagsCursor = createTableCursor<o2::aod::BCFlags>(pc);
2062 auto cascadesCursor = createTableCursor<o2::aod::Cascades>(pc);
2063 auto collisionsCursor = createTableCursor<o2::aod::Collisions>(pc);
2064 auto decay3BodyCursor = createTableCursor<o2::aod::Decay3Bodys>(pc);
2065 auto trackedCascadeCursor = createTableCursor<o2::aod::TrackedCascades>(pc);
2066 auto trackedV0Cursor = createTableCursor<o2::aod::TrackedV0s>(pc);
2067 auto tracked3BodyCurs = createTableCursor<o2::aod::Tracked3Bodys>(pc);
2068 auto fddCursor = createTableCursor<o2::aod::FDDs>(pc);
2069 auto fddExtraCursor = createTableCursor<o2::aod::FDDsExtra>(pc);
2070 auto ft0Cursor = createTableCursor<o2::aod::FT0s>(pc);
2071 auto ft0ExtraCursor = createTableCursor<o2::aod::FT0sExtra>(pc);
2072 auto fv0aCursor = createTableCursor<o2::aod::FV0As>(pc);
2073 auto fv0aExtraCursor = createTableCursor<o2::aod::FV0AsExtra>(pc);
2074 auto fwdTracksCursor = createTableCursor<o2::aod::StoredFwdTracks>(pc);
2075 auto fwdTracksCovCursor = createTableCursor<o2::aod::StoredFwdTracksCov>(pc);
2076 auto fwdTrkClsCursor = createTableCursor<o2::aod::FwdTrkCls>(pc);
2077 auto mftTracksCursor = createTableCursor<o2::aod::StoredMFTTracks>(pc);
2078 auto mftTracksCovCursor = createTableCursor<o2::aod::StoredMFTTracksCov>(pc);
2079 auto tracksCursor = createTableCursor<o2::aod::StoredTracksIU>(pc);
2080 auto tracksCovCursor = createTableCursor<o2::aod::StoredTracksCovIU>(pc);
2081 auto tracksExtraCursor = createTableCursor<o2::aod::StoredTracksExtra>(pc);
2082 auto tracksQACursor = createTableCursor<o2::aod::TracksQAVersion>(pc);
2083 auto ambigTracksCursor = createTableCursor<o2::aod::AmbiguousTracks>(pc);
2084 auto ambigMFTTracksCursor = createTableCursor<o2::aod::AmbiguousMFTTracks>(pc);
2085 auto ambigFwdTracksCursor = createTableCursor<o2::aod::AmbiguousFwdTracks>(pc);
2086 auto v0sCursor = createTableCursor<o2::aod::V0s>(pc);
2087 auto zdcCursor = createTableCursor<o2::aod::Zdcs>(pc);
2088 auto hmpCursor = createTableCursor<o2::aod::HMPIDs>(pc);
2089 auto caloCellsCursor = createTableCursor<o2::aod::Calos>(pc);
2090 auto caloCellsTRGTableCursor = createTableCursor<o2::aod::CaloTriggers>(pc);
2091 auto cpvClustersCursor = createTableCursor<o2::aod::CPVClusters>(pc);
2092 auto originCursor = createTableCursor<o2::aod::Origins>(pc);
2096 if (mEnableTRDextra) {
2097 trdExtraCursor = createTableCursor<o2::aod::TRDsExtra>(pc);
2112 mcColLabelsCursor = createTableCursor<o2::aod::McCollisionLabels>(pc);
2113 mcCollisionsCursor = createTableCursor<o2::aod::McCollisions>(pc);
2114 hepmcXSectionsCursor = createTableCursor<o2::aod::HepMCXSections>(pc);
2115 hepmcPdfInfosCursor = createTableCursor<o2::aod::HepMCPdfInfos>(pc);
2116 hepmcHeavyIonsCursor = createTableCursor<o2::aod::HepMCHeavyIons>(pc);
2117 mcMFTTrackLabelCursor = createTableCursor<o2::aod::McMFTTrackLabels>(pc);
2118 mcFwdTrackLabelCursor = createTableCursor<o2::aod::McFwdTrackLabels>(pc);
2119 mcParticlesCursor = createTableCursor<o2::aod::StoredMcParticles_001>(pc);
2120 mcTrackLabelCursor = createTableCursor<o2::aod::McTrackLabels>(pc);
2121 mcCaloLabelsCursor = createTableCursor<o2::aod::McCaloLabels_001>(pc);
2124 std::unique_ptr<o2::steer::MCKinematicsReader> mcReader;
2126 mcReader = std::make_unique<o2::steer::MCKinematicsReader>(
"collisioncontext.root");
2128 mMCKineReader = mcReader.get();
2129 std::map<uint64_t, int> bcsMap;
2130 collectBCs(recoData, mUseMC ? mcReader->getDigitizationContext()->getEventRecords() : std::vector<o2::InteractionTimeRecord>{}, bcsMap);
2131 if (!primVer2TRefs.empty()) {
2132 addRefGlobalBCsForTOF(primVer2TRefs.back(), primVerGIs, recoData, bcsMap);
2135 mBCLookup.
init(bcsMap);
2138 const int runNumber = (mRunNumber == -1) ?
int(tinfo.runNumber) : mRunNumber;
2139 if (mTFNumber == -1L) {
2141 tfNumber = uint64_t(tinfo.firstTForbit) + (uint64_t(tinfo.runNumber) << 32);
2143 tfNumber = mTFNumber;
2146 std::vector<float> aAmplitudes, aTimes;
2147 std::vector<uint8_t> aChannels;
2148 fv0aCursor.reserve(fv0RecPoints.size());
2149 for (
auto& fv0RecPoint : fv0RecPoints) {
2150 aAmplitudes.clear();
2153 const auto channelData = fv0RecPoint.getBunchChannelData(fv0ChData);
2154 for (
auto& channel : channelData) {
2155 if (channel.charge > 0) {
2156 aAmplitudes.push_back(truncateFloatFraction(channel.charge, mV0Amplitude));
2157 aTimes.push_back(truncateFloatFraction(channel.time * 1.E-3, mV0ChannelTime));
2158 aChannels.push_back(channel.channel);
2161 uint64_t
bc = fv0RecPoint.getInteractionRecord().toLong();
2162 auto item = bcsMap.find(
bc);
2164 if (item != bcsMap.end()) {
2165 bcID = item->second;
2167 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a FV0 rec. point; BC = " <<
bc;
2172 truncateFloatFraction(fv0RecPoint.getCollisionGlobalMeanTime() * 1E-3, mV0Time),
2173 fv0RecPoint.getTrigger().getTriggersignals());
2175 if (mEnableFITextra) {
2176 fv0aExtraCursor(bcID,
2181 std::vector<float> zdcEnergy, zdcAmplitudes, zdcTime;
2182 std::vector<uint8_t> zdcChannelsE, zdcChannelsT;
2183 zdcCursor.reserve(zdcBCRecData.size());
2184 for (
auto zdcRecData : zdcBCRecData) {
2185 uint64_t
bc = zdcRecData.ir.toLong();
2186 auto item = bcsMap.find(
bc);
2188 if (item != bcsMap.end()) {
2189 bcID = item->second;
2191 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a ZDC rec. point; BC = " <<
bc;
2193 int fe, ne, ft, nt, fi, ni;
2194 zdcRecData.getRef(fe, ne, ft, nt, fi, ni);
2196 zdcChannelsE.clear();
2197 zdcAmplitudes.clear();
2199 zdcChannelsT.clear();
2200 for (
int ie = 0; ie < ne; ie++) {
2201 auto& zdcEnergyData = zdcEnergies[fe + ie];
2202 zdcEnergy.emplace_back(zdcEnergyData.energy());
2203 zdcChannelsE.emplace_back(zdcEnergyData.ch());
2205 for (
int it = 0; it < nt; it++) {
2206 auto& tdc = zdcTDCData[ft + it];
2207 zdcAmplitudes.emplace_back(tdc.amplitude());
2208 zdcTime.emplace_back(tdc.value());
2220 std::vector<MCColInfo> mcColToEvSrc;
2226 int nMCCollisions = mcReader->getDigitizationContext()->getNCollisions();
2227 const auto& mcRecords = mcReader->getDigitizationContext()->getEventRecords();
2228 const auto& mcParts = mcReader->getDigitizationContext()->getEventParts();
2231 if (mUseSigFiltMC) {
2232 std::vector<int> sourceIDs{};
2233 for (
int iCol = 0; iCol < nMCCollisions; iCol++) {
2234 for (
auto const& colPart : mcParts[iCol]) {
2235 int sourceID = colPart.sourceID;
2236 if (std::find(sourceIDs.begin(), sourceIDs.end(), sourceID) == sourceIDs.end()) {
2237 sourceIDs.push_back(sourceID);
2239 if (sourceIDs.size() > 1) {
2243 if (sourceIDs.size() > 1) {
2247 if (sourceIDs.size() <= 1) {
2248 LOGP(fatal,
"Signal filtering cannot be enabled without embedding. Please fix the configuration either enabling the embedding, or turning off the signal filtering.");
2253 int totalNParts = 0;
2254 for (
int iCol = 0; iCol < nMCCollisions; iCol++) {
2255 totalNParts += mcParts[iCol].size();
2257 mcCollisionsCursor.
reserve(totalNParts);
2259 for (
int iCol = 0; iCol < nMCCollisions; iCol++) {
2260 const auto time = mcRecords[iCol].getTimeOffsetWrtBC();
2261 auto globalBC = mcRecords[iCol].toLong();
2262 auto item = bcsMap.find(globalBC);
2264 if (item != bcsMap.end()) {
2265 bcID = item->second;
2267 LOG(fatal) <<
"Error: could not find a corresponding BC ID "
2268 <<
"for MC collision; BC = " << globalBC
2269 <<
", mc collision = " << iCol;
2271 auto& colParts = mcParts[iCol];
2272 auto nParts = colParts.size();
2273 for (
auto colPart : colParts) {
2274 auto eventID = colPart.entryID;
2275 auto sourceID = colPart.sourceID;
2278 if (nParts == 1 || sourceID == 0) {
2281 auto&
header = mcReader->getMCEventHeader(sourceID, eventID);
2282 updateMCHeader(mcCollisionsCursor.
cursor,
2283 hepmcXSectionsCursor.
cursor,
2284 hepmcPdfInfosCursor.
cursor,
2285 hepmcHeavyIonsCursor.
cursor,
2293 mcColToEvSrc.emplace_back(
MCColInfo{iCol, sourceID, eventID, globalBC});
2298 std::sort(mcColToEvSrc.begin(), mcColToEvSrc.end(),
2302 int16_t aFDDAmplitudesA[8] = {0u}, aFDDAmplitudesC[8] = {0u};
2303 float aFDDTimesA[8] = {0.f}, aFDDTimesC[8] = {0.f};
2305 fddCursor.reserve(fddRecPoints.size());
2306 for (
const auto& fddRecPoint : fddRecPoints) {
2307 for (
int i = 0;
i < 8;
i++) {
2308 aFDDAmplitudesA[
i] = 0;
2309 aFDDAmplitudesC[
i] = 0;
2310 aFDDTimesA[
i] = 0.f;
2311 aFDDTimesC[
i] = 0.f;
2313 uint64_t globalBC = fddRecPoint.getInteractionRecord().toLong();
2314 uint64_t
bc = globalBC;
2315 auto item = bcsMap.find(
bc);
2317 if (item != bcsMap.end()) {
2318 bcID = item->second;
2320 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a FDD rec. point; BC = " <<
bc;
2322 const auto channelData = fddRecPoint.getBunchChannelData(fddChData);
2323 for (
const auto& channel : channelData) {
2324 if (channel.mPMNumber < 8) {
2325 aFDDAmplitudesC[channel.mPMNumber] = channel.mChargeADC;
2326 aFDDTimesC[channel.mPMNumber] = truncateFloatFraction(channel.mTime * 1E-3, mFDDChannelTime);
2328 aFDDAmplitudesA[channel.mPMNumber - 8] = channel.mChargeADC;
2329 aFDDTimesA[channel.mPMNumber - 8] = truncateFloatFraction(channel.mTime * 1E-3, mFDDChannelTime);
2336 truncateFloatFraction(fddRecPoint.getCollisionTimeA() * 1E-3, mFDDTime),
2337 truncateFloatFraction(fddRecPoint.getCollisionTimeC() * 1E-3, mFDDTime),
2338 fddRecPoint.getTrigger().getTriggersignals());
2339 if (mEnableFITextra) {
2340 fddExtraCursor(bcID,
2347 std::vector<float> aAmplitudesA, aAmplitudesC, aTimesA, aTimesC;
2348 std::vector<uint8_t> aChannelsA, aChannelsC;
2349 ft0Cursor.reserve(ft0RecPoints.size());
2350 for (
auto& ft0RecPoint : ft0RecPoints) {
2351 aAmplitudesA.clear();
2352 aAmplitudesC.clear();
2357 const auto channelData = ft0RecPoint.getBunchChannelData(ft0ChData);
2358 for (
auto& channel : channelData) {
2360 if (channel.QTCAmpl > 0) {
2362 if (channel.ChId < nFT0ChannelsAside) {
2363 aChannelsA.push_back(channel.ChId);
2364 aAmplitudesA.push_back(truncateFloatFraction(channel.QTCAmpl, mT0Amplitude));
2365 aTimesA.push_back(truncateFloatFraction(channel.CFDTime * 1E-3, mT0ChannelTime));
2367 aChannelsC.push_back(channel.ChId - nFT0ChannelsAside);
2368 aAmplitudesC.push_back(truncateFloatFraction(channel.QTCAmpl, mT0Amplitude));
2369 aTimesC.push_back(truncateFloatFraction(channel.CFDTime * 1E-3, mT0ChannelTime));
2373 uint64_t globalBC = ft0RecPoint.getInteractionRecord().toLong();
2374 uint64_t
bc = globalBC;
2375 auto item = bcsMap.find(
bc);
2377 if (item != bcsMap.end()) {
2378 bcID = item->second;
2380 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a FT0 rec. point; BC = " <<
bc;
2387 truncateFloatFraction(ft0RecPoint.getCollisionTimeA() * 1E-3, mT0Time),
2388 truncateFloatFraction(ft0RecPoint.getCollisionTimeC() * 1E-3, mT0Time),
2389 ft0RecPoint.getTrigger().getTriggersignals());
2390 if (mEnableFITextra) {
2391 ft0ExtraCursor(bcID,
2399 mcColLabelsCursor.
reserve(primVerLabels.size());
2400 for (
size_t ivert = 0; ivert < primVerLabels.size(); ++ivert) {
2401 const auto&
label = primVerLabels[ivert];
2407 std::vector<std::pair<int32_t, int64_t>> candidates;
2408 for (
const auto& colInfo : mcColToEvSrc) {
2409 if (colInfo.sourceID ==
label.getSourceID() &&
2410 colInfo.eventID ==
label.getEventID()) {
2411 candidates.emplace_back(colInfo.colIndex, colInfo.bc);
2415 int32_t mcCollisionID = -1;
2416 if (candidates.size() == 1) {
2417 mcCollisionID = candidates[0].first;
2418 }
else if (candidates.size() > 1) {
2424 const auto& timeStamp = primVertices[ivert].getTimeStamp();
2425 const double interactionTime = timeStamp.getTimeStamp() * 1E3;
2426 const auto recoBC = relativeTime_to_GlobalBC(interactionTime);
2427 int64_t bestDiff = std::numeric_limits<int64_t>::max();
2428 for (
const auto& [colIndex,
bc] : candidates) {
2429 const auto bcDiff = std::abs(
static_cast<int64_t
>(
bc) -
static_cast<int64_t
>(recoBC));
2430 if (bcDiff < bestDiff) {
2432 mcCollisionID = colIndex;
2437 uint16_t mcMask = 0;
2438 mcColLabelsCursor(mcCollisionID, mcMask);
2442 cacheTriggers(recoData);
2443 countTPCClusters(recoData);
2445 int collisionID = 0;
2449 auto& trackReffwd = primVer2TRefs.back();
2450 fillIndexTablesPerCollision(trackReffwd, primVerGIs, recoData);
2452 for (
auto&
vertex : primVertices) {
2453 auto& trackReffwd = primVer2TRefs[collisionID];
2454 fillIndexTablesPerCollision(trackReffwd, primVerGIs, recoData);
2459 prepareStrangenessTracking(recoData);
2461 mGIDToTableFwdID.clear();
2462 mGIDToTableMFTID.clear();
2464 if (mPropTracks || mThinTracks) {
2468 mGIDUsedBySVtx.reserve(v0s.size() * 2 + cascades.size() + decays3Body.size() * 3);
2469 for (
const auto&
v0 : v0s) {
2470 mGIDUsedBySVtx.insert(
v0.getProngID(0));
2471 mGIDUsedBySVtx.insert(
v0.getProngID(1));
2473 for (
const auto& cascade : cascades) {
2474 mGIDUsedBySVtx.insert(cascade.getBachelorID());
2476 for (
const auto& id3Body : decays3Body) {
2477 mGIDUsedBySVtx.insert(id3Body.getProngID(0));
2478 mGIDUsedBySVtx.insert(id3Body.getProngID(1));
2479 mGIDUsedBySVtx.insert(id3Body.getProngID(2));
2488 mCurrentTRDTrigID = 0;
2491 auto& trackRef = primVer2TRefs.back();
2493 fillTrackTablesPerCollision(-1, std::uint64_t(-1), trackRef, primVerGIs, recoData, tracksCursor, tracksCovCursor, tracksExtraCursor, tracksQACursor, trdExtraCursor,
2494 ambigTracksCursor, mftTracksCursor, mftTracksCovCursor, ambigMFTTracksCursor,
2495 fwdTracksCursor, fwdTracksCovCursor, ambigFwdTracksCursor, fwdTrkClsCursor, bcsMap);
2497 mCurrentTRDTrigID = 0;
2500 collisionsCursor.reserve(primVertices.size());
2501 for (
auto&
vertex : primVertices) {
2502 auto& cov =
vertex.getCov();
2503 auto& timeStamp =
vertex.getTimeStamp();
2504 const double interactionTime = timeStamp.getTimeStamp() * 1E3;
2505 uint64_t globalBC = relativeTime_to_GlobalBC(interactionTime);
2506 uint64_t localBC = relativeTime_to_LocalBC(interactionTime);
2507 LOG(
debug) <<
"global BC " << globalBC <<
" local BC " << localBC <<
" relative interaction time " << interactionTime;
2509 const float relInteractionTime =
static_cast<float>(localBC * o2::constants::lhc::LHCBunchSpacingNS - interactionTime);
2510 auto item = bcsMap.find(globalBC);
2512 if (item != bcsMap.end()) {
2513 bcID = item->second;
2515 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a collision; BC = " << globalBC <<
", collisionID = " << collisionID;
2517 collisionsCursor(bcID,
2518 truncateFloatFraction(
vertex.getX(), mCollisionPosition),
2519 truncateFloatFraction(
vertex.getY(), mCollisionPosition),
2520 truncateFloatFraction(
vertex.getZ(), mCollisionPosition),
2521 truncateFloatFraction(cov[0], mCollisionPositionCov),
2522 truncateFloatFraction(cov[1], mCollisionPositionCov),
2523 truncateFloatFraction(cov[2], mCollisionPositionCov),
2524 truncateFloatFraction(cov[3], mCollisionPositionCov),
2525 truncateFloatFraction(cov[4], mCollisionPositionCov),
2526 truncateFloatFraction(cov[5], mCollisionPositionCov),
2528 truncateFloatFraction(
vertex.getChi2(), mCollisionPositionCov),
2529 vertex.getNContributors(),
2530 truncateFloatFraction(relInteractionTime, mCollisionPosition),
2531 truncateFloatFraction(timeStamp.getTimeStampError() * 1E3, mCollisionPositionCov));
2532 mVtxToTableCollID[collisionID] = mTableCollID++;
2534 auto& trackRef = primVer2TRefs[collisionID];
2536 fillTrackTablesPerCollision(collisionID, globalBC, trackRef, primVerGIs, recoData, tracksCursor, tracksCovCursor, tracksExtraCursor, tracksQACursor, trdExtraCursor, ambigTracksCursor,
2537 mftTracksCursor, mftTracksCovCursor, ambigMFTTracksCursor,
2538 fwdTracksCursor, fwdTracksCovCursor, ambigFwdTracksCursor, fwdTrkClsCursor, bcsMap);
2542 fillSecondaryVertices(recoData, v0sCursor, cascadesCursor, decay3BodyCursor);
2543 fillHMPID(recoData, hmpCursor);
2544 fillStrangenessTrackingTables(recoData, trackedV0Cursor, trackedCascadeCursor, tracked3BodyCurs);
2548 std::unordered_map<uint64_t, std::pair<uint64_t, uint64_t>> bcToClassMask;
2550 LOG(
debug) <<
"CTP input available";
2551 for (
auto& ctpDigit : ctpDigits) {
2552 uint64_t
bc = ctpDigit.intRecord.toLong();
2553 uint64_t classMask = ctpDigit.CTPClassMask.to_ulong();
2554 uint64_t inputMask = ctpDigit.CTPInputMask.to_ulong();
2555 if (emcalIncomplete.find(
bc) != emcalIncomplete.end()) {
2557 auto classMaskOrig = classMask;
2558 classMask = classMask & ~mEMCALTrgClassMask;
2559 LOG(
debug) <<
"Found EMCAL incomplete event, mask before " << std::bitset<64>(classMaskOrig) <<
", after " << std::bitset<64>(classMask);
2561 bcToClassMask[
bc] = {classMask, inputMask};
2567 bcCursor.reserve(bcsMap.size());
2568 for (
auto& item : bcsMap) {
2569 uint64_t
bc = item.first;
2570 std::pair<uint64_t, uint64_t> masks{0, 0};
2572 auto bcClassPair = bcToClassMask.find(
bc);
2573 if (bcClassPair != bcToClassMask.end()) {
2574 masks = bcClassPair->second;
2583 bcToClassMask.clear();
2586 auto bcFlags = fillBCFlags(recoData, bcsMap);
2587 bcFlagsCursor.reserve(bcFlags.size());
2588 for (
auto f : bcFlags) {
2595 cpvClustersCursor.reserve(cpvClusters.size());
2596 for (
auto& cpvEvent : cpvTrigRecs) {
2597 uint64_t
bc = cpvEvent.getBCData().toLong();
2598 auto item = bcsMap.find(
bc);
2600 if (item != bcsMap.end()) {
2601 bcID = item->second;
2603 LOG(fatal) <<
"Error: could not find a corresponding BC ID for a CPV Trigger Record; BC = " <<
bc;
2605 for (
int iClu = cpvEvent.getFirstEntry(); iClu < cpvEvent.getFirstEntry() + cpvEvent.getNumberOfObjects(); iClu++) {
2606 auto&
clu = cpvClusters[iClu];
2607 clu.getLocalPosition(posX, posZ);
2608 cpvClustersCursor(bcID,
2609 truncateFloatFraction(posX, mCPVPos),
2610 truncateFloatFraction(posZ, mCPVPos),
2611 truncateFloatFraction(
clu.getEnergy(), mCPVAmpl),
2612 clu.getPackedClusterStatus());
2621 fillMCParticlesTable(*mcReader,
2622 mcParticlesCursor.
cursor,
2628 LOG(info) <<
"FILL MC took " << timer.RealTime() <<
" s";
2629 mcColToEvSrc.clear();
2635 fillMCTrackLabelsTable(mcTrackLabelCursor, mcMFTTrackLabelCursor, mcFwdTrackLabelCursor, primVer2TRefs.back(), primVerGIs, recoData);
2636 for (
auto iref = 0U; iref < primVer2TRefs.size() - 1; iref++) {
2637 auto& trackRef = primVer2TRefs[iref];
2638 fillMCTrackLabelsTable(mcTrackLabelCursor, mcMFTTrackLabelCursor, mcFwdTrackLabelCursor, trackRef, primVerGIs, recoData, iref);
2644 fillCaloTable(caloCellsCursor, caloCellsTRGTableCursor, mcCaloLabelsCursor, bcsMap, recoData);
2649 mGIDToTableID.clear();
2651 mGIDToTableFwdID.clear();
2653 mGIDToTableMFTID.clear();
2655 mVtxToTableCollID.clear();
2657 mV0ToTableID.clear();
2660 mIndexTableFwd.clear();
2662 mIndexTableMFT.clear();
2667 mGIDUsedBySVtx.clear();
2668 mGIDUsedByStr.clear();
2670 originCursor(tfNumber);
2673 TString dataType = mUseMC ?
"MC" :
"RAW";
2675 TString ROOTVersion = ROOT_RELEASE;
2676 mMetaDataKeys = {
"DataType",
"Run",
"O2Version",
"ROOTVersion",
"RecoPassName",
"AnchorProduction",
"AnchorPassName",
"LPMProductionTag",
"CreatedBy"};
2677 mMetaDataVals = {dataType,
"3", O2Version, ROOTVersion, mRecoPass, mAnchorProd, mAnchorPass, mLPMProdTag, mUser};
2678 add_additional_meta_info(mMetaDataKeys, mMetaDataVals);
2680 if (mCollectConfigFiles) {
2681 collectConfigFiles(mMetaDataKeys, mMetaDataVals);
2700 for (
const auto& rof : rofs) {
2701 int first = rof.getFirstEntry(), last =
first + rof.getNEntries();
2702 for (
int i =
first;
i < last;
i++) {
2703 mITSROFs.push_back(
count);
2713 for (
const auto& rof : rofs) {
2714 int first = rof.getFirstEntry(),
last =
first + rof.getNEntries();
2716 mMFTROFs.push_back(
count);
2723 mITSTPCTRDTriggers.clear();
2726 for (
const auto& trig : itstpctrigs) {
2727 int first = trig.getFirstTrack(),
last =
first + trig.getNumberOfTracks();
2729 mITSTPCTRDTriggers.push_back(
count);
2736 mTPCTRDTriggers.clear();
2739 for (
const auto& trig : tpctrigs) {
2740 int first = trig.getFirstTrack(),
last =
first + trig.getNumberOfTracks();
2742 mTPCTRDTriggers.push_back(
count);
2752 for (
const auto& rof : rofs) {
2755 mMCHROFs.push_back(
count);
2762AODProducerWorkflowDPL::TrackExtraInfo AODProducerWorkflowDPL::processBarrelTrack(
int collisionID, std::uint64_t collisionBC,
GIndex trackIndex,
2765 TrackExtraInfo extraInfoHolder;
2766 if (collisionID < 0) {
2769 bool needBCSlice = collisionID < 0;
2770 uint64_t bcOfTimeRef = collisionBC - mStartIR.
toLong();
2772 auto setTrackTime = [&](
double t,
double terr,
bool gaussian) {
2778 extraInfoHolder.trackTimeRes = terr;
2780 double error = this->mTimeMarginTrackTime + (gaussian ? extraInfoHolder.trackTimeRes * this->mNSigmaTimeTrack : extraInfoHolder.trackTimeRes);
2781 bcOfTimeRef = fillBCSlice(extraInfoHolder.bcSlice, t - error, t + error, bcsMap);
2783 extraInfoHolder.trackTime = float(t - bcOfTimeRef * o2::constants::lhc::LHCBunchSpacingNS);
2784 extraInfoHolder.diffBCRef =
int(bcOfTimeRef);
2785 LOGP(
debug,
"time : {}/{} -> {}/{} -> trunc: {}/{} CollID: {} Amb: {}", t, terr, t - bcOfTimeRef * o2::constants::lhc::LHCBunchSpacingNS, terr,
2786 truncateFloatFraction(extraInfoHolder.trackTime, mTrackTime), truncateFloatFraction(extraInfoHolder.trackTimeRes, mTrackTimeError),
2789 auto contributorsGID =
data.getSingleDetectorRefs(trackIndex);
2790 const auto& trackPar =
data.getTrackParam(trackIndex);
2791 extraInfoHolder.flags |= trackPar.getPID() << 28;
2792 auto src = trackIndex.getSource();
2794 const auto& tofMatch =
data.getTOFMatch(trackIndex);
2795 extraInfoHolder.tofChi2 = tofMatch.getChi2();
2796 const auto& tofInt = tofMatch.getLTIntegralOut();
2797 float intLen = tofInt.getL();
2798 extraInfoHolder.length = intLen;
2799 const float mass = o2::constants::physics::MassPionCharged;
2800 if (tofInt.getTOF(o2::track::PID::Pion) > 0.f) {
2801 float expBeta = (intLen / (tofInt.getTOF(o2::track::PID::Pion) * cSpeed));
2802 if (expBeta > o2::constants::math::Almost1) {
2803 expBeta = o2::constants::math::Almost1;
2805 extraInfoHolder.tofExpMom = mass * expBeta / std::sqrt(1.f - expBeta * expBeta);
2808 const double massZ = o2::track::PID::getMass2Z(trackPar.getPID());
2809 const double energy = sqrt((massZ * massZ) + (extraInfoHolder.tofExpMom * extraInfoHolder.tofExpMom));
2810 const double exp = extraInfoHolder.length * energy / (cSpeed * extraInfoHolder.tofExpMom);
2811 auto tofSignal = (tofMatch.getSignal() -
exp) * 1e-3;
2812 setTrackTime(tofSignal, 0.2,
true);
2816 extraInfoHolder.trdChi2 = trdOrig.getChi2();
2817 extraInfoHolder.trdSignal = trdOrig.getSignal();
2818 extraInfoHolder.trdPattern = getTRDPattern(trdOrig);
2819 if (extraInfoHolder.trackTimeRes < 0.) {
2821 const auto& trdTrig = (
src ==
GIndex::Source::TPCTRD) ?
data.getTPCTRDTriggers()[mTPCTRDTriggers[trackIndex.getIndex()]] :
data.getITSTPCTRDTriggers()[mITSTPCTRDTriggers[trackIndex.getIndex()]];
2822 double ttrig = trdTrig.getBCData().differenceInBC(mStartIR) * o2::constants::lhc::LHCBunchSpacingNS;
2823 setTrackTime(ttrig, 1.,
true);
2827 const auto& itsTrack =
data.getITSTrack(contributorsGID[
GIndex::ITS]);
2828 int nClusters = itsTrack.getNClusters();
2829 float chi2 = itsTrack.getChi2();
2831 extraInfoHolder.itsClusterSizes = itsTrack.getClusterSizes();
2833 const auto& rof =
data.getITSTracksROFRecords()[mITSROFs[trackIndex.getIndex()]];
2834 double t = rof.getBCData().differenceInBC(mStartIR) * o2::constants::lhc::LHCBunchSpacingNS + mITSROFrameHalfLengthNS + mITSROFBiasNS;
2835 setTrackTime(t, mITSROFrameHalfLengthNS,
false);
2838 extraInfoHolder.itsClusterSizes =
data.getITSABRefs()[contributorsGID[
GIndex::Source::ITSAB].getIndex()].getClusterSizes();
2842 const auto& tpcClData = mTPCCounters[contributorsGID[
GIndex::TPC]];
2843 const auto& dEdx = tpcOrig.getdEdx().dEdxTotTPC > 0 ? tpcOrig.getdEdx() : tpcOrig.getdEdxAlt();
2844 if (tpcOrig.getdEdx().dEdxTotTPC == 0) {
2847 if (tpcOrig.hasASideClusters()) {
2850 if (tpcOrig.hasCSideClusters()) {
2853 extraInfoHolder.tpcInnerParam = tpcOrig.getP() / tpcOrig.getAbsCharge();
2854 extraInfoHolder.tpcChi2NCl = tpcOrig.getNClusters() ? tpcOrig.getChi2() / tpcOrig.getNClusters() : 0;
2855 extraInfoHolder.tpcSignal = dEdx.dEdxTotTPC;
2856 extraInfoHolder.tpcNClsFindable = tpcOrig.getNClusters();
2857 extraInfoHolder.tpcNClsFindableMinusFound = tpcOrig.getNClusters() - tpcClData.found;
2858 extraInfoHolder.tpcNClsFindableMinusCrossedRows = tpcOrig.getNClusters() - tpcClData.crossed;
2859 extraInfoHolder.tpcNClsShared = tpcClData.shared;
2860 uint32_t clsUsedForPID = dEdx.NHitsIROC + dEdx.NHitsOROC1 + dEdx.NHitsOROC2 + dEdx.NHitsOROC3;
2861 extraInfoHolder.tpcNClsFindableMinusPID = tpcOrig.getNClusters() - clsUsedForPID;
2864 double t = (tpcOrig.getTime0() + 0.5 * (tpcOrig.getDeltaTFwd() - tpcOrig.getDeltaTBwd())) * mTPCBinNS;
2865 double terr = 0.5 * (tpcOrig.getDeltaTFwd() + tpcOrig.getDeltaTBwd()) * mTPCBinNS;
2866 double err = mTimeMarginTrackTime + terr;
2867 bcOfTimeRef = fillBCSlice(extraInfoHolder.bcSlice, t - err, t + err, bcsMap);
2870 p.setDeltaTFwd(tpcOrig.getDeltaTFwd());
2871 p.setDeltaTBwd(tpcOrig.getDeltaTBwd());
2872 extraInfoHolder.trackTimeRes =
p.getTimeErr();
2873 extraInfoHolder.trackTime = float(tpcOrig.getTime0() * mTPCBinNS - bcOfTimeRef * o2::constants::lhc::LHCBunchSpacingNS);
2874 extraInfoHolder.diffBCRef =
int(bcOfTimeRef);
2875 extraInfoHolder.isTPConly =
true;
2878 const auto& trITSTPC =
data.getTPCITSTrack(trackIndex);
2879 auto ts = trITSTPC.getTimeMUS();
2880 setTrackTime(ts.getTimeStamp() * 1.e3, ts.getTimeStampError() * 1.e3,
true);
2884 extrapolateToCalorimeters(extraInfoHolder,
data.getTrackParamOut(trackIndex));
2889 return extraInfoHolder;
2892AODProducerWorkflowDPL::TrackQA AODProducerWorkflowDPL::processBarrelTrackQA(
int collisionID, std::uint64_t collisionBC,
GIndex trackIndex,
2896 auto contributorsGID =
data.getTPCContributorGID(trackIndex);
2897 const auto& trackPar =
data.getTrackParam(trackIndex);
2898 if (contributorsGID.isIndexSet()) {
2900 const auto& tpcOrig =
data.getTPCTrack(contributorsGID);
2905 std::array<float, 2> dcaInfo{-999., -999.};
2906 if (prop->propagateToDCABxByBz({v.getX(), v.getY(), v.getZ()}, tpcTMP, 2.f, mMatType, &dcaInfo)) {
2907 trackQAHolder.tpcdcaR = 100. * dcaInfo[0] / sqrt(1. + trackPar.getQ2Pt() * trackPar.getQ2Pt());
2908 trackQAHolder.tpcdcaZ = 100. * dcaInfo[1] / sqrt(1. + trackPar.getQ2Pt() * trackPar.getQ2Pt());
2912 auto safeInt8Clamp = [](
auto value) -> int8_t {
2913 using ValType =
decltype(
value);
2914 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()))));
2916 auto safeUInt8Clamp = [](
auto value) -> uint8_t {
2917 using ValType =
decltype(
value);
2918 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()))));
2922 uint8_t clusterCounters[8] = {0};
2924 uint8_t sectorIndex, rowIndex;
2925 uint32_t clusterIndex;
2926 const auto& tpcClusRefs =
data.getTPCTracksClusterRefs();
2927 for (
int i = 0;
i < tpcOrig.getNClusterReferences();
i++) {
2928 o2::tpc::TrackTPC::getClusterReference(tpcClusRefs,
i, sectorIndex, rowIndex, clusterIndex, tpcOrig.getClusterRef());
2929 char indexTracklet = (rowIndex % 152) / 19;
2930 clusterCounters[indexTracklet]++;
2934 for (
int i = 0;
i < 8;
i++) {
2935 if (clusterCounters[
i] > 5) {
2936 byteMask |= (1 <<
i);
2939 trackQAHolder.tpcTime0 = tpcOrig.getTime0();
2940 trackQAHolder.tpcClusterByteMask = byteMask;
2941 const auto& dEdxInfoAlt = tpcOrig.getdEdxAlt();
2942 const float dEdxNorm = (dEdxInfoAlt.dEdxTotTPC > 0) ? 100. / dEdxInfoAlt.dEdxTotTPC : 0;
2943 trackQAHolder.tpcdEdxNorm = dEdxInfoAlt.dEdxTotTPC;
2944 trackQAHolder.tpcdEdxMax0R = safeUInt8Clamp(dEdxInfoAlt.dEdxMaxIROC * dEdxNorm);
2945 trackQAHolder.tpcdEdxMax1R = safeUInt8Clamp(dEdxInfoAlt.dEdxMaxOROC1 * dEdxNorm);
2946 trackQAHolder.tpcdEdxMax2R = safeUInt8Clamp(dEdxInfoAlt.dEdxMaxOROC2 * dEdxNorm);
2947 trackQAHolder.tpcdEdxMax3R = safeUInt8Clamp(dEdxInfoAlt.dEdxMaxOROC3 * dEdxNorm);
2949 trackQAHolder.tpcdEdxTot0R = safeUInt8Clamp(dEdxInfoAlt.dEdxTotIROC * dEdxNorm);
2950 trackQAHolder.tpcdEdxTot1R = safeUInt8Clamp(dEdxInfoAlt.dEdxTotOROC1 * dEdxNorm);
2951 trackQAHolder.tpcdEdxTot2R = safeUInt8Clamp(dEdxInfoAlt.dEdxTotOROC2 * dEdxNorm);
2952 trackQAHolder.tpcdEdxTot3R = safeUInt8Clamp(dEdxInfoAlt.dEdxTotOROC3 * dEdxNorm);
2955 auto contributorsGIDA =
data.getSingleDetectorRefs(trackIndex);
2957 const auto& tofMatch =
data.getTOFMatch(trackIndex);
2958 const float qpt = trackPar.getQ2Pt();
2960 trackQAHolder.dTofdX = safeInt8Clamp(tofMatch.getDXatTOF() / scaleTOF);
2961 trackQAHolder.dTofdZ = safeInt8Clamp(tofMatch.getDZatTOF() / scaleTOF);
2967 if (
auto itsContGID =
data.getITSContributorGID(trackIndex); itsContGID.isIndexSet() && itsContGID.getSource() !=
GIndex::ITSAB) {
2968 const auto& itsOrig =
data.getITSTrack(itsContGID);
2972 if (prop->propagateToX(gloCopy,
o2::aod::track::trackQARefRadius, prop->getNominalBz(), o2::base::Propagator::MAX_SIN_PHI, o2::base::Propagator::MAX_STEP, mMatCorr) &&
2973 prop->propagateToAlphaX(tpcCopy, gloCopy.getAlpha(),
o2::aod::track::trackQARefRadius,
false, o2::base::Propagator::MAX_SIN_PHI, o2::base::Propagator::MAX_STEP, 1, mMatCorr) &&
2974 prop->propagateToAlphaX(itsCopy, gloCopy.getAlpha(),
o2::aod::track::trackQARefRadius,
false, o2::base::Propagator::MAX_SIN_PHI, o2::base::Propagator::MAX_STEP, 1, mMatCorr)) {
2977 const float beta0 = std::sqrt(std::min(50.f / tpcOrig.getdEdx().dEdxMaxTPC, 1.f));
2978 const float qpt = gloCopy.getQ2Pt();
2979 const float x = qpt / beta0;
2981 auto scaleCont = [&
x](
int i) ->
float {
2984 auto scaleGlo = [&
x](
int i) ->
float {
2989 trackQAHolder.dRefContY = safeInt8Clamp((itsCopy.getY() - tpcCopy.getY()) * scaleCont(0));
2990 trackQAHolder.dRefContZ = safeInt8Clamp((itsCopy.getZ() - tpcCopy.getZ()) * scaleCont(1));
2991 trackQAHolder.dRefContSnp = safeInt8Clamp((itsCopy.getSnp() - tpcCopy.getSnp()) * scaleCont(2));
2992 trackQAHolder.dRefContTgl = safeInt8Clamp((itsCopy.getTgl() - tpcCopy.getTgl()) * scaleCont(3));
2993 trackQAHolder.dRefContQ2Pt = safeInt8Clamp((itsCopy.getQ2Pt() - tpcCopy.getQ2Pt()) * scaleCont(4));
2995 trackQAHolder.dRefGloY = safeInt8Clamp(((itsCopy.getY() + tpcCopy.getY()) * 0.5f - gloCopy.getY()) * scaleGlo(0));
2996 trackQAHolder.dRefGloZ = safeInt8Clamp(((itsCopy.getZ() + tpcCopy.getZ()) * 0.5f - gloCopy.getZ()) * scaleGlo(1));
2997 trackQAHolder.dRefGloSnp = safeInt8Clamp(((itsCopy.getSnp() + tpcCopy.getSnp()) * 0.5f - gloCopy.getSnp()) * scaleGlo(2));
2998 trackQAHolder.dRefGloTgl = safeInt8Clamp(((itsCopy.getTgl() + tpcCopy.getTgl()) * 0.5f - gloCopy.getTgl()) * scaleGlo(3));
2999 trackQAHolder.dRefGloQ2Pt = safeInt8Clamp(((itsCopy.getQ2Pt() + tpcCopy.getQ2Pt()) * 0.5f - gloCopy.getQ2Pt()) * scaleGlo(4));
3003 (*mStreamer) <<
"trackQA"
3004 <<
"trackITSOrig=" << itsOrig
3005 <<
"trackTPCOrig=" << tpcOrig
3006 <<
"trackITSTPCOrig=" << trackPar
3007 <<
"trackITSProp=" << itsCopy
3008 <<
"trackTPCProp=" << tpcCopy
3009 <<
"trackITSTPCProp=" << gloCopy
3012 <<
"scaleCont0=" << scaleCont(0)
3013 <<
"scaleCont1=" << scaleCont(1)
3014 <<
"scaleCont2=" << scaleCont(2)
3015 <<
"scaleCont3=" << scaleCont(3)
3016 <<
"scaleCont4=" << scaleCont(4)
3017 <<
"scaleGlo0=" << scaleGlo(0)
3018 <<
"scaleGlo1=" << scaleGlo(1)
3019 <<
"scaleGlo2=" << scaleGlo(2)
3020 <<
"scaleGlo3=" << scaleGlo(3)
3021 <<
"scaleGlo4=" << scaleGlo(4)
3022 <<
"trackQAHolder.tpcTime0=" << trackQAHolder.tpcTime0
3023 <<
"trackQAHolder.tpcdEdxNorm=" << trackQAHolder.tpcdEdxNorm
3024 <<
"trackQAHolder.tpcdcaR=" << trackQAHolder.tpcdcaR
3025 <<
"trackQAHolder.tpcdcaZ=" << trackQAHolder.tpcdcaZ
3026 <<
"trackQAHolder.tpcdcaClusterByteMask=" << trackQAHolder.tpcClusterByteMask
3027 <<
"trackQAHolder.tpcdEdxMax0R=" << trackQAHolder.tpcdEdxMax0R
3028 <<
"trackQAHolder.tpcdEdxMax1R=" << trackQAHolder.tpcdEdxMax1R
3029 <<
"trackQAHolder.tpcdEdxMax2R=" << trackQAHolder.tpcdEdxMax2R
3030 <<
"trackQAHolder.tpcdEdxMax3R=" << trackQAHolder.tpcdEdxMax3R
3031 <<
"trackQAHolder.tpcdEdxTot0R=" << trackQAHolder.tpcdEdxTot0R
3032 <<
"trackQAHolder.tpcdEdxTot1R=" << trackQAHolder.tpcdEdxTot1R
3033 <<
"trackQAHolder.tpcdEdxTot2R=" << trackQAHolder.tpcdEdxTot2R
3034 <<
"trackQAHolder.tpcdEdxTot3R=" << trackQAHolder.tpcdEdxTot3R
3035 <<
"trackQAHolder.dRefContY=" << trackQAHolder.dRefContY
3036 <<
"trackQAHolder.dRefContZ=" << trackQAHolder.dRefContZ
3037 <<
"trackQAHolder.dRefContSnp=" << trackQAHolder.dRefContSnp
3038 <<
"trackQAHolder.dRefContTgl=" << trackQAHolder.dRefContTgl
3039 <<
"trackQAHolder.dRefContQ2Pt=" << trackQAHolder.dRefContQ2Pt
3040 <<
"trackQAHolder.dRefGloY=" << trackQAHolder.dRefGloY
3041 <<
"trackQAHolder.dRefGloZ=" << trackQAHolder.dRefGloZ
3042 <<
"trackQAHolder.dRefGloSnp=" << trackQAHolder.dRefGloSnp
3043 <<
"trackQAHolder.dRefGloTgl=" << trackQAHolder.dRefGloTgl
3044 <<
"trackQAHolder.dRefGloQ2Pt=" << trackQAHolder.dRefGloQ2Pt
3045 <<
"trackQAHolder.dTofdX=" << trackQAHolder.dTofdX
3046 <<
"trackQAHolder.dTofdZ=" << trackQAHolder.dTofdZ
3047 <<
"scaleTOF=" << scaleTOF
3054 return trackQAHolder;
3062 dcaInfo.set(999.f, 999.f, 999.f, 999.f, 999.f);
3067void AODProducerWorkflowDPL::extrapolateToCalorimeters(TrackExtraInfo& extraInfoHolder,
const o2::track::TrackPar& track)
3069 constexpr float XEMCAL = 440.f, XPHOS = 460.f, XEMCAL2 = XEMCAL * XEMCAL;
3070 constexpr float ETAEMCAL = 0.75;
3071 constexpr float ZEMCALFastCheck = 460.;
3072 constexpr float ETADCALINNER = 0.22;
3073 constexpr float ETAPHOS = 0.13653194;
3074 constexpr float ETAPHOSMARGIN = 0.17946979;
3075 constexpr float ETADCALPHOSSWITCH = (ETADCALINNER + ETAPHOS) / 2;
3076 constexpr short SNONE = 0, SEMCAL = 0x1, SPHOS = 0x2;
3077 constexpr short SECTORTYPE[18] = {
3078 SNONE, SNONE, SNONE, SNONE,
3079 SEMCAL, SEMCAL, SEMCAL, SEMCAL, SEMCAL, SEMCAL,
3082 SPHOS | SEMCAL, SPHOS | SEMCAL, SPHOS | SEMCAL,
3093 (std::abs(outTr.getZAt(xtrg, 0)) > ZEMCALFastCheck) ||
3094 !prop->PropagateToXBxByBz(outTr, xtrg, 0.95, 10, o2::base::Propagator::MatCorrType::USEMatCorrLUT)) {
3095 LOGP(
debug,
"preliminary step: does not reach R={} {}", XEMCAL, outTr.asString());
3099 if ((outTr.getX() * outTr.getX() + outTr.getY() * outTr.getY() < XEMCAL2) &&
3100 (!outTr.rotateParam(outTr.getPhi()) ||
3102 !prop->PropagateToXBxByBz(outTr, xtrg, 0.95, 10, o2::base::Propagator::MatCorrType::USEMatCorrLUT))) {
3103 LOGP(
debug,
"does not reach R={} {}", XEMCAL, outTr.asString());
3109 auto propExactSector = [&outTr, §or, prop](
float xprop) ->
bool {
3112 auto outTrTmp = outTr;
3114 if ((std::abs(outTr.getZ()) > ZEMCALFastCheck) || !outTrTmp.rotateParam(
alpha) ||
3115 !prop->PropagateToXBxByBz(outTrTmp, xprop, 0.95, 10, o2::base::Propagator::MatCorrType::USEMatCorrLUT)) {
3116 LOGP(
debug,
"failed on rotation to {} (sector {}) or propagation to X={} {}",
alpha, sector, xprop, outTrTmp.asString());
3121 if (sectorTmp == sector) {
3129 LOGP(
debug,
"failed to rotate to sector, {}", outTr.asString());
3136 if (!propExactSector(XEMCAL) || SECTORTYPE[sector] == SNONE) {
3141 float r = std::sqrt(outTr.getX() * outTr.getX() + outTr.getY() * outTr.getY()), tg = std::atan2(
r, outTr.getZ());
3142 float eta = -std::log(std::tan(0.5f * tg)), etaAbs = std::abs(eta);
3143 if (etaAbs > ETAEMCAL) {
3144 LOGP(
debug,
"eta = {} is off at EMCAL radius", eta, outTr.asString());
3148 if ((SECTORTYPE[sector] & SPHOS) && etaAbs < ETADCALPHOSSWITCH) {
3149 if (!propExactSector(XPHOS)) {
3152 r = std::sqrt(outTr.getX() * outTr.getX() + outTr.getY() * outTr.getY());
3153 tg = std::atan2(
r, outTr.getZ());
3154 eta = -std::log(std::tan(0.5f * tg));
3155 }
else if (!(SECTORTYPE[sector] & SEMCAL)) {
3158 extraInfoHolder.trackPhiEMCAL = outTr.getPhiPos();
3159 extraInfoHolder.trackEtaEMCAL = eta;
3160 LOGP(
debug,
"eta = {} phi = {} sector {} for {}", extraInfoHolder.trackEtaEMCAL, extraInfoHolder.trackPhiEMCAL, sector, outTr.asString());
3164std::set<uint64_t> AODProducerWorkflowDPL::filterEMCALIncomplete(
const gsl::span<const o2::emcal::TriggerRecord> triggers)
3166 std::set<uint64_t> emcalIncompletes;
3167 for (
const auto& trg : triggers) {
3168 if (trg.getTriggerBits() & o2::emcal::triggerbits::Inc) {
3170 emcalIncompletes.insert(trg.getBCData().toLong());
3173 return emcalIncompletes;
3179 static bool initOnceDone =
false;
3180 if (!initOnceDone) {
3181 initOnceDone =
true;
3188 for (
auto i = 0U;
i < bs.size();
i++) {
3195 mITSROFrameHalfLengthNS = 0.5 * (grpECS->isDetContinuousReadOut(o2::detectors::DetID::ITS) ? alpParamsITS.roFrameLengthInBC * o2::constants::lhc::LHCBunchSpacingNS : alpParamsITS.roFrameLengthTrig);
3198 mMFTROFrameHalfLengthNS = 0.5 * (grpECS->isDetContinuousReadOut(o2::detectors::DetID::MFT) ? alpParamsMFT.roFrameLengthInBC * o2::constants::lhc::LHCBunchSpacingNS : alpParamsMFT.roFrameLengthTrig);
3203 mTPCBinNS = elParam.ZbinWidth * 1.e3;
3206 mNSigmaTimeTrack = pvParams.nSigmaTimeTrack;
3207 mTimeMarginTrackTime = pvParams.timeMarginTrackTime * 1.e3;
3211 if (mEnableTRDextra) {
3233 LOG(info) <<
"ITS Alpide param updated";
3235 par.printKeyValues();
3239 LOG(info) <<
"MFT Alpide param updated";
3241 par.printKeyValues();
3252 mEMCALTrgClassMask = 0;
3253 for (
const auto& trgclass : ctpconfig.getCTPClasses()) {
3254 if (trgclass.cluster->maskCluster[o2::detectors::DetID::EMC]) {
3255 mEMCALTrgClassMask |= trgclass.classMask;
3258 LOG(info) <<
"Loaded EMCAL trigger class mask: " << std::bitset<64>(mEMCALTrgClassMask);
3262void AODProducerWorkflowDPL::addRefGlobalBCsForTOF(
const o2::dataformats::VtxTrackRef& trackRef,
const gsl::span<const GIndex>& GIndices,
3273 int nbitsFrac = 24 - (32 - o2::math_utils::popcount(mTrackTime));
3274 int nbitsLoss = std::max(0,
int(std::log2(TOFTimePrecPS)));
3275 assert(nbitsFrac > 1);
3276 std::uint64_t maxRangePS = std::uint64_t(0x1) << (nbitsFrac + nbitsLoss);
3277 int maxGapBC = maxRangePS / (o2::constants::lhc::LHCBunchSpacingNS * 1e3);
3278 LOG(info) <<
"Max gap of " << maxGapBC <<
" BCs to closest globalBC reference is needed for TOF tracks to provide precision of "
3279 << TOFTimePrecPS <<
" ps";
3282 if (!trackRef.getEntries()) {
3286 std::uint64_t maxBC = mStartIR.
toLong();
3287 const auto& tofClus =
data.getTOFClusters();
3289 if (!GIndex::getSourceDetectorsMask(
src)[o2::detectors::DetID::TOF]) {
3294 for (
int ti =
start; ti <
end; ti++) {
3295 auto& trackIndex = GIndices[ti];
3296 const auto& tofMatch =
data.getTOFMatch(trackIndex);
3297 const auto& tofInt = tofMatch.getLTIntegralOut();
3298 float intLen = tofInt.getL();
3299 float tofExpMom = 0.;
3300 if (tofInt.getTOF(o2::track::PID::Pion) > 0.f) {
3301 float expBeta = (intLen / (tofInt.getTOF(o2::track::PID::Pion) * cSpeed));
3302 if (expBeta > o2::constants::math::Almost1) {
3303 expBeta = o2::constants::math::Almost1;
3305 tofExpMom = o2::constants::physics::MassPionCharged * expBeta / std::sqrt(1.f - expBeta * expBeta);
3309 double massZ = o2::track::PID::getMass2Z(
data.getTrackParam(trackIndex).getPID());
3310 double energy = sqrt((massZ * massZ) + (tofExpMom * tofExpMom));
3311 double exp = intLen * energy / (cSpeed * tofExpMom);
3312 auto tofSignal = (tofMatch.getSignal() -
exp) * 1e-3;
3313 auto bc = relativeTime_to_GlobalBC(tofSignal);
3315 auto it = bcsMap.lower_bound(
bc);
3316 if (it == bcsMap.end() || it->first >
bc + maxGapBC) {
3317 bcsMap.emplace_hint(it,
bc, 1);
3326 if ((--bcsMap.end())->first <= maxBC) {
3327 bcsMap.emplace_hint(bcsMap.end(), maxBC + 1, 1);
3331 for (
auto& item : bcsMap) {
3337std::uint64_t AODProducerWorkflowDPL::fillBCSlice(
int (&slice)[2],
double tmin,
double tmax,
const std::map<uint64_t, int>& bcsMap)
const
3349 uint64_t bcMin = relativeTime_to_GlobalBC(tmin), bcMax = relativeTime_to_GlobalBC(tmax);
3375 if (
p.first >= bcvector.size()) {
3376 p.first = bcvector.size() - 1;
3377 p.second = bcvector[
p.first];
3379 auto upperindex =
p.first;
3380 while (upperindex < bcvector.size() && bcvector[upperindex] <= bcMax) {
3383 if (upperindex !=
p.first) {
3387 slice[1] = upperindex;
3389 auto bcOfTimeRef =
p.second - this->mStartIR.
toLong();
3390 LOG(
debug) <<
"BC slice t:" << tmin <<
" " << slice[0]
3391 <<
" t: " << tmax <<
" " << slice[1]
3392 <<
" bcref: " << bcOfTimeRef;
3398 std::vector<uint8_t>
flags(bcsMap.size());
3401 auto bcIt = bcsMap.begin();
3402 auto itsrofs =
data.getITSTracksROFRecords();
3405 for (
auto& rof : itsrofs) {
3406 if (!rof.getFlag(o2::itsmft::ROFRecord::VtxUPCMode)) {
3409 uint64_t globalBC0 = rof.getBCData().toLong() + bROF, globalBC1 = globalBC0 + lROF - 1;
3411 while (bcIt != bcsMap.end()) {
3412 if (bcIt->first < globalBC0) {
3416 if (bcIt->first > globalBC1) {
3426bool AODProducerWorkflowDPL::collectConfigFiles(std::vector<TString>&
keys, std::vector<TString>&
values,
int indent)
3429 static std::string
pattern, directory;
3430 static size_t cachedNumberOfFiles = 0, cachedTotalFileSize = 0;
3431 static bool first =
true, discard =
false;
3440 if (dir ==
"/dev/null") {
3441 LOGP(warn,
"ConfigParams output is disabled, abandoning {} files collection for metadata",
pattern);
3445 directory = (dir.empty() || dir ==
"none") ?
"." : dir;
3446 if (!std::filesystem::is_directory(directory, ec)) {
3447 LOGP(error, R
"(No directory "{}" is found to look for {} configuration files)", directory, pattern);
3452 static std::unordered_map<std::string, std::string> cachedMap;
3453 std::vector<std::filesystem::path> files;
3454 size_t currentTotalFileSize = 0;
3456 for (
const auto&
entry :
std::filesystem::directory_iterator(directory)) {
3457 if (!
entry.is_regular_file()) {
3460 const std::string fileName =
entry.path().filename().string();
3461 if (fnmatch(
pattern.c_str(), fileName.c_str(), 0) != 0) {
3464 const auto fileSize =
entry.file_size(ec);
3466 LOGP(error,
"Cannot determine size of file {}, reason: {}",
entry.path().string(), ec.message());
3468 files.push_back(
entry.path());
3469 currentTotalFileSize +=
static_cast<size_t>(fileSize);
3472 if (files.size() != cachedNumberOfFiles || currentTotalFileSize != cachedTotalFileSize) {
3473 cachedNumberOfFiles = files.size();
3474 cachedTotalFileSize = currentTotalFileSize;
3478 if (!files.empty() && cachedMap.empty()) {
3479 for (
const auto& fname : files) {
3480 std::ifstream input(fname);
3482 LOGP(error,
"Cannot open JSON file {}", fname.string());
3483 cachedTotalFileSize = 0;
3486 nlohmann::json document;
3489 }
catch (
const nlohmann::json::parse_error& e) {
3490 LOGP(error,
"Cannot parse JSON file {}, reason: {}", fname.string(), e.what());
3491 cachedTotalFileSize = 0;
3495 if (!document.is_object()) {
3496 LOGP(error,
"Top-level JSON value is not an object in file: {}", fname.string());
3497 cachedTotalFileSize = 0;
3501 for (
auto it = document.begin(); it != document.end(); ++it) {
3502 const std::string&
key = it.key();
3503 if (cachedMap.find(
key) != cachedMap.end()) {
3504 LOGP(error,
"Duplicate top-level key {} in file {}",
key, fname.string());
3507 LOGP(info,
"Adding json config {} from file {} to AOD metadata",
key, fname.string());
3508 nlohmann::json valueDocument = nlohmann::json::object();
3509 valueDocument[
key] = it.value();
3510 cachedMap[
key] = valueDocument.dump(indent);
3515 for (
const auto& kv : cachedMap) {
3516 keys.push_back(kv.first.c_str());
3517 values.push_back(kv.second.c_str());
3524 LOGF(info,
"aod producer dpl total timing: Cpu: %.3e Real: %.3e s in %d slots",
3525 mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1);
3532 auto dataRequest = std::make_shared<DataRequest>();
3533 dataRequest->inputs.emplace_back(
"ctpconfig",
"CTP",
"CTPCONFIG", 0, Lifetime::Condition,
ccdbParamSpec(
"CTP/Config/Config", CTPConfigPerRun));
3535 dataRequest->requestTracks(
src, useMC);
3536 dataRequest->requestPrimaryVertices(useMC);
3538 dataRequest->requestCTPDigits(useMC);
3541 dataRequest->requestSecondaryVertices(useMC);
3543 if (enableStrangenessTracking) {
3544 dataRequest->requestStrangeTracks(useMC);
3545 LOGF(info,
"requestStrangeTracks Finish");
3554 dataRequest->requestTOFClusters(useMC);
3557 dataRequest->requestPHOSCells(useMC);
3560 dataRequest->requestTRDTracklets(
false);
3563 dataRequest->requestEMCALCells(useMC);
3566 dataRequest->requestCPVClusters(useMC);
3569 auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(
true,
3575 dataRequest->inputs,
3578 dataRequest->inputs.emplace_back(
"meanvtx",
"GLO",
"MEANVERTEX", 0, Lifetime::Condition,
ccdbParamSpec(
"GLO/Calib/MeanVertex", {}, 1));
3583 std::vector<OutputSpec> outputs{
3622 if (enableTRDextra) {
3624 dataRequest->inputs.emplace_back(
"trdlocalgainfactors",
"TRD",
"LOCALGAINFACTORS", 0, Lifetime::Condition,
ccdbParamSpec(
"TRD/Calib/LocalGainFactor"));
3625 dataRequest->inputs.emplace_back(
"trdnoisemap",
"TRD",
"NOISEMAP", 0, Lifetime::Condition,
ccdbParamSpec(
"TRD/Calib/NoiseMapMCM"));
3626 dataRequest->inputs.emplace_back(
"trdgaincalib",
"TRD",
"CALGAIN", 0, Lifetime::Condition,
ccdbParamSpec(
"TRD/Calib/CalGain"));
3630 outputs.insert(outputs.end(),
3631 {OutputForTable<McCollisions>::spec(),
3632 OutputForTable<HepMCXSections>::spec(),
3633 OutputForTable<HepMCPdfInfos>::spec(),
3634 OutputForTable<HepMCHeavyIons>::spec(),
3635 OutputForTable<McMFTTrackLabels>::spec(),
3636 OutputForTable<McFwdTrackLabels>::spec(),
3637 OutputForTable<StoredMcParticles_001>::spec(),
3638 OutputForTable<McTrackLabels>::spec(),
3639 OutputForTable<McCaloLabels_001>::spec(),
3644 {OutputLabel{
"McCollisionLabels"},
"AOD",
"MCCOLLISIONLABEL", 0, Lifetime::Timeframe}});
3648 "aod-producer-workflow",
3651 AlgorithmSpec{adaptFromTask<AODProducerWorkflowDPL>(
src, dataRequest, ggRequest, enableSV, useMC, enableFITextra, enableTRDextra)},
3653 ConfigParamSpec{
"run-number", VariantType::Int64, -1L, {
"The run-number. If left default we try to get it from DPL header."}},
3654 ConfigParamSpec{
"aod-timeframe-id", VariantType::Int64, -1L, {
"Set timeframe number"}},
3655 ConfigParamSpec{
"fill-calo-cells", VariantType::Int, 1, {
"Fill calo cells into cell table"}},
3656 ConfigParamSpec{
"enable-truncation", VariantType::Int, 1, {
"Truncation parameter: 1 -- on, != 1 -- off"}},
3657 ConfigParamSpec{
"lpmp-prod-tag", VariantType::String,
"", {
"LPMProductionTag"}},
3658 ConfigParamSpec{
"anchor-pass", VariantType::String,
"", {
"AnchorPassName"}},
3659 ConfigParamSpec{
"anchor-prod", VariantType::String,
"", {
"AnchorProduction"}},
3660 ConfigParamSpec{
"reco-pass", VariantType::String,
"", {
"RecoPassName"}},
3661 ConfigParamSpec{
"aod-parent", VariantType::String,
"", {
"Parent AOD file name (if any)"}},
3662 ConfigParamSpec{
"created-by", VariantType::String,
"", {
"Who created this AO2D"}},
3663 ConfigParamSpec{
"nthreads", VariantType::Int, std::max(1,
int(std::thread::hardware_concurrency() / 2)), {
"Number of threads"}},
3664 ConfigParamSpec{
"reco-mctracks-only", VariantType::Int, 0, {
"Store only reconstructed MC tracks and their mothers/daughters. 0 -- off, != 0 -- on"}},
3665 ConfigParamSpec{
"ctpreadout-create", VariantType::Int, 0, {
"Create CTP digits from detector readout and CTP inputs. !=1 -- off, 1 -- on"}},
3666 ConfigParamSpec{
"emc-select-leading", VariantType::Bool,
false, {
"Flag to select if only the leading contributing particle for an EMCal cell should be stored"}},
3667 ConfigParamSpec{
"propagate-tracks", VariantType::Bool,
false, {
"Propagate tracks (not used for secondary vertices) to IP"}},
3668 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)"}},
3669 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)"}},
3670 ConfigParamSpec{
"propagate-muons", VariantType::Bool,
false, {
"Propagate muons to IP"}},
3671 ConfigParamSpec{
"store-all-mft-cov", VariantType::Bool,
false, {
"Store covariance matrices for all MFT tracks"}},
3672 ConfigParamSpec{
"thin-tracks", VariantType::Bool,
false, {
"Produce thinned track tables"}},
3673 ConfigParamSpec{
"trackqc-keepglobaltracks", VariantType::Bool,
false, {
"Always keep TrackQA for global tracks"}},
3674 ConfigParamSpec{
"trackqc-retainonlydedx", VariantType::Bool,
false, {
"Keep only dEdx information, zero out everything else"}},
3675 ConfigParamSpec{
"trackqc-fraction", VariantType::Float, float(0.1), {
"Fraction of tracks to QC"}},
3676 ConfigParamSpec{
"trackqc-NTrCut", VariantType::Int64, 4L, {
"Minimal length of the track - in amount of tracklets"}},
3677 ConfigParamSpec{
"trackqc-tpc-dca", VariantType::Float, 3.f, {
"Keep TPC standalone track with this DCAxy to the PV"}},
3678 ConfigParamSpec{
"trackqc-tpc-cls", VariantType::Int, 80, {
"Keep TPC standalone track with this #clusters"}},
3679 ConfigParamSpec{
"trackqc-tpc-pt", VariantType::Float, 0.2f, {
"Keep TPC standalone track with this pt"}},
3680 ConfigParamSpec{
"with-streamers", VariantType::String,
"", {
"Bit-mask to steer writing of intermediate streamer files"}},
3681 ConfigParamSpec{
"seed", VariantType::Int, 0, {
"Set seed for random generator used for sampling (0 (default) means using a random_device)"}},
3682 ConfigParamSpec{
"mc-signal-filt", VariantType::Bool,
false, {
"Enable usage of signal filtering (only for MC with embedding)"}},
3683 ConfigParamSpec{
"collect-config-files", VariantType::Bool,
false, {
"Collect ConfigParams json files written by upsteam processors"}},
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
std::vector< std::string > header
std::vector< std::string > keys
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 Names Generator class.
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)
GPUd() value_type estimateLTFast(o2 static GPUd() float estimateLTIncrement(const o2 PropagatorImpl * Instance(bool uninitialized=false)
static const DPLAlpideParam< N > & Instance()
static const std::string & getOutputDir()
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
uint8_t int statusCode int
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)
Defining ITS Vertex explicitly as messageable.
std::vector< ConfigParamSpec > ccdbParamSpec(std::string const &path, int runDependent, std::vector< CCDBMetadata > metadata={}, int qrate=0)
const bool const int TrackITSInternal< NLayers > & track
int angle2Sector(float phi)
float sector2Angle(int sect)
const int TDCSignal[NTDCChannels]
constexpr int NTDCChannels
std::string fullVersion()
get full version information (official O2 release and git commit)
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