]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TPC/AliTPCCosmicUtils.cxx
// Combine cosmic track pairs (upper, lower) and do track fitting
[u/mrichter/AliRoot.git] / TPC / AliTPCCosmicUtils.cxx
CommitLineData
1f30d65c 1/**************************************************************************
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 **************************************************************************/
15//
16// Static function member
17// as utils for
18// AliTPCCombinedTrackfit
19//
20// grep "exitreport" in output log to check abnormal termination
21// comment tbc
22//
23// Xianguo Lu <lu@physi.uni-heidelberg.de>
24//
25
26#include <TAxis.h>
27#include <TCanvas.h>
28#include <TGraph.h>
29#include <TTreeStream.h>
30#include <TVector3.h>
31
32#include "AliESDtrack.h"
33#include "AliESDfriendTrack.h"
34#include "AliTPCseed.h"
35#include "AliTrackerBase.h"
36#include "AliTrackPointArray.h"
37
38#include "AliTPCCosmicUtils.h"
39
40Int_t AliTPCCosmicUtils::RotateSafe(AliExternalTrackParam *trackPar, const Double_t aa)
41{
42 //1. in AliExternalTrackParam::GetXYZ
43 //r[0]=fX; r[1]=fP[0]; r[2]=fP[1];
44 //return Local2GlobalPosition(r,fAlpha);
45 //in AliVParticle::Local2GlobalMomentum
46 //Double_t cs=TMath::Cos(alpha), sn=TMath::Sin(alpha);
47 //Double_t r=TMath::Sqrt((1. - p[1])*(1. + p[1]));
48 //p[0]=pt*(r*cs - p[1]*sn); p[1]=pt*(p[1]*cs + r*sn); p[2]=pt*p[2];
49 //which is cos(phi_local=Snp+fAlpha) > 0 always.
50 //2. also in Bool_t AliExternalTrackParam::Rotate(Double_t alpha)
51 // Double_t sf=fP2, cf=TMath::Sqrt((1.- fP2)*(1.+fP2));
52 //in AliExternalTrackParam::Set
53 //mom.RotateZ(-fAlpha);
54 //fP[2] = TMath::Sin(mom.Phi());
55 //since only sin is used for mom.Phi(), that is assuming cos(mom.Phi())>0
56
57 Double_t xyz[3], pxpypz[3];
58 trackPar->GetXYZ(xyz);
59 trackPar->GetPxPyPz(pxpypz);
60 const TVector3 pos0(xyz);
61 const TVector3 mom0(pxpypz);
62 TVector3 pos1, mom1, dpos, dmom;
63 const Double_t eps = 1e-6;
64 AliExternalTrackParam tmppar = (*trackPar);
65
66 if(!tmppar.Rotate(aa)){
67 return 0;
68 }
69
70 tmppar.GetXYZ(xyz);
71 tmppar.GetPxPyPz(pxpypz);
72 pos1.SetXYZ(xyz[0], xyz[1], xyz[2]);
73 mom1.SetXYZ(pxpypz[0], pxpypz[1], pxpypz[2]);
74 dpos = pos1-pos0;
75 dmom = mom1-mom0;
76 if(dpos.Mag()<eps && dmom.Mag()<eps){
77 (*trackPar)=tmppar;
78 return 1;
79 }
80 else
81 return 0;
82
83 /*
84 //flip
85 tmppar = (*trackPar);
86 if(!tmppar.Rotate(aa+TMath::Pi())){
87 return 0;
88 }
89
90 tmppar.GetXYZ(xyz);
91 tmppar.GetPxPyPz(pxpypz);
92 pos1.SetXYZ(xyz[0], xyz[1], xyz[2]);
93 mom1.SetXYZ(pxpypz[0], pxpypz[1], pxpypz[2]);
94 dpos = pos1-pos0;
95 dmom = mom1-mom0;
96 if(dpos.Mag()<eps && dmom.Mag()<eps){
97 (*trackPar)=tmppar;
98 return -1;
99 }
100
101 return 0;
102 */
103}
104
105void AliTPCCosmicUtils::PrintTrackParam(const Int_t id, const AliExternalTrackParam * trackpar, const char *tag)
106{
107 //
108 //print out TrackParam
109 //
110 Double_t xyz[3]={-999,-999,-999};
111 trackpar->GetXYZ(xyz);
112 Double_t pxpypz[3]={-999,-999,-999};
113 trackpar->GetPxPyPz(pxpypz);
114
115 printf("PrintTrackPar %2s %3d : %6.1f %5.1f : %6.6f %6.6f %6.6f : %8.3f %8.3f %8.3f : (%2d) %8.3f %11.6f %.2f\n", tag, id, trackpar->GetX(), sqrt(pow(xyz[0],2)+pow(xyz[1],2)), xyz[0], xyz[1], xyz[2], pxpypz[0], pxpypz[1], pxpypz[2], trackpar->Charge(), trackpar->Pt(), trackpar->P(), trackpar->GetAlpha()*TMath::RadToDeg());
116}
117
118void AliTPCCosmicUtils::DrawSeeds(const AliTPCseed * seeds[], const TString tag, const TString outputformat)
119{
120 //
121 //draw seed and output to file
122 //
123 TGraph *grsyx[]={new TGraph, new TGraph};
124 TGraph *grsyz[]={new TGraph, new TGraph};
125
126 for(Int_t itrk=0; itrk<2; itrk++){
127 if(!seeds[itrk])
128 continue;
129
130 Int_t ncl = 0;
131 for(Int_t irow=0; irow<fgkNRow; irow++){
132 const AliTPCclusterMI * cls = seeds[itrk]->GetClusterPointer(irow);
133 if(!cls)
134 continue;
135
136 Float_t xyz[3]={-999,-999,-999};
137 cls->GetGlobalXYZ(xyz);
138 //printf("Test %f %f %f \n", xyz[0], xyz[1], xyz[2]);
139 grsyx[itrk]->SetPoint(ncl, xyz[0], xyz[1]);
140 grsyz[itrk]->SetPoint(ncl, xyz[2], xyz[1]);
141 ncl++;
142 }
143 }
144
145 grsyx[0]->SetTitle(tag);
146 grsyx[0]->SetMaximum(250);
147 grsyx[0]->SetMinimum(-250);
148 grsyx[0]->GetXaxis()->SetLimits(-250,250);
149 grsyx[0]->GetXaxis()->SetTitle("X (cm)");
150 grsyx[0]->GetYaxis()->SetTitle("Y (cm)");
151
152 grsyx[0]->SetMarkerStyle(20);
153 grsyx[0]->SetMarkerColor(kRed);
154 grsyx[1]->SetMarkerStyle(22);
155 grsyx[1]->SetMarkerColor(kBlue);
156
157 grsyz[0]->SetTitle(tag);
158 grsyz[0]->SetMaximum(250);
159 grsyz[0]->SetMinimum(-250);
160 grsyz[0]->GetXaxis()->SetLimits(-250,250);
161 grsyz[0]->GetXaxis()->SetTitle("Z (cm)");
162 grsyz[0]->GetYaxis()->SetTitle("Y (cm)");
163
164 grsyz[0]->SetMarkerStyle(20);
165 grsyz[0]->SetMarkerColor(kRed);
166 grsyz[1]->SetMarkerStyle(22);
167 grsyz[1]->SetMarkerColor(kBlue);
168
169 TCanvas *cc=new TCanvas("cc","",1200,600);
170 cc->Divide(2);
171 cc->cd(1);
172 for(int itrk=0; itrk<2; itrk++){
173 grsyx[itrk]->SetMarkerSize(1);
174 grsyx[itrk]->Draw(itrk?"lp same":"alp");
175 }
176 cc->cd(2);
177 for(int itrk=0; itrk<2; itrk++){
178 grsyz[itrk]->SetMarkerSize(1);
179 grsyz[itrk]->Draw(itrk?"lp same":"alp");
180 }
181 cc->Print(Form("drawTrack%s.%s", tag.Data(), outputformat.Data()));
182
183 for(Int_t ii=0; ii<2; ii++){
184 delete grsyx[ii];
185 delete grsyz[ii];
186 }
187 delete cc;
188}
189
190//================================================================================================
191AliTPCseed * AliTPCCosmicUtils::GetTPCseed(const AliESDtrack *esdtrack)
192{
193 //
194 //Get TPC seeds from ESDfriendTrack
195 //
196
197 AliESDfriendTrack * friendtrk = (AliESDfriendTrack *) esdtrack->GetFriendTrack();
198 if(!friendtrk){
199 printf("exitreport AliTPCCosmicUtils::GetTPCseed no friend track!\n");
200 exit(1);
201 }
202
203 TObject *calibObject=0x0;
204 AliTPCseed *tseed = 0x0;
205 for(Int_t l=0; (calibObject=friendtrk->GetCalibObject(l)); l++) {
206 if( (tseed=dynamic_cast<AliTPCseed*>(calibObject)) )
207 break;
208 }
209 return tseed;
210}
211
212//================================================================================================
213AliExternalTrackParam *AliTPCCosmicUtils::MakeSeed(const AliTPCseed *tseed)
214{
215 //
216 //make seed for propagation of TrackParam, using np = 3 outer clusters (separated by deltancls clusters) in TPCseed
217 //
218
219 const Int_t rowstart = fgkNRow-1;
220 const Int_t rowstop = 0;
221 const Int_t drow = -1;
222
223 //---
224 const Int_t np = 3;
225 AliTrackPoint *tpos[np];
226 for(Int_t ii=0; ii<np; ii++)
227 tpos[ii] = 0x0;
228
229 const Float_t cov[6]={0,0,0, 0.01*0.01 ,0, 0.01*0.01};
230
231 //---
232 Int_t npos = 0;
233 Int_t icl = 0;
234 const Int_t deltancls = fgkNclsMin/2-1;
235 Int_t oldcl = -deltancls;
236
237 for(Int_t irow=rowstart; drow*irow<=drow*rowstop; irow+=drow){
238 AliTPCclusterMI *cls = tseed->GetClusterPointer(irow);
239 if(!cls) {
240 continue;
241 }
242
243 if( icl == (oldcl+deltancls) ){
244 Float_t txyz[3];
245 cls->GetGlobalXYZ(txyz);
246 tpos[npos++] = new AliTrackPoint(txyz, cov, 0);
247 //printf("------ %d %f %f %f\n", npos, txyz[0], txyz[1], txyz[2]);
248
249 oldcl = icl;
250 if(npos==np) break;
251 }
252 icl++;
253 }
254 if(npos!=np){
255 for(Int_t ii=0; ii<npos; ii++)
256 delete tpos[ii];
257
258 return 0x0;
259 }
260
261 AliExternalTrackParam * trackparam = AliTrackerBase::MakeSeed(*(tpos[0]), *(tpos[1]), *(tpos[2]));
262 if(!trackparam || trackparam->Pt()==0){
263 for(Int_t ii=0; ii<npos; ii++)
264 delete tpos[ii];
265 delete trackparam;
266
267 return 0x0;
268 }
269
270 //------
271
272 Double_t sxyz[3]={-999,-999,-999}, spxpypz[3]={-999,-999,-999};
273 trackparam->GetXYZ(sxyz);
274 trackparam->GetPxPyPz(spxpypz);
275 Double_t scov[21];
276 Int_t sign = trackparam->Charge();
277
278 //reset covariance matrix -- necessary, otherwise bad fitting result: trackparam->GetCovariance()[ii] has problem: some are strange values
279 for(Int_t ii=0; ii<21; ii++) {
280 scov[ii]=0;
281 }
282 trackparam->Set(sxyz, spxpypz, scov, sign);
283
284 for(Int_t ii=0; ii<np; ii++)
285 delete tpos[ii];
286
287 return trackparam;
288}
289
290//================================================================================================
291void AliTPCCosmicUtils::IniCov(AliExternalTrackParam *trackPar, const Double_t ncl)
292{
293 //
294 //initialize covariance matrix
295 //
296
297 const Double_t ksigma=5.;
298 Double_t acov[16];
299 for (Int_t i=0;i<15;i++)
300 acov[i]=0;
301
302 acov[0]=ksigma*ksigma;
303 acov[2]=ksigma*ksigma;
304 acov[5]=ksigma*ksigma;
305 acov[9]=ksigma*ksigma;
306 acov[14]=0.2*0.2;
307
308 acov[5] = ksigma*ksigma/(ncl*ncl);
309 acov[9] = ksigma*ksigma/(ncl*ncl);
310
311 const Double_t resetcov = 4;
312
313 trackPar->ResetCovariance(resetcov);
314 //the following helps a lot!!
315 trackPar->AddCovariance(acov);
316}
317
318void AliTPCCosmicUtils::SingleFit(AliExternalTrackParam * trackInOld, AliExternalTrackParam * trackOutOld, const AliTPCseed *tseed, const Bool_t kinward, Int_t &nfit, Int_t &nmiss, Double_t &pchi2, TTreeSRedirector *debugstreamer)
319{
320 //
321 //fit single track
322 //
323 //kinward is the true geometry of the track. Incomming track: 1; outgoing track: 0
324 const Double_t inde = kinward? -1 : 1;
325 const Double_t outde = kinward? 1 : -1;
326
327 //PrintTrackParam(9000, trackOutOld);
328
329 AliExternalTrackParam trackOut = *trackOutOld;
330 AliExternalTrackParam trackIn;
331 Int_t ksite = -999;
332
333 //nmiss is from the 2 FitKernel of the last iteration
334 //nfit, pchi2 is from the last FitKernel of the last iteration
335 for(Int_t ii=0; ii<fgkNiter; ii++){
336 nmiss = 0;
337
338 ksite = -999;
339 trackIn = trackOut;
340 FitKernel(&trackIn, tseed, fgkNRow-1, 0, inde , ksite, nfit, nmiss, pchi2, 0x0, kTRUE);
341 //PrintTrackParam(9010+ii, &trackIn);
342
343 nfit = 0;
344 pchi2 = 0;
345
346 ksite = -999;
347 trackOut = trackIn;
348 FitKernel(&trackOut, tseed, 0, fgkNRow-1, outde, ksite, nfit, nmiss, pchi2, (ii==fgkNiter-1 ? debugstreamer : 0x0), kTRUE);
349 //PrintTrackParam(90020+ii, &trackOut);
350 }
351
352 if(trackInOld)
353 (*trackInOld) = trackIn;
354
355 (*trackOutOld) = trackOut;
356}
357
358void AliTPCCosmicUtils::CombinedFit(AliExternalTrackParam *trackPars[], const AliTPCseed *seeds[], Int_t &nfit, Int_t &nmiss, Double_t &pchi2, TTreeSRedirector *debugstreamer)
359{
360 //
361 //combined propagation
362 //
363
364 //seen from 1/pt_fit - 1/pt_gen, for differnt de:
365 //u+d+: combUp good, combLow bad
366 //u+d-: combUp good, combLow good
367 //u-d-: combUp bad, combLow good
368 //u-d+: combUp bad, combLow bad
369 const Double_t upde = 1;
370 const Double_t lowde = -1;
371
372 AliExternalTrackParam trackLow = *(trackPars[1]);
373 AliExternalTrackParam trackUp;
374
375 for(Int_t ii=0; ii<fgkNiter; ii++){
376 nmiss = 0;
377
378 //lower->upper
379 trackUp = trackLow;
380 SubCombined(&trackUp, seeds, 1, 0, upde, nfit, nmiss, pchi2);
381
382 nfit = 0;
383 pchi2 = 0;
384
385 //upper->lower
386 trackLow = trackUp;
387 SubCombined(&trackLow, seeds, 0, 1, lowde, nfit, nmiss, pchi2, (ii==fgkNiter-1? debugstreamer : 0x0));
388 }
389
390 *(trackPars[0]) = trackUp;
391 *(trackPars[1]) = trackLow;
392}
393
394void AliTPCCosmicUtils::SubCombined(AliExternalTrackParam *trackPar, const AliTPCseed *seeds[], const Int_t tk0, const Int_t tk1, const Double_t eloss, Int_t &nfit, Int_t &nmiss, Double_t &pchi2, TTreeSRedirector *debugstreamer)
395{
396 //
397 //sub-routine for combined propagation
398 //
399
400 IniCov(trackPar, seeds[0]->GetNumberOfClusters()+seeds[1]->GetNumberOfClusters());
401
402 Int_t dtk=1;
403 if(tk0>tk1)
404 dtk=-1;
405
406 //reset counters
407 Int_t ksite = -999;
408 nfit = 0;
409 nmiss = 0;
410 pchi2 = 0;
411
412 //always nrow -> 1 -> nrow
413 Int_t rowstart=fgkNRow-1;
414 Int_t rowstop=0;
415 for(Int_t itrk=tk0; dtk*itrk<=dtk*tk1; itrk+=dtk){
416 if(itrk==tk1){
417 Int_t tmprow = rowstart;
418 rowstart = rowstop;
419 rowstop = tmprow;
420 }
421 FitKernel(trackPar, seeds[itrk], rowstart, rowstop, eloss, ksite, nfit, nmiss, pchi2, debugstreamer, kFALSE);
422 }
423}
424
425void AliTPCCosmicUtils::FitKernel(AliExternalTrackParam *trackPar, const AliTPCseed *tseed, const Int_t rowstart, const Int_t rowstop, const Double_t eloss, Int_t &ksite, Int_t &nfit, Int_t &nmiss, Double_t &pchi2, TTreeSRedirector *debugstreamer, const Bool_t kinicov)
426{
427 //
428 //routine for propagation
429 //
430
431 //only for SingleFit-->
432 if(kinicov)
433 IniCov(trackPar, tseed->GetNumberOfClusters());
434 //<--
435
436 Int_t drow=1;
437 if(rowstart>rowstop)
438 drow = -1;
439
440 for(Int_t irow=rowstart; drow*irow<=drow*rowstop; irow+=drow){
441 if(0){
442 //only for momentum resolution investigation, dumm for usual usage
443 if(eloss>0){
444 if(irow%2==0)
445 continue;
446 }
447 else{
448 if(irow%2!=0)
449 continue;
450 }
451 }
452
453 AliTPCclusterMI *cl=tseed->GetClusterPointer(irow);
454 if (!cl) continue;
455 if (cl->GetX()< fgkXMin) continue;
456
457 //if propagation not successful, trackPar is not changed
458 AliExternalTrackParam tmppar(*trackPar);
459
460 //--------------------------- to cure large chi2 in z, 2011-05-11. Thandks to M. Ivanov! ---------------------------
461 const Int_t tmpsite = ((cl->GetDetector()%36)<18);
462 if(tmpsite!=ksite && ksite!=-999){
463 Double_t *clscov=(Double_t*)tmppar.GetCovariance();
464 clscov[2]+=3*3;
465 }
466 ksite = tmpsite;
467
468 //--------------------------- rotate cluster position to trackPar position ---------------------------
469 //DO NOT rotate trackPar, there is "bug" in trackparam::rotate!! stay in the initial one defined as alpha = ATan2(posy0,posx0)
470 Float_t gxyz[3];
471 cl->GetGlobalXYZ(gxyz);
472 TVector3 ptogo(gxyz);
473
474 //printf("test %d : %f %f %f\n", irow, gxyz[0], gxyz[1], gxyz[2]);
475
476 const Double_t trkalpha = tmppar.GetAlpha();
477 ptogo.RotateZ(-trkalpha);
478 const Double_t xTogo = ptogo.X();
479 const Double_t yTogo = ptogo.Y();
480 const Double_t zTogo = ptogo.Z();
481
482 //--------------------------- propagate ---------------------------
483 //AliTrackerBase::PropagateTrackToBxByBz Double_t step = dir*TMath::Min(TMath::Abs(xToGo-xpos), maxStep);
484 const Double_t maxStep = 1;
485 const Bool_t rotateTo = kFALSE;
486 const Double_t maxSnp = 0.8;
487
488 //eloss critical only for combine fit!!!
489 const Bool_t kpro = AliTrackerBase::PropagateTrackToBxByBz(&tmppar, xTogo, fgkMass, maxStep, rotateTo, maxSnp, eloss);
490 if(!kpro){
491 nmiss++;
492 continue;
493 }
494
495 //--------------------------- set error ---------------------------
496 //necessary, help at mostly low p, and also high p
497 Double_t cov[3]={0.01, 0., 0.01};
498 AliTPCseed::GetError(cl, &tmppar, cov[0],cov[2]);
499 cov[0]*=cov[0];
500 cov[2]*=cov[2];
501
502 if(debugstreamer){
503 TVector3 tmpgxyz(gxyz);
504 (*debugstreamer)<<"ErrParam"<<
505 "Cl.="<<cl<<
506 "T.="<<&tmppar<<
507 "covy="<<cov[0]<<
508 "covz="<<cov[2]<<
509 "clpos.="<<&ptogo<<
510 "gpos.="<<&tmpgxyz<<
511 "\n";
512 }
513
514 //--------------------------- get chi2 and THEN update ---------------------------
515 Double_t yz[2]={yTogo, zTogo};
516
517 pchi2 += tmppar.GetPredictedChi2(yz, cov);
518
519 tmppar.Update(yz,cov);
520
521 //--------------------------- save change ---------------------------
522 (*trackPar) = tmppar;
523
524 nfit++;
525 }
526}