AliHLTTPCSpacePointData:
[u/mrichter/AliRoot.git] / HLT / TPCLib / AliHLTTPCDisplay.cxx
1 // @(#) $Id$
2
3 /** \class AliHLTTPCDisplay
4 <pre>
5 //_____________________________________________________________
6 // AliHLTTPCDisplay
7 //
8 // Display class for the HLT TPC events.
9 </pre>
10 */
11 // Author: Jochen Thaeder <mailto:thaeder@kip.uni-heidelberg.de>
12 //         Anders Vestbo <mailto:vestbo@fi.uib.no>      
13 //*-- Copyright &copy ALICE HLT Group 
14
15
16 // Recent Changes:
17 // ==============
18 // - Rename and Merge of functions / Complete new arrangement in order to use the AliHLTGUI
19 // - 3D Geometry
20 //   - display padrows, cluster, tracks
21 //   - select single Tracks
22 //   - select used / unused cluster
23 // - Histogram
24 //   - display padrows
25 //   - display pads in padrows
26
27 #include "AliHLTTPCStandardIncludes.h"
28 #include <TView.h>
29 #include <TPolyMarker3D.h>
30 #include <TPolyLine3D.h>
31 #include <TH2.h>
32 #include <TTree.h>
33 #include <TNode.h>
34 #include <TGeometry.h>
35 #include <TShape.h>
36 #include <TParticle.h>
37 #include <TFile.h>
38 #include <THelix.h>
39 #include <TStyle.h>
40
41 #ifdef use_aliroot
42 #include <TClonesArray.h>
43 #include <AliRun.h>
44 #include <AliSimDigits.h>
45 #include <AliTPCParam.h>
46 #endif
47
48 #include "AliHLTTPCLogging.h"
49 #include "AliHLTTPCDisplay.h"
50 #include "AliHLTTPCTransform.h"
51 #include "AliHLTTPCTrack.h"
52 #include "AliHLTTPCTrackArray.h"
53 #include "AliHLTTPCSpacePointData.h"
54 #include "AliHLTTPCMemHandler.h"
55 #include "AliHLTTPCDigitReaderPacked.h"
56
57 #if __GNUC__ == 3
58 using namespace std;
59 #endif
60
61 ClassImp(AliHLTTPCDisplay)
62
63 // #############################################################################
64 AliHLTTPCDisplay::AliHLTTPCDisplay(Char_t *gfile) {
65     //constructor
66     memset(fClusters,0,36*6*sizeof(AliHLTTPCSpacePointData*));
67     memset(fNcl, 0, 36*6*sizeof(UInt_t)); 
68
69     fTracks = NULL;
70     fHistrawcl = NULL;
71     fHistraw = NULL;
72     fHistpad1 = NULL;
73     fHistpad2 = NULL;
74     fHistpad3 = NULL;
75
76     fGeom = NULL;
77
78     fNPads = 0;
79     fNTimes = 0;
80     fMinHits = 0;
81     fPtThreshold = 0.;
82     fPad = -1;
83     fPadRow = 0;
84     fSlicePadRow = 0; 
85     fSelectTrack = -1;
86     fSelectTrackSlice = 0;
87     fSelectTrackSwitch = kFALSE;
88     fSelectCluster = 0;
89
90     fMinSlice = 0;
91     fMaxSlice = 35;
92     fSlicePair = kFALSE;
93
94     SetSliceArray();
95
96     fBackColor = 1; 
97     fLineColor = 0;
98
99     fSwitch3DCluster = kFALSE;
100     fSwitch3DTracks = kFALSE;
101     fSwitch3DPadRow = kFALSE;
102     fSwitch3DGeometry = kFALSE;
103
104     //ctor. Specify which slices you want to look at.
105     LoadGeometrie(gfile);
106 }
107
108
109 // #############################################################################
110 AliHLTTPCDisplay::~AliHLTTPCDisplay() {
111     //destructor
112     if(fTracks) delete fTracks;
113     fTracks = NULL;
114 }
115
116 // #############################################################################
117 Bool_t AliHLTTPCDisplay::LoadGeometrie(Char_t *gfile) {
118     if (gfile) {
119         TFile *file = TFile::Open(gfile);
120         if(!file) {
121             LOG(AliHLTTPCLog::kError,"AliHLTTPCDisplay::AliHLTTPCDisplay","File Open") <<"Geometry file " << gfile << " does not exist!"<<ENDLOG;
122             return kFALSE;
123         }
124         
125         fGeom = (TGeometry*)file->Get("AliceGeom");
126
127         file->Close();
128         delete file;
129     }
130     return kTRUE;
131 }
132
133 // #############################################################################
134 //                 SETTER
135 // #############################################################################
136 void AliHLTTPCDisplay::SetHistPadRowAxis() {
137     // Set Axis range of Histogramm, due to variable NPads per padrow
138
139     fNPads = AliHLTTPCTransform::GetNPads(fPadRow);
140     fHistrawcl->SetAxisRange(0,fNPads);
141     fHistraw->SetAxisRange(0,fNPads);
142     fHistrawcl->SetAxisRange(0,fNTimes,"Y");
143     fHistraw->SetAxisRange(0,fNTimes,"Y");
144 }
145
146 void AliHLTTPCDisplay::SetSliceArray() {
147     Int_t slice=0;
148     Int_t minSlice = fMinSlice; 
149     Int_t maxSlice = fMaxSlice; 
150     Int_t realslice = 0;
151
152     for (slice=0;slice<=35;slice++){
153         fSliceArray[slice] = kFALSE;
154     }
155
156     // Single Slice, or Range
157     if (minSlice > maxSlice) maxSlice += 17;
158         
159     for (slice=minSlice;slice<=maxSlice;slice++){
160         realslice = slice % 18;
161         fSliceArray[realslice] = kTRUE;
162         fSliceArray[realslice+18] = kTRUE;
163     }
164
165     // Pair of Slices
166     if (fSlicePair) {
167         minSlice = fMinSlice + 9;
168         maxSlice = fMaxSlice + 9;
169         
170         if (minSlice > maxSlice) maxSlice += 17;
171         
172         for (slice=minSlice;slice<=maxSlice;slice++){
173             realslice = slice % 18;
174             fSliceArray[realslice] = kTRUE;     
175             fSliceArray[realslice+18] = kTRUE;
176         }
177     }
178 }
179
180 // #############################################################################
181 //                 SETUP
182 // #############################################################################
183 void AliHLTTPCDisplay::SetupCluster(Int_t slice, Int_t patch, UInt_t nofClusters, AliHLTTPCSpacePointData* data)  {  
184
185     if (data && slice>=0 && slice<36 && patch>=0 && patch<AliHLTTPCTransform::GetNPatches()) {
186         if (fClusters[slice][patch]!=NULL) {
187             delete(fClusters[slice][patch]);
188             fClusters[slice][patch]=NULL;
189         }
190         Int_t arraysize=nofClusters*sizeof(AliHLTTPCSpacePointData);
191         fClusters[slice][patch] = (AliHLTTPCSpacePointData*)new Byte_t[arraysize];
192         if (fClusters[slice][patch]) {
193             memcpy(fClusters[slice][patch], data, arraysize);
194             fNcl[slice][patch]=nofClusters;
195         } else {
196             fNcl[slice][patch]=nofClusters;
197             LOG(AliHLTTPCLog::kError,"AliHLTTPCDisplay::SetupCluster","memory allocation") << "memory allocation failed "<<ENDLOG; 
198         }
199     } else LOG(AliHLTTPCLog::kError,"AliHLTTPCDisplay::SetupCluster","argument check") << "invalid argument "<<ENDLOG; 
200 }
201
202 // #############################################################################
203 void AliHLTTPCDisplay::SetupTracks(AliHLTTPCTrackArray *tracks) {
204     fTracks=tracks;
205
206     // Set USED cluster
207     Int_t ntracks = fTracks->GetNTracks();
208
209     for(Int_t j=0; j<ntracks; j++) {    
210         AliHLTTPCTrack *gtrack = fTracks->GetCheckedTrack(j); 
211         if(!gtrack) continue;
212
213         Int_t nHits = gtrack->GetNHits();
214         UInt_t *hitnum = gtrack->GetHitNumbers();
215
216         for(Int_t h=0; h<nHits; h++){
217           
218             UInt_t id=hitnum[h];
219             Int_t slice = (id>>25) & 0x7f;
220             Int_t patch = (id>>22) & 0x7;
221             UInt_t pos = id&0x3fffff;       
222                 
223             AliHLTTPCSpacePointData *points = fClusters[slice][patch];
224             
225             if(!points) {
226                 LOG(AliHLTTPCLog::kError,"AliHLTTPCDisplay::Draw3D","Clusterarray") <<"No points at slice "<<slice<<" patch "<<patch<<" pos "<<pos<<ENDLOG;
227                 continue;
228             }
229  
230             if(pos>=fNcl[slice][patch]) {
231                 LOG(AliHLTTPCLog::kError,"AliHLTTPCDisplay::Draw3D","Clusterarray") <<"Pos is too large: pos "<<pos <<" ncl "<<fNcl[slice][patch]<<ENDLOG;
232                 continue;
233             }
234             points[pos].fUsed = kTRUE;
235         }
236     }
237 }
238
239 // #############################################################################
240 void AliHLTTPCDisplay::SetupHistPadRow(){
241
242     Int_t maxpads = 150;
243     fNTimes = AliHLTTPCTransform::GetNTimeBins();
244
245     if ( fHistraw ){
246         delete fHistraw;
247         fHistraw = NULL;
248     }
249     if ( fHistrawcl ){
250         delete fHistrawcl;
251         fHistrawcl = NULL;
252     }
253
254     if ( fHistpad1 ){
255         delete fHistpad1;
256         fHistpad1 = NULL;
257     }
258
259     if ( fHistpad2 ){
260         delete fHistpad2;
261         fHistpad2 = NULL;
262     }
263
264     if ( fHistpad3 ){
265         delete fHistpad3;
266         fHistpad3 = NULL;
267     }
268
269     // Setup the histograms
270     Int_t padbinning = maxpads*10;
271     fHistraw = new TH2F("fHistraw","Selected PadRow with found Clusters;Pad #;Timebin #",maxpads,0,maxpads-1,fNTimes,0,fNTimes-1);
272     fHistrawcl = new TH1F("fHistrawcl","",padbinning,0,maxpads-1);
273     fHistpad1 = new TH1F ("fHistpad1","Selected Pad -1;Timebin #",fNTimes,0,fNTimes-1);
274     fHistpad2 = new TH1F ("fHistpad2","Selected Pad;Timebin #",fNTimes,0,fNTimes-1); 
275     fHistpad3 = new TH1F ("fHistpad3","Selected Pad +1;Timebin #",fNTimes,0,fNTimes-1);
276
277     fHistraw->SetOption("COLZ"); 
278
279     gStyle->SetPalette(1);
280
281     SetHistPadRowAxis();
282 }
283
284 // ####################################################################################################
285 void AliHLTTPCDisplay::FillPadRow(Int_t patch, ULong_t dataBlock, ULong_t dataLen){
286     AliHLTTPCDigitReaderPacked* fDigitReader = new AliHLTTPCDigitReaderPacked();
287     bool readValue = true;
288     Int_t rowOffset = 0;
289
290     // Initialize RAW DATA
291     Int_t firstRow = AliHLTTPCTransform::GetFirstRow(patch);
292     Int_t lastRow = AliHLTTPCTransform::GetLastRow(patch);
293
294     // Outer sector, patches 2, 3, 4, 5 -  start counting in patch 2 with row 0
295     if ( patch >= 2 ) rowOffset = AliHLTTPCTransform::GetFirstRow( 2 );
296
297     // Initialize block for reading packed data
298     void* tmpdataBlock = (void*) dataBlock;
299     fDigitReader->InitBlock(tmpdataBlock,dataLen,firstRow,lastRow);
300
301     readValue = fDigitReader->Next();
302
303     if (!readValue){    
304         LOG(AliHLTTPCLog::kError,"AliHLTTPCDisplay::FillPadRow","Read first value") << "No value in data block" << ENDLOG;
305         return;
306     }
307     
308     // FILL PADROW 3D --- Initialize the colorbins
309     if (fSwitch3DPadRow){
310         for (UInt_t ii=0;ii < 20;ii++){
311             fbinct[ii] = 0;
312             fcolorbin[ii] = 0;
313         }
314
315         // read number of entries in colorbin
316         while ( readValue ){ 
317
318             Int_t row = fDigitReader->GetRow() + rowOffset;
319             
320             if (row == fPadRow){    
321                 UInt_t charge = fDigitReader->GetSignal();
322                 
323                 for (UInt_t ii=0;ii < 19;ii++){
324                     if ( charge > (ii*21) && charge <= ((ii*21) + 21) ) fcolorbin[ii]++;
325                 }
326                 // larger than 19 * 21  
327                 if (charge > 399 ) fcolorbin[19]++;
328             }
329
330             // read next value
331             readValue = fDigitReader->Next();
332       
333             if(!readValue) break; //No more value
334         } 
335         //Initialize fpmarr[color][3*colorbin[ii]]  
336         fpmarr[0] = new Float_t[fcolorbin[0]*3]; 
337         fpmarr[1] = new Float_t[fcolorbin[1]*3]; 
338         fpmarr[2] = new Float_t[fcolorbin[2]*3]; 
339         fpmarr[3] = new Float_t[fcolorbin[3]*3]; 
340         fpmarr[4] = new Float_t[fcolorbin[4]*3];  
341         fpmarr[5] = new Float_t[fcolorbin[5]*3]; 
342         fpmarr[6] = new Float_t[fcolorbin[6]*3]; 
343         fpmarr[7] = new Float_t[fcolorbin[7]*3]; 
344         fpmarr[8] = new Float_t[fcolorbin[8]*3]; 
345         fpmarr[9] = new Float_t[fcolorbin[9]*3]; 
346         fpmarr[10] = new Float_t[fcolorbin[10]*3]; 
347         fpmarr[11] = new Float_t[fcolorbin[11]*3]; 
348         fpmarr[12] = new Float_t[fcolorbin[12]*3]; 
349         fpmarr[13] = new Float_t[fcolorbin[13]*3]; 
350         fpmarr[14] = new Float_t[fcolorbin[14]*3]; 
351         fpmarr[15] = new Float_t[fcolorbin[15]*3]; 
352         fpmarr[16] = new Float_t[fcolorbin[16]*3]; 
353         fpmarr[17] = new Float_t[fcolorbin[17]*3]; 
354         fpmarr[18] = new Float_t[fcolorbin[18]*3]; 
355         fpmarr[19] = new Float_t[fcolorbin[19]*3]; 
356         
357         // Rewind the raw reader and fill the polymarker3D
358         fDigitReader->InitBlock(tmpdataBlock,dataLen,firstRow,lastRow);
359         
360         readValue = fDigitReader->Next();
361     } // END if (fSwitch3DPadRow)
362
363     // -- Fill Raw Data
364     while ( readValue ){ 
365
366         Int_t row = fDigitReader->GetRow() + rowOffset;
367
368         // select padrow to fill in histogramm
369         if (row == fPadRow){    
370             UChar_t pad = fDigitReader->GetPad();
371             UShort_t time = fDigitReader->GetTime();
372             UInt_t charge = fDigitReader->GetSignal();
373             Float_t xyz[3];
374             fHistraw->Fill(pad,time,charge);
375
376             if (pad == (fPad-1) ) fHistpad1->Fill(time,charge);
377             if (pad == fPad) fHistpad2->Fill(time,charge);
378             if (pad == (fPad+1) ) fHistpad3->Fill(time,charge);
379
380             if (fSwitch3DPadRow) {
381                 // Transform raw coordinates to local coordinates
382                 AliHLTTPCTransform::RawHLT2Global(xyz, fSlicePadRow, fPadRow, pad, time);
383
384                 for (UInt_t ii=0;ii < 19;ii++){
385                     if ( charge > (ii*21) && charge <= ((ii*21) + 21) ){
386                         fpmarr[ii][fbinct[ii]] = xyz[0];
387                         fpmarr[ii][fbinct[ii]+1] = xyz[1];
388                         fpmarr[ii][fbinct[ii]+2] = xyz[2];
389                         fbinct[ii] += 3;
390                     }
391                 }
392                 // larger than 19 * 21
393                 if (charge > 399 ) {
394                     fpmarr[19][fbinct[19]] = xyz[0];
395                     fpmarr[19][fbinct[19]+1] = xyz[1];
396                     fpmarr[19][fbinct[19]+2] = xyz[2];
397                     fbinct[19] += 3;
398                 }
399             } // END if (fSwitch3DPadRow)
400         
401         }
402         
403         // read next value
404         readValue = fDigitReader->Next();
405       
406         //Check where to stop:
407         if(!readValue) break; //No more value
408     } 
409     
410     if ( fDigitReader )
411         delete fDigitReader;
412     fDigitReader = NULL;
413
414     AliHLTTPCSpacePointData *points = fClusters[fSlicePadRow][patch];
415     if(!points) return;
416     Int_t npoints = fNcl[fSlicePadRow][patch];
417     
418     Float_t xyz[3];
419     for(Int_t i=0; i<npoints; i++){
420         xyz[0] = points[i].fX;
421         xyz[1] = points[i].fY;
422         xyz[2] = points[i].fZ;
423         
424         Int_t clrow = AliHLTTPCTransform::GetPadRow(xyz[0]);
425         // select padrow to fill in histogramm
426         if (clrow == fPadRow){
427             AliHLTTPCTransform::LocHLT2Raw(xyz, fSlicePadRow, fPadRow);
428             fHistrawcl->Fill(xyz[1],xyz[2]);
429         }
430     }
431 }
432
433
434 // #############################################################################
435 void AliHLTTPCDisplay::ResetHistPadRow(){  
436     fHistraw->Reset();   
437     fHistrawcl->Reset(); 
438     fHistpad1->Reset(); 
439     fHistpad2->Reset();  
440     fHistpad3->Reset(); 
441 }
442
443
444 // #############################################################################
445 //                 DRAWER
446 // #############################################################################
447 void AliHLTTPCDisplay::DrawGeomSector(Int_t sector) {  
448   Char_t fname[256];
449   Int_t realsector = sector;// % 18;
450   
451   if (realsector < 10){
452     sprintf(fname,"LS0%d",realsector);
453     fGeom->GetNode(fname)->SetLineColor(fLineColor);
454     fGeom->GetNode(fname)->Draw("same");
455     sprintf(fname,"US0%d",realsector);
456     fGeom->GetNode(fname)->SetLineColor(fLineColor); 
457     fGeom->GetNode(fname)->Draw("same");
458   }
459   else {
460     sprintf(fname,"LS%d",realsector);
461     fGeom->GetNode(fname)->SetLineColor(fLineColor);
462     fGeom->GetNode(fname)->Draw("same");
463     sprintf(fname,"US%d",realsector);
464     fGeom->GetNode(fname)->SetLineColor(fLineColor); 
465     fGeom->GetNode(fname)->Draw("same");
466   }   
467 }
468 // #############################################################################
469 void AliHLTTPCDisplay::DrawHistPadRow(){  
470     Char_t title[256];
471     sprintf(title,"Selected PadRow %d with found Clusters",fPadRow);
472
473     fHistraw->SetTitle(title);
474     fHistraw->SetStats(kFALSE);
475     fHistraw->Draw("COLZ");
476
477     fHistrawcl->SetStats(kFALSE);
478     fHistrawcl->SetMarkerStyle(28);
479     fHistrawcl->SetMarkerSize(2);
480     fHistrawcl->SetMarkerColor(1);
481     fHistrawcl->Draw("psame");
482 }
483
484 // #############################################################################
485 void AliHLTTPCDisplay::DrawHistPad1(){  
486     Char_t title[256];
487     sprintf(title,"Selected Pad %d",fPad -1);
488     fHistpad1->SetStats(kFALSE);
489     fHistpad1->SetTitle(title);
490     fHistpad1->Draw();
491 }
492
493 // #############################################################################
494 void AliHLTTPCDisplay::DrawHistPad2(){  
495     Char_t title[256];
496     sprintf(title,"Selected Pad %d",fPad);
497
498     fHistpad2->SetStats(kFALSE);
499     fHistpad2->SetTitle(title);
500     fHistpad2->Draw();
501 }
502
503 // #############################################################################
504 void AliHLTTPCDisplay::DrawHistPad3(){  
505     Char_t title[256];
506     sprintf(title,"Selected Pad %d",fPad +1);
507
508     fHistpad3->SetStats(kFALSE);
509     fHistpad3->SetTitle(title);
510     fHistpad3->Draw();
511 }
512
513 // #############################################################################
514 void AliHLTTPCDisplay::Draw3D(){        
515     
516     TView *v = new TView(1);
517     v->SetRange(-800,-800,-800,800,800,800);
518
519     Float_t* etaRange = NULL;   // ------  STILL TO FIX
520
521     //--------------------------------------------------------------------------------------------
522     // DRAW 3D CLUSTER
523     //--------------------------------------------------------------------------------------------
524     if (fSwitch3DCluster){
525         for (Int_t slice=0; slice <= 35; slice++){
526             if (!fSliceArray[slice]) continue;
527             
528             for(Int_t p=0;p<6;p++){
529
530                     AliHLTTPCSpacePointData *points = fClusters[slice][p];
531                     if(!points) continue;
532                     Int_t npoints = fNcl[slice][p];
533                     TPolyMarker3D *pm = new TPolyMarker3D(npoints);
534
535                     Float_t xyz[3];
536                     for(Int_t i=0; i<npoints; i++){
537                         // Used  cluster only
538                         if (fSelectCluster == 1  && points[i].fUsed == kFALSE) continue; 
539                         // Unused clustr only
540                         if (fSelectCluster == 2  && points[i].fUsed == kTRUE) continue; 
541
542                         xyz[0] = points[i].fX;
543                         xyz[1] = points[i].fY;
544                         xyz[2] = points[i].fZ;
545                         
546                         if ( etaRange ){                  
547                             // Do this before the transform, because the tracker also uses
548                             // local coordinates when using this limit to determine 
549                             // which clusters to use for tracking
550                             Double_t pointEta = AliHLTTPCTransform::GetEta( xyz );
551                             if ( pointEta<etaRange[0] || pointEta>etaRange[1] )
552                                 continue;
553                         }
554                         AliHLTTPCTransform::Local2Global(xyz,slice);
555
556                         pm->SetPoint(i,xyz[0],xyz[1],xyz[2]); 
557
558                     }
559                     pm->SetMarkerColor(2); 
560                     pm->Draw("");
561
562                 }
563         }
564     }   // END - DRAW 3D CLUSTER 
565
566     //--------------------------------------------------------------------------------------------
567     // DRAW 3D TRACKS
568     //--------------------------------------------------------------------------------------------
569     if (fSwitch3DTracks){
570
571         Int_t ntracks = fTracks->GetNTracks();
572
573         TPolyLine3D *line = new TPolyLine3D[ntracks];
574
575         Float_t xcl[176];
576         Float_t ycl[176];
577         Float_t zcl[176];
578
579         Int_t trackcounter = 0;
580
581         for(Int_t j=0; j<ntracks; j++) {        
582
583             AliHLTTPCTrack *gtrack = fTracks->GetCheckedTrack(j); 
584             if(!gtrack) continue;
585
586             Int_t nHits = gtrack->GetNHits();
587             UInt_t *hitnum = gtrack->GetHitNumbers();
588
589             TPolyMarker3D *pm = new TPolyMarker3D(nHits);
590
591             Int_t hitcount=0;
592             Float_t xArr[2];
593             Float_t yArr[2];
594             Float_t zArr[2];
595
596             Bool_t nexttrack = kFALSE;
597
598             for(Int_t h=0; h<nHits; h++){
599           
600                 UInt_t id=hitnum[h];
601                 Int_t slice = (id>>25) & 0x7f;
602                 Int_t patch = (id>>22) & 0x7;
603                 UInt_t pos = id&0x3fffff; 
604
605                 // select if slice should be displayed or not
606                 if (!fSliceArray[slice]) {      
607                     nexttrack = kTRUE;
608                     break;         
609                 }
610                 
611                 // select Single Track
612                 if (fSelectTrackSwitch){
613                     if(slice != fSelectTrackSlice) {
614                         nexttrack = kTRUE;
615                         break;
616                     }
617
618                     if (trackcounter != fSelectTrack && h==0){
619                         trackcounter++;  
620                         nexttrack = kTRUE;
621                         break;
622                     }
623                     trackcounter++;  
624                 }
625
626                 // --> in the hit loop because of 'trackcounter++', otherwise wrong single track in slice will be selected
627                 if((fPtThreshold > 0) && (gtrack->GetPt()< fPtThreshold)) {     
628                     nexttrack = kTRUE;
629                     break;
630                 }
631                 
632                 // --> in the hit loop because of 'trackcounter++', otherwise wrong single track in slice will be selected
633                 if(nHits < fMinHits) {  
634                     nexttrack = kTRUE;
635                     break;
636                 }
637
638                 AliHLTTPCSpacePointData *points = fClusters[slice][patch];
639                 
640                 if(!points) {
641                     LOG(AliHLTTPCLog::kError,"AliHLTTPCDisplay::Draw3D","Clusterarray") <<"No points at slice "<<slice<<" patch "<<patch<<" pos "<<pos<<ENDLOG;
642                     continue;
643                 }
644  
645                 if(pos>=fNcl[slice][patch]) {
646                     LOG(AliHLTTPCLog::kError,"AliHLTTPCDisplay::Draw3D","Clusterarray") <<"Pos is too large: pos "<<pos <<" ncl "<<fNcl[slice][patch]<<ENDLOG;
647                     continue;
648                 }
649
650                 Float_t xyztmp[3];
651                 xyztmp[0] = points[pos].fX;
652                 xyztmp[1] = points[pos].fY;
653                 xyztmp[2] = points[pos].fZ;
654                 
655                 AliHLTTPCTransform::Local2Global(xyztmp,slice);
656             
657                 xcl[h] = xyztmp[0];
658                 ycl[h] = xyztmp[1];
659                 zcl[h] = xyztmp[2];
660                 
661                 if (h == 0){
662                     xArr[0]=xyztmp[0];
663                     yArr[0]=xyztmp[1];
664                     zArr[0]=xyztmp[2];
665                 }
666
667                 Int_t maxH = nHits - 1; 
668
669                 if (h == maxH){
670                     xArr[1]=xyztmp[0];
671                     yArr[1]=xyztmp[1];
672                     zArr[1]=xyztmp[2];
673                 }
674             
675                 pm->SetPoint(h,xcl[h],ycl[h],zcl[h]);
676           
677                 hitcount++;
678             }
679
680             if(nexttrack) continue;
681             if(hitcount==0) continue;
682         
683             //pm->SetMarkerColor(6); 
684             //pm->Draw();
685
686             TPolyLine3D *currentline = &(line[j]);
687             currentline = new TPolyLine3D(nHits,xcl,ycl,zcl,"");
688             currentline->SetLineColor(4);   
689             currentline->SetLineWidth(2);
690             currentline->Draw("same");
691         } // END for tracks
692
693     }   // END - DRAW 3D Tracks
694
695     //--------------------------------------------------------------------------------------------
696     // DRAW 3D GEOMETRY
697     //--------------------------------------------------------------------------------------------
698     if (fSwitch3DGeometry){
699
700         for (Int_t slice=0; slice <= 17; slice++){
701             if (!fSliceArray[slice]) continue;
702             DrawGeomSector(slice);
703         }
704     }   // END - DRAW 3D GEOMETRY
705     
706     //--------------------------------------------------------------------------------------------
707     // DRAW 3D PadRow
708     //--------------------------------------------------------------------------------------------
709     if (fSwitch3DPadRow && fSliceArray[fSlicePadRow]){
710         Int_t markercolor = 51;
711
712         for (UInt_t ii=0;ii < 20;ii++){
713             if (fcolorbin[ii]> 0){
714                 
715                 TPolyMarker3D *pm = new TPolyMarker3D(fcolorbin[ii], fpmarr[ii], 7 );
716
717                 pm->SetMarkerColor(markercolor); 
718                 pm->Draw(""); 
719             }
720
721             // in order to have the SetPalette(1), so called "pretty"
722             if (ii % 2 == 0 ) markercolor += 2;
723             else  markercolor += 3;
724         }
725     }
726
727     //--------------------------------------------------------------------------------------------
728     // DRAW 3D 
729     //--------------------------------------------------------------------------------------------
730     v->ZoomView(0,4);
731     v->Draw();   
732 }
733
734
735
736