Skip to content

Commit e10bdb3

Browse files
committed
[Common] add a function to get chi2IP in fwdtrackUtilities.h
1 parent 28f0ea4 commit e10bdb3

1 file changed

Lines changed: 62 additions & 0 deletions

File tree

Common/Core/fwdtrackUtilities.h

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,68 @@ o2::dataformats::GlobalFwdTrack refitGlobalMuonCov(TFwdTrack const& muon, TMFTTr
243243
return globalTrack;
244244
}
245245

246+
template <typename TFullFwdTrack, typename TCollision>
247+
float getFwdChi2IP(const TFullFwdTrack& fwdtrack, const TCollision& collision, const float bz, const float zShift)
248+
{
249+
// this function returns imcompatibility of fwdtrack respect to a given PV.
250+
// fwdtracks are never PV contributors in ALICE.
251+
// chi2IP is defined as chi2^{PV}_{with fwdtrack} - chi2^{PV}_{without fwdtrack}. https://arxiv.org/abs/2604.11574
252+
// chi2IP cannot be used to decide the best fwdtrack-to-collision match or MFT-MCH match, because it gives biases toward small muon impact parameter.
253+
// chi2IP should be used only after the best fwdtrack-to-collision association and the best MFT-MCH match are defined.
254+
255+
o2::track::TrackParCovFwd trk = getTrackParCovFwdShift(fwdtrack, zShift, fwdtrack);
256+
257+
if (std::abs(bz) < 1e-12) {
258+
trk.propagateToZlinear(collision.posZ());
259+
} else {
260+
trk.propagateToZhelix(collision.posZ(), bz);
261+
}
262+
263+
float x = trk.getX();
264+
float y = trk.getY();
265+
float phi = trk.getPhi();
266+
float tgl = trk.getTanl();
267+
268+
if (!std::isfinite(x) || !std::isfinite(y) || !std::isfinite(phi) || !std::isfinite(tgl) || std::abs(tgl) < 1e-8) {
269+
return -1.f;
270+
}
271+
272+
float dx = x - collision.posX();
273+
float dy = y - collision.posY();
274+
275+
// dx/dz and dy/dz for TrackParFwd.
276+
float tx = std::cos(phi) / tgl;
277+
float ty = std::sin(phi) / tgl;
278+
279+
const auto& ct = trk.getCovariances();
280+
281+
float trkXX = ct(0, 0);
282+
float trkXY = ct(0, 1);
283+
float trkYY = ct(1, 1);
284+
285+
float pvXX = collision.covXX() - 2.0 * tx * collision.covXZ() + tx * tx * collision.covZZ();
286+
float pvXY = collision.covXY() - ty * collision.covXZ() - tx * collision.covYZ() + tx * ty * collision.covZZ();
287+
float pvYY = collision.covYY() - 2.0 * ty * collision.covYZ() + ty * ty * collision.covZZ();
288+
289+
float sXX = trkXX + pvXX;
290+
float sXY = trkXY + pvXY;
291+
float sYY = trkYY + pvYY;
292+
293+
float det = sXX * sYY - sXY * sXY;
294+
295+
if (!std::isfinite(det) || det <= 0.0) {
296+
return -1.f;
297+
}
298+
299+
float chi2 = (sYY * dx * dx - 2.0 * sXY * dx * dy + sXX * dy * dy) / det;
300+
301+
if (!std::isfinite(chi2) || chi2 < -1e-8) {
302+
return -1.f;
303+
}
304+
305+
return std::max(0.f, chi2);
306+
}
307+
246308
} // namespace fwdtrackutils
247309
} // namespace o2::aod
248310

0 commit comments

Comments
 (0)