CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC2/src/RecoMuon/CosmicMuonProducer/src/CosmicMuonSmoother.cc

Go to the documentation of this file.
00001 
00015 #include "RecoMuon/CosmicMuonProducer/interface/CosmicMuonSmoother.h"
00016 
00017 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00018 #include "TrackingTools/KalmanUpdators/interface/KFUpdator.h"
00019 #include "TrackingTools/KalmanUpdators/interface/Chi2MeasurementEstimator.h"
00020 #include "TrackingTools/TrackFitters/interface/TrajectoryStateWithArbitraryError.h"
00021 #include "TrackingTools/TrackFitters/interface/TrajectoryStateCombiner.h"
00022 #include "TrackingTools/TransientTrackingRecHit/interface/TransientTrackingRecHit.h"
00023 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h"
00024 #include "DataFormats/GeometrySurface/interface/PlaneBuilder.h"
00025 
00026 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00027 
00028 using namespace edm;
00029 using namespace std;
00030 
00031 //
00032 // constructor
00033 //
00034 CosmicMuonSmoother::CosmicMuonSmoother(const ParameterSet& par, const MuonServiceProxy *service) : theService(service) {
00035 
00036   theUpdator     = new KFUpdator;
00037   theUtilities   = new CosmicMuonUtilities; 
00038   theEstimator   = new Chi2MeasurementEstimator(200.0);
00039   thePropagatorAlongName = par.getParameter<string>("PropagatorAlong");
00040   thePropagatorOppositeName = par.getParameter<string>("PropagatorOpposite");
00041   theErrorRescaling = par.getParameter<double>("RescalingFactor");
00042 
00043   category_ = "Muon|RecoMuon|CosmicMuon|CosmicMuonSmoother";
00044 }
00045 
00046 //
00047 // destructor
00048 //
00049 CosmicMuonSmoother::~CosmicMuonSmoother() {
00050 
00051   if ( theUpdator ) delete theUpdator;
00052   if ( theUtilities ) delete theUtilities;
00053   if ( theEstimator ) delete theEstimator;
00054 
00055 }
00056 
00057 
00058 //
00059 // fit and smooth trajectory
00060 //
00061 Trajectory CosmicMuonSmoother::trajectory(const Trajectory& t) const {
00062    std::vector<Trajectory> && fitted = fit(t);
00063    if (fitted.empty()) return  Trajectory();
00064    std::vector<Trajectory> && smoothed = smooth(fitted);
00065    return  smoothed.empty() ? Trajectory() : smoothed.front(); 
00066 }
00067 
00068 //
00069 // fit and smooth trajectory 
00070 //
00071 std::vector<Trajectory> CosmicMuonSmoother::trajectories(const TrajectorySeed& seed,
00072                                                    const ConstRecHitContainer& hits, 
00073                                                    const TrajectoryStateOnSurface& firstPredTsos) const {
00074 
00075   if ( hits.empty() ||!firstPredTsos.isValid() ) return vector<Trajectory>();
00076 
00077   LogTrace(category_)<< "trajectory begin (seed hits tsos)";
00078 
00079   TrajectoryStateOnSurface firstTsos = firstPredTsos;
00080   firstTsos.rescaleError(theErrorRescaling);
00081 
00082   LogTrace(category_)<< "first TSOS: "<<firstTsos;
00083 
00084   vector<Trajectory> fitted = fit(seed, hits, firstTsos);
00085   LogTrace(category_)<< "fitted: "<<fitted.size();
00086   vector<Trajectory> smoothed = smooth(fitted);
00087   LogTrace(category_)<< "smoothed: "<<smoothed.size();
00088 
00089   return smoothed;
00090 
00091 }
00092 
00093 //
00094 // fit trajectory
00095 //
00096 vector<Trajectory> CosmicMuonSmoother::fit(const Trajectory& t) const {
00097 
00098   if ( t.empty() ) return vector<Trajectory>();
00099 
00100   LogTrace(category_)<< "fit begin (trajectory) ";
00101 
00102   TrajectoryStateOnSurface firstTsos = initialState(t); 
00103   if ( !firstTsos.isValid() ) {
00104     LogTrace(category_)<< "Error: firstTsos invalid. ";
00105     return vector<Trajectory>();
00106   }
00107 
00108   LogTrace(category_)<< "firstTsos: "<<firstTsos;
00109 
00110   ConstRecHitContainer hits = t.recHits();
00111   LogTrace(category_)<< "hits: "<<hits.size();
00112   LogTrace(category_)<<"hit front" <<hits.front()->globalPosition()<< " hit back" 
00113     <<hits.back()->globalPosition();
00114 
00115   sortHitsAlongMom(hits, firstTsos);
00116 
00117   LogTrace(category_)<<"after sorting hit front" <<hits.front()->globalPosition()<< " hit back" 
00118     <<hits.back()->globalPosition();
00119 
00120   return fit(t.seed(), hits, firstTsos);
00121 
00122 }
00123 
00124 
00125 //
00126 // fit trajectory
00127 //
00128 vector<Trajectory> CosmicMuonSmoother::fit(const TrajectorySeed& seed,
00129                                           const ConstRecHitContainer& hits, 
00130                                           const TrajectoryStateOnSurface& firstPredTsos) const {
00131 
00132   LogTrace(category_)<< "fit begin (seed, hit, tsos).";
00133 
00134   if ( hits.empty() ) {
00135     LogTrace(category_)<< "Error: empty hits container.";
00136     return vector<Trajectory>();
00137   }
00138 
00139   Trajectory myTraj(seed, alongMomentum);
00140 
00141   TrajectoryStateOnSurface predTsos(firstPredTsos);
00142   LogTrace(category_)<< "first pred TSOS: "<<predTsos;
00143 
00144   if ( !predTsos.isValid() ) {
00145     LogTrace(category_)<< "Error: firstTsos invalid.";
00146     return vector<Trajectory>();
00147   }
00148   TrajectoryStateOnSurface currTsos;
00149 
00150   if ( hits.front()->isValid() ) {
00151 
00152     TransientTrackingRecHit::RecHitPointer preciseHit = hits.front()->clone(predTsos);
00153     LogTrace(category_)<<"first hit is at det "<< hits.front()->det()->surface().position();
00154 
00155     currTsos = theUpdator->update(predTsos, *preciseHit);
00156     if (!currTsos.isValid()){
00157       edm::LogWarning(category_)
00158         <<"an updated state is not valid. killing the trajectory.";
00159       return vector<Trajectory>();
00160     }
00161     myTraj.push(TrajectoryMeasurement(predTsos, currTsos, hits.front(),
00162                 theEstimator->estimate(predTsos, *hits.front()).second));
00163     if ( currTsos.isValid() )  LogTrace(category_)<< "first curr TSOS: "<<currTsos;
00164 
00165   } else {
00166 
00167     currTsos = predTsos;
00168     myTraj.push(TrajectoryMeasurement(predTsos, hits.front()));
00169   }
00170   //const TransientTrackingRecHit& firsthit = *hits.front();
00171 
00172   for ( ConstRecHitContainer::const_iterator ihit = hits.begin() + 1; 
00173         ihit != hits.end(); ++ihit ) {
00174 
00175     if ( !(**ihit).isValid() ) {
00176       LogTrace(category_)<< "Error: invalid hit.";
00177       continue;
00178     }
00179    if (currTsos.isValid())  {
00180      LogTrace(category_)<<"current pos "<<currTsos.globalPosition()
00181                        <<"mom "<<currTsos.globalMomentum();
00182     } else {
00183       LogTrace(category_)<<"current state invalid";
00184     }
00185 
00186     predTsos = propagatorAlong()->propagate(currTsos, (**ihit).det()->surface());
00187     LogTrace(category_)<<"predicted state propagate directly "<<predTsos.isValid();
00188 
00189     if ( !predTsos.isValid() ) {
00190       LogTrace(category_)<<"step-propagating from "<<currTsos.globalPosition() <<" to position: "<<(*ihit)->globalPosition();
00191       predTsos = theUtilities->stepPropagate(currTsos, (*ihit), *propagatorAlong());
00192     }
00193     if ( !predTsos.isValid() && (fabs(theService->magneticField()->inTesla(GlobalPoint(0,0,0)).z()) < 0.01) && (theService->propagator("StraightLinePropagator").isValid() ) ) {
00194       LogTrace(category_)<<"straight-line propagating from "<<currTsos.globalPosition() <<" to position: "<<(*ihit)->globalPosition();
00195       predTsos = theService->propagator("StraightLinePropagator")->propagate(currTsos, (**ihit).det()->surface());
00196     }
00197     if (predTsos.isValid())  {
00198       LogTrace(category_)<<"predicted pos "<<predTsos.globalPosition()
00199                          <<"mom "<<predTsos.globalMomentum();
00200     } else {
00201       LogTrace(category_)<<"predicted state invalid";
00202     }
00203     if ( !predTsos.isValid() ) {
00204       LogTrace(category_)<< "Error: predTsos is still invalid forward fit.";
00205 //      return vector<Trajectory>();
00206       continue;
00207     } else if ( (**ihit).isValid() ) {
00208       // update
00209       TransientTrackingRecHit::RecHitPointer preciseHit = (**ihit).clone(predTsos);
00210 
00211       if ( !preciseHit->isValid() ) {
00212         currTsos = predTsos;
00213         myTraj.push(TrajectoryMeasurement(predTsos, *ihit));
00214       } else {
00215         currTsos = theUpdator->update(predTsos, *preciseHit);
00216         if (!currTsos.isValid()){
00217           edm::LogWarning(category_)
00218             <<"an updated state is not valid. killing the trajectory.";
00219           return vector<Trajectory>();
00220         }
00221         myTraj.push(TrajectoryMeasurement(predTsos, currTsos, preciseHit,
00222                        theEstimator->estimate(predTsos, *preciseHit).second));
00223       }
00224     } else {
00225       currTsos = predTsos;
00226       myTraj.push(TrajectoryMeasurement(predTsos, *ihit));
00227     }
00228 
00229   }
00230 
00231   std::vector<TrajectoryMeasurement> mytms = myTraj.measurements();
00232   LogTrace(category_)<<"fit result "<<mytms.size();
00233   for (std::vector<TrajectoryMeasurement>::const_iterator itm = mytms.begin();
00234        itm != mytms.end(); ++itm ) {
00235        LogTrace(category_)<<"updated pos "<<itm->updatedState().globalPosition()
00236                        <<"mom "<<itm->updatedState().globalMomentum();
00237        }
00238 
00239 
00240   return vector<Trajectory>(1, myTraj);
00241 
00242 }
00243 
00244 
00245 //
00246 // smooth trajectory
00247 //
00248 vector<Trajectory> CosmicMuonSmoother::smooth(const vector<Trajectory>& tc) const {
00249 
00250   vector<Trajectory> result; 
00251 
00252   for ( vector<Trajectory>::const_iterator it = tc.begin(); it != tc.end(); ++it ) {
00253     vector<Trajectory> smoothed = smooth(*it);
00254     result.insert(result.end(), smoothed.begin(), smoothed.end());
00255   }
00256 
00257   return result;
00258 
00259 }
00260 
00261 
00262 //
00263 // smooth trajectory
00264 //
00265 vector<Trajectory> CosmicMuonSmoother::smooth(const Trajectory& t) const {
00266 
00267   if ( t.empty() ) {
00268     LogTrace(category_)<< "Error: smooth: empty trajectory.";
00269     return vector<Trajectory>();
00270   }
00271 
00272   Trajectory myTraj(t.seed(), oppositeToMomentum);
00273 
00274   vector<TrajectoryMeasurement> avtm = t.measurements();
00275 
00276   if ( avtm.size() < 2 ) {
00277     LogTrace(category_)<< "Error: smooth: too little TM. ";
00278     return vector<Trajectory>();
00279   }
00280 
00281   TrajectoryStateOnSurface predTsos = avtm.back().forwardPredictedState();
00282   predTsos.rescaleError(theErrorRescaling);
00283 
00284   if ( !predTsos.isValid() ) {
00285     LogTrace(category_)<< "Error: smooth: first TSOS from back invalid. ";
00286     return vector<Trajectory>();
00287   }
00288 
00289   TrajectoryStateOnSurface currTsos;
00290 
00291   // first smoothed TrajectoryMeasurement is last fitted
00292   if ( avtm.back().recHit()->isValid() ) {
00293     currTsos = theUpdator->update(predTsos, (*avtm.back().recHit()));
00294     if (!currTsos.isValid()){
00295       edm::LogWarning(category_)
00296         <<"an updated state is not valid. killing the trajectory.";
00297       return vector<Trajectory>();
00298     }
00299     myTraj.push(TrajectoryMeasurement(avtm.back().forwardPredictedState(),
00300                    predTsos,
00301                    avtm.back().updatedState(),
00302                    avtm.back().recHit(),
00303                    avtm.back().estimate()//,
00304                    /*avtm.back().layer()*/), 
00305                 avtm.back().estimate());
00306 
00307   } else {
00308     currTsos = predTsos;
00309     myTraj.push(TrajectoryMeasurement(avtm.back().forwardPredictedState(),
00310                    avtm.back().recHit()//,
00311                    /*avtm.back().layer()*/));
00312 
00313   }
00314 
00315   TrajectoryStateCombiner combiner;
00316 
00317 
00318   for ( vector<TrajectoryMeasurement>::reverse_iterator itm = avtm.rbegin() + 1; 
00319         itm != avtm.rend() - 1; ++itm ) {
00320 
00321    if (currTsos.isValid())  {
00322      LogTrace(category_)<<"current pos "<<currTsos.globalPosition()
00323                        <<"mom "<<currTsos.globalMomentum();
00324     } else {
00325       LogTrace(category_)<<"current state invalid";
00326     }
00327 
00328     predTsos = propagatorOpposite()->propagate(currTsos,(*itm).recHit()->det()->surface());
00329 
00330     if ( !predTsos.isValid() ) {
00331       LogTrace(category_)<<"step-propagating from "<<currTsos.globalPosition() <<" to position: "<<(*itm).recHit()->globalPosition();
00332       predTsos = theUtilities->stepPropagate(currTsos, (*itm).recHit(), *propagatorOpposite());
00333     }
00334    if (predTsos.isValid())  {
00335       LogTrace(category_)<<"predicted pos "<<predTsos.globalPosition()
00336                        <<"mom "<<predTsos.globalMomentum();
00337     } else {
00338       LogTrace(category_)<<"predicted state invalid";
00339     }
00340 
00341     if ( !predTsos.isValid() ) {
00342       LogTrace(category_)<< "Error: predTsos is still invalid backward smooth.";
00343       return vector<Trajectory>();
00344     //  continue;
00345     } else if ( (*itm).recHit()->isValid() ) {
00346       //update
00347       currTsos = theUpdator->update(predTsos, (*(*itm).recHit()));
00348       if (!currTsos.isValid()){
00349         edm::LogWarning(category_)
00350           <<"an updated state is not valid. killing the trajectory.";
00351         return vector<Trajectory>();
00352       }
00353       TrajectoryStateOnSurface combTsos = combiner(predTsos, (*itm).forwardPredictedState());
00354       if ( !combTsos.isValid() ) {
00355          LogTrace(category_)<< "Error: smooth: combining pred TSOS failed. ";
00356          return vector<Trajectory>();
00357       }
00358 
00359       TrajectoryStateOnSurface smooTsos = combiner((*itm).updatedState(), predTsos);
00360 
00361       if ( !smooTsos.isValid() ) {
00362          LogTrace(category_)<< "Error: smooth: combining smooth TSOS failed. ";
00363          return vector<Trajectory>();
00364       }
00365 
00366       myTraj.push(TrajectoryMeasurement((*itm).forwardPredictedState(),
00367                      predTsos,
00368                      smooTsos,
00369                      (*itm).recHit(),
00370                      theEstimator->estimate(combTsos, (*(*itm).recHit())).second//,
00371                      /*(*itm).layer()*/),
00372                      (*itm).estimate());
00373     } else {
00374       currTsos = predTsos;
00375       TrajectoryStateOnSurface combTsos = combiner(predTsos, (*itm).forwardPredictedState());
00376       
00377       if ( !combTsos.isValid() ) {
00378          LogTrace(category_)<< "Error: smooth: combining TSOS failed. ";
00379          return vector<Trajectory>();
00380       }
00381 
00382       myTraj.push(TrajectoryMeasurement((*itm).forwardPredictedState(),
00383                      predTsos,
00384                      combTsos,
00385                      (*itm).recHit()//,
00386                      /*(*itm).layer()*/));
00387     }
00388   }
00389 
00390   // last smoothed TrajectoryMeasurement is last filtered
00391   predTsos = propagatorOpposite()->propagate(currTsos, avtm.front().recHit()->det()->surface());
00392   
00393   if ( !predTsos.isValid() ){
00394     LogTrace(category_)<< "Error: last predict TSOS failed, use original one. ";
00395  //    return vector<Trajectory>();
00396       myTraj.push(TrajectoryMeasurement(avtm.front().forwardPredictedState(),
00397                    avtm.front().recHit()));
00398   } else  {
00399     if ( avtm.front().recHit()->isValid() ) {
00400       //update
00401       currTsos = theUpdator->update(predTsos, (*avtm.front().recHit()));
00402       if (currTsos.isValid())
00403       myTraj.push(TrajectoryMeasurement(avtm.front().forwardPredictedState(),
00404                    predTsos,
00405                    currTsos,
00406                    avtm.front().recHit(),
00407                    theEstimator->estimate(predTsos, (*avtm.front().recHit())).second//,
00408                    /*avtm.front().layer()*/),
00409                 avtm.front().estimate());
00410     }
00411   }
00412   LogTrace(category_)<< "myTraj foundHits. "<<myTraj.foundHits();
00413 
00414   if (myTraj.foundHits() >= 3)
00415     return vector<Trajectory>(1, myTraj);
00416   else {
00417      LogTrace(category_)<< "Error: smooth: No enough hits in trajctory. ";
00418      return vector<Trajectory>();
00419   } 
00420 
00421 }
00422 
00423 TrajectoryStateOnSurface CosmicMuonSmoother::initialState(const Trajectory& t) const {
00424   if ( t.empty() ) return TrajectoryStateOnSurface();
00425 
00426   if ( !t.firstMeasurement().updatedState().isValid() || !t.lastMeasurement().updatedState().isValid() )  return TrajectoryStateOnSurface();
00427 
00428   TrajectoryStateOnSurface result;
00429 
00430   bool beamhaloFlag = ( t.firstMeasurement().updatedState().globalMomentum().eta() > 4.0 || t.lastMeasurement().updatedState().globalMomentum().eta() > 4.0 ); 
00431 
00432   if ( !beamhaloFlag ) { //initialState is the top one
00433      if (t.firstMeasurement().updatedState().globalPosition().y() > t.lastMeasurement().updatedState().globalPosition().y()) {
00434      result = t.firstMeasurement().updatedState();
00435      } else {
00436        result = t.lastMeasurement().updatedState();
00437      } 
00438      if (result.globalMomentum().y()> 1.0 ) //top tsos should pointing down
00439        theUtilities->reverseDirection(result,&*theService->magneticField());
00440   } else {
00441      if ( t.firstMeasurement().updatedState().globalPosition().z() * t.lastMeasurement().updatedState().globalPosition().z() >0 ) { //same side
00442        if ( fabs(t.firstMeasurement().updatedState().globalPosition().z()) > fabs(t.lastMeasurement().updatedState().globalPosition().z()) ) {
00443          result = t.firstMeasurement().updatedState();
00444        } else {
00445          result = t.lastMeasurement().updatedState();
00446        }
00447      } else { //different sides
00448 
00449        if ( fabs(t.firstMeasurement().updatedState().globalPosition().eta()) > fabs(t.lastMeasurement().updatedState().globalPosition().eta()) ) {
00450          result = t.firstMeasurement().updatedState();
00451        } else {
00452          result = t.lastMeasurement().updatedState();
00453        }
00454      }
00455 
00456   }
00457 
00458   return result;
00459 
00460 }
00461 
00462 void CosmicMuonSmoother::sortHitsAlongMom(ConstRecHitContainer& hits, const TrajectoryStateOnSurface& tsos) const {
00463 
00464     if (hits.size() < 2) return;
00465     float dis1 = (hits.front()->globalPosition() - tsos.globalPosition()).mag();
00466     float dis2 = (hits.back()->globalPosition() - tsos.globalPosition()).mag();
00467 
00468     if ( dis1 > dis2 )
00469       std::reverse(hits.begin(),hits.end());
00470 
00471     return;
00472 }
00473