CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
NavPropagator.cc
Go to the documentation of this file.
5 // magVolume6Faces needed to get access to volume name and material:
7 //
11 
12 using namespace std;
13 
16  Propagator(dir)
17 {
18  theField = dynamic_cast<const VolumeBasedMagneticField*>(field);
19  //FIXME: iron volumes are hard-coded below... will change with new .xml geometry MM 28/6/07
20  int myIronVolumes[126] = {6,9,11,14,15,18,22,23,26,29,30,33,36,37,43,46,49,53,56,57,60,62,
21  63,65,71,77,105,106,107,111,112,113,114,115,116,117,118,122,123,
22  125,126,128,129,130,131,132,133,135,137,141,145,147,148,149,153,
23  154,155,156,157,158,159,160,164,165,167,168,170,171,172,173,174,
24  175,177,178,179,180,184,185,186,187,188,189,190,191,195,196,198,
25  200,204,208,210,211,212,216,217,218,219,220,221,222,223,227,228,
26  230,231,233,234,235,236,237,238,240,241,242,243,247,248,249,250,
27  251,252,253,254,258,259,261};
28  for(int i=0; i<272; i++) isIronVolume[i]=false;
29  for(int i=0; i<126 ; i++) isIronVolume[myIronVolumes[i]]=true;
30  // for(int i=1; i<272 ; i++) {
31  // if(isIronVolume[i]) std::cout << "Volume no." << i << " is made of iron " << std::endl;
32  // if(!isIronVolume[i]) std::cout << "Volume no." << i << " is made of air " << std::endl;
33  //}
34 }
35 
37  for (MagVolumeMap::iterator i = theNavVolumeMap.begin(); i != theNavVolumeMap.end(); ++i) {
38  delete i->second;
39  }
40 }
41 
43 
44 std::pair<TrajectoryStateOnSurface,double>
46  const Plane& targetPlane) const
47 {
48 
49  LogDebug("NavPropagator") << "NavPropagator::propagateWithPath(TrajectoryStateOnSurface, Plane) called with "
50  << inputState;
51 
52  VolumeCrossReturnType exitState( 0, inputState, 0.0);
53  TSOS startingState = inputState;
54  TSOS TempState = inputState;
55  const NavVolume* currentVolume = 0; // explicit initialization to get rid of compiler warning
56 
57  int count = 0;
58  int maxCount = 100;
59  while (!destinationCrossed( startingState, TempState, targetPlane)) {
60 
61  LogDebug("NavPropagator") << "NavPropagator:: at beginning of while loop at iteration " << count ;
62 
63  startingState = TempState;
64  bool isReflected = false;
65 
66  if (exitState.volume() != 0) { // next volume connected
67  currentVolume = exitState.volume();
68  }
69  else {
70  // 1 mm shifted peek is necessary only because geometry is not yet glued and exists only for z<0
71  GlobalPoint gp = startingState.globalPosition() + 0.1*startingState.globalMomentum().unit();
72 
73  if (gp.z()>0) { // Reflect in Z (as long as MagVolumes exist only for z<0
75  startingState.globalPosition().y(),
76  -startingState.globalPosition().z()),
77  GlobalVector(startingState.globalMomentum().x(),
78  startingState.globalMomentum().y(),
79  -startingState.globalMomentum().z()),
80  startingState.globalParameters().charge(), theField );
81  FreeTrajectoryState fts(gtp);
82  TempState = TSOS( fts, startingState.surface());
83  isReflected = true;
84  }
85  currentVolume = findVolume( TempState );
86  if (currentVolume == 0) {
87  std::cout << "NavPropagator: findVolume failed to find volume containing point "
88  << startingState.globalPosition() ;
89  return std::pair<TrajectoryStateOnSurface,double>(noNextVolume( startingState), 0);
90  }
91  }
92 
93  PropagatorType currentPropagator( *currentVolume);
94 
95  LogDebug("NavPropagator") << "NavPropagator: calling crossToNextVolume" ;
96  exitState = currentVolume->crossToNextVolume( TempState, currentPropagator);
97  LogDebug("NavPropagator") << "NavPropagator: crossToNextVolume returned" ;
98  LogDebug("NavPropagator") << "Volume pointer: " << exitState.volume() << " and new ";
99  LogDebug("NavPropagator") << exitState.tsos() ;
100  LogDebug("NavPropagator") << "So that was a path length " << exitState.path() ;
101 
102 
103  if ( !exitState.tsos().isValid()) {
104  // return propagateInVolume( currentVolume, startingState, targetPlane);
105  std::cout << "NavPropagator: failed to crossToNextVolume in volume at pos "
106  << currentVolume->position();
107  break;
108  }
109  else {
110  LogDebug("NavPropagator") << "NavPropagator: crossToNextVolume reached volume ";
111  if (exitState.volume() != 0) {
112  LogDebug("NavPropagator") << " at pos "
113  << exitState.volume()->position()
114  << "with state " << exitState.tsos() ;
115  }
116  else LogDebug("NavPropagator") << " unknown";
117  }
118 
119  TempState = exitState.tsos();
120 
121  if (fabs(exitState.path())<0.01) {
122  LogDebug("NavPropagator") << "failed to move at all!! at position: " << exitState.tsos().globalPosition();
123 
124  GlobalTrajectoryParameters gtp( exitState.tsos().globalPosition()+0.01*exitState.tsos().globalMomentum().unit(),
125  exitState.tsos().globalMomentum(),
126  exitState.tsos().globalParameters().charge(), theField );
127 
128  FreeTrajectoryState fts(gtp);
129  TSOS ShiftedState( fts, exitState.tsos().surface());
130  // exitState.tsos() = ShiftedState;
131  TempState = ShiftedState;
132 
133  LogDebug("NavPropagator") << "Shifted to new position " << TempState.globalPosition();
134 
135  }
136 
137 
138  // std::cout << "Just moved " << exitState.path() << " cm through " << ( currentVolume->isIron()? "IRON":"AIR" );
139  // std::cout << " at radius: " << TempState.globalPosition().perp() << std::endl;
140  // reflect back to normal universe if necessary:
141  if (isReflected) { // reflect back... nobody should know we secretely z-reflected the tsos
142 
143 
145  TempState.globalPosition().y(),
146  -TempState.globalPosition().z()),
147  GlobalVector(TempState.globalMomentum().x(),
148  TempState.globalMomentum().y(),
149  -TempState.globalMomentum().z()),
150  TempState.globalParameters().charge(), theField );
151 
152  FreeTrajectoryState fts(gtp);
153  TSOS ReflectedState( fts, TempState.surface());
154  TempState = ReflectedState;
155  isReflected = false;
156  }
157 
158  ++count;
159  if (count > maxCount) {
160  LogDebug("NavPropagator") << "Ohoh, NavPropagator in infinite loop, count = " << count;
161  return TsosWP();
162  }
163 
164  }
165 
166 
167 
168  // Arriving here only if destinationCrossed or if crossToNextVolume returned invalid state,
169  // in which case we should check if the targetPlane is not crossed in the current volume
170 
171  return propagateInVolume( currentVolume, startingState, targetPlane);
172 
173 }
174 
175 
177 {
178  LogDebug("NavPropagator") << "NavPropagator: calling theField->findVolume ";
179 
180  GlobalPoint gp = inputState.globalPosition() + 0.1*inputState.globalMomentum().unit();
181  // Next protection only needed when 1 mm linear move crosses the z==0 plane:
182  GlobalPoint gpSym(gp.x(), gp.y(), (gp.z()<0? gp.z() : -gp.z()));
183 
184  const MagVolume* magVolume = theField->findVolume( gpSym);
185 
186  LogDebug("NavPropagator") << "NavPropagator: got MagVolume* " << magVolume
187  << " when searching with pos " << gpSym ;
188 
189 
190  if (!magVolume) {
191  cout << "Got invalid volume pointer " << magVolume << " at position " << gpSym;
192  return 0;
193  }
194  return navVolume(magVolume);
195 }
196 
197 
198 const NavVolume* NavPropagator::navVolume( const MagVolume* magVolume) const
199 {
200  NavVolume* result;
201  MagVolumeMap::iterator i = theNavVolumeMap.find( magVolume);
202  if (i == theNavVolumeMap.end()) {
203  // Create a NavVolume from a MagVolume if the NavVolume doesn't exist yet
204  // FIXME: hardcoded iron/air classification should be made into something more general
205  // will break with new magnetic field volume .xml file MM 28/6/07
206  const MagVolume6Faces* pVol6 = dynamic_cast<const MagVolume6Faces*> ( magVolume );
207  int n=0;
208  bool isIron=false;
209  if(pVol6) {
210  std::stringstream ss(pVol6->name.substr(5));
211  ss >> n;
212  // std::cout << " Found volume with number " << n << std::endl;
213  } else {
214  std::cout << "Error (NavVolume6Faces) failed to get MagVolume6Faces pointer" << std::endl;
215  }
216  if(n<1 || n>271) {
217  std::cout << "Error (NavVolume6Faces) unexpected Volume number!" << std::endl;
218  } else {
219  isIron = isIronVolume[n];
220  }
221 
222  result= new NavVolume6Faces( *magVolume, isIron);
223  theNavVolumeMap[magVolume] = result;
224  }
225  else result = i->second;
226  return result;
227 }
228 
229 std::pair<TrajectoryStateOnSurface,double>
231  const TrajectoryStateOnSurface& startingState,
232  const Plane& targetPlane) const
233 {
234  PropagatorType prop( *currentVolume);
235 
236  // OK, fix is rather ugly for now: need to reflect z>0 states to z<0 MM 25/6/07
237  bool isReflected = false;
238  TSOS okState = startingState;
239  PlaneBuilder::ReturnType ReflectedPlane;
240  Plane okPlane = targetPlane;
241 
242  if (startingState.globalPosition().z()>0 ||
243  (fabs(startingState.globalPosition().z())<1.e-4 && startingState.globalMomentum().z()>1.e-4)) {
245  startingState.globalPosition().y(),
246  -startingState.globalPosition().z()),
247  GlobalVector(startingState.globalMomentum().x(),
248  startingState.globalMomentum().y(),
249  -startingState.globalMomentum().z()),
250  startingState.globalParameters().charge(), prop.magneticField() );
251 
252  FreeTrajectoryState fts(gtp);
253  TSOS ReflectedState( fts, startingState.surface());
254  okState = ReflectedState;
255 
256  GlobalVector TempVec = targetPlane.normalVector();
257  GlobalVector ReflectedVector = GlobalVector ( TempVec.x(), TempVec.y(), -TempVec.z());
258  GlobalVector zAxis = ReflectedVector.unit();
259  GlobalVector yAxis( zAxis.y(), -zAxis.x(), 0);
260  GlobalVector xAxis = yAxis.cross( zAxis);
261  Surface::RotationType rot = Surface::RotationType( xAxis, yAxis, zAxis);
262 
263  GlobalPoint gp = targetPlane.position();
264  GlobalPoint gpSym(gp.x(), gp.y(), -gp.z());
265  PlaneBuilder pb;
266  ReflectedPlane = pb.plane( gpSym, rot);
267 
268  okPlane = *ReflectedPlane;
269  isReflected = true;
270  }
271 
272  // Done Reflecting
273 
274 
275  TsosWP res = prop.propagateWithPath( okState, okPlane);
276 
277  // Now reflect back the result if necessary...
278  if (isReflected && res.first.isValid()) { // reflect back... nobody should know we secretely z-reflected the tsos
279 
280 
281  TSOS TempState = res.first;
283  TempState.globalPosition().y(),
284  -TempState.globalPosition().z()),
285  GlobalVector(TempState.globalMomentum().x(),
286  TempState.globalMomentum().y(),
287  -TempState.globalMomentum().z()),
288  TempState.globalParameters().charge(), prop.magneticField() );
289 
290  FreeTrajectoryState fts(gtp);
291  TSOS ReflectedState( fts, TempState.surface());
292  res.first = ReflectedState;
293  isReflected = false;
294  }
295  // Done Reflecting back !
296 
297  if (res.first.isValid()) {
298 
299  GlobalPoint gp = res.first.globalPosition();
300  GlobalPoint gpSym(gp.x(), gp.y(), (gp.z()<0? gp.z() : -gp.z()));
301 
302  if (currentVolume->inside( gpSym )) {
303  return res;
304  }
305  // sometimes fails when propagation on plane and surface are less than 0.1 mm apart...
306  }
307 
308  // return TsosWP( TrajectoryStateOnSurface(), 0); // Gives 'double free' errors... return res even when Outside volume...
309  return res;
310 
311 }
312 
313 bool NavPropagator::destinationCrossed( const TSOS& startState,
314  const TSOS& endState, const Plane& plane) const
315 {
316  bool res = ( plane.side( startState.globalPosition(), 1.e-6) !=
317  plane.side( endState.globalPosition(), 1.e-6));
318  /*
319  LogDebug("NavPropagator") << "NavPropagator::destinationCrossed called with startState "
320  << startState << std::endl
321  << " endState " << endState
322  << std::endl
323  << " plane at " << plane.position()
324  << std::endl;
325 
326  LogDebug("NavPropagator") << "plane.side( startState) " << plane.side( startState.globalPosition(), 1.e-6);
327  LogDebug("NavPropagator") << "plane.side( endState) " << plane.side( endState.globalPosition(), 1.e-6);
328  */
329 
330  return res;
331 }
332 
335 {
336  LogDebug("NavPropagator") << std::endl
337  << "Propagation reached end of volume geometry without crossing target surface"
338  << std::endl
339  << "starting state of last propagation " << startingState;
340 
341  return TrajectoryStateOnSurface();
342 }
343 
344 
345 
346 std::pair<TrajectoryStateOnSurface,double>
348  const Cylinder& cylinder) const
349 {
350  LogDebug("NavPropagator") << "propagateWithPath(const FreeTrajectoryState&) not implemented yet in NavPropagator" ;
351  return TsosWP();
352 }
353 std::pair<TrajectoryStateOnSurface,double>
355  const Plane& cylinder) const
356 {
357  LogDebug("NavPropagator") << "propagateWithPath(const FreeTrajectoryState&) not implemented yet in NavPropagator" ;
358  return TsosWP();
359 }
#define LogDebug(id)
int i
Definition: DBlmapReader.cc:9
std::pair< TrajectoryStateOnSurface, double > propagateInVolume(const NavVolume *currentVolume, const TrajectoryStateOnSurface &startingState, const Plane &targetPlane) const
const VolumeBasedMagneticField * theField
Definition: NavPropagator.h:76
MagVolumeMap theNavVolumeMap
Definition: NavPropagator.h:77
GlobalVector normalVector() const
Definition: Plane.h:47
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
TrajectoryStateOnSurface TSOS
Definition: NavPropagator.h:73
T y() const
Definition: PV3DBase.h:57
NavPropagator(const MagneticField *field, PropagationDirection dir=alongMomentum)
virtual VolumeCrossReturnType crossToNextVolume(const TrajectoryStateOnSurface &currentState, const Propagator &prop) const =0
double path() const
Access to actual NavSurface pointer.
const MagVolume * findVolume(const GlobalPoint &gp) const
GlobalPoint globalPosition() const
PropagationDirection
virtual const MagneticField * magneticField() const
const NavVolume * navVolume(const MagVolume *magVolume) const
Definition: Plane.h:17
bool destinationCrossed(const TSOS &startState, const TSOS &endState, const Plane &plane) const
const NavVolume * findVolume(const TrajectoryStateOnSurface &inputState) const
const TSOS & tsos() const
Access to actual Bounds pointer.
const NavVolume * volume() const
Access to actual NavVolume pointer.
virtual bool inside(const GlobalPoint &gp, double tolerance=0.) const =0
virtual std::pair< TrajectoryStateOnSurface, double > propagateWithPath(const FreeTrajectoryState &, const Plane &) const
Vector3DBase< typename PreciseFloatType< T, U >::Type, FrameTag > cross(const Vector3DBase< U, FrameTag > &v) const
Definition: Vector3DBase.h:119
T z() const
Definition: PV3DBase.h:58
tuple result
Definition: query.py:137
std::pair< TrajectoryStateOnSurface, double > TsosWP
Definition: NavPropagator.h:70
bool isIronVolume[272]
Definition: NavPropagator.h:78
Vector3DBase unit() const
Definition: Vector3DBase.h:57
const GlobalTrajectoryParameters & globalParameters() const
std::pair< TrajectoryStateOnSurface, double > propagateWithPath(const TrajectoryStateOnSurface &, const Plane &plane) const
propagation of TSOS to plane with path length
GlobalVector globalMomentum() const
TkRotation< float > RotationType
virtual SurfaceOrientation::Side side(const LocalPoint &p, Scalar toler) const
Definition: Plane.h:63
const Surface & surface() const
TrajectoryStateOnSurface noNextVolume(TrajectoryStateOnSurface startingState) const
tuple cout
Definition: gather_cfg.py:41
dbl *** dir
Definition: mlp_gen.cc:35
T x() const
Definition: PV3DBase.h:56
const PositionType & position() const
std::string name
Global3DVector GlobalVector
Definition: GlobalVector.h:10
virtual const MagneticField * magneticField() const