78d81ce58517404a437db3eec43154ed27517d9b
[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     float x = at->GetX();
474     float y = at->GetY();
475     if(sqrt(x*x+y*y)>.5 ) trackParam = *(at->GetInnerParam());
476   }
477   if( at->GetStatus()&AliESDtrack::kTRDin ){
478     // transport to TRD in
479     trackParam = *at;
480     trackParam.PropagateTo( 290.45, -10.*( cont->GetPropagator()->GetMagField(0,0,0).fZ) );
481   }
482
483   TEveRecTrack rt;
484   {
485     rt.fLabel  = at->GetLabel();
486     rt.fIndex  = (Int_t) at->GetID();
487     rt.fStatus = (Int_t) at->GetStatus();
488     rt.fSign   = (Int_t) trackParam.GetSign();  
489     trackParam.GetXYZ(vbuf);
490     trackParam.GetPxPyPz(pbuf);    
491     rt.fV.Set(vbuf);
492     rt.fP.Set(pbuf);
493     Double_t ep = at->GetP(), mc = at->GetMass();
494     rt.fBeta = ep/TMath::Sqrt(ep*ep + mc*mc);
495   }
496
497   AliEveTrack* track = new AliEveTrack(&rt, cont->GetPropagator());
498   track->SetName(Form("AliEveTrack %d", at->GetID()));
499   track->SetElementTitle(CreateTrackTitle(at));
500   track->SetSourceObject(at);
501
502
503   // Set reference points along the trajectory
504   // and the last point
505
506   { 
507     TEvePathMark startPoint(TEvePathMark::kReference);
508     trackParam.GetXYZ(vbuf);
509     trackParam.GetPxPyPz(pbuf);    
510     startPoint.fV.Set(vbuf);
511     startPoint.fP.Set(pbuf);
512     rt.fV.Set(vbuf);
513     rt.fP.Set(pbuf);
514     Double_t ep = at->GetP(), mc = at->GetMass();
515     rt.fBeta = ep/TMath::Sqrt(ep*ep + mc*mc);
516
517     track->AddPathMark( startPoint );    
518   }
519
520   bool ok = 1;
521   if( at->GetOuterParam() && at->GetTPCPoints(2)>80 ){
522
523     //
524     // use AliHLTTPCCATrackParam propagator 
525     // since AliExternalTrackParam:PropagateTo()
526     // has an offset at big distances
527     //
528     double rot = at->GetOuterParam()->GetAlpha() - trackParam.GetAlpha();
529     double crot = cos(rot), srot = sin(rot);
530     double xEnd = at->GetTPCPoints(2)*crot -  at->GetTPCPoints(3)*srot;
531   // take parameters constrained to vertex (if they are)
532  
533
534     AliHLTTPCCATrackParam t;
535     AliHLTTPCCATrackConvertor::SetExtParam( t, trackParam );
536     
537     Double_t x0 = trackParam.GetX();
538     Double_t dx = xEnd - x0;
539     
540     if( dx<0 ) ok = 0;
541     //
542     // set a reference at the half of trajectory for better drawing
543     //
544     
545     for( double dxx=dx/2; ok && TMath::Abs(dxx)>=1.; dxx*=.9 ){
546
547       if( !t.TransportToX(x0+dxx, bz, .999 ) ){
548         ok = 0;
549         break;
550         continue;
551       }
552       AliExternalTrackParam tt;
553       AliHLTTPCCATrackConvertor::GetExtParam( t, tt, trackParam.GetAlpha() ); 
554       tt.GetXYZ(vbuf);
555       tt.GetPxPyPz(pbuf);
556       TEvePathMark midPoint(TEvePathMark::kReference);
557       midPoint.fV.Set(vbuf);
558       midPoint.fP.Set(pbuf);    
559       track->AddPathMark( midPoint );
560       break;
561     }
562  
563    
564     //
565     // Set a reference at the end of the trajectory
566     // and a "decay point", to let the event display know where the track ends
567     //
568     
569     for( ; ok; dx*=.9 ){
570
571       if( !t.TransportToX(x0+dx, bz, .999 ) ){
572         ok = 0; 
573         break;
574         if( TMath::Abs(dx)<1. ) break;      
575         continue;
576       }
577       break;
578     }
579
580     {
581       if( !ok ){ 
582         AliHLTTPCCATrackConvertor::SetExtParam( t, trackParam );
583       }
584       AliExternalTrackParam tt;
585       AliHLTTPCCATrackConvertor::GetExtParam( t, tt, trackParam.GetAlpha() ); 
586       tt.GetXYZ(vbuf);
587       tt.GetPxPyPz(pbuf);
588       TEvePathMark endPoint(TEvePathMark::kReference);
589       TEvePathMark decPoint(TEvePathMark::kDecay);
590       endPoint.fV.Set(vbuf);
591       endPoint.fP.Set(pbuf);
592       decPoint.fV.Set(vbuf);
593       decPoint.fP.Set(pbuf);
594       track->AddPathMark( endPoint );
595       track->AddPathMark( decPoint );
596     }  
597   }
598
599   if ( ok &&  at->IsOn(AliESDtrack::kTPCrefit))
600   {
601     if ( ! innerTaken)
602     {
603       AddTrackParamToTrack(track, at->GetInnerParam());
604     }
605     AddTrackParamToTrack(track, at->GetOuterParam());
606   }
607   
608   return track;
609 }
610
611 void AliHLTEveHLT::SetUpTrackPropagator(TEveTrackPropagator* trkProp, Float_t magF, Float_t maxR) {
612   //See header file for documentation
613
614   if (fTrueField) {
615     trkProp->SetMagFieldObj(new AliEveMagField);
616   
617   } else {
618     trkProp->SetMagField(magF);
619   }
620  
621   if (fUseRkStepper) {
622     trkProp->SetStepper(TEveTrackPropagator::kRungeKutta);
623   }
624
625   trkProp->SetMaxR(maxR);
626 }
627
628
629 void AliHLTEveHLT::AddTrackParamToTrack(AliEveTrack* track, const AliExternalTrackParam* tp) {
630   //See header file for documentation
631
632   if (tp == 0)
633     return;
634
635   Double_t pbuf[3], vbuf[3];
636   tp->GetXYZ(vbuf);
637   tp->GetPxPyPz(pbuf);
638
639   TEvePathMark pm(TEvePathMark::kReference);
640   pm.fV.Set(vbuf);
641   pm.fP.Set(pbuf);
642   track->AddPathMark(pm);
643 }
644
645
646
647 TString AliHLTEveHLT::CreateTrackTitle(AliESDtrack* t) {
648   // Add additional track parameters as a path-mark to track.
649
650   TString s;
651
652   Int_t label = t->GetLabel(), index = t->GetID();
653   TString idx(index == kMinInt ? "<undef>" : Form("%d", index));
654   TString lbl(label == kMinInt ? "<undef>" : Form("%d", label));
655
656   Double_t p[3], v[3];
657   t->GetXYZ(v);
658   t->GetPxPyPz(p);
659   Double_t pt    = t->Pt();
660   Double_t ptsig = TMath::Sqrt(t->GetSigma1Pt2());
661   Double_t ptsq  = pt*pt;
662   Double_t ptm   = pt / (1.0 + pt*ptsig);
663   Double_t ptM   = pt / (1.0 - pt*ptsig);
664
665   s = Form("Index=%s, Label=%s\nChg=%d, Pdg=%d\n"
666            "pT = %.3f + %.3f - %.3f [%.3f]\n"
667            "P  = (%.3f, %.3f, %.3f)\n"
668            "V  = (%.3f, %.3f, %.3f)\n",
669            idx.Data(), lbl.Data(), t->Charge(), 0,
670            pt, ptM - pt, pt - ptm, ptsig*ptsq,
671            p[0], p[1], p[2],
672            v[0], v[1], v[2]);
673
674   Int_t   o;
675   s += "Det (in,out,refit,pid):\n";
676   o  = AliESDtrack::kITSin;
677   s += Form("ITS (%d,%d,%d,%d)  ",  t->IsOn(o), t->IsOn(o<<1), t->IsOn(o<<2), t->IsOn(o<<3));
678   o  = AliESDtrack::kTPCin;
679   s += Form("TPC(%d,%d,%d,%d)\n",   t->IsOn(o), t->IsOn(o<<1), t->IsOn(o<<2), t->IsOn(o<<3));
680   o  = AliESDtrack::kTRDin;
681   s += Form("TRD(%d,%d,%d,%d) ",    t->IsOn(o), t->IsOn(o<<1), t->IsOn(o<<2), t->IsOn(o<<3));
682   o  = AliESDtrack::kTOFin;
683   s += Form("TOF(%d,%d,%d,%d)\n",   t->IsOn(o), t->IsOn(o<<1), t->IsOn(o<<2), t->IsOn(o<<3));
684   o  = AliESDtrack::kHMPIDout;
685   s += Form("HMPID(out=%d,pid=%d)\n", t->IsOn(o), t->IsOn(o<<1));
686   s += Form("ESD pid=%d", t->IsOn(AliESDtrack::kESDpid));
687
688   if (t->IsOn(AliESDtrack::kESDpid))
689   {
690     Double_t pid[5];
691     t->GetESDpid(pid);
692     s += Form("\n[%.2f %.2f %.2f %.2f %.2f]", pid[0], pid[1], pid[2], pid[3], pid[4]);
693   }
694
695   return s;
696 }
697
698