5 //_____________________________________________________________
8 // Display class for the HLT TPC-3D events.
11 // Author: Jochen Thaeder <mailto:thaeder@kip.uni-heidelberg.de>
12 //*-- Copyright © ALICE HLT Group
14 #define TRACKHELIX 0 // use THelix for tracks
15 #define TRACKPOLYMARKER 0 // use TPolymarker3D for tracks
16 #define FIRSTLASTPOINT 0 // show first / last point of tracks
21 #define UNUSEDCLUSTERCOLOR 2
22 #define USEDCLUSTERCOLOR 3
24 #define TRACKPOLYMARKERCOLOR 5
25 #define TRACKHELIXCOLOR 6
27 #if defined(HAVE_HOMERREADER)
28 #include HOMERREADER_HEADER
29 #endif // defined(HAVE_HOMERREADER)
31 #include "AliHLTTPCDisplay3D.h"
32 #include "AliHLTTPCDisplayPadRow.h"
34 #include "AliHLTStdIncludes.h"
35 #ifndef HAVE_NOT_TVIEW3D
40 #include <TPolyMarker3D.h>
41 #include <TPolyLine3D.h>
45 #include <TGeometry.h>
47 #include <TParticle.h>
52 #include <TMultiGraph.h>
58 #include <TClonesArray.h>
60 #include <AliSimDigits.h>
61 #include <AliTPCParam.h>
64 #include "AliHLTTPCDefinitions.h"
65 #include "AliHLTDataTypes.h"
66 #include "AliHLTTPCSpacePointData.h"
67 #include "AliHLTTPCClusterDataFormat.h"
68 #include "AliHLTTPCTrackletDataFormat.h"
71 #include "AliHLTTPCDigitReader.h"
72 #include "AliHLT_C_Component_WrapperInterface.h"
74 #include "AliHLTTPCDisplayMain.h"
76 #include "AliHLTTPCLogging.h"
77 #include "AliHLTTPCDisplay.h"
78 #include "AliHLTTPCTransform.h"
79 #include "AliHLTTPCTrack.h"
80 #include "AliHLTTPCTrackArray.h"
81 #include "AliHLTTPCMemHandler.h"
82 #include "AliHLTTPCDigitReaderPacked.h"
89 ClassImp(AliHLTTPCDisplay3D)
91 //____________________________________________________________________________________________________
92 AliHLTTPCDisplay3D::AliHLTTPCDisplay3D(AliHLTTPCDisplayMain* display, Char_t* gfile ) :
101 //____________________________________________________________________________________________________
102 AliHLTTPCDisplay3D::~AliHLTTPCDisplay3D() {
107 //____________________________________________________________________________________________________
108 void AliHLTTPCDisplay3D::Save(){
109 fDisplay->GetCanvas3D()->SaveAs("HLT-3D-View.eps");
112 //____________________________________________________________________________________________________
113 void AliHLTTPCDisplay3D::Draw(){
114 fDisplay->GetCanvas3D()->cd();
115 fDisplay->GetCanvas3D()->Clear();
117 #ifndef HAVE_NOT_TVIEW3D
118 TView3D *v = new TView3D();
119 if (v) v->SetSystem(1);
121 TView *v = new TView(1);
124 HLTFatal("can not create viewer");
127 v->SetRange(-800,-800,-800,800,800,800);
129 Float_t* etaRange = NULL; // ------ STILL TO FIX
132 //--------------------------------------------------------------------------------------------
134 //--------------------------------------------------------------------------------------------
135 if (fDisplay->Get3DSwitchGeometry()){
137 TList* masterNodeList = fGeom->GetListOfNodes();
139 TIter next(masterNodeList);
141 while ((masterNode = static_cast<TNode*> (next()))) {
143 TList* nodeList = masterNode->GetListOfNodes();
145 TIter nextt(nodeList);
147 while ((node = static_cast<TNode*> (nextt()))) {
149 ULong_t tmpslice = atol(node->GetName() + 2);
151 if (fDisplay->GetDisplaySlice(tmpslice)) {
152 node->SetVisibility(1);
153 node->SetFillColor(0);
154 node->SetLineColor(fDisplay->GetLineColor());
156 else node->SetVisibility(0);
157 } // end while son Nodes
158 } // end while master Node
161 } // END - DRAW 3D GEOMETRY
163 //--------------------------------------------------------------------------------------------
165 //--------------------------------------------------------------------------------------------
167 if (fDisplay->ExistsRawData() && fDisplay->Get3DSwitchPadRow() && fDisplay->GetDisplaySlice(fDisplay->GetSlicePadRow())){
169 // -- only one padrow
170 if ( fDisplay->Get3DSwitchRaw() == 1 ) {
171 fDisplay->GetPadRowPointer()->Draw3D();
176 TPolyMarker3D *pmRawdata = new TPolyMarker3D(1,6);
177 pmRawdata->SetBit(kCanDelete);
179 if ( fDisplay->GetZeroSuppression() ){
180 for (Int_t row=0; row < AliHLTTPCTransform::GetNRows(); row++){
181 for (Int_t pad=0; pad < AliHLTTPCTransform::GetNPads(row); pad++){
182 for (Int_t timeBin=fDisplay->GetTimeBinMin(); timeBin <= fDisplay->GetTimeBinMax(); timeBin++){
184 Int_t time = (Int_t) fDisplay->fRawDataZeroSuppressed[row][pad][timeBin];
189 AliHLTTPCTransform::RawHLT2Global(xyz,fDisplay->GetSlicePadRow(), row, pad, timeBin);
191 pmRawdata->SetPoint(nRawdata,xyz[0],xyz[1],xyz[2]);
199 pmRawdata->SetMarkerSize(1);
200 pmRawdata->SetMarkerColor(6);
201 pmRawdata->Draw("same");
203 } // end show all padrows
207 //--------------------------------------------------------------------------------------------
209 //--------------------------------------------------------------------------------------------
210 if (fDisplay->Get3DSwitchCluster() && fDisplay->ExistsClusterData()){
212 for (Int_t slice=0; slice <= 35; slice++){
214 Int_t currenttrack = -1;
216 if (fDisplay->ExistsTrackData() && fDisplay->GetSelectTrackSwitch()) currenttrack = fDisplay->GetGlobalTrack(slice);
218 if (!fDisplay->GetDisplaySlice(slice)) continue;
220 for(Int_t patch=0;patch<6;patch++){
222 AliHLTTPCSpacePointData *points = fDisplay->GetSpacePointDataPointer(slice,patch);
223 if(!points) continue;
225 TPolyMarker3D *pmUsed = new TPolyMarker3D(1,6);
226 TPolyMarker3D *pmUnused = new TPolyMarker3D(1,6);
227 pmUnused->SetBit(kCanDelete);
228 pmUsed->SetBit(kCanDelete);
231 Int_t nUsedCluster = 0;
232 Int_t nUnusedCluster = 0;
235 for(Int_t i=0; i< fDisplay->GetNumberSpacePoints(slice,patch); i++){
237 if (fDisplay->GetSelectCluster() == 1 && points[i].fUsed == kFALSE) continue;
238 // Unused cluster only
239 if (fDisplay->GetSelectCluster() == 2 && points[i].fUsed == kTRUE) continue;
241 // if single track is selcted draw only cluster for this track
242 if (fDisplay->GetSelectCluster() == 1 && fDisplay->GetSelectTrackSwitch() && points[i].fTrackN != currenttrack) continue;
244 xyz[0] = points[i].fX;
245 xyz[1] = points[i].fY;
246 xyz[2] = points[i].fZ;
249 // Do this before the transform, because the tracker also uses
250 // local coordinates when using this limit to determine
251 // which clusters to use for tracking
252 Double_t pointEta = AliHLTTPCTransform::GetEta( xyz );
253 if ( pointEta<etaRange[0] || pointEta>etaRange[1] )
257 AliHLTTPCTransform::Local2Global(xyz,slice);
259 if (points[i].fUsed == kTRUE){
260 pmUsed->SetPoint(nUsedCluster,xyz[0],xyz[1],xyz[2]);
264 pmUnused->SetPoint(nUnusedCluster,xyz[0],xyz[1],xyz[2]);
269 pmUsed->SetMarkerSize(1);
270 pmUsed->SetMarkerColor(USEDCLUSTERCOLOR);
271 pmUsed->Draw("same");
273 pmUnused->SetMarkerSize(1);
274 pmUnused->SetMarkerColor(UNUSEDCLUSTERCOLOR);
275 pmUnused->Draw("same");
277 fDisplay->GetCanvas3D()->Modified();
278 fDisplay->GetCanvas3D()->Update();
280 } // END - PATCH LOOP
281 } // END - SLICE LOOP
282 } // END - DRAW 3D CLUSTER
284 //--------------------------------------------------------------------------------------------
286 //--------------------------------------------------------------------------------------------
287 if (fDisplay->Get3DSwitchTracks() && fDisplay->ExistsTrackData()){
289 AliHLTTPCTransform::SetBField( 0.5 ); // ++++++
292 AliHLTTPCTrackArray* tracks = fDisplay->GetTrackArrayPointer();
293 Int_t ntracks = tracks->GetNTracks();
295 // TPolyLine3D **line = new (TPolyLine3D*)[ntracks];
296 // for(Int_t j=0; j<ntracks; j++) line[j] = 0;
298 // THelix **helix = new (THelix*)[ntracks];
299 // for(Int_t j=0; j<ntracks; j++) helix[j] = 0;
302 for(Int_t j=0; j<ntracks; j++) {
304 AliHLTTPCTrack *gtrack = tracks->GetCheckedTrack(j);
305 if(!gtrack) continue;
307 Int_t nHits = gtrack->GetNHits(); // Number of associated hits to track
308 Int_t slice = gtrack->GetSector();
310 // --- CHECK if track is should be drawn
311 // select if slice should be displayed or not
312 if (!fDisplay->GetDisplaySlice(slice)) continue;
314 if (fDisplay->GetSelectTrackSwitch() && fDisplay->GetGlobalTrack(slice) != j) continue;
316 Double_t radius = gtrack->GetRadius(); // radius
317 Double_t kappa = gtrack->GetKappa(); // curvature = 1/R , signed
318 Double_t lambda = atan( gtrack->GetTgl() ); // dipAngle lambda
319 Double_t phi0 = gtrack->GetPsi() + (gtrack->GetCharge() * AliHLTTPCTransform::PiHalf() ); // azimuthal angle of startingpoint, with respect to helix axis
321 if (kappa == 0 && AliHLTTPCTransform::GetBFieldValue() > 0.) {
322 printf("================================KAPPA == 0");
326 Double_t xyzL[3]; // lastpoint of track
327 Double_t xyzF[3]; // firstpoint of track
329 xyzF[0] = gtrack->GetFirstPointX();
330 xyzF[1] = gtrack->GetFirstPointY();
331 xyzF[2] = gtrack->GetFirstPointZ();
333 xyzL[0] = gtrack->GetLastPointX();
334 xyzL[1] = gtrack->GetLastPointY();
335 xyzL[2] = gtrack->GetLastPointZ();
337 if ( xyzL[0] == xyzF[0] ) continue;
338 if ( xyzL[1] == xyzF[1] ) continue;
339 if ( xyzL[2] == xyzF[2] ) continue;
343 TPolyMarker3D *pmL = new TPolyMarker3D(1,2);
344 TPolyMarker3D *pmF = new TPolyMarker3D(1,2);
345 pmL->SetBit(kCanDelete);
346 pmF->SetBit(kCanDelete);
348 //TPolyMarker3D pmL(1,2);
349 //TPolyMarker3D pmF(1,2);
352 pmF->SetPoint(0,xyzF[0],xyzF[1],xyzF[2]);
353 pmL->SetPoint(0,xyzL[0],xyzL[1],xyzL[2]);
356 Double_t s = 0.; // length of the track
359 //if ( AliHLTTPCTransform::GetBFieldValue() == 0.)
360 if ( radius == 999999.0){ // IVAN HACK
362 s = sqrt ( (xyzL[0] - xyzF[0])*(xyzL[0] - xyzF[0]) + (xyzL[1] - xyzF[1])*(xyzL[1] - xyzF[1]) );
365 // Calculate the length of the track. If it is to flat in in s,z plane use sxy, otherwise use sz
366 if (fabs(lambda) > 0.05){
367 // length of track calculated out of z
368 s = fabs( (xyzL[2] - xyzF[2]) / sin(lambda) ); // length of track calculated out of z
371 Double_t d = (xyzL[0] - xyzF[0])*(xyzL[0] - xyzF[0]) + (xyzL[1] - xyzF[1])*(xyzL[1] - xyzF[1]);
372 // length of track calculated out of xy
373 s = fabs ( acos( 0.5 * (2 - (d / (radius*radius)))) / ( kappa * cos(lambda) ) );
380 if (nHits < fDisplay->GetCutHits() ) continue;
381 if (s < fDisplay->GetCutS() ) continue;
382 if (gtrack->GetPsi() < fDisplay->GetCutPsi() ) continue;
383 if (lambda < fDisplay->GetCutLambda() ) continue;
384 if (gtrack->GetPt() < fDisplay->GetCutPt() && AliHLTTPCTransform::GetBFieldValue() != 0. ) continue;
385 if ( AliHLTTPCTransform::GetPadRow((Float_t)xyzF[0]) > fDisplay->GetIncidentPadrow() ) continue;
387 Int_t nTrackPoints = 2 + (Int_t) floor(s / DRAWSTEP);
390 // TPolyMarker3D *pmT = new TPolyMarker3D(nTrackPoints,6);
391 TPolyMarker3D pmT(nTrackPoints,6);
394 Double_t *xT = new Double_t[nTrackPoints];
395 Double_t *yT = new Double_t[nTrackPoints];
396 Double_t *zT = new Double_t[nTrackPoints];
398 Int_t trackPointCounter = 0;
400 //Write Track Parameters for single track
401 if (fDisplay->GetSelectTrackSwitch() ){
402 fDisplay->fTrackParam.id = j;
403 fDisplay->fTrackParam.nHits = nHits;
404 fDisplay->fTrackParam.charge = gtrack->GetCharge();
405 fDisplay->fTrackParam.lambda = lambda;
406 fDisplay->fTrackParam.kappa = kappa;
407 fDisplay->fTrackParam.radius = radius;
408 fDisplay->fTrackParam.slice = slice;
409 fDisplay->fTrackParam.phi0 = phi0;
410 fDisplay->fTrackParam.pt = gtrack->GetPt();
411 fDisplay->fTrackParam.bfield = AliHLTTPCTransform::GetBFieldValue();
412 fDisplay->fTrackParam.psi = gtrack->GetPsi();
413 fDisplay->fTrackParam.s = s;
417 // if ( AliHLTTPCTransform::GetBFieldValue() == 0.) {
419 if ( radius == 999999.0) { // IVAN HACK
421 // cout << "ENTER IVAN 2 radius="<< radius << endl;
422 for (Double_t ds = 0.; ds < s; ds = ds + DRAWSTEP){
423 // FILL ARRAYS IN ORDER TO DRAW THE TRACKPOINTS, OUT OF THE PARAMETER
424 // xT[trackPointCounter] = xyzF[0] + ds * cos(phi0);
425 // yT[trackPointCounter] = xyzF[1] + ds * sin(phi0);
426 xT[trackPointCounter] = xyzF[0] + ds * cos(phi0 - 1.57);
427 yT[trackPointCounter] = xyzF[1] + ds * sin(phi0 - 1.57);
428 zT[trackPointCounter] = xyzF[2] + ds * sin(lambda);
430 pmT.SetPoint(trackPointCounter,xT[trackPointCounter],yT[trackPointCounter],zT[trackPointCounter]);
435 if (trackPointCounter > nTrackPoints) printf("N=%d n=%d", nTrackPoints,trackPointCounter);
437 //xT[trackPointCounter] = xyzF[0] + s * cos(phi0);
438 //yT[trackPointCounter] = xyzF[1] + s * sin(phi0);
440 xT[trackPointCounter] = xyzF[0] + s * cos(phi0 - 1.57);
441 yT[trackPointCounter] = xyzF[1] + s * sin(phi0 - 1.57);
442 zT[trackPointCounter] = xyzF[2] + s * sin(lambda);
444 pmT.SetPoint(trackPointCounter,xT[trackPointCounter],yT[trackPointCounter],zT[trackPointCounter]);
451 for (Double_t ds = 0.; ds < s; ds = ds + DRAWSTEP){
452 // FILL ARRAYS IN ORDER TO DRAW THE TRACKPOINTS, OUT OF THE PARAMETER
453 xT[trackPointCounter] = xyzF[0] + radius * ( cos( phi0 + (ds*kappa*cos(lambda)) ) - cos(phi0) );
454 yT[trackPointCounter] = xyzF[1] + radius * ( sin( phi0 + (ds*kappa*cos(lambda)) ) - sin(phi0) );
455 zT[trackPointCounter] = xyzF[2] + ds * sin(lambda);
457 pmT.SetPoint(trackPointCounter,xT[trackPointCounter],yT[trackPointCounter],zT[trackPointCounter]);
462 if (trackPointCounter > nTrackPoints) printf("N=%d n=%d", nTrackPoints,trackPointCounter);
464 xT[trackPointCounter] = xyzF[0] + radius * ( cos( phi0 + (s*kappa*cos(lambda)) ) - cos(phi0) );
465 yT[trackPointCounter] = xyzF[1] + radius * ( sin( phi0 + (s*kappa*cos(lambda)) ) - sin(phi0) );
466 zT[trackPointCounter] = xyzF[2] + s * sin(lambda);
468 pmT.SetPoint(trackPointCounter,xT[trackPointCounter],yT[trackPointCounter],zT[trackPointCounter]);
473 // Draw Track -- as line
474 //line[j] = new TPolyLine3D(nTrackPoints,xT,yT,zT,"");
475 //TPolyLine3D *currentline = line[j];
476 //* currentline = new TPolyLine3D(nTrackPoints,xT,yT,zT,"");
477 // TPolyLine3D currentline(nTrackPoints,xT,yT,zT,"");
479 TPolyLine3D *currentline = new TPolyLine3D(nTrackPoints,xT,yT,zT,"");
480 currentline->SetBit(kCanDelete);
481 currentline->SetLineColor(TRACKCOLOR);
482 currentline->SetLineWidth(2);
483 currentline->Draw("same");
487 // --- ADDITIONAL DRAW OPTIONS
489 // Draw last point of Track
490 pmL->SetMarkerSize(3);
491 pmL->SetMarkerColor(4);
494 // Draw first point of Track
495 pmF->SetMarkerSize(3);
496 pmF->SetMarkerColor(5);
500 // Draw Track -- as polymarker
501 pmT.SetMarkerSize(3);
502 pmT.SetMarkerColor(TRACKPOLYMARKERCOLOR);
506 // Draw Track -- as helix
507 // works ok, execpt for very small dipangles -> track almost horizontal
513 v0[0] = gtrack->GetPx();
514 v0[1] = gtrack->GetPy();
515 v0[2] = gtrack->GetPz();
516 omega = AliHLTTPCTransform::GetBFieldValue() * gtrack->GetCharge();
518 // helix[j] = new THelix(xyzF,v0,omega,hrange,kHelixZ,0);
519 // THelix *currenthelix = helix[j];
520 // currenthelix = new THelix(xyzF,v0,omega,hrange,kHelixZ,0);
521 THelix currenthelix(xyzF,v0,omega,hrange,kHelixZ,0);
522 currenthelix.SetLineColor(TRACKHELIXCOLOR);
523 currenthelix.SetLineWidth(1);
524 currenthelix.Draw("same");
529 //Double_t *xT = new Double_t[nTrackPoints];
530 // Double_t *yT = new Double_t[nTrackPoints];
531 // Double_t *zT = new Double_t[nTrackPoints];
545 } // END for track loop
548 // NO !!! DELETE line #ifdef helix delete helix
551 } // END - DRAW 3D Tracks
553 //--------------------------------------------------------------------------------------------
555 //--------------------------------------------------------------------------------------------
559 fDisplay->GetCanvas3D()->SetFillColor(fDisplay->GetBackColor());
561 if ( !fDisplay->GetKeepView() ){
562 fDisplay->GetCanvas3D()->SetTheta(fDisplay->GetTheta());
563 fDisplay->GetCanvas3D()->SetPhi(fDisplay->GetPhi());
566 // fDisplay->GetCanvas3D()->Modified();
568 fDisplay->GetCanvas3D()->Update();
572 //____________________________________________________________________________________________________
573 void AliHLTTPCDisplay3D::LoadGeometrie(Char_t *gfile) {
575 TFile *file = TFile::Open(gfile);
577 LOG(AliHLTTPCLog::kError,"AliHLTTPCDisplay3D::AliHLTDisplay","File Open")
578 <<"Geometry file " << gfile << " does not exist!"<<ENDLOG;
582 fGeom = (TGeometry*)file->Get("AliceGeom");