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