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