Separating run-dependent mapping data from data, which are not
[u/mrichter/AliRoot.git] / MUON / AliMUONMCDataInterface.cxx
CommitLineData
1df4a03e 1/**************************************************************************
2* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3* *
4* Author: The ALICE Off-line Project. *
5* Contributors are mentioned in the code where appropriate. *
6* *
7* Permission to use, copy, modify and distribute this software and its *
8* documentation strictly for non-commercial purposes is hereby granted *
9* without fee, provided that the above copyright notice appears in all *
10* copies and that both the copyright notice and this permission notice *
11* appear in the supporting documentation. The authors make no claims *
12* about the suitability of this software for any purpose. It is *
13* provided "as is" without express or implied warranty. *
14**************************************************************************/
15
16// $Id$
17
3d1463c8 18//-----------------------------------------------------------------------------
1df4a03e 19/// \class AliMUONMCDataInterface
20///
21/// Easy to use MC data accessor
22///
23/// \author Laurent Aphecetche, Subatech
e8636ba0 24///
25// Moved parts of old AliMUONDataInterface interface to AliMUONMCDataInterface
26// Artur Szostak <artursz@iafrica.com> (University of Cape Town)
3d1463c8 27//-----------------------------------------------------------------------------
1df4a03e 28
29#include "AliMUONMCDataInterface.h"
e9bef706 30#include "AliMUONVDigitStore.h"
31#include "AliMUONVHitStore.h"
e9bef706 32#include "AliMUONVTriggerStore.h"
e8636ba0 33#include "AliMUONHit.h"
34#include "AliMUONVDigit.h"
35#include "AliMUONLocalTrigger.h"
36#include "AliMUONRegionalTrigger.h"
37#include "AliMUONGlobalTrigger.h"
38
39#include "AliMpIntPair.h"
40#include "AliMpDEManager.h"
41#include "AliMpConstants.h"
a55f49a0 42#include "AliMpCDB.h"
1df4a03e 43
44#include "AliLog.h"
1df4a03e 45#include "AliRunLoader.h"
aa73f8fb 46#include "AliHeader.h"
1df4a03e 47#include "AliStack.h"
aa73f8fb 48#include "AliCDBManager.h"
e9bef706 49
1df4a03e 50#include <Riostream.h>
51#include <TClonesArray.h>
e9bef706 52#include <TList.h>
1df4a03e 53#include <TParticle.h>
e8636ba0 54#include <TIterator.h>
55#include <cstdlib>
56#include <cassert>
1df4a03e 57
58/// \cond CLASSIMP
59ClassImp(AliMUONMCDataInterface)
60/// \endcond
61
e9bef706 62Int_t AliMUONMCDataInterface::fgInstanceCounter(0);
63
1df4a03e 64//_____________________________________________________________________________
65AliMUONMCDataInterface::AliMUONMCDataInterface(const char* filename) :
66TObject(),
e9bef706 67fLoader(0x0),
68fHitStore(0x0),
69fSDigitStore(0x0),
70fDigitStore(0x0),
71fTriggerStore(0x0),
72fTrackRefs(0x0),
73fCurrentEvent(-1),
e8636ba0 74fIsValid(kFALSE),
75fCurrentIteratorType(kNoIterator),
76fCurrentIndex(-1),
77fDataX(-1),
78fDataY(-1),
79fIterator(0x0)
1df4a03e 80{
81 /// ctor
e9bef706 82
83 ++fgInstanceCounter;
84
88c5d53f 85 if ( AliCDBManager::Instance() != NULL &&
86 AliCDBManager::Instance()->GetDefaultStorage() == NULL ) {
87 AliFatal("CDB default storage not defined.");
ae9e8f66 88 }
89
e9bef706 90 Open(filename);
a55f49a0 91
92 // Load mapping
93 if ( ! AliMpCDB::LoadMpSegmentation() ) {
94 AliFatal("Could not access mapping from OCDB !");
95 }
1df4a03e 96}
97
98//_____________________________________________________________________________
99AliMUONMCDataInterface::~AliMUONMCDataInterface()
100{
101 /// dtor
e9bef706 102 if ( fLoader )
103 {
104 delete fLoader->GetRunLoader();
105 }
106 --fgInstanceCounter;
107}
108
109//_____________________________________________________________________________
e8636ba0 110AliMUONVHitStore*
111AliMUONMCDataInterface::HitStore(Int_t event, Int_t track)
112{
113 /// Return the hitStore for a given track of one event
114 /// Return 0x0 if event and/or track not found
115 /// Returned pointer should not be deleted
116
117 if (not IsValid()) return 0x0;
4cfe83bc 118
119 if (event == fCurrentEvent)
120 {
121 if (track == fDataX and fHitStore != 0x0) // using fDataX as track number.
e8636ba0 122 return fHitStore;
4cfe83bc 123 }
124 else
125 {
126 ResetStores();
127 if ( not LoadEvent(event) ) return 0x0;
128 }
e8636ba0 129
130 fLoader->LoadHits();
131
132 TTree* treeH = fLoader->TreeH();
133 if (treeH == 0x0)
134 {
135 AliError("Could not get treeH");
136 return 0x0;
137 }
138
139 fHitStore = AliMUONVHitStore::Create(*treeH);
140 AliDebug(1,"Creating hitStore from treeH");
141 if ( fHitStore != 0x0 )
142 {
143 fHitStore->Connect(*treeH);
144 if ( treeH->GetEvent(track) == 0 )
145 {
146 AliError(Form("Could not read track %d",track));
147 fHitStore->Clear();
148 return 0x0;
149 }
150 fDataX = track; // using fDataX as track number.
151 }
152
153 fLoader->UnloadHits();
154
155 return fHitStore;
156}
157
158//_____________________________________________________________________________
159AliMUONVDigitStore*
160AliMUONMCDataInterface::SDigitStore(Int_t event)
161{
162 /// Return the SDigit store for a given event.
163 /// Return 0 if event not found
164 /// Returned pointer should not be deleted
165
166 if (not IsValid()) return 0x0;
e8636ba0 167
4cfe83bc 168 if (event == fCurrentEvent)
169 {
170 if (fSDigitStore != 0x0)
171 return fSDigitStore;
172 }
173 else
174 {
175 ResetStores();
176 if ( not LoadEvent(event) ) return 0x0;
177 }
e8636ba0 178
179 fLoader->LoadSDigits();
180
181 TTree* treeS = fLoader->TreeS();
182 if (treeS == 0x0)
183 {
184 AliError("Could not get treeS");
185 return 0x0;
186 }
187
188 fSDigitStore = AliMUONVDigitStore::Create(*treeS);
189 if ( fSDigitStore != 0x0 )
190 {
191 fSDigitStore->Clear();
192 fSDigitStore->Connect(*treeS);
193 treeS->GetEvent(0);
194 }
195
196 fLoader->UnloadSDigits();
197
198 return fSDigitStore;
199}
200
201//_____________________________________________________________________________
e9bef706 202AliMUONVDigitStore*
203AliMUONMCDataInterface::DigitStore(Int_t event)
204{
205 /// Return a pointer to the digitStore for a given event (or 0 if not found)
206 /// Returned pointer should not be deleted
207
e8636ba0 208 if (not IsValid()) return 0x0;
e8636ba0 209
4cfe83bc 210 if (event == fCurrentEvent)
211 {
212 if (fDigitStore != 0x0)
213 return fDigitStore;
214 }
215 else
216 {
217 ResetStores();
218 if ( not LoadEvent(event) ) return 0x0;
219 }
e9bef706 220
221 fLoader->LoadDigits();
222
223 TTree* treeD = fLoader->TreeD();
e8636ba0 224 if (treeD == 0x0)
e9bef706 225 {
226 AliError("Could not get treeD");
227 return 0x0;
228 }
229
e8636ba0 230 fDigitStore = AliMUONVDigitStore::Create(*treeD);
231 if ( fDigitStore != 0x0 )
e9bef706 232 {
233 fDigitStore->Clear();
234 fDigitStore->Connect(*treeD);
235 treeD->GetEvent(0);
236 }
237
238 fLoader->UnloadDigits();
239
240 return fDigitStore;
241}
242
243//_____________________________________________________________________________
e8636ba0 244AliStack*
245AliMUONMCDataInterface::Stack(Int_t event)
246{
247 /// Get the Stack (list of generated particles) for one event
248 /// Returned pointer should not be deleted
249
250 if ( not IsValid() ) return 0x0;
251
252 if (event != fCurrentEvent)
253 {
254 ResetStores();
255 if ( not LoadEvent(event) ) return 0x0;
256 }
257
258 fLoader->GetRunLoader()->LoadKinematics();
259
260 return fLoader->GetRunLoader()->Stack();
261}
262
263//_____________________________________________________________________________
264TClonesArray*
265AliMUONMCDataInterface::TrackRefs(Int_t event, Int_t track)
266{
267 /// Get the track references for a given (generated) track of one event
268 /// Returned pointer should not be deleted
269
270 if ( not IsValid() ) return 0x0;
4cfe83bc 271
272 if (event == fCurrentEvent)
273 {
274 if (track == fDataX and fTrackRefs != 0x0) // using fDataX as track number.
275 return fTrackRefs;
276 }
277 else
e8636ba0 278 {
279 ResetStores();
280 if ( not LoadEvent(event) ) return 0x0;
281 }
282
e8636ba0 283 fLoader->GetRunLoader()->LoadTrackRefs();
284
285 TTree* treeTR = fLoader->GetRunLoader()->TreeTR();
286
287 if ( fTrackRefs != 0x0 ) fTrackRefs->Clear("C");
288
289 if (treeTR != 0x0)
290 {
291 if ( treeTR->GetEvent(track) > 0 )
292 {
91469ad4 293 TBranch* branch = treeTR->GetBranch("TrackReferences");
e8636ba0 294 branch->SetAddress(&fTrackRefs);
295 branch->GetEvent(track);
296 fDataX = track; // using fDataX as track number.
297 }
298 }
299 else
300 {
301 AliError("Could not get TreeTR");
302 }
303
304 fLoader->GetRunLoader()->UnloadTrackRefs();
305
306 return fTrackRefs;
307}
308
309//_____________________________________________________________________________
310AliMUONVTriggerStore*
311AliMUONMCDataInterface::TriggerStore(Int_t event)
312{
313 /// Return the triggerStore for a given event.
314 /// Return 0x0 if event not found.
315 /// Returned pointer should not be deleted.
316
317 if (not IsValid()) return 0x0;
e8636ba0 318
4cfe83bc 319 if (event == fCurrentEvent)
320 {
321 if (fTriggerStore != 0x0)
322 return fTriggerStore;
323 }
324 else
325 {
326 ResetStores();
327 if ( not LoadEvent(event) ) return 0x0;
328 }
e8636ba0 329
330 fLoader->LoadDigits();
331
332 TTree* treeD = fLoader->TreeD();
333 if ( treeD == 0x0 )
334 {
335 AliError("Could not get treeD");
336 return 0x0;
337 }
338
339 fTriggerStore = AliMUONVTriggerStore::Create(*treeD);
340 if ( fTriggerStore != 0x0 )
341 {
342 fTriggerStore->Clear();
343 fTriggerStore->Connect(*treeD);
344 treeD->GetEvent(0);
345 }
346
347 fLoader->UnloadDigits();
348
349 return fTriggerStore;
350}
351
352//_____________________________________________________________________________
e9bef706 353void
354AliMUONMCDataInterface::DumpDigits(Int_t event, Bool_t sorted)
355{
356 /// Dump the digits for a given event, sorted if requested.
357 DigitStore(event);
358
e8636ba0 359 if ( fDigitStore != 0x0 )
e9bef706 360 {
361 if ( sorted )
362 {
363 DumpSorted(*fDigitStore);
364 }
365 else
366 {
367 fDigitStore->Print();
368 }
369 }
1df4a03e 370}
371
372//_____________________________________________________________________________
373void
e9bef706 374AliMUONMCDataInterface::DumpHits(Int_t event)
1df4a03e 375{
376 /// Dump all the hits for one event
377
378 Int_t ntracks = NumberOfTracks(event);
379
380 for ( Int_t i = 0; i < ntracks; ++i )
381 {
382 cout << ">> Track " << i << endl;
e9bef706 383 HitStore(event,i);
384 if ( fHitStore )
385 {
386 fHitStore->Print("","full");
387 }
1df4a03e 388 }
389}
390
391//_____________________________________________________________________________
392void
e9bef706 393AliMUONMCDataInterface::DumpKine(Int_t event)
1df4a03e 394{
395 /// Dump all generated particles for one event
396 AliStack* stack = Stack(event);
397
e8636ba0 398 if ( stack != 0x0 )
1df4a03e 399 {
400 Int_t nparticles = (Int_t) stack->GetNtrack();
401
402 for (Int_t iparticle=0; iparticle<nparticles; ++iparticle)
403 {
404 stack->Particle(iparticle)->Print("");
405 }
406 }
407 else
408 {
409 AliError("Could not get stack");
410 }
411}
412
413//_____________________________________________________________________________
414void
e9bef706 415AliMUONMCDataInterface::DumpSDigits(Int_t event, Bool_t sorted)
416{
417 /// Dump the SDigits for a given event, sorted if requested
418 SDigitStore(event);
419
e8636ba0 420 if ( fSDigitStore != 0x0 )
e9bef706 421 {
422 if ( sorted )
423 {
424 DumpSorted(*fSDigitStore);
425 }
426 else
427 {
428 fSDigitStore->Print();
429 }
430 }
431}
432
433//_____________________________________________________________________________
434void
435AliMUONMCDataInterface::DumpSorted(const AliMUONVStore& store) const
436{
437 /// Dump the given store in sorted order
438
439 TIter next(store.CreateIterator());
440 TObject* object;
441 TList list;
442 list.SetOwner(kFALSE);
443
444 while ( ( object = next() ) )
445 {
446 list.Add(object);
447 }
448
449 list.Sort();
450
451 list.Print();
452}
453
454//_____________________________________________________________________________
455void
456AliMUONMCDataInterface::DumpTrackRefs(Int_t event)
1df4a03e 457{
458 /// Dump track references for one event
459 Int_t ntrackrefs = NumberOfTrackRefs(event);
460
461 for ( Int_t i = 0; i < ntrackrefs; ++i )
462 {
e9bef706 463 TrackRefs(event,i);
e8636ba0 464 if ( fTrackRefs != 0x0 )
e9bef706 465 {
466 fTrackRefs->Print("","*");
467 }
468 }
469}
470
471//_____________________________________________________________________________
472void
473AliMUONMCDataInterface::DumpTrigger(Int_t event)
474{
475 /// Dump trigger for a given event (trigger is read from TreeD)
476
477 TriggerStore(event);
478
e8636ba0 479 if ( fTriggerStore != 0x0 )
e9bef706 480 {
481 fTriggerStore->Print();
1df4a03e 482 }
483}
484
485//_____________________________________________________________________________
1df4a03e 486Bool_t
e9bef706 487AliMUONMCDataInterface::LoadEvent(Int_t event)
488{
489 /// Load event if different from the current one.
e8636ba0 490 /// Returns kFALSE on error and kTRUE if the event was loaded.
491
492 assert( IsValid() );
493
494 AliDebug(1,Form("Loading event %d using runLoader %p",event,fLoader->GetRunLoader()));
495 if (fLoader->GetRunLoader()->GetEvent(event) == 0)
e9bef706 496 {
497 fCurrentEvent = event;
e8636ba0 498 return kTRUE;
e9bef706 499 }
e8636ba0 500 else
501 return kFALSE;
1df4a03e 502}
503
e9bef706 504
1df4a03e 505//_____________________________________________________________________________
506Int_t
507AliMUONMCDataInterface::NumberOfEvents() const
508{
509 /// Number of events in the file we're connected to
e8636ba0 510 if (not IsValid()) return -1;
e9bef706 511 return fLoader->GetRunLoader()->GetNumberOfEvents();
1df4a03e 512}
513
514//_____________________________________________________________________________
515Int_t
e9bef706 516AliMUONMCDataInterface::NumberOfTracks(Int_t event)
1df4a03e 517{
518 /// Number of tracks in the event
e8636ba0 519 if ( not IsValid()) return -1;
1df4a03e 520
e8636ba0 521 if (event != fCurrentEvent)
522 {
523 ResetStores();
524 if ( not LoadEvent(event) ) return -1;
525 }
e9bef706 526
527 fLoader->LoadHits();
1df4a03e 528
e8636ba0 529 Int_t rv(-1);
1df4a03e 530
e9bef706 531 TTree* treeH = fLoader->TreeH();
e8636ba0 532 if (treeH != 0x0)
1df4a03e 533 {
e9bef706 534 rv = static_cast<Int_t>(treeH->GetEntries());
1df4a03e 535 }
536 else
537 {
538 AliError("Could not get TreeH");
539 }
540
e9bef706 541 fLoader->UnloadHits();
1df4a03e 542
543 return rv;
544}
545
546//_____________________________________________________________________________
547Int_t
e9bef706 548AliMUONMCDataInterface::NumberOfTrackRefs(Int_t event)
1df4a03e 549{
550 /// Number of track references in the event
e8636ba0 551 if ( not IsValid()) return -1;
1df4a03e 552
e8636ba0 553 if (event != fCurrentEvent)
554 {
555 ResetStores();
556 if ( not LoadEvent(event) ) return -1;
557 }
e9bef706 558
559 fLoader->GetRunLoader()->LoadTrackRefs();
1df4a03e 560
e8636ba0 561 Int_t rv(-1);
1df4a03e 562
e9bef706 563 TTree* treeTR = fLoader->GetRunLoader()->TreeTR();
e8636ba0 564 if (treeTR != 0x0)
1df4a03e 565 {
e9bef706 566 rv = static_cast<Int_t>(treeTR->GetEntries());
1df4a03e 567 }
568 else
569 {
570 AliError("Could not get TreeTR");
571 }
572
e9bef706 573 fLoader->GetRunLoader()->UnloadTrackRefs();
1df4a03e 574
575 return rv;
576}
577
578//_____________________________________________________________________________
e9bef706 579void
580AliMUONMCDataInterface::Open(const char* filename)
581{
582 /// Connect to a given galice.root file
583
e8636ba0 584 ResetStores();
e9bef706 585
586 fCurrentEvent=-1;
587
e8636ba0 588 if ( fLoader != 0x0 )
e9bef706 589 {
590 delete fLoader->GetRunLoader();
591 }
592
593 fLoader = 0x0;
594
595 fIsValid = kTRUE;
596
597 TString foldername(Form("%s-%d",ClassName(),fgInstanceCounter));
598
599 while (AliRunLoader::GetRunLoader(foldername))
600 {
601 delete AliRunLoader::GetRunLoader(foldername);
602 }
603
604 AliRunLoader* runLoader = AliRunLoader::Open(filename,foldername);
e8636ba0 605 if (runLoader == 0x0)
e9bef706 606 {
607 AliError(Form("Cannot open file %s",filename));
608 fIsValid = kFALSE;
609 }
aa73f8fb 610
611 // Get run number and set it to CDB manager
612 runLoader->LoadHeader();
613 if ( ! runLoader->GetHeader() ) {
614 AliError("Cannot load header.");
615 fIsValid = kFALSE;
616 }
617 else {
618 Int_t runNumber = runLoader->GetHeader()->GetRun();
619 AliCDBManager::Instance()->SetRun(runNumber);
620 }
621 runLoader->UnloadHeader();
622
e9bef706 623 fLoader = runLoader->GetDetectorLoader("MUON");
e8636ba0 624 if (fLoader == 0x0)
e9bef706 625 {
626 AliError("Cannot get AliMUONLoader");
627 fIsValid = kFALSE;
628 }
629
e8636ba0 630 if (not IsValid())
e9bef706 631 {
632 AliError(Form("Could not access %s filename. Object is unuseable",filename));
633 }
634}
635
636//_____________________________________________________________________________
e8636ba0 637Bool_t AliMUONMCDataInterface::GetEvent(Int_t event)
e9bef706 638{
e8636ba0 639/// Loads all simulated data for the given event.
640
641 if (HitStore(event, 0) == 0x0) return kFALSE;
642 if (SDigitStore(event) == 0x0) return kFALSE;
643 if (DigitStore(event) == 0x0) return kFALSE;
644 if (TriggerStore(event) == 0x0) return kFALSE;
645 if (TrackRefs(event, 0) == 0x0) return kFALSE;
646 return kTRUE;
647}
648
649//_____________________________________________________________________________
650Int_t AliMUONMCDataInterface::NumberOfParticles()
651{
652/// Returns the total number of particles in the kinematics tree.
653
654 AliStack* stack = Stack(fCurrentEvent);
655 if ( stack == 0x0 ) return -1;
656 return (Int_t) stack->GetNtrack();
657}
658
659//_____________________________________________________________________________
660TParticle* AliMUONMCDataInterface::Particle(Int_t index)
661{
662/// Returns the index'th particle in the kinematics tree.
663/// @param index The index number of the particle in the range [0 ... N-1]
664/// where N = NumberOfParticles()
665
666 AliStack* stack = Stack(fCurrentEvent);
667 if ( stack == 0x0 ) return 0x0;
668 return static_cast<TParticle*>( stack->Particle(index) );
669}
670
671//_____________________________________________________________________________
672Int_t AliMUONMCDataInterface::NumberOfTracks()
673{
674/// Returns the number of primary tracks (from primary particles) in the current event.
675
676 return NumberOfTracks(fCurrentEvent);
677}
678
679//_____________________________________________________________________________
680Int_t AliMUONMCDataInterface::NumberOfHits(Int_t track)
681{
682/// Returns the number of hits for a given primary track/particle.
683/// @param track The track number in the range [0 .. N-1]
684/// where N = NumberOfTracks()
685
686 TIterator* iter = GetIterator(kHitIterator, track);
687 return CountObjects(iter);
688}
689
690//_____________________________________________________________________________
691AliMUONHit*
692AliMUONMCDataInterface::Hit(Int_t track, Int_t index)
693{
694/// Returns a pointer to the index'th hit object.
695/// @param track The track number in the range [0 .. N-1]
696/// where N = NumberOfTracks()
697/// @param index The index number of the hit in the range [0 ... M-1]
698/// where M = NumberOfHits(track)
699
700 TIterator* iter = GetIterator(kHitIterator, track);
701 return static_cast<AliMUONHit*>( FetchObject(iter, index) );
702}
703
704//_____________________________________________________________________________
705Int_t AliMUONMCDataInterface::NumberOfSDigits(Int_t detElemId)
706{
707/// Returns the number of summable digits to be found on a given detector element.
708/// @param detElemId The detector element ID number to search on.
709
710 TIterator* iter = GetIterator(kSDigitIteratorByDetectorElement, detElemId);
711 return CountObjects(iter);
712}
713
714//_____________________________________________________________________________
715AliMUONVDigit* AliMUONMCDataInterface::SDigit(Int_t detElemId, Int_t index)
716{
717/// Returns the a pointer to the index'th summable digit on the specified detector element.
718/// @param detElemId The detector element ID number to search on.
719/// @param index The index number of the digit to fetch in the range [0 .. N-1],
720/// where N = NumberOfDigits(detElemId)
721
722 TIterator* iter = GetIterator(kSDigitIteratorByDetectorElement, detElemId);
723 return static_cast<AliMUONVDigit*>( FetchObject(iter, index) );
724}
725
726//_____________________________________________________________________________
727Int_t AliMUONMCDataInterface::NumberOfSDigits(Int_t chamber, Int_t cathode)
728{
729/// Returns the number of summable digits to be found on a specific chamber and cathode.
730/// @param chamber The chamber number in the range [0 .. 13].
731/// @param cathode The cathode in the range [0 .. 1], where 0 is the bending and
732/// 1 is the non-bending plane.
733
734 TIterator* iter = GetIterator(kSDigitIteratorByChamberAndCathode, chamber, cathode);
735 return CountObjects(iter);
736}
737
738//_____________________________________________________________________________
739AliMUONVDigit* AliMUONMCDataInterface::SDigit(Int_t chamber, Int_t cathode, Int_t index)
740{
741/// Returns the a pointer to the index'th summable digit on the specified chamber and cathode.
742/// @param chamber The chamber number in the range [0 .. 13].
743/// @param cathode The cathode in the range [0 .. 1], where 0 is the bending and
744/// 1 is the non-bending plane.
745/// @param index The index number of the digit to fetch in the range [0 .. N-1],
746/// where N = NumberOfDigits(chamber, cathode)
747
748 TIterator* iter = GetIterator(kSDigitIteratorByChamberAndCathode, chamber, cathode);
749 return static_cast<AliMUONVDigit*>( FetchObject(iter, index) );
750}
751
752//_____________________________________________________________________________
753Int_t AliMUONMCDataInterface::NumberOfDigits(Int_t detElemId)
754{
755/// Returns the number of simulated digits to be found on a given detector element.
756/// @param detElemId The detector element ID number to search on.
757
758 TIterator* iter = GetIterator(kDigitIteratorByDetectorElement, detElemId);
759 return CountObjects(iter);
760}
761
762//_____________________________________________________________________________
763AliMUONVDigit* AliMUONMCDataInterface::Digit(Int_t detElemId, Int_t index)
764{
765/// Returns the a pointer to the index'th simulated digit on the specified detector element.
766/// @param detElemId The detector element ID number to search on.
767/// @param index The index number of the digit to fetch in the range [0 .. N-1],
768/// where N = NumberOfDigits(detElemId)
769
770 TIterator* iter = GetIterator(kDigitIteratorByDetectorElement, detElemId);
771 return static_cast<AliMUONVDigit*>( FetchObject(iter, index) );
772}
773
774//_____________________________________________________________________________
775Int_t AliMUONMCDataInterface::NumberOfDigits(Int_t chamber, Int_t cathode)
776{
777/// Returns the number of simulated digits to be found on a specific chamber and cathode.
778/// @param chamber The chamber number in the range [0 .. 13].
779/// @param cathode The cathode in the range [0 .. 1], where 0 is the bending and
780/// 1 is the non-bending plane.
781
782 TIterator* iter = GetIterator(kDigitIteratorByChamberAndCathode, chamber, cathode);
783 return CountObjects(iter);
784}
785
786//_____________________________________________________________________________
787AliMUONVDigit* AliMUONMCDataInterface::Digit(Int_t chamber, Int_t cathode, Int_t index)
788{
789/// Returns the a pointer to the index'th simulated digit on the specified chamber and cathode.
790/// @param chamber The chamber number in the range [0 .. 13].
791/// @param cathode The cathode in the range [0 .. 1], where 0 is the bending and
792/// 1 is the non-bending plane.
793/// @param index The index number of the digit to fetch in the range [0 .. N-1],
794/// where N = NumberOfDigits(chamber, cathode)
795
796 TIterator* iter = GetIterator(kDigitIteratorByChamberAndCathode, chamber, cathode);
797 return static_cast<AliMUONVDigit*>( FetchObject(iter, index) );
798}
799
800//_____________________________________________________________________________
801Int_t AliMUONMCDataInterface::NumberOfLocalTriggers()
802{
803/// Returns the number of simulated local trigger objects.
804
805 TIterator* iter = GetIterator(kLocalTriggerIterator);
806 return CountObjects(iter);
807}
808
809//_____________________________________________________________________________
810AliMUONLocalTrigger* AliMUONMCDataInterface::LocalTrigger(Int_t index)
811{
812/// Returns a pointer to the index'th simulated local trigger object.
813/// @param index The index number of the local trigger object to fetch in the range [0 .. N-1],
814/// where N = NumberOfLocalTriggers()
815
816 TIterator* iter = GetIterator(kLocalTriggerIterator);
817 return static_cast<AliMUONLocalTrigger*>( FetchObject(iter, index) );
818}
819
820//_____________________________________________________________________________
821Int_t AliMUONMCDataInterface::NumberOfRegionalTriggers()
822{
823/// Returns the number of simulated regional trigger objects.
824
825 TIterator* iter = GetIterator(kRegionalTriggerIterator);
826 return CountObjects(iter);
827}
828
829//_____________________________________________________________________________
830AliMUONRegionalTrigger* AliMUONMCDataInterface::RegionalTrigger(Int_t index)
831{
832/// Returns a pointer to the index'th simulated regional trigger object.
833/// @param index The index number of the regional trigger object to fetch in the range [0 .. N-1],
834/// where N = NumberOfRegionalTriggers()
835
836 TIterator* iter = GetIterator(kRegionalTriggerIterator);
837 return static_cast<AliMUONRegionalTrigger*>( FetchObject(iter, index) );
838}
839
840//_____________________________________________________________________________
841AliMUONGlobalTrigger* AliMUONMCDataInterface::GlobalTrigger()
842{
843/// Returns a pointer to the simulated global trigger object for the event.
844
845 AliMUONVTriggerStore* store = TriggerStore(fCurrentEvent);
846 if (store == 0x0) return 0x0;
847 return store->Global();
848}
849
850//_____________________________________________________________________________
851Int_t AliMUONMCDataInterface::NumberOfTrackRefs()
852{
853/// Number of track references in the currently selected event.
854
855 return NumberOfTrackRefs(fCurrentEvent);
856}
857
858//_____________________________________________________________________________
859TClonesArray* AliMUONMCDataInterface::TrackRefs(Int_t track)
860{
861/// Returns the track references for a given track in the current event.
862/// @param track The track to returns track references for. In the range [0 .. N-1]
863/// where N = NumberOfTrackRefs()
864
865 return TrackRefs(fCurrentEvent, track);
866}
867
868//_____________________________________________________________________________
869void AliMUONMCDataInterface::ResetStores()
870{
871/// Deletes all the store objects that have been created and resets the pointers to 0x0.
872/// The temporary iterator object is automatically reset. See ResetIterator for more details.
873
874 ResetIterator();
875 if (fHitStore != 0x0)
e9bef706 876 {
e8636ba0 877 delete fHitStore;
878 fHitStore = 0x0;
e9bef706 879 }
e8636ba0 880 if (fSDigitStore != 0x0)
881 {
882 delete fSDigitStore;
883 fSDigitStore = 0x0;
884 }
885 if (fDigitStore != 0x0)
886 {
887 delete fDigitStore;
888 fDigitStore = 0x0;
889 }
890 if (fTrackRefs != 0x0)
e9bef706 891 {
e8636ba0 892 delete fTrackRefs;
893 fTrackRefs = 0x0;
e9bef706 894 }
e8636ba0 895 if (fTriggerStore != 0x0)
896 {
897 delete fTriggerStore;
898 fTriggerStore = 0x0;
899 }
900}
901
902//_____________________________________________________________________________
903TIterator* AliMUONMCDataInterface::GetIterator(IteratorType type, Int_t x, Int_t y)
904{
905/// Creates an appropriate iterator object and returns it.
906/// If the iterator has already been created then that one is returned otherwise
907/// a new object is created.
908/// Depending on the value of 'type' the semantics of parameters x and y can change.
909/// @param type The type of iterator to create.
910/// @param x This is the detector element ID if type equals kDigitIteratorByDetectorElement
911/// or kSDigitIteratorByDetectorElement.
912/// If type equals kDigitIteratorByChamberAndCathode or
913/// kSDigitIteratorByChamberAndCathode then this is the chamber number.
914/// For type == kHitIterator the parameter x is the track number.
915/// In all other cases this parameter is ignored.
916/// @param y If type equals kDigitIteratorByChamberAndCathode or
917/// kSDigitIteratorByChamberAndCathode then this parameter is the cathode
918/// number. In all other cases this parameter is ignored.
919
920 if (type == fCurrentIteratorType and fDataX == x and fDataY == y)
921 return fIterator;
e9bef706 922
e8636ba0 923 if (fCurrentEvent == -1)
e9bef706 924 {
e8636ba0 925 AliError("No event was selected. Try first using GetEvent().");
926 return 0x0;
e9bef706 927 }
928
e8636ba0 929 ResetIterator();
e9bef706 930
e8636ba0 931 switch (type)
932 {
933 case kHitIterator:
934 {
935 Int_t track = x;
936 AliMUONVHitStore* store = HitStore(fCurrentEvent, track);
937 if (store == 0x0) return 0x0;
938 fIterator = store->CreateIterator();
939 if (fIterator == 0x0) return 0x0;
940 fCurrentIteratorType = kHitIterator;
941 return fIterator;
942 }
943
944 case kSDigitIteratorByDetectorElement:
945 {
946 Int_t detElem = x;
947 AliMUONVDigitStore* store = SDigitStore(fCurrentEvent);
948 if (store == 0x0) return 0x0;
e8636ba0 949 fIterator = store->CreateIterator(detElem, detElem, 2);
950 if (fIterator == 0x0) return 0x0;
951 fCurrentIteratorType = kSDigitIteratorByDetectorElement;
952 fDataX = detElem;
953 return fIterator;
954 }
955
956 case kSDigitIteratorByChamberAndCathode:
957 {
958 Int_t chamber = x;
959 Int_t cathode = y;
960 if (chamber < 0 or AliMpConstants::NofChambers() <= chamber)
961 {
962 AliError(Form(
963 "Must have give a chamber value in the range [0..%d], but got a value of: %d",
964 AliMpConstants::NofChambers() - 1,
965 chamber
966 ));
967 return 0x0;
968 }
969 if (cathode < 0 or 1 < cathode)
970 {
971 AliError(Form("Must have give a cathode value in the range [0..1], but got a value of: %d", cathode));
972 return 0x0;
973 }
974
975 AliMUONVDigitStore* store = SDigitStore(fCurrentEvent);
976 if (store == 0x0) return 0x0;
e8636ba0 977 AliMpIntPair pair = AliMpDEManager::GetDetElemIdRange(chamber);
978 fIterator = store->CreateIterator(pair.GetFirst(), pair.GetSecond(), cathode);
979 if (fIterator == 0x0) return 0x0;
980 fCurrentIteratorType = kSDigitIteratorByChamberAndCathode;
981 fDataX = chamber;
982 fDataY = cathode;
983 return fIterator;
984 }
985
986 case kDigitIteratorByDetectorElement:
987 {
988 Int_t detElem = x;
989 AliMUONVDigitStore* store = DigitStore(fCurrentEvent);
990 if (store == 0x0) return 0x0;
e8636ba0 991 fIterator = store->CreateIterator(detElem, detElem, 2);
992 if (fIterator == 0x0) return 0x0;
993 fCurrentIteratorType = kDigitIteratorByDetectorElement;
994 fDataX = detElem;
995 return fIterator;
996 }
997
998 case kDigitIteratorByChamberAndCathode:
999 {
1000 Int_t chamber = x;
1001 Int_t cathode = y;
1002 if (chamber < 0 or AliMpConstants::NofChambers() <= chamber)
1003 {
1004 AliError(Form(
1005 "Must have give a chamber value in the range [0..%d], but got a value of: %d",
1006 AliMpConstants::NofChambers() - 1,
1007 chamber
1008 ));
1009 return 0x0;
1010 }
1011 if (cathode < 0 or 1 < cathode)
1012 {
1013 AliError(Form("Must have give a cathode value in the range [0..1], but got a value of: %d", cathode));
1014 return 0x0;
1015 }
1016
1017 AliMUONVDigitStore* store = DigitStore(fCurrentEvent);
1018 if (store == 0x0) return 0x0;
e8636ba0 1019 AliMpIntPair pair = AliMpDEManager::GetDetElemIdRange(chamber);
1020 fIterator = store->CreateIterator(pair.GetFirst(), pair.GetSecond(), cathode);
1021 if (fIterator == 0x0) return 0x0;
1022 fCurrentIteratorType = kDigitIteratorByChamberAndCathode;
1023 fDataX = chamber;
1024 fDataY = cathode;
1025 return fIterator;
1026 }
1027
1028 case kLocalTriggerIterator:
1029 {
1030 AliMUONVTriggerStore* store = TriggerStore(fCurrentEvent);
1031 if (store == 0x0) return 0x0;
1032 fIterator = store->CreateLocalIterator();
1033 if (fIterator == 0x0) return 0x0;
1034 fCurrentIteratorType = kLocalTriggerIterator;
1035 return fIterator;
1036 }
1037
1038 case kRegionalTriggerIterator:
1039 {
1040 AliMUONVTriggerStore* store = TriggerStore(fCurrentEvent);
1041 if (store == 0x0) return 0x0;
1042 fIterator = store->CreateRegionalIterator();
1043 if (fIterator == 0x0) return 0x0;
1044 fCurrentIteratorType = kRegionalTriggerIterator;
1045 return fIterator;
1046 }
1047
1048 default:
1049 return 0x0;
1050 }
e9bef706 1051}
1052
1053//_____________________________________________________________________________
e8636ba0 1054void AliMUONMCDataInterface::ResetIterator()
1df4a03e 1055{
e8636ba0 1056/// The temporary iterator object is deleted if it exists and the pointer reset to 0x0.
1057/// The iterator type and temporary data indicating the state of the iterator are
1058/// also reset.
1df4a03e 1059
e8636ba0 1060 if (fIterator != 0x0) delete fIterator;
1061 fCurrentIteratorType = kNoIterator;
1062 fCurrentIndex = fDataX = fDataY = -1;
1063 fIterator = 0x0;
1df4a03e 1064}
1065
1066//_____________________________________________________________________________
e8636ba0 1067Int_t AliMUONMCDataInterface::CountObjects(TIterator* iter)
1df4a03e 1068{
e8636ba0 1069/// Counts the number of objects in the iterator and resets it.
1070/// @return The number of objects in 'iter'.
e9bef706 1071
e8636ba0 1072 if (iter == 0x0) return -1;
1073 Int_t count = 0;
1074 iter->Reset();
1075 while ( iter->Next() != 0x0 ) count++;
1076 iter->Reset();
1077 fCurrentIndex = -1;
1078 return count;
e9bef706 1079}
1080
1081//_____________________________________________________________________________
e8636ba0 1082TObject* AliMUONMCDataInterface::FetchObject(TIterator* iter, Int_t index)
e9bef706 1083{
e8636ba0 1084/// Fetches the index'th object from the iterator counting the first object
1085/// returned by iterator after it is reset as index == 0. The next object
1086/// has index == 1 and so on where the last object returned by the iterator
1087/// has index == N-1 where N = CountObjects(iter)
1088/// This method will only reset the iterator if index is smaller than
1089/// fCurrentIndex, which is used to track the iteration progress and is
1090/// updated when a new object if returned by this method.
1091/// @param iter The iterator to fetch an object from.
1092/// @param index The index number of the object to fetch in the range [0 .. N-1]
1093/// where N = CountObjects(iter)
1094
1095 if (index < 0)
e9bef706 1096 {
e8636ba0 1097 AliError(Form("Index is out of bounds. Got a value of %d.", index));
e9bef706 1098 return 0x0;
1099 }
e8636ba0 1100
1101 if (iter == 0x0) return 0x0;
1102 if (index <= fCurrentIndex)
e9bef706 1103 {
e8636ba0 1104 iter->Reset();
1105 fCurrentIndex = -1;
e9bef706 1106 }
1107
e8636ba0 1108 TObject* object = 0x0;
1109 while (fCurrentIndex < index)
e9bef706 1110 {
e8636ba0 1111 object = iter->Next();
1112 if (object == 0x0)
1113 {
1114 AliError(Form("Index is out of bounds. Got a value of %d.", index));
1115 iter->Reset();
1116 fCurrentIndex = -1;
1117 return 0x0;
1118 }
1119 fCurrentIndex++;
e9bef706 1120 }
e8636ba0 1121 return object;
1df4a03e 1122}