00001
00017 #include "RecoMuon/TrackingTools/interface/MuonTrajectoryUpdator.h"
00018 #include "RecoMuon/TrackingTools/interface/MuonPatternRecoDumper.h"
00019 #include "DataFormats/MuonDetId/interface/MuonSubdetId.h"
00020
00021 #include "TrackingTools/KalmanUpdators/interface/Chi2MeasurementEstimator.h"
00022 #include "TrackingTools/PatternTools/interface/TrajectoryMeasurement.h"
00023 #include "TrackingTools/PatternTools/interface/Trajectory.h"
00024 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h"
00025 #include "TrackingTools/GeomPropagators/interface/Propagator.h"
00026 #include "TrackingTools/KalmanUpdators/interface/KFUpdator.h"
00027 #include "TrackingTools/DetLayers/interface/DetLayer.h"
00028
00029 #include "RecoMuon/TransientTrackingRecHit/interface/MuonTransientTrackingRecHit.h"
00030 #include "RecoMuon/TransientTrackingRecHit/interface/MuonTransientTrackingRecHitBreaker.h"
00031
00032 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00033 #include "FWCore/Utilities/interface/Exception.h"
00034 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00035
00036 #include <algorithm>
00037
00038 using namespace edm;
00039 using namespace std;
00040
00042 MuonTrajectoryUpdator::MuonTrajectoryUpdator(const edm::ParameterSet& par,
00043 NavigationDirection fitDirection): theFitDirection(fitDirection){
00044
00045
00046 theMaxChi2 = par.getParameter<double>("MaxChi2");
00047 theEstimator = new Chi2MeasurementEstimator(theMaxChi2);
00048
00049
00050 theUpdator= new KFUpdator();
00051
00052
00053 theGranularity = par.getParameter<int>("Granularity");
00054
00055
00056 theRescaleErrorFlag = par.getParameter<bool>("RescaleError");
00057
00058 if(theRescaleErrorFlag)
00059
00060 theRescaleFactor = par.getParameter<double>("RescaleErrorFactor");
00061
00062
00063 useInvalidHits = par.getParameter<bool>("UseInvalidHits");
00064
00065
00066 theFirstTSOSFlag = true;
00067
00068
00069 theRPCExFlag = par.getParameter<bool>("ExcludeRPCFromFit");
00070 }
00071
00072 MuonTrajectoryUpdator::MuonTrajectoryUpdator( NavigationDirection fitDirection,
00073 double chi2, int granularity): theMaxChi2(chi2),
00074 theGranularity(granularity),
00075 theFitDirection(fitDirection){
00076 theEstimator = new Chi2MeasurementEstimator(theMaxChi2);
00077
00078
00079 theUpdator= new KFUpdator();
00080 }
00081
00083 MuonTrajectoryUpdator::~MuonTrajectoryUpdator(){
00084 delete theEstimator;
00085 delete theUpdator;
00086 }
00087
00088 void MuonTrajectoryUpdator::makeFirstTime(){
00089 theFirstTSOSFlag = true;
00090 }
00091
00092
00093 pair<bool,TrajectoryStateOnSurface>
00094 MuonTrajectoryUpdator::update(const TrajectoryMeasurement* measurement,
00095 Trajectory& trajectory,
00096 const Propagator *propagator){
00097
00098 const std::string metname = "Muon|RecoMuon|MuonTrajectoryUpdator";
00099
00100 MuonPatternRecoDumper muonDumper;
00101
00102
00103 bool updated=false;
00104
00105 if(!measurement) return pair<bool,TrajectoryStateOnSurface>(updated,TrajectoryStateOnSurface() );
00106
00107
00108 const DetLayer* detLayer=measurement->layer();
00109
00110
00111 TransientTrackingRecHit::ConstRecHitPointer muonRecHit = measurement->recHit();
00112
00113
00114 TransientTrackingRecHit::ConstRecHitContainer recHitsForFit =
00115 MuonTransientTrackingRecHitBreaker::breakInSubRecHits(muonRecHit,theGranularity);
00116
00117
00118 sort(recHitsForFit,detLayer);
00119
00120 TrajectoryStateOnSurface lastUpdatedTSOS = measurement->predictedState();
00121
00122 LogTrace(metname)<<"Number of rechits for the fit: "<<recHitsForFit.size()<<endl;
00123
00124 TransientTrackingRecHit::ConstRecHitContainer::iterator recHit;
00125 for(recHit = recHitsForFit.begin(); recHit != recHitsForFit.end(); ++recHit ) {
00126 if ((*recHit)->isValid() ) {
00127
00128
00129 TrajectoryStateOnSurface propagatedTSOS = propagateState(lastUpdatedTSOS, measurement,
00130 *recHit, propagator);
00131
00132 if ( propagatedTSOS.isValid() ) {
00133 pair<bool,double> thisChi2 = estimator()->estimate(propagatedTSOS, *((*recHit).get()));
00134
00135 LogTrace(metname) << "Estimation for Kalman Fit. Chi2: " << thisChi2.second;
00136
00137
00138 bool wantIncludeThisHit = true;
00139 if (theRPCExFlag &&
00140 (*recHit)->geographicalId().det() == DetId::Muon &&
00141 (*recHit)->geographicalId().subdetId() == MuonSubdetId::RPC){
00142 wantIncludeThisHit = false;
00143 LogTrace(metname) << "This is an RPC hit and the present configuration is such that it will be excluded from the fit";
00144 }
00145
00146
00147
00148
00149
00150 if (thisChi2.first) {
00151 updated=true;
00152 if (wantIncludeThisHit) {
00153
00154 LogTrace(metname) << endl
00155 << " Kalman Start" << "\n" << "\n";
00156 LogTrace(metname) << " Meas. Position : " << (**recHit).globalPosition() << "\n"
00157 << " Pred. Position : " << propagatedTSOS.globalPosition()
00158 << " Pred Direction : " << propagatedTSOS.globalDirection()<< endl;
00159
00160 if(theRescaleErrorFlag && theFirstTSOSFlag){
00161 propagatedTSOS.rescaleError(theRescaleFactor);
00162 theFirstTSOSFlag = false;
00163 }
00164
00165 lastUpdatedTSOS = measurementUpdator()->update(propagatedTSOS,*((*recHit).get()));
00166
00167 LogTrace(metname) << " Fit Position : " << lastUpdatedTSOS.globalPosition()
00168 << " Fit Direction : " << lastUpdatedTSOS.globalDirection()
00169 << "\n"
00170 << " Fit position radius : "
00171 << lastUpdatedTSOS.globalPosition().perp()
00172 << "filter updated" << endl;
00173
00174 LogTrace(metname) << muonDumper.dumpTSOS(lastUpdatedTSOS);
00175
00176 LogTrace(metname) << "\n\n Kalman End" << "\n" << "\n";
00177
00178 TrajectoryMeasurement updatedMeasurement = updateMeasurement( propagatedTSOS, lastUpdatedTSOS,
00179 *recHit, thisChi2.second, detLayer,
00180 measurement);
00181
00182 trajectory.push(updatedMeasurement, thisChi2.second);
00183 }
00184 else {
00185 LogTrace(metname) << " Compatible RecHit with good chi2 but made with RPC when it was decided to not include it in the fit"
00186 << " --> trajectory NOT updated, invalid RecHit added." << endl;
00187
00188 MuonTransientTrackingRecHit::MuonRecHitPointer invalidRhPtr = MuonTransientTrackingRecHit::specificBuild( (*recHit)->det(), (*recHit)->hit() );
00189 invalidRhPtr->invalidateHit();
00190 TrajectoryMeasurement invalidRhMeasurement(propagatedTSOS, propagatedTSOS, invalidRhPtr.get(), thisChi2.second, detLayer);
00191 trajectory.push(invalidRhMeasurement, thisChi2.second);
00192 }
00193 }
00194 else {
00195 if(useInvalidHits) {
00196 LogTrace(metname) << " Compatible RecHit with too large chi2"
00197 << " --> trajectory NOT updated, invalid RecHit added." << endl;
00198
00199 MuonTransientTrackingRecHit::MuonRecHitPointer invalidRhPtr = MuonTransientTrackingRecHit::specificBuild( (*recHit)->det(), (*recHit)->hit() );
00200 invalidRhPtr->invalidateHit();
00201 TrajectoryMeasurement invalidRhMeasurement(propagatedTSOS, propagatedTSOS, invalidRhPtr.get(), thisChi2.second, detLayer);
00202 trajectory.push(invalidRhMeasurement, thisChi2.second);
00203 }
00204 }
00205 }
00206 }
00207 }
00208 recHitsForFit.clear();
00209 return pair<bool,TrajectoryStateOnSurface>(updated,lastUpdatedTSOS);
00210 }
00211
00212 TrajectoryStateOnSurface
00213 MuonTrajectoryUpdator::propagateState(const TrajectoryStateOnSurface& state,
00214 const TrajectoryMeasurement* measurement,
00215 const TransientTrackingRecHit::ConstRecHitPointer & current,
00216 const Propagator *propagator) const{
00217
00218 const TransientTrackingRecHit::ConstRecHitPointer mother = measurement->recHit();
00219
00220 if( current->geographicalId() == mother->geographicalId() )
00221 return measurement->predictedState();
00222
00223 const TrajectoryStateOnSurface tsos =
00224 propagator->propagate(state, current->det()->surface());
00225 return tsos;
00226
00227 }
00228
00229
00230 TrajectoryMeasurement MuonTrajectoryUpdator::updateMeasurement( const TrajectoryStateOnSurface &propagatedTSOS,
00231 const TrajectoryStateOnSurface &lastUpdatedTSOS,
00232 const TransientTrackingRecHit::ConstRecHitPointer &recHit,
00233 const double &chi2, const DetLayer *detLayer,
00234 const TrajectoryMeasurement *initialMeasurement){
00235 return TrajectoryMeasurement(propagatedTSOS, lastUpdatedTSOS,
00236 recHit,chi2,detLayer);
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251 }
00252
00253
00254 void MuonTrajectoryUpdator::sort(TransientTrackingRecHit::ConstRecHitContainer& recHitsForFit,
00255 const DetLayer* detLayer){
00256
00257 if(detLayer->subDetector()==GeomDetEnumerators::DT){
00258 if(fitDirection() == insideOut)
00259 stable_sort(recHitsForFit.begin(),recHitsForFit.end(), RadiusComparatorInOut() );
00260 else if(fitDirection() == outsideIn)
00261 stable_sort(recHitsForFit.begin(),recHitsForFit.end(),RadiusComparatorOutIn() );
00262 else
00263 LogError("Muon|RecoMuon|MuonTrajectoryUpdator") <<"MuonTrajectoryUpdator::sort: Wrong propagation direction!!";
00264 }
00265
00266 else if(detLayer->subDetector()==GeomDetEnumerators::CSC){
00267 if(fitDirection() == insideOut)
00268 stable_sort(recHitsForFit.begin(),recHitsForFit.end(), ZedComparatorInOut() );
00269 else if(fitDirection() == outsideIn)
00270 stable_sort(recHitsForFit.begin(),recHitsForFit.end(), ZedComparatorOutIn() );
00271 else
00272 LogError("Muon|RecoMuon|MuonTrajectoryUpdator") <<"MuonTrajectoryUpdator::sort: Wrong propagation direction!!";
00273 }
00274 }