@@ -65,6 +65,10 @@ struct matchingMFT {
6565 Configurable<float > maxEtaSA{" maxEtaSA" , -2.5 , " max. eta acceptance for MCH-MID" };
6666 Configurable<float > minEtaGL{" minEtaGL" , -3.6 , " min. eta acceptance for MFT-MCH-MID" };
6767 Configurable<float > maxEtaGL{" maxEtaGL" , -2.5 , " max. eta acceptance for MFT-MCH-MID" };
68+ Configurable<float > minPtMFTsa{" minPtMFTsa" , 0.01 , " min pt for MFTsa" };
69+ Configurable<float > maxPtMFTsa{" maxPtMFTsa" , 1e+10 , " max pt for MFTsa" };
70+ Configurable<float > minEtaMFTsa{" minEtaMFTsa" , -3.6 , " min. eta acceptance for MFTsa" };
71+ Configurable<float > maxEtaMFTsa{" maxEtaMFTsa" , -2.4 , " max. eta acceptance for MFTsa" };
6872 Configurable<float > minRabs{" minRabs" , 17.6 , " min. R at absorber end" };
6973 Configurable<float > midRabs{" midRabs" , 26.5 , " middle R at absorber end for pDCA cut" };
7074 Configurable<float > maxRabs{" maxRabs" , 89.5 , " max. R at absorber end" };
@@ -211,6 +215,24 @@ struct matchingMFT {
211215 fRegistry .add (" MFTMCHMID/primary/correct/hDeltaPhi_Neg" , " #varphi resolution;p_{T}^{gen} (GeV/c);#varphi^{rec} - #varphi^{gen} (rad.)" , kTH2F , {{100 , 0 , 10 }, {400 , -0.2 , +0.2 }}, false );
212216 fRegistry .addClone (" MFTMCHMID/primary/correct/" , " MFTMCHMID/primary/wrong/" );
213217 fRegistry .addClone (" MFTMCHMID/primary/" , " MFTMCHMID/secondary/" );
218+
219+ fRegistry .add (" MFT/primary/hPt" , " pT;p_{T} (GeV/c)" , kTH1D , {{1000 , 0 .0f , 10 }}, false );
220+ fRegistry .add (" MFT/primary/hEtaPhi" , " #eta vs. #varphi;#varphi (rad.);#eta" , kTH2D , {{180 , 0 , 2 * M_PI}, {80 , -5 .f , -1 .f }}, false );
221+ fRegistry .add (" MFT/primary/hSign" , " sign;sign" , kTH1D , {{3 , -1.5 , +1.5 }}, false );
222+ fRegistry .add (" MFT/primary/hChi2MFT" , " chi2 MFT/ndf;chi2 MFT/ndf" , kTH1D , {{100 , 0 .0f , 10 }}, false );
223+ fRegistry .add (" MFT/primary/hNclustersMFT" , " NclustersMFT;Nclusters MFT" , kTH1D , {{11 , -0 .5f , 10.5 }}, false );
224+ fRegistry .add (" MFT/primary/hMFTClusterMap" , " MFT cluster map" , kTH1D , {{1024 , -0.5 , 1023.5 }}, false );
225+ fRegistry .add (" MFT/primary/hDCAxy2D" , " DCA x vs. y;DCA_{x} (cm);DCA_{y} (cm)" , kTH2D , {{200 , -0.5 , 0.5 }, {200 , -0.5 , +0.5 }}, false );
226+ fRegistry .add (" MFT/primary/hDCAxy" , " DCAxy;DCA_{xy} (cm);" , kTH1D , {{100 , 0 , 1 }}, false );
227+ fRegistry .add (" MFT/primary/hDCAxyz" , " DCA xy vs. z;DCA_{xy} (cm);DCA_{z} (cm);" , kTH2D , {{100 , 0 , 1 }, {200 , -0.1 , 0.1 }}, false );
228+ fRegistry .add (" MFT/primary/hProdVtxZ" , " prod. vtx Z of track;V_{z} (cm)" , kTH1D , {{200 , -100 , 100 }}, false );
229+ fRegistry .add (" MFT/primary/hRelDeltaPt" , " pT resolution;p_{T}^{gen} (GeV/c);(p_{T}^{rec} - p_{T}^{gen})/p_{T}^{gen}" , kTH2D , {{200 , 0 , 10 }, {1000 , -1 , +9 }}, false );
230+ fRegistry .add (" MFT/primary/hDeltaEta_Pos" , " #eta resolution;p_{T}^{gen} (GeV/c);#eta^{rec} - #eta^{gen}" , kTH2D , {{200 , 0 , 10 }, {400 , -0.2 , +0.2 }}, false );
231+ fRegistry .add (" MFT/primary/hDeltaEta_Neg" , " #eta resolution;p_{T}^{gen} (GeV/c);#eta^{rec} - #eta^{gen}" , kTH2D , {{200 , 0 , 10 }, {400 , -0.2 , +0.2 }}, false );
232+ fRegistry .add (" MFT/primary/hDeltaPhi_Pos" , " #varphi resolution;p_{T}^{gen} (GeV/c);#varphi^{rec} - #varphi^{gen} (rad.)" , kTH2D , {{200 , 0 , 10 }, {400 , -0.2 , +0.2 }}, false );
233+ fRegistry .add (" MFT/primary/hDeltaPhi_Neg" , " #varphi resolution;p_{T}^{gen} (GeV/c);#varphi^{rec} - #varphi^{gen} (rad.)" , kTH2D , {{200 , 0 , 10 }, {400 , -0.2 , +0.2 }}, false );
234+ fRegistry .add (" MFT/primary/hCorrectAsocc" , " correct mfttrack-to-collision association" , kTH1F , {{2 , -0.5 , +1.5 }}, false );
235+ fRegistry .addClone (" MFT/primary/" , " MFT/secondary/" );
214236 }
215237
216238 bool isSelected (const float pt, const float eta, const float rAtAbsorberEnd, const float pDCA, const float chi2_per_ndf, const uint8_t trackType, const float dcaXY)
@@ -767,10 +789,133 @@ struct matchingMFT {
767789 // }
768790 }
769791
792+ template <typename TCollisions, typename TMFTTracks>
793+ void fillMFTsa (TCollisions const & collisions, TMFTTracks const & mfttracks)
794+ {
795+ for (const auto & collision : collisions) {
796+ if (!collision.has_mcCollision ()) {
797+ continue ;
798+ }
799+ if (cfgRequireGoodRCT && !rctChecker.checkTable (collision)) {
800+ continue ;
801+ }
802+ float centralities[3 ] = {collision.centFT0M (), collision.centFT0A (), collision.centFT0C ()};
803+ if (centralities[cfgCentEstimator] < cfgCentMin || cfgCentMax < centralities[cfgCentEstimator]) {
804+ continue ;
805+ }
806+
807+ auto mftsaPerCollision = mfttracks.sliceBy (perCollision_MFT, collision.globalIndex ());
808+ for (const auto & mfttrack : mftsaPerCollision) {
809+ if (!mfttrack.has_mcParticle ()) {
810+ continue ;
811+ }
812+ auto mcParticle = mfttrack.template mcParticle_as <aod::McParticles>();
813+ bool isPrimary = mcParticle.isPhysicalPrimary () || mcParticle.producedByGenerator ();
814+ float phiGen = mcParticle.phi ();
815+ o2::math_utils::bringTo02Pi (phiGen);
816+
817+ int ndf = 2 * mfttrack.nClusters () - 5 ;
818+
819+ if (mfttrack.nClusters () < minNclustersMFT) {
820+ continue ;
821+ }
822+
823+ if (mfttrack.chi2 () / ndf < 0 || maxChi2MFT < mfttrack.chi2 () / ndf) {
824+ continue ;
825+ }
826+
827+ if (requireMFTHitMap) {
828+ std::vector<bool > hasMFTs{hasMFT<0 , 1 >(mfttrack), hasMFT<2 , 3 >(mfttrack), hasMFT<4 , 5 >(mfttrack), hasMFT<6 , 7 >(mfttrack), hasMFT<8 , 9 >(mfttrack)};
829+ for (int i = 0 ; i < static_cast <int >(requiredMFTDisks->size ()); i++) {
830+ if (!hasMFTs[requiredMFTDisks->at (i)]) {
831+ return ;
832+ }
833+ }
834+ }
835+
836+ // propagate MFTsa track to PV
837+ std::array<double , 3 > dcaInfOrig{999 .f , 999 .f , 999 .f };
838+ std::vector<double > v1; // Temporary null vector for the computation of the covariance matrix
839+ SMatrix55 tcovs (v1.begin (), v1.end ());
840+ SMatrix5 tpars (mfttrack.x (), mfttrack.y (), mfttrack.phi (), mfttrack.tgl (), mfttrack.signed1Pt ());
841+ o2::track::TrackParCovFwd trackPar{mfttrack.z (), tpars, tcovs, mfttrack.chi2 ()};
842+ trackPar.propagateToDCAhelix (mBz , {collision.posX (), collision.posY (), collision.posZ ()}, dcaInfOrig);
843+ v1.clear ();
844+ v1.shrink_to_fit ();
845+ float dcaX = dcaInfOrig[0 ];
846+ float dcaY = dcaInfOrig[1 ];
847+ float dcaZ = dcaInfOrig[2 ];
848+ float dcaXY = std::sqrt (dcaX * dcaX + dcaY * dcaY);
849+
850+ float pt = trackPar.getPt ();
851+ float eta = trackPar.getEta ();
852+ float phi = trackPar.getPhi ();
853+ o2::math_utils::bringTo02Pi (phi);
854+
855+ if (pt < minPtMFTsa || maxPtMFTsa < pt) {
856+ continue ;
857+ }
858+ if (eta < minEtaMFTsa || maxEtaMFTsa < eta) {
859+ continue ;
860+ }
861+ if (maxDCAxy < dcaXY) {
862+ continue ;
863+ }
864+
865+ if (isPrimary) {
866+ fRegistry .fill (HIST (" MFT/primary/hPt" ), pt);
867+ fRegistry .fill (HIST (" MFT/primary/hEtaPhi" ), phi, eta);
868+ fRegistry .fill (HIST (" MFT/primary/hSign" ), mfttrack.sign ());
869+ fRegistry .fill (HIST (" MFT/primary/hNclustersMFT" ), mfttrack.nClusters ());
870+ fRegistry .fill (HIST (" MFT/primary/hChi2MFT" ), mfttrack.chi2 () / ndf);
871+ fRegistry .fill (HIST (" MFT/primary/hMFTClusterMap" ), mftClusterMap (mfttrack));
872+ fRegistry .fill (HIST (" MFT/primary/hDCAxy2D" ), dcaX, dcaY);
873+ fRegistry .fill (HIST (" MFT/primary/hDCAxy" ), dcaXY);
874+ fRegistry .fill (HIST (" MFT/primary/hDCAxyz" ), dcaXY, dcaZ);
875+ fRegistry .fill (HIST (" MFT/primary/hCorrectAsocc" ), mcParticle.mcCollisionId () == collision.mcCollisionId ());
876+
877+ fRegistry .fill (HIST (" MFT/primary/hProdVtxZ" ), mcParticle.vz ());
878+ fRegistry .fill (HIST (" MFT/primary/hRelDeltaPt" ), mcParticle.pt (), (pt - mcParticle.pt ()) / mcParticle.pt ());
879+ if (mfttrack.sign () > 0 ) {
880+ fRegistry .fill (HIST (" MFT/primary/hDeltaEta_Pos" ), mcParticle.pt (), eta - mcParticle.eta ());
881+ fRegistry .fill (HIST (" MFT/primary/hDeltaPhi_Pos" ), mcParticle.pt (), phi - phiGen);
882+ } else {
883+ fRegistry .fill (HIST (" MFT/primary/hDeltaEta_Neg" ), mcParticle.pt (), eta - mcParticle.eta ());
884+ fRegistry .fill (HIST (" MFT/primary/hDeltaPhi_Neg" ), mcParticle.pt (), phi - phiGen);
885+ }
886+
887+ } else {
888+ fRegistry .fill (HIST (" MFT/secondary/hPt" ), pt);
889+ fRegistry .fill (HIST (" MFT/secondary/hEtaPhi" ), phi, eta);
890+ fRegistry .fill (HIST (" MFT/secondary/hSign" ), mfttrack.sign ());
891+ fRegistry .fill (HIST (" MFT/secondary/hNclustersMFT" ), mfttrack.nClusters ());
892+ fRegistry .fill (HIST (" MFT/secondary/hChi2MFT" ), mfttrack.chi2 () / ndf);
893+ fRegistry .fill (HIST (" MFT/secondary/hMFTClusterMap" ), mftClusterMap (mfttrack));
894+ fRegistry .fill (HIST (" MFT/secondary/hDCAxy2D" ), dcaX, dcaY);
895+ fRegistry .fill (HIST (" MFT/secondary/hDCAxy" ), dcaXY);
896+ fRegistry .fill (HIST (" MFT/secondary/hDCAxyz" ), dcaXY, dcaZ);
897+ fRegistry .fill (HIST (" MFT/secondary/hCorrectAsocc" ), mcParticle.mcCollisionId () == collision.mcCollisionId ());
898+
899+ fRegistry .fill (HIST (" MFT/secondary/hProdVtxZ" ), mcParticle.vz ());
900+ fRegistry .fill (HIST (" MFT/secondary/hRelDeltaPt" ), mcParticle.pt (), (pt - mcParticle.pt ()) / mcParticle.pt ());
901+ if (mfttrack.sign () > 0 ) {
902+ fRegistry .fill (HIST (" MFT/secondary/hDeltaEta_Pos" ), mcParticle.pt (), eta - mcParticle.eta ());
903+ fRegistry .fill (HIST (" MFT/secondary/hDeltaPhi_Pos" ), mcParticle.pt (), phi - phiGen);
904+ } else {
905+ fRegistry .fill (HIST (" MFT/secondary/hDeltaEta_Neg" ), mcParticle.pt (), eta - mcParticle.eta ());
906+ fRegistry .fill (HIST (" MFT/secondary/hDeltaPhi_Neg" ), mcParticle.pt (), phi - phiGen);
907+ }
908+ }
909+
910+ } // end of mfttrack loop
911+ } // end of collision loop
912+ }
913+
770914 SliceCache cache;
771915 PresliceUnsorted<aod::FwdTracks> fwdtracksPerMCHTrack = aod::fwdtrack::matchMCHTrackId;
772916 PresliceUnsorted<aod::FwdTracks> perMFTTrack = o2::aod::fwdtrack::matchMFTTrackId;
773917 Preslice<aod::FwdTracks> perCollision = o2::aod::fwdtrack::collisionId;
918+ Preslice<aod::MFTTracks> perCollision_MFT = o2::aod::fwdtrack::collisionId;
774919 Preslice<aod::FwdTrackAssoc> fwdtrackIndicesPerCollision = aod::track_association::collisionId;
775920 PresliceUnsorted<aod::FwdTrackAssoc> fwdtrackIndicesPerFwdTrack = aod::track_association::fwdtrackId;
776921
@@ -791,6 +936,9 @@ struct matchingMFT {
791936 } // end of fwdtrack loop
792937 } // end of collision loop
793938
939+ // only for MFTsa
940+ fillMFTsa (collisions, mfttracks);
941+
794942 for (const auto & collision : collisions) {
795943 auto bc = collision.template bc_as <aod::BCsWithTimestamps>();
796944 initCCDB (bc);
@@ -850,6 +998,9 @@ struct matchingMFT {
850998 } // end of fwdtrack loop
851999 } // end of collision loop
8521000
1001+ // only for MFTsa
1002+ fillMFTsa (collisions, mfttracks);
1003+
8531004 for (const auto & collision : collisions) {
8541005 auto bc = collision.template bc_as <aod::BCsWithTimestamps>();
8551006 initCCDB (bc);
@@ -916,6 +1067,9 @@ struct matchingMFT {
9161067 } // end of fwdtrack loop
9171068 } // end of collision loop
9181069
1070+ // only for MFTsa
1071+ fillMFTsa (collisions, mfttracks);
1072+
9191073 for (const auto & collision : collisions) {
9201074 auto bc = collision.template bc_as <aod::BCsWithTimestamps>();
9211075 initCCDB (bc);
0 commit comments