coverity 15108 fixed
[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//
9edefa04 31
d1ddc9bd 32#include <TSystem.h>
9edefa04 33#include <TApplication.h>
34#include <TButton.h>
35#include <TCanvas.h>
36#include <TGeoManager.h>
37#include <TH1D.h>
38#include <TMarker3DBox.h>
39#include <TMath.h>
40#include <TSlider.h>
d98fbfa5 41#include <TSliderBox.h>
9edefa04 42#include <TStyle.h>
43#include <TView.h>
44#include <TVirtualX.h>
d98fbfa5 45#include <TVirtualViewer3D.h>
46#include <TList.h>
9edefa04 47// #include <TArrayF.h>
48// #include <TParticle.h>
49
bf000c32 50#include "AliFMDDisplay.h" // ALIFMDDISPLAY_H
51#include "AliFMDHit.h" // ALIFMDHIT_H
52#include "AliFMDDigit.h" // ALIFMDDIGIT_H
42f1b2f5 53#include "AliFMDSDigit.h" // ALIFMDSDIGIT_H
bf000c32 54#include "AliFMDRecPoint.h" // ALIFMDRECPOINT_H
55#include "AliFMDGeometry.h" // ALIFMDGEOMETRY_H
56#include "AliFMDParameters.h" // ALIFMDPARAMETERS_H
5cf05dbb 57#include "AliFMDRawReader.h" // ALIFMDRAWREADER_H
15b17c89 58#include <AliESDFMD.h> // ALIESDFMD_H
f95a63c4 59// #include <AliLog.h>
60#include "AliFMDDebug.h" // Better debug macros
bf000c32 61
62//____________________________________________________________________
63ClassImp(AliFMDDisplay)
64#if 0
65 ; // This is here to keep Emacs for indenting the next line
66#endif
67
68//____________________________________________________________________
69AliFMDDisplay* AliFMDDisplay::fgInstance = 0;
70
71//____________________________________________________________________
ef8e8623 72const AliFMDDisplay::Range_t AliFMDDisplay::fgkEdepRange = { 100, 0., 2. };
73const AliFMDDisplay::Range_t AliFMDDisplay::fgkAdcRange = { 1024, 0., 1023. };
74const AliFMDDisplay::Range_t AliFMDDisplay::fgkMultRange = { 500, 0., 20. };
75
76
77//____________________________________________________________________
bf000c32 78AliFMDDisplay*
79AliFMDDisplay::Instance()
80{
02a27b50 81 // Return static instance
5c96b03f 82 // If the instance does not exist
83 // it is not created!
bf000c32 84 return fgInstance;
85}
86
87//____________________________________________________________________
a9579262 88AliFMDDisplay::~AliFMDDisplay()
89{
5c96b03f 90 // Destructor.
91 // Cleans
92 // up
a9579262 93 if (fMarkers) {
94 fMarkers->Delete();
95 delete fMarkers;
96 }
97 if (fHits) {
98 fHits->Clear();
99 delete fHits;
100 }
101 if (fPad) delete fPad;
102 fButtons.Delete();
103 if (fSlider) delete fSlider;
104 if (fCanvas) delete fCanvas;
105}
106
107//____________________________________________________________________
108AliFMDDisplay::AliFMDDisplay(Bool_t onlyFMD, const char* gAliceFile)
bf000c32 109 : AliFMDInput(gAliceFile),
110 fWait(kFALSE),
b5ee4425 111 fMarkers(0),
112 fHits(0),
bf000c32 113 fCanvas(0),
114 fPad(0),
17e542eb 115 fButtons(0),
a9579262 116 fSlider(0),
d98fbfa5 117 fFactor(0),
b5ee4425 118 fZoomMode(kFALSE),
119 fX0(0),
120 fY0(0),
121 fX1(0),
122 fY1(0),
b5ee4425 123 fXPixel(0),
124 fYPixel(0),
125 fOldXPixel(0),
126 fOldYPixel(0),
a9579262 127 fLineDrawn(0),
17e542eb 128 fOnlyFMD(onlyFMD),
129 fSpec(0),
130 fSpecCut(0),
d98fbfa5 131 fAux(0),
2eddac03 132 fReturn(kFALSE),
133 fContinous(kFALSE),
e1a9aea4 134 fTimeout("gApplication->StopIdleing()", 10),
135 fInitialMin(0),
136 fInitialMax(1),
137 fInitialFactor(3/10.)
bf000c32 138{
139 // Constructor of an FMD display object.
5c96b03f 140 // Must be called
141 // before Instance
42f1b2f5 142 SetName("AliFMDDisplay");
143 SetTitle("3D Display of various kinds of FMD data");
bf000c32 144 AddLoad(kGeometry);
a9579262 145 if (fgInstance) delete fgInstance;
bf000c32 146 fgInstance = this;
147}
148
149//____________________________________________________________________
1e8f773e 150void
a9579262 151AliFMDDisplay::MakeCanvas(const char** which)
152{
5c96b03f 153 // Make a canvas
154 // Parameters:
155 // which Which button to put up.
a9579262 156 gStyle->SetPalette(1);
d98fbfa5 157 // gStyle->SetCanvasPreferGL(kTRUE);
a9579262 158 Double_t y1 = .10;
159 Int_t w = 700;
42f1b2f5 160 fCanvas = new TCanvas(Form("gl%s", GetName()),
161 Form("%s - Display", GetTitle()),
162 w, Int_t(w / (1-y1)));
a9579262 163 fCanvas->SetFillColor(1);
164 fCanvas->ToggleEventStatus();
165 fCanvas->cd();
d98fbfa5 166 fPad = new TPad("glview", "3DView", 0.0, y1, 1.0, 1.0, 1, 0, 0);
a9579262 167 fPad->Draw();
d98fbfa5 168
169 const char** p = which;
170 const char* m;
171 Int_t n = 0;
172 Int_t j = 0;
173 while (*(p++)) n++;
f38b1653 174 AliFMDDebug(1, ("Got %d buttons", n));
d98fbfa5 175 if (n <= 0) return;
a9579262 176
177 Double_t yb = 0;
d98fbfa5 178 Double_t xb = 1;
a9579262 179 fCanvas->cd();
59194467 180 if (TESTBIT(fTreeMask, kDigits) ||
e064ab4a 181 TESTBIT(fTreeMask, kRawCalib) ||
59194467 182 TESTBIT(fTreeMask, kRaw)) {
d98fbfa5 183 yb = .05;
184 xb = .66;
185 fFactor = new TSlider("pedFactor", "Pedestal Factor", xb+.01, 0, 1, yb);
186 fFactor->SetMethod("AliFMDDisplay::Instance()->ChangeFactor()");
e1a9aea4 187 fFactor->SetRange(fInitialFactor, 1);
d98fbfa5 188 fFactor->Draw();
e1a9aea4 189 fFactor->SetMinimum(fInitialFactor);
d98fbfa5 190 TSliderBox *sbox =
191 static_cast<TSliderBox*>(fFactor->GetListOfPrimitives()->
192 FindObject("TSliderBox"));
193 if (sbox) {
194 sbox->SetToolTipText("Adjust the noise suppression factor by moving "
195 "lower limit");
196 }
197 }
42f1b2f5 198 if (TESTBIT(fTreeMask, kHits) ||
199 TESTBIT(fTreeMask, kESD) ||
200 TESTBIT(fTreeMask, kDigits) ||
201 TESTBIT(fTreeMask, kSDigits) ||
e064ab4a 202 TESTBIT(fTreeMask, kRaw) ||
203 TESTBIT(fTreeMask, kRawCalib)) {
a9579262 204 yb = .05;
d98fbfa5 205 fSlider = new TSlider("genCut", "Multiplicity cut", 0, 0, xb, yb);
a9579262 206 fSlider->SetMethod("AliFMDDisplay::Instance()->ChangeCut()");
e1a9aea4 207 fSlider->SetRange(fInitialMin,fInitialMax);
a9579262 208 fSlider->Draw();
d98fbfa5 209 TSliderBox *sbox =
210 static_cast<TSliderBox*>(fSlider->GetListOfPrimitives()->
211 FindObject("TSliderBox"));
212 if (sbox) {
213 sbox->SetToolTipText("Adjust lower and upper limit on data signal");
214 }
a9579262 215 }
e1a9aea4 216 // fCanvas->Modified();
217 // fCanvas->Update();
218 // fCanvas->cd();
a9579262 219 Float_t x0 = 0;
220 Float_t dx = 1. / n;
221 p = which;
222 while ((m = *(p++))) {
223 fCanvas->cd();
f38b1653 224 AliFMDDebug(1, ("Adding button %s", m));
a9579262 225 TButton* b = new TButton(m, Form("AliFMDDisplay::Instance()->%s()", m),
d98fbfa5 226 x0, yb, TMath::Min(x0 + dx,.999F), y1);
a9579262 227 b->Draw();
228 fButtons.Add(b);
229 x0 += dx;
230 j++;
231 }
232}
233
234//____________________________________________________________________
235void
236AliFMDDisplay::ShowOnlyFMD()
237{
5c96b03f 238 // Show only the FMD
239 // Do not show
240 // other volumes
a9579262 241 if (!fGeoManager) return;
242 static bool once = false;
243 if (once) return;
244 once = true;
245 AliInfo("Will only show the FMD");
246 TGeoVolume* top = gGeoManager->GetTopVolume();
247 top->InvisibleAll(kTRUE);
248 TGeoIterator next(top);
249 TGeoNode* node;
250 TGeoVolume* v = 0;
251 Bool_t hasFMD1 = kFALSE;
252 Bool_t hasFMD2 = kFALSE;
253 Bool_t hasFMD3 = kFALSE;
f38b1653 254 AliFMDDebug(1, ("Getting material FMD_Si$"));
d98fbfa5 255 TGeoMaterial* si = gGeoManager->GetMaterial("FMD_Si$"); // kRed
f38b1653 256 AliFMDDebug(1, ("Getting material FMD_Carbon$"));
d98fbfa5 257 TGeoMaterial* c = gGeoManager->GetMaterial("FMD_Carbon$"); // kGray
f38b1653 258 AliFMDDebug(1, ("Getting material FMD_Aluminum$"));
d98fbfa5 259 TGeoMaterial* al = gGeoManager->GetMaterial("FMD_Aluminum$");// kGray-2
f38b1653 260 AliFMDDebug(1, ("Getting material FMD_Copper$"));
d98fbfa5 261 TGeoMaterial* cu = gGeoManager->GetMaterial("FMD_Copper$"); // kGreen-2
f38b1653 262 AliFMDDebug(1, ("Getting material FMD_PCB$"));
d98fbfa5 263 TGeoMaterial* pcb = gGeoManager->GetMaterial("FMD_PCB$"); // kGreen+2
f38b1653 264 AliFMDDebug(1, ("Getting material FMD_PCB$"));
d98fbfa5 265 TGeoMaterial* chip = gGeoManager->GetMaterial("FMD_Si Chip$");// kGreen+2
266 TObjArray toshow;
a9579262 267 while ((node = static_cast<TGeoNode*>(next()))) {
268 const char* name = node->GetName();
269 if (!name) continue;
270 if (!(v = node->GetVolume())) continue;
271
272 if (name[0] == 'F') {
d98fbfa5 273 TGeoMaterial* m = (v->IsAssembly() ? 0 : v->GetMaterial());
274 Int_t col = -1;
275 if (m == si) col = kRed;
276 else if (m == c) col = kGray;
277 else if (m == al) col = kYellow+4;
278 else if (m == cu) col = kRed+6;
279 else if (m == pcb) col = kGreen+2;
280 else if (m == chip) col = kGreen+4;
281 if (col >= 0) {
282 v->SetLineColor(col);
283 v->SetFillColor(col);
284 }
a9579262 285 if (name[2] == 'M' && (name[3] == 'T' || name[3] == 'B')) {
286 // Virtual Master half-ring volume - top-level
287 Int_t det = node->GetNumber();
288 switch (det) {
289 case 1: hasFMD1 = true; break;
290 case 2: hasFMD2 = true; break;
291 case 3: hasFMD3 = true; break;
292 default: continue;
293 }
294 toshow.Add(v);
295 }
296 else if (name[3] == 'V' && (name[2] == 'T' || name[2] == 'B'))
297 toshow.Add(v); // Virtual Half-ring, bare detectors
d98fbfa5 298 else if (name[3] == 'H' && (name[2] == 'F' || name[2] == 'B'))
299 toshow.Add(v); // Virtual Hybrid container
300 else if (name[2] == 'S' && name[3] == 'U')
301 toshow.Add(v); // Virtual support structre
a9579262 302 // else if (name[3] == 'H' && (name[2] == 'F' || name[2] == 'B'))
303 // toshow.Add(v); // Virtual Hybrid container
304 }
305 v->SetVisibility(kFALSE);
306 v->SetVisDaughters(kFALSE);
307 v->InvisibleAll(kTRUE);
308 }
309 TIter i(&toshow);
310 while ((v = static_cast<TGeoVolume*>(i()))) {
d98fbfa5 311 if (!v->IsAssembly())
312 v->SetVisibility(kTRUE);
a9579262 313 v->InvisibleAll(kFALSE);
d98fbfa5 314 v->SetVisDaughters(kTRUE);
315
a9579262 316 }
317}
318
319
320//____________________________________________________________________
321void
bf000c32 322AliFMDDisplay::ExecuteEvent(Int_t event, Int_t px, Int_t py)
323{
5c96b03f 324 // Execute an event on canvas
325 // Parameters:
326 // event What happened
327 // px, py Pixel coordinates
bf000c32 328 if (px == 0 && py == 0) return;
329 if (!fZoomMode && fPad->GetView()) {
330 fPad->GetView()->ExecuteRotateView(event, px, py);
331 return;
332 }
333 fPad->SetCursor(kCross);
334 switch (event) {
335 case kButton1Down:
336 fPad->TAttLine::Modify();
337 fX0 = fPad->AbsPixeltoX(px);
338 fY0 = fPad->AbsPixeltoY(py);
339 fXPixel = fOldXPixel = px;
340 fYPixel = fOldYPixel = py;
341 fLineDrawn = kFALSE;
342 return;
343 case kButton1Motion:
344 if (fLineDrawn)
345 gVirtualX->DrawBox(fXPixel, fYPixel, fOldXPixel, fOldYPixel,
346 TVirtualX::kHollow);
347 fOldXPixel = px;
348 fOldYPixel = py;
349 fLineDrawn = kTRUE;
350 gVirtualX->DrawBox(fXPixel, fYPixel, fOldXPixel, fOldYPixel,
351 TVirtualX::kHollow);
352 return;
353 case kButton1Up:
354 fPad->GetCanvas()->FeedbackMode(kFALSE);
355 if (px == fXPixel || py == fYPixel) return;
356 fX1 = fPad->AbsPixeltoX(px);
357 fY1 = fPad->AbsPixeltoY(py);
358 if (fX1 < fX0) std::swap(fX0, fX1);
359 if (fY1 < fY0) std::swap(fY0, fY1);
360 fPad->Range(fX0, fY0, fX1, fY1);
361 fPad->Modified();
362 return;
363 }
364}
365
366//____________________________________________________________________
bf000c32 367Bool_t
368AliFMDDisplay::Init()
369{
5c96b03f 370 // Initialize. GEt transforms and such,
371 // so that we can draw thins properly
372 // Returns true on success
bf000c32 373 if (!AliFMDInput::Init()) return kFALSE;
374 AliFMDGeometry* geom = AliFMDGeometry::Instance();
375 geom->Init();
376 geom->InitTransformations();
97b4001e 377 if (TESTBIT(fTreeMask, kDigits) || TESTBIT(fTreeMask, kRaw))
378 AliFMDParameters::Instance()->Init();
379
a9579262 380 fMarkers = new TObjArray;
381 fHits = new TObjArray;
382 fMarkers->SetOwner(kTRUE);
383 fHits->SetOwner(kFALSE);
bf000c32 384 return kTRUE;
385}
a9579262 386
387//____________________________________________________________________
388void
389AliFMDDisplay::MakeAux()
390{
5c96b03f 391 // MAke the aux canvas
392 // This is used to display spectra
393 // etc,
ef8e8623 394 const Range_t* range = 0;
395 if (TESTBIT(fTreeMask, kESD)) range = &fgkMultRange;
e064ab4a 396 else if (TESTBIT(fTreeMask, kRawCalib)) range = &fgkMultRange;
ef8e8623 397 else if (TESTBIT(fTreeMask, kDigits)) range = &fgkAdcRange;
398 else if (TESTBIT(fTreeMask, kSDigits)) range = &fgkAdcRange;
399 else if (TESTBIT(fTreeMask, kRaw)) range = &fgkAdcRange;
400 else if (TESTBIT(fTreeMask, kHits)) range = &fgkEdepRange;
401 if (!range) return;
402
403 if (!fAux) {
e1a9aea4 404 fAux = new TCanvas(Form("aux_%s", GetName()),
405 Form("Aux - %s", GetTitle()));
ef8e8623 406 fAux->SetLogy();
5cf05dbb 407 fAux->SetFillColor(kWhite);
408 fAux->SetBorderMode(0);
409 fAux->SetBorderSize(0);
ef8e8623 410 Float_t dBin = (range->fHigh - range->fLow) / range->fNbins;
411 fSpec = new TH1D("spec", "Spectra", range->fNbins,
5cf05dbb 412 range->fLow-dBin/2, range->fHigh+dBin/2);
ef8e8623 413 fSpecCut = static_cast<TH1*>(fSpec->Clone("specCut"));
e1a9aea4 414 TString xTitle((TESTBIT(fTreeMask, kRawCalib) ||
415 TESTBIT(fTreeMask, kESD)) ? "#Delta E/#Delta E_{mip}" :
416 (TESTBIT(fTreeMask, kDigits) ||
417 TESTBIT(fTreeMask, kSDigits) ||
418 TESTBIT(fTreeMask, kRaw)) ? "ADC [counts]" :
419 TESTBIT(fTreeMask, kHits) ? "Hits" : "signal");
420 fSpec->SetXTitle(xTitle.Data());
5cf05dbb 421 fSpec->SetYTitle("events");
ef8e8623 422 fSpec->SetFillColor(2);
423 fSpec->SetFillStyle(3001);
e1a9aea4 424 fSpecCut->SetXTitle(xTitle.Data());
5cf05dbb 425 fSpecCut->SetYTitle("events");
ef8e8623 426 fSpecCut->SetFillColor(4);
427 fSpecCut->SetFillStyle(3001);
a9579262 428 }
ef8e8623 429 else {
430 fSpec->Reset();
431 fSpecCut->Reset();
432 }
a9579262 433}
434
435//____________________________________________________________________
436void
437AliFMDDisplay::DrawAux()
438{
5c96b03f 439 // Draw in the Aux the canvas
440 // For example draw the spectra
441 // or such stuff
a9579262 442 if (!fAux) return;
443 fAux->cd();
444 fAux->Clear();
7af3df7f 445 fAux->SetLogy(fSpec->GetMaximum() > 10);
a9579262 446 fSpec->Draw();
447 fSpecCut->Draw("same");
448 fAux->Modified();
449 fAux->Update();
450 fAux->cd();
451}
452
bf000c32 453//____________________________________________________________________
454Bool_t
455AliFMDDisplay::Begin(Int_t event)
456{
02a27b50 457 // Begin of event. Make canvas is not already done
5c96b03f 458 // Parameters:
459 // event The event number
bf000c32 460 if (!fCanvas) {
d98fbfa5 461 const char* m[] = { "Continue",
462 "Break",
463 "Zoom",
464 "Pick",
465 "Redisplay",
466 "Render",
467 0 };
a9579262 468 MakeCanvas(m);
bf000c32 469 }
97b4001e 470 MakeAux();
d98fbfa5 471 fReturn = kFALSE;
472
a9579262 473 // AliInfo("Clearing canvas");
bf000c32 474 // fCanvas->Clear();
475 if (!fGeoManager) {
476 Warning("End", "No geometry manager");
477 return kFALSE;
478 }
f38b1653 479 AliFMDDebug(1, ("Drawing geometry"));
bf000c32 480 fPad->cd();
481 fGeoManager->GetTopVolume()->Draw();
a9579262 482 if (fOnlyFMD) ShowOnlyFMD();
f38b1653 483 AliFMDDebug(1, ("Adjusting view"));
bf000c32 484 Int_t irep;
485 if (fPad->GetView()) {
486 fPad->GetView()->SetView(-200, -40, 80, irep);
487 fPad->GetView()->Zoom();
488 fPad->Modified();
489 fPad->cd();
490 }
491 return AliFMDInput::Begin(event);
492}
493
494//____________________________________________________________________
a9579262 495void
496AliFMDDisplay::AtEnd()
bf000c32 497{
5c96b03f 498 // Called at of the event.
499 // Draw stuff.
500 // Draw spectrum.
bf000c32 501 fPad->cd();
502 fMarkers->Draw();
1e8f773e 503 fPad->cd();
bf000c32 504 AppendPad();
bf000c32 505 fPad->cd();
a9579262 506 DrawAux();
507}
508
509//____________________________________________________________________
510void
511AliFMDDisplay::Idle()
512{
5c96b03f 513 // Idle loop.
514 // Sends the ROOT loop into the idle loop,
515 // so that we can go on.
bf000c32 516 fWait = kTRUE;
2eddac03 517 if (fContinous) fTimeout.Start(10, kTRUE);
bf000c32 518 while (fWait) {
519 gApplication->StartIdleing();
520 gSystem->InnerLoop();
521 gApplication->StopIdleing();
2eddac03 522 if (fContinous) break;
bf000c32 523 }
e2c858f2 524 AliFMDDebug(3, ("After idle loop"));
a9579262 525 if (fMarkers) fMarkers->Delete();
526 if (fHits) fHits->Clear();
e2c858f2 527 AliFMDDebug(3, ("After clearing caches"));
a9579262 528}
529
530//____________________________________________________________________
531Bool_t
532AliFMDDisplay::End()
533{
534 // End of event. Draw everything
535 AtEnd();
536 Idle();
d98fbfa5 537 if (fReturn) return kFALSE;
bf000c32 538 return AliFMDInput::End();
539}
540
541//____________________________________________________________________
542Int_t
d98fbfa5 543AliFMDDisplay::LookupColor(Float_t x, Float_t min, Float_t max) const
bf000c32 544{
5c96b03f 545 // Look-up color.
546 // Get a colour from the current palette depending
547 // on the ratio x/max
d98fbfa5 548 Float_t range = (max-min);
549 Float_t l = fSlider->GetMinimum();
550 Float_t h = fSlider->GetMaximum();
551 if (l == h) { l = 0; h = 1; }
552 Float_t cmin = range * l;
553 Float_t cmax = range * h;
554 Float_t crange = (cmax-cmin);
555 Int_t idx = Int_t((x-cmin) / crange * gStyle->GetNumberOfColors());
bf000c32 556 return gStyle->GetColorPalette(idx);
d98fbfa5 557}
bf000c32 558
15b17c89 559//____________________________________________________________________
560void
ef8e8623 561AliFMDDisplay::SetCut(Float_t l, Float_t h)
562{
563 // Change the cut on the slider.
e1a9aea4 564 fInitialMin = l;
565 fInitialMax = h;
566 if (!fSlider) return;
567 fSlider->SetMinimum(fInitialMin);
568 fSlider->SetMaximum(fInitialMax);
ef8e8623 569 ChangeCut();
570}
571
572//____________________________________________________________________
573void
e1a9aea4 574AliFMDDisplay::SetFactor(Float_t f)
575{
576 // Change the cut on the slider.
577 fInitialFactor = f / 10;
578 if (!fFactor) return;
579 fFactor->SetMinimum(fInitialFactor);
580 ChangeFactor();
581}
582
583//____________________________________________________________________
584void
a9579262 585AliFMDDisplay::ChangeCut()
586{
5c96b03f 587 // Change the cut on the slider.
588 // The factor depends on what is
589 // drawn in the AUX canvas
ef8e8623 590 AliInfo(Form("Range is now %7.5f - %7.5f", fSlider->GetMinimum(),
d98fbfa5 591 fSlider->GetMaximum()));
e064ab4a 592 if ((TESTBIT(fTreeMask, kESD) ||
593 TESTBIT(fTreeMask, kDigits) ||
ef8e8623 594 TESTBIT(fTreeMask, kSDigits) ||
e064ab4a 595 TESTBIT(fTreeMask, kRaw) ||
596 TESTBIT(fTreeMask, kRawCalib))) {
ef8e8623 597 Float_t l = fSlider->GetMinimum();
598 Float_t h = fSlider->GetMaximum();
599 l = 1024 * l + 0;
600 h = 1024 * h + 0;
601 AliInfo(Form("ADC range is now %4d - %4d", int(l), int(h)));
602 }
d98fbfa5 603 Redisplay();
604}
605//____________________________________________________________________
606void
607AliFMDDisplay::ChangeFactor()
608{
609 // Change the cut on the slider.
610 // The factor depends on what is
611 // drawn in the AUX canvas
e064ab4a 612 AliInfo(Form("Noise factor is now %4.1f", 10 * fFactor->GetMinimum()));
a9579262 613 Redisplay();
614}
615
616//____________________________________________________________________
617void
618AliFMDDisplay::Redisplay()
619{
5c96b03f 620 // Redisplay stuff.
621 // Redraw markers, hits,
622 // spectra
a9579262 623 if (fMarkers) fMarkers->Delete();
624 if (fHits) fHits->Clear();
625 if (fSpec) fSpec->Reset();
626 if (fSpecCut) fSpecCut->Reset();
627 Event();
628 AtEnd();
629}
d98fbfa5 630//____________________________________________________________________
631void
632AliFMDDisplay::Break()
633{
634 // Redisplay stuff.
635 // Redraw markers, hits,
636 // spectra
637 if (fMarkers) fMarkers->Delete();
638 if (fHits) fHits->Clear();
639 if (fSpec) fSpec->Reset();
640 if (fSpecCut) fSpecCut->Reset();
641 fReturn = kTRUE;
642 fWait = kFALSE;
643}
644//____________________________________________________________________
645void
646AliFMDDisplay::Render()
647{
648 fPad->cd();
649 TVirtualViewer3D* viewer = fPad->GetViewer3D("ogl");
650 if (!viewer) return;
651}
a9579262 652
653//____________________________________________________________________
654void
d98fbfa5 655AliFMDDisplay::AddMarker(Float_t x, Float_t y, Float_t z,
656 TObject* o, Float_t s, Float_t min, Float_t max)
15b17c89 657{
658 // Add a marker to the display
659 //
660 // det Detector
661 // rng Ring
662 // sec Sector
663 // str Strip
664 // o Object to refer to
665 // s Signal
666 // max Maximum of signal
667 //
15b17c89 668 Float_t size = .1;
d98fbfa5 669 Float_t zsize = (s - min) / (max-min) * 10;
15b17c89 670 Float_t r = TMath::Sqrt(x * x + y * y);
671 Float_t theta = TMath::ATan2(r, z);
672 Float_t phi = TMath::ATan2(y, x);
673 Float_t rz = z + (z < 0 ? 1 : -1) * zsize;
674 TMarker3DBox* marker = new TMarker3DBox(x,y,rz,size,size,zsize,theta,phi);
675 if (o) marker->SetRefObject(o);
d98fbfa5 676 marker->SetLineColor(LookupColor(s, min, max));
15b17c89 677 fMarkers->Add(marker);
678}
d98fbfa5 679//____________________________________________________________________
680void
681AliFMDDisplay::AddMarker(UShort_t det, Char_t rng, UShort_t sec, UShort_t str,
682 TObject* o, Float_t s, Float_t min, Float_t max)
683{
684 // Add a marker to the display
685 //
686 // det Detector
687 // rng Ring
688 // sec Sector
689 // str Strip
690 // o Object to refer to
691 // s Signal
692 // max Maximum of signal
693 //
694 AliFMDGeometry* geom = AliFMDGeometry::Instance();
695 Double_t x, y, z;
696 geom->Detector2XYZ(det, rng, sec, str, x, y, z);
697 AddMarker(x,y,z,o,s,min,max);
698}
15b17c89 699
d98fbfa5 700//____________________________________________________________________
701Bool_t
702AliFMDDisplay::InsideCut(Float_t val, const Float_t& min,
703 const Float_t& max) const
704{
705 Float_t r = max - min;
706 Float_t l = fSlider->GetMinimum();
707 Float_t h = fSlider->GetMaximum();
708 if (l == h) { l = 0; h = 1; }
e064ab4a 709 if (val < r * l + min || val > r * h + min) {
e2c858f2 710 AliFMDDebug(2, ("Value %f is outside cut %f - %f (range %f - %f)",
e064ab4a 711 val, min+r*l, min+r*h, min, max));
712 return kFALSE;
713 }
d98fbfa5 714 return kTRUE;
715}
716
bf000c32 717
718//____________________________________________________________________
719Bool_t
a9579262 720AliFMDDisplay::ProcessHit(AliFMDHit* hit, TParticle* /* p */)
bf000c32 721{
5c96b03f 722 // Process a hit.
723 // Parameters:
724 // hit Hit data
ef8e8623 725 static const Float_t rMin = fgkEdepRange.fLow;
726 static const Float_t rMax = fgkEdepRange.fHigh;
d98fbfa5 727
bf000c32 728 if (!hit) { AliError("No hit"); return kFALSE; }
a9579262 729 // if (!p) { AliError("No track"); return kFALSE; }
d98fbfa5 730 Float_t edep = hit->Edep();
731
ef8e8623 732 if (fHits) fHits->Add(hit);
733 if (fSpec) fSpec->Fill(edep);
d98fbfa5 734 if (!InsideCut(edep, rMin, rMax)) return kTRUE;
ef8e8623 735 if (fSpecCut) fSpecCut->Fill(edep);
d98fbfa5 736
737 AddMarker(hit->X(), hit->Y(), hit->Z(), hit, edep, rMin, rMax);
bf000c32 738 return kTRUE;
739}
740
741//____________________________________________________________________
742Bool_t
743AliFMDDisplay::ProcessDigit(AliFMDDigit* digit)
744{
02a27b50 745 // Process a digit
5c96b03f 746 // Parameters:
747 // digit Digit information
ef8e8623 748 static const Float_t rMin = fgkAdcRange.fLow;
749 static const Float_t rMax = fgkAdcRange.fHigh;
d98fbfa5 750
bf000c32 751 if (!digit) { AliError("No digit"); return kFALSE; }
752
15b17c89 753 UShort_t det = digit->Detector();
754 Char_t ring = digit->Ring();
755 UShort_t sec = digit->Sector();
756 UShort_t str = digit->Strip();
e064ab4a 757 Double_t threshold = GetADCThreshold(det, ring, sec, str);
97b4001e 758 Float_t counts = digit->Counts();
e064ab4a 759 if (threshold < 0) { counts += -threshold; threshold = 0; }
d98fbfa5 760
59194467 761 AliFMDDebug(10, ("FMD%d%c[%02d,%03d] counts %4d threshold %4d",
762 det, ring, sec, str, Int_t(counts), Int_t(threshold)));
d98fbfa5 763 if (fHits) fHits->Add(digit);
764 if (fSpec) fSpec->Fill(counts);
765 if (!InsideCut(counts-threshold, rMin, rMax)) return kTRUE;
766 if (fSpecCut) fSpecCut->Fill(counts);
767
768
769 AddMarker(det, ring, sec, str, digit, counts, rMin, rMax);
bf000c32 770 return kTRUE;
771}
772
773//____________________________________________________________________
774Bool_t
42f1b2f5 775AliFMDDisplay::ProcessSDigit(AliFMDSDigit* sdigit)
776{
777 // Process a sdigit
778 // Parameters:
779 // sdigit Digit information
ef8e8623 780 static const Float_t rMin = fgkAdcRange.fLow;
781 static const Float_t rMax = fgkAdcRange.fHigh;
42f1b2f5 782
42f1b2f5 783 if (!sdigit) { AliError("No sdigit"); return kFALSE; }
784
785 UShort_t det = sdigit->Detector();
786 Char_t ring = sdigit->Ring();
787 UShort_t sec = sdigit->Sector();
788 UShort_t str = sdigit->Strip();
789 Float_t counts = sdigit->Counts();
790
791 if (fHits) fHits->Add(sdigit);
792 if (fSpec) fSpec->Fill(counts);
793 if (!InsideCut(counts, rMin, rMax)) return kTRUE;
794 if (fSpecCut) fSpecCut->Fill(counts);
795
42f1b2f5 796 AddMarker(det, ring, sec, str, sdigit, counts, rMin, rMax);
797 return kTRUE;
798}
799
800//____________________________________________________________________
801Bool_t
59194467 802AliFMDDisplay::ProcessRawDigit(AliFMDDigit* digit)
d760ea03 803{
02a27b50 804 // PRocess raw data
5c96b03f 805 // Parameters:
806 // digit Digit information
59194467 807 AliFMDDebug(50, ("Forwarding call of ProcessRaw to ProcessDigit "
a828379a 808 "for FMD%d%c[%02d,%03d] %d",
59194467 809 digit->Detector(), digit->Ring(), digit->Sector(),
810 digit->Strip(), digit->Counts()));
d760ea03 811 return ProcessDigit(digit);
812}
813
814//____________________________________________________________________
815Bool_t
e064ab4a 816AliFMDDisplay::ProcessRawCalibDigit(AliFMDDigit* digit)
817{
818 // Process a digit
819 // Parameters:
820 // digit Digit information
821 static const Float_t rMin = fgkMultRange.fLow;
822 static const Float_t rMax = fgkMultRange.fHigh;
823 static const Float_t aMin = fgkAdcRange.fLow;
824 static const Float_t aMax = fgkAdcRange.fHigh;
825
826 if (!digit) { AliError("No digit"); return kFALSE; }
827
828 AliFMDParameters* parm = AliFMDParameters::Instance();
829 UShort_t det = digit->Detector();
830 Char_t ring = digit->Ring();
831 UShort_t sec = digit->Sector();
832 UShort_t str = digit->Strip();
833 Double_t gain = parm->GetPulseGain(det, ring, sec, str);
834 Double_t ped = parm->GetPedestal(det, ring, sec, str);
835 Double_t threshold = GetADCThreshold(det, ring, sec, str);
836 Float_t counts = digit->Counts();
837 if (threshold < 0) { counts += -threshold; threshold = 0; ped = 0; }
838
839 // Double_t edep = ((counts * parm->GetEdepMip() /
840 // (gain * parm->GetDACPerMIP()));
841 Double_t mult = (counts-ped) / (gain * parm->GetDACPerMIP());
e1a9aea4 842 if (gain < 0.1 || gain > 10) mult = 0;
e064ab4a 843
844
845 AliFMDDebug(10, ("FMD%d%c[%02d,%03d] adc %4d "
846 "(threshold %4d, gain %6.3f) -> mult %7.4f",
847 det, ring, sec, str, int(counts), int(threshold),
848 gain, mult));
849 if (fHits) fHits->Add(digit);
850 if (fSpec) fSpec->Fill(mult);
851 if (!InsideCut(counts-threshold, aMin, aMax)) return kTRUE;
852 if (fSpecCut) fSpecCut->Fill(mult);
853
854 if (mult >= 0)
855 AddMarker(det, ring, sec, str, digit, mult, rMin, rMax);
856 return kTRUE;
857}
858
859//____________________________________________________________________
860Bool_t
bf000c32 861AliFMDDisplay::ProcessRecPoint(AliFMDRecPoint* recpoint)
862{
02a27b50 863 // Process reconstructed point
5c96b03f 864 // Parameters:
865 // recpoint Reconstructed multiplicity/energy
ef8e8623 866 static const Float_t rMin = fgkMultRange.fLow;
867 static const Float_t rMax = fgkMultRange.fHigh;
868
d98fbfa5 869
bf000c32 870 if (!recpoint) { AliError("No recpoint"); return kFALSE; }
d98fbfa5 871
872 if (!InsideCut(recpoint->Particles(), rMin, rMax)) return kTRUE;
873
a9579262 874 if (fHits) fHits->Add(recpoint);
15b17c89 875 AddMarker(recpoint->Detector(), recpoint->Ring(), recpoint->Sector(),
d98fbfa5 876 recpoint->Strip(), recpoint, recpoint->Particles(), rMin, rMax);
15b17c89 877 return kTRUE;
878}
bf000c32 879
15b17c89 880//____________________________________________________________________
881Bool_t
a9579262 882AliFMDDisplay::ProcessESD(UShort_t det, Char_t rng, UShort_t sec, UShort_t str,
97b4001e 883 Float_t, Float_t mult)
15b17c89 884{
5c96b03f 885 // Process data from ESD
886 // Parameters
887 // det,rng,sec,str Detector coordinates.
888 // mult Multiplicity.
ef8e8623 889 static const Float_t rMin = fgkMultRange.fLow;
890 static const Float_t rMax = fgkMultRange.fHigh;
d98fbfa5 891
97b4001e 892 Double_t cmult = mult;
a9579262 893 if (fSpec) fSpec->Fill(cmult);
d98fbfa5 894 if (!InsideCut(cmult, rMin, rMax) || cmult == AliESDFMD::kInvalidMult)
895 return kTRUE;
896
897 AddMarker(det,rng,sec,str, 0, cmult, rMin, rMax);
898
a9579262 899 if (fSpecCut) fSpecCut->Fill(cmult);
d98fbfa5 900
bf000c32 901 return kTRUE;
902}
903
3afd9281 904//____________________________________________________________________
e064ab4a 905Double_t
906AliFMDDisplay::GetADCThreshold(UShort_t d, Char_t r,
907 UShort_t s, UShort_t t) const
908{
909 AliFMDParameters* parm = AliFMDParameters::Instance();
910 Double_t ped = parm->GetPedestal(d,r, s, t);
911 Double_t pedW = parm->GetPedestalWidth(d,r, s, t);
912 Double_t threshold = 0;
913 if (fFMDReader && fFMDReader->IsZeroSuppressed(d-1))
914 threshold = - fFMDReader->NoiseFactor(d-1) * pedW;
915 else
916 threshold = ped + pedW * 10 * fFactor->GetMinimum();
917 AliFMDDebug(10, ("FMD%d%c[%2d,%3d] ped: %f +/- %f [factor: %f-%f]",
918 d, r, s, t, ped, pedW,
919 fFactor->GetMinimum(), fFactor->GetMaximum()));
920 if (threshold > fgkAdcRange.fHigh) threshold = fgkAdcRange.fHigh;
921 return threshold;
922}
923
bf000c32 924//____________________________________________________________________
925//
926// EOF
927//
6c652449 928