]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
From Christian Holm Christensen.
authormtadel <mtadel@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 26 May 2008 14:11:11 +0000 (14:11 +0000)
committermtadel <mtadel@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 26 May 2008 14:11:11 +0000 (14:11 +0000)
Attached is the code for the FMD event display in EVE.  The class
AliEveFMDLoader (in AliEveFMDLoader.h and AliEveFMDLoader.cxx) is a
singleton object that implements display of simulated hits, digits from
simulation, digits from raw data, and ESD data for the FMD.  The active
sensor areas are drawn using TEveGeoShape, and hits are drawn using
TEveBoxSet. The height and colour of the boxes depend on the current
palette range and the signal size of the appropriate kind.  The data is
structured according to the FMD hierarchy:

        FMD1 -+- FMD1i -+- FMD1i[ 0- 1] -+- FMD1i[0]
                        |                \- FMD1i[1]
                        +- FMD1i[ 2- 3] -+- FMD1i[2]
                        ...
                        +- FMD1i[18-19] -+- FMD1i[18]
                                         \- FMD1i[19]
        FMD2 -+- FMD2i -+- ...
              ...
              \- FMD2o -+- ...
        FMD3 -+- FMD3i -+- ...
              ...
              \- FMD3o -+- ...

The four attached scripts fmd_hits2.C, fmd_digits.C, fmd_raw.C, and
fmd_esd.C uses the AliEveFMDLoader instance to load and display
simulated hits, simulated digits, raw data, and ESD for the FMD.  The
script fmd_hits2.C could take the place of fmd_hits.C in
EVE/alice-macros.

Finally, the script display.C is my attempt at making some more
user-friendly navigation panels using ROOT's lightweight TControlBar
objects.

EVE/EveDet/AliEveFMDLoader.cxx [new file with mode: 0644]
EVE/EveDet/AliEveFMDLoader.h [new file with mode: 0644]
EVE/EveDet/LinkDef.h
EVE/alice-macros/fmd_digits.C [new file with mode: 0644]
EVE/alice-macros/fmd_esd.C [new file with mode: 0644]
EVE/alice-macros/fmd_hits2.C [new file with mode: 0644]
EVE/alice-macros/fmd_raw.C [new file with mode: 0644]
EVE/macros/display.C [new file with mode: 0644]

