CMS 3D CMS Logo

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

Go to the documentation of this file.
00001 
00011 #include "RecoMuon/StandAloneTrackFinder/interface/StandAloneTrajectoryBuilder.h"
00012 
00013 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00014 #include "DataFormats/TrajectorySeed/interface/TrajectorySeed.h"
00015 #include "DataFormats/TrajectoryState/interface/PTrajectoryStateOnDet.h"
00016 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h"
00017 #include "DataFormats/TrajectorySeed/interface/PropagationDirection.h"
00018 
00019 #include "RecoMuon/StandAloneTrackFinder/interface/StandAloneMuonFilter.h"
00020 #include "RecoMuon/StandAloneTrackFinder/interface/StandAloneMuonBackwardFilter.h"
00021 #include "RecoMuon/StandAloneTrackFinder/interface/StandAloneMuonRefitter.h"
00022 
00023 #include "RecoMuon/TrackingTools/interface/MuonPatternRecoDumper.h"
00024 #include "RecoMuon/TrackingTools/interface/MuonServiceProxy.h"
00025 #include "RecoMuon/Navigation/interface/DirectMuonNavigation.h"
00026 
00027 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00028 
00029 #include "DataFormats/TrajectoryState/interface/PTrajectoryStateOnDet.h"
00030 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h"
00031 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h"
00032 #include "TrackingTools/TrajectoryState/interface/FreeTrajectoryState.h"
00033 #include "TrackingTools/DetLayers/interface/DetLayer.h"
00034 #include "Geometry/CommonDetUnit/interface/GeomDet.h"
00035 #include "TrackingTools/TrackRefitter/interface/SeedTransformer.h"
00036 
00037 
00038 using namespace edm;
00039 using namespace std;
00040 
00041 StandAloneMuonTrajectoryBuilder::StandAloneMuonTrajectoryBuilder(const ParameterSet& par, 
00042                                                                  const MuonServiceProxy* service):theService(service){
00043   const std::string metname = "Muon|RecoMuon|StandAloneMuonTrajectoryBuilder";
00044   
00045   LogTrace(metname) << "constructor called" << endl;
00046 
00047   // The navigation type:
00048   // "Direct","Standard"
00049   theNavigationType = par.getParameter<string>("NavigationType");
00050   
00051   // The inward-outward fitter (starts from seed state)
00052   ParameterSet filterPSet = par.getParameter<ParameterSet>("FilterParameters");
00053   filterPSet.addParameter<string>("NavigationType",theNavigationType);
00054   theFilter = new StandAloneMuonFilter(filterPSet,theService);
00055 
00056   // Fit direction
00057   string seedPosition = par.getParameter<string>("SeedPosition");
00058   
00059   if (seedPosition == "in" ) theSeedPosition = recoMuon::in;
00060   else if (seedPosition == "out" ) theSeedPosition = recoMuon::out;
00061   else 
00062     throw cms::Exception("StandAloneMuonFilter constructor") 
00063       <<"Wrong seed position chosen in StandAloneMuonFilter::StandAloneMuonFilter ParameterSet"
00064       << "\n"
00065       << "Possible choices are:"
00066       << "\n"
00067       << "SeedPosition = in or SeedPosition = out";
00068   
00069   // Propagator for the seed extrapolation
00070   theSeedPropagatorName = par.getParameter<string>("SeedPropagator");
00071   
00072   // Disable/Enable the backward filter
00073   doBackwardFilter = par.getParameter<bool>("DoBackwardFilter");
00074   
00075   // Disable/Enable the refit of the trajectory
00076   doRefit = par.getParameter<bool>("DoRefit");
00077    
00078   // Disable/Enable the refit of the trajectory seed
00079   doSeedRefit = par.getParameter<bool>("DoSeedRefit");
00080    
00081   if(doBackwardFilter){
00082     // The outward-inward fitter (starts from theFilter outermost state)
00083     ParameterSet bwFilterPSet = par.getParameter<ParameterSet>("BWFilterParameters");
00084     //  theBWFilter = new StandAloneMuonBackwardFilter(bwFilterPSet,theService); // FIXME
00085     bwFilterPSet.addParameter<string>("NavigationType",theNavigationType);
00086     theBWFilter = new StandAloneMuonFilter(bwFilterPSet,theService);
00087     
00088     theBWSeedType = bwFilterPSet.getParameter<string>("BWSeedType");
00089   }
00090 
00091   if(doRefit){
00092     // The outward-inward fitter (starts from theBWFilter innermost state)
00093     ParameterSet refitterPSet = par.getParameter<ParameterSet>("RefitterParameters");
00094     theRefitter = new StandAloneMuonRefitter(refitterPSet, theService);
00095   }
00096 
00097   // The seed transformer (used to refit the seed and get the seed transient state)
00098   //  ParameterSet seedTransformerPSet = par.getParameter<ParameterSet>("SeedTransformerParameters");
00099   ParameterSet seedTransformerParameters = par.getParameter<ParameterSet>("SeedTransformerParameters");
00100   theSeedTransformer = new SeedTransformer(seedTransformerParameters);
00101 
00102 }
00103 
00104 void StandAloneMuonTrajectoryBuilder::setEvent(const edm::Event& event){
00105   theFilter->setEvent(event);
00106    if(doBackwardFilter) theBWFilter->setEvent(event);
00107 }
00108 
00109 StandAloneMuonTrajectoryBuilder::~StandAloneMuonTrajectoryBuilder(){
00110 
00111   LogTrace("Muon|RecoMuon|StandAloneMuonTrajectoryBuilder") 
00112     << "StandAloneMuonTrajectoryBuilder destructor called" << endl;
00113   
00114   if(theFilter) delete theFilter;
00115   if(doBackwardFilter && theBWFilter) delete theBWFilter;
00116   if(doRefit && theRefitter) delete theRefitter;
00117   if(theSeedTransformer) delete theSeedTransformer;
00118 }
00119 
00120 
00121 namespace {
00122   struct Resetter {
00123     StandAloneMuonFilter * mf;
00124     explicit Resetter(StandAloneMuonFilter * imf) : mf(imf){}
00125     ~Resetter() { if(mf) mf->reset();}
00126   };
00127 }
00128 
00129 MuonTrajectoryBuilder::TrajectoryContainer 
00130 StandAloneMuonTrajectoryBuilder::trajectories(const TrajectorySeed& seed){ 
00131   Resetter fwReset(filter());
00132   Resetter bwReset(bwfilter());
00133 
00134   const std::string metname = "Muon|RecoMuon|StandAloneMuonTrajectoryBuilder";
00135   MuonPatternRecoDumper debug;
00136 
00137   // Set the services for the seed transformer
00138   theSeedTransformer->setServices(theService->eventSetup());
00139 
00140   // the trajectory container. In principle starting from one seed we can
00141   // obtain more than one trajectory. TODO: this feature is not yet implemented!
00142   TrajectoryContainer trajectoryContainer;
00143 
00144   PropagationDirection fwDirection = (theSeedPosition == recoMuon::in) ? alongMomentum : oppositeToMomentum;  
00145   Trajectory trajectoryFW(seed,fwDirection);
00146 
00147   TrajectoryStateOnSurface lastTSOS;
00148   DetId lastDetId;
00149 
00150   vector<Trajectory> seedTrajectories;
00151 
00152   if(doSeedRefit) {
00153     seedTrajectories = theSeedTransformer->seedTransform(seed);
00154     if(!seedTrajectories.empty()) {
00155       TrajectoryMeasurement lastTM(seedTrajectories.front().lastMeasurement());
00156       lastTSOS = lastTM.updatedState();
00157       lastDetId = lastTM.recHit()->geographicalId();
00158     }
00159   }
00160   
00161   if(!doSeedRefit || seedTrajectories.empty()) {
00162     lastTSOS = theSeedTransformer->seedTransientState(seed);
00163     lastDetId = seed.startingState().detId();
00164   }
00165 
00166   DetLayerWithState inputFromSeed = propagateTheSeedTSOS(lastTSOS, lastDetId);
00167 
00168   // refine the FTS given by the seed
00169 
00170   // the trajectory is filled in the refitter::refit
00171   filter()->refit(inputFromSeed.second,inputFromSeed.first,trajectoryFW);
00172 
00173   // "0th order" check...
00174   if( trajectoryFW.empty() ) {
00175     LogTrace(metname) << "Forward trajectory EMPTY! No trajectory will be loaded!" << endl;
00176     return trajectoryContainer;
00177   }
00178 
00179   // Get the last TSOS
00180   //  TrajectoryStateOnSurface tsosAfterRefit = filter()->lastUpdatedTSOS();     // this is the last UPDATED TSOS
00181   TrajectoryStateOnSurface tsosAfterRefit = filter()->lastCompatibleTSOS();     // this is the last COMPATIBLE TSOS
00182 
00183   LogTrace(metname) << "StandAloneMuonTrajectoryBuilder filter output " << endl;
00184   LogTrace(metname) << debug.dumpTSOS(tsosAfterRefit);
00185   
00186 
00187   /*
00188   // -- 1st attempt
00189   if( filter()->isCompatibilitySatisfied() ) {
00190     if( filter()->layers().size() )   //  OR   if( filter()->goodState() ) ???  Maybe when only RPC hits are used...
00191       LogTrace(metname) << debug.dumpLayer( filter()->lastDetLayer() );
00192     else {
00193       LogTrace(metname) << "Compatibility satisfied, but all RecHits are invalid! A trajectory with only invalid hits will be loaded!" << endl;
00194       trajectoryContainer.push_back(new Trajectory(trajectoryFW));
00195       return trajectoryContainer;
00196     }
00197   }
00198   else {
00199     LogTrace(metname) << "Compatibility NOT satisfied after Forward filter! No trajectory will be loaded!" << endl;
00200     LogTrace(metname) << "Total chambers: " << filter()->getTotalCompatibleChambers() << "; DT: " 
00201                       << filter()->getDTCompatibleChambers() << "; CSC: " << filter()->getCSCCompatibleChambers() << endl;
00202     return trajectoryContainer; 
00203   }
00204   // -- end 1st attempt
00205   */
00206 
00207   // -- 2nd attempt
00208   if( filter()->goodState() ) {
00209     LogTrace(metname) << debug.dumpLayer( filter()->lastDetLayer() );
00210   }
00211   else if( filter()->isCompatibilitySatisfied() ) {
00212     int foundValidRh = trajectoryFW.foundHits();  // number of valid hits
00213     LogTrace(metname) << "Compatibility satisfied after Forward filter, but too few valid RecHits ("
00214                       << foundValidRh << ")." << endl
00215                       << "A trajectory with only invalid RecHits will be loaded!" << endl;
00216     if(!foundValidRh) {
00217       trajectoryContainer.push_back(new Trajectory(trajectoryFW));
00218       return trajectoryContainer;
00219     }
00220     Trajectory defaultTraj(seed,fwDirection);
00221     filter()->createDefaultTrajectory(trajectoryFW, defaultTraj);
00222     trajectoryContainer.push_back(new Trajectory(defaultTraj));
00223     return trajectoryContainer;
00224   }
00225   else {
00226     LogTrace(metname) << "Compatibility NOT satisfied after Forward filter! No trajectory will be loaded!" << endl;
00227     LogTrace(metname) << "Total compatible chambers: " << filter()->getTotalCompatibleChambers() << ";  DT: " 
00228                       << filter()->getDTCompatibleChambers() << ";  CSC: " << filter()->getCSCCompatibleChambers() 
00229                       << ";  RPC: " << filter()->getRPCCompatibleChambers() << endl;
00230     return trajectoryContainer; 
00231   }
00232   // -- end 2nd attempt
00233 
00234   LogTrace(metname) << "Number of DT/CSC/RPC chamber used (fw): " 
00235        << filter()->getDTChamberUsed() << "/"
00236        << filter()->getCSCChamberUsed() << "/"
00237        << filter()->getRPCChamberUsed() <<endl;
00238   LogTrace(metname) << "Momentum: " <<tsosAfterRefit.freeState()->momentum();
00239   
00240 
00241   if(!doBackwardFilter) { 
00242     LogTrace(metname) << "Only forward refit requested. No backward refit will be performed!"<<endl;
00243     
00244     // ***** Refit of fwd step *****
00245     //    if (doRefit && !trajectoryFW.empty() && filter()->goodState()){    // CHECK!!! Can trajectoryFW really be empty at this point??? And goodState...?
00246     if(doRefit) {
00247       pair<bool,Trajectory> refitResult = refitter()->refit(trajectoryFW);
00248       if(refitResult.first) {
00249         trajectoryContainer.push_back(new Trajectory(refitResult.second));
00250         LogTrace(metname) << "StandAloneMuonTrajectoryBuilder refit output " << endl ;
00251         LogTrace(metname) << debug.dumpTSOS(refitResult.second.lastMeasurement().updatedState());
00252       }
00253       else
00254         trajectoryContainer.push_back(new Trajectory(trajectoryFW));
00255     }
00256     else
00257       trajectoryContainer.push_back(new Trajectory(trajectoryFW));
00258 
00259     LogTrace(metname) << "Trajectory saved" << endl;
00260     return trajectoryContainer;
00261   }
00262 
00263 
00264   // ***** Backward filtering *****
00265   
00266   TrajectorySeed seedForBW;
00267 
00268   if(theBWSeedType == "noSeed") {
00269     TrajectorySeed seedVoid;
00270     seedForBW = seedVoid;
00271   }
00272   else if(theBWSeedType == "fromFWFit") {
00273 
00274     TrajectoryStateTransform tsTransform;
00275     
00276     PTrajectoryStateOnDet *seedTSOS =
00277       tsTransform.persistentState( tsosAfterRefit, trajectoryFW.lastMeasurement().recHit()->geographicalId().rawId());
00278     
00279     edm::OwnVector<TrackingRecHit> recHitsContainer;
00280     PropagationDirection seedDirection = (theSeedPosition == recoMuon::in) ?  oppositeToMomentum : alongMomentum;
00281     TrajectorySeed fwFit(*seedTSOS,recHitsContainer,seedDirection);
00282 
00283     seedForBW = fwFit;
00284   }
00285   else if(theBWSeedType == "fromGenerator") {
00286     seedForBW = seed;
00287   }
00288   else
00289     LogWarning(metname) << "Wrong seed type for the backward filter!";
00290 
00291   PropagationDirection bwDirection = (theSeedPosition == recoMuon::in) ?  oppositeToMomentum : alongMomentum;
00292   Trajectory trajectoryBW(seedForBW,bwDirection);
00293 
00294   // FIXME! under check!
00295   bwfilter()->refit(tsosAfterRefit,filter()->lastDetLayer(),trajectoryBW);
00296 
00297   // Get the last TSOS
00298   TrajectoryStateOnSurface tsosAfterBWRefit = bwfilter()->lastUpdatedTSOS();
00299 
00300   LogTrace(metname) << "StandAloneMuonTrajectoryBuilder BW filter output " << endl ;
00301   LogTrace(metname) << debug.dumpTSOS(tsosAfterBWRefit);
00302 
00303   LogTrace(metname) 
00304     << "Number of RecHits: " << trajectoryBW.foundHits() << "\n"
00305     << "Number of DT/CSC/RPC chamber used (bw): " 
00306     << bwfilter()->getDTChamberUsed() << "/"
00307     << bwfilter()->getCSCChamberUsed() << "/" 
00308     << bwfilter()->getRPCChamberUsed();
00309   
00310   // -- The trajectory is "good" if there are at least 2 chambers used in total and at
00311   //    least 1 is "tracking" (DT or CSC)
00312   // -- The trajectory satisfies the "compatibility" requirements if there are at least 
00313   //    2 compatible chambers (not necessarily used!) in total and at
00314   //    least 1 is "tracking" (DT or CSC)
00315   // 1st attempt
00316   /*
00317   if (bwfilter()->isCompatibilitySatisfied()) {
00318     
00319     if (doRefit && !trajectoryBW.empty() && bwfilter()->goodState()){
00320       pair<bool,Trajectory> refitResult = refitter()->refit(trajectoryBW);
00321       if (refitResult.first){
00322         trajectoryContainer.push_back(new Trajectory(refitResult.second));
00323         LogTrace(metname) << "StandAloneMuonTrajectoryBuilder Refit output " << endl;
00324         LogTrace(metname) << debug.dumpTSOS(refitResult.second.lastMeasurement().updatedState());
00325       }
00326       else
00327         trajectoryContainer.push_back(new Trajectory(trajectoryBW));
00328     }
00329     else
00330       trajectoryContainer.push_back(new Trajectory(trajectoryBW));
00331     
00332     LogTrace(metname)<< "Trajectory saved" << endl;
00333     
00334   }
00335   //if the trajectory is not saved, but at least two chamber are used in the
00336   //forward filtering, try to build a new trajectory starting from the old
00337   //trajectory w/o the latest measurement and a looser chi2 cut
00338   else if ( filter()->getTotalChamberUsed() >= 2 ) {
00339     LogTrace(metname)<< "Trajectory NOT saved. Second Attempt." << endl;
00340     // FIXME:
00341     // a better choice could be: identify the poorest one, exclude it, redo
00342     // the fw and bw filtering. Or maybe redo only the bw without the excluded
00343     // measure. As first step I will port the ORCA algo, then I will move to the
00344     // above pattern.
00345     
00346   }
00347 
00348   else {
00349     LogTrace(metname) << "Compatibility NOT satisfied after Backward filter!" << endl;
00350     LogTrace(metname) << "The result of Forward filter will be loaded!" << endl;
00351 
00352     trajectoryContainer.push_back(new Trajectory(trajectoryFW));
00353   }
00354   */
00355   // end 1st attempt
00356 
00357   // 2nd attempt
00358   if( bwfilter()->goodState() ) {
00359     LogTrace(metname) << debug.dumpLayer( bwfilter()->lastDetLayer() );
00360   }
00361   else if( bwfilter()->isCompatibilitySatisfied() ) {
00362     LogTrace(metname) << "Compatibility satisfied after Backward filter, but too few valid RecHits ("
00363                       << trajectoryBW.foundHits() << ")." << endl
00364                       << "The (good) result of FW filter will be loaded!" << endl;
00365     trajectoryContainer.push_back(new Trajectory(trajectoryFW));
00366     return trajectoryContainer;
00367   }
00368   else {
00369     LogTrace(metname) << "Compatibility NOT satisfied after Backward filter!" << endl 
00370                       << "The Forward trajectory will be invalidated and then loaded!" << endl;
00371     Trajectory defaultTraj(seed,fwDirection);
00372     filter()->createDefaultTrajectory(trajectoryFW, defaultTraj);
00373     trajectoryContainer.push_back(new Trajectory(defaultTraj));
00374     return trajectoryContainer;
00375   }
00376   // end 2nd attempt
00377 
00378   if(doRefit) {
00379     pair<bool,Trajectory> refitResult = refitter()->refit(trajectoryBW);
00380     if(refitResult.first) {
00381       trajectoryContainer.push_back(new Trajectory(refitResult.second));
00382       LogTrace(metname) << "StandAloneMuonTrajectoryBuilder Refit output " << endl;
00383       LogTrace(metname) << debug.dumpTSOS(refitResult.second.lastMeasurement().updatedState());
00384     }
00385     else
00386       trajectoryContainer.push_back(new Trajectory(trajectoryBW));
00387   }
00388   else
00389     trajectoryContainer.push_back(new Trajectory(trajectoryBW));
00390     
00391   LogTrace(metname) << "Trajectory saved" << endl;
00392     
00393   return trajectoryContainer;
00394 }
00395 
00396 
00397 StandAloneMuonTrajectoryBuilder::DetLayerWithState
00398 StandAloneMuonTrajectoryBuilder::propagateTheSeedTSOS(TrajectoryStateOnSurface& aTSOS, DetId& aDetId) {
00399 
00400   const std::string metname = "Muon|RecoMuon|StandAloneMuonTrajectoryBuilder";
00401   MuonPatternRecoDumper debug;
00402 
00403   DetId seedDetId(aDetId);
00404   //  const GeomDet* gdet = theService->trackingGeometry()->idToDet( seedDetId );
00405 
00406   TrajectoryStateOnSurface initialState(aTSOS);
00407 
00408   LogTrace(metname)<<"Seed's Pt: "<<initialState.freeState()->momentum().perp()<<endl;
00409 
00410   LogTrace(metname)<< "Seed's id: "<< endl ;
00411   LogTrace(metname) << debug.dumpMuonId(seedDetId);
00412   
00413   // Get the layer on which the seed relies
00414   const DetLayer *initialLayer = theService->detLayerGeometry()->idToLayer( seedDetId );
00415 
00416   LogTrace(metname)<< "Seed's detLayer: "<< endl ;
00417   LogTrace(metname) << debug.dumpLayer(initialLayer);
00418 
00419   LogTrace(metname)<< "TrajectoryStateOnSurface before propagation:" << endl;
00420   LogTrace(metname) << debug.dumpTSOS(initialState);
00421 
00422 
00423   PropagationDirection detLayerOrder = (theSeedPosition == recoMuon::in) ? oppositeToMomentum : alongMomentum;
00424 
00425   // ask for compatible layers
00426   vector<const DetLayer*> detLayers;
00427 
00428   if(theNavigationType == "Standard")
00429     detLayers = initialLayer->compatibleLayers( *initialState.freeState(),detLayerOrder); 
00430   else if (theNavigationType == "Direct"){
00431     DirectMuonNavigation navigation( &*theService->detLayerGeometry() );
00432     detLayers = navigation.compatibleLayers( *initialState.freeState(),detLayerOrder);
00433   }
00434   else
00435     edm::LogError(metname) << "No Properly Navigation Selected!!"<<endl;
00436 
00437  
00438   LogTrace(metname) << "There are "<< detLayers.size() <<" compatible layers"<<endl;
00439   
00440   DetLayerWithState result = DetLayerWithState(initialLayer,initialState);
00441 
00442   if(detLayers.size()){
00443 
00444     LogTrace(metname) << "Compatible layers:"<<endl;
00445     for( vector<const DetLayer*>::const_iterator layer = detLayers.begin(); 
00446          layer != detLayers.end(); layer++){
00447       LogTrace(metname) << debug.dumpMuonId((*layer)->basicComponents().front()->geographicalId());
00448       LogTrace(metname) << debug.dumpLayer(*layer);
00449     }
00450 
00451     const DetLayer* finalLayer = detLayers.back();
00452 
00453     if(theSeedPosition == recoMuon::in) LogTrace(metname) << "Most internal one:"<<endl;
00454     else LogTrace(metname) << "Most external one:"<<endl;
00455     
00456     LogTrace(metname) << debug.dumpLayer(finalLayer);
00457     
00458     const TrajectoryStateOnSurface propagatedState = 
00459       theService->propagator(theSeedPropagatorName)->propagate(initialState,
00460                                                                finalLayer->surface());
00461 
00462     if(propagatedState.isValid()){
00463       result = DetLayerWithState(finalLayer,propagatedState);
00464       
00465       LogTrace(metname) << "Trajectory State on Surface after the extrapolation"<<endl;
00466       LogTrace(metname) << debug.dumpTSOS(propagatedState);
00467       LogTrace(metname) << debug.dumpLayer(finalLayer);
00468     }
00469     else 
00470       LogTrace(metname)<< "Extrapolation failed. Keep the original seed state" <<endl;
00471   }
00472   else
00473     LogTrace(metname)<< "No compatible layers. Keep the original seed state" <<endl;
00474   
00475   return result;
00476 }
00477 
00478