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