00001
00002 #include "TwoBodyDecayTrajectoryFactory.h"
00003 #include "TrackingTools/TrajectoryState/interface/FreeTrajectoryState.h"
00004 #include "DataFormats/GeometrySurface/interface/Surface.h"
00005 #include "DataFormats/CLHEP/interface/AlgebraicObjects.h"
00006 #include "DataFormats/Math/interface/Vector.h"
00007 #include "DataFormats/Math/interface/Error.h"
00008 #include "TrackingTools/TrajectoryState/interface/CopyUsingClone.h"
00009 #include "RecoVertex/VertexTools/interface/PerigeeLinearizedTrackState.h"
00010 #include "Alignment/ReferenceTrajectories/interface/TrajectoryFactoryPlugin.h"
00011
00012 #include "TrackingTools/TransientTrack/interface/TransientTrack.h"
00013
00014 #include "DataFormats/GeometryCommonDetAlgo/interface/ErrorFrameTransformer.h"
00015 #include "DataFormats/TrackingRecHit/interface/AlignmentPositionError.h"
00016
00017 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00018
00019 #include "FWCore/Framework/interface/ESHandle.h"
00020 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00021
00022
00023 TwoBodyDecayTrajectoryFactory::TwoBodyDecayTrajectoryFactory( const edm::ParameterSet& config )
00024 : TrajectoryFactoryBase( config ),
00025 theFitter( new TwoBodyDecayFitter( config ) ),
00026 theNSigmaCutValue( config.getParameter< double >( "NSigmaCut" ) ),
00027 theUseRefittedStateFlag( config.getParameter< bool >( "UseRefittedState" ) ),
00028 theConstructTsosWithErrorsFlag( config.getParameter< bool >( "ConstructTsosWithErrors" ) )
00029 {
00030 produceVirtualMeasurement( config );
00031 }
00032
00033
00034 const TrajectoryFactoryBase::ReferenceTrajectoryCollection
00035 TwoBodyDecayTrajectoryFactory::trajectories( const edm::EventSetup& setup,
00036 const ConstTrajTrackPairCollection& tracks ) const
00037 {
00038 ReferenceTrajectoryCollection trajectories;
00039
00040 edm::ESHandle< MagneticField > magneticField;
00041 setup.get< IdealMagneticFieldRecord >().get( magneticField );
00042
00043 if ( tracks.size() == 2 )
00044 {
00045
00046 std::vector< reco::TransientTrack > transientTracks( 2 );
00047
00048 transientTracks[0] = reco::TransientTrack( *tracks[0].second, magneticField.product() );
00049 transientTracks[0].setES( setup );
00050
00051 transientTracks[1] = reco::TransientTrack( *tracks[1].second, magneticField.product() );
00052 transientTracks[1].setES( setup );
00053
00054
00055 TwoBodyDecay tbd = theFitter->estimate( transientTracks, theVM );
00056
00057 if ( !tbd.isValid() )
00058 {
00059 trajectories.push_back( ReferenceTrajectoryPtr( new TwoBodyDecayTrajectory() ) );
00060 return trajectories;
00061 }
00062
00063 return constructTrajectories( tracks, tbd, magneticField.product(), false );
00064 }
00065 else
00066 {
00067 edm::LogInfo( "ReferenceTrajectories" ) << "@SUB=TwoBodyDecayTrajectoryFactory::trajectories"
00068 << "Need 2 tracks, got " << tracks.size() << ".\n";
00069 }
00070
00071 return trajectories;
00072 }
00073
00074
00075 const TrajectoryFactoryBase::ReferenceTrajectoryCollection
00076 TwoBodyDecayTrajectoryFactory::trajectories( const edm::EventSetup& setup,
00077 const ConstTrajTrackPairCollection& tracks,
00078 const ExternalPredictionCollection& external ) const
00079 {
00080 ReferenceTrajectoryCollection trajectories;
00081
00082 edm::ESHandle< MagneticField > magneticField;
00083 setup.get< IdealMagneticFieldRecord >().get( magneticField );
00084
00085 if ( tracks.size() == 2 && external.size() == 2 )
00086 {
00087 if ( external[0].isValid() && external[1].isValid() )
00088 {
00089
00090 std::vector< reco::TransientTrack > transientTracks( 2 );
00091
00092 transientTracks[0] = reco::TransientTrack( *tracks[0].second, magneticField.product() );
00093 transientTracks[0].setES( setup );
00094
00095 transientTracks[1] = reco::TransientTrack( *tracks[1].second, magneticField.product() );
00096 transientTracks[1].setES( setup );
00097
00098
00099
00100
00101 TwoBodyDecay tbd = theFitter->estimate( transientTracks, external, theVM );
00102
00103 if ( !tbd.isValid() )
00104 {
00105 trajectories.push_back( ReferenceTrajectoryPtr( new TwoBodyDecayTrajectory() ) );
00106 return trajectories;
00107 }
00108
00109 return constructTrajectories( tracks, tbd, magneticField.product(), true );
00110 }
00111 else
00112 {
00113
00114 trajectories = this->trajectories( setup, tracks );
00115 }
00116 }
00117 else
00118 {
00119 edm::LogInfo( "ReferenceTrajectories" ) << "@SUB=TwoBodyDecayTrajectoryFactory::trajectories"
00120 << "Need 2 tracks, got " << tracks.size() << ".\n";
00121 }
00122
00123 return trajectories;
00124 }
00125
00126
00127 const TwoBodyDecayTrajectoryFactory::ReferenceTrajectoryCollection
00128 TwoBodyDecayTrajectoryFactory::constructTrajectories( const ConstTrajTrackPairCollection& tracks,
00129 const TwoBodyDecay& tbd,
00130 const MagneticField* magField,
00131 bool setParameterErrors ) const
00132 {
00133 ReferenceTrajectoryCollection trajectories;
00134
00135
00136 TrajectoryInput input1 = this->innermostStateAndRecHits( tracks[0] );
00137 TrajectoryInput input2 = this->innermostStateAndRecHits( tracks[1] );
00138
00139 if ( !( input1.first.isValid() && input2.first.isValid() ) ) return trajectories;
00140
00141
00142 TsosContainer tsos( input1.first, input2.first );
00143 ConstRecHitCollection recHits( input1.second, input2.second );
00144 TwoBodyDecayTrajectoryState trajectoryState( tsos, tbd, theVM.secondaryMass(), magField );
00145
00146 if ( !trajectoryState.isValid() )
00147 {
00148 trajectories.push_back( ReferenceTrajectoryPtr( new TwoBodyDecayTrajectory() ) );
00149 return trajectories;
00150 }
00151
00152
00153 TransientTrackingRecHit::ConstRecHitPointer updatedRecHit1( recHits.first.front()->clone( tsos.first ) );
00154 bool valid1 = match( trajectoryState.trajectoryStates( true ).first,
00155 updatedRecHit1 );
00156
00157 TransientTrackingRecHit::ConstRecHitPointer updatedRecHit2( recHits.second.front()->clone( tsos.second ) );
00158 bool valid2 = match( trajectoryState.trajectoryStates( true ).second,
00159 updatedRecHit2 );
00160
00161 if ( !valid1 || !valid2 )
00162 {
00163 trajectories.push_back( ReferenceTrajectoryPtr( new TwoBodyDecayTrajectory() ) );
00164 return trajectories;
00165 }
00166
00167
00168 TwoBodyDecayTrajectory* result = new TwoBodyDecayTrajectory( trajectoryState, recHits, magField,
00169 materialEffects(), propagationDirection(),
00170 false, theUseRefittedStateFlag,
00171 theConstructTsosWithErrorsFlag );
00172 if ( setParameterErrors && tbd.hasError() ) result->setParameterErrors( tbd.covariance() );
00173 trajectories.push_back( ReferenceTrajectoryPtr( result ) );
00174 return trajectories;
00175 }
00176
00177
00178 bool TwoBodyDecayTrajectoryFactory::match( const TrajectoryStateOnSurface& state,
00179 const TransientTrackingRecHit::ConstRecHitPointer& recHit ) const
00180 {
00181 LocalPoint lp1 = state.localPosition();
00182 LocalPoint lp2 = recHit->localPosition();
00183
00184 double deltaX = lp1.x() - lp2.x();
00185 double deltaY = lp1.y() - lp2.y();
00186
00187 LocalError le = recHit->localPositionError();
00188
00189 double varX = le.xx();
00190 double varY = le.yy();
00191
00192 AlignmentPositionError* gape = recHit->det()->alignmentPositionError();
00193 if ( gape )
00194 {
00195 ErrorFrameTransformer eft;
00196 LocalError lape = eft.transform( gape->globalError(), recHit->det()->surface() );
00197
00198 varX += lape.xx();
00199 varY += lape.yy();
00200 }
00201
00202 return ( ( fabs(deltaX)/sqrt(varX) < theNSigmaCutValue ) && ( fabs(deltaY)/sqrt(varY) < theNSigmaCutValue ) );
00203 }
00204
00205
00206 void TwoBodyDecayTrajectoryFactory::produceVirtualMeasurement( const edm::ParameterSet& config )
00207 {
00208 const edm::ParameterSet bsc = config.getParameter< edm::ParameterSet >( "BeamSpot" );
00209 const edm::ParameterSet ppc = config.getParameter< edm::ParameterSet >( "ParticleProperties" );
00210
00211 theBeamSpot = GlobalPoint( bsc.getParameter< double >( "MeanX" ),
00212 bsc.getParameter< double >( "MeanY" ),
00213 bsc.getParameter< double >( "MeanZ" ) );
00214
00215 theBeamSpotError = GlobalError( bsc.getParameter< double >( "VarXX" ),
00216 bsc.getParameter< double >( "VarXY" ),
00217 bsc.getParameter< double >( "VarYY" ),
00218 bsc.getParameter< double >( "VarXZ" ),
00219 bsc.getParameter< double >( "VarYZ" ),
00220 bsc.getParameter< double >( "VarZZ" ) );
00221
00222 theVM = VirtualMeasurement( ppc.getParameter< double >( "PrimaryMass" ),
00223 ppc.getParameter< double >( "PrimaryWidth" ),
00224 ppc.getParameter< double >( "SecondaryMass" ),
00225 theBeamSpot, theBeamSpotError );
00226 return;
00227 }
00228
00229
00230 DEFINE_EDM_PLUGIN( TrajectoryFactoryPlugin, TwoBodyDecayTrajectoryFactory, "TwoBodyDecayTrajectoryFactory" );