00001 #include "RecoTracker/CkfPattern/interface/BaseCkfTrajectoryBuilder.h"
00002
00003 #include "RecoTracker/MeasurementDet/interface/MeasurementTracker.h"
00004 #include "RecoTracker/TkDetLayers/interface/GeometricSearchTracker.h"
00005 #include "RecoTracker/TransientTrackingRecHit/interface/TkTransientTrackingRecHitBuilder.h"
00006 #include "TrackingTools/TrajectoryFiltering/interface/TrajectoryFilter.h"
00007
00008
00009 #include "TrackingTools/MeasurementDet/interface/LayerMeasurements.h"
00010 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h"
00011 #include "TrackingTools/GeomPropagators/interface/Propagator.h"
00012 #include "TrackingTools/PatternTools/interface/TrajectoryStateUpdator.h"
00013 #include "TrackingTools/TrajectoryState/interface/BasicSingleTrajectoryState.h"
00014 #include "TrackingTools/KalmanUpdators/interface/Chi2MeasurementEstimatorBase.h"
00015
00016 #include "DataFormats/TrajectorySeed/interface/TrajectorySeed.h"
00017 #include "TrackingTools/PatternTools/interface/TempTrajectory.h"
00018 #include "TrackingTools/PatternTools/interface/Trajectory.h"
00019
00020 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00021
00022
00023 BaseCkfTrajectoryBuilder::
00024 BaseCkfTrajectoryBuilder(const edm::ParameterSet& conf,
00025 const TrajectoryStateUpdator* updator,
00026 const Propagator* propagatorAlong,
00027 const Propagator* propagatorOpposite,
00028 const Chi2MeasurementEstimatorBase* estimator,
00029 const TransientTrackingRecHitBuilder* recHitBuilder,
00030 const MeasurementTracker* measurementTracker,
00031 const TrajectoryFilter* filter,
00032 const TrajectoryFilter* inOutFilter):
00033 theUpdator(updator),
00034 thePropagatorAlong(propagatorAlong),thePropagatorOpposite(propagatorOpposite),
00035 theEstimator(estimator),theTTRHBuilder(recHitBuilder),
00036 theMeasurementTracker(measurementTracker),
00037 theLayerMeasurements(new LayerMeasurements(theMeasurementTracker)),
00038 theForwardPropagator(0),theBackwardPropagator(0),
00039 theFilter(filter),
00040 theInOutFilter(inOutFilter)
00041 {
00042 if (conf.exists("clustersToSkip")){
00043 skipClusters_=true;
00044 clustersToSkip_=conf.getParameter<edm::InputTag>("clustersToSkip");
00045 }
00046 else
00047 skipClusters_=false;
00048 }
00049
00050 BaseCkfTrajectoryBuilder::~BaseCkfTrajectoryBuilder(){
00051 delete theLayerMeasurements;
00052 }
00053
00054
00055 void
00056 BaseCkfTrajectoryBuilder::seedMeasurements(const TrajectorySeed& seed, std::vector<TrajectoryMeasurement> & result) const
00057 {
00058
00059
00060 TrajectorySeed::range hitRange = seed.recHits();
00061 for (TrajectorySeed::const_iterator ihit = hitRange.first;
00062 ihit != hitRange.second; ihit++) {
00063 TransientTrackingRecHit::RecHitPointer recHit = theTTRHBuilder->build(&(*ihit));
00064 const GeomDet* hitGeomDet =
00065 theMeasurementTracker->geomTracker()->idToDet( ihit->geographicalId());
00066
00067 const DetLayer* hitLayer =
00068 theMeasurementTracker->geometricSearchTracker()->detLayer(ihit->geographicalId());
00069
00070 TSOS invalidState( new BasicSingleTrajectoryState( hitGeomDet->surface()));
00071 if (ihit == hitRange.second - 1) {
00072
00073 PTrajectoryStateOnDet pState( seed.startingState());
00074 const GeomDet* gdet = theMeasurementTracker->geomTracker()->idToDet( DetId(pState.detId()));
00075 if (&gdet->surface() != &hitGeomDet->surface()) {
00076 edm::LogError("CkfPattern") << "CkfTrajectoryBuilder error: the seed state is not on the surface of the detector of the last seed hit";
00077 return;
00078 }
00079
00080 TSOS updatedState = trajectoryStateTransform::transientState( pState, &(gdet->surface()),
00081 theForwardPropagator->magneticField());
00082 result.push_back(TM( invalidState, updatedState, recHit, 0, hitLayer));
00083 }
00084 else {
00085 PTrajectoryStateOnDet pState( seed.startingState());
00086
00087 TSOS outerState = trajectoryStateTransform::transientState(pState,
00088 &((theMeasurementTracker->geomTracker()->idToDet(
00089 (hitRange.second - 1)->geographicalId()))->surface()),
00090 theForwardPropagator->magneticField());
00091 TSOS innerState = theBackwardPropagator->propagate(outerState,hitGeomDet->surface());
00092 if(innerState.isValid()) {
00093 TSOS innerUpdated = theUpdator->update(innerState,*recHit);
00094 result.push_back(TM( invalidState, innerUpdated, recHit, 0, hitLayer));
00095 }
00096 }
00097 }
00098
00099
00100 fillSeedHistoDebugger(result.begin(),result.end());
00101
00102 }
00103
00104
00105 TempTrajectory BaseCkfTrajectoryBuilder::
00106 createStartingTrajectory( const TrajectorySeed& seed) const
00107 {
00108 TempTrajectory result( seed, seed.direction());
00109 if ( seed.direction() == alongMomentum) {
00110 theForwardPropagator = &(*thePropagatorAlong);
00111 theBackwardPropagator = &(*thePropagatorOpposite);
00112 }
00113 else {
00114 theForwardPropagator = &(*thePropagatorOpposite);
00115 theBackwardPropagator = &(*thePropagatorAlong);
00116 }
00117
00118 std::vector<TM> seedMeas;
00119 seedMeasurements(seed, seedMeas);
00120 for (std::vector<TM>::const_iterator i=seedMeas.begin(); i!=seedMeas.end(); i++)
00121 result.push(*i);
00122
00123 LogDebug("CkfPattern")
00124 <<" initial trajectory from the seed: "<<PrintoutHelper::dumpCandidate(result,true);
00125
00126 return result;
00127 }
00128
00129
00130 bool BaseCkfTrajectoryBuilder::toBeContinued (TempTrajectory& traj, bool inOut) const
00131 {
00132 if (traj.measurements().size() > 400) {
00133 edm::LogError("BaseCkfTrajectoryBuilder_InfiniteLoop");
00134 LogTrace("BaseCkfTrajectoryBuilder_InfiniteLoop") <<
00135 "Cropping Track After 400 Measurements:\n" <<
00136 " Last predicted state: " << traj.lastMeasurement().predictedState() << "\n" <<
00137 " Last layer subdetector: " << (traj.lastLayer() ? traj.lastLayer()->subDetector() : -1) << "\n" <<
00138 " Found hits: " << traj.foundHits() << ", lost hits: " << traj.lostHits() << "\n\n";
00139 return false;
00140 }
00141
00142
00143 if (inOut) {
00144 if (theInOutFilter == 0) edm::LogError("CkfPattern") << "CkfTrajectoryBuilder error: trying to use dedicated filter for in-out tracking phase, when none specified";
00145 return theInOutFilter->toBeContinued(traj);
00146 } else {
00147 return theFilter->toBeContinued(traj);
00148 }
00149 }
00150
00151
00152 bool BaseCkfTrajectoryBuilder::qualityFilter( const TempTrajectory& traj, bool inOut) const
00153 {
00154
00155
00156 if (inOut) {
00157 if (theInOutFilter == 0) edm::LogError("CkfPattern") << "CkfTrajectoryBuilder error: trying to use dedicated filter for in-out tracking phase, when none specified";
00158 return theInOutFilter->qualityFilter(traj);
00159 } else {
00160 return theFilter->qualityFilter(traj);
00161 }
00162 }
00163
00164
00165 void
00166 BaseCkfTrajectoryBuilder::addToResult (TempTrajectory& tmptraj,
00167 TrajectoryContainer& result,
00168 bool inOut) const
00169 {
00170
00171 if ( !qualityFilter(tmptraj, inOut) ) return;
00172 Trajectory traj = tmptraj.toTrajectory();
00173
00174 while (!traj.empty() && !traj.lastMeasurement().recHit()->isValid()) traj.pop();
00175 LogDebug("CkfPattern")<<inOut<<"=inOut option. pushing a Trajectory with: "<<traj.foundHits()<<" found hits. "<<traj.lostHits()
00176 <<" lost hits. Popped :"<<(tmptraj.measurements().size())-(traj.measurements().size())<<" hits.";
00177 result.push_back( traj);
00178 }
00179 void
00180 BaseCkfTrajectoryBuilder::addToResult (TempTrajectory& tmptraj,
00181 TempTrajectoryContainer& result,
00182 bool inOut) const
00183 {
00184
00185 if ( !qualityFilter(tmptraj, inOut) ) return;
00186
00187 TempTrajectory traj = tmptraj;
00188 while (!traj.empty() && !traj.lastMeasurement().recHit()->isValid()) traj.pop();
00189 LogDebug("CkfPattern")<<inOut<<"=inOut option. pushing a TempTrajectory with: "<<traj.foundHits()<<" found hits. "<<traj.lostHits()
00190 <<" lost hits. Popped :"<<(tmptraj.measurements().size())-(traj.measurements().size())<<" hits.";
00191 result.push_back( traj );
00192 }
00193
00194
00195
00196 BaseCkfTrajectoryBuilder::StateAndLayers
00197 BaseCkfTrajectoryBuilder::findStateAndLayers(const TempTrajectory& traj) const
00198 {
00199 if (traj.empty())
00200 {
00201
00202 PTrajectoryStateOnDet ptod = traj.seed().startingState();
00203 DetId id(ptod.detId());
00204 const GeomDet * g = theMeasurementTracker->geomTracker()->idToDet(id);
00205 const Surface * surface=&g->surface();
00206
00207
00208 TSOS currentState = TrajectoryStateOnSurface(trajectoryStateTransform::transientState(ptod,surface,theForwardPropagator->magneticField()));
00209 const DetLayer* lastLayer = theMeasurementTracker->geometricSearchTracker()->detLayer(id);
00210 return StateAndLayers(currentState,lastLayer->nextLayers( *currentState.freeState(), traj.direction()) );
00211 }
00212 else
00213 {
00214 TSOS currentState = traj.lastMeasurement().updatedState();
00215 return StateAndLayers(currentState,traj.lastLayer()->nextLayers( *currentState.freeState(), traj.direction()) );
00216 }
00217 }
00218
00219 void BaseCkfTrajectoryBuilder::setEvent(const edm::Event& event) const
00220 {
00221 theMeasurementTracker->update(event);
00222 if (skipClusters_)
00223 theMeasurementTracker->setClusterToSkip(clustersToSkip_,event);
00224 }
00225
00226 void BaseCkfTrajectoryBuilder::unset() const
00227 {
00228 if (skipClusters_)
00229 theMeasurementTracker->unsetClusterToSkip();
00230 }