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