Skip to content

Commit fac9fd9

Browse files
committed
Update tracking algorithm (#10)
1 parent f5a1ef9 commit fac9fd9

2 files changed

Lines changed: 97 additions & 52 deletions

File tree

Detectors/StrangenessTracking/tracking/include/StrangenessTracking/HyperTracker.h

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
// granted to it by virtue of its status as an Intergovernmental Organization
1010
// or submit itself to any jurisdiction.
1111

12-
/// \file HyperTracker.h
12+
/// \file hyperTracker.h
1313
/// \brief hypertracker
14-
/// \author francesco.mazzaschi@cern.ch
14+
///
1515

1616
#ifndef _ALICEO2_HYPER_TRACKER_
1717
#define _ALICEO2_HYPER_TRACKER_
@@ -20,36 +20,38 @@
2020
#include "DataFormatsITS/TrackITS.h"
2121
#include "ITSBase/GeometryTGeo.h"
2222
#include "ReconstructionDataFormats/Track.h"
23-
#include "DetectorsVertexing/DCAFitterN.h"
24-
2523
#include <TLorentzVector.h>
2624
#include "TMath.h"
25+
#include "DetectorsVertexing/DCAFitterN.h"
26+
#include "DetectorsBase/Propagator.h"
2727

2828
namespace o2
2929
{
3030
namespace tracking
3131
{
3232

33-
class HyperTracker
33+
class hyperTracker
3434
{
3535
public:
3636
using PID = o2::track::PID;
3737
using TrackITS = o2::its::TrackITS;
3838
using ITSCluster = o2::BaseCluster<float>;
3939
using V0 = o2::dataformats::V0;
4040
using DCAFitter2 = o2::vertexing::DCAFitterN<2>;
41+
using DCAFitter3 = o2::vertexing::DCAFitterN<3>;
4142

42-
HyperTracker() = default;
43-
HyperTracker(const TrackITS& motherTrack, const V0& v0, const std::vector<ITSCluster>& motherClusters, o2::its::GeometryTGeo* gman, DCAFitter2& mFitterV0); //recompute V0 using hypertriton hypothesis
44-
HyperTracker(const TrackITS& motherTrack, const V0& v0, const std::vector<ITSCluster>& motherClusters, o2::its::GeometryTGeo* gman);
43+
hyperTracker() = default;
44+
hyperTracker(const TrackITS& motherTrack, const V0& v0, const std::vector<ITSCluster>& motherClusters, o2::its::GeometryTGeo* gman, DCAFitter2& mFitterV0); // recompute V0 using hypertriton hypothesis
45+
hyperTracker(const TrackITS& motherTrack, const V0& v0, const std::vector<ITSCluster>& motherClusters, o2::its::GeometryTGeo* gman);
4546

4647
double getMatchingChi2();
4748
double calcV0alpha(const V0& v0);
4849
bool process();
4950
bool propagateToClus(const ITSCluster& clus, o2::track::TrackParCov& track);
50-
int updateV0topology(const ITSCluster& clus, bool tryDaughter);
51+
bool updateTrack(const ITSCluster& clus, o2::track::TrackParCov& track);
5152
bool recreateV0(const o2::track::TrackParCov& posTrack, const o2::track::TrackParCov& negTrack, const int posID, const int negID);
5253
V0& getV0() { return hypV0; };
54+
bool Refit3Body();
5355

5456
float getNclusMatching() const { return nClusMatching; }
5557
void setNclusMatching(float d) { nClusMatching = d; }
@@ -64,12 +66,16 @@ class HyperTracker
6466
TrackITS hyperTrack; // track of hypertriton mother
6567
V0 hypV0; // V0 of decay daughters
6668
std::vector<ITSCluster> hyperClusters; // clusters of hypertriton mother
67-
o2::its::GeometryTGeo* geomITS; //geometry for ITS clusters
69+
o2::its::GeometryTGeo* geomITS; // geometry for ITS clusters
6870
DCAFitter2 mFitterV0; // optional DCA Fitter for recreating V0 with hypertriton mass hypothesis
71+
DCAFitter3 mFitter3Body; // optional DCA Fitter for recreating V0 with hypertriton mass hypothesis
6972

7073
int nClusMatching; // number of cluster to be matched to V0
74+
float mInitR2;
7175
float mMaxChi2 = 40;
7276
float mBz = -5;
77+
78+
ClassDefNV(hyperTracker, 1);
7379
};
7480

7581
} // namespace tracking

Detectors/StrangenessTracking/tracking/src/HyperTracker.cxx

Lines changed: 81 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -9,36 +9,39 @@
99
// granted to it by virtue of its status as an Intergovernmental Organization
1010
// or submit itself to any jurisdiction.
1111

12-
#include "StrangenessTracking/HyperTracker.h"
12+
#include "hyperTracker.h"
1313
namespace o2
1414
{
1515
namespace tracking
1616
{
1717

18-
HyperTracker::HyperTracker(const TrackITS& motherTrack, const V0& v0, const std::vector<ITSCluster>& motherClusters, o2::its::GeometryTGeo* gman, DCAFitter2& mFitterV0)
18+
hyperTracker::hyperTracker(const TrackITS& motherTrack, const V0& v0, const std::vector<ITSCluster>& motherClusters, o2::its::GeometryTGeo* gman, DCAFitter2& mFitterV0)
1919
: hyperTrack{motherTrack}, hyperClusters{motherClusters}, geomITS{gman}, mFitterV0{mFitterV0}
2020
{
21+
mInitR2 = v0.calcR2();
22+
LOG(INFO) << "Original V0 radius: " << v0.calcR2();
2123

2224
auto posTrack = v0.getProng(0);
2325
auto negTrack = v0.getProng(1);
2426
auto alphaV0 = calcV0alpha(v0);
2527
alphaV0 > 0 ? posTrack.setAbsCharge(2) : negTrack.setAbsCharge(2);
2628

2729
auto isRecr = recreateV0(posTrack, negTrack, v0.getProngID(0), v0.getProngID(1));
30+
2831
if (!isRecr) {
2932
LOG(INFO) << "V0 regeneration not successful, using default one";
3033
hypV0 = v0;
3134
}
3235
setNclusMatching(motherClusters.size());
3336
}
3437

35-
HyperTracker::HyperTracker(const TrackITS& motherTrack, const V0& v0, const std::vector<ITSCluster>& motherClusters, o2::its::GeometryTGeo* gman)
38+
hyperTracker::hyperTracker(const TrackITS& motherTrack, const V0& v0, const std::vector<ITSCluster>& motherClusters, o2::its::GeometryTGeo* gman)
3639
: hyperTrack{motherTrack}, hypV0{v0}, hyperClusters{motherClusters}, geomITS{gman}
3740
{
3841
setNclusMatching(motherClusters.size());
3942
}
4043

41-
double HyperTracker::getMatchingChi2()
44+
double hyperTracker::getMatchingChi2()
4245
{
4346
auto& outerClus = hyperClusters[0];
4447
float alpha = geomITS->getSensorRefAlpha(outerClus.getSensorID()), x = outerClus.getX();
@@ -48,65 +51,69 @@ double HyperTracker::getMatchingChi2()
4851

4952
if (hypV0.rotate(alpha)) {
5053
if (hypV0.propagateTo(x, mBz)) {
54+
5155
std::cout << "Pred chi2 outermost Cluster: " << hypV0.getPredictedChi2(outerClus) << std::endl;
5256
std::cout << "Pred chi2 V0-ITStrack: " << hypV0.getPredictedChi2(hyperTrack.getParamOut()) << std::endl;
53-
return hypV0.getPredictedChi2(hyperTrack.getParamOut());
57+
return hypV0.getPredictedChi2(outerClus);
5458
}
5559
}
5660
return -1;
5761
}
5862

59-
bool HyperTracker::process()
63+
bool hyperTracker::process()
6064
{
65+
std::vector<o2::tracking::hyperTracker::ITSCluster> ITSclusV0;
6166
int isProcessed = 0;
6267
bool tryDaughter = true;
6368

6469
for (auto& clus : hyperClusters) {
70+
auto diffR2 = mInitR2 - clus.getX() * clus.getX() - clus.getY() * clus.getY();
71+
72+
// check V0 compatibility
73+
if (diffR2 > -4) {
74+
if (updateTrack(clus, hypV0)) {
75+
tryDaughter = false;
76+
LOG(INFO) << "Attach cluster to V0 for layer: " << geomITS->getLayer(clus.getSensorID());
77+
isProcessed++;
78+
ITSclusV0.push_back(clus);
79+
}
80+
}
6581

66-
if (updateV0topology(clus, tryDaughter) == 1) {
67-
tryDaughter = false;
68-
isProcessed++;
69-
LOG(INFO) << "Attach cluster to V0 for layer: " << geomITS->getLayer(clus.getSensorID());
70-
continue;
71-
} else if (updateV0topology(clus, tryDaughter) == 2) {
82+
// if V0 is not found, check He3 compatibility
83+
if (diffR2 < 4 && tryDaughter == true) {
84+
auto& he3track = calcV0alpha(hypV0) > 0 ? hypV0.getProng(0) : hypV0.getProng(1);
85+
if (!updateTrack(clus, he3track))
86+
return false; // no V0 or He3 compatible clusters
7287
recreateV0(hypV0.getProng(0), hypV0.getProng(1), hypV0.getProngID(0), hypV0.getProngID(1));
73-
isProcessed++;
7488
LOG(INFO) << "Attach cluster to He3 for layer: " << geomITS->getLayer(clus.getSensorID());
89+
isProcessed++;
7590
continue;
76-
} else {
77-
break;
7891
}
92+
if (isProcessed == 0)
93+
return false; // no V0 or He3 compatible clusters
7994
}
80-
return isProcessed >= nClusMatching;
81-
}
8295

83-
int HyperTracker::updateV0topology(const ITSCluster& clus, bool tryDaughter)
84-
{
85-
int isUpdated = 0;
86-
87-
if (propagateToClus(clus, hypV0)) {
88-
if (hypV0.getPredictedChi2(clus) < mMaxChi2) {
89-
hypV0.update(clus);
90-
isUpdated++;
96+
// outward V0 propagation
97+
if (ITSclusV0.size() > 0) {
98+
hypV0.resetCovariance();
99+
std::reverse(ITSclusV0.begin(), ITSclusV0.end());
100+
for (auto& clus : ITSclusV0) {
101+
if (!updateTrack(clus, hypV0))
102+
return false;
91103
}
92104
}
93105

94-
if (!isUpdated && tryDaughter) {
95-
auto alphaArm = calcV0alpha(hypV0);
96-
auto& he3track = alphaArm > 0 ? hypV0.getProng(0) : hypV0.getProng(1);
97-
98-
if (propagateToClus(clus, he3track)) {
99-
if (he3track.getPredictedChi2(clus) < mMaxChi2) {
100-
he3track.update(clus);
101-
isUpdated += 2;
102-
}
103-
}
104-
}
105-
return isUpdated;
106+
// final 3body refit
107+
auto finalRefit = Refit3Body();
108+
if (!finalRefit)
109+
return false;
110+
LOG(INFO) << "Final V0 radius: " << hypV0.calcR2();
111+
return isProcessed >= nClusMatching;
106112
}
107113

108-
bool HyperTracker::propagateToClus(const ITSCluster& clus, o2::track::TrackParCov& track)
114+
bool hyperTracker::updateTrack(const ITSCluster& clus, o2::track::TrackParCov& track)
109115
{
116+
int isUpdated = 0;
110117
float alpha = geomITS->getSensorRefAlpha(clus.getSensorID()), x = clus.getX();
111118
int layer{geomITS->getLayer(clus.getSensorID())};
112119
float thick = layer < 3 ? 0.005 : 0.01;
@@ -115,16 +122,19 @@ bool HyperTracker::propagateToClus(const ITSCluster& clus, o2::track::TrackParCo
115122
if (track.propagateTo(x, mBz)) {
116123
constexpr float radl = 9.36f; // Radiation length of Si [cm]
117124
constexpr float rho = 2.33f; // Density of Si [g/cm^3]
118-
return track.correctForMaterial(thick, thick * rho * radl);
125+
if (track.correctForMaterial(thick, thick * rho * radl) && track.getPredictedChi2(clus) < mMaxChi2 && track.getPredictedChi2(clus) > 0) {
126+
track.update(clus);
127+
return true;
128+
}
119129
}
120130
}
121131
return false;
122132
}
123133

124-
bool HyperTracker::recreateV0(const o2::track::TrackParCov& posTrack, const o2::track::TrackParCov& negTrack, const int posID, const int negID)
134+
bool hyperTracker::recreateV0(const o2::track::TrackParCov& posTrack, const o2::track::TrackParCov& negTrack, const int posID, const int negID)
125135
{
126136

127-
int cand = 0; //best V0 candidate
137+
int cand = 0; // best V0 candidate
128138
int nCand;
129139

130140
try {
@@ -147,11 +157,40 @@ bool HyperTracker::recreateV0(const o2::track::TrackParCov& posTrack, const o2::
147157

148158
hypV0 = V0(v0XYZ, pV0, mFitterV0.calcPCACovMatrixFlat(cand), propPos, propNeg, posID, negID, o2::track::PID::HyperTriton);
149159
hypV0.setAbsCharge(1);
160+
hypV0.setPID(o2::track::PID::HyperTriton);
161+
return true;
162+
}
163+
164+
bool hyperTracker::Refit3Body()
165+
{
166+
167+
int cand = 0; // best V0 candidate
168+
int nCand;
169+
170+
try {
171+
nCand = mFitter3Body.process(hypV0, hypV0.getProng(0), hypV0.getProng(1));
172+
} catch (std::runtime_error& e) {
173+
return false;
174+
}
175+
if (!nCand)
176+
return false;
177+
178+
mFitter3Body.propagateTracksToVertex();
179+
auto& propPos = mFitter3Body.getTrack(1, 0);
180+
auto& propNeg = mFitter3Body.getTrack(2, 0);
181+
182+
const auto& v0XYZ = mFitter3Body.getPCACandidatePos();
183+
std::array<float, 3> pP, pN;
184+
propPos.getPxPyPzGlo(pP);
185+
propNeg.getPxPyPzGlo(pN);
186+
std::array<float, 3> pV0 = {pP[0] + pN[0], pP[1] + pN[1], pP[2] + pN[2]};
150187

188+
hypV0 = V0(v0XYZ, pV0, mFitter3Body.calcPCACovMatrixFlat(cand), propPos, propNeg, hypV0.getProngID(0), hypV0.getProngID(1), o2::track::PID::HyperTriton);
189+
hypV0.setAbsCharge(1);
151190
return true;
152191
}
153192

154-
double HyperTracker::calcV0alpha(const V0& v0)
193+
double hyperTracker::calcV0alpha(const V0& v0)
155194
{
156195
std::array<float, 3> fV0mom, fPmom, fNmom = {0, 0, 0};
157196
v0.getProng(0).getPxPyPzGlo(fPmom);

0 commit comments

Comments
 (0)