From 274799f39efc9c1673bd6ea8342abfaf3c413879 Mon Sep 17 00:00:00 2001 From: mtadel Date: Mon, 26 May 2008 14:11:11 +0000 Subject: [PATCH] From Christian Holm Christensen. 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 | 646 +++++++++++++++++++++++++++++++++ EVE/EveDet/AliEveFMDLoader.h | 205 +++++++++++ EVE/EveDet/LinkDef.h | 3 + EVE/alice-macros/fmd_digits.C | 7 + EVE/alice-macros/fmd_esd.C | 7 + EVE/alice-macros/fmd_hits2.C | 7 + EVE/alice-macros/fmd_raw.C | 7 + EVE/macros/display.C | 396 ++++++++++++++++++++ 8 files changed, 1278 insertions(+) create mode 100644 EVE/EveDet/AliEveFMDLoader.cxx create mode 100644 EVE/EveDet/AliEveFMDLoader.h create mode 100644 EVE/alice-macros/fmd_digits.C create mode 100644 EVE/alice-macros/fmd_esd.C create mode 100644 EVE/alice-macros/fmd_hits2.C create mode 100644 EVE/alice-macros/fmd_raw.C create mode 100644 EVE/macros/display.C diff --git a/EVE/EveDet/AliEveFMDLoader.cxx b/EVE/EveDet/AliEveFMDLoader.cxx new file mode 100644 index 00000000000..6c98a3cd2a0 --- /dev/null +++ b/EVE/EveDet/AliEveFMDLoader.cxx @@ -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 + @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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// 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(gGeoManager->GetListOfShapes() + ->FindObject("FISE")); + if (!inner) throw TEveException("Shape of inner type sensors not found"); + TGeoShape* outer = static_cast(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((*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(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(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(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(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(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 index 00000000000..2080d035868 --- /dev/null +++ b/EVE/EveDet/AliEveFMDLoader.h @@ -0,0 +1,205 @@ +// -*- mode: C++ -*- +// +/* Copyright(c) 2008, Christian Holm Christensen + * + * Latest changes by Christian Holm Christensen + * + * See cxx source for full Copyright notice + */ +/** @file AliEveFMDLoader.h + @author Christian Holm Christensen + @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 +#include +#include +// 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 +// diff --git a/EVE/EveDet/LinkDef.h b/EVE/EveDet/LinkDef.h index 32b1b57a34d..1b95fd1b14b 100644 --- a/EVE/EveDet/LinkDef.h +++ b/EVE/EveDet/LinkDef.h @@ -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 index 00000000000..3886fd11bec --- /dev/null +++ b/EVE/alice-macros/fmd_digits.C @@ -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 index 00000000000..e29be95bd49 --- /dev/null +++ b/EVE/alice-macros/fmd_esd.C @@ -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 index 00000000000..60d35a32150 --- /dev/null +++ b/EVE/alice-macros/fmd_hits2.C @@ -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 index 00000000000..d3b663952f7 --- /dev/null +++ b/EVE/alice-macros/fmd_raw.C @@ -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 index 00000000000..c0f66e3fa08 --- /dev/null +++ b/EVE/macros/display.C @@ -0,0 +1,396 @@ +#ifndef __CINT__ +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include "aliroot/EVE/EveBase/AliEveEventManager.h" +# include +#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(buts); + char** meth = const_cast(meths); + char** hint = const_cast(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(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 +// -- 2.43.0