00001
00009 #include "RecoMuon/StandAloneTrackFinder/interface/StandAloneMuonFilter.h"
00010
00011 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00012
00013
00014 #include "FWCore/Framework/interface/Event.h"
00015
00016 #include "RecoMuon/TrackingTools/interface/MuonPatternRecoDumper.h"
00017 #include "RecoMuon/TrackingTools/interface/MuonTrajectoryUpdator.h"
00018 #include "RecoMuon/MeasurementDet/interface/MuonDetLayerMeasurements.h"
00019 #include "RecoMuon/TrackingTools/interface/MuonServiceProxy.h"
00020 #include "RecoMuon/TransientTrackingRecHit/interface/MuonTransientTrackingRecHit.h"
00021 #include "RecoMuon/Navigation/interface/DirectMuonNavigation.h"
00022
00023 #include "TrackingTools/GeomPropagators/interface/Propagator.h"
00024
00025 #include "TrackingTools/KalmanUpdators/interface/Chi2MeasurementEstimator.h"
00026
00027 #include "TrackingTools/PatternTools/interface/Trajectory.h"
00028
00029 #include "TrackingTools/TrajectoryState/interface/FreeTrajectoryState.h"
00030 #include "TrackingTools/PatternTools/interface/TrajectoryMeasurement.h"
00031 #include "TrackingTools/DetLayers/interface/DetLayer.h"
00032
00033 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00034 #include "FWCore/Utilities/interface/Exception.h"
00035
00036 #include <vector>
00037
00038 using namespace edm;
00039 using namespace std;
00040
00041 StandAloneMuonFilter::StandAloneMuonFilter(const ParameterSet& par,
00042 const MuonServiceProxy* service)
00043 :theService(service),
00044 theOverlappingChambersFlag(true)
00045 {
00046
00047 string fitDirectionName = par.getParameter<string>("FitDirection");
00048
00049 if (fitDirectionName == "insideOut" ) theFitDirection = insideOut;
00050 else if (fitDirectionName == "outsideIn" ) theFitDirection = outsideIn;
00051 else
00052 throw cms::Exception("StandAloneMuonFilter constructor")
00053 <<"Wrong fit direction chosen in StandAloneMuonFilter::StandAloneMuonFilter ParameterSet"
00054 << "\n"
00055 << "Possible choices are:"
00056 << "\n"
00057 << "FitDirection = insideOut or FitDirection = outsideIn";
00058
00059
00060 theMaxChi2 = par.getParameter<double>("MaxChi2");
00061
00062
00063
00064 theNSigma = par.getParameter<double>("NumberOfSigma");
00065
00066
00067
00068 theNavigationType = par.getParameter<string>("NavigationType");
00069
00070
00071
00072
00073
00074 theEstimator = new Chi2MeasurementEstimator(theMaxChi2,theNSigma);
00075
00076 thePropagatorName = par.getParameter<string>("Propagator");
00077
00078 theBestMeasurementFinder = new MuonBestMeasurementFinder();
00079
00080
00081 ParameterSet muonUpdatorPSet = par.getParameter<ParameterSet>("MuonTrajectoryUpdatorParameters");
00082
00083
00084 theMuonUpdator = new MuonTrajectoryUpdator(muonUpdatorPSet,
00085 fitDirection() );
00086
00087
00088 bool enableDTMeasurement = par.getParameter<bool>("EnableDTMeasurement");
00089 bool enableCSCMeasurement = par.getParameter<bool>("EnableCSCMeasurement");
00090 bool enableRPCMeasurement = par.getParameter<bool>("EnableRPCMeasurement");
00091
00092 theMeasurementExtractor = new MuonDetLayerMeasurements(par.getParameter<InputTag>("DTRecSegmentLabel"),
00093 par.getParameter<InputTag>("CSCRecSegmentLabel"),
00094 par.getParameter<InputTag>("RPCRecSegmentLabel"),
00095 enableDTMeasurement,
00096 enableCSCMeasurement,
00097 enableRPCMeasurement);
00098
00099 theRPCLoneliness = (!(enableDTMeasurement && enableCSCMeasurement)) ? enableRPCMeasurement : false;
00100 }
00101
00102 StandAloneMuonFilter::~StandAloneMuonFilter(){
00103
00104 LogTrace("Muon|RecoMuon|StandAloneMuonFilter")
00105 <<"StandAloneMuonFilter destructor called"<<endl;
00106
00107 delete theEstimator;
00108 delete theMuonUpdator;
00109 delete theMeasurementExtractor;
00110 delete theBestMeasurementFinder;
00111 }
00112
00113 const Propagator* StandAloneMuonFilter::propagator() const {
00114 return &*theService->propagator(thePropagatorName);
00115 }
00116
00118 PropagationDirection StandAloneMuonFilter::propagationDirection() const{
00119 if( fitDirection() == 0 ) return alongMomentum;
00120 else if ( fitDirection() == 1 ) return oppositeToMomentum;
00121 else return anyDirection;
00122 }
00123
00124
00125 void StandAloneMuonFilter::reset(){
00126 totalChambers = dtChambers = cscChambers = rpcChambers = 0;
00127 totalCompatibleChambers = dtCompatibleChambers = cscCompatibleChambers = rpcCompatibleChambers = 0;
00128
00129 theLastCompatibleTSOS = theLastUpdatedTSOS = theLastButOneUpdatedTSOS = TrajectoryStateOnSurface();
00130
00131 theMuonUpdator->makeFirstTime();
00132
00133 theDetLayers.clear();
00134 }
00135
00136 void StandAloneMuonFilter::setEvent(const Event& event){
00137 theMeasurementExtractor->setEvent(event);
00138 }
00139
00140
00141 void StandAloneMuonFilter::incrementChamberCounters(const DetLayer *layer){
00142
00143 if(layer->subDetector()==GeomDetEnumerators::DT) dtChambers++;
00144 else if(layer->subDetector()==GeomDetEnumerators::CSC) cscChambers++;
00145 else if(layer->subDetector()==GeomDetEnumerators::RPCBarrel || layer->subDetector()==GeomDetEnumerators::RPCEndcap) rpcChambers++;
00146 else
00147 LogError("Muon|RecoMuon|StandAloneMuonFilter")
00148 << "Unrecognized module type in incrementChamberCounters";
00149
00150
00151
00152 totalChambers++;
00153 }
00154
00155 void StandAloneMuonFilter::incrementCompatibleChamberCounters(const DetLayer *layer){
00156
00157 if(layer->subDetector()==GeomDetEnumerators::DT) dtCompatibleChambers++;
00158 else if(layer->subDetector()==GeomDetEnumerators::CSC) cscCompatibleChambers++;
00159 else if(layer->subDetector()==GeomDetEnumerators::RPCBarrel || layer->subDetector()==GeomDetEnumerators::RPCEndcap) rpcCompatibleChambers++;
00160 else
00161 LogError("Muon|RecoMuon|StandAloneMuonFilter")
00162 << "Unrecognized module type in incrementCompatibleChamberCounters";
00163
00164 totalCompatibleChambers++;
00165 }
00166
00167
00168 vector<const DetLayer*> StandAloneMuonFilter::compatibleLayers(const DetLayer *initialLayer,
00169 FreeTrajectoryState& fts,
00170 PropagationDirection propDir){
00171 vector<const DetLayer*> detLayers;
00172
00173 if(theNavigationType == "Standard"){
00174
00175 detLayers = initialLayer->compatibleLayers(fts,propDir);
00176
00177
00178 detLayers.insert(detLayers.begin(),initialLayer);
00179 }
00180 else if (theNavigationType == "Direct"){
00181 DirectMuonNavigation navigation(theService->detLayerGeometry());
00182 detLayers = navigation.compatibleLayers(fts,propDir);
00183 }
00184 else
00185 edm::LogError("Muon|RecoMuon|StandAloneMuonFilter") << "No Properly Navigation Selected!!"<<endl;
00186
00187 return detLayers;
00188 }
00189
00190
00191 void StandAloneMuonFilter::refit(const TrajectoryStateOnSurface& initialTSOS,
00192 const DetLayer* initialLayer, Trajectory &trajectory){
00193
00194 const std::string metname = "Muon|RecoMuon|StandAloneMuonFilter";
00195
00196
00197 reset();
00198
00199 MuonPatternRecoDumper debug;
00200
00201 LogTrace(metname) << "Starting the refit"<<endl;
00202
00203
00204 TrajectoryStateOnSurface lastTSOS = theLastCompatibleTSOS = theLastUpdatedTSOS = theLastButOneUpdatedTSOS = initialTSOS;
00205
00206 double eta0 = initialTSOS.freeTrajectoryState()->momentum().eta();
00207 vector<const DetLayer*> detLayers = compatibleLayers(initialLayer,*initialTSOS.freeTrajectoryState(),
00208 propagationDirection());
00209
00210 LogTrace(metname)<<"compatible layers found: "<<detLayers.size()<<endl;
00211
00212 vector<const DetLayer*>::const_iterator layer;
00213
00214
00215 for ( layer = detLayers.begin(); layer!= detLayers.end(); ++layer ) {
00216
00217
00218
00219 LogTrace(metname) << debug.dumpLayer(*layer);
00220
00221 LogTrace(metname) << "search Trajectory Measurement from: " << lastTSOS.globalPosition();
00222
00223
00224 std::vector<TrajectoryMeasurement> bestMeasurements = findBestMeasurements(*layer, lastTSOS);
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238 double lastdEta = fabs(lastTSOS.freeTrajectoryState()->momentum().eta() - eta0);
00239 if( bestMeasurements.empty() && lastdEta > 0.1) {
00240 LogTrace(metname) << "No measurement and big eta variation wrt seed" << endl
00241 << "trying with lastButOneUpdatedTSOS";
00242 bestMeasurements = findBestMeasurements(*layer, theLastButOneUpdatedTSOS);
00243 }
00244
00245
00246
00247
00248 if( bestMeasurements.empty() && lastdEta > 0.1) {
00249 LogTrace(metname) << "No measurement and big eta variation wrt seed" << endl
00250 << "tryng with seed TSOS";
00251 bestMeasurements = findBestMeasurements(*layer, initialTSOS);
00252 }
00253
00254
00255
00256
00257 if(!bestMeasurements.empty()) {
00258 incrementCompatibleChamberCounters(*layer);
00259 bool added = false;
00260 for(std::vector<TrajectoryMeasurement>::const_iterator tmItr = bestMeasurements.begin();
00261 tmItr != bestMeasurements.end(); ++tmItr){
00262 added |= update(*layer, &(*tmItr), trajectory);
00263 lastTSOS = theLastUpdatedTSOS;
00264 }
00265 if(added) {
00266 incrementChamberCounters(*layer);
00267 theDetLayers.push_back(*layer);
00268 }
00269 }
00270
00271
00272
00273 else{
00274 LogTrace(metname)<<"No best measurement found"<<endl;
00275
00276
00277
00278
00279 }
00280 }
00281 }
00282
00283
00284 std::vector<TrajectoryMeasurement>
00285 StandAloneMuonFilter::findBestMeasurements(const DetLayer* layer,
00286 const TrajectoryStateOnSurface& tsos){
00287
00288 const std::string metname = "Muon|RecoMuon|StandAloneMuonFilter";
00289
00290 std::vector<TrajectoryMeasurement> result;
00291 std::vector<TrajectoryMeasurement> measurements;
00292
00293 if(theOverlappingChambersFlag && layer->hasGroups()){
00294
00295 std::vector<TrajectoryMeasurementGroup> measurementGroups =
00296 theMeasurementExtractor->groupedMeasurements(layer, tsos, *propagator(), *estimator());
00297
00298 if(theFitDirection == outsideIn){
00299 LogTrace(metname) << "Reversing the order of groupedMeasurements as the direction of the fit is outside-in";
00300 reverse(measurementGroups.begin(),measurementGroups.end());
00301
00302
00303 }
00304
00305
00306 for(std::vector<TrajectoryMeasurementGroup>::const_iterator tmGroupItr = measurementGroups.begin();
00307 tmGroupItr != measurementGroups.end(); ++tmGroupItr){
00308
00309 measurements = tmGroupItr->measurements();
00310 LogTrace(metname) << "Number of Trajectory Measurement: " << measurements.size();
00311
00312 const TrajectoryMeasurement* bestMeasurement
00313 = bestMeasurementFinder()->findBestMeasurement(measurements, propagator());
00314
00315 if(bestMeasurement) result.push_back(*bestMeasurement);
00316 }
00317 }
00318 else{
00319 measurements = theMeasurementExtractor->measurements(layer, tsos, *propagator(), *estimator());
00320 LogTrace(metname) << "Number of Trajectory Measurement: " << measurements.size();
00321 const TrajectoryMeasurement* bestMeasurement
00322 = bestMeasurementFinder()->findBestMeasurement(measurements,
00323 propagator());
00324 if(bestMeasurement) result.push_back(*bestMeasurement);
00325 }
00326 return result;
00327 }
00328
00329
00330
00331
00332 bool StandAloneMuonFilter::update(const DetLayer * layer,
00333 const TrajectoryMeasurement * meas,
00334 Trajectory & trajectory)
00335 {
00336 const std::string metname = "Muon|RecoMuon|StandAloneMuonFilter";
00337 MuonPatternRecoDumper debug;
00338
00339 LogTrace(metname)<<"best measurement found" << "\n"
00340 <<"updating the trajectory..."<<endl;
00341 pair<bool,TrajectoryStateOnSurface> result = updator()->update(meas,
00342 trajectory,
00343 propagator());
00344 LogTrace(metname)<<"trajectory updated: "<<result.first<<endl;
00345 LogTrace(metname) << debug.dumpTSOS(result.second);
00346
00347 if(result.first){
00348 theLastButOneUpdatedTSOS = theLastUpdatedTSOS;
00349 theLastUpdatedTSOS = result.second;
00350 }
00351
00352 if(result.second.isValid())
00353 theLastCompatibleTSOS = result.second;
00354
00355 return result.first;
00356 }
00357
00358
00359 void StandAloneMuonFilter::createDefaultTrajectory(const Trajectory & oldTraj, Trajectory & defTraj) {
00360
00361 Trajectory::DataContainer oldMeas = oldTraj.measurements();
00362 defTraj.reserve(oldMeas.size());
00363
00364 for (Trajectory::DataContainer::const_iterator itm = oldMeas.begin(); itm != oldMeas.end(); itm++) {
00365 if( !(*itm).recHit()->isValid() )
00366 defTraj.push( *itm, (*itm).estimate() );
00367 else {
00368 MuonTransientTrackingRecHit::MuonRecHitPointer invRhPtr = MuonTransientTrackingRecHit::specificBuild( (*itm).recHit()->det(), (*itm).recHit()->hit() );
00369 invRhPtr->invalidateHit();
00370 TrajectoryMeasurement invRhMeas( (*itm).forwardPredictedState(), (*itm).updatedState(), invRhPtr.get(), (*itm).estimate(), (*itm).layer() );
00371 defTraj.push( invRhMeas, (*itm).estimate() );
00372 }
00373
00374 }
00375 }