CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch12/src/RecoMuon/TrackingTools/src/MuonTrackLoader.cc

Go to the documentation of this file.
00001 
00012 #include "RecoMuon/TrackingTools/interface/MuonTrackLoader.h"
00013 
00014 #include "RecoMuon/TrackingTools/interface/MuonPatternRecoDumper.h"
00015 #include "RecoMuon/TrackingTools/interface/MuonServiceProxy.h"
00016 #include "RecoMuon/TrackingTools/interface/MuonUpdatorAtVertex.h"
00017 
00018 #include "TrackingTools/PatternTools/interface/Trajectory.h"
00019 #include "TrackingTools/TrackFitters/interface/TrajectoryFitter.h"
00020 #include "TrackingTools/PatternTools/interface/TrajTrackAssociation.h"
00021 #include "TrackingTools/TransientTrack/interface/TransientTrack.h"
00022 #include "TrackingTools/GeomPropagators/interface/TrackerBounds.h"
00023 #include "TrackingTools/PatternTools/interface/TrajectorySmoother.h"
00024 #include "TrackingTools/Records/interface/TrackingComponentsRecord.h"
00025 #include "TrackingTools/DetLayers/interface/BarrelDetLayer.h"
00026 #include "TrackingTools/DetLayers/interface/ForwardDetLayer.h"
00027 
00028 #include "Geometry/CommonDetUnit/interface/GeomDet.h"
00029 
00030 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00031 #include "FWCore/Framework/interface/Event.h"
00032 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00033 
00034 #include "DataFormats/Math/interface/LorentzVector.h"
00035 #include "DataFormats/TrackReco/interface/Track.h"
00036 #include "DataFormats/TrackReco/interface/TrackExtra.h"
00037 #include "DataFormats/TrackReco/interface/TrackToTrackMap.h"
00038 
00039 #include "DataFormats/MuonReco/interface/MuonTrackLinks.h"
00040 #include "DataFormats/MuonReco/interface/MuonFwd.h"
00041 
00042 using namespace edm;
00043 using namespace std;
00044 
00045 // constructor
00046 MuonTrackLoader::MuonTrackLoader(ParameterSet &parameterSet, const MuonServiceProxy *service): 
00047   theService(service){
00048 
00049   // option to do or not the smoothing step.
00050   // the trajectories which are passed to the track loader are supposed to be non-smoothed
00051   theSmoothingStep = parameterSet.getParameter<bool>("DoSmoothing");
00052   if(theSmoothingStep)
00053     theSmootherName = parameterSet.getParameter<string>("Smoother");  
00054   
00055   // update at vertex
00056   theUpdatingAtVtx = parameterSet.getParameter<bool>("VertexConstraint");
00057 
00058   // beam spot input tag
00059   theBeamSpotInputTag = parameterSet.getParameter<edm::InputTag>("beamSpot");
00060   
00061   // Flag to put the trajectory into the event
00062   theTrajectoryFlag = parameterSet.getUntrackedParameter<bool>("PutTrajectoryIntoEvent",true);
00063 
00064   theL2SeededTkLabel = parameterSet.getUntrackedParameter<string>("MuonSeededTracksInstance",string());
00065   
00066   ParameterSet updatorPar = parameterSet.getParameter<ParameterSet>("MuonUpdatorAtVertexParameters");
00067   theUpdatorAtVtx = new MuonUpdatorAtVertex(updatorPar,service);
00068 
00069   thePutTkTrackFlag = parameterSet.getUntrackedParameter<bool>("PutTkTrackIntoEvent",false);
00070   theSmoothTkTrackFlag = parameterSet.getUntrackedParameter<bool>("SmoothTkTrack",false);
00071   theAllowNoVtxFlag = parameterSet.getUntrackedParameter<bool>("AllowNoVertex",false);
00072 }
00073 
00074 MuonTrackLoader::~MuonTrackLoader(){
00075   if(theUpdatorAtVtx) delete theUpdatorAtVtx;
00076 }
00077 
00078 OrphanHandle<reco::TrackCollection> 
00079 MuonTrackLoader::loadTracks(const TrajectoryContainer& trajectories,
00080                             Event& event, const string& instance, bool reallyDoSmoothing) {
00081   
00082   const bool doSmoothing = theSmoothingStep && reallyDoSmoothing;
00083   
00084   const string metname = "Muon|RecoMuon|MuonTrackLoader";
00085   
00086   // the track collectios; they will be loaded in the event  
00087   auto_ptr<reco::TrackCollection> trackCollection(new reco::TrackCollection());
00088   // ... and its reference into the event
00089   reco::TrackRefProd trackCollectionRefProd = event.getRefBeforePut<reco::TrackCollection>(instance);
00090   
00091   // track collection for the tracks updated at vertex
00092   auto_ptr<reco::TrackCollection> updatedAtVtxTrackCollection(new reco::TrackCollection());
00093   // ... and its (eventually) reference into the event
00094   reco::TrackRefProd trackUpdatedCollectionRefProd;
00095   if(theUpdatingAtVtx)  trackUpdatedCollectionRefProd = event.getRefBeforePut<reco::TrackCollection>(instance+"UpdatedAtVtx");
00096   
00097   // Association map between updated and non updated at vtx tracks
00098   auto_ptr<reco:: TrackToTrackMap> trackToTrackmap(new reco::TrackToTrackMap);
00099   
00100   // the track extra collection, it will be loaded in the event  
00101   auto_ptr<reco::TrackExtraCollection> trackExtraCollection(new reco::TrackExtraCollection() );
00102   // ... and its reference into the event
00103   reco::TrackExtraRefProd trackExtraCollectionRefProd = event.getRefBeforePut<reco::TrackExtraCollection>(instance);
00104   
00105   // the rechit collection, it will be loaded in the event  
00106   auto_ptr<TrackingRecHitCollection> recHitCollection(new TrackingRecHitCollection() );
00107   // ... and its reference into the event
00108   TrackingRecHitRefProd recHitCollectionRefProd = event.getRefBeforePut<TrackingRecHitCollection>(instance);
00109   
00110   // Collection of Trajectory
00111   auto_ptr<vector<Trajectory> > trajectoryCollection(new vector<Trajectory>);
00112   
00113   // Association map between track and trajectory
00114   std::auto_ptr<TrajTrackAssociationCollection> trajTrackMap( new TrajTrackAssociationCollection() );
00115   
00116   // don't waste any time...
00117   if ( trajectories.empty() ) { 
00118     event.put(recHitCollection,instance);
00119     event.put(trackExtraCollection,instance);
00120     if(theTrajectoryFlag) {
00121       event.put(trajectoryCollection,instance);
00122       event.put( trajTrackMap, instance );
00123     }
00124     if(theUpdatingAtVtx){
00125       event.put(trackToTrackmap);
00126       event.put(updatedAtVtxTrackCollection,instance+"UpdatedAtVtx");
00127     }
00128     return event.put(trackCollection,instance);
00129   }
00130   
00131   edm::Handle<reco::BeamSpot> beamSpot;
00132   event.getByLabel(theBeamSpotInputTag, beamSpot);
00133 
00134   LogTrace(metname) << "Create the collection of Tracks";
00135   
00136   reco::TrackRef::key_type trackIndex = 0;
00137   reco::TrackRef::key_type trackUpdatedIndex = 0;
00138   
00139   reco::TrackExtraRef::key_type trackExtraIndex = 0;
00140   TrackingRecHitRef::key_type recHitsIndex = 0;
00141   
00142   edm::Ref<reco::TrackCollection>::key_type iTkRef = 0;
00143   edm::Ref< std::vector<Trajectory> >::key_type iTjRef = 0;
00144   std::map<unsigned int, unsigned int> tjTkMap;
00145   
00146   if(doSmoothing)
00147     theService->eventSetup().get<TrajectoryFitter::Record>().get(theSmootherName,theSmoother);
00148   
00149   
00150   for(TrajectoryContainer::const_iterator rawTrajectory = trajectories.begin();
00151       rawTrajectory != trajectories.end(); ++rawTrajectory){
00152     
00153     Trajectory &trajectory = **rawTrajectory;
00154     
00155     if(doSmoothing){
00156       vector<Trajectory> trajectoriesSM = theSmoother->trajectories(**rawTrajectory);
00157       
00158       if(!trajectoriesSM.empty()) {
00159         const edm::RefToBase<TrajectorySeed> tmpSeedRef = (**rawTrajectory).seedRef();
00160         trajectory = trajectoriesSM.front();
00161         trajectory.setSeedRef(tmpSeedRef);
00162         LogDebug(metname) << "theSeedRef.isNonnull " << trajectory.seedRef().isNonnull();
00163       } else
00164         LogInfo(metname)<<"The trajectory has not been smoothed!"<<endl;
00165     }
00166     
00167     if(theTrajectoryFlag) {
00168       trajectoryCollection->push_back(trajectory);
00169       iTjRef++;
00170     }    
00171     
00172     // get the transient rechit from the trajectory
00173     Trajectory::RecHitContainer transHits = trajectory.recHits();
00174     
00175     if ( trajectory.direction() == oppositeToMomentum)
00176       reverse(transHits.begin(),transHits.end());
00177     
00178     // build the "bare" track from the trajectory.
00179     // This track has the parameters defined at PCA (no update)
00180     pair<bool,reco::Track> resultOfTrackExtrapAtPCA = buildTrackAtPCA(trajectory, *beamSpot);
00181     
00182     // Check if the extrapolation went well    
00183     if(!resultOfTrackExtrapAtPCA.first) {
00184       delete *rawTrajectory;
00185       continue;
00186     }
00187     
00188     // take the "bare" track at PCA
00189     reco::Track &track = resultOfTrackExtrapAtPCA.second;
00190     
00191     // build the "bare" track extra from the trajectory
00192     reco::TrackExtra trackExtra = buildTrackExtra( trajectory );
00193     
00194     // get the TrackExtraRef (persitent reference of the track extra)
00195     reco::TrackExtraRef trackExtraRef(trackExtraCollectionRefProd, trackExtraIndex++ );
00196     
00197     // set the persistent track-extra reference to the Track
00198     track.setExtra(trackExtraRef);
00199     
00200     // build the updated-at-vertex track, starting from the previous track
00201     pair<bool,reco::Track> updateResult(false,reco::Track());
00202     
00203     if(theUpdatingAtVtx){
00204       // build the "bare" track UPDATED at vtx
00205       updateResult = buildTrackUpdatedAtPCA(track, *beamSpot);
00206 
00207       if(!updateResult.first) ++trackIndex;
00208       else{
00209         
00210         // set the persistent track-extra reference to the Track
00211         updateResult.second.setExtra(trackExtraRef);
00212         
00213         // Fill the map
00214         trackToTrackmap->insert(reco::TrackRef(trackCollectionRefProd,trackIndex++),
00215                                 reco::TrackRef(trackUpdatedCollectionRefProd,trackUpdatedIndex++));
00216       }
00217     }
00218     
00219     // Fill the track extra with the rec hit (persistent-)reference
00220     size_t i = 0;
00221     for (Trajectory::RecHitContainer::const_iterator recHit = transHits.begin();
00222          recHit != transHits.end(); ++recHit) {
00223       TrackingRecHit *singleHit = (**recHit).hit()->clone();
00224       track.setHitPattern( *singleHit, i ++ );
00225       if(theUpdatingAtVtx && updateResult.first) updateResult.second.setHitPattern( *singleHit, i-1 ); // i was already incremented
00226       recHitCollection->push_back( singleHit );  
00227       // set the TrackingRecHitRef (persitent reference of the tracking rec hits)
00228       trackExtra.add(TrackingRecHitRef(recHitCollectionRefProd, recHitsIndex++ ));
00229     }
00230     
00231     // fill the TrackExtraCollection
00232     trackExtraCollection->push_back(trackExtra);
00233     
00234     // fill the TrackCollection
00235     trackCollection->push_back(track);
00236     iTkRef++;
00237     LogTrace(metname) << "Debug Track being loaded pt "<< track.pt();
00238     // fill the TrackCollection updated at vtx
00239     if(theUpdatingAtVtx && updateResult.first) 
00240       updatedAtVtxTrackCollection->push_back(updateResult.second);
00241     
00242     // We don't need the original trajectory anymore.
00243     // It has been copied by value in the trajectoryCollection, if 
00244     // it is required to put it into the event.
00245     delete *rawTrajectory;
00246 
00247     if(theTrajectoryFlag) tjTkMap[iTjRef-1] = iTkRef-1;
00248   }
00249   
00250 
00251   
00252   // Put the Collections in the event
00253   LogTrace(metname) << "put the Collections in the event";
00254   event.put(recHitCollection,instance);
00255   event.put(trackExtraCollection,instance);
00256 
00257   OrphanHandle<reco::TrackCollection> returnTrackHandle;
00258   OrphanHandle<reco::TrackCollection> nonUpdatedHandle;
00259   if(theUpdatingAtVtx){
00260     nonUpdatedHandle = event.put(trackCollection,instance);
00261     event.put(trackToTrackmap);
00262     returnTrackHandle = event.put(updatedAtVtxTrackCollection,instance+"UpdatedAtVtx");
00263   }
00264   else {
00265     returnTrackHandle = event.put(trackCollection,instance);
00266     nonUpdatedHandle = returnTrackHandle;
00267   }
00268 
00269   if ( theTrajectoryFlag ) {
00270     OrphanHandle<std::vector<Trajectory> > rTrajs = event.put(trajectoryCollection,instance);
00271     // Now Create traj<->tracks association map
00272     for ( std::map<unsigned int, unsigned int>::iterator i = tjTkMap.begin(); 
00273           i != tjTkMap.end(); i++ ) {
00274       trajTrackMap->insert( edm::Ref<std::vector<Trajectory> >( rTrajs, (*i).first ),
00275                             edm::Ref<reco::TrackCollection>( nonUpdatedHandle, (*i).second ) );
00276     }
00277     event.put( trajTrackMap, instance );
00278   }
00279   
00280   return returnTrackHandle;
00281 }
00282 
00283 OrphanHandle<reco::MuonTrackLinksCollection> 
00284 MuonTrackLoader::loadTracks(const CandidateContainer& muonCands,
00285                             Event& event) {
00286 
00287   const string metname = "Muon|RecoMuon|MuonTrackLoader";
00288   
00289   // the muon collection, it will be loaded in the event
00290   auto_ptr<reco::MuonTrackLinksCollection> trackLinksCollection(new reco::MuonTrackLinksCollection());
00291   
00292   // don't waste any time...
00293   if ( muonCands.empty() ) {
00294     auto_ptr<reco::TrackExtraCollection> trackExtraCollection(new reco::TrackExtraCollection() );
00295     auto_ptr<TrackingRecHitCollection> recHitCollection(new TrackingRecHitCollection() );
00296     auto_ptr<reco::TrackCollection> trackCollection( new reco::TrackCollection() );
00297 
00298     event.put(recHitCollection);
00299     event.put(trackExtraCollection);
00300     event.put(trackCollection);
00301 
00302     //need to also put the tracker tracks collection if requested
00303     if(thePutTkTrackFlag){
00304       //will take care of putting nothing in the event but the empty collection
00305       TrajectoryContainer trackerTrajs;
00306       loadTracks(trackerTrajs, event, theL2SeededTkLabel, theSmoothTkTrackFlag);
00307     } 
00308 
00309     return event.put(trackLinksCollection);
00310   }
00311   
00312   // get combined Trajectories
00313   TrajectoryContainer combinedTrajs;
00314   TrajectoryContainer trackerTrajs;
00315   for (CandidateContainer::const_iterator it = muonCands.begin(); it != muonCands.end(); it++) {
00316     LogDebug(metname) << "Loader glbSeedRef " << (*it)->trajectory()->seedRef().isNonnull();
00317     if ((*it)->trackerTrajectory() )  LogDebug(metname) << " " << "tkSeedRef " << (*it)->trackerTrajectory()->seedRef().isNonnull();
00318 
00319     combinedTrajs.push_back((*it)->trajectory());
00320     if ( thePutTkTrackFlag ) trackerTrajs.push_back((*it)->trackerTrajectory());
00321 
00322     else {
00323       if ((*it)->trackerTrajectory()) delete ((*it)->trackerTrajectory());
00324     }
00325   
00326     // Create the links between sta and tracker tracks
00327     reco::MuonTrackLinks links;
00328     links.setStandAloneTrack((*it)->muonTrack());
00329     links.setTrackerTrack((*it)->trackerTrack());
00330     trackLinksCollection->push_back(links);
00331     delete *it;
00332   }
00333   
00334   // create the TrackCollection of combined Trajectories
00335   // FIXME: could this be done one track at a time in the previous loop?
00336   LogTrace(metname) << "Build combinedTracks";
00337   OrphanHandle<reco::TrackCollection> combinedTracks = loadTracks(combinedTrajs, event);
00338 
00339   OrphanHandle<reco::TrackCollection> trackerTracks;
00340   if(thePutTkTrackFlag) {
00341     LogTrace(metname) << "Build trackerTracks: "
00342                       << trackerTrajs.size();
00343     trackerTracks = loadTracks(trackerTrajs, event, theL2SeededTkLabel, theSmoothTkTrackFlag);
00344   } else {
00345     for (TrajectoryContainer::iterator it = trackerTrajs.begin(); it != trackerTrajs.end(); ++it) {
00346         if(*it) delete *it;
00347     }
00348   }
00349 
00350   LogTrace(metname) << "Set the final links in the MuonTrackLinks collection";
00351 
00352   reco::MuonTrackLinksCollection::iterator links = trackLinksCollection->begin();
00353   for ( unsigned int position = 0; position != combinedTracks->size(); ++position, ++links) {
00354     reco::TrackRef combinedTR(combinedTracks, position);
00355 
00356     reco::TrackRef trackerTR;
00357     if(thePutTkTrackFlag) trackerTR = reco::TrackRef(trackerTracks, position);
00358 
00359     // fill the combined information.
00360     links->setGlobalTrack(combinedTR);
00361     if(thePutTkTrackFlag) links->setTrackerTrack(trackerTR);
00362   }
00363 
00364   if( thePutTkTrackFlag && trackerTracks.isValid() && !(combinedTracks->size() > 0 && trackerTracks->size() > 0 ) )
00365     LogWarning(metname)<<"The MuonTrackLinkCollection is incomplete"; 
00366   
00367   // put the MuonCollection in the event
00368   LogTrace(metname) << "put the MuonCollection in the event" << "\n";
00369   
00370   return event.put(trackLinksCollection);
00371 } 
00372 
00373 OrphanHandle<reco::TrackCollection> 
00374 MuonTrackLoader::loadTracks(const TrajectoryContainer& trajectories,
00375                             Event& event, std::vector<std::pair<Trajectory*,reco::TrackRef> > miniMap, const string& instance, bool reallyDoSmoothing) {
00376   
00377   const bool doSmoothing = theSmoothingStep && reallyDoSmoothing;
00378   
00379   const string metname = "Muon|RecoMuon|MuonTrackLoader|TevMuonTrackLoader";
00380 
00381   LogDebug(metname)<<"TeV LoadTracks instance: " << instance;
00382   
00383   // the track collectios; they will be loaded in the event  
00384   auto_ptr<reco::TrackCollection> trackCollection(new reco::TrackCollection());
00385   // ... and its reference into the event
00386   reco::TrackRefProd trackCollectionRefProd = event.getRefBeforePut<reco::TrackCollection>(instance);
00387     
00388   // Association map between GlobalMuons and TeVMuons
00389   auto_ptr<reco:: TrackToTrackMap> trackToTrackmap(new reco::TrackToTrackMap);
00390   
00391   // the track extra collection, it will be loaded in the event  
00392   auto_ptr<reco::TrackExtraCollection> trackExtraCollection(new reco::TrackExtraCollection() );
00393   // ... and its reference into the event
00394   reco::TrackExtraRefProd trackExtraCollectionRefProd = event.getRefBeforePut<reco::TrackExtraCollection>(instance);
00395   
00396   // the rechit collection, it will be loaded in the event  
00397   auto_ptr<TrackingRecHitCollection> recHitCollection(new TrackingRecHitCollection() );
00398   // ... and its reference into the event
00399   TrackingRecHitRefProd recHitCollectionRefProd = event.getRefBeforePut<TrackingRecHitCollection>(instance);
00400   
00401   // Collection of Trajectory
00402   auto_ptr<vector<Trajectory> > trajectoryCollection(new vector<Trajectory>);
00403   
00404   // Association map between track and trajectory
00405   std::auto_ptr<TrajTrackAssociationCollection> trajTrackMap( new TrajTrackAssociationCollection() );
00406   
00407   // don't waste any time...
00408   if ( trajectories.empty() ) { 
00409     event.put(recHitCollection,instance);
00410     event.put(trackExtraCollection,instance);
00411     if(theTrajectoryFlag) {
00412       event.put(trajectoryCollection,instance);
00413       event.put( trajTrackMap, instance );
00414     }
00415     event.put(trackToTrackmap, instance);
00416     return event.put(trackCollection,instance);
00417   }
00418   
00419   LogTrace(metname) << "Create the collection of Tracks";
00420   
00421   edm::Handle<reco::BeamSpot> beamSpot;
00422   event.getByLabel(theBeamSpotInputTag,beamSpot);
00423 
00424   reco::TrackRef::key_type trackIndex = 0;
00425   //  reco::TrackRef::key_type trackUpdatedIndex = 0;
00426   
00427   reco::TrackExtraRef::key_type trackExtraIndex = 0;
00428   TrackingRecHitRef::key_type recHitsIndex = 0;
00429   
00430   edm::Ref<reco::TrackCollection>::key_type iTkRef = 0;
00431   edm::Ref< std::vector<Trajectory> >::key_type iTjRef = 0;
00432   std::map<unsigned int, unsigned int> tjTkMap;
00433   
00434   if(doSmoothing)
00435     theService->eventSetup().get<TrajectoryFitter::Record>().get(theSmootherName,theSmoother);
00436   
00437   
00438   for(TrajectoryContainer::const_iterator rawTrajectory = trajectories.begin();
00439       rawTrajectory != trajectories.end(); ++rawTrajectory){
00440 
00441     reco::TrackRef glbRef;
00442     std::vector<std::pair<Trajectory*,reco::TrackRef> >::const_iterator mmit;
00443     for(mmit = miniMap.begin();mmit!=miniMap.end();++mmit){
00444       if(mmit->first == *rawTrajectory) glbRef = mmit->second;
00445     }
00446     
00447     Trajectory &trajectory = **rawTrajectory;
00448     
00449     if(doSmoothing){
00450       vector<Trajectory> trajectoriesSM = theSmoother->trajectories(**rawTrajectory);
00451       
00452       if(!trajectoriesSM.empty()) {
00453         const edm::RefToBase<TrajectorySeed> tmpSeedRef = (**rawTrajectory).seedRef();
00454         trajectory = trajectoriesSM.front();
00455         trajectory.setSeedRef(tmpSeedRef);
00456       } else
00457         LogInfo(metname)<<"The trajectory has not been smoothed!"<<endl;
00458     }
00459     
00460     if(theTrajectoryFlag) {
00461       trajectoryCollection->push_back(trajectory);
00462       iTjRef++;
00463     }    
00464     
00465     // get the transient rechit from the trajectory
00466     Trajectory::RecHitContainer transHits = trajectory.recHits();
00467     
00468     if ( trajectory.direction() == oppositeToMomentum)
00469       reverse(transHits.begin(),transHits.end());
00470     
00471     // build the "bare" track from the trajectory.
00472     // This track has the parameters defined at PCA (no update)
00473     pair<bool,reco::Track> resultOfTrackExtrapAtPCA = buildTrackAtPCA(trajectory, *beamSpot);
00474     
00475     // Check if the extrapolation went well    
00476     if(!resultOfTrackExtrapAtPCA.first) {
00477       //      ++trackIndex;//ADAM
00478       delete *rawTrajectory;
00479       continue;
00480     }
00481     
00482     // take the "bare" track at PCA
00483     reco::Track &track = resultOfTrackExtrapAtPCA.second;
00484     
00485     // build the "bare" track extra from the trajectory
00486     reco::TrackExtra trackExtra = buildTrackExtra( trajectory );
00487     
00488     // get the TrackExtraRef (persitent reference of the track extra)
00489     reco::TrackExtraRef trackExtraRef(trackExtraCollectionRefProd, trackExtraIndex++ );
00490     
00491     // set the persistent track-extra reference to the Track
00492     track.setExtra(trackExtraRef);
00493 
00494     // Fill the map
00495     trackToTrackmap->insert(glbRef,
00496                             reco::TrackRef(trackCollectionRefProd,trackIndex++));
00497 
00498     // build the updated-at-vertex track, starting from the previous track
00499     pair<bool,reco::Track> updateResult(false,reco::Track());
00500             
00501     // Fill the track extra with the rec hit (persistent-)reference
00502     size_t i = 0;
00503     for (Trajectory::RecHitContainer::const_iterator recHit = transHits.begin();
00504          recHit != transHits.end(); ++recHit) {
00505         TrackingRecHit *singleHit = (**recHit).hit()->clone();
00506         track.setHitPattern( *singleHit, i ++ );
00507         if(theUpdatingAtVtx && updateResult.first) updateResult.second.setHitPattern( *singleHit, i-1 ); // i was already incremented
00508         recHitCollection->push_back( singleHit );  
00509         // set the TrackingRecHitRef (persitent reference of the tracking rec hits)
00510         trackExtra.add(TrackingRecHitRef(recHitCollectionRefProd, recHitsIndex++ ));
00511     }
00512     
00513     // fill the TrackExtraCollection
00514     trackExtraCollection->push_back(trackExtra);
00515     
00516     // fill the TrackCollection
00517     trackCollection->push_back(track);
00518     iTkRef++;
00519     LogTrace(metname) << "Debug Track being loaded pt "<< track.pt();
00520     
00521     // We don't need the original trajectory anymore.
00522     // It has been copied by value in the trajectoryCollection, if 
00523     // it is required to put it into the event.
00524     delete *rawTrajectory;
00525 
00526     if(theTrajectoryFlag) tjTkMap[iTjRef-1] = iTkRef-1;
00527   }
00528   
00529 
00530   
00531   // Put the Collections in the event
00532   LogTrace(metname) << "put the Collections in the event";
00533   event.put(recHitCollection,instance);
00534   event.put(trackExtraCollection,instance);
00535 
00536   OrphanHandle<reco::TrackCollection> returnTrackHandle;
00537   OrphanHandle<reco::TrackCollection> nonUpdatedHandle;
00538   if(theUpdatingAtVtx){
00539   }
00540   else {
00541     event.put(trackToTrackmap,instance);
00542     returnTrackHandle = event.put(trackCollection,instance);
00543     nonUpdatedHandle = returnTrackHandle;
00544   }
00545 
00546   if ( theTrajectoryFlag ) {
00547     OrphanHandle<std::vector<Trajectory> > rTrajs = event.put(trajectoryCollection,instance);
00548     // Now Create traj<->tracks association map
00549     for ( std::map<unsigned int, unsigned int>::iterator i = tjTkMap.begin(); 
00550           i != tjTkMap.end(); i++ ) {
00551       trajTrackMap->insert( edm::Ref<std::vector<Trajectory> >( rTrajs, (*i).first ),
00552                             edm::Ref<reco::TrackCollection>( nonUpdatedHandle, (*i).second ) );
00553     }
00554     event.put( trajTrackMap, instance );
00555   }
00556 
00557   return returnTrackHandle;
00558 }
00559 
00560 
00561 pair<bool,reco::Track> MuonTrackLoader::buildTrackAtPCA(const Trajectory& trajectory, const reco::BeamSpot &beamSpot) const {
00562 
00563   const string metname = "Muon|RecoMuon|MuonTrackLoader";
00564 
00565   MuonPatternRecoDumper debug;
00566   
00567   // FIXME: check the prop direction
00568   TrajectoryStateOnSurface innerTSOS = trajectory.geometricalInnermostState();
00569   
00570   // This is needed to extrapolate the tsos at vertex
00571   LogTrace(metname) << "Propagate to PCA...";
00572   pair<bool,FreeTrajectoryState> 
00573     extrapolationResult = theUpdatorAtVtx->propagate(innerTSOS, beamSpot);  
00574   FreeTrajectoryState ftsAtVtx;
00575   
00576   if(extrapolationResult.first)
00577     ftsAtVtx = extrapolationResult.second;
00578   else{    
00579     if(TrackerBounds::isInside(innerTSOS.globalPosition())){
00580       LogInfo(metname) << "Track in the Tracker: taking the innermost state instead of the state at PCA";
00581       ftsAtVtx = *innerTSOS.freeState();
00582     }
00583     else{
00584       if ( theAllowNoVtxFlag ) {
00585         LogInfo(metname) << "Propagation to PCA failed, taking the innermost state instead of the state at PCA";
00586         ftsAtVtx = *innerTSOS.freeState();
00587       } else {
00588         LogInfo(metname) << "Stand Alone track: this track will be rejected";
00589         return pair<bool,reco::Track>(false,reco::Track());
00590       }
00591     }
00592   }
00593     
00594   LogTrace(metname) << "TSOS after the extrapolation at vtx";
00595   LogTrace(metname) << debug.dumpFTS(ftsAtVtx);
00596   
00597   GlobalPoint pca = ftsAtVtx.position();
00598   math::XYZPoint persistentPCA(pca.x(),pca.y(),pca.z());
00599   GlobalVector p = ftsAtVtx.momentum();
00600   math::XYZVector persistentMomentum(p.x(),p.y(),p.z());
00601 
00602   bool bon = true;
00603   if(fabs(theService->magneticField()->inTesla(GlobalPoint(0,0,0)).z()) < 0.01) bon=false;   
00604   double ndof = trajectory.ndof(bon);
00605   
00606   reco::Track track(trajectory.chiSquared(), 
00607                     ndof,
00608                     persistentPCA,
00609                     persistentMomentum,
00610                     ftsAtVtx.charge(),
00611                     ftsAtVtx.curvilinearError());
00612   
00613   return pair<bool,reco::Track>(true,track);
00614 }
00615 
00616 
00617 pair<bool,reco::Track> MuonTrackLoader::buildTrackUpdatedAtPCA(const reco::Track &track, const reco::BeamSpot &beamSpot) const {
00618 
00619   const string metname = "Muon|RecoMuon|MuonTrackLoader";
00620   MuonPatternRecoDumper debug;
00621  
00622   // build the transient track
00623   reco::TransientTrack transientTrack(track,
00624                                       &*theService->magneticField(),
00625                                       theService->trackingGeometry());
00626 
00627   LogTrace(metname) << "Apply the vertex constraint";
00628   pair<bool,FreeTrajectoryState> updateResult = theUpdatorAtVtx->update(transientTrack,beamSpot);
00629 
00630   if(!updateResult.first){
00631     return pair<bool,reco::Track>(false,reco::Track());
00632   }
00633 
00634   LogTrace(metname) << "FTS after the vertex constraint";
00635   FreeTrajectoryState &ftsAtVtx = updateResult.second;
00636 
00637   LogTrace(metname) << debug.dumpFTS(ftsAtVtx);
00638   
00639   GlobalPoint pca = ftsAtVtx.position();
00640   math::XYZPoint persistentPCA(pca.x(),pca.y(),pca.z());
00641   GlobalVector p = ftsAtVtx.momentum();
00642   math::XYZVector persistentMomentum(p.x(),p.y(),p.z());
00643   
00644   reco::Track updatedTrack(track.chi2(), 
00645                            track.ndof(),
00646                            persistentPCA,
00647                            persistentMomentum,
00648                            ftsAtVtx.charge(),
00649                            ftsAtVtx.curvilinearError());
00650   
00651   return pair<bool,reco::Track>(true,updatedTrack);
00652 }
00653 
00654 
00655 reco::TrackExtra MuonTrackLoader::buildTrackExtra(const Trajectory& trajectory) const {
00656 
00657   const string metname = "Muon|RecoMuon|MuonTrackLoader";
00658 
00659   const Trajectory::RecHitContainer transRecHits = trajectory.recHits();
00660   
00661   // put the collection of TrackingRecHit in the event
00662   
00663   // sets the outermost and innermost TSOSs
00664   // FIXME: check it!
00665   TrajectoryStateOnSurface outerTSOS;
00666   TrajectoryStateOnSurface innerTSOS;
00667   unsigned int innerId=0, outerId=0;
00668   TrajectoryMeasurement::ConstRecHitPointer outerRecHit;
00669   DetId outerDetId;
00670 
00671   if (trajectory.direction() == alongMomentum) {
00672     LogTrace(metname)<<"alongMomentum";
00673     outerTSOS = trajectory.lastMeasurement().updatedState();
00674     innerTSOS = trajectory.firstMeasurement().updatedState();
00675     outerId = trajectory.lastMeasurement().recHit()->geographicalId().rawId();
00676     innerId = trajectory.firstMeasurement().recHit()->geographicalId().rawId();
00677     outerRecHit =  trajectory.lastMeasurement().recHit();
00678     outerDetId =   trajectory.lastMeasurement().recHit()->geographicalId();
00679   } 
00680   else if (trajectory.direction() == oppositeToMomentum) {
00681     LogTrace(metname)<<"oppositeToMomentum";
00682     outerTSOS = trajectory.firstMeasurement().updatedState();
00683     innerTSOS = trajectory.lastMeasurement().updatedState();
00684     outerId = trajectory.firstMeasurement().recHit()->geographicalId().rawId();
00685     innerId = trajectory.lastMeasurement().recHit()->geographicalId().rawId();
00686     outerRecHit =  trajectory.firstMeasurement().recHit();
00687     outerDetId =   trajectory.firstMeasurement().recHit()->geographicalId();
00688   }
00689   else LogError(metname)<<"Wrong propagation direction!";
00690   
00691   const GeomDet *outerDet = theService->trackingGeometry()->idToDet(outerDetId);
00692   GlobalPoint outerTSOSPos = outerTSOS.globalParameters().position();
00693   bool inside = outerDet->surface().bounds().inside(outerDet->toLocal(outerTSOSPos));
00694 
00695   
00696   GlobalPoint hitPos = (outerRecHit->isValid()) ? outerRecHit->globalPosition() :  outerTSOS.globalParameters().position() ;
00697   
00698   if(!inside) {
00699     LogTrace(metname)<<"The Global Muon outerMostMeasurementState is not compatible with the recHit detector! Setting outerMost postition to recHit position if recHit isValid: " << outerRecHit->isValid();
00700     LogTrace(metname)<<"From " << outerTSOSPos << " to " <<  hitPos;
00701   }
00702   
00703   
00704   //build the TrackExtra
00705   GlobalPoint v = (inside) ? outerTSOSPos : hitPos ;
00706   GlobalVector p = outerTSOS.globalParameters().momentum();
00707   math::XYZPoint  outpos( v.x(), v.y(), v.z() );   
00708   math::XYZVector outmom( p.x(), p.y(), p.z() );
00709   
00710   v = innerTSOS.globalParameters().position();
00711   p = innerTSOS.globalParameters().momentum();
00712   math::XYZPoint  inpos( v.x(), v.y(), v.z() );   
00713   math::XYZVector inmom( p.x(), p.y(), p.z() );
00714 
00715   reco::TrackExtra trackExtra(outpos, outmom, true, inpos, inmom, true,
00716                               outerTSOS.curvilinearError(), outerId,
00717                               innerTSOS.curvilinearError(), innerId,
00718                               trajectory.direction(),trajectory.seedRef());
00719   
00720   return trackExtra;
00721  
00722 }