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);
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);
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);
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];
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};
885 const auto& eve = mMCReader.
getMCEventHeader(lbl.getSourceID(), lbl.getEventID());
886 auto trFitOut = iTrack.getParamIn();
887 pv.setXYZ(eve.GetX(), eve.GetY(), eve.GetZ());
891 pv.setSigmaX(20e-4f);
892 pv.setSigmaY(20e-4f);
893 pv.setSigmaZ(20e-4f);
894 float cosAlp = NAN, sinAlp = NAN;
895 o2::math_utils::sincos(trFitOut.getAlpha(), sinAlp, cosAlp);
896 cl[0].alpha = trFitOut.getAlpha();
897 cl[0].setXYZ((pv.getX() * cosAlp) + (pv.getY() * sinAlp), (-pv.getX() * sinAlp) + (pv.getY() * cosAlp), pv.getZ());
898 cl[0].setErrors(0.5f * (pv.getSigmaX2() + pv.getSigmaY2()), pv.getSigmaZ2(), 0.f);
899 cl[0].setSensorID(-1);
904 int nCl = iTrack.getNClusters();
905 for (
int i = 0;
i <
nCl;
i++) {
907 int sens = curClu.getSensorID();
908 int llr = geom->getLayer(sens);
909 if (clArr[1 + llr]) {
910 LOGP(fatal,
"Cluster at lr {} was already assigned, old sens {}, new sens {}", llr, clArr[1 + llr]->
getSensorID(), sens);
912 clArr[1 + llr] = &curClu;
915 std::array<o2::track::TrackParCov, 8> extrapOut, extrapInw;
922 for (
int i = 0;
i <= 7;
i++) {
925 if (!tInt.isValid()) {
928 auto phi =
i == 0 ? tInt.getPhi() : tInt.getPhiPos();
929 o2::math_utils::bringTo02Pi(phi);
931 getImpactParams(tInt, pv, ip, bz);
934 <<
"dYInt=" << clArr[
i]->getY() - tInt.getY()
935 <<
"dZInt=" << clArr[
i]->getZ() - tInt.getZ()
936 <<
"dYIn=" << clArr[
i]->getY() - extrapInw[
i].getY()
937 <<
"dZIn=" << clArr[
i]->getZ() - extrapInw[
i].getZ()
938 <<
"dYOut=" << clArr[
i]->getY() - extrapOut[
i].getY()
939 <<
"dZOut=" << clArr[
i]->getZ() - extrapOut[
i].getZ()
941 <<
"clY=" << clArr[
i]->getY()
942 <<
"clZ=" << clArr[
i]->getZ()
943 <<
"clX=" << clArr[
i]->getX()
944 <<
"alpha=" << clArr[
i]->alpha
945 <<
"sens=" << clArr[
i]->getSensorID()
949 <<
"pt=" << tInt.getPt()
960 for (
size_t iTrk{0}; iTrk < itsTracks.size(); ++iTrk) {
961 const auto& iTrack = itsTracks[iTrk];
962 const auto& lbl = itsMC[iTrk];
963 const auto& mc = mMCReader.
getTrack(lbl);
964 if (std::abs(iTrack.getEta()) > mParams->
maxEta || iTrack.getChi2() > mParams->
maxChi2 || iTrack.getNClusters() < mParams->
minITSCls || iTrack.getPt() < mParams->
minPt || !lbl.isCorrect() || !mc->isPrimary()) {
968 doRefits(iTrack, lbl);
971 LOGP(info,
"\trefitted {} out of {} tracks ({} !sel, {} !fit)", goodRefit, itsTracks.size(), notPassedSel, fitFail);
974void TrackingStudySpec::doMisalignmentStudy()
976 LOGP(info,
"Doing misalignment study");
980 int goodRefit{0}, notPassedSel{0}, fitFail{0}, fitFailMis{0};
984 auto writeTree = [&](
const char* treeName,
985 const std::array<const TrackingCluster*, 8>& clArr,
986 const std::array<o2::track::TrackParCov, 8>& extrapOut,
987 const std::array<o2::track::TrackParCov, 8>& extrapInw,
989 for (
int i = 0;
i <= 7;
i++) {
995 if (!tInt.isValid()) {
998 float dY = clArr[
i]->getY() - tInt.getY();
999 float dZ = clArr[
i]->getZ() - tInt.getZ();
1002 const auto mcTrk = mMCReader.
getTrack(lbl);
1004 std::array<float, 3> xyz{(float)mcTrk->
GetStartVertexCoordinatesX(), (float)mcTrk->GetStartVertexCoordinatesY(), (float)mcTrk->GetStartVertexCoordinatesZ()};
1005 std::array<float, 3> pxyz{(float)mcTrk->GetStartVertexMomentumX(), (float)mcTrk->GetStartVertexMomentumY(), (float)mcTrk->GetStartVertexMomentumZ()};
1006 TParticlePDG* pPDG = TDatabasePDG::Instance()->GetParticle(mcTrk->GetPdgCode());
1009 if (mcTrkAtX.rotate(tInt.getAlpha()) && prop->PropagateToXBxByBz(mcTrkAtX, tInt.getX())) {
1010 auto phi =
i == 0 ? tInt.getPhi() : tInt.getPhiPos();
1011 o2::math_utils::bringTo02Pi(phi);
1013 getImpactParams(tInt, pv, ip, prop->getNominalBz());
1015 (*mDBGOut) << treeName
1017 <<
"mcTrk=" << mcTrkAtX
1021 <<
"dcaXY=" << ip[0]
1024 <<
"eta=" << tInt.getEta()
1035 for (
size_t iTrk{0}; iTrk < itsTracks.size(); ++iTrk) {
1036 const auto& iTrack = itsTracks[iTrk];
1037 if (std::abs(iTrack.getEta()) > mParams->
maxEta || iTrack.getChi2() > mParams->
maxChi2 || iTrack.getNClusters() < mParams->
minITSCls || iTrack.getPt() < mParams->
minPt) {
1041 const auto& lbl = itsMC[iTrk];
1042 if (!lbl.isCorrect() || !lbl.isValid()) {
1046 const auto& mc = mMCReader.
getTrack(lbl);
1047 if (!mc->isPrimary()) {
1053 std::array<TrackingCluster, 8> cl;
1054 std::array<const TrackingCluster*, 8> clArr{
nullptr};
1056 const auto& eve = mMCReader.
getMCEventHeader(lbl.getSourceID(), lbl.getEventID());
1057 auto trFitOut = iTrack.getParamIn();
1058 pv.setXYZ(eve.GetX(), eve.GetY(), eve.GetZ());
1062 pv.setSigmaX(20e-4f);
1063 pv.setSigmaY(20e-4f);
1064 pv.setSigmaZ(20e-4f);
1065 float cosAlp = NAN, sinAlp = NAN;
1066 o2::math_utils::sincos(trFitOut.getAlpha(), sinAlp, cosAlp);
1067 cl[0].alpha = trFitOut.getAlpha();
1068 cl[0].setXYZ((pv.getX() * cosAlp) + (pv.getY() * sinAlp), (-pv.getX() * sinAlp) + (pv.getY() * cosAlp), pv.getZ());
1069 cl[0].setErrors(0.5f * (pv.getSigmaX2() + pv.getSigmaY2()), pv.getSigmaZ2(), 0.f);
1070 cl[0].setSensorID(-1);
1075 int nCl = iTrack.getNClusters();
1076 for (
int i = 0;
i <
nCl;
i++) {
1078 int sens = curClu.getSensorID();
1079 int llr = geom->getLayer(sens);
1080 if (clArr[1 + llr]) {
1081 LOGP(fatal,
"Cluster at lr {} was already assigned, old sens {}, new sens {}", llr, clArr[1 + llr]->
getSensorID(), sens);
1083 clArr[1 + llr] = &curClu;
1085 std::array<o2::track::TrackParCov, 8> extrapOut, extrapInw;
1091 writeTree(
"idealRes", clArr, extrapOut, extrapInw, lbl);
1095 const auto mcTrk = mMCReader.
getTrack(lbl);
1099 std::array<float, 3> xyz{(float)mcTrk->
GetStartVertexCoordinatesX(), (float)mcTrk->GetStartVertexCoordinatesY(), (float)mcTrk->GetStartVertexCoordinatesZ()};
1100 std::array<float, 3> pxyz{(float)mcTrk->GetStartVertexMomentumX(), (float)mcTrk->GetStartVertexMomentumY(), (float)mcTrk->GetStartVertexMomentumZ()};
1101 TParticlePDG* pPDG = TDatabasePDG::Instance()->GetParticle(mcTrk->GetPdgCode());
1107 std::array<TrackingCluster, 3> misClArr;
1108 std::array<const TrackingCluster*, 8> clArrMis{};
1109 for (
int i = 0;
i <= 7;
i++) {
1110 clArrMis[
i] = clArr[
i];
1112 for (
int iLay = 0; iLay < 3; ++iLay) {
1113 if (!clArr[1 + iLay]) {
1116 const auto& orig = *clArr[1 + iLay];
1117 const int sens = orig.getSensorID();
1123 const auto& sensorMis = mMisalignment[sensorID];
1126 auto mcAtCl = mcPar;
1127 if (!mcAtCl.rotate(orig.alpha) || !prop->PropagateToXBxByBz(mcAtCl, orig.getX())) {
1128 clArrMis[1 + iLay] =
nullptr;
1131 const align::MisalignmentFrame misFrame{
1132 .sensorID = sensorID,
1135 .alpha = orig.alpha,
1139 align::MisalignmentShift totalShift;
1140 if (sensorMis.hasLegendre) {
1142 if (!shift.accepted) {
1143 clArrMis[1 + iLay] =
nullptr;
1146 totalShift += shift;
1148 if (sensorMis.hasInextensional) {
1153 misClArr[iLay] = orig;
1154 misClArr[iLay].setY(orig.getY() + totalShift.dy);
1155 misClArr[iLay].setZ(orig.getZ() + totalShift.dz);
1156 misClArr[iLay].setSigmaY2(orig.getSigmaY2() + (mParams->
misAlgExtCY[sensorID] * mParams->
misAlgExtCY[sensorID]));
1157 misClArr[iLay].setSigmaZ2(orig.getSigmaZ2() + (mParams->
misAlgExtCZ[sensorID] * mParams->
misAlgExtCZ[sensorID]));
1158 clArrMis[1 + iLay] = &misClArr[iLay];
1168 writeTree(
"misRes", clArrMis, extrapOut, extrapInw, lbl);
1173 LOGP(info,
"\tdoMisalignmentStudy: refitted {} out of {} tracks ({} !sel, {} !fit, {} !fitMis)", goodRefit, itsTracks.size(), notPassedSel, fitFail, fitFailMis);
1180 float x = pv.getX(),
y = pv.getY(),
z = pv.getZ();
1181 float f1 = trk.getSnp(), r1 = std::sqrt((1.f - f1) * (1.f + f1));
1182 float xt = trk.getX(), yt = trk.getY();
1183 float sn = std::sin(trk.getAlpha()), cs = std::cos(trk.getAlpha());
1184 float a = (
x * cs) + (
y * sn);
1185 y = (-
x * sn) + (
y * cs);
1189 float rp4 = trk.getCurvature(bz);
1191 ip[0] = -((xt *
f1) - (yt * r1));
1192 ip[1] = trk.getZ() + ((ip[0] *
f1 - xt) / r1 * trk.getTgl()) -
z;
1195 sn = (rp4 * xt) - f1;
1196 cs = (rp4 * yt) + r1;
1197 a = (2 * (xt *
f1 - yt * r1)) - (rp4 * (xt * xt + yt * yt));
1198 float rr = std::sqrt((sn * sn) + (cs * cs));
1199 ip[0] = -
a / (1 + rr);
1200 float f2 = -sn / rr, r2 = std::sqrt((1.f - f2) * (1.f + f2));
1201 ip[1] = trk.getZ() + (trk.getTgl() / rp4 * std::asin((f2 * r1) - (f1 * r2))) -
z;
1206 std::vector<OutputSpec> outputs;
1207 auto dataRequest = std::make_shared<DataRequest>();
1209 dataRequest->requestTracks(srcTracks, useMC);
1210 dataRequest->requestIT3Clusters(useMC);
1211 dataRequest->requestClusters(srcClusters, useMC);
1213 dataRequest->requestPrimaryVertices(useMC);
1215 auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(
false,
1221 dataRequest->inputs,
1225 .
name =
"its3-track-study",
1226 .inputs = dataRequest->inputs,
1228 .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="")
static constexpr float MAX_STEP
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.
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)
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