Skip to content

Commit e40ebed

Browse files
committed
Add check for V0s prongs binding on top of reco status
1 parent 2c31473 commit e40ebed

File tree

4 files changed

+152
-14
lines changed

4 files changed

+152
-14
lines changed

Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudy.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ namespace o2::trackstudy
2121
{
2222

2323
/// create a processor spec
24-
o2::framework::DataProcessorSpec getTrackMCStudySpec(o2::dataformats::GlobalTrackID::mask_t srcTracks, o2::dataformats::GlobalTrackID::mask_t srcClus, const o2::tpc::CorrectionMapsLoaderGloOpts& sclOpts);
24+
o2::framework::DataProcessorSpec getTrackMCStudySpec(o2::dataformats::GlobalTrackID::mask_t srcTracks, o2::dataformats::GlobalTrackID::mask_t srcClus, const o2::tpc::CorrectionMapsLoaderGloOpts& sclOpts, bool checkSV);
2525

2626
} // namespace o2::trackstudy
2727

Detectors/GlobalTrackingWorkflow/study/include/GlobalTrackingStudy/TrackMCStudyTypes.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,18 @@ struct MCTrackInfo {
4040
int bcInTF = -1;
4141
int pdg = 0;
4242
int pdgParent = 0;
43+
int parentEntry = -1;
4344
int16_t nTPCCl = 0;
4445
int16_t nTPCClShared = 0;
46+
int8_t parentDecID = -1;
4547
uint8_t minTPCRow = -1;
4648
uint8_t maxTPCRow = 0;
4749
uint8_t maxTPCRowInner = 0; // highest row in the sector containing the lowest one
4850
uint8_t minTPCRowSect = -1;
4951
uint8_t maxTPCRowSect = -1;
5052
int8_t nITSCl = 0;
5153
int8_t pattITSCl = 0;
52-
ClassDefNV(MCTrackInfo, 2);
54+
ClassDefNV(MCTrackInfo, 3);
5355
};
5456

5557
struct RecTrack {

Detectors/GlobalTrackingWorkflow/study/src/TrackMCStudy.cxx

Lines changed: 142 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
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"
@@ -45,6 +46,8 @@
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>;
8083
class 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+
10081136
void 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

Detectors/GlobalTrackingWorkflow/study/src/trackMCStudy-workflow.cxx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ void customize(std::vector<ConfigParamSpec>& workflowOptions)
4141
{"track-sources", VariantType::String, std::string{GID::ALL}, {"comma-separated list of track sources to use"}},
4242
{"cluster-sources", VariantType::String, std::string{GID::ALL}, {"comma-separated list of cluster sources to use"}},
4343
{"disable-root-input", VariantType::Bool, false, {"disable root-files input reader"}},
44+
{"ignore-sv-check", VariantType::Bool, false, {"disable check for SV combinatorics"}},
4445
{"disable-mc", o2::framework::VariantType::Bool, false, {"disable MC propagation, never use it"}},
4546
{"configKeyValues", VariantType::String, "", {"Semicolon separated key=value strings ..."}}};
4647
o2::tpc::CorrectionMapsLoader::addGlobalOptions(options);
@@ -56,6 +57,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext)
5657
{
5758
WorkflowSpec specs;
5859
auto useMC = !configcontext.options().get<bool>("disable-mc");
60+
auto checkSV = !configcontext.options().get<bool>("ignore-sv-check");
5961
if (!useMC) {
6062
throw std::runtime_error("MC cannot be disabled for this workflow");
6163
}
@@ -72,11 +74,14 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext)
7274

7375
o2::globaltracking::InputHelper::addInputSpecs(configcontext, specs, srcCls, srcTrc, srcTrc, true);
7476
o2::globaltracking::InputHelper::addInputSpecsPVertex(configcontext, specs, true); // P-vertex is always needed
77+
if (checkSV) {
78+
o2::globaltracking::InputHelper::addInputSpecsSVertex(configcontext, specs);
79+
}
7580
if (sclOpt.needTPCScalersWorkflow() && !configcontext.options().get<bool>("disable-root-input")) {
7681
specs.emplace_back(o2::tpc::getTPCScalerSpec(sclOpt.lumiType == 2, sclOpt.enableMShapeCorrection));
7782
}
7883

79-
specs.emplace_back(o2::trackstudy::getTrackMCStudySpec(srcTrc, srcCls, sclOpt));
84+
specs.emplace_back(o2::trackstudy::getTrackMCStudySpec(srcTrc, srcCls, sclOpt, checkSV));
8085
// configure dpl timer to inject correct firstTForbit: start from the 1st orbit of TF containing 1st sampled orbit
8186
o2::raw::HBFUtilsInitializer hbfIni(configcontext, specs);
8287

0 commit comments

Comments
 (0)