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.55 2001/09/07 08:38:30 hristov
18 Pointers initialised to 0 in the default constructors
20 Revision 1.54 2001/08/30 09:52:12 hristov
21 The operator[] is replaced by At() or AddAt() in case of TObjArray.
23 Revision 1.53 2001/07/20 10:03:13 morsch
24 Changes needed to work with Root 3.01 (substitute lhs [] operator). (Jiri Chudoba)
26 Revision 1.52 2001/06/14 13:49:22 hristov
27 Write a TreeD in SDigits2Digits method (needed to be compatible with alirun script)
29 Revision 1.51 2001/05/31 10:19:52 morsch
30 Fix for new AliRun::RunReco().
32 Revision 1.50 2001/05/16 14:57:17 alibrary
33 New files for folders and Stack
35 Revision 1.49 2001/03/12 17:45:48 hristov
36 Changes needed on Sun with CC 5.0
38 Revision 1.48 2001/03/06 00:01:36 morsch
39 Add Digits2Reco() and FindClusters()
40 Adapt call of cluster finder to new STEER.
42 Revision 1.47 2001/03/05 08:38:36 morsch
43 Digitization related methods moved to AliMUONMerger.
45 Revision 1.46 2001/01/26 21:34:59 morsch
46 Use access functions for AliMUONHit, AliMUONDigit and AliMUONPadHit data members.
48 Revision 1.45 2001/01/26 20:00:49 hristov
49 Major upgrade of AliRoot code
51 Revision 1.44 2001/01/25 17:39:09 morsch
52 Pass size of fNdch and fNrawch to CINT.
54 Revision 1.43 2001/01/23 18:58:19 hristov
55 Initialisation of some pointers
57 Revision 1.42 2001/01/17 20:53:40 hristov
58 Destructors corrected to avoid memory leaks
60 Revision 1.41 2000/12/21 22:12:40 morsch
61 Clean-up of coding rule violations,
63 Revision 1.40 2000/11/29 20:32:26 gosset
65 1. correction for array index out of bounds
66 2. one printout commented
68 Revision 1.39 2000/11/12 17:17:03 pcrochet
69 BuildGeometry of AliMUON for trigger chambers delegated to AliMUONSegmentationTriggerX (same strategy as for tracking chambers)
71 Revision 1.38 2000/11/06 09:20:43 morsch
72 AliMUON delegates part of BuildGeometry() to AliMUONSegmentation using the
73 Draw() method. This avoids code and parameter replication.
75 Revision 1.37 2000/10/26 09:53:37 pcrochet
76 put back trigger chambers in the display (there was a problem in buildgeometry)
78 Revision 1.36 2000/10/25 19:51:18 morsch
79 Correct x-position of chambers.
81 Revision 1.35 2000/10/24 19:46:21 morsch
82 BuildGeometry updated for slats in station 3-4.
84 Revision 1.34 2000/10/18 11:42:06 morsch
85 - AliMUONRawCluster contains z-position.
86 - Some clean-up of useless print statements during initialisations.
88 Revision 1.33 2000/10/09 14:01:57 morsch
89 Unused variables removed.
91 Revision 1.32 2000/10/06 09:08:10 morsch
92 Built geometry includes slat geometry for event display.
94 Revision 1.31 2000/10/02 21:28:08 fca
95 Removal of useless dependecies via forward declarations
97 Revision 1.30 2000/10/02 16:58:29 egangler
98 Cleaning of the code :
101 -> some useless includes removed or replaced by "class" statement
103 Revision 1.29 2000/07/28 13:49:38 morsch
104 SetAcceptance defines inner and outer chamber radii according to angular acceptance.
105 Can be used for simple acceptance studies.
107 Revision 1.28 2000/07/22 16:43:15 morsch
108 Same comment as before, but now done correctly I hope (sorry it's Saturday evening)
110 Revision 1.27 2000/07/22 16:36:50 morsch
111 Change order of indices in creation (new) of xhit and yhit
113 Revision 1.26 2000/07/03 11:54:57 morsch
114 AliMUONSegmentation and AliMUONHitMap have been replaced by AliSegmentation and AliHitMap in STEER
115 The methods GetPadIxy and GetPadXxy of AliMUONSegmentation have changed name to GetPadI and GetPadC.
117 Revision 1.25 2000/06/29 12:34:09 morsch
118 AliMUONSegmentation class has been made independent of AliMUONChamber. This makes
119 it usable with any other geometry class. The link to the object to which it belongs is
120 established via an index. This assumes that there exists a global geometry manager
121 from which the pointer to the parent object can be obtained (in our case gAlice).
123 Revision 1.24 2000/06/28 15:16:35 morsch
124 (1) Client code adapted to new method signatures in AliMUONSegmentation (see comments there)
125 to allow development of slat-muon chamber simulation and reconstruction code in the MUON
126 framework. The changes should have no side effects (mostly dummy arguments).
127 (2) Hit disintegration uses 3-dim hit coordinates to allow simulation
128 of chambers with overlapping modules (MakePadHits, Disintegration).
130 Revision 1.23 2000/06/28 12:19:17 morsch
131 More consequent seperation of global input data services (AliMUONClusterInput singleton) and the
132 cluster and hit reconstruction algorithms in AliMUONClusterFindRawinderVS.
133 AliMUONClusterFinderVS becomes the base class for clustering and hit reconstruction.
134 It requires two cathode planes. Small modifications in the code will make it usable for
135 one cathode plane and, hence, more general (for test beam data).
136 AliMUONClusterFinder is now obsolete.
138 Revision 1.22 2000/06/28 08:06:10 morsch
139 Avoid global variables in AliMUONClusterFinderVS by seperating the input data for the fit from the
140 algorithmic part of the class. Input data resides inside the AliMUONClusterInput singleton.
141 It also naturally takes care of the TMinuit instance.
143 Revision 1.21 2000/06/27 08:54:41 morsch
144 Problems with on constant array sizes (in hitMap, nmuon, xhit, yhit) corrected.
146 Revision 1.20 2000/06/26 14:02:38 morsch
147 Add class AliMUONConstants with MUON specific constants using static memeber data and access methods.
149 Revision 1.19 2000/06/22 13:40:51 morsch
150 scope problem on HP, "i" declared once
151 pow changed to TMath::Power (PH, AM)
153 Revision 1.18 2000/06/15 07:58:48 morsch
154 Code from MUON-dev joined
156 Revision 1.14.4.17 2000/06/14 14:36:46 morsch
157 - add TriggerCircuit (PC)
158 - add GlobalTrigger and LocalTrigger and specific methods (PC)
160 Revision 1.14.4.16 2000/06/09 21:20:28 morsch
161 Most coding rule violations corrected
163 Revision 1.14.4.15 2000/05/02 09:54:32 morsch
164 RULE RN17 violations corrected
166 Revision 1.14.4.12 2000/04/26 12:25:02 morsch
167 Code revised by P. Crochet:
168 - Z position of TriggerChamber changed according to A.Tournaire Priv.Comm.
169 - ToF included in the method MakePadHits
170 - inner radius of flange between beam shielding and trigger corrected
171 - Trigger global volume updated (according to the new geometry)
173 Revision 1.14.4.11 2000/04/19 19:42:08 morsch
174 Some changes of variable names curing viols and methods concerning
175 correlated clusters removed.
177 Revision 1.14.4.10 2000/03/22 16:44:07 gosset
178 Memory leak suppressed in function Digitise:
179 p_adr->Delete() instead of Clear (I.Chevrot and A.Baldisseri)
181 Revision 1.14.4.9 2000/03/20 18:15:25 morsch
182 Positions of trigger chambers corrected (P.C.)
184 Revision 1.14.4.8 2000/02/21 15:38:01 morsch
185 Call to AddHitList introduced to make this version compatible with head.
187 Revision 1.14.4.7 2000/02/20 07:45:53 morsch
188 Bugs in Trigger part of BuildGeomemetry corrected (P.C)
190 Revision 1.14.4.6 2000/02/17 14:28:54 morsch
191 Trigger included into initialization and digitization
193 Revision 1.14.4.5 2000/02/15 10:02:58 morsch
194 Log messages of previous revisions added
196 Revision 1.14.4.2 2000/02/04 10:57:34 gosset
197 Z position of the chambers:
198 it was the Z position of the stations;
199 it is now really the Z position of the chambers.
200 !!!! WARNING: THE CALLS TO "AliMUONChamber::SetZPOS"
201 !!!! AND "AliMUONChamber::ZPosition"
202 !!!! HAVE TO BE CHANGED TO "AliMUONChamber::"SetZ"
203 !!!! AND "AliMUONChamber::Z"
205 Revision 1.14.4.3 2000/02/04 16:19:04 gosset
206 Correction for mis-spelling of NCH
208 Revision 1.14.4.4 2000/02/15 09:43:38 morsch
214 ///////////////////////////////////////////////
215 // Manager and hits classes for set:MUON //
216 ////////////////////////////////////////////////
220 #include <TRotMatrix.h>
221 #include <TGeometry.h>
227 #include <TObjArray.h>
229 #include <TParticle.h>
235 #include <TDirectory.h>
236 #include <TObjectTable.h>
241 #include "AliMUONHit.h"
242 #include "AliMUONPadHit.h"
243 #include "AliMUONDigit.h"
244 #include "AliMUONTransientDigit.h"
245 #include "AliMUONRawCluster.h"
246 #include "AliMUONLocalTrigger.h"
247 #include "AliMUONGlobalTrigger.h"
248 #include "AliMUONTriggerCircuit.h"
249 #include "AliHitMap.h"
250 #include "AliMUONHitMapA1.h"
251 #include "AliMUONChamberTrigger.h"
252 #include "AliMUONConstants.h"
253 #include "AliMUONClusterFinderVS.h"
254 #include "AliMUONTriggerDecision.h"
256 #include "AliHeader.h"
258 #include "AliMUONClusterInput.h"
259 #include "AliMUONMerger.h"
260 #include "iostream.h"
261 #include "AliCallf77.h"
262 #include "AliConst.h"
264 // Defaults parameters for Z positions of chambers
265 // taken from values for "stations" in AliMUON::AliMUON
266 // const Float_t zch[7]={528, 690., 975., 1249., 1449., 1610, 1710.};
267 // and from array "dstation" in AliMUONv1::CreateGeometry
268 // Float_t dstation[5]={20., 20., 20, 20., 20.};
269 // for tracking chambers,
270 // according to (Z1 = zch - dstation) and (Z2 = zch + dstation)
271 // for the first and second chambers in the station, respectively,
272 // and from "DTPLANES" in AliMUONv1::CreateGeometry
273 // const Float_t DTPLANES = 15.;
274 // for trigger chambers,
275 // according to (Z1 = zch) and (Z2 = zch + DTPLANES)
276 // for the first and second chambers in the station, respectively
279 //___________________________________________
282 // Default Constructor
291 fTriggerCircuits = 0;
306 //___________________________________________
307 AliMUON::AliMUON(const char *name, const char *title)
308 : AliDetector(name,title)
312 <img src="gif/alimuon.gif">
316 fHits = new TClonesArray("AliMUONHit",1000);
317 gAlice->AddHitList(fHits);
318 fPadHits = new TClonesArray("AliMUONPadHit",10000);
322 fNCh = AliMUONConstants::NCh();
323 fNTrackingCh = AliMUONConstants::NTrackingCh();
324 fNdch = new Int_t[fNCh];
326 fDchambers = new TObjArray(AliMUONConstants::NCh());
330 for (i=0; i<AliMUONConstants::NCh() ;i++) {
331 fDchambers->AddAt(new TClonesArray("AliMUONDigit",10000),i);
335 fNrawch = new Int_t[fNTrackingCh];
337 fRawClusters = new TObjArray(AliMUONConstants::NTrackingCh());
339 for (i=0; i<AliMUONConstants::NTrackingCh();i++) {
340 fRawClusters->AddAt(new TClonesArray("AliMUONRawCluster",10000),i);
344 fGlobalTrigger = new TClonesArray("AliMUONGlobalTrigger",1);
346 fLocalTrigger = new TClonesArray("AliMUONLocalTrigger",234);
349 SetMarkerColor(kRed);
357 fChambers = new TObjArray(AliMUONConstants::NCh());
359 // Loop over stations
360 for (Int_t st = 0; st < AliMUONConstants::NCh() / 2; st++) {
361 // Loop over 2 chambers in the station
362 for (Int_t stCH = 0; stCH < 2; stCH++) {
365 // Default Parameters for Muon Tracking Stations
370 if (ch < AliMUONConstants::NTrackingCh()) {
371 fChambers->AddAt(new AliMUONChamber(ch),ch);
373 fChambers->AddAt(new AliMUONChamberTrigger(ch),ch);
376 //PH AliMUONChamber* chamber = (AliMUONChamber*) (*fChambers)[ch];
377 AliMUONChamber* chamber = (AliMUONChamber*) fChambers->At(ch);
380 // Default values for Z of chambers
381 chamber->SetZ(AliMUONConstants::DefaultChamberZ(ch));
383 chamber->InitGeo(AliMUONConstants::DefaultChamberZ(ch));
384 // Set chamber inner and outer radius to default
385 chamber->SetRInner(AliMUONConstants::Dmin(st)/2);
386 chamber->SetROuter(AliMUONConstants::Dmax(st)/2);
388 } // Chamber stCH (0, 1) in
389 } // Station st (0...)
390 // fChambers->SetLast(AliMUONConstants::NCh());
403 // cp new design of AliMUONTriggerDecision
404 fTriggerCircuits = new TObjArray(AliMUONConstants::NTriggerCircuit());
405 for (Int_t circ=0; circ<AliMUONConstants::NTriggerCircuit(); circ++) {
406 fTriggerCircuits->AddAt(new AliMUONTriggerCircuit(),circ);
412 //___________________________________________
413 AliMUON::AliMUON(const AliMUON& rMUON)
415 // Dummy copy constructor
423 if(fDebug) printf("%s: Calling AliMUON destructor !!!\n",ClassName());
435 if (fTriggerCircuits){
436 fTriggerCircuits->Delete();
437 delete fTriggerCircuits;
441 fDchambers->Delete();
446 fRawClusters->Delete();
450 if (fNrawch) delete [] fNrawch;
452 // Delete TClonesArrays
460 fGlobalTrigger->Delete();
461 delete fGlobalTrigger;
466 fLocalTrigger->Delete();
467 delete fLocalTrigger;
476 if (fMerger) delete fMerger;
477 if (fNdch) delete [] fNdch;
481 //___________________________________________
482 void AliMUON::AddHit(Int_t track, Int_t *vol, Float_t *hits)
484 TClonesArray &lhits = *fHits;
485 new(lhits[fNhits++]) AliMUONHit(fIshunt,track,vol,hits);
487 //___________________________________________
488 void AliMUON::AddPadHit(Int_t *clhits)
490 TClonesArray &lclusters = *fPadHits;
491 new(lclusters[fNPadHits++]) AliMUONPadHit(clhits);
493 //_____________________________________________________________________________
494 void AliMUON::AddDigits(Int_t id, Int_t *tracks, Int_t *charges, Int_t *digits)
497 // Add a MUON digit to the list
500 //PH TClonesArray &ldigits = *((TClonesArray*)(*fDchambers)[id]);
501 TClonesArray &ldigits = *((TClonesArray*)fDchambers->At(id));
502 new(ldigits[fNdch[id]++]) AliMUONDigit(tracks,charges,digits);
505 //_____________________________________________________________________________
506 void AliMUON::AddRawCluster(Int_t id, const AliMUONRawCluster& c)
509 // Add a MUON digit to the list
512 //PH TClonesArray &lrawcl = *((TClonesArray*)(*fRawClusters)[id]);
513 TClonesArray &lrawcl = *((TClonesArray*)fRawClusters->At(id));
514 new(lrawcl[fNrawch[id]++]) AliMUONRawCluster(c);
517 //___________________________________________
518 void AliMUON::AddGlobalTrigger(Int_t *singlePlus, Int_t *singleMinus,
520 Int_t *pairUnlike, Int_t *pairLike)
522 // add a MUON Global Trigger to the list (only one GlobalTrigger per event !)
523 TClonesArray &globalTrigger = *fGlobalTrigger;
524 new(globalTrigger[fNGlobalTrigger++])
525 AliMUONGlobalTrigger(singlePlus, singleMinus, singleUndef, pairUnlike,
528 //___________________________________________
529 void AliMUON::AddLocalTrigger(Int_t *localtr)
531 // add a MUON Local Trigger to the list
532 TClonesArray &localTrigger = *fLocalTrigger;
533 new(localTrigger[fNLocalTrigger++]) AliMUONLocalTrigger(localtr);
536 //___________________________________________
537 void AliMUON::BuildGeometry()
539 // Geometry for event display
540 for (Int_t i=0; i<7; i++) {
541 for (Int_t j=0; j<2; j++) {
543 this->Chamber(id-1).SegmentationModel(1)->Draw("eventdisplay");
548 //___________________________________________
549 Int_t AliMUON::DistancetoPrimitive(Int_t , Int_t )
554 //___________________________________________
555 void AliMUON::MakeBranch(Option_t* option, const char *file)
558 // Create Tree branches for the MUON.
560 const Int_t kBufferSize = 4000;
562 sprintf(branchname,"%sCluster",GetName());
564 AliDetector::MakeBranch(option,file);
566 const char *cD = strstr(option,"D");
567 const char *cR = strstr(option,"R");
568 const char *cH = strstr(option,"H");
570 if (fPadHits && gAlice->TreeH() && cH) {
571 MakeBranchInTree(gAlice->TreeH(),
572 branchname, &fPadHits, kBufferSize, file);
577 // one branch for digits per chamber
581 for (i=0; i<AliMUONConstants::NCh() ;i++) {
582 sprintf(branchname,"%sDigits%d",GetName(),i+1);
583 if (fDchambers && gAlice->TreeD()) {
584 MakeBranchInTree(gAlice->TreeD(),
585 branchname, &((*fDchambers)[i]), kBufferSize, file);
586 printf("Making Branch %s for digits in chamber %d\n",branchname,i+1);
593 // one branch for raw clusters per chamber
595 printf("Make Branch - TreeR address %p\n",gAlice->TreeR());
599 for (i=0; i<AliMUONConstants::NTrackingCh() ;i++) {
600 sprintf(branchname,"%sRawClusters%d",GetName(),i+1);
601 if (fRawClusters && gAlice->TreeR()) {
602 MakeBranchInTree(gAlice->TreeR(),
603 branchname, &((*fRawClusters)[i]), kBufferSize, file);
604 printf("Making Branch %s for raw clusters in chamber %d\n",branchname,i+1);
608 // one branch for global trigger
610 sprintf(branchname,"%sGlobalTrigger",GetName());
611 if (fGlobalTrigger && gAlice->TreeR()) {
612 MakeBranchInTree(gAlice->TreeR(),
613 branchname, &fGlobalTrigger, kBufferSize, file);
614 printf("Making Branch %s for Global Trigger\n",branchname);
617 // one branch for local trigger
619 sprintf(branchname,"%sLocalTrigger",GetName());
620 if (fLocalTrigger && gAlice->TreeR()) {
621 MakeBranchInTree(gAlice->TreeR(),
622 branchname, &fLocalTrigger, kBufferSize, file);
623 printf("Making Branch %s for Local Trigger\n",branchname);
628 //___________________________________________
629 void AliMUON::SetTreeAddress()
631 // Set branch address for the Hits and Digits Tree.
633 AliDetector::SetTreeAddress();
636 TTree *treeH = gAlice->TreeH();
637 TTree *treeD = gAlice->TreeD();
638 TTree *treeR = gAlice->TreeR();
642 branch = treeH->GetBranch("MUONCluster");
643 if (branch) branch->SetAddress(&fPadHits);
648 for (int i=0; i<AliMUONConstants::NCh(); i++) {
649 sprintf(branchname,"%sDigits%d",GetName(),i+1);
651 branch = treeD->GetBranch(branchname);
652 if (branch) branch->SetAddress(&((*fDchambers)[i]));
657 // printf("SetTreeAddress --- treeR address %p \n",treeR);
660 for (int i=0; i<AliMUONConstants::NTrackingCh(); i++) {
661 sprintf(branchname,"%sRawClusters%d",GetName(),i+1);
663 branch = treeR->GetBranch(branchname);
664 if (branch) branch->SetAddress(&((*fRawClusters)[i]));
669 branch = treeR->GetBranch("MUONLocalTrigger");
670 if (branch) branch->SetAddress(&fLocalTrigger);
672 if (fGlobalTrigger) {
673 branch = treeR->GetBranch("MUONGlobalTrigger");
674 if (branch) branch->SetAddress(&fGlobalTrigger);
678 //___________________________________________
679 void AliMUON::ResetHits()
681 // Reset number of clusters and the cluster array for this detector
682 AliDetector::ResetHits();
684 if (fPadHits) fPadHits->Clear();
687 //____________________________________________
688 void AliMUON::ResetDigits()
691 // Reset number of digits and the digits array for this detector
693 for ( int i=0;i<AliMUONConstants::NCh();i++ ) {
694 //PH if ((*fDchambers)[i]) ((TClonesArray*)(*fDchambers)[i])->Clear();
695 if ((*fDchambers)[i]) ((TClonesArray*)fDchambers->At(i))->Clear();
696 if (fNdch) fNdch[i]=0;
699 //____________________________________________
700 void AliMUON::ResetRawClusters()
703 // Reset number of raw clusters and the raw clust array for this detector
705 for ( int i=0;i<AliMUONConstants::NTrackingCh();i++ ) {
706 //PH if ((*fRawClusters)[i]) ((TClonesArray*)(*fRawClusters)[i])->Clear();
707 if ((*fRawClusters)[i]) ((TClonesArray*)fRawClusters->At(i))->Clear();
708 if (fNrawch) fNrawch[i]=0;
712 //____________________________________________
713 void AliMUON::ResetTrigger()
715 // Reset Local and Global Trigger
717 if (fGlobalTrigger) fGlobalTrigger->Clear();
719 if (fLocalTrigger) fLocalTrigger->Clear();
722 //____________________________________________
723 void AliMUON::SetPadSize(Int_t id, Int_t isec, Float_t p1, Float_t p2)
725 // Set the pad size for chamber id and cathode isec
727 //PH ((AliMUONChamber*) (*fChambers)[i]) ->SetPadSize(isec,p1,p2);
728 //PH ((AliMUONChamber*) (*fChambers)[i+1])->SetPadSize(isec,p1,p2);
729 ((AliMUONChamber*) fChambers->At(i)) ->SetPadSize(isec,p1,p2);
730 ((AliMUONChamber*) fChambers->At(i+1))->SetPadSize(isec,p1,p2);
733 //___________________________________________
734 void AliMUON::SetChambersZ(const Float_t *Z)
736 // Set Z values for all chambers (tracking and trigger)
737 // from the array pointed to by "Z"
738 for (Int_t ch = 0; ch < AliMUONConstants::NCh(); ch++)
739 //PH ((AliMUONChamber*) ((*fChambers)[ch]))->SetZ(Z[ch]);
740 ((AliMUONChamber*) fChambers->At(ch))->SetZ(Z[ch]);
744 //___________________________________________
745 void AliMUON::SetChambersZToDefault()
747 // Set Z values for all chambers (tracking and trigger)
749 SetChambersZ(AliMUONConstants::DefaultChamberZ());
753 //___________________________________________
754 void AliMUON::SetChargeSlope(Int_t id, Float_t p1)
756 // Set the inverse charge slope for chamber id
758 //PH ((AliMUONChamber*) (*fChambers)[i])->SetChargeSlope(p1);
759 //PH ((AliMUONChamber*) (*fChambers)[i+1])->SetChargeSlope(p1);
760 ((AliMUONChamber*) fChambers->At(i))->SetChargeSlope(p1);
761 ((AliMUONChamber*) fChambers->At(i+1))->SetChargeSlope(p1);
764 //___________________________________________
765 void AliMUON::SetChargeSpread(Int_t id, Float_t p1, Float_t p2)
767 // Set sigma of charge spread for chamber id
769 //PH ((AliMUONChamber*) fChambers->At(i))->SetChargeSpread(p1,p2);
770 //PH ((AliMUONChamber*) fChambers->Ati+1])->SetChargeSpread(p1,p2);
771 ((AliMUONChamber*) fChambers->At(i))->SetChargeSpread(p1,p2);
772 ((AliMUONChamber*) fChambers->At(i+1))->SetChargeSpread(p1,p2);
775 //___________________________________________
776 void AliMUON::SetSigmaIntegration(Int_t id, Float_t p1)
778 // Set integration limits for charge spread
780 //PH ((AliMUONChamber*) (*fChambers)[i])->SetSigmaIntegration(p1);
781 //PH ((AliMUONChamber*) (*fChambers)[i+1])->SetSigmaIntegration(p1);
782 ((AliMUONChamber*) fChambers->At(i))->SetSigmaIntegration(p1);
783 ((AliMUONChamber*) fChambers->At(i+1))->SetSigmaIntegration(p1);
786 //___________________________________________
787 void AliMUON::SetMaxAdc(Int_t id, Int_t p1)
789 // Set maximum number for ADCcounts (saturation)
791 //PH ((AliMUONChamber*) (*fChambers)[i])->SetMaxAdc(p1);
792 //PH ((AliMUONChamber*) (*fChambers)[i+1])->SetMaxAdc(p1);
793 ((AliMUONChamber*) fChambers->At(i))->SetMaxAdc(p1);
794 ((AliMUONChamber*) fChambers->At(i+1))->SetMaxAdc(p1);
797 //___________________________________________
798 void AliMUON::SetMaxStepGas(Float_t p1)
800 // Set stepsize in gas
804 //___________________________________________
805 void AliMUON::SetMaxStepAlu(Float_t p1)
807 // Set step size in Alu
811 //___________________________________________
812 void AliMUON::SetMaxDestepGas(Float_t p1)
814 // Set maximum step size in Gas
818 //___________________________________________
819 void AliMUON::SetMaxDestepAlu(Float_t p1)
821 // Set maximum step size in Alu
824 //___________________________________________
825 void AliMUON::SetAcceptance(Bool_t acc, Float_t angmin, Float_t angmax)
827 // Set acceptance cuts
829 fAccMin=angmin*TMath::Pi()/180;
830 fAccMax=angmax*TMath::Pi()/180;
833 for (Int_t st = 0; st < AliMUONConstants::NCh() / 2; st++) {
834 // Loop over 2 chambers in the station
835 for (Int_t stCH = 0; stCH < 2; stCH++) {
837 // Set chamber inner and outer radius according to acceptance cuts
838 Chamber(ch).SetRInner(AliMUONConstants::DefaultChamberZ(ch)*TMath::Tan(fAccMin));
839 Chamber(ch).SetROuter(AliMUONConstants::DefaultChamberZ(ch)*TMath::Tan(fAccMax));
844 //___________________________________________
845 void AliMUON::SetSegmentationModel(Int_t id, Int_t isec, AliSegmentation *segmentation)
847 // Set the segmentation for chamber id cathode isec
848 //PH ((AliMUONChamber*) (*fChambers)[id])->SetSegmentationModel(isec, segmentation);
849 ((AliMUONChamber*) fChambers->At(id))->SetSegmentationModel(isec, segmentation);
852 //___________________________________________
853 void AliMUON::SetResponseModel(Int_t id, AliMUONResponse *response)
855 // Set the response for chamber id
856 //PH ((AliMUONChamber*) (*fChambers)[id])->SetResponseModel(response);
857 ((AliMUONChamber*) fChambers->At(id))->SetResponseModel(response);
860 void AliMUON::SetReconstructionModel(Int_t id, AliMUONClusterFinderVS *reconst)
862 // Set ClusterFinder for chamber id
863 //PH ((AliMUONChamber*) (*fChambers)[id])->SetReconstructionModel(reconst);
864 ((AliMUONChamber*) fChambers->At(id))->SetReconstructionModel(reconst);
867 void AliMUON::SetNsec(Int_t id, Int_t nsec)
869 // Set number of segmented cathods for chamber id
870 //PH ((AliMUONChamber*) (*fChambers)[id])->SetNsec(nsec);
871 ((AliMUONChamber*) fChambers->At(id))->SetNsec(nsec);
874 //___________________________________________
875 void AliMUON::SDigits2Digits()
881 if (gAlice->GetDebug()>0) {
882 cerr<<"AliMUON::SDigits2Digits: create default AliMUONMerger "<<endl;
883 cerr<<" no merging, just digitization of 1 event will be done"<<endl;
885 fMerger = new AliMUONMerger();
890 sprintf(hname,"TreeD%d",gAlice->GetHeader()->GetEvent());
891 gAlice->TreeD()->Write(hname,TObject::kOverwrite);
892 gAlice->TreeD()->Reset();
895 //___________________________________________
896 void AliMUON::MakePadHits(Float_t xhit,Float_t yhit, Float_t zhit,
897 Float_t eloss, Float_t tof, Int_t idvol)
900 // Calls the charge disintegration method of the current chamber and adds
901 // the simulated cluster to the root treee
904 Float_t newclust[6][500];
909 // Integrated pulse height on chamber
915 // if (idvol == 6) printf("\n ->Disintegration %f %f %f", xhit, yhit, eloss );
918 //PH ((AliMUONChamber*) (*fChambers)[idvol])
919 ((AliMUONChamber*) fChambers->At(idvol))
920 ->DisIntegration(eloss, tof, xhit, yhit, zhit, nnew, newclust);
922 // if (idvol == 6) printf("\n nnew %d \n", nnew);
925 for (Int_t i=0; i<nnew; i++) {
926 if (Int_t(newclust[3][i]) > 0) {
929 clhits[1] = Int_t(newclust[5][i]);
931 clhits[2] = Int_t(newclust[0][i]);
933 clhits[3] = Int_t(newclust[1][i]);
935 clhits[4] = Int_t(newclust[2][i]);
937 clhits[5] = Int_t(newclust[3][i]);
938 // Pad: chamber sector
939 clhits[6] = Int_t(newclust[4][i]);
946 //___________________________________________
947 void AliMUON::Trigger(Int_t nev){
948 // call the Trigger Algorithm and fill TreeR
950 Int_t singlePlus[3] = {0,0,0};
951 Int_t singleMinus[3] = {0,0,0};
952 Int_t singleUndef[3] = {0,0,0};
953 Int_t pairUnlike[3] = {0,0,0};
954 Int_t pairLike[3] = {0,0,0};
957 AliMUONTriggerDecision* decision= new AliMUONTriggerDecision(1);
959 decision->GetGlobalTrigger(singlePlus, singleMinus, singleUndef,
960 pairUnlike, pairLike);
961 // add a local trigger in the list
962 AddGlobalTrigger(singlePlus, singleMinus, singleUndef, pairUnlike, pairLike);
965 for (Int_t icirc=0; icirc<AliMUONConstants::NTriggerCircuit(); icirc++) {
966 if(decision->GetITrigger(icirc)==1) {
967 Int_t localtr[7]={0,0,0,0,0,0,0};
968 Int_t loLpt[2]={0,0}; Int_t loHpt[2]={0,0}; Int_t loApt[2]={0,0};
969 decision->GetLutOutput(icirc, loLpt, loHpt, loApt);
971 localtr[1] = decision->GetStripX11(icirc);
972 localtr[2] = decision->GetDev(icirc);
973 localtr[3] = decision->GetStripY11(icirc);
974 for (i=0; i<2; i++) { // convert the Lut output in 1 digit
975 localtr[4] = localtr[4]+Int_t(loLpt[i]*TMath::Power(2,i));
976 localtr[5] = localtr[5]+Int_t(loHpt[i]*TMath::Power(2,i));
977 localtr[6] = localtr[6]+Int_t(loApt[i]*TMath::Power(2,i));
979 AddLocalTrigger(localtr); // add a local trigger in the list
984 gAlice->TreeR()->Fill();
987 sprintf(hname,"TreeR%d",nev);
988 gAlice->TreeR()->Write(hname,TObject::kOverwrite);
989 gAlice->TreeR()->Reset();
990 printf("\n End of trigger for event %d", nev);
994 //____________________________________________
995 void AliMUON::Digits2Reco()
998 Int_t nev = gAlice->GetHeader()->GetEvent();
999 gAlice->TreeR()->Fill();
1001 sprintf(hname,"TreeR%d", nev);
1002 gAlice->TreeR()->Write(hname);
1003 gAlice->TreeR()->Reset();
1005 printf("\n End of cluster finding for event %d", nev);
1008 void AliMUON::FindClusters()
1011 // Perform cluster finding
1013 TClonesArray *dig1, *dig2;
1015 dig1 = new TClonesArray("AliMUONDigit",1000);
1016 dig2 = new TClonesArray("AliMUONDigit",1000);
1017 AliMUONDigit *digit;
1019 // Loop on chambers and on cathode planes
1022 for (Int_t ich = 0; ich < 10; ich++) {
1023 //PH AliMUONChamber* iChamber = (AliMUONChamber*) (*fChambers)[ich];
1024 AliMUONChamber* iChamber = (AliMUONChamber*) fChambers->At(ich);
1025 AliMUONClusterFinderVS* rec = iChamber->ReconstructionModel();
1027 gAlice->ResetDigits();
1028 gAlice->TreeD()->GetEvent(0);
1029 TClonesArray *muonDigits = this->DigitsAddress(ich);
1030 ndig=muonDigits->GetEntriesFast();
1031 printf("\n 1 Found %d digits in %p %d", ndig, muonDigits,ich);
1032 TClonesArray &lhits1 = *dig1;
1034 for (k = 0; k < ndig; k++) {
1035 digit = (AliMUONDigit*) muonDigits->UncheckedAt(k);
1036 if (rec->TestTrack(digit->Track(0)))
1037 new(lhits1[n++]) AliMUONDigit(*digit);
1039 gAlice->ResetDigits();
1040 gAlice->TreeD()->GetEvent(1);
1041 muonDigits = this->DigitsAddress(ich);
1042 ndig=muonDigits->GetEntriesFast();
1043 printf("\n 2 Found %d digits in %p %d", ndig, muonDigits, ich);
1044 TClonesArray &lhits2 = *dig2;
1047 for (k=0; k<ndig; k++) {
1048 digit= (AliMUONDigit*) muonDigits->UncheckedAt(k);
1049 if (rec->TestTrack(digit->Track(0)))
1050 new(lhits2[n++]) AliMUONDigit(*digit);
1054 AliMUONClusterInput::Instance()->SetDigits(ich, dig1, dig2);
1055 rec->FindRawClusters();
1065 void AliMUON::Streamer(TBuffer &R__b)
1067 // Stream an object of class AliMUON.
1068 AliMUONChamber *iChamber;
1069 AliMUONTriggerCircuit *iTriggerCircuit;
1070 AliSegmentation *segmentation;
1071 AliMUONResponse *response;
1072 TClonesArray *digitsaddress;
1073 TClonesArray *rawcladdress;
1075 if (R__b.IsReading()) {
1076 Version_t R__v = R__b.ReadVersion(); if (R__v) { }
1077 AliDetector::Streamer(R__b);
1079 R__b >> fPadHits; // diff
1080 R__b >> fNLocalTrigger;
1081 R__b >> fLocalTrigger;
1082 R__b >> fNGlobalTrigger;
1083 R__b >> fGlobalTrigger;
1085 R__b >> fRawClusters;
1086 R__b.ReadArray(fNdch);
1087 R__b.ReadArray(fNrawch);
1092 R__b >> fTriggerCircuits;
1093 for (i =0; i<AliMUONConstants::NTriggerCircuit(); i++) {
1094 iTriggerCircuit=(AliMUONTriggerCircuit*) (*fTriggerCircuits)[i];
1095 iTriggerCircuit->Streamer(R__b);
1097 // Stream chamber related information
1098 for (i =0; i<AliMUONConstants::NCh(); i++) {
1099 iChamber=(AliMUONChamber*) (*fChambers)[i];
1100 iChamber->Streamer(R__b);
1101 if (iChamber->Nsec()==1) {
1102 segmentation=iChamber->SegmentationModel(1);
1104 segmentation->Streamer(R__b);
1106 segmentation=iChamber->SegmentationModel(1);
1108 segmentation->Streamer(R__b);
1110 segmentation=iChamber->SegmentationModel(2);
1111 segmentation->Streamer(R__b);
1113 response=iChamber->ResponseModel();
1115 response->Streamer(R__b);
1116 digitsaddress=(TClonesArray*) (*fDchambers)[i];
1117 digitsaddress->Streamer(R__b);
1118 if (i < AliMUONConstants::NTrackingCh()) {
1119 rawcladdress=(TClonesArray*) (*fRawClusters)[i];
1120 rawcladdress->Streamer(R__b);
1125 R__b.WriteVersion(AliMUON::IsA());
1126 AliDetector::Streamer(R__b);
1128 R__b << fPadHits; // diff
1129 R__b << fNLocalTrigger;
1130 R__b << fLocalTrigger;
1131 R__b << fNGlobalTrigger;
1132 R__b << fGlobalTrigger;
1134 R__b << fRawClusters;
1135 R__b.WriteArray(fNdch, AliMUONConstants::NCh());
1136 R__b.WriteArray(fNrawch, AliMUONConstants::NTrackingCh());
1143 R__b << fTriggerCircuits;
1144 for (i =0; i<AliMUONConstants::NTriggerCircuit(); i++) {
1145 iTriggerCircuit=(AliMUONTriggerCircuit*) (*fTriggerCircuits)[i];
1146 iTriggerCircuit->Streamer(R__b);
1148 for (i =0; i<AliMUONConstants::NCh(); i++) {
1149 iChamber=(AliMUONChamber*) (*fChambers)[i];
1150 iChamber->Streamer(R__b);
1151 if (iChamber->Nsec()==1) {
1152 segmentation=iChamber->SegmentationModel(1);
1154 segmentation->Streamer(R__b);
1156 segmentation=iChamber->SegmentationModel(1);
1158 segmentation->Streamer(R__b);
1159 segmentation=iChamber->SegmentationModel(2);
1161 segmentation->Streamer(R__b);
1163 response=iChamber->ResponseModel();
1165 response->Streamer(R__b);
1166 digitsaddress=(TClonesArray*) (*fDchambers)[i];
1167 digitsaddress->Streamer(R__b);
1168 if (i < AliMUONConstants::NTrackingCh()) {
1169 rawcladdress=(TClonesArray*) (*fRawClusters)[i];
1170 rawcladdress->Streamer(R__b);
1177 AliMUONPadHit* AliMUON::FirstPad(AliMUONHit* hit, TClonesArray *clusters)
1180 // Initialise the pad iterator
1181 // Return the address of the first padhit for hit
1182 TClonesArray *theClusters = clusters;
1183 Int_t nclust = theClusters->GetEntriesFast();
1184 if (nclust && hit->PHlast() > 0) {
1185 AliMUON::fMaxIterPad=hit->PHlast();
1186 AliMUON::fCurIterPad=hit->PHfirst();
1187 return (AliMUONPadHit*) clusters->UncheckedAt(AliMUON::fCurIterPad-1);
1193 AliMUONPadHit* AliMUON::NextPad(TClonesArray *clusters)
1195 // Get next pad (in iterator)
1197 AliMUON::fCurIterPad++;
1198 if (AliMUON::fCurIterPad <= AliMUON::fMaxIterPad) {
1199 return (AliMUONPadHit*) clusters->UncheckedAt(AliMUON::fCurIterPad-1);
1206 AliMUONRawCluster *AliMUON::RawCluster(Int_t ichamber, Int_t icathod, Int_t icluster)
1209 // Return rawcluster (icluster) for chamber ichamber and cathode icathod
1211 TClonesArray *muonRawCluster = RawClustAddress(ichamber);
1213 TTree *treeR = gAlice->TreeR();
1214 Int_t nent=(Int_t)treeR->GetEntries();
1215 treeR->GetEvent(nent-2+icathod-1);
1216 //treeR->GetEvent(icathod);
1217 //Int_t nrawcl = (Int_t)muonRawCluster->GetEntriesFast();
1219 AliMUONRawCluster * mRaw = (AliMUONRawCluster*)muonRawCluster->UncheckedAt(icluster);
1220 //printf("RawCluster _ nent nrawcl icluster mRaw %d %d %d%p\n",nent,nrawcl,icluster,mRaw);
1225 void AliMUON::SetMerger(AliMUONMerger* merger)
1227 // Set pointer to merger
1231 AliMUONMerger* AliMUON::Merger()
1233 // Return pointer to merger
1239 AliMUON& AliMUON::operator = (const AliMUON& rhs)
1246 ////////////////////////////////////////////////////////////////////////
1247 void AliMUON::MakeBranchInTreeD(TTree *treeD, const char *file)
1250 // Create TreeD branches for the MUON.
1253 const Int_t kBufferSize = 4000;
1254 char branchname[30];
1257 // one branch for digits per chamber
1259 for (Int_t i=0; i<AliMUONConstants::NCh() ;i++) {
1260 sprintf(branchname,"%sDigits%d",GetName(),i+1);
1261 if (fDchambers && treeD) {
1262 MakeBranchInTree(treeD,
1263 branchname, &((*fDchambers)[i]), kBufferSize, file);
1264 // printf("Making Branch %s for digits in chamber %d\n",branchname,i+1);
1269 //___________________________________________