Project
Loading...
Searching...
No Matches
StrangenessTracker.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
13
14#include <numeric>
16#include "ITStracking/IOUtils.h"
18
19#ifdef ENABLE_UPGRADES
21#endif
22
23namespace o2
24{
25namespace strangeness_tracking
26{
27
29{
30 clear();
31
32 mInputV0tracks = recoData.getV0s();
33 mInputV0Indices = recoData.getV0sIdx();
38 if (mInputV0Indices.size() != mInputV0tracks.size() || mInputCascadeIndices.size() != mInputCascadeTracks.size() || mInput3BodyIndices.size() != mInput3BodyTracks.size()) {
39 LOGP(fatal, "Mismatch between input SVertices indices and kinematics (not requested?): V0: {}/{} Cascades: {}/{} Decay3Bodys: {}/{}",
41 }
42 mInputITStracks = recoData.getITSTracks();
44
45 int nLr = recoData.getITSPerLayer() ? o2::globaltracking::MaxITSLayers : 1;
47 mInputClusterSizes.clear();
48 for (int lr = 0; lr < nLr; lr++) { // with a single (monolithic) input all clusters are in the layer slot 0
50 auto compClus = recoData.getITSClusters(lr);
51 auto clusPatt = recoData.getITSClustersPatterns(lr);
52 auto pattIt = clusPatt.begin();
53 auto pattIt2 = clusPatt.begin();
54 int offs = (int)mInputClusterSizes.size();
55 mInputITSclusters.getClusters().reserve(offs + compClus.size());
56 mInputClusterSizes.resize(offs + compClus.size());
57#ifdef ENABLE_UPGRADES
60 getClusterSizesIT3(mInputClusterSizes, offs, compClus, pattIt2, mIT3Dict);
61 } else {
63 getClusterSizesITS(mInputClusterSizes, offs, compClus, pattIt2, mITSDict);
64 }
65#else
67 getClusterSizesITS(mInputClusterSizes, offs, compClus, pattIt2, mITSDict);
68#endif
69 }
71
72 mITSvtxBrackets.resize(mInputITStracks.size());
73 for (int i = 0; i < mInputITStracks.size(); i++) {
74 mITSvtxBrackets[i] = {-1, -1};
75 }
76
77 // build time bracket for each ITS track
78 auto trackIndex = recoData.getPrimaryVertexMatchedTracks(); // Global ID's for associated tracks
79 auto vtxRefs = recoData.getPrimaryVertexMatchedTrackRefs(); // references from vertex to these track IDs
80
82 int nv = vtxRefs.size();
83 for (int iv = 0; iv < nv; iv++) {
84 const auto& vtref = vtxRefs[iv];
85 int it = vtref.getFirstEntry(), itLim = it + vtref.getEntries();
86 for (; it < itLim; it++) {
87 auto tvid = trackIndex[it];
88 if (!recoData.isTrackSourceLoaded(tvid.getSource()) || tvid.getSource() != GIndex::ITS) {
89 continue;
90 }
91 if (mITSvtxBrackets[tvid.getIndex()].getMin() == -1) {
92 mITSvtxBrackets[tvid.getIndex()].setMin(iv);
93 mITSvtxBrackets[tvid.getIndex()].setMax(iv);
94 } else {
95 mITSvtxBrackets[tvid.getIndex()].setMax(iv);
96 }
97 }
98 }
99 }
100
101 if (mMCTruthON) {
104 }
105
106 LOG(debug) << "V0 tracks size: " << mInputV0tracks.size();
107 LOG(debug) << "Cascade tracks size: " << mInputCascadeTracks.size();
108 LOG(debug) << "Decay3Body tracks size: " << mInput3BodyTracks.size();
109 LOG(debug) << "ITS tracks size: " << mInputITStracks.size();
110 LOG(debug) << "ITS idxs size: " << mInputITSidxs.size();
111 LOG(debug) << "ITS clusters size: " << mInputITSclusters.size();
112 LOG(debug) << "VtxRefs size: " << vtxRefs.size();
113
114 return true;
115}
116
117void StrangenessTracker::prepareITStracks() // sort tracks by eta and phi and select only tracks with vertex matching
118{
119
120 for (int iTrack{0}; iTrack < mInputITStracks.size(); iTrack++) {
121 if (mStrParams->mVertexMatching && mITSvtxBrackets[iTrack].getMin() == -1) {
122 continue;
123 }
124 mSortedITStracks.push_back(mInputITStracks[iTrack]);
125 mSortedITSindexes.push_back(iTrack);
126 }
127
129 std::sort(mSortedITStracks.begin(), mSortedITStracks.end(), [&](o2::its::TrackITS& a, o2::its::TrackITS& b) { return mUtils.getBinIndex(a.getEta(), a.getPhi()) < mUtils.getBinIndex(b.getEta(), b.getPhi()); });
130 std::sort(mSortedITSindexes.begin(), mSortedITSindexes.end(), [&](int i, int j) { return mUtils.getBinIndex(mInputITStracks[i].getEta(), mInputITStracks[i].getPhi()) < mUtils.getBinIndex(mInputITStracks[j].getEta(), mInputITStracks[j].getPhi()); });
131
132 for (auto& track : mSortedITStracks) {
133 mTracksIdxTable[mUtils.getBinIndex(track.getEta(), track.getPhi())]++;
134 }
135 std::exclusive_scan(mTracksIdxTable.begin(), mTracksIdxTable.begin() + mUtils.mPhiBins * mUtils.mEtaBins, mTracksIdxTable.begin(), 0);
137}
138
139void StrangenessTracker::processV0(int iv0, const V0& v0, const V0Index& v0Idx, int iThread)
140{
141 if (mStrParams->mSkipTPC && ((v0Idx.getProngID(kV0DauNeg).getSource() == GIndex::TPC) || (v0Idx.getProngID(kV0DauPos).getSource() == GIndex::TPC))) {
142 return;
143 }
144 ClusAttachments structClus;
145 auto& daughterTracks = mDaughterTracks[iThread];
146 daughterTracks.resize(2); // resize to 2 prongs: first positive second negative
147 auto posTrack = v0.getProng(kV0DauPos);
148 auto negTrack = v0.getProng(kV0DauNeg);
149 auto alphaV0 = calcV0alpha(v0);
150 if (alphaV0 > 0) {
151 if (posTrack.getPID() != PID::Alpha) {
152 posTrack.setPID(PID::Helium3, true);
153 }
154 } else {
155 if (negTrack.getPID() != PID::Alpha) {
156 negTrack.setPID(PID::Helium3, true);
157 }
158 }
159 V0 correctedV0; // recompute V0 for Hypertriton
160 if (!recreateV0(posTrack, negTrack, correctedV0, iThread)) {
161 return;
162 }
163 StrangeTrack strangeTrack;
164 strangeTrack.mPartType = dataformats::kStrkV0;
165 auto v0R = std::sqrt(v0.calcR2());
166 auto iBinsV0 = mUtils.getBinRect(correctedV0.getEta(), correctedV0.getPhi(), mStrParams->mEtaBinSize, mStrParams->mPhiBinSize);
167 for (int& iBinV0 : iBinsV0) {
168 for (int iTrack{mTracksIdxTable[iBinV0]}; iTrack < TMath::Min(mTracksIdxTable[iBinV0 + 1], int(mSortedITStracks.size())); iTrack++) {
169 strangeTrack.mMother = (o2::track::TrackParCovF)correctedV0;
170 daughterTracks[kV0DauPos] = correctedV0.getProng(kV0DauPos);
171 daughterTracks[kV0DauNeg] = correctedV0.getProng(kV0DauNeg);
172 const auto& itsTrack = mSortedITStracks[iTrack];
173 const auto& ITSindexRef = mSortedITSindexes[iTrack];
174 if (mStrParams->mVertexMatching && (mITSvtxBrackets[ITSindexRef].getMin() > v0Idx.getVertexID() || mITSvtxBrackets[ITSindexRef].getMax() < v0Idx.getVertexID())) {
175 continue;
176 }
177 if (matchDecayToITStrack(v0R, strangeTrack, structClus, itsTrack, daughterTracks, iThread)) {
178 auto propInstance = o2::base::Propagator::Instance();
179 o2::track::TrackParCov decayVtxTrackClone = strangeTrack.mMother; // clone track and propagate to decay vertex
180 if (!propInstance->propagateToX(decayVtxTrackClone, strangeTrack.mDecayVtx[0], getBz(), o2::base::PropagatorImpl<float>::MAX_SIN_PHI, o2::base::PropagatorImpl<float>::MAX_STEP, mCorrType)) {
181 LOG(debug) << "Mother propagation to decay vertex failed";
182 continue;
183 }
184 decayVtxTrackClone.getPxPyPzGlo(strangeTrack.mDecayMom);
185 std::array<float, 3> momPos, momNeg;
186 mFitter3Body[iThread].getTrack(kV0DauPos).getPxPyPzGlo(momPos);
187 mFitter3Body[iThread].getTrack(kV0DauNeg).getPxPyPzGlo(momNeg);
188 if (alphaV0 > 0) {
189 strangeTrack.mMasses[0] = calcMotherMass(momPos, momNeg, PID::Helium3, PID::Pion); // Hypertriton invariant mass at decay vertex
190 strangeTrack.mMasses[1] = calcMotherMass(momPos, momNeg, PID::Alpha, PID::Pion); // Hyperhydrogen4Lam invariant mass at decay vertex
191 } else {
192 strangeTrack.mMasses[0] = calcMotherMass(momPos, momNeg, PID::Pion, PID::Helium3); // Anti-Hypertriton invariant mass at decay vertex
193 strangeTrack.mMasses[1] = calcMotherMass(momPos, momNeg, PID::Pion, PID::Alpha); // Anti-Hyperhydrogen4Lam invariant mass at decay vertex
194 }
195
196 LOG(debug) << "ITS Track matched with a V0 decay topology ....";
197 LOG(debug) << "Number of ITS track clusters attached: " << itsTrack.getNumberOfClusters();
198 strangeTrack.mDecayRef = iv0;
199 strangeTrack.mITSRef = mSortedITSindexes[iTrack];
200 mStrangeTrackVec[iThread].push_back(strangeTrack);
201 mClusAttachments[iThread].push_back(structClus);
202 if (mMCTruthON) {
203 auto lab = getStrangeTrackLabel(itsTrack, strangeTrack, structClus);
204 mStrangeTrackLabels[iThread].push_back(lab);
205 }
206 }
207 }
208 }
209}
210
211void StrangenessTracker::processCascade(int iCasc, const Cascade& casc, const CascadeIndex& cascIdx, const V0& cascV0, int iThread)
212{
213 ClusAttachments structClus;
214 auto& daughterTracks = mDaughterTracks[iThread];
215 daughterTracks.resize(3); // resize to 3 prongs: first bachelor, second V0 pos, third V0 neg
216
217 StrangeTrack strangeTrack;
219 // first: bachelor, second: V0 pos, third: V0 neg
220 auto cascR = std::sqrt(casc.calcR2());
221 auto iBinsCasc = mUtils.getBinRect(casc.getEta(), casc.getPhi(), mStrParams->mEtaBinSize, mStrParams->mPhiBinSize);
222 for (int& iBinCasc : iBinsCasc) {
223 for (int iTrack{mTracksIdxTable[iBinCasc]}; iTrack < TMath::Min(mTracksIdxTable[iBinCasc + 1], int(mSortedITStracks.size())); iTrack++) {
224 strangeTrack.mMother = (o2::track::TrackParCovF)casc;
225 daughterTracks[kV0DauPos] = cascV0.getProng(kV0DauPos);
226 daughterTracks[kV0DauNeg] = cascV0.getProng(kV0DauNeg);
227 daughterTracks[kBach] = casc.getBachelorTrack();
228 const auto& itsTrack = mSortedITStracks[iTrack];
229 const auto& ITSindexRef = mSortedITSindexes[iTrack];
230 LOG(debug) << "----------------------";
231 LOG(debug) << "CascV0: " << cascIdx.getV0ID() << ", Bach ID: " << cascIdx.getBachelorID() << ", ITS track ref: " << mSortedITSindexes[iTrack];
232 if (mStrParams->mVertexMatching && (mITSvtxBrackets[ITSindexRef].getMin() > cascIdx.getVertexID() || mITSvtxBrackets[ITSindexRef].getMax() < cascIdx.getVertexID())) {
233 LOG(debug) << "Vertex ID mismatch: " << mITSvtxBrackets[ITSindexRef].getMin() << " < " << cascIdx.getVertexID() << " < " << mITSvtxBrackets[ITSindexRef].getMax();
234 continue;
235 }
236 if (matchDecayToITStrack(cascR, strangeTrack, structClus, itsTrack, daughterTracks, iThread)) {
237 auto propInstance = o2::base::Propagator::Instance();
238 o2::track::TrackParCov decayVtxTrackClone = strangeTrack.mMother; // clone track and propagate to decay vertex
239 if (!propInstance->propagateToX(decayVtxTrackClone, strangeTrack.mDecayVtx[0], getBz(), o2::base::PropagatorImpl<float>::MAX_SIN_PHI, o2::base::PropagatorImpl<float>::MAX_STEP, mCorrType)) {
240 LOG(debug) << "Mother propagation to decay vertex failed";
241 continue;
242 }
243 decayVtxTrackClone.getPxPyPzGlo(strangeTrack.mDecayMom);
244 std::array<float, 3> momV0, momBach;
245 mFitter3Body[iThread].getTrack(0).getPxPyPzGlo(momV0); // V0 momentum at decay vertex
246 mFitter3Body[iThread].getTrack(1).getPxPyPzGlo(momBach); // bachelor momentum at decay vertex
247 strangeTrack.mMasses[0] = calcMotherMass(momV0, momBach, PID::Lambda, PID::Pion); // Xi invariant mass at decay vertex
248 strangeTrack.mMasses[1] = calcMotherMass(momV0, momBach, PID::Lambda, PID::Kaon); // Omega invariant mass at decay vertex
249
250 LOG(debug) << "ITS Track matched with a Cascade decay topology ....";
251 LOG(debug) << "Number of ITS track clusters attached: " << itsTrack.getNumberOfClusters();
252
253 strangeTrack.mDecayRef = iCasc;
254 strangeTrack.mITSRef = mSortedITSindexes[iTrack];
255 mStrangeTrackVec[iThread].push_back(strangeTrack);
256 mClusAttachments[iThread].push_back(structClus);
257 if (mMCTruthON) {
258 auto lab = getStrangeTrackLabel(itsTrack, strangeTrack, structClus);
259 mStrangeTrackLabels[iThread].push_back(lab);
260 }
261 }
262 }
263 }
264}
265
266void StrangenessTracker::process3Body(int i3Body, const Decay3Body& dec3body, const Decay3BodyIndex& dec3bodyIdx, int iThread)
267{
268 if (!mStrParams->mSkip3Body) {
269 ClusAttachments structClus;
270 auto& daughterTracks = mDaughterTracks[iThread];
271 daughterTracks.resize(3); // resize to 3 prongs
272
273 StrangeTrack strangeTrack;
275 auto dec3bodyR = std::sqrt(dec3body.calcR2());
276 auto iBins3Body = mUtils.getBinRect(dec3body.getEta(), dec3body.getPhi(), mStrParams->mEtaBinSize, mStrParams->mPhiBinSize);
277 for (int& iBin3Body : iBins3Body) {
278 for (int iTrack{mTracksIdxTable[iBin3Body]}; iTrack < TMath::Min(mTracksIdxTable[iBin3Body + 1], int(mSortedITStracks.size())); iTrack++) {
279 strangeTrack.mMother = (o2::track::TrackParCovF)dec3body;
281 daughterTracks[kV0DauPos] = dec3body.getProng(kV0DauPos); // proton
282 daughterTracks[kV0DauNeg] = dec3body.getProng(kV0DauNeg); // pion
283 daughterTracks[kBach] = dec3body.getProng(kBach); // deuteron
284 const auto& itsTrack = mSortedITStracks[iTrack];
285 const auto& ITSindexRef = mSortedITSindexes[iTrack];
286 if (mStrParams->mVertexMatching && (mITSvtxBrackets[ITSindexRef].getMin() > dec3bodyIdx.getVertexID() || mITSvtxBrackets[ITSindexRef].getMax() < dec3bodyIdx.getVertexID())) {
287 continue;
288 }
289 if (matchDecayToITStrack(dec3bodyR, strangeTrack, structClus, itsTrack, daughterTracks, iThread)) {
290 auto propInstance = o2::base::Propagator::Instance();
291 o2::track::TrackParCov decayVtxTrackClone = strangeTrack.mMother; // clone track and propagate to decay vertex
292 if (!propInstance->propagateToX(decayVtxTrackClone, strangeTrack.mDecayVtx[0], getBz(), o2::base::PropagatorImpl<float>::MAX_SIN_PHI, o2::base::PropagatorImpl<float>::MAX_STEP, mCorrType)) {
293 LOG(debug) << "Mother propagation to decay vertex failed";
294 continue;
295 }
296 decayVtxTrackClone.getPxPyPzGlo(strangeTrack.mDecayMom);
297 std::array<float, 3> momPos, momNeg, momBach;
298 mFitter4Body[iThread].propagateTracksToVertex();
299 mFitter4Body[iThread].getTrack(kV0DauPos).getPxPyPzGlo(momPos);
300 mFitter4Body[iThread].getTrack(kV0DauNeg).getPxPyPzGlo(momNeg);
301 mFitter4Body[iThread].getTrack(kBach).getPxPyPzGlo(momBach);
303 if (daughterTracks[kBach].getCharge() > 0) {
304 strangeTrack.mMasses[0] = calcMotherMass3body(momPos, momNeg, momBach, PID::Proton, PID::Pion, PID::Deuteron);
305 } else {
306 strangeTrack.mMasses[0] = calcMotherMass3body(momPos, momNeg, momBach, PID::Pion, PID::Proton, PID::Deuteron);
307 }
308
309 LOG(debug) << "ITS Track matched with a dec3body decay topology ....";
310 LOG(debug) << "Number of ITS track clusters attached: " << itsTrack.getNumberOfClusters();
311 strangeTrack.mDecayRef = i3Body;
312 strangeTrack.mITSRef = mSortedITSindexes[iTrack];
313 mStrangeTrackVec[iThread].push_back(strangeTrack);
314 mClusAttachments[iThread].push_back(structClus);
315 if (mMCTruthON) {
316 auto lab = getStrangeTrackLabel(itsTrack, strangeTrack, structClus);
317 mStrangeTrackLabels[iThread].push_back(lab);
318 }
319 }
320 }
321 }
322 } else {
323 return;
324 }
325}
326
328{
329 // Loop over V0s
330 for (int iV0{0}; iV0 < mInputV0tracks.size(); iV0++) {
331 LOG(debug) << "Analysing V0: " << iV0 + 1 << "/" << mInputV0tracks.size();
333 }
334
335 // Loop over Cascades
336 for (int iCasc{0}; iCasc < mInputCascadeTracks.size(); iCasc++) {
337 LOG(debug) << "Analysing Cascade: " << iCasc + 1 << "/" << mInputCascadeTracks.size();
339 }
340
341 // Loop over 3bodys
342 if (!mStrParams->mSkip3Body) {
343 for (int i3Body{0}; i3Body < mInput3BodyTracks.size(); i3Body++) {
344 LOG(debug) << "Analysing 3-Body: " << i3Body + 1 << "/" << mInput3BodyTracks.size();
345 process3Body(i3Body, mInput3BodyTracks[i3Body], mInput3BodyIndices[i3Body]);
346 }
347 }
348}
349
350bool StrangenessTracker::matchDecayToITStrack(float decayR, StrangeTrack& strangeTrack, ClusAttachments& structClus, const TrackITS& itsTrack, std::vector<o2::track::TrackParCovF>& daughterTracks, int iThread)
351{
353 auto trackClusters = getTrackClusters(itsTrack);
354 auto trackClusSizes = getTrackClusterSizes(itsTrack);
355 auto& lastClus = trackClusters[0];
356
357 auto radTol = decayR < 4 ? mStrParams->mRadiusTolIB : mStrParams->mRadiusTolOB;
358 auto nMinClusMother = trackClusters.size() < 4 ? 2 : mStrParams->mMinMotherClus;
359
360 std::vector<ITSCluster> motherClusters;
361 std::array<int, 7> nAttachments;
362 nAttachments.fill(-1); // fill arr with -1
363
364 int nUpdates = 0;
365 bool isMotherUpdated = false;
366
367 for (int iClus{0}; iClus < trackClusters.size(); iClus++) {
368 auto& clus = trackClusters[iClus];
369 auto& compClus = trackClusSizes[iClus];
370 int nUpdOld = nUpdates;
371 double clusRad = sqrt(clus.getX() * clus.getX() - clus.getY() * clus.getY());
372 auto diffR = decayR - clusRad;
373 auto relDiffR = diffR / decayR;
374 auto lay = geom->getLayer(clus.getSensorID());
375 // Look for the Mother if the Decay radius allows for it, within a tolerance
376 LOG(debug) << "decayR: " << decayR << ", diffR: " << diffR << ", clus rad: " << clusRad << ", radTol: " << radTol;
377 if (relDiffR > -radTol) {
378 LOG(debug) << "Try to attach cluster to Mother, layer: " << lay;
379 if (updateTrack(clus, strangeTrack.mMother)) {
380 motherClusters.push_back(clus);
381 strangeTrack.setClusterSize(lay, compClus);
382 nAttachments[lay] = 0;
383 isMotherUpdated = true;
384 nUpdates++;
385 LOG(debug) << "Cluster attached to Mother";
386 continue; // if the cluster is attached to the mother, skip the rest of the loop
387 }
388 }
389
390 // if Mother is not found, check for V0 daughters compatibility
391 if (relDiffR < radTol && !isMotherUpdated) {
392 bool isDauUpdated = false;
393 LOG(debug) << "Try to attach cluster to Daughters, layer: " << lay;
394 for (int iDau{0}; iDau < daughterTracks.size(); iDau++) {
395 auto& dauTrack = daughterTracks[iDau];
396 if (updateTrack(clus, dauTrack)) {
397 nAttachments[lay] = iDau + 1;
398 isDauUpdated = true;
399 break;
400 }
401 }
402 if (!isDauUpdated) {
403 break; // no daughter track updated, stop the loop
404 }
405 nUpdates++;
406 }
407 if (nUpdates == nUpdOld) {
408 break; // no track updated, stop the loop
409 }
410 }
411
412 if (nUpdates < trackClusters.size() || motherClusters.size() < nMinClusMother) {
413 return false;
414 }
415
416 o2::track::TrackParCov motherTrackClone = strangeTrack.mMother; // clone and reset covariance for final topology refit
417 motherTrackClone.resetCovariance();
418
419 LOG(debug) << "Clusters attached, starting inward-outward refit";
420
421 std::reverse(motherClusters.begin(), motherClusters.end());
422
423 mGlobalChi2 = 0;
424 for (auto& clus : motherClusters) {
425 if (!updateTrack(clus, motherTrackClone)) {
426 break;
427 }
428 }
429 strangeTrack.mMatchChi2 = mGlobalChi2 / motherClusters.size();
430
431 LOG(debug) << "Inward-outward refit finished, starting final topology refit";
432 // final Topology refit
433
434 int cand = 0; // best V0 candidate
435 int nCand;
436
437 // refit cascade
438 if (strangeTrack.mPartType == dataformats::kStrkCascade) {
439 V0 cascV0Upd;
440 if (!recreateV0(daughterTracks[kV0DauPos], daughterTracks[kV0DauNeg], cascV0Upd, iThread)) {
441 LOG(debug) << "Cascade V0 refit failed";
442 return false;
443 }
444 try {
445 nCand = mFitter3Body[iThread].process(cascV0Upd, daughterTracks[kBach], motherTrackClone);
446 } catch (std::runtime_error& e) {
447 LOG(debug) << "Fitter3Body failed: " << e.what();
448 return false;
449 }
450 if (!nCand || !mFitter3Body[iThread].propagateTracksToVertex()) {
451 LOG(debug) << "Fitter3Body failed: propagation to vertex failed";
452 return false;
453 }
454 }
455
456 // refit V0
457 else if (strangeTrack.mPartType == dataformats::kStrkV0) {
458 try {
459 nCand = mFitter3Body[iThread].process(daughterTracks[kV0DauPos], daughterTracks[kV0DauNeg], motherTrackClone);
460 } catch (std::runtime_error& e) {
461 LOG(debug) << "Fitter3Body failed: " << e.what();
462 return false;
463 }
464 if (!nCand || !mFitter3Body[iThread].propagateTracksToVertex()) {
465 LOG(debug) << "Fitter3Body failed: propagation to vertex failed";
466 return false;
467 }
468 }
469
470 // refit 3body
471 else if (strangeTrack.mPartType == dataformats::kStrkThreeBody) {
472 try {
473 nCand = mFitter4Body[iThread].process(daughterTracks[kV0DauPos], daughterTracks[kV0DauNeg], daughterTracks[kBach], motherTrackClone);
474 } catch (std::runtime_error& e) {
475 LOG(debug) << "Fitter4Body failed: " << e.what();
476 return false;
477 }
478 if (!nCand || !mFitter4Body[iThread].propagateTracksToVertex()) {
479 LOG(debug) << "Fitter4Body failed: propagation to vertex failed";
480 return false;
481 }
482 }
483
484 if (strangeTrack.mPartType == dataformats::kStrkThreeBody) {
485 strangeTrack.mDecayVtx = mFitter4Body[iThread].getPCACandidatePos();
486 strangeTrack.mTopoChi2 = mFitter4Body[iThread].getChi2AtPCACandidate();
487 } else {
488 strangeTrack.mDecayVtx = mFitter3Body[iThread].getPCACandidatePos();
489 strangeTrack.mTopoChi2 = mFitter3Body[iThread].getChi2AtPCACandidate();
490 }
491 structClus.arr = nAttachments;
492 return true;
493}
494
496{
498 auto propInstance = o2::base::Propagator::Instance();
499 float alpha = geom->getSensorRefAlpha(clus.getSensorID()), x = clus.getX();
500 int layer{geom->getLayer(clus.getSensorID())};
501
502 if (!track.rotate(alpha)) {
503 return false;
504 }
505
507 return false;
508 }
509
510 if (mCorrType == o2::base::PropagatorF::MatCorrType::USEMatCorrNONE) {
511 float thick = layer < 3 ? 0.005 : 0.01;
512 constexpr float radl = 9.36f; // Radiation length of Si [cm]
513 constexpr float rho = 2.33f; // Density of Si [g/cm^3]
514 if (!track.correctForMaterial(thick, thick * rho * radl)) {
515 return false;
516 }
517 }
518 auto chi2 = track.getPredictedChi2Quiet(clus); // abs to be understood
519 if (std::abs(chi2) > mStrParams->mMaxChi2) {
520 return false;
521 }
522
523 if (!track.update(clus)) {
524 return false;
525 }
526
527 mGlobalChi2 += chi2;
528 return true;
529}
530
531} // namespace strangeness_tracking
532} // namespace o2
std::ostringstream debug
int32_t i
float chi2
uint32_t j
Definition RawData.h:0
T getX() const
Definition BaseCluster.h:62
std::int16_t getSensorID() const
Definition BaseCluster.h:81
GPUd() value_type estimateLTFast(o2 static GPUd() float estimateLTIncrement(const o2 PropagatorImpl * Instance(bool uninitialized=false)
Definition Propagator.h:180
const Track & getBachelorTrack() const
Definition Cascade.h:40
TO BE DONE: extend to generic N body vertex.
Definition Decay3Body.h:26
const Track & getProng(int i) const
Definition Decay3Body.h:34
const Track & getProng(int i) const
Definition V0.h:39
float calcR2() const
Definition V0.h:63
static GeometryTGeo * Instance()
void beginLayer(int lr)
to be called once all the layers were filled
void init(int nLr)
< prepare for filling nLr layer slots, discarding the previous content
std::vector< std::vector< o2::track::TrackParCovF > > mDaughterTracks
o2::MCCompLabel getStrangeTrackLabel(const TrackITS &itsTrack, const StrangeTrack &strangeTrack, const ClusAttachments &structClus)
const StrangenessTrackingParamConfig * mStrParams
double calcMotherMass(const std::array< float, 3 > &pDauFirst, const std::array< float, 3 > &pDauSecond, PID pidDauFirst, PID pidDauSecond)
gsl::span< const TrackITS > mInputITStracks
global topology matching chi2
std::vector< std::vector< StrangeTrack > > mStrangeTrackVec
void processV0(int iv0, const V0 &v0, const V0Index &v0Idx, int iThread=0)
void processCascade(int icasc, const Cascade &casc, const CascadeIndex &cascIdx, const V0 &cascV0, int iThread=0)
std::vector< ITSCluster > getTrackClusters(const TrackITS &itsTrack)
o2::base::PropagatorImpl< float >::MatCorrType mCorrType
std::vector< int > getTrackClusterSizes(const TrackITS &itsTrack)
std::vector< std::vector< o2::MCCompLabel > > mStrangeTrackLabels
bool matchDecayToITStrack(float decayR, StrangeTrack &strangeTrack, ClusAttachments &structClus, const TrackITS &itsTrack, std::vector< o2::track::TrackParCovF > &daughterTracks, int iThread=0)
std::vector< o2::its::TrackITS > mSortedITStracks
input ITS Track MC labels
gsl::span< const Decay3Body > mInput3BodyTracks
bool recreateV0(const o2::track::TrackParCov &posTrack, const o2::track::TrackParCov &negTrack, V0 &newV0, int iThread=0)
std::vector< std::vector< ClusAttachments > > mClusAttachments
double calcMotherMass3body(const std::array< float, 3 > &pDauFirst, const std::array< float, 3 > &pDauSecond, const std::array< float, 3 > &pDauThird, PID pidDauFirst, PID pidDauSecond, PID pidDauThird)
float mGlobalChi2
number of threads (externally driven)
bool updateTrack(const ITSCluster &clus, o2::track::TrackParCov &track)
void process3Body(int i3body, const Decay3Body &dec3body, const Decay3BodyIndex &dec3bodyIdx, int iThread=0)
gsl::span< const Decay3BodyIndex > mInput3BodyIndices
const o2::itsmft::TopologyDictionary * mITSDict
gsl::span< const CascadeIndex > mInputCascadeIndices
bool loadData(const o2::globaltracking::RecoContainer &recoData)
void getClusterSizesITS(std::vector< int > &clusSizeVec, int offs, const gsl::span< const o2::itsmft::CompClusterExt > ITSclus, gsl::span< const unsigned char >::iterator &pattIt, const o2::itsmft::TopologyDictionary *mdict)
MCLabSpan mITSTrkLabels
input ITS Cluster MC labels
GLfloat GLfloat GLfloat alpha
Definition glcorearb.h:279
GLint GLenum GLint x
Definition glcorearb.h:403
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLfloat v0
Definition glcorearb.h:811
GLenum GLuint GLint GLint layer
Definition glcorearb.h:1310
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
constexpr int MaxITSLayers
void convertCompactClusters(gsl::span< const itsmft::CompClusterExt > clusters, gsl::span< const unsigned char >::iterator &pattIt, std::vector< o2::BaseCluster< float > > &output, const o2::its3::TopologyDictionary *dict)
convert compact clusters to 3D spacepoints
Definition IOUtils.cxx:25
void convertCompactClusters(gsl::span< const itsmft::CompClusterExt > clusters, gsl::span< const unsigned char >::iterator &pattIt, std::vector< o2::BaseCluster< float > > &output, const itsmft::TopologyDictionary *dict)
convert compact clusters to 3D spacepoints
Definition IOUtils.cxx:35
TrackParCovF TrackParCov
Definition Track.h:33
TrackParametrizationWithError< float > TrackParCovF
Definition Track.h:31
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
o2::track::TrackParCovF mMother
std::array< float, 3 > mDecayVtx
std::array< float, 3 > mDecayMom
std::array< float, 2 > mMasses
void setClusterSize(int l, int size)
auto getITSClustersPatterns(int layer=0) const
auto getITSClusters(int layer=0) const
auto getITSClustersMCLabels(int layer=0) const
std::vector< int > getBinRect(float eta, float phi, float deltaEta, float deltaPhi)
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"