14b849a64d0fb7c68c8a44484e7ac853f63356f8
[u/mrichter/AliRoot.git] / HLT / EVE / AliHLTEveHLT.cxx
1 /**************************************************************************
2  * This file is property of and copyright by the ALICE HLT Project        *
3  * ALICE Experiment at CERN, All rights reserved.                         *
4  *                                                                        *
5  * Primary Authors: Svein Lindal <slindal@fys.uio.no   >                  *
6  *                  for The ALICE HLT Project.                            *
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 /// @file   AliHLTEvePhos.cxx
18 /// @author Svein Lindal <slindal@fys.uio.no>
19 /// @brief  HLT class for the HLT EVE display
20
21 #include "AliHLTEveHLT.h"
22 #include "AliHLTHOMERBlockDesc.h"
23 #include "AliHLTEveBase.h"
24 #include "AliEveHLTEventManager.h"
25 #include "AliHLTGlobalTriggerDecision.h"
26 #include "TEveManager.h"
27 #include "TEvePointSet.h"
28 #include "TEveTrack.h"
29 #include "TEveElement.h"
30 #include "TCanvas.h"
31 #include "AliESDEvent.h"
32 #include "AliESDtrack.h"
33 #include "TEveTrackPropagator.h"
34 #include "AliEveTrack.h"
35 #include "TEveVSDStructs.h"
36 #include "TString.h"
37 #include "TPCLib/tracking-ca/AliHLTTPCCATrackParam.h"
38 #include "TPCLib/tracking-ca/AliHLTTPCCATrackConvertor.h"
39 #include "AliEveMagField.h"
40 #include "TH1.h"
41 #include "TH1F.h"
42 #include "TH2F.h"
43 #include "TThread.h"
44
45 ClassImp(AliHLTEveHLT)
46
47 AliHLTEveHLT::AliHLTEveHLT() : 
48   AliHLTEveBase("TPC tracks"), 
49   fTrueField(kFALSE),
50   fUseIpOnFailedITS(kFALSE),
51   fUseRkStepper(kFALSE),
52   fTrackList(NULL),
53   fTrackLists(NULL),
54   fOldTrackList(NULL),
55   fPointSetVertex(NULL),
56   fTrCanvas(NULL),
57   fVertexCanvas(NULL),
58   fHistEta(NULL),
59   fHistPhi(NULL),
60   fHistnClusters(NULL),
61   fHistMult(NULL),
62   fHistDCAr(NULL),
63   fTrCount(0), 
64   fVCount(0),
65   fNTrackBins(10)
66 {
67   // Constructor.
68   CreateHistograms();
69
70 }
71 ///___________________________________________________________________
72 AliHLTEveHLT::~AliHLTEveHLT()
73 {
74   //Destructor, not implemented
75   if(fTrackList)
76     delete fTrackList;
77   fTrackList = NULL;
78
79   if(fTrackLists)
80     delete fTrackLists;
81   fTrackLists = NULL;
82
83
84 }
85
86
87 ///________________________________________________________________________
88 void AliHLTEveHLT::CreateHistograms(){
89   //See header file for documentation
90
91   //fHistPt        = new TH1F("fHistPt",       "transverse momentum",    100, 0, 10); // KK   
92   //fHistP         = new TH1F("fHistP",        "signed momentum",        100,-7,  7);      
93
94   //fHistPt   ->SetXTitle("p_{t} (GeV/c)");   // KK
95   //fHistP    ->SetXTitle("P*charge (GeV/c)");
96
97   // fHistTheta     = new TH1F("fHistTheta",    "polar angle",            180, 0,180);   
98   // fHistTheta->SetXTitle("#theta (degrees)");
99   
100   fHistEta       = new TH1F("fHistEta",      "pseudorapidity",         100,-2,  2);        
101   fHistEta  ->SetXTitle("#eta");
102
103   fHistPhi       = new TH1F("fHistPhi",      "azimuthal angle",        180, 0,360);   
104   fHistPhi  ->SetXTitle("#phi (degrees)");
105
106   fHistnClusters = new TH1F("fHistnClusters","TPC clusters per track", 160, 0,160);
107
108   fHistMult      = new TH1F("fHistMult",     "event track multiplicity",150, 0, 15000);    
109   
110   fHistDCAr = new TH1F("fHistDCAr", "DCA r", 200, -100, 100);
111
112 }
113
114
115 ///_____________________________________________________________________
116 void AliHLTEveHLT::ProcessBlock(AliHLTHOMERBlockDesc * block) {
117   //See header file for documentation
118   if ( ! block->GetDataType().CompareTo("ALIESDV0") ) {
119     ProcessEsdBlock(block);
120   } 
121   
122   else if ( ! block->GetDataType().CompareTo("ROOTTOBJ") ) {
123     //processROOTTOBJ( block, gHLTText );
124   } 
125
126   else if ( ! block->GetDataType().CompareTo("HLTRDLST") ) {
127     cout << "ignoring hlt rdlst"<<endl;
128     //processHLTRDLST( block );
129   } 
130
131   else if ( ! block->GetDataType().CompareTo("GLOBTRIG") ) {
132     ProcessGlobalTrigger( block );
133   } 
134
135   else if ( !block->GetDataType().CompareTo("ROOTHIST") ) {      
136     if( !fCanvas ) { 
137       fCanvas = CreateCanvas("PVtx/Tr QA", "PrimV");
138       fCanvas->Divide(3, 3);
139     }
140     ProcessHistograms( block , fCanvas);
141   }  
142 }
143
144 ///____________________________________________________________________________
145 void AliHLTEveHLT::UpdateElements() {
146   //See header file for documentation
147
148   DrawHistograms();
149
150   if(fTrackLists) {
151     for(Int_t il = 0; il < fNTrackBins; il++) {
152       TEveTrackList * trackList = dynamic_cast<TEveTrackList*>(fTrackLists->FindChild(Form("Tracks_%d", il)));
153       trackList->ElementChanged();
154     } 
155   }
156
157   if(fPointSetVertex) fPointSetVertex->ResetBBox();
158   if(fTrCanvas) fTrCanvas->Update();
159   if(fVertexCanvas) fVertexCanvas->Update();
160   if(fCanvas) fCanvas->Update();
161   
162 }
163
164 ///_________________________________________________________________________________
165 void AliHLTEveHLT::ResetElements(){
166   //See header file for documentation
167   
168   cout << "destroy"<<endl;
169
170   if(fTrackLists) {
171     for(Int_t il = 0; il < fNTrackBins; il++) {
172       TEveTrackList * trackList = dynamic_cast<TEveTrackList*>(fTrackLists->FindChild(Form("Tracks_%d", il)));
173       trackList->DestroyElements();
174     } 
175   }
176
177   
178   fTrCount = 0;
179   fVCount = 0;
180
181   if(fPointSetVertex) fPointSetVertex->Reset();
182   cout<< "reset done"<<endl;
183   fHistoCount = 0;
184
185 }
186
187 ///_____________________________________________________________________________________
188 void * AliHLTEveHLT::DestroyGarbage(void * arg) {
189   AliHLTEveHLT * hlt = reinterpret_cast<AliHLTEveHLT*>(arg);
190   if(hlt) hlt->DestroyOldTrackList();
191   return (void*)0;
192 }
193 ///_____________________________________________________________________________________
194 void AliHLTEveHLT::DestroyOldTrackList() {
195   cout << "Destroying the old tracklist's elements"<<endl;
196   fOldTrackList->DestroyElements();
197   cout << "Destroying the old tracklist itself"<<endl;
198   fOldTrackList->Destroy();
199 }
200
201 ///_____________________________________________________________________________________
202 void AliHLTEveHLT::ProcessHistograms(AliHLTHOMERBlockDesc * block, TCanvas * canvas) {
203   //See header file for documentation
204   if (!fTrCanvas) {
205     fTrCanvas = CreateCanvas("ESD", "ESD");
206     fTrCanvas->Divide(4, 2);
207   }
208
209   if(!fVertexCanvas) {
210     fVertexCanvas = CreateCanvas("Vtx", "Vtx");
211     fVertexCanvas->Divide(4, 2);
212   }
213
214
215
216   if ( ! block->GetClassName().CompareTo("TH1F")) {
217     TH1F* histo = reinterpret_cast<TH1F*>(block->GetTObject());
218     if( histo ){
219       TString name(histo->GetName());
220       cout << "TH1F " <<name << endl;
221       if( !name.CompareTo("primVertexZ") ){
222         canvas->cd(2);
223         histo->Draw();
224       }else if( !name.CompareTo("primVertexX") ){
225         canvas->cd(3);
226         histo->Draw();
227       }else if( !name.CompareTo("primVertexY") ){
228         canvas->cd(4);
229         histo->Draw();
230       } else if ( name.Contains("Track")) {
231         AddHistogramToCanvas(histo, fTrCanvas, fTrCount);
232       } else {
233         AddHistogramToCanvas(histo, fVertexCanvas, fVCount);
234       }
235     }
236   }  else if ( ! block->GetClassName().CompareTo("TH2F")) {
237     TH2F *hista = reinterpret_cast<TH2F*>(block->GetTObject());
238     if (hista ){
239        TString name(hista->GetName());
240        cout << "TH2F " << name << endl;
241        if( !name.CompareTo("primVertexXY")) {      
242          canvas->cd(1);
243          hista->Draw();
244        } else if ( name.Contains("Track")) {
245         AddHistogramToCanvas(hista, fTrCanvas, fTrCount);
246       } else {
247         AddHistogramToCanvas(hista, fVertexCanvas, fVCount);
248       }
249     }
250   }
251   canvas->cd();
252 }
253
254 ///_____________________________________________________________________________________
255 void AliHLTEveHLT::AddHistogramToCanvas(TH1* histogram, TCanvas * canvas, Int_t &cdCount) {
256   canvas->cd(++cdCount);
257   histogram->Draw();
258 }
259
260
261 ///________________________________________________________________________________________
262 void AliHLTEveHLT::CreateTrackList() {
263   //See header file for documentation
264   fTrackList = new TEveTrackList("ESD Tracks");
265   fTrackList->SetMainColor(kOrange);
266   AddElement(fTrackList);
267 }
268
269 ///________________________________________________________________________________________
270 void AliHLTEveHLT::CreateTrackLists() {
271   //See header file for documentation
272   fTrackLists = new TEveElementList("ESD Track lists");
273   AddElement(fTrackLists);
274   for(Int_t i = 0; i < 10; i++) {
275     TEveTrackList * trackList = new TEveTrackList(Form("Tracks_%d", i));
276     trackList->SetMainColor(kOrange-i);
277     fTrackLists->AddElement(trackList);
278   }
279 }
280
281
282 ///_________________________________________________________________________________________
283 void AliHLTEveHLT::CreateVertexPointSet() {
284   //See header file for documentation
285   fPointSetVertex = new TEvePointSet("Primary Vertex");
286   fPointSetVertex->SetMainColor(6);
287   fPointSetVertex->SetMarkerStyle((Style_t)kFullStar);
288
289   AddElement(fPointSetVertex);
290 }
291
292 ///________________________________________________________________________
293 void AliHLTEveHLT::ProcessGlobalTrigger( AliHLTHOMERBlockDesc * block ) {
294   //See header file for documentation
295   AliHLTGlobalTriggerDecision * decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(block->GetTObject());
296   decision->Print();
297
298 }
299
300
301 ///______________________________________________________________________
302 void AliHLTEveHLT::ProcessEsdBlock( AliHLTHOMERBlockDesc * block) {
303   //See header file for documentation
304
305   AliESDEvent* esd = (AliESDEvent *) (block->GetTObject());
306   if (!esd) return;
307   
308   ProcessEsdEvent(esd);
309 }
310
311
312
313 ///_________________________________________________________________________________
314 Color_t AliHLTEveHLT::GetColor(Float_t pt) {
315   //See header file
316   Color_t baseColor = kOrange;
317   
318   Float_t binlimit = 0.1;
319   for(Int_t i = 0; i< 10; i++) {
320    
321     if (pt < binlimit)
322       return baseColor - i;
323     
324     binlimit +=0.1;
325   }
326   
327   return baseColor - 9;
328
329 }
330
331 ///_________________________________________________________________________________
332 Int_t AliHLTEveHLT::GetColorBin(Float_t pt) {
333   //See header file
334   
335   Float_t binlimit = 0.1;
336   for(Int_t i = 0; i< 10; i++) {
337    
338     if (pt < binlimit)
339       return i;
340     
341     binlimit +=0.1;
342   }
343   
344   return 9;
345   
346 }
347
348 ///____________________________________________________________________
349 void AliHLTEveHLT::ProcessEsdEvent( AliESDEvent * esd ) {
350   //See header file for documentation
351   if(!fPointSetVertex) CreateVertexPointSet();
352   if(!fTrackLists) CreateTrackLists();
353
354   cout << "ProcessESDEvent() :"<< esd->GetEventNumberInFile()<< "  " << esd->GetNumberOfCaloClusters() << " tracks : " << esd->GetNumberOfTracks() << endl;
355
356   //fEventManager->SetRunNumber(esd->GetRunNumber());
357
358   Double_t vertex[3];
359   const AliESDVertex * esdVertex = esd->GetPrimaryVertex();
360   
361   if(esdVertex) {
362     esdVertex->GetXYZ(vertex);
363     fPointSetVertex->SetNextPoint(vertex[0], vertex[1], vertex[2]);
364   }
365   
366   SetUpTrackPropagator(dynamic_cast<TEveTrackList*>(fTrackLists->FirstChild())->GetPropagator(),-0.1*esd->GetMagneticField(), 520);
367
368   for (Int_t iter = 0; iter < esd->GetNumberOfTracks(); ++iter) {
369
370    AliESDtrack * esdTrack = dynamic_cast<AliESDtrack*>(esd->GetTrack(iter));
371    FillTrackList(esdTrack);
372    FillHistograms(esdTrack);
373    
374   }
375   fHistMult->Fill(esd->GetNumberOfTracks()); // KK
376   
377   //BALLE hardcoded size
378   for(Int_t il = 0; il < fNTrackBins; il++) {
379     TEveTrackList * trackList = dynamic_cast<TEveTrackList*>(fTrackLists->FindChild(Form("Tracks_%d", il)));
380     trackList->MakeTracks();
381   } 
382 }
383 ///__________________________________________________________________________
384 void AliHLTEveHLT::FillTrackList(AliESDtrack * esdTrack) {
385   //See header file for documentation
386   AliEveTrack* track = dynamic_cast<AliEveTrack*>(MakeEsdTrack(esdTrack, dynamic_cast<TEveTrackList*>(fTrackLists->FirstChild())));        
387   Int_t bin = GetColorBin(esdTrack->Pt());
388   TEveTrackList * trackList = dynamic_cast<TEveTrackList*>(fTrackLists->FindChild(Form("Tracks_%d", bin)));
389   if(trackList) {
390     track->SetAttLineAttMarker(trackList);
391     trackList->AddElement(track);
392   } else cout << "BALLE"<<endl;
393
394
395 }
396
397
398 ///____________________________________________________________________________________
399 void AliHLTEveHLT::FillHistograms(AliESDtrack * esdTrack) {
400
401   if(esdTrack->GetTPCNcls() == 0) return;
402   
403   fHistEta->Fill(esdTrack->Eta());
404   // fHistTheta->Fill(esdTrack->Theta()*TMath::RadToDeg());
405   fHistPhi->Fill(esdTrack->Phi()*TMath::RadToDeg());
406   
407   
408   Float_t DCAr, DCAz = -99;
409   esdTrack->GetImpactParametersTPC(DCAr, DCAz);
410   fHistDCAr->Fill(DCAr);
411   
412   
413   if(esdTrack->GetStatus()&AliESDtrack::kTPCin || (esdTrack->GetStatus()&AliESDtrack::kTPCin && esdTrack->GetStatus()&AliESDtrack::kITSin)){
414     fHistnClusters->Fill(esdTrack->GetTPCNcls());  
415   }
416 }
417
418 void AliHLTEveHLT::DrawHistograms(){
419   //See header file for documentation
420   if(!fCanvas) {
421     fCanvas = CreateCanvas("PVtx/Tr QA", "Primary vertex, Track QA");
422     fCanvas->Divide(3, 3);
423   }
424
425   fCanvas->cd(5);
426   fHistEta->Draw();
427
428   fCanvas->cd(6);
429   fHistPhi->Draw();
430
431   fCanvas->cd(7);
432   fHistnClusters->Draw();
433
434   fCanvas->cd(8);
435   fHistMult->Draw();
436
437   fCanvas->cd(9);
438   fHistDCAr->Draw();
439
440   fCanvas->cd();
441
442 }
443
444 AliEveTrack* AliHLTEveHLT::MakeEsdTrack (AliESDtrack *at, TEveTrackList* cont) {
445   //See header file for documentation
446   
447     
448
449
450
451   const double kCLight = 0.000299792458;
452   double bz = - kCLight*10.*( cont->GetPropagator()->GetMagField(0,0,0).fZ);
453
454   Bool_t innerTaken = kFALSE;
455   if ( ! at->IsOn(AliESDtrack::kITSrefit) && fUseIpOnFailedITS)
456   {
457     //tp = at->GetInnerParam();
458     innerTaken = kTRUE;
459   }
460
461   // Add inner/outer track parameters as path-marks.
462
463   Double_t     pbuf[3], vbuf[3];
464
465   AliExternalTrackParam trackParam = *at;
466
467   // take parameters constrained to vertex (if they are)
468
469   if( at->GetConstrainedParam() ){
470     trackParam = *at->GetConstrainedParam();
471   }
472   else if( at->GetInnerParam() ){
473     trackParam = *(at->GetInnerParam());
474   }
475   if( at->GetStatus()&AliESDtrack::kTRDin ){
476     // transport to TRD in
477     trackParam = *at;
478     trackParam.PropagateTo( 290.45, -10.*( cont->GetPropagator()->GetMagField(0,0,0).fZ) );
479   }
480
481   TEveRecTrack rt;
482   {
483     rt.fLabel  = at->GetLabel();
484     rt.fIndex  = (Int_t) at->GetID();
485     rt.fStatus = (Int_t) at->GetStatus();
486     rt.fSign   = (Int_t) trackParam.GetSign();  
487     trackParam.GetXYZ(vbuf);
488     trackParam.GetPxPyPz(pbuf);    
489     rt.fV.Set(vbuf);
490     rt.fP.Set(pbuf);
491     Double_t ep = at->GetP(), mc = at->GetMass();
492     rt.fBeta = ep/TMath::Sqrt(ep*ep + mc*mc);
493   }
494
495   AliEveTrack* track = new AliEveTrack(&rt, cont->GetPropagator());
496   track->SetName(Form("AliEveTrack %d", at->GetID()));
497   track->SetElementTitle(CreateTrackTitle(at));
498   track->SetSourceObject(at);
499
500
501   // Set reference points along the trajectory
502   // and the last point
503
504   { 
505     TEvePathMark startPoint(TEvePathMark::kReference);
506     trackParam.GetXYZ(vbuf);
507     trackParam.GetPxPyPz(pbuf);    
508     startPoint.fV.Set(vbuf);
509     startPoint.fP.Set(pbuf);
510     rt.fV.Set(vbuf);
511     rt.fP.Set(pbuf);
512     Double_t ep = at->GetP(), mc = at->GetMass();
513     rt.fBeta = ep/TMath::Sqrt(ep*ep + mc*mc);
514
515     track->AddPathMark( startPoint );    
516   }
517
518   bool ok = 1;
519   if( at->GetOuterParam() && at->GetTPCPoints(2)>80 ){
520
521     //
522     // use AliHLTTPCCATrackParam propagator 
523     // since AliExternalTrackParam:PropagateTo()
524     // has an offset at big distances
525     //
526     double rot = at->GetOuterParam()->GetAlpha() - trackParam.GetAlpha();
527     double crot = cos(rot), srot = sin(rot);
528     double xEnd = at->GetTPCPoints(2)*crot -  at->GetTPCPoints(3)*srot;
529   // take parameters constrained to vertex (if they are)
530  
531
532     AliHLTTPCCATrackParam t;
533     AliHLTTPCCATrackConvertor::SetExtParam( t, trackParam );
534     
535     Double_t x0 = trackParam.GetX();
536     Double_t dx = xEnd - x0;
537     
538     if( dx<0 ) ok = 0;
539     //
540     // set a reference at the half of trajectory for better drawing
541     //
542     
543     for( double dxx=dx/2; ok && TMath::Abs(dxx)>=1.; dxx*=.9 ){
544
545       if( !t.TransportToX(x0+dxx, bz, .999 ) ){
546         ok = 0;
547         break;
548         continue;
549       }
550       AliExternalTrackParam tt;
551       AliHLTTPCCATrackConvertor::GetExtParam( t, tt, trackParam.GetAlpha() ); 
552       tt.GetXYZ(vbuf);
553       tt.GetPxPyPz(pbuf);
554       TEvePathMark midPoint(TEvePathMark::kReference);
555       midPoint.fV.Set(vbuf);
556       midPoint.fP.Set(pbuf);    
557       track->AddPathMark( midPoint );
558       break;
559     }
560  
561    
562     //
563     // Set a reference at the end of the trajectory
564     // and a "decay point", to let the event display know where the track ends
565     //
566     
567     for( ; ok; dx*=.9 ){
568
569       if( !t.TransportToX(x0+dx, bz, .999 ) ){
570         ok = 0; 
571         break;
572         if( TMath::Abs(dx)<1. ) break;      
573         continue;
574       }
575       break;
576     }
577
578     {
579       if( !ok ){ 
580         AliHLTTPCCATrackConvertor::SetExtParam( t, trackParam );
581       }
582       AliExternalTrackParam tt;
583       AliHLTTPCCATrackConvertor::GetExtParam( t, tt, trackParam.GetAlpha() ); 
584       tt.GetXYZ(vbuf);
585       tt.GetPxPyPz(pbuf);
586       TEvePathMark endPoint(TEvePathMark::kReference);
587       TEvePathMark decPoint(TEvePathMark::kDecay);
588       endPoint.fV.Set(vbuf);
589       endPoint.fP.Set(pbuf);
590       decPoint.fV.Set(vbuf);
591       decPoint.fP.Set(pbuf);
592       track->AddPathMark( endPoint );
593       track->AddPathMark( decPoint );
594     }  
595   }
596
597   if ( ok &&  at->IsOn(AliESDtrack::kTPCrefit))
598   {
599     if ( ! innerTaken)
600     {
601       AddTrackParamToTrack(track, at->GetInnerParam());
602     }
603     AddTrackParamToTrack(track, at->GetOuterParam());
604   }
605   
606   return track;
607 }
608
609 void AliHLTEveHLT::SetUpTrackPropagator(TEveTrackPropagator* trkProp, Float_t magF, Float_t maxR) {
610   //See header file for documentation
611
612   if (fTrueField) {
613     trkProp->SetMagFieldObj(new AliEveMagField);
614   
615   } else {
616     trkProp->SetMagField(magF);
617   }
618  
619   if (fUseRkStepper) {
620     trkProp->SetStepper(TEveTrackPropagator::kRungeKutta);
621   }
622
623   trkProp->SetMaxR(maxR);
624 }
625
626
627 void AliHLTEveHLT::AddTrackParamToTrack(AliEveTrack* track, const AliExternalTrackParam* tp) {
628   //See header file for documentation
629
630   if (tp == 0)
631     return;
632
633   Double_t pbuf[3], vbuf[3];
634   tp->GetXYZ(vbuf);
635   tp->GetPxPyPz(pbuf);
636
637   TEvePathMark pm(TEvePathMark::kReference);
638   pm.fV.Set(vbuf);
639   pm.fP.Set(pbuf);
640   track->AddPathMark(pm);
641 }
642
643
644
645 TString AliHLTEveHLT::CreateTrackTitle(AliESDtrack* t) {
646   // Add additional track parameters as a path-mark to track.
647
648   TString s;
649
650   Int_t label = t->GetLabel(), index = t->GetID();
651   TString idx(index == kMinInt ? "<undef>" : Form("%d", index));
652   TString lbl(label == kMinInt ? "<undef>" : Form("%d", label));
653
654   Double_t p[3], v[3];
655   t->GetXYZ(v);
656   t->GetPxPyPz(p);
657   Double_t pt    = t->Pt();
658   Double_t ptsig = TMath::Sqrt(t->GetSigma1Pt2());
659   Double_t ptsq  = pt*pt;
660   Double_t ptm   = pt / (1.0 + pt*ptsig);
661   Double_t ptM   = pt / (1.0 - pt*ptsig);
662
663   s = Form("Index=%s, Label=%s\nChg=%d, Pdg=%d\n"
664            "pT = %.3f + %.3f - %.3f [%.3f]\n"
665            "P  = (%.3f, %.3f, %.3f)\n"
666            "V  = (%.3f, %.3f, %.3f)\n",
667            idx.Data(), lbl.Data(), t->Charge(), 0,
668            pt, ptM - pt, pt - ptm, ptsig*ptsq,
669            p[0], p[1], p[2],
670            v[0], v[1], v[2]);
671
672   Int_t   o;
673   s += "Det (in,out,refit,pid):\n";
674   o  = AliESDtrack::kITSin;
675   s += Form("ITS (%d,%d,%d,%d)  ",  t->IsOn(o), t->IsOn(o<<1), t->IsOn(o<<2), t->IsOn(o<<3));
676   o  = AliESDtrack::kTPCin;
677   s += Form("TPC(%d,%d,%d,%d)\n",   t->IsOn(o), t->IsOn(o<<1), t->IsOn(o<<2), t->IsOn(o<<3));
678   o  = AliESDtrack::kTRDin;
679   s += Form("TRD(%d,%d,%d,%d) ",    t->IsOn(o), t->IsOn(o<<1), t->IsOn(o<<2), t->IsOn(o<<3));
680   o  = AliESDtrack::kTOFin;
681   s += Form("TOF(%d,%d,%d,%d)\n",   t->IsOn(o), t->IsOn(o<<1), t->IsOn(o<<2), t->IsOn(o<<3));
682   o  = AliESDtrack::kHMPIDout;
683   s += Form("HMPID(out=%d,pid=%d)\n", t->IsOn(o), t->IsOn(o<<1));
684   s += Form("ESD pid=%d", t->IsOn(AliESDtrack::kESDpid));
685
686   if (t->IsOn(AliESDtrack::kESDpid))
687   {
688     Double_t pid[5];
689     t->GetESDpid(pid);
690     s += Form("\n[%.2f %.2f %.2f %.2f %.2f]", pid[0], pid[1], pid[2], pid[3], pid[4]);
691   }
692
693   return s;
694 }
695
696