CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/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   LogTrace(metname) << "Trajectory State on Surface before the extrapolation"<<endl;
00167   LogTrace(metname) << debug.dumpTSOS(lastTSOS);
00168   
00169   // Segment layer
00170   LogTrace(metname) << "The RecSegment relies on: "<<endl;
00171   LogTrace(metname) << debug.dumpMuonId(lastDetId);
00172 
00173   DetLayerWithState inputFromSeed = propagateTheSeedTSOS(lastTSOS, lastDetId);
00174 
00175   // refine the FTS given by the seed
00176 
00177   // the trajectory is filled in the refitter::refit
00178   filter()->refit(inputFromSeed.second,inputFromSeed.first,trajectoryFW);
00179 
00180   // "0th order" check...
00181   if( trajectoryFW.empty() ) {
00182     LogTrace(metname) << "Forward trajectory EMPTY! No trajectory will be loaded!" << endl;
00183     return trajectoryContainer;
00184   }
00185 
00186   // Get the last TSOS
00187   //  TrajectoryStateOnSurface tsosAfterRefit = filter()->lastUpdatedTSOS();     // this is the last UPDATED TSOS
00188   TrajectoryStateOnSurface tsosAfterRefit = filter()->lastCompatibleTSOS();     // this is the last COMPATIBLE TSOS
00189 
00190   LogTrace(metname) << "StandAloneMuonTrajectoryBuilder filter output " << endl;
00191   LogTrace(metname) << debug.dumpTSOS(tsosAfterRefit);
00192   
00193 
00194   /*
00195   // -- 1st attempt
00196   if( filter()->isCompatibilitySatisfied() ) {
00197     if( filter()->layers().size() )   //  OR   if( filter()->goodState() ) ???  Maybe when only RPC hits are used...
00198       LogTrace(metname) << debug.dumpLayer( filter()->lastDetLayer() );
00199     else {
00200       LogTrace(metname) << "Compatibility satisfied, but all RecHits are invalid! A trajectory with only invalid hits will be loaded!" << endl;
00201       trajectoryContainer.push_back(new Trajectory(trajectoryFW));
00202       return trajectoryContainer;
00203     }
00204   }
00205   else {
00206     LogTrace(metname) << "Compatibility NOT satisfied after Forward filter! No trajectory will be loaded!" << endl;
00207     LogTrace(metname) << "Total chambers: " << filter()->getTotalCompatibleChambers() << "; DT: " 
00208                       << filter()->getDTCompatibleChambers() << "; CSC: " << filter()->getCSCCompatibleChambers() << endl;
00209     return trajectoryContainer; 
00210   }
00211   // -- end 1st attempt
00212   */
00213 
00214   // -- 2nd attempt
00215   if( filter()->goodState() ) {
00216     LogTrace(metname) << debug.dumpLayer( filter()->lastDetLayer() );
00217   }
00218   else if( filter()->isCompatibilitySatisfied() ) {
00219     int foundValidRh = trajectoryFW.foundHits();  // number of valid hits
00220     LogTrace(metname) << "Compatibility satisfied after Forward filter, but too few valid RecHits ("
00221                       << foundValidRh << ")." << endl
00222                       << "A trajectory with only invalid RecHits will be loaded!" << endl;
00223     if(!foundValidRh) {
00224       trajectoryContainer.push_back(new Trajectory(trajectoryFW));
00225       return trajectoryContainer;
00226     }
00227     Trajectory defaultTraj(seed,fwDirection);
00228     filter()->createDefaultTrajectory(trajectoryFW, defaultTraj);
00229     trajectoryContainer.push_back(new Trajectory(defaultTraj));
00230     return trajectoryContainer;
00231   }
00232   else {
00233     LogTrace(metname) << "Compatibility NOT satisfied after Forward filter! No trajectory will be loaded!" << endl;
00234     LogTrace(metname) << "Total compatible chambers: " << filter()->getTotalCompatibleChambers() << ";  DT: " 
00235                       << filter()->getDTCompatibleChambers() << ";  CSC: " << filter()->getCSCCompatibleChambers() 
00236                       << ";  RPC: " << filter()->getRPCCompatibleChambers() << endl;
00237     return trajectoryContainer; 
00238   }
00239   // -- end 2nd attempt
00240 
00241   LogTrace(metname) << "Number of DT/CSC/RPC chamber used (fw): " 
00242        << filter()->getDTChamberUsed() << "/"
00243        << filter()->getCSCChamberUsed() << "/"
00244        << filter()->getRPCChamberUsed() <<endl;
00245   LogTrace(metname) << "Momentum: " <<tsosAfterRefit.freeState()->momentum();
00246   
00247 
00248   if(!doBackwardFilter) { 
00249     LogTrace(metname) << "Only forward refit requested. No backward refit will be performed!"<<endl;
00250     
00251     // ***** Refit of fwd step *****
00252     //    if (doRefit && !trajectoryFW.empty() && filter()->goodState()){    // CHECK!!! Can trajectoryFW really be empty at this point??? And goodState...?
00253     if(doRefit) {
00254       pair<bool,Trajectory> refitResult = refitter()->refit(trajectoryFW);
00255       if(refitResult.first) {
00256         trajectoryContainer.push_back(new Trajectory(refitResult.second));
00257         LogTrace(metname) << "StandAloneMuonTrajectoryBuilder refit output " << endl ;
00258         LogTrace(metname) << debug.dumpTSOS(refitResult.second.lastMeasurement().updatedState());
00259       }
00260       else
00261         trajectoryContainer.push_back(new Trajectory(trajectoryFW));
00262     }
00263     else
00264       trajectoryContainer.push_back(new Trajectory(trajectoryFW));
00265 
00266     LogTrace(metname) << "Trajectory saved" << endl;
00267     return trajectoryContainer;
00268   }
00269 
00270 
00271   // ***** Backward filtering *****
00272   
00273   TrajectorySeed seedForBW;
00274 
00275   if(theBWSeedType == "noSeed") {
00276     TrajectorySeed seedVoid;
00277     seedForBW = seedVoid;
00278   }
00279   else if(theBWSeedType == "fromFWFit") {
00280 
00281     
00282     
00283     PTrajectoryStateOnDet seedTSOS =
00284       trajectoryStateTransform::persistentState( tsosAfterRefit, trajectoryFW.lastMeasurement().recHit()->geographicalId().rawId());
00285     
00286     edm::OwnVector<TrackingRecHit> recHitsContainer;
00287     PropagationDirection seedDirection = (theSeedPosition == recoMuon::in) ?  oppositeToMomentum : alongMomentum;
00288     TrajectorySeed fwFit(seedTSOS,recHitsContainer,seedDirection);
00289 
00290     seedForBW = fwFit;
00291   }
00292   else if(theBWSeedType == "fromGenerator") {
00293     seedForBW = seed;
00294   }
00295   else
00296     LogWarning(metname) << "Wrong seed type for the backward filter!";
00297 
00298   PropagationDirection bwDirection = (theSeedPosition == recoMuon::in) ?  oppositeToMomentum : alongMomentum;
00299   Trajectory trajectoryBW(seedForBW,bwDirection);
00300 
00301   // FIXME! under check!
00302   bwfilter()->refit(tsosAfterRefit,filter()->lastDetLayer(),trajectoryBW);
00303 
00304   // Get the last TSOS
00305   TrajectoryStateOnSurface tsosAfterBWRefit = bwfilter()->lastUpdatedTSOS();
00306 
00307   LogTrace(metname) << "StandAloneMuonTrajectoryBuilder BW filter output " << endl ;
00308   LogTrace(metname) << debug.dumpTSOS(tsosAfterBWRefit);
00309 
00310   LogTrace(metname) 
00311     << "Number of RecHits: " << trajectoryBW.foundHits() << "\n"
00312     << "Number of DT/CSC/RPC chamber used (bw): " 
00313     << bwfilter()->getDTChamberUsed() << "/"
00314     << bwfilter()->getCSCChamberUsed() << "/" 
00315     << bwfilter()->getRPCChamberUsed();
00316   
00317   // -- The trajectory is "good" if there are at least 2 chambers used in total and at
00318   //    least 1 is "tracking" (DT or CSC)
00319   // -- The trajectory satisfies the "compatibility" requirements if there are at least 
00320   //    2 compatible chambers (not necessarily used!) in total and at
00321   //    least 1 is "tracking" (DT or CSC)
00322   // 1st attempt
00323   /*
00324   if (bwfilter()->isCompatibilitySatisfied()) {
00325     
00326     if (doRefit && !trajectoryBW.empty() && bwfilter()->goodState()){
00327       pair<bool,Trajectory> refitResult = refitter()->refit(trajectoryBW);
00328       if (refitResult.first){
00329         trajectoryContainer.push_back(new Trajectory(refitResult.second));
00330         LogTrace(metname) << "StandAloneMuonTrajectoryBuilder Refit output " << endl;
00331         LogTrace(metname) << debug.dumpTSOS(refitResult.second.lastMeasurement().updatedState());
00332       }
00333       else
00334         trajectoryContainer.push_back(new Trajectory(trajectoryBW));
00335     }
00336     else
00337       trajectoryContainer.push_back(new Trajectory(trajectoryBW));
00338     
00339     LogTrace(metname)<< "Trajectory saved" << endl;
00340     
00341   }
00342   //if the trajectory is not saved, but at least two chamber are used in the
00343   //forward filtering, try to build a new trajectory starting from the old
00344   //trajectory w/o the latest measurement and a looser chi2 cut
00345   else if ( filter()->getTotalChamberUsed() >= 2 ) {
00346     LogTrace(metname)<< "Trajectory NOT saved. Second Attempt." << endl;
00347     // FIXME:
00348     // a better choice could be: identify the poorest one, exclude it, redo
00349     // the fw and bw filtering. Or maybe redo only the bw without the excluded
00350     // measure. As first step I will port the ORCA algo, then I will move to the
00351     // above pattern.
00352     
00353   }
00354 
00355   else {
00356     LogTrace(metname) << "Compatibility NOT satisfied after Backward filter!" << endl;
00357     LogTrace(metname) << "The result of Forward filter will be loaded!" << endl;
00358 
00359     trajectoryContainer.push_back(new Trajectory(trajectoryFW));
00360   }
00361   */
00362   // end 1st attempt
00363 
00364   // 2nd attempt
00365   if( bwfilter()->goodState() ) {
00366     LogTrace(metname) << debug.dumpLayer( bwfilter()->lastDetLayer() );
00367   }
00368   else if( bwfilter()->isCompatibilitySatisfied() ) {
00369     LogTrace(metname) << "Compatibility satisfied after Backward filter, but too few valid RecHits ("
00370                       << trajectoryBW.foundHits() << ")." << endl
00371                       << "The (good) result of FW filter will be loaded!" << endl;
00372     trajectoryContainer.push_back(new Trajectory(trajectoryFW));
00373     return trajectoryContainer;
00374   }
00375   else {
00376     LogTrace(metname) << "Compatibility NOT satisfied after Backward filter!" << endl 
00377                       << "The Forward trajectory will be invalidated and then loaded!" << endl;
00378     Trajectory defaultTraj(seed,fwDirection);
00379     filter()->createDefaultTrajectory(trajectoryFW, defaultTraj);
00380     trajectoryContainer.push_back(new Trajectory(defaultTraj));
00381     return trajectoryContainer;
00382   }
00383   // end 2nd attempt
00384 
00385   if(doRefit) {
00386     pair<bool,Trajectory> refitResult = refitter()->refit(trajectoryBW);
00387     if(refitResult.first) {
00388       trajectoryContainer.push_back(new Trajectory(refitResult.second));
00389       LogTrace(metname) << "StandAloneMuonTrajectoryBuilder Refit output " << endl;
00390       LogTrace(metname) << debug.dumpTSOS(refitResult.second.lastMeasurement().updatedState());
00391     }
00392     else
00393       trajectoryContainer.push_back(new Trajectory(trajectoryBW));
00394   }
00395   else
00396     trajectoryContainer.push_back(new Trajectory(trajectoryBW));
00397     
00398   LogTrace(metname) << "Trajectory saved" << endl;
00399     
00400   return trajectoryContainer;
00401 }
00402 
00403 
00404 StandAloneMuonTrajectoryBuilder::DetLayerWithState
00405 StandAloneMuonTrajectoryBuilder::propagateTheSeedTSOS(TrajectoryStateOnSurface& aTSOS, DetId& aDetId) {
00406 
00407   const std::string metname = "Muon|RecoMuon|StandAloneMuonTrajectoryBuilder";
00408   MuonPatternRecoDumper debug;
00409 
00410   DetId seedDetId(aDetId);
00411   //  const GeomDet* gdet = theService->trackingGeometry()->idToDet( seedDetId );
00412 
00413   TrajectoryStateOnSurface initialState(aTSOS);
00414 
00415   LogTrace(metname)<<"Seed's Pt: "<<initialState.freeState()->momentum().perp()<<endl;
00416 
00417   LogTrace(metname)<< "Seed's id: "<< endl ;
00418   LogTrace(metname) << debug.dumpMuonId(seedDetId);
00419   
00420   // Get the layer on which the seed relies
00421   const DetLayer *initialLayer = theService->detLayerGeometry()->idToLayer( seedDetId );
00422 
00423   LogTrace(metname)<< "Seed's detLayer: "<< endl ;
00424   LogTrace(metname) << debug.dumpLayer(initialLayer);
00425 
00426   LogTrace(metname)<< "TrajectoryStateOnSurface before propagation:" << endl;
00427   LogTrace(metname) << debug.dumpTSOS(initialState);
00428 
00429 
00430   PropagationDirection detLayerOrder = (theSeedPosition == recoMuon::in) ? oppositeToMomentum : alongMomentum;
00431 
00432   // ask for compatible layers
00433   vector<const DetLayer*> detLayers;
00434 
00435   if(theNavigationType == "Standard")
00436     detLayers = initialLayer->compatibleLayers( *initialState.freeState(),detLayerOrder); 
00437   else if (theNavigationType == "Direct"){
00438     DirectMuonNavigation navigation( &*theService->detLayerGeometry() );
00439     detLayers = navigation.compatibleLayers( *initialState.freeState(),detLayerOrder);
00440   }
00441   else
00442     edm::LogError(metname) << "No Properly Navigation Selected!!"<<endl;
00443 
00444  
00445   LogTrace(metname) << "There are "<< detLayers.size() <<" compatible layers"<<endl;
00446   
00447   DetLayerWithState result = DetLayerWithState(initialLayer,initialState);
00448 
00449   if(detLayers.size()){
00450 
00451     LogTrace(metname) << "Compatible layers:"<<endl;
00452     for( vector<const DetLayer*>::const_iterator layer = detLayers.begin(); 
00453          layer != detLayers.end(); layer++){
00454       LogTrace(metname) << debug.dumpMuonId((*layer)->basicComponents().front()->geographicalId());
00455       LogTrace(metname) << debug.dumpLayer(*layer);
00456     }
00457 
00458     const DetLayer* finalLayer = detLayers.back();
00459 
00460     if(theSeedPosition == recoMuon::in) LogTrace(metname) << "Most internal one:"<<endl;
00461     else LogTrace(metname) << "Most external one:"<<endl;
00462     
00463     LogTrace(metname) << debug.dumpLayer(finalLayer);
00464     
00465     const TrajectoryStateOnSurface propagatedState = 
00466       theService->propagator(theSeedPropagatorName)->propagate(initialState,
00467                                                                finalLayer->surface());
00468 
00469     if(propagatedState.isValid()){
00470       result = DetLayerWithState(finalLayer,propagatedState);
00471       
00472       LogTrace(metname) << "Trajectory State on Surface after the extrapolation"<<endl;
00473       LogTrace(metname) << debug.dumpTSOS(propagatedState);
00474       LogTrace(metname) << debug.dumpLayer(finalLayer);
00475     }
00476     else 
00477       LogTrace(metname)<< "Extrapolation failed. Keep the original seed state" <<endl;
00478   }
00479   else
00480     LogTrace(metname)<< "No compatible layers. Keep the original seed state" <<endl;
00481   
00482   return result;
00483 }
00484 
00485