]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONv1.cxx
New segmentation with switch between old and new (Ch. Finck)
[u/mrichter/AliRoot.git] / MUON / AliMUONv1.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *      SigmaEffect_thetadegrees                                                                  *
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 purpeateose. It is      *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /* $Id$ */
17
18 /////////////////////////////////////////////////////////
19 //  Manager and hits classes for set:MUON version 1    //
20 /////////////////////////////////////////////////////////
21
22 #include <TRandom.h>
23 #include <TF1.h>
24 #include <TClonesArray.h>
25 #include <TRandom.h> 
26 #include <TVirtualMC.h>
27 #include <TGeoMatrix.h>
28
29 #include "AliMUONv1.h"
30 #include "AliConst.h" 
31 #include "AliMUONChamber.h"
32 #include "AliMUONConstants.h"
33 #include "AliMUONFactoryV2.h"
34 #include "AliMUONHit.h"
35 #include "AliMUONTriggerCircuit.h"
36 #include "AliMUONGeometryBuilder.h"     
37 #include "AliMUONGeometryModule.h"      
38 #include "AliMUONGeometrySVMap.h"       
39 #include "AliMUONGeometryDetElement.h"  
40 #include "AliMagF.h"
41 #include "AliRun.h"
42 #include "AliMC.h"
43 #include "AliLog.h"
44
45 ClassImp(AliMUONv1)
46  
47 //___________________________________________
48 AliMUONv1::AliMUONv1() 
49   : AliMUON(),
50     fStepManagerVersionOld(kFALSE),
51     fStepManagerVersionDE(kFALSE),
52     fAngleEffect(kTRUE),
53     fStepMaxInActiveGas(0.6),
54     fStepSum(0x0),
55     fDestepSum(0x0),
56     fTrackMomentum(), 
57     fTrackPosition(),
58     fElossRatio(0x0),
59     fAngleEffect10(0x0),
60     fAngleEffectNorma(0x0)
61 {
62 // Default constructor
63
64
65 //___________________________________________
66 AliMUONv1::AliMUONv1(const char *name, const char *title)
67   : AliMUON(name,title), 
68     fStepManagerVersionOld(kFALSE),
69     fStepManagerVersionDE(kFALSE),
70     fAngleEffect(kTRUE),
71     fStepMaxInActiveGas(0.6),
72     fStepSum(0x0),
73     fDestepSum(0x0),
74     fTrackMomentum(), 
75     fTrackPosition(),
76     fElossRatio(0x0),
77     fAngleEffect10(0x0),
78     fAngleEffectNorma(0x0)
79 {
80 // Standard onstructor
81
82     // By default include all stations
83
84     fStepSum   = new Float_t [AliMUONConstants::NCh()];
85     fDestepSum = new Float_t [AliMUONConstants::NCh()];
86     for (Int_t i=0; i<AliMUONConstants::NCh(); i++) {
87       fStepSum[i] =0.0;
88       fDestepSum[i]=0.0;
89     }
90     // Ratio of particle mean eloss with respect MIP's Khalil Boudjemline, sep 2003, PhD.Thesis and Particle Data Book
91     fElossRatio = new TF1("ElossRatio","[0]+[1]*x+[2]*x*x+[3]*x*x*x+[4]*x*x*x*x",0.5,5.); 
92     fElossRatio->SetParameter(0,1.02138);
93     fElossRatio->SetParameter(1,-9.54149e-02);
94     fElossRatio->SetParameter(2,+7.83433e-02); 
95     fElossRatio->SetParameter(3,-9.98208e-03);
96     fElossRatio->SetParameter(4,+3.83279e-04);
97
98     // Angle effect in tracking chambers at theta =10 degres as a function of ElossRatio (Khalil BOUDJEMLINE sep 2003 Ph.D Thesis) (in micrometers)
99     fAngleEffect10 = new TF1("AngleEffect10","[0]+[1]*x+[2]*x*x",0.5,3.0);
100     fAngleEffect10->SetParameter(0, 1.90691e+02);
101     fAngleEffect10->SetParameter(1,-6.62258e+01);
102     fAngleEffect10->SetParameter(2,+1.28247e+01);
103     // Angle effect: Normalisation form theta=10 degres to theta between 0 and 10 (Khalil BOUDJEMLINE sep 2003 Ph.D Thesis)  
104     // Angle with respect to the wires assuming that chambers are perpendicular to the z axis.
105     fAngleEffectNorma = new TF1("AngleEffectNorma","[0]+[1]*x+[2]*x*x+[3]*x*x*x",0.0,10.0);
106     fAngleEffectNorma->SetParameter(0,4.148);
107     fAngleEffectNorma->SetParameter(1,-6.809e-01);
108     fAngleEffectNorma->SetParameter(2,5.151e-02);
109     fAngleEffectNorma->SetParameter(3,-1.490e-03);
110 }
111
112 //_____________________________________________________________________________
113 AliMUONv1::AliMUONv1(const AliMUONv1& right) 
114   : AliMUON(right) 
115 {  
116   // copy constructor (not implemented)
117
118   AliFatal("Copy constructor not provided.");
119 }
120
121 //___________________________________________
122 AliMUONv1::~AliMUONv1()
123 {
124 // Destructor
125
126   delete [] fStepSum;
127   delete [] fDestepSum;
128   delete fElossRatio;
129   delete fAngleEffect10;
130   delete fAngleEffectNorma;  
131 }
132
133 //_____________________________________________________________________________
134 AliMUONv1& AliMUONv1::operator=(const AliMUONv1& right)
135 {
136   // assignement operator (not implemented)
137
138   // check assignement to self
139   if (this == &right) return *this;
140
141   AliFatal("Assignement operator not provided.");
142     
143   return *this;  
144 }    
145
146 //__________________________________________________
147 void AliMUONv1::CreateGeometry()
148 {
149 //
150 // Construct geometry using geometry builder
151 //
152
153   fGeometryBuilder->CreateGeometry();
154 }
155
156 //________________________________________________________________
157 void AliMUONv1::CreateMaterials()
158 {
159 //
160 // Construct materials using geometry builder
161 //
162
163   fGeometryBuilder->CreateMaterials();
164 }
165
166 //___________________________________________
167 void AliMUONv1::Init()
168
169    AliDebug(1,"Start Init for version 1 - CPC chamber type");
170    Int_t i;
171
172  
173   //
174    // Initialize geometry
175    //
176    fGeometryBuilder->InitGeometry();
177    AliDebug(1,"Finished Init for version 1 - CPC chamber type");   
178
179    AliMUONFactory* factory = 0x0;
180
181    if (fSegmentationType == 1) {
182      factory = new AliMUONFactory();
183      printf("\n Old Segmentation \n");
184    }
185
186    if (fSegmentationType == 2) {
187      factory = new AliMUONFactoryV2();
188      printf("\n New Segmentation \n");
189    } 
190
191    factory->Build(this, "default");
192
193    //
194    // Initialize segmentation
195    //
196    if (!fSegmentationType) {
197      AliFatal("No Segmentation Type defined.");
198      return;
199    }
200
201    if (fSegmentationType == 1) {
202    for (i=0; i<AliMUONConstants::NCh(); i++) 
203        ( (AliMUONChamber*) (*fChambers)[i])->Init();
204    }
205
206    if (fSegmentationType == 2) {
207      for (i=0; i<AliMUONConstants::NCh(); i++) 
208        ( (AliMUONChamber*) (*fChambers)[i])->Init(fSegmentationType);// new segmentation
209    }
210  
211    if (fSegmentationType == 1) {
212     //cp 
213      AliDebug(1,"Start Init for Trigger Circuits");
214      for (i=0; i<AliMUONConstants::NTriggerCircuit(); i++) 
215        ( (AliMUONTriggerCircuit*) (*fTriggerCircuits)[i])->Init(i);
216      AliDebug(1,"Finished Init for Trigger Circuits");
217    } 
218
219
220
221 }
222
223 //__________________________________________________________________
224 Int_t  AliMUONv1::GetChamberId(Int_t volId) const
225 {
226 // Check if the volume with specified  volId is a sensitive volume (gas) 
227 // of some chamber and returns the chamber number;
228 // if not sensitive volume - return 0.
229 // ---
230
231 /*
232   for (Int_t i = 1; i <= AliMUONConstants::NCh(); i++)
233     if (volId==((AliMUONChamber*)(*fChambers)[i-1])->GetGid()) return i;
234 */
235   for (Int_t i = 1; i <= AliMUONConstants::NCh(); i++)
236     if ( ((AliMUONChamber*)(*fChambers)[i-1])->IsSensId(volId) ) return i;
237
238   return 0;
239 }
240
241 //_______________________________________________________________________________
242 TString  AliMUONv1::CurrentVolumePath() const
243 {
244 // Returns current volume path
245 // (Could be removed when this function is available via gMC)
246 // ---       
247
248   TString path = "";
249   TString name;
250   Int_t copyNo;
251   Int_t imother = 0;
252   do {
253     name = gMC->CurrentVolOffName(imother);
254     gMC->CurrentVolOffID(imother++, copyNo);
255     TString add = "/";
256     add += name;
257     add += ".";
258     add += copyNo;
259     path.Insert(0,add); 
260   }
261   while ( name != TString("ALIC") );
262   
263   return path;  
264 }
265
266 //_______________________________________________________________________________
267 void AliMUONv1::StepManager()
268 {
269   // Stepmanager for the chambers
270   // TBR
271
272  if (fStepManagerVersionDE) {
273     StepManager2();
274     return;
275   }
276
277  if (fStepManagerVersionOld) {
278     StepManagerOld();
279     return;
280   }
281
282   // Only charged tracks
283   if( !(gMC->TrackCharge()) ) return; 
284   // Only charged tracks
285   
286   // Only gas gap inside chamber
287   // Tag chambers and record hits when track enters 
288   static Int_t   idvol=-1;
289   Int_t   iChamber=0;
290   Int_t   id=0;
291   Int_t   copy;
292   const  Float_t kBig = 1.e10;
293
294
295   //
296   // Only gas gap inside chamber
297   // Tag chambers and record hits when track enters 
298   id=gMC->CurrentVolID(copy);
299   iChamber = GetChamberId(id);
300   idvol = iChamber -1;
301
302   if (idvol == -1) return;
303
304   // Filling TrackRefs file for MUON. Our Track references are the active volume of the chambers
305   if ( (gMC->IsTrackEntering() || gMC->IsTrackExiting() ) )     
306     AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber());
307   
308    if( gMC->IsTrackEntering() ) {
309      Float_t theta = fTrackMomentum.Theta();
310      if ((TMath::Pi()-theta)*kRaddeg>=15.) gMC->SetMaxStep(fStepMaxInActiveGas); // We use Pi-theta because z is negative
311   }
312
313 //  if (GetDebug()) {
314 //     Float_t z = ( (AliMUONChamber*)(*fChambers)[idvol])->Z() ;
315 //      Info("StepManager Step","Active volume found %d chamber %d Z chamber is %f ",idvol,iChamber, z);
316 //   }  
317   // Particule id and mass, 
318   Int_t     ipart = gMC->TrackPid();
319   Float_t   mass  = gMC->TrackMass();
320
321   fDestepSum[idvol]+=gMC->Edep();
322   // Get current particle id (ipart), track position (pos)  and momentum (mom)
323   if ( fStepSum[idvol]==0.0 )  gMC->TrackMomentum(fTrackMomentum);
324   fStepSum[idvol]+=gMC->TrackStep();
325   
326 //   if (GetDebug()) {
327 //     Info("StepManager Step","iChamber %d, Particle %d, theta %f phi %f mass %f StepSum %f eloss %g",
328 //       iChamber,ipart, fTrackMomentum.Theta()*kRaddeg, fTrackMomentum.Phi()*kRaddeg, mass, fStepSum[idvol], gMC->Edep());//     Info("StepManager Step","Track Momentum %f %f %f", fTrackMomentum.X(), fTrackMomentum.Y(), fTrackMomentum.Z()) ;
329 //     gMC->TrackPosition(fTrackPosition);
330 //     Info("StepManager Step","Track Position %f %f %f",fTrackPosition.X(),fTrackPosition.Y(),fTrackPosition.Z()) ;
331 //   }
332
333   // Track left chamber or StepSum larger than fStepMaxInActiveGas
334   if ( gMC->IsTrackExiting() || 
335        gMC->IsTrackStop() || 
336        gMC->IsTrackDisappeared()||
337        (fStepSum[idvol]>fStepMaxInActiveGas) ) {
338     
339     if   ( gMC->IsTrackExiting() || 
340            gMC->IsTrackStop() || 
341            gMC->IsTrackDisappeared() ) gMC->SetMaxStep(kBig);
342
343     gMC->TrackPosition(fTrackPosition);
344     Float_t theta = fTrackMomentum.Theta();
345     Float_t phi   = fTrackMomentum.Phi();
346     
347     TLorentzVector backToWire( fStepSum[idvol]/2.*sin(theta)*cos(phi),
348                                fStepSum[idvol]/2.*sin(theta)*sin(phi),
349                                fStepSum[idvol]/2.*cos(theta),0.0       );
350     //     if (GetDebug()) 
351     //       Info("StepManager Exit","Track Position %f %f %f",fTrackPosition.X(),fTrackPosition.Y(),fTrackPosition.Z()) ;
352     //     if (GetDebug()) 
353     //        Info("StepManager Exit ","Track backToWire %f %f %f",backToWire.X(),backToWire.Y(),backToWire.Z()) ;
354     fTrackPosition-=backToWire;
355     
356     //-------------- Angle effect 
357     // Ratio between energy loss of particle and Mip as a function of BetaGamma of particle (Energy/Mass)
358     
359     Float_t betaxGamma    = fTrackMomentum.P()/mass;//  pc/mc2
360     Float_t sigmaEffect10degrees;
361     Float_t sigmaEffectThetadegrees;
362     Float_t eLossParticleELossMip;
363     Float_t yAngleEffect=0.;
364     Float_t thetawires      =  TMath::Abs( TMath::ASin( TMath::Sin(TMath::Pi()-theta) * TMath::Sin(phi) ) );// We use Pi-theta because z is negative
365
366
367     if (fAngleEffect){
368     if ( (betaxGamma >3.2)   &&  (thetawires*kRaddeg<=15.) ) {
369       betaxGamma=TMath::Log(betaxGamma);
370       eLossParticleELossMip = fElossRatio->Eval(betaxGamma);
371       // 10 degrees is a reference for a model (arbitrary)
372       sigmaEffect10degrees=fAngleEffect10->Eval(eLossParticleELossMip);// in micrometers
373       // Angle with respect to the wires assuming that chambers are perpendicular to the z axis.
374       sigmaEffectThetadegrees =  sigmaEffect10degrees/fAngleEffectNorma->Eval(thetawires*kRaddeg);  // For 5mm gap  
375       if ( (iChamber==1)  ||  (iChamber==2) )  
376         sigmaEffectThetadegrees/=(1.09833e+00+1.70000e-02*(thetawires*kRaddeg)); // The gap is different (4mm)
377       yAngleEffect=1.e-04*gRandom->Gaus(0,sigmaEffectThetadegrees); // Error due to the angle effect in cm
378     }
379     }
380     
381     // Detection elements ids
382     AliMUONGeometryModule* geometry
383       = Chamber(iChamber-1).GetGeometry();
384
385     AliMUONGeometryDetElement* detElement
386       = geometry->FindBySensitiveVolume(CurrentVolumePath());
387
388     Int_t detElemId = 0;
389     if (detElement) detElemId = detElement->GetUniqueID(); 
390  
391     if (!detElemId) {
392       cerr << "Chamber id: "
393            << setw(3) << iChamber << "  "
394            << "Current SV: " 
395            <<  CurrentVolumePath() 
396            << "  detElemId: "
397            << setw(5) << detElemId 
398            << endl;
399       Double_t x, y, z;
400       gMC->TrackPosition(x, y, z);         
401       cerr << "   global position: "
402            << x << ", " << y << ", " << z
403            << endl;
404       AliWarning("DetElemId not identified.");
405     }  
406     
407     // One hit per chamber
408     GetMUONData()->AddHit(fIshunt, 
409                           gAlice->GetMCApp()->GetCurrentTrackNumber(), 
410                           iChamber, ipart,
411                           fTrackPosition.X(), 
412                           fTrackPosition.Y()+yAngleEffect, 
413                           fTrackPosition.Z(), 
414                           gMC->TrackTime(),
415                           fTrackMomentum.P(),
416                           theta, 
417                           phi, 
418                           fStepSum[idvol], 
419                           fDestepSum[idvol],                        
420                           fTrackPosition.X(),
421                           fTrackPosition.Y(),
422                           fTrackPosition.Z());
423
424 //     if (GetDebug()){
425 //       Info("StepManager Exit","Particle exiting from chamber %d",iChamber);
426 //       Info("StepManager Exit","StepSum %f eloss geant %g ",fStepSum[idvol],fDestepSum[idvol]);
427 //       Info("StepManager Exit","Track Position %f %f %f",fTrackPosition.X(),fTrackPosition.Y(),fTrackPosition.Z()) ;
428 //     }
429     fStepSum[idvol]  =0; // Reset for the next event
430     fDestepSum[idvol]=0; // Reset for the next event
431   }
432 }
433
434 //_______________________________________________________________________________
435 void AliMUONv1::StepManager2()
436 {
437   // Stepmanager for the chambers
438
439  if (fStepManagerVersionOld) {
440     StepManagerOld2();
441     return;
442   }
443
444   // Only charged tracks
445   if( !(gMC->TrackCharge()) ) return; 
446   // Only charged tracks
447   
448   // Only gas gap inside chamber
449   // Tag chambers and record hits when track enters 
450   static Int_t   idvol=-1;
451   Int_t   iChamber=0;
452   Int_t   id=0;
453   Int_t   copy;
454   const  Float_t kBig = 1.e10;
455
456
457   //
458   // Only gas gap inside chamber
459   // Tag chambers and record hits when track enters 
460   id=gMC->CurrentVolID(copy);
461   iChamber = GetChamberId(id);
462   idvol = iChamber -1;
463
464   if (idvol == -1) return;
465   
466   // Filling TrackRefs file for MUON. Our Track references are the active volume of the chambers
467   if ( (gMC->IsTrackEntering() || gMC->IsTrackExiting() ) )     
468     AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber());
469   
470    if( gMC->IsTrackEntering() ) {
471      Float_t theta = fTrackMomentum.Theta();
472      if ((TMath::Pi()-theta)*kRaddeg>=15.) gMC->SetMaxStep(fStepMaxInActiveGas); // We use Pi-theta because z is negative
473   }
474
475 //  if (GetDebug()) {
476 //     Float_t z = ( (AliMUONChamber*)(*fChambers)[idvol])->Z() ;
477 //      Info("StepManager Step","Active volume found %d chamber %d Z chamber is %f ",idvol,iChamber, z);
478 //   }  
479   // Particule id and mass, 
480   Int_t     ipart = gMC->TrackPid();
481   Float_t   mass  = gMC->TrackMass();
482
483   fDestepSum[idvol]+=gMC->Edep();
484   // Get current particle id (ipart), track position (pos)  and momentum (mom)
485   if ( fStepSum[idvol]==0.0 )  gMC->TrackMomentum(fTrackMomentum);
486   fStepSum[idvol]+=gMC->TrackStep();
487   
488 //   if (GetDebug()) {
489 //     Info("StepManager Step","iChamber %d, Particle %d, theta %f phi %f mass %f StepSum %f eloss %g",
490 //       iChamber,ipart, fTrackMomentum.Theta()*kRaddeg, fTrackMomentum.Phi()*kRaddeg, mass, fStepSum[idvol], gMC->Edep());//     Info("StepManager Step","Track Momentum %f %f %f", fTrackMomentum.X(), fTrackMomentum.Y(), fTrackMomentum.Z()) ;
491 //     gMC->TrackPosition(fTrackPosition);
492 //     Info("StepManager Step","Track Position %f %f %f",fTrackPosition.X(),fTrackPosition.Y(),fTrackPosition.Z()) ;
493 //   }
494
495   // Track left chamber or StepSum larger than fStepMaxInActiveGas
496   if ( gMC->IsTrackExiting() || 
497        gMC->IsTrackStop() || 
498        gMC->IsTrackDisappeared()||
499        (fStepSum[idvol]>fStepMaxInActiveGas) ) {
500     
501     if   ( gMC->IsTrackExiting() || 
502            gMC->IsTrackStop() || 
503            gMC->IsTrackDisappeared() ) gMC->SetMaxStep(kBig);
504
505     gMC->TrackPosition(fTrackPosition);
506     Float_t theta = fTrackMomentum.Theta();
507     Float_t phi   = fTrackMomentum.Phi();
508     
509     TLorentzVector backToWire( fStepSum[idvol]/2.*sin(theta)*cos(phi),
510                                fStepSum[idvol]/2.*sin(theta)*sin(phi),
511                                fStepSum[idvol]/2.*cos(theta),0.0       );
512     //     if (GetDebug()) 
513     //       Info("StepManager Exit","Track Position %f %f %f",fTrackPosition.X(),fTrackPosition.Y(),fTrackPosition.Z()) ;
514     //     if (GetDebug()) 
515     //        Info("StepManager Exit ","Track backToWire %f %f %f",backToWire.X(),backToWire.Y(),backToWire.Z()) ;
516     fTrackPosition-=backToWire;
517     
518     //-------------- Angle effect 
519     // Ratio between energy loss of particle and Mip as a function of BetaGamma of particle (Energy/Mass)
520     
521     Float_t betaxGamma    = fTrackMomentum.P()/mass;//  pc/mc2
522     Float_t sigmaEffect10degrees;
523     Float_t sigmaEffectThetadegrees;
524     Float_t eLossParticleELossMip;
525     Float_t yAngleEffect=0.;
526     Float_t thetawires      =  TMath::Abs( TMath::ASin( TMath::Sin(TMath::Pi()-theta) * TMath::Sin(phi) ) );// We use Pi-theta because z is negative
527
528
529     if (fAngleEffect){
530     if ( (betaxGamma >3.2)   &&  (thetawires*kRaddeg<=15.) ) {
531       betaxGamma=TMath::Log(betaxGamma);
532       eLossParticleELossMip = fElossRatio->Eval(betaxGamma);
533       // 10 degrees is a reference for a model (arbitrary)
534       sigmaEffect10degrees=fAngleEffect10->Eval(eLossParticleELossMip);// in micrometers
535       // Angle with respect to the wires assuming that chambers are perpendicular to the z axis.
536       sigmaEffectThetadegrees =  sigmaEffect10degrees/fAngleEffectNorma->Eval(thetawires*kRaddeg);  // For 5mm gap  
537       if ( (iChamber==1)  ||  (iChamber==2) )  
538         sigmaEffectThetadegrees/=(1.09833e+00+1.70000e-02*(thetawires*kRaddeg)); // The gap is different (4mm)
539       yAngleEffect=1.e-04*gRandom->Gaus(0,sigmaEffectThetadegrees); // Error due to the angle effect in cm
540     }
541     }
542     
543     // Detection elements ids
544     AliMUONGeometryModule* geometry
545       = Chamber(iChamber-1).GetGeometry();
546
547     AliMUONGeometryDetElement* detElement
548       = geometry->FindBySensitiveVolume(CurrentVolumePath());
549
550     Int_t detElemId = 0;
551     if (detElement) detElemId = detElement->GetUniqueID(); 
552  
553     if (!detElemId) {
554       cerr << "Chamber id: "
555            << setw(3) << iChamber << "  "
556            << "Current SV: " 
557            <<  CurrentVolumePath() 
558            << "  detElemId: "
559            << setw(5) << detElemId 
560            << endl;
561       Double_t x, y, z;
562       gMC->TrackPosition(x, y, z);         
563       cerr << "   global position: "
564            << x << ", " << y << ", " << z
565            << endl;
566       AliError("DetElemId not identified.");
567     }  
568     
569     // One hit per chamber
570     GetMUONData()->AddHit2(fIshunt, 
571                           gAlice->GetMCApp()->GetCurrentTrackNumber(), 
572                           detElemId, ipart,
573                           fTrackPosition.X(), 
574                           fTrackPosition.Y()+yAngleEffect, 
575                           fTrackPosition.Z(), 
576                           gMC->TrackTime(),
577                           fTrackMomentum.P(),
578                           theta, 
579                           phi, 
580                           fStepSum[idvol], 
581                           fDestepSum[idvol],                        
582                           fTrackPosition.X(),
583                           fTrackPosition.Y(),
584                           fTrackPosition.Z());
585
586 //     if (GetDebug()){
587 //       Info("StepManager Exit","Particle exiting from chamber %d",iChamber);
588 //       Info("StepManager Exit","StepSum %f eloss geant %g ",fStepSum[idvol],fDestepSum[idvol]);
589 //       Info("StepManager Exit","Track Position %f %f %f",fTrackPosition.X(),fTrackPosition.Y(),fTrackPosition.Z()) ;
590 //     }
591     fStepSum[idvol]  =0; // Reset for the next event
592     fDestepSum[idvol]=0; // Reset for the next event
593   }
594 }
595
596 //__________________________________________
597 void AliMUONv1::StepManagerOld()
598 {
599   // Old Stepmanager for the chambers
600   // TBR
601   
602   Int_t          copy, id;
603   static Int_t   idvol =-1;
604   static Int_t   vol[2];
605   Int_t          ipart;
606   TLorentzVector pos;
607   TLorentzVector mom;
608   Float_t        theta,phi;
609   Float_t        destep, step;
610   
611   static Float_t sstep;
612   static Float_t eloss, eloss2, xhit, yhit, zhit, tof, tlength;
613   const  Float_t kBig = 1.e10;
614   static Float_t hits[15];
615
616   TClonesArray &lhits = *fHits;
617
618   //
619   //
620   // Only charged tracks
621   if( !(gMC->TrackCharge()) ) return; 
622   //
623   // Only gas gap inside chamber
624   // Tag chambers and record hits when track enters 
625   id=gMC->CurrentVolID(copy);
626   vol[0] = GetChamberId(id);
627   idvol = vol[0] -1;
628
629   if (idvol == -1) return;
630
631   //
632   // Get current particle id (ipart), track position (pos)  and momentum (mom) 
633   gMC->TrackPosition(pos);
634   gMC->TrackMomentum(mom);
635
636   ipart  = gMC->TrackPid();
637
638   //
639   // momentum loss and steplength in last step
640   destep = gMC->Edep();
641   step   = gMC->TrackStep();
642   // cout<<"------------"<<step<<endl;
643   //
644   // record hits when track enters ...
645   if( gMC->IsTrackEntering()) {
646
647       gMC->SetMaxStep(fMaxStepGas);
648       Double_t tc = mom[0]*mom[0]+mom[1]*mom[1];
649       Double_t rt = TMath::Sqrt(tc);
650       Double_t pmom = TMath::Sqrt(tc+mom[2]*mom[2]);
651       Double_t tx = mom[0]/pmom;
652       Double_t ty = mom[1]/pmom;
653       Double_t tz = mom[2]/pmom;
654       Double_t s  = ((AliMUONChamber*)(*fChambers)[idvol])
655           ->ResponseModel()
656           ->Pitch()/tz;
657       theta   = Float_t(TMath::ATan2(rt,Double_t(mom[2])))*kRaddeg;
658       phi     = Float_t(TMath::ATan2(Double_t(mom[1]),Double_t(mom[0])))*kRaddeg;
659       hits[0] = Float_t(ipart);         // Geant3 particle type
660       hits[1] = pos[0]+s*tx;            // X-position for hit
661       hits[2] = pos[1]+s*ty;            // Y-position for hit
662       hits[3] = pos[2]+s*tz;            // Z-position for hit
663       hits[4] = theta;                  // theta angle of incidence
664       hits[5] = phi;                    // phi angle of incidence 
665       hits[8] = 0;//PadHits does not exist anymore  (Float_t) fNPadHits;    // first padhit
666       hits[9] = -1;                     // last pad hit
667       hits[10] = mom[3];                // hit momentum P
668       hits[11] = mom[0];                // Px
669       hits[12] = mom[1];                // Py
670       hits[13] = mom[2];                // Pz
671       tof=gMC->TrackTime();
672       hits[14] = tof;                   // Time of flight
673       tlength  = 0;
674       eloss    = 0;
675       eloss2   = 0;
676       sstep=0;
677       xhit     = pos[0];
678       yhit     = pos[1];      
679       zhit     = pos[2];      
680       Chamber(idvol).ChargeCorrelationInit();
681       // Only if not trigger chamber
682
683 //       printf("---------------------------\n");
684 //       printf(">>>> Y =  %f \n",hits[2]);
685 //       printf("---------------------------\n");
686     
687       
688
689      //  if(idvol < AliMUONConstants::NTrackingCh()) {
690 //        //
691 //        //  Initialize hit position (cursor) in the segmentation model 
692 //        ((AliMUONChamber*) (*fChambers)[idvol])
693 //            ->SigGenInit(pos[0], pos[1], pos[2]);
694 //       } else {
695 //        //geant3->Gpcxyz();
696 //        //printf("In the Trigger Chamber #%d\n",idvol-9);
697 //       }
698   }
699   eloss2+=destep;
700   sstep+=step;
701
702   // cout<<sstep<<endl;
703
704   // 
705   // Calculate the charge induced on a pad (disintegration) in case 
706   //
707   // Mip left chamber ...
708   if( gMC->IsTrackExiting() || gMC->IsTrackStop() || gMC->IsTrackDisappeared()){
709       gMC->SetMaxStep(kBig);
710       eloss   += destep;
711       tlength += step;
712       
713       Float_t x0,y0,z0;
714       Float_t localPos[3];
715       Float_t globalPos[3] = {pos[0], pos[1], pos[2]};
716       gMC->Gmtod(globalPos,localPos,1); 
717
718       if(idvol < AliMUONConstants::NTrackingCh()) {
719 // tracking chambers
720           x0 = 0.5*(xhit+pos[0]);
721           y0 = 0.5*(yhit+pos[1]);
722           z0 = 0.5*(zhit+pos[2]);
723       } else {
724 // trigger chambers
725           x0 = xhit;
726           y0 = yhit;
727           z0 = 0.;
728       }
729       
730
731       //      if (eloss >0)  MakePadHits(x0,y0,z0,eloss,tof,idvol);
732       
733           
734       hits[6] = tlength;   // track length
735       hits[7] = eloss2;    // de/dx energy loss
736
737
738       //      if (fNPadHits > (Int_t)hits[8]) {
739       //          hits[8] = hits[8]+1;
740       //          hits[9] = 0: // PadHits does not exist anymore (Float_t) fNPadHits;
741       //}
742 //
743 //    new hit 
744       
745       new(lhits[fNhits++]) 
746         AliMUONHit(fIshunt, gAlice->GetMCApp()->GetCurrentTrackNumber(), vol, hits, kTRUE);
747       eloss = 0; 
748       //
749       // Check additional signal generation conditions 
750       // defined by the segmentation
751       // model (boundary crossing conditions)
752       // only for tracking chambers
753   } else if 
754       ((idvol < AliMUONConstants::NTrackingCh()) &&
755        ((AliMUONChamber*) (*fChambers)[idvol])->SigGenCond(pos[0], pos[1], pos[2]))
756   {
757       ((AliMUONChamber*) (*fChambers)[idvol])
758           ->SigGenInit(pos[0], pos[1], pos[2]);
759       
760       Float_t localPos[3];
761       Float_t globalPos[3] = {pos[0], pos[1], pos[2]};
762       gMC->Gmtod(globalPos,localPos,1); 
763
764       eloss    += destep;
765
766       // if (eloss > 0 && idvol < AliMUONConstants::NTrackingCh())
767       //        MakePadHits(0.5*(xhit+pos[0]),0.5*(yhit+pos[1]),pos[2],eloss,tof,idvol);
768       xhit     = pos[0];
769       yhit     = pos[1]; 
770       zhit     = pos[2];
771       eloss = 0;
772       tlength += step ;
773       //
774       // nothing special  happened, add up energy loss
775   } else {        
776       eloss   += destep;
777       tlength += step ;
778   }
779 }
780
781 //__________________________________________
782 void AliMUONv1::StepManagerOld2()
783 {
784   // Old Stepmanager for the chambers
785   Int_t          copy, id;
786   static Int_t   idvol =-1;
787   static Int_t   vol[2];
788   Int_t          ipart;
789   TLorentzVector pos;
790   TLorentzVector mom;
791   Float_t        theta,phi;
792   Float_t        destep, step;
793   
794   static Float_t sstep;
795   static Float_t eloss, eloss2, xhit, yhit, zhit, tof, tlength;
796   const  Float_t kBig = 1.e10;
797   static Float_t hits[15];
798
799   TClonesArray &lhits = *fHits;
800
801   //
802   //
803   // Only charged tracks
804   if( !(gMC->TrackCharge()) ) return; 
805   //
806   // Only gas gap inside chamber
807   // Tag chambers and record hits when track enters 
808   id=gMC->CurrentVolID(copy);
809
810   Int_t iChamber = GetChamberId(id);
811   idvol =  iChamber-1;
812
813   if (idvol == -1) return;
814
815   // Detection elements id
816   AliMUONGeometryModule* geometry
817     = Chamber(iChamber-1).GetGeometry();
818
819   AliMUONGeometryDetElement* detElement
820     = geometry->FindBySensitiveVolume(CurrentVolumePath());
821
822   Int_t detElemId = 0;
823   if (detElement) detElemId = detElement->GetUniqueID(); 
824  
825   if (!detElemId) {
826     cerr << "Chamber id: "
827          << setw(3) << iChamber << "  "
828          << "Current SV: " 
829          <<  CurrentVolumePath() 
830          << "  detElemId: "
831          << setw(5) << detElemId 
832          << endl;
833     Double_t x, y, z;
834     gMC->TrackPosition(x, y, z);           
835     cerr << "   global position: "
836          << x << ", " << y << ", " << z
837          << endl;
838     AliError("DetElemId not identified.");
839   }  
840   vol[0] = detElemId;
841     
842   //
843   // Get current particle id (ipart), track position (pos)  and momentum (mom) 
844   gMC->TrackPosition(pos);
845   gMC->TrackMomentum(mom);
846
847   ipart  = gMC->TrackPid();
848
849   //
850   // momentum loss and steplength in last step
851   destep = gMC->Edep();
852   step   = gMC->TrackStep();
853   // cout<<"------------"<<step<<endl;
854   //
855   // record hits when track enters ...
856   if( gMC->IsTrackEntering()) {
857
858       gMC->SetMaxStep(fMaxStepGas);
859       Double_t tc = mom[0]*mom[0]+mom[1]*mom[1];
860       Double_t rt = TMath::Sqrt(tc);
861       Double_t pmom = TMath::Sqrt(tc+mom[2]*mom[2]);
862       Double_t tx = mom[0]/pmom;
863       Double_t ty = mom[1]/pmom;
864       Double_t tz = mom[2]/pmom;
865       Double_t s  = ((AliMUONChamber*)(*fChambers)[idvol])
866           ->ResponseModel()
867           ->Pitch()/tz;
868       theta   = Float_t(TMath::ATan2(rt,Double_t(mom[2])))*kRaddeg;
869       phi     = Float_t(TMath::ATan2(Double_t(mom[1]),Double_t(mom[0])))*kRaddeg;
870       hits[0] = Float_t(ipart);         // Geant3 particle type
871       hits[1] = pos[0]+s*tx;            // X-position for hit
872       hits[2] = pos[1]+s*ty;            // Y-position for hit
873       hits[3] = pos[2]+s*tz;            // Z-position for hit
874       hits[4] = theta;                  // theta angle of incidence
875       hits[5] = phi;                    // phi angle of incidence 
876       hits[8] = 0;//PadHits does not exist anymore  (Float_t) fNPadHits;    // first padhit
877       hits[9] = -1;                     // last pad hit
878       hits[10] = mom[3];                // hit momentum P
879       hits[11] = mom[0];                // Px
880       hits[12] = mom[1];                // Py
881       hits[13] = mom[2];                // Pz
882       tof=gMC->TrackTime();
883       hits[14] = tof;                   // Time of flight
884       tlength  = 0;
885       eloss    = 0;
886       eloss2   = 0;
887       sstep=0;
888       xhit     = pos[0];
889       yhit     = pos[1];      
890       zhit     = pos[2];      
891       Chamber(idvol).ChargeCorrelationInit();
892       // Only if not trigger chamber
893
894 //       printf("---------------------------\n");
895 //       printf(">>>> Y =  %f \n",hits[2]);
896 //       printf("---------------------------\n");
897     
898       
899
900      //  if(idvol < AliMUONConstants::NTrackingCh()) {
901 //        //
902 //        //  Initialize hit position (cursor) in the segmentation model 
903 //        ((AliMUONChamber*) (*fChambers)[idvol])
904 //            ->SigGenInit(pos[0], pos[1], pos[2]);
905 //       } else {
906 //        //geant3->Gpcxyz();
907 //        //printf("In the Trigger Chamber #%d\n",idvol-9);
908 //       }
909   }
910   eloss2+=destep;
911   sstep+=step;
912
913   // cout<<sstep<<endl;
914
915   // 
916   // Calculate the charge induced on a pad (disintegration) in case 
917   //
918   // Mip left chamber ...
919   if( gMC->IsTrackExiting() || gMC->IsTrackStop() || gMC->IsTrackDisappeared()){
920       gMC->SetMaxStep(kBig);
921       eloss   += destep;
922       tlength += step;
923       
924       Float_t x0,y0,z0;
925       Float_t localPos[3];
926       Float_t globalPos[3] = {pos[0], pos[1], pos[2]};
927       gMC->Gmtod(globalPos,localPos,1); 
928
929       if(idvol < AliMUONConstants::NTrackingCh()) {
930 // tracking chambers
931           x0 = 0.5*(xhit+pos[0]);
932           y0 = 0.5*(yhit+pos[1]);
933           z0 = 0.5*(zhit+pos[2]);
934       } else {
935 // trigger chambers
936           x0 = xhit;
937           y0 = yhit;
938           z0 = 0.;
939       }
940       
941
942       //      if (eloss >0)  MakePadHits(x0,y0,z0,eloss,tof,idvol);
943       
944           
945       hits[6] = tlength;   // track length
946       hits[7] = eloss2;    // de/dx energy loss
947
948
949       //      if (fNPadHits > (Int_t)hits[8]) {
950       //          hits[8] = hits[8]+1;
951       //          hits[9] = 0: // PadHits does not exist anymore (Float_t) fNPadHits;
952       //}
953 //
954 //    new hit 
955       
956       new(lhits[fNhits++]) 
957           AliMUONHit(fIshunt, gAlice->GetMCApp()->GetCurrentTrackNumber(), vol,hits);
958       eloss = 0; 
959       //
960       // Check additional signal generation conditions 
961       // defined by the segmentation
962       // model (boundary crossing conditions)
963       // only for tracking chambers
964   } else if 
965       ((idvol < AliMUONConstants::NTrackingCh()) &&
966        ((AliMUONChamber*) (*fChambers)[idvol])->SigGenCond(pos[0], pos[1], pos[2]))
967   {
968       ((AliMUONChamber*) (*fChambers)[idvol])
969           ->SigGenInit(pos[0], pos[1], pos[2]);
970       
971       Float_t localPos[3];
972       Float_t globalPos[3] = {pos[0], pos[1], pos[2]};
973       gMC->Gmtod(globalPos,localPos,1); 
974
975       eloss    += destep;
976
977       // if (eloss > 0 && idvol < AliMUONConstants::NTrackingCh())
978       //        MakePadHits(0.5*(xhit+pos[0]),0.5*(yhit+pos[1]),pos[2],eloss,tof,idvol);
979       xhit     = pos[0];
980       yhit     = pos[1]; 
981       zhit     = pos[2];
982       eloss = 0;
983       tlength += step ;
984       //
985       // nothing special  happened, add up energy loss
986   } else {        
987       eloss   += destep;
988       tlength += step ;
989   }
990 }