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