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