23-jan-2007 NvE Bug fixed by Garmt in IceMakeHits.cxx.
[u/mrichter/AliRoot.git] / FMD / AliFMDDisplay.cxx
CommitLineData
bf000c32 1/**************************************************************************
2 * Copyright(c) 2004, 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 **************************************************************************/
bf000c32 15/* $Id$ */
c2fc1258 16/** @file AliFMDDisplay.cxx
17 @author Christian Holm Christensen <cholm@nbi.dk>
18 @date Mon Mar 27 12:39:09 2006
19 @brief FMD Event display
20*/
bf000c32 21//___________________________________________________________________
22//
23// The classes defined here, are utility classes for reading in data
24// for the FMD. They are put in a seperate library to not polute the
25// normal libraries. The classes are intended to be used as base
26// classes for customized class that do some sort of analysis on the
27// various types of data produced by the FMD.
28//
29// Latest changes by Christian Holm Christensen
30//
31#include "AliFMDDisplay.h" // ALIFMDDISPLAY_H
32#include "AliFMDHit.h" // ALIFMDHIT_H
33#include "AliFMDDigit.h" // ALIFMDDIGIT_H
34#include "AliFMDRecPoint.h" // ALIFMDRECPOINT_H
35#include "AliFMDGeometry.h" // ALIFMDGEOMETRY_H
36#include "AliFMDParameters.h" // ALIFMDPARAMETERS_H
15b17c89 37#include <AliESDFMD.h> // ALIESDFMD_H
bf000c32 38#include <AliLog.h>
39#include <TStyle.h>
02a27b50 40// #include <TArrayF.h>
bf000c32 41#include <TMarker3DBox.h>
42#include <TGeoManager.h>
02a27b50 43// #include <TMath.h>
bf000c32 44#include <TApplication.h>
45#include <TButton.h>
02a27b50 46// #include <TParticle.h>
bf000c32 47#include <TCanvas.h>
48#include <TView.h>
49#include <TVirtualX.h>
a9579262 50#include <TSlider.h>
51#include <TH1D.h>
bf000c32 52
53//____________________________________________________________________
54ClassImp(AliFMDDisplay)
55#if 0
56 ; // This is here to keep Emacs for indenting the next line
57#endif
58
59//____________________________________________________________________
60AliFMDDisplay* AliFMDDisplay::fgInstance = 0;
61
62//____________________________________________________________________
63AliFMDDisplay*
64AliFMDDisplay::Instance()
65{
02a27b50 66 // Return static instance
bf000c32 67 return fgInstance;
68}
69
70//____________________________________________________________________
a9579262 71AliFMDDisplay::~AliFMDDisplay()
72{
73 if (fMarkers) {
74 fMarkers->Delete();
75 delete fMarkers;
76 }
77 if (fHits) {
78 fHits->Clear();
79 delete fHits;
80 }
81 if (fPad) delete fPad;
82 fButtons.Delete();
83 if (fSlider) delete fSlider;
84 if (fCanvas) delete fCanvas;
85}
86
87//____________________________________________________________________
88AliFMDDisplay::AliFMDDisplay(Bool_t onlyFMD, const char* gAliceFile)
bf000c32 89 : AliFMDInput(gAliceFile),
90 fWait(kFALSE),
b5ee4425 91 fMarkers(0),
92 fHits(0),
bf000c32 93 fCanvas(0),
94 fPad(0),
a9579262 95 fSlider(0),
b5ee4425 96 fZoomMode(kFALSE),
97 fX0(0),
98 fY0(0),
99 fX1(0),
100 fY1(0),
101 fMultCut(0),
102 fPedestalFactor(0),
103 fXPixel(0),
104 fYPixel(0),
105 fOldXPixel(0),
106 fOldYPixel(0),
a9579262 107 fLineDrawn(0),
108 fOnlyFMD(onlyFMD)
bf000c32 109{
110 // Constructor of an FMD display object.
111 AddLoad(kGeometry);
a9579262 112 if (fgInstance) delete fgInstance;
bf000c32 113 fgInstance = this;
15b17c89 114 SetMultiplicityCut();
115 SetPedestalFactor();
bf000c32 116}
117
118//____________________________________________________________________
1e8f773e 119void
a9579262 120AliFMDDisplay::MakeCanvas(const char** which)
121{
122 gStyle->SetPalette(1);
123 Double_t y1 = .10;
124 Int_t w = 700;
125 fCanvas = new TCanvas("display", "Display", w, Int_t(w / (1-y1)));
126 fCanvas->SetFillColor(1);
127 fCanvas->ToggleEventStatus();
128 fCanvas->cd();
129 fPad = new TPad("view", "3DView", 0.0, y1, 1.0, 1.0, 1, 0, 0);
130 fPad->Draw();
131
132 Double_t yb = 0;
133 fCanvas->cd();
134 if (TESTBIT(fTreeMask, kESD) ||
135 TESTBIT(fTreeMask, kDigits) ||
136 TESTBIT(fTreeMask, kRaw)) {
137 yb = .05;
138 fSlider = new TSlider("multCut", "Multiplicity cut", 0, 0, 1, yb);
139 fSlider->SetMethod("AliFMDDisplay::Instance()->ChangeCut()");
a9579262 140 fSlider->Draw();
97b4001e 141 fSlider->SetMinimum(TESTBIT(fTreeMask, kESD) ? fMultCut * 10 :
142 fPedestalFactor * 10);
a9579262 143 }
144 const char** p = which;
145 const char* m;
146 Int_t n = 0;
147 Int_t j = 0;
148 while (*(p++)) n++;
149 AliInfo(Form("Got %d buttons", n));
150 Float_t x0 = 0;
151 Float_t dx = 1. / n;
152 p = which;
153 while ((m = *(p++))) {
154 fCanvas->cd();
155 AliInfo(Form("Adding button %s", m));
156 TButton* b = new TButton(m, Form("AliFMDDisplay::Instance()->%s()", m),
157 x0, yb, x0 + dx, y1);
158 b->Draw();
159 fButtons.Add(b);
160 x0 += dx;
161 j++;
162 }
163}
164
165//____________________________________________________________________
166void
167AliFMDDisplay::ShowOnlyFMD()
168{
169 if (!fGeoManager) return;
170 static bool once = false;
171 if (once) return;
172 once = true;
173 AliInfo("Will only show the FMD");
174 TGeoVolume* top = gGeoManager->GetTopVolume();
175 top->InvisibleAll(kTRUE);
176 TGeoIterator next(top);
177 TGeoNode* node;
178 TGeoVolume* v = 0;
179 Bool_t hasFMD1 = kFALSE;
180 Bool_t hasFMD2 = kFALSE;
181 Bool_t hasFMD3 = kFALSE;
182 TObjArray toshow;
183 while ((node = static_cast<TGeoNode*>(next()))) {
184 const char* name = node->GetName();
185 if (!name) continue;
186 if (!(v = node->GetVolume())) continue;
187
188 if (name[0] == 'F') {
189 if (name[2] == 'M' && (name[3] == 'T' || name[3] == 'B')) {
190 // Virtual Master half-ring volume - top-level
191 Int_t det = node->GetNumber();
192 switch (det) {
193 case 1: hasFMD1 = true; break;
194 case 2: hasFMD2 = true; break;
195 case 3: hasFMD3 = true; break;
196 default: continue;
197 }
198 toshow.Add(v);
199 }
200 else if (name[3] == 'V' && (name[2] == 'T' || name[2] == 'B'))
201 toshow.Add(v); // Virtual Half-ring, bare detectors
202 // else if (name[3] == 'H' && (name[2] == 'F' || name[2] == 'B'))
203 // toshow.Add(v); // Virtual Hybrid container
204 }
205 v->SetVisibility(kFALSE);
206 v->SetVisDaughters(kFALSE);
207 v->InvisibleAll(kTRUE);
208 }
209 TIter i(&toshow);
210 while ((v = static_cast<TGeoVolume*>(i()))) {
211 v->SetVisibility(kTRUE);
212 v->SetVisDaughters(kTRUE);
213 v->InvisibleAll(kFALSE);
214 }
215}
216
217
218//____________________________________________________________________
219void
bf000c32 220AliFMDDisplay::ExecuteEvent(Int_t event, Int_t px, Int_t py)
221{
1e8f773e 222 // AliInfo(Form("Event %d, at (%d,%d)", px, py));
bf000c32 223 if (px == 0 && py == 0) return;
224 if (!fZoomMode && fPad->GetView()) {
225 fPad->GetView()->ExecuteRotateView(event, px, py);
226 return;
227 }
228 fPad->SetCursor(kCross);
229 switch (event) {
230 case kButton1Down:
231 fPad->TAttLine::Modify();
232 fX0 = fPad->AbsPixeltoX(px);
233 fY0 = fPad->AbsPixeltoY(py);
234 fXPixel = fOldXPixel = px;
235 fYPixel = fOldYPixel = py;
236 fLineDrawn = kFALSE;
237 return;
238 case kButton1Motion:
239 if (fLineDrawn)
240 gVirtualX->DrawBox(fXPixel, fYPixel, fOldXPixel, fOldYPixel,
241 TVirtualX::kHollow);
242 fOldXPixel = px;
243 fOldYPixel = py;
244 fLineDrawn = kTRUE;
245 gVirtualX->DrawBox(fXPixel, fYPixel, fOldXPixel, fOldYPixel,
246 TVirtualX::kHollow);
247 return;
248 case kButton1Up:
249 fPad->GetCanvas()->FeedbackMode(kFALSE);
250 if (px == fXPixel || py == fYPixel) return;
251 fX1 = fPad->AbsPixeltoX(px);
252 fY1 = fPad->AbsPixeltoY(py);
253 if (fX1 < fX0) std::swap(fX0, fX1);
254 if (fY1 < fY0) std::swap(fY0, fY1);
255 fPad->Range(fX0, fY0, fX1, fY1);
256 fPad->Modified();
257 return;
258 }
259}
260
261//____________________________________________________________________
1e8f773e 262Int_t
263AliFMDDisplay::DistancetoPrimitive(Int_t px, Int_t)
bf000c32 264{
1e8f773e 265 // AliInfo(Form("@ (%d,%d)", px, py));
bf000c32 266 fPad->SetCursor(kCross);
267 Float_t xmin = fPad->GetX1();
268 Float_t xmax = fPad->GetX2();
269 Float_t dx = .02 * (xmax - xmin);
270 Float_t x = fPad->AbsPixeltoX(px);
271 if (x < xmin + dx || x > xmax - dx) return 9999;
272 return (fZoomMode ? 0 : 7);
273}
274//____________________________________________________________________
275Bool_t
276AliFMDDisplay::Init()
277{
02a27b50 278 // Initialize. GEt transforms and such,
bf000c32 279 if (!AliFMDInput::Init()) return kFALSE;
280 AliFMDGeometry* geom = AliFMDGeometry::Instance();
281 geom->Init();
282 geom->InitTransformations();
97b4001e 283 if (TESTBIT(fTreeMask, kDigits) || TESTBIT(fTreeMask, kRaw))
284 AliFMDParameters::Instance()->Init();
285
a9579262 286 fMarkers = new TObjArray;
287 fHits = new TObjArray;
288 fMarkers->SetOwner(kTRUE);
289 fHits->SetOwner(kFALSE);
bf000c32 290 return kTRUE;
291}
a9579262 292
293//____________________________________________________________________
294void
295AliFMDDisplay::MakeAux()
296{
297 if ((TESTBIT(fTreeMask, kESD) ||
298 TESTBIT(fTreeMask, kDigits) ||
299 TESTBIT(fTreeMask, kRaw))) {
300 if (!fAux) {
301 fAux = new TCanvas("aux", "Aux");
302 fAux->SetLogy();
303 if (TESTBIT(fTreeMask, kESD))
97b4001e 304 fSpec = new TH1D("spec", "Mult spectra", 500, 0, 10);
a9579262 305 else
306 fSpec = new TH1D("spec", "Adc spectra", 1024, -.5, 1023.5);
307 fSpecCut = static_cast<TH1*>(fSpec->Clone("specCut"));
308 fSpec->SetFillColor(2);
309 fSpec->SetFillStyle(3001);
310 fSpecCut->SetFillColor(4);
311 fSpecCut->SetFillStyle(3001);
312 }
313 else {
314 fSpec->Reset();
315 fSpecCut->Reset();
316 }
317 }
318}
319
320//____________________________________________________________________
321void
322AliFMDDisplay::DrawAux()
323{
324 if (!fAux) return;
325 fAux->cd();
326 fAux->Clear();
327 fSpec->Draw();
328 fSpecCut->Draw("same");
329 fAux->Modified();
330 fAux->Update();
331 fAux->cd();
332}
333
bf000c32 334//____________________________________________________________________
335Bool_t
336AliFMDDisplay::Begin(Int_t event)
337{
02a27b50 338 // Begin of event. Make canvas is not already done
bf000c32 339 if (!fCanvas) {
a9579262 340 const char* m[] = { "Continue", "Zoom", "Pick", "Redisplay", 0 };
341 MakeCanvas(m);
bf000c32 342 }
97b4001e 343 MakeAux();
344
a9579262 345 // AliInfo("Clearing canvas");
bf000c32 346 // fCanvas->Clear();
347 if (!fGeoManager) {
348 Warning("End", "No geometry manager");
349 return kFALSE;
350 }
351 AliInfo("Drawing geometry");
352 fPad->cd();
353 fGeoManager->GetTopVolume()->Draw();
a9579262 354 if (fOnlyFMD) ShowOnlyFMD();
bf000c32 355 AliInfo("Adjusting view");
356 Int_t irep;
357 if (fPad->GetView()) {
358 fPad->GetView()->SetView(-200, -40, 80, irep);
359 fPad->GetView()->Zoom();
360 fPad->Modified();
361 fPad->cd();
362 }
363 return AliFMDInput::Begin(event);
364}
365
366//____________________________________________________________________
a9579262 367void
368AliFMDDisplay::AtEnd()
bf000c32 369{
370 fPad->cd();
371 fMarkers->Draw();
1e8f773e 372 fPad->cd();
bf000c32 373 AppendPad();
bf000c32 374 fPad->cd();
a9579262 375 DrawAux();
376}
377
378//____________________________________________________________________
379void
380AliFMDDisplay::Idle()
381{
bf000c32 382 fWait = kTRUE;
383 while (fWait) {
384 gApplication->StartIdleing();
385 gSystem->InnerLoop();
386 gApplication->StopIdleing();
387 }
388 AliInfo("After idle loop");
a9579262 389 if (fMarkers) fMarkers->Delete();
390 if (fHits) fHits->Clear();
bf000c32 391 AliInfo("After clearing caches");
a9579262 392}
393
394//____________________________________________________________________
395Bool_t
396AliFMDDisplay::End()
397{
398 // End of event. Draw everything
399 AtEnd();
400 Idle();
bf000c32 401 return AliFMDInput::End();
402}
403
404//____________________________________________________________________
405Int_t
406AliFMDDisplay::LookupColor(Float_t x, Float_t max) const
407{
02a27b50 408 // Look-up color
bf000c32 409 Int_t idx = Int_t(x / max * gStyle->GetNumberOfColors());
410 return gStyle->GetColorPalette(idx);
411}
412
15b17c89 413//____________________________________________________________________
414void
a9579262 415AliFMDDisplay::ChangeCut()
416{
97b4001e 417 fMultCut = fSlider->GetMinimum() * 10;
a9579262 418 fPedestalFactor = fSlider->GetMinimum() * 10;
419 AliInfo(Form("Multiplicity cut: %7.5f, Pedestal factor: %7.4f (%6.5f)",
420 fMultCut, fPedestalFactor, fSlider->GetMinimum()));
421 Redisplay();
422}
423
424//____________________________________________________________________
425void
426AliFMDDisplay::Redisplay()
427{
428 if (fMarkers) fMarkers->Delete();
429 if (fHits) fHits->Clear();
430 if (fSpec) fSpec->Reset();
431 if (fSpecCut) fSpecCut->Reset();
432 Event();
433 AtEnd();
434}
435
436//____________________________________________________________________
437void
15b17c89 438AliFMDDisplay::AddMarker(UShort_t det, Char_t rng, UShort_t sec, UShort_t str,
439 TObject* o, Float_t s, Float_t max)
440{
441 // Add a marker to the display
442 //
443 // det Detector
444 // rng Ring
445 // sec Sector
446 // str Strip
447 // o Object to refer to
448 // s Signal
449 // max Maximum of signal
450 //
451 AliFMDGeometry* geom = AliFMDGeometry::Instance();
452 Double_t x, y, z;
453 geom->Detector2XYZ(det, rng, sec, str, x, y, z);
454 Float_t size = .1;
455 Float_t zsize = s / max * 10;
456 Float_t r = TMath::Sqrt(x * x + y * y);
457 Float_t theta = TMath::ATan2(r, z);
458 Float_t phi = TMath::ATan2(y, x);
459 Float_t rz = z + (z < 0 ? 1 : -1) * zsize;
460 TMarker3DBox* marker = new TMarker3DBox(x,y,rz,size,size,zsize,theta,phi);
461 if (o) marker->SetRefObject(o);
462 marker->SetLineColor(LookupColor(s, max));
463 fMarkers->Add(marker);
464}
465
bf000c32 466
467//____________________________________________________________________
468Bool_t
a9579262 469AliFMDDisplay::ProcessHit(AliFMDHit* hit, TParticle* /* p */)
bf000c32 470{
02a27b50 471 // Process a hit
bf000c32 472 if (!hit) { AliError("No hit"); return kFALSE; }
a9579262 473 // if (!p) { AliError("No track"); return kFALSE; }
bf000c32 474
a9579262 475 if (fHits) fHits->Add(hit);
bf000c32 476 Float_t size = .1;
a9579262 477 Float_t zsize = TMath::Sqrt(hit->Edep() * 20);
15b17c89 478 Float_t z = hit->Z() + (hit->Z() < 0 ? 1 : -1) * zsize;
bf000c32 479 Float_t pt = TMath::Sqrt(hit->Py()*hit->Py()+hit->Px()*hit->Px());
480 Float_t theta = TMath::ATan2(pt, hit->Pz());
481 Float_t phi = TMath::ATan2(hit->Py(), hit->Px());
15b17c89 482 TMarker3DBox* marker = new TMarker3DBox(hit->X(), hit->Y(), z,
483 size, size, zsize, theta, phi);
bf000c32 484 marker->SetLineColor(LookupColor(hit->Edep(), 1));
485 marker->SetRefObject(hit);
486 fMarkers->Add(marker);
487 return kTRUE;
488}
489
490//____________________________________________________________________
491Bool_t
492AliFMDDisplay::ProcessDigit(AliFMDDigit* digit)
493{
02a27b50 494 // Process a digit
bf000c32 495 if (!digit) { AliError("No digit"); return kFALSE; }
496
bf000c32 497 AliFMDParameters* parm = AliFMDParameters::Instance();
15b17c89 498 UShort_t det = digit->Detector();
499 Char_t ring = digit->Ring();
500 UShort_t sec = digit->Sector();
501 UShort_t str = digit->Strip();
502 Double_t ped = parm->GetPedestal(det,ring, sec, str);
503 Double_t pedW = parm->GetPedestalWidth(det,ring, sec, str);
97b4001e 504 Double_t threshold = ped + fPedestalFactor * pedW;
505 Float_t counts = digit->Counts();
506 AliDebug(10, Form("FMD%d%c[%2d,%3d] ADC: %d > %d (=%4.2f+%4.2f*%4.2f)",
507 digit->Detector(), digit->Ring(), digit->Sector(),
508 digit->Strip(), Int_t(counts), Int_t(threshold),
509 ped, fPedestalFactor, pedW));
a9579262 510 if (fSpec) fSpec->Fill(counts);
15b17c89 511 if (counts < threshold) return kTRUE;
a9579262 512 if (fHits) fHits->Add(digit);
513 if (fSpecCut) fSpecCut->Fill(counts);
15b17c89 514
515 AddMarker(det, ring, sec, str, digit, counts, 1024);
bf000c32 516 return kTRUE;
517}
518
519//____________________________________________________________________
520Bool_t
d760ea03 521AliFMDDisplay::ProcessRaw(AliFMDDigit* digit)
522{
02a27b50 523 // PRocess raw data
d760ea03 524 return ProcessDigit(digit);
525}
526
527//____________________________________________________________________
528Bool_t
bf000c32 529AliFMDDisplay::ProcessRecPoint(AliFMDRecPoint* recpoint)
530{
02a27b50 531 // Process reconstructed point
bf000c32 532 if (!recpoint) { AliError("No recpoint"); return kFALSE; }
15b17c89 533 if (recpoint->Particles() < fMultCut) return kTRUE;
a9579262 534 if (fHits) fHits->Add(recpoint);
15b17c89 535 AddMarker(recpoint->Detector(), recpoint->Ring(), recpoint->Sector(),
536 recpoint->Strip(), recpoint, recpoint->Particles(), 20);
537 return kTRUE;
538}
bf000c32 539
15b17c89 540//____________________________________________________________________
541Bool_t
a9579262 542AliFMDDisplay::ProcessESD(UShort_t det, Char_t rng, UShort_t sec, UShort_t str,
97b4001e 543 Float_t, Float_t mult)
15b17c89 544{
97b4001e 545 Double_t cmult = mult;
a9579262 546 if (fSpec) fSpec->Fill(cmult);
547 if (cmult < fMultCut || cmult == AliESDFMD::kInvalidMult) return kTRUE;
548 AddMarker(det,rng,sec,str, 0, cmult, 20);
549 if (fSpecCut) fSpecCut->Fill(cmult);
bf000c32 550 return kTRUE;
551}
552
553//____________________________________________________________________
554//
555// EOF
556//