CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/RecoTracker/NuclearSeedGenerator/plugins/NuclearTrackCorrector.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:    NuclearTrackCorrector
00004 // Class:      NuclearTrackCorrector
00005 // 
00013 //
00014 // Original Author:  Loic QUERTENMONT, Vincent ROBERFROID
00015 //         Created:  Tue Sep 18 14:22:48 CEST 2007
00016 // $Id: NuclearTrackCorrector.cc,v 1.12 2010/03/10 16:43:16 vlimant Exp $
00017 //
00018 //
00019 
00020 #include "RecoTracker/NuclearSeedGenerator/interface/NuclearTrackCorrector.h"
00021 #include "FWCore/Framework/interface/EventSetup.h"
00022 #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
00023 #include "RecoTracker/CkfPattern/interface/TransientInitialStateEstimator.h"
00024 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h"
00025 #include "TrackingTools/Records/interface/TrackingComponentsRecord.h" 
00026 
00027 #include "DataFormats/BeamSpot/interface/BeamSpot.h"
00028 
00029 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00030 
00031 using namespace edm;
00032 using namespace std;
00033 using namespace reco;
00034 
00035 
00036 NuclearTrackCorrector::NuclearTrackCorrector(const edm::ParameterSet& iConfig) :
00037 conf_(iConfig),
00038 theInitialState(0)
00039 {
00040      str_Input_Trajectory           = iConfig.getParameter<std::string>     ("InputTrajectory");
00041      str_Input_NuclearInteraction   = iConfig.getParameter<std::string>     ("InputNuclearInteraction");
00042      verbosity                      = iConfig.getParameter<int>             ("Verbosity");
00043      KeepOnlyCorrectedTracks        = iConfig.getParameter<bool>             ("KeepOnlyCorrectedTracks");
00044 
00045 
00046      theAlgo = new TrackProducerAlgorithm<reco::Track>(iConfig);
00047 
00048      produces< TrajectoryCollection >();
00049      produces< TrajectoryToTrajectoryMap >();
00050 
00051      produces< reco::TrackExtraCollection >();
00052      produces< reco::TrackCollection >();       
00053      produces< TrackToTrajectoryMap >();
00054 
00055      produces< TrackToTrackMap >();
00056 }
00057 
00058 
00059 NuclearTrackCorrector::~NuclearTrackCorrector()
00060 {
00061 }
00062 
00063 void
00064 NuclearTrackCorrector::produce(edm::Event& iEvent, const edm::EventSetup& iSetup)
00065 {
00066   // Create Output Collections
00067   // --------------------------------------------------------------------------------------------------
00068   std::auto_ptr<TrajectoryCollection>           Output_traj          ( new TrajectoryCollection );
00069   std::auto_ptr<TrajectoryToTrajectoryMap>      Output_trajmap       ( new TrajectoryToTrajectoryMap );
00070 
00071   std::auto_ptr<reco::TrackExtraCollection>     Output_trackextra    ( new reco::TrackExtraCollection );
00072   std::auto_ptr<reco::TrackCollection>          Output_track         ( new reco::TrackCollection );
00073   std::auto_ptr<TrackToTrajectoryMap>           Output_trackmap      ( new TrackToTrajectoryMap );
00074 
00075   std::auto_ptr<TrackToTrackMap>                Output_tracktrackmap ( new TrackToTrackMap );
00076 
00077 
00078 
00079 
00080 
00081   // Load Reccord
00082   // --------------------------------------------------------------------------------------------------
00083   std::string fitterName = conf_.getParameter<std::string>("Fitter");   
00084   iSetup.get<TrajectoryFitter::Record>().get(fitterName,theFitter);
00085 
00086   std::string propagatorName = conf_.getParameter<std::string>("Propagator");   
00087   iSetup.get<TrackingComponentsRecord>().get(propagatorName,thePropagator);
00088 
00089   iSetup.get<TrackerDigiGeometryRecord>().get(theG);
00090 
00091   reco::TrackExtraRefProd rTrackExtras = iEvent.getRefBeforePut<reco::TrackExtraCollection>();
00092 
00093    iSetup.get<IdealMagneticFieldRecord>().get(theMF); 
00094 
00095   // Load Inputs
00096   // --------------------------------------------------------------------------------------------------
00097   edm::Handle< TrajectoryCollection > temp_m_TrajectoryCollection;
00098   iEvent.getByLabel( str_Input_Trajectory.c_str(), temp_m_TrajectoryCollection );
00099   const TrajectoryCollection m_TrajectoryCollection = *(temp_m_TrajectoryCollection.product());
00100 
00101   edm::Handle< NuclearInteractionCollection > temp_m_NuclearInteractionCollection;
00102   iEvent.getByLabel( str_Input_NuclearInteraction.c_str(), temp_m_NuclearInteractionCollection );
00103   const NuclearInteractionCollection m_NuclearInteractionCollection = *(temp_m_NuclearInteractionCollection.product());
00104 
00105   edm::Handle< TrajTrackAssociationCollection > h_TrajToTrackCollection;
00106   iEvent.getByLabel( str_Input_Trajectory.c_str(), h_TrajToTrackCollection );
00107   m_TrajToTrackCollection = h_TrajToTrackCollection.product();
00108 
00109 
00110   // Correct the trajectories (Remove trajectory's hits that are located after the nuclear interacion)
00111   // --------------------------------------------------------------------------------------------------
00112   if(verbosity>=1){
00113     LogDebug("NuclearTrackCorrector")
00114       <<"Number of trajectories                    = "<<m_TrajectoryCollection.size() <<std::endl
00115       <<"Number of nuclear interactions            = "<<m_NuclearInteractionCollection.size();
00116   }
00117 
00118   std::map<reco::TrackRef,TrajectoryRef> m_TrackToTrajMap; 
00119   swap_map(temp_m_TrajectoryCollection, m_TrackToTrajMap);
00120 
00121   for(unsigned int i = 0 ; i < m_NuclearInteractionCollection.size() ; i++)
00122   {
00123         reco::NuclearInteraction ni =  m_NuclearInteractionCollection[i];
00124         if( ni.likelihood()<0.4) continue;
00125 
00126         reco::TrackRef primTrackRef = ni.primaryTrack().castTo<reco::TrackRef>();
00127 
00128         TrajectoryRef  trajRef = m_TrackToTrajMap[primTrackRef];
00129 
00130         Trajectory newTraj;
00131         if( newTrajNeeded(newTraj, trajRef, ni) ) {
00132 
00133           AlgoProductCollection   algoResults; 
00134           bool isOK = getTrackFromTrajectory( newTraj , trajRef, algoResults);
00135 
00136           if( isOK ) {
00137 
00138                 pair<unsigned int, unsigned int> tempory_pair;
00139                 tempory_pair.first  = Output_track->size();
00140                 tempory_pair.second = i;
00141                 Indice_Map.push_back(tempory_pair);
00142 
00143                 reco::TrackExtraRef teref= reco::TrackExtraRef ( rTrackExtras, i );
00144                 reco::TrackExtra newTrackExtra = getNewTrackExtra(algoResults);
00145                 (algoResults[0].second.first)->setExtra( teref ); 
00146 
00147                 Output_track->push_back(*algoResults[0].second.first);        
00148                 Output_trackextra->push_back( newTrackExtra );
00149                 Output_traj->push_back(newTraj);
00150 
00151           }
00152         }
00153         else {
00154            if(!KeepOnlyCorrectedTracks) {
00155                 Output_track->push_back(*primTrackRef);
00156                 Output_trackextra->push_back( *primTrackRef->extra() );
00157                 Output_traj->push_back(*trajRef);
00158            }
00159         }
00160 
00161   }
00162   const edm::OrphanHandle<TrajectoryCollection>     Handle_traj = iEvent.put(Output_traj);
00163   const edm::OrphanHandle<reco::TrackCollection> Handle_tracks = iEvent.put(Output_track);
00164   iEvent.put(Output_trackextra);
00165 
00166   // Make Maps between elements
00167   // --------------------------------------------------------------------------------------------------
00168   if(Handle_tracks->size() != Handle_traj->size() )
00169   {
00170      printf("ERROR Handle_tracks->size() != Handle_traj->size() \n");
00171      return;
00172   }
00173 
00174 
00175 
00176   for(unsigned int i = 0 ; i < Indice_Map.size() ; i++)
00177   {
00178         TrajectoryRef      InTrajRef    ( temp_m_TrajectoryCollection, Indice_Map[i].second );
00179         TrajectoryRef      OutTrajRef   ( Handle_traj, Indice_Map[i].first );
00180         reco::TrackRef     TrackRef     ( Handle_tracks, Indice_Map[i].first );
00181 
00182         Output_trajmap ->insert(OutTrajRef,InTrajRef);
00183         Output_trackmap->insert(TrackRef,InTrajRef);
00184 
00185         try{
00186                 reco::TrackRef  PrimaryTrackRef     = m_TrajToTrackCollection->operator[]( InTrajRef );
00187                 Output_tracktrackmap->insert(TrackRef,PrimaryTrackRef);
00188         }catch(edm::Exception event){}
00189         
00190   }
00191   iEvent.put(Output_trajmap);
00192   iEvent.put(Output_trackmap);
00193   iEvent.put(Output_tracktrackmap);
00194 
00195 
00196   if(verbosity>=3)printf("-----------------------\n");
00197 }
00198 
00199 // ------------ method called once each job just before starting event loop  ------------
00200 void 
00201 NuclearTrackCorrector::beginRun(edm::Run & run, const edm::EventSetup& iSetup)
00202 {
00203 }
00204 
00205 // ------------ method called once each job just after ending the event loop  ------------
00206 void 
00207 NuclearTrackCorrector::endJob() {
00208 }
00209 //----------------------------------------------------------------------------------------
00210 bool NuclearTrackCorrector::newTrajNeeded(Trajectory& newtrajectory, const TrajectoryRef& trajRef, const NuclearInteraction& ni) {
00211 
00212         bool needNewTraj=false;
00213         reco::Vertex::Point vtx_pos = ni.vertex().position();
00214         double vtx_pos_mag = sqrt (vtx_pos.X()*vtx_pos.X()+vtx_pos.Y()*vtx_pos.Y()+vtx_pos.Z()*vtx_pos.Z());
00215         if(verbosity>=2) printf("Nuclear Interaction pos = %f\n",vtx_pos_mag );
00216 
00217 
00218         newtrajectory = Trajectory(trajRef->seed(), alongMomentum);
00219 
00220         // Look all the Hits of the trajectory and keep only Hits before seeds
00221         Trajectory::DataContainer Measurements = trajRef->measurements();
00222         if(verbosity>=2)LogDebug("NuclearTrackCorrector")<<"Size of Measurements  = "<<Measurements.size();
00223 
00224         for(unsigned int m=Measurements.size()-1 ;m!=(unsigned int)-1 ; m--){
00225 
00226                 if(!Measurements[m].recHit()->isValid() )continue;
00227                 GlobalPoint hit_pos = theG->idToDet(Measurements[m].recHit()->geographicalId())->surface().toGlobal(Measurements[m].recHit()->localPosition());
00228 
00229                 if(verbosity>=2)printf("Hit pos = %f",hit_pos.mag() );
00230 
00231                 if(hit_pos.mag()>vtx_pos_mag){
00232                          if(verbosity>=2)printf(" X ");
00233                          needNewTraj=true;
00234                 }else{
00235                         newtrajectory.push(Measurements[m]);
00236                 }
00237                 if(verbosity>=2)printf("\n");
00238         }
00239 
00240         return needNewTraj;
00241 }
00242 
00243 //----------------------------------------------------------------------------------------
00244 bool NuclearTrackCorrector::getTrackFromTrajectory(const Trajectory& newTraj , const TrajectoryRef& initialTrajRef, AlgoProductCollection& algoResults) {
00245 
00246         const Trajectory*  it = &newTraj;
00247 
00248         TransientTrackingRecHit::RecHitContainer hits;
00249         it->validRecHits( hits  );
00250         
00251 
00252         float ndof=0;
00253         for(unsigned int h=0 ; h<hits.size() ; h++)
00254         {
00255             if( hits[h]->isValid() )
00256             {
00257                 ndof = ndof + hits[h]->dimension() * hits[h]->weight();
00258             }
00259             else {
00260                  LogDebug("NuclearSeedGenerator") << " HIT IS INVALID ???";
00261             }
00262         }
00263 
00264 
00265         ndof = ndof - 5;
00266         reco::TrackRef  theT     = m_TrajToTrackCollection->operator[]( initialTrajRef );
00267         LogDebug("NuclearSeedGenerator") << " TrackCorrector - number of valid hits" << hits.size() << "\n"
00268                                          << "                - number of hits from Track " << theT->recHitsSize() << "\n"
00269                                          << "                - number of valid hits from initial track " << theT->numberOfValidHits();
00270 
00271 
00272         if(  hits.size() > 1){
00273 
00274                 TrajectoryStateOnSurface theInitialStateForRefitting = getInitialState(&(*theT),hits,theG.product(),theMF.product()
00275 );
00276 
00277            reco::BeamSpot bs;
00278            return theAlgo->buildTrack(theFitter.product(), thePropagator.product(), algoResults, hits, theInitialStateForRefitting ,it->seed(), ndof, bs, theT->seedRef());
00279          }
00280 
00281         return false;
00282 }
00283 //----------------------------------------------------------------------------------------
00284 reco::TrackExtra NuclearTrackCorrector::getNewTrackExtra(const AlgoProductCollection& algoResults) {
00285                 Trajectory* theTraj          = algoResults[0].first;
00286                 PropagationDirection seedDir = algoResults[0].second.second;
00287 
00288                 TrajectoryStateOnSurface outertsos;
00289                 TrajectoryStateOnSurface innertsos;
00290                 unsigned int innerId, outerId;
00291                 if (theTraj->direction() == alongMomentum) {
00292                   outertsos = theTraj->lastMeasurement().updatedState();
00293                   innertsos = theTraj->firstMeasurement().updatedState();
00294                   outerId   = theTraj->lastMeasurement().recHit()->geographicalId().rawId();
00295                   innerId   = theTraj->firstMeasurement().recHit()->geographicalId().rawId();
00296                 } else {
00297                   outertsos = theTraj->firstMeasurement().updatedState();
00298                   innertsos = theTraj->lastMeasurement().updatedState();
00299                   outerId   = theTraj->firstMeasurement().recHit()->geographicalId().rawId();
00300                   innerId   = theTraj->lastMeasurement().recHit()->geographicalId().rawId();
00301                 }
00302 
00303                 GlobalPoint v = outertsos.globalParameters().position();
00304                 GlobalVector p = outertsos.globalParameters().momentum();
00305                 math::XYZVector outmom( p.x(), p.y(), p.z() );
00306                 math::XYZPoint  outpos( v.x(), v.y(), v.z() );
00307                 v = innertsos.globalParameters().position();
00308                 p = innertsos.globalParameters().momentum();
00309                 math::XYZVector inmom( p.x(), p.y(), p.z() );
00310                 math::XYZPoint  inpos( v.x(), v.y(), v.z() );
00311 
00312                 return reco::TrackExtra (outpos, outmom, true, inpos, inmom, true,
00313                                         outertsos.curvilinearError(), outerId,
00314                                         innertsos.curvilinearError(), innerId, seedDir);
00315 
00316 }
00317 //----------------------------------------------------------------------------------------
00318 TrajectoryStateOnSurface NuclearTrackCorrector::getInitialState(const reco::Track * theT,
00319                                                                  TransientTrackingRecHit::RecHitContainer& hits,
00320                                                                  const TrackingGeometry * theG,
00321                                                                  const MagneticField * theMF){
00322 
00323   TrajectoryStateOnSurface theInitialStateForRefitting;
00324   //the starting state is the state closest to the first hit along seedDirection.
00325   TrajectoryStateTransform transformer;
00326   //avoiding to use transientTrack, it should be faster;
00327   TrajectoryStateOnSurface innerStateFromTrack=transformer.innerStateOnSurface(*theT,*theG,theMF);
00328   TrajectoryStateOnSurface outerStateFromTrack=transformer.outerStateOnSurface(*theT,*theG,theMF);
00329   TrajectoryStateOnSurface initialStateFromTrack = 
00330     ( (innerStateFromTrack.globalPosition()-hits.front()->globalPosition()).mag2() <
00331       (outerStateFromTrack.globalPosition()-hits.front()->globalPosition()).mag2() ) ? 
00332     innerStateFromTrack: outerStateFromTrack;       
00333   
00334   // error is rescaled, but correlation are kept.
00335   initialStateFromTrack.rescaleError(100);
00336   theInitialStateForRefitting = TrajectoryStateOnSurface(initialStateFromTrack.localParameters(),
00337                                                          initialStateFromTrack.localError(),                  
00338                                                          initialStateFromTrack.surface(),
00339                                                          theMF); 
00340   return theInitialStateForRefitting;
00341 }
00342 //----------------------------------------------------------------------------------------
00343 void  NuclearTrackCorrector::swap_map(const  edm::Handle< TrajectoryCollection >& trajColl , std::map< reco::TrackRef, edm::Ref<TrajectoryCollection> >& result) {
00344   for(unsigned int i = 0 ; i < trajColl->size() ; i++)
00345   {
00346      TrajectoryRef      InTrajRef    ( trajColl, i);
00347      reco::TrackRef  PrimaryTrackRef     = m_TrajToTrackCollection->operator[]( InTrajRef );
00348      result[ PrimaryTrackRef ] = InTrajRef;
00349   }
00350 }