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