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