1 /**************************************************************************
2 * Copyright(c) 2008, Christian Holm Christensen *
4 * Author: Christian Holm Christensen. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation for any purposes is hereby granted without fee, *
9 * provided that the above copyright notice appears in all copies and *
10 * that both the copyright notice and this permission notice remains *
11 * intact. The authors make no claims about the suitability of this *
12 * software for any purpose. It is provided "as is" without express or *
14 **************************************************************************/
16 /** @file AliEveFMDLoader.cxx
17 @author Christian Holm Christensen <cholm@nbi.dk>
18 @date Sun Mar 26 17:59:18 2006
19 @brief Implementation of AliEveFMDLoader singleton class
21 //____________________________________________________________________
23 // Forward Multiplicity Detector based on Silicon wafers. This class
24 // is the loader for the event display.
26 // This class is a singleton, meaning that there's only one instance
27 // of this. This is done to speed up the processing by putting all
28 // things that are needed every time into the constructor.
30 #include "AliRunLoader.h"
31 #include "EveBase/AliEveEventManager.h"
32 #include "AliEveFMDLoader.h"
33 #include "../FMD/AliFMDUShortMap.h"
34 #include "../FMD/AliFMDBoolMap.h"
35 #include "../FMD/AliFMDGeometry.h"
36 #include "../FMD/AliFMDParameters.h"
37 #include "../FMD/AliFMDDetector.h"
38 #include "../FMD/AliFMDRing.h"
39 #include "../FMD/AliFMDBaseDigit.h"
40 #include "../FMD/AliFMDDigit.h"
41 #include "../FMD/AliFMDRawReader.h"
42 #include "../FMD/AliFMDHit.h"
43 #include "AliESDEvent.h"
44 #include "AliESDFMD.h"
46 #include "AliRawReader.h"
47 #include <TClonesArray.h>
49 #include <TGeoShape.h>
50 #include <TGeoManager.h>
51 #include <TEveGeoNode.h>
52 #include <TEveBoxSet.h>
53 #include <TEveQuadSet.h>
54 #include <TEveManager.h>
60 // Some very private variables.
63 const Char_t* kDetector = "FMD%d";
64 const Char_t* kRing = "FMD%d%c";
65 const Char_t* kModule = "FMD%d%c[%02d-%02d]";
66 const Char_t* kSector = "FMD%d%c[%02d] %s";
68 const Char_t* kHits = "Hits";
69 const Char_t* kDigits = "Digits";
70 const Char_t* kRaw = "Raw";
71 const Char_t* kESD = "ESD";
75 //____________________________________________________________________
76 AliEveFMDLoader* AliEveFMDLoader::fgInstance = 0;
78 //____________________________________________________________________
79 AliEveFMDLoader* AliEveFMDLoader::Instance()
81 // Get the singleton instance. If the instance has not been
82 // instantised yet, it will be after this call.
84 fgInstance = new AliEveFMDLoader();
88 //____________________________________________________________________
89 AliEveFMDLoader::AliEveFMDLoader(const char* name, Bool_t useBoxes,
91 : TEveElementList(name, 0),
93 fDigitPalette(0, 1023),
95 fUseBoxDigits(useBoxes),
96 fHitCache("AliFMDHit",0),
97 fDigitCache("AliFMDDigit", 0),
98 fRawCache("AliFMDDigit", 0)
102 // @param name Name of the folder.
103 // @param useBoxes Whether to use boxes or Quads for the signals
104 // @param old Whether to enable reading old RCU data format
106 // increase reference count
109 // Increase reference counts on palettes
110 fHitPalette.IncRefCount();
111 fDigitPalette.IncRefCount();
112 fMultPalette.IncRefCount();
115 // Initialize the FMD geometry manager
116 TGeoManager* geoMan = AliEveEventManager::AssertGeometry();
118 geoMan->GetTopVolume()->cd(0);
120 AliFMDGeometry* geom = AliFMDGeometry::Instance();
122 geom->InitTransformations();
124 AliFMDParameters* pars = AliFMDParameters::Instance();
125 // pars->UseRcuTrailer(!old);
126 // pars->UseCompleteHeader(old);
127 // pars->SetSampleRate(4);
128 pars->Init(kFALSE, 0);
131 TGeoShape* inner = static_cast<TGeoShape*>(gGeoManager->GetListOfShapes()
132 ->FindObject("FMDI_physical_sensor"));
133 if (!inner) throw TEveException("Shape of inner type sensors not found");
134 TGeoShape* outer = static_cast<TGeoShape*>(gGeoManager->GetListOfShapes()
135 ->FindObject("FMDO_physical_sensor"));
136 if (!outer) throw TEveException("Shape of outer type sensors not found");
138 // Emulate reference counting
139 inner->SetUniqueID(1000);
140 outer->SetUniqueID(1000);
142 // Loop over detectors
143 for (UShort_t d = 1; d <= 3; d++) {
144 AliFMDDetector* detector = geom->GetDetector(d);
145 if (!detector) continue;
146 TEveElementList* ed = new TEveElementList(Form(kDetector,
149 ed->IncDenyDestroy();
150 ed->SetUserData(detector);
153 Char_t rings[] = { 'I', 'O', 0 };
154 Char_t* pr = &(rings[0]);
156 AliFMDRing* ring = detector->GetRing(*pr);
159 TEveElementList* er = new TEveElementList(Form(kRing,
163 er->IncDenyDestroy();
164 er->SetUserData(ring);
166 // UShort_t nsec = ring->GetNSectors();
167 // UShort_t nstr = ring->GetNStrips();
168 UShort_t nmod = ring->GetNModules();
170 for (UShort_t m = 0; m < nmod; m++) {
171 TEveGeoShape* em = new TEveGeoShape(Form(kModule,
176 em->SetTransMatrix(*(detector->FindTransform(ring->GetId(), 2*m)));
177 em->SetShape(ring->GetId() == 'I' ? inner : outer);
178 em->SetMainColor(Color_t(kRed));
179 em->SetMainTransparency(32);
180 em->IncDenyDestroy();
183 for (UShort_t s = 2*m; s < 2*m+2 && s < nsec; s++) {
184 TEveDigitSet* eb = MakeDigitSet(Form(kSector,
186 ring->GetId(), s), nstr);
188 eb->SetEmitSignals(kFALSE);
189 eb->SetPickable(kTRUE);
190 // eb->SetOwnIds(kTRUE);
191 } // for (UShort_t s ...)
193 } // for (UShort_t m ...)
195 } // for (UShort_t d ...)
198 //____________________________________________________________________
199 AliEveFMDLoader::~AliEveFMDLoader()
202 AliWarning("AliEveFMDLoader being destroyed!");
205 //____________________________________________________________________
207 AliEveFMDLoader::RemoveFromListTrees(TEveElement* el)
209 // Called when the element should be removed from the list. We
210 // overload this to allow clearing of signals.
212 // @param el Tree to remove from.
214 // Since we're most likely setting up for a new event, we clear all
215 // signals here - a little tricky, but it works(tm).
216 ClearDigitSets("All");
218 // Do normal TEveElement::RemoveElement
219 return TEveElementList::RemoveFromListTrees(el);
221 //____________________________________________________________________
223 AliEveFMDLoader::RemoveParent(TEveElement* el)
225 // Called when the element should be removed from the list. We
226 // overload this to allow clearing of signals.
228 // @param el Parent to remove from.
229 TEveElementList::RemoveParent(el);
232 //____________________________________________________________________
234 AliEveFMDLoader::MakeDigitSet(const char* name, UShort_t nstr)
236 // Make a digit set. The type of digit set depends on the setting
237 // of fUseBoxDigits. If this is true, we return a TEveBoxSet,
238 // otherwise a TEveQuadSet
241 // nstr The number of strips
243 // newly allocated digit set
244 TEveDigitSet* ret = 0;
246 TEveBoxSet* boxes = new TEveBoxSet(name);
247 // boxes->Reset(TEveBoxSet::kBT_AABox, kFALSE, nstr);
248 boxes->Reset(TEveBoxSet::kBT_FreeBox, kFALSE, nstr);
252 TEveQuadSet* quads = new TEveQuadSet(name);
253 quads->Reset(TEveQuadSet::kQT_RectangleXY, kFALSE, nstr);
259 //____________________________________________________________________
261 AliEveFMDLoader::ClearDigitSets(const char* type)
263 // Clear signals of some type.
265 // @param type Type of signals to clear
266 // Type can be one of
274 for (TEveElement::List_i di = BeginChildren();
275 di != EndChildren(); ++di) {
276 for (TEveElement::List_i ri = (*di)->BeginChildren();
277 ri != (*di)->EndChildren(); ++ri) {
278 for (TEveElement::List_i mi = (*ri)->BeginChildren();
279 mi != (*ri)->EndChildren(); ++mi) {
280 if (stype == "All") {
281 (*mi)->RemoveElements();
284 for (TEveElement::List_i si = (*mi)->BeginChildren();
285 si != (*mi)->EndChildren(); ++si) {
286 TEveDigitSet* signals = static_cast<TEveDigitSet*>((*si));
287 if (!signals) continue;
288 TString s(signals->GetName());
289 if (!s.Contains(type)) continue;
290 (*mi)->RemoveElement(signals);
297 //____________________________________________________________________
299 AliEveFMDLoader::FindDigitSet(const char* t, UShort_t d, Char_t r, UShort_t s)
301 // Find a digit set corresponding to the passed parameters. If it
302 // is not found, one is created
304 // @param type Type of data
308 // @return a digit set
309 TEveElement* detector = FindChild(Form(kDetector, d));
311 AliError(Form("Detector %s not found", Form(kDetector, d)));
315 TEveElement* ring = detector->FindChild(Form(kRing, d, r));
317 AliError(Form("Ring %s not found", Form(kRing, d, r)));
322 TEveElement* module = ring->FindChild(Form(kModule, d, r, mod, mod+1));
324 AliError(Form("Module %s not found", Form(kModule, d, r, s, s+1)));
328 TEveElement* sector = module->FindChild(Form(kSector, d, r, s, t));
329 TEveDigitSet* signal = static_cast<TEveDigitSet*>(sector);
331 AliFMDRing* rng = AliFMDGeometry::Instance()->GetRing(r);
332 signal = MakeDigitSet(Form(kSector, d, r, s, t), rng->GetNStrips());
333 module->AddElement(signal);
334 signal->SetEmitSignals(kFALSE);
335 signal->SetPickable(kTRUE);
337 if (t == kHits) signal->SetPalette(&fHitPalette);
338 else if (t == kDigits) signal->SetPalette(&fDigitPalette);
339 else if (t == kRaw) signal->SetPalette(&fDigitPalette);
340 else if (t == kESD) {
341 signal->SetPalette(&fMultPalette);
342 signal->SetOwnIds(kTRUE);
348 //____________________________________________________________________
350 AliEveFMDLoader::AddSignal(const char* t,
351 UShort_t det, Char_t rng, UShort_t sec,
352 UShort_t str, Float_t signal, Float_t min,
353 Float_t max, TObject* ref)
355 // Add a signal to a digit set
357 // @param type Type of data
358 // @param det Detector
362 // @param signal Signal value
363 // @param min Minimum of this kind of signal
364 // @param max Maximum of this kind of signal
365 // @param ref Reference object
366 AliFMDGeometry* geom = AliFMDGeometry::Instance();
368 geom->Detector2XYZ(det, rng, sec, str, x, y, z);
369 AddSignal(t, det, rng, sec, str, x, y, z, signal, min, max, ref);
372 //____________________________________________________________________
374 AliEveFMDLoader::AddSignal(const char* t,
375 UShort_t det, Char_t rng, UShort_t sec,
376 UShort_t str, Double_t x, Double_t y, Double_t z,
377 Float_t signal, Float_t min, Float_t max,
380 // Add a signal to a digit set, with known (x,y,z) coordinates
381 // (this is for hits)
383 // @param type Type of data
384 // @param det Detector
388 // @param x X coordinate
389 // @param y Y coordinate
390 // @param z Z coordinate
391 // @param signal Signal value
392 // @param min Minimum of this kind of signal
393 // @param max Maximum of this kind of signal
394 // @param ref Reference object
395 AliFMDGeometry* geom = AliFMDGeometry::Instance();
396 AliFMDRing* ring = geom->GetRing(rng);
399 TEveDigitSet* signals = FindDigitSet(t, det, rng, sec);
401 AliWarning(Form("No signal (%s) found for FMD%d%c[%02d,%03d]",
402 t, det, rng, sec, str));
406 Float_t scaled = TMath::Min((signal - min) / (max - min) * 10., 10.);
407 Double_t w = 2*ring->GetPitch();
408 Int_t value = int(TMath::Nint(signal));
409 AliDebug(1, Form("New signal at FMD%d%c[%02d,%03d]=%f (v=%d, s=%f)",
410 det, rng, sec, str, signal, value, scaled));
411 AddDigit(signals, x, y, z, w, scaled, value, ref);
414 //____________________________________________________________________
416 AliEveFMDLoader::AddDigit(TEveDigitSet* signals,
417 Double_t x, Double_t y, Double_t z,
418 Double_t w, Float_t scaled, Int_t value,
421 // Add a digit to a digit set.
423 // @param signals Digit set.
424 // @param x X coordinate
425 // @param y Y coordinate
426 // @param z Z coordinate
427 // @param w strip pitch
428 // @param scaled Scaled value
429 // @param value Signal value
430 // @param ref Reference object
432 TEveBoxSet* boxes = static_cast<TEveBoxSet*>(signals);
433 Float_t zc = (z > 0 ? -1 : 1) * scaled + z;
434 Float_t vs[] = { -w, -5*w, zc-scaled, // Lower back left
435 +w, -5*w, zc-scaled, // Lower back right
436 +w, +5*w, zc-scaled, // Lower front right
437 -w, +5*w, zc-scaled, // Lower front left
438 -w, -5*w, zc+scaled, // Upper back left
439 +w, -5*w, zc+scaled, // Upper back right
440 +w, +5*w, zc+scaled, // Upper front right
441 -w, +5*w, zc+scaled }; // Upper front left
442 Float_t ang = TMath::ATan2(y,x);
443 for (size_t i = 0; i < 8; i++) {
444 Float_t bx = vs[3*i+0];
445 Float_t by = vs[3*i+1];
446 Float_t ca = TMath::Cos(ang);
447 Float_t sa = TMath::Sin(ang);
448 vs[3*i+0] = bx * ca - by * sa + x;
449 vs[3*i+1] = bx * sa + by * ca + y;
451 // boxes->AddBox(x, y, (z > 0 ? -scaled : 0) + z , 5*w, w, scaled);
453 boxes->DigitValue(value);
454 if (ref) boxes->DigitId(ref);
457 TEveQuadSet* quads = static_cast<TEveQuadSet*>(signals);
458 quads->AddQuad(x,y,z,w,w);
459 quads->QuadValue(value);
460 if (ref) quads->QuadId(ref);
465 //____________________________________________________________________
467 AliEveFMDLoader::CheckAdd()
469 // check if we shoul re-add ourselves to the current event node
470 TEveElement* event = gEve->GetCurrentEvent();
471 if (event && event->FindChild(GetName())) return;
472 gEve->AddElement(this);
476 //____________________________________________________________________
478 AliEveFMDLoader::LoadHits()
480 // Load and display hits
481 ClearDigitSets(kHits);
483 AliRunLoader* rl = AliEveEventManager::AssertRunLoader();
485 AliError("No run loader");
490 TTree* ht = rl->GetTreeH("FMD", false);
492 AliError("No FMD tree");
496 TClonesArray* hits = &fHitCache;
498 ht->SetBranchAddress("FMD", &hits);
500 Float_t min = fHitPalette.GetMinVal();
501 Float_t max = fHitPalette.GetMaxVal();
503 Int_t nTracks = ht->GetEntriesFast();
504 for (Int_t i = 0; i < nTracks; i++) {
505 Int_t hitRead = ht->GetEntry(i);
506 if (hitRead <= 0) continue;
508 Int_t nHit = hits->GetEntriesFast();
509 if (nHit <= 0) continue;
511 for (Int_t j = 0; j < nHit; j++) {
512 AliFMDHit* hit = static_cast<AliFMDHit*>(hits->At(j));
516 hit->Detector(), hit->Ring(), hit->Sector(), hit->Strip(),
517 hit->X(), hit->Y(), hit->Z(), int(hit->Edep()*1000),
524 //____________________________________________________________________
526 AliEveFMDLoader::DoLoadDigits(const char* t, TClonesArray* digits)
528 // Do the actual display of digits
530 // @param type What to show
531 // @param digits The digits
532 Float_t min = fDigitPalette.GetMinVal();
533 Float_t max = fDigitPalette.GetMaxVal();
535 Int_t n = digits->GetEntriesFast();
536 for (Int_t i = 0; i < n; i++) {
537 AliFMDDigit* digit = static_cast<AliFMDDigit*>(digits->At(i));
539 AddSignal(t, digit->Detector(), digit->Ring(), digit->Sector(),
540 digit->Strip(), digit->Counts(), min, max, digit);
545 //____________________________________________________________________
547 AliEveFMDLoader::LoadDigits()
549 // Load and display simulated digits
550 ClearDigitSets(kDigits);
552 AliRunLoader* rl = AliEveEventManager::AssertRunLoader();
554 AliError("No run-loader");
558 rl->LoadDigits("FMD");
559 TTree* dt = rl->GetTreeD("FMD", false);
561 AliError("No FMD tree");
565 TClonesArray* digits = &fDigitCache;
567 dt->SetBranchAddress("FMD", &digits);
569 Int_t read = dt->GetEntry(0);
571 AliWarning("Nothing read");
574 DoLoadDigits(kDigits, digits);
578 //____________________________________________________________________
580 AliEveFMDLoader::LoadRaw()
582 // Load and display raw digits
583 ClearDigitSets(kRaw);
585 AliRawReader* rr = AliEveEventManager::AssertRawReader();
587 AliError("No raw-reader");
591 std::cout<<"Now in event # " << *(rr->GetEventId()) << std::endl;
592 AliFMDRawReader* fr = new AliFMDRawReader(rr, 0);
593 TClonesArray* digits = &fRawCache;
596 fr->ReadAdcs(digits);
598 DoLoadDigits(kRaw, digits);
601 //____________________________________________________________________
603 AliEveFMDLoader::LoadESD()
605 // Load and display ESD information
606 ClearDigitSets(kESD);
608 AliESDEvent* esd = AliEveEventManager::AssertESD();
614 AliESDFMD* fmd = esd->GetFMDData();
616 AliError("No FMD ESD data");
620 Float_t min = fMultPalette.GetMinVal();
621 Float_t max = fMultPalette.GetMaxVal();
623 for (UShort_t det = 1; det <= 3; det++) {
624 Char_t rings[] = { 'I', (det == 1 ? '\0' : 'O'), '\0' };
625 for (Char_t* rng = rings; *rng != '\0'; rng++) {
626 UShort_t nsec = (*rng == 'I' ? 20 : 40);
627 UShort_t nstr = (*rng == 'I' ? 512 : 256);
628 for (UShort_t sec = 0; sec < nsec; sec++) {
629 for (UShort_t str = 0; str < nstr; str++) {
630 Float_t mult = fmd->Multiplicity(det,*rng,sec,str);
631 if (mult == AliESDFMD::kInvalidMult) continue;
632 Float_t eta = fmd->Eta(det,*rng,sec,str);
633 AddSignal(kESD, det, *rng, sec, str, mult, min, max,
634 new TNamed(Form("FMD%d%c[%02d,%03d]", det, *rng, sec, str),
635 Form("Mch=%f, eta=%f", mult, eta)));
648 //____________________________________________________________________