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