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.41 2000/12/21 22:12:40 morsch
18 Clean-up of coding rule violations,
20 Revision 1.40 2000/11/29 20:32:26 gosset
22 1. correction for array index out of bounds
23 2. one printout commented
25 Revision 1.39 2000/11/12 17:17:03 pcrochet
26 BuildGeometry of AliMUON for trigger chambers delegated to AliMUONSegmentationTriggerX (same strategy as for tracking chambers)
28 Revision 1.38 2000/11/06 09:20:43 morsch
29 AliMUON delegates part of BuildGeometry() to AliMUONSegmentation using the
30 Draw() method. This avoids code and parameter replication.
32 Revision 1.37 2000/10/26 09:53:37 pcrochet
33 put back trigger chambers in the display (there was a problem in buildgeometry)
35 Revision 1.36 2000/10/25 19:51:18 morsch
36 Correct x-position of chambers.
38 Revision 1.35 2000/10/24 19:46:21 morsch
39 BuildGeometry updated for slats in station 3-4.
41 Revision 1.34 2000/10/18 11:42:06 morsch
42 - AliMUONRawCluster contains z-position.
43 - Some clean-up of useless print statements during initialisations.
45 Revision 1.33 2000/10/09 14:01:57 morsch
46 Unused variables removed.
48 Revision 1.32 2000/10/06 09:08:10 morsch
49 Built geometry includes slat geometry for event display.
51 Revision 1.31 2000/10/02 21:28:08 fca
52 Removal of useless dependecies via forward declarations
54 Revision 1.30 2000/10/02 16:58:29 egangler
55 Cleaning of the code :
58 -> some useless includes removed or replaced by "class" statement
60 Revision 1.29 2000/07/28 13:49:38 morsch
61 SetAcceptance defines inner and outer chamber radii according to angular acceptance.
62 Can be used for simple acceptance studies.
64 Revision 1.28 2000/07/22 16:43:15 morsch
65 Same comment as before, but now done correctly I hope (sorry it's Saturday evening)
67 Revision 1.27 2000/07/22 16:36:50 morsch
68 Change order of indices in creation (new) of xhit and yhit
70 Revision 1.26 2000/07/03 11:54:57 morsch
71 AliMUONSegmentation and AliMUONHitMap have been replaced by AliSegmentation and AliHitMap in STEER
72 The methods GetPadIxy and GetPadXxy of AliMUONSegmentation have changed name to GetPadI and GetPadC.
74 Revision 1.25 2000/06/29 12:34:09 morsch
75 AliMUONSegmentation class has been made independent of AliMUONChamber. This makes
76 it usable with any other geometry class. The link to the object to which it belongs is
77 established via an index. This assumes that there exists a global geometry manager
78 from which the pointer to the parent object can be obtained (in our case gAlice).
80 Revision 1.24 2000/06/28 15:16:35 morsch
81 (1) Client code adapted to new method signatures in AliMUONSegmentation (see comments there)
82 to allow development of slat-muon chamber simulation and reconstruction code in the MUON
83 framework. The changes should have no side effects (mostly dummy arguments).
84 (2) Hit disintegration uses 3-dim hit coordinates to allow simulation
85 of chambers with overlapping modules (MakePadHits, Disintegration).
87 Revision 1.23 2000/06/28 12:19:17 morsch
88 More consequent seperation of global input data services (AliMUONClusterInput singleton) and the
89 cluster and hit reconstruction algorithms in AliMUONClusterFinderVS.
90 AliMUONClusterFinderVS becomes the base class for clustering and hit reconstruction.
91 It requires two cathode planes. Small modifications in the code will make it usable for
92 one cathode plane and, hence, more general (for test beam data).
93 AliMUONClusterFinder is now obsolete.
95 Revision 1.22 2000/06/28 08:06:10 morsch
96 Avoid global variables in AliMUONClusterFinderVS by seperating the input data for the fit from the
97 algorithmic part of the class. Input data resides inside the AliMUONClusterInput singleton.
98 It also naturally takes care of the TMinuit instance.
100 Revision 1.21 2000/06/27 08:54:41 morsch
101 Problems with on constant array sizes (in hitMap, nmuon, xhit, yhit) corrected.
103 Revision 1.20 2000/06/26 14:02:38 morsch
104 Add class AliMUONConstants with MUON specific constants using static memeber data and access methods.
106 Revision 1.19 2000/06/22 13:40:51 morsch
107 scope problem on HP, "i" declared once
108 pow changed to TMath::Power (PH, AM)
110 Revision 1.18 2000/06/15 07:58:48 morsch
111 Code from MUON-dev joined
113 Revision 1.14.4.17 2000/06/14 14:36:46 morsch
114 - add TriggerCircuit (PC)
115 - add GlobalTrigger and LocalTrigger and specific methods (PC)
117 Revision 1.14.4.16 2000/06/09 21:20:28 morsch
118 Most coding rule violations corrected
120 Revision 1.14.4.15 2000/05/02 09:54:32 morsch
121 RULE RN17 violations corrected
123 Revision 1.14.4.12 2000/04/26 12:25:02 morsch
124 Code revised by P. Crochet:
125 - Z position of TriggerChamber changed according to A.Tournaire Priv.Comm.
126 - ToF included in the method MakePadHits
127 - inner radius of flange between beam shielding and trigger corrected
128 - Trigger global volume updated (according to the new geometry)
130 Revision 1.14.4.11 2000/04/19 19:42:08 morsch
131 Some changes of variable names curing viols and methods concerning
132 correlated clusters removed.
134 Revision 1.14.4.10 2000/03/22 16:44:07 gosset
135 Memory leak suppressed in function Digitise:
136 p_adr->Delete() instead of Clear (I.Chevrot and A.Baldisseri)
138 Revision 1.14.4.9 2000/03/20 18:15:25 morsch
139 Positions of trigger chambers corrected (P.C.)
141 Revision 1.14.4.8 2000/02/21 15:38:01 morsch
142 Call to AddHitList introduced to make this version compatible with head.
144 Revision 1.14.4.7 2000/02/20 07:45:53 morsch
145 Bugs in Trigger part of BuildGeomemetry corrected (P.C)
147 Revision 1.14.4.6 2000/02/17 14:28:54 morsch
148 Trigger included into initialization and digitization
150 Revision 1.14.4.5 2000/02/15 10:02:58 morsch
151 Log messages of previous revisions added
153 Revision 1.14.4.2 2000/02/04 10:57:34 gosset
154 Z position of the chambers:
155 it was the Z position of the stations;
156 it is now really the Z position of the chambers.
157 !!!! WARNING: THE CALLS TO "AliMUONChamber::SetZPOS"
158 !!!! AND "AliMUONChamber::ZPosition"
159 !!!! HAVE TO BE CHANGED TO "AliMUONChamber::"SetZ"
160 !!!! AND "AliMUONChamber::Z"
162 Revision 1.14.4.3 2000/02/04 16:19:04 gosset
163 Correction for mis-spelling of NCH
165 Revision 1.14.4.4 2000/02/15 09:43:38 morsch
171 ///////////////////////////////////////////////
172 // Manager and hits classes for set:MUON //
173 ////////////////////////////////////////////////
177 #include <TRotMatrix.h>
178 #include <TGeometry.h>
184 #include <TObjArray.h>
186 #include <TParticle.h>
192 #include <TDirectory.h>
193 #include <TObjectTable.h>
198 #include "AliMUONHit.h"
199 #include "AliMUONPadHit.h"
200 #include "AliMUONDigit.h"
201 #include "AliMUONTransientDigit.h"
202 #include "AliMUONRawCluster.h"
203 #include "AliMUONLocalTrigger.h"
204 #include "AliMUONGlobalTrigger.h"
205 #include "AliMUONTriggerCircuit.h"
206 #include "AliHitMap.h"
207 #include "AliMUONHitMapA1.h"
208 #include "AliMUONChamberTrigger.h"
209 #include "AliMUONConstants.h"
210 #include "AliMUONClusterFinderVS.h"
211 #include "AliMUONTriggerDecision.h"
214 #include "AliMUONClusterInput.h"
215 #include "iostream.h"
216 #include "AliCallf77.h"
217 #include "AliConst.h"
219 // Defaults parameters for Z positions of chambers
220 // taken from values for "stations" in AliMUON::AliMUON
221 // const Float_t zch[7]={528, 690., 975., 1249., 1449., 1610, 1710.};
222 // and from array "dstation" in AliMUONv1::CreateGeometry
223 // Float_t dstation[5]={20., 20., 20, 20., 20.};
224 // for tracking chambers,
225 // according to (Z1 = zch - dstation) and (Z2 = zch + dstation)
226 // for the first and second chambers in the station, respectively,
227 // and from "DTPLANES" in AliMUONv1::CreateGeometry
228 // const Float_t DTPLANES = 15.;
229 // for trigger chambers,
230 // according to (Z1 = zch) and (Z2 = zch + DTPLANES)
231 // for the first and second chambers in the station, respectively
234 //___________________________________________
237 // Default Constructor
244 fTriggerCircuits = 0; // cp new design of AliMUONTriggerDecision
257 //___________________________________________
258 AliMUON::AliMUON(const char *name, const char *title)
259 : AliDetector(name,title)
263 <img src="gif/alimuon.gif">
267 fHits = new TClonesArray("AliMUONHit",1000);
268 gAlice->AddHitList(fHits);
269 fPadHits = new TClonesArray("AliMUONPadHit",10000);
273 fNdch = new Int_t[AliMUONConstants::NCh()];
275 fDchambers = new TObjArray(AliMUONConstants::NCh());
279 for (i=0; i<AliMUONConstants::NCh() ;i++) {
280 (*fDchambers)[i] = new TClonesArray("AliMUONDigit",10000);
284 fNrawch = new Int_t[AliMUONConstants::NTrackingCh()];
286 fRawClusters = new TObjArray(AliMUONConstants::NTrackingCh());
288 for (i=0; i<AliMUONConstants::NTrackingCh();i++) {
289 (*fRawClusters)[i] = new TClonesArray("AliMUONRawCluster",10000);
293 fGlobalTrigger = new TClonesArray("AliMUONGlobalTrigger",1);
295 fLocalTrigger = new TClonesArray("AliMUONLocalTrigger",234);
298 SetMarkerColor(kRed);
306 fChambers = new TObjArray(AliMUONConstants::NCh());
308 // Loop over stations
309 for (Int_t st = 0; st < AliMUONConstants::NCh() / 2; st++) {
310 // Loop over 2 chambers in the station
311 for (Int_t stCH = 0; stCH < 2; stCH++) {
314 // Default Parameters for Muon Tracking Stations
319 if (ch < AliMUONConstants::NTrackingCh()) {
320 (*fChambers)[ch] = new AliMUONChamber(ch);
322 (*fChambers)[ch] = new AliMUONChamberTrigger(ch);
325 AliMUONChamber* chamber = (AliMUONChamber*) (*fChambers)[ch];
328 // Default values for Z of chambers
329 chamber->SetZ(AliMUONConstants::DefaultChamberZ(ch));
331 chamber->InitGeo(AliMUONConstants::DefaultChamberZ(ch));
332 // Set chamber inner and outer radius to default
333 chamber->SetRInner(AliMUONConstants::Dmin(st)/2);
334 chamber->SetROuter(AliMUONConstants::Dmax(st)/2);
336 } // Chamber stCH (0, 1) in
337 } // Station st (0...)
350 // cp new design of AliMUONTriggerDecision
351 fTriggerCircuits = new TObjArray(AliMUONConstants::NTriggerCircuit());
352 for (Int_t circ=0; circ<AliMUONConstants::NTriggerCircuit(); circ++) {
353 (*fTriggerCircuits)[circ] = new AliMUONTriggerCircuit();
355 // cp new design of AliMUONTriggerDecision
359 //___________________________________________
360 AliMUON::AliMUON(const AliMUON& rMUON)
362 // Dummy copy constructor
370 printf("Calling AliMUON destructor !!!\n");
382 if (fTriggerCircuits){
383 fTriggerCircuits->Delete();
384 delete fTriggerCircuits;
388 fDchambers->Delete();
393 fRawClusters->Delete();
396 for (i=0;i<AliMUONConstants::NTrackingCh();i++) {
400 // Delete TClonesArrays
408 fGlobalTrigger->Delete();
409 delete fGlobalTrigger;
414 fLocalTrigger->Delete();
415 delete fLocalTrigger;
434 // Delete hits tree for background event
442 //___________________________________________
443 void AliMUON::AddHit(Int_t track, Int_t *vol, Float_t *hits)
445 TClonesArray &lhits = *fHits;
446 new(lhits[fNhits++]) AliMUONHit(fIshunt,track,vol,hits);
448 //___________________________________________
449 void AliMUON::AddPadHit(Int_t *clhits)
451 TClonesArray &lclusters = *fPadHits;
452 new(lclusters[fNPadHits++]) AliMUONPadHit(clhits);
454 //_____________________________________________________________________________
455 void AliMUON::AddDigits(Int_t id, Int_t *tracks, Int_t *charges, Int_t *digits)
458 // Add a MUON digit to the list
461 TClonesArray &ldigits = *((TClonesArray*)(*fDchambers)[id]);
462 new(ldigits[fNdch[id]++]) AliMUONDigit(tracks,charges,digits);
465 //_____________________________________________________________________________
466 void AliMUON::AddRawCluster(Int_t id, const AliMUONRawCluster& c)
469 // Add a MUON digit to the list
472 TClonesArray &lrawcl = *((TClonesArray*)(*fRawClusters)[id]);
473 new(lrawcl[fNrawch[id]++]) AliMUONRawCluster(c);
476 //___________________________________________
477 void AliMUON::AddGlobalTrigger(Int_t *singlePlus, Int_t *singleMinus,
479 Int_t *pairUnlike, Int_t *pairLike)
481 // add a MUON Global Trigger to the list (only one GlobalTrigger per event !)
482 TClonesArray &globalTrigger = *fGlobalTrigger;
483 new(globalTrigger[fNGlobalTrigger++])
484 AliMUONGlobalTrigger(singlePlus, singleMinus, singleUndef, pairUnlike,
487 //___________________________________________
488 void AliMUON::AddLocalTrigger(Int_t *localtr)
490 // add a MUON Local Trigger to the list
491 TClonesArray &localTrigger = *fLocalTrigger;
492 new(localTrigger[fNLocalTrigger++]) AliMUONLocalTrigger(localtr);
495 //___________________________________________
496 void AliMUON::BuildGeometry()
498 // Geometry for event display
499 for (Int_t i=0; i<7; i++) {
500 for (Int_t j=0; j<2; j++) {
502 this->Chamber(id-1).SegmentationModel(1)->Draw("eventdisplay");
507 //___________________________________________
508 Int_t AliMUON::DistancetoPrimitive(Int_t , Int_t )
513 //___________________________________________
514 void AliMUON::MakeBranch(Option_t* option)
516 // Create Tree branches for the MUON.
517 const Int_t kBufferSize = 4000;
519 sprintf(branchname,"%sCluster",GetName());
521 AliDetector::MakeBranch(option);
523 if (fPadHits && gAlice->TreeH()) {
524 gAlice->TreeH()->Branch(branchname,&fPadHits, kBufferSize);
525 printf("Making Branch %s for clusters\n",branchname);
528 // one branch for digits per chamber
531 for (i=0; i<AliMUONConstants::NCh() ;i++) {
532 sprintf(branchname,"%sDigits%d",GetName(),i+1);
534 if (fDchambers && gAlice->TreeD()) {
535 gAlice->TreeD()->Branch(branchname,&((*fDchambers)[i]), kBufferSize);
536 printf("Making Branch %s for digits in chamber %d\n",branchname,i+1);
540 printf("Make Branch - TreeR address %p\n",gAlice->TreeR());
542 // one branch for raw clusters per chamber
543 for (i=0; i<AliMUONConstants::NTrackingCh() ;i++) {
544 sprintf(branchname,"%sRawClusters%d",GetName(),i+1);
546 if (fRawClusters && gAlice->TreeR()) {
547 gAlice->TreeR()->Branch(branchname,&((*fRawClusters)[i]), kBufferSize);
548 printf("Making Branch %s for raw clusters in chamber %d\n",branchname,i+1);
552 // one branch for global trigger
553 sprintf(branchname,"%sGlobalTrigger",GetName());
554 if (fGlobalTrigger && gAlice->TreeR()) {
555 gAlice->TreeR()->Branch(branchname,&fGlobalTrigger,kBufferSize);
556 printf("Making Branch %s for Global Trigger\n",branchname);
558 // one branch for local trigger
559 sprintf(branchname,"%sLocalTrigger",GetName());
560 if (fLocalTrigger && gAlice->TreeR()) {
561 gAlice->TreeR()->Branch(branchname,&fLocalTrigger,kBufferSize);
562 printf("Making Branch %s for Local Trigger\n",branchname);
567 //___________________________________________
568 void AliMUON::SetTreeAddress()
570 // Set branch address for the Hits and Digits Tree.
572 AliDetector::SetTreeAddress();
575 TTree *treeH = gAlice->TreeH();
576 TTree *treeD = gAlice->TreeD();
577 TTree *treeR = gAlice->TreeR();
581 branch = treeH->GetBranch("MUONCluster");
582 if (branch) branch->SetAddress(&fPadHits);
587 for (int i=0; i<AliMUONConstants::NCh(); i++) {
588 sprintf(branchname,"%sDigits%d",GetName(),i+1);
590 branch = treeD->GetBranch(branchname);
591 if (branch) branch->SetAddress(&((*fDchambers)[i]));
596 // printf("SetTreeAddress --- treeR address %p \n",treeR);
599 for (int i=0; i<AliMUONConstants::NTrackingCh(); i++) {
600 sprintf(branchname,"%sRawClusters%d",GetName(),i+1);
602 branch = treeR->GetBranch(branchname);
603 if (branch) branch->SetAddress(&((*fRawClusters)[i]));
608 branch = treeR->GetBranch("MUONLocalTrigger");
609 if (branch) branch->SetAddress(&fLocalTrigger);
611 if (fGlobalTrigger) {
612 branch = treeR->GetBranch("MUONGlobalTrigger");
613 if (branch) branch->SetAddress(&fGlobalTrigger);
617 //___________________________________________
618 void AliMUON::ResetHits()
620 // Reset number of clusters and the cluster array for this detector
621 AliDetector::ResetHits();
623 if (fPadHits) fPadHits->Clear();
626 //____________________________________________
627 void AliMUON::ResetDigits()
630 // Reset number of digits and the digits array for this detector
632 for ( int i=0;i<AliMUONConstants::NCh();i++ ) {
633 if ((*fDchambers)[i]) ((TClonesArray*)(*fDchambers)[i])->Clear();
634 if (fNdch) fNdch[i]=0;
637 //____________________________________________
638 void AliMUON::ResetRawClusters()
641 // Reset number of raw clusters and the raw clust array for this detector
643 for ( int i=0;i<AliMUONConstants::NTrackingCh();i++ ) {
644 if ((*fRawClusters)[i]) ((TClonesArray*)(*fRawClusters)[i])->Clear();
645 if (fNrawch) fNrawch[i]=0;
649 //____________________________________________
650 void AliMUON::ResetTrigger()
652 // Reset Local and Global Trigger
654 if (fGlobalTrigger) fGlobalTrigger->Clear();
656 if (fLocalTrigger) fLocalTrigger->Clear();
659 //____________________________________________
660 void AliMUON::SetPadSize(Int_t id, Int_t isec, Float_t p1, Float_t p2)
662 // Set the pad size for chamber id and cathode isec
664 ((AliMUONChamber*) (*fChambers)[i]) ->SetPadSize(isec,p1,p2);
665 ((AliMUONChamber*) (*fChambers)[i+1])->SetPadSize(isec,p1,p2);
668 //___________________________________________
669 void AliMUON::SetChambersZ(const Float_t *Z)
671 // Set Z values for all chambers (tracking and trigger)
672 // from the array pointed to by "Z"
673 for (Int_t ch = 0; ch < AliMUONConstants::NCh(); ch++)
674 ((AliMUONChamber*) ((*fChambers)[ch]))->SetZ(Z[ch]);
678 //___________________________________________
679 void AliMUON::SetChambersZToDefault()
681 // Set Z values for all chambers (tracking and trigger)
683 SetChambersZ(AliMUONConstants::DefaultChamberZ());
687 //___________________________________________
688 void AliMUON::SetChargeSlope(Int_t id, Float_t p1)
690 // Set the inverse charge slope for chamber id
692 ((AliMUONChamber*) (*fChambers)[i])->SetChargeSlope(p1);
693 ((AliMUONChamber*) (*fChambers)[i+1])->SetChargeSlope(p1);
696 //___________________________________________
697 void AliMUON::SetChargeSpread(Int_t id, Float_t p1, Float_t p2)
699 // Set sigma of charge spread for chamber id
701 ((AliMUONChamber*) (*fChambers)[i])->SetChargeSpread(p1,p2);
702 ((AliMUONChamber*) (*fChambers)[i+1])->SetChargeSpread(p1,p2);
705 //___________________________________________
706 void AliMUON::SetSigmaIntegration(Int_t id, Float_t p1)
708 // Set integration limits for charge spread
710 ((AliMUONChamber*) (*fChambers)[i])->SetSigmaIntegration(p1);
711 ((AliMUONChamber*) (*fChambers)[i+1])->SetSigmaIntegration(p1);
714 //___________________________________________
715 void AliMUON::SetMaxAdc(Int_t id, Int_t p1)
717 // Set maximum number for ADCcounts (saturation)
719 ((AliMUONChamber*) (*fChambers)[i])->SetMaxAdc(p1);
720 ((AliMUONChamber*) (*fChambers)[i+1])->SetMaxAdc(p1);
723 //___________________________________________
724 void AliMUON::SetMaxStepGas(Float_t p1)
726 // Set stepsize in gas
730 //___________________________________________
731 void AliMUON::SetMaxStepAlu(Float_t p1)
733 // Set step size in Alu
737 //___________________________________________
738 void AliMUON::SetMaxDestepGas(Float_t p1)
740 // Set maximum step size in Gas
744 //___________________________________________
745 void AliMUON::SetMaxDestepAlu(Float_t p1)
747 // Set maximum step size in Alu
750 //___________________________________________
751 void AliMUON::SetAcceptance(Bool_t acc, Float_t angmin, Float_t angmax)
753 // Set acceptance cuts
755 fAccMin=angmin*TMath::Pi()/180;
756 fAccMax=angmax*TMath::Pi()/180;
759 for (Int_t st = 0; st < AliMUONConstants::NCh() / 2; st++) {
760 // Loop over 2 chambers in the station
761 for (Int_t stCH = 0; stCH < 2; stCH++) {
763 // Set chamber inner and outer radius according to acceptance cuts
764 Chamber(ch).SetRInner(AliMUONConstants::DefaultChamberZ(ch)*TMath::Tan(fAccMin));
765 Chamber(ch).SetROuter(AliMUONConstants::DefaultChamberZ(ch)*TMath::Tan(fAccMax));
770 //___________________________________________
771 void AliMUON::SetSegmentationModel(Int_t id, Int_t isec, AliSegmentation *segmentation)
773 // Set the segmentation for chamber id cathode isec
774 ((AliMUONChamber*) (*fChambers)[id])->SetSegmentationModel(isec, segmentation);
777 //___________________________________________
778 void AliMUON::SetResponseModel(Int_t id, AliMUONResponse *response)
780 // Set the response for chamber id
781 ((AliMUONChamber*) (*fChambers)[id])->SetResponseModel(response);
784 void AliMUON::SetReconstructionModel(Int_t id, AliMUONClusterFinderVS *reconst)
786 // Set ClusterFinder for chamber id
787 ((AliMUONChamber*) (*fChambers)[id])->SetReconstructionModel(reconst);
790 void AliMUON::SetNsec(Int_t id, Int_t nsec)
792 // Set number of segmented cathods for chamber id
793 ((AliMUONChamber*) (*fChambers)[id])->SetNsec(nsec);
797 //___________________________________________
801 void AliMUON::MakePadHits(Float_t xhit,Float_t yhit, Float_t zhit,
802 Float_t eloss, Float_t tof, Int_t idvol)
805 // Calls the charge disintegration method of the current chamber and adds
806 // the simulated cluster to the root treee
809 Float_t newclust[6][500];
814 // Integrated pulse height on chamber
820 // if (idvol == 6) printf("\n ->Disintegration %f %f %f", xhit, yhit, eloss );
823 ((AliMUONChamber*) (*fChambers)[idvol])
824 ->DisIntegration(eloss, tof, xhit, yhit, zhit, nnew, newclust);
826 // if (idvol == 6) printf("\n nnew %d \n", nnew);
829 for (Int_t i=0; i<nnew; i++) {
830 if (Int_t(newclust[3][i]) > 0) {
833 clhits[1] = Int_t(newclust[5][i]);
835 clhits[2] = Int_t(newclust[0][i]);
837 clhits[3] = Int_t(newclust[1][i]);
839 clhits[4] = Int_t(newclust[2][i]);
841 clhits[5] = Int_t(newclust[3][i]);
842 // Pad: chamber sector
843 clhits[6] = Int_t(newclust[4][i]);
850 //----------------------------------------------------------------------
852 void AliMUON::Digitise(Int_t nev,Int_t bgrEvent,Option_t *option,Option_t *opt,Text_t *filename)
854 // keep galice.root for signal and name differently the file for
855 // background when add! otherwise the track info for signal will be lost !
857 static Bool_t first=kTRUE;
859 char *addBackground = strstr(option,"Add");
862 AliMUONChamber* iChamber;
863 AliSegmentation* segmentation;
868 TObjArray *list=new TObjArray;
869 static TClonesArray *pAddress=0;
870 if(!pAddress) pAddress=new TClonesArray("TVector",1000);
873 AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
874 AliHitMap** hitMap= new AliHitMap* [AliMUONConstants::NCh()];
875 for (Int_t i=0; i<AliMUONConstants::NCh(); i++) {hitMap[i]=0;}
876 if (addBackground ) {
879 cout<<"filename"<<fFileName<<endl;
880 file=new TFile(fFileName);
881 cout<<"I have opened "<<fFileName<<" file "<<endl;
882 fHits2 = new TClonesArray("AliMUONHit",1000 );
883 fPadHits2 = new TClonesArray("AliMUONPadHit",10000);
888 // Get Hits Tree header from file
889 if(fHits2) fHits2->Clear();
890 if(fPadHits2) fPadHits2->Clear();
891 if(fTrH1) delete fTrH1;
895 sprintf(treeName,"TreeH%d",bgrEvent);
896 fTrH1 = (TTree*)gDirectory->Get(treeName);
897 //printf("fTrH1 %p of treename %s for event %d \n",fTrH1,treeName,bgrEvent);
900 printf("ERROR: cannot find Hits Tree for event:%d\n",bgrEvent);
902 // Set branch addresses
905 sprintf(branchname,"%s",GetName());
906 if (fTrH1 && fHits2) {
907 branch = fTrH1->GetBranch(branchname);
908 if (branch) branch->SetAddress(&fHits2);
910 if (fTrH1 && fPadHits2) {
911 branch = fTrH1->GetBranch("MUONCluster");
912 if (branch) branch->SetAddress(&fPadHits2);
915 //Int_t ntracks1 =(Int_t)fTrH1->GetEntries();
916 //printf("background - ntracks1 - %d\n",ntracks1);
919 // loop over cathodes
923 for (int icat=0; icat<2; icat++) {
925 Int_t * nmuon = new Int_t [AliMUONConstants::NCh()];
926 for (Int_t i =0; i<AliMUONConstants::NCh(); i++) {
927 iChamber=(AliMUONChamber*) (*fChambers)[i];
928 if (iChamber->Nsec()==1 && icat==1) {
931 segmentation=iChamber->SegmentationModel(icat+1);
933 hitMap[i] = new AliMUONHitMapA1(segmentation, list);
936 //printf("Start loop over tracks \n");
941 TTree *treeH = gAlice->TreeH();
942 Int_t ntracks =(Int_t) treeH->GetEntries();
946 Float_t ** xhit = new Float_t * [AliMUONConstants::NCh()];
947 for (jj=0; jj<AliMUONConstants::NCh(); jj++)
948 xhit[jj] = new Float_t[nmaxmuon];
949 Float_t ** yhit = new Float_t * [AliMUONConstants::NCh()];
950 for (jj=0; jj<AliMUONConstants::NCh(); jj++)
951 yhit[jj] = new Float_t[nmaxmuon];
953 for (Int_t track=0; track<ntracks; track++) {
955 treeH->GetEvent(track);
958 for(AliMUONHit* mHit=(AliMUONHit*)pMUON->FirstHit(-1);
960 mHit=(AliMUONHit*)pMUON->NextHit())
962 Int_t nch = mHit->fChamber-1; // chamber number
963 if (nch > AliMUONConstants::NCh()-1) continue;
964 // if (nch > 9) continue;
965 iChamber = &(pMUON->Chamber(nch));
969 if (mHit->fParticle == kMuonPlus
970 || mHit->fParticle == kMuonMinus) {
972 if (nmuon[nch] < nmaxmuon) {
973 xhit[nch][nmuon[nch]]=mHit->X();
974 yhit[nch][nmuon[nch]]=mHit->Y();
977 // ignore muon if too many compared to nmaxmuon
978 else printf("AliMUON::Digitize: nmuon %d ==> ignored\n",nmuon[nch]);
986 // Loop over pad hits
987 for (AliMUONPadHit* mPad=
988 (AliMUONPadHit*)pMUON->FirstPad(mHit,fPadHits);
990 mPad=(AliMUONPadHit*)pMUON->NextPad(fPadHits))
992 Int_t cathode = mPad->fCathode; // cathode number
993 Int_t ipx = mPad->fPadX; // pad number on X
994 Int_t ipy = mPad->fPadY; // pad number on Y
995 Int_t iqpad = Int_t(mPad->fQpad);// charge per pad
996 // printf("\n Pad: %d %d %d %d", ipx, ipy, cathode,nch);
1000 if (cathode != (icat+1)) continue;
1001 // fill the info array
1002 // Float_t thex, they, thez;
1003 segmentation=iChamber->SegmentationModel(cathode);
1004 // segmentation->GetPadC(ipx,ipy,thex,they,thez);
1005 // Float_t rpad=TMath::Sqrt(thex*thex+they*they);
1006 // if (rpad < rmin || iqpad ==0 || rpad > rmax) continue;
1008 new((*pAddress)[countadr++]) TVector(2);
1009 TVector &trinfo=*((TVector*) (*pAddress)[countadr-1]);
1010 trinfo(0)=(Float_t)track;
1011 trinfo(1)=(Float_t)iqpad;
1017 if (mHit->fParticle == kMuonPlus ||
1018 mHit->fParticle == kMuonMinus) {
1019 digits[4]=mPad->fHitNumber;
1020 } else digits[4]=-1;
1022 AliMUONTransientDigit* pdigit;
1023 // build the list of fired pads and update the info
1024 if (!hitMap[nch]->TestHit(ipx, ipy)) {
1026 list->AddAtAndExpand(
1027 new AliMUONTransientDigit(nch,digits),counter);
1029 hitMap[nch]->SetHit(ipx, ipy, counter);
1031 pdigit=(AliMUONTransientDigit*)list->At(list->GetLast());
1033 TObjArray *trlist=(TObjArray*)pdigit->TrackList();
1034 trlist->Add(&trinfo);
1036 pdigit=(AliMUONTransientDigit*) hitMap[nch]->GetHit(ipx, ipy);
1038 (*pdigit).fSignal+=iqpad;
1039 (*pdigit).fPhysics+=iqpad;
1040 // update list of tracks
1041 TObjArray* trlist=(TObjArray*)pdigit->TrackList();
1042 Int_t lastEntry=trlist->GetLast();
1043 TVector *pTrack=(TVector*)trlist->At(lastEntry);
1044 TVector &ptrk=*pTrack;
1045 Int_t lastTrack = Int_t(ptrk(0));
1046 Int_t lastCharge = Int_t(ptrk(1));
1047 if (lastTrack==track) {
1049 trlist->RemoveAt(lastEntry);
1050 trinfo(0)=lastTrack;
1051 trinfo(1)=lastCharge;
1052 trlist->AddAt(&trinfo,lastEntry);
1054 trlist->Add(&trinfo);
1056 // check the track list
1057 Int_t nptracks=trlist->GetEntriesFast();
1059 for (Int_t tr=0;tr<nptracks;tr++) {
1060 TVector *ppTrack=(TVector*)trlist->At(tr);
1061 TVector &pptrk=*ppTrack;
1062 trk[tr] = Int_t(pptrk(0));
1063 chtrk[tr] = Int_t(pptrk(1));
1065 } // end if nptracks
1067 } //end loop over clusters
1071 // open the file with background
1073 if (addBackground) {
1074 ntracks =(Int_t)fTrH1->GetEntries();
1078 for (Int_t track=0; track<ntracks; track++) {
1080 if (fHits2) fHits2->Clear();
1081 if (fPadHits2) fPadHits2->Clear();
1083 fTrH1->GetEvent(track);
1087 for(int i=0;i<fHits2->GetEntriesFast();++i)
1089 mHit=(AliMUONHit*) (*fHits2)[i];
1090 Int_t nch = mHit->fChamber-1; // chamber number
1091 if (nch >9) continue;
1092 iChamber = &(pMUON->Chamber(nch));
1093 // Int_t rmin = (Int_t)iChamber->RInner();
1094 // Int_t rmax = (Int_t)iChamber->ROuter();
1095 Float_t xbgr=mHit->X();
1096 Float_t ybgr=mHit->Y();
1099 for (Int_t imuon =0; imuon < nmuon[nch]; imuon++) {
1100 Float_t dist= (xbgr-xhit[nch][imuon])*(xbgr-xhit[nch][imuon])
1101 +(ybgr-yhit[nch][imuon])*(ybgr-yhit[nch][imuon]);
1102 if (dist<100) cond=kTRUE;
1104 if (!cond) continue;
1107 // Loop over pad hits
1108 for (AliMUONPadHit* mPad=
1109 (AliMUONPadHit*)pMUON->FirstPad(mHit,fPadHits2);
1111 mPad=(AliMUONPadHit*)pMUON->NextPad(fPadHits2))
1113 // mPad = (AliMUONPadHit*) (*fPadHits2)[j];
1114 Int_t cathode = mPad->fCathode; // cathode number
1115 Int_t ipx = mPad->fPadX; // pad number on X
1116 Int_t ipy = mPad->fPadY; // pad number on Y
1117 Int_t iqpad = Int_t(mPad->fQpad);// charge per pad
1119 if (cathode != (icat+1)) continue;
1120 // printf("\n Pad: %d %d %d", ipx, ipy, cathode);
1122 // Float_t thex, they, thez;
1123 // segmentation=iChamber->SegmentationModel(cathode);
1124 // segmentation->GetPadC(ipx,ipy,thex,they,thez);
1125 // Float_t rpad=TMath::Sqrt(thex*thex+they*they);
1126 // if (rpad < rmin || iqpad ==0 || rpad > rmax) continue;
1127 new((*pAddress)[countadr++]) TVector(2);
1128 TVector &trinfo=*((TVector*) (*pAddress)[countadr-1]);
1129 trinfo(0)=-1; // tag background
1138 AliMUONTransientDigit* pdigit;
1139 // build the list of fired pads and update the info
1140 if (!hitMap[nch]->TestHit(ipx, ipy)) {
1141 list->AddAtAndExpand(new AliMUONTransientDigit(nch,digits),counter);
1143 hitMap[nch]->SetHit(ipx, ipy, counter);
1146 pdigit=(AliMUONTransientDigit*)list->At(list->GetLast());
1148 TObjArray *trlist=(TObjArray*)pdigit->
1150 trlist->Add(&trinfo);
1152 pdigit=(AliMUONTransientDigit*) hitMap[nch]->GetHit(ipx, ipy);
1154 (*pdigit).fSignal+=iqpad;
1156 // update list of tracks
1157 TObjArray* trlist=(TObjArray*)pdigit->
1159 Int_t lastEntry=trlist->GetLast();
1160 TVector *pTrack=(TVector*)trlist->
1162 TVector &ptrk=*pTrack;
1163 Int_t lastTrack=Int_t(ptrk(0));
1164 if (lastTrack==-1) {
1167 trlist->Add(&trinfo);
1169 // check the track list
1170 Int_t nptracks=trlist->GetEntriesFast();
1172 for (Int_t tr=0;tr<nptracks;tr++) {
1173 TVector *ppTrack=(TVector*)trlist->At(tr);
1174 TVector &pptrk=*ppTrack;
1175 trk[tr]=Int_t(pptrk(0));
1176 chtrk[tr]=Int_t(pptrk(1));
1178 } // end if nptracks
1180 } //end loop over clusters
1183 //Int_t nentr2=list->GetEntriesFast();
1184 //printf(" \n counter2, nentr2 %d %d \n",counter,nentr2);
1185 TTree *fAli=gAlice->TreeK();
1188 if (fAli) file =fAli->GetCurrentFile();
1190 } // if addBackground
1196 Int_t nentries=list->GetEntriesFast();
1198 for (Int_t nent=0;nent<nentries;nent++) {
1199 AliMUONTransientDigit *address=(AliMUONTransientDigit*)list->At(nent);
1200 if (address==0) continue;
1201 Int_t ich=address->fChamber;
1202 Int_t q=address->fSignal;
1203 iChamber=(AliMUONChamber*) (*fChambers)[ich];
1205 // Digit Response (noise, threshold, saturation, ...)
1206 // if (address->fPhysics !=0 ) address->fPhysics+=(Int_t)Noise;
1207 AliMUONResponse * response=iChamber->ResponseModel();
1208 q=response->DigitResponse(q);
1212 digits[0]=address->fPadX;
1213 digits[1]=address->fPadY;
1215 digits[3]=address->fPhysics;
1216 digits[4]=address->fHit;
1218 TObjArray* trlist=(TObjArray*)address->TrackList();
1219 Int_t nptracks=trlist->GetEntriesFast();
1220 //printf("nptracks, trlist %d %p\n",nptracks,trlist);
1222 // this was changed to accomodate the real number of tracks
1223 if (nptracks > 10) {
1224 cout<<"Attention - nptracks > 10 "<<nptracks<<endl;
1228 printf("Attention - nptracks > 2 %d \n",nptracks);
1229 printf("cat,ich,ix,iy,q %d %d %d %d %d \n",icat,ich,digits[0],digits[1],q);
1231 for (Int_t tr=0;tr<nptracks;tr++) {
1232 TVector *ppP=(TVector*)trlist->At(tr);
1233 if(!ppP ) printf("ppP - %p\n",ppP);
1235 tracks[tr]=Int_t(pp(0));
1236 charges[tr]=Int_t(pp(1));
1237 //printf("tracks, charges - %d %d\n",tracks[tr],charges[tr]);
1238 } //end loop over list of tracks for one pad
1239 // Sort list of tracks according to charge
1241 SortTracks(tracks,charges,nptracks);
1243 if (nptracks < 10 ) {
1244 for (Int_t i=nptracks; i<10; i++) {
1251 pMUON->AddDigits(ich,tracks,charges,digits);
1254 //cout<<"I'm out of the loops for digitisation"<<endl;
1255 // gAlice->GetEvent(nev);
1256 gAlice->TreeD()->Fill();
1257 pMUON->ResetDigits();
1261 for(Int_t ii=0;ii<AliMUONConstants::NCh();++ii) {
1269 } //end loop over cathodes
1272 sprintf(hname,"TreeD%d",nev);
1273 gAlice->TreeD()->Write(hname);
1275 gAlice->TreeD()->Reset();
1279 // gObjectTable->Print();
1282 void AliMUON::SortTracks(Int_t *tracks,Int_t *charges,Int_t ntr)
1285 // Sort the list of tracks contributing to a given digit
1286 // Only the 3 most significant tracks are acctually sorted
1290 // Loop over signals, only 3 times
1295 Int_t idx[3] = {-2,-2,-2};
1296 Int_t jch[3] = {-2,-2,-2};
1297 Int_t jtr[3] = {-2,-2,-2};
1300 if (ntr<3) imax=ntr;
1302 for(i=0;i<imax;i++){
1308 if((i == 1 && j == idx[i-1])
1309 ||(i == 2 && (j == idx[i-1] || j == idx[i-2]))) continue;
1311 if(charges[j] > qmax) {
1319 jch[i]=charges[jmax];
1320 jtr[i]=tracks[jmax];
1337 //___________________________________________
1338 void AliMUON::Trigger(Int_t nev){
1339 // call the Trigger Algorithm and fill TreeR
1341 Int_t singlePlus[3] = {0,0,0};
1342 Int_t singleMinus[3] = {0,0,0};
1343 Int_t singleUndef[3] = {0,0,0};
1344 Int_t pairUnlike[3] = {0,0,0};
1345 Int_t pairLike[3] = {0,0,0};
1348 AliMUONTriggerDecision* decision= new AliMUONTriggerDecision(1);
1349 decision->Trigger();
1350 decision->GetGlobalTrigger(singlePlus, singleMinus, singleUndef,
1351 pairUnlike, pairLike);
1352 // add a local trigger in the list
1353 AddGlobalTrigger(singlePlus, singleMinus, singleUndef, pairUnlike, pairLike);
1356 for (Int_t icirc=0; icirc<AliMUONConstants::NTriggerCircuit(); icirc++) {
1357 if(decision->GetITrigger(icirc)==1) {
1358 Int_t localtr[7]={0,0,0,0,0,0,0};
1359 Int_t loLpt[2]={0,0}; Int_t loHpt[2]={0,0}; Int_t loApt[2]={0,0};
1360 decision->GetLutOutput(icirc, loLpt, loHpt, loApt);
1362 localtr[1] = decision->GetStripX11(icirc);
1363 localtr[2] = decision->GetDev(icirc);
1364 localtr[3] = decision->GetStripY11(icirc);
1365 for (i=0; i<2; i++) { // convert the Lut output in 1 digit
1366 localtr[4] = localtr[4]+Int_t(loLpt[i]*TMath::Power(2,i));
1367 localtr[5] = localtr[5]+Int_t(loHpt[i]*TMath::Power(2,i));
1368 localtr[6] = localtr[6]+Int_t(loApt[i]*TMath::Power(2,i));
1370 AddLocalTrigger(localtr); // add a local trigger in the list
1375 gAlice->TreeR()->Fill();
1378 sprintf(hname,"TreeR%d",nev);
1379 gAlice->TreeR()->Write(hname);
1380 gAlice->TreeR()->Reset();
1381 printf("\n End of trigger for event %d", nev);
1385 //____________________________________________
1386 void AliMUON::FindClusters(Int_t nev,Int_t lastEntry)
1389 // Perform cluster finding
1391 TClonesArray *dig1, *dig2;
1393 dig1 = new TClonesArray("AliMUONDigit",1000);
1394 dig2 = new TClonesArray("AliMUONDigit",1000);
1395 AliMUONDigit *digit;
1397 // Loop on chambers and on cathode planes
1400 for (Int_t ich=0;ich<10;ich++) {
1401 AliMUONChamber* iChamber=(AliMUONChamber*) (*fChambers)[ich];
1402 AliMUONClusterFinderVS* rec = iChamber->ReconstructionModel();
1403 gAlice->ResetDigits();
1404 gAlice->TreeD()->GetEvent(lastEntry);
1405 TClonesArray *muonDigits = this->DigitsAddress(ich);
1406 ndig=muonDigits->GetEntriesFast();
1407 printf("\n 1 Found %d digits in %p %d", ndig, muonDigits,ich);
1408 TClonesArray &lhits1 = *dig1;
1410 for (k=0; k<ndig; k++) {
1411 digit=(AliMUONDigit*) muonDigits->UncheckedAt(k);
1412 if (rec->TestTrack(digit->fTracks[0]))
1413 new(lhits1[n++]) AliMUONDigit(*digit);
1415 gAlice->ResetDigits();
1416 gAlice->TreeD()->GetEvent(lastEntry+1);
1417 muonDigits = this->DigitsAddress(ich);
1418 ndig=muonDigits->GetEntriesFast();
1419 printf("\n 2 Found %d digits in %p %d", ndig, muonDigits, ich);
1420 TClonesArray &lhits2 = *dig2;
1423 for (k=0; k<ndig; k++) {
1424 digit= (AliMUONDigit*) muonDigits->UncheckedAt(k);
1425 if (rec->TestTrack(digit->fTracks[0]))
1426 new(lhits2[n++]) AliMUONDigit(*digit);
1430 AliMUONClusterInput::Instance()->SetDigits(ich, dig1, dig2);
1431 rec->FindRawClusters();
1436 gAlice->TreeR()->Fill();
1439 sprintf(hname,"TreeR%d",nev);
1440 gAlice->TreeR()->Write(hname);
1441 gAlice->TreeR()->Reset();
1442 printf("\n End of cluster finding for event %d", nev);
1446 //gObjectTable->Print();
1450 void AliMUON::Streamer(TBuffer &R__b)
1452 // Stream an object of class AliMUON.
1453 AliMUONChamber *iChamber;
1454 AliMUONTriggerCircuit *iTriggerCircuit;
1455 AliSegmentation *segmentation;
1456 AliMUONResponse *response;
1457 TClonesArray *digitsaddress;
1458 TClonesArray *rawcladdress;
1460 if (R__b.IsReading()) {
1461 Version_t R__v = R__b.ReadVersion(); if (R__v) { }
1462 AliDetector::Streamer(R__b);
1464 R__b >> fPadHits; // diff
1465 R__b >> fNLocalTrigger;
1466 R__b >> fLocalTrigger;
1467 R__b >> fNGlobalTrigger;
1468 R__b >> fGlobalTrigger;
1470 R__b >> fRawClusters;
1471 R__b.ReadArray(fNdch);
1472 R__b.ReadArray(fNrawch);
1477 R__b >> fTriggerCircuits;
1478 for (i =0; i<AliMUONConstants::NTriggerCircuit(); i++) {
1479 iTriggerCircuit=(AliMUONTriggerCircuit*) (*fTriggerCircuits)[i];
1480 iTriggerCircuit->Streamer(R__b);
1482 // Stream chamber related information
1483 for (i =0; i<AliMUONConstants::NCh(); i++) {
1484 iChamber=(AliMUONChamber*) (*fChambers)[i];
1485 iChamber->Streamer(R__b);
1486 if (iChamber->Nsec()==1) {
1487 segmentation=iChamber->SegmentationModel(1);
1489 segmentation->Streamer(R__b);
1491 segmentation=iChamber->SegmentationModel(1);
1493 segmentation->Streamer(R__b);
1495 segmentation=iChamber->SegmentationModel(2);
1496 segmentation->Streamer(R__b);
1498 response=iChamber->ResponseModel();
1500 response->Streamer(R__b);
1501 digitsaddress=(TClonesArray*) (*fDchambers)[i];
1502 digitsaddress->Streamer(R__b);
1503 if (i < AliMUONConstants::NTrackingCh()) {
1504 rawcladdress=(TClonesArray*) (*fRawClusters)[i];
1505 rawcladdress->Streamer(R__b);
1510 R__b.WriteVersion(AliMUON::IsA());
1511 AliDetector::Streamer(R__b);
1513 R__b << fPadHits; // diff
1514 R__b << fNLocalTrigger;
1515 R__b << fLocalTrigger;
1516 R__b << fNGlobalTrigger;
1517 R__b << fGlobalTrigger;
1519 R__b << fRawClusters;
1520 R__b.WriteArray(fNdch, AliMUONConstants::NCh());
1521 R__b.WriteArray(fNrawch, AliMUONConstants::NTrackingCh());
1528 R__b << fTriggerCircuits;
1529 for (i =0; i<AliMUONConstants::NTriggerCircuit(); i++) {
1530 iTriggerCircuit=(AliMUONTriggerCircuit*) (*fTriggerCircuits)[i];
1531 iTriggerCircuit->Streamer(R__b);
1533 for (i =0; i<AliMUONConstants::NCh(); i++) {
1534 iChamber=(AliMUONChamber*) (*fChambers)[i];
1535 iChamber->Streamer(R__b);
1536 if (iChamber->Nsec()==1) {
1537 segmentation=iChamber->SegmentationModel(1);
1539 segmentation->Streamer(R__b);
1541 segmentation=iChamber->SegmentationModel(1);
1543 segmentation->Streamer(R__b);
1544 segmentation=iChamber->SegmentationModel(2);
1546 segmentation->Streamer(R__b);
1548 response=iChamber->ResponseModel();
1550 response->Streamer(R__b);
1551 digitsaddress=(TClonesArray*) (*fDchambers)[i];
1552 digitsaddress->Streamer(R__b);
1553 if (i < AliMUONConstants::NTrackingCh()) {
1554 rawcladdress=(TClonesArray*) (*fRawClusters)[i];
1555 rawcladdress->Streamer(R__b);
1560 AliMUONPadHit* AliMUON::FirstPad(AliMUONHit* hit, TClonesArray *clusters)
1563 // Initialise the pad iterator
1564 // Return the address of the first padhit for hit
1565 TClonesArray *theClusters = clusters;
1566 Int_t nclust = theClusters->GetEntriesFast();
1567 if (nclust && hit->fPHlast > 0) {
1568 AliMUON::fMaxIterPad=hit->fPHlast;
1569 AliMUON::fCurIterPad=hit->fPHfirst;
1570 return (AliMUONPadHit*) clusters->UncheckedAt(AliMUON::fCurIterPad-1);
1576 AliMUONPadHit* AliMUON::NextPad(TClonesArray *clusters)
1578 // Get next pad (in iterator)
1580 AliMUON::fCurIterPad++;
1581 if (AliMUON::fCurIterPad <= AliMUON::fMaxIterPad) {
1582 return (AliMUONPadHit*) clusters->UncheckedAt(AliMUON::fCurIterPad-1);
1589 AliMUONRawCluster *AliMUON::RawCluster(Int_t ichamber, Int_t icathod, Int_t icluster)
1592 // Return rawcluster (icluster) for chamber ichamber and cathode icathod
1594 TClonesArray *muonRawCluster = RawClustAddress(ichamber);
1596 TTree *treeR = gAlice->TreeR();
1597 Int_t nent=(Int_t)treeR->GetEntries();
1598 treeR->GetEvent(nent-2+icathod-1);
1599 //treeR->GetEvent(icathod);
1600 //Int_t nrawcl = (Int_t)muonRawCluster->GetEntriesFast();
1602 AliMUONRawCluster * mRaw = (AliMUONRawCluster*)muonRawCluster->UncheckedAt(icluster);
1603 //printf("RawCluster _ nent nrawcl icluster mRaw %d %d %d%p\n",nent,nrawcl,icluster,mRaw);
1608 AliMUON& AliMUON::operator = (const AliMUON& rhs)