GEAR  1.9.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Friends Pages
TGeoGearDistanceProperties.cc
1 #include <string>
2 #include <vector>
3 
4 #include "gear/GEAR.h"
5 #include "geartgeo/TGeoGearDistanceProperties.h"
6 #include "TVirtualGeoTrack.h"
7 #include "TGeoNode.h"
8 #include "TGeoManager.h"
9 
10 #define MINSTEP 1.e-5
11 
12 namespace gear {
13 
14  TGeoGearDistanceProperties::TGeoGearDistanceProperties(TGeoManager *geoMgr){
15  _tgeomanager=geoMgr;
16  }
17 
18 
19  void TGeoGearDistanceProperties::beamOn(const Vector3D &p0, const Vector3D &p1) const
20  {
21  //check if this point was just computetd and the values are still in memory
22  if(p0==_p0 && p1==_p1)
23  return;
24  else{
25  _p0=p0;
26  _p1=p1;
27  _volNames.clear();
28  _matNames.clear();
29  _distance.clear();
30  _intLen.clear();
31  _radLen.clear();
32  }
33 
34 
35  // printf( " ----- beamOn called : %1.8e %1.8e %1.8e %1.8e %1.8e %1.8e \n" ,
36  // p0[0], p0[1], p0[2], p1[0], p1[1], p1[2] ) ;
37 
38  double startpoint[3], endpoint[3], direction[3];
39  double L=0;
40  for(unsigned int i=0; i<3; i++) {
41  startpoint[i] = p0[i];
42  endpoint[i] = p1[i];
43  direction[i] = endpoint[i] - startpoint[i];
44  L+=direction[i]*direction[i];
45  }
46  double totDist = sqrt( L ) ;
47 
48  //normalize direction
49  for(unsigned int i=0; i<3; i++)
50  direction[i]=direction[i]/sqrt(L);
51 
52  _tgeomanager->AddTrack(0,12);
53  TGeoNode *node1 = _tgeomanager->InitTrack(startpoint, direction);
54  //check if there is a node at startpoint
55  if(!node1)
56  throw OutsideGeometryException("No geometry node found at given location. Either there is no node placed here or position is outside of top volume.");
57 
58  while (!_tgeomanager->IsOutside())
59  {
60  TGeoNode *node2;
61  TVirtualGeoTrack *track;
62  node2 = _tgeomanager->FindNextBoundaryAndStep(500, 1) ;
63 
64  if(!node2 || _tgeomanager->IsOutside())
65  break;
66 
67  const double *position =(double*) _tgeomanager->GetCurrentPoint();
68  const double *previouspos =(double*) _tgeomanager->GetLastPoint();
69  double length=_tgeomanager->GetStep();
70  track = _tgeomanager->GetLastTrack();
71  //protection against infinitive loop in root which should not happen, but well it does...
72  //work around until solution within root can be found when the step gets very small e.g. 1e-10
73  //and the next boundary is never reached
74 
75  if(length<MINSTEP)
76  {
77  _tgeomanager->SetCurrentPoint(position[0]+MINSTEP*direction[0], position[1]+MINSTEP*direction[1], position[2]+MINSTEP*direction[2]);
78  length=_tgeomanager->GetStep();
79  node2 = _tgeomanager->FindNextBoundaryAndStep(500, 1) ;
80 
81  //fg: need to update positions as well !?
82  position = (const double*) _tgeomanager->GetCurrentPoint();
83  previouspos = (const double*) _tgeomanager->GetLastPoint();
84 
85  }
86 
87  // printf( " -- step length : %1.8e %1.8e %1.8e %1.8e %1.8e %1.8e %1.8e - %s \n" , length ,
88  // position[0], position[1], position[2], previouspos[0], previouspos[1], previouspos[2] , node1->GetMedium()->GetMaterial()->GetName() ) ;
89 
90  Vector3D posV( position ) ;
91  double currDistance = ( posV - p0 ).r() ;
92 
93  // //if the next boundary is further than end point
94  // if(fabs(position[0])>fabs(endpoint[0]) || fabs(position[1])>fabs(endpoint[1])
95  // || fabs(position[2])>fabs(endpoint[2]))
96 
97  //if we travelled too far:
98  if( currDistance > totDist )
99  {
100  length=sqrt(pow(endpoint[0]-previouspos[0],2)
101  +pow(endpoint[1]-previouspos[1],2)
102  +pow(endpoint[2]-previouspos[2],2));
103 
104  track->AddPoint(endpoint[0], endpoint[1], endpoint[2], 0.);
105  _distance.push_back(length);
106  std::string svoln(node1->GetName());
107  std::string svolm(node1->GetMedium()->GetMaterial()->GetName());
108  _volNames.push_back(svoln);
109  _matNames.push_back(svolm);
110  _intLen.push_back(node1->GetMedium()->GetMaterial()->GetIntLen());
111  _radLen.push_back(node1->GetMedium()->GetMaterial()->GetRadLen());
112  break;
113  }
114 
115  track->AddPoint(position[0], position[1], position[2], 0.);
116  _distance.push_back(length);
117  std::string svoln(node1->GetName());
118  std::string svolm(node1->GetMedium()->GetMaterial()->GetName());
119  _volNames.push_back(svoln);
120  _matNames.push_back(svolm);
121  _intLen.push_back(node1->GetMedium()->GetMaterial()->GetIntLen());
122  _radLen.push_back(node1->GetMedium()->GetMaterial()->GetRadLen());
123 
124  node1=node2;
125  }
126  _tgeomanager->ClearTracks();
127  _tgeomanager->CleanGarbage();
128  }
129 
132  const std::vector<std::string>& TGeoGearDistanceProperties::getMaterialNames(const Vector3D & p0, const Vector3D & p1) const {
133 
134  //check if itp0 and p1 are the same point, if so don't do anything, no material in between
135  if(p0==p1)
136  _matNames.clear();
137  else
138  beamOn(p0, p1);
139 
140  return _matNames;
141  }
142 
145  const std::vector<std::string> TGeoGearDistanceProperties::getVolumeNames(const Vector3D & p0, const Vector3D & p1) const {
146 
147  //check if itp0 and p1 are the same point, if so don't do anything, no material in between
148  if(p0==p1)
149  _volNames.clear();
150  else
151  beamOn(p0, p1);
152 
153  return _volNames;
154  }
155 
159  const std::vector<double>& TGeoGearDistanceProperties::getMaterialThicknesses(const Vector3D & p0, const Vector3D & p1) const {
160 
161  //check if itp0 and p1 are the same point, if so don't do anything, no material in between
162  if(p0==p1)
163  _distance.clear();
164  else
165  beamOn(p0, p1);
166 
167  return _distance;
168  }
169 
172  double TGeoGearDistanceProperties::getNRadlen(const Vector3D & p0, const Vector3D & p1) const {
173 
174  //check if itp0 and p1 are the same point, if so don't do anything, no material in between
175  if(p0==p1)
176  return 0;
177 
178  beamOn(p0, p1);
179 
180  double nRadLen=0;
181  for(unsigned int i=0; i < _radLen.size(); i++){
182  if(_radLen[i]!=0)
183  nRadLen += _distance[i]/_radLen[i];
184  }
185  return nRadLen;
186  }
187 
188 
191  double TGeoGearDistanceProperties::getNIntlen(const Vector3D & p0, const Vector3D & p1) const {
192 
193  if(p0==p1)
194  return 0;
195 
196  beamOn(p0, p1);
197 
198  double nInterLen = 0;
199  for(unsigned int i=0; i<_intLen.size(); i++)
200  {
201  if(_intLen[i]!=0)
202  nInterLen += _distance[i]/_intLen[i];
203  }
204  return nInterLen;
205  }
206 
207 
210  double TGeoGearDistanceProperties::getBdL(const Vector3D & /*p0*/, const Vector3D & /*p1*/) const {
211 
212  throw NotImplementedException("getBdl not implemented yet in TGeoGearPointProperties");
213  return 0;
214  }
215 
216 
217 
220  double TGeoGearDistanceProperties::getEdL(const Vector3D & /*p0*/, const Vector3D & /*p1*/) const {
221 
222  throw NotImplementedException("getEdl not implemented yet in TGeoGearPointProperties");
223  return 0;
224  }
225 
226 
227 } // namespace gear
virtual double getEdL(const Vector3D &p0, const Vector3D &p1) const
The integrated electric field along the distance between [p0,p1] in mVolt.
virtual double getNRadlen(const Vector3D &p0, const Vector3D &p1) const
The number of radiation lengths along the distance between [p0,p1] .
virtual double getNIntlen(const Vector3D &p0, const Vector3D &p1) const
The number of interaction lengths along the distance between [p0,p1] .
virtual const std::vector< std::string > & getMaterialNames(const Vector3D &p0, const Vector3D &p1) const
List of matrial names along the distance between [p0,p1]- WARNING: this method returns a reference to...
virtual const std::vector< std::string > getVolumeNames(const Vector3D &p0, const Vector3D &p1) const
List of traversed volumes by name.
NotImplementedException used for features that are not implemented.
Definition: GEAR.h:81
Simple three dimensional vector providing the components for cartesian, cylindrical and spherical coo...
Definition: Vector3D.h:18
virtual const std::vector< double > & getMaterialThicknesses(const Vector3D &p0, const Vector3D &p1) const
List of matrial thicknesses in mm along the distance between [p0,p1] - runs parallel to the array ret...
virtual double getBdL(const Vector3D &p0, const Vector3D &p1) const
The integrated magnetic field along the distance between [p0,p1] in Tesla*mm.