8585#include " MathUtils/Utils.h"
8686#include " Math/SMatrix.h"
8787#include " TString.h"
88+ #include < limits>
8889#include < map>
8990#include < numeric>
91+ #include < type_traits>
9092#include < unordered_map>
9193#include < set>
9294#include < string>
@@ -354,25 +356,47 @@ void AODProducerWorkflowDPL::addToTracksExtraTable(TracksExtraCursorType& tracks
354356template <typename TracksQACursorType>
355357void AODProducerWorkflowDPL::addToTracksQATable (TracksQACursorType& tracksQACursor, TrackQA& trackQAInfoHolder)
356358{
357-
358- // trackQA
359- tracksQACursor (
360-
361- // truncateFloatFraction(trackQAInfoHolder.tpcdcaR, mTrackChi2),
362- // truncateFloatFraction(trackQAInfoHolder.tpcdcaZ, mTrackChi2),
363- trackQAInfoHolder.trackID ,
364- trackQAInfoHolder.tpcTime0 ,
365- trackQAInfoHolder.tpcdcaR ,
366- trackQAInfoHolder.tpcdcaZ ,
367- trackQAInfoHolder.tpcClusterByteMask ,
368- trackQAInfoHolder.tpcdEdxMax0R ,
369- trackQAInfoHolder.tpcdEdxMax1R ,
370- trackQAInfoHolder.tpcdEdxMax2R ,
371- trackQAInfoHolder.tpcdEdxMax3R ,
372- trackQAInfoHolder.tpcdEdxTot0R ,
373- trackQAInfoHolder.tpcdEdxTot1R ,
374- trackQAInfoHolder.tpcdEdxTot2R ,
375- trackQAInfoHolder.tpcdEdxTot3R );
359+ if constexpr (std::is_same_v<o2::aod::TracksQAVersion, o2::aod::TracksQA_001>) { // TODO remove remove once version changes
360+ tracksQACursor (
361+ trackQAInfoHolder.trackID ,
362+ truncateFloatFraction (trackQAInfoHolder.tpcTime0 , mTPCTime0 ),
363+ trackQAInfoHolder.tpcdcaR ,
364+ trackQAInfoHolder.tpcdcaZ ,
365+ trackQAInfoHolder.tpcClusterByteMask ,
366+ trackQAInfoHolder.tpcdEdxMax0R ,
367+ trackQAInfoHolder.tpcdEdxMax1R ,
368+ trackQAInfoHolder.tpcdEdxMax2R ,
369+ trackQAInfoHolder.tpcdEdxMax3R ,
370+ trackQAInfoHolder.tpcdEdxTot0R ,
371+ trackQAInfoHolder.tpcdEdxTot1R ,
372+ trackQAInfoHolder.tpcdEdxTot2R ,
373+ trackQAInfoHolder.tpcdEdxTot3R ,
374+ trackQAInfoHolder.dRefContY ,
375+ trackQAInfoHolder.dRefContZ ,
376+ trackQAInfoHolder.dRefContSnp ,
377+ trackQAInfoHolder.dRefContTgl ,
378+ trackQAInfoHolder.dRefContQ2Pt ,
379+ trackQAInfoHolder.dRefGloY ,
380+ trackQAInfoHolder.dRefGloZ ,
381+ trackQAInfoHolder.dRefGloSnp ,
382+ trackQAInfoHolder.dRefGloTgl ,
383+ trackQAInfoHolder.dRefGloQ2Pt );
384+ } else {
385+ tracksQACursor (
386+ trackQAInfoHolder.trackID ,
387+ trackQAInfoHolder.tpcTime0 ,
388+ trackQAInfoHolder.tpcdcaR ,
389+ trackQAInfoHolder.tpcdcaZ ,
390+ trackQAInfoHolder.tpcClusterByteMask ,
391+ trackQAInfoHolder.tpcdEdxMax0R ,
392+ trackQAInfoHolder.tpcdEdxMax1R ,
393+ trackQAInfoHolder.tpcdEdxMax2R ,
394+ trackQAInfoHolder.tpcdEdxMax3R ,
395+ trackQAInfoHolder.tpcdEdxTot0R ,
396+ trackQAInfoHolder.tpcdEdxTot1R ,
397+ trackQAInfoHolder.tpcdEdxTot2R ,
398+ trackQAInfoHolder.tpcdEdxTot3R );
399+ }
376400}
377401
378402template <typename mftTracksCursorType, typename AmbigMFTTracksCursorType>
@@ -1704,6 +1728,7 @@ void AODProducerWorkflowDPL::init(InitContext& ic)
17041728 mTrackCovOffDiag = 0xFFFFFFFF ;
17051729 mTrackSignal = 0xFFFFFFFF ;
17061730 mTrackTime = 0xFFFFFFFF ;
1731+ mTPCTime0 = 0xFFFFFFFF ;
17071732 mTrackTimeError = 0xFFFFFFFF ;
17081733 mTrackPosEMCAL = 0xFFFFFFFF ;
17091734 mTracklets = 0xFFFFFFFF ;
@@ -1815,7 +1840,7 @@ void AODProducerWorkflowDPL::run(ProcessingContext& pc)
18151840 auto tracksCursor = createTableCursor<o2::aod::StoredTracksIU>(pc);
18161841 auto tracksCovCursor = createTableCursor<o2::aod::StoredTracksCovIU>(pc);
18171842 auto tracksExtraCursor = createTableCursor<o2::aod::StoredTracksExtra>(pc);
1818- auto tracksQACursor = createTableCursor<o2::aod::TracksQA >(pc);
1843+ auto tracksQACursor = createTableCursor<o2::aod::TracksQAVersion >(pc);
18191844 auto ambigTracksCursor = createTableCursor<o2::aod::AmbiguousTracks>(pc);
18201845 auto ambigMFTTracksCursor = createTableCursor<o2::aod::AmbiguousMFTTracks>(pc);
18211846 auto ambigFwdTracksCursor = createTableCursor<o2::aod::AmbiguousFwdTracks>(pc);
@@ -2531,16 +2556,15 @@ AODProducerWorkflowDPL::TrackQA AODProducerWorkflowDPL::processBarrelTrackQA(int
25312556 TrackQA trackQAHolder;
25322557 auto contributorsGID = data.getTPCContributorGID (trackIndex);
25332558 const auto & trackPar = data.getTrackParam (trackIndex);
2534- // auto src = trackIndex.getSource();
25352559 if (contributorsGID.isIndexSet ()) {
2560+ auto prop = o2::base::Propagator::Instance ();
25362561 const auto & tpcOrig = data.getTPCTrack (contributorsGID);
25372562 // / getDCA - should be done with the copy of TPC only track
2538- // LOGP(info, "GloIdx: {} TPCIdx: {}, NTPCTracks: {}", trackIndex.asString(), contributorsGID.asString(), data.getTPCTracks().size());
2539- o2::track::TrackParametrization<float > tpcTMP = tpcOrig; // / get backup of the track
2540- o2::base::Propagator::MatCorrType mMatType = o2::base::Propagator::MatCorrType::USEMatCorrLUT; // / should be parameterized
2541- o2::dataformats::VertexBase v = mVtx .getMeanVertex (collisionID < 0 ? 0 .f : data.getPrimaryVertex (collisionID).getZ ());
2563+ o2::track::TrackParametrization<float > tpcTMP = tpcOrig; // / get backup of the track
2564+ const o2::base::Propagator::MatCorrType mMatType = o2::base::Propagator::MatCorrType::USEMatCorrLUT; // / should be parameterized
2565+ const o2::dataformats::VertexBase v = mVtx .getMeanVertex (collisionID < 0 ? 0 .f : data.getPrimaryVertex (collisionID).getZ ());
25422566 o2::gpu::gpustd::array<float , 2 > dcaInfo{-999 ., -999 .};
2543- if (o2::base::Propagator::Instance () ->propagateToDCABxByBz ({v.getX (), v.getY (), v.getZ ()}, tpcTMP, 2 .f , mMatType , &dcaInfo)) {
2567+ if (prop ->propagateToDCABxByBz ({v.getX (), v.getY (), v.getZ ()}, tpcTMP, 2 .f , mMatType , &dcaInfo)) {
25442568 trackQAHolder.tpcdcaR = 100 . * dcaInfo[0 ] / sqrt (1 . + trackPar.getQ2Pt () * trackPar.getQ2Pt ());
25452569 trackQAHolder.tpcdcaZ = 100 . * dcaInfo[1 ] / sqrt (1 . + trackPar.getQ2Pt () * trackPar.getQ2Pt ());
25462570 }
@@ -2564,7 +2588,7 @@ AODProducerWorkflowDPL::TrackQA AODProducerWorkflowDPL::processBarrelTrackQA(int
25642588 }
25652589 trackQAHolder.tpcTime0 = tpcOrig.getTime0 ();
25662590 trackQAHolder.tpcClusterByteMask = byteMask;
2567- float dEdxNorm = (tpcOrig.getdEdx ().dEdxTotTPC > 0 ) ? 100 . / tpcOrig.getdEdx ().dEdxTotTPC : 0 ;
2591+ const float dEdxNorm = (tpcOrig.getdEdx ().dEdxTotTPC > 0 ) ? 100 . / tpcOrig.getdEdx ().dEdxTotTPC : 0 ;
25682592 trackQAHolder.tpcdEdxMax0R = uint8_t (tpcOrig.getdEdx ().dEdxMaxIROC * dEdxNorm);
25692593 trackQAHolder.tpcdEdxMax1R = uint8_t (tpcOrig.getdEdx ().dEdxMaxOROC1 * dEdxNorm);
25702594 trackQAHolder.tpcdEdxMax2R = uint8_t (tpcOrig.getdEdx ().dEdxMaxOROC2 * dEdxNorm);
@@ -2574,7 +2598,54 @@ AODProducerWorkflowDPL::TrackQA AODProducerWorkflowDPL::processBarrelTrackQA(int
25742598 trackQAHolder.tpcdEdxTot1R = uint8_t (tpcOrig.getdEdx ().dEdxTotOROC1 * dEdxNorm);
25752599 trackQAHolder.tpcdEdxTot2R = uint8_t (tpcOrig.getdEdx ().dEdxTotOROC2 * dEdxNorm);
25762600 trackQAHolder.tpcdEdxTot3R = uint8_t (tpcOrig.getdEdx ().dEdxTotOROC3 * dEdxNorm);
2577- // /
2601+
2602+ if constexpr (std::is_same_v<o2::aod::TracksQAVersion, o2::aod::TracksQA_001>) { // TODO remove remove once version changes
2603+ // Add matching information at a reference point (defined by
2604+ // o2::aod::track::trackQARefRadius) in the same frame as the global track
2605+ // without material corrections and error propagation
2606+ if (auto itsContGID = data.getITSContributorGID (trackIndex); itsContGID.isIndexSet () && itsContGID.getSource () != GIndex::ITSAB) {
2607+ const auto & itsOrig = data.getITSTrack (itsContGID);
2608+ o2::track::TrackPar gloCopy = trackPar;
2609+ o2::track::TrackPar itsCopy = itsOrig;
2610+ o2::track::TrackPar tpcCopy = tpcOrig;
2611+ if (prop->propagateToX (gloCopy, o2::aod::track::trackQARefRadius, prop->getNominalBz (), o2::base::Propagator::MAX_SIN_PHI, o2::base::Propagator::MAX_STEP, mMatCorr ) &&
2612+ prop->propagateToAlphaX (tpcCopy, gloCopy.getAlpha (), o2::aod::track::trackQARefRadius, false , o2::base::Propagator::MAX_SIN_PHI, o2::base::Propagator::MAX_STEP, 1 , mMatCorr ) &&
2613+ prop->propagateToAlphaX (itsCopy, gloCopy.getAlpha (), o2::aod::track::trackQARefRadius, false , o2::base::Propagator::MAX_SIN_PHI, o2::base::Propagator::MAX_STEP, 1 , mMatCorr )) {
2614+ // All tracks are now at the same radius and in the same frame and we can calculate the deltas wrt. to the global track
2615+ // The scale is defined by the global track scaling depending on beta0
2616+ const float beta0 = std::sqrt (std::min (50 .f / tpcOrig.getdEdx ().dEdxMaxTPC , 1 .f ));
2617+ const float qpt = gloCopy.getQ2Pt ();
2618+ const float x = qpt / beta0;
2619+ // scaling is defined as sigmaBins/sqrt(p0^2 + (p1 * q/pt / beta)^2)
2620+ auto scaleCont = [&x](int i) -> float {
2621+ return o2::aod::track::trackQAScaleBins / std::sqrt (o2::aod::track::trackQAScaleContP0[i] * o2::aod::track::trackQAScaleContP0[i] + (o2::aod::track::trackQAScaleContP1[i] * x) * (o2::aod::track::trackQAScaleContP1[i] * x));
2622+ };
2623+ auto scaleGlo = [&x](int i) -> float {
2624+ return o2::aod::track::trackQAScaleBins / std::sqrt (o2::aod::track::trackQAScaleGloP0[i] * o2::aod::track::trackQAScaleGloP0[i] + (o2::aod::track::trackQAScaleGloP1[i] * x) * (o2::aod::track::trackQAScaleGloP1[i] * x));
2625+ };
2626+
2627+ // This allows to safely clamp any float to one byte, using the
2628+ // minmal/maximum values as under-/overflow borders and rounding to the nearest integer
2629+ auto safeInt8Clamp = [](auto value) -> int8_t {
2630+ using ValType = decltype (value);
2631+ 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 ()))));
2632+ };
2633+
2634+ // Calculate deltas for contributors
2635+ trackQAHolder.dRefContY = safeInt8Clamp ((itsCopy.getY () - tpcCopy.getY ()) * scaleCont (0 ));
2636+ trackQAHolder.dRefContZ = safeInt8Clamp ((itsCopy.getZ () - tpcCopy.getZ ()) * scaleCont (1 ));
2637+ trackQAHolder.dRefContSnp = safeInt8Clamp ((itsCopy.getSnp () - tpcCopy.getSnp ()) * scaleCont (2 ));
2638+ trackQAHolder.dRefContTgl = safeInt8Clamp ((itsCopy.getTgl () - tpcCopy.getTgl ()) * scaleCont (3 ));
2639+ trackQAHolder.dRefContQ2Pt = safeInt8Clamp ((itsCopy.getQ2Pt () - tpcCopy.getQ2Pt ()) * scaleCont (4 ));
2640+ // Calculate deltas for global track against averaged contributors
2641+ trackQAHolder.dRefGloY = safeInt8Clamp (((itsCopy.getY () + tpcCopy.getY ()) * 0 .5f - gloCopy.getY ()) * scaleGlo (0 ));
2642+ trackQAHolder.dRefGloZ = safeInt8Clamp (((itsCopy.getZ () + tpcCopy.getZ ()) * 0 .5f - gloCopy.getZ ()) * scaleGlo (1 ));
2643+ trackQAHolder.dRefGloSnp = safeInt8Clamp (((itsCopy.getSnp () + tpcCopy.getSnp ()) * 0 .5f - gloCopy.getSnp ()) * scaleGlo (2 ));
2644+ trackQAHolder.dRefGloTgl = safeInt8Clamp (((itsCopy.getTgl () + tpcCopy.getTgl ()) * 0 .5f - gloCopy.getTgl ()) * scaleGlo (3 ));
2645+ trackQAHolder.dRefGloQ2Pt = safeInt8Clamp (((itsCopy.getQ2Pt () + tpcCopy.getQ2Pt ()) * 0 .5f - gloCopy.getQ2Pt ()) * scaleGlo (4 ));
2646+ }
2647+ }
2648+ }
25782649 }
25792650
25802651 return trackQAHolder;
0 commit comments