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