CMS 3D CMS Logo

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