Go to the documentation of this file.00001 #include "TrackingTools/TrackFitters/interface/KFFittingSmoother.h"
00002
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
00011 #include "DataFormats/TrackerRecHit2D/interface/SiPixelRecHit.h"
00012 #include "DataFormats/SiPixelDetId/interface/PXBDetId.h"
00013 #include "DataFormats/SiPixelDetId/interface/PXFDetId.h"
00014 #include <cmath>
00015
00016 using namespace std;
00017
00018 KFFittingSmoother::~KFFittingSmoother()
00019 {
00020 delete theSmoother;
00021 delete theFitter;
00022 }
00023
00024 vector<Trajectory> KFFittingSmoother::fit(const Trajectory& t) const
00025 {
00026 vector<Trajectory> smoothed;
00027 if ( t.isValid() )
00028 {
00029 vector<Trajectory> fitted = fitter()->fit(t);
00030 smoothingStep(fitted, smoothed);
00031 }
00032 return smoothed;
00033 }
00034
00035 bool KFFittingSmoother::checkForNans(const Trajectory & theTraj) const
00036 {
00037 if (std::isnan(theTraj.chiSquared ())) return false;
00038 const std::vector<TrajectoryMeasurement> & vtm = theTraj.measurements();
00039 for (std::vector<TrajectoryMeasurement>::const_iterator tm=vtm.begin(); tm!=vtm.end();tm++) {
00040 if (std::isnan(tm->estimate())) return false;
00041 AlgebraicVector5 v = tm->updatedState ().localParameters ().vector();
00042 for (int i=0;i<5;++i) if (std::isnan(v[i])) return false;
00043 const AlgebraicSymMatrix55 & m = tm->updatedState ().curvilinearError ().matrix();
00044 for (int i=0;i<5;++i)
00045 for (int j=0;j<(i+1);++j) if (std::isnan(m(i,j))) return false;
00046 }
00047 return true;
00048 }
00049
00050 vector<Trajectory> KFFittingSmoother::fit(const TrajectorySeed& aSeed,
00051 const RecHitContainer& hits,
00052 const TrajectoryStateOnSurface& firstPredTsos) const
00053 {
00054 LogDebug("TrackFitters") << "In KFFittingSmoother::fit";
00055
00056
00057
00058 bool hasoutliers;
00059 bool has_low_pixel_prob;
00060
00061
00062 double log_pixel_probability_lower_limit = -15.0;
00063
00064 RecHitContainer myHits = hits;
00065 vector<Trajectory> smoothed;
00066 vector<Trajectory> tmp_first;
00067
00068 do
00069 {
00070 if ( hits.empty() )
00071 {
00072 smoothed.clear();
00073 break;
00074 }
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 hasoutliers = false;
00086 has_low_pixel_prob = false;
00087
00088 double cut = theEstimateCut;
00089
00090 double log_pixel_prob_cut = theLogPixelProbabilityCut;
00091
00092
00093 unsigned int outlierId = 0;
00094 const GeomDet* outlierDet = 0;
00095
00096 unsigned int low_pixel_prob_Id = 0;
00097 const GeomDet* low_pixel_prob_Det = 0;
00098
00099
00100 vector<Trajectory> fitted = fitter()->fit(aSeed, myHits, firstPredTsos);
00101
00102 smoothed.clear();
00103 smoothingStep(fitted, smoothed);
00104
00105
00106
00107 if ( smoothed.empty() )
00108 {
00109 if ( rejectTracksFlag )
00110 {
00111 LogTrace("TrackFitters") << "smoothed.size()==0 => trajectory rejected";
00112
00113 }
00114 else
00115 {
00116 LogTrace("TrackFitters") << "smoothed.size()==0 => returning orignal trajectory" ;
00117 smoothed.swap(tmp_first);
00118 }
00119 break;
00120 }
00121
00122
00123
00124
00125
00126
00127
00128
00129 if (!checkForNans(smoothed[0])) {
00130 edm::LogError("TrackNaN")<<"Track has NaN";
00131 smoothed.clear();
00132 break;
00133 }
00134
00135 if ( theEstimateCut > 0 || log_pixel_prob_cut > log_pixel_probability_lower_limit )
00136 {
00137 if ( smoothed[0].foundHits() < theMinNumberOfHits )
00138 {
00139 if ( rejectTracksFlag )
00140 {
00141 LogTrace("TrackFitters") << "smoothed[0].foundHits()<theMinNumberOfHits => trajectory rejected";
00142 smoothed.clear();
00143
00144 }
00145 else
00146 {
00147
00148 if ( !tmp_first.empty() )
00149 {
00150 tmp_first.swap(smoothed);
00151 }
00152
00153 LogTrace("TrackFitters")
00154 << "smoothed[0].foundHits()<theMinNumberOfHits => returning orignal trajectory with chi2="
00155 << smoothed[0].chiSquared() ;
00156 }
00157 break;
00158 }
00159
00160
00161 const std::vector<TrajectoryMeasurement> & vtm = smoothed[0].measurements();
00162
00163 double log_pixel_hit_probability = -999999.9;
00164
00165 for (std::vector<TrajectoryMeasurement>::const_iterator tm=vtm.begin(); tm!=vtm.end();tm++)
00166 {
00167 double estimate = tm->estimate();
00168
00169
00170 if ( estimate > cut && theEstimateCut > 0 )
00171 {
00172 hasoutliers = true;
00173 cut = estimate;
00174 outlierId = tm->recHit()->geographicalId().rawId();
00175 outlierDet = tm->recHit()->det();
00176 }
00177
00178
00179
00180
00181 if(log_pixel_prob_cut > log_pixel_probability_lower_limit){
00182
00183
00184
00185
00186
00187
00188 TransientTrackingRecHit::ConstRecHitPointer hit = tm->recHit();
00189 unsigned int testSubDetID = ( hit->geographicalId().subdetId() );
00190
00191 if ( hit->isValid() &&
00192 hit->geographicalId().det() == DetId::Tracker &&
00193 ( testSubDetID == PixelSubdetector::PixelBarrel ||
00194 testSubDetID == PixelSubdetector::PixelEndcap )
00195 )
00196 {
00197
00198 const TrackingRecHit* persistentHit = hit->hit();
00199
00200
00201 if ( !persistentHit == 0 &&
00202 typeid(*persistentHit) == typeid(SiPixelRecHit) )
00203 {
00204
00205
00206 const SiPixelRecHit* pixhit = dynamic_cast<const SiPixelRecHit*>( hit->hit() );
00207
00208 double pixel_hit_probability = (float)pixhit->clusterProbability(0);
00209
00210 if ( pixel_hit_probability < 0.0 )
00211 LogDebug("From KFFittingSmoother.cc")
00212 << "Wraning : Negative pixel hit probability !!!! Will set the probability to 10^{-15} !!!" << endl;
00213
00214 if ( pixel_hit_probability <= 0.0 || log10( pixel_hit_probability ) < log_pixel_probability_lower_limit )
00215 log_pixel_hit_probability = log_pixel_probability_lower_limit;
00216 else
00217 log_pixel_hit_probability = log10( pixel_hit_probability );
00218
00219 int qbin = (int)pixhit->qBin();
00220
00221 if ( ( log_pixel_hit_probability < log_pixel_prob_cut ) &&
00222 ( qbin != 0 ) )
00223 {
00224 has_low_pixel_prob = true;
00225 log_pixel_prob_cut = log_pixel_hit_probability;
00226 low_pixel_prob_Id = tm->recHit()->geographicalId().rawId();
00227 low_pixel_prob_Det = tm->recHit()->det();
00228 }
00229
00230 }
00231
00232 }
00233 }
00234
00235
00236
00237 }
00238
00239
00240 if ( hasoutliers || has_low_pixel_prob )
00241 {
00242
00243
00244 for ( unsigned int j=0; j<myHits.size(); ++j )
00245 {
00246 if ( hasoutliers && outlierId == myHits[j]->geographicalId().rawId() )
00247 {
00248 LogTrace("TrackFitters") << "Rejecting outlier hit with estimate " << cut << " at position "
00249 << j << " with rawId=" << myHits[j]->geographicalId().rawId();
00250 LogTrace("TrackFitters") << "The fit will be repeated without the outlier";
00251 myHits[j] = InvalidTransientRecHit::build(outlierDet, TrackingRecHit::missing);
00252 }
00253 else if ( has_low_pixel_prob && low_pixel_prob_Id == myHits[j]->geographicalId().rawId() )
00254 {
00255 LogTrace("TrackFitters") << "Rejecting low proability pixel hit with log_pixel_prob_cut = "
00256 << log_pixel_prob_cut << " at position "
00257 << j << " with rawId =" << myHits[j]->geographicalId().rawId();
00258 LogTrace("TrackFitters") << "The fit will be repeated without the outlier";
00259 myHits[j] = InvalidTransientRecHit::build(low_pixel_prob_Det, TrackingRecHit::missing);
00260 }
00261
00262 }
00263
00264
00265 if ( breakTrajWith2ConsecutiveMissing )
00266 {
00267 unsigned int firstinvalid = myHits.size()-1;
00268 for ( unsigned int j=0; j<myHits.size()-1; ++j )
00269 {
00270 if ( ((myHits[j ]->type() == TrackingRecHit::missing) && (myHits[j ]->geographicalId().rawId() != 0)) &&
00271 ((myHits[j+1]->type() == TrackingRecHit::missing) && (myHits[j+1]->geographicalId().rawId() != 0)) )
00272 {
00273 firstinvalid = j;
00274 LogTrace("TrackFitters") << "Found two consecutive missing hits. First invalid: " << firstinvalid;
00275 break;
00276 }
00277 }
00278
00279
00280
00281 myHits.erase(myHits.begin()+firstinvalid,myHits.end());
00282
00283 }
00284
00285 }
00286
00287 }
00288
00289 if ( ( hasoutliers ||
00290 has_low_pixel_prob ) &&
00291 !rejectTracksFlag &&
00292 tmp_first.empty() )
00293 {
00294 smoothed.swap(tmp_first);
00295 }
00296
00297 }
00298 while ( hasoutliers || has_low_pixel_prob );
00299
00300 if ( !smoothed.empty() )
00301 {
00302 if ( noInvalidHitsBeginEnd )
00303 {
00304
00305 if ( !smoothed[0].empty() &&
00306 !smoothed[0].lastMeasurement().recHit()->isValid() )
00307 LogTrace("TrackFitters") << "Last measurement is invalid";
00308
00309 while ( !smoothed[0].empty() &&
00310 !smoothed[0].lastMeasurement().recHit()->isValid() )
00311 smoothed[0].pop();
00312
00313
00314 if ( !smoothed[0].firstMeasurement().recHit()->isValid() )
00315 {
00316 LogTrace("TrackFitters") << "First measurement is invalid";
00317 Trajectory tmpTraj(smoothed[0].seed(),smoothed[0].direction());
00318 Trajectory::DataContainer meas = smoothed[0].measurements();
00319
00320 Trajectory::DataContainer::iterator it;
00321 for ( it=meas.begin(); it!=meas.end(); ++it )
00322 {
00323 if ( !it->recHit()->isValid() )
00324 continue;
00325 else break;
00326 }
00327 tmpTraj.push(*it,smoothed[0].chiSquared());
00328
00329 for (Trajectory::DataContainer::iterator itt=it+1; itt!=meas.end();++itt)
00330 {
00331 tmpTraj.push(*itt,0);
00332 }
00333
00334 smoothed.clear();
00335 smoothed.push_back(tmpTraj);
00336
00337 }
00338
00339 }
00340
00341 LogTrace("TrackFitters") << "end: returning smoothed trajectory with chi2="
00342 << smoothed[0].chiSquared() ;
00343
00344
00345
00346
00347
00348
00349
00350
00351 }
00352
00353 return smoothed;
00354
00355 }
00356
00357
00358 void
00359 KFFittingSmoother::smoothingStep(vector<Trajectory>& fitted, vector<Trajectory> &smoothed) const
00360 {
00361
00362 for(vector<Trajectory>::iterator it = fitted.begin(); it != fitted.end();
00363 it++) {
00364 vector<Trajectory> mysmoothed = smoother()->trajectories(*it);
00365 smoothed.insert(smoothed.end(), mysmoothed.begin(), mysmoothed.end());
00366 }
00367 LogDebug("TrackFitters") << "In KFFittingSmoother::smoothingStep "<<smoothed.size();
00368 }
00369
00370 vector<Trajectory> KFFittingSmoother::fit(const TrajectorySeed& aSeed,
00371 const RecHitContainer& hits) const{
00372
00373 throw cms::Exception("TrackFitters",
00374 "KFFittingSmoother::fit(TrajectorySeed, <TransientTrackingRecHit>) not implemented");
00375
00376 return vector<Trajectory>();
00377 }