00001 #include "TrackPropagation/NavPropagator/interface/NavPropagator.h"
00002 #include "MagneticField/VolumeBasedEngine/interface/VolumeBasedMagneticField.h"
00003 #include "TrackingTools/GeomPropagators/interface/PropagationExceptions.h"
00004 #include "TrackPropagation/NavGeometry/interface/NavVolume6Faces.h"
00005
00006 #include "MagneticField/VolumeGeometry/interface/MagVolume6Faces.h"
00007
00008 #include "TrackPropagation/RungeKutta/interface/RKPropagatorInS.h"
00009 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00010 #include "DataFormats/GeometrySurface/interface/PlaneBuilder.h"
00011
00012 using namespace std;
00013
00014 NavPropagator::NavPropagator( const MagneticField* field,
00015 PropagationDirection dir) :
00016 Propagator(dir)
00017 {
00018 theField = dynamic_cast<const VolumeBasedMagneticField*>(field);
00019
00020 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,
00021 63,65,71,77,105,106,107,111,112,113,114,115,116,117,118,122,123,
00022 125,126,128,129,130,131,132,133,135,137,141,145,147,148,149,153,
00023 154,155,156,157,158,159,160,164,165,167,168,170,171,172,173,174,
00024 175,177,178,179,180,184,185,186,187,188,189,190,191,195,196,198,
00025 200,204,208,210,211,212,216,217,218,219,220,221,222,223,227,228,
00026 230,231,233,234,235,236,237,238,240,241,242,243,247,248,249,250,
00027 251,252,253,254,258,259,261};
00028 for(int i=0; i<272; i++) isIronVolume[i]=false;
00029 for(int i=0; i<126 ; i++) isIronVolume[myIronVolumes[i]]=true;
00030
00031
00032
00033
00034 }
00035
00036 NavPropagator::~NavPropagator() {
00037 for (MagVolumeMap::iterator i = theNavVolumeMap.begin(); i != theNavVolumeMap.end(); ++i) {
00038 delete i->second;
00039 }
00040 }
00041
00042 const MagneticField* NavPropagator::magneticField() const {return theField;}
00043
00044 std::pair<TrajectoryStateOnSurface,double>
00045 NavPropagator::propagateWithPath(const TrajectoryStateOnSurface& inputState,
00046 const Plane& targetPlane) const
00047 {
00048
00049 LogDebug("NavPropagator") << "NavPropagator::propagateWithPath(TrajectoryStateOnSurface, Plane) called with "
00050 << inputState;
00051
00052 VolumeCrossReturnType exitState( 0, inputState, 0.0);
00053 TSOS startingState = inputState;
00054 TSOS TempState = inputState;
00055 const NavVolume* currentVolume = 0;
00056
00057 int count = 0;
00058 int maxCount = 100;
00059 while (!destinationCrossed( startingState, TempState, targetPlane)) {
00060
00061 LogDebug("NavPropagator") << "NavPropagator:: at beginning of while loop at iteration " << count ;
00062
00063 startingState = TempState;
00064 bool isReflected = false;
00065
00066 if (exitState.volume() != 0) {
00067 currentVolume = exitState.volume();
00068 }
00069 else {
00070
00071 GlobalPoint gp = startingState.globalPosition() + 0.1*startingState.globalMomentum().unit();
00072
00073 if (gp.z()>0) {
00074 GlobalTrajectoryParameters gtp( GlobalPoint(startingState.globalPosition().x(),
00075 startingState.globalPosition().y(),
00076 -startingState.globalPosition().z()),
00077 GlobalVector(startingState.globalMomentum().x(),
00078 startingState.globalMomentum().y(),
00079 -startingState.globalMomentum().z()),
00080 startingState.globalParameters().charge(), theField );
00081 FreeTrajectoryState fts(gtp);
00082 TempState = TSOS( fts, startingState.surface());
00083 isReflected = true;
00084 }
00085 currentVolume = findVolume( TempState );
00086 if (currentVolume == 0) {
00087 std::cout << "NavPropagator: findVolume failed to find volume containing point "
00088 << startingState.globalPosition() ;
00089 return std::pair<TrajectoryStateOnSurface,double>(noNextVolume( startingState), 0);
00090 }
00091 }
00092
00093 PropagatorType currentPropagator( *currentVolume);
00094
00095 LogDebug("NavPropagator") << "NavPropagator: calling crossToNextVolume" ;
00096 exitState = currentVolume->crossToNextVolume( TempState, currentPropagator);
00097 LogDebug("NavPropagator") << "NavPropagator: crossToNextVolume returned" ;
00098 LogDebug("NavPropagator") << "Volume pointer: " << exitState.volume() << " and new ";
00099 LogDebug("NavPropagator") << exitState.tsos() ;
00100 LogDebug("NavPropagator") << "So that was a path length " << exitState.path() ;
00101
00102
00103 if ( !exitState.tsos().isValid()) {
00104
00105 std::cout << "NavPropagator: failed to crossToNextVolume in volume at pos "
00106 << currentVolume->position();
00107 break;
00108 }
00109 else {
00110 LogDebug("NavPropagator") << "NavPropagator: crossToNextVolume reached volume ";
00111 if (exitState.volume() != 0) {
00112 LogDebug("NavPropagator") << " at pos "
00113 << exitState.volume()->position()
00114 << "with state " << exitState.tsos() ;
00115 }
00116 else LogDebug("NavPropagator") << " unknown";
00117 }
00118
00119 TempState = exitState.tsos();
00120
00121 if (fabs(exitState.path())<0.01) {
00122 LogDebug("NavPropagator") << "failed to move at all!! at position: " << exitState.tsos().globalPosition();
00123
00124 GlobalTrajectoryParameters gtp( exitState.tsos().globalPosition()+0.01*exitState.tsos().globalMomentum().unit(),
00125 exitState.tsos().globalMomentum(),
00126 exitState.tsos().globalParameters().charge(), theField );
00127
00128 FreeTrajectoryState fts(gtp);
00129 TSOS ShiftedState( fts, exitState.tsos().surface());
00130
00131 TempState = ShiftedState;
00132
00133 LogDebug("NavPropagator") << "Shifted to new position " << TempState.globalPosition();
00134
00135 }
00136
00137
00138
00139
00140
00141 if (isReflected) {
00142
00143
00144 GlobalTrajectoryParameters gtp( GlobalPoint(TempState.globalPosition().x(),
00145 TempState.globalPosition().y(),
00146 -TempState.globalPosition().z()),
00147 GlobalVector(TempState.globalMomentum().x(),
00148 TempState.globalMomentum().y(),
00149 -TempState.globalMomentum().z()),
00150 TempState.globalParameters().charge(), theField );
00151
00152 FreeTrajectoryState fts(gtp);
00153 TSOS ReflectedState( fts, TempState.surface());
00154 TempState = ReflectedState;
00155 isReflected = false;
00156 }
00157
00158 ++count;
00159 if (count > maxCount) {
00160 LogDebug("NavPropagator") << "Ohoh, NavPropagator in infinite loop, count = " << count;
00161 return TsosWP();
00162 }
00163
00164 }
00165
00166
00167
00168
00169
00170
00171 return propagateInVolume( currentVolume, startingState, targetPlane);
00172
00173 }
00174
00175
00176 const NavVolume* NavPropagator::findVolume( const TrajectoryStateOnSurface& inputState) const
00177 {
00178 LogDebug("NavPropagator") << "NavPropagator: calling theField->findVolume ";
00179
00180 GlobalPoint gp = inputState.globalPosition() + 0.1*inputState.globalMomentum().unit();
00181
00182 GlobalPoint gpSym(gp.x(), gp.y(), (gp.z()<0? gp.z() : -gp.z()));
00183
00184 const MagVolume* magVolume = theField->findVolume( gpSym);
00185
00186 LogDebug("NavPropagator") << "NavPropagator: got MagVolume* " << magVolume
00187 << " when searching with pos " << gpSym ;
00188
00189
00190 if (!magVolume) {
00191 cout << "Got invalid volume pointer " << magVolume << " at position " << gpSym;
00192 return 0;
00193 }
00194 return navVolume(magVolume);
00195 }
00196
00197
00198 const NavVolume* NavPropagator::navVolume( const MagVolume* magVolume) const
00199 {
00200 NavVolume* result;
00201 MagVolumeMap::iterator i = theNavVolumeMap.find( magVolume);
00202 if (i == theNavVolumeMap.end()) {
00203
00204
00205
00206 const MagVolume6Faces* pVol6 = dynamic_cast<const MagVolume6Faces*> ( magVolume );
00207 int n=0;
00208 bool isIron=false;
00209 if(pVol6) {
00210 std::stringstream ss(pVol6->name.substr(5));
00211 ss >> n;
00212
00213 } else {
00214 std::cout << "Error (NavVolume6Faces) failed to get MagVolume6Faces pointer" << std::endl;
00215 }
00216 if(n<1 || n>271) {
00217 std::cout << "Error (NavVolume6Faces) unexpected Volume number!" << std::endl;
00218 } else {
00219 isIron = isIronVolume[n];
00220 }
00221
00222 result= new NavVolume6Faces( *magVolume, isIron);
00223 theNavVolumeMap[magVolume] = result;
00224 }
00225 else result = i->second;
00226 return result;
00227 }
00228
00229 std::pair<TrajectoryStateOnSurface,double>
00230 NavPropagator::propagateInVolume( const NavVolume* currentVolume,
00231 const TrajectoryStateOnSurface& startingState,
00232 const Plane& targetPlane) const
00233 {
00234 PropagatorType prop( *currentVolume);
00235
00236
00237 bool isReflected = false;
00238 TSOS okState = startingState;
00239 PlaneBuilder::ReturnType ReflectedPlane;
00240 Plane okPlane = targetPlane;
00241
00242 if (startingState.globalPosition().z()>0 ||
00243 (fabs(startingState.globalPosition().z())<1.e-4 && startingState.globalMomentum().z()>1.e-4)) {
00244 GlobalTrajectoryParameters gtp( GlobalPoint(startingState.globalPosition().x(),
00245 startingState.globalPosition().y(),
00246 -startingState.globalPosition().z()),
00247 GlobalVector(startingState.globalMomentum().x(),
00248 startingState.globalMomentum().y(),
00249 -startingState.globalMomentum().z()),
00250 startingState.globalParameters().charge(), prop.magneticField() );
00251
00252 FreeTrajectoryState fts(gtp);
00253 TSOS ReflectedState( fts, startingState.surface());
00254 okState = ReflectedState;
00255
00256 GlobalVector TempVec = targetPlane.normalVector();
00257 GlobalVector ReflectedVector = GlobalVector ( TempVec.x(), TempVec.y(), -TempVec.z());
00258 GlobalVector zAxis = ReflectedVector.unit();
00259 GlobalVector yAxis( zAxis.y(), -zAxis.x(), 0);
00260 GlobalVector xAxis = yAxis.cross( zAxis);
00261 Surface::RotationType rot = Surface::RotationType( xAxis, yAxis, zAxis);
00262
00263 GlobalPoint gp = targetPlane.position();
00264 GlobalPoint gpSym(gp.x(), gp.y(), -gp.z());
00265 PlaneBuilder pb;
00266 ReflectedPlane = pb.plane( gpSym, rot);
00267
00268 okPlane = *ReflectedPlane;
00269 isReflected = true;
00270 }
00271
00272
00273
00274
00275 TsosWP res = prop.propagateWithPath( okState, okPlane);
00276
00277
00278 if (isReflected && res.first.isValid()) {
00279
00280
00281 TSOS TempState = res.first;
00282 GlobalTrajectoryParameters gtp( GlobalPoint(TempState.globalPosition().x(),
00283 TempState.globalPosition().y(),
00284 -TempState.globalPosition().z()),
00285 GlobalVector(TempState.globalMomentum().x(),
00286 TempState.globalMomentum().y(),
00287 -TempState.globalMomentum().z()),
00288 TempState.globalParameters().charge(), prop.magneticField() );
00289
00290 FreeTrajectoryState fts(gtp);
00291 TSOS ReflectedState( fts, TempState.surface());
00292 res.first = ReflectedState;
00293 isReflected = false;
00294 }
00295
00296
00297 if (res.first.isValid()) {
00298
00299 GlobalPoint gp = res.first.globalPosition();
00300 GlobalPoint gpSym(gp.x(), gp.y(), (gp.z()<0? gp.z() : -gp.z()));
00301
00302 if (currentVolume->inside( gpSym )) {
00303 return res;
00304 }
00305
00306 }
00307
00308
00309 return res;
00310
00311 }
00312
00313 bool NavPropagator::destinationCrossed( const TSOS& startState,
00314 const TSOS& endState, const Plane& plane) const
00315 {
00316 bool res = ( plane.side( startState.globalPosition(), 1.e-6) !=
00317 plane.side( endState.globalPosition(), 1.e-6));
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330 return res;
00331 }
00332
00333 TrajectoryStateOnSurface
00334 NavPropagator::noNextVolume( TrajectoryStateOnSurface startingState) const
00335 {
00336 LogDebug("NavPropagator") << std::endl
00337 << "Propagation reached end of volume geometry without crossing target surface"
00338 << std::endl
00339 << "starting state of last propagation " << startingState;
00340
00341 return TrajectoryStateOnSurface();
00342 }
00343
00344
00345
00346 std::pair<TrajectoryStateOnSurface,double>
00347 NavPropagator::propagateWithPath(const FreeTrajectoryState& fts,
00348 const Cylinder& cylinder) const
00349 {
00350 LogDebug("NavPropagator") << "propagateWithPath(const FreeTrajectoryState&) not implemented yet in NavPropagator" ;
00351 return TsosWP();
00352 }
00353 std::pair<TrajectoryStateOnSurface,double>
00354 NavPropagator::propagateWithPath(const FreeTrajectoryState& fts,
00355 const Plane& cylinder) const
00356 {
00357 LogDebug("NavPropagator") << "propagateWithPath(const FreeTrajectoryState&) not implemented yet in NavPropagator" ;
00358 return TsosWP();
00359 }