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.54 2001/08/30 09:52:12 hristov
18 The operator[] is replaced by At() or AddAt() in case of TObjArray.
20 Revision 1.53 2001/07/20 10:03:13 morsch
21 Changes needed to work with Root 3.01 (substitute lhs [] operator). (Jiri Chudoba)
23 Revision 1.52 2001/06/14 13:49:22 hristov
24 Write a TreeD in SDigits2Digits method (needed to be compatible with alirun script)
26 Revision 1.51 2001/05/31 10:19:52 morsch
27 Fix for new AliRun::RunReco().
29 Revision 1.50 2001/05/16 14:57:17 alibrary
30 New files for folders and Stack
32 Revision 1.49 2001/03/12 17:45:48 hristov
33 Changes needed on Sun with CC 5.0
35 Revision 1.48 2001/03/06 00:01:36 morsch
36 Add Digits2Reco() and FindClusters()
37 Adapt call of cluster finder to new STEER.
39 Revision 1.47 2001/03/05 08:38:36 morsch
40 Digitization related methods moved to AliMUONMerger.
42 Revision 1.46 2001/01/26 21:34:59 morsch
43 Use access functions for AliMUONHit, AliMUONDigit and AliMUONPadHit data members.
45 Revision 1.45 2001/01/26 20:00:49 hristov
46 Major upgrade of AliRoot code
48 Revision 1.44 2001/01/25 17:39:09 morsch
49 Pass size of fNdch and fNrawch to CINT.
51 Revision 1.43 2001/01/23 18:58:19 hristov
52 Initialisation of some pointers
54 Revision 1.42 2001/01/17 20:53:40 hristov
55 Destructors corrected to avoid memory leaks
57 Revision 1.41 2000/12/21 22:12:40 morsch
58 Clean-up of coding rule violations,
60 Revision 1.40 2000/11/29 20:32:26 gosset
62 1. correction for array index out of bounds
63 2. one printout commented
65 Revision 1.39 2000/11/12 17:17:03 pcrochet
66 BuildGeometry of AliMUON for trigger chambers delegated to AliMUONSegmentationTriggerX (same strategy as for tracking chambers)
68 Revision 1.38 2000/11/06 09:20:43 morsch
69 AliMUON delegates part of BuildGeometry() to AliMUONSegmentation using the
70 Draw() method. This avoids code and parameter replication.
72 Revision 1.37 2000/10/26 09:53:37 pcrochet
73 put back trigger chambers in the display (there was a problem in buildgeometry)
75 Revision 1.36 2000/10/25 19:51:18 morsch
76 Correct x-position of chambers.
78 Revision 1.35 2000/10/24 19:46:21 morsch
79 BuildGeometry updated for slats in station 3-4.
81 Revision 1.34 2000/10/18 11:42:06 morsch
82 - AliMUONRawCluster contains z-position.
83 - Some clean-up of useless print statements during initialisations.
85 Revision 1.33 2000/10/09 14:01:57 morsch
86 Unused variables removed.
88 Revision 1.32 2000/10/06 09:08:10 morsch
89 Built geometry includes slat geometry for event display.
91 Revision 1.31 2000/10/02 21:28:08 fca
92 Removal of useless dependecies via forward declarations
94 Revision 1.30 2000/10/02 16:58:29 egangler
95 Cleaning of the code :
98 -> some useless includes removed or replaced by "class" statement
100 Revision 1.29 2000/07/28 13:49:38 morsch
101 SetAcceptance defines inner and outer chamber radii according to angular acceptance.
102 Can be used for simple acceptance studies.
104 Revision 1.28 2000/07/22 16:43:15 morsch
105 Same comment as before, but now done correctly I hope (sorry it's Saturday evening)
107 Revision 1.27 2000/07/22 16:36:50 morsch
108 Change order of indices in creation (new) of xhit and yhit
110 Revision 1.26 2000/07/03 11:54:57 morsch
111 AliMUONSegmentation and AliMUONHitMap have been replaced by AliSegmentation and AliHitMap in STEER
112 The methods GetPadIxy and GetPadXxy of AliMUONSegmentation have changed name to GetPadI and GetPadC.
114 Revision 1.25 2000/06/29 12:34:09 morsch
115 AliMUONSegmentation class has been made independent of AliMUONChamber. This makes
116 it usable with any other geometry class. The link to the object to which it belongs is
117 established via an index. This assumes that there exists a global geometry manager
118 from which the pointer to the parent object can be obtained (in our case gAlice).
120 Revision 1.24 2000/06/28 15:16:35 morsch
121 (1) Client code adapted to new method signatures in AliMUONSegmentation (see comments there)
122 to allow development of slat-muon chamber simulation and reconstruction code in the MUON
123 framework. The changes should have no side effects (mostly dummy arguments).
124 (2) Hit disintegration uses 3-dim hit coordinates to allow simulation
125 of chambers with overlapping modules (MakePadHits, Disintegration).
127 Revision 1.23 2000/06/28 12:19:17 morsch
128 More consequent seperation of global input data services (AliMUONClusterInput singleton) and the
129 cluster and hit reconstruction algorithms in AliMUONClusterFindRawinderVS.
130 AliMUONClusterFinderVS becomes the base class for clustering and hit reconstruction.
131 It requires two cathode planes. Small modifications in the code will make it usable for
132 one cathode plane and, hence, more general (for test beam data).
133 AliMUONClusterFinder is now obsolete.
135 Revision 1.22 2000/06/28 08:06:10 morsch
136 Avoid global variables in AliMUONClusterFinderVS by seperating the input data for the fit from the
137 algorithmic part of the class. Input data resides inside the AliMUONClusterInput singleton.
138 It also naturally takes care of the TMinuit instance.
140 Revision 1.21 2000/06/27 08:54:41 morsch
141 Problems with on constant array sizes (in hitMap, nmuon, xhit, yhit) corrected.
143 Revision 1.20 2000/06/26 14:02:38 morsch
144 Add class AliMUONConstants with MUON specific constants using static memeber data and access methods.
146 Revision 1.19 2000/06/22 13:40:51 morsch
147 scope problem on HP, "i" declared once
148 pow changed to TMath::Power (PH, AM)
150 Revision 1.18 2000/06/15 07:58:48 morsch
151 Code from MUON-dev joined
153 Revision 1.14.4.17 2000/06/14 14:36:46 morsch
154 - add TriggerCircuit (PC)
155 - add GlobalTrigger and LocalTrigger and specific methods (PC)
157 Revision 1.14.4.16 2000/06/09 21:20:28 morsch
158 Most coding rule violations corrected
160 Revision 1.14.4.15 2000/05/02 09:54:32 morsch
161 RULE RN17 violations corrected
163 Revision 1.14.4.12 2000/04/26 12:25:02 morsch
164 Code revised by P. Crochet:
165 - Z position of TriggerChamber changed according to A.Tournaire Priv.Comm.
166 - ToF included in the method MakePadHits
167 - inner radius of flange between beam shielding and trigger corrected
168 - Trigger global volume updated (according to the new geometry)
170 Revision 1.14.4.11 2000/04/19 19:42:08 morsch
171 Some changes of variable names curing viols and methods concerning
172 correlated clusters removed.
174 Revision 1.14.4.10 2000/03/22 16:44:07 gosset
175 Memory leak suppressed in function Digitise:
176 p_adr->Delete() instead of Clear (I.Chevrot and A.Baldisseri)
178 Revision 1.14.4.9 2000/03/20 18:15:25 morsch
179 Positions of trigger chambers corrected (P.C.)
181 Revision 1.14.4.8 2000/02/21 15:38:01 morsch
182 Call to AddHitList introduced to make this version compatible with head.
184 Revision 1.14.4.7 2000/02/20 07:45:53 morsch
185 Bugs in Trigger part of BuildGeomemetry corrected (P.C)
187 Revision 1.14.4.6 2000/02/17 14:28:54 morsch
188 Trigger included into initialization and digitization
190 Revision 1.14.4.5 2000/02/15 10:02:58 morsch
191 Log messages of previous revisions added
193 Revision 1.14.4.2 2000/02/04 10:57:34 gosset
194 Z position of the chambers:
195 it was the Z position of the stations;
196 it is now really the Z position of the chambers.
197 !!!! WARNING: THE CALLS TO "AliMUONChamber::SetZPOS"
198 !!!! AND "AliMUONChamber::ZPosition"
199 !!!! HAVE TO BE CHANGED TO "AliMUONChamber::"SetZ"
200 !!!! AND "AliMUONChamber::Z"
202 Revision 1.14.4.3 2000/02/04 16:19:04 gosset
203 Correction for mis-spelling of NCH
205 Revision 1.14.4.4 2000/02/15 09:43:38 morsch
211 ///////////////////////////////////////////////
212 // Manager and hits classes for set:MUON //
213 ////////////////////////////////////////////////
217 #include <TRotMatrix.h>
218 #include <TGeometry.h>
224 #include <TObjArray.h>
226 #include <TParticle.h>
232 #include <TDirectory.h>
233 #include <TObjectTable.h>
238 #include "AliMUONHit.h"
239 #include "AliMUONPadHit.h"
240 #include "AliMUONDigit.h"
241 #include "AliMUONTransientDigit.h"
242 #include "AliMUONRawCluster.h"
243 #include "AliMUONLocalTrigger.h"
244 #include "AliMUONGlobalTrigger.h"
245 #include "AliMUONTriggerCircuit.h"
246 #include "AliHitMap.h"
247 #include "AliMUONHitMapA1.h"
248 #include "AliMUONChamberTrigger.h"
249 #include "AliMUONConstants.h"
250 #include "AliMUONClusterFinderVS.h"
251 #include "AliMUONTriggerDecision.h"
253 #include "AliHeader.h"
255 #include "AliMUONClusterInput.h"
256 #include "AliMUONMerger.h"
257 #include "iostream.h"
258 #include "AliCallf77.h"
259 #include "AliConst.h"
261 // Defaults parameters for Z positions of chambers
262 // taken from values for "stations" in AliMUON::AliMUON
263 // const Float_t zch[7]={528, 690., 975., 1249., 1449., 1610, 1710.};
264 // and from array "dstation" in AliMUONv1::CreateGeometry
265 // Float_t dstation[5]={20., 20., 20, 20., 20.};
266 // for tracking chambers,
267 // according to (Z1 = zch - dstation) and (Z2 = zch + dstation)
268 // for the first and second chambers in the station, respectively,
269 // and from "DTPLANES" in AliMUONv1::CreateGeometry
270 // const Float_t DTPLANES = 15.;
271 // for trigger chambers,
272 // according to (Z1 = zch) and (Z2 = zch + DTPLANES)
273 // for the first and second chambers in the station, respectively
276 //___________________________________________
279 // Default Constructor
289 fTriggerCircuits = 0;
307 //___________________________________________
308 AliMUON::AliMUON(const char *name, const char *title)
309 : AliDetector(name,title)
313 <img src="gif/alimuon.gif">
317 fHits = new TClonesArray("AliMUONHit",1000);
318 gAlice->AddHitList(fHits);
319 fPadHits = new TClonesArray("AliMUONPadHit",10000);
323 fNCh = AliMUONConstants::NCh();
324 fNTrackingCh = AliMUONConstants::NTrackingCh();
325 fNdch = new Int_t[fNCh];
327 fDchambers = new TObjArray(AliMUONConstants::NCh());
331 for (i=0; i<AliMUONConstants::NCh() ;i++) {
332 fDchambers->AddAt(new TClonesArray("AliMUONDigit",10000),i);
336 fNrawch = new Int_t[fNTrackingCh];
338 fRawClusters = new TObjArray(AliMUONConstants::NTrackingCh());
340 for (i=0; i<AliMUONConstants::NTrackingCh();i++) {
341 fRawClusters->AddAt(new TClonesArray("AliMUONRawCluster",10000),i);
345 fGlobalTrigger = new TClonesArray("AliMUONGlobalTrigger",1);
347 fLocalTrigger = new TClonesArray("AliMUONLocalTrigger",234);
350 SetMarkerColor(kRed);
358 fChambers = new TObjArray(AliMUONConstants::NCh());
360 // Loop over stations
361 for (Int_t st = 0; st < AliMUONConstants::NCh() / 2; st++) {
362 // Loop over 2 chambers in the station
363 for (Int_t stCH = 0; stCH < 2; stCH++) {
366 // Default Parameters for Muon Tracking Stations
371 if (ch < AliMUONConstants::NTrackingCh()) {
372 fChambers->AddAt(new AliMUONChamber(ch),ch);
374 fChambers->AddAt(new AliMUONChamberTrigger(ch),ch);
377 //PH AliMUONChamber* chamber = (AliMUONChamber*) (*fChambers)[ch];
378 AliMUONChamber* chamber = (AliMUONChamber*) fChambers->At(ch);
381 // Default values for Z of chambers
382 chamber->SetZ(AliMUONConstants::DefaultChamberZ(ch));
384 chamber->InitGeo(AliMUONConstants::DefaultChamberZ(ch));
385 // Set chamber inner and outer radius to default
386 chamber->SetRInner(AliMUONConstants::Dmin(st)/2);
387 chamber->SetROuter(AliMUONConstants::Dmax(st)/2);
389 } // Chamber stCH (0, 1) in
390 } // Station st (0...)
391 // fChambers->SetLast(AliMUONConstants::NCh());
404 // cp new design of AliMUONTriggerDecision
405 fTriggerCircuits = new TObjArray(AliMUONConstants::NTriggerCircuit());
406 for (Int_t circ=0; circ<AliMUONConstants::NTriggerCircuit(); circ++) {
407 fTriggerCircuits->AddAt(new AliMUONTriggerCircuit(),circ);
413 //___________________________________________
414 AliMUON::AliMUON(const AliMUON& rMUON)
416 // Dummy copy constructor
424 if(fDebug) printf("%s: Calling AliMUON destructor !!!\n",ClassName());
436 if (fTriggerCircuits){
437 fTriggerCircuits->Delete();
438 delete fTriggerCircuits;
442 fDchambers->Delete();
447 fRawClusters->Delete();
450 for (i=0;i<AliMUONConstants::NTrackingCh();i++) {
454 // Delete TClonesArrays
462 fGlobalTrigger->Delete();
463 delete fGlobalTrigger;
468 fLocalTrigger->Delete();
469 delete fLocalTrigger;
488 // Delete hits tree for background event
495 if (fMerger) delete fMerger;
498 //___________________________________________
499 void AliMUON::AddHit(Int_t track, Int_t *vol, Float_t *hits)
501 TClonesArray &lhits = *fHits;
502 new(lhits[fNhits++]) AliMUONHit(fIshunt,track,vol,hits);
504 //___________________________________________
505 void AliMUON::AddPadHit(Int_t *clhits)
507 TClonesArray &lclusters = *fPadHits;
508 new(lclusters[fNPadHits++]) AliMUONPadHit(clhits);
510 //_____________________________________________________________________________
511 void AliMUON::AddDigits(Int_t id, Int_t *tracks, Int_t *charges, Int_t *digits)
514 // Add a MUON digit to the list
517 //PH TClonesArray &ldigits = *((TClonesArray*)(*fDchambers)[id]);
518 TClonesArray &ldigits = *((TClonesArray*)fDchambers->At(id));
519 new(ldigits[fNdch[id]++]) AliMUONDigit(tracks,charges,digits);
522 //_____________________________________________________________________________
523 void AliMUON::AddRawCluster(Int_t id, const AliMUONRawCluster& c)
526 // Add a MUON digit to the list
529 //PH TClonesArray &lrawcl = *((TClonesArray*)(*fRawClusters)[id]);
530 TClonesArray &lrawcl = *((TClonesArray*)fRawClusters->At(id));
531 new(lrawcl[fNrawch[id]++]) AliMUONRawCluster(c);
534 //___________________________________________
535 void AliMUON::AddGlobalTrigger(Int_t *singlePlus, Int_t *singleMinus,
537 Int_t *pairUnlike, Int_t *pairLike)
539 // add a MUON Global Trigger to the list (only one GlobalTrigger per event !)
540 TClonesArray &globalTrigger = *fGlobalTrigger;
541 new(globalTrigger[fNGlobalTrigger++])
542 AliMUONGlobalTrigger(singlePlus, singleMinus, singleUndef, pairUnlike,
545 //___________________________________________
546 void AliMUON::AddLocalTrigger(Int_t *localtr)
548 // add a MUON Local Trigger to the list
549 TClonesArray &localTrigger = *fLocalTrigger;
550 new(localTrigger[fNLocalTrigger++]) AliMUONLocalTrigger(localtr);
553 //___________________________________________
554 void AliMUON::BuildGeometry()
556 // Geometry for event display
557 for (Int_t i=0; i<7; i++) {
558 for (Int_t j=0; j<2; j++) {
560 this->Chamber(id-1).SegmentationModel(1)->Draw("eventdisplay");
565 //___________________________________________
566 Int_t AliMUON::DistancetoPrimitive(Int_t , Int_t )
571 //___________________________________________
572 void AliMUON::MakeBranch(Option_t* option, const char *file)
575 // Create Tree branches for the MUON.
577 const Int_t kBufferSize = 4000;
579 sprintf(branchname,"%sCluster",GetName());
581 AliDetector::MakeBranch(option,file);
583 const char *cD = strstr(option,"D");
584 const char *cR = strstr(option,"R");
585 const char *cH = strstr(option,"H");
587 if (fPadHits && gAlice->TreeH() && cH) {
588 MakeBranchInTree(gAlice->TreeH(),
589 branchname, &fPadHits, kBufferSize, file);
594 // one branch for digits per chamber
598 for (i=0; i<AliMUONConstants::NCh() ;i++) {
599 sprintf(branchname,"%sDigits%d",GetName(),i+1);
600 if (fDchambers && gAlice->TreeD()) {
601 MakeBranchInTree(gAlice->TreeD(),
602 branchname, &((*fDchambers)[i]), kBufferSize, file);
603 printf("Making Branch %s for digits in chamber %d\n",branchname,i+1);
610 // one branch for raw clusters per chamber
612 printf("Make Branch - TreeR address %p\n",gAlice->TreeR());
616 for (i=0; i<AliMUONConstants::NTrackingCh() ;i++) {
617 sprintf(branchname,"%sRawClusters%d",GetName(),i+1);
618 if (fRawClusters && gAlice->TreeR()) {
619 MakeBranchInTree(gAlice->TreeR(),
620 branchname, &((*fRawClusters)[i]), kBufferSize, file);
621 printf("Making Branch %s for raw clusters in chamber %d\n",branchname,i+1);
625 // one branch for global trigger
627 sprintf(branchname,"%sGlobalTrigger",GetName());
628 if (fGlobalTrigger && gAlice->TreeR()) {
629 MakeBranchInTree(gAlice->TreeR(),
630 branchname, &fGlobalTrigger, kBufferSize, file);
631 printf("Making Branch %s for Global Trigger\n",branchname);
634 // one branch for local trigger
636 sprintf(branchname,"%sLocalTrigger",GetName());
637 if (fLocalTrigger && gAlice->TreeR()) {
638 MakeBranchInTree(gAlice->TreeR(),
639 branchname, &fLocalTrigger, kBufferSize, file);
640 printf("Making Branch %s for Local Trigger\n",branchname);
645 //___________________________________________
646 void AliMUON::SetTreeAddress()
648 // Set branch address for the Hits and Digits Tree.
650 AliDetector::SetTreeAddress();
653 TTree *treeH = gAlice->TreeH();
654 TTree *treeD = gAlice->TreeD();
655 TTree *treeR = gAlice->TreeR();
659 branch = treeH->GetBranch("MUONCluster");
660 if (branch) branch->SetAddress(&fPadHits);
665 for (int i=0; i<AliMUONConstants::NCh(); i++) {
666 sprintf(branchname,"%sDigits%d",GetName(),i+1);
668 branch = treeD->GetBranch(branchname);
669 if (branch) branch->SetAddress(&((*fDchambers)[i]));
674 // printf("SetTreeAddress --- treeR address %p \n",treeR);
677 for (int i=0; i<AliMUONConstants::NTrackingCh(); i++) {
678 sprintf(branchname,"%sRawClusters%d",GetName(),i+1);
680 branch = treeR->GetBranch(branchname);
681 if (branch) branch->SetAddress(&((*fRawClusters)[i]));
686 branch = treeR->GetBranch("MUONLocalTrigger");
687 if (branch) branch->SetAddress(&fLocalTrigger);
689 if (fGlobalTrigger) {
690 branch = treeR->GetBranch("MUONGlobalTrigger");
691 if (branch) branch->SetAddress(&fGlobalTrigger);
695 //___________________________________________
696 void AliMUON::ResetHits()
698 // Reset number of clusters and the cluster array for this detector
699 AliDetector::ResetHits();
701 if (fPadHits) fPadHits->Clear();
704 //____________________________________________
705 void AliMUON::ResetDigits()
708 // Reset number of digits and the digits array for this detector
710 for ( int i=0;i<AliMUONConstants::NCh();i++ ) {
711 //PH if ((*fDchambers)[i]) ((TClonesArray*)(*fDchambers)[i])->Clear();
712 if ((*fDchambers)[i]) ((TClonesArray*)fDchambers->At(i))->Clear();
713 if (fNdch) fNdch[i]=0;
716 //____________________________________________
717 void AliMUON::ResetRawClusters()
720 // Reset number of raw clusters and the raw clust array for this detector
722 for ( int i=0;i<AliMUONConstants::NTrackingCh();i++ ) {
723 //PH if ((*fRawClusters)[i]) ((TClonesArray*)(*fRawClusters)[i])->Clear();
724 if ((*fRawClusters)[i]) ((TClonesArray*)fRawClusters->At(i))->Clear();
725 if (fNrawch) fNrawch[i]=0;
729 //____________________________________________
730 void AliMUON::ResetTrigger()
732 // Reset Local and Global Trigger
734 if (fGlobalTrigger) fGlobalTrigger->Clear();
736 if (fLocalTrigger) fLocalTrigger->Clear();
739 //____________________________________________
740 void AliMUON::SetPadSize(Int_t id, Int_t isec, Float_t p1, Float_t p2)
742 // Set the pad size for chamber id and cathode isec
744 //PH ((AliMUONChamber*) (*fChambers)[i]) ->SetPadSize(isec,p1,p2);
745 //PH ((AliMUONChamber*) (*fChambers)[i+1])->SetPadSize(isec,p1,p2);
746 ((AliMUONChamber*) fChambers->At(i)) ->SetPadSize(isec,p1,p2);
747 ((AliMUONChamber*) fChambers->At(i+1))->SetPadSize(isec,p1,p2);
750 //___________________________________________
751 void AliMUON::SetChambersZ(const Float_t *Z)
753 // Set Z values for all chambers (tracking and trigger)
754 // from the array pointed to by "Z"
755 for (Int_t ch = 0; ch < AliMUONConstants::NCh(); ch++)
756 //PH ((AliMUONChamber*) ((*fChambers)[ch]))->SetZ(Z[ch]);
757 ((AliMUONChamber*) fChambers->At(ch))->SetZ(Z[ch]);
761 //___________________________________________
762 void AliMUON::SetChambersZToDefault()
764 // Set Z values for all chambers (tracking and trigger)
766 SetChambersZ(AliMUONConstants::DefaultChamberZ());
770 //___________________________________________
771 void AliMUON::SetChargeSlope(Int_t id, Float_t p1)
773 // Set the inverse charge slope for chamber id
775 //PH ((AliMUONChamber*) (*fChambers)[i])->SetChargeSlope(p1);
776 //PH ((AliMUONChamber*) (*fChambers)[i+1])->SetChargeSlope(p1);
777 ((AliMUONChamber*) fChambers->At(i))->SetChargeSlope(p1);
778 ((AliMUONChamber*) fChambers->At(i+1))->SetChargeSlope(p1);
781 //___________________________________________
782 void AliMUON::SetChargeSpread(Int_t id, Float_t p1, Float_t p2)
784 // Set sigma of charge spread for chamber id
786 //PH ((AliMUONChamber*) fChambers->At(i))->SetChargeSpread(p1,p2);
787 //PH ((AliMUONChamber*) fChambers->Ati+1])->SetChargeSpread(p1,p2);
788 ((AliMUONChamber*) fChambers->At(i))->SetChargeSpread(p1,p2);
789 ((AliMUONChamber*) fChambers->At(i+1))->SetChargeSpread(p1,p2);
792 //___________________________________________
793 void AliMUON::SetSigmaIntegration(Int_t id, Float_t p1)
795 // Set integration limits for charge spread
797 //PH ((AliMUONChamber*) (*fChambers)[i])->SetSigmaIntegration(p1);
798 //PH ((AliMUONChamber*) (*fChambers)[i+1])->SetSigmaIntegration(p1);
799 ((AliMUONChamber*) fChambers->At(i))->SetSigmaIntegration(p1);
800 ((AliMUONChamber*) fChambers->At(i+1))->SetSigmaIntegration(p1);
803 //___________________________________________
804 void AliMUON::SetMaxAdc(Int_t id, Int_t p1)
806 // Set maximum number for ADCcounts (saturation)
808 //PH ((AliMUONChamber*) (*fChambers)[i])->SetMaxAdc(p1);
809 //PH ((AliMUONChamber*) (*fChambers)[i+1])->SetMaxAdc(p1);
810 ((AliMUONChamber*) fChambers->At(i))->SetMaxAdc(p1);
811 ((AliMUONChamber*) fChambers->At(i+1))->SetMaxAdc(p1);
814 //___________________________________________
815 void AliMUON::SetMaxStepGas(Float_t p1)
817 // Set stepsize in gas
821 //___________________________________________
822 void AliMUON::SetMaxStepAlu(Float_t p1)
824 // Set step size in Alu
828 //___________________________________________
829 void AliMUON::SetMaxDestepGas(Float_t p1)
831 // Set maximum step size in Gas
835 //___________________________________________
836 void AliMUON::SetMaxDestepAlu(Float_t p1)
838 // Set maximum step size in Alu
841 //___________________________________________
842 void AliMUON::SetAcceptance(Bool_t acc, Float_t angmin, Float_t angmax)
844 // Set acceptance cuts
846 fAccMin=angmin*TMath::Pi()/180;
847 fAccMax=angmax*TMath::Pi()/180;
850 for (Int_t st = 0; st < AliMUONConstants::NCh() / 2; st++) {
851 // Loop over 2 chambers in the station
852 for (Int_t stCH = 0; stCH < 2; stCH++) {
854 // Set chamber inner and outer radius according to acceptance cuts
855 Chamber(ch).SetRInner(AliMUONConstants::DefaultChamberZ(ch)*TMath::Tan(fAccMin));
856 Chamber(ch).SetROuter(AliMUONConstants::DefaultChamberZ(ch)*TMath::Tan(fAccMax));
861 //___________________________________________
862 void AliMUON::SetSegmentationModel(Int_t id, Int_t isec, AliSegmentation *segmentation)
864 // Set the segmentation for chamber id cathode isec
865 //PH ((AliMUONChamber*) (*fChambers)[id])->SetSegmentationModel(isec, segmentation);
866 ((AliMUONChamber*) fChambers->At(id))->SetSegmentationModel(isec, segmentation);
869 //___________________________________________
870 void AliMUON::SetResponseModel(Int_t id, AliMUONResponse *response)
872 // Set the response for chamber id
873 //PH ((AliMUONChamber*) (*fChambers)[id])->SetResponseModel(response);
874 ((AliMUONChamber*) fChambers->At(id))->SetResponseModel(response);
877 void AliMUON::SetReconstructionModel(Int_t id, AliMUONClusterFinderVS *reconst)
879 // Set ClusterFinder for chamber id
880 //PH ((AliMUONChamber*) (*fChambers)[id])->SetReconstructionModel(reconst);
881 ((AliMUONChamber*) fChambers->At(id))->SetReconstructionModel(reconst);
884 void AliMUON::SetNsec(Int_t id, Int_t nsec)
886 // Set number of segmented cathods for chamber id
887 //PH ((AliMUONChamber*) (*fChambers)[id])->SetNsec(nsec);
888 ((AliMUONChamber*) fChambers->At(id))->SetNsec(nsec);
891 //___________________________________________
892 void AliMUON::SDigits2Digits()
898 if (gAlice->GetDebug()>0) {
899 cerr<<"AliMUON::SDigits2Digits: create default AliMUONMerger "<<endl;
900 cerr<<" no merging, just digitization of 1 event will be done"<<endl;
902 fMerger = new AliMUONMerger();
907 sprintf(hname,"TreeD%d",gAlice->GetHeader()->GetEvent());
908 gAlice->TreeD()->Write(hname,TObject::kOverwrite);
909 gAlice->TreeD()->Reset();
912 //___________________________________________
913 void AliMUON::MakePadHits(Float_t xhit,Float_t yhit, Float_t zhit,
914 Float_t eloss, Float_t tof, Int_t idvol)
917 // Calls the charge disintegration method of the current chamber and adds
918 // the simulated cluster to the root treee
921 Float_t newclust[6][500];
926 // Integrated pulse height on chamber
932 // if (idvol == 6) printf("\n ->Disintegration %f %f %f", xhit, yhit, eloss );
935 //PH ((AliMUONChamber*) (*fChambers)[idvol])
936 ((AliMUONChamber*) fChambers->At(idvol))
937 ->DisIntegration(eloss, tof, xhit, yhit, zhit, nnew, newclust);
939 // if (idvol == 6) printf("\n nnew %d \n", nnew);
942 for (Int_t i=0; i<nnew; i++) {
943 if (Int_t(newclust[3][i]) > 0) {
946 clhits[1] = Int_t(newclust[5][i]);
948 clhits[2] = Int_t(newclust[0][i]);
950 clhits[3] = Int_t(newclust[1][i]);
952 clhits[4] = Int_t(newclust[2][i]);
954 clhits[5] = Int_t(newclust[3][i]);
955 // Pad: chamber sector
956 clhits[6] = Int_t(newclust[4][i]);
963 //___________________________________________
964 void AliMUON::Trigger(Int_t nev){
965 // call the Trigger Algorithm and fill TreeR
967 Int_t singlePlus[3] = {0,0,0};
968 Int_t singleMinus[3] = {0,0,0};
969 Int_t singleUndef[3] = {0,0,0};
970 Int_t pairUnlike[3] = {0,0,0};
971 Int_t pairLike[3] = {0,0,0};
974 AliMUONTriggerDecision* decision= new AliMUONTriggerDecision(1);
976 decision->GetGlobalTrigger(singlePlus, singleMinus, singleUndef,
977 pairUnlike, pairLike);
978 // add a local trigger in the list
979 AddGlobalTrigger(singlePlus, singleMinus, singleUndef, pairUnlike, pairLike);
982 for (Int_t icirc=0; icirc<AliMUONConstants::NTriggerCircuit(); icirc++) {
983 if(decision->GetITrigger(icirc)==1) {
984 Int_t localtr[7]={0,0,0,0,0,0,0};
985 Int_t loLpt[2]={0,0}; Int_t loHpt[2]={0,0}; Int_t loApt[2]={0,0};
986 decision->GetLutOutput(icirc, loLpt, loHpt, loApt);
988 localtr[1] = decision->GetStripX11(icirc);
989 localtr[2] = decision->GetDev(icirc);
990 localtr[3] = decision->GetStripY11(icirc);
991 for (i=0; i<2; i++) { // convert the Lut output in 1 digit
992 localtr[4] = localtr[4]+Int_t(loLpt[i]*TMath::Power(2,i));
993 localtr[5] = localtr[5]+Int_t(loHpt[i]*TMath::Power(2,i));
994 localtr[6] = localtr[6]+Int_t(loApt[i]*TMath::Power(2,i));
996 AddLocalTrigger(localtr); // add a local trigger in the list
1001 gAlice->TreeR()->Fill();
1004 sprintf(hname,"TreeR%d",nev);
1005 gAlice->TreeR()->Write(hname,TObject::kOverwrite);
1006 gAlice->TreeR()->Reset();
1007 printf("\n End of trigger for event %d", nev);
1011 //____________________________________________
1012 void AliMUON::Digits2Reco()
1015 Int_t nev = gAlice->GetHeader()->GetEvent();
1016 gAlice->TreeR()->Fill();
1018 sprintf(hname,"TreeR%d", nev);
1019 gAlice->TreeR()->Write(hname);
1020 gAlice->TreeR()->Reset();
1022 printf("\n End of cluster finding for event %d", nev);
1025 void AliMUON::FindClusters()
1028 // Perform cluster finding
1030 TClonesArray *dig1, *dig2;
1032 dig1 = new TClonesArray("AliMUONDigit",1000);
1033 dig2 = new TClonesArray("AliMUONDigit",1000);
1034 AliMUONDigit *digit;
1036 // Loop on chambers and on cathode planes
1039 for (Int_t ich = 0; ich < 10; ich++) {
1040 //PH AliMUONChamber* iChamber = (AliMUONChamber*) (*fChambers)[ich];
1041 AliMUONChamber* iChamber = (AliMUONChamber*) fChambers->At(ich);
1042 AliMUONClusterFinderVS* rec = iChamber->ReconstructionModel();
1044 gAlice->ResetDigits();
1045 gAlice->TreeD()->GetEvent(0);
1046 TClonesArray *muonDigits = this->DigitsAddress(ich);
1047 ndig=muonDigits->GetEntriesFast();
1048 printf("\n 1 Found %d digits in %p %d", ndig, muonDigits,ich);
1049 TClonesArray &lhits1 = *dig1;
1051 for (k = 0; k < ndig; k++) {
1052 digit = (AliMUONDigit*) muonDigits->UncheckedAt(k);
1053 if (rec->TestTrack(digit->Track(0)))
1054 new(lhits1[n++]) AliMUONDigit(*digit);
1056 gAlice->ResetDigits();
1057 gAlice->TreeD()->GetEvent(1);
1058 muonDigits = this->DigitsAddress(ich);
1059 ndig=muonDigits->GetEntriesFast();
1060 printf("\n 2 Found %d digits in %p %d", ndig, muonDigits, ich);
1061 TClonesArray &lhits2 = *dig2;
1064 for (k=0; k<ndig; k++) {
1065 digit= (AliMUONDigit*) muonDigits->UncheckedAt(k);
1066 if (rec->TestTrack(digit->Track(0)))
1067 new(lhits2[n++]) AliMUONDigit(*digit);
1071 AliMUONClusterInput::Instance()->SetDigits(ich, dig1, dig2);
1072 rec->FindRawClusters();
1082 void AliMUON::Streamer(TBuffer &R__b)
1084 // Stream an object of class AliMUON.
1085 AliMUONChamber *iChamber;
1086 AliMUONTriggerCircuit *iTriggerCircuit;
1087 AliSegmentation *segmentation;
1088 AliMUONResponse *response;
1089 TClonesArray *digitsaddress;
1090 TClonesArray *rawcladdress;
1092 if (R__b.IsReading()) {
1093 Version_t R__v = R__b.ReadVersion(); if (R__v) { }
1094 AliDetector::Streamer(R__b);
1096 R__b >> fPadHits; // diff
1097 R__b >> fNLocalTrigger;
1098 R__b >> fLocalTrigger;
1099 R__b >> fNGlobalTrigger;
1100 R__b >> fGlobalTrigger;
1102 R__b >> fRawClusters;
1103 R__b.ReadArray(fNdch);
1104 R__b.ReadArray(fNrawch);
1109 R__b >> fTriggerCircuits;
1110 for (i =0; i<AliMUONConstants::NTriggerCircuit(); i++) {
1111 iTriggerCircuit=(AliMUONTriggerCircuit*) (*fTriggerCircuits)[i];
1112 iTriggerCircuit->Streamer(R__b);
1114 // Stream chamber related information
1115 for (i =0; i<AliMUONConstants::NCh(); i++) {
1116 iChamber=(AliMUONChamber*) (*fChambers)[i];
1117 iChamber->Streamer(R__b);
1118 if (iChamber->Nsec()==1) {
1119 segmentation=iChamber->SegmentationModel(1);
1121 segmentation->Streamer(R__b);
1123 segmentation=iChamber->SegmentationModel(1);
1125 segmentation->Streamer(R__b);
1127 segmentation=iChamber->SegmentationModel(2);
1128 segmentation->Streamer(R__b);
1130 response=iChamber->ResponseModel();
1132 response->Streamer(R__b);
1133 digitsaddress=(TClonesArray*) (*fDchambers)[i];
1134 digitsaddress->Streamer(R__b);
1135 if (i < AliMUONConstants::NTrackingCh()) {
1136 rawcladdress=(TClonesArray*) (*fRawClusters)[i];
1137 rawcladdress->Streamer(R__b);
1142 R__b.WriteVersion(AliMUON::IsA());
1143 AliDetector::Streamer(R__b);
1145 R__b << fPadHits; // diff
1146 R__b << fNLocalTrigger;
1147 R__b << fLocalTrigger;
1148 R__b << fNGlobalTrigger;
1149 R__b << fGlobalTrigger;
1151 R__b << fRawClusters;
1152 R__b.WriteArray(fNdch, AliMUONConstants::NCh());
1153 R__b.WriteArray(fNrawch, AliMUONConstants::NTrackingCh());
1160 R__b << fTriggerCircuits;
1161 for (i =0; i<AliMUONConstants::NTriggerCircuit(); i++) {
1162 iTriggerCircuit=(AliMUONTriggerCircuit*) (*fTriggerCircuits)[i];
1163 iTriggerCircuit->Streamer(R__b);
1165 for (i =0; i<AliMUONConstants::NCh(); i++) {
1166 iChamber=(AliMUONChamber*) (*fChambers)[i];
1167 iChamber->Streamer(R__b);
1168 if (iChamber->Nsec()==1) {
1169 segmentation=iChamber->SegmentationModel(1);
1171 segmentation->Streamer(R__b);
1173 segmentation=iChamber->SegmentationModel(1);
1175 segmentation->Streamer(R__b);
1176 segmentation=iChamber->SegmentationModel(2);
1178 segmentation->Streamer(R__b);
1180 response=iChamber->ResponseModel();
1182 response->Streamer(R__b);
1183 digitsaddress=(TClonesArray*) (*fDchambers)[i];
1184 digitsaddress->Streamer(R__b);
1185 if (i < AliMUONConstants::NTrackingCh()) {
1186 rawcladdress=(TClonesArray*) (*fRawClusters)[i];
1187 rawcladdress->Streamer(R__b);
1194 AliMUONPadHit* AliMUON::FirstPad(AliMUONHit* hit, TClonesArray *clusters)
1197 // Initialise the pad iterator
1198 // Return the address of the first padhit for hit
1199 TClonesArray *theClusters = clusters;
1200 Int_t nclust = theClusters->GetEntriesFast();
1201 if (nclust && hit->PHlast() > 0) {
1202 AliMUON::fMaxIterPad=hit->PHlast();
1203 AliMUON::fCurIterPad=hit->PHfirst();
1204 return (AliMUONPadHit*) clusters->UncheckedAt(AliMUON::fCurIterPad-1);
1210 AliMUONPadHit* AliMUON::NextPad(TClonesArray *clusters)
1212 // Get next pad (in iterator)
1214 AliMUON::fCurIterPad++;
1215 if (AliMUON::fCurIterPad <= AliMUON::fMaxIterPad) {
1216 return (AliMUONPadHit*) clusters->UncheckedAt(AliMUON::fCurIterPad-1);
1223 AliMUONRawCluster *AliMUON::RawCluster(Int_t ichamber, Int_t icathod, Int_t icluster)
1226 // Return rawcluster (icluster) for chamber ichamber and cathode icathod
1228 TClonesArray *muonRawCluster = RawClustAddress(ichamber);
1230 TTree *treeR = gAlice->TreeR();
1231 Int_t nent=(Int_t)treeR->GetEntries();
1232 treeR->GetEvent(nent-2+icathod-1);
1233 //treeR->GetEvent(icathod);
1234 //Int_t nrawcl = (Int_t)muonRawCluster->GetEntriesFast();
1236 AliMUONRawCluster * mRaw = (AliMUONRawCluster*)muonRawCluster->UncheckedAt(icluster);
1237 //printf("RawCluster _ nent nrawcl icluster mRaw %d %d %d%p\n",nent,nrawcl,icluster,mRaw);
1242 void AliMUON::SetMerger(AliMUONMerger* merger)
1244 // Set pointer to merger
1248 AliMUONMerger* AliMUON::Merger()
1250 // Return pointer to merger
1256 AliMUON& AliMUON::operator = (const AliMUON& rhs)
1263 ////////////////////////////////////////////////////////////////////////
1264 void AliMUON::MakeBranchInTreeD(TTree *treeD, const char *file)
1267 // Create TreeD branches for the MUON.
1270 const Int_t kBufferSize = 4000;
1271 char branchname[30];
1274 // one branch for digits per chamber
1276 for (Int_t i=0; i<AliMUONConstants::NCh() ;i++) {
1277 sprintf(branchname,"%sDigits%d",GetName(),i+1);
1278 if (fDchambers && treeD) {
1279 MakeBranchInTree(treeD,
1280 branchname, &((*fDchambers)[i]), kBufferSize, file);
1281 printf("Making Branch %s for digits in chamber %d\n",branchname,i+1);
1286 //___________________________________________