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
00012 #include "DualTrajectoryFactory.h"
00013 #include "Alignment/ReferenceTrajectories/interface/DualReferenceTrajectory.h"
00014
00015
00016 DualTrajectoryFactory::DualTrajectoryFactory( const edm::ParameterSet & config ) :
00017 TrajectoryFactoryBase( config )
00018 {
00019 theMass = config.getParameter< double >( "ParticleMass" );
00020 }
00021
00022
00023 DualTrajectoryFactory::~DualTrajectoryFactory( void ) {}
00024
00025
00026 const DualTrajectoryFactory::ReferenceTrajectoryCollection
00027 DualTrajectoryFactory::trajectories( const edm::EventSetup & setup,
00028 const ConstTrajTrackPairCollection & tracks ) const
00029 {
00030 ReferenceTrajectoryCollection trajectories;
00031
00032 edm::ESHandle< MagneticField > magneticField;
00033 setup.get< IdealMagneticFieldRecord >().get( magneticField );
00034
00035 ConstTrajTrackPairCollection::const_iterator itTracks = tracks.begin();
00036
00037 while ( itTracks != tracks.end() )
00038 {
00039 const DualTrajectoryInput input = this->referenceStateAndRecHits( *itTracks );
00040
00041 if ( input.refTsos.isValid() )
00042 {
00043 ReferenceTrajectoryPtr ptr( new DualReferenceTrajectory( input.refTsos,
00044 input.fwdRecHits,
00045 input.bwdRecHits,
00046 magneticField.product(),
00047 materialEffects(),
00048 propagationDirection(),
00049 theMass ) );
00050 trajectories.push_back( ptr );
00051 }
00052
00053 ++itTracks;
00054 }
00055
00056 return trajectories;
00057 }
00058
00059 const DualTrajectoryFactory::ReferenceTrajectoryCollection
00060 DualTrajectoryFactory::trajectories( const edm::EventSetup & setup,
00061 const ConstTrajTrackPairCollection& tracks,
00062 const ExternalPredictionCollection& external ) const
00063 {
00064 ReferenceTrajectoryCollection trajectories;
00065
00066 if ( tracks.size() != external.size() )
00067 {
00068 edm::LogInfo("ReferenceTrajectories") << "@SUB=DualTrajectoryFactory::trajectories"
00069 << "Inconsistent input:\n"
00070 << "\tnumber of tracks = " << tracks.size()
00071 << "\tnumber of external predictions = " << external.size();
00072 return trajectories;
00073 }
00074
00075 edm::ESHandle< MagneticField > magneticField;
00076 setup.get< IdealMagneticFieldRecord >().get( magneticField );
00077
00078 ConstTrajTrackPairCollection::const_iterator itTracks = tracks.begin();
00079 ExternalPredictionCollection::const_iterator itExternal = external.begin();
00080
00081 while ( itTracks != tracks.end() )
00082 {
00083 const DualTrajectoryInput input = referenceStateAndRecHits( *itTracks );
00084
00085 if ( input.refTsos.isValid() )
00086 {
00087 if ( (*itExternal).isValid() )
00088 {
00089 TrajectoryStateOnSurface propExternal =
00090 propagateExternal( *itExternal, input.refTsos.surface(), magneticField.product() );
00091
00092 if ( !propExternal.isValid() ) continue;
00093
00094
00095 ReferenceTrajectoryPtr ptr( new DualReferenceTrajectory( propExternal,
00096 input.fwdRecHits,
00097 input.bwdRecHits,
00098 magneticField.product(),
00099 materialEffects(),
00100 propagationDirection(),
00101 theMass ) );
00102
00103 AlgebraicSymMatrix externalParamErrors( asHepMatrix<5>( propExternal.localError().matrix() ) );
00104 ptr->setParameterErrors( externalParamErrors );
00105 trajectories.push_back( ptr );
00106 }
00107 else
00108 {
00109 ReferenceTrajectoryPtr ptr( new DualReferenceTrajectory( input.refTsos,
00110 input.fwdRecHits,
00111 input.bwdRecHits,
00112 magneticField.product(),
00113 materialEffects(),
00114 propagationDirection(),
00115 theMass ) );
00116 trajectories.push_back( ptr );
00117 }
00118 }
00119
00120 ++itTracks;
00121 ++itExternal;
00122 }
00123
00124 return trajectories;
00125 }
00126
00127
00128 const DualTrajectoryFactory::DualTrajectoryInput
00129 DualTrajectoryFactory::referenceStateAndRecHits( const ConstTrajTrackPair& track ) const
00130 {
00131 DualTrajectoryInput input;
00132
00133
00134 Trajectory::DataContainer allTrajMeas = this->orderedTrajectoryMeasurements( *track.first );
00135 Trajectory::DataContainer usedTrajMeas;
00136 Trajectory::DataContainer::iterator itM;
00137
00138 for ( itM = allTrajMeas.begin(); itM != allTrajMeas.end(); itM++ )
00139 {
00140 if ( useRecHit( ( *itM ).recHit() ) ) usedTrajMeas.push_back( *itM );
00141 }
00142
00143 unsigned int iMeas = 0;
00144 unsigned int nMeas = usedTrajMeas.size();
00145 unsigned int nRefStateMeas = nMeas/2;
00146
00147 for ( itM = usedTrajMeas.begin(); itM != usedTrajMeas.end(); itM++, iMeas++ )
00148 {
00149 TransientTrackingRecHit::ConstRecHitPointer aRecHit = ( *itM ).recHit();
00150
00151 if ( iMeas < nRefStateMeas ) {
00152 input.bwdRecHits.push_back( aRecHit );
00153 } else if ( iMeas > nRefStateMeas ) {
00154 input.fwdRecHits.push_back( aRecHit );
00155 } else {
00156 if ( ( *itM ).updatedState().isValid() )
00157 {
00158 input.refTsos = ( *itM ).updatedState();
00159 input.bwdRecHits.push_back( aRecHit );
00160 input.fwdRecHits.push_back( aRecHit );
00161 } else {
00162
00163 nRefStateMeas++;
00164 input.bwdRecHits.push_back( aRecHit );
00165 }
00166 }
00167 }
00168
00169
00170 std::reverse( input.bwdRecHits.begin(), input.bwdRecHits.end() );
00171
00172 return input;
00173 }
00174
00175 const TrajectoryStateOnSurface
00176 DualTrajectoryFactory::propagateExternal( const TrajectoryStateOnSurface& external,
00177 const Surface& surface,
00178 const MagneticField* magField ) const
00179 {
00180 AnalyticalPropagator propagator( magField, anyDirection );
00181 const std::pair< TrajectoryStateOnSurface, double > tsosWithPath =
00182 propagator.propagateWithPath( external, surface );
00183 return tsosWithPath.first;
00184 }
00185
00186
00187 DEFINE_EDM_PLUGIN( TrajectoryFactoryPlugin, DualTrajectoryFactory, "DualTrajectoryFactory" );