]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TRD/AliTRDseedV1.cxx
AliTPCcalibDB::GetGoofieSensors
[u/mrichter/AliRoot.git] / TRD / AliTRDseedV1.cxx
CommitLineData
e4f2f73d 1/**************************************************************************
29b87567 2* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3* *
4* Author: The ALICE Off-line Project. *
5* Contributors are mentioned in the code where appropriate. *
6* *
7* Permission to use, copy, modify and distribute this software and its *
8* documentation strictly for non-commercial purposes is hereby granted *
9* without fee, provided that the above copyright notice appears in all *
10* copies and that both the copyright notice and this permission notice *
11* appear in the supporting documentation. The authors make no claims *
12* about the suitability of this software for any purpose. It is *
13* provided "as is" without express or implied warranty. *
14**************************************************************************/
e4f2f73d 15
16/* $Id$ */
17
18////////////////////////////////////////////////////////////////////////////
dd8059a8 19////
20// The TRD offline tracklet
21//
22// The running horse of the TRD reconstruction. The following tasks are preformed:
23// 1. Clusters attachment to tracks based on prior information stored at tracklet level (see AttachClusters)
24// 2. Clusters position recalculation based on track information (see GetClusterXY and Fit)
25// 3. Cluster error parametrization recalculation (see Fit)
26// 4. Linear track approximation (Fit)
27// 5. Optimal position (including z estimate for pad row cross tracklets) and covariance matrix of the track fit inside one TRD chamber (Fit)
28// 6. Tilt pad correction and systematic effects (GetCovAt)
29// 7. dEdx calculation (CookdEdx)
30// 8. PID probabilities estimation (CookPID)
31//
e4f2f73d 32// Authors: //
33// Alex Bercuci <A.Bercuci@gsi.de> //
34// Markus Fasel <M.Fasel@gsi.de> //
35// //
36////////////////////////////////////////////////////////////////////////////
37
38#include "TMath.h"
39#include "TLinearFitter.h"
eb38ed55 40#include "TClonesArray.h" // tmp
41#include <TTreeStream.h>
e4f2f73d 42
43#include "AliLog.h"
44#include "AliMathBase.h"
d937ad7a 45#include "AliCDBManager.h"
46#include "AliTracker.h"
e4f2f73d 47
03cef9b2 48#include "AliTRDpadPlane.h"
e4f2f73d 49#include "AliTRDcluster.h"
f3d3af1b 50#include "AliTRDseedV1.h"
51#include "AliTRDtrackV1.h"
e4f2f73d 52#include "AliTRDcalibDB.h"
eb38ed55 53#include "AliTRDchamberTimeBin.h"
54#include "AliTRDtrackingChamber.h"
55#include "AliTRDtrackerV1.h"
56#include "AliTRDReconstructor.h"
e4f2f73d 57#include "AliTRDrecoParam.h"
a076fc2f 58#include "AliTRDCommonParam.h"
d937ad7a 59
0906e73e 60#include "Cal/AliTRDCalPID.h"
d937ad7a 61#include "Cal/AliTRDCalROC.h"
62#include "Cal/AliTRDCalDet.h"
e4f2f73d 63
e4f2f73d 64ClassImp(AliTRDseedV1)
65
66//____________________________________________________________________
ae4e8b84 67AliTRDseedV1::AliTRDseedV1(Int_t det)
3e778975 68 :AliTRDtrackletBase()
3a039a31 69 ,fReconstructor(0x0)
ae4e8b84 70 ,fClusterIter(0x0)
e3cf3d02 71 ,fExB(0.)
72 ,fVD(0.)
73 ,fT0(0.)
74 ,fS2PRF(0.)
75 ,fDiffL(0.)
76 ,fDiffT(0.)
ae4e8b84 77 ,fClusterIdx(0)
3e778975 78 ,fN(0)
ae4e8b84 79 ,fDet(det)
b25a5e9e 80 ,fPt(0.)
bcb6fb78 81 ,fdX(0.)
e3cf3d02 82 ,fX0(0.)
83 ,fX(0.)
84 ,fY(0.)
85 ,fZ(0.)
86 ,fS2Y(0.)
87 ,fS2Z(0.)
88 ,fC(0.)
89 ,fChi2(0.)
e4f2f73d 90{
91 //
92 // Constructor
93 //
8d2bec9e 94 for(Int_t ic=kNclusters; ic--;) fIndexes[ic] = -1;
95 memset(fClusters, 0, kNclusters*sizeof(AliTRDcluster*));
dd8059a8 96 memset(fPad, 0, 3*sizeof(Float_t));
e3cf3d02 97 fYref[0] = 0.; fYref[1] = 0.;
98 fZref[0] = 0.; fZref[1] = 0.;
99 fYfit[0] = 0.; fYfit[1] = 0.;
100 fZfit[0] = 0.; fZfit[1] = 0.;
8d2bec9e 101 memset(fdEdx, 0, kNslices*sizeof(Float_t));
29b87567 102 for(int ispec=0; ispec<AliPID::kSPECIES; ispec++) fProb[ispec] = -1.;
e3cf3d02 103 fLabels[0]=-1; fLabels[1]=-1; // most freq MC labels
104 fLabels[2]=0; // number of different labels for tracklet
16cca13f 105 memset(fRefCov, 0, 7*sizeof(Double_t));
d937ad7a 106 // covariance matrix [diagonal]
107 // default sy = 200um and sz = 2.3 cm
108 fCov[0] = 4.e-4; fCov[1] = 0.; fCov[2] = 5.3;
f29f13a6 109 SetStandAlone(kFALSE);
e4f2f73d 110}
111
112//____________________________________________________________________
0906e73e 113AliTRDseedV1::AliTRDseedV1(const AliTRDseedV1 &ref)
3e778975 114 :AliTRDtrackletBase((AliTRDtrackletBase&)ref)
e3cf3d02 115 ,fReconstructor(0x0)
ae4e8b84 116 ,fClusterIter(0x0)
e3cf3d02 117 ,fExB(0.)
118 ,fVD(0.)
119 ,fT0(0.)
120 ,fS2PRF(0.)
121 ,fDiffL(0.)
122 ,fDiffT(0.)
ae4e8b84 123 ,fClusterIdx(0)
3e778975 124 ,fN(0)
e3cf3d02 125 ,fDet(-1)
b25a5e9e 126 ,fPt(0.)
e3cf3d02 127 ,fdX(0.)
128 ,fX0(0.)
129 ,fX(0.)
130 ,fY(0.)
131 ,fZ(0.)
132 ,fS2Y(0.)
133 ,fS2Z(0.)
134 ,fC(0.)
135 ,fChi2(0.)
e4f2f73d 136{
137 //
138 // Copy Constructor performing a deep copy
139 //
e3cf3d02 140 if(this != &ref){
141 ref.Copy(*this);
142 }
29b87567 143 SetBit(kOwner, kFALSE);
f29f13a6 144 SetStandAlone(ref.IsStandAlone());
fbb2ea06 145}
d9950a5a 146
0906e73e 147
e4f2f73d 148//____________________________________________________________________
149AliTRDseedV1& AliTRDseedV1::operator=(const AliTRDseedV1 &ref)
150{
151 //
152 // Assignment Operator using the copy function
153 //
154
29b87567 155 if(this != &ref){
156 ref.Copy(*this);
157 }
221ab7e0 158 SetBit(kOwner, kFALSE);
159
29b87567 160 return *this;
e4f2f73d 161}
162
163//____________________________________________________________________
164AliTRDseedV1::~AliTRDseedV1()
165{
166 //
167 // Destructor. The RecoParam object belongs to the underlying tracker.
168 //
169
29b87567 170 //printf("I-AliTRDseedV1::~AliTRDseedV1() : Owner[%s]\n", IsOwner()?"YES":"NO");
e4f2f73d 171
e3cf3d02 172 if(IsOwner()) {
8d2bec9e 173 for(int itb=0; itb<kNclusters; itb++){
29b87567 174 if(!fClusters[itb]) continue;
175 //AliInfo(Form("deleting c %p @ %d", fClusters[itb], itb));
176 delete fClusters[itb];
177 fClusters[itb] = 0x0;
178 }
e3cf3d02 179 }
e4f2f73d 180}
181
182//____________________________________________________________________
183void AliTRDseedV1::Copy(TObject &ref) const
184{
185 //
186 // Copy function
187 //
188
29b87567 189 //AliInfo("");
190 AliTRDseedV1 &target = (AliTRDseedV1 &)ref;
191
e3cf3d02 192 target.fReconstructor = fReconstructor;
ae4e8b84 193 target.fClusterIter = 0x0;
e3cf3d02 194 target.fExB = fExB;
195 target.fVD = fVD;
196 target.fT0 = fT0;
197 target.fS2PRF = fS2PRF;
198 target.fDiffL = fDiffL;
199 target.fDiffT = fDiffT;
ae4e8b84 200 target.fClusterIdx = 0;
3e778975 201 target.fN = fN;
ae4e8b84 202 target.fDet = fDet;
b25a5e9e 203 target.fPt = fPt;
29b87567 204 target.fdX = fdX;
e3cf3d02 205 target.fX0 = fX0;
206 target.fX = fX;
207 target.fY = fY;
208 target.fZ = fZ;
209 target.fS2Y = fS2Y;
210 target.fS2Z = fS2Z;
211 target.fC = fC;
212 target.fChi2 = fChi2;
29b87567 213
8d2bec9e 214 memcpy(target.fIndexes, fIndexes, kNclusters*sizeof(Int_t));
215 memcpy(target.fClusters, fClusters, kNclusters*sizeof(AliTRDcluster*));
dd8059a8 216 memcpy(target.fPad, fPad, 3*sizeof(Float_t));
e3cf3d02 217 target.fYref[0] = fYref[0]; target.fYref[1] = fYref[1];
218 target.fZref[0] = fZref[0]; target.fZref[1] = fZref[1];
219 target.fYfit[0] = fYfit[0]; target.fYfit[1] = fYfit[1];
220 target.fZfit[0] = fZfit[0]; target.fZfit[1] = fZfit[1];
8d2bec9e 221 memcpy(target.fdEdx, fdEdx, kNslices*sizeof(Float_t));
e3cf3d02 222 memcpy(target.fProb, fProb, AliPID::kSPECIES*sizeof(Float_t));
223 memcpy(target.fLabels, fLabels, 3*sizeof(Int_t));
16cca13f 224 memcpy(target.fRefCov, fRefCov, 7*sizeof(Double_t));
e3cf3d02 225 memcpy(target.fCov, fCov, 3*sizeof(Double_t));
29b87567 226
e3cf3d02 227 TObject::Copy(ref);
e4f2f73d 228}
229
0906e73e 230
231//____________________________________________________________
f3d3af1b 232Bool_t AliTRDseedV1::Init(AliTRDtrackV1 *track)
0906e73e 233{
234// Initialize this tracklet using the track information
235//
236// Parameters:
237// track - the TRD track used to initialize the tracklet
238//
239// Detailed description
240// The function sets the starting point and direction of the
241// tracklet according to the information from the TRD track.
242//
243// Caution
244// The TRD track has to be propagated to the beginning of the
245// chamber where the tracklet will be constructed
246//
247
29b87567 248 Double_t y, z;
249 if(!track->GetProlongation(fX0, y, z)) return kFALSE;
16cca13f 250 Update(track);
29b87567 251 return kTRUE;
0906e73e 252}
253
bcb6fb78 254
e3cf3d02 255//_____________________________________________________________________________
256void AliTRDseedV1::Reset()
257{
258 //
259 // Reset seed
260 //
261 fExB=0.;fVD=0.;fT0=0.;fS2PRF=0.;
262 fDiffL=0.;fDiffT=0.;
3e778975 263 fClusterIdx=0;
264 fN=0;
dd8059a8 265 fDet=-1;
b25a5e9e 266 fPt=0.;
e3cf3d02 267 fdX=0.;fX0=0.; fX=0.; fY=0.; fZ=0.;
268 fS2Y=0.; fS2Z=0.;
269 fC=0.; fChi2 = 0.;
270
8d2bec9e 271 for(Int_t ic=kNclusters; ic--;) fIndexes[ic] = -1;
272 memset(fClusters, 0, kNclusters*sizeof(AliTRDcluster*));
dd8059a8 273 memset(fPad, 0, 3*sizeof(Float_t));
e3cf3d02 274 fYref[0] = 0.; fYref[1] = 0.;
275 fZref[0] = 0.; fZref[1] = 0.;
276 fYfit[0] = 0.; fYfit[1] = 0.;
277 fZfit[0] = 0.; fZfit[1] = 0.;
8d2bec9e 278 memset(fdEdx, 0, kNslices*sizeof(Float_t));
e3cf3d02 279 for(int ispec=0; ispec<AliPID::kSPECIES; ispec++) fProb[ispec] = -1.;
280 fLabels[0]=-1; fLabels[1]=-1; // most freq MC labels
281 fLabels[2]=0; // number of different labels for tracklet
16cca13f 282 memset(fRefCov, 0, 7*sizeof(Double_t));
e3cf3d02 283 // covariance matrix [diagonal]
284 // default sy = 200um and sz = 2.3 cm
285 fCov[0] = 4.e-4; fCov[1] = 0.; fCov[2] = 5.3;
286}
287
b1957d3c 288//____________________________________________________________________
16cca13f 289void AliTRDseedV1::Update(const AliTRDtrackV1 *trk)
b1957d3c 290{
291 // update tracklet reference position from the TRD track
b1957d3c 292
e3cf3d02 293 Double_t fSnp = trk->GetSnp();
294 Double_t fTgl = trk->GetTgl();
b25a5e9e 295 fPt = trk->Pt();
e96c1c72 296 fYref[1] = fSnp/TMath::Sqrt(1. - fSnp*fSnp);
b1957d3c 297 fZref[1] = fTgl;
298 SetCovRef(trk->GetCovariance());
299
300 Double_t dx = trk->GetX() - fX0;
301 fYref[0] = trk->GetY() - dx*fYref[1];
302 fZref[0] = trk->GetZ() - dx*fZref[1];
303}
304
e3cf3d02 305//_____________________________________________________________________________
306void AliTRDseedV1::UpdateUsed()
307{
308 //
f29f13a6 309 // Calculate number of used clusers in the tracklet
e3cf3d02 310 //
311
3e778975 312 Int_t nused = 0, nshared = 0;
8d2bec9e 313 for (Int_t i = kNclusters; i--; ) {
e3cf3d02 314 if (!fClusters[i]) continue;
3e778975 315 if(fClusters[i]->IsUsed()){
316 nused++;
317 } else if(fClusters[i]->IsShared()){
318 if(IsStandAlone()) nused++;
319 else nshared++;
320 }
e3cf3d02 321 }
3e778975 322 SetNUsed(nused);
323 SetNShared(nshared);
e3cf3d02 324}
325
326//_____________________________________________________________________________
327void AliTRDseedV1::UseClusters()
328{
329 //
330 // Use clusters
331 //
f29f13a6 332 // In stand alone mode:
333 // Clusters which are marked as used or shared from another track are
334 // removed from the tracklet
335 //
336 // In barrel mode:
337 // - Clusters which are used by another track become shared
338 // - Clusters which are attached to a kink track become shared
339 //
e3cf3d02 340 AliTRDcluster **c = &fClusters[0];
8d2bec9e 341 for (Int_t ic=kNclusters; ic--; c++) {
e3cf3d02 342 if(!(*c)) continue;
f29f13a6 343 if(IsStandAlone()){
344 if((*c)->IsShared() || (*c)->IsUsed()){
b82b4de1 345 if((*c)->IsShared()) SetNShared(GetNShared()-1);
346 else SetNUsed(GetNUsed()-1);
3e778975 347 (*c) = 0x0;
f29f13a6 348 fIndexes[ic] = -1;
3e778975 349 SetN(GetN()-1);
3e778975 350 continue;
f29f13a6 351 }
3e778975 352 } else {
f29f13a6 353 if((*c)->IsUsed() || IsKink()){
3e778975 354 (*c)->SetShared();
355 continue;
f29f13a6 356 }
357 }
358 (*c)->Use();
e3cf3d02 359 }
360}
361
362
f29f13a6 363
bcb6fb78 364//____________________________________________________________________
365void AliTRDseedV1::CookdEdx(Int_t nslices)
366{
367// Calculates average dE/dx for all slices and store them in the internal array fdEdx.
368//
369// Parameters:
370// nslices : number of slices for which dE/dx should be calculated
371// Output:
372// store results in the internal array fdEdx. This can be accessed with the method
373// AliTRDseedV1::GetdEdx()
374//
375// Detailed description
376// Calculates average dE/dx for all slices. Depending on the PID methode
377// the number of slices can be 3 (LQ) or 8(NN).
3ee48d6e 378// The calculation of dQ/dl are done using the tracklet fit results (see AliTRDseedV1::GetdQdl(Int_t))
bcb6fb78 379//
380// The following effects are included in the calculation:
381// 1. calibration values for t0 and vdrift (using x coordinate to calculate slice)
382// 2. cluster sharing (optional see AliTRDrecoParam::SetClusterSharing())
383// 3. cluster size
384//
385
8d2bec9e 386 Int_t nclusters[kNslices];
387 memset(nclusters, 0, kNslices*sizeof(Int_t));
388 memset(fdEdx, 0, kNslices*sizeof(Float_t));
e3cf3d02 389
e73abf77 390 const Double_t kDriftLength = (.5 * AliTRDgeometry::AmThick() + AliTRDgeometry::DrThick());
29b87567 391
3ee48d6e 392 AliTRDcluster *c = 0x0;
29b87567 393 for(int ic=0; ic<AliTRDtrackerV1::GetNTimeBins(); ic++){
8e709c82 394 if(!(c = fClusters[ic]) && !(c = fClusters[ic+kNtb])) continue;
e73abf77 395 Float_t dx = TMath::Abs(fX0 - c->GetX());
29b87567 396
397 // Filter clusters for dE/dx calculation
398
399 // 1.consider calibration effects for slice determination
e73abf77 400 Int_t slice;
401 if(dx<kDriftLength){ // TODO should be replaced by c->IsInChamber()
402 slice = Int_t(dx * nslices / kDriftLength);
403 } else slice = c->GetX() < fX0 ? nslices-1 : 0;
404
405
29b87567 406 // 2. take sharing into account
3e778975 407 Float_t w = /*c->IsShared() ? .5 :*/ 1.;
29b87567 408
409 // 3. take into account large clusters TODO
410 //w *= c->GetNPads() > 3 ? .8 : 1.;
411
412 //CHECK !!!
413 fdEdx[slice] += w * GetdQdl(ic); //fdQdl[ic];
414 nclusters[slice]++;
415 } // End of loop over clusters
416
cd40b287 417 //if(fReconstructor->GetPIDMethod() == AliTRDReconstructor::kLQPID){
0d83b3a5 418 if(nslices == AliTRDpidUtil::kLQslices){
29b87567 419 // calculate mean charge per slice (only LQ PID)
420 for(int is=0; is<nslices; is++){
421 if(nclusters[is]) fdEdx[is] /= nclusters[is];
422 }
423 }
bcb6fb78 424}
425
e3cf3d02 426//_____________________________________________________________________________
427void AliTRDseedV1::CookLabels()
428{
429 //
430 // Cook 2 labels for seed
431 //
432
433 Int_t labels[200];
434 Int_t out[200];
435 Int_t nlab = 0;
8d2bec9e 436 for (Int_t i = 0; i < kNclusters; i++) {
e3cf3d02 437 if (!fClusters[i]) continue;
438 for (Int_t ilab = 0; ilab < 3; ilab++) {
439 if (fClusters[i]->GetLabel(ilab) >= 0) {
440 labels[nlab] = fClusters[i]->GetLabel(ilab);
441 nlab++;
442 }
443 }
444 }
445
fac58f00 446 fLabels[2] = AliMathBase::Freq(nlab,labels,out,kTRUE);
e3cf3d02 447 fLabels[0] = out[0];
448 if ((fLabels[2] > 1) && (out[3] > 1)) fLabels[1] = out[2];
449}
450
451
bcb6fb78 452//____________________________________________________________________
0b433f72 453Float_t AliTRDseedV1::GetdQdl(Int_t ic, Float_t *dl) const
bcb6fb78 454{
3ee48d6e 455// Using the linear approximation of the track inside one TRD chamber (TRD tracklet)
456// the charge per unit length can be written as:
457// BEGIN_LATEX
458// #frac{dq}{dl} = #frac{q_{c}}{dx * #sqrt{1 + #(){#frac{dy}{dx}}^{2}_{fit} + #(){#frac{dy}{dx}}^{2}_{ref}}}
459// END_LATEX
460// where qc is the total charge collected in the current time bin and dx is the length
0b433f72 461// of the time bin.
462// The following correction are applied :
463// - charge : pad row cross corrections
464// [diffusion and TRF assymetry] TODO
465// - dx : anisochronity, track inclination - see Fit and AliTRDcluster::GetXloc()
466// and AliTRDcluster::GetYloc() for the effects taken into account
3ee48d6e 467//
468// Author : Alex Bercuci <A.Bercuci@gsi.de>
469//
470 Float_t dq = 0.;
471 if(fClusters[ic]) dq += TMath::Abs(fClusters[ic]->GetQ());
8e709c82 472 if(fClusters[ic+kNtb]) dq += TMath::Abs(fClusters[ic+kNtb]->GetQ());
0b433f72 473 if(dq<1.e-3) return 0.;
3ee48d6e 474
a2abcbc5 475 Double_t dx = fdX;
476 if(ic-1>=0 && ic+1<kNtb){
477 Float_t x2(0.), x1(0.);
478 // try to estimate upper radial position
479 if(fClusters[ic-1]) x2 = fClusters[ic-1]->GetX();
480 else if(fClusters[ic-1+kNtb]) x2 = fClusters[ic-1+kNtb]->GetX();
481 else if(fClusters[ic]) x2 = fClusters[ic]->GetX()+fdX;
482 else x2 = fClusters[ic+kNtb]->GetX()+fdX;
483 // try to estimate lower radial position
484 if(fClusters[ic+1]) x1 = fClusters[ic+1]->GetX();
485 else if(fClusters[ic+1+kNtb]) x1 = fClusters[ic+1+kNtb]->GetX();
486 else if(fClusters[ic]) x1 = fClusters[ic]->GetX()-fdX;
487 else x1 = fClusters[ic+kNtb]->GetX()-fdX;
488
489 dx = .5*(x2 - x1);
490 }
0b433f72 491 dx *= TMath::Sqrt(1. + fYfit[1]*fYfit[1] + fZref[1]*fZref[1]);
492
493 if(dl) (*dl) = dx;
494 return dq/dx;
bcb6fb78 495}
496
0b433f72 497//____________________________________________________________
498Float_t AliTRDseedV1::GetMomentum(Float_t *err) const
499{
500// Returns momentum of the track after update with the current tracklet as:
501// BEGIN_LATEX
502// p=#frac{1}{1/p_{t}} #sqrt{1+tgl^{2}}
503// END_LATEX
504// and optionally the momentum error (if err is not null).
505// The estimated variance of the momentum is given by:
506// BEGIN_LATEX
507// #sigma_{p}^{2} = (#frac{dp}{dp_{t}})^{2} #sigma_{p_{t}}^{2}+(#frac{dp}{dtgl})^{2} #sigma_{tgl}^{2}+2#frac{dp}{dp_{t}}#frac{dp}{dtgl} cov(tgl,1/p_{t})
508// END_LATEX
509// which can be simplified to
510// BEGIN_LATEX
511// #sigma_{p}^{2} = p^{2}p_{t}^{4}tgl^{2}#sigma_{tgl}^{2}-2p^{2}p_{t}^{3}tgl cov(tgl,1/p_{t})+p^{2}p_{t}^{2}#sigma_{1/p_{t}}^{2}
512// END_LATEX
513//
514
515 Double_t p = fPt*TMath::Sqrt(1.+fZref[1]*fZref[1]);
516 Double_t p2 = p*p;
517 Double_t tgl2 = fZref[1]*fZref[1];
518 Double_t pt2 = fPt*fPt;
519 if(err){
520 Double_t s2 =
521 p2*tgl2*pt2*pt2*fRefCov[4]
522 -2.*p2*fZref[1]*fPt*pt2*fRefCov[5]
523 +p2*pt2*fRefCov[6];
524 (*err) = TMath::Sqrt(s2);
525 }
526 return p;
527}
528
529
0906e73e 530//____________________________________________________________________
3e778975 531Float_t* AliTRDseedV1::GetProbability(Bool_t force)
0906e73e 532{
3e778975 533 if(!force) return &fProb[0];
534 if(!CookPID()) return 0x0;
535 return &fProb[0];
536}
537
538//____________________________________________________________
539Bool_t AliTRDseedV1::CookPID()
540{
0906e73e 541// Fill probability array for tracklet from the DB.
542//
543// Parameters
544//
545// Output
546// returns pointer to the probability array and 0x0 if missing DB access
547//
548// Detailed description
549
29b87567 550
551 // retrive calibration db
0906e73e 552 AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
553 if (!calibration) {
554 AliError("No access to calibration data");
3e778975 555 return kFALSE;
0906e73e 556 }
557
3a039a31 558 if (!fReconstructor) {
559 AliError("Reconstructor not set.");
3e778975 560 return kFALSE;
4ba1d6ae 561 }
562
0906e73e 563 // Retrieve the CDB container class with the parametric detector response
3a039a31 564 const AliTRDCalPID *pd = calibration->GetPIDObject(fReconstructor->GetPIDMethod());
0906e73e 565 if (!pd) {
566 AliError("No access to AliTRDCalPID object");
3e778975 567 return kFALSE;
0906e73e 568 }
29b87567 569 //AliInfo(Form("Method[%d] : %s", fReconstructor->GetRecoParam() ->GetPIDMethod(), pd->IsA()->GetName()));
10f75631 570
29b87567 571 // calculate tracklet length TO DO
0906e73e 572 Float_t length = (AliTRDgeometry::AmThick() + AliTRDgeometry::DrThick());
573 /// TMath::Sqrt((1.0 - fSnp[iPlane]*fSnp[iPlane]) / (1.0 + fTgl[iPlane]*fTgl[iPlane]));
574
575 //calculate dE/dx
3a039a31 576 CookdEdx(fReconstructor->GetNdEdxSlices());
0906e73e 577
578 // Sets the a priori probabilities
579 for(int ispec=0; ispec<AliPID::kSPECIES; ispec++) {
b25a5e9e 580 fProb[ispec] = pd->GetProbability(ispec, GetMomentum(), &fdEdx[0], length, GetPlane());
0906e73e 581 }
582
3e778975 583 return kTRUE;
0906e73e 584}
585
e4f2f73d 586//____________________________________________________________________
587Float_t AliTRDseedV1::GetQuality(Bool_t kZcorr) const
588{
589 //
590 // Returns a quality measurement of the current seed
591 //
592
dd8059a8 593 Float_t zcorr = kZcorr ? GetTilt() * (fZfit[0] - fZref[0]) : 0.;
29b87567 594 return
3e778975 595 .5 * TMath::Abs(18.0 - GetN())
29b87567 596 + 10.* TMath::Abs(fYfit[1] - fYref[1])
597 + 5. * TMath::Abs(fYfit[0] - fYref[0] + zcorr)
dd8059a8 598 + 2. * TMath::Abs(fZfit[0] - fZref[0]) / GetPadLength();
e4f2f73d 599}
600
0906e73e 601//____________________________________________________________________
d937ad7a 602void AliTRDseedV1::GetCovAt(Double_t x, Double_t *cov) const
0906e73e 603{
d937ad7a 604// Computes covariance in the y-z plane at radial point x (in tracking coordinates)
605// and returns the results in the preallocated array cov[3] as :
606// cov[0] = Var(y)
607// cov[1] = Cov(yz)
608// cov[2] = Var(z)
609//
610// Details
611//
612// For the linear transformation
613// BEGIN_LATEX
614// Y = T_{x} X^{T}
615// END_LATEX
616// The error propagation has the general form
617// BEGIN_LATEX
618// C_{Y} = T_{x} C_{X} T_{x}^{T}
619// END_LATEX
620// We apply this formula 2 times. First to calculate the covariance of the tracklet
621// at point x we consider:
622// BEGIN_LATEX
623// T_{x} = (1 x); X=(y0 dy/dx); C_{X}=#(){#splitline{Var(y0) Cov(y0, dy/dx)}{Cov(y0, dy/dx) Var(dy/dx)}}
624// END_LATEX
625// and secondly to take into account the tilt angle
626// BEGIN_LATEX
627// T_{#alpha} = #(){#splitline{cos(#alpha) __ sin(#alpha)}{-sin(#alpha) __ cos(#alpha)}}; X=(y z); C_{X}=#(){#splitline{Var(y) 0}{0 Var(z)}}
628// END_LATEX
629//
630// using simple trigonometrics one can write for this last case
631// BEGIN_LATEX
632// C_{Y}=#frac{1}{1+tg^{2}#alpha} #(){#splitline{(#sigma_{y}^{2}+tg^{2}#alpha#sigma_{z}^{2}) __ tg#alpha(#sigma_{z}^{2}-#sigma_{y}^{2})}{tg#alpha(#sigma_{z}^{2}-#sigma_{y}^{2}) __ (#sigma_{z}^{2}+tg^{2}#alpha#sigma_{y}^{2})}}
633// END_LATEX
634// which can be aproximated for small alphas (2 deg) with
635// BEGIN_LATEX
636// C_{Y}=#(){#splitline{#sigma_{y}^{2} __ (#sigma_{z}^{2}-#sigma_{y}^{2})tg#alpha}{((#sigma_{z}^{2}-#sigma_{y}^{2})tg#alpha __ #sigma_{z}^{2}}}
637// END_LATEX
638//
639// before applying the tilt rotation we also apply systematic uncertainties to the tracklet
640// position which can be tunned from outside via the AliTRDrecoParam::SetSysCovMatrix(). They might
641// account for extra misalignment/miscalibration uncertainties.
642//
643// Author :
644// Alex Bercuci <A.Bercuci@gsi.de>
645// Date : Jan 8th 2009
646//
b1957d3c 647
648
d937ad7a 649 Double_t xr = fX0-x;
650 Double_t sy2 = fCov[0] +2.*xr*fCov[1] + xr*xr*fCov[2];
b72f4eaf 651 Double_t sz2 = fS2Z;
652 //GetPadLength()*GetPadLength()/12.;
0906e73e 653
d937ad7a 654 // insert systematic uncertainties
bb2db46c 655 if(fReconstructor){
656 Double_t sys[15]; memset(sys, 0, 15*sizeof(Double_t));
657 fReconstructor->GetRecoParam()->GetSysCovMatrix(sys);
658 sy2 += sys[0];
659 sz2 += sys[1];
660 }
d937ad7a 661 // rotate covariance matrix
dd8059a8 662 Double_t t2 = GetTilt()*GetTilt();
d937ad7a 663 Double_t correction = 1./(1. + t2);
664 cov[0] = (sy2+t2*sz2)*correction;
dd8059a8 665 cov[1] = GetTilt()*(sz2 - sy2)*correction;
d937ad7a 666 cov[2] = (t2*sy2+sz2)*correction;
b72f4eaf 667
668 //printf("C(%6.1f %+6.3f %6.1f) [%s]\n", 1.e4*TMath::Sqrt(cov[0]), cov[1], 1.e4*TMath::Sqrt(cov[2]), IsRowCross()?" RC ":"-");
d937ad7a 669}
eb38ed55 670
bb2db46c 671//____________________________________________________________
672Double_t AliTRDseedV1::GetCovSqrt(Double_t *c, Double_t *d)
673{
674// Helper function to calculate the square root of the covariance matrix.
675// The input matrix is stored in the vector c and the result in the vector d.
41b7c7b6 676// Both arrays have to be initialized by the user with at least 3 elements. Return negative in case of failure.
bb2db46c 677//
ec3f0161 678// For calculating the square root of the symmetric matrix c
679// the following relation is used:
bb2db46c 680// BEGIN_LATEX
ec3f0161 681// C^{1/2} = VD^{1/2}V^{-1}
bb2db46c 682// END_LATEX
41b7c7b6 683// with V being the matrix with the n eigenvectors as columns.
ec3f0161 684// In case C is symmetric the followings are true:
685// - matrix D is diagonal with the diagonal given by the eigenvalues of C
41b7c7b6 686// - V = V^{-1}
bb2db46c 687//
688// Author A.Bercuci <A.Bercuci@gsi.de>
689// Date Mar 19 2009
690
41b7c7b6 691 Double_t L[2], // eigenvalues
692 V[3]; // eigenvectors
bb2db46c 693 // the secular equation and its solution :
694 // (c[0]-L)(c[2]-L)-c[1]^2 = 0
695 // L^2 - L*Tr(c)+DET(c) = 0
696 // L12 = [Tr(c) +- sqrt(Tr(c)^2-4*DET(c))]/2
697 Double_t Tr = c[0]+c[2], // trace
698 DET = c[0]*c[2]-c[1]*c[1]; // determinant
41b7c7b6 699 if(TMath::Abs(DET)<1.e-20) return -1.;
bb2db46c 700 Double_t DD = TMath::Sqrt(Tr*Tr - 4*DET);
701 L[0] = .5*(Tr + DD);
702 L[1] = .5*(Tr - DD);
41b7c7b6 703 if(L[0]<0. || L[1]<0.) return -1.;
704
705 // the sym V matrix
706 // | v00 v10|
707 // | v10 v11|
708 Double_t tmp = (L[0]-c[0])/c[1];
709 V[0] = TMath::Sqrt(1./(tmp*tmp+1));
710 V[1] = tmp*V[0];
711 V[2] = V[1]*c[1]/(L[1]-c[2]);
712 // the VD^{1/2}V is:
713 L[0] = TMath::Sqrt(L[0]); L[1] = TMath::Sqrt(L[1]);
714 d[0] = V[0]*V[0]*L[0]+V[1]*V[1]*L[1];
715 d[1] = V[0]*V[1]*L[0]+V[1]*V[2]*L[1];
716 d[2] = V[1]*V[1]*L[0]+V[2]*V[2]*L[1];
bb2db46c 717
718 return 1.;
719}
720
721//____________________________________________________________
722Double_t AliTRDseedV1::GetCovInv(Double_t *c, Double_t *d)
723{
724// Helper function to calculate the inverse of the covariance matrix.
725// The input matrix is stored in the vector c and the result in the vector d.
726// Both arrays have to be initialized by the user with at least 3 elements
727// The return value is the determinant or 0 in case of singularity.
728//
729// Author A.Bercuci <A.Bercuci@gsi.de>
730// Date Mar 19 2009
731
732 Double_t Det = c[0]*c[2] - c[1]*c[1];
733 if(TMath::Abs(Det)<1.e-20) return 0.;
734 Double_t InvDet = 1./Det;
735 d[0] = c[2]*InvDet;
736 d[1] =-c[1]*InvDet;
737 d[2] = c[0]*InvDet;
738 return Det;
739}
0906e73e 740
b72f4eaf 741//____________________________________________________________________
742UShort_t AliTRDseedV1::GetVolumeId() const
743{
744 Int_t ic=0;
745 while(ic<kNclusters && !fClusters[ic]) ic++;
746 return fClusters[ic] ? fClusters[ic]->GetVolumeId() : 0;
747}
748
749
d937ad7a 750//____________________________________________________________________
e3cf3d02 751void AliTRDseedV1::Calibrate()
d937ad7a 752{
e3cf3d02 753// Retrieve calibration and position parameters from OCDB.
754// The following information are used
d937ad7a 755// - detector index
e3cf3d02 756// - column and row position of first attached cluster. If no clusters are attached
757// to the tracklet a random central chamber position (c=70, r=7) will be used.
758//
759// The following information is cached in the tracklet
760// t0 (trigger delay)
761// drift velocity
762// PRF width
763// omega*tau = tg(a_L)
764// diffusion coefficients (longitudinal and transversal)
d937ad7a 765//
766// Author :
767// Alex Bercuci <A.Bercuci@gsi.de>
768// Date : Jan 8th 2009
769//
eb38ed55 770
d937ad7a 771 AliCDBManager *cdb = AliCDBManager::Instance();
772 if(cdb->GetRun() < 0){
773 AliError("OCDB manager not properly initialized");
774 return;
775 }
0906e73e 776
e3cf3d02 777 AliTRDcalibDB *calib = AliTRDcalibDB::Instance();
778 AliTRDCalROC *vdROC = calib->GetVdriftROC(fDet),
779 *t0ROC = calib->GetT0ROC(fDet);;
780 const AliTRDCalDet *vdDet = calib->GetVdriftDet();
781 const AliTRDCalDet *t0Det = calib->GetT0Det();
d937ad7a 782
783 Int_t col = 70, row = 7;
784 AliTRDcluster **c = &fClusters[0];
3e778975 785 if(GetN()){
d937ad7a 786 Int_t ic = 0;
8d2bec9e 787 while (ic<kNclusters && !(*c)){ic++; c++;}
d937ad7a 788 if(*c){
789 col = (*c)->GetPadCol();
790 row = (*c)->GetPadRow();
791 }
792 }
3a039a31 793
e3cf3d02 794 fT0 = t0Det->GetValue(fDet) + t0ROC->GetValue(col,row);
795 fVD = vdDet->GetValue(fDet) * vdROC->GetValue(col, row);
796 fS2PRF = calib->GetPRFWidth(fDet, col, row); fS2PRF *= fS2PRF;
797 fExB = AliTRDCommonParam::Instance()->GetOmegaTau(fVD);
798 AliTRDCommonParam::Instance()->GetDiffCoeff(fDiffL,
799 fDiffT, fVD);
800 SetBit(kCalib, kTRUE);
0906e73e 801}
802
0906e73e 803//____________________________________________________________________
29b87567 804void AliTRDseedV1::SetOwner()
0906e73e 805{
29b87567 806 //AliInfo(Form("own [%s] fOwner[%s]", own?"YES":"NO", fOwner?"YES":"NO"));
807
808 if(TestBit(kOwner)) return;
8d2bec9e 809 for(int ic=0; ic<kNclusters; ic++){
29b87567 810 if(!fClusters[ic]) continue;
811 fClusters[ic] = new AliTRDcluster(*fClusters[ic]);
812 }
813 SetBit(kOwner);
0906e73e 814}
815
eb2b4f91 816//____________________________________________________________
817void AliTRDseedV1::SetPadPlane(AliTRDpadPlane *p)
818{
819// Shortcut method to initialize pad geometry.
820 if(!p) return;
821 SetTilt(TMath::Tan(TMath::DegToRad()*p->GetTiltingAngle()));
822 SetPadLength(p->GetLengthIPad());
823 SetPadWidth(p->GetWidthIPad());
824}
825
826
e4f2f73d 827//____________________________________________________________________
b1957d3c 828Bool_t AliTRDseedV1::AttachClusters(AliTRDtrackingChamber *chamber, Bool_t tilt)
e4f2f73d 829{
830 //
831 // Projective algorithm to attach clusters to seeding tracklets
832 //
833 // Parameters
834 //
835 // Output
836 //
837 // Detailed description
838 // 1. Collapse x coordinate for the full detector plane
839 // 2. truncated mean on y (r-phi) direction
840 // 3. purge clusters
841 // 4. truncated mean on z direction
842 // 5. purge clusters
843 // 6. fit tracklet
844 //
b1957d3c 845 Bool_t kPRINT = kFALSE;
29b87567 846 if(!fReconstructor->GetRecoParam() ){
847 AliError("Seed can not be used without a valid RecoParam.");
848 return kFALSE;
849 }
b1957d3c 850 // Initialize reco params for this tracklet
851 // 1. first time bin in the drift region
a2abcbc5 852 Int_t t0 = 14;
b1957d3c 853 Int_t kClmin = Int_t(fReconstructor->GetRecoParam() ->GetFindableClusters()*AliTRDtrackerV1::GetNTimeBins());
29b87567 854
b1957d3c 855 Double_t syRef = TMath::Sqrt(fRefCov[0]);
29b87567 856 //define roads
b1957d3c 857 Double_t kroady = 1.;
858 //fReconstructor->GetRecoParam() ->GetRoad1y();
dd8059a8 859 Double_t kroadz = GetPadLength() * 1.5 + 1.;
b1957d3c 860 if(kPRINT) printf("AttachClusters() sy[%f] road[%f]\n", syRef, kroady);
29b87567 861
862 // working variables
b1957d3c 863 const Int_t kNrows = 16;
8d2bec9e 864 AliTRDcluster *clst[kNrows][kNclusters];
b1957d3c 865 Double_t cond[4], dx, dy, yt, zt,
8d2bec9e 866 yres[kNrows][kNclusters];
867 Int_t idxs[kNrows][kNclusters], ncl[kNrows], ncls = 0;
b1957d3c 868 memset(ncl, 0, kNrows*sizeof(Int_t));
8d2bec9e 869 memset(clst, 0, kNrows*kNclusters*sizeof(AliTRDcluster*));
b1957d3c 870
29b87567 871 // Do cluster projection
b1957d3c 872 AliTRDcluster *c = 0x0;
29b87567 873 AliTRDchamberTimeBin *layer = 0x0;
b1957d3c 874 Bool_t kBUFFER = kFALSE;
875 for (Int_t it = 0; it < AliTRDtrackerV1::GetNTimeBins(); it++) {
876 if(!(layer = chamber->GetTB(it))) continue;
29b87567 877 if(!Int_t(*layer)) continue;
878
b1957d3c 879 dx = fX0 - layer->GetX();
880 yt = fYref[0] - fYref[1] * dx;
881 zt = fZref[0] - fZref[1] * dx;
882 if(kPRINT) printf("\t%2d dx[%f] yt[%f] zt[%f]\n", it, dx, yt, zt);
883
884 // select clusters on a 5 sigmaKalman level
885 cond[0] = yt; cond[2] = kroady;
886 cond[1] = zt; cond[3] = kroadz;
887 Int_t n=0, idx[6];
888 layer->GetClusters(cond, idx, n, 6);
889 for(Int_t ic = n; ic--;){
890 c = (*layer)[idx[ic]];
891 dy = yt - c->GetY();
dd8059a8 892 dy += tilt ? GetTilt() * (c->GetZ() - zt) : 0.;
b1957d3c 893 // select clusters on a 3 sigmaKalman level
894/* if(tilt && TMath::Abs(dy) > 3.*syRef){
895 printf("too large !!!\n");
896 continue;
897 }*/
898 Int_t r = c->GetPadRow();
899 if(kPRINT) printf("\t\t%d dy[%f] yc[%f] r[%d]\n", ic, TMath::Abs(dy), c->GetY(), r);
900 clst[r][ncl[r]] = c;
901 idxs[r][ncl[r]] = idx[ic];
902 yres[r][ncl[r]] = dy;
903 ncl[r]++; ncls++;
904
8d2bec9e 905 if(ncl[r] >= kNclusters) {
906 AliWarning(Form("Cluster candidates reached limit %d. Some may be lost.", kNclusters));
b1957d3c 907 kBUFFER = kTRUE;
29b87567 908 break;
909 }
910 }
b1957d3c 911 if(kBUFFER) break;
29b87567 912 }
b1957d3c 913 if(kPRINT) printf("Found %d clusters\n", ncls);
914 if(ncls<kClmin) return kFALSE;
915
916 // analyze each row individualy
917 Double_t mean, syDis;
918 Int_t nrow[] = {0, 0, 0}, nr = 0, lr=-1;
919 for(Int_t ir=kNrows; ir--;){
920 if(!(ncl[ir])) continue;
921 if(lr>0 && lr-ir != 1){
922 if(kPRINT) printf("W - gap in rows attached !!\n");
29b87567 923 }
b1957d3c 924 if(kPRINT) printf("\tir[%d] lr[%d] n[%d]\n", ir, lr, ncl[ir]);
925 // Evaluate truncated mean on the y direction
926 if(ncl[ir] > 3) AliMathBase::EvaluateUni(ncl[ir], yres[ir], mean, syDis, Int_t(ncl[ir]*.8));
927 else {
928 mean = 0.; syDis = 0.;
929 }
930
931 // TODO check mean and sigma agains cluster resolution !!
932 if(kPRINT) printf("\tr[%2d] m[%f %5.3fsigma] s[%f]\n", ir, mean, TMath::Abs(mean/syRef), syDis);
933 // select clusters on a 3 sigmaDistr level
934 Bool_t kFOUND = kFALSE;
935 for(Int_t ic = ncl[ir]; ic--;){
936 if(yres[ir][ic] - mean > 3. * syDis){
937 clst[ir][ic] = 0x0; continue;
938 }
939 nrow[nr]++; kFOUND = kTRUE;
940 }
941 // exit loop
942 if(kFOUND) nr++;
943 lr = ir; if(nr>=3) break;
29b87567 944 }
b1957d3c 945 if(kPRINT) printf("lr[%d] nr[%d] nrow[0]=%d nrow[1]=%d nrow[2]=%d\n", lr, nr, nrow[0], nrow[1], nrow[2]);
946
947 // classify cluster rows
948 Int_t row = -1;
949 switch(nr){
950 case 1:
951 row = lr;
952 break;
953 case 2:
954 SetBit(kRowCross, kTRUE); // mark pad row crossing
955 if(nrow[0] > nrow[1]){ row = lr+1; lr = -1;}
956 else{
957 row = lr; lr = 1;
958 nrow[2] = nrow[1];
959 nrow[1] = nrow[0];
960 nrow[0] = nrow[2];
29b87567 961 }
b1957d3c 962 break;
963 case 3:
964 SetBit(kRowCross, kTRUE); // mark pad row crossing
965 break;
29b87567 966 }
b1957d3c 967 if(kPRINT) printf("\trow[%d] n[%d]\n\n", row, nrow[0]);
968 if(row<0) return kFALSE;
29b87567 969
b1957d3c 970 // Select and store clusters
971 // We should consider here :
972 // 1. How far is the chamber boundary
973 // 2. How big is the mean
3e778975 974 Int_t n = 0;
b1957d3c 975 for (Int_t ir = 0; ir < nr; ir++) {
976 Int_t jr = row + ir*lr;
977 if(kPRINT) printf("\tattach %d clusters for row %d\n", ncl[jr], jr);
978 for (Int_t ic = 0; ic < ncl[jr]; ic++) {
979 if(!(c = clst[jr][ic])) continue;
980 Int_t it = c->GetPadTime();
981 // TODO proper indexing of clusters !!
e3cf3d02 982 fIndexes[it+kNtb*ir] = chamber->GetTB(it)->GetGlobalIndex(idxs[jr][ic]);
983 fClusters[it+kNtb*ir] = c;
29b87567 984
b1957d3c 985 //printf("\tid[%2d] it[%d] idx[%d]\n", ic, it, fIndexes[it]);
986
3e778975 987 n++;
b1957d3c 988 }
989 }
990
29b87567 991 // number of minimum numbers of clusters expected for the tracklet
3e778975 992 if (n < kClmin){
993 //AliWarning(Form("Not enough clusters to fit the tracklet %d [%d].", n, kClmin));
e4f2f73d 994 return kFALSE;
995 }
3e778975 996 SetN(n);
0906e73e 997
e3cf3d02 998 // Load calibration parameters for this tracklet
999 Calibrate();
b1957d3c 1000
1001 // calculate dx for time bins in the drift region (calibration aware)
a2abcbc5 1002 Float_t x[2] = {0.,0.}; Int_t tb[2]={0,0};
1003 for (Int_t it = t0, irp=0; irp<2 && it < AliTRDtrackerV1::GetNTimeBins(); it++) {
b1957d3c 1004 if(!fClusters[it]) continue;
1005 x[irp] = fClusters[it]->GetX();
a2abcbc5 1006 tb[irp] = fClusters[it]->GetLocalTimeBin();
1007 printf(" x[%d]=%f t[%d]=%d\n", irp, x[irp], irp, tb[irp]);
b1957d3c 1008 irp++;
e3cf3d02 1009 }
d86ed84c 1010 Int_t dtb = tb[1] - tb[0];
1011 fdX = dtb ? (x[0] - x[1]) / dtb : 0.15;
b1957d3c 1012
29b87567 1013 return kTRUE;
e4f2f73d 1014}
1015
03cef9b2 1016//____________________________________________________________
1017void AliTRDseedV1::Bootstrap(const AliTRDReconstructor *rec)
1018{
1019// Fill in all derived information. It has to be called after recovery from file or HLT.
1020// The primitive data are
1021// - list of clusters
1022// - detector (as the detector will be removed from clusters)
1023// - position of anode wire (fX0) - temporary
1024// - track reference position and direction
1025// - momentum of the track
1026// - time bin length [cm]
1027//
1028// A.Bercuci <A.Bercuci@gsi.de> Oct 30th 2008
1029//
1030 fReconstructor = rec;
1031 AliTRDgeometry g;
1032 AliTRDpadPlane *pp = g.GetPadPlane(fDet);
dd8059a8 1033 fPad[0] = pp->GetLengthIPad();
1034 fPad[1] = pp->GetWidthIPad();
1035 fPad[3] = TMath::Tan(TMath::DegToRad()*pp->GetTiltingAngle());
e3cf3d02 1036 //fSnp = fYref[1]/TMath::Sqrt(1+fYref[1]*fYref[1]);
1037 //fTgl = fZref[1];
3e778975 1038 Int_t n = 0, nshare = 0, nused = 0;
03cef9b2 1039 AliTRDcluster **cit = &fClusters[0];
8d2bec9e 1040 for(Int_t ic = kNclusters; ic--; cit++){
03cef9b2 1041 if(!(*cit)) return;
3e778975 1042 n++;
1043 if((*cit)->IsShared()) nshare++;
1044 if((*cit)->IsUsed()) nused++;
03cef9b2 1045 }
3e778975 1046 SetN(n); SetNUsed(nused); SetNShared(nshare);
e3cf3d02 1047 Fit();
03cef9b2 1048 CookLabels();
1049 GetProbability();
1050}
1051
1052
e4f2f73d 1053//____________________________________________________________________
b72f4eaf 1054Bool_t AliTRDseedV1::Fit(Bool_t tilt, Bool_t zcorr)
e4f2f73d 1055{
16cca13f 1056//
1057// Linear fit of the clusters attached to the tracklet
1058//
1059// Parameters :
1060// - tilt : switch for tilt pad correction of cluster y position based on
1061// the z, dzdx info from outside [default false].
1062// - zcorr : switch for using z information to correct for anisochronity
1063// and a finner error parametrization estimation [default false]
1064// Output :
1065// True if successful
1066//
1067// Detailed description
1068//
1069// Fit in the xy plane
1070//
1071//
e4f2f73d 1072
b72f4eaf 1073 if(!IsCalibrated()) Calibrate();
e3cf3d02 1074
29b87567 1075 const Int_t kClmin = 8;
010d62b0 1076
9462866a 1077
1078 // cluster error parametrization parameters
010d62b0 1079 // 1. sy total charge
9462866a 1080 const Float_t sq0inv = 0.019962; // [1/q0]
1081 const Float_t sqb = 1.0281564; //[cm]
010d62b0 1082 // 2. sy for the PRF
1083 const Float_t scy[AliTRDgeometry::kNlayer][4] = {
d937ad7a 1084 {2.827e-02, 9.600e-04, 4.296e-01, 2.271e-02},
1085 {2.952e-02,-2.198e-04, 4.146e-01, 2.339e-02},
1086 {3.090e-02, 1.514e-03, 4.020e-01, 2.402e-02},
1087 {3.260e-02,-2.037e-03, 3.946e-01, 2.509e-02},
1088 {3.439e-02,-3.601e-04, 3.883e-01, 2.623e-02},
1089 {3.510e-02, 2.066e-03, 3.651e-01, 2.588e-02},
010d62b0 1090 };
d937ad7a 1091
2f7d6ac8 1092 // get track direction
1093 Double_t y0 = fYref[0];
1094 Double_t dydx = fYref[1];
1095 Double_t z0 = fZref[0];
1096 Double_t dzdx = fZref[1];
1097 Double_t yt, zt;
ae4e8b84 1098
e3cf3d02 1099 // calculation of tg^2(phi - a_L) and tg^2(a_L)
1100 Double_t tgg = (dydx-fExB)/(1.+dydx*fExB); tgg *= tgg;
1101 //Double_t exb2= fExB*fExB;
1102
b1957d3c 1103 //AliTRDtrackerV1::AliTRDLeastSquare fitterZ;
24d8660e 1104 TLinearFitter fitterY(1, "pol1");
b72f4eaf 1105 TLinearFitter fitterZ(1, "pol1");
ae4e8b84 1106
29b87567 1107 // book cluster information
8d2bec9e 1108 Double_t qc[kNclusters], xc[kNclusters], yc[kNclusters], zc[kNclusters], sy[kNclusters];
e3cf3d02 1109
010d62b0 1110 Int_t ily = AliTRDgeometry::GetLayer(fDet);
dd8059a8 1111 Int_t n = 0;
9eb2d46c 1112 AliTRDcluster *c=0x0, **jc = &fClusters[0];
9eb2d46c 1113 for (Int_t ic=0; ic<kNtb; ic++, ++jc) {
b1957d3c 1114 //zRow[ic] = -1;
29b87567 1115 xc[ic] = -1.;
1116 yc[ic] = 999.;
1117 zc[ic] = 999.;
1118 sy[ic] = 0.;
9eb2d46c 1119 if(!(c = (*jc))) continue;
29b87567 1120 if(!c->IsInChamber()) continue;
9462866a 1121
29b87567 1122 Float_t w = 1.;
1123 if(c->GetNPads()>4) w = .5;
1124 if(c->GetNPads()>5) w = .2;
b72f4eaf 1125 Int_t tb = c->GetLocalTimeBin();
010d62b0 1126
dd8059a8 1127 qc[n] = TMath::Abs(c->GetQ());
b72f4eaf 1128 // Radial cluster position
e3cf3d02 1129 //Int_t jc = TMath::Max(fN-3, 0);
1130 //xc[fN] = c->GetXloc(fT0, fVD, &qc[jc], &xc[jc]/*, z0 - c->GetX()*dzdx*/);
b72f4eaf 1131 xc[n] = fX0 - c->GetX();
1132
1133 //Double_t s2 = fS2PRF + fDiffL*fDiffL*xc[n]/(1.+2.*exb2)+tgg*xc[n]*xc[n]*exb2/12.;
dd8059a8 1134 //yc[fN] = c->GetYloc(s2, GetPadWidth(), xc[fN], fExB);
b72f4eaf 1135 yc[n] = c->GetY()-AliTRDcluster::GetYcorr(ily, c->GetCenter());
dd8059a8 1136 zc[n] = c->GetZ();
2f7d6ac8 1137
1138 // extrapolated y value for the track
dd8059a8 1139 yt = y0 - xc[n]*dydx;
2f7d6ac8 1140 // extrapolated z value for the track
dd8059a8 1141 zt = z0 - xc[n]*dzdx;
2f7d6ac8 1142 // tilt correction
dd8059a8 1143 if(tilt) yc[n] -= GetTilt()*(zc[n] - zt);
2f7d6ac8 1144
010d62b0 1145 // ELABORATE CLUSTER ERROR
010d62b0 1146 // basic y error (|| to track).
b72f4eaf 1147 sy[n] = AliTRDcluster::GetSY(tb, zcorr?zt:-1.);
d937ad7a 1148 //printf("cluster[%d]\n\tsy[0] = %5.3e [um]\n", fN, sy[fN]*1.e4);
010d62b0 1149 // y error due to total charge
dd8059a8 1150 sy[n] += sqb*(1./qc[n] - sq0inv);
d937ad7a 1151 //printf("\tsy[1] = %5.3e [um]\n", sy[fN]*1.e4);
010d62b0 1152 // y error due to PRF
dd8059a8 1153 sy[n] += scy[ily][0]*TMath::Gaus(c->GetCenter(), scy[ily][1], scy[ily][2]) - scy[ily][3];
d937ad7a 1154 //printf("\tsy[2] = %5.3e [um]\n", sy[fN]*1.e4);
1155
dd8059a8 1156 sy[n] *= sy[n];
010d62b0 1157
1158 // ADD ERROR ON x
9462866a 1159 // error of drift length parallel to the track
b72f4eaf 1160 Double_t sx = AliTRDcluster::GetSX(tb, zcorr?zt:-1.); // [cm]
d937ad7a 1161 //printf("\tsx[0] = %5.3e [um]\n", sx*1.e4);
d937ad7a 1162 sx *= sx; // square sx
d937ad7a 1163
9462866a 1164 // add error from ExB
b72f4eaf 1165 sy[n] += fExB*fExB*sx;
d937ad7a 1166 //printf("\tsy[3] = %5.3e [um^2]\n", sy[fN]*1.e8);
1167
1168 // global radial error due to misalignment/miscalibration
1169 Double_t sx0 = 0.; sx0 *= sx0;
1170 // add sx contribution to sy due to track angle
b72f4eaf 1171 sy[n] += tgg*(sx+sx0);
d937ad7a 1172 // TODO we should add tilt pad correction here
1173 //printf("\tsy[4] = %5.3e [um^2]\n", sy[fN]*1.e8);
dd8059a8 1174 c->SetSigmaY2(sy[n]);
d937ad7a 1175
dd8059a8 1176 sy[n] = TMath::Sqrt(sy[n]);
1177 fitterY.AddPoint(&xc[n], yc[n], sy[n]);
b72f4eaf 1178 fitterZ.AddPoint(&xc[n], qc[n], 1.);
dd8059a8 1179 n++;
29b87567 1180 }
47d5d320 1181 // to few clusters
dd8059a8 1182 if (n < kClmin) return kFALSE;
2f7d6ac8 1183
d937ad7a 1184 // fit XY
2f7d6ac8 1185 fitterY.Eval();
d937ad7a 1186 fYfit[0] = fitterY.GetParameter(0);
1187 fYfit[1] = -fitterY.GetParameter(1);
1188 // store covariance
1189 Double_t *p = fitterY.GetCovarianceMatrix();
1190 fCov[0] = p[0]; // variance of y0
1191 fCov[1] = p[1]; // covariance of y0, dydx
1192 fCov[2] = p[3]; // variance of dydx
b1957d3c 1193 // the ref radial position is set at the minimum of
1194 // the y variance of the tracklet
b72f4eaf 1195 fX = -fCov[1]/fCov[2];
b1957d3c 1196
1197 // fit XZ
b72f4eaf 1198 if(IsRowCross()){
1199 Int_t ic=n=kNclusters-1; jc = &fClusters[ic];
1200 for(; ic>kNtb; ic--, --jc){
1201 if(!(c = (*jc))) continue;
1202 if(!c->IsInChamber()) continue;
1203 qc[n] = TMath::Abs(c->GetQ());
1204 xc[n] = fX0 - c->GetX();
1205 zc[n] = c->GetZ();
1206 fitterZ.AddPoint(&xc[n], -qc[n], 1.);
1207 n--;
1208 }
1209 // fit XZ
1210 fitterZ.Eval();
1211 if(fitterZ.GetParameter(1)!=0.){
1212 fX = -fitterZ.GetParameter(0)/fitterZ.GetParameter(1);
1213 fX=(fX<0.)?0.:fX;
1214 Float_t dl = .5*AliTRDgeometry::CamHght()+AliTRDgeometry::CdrHght();
1215 fX=(fX> dl)?dl:fX;
07bbc13c 1216 fX-=.055; // TODO to be understood
b72f4eaf 1217 }
1218
1219 fZfit[0] = .5*(zc[0]+zc[kNclusters-1]); fZfit[1] = 0.;
c850c351 1220 // temporary external error parameterization
1221 fS2Z = 0.05+0.4*TMath::Abs(fZref[1]); fS2Z *= fS2Z;
1222 // TODO correct formula
1223 //fS2Z = sigma_x*TMath::Abs(fZref[1]);
b1957d3c 1224 } else {
1225 fZfit[0] = zc[0]; fZfit[1] = 0.;
dd8059a8 1226 fS2Z = GetPadLength()*GetPadLength()/12.;
29b87567 1227 }
b72f4eaf 1228 fS2Y = fCov[0] +2.*fX*fCov[1] + fX*fX*fCov[2];
29b87567 1229 return kTRUE;
16cca13f 1230// // determine z offset of the fit
1231// Float_t zslope = 0.;
1232// Int_t nchanges = 0, nCross = 0;
1233// if(nz==2){ // tracklet is crossing pad row
1234// // Find the break time allowing one chage on pad-rows
1235// // with maximal number of accepted clusters
1236// Int_t padRef = zRow[0];
1237// for (Int_t ic=1; ic<fN; ic++) {
1238// if(zRow[ic] == padRef) continue;
1239//
1240// // debug
1241// if(zRow[ic-1] == zRow[ic]){
1242// printf("ERROR in pad row change!!!\n");
1243// }
1244//
1245// // evaluate parameters of the crossing point
1246// Float_t sx = (xc[ic-1] - xc[ic])*convert;
1247// fCross[0] = .5 * (xc[ic-1] + xc[ic]);
1248// fCross[2] = .5 * (zc[ic-1] + zc[ic]);
1249// fCross[3] = TMath::Max(dzdx * sx, .01);
1250// zslope = zc[ic-1] > zc[ic] ? 1. : -1.;
1251// padRef = zRow[ic];
1252// nCross = ic;
1253// nchanges++;
1254// }
1255// }
1256//
1257// // condition on nCross and reset nchanges TODO
1258//
1259// if(nchanges==1){
1260// if(dzdx * zslope < 0.){
1261// AliInfo("Tracklet-Track mismatch in dzdx. TODO.");
1262// }
1263//
1264//
1265// //zc[nc] = fitterZ.GetFunctionParameter(0);
1266// fCross[1] = fYfit[0] - fCross[0] * fYfit[1];
1267// fCross[0] = fX0 - fCross[0];
1268// }
e4f2f73d 1269}
1270
e4f2f73d 1271
f29f13a6 1272/*
e3cf3d02 1273//_____________________________________________________________________________
1274void AliTRDseedV1::FitMI()
1275{
1276//
1277// Fit the seed.
1278// Marian Ivanov's version
1279//
1280// linear fit on the y direction with respect to the reference direction.
1281// The residuals for each x (x = xc - x0) are deduced from:
1282// dy = y - yt (1)
1283// the tilting correction is written :
1284// y = yc + h*(zc-zt) (2)
1285// yt = y0+dy/dx*x (3)
1286// zt = z0+dz/dx*x (4)
1287// from (1),(2),(3) and (4)
1288// dy = yc - y0 - (dy/dx + h*dz/dx)*x + h*(zc-z0)
1289// the last term introduces the correction on y direction due to tilting pads. There are 2 ways to account for this:
1290// 1. use tilting correction for calculating the y
1291// 2. neglect tilting correction here and account for it in the error parametrization of the tracklet.
1292 const Float_t kRatio = 0.8;
1293 const Int_t kClmin = 5;
1294 const Float_t kmaxtan = 2;
1295
1296 if (TMath::Abs(fYref[1]) > kmaxtan){
1297 //printf("Exit: Abs(fYref[1]) = %3.3f, kmaxtan = %3.3f\n", TMath::Abs(fYref[1]), kmaxtan);
1298 return; // Track inclined too much
1299 }
1300
1301 Float_t sigmaexp = 0.05 + TMath::Abs(fYref[1] * 0.25); // Expected r.m.s in y direction
dd8059a8 1302 Float_t ycrosscor = GetPadLength() * GetTilt() * 0.5; // Y correction for crossing
e3cf3d02 1303 Int_t fNChange = 0;
1304
1305 Double_t sumw;
1306 Double_t sumwx;
1307 Double_t sumwx2;
1308 Double_t sumwy;
1309 Double_t sumwxy;
1310 Double_t sumwz;
1311 Double_t sumwxz;
1312
1313 // Buffering: Leave it constant fot Performance issues
1314 Int_t zints[kNtb]; // Histograming of the z coordinate
1315 // Get 1 and second max probable coodinates in z
1316 Int_t zouts[2*kNtb];
1317 Float_t allowedz[kNtb]; // Allowed z for given time bin
1318 Float_t yres[kNtb]; // Residuals from reference
dd8059a8 1319 //Float_t anglecor = GetTilt() * fZref[1]; // Correction to the angle
e3cf3d02 1320
1321 Float_t pos[3*kNtb]; memset(pos, 0, 3*kNtb*sizeof(Float_t));
1322 Float_t *fX = &pos[0], *fY = &pos[kNtb], *fZ = &pos[2*kNtb];
1323
1324 Int_t fN = 0; AliTRDcluster *c = 0x0;
1325 fN2 = 0;
1326 for (Int_t i = 0; i < AliTRDtrackerV1::GetNTimeBins(); i++) {
1327 yres[i] = 10000.0;
1328 if (!(c = fClusters[i])) continue;
1329 if(!c->IsInChamber()) continue;
1330 // Residual y
dd8059a8 1331 //yres[i] = fY[i] - fYref[0] - (fYref[1] + anglecor) * fX[i] + GetTilt()*(fZ[i] - fZref[0]);
e3cf3d02 1332 fX[i] = fX0 - c->GetX();
1333 fY[i] = c->GetY();
1334 fZ[i] = c->GetZ();
dd8059a8 1335 yres[i] = fY[i] - GetTilt()*(fZ[i] - (fZref[0] - fX[i]*fZref[1]));
e3cf3d02 1336 zints[fN] = Int_t(fZ[i]);
1337 fN++;
1338 }
1339
1340 if (fN < kClmin){
1341 //printf("Exit fN < kClmin: fN = %d\n", fN);
1342 return;
1343 }
1344 Int_t nz = AliTRDtrackerV1::Freq(fN, zints, zouts, kFALSE);
1345 Float_t fZProb = zouts[0];
1346 if (nz <= 1) zouts[3] = 0;
1347 if (zouts[1] + zouts[3] < kClmin) {
1348 //printf("Exit zouts[1] = %d, zouts[3] = %d\n",zouts[1],zouts[3]);
1349 return;
1350 }
1351
1352 // Z distance bigger than pad - length
1353 if (TMath::Abs(zouts[0]-zouts[2]) > 12.0) zouts[3] = 0;
1354
1355 Int_t breaktime = -1;
1356 Bool_t mbefore = kFALSE;
1357 Int_t cumul[kNtb][2];
1358 Int_t counts[2] = { 0, 0 };
1359
1360 if (zouts[3] >= 3) {
1361
1362 //
1363 // Find the break time allowing one chage on pad-rows
1364 // with maximal number of accepted clusters
1365 //
1366 fNChange = 1;
1367 for (Int_t i = 0; i < AliTRDtrackerV1::GetNTimeBins(); i++) {
1368 cumul[i][0] = counts[0];
1369 cumul[i][1] = counts[1];
1370 if (TMath::Abs(fZ[i]-zouts[0]) < 2) counts[0]++;
1371 if (TMath::Abs(fZ[i]-zouts[2]) < 2) counts[1]++;
1372 }
1373 Int_t maxcount = 0;
1374 for (Int_t i = 0; i < AliTRDtrackerV1::GetNTimeBins(); i++) {
1375 Int_t after = cumul[AliTRDtrackerV1::GetNTimeBins()][0] - cumul[i][0];
1376 Int_t before = cumul[i][1];
1377 if (after + before > maxcount) {
1378 maxcount = after + before;
1379 breaktime = i;
1380 mbefore = kFALSE;
1381 }
1382 after = cumul[AliTRDtrackerV1::GetNTimeBins()-1][1] - cumul[i][1];
1383 before = cumul[i][0];
1384 if (after + before > maxcount) {
1385 maxcount = after + before;
1386 breaktime = i;
1387 mbefore = kTRUE;
1388 }
1389 }
1390 breaktime -= 1;
1391 }
1392
1393 for (Int_t i = 0; i < AliTRDtrackerV1::GetNTimeBins()+1; i++) {
1394 if (i > breaktime) allowedz[i] = mbefore ? zouts[2] : zouts[0];
1395 if (i <= breaktime) allowedz[i] = (!mbefore) ? zouts[2] : zouts[0];
1396 }
1397
1398 if (((allowedz[0] > allowedz[AliTRDtrackerV1::GetNTimeBins()]) && (fZref[1] < 0)) ||
1399 ((allowedz[0] < allowedz[AliTRDtrackerV1::GetNTimeBins()]) && (fZref[1] > 0))) {
1400 //
1401 // Tracklet z-direction not in correspondance with track z direction
1402 //
1403 fNChange = 0;
1404 for (Int_t i = 0; i < AliTRDtrackerV1::GetNTimeBins()+1; i++) {
1405 allowedz[i] = zouts[0]; // Only longest taken
1406 }
1407 }
1408
1409 if (fNChange > 0) {
1410 //
1411 // Cross pad -row tracklet - take the step change into account
1412 //
1413 for (Int_t i = 0; i < AliTRDtrackerV1::GetNTimeBins()+1; i++) {
1414 if (!fClusters[i]) continue;
1415 if(!fClusters[i]->IsInChamber()) continue;
1416 if (TMath::Abs(fZ[i] - allowedz[i]) > 2) continue;
1417 // Residual y
dd8059a8 1418 //yres[i] = fY[i] - fYref[0] - (fYref[1] + anglecor) * fX[i] + GetTilt()*(fZ[i] - fZref[0]);
1419 yres[i] = fY[i] - GetTilt()*(fZ[i] - (fZref[0] - fX[i]*fZref[1]));
f29f13a6 1420// if (TMath::Abs(fZ[i] - fZProb) > 2) {
dd8059a8 1421// if (fZ[i] > fZProb) yres[i] += GetTilt() * GetPadLength();
1422// if (fZ[i] < fZProb) yres[i] -= GetTilt() * GetPadLength();
f29f13a6 1423 }
e3cf3d02 1424 }
1425 }
1426
1427 Double_t yres2[kNtb];
1428 Double_t mean;
1429 Double_t sigma;
1430 for (Int_t i = 0; i < AliTRDtrackerV1::GetNTimeBins()+1; i++) {
1431 if (!fClusters[i]) continue;
1432 if(!fClusters[i]->IsInChamber()) continue;
1433 if (TMath::Abs(fZ[i] - allowedz[i]) > 2) continue;
1434 yres2[fN2] = yres[i];
1435 fN2++;
1436 }
1437 if (fN2 < kClmin) {
1438 //printf("Exit fN2 < kClmin: fN2 = %d\n", fN2);
1439 fN2 = 0;
1440 return;
1441 }
1442 AliMathBase::EvaluateUni(fN2,yres2,mean,sigma, Int_t(fN2*kRatio-2.));
1443 if (sigma < sigmaexp * 0.8) {
1444 sigma = sigmaexp;
1445 }
1446 //Float_t fSigmaY = sigma;
1447
1448 // Reset sums
1449 sumw = 0;
1450 sumwx = 0;
1451 sumwx2 = 0;
1452 sumwy = 0;
1453 sumwxy = 0;
1454 sumwz = 0;
1455 sumwxz = 0;
1456
1457 fN2 = 0;
1458 Float_t fMeanz = 0;
1459 Float_t fMPads = 0;
1460 fUsable = 0;
1461 for (Int_t i = 0; i < AliTRDtrackerV1::GetNTimeBins()+1; i++) {
1462 if (!fClusters[i]) continue;
1463 if (!fClusters[i]->IsInChamber()) continue;
1464 if (TMath::Abs(fZ[i] - allowedz[i]) > 2){fClusters[i] = 0x0; continue;}
1465 if (TMath::Abs(yres[i] - mean) > 4.0 * sigma){fClusters[i] = 0x0; continue;}
1466 SETBIT(fUsable,i);
1467 fN2++;
1468 fMPads += fClusters[i]->GetNPads();
1469 Float_t weight = 1.0;
1470 if (fClusters[i]->GetNPads() > 4) weight = 0.5;
1471 if (fClusters[i]->GetNPads() > 5) weight = 0.2;
1472
1473
1474 Double_t x = fX[i];
1475 //printf("x = %7.3f dy = %7.3f fit %7.3f\n", x, yres[i], fY[i]-yres[i]);
1476
1477 sumw += weight;
1478 sumwx += x * weight;
1479 sumwx2 += x*x * weight;
1480 sumwy += weight * yres[i];
1481 sumwxy += weight * (yres[i]) * x;
1482 sumwz += weight * fZ[i];
1483 sumwxz += weight * fZ[i] * x;
1484
1485 }
1486
1487 if (fN2 < kClmin){
1488 //printf("Exit fN2 < kClmin(2): fN2 = %d\n",fN2);
1489 fN2 = 0;
1490 return;
1491 }
1492 fMeanz = sumwz / sumw;
1493 Float_t correction = 0;
1494 if (fNChange > 0) {
1495 // Tracklet on boundary
1496 if (fMeanz < fZProb) correction = ycrosscor;
1497 if (fMeanz > fZProb) correction = -ycrosscor;
1498 }
1499
1500 Double_t det = sumw * sumwx2 - sumwx * sumwx;
1501 fYfit[0] = (sumwx2 * sumwy - sumwx * sumwxy) / det;
1502 fYfit[1] = (sumw * sumwxy - sumwx * sumwy) / det;
1503
1504 fS2Y = 0;
1505 for (Int_t i = 0; i < AliTRDtrackerV1::GetNTimeBins()+1; i++) {
1506 if (!TESTBIT(fUsable,i)) continue;
1507 Float_t delta = yres[i] - fYfit[0] - fYfit[1] * fX[i];
1508 fS2Y += delta*delta;
1509 }
1510 fS2Y = TMath::Sqrt(fS2Y / Float_t(fN2-2));
1511 // TEMPORARY UNTIL covariance properly calculated
1512 fS2Y = TMath::Max(fS2Y, Float_t(.1));
1513
1514 fZfit[0] = (sumwx2 * sumwz - sumwx * sumwxz) / det;
1515 fZfit[1] = (sumw * sumwxz - sumwx * sumwz) / det;
1516// fYfitR[0] += fYref[0] + correction;
1517// fYfitR[1] += fYref[1];
1518// fYfit[0] = fYfitR[0];
1519 fYfit[1] = -fYfit[1];
1520
1521 UpdateUsed();
f29f13a6 1522}*/
e3cf3d02 1523
e4f2f73d 1524//___________________________________________________________________
203967fc 1525void AliTRDseedV1::Print(Option_t *o) const
e4f2f73d 1526{
1527 //
1528 // Printing the seedstatus
1529 //
1530
b72f4eaf 1531 AliInfo(Form("Det[%3d] X0[%7.2f] Pad{L[%5.2f] W[%5.2f] Tilt[%+6.2f]}", fDet, fX0, GetPadLength(), GetPadWidth(), GetTilt()));
dd8059a8 1532 AliInfo(Form("N[%2d] Nused[%2d] Nshared[%2d] [%d]", GetN(), GetNUsed(), GetNShared(), fN));
b72f4eaf 1533 AliInfo(Form("FLAGS : RC[%c] Kink[%c] SA[%c]", IsRowCross()?'y':'n', IsKink()?'y':'n', IsStandAlone()?'y':'n'));
dd8059a8 1534
1535 Double_t cov[3], x=GetX();
1536 GetCovAt(x, cov);
1537 AliInfo(" | x[cm] | y[cm] | z[cm] | dydx | dzdx |");
1538 AliInfo(Form("Fit | %7.2f | %7.2f+-%7.2f | %7.2f+-%7.2f| %5.2f | ----- |", x, GetY(), TMath::Sqrt(cov[0]), GetZ(), TMath::Sqrt(cov[2]), fYfit[1]));
16cca13f 1539 AliInfo(Form("Ref | %7.2f | %7.2f+-%7.2f | %7.2f+-%7.2f| %5.2f | %5.2f |", x, fYref[0]-fX*fYref[1], TMath::Sqrt(fRefCov[0]), fZref[0]-fX*fYref[1], TMath::Sqrt(fRefCov[2]), fYref[1], fZref[1]))
203967fc 1540
1541
1542 if(strcmp(o, "a")!=0) return;
1543
4dc4dc2e 1544 AliTRDcluster* const* jc = &fClusters[0];
8d2bec9e 1545 for(int ic=0; ic<kNclusters; ic++, jc++) {
4dc4dc2e 1546 if(!(*jc)) continue;
203967fc 1547 (*jc)->Print(o);
4dc4dc2e 1548 }
e4f2f73d 1549}
47d5d320 1550
203967fc 1551
1552//___________________________________________________________________
1553Bool_t AliTRDseedV1::IsEqual(const TObject *o) const
1554{
1555 // Checks if current instance of the class has the same essential members
1556 // as the given one
1557
1558 if(!o) return kFALSE;
1559 const AliTRDseedV1 *inTracklet = dynamic_cast<const AliTRDseedV1*>(o);
1560 if(!inTracklet) return kFALSE;
1561
1562 for (Int_t i = 0; i < 2; i++){
e3cf3d02 1563 if ( fYref[i] != inTracklet->fYref[i] ) return kFALSE;
1564 if ( fZref[i] != inTracklet->fZref[i] ) return kFALSE;
203967fc 1565 }
1566
e3cf3d02 1567 if ( fS2Y != inTracklet->fS2Y ) return kFALSE;
dd8059a8 1568 if ( GetTilt() != inTracklet->GetTilt() ) return kFALSE;
1569 if ( GetPadLength() != inTracklet->GetPadLength() ) return kFALSE;
203967fc 1570
8d2bec9e 1571 for (Int_t i = 0; i < kNclusters; i++){
e3cf3d02 1572// if ( fX[i] != inTracklet->GetX(i) ) return kFALSE;
1573// if ( fY[i] != inTracklet->GetY(i) ) return kFALSE;
1574// if ( fZ[i] != inTracklet->GetZ(i) ) return kFALSE;
1575 if ( fIndexes[i] != inTracklet->fIndexes[i] ) return kFALSE;
203967fc 1576 }
f29f13a6 1577// if ( fUsable != inTracklet->fUsable ) return kFALSE;
203967fc 1578
1579 for (Int_t i=0; i < 2; i++){
e3cf3d02 1580 if ( fYfit[i] != inTracklet->fYfit[i] ) return kFALSE;
1581 if ( fZfit[i] != inTracklet->fZfit[i] ) return kFALSE;
1582 if ( fLabels[i] != inTracklet->fLabels[i] ) return kFALSE;
203967fc 1583 }
1584
e3cf3d02 1585/* if ( fMeanz != inTracklet->GetMeanz() ) return kFALSE;
1586 if ( fZProb != inTracklet->GetZProb() ) return kFALSE;*/
3e778975 1587 if ( fN != inTracklet->fN ) return kFALSE;
1588 //if ( fNUsed != inTracklet->fNUsed ) return kFALSE;
e3cf3d02 1589 //if ( fFreq != inTracklet->GetFreq() ) return kFALSE;
1590 //if ( fNChange != inTracklet->GetNChange() ) return kFALSE;
203967fc 1591
e3cf3d02 1592 if ( fC != inTracklet->fC ) return kFALSE;
1593 //if ( fCC != inTracklet->GetCC() ) return kFALSE;
1594 if ( fChi2 != inTracklet->fChi2 ) return kFALSE;
203967fc 1595 // if ( fChi2Z != inTracklet->GetChi2Z() ) return kFALSE;
1596
e3cf3d02 1597 if ( fDet != inTracklet->fDet ) return kFALSE;
b25a5e9e 1598 if ( fPt != inTracklet->fPt ) return kFALSE;
e3cf3d02 1599 if ( fdX != inTracklet->fdX ) return kFALSE;
203967fc 1600
8d2bec9e 1601 for (Int_t iCluster = 0; iCluster < kNclusters; iCluster++){
203967fc 1602 AliTRDcluster *curCluster = fClusters[iCluster];
e3cf3d02 1603 AliTRDcluster *inCluster = inTracklet->fClusters[iCluster];
203967fc 1604 if (curCluster && inCluster){
1605 if (! curCluster->IsEqual(inCluster) ) {
1606 curCluster->Print();
1607 inCluster->Print();
1608 return kFALSE;
1609 }
1610 } else {
1611 // if one cluster exists, and corresponding
1612 // in other tracklet doesn't - return kFALSE
1613 if(curCluster || inCluster) return kFALSE;
1614 }
1615 }
1616 return kTRUE;
1617}