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