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