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
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
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
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
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;
00100
00101
00102
00103
00104
00105
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
00116 int startIndex = 2*(1+index/2);
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
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
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
00163 int startIndex = 2*(1+index/2);
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;
00186 Container unreachableSurfaces;
00187
00188 double epsilon = 0.01;
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;
00221 Container unreachableSurfaces;
00222
00223 double epsilon = 0.01;
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
00286
00287
00288
00289
00290
00291
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
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358