CMS 3D CMS Logo

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