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