1313#include < TStopwatch.h>
1414#include " DataFormatsGlobalTracking/RecoContainer.h"
1515#include " DataFormatsGlobalTracking/RecoContainerCreateTracksVariadic.h"
16+ #include " ReconstructionDataFormats/V0.h"
1617#include " ReconstructionDataFormats/TrackTPCITS.h"
1718#include " ReconstructionDataFormats/GlobalTrackID.h"
1819#include " TPCCalibration/VDriftHelper.h"
4546#include " ReconstructionDataFormats/VtxTrackRef.h"
4647#include " ReconstructionDataFormats/DCA.h"
4748#include " Steer/MCKinematicsReader.h"
49+ #include " DCAFitter/DCAFitterN.h"
50+ #include " DetectorsVertexing/SVertexerParams.h"
4851#include " CommonUtils/ConfigurableParam.h"
4952#include " CommonUtils/ConfigurableParamHelper.h"
5053#include " GPUO2InterfaceRefit.h"
@@ -80,8 +83,8 @@ using timeEst = o2::dataformats::TimeStampWithError<float, float>;
8083class TrackMCStudy : public Task
8184{
8285 public:
83- TrackMCStudy (std::shared_ptr<DataRequest> dr, std::shared_ptr<o2::base::GRPGeomRequest> gr, GTrackID::mask_t src, const o2::tpc::CorrectionMapsLoaderGloOpts& sclOpts)
84- : mDataRequest (dr), mGGCCDBRequest (gr), mTracksSrc (src)
86+ TrackMCStudy (std::shared_ptr<DataRequest> dr, std::shared_ptr<o2::base::GRPGeomRequest> gr, GTrackID::mask_t src, const o2::tpc::CorrectionMapsLoaderGloOpts& sclOpts, bool checkSV )
87+ : mDataRequest (dr), mGGCCDBRequest (gr), mTracksSrc (src), mCheckSV (checkSV)
8588 {
8689 mTPCCorrMapsLoader .setLumiScaleType (sclOpts.lumiType );
8790 mTPCCorrMapsLoader .setLumiScaleMode (sclOpts.lumiMode );
@@ -102,6 +105,7 @@ class TrackMCStudy : public Task
102105 bool addMCParticle (const MCTrack& mctr, const o2::MCCompLabel& lb, TParticlePDG* pPDG = nullptr );
103106 bool acceptMCCharged (const MCTrack& tr, const o2::MCCompLabel& lb, int followDec = -1 );
104107 bool propagateToRefX (o2::track::TrackParCov& trcTPC, o2::track::TrackParCov& trcITS);
108+ bool refitV0 (int i, o2::dataformats::V0& v0, const o2::globaltracking::RecoContainer& recoData);
105109 void updateTimeDependentParams (ProcessingContext& pc);
106110 float getDCAYCut (float pt) const ;
107111
@@ -116,6 +120,7 @@ class TrackMCStudy : public Task
116120 std::vector<long > mIntBC ; // /< interaction global BC wrt TF start
117121 std::vector<float > mTPCOcc ; // /< TPC occupancy for this interaction time
118122 std::vector<int > mITSOcc ; // < N ITS clusters in the ROF containing collision
123+ bool mCheckSV = false ; // < check SV binding (apart from prongs availability)
119124 int mNTPCOccBinLength = 0 ; // /< TPC occ. histo bin length in TBs
120125 float mNTPCOccBinLengthInv ;
121126 int mVerbose = 0 ;
@@ -138,12 +143,13 @@ class TrackMCStudy : public Task
138143 int pdg = 0 ;
139144 int daughterFirst = -1 ;
140145 int daughterLast = -1 ;
146+ int foundSVID = -1 ;
141147 };
142- std::vector<std::vector<DecayRef>> mDecaysMaps ; // for every parent particle to watch store its label and entries of 1st/last decay product labels in mDecProdLblPool
148+ std::vector<std::vector<DecayRef>> mDecaysMaps ; // for every parent particle to watch, store its label and entries of 1st/last decay product labels in mDecProdLblPool
143149 std::unordered_map<o2::MCCompLabel, TrackFamily> mSelMCTracks ;
144150 std::unordered_map<o2::MCCompLabel, std::pair<int , int >> mSelTRefIdx ;
145151 std::vector<o2::track::TrackPar> mSelTRefs ;
146-
152+ o2::vertexing::DCAFitterN< 2 > mFitterV0 ;
147153 static constexpr float MaxSnp = 0.9 ; // max snp of ITS or TPC track at xRef to be matched
148154};
149155
@@ -211,6 +217,25 @@ void TrackMCStudy::updateTimeDependentParams(ProcessingContext& pc)
211217
212218 auto & elParam = o2::tpc::ParameterElectronics::Instance ();
213219 mTPCTBinMUS = elParam.ZbinWidth ;
220+
221+ if (mCheckSV ) {
222+ const auto & svparam = o2::vertexing::SVertexerParams::Instance ();
223+ mFitterV0 .setBz (o2::base::Propagator::Instance ()->getNominalBz ());
224+ mFitterV0 .setUseAbsDCA (svparam.useAbsDCA );
225+ mFitterV0 .setPropagateToPCA (false );
226+ mFitterV0 .setMaxR (svparam.maxRIni );
227+ mFitterV0 .setMinParamChange (svparam.minParamChange );
228+ mFitterV0 .setMinRelChi2Change (svparam.minRelChi2Change );
229+ mFitterV0 .setMaxDZIni (svparam.maxDZIni );
230+ mFitterV0 .setMaxDXYIni (svparam.maxDXYIni );
231+ mFitterV0 .setMaxChi2 (svparam.maxChi2 );
232+ mFitterV0 .setMatCorrType (o2::base::Propagator::MatCorrType (svparam.matCorr ));
233+ mFitterV0 .setUsePropagator (svparam.usePropagator );
234+ mFitterV0 .setRefitWithMatCorr (svparam.refitWithMatCorr );
235+ mFitterV0 .setMaxStep (svparam.maxStep );
236+ mFitterV0 .setMaxSnp (svparam.maxSnp );
237+ mFitterV0 .setMinXSeed (svparam.minXSeed );
238+ }
214239 }
215240}
216241
@@ -547,6 +572,54 @@ void TrackMCStudy::process(const o2::globaltracking::RecoContainer& recoData)
547572 }
548573 }
549574
575+ // SVertices (V0s)
576+ if (mCheckSV ) {
577+ auto v0s = recoData.getV0sIdx ();
578+ auto prpr = [](o2::trackstudy::TrackFamily& f) {
579+ std::string s;
580+ s += fmt::format (" par {} Ntpccl={} Nitscl={} " , f.mcTrackInfo .pdgParent , f.mcTrackInfo .nTPCCl , f.mcTrackInfo .nITSCl );
581+ for (auto & t : f.recTracks ) {
582+ s += t.gid .asString ();
583+ s += " " ;
584+ }
585+ return s;
586+ };
587+ for (int svID; svID < (int )v0s.size (); svID++) {
588+ const auto & v0idx = v0s[svID];
589+ int nOKProngs = 0 , realMCSVID = -1 ;
590+ int8_t decTypeID = -1 ;
591+ for (int ipr = 0 ; ipr < v0idx.getNProngs (); ipr++) {
592+ auto mcl = recoData.getTrackMCLabel (v0idx.getProngID (ipr)); // was this MC particle selected?
593+ auto itl = mSelMCTracks .find (mcl);
594+ if (itl == mSelMCTracks .end ()) {
595+ nOKProngs = -1 ; // was not selected as interesting one, ignore
596+ break ;
597+ }
598+ auto & trackFamily = itl->second ;
599+ int decayParentIndex = trackFamily.mcTrackInfo .parentEntry ;
600+ if (decayParentIndex < 0 ) { // does not come from decay
601+ break ;
602+ }
603+ if (ipr == 0 ) {
604+ realMCSVID = decayParentIndex;
605+ decTypeID = trackFamily.mcTrackInfo .parentDecID ;
606+ nOKProngs = 1 ;
607+ LOGP (debug, " Prong{} {} comes from {}/{}" , ipr, prpr (trackFamily), decTypeID, realMCSVID);
608+ continue ;
609+ }
610+ if (realMCSVID != decayParentIndex || decTypeID != trackFamily.mcTrackInfo .parentDecID ) {
611+ break ;
612+ }
613+ LOGP (debug, " Prong{} {} comes from {}/{}" , ipr, prpr (trackFamily), decTypeID, realMCSVID);
614+ nOKProngs++;
615+ }
616+ if (nOKProngs == v0idx.getNProngs ()) { // all prongs are from the decay of MC parent which deemed to be interesting, flag it
617+ LOGP (debug, " Decay {}/{} was found" , decTypeID, realMCSVID);
618+ mDecaysMaps [decTypeID][realMCSVID].foundSVID = svID;
619+ }
620+ }
621+ }
622+
550623 // single tracks
551624 for (auto & entry : mSelMCTracks ) {
552625 auto & trackFam = entry.second ;
@@ -574,7 +647,11 @@ void TrackMCStudy::process(const o2::globaltracking::RecoContainer& recoData)
574647 decFam.push_back (dtFamily);
575648 }
576649 if (!skip) {
577- (*mDBGOut ) << decTreeName.c_str () << " pdgPar=" << dec.pdg << " trPar=" << dec.parent << " prod=" << decFam << " \n " ;
650+ o2::dataformats::V0 v0;
651+ if (dec.foundSVID >= 0 && !refitV0 (dec.foundSVID , v0, recoData)) {
652+ v0.invalidate ();
653+ }
654+ (*mDBGOut ) << decTreeName.c_str () << " pdgPar=" << dec.pdg << " trPar=" << dec.parent << " prod=" << decFam << " found=" << dec.foundSVID << " sv=" << v0 << " \n " ;
578655 }
579656 }
580657 }
@@ -891,6 +968,7 @@ bool TrackMCStudy::processMCParticle(int src, int ev, int trid)
891968 }
892969 }
893970 if (decay >= 0 ) { // check if decay and kinematics is acceptable
971+ auto & decayPool = mDecaysMaps [decay];
894972 int idd0 = mcPart.getFirstDaughterTrackId (), idd1 = mcPart.getLastDaughterTrackId (); // we want only charged and trackable daughters
895973 int dtStart = mDecProdLblPool .size (), dtEnd = -1 ;
896974 if (idd0 < 0 ) {
@@ -908,12 +986,17 @@ bool TrackMCStudy::processMCParticle(int src, int ev, int trid)
908986 }
909987 if (decay >= 0 ) {
910988 // account decay
911- dtEnd = mDecProdLblPool .size () - 1 ;
989+ dtEnd = mDecProdLblPool .size ();
990+ for (int dtid = dtStart; dtid < dtEnd; dtid++) { // flag selected decay parent entry in the prongs MCs
991+ mSelMCTracks [mDecProdLblPool [dtid]].mcTrackInfo .parentEntry = decayPool.size ();
992+ mSelMCTracks [mDecProdLblPool [dtid]].mcTrackInfo .parentDecID = int8_t (decay);
993+ }
994+ dtEnd--;
912995 std::array<float , 3 > xyz{(float )mcPart.GetStartVertexCoordinatesX (), (float )mcPart.GetStartVertexCoordinatesY (), (float )mcPart.GetStartVertexCoordinatesZ ()};
913996 std::array<float , 3 > pxyz{(float )mcPart.GetStartVertexMomentumX (), (float )mcPart.GetStartVertexMomentumY (), (float )mcPart.GetStartVertexMomentumZ ()};
914- mDecaysMaps [decay] .emplace_back (DecayRef{lbl,
915- o2::track::TrackPar (xyz, pxyz, TMath::Nint (O2DatabasePDG::Instance ()->GetParticle (mcPart.GetPdgCode ())->Charge () / 3 ), false ),
916- mcPart.GetPdgCode (), dtStart, dtEnd});
997+ decayPool .emplace_back (DecayRef{lbl,
998+ o2::track::TrackPar (xyz, pxyz, TMath::Nint (O2DatabasePDG::Instance ()->GetParticle (mcPart.GetPdgCode ())->Charge () / 3 ), false ),
999+ mcPart.GetPdgCode (), dtStart, dtEnd});
9171000 if (mVerbose > 1 ) {
9181001 LOGP (info, " Adding MC parent pdg={} {}, with prongs in {}:{} range" , pdg, lbl.asString (), dtStart, dtEnd);
9191002 }
@@ -1005,6 +1088,51 @@ bool TrackMCStudy::addMCParticle(const MCTrack& mcPart, const o2::MCCompLabel& l
10051088 return true ;
10061089}
10071090
1091+ bool TrackMCStudy::refitV0 (int i, o2::dataformats::V0& v0, const o2::globaltracking::RecoContainer& recoData)
1092+ {
1093+ const auto & id = recoData.getV0sIdx ()[i];
1094+ auto seedP = recoData.getTrackParam (id.getProngID (0 ));
1095+ auto seedN = recoData.getTrackParam (id.getProngID (1 ));
1096+ bool isTPConly = (id.getProngID (0 ).getSource () == GTrackID::TPC) || (id.getProngID (1 ).getSource () == GTrackID::TPC);
1097+ const auto & svparam = o2::vertexing::SVertexerParams::Instance ();
1098+ if (svparam.mTPCTrackPhotonTune && isTPConly) {
1099+ mFitterV0 .setMaxDZIni (svparam.mTPCTrackMaxDZIni );
1100+ mFitterV0 .setMaxDXYIni (svparam.mTPCTrackMaxDXYIni );
1101+ mFitterV0 .setMaxChi2 (svparam.mTPCTrackMaxChi2 );
1102+ mFitterV0 .setCollinear (true );
1103+ }
1104+ int nCand = mFitterV0 .process (seedP, seedN);
1105+ if (svparam.mTPCTrackPhotonTune && isTPConly) { // restore
1106+ // Reset immediately to the defaults
1107+ mFitterV0 .setMaxDZIni (svparam.maxDZIni );
1108+ mFitterV0 .setMaxDXYIni (svparam.maxDXYIni );
1109+ mFitterV0 .setMaxChi2 (svparam.maxChi2 );
1110+ mFitterV0 .setCollinear (false );
1111+ }
1112+ if (nCand == 0 ) { // discard this pair
1113+ return false ;
1114+ }
1115+ const int cand = 0 ;
1116+ if (!mFitterV0 .isPropagateTracksToVertexDone (cand) && !mFitterV0 .propagateTracksToVertex (cand)) {
1117+ return false ;
1118+ }
1119+ const auto & trPProp = mFitterV0 .getTrack (0 , cand);
1120+ const auto & trNProp = mFitterV0 .getTrack (1 , cand);
1121+ std::array<float , 3 > pP{}, pN{};
1122+ trPProp.getPxPyPzGlo (pP);
1123+ trNProp.getPxPyPzGlo (pN);
1124+ std::array<float , 3 > pV0 = {pP[0 ] + pN[0 ], pP[1 ] + pN[1 ], pP[2 ] + pN[2 ]};
1125+ auto p2V0 = pV0[0 ] * pV0[0 ] + pV0[1 ] * pV0[1 ] + pV0[2 ] * pV0[2 ];
1126+ const auto & pv = recoData.getPrimaryVertex (id.getVertexID ());
1127+ const auto v0XYZ = mFitterV0 .getPCACandidatePos (cand);
1128+ float dx = v0XYZ[0 ] - pv.getX (), dy = v0XYZ[1 ] - pv.getY (), dz = v0XYZ[2 ] - pv.getZ (), prodXYZv0 = dx * pV0[0 ] + dy * pV0[1 ] + dz * pV0[2 ];
1129+ float cosPA = prodXYZv0 / std::sqrt ((dx * dx + dy * dy + dz * dz) * p2V0);
1130+ new (&v0) o2::dataformats::V0 (v0XYZ, pV0, mFitterV0 .calcPCACovMatrixFlat (cand), trPProp, trNProp);
1131+ v0.setDCA (mFitterV0 .getChi2AtPCACandidate (cand));
1132+ v0.setCosPA (cosPA);
1133+ return true ;
1134+ }
1135+
10081136void TrackMCStudy::loadTPCOccMap (const o2::globaltracking::RecoContainer& recoData)
10091137{
10101138 auto NHBPerTF = o2::base::GRPGeomHelper::instance ().getGRPECS ()->getNHBFPerTF ();
@@ -1037,7 +1165,7 @@ void TrackMCStudy::loadTPCOccMap(const o2::globaltracking::RecoContainer& recoDa
10371165 }
10381166}
10391167
1040- DataProcessorSpec getTrackMCStudySpec (GTrackID::mask_t srcTracks, GTrackID::mask_t srcClusters, const o2::tpc::CorrectionMapsLoaderGloOpts& sclOpts)
1168+ DataProcessorSpec getTrackMCStudySpec (GTrackID::mask_t srcTracks, GTrackID::mask_t srcClusters, const o2::tpc::CorrectionMapsLoaderGloOpts& sclOpts, bool checkSV )
10411169{
10421170 std::vector<OutputSpec> outputs;
10431171 Options opts{
@@ -1052,6 +1180,9 @@ DataProcessorSpec getTrackMCStudySpec(GTrackID::mask_t srcTracks, GTrackID::mask
10521180 dataRequest->requestTracks (srcTracks, useMC);
10531181 dataRequest->requestClusters (srcClusters, useMC);
10541182 dataRequest->requestPrimaryVertices (useMC);
1183+ if (checkSV) {
1184+ dataRequest->requestSecondaryVertices (useMC);
1185+ }
10551186 o2::tpc::VDriftHelper::requestCCDBInputs (dataRequest->inputs );
10561187 o2::tpc::CorrectionMapsLoader::requestCCDBInputs (dataRequest->inputs , opts, sclOpts);
10571188 auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(false , // orbitResetTime
@@ -1067,7 +1198,7 @@ DataProcessorSpec getTrackMCStudySpec(GTrackID::mask_t srcTracks, GTrackID::mask
10671198 " track-mc-study" ,
10681199 dataRequest->inputs ,
10691200 outputs,
1070- AlgorithmSpec{adaptFromTask<TrackMCStudy>(dataRequest, ggRequest, srcTracks, sclOpts)},
1201+ AlgorithmSpec{adaptFromTask<TrackMCStudy>(dataRequest, ggRequest, srcTracks, sclOpts, checkSV )},
10711202 opts};
10721203}
10731204
0 commit comments