00001 #include "TrackingTools/GeomPropagators/interface/PropagationDirectionFromPath.h"
00002 #include "TrackingTools/MaterialEffects/interface/PropagatorWithMaterial.h"
00003 #include "TrackingTools/GeomPropagators/interface/AnalyticalPropagator.h"
00004 #include "TrackingTools/MaterialEffects/interface/CombinedMaterialEffectsUpdator.h"
00005 #include "FWCore/Utilities/interface/Exception.h"
00006 #include "TrackPropagation/RungeKutta/interface/RKTestPropagator.h"
00007 #include <string>
00008
00009 using namespace std;
00010 PropagatorWithMaterial::PropagatorWithMaterial (PropagationDirection dir,
00011 const float mass,
00012 const MagneticField * mf,
00013 const float maxDPhi,
00014 bool useRungeKutta) :
00015 Propagator(dir),
00016 theGeometricalPropagator(),
00017 theMEUpdator(new CombinedMaterialEffectsUpdator(mass)),
00018 theMaterialLocation(atDestination), field(mf),useRungeKutta_(useRungeKutta) {
00019
00020 if(useRungeKutta_)
00021 theGeometricalPropagator = DeepCopyPointerByClone<Propagator>(new RKTestPropagator(mf,dir));
00022 else theGeometricalPropagator = DeepCopyPointerByClone<Propagator>(new AnalyticalPropagator(mf,dir,maxDPhi));
00023
00024 }
00025
00026 PropagatorWithMaterial::PropagatorWithMaterial (const Propagator& aPropagator,
00027 const MaterialEffectsUpdator& aMEUpdator,
00028 const MagneticField * mf,
00029 bool useRungeKutta) :
00030 Propagator(aPropagator.propagationDirection()),
00031 theGeometricalPropagator(aPropagator.clone()),
00032 theMEUpdator(aMEUpdator.clone()),
00033 theMaterialLocation(atDestination), field(mf),useRungeKutta_(useRungeKutta) {}
00034
00035 pair<TrajectoryStateOnSurface,double>
00036 PropagatorWithMaterial::propagateWithPath (const FreeTrajectoryState& fts,
00037 const Plane& plane) const {
00038 TsosWP newTsosWP = theGeometricalPropagator->propagateWithPath(fts,plane);
00039 if ( !(newTsosWP.first).isValid() || materialAtSource() ) return newTsosWP;
00040 TrajectoryStateOnSurface updatedTSoS =
00041 theMEUpdator->updateState(newTsosWP.first,
00042 PropagationDirectionFromPath()(newTsosWP.second,
00043 propagationDirection()));
00044 return TsosWP(updatedTSoS,newTsosWP.second);
00045 }
00046
00047 pair<TrajectoryStateOnSurface,double>
00048 PropagatorWithMaterial::propagateWithPath (const FreeTrajectoryState& fts,
00049 const Cylinder& cylinder) const {
00050 TsosWP newTsosWP = theGeometricalPropagator->propagateWithPath(fts,cylinder);
00051 if ( !(newTsosWP.first).isValid() || materialAtSource() ) return newTsosWP;
00052 TrajectoryStateOnSurface updatedTSoS =
00053 theMEUpdator->updateState(newTsosWP.first,
00054 PropagationDirectionFromPath()(newTsosWP.second,
00055 propagationDirection()));
00056 return TsosWP(updatedTSoS,newTsosWP.second);
00057 }
00058
00059
00060 pair<TrajectoryStateOnSurface,double>
00061 PropagatorWithMaterial::propagateWithPath (const TrajectoryStateOnSurface& tsos,
00062 const Plane& plane) const {
00063
00064
00065
00066 TrajectoryStateOnSurface stateAtSource;
00067 if ( materialAtSource() )
00068 stateAtSource = theMEUpdator->updateState(tsos,propagationDirection());
00069 else
00070 stateAtSource = tsos;
00071 if ( !stateAtSource.isValid() ) return TsosWP(stateAtSource,0.);
00072
00073
00074
00075 TsosWP newTsosWP = theGeometricalPropagator->propagateWithPath(stateAtSource,plane);
00076 if ( !(newTsosWP.first).isValid() || materialAtSource() ) return newTsosWP;
00077
00078
00079
00080 TrajectoryStateOnSurface updatedTSoS =
00081 theMEUpdator->updateState(newTsosWP.first,
00082 PropagationDirectionFromPath()(newTsosWP.second,
00083 propagationDirection()));
00084 return TsosWP(updatedTSoS,newTsosWP.second);
00085 }
00086
00087 pair<TrajectoryStateOnSurface,double>
00088 PropagatorWithMaterial::propagateWithPath (const TrajectoryStateOnSurface& tsos,
00089 const Cylinder& cylinder) const {
00090
00091
00092
00093 TrajectoryStateOnSurface stateAtSource;
00094 if ( materialAtSource() )
00095 stateAtSource = theMEUpdator->updateState(tsos,propagationDirection());
00096 else
00097 stateAtSource = tsos;
00098 if ( !stateAtSource.isValid() ) return TsosWP(stateAtSource,0.);
00099
00100
00101
00102 TsosWP newTsosWP = theGeometricalPropagator->propagateWithPath(stateAtSource,cylinder);
00103 if ( !(newTsosWP.first).isValid() || materialAtSource() ) return newTsosWP;
00104
00105
00106
00107 TrajectoryStateOnSurface updatedTSoS =
00108 theMEUpdator->updateState(newTsosWP.first,
00109 PropagationDirectionFromPath()(newTsosWP.second,
00110 propagationDirection()));
00111 return TsosWP(updatedTSoS,newTsosWP.second);
00112 }
00113
00114 void PropagatorWithMaterial::setPropagationDirection (PropagationDirection dir) {
00115 theGeometricalPropagator->setPropagationDirection(dir);
00116 Propagator::setPropagationDirection(dir);
00117 }
00118
00119 bool
00120 PropagatorWithMaterial::materialAtSource() const {
00121 if ( propagationDirection()==anyDirection ) {
00122 if ( theMaterialLocation!=atDestination ) {
00123 string message("PropagatorWithMaterial: propagation direction = anyDirection is ");
00124 message += "incompatible with adding of material at source";
00125 throw cms::Exception("TrackingTools/MaterialEffects",message);
00126 }
00127 }
00128 return theMaterialLocation==atSource || (theMaterialLocation==fromDirection&&
00129 propagationDirection()==alongMomentum);
00130 }