00001 #include "FWCore/Framework/interface/ESHandle.h"
00002 #include "FWCore/Framework/interface/EventSetup.h"
00003 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00004 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00005 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00006 #include "Alignment/ReferenceTrajectories/interface/TrajectoryFactoryPlugin.h"
00007 #include "TrackingTools/GeomPropagators/interface/AnalyticalPropagator.h"
00008
00009 #include <algorithm>
00010
00011 #include "Alignment/ReferenceTrajectories/interface/DualReferenceTrajectory.h"
00012 #include "Alignment/ReferenceTrajectories/interface/TrajectoryFactoryBase.h"
00013
00015
00016
00017 class DualTrajectoryFactory : public TrajectoryFactoryBase
00018 {
00019 public:
00020 DualTrajectoryFactory(const edm::ParameterSet &config);
00021 virtual ~DualTrajectoryFactory();
00022
00024 virtual const ReferenceTrajectoryCollection trajectories(const edm::EventSetup &setup,
00025 const ConstTrajTrackPairCollection &tracks,
00026 const reco::BeamSpot &beamSpot) const;
00027
00028 virtual const ReferenceTrajectoryCollection trajectories(const edm::EventSetup &setup,
00029 const ConstTrajTrackPairCollection &tracks,
00030 const ExternalPredictionCollection &external,
00031 const reco::BeamSpot &beamSpot) const;
00032
00033 virtual DualTrajectoryFactory* clone() const { return new DualTrajectoryFactory(*this); }
00034
00035 protected:
00036 struct DualTrajectoryInput
00037 {
00038 TrajectoryStateOnSurface refTsos;
00039 TransientTrackingRecHit::ConstRecHitContainer fwdRecHits;
00040 TransientTrackingRecHit::ConstRecHitContainer bwdRecHits;
00041 };
00042
00043 const DualTrajectoryInput referenceStateAndRecHits(const ConstTrajTrackPair &track) const;
00044
00045 const TrajectoryStateOnSurface propagateExternal(const TrajectoryStateOnSurface &external,
00046 const Surface &surface,
00047 const MagneticField *magField) const;
00048
00049 double theMass;
00050 };
00051
00055
00056 DualTrajectoryFactory::DualTrajectoryFactory( const edm::ParameterSet & config ) :
00057 TrajectoryFactoryBase( config )
00058 {
00059 theMass = config.getParameter< double >( "ParticleMass" );
00060 }
00061
00062
00063 DualTrajectoryFactory::~DualTrajectoryFactory( void ) {}
00064
00065
00066 const DualTrajectoryFactory::ReferenceTrajectoryCollection
00067 DualTrajectoryFactory::trajectories(const edm::EventSetup &setup,
00068 const ConstTrajTrackPairCollection &tracks,
00069 const reco::BeamSpot &beamSpot) const
00070 {
00071 ReferenceTrajectoryCollection trajectories;
00072
00073 edm::ESHandle< MagneticField > magneticField;
00074 setup.get< IdealMagneticFieldRecord >().get( magneticField );
00075
00076 ConstTrajTrackPairCollection::const_iterator itTracks = tracks.begin();
00077
00078 while ( itTracks != tracks.end() )
00079 {
00080 const DualTrajectoryInput input = this->referenceStateAndRecHits( *itTracks );
00081
00082 if ( input.refTsos.isValid() )
00083 {
00084 ReferenceTrajectoryPtr ptr( new DualReferenceTrajectory( input.refTsos,
00085 input.fwdRecHits,
00086 input.bwdRecHits,
00087 magneticField.product(),
00088 materialEffects(),
00089 propagationDirection(),
00090 theMass,
00091 theUseBeamSpot, beamSpot ) );
00092 trajectories.push_back( ptr );
00093 }
00094
00095 ++itTracks;
00096 }
00097
00098 return trajectories;
00099 }
00100
00101 const DualTrajectoryFactory::ReferenceTrajectoryCollection
00102 DualTrajectoryFactory::trajectories(const edm::EventSetup &setup,
00103 const ConstTrajTrackPairCollection &tracks,
00104 const ExternalPredictionCollection &external,
00105 const reco::BeamSpot &beamSpot) const
00106 {
00107 ReferenceTrajectoryCollection trajectories;
00108
00109 if ( tracks.size() != external.size() )
00110 {
00111 edm::LogInfo("ReferenceTrajectories") << "@SUB=DualTrajectoryFactory::trajectories"
00112 << "Inconsistent input:\n"
00113 << "\tnumber of tracks = " << tracks.size()
00114 << "\tnumber of external predictions = " << external.size();
00115 return trajectories;
00116 }
00117
00118 edm::ESHandle< MagneticField > magneticField;
00119 setup.get< IdealMagneticFieldRecord >().get( magneticField );
00120
00121 ConstTrajTrackPairCollection::const_iterator itTracks = tracks.begin();
00122 ExternalPredictionCollection::const_iterator itExternal = external.begin();
00123
00124 while ( itTracks != tracks.end() )
00125 {
00126 const DualTrajectoryInput input = referenceStateAndRecHits( *itTracks );
00127
00128 if ( input.refTsos.isValid() )
00129 {
00130 if ( (*itExternal).isValid() )
00131 {
00132 TrajectoryStateOnSurface propExternal =
00133 propagateExternal( *itExternal, input.refTsos.surface(), magneticField.product() );
00134
00135 if ( !propExternal.isValid() ) continue;
00136
00137
00138 ReferenceTrajectoryPtr ptr( new DualReferenceTrajectory( propExternal,
00139 input.fwdRecHits,
00140 input.bwdRecHits,
00141 magneticField.product(),
00142 materialEffects(),
00143 propagationDirection(),
00144 theMass,
00145 theUseBeamSpot, beamSpot ) );
00146
00147 AlgebraicSymMatrix externalParamErrors( asHepMatrix<5>( propExternal.localError().matrix() ) );
00148 ptr->setParameterErrors( externalParamErrors );
00149 trajectories.push_back( ptr );
00150 }
00151 else
00152 {
00153 ReferenceTrajectoryPtr ptr( new DualReferenceTrajectory( input.refTsos,
00154 input.fwdRecHits,
00155 input.bwdRecHits,
00156 magneticField.product(),
00157 materialEffects(),
00158 propagationDirection(),
00159 theMass,
00160 theUseBeamSpot, beamSpot ) );
00161 trajectories.push_back( ptr );
00162 }
00163 }
00164
00165 ++itTracks;
00166 ++itExternal;
00167 }
00168
00169 return trajectories;
00170 }
00171
00172
00173 const DualTrajectoryFactory::DualTrajectoryInput
00174 DualTrajectoryFactory::referenceStateAndRecHits( const ConstTrajTrackPair& track ) const
00175 {
00176 DualTrajectoryInput input;
00177
00178
00179 Trajectory::DataContainer allTrajMeas = this->orderedTrajectoryMeasurements( *track.first );
00180 Trajectory::DataContainer usedTrajMeas;
00181 Trajectory::DataContainer::iterator itM;
00182
00183 for ( itM = allTrajMeas.begin(); itM != allTrajMeas.end(); itM++ )
00184 {
00185 if ( useRecHit( ( *itM ).recHit() ) ) usedTrajMeas.push_back( *itM );
00186 }
00187
00188 unsigned int iMeas = 0;
00189 unsigned int nMeas = usedTrajMeas.size();
00190 unsigned int nRefStateMeas = nMeas/2;
00191
00192 for ( itM = usedTrajMeas.begin(); itM != usedTrajMeas.end(); itM++, iMeas++ )
00193 {
00194 TransientTrackingRecHit::ConstRecHitPointer aRecHit = ( *itM ).recHit();
00195
00196 if ( iMeas < nRefStateMeas ) {
00197 input.bwdRecHits.push_back( aRecHit );
00198 } else if ( iMeas > nRefStateMeas ) {
00199 input.fwdRecHits.push_back( aRecHit );
00200 } else {
00201 if ( ( *itM ).updatedState().isValid() )
00202 {
00203 input.refTsos = ( *itM ).updatedState();
00204 input.bwdRecHits.push_back( aRecHit );
00205 input.fwdRecHits.push_back( aRecHit );
00206 } else {
00207
00208 nRefStateMeas++;
00209 input.bwdRecHits.push_back( aRecHit );
00210 }
00211 }
00212 }
00213
00214
00215 std::reverse( input.bwdRecHits.begin(), input.bwdRecHits.end() );
00216
00217 return input;
00218 }
00219
00220 const TrajectoryStateOnSurface
00221 DualTrajectoryFactory::propagateExternal( const TrajectoryStateOnSurface& external,
00222 const Surface& surface,
00223 const MagneticField* magField ) const
00224 {
00225 AnalyticalPropagator propagator( magField, anyDirection );
00226 const std::pair< TrajectoryStateOnSurface, double > tsosWithPath =
00227 propagator.propagateWithPath( external, surface );
00228 return tsosWithPath.first;
00229 }
00230
00231
00232 DEFINE_EDM_PLUGIN( TrajectoryFactoryPlugin, DualTrajectoryFactory, "DualTrajectoryFactory" );