CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch12/src/TrackPropagation/NavGeometry/src/NavVolume6Faces.cc

Go to the documentation of this file.
00001 #include "TrackPropagation/NavGeometry/interface/NavVolume6Faces.h"
00002 #include "MagneticField/VolumeGeometry/interface/FourPointPlaneBounds.h"
00003 #include "TrackPropagation/NavGeometry/src/ThreePlaneCrossing.h"
00004 #include "DataFormats/GeometrySurface/interface/Plane.h"
00005 #include "TrackingTools/GeomPropagators/interface/StraightLinePlaneCrossing.h"
00006 #include "DataFormats/GeometrySurface/interface/GeneralNSurfaceDelimitedBounds.h"
00007 #include "TrackPropagation/NavGeometry/interface/NavSurface.h"
00008 #include "TrackPropagation/NavGeometry/interface/NavSurfaceBuilder.h"
00009 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h"
00010 
00011 #include "MagneticField/VolumeGeometry/interface/MagVolumeOutsideValidity.h"
00012 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00013 #include <map>
00014 
00015 SurfaceOrientation::Side oppositeSide( SurfaceOrientation::Side side = SurfaceOrientation::onSurface) {
00016   if ( side == SurfaceOrientation::onSurface ) {
00017     return side; 
00018   } else {
00019     SurfaceOrientation::Side oppositeSide = ( side ==SurfaceOrientation::positiveSide ? SurfaceOrientation::negativeSide : SurfaceOrientation::positiveSide);
00020     return oppositeSide;
00021   } 
00022 }
00023 
00024 
00025 NavVolume6Faces::NavVolume6Faces( const PositionType& pos,
00026                                   const RotationType& rot, 
00027                                   DDSolidShape shape,
00028                                   const std::vector<NavVolumeSide>& faces,
00029                                   const MagneticFieldProvider<float> * mfp) :
00030   NavVolume(pos,rot,shape,mfp) 
00031 {
00032   for (std::vector<NavVolumeSide>::const_iterator i=faces.begin();
00033        i != faces.end(); i++) {
00034     theFaces.push_back( VolumeSide( const_cast<Surface*>(&(i->surface().surface())), 
00035                                     i->globalFace(), i->surfaceSide()));
00036     //  LogDebug("NavGeometry") << " or actually this is where we have side " << i->surfaceSide() << " and face " << i->globalFace() ;
00037   }
00038 
00039 
00040 
00041     computeBounds(faces);
00042 }
00043 
00044 NavVolume6Faces::NavVolume6Faces( const MagVolume& magvol, bool isIron) :
00045   NavVolume( magvol.position(), magvol.rotation(), magvol.shapeType(), magvol.provider()),
00046   theFaces(magvol.faces()), isThisIron(isIron)
00047 {
00048   std::vector<NavVolumeSide> navSides;
00049   std::vector<VolumeSide> magSides( magvol.faces());
00050   NavSurfaceBuilder navBuilder;
00051 
00052   for (std::vector<VolumeSide>::const_iterator i=magSides.begin();
00053        i != magSides.end(); i++) {
00054     NavSurface* navSurface = navBuilder.build( i->surface());
00055     navSides.push_back( NavVolumeSide( navSurface, i->globalFace(), i->surfaceSide()));
00056   }
00057   computeBounds(navSides);
00058 }
00059 
00060 
00061 bool NavVolume6Faces::inside( const GlobalPoint& gp, double tolerance) const 
00062 {
00063   // check if the point is on the correct side of all delimiting surfaces
00064   for (std::vector<VolumeSide>::const_iterator i=theFaces.begin(); i!=theFaces.end(); i++) {
00065     Surface::Side side = i->surface().side( gp, tolerance);
00066     if ( side != i->surfaceSide() && side != SurfaceOrientation::onSurface) return false;
00067   }
00068   return true;
00069 }
00070 
00071 
00072 
00073 void NavVolume6Faces::computeBounds(const std::vector<NavVolumeSide>& faces) 
00074 {
00075     bool allPlanes = true;
00076     // bool allPlanes = false; // for TESTS ONLY!!!
00077     std::vector<const Plane*> planes;
00078     for (std::vector<NavVolumeSide>::const_iterator iface=faces.begin(); iface!=faces.end(); iface++) {
00079         const Plane* plane = dynamic_cast<const Plane*>(&(iface->surface()));
00080         if (plane != 0) {
00081             planes.push_back(plane);
00082         }
00083         else allPlanes = false;
00084     }
00085     
00086     for (unsigned int i=0; i<faces.size(); i++) {
00087 
00088       // FIXME: who owns the new NavSurface? memory leak???
00089 
00090         NavSurface& navSurf = faces[i].mutableSurface();
00091         Bounds* myBounds = 0;
00092         if (allPlanes) {        
00093             myBounds = computeBounds( i, planes);
00094         }
00095         else {
00096             myBounds = computeBounds( i, faces);
00097         }
00098         navSurf.addVolume( this, myBounds, faces[i].surfaceSide());
00099         delete myBounds; // since navSurf now owns a copy
00100 
00101 // this is tricky: we want to avoid multiple copies of the Bounds; the NavSurface owns
00102 // a copy of Bounds for each touching Volume (instantiated in the call to addVolume).
00103 // We would like to keep a pointer to the same Bounds in the NavVolume, so we have to ASK
00104 // the NavSurface for the Bounds* of the Bounds we just gave it!
00105         //LogDebug("NavGeometry") << "Adding a Volume Side with center " << navSurf.surface().position() << " side "<< faces[i].surfaceSide() << " and face " << faces[i].globalFace();
00106         theNavSurfaces.push_back( SurfaceAndBounds(&navSurf, navSurf.bounds(this), faces[i].surfaceSide(), faces[i].globalFace()));
00107     }
00108 }
00109 
00110 Bounds* NavVolume6Faces::computeBounds( int index, 
00111                                         const std::vector<const Plane*>& bpc)
00112 {
00113   const Plane* plane( bpc[index]);
00114 
00115   // find the 4 intersecting planes
00116   int startIndex = 2*(1+index/2); // 2, 4, 6
00117   std::vector<const Plane*> crossed; crossed.reserve(4);
00118   for (int j = startIndex; j <  startIndex+4; j++) {
00119     crossed.push_back(bpc[j%6]);
00120   }
00121 
00122   // compute intersection corners of the plane triplets
00123   std::vector<GlobalPoint> corners; corners.reserve(4);
00124   ThreePlaneCrossing crossing;
00125   for ( int i=0; i<2; i++) {
00126     for ( int j=2; j<4; j++) {
00127       GlobalPoint corner( crossing.crossing( *plane, *crossed[i], *crossed[j]));
00128       corners.push_back(corner);
00129 
00130 #ifdef DEBUG
00131       std::cout << "Crossing of planes is " << corner << std::endl;
00132       std::cout << "NormalVectors of the planes are " << plane->normalVector()
00133            << " " << crossed[i]->normalVector() << " " << crossed[j]->normalVector() << std::endl;
00134       std::cout << "Positions of planes are " << plane->position()
00135            << " " << crossed[i]->position() << " " << crossed[j]->position() << std::endl;
00136       if (plane->side( corner, 1.e-5) == SurfaceOrientation::onSurface &&
00137           crossed[i]->side( corner, 1.e-5) == SurfaceOrientation::onSurface &&
00138           crossed[j]->side( corner, 1.e-5) == SurfaceOrientation::onSurface) {
00139           std::cout << "Crossing is really on all three surfaces" << std::endl;
00140       }
00141       else {
00142           std::cout << "CROSSING IS NOT ON SURFACES!!!" << std::endl;
00143           std::cout << plane->localZ(corner) << std::endl;
00144           std::cout << crossed[i]->localZ(corner) << std::endl;
00145           std::cout << crossed[j]->localZ(corner) << std::endl;
00146        }
00147 #endif
00148 
00149     }
00150   }
00151 
00152   // put corners in cyclic sequence (2 and 3 swapped)
00153   return new FourPointPlaneBounds( plane->toLocal( corners[0]), plane->toLocal( corners[1]),
00154                                    plane->toLocal( corners[3]), plane->toLocal( corners[2]));
00155 }
00156 
00157 Bounds* NavVolume6Faces::computeBounds( int index, const std::vector<NavVolumeSide>& faces)
00158 {
00159     typedef GeneralNSurfaceDelimitedBounds::SurfaceAndSide         SurfaceAndSide;
00160     typedef GeneralNSurfaceDelimitedBounds::SurfaceContainer       SurfaceContainer;
00161 
00162   // find the 4 intersecting surfaces
00163   int startIndex = 2*(1+index/2); // 2, 4, 6
00164   SurfaceContainer crossed; crossed.reserve(4);
00165   for (int j = startIndex; j <  startIndex+4; j++) {
00166     const NavVolumeSide& face(faces[j%6]);
00167     crossed.push_back( SurfaceAndSide(&(face.surface().surface()), face.surfaceSide()));
00168   }
00169   return new GeneralNSurfaceDelimitedBounds( &(faces[index].surface().surface()), crossed);
00170 }
00171 
00172 
00173 NavVolume::Container
00174 NavVolume6Faces::nextSurface( const NavVolume::LocalPoint& pos, 
00175                               const NavVolume::LocalVector& mom,
00176                               double charge, PropagationDirection propDir) const
00177 {
00178     typedef std::map<double,SurfaceAndBounds>   SortedContainer;
00179 
00180     GlobalPoint  gpos( toGlobal(pos));
00181     GlobalVector gmom( toGlobal(mom));
00182     GlobalVector gdir = (propDir == alongMomentum ? gmom : -gmom);
00183 
00184     SortedContainer sortedSurfaces;
00185     Container       verycloseSurfaces; // reachable surface with dist < epsilon !!
00186     Container       unreachableSurfaces;
00187 
00188     double epsilon = 0.01; // should epsilon be hard-coded or a variable in NavVolume?
00189 
00190     for (Container::const_iterator i=theNavSurfaces.begin(); i!=theNavSurfaces.end(); i++) {
00191         std::pair<bool,double> dist = i->surface().distanceAlongLine( gpos, gdir);
00192         if (dist.first) {
00193           if (dist.second > epsilon) sortedSurfaces[dist.second] = *i;
00194           else verycloseSurfaces.push_back(*i);
00195         } 
00196         else unreachableSurfaces.push_back(*i);
00197     }
00198     NavVolume::Container result;
00199     for (SortedContainer::const_iterator i=sortedSurfaces.begin(); i!=sortedSurfaces.end(); ++i) {
00200         result.push_back(i->second);
00201     }
00202     result.insert( result.end(), unreachableSurfaces.begin(), unreachableSurfaces.end());
00203     result.insert( result.end(), verycloseSurfaces.begin(), verycloseSurfaces.end());
00204     return result;
00205 }
00206 
00207 NavVolume::Container
00208 NavVolume6Faces::nextSurface( const NavVolume::LocalPoint& pos, 
00209                               const NavVolume::LocalVector& mom,
00210                               double charge, PropagationDirection propDir,
00211                               ConstReferenceCountingPointer<Surface> NotThisSurfaceP) const
00212 {
00213     typedef std::map<double,SurfaceAndBounds>   SortedContainer;
00214 
00215     GlobalPoint  gpos( toGlobal(pos));
00216     GlobalVector gmom( toGlobal(mom));
00217     GlobalVector gdir = (propDir == alongMomentum ? gmom : -gmom);
00218 
00219     SortedContainer sortedSurfaces;
00220     Container       verycloseSurfaces; // reachable surface with dist < epsilon (if 6-surface check fails)
00221     Container       unreachableSurfaces;
00222 
00223     double epsilon = 0.01; // should epsilon be hard-coded or a variable in NavVolume?
00224     bool surfaceMatched = false;
00225 
00226     for (Container::const_iterator i=theNavSurfaces.begin(); i!=theNavSurfaces.end(); i++) {
00227       if (&(i->surface().surface()) == NotThisSurfaceP) surfaceMatched = true;
00228     }
00229     
00230     for (Container::const_iterator i=theNavSurfaces.begin(); i!=theNavSurfaces.end(); i++) {
00231         std::pair<bool,double> dist = i->surface().distanceAlongLine( gpos, gdir);
00232         if (dist.first) { 
00233           if ( &(i->surface().surface()) == NotThisSurfaceP || (!surfaceMatched && dist.second < epsilon)) 
00234             verycloseSurfaces.push_back(*i);
00235           else sortedSurfaces[dist.second] = *i;
00236         }
00237         else unreachableSurfaces.push_back(*i);
00238     }
00239 
00240     NavVolume::Container result;
00241     for (SortedContainer::const_iterator i=sortedSurfaces.begin(); i!=sortedSurfaces.end(); ++i) {
00242         result.push_back(i->second);
00243     }
00244     result.insert( result.end(), unreachableSurfaces.begin(), unreachableSurfaces.end());
00245     result.insert( result.end(), verycloseSurfaces.begin(), verycloseSurfaces.end());
00246     return result;
00247 }
00248 
00249 VolumeCrossReturnType
00250 NavVolume6Faces::crossToNextVolume( const TrajectoryStateOnSurface& startingState, const Propagator& prop ) const
00251 {
00252   typedef TrajectoryStateOnSurface TSOS;
00253   typedef std::pair<TSOS,double> TSOSwithPath;
00254 
00255   NavVolume::Container nsc = nextSurface( toLocal( startingState.globalPosition()), 
00256                                           toLocal( startingState.globalMomentum()), -1,
00257                                           alongMomentum, &(startingState.surface()));
00258   int itry = 0;
00259   VolumeCrossReturnType VolumeCrossResult( 0, startingState, 0.0);
00260 
00261   for (NavVolume::Container::const_iterator isur = nsc.begin(); isur!=nsc.end(); isur++) {
00262 
00263     LogDebug("NavGeometry") <<  "crossToNextVolume: trying Surface no. " << itry ;
00264     TSOSwithPath state;
00265     
00266     try {
00267       state = isur->surface().propagateWithPath( prop, startingState);
00268     }
00269     catch (MagVolumeOutsideValidity& except) {
00270       LogDebug("NavGeometry") << "Ohoh... failed to stay inside magnetic field !! skip this surface " ;
00271         ++itry;
00272       continue;
00273     }
00274     
00275     if (!state.first.isValid()) {
00276       ++itry;
00277       continue;
00278     }
00279 
00280     LogDebug("NavGeometry") <<  "crossToNextVolume: reached Valid State at Surface no. " << itry ;
00281     LogDebug("NavGeometry") << " --> local position of Valid state is " <<  state.first.localPosition()  ;
00282     LogDebug("NavGeometry") << " --> global position of Valid state is " <<  state.first.globalPosition()  ;
00283 
00284     if (isur->bounds().inside(state.first.localPosition())) {
00285       //LogDebug("NavGeometry") << "crossToNextVolume: Surface containing destination point found at try " << itry ;
00286       // Found the exit surface !! Get pointer to next volume and save exit state:
00287       //VolumeCrossResult.first = isur->surface().nextVolume(state.localPosition(),oppositeSide(isur->side()));
00288       //VolumeCrossResult.second = state;
00289       //      exitSurface = &( isur->surface().surface() );
00290       //if(VolumeCrossResult.path() < 0.01) {
00291       //        LogDebug("NavGeometry") << " Stuck at  " << state.first.globalPosition() ;
00292       //}
00293       return VolumeCrossReturnType ( isur->surface().nextVolume(state.first.localPosition(), oppositeSide(isur->side())),
00294                             state.first, state.second );
00295       
00296       break;
00297     }
00298     else {
00299       LogDebug("NavGeometry") << "crossToNextVolume: BUT not inside the Bounds !! " ;
00300       ++itry;
00301     }
00302   }
00303 
00304   return VolumeCrossResult;
00305 }
00306 
00307 /*
00308 std::pair<bool,double>
00309 NavVolume6Faces::linearDistance( const NavSurface& surf, const NavVolume::LocalPoint& pos, 
00310                                  const NavVolume::LocalVector& mom) const
00311 {
00312     const Plane* plane = dynamic_cast<const Plane*>(&surf);
00313     if (plane != 0) {
00314         
00315 
00316 }
00317 */
00318 
00319 /*
00320 NavVolume::Container
00321 NavVolume6Faces::nextSurface( const NavVolume::LocalPoint& pos, 
00322                               const NavVolume::LocalVector& mom,
00323                               double charge, PropagationDirection propDir) const
00324 {
00325     StraightLinePlaneCrossing pc( toGlobal(pos).basicVector(), toGlobal(mom).basicVector(), propDir);
00326     Container approaching;
00327     Container movingaway;
00328     SurfaceAndBounds bestGuess;
00329 
00330     for (Container::const_iterator i=theNavSurfaces.begin(); i!=theNavSurfaces.end(); i++) {
00331         const Plane& plane = dynamic_cast<const Plane&>(*(i->first));
00332         std::pair<bool,StraightLinePlaneCrossing::PositionType> crossed = pc.position( plane);
00333         if (crossed.first) {
00334 
00335 #ifdef DEBUG
00336             std::cout << "Plane crossed at global point " << crossed.second
00337                  << " local point " << plane.toLocal( Plane::GlobalPoint(crossed.second)) << std::endl;
00338 #endif
00339 
00340             if ( i->second->inside( plane.toLocal( Plane::GlobalPoint(crossed.second)))) {
00341                 bestGuess = SurfaceAndBounds( i->first, i->second);
00342             }
00343             else {
00344                 // momentm is pointing towards the plane
00345                 approaching.push_back( SurfaceAndBounds( i->first, i->second));
00346             }
00347         }
00348         else {
00349             movingaway.push_back( SurfaceAndBounds( i->first, i->second));
00350         }
00351     }
00352 
00353     NavVolume::Container result(1,bestGuess); result.reserve(theNavSurfaces.size());
00354     result.insert(result.end(), approaching.begin(), approaching.end());
00355     result.insert(result.end(), movingaway.begin(), movingaway.end());
00356     return result;
00357 }
00358 */