00001 #include "TrackingTools/TrackFitters/interface/KFFittingSmoother.h"
00002 #include "TrackingTools/MaterialEffects/interface/PropagatorWithMaterial.h"
00003 #include "TrackingTools/KalmanUpdators/interface/KFUpdator.h"
00004 #include "TrackingTools/TrackFitters/interface/KFTrajectoryFitter.h"
00005 #include "TrackingTools/TrackFitters/interface/KFTrajectorySmoother.h"
00006 #include "TrackingTools/GeomPropagators/interface/AnalyticalPropagator.h"
00007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00008 #include "TrackingTools/TransientTrackingRecHit/interface/InvalidTransientRecHit.h"
00009
00010 using namespace std;
00011
00012 KFFittingSmoother::~KFFittingSmoother() {
00013 delete theSmoother;
00014 delete theFitter;
00015 }
00016
00017
00018 vector<Trajectory>
00019 KFFittingSmoother::fit(const Trajectory& t) const {
00020 vector<Trajectory> smoothed;
00021 if(t.isValid()) {
00022 vector<Trajectory> fitted = fitter()->fit(t);
00023 smoothingStep(fitted, smoothed);
00024 }
00025 return smoothed;
00026 }
00027
00028 vector<Trajectory> KFFittingSmoother::
00029 fit(const TrajectorySeed& aSeed,
00030 const RecHitContainer& hits,
00031 const TrajectoryStateOnSurface& firstPredTsos) const
00032 {
00033 LogDebug("TrackFitters") << "In KFFittingSmoother::fit";
00034
00035
00036
00037 bool hasoutliers;
00038 RecHitContainer myHits = hits;
00039 vector<Trajectory> smoothed;
00040 vector<Trajectory> tmp_first;
00041
00042 do{
00043 if(hits.empty()) { smoothed.clear(); break; }
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 hasoutliers = false;
00055 double cut = theEstimateCut;
00056 unsigned int outlierId = 0;
00057 const GeomDet* outlierDet = 0;
00058
00059
00060 vector<Trajectory> fitted = fitter()->fit(aSeed, myHits, firstPredTsos);
00061
00062 smoothed.clear();
00063 smoothingStep(fitted, smoothed);
00064
00065
00066
00067 if (smoothed.empty()) {
00068 if (rejectTracksFlag){
00069 LogTrace("TrackFitters") << "smoothed.size()==0 => trajectory rejected";
00070
00071 } else {
00072 LogTrace("TrackFitters") << "smoothed.size()==0 => returning orignal trajectory" ;
00073 smoothed.swap(tmp_first);
00074 }
00075 break;
00076 }
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 if (theEstimateCut>0) {
00087 if (smoothed[0].foundHits()<theMinNumberOfHits) {
00088 if (rejectTracksFlag){
00089 LogTrace("TrackFitters") << "smoothed[0].foundHits()<theMinNumberOfHits => trajectory rejected";
00090 smoothed.clear();
00091
00092 } else {
00093
00094 if (!tmp_first.empty()) { tmp_first.swap(smoothed); }
00095 LogTrace("TrackFitters")
00096 << "smoothed[0].foundHits()<theMinNumberOfHits => returning orignal trajectory with chi2="
00097 << smoothed[0].chiSquared() ;
00098 }
00099 break;
00100 }
00101
00102 const std::vector<TrajectoryMeasurement> & vtm = smoothed[0].measurements();
00103 for (std::vector<TrajectoryMeasurement>::const_iterator tm=vtm.begin(); tm!=vtm.end();tm++){
00104 double estimate = tm->estimate();
00105 if (estimate > cut) {
00106 hasoutliers = true;
00107 cut = estimate;
00108 outlierId = tm->recHit()->geographicalId().rawId();
00109 outlierDet = tm->recHit()->det();
00110 }
00111 }
00112 if (hasoutliers) {
00113
00114
00115 for (unsigned int j=0;j<myHits.size();++j) {
00116 if (outlierId == myHits[j]->geographicalId().rawId()){
00117 LogTrace("TrackFitters") << "Rejecting outlier hit with estimate " << cut << " at position "
00118 << j << " with rawId=" << myHits[j]->geographicalId().rawId();
00119 LogTrace("TrackFitters") << "The fit will be repeated without the outlier";
00120 myHits[j] = InvalidTransientRecHit::build(outlierDet, TrackingRecHit::missing);
00121 }
00122 }
00123
00124
00125 if (breakTrajWith2ConsecutiveMissing) {
00126 unsigned int firstinvalid = myHits.size()-1;
00127 for (unsigned int j=0;j<myHits.size()-1;++j) {
00128 if (myHits[j]->type()==TrackingRecHit::missing && myHits[j+1]->type()==TrackingRecHit::missing) {
00129 firstinvalid = j;
00130 LogTrace("TrackFitters") << "Found two consecutive missing hits. First invalid: " << firstinvalid;
00131 break;
00132 }
00133 }
00134
00135
00136 myHits.erase(myHits.begin()+firstinvalid,myHits.end());
00137 }
00138 }
00139 }
00140 if ( hasoutliers &&
00141 !rejectTracksFlag &&
00142 tmp_first.empty() ) {
00143 smoothed.swap(tmp_first);
00144 }
00145
00146 } while(hasoutliers);
00147 if (!smoothed.empty()) {
00148
00149 if (noInvalidHitsBeginEnd) {
00150
00151
00152 if (!smoothed[0].empty() && !smoothed[0].lastMeasurement().recHit()->isValid())
00153 LogTrace("TrackFitters") << "Last measurement is invalid";
00154 while (!smoothed[0].empty() && !smoothed[0].lastMeasurement().recHit()->isValid()) smoothed[0].pop();
00155
00156
00157 if(!smoothed[0].firstMeasurement().recHit()->isValid()) {
00158 LogTrace("TrackFitters") << "First measurement is invalid";
00159 Trajectory tmpTraj(smoothed[0].seed(),smoothed[0].direction());
00160 Trajectory::DataContainer meas = smoothed[0].measurements();
00161
00162 for (Trajectory::DataContainer::iterator it=meas.begin();it!=meas.end();++it) {
00163 if (!it->recHit()->isValid()) continue;
00164 else {
00165 LogTrace("TrackFitters") << "First valid measurement is: " << it-meas.begin();
00166 const KFTrajectorySmoother* myKFSmoother = dynamic_cast<const KFTrajectorySmoother*>(smoother());
00167 if (!myKFSmoother) throw cms::Exception("TrackFitters") << "trying to use outliers rejection with a smoother different from KFTrajectorySmoother. Please disable outlier rejection.";
00168 const MeasurementEstimator* estimator = myKFSmoother->estimator();
00169 for (Trajectory::DataContainer::iterator itt=it;itt!=meas.end();++itt) {
00170 if (itt->recHit()->isValid())
00171 tmpTraj.push(*itt,estimator->estimate(itt->backwardPredictedState(),*itt->recHit()).second);
00172 else tmpTraj.push(*itt);
00173 }
00174 break;
00175 }
00176 }
00177 smoothed.clear();
00178 smoothed.push_back(tmpTraj);
00179
00180 }
00181 }
00182
00183 LogTrace("TrackFitters") << "end: returning smoothed trajectory with chi2="
00184 << smoothed[0].chiSquared() ;
00185
00186
00187
00188
00189
00190
00191
00192
00193 }
00194 return smoothed;
00195 }
00196
00197
00198 void
00199 KFFittingSmoother::smoothingStep(vector<Trajectory>& fitted, vector<Trajectory> &smoothed) const
00200 {
00201
00202 for(vector<Trajectory>::iterator it = fitted.begin(); it != fitted.end();
00203 it++) {
00204 vector<Trajectory> mysmoothed = smoother()->trajectories(*it);
00205 smoothed.insert(smoothed.end(), mysmoothed.begin(), mysmoothed.end());
00206 }
00207 LogDebug("TrackFitters") << "In KFFittingSmoother::smoothingStep "<<smoothed.size();
00208 }
00209
00210 vector<Trajectory> KFFittingSmoother::fit(const TrajectorySeed& aSeed,
00211 const RecHitContainer& hits) const{
00212
00213 throw cms::Exception("TrackFitters",
00214 "KFFittingSmoother::fit(TrajectorySeed, <TransientTrackingRecHit>) not implemented");
00215
00216 return vector<Trajectory>();
00217 }