15#include <TStopwatch.h>
60using T2VMap = std::unordered_map<GTrackID, size_t>;
70 : mDataRequest(dr), mGGCCDBRequest(gr), mTracksSrc(
src), mUseMC(useMC), mWithPV(withPV) {}
80 void prepareITSClusters();
81 bool selectTrack(
GTrackID trkID,
bool checkMCTruth = true) const;
82 T2VMap buildT2V(
bool includeCont = false,
bool requireMCMatch = true) const;
84 void getImpactParams(const
o2::track::
TrackParCov& trk, const
o2::dataformats::VertexBase& pv,
float ip[2],
float bz);
87 void doDCARefitStudy();
91 void doMisalignmentStudy();
94 TrackCounter() =
default;
96 void operator+=(
int src)
98 if (
src >= 0 &&
src <
static_cast<int>(mSuccess.size())) {
103 void operator-=(
int src)
105 if (
src >= 0 &&
src <
static_cast<int>(mirrors.size())) {
110 void operator&=(
int src)
112 if (
src >= 0 &&
src <
static_cast<int>(mRejected.size())) {
119 LOGP(info,
"\t\t\tSuccess / Error / Rejected");
121 const auto cdm = GTrackID::getSourceDetectorsMask(cis);
122 if (cdm[DetID::ITS]) {
123 LOGP(info,
"\t{:{}}\t{} / {} / {}",
GTrackID::getSourceName(cis), 15, mSuccess[cis], mirrors[cis], mRejected[cis]);
135 std::array<size_t, GTrackID::NSources> mSuccess{};
136 std::array<size_t, GTrackID::NSources> mirrors{};
137 std::array<size_t, GTrackID::NSources> mRejected{};
139 TrackCounter mTrackCounter;
142 std::vector<TrackingCluster> mITScl;
143 std::span<const int> mITSclRef;
146 std::unique_ptr<o2::utils::TreeStreamRedirector> mDBGOut;
147 std::shared_ptr<DataRequest> mDataRequest;
148 std::shared_ptr<o2::base::GRPGeomRequest> mGGCCDBRequest;
156 align::MisalignmentModel mMisalignment;
164 std::string dbgnm = maxLanes == 1 ?
"its3TrackStudy.root" : fmt::format(
"its3TrackStudy_{}.root", lane);
165 mDBGOut = std::make_unique<o2::utils::TreeStreamRedirector>(dbgnm.c_str(),
"recreate");
168 LOGP(fatal,
"initialization of MCKinematicsReader failed");
175 updateTimeDependentParams(pc);
182 if (
static bool initOnceDone{
false}; !initOnceDone) {
209 LOG(info) <<
"cluster dictionary updated";
215void TrackingStudySpec::process()
217 prepareITSClusters();
218 if (mParams->
doDCA) {
224 if (mUseMC && mParams->
doPull) {
227 if (mUseMC && mParams->
doMC) {
234 doMisalignmentStudy();
238void TrackingStudySpec::prepareITSClusters()
241 LOGP(info,
"Preparing {} measurments", clusITS.size());
243 mITScl.reserve(clusITS.size());
244 auto pattIt = patterns.begin();
248 mITScl.reserve(clusITS.size());
249 for (
const auto& cls : clusITS) {
250 const auto sens = cls.getSensorID();
251 float sigmaY2{0}, sigmaZ2{0};
254 const auto gloXYZ = geom->getMatrixL2G(sens) * locXYZ;
261 float alpha = geom->getSensorRefAlpha(sens);
265 trkXYZ.SetX(std::hypot(gloXYZ.x(), gloXYZ.y()));
266 alpha = std::atan2(gloXYZ.y(), gloXYZ.x());
268 auto& cl3d = mITScl.emplace_back(sens, trkXYZ);
269 cl3d.setErrors(sigmaY2, sigmaZ2, 0.f);
271 math_utils::detail::bringToPMPi(cl3d.alpha);
275bool TrackingStudySpec::selectTrack(
GTrackID trkID,
bool checkMCTruth)
const
289 if (itsTrk.getChi2() > mParams->
maxChi2 || itsTrk.getNClusters() < mParams->
minITSCls) {
295 if (tpcTrk.getNClusters() < mParams->
minTPCCls) {
301 if (gTrk.getPt() < mParams->
minPt || gTrk.getPt() > mParams->
maxPt) {
304 if (std::abs(gTrk.getEta()) > mParams->
maxEta) {
307 if (mUseMC && checkMCTruth) {
309 if (!itsLbl.isValid()) {
314 if (itsLbl != tpcLbl) {
323 for (
const auto& lbl : tofLbls) {
333T2VMap TrackingStudySpec::buildT2V(
bool includeCont,
bool requireMCMatch)
const
339 auto nv = vtxRefs.size() - 1;
341 for (
size_t iv = 0; iv < nv; ++iv) {
342 const auto& pv = pvvec[iv];
343 if (pv.getNContributors() - 1 < mParams->
minPVCont) {
346 if (requireMCMatch) {
349 const auto& vtxRef = vtxRefs[iv];
350 int it = vtxRef.getFirstEntry(), itLim = it + vtxRef.getEntries();
351 for (; it < itLim; it++) {
352 const auto& tvid = trackIndex[it];
353 if (tvid.isAmbiguous()) {
359 if (mUseMC && requireMCMatch) {
369 const auto cdm = GTrackID::getSourceDetectorsMask(cis);
370 if (!mRecoData.
isTrackSourceLoaded(cis) || !cdm[DetID::ITS] || !contributorsGID[cis].isIndexSet()) {
373 if (mUseMC && requireMCMatch) {
379 t2v[contributorsGID[cis]] = iv;
384 return std::move(t2v);
395 std::array<const TrackingCluster*, 8> clArr{
nullptr};
397 const auto& itsTrOrig = mRecoData.
getITSTrack(gidx);
401 if (!prop->propagateToDCA(pv, trkPV, prop->getNominalBz(), 2.0, mParams->
CorrType)) {
402 mTrackCounter -= gidx.getSource();
406 float cosAlp = NAN, sinAlp = NAN;
407 o2::math_utils::sincos(trkPV.getAlpha(), sinAlp, cosAlp);
409 TrackingCluster pvCls;
410 pvCls.alpha = trkPV.getAlpha();
411 pvCls.setXYZ((pv.getX() * cosAlp) + (pv.getY() * sinAlp), (-pv.getX() * sinAlp) + (pv.getY() * cosAlp), pv.getZ());
412 pvCls.setErrors(0.5f * (pv.getSigmaX2() + pv.getSigmaY2()), pv.getSigmaZ2(), 0.f);
413 pvCls.setSensorID(-1);
416 const int ncl = itsTrOrig.getNumberOfClusters();
417 for (
int icl = 0; icl <
ncl; ++icl) {
418 const auto& curClu = mITScl[mITSclRef[itsTrOrig.getClusterEntry(icl)]];
419 const int llr = geom->getLayer(curClu.getSensorID());
420 if (clArr[1 + llr]) {
421 LOGP(fatal,
"Cluster at lr {} was already assigned, old sens {}, new sens {}", llr, clArr[1 + llr]->
getSensorID(), curClu.getSensorID());
423 clArr[1 + llr] = &curClu;
427 trFit.resetCovariance(1'000);
429 for (
int icl = clArr.size() - 1; icl >= 0; --icl) {
433 if (!trFit.rotate(clArr[icl]->alpha) || !prop->propagateToX(trFit, clArr[icl]->
getX(), prop->getNominalBz(), 0.85, 2.0, mParams->
CorrType)) {
434 mTrackCounter -= gidx.getSource();
437 chi2 += trFit.getPredictedChi2(*clArr[icl]);
438 if (!trFit.update(*clArr[icl])) {
439 mTrackCounter -= gidx.getSource();
446void TrackingStudySpec::doDCAStudy()
449 LOGP(info,
"Doing DCA study");
450 mTrackCounter.reset();
454 int nDCAFits{0}, nDCAFitsFail{0};
458 auto nv = vtxRefs.size() - 1;
459 auto&
stream = (*mDBGOut) <<
"dca";
460 for (
int iv = 0; iv < nv; iv++) {
461 const auto& pv = pvvec[iv];
462 const auto& vtref = vtxRefs[iv];
464 const auto dm = GTrackID::getSourceDetectorsMask(is);
469 int idMin = vtref.getFirstEntryOfSource(is), idMax = idMin + vtref.getEntriesOfSource(is);
470 for (
int i = idMin;
i < idMax;
i++) {
471 const auto vid = trackIndex[
i];
472 if (!vid.isPVContributor()) {
473 mTrackCounter &= vid.getSource();
481 const auto cdm = GTrackID::getSourceDetectorsMask(cis);
482 if (!mRecoData.
isTrackSourceLoaded(cis) || !cdm[DetID::ITS] || !contributorsGID[cis].isIndexSet()) {
483 mTrackCounter &= cis;
486 if (!selectTrack(contributorsGID[cis])) {
487 mTrackCounter &= vid.getSource();
492 const auto& trk = mRecoData.
getTrackParam(contributorsGID[cis]);
495 if (mWithPV && mParams->
refitITS && cis ==
GTrackID::ITS && !refitITSPVTrack(trkRefit, contributorsGID[cis], pv)) {
496 mTrackCounter -= cis;
499 trkRefit.invalidate();
503 if (!prop->propagateToDCABxByBz(pv, trkDCA, 2.f, mParams->
CorrType, &dcaInfo)) {
504 mTrackCounter -= cis;
512 <<
"trkRefit=" << trkRefit
513 <<
"trkAtPV=" << trkDCA
514 <<
"dca=" << dcaInfo;
520 const auto& eve = mMCReader.
getMCEventHeader(lbl.getSourceID(), lbl.getEventID());
522 mcEve.setPos({(float)eve.GetX(), (float)eve.GetY(), (float)eve.GetZ()});
524 if (!prop->propagateToDCABxByBz(mcEve, trkC, 2.f, mParams->
CorrType, &dcaInfoMC)) {
525 mTrackCounter -= cis;
529 const auto& mcTrk = mMCReader.
getTrack(lbl);
530 if (mcTrk ==
nullptr) {
531 LOGP(fatal,
"mcTrk is null did selection fail?");
533 stream <<
"mcTrk=" << *mcTrk
534 <<
"dca2MC=" << dcaInfoMC
540 mTrackCounter += cis;
546 LOGP(info,
"doDCAStudy: accepted {} fits, failed {} (in {:.2f} seconds)", nDCAFits, nDCAFitsFail,
sw.RealTime());
547 mTrackCounter.print();
550void TrackingStudySpec::doDCARefitStudy()
553 LOGP(info,
"Doing DCARefit study");
554 mTrackCounter.reset();
562 auto nv = vtxRefs.size() - 1;
563 auto t2v = buildT2V();
564 std::vector<std::vector<GTrackID>> v2t;
566 auto creator = [&](
const auto& trk,
GTrackID trkID,
float _t0,
float terr) ->
bool {
567 if constexpr (!isBarrelTrack<decltype(trk)>()) {
568 mTrackCounter &= trkID.getSource();
572 mTrackCounter &= trkID.getSource();
576 if constexpr (isBarrelTrack<decltype(trk)>()) {
577 if (trk.getPt() < mParams->
minPt || trk.getPt() > mParams->
maxPt) {
578 mTrackCounter &= trkID.getSource();
581 if (std::abs(trk.getEta()) > mParams->
maxEta) {
582 mTrackCounter &= trkID.getSource();
585 if (!t2v.contains(trkID)) {
586 mTrackCounter &= trkID.getSource();
589 if (!selectTrack(trkID, mUseMC)) {
590 mTrackCounter &= trkID.getSource();
594 v2t[t2v[trkID]].push_back(trkID);
599 int nDCAFits{0}, nDCAFitsFail{0};
600 auto&
stream = (*mDBGOut) <<
"dcaRefit";
601 for (
size_t iv = 0; iv < nv; ++iv) {
602 const auto& pv = pvvec[iv];
603 const auto& trkIDs = v2t[iv];
604 if (trkIDs.size() - 1 < mParams->
minPVCont) {
607 std::vector<o2::track::TrackParCov> trks;
608 trks.reserve(trkIDs.size());
609 for (
const auto& trkID : trkIDs) {
616 std::vector<bool>
trkMask(trkIDs.size(),
true);
617 for (
size_t it{0}; it <
trkMask.size(); ++it) {
623 if (pvRefit.getChi2() < 0) {
630 auto trkC = trks[it];
631 if (!prop->propagateToDCABxByBz(pv, trkC, 2.f, mParams->
CorrType, &dcaInfo)) {
632 mTrackCounter -= trkIDs[it].getSource();
637 auto trkCRefit = trks[it];
638 if (!prop->propagateToDCABxByBz(pv, trkCRefit, 2.f, mParams->
CorrType, &dcaInfoRefit)) {
639 mTrackCounter -= trkIDs[it].getSource();
644 stream <<
"src=" << trkIDs[it].getSource()
646 <<
"trkAtPV=" << trkC
648 <<
"pvRefit=" << pvRefit
649 <<
"trkAtPVRefit=" << trkC
650 <<
"dcaRefit=" << dcaInfoRefit;
653 if (mcTrk ==
nullptr) {
654 LOGP(fatal,
"mcTrk is null did selection fail?");
656 stream <<
"mcTrk=" << *mcTrk;
660 mTrackCounter += trkIDs[it].getSource();
664 LOGP(info,
"doDCARefitStudy: accepted {} fits, failed {} (in {:.2f} seconds)", nDCAFits, nDCAFitsFail,
sw.RealTime());
665 mTrackCounter.print();
668void TrackingStudySpec::doPullStudy()
671 LOGP(info,
"Doing Pull study");
672 mTrackCounter.reset();
675 int nPulls{0}, nPullsFail{0};
678 auto checkInTrack = [&](
GTrackID trkID) {
679 if (!selectTrack(trkID)) {
680 mTrackCounter &= trkID.getSource();
684 const auto mcTrk = mMCReader.
getTrack(lbl);
688 if (!mcTrk->isPrimary()) {
689 mTrackCounter &= trkID.getSource();
696 const auto& eve = mMCReader.
getMCEventHeader(lbl.getSourceID(), lbl.getEventID());
698 mcEve.setXYZ((
float)eve.GetX(), (float)eve.GetY(), (float)eve.GetZ());
699 mcEve.setSigmaX(20e-4f);
700 mcEve.setSigmaY(20e-4f);
701 mcEve.setSigmaZ(20e-4f);
702 if (!refitITSPVTrack(trk, trkID, mcEve)) {
703 mTrackCounter -= trkID.getSource();
709 std::array<float, 3> xyz{(float)mcTrk->GetStartVertexCoordinatesX(), (float)mcTrk->GetStartVertexCoordinatesY(), (float)mcTrk->GetStartVertexCoordinatesZ()},
710 pxyz{(float)mcTrk->GetStartVertexMomentumX(), (float)mcTrk->GetStartVertexMomentumY(), (float)mcTrk->GetStartVertexMomentumZ()};
711 TParticlePDG* pPDG = TDatabasePDG::Instance()->GetParticle(mcTrk->GetPdgCode());
713 mTrackCounter -= trkID.getSource();
719 if (!mcTrkO2.rotate(trk.getAlpha()) || !prop->PropagateToXBxByBz(mcTrkO2, trk.getX())) {
720 mTrackCounter -= trkID.getSource();
729 <<
"src=" << trkID.getSource()
730 <<
"itsTrk=" << itsTrk
731 <<
"mcTrk=" << mcTrkO2
732 <<
"mcPart=" << mcTrk
736 mTrackCounter += trkID.getSource();
755 LOGP(info,
"doPullStudy: accepted {} pulls; rejected {} (in {:.2f} seconds)", nPulls, nPullsFail,
sw.RealTime());
756 mTrackCounter.print();
759void TrackingStudySpec::doMCStudy()
761 LOGP(info,
"Doing MC study");
762 mTrackCounter.reset();
769 std::unordered_map<o2::MCCompLabel, ParticleInfoExt>
info;
771 LOGP(info,
"** Filling particle table ... ");
772 for (
int iEve{0}; iEve < nev; ++iEve) {
773 const auto& mcTrks = mMCReader.
getTracks(iSrc, iEve);
774 for (
int iTrk{0}; iTrk < mcTrks.size(); ++iTrk) {
775 const auto& mcTrk = mcTrks[iTrk];
776 const auto pdg = mcTrk.GetPdgCode();
780 const auto apdg = std::abs(pdg);
781 if (apdg != 11 && apdg != 211 && apdg != 321 && apdg != 2212) {
785 auto& part =
info[lbl];
786 part.mcTrack = mcTrk;
789 LOGP(info,
"** Creating particle/clusters correspondence ... ");
792 for (
auto iCluster{0}; iCluster <
clusters.size(); ++iCluster) {
793 auto labs = clustersMCLCont->getLabels(iCluster);
794 for (
auto& lab : labs) {
795 if (!lab.isValid() || lab.getSourceID() != 0 || !lab.isCorrect()) {
798 int trackID = 0, evID = 0, srcID = 0;
800 lab.get(trackID, evID, srcID, fake);
803 auto& part =
info[{trackID, evID, srcID}];
804 part.clusters |= (1 <<
layer);
806 part.fakeClusters |= (1 <<
layer);
810 LOGP(info,
"** Analysing tracks ... ");
812 if (contributorsGID[det].isIndexSet()) {
815 o2::MCCompLabel iLbl(lbl.getTrackID(), lbl.getEventID(), lbl.getSourceID());
816 if (
info.contains(iLbl)) {
817 auto& part =
info[iLbl];
818 SETBIT(part.recoTracks, det);
820 SETBIT(part.fakeTracks, det);
826 auto creator = [&](
const auto& trk,
GTrackID trkID,
float _t0,
float terr) ->
bool {
827 if constexpr (!isBarrelTrack<decltype(trk)>()) {
839 if (!gLbl.isValid()) {
842 o2::MCCompLabel iLbl(gLbl.getTrackID(), gLbl.getEventID(), gLbl.getSourceID());
843 if (!
info.contains(iLbl)) {
846 auto& part =
info[iLbl];
849 accountLbl(contributorsGID, DetID::ITS);
850 accountLbl(contributorsGID, DetID::TPC);
851 accountLbl(contributorsGID, DetID::TRD);
852 accountLbl(contributorsGID, DetID::TOF);
859 LOGP(info,
"Streaming output to tree");
860 for (
const auto& [_, part] :
info) {
867 LOGP(info,
"doMCStudy: accounted {} MCParticles and {} tracks (in {:.2f} seconds)",
info.size(), nTracks,
sw.RealTime());
870void TrackingStudySpec::doResidStudy()
872 LOGP(info,
"Doing residual study");
875 const float bz = prop->getNominalBz();
877 int goodRefit{0}, notPassedSel{0}, fitFail{0};
880 std::array<TrackingCluster, 8> cl;
881 std::array<const TrackingCluster*, 8> clArr{
nullptr};
883 float ip[2]{0.f, 0.f};
890 const auto& eve = mMCReader.
getMCEventHeader(lbl.getSourceID(), lbl.getEventID());
891 pv.setXYZ(eve.GetX(), eve.GetY(), eve.GetZ());
893 auto trFitOut = iTrack.getParamIn();
894 if (!prop->propagateToDCA(pv, trFitOut, bz, base::Propagator::MAX_STEP, mParams->
CorrType)) {
897 pv.setSigmaX(20e-4f);
898 pv.setSigmaY(20e-4f);
899 pv.setSigmaZ(20e-4f);
900 float cosAlp = NAN, sinAlp = NAN;
901 o2::math_utils::sincos(trFitOut.getAlpha(), sinAlp, cosAlp);
902 cl[0].alpha = trFitOut.getAlpha();
903 cl[0].setXYZ((pv.getX() * cosAlp) + (pv.getY() * sinAlp), (-pv.getX() * sinAlp) + (pv.getY() * cosAlp), pv.getZ());
904 cl[0].setErrors(0.5f * (pv.getSigmaX2() + pv.getSigmaY2()), pv.getSigmaZ2(), 0.f);
905 cl[0].setSensorID(-1);
910 int nCl = iTrack.getNClusters();
911 for (
int i = 0;
i <
nCl;
i++) {
913 int sens = curClu.getSensorID();
914 int llr = geom->getLayer(sens);
915 if (clArr[1 + llr]) {
916 LOGP(fatal,
"Cluster at lr {} was already assigned, old sens {}, new sens {}", llr, clArr[1 + llr]->
getSensorID(), sens);
918 clArr[1 + llr] = &curClu;
921 std::array<o2::track::TrackParCov, 8> extrapOut, extrapInw;
928 for (
int i = 0;
i <= 7;
i++) {
931 if (!tInt.isValid()) {
934 auto phi =
i == 0 ? tInt.getPhi() : tInt.getPhiPos();
935 o2::math_utils::bringTo02Pi(phi);
938 getImpactParams(tInt, pv, ip, bz);
940 <<
"dYInt=" << clArr[
i]->getY() - tInt.getY()
941 <<
"dZInt=" << clArr[
i]->getZ() - tInt.getZ()
942 <<
"dYIn=" << clArr[
i]->getY() - extrapInw[
i].getY()
943 <<
"dZIn=" << clArr[
i]->getZ() - extrapInw[
i].getZ()
944 <<
"dYOut=" << clArr[
i]->getY() - extrapOut[
i].getY()
945 <<
"dZOut=" << clArr[
i]->getZ() - extrapOut[
i].getZ()
947 <<
"clY=" << clArr[
i]->getY()
948 <<
"clZ=" << clArr[
i]->getZ()
949 <<
"clX=" << clArr[
i]->getX()
950 <<
"alpha=" << clArr[
i]->alpha
951 <<
"sens=" << clArr[
i]->getSensorID()
955 <<
"pt=" << tInt.getPt()
966 for (
size_t iTrk{0}; iTrk < itsTracks.size(); ++iTrk) {
967 const auto& iTrack = itsTracks[iTrk];
968 const auto& lbl = itsMC[iTrk];
969 const auto& mc = mMCReader.
getTrack(lbl);
970 if (std::abs(iTrack.getEta()) > mParams->
maxEta || iTrack.getChi2() > mParams->
maxChi2 || iTrack.getNClusters() < mParams->
minITSCls || iTrack.getPt() < mParams->
minPt || !lbl.isCorrect() || !mc->isPrimary()) {
974 doRefits(iTrack, lbl);
977 LOGP(info,
"\trefitted {} out of {} tracks ({} !sel, {} !fit)", goodRefit, itsTracks.size(), notPassedSel, fitFail);
980void TrackingStudySpec::doMisalignmentStudy()
982 LOGP(info,
"Doing misalignment study");
986 int goodRefit{0}, notPassedSel{0}, fitFail{0}, fitFailMis{0};
988 float ip[2]{0.f, 0.f};
990 auto writeTree = [&](
const char* treeName,
991 const std::array<const TrackingCluster*, 8>& clArr,
992 const std::array<o2::track::TrackParCov, 8>& extrapOut,
993 const std::array<o2::track::TrackParCov, 8>& extrapInw,
995 const auto mcTrk = mMCReader.
getTrack(lbl);
999 TParticlePDG* pPDG = TDatabasePDG::Instance()->GetParticle(mcTrk->GetPdgCode());
1003 const std::array<float, 3> xyz{(float)mcTrk->
GetStartVertexCoordinatesX(), (float)mcTrk->GetStartVertexCoordinatesY(), (float)mcTrk->GetStartVertexCoordinatesZ()};
1004 const std::array<float, 3> pxyz{(float)mcTrk->GetStartVertexMomentumX(), (float)mcTrk->GetStartVertexMomentumY(), (float)mcTrk->GetStartVertexMomentumZ()};
1005 const int mcCharge = TMath::Nint(pPDG->Charge() / 3);
1010 if (!mcTrkAtX.rotate(tInt.getAlpha()) || !prop->PropagateToXBxByBz(mcTrkAtX, tInt.getX())) {
1013 auto phi = (layOut < 0) ? tInt.getPhi() : tInt.getPhiPos();
1014 o2::math_utils::bringTo02Pi(phi);
1018 getImpactParams(tInt, pv, ip, prop->getNominalBz());
1019 (*mDBGOut) << treeName
1021 <<
"mcTrk=" << mcTrkAtX
1025 <<
"dcaXY=" << ip[0]
1028 <<
"eta=" << tInt.getEta()
1046 for (
int i = 1;
i <= 7; ++
i) {
1051 if (!tFull.isValid() || !tFull.update(*clArr[
i])) {
1054 writeRow(tFull, 0.f, 0.f, -1);
1059 for (
int i = 0;
i <= 7;
i++) {
1065 if (!tInt.isValid()) {
1068 writeRow(tInt, clArr[
i]->
getY() - tInt.getY(), clArr[
i]->getZ() - tInt.getZ(),
i - 1);
1074 for (
size_t iTrk{0}; iTrk < itsTracks.size(); ++iTrk) {
1075 const auto& iTrack = itsTracks[iTrk];
1076 if (std::abs(iTrack.getEta()) > mParams->
maxEta || iTrack.getChi2() > mParams->
maxChi2 || iTrack.getNClusters() < mParams->
minITSCls || iTrack.getPt() < mParams->
minPt) {
1080 const auto& lbl = itsMC[iTrk];
1081 if (!lbl.isCorrect() || !lbl.isValid()) {
1085 const auto& mc = mMCReader.
getTrack(lbl);
1086 if (!mc->isPrimary()) {
1092 std::array<TrackingCluster, 8> cl;
1093 std::array<const TrackingCluster*, 8> clArr{
nullptr};
1096 const auto& eve = mMCReader.
getMCEventHeader(lbl.getSourceID(), lbl.getEventID());
1097 pv.setXYZ(eve.GetX(), eve.GetY(), eve.GetZ());
1099 auto trFitOut = iTrack.getParamIn();
1100 if (!prop->propagateToDCA(pv, trFitOut, prop->getNominalBz(), base::Propagator::MAX_STEP, mParams->
CorrType)) {
1103 pv.setSigmaX(20e-4f);
1104 pv.setSigmaY(20e-4f);
1105 pv.setSigmaZ(20e-4f);
1106 float cosAlp = NAN, sinAlp = NAN;
1107 o2::math_utils::sincos(trFitOut.getAlpha(), sinAlp, cosAlp);
1108 cl[0].alpha = trFitOut.getAlpha();
1109 cl[0].setXYZ((pv.getX() * cosAlp) + (pv.getY() * sinAlp), (-pv.getX() * sinAlp) + (pv.getY() * cosAlp), pv.getZ());
1110 cl[0].setErrors(0.5f * (pv.getSigmaX2() + pv.getSigmaY2()), pv.getSigmaZ2(), 0.f);
1111 cl[0].setSensorID(-1);
1116 int nCl = iTrack.getNClusters();
1117 for (
int i = 0;
i <
nCl;
i++) {
1119 int sens = curClu.getSensorID();
1120 int llr = geom->getLayer(sens);
1121 if (clArr[1 + llr]) {
1122 LOGP(fatal,
"Cluster at lr {} was already assigned, old sens {}, new sens {}", llr, clArr[1 + llr]->
getSensorID(), sens);
1124 clArr[1 + llr] = &curClu;
1126 std::array<o2::track::TrackParCov, 8> extrapOut, extrapInw;
1132 writeTree(
"idealRes", clArr, extrapOut, extrapInw, lbl);
1136 const auto mcTrk = mMCReader.
getTrack(lbl);
1140 std::array<float, 3> xyz{(float)mcTrk->
GetStartVertexCoordinatesX(), (float)mcTrk->GetStartVertexCoordinatesY(), (float)mcTrk->GetStartVertexCoordinatesZ()};
1141 std::array<float, 3> pxyz{(float)mcTrk->GetStartVertexMomentumX(), (float)mcTrk->GetStartVertexMomentumY(), (float)mcTrk->GetStartVertexMomentumZ()};
1142 TParticlePDG* pPDG = TDatabasePDG::Instance()->GetParticle(mcTrk->GetPdgCode());
1148 std::array<TrackingCluster, 3> misClArr;
1149 std::array<const TrackingCluster*, 8> clArrMis{};
1150 for (
int i = 0;
i <= 7;
i++) {
1151 clArrMis[
i] = clArr[
i];
1153 for (
int iLay = 0; iLay < 3; ++iLay) {
1154 if (!clArr[1 + iLay]) {
1157 const auto& orig = *clArr[1 + iLay];
1158 const int sens = orig.getSensorID();
1164 const auto& sensorMis = mMisalignment[sensorID];
1167 auto mcAtCl = mcPar;
1168 if (!mcAtCl.rotate(orig.alpha) || !prop->PropagateToXBxByBz(mcAtCl, orig.getX())) {
1169 clArrMis[1 + iLay] =
nullptr;
1172 const align::MisalignmentFrame misFrame{
1173 .sensorID = sensorID,
1176 .alpha = orig.alpha,
1180 align::MisalignmentShift totalShift;
1181 if (sensorMis.hasLegendre) {
1183 if (!shift.accepted) {
1184 clArrMis[1 + iLay] =
nullptr;
1187 totalShift += shift;
1189 if (sensorMis.hasInextensional) {
1194 misClArr[iLay] = orig;
1195 misClArr[iLay].setY(orig.getY() + totalShift.dy);
1196 misClArr[iLay].setZ(orig.getZ() + totalShift.dz);
1197 misClArr[iLay].setSigmaY2(orig.getSigmaY2() + (mParams->
misAlgExtCY[sensorID] * mParams->
misAlgExtCY[sensorID]));
1198 misClArr[iLay].setSigmaZ2(orig.getSigmaZ2() + (mParams->
misAlgExtCZ[sensorID] * mParams->
misAlgExtCZ[sensorID]));
1199 clArrMis[1 + iLay] = &misClArr[iLay];
1209 writeTree(
"misRes", clArrMis, extrapOut, extrapInw, lbl);
1214 LOGP(info,
"\tdoMisalignmentStudy: refitted {} out of {} tracks ({} !sel, {} !fit, {} !fitMis)", goodRefit, itsTracks.size(), notPassedSel, fitFail, fitFailMis);
1221 float x = pv.getX(),
y = pv.getY(),
z = pv.getZ();
1222 float f1 = trk.getSnp(), r1 = std::sqrt((1.f - f1) * (1.f + f1));
1223 float xt = trk.getX(), yt = trk.getY();
1224 float sn = std::sin(trk.getAlpha()), cs = std::cos(trk.getAlpha());
1225 float a = (
x * cs) + (
y * sn);
1226 y = (-
x * sn) + (
y * cs);
1230 float rp4 = trk.getCurvature(bz);
1231 if ((std::abs(bz) < o2::constants::math::Almost0) || (std::abs(rp4) < o2::constants::math::Almost0)) {
1232 ip[0] = -((xt *
f1) - (yt * r1));
1233 ip[1] = trk.getZ() + ((ip[0] *
f1 - xt) / r1 * trk.getTgl()) -
z;
1236 sn = (rp4 * xt) - f1;
1237 cs = (rp4 * yt) + r1;
1238 a = (2 * (xt *
f1 - yt * r1)) - (rp4 * (xt * xt + yt * yt));
1239 float rr = std::sqrt((sn * sn) + (cs * cs));
1240 ip[0] = -
a / (1 + rr);
1241 float f2 = -sn / rr, r2 = std::sqrt((1.f - f2) * (1.f + f2));
1242 ip[1] = trk.getZ() + (trk.getTgl() / rp4 * std::asin((f2 * r1) - (f1 * r2))) -
z;
1247 std::vector<OutputSpec> outputs;
1248 auto dataRequest = std::make_shared<DataRequest>();
1250 dataRequest->requestTracks(srcTracks, useMC);
1251 dataRequest->requestIT3Clusters(useMC);
1252 dataRequest->requestClusters(srcClusters, useMC);
1254 dataRequest->requestPrimaryVertices(useMC);
1256 auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(
false,
1262 dataRequest->inputs,
1266 .
name =
"its3-track-study",
1267 .inputs = dataRequest->inputs,
1269 .algorithm =
AlgorithmSpec{adaptFromTask<TrackingStudySpec>(dataRequest, ggRequest, srcTracks, useMC, withPV)},
Definition of the GeometryManager class.
Definition of the ITSMFT Hit class.
Definition of the BuildTopologyDictionary class for ITS3.
Helper for geometry and GRP related CCDB requests.
Global index for barrel track: provides provenance (detectors combination), index in respective array...
Definition of the GeometryTGeo class.
Utility functions for MC particles.
Wrapper container for different reconstructed object types.
o2::track::TrackParCov TrackParCov
Referenc on track indices contributing to the vertex, with possibility chose tracks from specific sou...
Double_t GetStartVertexCoordinatesX() const
static TDatabasePDG * Instance()
void checkUpdates(o2::framework::ProcessingContext &pc)
static GRPGeomHelper & instance()
void setRequest(std::shared_ptr< GRPGeomRequest > req)
static std::string getCollisionContextFileName(const std::string_view prefix="")
GPUd() value_type estimateLTFast(o2 static GPUd() float estimateLTIncrement(const o2 PropagatorImpl * Instance(bool uninitialized=false)
void printKeyValues(bool showProv=true, bool useLogger=false, bool withPadding=true, bool showHash=true) const final
static const ITS3TrackingStudyParam & Instance()
Static class with identifiers, bitmasks and names for ALICE detectors.
int ID
Detector identifiers: continuous, starting from 0.
ServiceRegistryRef services()
void finaliseCCDB(ConcreteDataMatcher &matcher, void *obj) final
TrackingStudySpec & operator=(TrackingStudySpec &&)=delete
void run(ProcessingContext &pc) final
void endOfStream(EndOfStreamContext &ec) final
This is invoked whenever we have an EndOfStream event.
TrackingStudySpec(const TrackingStudySpec &)=delete
void init(InitContext &ic) final
TrackingStudySpec(TrackingStudySpec &&)=delete
~TrackingStudySpec() final=default
TrackingStudySpec(std::shared_ptr< DataRequest > dr, std::shared_ptr< o2::base::GRPGeomRequest > gr, GTrackID::mask_t src, bool useMC, bool withPV)
TrackingStudySpec & operator=(const TrackingStudySpec &)=delete
static GeometryTGeo * Instance()
int getLayer(int index) const final
Get chip layer, from 0.
void fillMatrixCache(int mask) override
int getClusterEntry(int i) const
bool initFromDigitContext(std::string_view filename)
MCTrack const * getTrack(o2::MCCompLabel const &) const
size_t getNEvents(int source) const
Get number of events.
o2::dataformats::MCEventHeader const & getMCEventHeader(int source, int event) const
retrieves the MCEventHeader for a given eventID and sourceID
std::vector< MCTrack > const & getTracks(int source, int event) const
variant returning all tracks for source and event at once
bool prepareVertexRefit(const TR &tracks, const o2d::VertexBase &vtxSeed)
PVertex refitVertex(const std::vector< bool > useTrack, const o2d::VertexBase &vtxSeed)
GLfloat GLfloat GLfloat alpha
GLenum GLuint GLint GLint layer
GLboolean GLboolean GLboolean GLboolean a
GLdouble GLdouble GLdouble z
Defining ITS Vertex explicitly as messageable.
MisalignmentShift evaluateInextensionalShift(const SensorMisalignment &sensor, const MisalignmentFrame &frame, const TrackSlopes &slopes)
bool doBidirRefit(const o2::its::TrackITS &iTrack, std::array< const TrackingCluster< T > *, 8 > &clArr, std::array< o2::track::TrackParametrizationWithError< T >, 8 > &extrapOut, std::array< o2::track::TrackParametrizationWithError< T >, 8 > &extrapInw, T &chi2, bool useStableRef, typename o2::base::PropagatorImpl< T >::MatCorrType corrType)
MisalignmentModel loadMisalignmentModel(const std::string &jsonPath)
o2::track::TrackParametrizationWithError< T > interpolateTrackParCov(const o2::track::TrackParametrizationWithError< T > &tA, const o2::track::TrackParametrizationWithError< T > &tB)
MisalignmentShift evaluateLegendreShift(const SensorMisalignment &sensor, const MisalignmentFrame &frame, const TrackSlopes &slopes)
TrackSlopes computeTrackSlopes(double snp, double tgl)
T getDetID2Layer(T detID)
o2::math_utils::Point3D< T > extractClusterData(const itsmft::CompClusterExt &c, iterator &iter, const o2::its3::TopologyDictionary *dict, T &sig2y, T &sig2z)
o2::framework::DataProcessorSpec getTrackingStudySpec(o2::dataformats::GlobalTrackID::mask_t srcTracks, o2::dataformats::GlobalTrackID::mask_t srcClus, bool useMC, bool withPV)
std::unordered_map< GTrackID, size_t > T2VMap
o2::dataformats::GlobalTrackID GTrackID
o2::track::TrackParCov int int int float int nCl
const TrackingFrameInfo *const const Cluster *const const float const float bz
double * getX(double *xyDxy, int N)
double * getY(double *xyDxy, int N)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
auto getITSTracks() const
bool isTrackSourceLoaded(int src) const
GlobalIDSet getSingleDetectorRefs(GTrackID gidx) const
const o2::tpc::TrackTPC & getTPCTrack(GTrackID id) const
auto getITSClustersMCLabels() const
auto getITSTPCTOFMatches() const
auto getITSTPCTRDTracksMCLabels() const
auto getITSTracksClusterRefs() const
auto getPrimaryVertices() const
auto getPrimaryVertexMatchedTracks() const
auto getTPCITSTracks() const
void createTracksVariadic(T creator, GTrackID::mask_t srcSel=GTrackID::getSourcesMask("all")) const
auto getPrimaryVertexMatchedTrackRefs() const
auto getITSClustersPatterns() const
o2::MCCompLabel getTrackMCLabel(GTrackID id) const
auto getTOFClustersMCLabels() const
const o2::track::TrackParCov & getTrackParam(GTrackID gidx) const
const o2::MCEventLabel & getPrimaryVertexMCLabel(int i) const
void collectData(o2::framework::ProcessingContext &pc, const DataRequest &request)
const o2::track::TrackParCov & getTrackParamOut(GTrackID gidx) const
const o2::its::TrackITS & getITSTrack(GTrackID gid) const
auto getITSTPCTRDTOFMatches() const
std::array< GTrackID, GTrackID::NSources > GlobalIDSet
auto getITSTracksMCLabels() const
auto getITSClusters() const
int minTPCCls
TPC track selection.
o2::base::PropagatorImpl< float >::MatCorrType CorrType
float maxChi2
general track selection
int minPVCont
PV selection.
int minITSCls
ITS track selection.
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< Cluster > clusters