Fixed memory leak
[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();
e9bef706 113 --fgInstanceCounter;
a202c2d2 114}
48b32e42 115
a202c2d2 116//______________________________________________________________________________
e8636ba0 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
46df197d 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.
e8636ba0 129
130 if (not IsValid()) return 0x0;
e8636ba0 131
46df197d 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 }
e8636ba0 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//______________________________________________________________________________
a202c2d2 166AliMUONVClusterStore*
e9bef706 167AliMUONDataInterface::ClusterStore(Int_t event)
a202c2d2 168{
e9bef706 169 /// Return clusterStore for a given event.
170 /// Return 0x0 if event not found.
171 /// Returned pointer should not be deleted
46df197d 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.
e9bef706 178
e8636ba0 179 if (not IsValid()) return 0x0;
e8636ba0 180
46df197d 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 }
e9bef706 191
192 fLoader->LoadRecPoints();
193
194 TTree* treeR = fLoader->TreeR();
e8636ba0 195 if (treeR == 0x0)
e9bef706 196 {
197 AliError("Could not get treeR");
198 return 0x0;
199 }
200
e8636ba0 201 fClusterStore = AliMUONVClusterStore::Create(*treeR);
202 if ( fClusterStore != 0x0 )
e9bef706 203 {
204 fClusterStore->Clear();
205 fClusterStore->Connect(*treeR);
206 treeR->GetEvent(0);
207 }
208
209 fLoader->UnloadRecPoints();
210
211 return fClusterStore;
212}
3455463a 213
e8636ba0 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
46df197d 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.
e8636ba0 228
229 if (not IsValid()) return 0x0;
e8636ba0 230
46df197d 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 }
e8636ba0 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 }
46df197d 294 fTreeLetter = stree;
e8636ba0 295
296 return fTriggerStore;
925e6570 297}
48b32e42 298
a202c2d2 299//______________________________________________________________________________
300void
e9bef706 301AliMUONDataInterface::DumpDigits(Int_t event, Bool_t sorted)
48b32e42 302{
e9bef706 303 /// Dump the digits for a given event, sorted if so required
304 DigitStore(event);
e8636ba0 305 if ( fDigitStore != 0x0 )
e9bef706 306 {
307 if ( sorted )
308 {
309 DumpSorted(*fDigitStore);
310 }
311 else
312 {
313 fDigitStore->Print();
314 }
315 }
925e6570 316}
48b32e42 317
a202c2d2 318//______________________________________________________________________________
e9bef706 319void
320AliMUONDataInterface::DumpRecPoints(Int_t event, Bool_t sorted)
6d149c9e 321{
e9bef706 322 /// Dump the recpoints for a given event, sorted if so required
323 ClusterStore(event);
e8636ba0 324 if ( fClusterStore != 0x0 )
e9bef706 325 {
326 if ( sorted )
327 {
328 DumpSorted(*fClusterStore);
329 }
330 else
331 {
332 fClusterStore->Print();
333 }
334 }
6d149c9e 335}
336
e9bef706 337//_____________________________________________________________________________
338void
339AliMUONDataInterface::DumpSorted(const AliMUONVStore& store) const
6d149c9e 340{
e9bef706 341 /// Dump the given store, in sorted order
a202c2d2 342
e9bef706 343 TIter next(store.CreateIterator());
a202c2d2 344 TObject* object;
e9bef706 345 TList list;
346 list.SetOwner(kFALSE);
a202c2d2 347
e9bef706 348 while ( ( object = next() ) )
a202c2d2 349 {
e9bef706 350 list.Add(object);
a202c2d2 351 }
352
e9bef706 353 list.Sort();
354
355 list.Print();
a202c2d2 356}
357
e9bef706 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
a202c2d2 365
e9bef706 366 if ( event < 0 )
367 {
368 NtupleTrigger(treeLetter);
a202c2d2 369 }
370 else
371 {
e9bef706 372 TriggerStore(event,treeLetter);
a202c2d2 373
e8636ba0 374 if ( fTriggerStore != 0x0 )
e9bef706 375 {
376 fTriggerStore->Print();
377 }
378 }
a202c2d2 379}
6d149c9e 380
e9bef706 381//_____________________________________________________________________________
a202c2d2 382void
e9bef706 383AliMUONDataInterface::NtupleTrigger(const char* treeLetter)
48b32e42 384{
e9bef706 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
d3acfadf 411 AliMUONGeometryTransformer transformer;
ef4cb4f1 412 transformer.LoadGeometryData(Form("%s/geometry.root",
e9bef706 413 gSystem->DirName(fLoader->GetRunLoader()->GetFileName())));
a55f49a0 414 AliMUONTriggerCircuit triggerCircuit(&transformer);
e9bef706 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
8af099d3 436 AliMUONVTriggerStore* triggerStore = TriggerStore(ievent,treeLetter);
e9bef706 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 {
d72d7b9e 458 Bool_t xTrig=locTrg->IsTrigX();
459 Bool_t yTrig=locTrg->IsTrigY();
e9bef706 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();
925e6570 503}
48b32e42 504
e9bef706 505//_____________________________________________________________________________
e8636ba0 506Bool_t
e9bef706 507AliMUONDataInterface::LoadEvent(Int_t event)
48b32e42 508{
e9bef706 509 /// Load event if different from the current one.
e8636ba0 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)
e9bef706 516 {
517 fCurrentEvent = event;
e8636ba0 518 return kTRUE;
e9bef706 519 }
e8636ba0 520 else
521 return kFALSE;
925e6570 522}
48b32e42 523
a202c2d2 524//______________________________________________________________________________
e9bef706 525Int_t
526AliMUONDataInterface::NumberOfEvents() const
a202c2d2 527{
e9bef706 528 /// Number of events in the current galice.root file we're attached to
e8636ba0 529 if (not IsValid()) return -1;
e9bef706 530 return fLoader->GetRunLoader()->GetNumberOfEvents();
a202c2d2 531}
48b32e42 532
e9bef706 533//_____________________________________________________________________________
a202c2d2 534void
e9bef706 535AliMUONDataInterface::Open(const char* filename)
48b32e42 536{
e9bef706 537 /// Connect to a given galice.root file
538
e8636ba0 539 ResetStores();
e9bef706 540
541 fCurrentEvent=-1;
542
e8636ba0 543 if ( fLoader != 0x0 )
e9bef706 544 {
545 delete fLoader->GetRunLoader();
546 }
547
548 fLoader = 0x0;
549
550 fIsValid = kTRUE;
551
552 TString foldername(Form("%s-%d",ClassName(),fgInstanceCounter));
553
e8636ba0 554 while (AliRunLoader::GetRunLoader(foldername) != 0x0)
e9bef706 555 {
556 delete AliRunLoader::GetRunLoader(foldername);
557 }
558
559 AliRunLoader* runLoader = AliRunLoader::Open(filename,foldername);
e8636ba0 560 if (runLoader == 0x0)
e9bef706 561 {
562 AliError(Form("Cannot open file %s",filename));
563 fIsValid = kFALSE;
fc2293be 564 return;
e9bef706 565 }
aa73f8fb 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();
e0edcfea 574 AliCDBManager::Instance()->SetRun(runNumber>=0 ? runNumber : 1);
aa73f8fb 575 }
576 runLoader->UnloadHeader();
577
e9bef706 578 fLoader = runLoader->GetDetectorLoader("MUON");
e8636ba0 579 if (fLoader == 0x0)
e9bef706 580 {
581 AliError("Cannot get AliMUONLoader");
582 fIsValid = kFALSE;
583 }
584
e8636ba0 585 if (not IsValid())
e9bef706 586 {
587 AliError(Form("Could not access %s filename. Object is unuseable",filename));
588 }
925e6570 589}
48b32e42 590
e9bef706 591//_____________________________________________________________________________
e8636ba0 592Bool_t AliMUONDataInterface::GetEvent(Int_t event)
48b32e42 593{
e8636ba0 594/// Loads all reconstructed data for the given event.
595
596 if (DigitStore(event) == 0x0) return kFALSE;
597 if (ClusterStore(event) == 0x0) return kFALSE;
e8636ba0 598 if (TriggerStore(event) == 0x0) return kFALSE;
e8636ba0 599 return kTRUE;
925e6570 600}
48b32e42 601
e8636ba0 602//_____________________________________________________________________________
603Int_t AliMUONDataInterface::NumberOfDigits(Int_t detElemId)
48b32e42 604{
e8636ba0 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.
a202c2d2 607
e8636ba0 608 TIterator* iter = GetIterator(kDigitIteratorByDetectorElement, detElemId);
609 return CountObjects(iter);
925e6570 610}
48b32e42 611
e8636ba0 612//_____________________________________________________________________________
613AliMUONVDigit* AliMUONDataInterface::Digit(Int_t detElemId, Int_t index)
48b32e42 614{
e8636ba0 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)
a202c2d2 619
e8636ba0 620 TIterator* iter = GetIterator(kDigitIteratorByDetectorElement, detElemId);
621 return static_cast<AliMUONVDigit*>( FetchObject(iter, index) );
925e6570 622}
48b32e42 623
e8636ba0 624//_____________________________________________________________________________
625Int_t AliMUONDataInterface::NumberOfDigits(Int_t chamber, Int_t cathode)
48b32e42 626{
e8636ba0 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.
48b32e42 631
e8636ba0 632 TIterator* iter = GetIterator(kDigitIteratorByChamberAndCathode, chamber, cathode);
633 return CountObjects(iter);
925e6570 634}
48b32e42 635
e8636ba0 636//_____________________________________________________________________________
637AliMUONVDigit* AliMUONDataInterface::Digit(Int_t chamber, Int_t cathode, Int_t index)
48b32e42 638{
e8636ba0 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) );
925e6570 648}
48b32e42 649
e8636ba0 650//_____________________________________________________________________________
651Int_t AliMUONDataInterface::NumberOfRawClusters(Int_t chamber)
48b32e42 652{
e8636ba0 653/// Returns the number of reconstructed raw clusters on the specified chamber.
654/// @param chamber The chamber number in the range [0 .. 13].
a202c2d2 655
e8636ba0 656 TIterator* iter = GetIterator(kRawClusterIterator, chamber);
657 return CountObjects(iter);
925e6570 658}
48b32e42 659
e8636ba0 660//_____________________________________________________________________________
2060b217 661AliMUONVCluster* AliMUONDataInterface::RawCluster(Int_t chamber, Int_t index)
48b32e42 662{
e8636ba0 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)
a202c2d2 667
e8636ba0 668 TIterator* iter = GetIterator(kRawClusterIterator, chamber);
2060b217 669 return static_cast<AliMUONVCluster*>( FetchObject(iter, index) );
925e6570 670}
48b32e42 671
e8636ba0 672//_____________________________________________________________________________
e8636ba0 673Int_t AliMUONDataInterface::NumberOfLocalTriggers()
48b32e42 674{
e8636ba0 675/// Returns the number of reconstructed local trigger objects.
a202c2d2 676
e8636ba0 677 TIterator* iter = GetIterator(kLocalTriggerIterator);
678 return CountObjects(iter);
925e6570 679}
48b32e42 680
e8636ba0 681//_____________________________________________________________________________
682AliMUONLocalTrigger* AliMUONDataInterface::LocalTrigger(Int_t index)
48b32e42 683{
e8636ba0 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()
a202c2d2 687
e8636ba0 688 TIterator* iter = GetIterator(kLocalTriggerIterator);
689 return static_cast<AliMUONLocalTrigger*>( FetchObject(iter, index) );
925e6570 690}
48b32e42 691
e8636ba0 692//_____________________________________________________________________________
693Int_t AliMUONDataInterface::NumberOfRegionalTriggers()
48b32e42 694{
e8636ba0 695/// Returns the number of regional trigger objects reconstructed.
a202c2d2 696
e8636ba0 697 TIterator* iter = GetIterator(kRegionalTriggerIterator);
698 return CountObjects(iter);
925e6570 699}
48b32e42 700
e8636ba0 701//_____________________________________________________________________________
702AliMUONRegionalTrigger* AliMUONDataInterface::RegionalTrigger(Int_t index)
48b32e42 703{
e8636ba0 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()
a202c2d2 707
e8636ba0 708 TIterator* iter = GetIterator(kRegionalTriggerIterator);
709 return static_cast<AliMUONRegionalTrigger*>( FetchObject(iter, index) );
925e6570 710}
48b32e42 711
e8636ba0 712//_____________________________________________________________________________
713AliMUONGlobalTrigger* AliMUONDataInterface::GlobalTrigger()
48b32e42 714{
e8636ba0 715/// Returns a pointer to the reconstructed global trigger object for the event.
a202c2d2 716
e8636ba0 717 AliMUONVTriggerStore* store = TriggerStore(fCurrentEvent);
718 if (store == 0x0) return 0x0;
719 return store->Global();
925e6570 720}
48b32e42 721
e8636ba0 722//_____________________________________________________________________________
e8636ba0 723void AliMUONDataInterface::ResetStores()
48b32e42 724{
e8636ba0 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.
a202c2d2 727
e8636ba0 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 }
925e6570 744}
554b38a6 745
e8636ba0 746//_____________________________________________________________________________
747TIterator* AliMUONDataInterface::GetIterator(IteratorType type, Int_t x, Int_t y)
554b38a6 748{
e8636ba0 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;
e8636ba0 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;
168e9c4d 808 MpPair_t pair = AliMpDEManager::GetDetElemIdRange(chamber);
809 fIterator = store->CreateIterator(AliMp::PairFirst(pair), AliMp::PairSecond(pair), cathode);
e8636ba0 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
e8636ba0 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
e8636ba0 849 default:
850 return 0x0;
851 }
554b38a6 852}
853
e8636ba0 854//_____________________________________________________________________________
855void AliMUONDataInterface::ResetIterator()
554b38a6 856{
e8636ba0 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;
554b38a6 865}
866
e8636ba0 867//_____________________________________________________________________________
868Int_t AliMUONDataInterface::CountObjects(TIterator* iter)
554b38a6 869{
e8636ba0 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;
554b38a6 880}
881
e8636ba0 882//_____________________________________________________________________________
883TObject* AliMUONDataInterface::FetchObject(TIterator* iter, Int_t index)
554b38a6 884{
e8636ba0 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 }
a202c2d2 901
e8636ba0 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;
554b38a6 923}