]> git.uio.no Git - u/mrichter/AliRoot.git/blame_incremental - MUON/AliMUONDataInterface.cxx
- update track cuts
[u/mrichter/AliRoot.git] / MUON / AliMUONDataInterface.cxx
... / ...
CommitLineData
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#include "AliMUONDataInterface.h"
19#include "AliMUONGeometryTransformer.h"
20#include "AliMUONVDigit.h"
21#include "AliMUONVCluster.h"
22#include "AliMUONLocalTrigger.h"
23#include "AliMUONRegionalTrigger.h"
24#include "AliMUONGlobalTrigger.h"
25#include "AliMUONTriggerCircuit.h"
26#include "AliMUONVClusterStore.h"
27#include "AliMUONVDigitStore.h"
28#include "AliMUONVTriggerStore.h"
29#include "AliMpCDB.h"
30
31#include "AliMpEncodePair.h"
32#include "AliMpDEManager.h"
33#include "AliMpConstants.h"
34#include "AliMpCDB.h"
35
36#include "AliLoader.h"
37#include "AliRunLoader.h"
38#include "AliHeader.h"
39#include "AliCDBManager.h"
40#include "AliLog.h"
41
42#include <Riostream.h>
43#include <TFile.h>
44#include <TList.h>
45#include <TNtuple.h>
46#include <TSystem.h>
47#include <TIterator.h>
48#include <cstdlib>
49#include <cassert>
50
51//-----------------------------------------------------------------------------
52/// \class AliMUONDataInterface
53///
54/// An easy to use interface to the MUON data data stored in
55/// TreeS, TreeD and TreeR.
56///
57/// For MC related information (i.e. TreeH, TreeK, TreeTR), see
58/// AliMUONMCDataInterface.
59///
60///
61/// This interface in not necessarily the fastest way to fetch the data but
62/// it is the easiest.
63///
64/// \author Laurent Aphecetche, Subatech & Artur Szostak <artursz@iafrica.com> (University of Cape Town)
65//-----------------------------------------------------------------------------
66
67/// \cond CLASSIMP
68ClassImp(AliMUONDataInterface)
69/// \endcond
70
71
72Int_t AliMUONDataInterface::fgInstanceCounter(0);
73
74//______________________________________________________________________________
75AliMUONDataInterface::AliMUONDataInterface(const char* filename)
76: TObject(),
77fLoader(0x0),
78fDigitStore(0x0),
79fTriggerStore(0x0),
80fClusterStore(0x0),
81fCurrentEvent(-1),
82fTreeLetter(""),
83fIsValid(kFALSE),
84fCurrentIteratorType(kNoIterator),
85fCurrentIndex(-1),
86fDataX(-1),
87fDataY(-1),
88fIterator(0x0)
89{
90 /// ctor
91 /// @param filename should be the full path to a valid galice.root file
92
93 ++fgInstanceCounter;
94
95 if ( AliCDBManager::Instance() != NULL &&
96 AliCDBManager::Instance()->GetDefaultStorage() == NULL ) {
97 AliFatal("CDB default storage not defined.");
98 }
99
100 Open(filename);
101
102 // Load mapping
103 if ( ! AliMpCDB::LoadDDLStore() ) {
104 AliFatal("Could not access mapping from OCDB !");
105 }
106}
107
108//______________________________________________________________________________
109AliMUONDataInterface::~AliMUONDataInterface()
110{
111 /// dtor
112 ResetStores();
113 --fgInstanceCounter;
114}
115
116//______________________________________________________________________________
117AliMUONVDigitStore*
118AliMUONDataInterface::DigitStore(Int_t event)
119{
120 /// Return digitStore for a given event.
121 /// Return 0x0 if event not found.
122 /// Returned pointer should not be deleted
123 ///
124 /// \note If a previous store has been retrieved by one of the methods of
125 /// this class, but for a different event number, then those stores will
126 /// be deleted and no longer valid.
127 /// If you require access to the data for the earlier retrieved store,
128 /// but for different events, then you should deep copy / clone the object.
129
130 if (not IsValid()) return 0x0;
131
132 if (event == fCurrentEvent)
133 {
134 if (fDigitStore != 0x0)
135 return fDigitStore;
136 }
137 else
138 {
139 ResetStores();
140 if ( not LoadEvent(event) ) return 0x0;
141 }
142
143 fLoader->LoadDigits();
144
145 TTree* treeD = fLoader->TreeD();
146 if (treeD == 0x0)
147 {
148 AliError("Could not get treeD");
149 return 0x0;
150 }
151
152 fDigitStore = AliMUONVDigitStore::Create(*treeD);
153 if ( fDigitStore != 0x0 )
154 {
155 fDigitStore->Clear();
156 fDigitStore->Connect(*treeD);
157 treeD->GetEvent(0);
158 }
159
160 fLoader->UnloadDigits();
161
162 return fDigitStore;
163}
164
165//______________________________________________________________________________
166AliMUONVClusterStore*
167AliMUONDataInterface::ClusterStore(Int_t event)
168{
169 /// Return clusterStore for a given event.
170 /// Return 0x0 if event not found.
171 /// Returned pointer should not be deleted
172 ///
173 /// \note If a previous store has been retrieved by one of the methods of
174 /// this class, but for a different event number, then those stores will
175 /// be deleted and no longer valid.
176 /// If you require access to the data for the earlier retrieved store,
177 /// but for different events, then you should deep copy / clone the object.
178
179 if (not IsValid()) return 0x0;
180
181 if (event == fCurrentEvent)
182 {
183 if (fClusterStore != 0x0)
184 return fClusterStore;
185 }
186 else
187 {
188 ResetStores();
189 if ( not LoadEvent(event) ) return 0x0;
190 }
191
192 fLoader->LoadRecPoints();
193
194 TTree* treeR = fLoader->TreeR();
195 if (treeR == 0x0)
196 {
197 AliError("Could not get treeR");
198 return 0x0;
199 }
200
201 fClusterStore = AliMUONVClusterStore::Create(*treeR);
202 if ( fClusterStore != 0x0 )
203 {
204 fClusterStore->Clear();
205 fClusterStore->Connect(*treeR);
206 treeR->GetEvent(0);
207 }
208
209 fLoader->UnloadRecPoints();
210
211 return fClusterStore;
212}
213
214//_____________________________________________________________________________
215AliMUONVTriggerStore*
216AliMUONDataInterface::TriggerStore(Int_t event, const char* treeLetter)
217{
218 /// Return the triggerStore for a given event.
219 /// Return 0x0 if event not found.
220 /// Returned pointer should not be deleted
221 /// treeLetter can be R or D to tell from which tree to read the information
222 ///
223 /// \note If a previous store has been retrieved by one of the methods of
224 /// this class, but for a different event number, then those stores will
225 /// be deleted and no longer valid.
226 /// If you require access to the data for the earlier retrieved store,
227 /// but for different events, then you should deep copy / clone the object.
228
229 if (not IsValid()) return 0x0;
230
231 if (event == fCurrentEvent)
232 {
233 if (fTreeLetter == treeLetter)
234 {
235 if (fTriggerStore != 0x0)
236 return fTriggerStore;
237 }
238 else
239 {
240 // Reset only the fTriggerStore since the others might still be valid
241 // for the same event.
242 if (fTriggerStore != 0x0)
243 {
244 delete fTriggerStore;
245 fTriggerStore = 0x0;
246 }
247 }
248 }
249 else
250 {
251 // Event has changed so reset all the stores.
252 ResetStores();
253 if ( not LoadEvent(event) ) return 0x0;
254 }
255
256 TTree* tree(0x0);
257
258 TString stree(treeLetter);
259 stree.ToUpper();
260
261 if ( stree == "D" )
262 {
263 fLoader->LoadDigits();
264 tree = fLoader->TreeD();
265 }
266 else if ( stree == "R" )
267 {
268 fLoader->LoadRecPoints();
269 tree = fLoader->TreeR();
270 }
271
272 if ( tree == 0x0 )
273 {
274 AliError(Form("Could not get tree%s",treeLetter));
275 return 0x0;
276 }
277
278 fTriggerStore = AliMUONVTriggerStore::Create(*tree);
279 if ( fTriggerStore != 0x0 )
280 {
281 fTriggerStore->Clear();
282 fTriggerStore->Connect(*tree);
283 tree->GetEvent(0);
284 }
285
286 if ( stree == "D" )
287 {
288 fLoader->UnloadDigits();
289 }
290 else if ( stree == "R" )
291 {
292 fLoader->UnloadRecPoints();
293 }
294 fTreeLetter = stree;
295
296 return fTriggerStore;
297}
298
299//______________________________________________________________________________
300void
301AliMUONDataInterface::DumpDigits(Int_t event, Bool_t sorted)
302{
303 /// Dump the digits for a given event, sorted if so required
304 DigitStore(event);
305 if ( fDigitStore != 0x0 )
306 {
307 if ( sorted )
308 {
309 DumpSorted(*fDigitStore);
310 }
311 else
312 {
313 fDigitStore->Print();
314 }
315 }
316}
317
318//______________________________________________________________________________
319void
320AliMUONDataInterface::DumpRecPoints(Int_t event, Bool_t sorted)
321{
322 /// Dump the recpoints for a given event, sorted if so required
323 ClusterStore(event);
324 if ( fClusterStore != 0x0 )
325 {
326 if ( sorted )
327 {
328 DumpSorted(*fClusterStore);
329 }
330 else
331 {
332 fClusterStore->Print();
333 }
334 }
335}
336
337//_____________________________________________________________________________
338void
339AliMUONDataInterface::DumpSorted(const AliMUONVStore& store) const
340{
341 /// Dump the given store, in sorted order
342
343 TIter next(store.CreateIterator());
344 TObject* object;
345 TList list;
346 list.SetOwner(kFALSE);
347
348 while ( ( object = next() ) )
349 {
350 list.Add(object);
351 }
352
353 list.Sort();
354
355 list.Print();
356}
357
358//_____________________________________________________________________________
359void
360AliMUONDataInterface::DumpTrigger(Int_t event, const char* treeLetter)
361{
362 /// Dump trigger for a given event from a given tree (if event>=0)
363 /// or loop over all events and build a trigger ntuple if event<0
364 /// treeLetter can be R or D to tell from which tree to read the information
365
366 if ( event < 0 )
367 {
368 NtupleTrigger(treeLetter);
369 }
370 else
371 {
372 TriggerStore(event,treeLetter);
373
374 if ( fTriggerStore != 0x0 )
375 {
376 fTriggerStore->Print();
377 }
378 }
379}
380
381//_____________________________________________________________________________
382void
383AliMUONDataInterface::NtupleTrigger(const char* treeLetter)
384{
385 //// Loop over events to build trigger ntuples
386 ///
387
388 TString sTreeLetter(treeLetter);
389 sTreeLetter.ToUpper();
390
391 if ( sTreeLetter != "R" && sTreeLetter != "D" )
392 {
393 AliError(Form("Cannot handle tree%s. Use D or R",treeLetter));
394 return;
395 }
396
397 // book ntuples
398 TNtuple tupleGlo("TgtupleGlo","Global Trigger Ntuple",
399 "ev:slpt:shpt:uplpt:uphpt:lplpt:lplpt");
400 TNtuple tupleLoc("TgtupleLoc","Local Trigger Ntuple",
401 "ev:LoCircuit:LoStripX:LoDev:StripY:LoLpt:LoHpt:y11:y21:x11");
402
403 // initialize counters
404 Int_t sLowpt=0;
405 Int_t sHighpt=0;
406 Int_t uSLowpt=0;
407 Int_t uSHighpt=0;
408 Int_t lSLowpt=0;
409 Int_t lSHighpt=0;
410
411 AliMUONGeometryTransformer transformer;
412 transformer.LoadGeometryData(Form("%s/geometry.root",
413 gSystem->DirName(fLoader->GetRunLoader()->GetFileName())));
414 AliMUONTriggerCircuit triggerCircuit(&transformer);
415
416 // select output file name from selected Tree
417 Char_t fileNameOut[30];
418 if (sTreeLetter == "D")
419 {
420 AliInfo(Form("reading from Digits\n"));
421 sprintf(fileNameOut,"TriggerCheckFromDigits.root");
422 }
423 else if (sTreeLetter == "R")
424 {
425 AliInfo(Form("reading from RecPoints\n"));
426 sprintf(fileNameOut,"TriggerCheckFromRP.root");
427 }
428
429 // loop on events
430 Int_t nevents = NumberOfEvents();
431
432 for (Int_t ievent=0; ievent<nevents; ++ievent)
433 {
434 if (ievent%100==0) AliInfo(Form("Processing event %d\n",ievent));
435
436 AliMUONVTriggerStore* triggerStore = TriggerStore(ievent,treeLetter);
437
438 if (!triggerStore)
439 {
440 AliError(Form("Could not read %s from tree%s","Trigger",treeLetter));
441 return;
442 }
443
444 // get global trigger info
445 AliMUONGlobalTrigger* gloTrg = triggerStore->Global();
446 sLowpt+=gloTrg->SingleLpt();
447 sHighpt+=gloTrg->SingleHpt();
448 uSLowpt+=gloTrg->PairUnlikeLpt();
449 uSHighpt+=gloTrg->PairUnlikeHpt();
450 lSLowpt+=gloTrg->PairLikeLpt();
451 lSHighpt+=gloTrg->PairLikeHpt();
452
453 // loop on local triggers
454 TIter next(triggerStore->CreateIterator());
455 AliMUONLocalTrigger* locTrg(0x0);
456 while ( ( locTrg = static_cast<AliMUONLocalTrigger*>(next()) ) )
457 {
458 Bool_t xTrig=locTrg->IsTrigX();
459 Bool_t yTrig=locTrg->IsTrigY();
460
461 if (xTrig && yTrig)
462 { // fill ntuple if trigger in X and Y
463 tupleLoc.Fill(ievent,locTrg->LoCircuit(),
464 locTrg->LoStripX(),
465 locTrg->LoDev(),
466 locTrg->LoStripY(),
467 locTrg->LoLpt(),
468 locTrg->LoHpt(),
469 triggerCircuit.GetY11Pos(locTrg->LoCircuit(),locTrg->LoStripX()),
470 triggerCircuit.GetY21Pos(locTrg->LoCircuit(),locTrg->LoStripX()+locTrg->LoDev()+1),
471 triggerCircuit.GetX11Pos(locTrg->LoCircuit(),locTrg->LoStripY()));
472 }
473 tupleGlo.Fill(ievent,gloTrg->SingleLpt(),gloTrg->SingleHpt(),
474 gloTrg->PairUnlikeLpt(),gloTrg->PairUnlikeHpt(),
475 gloTrg->PairLikeLpt(),gloTrg->PairLikeHpt());
476 } // end of loop on local triggers
477 } // end of loop on events
478
479 // print info and store ntuples
480 printf("\n");
481 printf("=============================================\n");
482 printf("================ SUMMARY ==================\n");
483 printf("\n");
484 printf("Total number of events processed %d \n",nevents);
485 printf("\n");
486 printf(" Global Trigger output Low pt High pt\n");
487 printf(" number of Single :\t");
488 printf("%i\t%i\t",sLowpt,sHighpt);
489 printf("\n");
490 printf(" number of UnlikeSign pair :\t");
491 printf("%i\t%i\t",uSLowpt,uSHighpt);
492 printf("\n");
493 printf(" number of LikeSign pair :\t");
494 printf("%i\t%i\t",lSLowpt,lSHighpt);
495 printf("\n");
496 printf("=============================================\n");
497 fflush(stdout);
498
499 TFile myFile(fileNameOut, "RECREATE");
500 tupleGlo.Write();
501 tupleLoc.Write();
502 myFile.Close();
503}
504
505//_____________________________________________________________________________
506Bool_t
507AliMUONDataInterface::LoadEvent(Int_t event)
508{
509 /// Load event if different from the current one.
510 /// Returns kFALSE on error and kTRUE if the event was loaded.
511
512 assert( IsValid() );
513
514 AliDebug(1,Form("Loading event %d using runLoader %p",event,fLoader->GetRunLoader()));
515 if (fLoader->GetRunLoader()->GetEvent(event) == 0)
516 {
517 fCurrentEvent = event;
518 return kTRUE;
519 }
520 else
521 return kFALSE;
522}
523
524//______________________________________________________________________________
525Int_t
526AliMUONDataInterface::NumberOfEvents() const
527{
528 /// Number of events in the current galice.root file we're attached to
529 if (not IsValid()) return -1;
530 return fLoader->GetRunLoader()->GetNumberOfEvents();
531}
532
533//_____________________________________________________________________________
534void
535AliMUONDataInterface::Open(const char* filename)
536{
537 /// Connect to a given galice.root file
538
539 ResetStores();
540
541 fCurrentEvent=-1;
542
543 if ( fLoader != 0x0 )
544 {
545 delete fLoader->GetRunLoader();
546 }
547
548 fLoader = 0x0;
549
550 fIsValid = kTRUE;
551
552 TString foldername(Form("%s-%d",ClassName(),fgInstanceCounter));
553
554 while (AliRunLoader::GetRunLoader(foldername) != 0x0)
555 {
556 delete AliRunLoader::GetRunLoader(foldername);
557 }
558
559 AliRunLoader* runLoader = AliRunLoader::Open(filename,foldername);
560 if (runLoader == 0x0)
561 {
562 AliError(Form("Cannot open file %s",filename));
563 fIsValid = kFALSE;
564 return;
565 }
566
567 runLoader->LoadHeader();
568 if ( ! runLoader->GetHeader() ) {
569 AliError("Cannot load header.");
570 fIsValid = kFALSE;
571 }
572 else {
573 Int_t runNumber = runLoader->GetHeader()->GetRun();
574 AliCDBManager::Instance()->SetRun(runNumber>=0 ? runNumber : 1);
575 }
576 runLoader->UnloadHeader();
577
578 fLoader = runLoader->GetDetectorLoader("MUON");
579 if (fLoader == 0x0)
580 {
581 AliError("Cannot get AliMUONLoader");
582 fIsValid = kFALSE;
583 }
584
585 if (not IsValid())
586 {
587 AliError(Form("Could not access %s filename. Object is unuseable",filename));
588 }
589}
590
591//_____________________________________________________________________________
592Bool_t AliMUONDataInterface::GetEvent(Int_t event)
593{
594/// Loads all reconstructed data for the given event.
595
596 if (DigitStore(event) == 0x0) return kFALSE;
597 if (ClusterStore(event) == 0x0) return kFALSE;
598 if (TriggerStore(event) == 0x0) return kFALSE;
599 return kTRUE;
600}
601
602//_____________________________________________________________________________
603Int_t AliMUONDataInterface::NumberOfDigits(Int_t detElemId)
604{
605/// Returns the number of digits to be found on a given detector element.
606/// @param detElemId The detector element ID number to search on.
607
608 TIterator* iter = GetIterator(kDigitIteratorByDetectorElement, detElemId);
609 return CountObjects(iter);
610}
611
612//_____________________________________________________________________________
613AliMUONVDigit* AliMUONDataInterface::Digit(Int_t detElemId, Int_t index)
614{
615/// Returns the a pointer to the index'th digit on the specified detector element.
616/// @param detElemId The detector element ID number to search on.
617/// @param index The index number of the digit to fetch in the range [0 .. N-1],
618/// where N = NumberOfDigits(detElemId)
619
620 TIterator* iter = GetIterator(kDigitIteratorByDetectorElement, detElemId);
621 return static_cast<AliMUONVDigit*>( FetchObject(iter, index) );
622}
623
624//_____________________________________________________________________________
625Int_t AliMUONDataInterface::NumberOfDigits(Int_t chamber, Int_t cathode)
626{
627/// Returns the number of digits to be found on a specific chamber and cathode.
628/// @param chamber The chamber number in the range [0 .. 13].
629/// @param cathode The cathode in the range [0 .. 1], where 0 is the bending and
630/// 1 is the non-bending plane.
631
632 TIterator* iter = GetIterator(kDigitIteratorByChamberAndCathode, chamber, cathode);
633 return CountObjects(iter);
634}
635
636//_____________________________________________________________________________
637AliMUONVDigit* AliMUONDataInterface::Digit(Int_t chamber, Int_t cathode, Int_t index)
638{
639/// Returns the a pointer to the index'th digit on the specified chamber and cathode.
640/// @param chamber The chamber number in the range [0 .. 13].
641/// @param cathode The cathode in the range [0 .. 1], where 0 is the bending and
642/// 1 is the non-bending plane.
643/// @param index The index number of the digit to fetch in the range [0 .. N-1],
644/// where N = NumberOfDigits(chamber, cathode)
645
646 TIterator* iter = GetIterator(kDigitIteratorByChamberAndCathode, chamber, cathode);
647 return static_cast<AliMUONVDigit*>( FetchObject(iter, index) );
648}
649
650//_____________________________________________________________________________
651Int_t AliMUONDataInterface::NumberOfRawClusters(Int_t chamber)
652{
653/// Returns the number of reconstructed raw clusters on the specified chamber.
654/// @param chamber The chamber number in the range [0 .. 13].
655
656 TIterator* iter = GetIterator(kRawClusterIterator, chamber);
657 return CountObjects(iter);
658}
659
660//_____________________________________________________________________________
661AliMUONVCluster* AliMUONDataInterface::RawCluster(Int_t chamber, Int_t index)
662{
663/// Returns a pointer to the index'th raw cluster on the specified chamber.
664/// @param chamber The chamber number in the range [0 .. 13].
665/// @param index The index number of the raw cluster to fetch in the range [0 .. N-1],
666/// where N = NumberOfRawClusters(chamber)
667
668 TIterator* iter = GetIterator(kRawClusterIterator, chamber);
669 return static_cast<AliMUONVCluster*>( FetchObject(iter, index) );
670}
671
672//_____________________________________________________________________________
673Int_t AliMUONDataInterface::NumberOfLocalTriggers()
674{
675/// Returns the number of reconstructed local trigger objects.
676
677 TIterator* iter = GetIterator(kLocalTriggerIterator);
678 return CountObjects(iter);
679}
680
681//_____________________________________________________________________________
682AliMUONLocalTrigger* AliMUONDataInterface::LocalTrigger(Int_t index)
683{
684/// Returns a pointer to the index'th local trigger object.
685/// @param index The index number of the local trigger object to fetch in the range [0 .. N-1],
686/// where N = NumberOfLocalTriggers()
687
688 TIterator* iter = GetIterator(kLocalTriggerIterator);
689 return static_cast<AliMUONLocalTrigger*>( FetchObject(iter, index) );
690}
691
692//_____________________________________________________________________________
693Int_t AliMUONDataInterface::NumberOfRegionalTriggers()
694{
695/// Returns the number of regional trigger objects reconstructed.
696
697 TIterator* iter = GetIterator(kRegionalTriggerIterator);
698 return CountObjects(iter);
699}
700
701//_____________________________________________________________________________
702AliMUONRegionalTrigger* AliMUONDataInterface::RegionalTrigger(Int_t index)
703{
704/// Returns a pointer to the index'th regional trigger object.
705/// @param index The index number of the regional trigger object to fetch in the range [0 .. N-1],
706/// where N = NumberOfRegionalTriggers()
707
708 TIterator* iter = GetIterator(kRegionalTriggerIterator);
709 return static_cast<AliMUONRegionalTrigger*>( FetchObject(iter, index) );
710}
711
712//_____________________________________________________________________________
713AliMUONGlobalTrigger* AliMUONDataInterface::GlobalTrigger()
714{
715/// Returns a pointer to the reconstructed global trigger object for the event.
716
717 AliMUONVTriggerStore* store = TriggerStore(fCurrentEvent);
718 if (store == 0x0) return 0x0;
719 return store->Global();
720}
721
722//_____________________________________________________________________________
723void AliMUONDataInterface::ResetStores()
724{
725/// Deletes all the store objects that have been created and resets the pointers to 0x0.
726/// The temporary iterator object is automatically reset. See ResetIterator for more details.
727
728 ResetIterator();
729 if (fDigitStore != 0x0)
730 {
731 delete fDigitStore;
732 fDigitStore = 0x0;
733 }
734 if (fTriggerStore != 0x0)
735 {
736 delete fTriggerStore;
737 fTriggerStore = 0x0;
738 }
739 if (fClusterStore != 0x0)
740 {
741 delete fClusterStore;
742 fClusterStore = 0x0;
743 }
744}
745
746//_____________________________________________________________________________
747TIterator* AliMUONDataInterface::GetIterator(IteratorType type, Int_t x, Int_t y)
748{
749/// Creates an appropriate iterator object and returns it.
750/// If the iterator has already been created then that one is returned otherwise
751/// a new object is created.
752/// Depending on the value of 'type' the semantics of parameters x and y can change.
753/// @param type The type of iterator to create.
754/// @param x This is the detector element ID if type == kDigitIteratorByDetectorElement
755/// If type equals kDigitIteratorByChamberAndCathode or kRawClusterIterator
756/// then this is the chamber number. In all other cases this parameter is
757/// ignored.
758/// @param y If type == kDigitIteratorByChamberAndCathode then this parameter is the
759/// cathode number. In all other cases this parameter is
760/// ignored.
761
762 if (type == fCurrentIteratorType and fDataX == x and fDataY == y)
763 return fIterator;
764
765 if (fCurrentEvent == -1)
766 {
767 AliError("No event was selected. Try first using GetEvent().");
768 return 0x0;
769 }
770
771 ResetIterator();
772
773 switch (type)
774 {
775 case kDigitIteratorByDetectorElement:
776 {
777 Int_t detElem = x;
778 AliMUONVDigitStore* store = DigitStore(fCurrentEvent);
779 if (store == 0x0) return 0x0;
780 fIterator = store->CreateIterator(detElem, detElem, 2);
781 if (fIterator == 0x0) return 0x0;
782 fCurrentIteratorType = kDigitIteratorByDetectorElement;
783 fDataX = detElem;
784 return fIterator;
785 }
786
787 case kDigitIteratorByChamberAndCathode:
788 {
789 Int_t chamber = x;
790 Int_t cathode = y;
791 if (chamber < 0 or AliMpConstants::NofChambers() <= chamber)
792 {
793 AliError(Form(
794 "Must have give a chamber value in the range [0..%d], but got a value of: %d",
795 AliMpConstants::NofChambers() - 1,
796 chamber
797 ));
798 return 0x0;
799 }
800 if (cathode < 0 or 1 < cathode)
801 {
802 AliError(Form("Must have give a cathode value in the range [0..1], but got a value of: %d", cathode));
803 return 0x0;
804 }
805
806 AliMUONVDigitStore* store = DigitStore(fCurrentEvent);
807 if (store == 0x0) return 0x0;
808 MpPair_t pair = AliMpDEManager::GetDetElemIdRange(chamber);
809 fIterator = store->CreateIterator(AliMp::PairFirst(pair), AliMp::PairSecond(pair), cathode);
810 if (fIterator == 0x0) return 0x0;
811 fCurrentIteratorType = kDigitIteratorByChamberAndCathode;
812 fDataX = chamber;
813 fDataY = cathode;
814 return fIterator;
815 }
816
817 case kRawClusterIterator:
818 {
819 Int_t chamber = x;
820 AliMUONVClusterStore* store = ClusterStore(fCurrentEvent);
821 if (store == 0x0) return 0x0;
822 fIterator = store->CreateChamberIterator(chamber, chamber);
823 if (fIterator == 0x0) return 0x0;
824 fCurrentIteratorType = kRawClusterIterator;
825 fDataX = chamber;
826 return fIterator;
827 }
828
829 case kLocalTriggerIterator:
830 {
831 AliMUONVTriggerStore* store = TriggerStore(fCurrentEvent);
832 if (store == 0x0) return 0x0;
833 fIterator = store->CreateLocalIterator();
834 if (fIterator == 0x0) return 0x0;
835 fCurrentIteratorType = kLocalTriggerIterator;
836 return fIterator;
837 }
838
839 case kRegionalTriggerIterator:
840 {
841 AliMUONVTriggerStore* store = TriggerStore(fCurrentEvent);
842 if (store == 0x0) return 0x0;
843 fIterator = store->CreateRegionalIterator();
844 if (fIterator == 0x0) return 0x0;
845 fCurrentIteratorType = kRegionalTriggerIterator;
846 return fIterator;
847 }
848
849 default:
850 return 0x0;
851 }
852}
853
854//_____________________________________________________________________________
855void AliMUONDataInterface::ResetIterator()
856{
857/// The temporary iterator object is deleted if it exists and the pointer reset to 0x0.
858/// The iterator type and temporary data indicating the state of the iterator are
859/// also reset.
860
861 if (fIterator != 0x0) delete fIterator;
862 fCurrentIteratorType = kNoIterator;
863 fCurrentIndex = fDataX = fDataY = -1;
864 fIterator = 0x0;
865}
866
867//_____________________________________________________________________________
868Int_t AliMUONDataInterface::CountObjects(TIterator* iter)
869{
870/// Counts the number of objects in the iterator and resets it.
871/// @return The number of objects in 'iter'.
872
873 if (iter == 0x0) return -1;
874 Int_t count = 0;
875 iter->Reset();
876 while ( iter->Next() != 0x0 ) count++;
877 iter->Reset();
878 fCurrentIndex = -1;
879 return count;
880}
881
882//_____________________________________________________________________________
883TObject* AliMUONDataInterface::FetchObject(TIterator* iter, Int_t index)
884{
885/// Fetches the index'th object from the iterator counting the first object
886/// returned by iterator after it is reset as index == 0. The next object
887/// has index == 1 and so on where the last object returned by the iterator
888/// has index == N-1 where N = CountObjects(iter)
889/// This method will only reset the iterator if index is smaller than
890/// fCurrentIndex, which is used to track the iteration progress and is
891/// updated when a new object if returned by this method.
892/// @param iter The iterator to fetch an object from.
893/// @param index The index number of the object to fetch in the range [0 .. N-1]
894/// where N = CountObjects(iter)
895
896 if (index < 0)
897 {
898 AliError(Form("Index is out of bounds. Got a value of %d.", index));
899 return 0x0;
900 }
901
902 if (iter == 0x0) return 0x0;
903 if (index <= fCurrentIndex)
904 {
905 iter->Reset();
906 fCurrentIndex = -1;
907 }
908
909 TObject* object = 0x0;
910 while (fCurrentIndex < index)
911 {
912 object = iter->Next();
913 if (object == 0x0)
914 {
915 AliError(Form("Index is out of bounds. Got a value of %d.", index));
916 iter->Reset();
917 fCurrentIndex = -1;
918 return 0x0;
919 }
920 fCurrentIndex++;
921 }
922 return object;
923}