diff --git a/EVE/EveDet/AliEveFMDLoader.cxx b/EVE/EveDet/AliEveFMDLoader.cxx
new file mode 100644 (file)
index 0000000..6c98a3c
--- /dev/null
@@ -0,0 +1,646 @@
+/**************************************************************************
+ * Copyright(c) 2008, Christian Holm Christensen                          *
+ *                                                                        *
+ * Author: Christian Holm Christensen.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation for any purposes is hereby granted without fee,          * 
+ * provided that the above copyright notice appears in all copies and     *
+ * that both the copyright notice and this permission notice remains      *
+ * intact.  The authors make no claims about the suitability of this      * 
+ * software for any purpose. It is provided "as is" without express or    *
+ * implied warranty.                                                     * 
+ **************************************************************************/
+/* $Id$ */
+/** @file    AliEveFMDLoader.cxx
+    @author  Christian Holm Christensen <cholm@nbi.dk>
+    @date    Sun Mar 26 17:59:18 2006
+    @brief   Implementation of AliEveFMDLoader singleton class 
+*/
+//____________________________________________________________________
+//                                                                          
+// Forward Multiplicity Detector based on Silicon wafers. This class
+// is the loader for the event display. 
+//
+// This class is a singleton, meaning that there's only one instance
+// of this.  This is done to speed up the processing by putting all
+// things that are needed every time into the constructor. 
+//
+#include "AliRunLoader.h"
+#include "EveBase/AliEveEventManager.h"
+#include "AliEveFMDLoader.h"
+#include "../FMD/AliFMDUShortMap.h"
+#include "../FMD/AliFMDBoolMap.h"
+#include "../FMD/AliFMDGeometry.h"
+#include "../FMD/AliFMDParameters.h"
+#include "../FMD/AliFMDDetector.h"
+#include "../FMD/AliFMDRing.h"
+#include "../FMD/AliFMDBaseDigit.h"
+#include "../FMD/AliFMDDigit.h"
+#include "../FMD/AliFMDRawReader.h"
+#include "../FMD/AliFMDHit.h"
+#include "AliESDEvent.h"
+#include "AliESDFMD.h"
+#include "AliLog.h"
+#include "AliRawReader.h"
+#include <TClonesArray.h>
+#include <TTree.h>
+#include <TGeoShape.h>
+#include <TGeoManager.h>
+#include <TEveGeoNode.h>
+#include <TEveBoxSet.h>
+#include <TEveQuadSet.h>
+#include <TEveManager.h>
+#include <TEveUtil.h>
+#include <TStyle.h>
+#include <TMath.h>
+#include <iostream>
+
+// Some very private variables. 
+namespace 
+{
+  const Char_t* kDetector = "FMD%d";
+  const Char_t* kRing     = "FMD%d%c";
+  const Char_t* kModule   = "FMD%d%c[%02d-%02d]";
+  const Char_t* kSector   = "FMD%d%c[%02d] %s";
+
+  const Char_t* kHits     = "Hits";
+  const Char_t* kDigits   = "Digits";
+  const Char_t* kRaw      = "Raw";
+  const Char_t* kESD      = "ESD";
+  
+}
+
+//____________________________________________________________________
+AliEveFMDLoader* AliEveFMDLoader::fgInstance = 0;
+
+//____________________________________________________________________
+AliEveFMDLoader* AliEveFMDLoader::Instance()
+{
+  // Get the singleton instance.  If the instance has not been
+  // instantised yet, it will be after this call.
+  if (!fgInstance) 
+    fgInstance = new AliEveFMDLoader();
+  return fgInstance;
+}
+
+//____________________________________________________________________
+AliEveFMDLoader::AliEveFMDLoader(const char* name, Bool_t useBoxes, 
+                                Bool_t old)
+  : TEveElementList(name, 0), 
+    fHitPalette(0, 1000),
+    fDigitPalette(0, 1023), 
+    fMultPalette(0, 20),
+    fUseBoxDigits(useBoxes), 
+    fHitCache("AliFMDHit",0),
+    fDigitCache("AliFMDDigit", 0),
+    fRawCache("AliFMDDigit", 0)
+{
+  // Constructor 
+  // Parameters:
+  // @param name     Name of the folder. 
+  // @param useBoxes Whether to use boxes or Quads for the signals 
+  // @param old      Whether to enable reading old RCU data format
+
+  // increase reference count 
+  IncDenyDestroy();
+  
+  // Increase reference counts on palettes 
+  fHitPalette.IncRefCount();
+  fDigitPalette.IncRefCount();
+  fMultPalette.IncRefCount();
+  
+  // Initialize the FMD geometry manager 
+  AliFMDGeometry* geom = AliFMDGeometry::Instance();
+  geom->Init();
+  geom->InitTransformations();
+
+  AliFMDParameters* pars = AliFMDParameters::Instance();
+  // pars->UseRcuTrailer(!old);
+  pars->UseCompleteHeader(old);
+  pars->SetSampleRate(4);
+  pars->Init(kFALSE, 0);
+
+  // Get shapes
+  TGeoShape* inner = static_cast<TGeoShape*>(gGeoManager->GetListOfShapes()
+                                            ->FindObject("FISE"));
+  if (!inner) throw TEveException("Shape of inner type sensors not found");
+  TGeoShape* outer = static_cast<TGeoShape*>(gGeoManager->GetListOfShapes()
+                                            ->FindObject("FOSE"));
+  if (!outer) throw TEveException("Shape of outer type sensors not found");
+
+  // Emulate reference counting 
+  inner->SetUniqueID(1000);
+  outer->SetUniqueID(1000);
+  
+  // Loop over detectors 
+  for (UShort_t d = 1; d <= 3; d++) { 
+    AliFMDDetector*  detector = geom->GetDetector(d);
+    if (!detector) continue;
+    TEveElementList* ed       = new TEveElementList(Form(kDetector, 
+                                                        detector->GetId()));
+    AddElement(ed);
+    ed->IncDenyDestroy();
+    ed->SetUserData(detector);
+
+    // Loop over rings 
+    Char_t           rings[]  = { 'I', 'O', 0 };
+    Char_t*          pr       = &(rings[0]);
+    while (*pr) { 
+      AliFMDRing* ring = detector->GetRing(*pr);
+      pr++;
+      if (!ring) continue;
+      TEveElementList* er      = new TEveElementList(Form(kRing, 
+                                                         detector->GetId(),
+                                                         ring->GetId()));
+      ed->AddElement(er);
+      er->IncDenyDestroy();
+      er->SetUserData(ring);
+      
+      // UShort_t      nsec    = ring->GetNSectors();
+      // UShort_t      nstr    = ring->GetNStrips();
+      UShort_t         nmod    = ring->GetNModules();
+      // Loop over modules 
+      for (UShort_t m = 0; m < nmod; m++) { 
+       TEveGeoShape* em = new TEveGeoShape(Form(kModule, 
+                                                detector->GetId(),
+                                                ring->GetId(), 
+                                                2*m, 2*m+1));
+       er->AddElement(em);
+       em->SetTransMatrix(*(detector->FindTransform(ring->GetId(), 2*m)));
+       em->SetShape(ring->GetId() == 'I' ? inner : outer);
+       em->SetMainColor(Color_t(kRed));
+       em->SetMainTransparency(32);
+       em->IncDenyDestroy();
+
+#if 0
+       for (UShort_t s = 2*m; s < 2*m+2 && s < nsec; s++) { 
+         TEveDigitSet* eb = MakeDigitSet(Form(kSector,
+                                              detector->GetId(), 
+                                              ring->GetId(), s), nstr);
+         em->AddElement(eb);
+         eb->SetEmitSignals(kFALSE);
+         eb->SetPickable(kTRUE);
+         // eb->SetOwnIds(kTRUE);
+       } // for (UShort_t s ...)
+#endif
+      }  // for (UShort_t m ...)
+    }  // while (pr)
+  }  // for (UShort_t d ...)
+}
+
+//____________________________________________________________________
+AliEveFMDLoader::~AliEveFMDLoader()
+{
+  // Destructor
+  AliWarning("AliEveFMDLoader being destroyed!");
+}
+
+//____________________________________________________________________
+Int_t
+AliEveFMDLoader::RemoveFromListTrees(TEveElement* el)
+{
+  // Called when the element should be removed from the list. We
+  // overload this to allow clearing of signals.
+  // Parameters:
+  // @param el Tree to remove from.
+
+  // Since we're most likely setting up for a new event, we clear all
+  // signals here - a little tricky, but it works(tm). 
+  ClearDigitSets("All");
+  
+  // Do normal TEveElement::RemoveElement
+  return TEveElementList::RemoveFromListTrees(el);
+}
+//____________________________________________________________________
+void
+AliEveFMDLoader::RemoveParent(TEveElement* el)
+{
+  // Called when the element should be removed from the list. We
+  // overload this to allow clearing of signals.
+  // Parameters:
+  // @param el Parent to remove from.
+  TEveElementList::RemoveParent(el);
+}
+
+//____________________________________________________________________
+TEveDigitSet* 
+AliEveFMDLoader::MakeDigitSet(const char* name, UShort_t nstr)
+{
+  // Make a digit set.  The type of digit set depends on the setting
+  // of fUseBoxDigits.  If this is true, we return a TEveBoxSet,
+  // otherwise a TEveQuadSet   
+  // Parameters: 
+  //    name   The name 
+  //   nstr    The number of strips 
+  // Return 
+  //    newly allocated digit set
+  TEveDigitSet* ret = 0;
+  if (fUseBoxDigits) { 
+    TEveBoxSet* boxes = new TEveBoxSet(name);
+    // boxes->Reset(TEveBoxSet::kBT_AABox, kFALSE, nstr);
+    boxes->Reset(TEveBoxSet::kBT_FreeBox, kFALSE, nstr);
+    ret = boxes;
+  }
+  else { 
+    TEveQuadSet* quads = new TEveQuadSet(name);
+    quads->Reset(TEveQuadSet::kQT_RectangleXY, kFALSE, nstr);
+    ret = quads;
+  }
+  return ret;
+}
+
+//____________________________________________________________________
+void
+AliEveFMDLoader::ClearDigitSets(const char* type)
+{
+  // Clear signals of some type.   
+  // Parameters:
+  // @param type Type of signals to clear 
+  //     Type can be one of 
+  //     - All    All signals 
+  //     - Hits   Hits 
+  //     - Digits Digits 
+  //     - Raw    Raw 
+  //     - ESD    ESD 
+  TString stype(type);
+
+  for (TEveElement::List_i di = BeginChildren(); 
+       di != EndChildren(); ++di) { 
+    for (TEveElement::List_i ri = (*di)->BeginChildren(); 
+        ri != (*di)->EndChildren(); ++ri) { 
+      for (TEveElement::List_i mi = (*ri)->BeginChildren();
+          mi != (*ri)->EndChildren(); ++mi) { 
+       if (stype == "All") {
+         (*mi)->RemoveElements();
+         continue;
+       }
+       for (TEveElement::List_i si = (*mi)->BeginChildren(); 
+            si != (*mi)->EndChildren(); ++si) { 
+         TEveDigitSet* signals = static_cast<TEveDigitSet*>((*si));
+         if (!signals) continue;
+         TString s(signals->GetName());
+         if (!s.Contains(type)) continue;
+         (*mi)->RemoveElement(signals);
+       }
+      }
+    }
+  }
+}
+
+//____________________________________________________________________
+TEveDigitSet*
+AliEveFMDLoader::FindDigitSet(const char* t, UShort_t d, Char_t r, UShort_t s)
+{
+  // Find a digit set corresponding to the passed parameters.  If it
+  // is not found, one is created
+  // Parameters:
+  // @param type   Type of data 
+  // @param d      Detector 
+  // @param r      Ring 
+  // @param s      Sector 
+  // @return a digit set
+  TEveElement* detector = FindChild(Form(kDetector, d));
+  if (!detector) { 
+    AliError(Form("Detector %s not found", Form(kDetector, d)));
+    return 0;
+  }
+  
+  TEveElement* ring = detector->FindChild(Form(kRing, d, r));
+  if (!ring) { 
+    AliError(Form("Ring %s not found", Form(kRing, d, r)));
+    return 0;
+  }
+  
+  Int_t mod = 2*(s/2);
+  TEveElement* module = ring->FindChild(Form(kModule, d, r, mod, mod+1));
+  if (!module) { 
+    AliError(Form("Module %s not found", Form(kModule, d, r, s, s+1)));
+    return 0;
+  }
+  
+  TEveElement*  sector = module->FindChild(Form(kSector, d, r, s, t));
+  TEveDigitSet* signal = static_cast<TEveDigitSet*>(sector);
+  if (!sector) { 
+    AliFMDRing* rng = AliFMDGeometry::Instance()->GetRing(r);
+    signal = MakeDigitSet(Form(kSector, d, r, s, t), rng->GetNStrips());
+    module->AddElement(signal);
+    signal->SetEmitSignals(kFALSE);
+    signal->SetPickable(kTRUE);
+    TString st(t);
+    if      (t == kHits)   signal->SetPalette(&fHitPalette);
+    else if (t == kDigits) signal->SetPalette(&fDigitPalette);
+    else if (t == kRaw)    signal->SetPalette(&fDigitPalette);
+    else if (t == kESD) {
+      signal->SetPalette(&fMultPalette);
+      signal->SetOwnIds(kTRUE);
+    }
+  }
+  return signal;
+}
+
+//____________________________________________________________________
+void
+AliEveFMDLoader::AddSignal(const char* t, 
+                          UShort_t det, Char_t rng, UShort_t sec, 
+                          UShort_t str, Float_t signal, Float_t min, 
+                          Float_t  max, TObject* ref)
+{
+  // Add a signal to a digit set
+  // Parameters:
+  // @param type   Type of data 
+  // @param det    Detector 
+  // @param rng    Ring 
+  // @param sec    Sector 
+  // @param str    Strip
+  // @param signal Signal value 
+  // @param min    Minimum of this kind of signal 
+  // @param max    Maximum of this kind of signal 
+  // @param ref    Reference object 
+  AliFMDGeometry* geom = AliFMDGeometry::Instance();
+  Double_t x, y, z;
+  geom->Detector2XYZ(det, rng, sec, str, x, y, z);
+  AddSignal(t, det, rng, sec, str, x, y, z, signal, min, max, ref);
+}
+
+//____________________________________________________________________
+void
+AliEveFMDLoader::AddSignal(const char* t, 
+                          UShort_t det, Char_t rng, UShort_t sec, 
+                          UShort_t str, Double_t x, Double_t y, Double_t z, 
+                          Float_t signal, Float_t min, Float_t  max, 
+                          TObject* ref)
+{
+  // Add a signal to a digit set, with known (x,y,z) coordinates
+  // (this is for hits)
+  // Parameters:
+  // @param type   Type of data 
+  // @param det    Detector 
+  // @param rng    Ring 
+  // @param sec    Sector 
+  // @param str    Strip
+  // @param x      X coordinate  
+  // @param y      Y coordinate  
+  // @param z      Z coordinate  
+  // @param signal Signal value 
+  // @param min    Minimum of this kind of signal 
+  // @param max    Maximum of this kind of signal 
+  // @param ref    Reference object 
+  AliFMDGeometry* geom = AliFMDGeometry::Instance();
+  AliFMDRing*     ring = geom->GetRing(rng);
+  if (!ring) return;
+
+  TEveDigitSet* signals = FindDigitSet(t, det, rng, sec);
+  if (!signals) { 
+    AliWarning(Form("No signal (%s) found for FMD%d%c[%02d,%03d]", 
+                   t, det, rng, sec, str));
+    return;
+  }
+  
+  Float_t  scaled = TMath::Min((signal - min) / (max - min) * 10., 10.);
+  Double_t w      = 2*ring->GetPitch();
+  Int_t    value  = int(TMath::Nint(signal));
+  AliDebug(1, Form("New signal at FMD%d%c[%02d,%03d]=%f (v=%d, s=%f)", 
+                  det, rng, sec, str, signal, value, scaled));
+  AddDigit(signals, x, y, z, w, scaled, value, ref);
+}
+
+//____________________________________________________________________
+void
+AliEveFMDLoader::AddDigit(TEveDigitSet* signals, 
+                         Double_t x, Double_t y, Double_t z, 
+                         Double_t w, Float_t scaled, Int_t value, 
+                         TObject* ref)
+{
+  // Add a digit to a digit set. 
+  // Parameters:
+  // @param signals Digit set. 
+  // @param x      X coordinate  
+  // @param y      Y coordinate  
+  // @param z      Z coordinate  
+  // @param w      strip pitch 
+  // @param scaled Scaled value 
+  // @param value  Signal value 
+  // @param ref    Reference object
+  if (fUseBoxDigits) { 
+    TEveBoxSet* boxes = static_cast<TEveBoxSet*>(signals);
+    Float_t zc   = (z > 0 ? -1 : 1) * scaled + z;
+    Float_t vs[] = { -w, -5*w, zc-scaled,   // Lower back  left
+                    +w, -5*w, zc-scaled,   // Lower back  right
+                    +w, +5*w, zc-scaled,   // Lower front right
+                    -w, +5*w, zc-scaled,   // Lower front left 
+                    -w, -5*w, zc+scaled,   // Upper back  left
+                    +w, -5*w, zc+scaled,   // Upper back  right
+                    +w, +5*w, zc+scaled,   // Upper front right
+                    -w, +5*w, zc+scaled }; // Upper front left
+    Float_t ang  = TMath::ATan2(y,x);
+    for (size_t i = 0; i < 8; i++) { 
+      Float_t bx = vs[3*i+0];
+      Float_t by = vs[3*i+1];
+      Float_t ca = TMath::Cos(ang);
+      Float_t sa = TMath::Sin(ang);
+      vs[3*i+0]  = bx * ca - by * sa + x;
+      vs[3*i+1]  = bx * sa + by * ca + y;
+    }
+    // boxes->AddBox(x, y, (z > 0 ? -scaled : 0) + z , 5*w, w, scaled);
+    boxes->AddBox(vs);
+    boxes->DigitValue(value);
+    if (ref) boxes->DigitId(ref);
+  }
+  else { 
+    TEveQuadSet* quads = static_cast<TEveQuadSet*>(signals);
+    quads->AddQuad(x,y,z,w,w);
+    quads->QuadValue(value);
+    if (ref) quads->QuadId(ref);
+  }
+}
+
+
+//____________________________________________________________________
+void
+AliEveFMDLoader::CheckAdd()
+{
+  // check if we shoul re-add ourselves to the current event node 
+  TEveElement* event = gEve->GetCurrentEvent();
+  if (event && event->FindChild(GetName())) return;
+  gEve->AddElement(this);
+}
+
+
+//____________________________________________________________________
+void
+AliEveFMDLoader::LoadHits()
+{
+  // Load and display hits
+  ClearDigitSets(kHits);
+
+  AliRunLoader* rl =  AliEveEventManager::AssertRunLoader();
+  if (!rl) { 
+    AliError("No run loader");
+    return;
+  }
+  
+  rl->LoadHits("FMD");
+  TTree* ht = rl->GetTreeH("FMD", false);
+  if (!ht) { 
+    AliError("No FMD tree");
+    return;
+  }
+  
+  TClonesArray* hits = &fHitCache;
+  fHitCache.Clear();
+  ht->SetBranchAddress("FMD", &hits);
+
+  Float_t min = fHitPalette.GetMinVal();
+  Float_t max = fHitPalette.GetMaxVal();
+
+  Int_t nTracks = ht->GetEntriesFast();
+  for (Int_t i = 0; i < nTracks; i++) {
+    Int_t hitRead  = ht->GetEntry(i);
+    if (hitRead <= 0) continue;
+
+    Int_t nHit = hits->GetEntriesFast();
+    if (nHit <= 0) continue;
+  
+    for (Int_t j = 0; j < nHit; j++) {
+      AliFMDHit* hit = static_cast<AliFMDHit*>(hits->At(j));
+      if (!hit) continue;
+  
+      AddSignal(kHits, 
+               hit->Detector(), hit->Ring(), hit->Sector(), hit->Strip(),
+               hit->X(), hit->Y(), hit->Z(), int(hit->Edep()*1000), 
+               min, max, hit);
+    }
+  }
+  CheckAdd();
+}
+
+//____________________________________________________________________
+void
+AliEveFMDLoader::DoLoadDigits(const char* t, TClonesArray* digits)
+{
+  // Do the actual display of digits 
+  // Parameters:
+  // @param type What to show 
+  // @param digits The digits
+  Float_t min = fDigitPalette.GetMinVal();
+  Float_t max = fDigitPalette.GetMaxVal();
+
+  Int_t n = digits->GetEntriesFast();
+  for (Int_t i = 0; i < n; i++) { 
+    AliFMDDigit* digit = static_cast<AliFMDDigit*>(digits->At(i));
+    if (!digit) return;
+    AddSignal(t, digit->Detector(), digit->Ring(), digit->Sector(),
+             digit->Strip(), digit->Counts(), min, max, digit);
+  }
+  CheckAdd();
+}
+
+//____________________________________________________________________
+void
+AliEveFMDLoader::LoadDigits()
+{
+  // Load and display simulated digits 
+  ClearDigitSets(kDigits);
+
+  AliRunLoader* rl =  AliEveEventManager::AssertRunLoader();
+  if (!rl) { 
+    AliError("No run-loader");
+    return;
+  }
+  
+  rl->LoadDigits("FMD");
+  TTree* dt = rl->GetTreeD("FMD", false);
+  if (!dt) { 
+    AliError("No FMD tree");
+    return;
+  }
+  
+  TClonesArray* digits = &fDigitCache;
+  fDigitCache.Clear();
+  dt->SetBranchAddress("FMD", &digits);
+
+  Int_t read = dt->GetEntry(0);
+  if (read <= 0) { 
+    AliWarning("Nothing read");
+    return;
+  }
+  DoLoadDigits(kDigits, digits);
+}
+
+
+//____________________________________________________________________
+void
+AliEveFMDLoader::LoadRaw()
+{
+  // Load and display raw digits 
+  ClearDigitSets(kRaw);
+
+  AliRawReader* rr =  AliEveEventManager::AssertRawReader();
+  if (!rr) { 
+    AliError("No raw-reader");
+    return;
+  }
+  rr->Reset();
+  std::cout<<"Now in event # " << *(rr->GetEventId()) << std::endl;
+  AliFMDRawReader* fr = new AliFMDRawReader(rr, 0);
+  TClonesArray* digits = &fRawCache;
+  fRawCache.Clear();
+  
+  fr->ReadAdcs(digits);
+  
+  DoLoadDigits(kRaw, digits);
+}
+
+//____________________________________________________________________
+void
+AliEveFMDLoader::LoadESD()
+{
+  // Load and display ESD information 
+  ClearDigitSets(kESD);
+
+  AliESDEvent* esd =  AliEveEventManager::AssertESD();
+  if (!esd) { 
+    AliError("No ESD");
+    return;
+  }
+
+  AliESDFMD* fmd = esd->GetFMDData();
+  if (!fmd) { 
+    AliError("No FMD ESD data");
+    return;
+  }
+
+  Float_t min = fMultPalette.GetMinVal();
+  Float_t max = fMultPalette.GetMaxVal();
+  
+  for (UShort_t det = 1; det <= 3; det++) {
+    Char_t rings[] = { 'I', (det == 1 ? '\0' : 'O'), '\0' };
+    for (Char_t* rng = rings; *rng != '\0'; rng++) {
+      UShort_t nsec = (*rng == 'I' ?  20 :  40);
+      UShort_t nstr = (*rng == 'I' ? 512 : 256);
+      for (UShort_t sec = 0; sec < nsec; sec++) {
+       for (UShort_t str = 0; str < nstr; str++) {
+         Float_t mult = fmd->Multiplicity(det,*rng,sec,str);
+         if (mult == AliESDFMD::kInvalidMult) continue;
+         Float_t eta  = fmd->Eta(det,*rng,sec,str);
+         AddSignal(kESD, det, *rng, sec, str, mult, min, max, 
+                   new TNamed(Form("FMD%d%c[%02d,%03d]", det, *rng, sec, str), 
+                              Form("Mch=%f, eta=%f", mult, eta)));
+       }
+      }
+    }
+  }
+  CheckAdd();
+}
+
+
+       
+      
+
+  
+//____________________________________________________________________
+//
+// EOF
+//
diff --git a/EVE/EveDet/AliEveFMDLoader.h b/EVE/EveDet/AliEveFMDLoader.h
new file mode 100644 (file)
index 0000000..2080d03
--- /dev/null
@@ -0,0 +1,205 @@
+// -*- mode: C++ -*- 
+//
+/* Copyright(c) 2008, Christian Holm Christensen
+ *
+ * Latest changes by Christian Holm Christensen <cholm@nbi.dk>
+ *
+ * See cxx source for full Copyright notice                               
+ */
+/** @file    AliEveFMDLoader.h
+    @author  Christian Holm Christensen <cholm@nbi.dk>
+    @date    Sun Mar 26 17:59:37 2006
+    @brief   Declaration of AliEveFMDLoader singleton class 
+*/
+//____________________________________________________________________
+// 
+// Forward Multiplicity Detector based on Silicon wafers. 
+// . 
+// This class is the loader for the event display.
+// 
+#ifndef ALIEVEFMDLOADER_H
+#define ALIEVEFMDLOADER_H
+#include <TEveElement.h>
+#include <TEveRGBAPalette.h>
+#include <TClonesArray.h>
+// Forward declarations
+class TEveDigitSet;
+
+/** @class AliEveFMDLoader 
+    @brief Loader of FMD data for the EVE event display 
+    @ingroup FMD_util
+
+    This class is a singleton, meaning that there's only one instance
+    of this.  This is done to speed up the processing by putting all
+    things that are needed every time into the constructor.
+*/
+class AliEveFMDLoader : public TEveElementList
+{
+public:
+  /** @{ 
+      @name Loading and displaying data */
+  /** Load and display hits */
+  virtual void LoadHits();
+  /** Load and display digits */
+  virtual void LoadDigits();
+  /** Load and display raw data digits */
+  virtual void LoadRaw();
+  /** Load and display ESD */
+  virtual void LoadESD();
+  /** @} */
+
+  /** @{ 
+      @name Hacks to optimise performance */
+  /** Called when the element should be removed from the list. We
+      overload this to allow clearing of signals.
+      @param el Tree to remove from.
+  */
+  virtual Int_t RemoveFromListTrees(TEveElement* el);
+  /** Called when the element should be removed from the list. We
+      overload this to allow clearing of signals.
+      @param el Parent to remove from.
+  */  
+  virtual void RemoveParent(TEveElement* el);
+  /** @} */
+
+  /** @{ 
+      @name Singleton interface */
+  /** Get the singleton instance.  If the instance has not been
+      instantised yet, it will be after this call. */
+  static AliEveFMDLoader* Instance();
+  /** Destructor */
+  virtual ~AliEveFMDLoader();
+  /** @} */
+protected:
+  /** Constructor 
+      @param name     Name of the folder. 
+      @param useBoxes Whether to use boxes or Quads for the signals 
+      @param old      Whether to enable reading old RCU data format */
+  AliEveFMDLoader(const char* name="FMD", Bool_t useBoxes=true, 
+                 Bool_t old=kTRUE);
+
+  /** @{ 
+      @name Service functions for loading data */
+  /** Do the actual display of digits 
+      @param type What to show 
+      @param digits The digits */
+  void          DoLoadDigits(const char* type, TClonesArray* digits);
+  /** @} */
+
+  /** @{ 
+      @name Digit set management */
+  /** Find a digit set corresponding to the passed parameters.  If it
+      is not found, one is created 
+      @param type   Type of data 
+      @param d      Detector 
+      @param r      Ring 
+      @param s      Sector 
+      @return a digit set */
+  TEveDigitSet* FindDigitSet(const char* type,UShort_t d, Char_t r, UShort_t s);
+  /** Make a digit set.  The type of digit set depends on the setting
+      of fUseBoxDigits.  If this is true, we return a TEveBoxSet,
+      otherwise a TEveQuadSet 
+      @param name  Name of set. 
+      @param nstr  Number of strips to make room for. 
+      @return newly allocated digit set */
+  virtual TEveDigitSet* MakeDigitSet(const char* name, UShort_t nstr);
+  /** Clear signals of some type.   
+      @param type Type of signals to clear 
+      Type can be one of 
+      - All    All signals 
+      - Hits   Hits 
+      - Digits Digits 
+      - Raw    Raw 
+      - ESD    ESD */
+  virtual void ClearDigitSets(const char* type);
+  /** @} */
+
+  /** @{ 
+      @name Adding signals to digit sets */
+  /** Add a signal to a digit set
+      @param type   Type of data 
+      @param det    Detector 
+      @param rng    Ring 
+      @param sec    Sector 
+      @param str    Strip
+      @param signal Signal value 
+      @param min    Minimum of this kind of signal 
+      @param max    Maximum of this kind of signal 
+      @param ref    Reference object  */
+  void          AddSignal(const char* type, UShort_t det, Char_t ring, 
+                         UShort_t sec, UShort_t str, 
+                         Float_t signal, Float_t min, Float_t  max, 
+                         TObject* ref=0);
+  /** Add a signal to a digit set, with known (x,y,z) coordinates
+      (this is for hits)
+      @param type   Type of data 
+      @param det    Detector 
+      @param rng    Ring 
+      @param sec    Sector 
+      @param str    Strip
+      @param x      X coordinate  
+      @param y      Y coordinate  
+      @param z      Z coordinate  
+      @param signal Signal value 
+      @param min    Minimum of this kind of signal 
+      @param max    Maximum of this kind of signal 
+      @param ref    Reference object */
+  void          AddSignal(const char* type, UShort_t det, Char_t ring, 
+                         UShort_t sec, UShort_t str, 
+                         Double_t x, Double_t y, Double_t z, 
+                         Float_t signal, Float_t min, Float_t  max, 
+                         TObject* ref=0);
+  /** Add a digit to a digit set. 
+      @param signals Digit set. 
+      @param x      X coordinate  
+      @param y      Y coordinate  
+      @param z      Z coordinate  
+      @param w      strip pitch 
+      @param scaled Scaled value 
+      @param value  Signal value 
+      @param ref    Reference object */
+  virtual void AddDigit(TEveDigitSet* signals, 
+                       Double_t x, Double_t y, Double_t z, 
+                       Double_t w, Float_t scaled, Int_t value, 
+                       TObject* ref);
+  /** @} */
+
+  /** @{
+      @name Various service functions */
+  /** check if we shoul re-add ourselves to the current event node */
+  virtual void CheckAdd();
+  /** @} */
+
+  /** @{ 
+      @name Palettes */
+  TEveRGBAPalette  fHitPalette;    // Palette for hits
+  TEveRGBAPalette  fDigitPalette;  // Palette for ADC values
+  TEveRGBAPalette  fMultPalette;   // Palette for multiplicity values
+  /** @} */
+  
+  /** @{ 
+      @name Settings */
+  Bool_t           fUseBoxDigits;  // Whether to show as boxes or quads
+  /** @} */
+
+  /** @{ 
+      @name Caches */
+  TClonesArray     fHitCache;      // Cache of digits
+  TClonesArray     fDigitCache;    // Cache of digits
+  TClonesArray     fRawCache;      // Cache of raw
+  /** @} */
+
+  /** @{ 
+      @name Singleton interface */
+  static AliEveFMDLoader* fgInstance; // Singleton
+  /** @} */
+
+  ClassDef(AliEveFMDLoader,0)
+};
+
+  
+  
+#endif
+//
+// EOF
+//
index 32b1b57a34d977852b4adb9ae44b2b05e08787c9..1b95fd1b14b3cbc65104bbb556f75e720d32e9c0 100644 (file)
@@ -11,6 +11,9 @@
 #pragma link off all globals;
 #pragma link off all classes;
 
