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.50 2001/05/16 14:57:17 alibrary
18 New files for folders and Stack
20 Revision 1.49 2001/03/12 17:45:48 hristov
21 Changes needed on Sun with CC 5.0
23 Revision 1.48 2001/03/06 00:01:36 morsch
24 Add Digits2Reco() and FindClusters()
25 Adapt call of cluster finder to new STEER.
27 Revision 1.47 2001/03/05 08:38:36 morsch
28 Digitization related methods moved to AliMUONMerger.
30 Revision 1.46 2001/01/26 21:34:59 morsch
31 Use access functions for AliMUONHit, AliMUONDigit and AliMUONPadHit data members.
33 Revision 1.45 2001/01/26 20:00:49 hristov
34 Major upgrade of AliRoot code
36 Revision 1.44 2001/01/25 17:39:09 morsch
37 Pass size of fNdch and fNrawch to CINT.
39 Revision 1.43 2001/01/23 18:58:19 hristov
40 Initialisation of some pointers
42 Revision 1.42 2001/01/17 20:53:40 hristov
43 Destructors corrected to avoid memory leaks
45 Revision 1.41 2000/12/21 22:12:40 morsch
46 Clean-up of coding rule violations,
48 Revision 1.40 2000/11/29 20:32:26 gosset
50 1. correction for array index out of bounds
51 2. one printout commented
53 Revision 1.39 2000/11/12 17:17:03 pcrochet
54 BuildGeometry of AliMUON for trigger chambers delegated to AliMUONSegmentationTriggerX (same strategy as for tracking chambers)
56 Revision 1.38 2000/11/06 09:20:43 morsch
57 AliMUON delegates part of BuildGeometry() to AliMUONSegmentation using the
58 Draw() method. This avoids code and parameter replication.
60 Revision 1.37 2000/10/26 09:53:37 pcrochet
61 put back trigger chambers in the display (there was a problem in buildgeometry)
63 Revision 1.36 2000/10/25 19:51:18 morsch
64 Correct x-position of chambers.
66 Revision 1.35 2000/10/24 19:46:21 morsch
67 BuildGeometry updated for slats in station 3-4.
69 Revision 1.34 2000/10/18 11:42:06 morsch
70 - AliMUONRawCluster contains z-position.
71 - Some clean-up of useless print statements during initialisations.
73 Revision 1.33 2000/10/09 14:01:57 morsch
74 Unused variables removed.
76 Revision 1.32 2000/10/06 09:08:10 morsch
77 Built geometry includes slat geometry for event display.
79 Revision 1.31 2000/10/02 21:28:08 fca
80 Removal of useless dependecies via forward declarations
82 Revision 1.30 2000/10/02 16:58:29 egangler
83 Cleaning of the code :
86 -> some useless includes removed or replaced by "class" statement
88 Revision 1.29 2000/07/28 13:49:38 morsch
89 SetAcceptance defines inner and outer chamber radii according to angular acceptance.
90 Can be used for simple acceptance studies.
92 Revision 1.28 2000/07/22 16:43:15 morsch
93 Same comment as before, but now done correctly I hope (sorry it's Saturday evening)
95 Revision 1.27 2000/07/22 16:36:50 morsch
96 Change order of indices in creation (new) of xhit and yhit
98 Revision 1.26 2000/07/03 11:54:57 morsch
99 AliMUONSegmentation and AliMUONHitMap have been replaced by AliSegmentation and AliHitMap in STEER
100 The methods GetPadIxy and GetPadXxy of AliMUONSegmentation have changed name to GetPadI and GetPadC.
102 Revision 1.25 2000/06/29 12:34:09 morsch
103 AliMUONSegmentation class has been made independent of AliMUONChamber. This makes
104 it usable with any other geometry class. The link to the object to which it belongs is
105 established via an index. This assumes that there exists a global geometry manager
106 from which the pointer to the parent object can be obtained (in our case gAlice).
108 Revision 1.24 2000/06/28 15:16:35 morsch
109 (1) Client code adapted to new method signatures in AliMUONSegmentation (see comments there)
110 to allow development of slat-muon chamber simulation and reconstruction code in the MUON
111 framework. The changes should have no side effects (mostly dummy arguments).
112 (2) Hit disintegration uses 3-dim hit coordinates to allow simulation
113 of chambers with overlapping modules (MakePadHits, Disintegration).
115 Revision 1.23 2000/06/28 12:19:17 morsch
116 More consequent seperation of global input data services (AliMUONClusterInput singleton) and the
117 cluster and hit reconstruction algorithms in AliMUONClusterFindRawinderVS.
118 AliMUONClusterFinderVS becomes the base class for clustering and hit reconstruction.
119 It requires two cathode planes. Small modifications in the code will make it usable for
120 one cathode plane and, hence, more general (for test beam data).
121 AliMUONClusterFinder is now obsolete.
123 Revision 1.22 2000/06/28 08:06:10 morsch
124 Avoid global variables in AliMUONClusterFinderVS by seperating the input data for the fit from the
125 algorithmic part of the class. Input data resides inside the AliMUONClusterInput singleton.
126 It also naturally takes care of the TMinuit instance.
128 Revision 1.21 2000/06/27 08:54:41 morsch
129 Problems with on constant array sizes (in hitMap, nmuon, xhit, yhit) corrected.
131 Revision 1.20 2000/06/26 14:02:38 morsch
132 Add class AliMUONConstants with MUON specific constants using static memeber data and access methods.
134 Revision 1.19 2000/06/22 13:40:51 morsch
135 scope problem on HP, "i" declared once
136 pow changed to TMath::Power (PH, AM)
138 Revision 1.18 2000/06/15 07:58:48 morsch
139 Code from MUON-dev joined
141 Revision 1.14.4.17 2000/06/14 14:36:46 morsch
142 - add TriggerCircuit (PC)
143 - add GlobalTrigger and LocalTrigger and specific methods (PC)
145 Revision 1.14.4.16 2000/06/09 21:20:28 morsch
146 Most coding rule violations corrected
148 Revision 1.14.4.15 2000/05/02 09:54:32 morsch
149 RULE RN17 violations corrected
151 Revision 1.14.4.12 2000/04/26 12:25:02 morsch
152 Code revised by P. Crochet:
153 - Z position of TriggerChamber changed according to A.Tournaire Priv.Comm.
154 - ToF included in the method MakePadHits
155 - inner radius of flange between beam shielding and trigger corrected
156 - Trigger global volume updated (according to the new geometry)
158 Revision 1.14.4.11 2000/04/19 19:42:08 morsch
159 Some changes of variable names curing viols and methods concerning
160 correlated clusters removed.
162 Revision 1.14.4.10 2000/03/22 16:44:07 gosset
163 Memory leak suppressed in function Digitise:
164 p_adr->Delete() instead of Clear (I.Chevrot and A.Baldisseri)
166 Revision 1.14.4.9 2000/03/20 18:15:25 morsch
167 Positions of trigger chambers corrected (P.C.)
169 Revision 1.14.4.8 2000/02/21 15:38:01 morsch
170 Call to AddHitList introduced to make this version compatible with head.
172 Revision 1.14.4.7 2000/02/20 07:45:53 morsch
173 Bugs in Trigger part of BuildGeomemetry corrected (P.C)
175 Revision 1.14.4.6 2000/02/17 14:28:54 morsch
176 Trigger included into initialization and digitization
178 Revision 1.14.4.5 2000/02/15 10:02:58 morsch
179 Log messages of previous revisions added
181 Revision 1.14.4.2 2000/02/04 10:57:34 gosset
182 Z position of the chambers:
183 it was the Z position of the stations;
184 it is now really the Z position of the chambers.
185 !!!! WARNING: THE CALLS TO "AliMUONChamber::SetZPOS"
186 !!!! AND "AliMUONChamber::ZPosition"
187 !!!! HAVE TO BE CHANGED TO "AliMUONChamber::"SetZ"
188 !!!! AND "AliMUONChamber::Z"
190 Revision 1.14.4.3 2000/02/04 16:19:04 gosset
191 Correction for mis-spelling of NCH
193 Revision 1.14.4.4 2000/02/15 09:43:38 morsch
199 ///////////////////////////////////////////////
200 // Manager and hits classes for set:MUON //
201 ////////////////////////////////////////////////
205 #include <TRotMatrix.h>
206 #include <TGeometry.h>
212 #include <TObjArray.h>
214 #include <TParticle.h>
220 #include <TDirectory.h>
221 #include <TObjectTable.h>
226 #include "AliMUONHit.h"
227 #include "AliMUONPadHit.h"
228 #include "AliMUONDigit.h"
229 #include "AliMUONTransientDigit.h"
230 #include "AliMUONRawCluster.h"
231 #include "AliMUONLocalTrigger.h"
232 #include "AliMUONGlobalTrigger.h"
233 #include "AliMUONTriggerCircuit.h"
234 #include "AliHitMap.h"
235 #include "AliMUONHitMapA1.h"
236 #include "AliMUONChamberTrigger.h"
237 #include "AliMUONConstants.h"
238 #include "AliMUONClusterFinderVS.h"
239 #include "AliMUONTriggerDecision.h"
241 #include "AliHeader.h"
243 #include "AliMUONClusterInput.h"
244 #include "AliMUONMerger.h"
245 #include "iostream.h"
246 #include "AliCallf77.h"
247 #include "AliConst.h"
249 // Defaults parameters for Z positions of chambers
250 // taken from values for "stations" in AliMUON::AliMUON
251 // const Float_t zch[7]={528, 690., 975., 1249., 1449., 1610, 1710.};
252 // and from array "dstation" in AliMUONv1::CreateGeometry
253 // Float_t dstation[5]={20., 20., 20, 20., 20.};
254 // for tracking chambers,
255 // according to (Z1 = zch - dstation) and (Z2 = zch + dstation)
256 // for the first and second chambers in the station, respectively,
257 // and from "DTPLANES" in AliMUONv1::CreateGeometry
258 // const Float_t DTPLANES = 15.;
259 // for trigger chambers,
260 // according to (Z1 = zch) and (Z2 = zch + DTPLANES)
261 // for the first and second chambers in the station, respectively
264 //___________________________________________
267 // Default Constructor
277 fTriggerCircuits = 0;
291 //___________________________________________
292 AliMUON::AliMUON(const char *name, const char *title)
293 : AliDetector(name,title)
297 <img src="gif/alimuon.gif">
301 fHits = new TClonesArray("AliMUONHit",1000);
302 gAlice->AddHitList(fHits);
303 fPadHits = new TClonesArray("AliMUONPadHit",10000);
307 fNCh = AliMUONConstants::NCh();
308 fNTrackingCh = AliMUONConstants::NTrackingCh();
309 fNdch = new Int_t[fNCh];
311 fDchambers = new TObjArray(AliMUONConstants::NCh());
315 for (i=0; i<AliMUONConstants::NCh() ;i++) {
316 (*fDchambers)[i] = new TClonesArray("AliMUONDigit",10000);
320 fNrawch = new Int_t[fNTrackingCh];
322 fRawClusters = new TObjArray(AliMUONConstants::NTrackingCh());
324 for (i=0; i<AliMUONConstants::NTrackingCh();i++) {
325 (*fRawClusters)[i] = new TClonesArray("AliMUONRawCluster",10000);
329 fGlobalTrigger = new TClonesArray("AliMUONGlobalTrigger",1);
331 fLocalTrigger = new TClonesArray("AliMUONLocalTrigger",234);
334 SetMarkerColor(kRed);
342 fChambers = new TObjArray(AliMUONConstants::NCh());
344 // Loop over stations
345 for (Int_t st = 0; st < AliMUONConstants::NCh() / 2; st++) {
346 // Loop over 2 chambers in the station
347 for (Int_t stCH = 0; stCH < 2; stCH++) {
350 // Default Parameters for Muon Tracking Stations
355 if (ch < AliMUONConstants::NTrackingCh()) {
356 (*fChambers)[ch] = new AliMUONChamber(ch);
358 (*fChambers)[ch] = new AliMUONChamberTrigger(ch);
361 AliMUONChamber* chamber = (AliMUONChamber*) (*fChambers)[ch];
364 // Default values for Z of chambers
365 chamber->SetZ(AliMUONConstants::DefaultChamberZ(ch));
367 chamber->InitGeo(AliMUONConstants::DefaultChamberZ(ch));
368 // Set chamber inner and outer radius to default
369 chamber->SetRInner(AliMUONConstants::Dmin(st)/2);
370 chamber->SetROuter(AliMUONConstants::Dmax(st)/2);
372 } // Chamber stCH (0, 1) in
373 } // Station st (0...)
386 // cp new design of AliMUONTriggerDecision
387 fTriggerCircuits = new TObjArray(AliMUONConstants::NTriggerCircuit());
388 for (Int_t circ=0; circ<AliMUONConstants::NTriggerCircuit(); circ++) {
389 (*fTriggerCircuits)[circ] = new AliMUONTriggerCircuit();
395 //___________________________________________
396 AliMUON::AliMUON(const AliMUON& rMUON)
398 // Dummy copy constructor
406 if(fDebug) printf("%s: Calling AliMUON destructor !!!\n",ClassName());
418 if (fTriggerCircuits){
419 fTriggerCircuits->Delete();
420 delete fTriggerCircuits;
424 fDchambers->Delete();
429 fRawClusters->Delete();
432 for (i=0;i<AliMUONConstants::NTrackingCh();i++) {
436 // Delete TClonesArrays
444 fGlobalTrigger->Delete();
445 delete fGlobalTrigger;
450 fLocalTrigger->Delete();
451 delete fLocalTrigger;
470 // Delete hits tree for background event
477 if (fMerger) delete fMerger;
480 //___________________________________________
481 void AliMUON::AddHit(Int_t track, Int_t *vol, Float_t *hits)
483 TClonesArray &lhits = *fHits;
484 new(lhits[fNhits++]) AliMUONHit(fIshunt,track,vol,hits);
486 //___________________________________________
487 void AliMUON::AddPadHit(Int_t *clhits)
489 TClonesArray &lclusters = *fPadHits;
490 new(lclusters[fNPadHits++]) AliMUONPadHit(clhits);
492 //_____________________________________________________________________________
493 void AliMUON::AddDigits(Int_t id, Int_t *tracks, Int_t *charges, Int_t *digits)
496 // Add a MUON digit to the list
499 TClonesArray &ldigits = *((TClonesArray*)(*fDchambers)[id]);
500 new(ldigits[fNdch[id]++]) AliMUONDigit(tracks,charges,digits);
503 //_____________________________________________________________________________
504 void AliMUON::AddRawCluster(Int_t id, const AliMUONRawCluster& c)
507 // Add a MUON digit to the list
510 TClonesArray &lrawcl = *((TClonesArray*)(*fRawClusters)[id]);
511 new(lrawcl[fNrawch[id]++]) AliMUONRawCluster(c);
514 //___________________________________________
515 void AliMUON::AddGlobalTrigger(Int_t *singlePlus, Int_t *singleMinus,
517 Int_t *pairUnlike, Int_t *pairLike)
519 // add a MUON Global Trigger to the list (only one GlobalTrigger per event !)
520 TClonesArray &globalTrigger = *fGlobalTrigger;
521 new(globalTrigger[fNGlobalTrigger++])
522 AliMUONGlobalTrigger(singlePlus, singleMinus, singleUndef, pairUnlike,
525 //___________________________________________
526 void AliMUON::AddLocalTrigger(Int_t *localtr)
528 // add a MUON Local Trigger to the list
529 TClonesArray &localTrigger = *fLocalTrigger;
530 new(localTrigger[fNLocalTrigger++]) AliMUONLocalTrigger(localtr);
533 //___________________________________________
534 void AliMUON::BuildGeometry()
536 // Geometry for event display
537 for (Int_t i=0; i<7; i++) {
538 for (Int_t j=0; j<2; j++) {
540 this->Chamber(id-1).SegmentationModel(1)->Draw("eventdisplay");
545 //___________________________________________
546 Int_t AliMUON::DistancetoPrimitive(Int_t , Int_t )
551 //___________________________________________
552 void AliMUON::MakeBranch(Option_t* option, const char *file)
555 // Create Tree branches for the MUON.
557 const Int_t kBufferSize = 4000;
559 sprintf(branchname,"%sCluster",GetName());
561 AliDetector::MakeBranch(option,file);
563 const char *cD = strstr(option,"D");
564 const char *cR = strstr(option,"R");
565 const char *cH = strstr(option,"H");
567 if (fPadHits && gAlice->TreeH() && cH) {
568 MakeBranchInTree(gAlice->TreeH(),
569 branchname, &fPadHits, kBufferSize, file);
574 // one branch for digits per chamber
578 for (i=0; i<AliMUONConstants::NCh() ;i++) {
579 sprintf(branchname,"%sDigits%d",GetName(),i+1);
580 if (fDchambers && gAlice->TreeD()) {
581 MakeBranchInTree(gAlice->TreeD(),
582 branchname, &((*fDchambers)[i]), kBufferSize, file);
583 printf("Making Branch %s for digits in chamber %d\n",branchname,i+1);
590 // one branch for raw clusters per chamber
592 printf("Make Branch - TreeR address %p\n",gAlice->TreeR());
596 for (i=0; i<AliMUONConstants::NTrackingCh() ;i++) {
597 sprintf(branchname,"%sRawClusters%d",GetName(),i+1);
598 if (fRawClusters && gAlice->TreeR()) {
599 MakeBranchInTree(gAlice->TreeR(),
600 branchname, &((*fRawClusters)[i]), kBufferSize, file);
601 printf("Making Branch %s for raw clusters in chamber %d\n",branchname,i+1);
605 // one branch for global trigger
607 sprintf(branchname,"%sGlobalTrigger",GetName());
608 if (fGlobalTrigger && gAlice->TreeR()) {
609 MakeBranchInTree(gAlice->TreeR(),
610 branchname, &fGlobalTrigger, kBufferSize, file);
611 printf("Making Branch %s for Global Trigger\n",branchname);
614 // one branch for local trigger
616 sprintf(branchname,"%sLocalTrigger",GetName());
617 if (fLocalTrigger && gAlice->TreeR()) {
618 MakeBranchInTree(gAlice->TreeR(),
619 branchname, &fLocalTrigger, kBufferSize, file);
620 printf("Making Branch %s for Local Trigger\n",branchname);
625 //___________________________________________
626 void AliMUON::SetTreeAddress()
628 // Set branch address for the Hits and Digits Tree.
630 AliDetector::SetTreeAddress();
633 TTree *treeH = gAlice->TreeH();
634 TTree *treeD = gAlice->TreeD();
635 TTree *treeR = gAlice->TreeR();
639 branch = treeH->GetBranch("MUONCluster");
640 if (branch) branch->SetAddress(&fPadHits);
645 for (int i=0; i<AliMUONConstants::NCh(); i++) {
646 sprintf(branchname,"%sDigits%d",GetName(),i+1);
648 branch = treeD->GetBranch(branchname);
649 if (branch) branch->SetAddress(&((*fDchambers)[i]));
654 // printf("SetTreeAddress --- treeR address %p \n",treeR);
657 for (int i=0; i<AliMUONConstants::NTrackingCh(); i++) {
658 sprintf(branchname,"%sRawClusters%d",GetName(),i+1);
660 branch = treeR->GetBranch(branchname);
661 if (branch) branch->SetAddress(&((*fRawClusters)[i]));
666 branch = treeR->GetBranch("MUONLocalTrigger");
667 if (branch) branch->SetAddress(&fLocalTrigger);
669 if (fGlobalTrigger) {
670 branch = treeR->GetBranch("MUONGlobalTrigger");
671 if (branch) branch->SetAddress(&fGlobalTrigger);
675 //___________________________________________
676 void AliMUON::ResetHits()
678 // Reset number of clusters and the cluster array for this detector
679 AliDetector::ResetHits();
681 if (fPadHits) fPadHits->Clear();
684 //____________________________________________
685 void AliMUON::ResetDigits()
688 // Reset number of digits and the digits array for this detector
690 for ( int i=0;i<AliMUONConstants::NCh();i++ ) {
691 if ((*fDchambers)[i]) ((TClonesArray*)(*fDchambers)[i])->Clear();
692 if (fNdch) fNdch[i]=0;
695 //____________________________________________
696 void AliMUON::ResetRawClusters()
699 // Reset number of raw clusters and the raw clust array for this detector
701 for ( int i=0;i<AliMUONConstants::NTrackingCh();i++ ) {
702 if ((*fRawClusters)[i]) ((TClonesArray*)(*fRawClusters)[i])->Clear();
703 if (fNrawch) fNrawch[i]=0;
707 //____________________________________________
708 void AliMUON::ResetTrigger()
710 // Reset Local and Global Trigger
712 if (fGlobalTrigger) fGlobalTrigger->Clear();
714 if (fLocalTrigger) fLocalTrigger->Clear();
717 //____________________________________________
718 void AliMUON::SetPadSize(Int_t id, Int_t isec, Float_t p1, Float_t p2)
720 // Set the pad size for chamber id and cathode isec
722 ((AliMUONChamber*) (*fChambers)[i]) ->SetPadSize(isec,p1,p2);
723 ((AliMUONChamber*) (*fChambers)[i+1])->SetPadSize(isec,p1,p2);
726 //___________________________________________
727 void AliMUON::SetChambersZ(const Float_t *Z)
729 // Set Z values for all chambers (tracking and trigger)
730 // from the array pointed to by "Z"
731 for (Int_t ch = 0; ch < AliMUONConstants::NCh(); ch++)
732 ((AliMUONChamber*) ((*fChambers)[ch]))->SetZ(Z[ch]);
736 //___________________________________________
737 void AliMUON::SetChambersZToDefault()
739 // Set Z values for all chambers (tracking and trigger)
741 SetChambersZ(AliMUONConstants::DefaultChamberZ());
745 //___________________________________________
746 void AliMUON::SetChargeSlope(Int_t id, Float_t p1)
748 // Set the inverse charge slope for chamber id
750 ((AliMUONChamber*) (*fChambers)[i])->SetChargeSlope(p1);
751 ((AliMUONChamber*) (*fChambers)[i+1])->SetChargeSlope(p1);
754 //___________________________________________
755 void AliMUON::SetChargeSpread(Int_t id, Float_t p1, Float_t p2)
757 // Set sigma of charge spread for chamber id
759 ((AliMUONChamber*) (*fChambers)[i])->SetChargeSpread(p1,p2);
760 ((AliMUONChamber*) (*fChambers)[i+1])->SetChargeSpread(p1,p2);
763 //___________________________________________
764 void AliMUON::SetSigmaIntegration(Int_t id, Float_t p1)
766 // Set integration limits for charge spread
768 ((AliMUONChamber*) (*fChambers)[i])->SetSigmaIntegration(p1);
769 ((AliMUONChamber*) (*fChambers)[i+1])->SetSigmaIntegration(p1);
772 //___________________________________________
773 void AliMUON::SetMaxAdc(Int_t id, Int_t p1)
775 // Set maximum number for ADCcounts (saturation)
777 ((AliMUONChamber*) (*fChambers)[i])->SetMaxAdc(p1);
778 ((AliMUONChamber*) (*fChambers)[i+1])->SetMaxAdc(p1);
781 //___________________________________________
782 void AliMUON::SetMaxStepGas(Float_t p1)
784 // Set stepsize in gas
788 //___________________________________________
789 void AliMUON::SetMaxStepAlu(Float_t p1)
791 // Set step size in Alu
795 //___________________________________________
796 void AliMUON::SetMaxDestepGas(Float_t p1)
798 // Set maximum step size in Gas
802 //___________________________________________
803 void AliMUON::SetMaxDestepAlu(Float_t p1)
805 // Set maximum step size in Alu
808 //___________________________________________
809 void AliMUON::SetAcceptance(Bool_t acc, Float_t angmin, Float_t angmax)
811 // Set acceptance cuts
813 fAccMin=angmin*TMath::Pi()/180;
814 fAccMax=angmax*TMath::Pi()/180;
817 for (Int_t st = 0; st < AliMUONConstants::NCh() / 2; st++) {
818 // Loop over 2 chambers in the station
819 for (Int_t stCH = 0; stCH < 2; stCH++) {
821 // Set chamber inner and outer radius according to acceptance cuts
822 Chamber(ch).SetRInner(AliMUONConstants::DefaultChamberZ(ch)*TMath::Tan(fAccMin));
823 Chamber(ch).SetROuter(AliMUONConstants::DefaultChamberZ(ch)*TMath::Tan(fAccMax));
828 //___________________________________________
829 void AliMUON::SetSegmentationModel(Int_t id, Int_t isec, AliSegmentation *segmentation)
831 // Set the segmentation for chamber id cathode isec
832 ((AliMUONChamber*) (*fChambers)[id])->SetSegmentationModel(isec, segmentation);
835 //___________________________________________
836 void AliMUON::SetResponseModel(Int_t id, AliMUONResponse *response)
838 // Set the response for chamber id
839 ((AliMUONChamber*) (*fChambers)[id])->SetResponseModel(response);
842 void AliMUON::SetReconstructionModel(Int_t id, AliMUONClusterFinderVS *reconst)
844 // Set ClusterFinder for chamber id
845 ((AliMUONChamber*) (*fChambers)[id])->SetReconstructionModel(reconst);
848 void AliMUON::SetNsec(Int_t id, Int_t nsec)
850 // Set number of segmented cathods for chamber id
851 ((AliMUONChamber*) (*fChambers)[id])->SetNsec(nsec);
854 //___________________________________________
855 void AliMUON::SDigits2Digits()
863 //___________________________________________
864 void AliMUON::MakePadHits(Float_t xhit,Float_t yhit, Float_t zhit,
865 Float_t eloss, Float_t tof, Int_t idvol)
868 // Calls the charge disintegration method of the current chamber and adds
869 // the simulated cluster to the root treee
872 Float_t newclust[6][500];
877 // Integrated pulse height on chamber
883 // if (idvol == 6) printf("\n ->Disintegration %f %f %f", xhit, yhit, eloss );
886 ((AliMUONChamber*) (*fChambers)[idvol])
887 ->DisIntegration(eloss, tof, xhit, yhit, zhit, nnew, newclust);
889 // if (idvol == 6) printf("\n nnew %d \n", nnew);
892 for (Int_t i=0; i<nnew; i++) {
893 if (Int_t(newclust[3][i]) > 0) {
896 clhits[1] = Int_t(newclust[5][i]);
898 clhits[2] = Int_t(newclust[0][i]);
900 clhits[3] = Int_t(newclust[1][i]);
902 clhits[4] = Int_t(newclust[2][i]);
904 clhits[5] = Int_t(newclust[3][i]);
905 // Pad: chamber sector
906 clhits[6] = Int_t(newclust[4][i]);
913 //___________________________________________
914 void AliMUON::Trigger(Int_t nev){
915 // call the Trigger Algorithm and fill TreeR
917 Int_t singlePlus[3] = {0,0,0};
918 Int_t singleMinus[3] = {0,0,0};
919 Int_t singleUndef[3] = {0,0,0};
920 Int_t pairUnlike[3] = {0,0,0};
921 Int_t pairLike[3] = {0,0,0};
924 AliMUONTriggerDecision* decision= new AliMUONTriggerDecision(1);
926 decision->GetGlobalTrigger(singlePlus, singleMinus, singleUndef,
927 pairUnlike, pairLike);
928 // add a local trigger in the list
929 AddGlobalTrigger(singlePlus, singleMinus, singleUndef, pairUnlike, pairLike);
932 for (Int_t icirc=0; icirc<AliMUONConstants::NTriggerCircuit(); icirc++) {
933 if(decision->GetITrigger(icirc)==1) {
934 Int_t localtr[7]={0,0,0,0,0,0,0};
935 Int_t loLpt[2]={0,0}; Int_t loHpt[2]={0,0}; Int_t loApt[2]={0,0};
936 decision->GetLutOutput(icirc, loLpt, loHpt, loApt);
938 localtr[1] = decision->GetStripX11(icirc);
939 localtr[2] = decision->GetDev(icirc);
940 localtr[3] = decision->GetStripY11(icirc);
941 for (i=0; i<2; i++) { // convert the Lut output in 1 digit
942 localtr[4] = localtr[4]+Int_t(loLpt[i]*TMath::Power(2,i));
943 localtr[5] = localtr[5]+Int_t(loHpt[i]*TMath::Power(2,i));
944 localtr[6] = localtr[6]+Int_t(loApt[i]*TMath::Power(2,i));
946 AddLocalTrigger(localtr); // add a local trigger in the list
951 gAlice->TreeR()->Fill();
954 sprintf(hname,"TreeR%d",nev);
955 gAlice->TreeR()->Write(hname,TObject::kOverwrite);
956 gAlice->TreeR()->Reset();
957 printf("\n End of trigger for event %d", nev);
961 //____________________________________________
962 void AliMUON::Digits2Reco()
965 Int_t nev = gAlice->GetHeader()->GetEvent();
966 gAlice->TreeR()->Fill();
968 sprintf(hname,"TreeR%d", nev);
969 gAlice->TreeR()->Write(hname);
970 gAlice->TreeR()->Reset();
972 printf("\n End of cluster finding for event %d", nev);
975 void AliMUON::FindClusters()
978 // Perform cluster finding
980 TClonesArray *dig1, *dig2;
982 dig1 = new TClonesArray("AliMUONDigit",1000);
983 dig2 = new TClonesArray("AliMUONDigit",1000);
986 // Loop on chambers and on cathode planes
989 for (Int_t ich = 0; ich < 10; ich++) {
990 AliMUONChamber* iChamber = (AliMUONChamber*) (*fChambers)[ich];
991 AliMUONClusterFinderVS* rec = iChamber->ReconstructionModel();
993 gAlice->ResetDigits();
994 gAlice->TreeD()->GetEvent(0);
995 TClonesArray *muonDigits = this->DigitsAddress(ich);
996 ndig=muonDigits->GetEntriesFast();
997 printf("\n 1 Found %d digits in %p %d", ndig, muonDigits,ich);
998 TClonesArray &lhits1 = *dig1;
1000 for (k = 0; k < ndig; k++) {
1001 digit = (AliMUONDigit*) muonDigits->UncheckedAt(k);
1002 if (rec->TestTrack(digit->Track(0)))
1003 new(lhits1[n++]) AliMUONDigit(*digit);
1005 gAlice->ResetDigits();
1006 gAlice->TreeD()->GetEvent(1);
1007 muonDigits = this->DigitsAddress(ich);
1008 ndig=muonDigits->GetEntriesFast();
1009 printf("\n 2 Found %d digits in %p %d", ndig, muonDigits, ich);
1010 TClonesArray &lhits2 = *dig2;
1013 for (k=0; k<ndig; k++) {
1014 digit= (AliMUONDigit*) muonDigits->UncheckedAt(k);
1015 if (rec->TestTrack(digit->Track(0)))
1016 new(lhits2[n++]) AliMUONDigit(*digit);
1020 AliMUONClusterInput::Instance()->SetDigits(ich, dig1, dig2);
1021 rec->FindRawClusters();
1031 void AliMUON::Streamer(TBuffer &R__b)
1033 // Stream an object of class AliMUON.
1034 AliMUONChamber *iChamber;
1035 AliMUONTriggerCircuit *iTriggerCircuit;
1036 AliSegmentation *segmentation;
1037 AliMUONResponse *response;
1038 TClonesArray *digitsaddress;
1039 TClonesArray *rawcladdress;
1041 if (R__b.IsReading()) {
1042 Version_t R__v = R__b.ReadVersion(); if (R__v) { }
1043 AliDetector::Streamer(R__b);
1045 R__b >> fPadHits; // diff
1046 R__b >> fNLocalTrigger;
1047 R__b >> fLocalTrigger;
1048 R__b >> fNGlobalTrigger;
1049 R__b >> fGlobalTrigger;
1051 R__b >> fRawClusters;
1052 R__b.ReadArray(fNdch);
1053 R__b.ReadArray(fNrawch);
1058 R__b >> fTriggerCircuits;
1059 for (i =0; i<AliMUONConstants::NTriggerCircuit(); i++) {
1060 iTriggerCircuit=(AliMUONTriggerCircuit*) (*fTriggerCircuits)[i];
1061 iTriggerCircuit->Streamer(R__b);
1063 // Stream chamber related information
1064 for (i =0; i<AliMUONConstants::NCh(); i++) {
1065 iChamber=(AliMUONChamber*) (*fChambers)[i];
1066 iChamber->Streamer(R__b);
1067 if (iChamber->Nsec()==1) {
1068 segmentation=iChamber->SegmentationModel(1);
1070 segmentation->Streamer(R__b);
1072 segmentation=iChamber->SegmentationModel(1);
1074 segmentation->Streamer(R__b);
1076 segmentation=iChamber->SegmentationModel(2);
1077 segmentation->Streamer(R__b);
1079 response=iChamber->ResponseModel();
1081 response->Streamer(R__b);
1082 digitsaddress=(TClonesArray*) (*fDchambers)[i];
1083 digitsaddress->Streamer(R__b);
1084 if (i < AliMUONConstants::NTrackingCh()) {
1085 rawcladdress=(TClonesArray*) (*fRawClusters)[i];
1086 rawcladdress->Streamer(R__b);
1091 R__b.WriteVersion(AliMUON::IsA());
1092 AliDetector::Streamer(R__b);
1094 R__b << fPadHits; // diff
1095 R__b << fNLocalTrigger;
1096 R__b << fLocalTrigger;
1097 R__b << fNGlobalTrigger;
1098 R__b << fGlobalTrigger;
1100 R__b << fRawClusters;
1101 R__b.WriteArray(fNdch, AliMUONConstants::NCh());
1102 R__b.WriteArray(fNrawch, AliMUONConstants::NTrackingCh());
1109 R__b << fTriggerCircuits;
1110 for (i =0; i<AliMUONConstants::NTriggerCircuit(); i++) {
1111 iTriggerCircuit=(AliMUONTriggerCircuit*) (*fTriggerCircuits)[i];
1112 iTriggerCircuit->Streamer(R__b);
1114 for (i =0; i<AliMUONConstants::NCh(); i++) {
1115 iChamber=(AliMUONChamber*) (*fChambers)[i];
1116 iChamber->Streamer(R__b);
1117 if (iChamber->Nsec()==1) {
1118 segmentation=iChamber->SegmentationModel(1);
1120 segmentation->Streamer(R__b);
1122 segmentation=iChamber->SegmentationModel(1);
1124 segmentation->Streamer(R__b);
1125 segmentation=iChamber->SegmentationModel(2);
1127 segmentation->Streamer(R__b);
1129 response=iChamber->ResponseModel();
1131 response->Streamer(R__b);
1132 digitsaddress=(TClonesArray*) (*fDchambers)[i];
1133 digitsaddress->Streamer(R__b);
1134 if (i < AliMUONConstants::NTrackingCh()) {
1135 rawcladdress=(TClonesArray*) (*fRawClusters)[i];
1136 rawcladdress->Streamer(R__b);
1143 AliMUONPadHit* AliMUON::FirstPad(AliMUONHit* hit, TClonesArray *clusters)
1146 // Initialise the pad iterator
1147 // Return the address of the first padhit for hit
1148 TClonesArray *theClusters = clusters;
1149 Int_t nclust = theClusters->GetEntriesFast();
1150 if (nclust && hit->PHlast() > 0) {
1151 AliMUON::fMaxIterPad=hit->PHlast();
1152 AliMUON::fCurIterPad=hit->PHfirst();
1153 return (AliMUONPadHit*) clusters->UncheckedAt(AliMUON::fCurIterPad-1);
1159 AliMUONPadHit* AliMUON::NextPad(TClonesArray *clusters)
1161 // Get next pad (in iterator)
1163 AliMUON::fCurIterPad++;
1164 if (AliMUON::fCurIterPad <= AliMUON::fMaxIterPad) {
1165 return (AliMUONPadHit*) clusters->UncheckedAt(AliMUON::fCurIterPad-1);
1172 AliMUONRawCluster *AliMUON::RawCluster(Int_t ichamber, Int_t icathod, Int_t icluster)
1175 // Return rawcluster (icluster) for chamber ichamber and cathode icathod
1177 TClonesArray *muonRawCluster = RawClustAddress(ichamber);
1179 TTree *treeR = gAlice->TreeR();
1180 Int_t nent=(Int_t)treeR->GetEntries();
1181 treeR->GetEvent(nent-2+icathod-1);
1182 //treeR->GetEvent(icathod);
1183 //Int_t nrawcl = (Int_t)muonRawCluster->GetEntriesFast();
1185 AliMUONRawCluster * mRaw = (AliMUONRawCluster*)muonRawCluster->UncheckedAt(icluster);
1186 //printf("RawCluster _ nent nrawcl icluster mRaw %d %d %d%p\n",nent,nrawcl,icluster,mRaw);
1191 void AliMUON::SetMerger(AliMUONMerger* merger)
1193 // Set pointer to merger
1197 AliMUONMerger* AliMUON::Merger()
1199 // Return pointer to merger
1205 AliMUON& AliMUON::operator = (const AliMUON& rhs)