Project
Loading...
Searching...
No Matches
StrangenessTracker.h
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.
11
15
16#ifndef _ALICEO2_STRANGENESS_TRACKER_
17#define _ALICEO2_STRANGENESS_TRACKER_
18
19#include <gsl/gsl>
20
33
39
42
43#ifdef ENABLE_UPGRADES
45#endif
46
47namespace o2
48{
49namespace strangeness_tracking
50{
51
52enum DauType : int {
55 kBach = 2
56};
57
59
60 std::array<int, 7> arr;
61};
62
64{
65 public:
82 using MCLabSpan = gsl::span<const o2::MCCompLabel>;
84
85 StrangenessTracker() = default;
87
88 bool loadData(const o2::globaltracking::RecoContainer& recoData);
89 bool matchDecayToITStrack(float decayR, StrangeTrack& strangeTrack, ClusAttachments& structClus, const TrackITS& itsTrack, std::vector<o2::track::TrackParCovF>& daughterTracks, int iThread = 0);
90 void prepareITStracks();
91 void process();
92 void processV0(int iv0, const V0& v0, const V0Index& v0Idx, int iThread = 0);
93 void processCascade(int icasc, const Cascade& casc, const CascadeIndex& cascIdx, const V0& cascV0, int iThread = 0);
94 void process3Body(int i3body, const Decay3Body& dec3body, const Decay3BodyIndex& dec3bodyIdx, int iThread = 0);
95 bool updateTrack(const ITSCluster& clus, o2::track::TrackParCov& track);
96
97 std::vector<ClusAttachments>& getClusAttachments(int iThread = 0) { return mClusAttachments[iThread]; };
98 std::vector<StrangeTrack>& getStrangeTrackVec(int iThread = 0) { return mStrangeTrackVec[iThread]; };
99 std::vector<o2::MCCompLabel>& getStrangeTrackLabels(int iThread = 0) { return mStrangeTrackLabels[iThread]; };
100 size_t getNTracks(int ithread = 0) const { return ithread < (int)mStrangeTrackVec.size() ? mStrangeTrackVec[ithread].size() : 0; }
101
102 float getBz() const { return mBz; }
103 void setBz(float d) { mBz = d; }
107 void setMCTruthOn(bool v) { mMCTruthON = v; }
108 bool getMCTruthOn() const { return mMCTruthON; }
109
110#ifdef ENABLE_UPGRADES
111 void setClusterDictionaryIT3(const o2::its3::TopologyDictionary* d)
112 {
113 mIT3Dict = d;
114 }
115#endif
116
117 void clear()
118 {
119 for (int i = 0; i < mNThreads; i++) {
120 mDaughterTracks[i].clear();
121 mClusAttachments[i].clear();
122 mStrangeTrackVec[i].clear();
123 if (mMCTruthON) {
124 mStrangeTrackLabels[i].clear();
125 }
126 }
127 mTracksIdxTable.clear();
128 mSortedITStracks.clear();
129 mSortedITSindexes.clear();
130 mITSvtxBrackets.clear();
132 mInputClusterSizes.clear();
133 }
134
135 void setupThreads(int nThreads = 1)
136 {
137 mNThreads = nThreads;
138 mFitterV0.resize(nThreads);
139 mFitter3Body.resize(nThreads);
140 mFitter4Body.resize(nThreads);
141 mStrangeTrackVec.resize(nThreads);
142 mClusAttachments.resize(nThreads);
143 mStrangeTrackLabels.resize(nThreads);
144 mDaughterTracks.resize(nThreads);
145 }
146
148 {
149 for (auto& fitter : mFitterV0) {
150 fitter.setBz(mBz);
151 fitter.setUseAbsDCA(true);
152 }
153 for (auto& fitter : mFitter3Body) {
154 fitter.setBz(mBz);
155 fitter.setUseAbsDCA(true);
156 }
157 for (auto& fitter : mFitter4Body) {
158 fitter.setBz(mBz);
159 fitter.setUseAbsDCA(true);
160 }
161 }
162
163 double calcV0alpha(const V0& v0)
164 {
165 std::array<float, 3> momT, momP, momN;
166 v0.getProng(0).getPxPyPzGlo(momP);
167 v0.getProng(1).getPxPyPzGlo(momN);
168 v0.getPxPyPzGlo(momT);
169 float qNeg = momN[0] * momT[0] + momN[1] * momT[1] + momN[2] * momT[2];
170 float qPos = momP[0] * momT[0] + momP[1] * momT[1] + momP[2] * momT[2];
171 return (qPos - qNeg) / (qPos + qNeg);
172 };
173
174 double calcMotherMass(const std::array<float, 3>& pDauFirst, const std::array<float, 3>& pDauSecond, PID pidDauFirst, PID pidDauSecond)
175 {
176 double m2DauFirst = PID::getMass2(pidDauFirst);
177 double m2DauSecond = PID::getMass2(pidDauSecond);
178 double p2DauFirst = (pDauFirst[0] * pDauFirst[0]) + (pDauFirst[1] * pDauFirst[1]) + (pDauFirst[2] * pDauFirst[2]);
179 double p2DauSecond = (pDauSecond[0] * pDauSecond[0]) + (pDauSecond[1] * pDauSecond[1]) + (pDauSecond[2] * pDauSecond[2]);
180 float ePos = std::sqrt(p2DauFirst + m2DauFirst), eNeg = std::sqrt(p2DauSecond + m2DauSecond);
181
182 double e2Mother = (ePos + eNeg) * (ePos + eNeg);
183 double pxMother = (pDauFirst[0] + pDauSecond[0]);
184 double pyMother = (pDauFirst[1] + pDauSecond[1]);
185 double pzMother = (pDauFirst[2] + pDauSecond[2]);
186 double p2Mother = (pxMother * pxMother) + (pyMother * pyMother) + (pzMother * pzMother);
187 return std::sqrt(e2Mother - p2Mother);
188 }
189
190 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)
191 {
192 double m2DauFirst = PID::getMass2(pidDauFirst);
193 double m2DauSecond = PID::getMass2(pidDauSecond);
194 double m2DauThird = PID::getMass2(pidDauThird);
195 double p2DauFirst = (pDauFirst[0] * pDauFirst[0]) + (pDauFirst[1] * pDauFirst[1]) + (pDauFirst[2] * pDauFirst[2]);
196 double p2DauSecond = (pDauSecond[0] * pDauSecond[0]) + (pDauSecond[1] * pDauSecond[1]) + (pDauSecond[2] * pDauSecond[2]);
197 double p2DauThird = (pDauThird[0] * pDauThird[0]) + (pDauThird[1] * pDauThird[1]) + (pDauThird[2] * pDauThird[2]);
198 float eFirst = std::sqrt(p2DauFirst + m2DauFirst), eSecond = std::sqrt(p2DauSecond + m2DauSecond), eThird = std::sqrt(p2DauThird + m2DauThird);
199
200 double e2Mother = (eFirst + eSecond + eThird) * (eFirst + eSecond + eThird);
201 double pxMother = (pDauFirst[0] + pDauSecond[0] + pDauThird[0]);
202 double pyMother = (pDauFirst[1] + pDauSecond[1] + pDauThird[1]);
203 double pzMother = (pDauFirst[2] + pDauSecond[2] + pDauThird[2]);
204 double p2Mother = (pxMother * pxMother) + (pyMother * pyMother) + (pzMother * pzMother);
205 return std::sqrt(e2Mother - p2Mother);
206 }
207
208 bool recreateV0(const o2::track::TrackParCov& posTrack, const o2::track::TrackParCov& negTrack, V0& newV0, int iThread = 0)
209 {
210 int nCand;
211 try {
212 nCand = mFitterV0[iThread].process(posTrack, negTrack);
213 } catch (std::runtime_error& e) {
214 return false;
215 }
216 if (!nCand || !mFitterV0[iThread].propagateTracksToVertex()) {
217 return false;
218 }
219
220 const auto& v0XYZ = mFitterV0[iThread].getPCACandidatePos();
221
222 auto& propPos = mFitterV0[iThread].getTrack(0, 0);
223 auto& propNeg = mFitterV0[iThread].getTrack(1, 0);
224
225 std::array<float, 3> pP, pN;
226 propPos.getPxPyPzGlo(pP);
227 propNeg.getPxPyPzGlo(pN);
228 std::array<float, 3> pV0 = {pP[0] + pN[0], pP[1] + pN[1], pP[2] + pN[2]};
229 newV0 = V0(v0XYZ, pV0, mFitterV0[iThread].calcPCACovMatrixFlat(0), propPos, propNeg, PID::HyperTriton);
230 return true;
231 };
232
233 std::vector<ITSCluster> getTrackClusters(const TrackITS& itsTrack)
234 {
235 std::vector<ITSCluster> outVec;
236 outVec.reserve(7);
237 auto firstClus = itsTrack.getFirstClusterEntry();
238 auto ncl = itsTrack.getNumberOfClusters();
239 for (int icl = 0; icl < ncl; icl++) {
240 outVec.push_back(mInputITSclusters[mInputITSidxs[firstClus + icl]]);
241 }
242 return outVec;
243 };
244
245 std::vector<int> getTrackClusterSizes(const TrackITS& itsTrack)
246 {
247 std::vector<int> outVec;
248 outVec.reserve(7);
249 auto firstClus = itsTrack.getFirstClusterEntry();
250 auto ncl = itsTrack.getNumberOfClusters();
251 for (int icl = 0; icl < ncl; icl++) {
252 outVec.push_back(mInputClusterSizes[mInputITSclusters.flatIndex(mInputITSidxs[firstClus + icl])]);
253 }
254 return outVec;
255 };
256
257 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)
258 {
259 for (unsigned int iClus{0}; iClus < ITSclus.size(); ++iClus) {
260 auto& clus = ITSclus[iClus];
261 auto pattID = clus.getPatternID();
262 int npix;
264
265 if (pattID == o2::itsmft::CompCluster::InvalidPatternID || mdict->isGroup(pattID)) {
266 patt.acquirePattern(pattIt);
267 npix = patt.getNPixels();
268 } else {
269
270 npix = mdict->getNpixels(pattID);
271 patt = mdict->getPattern(pattID);
272 }
273 clusSizeVec[offs + iClus] = npix;
274 }
275 // LOG(info) << " Patt Npixel: " << pattVec[0].getNPixels();
276 }
277
278#ifdef ENABLE_UPGRADES
279 void getClusterSizesIT3(std::vector<int>& clusSizeVec, int offs, const gsl::span<const o2::itsmft::CompClusterExt> ITSclus, gsl::span<const unsigned char>::iterator& pattIt, const o2::its3::TopologyDictionary* mdict)
280 {
281 for (unsigned int iClus{0}; iClus < ITSclus.size(); ++iClus) {
282 auto& clus = ITSclus[iClus];
283 auto pattID = clus.getPatternID();
284 auto ib = o2::its3::constants::detID::isDetITS3(clus.getChipID());
285 int npix;
287
288 if (pattID == o2::itsmft::CompCluster::InvalidPatternID || mdict->isGroup(pattID, ib)) {
289 patt.acquirePattern(pattIt);
290 npix = patt.getNPixels();
291 } else {
292
293 npix = mdict->getNpixels(pattID, ib);
294 patt = mdict->getPattern(pattID, ib);
295 }
296 clusSizeVec[offs + iClus] = npix;
297 }
298 }
299#endif
300
302 {
303 if (v0.rotate(itsTrack.getParamOut().getAlpha()) && v0.propagateTo(itsTrack.getParamOut().getX(), mBz)) {
304 return v0.getPredictedChi2(itsTrack.getParamOut());
305 }
306 return -100;
307 };
308
309 o2::MCCompLabel getStrangeTrackLabel(const TrackITS& itsTrack, const StrangeTrack& strangeTrack, const ClusAttachments& structClus) // ITS label with fake flag recomputed
310 {
311 bool isFake = false;
312 auto itsTrkLab = mITSTrkLabels[strangeTrack.mITSRef];
313 for (unsigned int iLay = 0; iLay < 7; iLay++) {
314 if (itsTrack.hasHitOnLayer(iLay) && itsTrack.isFakeOnLayer(iLay) && structClus.arr[iLay] == 0) {
315 isFake = true;
316 break;
317 }
318 }
319 itsTrkLab.setFakeFlag(isFake);
320 return itsTrkLab;
321 }
322
323 protected:
324 bool mMCTruthON = false;
325 int mNThreads = 1;
326 float mGlobalChi2 = -1;
327 gsl::span<const TrackITS> mInputITStracks; // input ITS tracks
328 std::vector<VBracket> mITSvtxBrackets; // time brackets for ITS tracks
329 std::vector<int> mTracksIdxTable; // index table for ITS tracks
330 std::vector<int> mInputClusterSizes; // input cluster sizes
331 ITSClusters mInputITSclusters; // input ITS clusters, by composed (layer,index) ID
332 gsl::span<const int> mInputITSidxs; // input ITS track-cluster indexes
333 gsl::span<const V0> mInputV0tracks; // input V0 of decay daughters
334 gsl::span<const V0Index> mInputV0Indices; // input V0 indices of decay daughters
335 gsl::span<const Cascade> mInputCascadeTracks; // input cascade of decay daughters
336 gsl::span<const CascadeIndex> mInputCascadeIndices; // input cascade indices of decay daughters
337 gsl::span<const Decay3Body> mInput3BodyTracks; // input decay3body of decay daughters
338 gsl::span<const Decay3BodyIndex> mInput3BodyIndices; // input decay3body indices of decay daughters
339 const MCLabContCl* mITSClsLabels = nullptr;
341
342 std::vector<o2::its::TrackITS> mSortedITStracks; // sorted ITS tracks
343 std::vector<int> mSortedITSindexes; // indexes of sorted ITS tracks
344 IndexTableUtils mUtils; // structure for computing eta/phi matching selections
345
346 std::vector<std::vector<StrangeTrack>> mStrangeTrackVec; // structure containing updated mother and daughter tracks (per thread)
347 std::vector<std::vector<ClusAttachments>> mClusAttachments; // # of attached tracks, -1 not attached, 0 for the mother, > 0 for the daughters (per thread)
348 std::vector<std::vector<o2::MCCompLabel>> mStrangeTrackLabels; // vector of MC labels for mother track (per thread)
349
351 float mBz = -5; // Magnetic field
353#ifdef ENABLE_UPGRADES
354 const o2::its3::TopologyDictionary* mIT3Dict = nullptr;
355#endif
356
357 std::vector<DCAFitter2> mFitterV0; // optional DCA Fitter for recreating V0 with hypertriton mass hypothesis (per thread)
358 std::vector<DCAFitter3> mFitter3Body; // optional DCA Fitter for final 3 Body refit (per thread)
359 std::vector<DCAFitter4> mFitter4Body; // optional DCA Fitter for final 4 Body refit (per thread)
360
362 std::vector<std::vector<o2::track::TrackParCovF>> mDaughterTracks; // vector of daughter tracks (per thread)
364};
365
366} // namespace strangeness_tracking
367} // namespace o2
368
369#endif // _ALICEO2_STRANGENESS_TRACKER_
Container of the ITS/MFT clusters addressed by the composed (layer,index) ID.
Definition of the ITSMFT compact cluster.
Defintions for N-prongs secondary vertex fit.
Wrapper container for different reconstructed object types.
Definition of the ClusterTopology class.
particle ids, masses, names class definition
Base track model for the Barrel, params only, w/o covariance.
Definition of the BuildTopologyDictionary class for ITS3.
int32_t i
Definition of the GeometryTGeo class.
Definition of the ITS track.
Extention of GlobalTrackID by flags relevant for verter-track association.
Referenc on track indices contributing to the vertex, with possibility chose tracks from specific sou...
void setFakeFlag(bool v=true)
TO BE DONE: extend to generic N body vertex.
Definition Decay3Body.h:26
const itsmft::ClusterPattern & getPattern(int n, bool IB=true) const
Returns the pattern of the topology.
int getNpixels(int n, bool IB=true) const
Returns the number of fired pixels of the n_th element.
bool isGroup(int n, bool IB=true) const
Returns true if the element corresponds to a group of rare topologies.
bool hasHitOnLayer(uint32_t i) const
Definition TrackITS.h:112
bool isFakeOnLayer(uint32_t i) const
Definition TrackITS.h:113
int getFirstClusterEntry() const
Definition TrackITS.h:71
void acquirePattern(iterator &pattIt)
int getNPixels() const
Returns the number of fired pixels.
void clear()
the clusters of all layers, to be appended to by the caller between beginLayer and finalize
int flatIndex(int composedID) const
static constexpr unsigned short InvalidPatternID
Definition CompCluster.h:46
const ClusterPattern & getPattern(int n) const
Returns the pattern of the topology.
int getNpixels(int n) const
Returns the number of fired pixels of the n_th element.
bool isGroup(int n) const
Returns true if the element corresponds to a group of rare topologies.
void setConfigParams(const StrangenessTrackingParamConfig *params)
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
int mNThreads
flag availability of MC truth
std::vector< std::vector< StrangeTrack > > mStrangeTrackVec
void processV0(int iv0, const V0 &v0, const V0Index &v0Idx, int iThread=0)
std::vector< StrangeTrack > & getStrangeTrackVec(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)
void setCorrType(const o2::base::PropagatorImpl< float >::MatCorrType &type)
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
std::vector< ClusAttachments > & getClusAttachments(int iThread=0)
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
float getMatchingChi2(o2::track::TrackParCovF v0, const TrackITS &itsTrack)
void setClusterDictionaryITS(const o2::itsmft::TopologyDictionary *d)
const o2::itsmft::TopologyDictionary * mITSDict
gsl::span< const CascadeIndex > mInputCascadeIndices
bool loadData(const o2::globaltracking::RecoContainer &recoData)
std::vector< o2::MCCompLabel > & getStrangeTrackLabels(int iThread=0)
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
gsl::span< const o2::MCCompLabel > MCLabSpan
const GLdouble * v
Definition glcorearb.h:832
GLint GLint GLsizei GLint GLenum GLenum type
Definition glcorearb.h:275
GLenum const GLfloat * params
Definition glcorearb.h:272
GLfloat v0
Definition glcorearb.h:811
bool isDetITS3(T detID)
Definition SpecsV2.h:210
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 ...