15#include <TStopwatch.h>
60using T2VMap = std::unordered_map<GTrackID, size_t>;
70 : mDataRequest(dr), mGGCCDBRequest(gr), mTracksSrc(
src), mUseMC(useMC) {}
80 void prepareITSClusters();
81 bool selectTrack(
GTrackID trkID,
bool checkMCTruth = true) const;
82 T2VMap buildT2V(
bool includeCont = false,
bool requireMCMatch = true) const;
86 void doDCARefitStudy();
90 void doMisalignmentStudy();
93 TrackCounter() =
default;
95 void operator+=(
int src)
97 if (
src >= 0 &&
src <
static_cast<int>(mSuccess.size())) {
102 void operator-=(
int src)
104 if (
src >= 0 &&
src <
static_cast<int>(mirrors.size())) {
109 void operator&=(
int src)
111 if (
src >= 0 &&
src <
static_cast<int>(mRejected.size())) {
118 LOGP(info,
"\t\t\tSuccess / Error / Rejected");
120 const auto cdm = GTrackID::getSourceDetectorsMask(cis);
122 LOGP(info,
"\t{:{}}\t{} / {} / {}",
GTrackID::getSourceName(cis), 15, mSuccess[cis], mirrors[cis], mRejected[cis]);
134 std::array<size_t, GTrackID::NSources> mSuccess{};
135 std::array<size_t, GTrackID::NSources> mirrors{};
136 std::array<size_t, GTrackID::NSources> mRejected{};
138 TrackCounter mTrackCounter;
141 std::vector<TrackingCluster> mITScl;
142 std::span<const int> mITSclRef;
145 std::unique_ptr<o2::utils::TreeStreamRedirector> mDBGOut;
146 std::shared_ptr<DataRequest> mDataRequest;
147 std::shared_ptr<o2::base::GRPGeomRequest> mGGCCDBRequest;
154 align::MisalignmentModel mMisalignment;
162 std::string dbgnm = maxLanes == 1 ?
"its3TrackStudy.root" : fmt::format(
"its3TrackStudy_{}.root", lane);
163 mDBGOut = std::make_unique<o2::utils::TreeStreamRedirector>(dbgnm.c_str(),
"recreate");
166 LOGP(fatal,
"initialization of MCKinematicsReader failed");
173 updateTimeDependentParams(pc);
180 if (
static bool initOnceDone{
false}; !initOnceDone) {
206 LOG(info) <<
"cluster dictionary updated";
212void TrackingStudySpec::process()
214 prepareITSClusters();
215 if (mParams->
doDCA) {
221 if (mUseMC && mParams->
doPull) {
224 if (mUseMC && mParams->
doMC) {
231 doMisalignmentStudy();
235void TrackingStudySpec::prepareITSClusters()
238 LOGP(info,
"Preparing {} measurments", clusITS.size());
240 mITScl.reserve(clusITS.size());
241 auto pattIt = patterns.begin();
245 mITScl.reserve(clusITS.size());
246 for (
const auto& cls : clusITS) {
247 const auto sens = cls.getSensorID();
248 float sigmaY2{0}, sigmaZ2{0};
251 const auto gloXYZ = geom->getMatrixL2G(sens) * locXYZ;
258 float alpha = geom->getSensorRefAlpha(sens);
262 trkXYZ.SetX(std::hypot(gloXYZ.x(), gloXYZ.y()));
263 alpha = std::atan2(gloXYZ.y(), gloXYZ.x());
265 auto& cl3d = mITScl.emplace_back(sens, trkXYZ);
266 cl3d.setErrors(sigmaY2, sigmaZ2, 0.f);
268 math_utils::detail::bringToPMPi(cl3d.alpha);
272bool TrackingStudySpec::selectTrack(
GTrackID trkID,
bool checkMCTruth)
const
286 if (itsTrk.getChi2() > mParams->
maxChi2 || itsTrk.getNClusters() < mParams->
minITSCls) {
292 if (tpcTrk.getNClusters() < mParams->
minTPCCls) {
298 if (gTrk.getPt() < mParams->
minPt || gTrk.getPt() > mParams->
maxPt) {
301 if (std::abs(gTrk.getEta()) > mParams->
maxEta) {
304 if (mUseMC && checkMCTruth) {
306 if (!itsLbl.isValid()) {
311 if (itsLbl != tpcLbl) {
320 for (
const auto& lbl : tofLbls) {
330T2VMap TrackingStudySpec::buildT2V(
bool includeCont,
bool requireMCMatch)
const
336 auto nv = vtxRefs.size() - 1;
338 for (
size_t iv = 0; iv < nv; ++iv) {
339 const auto& pv = pvvec[iv];
340 if (pv.getNContributors() - 1 < mParams->
minPVCont) {
343 if (requireMCMatch) {
346 const auto& vtxRef = vtxRefs[iv];
347 int it = vtxRef.getFirstEntry(), itLim = it + vtxRef.getEntries();
348 for (; it < itLim; it++) {
349 const auto& tvid = trackIndex[it];
350 if (tvid.isAmbiguous()) {
356 if (mUseMC && requireMCMatch) {
366 const auto cdm = GTrackID::getSourceDetectorsMask(cis);
370 if (mUseMC && requireMCMatch) {
376 t2v[contributorsGID[cis]] = iv;
381 return std::move(t2v);
390 static auto t2v = buildT2V(
true,
true);
391 static std::vector<unsigned int> itsTracksROF;
392 if (
static bool done{
false}; !
done) {
396 for (
unsigned irf = 0, cnt = 0; irf < itsTracksROFRec.size(); irf++) {
397 int ntr = itsTracksROFRec[irf].getNEntries();
398 for (
int itr = 0; itr < ntr; itr++) {
399 itsTracksROF[cnt++] = irf;
404 std::array<const TrackingCluster*, 8> clArr{
nullptr};
407 const auto& itsTrOrig = mRecoData.
getITSTrack(gidx);
408 int ncl = itsTrOrig.getNumberOfClusters(), rof = itsTracksROF[gidx.getIndex()];
410 int clEntry = itsTrOrig.getFirstClusterEntry();
413 const auto& pv = pvvec[t2v[gidx]];
415 if (!prop->propagateToDCA(pv, trkPV, prop->getNominalBz(), 2.0, mParams->
CorrType)) {
416 mTrackCounter -= gidx.getSource();
420 float cosAlp = NAN, sinAlp = NAN;
421 o2::math_utils::sincos(trkPV.getAlpha(), sinAlp, cosAlp);
423 TrackingCluster pvCls;
424 pvCls.setXYZ((pv.getX() * cosAlp) + (pv.getY() * sinAlp), (-pv.getX() * sinAlp) + (pv.getY() * cosAlp), pv.getZ());
425 pvCls.setSigmaY2(0.5f * (pv.getSigmaX2() + pv.getSigmaY2()));
426 pvCls.setSigmaZ2(pv.getSigmaZ2());
428 for (
int icl = 0; icl < ncl; ++icl) {
429 clArr[ncl - icl] = &mITScl[itsTrackClusRefs[clEntry + icl]];
433 trFit.resetCovariance(1'000);
435 for (
int icl = ncl; icl >= 0; --icl) {
436 if (!trFit.rotate(clArr[icl]->alpha) || !prop->propagateToX(trFit, clArr[icl]->getX(), prop->getNominalBz(), 0.85, 2.0, mParams->
CorrType)) {
437 mTrackCounter -= gidx.getSource();
440 chi2 += trFit.getPredictedChi2(*clArr[icl]);
441 if (!trFit.update(*clArr[icl])) {
442 mTrackCounter -= gidx.getSource();
450void TrackingStudySpec::doDCAStudy()
453 LOGP(info,
"Doing DCA study");
454 mTrackCounter.reset();
458 int nDCAFits{0}, nDCAFitsFail{0};
462 auto nv = vtxRefs.size() - 1;
463 auto&
stream = (*mDBGOut) <<
"dca";
464 for (
int iv = 0; iv < nv; iv++) {
465 const auto& pv = pvvec[iv];
466 const auto& vtref = vtxRefs[iv];
468 const auto dm = GTrackID::getSourceDetectorsMask(is);
473 int idMin = vtref.getFirstEntryOfSource(is), idMax = idMin + vtref.getEntriesOfSource(is);
474 for (
int i = idMin;
i < idMax;
i++) {
475 const auto vid = trackIndex[
i];
476 if (!vid.isPVContributor()) {
477 mTrackCounter &= vid.getSource();
485 const auto cdm = GTrackID::getSourceDetectorsMask(cis);
487 mTrackCounter &= cis;
490 if (!selectTrack(contributorsGID[cis])) {
491 mTrackCounter &= vid.getSource();
496 const auto& trk = mRecoData.
getTrackParam(contributorsGID[cis]);
500 mTrackCounter -= cis;
503 trkRefit.invalidate();
507 if (!prop->propagateToDCABxByBz(pv, trkDCA, 2.f, mParams->
CorrType, &dcaInfo)) {
508 mTrackCounter -= cis;
516 <<
"trkRefit=" << trkRefit
517 <<
"trkAtPV=" << trkDCA
518 <<
"dca=" << dcaInfo;
524 const auto& eve = mMCReader.
getMCEventHeader(lbl.getSourceID(), lbl.getEventID());
526 mcEve.setPos({(float)eve.GetX(), (float)eve.GetY(), (float)eve.GetZ()});
528 if (!prop->propagateToDCABxByBz(mcEve, trkC, 2.f, mParams->
CorrType, &dcaInfoMC)) {
529 mTrackCounter -= cis;
533 const auto& mcTrk = mMCReader.
getTrack(lbl);
534 if (mcTrk ==
nullptr) {
535 LOGP(fatal,
"mcTrk is null did selection fail?");
537 stream <<
"mcTrk=" << *mcTrk
538 <<
"dca2MC=" << dcaInfoMC
544 mTrackCounter += cis;
550 LOGP(info,
"doDCAStudy: accepted {} fits, failed {} (in {:.2f} seconds)", nDCAFits, nDCAFitsFail,
sw.RealTime());
551 mTrackCounter.print();
554void TrackingStudySpec::doDCARefitStudy()
557 LOGP(info,
"Doing DCARefit study");
558 mTrackCounter.reset();
566 auto nv = vtxRefs.size() - 1;
567 auto t2v = buildT2V();
568 std::vector<std::vector<GTrackID>> v2t;
570 auto creator = [&](
const auto& trk,
GTrackID trkID,
float _t0,
float terr) ->
bool {
571 if constexpr (!isBarrelTrack<decltype(trk)>()) {
572 mTrackCounter &= trkID.getSource();
576 mTrackCounter &= trkID.getSource();
580 if constexpr (isBarrelTrack<decltype(trk)>()) {
581 if (trk.getPt() < mParams->
minPt || trk.getPt() > mParams->
maxPt) {
582 mTrackCounter &= trkID.getSource();
585 if (std::abs(trk.getEta()) > mParams->
maxEta) {
586 mTrackCounter &= trkID.getSource();
589 if (!t2v.contains(trkID)) {
590 mTrackCounter &= trkID.getSource();
593 if (!selectTrack(trkID, mUseMC)) {
594 mTrackCounter &= trkID.getSource();
598 v2t[t2v[trkID]].push_back(trkID);
603 int nDCAFits{0}, nDCAFitsFail{0};
604 auto&
stream = (*mDBGOut) <<
"dcaRefit";
605 for (
size_t iv = 0; iv < nv; ++iv) {
606 const auto& pv = pvvec[iv];
607 const auto& trkIDs = v2t[iv];
608 if (trkIDs.size() - 1 < mParams->
minPVCont) {
611 std::vector<o2::track::TrackParCov> trks;
612 trks.reserve(trkIDs.size());
613 for (
const auto& trkID : trkIDs) {
620 std::vector<bool>
trkMask(trkIDs.size(),
true);
621 for (
size_t it{0}; it <
trkMask.size(); ++it) {
627 if (pvRefit.getChi2() < 0) {
634 auto trkC = trks[it];
635 if (!prop->propagateToDCABxByBz(pv, trkC, 2.f, mParams->
CorrType, &dcaInfo)) {
636 mTrackCounter -= trkIDs[it].getSource();
641 auto trkCRefit = trks[it];
642 if (!prop->propagateToDCABxByBz(pv, trkCRefit, 2.f, mParams->
CorrType, &dcaInfoRefit)) {
643 mTrackCounter -= trkIDs[it].getSource();
648 stream <<
"src=" << trkIDs[it].getSource()
650 <<
"trkAtPV=" << trkC
652 <<
"pvRefit=" << pvRefit
653 <<
"trkAtPVRefit=" << trkC
654 <<
"dcaRefit=" << dcaInfoRefit;
657 if (mcTrk ==
nullptr) {
658 LOGP(fatal,
"mcTrk is null did selection fail?");
660 stream <<
"mcTrk=" << *mcTrk;
664 mTrackCounter += trkIDs[it].getSource();
668 LOGP(info,
"doDCARefitStudy: accepted {} fits, failed {} (in {:.2f} seconds)", nDCAFits, nDCAFitsFail,
sw.RealTime());
669 mTrackCounter.print();
672void TrackingStudySpec::doPullStudy()
675 LOGP(info,
"Doing Pull study");
676 mTrackCounter.reset();
679 int nPulls{0}, nPullsFail{0};
682 auto checkInTrack = [&](
GTrackID trkID) {
683 if (!selectTrack(trkID)) {
684 mTrackCounter &= trkID.getSource();
695 mTrackCounter -= trkID.getSource();
700 std::array<float, 3> xyz{(float)mcTrk->GetStartVertexCoordinatesX(), (float)mcTrk->GetStartVertexCoordinatesY(), (float)mcTrk->GetStartVertexCoordinatesZ()},
701 pxyz{(float)mcTrk->GetStartVertexMomentumX(), (float)mcTrk->GetStartVertexMomentumY(), (float)mcTrk->GetStartVertexMomentumZ()};
702 TParticlePDG* pPDG = TDatabasePDG::Instance()->GetParticle(mcTrk->GetPdgCode());
704 mTrackCounter -= trkID.getSource();
710 if (!mcTrkO2.rotate(trk.getAlpha()) || !prop->PropagateToXBxByBz(mcTrkO2, trk.getX())) {
711 mTrackCounter -= trkID.getSource();
720 <<
"src=" << trkID.getSource()
721 <<
"itsTrk=" << itsTrk
722 <<
"mcTrk=" << mcTrkO2
723 <<
"mcPart=" << mcTrk
727 mTrackCounter += trkID.getSource();
746 LOGP(info,
"doPullStudy: accepted {} pulls; rejected {} (in {:.2f} seconds)", nPulls, nPullsFail,
sw.RealTime());
747 mTrackCounter.print();
750void TrackingStudySpec::doMCStudy()
752 LOGP(info,
"Doing MC study");
753 mTrackCounter.reset();
760 std::unordered_map<o2::MCCompLabel, ParticleInfoExt> info;
762 LOGP(info,
"** Filling particle table ... ");
763 for (
int iEve{0}; iEve < nev; ++iEve) {
764 const auto& mcTrks = mMCReader.
getTracks(iSrc, iEve);
765 for (
int iTrk{0}; iTrk < mcTrks.size(); ++iTrk) {
766 const auto& mcTrk = mcTrks[iTrk];
767 const auto pdg = mcTrk.GetPdgCode();
771 const auto apdg = std::abs(pdg);
772 if (apdg != 11 && apdg != 211 && apdg != 321 && apdg != 2212) {
776 auto& part = info[lbl];
777 part.mcTrack = mcTrk;
780 LOGP(info,
"** Creating particle/clusters correspondence ... ");
783 for (
auto iCluster{0}; iCluster <
clusters.size(); ++iCluster) {
784 auto labs = clustersMCLCont->getLabels(iCluster);
785 for (
auto& lab : labs) {
786 if (!lab.isValid() || lab.getSourceID() != 0 || !lab.isCorrect()) {
789 int trackID = 0, evID = 0, srcID = 0;
791 lab.get(trackID, evID, srcID, fake);
794 auto& part = info[{trackID, evID, srcID}];
795 part.clusters |= (1 <<
layer);
797 part.fakeClusters |= (1 <<
layer);
801 LOGP(info,
"** Analysing tracks ... ");
803 if (contributorsGID[det].isIndexSet()) {
806 o2::MCCompLabel iLbl(lbl.getTrackID(), lbl.getEventID(), lbl.getSourceID());
807 if (info.contains(iLbl)) {
808 auto& part = info[iLbl];
809 SETBIT(part.recoTracks, det);
811 SETBIT(part.fakeTracks, det);
817 auto creator = [&](
const auto& trk,
GTrackID trkID,
float _t0,
float terr) ->
bool {
818 if constexpr (!isBarrelTrack<decltype(trk)>()) {
830 if (!gLbl.isValid()) {
833 o2::MCCompLabel iLbl(gLbl.getTrackID(), gLbl.getEventID(), gLbl.getSourceID());
834 if (!info.contains(iLbl)) {
837 auto& part = info[iLbl];
850 LOGP(info,
"Streaming output to tree");
851 for (
const auto& [_, part] : info) {
858 LOGP(info,
"doMCStudy: accounted {} MCParticles and {} tracks (in {:.2f} seconds)", info.size(), nTracks,
sw.RealTime());
861void TrackingStudySpec::doResidStudy()
863 LOGP(info,
"Doing residual study");
866 const float bz = prop->getNominalBz();
868 int goodRefit{0}, notPassedSel{0}, fitFail{0};
871 std::array<TrackingCluster, 8> cl;
872 std::array<const TrackingCluster*, 8> clArr{
nullptr};
874 const auto& eve = mMCReader.
getMCEventHeader(lbl.getSourceID(), lbl.getEventID());
876 auto trFitOut = iTrack.getParamIn();
877 pv.setXYZ(eve.GetX(), eve.GetY(), eve.GetZ());
881 pv.setSigmaX(20e-4f);
882 pv.setSigmaY(20e-4f);
883 pv.setSigmaZ(20e-4f);
884 float cosAlp = NAN, sinAlp = NAN;
885 o2::math_utils::sincos(trFitOut.getAlpha(), sinAlp, cosAlp);
886 cl[0].alpha = trFitOut.getAlpha();
887 cl[0].setXYZ((pv.getX() * cosAlp) + (pv.getY() * sinAlp), (-pv.getX() * sinAlp) + (pv.getY() * cosAlp), pv.getZ());
888 cl[0].setSigmaY2(0.5f * (pv.getSigmaX2() + pv.getSigmaY2()));
889 cl[0].setSigmaZ2(pv.getSigmaZ2());
890 cl[0].setSensorID(-1);
895 int nCl = iTrack.getNClusters();
896 for (
int i = 0;
i < nCl;
i++) {
898 int sens = curClu.getSensorID();
899 int llr = geom->getLayer(sens);
900 if (clArr[1 + llr]) {
901 LOGP(fatal,
"Cluster at lr {} was already assigned, old sens {}, new sens {}", llr, clArr[1 + llr]->
getSensorID(), sens);
903 clArr[1 + llr] = &curClu;
906 std::array<o2::track::TrackParCov, 8> extrapOut, extrapInw;
913 for (
int i = 0;
i <= 7;
i++) {
916 if (!tInt.isValid()) {
919 auto phi =
i == 0 ? tInt.getPhi() : tInt.getPhiPos();
920 o2::math_utils::bringTo02Pi(phi);
922 <<
"dYInt=" << clArr[
i]->getY() - tInt.getY()
923 <<
"dZInt=" << clArr[
i]->getZ() - tInt.getZ()
924 <<
"dYIn=" << clArr[
i]->getY() - extrapInw[
i].getY()
925 <<
"dZIn=" << clArr[
i]->getZ() - extrapInw[
i].getZ()
926 <<
"dYOut=" << clArr[
i]->getY() - extrapOut[
i].getY()
927 <<
"dZOut=" << clArr[
i]->getZ() - extrapOut[
i].getZ()
929 <<
"clY=" << clArr[
i]->getY()
930 <<
"clZ=" << clArr[
i]->getZ()
931 <<
"clX=" << clArr[
i]->getX()
932 <<
"alpha=" << clArr[
i]->alpha
933 <<
"sens=" << clArr[
i]->getSensorID()
935 <<
"pt=" << tInt.getPt()
946 for (
size_t iTrk{0}; iTrk < itsTracks.size(); ++iTrk) {
947 const auto& iTrack = itsTracks[iTrk];
948 const auto& lbl = itsMC[iTrk];
949 const auto& mc = mMCReader.
getTrack(lbl);
950 if (std::abs(iTrack.getEta()) > mParams->
maxEta || iTrack.getChi2() > mParams->
maxChi2 || iTrack.getNClusters() < mParams->
minITSCls || iTrack.getPt() < mParams->
minPt || !lbl.isCorrect() || !mc->isPrimary()) {
954 doRefits(iTrack, lbl);
957 LOGP(info,
"\trefitted {} out of {} tracks ({} !sel, {} !fit)", goodRefit, itsTracks.size(), notPassedSel, fitFail);
960void TrackingStudySpec::doMisalignmentStudy()
962 LOGP(info,
"Doing misalignment study");
966 int goodRefit{0}, notPassedSel{0}, fitFail{0}, fitFailMis{0};
969 auto writeTree = [&](
const char* treeName,
970 const std::array<const TrackingCluster*, 8>& clArr,
971 const std::array<o2::track::TrackParCov, 8>& extrapOut,
972 const std::array<o2::track::TrackParCov, 8>& extrapInw,
974 for (
int i = 0;
i <= 7;
i++) {
980 if (!tInt.isValid()) {
983 float dY = clArr[
i]->getY() - tInt.getY();
984 float dZ = clArr[
i]->getZ() - tInt.getZ();
987 const auto mcTrk = mMCReader.
getTrack(lbl);
989 std::array<float, 3> xyz{(float)mcTrk->
GetStartVertexCoordinatesX(), (float)mcTrk->GetStartVertexCoordinatesY(), (float)mcTrk->GetStartVertexCoordinatesZ()};
990 std::array<float, 3> pxyz{(float)mcTrk->GetStartVertexMomentumX(), (float)mcTrk->GetStartVertexMomentumY(), (float)mcTrk->GetStartVertexMomentumZ()};
991 TParticlePDG* pPDG = TDatabasePDG::Instance()->GetParticle(mcTrk->GetPdgCode());
994 if (mcTrkAtX.rotate(tInt.getAlpha()) && prop->PropagateToXBxByBz(mcTrkAtX, tInt.getX())) {
995 auto phi =
i == 0 ? tInt.getPhi() : tInt.getPhiPos();
996 o2::math_utils::bringTo02Pi(phi);
997 (*mDBGOut) << treeName
999 <<
"mcTrk=" << mcTrkAtX
1004 <<
"eta=" << tInt.getEta()
1015 for (
size_t iTrk{0}; iTrk < itsTracks.size(); ++iTrk) {
1016 const auto& iTrack = itsTracks[iTrk];
1017 if (std::abs(iTrack.getEta()) > mParams->
maxEta || iTrack.getChi2() > mParams->
maxChi2 || iTrack.getNClusters() < mParams->
minITSCls || iTrack.getPt() < mParams->
minPt) {
1021 const auto& lbl = itsMC[iTrk];
1022 if (!lbl.isCorrect() || !lbl.isValid()) {
1026 const auto& mc = mMCReader.
getTrack(lbl);
1027 if (!mc->isPrimary()) {
1033 std::array<TrackingCluster, 8> cl;
1034 std::array<const TrackingCluster*, 8> clArr{
nullptr};
1036 const auto& eve = mMCReader.
getMCEventHeader(lbl.getSourceID(), lbl.getEventID());
1038 auto trFitOut = iTrack.getParamIn();
1039 pv.setXYZ(eve.GetX(), eve.GetY(), eve.GetZ());
1043 pv.setSigmaX(20e-4f);
1044 pv.setSigmaY(20e-4f);
1045 pv.setSigmaZ(20e-4f);
1046 float cosAlp = NAN, sinAlp = NAN;
1047 o2::math_utils::sincos(trFitOut.getAlpha(), sinAlp, cosAlp);
1048 cl[0].alpha = trFitOut.getAlpha();
1049 cl[0].setXYZ((pv.getX() * cosAlp) + (pv.getY() * sinAlp), (-pv.getX() * sinAlp) + (pv.getY() * cosAlp), pv.getZ());
1050 cl[0].setSigmaY2(0.5f * (pv.getSigmaX2() + pv.getSigmaY2()));
1051 cl[0].setSigmaZ2(pv.getSigmaZ2());
1052 cl[0].setSensorID(-1);
1057 int nCl = iTrack.getNClusters();
1058 for (
int i = 0;
i < nCl;
i++) {
1060 int sens = curClu.getSensorID();
1061 int llr = geom->getLayer(sens);
1062 if (clArr[1 + llr]) {
1063 LOGP(fatal,
"Cluster at lr {} was already assigned, old sens {}, new sens {}", llr, clArr[1 + llr]->
getSensorID(), sens);
1065 clArr[1 + llr] = &curClu;
1067 std::array<o2::track::TrackParCov, 8> extrapOut, extrapInw;
1073 writeTree(
"idealRes", clArr, extrapOut, extrapInw, lbl);
1077 const auto mcTrk = mMCReader.
getTrack(lbl);
1081 std::array<float, 3> xyz{(float)mcTrk->
GetStartVertexCoordinatesX(), (float)mcTrk->GetStartVertexCoordinatesY(), (float)mcTrk->GetStartVertexCoordinatesZ()};
1082 std::array<float, 3> pxyz{(float)mcTrk->GetStartVertexMomentumX(), (float)mcTrk->GetStartVertexMomentumY(), (float)mcTrk->GetStartVertexMomentumZ()};
1083 TParticlePDG* pPDG = TDatabasePDG::Instance()->GetParticle(mcTrk->GetPdgCode());
1089 std::array<TrackingCluster, 3> misClArr;
1090 std::array<const TrackingCluster*, 8> clArrMis{};
1091 for (
int i = 0;
i <= 7;
i++) {
1092 clArrMis[
i] = clArr[
i];
1094 for (
int iLay = 0; iLay < 3; ++iLay) {
1095 if (!clArr[1 + iLay]) {
1098 const auto& orig = *clArr[1 + iLay];
1099 const int sens = orig.getSensorID();
1105 const auto& sensorMis = mMisalignment[sensorID];
1108 auto mcAtCl = mcPar;
1109 if (!mcAtCl.rotate(orig.alpha) || !prop->PropagateToXBxByBz(mcAtCl, orig.getX())) {
1110 clArrMis[1 + iLay] =
nullptr;
1113 const align::MisalignmentFrame misFrame{
1114 .sensorID = sensorID,
1117 .alpha = orig.alpha,
1121 align::MisalignmentShift totalShift;
1122 if (sensorMis.hasLegendre) {
1124 if (!shift.accepted) {
1125 clArrMis[1 + iLay] =
nullptr;
1128 totalShift += shift;
1130 if (sensorMis.hasInextensional) {
1135 misClArr[iLay] = orig;
1136 misClArr[iLay].setY(orig.getY() + totalShift.dy);
1137 misClArr[iLay].setZ(orig.getZ() + totalShift.dz);
1138 misClArr[iLay].setSigmaY2(orig.getSigmaY2() + (mParams->
misAlgExtCY[sensorID] * mParams->
misAlgExtCY[sensorID]));
1139 misClArr[iLay].setSigmaZ2(orig.getSigmaZ2() + (mParams->
misAlgExtCZ[sensorID] * mParams->
misAlgExtCZ[sensorID]));
1140 clArrMis[1 + iLay] = &misClArr[iLay];
1150 writeTree(
"misRes", clArrMis, extrapOut, extrapInw, lbl);
1155 LOGP(info,
"\tdoMisalignmentStudy: refitted {} out of {} tracks ({} !sel, {} !fit, {} !fitMis)", goodRefit, itsTracks.size(), notPassedSel, fitFail, fitFailMis);
1160 std::vector<OutputSpec> outputs;
1161 auto dataRequest = std::make_shared<DataRequest>();
1163 dataRequest->requestTracks(srcTracks, useMC);
1164 dataRequest->requestIT3Clusters(useMC);
1165 dataRequest->requestClusters(srcClusters, useMC);
1167 dataRequest->requestPrimaryVertices(useMC);
1169 auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(
false,
1175 dataRequest->inputs,
1179 .
name =
"its3-track-study",
1180 .inputs = dataRequest->inputs,
1182 .algorithm =
AlgorithmSpec{adaptFromTask<TrackingStudySpec>(dataRequest, ggRequest, srcTracks, useMC)},
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="")
static constexpr float MAX_STEP
GPUd() value_type estimateLTFast(o2 static GPUd() float estimateLTIncrement(const o2 PropagatorImpl * Instance(bool uninitialized=false)
static const ITS3TrackingStudyParam & Instance()
Static class with identifiers, bitmasks and names for ALICE detectors.
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)
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
Defining PrimaryVertex 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
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 getITSTracksROFRecords() 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