1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
17 Revision 1.40 2000/11/29 20:32:26 gosset
19 1. correction for array index out of bounds
20 2. one printout commented
22 Revision 1.39 2000/11/12 17:17:03 pcrochet
23 BuildGeometry of AliMUON for trigger chambers delegated to AliMUONSegmentationTriggerX (same strategy as for tracking chambers)
25 Revision 1.38 2000/11/06 09:20:43 morsch
26 AliMUON delegates part of BuildGeometry() to AliMUONSegmentation using the
27 Draw() method. This avoids code and parameter replication.
29 Revision 1.37 2000/10/26 09:53:37 pcrochet
30 put back trigger chambers in the display (there was a problem in buildgeometry)
32 Revision 1.36 2000/10/25 19:51:18 morsch
33 Correct x-position of chambers.
35 Revision 1.35 2000/10/24 19:46:21 morsch
36 BuildGeometry updated for slats in station 3-4.
38 Revision 1.34 2000/10/18 11:42:06 morsch
39 - AliMUONRawCluster contains z-position.
40 - Some clean-up of useless print statements during initialisations.
42 Revision 1.33 2000/10/09 14:01:57 morsch
43 Unused variables removed.
45 Revision 1.32 2000/10/06 09:08:10 morsch
46 Built geometry includes slat geometry for event display.
48 Revision 1.31 2000/10/02 21:28:08 fca
49 Removal of useless dependecies via forward declarations
51 Revision 1.30 2000/10/02 16:58:29 egangler
52 Cleaning of the code :
55 -> some useless includes removed or replaced by "class" statement
57 Revision 1.29 2000/07/28 13:49:38 morsch
58 SetAcceptance defines inner and outer chamber radii according to angular acceptance.
59 Can be used for simple acceptance studies.
61 Revision 1.28 2000/07/22 16:43:15 morsch
62 Same comment as before, but now done correctly I hope (sorry it's Saturday evening)
64 Revision 1.27 2000/07/22 16:36:50 morsch
65 Change order of indices in creation (new) of xhit and yhit
67 Revision 1.26 2000/07/03 11:54:57 morsch
68 AliMUONSegmentation and AliMUONHitMap have been replaced by AliSegmentation and AliHitMap in STEER
69 The methods GetPadIxy and GetPadXxy of AliMUONSegmentation have changed name to GetPadI and GetPadC.
71 Revision 1.25 2000/06/29 12:34:09 morsch
72 AliMUONSegmentation class has been made independent of AliMUONChamber. This makes
73 it usable with any other geometry class. The link to the object to which it belongs is
74 established via an index. This assumes that there exists a global geometry manager
75 from which the pointer to the parent object can be obtained (in our case gAlice).
77 Revision 1.24 2000/06/28 15:16:35 morsch
78 (1) Client code adapted to new method signatures in AliMUONSegmentation (see comments there)
79 to allow development of slat-muon chamber simulation and reconstruction code in the MUON
80 framework. The changes should have no side effects (mostly dummy arguments).
81 (2) Hit disintegration uses 3-dim hit coordinates to allow simulation
82 of chambers with overlapping modules (MakePadHits, Disintegration).
84 Revision 1.23 2000/06/28 12:19:17 morsch
85 More consequent seperation of global input data services (AliMUONClusterInput singleton) and the
86 cluster and hit reconstruction algorithms in AliMUONClusterFinderVS.
87 AliMUONClusterFinderVS becomes the base class for clustering and hit reconstruction.
88 It requires two cathode planes. Small modifications in the code will make it usable for
89 one cathode plane and, hence, more general (for test beam data).
90 AliMUONClusterFinder is now obsolete.
92 Revision 1.22 2000/06/28 08:06:10 morsch
93 Avoid global variables in AliMUONClusterFinderVS by seperating the input data for the fit from the
94 algorithmic part of the class. Input data resides inside the AliMUONClusterInput singleton.
95 It also naturally takes care of the TMinuit instance.
97 Revision 1.21 2000/06/27 08:54:41 morsch
98 Problems with on constant array sizes (in hitMap, nmuon, xhit, yhit) corrected.
100 Revision 1.20 2000/06/26 14:02:38 morsch
101 Add class AliMUONConstants with MUON specific constants using static memeber data and access methods.
103 Revision 1.19 2000/06/22 13:40:51 morsch
104 scope problem on HP, "i" declared once
105 pow changed to TMath::Power (PH, AM)
107 Revision 1.18 2000/06/15 07:58:48 morsch
108 Code from MUON-dev joined
110 Revision 1.14.4.17 2000/06/14 14:36:46 morsch
111 - add TriggerCircuit (PC)
112 - add GlobalTrigger and LocalTrigger and specific methods (PC)
114 Revision 1.14.4.16 2000/06/09 21:20:28 morsch
115 Most coding rule violations corrected
117 Revision 1.14.4.15 2000/05/02 09:54:32 morsch
118 RULE RN17 violations corrected
120 Revision 1.14.4.12 2000/04/26 12:25:02 morsch
121 Code revised by P. Crochet:
122 - Z position of TriggerChamber changed according to A.Tournaire Priv.Comm.
123 - ToF included in the method MakePadHits
124 - inner radius of flange between beam shielding and trigger corrected
125 - Trigger global volume updated (according to the new geometry)
127 Revision 1.14.4.11 2000/04/19 19:42:08 morsch
128 Some changes of variable names curing viols and methods concerning
129 correlated clusters removed.
131 Revision 1.14.4.10 2000/03/22 16:44:07 gosset
132 Memory leak suppressed in function Digitise:
133 p_adr->Delete() instead of Clear (I.Chevrot and A.Baldisseri)
135 Revision 1.14.4.9 2000/03/20 18:15:25 morsch
136 Positions of trigger chambers corrected (P.C.)
138 Revision 1.14.4.8 2000/02/21 15:38:01 morsch
139 Call to AddHitList introduced to make this version compatible with head.
141 Revision 1.14.4.7 2000/02/20 07:45:53 morsch
142 Bugs in Trigger part of BuildGeomemetry corrected (P.C)
144 Revision 1.14.4.6 2000/02/17 14:28:54 morsch
145 Trigger included into initialization and digitization
147 Revision 1.14.4.5 2000/02/15 10:02:58 morsch
148 Log messages of previous revisions added
150 Revision 1.14.4.2 2000/02/04 10:57:34 gosset
151 Z position of the chambers:
152 it was the Z position of the stations;
153 it is now really the Z position of the chambers.
154 !!!! WARNING: THE CALLS TO "AliMUONChamber::SetZPOS"
155 !!!! AND "AliMUONChamber::ZPosition"
156 !!!! HAVE TO BE CHANGED TO "AliMUONChamber::"SetZ"
157 !!!! AND "AliMUONChamber::Z"
159 Revision 1.14.4.3 2000/02/04 16:19:04 gosset
160 Correction for mis-spelling of NCH
162 Revision 1.14.4.4 2000/02/15 09:43:38 morsch
168 ///////////////////////////////////////////////
169 // Manager and hits classes for set:MUON //
170 ////////////////////////////////////////////////
174 #include <TRotMatrix.h>
175 #include <TGeometry.h>
181 #include <TObjArray.h>
183 #include <TParticle.h>
189 #include <TDirectory.h>
190 #include <TObjectTable.h>
195 #include "AliMUONHit.h"
196 #include "AliMUONPadHit.h"
197 #include "AliMUONDigit.h"
198 #include "AliMUONTransientDigit.h"
199 #include "AliMUONRawCluster.h"
200 #include "AliMUONLocalTrigger.h"
201 #include "AliMUONGlobalTrigger.h"
202 #include "AliMUONTriggerCircuit.h"
203 #include "AliHitMap.h"
204 #include "AliMUONHitMapA1.h"
205 #include "AliMUONChamberTrigger.h"
206 #include "AliMUONConstants.h"
207 #include "AliMUONClusterFinderVS.h"
208 #include "AliMUONTriggerDecision.h"
211 #include "AliMUONClusterInput.h"
212 #include "iostream.h"
213 #include "AliCallf77.h"
214 #include "AliConst.h"
216 // Defaults parameters for Z positions of chambers
217 // taken from values for "stations" in AliMUON::AliMUON
218 // const Float_t zch[7]={528, 690., 975., 1249., 1449., 1610, 1710.};
219 // and from array "dstation" in AliMUONv1::CreateGeometry
220 // Float_t dstation[5]={20., 20., 20, 20., 20.};
221 // for tracking chambers,
222 // according to (Z1 = zch - dstation) and (Z2 = zch + dstation)
223 // for the first and second chambers in the station, respectively,
224 // and from "DTPLANES" in AliMUONv1::CreateGeometry
225 // const Float_t DTPLANES = 15.;
226 // for trigger chambers,
227 // according to (Z1 = zch) and (Z2 = zch + DTPLANES)
228 // for the first and second chambers in the station, respectively
231 //___________________________________________
234 // Default Constructor
241 fTriggerCircuits = 0; // cp new design of AliMUONTriggerDecision
254 //___________________________________________
255 AliMUON::AliMUON(const char *name, const char *title)
256 : AliDetector(name,title)
260 <img src="gif/alimuon.gif">
264 fHits = new TClonesArray("AliMUONHit",1000);
265 gAlice->AddHitList(fHits);
266 fPadHits = new TClonesArray("AliMUONPadHit",10000);
270 fNdch = new Int_t[AliMUONConstants::NCh()];
272 fDchambers = new TObjArray(AliMUONConstants::NCh());
276 for (i=0; i<AliMUONConstants::NCh() ;i++) {
277 (*fDchambers)[i] = new TClonesArray("AliMUONDigit",10000);
281 fNrawch = new Int_t[AliMUONConstants::NTrackingCh()];
283 fRawClusters = new TObjArray(AliMUONConstants::NTrackingCh());
285 for (i=0; i<AliMUONConstants::NTrackingCh();i++) {
286 (*fRawClusters)[i] = new TClonesArray("AliMUONRawCluster",10000);
290 fGlobalTrigger = new TClonesArray("AliMUONGlobalTrigger",1);
292 fLocalTrigger = new TClonesArray("AliMUONLocalTrigger",234);
295 SetMarkerColor(kRed);
303 fChambers = new TObjArray(AliMUONConstants::NCh());
305 // Loop over stations
306 for (Int_t st = 0; st < AliMUONConstants::NCh() / 2; st++) {
307 // Loop over 2 chambers in the station
308 for (Int_t stCH = 0; stCH < 2; stCH++) {
311 // Default Parameters for Muon Tracking Stations
316 if (ch < AliMUONConstants::NTrackingCh()) {
317 (*fChambers)[ch] = new AliMUONChamber(ch);
319 (*fChambers)[ch] = new AliMUONChamberTrigger(ch);
322 AliMUONChamber* chamber = (AliMUONChamber*) (*fChambers)[ch];
325 // Default values for Z of chambers
326 chamber->SetZ(AliMUONConstants::DefaultChamberZ(ch));
328 chamber->InitGeo(AliMUONConstants::DefaultChamberZ(ch));
329 // Set chamber inner and outer radius to default
330 chamber->SetRInner(AliMUONConstants::Dmin(st)/2);
331 chamber->SetROuter(AliMUONConstants::Dmax(st)/2);
333 } // Chamber stCH (0, 1) in
334 } // Station st (0...)
347 // cp new design of AliMUONTriggerDecision
348 fTriggerCircuits = new TObjArray(AliMUONConstants::NTriggerCircuit());
349 for (Int_t circ=0; circ<AliMUONConstants::NTriggerCircuit(); circ++) {
350 (*fTriggerCircuits)[circ] = new AliMUONTriggerCircuit();
352 // cp new design of AliMUONTriggerDecision
356 //___________________________________________
357 AliMUON::AliMUON(const AliMUON& rMUON)
359 // Dummy copy constructor
367 printf("Calling AliMUON destructor !!!\n");
374 delete fGlobalTrigger;
377 delete fLocalTrigger;
380 for (i=0;i<AliMUONConstants::NCh();i++) {
381 delete (*fDchambers)[i];
386 for (i=0;i<AliMUONConstants::NTrackingCh();i++) {
387 delete (*fRawClusters)[i];
392 for (Int_t circ=0; circ<AliMUONConstants::NTriggerCircuit(); circ++) {
393 delete (*fTriggerCircuits)[circ];
395 delete fTriggerCircuits;
398 //___________________________________________
399 void AliMUON::AddHit(Int_t track, Int_t *vol, Float_t *hits)
401 TClonesArray &lhits = *fHits;
402 new(lhits[fNhits++]) AliMUONHit(fIshunt,track,vol,hits);
404 //___________________________________________
405 void AliMUON::AddPadHit(Int_t *clhits)
407 TClonesArray &lclusters = *fPadHits;
408 new(lclusters[fNPadHits++]) AliMUONPadHit(clhits);
410 //_____________________________________________________________________________
411 void AliMUON::AddDigits(Int_t id, Int_t *tracks, Int_t *charges, Int_t *digits)
414 // Add a MUON digit to the list
417 TClonesArray &ldigits = *((TClonesArray*)(*fDchambers)[id]);
418 new(ldigits[fNdch[id]++]) AliMUONDigit(tracks,charges,digits);
421 //_____________________________________________________________________________
422 void AliMUON::AddRawCluster(Int_t id, const AliMUONRawCluster& c)
425 // Add a MUON digit to the list
428 TClonesArray &lrawcl = *((TClonesArray*)(*fRawClusters)[id]);
429 new(lrawcl[fNrawch[id]++]) AliMUONRawCluster(c);
432 //___________________________________________
433 void AliMUON::AddGlobalTrigger(Int_t *singlePlus, Int_t *singleMinus,
435 Int_t *pairUnlike, Int_t *pairLike)
437 // add a MUON Global Trigger to the list (only one GlobalTrigger per event !)
438 TClonesArray &globalTrigger = *fGlobalTrigger;
439 new(globalTrigger[fNGlobalTrigger++])
440 AliMUONGlobalTrigger(singlePlus, singleMinus, singleUndef, pairUnlike,
443 //___________________________________________
444 void AliMUON::AddLocalTrigger(Int_t *localtr)
446 // add a MUON Local Trigger to the list
447 TClonesArray &localTrigger = *fLocalTrigger;
448 new(localTrigger[fNLocalTrigger++]) AliMUONLocalTrigger(localtr);
451 //___________________________________________
452 void AliMUON::BuildGeometry()
454 // Geometry for event display
455 for (Int_t i=0; i<7; i++) {
456 for (Int_t j=0; j<2; j++) {
458 this->Chamber(id-1).SegmentationModel(1)->Draw("eventdisplay");
463 //___________________________________________
464 Int_t AliMUON::DistancetoPrimitive(Int_t , Int_t )
469 //___________________________________________
470 void AliMUON::MakeBranch(Option_t* option)
472 // Create Tree branches for the MUON.
473 const Int_t kBufferSize = 4000;
475 sprintf(branchname,"%sCluster",GetName());
477 AliDetector::MakeBranch(option);
479 if (fPadHits && gAlice->TreeH()) {
480 gAlice->TreeH()->Branch(branchname,&fPadHits, kBufferSize);
481 printf("Making Branch %s for clusters\n",branchname);
484 // one branch for digits per chamber
487 for (i=0; i<AliMUONConstants::NCh() ;i++) {
488 sprintf(branchname,"%sDigits%d",GetName(),i+1);
490 if (fDchambers && gAlice->TreeD()) {
491 gAlice->TreeD()->Branch(branchname,&((*fDchambers)[i]), kBufferSize);
492 printf("Making Branch %s for digits in chamber %d\n",branchname,i+1);
496 printf("Make Branch - TreeR address %p\n",gAlice->TreeR());
498 // one branch for raw clusters per chamber
499 for (i=0; i<AliMUONConstants::NTrackingCh() ;i++) {
500 sprintf(branchname,"%sRawClusters%d",GetName(),i+1);
502 if (fRawClusters && gAlice->TreeR()) {
503 gAlice->TreeR()->Branch(branchname,&((*fRawClusters)[i]), kBufferSize);
504 printf("Making Branch %s for raw clusters in chamber %d\n",branchname,i+1);
508 // one branch for global trigger
509 sprintf(branchname,"%sGlobalTrigger",GetName());
510 if (fGlobalTrigger && gAlice->TreeR()) {
511 gAlice->TreeR()->Branch(branchname,&fGlobalTrigger,kBufferSize);
512 printf("Making Branch %s for Global Trigger\n",branchname);
514 // one branch for local trigger
515 sprintf(branchname,"%sLocalTrigger",GetName());
516 if (fLocalTrigger && gAlice->TreeR()) {
517 gAlice->TreeR()->Branch(branchname,&fLocalTrigger,kBufferSize);
518 printf("Making Branch %s for Local Trigger\n",branchname);
523 //___________________________________________
524 void AliMUON::SetTreeAddress()
526 // Set branch address for the Hits and Digits Tree.
528 AliDetector::SetTreeAddress();
531 TTree *treeH = gAlice->TreeH();
532 TTree *treeD = gAlice->TreeD();
533 TTree *treeR = gAlice->TreeR();
537 branch = treeH->GetBranch("MUONCluster");
538 if (branch) branch->SetAddress(&fPadHits);
543 for (int i=0; i<AliMUONConstants::NCh(); i++) {
544 sprintf(branchname,"%sDigits%d",GetName(),i+1);
546 branch = treeD->GetBranch(branchname);
547 if (branch) branch->SetAddress(&((*fDchambers)[i]));
552 // printf("SetTreeAddress --- treeR address %p \n",treeR);
555 for (int i=0; i<AliMUONConstants::NTrackingCh(); i++) {
556 sprintf(branchname,"%sRawClusters%d",GetName(),i+1);
558 branch = treeR->GetBranch(branchname);
559 if (branch) branch->SetAddress(&((*fRawClusters)[i]));
564 branch = treeR->GetBranch("MUONLocalTrigger");
565 if (branch) branch->SetAddress(&fLocalTrigger);
567 if (fGlobalTrigger) {
568 branch = treeR->GetBranch("MUONGlobalTrigger");
569 if (branch) branch->SetAddress(&fGlobalTrigger);
573 //___________________________________________
574 void AliMUON::ResetHits()
576 // Reset number of clusters and the cluster array for this detector
577 AliDetector::ResetHits();
579 if (fPadHits) fPadHits->Clear();
582 //____________________________________________
583 void AliMUON::ResetDigits()
586 // Reset number of digits and the digits array for this detector
588 for ( int i=0;i<AliMUONConstants::NCh();i++ ) {
589 if ((*fDchambers)[i]) ((TClonesArray*)(*fDchambers)[i])->Clear();
590 if (fNdch) fNdch[i]=0;
593 //____________________________________________
594 void AliMUON::ResetRawClusters()
597 // Reset number of raw clusters and the raw clust array for this detector
599 for ( int i=0;i<AliMUONConstants::NTrackingCh();i++ ) {
600 if ((*fRawClusters)[i]) ((TClonesArray*)(*fRawClusters)[i])->Clear();
601 if (fNrawch) fNrawch[i]=0;
605 //____________________________________________
606 void AliMUON::ResetTrigger()
608 // Reset Local and Global Trigger
610 if (fGlobalTrigger) fGlobalTrigger->Clear();
612 if (fLocalTrigger) fLocalTrigger->Clear();
615 //____________________________________________
616 void AliMUON::SetPadSize(Int_t id, Int_t isec, Float_t p1, Float_t p2)
618 // Set the pad size for chamber id and cathode isec
620 ((AliMUONChamber*) (*fChambers)[i]) ->SetPadSize(isec,p1,p2);
621 ((AliMUONChamber*) (*fChambers)[i+1])->SetPadSize(isec,p1,p2);
624 //___________________________________________
625 void AliMUON::SetChambersZ(const Float_t *Z)
627 // Set Z values for all chambers (tracking and trigger)
628 // from the array pointed to by "Z"
629 for (Int_t ch = 0; ch < AliMUONConstants::NCh(); ch++)
630 ((AliMUONChamber*) ((*fChambers)[ch]))->SetZ(Z[ch]);
634 //___________________________________________
635 void AliMUON::SetChambersZToDefault()
637 // Set Z values for all chambers (tracking and trigger)
639 SetChambersZ(AliMUONConstants::DefaultChamberZ());
643 //___________________________________________
644 void AliMUON::SetChargeSlope(Int_t id, Float_t p1)
646 // Set the inverse charge slope for chamber id
648 ((AliMUONChamber*) (*fChambers)[i])->SetChargeSlope(p1);
649 ((AliMUONChamber*) (*fChambers)[i+1])->SetChargeSlope(p1);
652 //___________________________________________
653 void AliMUON::SetChargeSpread(Int_t id, Float_t p1, Float_t p2)
655 // Set sigma of charge spread for chamber id
657 ((AliMUONChamber*) (*fChambers)[i])->SetChargeSpread(p1,p2);
658 ((AliMUONChamber*) (*fChambers)[i+1])->SetChargeSpread(p1,p2);
661 //___________________________________________
662 void AliMUON::SetSigmaIntegration(Int_t id, Float_t p1)
664 // Set integration limits for charge spread
666 ((AliMUONChamber*) (*fChambers)[i])->SetSigmaIntegration(p1);
667 ((AliMUONChamber*) (*fChambers)[i+1])->SetSigmaIntegration(p1);
670 //___________________________________________
671 void AliMUON::SetMaxAdc(Int_t id, Int_t p1)
673 // Set maximum number for ADCcounts (saturation)
675 ((AliMUONChamber*) (*fChambers)[i])->SetMaxAdc(p1);
676 ((AliMUONChamber*) (*fChambers)[i+1])->SetMaxAdc(p1);
679 //___________________________________________
680 void AliMUON::SetMaxStepGas(Float_t p1)
682 // Set stepsize in gas
686 //___________________________________________
687 void AliMUON::SetMaxStepAlu(Float_t p1)
689 // Set step size in Alu
693 //___________________________________________
694 void AliMUON::SetMaxDestepGas(Float_t p1)
696 // Set maximum step size in Gas
700 //___________________________________________
701 void AliMUON::SetMaxDestepAlu(Float_t p1)
703 // Set maximum step size in Alu
706 //___________________________________________
707 void AliMUON::SetAcceptance(Bool_t acc, Float_t angmin, Float_t angmax)
709 // Set acceptance cuts
711 fAccMin=angmin*TMath::Pi()/180;
712 fAccMax=angmax*TMath::Pi()/180;
715 for (Int_t st = 0; st < AliMUONConstants::NCh() / 2; st++) {
716 // Loop over 2 chambers in the station
717 for (Int_t stCH = 0; stCH < 2; stCH++) {
719 // Set chamber inner and outer radius according to acceptance cuts
720 Chamber(ch).SetRInner(AliMUONConstants::DefaultChamberZ(ch)*TMath::Tan(fAccMin));
721 Chamber(ch).SetROuter(AliMUONConstants::DefaultChamberZ(ch)*TMath::Tan(fAccMax));
726 //___________________________________________
727 void AliMUON::SetSegmentationModel(Int_t id, Int_t isec, AliSegmentation *segmentation)
729 // Set the segmentation for chamber id cathode isec
730 ((AliMUONChamber*) (*fChambers)[id])->SetSegmentationModel(isec, segmentation);
733 //___________________________________________
734 void AliMUON::SetResponseModel(Int_t id, AliMUONResponse *response)
736 // Set the response for chamber id
737 ((AliMUONChamber*) (*fChambers)[id])->SetResponseModel(response);
740 void AliMUON::SetReconstructionModel(Int_t id, AliMUONClusterFinderVS *reconst)
742 // Set ClusterFinder for chamber id
743 ((AliMUONChamber*) (*fChambers)[id])->SetReconstructionModel(reconst);
746 void AliMUON::SetNsec(Int_t id, Int_t nsec)
748 // Set number of segmented cathods for chamber id
749 ((AliMUONChamber*) (*fChambers)[id])->SetNsec(nsec);
753 //___________________________________________
757 void AliMUON::MakePadHits(Float_t xhit,Float_t yhit, Float_t zhit,
758 Float_t eloss, Float_t tof, Int_t idvol)
761 // Calls the charge disintegration method of the current chamber and adds
762 // the simulated cluster to the root treee
765 Float_t newclust[6][500];
770 // Integrated pulse height on chamber
776 // if (idvol == 6) printf("\n ->Disintegration %f %f %f", xhit, yhit, eloss );
779 ((AliMUONChamber*) (*fChambers)[idvol])
780 ->DisIntegration(eloss, tof, xhit, yhit, zhit, nnew, newclust);
782 // if (idvol == 6) printf("\n nnew %d \n", nnew);
785 for (Int_t i=0; i<nnew; i++) {
786 if (Int_t(newclust[3][i]) > 0) {
789 clhits[1] = Int_t(newclust[5][i]);
791 clhits[2] = Int_t(newclust[0][i]);
793 clhits[3] = Int_t(newclust[1][i]);
795 clhits[4] = Int_t(newclust[2][i]);
797 clhits[5] = Int_t(newclust[3][i]);
798 // Pad: chamber sector
799 clhits[6] = Int_t(newclust[4][i]);
806 //----------------------------------------------------------------------
808 void AliMUON::Digitise(Int_t nev,Int_t bgrEvent,Option_t *option,Option_t *opt,Text_t *filename)
810 // keep galice.root for signal and name differently the file for
811 // background when add! otherwise the track info for signal will be lost !
813 static Bool_t first=kTRUE;
815 char *addBackground = strstr(option,"Add");
818 AliMUONChamber* iChamber;
819 AliSegmentation* segmentation;
824 TObjArray *list=new TObjArray;
825 static TClonesArray *pAddress=0;
826 if(!pAddress) pAddress=new TClonesArray("TVector",1000);
829 AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
830 AliHitMap** hitMap= new AliHitMap* [AliMUONConstants::NCh()];
831 for (Int_t i=0; i<AliMUONConstants::NCh(); i++) {hitMap[i]=0;}
832 if (addBackground ) {
835 cout<<"filename"<<fFileName<<endl;
836 file=new TFile(fFileName);
837 cout<<"I have opened "<<fFileName<<" file "<<endl;
838 fHits2 = new TClonesArray("AliMUONHit",1000 );
839 fPadHits2 = new TClonesArray("AliMUONPadHit",10000);
844 // Get Hits Tree header from file
845 if(fHits2) fHits2->Clear();
846 if(fPadHits2) fPadHits2->Clear();
847 if(fTrH1) delete fTrH1;
851 sprintf(treeName,"TreeH%d",bgrEvent);
852 fTrH1 = (TTree*)gDirectory->Get(treeName);
853 //printf("fTrH1 %p of treename %s for event %d \n",fTrH1,treeName,bgrEvent);
856 printf("ERROR: cannot find Hits Tree for event:%d\n",bgrEvent);
858 // Set branch addresses
861 sprintf(branchname,"%s",GetName());
862 if (fTrH1 && fHits2) {
863 branch = fTrH1->GetBranch(branchname);
864 if (branch) branch->SetAddress(&fHits2);
866 if (fTrH1 && fPadHits2) {
867 branch = fTrH1->GetBranch("MUONCluster");
868 if (branch) branch->SetAddress(&fPadHits2);
871 //Int_t ntracks1 =(Int_t)fTrH1->GetEntries();
872 //printf("background - ntracks1 - %d\n",ntracks1);
875 // loop over cathodes
879 for (int icat=0; icat<2; icat++) {
881 Int_t * nmuon = new Int_t [AliMUONConstants::NCh()];
882 for (Int_t i =0; i<AliMUONConstants::NCh(); i++) {
883 iChamber=(AliMUONChamber*) (*fChambers)[i];
884 if (iChamber->Nsec()==1 && icat==1) {
887 segmentation=iChamber->SegmentationModel(icat+1);
889 hitMap[i] = new AliMUONHitMapA1(segmentation, list);
892 //printf("Start loop over tracks \n");
897 TTree *treeH = gAlice->TreeH();
898 Int_t ntracks =(Int_t) treeH->GetEntries();
902 Float_t ** xhit = new Float_t * [AliMUONConstants::NCh()];
903 for (jj=0; jj<AliMUONConstants::NCh(); jj++)
904 xhit[jj] = new Float_t[nmaxmuon];
905 Float_t ** yhit = new Float_t * [AliMUONConstants::NCh()];
906 for (jj=0; jj<AliMUONConstants::NCh(); jj++)
907 yhit[jj] = new Float_t[nmaxmuon];
909 for (Int_t track=0; track<ntracks; track++) {
911 treeH->GetEvent(track);
914 for(AliMUONHit* mHit=(AliMUONHit*)pMUON->FirstHit(-1);
916 mHit=(AliMUONHit*)pMUON->NextHit())
918 Int_t nch = mHit->fChamber-1; // chamber number
919 if (nch > AliMUONConstants::NCh()-1) continue;
920 // if (nch > 9) continue;
921 iChamber = &(pMUON->Chamber(nch));
925 if (mHit->fParticle == kMuonPlus
926 || mHit->fParticle == kMuonMinus) {
928 if (nmuon[nch] < nmaxmuon) {
929 xhit[nch][nmuon[nch]]=mHit->X();
930 yhit[nch][nmuon[nch]]=mHit->Y();
933 // ignore muon if too many compared to nmaxmuon
934 else printf("AliMUON::Digitize: nmuon %d ==> ignored\n",nmuon[nch]);
942 // Loop over pad hits
943 for (AliMUONPadHit* mPad=
944 (AliMUONPadHit*)pMUON->FirstPad(mHit,fPadHits);
946 mPad=(AliMUONPadHit*)pMUON->NextPad(fPadHits))
948 Int_t cathode = mPad->fCathode; // cathode number
949 Int_t ipx = mPad->fPadX; // pad number on X
950 Int_t ipy = mPad->fPadY; // pad number on Y
951 Int_t iqpad = Int_t(mPad->fQpad);// charge per pad
952 // printf("\n Pad: %d %d %d %d", ipx, ipy, cathode,nch);
956 if (cathode != (icat+1)) continue;
957 // fill the info array
958 // Float_t thex, they, thez;
959 segmentation=iChamber->SegmentationModel(cathode);
960 // segmentation->GetPadC(ipx,ipy,thex,they,thez);
961 // Float_t rpad=TMath::Sqrt(thex*thex+they*they);
962 // if (rpad < rmin || iqpad ==0 || rpad > rmax) continue;
964 new((*pAddress)[countadr++]) TVector(2);
965 TVector &trinfo=*((TVector*) (*pAddress)[countadr-1]);
966 trinfo(0)=(Float_t)track;
967 trinfo(1)=(Float_t)iqpad;
973 if (mHit->fParticle == kMuonPlus ||
974 mHit->fParticle == kMuonMinus) {
975 digits[4]=mPad->fHitNumber;
978 AliMUONTransientDigit* pdigit;
979 // build the list of fired pads and update the info
980 if (!hitMap[nch]->TestHit(ipx, ipy)) {
982 list->AddAtAndExpand(
983 new AliMUONTransientDigit(nch,digits),counter);
985 hitMap[nch]->SetHit(ipx, ipy, counter);
987 pdigit=(AliMUONTransientDigit*)list->At(list->GetLast());
989 TObjArray *trlist=(TObjArray*)pdigit->TrackList();
990 trlist->Add(&trinfo);
992 pdigit=(AliMUONTransientDigit*) hitMap[nch]->GetHit(ipx, ipy);
994 (*pdigit).fSignal+=iqpad;
995 (*pdigit).fPhysics+=iqpad;
996 // update list of tracks
997 TObjArray* trlist=(TObjArray*)pdigit->TrackList();
998 Int_t lastEntry=trlist->GetLast();
999 TVector *pTrack=(TVector*)trlist->At(lastEntry);
1000 TVector &ptrk=*pTrack;
1001 Int_t lastTrack = Int_t(ptrk(0));
1002 Int_t lastCharge = Int_t(ptrk(1));
1003 if (lastTrack==track) {
1005 trlist->RemoveAt(lastEntry);
1006 trinfo(0)=lastTrack;
1007 trinfo(1)=lastCharge;
1008 trlist->AddAt(&trinfo,lastEntry);
1010 trlist->Add(&trinfo);
1012 // check the track list
1013 Int_t nptracks=trlist->GetEntriesFast();
1015 for (Int_t tr=0;tr<nptracks;tr++) {
1016 TVector *ppTrack=(TVector*)trlist->At(tr);
1017 TVector &pptrk=*ppTrack;
1018 trk[tr] = Int_t(pptrk(0));
1019 chtrk[tr] = Int_t(pptrk(1));
1021 } // end if nptracks
1023 } //end loop over clusters
1027 // open the file with background
1029 if (addBackground) {
1030 ntracks =(Int_t)fTrH1->GetEntries();
1034 for (Int_t track=0; track<ntracks; track++) {
1036 if (fHits2) fHits2->Clear();
1037 if (fPadHits2) fPadHits2->Clear();
1039 fTrH1->GetEvent(track);
1043 for(int i=0;i<fHits2->GetEntriesFast();++i)
1045 mHit=(AliMUONHit*) (*fHits2)[i];
1046 Int_t nch = mHit->fChamber-1; // chamber number
1047 if (nch >9) continue;
1048 iChamber = &(pMUON->Chamber(nch));
1049 // Int_t rmin = (Int_t)iChamber->RInner();
1050 // Int_t rmax = (Int_t)iChamber->ROuter();
1051 Float_t xbgr=mHit->X();
1052 Float_t ybgr=mHit->Y();
1055 for (Int_t imuon =0; imuon < nmuon[nch]; imuon++) {
1056 Float_t dist= (xbgr-xhit[nch][imuon])*(xbgr-xhit[nch][imuon])
1057 +(ybgr-yhit[nch][imuon])*(ybgr-yhit[nch][imuon]);
1058 if (dist<100) cond=kTRUE;
1060 if (!cond) continue;
1063 // Loop over pad hits
1064 for (AliMUONPadHit* mPad=
1065 (AliMUONPadHit*)pMUON->FirstPad(mHit,fPadHits2);
1067 mPad=(AliMUONPadHit*)pMUON->NextPad(fPadHits2))
1069 // mPad = (AliMUONPadHit*) (*fPadHits2)[j];
1070 Int_t cathode = mPad->fCathode; // cathode number
1071 Int_t ipx = mPad->fPadX; // pad number on X
1072 Int_t ipy = mPad->fPadY; // pad number on Y
1073 Int_t iqpad = Int_t(mPad->fQpad);// charge per pad
1075 if (cathode != (icat+1)) continue;
1076 // printf("\n Pad: %d %d %d", ipx, ipy, cathode);
1078 // Float_t thex, they, thez;
1079 // segmentation=iChamber->SegmentationModel(cathode);
1080 // segmentation->GetPadC(ipx,ipy,thex,they,thez);
1081 // Float_t rpad=TMath::Sqrt(thex*thex+they*they);
1082 // if (rpad < rmin || iqpad ==0 || rpad > rmax) continue;
1083 new((*pAddress)[countadr++]) TVector(2);
1084 TVector &trinfo=*((TVector*) (*pAddress)[countadr-1]);
1085 trinfo(0)=-1; // tag background
1094 AliMUONTransientDigit* pdigit;
1095 // build the list of fired pads and update the info
1096 if (!hitMap[nch]->TestHit(ipx, ipy)) {
1097 list->AddAtAndExpand(new AliMUONTransientDigit(nch,digits),counter);
1099 hitMap[nch]->SetHit(ipx, ipy, counter);
1102 pdigit=(AliMUONTransientDigit*)list->At(list->GetLast());
1104 TObjArray *trlist=(TObjArray*)pdigit->
1106 trlist->Add(&trinfo);
1108 pdigit=(AliMUONTransientDigit*) hitMap[nch]->GetHit(ipx, ipy);
1110 (*pdigit).fSignal+=iqpad;
1112 // update list of tracks
1113 TObjArray* trlist=(TObjArray*)pdigit->
1115 Int_t lastEntry=trlist->GetLast();
1116 TVector *pTrack=(TVector*)trlist->
1118 TVector &ptrk=*pTrack;
1119 Int_t lastTrack=Int_t(ptrk(0));
1120 if (lastTrack==-1) {
1123 trlist->Add(&trinfo);
1125 // check the track list
1126 Int_t nptracks=trlist->GetEntriesFast();
1128 for (Int_t tr=0;tr<nptracks;tr++) {
1129 TVector *ppTrack=(TVector*)trlist->At(tr);
1130 TVector &pptrk=*ppTrack;
1131 trk[tr]=Int_t(pptrk(0));
1132 chtrk[tr]=Int_t(pptrk(1));
1134 } // end if nptracks
1136 } //end loop over clusters
1139 //Int_t nentr2=list->GetEntriesFast();
1140 //printf(" \n counter2, nentr2 %d %d \n",counter,nentr2);
1141 TTree *fAli=gAlice->TreeK();
1144 if (fAli) file =fAli->GetCurrentFile();
1146 } // if addBackground
1152 Int_t nentries=list->GetEntriesFast();
1154 for (Int_t nent=0;nent<nentries;nent++) {
1155 AliMUONTransientDigit *address=(AliMUONTransientDigit*)list->At(nent);
1156 if (address==0) continue;
1157 Int_t ich=address->fChamber;
1158 Int_t q=address->fSignal;
1159 iChamber=(AliMUONChamber*) (*fChambers)[ich];
1161 // Digit Response (noise, threshold, saturation, ...)
1162 // if (address->fPhysics !=0 ) address->fPhysics+=(Int_t)Noise;
1163 AliMUONResponse * response=iChamber->ResponseModel();
1164 q=response->DigitResponse(q);
1168 digits[0]=address->fPadX;
1169 digits[1]=address->fPadY;
1171 digits[3]=address->fPhysics;
1172 digits[4]=address->fHit;
1174 TObjArray* trlist=(TObjArray*)address->TrackList();
1175 Int_t nptracks=trlist->GetEntriesFast();
1176 //printf("nptracks, trlist %d %p\n",nptracks,trlist);
1178 // this was changed to accomodate the real number of tracks
1179 if (nptracks > 10) {
1180 cout<<"Attention - nptracks > 10 "<<nptracks<<endl;
1184 printf("Attention - nptracks > 2 %d \n",nptracks);
1185 printf("cat,ich,ix,iy,q %d %d %d %d %d \n",icat,ich,digits[0],digits[1],q);
1187 for (Int_t tr=0;tr<nptracks;tr++) {
1188 TVector *ppP=(TVector*)trlist->At(tr);
1189 if(!ppP ) printf("ppP - %p\n",ppP);
1191 tracks[tr]=Int_t(pp(0));
1192 charges[tr]=Int_t(pp(1));
1193 //printf("tracks, charges - %d %d\n",tracks[tr],charges[tr]);
1194 } //end loop over list of tracks for one pad
1195 // Sort list of tracks according to charge
1197 SortTracks(tracks,charges,nptracks);
1199 if (nptracks < 10 ) {
1200 for (Int_t i=nptracks; i<10; i++) {
1207 pMUON->AddDigits(ich,tracks,charges,digits);
1210 //cout<<"I'm out of the loops for digitisation"<<endl;
1211 // gAlice->GetEvent(nev);
1212 gAlice->TreeD()->Fill();
1213 pMUON->ResetDigits();
1217 for(Int_t ii=0;ii<AliMUONConstants::NCh();++ii) {
1225 } //end loop over cathodes
1228 sprintf(hname,"TreeD%d",nev);
1229 gAlice->TreeD()->Write(hname);
1231 gAlice->TreeD()->Reset();
1235 // gObjectTable->Print();
1238 void AliMUON::SortTracks(Int_t *tracks,Int_t *charges,Int_t ntr)
1241 // Sort the list of tracks contributing to a given digit
1242 // Only the 3 most significant tracks are acctually sorted
1246 // Loop over signals, only 3 times
1251 Int_t idx[3] = {-2,-2,-2};
1252 Int_t jch[3] = {-2,-2,-2};
1253 Int_t jtr[3] = {-2,-2,-2};
1256 if (ntr<3) imax=ntr;
1258 for(i=0;i<imax;i++){
1264 if((i == 1 && j == idx[i-1])
1265 ||(i == 2 && (j == idx[i-1] || j == idx[i-2]))) continue;
1267 if(charges[j] > qmax) {
1275 jch[i]=charges[jmax];
1276 jtr[i]=tracks[jmax];
1293 //___________________________________________
1294 void AliMUON::Trigger(Int_t nev){
1295 // call the Trigger Algorithm and fill TreeR
1297 Int_t singlePlus[3] = {0,0,0};
1298 Int_t singleMinus[3] = {0,0,0};
1299 Int_t singleUndef[3] = {0,0,0};
1300 Int_t pairUnlike[3] = {0,0,0};
1301 Int_t pairLike[3] = {0,0,0};
1304 AliMUONTriggerDecision* decision= new AliMUONTriggerDecision(1);
1305 decision->Trigger();
1306 decision->GetGlobalTrigger(singlePlus, singleMinus, singleUndef,
1307 pairUnlike, pairLike);
1308 // add a local trigger in the list
1309 AddGlobalTrigger(singlePlus, singleMinus, singleUndef, pairUnlike, pairLike);
1312 for (Int_t icirc=0; icirc<AliMUONConstants::NTriggerCircuit(); icirc++) {
1313 if(decision->GetITrigger(icirc)==1) {
1314 Int_t localtr[7]={0,0,0,0,0,0,0};
1315 Int_t loLpt[2]={0,0}; Int_t loHpt[2]={0,0}; Int_t loApt[2]={0,0};
1316 decision->GetLutOutput(icirc, loLpt, loHpt, loApt);
1318 localtr[1] = decision->GetStripX11(icirc);
1319 localtr[2] = decision->GetDev(icirc);
1320 localtr[3] = decision->GetStripY11(icirc);
1321 for (i=0; i<2; i++) { // convert the Lut output in 1 digit
1322 localtr[4] = localtr[4]+Int_t(loLpt[i]*TMath::Power(2,i));
1323 localtr[5] = localtr[5]+Int_t(loHpt[i]*TMath::Power(2,i));
1324 localtr[6] = localtr[6]+Int_t(loApt[i]*TMath::Power(2,i));
1326 AddLocalTrigger(localtr); // add a local trigger in the list
1331 gAlice->TreeR()->Fill();
1334 sprintf(hname,"TreeR%d",nev);
1335 gAlice->TreeR()->Write(hname);
1336 gAlice->TreeR()->Reset();
1337 printf("\n End of trigger for event %d", nev);
1341 //____________________________________________
1342 void AliMUON::FindClusters(Int_t nev,Int_t lastEntry)
1345 // Perform cluster finding
1347 TClonesArray *dig1, *dig2;
1349 dig1 = new TClonesArray("AliMUONDigit",1000);
1350 dig2 = new TClonesArray("AliMUONDigit",1000);
1351 AliMUONDigit *digit;
1353 // Loop on chambers and on cathode planes
1356 for (Int_t ich=0;ich<10;ich++) {
1357 AliMUONChamber* iChamber=(AliMUONChamber*) (*fChambers)[ich];
1358 AliMUONClusterFinderVS* rec = iChamber->ReconstructionModel();
1359 gAlice->ResetDigits();
1360 gAlice->TreeD()->GetEvent(lastEntry);
1361 TClonesArray *muonDigits = this->DigitsAddress(ich);
1362 ndig=muonDigits->GetEntriesFast();
1363 printf("\n 1 Found %d digits in %p %d", ndig, muonDigits,ich);
1364 TClonesArray &lhits1 = *dig1;
1366 for (k=0; k<ndig; k++) {
1367 digit=(AliMUONDigit*) muonDigits->UncheckedAt(k);
1368 if (rec->TestTrack(digit->fTracks[0]))
1369 new(lhits1[n++]) AliMUONDigit(*digit);
1371 gAlice->ResetDigits();
1372 gAlice->TreeD()->GetEvent(lastEntry+1);
1373 muonDigits = this->DigitsAddress(ich);
1374 ndig=muonDigits->GetEntriesFast();
1375 printf("\n 2 Found %d digits in %p %d", ndig, muonDigits, ich);
1376 TClonesArray &lhits2 = *dig2;
1379 for (k=0; k<ndig; k++) {
1380 digit= (AliMUONDigit*) muonDigits->UncheckedAt(k);
1381 if (rec->TestTrack(digit->fTracks[0]))
1382 new(lhits2[n++]) AliMUONDigit(*digit);
1386 AliMUONClusterInput::Instance()->SetDigits(ich, dig1, dig2);
1387 rec->FindRawClusters();
1392 gAlice->TreeR()->Fill();
1395 sprintf(hname,"TreeR%d",nev);
1396 gAlice->TreeR()->Write(hname);
1397 gAlice->TreeR()->Reset();
1398 printf("\n End of cluster finding for event %d", nev);
1402 //gObjectTable->Print();
1406 void AliMUON::Streamer(TBuffer &R__b)
1408 // Stream an object of class AliMUON.
1409 AliMUONChamber *iChamber;
1410 AliMUONTriggerCircuit *iTriggerCircuit;
1411 AliSegmentation *segmentation;
1412 AliMUONResponse *response;
1413 TClonesArray *digitsaddress;
1414 TClonesArray *rawcladdress;
1416 if (R__b.IsReading()) {
1417 Version_t R__v = R__b.ReadVersion(); if (R__v) { }
1418 AliDetector::Streamer(R__b);
1420 R__b >> fPadHits; // diff
1421 R__b >> fNLocalTrigger;
1422 R__b >> fLocalTrigger;
1423 R__b >> fNGlobalTrigger;
1424 R__b >> fGlobalTrigger;
1426 R__b >> fRawClusters;
1427 R__b.ReadArray(fNdch);
1428 R__b.ReadArray(fNrawch);
1433 R__b >> fTriggerCircuits;
1434 for (i =0; i<AliMUONConstants::NTriggerCircuit(); i++) {
1435 iTriggerCircuit=(AliMUONTriggerCircuit*) (*fTriggerCircuits)[i];
1436 iTriggerCircuit->Streamer(R__b);
1438 // Stream chamber related information
1439 for (i =0; i<AliMUONConstants::NCh(); i++) {
1440 iChamber=(AliMUONChamber*) (*fChambers)[i];
1441 iChamber->Streamer(R__b);
1442 if (iChamber->Nsec()==1) {
1443 segmentation=iChamber->SegmentationModel(1);
1445 segmentation->Streamer(R__b);
1447 segmentation=iChamber->SegmentationModel(1);
1449 segmentation->Streamer(R__b);
1451 segmentation=iChamber->SegmentationModel(2);
1452 segmentation->Streamer(R__b);
1454 response=iChamber->ResponseModel();
1456 response->Streamer(R__b);
1457 digitsaddress=(TClonesArray*) (*fDchambers)[i];
1458 digitsaddress->Streamer(R__b);
1459 if (i < AliMUONConstants::NTrackingCh()) {
1460 rawcladdress=(TClonesArray*) (*fRawClusters)[i];
1461 rawcladdress->Streamer(R__b);
1466 R__b.WriteVersion(AliMUON::IsA());
1467 AliDetector::Streamer(R__b);
1469 R__b << fPadHits; // diff
1470 R__b << fNLocalTrigger;
1471 R__b << fLocalTrigger;
1472 R__b << fNGlobalTrigger;
1473 R__b << fGlobalTrigger;
1475 R__b << fRawClusters;
1476 R__b.WriteArray(fNdch, AliMUONConstants::NCh());
1477 R__b.WriteArray(fNrawch, AliMUONConstants::NTrackingCh());
1484 R__b << fTriggerCircuits;
1485 for (i =0; i<AliMUONConstants::NTriggerCircuit(); i++) {
1486 iTriggerCircuit=(AliMUONTriggerCircuit*) (*fTriggerCircuits)[i];
1487 iTriggerCircuit->Streamer(R__b);
1489 for (i =0; i<AliMUONConstants::NCh(); i++) {
1490 iChamber=(AliMUONChamber*) (*fChambers)[i];
1491 iChamber->Streamer(R__b);
1492 if (iChamber->Nsec()==1) {
1493 segmentation=iChamber->SegmentationModel(1);
1495 segmentation->Streamer(R__b);
1497 segmentation=iChamber->SegmentationModel(1);
1499 segmentation->Streamer(R__b);
1500 segmentation=iChamber->SegmentationModel(2);
1502 segmentation->Streamer(R__b);
1504 response=iChamber->ResponseModel();
1506 response->Streamer(R__b);
1507 digitsaddress=(TClonesArray*) (*fDchambers)[i];
1508 digitsaddress->Streamer(R__b);
1509 if (i < AliMUONConstants::NTrackingCh()) {
1510 rawcladdress=(TClonesArray*) (*fRawClusters)[i];
1511 rawcladdress->Streamer(R__b);
1516 AliMUONPadHit* AliMUON::FirstPad(AliMUONHit* hit, TClonesArray *clusters)
1519 // Initialise the pad iterator
1520 // Return the address of the first padhit for hit
1521 TClonesArray *theClusters = clusters;
1522 Int_t nclust = theClusters->GetEntriesFast();
1523 if (nclust && hit->fPHlast > 0) {
1524 AliMUON::fMaxIterPad=hit->fPHlast;
1525 AliMUON::fCurIterPad=hit->fPHfirst;
1526 return (AliMUONPadHit*) clusters->UncheckedAt(AliMUON::fCurIterPad-1);
1532 AliMUONPadHit* AliMUON::NextPad(TClonesArray *clusters)
1534 // Get next pad (in iterator)
1536 AliMUON::fCurIterPad++;
1537 if (AliMUON::fCurIterPad <= AliMUON::fMaxIterPad) {
1538 return (AliMUONPadHit*) clusters->UncheckedAt(AliMUON::fCurIterPad-1);
1545 AliMUONRawCluster *AliMUON::RawCluster(Int_t ichamber, Int_t icathod, Int_t icluster)
1548 // Return rawcluster (icluster) for chamber ichamber and cathode icathod
1550 TClonesArray *muonRawCluster = RawClustAddress(ichamber);
1552 TTree *treeR = gAlice->TreeR();
1553 Int_t nent=(Int_t)treeR->GetEntries();
1554 treeR->GetEvent(nent-2+icathod-1);
1555 //treeR->GetEvent(icathod);
1556 //Int_t nrawcl = (Int_t)muonRawCluster->GetEntriesFast();
1558 AliMUONRawCluster * mRaw = (AliMUONRawCluster*)muonRawCluster->UncheckedAt(icluster);
1559 //printf("RawCluster _ nent nrawcl icluster mRaw %d %d %d%p\n",nent,nrawcl,icluster,mRaw);
1564 AliMUON& AliMUON::operator = (const AliMUON& rhs)