Skip to content

Commit 7e09a3e

Browse files
committed
feat(nucleiFilter): Implement 2-body vertex finding for He-V0 selection
The changes in this commit focus on improving the selection of He-V0 candidates by introducing a 2-body vertex finding step. The key changes are: 1. Added a 2-body vertex fitter (DCAFitterN<2>) to process the positive and negative tracks and obtain the PCA (point of closest approach) candidate. 2. Calculated the cosine of the pointing angle and applied a cut on this value to further select the He-V0 candidates. 3. Refactored the existing He-V0 selection logic to use the new 2-body vertex information.
1 parent 54028b2 commit 7e09a3e

File tree

1 file changed

+45
-17
lines changed

1 file changed

+45
-17
lines changed

EventFiltering/PWGLF/nucleiFilter.cxx

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ struct nucleiFilter {
102102
Configurable<float> cfgCutDCAxy{"cfgCutDCAxy", 3, "Max DCAxy"};
103103
Configurable<float> cfgCutDCAz{"cfgCutDCAz", 10, "Max DCAz"};
104104
Configurable<float> cfgCutKstar{"cfgCutKstar", 1.f, "Kstar cut for triton femto trigger"};
105+
Configurable<double> cfgCutCosPAheV0{"cfgCutCosPAheV0", 0.99, "CosPA cut for HeV0"};
105106

106107
Configurable<LabeledArray<double>> cfgBetheBlochParams{"cfgBetheBlochParams", {betheBlochDefault[0], nNuclei, 6, nucleiNames, betheBlochParNames}, "TPC Bethe-Bloch parameterisation for light nuclei"};
107108
Configurable<LabeledArray<double>> cfgMomentumScalingBetheBloch{"cfgMomentumScalingBetheBloch", {bbMomScalingDefault[0], nNuclei, 2, nucleiNames, matterOrNot}, "TPC Bethe-Bloch momentum scaling for light nuclei"};
@@ -112,16 +113,17 @@ struct nucleiFilter {
112113

113114
// variable/tool for hypertriton 3body decay
114115
int mRunNumber;
115-
float d_bz;
116+
float mBz;
116117
Service<o2::ccdb::BasicCCDBManager> ccdb;
117118
using TrackCandidates = soa::Join<aod::TracksIU, aod::TracksExtra, aod::TracksCovIU, aod::TrackSelection, aod::TracksDCA, aod::EvTimeTOFFT0ForTrack, aod::pidTPCFullPi, aod::pidTPCFullPr, aod::pidTPCFullDe, aod::pidTPCFullTr, aod::pidTPCFullHe, aod::pidTPCFullAl, aod::pidTOFFullDe, aod::pidTOFFullTr, aod::pidTOFFullHe, aod::pidTOFFullAl>; // FIXME: positio has been changed
118119
o2::aod::pidtofgeneric::TofPidNewCollision<TrackCandidates::iterator> bachelorTOFPID;
119120
o2::base::MatLayerCylSet* lut = nullptr;
121+
o2::vertexing::DCAFitterN<2> fitter2body;
120122
o2::vertexing::DCAFitterN<3> fitter3body;
121123
o2::pid::tof::TOFResoParamsV2 mRespParamsV2;
122124
// configurable for hypertriton 3body decay
123125
struct : ConfigurableGroup {
124-
Configurable<double> d_bz_input{"trgH3L3Body.d_bz", -999, "bz field, -999 is automatic"};
126+
Configurable<double> bFieldInput{"trgH3L3Body.mBz", -999, "bz field, -999 is automatic"};
125127
Configurable<float> minCosPA3body{"trgH3L3Body.minCosPA3body", 0.9995, "minCosPA3body"};
126128
Configurable<float> dcavtxdau{"trgH3L3Body.dcavtxdau", 0.02, "meen DCA among Daughters"};
127129
Configurable<float> dcapiontopv{"trgH3L3Body.dcapiontopv", 0.05, "DCA Pion To PV"};
@@ -200,6 +202,14 @@ struct nucleiFilter {
200202
fitter3body.setMaxChi2(1e9);
201203
fitter3body.setUseAbsDCA(true);
202204

205+
fitter2body.setPropagateToPCA(true);
206+
fitter2body.setMaxR(200.);
207+
fitter2body.setMinParamChange(1e-3);
208+
fitter2body.setMinRelChi2Change(0.9);
209+
fitter2body.setMaxDZIni(1e9);
210+
fitter2body.setMaxChi2(1e9);
211+
fitter2body.setUseAbsDCA(true);
212+
203213
ccdb->setURL(trgH3L3Body.ccdburl);
204214
ccdb->setCaching(true);
205215
ccdb->setLocalObjectValidityChecking();
@@ -213,12 +223,11 @@ struct nucleiFilter {
213223
}
214224

215225
// In case override, don't proceed, please - no CCDB access required
216-
if (trgH3L3Body.d_bz_input > -990) {
217-
d_bz = trgH3L3Body.d_bz_input;
218-
fitter3body.setBz(d_bz);
226+
if (trgH3L3Body.bFieldInput > -990) {
227+
mBz = trgH3L3Body.bFieldInput;
219228
o2::parameters::GRPMagField grpmag;
220-
if (std::fabs(d_bz) > 1e-5) {
221-
grpmag.setL3Current(30000.f / (d_bz / 5.0f));
229+
if (std::fabs(mBz) > 1e-5) {
230+
grpmag.setL3Current(30000.f / (mBz / 5.0f));
222231
}
223232
o2::base::Propagator::initFieldFromGRP(&grpmag);
224233
mRunNumber = bc.runNumber();
@@ -231,22 +240,23 @@ struct nucleiFilter {
231240
if (grpo) {
232241
o2::base::Propagator::initFieldFromGRP(grpo);
233242
// Fetch magnetic field from ccdb for current collision
234-
d_bz = grpo->getNominalL3Field();
235-
LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kZG";
243+
mBz = grpo->getNominalL3Field();
244+
LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << mBz << " kZG";
236245
} else {
237246
grpmag = ccdb->getForTimeStamp<o2::parameters::GRPMagField>(trgH3L3Body.grpmagPath, run3grp_timestamp);
238247
if (!grpmag) {
239248
LOG(fatal) << "Got nullptr from CCDB for path " << trgH3L3Body.grpmagPath << " of object GRPMagField and " << trgH3L3Body.grpPath << " of object GRPObject for timestamp " << run3grp_timestamp;
240249
}
241250
o2::base::Propagator::initFieldFromGRP(grpmag);
242251
// Fetch magnetic field from ccdb for current collision
243-
// d_bz = std::lround(5.f * grpmag->getL3Current() / 30000.f);
244-
d_bz = o2::base::Propagator::Instance()->getNominalBz();
245-
LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kZG";
252+
// mBz = std::lround(5.f * grpmag->getL3Current() / 30000.f);
253+
mBz = o2::base::Propagator::Instance()->getNominalBz();
254+
LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << mBz << " kZG";
246255
}
247256
mRunNumber = bc.runNumber();
248257
// Set magnetic field value once known
249-
fitter3body.setBz(d_bz);
258+
fitter2body.setBz(mBz);
259+
fitter3body.setBz(mBz);
250260

251261
if (trgH3L3Body.useMatCorrType == 2) {
252262
// setMatLUT only after magfield has been initalized
@@ -457,11 +467,29 @@ struct nucleiFilter {
457467
float nSigmas[2]{
458468
cfgBetheBlochParams->get(2, 5u) > 0.f ? getNsigma(posTrack, 2, 0) : posTrack.tpcNSigmaHe(),
459469
cfgBetheBlochParams->get(2, 5u) > 0.f ? getNsigma(negTrack, 2, 1) : negTrack.tpcNSigmaHe()};
460-
if ((nSigmas[0] > cfgCutsPID->get(2, 0u) && nSigmas[0] < cfgCutsPID->get(2, 1u)) ||
461-
(nSigmas[1] > cfgCutsPID->get(2, 0u) && nSigmas[1] < cfgCutsPID->get(2, 1u))) {
462-
keepEvent[kHeV0] = true;
463-
break;
470+
if ((nSigmas[0] < cfgCutsPID->get(2, 0u) || nSigmas[0] > cfgCutsPID->get(2, 1u)) &&
471+
(nSigmas[1] < cfgCutsPID->get(2, 0u) || nSigmas[1] > cfgCutsPID->get(2, 1u))) {
472+
continue;
473+
}
474+
int n2bodyVtx = fitter2body.process(getTrackParCov(posTrack), getTrackParCov(negTrack));
475+
if (n2bodyVtx == 0) {
476+
continue;
477+
}
478+
auto vtxXYZ = fitter2body.getPCACandidate();
479+
o2::gpu::gpustd::array<float, 3> mom = {0.};
480+
vtxXYZ[0] -= collision.posX();
481+
vtxXYZ[1] -= collision.posY();
482+
vtxXYZ[2] -= collision.posZ();
483+
auto momTrackParCov = fitter2body.createParentTrackPar();
484+
momTrackParCov.getPxPyPzGlo(mom);
485+
double cosPA = (vtxXYZ[0] * mom[0] + vtxXYZ[1] * mom[1] + vtxXYZ[2] * mom[2]) /
486+
std::sqrt((vtxXYZ[0] * vtxXYZ[0] + vtxXYZ[1] * vtxXYZ[1] + vtxXYZ[2] * vtxXYZ[2]) *
487+
(mom[0] * mom[0] + mom[1] * mom[1] + mom[2] * mom[2]));
488+
if (cosPA < cfgCutCosPAheV0) {
489+
continue;
464490
}
491+
keepEvent[kHeV0] = true;
492+
break;
465493
}
466494

467495
//

0 commit comments

Comments
 (0)