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