CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/RecoMuon/StandAloneTrackFinder/src/StandAloneMuonFilter.cc

Go to the documentation of this file.
00001 
00009 #include "RecoMuon/StandAloneTrackFinder/interface/StandAloneMuonFilter.h"
00010 
00011 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00012 
00013 // FIXME: remove this
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   // Fit direction
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   // The max allowed chi2 to accept a rechit in the fit
00060   theMaxChi2 = par.getParameter<double>("MaxChi2");
00061 
00062   // The errors of the trajectory state are multiplied by nSigma 
00063   // to define acceptance of BoundPlane and maximalLocalDisplacement
00064   theNSigma = par.getParameter<double>("NumberOfSigma"); // default = 3.
00065 
00066   // The navigation type:
00067   // "Direct","Standard"
00068   theNavigationType = par.getParameter<string>("NavigationType");
00069   
00070   // The estimator: makes the decision wheter a measure is good or not
00071   // it isn't used by the updator which does the real fit. In fact, in principle,
00072   // a looser request onto the measure set can be requested 
00073   // (w.r.t. the request on the accept/reject measure in the fit)
00074   theEstimator = new Chi2MeasurementEstimator(theMaxChi2,theNSigma);
00075   
00076   thePropagatorName = par.getParameter<string>("Propagator");
00077 
00078   theBestMeasurementFinder = new MuonBestMeasurementFinder();
00079 
00080   // Muon trajectory updator parameters
00081   ParameterSet muonUpdatorPSet = par.getParameter<ParameterSet>("MuonTrajectoryUpdatorParameters");
00082   
00083   // the updator needs the fit direction
00084   theMuonUpdator = new MuonTrajectoryUpdator(muonUpdatorPSet,
00085                                              fitDirection() );
00086 
00087   // Measurement Extractor: enable the measure for each muon sub detector
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   // FIXME:
00150   //   << layer->module() << " " <<layer->Part() << endl;
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     // ask for compatible layers
00175     detLayers = initialLayer->compatibleLayers(fts,propDir);  
00176     // I have to fit by hand the first layer until the seedTSOS is defined on the first rechit layer
00177     // In fact the first layer is not returned by initialLayer->compatibleLayers.
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   // reset the refitter each seed refinement
00197   reset();
00198   
00199   MuonPatternRecoDumper debug;
00200   
00201   LogTrace(metname) << "Starting the refit"<<endl; 
00202 
00203   // this is the most outward TSOS (updated or predicted) onto a DetLayer
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   // the layers are ordered in agreement with the fit/propagation direction 
00215   for ( layer = detLayers.begin(); layer!= detLayers.end(); ++layer ) {
00216     
00217     //    bool firstTime = true;
00218 
00219     LogTrace(metname) << debug.dumpLayer(*layer);
00220     
00221     LogTrace(metname) << "search Trajectory Measurement from: " << lastTSOS.globalPosition();
00222     
00223     // pick the best measurement from each group
00224     std::vector<TrajectoryMeasurement> bestMeasurements = findBestMeasurements(*layer, lastTSOS);
00225 
00226     // RB: Different ways can be choosen if no bestMeasurement is available:
00227     // 1- check on lastTSOS-initialTSOS eta difference
00228     // 2- check on lastTSOS-lastButOneUpdatedTSOS eta difference
00229     // After this choice:
00230     // A- extract the measurements compatible with the initialTSOS (seed)
00231     // B- extract the measurements compatible with the lastButOneUpdatedTSOS
00232     // In ORCA the choice was 1A. Here I will try 1B and if it fail I'll try 1A
00233     // another possibility could be 2B and then 1A.
00234 
00235     // if no measurement found and the current TSOS has an eta very different
00236     // wrt the initial one (i.e. seed), then try to find the measurements
00237     // according to the lastButOne FTS. (1B)
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     //if no measurement found and the current FTS has an eta very different
00246     //wrt the initial one (i.e. seed), then try to find the measurements
00247     //according to the initial FTS. (1A)
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     // FIXME: uncomment this line!!
00255     // if(!bestMeasurement && firstTime) break;
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     // SL in case no valid mesurement is found, still I want to use the predicted
00271     // state for the following measurement serches. I take the first in the
00272     // container. FIXME!!! I want to carefully check this!!!!!
00273     else{
00274       LogTrace(metname)<<"No best measurement found"<<endl;
00275       //       if (!theMeasurementCache.empty()){
00276       //        LogTrace(metname)<<"but the #of measurement is "<<theMeasurementCache.size()<<endl;
00277       //         lastTSOS = theMeasurementCache.front().predictedState();
00278       //       }
00279     }
00280   } // loop over layers
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       // this should be fixed either in RecoMuon/MeasurementDet/MuonDetLayerMeasurements or
00302       // RecoMuon/DetLayers/MuRingForwardDoubleLayer
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   } // end for
00375 }