+// FMD
+#pragma link C++ class AliEveFMDLoader+;
+
 // ITS
 #pragma link C++ class AliEveITSModuleSelection+;
 #pragma link C++ class AliEveITSDigitsInfo+;
diff --git a/EVE/alice-macros/fmd_digits.C b/EVE/alice-macros/fmd_digits.C
new file mode 100644 (file)
index 0000000..3886fd1
--- /dev/null
@@ -0,0 +1,7 @@
+void fmd_digits()
+{
+  gStyle->SetPalette(1);
+  AliEveFMDLoader* gFmdLoader = AliEveFMDLoader::Instance();
+  gFmdLoader->LoadDigits();
+  gEve->Redraw3D();
+}
diff --git a/EVE/alice-macros/fmd_esd.C b/EVE/alice-macros/fmd_esd.C
new file mode 100644 (file)
index 0000000..e29be95
--- /dev/null
@@ -0,0 +1,7 @@
+void fmd_esd()
+{
+  gStyle->SetPalette(1);
+  AliEveFMDLoader* gFmdLoader = AliEveFMDLoader::Instance();
+  gFmdLoader->LoadESD();
+  gEve->Redraw3D();
+}
diff --git a/EVE/alice-macros/fmd_hits2.C b/EVE/alice-macros/fmd_hits2.C
new file mode 100644 (file)
index 0000000..60d35a3
--- /dev/null
@@ -0,0 +1,7 @@
+void fmd_hits2()
+{
+  gStyle->SetPalette(1);
+  AliEveFMDLoader* gFmdLoader = AliEveFMDLoader::Instance();
+  gFmdLoader->LoadHits();
+  gEve->Redraw3D();
+}
diff --git a/EVE/alice-macros/fmd_raw.C b/EVE/alice-macros/fmd_raw.C
new file mode 100644 (file)
index 0000000..d3b6639
--- /dev/null
@@ -0,0 +1,7 @@
+void fmd_raw()
+{
+  gStyle->SetPalette(1);
+  AliEveFMDLoader* gFmdLoader = AliEveFMDLoader::Instance();
+  gFmdLoader->LoadRaw();
+  gEve->Redraw3D();
+}
diff --git a/EVE/macros/display.C b/EVE/macros/display.C
new file mode 100644 (file)
index 0000000..c0f66e3
--- /dev/null
@@ -0,0 +1,396 @@
+#ifndef __CINT__
+# include <TGFileDialog.h>
+# include <TGFileBrowser.h>
+# include <TControlBar.h>
+# include <TString.h>
+# include <TSystem.h>
+# include <TROOT.h>
+# include <TEveManager.h>
+# include <TSystemDirectory.h>
+# include <TEveMacro.h>
+# include <TEveBrowser.h>
+# include <TFolder.h>
+# include <TList.h>
+# include <TApplication.h>
+# include "aliroot/EVE/EveBase/AliEveEventManager.h"
+# include <iostream>
+#endif
+
+class Display
+{
+public:
+  //____________________________________________________________________
+  /** Constructor 
+      @param file File or directory to read data from */
+  Display(const char* file="./")
+    : fCb(0), 
+      fEnableHits(kFALSE),
+      fEnableDigits(kFALSE),
+      fEnableRaw(kFALSE),
+      fEnableESD(kFALSE),
+      fHasHits(kFALSE),
+      fHasDigits(kFALSE),
+      fHasRaw(kFALSE),
+      fHasESD(kFALSE)
+  {
+    AliEveEventManager::SetCdbUri("local://$ALICE_ROOT");
+    LoadMacros();
+    Setup(file, false);
+    SetupSelect();
+    SetupControl();
+  }
+  //____________________________________________________________________
+  /** Setup the control bar */
+  void SetupControl()
+  {
+    fCb = new TControlBar("vertical", "EVE Controls");
+    const char* buts[] = { "Load ...", 
+                          "Select ...",
+                          "Next event", 
+                          "Previous event", 
+                          "Hits", 
+                          "Digits", 
+                          "Raw", 
+                          "ESD", 
+                          "Tracks", 
+                          "Quit", 
+                          0 }; 
+    const char* meths[] = { "LoadFile", 
+                           "Select",
+                           "NextEvent", 
+                           "PrevEvent", 
+                           "ToggleHits", 
+                           "ToggleDigits", 
+                           "ToggleRaw", 
+                           "ToggleESD", 
+                           "ToggleTracks", 
+                           "Quit", 
+                           0 };
+    const char* hints[] = { "Specify input" , 
+                           "Select which detectors to show",
+                           "Get next event", 
+                           "Get previous event", 
+                           "Toggle display of hits", 
+                           "Toggle display of simulated digits", 
+                           "Toggle display of raw digits", 
+                           "Toggle display of event summary data", 
+                           "Toggle display of tracks", 
+                           "Quit", 
+                           0 };
+                           
+    char** but  = const_cast<char**>(buts);
+    char** meth = const_cast<char**>(meths);
+    char** hint = const_cast<char**>(hints);
+    while (*but) { 
+      fCb->AddButton(*but, Form("Display::Instance()->%s()", *meth), *hint);
+      but++;
+      meth++;
+      hint++;
+    }
+    fCb->Show();
+  }
+  //____________________________________________________________________
+  /** Setup the selection bar */
+  void SetupSelect()
+  {
+    fSelect = new TControlBar("vertical", "Detector selection");
+    char* dets[] = { "emcal", 
+                    "fmd", 
+                    "its", 
+                    "pmd", 
+                    "t0", 
+                    "tof", 
+                    "tpc", 
+                    "trd", 
+                    "vzero",
+                    "kine", 
+                    "esd",
+                    0 };
+    char** det = dets;
+    while (*det) { 
+      // TString cmd(Form("Display::Instance()->Enable(\"%s\")", *det));
+      // TString help(Form("Enable display of %s data", name.Data()));
+      fSelect->AddButton(*det, 
+                        Form("Display::Instance()->Enable(\"%s\")", *det),
+                        Form("Enable display of %s data", *det));
+      det++;
+    }
+    std::cout << "Adding \"Hide\" to select" << std::endl;
+    fSelect->AddButton("Hide", "Display::Instance()->HideSelect()", 
+                      "Hide the detector selection menu");
+  }
+  //____________________________________________________________________
+  /** Load macros used by EVE */
+  void LoadMacros()
+  {
+    std::cout << "Loading macros ... " << std::flush;
+    TString savdir(gSystem->pwd());
+    TString macdir("$(ALICE_ROOT)/EVE/alice-macros");
+    gSystem->ExpandPathName(macdir);
+  
+    TFolder*          f     = gEve->GetMacroFolder();
+    TSystemDirectory* dir   = new TSystemDirectory(macdir.Data(), 
+                                                  macdir.Data());
+    TList*            files = dir->GetListOfFiles();
+    files->Sort();
+    TIter             next(files);
+    TSystemFile*      file  = 0;
+    while ((file = static_cast<TSystemFile*>(next()))) { 
+      if (file->IsDirectory()) continue;
+      TString name(gSystem->ConcatFileName(macdir.Data(),file->GetName()));
+      if (!name.EndsWith(".C")) continue;
+      f->Add(new TEveMacro(name.Data()));
+    }
+    
+    gROOT->GetListOfBrowsables()->Add(dir);
+  
+    {
+      TEveBrowser*   b  = gEve->GetBrowser();
+      TGFileBrowser* fb = b->GetFileBrowser();
+      fb->GotoDir(macdir);
+      { 
+       b->StartEmbedding(0);
+       fb = b->MakeFileBrowser();
+       fb->BrowseObj(f);
+       fb->Show();
+       b->StopEmbedding(0);
+       b->SetTabTitle("Macros", 0);
+       b->SetTab(0,0);
+      }
+    }
+    gSystem->cd(savdir);
+    std::cout << "done" << std::endl;
+  }
+  //____________________________________________________________________
+  /** Set-up load location, etc. 
+      @param file File or directory to read data from 
+      @param refresh Force a refresh */
+  void Setup(const char* file, bool refresh)
+  {
+    TString fileName(gSystem->BaseName(file));
+    TString dirName(gSystem->DirName(file));
+    
+    if (fileName.Contains("ESD")) { 
+      std::cout << "Adding ESD file " << fileName << std::endl;
+      AliEveEventManager::SetESDFileName(fileName.Data());
+    }
+    else if (fileName.EndsWith(".root") || fileName.EndsWith(".raw")) { 
+      std::cout << "Adding raw file " << fileName << std::endl;
+      AliEveEventManager::SetRawFileName(fileName.Data());
+    }
+    else if (fileName.IsNull()) { 
+      std::cout << "No file given!" << std::endl;
+      // std::cout << "Adding raw directory " << dirName.Data() << std::endl;
+      // AliEveEventManager::SetRawFileName(dirName.Data());
+    }
+    else {
+      std::cerr << "Don't know how to deal with '" << fileName << "'" 
+               << std::endl;
+      return;
+    }
+    std::cout << "Opening " << fileName << " (" << dirName << ")" << std::endl;
+    
+    if (gAliEveEvent) delete gAliEveEvent;
+    gAliEveEvent = new AliEveEventManager(dirName.Data(), 0);
+    gEve->AddEvent(gAliEveEvent);
+    
+    if (refresh) Refresh();
+  }
+  //____________________________________________________________________
+  /** Executed in response to hitting the "Load ..." button. */
+  void 
+  LoadFile()
+  {
+    fCb->SetButtonState("Load ...", 1);
+    TGFileInfo fi;
+    fi.fIniDir = StrDup(gSystem->pwd());
+    new TGFileDialog(gClient->GetRoot(), gClient->GetRoot(), kFDOpen, &fi);
+    Setup(fi.fFilename, true);
+    fCb->SetButtonState("Load ...", 0);
+  }
+  //____________________________________________________________________
+  /** Pop-up or down the selection menu */
+  void 
+  Select()
+  {
+    fSelect->Show();
+    fCb->SetButtonState("Select ...", 1);
+  }
+  //____________________________________________________________________
+  /** Enable a detector or type of display */
+  void 
+  Enable(const char* what)
+  {
+    TObject* o = fEnabled.FindObject(what);
+    //TString n(what);
+    // n.ToUpper();
+    std::cout << "Enable " << what << "?" << std::endl;
+    if (o) { 
+      fEnabled.Remove(o);
+      fSelect->SetButtonState(what, 0);
+      delete o;
+    }
+    else { 
+      fEnabled.Add(new TObjString(what));
+      fSelect->SetButtonState(what, 1);
+    }
+    Refresh();
+  }
+  //____________________________________________________________________
+  /** Pop-down the selection menu */
+  void 
+  HideSelect()
+  {
+    fCb->SetButtonState("Select ...", 0);
+    fSelect->Hide();
+  }
+  //____________________________________________________________________
+  /** Prepare for a new event */
+  void 
+  Prepare()
+  {
+    fHasHits   = kFALSE;
+    fHasDigits = kFALSE;
+    fHasRaw    = kFALSE;
+    fHasESD    = kFALSE;
+    fHasTracks = kFALSE;
+  }
+  //____________________________________________________________________
+  /** Get the next event */
+  void 
+  NextEvent()
+  {
+    Prepare();
+    std::cout << "Getting next event, please wait ... " << std::flush;
+    gROOT->Macro("event_next.C");
+    std::cout << "done" << std::endl;
+    Refresh();
+  }
+  //____________________________________________________________________
+  /** Get the previous event */
+  void 
+  PrevEvent()
+  {
+    Prepare();
+    std::cout << "Getting previous event, please wait ... " << std::flush;
+    gROOT->Macro("event_prev.C"); 
+    std::cout << "done" << std::endl;
+    Refresh();
+  }
+  //____________________________________________________________________
+  /** Reload the current event */
+  void
+  Reload()
+  {
+    Prepare();
+    Int_t event = gAliEveEvent->GetEventId();
+    std::cout << "Getting event " << event 
+             << ", please wait ... " << std::flush;
+    gROOT->Macro(Form("event_goto.C(%d)", event));
+    std::cout << "done" << std::endl;
+    Refresh();
+  }
+  //__________________________________________________________________
+  /** Refresh the display of something
+      @param enabled Whether this something is enabled or not 
+      @param has     Whether we have already shown this data 
+      @param what    What data to show */
+  void 
+  RefreshOne(Bool_t enabled, Bool_t& has, const char* what)
+  {
+    if (!enabled || has) return;
+    std::cout << what << "..." << std::flush;
+    TIter next(&fEnabled);
+    TObject* o = 0;
+    while ((o = next())) { 
+      TMacro* macro = gEve->GetMacro(Form("%s_%s", o->GetName(), what));
+      if (macro) macro->Exec();
+    }
+    has = kTRUE;
+  }
+  
+  //____________________________________________________________________
+  /** Refresh the display of the data */
+  void 
+  Refresh()
+  {
+    std::cout << "Drawing ... " << std::flush;
+    RefreshOne(fEnableTracks, fHasTracks, "tracks");
+    RefreshOne(fEnableHits,   fHasHits,   "hits2");
+    RefreshOne(fEnableDigits, fHasDigits, "digits");
+    RefreshOne(fEnableRaw,    fHasRaw,    "raw");
+    RefreshOne(fEnableESD,    fHasESD,    "esd");
+    std::cout << "done" << std::endl;
+  }
+  //____________________________________________________________________
+  /** Toggle the diplay of some data */
+  void 
+  Toggle(Bool_t& what, const char* name)
+  {
+    what = !what;
+    fCb->SetButtonState(name, what ? 1 : 0);
+    if (!what) Reload();
+    Refresh();
+  }
+  //____________________________________________________________________
+  /** Toggle the diplay the simulated hits */
+  void ToggleHits() { Toggle(fEnableHits, "Hits"); } 
+  //____________________________________________________________________
+  /** Toggle the diplay the simulated digits */
+  void ToggleDigits() { Toggle(fEnableDigits, "Digits"); }
+  //____________________________________________________________________
+  /** Toggle the diplay the raw digits */
+  void ToggleRaw() { Toggle(fEnableRaw, "Raw"); }
+  //____________________________________________________________________
+  /** Toggle the diplay the Event Summary Data */
+  void ToggleESD() { Toggle(fEnableESD, "ESD"); }
+  //____________________________________________________________________
+  /** Toggle the diplay of tracks */
+  void ToggleTracks() { Toggle(fEnableTracks, "Tracks"); }
+  //____________________________________________________________________
+  /** Pop-down both menues */
+  void Quit() 
+  { 
+    fCb->Hide();
+    fSelect->Hide();
+    fgInstance = 0;
+    delete this;
+  }
+  //____________________________________________________________________
+  /** Get the static instance */
+  static Display* Instance() { 
+    if (!fgInstance) fgInstance = new Display();
+    return fgInstance;
+  }
+protected:
+  TControlBar* fCb;       // Control bar
+  TControlBar* fSelect;   // Selection bar
+  Bool_t fEnableHits;     // Whether simulated hits are enabled 
+  Bool_t fEnableDigits;   // Whether simulated digits are enabled 
+  Bool_t fEnableRaw;      // Whehter raw data digits are enabled
+  Bool_t fEnableESD;      // Whehter Event Summary Data is enabled
+  Bool_t fEnableTracks;   // Whether tracks are shown
+  Bool_t fHasHits;        // Whether simulated hits are rendered
+  Bool_t fHasDigits;      // Whether simulated digits are rendered
+  Bool_t fHasRaw;         // Whether raw data digits are rendered
+  Bool_t fHasESD;         // Whether Event Summary Data is rendered
+  Bool_t fHasTracks;      // Whether tracks are rendered
+  TList  fEnabled;
+  static Display* fgInstance; // Static singleton instance 
+};
+Display* Display::fgInstance = 0;
+
+
+//____________________________________________________________________
+Display* display()
+{
+  TGeoManager::Import("geometry.root");
+
+  Display* d = Display::Instance();
+  return d;
+
+}
+//____________________________________________________________________
+//
+// EOF
+//