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>
41 #include <TSliderBox.h>
44 #include <TVirtualX.h>
45 #include <TVirtualViewer3D.h>
47 // #include <TArrayF.h>
48 // #include <TParticle.h>
50 #include "AliFMDDisplay.h" // ALIFMDDISPLAY_H
51 #include "AliFMDHit.h" // ALIFMDHIT_H
52 #include "AliFMDDigit.h" // ALIFMDDIGIT_H
53 #include "AliFMDRecPoint.h" // ALIFMDRECPOINT_H
54 #include "AliFMDGeometry.h" // ALIFMDGEOMETRY_H
55 #include "AliFMDParameters.h" // ALIFMDPARAMETERS_H
56 #include <AliESDFMD.h> // ALIESDFMD_H
57 // #include <AliLog.h>
58 #include "AliFMDDebug.h" // Better debug macros
60 //____________________________________________________________________
61 ClassImp(AliFMDDisplay)
63 ; // This is here to keep Emacs for indenting the next line
66 //____________________________________________________________________
67 AliFMDDisplay* AliFMDDisplay::fgInstance = 0;
69 //____________________________________________________________________
71 AliFMDDisplay::Instance()
73 // Return static instance
74 // If the instance does not exist
79 //____________________________________________________________________
80 AliFMDDisplay::~AliFMDDisplay()
93 if (fPad) delete fPad;
95 if (fSlider) delete fSlider;
96 if (fCanvas) delete fCanvas;
99 //____________________________________________________________________
100 AliFMDDisplay::AliFMDDisplay(Bool_t onlyFMD, const char* gAliceFile)
101 : AliFMDInput(gAliceFile),
126 // Constructor of an FMD display object.
130 if (fgInstance) delete fgInstance;
134 //____________________________________________________________________
136 AliFMDDisplay::MakeCanvas(const char** which)
140 // which Which button to put up.
141 gStyle->SetPalette(1);
142 // gStyle->SetCanvasPreferGL(kTRUE);
145 fCanvas = new TCanvas("gldisplay", "Display", w, Int_t(w / (1-y1)));
146 fCanvas->SetFillColor(1);
147 fCanvas->ToggleEventStatus();
149 fPad = new TPad("glview", "3DView", 0.0, y1, 1.0, 1.0, 1, 0, 0);
152 const char** p = which;
157 AliInfo(Form("Got %d buttons", n));
163 if (TESTBIT(fTreeMask, kDigits)) {
166 fFactor = new TSlider("pedFactor", "Pedestal Factor", xb+.01, 0, 1, yb);
167 fFactor->SetMethod("AliFMDDisplay::Instance()->ChangeFactor()");
168 fFactor->SetRange(3./10, 1);
171 static_cast<TSliderBox*>(fFactor->GetListOfPrimitives()->
172 FindObject("TSliderBox"));
174 sbox->SetToolTipText("Adjust the noise suppression factor by moving "
178 if (TESTBIT(fTreeMask, kHits) ||
179 TESTBIT(fTreeMask, kESD) ||
180 TESTBIT(fTreeMask, kDigits) ||
181 TESTBIT(fTreeMask, kRaw)) {
183 fSlider = new TSlider("genCut", "Multiplicity cut", 0, 0, xb, yb);
184 fSlider->SetMethod("AliFMDDisplay::Instance()->ChangeCut()");
185 fSlider->SetRange(0,1);
188 static_cast<TSliderBox*>(fSlider->GetListOfPrimitives()->
189 FindObject("TSliderBox"));
191 sbox->SetToolTipText("Adjust lower and upper limit on data signal");
197 while ((m = *(p++))) {
199 AliInfo(Form("Adding button %s", m));
200 TButton* b = new TButton(m, Form("AliFMDDisplay::Instance()->%s()", m),
201 x0, yb, TMath::Min(x0 + dx,.999F), y1);
209 //____________________________________________________________________
211 AliFMDDisplay::ShowOnlyFMD()
216 if (!fGeoManager) return;
217 static bool once = false;
220 AliInfo("Will only show the FMD");
221 TGeoVolume* top = gGeoManager->GetTopVolume();
222 top->InvisibleAll(kTRUE);
223 TGeoIterator next(top);
226 Bool_t hasFMD1 = kFALSE;
227 Bool_t hasFMD2 = kFALSE;
228 Bool_t hasFMD3 = kFALSE;
229 AliInfo("Getting material FMD_Si$");
230 TGeoMaterial* si = gGeoManager->GetMaterial("FMD_Si$"); // kRed
231 AliInfo("Getting material FMD_Carbon$");
232 TGeoMaterial* c = gGeoManager->GetMaterial("FMD_Carbon$"); // kGray
233 AliInfo("Getting material FMD_Aluminum$");
234 TGeoMaterial* al = gGeoManager->GetMaterial("FMD_Aluminum$");// kGray-2
235 AliInfo("Getting material FMD_Copper$");
236 TGeoMaterial* cu = gGeoManager->GetMaterial("FMD_Copper$"); // kGreen-2
237 AliInfo("Getting material FMD_PCB$");
238 TGeoMaterial* pcb = gGeoManager->GetMaterial("FMD_PCB$"); // kGreen+2
239 AliInfo("Getting material FMD_PCB$");
240 TGeoMaterial* chip = gGeoManager->GetMaterial("FMD_Si Chip$");// kGreen+2
242 while ((node = static_cast<TGeoNode*>(next()))) {
243 const char* name = node->GetName();
245 if (!(v = node->GetVolume())) continue;
247 if (name[0] == 'F') {
248 TGeoMaterial* m = (v->IsAssembly() ? 0 : v->GetMaterial());
250 if (m == si) col = kRed;
251 else if (m == c) col = kGray;
252 else if (m == al) col = kYellow+4;
253 else if (m == cu) col = kRed+6;
254 else if (m == pcb) col = kGreen+2;
255 else if (m == chip) col = kGreen+4;
257 v->SetLineColor(col);
258 v->SetFillColor(col);
260 if (name[2] == 'M' && (name[3] == 'T' || name[3] == 'B')) {
261 // Virtual Master half-ring volume - top-level
262 Int_t det = node->GetNumber();
264 case 1: hasFMD1 = true; break;
265 case 2: hasFMD2 = true; break;
266 case 3: hasFMD3 = true; break;
271 else if (name[3] == 'V' && (name[2] == 'T' || name[2] == 'B'))
272 toshow.Add(v); // Virtual Half-ring, bare detectors
273 else if (name[3] == 'H' && (name[2] == 'F' || name[2] == 'B'))
274 toshow.Add(v); // Virtual Hybrid container
275 else if (name[2] == 'S' && name[3] == 'U')
276 toshow.Add(v); // Virtual support structre
277 // else if (name[3] == 'H' && (name[2] == 'F' || name[2] == 'B'))
278 // toshow.Add(v); // Virtual Hybrid container
280 v->SetVisibility(kFALSE);
281 v->SetVisDaughters(kFALSE);
282 v->InvisibleAll(kTRUE);
285 while ((v = static_cast<TGeoVolume*>(i()))) {
286 if (!v->IsAssembly())
287 v->SetVisibility(kTRUE);
288 v->InvisibleAll(kFALSE);
289 v->SetVisDaughters(kTRUE);
295 //____________________________________________________________________
297 AliFMDDisplay::ExecuteEvent(Int_t event, Int_t px, Int_t py)
299 // Execute an event on canvas
301 // event What happened
302 // px, py Pixel coordinates
303 if (px == 0 && py == 0) return;
304 if (!fZoomMode && fPad->GetView()) {
305 fPad->GetView()->ExecuteRotateView(event, px, py);
308 fPad->SetCursor(kCross);
311 fPad->TAttLine::Modify();
312 fX0 = fPad->AbsPixeltoX(px);
313 fY0 = fPad->AbsPixeltoY(py);
314 fXPixel = fOldXPixel = px;
315 fYPixel = fOldYPixel = py;
320 gVirtualX->DrawBox(fXPixel, fYPixel, fOldXPixel, fOldYPixel,
325 gVirtualX->DrawBox(fXPixel, fYPixel, fOldXPixel, fOldYPixel,
329 fPad->GetCanvas()->FeedbackMode(kFALSE);
330 if (px == fXPixel || py == fYPixel) return;
331 fX1 = fPad->AbsPixeltoX(px);
332 fY1 = fPad->AbsPixeltoY(py);
333 if (fX1 < fX0) std::swap(fX0, fX1);
334 if (fY1 < fY0) std::swap(fY0, fY1);
335 fPad->Range(fX0, fY0, fX1, fY1);
341 //____________________________________________________________________
343 AliFMDDisplay::DistancetoPrimitive(Int_t px, Int_t)
345 // Calculate the distance from point to
346 // something in the canvas.
347 // Depends on the zoom mode.
348 fPad->SetCursor(kCross);
349 Float_t xmin = fPad->GetX1();
350 Float_t xmax = fPad->GetX2();
351 Float_t dx = .02 * (xmax - xmin);
352 Float_t x = fPad->AbsPixeltoX(px);
353 if (x < xmin + dx || x > xmax - dx) return 9999;
354 return (fZoomMode ? 0 : 7);
356 //____________________________________________________________________
358 AliFMDDisplay::Init()
360 // Initialize. GEt transforms and such,
361 // so that we can draw thins properly
362 // Returns true on success
363 if (!AliFMDInput::Init()) return kFALSE;
364 AliFMDGeometry* geom = AliFMDGeometry::Instance();
366 geom->InitTransformations();
367 if (TESTBIT(fTreeMask, kDigits) || TESTBIT(fTreeMask, kRaw))
368 AliFMDParameters::Instance()->Init();
370 fMarkers = new TObjArray;
371 fHits = new TObjArray;
372 fMarkers->SetOwner(kTRUE);
373 fHits->SetOwner(kFALSE);
377 //____________________________________________________________________
379 AliFMDDisplay::MakeAux()
381 // MAke the aux canvas
382 // This is used to display spectra
384 if ((TESTBIT(fTreeMask, kESD) ||
385 TESTBIT(fTreeMask, kDigits) ||
386 TESTBIT(fTreeMask, kRaw))) {
388 fAux = new TCanvas("aux", "Aux");
390 if (TESTBIT(fTreeMask, kESD))
391 fSpec = new TH1D("spec", "Mult spectra", 500, 0, 10);
393 fSpec = new TH1D("spec", "Adc spectra", 1024, -.5, 1023.5);
394 fSpecCut = static_cast<TH1*>(fSpec->Clone("specCut"));
395 fSpec->SetFillColor(2);
396 fSpec->SetFillStyle(3001);
397 fSpecCut->SetFillColor(4);
398 fSpecCut->SetFillStyle(3001);
407 //____________________________________________________________________
409 AliFMDDisplay::DrawAux()
411 // Draw in the Aux the canvas
412 // For example draw the spectra
418 fSpecCut->Draw("same");
424 //____________________________________________________________________
426 AliFMDDisplay::Begin(Int_t event)
428 // Begin of event. Make canvas is not already done
430 // event The event number
432 const char* m[] = { "Continue",
444 // AliInfo("Clearing canvas");
447 Warning("End", "No geometry manager");
450 AliInfo("Drawing geometry");
452 fGeoManager->GetTopVolume()->Draw();
453 if (fOnlyFMD) ShowOnlyFMD();
454 AliInfo("Adjusting view");
456 if (fPad->GetView()) {
457 fPad->GetView()->SetView(-200, -40, 80, irep);
458 fPad->GetView()->Zoom();
462 return AliFMDInput::Begin(event);
465 //____________________________________________________________________
467 AliFMDDisplay::AtEnd()
469 // Called at of the event.
480 //____________________________________________________________________
482 AliFMDDisplay::Idle()
485 // Sends the ROOT loop into the idle loop,
486 // so that we can go on.
489 gApplication->StartIdleing();
490 gSystem->InnerLoop();
491 gApplication->StopIdleing();
493 AliInfo("After idle loop");
494 if (fMarkers) fMarkers->Delete();
495 if (fHits) fHits->Clear();
496 AliInfo("After clearing caches");
499 //____________________________________________________________________
503 // End of event. Draw everything
506 if (fReturn) return kFALSE;
507 return AliFMDInput::End();
510 //____________________________________________________________________
512 AliFMDDisplay::LookupColor(Float_t x, Float_t min, Float_t max) const
515 // Get a colour from the current palette depending
516 // on the ratio x/max
517 Float_t range = (max-min);
518 Float_t l = fSlider->GetMinimum();
519 Float_t h = fSlider->GetMaximum();
520 if (l == h) { l = 0; h = 1; }
521 Float_t cmin = range * l;
522 Float_t cmax = range * h;
523 Float_t crange = (cmax-cmin);
524 Int_t idx = Int_t((x-cmin) / crange * gStyle->GetNumberOfColors());
525 return gStyle->GetColorPalette(idx);
528 //____________________________________________________________________
530 AliFMDDisplay::ChangeCut()
532 // Change the cut on the slider.
533 // The factor depends on what is
534 // drawn in the AUX canvas
535 AliInfo(Form("Range is now %3.1f - %3.1f", fSlider->GetMinimum(),
536 fSlider->GetMaximum()));
539 //____________________________________________________________________
541 AliFMDDisplay::ChangeFactor()
543 // Change the cut on the slider.
544 // The factor depends on what is
545 // drawn in the AUX canvas
546 AliInfo(Form("Noise factor is now %4.1f, pedestal factor %3.1f",
547 fFactor->GetMinimum()*10,fFactor->GetMaximum()));
551 //____________________________________________________________________
553 AliFMDDisplay::Redisplay()
556 // Redraw markers, hits,
558 if (fMarkers) fMarkers->Delete();
559 if (fHits) fHits->Clear();
560 if (fSpec) fSpec->Reset();
561 if (fSpecCut) fSpecCut->Reset();
565 //____________________________________________________________________
567 AliFMDDisplay::Break()
570 // Redraw markers, hits,
572 if (fMarkers) fMarkers->Delete();
573 if (fHits) fHits->Clear();
574 if (fSpec) fSpec->Reset();
575 if (fSpecCut) fSpecCut->Reset();
579 //____________________________________________________________________
581 AliFMDDisplay::Render()
584 TVirtualViewer3D* viewer = fPad->GetViewer3D("ogl");
588 //____________________________________________________________________
590 AliFMDDisplay::AddMarker(Float_t x, Float_t y, Float_t z,
591 TObject* o, Float_t s, Float_t min, Float_t max)
593 // Add a marker to the display
599 // o Object to refer to
601 // max Maximum of signal
604 Float_t zsize = (s - min) / (max-min) * 10;
605 Float_t r = TMath::Sqrt(x * x + y * y);
606 Float_t theta = TMath::ATan2(r, z);
607 Float_t phi = TMath::ATan2(y, x);
608 Float_t rz = z + (z < 0 ? 1 : -1) * zsize;
609 TMarker3DBox* marker = new TMarker3DBox(x,y,rz,size,size,zsize,theta,phi);
610 if (o) marker->SetRefObject(o);
611 marker->SetLineColor(LookupColor(s, min, max));
612 fMarkers->Add(marker);
614 //____________________________________________________________________
616 AliFMDDisplay::AddMarker(UShort_t det, Char_t rng, UShort_t sec, UShort_t str,
617 TObject* o, Float_t s, Float_t min, Float_t max)
619 // Add a marker to the display
625 // o Object to refer to
627 // max Maximum of signal
629 AliFMDGeometry* geom = AliFMDGeometry::Instance();
631 geom->Detector2XYZ(det, rng, sec, str, x, y, z);
632 AddMarker(x,y,z,o,s,min,max);
635 //____________________________________________________________________
637 AliFMDDisplay::InsideCut(Float_t val, const Float_t& min,
638 const Float_t& max) const
640 Float_t r = max - min;
641 Float_t l = fSlider->GetMinimum();
642 Float_t h = fSlider->GetMaximum();
643 if (l == h) { l = 0; h = 1; }
644 if (val < r * l + min || val > r * h + min) return kFALSE;
649 //____________________________________________________________________
651 AliFMDDisplay::ProcessHit(AliFMDHit* hit, TParticle* /* p */)
657 static const Float_t rMin = 0;
658 static const Float_t rMax = .1;
660 if (!hit) { AliError("No hit"); return kFALSE; }
661 // if (!p) { AliError("No track"); return kFALSE; }
663 if (fHits) fHits->Add(hit);
664 Float_t edep = hit->Edep();
666 if (!InsideCut(edep, rMin, rMax)) return kTRUE;
668 AddMarker(hit->X(), hit->Y(), hit->Z(), hit, edep, rMin, rMax);
672 //____________________________________________________________________
674 AliFMDDisplay::ProcessDigit(AliFMDDigit* digit)
678 // digit Digit information
680 static const Float_t rMin = 0;
681 static const Float_t rMax = 1023;
682 if (!digit) { AliError("No digit"); return kFALSE; }
684 AliFMDParameters* parm = AliFMDParameters::Instance();
685 UShort_t det = digit->Detector();
686 Char_t ring = digit->Ring();
687 UShort_t sec = digit->Sector();
688 UShort_t str = digit->Strip();
689 Double_t ped = parm->GetPedestal(det,ring, sec, str);
690 Double_t pedW = parm->GetPedestalWidth(det,ring, sec, str);
691 Double_t threshold = (ped * fFactor->GetMaximum()
692 + pedW * fFactor->GetMinimum());
693 Float_t counts = digit->Counts();
695 if (fHits) fHits->Add(digit);
696 if (fSpec) fSpec->Fill(counts);
697 if (!InsideCut(counts-threshold, rMin, rMax)) return kTRUE;
698 if (fSpecCut) fSpecCut->Fill(counts);
701 AddMarker(det, ring, sec, str, digit, counts, rMin, rMax);
705 //____________________________________________________________________
707 AliFMDDisplay::ProcessRaw(AliFMDDigit* digit)
711 // digit Digit information
712 return ProcessDigit(digit);
715 //____________________________________________________________________
717 AliFMDDisplay::ProcessRecPoint(AliFMDRecPoint* recpoint)
719 // Process reconstructed point
721 // recpoint Reconstructed multiplicity/energy
722 static const Float_t rMin = 0;
723 static const Float_t rMax = 20;
725 if (!recpoint) { AliError("No recpoint"); return kFALSE; }
727 if (!InsideCut(recpoint->Particles(), rMin, rMax)) return kTRUE;
729 if (fHits) fHits->Add(recpoint);
730 AddMarker(recpoint->Detector(), recpoint->Ring(), recpoint->Sector(),
731 recpoint->Strip(), recpoint, recpoint->Particles(), rMin, rMax);
735 //____________________________________________________________________
737 AliFMDDisplay::ProcessESD(UShort_t det, Char_t rng, UShort_t sec, UShort_t str,
738 Float_t, Float_t mult)
740 // Process data from ESD
742 // det,rng,sec,str Detector coordinates.
743 // mult Multiplicity.
744 static const Float_t rMin = 0;
745 static const Float_t rMax = 20;
747 Double_t cmult = mult;
748 if (fSpec) fSpec->Fill(cmult);
749 if (!InsideCut(cmult, rMin, rMax) || cmult == AliESDFMD::kInvalidMult)
752 AddMarker(det,rng,sec,str, 0, cmult, rMin, rMax);
754 if (fSpecCut) fSpecCut->Fill(cmult);
759 //____________________________________________________________________