Line data Source code
1 : #ifndef ALITRDSEEDV1_H
2 : #define ALITRDSEEDV1_H
3 : /* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 : * See cxx source for full Copyright notice */
5 :
6 : /* $Id: AliTRDseedV1.h 60233 2013-01-10 09:04:08Z abercuci $ */
7 :
8 : ////////////////////////////////////////////////////////////////////////////
9 : // //
10 : // \class AliTRDseedV1
11 : // \brief The TRD offline tracklet
12 : // \author Alexandru Bercuci
13 : // //
14 : ////////////////////////////////////////////////////////////////////////////
15 :
16 : #ifndef ALITRDTRACKLETBASE_H
17 : #include "AliTRDtrackletBase.h"
18 : #endif
19 :
20 : #ifndef ROOT_TMath
21 : #include "TMath.h"
22 : #endif
23 :
24 : #ifndef ALITRDGEOMETRY_H
25 : #include "AliTRDgeometry.h"
26 : #endif
27 :
28 : #ifndef ALIPID_H
29 : #include "AliPID.h"
30 : #endif
31 :
32 :
33 : #ifndef ALITRDCLUSTER_H
34 : #include "AliTRDcluster.h"
35 : #endif
36 :
37 :
38 : class TTreeSRedirector;
39 : class TLinearFitter;
40 : class TGeoHMatrix;
41 : class AliRieman;
42 :
43 : class AliTRDReconstructor;
44 : class AliTRDtrackingChamber;
45 : class AliTRDtrackV1;
46 : class AliTRDpadPlane;
47 : class AliTRDseedV1 : public AliTRDtrackletBase
48 : {
49 : friend class AliHLTTRDTracklet; // wrapper for HLT
50 :
51 : public:
52 : enum ETRDtrackletBuffers {
53 : kNbits = 6 // bits to store number of clusters
54 : ,kMask = 0x3f // bit mask
55 : ,kNtb = 31 // max clusters/pad row
56 : ,kNclusters = 2*kNtb // max number of clusters/tracklet
57 : ,kNdEdxSlices= 8 // dEdx slices allocated in reconstruction
58 : };
59 :
60 : // bits from 0-13 are reserved by ROOT (see TObject.h)
61 : enum ETRDtrackletStatus {
62 : kOwner = BIT(14) // owner of its clusters
63 : ,kRowCross = BIT(15) // pad row cross tracklet
64 : ,kChmbGood = BIT(16) // status of the detector from calibration view point
65 : ,kCalib = BIT(17) // calibrated tracklet
66 : ,kKink = BIT(18) // kink prolongation tracklet
67 : ,kStandAlone = BIT(19) // tracklet build during stand alone track finding
68 : ,kPrimary = BIT(20) // tracklet from a primary track candidate
69 : };
70 :
71 : enum ETRDtrackletError { // up to 8 bits
72 : kAttachClFound = 0 // not enough clusters found
73 : ,kAttachRowGap = 1 // found gap attached rows
74 : ,kAttachRow = 2 // found 3 rows
75 : ,kAttachMultipleCl= 3// multiple clusters attached to time bin
76 : ,kAttachClAttach= 4 // not enough clusters attached
77 : ,kFitCl = 5 // not enough clusters for fit
78 : ,kFitFailedY = 6 // fit failed in XY plane failed
79 : ,kFitFailedZ = 7 // fit in the QZ plane failed
80 : };
81 :
82 : AliTRDseedV1(Int_t det = -1);
83 : ~AliTRDseedV1();
84 : AliTRDseedV1(const AliTRDseedV1 &ref);
85 : AliTRDseedV1& operator=(const AliTRDseedV1 &ref);
86 :
87 : Bool_t AttachClusters(AliTRDtrackingChamber *const chamber, Bool_t tilt = kFALSE, Bool_t ChgPlus=kTRUE, Int_t ev=-1);
88 : void Bootstrap(const AliTRDReconstructor *rec);
89 : void Calibrate();
90 : void CookdEdx(Int_t nslices);
91 : void CookLabels();
92 : Bool_t CookPID();
93 : Bool_t Fit(UChar_t opt=0); // OBSOLETE
94 : Bool_t FitRobust(AliTRDpadPlane *pp, TGeoHMatrix *mdet, Float_t bz, Int_t chg, Int_t opt=0, Float_t tgl=0);
95 : Double_t EstimatedCrossPoint(AliTRDpadPlane *pp, Float_t bz);
96 : Bool_t Init(const AliTRDtrackV1 *track);
97 : void Init(const AliRieman *fit);
98 : Bool_t IsEqual(const TObject *inTracklet) const;
99 524 : Bool_t IsCalibrated() const { return TestBit(kCalib);}
100 868 : Bool_t IsChmbGood() const { return TestBit(kChmbGood);}
101 1562 : Bool_t IsOwner() const { return TestBit(kOwner);}
102 8960 : Bool_t IsKink() const { return TestBit(kKink);}
103 0 : Bool_t IsPrimary() const { return TestBit(kPrimary);}
104 : Bool_t HasError(ETRDtrackletError err) const
105 0 : { return TESTBIT(fErrorMsg, err);}
106 1648 : Bool_t IsOK() const { return GetN() > 4 && GetNUsed() < 4;}
107 16606 : Bool_t IsRowCross() const { return TestBit(kRowCross);}
108 0 : Bool_t IsUsable(Int_t i) const { return fClusters[i] && !fClusters[i]->IsUsed();}
109 9784 : Bool_t IsStandAlone() const { return TestBit(kStandAlone);}
110 :
111 : Float_t GetAnodeWireOffset(Float_t zt);
112 0 : Float_t GetC(Int_t typ=0) const { return fC[typ]; }
113 : Float_t GetCharge(Bool_t useOutliers=kFALSE) const;
114 0 : Float_t GetChi2() const { return fChi2; }
115 : inline Float_t GetChi2Z() const;
116 : inline Float_t GetChi2Y() const;
117 : inline Float_t GetChi2Phi() const;
118 : void GetCovAt(Double_t x, Double_t *cov) const;
119 0 : void GetCovXY(Double_t *cov) const { memcpy(cov, &fCov[0], 3*sizeof(Double_t));}
120 0 : void GetCovRef(Double_t *cov) const { memcpy(cov, &fRefCov, 7*sizeof(Double_t));}
121 : static Int_t GetCovSqrt(const Double_t * const c, Double_t *d);
122 : static Double_t GetCovInv(const Double_t * const c, Double_t *d);
123 0 : UChar_t GetErrorMsg() const { return fErrorMsg;}
124 0 : Float_t GetdX() const { return fdX;}
125 412 : const Float_t* GetdEdx() const { return &fdEdx[0];}
126 : Float_t GetQperTB(Int_t tb) const;
127 : Float_t GetdQdl() const;
128 : Float_t GetdQdl(Int_t ic, Float_t *dx=NULL) const;
129 0 : Float_t GetdYdX() const { return fYfit[1];}
130 0 : Float_t GetdZdX() const { return fZfit[1];}
131 0 : Int_t GetdY() const { return Int_t(GetY()/0.014);}
132 642 : Int_t GetDetector() const { return fDet;}
133 : Int_t GetChargeGaps(Float_t sz[kNtb], Float_t pos[kNtb], Int_t ntb[kNtb]) const;
134 : void GetCalibParam(Float_t &exb, Float_t &vd, Float_t &t0, Float_t &s2, Float_t &dl, Float_t &dt) const {
135 0 : exb = fExB; vd = fVD; t0 = fT0; s2 = fS2PRF; dl = fDiffL; dt = fDiffT;}
136 102176 : AliTRDcluster* GetClusters(Int_t i) const { return i<0 || i>=kNclusters ? NULL: fClusters[i];}
137 0 : Int_t GetIndexes(Int_t i) const{ return i<0 || i>=kNclusters ? -1 : fIndexes[i];}
138 0 : Int_t GetLabels(Int_t i) const { return fLabels[i];}
139 0 : Float_t GetLocalZ() const { return fZfit[0] - fZfit[1] * fX;}
140 456 : Float_t GetLocalY() const { return fYfit[0] - fYfit[1] * fX;}
141 : Float_t GetMomentum(Float_t *err = NULL) const;
142 6792 : Int_t GetN() const { return (Int_t)fN&kMask;}
143 0 : Int_t GetN2() const { return GetN();}
144 824 : Int_t GetNUsed() const { return Int_t((fN>>kNbits)&kMask);}
145 0 : Int_t GetNShared() const { return Int_t(((fN>>kNbits)>>kNbits)&kMask);}
146 : Int_t GetTBoccupancy() const;
147 : Int_t GetTBcross() const;
148 : Float_t GetQuality(Bool_t kZcorr) const;
149 12546 : Float_t GetPadLength() const { return fPad[0];}
150 0 : Float_t GetPadWidth() const { return fPad[1];}
151 824 : Int_t GetPlane() const { return AliTRDgeometry::GetLayer(fDet); }
152 :
153 : Float_t* GetProbability(Bool_t force=kFALSE);
154 0 : Float_t GetPt() const { return fPt; }
155 : inline Double_t GetPID(Int_t is=-1) const;
156 0 : Float_t GetS2Y() const { return fCov[0];}
157 0 : Float_t GetS2Z() const { return fS2Z;}
158 0 : Double_t GetS2DYDX(Float_t) const { return fCov[2];}
159 : inline Double_t GetS2DZDX(Float_t) const;
160 : inline Double_t GetS2XcrossDZDX(Double_t absdzdx) const;
161 0 : Float_t GetSigmaY() const { return fS2Y > 0. ? TMath::Sqrt(fS2Y) : 0.2;}
162 0 : Float_t GetSnp() const { return fYref[1]/TMath::Sqrt(1+fYref[1]*fYref[1]);}
163 0 : Float_t GetTgl() const { return fZref[1]/TMath::Sqrt(1+fYref[1]*fYref[1]);}
164 16858 : Float_t GetTilt() const { return fPad[2];}
165 0 : UInt_t GetTrackletWord() const { return 0;}
166 : UShort_t GetVolumeId() const;
167 0 : Float_t GetX0() const { return fX0;}
168 1098 : Float_t GetX() const { return fX0 - fX;}
169 0 : Float_t GetXcross() const { return fS2Y;}
170 2196 : Float_t GetY() const { return TMath::Abs(fY)<1.e-15?GetLocalY():fY;/*fYfit[0] - fYfit[1] * fX;*/}
171 0 : Double_t GetYat(Double_t x) const { return fY/*fit[0]*/ - fYfit[1] * (fX0-x);}
172 0 : Float_t GetYfit(Int_t id) const { return fYfit[id];}
173 25544 : Float_t GetYref(Int_t id) const { return fYref[id];}
174 0 : Float_t GetYref() const { return fYref[0] - fYref[1] *fX;}
175 2196 : Float_t GetZ() const { return TMath::Abs(fZ)<1.e-15?GetLocalZ():fZ;/*fZfit[0] - fZfit[1] * fX;*/}
176 0 : Double_t GetZat(Double_t x) const { return fZ/*fit[0]*/ - fZfit[1] * (fX0-x);}
177 0 : Float_t GetZfit(Int_t id) const { return fZfit[id];}
178 25544 : Float_t GetZref(Int_t id) const { return fZref[id];}
179 0 : Float_t GetZref() const { return fZref[0] - fZref[1] *fX;}
180 0 : Int_t GetYbin() const { return Int_t(GetY()/0.016);}
181 0 : Int_t GetZbin() const { return Int_t(GetZ()/fPad[0]);}
182 :
183 : inline AliTRDcluster* NextCluster();
184 : inline AliTRDcluster* PrevCluster();
185 : void Print(Option_t *o = "") const;
186 : inline void ResetClusterIter(Bool_t forward = kTRUE);
187 : void Reset(Option_t *opt="");
188 :
189 0 : void SetC(Float_t c, Int_t typ=0) { fC[typ] = c;}
190 228 : void SetChmbGood(Bool_t k = kTRUE){ SetBit(kChmbGood, k);}
191 0 : void SetChi2(Float_t chi2) { fChi2 = chi2;}
192 : inline void SetCovRef(const Double_t *cov);
193 68 : void SetErrorMsg(ETRDtrackletError err) { SETBIT(fErrorMsg, err);}
194 0 : void SetIndexes(Int_t i, Int_t idx) { fIndexes[i] = idx; }
195 0 : void SetLabels(Int_t *lbls) { memcpy(fLabels, lbls, 3*sizeof(Int_t)); }
196 262 : void SetKink(Bool_t k = kTRUE){ SetBit(kKink, k);}
197 262 : void SetPrimary(Bool_t k = kTRUE){ SetBit(kPrimary, k);}
198 781 : void SetStandAlone(Bool_t st) { SetBit(kStandAlone, st); }
199 0 : void SetPt(Double_t pt) { fPt = pt;}
200 : void SetOwner();
201 : void SetPadPlane(AliTRDpadPlane * const p);
202 0 : void SetPadLength(Float_t l) { fPad[0] = l;}
203 0 : void SetPadWidth(Float_t w) { fPad[1] = w;}
204 0 : void SetTilt(Float_t tilt) { fPad[2] = tilt; }
205 0 : void SetDetector(Int_t d) { fDet = d; }
206 0 : void SetDX(Float_t inDX) { fdX = inDX;}
207 524 : void SetReconstructor(const AliTRDReconstructor *rec) {fkReconstructor = rec;}
208 524 : void SetX0(Float_t x0) { fX0 = x0; }
209 : void SetXYZ(TGeoHMatrix *mDet);
210 0 : void SetYref(Int_t i, Float_t y) { if(i==0||i==1) fYref[i] = y;}
211 0 : void SetZref(Int_t i, Float_t z) { if(i==0||i==1) fZref[i] = z;}
212 : // void SetUsabilityMap(Long_t um) { fUsable = um; }
213 : void Update(const AliTRDtrackV1* trk);
214 : void UpdateUsed();
215 : void UseClusters();
216 :
217 : protected:
218 : void Copy(TObject &ref) const;
219 : void UnbiasDZDX(Bool_t rc, Float_t bz);
220 : Double_t UnbiasY(Bool_t rc, Float_t bz);
221 :
222 : private:
223 : inline void SetN(Int_t n);
224 : inline void SetNUsed(Int_t n);
225 : inline void SetNShared(Int_t n);
226 : inline void Swap(Int_t &n1, Int_t &n2) const;
227 : inline void Swap(Double_t &d1, Double_t &d2) const;
228 :
229 : const AliTRDReconstructor *fkReconstructor;//! local reconstructor
230 : AliTRDcluster **fClusterIter; //! clusters iterator
231 : Int_t fIndexes[kNclusters]; //! Indexes
232 : Float_t fExB; // tg(a_L) @ tracklet location
233 : Float_t fVD; // drift velocity @ tracklet location
234 : Float_t fT0; // time 0 @ tracklet location
235 : Float_t fS2PRF; // sigma^2 PRF for xd->0 and phi=a_L
236 : Float_t fDiffL; // longitudinal diffusion coefficient
237 : Float_t fDiffT; // transversal diffusion coefficient
238 : Char_t fClusterIdx; //! clusters iterator
239 : UChar_t fErrorMsg; // processing error
240 : UInt_t fN; // number of clusters attached/used/shared
241 : Short_t fDet; // TRD detector
242 : AliTRDcluster *fClusters[kNclusters]; // Clusters
243 : Float_t fPad[4]; // local pad definition : length/width/tilt/anode wire offset
244 : Float_t fYref[2]; // Reference y, dydx
245 : Float_t fZref[2]; // Reference z, dz/dx
246 : Float_t fYfit[2]; // Fit :: chamber local y, dy/dx
247 : Float_t fZfit[2]; // Fit :: chamber local z, dz/dx
248 : Float_t fPt; // Pt estimate @ tracklet [GeV/c]
249 : Float_t fdX; // length of time bin
250 : Float_t fX0; // anode wire position in TrackingCoordinates (alignment included)
251 : Float_t fX; // local radial offset from anode wire where tracklet position is estimated
252 : Float_t fY; // r-phi position of the tracklet in TrackingCoordinates (alignment included)
253 : Float_t fZ; // z position of the tracklet in TrackingCoordinates (alignment included)
254 : Float_t fS2Y; // estimated radial cross point (chmb. coord.) in case of RC tracklets
255 : Float_t fS2Z; // estimated resolution in the z direction
256 : Float_t fC[2]; // Curvature for standalone [0] rieman [1] vertex constrained
257 : Float_t fChi2; // Global chi2
258 : Float_t fdEdx[kNdEdxSlices]; // dE/dx measurements for tracklet
259 : Float_t fProb[AliPID::kSPECIES]; // PID probabilities
260 : Int_t fLabels[3]; // most frequent MC labels and total number of different labels
261 : Double_t fRefCov[7]; // covariance matrix of the track in the yz plane + the rest of the diagonal elements
262 : Double_t fCov[3]; // covariance matrix of the tracklet in the xy plane
263 :
264 28632 : ClassDef(AliTRDseedV1, 13) // The offline TRD tracklet
265 : };
266 :
267 : //____________________________________________________________
268 : inline Float_t AliTRDseedV1::GetChi2Z() const
269 : {
270 0 : Double_t dz = fZref[0]-fZfit[0]; dz*=dz;
271 0 : Double_t cov[3]; GetCovAt(fX, cov);
272 0 : Double_t s2 = fRefCov[2]+cov[2];
273 0 : return s2 > 0. ? dz/s2 : 0.;
274 0 : }
275 :
276 : //____________________________________________________________
277 : inline Float_t AliTRDseedV1::GetChi2Y() const
278 : {
279 0 : Double_t dy = fYref[0]-fYfit[0]; dy*=dy;
280 0 : Double_t cov[3]; GetCovAt(fX, cov);
281 0 : Double_t s2 = fRefCov[0]+cov[0];
282 0 : return s2 > 0. ? dy/s2 : 0.;
283 0 : }
284 :
285 : //____________________________________________________________
286 : inline Float_t AliTRDseedV1::GetChi2Phi() const
287 : {
288 0 : Double_t dphi = fYref[1]-fYfit[1]; dphi*=dphi;
289 0 : Double_t cov[3]; GetCovAt(fX, cov);
290 0 : Double_t s2 = fRefCov[2]+cov[2];
291 0 : return s2 > 0. ? dphi/s2 : 0.;
292 0 : }
293 :
294 :
295 :
296 : //____________________________________________________________
297 : inline Double_t AliTRDseedV1::GetPID(Int_t is) const
298 : {
299 0 : if(is<0) return fProb[AliPID::kElectron];
300 0 : if(is<AliPID::kSPECIES) return fProb[is];
301 0 : return 0.;
302 0 : }
303 :
304 : //____________________________________________________________
305 : Double_t AliTRDseedV1::GetS2XcrossDZDX(Double_t absdzdx) const
306 : {
307 : // correct sigma(x_cross) for the width of the crossing area
308 42 : if(absdzdx>0.05) return TMath::Exp(-1.58839-absdzdx*3.24116);
309 0 : else return 0.957043-absdzdx*12.4597;
310 14 : }
311 :
312 : //____________________________________________________________
313 : Double_t AliTRDseedV1::GetS2DZDX(Float_t dzdx) const
314 : {
315 : // Error parametrization for dzdx.
316 : // TODO Should be layer dependent
317 :
318 84 : Double_t p0[] = {0.02835, 0.03925},
319 42 : p1[] = {0.04746, 0.06316};
320 :
321 42 : Double_t s2(p0[IsRowCross()]+p1[IsRowCross()]*dzdx*dzdx);
322 42 : s2*=s2;
323 42 : return s2;
324 42 : }
325 :
326 : //____________________________________________________________
327 : inline AliTRDcluster* AliTRDseedV1::NextCluster()
328 : {
329 : // Mimic the usage of STL iterators.
330 : // Forward iterator
331 :
332 0 : fClusterIdx++; fClusterIter++;
333 0 : while(fClusterIdx < kNclusters){
334 0 : if(!(*fClusterIter)){
335 0 : fClusterIdx++;
336 0 : fClusterIter++;
337 0 : continue;
338 : }
339 0 : return *fClusterIter;
340 : }
341 0 : return NULL;
342 0 : }
343 :
344 : //____________________________________________________________
345 : inline AliTRDcluster* AliTRDseedV1::PrevCluster()
346 : {
347 : // Mimic the usage of STL iterators.
348 : // Backward iterator
349 :
350 0 : fClusterIdx--; fClusterIter--;
351 0 : while(fClusterIdx >= 0){
352 0 : if(!(*fClusterIter)){
353 0 : fClusterIdx--;
354 0 : fClusterIter--;
355 0 : continue;
356 : }
357 0 : return *fClusterIter;
358 : }
359 0 : return NULL;
360 0 : }
361 :
362 : //____________________________________________________________
363 : inline void AliTRDseedV1::ResetClusterIter(Bool_t forward)
364 : {
365 : // Mimic the usage of STL iterators.
366 : // Facilitate the usage of NextCluster for forward like
367 : // iterator (kTRUE) and PrevCluster for backward like iterator (kFALSE)
368 :
369 0 : if(forward){
370 0 : fClusterIter = &fClusters[0]; fClusterIter--;
371 0 : fClusterIdx=-1;
372 0 : } else {
373 0 : fClusterIter = &fClusters[kNclusters-1]; fClusterIter++;
374 0 : fClusterIdx=kNclusters;
375 : }
376 0 : }
377 :
378 : //____________________________________________________________
379 : inline void AliTRDseedV1::SetCovRef(const Double_t *cov)
380 : {
381 : // Copy some "important" covariance matrix elements
382 : // var(y)
383 : // cov(y,z) var(z)
384 : // var(snp)
385 : // var(tgl)
386 : // cov(tgl, 1/pt) var(1/pt)
387 :
388 524 : memcpy(&fRefCov[0], cov, 3*sizeof(Double_t)); // yz full covariance
389 262 : fRefCov[3] = cov[ 5]; // snp variance
390 262 : fRefCov[4] = cov[ 9]; // tgl variance
391 262 : fRefCov[5] = cov[13]; // cov(tgl, 1/pt)
392 262 : fRefCov[6] = cov[14]; // 1/pt variance
393 262 : }
394 :
395 :
396 : //____________________________________________________________
397 : inline void AliTRDseedV1::SetN(Int_t n)
398 : {
399 456 : if(n<0 || n>kNclusters) return;
400 228 : fN &= ~kMask;
401 228 : fN |= (n&kMask);
402 456 : }
403 :
404 : //____________________________________________________________
405 : inline void AliTRDseedV1::SetNUsed(Int_t n)
406 : {
407 456 : if(n<0 || n>kNclusters) return;
408 : UInt_t mask(kMask<<kNbits);
409 228 : fN &= ~mask;
410 228 : n=n<<kNbits; fN |= (n&mask);
411 456 : }
412 :
413 : //____________________________________________________________
414 : inline void AliTRDseedV1::SetNShared(Int_t n)
415 : {
416 456 : if(n<0 || n>kNclusters) return;
417 : UInt_t mask((kMask<<kNbits)<<kNbits);
418 228 : fN &= ~mask;
419 228 : n = (n<<kNbits)<<kNbits; fN|=(n&mask);
420 456 : }
421 :
422 : //____________________________________________________________
423 : inline void AliTRDseedV1::Swap(Int_t &n1, Int_t &n2) const
424 : {
425 : // swap values of n1 with n2
426 : Int_t tmp(n1);
427 : n1=n2; n2=tmp;
428 : }
429 :
430 : //____________________________________________________________
431 : inline void AliTRDseedV1::Swap(Double_t &d1, Double_t &d2) const
432 : {
433 : // swap values of d1 with d2
434 : Double_t tmp(d1);
435 : d1=d2; d2=tmp;
436 : }
437 :
438 :
439 : #endif
440 :
441 :
442 :
|