CMS 3D CMS Logo

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