GEAR  1.9.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Friends Pages
MaterialMap.cc
1 #include <string>
2 #include <vector>
3 #include <math.h>
4 
5 #include "gear/GEAR.h"
6 #include "gear/geartgeo/MaterialMap.h"
7 #include "gear/GearDistanceProperties.h"
8 
9 namespace gear {
10 
11  MaterialMap::MaterialMap(GearMgr *gearMgr,double xmin, double xmax, int nxsteps,
12  double ymin, double ymax, int nysteps,
13  double zmin, double zmax, int nzsteps, int coord)
14  {
15  //check the conformity of the input with the requested coordinate system
16  if(xmax<xmin || ymax<ymin || zmax<zmin)
17  throw gear::Exception("MaterialMap constructor: Grid range error (max value is smaller than min)!");
18  if(nxsteps<0 || nysteps<0 || nzsteps<0)
19  throw gear::Exception("MaterialMap constructor: Grid step error (number of steps must be positive number)!");
20  switch (coord)
21  {
23  {}
24  break;
26  {
27  //r>0,0<phi<2Pi
28  if(xmin<0 || xmax<0)
29  throw gear::Exception("MaterialMap constructor: Grid range error (r>0 for cylindrical coordinates)!");
30  if(ymin<0 || ymin>2*M_PI || ymax<0 || ymax>2*M_PI)
31  throw gear::Exception("MaterialMap constructor: Grid range error (0<phi<2Pi for cylindrical coordinates)!");
32  }
33  break;
35  {
36  //r>0,0<theta<Pi ,0<phi<2Pi
37  if(xmin<0 || xmax<0)
38  throw gear::Exception("MaterialMap constructor: Grid range error (r>0 for shperical coordinates)!");
39  if(ymin<0 || ymin>M_PI || ymax<0 || ymax>M_PI)
40  throw gear::Exception("MaterialMap constructor: Grid range error (0<theta<Pi for spherical coordinates)!");
41  if(zmin<0 || zmin>2*M_PI || zmax<0 || zmax>2*M_PI)
42  throw gear::Exception("MaterialMap constructor: Grid range error (0<phi<2Pi for spherical coordinates)!");
43  }
44  break;
45  default:
46  throw gear::Exception("MaterialMap constructor: unkown coordinate type");
47  }
48 
49 
50  const GearDistanceProperties &gDP=gearMgr->getDistanceProperties();
51  _xmin =xmin ;
52  _xmax =xmax ;
53  _nxsteps=nxsteps ;
54  _ymin =ymin ;
55  _ymax =ymax ;
56  _nysteps=nysteps ;
57  _zmin =zmin ;
58  _zmax =zmax ;
59  _nzsteps=nzsteps ;
60 
61  //setting the sizes of the matrix
62  _myMap.resize(nxsteps+1);
63  for(int s=0;s<=nxsteps;++s)
64  {
65  _myMap[s].resize(nysteps+1);
66  for(int s2=0;s2<=nysteps;++s2)
67  _myMap[s][s2].resize(nzsteps+1);
68  }
69 
70  if(nxsteps==0)
71  _xstep=1;
72  else
73  _xstep=(xmax-xmin)/nxsteps;
74  if(nysteps==0)
75  _ystep=1;
76  else
77  _ystep=(ymax-ymin)/nysteps;
78  if(nzsteps==0)
79  _zstep=1;
80  else
81  _zstep=(zmax-zmin)/nzsteps;
82 
83  Vector3D initial,final;
84  //always vertex as reference point
85  initial[0]=0;
86  initial[1]=0;
87  initial[2]=0;
88 
89  for(double x= xmin;x<=xmax;x+=_xstep)//or r
90  {
91  for(double y= ymin;y<=ymax;y+=_ystep)// or phi or theta
92  {
93  for(double z= zmin;z<=zmax;z+=_zstep) //or theta
94  {
95  //GearDistanceProperties need coordinates in cartesian x,y,z
96  switch (coord)
97  {
99  {
100  final[0]=x;
101  final[1]=y;
102  final[2]=z;
103  }
104  break;
106  {
107  final[0]=x*cos(y);//r*cos(phi)
108  final[1]=x*sin(y);//r*sin(phi)
109  final[2]=z;
110  }
111  break;
113  {
114  final[0]=x*sin(y)*cos(z);//r*sin(theta)*cos(phi)
115  final[1]=x*sin(y)*sin(z);//r*sin(theta)*cos(phi)
116  final[2]=x*cos(y);//r*cos(theta)
117  }
118  break;
119  default:
120  throw gear::Exception("MaterialMap constructor: unkown coordinate type");
121  }
122  if(final==initial)//no need to go to geometry
123  {
124  _values.first=0;
125  _values.second=0;
126  }
127  else
128  {
129  _values.first=gDP.getNRadlen( initial, final);
130  _values.second=gDP.getNIntlen( initial, final);
131  }
132  std::vector<int> pos;
133  calculateGridIndex(pos,x,y,z);
134  _myMap[pos[0]][pos[1]][pos[2]]=_values;
135  }//z
136  }//y
137  }//x
138  }
139 
140  double MaterialMap::getInteractionLength(double x, double y, double z)const
141  {
142  //check whether point is in grid using calculateGridIndex
143  std::vector<int> pos;
144  calculateGridIndex(pos,x,y,z);
145  std::pair<double,double> result;
146  interpolateOnGrid(result,x,y,z);
147  return result.second;
148  }
149 
150  double MaterialMap::getRadiationLength(double x, double y, double z)const
151  {
152  //check whether point is in grid using calculateGridIndex
153  std::vector<int> pos;
154  calculateGridIndex(pos,x,y,z);
155  std::pair<double,double> result;
156  interpolateOnGrid(result,x,y,z);
157  return result.first;
158  }
159 
160  void MaterialMap::calculateGridIndex(std::vector<int> & gpos,double x, double y, double z) const
161  {
162  //check if in map
163  if(x+1e-5<_xmin || x-1e-5>_xmax || y+1e-5<_ymin || y-1e-5>_ymax || z+1e-5<_zmin || z-1e-5>_zmax)
164  throw Exception("Coordinate not found in MaterialMap!");
165  // convert input to grid spacing
166  gpos.resize(3);
167  gpos[0]=int((x-_xmin)/_xstep+0.5);
168  gpos[1]=int((y-_ymin)/_ystep+0.5);
169  gpos[2]=int((z-_zmin)/_zstep+0.5);
170  }
171 
172  void MaterialMap::interpolateOnGrid(std::pair<double,double> &result, double x, double y, double z) const
173  {
174  //find eight neighbouring grid points
175  double px[2],py[2],pz[2];
176  px[0]=x-fmod(x-_xmin,_xstep);
177  px[1]=px[0]+_xstep;
178  py[0]=y-fmod(y-_ymin,_ystep);
179  py[1]=py[0]+_ystep;
180  pz[0]=z-fmod(z-_zmin,_zstep);
181  pz[1]=pz[0]+_zstep;
182  //check wether they are within grid
183  int xcount=0,ycount=0,zcount=0;
184  if(_xmin<=px[0] && px[0]<=_xmax)
185  xcount++;
186  if(_xmin<=px[1] && px[1]<=_xmax)
187  xcount++;
188  if(_ymin<=py[0] && py[0]<=_ymax)
189  ycount++;
190  if(_ymin<=py[1] && py[1]<=_ymax)
191  ycount++;
192  if(_zmin<=pz[0] && pz[0]<=_zmax)
193  zcount++;
194  if(_zmin<=pz[1] && pz[1]<=_zmax)
195  zcount++;
196  //calculate distances from x,y,z to each neighbour
197  int counter=0;
198  double sumIntL=0,sumRadL=0,sumWeight=0;
199  bool isOnGrid=false;
200  for(int ix=0;ix<xcount;ix++)
201  {
202  for(int iy=0;iy<ycount;iy++)
203  {
204  for(int iz=0;iz<zcount;iz++)
205  {
206  double d=sqrt((x-px[ix])*(x-px[ix])+(y-py[iy])*(y-py[iy])+(z-pz[iz])*(z-pz[iz]));
207  std::vector<int> gpos;
208  calculateGridIndex(gpos,px[ix],py[iy],pz[iz]);
209  std::pair<double,double> vals=_myMap[gpos[0]][gpos[1]][gpos[2]];
210  counter++;
211  if(fabs(d)<1e-5)//point in querry is a grid point
212  {
213  sumRadL=vals.first;
214  sumIntL=vals.second;
215  sumWeight=1;
216  isOnGrid=true;
217  break;
218  }
219  else if(!isOnGrid)
220  {
221  sumRadL+=vals.first/d;
222  sumIntL+=vals.second/d;
223  sumWeight+=1./d;
224  }
225  }
226  if(isOnGrid)
227  break;
228  }
229  if(isOnGrid)
230  break;
231  }
232  result.first=sumRadL/sumWeight;
233  result.second=sumIntL/sumWeight;
234  }
235 
236 } // namespace gear
static const int CYLINDRICAL
coord=1 : CYLINDRICAL (r,phi,z)
Definition: MaterialMap.h:44
double getRadiationLength(double x, double y, double z) const
Returns the radiation length from the vertex at (0,0,0) to (x,y,z) using a distance wheighted interpo...
Definition: MaterialMap.cc:150
Abstract interface for a class that returns the (material) properties along a given distance between ...
virtual double getNIntlen(const Vector3D &p0, const Vector3D &p1) const =0
The number of interaction lengths along the distance between [p0,p1] .
Base exception class for GEAR - all other exceptions extend this.
Definition: GEAR.h:41
virtual const GearDistanceProperties & getDistanceProperties() const =0
Get the distance properties object.
virtual double getNRadlen(const Vector3D &p0, const Vector3D &p1) const =0
The number of radiation lengths along the distance between [p0,p1] .
Simple three dimensional vector providing the components for cartesian, cylindrical and spherical coo...
Definition: Vector3D.h:18
static const int CARTESIAN
coord=0 : CARTESIAN (x,y,z)
Definition: MaterialMap.h:42
static const int SPHERICAL
coord=2 : SPERICAL (r,theta,phi)
Definition: MaterialMap.h:46
Abstract interface for a manager class that returns the Gear classes for the relevant subdetectors...
Definition: GearMgr.h:36
MaterialMap(GearMgr *gearMgr, double xmin, double xmax, int nxsteps, double ymin, double ymax, int nysteps, double zmin, double zmax, int nzsteps, int coord)
Should be called through the MaterialMapFactory! Creating a material map in memory.
Definition: MaterialMap.cc:11
double getInteractionLength(double x, double y, double z) const
Returns the interaction length from the vertex at (0,0,0) to (x,y,z) using a distance wheighted inter...
Definition: MaterialMap.cc:140