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