Corrections to obey our coding conventions
[u/mrichter/AliRoot.git] / STEER / AliLegoGenerator.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 //        Generic Lego generator code
20 //    Uses geantino rays to check the material distributions and detector's
21 //    geometry
22 //    Author: A.Morsch
23 //------------------------------------------------------------------------
24
25 #include "AliLegoGenerator.h"
26 #include "AliRun.h"
27 #include "AliMC.h"
28
29 ClassImp(AliLegoGenerator)
30
31 //_______________________________________________________________________
32 AliLegoGenerator::AliLegoGenerator():
33   fRadMin(0),
34   fRadMax(0),
35   fZMax(0),
36   fNCoor1(0),
37   fNCoor2(0),
38   fCoor1Min(0),
39   fCoor1Max(0),
40   fCoor2Min(0),
41   fCoor2Max(0),
42   fCoor1Bin(-1),
43   fCoor2Bin(-1),
44   fCurCoor1(0),
45   fCurCoor2(0)
46 {
47   //
48   // Default Constructor
49   //
50   SetName("Lego");
51 }
52
53 //_______________________________________________________________________
54 AliLegoGenerator::AliLegoGenerator(Int_t nc1, Float_t c1min,
55                                    Float_t c1max, Int_t nc2, 
56                                    Float_t c2min, Float_t c2max,
57                                    Float_t rmin, Float_t rmax, Float_t zmax):
58   AliGenerator(0), 
59   fRadMin(rmin),
60   fRadMax(rmax),
61   fZMax(zmax),
62   fNCoor1(nc1),
63   fNCoor2(nc2),
64   fCoor1Min(0),
65   fCoor1Max(0),
66   fCoor2Min(0),
67   fCoor2Max(0),
68   fCoor1Bin(nc1),
69   fCoor2Bin(-1),
70   fCurCoor1(0),
71   fCurCoor2(0)
72 {
73   //
74   // Standard generator for Lego rays
75   //
76   SetName("Lego");
77   SetCoor1Range(nc1, c1min, c1max);
78   SetCoor2Range(nc2, c2min, c2max);
79 }
80
81 //_______________________________________________________________________
82 void AliLegoGenerator::Generate()
83 {
84   // Create a geantino with kinematics corresponding to the current bins
85   // Here: Coor1 =  theta 
86   //       Coor2 =  phi.
87   
88   //
89   // Rootinos are 0
90    const Int_t kMpart = 0;
91    Float_t orig[3], pmom[3];
92    Float_t t, cost, sint, cosp, sinp;
93    if (fCoor1Bin==-1) fCoor1Bin=fNCoor1;
94    // Prepare for next step
95    if(fCoor1Bin>=fNCoor1-1)
96      if(fCoor2Bin>=fNCoor2-1) {
97        Warning("Generate","End of Lego Generation");
98        return;
99      } else { 
100        fCoor2Bin++;
101        printf("Generating rays in phi bin:%d\n",fCoor2Bin);
102        fCoor1Bin=0;
103      } else fCoor1Bin++;
104
105    fCurCoor1 = (fCoor1Min+(fCoor1Bin+0.5)*(fCoor1Max-fCoor1Min)/fNCoor1);
106    fCurCoor2 = (fCoor2Min+(fCoor2Bin+0.5)*(fCoor2Max-fCoor2Min)/fNCoor2);
107    cost      = TMath::Cos(fCurCoor1 * TMath::Pi()/180.);
108    sint      = TMath::Sin(fCurCoor1 * TMath::Pi()/180.);
109    cosp      = TMath::Cos(fCurCoor2 * TMath::Pi()/180.);
110    sinp      = TMath::Sin(fCurCoor2 * TMath::Pi()/180.);
111    
112    pmom[0] = cosp*sint;
113    pmom[1] = sinp*sint;
114    pmom[2] = cost;
115    
116    // --- Where to start
117    orig[0] = orig[1] = orig[2] = 0;
118    Float_t dalicz = 3000;
119    if (fRadMin > 0) {
120        t = PropagateCylinder(orig,pmom,fRadMin,dalicz);
121        orig[0] = pmom[0]*t;
122        orig[1] = pmom[1]*t;
123        orig[2] = pmom[2]*t;
124        if (TMath::Abs(orig[2]) > fZMax) return;
125    }
126    
127    Float_t polar[3]={0.,0.,0.};
128    Int_t ntr;
129    gAlice->GetMCApp()->PushTrack(1, -1, kMpart, pmom, orig, polar, 0, kPPrimary, ntr);
130    
131 }
132
133 //_______________________________________________________________________
134 Float_t AliLegoGenerator::PropagateCylinder(Float_t *x, Float_t *v, Float_t r, 
135                                             Float_t z)
136 {
137   //
138   // Propagate to cylinder from inside
139   //
140    Double_t hnorm, sz, t, t1, t2, t3, sr;
141    Double_t d[3];
142    const Float_t kSmall  = 1e-8;
143    const Float_t kSmall2 = kSmall*kSmall;
144
145 // ---> Find intesection with Z planes
146    d[0]  = v[0];
147    d[1]  = v[1];
148    d[2]  = v[2];
149    hnorm = TMath::Sqrt(1/(d[0]*d[0]+d[1]*d[1]+d[2]*d[2]));
150    d[0] *= hnorm;
151    d[1] *= hnorm;
152    d[2] *= hnorm;
153    if (d[2] > kSmall)       sz = (z-x[2])/d[2];
154    else if (d[2] < -kSmall) sz = -(z+x[2])/d[2];
155    else                     sz = 1.e10;  // ---> Direction parallel to X-Y, no intersection
156
157 // ---> Intersection with cylinders
158 //      Intersection point (x,y,z)
159 //      (x,y,z) is on track :    x=X(1)+t*D(1)
160 //                               y=X(2)+t*D(2)
161 //                               z=X(3)+t*D(3)
162 //      (x,y,z) is on cylinder : x**2 + y**2 = R**2
163 //
164 //      (D(1)**2+D(2)**2)*t**2
165 //      +2.*(X(1)*D(1)+X(2)*D(2))*t
166 //      +X(1)**2+X(2)**2-R**2=0
167 // ---> Solve second degree equation
168    t1 = d[0]*d[0] + d[1]*d[1];
169    if (t1 <= kSmall2) {
170       t = sz;  // ---> Track parallel to the z-axis, take distance to planes
171    } else {
172       t2 = x[0]*d[0] + x[1]*d[1];
173       t3 = x[0]*x[0] + x[1]*x[1];
174       // ---> It should be positive, but there may be numerical problems
175       sr = (-t2 +TMath::Sqrt(TMath::Max(t2*t2-(t3-r*r)*t1,0.)))/t1;
176       // ---> Find minimum distance between planes and cylinder
177       t  = TMath::Min(sz,sr);
178    }
179    return t;
180 }
181
182