]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUON.cxx
Put vacuum in beam-pipe not air.
[u/mrichter/AliRoot.git] / MUON / AliMUON.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
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  **************************************************************************/
15 /*
16 $Log$
17 Revision 1.48  2001/03/06 00:01:36  morsch
18 Add  Digits2Reco() and FindClusters()
19 Adapt call of cluster finder to new STEER.
20
21 Revision 1.47  2001/03/05 08:38:36  morsch
22 Digitization related methods moved to AliMUONMerger.
23
24 Revision 1.46  2001/01/26 21:34:59  morsch
25 Use access functions for AliMUONHit, AliMUONDigit and AliMUONPadHit data members.
26
27 Revision 1.45  2001/01/26 20:00:49  hristov
28 Major upgrade of AliRoot code
29
30 Revision 1.44  2001/01/25 17:39:09  morsch
31 Pass size of fNdch and fNrawch to CINT.
32
33 Revision 1.43  2001/01/23 18:58:19  hristov
34 Initialisation of some pointers
35
36 Revision 1.42  2001/01/17 20:53:40  hristov
37 Destructors corrected to avoid memory leaks
38
39 Revision 1.41  2000/12/21 22:12:40  morsch
40 Clean-up of coding rule violations,
41
42 Revision 1.40  2000/11/29 20:32:26  gosset
43 Digitize:
44 1. correction for array index out of bounds
45 2. one printout commented
46
47 Revision 1.39  2000/11/12 17:17:03  pcrochet
48 BuildGeometry of AliMUON for trigger chambers delegated to AliMUONSegmentationTriggerX (same strategy as for tracking chambers)
49
50 Revision 1.38  2000/11/06 09:20:43  morsch
51 AliMUON delegates part of BuildGeometry() to AliMUONSegmentation using the
52 Draw() method. This avoids code and parameter replication.
53
54 Revision 1.37  2000/10/26 09:53:37  pcrochet
55 put back trigger chambers in the display (there was a problem in buildgeometry)
56
57 Revision 1.36  2000/10/25 19:51:18  morsch
58 Correct x-position of chambers.
59
60 Revision 1.35  2000/10/24 19:46:21  morsch
61 BuildGeometry updated for slats in station 3-4.
62
63 Revision 1.34  2000/10/18 11:42:06  morsch
64 - AliMUONRawCluster contains z-position.
65 - Some clean-up of useless print statements during initialisations.
66
67 Revision 1.33  2000/10/09 14:01:57  morsch
68 Unused variables removed.
69
70 Revision 1.32  2000/10/06 09:08:10  morsch
71 Built geometry includes slat geometry for event display.
72
73 Revision 1.31  2000/10/02 21:28:08  fca
74 Removal of useless dependecies via forward declarations
75
76 Revision 1.30  2000/10/02 16:58:29  egangler
77 Cleaning of the code :
78 -> coding conventions
79 -> void Streamers
80 -> some useless includes removed or replaced by "class" statement
81
82 Revision 1.29  2000/07/28 13:49:38  morsch
83 SetAcceptance defines inner and outer chamber radii according to angular acceptance.
84 Can be used for simple acceptance studies.
85
86 Revision 1.28  2000/07/22 16:43:15  morsch
87 Same comment as before, but now done correctly I hope (sorry it's Saturday evening)
88
89 Revision 1.27  2000/07/22 16:36:50  morsch
90 Change order of indices in creation (new) of xhit and yhit
91
92 Revision 1.26  2000/07/03 11:54:57  morsch
93 AliMUONSegmentation and AliMUONHitMap have been replaced by AliSegmentation and AliHitMap in STEER
94 The methods GetPadIxy and GetPadXxy of AliMUONSegmentation have changed name to GetPadI and GetPadC.
95
96 Revision 1.25  2000/06/29 12:34:09  morsch
97 AliMUONSegmentation class has been made independent of AliMUONChamber. This makes
98 it usable with any other geometry class. The link to the object to which it belongs is
99 established via an index. This assumes that there exists a global geometry manager
100 from which the pointer to the parent object can be obtained (in our case gAlice).
101
102 Revision 1.24  2000/06/28 15:16:35  morsch
103 (1) Client code adapted to new method signatures in AliMUONSegmentation (see comments there)
104 to allow development of slat-muon chamber simulation and reconstruction code in the MUON
105 framework. The changes should have no side effects (mostly dummy arguments).
106 (2) Hit disintegration uses 3-dim hit coordinates to allow simulation
107 of chambers with overlapping modules (MakePadHits, Disintegration).
108
109 Revision 1.23  2000/06/28 12:19:17  morsch
110 More consequent seperation of global input data services (AliMUONClusterInput singleton) and the
111 cluster and hit reconstruction algorithms in AliMUONClusterFindRawinderVS.
112 AliMUONClusterFinderVS becomes the base class for clustering and hit reconstruction.
113 It requires two cathode planes. Small modifications in the code will make it usable for
114 one cathode plane and, hence, more general (for test beam data).
115 AliMUONClusterFinder is now obsolete.
116
117 Revision 1.22  2000/06/28 08:06:10  morsch
118 Avoid global variables in AliMUONClusterFinderVS by seperating the input data for the fit from the
119 algorithmic part of the class. Input data resides inside the AliMUONClusterInput singleton.
120 It also naturally takes care of the TMinuit instance.
121
122 Revision 1.21  2000/06/27 08:54:41  morsch
123 Problems with on constant array sizes (in hitMap, nmuon, xhit, yhit) corrected.
124
125 Revision 1.20  2000/06/26 14:02:38  morsch
126 Add class AliMUONConstants with MUON specific constants using static memeber data and access methods.
127
128 Revision 1.19  2000/06/22 13:40:51  morsch
129 scope problem on HP, "i" declared once
130 pow changed to TMath::Power (PH, AM)
131
132 Revision 1.18  2000/06/15 07:58:48  morsch
133 Code from MUON-dev joined
134
135 Revision 1.14.4.17  2000/06/14 14:36:46  morsch
136 - add TriggerCircuit (PC)
137 - add GlobalTrigger and LocalTrigger and specific methods (PC)
138
139 Revision 1.14.4.16  2000/06/09 21:20:28  morsch
140 Most coding rule violations corrected
141
142 Revision 1.14.4.15  2000/05/02 09:54:32  morsch
143 RULE RN17 violations corrected
144
145 Revision 1.14.4.12  2000/04/26 12:25:02  morsch
146 Code revised by P. Crochet:
147 - Z position of TriggerChamber changed according to A.Tournaire Priv.Comm.
148 - ToF included in the method MakePadHits
149 - inner radius of flange between beam shielding and trigger corrected
150 - Trigger global volume updated (according to the new geometry)
151
152 Revision 1.14.4.11  2000/04/19 19:42:08  morsch
153 Some changes of variable names curing viols and methods concerning
154 correlated clusters removed.
155
156 Revision 1.14.4.10  2000/03/22 16:44:07  gosset
157 Memory leak suppressed in function Digitise:
158 p_adr->Delete() instead of Clear (I.Chevrot and A.Baldisseri)
159
160 Revision 1.14.4.9  2000/03/20 18:15:25  morsch
161 Positions of trigger chambers corrected (P.C.)
162
163 Revision 1.14.4.8  2000/02/21 15:38:01  morsch
164 Call to AddHitList introduced to make this version compatible with head.
165
166 Revision 1.14.4.7  2000/02/20 07:45:53  morsch
167 Bugs in Trigger part of BuildGeomemetry corrected (P.C)
168
169 Revision 1.14.4.6  2000/02/17 14:28:54  morsch
170 Trigger included into initialization and digitization
171
172 Revision 1.14.4.5  2000/02/15 10:02:58  morsch
173 Log messages of previous revisions added
174
175 Revision 1.14.4.2  2000/02/04 10:57:34  gosset
176 Z position of the chambers:
177 it was the Z position of the stations;
178 it is now really the Z position of the chambers.
179    !!!! WARNING: THE CALLS TO "AliMUONChamber::SetZPOS"
180    !!!!                   AND "AliMUONChamber::ZPosition"
181    !!!! HAVE TO BE CHANGED TO "AliMUONChamber::"SetZ"
182    !!!!                   AND "AliMUONChamber::Z"
183
184 Revision 1.14.4.3  2000/02/04 16:19:04  gosset
185 Correction for mis-spelling of NCH 
186
187 Revision 1.14.4.4  2000/02/15 09:43:38  morsch
188 Log message added
189
190 */
191
192
193 ///////////////////////////////////////////////
194 //  Manager and hits classes for set:MUON     //
195 ////////////////////////////////////////////////
196
197 #include <TTUBE.h>
198 #include <TBRIK.h>
199 #include <TRotMatrix.h>
200 #include <TGeometry.h>
201 #include <TNode.h> 
202 #include <TTree.h> 
203 #include <TRandom.h> 
204 #include <TObject.h>
205 #include <TVector.h>
206 #include <TObjArray.h>
207 #include <TMinuit.h>
208 #include <TParticle.h>
209 #include <TROOT.h>
210 #include <TFile.h>
211 #include <TNtuple.h>
212 #include <TCanvas.h>
213 #include <TPad.h>
214 #include <TDirectory.h>
215 #include <TObjectTable.h>
216 #include <AliPDG.h>
217 #include <TTUBE.h>
218
219 #include "AliMUON.h"
220 #include "AliMUONHit.h"
221 #include "AliMUONPadHit.h"
222 #include "AliMUONDigit.h"
223 #include "AliMUONTransientDigit.h"
224 #include "AliMUONRawCluster.h"
225 #include "AliMUONLocalTrigger.h"
226 #include "AliMUONGlobalTrigger.h"
227 #include "AliMUONTriggerCircuit.h"
228 #include "AliHitMap.h"
229 #include "AliMUONHitMapA1.h"
230 #include "AliMUONChamberTrigger.h"
231 #include "AliMUONConstants.h"
232 #include "AliMUONClusterFinderVS.h"
233 #include "AliMUONTriggerDecision.h"
234 #include "AliRun.h"
235 #include "AliMC.h"
236 #include "AliMUONClusterInput.h"
237 #include "AliMUONMerger.h"      
238 #include "iostream.h"
239 #include "AliCallf77.h" 
240 #include "AliConst.h" 
241
242 // Defaults parameters for Z positions of chambers
243 // taken from values for "stations" in AliMUON::AliMUON
244 //     const Float_t zch[7]={528, 690., 975., 1249., 1449., 1610, 1710.};
245 // and from array "dstation" in AliMUONv1::CreateGeometry
246 //          Float_t dstation[5]={20., 20., 20, 20., 20.};
247 //     for tracking chambers,
248 //          according to (Z1 = zch - dstation) and  (Z2 = zch + dstation)
249 //          for the first and second chambers in the station, respectively,
250 // and from "DTPLANES" in AliMUONv1::CreateGeometry
251 //           const Float_t DTPLANES = 15.;
252 //     for trigger chambers,
253 //          according to (Z1 = zch) and  (Z2 = zch + DTPLANES)
254 //          for the first and second chambers in the station, respectively
255
256 ClassImp(AliMUON)
257 //___________________________________________
258 AliMUON::AliMUON()
259 {
260 // Default Constructor
261 //
262     fNCh             = 0;
263     fNTrackingCh     = 0;
264     fIshunt          = 0;
265     fHits            = 0;
266     fPadHits         = 0;
267     fNPadHits        = 0;
268     fChambers        = 0;
269     fDchambers       = 0;
270     fTriggerCircuits = 0;  
271     fNdch            = 0;
272     fRawClusters     = 0;
273     fNrawch          = 0;
274     fGlobalTrigger   = 0;
275     fNLocalTrigger   = 0;
276     fLocalTrigger    = 0;
277     fNLocalTrigger   = 0;
278     fAccMin          = 0.;
279     fAccMax          = 0.;   
280     fAccCut          = kFALSE;
281     fMerger          = 0;
282 }
283  
284 //___________________________________________
285 AliMUON::AliMUON(const char *name, const char *title)
286        : AliDetector(name,title)
287 {
288 //Begin_Html
289 /*
290 <img src="gif/alimuon.gif">
291 */
292 //End_Html
293
294    fHits     = new TClonesArray("AliMUONHit",1000);
295    gAlice->AddHitList(fHits);
296    fPadHits = new TClonesArray("AliMUONPadHit",10000);
297    fNPadHits  =  0;
298    fIshunt     =  0;
299
300    fNCh             = AliMUONConstants::NCh(); 
301    fNTrackingCh     = AliMUONConstants::NTrackingCh();
302    fNdch            = new Int_t[fNCh];
303
304    fDchambers = new TObjArray(AliMUONConstants::NCh());
305
306    Int_t i;
307    
308    for (i=0; i<AliMUONConstants::NCh() ;i++) {
309        (*fDchambers)[i] = new TClonesArray("AliMUONDigit",10000); 
310        fNdch[i]=0;
311    }
312
313    fNrawch      = new Int_t[fNTrackingCh];
314
315    fRawClusters = new TObjArray(AliMUONConstants::NTrackingCh());
316
317    for (i=0; i<AliMUONConstants::NTrackingCh();i++) {
318        (*fRawClusters)[i] = new TClonesArray("AliMUONRawCluster",10000); 
319        fNrawch[i]=0;
320    }
321
322    fGlobalTrigger = new TClonesArray("AliMUONGlobalTrigger",1);    
323    fNGlobalTrigger = 0;
324    fLocalTrigger  = new TClonesArray("AliMUONLocalTrigger",234);    
325    fNLocalTrigger = 0;
326
327    SetMarkerColor(kRed);
328 //
329 //
330 //
331 //
332
333     Int_t ch;
334
335     fChambers = new TObjArray(AliMUONConstants::NCh());
336
337     // Loop over stations
338     for (Int_t st = 0; st < AliMUONConstants::NCh() / 2; st++) {
339       // Loop over 2 chambers in the station
340         for (Int_t stCH = 0; stCH < 2; stCH++) {
341 //
342 //    
343 //    Default Parameters for Muon Tracking Stations
344
345
346             ch = 2 * st + stCH;
347 //
348             if (ch < AliMUONConstants::NTrackingCh()) {
349                 (*fChambers)[ch] = new AliMUONChamber(ch);
350             } else {
351                 (*fChambers)[ch] = new AliMUONChamberTrigger(ch);
352             }
353             
354             AliMUONChamber* chamber = (AliMUONChamber*) (*fChambers)[ch];
355             
356             chamber->SetGid(0);
357             // Default values for Z of chambers
358             chamber->SetZ(AliMUONConstants::DefaultChamberZ(ch));
359 //
360             chamber->InitGeo(AliMUONConstants::DefaultChamberZ(ch));
361 //          Set chamber inner and outer radius to default
362             chamber->SetRInner(AliMUONConstants::Dmin(st)/2);
363             chamber->SetROuter(AliMUONConstants::Dmax(st)/2);
364 //
365         } // Chamber stCH (0, 1) in 
366     }     // Station st (0...)
367     fMaxStepGas=0.01; 
368     fMaxStepAlu=0.1; 
369     fMaxDestepGas=-1;
370     fMaxDestepAlu=-1;
371 //
372    fMaxIterPad   = 0;
373    fCurIterPad   = 0;
374 //
375    fAccMin          = 0.;
376    fAccMax          = 0.;   
377    fAccCut          = kFALSE;
378
379    // cp new design of AliMUONTriggerDecision
380    fTriggerCircuits = new TObjArray(AliMUONConstants::NTriggerCircuit());
381    for (Int_t circ=0; circ<AliMUONConstants::NTriggerCircuit(); circ++) {
382      (*fTriggerCircuits)[circ] = new AliMUONTriggerCircuit();     
383
384    }
385      fMerger = 0;
386 }
387  
388 //___________________________________________
389 AliMUON::AliMUON(const AliMUON& rMUON)
390 {
391 // Dummy copy constructor
392     ;
393     
394 }
395
396 AliMUON::~AliMUON()
397 {
398 // Destructor
399     printf("Calling AliMUON destructor !!!\n");
400     
401     Int_t i;
402     fIshunt  = 0;
403  
404     // Delete TObjArrays
405  
406     if (fChambers){
407       fChambers->Delete();
408       delete fChambers;
409     }
410  
411     if (fTriggerCircuits){
412       fTriggerCircuits->Delete();
413       delete fTriggerCircuits;
414     }
415  
416     if (fDchambers){
417       fDchambers->Delete();
418       delete fDchambers;
419     }
420  
421     if (fRawClusters){
422       fRawClusters->Delete();
423       delete fRawClusters;
424     }
425     for (i=0;i<AliMUONConstants::NTrackingCh();i++) {
426       fNrawch[i]=0;
427     }
428  
429     // Delete TClonesArrays
430  
431     if (fPadHits){
432       fPadHits->Delete();
433       delete fPadHits;
434     }
435  
436     if (fGlobalTrigger){
437       fGlobalTrigger->Delete();
438       delete fGlobalTrigger;
439     }
440     fNGlobalTrigger = 0;
441     
442     if (fLocalTrigger){
443       fLocalTrigger->Delete();
444       delete fLocalTrigger;
445     }
446     fNLocalTrigger = 0;
447
448     if (fHits2){
449       fHits2->Delete();
450       delete fHits2;
451     }
452
453     if (fPadHits2){
454       fPadHits2->Delete();
455       delete fPadHits2;
456     }
457
458     if (fHits) {
459       fHits->Delete();
460       delete fHits;
461     }
462
463     // Delete hits tree for background event
464
465     if (fTrH1) {
466       fTrH1->Delete();
467       delete fTrH1;
468     }
469
470     if (fMerger) delete fMerger;
471 }
472  
473 //___________________________________________
474 void AliMUON::AddHit(Int_t track, Int_t *vol, Float_t *hits)
475 {
476   TClonesArray &lhits = *fHits;
477   new(lhits[fNhits++]) AliMUONHit(fIshunt,track,vol,hits);
478 }
479 //___________________________________________
480 void AliMUON::AddPadHit(Int_t *clhits)
481 {
482    TClonesArray &lclusters = *fPadHits;
483    new(lclusters[fNPadHits++]) AliMUONPadHit(clhits);
484 }
485 //_____________________________________________________________________________
486 void AliMUON::AddDigits(Int_t id, Int_t *tracks, Int_t *charges, Int_t *digits)
487 {
488     //
489     // Add a MUON digit to the list
490     //
491
492     TClonesArray &ldigits = *((TClonesArray*)(*fDchambers)[id]);
493     new(ldigits[fNdch[id]++]) AliMUONDigit(tracks,charges,digits);
494 }
495
496 //_____________________________________________________________________________
497 void AliMUON::AddRawCluster(Int_t id, const AliMUONRawCluster& c)
498 {
499     //
500     // Add a MUON digit to the list
501     //
502
503     TClonesArray &lrawcl = *((TClonesArray*)(*fRawClusters)[id]);
504     new(lrawcl[fNrawch[id]++]) AliMUONRawCluster(c);
505 }
506
507 //___________________________________________
508 void AliMUON::AddGlobalTrigger(Int_t *singlePlus, Int_t *singleMinus,
509                                Int_t *singleUndef,
510                                Int_t *pairUnlike, Int_t *pairLike)
511 {
512 // add a MUON Global Trigger to the list (only one GlobalTrigger per event !)
513   TClonesArray &globalTrigger = *fGlobalTrigger;
514   new(globalTrigger[fNGlobalTrigger++]) 
515     AliMUONGlobalTrigger(singlePlus, singleMinus,  singleUndef, pairUnlike, 
516                          pairLike);
517 }
518 //___________________________________________
519 void AliMUON::AddLocalTrigger(Int_t *localtr)
520 {
521 // add a MUON Local Trigger to the list
522   TClonesArray &localTrigger = *fLocalTrigger;
523   new(localTrigger[fNLocalTrigger++]) AliMUONLocalTrigger(localtr);
524 }
525
526 //___________________________________________
527 void AliMUON::BuildGeometry()
528 {
529 // Geometry for event display
530   for (Int_t i=0; i<7; i++) {
531     for (Int_t j=0; j<2; j++) {
532       Int_t id=2*i+j+1;
533       this->Chamber(id-1).SegmentationModel(1)->Draw("eventdisplay");
534     }
535   }
536 }
537
538 //___________________________________________
539 Int_t AliMUON::DistancetoPrimitive(Int_t , Int_t )
540 {
541    return 9999;
542 }
543
544 //___________________________________________
545 void AliMUON::MakeBranch(Option_t* option, char *file)
546 {
547     //
548     // Create Tree branches for the MUON.
549     //
550     const Int_t kBufferSize = 4000;
551     char branchname[30];
552     sprintf(branchname,"%sCluster",GetName());
553     
554     AliDetector::MakeBranch(option,file);
555     
556     const char *cD = strstr(option,"D");
557     const char *cR = strstr(option,"R");
558     const char *cH = strstr(option,"H");
559
560     if (fPadHits   && gAlice->TreeH() && cH) {
561       gAlice->MakeBranchInTree(gAlice->TreeH(), 
562                                branchname, &fPadHits, kBufferSize, file) ;        
563           printf("Making Branch %s for clusters\n",branchname);
564     }
565     
566     if (cD) {
567       //
568       // one branch for digits per chamber
569       // 
570       Int_t i;
571     
572       for (i=0; i<AliMUONConstants::NCh() ;i++) {
573             sprintf(branchname,"%sDigits%d",GetName(),i+1);     
574             if (fDchambers   && gAlice->TreeD()) {
575           gAlice->MakeBranchInTree(gAlice->TreeD(), 
576                                    branchname, &((*fDchambers)[i]), kBufferSize, file) ;          
577               printf("Making Branch %s for digits in chamber %d\n",branchname,i+1);
578         }
579           }     
580     }
581     
582     if (cR) {
583       //     
584       // one branch for raw clusters per chamber
585       //  
586       printf("Make Branch - TreeR address %p\n",gAlice->TreeR());
587       
588       Int_t i;
589
590       for (i=0; i<AliMUONConstants::NTrackingCh() ;i++) {
591             sprintf(branchname,"%sRawClusters%d",GetName(),i+1);        
592             if (fRawClusters   && gAlice->TreeR()) {
593           gAlice->MakeBranchInTree(gAlice->TreeR(), 
594                                    branchname, &((*fRawClusters)[i]), kBufferSize, file) ;        
595               printf("Making Branch %s for raw clusters in chamber %d\n",branchname,i+1);
596             }   
597       }
598       //
599       // one branch for global trigger
600       //
601       sprintf(branchname,"%sGlobalTrigger",GetName());
602       if (fGlobalTrigger && gAlice->TreeR()) {  
603         gAlice->MakeBranchInTree(gAlice->TreeR(), 
604                                  branchname, &fGlobalTrigger, kBufferSize, file) ;        
605             printf("Making Branch %s for Global Trigger\n",branchname);
606       }
607       //
608       // one branch for local trigger
609       //  
610       sprintf(branchname,"%sLocalTrigger",GetName());
611       if (fLocalTrigger && gAlice->TreeR()) {  
612         gAlice->MakeBranchInTree(gAlice->TreeR(), 
613                                  branchname, &fLocalTrigger, kBufferSize, file) ;         
614             printf("Making Branch %s for Local Trigger\n",branchname);
615       }
616    }
617 }
618
619 //___________________________________________
620 void AliMUON::SetTreeAddress()
621 {
622   // Set branch address for the Hits and Digits Tree.
623   char branchname[30];
624   AliDetector::SetTreeAddress();
625
626   TBranch *branch;
627   TTree *treeH = gAlice->TreeH();
628   TTree *treeD = gAlice->TreeD();
629   TTree *treeR = gAlice->TreeR();
630
631   if (treeH) {
632     if (fPadHits) {
633       branch = treeH->GetBranch("MUONCluster");
634       if (branch) branch->SetAddress(&fPadHits);
635     }
636   }
637
638   if (treeD) {
639       for (int i=0; i<AliMUONConstants::NCh(); i++) {
640           sprintf(branchname,"%sDigits%d",GetName(),i+1);
641           if (fDchambers) {
642               branch = treeD->GetBranch(branchname);
643               if (branch) branch->SetAddress(&((*fDchambers)[i]));
644           }
645       }
646   }
647
648   // printf("SetTreeAddress --- treeR address  %p \n",treeR);
649
650   if (treeR) {
651       for (int i=0; i<AliMUONConstants::NTrackingCh(); i++) {
652           sprintf(branchname,"%sRawClusters%d",GetName(),i+1);
653           if (fRawClusters) {
654               branch = treeR->GetBranch(branchname);
655               if (branch) branch->SetAddress(&((*fRawClusters)[i]));
656           }
657       }
658
659       if (fLocalTrigger) {
660         branch = treeR->GetBranch("MUONLocalTrigger");
661         if (branch) branch->SetAddress(&fLocalTrigger);
662       }
663       if (fGlobalTrigger) {
664         branch = treeR->GetBranch("MUONGlobalTrigger");
665         if (branch) branch->SetAddress(&fGlobalTrigger);
666       }
667   }
668 }
669 //___________________________________________
670 void AliMUON::ResetHits()
671 {
672   // Reset number of clusters and the cluster array for this detector
673   AliDetector::ResetHits();
674   fNPadHits = 0;
675   if (fPadHits) fPadHits->Clear();
676 }
677
678 //____________________________________________
679 void AliMUON::ResetDigits()
680 {
681     //
682     // Reset number of digits and the digits array for this detector
683     //
684     for ( int i=0;i<AliMUONConstants::NCh();i++ ) {
685         if ((*fDchambers)[i])    ((TClonesArray*)(*fDchambers)[i])->Clear();
686         if (fNdch)  fNdch[i]=0;
687     }
688 }
689 //____________________________________________
690 void AliMUON::ResetRawClusters()
691 {
692     //
693     // Reset number of raw clusters and the raw clust array for this detector
694     //
695     for ( int i=0;i<AliMUONConstants::NTrackingCh();i++ ) {
696         if ((*fRawClusters)[i])    ((TClonesArray*)(*fRawClusters)[i])->Clear();
697         if (fNrawch)  fNrawch[i]=0;
698     }
699 }
700
701 //____________________________________________
702 void AliMUON::ResetTrigger()
703 {
704   //  Reset Local and Global Trigger 
705   fNGlobalTrigger = 0;
706   if (fGlobalTrigger) fGlobalTrigger->Clear();
707   fNLocalTrigger = 0;
708   if (fLocalTrigger) fLocalTrigger->Clear();
709 }
710
711 //____________________________________________
712 void AliMUON::SetPadSize(Int_t id, Int_t isec, Float_t p1, Float_t p2)
713 {
714 // Set the pad size for chamber id and cathode isec
715     Int_t i=2*(id-1);
716     ((AliMUONChamber*) (*fChambers)[i])  ->SetPadSize(isec,p1,p2);
717     ((AliMUONChamber*) (*fChambers)[i+1])->SetPadSize(isec,p1,p2);
718 }
719
720 //___________________________________________
721 void AliMUON::SetChambersZ(const Float_t *Z)
722 {
723   // Set Z values for all chambers (tracking and trigger)
724   // from the array pointed to by "Z"
725     for (Int_t ch = 0; ch < AliMUONConstants::NCh(); ch++)
726         ((AliMUONChamber*) ((*fChambers)[ch]))->SetZ(Z[ch]);
727     return;
728 }
729
730 //___________________________________________
731 void AliMUON::SetChambersZToDefault()
732 {
733   // Set Z values for all chambers (tracking and trigger)
734   // to default values
735   SetChambersZ(AliMUONConstants::DefaultChamberZ());
736   return;
737 }
738
739 //___________________________________________
740 void AliMUON::SetChargeSlope(Int_t id, Float_t p1)
741 {
742 // Set the inverse charge slope for chamber id
743     Int_t i=2*(id-1);
744     ((AliMUONChamber*) (*fChambers)[i])->SetChargeSlope(p1);
745     ((AliMUONChamber*) (*fChambers)[i+1])->SetChargeSlope(p1);
746 }
747
748 //___________________________________________
749 void AliMUON::SetChargeSpread(Int_t id, Float_t p1, Float_t p2)
750 {
751 // Set sigma of charge spread for chamber id
752     Int_t i=2*(id-1);
753     ((AliMUONChamber*) (*fChambers)[i])->SetChargeSpread(p1,p2);
754     ((AliMUONChamber*) (*fChambers)[i+1])->SetChargeSpread(p1,p2);
755 }
756
757 //___________________________________________
758 void AliMUON::SetSigmaIntegration(Int_t id, Float_t p1)
759 {
760 // Set integration limits for charge spread
761     Int_t i=2*(id-1);
762     ((AliMUONChamber*) (*fChambers)[i])->SetSigmaIntegration(p1);
763     ((AliMUONChamber*) (*fChambers)[i+1])->SetSigmaIntegration(p1);
764 }
765
766 //___________________________________________
767 void AliMUON::SetMaxAdc(Int_t id, Int_t p1)
768 {
769 // Set maximum number for ADCcounts (saturation)
770     Int_t i=2*(id-1);
771     ((AliMUONChamber*) (*fChambers)[i])->SetMaxAdc(p1);
772     ((AliMUONChamber*) (*fChambers)[i+1])->SetMaxAdc(p1);
773 }
774
775 //___________________________________________
776 void AliMUON::SetMaxStepGas(Float_t p1)
777 {
778 // Set stepsize in gas
779      fMaxStepGas=p1;
780 }
781
782 //___________________________________________
783 void AliMUON::SetMaxStepAlu(Float_t p1)
784 {
785 // Set step size in Alu
786     fMaxStepAlu=p1;
787 }
788
789 //___________________________________________
790 void AliMUON::SetMaxDestepGas(Float_t p1)
791 {
792 // Set maximum step size in Gas
793     fMaxDestepGas=p1;
794 }
795
796 //___________________________________________
797 void AliMUON::SetMaxDestepAlu(Float_t p1)
798 {
799 // Set maximum step size in Alu
800     fMaxDestepAlu=p1;
801 }
802 //___________________________________________
803 void AliMUON::SetAcceptance(Bool_t acc, Float_t angmin, Float_t angmax)
804 {
805 // Set acceptance cuts 
806    fAccCut=acc;
807    fAccMin=angmin*TMath::Pi()/180;
808    fAccMax=angmax*TMath::Pi()/180;
809    Int_t ch;
810    if (acc) {
811        for (Int_t st = 0; st < AliMUONConstants::NCh() / 2; st++) {
812            // Loop over 2 chambers in the station
813            for (Int_t stCH = 0; stCH < 2; stCH++) {
814                ch = 2 * st + stCH;
815 //         Set chamber inner and outer radius according to acceptance cuts
816                Chamber(ch).SetRInner(AliMUONConstants::DefaultChamberZ(ch)*TMath::Tan(fAccMin));
817                Chamber(ch).SetROuter(AliMUONConstants::DefaultChamberZ(ch)*TMath::Tan(fAccMax));
818            } // chamber loop
819        } // station loop
820    }
821 }
822 //___________________________________________
823 void   AliMUON::SetSegmentationModel(Int_t id, Int_t isec, AliSegmentation *segmentation)
824 {
825 // Set the segmentation for chamber id cathode isec
826     ((AliMUONChamber*) (*fChambers)[id])->SetSegmentationModel(isec, segmentation);
827
828 }
829 //___________________________________________
830 void   AliMUON::SetResponseModel(Int_t id, AliMUONResponse *response)
831 {
832 // Set the response for chamber id
833     ((AliMUONChamber*) (*fChambers)[id])->SetResponseModel(response);
834 }
835
836 void   AliMUON::SetReconstructionModel(Int_t id, AliMUONClusterFinderVS *reconst)
837 {
838 // Set ClusterFinder for chamber id
839     ((AliMUONChamber*) (*fChambers)[id])->SetReconstructionModel(reconst);
840 }
841
842 void   AliMUON::SetNsec(Int_t id, Int_t nsec)
843 {
844 // Set number of segmented cathods for chamber id
845     ((AliMUONChamber*) (*fChambers)[id])->SetNsec(nsec);
846 }
847
848 //___________________________________________
849 void AliMUON::SDigits2Digits()
850 {
851     if (fMerger) {
852         fMerger->Init();
853         fMerger->Digitise();
854     }
855 }
856
857 //___________________________________________
858 void AliMUON::MakePadHits(Float_t xhit,Float_t yhit, Float_t zhit,
859                           Float_t eloss, Float_t tof,  Int_t idvol)
860 {
861 //
862 //  Calls the charge disintegration method of the current chamber and adds
863 //  the simulated cluster to the root treee 
864 //
865     Int_t clhits[7];
866     Float_t newclust[6][500];
867     Int_t nnew;
868     
869     
870 //
871 //  Integrated pulse height on chamber
872
873     
874     clhits[0]=fNhits+1;
875 //
876 //
877 //    if (idvol == 6) printf("\n ->Disintegration %f %f %f", xhit, yhit, eloss );
878     
879
880     ((AliMUONChamber*) (*fChambers)[idvol])
881         ->DisIntegration(eloss, tof, xhit, yhit, zhit, nnew, newclust);
882     Int_t ic=0;
883 //    if (idvol == 6) printf("\n nnew  %d \n", nnew);
884 //
885 //  Add new clusters
886     for (Int_t i=0; i<nnew; i++) {
887         if (Int_t(newclust[3][i]) > 0) {
888             ic++;
889 // Cathode plane
890             clhits[1] = Int_t(newclust[5][i]);
891 //  Cluster Charge
892             clhits[2] = Int_t(newclust[0][i]);
893 //  Pad: ix
894             clhits[3] = Int_t(newclust[1][i]);
895 //  Pad: iy 
896             clhits[4] = Int_t(newclust[2][i]);
897 //  Pad: charge
898             clhits[5] = Int_t(newclust[3][i]);
899 //  Pad: chamber sector
900             clhits[6] = Int_t(newclust[4][i]);
901             
902             AddPadHit(clhits);
903         }
904     }
905 }
906
907 //___________________________________________
908 void AliMUON::Trigger(Int_t nev){
909 // call the Trigger Algorithm and fill TreeR
910
911   Int_t singlePlus[3]  = {0,0,0}; 
912   Int_t singleMinus[3] = {0,0,0}; 
913   Int_t singleUndef[3] = {0,0,0};
914   Int_t pairUnlike[3]  = {0,0,0}; 
915   Int_t pairLike[3]    = {0,0,0};
916
917   ResetTrigger();
918   AliMUONTriggerDecision* decision= new AliMUONTriggerDecision(1);
919   decision->Trigger();   
920   decision->GetGlobalTrigger(singlePlus, singleMinus, singleUndef,
921                              pairUnlike, pairLike);
922 // add a local trigger in the list 
923   AddGlobalTrigger(singlePlus, singleMinus, singleUndef, pairUnlike, pairLike);
924   Int_t i;
925   
926   for (Int_t icirc=0; icirc<AliMUONConstants::NTriggerCircuit(); icirc++) { 
927       if(decision->GetITrigger(icirc)==1) {
928           Int_t localtr[7]={0,0,0,0,0,0,0};      
929           Int_t loLpt[2]={0,0}; Int_t loHpt[2]={0,0}; Int_t loApt[2]={0,0};
930           decision->GetLutOutput(icirc, loLpt, loHpt, loApt);
931           localtr[0] = icirc;
932           localtr[1] = decision->GetStripX11(icirc);
933           localtr[2] = decision->GetDev(icirc);
934           localtr[3] = decision->GetStripY11(icirc);
935           for (i=0; i<2; i++) {    // convert the Lut output in 1 digit 
936               localtr[4] = localtr[4]+Int_t(loLpt[i]*TMath::Power(2,i));
937               localtr[5] = localtr[5]+Int_t(loHpt[i]*TMath::Power(2,i));
938               localtr[6] = localtr[6]+Int_t(loApt[i]*TMath::Power(2,i));
939           }
940           AddLocalTrigger(localtr);  // add a local trigger in the list
941       }
942   }
943   delete decision;
944
945   gAlice->TreeR()->Fill();
946   ResetTrigger();
947   char hname[30];
948   sprintf(hname,"TreeR%d",nev);
949   gAlice->TreeR()->Write(hname,TObject::kOverwrite);
950   gAlice->TreeR()->Reset();
951   printf("\n End of trigger for event %d", nev);
952 }
953
954
955 //____________________________________________
956 void AliMUON::Digits2Reco()
957 {
958   FindClusters();
959 }
960
961 void AliMUON::FindClusters()
962 {
963 //
964 //  Perform cluster finding
965 //
966     TClonesArray *dig1, *dig2;
967     Int_t ndig, k;
968     dig1 = new TClonesArray("AliMUONDigit",1000);
969     dig2 = new TClonesArray("AliMUONDigit",1000);
970     AliMUONDigit *digit;
971 //
972 // Loop on chambers and on cathode planes
973 //
974     ResetRawClusters();        
975     for (Int_t ich = 0; ich < 10; ich++) {
976         AliMUONChamber* iChamber = (AliMUONChamber*) (*fChambers)[ich];
977         AliMUONClusterFinderVS* rec = iChamber->ReconstructionModel();
978     
979         gAlice->ResetDigits();
980         gAlice->TreeD()->GetEvent(0);
981         TClonesArray *muonDigits = this->DigitsAddress(ich);
982         ndig=muonDigits->GetEntriesFast();
983         printf("\n 1 Found %d digits in %p %d", ndig, muonDigits,ich);
984         TClonesArray &lhits1 = *dig1;
985         Int_t n = 0;
986         for (k = 0; k < ndig; k++) {
987             digit = (AliMUONDigit*) muonDigits->UncheckedAt(k);
988             if (rec->TestTrack(digit->Track(0)))
989                 new(lhits1[n++]) AliMUONDigit(*digit);
990         }
991         gAlice->ResetDigits();
992         gAlice->TreeD()->GetEvent(1);
993         muonDigits  = this->DigitsAddress(ich);
994         ndig=muonDigits->GetEntriesFast();
995         printf("\n 2 Found %d digits in %p %d", ndig, muonDigits, ich);
996         TClonesArray &lhits2 = *dig2;
997         n=0;
998         
999         for (k=0; k<ndig; k++) {
1000             digit= (AliMUONDigit*) muonDigits->UncheckedAt(k);
1001             if (rec->TestTrack(digit->Track(0)))
1002             new(lhits2[n++]) AliMUONDigit(*digit);
1003         }
1004
1005         if (rec) {       
1006             AliMUONClusterInput::Instance()->SetDigits(ich, dig1, dig2);
1007             rec->FindRawClusters();
1008         }
1009         dig1->Delete();
1010         dig2->Delete();
1011     } // for ich
1012     delete dig1;
1013     delete dig2;
1014 }
1015  
1016 #ifdef never
1017 void AliMUON::Streamer(TBuffer &R__b)
1018 {
1019    // Stream an object of class AliMUON.
1020       AliMUONChamber        *iChamber;
1021       AliMUONTriggerCircuit *iTriggerCircuit;
1022       AliSegmentation       *segmentation;
1023       AliMUONResponse       *response;
1024       TClonesArray          *digitsaddress;
1025       TClonesArray          *rawcladdress;
1026       Int_t i;
1027       if (R__b.IsReading()) {
1028           Version_t R__v = R__b.ReadVersion(); if (R__v) { }
1029           AliDetector::Streamer(R__b);
1030           R__b >> fNPadHits;
1031           R__b >> fPadHits; // diff
1032           R__b >> fNLocalTrigger;       
1033           R__b >> fLocalTrigger;       
1034           R__b >> fNGlobalTrigger;       
1035           R__b >> fGlobalTrigger;   
1036           R__b >> fDchambers;
1037           R__b >> fRawClusters;
1038           R__b.ReadArray(fNdch);
1039           R__b.ReadArray(fNrawch);
1040           R__b >> fAccCut;
1041           R__b >> fAccMin;
1042           R__b >> fAccMax; 
1043           R__b >> fChambers;
1044           R__b >> fTriggerCircuits;
1045           for (i =0; i<AliMUONConstants::NTriggerCircuit(); i++) {
1046               iTriggerCircuit=(AliMUONTriggerCircuit*) (*fTriggerCircuits)[i];
1047               iTriggerCircuit->Streamer(R__b);
1048           }
1049 // Stream chamber related information
1050           for (i =0; i<AliMUONConstants::NCh(); i++) {
1051               iChamber=(AliMUONChamber*) (*fChambers)[i];
1052               iChamber->Streamer(R__b);
1053               if (iChamber->Nsec()==1) {
1054                   segmentation=iChamber->SegmentationModel(1);
1055                   if (segmentation)
1056                       segmentation->Streamer(R__b);
1057               } else {
1058                   segmentation=iChamber->SegmentationModel(1);
1059                   if (segmentation)
1060                       segmentation->Streamer(R__b);
1061                   if (segmentation)
1062                       segmentation=iChamber->SegmentationModel(2);
1063                   segmentation->Streamer(R__b);
1064               }
1065               response=iChamber->ResponseModel();
1066               if (response)
1067                   response->Streamer(R__b);       
1068               digitsaddress=(TClonesArray*) (*fDchambers)[i];
1069               digitsaddress->Streamer(R__b);
1070               if (i < AliMUONConstants::NTrackingCh()) {
1071                   rawcladdress=(TClonesArray*) (*fRawClusters)[i];
1072                   rawcladdress->Streamer(R__b);
1073               }
1074           }
1075           
1076       } else {
1077           R__b.WriteVersion(AliMUON::IsA());
1078           AliDetector::Streamer(R__b);
1079           R__b << fNPadHits;
1080           R__b << fPadHits; // diff
1081           R__b << fNLocalTrigger;       
1082           R__b << fLocalTrigger;       
1083           R__b << fNGlobalTrigger;       
1084           R__b << fGlobalTrigger; 
1085           R__b << fDchambers;
1086           R__b << fRawClusters;
1087           R__b.WriteArray(fNdch, AliMUONConstants::NCh());
1088           R__b.WriteArray(fNrawch, AliMUONConstants::NTrackingCh());
1089           
1090           R__b << fAccCut;
1091           R__b << fAccMin;
1092           R__b << fAccMax; 
1093           
1094           R__b << fChambers;
1095           R__b << fTriggerCircuits;
1096           for (i =0; i<AliMUONConstants::NTriggerCircuit(); i++) {
1097               iTriggerCircuit=(AliMUONTriggerCircuit*) (*fTriggerCircuits)[i];
1098               iTriggerCircuit->Streamer(R__b);
1099           }
1100           for (i =0; i<AliMUONConstants::NCh(); i++) {
1101               iChamber=(AliMUONChamber*) (*fChambers)[i];
1102               iChamber->Streamer(R__b);
1103               if (iChamber->Nsec()==1) {
1104                   segmentation=iChamber->SegmentationModel(1);
1105                   if (segmentation)
1106                       segmentation->Streamer(R__b);
1107               } else {
1108                   segmentation=iChamber->SegmentationModel(1);
1109                   if (segmentation)
1110                       segmentation->Streamer(R__b);
1111                   segmentation=iChamber->SegmentationModel(2);
1112                   if (segmentation)
1113                       segmentation->Streamer(R__b);
1114               }
1115               response=iChamber->ResponseModel();
1116               if (response)
1117                   response->Streamer(R__b);
1118               digitsaddress=(TClonesArray*) (*fDchambers)[i];
1119               digitsaddress->Streamer(R__b);
1120               if (i < AliMUONConstants::NTrackingCh()) {
1121                   rawcladdress=(TClonesArray*) (*fRawClusters)[i];
1122                   rawcladdress->Streamer(R__b);
1123               }
1124           }
1125       }
1126 }
1127 #endif
1128
1129 AliMUONPadHit* AliMUON::FirstPad(AliMUONHit*  hit, TClonesArray *clusters) 
1130 {
1131 //
1132     // Initialise the pad iterator
1133     // Return the address of the first padhit for hit
1134     TClonesArray *theClusters = clusters;
1135     Int_t nclust = theClusters->GetEntriesFast();
1136     if (nclust && hit->PHlast() > 0) {
1137         AliMUON::fMaxIterPad=hit->PHlast();
1138         AliMUON::fCurIterPad=hit->PHfirst();
1139         return (AliMUONPadHit*) clusters->UncheckedAt(AliMUON::fCurIterPad-1);
1140     } else {
1141         return 0;
1142     }
1143 }
1144
1145 AliMUONPadHit* AliMUON::NextPad(TClonesArray *clusters) 
1146 {
1147 // Get next pad (in iterator) 
1148 //
1149     AliMUON::fCurIterPad++;
1150     if (AliMUON::fCurIterPad <= AliMUON::fMaxIterPad) {
1151         return (AliMUONPadHit*) clusters->UncheckedAt(AliMUON::fCurIterPad-1);
1152     } else {
1153         return 0;
1154     }
1155 }
1156
1157
1158 AliMUONRawCluster *AliMUON::RawCluster(Int_t ichamber, Int_t icathod, Int_t icluster)
1159 {
1160 //
1161 //  Return rawcluster (icluster) for chamber ichamber and cathode icathod
1162 //  Obsolete ??
1163     TClonesArray *muonRawCluster  = RawClustAddress(ichamber);
1164     ResetRawClusters();
1165     TTree *treeR = gAlice->TreeR();
1166     Int_t nent=(Int_t)treeR->GetEntries();
1167     treeR->GetEvent(nent-2+icathod-1);
1168     //treeR->GetEvent(icathod);
1169     //Int_t nrawcl = (Int_t)muonRawCluster->GetEntriesFast();
1170
1171     AliMUONRawCluster * mRaw = (AliMUONRawCluster*)muonRawCluster->UncheckedAt(icluster);
1172     //printf("RawCluster _ nent nrawcl icluster mRaw %d %d %d%p\n",nent,nrawcl,icluster,mRaw);
1173     
1174     return  mRaw;
1175 }
1176  
1177 void   AliMUON::SetMerger(AliMUONMerger* merger)
1178 {
1179 // Set pointer to merger 
1180     fMerger = merger;
1181 }
1182
1183 AliMUONMerger*  AliMUON::Merger()
1184 {
1185 // Return pointer to merger
1186     return fMerger;
1187 }
1188
1189
1190
1191 AliMUON& AliMUON::operator = (const AliMUON& rhs)
1192 {
1193 // copy operator
1194 // dummy version
1195     return *this;
1196 }
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215