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.53 2001/07/20 10:03:13 morsch
18 Changes needed to work with Root 3.01 (substitute lhs [] operator). (Jiri Chudoba)
20 Revision 1.52 2001/06/14 13:49:22 hristov
21 Write a TreeD in SDigits2Digits method (needed to be compatible with alirun script)
23 Revision 1.51 2001/05/31 10:19:52 morsch
24 Fix for new AliRun::RunReco().
26 Revision 1.50 2001/05/16 14:57:17 alibrary
27 New files for folders and Stack
29 Revision 1.49 2001/03/12 17:45:48 hristov
30 Changes needed on Sun with CC 5.0
32 Revision 1.48 2001/03/06 00:01:36 morsch
33 Add Digits2Reco() and FindClusters()
34 Adapt call of cluster finder to new STEER.
36 Revision 1.47 2001/03/05 08:38:36 morsch
37 Digitization related methods moved to AliMUONMerger.
39 Revision 1.46 2001/01/26 21:34:59 morsch
40 Use access functions for AliMUONHit, AliMUONDigit and AliMUONPadHit data members.
42 Revision 1.45 2001/01/26 20:00:49 hristov
43 Major upgrade of AliRoot code
45 Revision 1.44 2001/01/25 17:39:09 morsch
46 Pass size of fNdch and fNrawch to CINT.
48 Revision 1.43 2001/01/23 18:58:19 hristov
49 Initialisation of some pointers
51 Revision 1.42 2001/01/17 20:53:40 hristov
52 Destructors corrected to avoid memory leaks
54 Revision 1.41 2000/12/21 22:12:40 morsch
55 Clean-up of coding rule violations,
57 Revision 1.40 2000/11/29 20:32:26 gosset
59 1. correction for array index out of bounds
60 2. one printout commented
62 Revision 1.39 2000/11/12 17:17:03 pcrochet
63 BuildGeometry of AliMUON for trigger chambers delegated to AliMUONSegmentationTriggerX (same strategy as for tracking chambers)
65 Revision 1.38 2000/11/06 09:20:43 morsch
66 AliMUON delegates part of BuildGeometry() to AliMUONSegmentation using the
67 Draw() method. This avoids code and parameter replication.
69 Revision 1.37 2000/10/26 09:53:37 pcrochet
70 put back trigger chambers in the display (there was a problem in buildgeometry)
72 Revision 1.36 2000/10/25 19:51:18 morsch
73 Correct x-position of chambers.
75 Revision 1.35 2000/10/24 19:46:21 morsch
76 BuildGeometry updated for slats in station 3-4.
78 Revision 1.34 2000/10/18 11:42:06 morsch
79 - AliMUONRawCluster contains z-position.
80 - Some clean-up of useless print statements during initialisations.
82 Revision 1.33 2000/10/09 14:01:57 morsch
83 Unused variables removed.
85 Revision 1.32 2000/10/06 09:08:10 morsch
86 Built geometry includes slat geometry for event display.
88 Revision 1.31 2000/10/02 21:28:08 fca
89 Removal of useless dependecies via forward declarations
91 Revision 1.30 2000/10/02 16:58:29 egangler
92 Cleaning of the code :
95 -> some useless includes removed or replaced by "class" statement
97 Revision 1.29 2000/07/28 13:49:38 morsch
98 SetAcceptance defines inner and outer chamber radii according to angular acceptance.
99 Can be used for simple acceptance studies.
101 Revision 1.28 2000/07/22 16:43:15 morsch
102 Same comment as before, but now done correctly I hope (sorry it's Saturday evening)
104 Revision 1.27 2000/07/22 16:36:50 morsch
105 Change order of indices in creation (new) of xhit and yhit
107 Revision 1.26 2000/07/03 11:54:57 morsch
108 AliMUONSegmentation and AliMUONHitMap have been replaced by AliSegmentation and AliHitMap in STEER
109 The methods GetPadIxy and GetPadXxy of AliMUONSegmentation have changed name to GetPadI and GetPadC.
111 Revision 1.25 2000/06/29 12:34:09 morsch
112 AliMUONSegmentation class has been made independent of AliMUONChamber. This makes
113 it usable with any other geometry class. The link to the object to which it belongs is
114 established via an index. This assumes that there exists a global geometry manager
115 from which the pointer to the parent object can be obtained (in our case gAlice).
117 Revision 1.24 2000/06/28 15:16:35 morsch
118 (1) Client code adapted to new method signatures in AliMUONSegmentation (see comments there)
119 to allow development of slat-muon chamber simulation and reconstruction code in the MUON
120 framework. The changes should have no side effects (mostly dummy arguments).
121 (2) Hit disintegration uses 3-dim hit coordinates to allow simulation
122 of chambers with overlapping modules (MakePadHits, Disintegration).
124 Revision 1.23 2000/06/28 12:19:17 morsch
125 More consequent seperation of global input data services (AliMUONClusterInput singleton) and the
126 cluster and hit reconstruction algorithms in AliMUONClusterFindRawinderVS.
127 AliMUONClusterFinderVS becomes the base class for clustering and hit reconstruction.
128 It requires two cathode planes. Small modifications in the code will make it usable for
129 one cathode plane and, hence, more general (for test beam data).
130 AliMUONClusterFinder is now obsolete.
132 Revision 1.22 2000/06/28 08:06:10 morsch
133 Avoid global variables in AliMUONClusterFinderVS by seperating the input data for the fit from the
134 algorithmic part of the class. Input data resides inside the AliMUONClusterInput singleton.
135 It also naturally takes care of the TMinuit instance.
137 Revision 1.21 2000/06/27 08:54:41 morsch
138 Problems with on constant array sizes (in hitMap, nmuon, xhit, yhit) corrected.
140 Revision 1.20 2000/06/26 14:02:38 morsch
141 Add class AliMUONConstants with MUON specific constants using static memeber data and access methods.
143 Revision 1.19 2000/06/22 13:40:51 morsch
144 scope problem on HP, "i" declared once
145 pow changed to TMath::Power (PH, AM)
147 Revision 1.18 2000/06/15 07:58:48 morsch
148 Code from MUON-dev joined
150 Revision 1.14.4.17 2000/06/14 14:36:46 morsch
151 - add TriggerCircuit (PC)
152 - add GlobalTrigger and LocalTrigger and specific methods (PC)
154 Revision 1.14.4.16 2000/06/09 21:20:28 morsch
155 Most coding rule violations corrected
157 Revision 1.14.4.15 2000/05/02 09:54:32 morsch
158 RULE RN17 violations corrected
160 Revision 1.14.4.12 2000/04/26 12:25:02 morsch
161 Code revised by P. Crochet:
162 - Z position of TriggerChamber changed according to A.Tournaire Priv.Comm.
163 - ToF included in the method MakePadHits
164 - inner radius of flange between beam shielding and trigger corrected
165 - Trigger global volume updated (according to the new geometry)
167 Revision 1.14.4.11 2000/04/19 19:42:08 morsch
168 Some changes of variable names curing viols and methods concerning
169 correlated clusters removed.
171 Revision 1.14.4.10 2000/03/22 16:44:07 gosset
172 Memory leak suppressed in function Digitise:
173 p_adr->Delete() instead of Clear (I.Chevrot and A.Baldisseri)
175 Revision 1.14.4.9 2000/03/20 18:15:25 morsch
176 Positions of trigger chambers corrected (P.C.)
178 Revision 1.14.4.8 2000/02/21 15:38:01 morsch
179 Call to AddHitList introduced to make this version compatible with head.
181 Revision 1.14.4.7 2000/02/20 07:45:53 morsch
182 Bugs in Trigger part of BuildGeomemetry corrected (P.C)
184 Revision 1.14.4.6 2000/02/17 14:28:54 morsch
185 Trigger included into initialization and digitization
187 Revision 1.14.4.5 2000/02/15 10:02:58 morsch
188 Log messages of previous revisions added
190 Revision 1.14.4.2 2000/02/04 10:57:34 gosset
191 Z position of the chambers:
192 it was the Z position of the stations;
193 it is now really the Z position of the chambers.
194 !!!! WARNING: THE CALLS TO "AliMUONChamber::SetZPOS"
195 !!!! AND "AliMUONChamber::ZPosition"
196 !!!! HAVE TO BE CHANGED TO "AliMUONChamber::"SetZ"
197 !!!! AND "AliMUONChamber::Z"
199 Revision 1.14.4.3 2000/02/04 16:19:04 gosset
200 Correction for mis-spelling of NCH
202 Revision 1.14.4.4 2000/02/15 09:43:38 morsch
208 ///////////////////////////////////////////////
209 // Manager and hits classes for set:MUON //
210 ////////////////////////////////////////////////
214 #include <TRotMatrix.h>
215 #include <TGeometry.h>
221 #include <TObjArray.h>
223 #include <TParticle.h>
229 #include <TDirectory.h>
230 #include <TObjectTable.h>
235 #include "AliMUONHit.h"
236 #include "AliMUONPadHit.h"
237 #include "AliMUONDigit.h"
238 #include "AliMUONTransientDigit.h"
239 #include "AliMUONRawCluster.h"
240 #include "AliMUONLocalTrigger.h"
241 #include "AliMUONGlobalTrigger.h"
242 #include "AliMUONTriggerCircuit.h"
243 #include "AliHitMap.h"
244 #include "AliMUONHitMapA1.h"
245 #include "AliMUONChamberTrigger.h"
246 #include "AliMUONConstants.h"
247 #include "AliMUONClusterFinderVS.h"
248 #include "AliMUONTriggerDecision.h"
250 #include "AliHeader.h"
252 #include "AliMUONClusterInput.h"
253 #include "AliMUONMerger.h"
254 #include "iostream.h"
255 #include "AliCallf77.h"
256 #include "AliConst.h"
258 // Defaults parameters for Z positions of chambers
259 // taken from values for "stations" in AliMUON::AliMUON
260 // const Float_t zch[7]={528, 690., 975., 1249., 1449., 1610, 1710.};
261 // and from array "dstation" in AliMUONv1::CreateGeometry
262 // Float_t dstation[5]={20., 20., 20, 20., 20.};
263 // for tracking chambers,
264 // according to (Z1 = zch - dstation) and (Z2 = zch + dstation)
265 // for the first and second chambers in the station, respectively,
266 // and from "DTPLANES" in AliMUONv1::CreateGeometry
267 // const Float_t DTPLANES = 15.;
268 // for trigger chambers,
269 // according to (Z1 = zch) and (Z2 = zch + DTPLANES)
270 // for the first and second chambers in the station, respectively
273 //___________________________________________
276 // Default Constructor
286 fTriggerCircuits = 0;
300 //___________________________________________
301 AliMUON::AliMUON(const char *name, const char *title)
302 : AliDetector(name,title)
306 <img src="gif/alimuon.gif">
310 fHits = new TClonesArray("AliMUONHit",1000);
311 gAlice->AddHitList(fHits);
312 fPadHits = new TClonesArray("AliMUONPadHit",10000);
316 fNCh = AliMUONConstants::NCh();
317 fNTrackingCh = AliMUONConstants::NTrackingCh();
318 fNdch = new Int_t[fNCh];
320 fDchambers = new TObjArray(AliMUONConstants::NCh());
324 for (i=0; i<AliMUONConstants::NCh() ;i++) {
325 fDchambers->AddAt(new TClonesArray("AliMUONDigit",10000),i);
329 fNrawch = new Int_t[fNTrackingCh];
331 fRawClusters = new TObjArray(AliMUONConstants::NTrackingCh());
333 for (i=0; i<AliMUONConstants::NTrackingCh();i++) {
334 fRawClusters->AddAt(new TClonesArray("AliMUONRawCluster",10000),i);
338 fGlobalTrigger = new TClonesArray("AliMUONGlobalTrigger",1);
340 fLocalTrigger = new TClonesArray("AliMUONLocalTrigger",234);
343 SetMarkerColor(kRed);
351 fChambers = new TObjArray(AliMUONConstants::NCh());
353 // Loop over stations
354 for (Int_t st = 0; st < AliMUONConstants::NCh() / 2; st++) {
355 // Loop over 2 chambers in the station
356 for (Int_t stCH = 0; stCH < 2; stCH++) {
359 // Default Parameters for Muon Tracking Stations
364 if (ch < AliMUONConstants::NTrackingCh()) {
365 fChambers->AddAt(new AliMUONChamber(ch),ch);
367 fChambers->AddAt(new AliMUONChamberTrigger(ch),ch);
370 //PH AliMUONChamber* chamber = (AliMUONChamber*) (*fChambers)[ch];
371 AliMUONChamber* chamber = (AliMUONChamber*) fChambers->At(ch);
374 // Default values for Z of chambers
375 chamber->SetZ(AliMUONConstants::DefaultChamberZ(ch));
377 chamber->InitGeo(AliMUONConstants::DefaultChamberZ(ch));
378 // Set chamber inner and outer radius to default
379 chamber->SetRInner(AliMUONConstants::Dmin(st)/2);
380 chamber->SetROuter(AliMUONConstants::Dmax(st)/2);
382 } // Chamber stCH (0, 1) in
383 } // Station st (0...)
384 // fChambers->SetLast(AliMUONConstants::NCh());
397 // cp new design of AliMUONTriggerDecision
398 fTriggerCircuits = new TObjArray(AliMUONConstants::NTriggerCircuit());
399 for (Int_t circ=0; circ<AliMUONConstants::NTriggerCircuit(); circ++) {
400 fTriggerCircuits->AddAt(new AliMUONTriggerCircuit(),circ);
406 //___________________________________________
407 AliMUON::AliMUON(const AliMUON& rMUON)
409 // Dummy copy constructor
417 if(fDebug) printf("%s: Calling AliMUON destructor !!!\n",ClassName());
429 if (fTriggerCircuits){
430 fTriggerCircuits->Delete();
431 delete fTriggerCircuits;
435 fDchambers->Delete();
440 fRawClusters->Delete();
443 for (i=0;i<AliMUONConstants::NTrackingCh();i++) {
447 // Delete TClonesArrays
455 fGlobalTrigger->Delete();
456 delete fGlobalTrigger;
461 fLocalTrigger->Delete();
462 delete fLocalTrigger;
481 // Delete hits tree for background event
488 if (fMerger) delete fMerger;
491 //___________________________________________
492 void AliMUON::AddHit(Int_t track, Int_t *vol, Float_t *hits)
494 TClonesArray &lhits = *fHits;
495 new(lhits[fNhits++]) AliMUONHit(fIshunt,track,vol,hits);
497 //___________________________________________
498 void AliMUON::AddPadHit(Int_t *clhits)
500 TClonesArray &lclusters = *fPadHits;
501 new(lclusters[fNPadHits++]) AliMUONPadHit(clhits);
503 //_____________________________________________________________________________
504 void AliMUON::AddDigits(Int_t id, Int_t *tracks, Int_t *charges, Int_t *digits)
507 // Add a MUON digit to the list
510 //PH TClonesArray &ldigits = *((TClonesArray*)(*fDchambers)[id]);
511 TClonesArray &ldigits = *((TClonesArray*)fDchambers->At(id));
512 new(ldigits[fNdch[id]++]) AliMUONDigit(tracks,charges,digits);
515 //_____________________________________________________________________________
516 void AliMUON::AddRawCluster(Int_t id, const AliMUONRawCluster& c)
519 // Add a MUON digit to the list
522 //PH TClonesArray &lrawcl = *((TClonesArray*)(*fRawClusters)[id]);
523 TClonesArray &lrawcl = *((TClonesArray*)fRawClusters->At(id));
524 new(lrawcl[fNrawch[id]++]) AliMUONRawCluster(c);
527 //___________________________________________
528 void AliMUON::AddGlobalTrigger(Int_t *singlePlus, Int_t *singleMinus,
530 Int_t *pairUnlike, Int_t *pairLike)
532 // add a MUON Global Trigger to the list (only one GlobalTrigger per event !)
533 TClonesArray &globalTrigger = *fGlobalTrigger;
534 new(globalTrigger[fNGlobalTrigger++])
535 AliMUONGlobalTrigger(singlePlus, singleMinus, singleUndef, pairUnlike,
538 //___________________________________________
539 void AliMUON::AddLocalTrigger(Int_t *localtr)
541 // add a MUON Local Trigger to the list
542 TClonesArray &localTrigger = *fLocalTrigger;
543 new(localTrigger[fNLocalTrigger++]) AliMUONLocalTrigger(localtr);
546 //___________________________________________
547 void AliMUON::BuildGeometry()
549 // Geometry for event display
550 for (Int_t i=0; i<7; i++) {
551 for (Int_t j=0; j<2; j++) {
553 this->Chamber(id-1).SegmentationModel(1)->Draw("eventdisplay");
558 //___________________________________________
559 Int_t AliMUON::DistancetoPrimitive(Int_t , Int_t )
564 //___________________________________________
565 void AliMUON::MakeBranch(Option_t* option, const char *file)
568 // Create Tree branches for the MUON.
570 const Int_t kBufferSize = 4000;
572 sprintf(branchname,"%sCluster",GetName());
574 AliDetector::MakeBranch(option,file);
576 const char *cD = strstr(option,"D");
577 const char *cR = strstr(option,"R");
578 const char *cH = strstr(option,"H");
580 if (fPadHits && gAlice->TreeH() && cH) {
581 MakeBranchInTree(gAlice->TreeH(),
582 branchname, &fPadHits, kBufferSize, file);
587 // one branch for digits per chamber
591 for (i=0; i<AliMUONConstants::NCh() ;i++) {
592 sprintf(branchname,"%sDigits%d",GetName(),i+1);
593 if (fDchambers && gAlice->TreeD()) {
594 MakeBranchInTree(gAlice->TreeD(),
595 branchname, &((*fDchambers)[i]), kBufferSize, file);
596 printf("Making Branch %s for digits in chamber %d\n",branchname,i+1);
603 // one branch for raw clusters per chamber
605 printf("Make Branch - TreeR address %p\n",gAlice->TreeR());
609 for (i=0; i<AliMUONConstants::NTrackingCh() ;i++) {
610 sprintf(branchname,"%sRawClusters%d",GetName(),i+1);
611 if (fRawClusters && gAlice->TreeR()) {
612 MakeBranchInTree(gAlice->TreeR(),
613 branchname, &((*fRawClusters)[i]), kBufferSize, file);
614 printf("Making Branch %s for raw clusters in chamber %d\n",branchname,i+1);
618 // one branch for global trigger
620 sprintf(branchname,"%sGlobalTrigger",GetName());
621 if (fGlobalTrigger && gAlice->TreeR()) {
622 MakeBranchInTree(gAlice->TreeR(),
623 branchname, &fGlobalTrigger, kBufferSize, file);
624 printf("Making Branch %s for Global Trigger\n",branchname);
627 // one branch for local trigger
629 sprintf(branchname,"%sLocalTrigger",GetName());
630 if (fLocalTrigger && gAlice->TreeR()) {
631 MakeBranchInTree(gAlice->TreeR(),
632 branchname, &fLocalTrigger, kBufferSize, file);
633 printf("Making Branch %s for Local Trigger\n",branchname);
638 //___________________________________________
639 void AliMUON::SetTreeAddress()
641 // Set branch address for the Hits and Digits Tree.
643 AliDetector::SetTreeAddress();
646 TTree *treeH = gAlice->TreeH();
647 TTree *treeD = gAlice->TreeD();
648 TTree *treeR = gAlice->TreeR();
652 branch = treeH->GetBranch("MUONCluster");
653 if (branch) branch->SetAddress(&fPadHits);
658 for (int i=0; i<AliMUONConstants::NCh(); i++) {
659 sprintf(branchname,"%sDigits%d",GetName(),i+1);
661 branch = treeD->GetBranch(branchname);
662 if (branch) branch->SetAddress(&((*fDchambers)[i]));
667 // printf("SetTreeAddress --- treeR address %p \n",treeR);
670 for (int i=0; i<AliMUONConstants::NTrackingCh(); i++) {
671 sprintf(branchname,"%sRawClusters%d",GetName(),i+1);
673 branch = treeR->GetBranch(branchname);
674 if (branch) branch->SetAddress(&((*fRawClusters)[i]));
679 branch = treeR->GetBranch("MUONLocalTrigger");
680 if (branch) branch->SetAddress(&fLocalTrigger);
682 if (fGlobalTrigger) {
683 branch = treeR->GetBranch("MUONGlobalTrigger");
684 if (branch) branch->SetAddress(&fGlobalTrigger);
688 //___________________________________________
689 void AliMUON::ResetHits()
691 // Reset number of clusters and the cluster array for this detector
692 AliDetector::ResetHits();
694 if (fPadHits) fPadHits->Clear();
697 //____________________________________________
698 void AliMUON::ResetDigits()
701 // Reset number of digits and the digits array for this detector
703 for ( int i=0;i<AliMUONConstants::NCh();i++ ) {
704 //PH if ((*fDchambers)[i]) ((TClonesArray*)(*fDchambers)[i])->Clear();
705 if ((*fDchambers)[i]) ((TClonesArray*)fDchambers->At(i))->Clear();
706 if (fNdch) fNdch[i]=0;
709 //____________________________________________
710 void AliMUON::ResetRawClusters()
713 // Reset number of raw clusters and the raw clust array for this detector
715 for ( int i=0;i<AliMUONConstants::NTrackingCh();i++ ) {
716 //PH if ((*fRawClusters)[i]) ((TClonesArray*)(*fRawClusters)[i])->Clear();
717 if ((*fRawClusters)[i]) ((TClonesArray*)fRawClusters->At(i))->Clear();
718 if (fNrawch) fNrawch[i]=0;
722 //____________________________________________
723 void AliMUON::ResetTrigger()
725 // Reset Local and Global Trigger
727 if (fGlobalTrigger) fGlobalTrigger->Clear();
729 if (fLocalTrigger) fLocalTrigger->Clear();
732 //____________________________________________
733 void AliMUON::SetPadSize(Int_t id, Int_t isec, Float_t p1, Float_t p2)
735 // Set the pad size for chamber id and cathode isec
737 //PH ((AliMUONChamber*) (*fChambers)[i]) ->SetPadSize(isec,p1,p2);
738 //PH ((AliMUONChamber*) (*fChambers)[i+1])->SetPadSize(isec,p1,p2);
739 ((AliMUONChamber*) fChambers->At(i)) ->SetPadSize(isec,p1,p2);
740 ((AliMUONChamber*) fChambers->At(i+1))->SetPadSize(isec,p1,p2);
743 //___________________________________________
744 void AliMUON::SetChambersZ(const Float_t *Z)
746 // Set Z values for all chambers (tracking and trigger)
747 // from the array pointed to by "Z"
748 for (Int_t ch = 0; ch < AliMUONConstants::NCh(); ch++)
749 //PH ((AliMUONChamber*) ((*fChambers)[ch]))->SetZ(Z[ch]);
750 ((AliMUONChamber*) fChambers->At(ch))->SetZ(Z[ch]);
754 //___________________________________________
755 void AliMUON::SetChambersZToDefault()
757 // Set Z values for all chambers (tracking and trigger)
759 SetChambersZ(AliMUONConstants::DefaultChamberZ());
763 //___________________________________________
764 void AliMUON::SetChargeSlope(Int_t id, Float_t p1)
766 // Set the inverse charge slope for chamber id
768 //PH ((AliMUONChamber*) (*fChambers)[i])->SetChargeSlope(p1);
769 //PH ((AliMUONChamber*) (*fChambers)[i+1])->SetChargeSlope(p1);
770 ((AliMUONChamber*) fChambers->At(i))->SetChargeSlope(p1);
771 ((AliMUONChamber*) fChambers->At(i+1))->SetChargeSlope(p1);
774 //___________________________________________
775 void AliMUON::SetChargeSpread(Int_t id, Float_t p1, Float_t p2)
777 // Set sigma of charge spread for chamber id
779 //PH ((AliMUONChamber*) fChambers->At(i))->SetChargeSpread(p1,p2);
780 //PH ((AliMUONChamber*) fChambers->Ati+1])->SetChargeSpread(p1,p2);
781 ((AliMUONChamber*) fChambers->At(i))->SetChargeSpread(p1,p2);
782 ((AliMUONChamber*) fChambers->At(i+1))->SetChargeSpread(p1,p2);
785 //___________________________________________
786 void AliMUON::SetSigmaIntegration(Int_t id, Float_t p1)
788 // Set integration limits for charge spread
790 //PH ((AliMUONChamber*) (*fChambers)[i])->SetSigmaIntegration(p1);
791 //PH ((AliMUONChamber*) (*fChambers)[i+1])->SetSigmaIntegration(p1);
792 ((AliMUONChamber*) fChambers->At(i))->SetSigmaIntegration(p1);
793 ((AliMUONChamber*) fChambers->At(i+1))->SetSigmaIntegration(p1);
796 //___________________________________________
797 void AliMUON::SetMaxAdc(Int_t id, Int_t p1)
799 // Set maximum number for ADCcounts (saturation)
801 //PH ((AliMUONChamber*) (*fChambers)[i])->SetMaxAdc(p1);
802 //PH ((AliMUONChamber*) (*fChambers)[i+1])->SetMaxAdc(p1);
803 ((AliMUONChamber*) fChambers->At(i))->SetMaxAdc(p1);
804 ((AliMUONChamber*) fChambers->At(i+1))->SetMaxAdc(p1);
807 //___________________________________________
808 void AliMUON::SetMaxStepGas(Float_t p1)
810 // Set stepsize in gas
814 //___________________________________________
815 void AliMUON::SetMaxStepAlu(Float_t p1)
817 // Set step size in Alu
821 //___________________________________________
822 void AliMUON::SetMaxDestepGas(Float_t p1)
824 // Set maximum step size in Gas
828 //___________________________________________
829 void AliMUON::SetMaxDestepAlu(Float_t p1)
831 // Set maximum step size in Alu
834 //___________________________________________
835 void AliMUON::SetAcceptance(Bool_t acc, Float_t angmin, Float_t angmax)
837 // Set acceptance cuts
839 fAccMin=angmin*TMath::Pi()/180;
840 fAccMax=angmax*TMath::Pi()/180;
843 for (Int_t st = 0; st < AliMUONConstants::NCh() / 2; st++) {
844 // Loop over 2 chambers in the station
845 for (Int_t stCH = 0; stCH < 2; stCH++) {
847 // Set chamber inner and outer radius according to acceptance cuts
848 Chamber(ch).SetRInner(AliMUONConstants::DefaultChamberZ(ch)*TMath::Tan(fAccMin));
849 Chamber(ch).SetROuter(AliMUONConstants::DefaultChamberZ(ch)*TMath::Tan(fAccMax));
854 //___________________________________________
855 void AliMUON::SetSegmentationModel(Int_t id, Int_t isec, AliSegmentation *segmentation)
857 // Set the segmentation for chamber id cathode isec
858 //PH ((AliMUONChamber*) (*fChambers)[id])->SetSegmentationModel(isec, segmentation);
859 ((AliMUONChamber*) fChambers->At(id))->SetSegmentationModel(isec, segmentation);
862 //___________________________________________
863 void AliMUON::SetResponseModel(Int_t id, AliMUONResponse *response)
865 // Set the response for chamber id
866 //PH ((AliMUONChamber*) (*fChambers)[id])->SetResponseModel(response);
867 ((AliMUONChamber*) fChambers->At(id))->SetResponseModel(response);
870 void AliMUON::SetReconstructionModel(Int_t id, AliMUONClusterFinderVS *reconst)
872 // Set ClusterFinder for chamber id
873 //PH ((AliMUONChamber*) (*fChambers)[id])->SetReconstructionModel(reconst);
874 ((AliMUONChamber*) fChambers->At(id))->SetReconstructionModel(reconst);
877 void AliMUON::SetNsec(Int_t id, Int_t nsec)
879 // Set number of segmented cathods for chamber id
880 //PH ((AliMUONChamber*) (*fChambers)[id])->SetNsec(nsec);
881 ((AliMUONChamber*) fChambers->At(id))->SetNsec(nsec);
884 //___________________________________________
885 void AliMUON::SDigits2Digits()
891 if (gAlice->GetDebug()>0) {
892 cerr<<"AliMUON::SDigits2Digits: create default AliMUONMerger "<<endl;
893 cerr<<" no merging, just digitization of 1 event will be done"<<endl;
895 fMerger = new AliMUONMerger();
900 sprintf(hname,"TreeD%d",gAlice->GetHeader()->GetEvent());
901 gAlice->TreeD()->Write(hname,TObject::kOverwrite);
902 gAlice->TreeD()->Reset();
905 //___________________________________________
906 void AliMUON::MakePadHits(Float_t xhit,Float_t yhit, Float_t zhit,
907 Float_t eloss, Float_t tof, Int_t idvol)
910 // Calls the charge disintegration method of the current chamber and adds
911 // the simulated cluster to the root treee
914 Float_t newclust[6][500];
919 // Integrated pulse height on chamber
925 // if (idvol == 6) printf("\n ->Disintegration %f %f %f", xhit, yhit, eloss );
928 //PH ((AliMUONChamber*) (*fChambers)[idvol])
929 ((AliMUONChamber*) fChambers->At(idvol))
930 ->DisIntegration(eloss, tof, xhit, yhit, zhit, nnew, newclust);
932 // if (idvol == 6) printf("\n nnew %d \n", nnew);
935 for (Int_t i=0; i<nnew; i++) {
936 if (Int_t(newclust[3][i]) > 0) {
939 clhits[1] = Int_t(newclust[5][i]);
941 clhits[2] = Int_t(newclust[0][i]);
943 clhits[3] = Int_t(newclust[1][i]);
945 clhits[4] = Int_t(newclust[2][i]);
947 clhits[5] = Int_t(newclust[3][i]);
948 // Pad: chamber sector
949 clhits[6] = Int_t(newclust[4][i]);
956 //___________________________________________
957 void AliMUON::Trigger(Int_t nev){
958 // call the Trigger Algorithm and fill TreeR
960 Int_t singlePlus[3] = {0,0,0};
961 Int_t singleMinus[3] = {0,0,0};
962 Int_t singleUndef[3] = {0,0,0};
963 Int_t pairUnlike[3] = {0,0,0};
964 Int_t pairLike[3] = {0,0,0};
967 AliMUONTriggerDecision* decision= new AliMUONTriggerDecision(1);
969 decision->GetGlobalTrigger(singlePlus, singleMinus, singleUndef,
970 pairUnlike, pairLike);
971 // add a local trigger in the list
972 AddGlobalTrigger(singlePlus, singleMinus, singleUndef, pairUnlike, pairLike);
975 for (Int_t icirc=0; icirc<AliMUONConstants::NTriggerCircuit(); icirc++) {
976 if(decision->GetITrigger(icirc)==1) {
977 Int_t localtr[7]={0,0,0,0,0,0,0};
978 Int_t loLpt[2]={0,0}; Int_t loHpt[2]={0,0}; Int_t loApt[2]={0,0};
979 decision->GetLutOutput(icirc, loLpt, loHpt, loApt);
981 localtr[1] = decision->GetStripX11(icirc);
982 localtr[2] = decision->GetDev(icirc);
983 localtr[3] = decision->GetStripY11(icirc);
984 for (i=0; i<2; i++) { // convert the Lut output in 1 digit
985 localtr[4] = localtr[4]+Int_t(loLpt[i]*TMath::Power(2,i));
986 localtr[5] = localtr[5]+Int_t(loHpt[i]*TMath::Power(2,i));
987 localtr[6] = localtr[6]+Int_t(loApt[i]*TMath::Power(2,i));
989 AddLocalTrigger(localtr); // add a local trigger in the list
994 gAlice->TreeR()->Fill();
997 sprintf(hname,"TreeR%d",nev);
998 gAlice->TreeR()->Write(hname,TObject::kOverwrite);
999 gAlice->TreeR()->Reset();
1000 printf("\n End of trigger for event %d", nev);
1004 //____________________________________________
1005 void AliMUON::Digits2Reco()
1008 Int_t nev = gAlice->GetHeader()->GetEvent();
1009 gAlice->TreeR()->Fill();
1011 sprintf(hname,"TreeR%d", nev);
1012 gAlice->TreeR()->Write(hname);
1013 gAlice->TreeR()->Reset();
1015 printf("\n End of cluster finding for event %d", nev);
1018 void AliMUON::FindClusters()
1021 // Perform cluster finding
1023 TClonesArray *dig1, *dig2;
1025 dig1 = new TClonesArray("AliMUONDigit",1000);
1026 dig2 = new TClonesArray("AliMUONDigit",1000);
1027 AliMUONDigit *digit;
1029 // Loop on chambers and on cathode planes
1032 for (Int_t ich = 0; ich < 10; ich++) {
1033 //PH AliMUONChamber* iChamber = (AliMUONChamber*) (*fChambers)[ich];
1034 AliMUONChamber* iChamber = (AliMUONChamber*) fChambers->At(ich);
1035 AliMUONClusterFinderVS* rec = iChamber->ReconstructionModel();
1037 gAlice->ResetDigits();
1038 gAlice->TreeD()->GetEvent(0);
1039 TClonesArray *muonDigits = this->DigitsAddress(ich);
1040 ndig=muonDigits->GetEntriesFast();
1041 printf("\n 1 Found %d digits in %p %d", ndig, muonDigits,ich);
1042 TClonesArray &lhits1 = *dig1;
1044 for (k = 0; k < ndig; k++) {
1045 digit = (AliMUONDigit*) muonDigits->UncheckedAt(k);
1046 if (rec->TestTrack(digit->Track(0)))
1047 new(lhits1[n++]) AliMUONDigit(*digit);
1049 gAlice->ResetDigits();
1050 gAlice->TreeD()->GetEvent(1);
1051 muonDigits = this->DigitsAddress(ich);
1052 ndig=muonDigits->GetEntriesFast();
1053 printf("\n 2 Found %d digits in %p %d", ndig, muonDigits, ich);
1054 TClonesArray &lhits2 = *dig2;
1057 for (k=0; k<ndig; k++) {
1058 digit= (AliMUONDigit*) muonDigits->UncheckedAt(k);
1059 if (rec->TestTrack(digit->Track(0)))
1060 new(lhits2[n++]) AliMUONDigit(*digit);
1064 AliMUONClusterInput::Instance()->SetDigits(ich, dig1, dig2);
1065 rec->FindRawClusters();
1075 void AliMUON::Streamer(TBuffer &R__b)
1077 // Stream an object of class AliMUON.
1078 AliMUONChamber *iChamber;
1079 AliMUONTriggerCircuit *iTriggerCircuit;
1080 AliSegmentation *segmentation;
1081 AliMUONResponse *response;
1082 TClonesArray *digitsaddress;
1083 TClonesArray *rawcladdress;
1085 if (R__b.IsReading()) {
1086 Version_t R__v = R__b.ReadVersion(); if (R__v) { }
1087 AliDetector::Streamer(R__b);
1089 R__b >> fPadHits; // diff
1090 R__b >> fNLocalTrigger;
1091 R__b >> fLocalTrigger;
1092 R__b >> fNGlobalTrigger;
1093 R__b >> fGlobalTrigger;
1095 R__b >> fRawClusters;
1096 R__b.ReadArray(fNdch);
1097 R__b.ReadArray(fNrawch);
1102 R__b >> fTriggerCircuits;
1103 for (i =0; i<AliMUONConstants::NTriggerCircuit(); i++) {
1104 iTriggerCircuit=(AliMUONTriggerCircuit*) (*fTriggerCircuits)[i];
1105 iTriggerCircuit->Streamer(R__b);
1107 // Stream chamber related information
1108 for (i =0; i<AliMUONConstants::NCh(); i++) {
1109 iChamber=(AliMUONChamber*) (*fChambers)[i];
1110 iChamber->Streamer(R__b);
1111 if (iChamber->Nsec()==1) {
1112 segmentation=iChamber->SegmentationModel(1);
1114 segmentation->Streamer(R__b);
1116 segmentation=iChamber->SegmentationModel(1);
1118 segmentation->Streamer(R__b);
1120 segmentation=iChamber->SegmentationModel(2);
1121 segmentation->Streamer(R__b);
1123 response=iChamber->ResponseModel();
1125 response->Streamer(R__b);
1126 digitsaddress=(TClonesArray*) (*fDchambers)[i];
1127 digitsaddress->Streamer(R__b);
1128 if (i < AliMUONConstants::NTrackingCh()) {
1129 rawcladdress=(TClonesArray*) (*fRawClusters)[i];
1130 rawcladdress->Streamer(R__b);
1135 R__b.WriteVersion(AliMUON::IsA());
1136 AliDetector::Streamer(R__b);
1138 R__b << fPadHits; // diff
1139 R__b << fNLocalTrigger;
1140 R__b << fLocalTrigger;
1141 R__b << fNGlobalTrigger;
1142 R__b << fGlobalTrigger;
1144 R__b << fRawClusters;
1145 R__b.WriteArray(fNdch, AliMUONConstants::NCh());
1146 R__b.WriteArray(fNrawch, AliMUONConstants::NTrackingCh());
1153 R__b << fTriggerCircuits;
1154 for (i =0; i<AliMUONConstants::NTriggerCircuit(); i++) {
1155 iTriggerCircuit=(AliMUONTriggerCircuit*) (*fTriggerCircuits)[i];
1156 iTriggerCircuit->Streamer(R__b);
1158 for (i =0; i<AliMUONConstants::NCh(); i++) {
1159 iChamber=(AliMUONChamber*) (*fChambers)[i];
1160 iChamber->Streamer(R__b);
1161 if (iChamber->Nsec()==1) {
1162 segmentation=iChamber->SegmentationModel(1);
1164 segmentation->Streamer(R__b);
1166 segmentation=iChamber->SegmentationModel(1);
1168 segmentation->Streamer(R__b);
1169 segmentation=iChamber->SegmentationModel(2);
1171 segmentation->Streamer(R__b);
1173 response=iChamber->ResponseModel();
1175 response->Streamer(R__b);
1176 digitsaddress=(TClonesArray*) (*fDchambers)[i];
1177 digitsaddress->Streamer(R__b);
1178 if (i < AliMUONConstants::NTrackingCh()) {
1179 rawcladdress=(TClonesArray*) (*fRawClusters)[i];
1180 rawcladdress->Streamer(R__b);
1187 AliMUONPadHit* AliMUON::FirstPad(AliMUONHit* hit, TClonesArray *clusters)
1190 // Initialise the pad iterator
1191 // Return the address of the first padhit for hit
1192 TClonesArray *theClusters = clusters;
1193 Int_t nclust = theClusters->GetEntriesFast();
1194 if (nclust && hit->PHlast() > 0) {
1195 AliMUON::fMaxIterPad=hit->PHlast();
1196 AliMUON::fCurIterPad=hit->PHfirst();
1197 return (AliMUONPadHit*) clusters->UncheckedAt(AliMUON::fCurIterPad-1);
1203 AliMUONPadHit* AliMUON::NextPad(TClonesArray *clusters)
1205 // Get next pad (in iterator)
1207 AliMUON::fCurIterPad++;
1208 if (AliMUON::fCurIterPad <= AliMUON::fMaxIterPad) {
1209 return (AliMUONPadHit*) clusters->UncheckedAt(AliMUON::fCurIterPad-1);
1216 AliMUONRawCluster *AliMUON::RawCluster(Int_t ichamber, Int_t icathod, Int_t icluster)
1219 // Return rawcluster (icluster) for chamber ichamber and cathode icathod
1221 TClonesArray *muonRawCluster = RawClustAddress(ichamber);
1223 TTree *treeR = gAlice->TreeR();
1224 Int_t nent=(Int_t)treeR->GetEntries();
1225 treeR->GetEvent(nent-2+icathod-1);
1226 //treeR->GetEvent(icathod);
1227 //Int_t nrawcl = (Int_t)muonRawCluster->GetEntriesFast();
1229 AliMUONRawCluster * mRaw = (AliMUONRawCluster*)muonRawCluster->UncheckedAt(icluster);
1230 //printf("RawCluster _ nent nrawcl icluster mRaw %d %d %d%p\n",nent,nrawcl,icluster,mRaw);
1235 void AliMUON::SetMerger(AliMUONMerger* merger)
1237 // Set pointer to merger
1241 AliMUONMerger* AliMUON::Merger()
1243 // Return pointer to merger
1249 AliMUON& AliMUON::operator = (const AliMUON& rhs)
1256 ////////////////////////////////////////////////////////////////////////
1257 void AliMUON::MakeBranchInTreeD(TTree *treeD, const char *file)
1260 // Create TreeD branches for the MUON.
1263 const Int_t kBufferSize = 4000;
1264 char branchname[30];
1267 // one branch for digits per chamber
1269 for (Int_t i=0; i<AliMUONConstants::NCh() ;i++) {
1270 sprintf(branchname,"%sDigits%d",GetName(),i+1);
1271 if (fDchambers && treeD) {
1272 MakeBranchInTree(treeD,
1273 branchname, &((*fDchambers)[i]), kBufferSize, file);
1274 printf("Making Branch %s for digits in chamber %d\n",branchname,i+1);
1279 //___________________________________________