a0cb78fb1046fbea4598d39855aba852e5042bdc
[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 /* $Id$ */
17
18
19 ///////////////////////////////////////////////
20 //  Manager and hits classes for set:MUON     //
21 ////////////////////////////////////////////////
22
23 #include "Riostream.h"
24
25 #include <AliPDG.h>
26 #include <TBRIK.h>
27 #include <TCanvas.h>
28 #include <TDirectory.h>
29 #include <TFile.h>
30 #include <TGeometry.h>
31 #include <TMinuit.h>
32 #include <TNode.h> 
33 #include <TNtuple.h>
34 #include <TObjArray.h>
35 #include <TObject.h>
36 #include <TObjectTable.h>
37 #include <TPad.h>
38 #include <TParticle.h>
39 #include <TROOT.h>
40 #include <TRandom.h> 
41 #include <TRotMatrix.h>
42 #include <TTUBE.h>
43 #include <TTUBE.h>
44 #include <TTree.h> 
45 #include <TVector.h>
46 #include <TVirtualMC.h>
47
48 #include "AliConst.h" 
49 #include "AliHeader.h"
50 #include "AliHitMap.h"
51 #include "AliLoader.h"
52 #include "AliMUONLoader.h"
53 #include "AliMUON.h"
54 #include "AliMUONChamberTrigger.h"
55 #include "AliMUONClusterFinderVS.h"
56 #include "AliMUONClusterInput.h"
57 #include "AliMUONConstants.h"
58 #include "AliMUONDigit.h"
59 #include "AliMUONGlobalTrigger.h"
60 #include "AliMUONHit.h"
61 #include "AliMUONHitMapA1.h"
62 #include "AliMUONLocalTrigger.h"
63 #include "AliMUONMerger.h"      
64 #include "AliMUONPadHit.h"
65 #include "AliMUONRawCluster.h"
66 #include "AliMUONTransientDigit.h"
67 #include "AliMUONTriggerCircuit.h"
68 #include "AliMUONTriggerDecision.h"
69 #include "AliRun.h"     
70
71
72 // Defaults parameters for Z positions of chambers
73 // taken from values for "stations" in AliMUON::AliMUON
74 //     const Float_t zch[7]={528, 690., 975., 1249., 1449., 1610, 1710.};
75 // and from array "dstation" in AliMUONv1::CreateGeometry
76 //          Float_t dstation[5]={20., 20., 20, 20., 20.};
77 //     for tracking chambers,
78 //          according to (Z1 = zch - dstation) and  (Z2 = zch + dstation)
79 //          for the first and second chambers in the station, respectively,
80 // and from "DTPLANES" in AliMUONv1::CreateGeometry
81 //           const Float_t DTPLANES = 15.;
82 //     for trigger chambers,
83 //          according to (Z1 = zch) and  (Z2 = zch + DTPLANES)
84 //          for the first and second chambers in the station, respectively
85
86 ClassImp(AliMUON)
87 //___________________________________________
88 AliMUON::AliMUON()
89 {
90 // Default Constructor
91 //
92     fNCh             = 0;
93     fNTrackingCh     = 0;
94     fIshunt          = 0;
95     fPadHits         = 0;
96     fNPadHits        = 0;
97     fChambers        = 0;
98     fDchambers       = 0;
99     fTriggerCircuits = 0;  
100     fNdch            = 0;
101     fRawClusters     = 0;
102     fNrawch          = 0;
103     fGlobalTrigger   = 0;
104     fNLocalTrigger   = 0;
105     fLocalTrigger    = 0;
106     fNLocalTrigger   = 0;
107     fAccMin          = 0.;
108     fAccMax          = 0.;   
109     fAccCut          = kFALSE;
110     fMerger          = 0;
111     fFileName        = 0;
112 }
113  
114 //___________________________________________
115 AliMUON::AliMUON(const char *name, const char *title)
116        : AliDetector(name,title)
117 {
118 //Begin_Html
119 /*
120 <img src="gif/alimuon.gif">
121 */
122 //End_Html
123
124    fHits     = new TClonesArray("AliMUONHit",1000);
125    gAlice->AddHitList(fHits);
126    fPadHits = new TClonesArray("AliMUONPadHit",10000);
127    fNPadHits  =  0;
128    fIshunt     =  0;
129
130    fNCh             = AliMUONConstants::NCh(); 
131    fNTrackingCh     = AliMUONConstants::NTrackingCh();
132    fNdch            = new Int_t[fNCh];
133
134    fDchambers = new TObjArray(AliMUONConstants::NCh());
135
136    Int_t i;
137    
138    for (i=0; i<AliMUONConstants::NCh() ;i++) {
139        fDchambers->AddAt(new TClonesArray("AliMUONDigit",10000),i); 
140        fNdch[i]=0;
141    }
142
143    fNrawch      = new Int_t[fNTrackingCh];
144
145    fRawClusters = new TObjArray(AliMUONConstants::NTrackingCh());
146
147    for (i=0; i<AliMUONConstants::NTrackingCh();i++) {
148        fRawClusters->AddAt(new TClonesArray("AliMUONRawCluster",10000),i); 
149        fNrawch[i]=0;
150    }
151
152    fGlobalTrigger = new TClonesArray("AliMUONGlobalTrigger",1);    
153    fNGlobalTrigger = 0;
154    fLocalTrigger  = new TClonesArray("AliMUONLocalTrigger",234);    
155    fNLocalTrigger = 0;
156
157    SetMarkerColor(kRed);
158 //
159 //
160 //
161 //
162
163     Int_t ch;
164
165     fChambers = new TObjArray(AliMUONConstants::NCh());
166
167     // Loop over stations
168     for (Int_t st = 0; st < AliMUONConstants::NCh() / 2; st++) {
169       // Loop over 2 chambers in the station
170         for (Int_t stCH = 0; stCH < 2; stCH++) {
171 //
172 //    
173 //    Default Parameters for Muon Tracking Stations
174
175
176             ch = 2 * st + stCH;
177 //
178             if (ch < AliMUONConstants::NTrackingCh()) {
179               fChambers->AddAt(new AliMUONChamber(ch),ch);
180             } else {
181               fChambers->AddAt(new AliMUONChamberTrigger(ch),ch);
182             }
183             
184         //PH        AliMUONChamber* chamber = (AliMUONChamber*) (*fChambers)[ch];
185             AliMUONChamber* chamber = (AliMUONChamber*) fChambers->At(ch);
186             
187             chamber->SetGid(0);
188             // Default values for Z of chambers
189             chamber->SetZ(AliMUONConstants::DefaultChamberZ(ch));
190 //
191             chamber->InitGeo(AliMUONConstants::DefaultChamberZ(ch));
192 //          Set chamber inner and outer radius to default
193             chamber->SetRInner(AliMUONConstants::Dmin(st)/2);
194             chamber->SetROuter(AliMUONConstants::Dmax(st)/2);
195 //
196         } // Chamber stCH (0, 1) in 
197     }     // Station st (0...)
198 //    fChambers->SetLast(AliMUONConstants::NCh());
199     fMaxStepGas=0.01; 
200     fMaxStepAlu=0.1; 
201     fMaxDestepGas=-1;
202     fMaxDestepAlu=-1;
203 //
204    fMaxIterPad   = 0;
205    fCurIterPad   = 0;
206 //
207    fAccMin          = 0.;
208    fAccMax          = 0.;   
209    fAccCut          = kFALSE;
210
211    // cp new design of AliMUONTriggerDecision
212    fTriggerCircuits = new TObjArray(AliMUONConstants::NTriggerCircuit());
213    for (Int_t circ=0; circ<AliMUONConstants::NTriggerCircuit(); circ++) {
214      fTriggerCircuits->AddAt(new AliMUONTriggerCircuit(),circ);     
215
216    }
217      fMerger = 0;
218 }
219  
220 //___________________________________________
221 AliMUON::AliMUON(const AliMUON& rMUON):AliDetector(rMUON)
222 {
223 // Dummy copy constructor
224     ;
225     
226 }
227
228 AliMUON::~AliMUON()
229 {
230 // Destructor
231     if(fDebug) printf("%s: Calling AliMUON destructor !!!\n",ClassName());
232     
233     fIshunt  = 0;
234  
235     // Delete TObjArrays
236  
237     if (fChambers){
238       fChambers->Delete();
239       delete fChambers;
240     }
241  
242     if (fTriggerCircuits){
243       fTriggerCircuits->Delete();
244       delete fTriggerCircuits;
245     }
246  
247     if (fDchambers){
248       fDchambers->Delete();
249       delete fDchambers;
250     }
251  
252     if (fRawClusters){
253       fRawClusters->Delete();
254       delete fRawClusters;
255     }
256
257     if (fNrawch) delete [] fNrawch;
258  
259     // Delete TClonesArrays
260  
261     if (fPadHits){
262       fPadHits->Delete();
263       delete fPadHits;
264     }
265  
266     if (fGlobalTrigger){
267       fGlobalTrigger->Delete();
268       delete fGlobalTrigger;
269     }
270     fNGlobalTrigger = 0;
271     
272     if (fLocalTrigger){
273       fLocalTrigger->Delete();
274       delete fLocalTrigger;
275     }
276     fNLocalTrigger = 0;
277
278     if (fHits) {
279       fHits->Delete();
280       delete fHits;
281     }
282
283     if (fMerger) delete fMerger;
284     if (fNdch) delete [] fNdch;
285
286 }
287  
288 //___________________________________________
289 void AliMUON::AddHit(Int_t track, Int_t *vol, Float_t *hits)
290 {
291   TClonesArray &lhits = *fHits;
292   new(lhits[fNhits++]) AliMUONHit(fIshunt,track,vol,hits);
293 }
294 //___________________________________________
295 void AliMUON::AddHit(Int_t fIshunt, Int_t track, Int_t iChamber, 
296               Int_t idpart, Float_t X, Float_t Y, Float_t Z, 
297               Float_t tof, Float_t momentum, Float_t theta, 
298               Float_t phi, Float_t length, Float_t destep)
299 {
300   TClonesArray &lhits = *fHits;
301   new(lhits[fNhits++]) AliMUONHit(fIshunt, track, iChamber, 
302                idpart, X, Y, Z, 
303                tof, momentum, theta, 
304                phi, length, destep);
305 }
306 //___________________________________________
307 void AliMUON::AddPadHit(Int_t *clhits)  // To be removed
308 {
309    TClonesArray &lclusters = *fPadHits;
310    new(lclusters[fNPadHits++]) AliMUONPadHit(clhits);
311 }
312 //_____________________________________________________________________________
313 void AliMUON::AddDigits(Int_t id, Int_t *tracks, Int_t *charges, Int_t *digits)
314 {
315     //
316     // Add a MUON digit to the list
317     //
318
319   //PH    TClonesArray &ldigits = * ((TClonesArray*)(*fDchambers)[id]);
320     TClonesArray &ldigits = * ( (TClonesArray*) fDchambers->At(id) );
321     new(ldigits[fNdch[id]++]) AliMUONDigit(tracks,charges,digits);
322 }
323
324 //_____________________________________________________________________________
325 void AliMUON::AddRawCluster(Int_t id, const AliMUONRawCluster& c)
326 {
327     //
328     // Add a MUON digit to the list
329     //
330
331   //PH    TClonesArray &lrawcl = *((TClonesArray*)(*fRawClusters)[id]);
332     TClonesArray &lrawcl = *((TClonesArray*)fRawClusters->At(id));
333     new(lrawcl[fNrawch[id]++]) AliMUONRawCluster(c);
334 }
335
336 //___________________________________________
337 void AliMUON::AddGlobalTrigger(Int_t *singlePlus, Int_t *singleMinus,
338                                Int_t *singleUndef,
339                                Int_t *pairUnlike, Int_t *pairLike)
340 {
341 // add a MUON Global Trigger to the list (only one GlobalTrigger per event !)
342   TClonesArray &globalTrigger = *fGlobalTrigger;
343   new(globalTrigger[fNGlobalTrigger++]) 
344     AliMUONGlobalTrigger(singlePlus, singleMinus,  singleUndef, pairUnlike, 
345                          pairLike);
346 }
347 //___________________________________________
348 void AliMUON::AddLocalTrigger(Int_t *localtr)
349 {
350 // add a MUON Local Trigger to the list
351   TClonesArray &localTrigger = *fLocalTrigger;
352   new(localTrigger[fNLocalTrigger++]) AliMUONLocalTrigger(localtr);
353 }
354
355 //___________________________________________
356 void AliMUON::BuildGeometry()
357 {
358 // Geometry for event display
359   for (Int_t i=0; i<7; i++) {
360     for (Int_t j=0; j<2; j++) {
361       Int_t id=2*i+j+1;
362       this->Chamber(id-1).SegmentationModel(1)->Draw("eventdisplay");
363     }
364   }
365 }
366
367 //___________________________________________
368 Int_t AliMUON::DistancetoPrimitive(Int_t , Int_t )
369 {
370    return 9999;
371 }
372
373 //___________________________________________
374 void AliMUON::MakeBranch(Option_t* option)
375 {
376     //
377     // Create Tree branches for the MUON.
378     //
379     const Int_t kBufferSize = 4000;
380     char branchname[30];
381     sprintf(branchname,"%sCluster",GetName());
382     
383     
384     const char *cD = strstr(option,"D");
385     const char *cR = strstr(option,"R");
386     const char *cH = strstr(option,"H");
387
388     if (TreeH() && cH) 
389      {
390       if (fPadHits == 0x0) fPadHits = new TClonesArray("AliMUONPadHit",10000);
391       MakeBranchInTree(TreeH(), branchname, &fPadHits, kBufferSize, 0);
392       if (fHits == 0x0) fHits     = new TClonesArray("AliMUONHit",1000);
393      }
394     //it must be under fHits creation
395     AliDetector::MakeBranch(option);
396     
397     if (cD  && fLoader->TreeD()) {
398       //
399       // one branch for digits per chamber
400       // 
401       Int_t i;
402       if (fDchambers  == 0x0) 
403         {
404           fDchambers = new TObjArray(AliMUONConstants::NCh());
405           for (Int_t i=0; i<AliMUONConstants::NCh() ;i++) {
406               fDchambers->AddAt(new TClonesArray("AliMUONDigit",10000),i); 
407           }
408         }
409     
410       for (i=0; i<AliMUONConstants::NCh() ;i++) 
411        {
412         sprintf(branchname,"%sDigits%d",GetName(),i+1); 
413         MakeBranchInTree(fLoader->TreeD(), branchname, &((*fDchambers)[i]), kBufferSize, 0);
414         printf("Making Branch %s for digits in chamber %d\n",branchname,i+1);
415        }
416     }
417     
418     if (cR  && fLoader->TreeR()) {
419       //     
420       // one branch for raw clusters per chamber
421       //  
422       printf("Make Branch - TreeR address %p\n",fLoader->TreeR());
423       
424       Int_t i;
425       if (fRawClusters == 0x0)
426       {
427         fRawClusters = new TObjArray(AliMUONConstants::NTrackingCh());
428         for (Int_t i=0; i<AliMUONConstants::NTrackingCh();i++) {
429             fRawClusters->AddAt(new TClonesArray("AliMUONRawCluster",10000),i); 
430         }
431       }
432
433       for (i=0; i<AliMUONConstants::NTrackingCh() ;i++) 
434        {
435          sprintf(branchname,"%sRawClusters%d",GetName(),i+1);   
436          MakeBranchInTree(fLoader->TreeR(), branchname, &((*fRawClusters)[i]), kBufferSize, 0);
437          printf("Making Branch %s for raw clusters in chamber %d\n",branchname,i+1);
438       }
439       //
440       // one branch for global trigger
441       //
442       sprintf(branchname,"%sGlobalTrigger",GetName());
443       
444       if (fGlobalTrigger == 0x0) {
445         fGlobalTrigger = new TClonesArray("AliMUONGlobalTrigger",1); 
446       }
447       MakeBranchInTree(fLoader->TreeR(), branchname, &fGlobalTrigger, kBufferSize, 0);
448       printf("Making Branch %s for Global Trigger\n",branchname);
449       //
450       // one branch for local trigger
451       //  
452       sprintf(branchname,"%sLocalTrigger",GetName());
453       
454       if (fLocalTrigger == 0x0) {
455         fLocalTrigger  = new TClonesArray("AliMUONLocalTrigger",234);
456       }
457       
458       MakeBranchInTree(fLoader->TreeR(), branchname, &fLocalTrigger, kBufferSize, 0);
459       printf("Making Branch %s for Local Trigger\n",branchname);
460    }
461 }
462
463 //___________________________________________
464 void AliMUON::SetTreeAddress()
465 {
466   // Set branch address for the Hits and Digits Tree.
467   char branchname[30];
468
469   TBranch *branch;
470   TTree *treeH = fLoader->TreeH();
471   TTree *treeD = fLoader->TreeD();
472   TTree *treeR = fLoader->TreeR();
473
474   if (treeH) {
475     if (fPadHits == 0x0) fPadHits = new TClonesArray("AliMUONPadHit",10000);
476     if (fPadHits) {
477       branch = treeH->GetBranch("MUONCluster");
478       if (branch) branch->SetAddress(&fPadHits);
479     }
480     if (fHits == 0x0) fHits     = new TClonesArray("AliMUONHit",1000);
481   }
482   //it must be under fHits creation
483   AliDetector::SetTreeAddress();
484
485   if (treeD) {
486       if (fDchambers == 0x0) 
487         {
488           fDchambers = new TObjArray(AliMUONConstants::NCh());
489           for (Int_t i=0; i<AliMUONConstants::NCh() ;i++) {
490               fDchambers->AddAt(new TClonesArray("AliMUONDigit",10000),i); 
491           }
492         }
493       for (int i=0; i<AliMUONConstants::NCh(); i++) {
494           sprintf(branchname,"%sDigits%d",GetName(),i+1);
495                         
496                       if (fDchambers) {
497               branch = treeD->GetBranch(branchname);
498               if (branch) branch->SetAddress(&((*fDchambers)[i]));
499           }
500       }
501   }
502
503   // printf("SetTreeAddress --- treeR address  %p \n",treeR);
504
505   if (treeR) {
506       if (fRawClusters == 0x0)
507       {
508         fRawClusters = new TObjArray(AliMUONConstants::NTrackingCh());
509         for (Int_t i=0; i<AliMUONConstants::NTrackingCh();i++) {
510             fRawClusters->AddAt(new TClonesArray("AliMUONRawCluster",10000),i); 
511         }
512       }
513       
514       for (int i=0; i<AliMUONConstants::NTrackingCh(); i++) {
515           sprintf(branchname,"%sRawClusters%d",GetName(),i+1);
516           if (fRawClusters) {
517               branch = treeR->GetBranch(branchname);
518               if (branch) branch->SetAddress(&((*fRawClusters)[i]));
519           }
520       }
521
522       if (fLocalTrigger == 0x0) {
523         fLocalTrigger  = new TClonesArray("AliMUONLocalTrigger",234);
524       }
525
526       if (fLocalTrigger) {
527         branch = treeR->GetBranch("MUONLocalTrigger");
528         if (branch) branch->SetAddress(&fLocalTrigger);
529       }
530       
531       if (fGlobalTrigger == 0x0) {
532         fGlobalTrigger = new TClonesArray("AliMUONGlobalTrigger",1); 
533       }
534       
535       if (fGlobalTrigger) {
536         branch = treeR->GetBranch("MUONGlobalTrigger");
537         if (branch) branch->SetAddress(&fGlobalTrigger);
538       }
539   }
540 }
541 //___________________________________________
542 void AliMUON::ResetHits()
543 {
544   // Reset number of clusters and the cluster array for this detector
545   AliDetector::ResetHits();
546   fNPadHits = 0;
547   if (fPadHits) fPadHits->Clear();
548 }
549
550 //____________________________________________
551 void AliMUON::ResetDigits()
552 {
553     //
554     // Reset number of digits and the digits array for this detector
555     //
556     if (fDchambers == 0x0) return;
557     for ( int i=0;i<AliMUONConstants::NCh();i++ ) {
558       //PH      if ((*fDchambers)[i])    ((TClonesArray*)(*fDchambers)[i])->Clear();
559         if ((*fDchambers)[i])    ((TClonesArray*)fDchambers->At(i))->Clear();
560         if (fNdch)  fNdch[i]=0;
561     }
562 }
563 //____________________________________________
564 void AliMUON::ResetRawClusters()
565 {
566     //
567     // Reset number of raw clusters and the raw clust array for this detector
568     //
569     for ( int i=0;i<AliMUONConstants::NTrackingCh();i++ ) {
570       //PH      if ((*fRawClusters)[i])    ((TClonesArray*)(*fRawClusters)[i])->Clear();
571         if ((*fRawClusters)[i])    ((TClonesArray*)fRawClusters->At(i))->Clear();
572         if (fNrawch)  fNrawch[i]=0;
573     }
574 }
575
576 //____________________________________________
577 void AliMUON::ResetTrigger()
578 {
579   //  Reset Local and Global Trigger 
580   fNGlobalTrigger = 0;
581   if (fGlobalTrigger) fGlobalTrigger->Clear();
582   fNLocalTrigger = 0;
583   if (fLocalTrigger) fLocalTrigger->Clear();
584 }
585
586 //____________________________________________
587 void AliMUON::SetPadSize(Int_t id, Int_t isec, Float_t p1, Float_t p2)
588 {
589 // Set the pad size for chamber id and cathode isec
590     Int_t i=2*(id-1);
591     //PH    ((AliMUONChamber*) (*fChambers)[i])  ->SetPadSize(isec,p1,p2);
592     //PH    ((AliMUONChamber*) (*fChambers)[i+1])->SetPadSize(isec,p1,p2);
593     ((AliMUONChamber*) fChambers->At(i))  ->SetPadSize(isec,p1,p2);
594     ((AliMUONChamber*) fChambers->At(i+1))->SetPadSize(isec,p1,p2);
595 }
596
597 //___________________________________________
598 void AliMUON::SetChambersZ(const Float_t *Z)
599 {
600   // Set Z values for all chambers (tracking and trigger)
601   // from the array pointed to by "Z"
602     for (Int_t ch = 0; ch < AliMUONConstants::NCh(); ch++)
603       //PH      ((AliMUONChamber*) ((*fChambers)[ch]))->SetZ(Z[ch]);
604         ((AliMUONChamber*) fChambers->At(ch))->SetZ(Z[ch]);
605     return;
606 }
607
608 //___________________________________________
609 void AliMUON::SetChambersZToDefault()
610 {
611   // Set Z values for all chambers (tracking and trigger)
612   // to default values
613   SetChambersZ(AliMUONConstants::DefaultChamberZ());
614   return;
615 }
616
617 //___________________________________________
618 void AliMUON::SetChargeSlope(Int_t id, Float_t p1)
619 {
620 // Set the inverse charge slope for chamber id
621     Int_t i=2*(id-1);
622     //PH    ((AliMUONChamber*) (*fChambers)[i])->SetChargeSlope(p1);
623     //PH    ((AliMUONChamber*) (*fChambers)[i+1])->SetChargeSlope(p1);
624     ((AliMUONChamber*) fChambers->At(i))->SetChargeSlope(p1);
625     ((AliMUONChamber*) fChambers->At(i+1))->SetChargeSlope(p1);
626 }
627
628 //___________________________________________
629 void AliMUON::SetChargeSpread(Int_t id, Float_t p1, Float_t p2)
630 {
631 // Set sigma of charge spread for chamber id
632     Int_t i=2*(id-1);
633     //PH    ((AliMUONChamber*) fChambers->At(i))->SetChargeSpread(p1,p2);
634     //PH    ((AliMUONChamber*) fChambers->Ati+1])->SetChargeSpread(p1,p2);
635     ((AliMUONChamber*) fChambers->At(i))->SetChargeSpread(p1,p2);
636     ((AliMUONChamber*) fChambers->At(i+1))->SetChargeSpread(p1,p2);
637 }
638
639 //___________________________________________
640 void AliMUON::SetSigmaIntegration(Int_t id, Float_t p1)
641 {
642 // Set integration limits for charge spread
643     Int_t i=2*(id-1);
644     //PH    ((AliMUONChamber*) (*fChambers)[i])->SetSigmaIntegration(p1);
645     //PH    ((AliMUONChamber*) (*fChambers)[i+1])->SetSigmaIntegration(p1);
646     ((AliMUONChamber*) fChambers->At(i))->SetSigmaIntegration(p1);
647     ((AliMUONChamber*) fChambers->At(i+1))->SetSigmaIntegration(p1);
648 }
649
650 //___________________________________________
651 void AliMUON::SetMaxAdc(Int_t id, Int_t p1)
652 {
653 // Set maximum number for ADCcounts (saturation)
654     Int_t i=2*(id-1);
655     //PH    ((AliMUONChamber*) (*fChambers)[i])->SetMaxAdc(p1);
656     //PH    ((AliMUONChamber*) (*fChambers)[i+1])->SetMaxAdc(p1);
657     ((AliMUONChamber*) fChambers->At(i))->SetMaxAdc(p1);
658     ((AliMUONChamber*) fChambers->At(i+1))->SetMaxAdc(p1);
659 }
660
661 //___________________________________________
662 void AliMUON::SetMaxStepGas(Float_t p1)
663 {
664 // Set stepsize in gas
665      fMaxStepGas=p1;
666 }
667
668 //___________________________________________
669 void AliMUON::SetMaxStepAlu(Float_t p1)
670 {
671 // Set step size in Alu
672     fMaxStepAlu=p1;
673 }
674
675 //___________________________________________
676 void AliMUON::SetMaxDestepGas(Float_t p1)
677 {
678 // Set maximum step size in Gas
679     fMaxDestepGas=p1;
680 }
681
682 //___________________________________________
683 void AliMUON::SetMaxDestepAlu(Float_t p1)
684 {
685 // Set maximum step size in Alu
686     fMaxDestepAlu=p1;
687 }
688 //___________________________________________
689 void AliMUON::SetAcceptance(Bool_t acc, Float_t angmin, Float_t angmax)
690 {
691 // Set acceptance cuts 
692    fAccCut=acc;
693    fAccMin=angmin*TMath::Pi()/180;
694    fAccMax=angmax*TMath::Pi()/180;
695    Int_t ch;
696    if (acc) {
697        for (Int_t st = 0; st < AliMUONConstants::NCh() / 2; st++) {
698            // Loop over 2 chambers in the station
699            for (Int_t stCH = 0; stCH < 2; stCH++) {
700                ch = 2 * st + stCH;
701 //         Set chamber inner and outer radius according to acceptance cuts
702                Chamber(ch).SetRInner(AliMUONConstants::DefaultChamberZ(ch)*TMath::Tan(fAccMin));
703                Chamber(ch).SetROuter(AliMUONConstants::DefaultChamberZ(ch)*TMath::Tan(fAccMax));
704            } // chamber loop
705        } // station loop
706    }
707 }
708 //___________________________________________
709 void   AliMUON::SetSegmentationModel(Int_t id, Int_t isec, AliSegmentation *segmentation)
710 {
711 // Set the segmentation for chamber id cathode isec
712   //PH    ((AliMUONChamber*) (*fChambers)[id])->SetSegmentationModel(isec, segmentation);
713     ((AliMUONChamber*) fChambers->At(id))->SetSegmentationModel(isec, segmentation);
714
715 }
716 //___________________________________________
717 void   AliMUON::SetResponseModel(Int_t id, AliMUONResponse *response)
718 {
719 // Set the response for chamber id
720   //PH    ((AliMUONChamber*) (*fChambers)[id])->SetResponseModel(response);
721     ((AliMUONChamber*) fChambers->At(id))->SetResponseModel(response);
722 }
723
724 void   AliMUON::SetReconstructionModel(Int_t id, AliMUONClusterFinderVS *reconst)
725 {
726 // Set ClusterFinder for chamber id
727   //PH    ((AliMUONChamber*) (*fChambers)[id])->SetReconstructionModel(reconst);
728     ((AliMUONChamber*) fChambers->At(id))->SetReconstructionModel(reconst);
729 }
730
731 void   AliMUON::SetNsec(Int_t id, Int_t nsec)
732 {
733 // Set number of segmented cathods for chamber id
734   //PH    ((AliMUONChamber*) (*fChambers)[id])->SetNsec(nsec);
735     ((AliMUONChamber*) fChambers->At(id))->SetNsec(nsec);
736 }
737
738 //___________________________________________
739 void AliMUON::SDigits2Digits()
740 {
741
742 // write TreeD here 
743
744     if (!fMerger) {
745       if (gAlice->GetDebug()>0) {
746         cerr<<"AliMUON::SDigits2Digits: create default AliMUONMerger "<<endl;
747         cerr<<" no merging, just digitization of 1 event will be done"<<endl;
748       }
749       fMerger = new AliMUONMerger();
750     }
751     fMerger->Init();
752     fMerger->Digitise();
753     char hname[30];
754     //    sprintf(hname,"TreeD%d",fLoader->GetHeader()->GetEvent());
755     fLoader->TreeD()->Write(hname,TObject::kOverwrite);
756     fLoader->TreeD()->Reset();
757 }
758
759
760 //__________________________________________________________________________
761 AliLoader* AliMUON::MakeLoader(const char* topfoldername)
762
763 //builds standard getter (AliLoader type)
764 //if detector wants to use castomized getter, it must overload this method
765
766  if (GetDebug())
767    Info("MakeLoader",
768         "Creating standard getter for detector %s. Top folder is %s.",
769          GetName(),topfoldername);
770      
771  fLoader = new AliMUONLoader(GetName(),topfoldername);
772  return fLoader;
773 }
774 //__________________________________________________________________________
775 // To be removed
776 void AliMUON::MakePadHits(Float_t xhit,Float_t yhit, Float_t zhit,
777                           Float_t eloss, Float_t tof,  Int_t idvol)
778 {
779 //
780 //  Calls the charge disintegration method of the current chamber and adds
781 //  the simulated cluster to the root treee 
782 //
783     Int_t clhits[7];
784     Float_t newclust[6][500];
785     Int_t nnew;
786     
787     
788 //
789 //  Integrated pulse height on chamber
790
791     
792     clhits[0]=fNhits+1;
793 //
794 //
795 //    if (idvol == 6) printf("\n ->Disintegration %f %f %f", xhit, yhit, eloss );
796     
797
798     //PH    ((AliMUONChamber*) (*fChambers)[idvol])
799     ((AliMUONChamber*) fChambers->At(idvol))
800         ->DisIntegration(eloss, tof, xhit, yhit, zhit, nnew, newclust);
801     Int_t ic=0;
802 //    if (idvol == 6) printf("\n nnew  %d \n", nnew);
803 //
804 //  Add new clusters
805     for (Int_t i=0; i<nnew; i++) {
806         if (Int_t(newclust[3][i]) > 0) {
807             ic++;
808 // Cathode plane
809             clhits[1] = Int_t(newclust[5][i]);
810 //  Cluster Charge
811             clhits[2] = Int_t(newclust[0][i]);
812 //  Pad: ix
813             clhits[3] = Int_t(newclust[1][i]);
814 //  Pad: iy 
815             clhits[4] = Int_t(newclust[2][i]);
816 //  Pad: charge
817             clhits[5] = Int_t(newclust[3][i]);
818 //  Pad: chamber sector
819             clhits[6] = Int_t(newclust[4][i]);
820             
821             AddPadHit(clhits);
822         }
823     }
824 }
825
826 //___________________________________________
827 void AliMUON::Trigger(Int_t nev){
828 // call the Trigger Algorithm and fill TreeR
829
830   Int_t singlePlus[3]  = {0,0,0}; 
831   Int_t singleMinus[3] = {0,0,0}; 
832   Int_t singleUndef[3] = {0,0,0};
833   Int_t pairUnlike[3]  = {0,0,0}; 
834   Int_t pairLike[3]    = {0,0,0};
835
836   ResetTrigger();
837   AliMUONTriggerDecision* decision= new AliMUONTriggerDecision(1);
838   decision->Trigger();   
839   decision->GetGlobalTrigger(singlePlus, singleMinus, singleUndef,
840                              pairUnlike, pairLike);
841
842 // add a local trigger in the list 
843   AddGlobalTrigger(singlePlus, singleMinus, singleUndef, pairUnlike, pairLike);
844   Int_t i;
845   
846   for (Int_t icirc=0; icirc<AliMUONConstants::NTriggerCircuit(); icirc++) { 
847       if(decision->GetITrigger(icirc)==1) {
848           Int_t localtr[7]={0,0,0,0,0,0,0};      
849           Int_t loLpt[2]={0,0}; Int_t loHpt[2]={0,0}; Int_t loApt[2]={0,0};
850           decision->GetLutOutput(icirc, loLpt, loHpt, loApt);
851           localtr[0] = icirc;
852           localtr[1] = decision->GetStripX11(icirc);
853           localtr[2] = decision->GetDev(icirc);
854           localtr[3] = decision->GetStripY11(icirc);
855           for (i=0; i<2; i++) {    // convert the Lut output in 1 digit 
856               localtr[4] = localtr[4]+Int_t(loLpt[i]*TMath::Power(2,i));
857               localtr[5] = localtr[5]+Int_t(loHpt[i]*TMath::Power(2,i));
858               localtr[6] = localtr[6]+Int_t(loApt[i]*TMath::Power(2,i));
859           }
860           AddLocalTrigger(localtr);  // add a local trigger in the list
861       }
862   }
863
864   delete decision;
865
866   fLoader->TreeR()->Fill();
867 //  char hname[30];
868 //  sprintf(hname,"TreeR%d",nev);
869 //  fLoader->TreeR()->Write(hname,TObject::kOverwrite);
870 //  fLoader->TreeR()->Reset();
871   fLoader->WriteRecPoints("OVERWRITE");
872   ResetTrigger();
873   
874   printf("\n End of trigger for event %d", nev);
875 }
876
877
878 //____________________________________________
879 void AliMUON::Digits2Reco()
880 {
881   FindClusters();
882   Int_t nev = gAlice->GetHeader()->GetEvent();
883   fLoader->TreeR()->Fill();
884   // char hname[30];
885   // sprintf(hname,"TreeR%d", nev);
886   //fLoader->TreeR()->Write(hname);
887   //fLoader->TreeR()->Reset();
888   fLoader->WriteRecPoints("OVERWRITE");
889   ResetRawClusters();        
890   printf("\n End of cluster finding for event %d", nev);
891 }
892
893 void AliMUON::FindClusters()
894 {
895 //
896 //  Perform cluster finding
897 //
898     TClonesArray *dig1, *dig2;
899     Int_t ndig, k;
900     dig1 = new TClonesArray("AliMUONDigit",1000);
901     dig2 = new TClonesArray("AliMUONDigit",1000);
902     AliMUONDigit *digit;
903 // Loop on chambers and on cathode planes
904 //
905     ResetRawClusters();        
906     TClonesArray * muonDigits;
907
908     for (Int_t ich = 0; ich < 10; ich++) {
909       //PH      AliMUONChamber* iChamber = (AliMUONChamber*) (*fChambers)[ich];
910         AliMUONChamber* iChamber = (AliMUONChamber*) fChambers->At(ich);
911         AliMUONClusterFinderVS* rec = iChamber->ReconstructionModel();
912     
913         ResetDigits();
914         fLoader->TreeD()->GetEvent(0);
915         //TClonesArray *
916         muonDigits = (TClonesArray *) Dchambers()->At(ich);
917         ndig=muonDigits->GetEntriesFast();
918         printf("\n 1 Found %d digits in %p chamber %d", ndig, muonDigits,ich);
919         TClonesArray &lhits1 = *dig1;
920         Int_t n = 0;
921         for (k = 0; k < ndig; k++) {
922             digit = (AliMUONDigit*) muonDigits->UncheckedAt(k);
923             if (rec->TestTrack(digit->Track(0)))
924                 new(lhits1[n++]) AliMUONDigit(*digit);
925         }
926         ResetDigits();
927         fLoader->TreeD()->GetEvent(1);
928         //muonDigits  = this->DigitsAddress(ich);
929         muonDigits = (TClonesArray *) Dchambers()->At(ich);
930         ndig=muonDigits->GetEntriesFast();
931         printf("\n 2 Found %d digits in %p %d", ndig, muonDigits, ich);
932         TClonesArray &lhits2 = *dig2;
933         n=0;
934         
935         for (k=0; k<ndig; k++) {
936             digit= (AliMUONDigit*) muonDigits->UncheckedAt(k);
937             if (rec->TestTrack(digit->Track(0)))
938             new(lhits2[n++]) AliMUONDigit(*digit);
939         }
940
941         if (rec) {       
942             AliMUONClusterInput::Instance()->SetDigits(ich, dig1, dig2);
943             rec->FindRawClusters();
944         }
945         dig1->Delete();
946         dig2->Delete();
947     } // for ich
948     delete dig1;
949     delete dig2;
950 }
951  
952 #ifdef never
953 void AliMUON::Streamer(TBuffer &R__b)
954 {
955    // Stream an object of class AliMUON.
956       AliMUONChamber        *iChamber;
957       AliMUONTriggerCircuit *iTriggerCircuit;
958       AliSegmentation       *segmentation;
959       AliMUONResponse       *response;
960       TClonesArray          *digitsaddress;
961       TClonesArray          *rawcladdress;
962       Int_t i;
963       if (R__b.IsReading()) {
964           Version_t R__v = R__b.ReadVersion(); if (R__v) { }
965           AliDetector::Streamer(R__b);
966           R__b >> fNPadHits;
967           R__b >> fPadHits; // diff
968           R__b >> fNLocalTrigger;       
969           R__b >> fLocalTrigger;       
970           R__b >> fNGlobalTrigger;       
971           R__b >> fGlobalTrigger;   
972           R__b >> fDchambers;
973           R__b >> fRawClusters;
974           R__b.ReadArray(fNdch);
975           R__b.ReadArray(fNrawch);
976           R__b >> fAccCut;
977           R__b >> fAccMin;
978           R__b >> fAccMax; 
979           R__b >> fChambers;
980           R__b >> fTriggerCircuits;
981           for (i =0; i<AliMUONConstants::NTriggerCircuit(); i++) {
982               iTriggerCircuit=(AliMUONTriggerCircuit*) (*fTriggerCircuits)[i];
983               iTriggerCircuit->Streamer(R__b);
984           }
985 // Stream chamber related information
986           for (i =0; i<AliMUONConstants::NCh(); i++) {
987               iChamber=(AliMUONChamber*) (*fChambers)[i];
988               iChamber->Streamer(R__b);
989               if (iChamber->Nsec()==1) {
990                   segmentation=iChamber->SegmentationModel(1);
991                   if (segmentation)
992                       segmentation->Streamer(R__b);
993               } else {
994                   segmentation=iChamber->SegmentationModel(1);
995                   if (segmentation)
996                       segmentation->Streamer(R__b);
997                   if (segmentation)
998                       segmentation=iChamber->SegmentationModel(2);
999                   segmentation->Streamer(R__b);
1000               }
1001               response=iChamber->ResponseModel();
1002               if (response)
1003                   response->Streamer(R__b);       
1004               digitsaddress=(TClonesArray*) (*fDchambers)[i];
1005               digitsaddress->Streamer(R__b);
1006               if (i < AliMUONConstants::NTrackingCh()) {
1007                   rawcladdress=(TClonesArray*) (*fRawClusters)[i];
1008                   rawcladdress->Streamer(R__b);
1009               }
1010           }
1011           
1012       } else {
1013           R__b.WriteVersion(AliMUON::IsA());
1014           AliDetector::Streamer(R__b);
1015           R__b << fNPadHits;
1016           R__b << fPadHits; // diff
1017           R__b << fNLocalTrigger;       
1018           R__b << fLocalTrigger;       
1019           R__b << fNGlobalTrigger;       
1020           R__b << fGlobalTrigger; 
1021           R__b << fDchambers;
1022           R__b << fRawClusters;
1023           R__b.WriteArray(fNdch, AliMUONConstants::NCh());
1024           R__b.WriteArray(fNrawch, AliMUONConstants::NTrackingCh());
1025           
1026           R__b << fAccCut;
1027           R__b << fAccMin;
1028           R__b << fAccMax; 
1029           
1030           R__b << fChambers;
1031           R__b << fTriggerCircuits;
1032           for (i =0; i<AliMUONConstants::NTriggerCircuit(); i++) {
1033               iTriggerCircuit=(AliMUONTriggerCircuit*) (*fTriggerCircuits)[i];
1034               iTriggerCircuit->Streamer(R__b);
1035           }
1036           for (i =0; i<AliMUONConstants::NCh(); i++) {
1037               iChamber=(AliMUONChamber*) (*fChambers)[i];
1038               iChamber->Streamer(R__b);
1039               if (iChamber->Nsec()==1) {
1040                   segmentation=iChamber->SegmentationModel(1);
1041                   if (segmentation)
1042                       segmentation->Streamer(R__b);
1043               } else {
1044                   segmentation=iChamber->SegmentationModel(1);
1045                   if (segmentation)
1046                       segmentation->Streamer(R__b);
1047                   segmentation=iChamber->SegmentationModel(2);
1048                   if (segmentation)
1049                       segmentation->Streamer(R__b);
1050               }
1051               response=iChamber->ResponseModel();
1052               if (response)
1053                   response->Streamer(R__b);
1054               digitsaddress=(TClonesArray*) (*fDchambers)[i];
1055               digitsaddress->Streamer(R__b);
1056               if (i < AliMUONConstants::NTrackingCh()) {
1057                   rawcladdress=(TClonesArray*) (*fRawClusters)[i];
1058                   rawcladdress->Streamer(R__b);
1059               }
1060           }
1061       }
1062 }
1063 #endif
1064
1065 AliMUONPadHit* AliMUON::FirstPad(AliMUONHit*  hit, TClonesArray *clusters) 
1066 {
1067 // to be removed
1068     // Initialise the pad iterator
1069     // Return the address of the first padhit for hit
1070     TClonesArray *theClusters = clusters;
1071     Int_t nclust = theClusters->GetEntriesFast();
1072     if (nclust && hit->PHlast() > 0) {
1073         AliMUON::fMaxIterPad=hit->PHlast();
1074         AliMUON::fCurIterPad=hit->PHfirst();
1075         return (AliMUONPadHit*) clusters->UncheckedAt(AliMUON::fCurIterPad-1);
1076     } else {
1077         return 0;
1078     }
1079 }
1080
1081 AliMUONPadHit* AliMUON::NextPad(TClonesArray *clusters) 
1082 {
1083   // To be removed
1084 // Get next pad (in iterator) 
1085 //
1086     AliMUON::fCurIterPad++;
1087     if (AliMUON::fCurIterPad <= AliMUON::fMaxIterPad) {
1088         return (AliMUONPadHit*) clusters->UncheckedAt(AliMUON::fCurIterPad-1);
1089     } else {
1090         return 0;
1091     }
1092 }
1093
1094
1095 AliMUONRawCluster *AliMUON::RawCluster(Int_t ichamber, Int_t icathod, Int_t icluster)
1096 {
1097 //
1098 //  Return rawcluster (icluster) for chamber ichamber and cathode icathod
1099 //  Obsolete ??
1100     TClonesArray *muonRawCluster  = RawClustAddress(ichamber);
1101     ResetRawClusters();
1102     TTree *treeR = fLoader->TreeR();
1103     Int_t nent=(Int_t)treeR->GetEntries();
1104     treeR->GetEvent(nent-2+icathod-1);
1105     //treeR->GetEvent(icathod);
1106     //Int_t nrawcl = (Int_t)muonRawCluster->GetEntriesFast();
1107
1108     AliMUONRawCluster * mRaw = (AliMUONRawCluster*)muonRawCluster->UncheckedAt(icluster);
1109     //printf("RawCluster _ nent nrawcl icluster mRaw %d %d %d%p\n",nent,nrawcl,icluster,mRaw);
1110     
1111     return  mRaw;
1112 }
1113  
1114 void   AliMUON::SetMerger(AliMUONMerger* merger)
1115 {
1116 // Set pointer to merger 
1117     fMerger = merger;
1118 }
1119
1120 AliMUONMerger*  AliMUON::Merger()
1121 {
1122 // Return pointer to merger
1123     return fMerger;
1124 }
1125
1126
1127
1128 AliMUON& AliMUON::operator = (const AliMUON& /*rhs*/)
1129 {
1130 // copy operator
1131 // dummy version
1132     return *this;
1133 }
1134
1135 ////////////////////////////////////////////////////////////////////////
1136 void AliMUON::MakeBranchInTreeD(TTree *treeD, const char *file)
1137 {
1138     //
1139     // Create TreeD branches for the MUON.
1140     //
1141
1142   const Int_t kBufferSize = 4000;
1143   char branchname[30];
1144     
1145   if (fDchambers  == 0x0)   {
1146     fDchambers = new TObjArray(AliMUONConstants::NCh());
1147     for (Int_t i=0; i<AliMUONConstants::NCh() ;i++) {
1148       fDchambers->AddAt(new TClonesArray("AliMUONDigit",10000),i); 
1149     }
1150   }
1151   //
1152   // one branch for digits per chamber
1153   // 
1154   for (Int_t i=0; i<AliMUONConstants::NCh() ;i++) {
1155     sprintf(branchname,"%sDigits%d",GetName(),i+1);     
1156     if (fDchambers && treeD) {
1157       MakeBranchInTree(treeD, 
1158                        branchname, &((*fDchambers)[i]), kBufferSize, file);
1159 //      printf("Making Branch %s for digits in chamber %d\n",branchname,i+1);
1160     }
1161   }
1162 }
1163
1164 //___________________________________________
1165