1 /**************************************************************************
2 * Copyright(c) 2004, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
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
21 //___________________________________________________________________
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.
29 // Latest changes by Christian Holm Christensen
33 #include <TApplication.h>
36 #include <TGeoManager.h>
38 #include <TMarker3DBox.h>
43 #include <TVirtualX.h>
44 // #include <TArrayF.h>
45 // #include <TParticle.h>
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
53 #include <AliESDFMD.h> // ALIESDFMD_H
54 // #include <AliLog.h>
55 #include "AliFMDDebug.h" // Better debug macros
57 //____________________________________________________________________
58 ClassImp(AliFMDDisplay)
60 ; // This is here to keep Emacs for indenting the next line
63 //____________________________________________________________________
64 AliFMDDisplay* AliFMDDisplay::fgInstance = 0;
66 //____________________________________________________________________
68 AliFMDDisplay::Instance()
70 // Return static instance
71 // If the instance does not exist
76 //____________________________________________________________________
77 AliFMDDisplay::~AliFMDDisplay()
90 if (fPad) delete fPad;
92 if (fSlider) delete fSlider;
93 if (fCanvas) delete fCanvas;
96 //____________________________________________________________________
97 AliFMDDisplay::AliFMDDisplay(Bool_t onlyFMD, const char* gAliceFile)
98 : AliFMDInput(gAliceFile),
119 // Constructor of an FMD display object.
123 if (fgInstance) delete fgInstance;
125 SetMultiplicityCut();
129 //____________________________________________________________________
131 AliFMDDisplay::MakeCanvas(const char** which)
135 // which Which button to put up.
136 gStyle->SetPalette(1);
139 fCanvas = new TCanvas("display", "Display", w, Int_t(w / (1-y1)));
140 fCanvas->SetFillColor(1);
141 fCanvas->ToggleEventStatus();
143 fPad = new TPad("view", "3DView", 0.0, y1, 1.0, 1.0, 1, 0, 0);
148 if (TESTBIT(fTreeMask, kESD) ||
149 TESTBIT(fTreeMask, kDigits) ||
150 TESTBIT(fTreeMask, kRaw)) {
152 fSlider = new TSlider("multCut", "Multiplicity cut", 0, 0, 1, yb);
153 fSlider->SetMethod("AliFMDDisplay::Instance()->ChangeCut()");
155 fSlider->SetMinimum(TESTBIT(fTreeMask, kESD) ? fMultCut * 10 :
156 fPedestalFactor * 10);
158 const char** p = which;
163 AliInfo(Form("Got %d buttons", n));
167 while ((m = *(p++))) {
169 AliInfo(Form("Adding button %s", m));
170 TButton* b = new TButton(m, Form("AliFMDDisplay::Instance()->%s()", m),
171 x0, yb, x0 + dx, y1);
179 //____________________________________________________________________
181 AliFMDDisplay::ShowOnlyFMD()
186 if (!fGeoManager) return;
187 static bool once = false;
190 AliInfo("Will only show the FMD");
191 TGeoVolume* top = gGeoManager->GetTopVolume();
192 top->InvisibleAll(kTRUE);
193 TGeoIterator next(top);
196 Bool_t hasFMD1 = kFALSE;
197 Bool_t hasFMD2 = kFALSE;
198 Bool_t hasFMD3 = kFALSE;
200 while ((node = static_cast<TGeoNode*>(next()))) {
201 const char* name = node->GetName();
203 if (!(v = node->GetVolume())) continue;
205 if (name[0] == 'F') {
206 if (name[2] == 'M' && (name[3] == 'T' || name[3] == 'B')) {
207 // Virtual Master half-ring volume - top-level
208 Int_t det = node->GetNumber();
210 case 1: hasFMD1 = true; break;
211 case 2: hasFMD2 = true; break;
212 case 3: hasFMD3 = true; break;
217 else if (name[3] == 'V' && (name[2] == 'T' || name[2] == 'B'))
218 toshow.Add(v); // Virtual Half-ring, bare detectors
219 // else if (name[3] == 'H' && (name[2] == 'F' || name[2] == 'B'))
220 // toshow.Add(v); // Virtual Hybrid container
222 v->SetVisibility(kFALSE);
223 v->SetVisDaughters(kFALSE);
224 v->InvisibleAll(kTRUE);
227 while ((v = static_cast<TGeoVolume*>(i()))) {
228 v->SetVisibility(kTRUE);
229 v->SetVisDaughters(kTRUE);
230 v->InvisibleAll(kFALSE);
235 //____________________________________________________________________
237 AliFMDDisplay::ExecuteEvent(Int_t event, Int_t px, Int_t py)
239 // Execute an event on canvas
241 // event What happened
242 // px, py Pixel coordinates
243 if (px == 0 && py == 0) return;
244 if (!fZoomMode && fPad->GetView()) {
245 fPad->GetView()->ExecuteRotateView(event, px, py);
248 fPad->SetCursor(kCross);
251 fPad->TAttLine::Modify();
252 fX0 = fPad->AbsPixeltoX(px);
253 fY0 = fPad->AbsPixeltoY(py);
254 fXPixel = fOldXPixel = px;
255 fYPixel = fOldYPixel = py;
260 gVirtualX->DrawBox(fXPixel, fYPixel, fOldXPixel, fOldYPixel,
265 gVirtualX->DrawBox(fXPixel, fYPixel, fOldXPixel, fOldYPixel,
269 fPad->GetCanvas()->FeedbackMode(kFALSE);
270 if (px == fXPixel || py == fYPixel) return;
271 fX1 = fPad->AbsPixeltoX(px);
272 fY1 = fPad->AbsPixeltoY(py);
273 if (fX1 < fX0) std::swap(fX0, fX1);
274 if (fY1 < fY0) std::swap(fY0, fY1);
275 fPad->Range(fX0, fY0, fX1, fY1);
281 //____________________________________________________________________
283 AliFMDDisplay::DistancetoPrimitive(Int_t px, Int_t)
285 // Calculate the distance from point to
286 // something in the canvas.
287 // Depends on the zoom mode.
288 fPad->SetCursor(kCross);
289 Float_t xmin = fPad->GetX1();
290 Float_t xmax = fPad->GetX2();
291 Float_t dx = .02 * (xmax - xmin);
292 Float_t x = fPad->AbsPixeltoX(px);
293 if (x < xmin + dx || x > xmax - dx) return 9999;
294 return (fZoomMode ? 0 : 7);
296 //____________________________________________________________________
298 AliFMDDisplay::Init()
300 // Initialize. GEt transforms and such,
301 // so that we can draw thins properly
302 // Returns true on success
303 if (!AliFMDInput::Init()) return kFALSE;
304 AliFMDGeometry* geom = AliFMDGeometry::Instance();
306 geom->InitTransformations();
307 if (TESTBIT(fTreeMask, kDigits) || TESTBIT(fTreeMask, kRaw))
308 AliFMDParameters::Instance()->Init();
310 fMarkers = new TObjArray;
311 fHits = new TObjArray;
312 fMarkers->SetOwner(kTRUE);
313 fHits->SetOwner(kFALSE);
317 //____________________________________________________________________
319 AliFMDDisplay::MakeAux()
321 // MAke the aux canvas
322 // This is used to display spectra
324 if ((TESTBIT(fTreeMask, kESD) ||
325 TESTBIT(fTreeMask, kDigits) ||
326 TESTBIT(fTreeMask, kRaw))) {
328 fAux = new TCanvas("aux", "Aux");
330 if (TESTBIT(fTreeMask, kESD))
331 fSpec = new TH1D("spec", "Mult spectra", 500, 0, 10);
333 fSpec = new TH1D("spec", "Adc spectra", 1024, -.5, 1023.5);
334 fSpecCut = static_cast<TH1*>(fSpec->Clone("specCut"));
335 fSpec->SetFillColor(2);
336 fSpec->SetFillStyle(3001);
337 fSpecCut->SetFillColor(4);
338 fSpecCut->SetFillStyle(3001);
347 //____________________________________________________________________
349 AliFMDDisplay::DrawAux()
351 // Draw in the Aux the canvas
352 // For example draw the spectra
358 fSpecCut->Draw("same");
364 //____________________________________________________________________
366 AliFMDDisplay::Begin(Int_t event)
368 // Begin of event. Make canvas is not already done
370 // event The event number
372 const char* m[] = { "Continue", "Zoom", "Pick", "Redisplay", 0 };
377 // AliInfo("Clearing canvas");
380 Warning("End", "No geometry manager");
383 AliInfo("Drawing geometry");
385 fGeoManager->GetTopVolume()->Draw();
386 if (fOnlyFMD) ShowOnlyFMD();
387 AliInfo("Adjusting view");
389 if (fPad->GetView()) {
390 fPad->GetView()->SetView(-200, -40, 80, irep);
391 fPad->GetView()->Zoom();
395 return AliFMDInput::Begin(event);
398 //____________________________________________________________________
400 AliFMDDisplay::AtEnd()
402 // Called at of the event.
413 //____________________________________________________________________
415 AliFMDDisplay::Idle()
418 // Sends the ROOT loop into the idle loop,
419 // so that we can go on.
422 gApplication->StartIdleing();
423 gSystem->InnerLoop();
424 gApplication->StopIdleing();
426 AliInfo("After idle loop");
427 if (fMarkers) fMarkers->Delete();
428 if (fHits) fHits->Clear();
429 AliInfo("After clearing caches");
432 //____________________________________________________________________
436 // End of event. Draw everything
439 return AliFMDInput::End();
442 //____________________________________________________________________
444 AliFMDDisplay::LookupColor(Float_t x, Float_t max) const
447 // Get a colour from the current palette depending
448 // on the ratio x/max
449 Int_t idx = Int_t(x / max * gStyle->GetNumberOfColors());
450 return gStyle->GetColorPalette(idx);
453 //____________________________________________________________________
455 AliFMDDisplay::ChangeCut()
457 // Change the cut on the slider.
458 // The factor depends on what is
459 // drawn in the AUX canvas
460 fMultCut = fSlider->GetMinimum() * 10;
461 fPedestalFactor = fSlider->GetMinimum() * 10;
462 AliInfo(Form("Multiplicity cut: %7.5f, Pedestal factor: %7.4f (%6.5f)",
463 fMultCut, fPedestalFactor, fSlider->GetMinimum()));
467 //____________________________________________________________________
469 AliFMDDisplay::Redisplay()
472 // Redraw markers, hits,
474 if (fMarkers) fMarkers->Delete();
475 if (fHits) fHits->Clear();
476 if (fSpec) fSpec->Reset();
477 if (fSpecCut) fSpecCut->Reset();
482 //____________________________________________________________________
484 AliFMDDisplay::AddMarker(UShort_t det, Char_t rng, UShort_t sec, UShort_t str,
485 TObject* o, Float_t s, Float_t max)
487 // Add a marker to the display
493 // o Object to refer to
495 // max Maximum of signal
497 AliFMDGeometry* geom = AliFMDGeometry::Instance();
499 geom->Detector2XYZ(det, rng, sec, str, x, y, z);
501 Float_t zsize = s / max * 10;
502 Float_t r = TMath::Sqrt(x * x + y * y);
503 Float_t theta = TMath::ATan2(r, z);
504 Float_t phi = TMath::ATan2(y, x);
505 Float_t rz = z + (z < 0 ? 1 : -1) * zsize;
506 TMarker3DBox* marker = new TMarker3DBox(x,y,rz,size,size,zsize,theta,phi);
507 if (o) marker->SetRefObject(o);
508 marker->SetLineColor(LookupColor(s, max));
509 fMarkers->Add(marker);
513 //____________________________________________________________________
515 AliFMDDisplay::ProcessHit(AliFMDHit* hit, TParticle* /* p */)
520 if (!hit) { AliError("No hit"); return kFALSE; }
521 // if (!p) { AliError("No track"); return kFALSE; }
523 if (fHits) fHits->Add(hit);
525 Float_t zsize = TMath::Sqrt(hit->Edep() * 20);
526 Float_t z = hit->Z() + (hit->Z() < 0 ? 1 : -1) * zsize;
527 Float_t pt = TMath::Sqrt(hit->Py()*hit->Py()+hit->Px()*hit->Px());
528 Float_t theta = TMath::ATan2(pt, hit->Pz());
529 Float_t phi = TMath::ATan2(hit->Py(), hit->Px());
530 TMarker3DBox* marker = new TMarker3DBox(hit->X(), hit->Y(), z,
531 size, size, zsize, theta, phi);
532 marker->SetLineColor(LookupColor(hit->Edep(), 1));
533 marker->SetRefObject(hit);
534 fMarkers->Add(marker);
538 //____________________________________________________________________
540 AliFMDDisplay::ProcessDigit(AliFMDDigit* digit)
544 // digit Digit information
545 if (!digit) { AliError("No digit"); return kFALSE; }
547 AliFMDParameters* parm = AliFMDParameters::Instance();
548 UShort_t det = digit->Detector();
549 Char_t ring = digit->Ring();
550 UShort_t sec = digit->Sector();
551 UShort_t str = digit->Strip();
552 Double_t ped = parm->GetPedestal(det,ring, sec, str);
553 Double_t pedW = parm->GetPedestalWidth(det,ring, sec, str);
554 Double_t threshold = ped + fPedestalFactor * pedW;
555 Float_t counts = digit->Counts();
556 AliFMDDebug(10, ("FMD%d%c[%2d,%3d] ADC: %d > %d (=%4.2f+%4.2f*%4.2f)",
557 digit->Detector(), digit->Ring(), digit->Sector(),
558 digit->Strip(), Int_t(counts), Int_t(threshold),
559 ped, fPedestalFactor, pedW));
560 if (fSpec) fSpec->Fill(counts);
561 if (counts < threshold) return kTRUE;
562 if (fHits) fHits->Add(digit);
563 if (fSpecCut) fSpecCut->Fill(counts);
565 AddMarker(det, ring, sec, str, digit, counts, 1024);
569 //____________________________________________________________________
571 AliFMDDisplay::ProcessRaw(AliFMDDigit* digit)
575 // digit Digit information
576 return ProcessDigit(digit);
579 //____________________________________________________________________
581 AliFMDDisplay::ProcessRecPoint(AliFMDRecPoint* recpoint)
583 // Process reconstructed point
585 // recpoint Reconstructed multiplicity/energy
586 if (!recpoint) { AliError("No recpoint"); return kFALSE; }
587 if (recpoint->Particles() < fMultCut) return kTRUE;
588 if (fHits) fHits->Add(recpoint);
589 AddMarker(recpoint->Detector(), recpoint->Ring(), recpoint->Sector(),
590 recpoint->Strip(), recpoint, recpoint->Particles(), 20);
594 //____________________________________________________________________
596 AliFMDDisplay::ProcessESD(UShort_t det, Char_t rng, UShort_t sec, UShort_t str,
597 Float_t, Float_t mult)
599 // Process data from ESD
601 // det,rng,sec,str Detector coordinates.
602 // mult Multiplicity.
603 Double_t cmult = mult;
604 if (fSpec) fSpec->Fill(cmult);
605 if (cmult < fMultCut || cmult == AliESDFMD::kInvalidMult) return kTRUE;
606 AddMarker(det,rng,sec,str, 0, cmult, 20);
607 if (fSpecCut) fSpecCut->Fill(cmult);
611 //____________________________________________________________________