Line data Source code
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 :
18 : //-----------------------------------------------------------------------------
19 : /// \class AliMUONMCDataInterface
20 : ///
21 : /// Easy to use MC data accessor
22 : ///
23 : /// \author Laurent Aphecetche, Subatech
24 : ///
25 : // Moved parts of old AliMUONDataInterface interface to AliMUONMCDataInterface
26 : // Artur Szostak <artursz@iafrica.com> (University of Cape Town)
27 : //-----------------------------------------------------------------------------
28 :
29 : #include "AliMUONMCDataInterface.h"
30 : #include "AliMUONVDigitStore.h"
31 : #include "AliMUONVHitStore.h"
32 : #include "AliMUONVTriggerStore.h"
33 : #include "AliMUONHit.h"
34 : #include "AliMUONVDigit.h"
35 : #include "AliMUONLocalTrigger.h"
36 : #include "AliMUONRegionalTrigger.h"
37 : #include "AliMUONGlobalTrigger.h"
38 :
39 : #include "AliMpEncodePair.h"
40 : #include "AliMpDEManager.h"
41 : #include "AliMpConstants.h"
42 : #include "AliMpCDB.h"
43 :
44 : #include "AliLog.h"
45 : #include "AliLoader.h"
46 : #include "AliRunLoader.h"
47 : #include "AliHeader.h"
48 : #include "AliStack.h"
49 : #include "AliCDBManager.h"
50 :
51 : #include <TTree.h>
52 : #include <Riostream.h>
53 : #include <TClonesArray.h>
54 : #include <TList.h>
55 : #include <TParticle.h>
56 : #include <TIterator.h>
57 : #include <cstdlib>
58 : #include <cassert>
59 :
60 : using std::endl;
61 : using std::cout;
62 : /// \cond CLASSIMP
63 16 : ClassImp(AliMUONMCDataInterface)
64 : /// \endcond
65 :
66 : Int_t AliMUONMCDataInterface::fgInstanceCounter(0);
67 :
68 : //_____________________________________________________________________________
69 : AliMUONMCDataInterface::AliMUONMCDataInterface(const char* filename) :
70 0 : TObject(),
71 0 : fLoader(0x0),
72 0 : fHitStore(0x0),
73 0 : fSDigitStore(0x0),
74 0 : fDigitStore(0x0),
75 0 : fTriggerStore(0x0),
76 0 : fTrackRefs(0x0),
77 0 : fCurrentEvent(-1),
78 0 : fIsValid(kFALSE),
79 0 : fCurrentIteratorType(kNoIterator),
80 0 : fCurrentIndex(-1),
81 0 : fDataX(-1),
82 0 : fDataY(-1),
83 0 : fIterator(0x0)
84 0 : {
85 : /// ctor
86 :
87 0 : ++fgInstanceCounter;
88 :
89 0 : if ( AliCDBManager::Instance() != NULL &&
90 0 : AliCDBManager::Instance()->GetDefaultStorage() == NULL ) {
91 0 : AliFatal("CDB default storage not defined.");
92 : }
93 :
94 0 : Open(filename);
95 :
96 : // Load mapping
97 0 : if ( ! AliMpCDB::LoadMpSegmentation() ) {
98 0 : AliFatal("Could not access mapping from OCDB !");
99 : }
100 0 : }
101 :
102 : //_____________________________________________________________________________
103 : AliMUONMCDataInterface::~AliMUONMCDataInterface()
104 0 : {
105 : /// dtor
106 0 : --fgInstanceCounter;
107 0 : }
108 :
109 : //_____________________________________________________________________________
110 : AliMUONVHitStore*
111 : AliMUONMCDataInterface::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 : /// \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.
122 :
123 0 : if (not IsValid()) return 0x0;
124 :
125 0 : if (event == fCurrentEvent)
126 : {
127 0 : if (track == fDataX and fHitStore != 0x0) // using fDataX as track number.
128 0 : return fHitStore;
129 : }
130 : else
131 : {
132 0 : ResetStores();
133 0 : if ( not LoadEvent(event) ) return 0x0;
134 : }
135 :
136 0 : fLoader->LoadHits();
137 :
138 0 : TTree* treeH = fLoader->TreeH();
139 0 : if (treeH == 0x0)
140 : {
141 0 : AliError("Could not get treeH");
142 0 : return 0x0;
143 : }
144 :
145 0 : fHitStore = AliMUONVHitStore::Create(*treeH);
146 0 : AliDebug(1,"Creating hitStore from treeH");
147 0 : if ( fHitStore != 0x0 )
148 : {
149 0 : fHitStore->Connect(*treeH);
150 0 : if ( treeH->GetEvent(track) == 0 )
151 : {
152 0 : AliError(Form("Could not read track %d",track));
153 0 : fHitStore->Clear();
154 0 : return 0x0;
155 : }
156 0 : fDataX = track; // using fDataX as track number.
157 0 : }
158 :
159 0 : fLoader->UnloadHits();
160 :
161 0 : return fHitStore;
162 0 : }
163 :
164 : //_____________________________________________________________________________
165 : AliMUONVDigitStore*
166 : AliMUONMCDataInterface::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
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.
177 :
178 0 : if (not IsValid()) return 0x0;
179 :
180 0 : if (event == fCurrentEvent)
181 : {
182 0 : if (fSDigitStore != 0x0)
183 0 : return fSDigitStore;
184 : }
185 : else
186 : {
187 0 : ResetStores();
188 0 : if ( not LoadEvent(event) ) return 0x0;
189 : }
190 :
191 0 : fLoader->LoadSDigits();
192 :
193 0 : TTree* treeS = fLoader->TreeS();
194 0 : if (treeS == 0x0)
195 : {
196 0 : AliError("Could not get treeS");
197 0 : return 0x0;
198 : }
199 :
200 0 : fSDigitStore = AliMUONVDigitStore::Create(*treeS);
201 0 : if ( fSDigitStore != 0x0 )
202 : {
203 0 : fSDigitStore->Clear();
204 0 : fSDigitStore->Connect(*treeS);
205 0 : treeS->GetEvent(0);
206 0 : }
207 :
208 0 : fLoader->UnloadSDigits();
209 :
210 0 : return fSDigitStore;
211 0 : }
212 :
213 : //_____________________________________________________________________________
214 : AliMUONVDigitStore*
215 : AliMUONMCDataInterface::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
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.
225 :
226 0 : if (not IsValid()) return 0x0;
227 :
228 0 : if (event == fCurrentEvent)
229 : {
230 0 : if (fDigitStore != 0x0)
231 0 : return fDigitStore;
232 : }
233 : else
234 : {
235 0 : ResetStores();
236 0 : if ( not LoadEvent(event) ) return 0x0;
237 : }
238 :
239 0 : fLoader->LoadDigits();
240 :
241 0 : TTree* treeD = fLoader->TreeD();
242 0 : if (treeD == 0x0)
243 : {
244 0 : AliError("Could not get treeD");
245 0 : return 0x0;
246 : }
247 :
248 0 : fDigitStore = AliMUONVDigitStore::Create(*treeD);
249 0 : if ( fDigitStore != 0x0 )
250 : {
251 0 : fDigitStore->Clear();
252 0 : fDigitStore->Connect(*treeD);
253 0 : treeD->GetEvent(0);
254 0 : }
255 :
256 0 : fLoader->UnloadDigits();
257 :
258 0 : return fDigitStore;
259 0 : }
260 :
261 : //_____________________________________________________________________________
262 : AliStack*
263 : AliMUONMCDataInterface::Stack(Int_t event)
264 : {
265 : /// Get the Stack (list of generated particles) for one event
266 : /// Returned pointer should not be deleted
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.
273 :
274 0 : if ( not IsValid() ) return 0x0;
275 :
276 0 : if (event != fCurrentEvent)
277 : {
278 0 : ResetStores();
279 0 : if ( not LoadEvent(event) ) return 0x0;
280 : }
281 :
282 0 : fLoader->GetRunLoader()->LoadKinematics();
283 :
284 0 : return fLoader->GetRunLoader()->Stack();
285 0 : }
286 :
287 : //_____________________________________________________________________________
288 : TClonesArray*
289 : AliMUONMCDataInterface::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
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.
299 :
300 0 : if ( not IsValid() ) return 0x0;
301 :
302 0 : if (event == fCurrentEvent)
303 : {
304 0 : if (track == fDataX and fTrackRefs != 0x0) // using fDataX as track number.
305 0 : return fTrackRefs;
306 : }
307 : else
308 : {
309 0 : ResetStores();
310 0 : if ( not LoadEvent(event) ) return 0x0;
311 : }
312 :
313 0 : fLoader->GetRunLoader()->LoadTrackRefs();
314 :
315 0 : TTree* treeTR = fLoader->GetRunLoader()->TreeTR();
316 :
317 0 : if ( fTrackRefs != 0x0 ) fTrackRefs->Clear("C");
318 :
319 0 : if (treeTR != 0x0)
320 : {
321 0 : if ( treeTR->GetEvent(track) > 0 )
322 : {
323 0 : TBranch* branch = treeTR->GetBranch("TrackReferences");
324 0 : branch->SetAddress(&fTrackRefs);
325 0 : branch->GetEvent(track);
326 0 : fDataX = track; // using fDataX as track number.
327 0 : }
328 : }
329 : else
330 : {
331 0 : AliError("Could not get TreeTR");
332 : }
333 :
334 0 : fLoader->GetRunLoader()->UnloadTrackRefs();
335 :
336 0 : return fTrackRefs;
337 0 : }
338 :
339 : //_____________________________________________________________________________
340 : AliMUONVTriggerStore*
341 : AliMUONMCDataInterface::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.
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.
352 :
353 0 : if (not IsValid()) return 0x0;
354 :
355 0 : if (event == fCurrentEvent)
356 : {
357 0 : if (fTriggerStore != 0x0)
358 0 : return fTriggerStore;
359 : }
360 : else
361 : {
362 0 : ResetStores();
363 0 : if ( not LoadEvent(event) ) return 0x0;
364 : }
365 :
366 0 : fLoader->LoadDigits();
367 :
368 0 : TTree* treeD = fLoader->TreeD();
369 0 : if ( treeD == 0x0 )
370 : {
371 0 : AliError("Could not get treeD");
372 0 : return 0x0;
373 : }
374 :
375 0 : fTriggerStore = AliMUONVTriggerStore::Create(*treeD);
376 0 : if ( fTriggerStore != 0x0 )
377 : {
378 0 : fTriggerStore->Clear();
379 0 : fTriggerStore->Connect(*treeD);
380 0 : treeD->GetEvent(0);
381 0 : }
382 :
383 0 : fLoader->UnloadDigits();
384 :
385 0 : return fTriggerStore;
386 0 : }
387 :
388 : //_____________________________________________________________________________
389 : void
390 : AliMUONMCDataInterface::DumpDigits(Int_t event, Bool_t sorted)
391 : {
392 : /// Dump the digits for a given event, sorted if requested.
393 0 : DigitStore(event);
394 :
395 0 : if ( fDigitStore != 0x0 )
396 : {
397 0 : if ( sorted )
398 : {
399 0 : DumpSorted(*fDigitStore);
400 0 : }
401 : else
402 : {
403 0 : fDigitStore->Print();
404 : }
405 : }
406 0 : }
407 :
408 : //_____________________________________________________________________________
409 : void
410 : AliMUONMCDataInterface::DumpHits(Int_t event)
411 : {
412 : /// Dump all the hits for one event
413 :
414 0 : Int_t ntracks = NumberOfTracks(event);
415 :
416 0 : for ( Int_t i = 0; i < ntracks; ++i )
417 : {
418 0 : cout << ">> Track " << i << endl;
419 0 : HitStore(event,i);
420 0 : if ( fHitStore )
421 : {
422 0 : fHitStore->Print("","full");
423 0 : }
424 : }
425 0 : }
426 :
427 : //_____________________________________________________________________________
428 : void
429 : AliMUONMCDataInterface::DumpKine(Int_t event)
430 : {
431 : /// Dump all generated particles for one event
432 0 : AliStack* stack = Stack(event);
433 :
434 0 : if ( stack != 0x0 )
435 : {
436 0 : Int_t nparticles = (Int_t) stack->GetNtrack();
437 :
438 0 : for (Int_t iparticle=0; iparticle<nparticles; ++iparticle)
439 : {
440 0 : stack->Particle(iparticle)->Print("");
441 : }
442 0 : }
443 : else
444 : {
445 0 : AliError("Could not get stack");
446 : }
447 0 : }
448 :
449 : //_____________________________________________________________________________
450 : void
451 : AliMUONMCDataInterface::DumpSDigits(Int_t event, Bool_t sorted)
452 : {
453 : /// Dump the SDigits for a given event, sorted if requested
454 0 : SDigitStore(event);
455 :
456 0 : if ( fSDigitStore != 0x0 )
457 : {
458 0 : if ( sorted )
459 : {
460 0 : DumpSorted(*fSDigitStore);
461 0 : }
462 : else
463 : {
464 0 : fSDigitStore->Print();
465 : }
466 : }
467 0 : }
468 :
469 : //_____________________________________________________________________________
470 : void
471 : AliMUONMCDataInterface::DumpSorted(const AliMUONVStore& store) const
472 : {
473 : /// Dump the given store in sorted order
474 :
475 0 : TIter next(store.CreateIterator());
476 : TObject* object;
477 0 : TList list;
478 0 : list.SetOwner(kFALSE);
479 :
480 0 : while ( ( object = next() ) )
481 : {
482 0 : list.Add(object);
483 : }
484 :
485 0 : list.Sort();
486 :
487 0 : list.Print();
488 0 : }
489 :
490 : //_____________________________________________________________________________
491 : void
492 : AliMUONMCDataInterface::DumpTrackRefs(Int_t event)
493 : {
494 : /// Dump track references for one event
495 0 : Int_t ntrackrefs = NumberOfTrackRefs(event);
496 :
497 0 : for ( Int_t i = 0; i < ntrackrefs; ++i )
498 : {
499 0 : TrackRefs(event,i);
500 0 : if ( fTrackRefs != 0x0 )
501 : {
502 0 : fTrackRefs->Print("","*");
503 0 : }
504 : }
505 0 : }
506 :
507 : //_____________________________________________________________________________
508 : void
509 : AliMUONMCDataInterface::DumpTrigger(Int_t event)
510 : {
511 : /// Dump trigger for a given event (trigger is read from TreeD)
512 :
513 0 : TriggerStore(event);
514 :
515 0 : if ( fTriggerStore != 0x0 )
516 : {
517 0 : fTriggerStore->Print();
518 0 : }
519 0 : }
520 :
521 : //_____________________________________________________________________________
522 : Bool_t
523 : AliMUONMCDataInterface::LoadEvent(Int_t event)
524 : {
525 : /// Load event if different from the current one.
526 : /// Returns kFALSE on error and kTRUE if the event was loaded.
527 :
528 0 : assert( IsValid() );
529 :
530 0 : AliDebug(1,Form("Loading event %d using runLoader %p",event,fLoader->GetRunLoader()));
531 0 : if (fLoader->GetRunLoader()->GetEvent(event) == 0)
532 : {
533 0 : fCurrentEvent = event;
534 0 : return kTRUE;
535 : }
536 : else
537 0 : return kFALSE;
538 0 : }
539 :
540 :
541 : //_____________________________________________________________________________
542 : Int_t
543 : AliMUONMCDataInterface::NumberOfEvents() const
544 : {
545 : /// Number of events in the file we're connected to
546 0 : if (not IsValid()) return -1;
547 0 : return fLoader->GetRunLoader()->GetNumberOfEvents();
548 0 : }
549 :
550 : //_____________________________________________________________________________
551 : Int_t
552 : AliMUONMCDataInterface::NumberOfTracks(Int_t event)
553 : {
554 : /// Number of tracks in the event
555 0 : if ( not IsValid()) return -1;
556 :
557 0 : if (event != fCurrentEvent)
558 : {
559 0 : ResetStores();
560 0 : if ( not LoadEvent(event) ) return -1;
561 : }
562 :
563 0 : fLoader->LoadHits();
564 :
565 : Int_t rv(-1);
566 :
567 0 : TTree* treeH = fLoader->TreeH();
568 0 : if (treeH != 0x0)
569 : {
570 0 : rv = static_cast<Int_t>(treeH->GetEntries());
571 0 : }
572 : else
573 : {
574 0 : AliError("Could not get TreeH");
575 : }
576 :
577 0 : fLoader->UnloadHits();
578 :
579 : return rv;
580 0 : }
581 :
582 : //_____________________________________________________________________________
583 : Int_t
584 : AliMUONMCDataInterface::NumberOfTrackRefs(Int_t event)
585 : {
586 : /// Number of track references in the event
587 0 : if ( not IsValid()) return -1;
588 :
589 0 : if (event != fCurrentEvent)
590 : {
591 0 : ResetStores();
592 0 : if ( not LoadEvent(event) ) return -1;
593 : }
594 :
595 0 : fLoader->GetRunLoader()->LoadTrackRefs();
596 :
597 : Int_t rv(-1);
598 :
599 0 : TTree* treeTR = fLoader->GetRunLoader()->TreeTR();
600 0 : if (treeTR != 0x0)
601 : {
602 0 : rv = static_cast<Int_t>(treeTR->GetEntries());
603 0 : }
604 : else
605 : {
606 0 : AliError("Could not get TreeTR");
607 : }
608 :
609 0 : fLoader->GetRunLoader()->UnloadTrackRefs();
610 :
611 : return rv;
612 0 : }
613 :
614 : //_____________________________________________________________________________
615 : void
616 : AliMUONMCDataInterface::Open(const char* filename)
617 : {
618 : /// Connect to a given galice.root file
619 :
620 0 : ResetStores();
621 :
622 0 : fCurrentEvent=-1;
623 :
624 0 : if ( fLoader != 0x0 )
625 : {
626 0 : delete fLoader->GetRunLoader();
627 : }
628 :
629 0 : fLoader = 0x0;
630 :
631 0 : fIsValid = kTRUE;
632 :
633 0 : TString foldername(Form("%s-%d",ClassName(),fgInstanceCounter));
634 :
635 0 : while (AliRunLoader::GetRunLoader(foldername))
636 : {
637 0 : delete AliRunLoader::GetRunLoader(foldername);
638 : }
639 :
640 0 : AliRunLoader* runLoader = AliRunLoader::Open(filename,foldername);
641 0 : if (runLoader == 0x0)
642 : {
643 0 : AliError(Form("Cannot open file %s",filename));
644 0 : fIsValid = kFALSE;
645 0 : return;
646 : }
647 :
648 : // Get run number and set it to CDB manager
649 0 : runLoader->LoadHeader();
650 0 : if ( ! runLoader->GetHeader() ) {
651 0 : AliError("Cannot load header.");
652 0 : fIsValid = kFALSE;
653 0 : }
654 : else {
655 0 : Int_t runNumber = runLoader->GetHeader()->GetRun();
656 0 : AliCDBManager::Instance()->SetRun(runNumber);
657 : }
658 0 : runLoader->UnloadHeader();
659 :
660 0 : fLoader = runLoader->GetDetectorLoader("MUON");
661 0 : if (fLoader == 0x0)
662 : {
663 0 : AliError("Cannot get AliMUONLoader");
664 0 : fIsValid = kFALSE;
665 0 : }
666 :
667 0 : if (not IsValid())
668 : {
669 0 : AliError(Form("Could not access %s filename. Object is unuseable",filename));
670 : }
671 0 : }
672 :
673 : //_____________________________________________________________________________
674 : Bool_t AliMUONMCDataInterface::GetEvent(Int_t event)
675 : {
676 : /// Loads all simulated data for the given event.
677 :
678 0 : if (HitStore(event, 0) == 0x0) return kFALSE;
679 0 : if (SDigitStore(event) == 0x0) return kFALSE;
680 0 : if (DigitStore(event) == 0x0) return kFALSE;
681 0 : if (TriggerStore(event) == 0x0) return kFALSE;
682 0 : if (TrackRefs(event, 0) == 0x0) return kFALSE;
683 0 : return kTRUE;
684 0 : }
685 :
686 : //_____________________________________________________________________________
687 : Int_t AliMUONMCDataInterface::NumberOfParticles()
688 : {
689 : /// Returns the total number of particles in the kinematics tree.
690 :
691 0 : AliStack* stack = Stack(fCurrentEvent);
692 0 : if ( stack == 0x0 ) return -1;
693 0 : return (Int_t) stack->GetNtrack();
694 0 : }
695 :
696 : //_____________________________________________________________________________
697 : TParticle* 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 0 : AliStack* stack = Stack(fCurrentEvent);
704 0 : if ( stack == 0x0 ) return 0x0;
705 0 : return static_cast<TParticle*>( stack->Particle(index) );
706 0 : }
707 :
708 : //_____________________________________________________________________________
709 : Int_t AliMUONMCDataInterface::NumberOfTracks()
710 : {
711 : /// Returns the number of primary tracks (from primary particles) in the current event.
712 :
713 0 : return NumberOfTracks(fCurrentEvent);
714 : }
715 :
716 : //_____________________________________________________________________________
717 : Int_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 0 : TIterator* iter = GetIterator(kHitIterator, track);
724 0 : return CountObjects(iter);
725 : }
726 :
727 : //_____________________________________________________________________________
728 : AliMUONHit*
729 : AliMUONMCDataInterface::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 0 : TIterator* iter = GetIterator(kHitIterator, track);
738 0 : return static_cast<AliMUONHit*>( FetchObject(iter, index) );
739 : }
740 :
741 : //_____________________________________________________________________________
742 : Int_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 0 : TIterator* iter = GetIterator(kSDigitIteratorByDetectorElement, detElemId);
748 0 : return CountObjects(iter);
749 : }
750 :
751 : //_____________________________________________________________________________
752 : AliMUONVDigit* 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 0 : TIterator* iter = GetIterator(kSDigitIteratorByDetectorElement, detElemId);
760 0 : return static_cast<AliMUONVDigit*>( FetchObject(iter, index) );
761 : }
762 :
763 : //_____________________________________________________________________________
764 : Int_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 0 : TIterator* iter = GetIterator(kSDigitIteratorByChamberAndCathode, chamber, cathode);
772 0 : return CountObjects(iter);
773 : }
774 :
775 : //_____________________________________________________________________________
776 : AliMUONVDigit* 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 0 : TIterator* iter = GetIterator(kSDigitIteratorByChamberAndCathode, chamber, cathode);
786 0 : return static_cast<AliMUONVDigit*>( FetchObject(iter, index) );
787 : }
788 :
789 : //_____________________________________________________________________________
790 : Int_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 0 : TIterator* iter = GetIterator(kDigitIteratorByDetectorElement, detElemId);
796 0 : return CountObjects(iter);
797 : }
798 :
799 : //_____________________________________________________________________________
800 : AliMUONVDigit* 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 0 : TIterator* iter = GetIterator(kDigitIteratorByDetectorElement, detElemId);
808 0 : return static_cast<AliMUONVDigit*>( FetchObject(iter, index) );
809 : }
810 :
811 : //_____________________________________________________________________________
812 : Int_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 0 : TIterator* iter = GetIterator(kDigitIteratorByChamberAndCathode, chamber, cathode);
820 0 : return CountObjects(iter);
821 : }
822 :
823 : //_____________________________________________________________________________
824 : AliMUONVDigit* 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 0 : TIterator* iter = GetIterator(kDigitIteratorByChamberAndCathode, chamber, cathode);
834 0 : return static_cast<AliMUONVDigit*>( FetchObject(iter, index) );
835 : }
836 :
837 : //_____________________________________________________________________________
838 : Int_t AliMUONMCDataInterface::NumberOfLocalTriggers()
839 : {
840 : /// Returns the number of simulated local trigger objects.
841 :
842 0 : TIterator* iter = GetIterator(kLocalTriggerIterator);
843 0 : return CountObjects(iter);
844 : }
845 :
846 : //_____________________________________________________________________________
847 : AliMUONLocalTrigger* 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 0 : TIterator* iter = GetIterator(kLocalTriggerIterator);
854 0 : return static_cast<AliMUONLocalTrigger*>( FetchObject(iter, index) );
855 : }
856 :
857 : //_____________________________________________________________________________
858 : Int_t AliMUONMCDataInterface::NumberOfRegionalTriggers()
859 : {
860 : /// Returns the number of simulated regional trigger objects.
861 :
862 0 : TIterator* iter = GetIterator(kRegionalTriggerIterator);
863 0 : return CountObjects(iter);
864 : }
865 :
866 : //_____________________________________________________________________________
867 : AliMUONRegionalTrigger* 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 0 : TIterator* iter = GetIterator(kRegionalTriggerIterator);
874 0 : return static_cast<AliMUONRegionalTrigger*>( FetchObject(iter, index) );
875 : }
876 :
877 : //_____________________________________________________________________________
878 : AliMUONGlobalTrigger* AliMUONMCDataInterface::GlobalTrigger()
879 : {
880 : /// Returns a pointer to the simulated global trigger object for the event.
881 :
882 0 : AliMUONVTriggerStore* store = TriggerStore(fCurrentEvent);
883 0 : if (store == 0x0) return 0x0;
884 0 : return store->Global();
885 0 : }
886 :
887 : //_____________________________________________________________________________
888 : Int_t AliMUONMCDataInterface::NumberOfTrackRefs()
889 : {
890 : /// Number of track references in the currently selected event.
891 :
892 0 : return NumberOfTrackRefs(fCurrentEvent);
893 : }
894 :
895 : //_____________________________________________________________________________
896 : TClonesArray* 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 0 : return TrackRefs(fCurrentEvent, track);
903 : }
904 :
905 : //_____________________________________________________________________________
906 : void 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 0 : ResetIterator();
912 0 : if (fHitStore != 0x0)
913 : {
914 0 : delete fHitStore;
915 0 : fHitStore = 0x0;
916 0 : }
917 0 : if (fSDigitStore != 0x0)
918 : {
919 0 : delete fSDigitStore;
920 0 : fSDigitStore = 0x0;
921 0 : }
922 0 : if (fDigitStore != 0x0)
923 : {
924 0 : delete fDigitStore;
925 0 : fDigitStore = 0x0;
926 0 : }
927 0 : if (fTrackRefs != 0x0)
928 : {
929 0 : delete fTrackRefs;
930 0 : fTrackRefs = 0x0;
931 0 : }
932 0 : if (fTriggerStore != 0x0)
933 : {
934 0 : delete fTriggerStore;
935 0 : fTriggerStore = 0x0;
936 0 : }
937 0 : }
938 :
939 : //_____________________________________________________________________________
940 : TIterator* 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 0 : if (type == fCurrentIteratorType and fDataX == x and fDataY == y)
958 0 : return fIterator;
959 :
960 0 : if (fCurrentEvent == -1)
961 : {
962 0 : AliError("No event was selected. Try first using GetEvent().");
963 0 : return 0x0;
964 : }
965 :
966 0 : ResetIterator();
967 :
968 0 : switch (type)
969 : {
970 : case kHitIterator:
971 : {
972 : Int_t track = x;
973 0 : AliMUONVHitStore* store = HitStore(fCurrentEvent, track);
974 0 : if (store == 0x0) return 0x0;
975 0 : fIterator = store->CreateIterator();
976 0 : if (fIterator == 0x0) return 0x0;
977 0 : fCurrentIteratorType = kHitIterator;
978 0 : return fIterator;
979 : }
980 :
981 : case kSDigitIteratorByDetectorElement:
982 : {
983 : Int_t detElem = x;
984 0 : AliMUONVDigitStore* store = SDigitStore(fCurrentEvent);
985 0 : if (store == 0x0) return 0x0;
986 0 : fIterator = store->CreateIterator(detElem, detElem, 2);
987 0 : if (fIterator == 0x0) return 0x0;
988 0 : fCurrentIteratorType = kSDigitIteratorByDetectorElement;
989 0 : fDataX = detElem;
990 0 : return fIterator;
991 : }
992 :
993 : case kSDigitIteratorByChamberAndCathode:
994 : {
995 : Int_t chamber = x;
996 : Int_t cathode = y;
997 0 : if (chamber < 0 or AliMpConstants::NofChambers() <= chamber)
998 : {
999 0 : 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 0 : return 0x0;
1005 : }
1006 0 : if (cathode < 0 or 1 < cathode)
1007 : {
1008 0 : AliError(Form("Must have give a cathode value in the range [0..1], but got a value of: %d", cathode));
1009 0 : return 0x0;
1010 : }
1011 :
1012 0 : AliMUONVDigitStore* store = SDigitStore(fCurrentEvent);
1013 0 : if (store == 0x0) return 0x0;
1014 0 : MpPair_t pair = AliMpDEManager::GetDetElemIdRange(chamber);
1015 0 : fIterator = store->CreateIterator(AliMp::PairFirst(pair), AliMp::PairSecond(pair), cathode);
1016 0 : if (fIterator == 0x0) return 0x0;
1017 0 : fCurrentIteratorType = kSDigitIteratorByChamberAndCathode;
1018 0 : fDataX = chamber;
1019 0 : fDataY = cathode;
1020 0 : return fIterator;
1021 : }
1022 :
1023 : case kDigitIteratorByDetectorElement:
1024 : {
1025 : Int_t detElem = x;
1026 0 : AliMUONVDigitStore* store = DigitStore(fCurrentEvent);
1027 0 : if (store == 0x0) return 0x0;
1028 0 : fIterator = store->CreateIterator(detElem, detElem, 2);
1029 0 : if (fIterator == 0x0) return 0x0;
1030 0 : fCurrentIteratorType = kDigitIteratorByDetectorElement;
1031 0 : fDataX = detElem;
1032 0 : return fIterator;
1033 : }
1034 :
1035 : case kDigitIteratorByChamberAndCathode:
1036 : {
1037 : Int_t chamber = x;
1038 : Int_t cathode = y;
1039 0 : if (chamber < 0 or AliMpConstants::NofChambers() <= chamber)
1040 : {
1041 0 : 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 0 : return 0x0;
1047 : }
1048 0 : if (cathode < 0 or 1 < cathode)
1049 : {
1050 0 : AliError(Form("Must have give a cathode value in the range [0..1], but got a value of: %d", cathode));
1051 0 : return 0x0;
1052 : }
1053 :
1054 0 : AliMUONVDigitStore* store = DigitStore(fCurrentEvent);
1055 0 : if (store == 0x0) return 0x0;
1056 0 : MpPair_t pair = AliMpDEManager::GetDetElemIdRange(chamber);
1057 0 : fIterator = store->CreateIterator(AliMp::PairFirst(pair), AliMp::PairSecond(pair), cathode);
1058 0 : if (fIterator == 0x0) return 0x0;
1059 0 : fCurrentIteratorType = kDigitIteratorByChamberAndCathode;
1060 0 : fDataX = chamber;
1061 0 : fDataY = cathode;
1062 0 : return fIterator;
1063 : }
1064 :
1065 : case kLocalTriggerIterator:
1066 : {
1067 0 : AliMUONVTriggerStore* store = TriggerStore(fCurrentEvent);
1068 0 : if (store == 0x0) return 0x0;
1069 0 : fIterator = store->CreateLocalIterator();
1070 0 : if (fIterator == 0x0) return 0x0;
1071 0 : fCurrentIteratorType = kLocalTriggerIterator;
1072 0 : return fIterator;
1073 : }
1074 :
1075 : case kRegionalTriggerIterator:
1076 : {
1077 0 : AliMUONVTriggerStore* store = TriggerStore(fCurrentEvent);
1078 0 : if (store == 0x0) return 0x0;
1079 0 : fIterator = store->CreateRegionalIterator();
1080 0 : if (fIterator == 0x0) return 0x0;
1081 0 : fCurrentIteratorType = kRegionalTriggerIterator;
1082 0 : return fIterator;
1083 : }
1084 :
1085 : default:
1086 0 : return 0x0;
1087 : }
1088 0 : }
1089 :
1090 : //_____________________________________________________________________________
1091 : void AliMUONMCDataInterface::ResetIterator()
1092 : {
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.
1096 :
1097 0 : if (fIterator != 0x0) delete fIterator;
1098 0 : fCurrentIteratorType = kNoIterator;
1099 0 : fCurrentIndex = fDataX = fDataY = -1;
1100 0 : fIterator = 0x0;
1101 0 : }
1102 :
1103 : //_____________________________________________________________________________
1104 : Int_t AliMUONMCDataInterface::CountObjects(TIterator* iter)
1105 : {
1106 : /// Counts the number of objects in the iterator and resets it.
1107 : /// @return The number of objects in 'iter'.
1108 :
1109 0 : if (iter == 0x0) return -1;
1110 : Int_t count = 0;
1111 0 : iter->Reset();
1112 0 : while ( iter->Next() != 0x0 ) count++;
1113 0 : iter->Reset();
1114 0 : fCurrentIndex = -1;
1115 : return count;
1116 0 : }
1117 :
1118 : //_____________________________________________________________________________
1119 : TObject* AliMUONMCDataInterface::FetchObject(TIterator* iter, Int_t index)
1120 : {
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 0 : if (index < 0)
1133 : {
1134 0 : AliError(Form("Index is out of bounds. Got a value of %d.", index));
1135 0 : return 0x0;
1136 : }
1137 :
1138 0 : if (iter == 0x0) return 0x0;
1139 0 : if (index <= fCurrentIndex)
1140 : {
1141 0 : iter->Reset();
1142 0 : fCurrentIndex = -1;
1143 0 : }
1144 :
1145 : TObject* object = 0x0;
1146 0 : while (fCurrentIndex < index)
1147 : {
1148 0 : object = iter->Next();
1149 0 : if (object == 0x0)
1150 : {
1151 0 : AliError(Form("Index is out of bounds. Got a value of %d.", index));
1152 0 : iter->Reset();
1153 0 : fCurrentIndex = -1;
1154 0 : return 0x0;
1155 : }
1156 0 : fCurrentIndex++;
1157 : }
1158 0 : return object;
1159 0 : }
|