CMS 3D CMS Logo

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