next50 trigger mask in AliHLTGlobalEsdConverterComponent
[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
1d26da6d 135 SetMass(t.GetMassForTracking());
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();
fc9b31a7 162 Double_t times[AliPID::kSPECIESC];
163 t.GetIntegratedTimes(times,AliPID::kSPECIESC);
3b57a3f7 164 SetIntegratedTimes(times);
165 SetIntegratedLength(t.GetIntegratedLength());
166 }
d9950a5a 167}
168
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
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
257//_______________________________________________________________
e08a5492 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
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
367//_______________________________________________________________
d9950a5a 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
3b57a3f7 436//_______________________________________________________________
0349cc67 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
458//_______________________________________________________________
3b57a3f7 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
22a4ab0c 496//_______________________________________________________________
eb2b4f91 497Int_t AliTRDtrackV1::GetSector() const
498{
499 return Int_t(GetAlpha()/AliTRDgeometry::GetAlpha() + (GetAlpha()>0. ? 0 : AliTRDgeometry::kNsector));
500}
501
502//_______________________________________________________________
203967fc 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
549//_______________________________________________________________
22a4ab0c 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());
1d26da6d 672 if (fMass<0) p2 *= 4; // q=2
35315297 673 Double_t beta2 = p2 / (p2 + fMass*fMass);
3b57a3f7 674 if ((beta2 < 1.0e-10) ||
675 ((5940.0 * beta2/(1.0 - beta2 + 1.0e-10) - beta2) < 0.0)) {
676 return kFALSE;
677 }
678
679 Double_t dE = 0.153e-3 / beta2
680 * (TMath::Log(5940.0 * beta2/(1.0 - beta2 + 1.0e-10)) - beta2)
681 * xrho;
1d26da6d 682 if (fMass<0) dE *= 4; // q=2
3b57a3f7 683 fBudget[0] += xrho;
684
685 /*
686 // Suspicious part - think about it ?
687 Double_t kinE = TMath::Sqrt(p2);
688 if (dE > 0.8*kinE) dE = 0.8 * kinE; //
689 if (dE < 0) dE = 0.0; // Not valid region for Bethe bloch
690 */
691
692 fDE += dE;
693
694 /*
695 // Suspicious ! I.B.
696 Double_t sigmade = 0.07 * TMath::Sqrt(TMath::Abs(dE)); // Energy loss fluctuation
35315297 697 Double_t sigmac2 = sigmade*sigmade*fC*fC*(p2+fMass*fMass)/(p2*p2);
3b57a3f7 698 fCcc += sigmac2;
699 fCee += fX*fX * sigmac2;
700 */
701
702 }
703
704 return kTRUE;
0906e73e 705}
3b57a3f7 706
87a7fa94 707//_____________________________________________________________________________
3b57a3f7 708Int_t AliTRDtrackV1::PropagateToR(Double_t r,Double_t step)
87a7fa94 709{
710 //
3b57a3f7 711 // Propagate track to the radial position
712 // Rotation always connected to the last track position
87a7fa94 713 //
714
3b57a3f7 715 Double_t xyz0[3];
716 Double_t xyz1[3];
717 Double_t y;
718 Double_t z;
719
720 Double_t radius = TMath::Sqrt(GetX()*GetX() + GetY()*GetY());
721 // Direction +-
722 Double_t dir = (radius > r) ? -1.0 : 1.0;
723
724 for (Double_t x = radius+dir*step; dir*x < dir*r; x += dir*step) {
725
726 GetXYZ(xyz0);
727 Double_t alpha = TMath::ATan2(xyz0[1],xyz0[0]);
728 Rotate(alpha,kTRUE);
729 GetXYZ(xyz0);
e20bef2b 730 if(GetProlongation(x,y,z)<0) return -1;
3b57a3f7 731 xyz1[0] = x * TMath::Cos(alpha) + y * TMath::Sin(alpha);
732 xyz1[1] = x * TMath::Sin(alpha) - y * TMath::Cos(alpha);
733 xyz1[2] = z;
734 Double_t param[7];
83dea92e 735 if(AliTracker::MeanMaterialBudget(xyz0,xyz1,param)<=0.) return -1;
3b57a3f7 736 if (param[1] <= 0) {
737 param[1] = 100000000;
738 }
739 PropagateTo(x,param[1],param[0]*param[4]);
740
741 }
742
743 GetXYZ(xyz0);
744 Double_t alpha = TMath::ATan2(xyz0[1],xyz0[0]);
745 Rotate(alpha,kTRUE);
746 GetXYZ(xyz0);
530fb4e2 747 if(GetProlongation(r,y,z)<0) return -1;
3b57a3f7 748 xyz1[0] = r * TMath::Cos(alpha) + y * TMath::Sin(alpha);
749 xyz1[1] = r * TMath::Sin(alpha) - y * TMath::Cos(alpha);
750 xyz1[2] = z;
751 Double_t param[7];
83dea92e 752 if(AliTracker::MeanMaterialBudget(xyz0,xyz1,param) <= 0.) return -1;
3b57a3f7 753
754 if (param[1] <= 0) {
755 param[1] = 100000000;
87a7fa94 756 }
3b57a3f7 757 PropagateTo(r,param[1],param[0]*param[4]);
758
759 return 0;
760
87a7fa94 761}
762
3b57a3f7 763//_____________________________________________________________________________
203967fc 764void AliTRDtrackV1::Print(Option_t *o) const
765{
4d6aee34 766 // Print track status
eb2b4f91 767 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 768 AliInfo(Form("Material[%5.2f %5.2f %5.2f]", fBudget[0], fBudget[1], fBudget[2]));
769
770 AliInfo(Form("x[%7.2f] t[%7.4f] alpha[%f] mass[%f]", GetX(), GetIntegratedLength(), GetAlpha(), fMass));
eb2b4f91 771 AliInfo(Form("Ntr[%1d] NtrPID[%1d] Ncl[%3d] lab[%3d]", GetNumberOfTracklets(), GetNumberOfTrackletsPID(), fN, fLab));
203967fc 772
203967fc 773 printf("|X| = (");
774 const Double_t *curP = GetParameter();
775 for (Int_t i = 0; i < 5; i++) printf("%7.2f ", curP[i]);
776 printf(")\n");
777
778 printf("|V| = \n");
779 const Double_t *curC = GetCovariance();
780 for (Int_t i = 0, j=4, k=0; i<15; i++, k++){
781 printf("%7.2f ", curC[i]);
782 if(k==j){
783 printf("\n");
784 k=-1; j--;
785 }
786 }
0217fcd0 787 if(strcmp(o, "a")!=0) return;
203967fc 788
789 for(Int_t ip=0; ip<kNplane; ip++){
790 if(!fTracklet[ip]) continue;
791 fTracklet[ip]->Print(o);
792 }
793}
794
795
796//_____________________________________________________________________________
3b57a3f7 797Bool_t AliTRDtrackV1::Rotate(Double_t alpha, Bool_t absolute)
798{
799 //
800 // Rotates track parameters in R*phi plane
801 // if absolute rotation alpha is in global system
802 // otherwise alpha rotation is relative to the current rotation angle
803 //
804
805 if (absolute) alpha -= GetAlpha();
806 //else fNRotate++;
807
808 return AliExternalTrackParam::Rotate(GetAlpha()+alpha);
809}
87a7fa94 810
eb38ed55 811//___________________________________________________________
812void AliTRDtrackV1::SetNumberOfClusters()
813{
814// Calculate the number of clusters attached to this track
815
3b57a3f7 816 Int_t ncls = 0;
817 for(int ip=0; ip<kNplane; ip++){
68f9b6bd 818 if(fTracklet[ip] && fTrackletIndex[ip] >= 0) ncls += fTracklet[ip]->GetN();
3b57a3f7 819 }
820 AliKalmanTrack::SetNumberOfClusters(ncls);
eb38ed55 821}
822
823
0906e73e 824//_______________________________________________________________
3b57a3f7 825void AliTRDtrackV1::SetOwner()
0906e73e 826{
827 //
828 // Toggle ownership of tracklets
829 //
830
e44586fb 831 if(TestBit(kOwner)) return;
3b57a3f7 832 for (Int_t ip = 0; ip < kNplane; ip++) {
68f9b6bd 833 if(fTrackletIndex[ip]<0 || !fTracklet[ip]) continue;
3b57a3f7 834 fTracklet[ip] = new AliTRDseedV1(*fTracklet[ip]);
835 fTracklet[ip]->SetOwner();
836 }
e44586fb 837 SetBit(kOwner);
0906e73e 838}
839
840//_______________________________________________________________
4d6aee34 841void AliTRDtrackV1::SetTracklet(AliTRDseedV1 *const trklt, Int_t index)
d9950a5a 842{
843 //
0906e73e 844 // Set the tracklets
d9950a5a 845 //
3b57a3f7 846 Int_t plane = trklt->GetPlane();
76b60503 847
3b57a3f7 848 fTracklet[plane] = trklt;
849 fTrackletIndex[plane] = index;
d9950a5a 850}
851
852//_______________________________________________________________
a310e49b 853void AliTRDtrackV1::SetTrackIn()
e3cf3d02 854{
fc6d4c2d 855// Save location of birth for the TRD track
856// If the pointer is not valid allocate memory
857//
e3cf3d02 858 const AliExternalTrackParam *op = dynamic_cast<const AliExternalTrackParam*>(this);
fc6d4c2d 859
5d4510fe 860 //printf("SetTrackIn() : fTrackLow[%p]\n", (void*)fTrackLow);
fc6d4c2d 861 if(fTrackLow){
862 fTrackLow->~AliExternalTrackParam();
863 new(fTrackLow) AliExternalTrackParam(*op);
864 } else fTrackLow = new AliExternalTrackParam(*op);
e3cf3d02 865}
866
867//_______________________________________________________________
a310e49b 868void AliTRDtrackV1::SetTrackOut(const AliExternalTrackParam *op)
e3cf3d02 869{
fc6d4c2d 870// Save location of death for the TRD track
871// If the pointer is not valid allocate memory
872//
e3cf3d02 873 if(!op) op = dynamic_cast<const AliExternalTrackParam*>(this);
fc6d4c2d 874 if(fTrackHigh){
875 fTrackHigh->~AliExternalTrackParam();
876 new(fTrackHigh) AliExternalTrackParam(*op);
877 } else fTrackHigh = new AliExternalTrackParam(*op);
e3cf3d02 878}
879
880//_______________________________________________________________
181d2c97 881void AliTRDtrackV1::UnsetTracklet(Int_t plane)
882{
87f70a90 883 if(plane<0) return;
17896e82 884 fTrackletIndex[plane] = -1;
4d6aee34 885 fTracklet[plane] = NULL;
181d2c97 886}
887
888
889//_______________________________________________________________
ef867f55 890void AliTRDtrackV1::UpdateChi2(Float_t chi2)
d9950a5a 891{
ef867f55 892// Update chi2/track with one tracklet contribution
b72f4eaf 893 SetChi2(GetChi2() + chi2);
d9950a5a 894}
895
896//_______________________________________________________________
0906e73e 897void AliTRDtrackV1::UpdateESDtrack(AliESDtrack *track)
d9950a5a 898{
899 //
6984f7c1 900 // Update the TRD PID information in the ESD track
d9950a5a 901 //
6984f7c1 902
93fc2389 903// Int_t nslices = AliTRDcalibDB::Instance()->GetPIDResponse(fkReconstructor->GetRecoParam()->GetPIDmethod())->GetNumberOfSlices();
e20bef2b 904 // number of tracklets used for PID calculation
905 UChar_t nPID = GetNumberOfTrackletsPID();
906 // number of tracklets attached to the track
907 UChar_t nTrk = GetNumberOfTracklets();
908 // pack the two numbers together and store them in the ESD
909 track->SetTRDntracklets(nPID | (nTrk<<3));
910 // allocate space to store raw PID signals dEdx & momentum
1f97f376 911 // independent of the method used to calculate PID (see below AliTRDPIDResponse)
912 track->SetNumberOfTRDslices((AliTRDseedV1::kNdEdxSlices+2)*AliTRDgeometry::kNlayer);
e20bef2b 913 // store raw signals
7b23a4e1 914 Float_t p, sp; Double_t spd;
6984f7c1 915 for (Int_t ip = 0; ip < kNplane; ip++) {
68f9b6bd 916 if(fTrackletIndex[ip]<0 || !fTracklet[ip]) continue;
1f97f376 917 // Fill TRD dEdx info into ESD track
918 // a. Set Summed dEdx into the first slice
919 track->SetTRDslice(fTracklet[ip]->GetdQdl(), ip, 0);
920 // b. Set NN dEdx slices
93fc2389 921 fTracklet[ip]->CookdEdx(AliTRDPIDResponse::kNslicesNN);
4d6aee34 922 const Float_t *dedx = fTracklet[ip]->GetdEdx();
1f97f376 923 for (Int_t js(0), ks(1); js < AliTRDPIDResponse::kNslicesNN; js++, ks++, dedx++){
924 if(ks>=AliTRDseedV1::kNdEdxSlices){
925 AliError(Form("Exceed allocated space for dEdx slices."));
926 break;
927 }
928 track->SetTRDslice(*dedx, ip, ks);
93fc2389 929 }
1f97f376 930 // fill TRD momentum info into ESD track
931 p = fTracklet[ip]->GetMomentum(&sp); spd = sp;
932 track->SetTRDmomentum(p, ip, &spd);
5c5d503a 933 // store global quality per tracklet instead of momentum error
934 // 26.09.11 A.Bercuci
935 // first implementation store no. of time bins filled in tracklet (5bits see "y" bits) and
936 // no. of double clusters in case of pad row cross (4bits see "x" bits)
937 // bit map for tracklet quality xxxxyyyyy
803dc399 938 // 27.10.11 A.Bercuci
c05ef2e8 939 // add chamber status bit "z" bit
803dc399 940 // bit map for tracklet quality zxxxxyyyyy
c05ef2e8 941 // 12.11.11 A.Bercuci
942 // fit tracklet quality into the field fTRDTimeBin [Char_t]
943 // bit map for tracklet quality zxxyyyyy
5554f68d 944 // The information should be retrieved by the following functions of AliESDtrack for each TRD layer
945 // GetTRDtrkltOccupancy(layer) -> no of TB filled in tracklet
946 // GetTRDtrkltClCross(layer) -> no of TB filled in crossing pad rows
947 // IsTRDtrkltChmbGood(layer) -> status of the chamber from which the tracklet is found
948 Int_t nCross(fTracklet[ip]->IsRowCross()?fTracklet[ip]->GetTBcross():0); if(nCross>3) nCross = 3;
c05ef2e8 949 Char_t trackletQ = Char_t(fTracklet[ip]->GetTBoccupancy() | (nCross<<5) | (fTracklet[ip]->IsChmbGood()<<7));
950 track->SetTRDTimBin(trackletQ, ip);
6984f7c1 951 }
e20bef2b 952 // store PID probabilities
953 track->SetTRDpid(fPID);
e2a1c98b 954
955 //store truncated mean
956 track->SetTRDsignal(fTruncatedMean);
d0037ea4 957 track->SetTRDNchamberdEdx(fNchamberdEdx);
958 track->SetTRDNclusterdEdx(fNclusterdEdx);
d9950a5a 959}
e2a1c98b 960
961//_______________________________________________________________
d0037ea4 962Double_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 963{
964 //
965 //Origin: Xianguo Lu <xianguo.lu@cern.ch>, Marian Ivanov <marian.ivanov@cern.ch>
966 //
967
968 TVectorD arrayQ(200), arrayX(200);
6951a056 969 ncls = AliTRDdEdxReconUtils::GetArrayClusterQ(kinvq, &arrayQ, &arrayX, this, timeBin0, timeBin1, tstep);
e2a1c98b 970
6951a056 971 const TObjArray *cobj = kcalib ? AliTRDdEdxCalibUtils::GetObj(kinvq, mag, charge) : NULL;
e2a1c98b 972
6951a056 973 const Double_t tmean = AliTRDdEdxReconUtils::ToyCook(kinvq, ncls, &arrayQ, &arrayX, cobj);
e2a1c98b 974
6951a056 975 nch = AliTRDdEdxReconUtils::UpdateArrayX(ncls, &arrayX);
e2a1c98b 976
977 if(Qs && Xs){
978 (*Qs)=arrayQ;
979 (*Xs)=arrayX;
980 }
981
a96ab3fd 982 //printf("\ntest %.10f %d %d\n", tmean, nch, ncls);
d0037ea4 983
984 return tmean;
e2a1c98b 985}
986
24aea01c 987//_______________________________________________________________
988TObject* AliTRDtrackV1::Clone(const char* newname) const
989{
990 // temporary override TObject::Clone to avoid crashes in reco
991 AliTRDtrackV1* src = (AliTRDtrackV1*)this;
992 Bool_t isown = src->IsOwner();
993 AliInfo(Form("src_owner %d",isown));
994 AliTRDtrackV1* dst = new AliTRDtrackV1(*src);
995 if (isown) {
996 src->SetBit(kOwner);
997 dst->SetOwner();
998 }
999 return dst;
1000}