CMS 3D CMS Logo

NavVolume6Faces.cc
Go to the documentation of this file.
10 
13 #include <map>
14 
16  if ( side == SurfaceOrientation::onSurface ) {
17  return side;
18  } else {
20  return oppositeSide;
21  }
22 }
23 
24 
26  const RotationType& rot,
27  DDSolidShape shape,
28  const std::vector<NavVolumeSide>& faces,
29  const MagneticFieldProvider<float> * mfp) :
30  NavVolume(pos,rot,shape,mfp)
31 {
32  for (std::vector<NavVolumeSide>::const_iterator i=faces.begin();
33  i != faces.end(); i++) {
34  theFaces.push_back( VolumeSide( const_cast<Surface*>(&(i->surface().surface())),
35  i->globalFace(), i->surfaceSide()));
36  // LogDebug("NavGeometry") << " or actually this is where we have side " << i->surfaceSide() << " and face " << i->globalFace() ;
37  }
38 
39 
40 
41  computeBounds(faces);
42 }
43 
45  NavVolume( magvol.position(), magvol.rotation(), magvol.shapeType(), magvol.provider()),
46  theFaces(magvol.faces()), isThisIron(isIron)
47 {
48  std::vector<NavVolumeSide> navSides;
49  std::vector<VolumeSide> magSides( magvol.faces());
50  NavSurfaceBuilder navBuilder;
51 
52  for (std::vector<VolumeSide>::const_iterator i=magSides.begin();
53  i != magSides.end(); i++) {
54  NavSurface* navSurface = navBuilder.build( i->surface());
55  navSides.push_back( NavVolumeSide( navSurface, i->globalFace(), i->surfaceSide()));
56  }
57  computeBounds(navSides);
58 }
59 
60 
61 bool NavVolume6Faces::inside( const GlobalPoint& gp, double tolerance) const
62 {
63  // check if the point is on the correct side of all delimiting surfaces
64  for (std::vector<VolumeSide>::const_iterator i=theFaces.begin(); i!=theFaces.end(); i++) {
65  Surface::Side side = i->surface().side( gp, tolerance);
66  if ( side != i->surfaceSide() && side != SurfaceOrientation::onSurface) return false;
67  }
68  return true;
69 }
70 
71 
72 
73 void NavVolume6Faces::computeBounds(const std::vector<NavVolumeSide>& faces)
74 {
75  bool allPlanes = true;
76  // bool allPlanes = false; // for TESTS ONLY!!!
77  std::vector<const Plane*> planes;
78  for (std::vector<NavVolumeSide>::const_iterator iface=faces.begin(); iface!=faces.end(); iface++) {
79  const Plane* plane = dynamic_cast<const Plane*>(&(iface->surface()));
80  if (plane != nullptr) {
81  planes.push_back(plane);
82  }
83  else allPlanes = false;
84  }
85 
86  for (unsigned int i=0; i<faces.size(); i++) {
87 
88  // FIXME: who owns the new NavSurface? memory leak???
89 
90  NavSurface& navSurf = faces[i].mutableSurface();
91  Bounds* myBounds = nullptr;
92  if (allPlanes) {
93  myBounds = computeBounds( i, planes);
94  }
95  else {
96  myBounds = computeBounds( i, faces);
97  }
98  navSurf.addVolume( this, myBounds, faces[i].surfaceSide());
99  delete myBounds; // since navSurf now owns a copy
100 
101 // this is tricky: we want to avoid multiple copies of the Bounds; the NavSurface owns
102 // a copy of Bounds for each touching Volume (instantiated in the call to addVolume).
103 // We would like to keep a pointer to the same Bounds in the NavVolume, so we have to ASK
104 // the NavSurface for the Bounds* of the Bounds we just gave it!
105  //LogDebug("NavGeometry") << "Adding a Volume Side with center " << navSurf.surface().position() << " side "<< faces[i].surfaceSide() << " and face " << faces[i].globalFace();
106  theNavSurfaces.push_back( SurfaceAndBounds(&navSurf, navSurf.bounds(this), faces[i].surfaceSide(), faces[i].globalFace()));
107  }
108 }
109 
111  const std::vector<const Plane*>& bpc)
112 {
113  const Plane* plane( bpc[index]);
114 
115  // find the 4 intersecting planes
116  int startIndex = 2*(1+index/2); // 2, 4, 6
117  std::vector<const Plane*> crossed; crossed.reserve(4);
118  for (int j = startIndex; j < startIndex+4; j++) {
119  crossed.push_back(bpc[j%6]);
120  }
121 
122  // compute intersection corners of the plane triplets
123  std::vector<GlobalPoint> corners; corners.reserve(4);
124  ThreePlaneCrossing crossing;
125  for ( int i=0; i<2; i++) {
126  for ( int j=2; j<4; j++) {
127  GlobalPoint corner( crossing.crossing( *plane, *crossed[i], *crossed[j]));
128  corners.push_back(corner);
129 
130 #ifdef DEBUG
131  std::cout << "Crossing of planes is " << corner << std::endl;
132  std::cout << "NormalVectors of the planes are " << plane->normalVector()
133  << " " << crossed[i]->normalVector() << " " << crossed[j]->normalVector() << std::endl;
134  std::cout << "Positions of planes are " << plane->position()
135  << " " << crossed[i]->position() << " " << crossed[j]->position() << std::endl;
136  if (plane->side( corner, 1.e-5) == SurfaceOrientation::onSurface &&
137  crossed[i]->side( corner, 1.e-5) == SurfaceOrientation::onSurface &&
138  crossed[j]->side( corner, 1.e-5) == SurfaceOrientation::onSurface) {
139  std::cout << "Crossing is really on all three surfaces" << std::endl;
140  }
141  else {
142  std::cout << "CROSSING IS NOT ON SURFACES!!!" << std::endl;
143  std::cout << plane->localZ(corner) << std::endl;
144  std::cout << crossed[i]->localZ(corner) << std::endl;
145  std::cout << crossed[j]->localZ(corner) << std::endl;
146  }
147 #endif
148 
149  }
150  }
151 
152  // put corners in cyclic sequence (2 and 3 swapped)
153  return new FourPointPlaneBounds( plane->toLocal( corners[0]), plane->toLocal( corners[1]),
154  plane->toLocal( corners[3]), plane->toLocal( corners[2]));
155 }
156 
157 Bounds* NavVolume6Faces::computeBounds( int index, const std::vector<NavVolumeSide>& faces)
158 {
159  typedef GeneralNSurfaceDelimitedBounds::SurfaceAndSide SurfaceAndSide;
160  typedef GeneralNSurfaceDelimitedBounds::SurfaceContainer SurfaceContainer;
161 
162  // find the 4 intersecting surfaces
163  int startIndex = 2*(1+index/2); // 2, 4, 6
164  SurfaceContainer crossed; crossed.reserve(4);
165  for (int j = startIndex; j < startIndex+4; j++) {
166  const NavVolumeSide& face(faces[j%6]);
167  crossed.push_back( SurfaceAndSide(&(face.surface().surface()), face.surfaceSide()));
168  }
169  return new GeneralNSurfaceDelimitedBounds( &(faces[index].surface().surface()), crossed);
170 }
171 
172 
175  const NavVolume::LocalVector& mom,
176  double charge, PropagationDirection propDir) const
177 {
178  typedef std::map<double,SurfaceAndBounds> SortedContainer;
179 
180  GlobalPoint gpos( toGlobal(pos));
181  GlobalVector gmom( toGlobal(mom));
182  GlobalVector gdir = (propDir == alongMomentum ? gmom : -gmom);
183 
184  SortedContainer sortedSurfaces;
185  Container verycloseSurfaces; // reachable surface with dist < epsilon !!
186  Container unreachableSurfaces;
187 
188  double epsilon = 0.01; // should epsilon be hard-coded or a variable in NavVolume?
189 
190  for (Container::const_iterator i=theNavSurfaces.begin(); i!=theNavSurfaces.end(); i++) {
191  std::pair<bool,double> dist = i->surface().distanceAlongLine( gpos, gdir);
192  if (dist.first) {
193  if (dist.second > epsilon) sortedSurfaces[dist.second] = *i;
194  else verycloseSurfaces.push_back(*i);
195  }
196  else unreachableSurfaces.push_back(*i);
197  }
199  for (SortedContainer::const_iterator i=sortedSurfaces.begin(); i!=sortedSurfaces.end(); ++i) {
200  result.push_back(i->second);
201  }
202  result.insert( result.end(), unreachableSurfaces.begin(), unreachableSurfaces.end());
203  result.insert( result.end(), verycloseSurfaces.begin(), verycloseSurfaces.end());
204  return result;
205 }
206 
209  const NavVolume::LocalVector& mom,
210  double charge, PropagationDirection propDir,
211  ConstReferenceCountingPointer<Surface> NotThisSurfaceP) const
212 {
213  typedef std::map<double,SurfaceAndBounds> SortedContainer;
214 
215  GlobalPoint gpos( toGlobal(pos));
216  GlobalVector gmom( toGlobal(mom));
217  GlobalVector gdir = (propDir == alongMomentum ? gmom : -gmom);
218 
219  SortedContainer sortedSurfaces;
220  Container verycloseSurfaces; // reachable surface with dist < epsilon (if 6-surface check fails)
221  Container unreachableSurfaces;
222 
223  double epsilon = 0.01; // should epsilon be hard-coded or a variable in NavVolume?
224  bool surfaceMatched = false;
225 
226  for (Container::const_iterator i=theNavSurfaces.begin(); i!=theNavSurfaces.end(); i++) {
227  if (&(i->surface().surface()) == NotThisSurfaceP) surfaceMatched = true;
228  }
229 
230  for (Container::const_iterator i=theNavSurfaces.begin(); i!=theNavSurfaces.end(); i++) {
231  std::pair<bool,double> dist = i->surface().distanceAlongLine( gpos, gdir);
232  if (dist.first) {
233  if ( &(i->surface().surface()) == NotThisSurfaceP || (!surfaceMatched && dist.second < epsilon))
234  verycloseSurfaces.push_back(*i);
235  else sortedSurfaces[dist.second] = *i;
236  }
237  else unreachableSurfaces.push_back(*i);
238  }
239 
241  for (SortedContainer::const_iterator i=sortedSurfaces.begin(); i!=sortedSurfaces.end(); ++i) {
242  result.push_back(i->second);
243  }
244  result.insert( result.end(), unreachableSurfaces.begin(), unreachableSurfaces.end());
245  result.insert( result.end(), verycloseSurfaces.begin(), verycloseSurfaces.end());
246  return result;
247 }
248 
251 {
253  typedef std::pair<TSOS,double> TSOSwithPath;
254 
255  NavVolume::Container nsc = nextSurface( toLocal( startingState.globalPosition()),
256  toLocal( startingState.globalMomentum()), -1,
257  alongMomentum, &(startingState.surface()));
258  int itry = 0;
259  VolumeCrossReturnType VolumeCrossResult( nullptr, startingState, 0.0);
260 
261  for (NavVolume::Container::const_iterator isur = nsc.begin(); isur!=nsc.end(); isur++) {
262 
263  LogDebug("NavGeometry") << "crossToNextVolume: trying Surface no. " << itry ;
264  TSOSwithPath state;
265 
266  try {
267  state = isur->surface().propagateWithPath( prop, startingState);
268  }
269  catch (MagVolumeOutsideValidity& except) {
270  LogDebug("NavGeometry") << "Ohoh... failed to stay inside magnetic field !! skip this surface " ;
271  ++itry;
272  continue;
273  }
274 
275  if (!state.first.isValid()) {
276  ++itry;
277  continue;
278  }
279 
280  LogDebug("NavGeometry") << "crossToNextVolume: reached Valid State at Surface no. " << itry ;
281  LogDebug("NavGeometry") << " --> local position of Valid state is " << state.first.localPosition() ;
282  LogDebug("NavGeometry") << " --> global position of Valid state is " << state.first.globalPosition() ;
283 
284  if (isur->bounds().inside(state.first.localPosition())) {
285  //LogDebug("NavGeometry") << "crossToNextVolume: Surface containing destination point found at try " << itry ;
286  // Found the exit surface !! Get pointer to next volume and save exit state:
287  //VolumeCrossResult.first = isur->surface().nextVolume(state.localPosition(),oppositeSide(isur->side()));
288  //VolumeCrossResult.second = state;
289  // exitSurface = &( isur->surface().surface() );
290  //if(VolumeCrossResult.path() < 0.01) {
291  // LogDebug("NavGeometry") << " Stuck at " << state.first.globalPosition() ;
292  //}
293  return VolumeCrossReturnType ( isur->surface().nextVolume(state.first.localPosition(), oppositeSide(isur->side())),
294  state.first, state.second );
295 
296  break;
297  }
298  else {
299  LogDebug("NavGeometry") << "crossToNextVolume: BUT not inside the Bounds !! " ;
300  ++itry;
301  }
302  }
303 
304  return VolumeCrossResult;
305 }
306 
307 /*
308 std::pair<bool,double>
309 NavVolume6Faces::linearDistance( const NavSurface& surf, const NavVolume::LocalPoint& pos,
310  const NavVolume::LocalVector& mom) const
311 {
312  const Plane* plane = dynamic_cast<const Plane*>(&surf);
313  if (plane != 0) {
314 
315 
316 }
317 */
318 
319 /*
320 NavVolume::Container
321 NavVolume6Faces::nextSurface( const NavVolume::LocalPoint& pos,
322  const NavVolume::LocalVector& mom,
323  double charge, PropagationDirection propDir) const
324 {
325  StraightLinePlaneCrossing pc( toGlobal(pos).basicVector(), toGlobal(mom).basicVector(), propDir);
326  Container approaching;
327  Container movingaway;
328  SurfaceAndBounds bestGuess;
329 
330  for (Container::const_iterator i=theNavSurfaces.begin(); i!=theNavSurfaces.end(); i++) {
331  const Plane& plane = dynamic_cast<const Plane&>(*(i->first));
332  std::pair<bool,StraightLinePlaneCrossing::PositionType> crossed = pc.position( plane);
333  if (crossed.first) {
334 
335 #ifdef DEBUG
336  std::cout << "Plane crossed at global point " << crossed.second
337  << " local point " << plane.toLocal( Plane::GlobalPoint(crossed.second)) << std::endl;
338 #endif
339 
340  if ( i->second->inside( plane.toLocal( Plane::GlobalPoint(crossed.second)))) {
341  bestGuess = SurfaceAndBounds( i->first, i->second);
342  }
343  else {
344  // momentm is pointing towards the plane
345  approaching.push_back( SurfaceAndBounds( i->first, i->second));
346  }
347  }
348  else {
349  movingaway.push_back( SurfaceAndBounds( i->first, i->second));
350  }
351  }
352 
353  NavVolume::Container result(1,bestGuess); result.reserve(theNavSurfaces.size());
354  result.insert(result.end(), approaching.begin(), approaching.end());
355  result.insert(result.end(), movingaway.begin(), movingaway.end());
356  return result;
357 }
358 */
#define LogDebug(id)
DDSolidShape shapeType() const
Definition: MagVolume.h:31
Container theNavSurfaces
const std::vector< VolumeSide > & faces() const override
Access to volume faces.
GloballyPositioned< float >::GlobalPoint GlobalPoint
Definition: MagVolume.h:20
Container nextSurface(const NavVolume::LocalPoint &pos, const NavVolume::LocalVector &mom, double charge, PropagationDirection propDir=alongMomentum) const override
Give a sorted list of possible surfaces to propagate to.
GlobalVector normalVector() const
Definition: Plane.h:41
DDSolidShape
Definition: DDSolidShapes.h:6
float localZ(const GlobalPoint &gp) const
Definition: Plane.h:45
GlobalPoint globalPosition() const
const NavSurface & surface() const
Definition: NavVolumeSide.h:30
SurfaceOrientation::Side side(const LocalPoint &p, Scalar toler) const final
Definition: Plane.h:67
PropagationDirection
helper: builde a NavSurface for a Surface
std::pair< const Surface *, SurfaceOrientation::Side > SurfaceAndSide
Plane::GlobalPoint crossing(const Plane &a, const Plane &b, const Plane &c) const
Definition: Plane.h:17
std::vector< SurfaceAndBounds > Container
Definition: NavVolume.h:27
virtual const std::vector< VolumeSide > & faces() const =0
Access to volume faces.
bool isIron() const override
Access to Iron/Air information:
const MagneticFieldProvider< float > * provider() const
Definition: MagVolume.h:41
GloballyPositioned< float >::LocalPoint LocalPoint
Definition: MagVolume.h:18
GloballyPositioned< float >::LocalVector LocalVector
Definition: MagVolume.h:19
const SurfaceType & surface() const
virtual const Surface & surface() const =0
Access to actual surface.
LocalPoint toLocal(const GlobalPoint &gp) const
bool inside(const GlobalPoint &gp, double tolerance) const override
NavVolume6Faces(const PositionType &pos, const RotationType &rot, DDSolidShape shape, const std::vector< NavVolumeSide > &faces, const MagneticFieldProvider< float > *mfp)
std::vector< SurfaceAndSide > SurfaceContainer
Side surfaceSide() const
Definition: NavVolumeSide.h:34
GlobalPoint toGlobal(const LocalPoint &lp) const
TrajectoryStateOnSurface TSOS
Definition: TestHits.cc:19
virtual const Bounds * bounds(const NavVolume *vol)=0
Bounds corresponding to a NavVolume if present.
GloballyPositioned< float >::GlobalVector GlobalVector
Definition: MagVolume.h:21
virtual void addVolume(const NavVolume *vol, const Bounds *bounds, SurfaceOrientation::Side side)=0
NavVolumes are supposed to call this method to "register" with the NavSurface.
GlobalVector globalMomentum() const
VolumeCrossReturnType crossToNextVolume(const TrajectoryStateOnSurface &currentState, const Propagator &prop) const override
Cross this volume and point at the next.
const RotationType & rotation() const
Definition: Bounds.h:22
std::vector< VolumeSide > theFaces
const PositionType & position() const
void computeBounds(const std::vector< NavVolumeSide > &faces)