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