]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TRD/AliTRDtrackV1.cxx
Merge branch 'master' of https://git.cern.ch/reps/AliRoot
[u/mrichter/AliRoot.git] / TRD / AliTRDtrackV1.cxx
CommitLineData
93fc2389 1
d9950a5a 2/**************************************************************************
3 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * *
5 * Author: The ALICE Off-line Project. *
6 * Contributors are mentioned in the code where appropriate. *
7 * *
8 * Permission to use, copy, modify and distribute this software and its *
9 * documentation strictly for non-commercial purposes is hereby granted *
10 * without fee, provided that the above copyright notice appears in all *
11 * copies and that both the copyright notice and this permission notice *
12 * appear in the supporting documentation. The authors make no claims *
13 * about the suitability of this software for any purpose. It is *
14 * provided "as is" without express or implied warranty. *
15 **************************************************************************/
16
17/* $Id$ */
18
e2a1c98b 19#include "TVectorT.h"
203967fc 20#include "AliLog.h"
eb38ed55 21#include "AliESDtrack.h"
41880fac 22#include "AliTracker.h"
eb38ed55 23
d9950a5a 24#include "AliTRDtrackV1.h"
25#include "AliTRDcluster.h"
26#include "AliTRDcalibDB.h"
3afdab72 27#include "AliTRDReconstructor.h"
9dcc64cc 28#include "AliTRDPIDResponse.h"
d9950a5a 29#include "AliTRDrecoParam.h"
6951a056 30#include "AliTRDdEdxBaseUtils.h"
31#include "AliTRDdEdxCalibHistArray.h"
32#include "AliTRDdEdxCalibUtils.h"
33#include "AliTRDdEdxReconUtils.h"
d9950a5a 34
d9950a5a 35ClassImp(AliTRDtrackV1)
36
0906e73e 37///////////////////////////////////////////////////////////////////////////////
38// //
39// Represents a reconstructed TRD track //
40// Local TRD Kalman track //
41// //
42// Authors: //
43// Alex Bercuci <A.Bercuci@gsi.de> //
44// Markus Fasel <M.Fasel@gsi.de> //
45// //
46///////////////////////////////////////////////////////////////////////////////
d9950a5a 47
48//_______________________________________________________________
3b57a3f7 49AliTRDtrackV1::AliTRDtrackV1() : AliKalmanTrack()
eb2b4f91 50 ,fStatus(0)
352cef8f 51 ,fESDid(0)
3b57a3f7 52 ,fDE(0.)
e2a1c98b 53 ,fTruncatedMean(0)
d0037ea4 54 ,fNchamberdEdx(0)
55 ,fNclusterdEdx(0)
1f97f376 56 ,fNdEdxSlices(0)
4d6aee34 57 ,fkReconstructor(NULL)
58 ,fBackupTrack(NULL)
59 ,fTrackLow(NULL)
60 ,fTrackHigh(NULL)
0906e73e 61{
d9950a5a 62 //
63 // Default constructor
64 //
6e49cfdb 65 //printf("AliTRDtrackV1::AliTRDtrackV1()\n");
e44586fb 66
3b57a3f7 67 for(int i =0; i<3; i++) fBudget[i] = 0.;
68
69 Float_t pid = 1./AliPID::kSPECIES;
70 for(int is =0; is<AliPID::kSPECIES; is++) fPID[is] = pid;
71
72 for(int ip=0; ip<kNplane; ip++){
17896e82 73 fTrackletIndex[ip] = -1;
4d6aee34 74 fTracklet[ip] = NULL;
3b57a3f7 75 }
1f97f376 76 SetLabel(-123456789); // reset label
d9950a5a 77}
78
79//_______________________________________________________________
3b57a3f7 80AliTRDtrackV1::AliTRDtrackV1(const AliTRDtrackV1 &ref) : AliKalmanTrack(ref)
eb2b4f91 81 ,fStatus(ref.fStatus)
352cef8f 82 ,fESDid(ref.fESDid)
3b57a3f7 83 ,fDE(ref.fDE)
e2a1c98b 84 ,fTruncatedMean(ref.fTruncatedMean)
d0037ea4 85 ,fNchamberdEdx(ref.fNchamberdEdx)
86 ,fNclusterdEdx(ref.fNclusterdEdx)
1f97f376 87 ,fNdEdxSlices(ref.fNdEdxSlices)
4d6aee34 88 ,fkReconstructor(ref.fkReconstructor)
89 ,fBackupTrack(NULL)
90 ,fTrackLow(NULL)
91 ,fTrackHigh(NULL)
d9950a5a 92{
93 //
3b57a3f7 94 // Copy constructor
d9950a5a 95 //
96
6e49cfdb 97 //printf("AliTRDtrackV1::AliTRDtrackV1(const AliTRDtrackV1 &)\n");
29b87567 98 SetBit(kOwner, kFALSE);
3b57a3f7 99 for(int ip=0; ip<kNplane; ip++){
100 fTrackletIndex[ip] = ref.fTrackletIndex[ip];
101 fTracklet[ip] = ref.fTracklet[ip];
102 }
e3cf3d02 103 if(ref.fTrackLow) fTrackLow = new AliExternalTrackParam(*ref.fTrackLow);
104 if(ref.fTrackHigh) fTrackHigh = new AliExternalTrackParam(*ref.fTrackHigh);
105
3b57a3f7 106 for (Int_t i = 0; i < 3;i++) fBudget[i] = ref.fBudget[i];
107
108 for(Int_t is = 0; is<AliPID::kSPECIES; is++) fPID[is] = ref.fPID[is];
109
110 AliKalmanTrack::SetNumberOfClusters(ref.GetNumberOfClusters());
d9950a5a 111}
112
113//_______________________________________________________________
3b57a3f7 114AliTRDtrackV1::AliTRDtrackV1(const AliESDtrack &t) : AliKalmanTrack()
eb2b4f91 115 ,fStatus(0)
352cef8f 116 ,fESDid(0)
3b57a3f7 117 ,fDE(0.)
e2a1c98b 118 ,fTruncatedMean(0)
d0037ea4 119 ,fNchamberdEdx(0)
120 ,fNclusterdEdx(0)
1f97f376 121 ,fNdEdxSlices(0)
4d6aee34 122 ,fkReconstructor(NULL)
123 ,fBackupTrack(NULL)
124 ,fTrackLow(NULL)
125 ,fTrackHigh(NULL)
d9950a5a 126{
127 //
3b57a3f7 128 // Constructor from AliESDtrack
d9950a5a 129 //
130
352cef8f 131 SetESDid(t.GetID());
3b57a3f7 132 SetLabel(t.GetLabel());
133 SetChi2(0.0);
0b433f72 134
35315297 135 SetMass(t.GetMass(kTRUE));
3b57a3f7 136 AliKalmanTrack::SetNumberOfClusters(t.GetTRDncls());
17896e82 137 Int_t ti[]={-1, -1, -1, -1, -1, -1}; t.GetTRDtracklets(&ti[0]);
3b57a3f7 138 for(int ip=0; ip<kNplane; ip++){
17896e82 139 fTrackletIndex[ip] = ti[ip];
4d6aee34 140 fTracklet[ip] = NULL;
3b57a3f7 141 }
142 for(int i =0; i<3; i++) fBudget[i] = 0.;
143
144 Float_t pid = 1./AliPID::kSPECIES;
145 for(int is =0; is<AliPID::kSPECIES; is++) fPID[is] = pid;
146
147 const AliExternalTrackParam *par = &t;
88987d18 148 if (t.GetStatus() & AliESDtrack::kTRDbackup) {
3b57a3f7 149 par = t.GetOuterParam();
150 if (!par) {
151 AliError("No backup info!");
152 par = &t;
153 }
88987d18 154 }
3b57a3f7 155 Set(par->GetX()
156 ,par->GetAlpha()
157 ,par->GetParameter()
158 ,par->GetCovariance());
159
160 if(t.GetStatus() & AliESDtrack::kTIME) {
161 StartTimeIntegral();
162 Double_t times[10];
163 t.GetIntegratedTimes(times);
164 SetIntegratedTimes(times);
165 SetIntegratedLength(t.GetIntegratedLength());
166 }
d9950a5a 167}
168
d9950a5a 169//_______________________________________________________________
e17f4785 170AliTRDtrackV1::AliTRDtrackV1(AliTRDseedV1 * const trklts, const Double_t p[5], const Double_t cov[15]
3b57a3f7 171 , Double_t x, Double_t alpha) : AliKalmanTrack()
eb2b4f91 172 ,fStatus(0)
352cef8f 173 ,fESDid(0)
3b57a3f7 174 ,fDE(0.)
e2a1c98b 175 ,fTruncatedMean(0)
d0037ea4 176 ,fNchamberdEdx(0)
177 ,fNclusterdEdx(0)
1f97f376 178 ,fNdEdxSlices(0)
4d6aee34 179 ,fkReconstructor(NULL)
180 ,fBackupTrack(NULL)
181 ,fTrackLow(NULL)
182 ,fTrackHigh(NULL)
d9950a5a 183{
0906e73e 184 //
185 // The stand alone tracking constructor
186 // TEMPORARY !!!!!!!!!!!
187 // to check :
188 // 1. covariance matrix
189 // 2. dQdl calculation
190 //
d9950a5a 191
68f9b6bd 192 Double_t b(GetBz());
193 Double_t cnv = (TMath::Abs(b) < 1.e-5) ? 1.e5 : 1./GetBz()/kB2C;
194
d9950a5a 195 Double_t pp[5] = { p[0]
68f9b6bd 196 , p[1]
197 , p[2]
198 , p[3]
199 , p[4]*cnv };
200
d9950a5a 201 Double_t c22 = x*x*cov[14] - 2*x*cov[12] + cov[ 5];
202 Double_t c32 = x*cov[13] - cov[ 8];
203 Double_t c20 = x*cov[10] - cov[ 3];
204 Double_t c21 = x*cov[11] - cov[ 4];
205 Double_t c42 = x*cov[14] - cov[12];
68f9b6bd 206
d9950a5a 207 Double_t cc[15] = { cov[ 0]
208 , cov[ 1], cov[ 2]
209 , c20, c21, c22
210 , cov[ 6], cov[ 7], c32, cov[ 9]
211 , cov[10]*cnv, cov[11]*cnv, c42*cnv, cov[13]*cnv, cov[14]*cnv*cnv };
68f9b6bd 212
ae3fbe1f 213 Double_t mostProbablePt=AliExternalTrackParam::GetMostProbablePt();
214 Double_t p0=TMath::Sign(1/mostProbablePt,pp[4]);
215 Double_t w0=cc[14]/(cc[14] + p0*p0), w1=p0*p0/(cc[14] + p0*p0);
68f9b6bd 216 AliDebug(3, Form("Pt mixing : w0[%4.2f] pt0[%5.3f] w1[%4.2f] pt[%5.3f]", w0, 1./p0, w1, 1./pp[4]));
217
ae3fbe1f 218 pp[4] = w0*p0 + w1*pp[4];
219 cc[10]*=w1; cc[11]*=w1; cc[12]*=w1; cc[13]*=w1; cc[14]*=w1;
68f9b6bd 220 Set(x,alpha,pp,cc);
0217fcd0 221 AliDebug(2, Form("Init @ x[%6.2f] pt[%5.3f]", x, 1./pp[4]));
41702fec 222 Int_t ncls = 0;
68f9b6bd 223 for(int iplane=0; iplane<kNplane; iplane++){
17896e82 224 fTrackletIndex[iplane] = -1;
68f9b6bd 225 if(!trklts[iplane].IsOK()) fTracklet[iplane] = NULL;
41702fec 226 else{
e17f4785 227 fTracklet[iplane] = &trklts[iplane];
41702fec 228 ncls += fTracklet[iplane]->GetN();
229 }
68f9b6bd 230 }
41702fec 231 AliKalmanTrack::SetNumberOfClusters(ncls);
232 for(int i =0; i<3; i++) fBudget[i] = 0.;
233
234 Float_t pid = 1./AliPID::kSPECIES;
235 for(int is =0; is<AliPID::kSPECIES; is++) fPID[is] = pid;
1f97f376 236 SetLabel(-123456789); // reset label
d9950a5a 237}
238
bb56afff 239//_______________________________________________________________
3b57a3f7 240AliTRDtrackV1::~AliTRDtrackV1()
bb56afff 241{
4d8f1bd9 242 // Clean up all objects allocated by the track during its lifetime.
243 AliDebug(2, Form("Deleting track[%d]\n fBackupTrack[%p] fTrackLow[%p] fTrackHigh[%p] Owner[%c].", fESDid, (void*)fBackupTrack, (void*)fTrackLow, (void*)fTrackHigh, TestBit(kOwner)?'y':'n'));
76b60503 244
4d6aee34 245 if(fBackupTrack) delete fBackupTrack; fBackupTrack = NULL;
e3cf3d02 246
4d6aee34 247 if(fTrackLow) delete fTrackLow; fTrackLow = NULL;
248 if(fTrackHigh) delete fTrackHigh; fTrackHigh = NULL;
bb56afff 249
76b60503 250 for(Int_t ip=0; ip<kNplane; ip++){
251 if(TestBit(kOwner) && fTracklet[ip]) delete fTracklet[ip];
4d6aee34 252 fTracklet[ip] = NULL;
17896e82 253 fTrackletIndex[ip] = -1;
3b57a3f7 254 }
255}
256
e08a5492 257//_______________________________________________________________
258AliTRDtrackV1 &AliTRDtrackV1::operator=(const AliTRDtrackV1 &t)
259{
260 //
261 // Assignment operator
262 //
263
264 if (this != &t) {
5c5d503a 265 AliKalmanTrack::operator=(t);
e08a5492 266 ((AliTRDtrackV1 &) t).Copy(*this);
267 }
268
269 return *this;
270
271}
272
273//_____________________________________________________________________________
274void AliTRDtrackV1::Copy(TObject &t) const
275{
276 //
277 // Copy function
278 //
279
280 ((AliTRDtrackV1 &) t).fStatus = fStatus;
281 ((AliTRDtrackV1 &) t).fESDid = fESDid;
282 ((AliTRDtrackV1 &) t).fDE = fDE;
283 ((AliTRDtrackV1 &) t).fkReconstructor = fkReconstructor;
284 ((AliTRDtrackV1 &) t).fBackupTrack = 0x0;
285 ((AliTRDtrackV1 &) t).fTrackLow = 0x0;
286 ((AliTRDtrackV1 &) t).fTrackHigh = 0x0;
287
288 for(Int_t ip = 0; ip < kNplane; ip++) {
289 ((AliTRDtrackV1 &) t).fTrackletIndex[ip] = fTrackletIndex[ip];
290 ((AliTRDtrackV1 &) t).fTracklet[ip] = fTracklet[ip];
291 }
292 if (fTrackLow) {
293 ((AliTRDtrackV1 &) t).fTrackLow = new AliExternalTrackParam(*fTrackLow);
294 }
295 if (fTrackHigh){
296 ((AliTRDtrackV1 &) t).fTrackHigh = new AliExternalTrackParam(*fTrackHigh);
297 }
298
299 for (Int_t i = 0; i < 3; i++) {
300 ((AliTRDtrackV1 &) t).fBudget[i] = fBudget[i];
301 }
302 for (Int_t is = 0; is < AliPID::kSPECIES; is++) {
303 ((AliTRDtrackV1 &) t).fPID[is] = fPID[is];
304 }
305
306}
307
3b57a3f7 308//_______________________________________________________________
e73baf29 309Int_t AliTRDtrackV1::CookLabel(Float_t wrong, Int_t *labs, Float_t *freq)
3b57a3f7 310{
e73baf29 311// Set MC label for this track
312// On demand i.e. if arrays "labs" and "freq" are allocated by user returns :
313// nlabs = the no of distinct labels
314// labs = array of distinct labels in decreasing order of frequency
315// freq = frequency of each label in decreasing order
bb2db46c 316
e73baf29 317 Int_t ncl(0);
318 if(!(ncl = GetNumberOfClusters())) return 0;
319
320 Int_t s[2][kMAXCLUSTERSPERTRACK];
bb56afff 321 for (Int_t i = 0; i < kMAXCLUSTERSPERTRACK; i++) {
e73baf29 322 s[0][i] = -1;
323 s[1][i] = 0;
bb56afff 324 }
e73baf29 325
326 Int_t label(-123456789), nlabels(0);
327 AliTRDcluster *c(NULL);
328 for (Int_t ip(0); ip < AliTRDgeometry::kNlayer; ip++) {
68f9b6bd 329 if(fTrackletIndex[ip]<0 || !fTracklet[ip]) continue;
e73baf29 330 for (Int_t ic(0); ic < AliTRDseedV1::kNclusters; ic++) {
3b57a3f7 331 if(!(c = fTracklet[ip]->GetClusters(ic))) continue;
e73baf29 332 for (Int_t k(0); k < 3; k++) {
333 if ((label = c->GetLabel(k)) < 0) continue;
334 Int_t j(0);
335 while(j < kMAXCLUSTERSPERTRACK){
336 if(s[0][j]!=label && s[1][j]!=0){j++; continue;}
337 if(!s[1][j]) nlabels++;
338 s[0][j] = label; s[1][j]++;
339 break;
3b57a3f7 340 }
341 }
342 }
343 }
e73baf29 344 //printf(" Found %4d labels\n", nlabels);
345 Float_t prob(1.);
346 if(!nlabels){
347 AliError(Form("No MC labels found for track %d.", fESDid));
348 return 0;
349 } else if(nlabels==1) {
350 label = s[0][0];
351 if(labs && freq){labs[0]=label; freq[0]=1.;}
352 } else {
353 Int_t idx[kMAXCLUSTERSPERTRACK];
354 TMath::Sort(nlabels, s[1], idx);
355 label = s[0][idx[0]]; prob = s[1][idx[0]]/Float_t(ncl);
356 if(labs && freq){
357 for (Int_t i(0); i<nlabels; i++){
358 labs[i] = s[0][idx[i]];
359 freq[i] = s[1][idx[i]]/Float_t(ncl);
360 }
361 }
bb56afff 362 }
e73baf29 363 SetLabel((1.-prob > wrong)?-label:label);
364 return nlabels;
bb56afff 365}
366
d9950a5a 367//_______________________________________________________________
368Bool_t AliTRDtrackV1::CookPID()
369{
2a3191bb 370//
371// Cook the PID information for the track by delegating the omonim function of the tracklets.
372// Computes the number of tracklets used. The tracklet information are considered independent.
373// For the moment no global track measurement of PID is performed as for example to estimate
374// bremsstrahlung probability based on global chi2 of the track.
375//
376// The status bit AliESDtrack::kTRDpid is set during the call of AliTRDtrackV1::UpdateESDtrack().The PID performance of the
377//TRD for tracks with 6 tacklets is displayed below.
378//Begin_Html
379//<img src="TRD/trackPID.gif">
380//End_Html
381//
9dcc64cc 382 const AliTRDPIDResponse *pidResponse = AliTRDcalibDB::Instance()->GetPIDResponse(fkReconstructor->GetRecoParam()->GetPIDmethod());
383 if(!pidResponse){
384 AliError("PID Response not available");
eb2b4f91 385 return kFALSE;
3b57a3f7 386 }
1f97f376 387 Double_t dEdx[kNplane * (Int_t)AliTRDseedV1::kNdEdxSlices] = {0.};
388 Float_t trackletP[kNplane] = {0.};
389
390 fNdEdxSlices = pidResponse->GetNumberOfSlices();
9dcc64cc 391 for(Int_t iseed = 0; iseed < kNplane; iseed++){
392 if(!fTracklet[iseed]) continue;
393 trackletP[iseed] = fTracklet[iseed]->GetMomentum();
1f97f376 394// if(pidResponse->GetPIDmethod() == AliTRDPIDResponse::kLQ1D){
9dcc64cc 395 dEdx[iseed] = fTracklet[iseed]->GetdQdl();
1f97f376 396/* } else {
397 fTracklet[iseed]->CookdEdx(fNdEdxSlices);
9dcc64cc 398 const Float_t *trackletdEdx = fTracklet[iseed]->GetdEdx();
1f97f376 399 for(Int_t islice = 0; islice < fNdEdxSlices; islice++){
400 dEdx[iseed*fNdEdxSlices + islice] = trackletdEdx[islice];
9dcc64cc 401 }
1f97f376 402 }*/
9dcc64cc 403 }
1f97f376 404 pidResponse->GetResponse(fNdEdxSlices, dEdx, trackletP, fPID);
e2a1c98b 405
9a8b0e85 406 static Int_t nprint = 0;
407 if(!nprint){
6951a056 408 AliTRDdEdxBaseUtils::PrintControl();
9a8b0e85 409 nprint++;
410 }
411
e2a1c98b 412 //do truncated mean
6951a056 413 AliTRDdEdxCalibUtils::SetObjArray(AliTRDcalibDB::Instance()->GetPHQ());
414 const Double_t mag = AliTRDdEdxBaseUtils::IsExBOn() ? GetBz() : -1;
415 const Double_t charge = AliTRDdEdxBaseUtils::IsExBOn() ? Charge() : -1;
d0037ea4 416 fTruncatedMean = CookTruncatedMean(0, mag, charge, kTRUE, fNchamberdEdx, fNclusterdEdx);
e2a1c98b 417
eb2b4f91 418 return kTRUE;
419}
420
421//___________________________________________________________
422UChar_t AliTRDtrackV1::GetNumberOfTrackletsPID() const
423{
424// Retrieve number of tracklets used for PID calculation.
425
e20bef2b 426 UChar_t nPID = 0;
3b57a3f7 427 for(int ip=0; ip<kNplane; ip++){
68f9b6bd 428 if(fTrackletIndex[ip]<0 || !fTracklet[ip]) continue;
3b57a3f7 429 if(!fTracklet[ip]->IsOK()) continue;
3b57a3f7 430
e20bef2b 431 nPID++;
0906e73e 432 }
e20bef2b 433 return nPID;
eb2b4f91 434}
435
0349cc67 436//_______________________________________________________________
437AliTRDcluster* AliTRDtrackV1::GetCluster(Int_t id)
438{
4d6aee34 439 // Get the cluster at a certain position in the track
0349cc67 440 Int_t n = 0;
441 for(Int_t ip=0; ip<kNplane; ip++){
442 if(!fTracklet[ip]) continue;
443 if(n+fTracklet[ip]->GetN() <= id){
444 n+=fTracklet[ip]->GetN();
445 continue;
446 }
4d6aee34 447 AliTRDcluster *c = NULL;
8d2bec9e 448 for(Int_t ic=AliTRDseedV1::kNclusters; ic--;){
0349cc67 449 if(!(c = fTracklet[ip]->GetClusters(ic))) continue;
450
451 if(n<id){n++; continue;}
452 return c;
453 }
454 }
4d6aee34 455 return NULL;
0349cc67 456}
457
3b57a3f7 458//_______________________________________________________________
459Int_t AliTRDtrackV1::GetClusterIndex(Int_t id) const
460{
4d6aee34 461 // Get the cluster index at a certain position in the track
3b57a3f7 462 Int_t n = 0;
463 for(Int_t ip=0; ip<kNplane; ip++){
464 if(!fTracklet[ip]) continue;
76b60503 465 if(n+fTracklet[ip]->GetN() <= id){
3b57a3f7 466 n+=fTracklet[ip]->GetN();
467 continue;
468 }
8d2bec9e 469 for(Int_t ic=AliTRDseedV1::kNclusters; ic--;){
87f70a90 470 if(!(fTracklet[ip]->GetClusters(ic))) continue;
76b60503 471 if(n<id){n++; continue;}
3b57a3f7 472 return fTracklet[ip]->GetIndexes(ic);
473 }
474 }
475 return -1;
0906e73e 476}
d9950a5a 477
478//_______________________________________________________________
b72f4eaf 479Double_t AliTRDtrackV1::GetPredictedChi2(const AliTRDseedV1 *trklt, Double_t *cov) const
d9950a5a 480{
ed15ef4f 481// Compute chi2 between tracklet and track. The value is calculated at the radial position of the track
482// equal to the reference radial position of the tracklet (see AliTRDseedV1)
483//
484// The chi2 estimator is computed according to the following formula
485// BEGIN_LATEX
486// #chi^{2}=(X_{trklt}-X_{track})(C_{trklt}+C_{track})^{-1}(X_{trklt}-X_{track})^{T}
487// END_LATEX
488// where X=(y z), the position of the track/tracklet in the yz plane
489//
490
b72f4eaf 491 Double_t p[2] = { trklt->GetY(), trklt->GetZ()};
492 trklt->GetCovAt(trklt->GetX(), cov);
ed15ef4f 493 return AliExternalTrackParam::GetPredictedChi2(p, cov);
3b57a3f7 494}
d9950a5a 495
eb2b4f91 496//_______________________________________________________________
497Int_t AliTRDtrackV1::GetSector() const
498{
499 return Int_t(GetAlpha()/AliTRDgeometry::GetAlpha() + (GetAlpha()>0. ? 0 : AliTRDgeometry::kNsector));
500}
501
203967fc 502//_______________________________________________________________
503Bool_t AliTRDtrackV1::IsEqual(const TObject *o) const
504{
4d6aee34 505 // Checks whether two tracks are equal
203967fc 506 if (!o) return kFALSE;
507 const AliTRDtrackV1 *inTrack = dynamic_cast<const AliTRDtrackV1*>(o);
508 if (!inTrack) return kFALSE;
509
eb2b4f91 510 //if ( fPIDquality != inTrack->GetPIDquality() ) return kFALSE;
203967fc 511
d8069611 512 if(memcmp(fPID, inTrack->fPID, AliPID::kSPECIES*sizeof(Double32_t))) return kFALSE;
513 if(memcmp(fBudget, inTrack->fBudget, 3*sizeof(Double32_t))) return kFALSE;
514 if(memcmp(&fDE, &inTrack->fDE, sizeof(Double32_t))) return kFALSE;
515 if(memcmp(&fFakeRatio, &inTrack->fFakeRatio, sizeof(Double32_t))) return kFALSE;
516 if(memcmp(&fChi2, &inTrack->fChi2, sizeof(Double32_t))) return kFALSE;
517 if(memcmp(&fMass, &inTrack->fMass, sizeof(Double32_t))) return kFALSE;
518 if( fLab != inTrack->fLab ) return kFALSE;
519 if( fN != inTrack->fN ) return kFALSE;
520 Double32_t l(0.), in(0.);
521 l = GetIntegratedLength(); in = inTrack->GetIntegratedLength();
522 if(memcmp(&l, &in, sizeof(Double32_t))) return kFALSE;
523 l=GetX(); in=inTrack->GetX();
524 if(memcmp(&l, &in, sizeof(Double32_t))) return kFALSE;
525 l = GetAlpha(); in = inTrack->GetAlpha();
526 if(memcmp(&l, &in, sizeof(Double32_t))) return kFALSE;
527 if(memcmp(GetParameter(), inTrack->GetParameter(), 5*sizeof(Double32_t))) return kFALSE;
528 if(memcmp(GetCovariance(), inTrack->GetCovariance(), 15*sizeof(Double32_t))) return kFALSE;
203967fc 529
530 for (Int_t iTracklet = 0; iTracklet < kNplane; iTracklet++){
531 AliTRDseedV1 *curTracklet = fTracklet[iTracklet];
532 AliTRDseedV1 *inTracklet = inTrack->GetTracklet(iTracklet);
533 if (curTracklet && inTracklet){
534 if (! curTracklet->IsEqual(inTracklet) ) {
535 curTracklet->Print();
536 inTracklet->Print();
537 return kFALSE;
538 }
539 } else {
540 // if one tracklet exists, and corresponding
541 // in other track doesn't - return kFALSE
542 if(inTracklet || curTracklet) return kFALSE;
543 }
544 }
545
546 return kTRUE;
547}
548
22a4ab0c 549//_______________________________________________________________
550Bool_t AliTRDtrackV1::IsElectron() const
551{
4d6aee34 552 if(GetPID(0) > fkReconstructor->GetRecoParam()->GetPIDThreshold(GetP())) return kTRUE;
22a4ab0c 553 return kFALSE;
554}
555
3b57a3f7 556
557//_____________________________________________________________________________
b453ef55 558Int_t AliTRDtrackV1::MakeBackupTrack()
3b57a3f7 559{
b453ef55 560//
561// Creates a backup track
562// TO DO update quality check of the track.
563//
564
565 Float_t occupancy(0.); Int_t n(0), ncls(0);
566 for(Int_t il(AliTRDgeometry::kNlayer); il--;){
567 if(!fTracklet[il]) continue;
568 n++;
5c5d503a 569 occupancy+=fTracklet[il]->GetTBoccupancy()/AliTRDseedV1::kNtb;
b453ef55 570 ncls += fTracklet[il]->GetN();
571 }
572 if(!n) return -1;
573 occupancy/=n;
574
575 //Float_t ratio1 = Float_t(t.GetNumberOfClusters()+1) / Float_t(t.GetNExpected()+1);
576
577 Int_t failedCutId(0);
578 if(GetChi2()/n > 5.0) failedCutId=1;
579 if(occupancy < 0.7) failedCutId=2;
580 //if(ratio1 > 0.6) &&
581 //if(ratio0+ratio1 > 1.5) &&
582 if(GetNCross() != 0) failedCutId=3;
583 if(TMath::Abs(GetSnp()) > 0.85) failedCutId=4;
584 if(ncls < 20) failedCutId=5;
585
586 if(failedCutId){
587 AliDebug(2, Form("\n"
588 "chi2/tracklet < 5.0 [%c] %5.2f\n"
589 "occupancy > 0.7 [%c] %4.2f\n"
590 "NCross == 0 [%c] %d\n"
591 "Abs(snp) < 0.85 [%c] %4.2f\n"
592 "NClusters > 20 [%c] %d"
593 ,(GetChi2()/n<5.0)?'y':'n', GetChi2()/n
594 ,(occupancy>0.7)?'y':'n', occupancy
595 ,(GetNCross()==0)?'y':'n', GetNCross()
596 ,(TMath::Abs(GetSnp())<0.85)?'y':'n', TMath::Abs(GetSnp())
597 ,(ncls>20)?'y':'n', ncls
598 ));
599 return failedCutId;
600 }
3b57a3f7 601
602 if(fBackupTrack) {
603 fBackupTrack->~AliTRDtrackV1();
604 new(fBackupTrack) AliTRDtrackV1((AliTRDtrackV1&)(*this));
b453ef55 605 return 0;
3b57a3f7 606 }
607 fBackupTrack = new AliTRDtrackV1((AliTRDtrackV1&)(*this));
b453ef55 608 return 0;
d9950a5a 609}
610
3b57a3f7 611//_____________________________________________________________________________
f8a9723f 612Int_t AliTRDtrackV1::GetProlongation(Double_t xk, Double_t &y, Double_t &z) const
3b57a3f7 613{
614 //
615 // Find a prolongation at given x
530fb4e2 616 // Return -1 if it does not exist
3b57a3f7 617 //
618
619 Double_t bz = GetBz();
530fb4e2 620 if (!AliExternalTrackParam::GetYAt(xk,bz,y)) return -1;
621 if (!AliExternalTrackParam::GetZAt(xk,bz,z)) return -1;
3b57a3f7 622
623 return 1;
624
625}
626
627//_____________________________________________________________________________
15a2657d 628Bool_t AliTRDtrackV1::PropagateTo(Double_t xk, Double_t xx0, Double_t xrho)
0906e73e 629{
630 //
3b57a3f7 631 // Propagates this track to a reference plane defined by "xk" [cm]
632 // correcting for the mean crossed material.
0906e73e 633 //
3b57a3f7 634 // "xx0" - thickness/rad.length [units of the radiation length]
635 // "xrho" - thickness*density [g/cm^2]
636 //
0906e73e 637
952051c5 638 if (TMath::Abs(xk - GetX())<AliTRDReconstructor::GetEpsilon()*0.1) return kTRUE; // 10% of the tracker precision
dc5e390a 639
307aac71 640 Double_t xyz0[3] = {GetX(), GetY(), GetZ()}, // track position BEFORE propagation
dc5e390a 641 b[3]; // magnetic field
307aac71 642 GetBxByBz(b);
dc5e390a 643 if(!AliExternalTrackParam::PropagateToBxByBz(xk,b)) return kFALSE;
644
307aac71 645 // local track position AFTER propagation
646 Double_t xyz1[3] = {GetX(), GetY(), GetZ()};
2f4384e6 647// printf("x0[%6.2f] -> x1[%6.2f] dx[%6.2f] rho[%f]\n", xyz0[0], xyz1[0], xyz0[0]-xk, xrho/TMath::Abs(xyz0[0]-xk));
dc5e390a 648 if(xyz0[0] < xk) {
5c5d503a 649 xrho = -xrho;
3b57a3f7 650 if (IsStartedTimeIntegral()) {
dc5e390a 651 Double_t l2 = TMath::Sqrt((xyz1[0]-xyz0[0])*(xyz1[0]-xyz0[0])
652 + (xyz1[1]-xyz0[1])*(xyz1[1]-xyz0[1])
653 + (xyz1[2]-xyz0[2])*(xyz1[2]-xyz0[2]));
6790f7d7 654 Double_t crv = AliExternalTrackParam::GetC(b[2]);
3b57a3f7 655 if (TMath::Abs(l2*crv) > 0.0001) {
656 // Make correction for curvature if neccesary
dc5e390a 657 l2 = 0.5 * TMath::Sqrt((xyz1[0]-xyz0[0])*(xyz1[0]-xyz0[0])
658 + (xyz1[1]-xyz0[1])*(xyz1[1]-xyz0[1]));
3b57a3f7 659 l2 = 2.0 * TMath::ASin(l2 * crv) / crv;
dc5e390a 660 l2 = TMath::Sqrt(l2*l2 + (xyz1[2]-xyz0[2])*(xyz1[2]-xyz0[2]));
3b57a3f7 661 }
662 AddTimeStep(l2);
663 }
664 }
35315297 665 if (!AliExternalTrackParam::CorrectForMeanMaterial(xx0, xrho, fMass)) return kFALSE;
fd40f855 666
3b57a3f7 667
668 {
669
670 // Energy losses
671 Double_t p2 = (1.0 + GetTgl()*GetTgl()) / (GetSigned1Pt()*GetSigned1Pt());
35315297 672 Double_t beta2 = p2 / (p2 + fMass*fMass);
3b57a3f7 673 if ((beta2 < 1.0e-10) ||
674 ((5940.0 * beta2/(1.0 - beta2 + 1.0e-10) - beta2) < 0.0)) {
675 return kFALSE;
676 }
677
678 Double_t dE = 0.153e-3 / beta2
679 * (TMath::Log(5940.0 * beta2/(1.0 - beta2 + 1.0e-10)) - beta2)
680 * xrho;
681 fBudget[0] += xrho;
682
683 /*
684 // Suspicious part - think about it ?
685 Double_t kinE = TMath::Sqrt(p2);
686 if (dE > 0.8*kinE) dE = 0.8 * kinE; //
687 if (dE < 0) dE = 0.0; // Not valid region for Bethe bloch
688 */
689
690 fDE += dE;
691
692 /*
693 // Suspicious ! I.B.
694 Double_t sigmade = 0.07 * TMath::Sqrt(TMath::Abs(dE)); // Energy loss fluctuation
35315297 695 Double_t sigmac2 = sigmade*sigmade*fC*fC*(p2+fMass*fMass)/(p2*p2);
3b57a3f7 696 fCcc += sigmac2;
697 fCee += fX*fX * sigmac2;
698 */
699
700 }
701
702 return kTRUE;
0906e73e 703}
3b57a3f7 704
87a7fa94 705//_____________________________________________________________________________
3b57a3f7 706Int_t AliTRDtrackV1::PropagateToR(Double_t r,Double_t step)
87a7fa94 707{
708 //
3b57a3f7 709 // Propagate track to the radial position
710 // Rotation always connected to the last track position
87a7fa94 711 //
712
3b57a3f7 713 Double_t xyz0[3];
714 Double_t xyz1[3];
715 Double_t y;
716 Double_t z;
717
718 Double_t radius = TMath::Sqrt(GetX()*GetX() + GetY()*GetY());
719 // Direction +-
720 Double_t dir = (radius > r) ? -1.0 : 1.0;
721
722 for (Double_t x = radius+dir*step; dir*x < dir*r; x += dir*step) {
723
724 GetXYZ(xyz0);
725 Double_t alpha = TMath::ATan2(xyz0[1],xyz0[0]);
726 Rotate(alpha,kTRUE);
727 GetXYZ(xyz0);
e20bef2b 728 if(GetProlongation(x,y,z)<0) return -1;
3b57a3f7 729 xyz1[0] = x * TMath::Cos(alpha) + y * TMath::Sin(alpha);
730 xyz1[1] = x * TMath::Sin(alpha) - y * TMath::Cos(alpha);
731 xyz1[2] = z;
732 Double_t param[7];
83dea92e 733 if(AliTracker::MeanMaterialBudget(xyz0,xyz1,param)<=0.) return -1;
3b57a3f7 734 if (param[1] <= 0) {
735 param[1] = 100000000;
736 }
737 PropagateTo(x,param[1],param[0]*param[4]);
738
739 }
740
741 GetXYZ(xyz0);
742 Double_t alpha = TMath::ATan2(xyz0[1],xyz0[0]);
743 Rotate(alpha,kTRUE);
744 GetXYZ(xyz0);
530fb4e2 745 if(GetProlongation(r,y,z)<0) return -1;
3b57a3f7 746 xyz1[0] = r * TMath::Cos(alpha) + y * TMath::Sin(alpha);
747 xyz1[1] = r * TMath::Sin(alpha) - y * TMath::Cos(alpha);
748 xyz1[2] = z;
749 Double_t param[7];
83dea92e 750 if(AliTracker::MeanMaterialBudget(xyz0,xyz1,param) <= 0.) return -1;
3b57a3f7 751
752 if (param[1] <= 0) {
753 param[1] = 100000000;
87a7fa94 754 }
3b57a3f7 755 PropagateTo(r,param[1],param[0]*param[4]);
756
757 return 0;
758
87a7fa94 759}
760
203967fc 761//_____________________________________________________________________________
762void AliTRDtrackV1::Print(Option_t *o) const
763{
4d6aee34 764 // Print track status
eb2b4f91 765 AliInfo(Form("PID [%4.1f %4.1f %4.1f %4.1f %4.1f]", 1.E2*fPID[0], 1.E2*fPID[1], 1.E2*fPID[2], 1.E2*fPID[3], 1.E2*fPID[4]));
203967fc 766 AliInfo(Form("Material[%5.2f %5.2f %5.2f]", fBudget[0], fBudget[1], fBudget[2]));
767
768 AliInfo(Form("x[%7.2f] t[%7.4f] alpha[%f] mass[%f]", GetX(), GetIntegratedLength(), GetAlpha(), fMass));
eb2b4f91 769 AliInfo(Form("Ntr[%1d] NtrPID[%1d] Ncl[%3d] lab[%3d]", GetNumberOfTracklets(), GetNumberOfTrackletsPID(), fN, fLab));
203967fc 770
203967fc 771 printf("|X| = (");
772 const Double_t *curP = GetParameter();
773 for (Int_t i = 0; i < 5; i++) printf("%7.2f ", curP[i]);
774 printf(")\n");
775
776 printf("|V| = \n");
777 const Double_t *curC = GetCovariance();
778 for (Int_t i = 0, j=4, k=0; i<15; i++, k++){
779 printf("%7.2f ", curC[i]);
780 if(k==j){
781 printf("\n");
782 k=-1; j--;
783 }
784 }
0217fcd0 785 if(strcmp(o, "a")!=0) return;
203967fc 786
787 for(Int_t ip=0; ip<kNplane; ip++){
788 if(!fTracklet[ip]) continue;
789 fTracklet[ip]->Print(o);
790 }
791}
792
793
3b57a3f7 794//_____________________________________________________________________________
795Bool_t AliTRDtrackV1::Rotate(Double_t alpha, Bool_t absolute)
796{
797 //
798 // Rotates track parameters in R*phi plane
799 // if absolute rotation alpha is in global system
800 // otherwise alpha rotation is relative to the current rotation angle
801 //
802
803 if (absolute) alpha -= GetAlpha();
804 //else fNRotate++;
805
806 return AliExternalTrackParam::Rotate(GetAlpha()+alpha);
807}
87a7fa94 808
eb38ed55 809//___________________________________________________________
810void AliTRDtrackV1::SetNumberOfClusters()
811{
812// Calculate the number of clusters attached to this track
813
3b57a3f7 814 Int_t ncls = 0;
815 for(int ip=0; ip<kNplane; ip++){
68f9b6bd 816 if(fTracklet[ip] && fTrackletIndex[ip] >= 0) ncls += fTracklet[ip]->GetN();
3b57a3f7 817 }
818 AliKalmanTrack::SetNumberOfClusters(ncls);
eb38ed55 819}
820
821
0906e73e 822//_______________________________________________________________
3b57a3f7 823void AliTRDtrackV1::SetOwner()
0906e73e 824{
825 //
826 // Toggle ownership of tracklets
827 //
828
e44586fb 829 if(TestBit(kOwner)) return;
3b57a3f7 830 for (Int_t ip = 0; ip < kNplane; ip++) {
68f9b6bd 831 if(fTrackletIndex[ip]<0 || !fTracklet[ip]) continue;
3b57a3f7 832 fTracklet[ip] = new AliTRDseedV1(*fTracklet[ip]);
833 fTracklet[ip]->SetOwner();
834 }
e44586fb 835 SetBit(kOwner);
0906e73e 836}
837
d9950a5a 838//_______________________________________________________________
4d6aee34 839void AliTRDtrackV1::SetTracklet(AliTRDseedV1 *const trklt, Int_t index)
d9950a5a 840{
841 //
0906e73e 842 // Set the tracklets
d9950a5a 843 //
3b57a3f7 844 Int_t plane = trklt->GetPlane();
76b60503 845
3b57a3f7 846 fTracklet[plane] = trklt;
847 fTrackletIndex[plane] = index;
d9950a5a 848}
849
e3cf3d02 850//_______________________________________________________________
a310e49b 851void AliTRDtrackV1::SetTrackIn()
e3cf3d02 852{
fc6d4c2d 853// Save location of birth for the TRD track
854// If the pointer is not valid allocate memory
855//
e3cf3d02 856 const AliExternalTrackParam *op = dynamic_cast<const AliExternalTrackParam*>(this);
fc6d4c2d 857
5d4510fe 858 //printf("SetTrackIn() : fTrackLow[%p]\n", (void*)fTrackLow);
fc6d4c2d 859 if(fTrackLow){
860 fTrackLow->~AliExternalTrackParam();
861 new(fTrackLow) AliExternalTrackParam(*op);
862 } else fTrackLow = new AliExternalTrackParam(*op);
e3cf3d02 863}
864
865//_______________________________________________________________
a310e49b 866void AliTRDtrackV1::SetTrackOut(const AliExternalTrackParam *op)
e3cf3d02 867{
fc6d4c2d 868// Save location of death for the TRD track
869// If the pointer is not valid allocate memory
870//
e3cf3d02 871 if(!op) op = dynamic_cast<const AliExternalTrackParam*>(this);
fc6d4c2d 872 if(fTrackHigh){
873 fTrackHigh->~AliExternalTrackParam();
874 new(fTrackHigh) AliExternalTrackParam(*op);
875 } else fTrackHigh = new AliExternalTrackParam(*op);
e3cf3d02 876}
877
181d2c97 878//_______________________________________________________________
879void AliTRDtrackV1::UnsetTracklet(Int_t plane)
880{
87f70a90 881 if(plane<0) return;
17896e82 882 fTrackletIndex[plane] = -1;
4d6aee34 883 fTracklet[plane] = NULL;
181d2c97 884}
885
886
d9950a5a 887//_______________________________________________________________
ef867f55 888void AliTRDtrackV1::UpdateChi2(Float_t chi2)
d9950a5a 889{
ef867f55 890// Update chi2/track with one tracklet contribution
b72f4eaf 891 SetChi2(GetChi2() + chi2);
d9950a5a 892}
893
894//_______________________________________________________________
0906e73e 895void AliTRDtrackV1::UpdateESDtrack(AliESDtrack *track)
d9950a5a 896{
897 //
6984f7c1 898 // Update the TRD PID information in the ESD track
d9950a5a 899 //
6984f7c1 900
93fc2389 901// Int_t nslices = AliTRDcalibDB::Instance()->GetPIDResponse(fkReconstructor->GetRecoParam()->GetPIDmethod())->GetNumberOfSlices();
e20bef2b 902 // number of tracklets used for PID calculation
903 UChar_t nPID = GetNumberOfTrackletsPID();
904 // number of tracklets attached to the track
905 UChar_t nTrk = GetNumberOfTracklets();
906 // pack the two numbers together and store them in the ESD
907 track->SetTRDntracklets(nPID | (nTrk<<3));
908 // allocate space to store raw PID signals dEdx & momentum
1f97f376 909 // independent of the method used to calculate PID (see below AliTRDPIDResponse)
910 track->SetNumberOfTRDslices((AliTRDseedV1::kNdEdxSlices+2)*AliTRDgeometry::kNlayer);
e20bef2b 911 // store raw signals
7b23a4e1 912 Float_t p, sp; Double_t spd;
6984f7c1 913 for (Int_t ip = 0; ip < kNplane; ip++) {
68f9b6bd 914 if(fTrackletIndex[ip]<0 || !fTracklet[ip]) continue;
1f97f376 915 // Fill TRD dEdx info into ESD track
916 // a. Set Summed dEdx into the first slice
917 track->SetTRDslice(fTracklet[ip]->GetdQdl(), ip, 0);
918 // b. Set NN dEdx slices
93fc2389 919 fTracklet[ip]->CookdEdx(AliTRDPIDResponse::kNslicesNN);
4d6aee34 920 const Float_t *dedx = fTracklet[ip]->GetdEdx();
1f97f376 921 for (Int_t js(0), ks(1); js < AliTRDPIDResponse::kNslicesNN; js++, ks++, dedx++){
922 if(ks>=AliTRDseedV1::kNdEdxSlices){
923 AliError(Form("Exceed allocated space for dEdx slices."));
924 break;
925 }
926 track->SetTRDslice(*dedx, ip, ks);
93fc2389 927 }
1f97f376 928 // fill TRD momentum info into ESD track
929 p = fTracklet[ip]->GetMomentum(&sp); spd = sp;
930 track->SetTRDmomentum(p, ip, &spd);
5c5d503a 931 // store global quality per tracklet instead of momentum error
932 // 26.09.11 A.Bercuci
933 // first implementation store no. of time bins filled in tracklet (5bits see "y" bits) and
934 // no. of double clusters in case of pad row cross (4bits see "x" bits)
935 // bit map for tracklet quality xxxxyyyyy
803dc399 936 // 27.10.11 A.Bercuci
c05ef2e8 937 // add chamber status bit "z" bit
803dc399 938 // bit map for tracklet quality zxxxxyyyyy
c05ef2e8 939 // 12.11.11 A.Bercuci
940 // fit tracklet quality into the field fTRDTimeBin [Char_t]
941 // bit map for tracklet quality zxxyyyyy
5554f68d 942 // The information should be retrieved by the following functions of AliESDtrack for each TRD layer
943 // GetTRDtrkltOccupancy(layer) -> no of TB filled in tracklet
944 // GetTRDtrkltClCross(layer) -> no of TB filled in crossing pad rows
945 // IsTRDtrkltChmbGood(layer) -> status of the chamber from which the tracklet is found
946 Int_t nCross(fTracklet[ip]->IsRowCross()?fTracklet[ip]->GetTBcross():0); if(nCross>3) nCross = 3;
c05ef2e8 947 Char_t trackletQ = Char_t(fTracklet[ip]->GetTBoccupancy() | (nCross<<5) | (fTracklet[ip]->IsChmbGood()<<7));
948 track->SetTRDTimBin(trackletQ, ip);
6984f7c1 949 }
e20bef2b 950 // store PID probabilities
951 track->SetTRDpid(fPID);
e2a1c98b 952
953 //store truncated mean
954 track->SetTRDsignal(fTruncatedMean);
d0037ea4 955 track->SetTRDNchamberdEdx(fNchamberdEdx);
956 track->SetTRDNclusterdEdx(fNclusterdEdx);
d9950a5a 957}
e2a1c98b 958
959//_______________________________________________________________
d0037ea4 960Double_t AliTRDtrackV1::CookTruncatedMean(const Bool_t kinvq, const Double_t mag, const Int_t charge, const Int_t kcalib, Int_t &nch, Int_t &ncls, TVectorD *Qs, TVectorD *Xs, Int_t timeBin0, Int_t timeBin1, Int_t tstep) const
e2a1c98b 961{
962 //
963 //Origin: Xianguo Lu <xianguo.lu@cern.ch>, Marian Ivanov <marian.ivanov@cern.ch>
964 //
965
966 TVectorD arrayQ(200), arrayX(200);
6951a056 967 ncls = AliTRDdEdxReconUtils::GetArrayClusterQ(kinvq, &arrayQ, &arrayX, this, timeBin0, timeBin1, tstep);
e2a1c98b 968
6951a056 969 const TObjArray *cobj = kcalib ? AliTRDdEdxCalibUtils::GetObj(kinvq, mag, charge) : NULL;
e2a1c98b 970
6951a056 971 const Double_t tmean = AliTRDdEdxReconUtils::ToyCook(kinvq, ncls, &arrayQ, &arrayX, cobj);
e2a1c98b 972
6951a056 973 nch = AliTRDdEdxReconUtils::UpdateArrayX(ncls, &arrayX);
e2a1c98b 974
975 if(Qs && Xs){
976 (*Qs)=arrayQ;
977 (*Xs)=arrayX;
978 }
979
a96ab3fd 980 //printf("\ntest %.10f %d %d\n", tmean, nch, ncls);
d0037ea4 981
982 return tmean;
e2a1c98b 983}
984
24aea01c 985//_______________________________________________________________
986TObject* AliTRDtrackV1::Clone(const char* newname) const
987{
988 // temporary override TObject::Clone to avoid crashes in reco
989 AliTRDtrackV1* src = (AliTRDtrackV1*)this;
990 Bool_t isown = src->IsOwner();
991 AliInfo(Form("src_owner %d",isown));
992 AliTRDtrackV1* dst = new AliTRDtrackV1(*src);
993 if (isown) {
994 src->SetBit(kOwner);
995 dst->SetOwner();
996 }
997 return dst;
998}