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