new functionality and new class added
[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;
567 }
aa73f8fb 568
569 runLoader->LoadHeader();
570 if ( ! runLoader->GetHeader() ) {
571 AliError("Cannot load header.");
572 fIsValid = kFALSE;
573 }
574 else {
575 Int_t runNumber = runLoader->GetHeader()->GetRun();
576 AliCDBManager::Instance()->SetRun(runNumber);
577 }
578 runLoader->UnloadHeader();
579
e9bef706 580 fLoader = runLoader->GetDetectorLoader("MUON");
e8636ba0 581 if (fLoader == 0x0)
e9bef706 582 {
583 AliError("Cannot get AliMUONLoader");
584 fIsValid = kFALSE;
585 }
586
e8636ba0 587 if (not IsValid())
e9bef706 588 {
589 AliError(Form("Could not access %s filename. Object is unuseable",filename));
590 }
925e6570 591}
48b32e42 592
e9bef706 593//_____________________________________________________________________________
e8636ba0 594Bool_t AliMUONDataInterface::GetEvent(Int_t event)
48b32e42 595{
e8636ba0 596/// Loads all reconstructed data for the given event.
597
598 if (DigitStore(event) == 0x0) return kFALSE;
599 if (ClusterStore(event) == 0x0) return kFALSE;
e8636ba0 600 if (TriggerStore(event) == 0x0) return kFALSE;
e8636ba0 601 return kTRUE;
925e6570 602}
48b32e42 603
e8636ba0 604//_____________________________________________________________________________
605Int_t AliMUONDataInterface::NumberOfDigits(Int_t detElemId)
48b32e42 606{
e8636ba0 607/// Returns the number of digits to be found on a given detector element.
608/// @param detElemId The detector element ID number to search on.
a202c2d2 609
e8636ba0 610 TIterator* iter = GetIterator(kDigitIteratorByDetectorElement, detElemId);
611 return CountObjects(iter);
925e6570 612}
48b32e42 613
e8636ba0 614//_____________________________________________________________________________
615AliMUONVDigit* AliMUONDataInterface::Digit(Int_t detElemId, Int_t index)
48b32e42 616{
e8636ba0 617/// Returns the a pointer to the index'th digit on the specified detector element.
618/// @param detElemId The detector element ID number to search on.
619/// @param index The index number of the digit to fetch in the range [0 .. N-1],
620/// where N = NumberOfDigits(detElemId)
a202c2d2 621
e8636ba0 622 TIterator* iter = GetIterator(kDigitIteratorByDetectorElement, detElemId);
623 return static_cast<AliMUONVDigit*>( FetchObject(iter, index) );
925e6570 624}
48b32e42 625
e8636ba0 626//_____________________________________________________________________________
627Int_t AliMUONDataInterface::NumberOfDigits(Int_t chamber, Int_t cathode)
48b32e42 628{
e8636ba0 629/// Returns the number of digits to be found on a specific chamber and cathode.
630/// @param chamber The chamber number in the range [0 .. 13].
631/// @param cathode The cathode in the range [0 .. 1], where 0 is the bending and
632/// 1 is the non-bending plane.
48b32e42 633
e8636ba0 634 TIterator* iter = GetIterator(kDigitIteratorByChamberAndCathode, chamber, cathode);
635 return CountObjects(iter);
925e6570 636}
48b32e42 637
e8636ba0 638//_____________________________________________________________________________
639AliMUONVDigit* AliMUONDataInterface::Digit(Int_t chamber, Int_t cathode, Int_t index)
48b32e42 640{
e8636ba0 641/// Returns the a pointer to the index'th digit on the specified chamber and cathode.
642/// @param chamber The chamber number in the range [0 .. 13].
643/// @param cathode The cathode in the range [0 .. 1], where 0 is the bending and
644/// 1 is the non-bending plane.
645/// @param index The index number of the digit to fetch in the range [0 .. N-1],
646/// where N = NumberOfDigits(chamber, cathode)
647
648 TIterator* iter = GetIterator(kDigitIteratorByChamberAndCathode, chamber, cathode);
649 return static_cast<AliMUONVDigit*>( FetchObject(iter, index) );
925e6570 650}
48b32e42 651
e8636ba0 652//_____________________________________________________________________________
653Int_t AliMUONDataInterface::NumberOfRawClusters(Int_t chamber)
48b32e42 654{
e8636ba0 655/// Returns the number of reconstructed raw clusters on the specified chamber.
656/// @param chamber The chamber number in the range [0 .. 13].
a202c2d2 657
e8636ba0 658 TIterator* iter = GetIterator(kRawClusterIterator, chamber);
659 return CountObjects(iter);
925e6570 660}
48b32e42 661
e8636ba0 662//_____________________________________________________________________________
2060b217 663AliMUONVCluster* AliMUONDataInterface::RawCluster(Int_t chamber, Int_t index)
48b32e42 664{
e8636ba0 665/// Returns a pointer to the index'th raw cluster on the specified chamber.
666/// @param chamber The chamber number in the range [0 .. 13].
667/// @param index The index number of the raw cluster to fetch in the range [0 .. N-1],
668/// where N = NumberOfRawClusters(chamber)
a202c2d2 669
e8636ba0 670 TIterator* iter = GetIterator(kRawClusterIterator, chamber);
2060b217 671 return static_cast<AliMUONVCluster*>( FetchObject(iter, index) );
925e6570 672}
48b32e42 673
e8636ba0 674//_____________________________________________________________________________
e8636ba0 675Int_t AliMUONDataInterface::NumberOfLocalTriggers()
48b32e42 676{
e8636ba0 677/// Returns the number of reconstructed local trigger objects.
a202c2d2 678
e8636ba0 679 TIterator* iter = GetIterator(kLocalTriggerIterator);
680 return CountObjects(iter);
925e6570 681}
48b32e42 682
e8636ba0 683//_____________________________________________________________________________
684AliMUONLocalTrigger* AliMUONDataInterface::LocalTrigger(Int_t index)
48b32e42 685{
e8636ba0 686/// Returns a pointer to the index'th local trigger object.
687/// @param index The index number of the local trigger object to fetch in the range [0 .. N-1],
688/// where N = NumberOfLocalTriggers()
a202c2d2 689
e8636ba0 690 TIterator* iter = GetIterator(kLocalTriggerIterator);
691 return static_cast<AliMUONLocalTrigger*>( FetchObject(iter, index) );
925e6570 692}
48b32e42 693
e8636ba0 694//_____________________________________________________________________________
695Int_t AliMUONDataInterface::NumberOfRegionalTriggers()
48b32e42 696{
e8636ba0 697/// Returns the number of regional trigger objects reconstructed.
a202c2d2 698
e8636ba0 699 TIterator* iter = GetIterator(kRegionalTriggerIterator);
700 return CountObjects(iter);
925e6570 701}
48b32e42 702
e8636ba0 703//_____________________________________________________________________________
704AliMUONRegionalTrigger* AliMUONDataInterface::RegionalTrigger(Int_t index)
48b32e42 705{
e8636ba0 706/// Returns a pointer to the index'th regional trigger object.
707/// @param index The index number of the regional trigger object to fetch in the range [0 .. N-1],
708/// where N = NumberOfRegionalTriggers()
a202c2d2 709
e8636ba0 710 TIterator* iter = GetIterator(kRegionalTriggerIterator);
711 return static_cast<AliMUONRegionalTrigger*>( FetchObject(iter, index) );
925e6570 712}
48b32e42 713
e8636ba0 714//_____________________________________________________________________________
715AliMUONGlobalTrigger* AliMUONDataInterface::GlobalTrigger()
48b32e42 716{
e8636ba0 717/// Returns a pointer to the reconstructed global trigger object for the event.
a202c2d2 718
e8636ba0 719 AliMUONVTriggerStore* store = TriggerStore(fCurrentEvent);
720 if (store == 0x0) return 0x0;
721 return store->Global();
925e6570 722}
48b32e42 723
e8636ba0 724//_____________________________________________________________________________
e8636ba0 725void AliMUONDataInterface::ResetStores()
48b32e42 726{
e8636ba0 727/// Deletes all the store objects that have been created and resets the pointers to 0x0.
728/// The temporary iterator object is automatically reset. See ResetIterator for more details.
a202c2d2 729
e8636ba0 730 ResetIterator();
731 if (fDigitStore != 0x0)
732 {
733 delete fDigitStore;
734 fDigitStore = 0x0;
735 }
736 if (fTriggerStore != 0x0)
737 {
738 delete fTriggerStore;
739 fTriggerStore = 0x0;
740 }
741 if (fClusterStore != 0x0)
742 {
743 delete fClusterStore;
744 fClusterStore = 0x0;
745 }
925e6570 746}
554b38a6 747
e8636ba0 748//_____________________________________________________________________________
749TIterator* AliMUONDataInterface::GetIterator(IteratorType type, Int_t x, Int_t y)
554b38a6 750{
e8636ba0 751/// Creates an appropriate iterator object and returns it.
752/// If the iterator has already been created then that one is returned otherwise
753/// a new object is created.
754/// Depending on the value of 'type' the semantics of parameters x and y can change.
755/// @param type The type of iterator to create.
756/// @param x This is the detector element ID if type == kDigitIteratorByDetectorElement
757/// If type equals kDigitIteratorByChamberAndCathode or kRawClusterIterator
758/// then this is the chamber number. In all other cases this parameter is
759/// ignored.
760/// @param y If type == kDigitIteratorByChamberAndCathode then this parameter is the
761/// cathode number. In all other cases this parameter is
762/// ignored.
763
764 if (type == fCurrentIteratorType and fDataX == x and fDataY == y)
765 return fIterator;
766
767 if (fCurrentEvent == -1)
768 {
769 AliError("No event was selected. Try first using GetEvent().");
770 return 0x0;
771 }
772
773 ResetIterator();
774
775 switch (type)
776 {
777 case kDigitIteratorByDetectorElement:
778 {
779 Int_t detElem = x;
780 AliMUONVDigitStore* store = DigitStore(fCurrentEvent);
781 if (store == 0x0) return 0x0;
e8636ba0 782 fIterator = store->CreateIterator(detElem, detElem, 2);
783 if (fIterator == 0x0) return 0x0;
784 fCurrentIteratorType = kDigitIteratorByDetectorElement;
785 fDataX = detElem;
786 return fIterator;
787 }
788
789 case kDigitIteratorByChamberAndCathode:
790 {
791 Int_t chamber = x;
792 Int_t cathode = y;
793 if (chamber < 0 or AliMpConstants::NofChambers() <= chamber)
794 {
795 AliError(Form(
796 "Must have give a chamber value in the range [0..%d], but got a value of: %d",
797 AliMpConstants::NofChambers() - 1,
798 chamber
799 ));
800 return 0x0;
801 }
802 if (cathode < 0 or 1 < cathode)
803 {
804 AliError(Form("Must have give a cathode value in the range [0..1], but got a value of: %d", cathode));
805 return 0x0;
806 }
807
808 AliMUONVDigitStore* store = DigitStore(fCurrentEvent);
809 if (store == 0x0) return 0x0;
168e9c4d 810 MpPair_t pair = AliMpDEManager::GetDetElemIdRange(chamber);
811 fIterator = store->CreateIterator(AliMp::PairFirst(pair), AliMp::PairSecond(pair), cathode);
e8636ba0 812 if (fIterator == 0x0) return 0x0;
813 fCurrentIteratorType = kDigitIteratorByChamberAndCathode;
814 fDataX = chamber;
815 fDataY = cathode;
816 return fIterator;
817 }
818
819 case kRawClusterIterator:
820 {
821 Int_t chamber = x;
822 AliMUONVClusterStore* store = ClusterStore(fCurrentEvent);
823 if (store == 0x0) return 0x0;
824 fIterator = store->CreateChamberIterator(chamber, chamber);
825 if (fIterator == 0x0) return 0x0;
826 fCurrentIteratorType = kRawClusterIterator;
827 fDataX = chamber;
828 return fIterator;
829 }
830
e8636ba0 831 case kLocalTriggerIterator:
832 {
833 AliMUONVTriggerStore* store = TriggerStore(fCurrentEvent);
834 if (store == 0x0) return 0x0;
835 fIterator = store->CreateLocalIterator();
836 if (fIterator == 0x0) return 0x0;
837 fCurrentIteratorType = kLocalTriggerIterator;
838 return fIterator;
839 }
840
841 case kRegionalTriggerIterator:
842 {
843 AliMUONVTriggerStore* store = TriggerStore(fCurrentEvent);
844 if (store == 0x0) return 0x0;
845 fIterator = store->CreateRegionalIterator();
846 if (fIterator == 0x0) return 0x0;
847 fCurrentIteratorType = kRegionalTriggerIterator;
848 return fIterator;
849 }
850
e8636ba0 851 default:
852 return 0x0;
853 }
554b38a6 854}
855
e8636ba0 856//_____________________________________________________________________________
857void AliMUONDataInterface::ResetIterator()
554b38a6 858{
e8636ba0 859/// The temporary iterator object is deleted if it exists and the pointer reset to 0x0.
860/// The iterator type and temporary data indicating the state of the iterator are
861/// also reset.
862
863 if (fIterator != 0x0) delete fIterator;
864 fCurrentIteratorType = kNoIterator;
865 fCurrentIndex = fDataX = fDataY = -1;
866 fIterator = 0x0;
554b38a6 867}
868
e8636ba0 869//_____________________________________________________________________________
870Int_t AliMUONDataInterface::CountObjects(TIterator* iter)
554b38a6 871{
e8636ba0 872/// Counts the number of objects in the iterator and resets it.
873/// @return The number of objects in 'iter'.
874
875 if (iter == 0x0) return -1;
876 Int_t count = 0;
877 iter->Reset();
878 while ( iter->Next() != 0x0 ) count++;
879 iter->Reset();
880 fCurrentIndex = -1;
881 return count;
554b38a6 882}
883
e8636ba0 884//_____________________________________________________________________________
885TObject* AliMUONDataInterface::FetchObject(TIterator* iter, Int_t index)
554b38a6 886{
e8636ba0 887/// Fetches the index'th object from the iterator counting the first object
888/// returned by iterator after it is reset as index == 0. The next object
889/// has index == 1 and so on where the last object returned by the iterator
890/// has index == N-1 where N = CountObjects(iter)
891/// This method will only reset the iterator if index is smaller than
892/// fCurrentIndex, which is used to track the iteration progress and is
893/// updated when a new object if returned by this method.
894/// @param iter The iterator to fetch an object from.
895/// @param index The index number of the object to fetch in the range [0 .. N-1]
896/// where N = CountObjects(iter)
897
898 if (index < 0)
899 {
900 AliError(Form("Index is out of bounds. Got a value of %d.", index));
901 return 0x0;
902 }
a202c2d2 903
e8636ba0 904 if (iter == 0x0) return 0x0;
905 if (index <= fCurrentIndex)
906 {
907 iter->Reset();
908 fCurrentIndex = -1;
909 }
910
911 TObject* object = 0x0;
912 while (fCurrentIndex < index)
913 {
914 object = iter->Next();
915 if (object == 0x0)
916 {
917 AliError(Form("Index is out of bounds. Got a value of %d.", index));
918 iter->Reset();
919 fCurrentIndex = -1;
920 return 0x0;
921 }
922 fCurrentIndex++;
923 }
924 return object;
554b38a6 925}