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