CMS 3D CMS Logo

NavPropagator.cc

Go to the documentation of this file.
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 // magVolume6Faces needed to get access to volume name and material:
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   //FIXME: iron volumes are hard-coded below... will change with new .xml geometry MM 28/6/07
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   //  for(int i=1; i<272 ; i++) {
00031   //  if(isIronVolume[i]) std::cout << "Volume no." << i << " is made of iron " << std::endl;
00032   //  if(!isIronVolume[i]) std::cout << "Volume no." << i << " is made of air " << std::endl;
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; // explicit initialization to get rid of compiler warning
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) { // next volume connected
00067       currentVolume = exitState.volume();
00068     }
00069     else {
00070       // 1 mm shifted peek is necessary only because geometry is not yet glued and exists only for z<0
00071       GlobalPoint gp = startingState.globalPosition() + 0.1*startingState.globalMomentum().unit();
00072 
00073       if (gp.z()>0) { // Reflect in Z (as long as MagVolumes exist only for 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       // return propagateInVolume( currentVolume, startingState, targetPlane);
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       //      exitState.tsos() = ShiftedState;
00131       TempState = ShiftedState;
00132 
00133       LogDebug("NavPropagator") <<  "Shifted to new position " << TempState.globalPosition();
00134 
00135     }
00136 
00137 
00138     // std::cout << "Just moved " << exitState.path() << " cm through " << ( currentVolume->isIron()? "IRON":"AIR" ); 
00139     // std::cout << " at radius: " << TempState.globalPosition().perp() << std::endl;
00140     // reflect back to normal universe if necessary:
00141     if (isReflected) { // reflect back... nobody should know we secretely z-reflected the tsos 
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   // Arriving here only if destinationCrossed or if crossToNextVolume returned invalid state,
00169   // in which case we should check if the targetPlane is not crossed in the current volume
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   // Next protection only needed when 1 mm linear move crosses the z==0 plane:
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     // Create a NavVolume from a MagVolume if the NavVolume doesn't exist yet
00204     // FIXME: hardcoded iron/air classification should be made into something more general
00205     // will break with new magnetic field volume .xml file MM 28/6/07
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       //      std::cout << " Found volume with number " << n << std::endl;
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   // OK, fix is rather ugly for now: need to reflect z>0 states to z<0 MM 25/6/07
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   // Done Reflecting
00273 
00274 
00275   TsosWP res = prop.propagateWithPath( okState, okPlane);
00276 
00277   // Now reflect back the result if necessary...
00278   if (isReflected && res.first.isValid()) { // reflect back... nobody should know we secretely z-reflected the tsos 
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   // Done Reflecting back !
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     // sometimes fails when propagation on plane and surface are less than 0.1 mm apart... 
00306   } 
00307 
00308   //  return TsosWP( TrajectoryStateOnSurface(), 0); // Gives 'double free' errors... return res even when Outside volume... 
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    LogDebug("NavPropagator") <<  "NavPropagator::destinationCrossed called with startState "
00320        << startState << std::endl
00321        << " endState " << endState 
00322        << std::endl
00323        << " plane at " << plane.position()
00324        << std::endl;
00325 
00326    LogDebug("NavPropagator") <<  "plane.side( startState) " << plane.side( startState.globalPosition(), 1.e-6);
00327    LogDebug("NavPropagator") <<  "plane.side( endState)   " << plane.side( endState.globalPosition(), 1.e-6);
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 }

Generated on Tue Jun 9 17:48:42 2009 for CMSSW by  doxygen 1.5.4