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
00046 MuonTrackLoader::MuonTrackLoader(ParameterSet ¶meterSet, const MuonServiceProxy *service):
00047 theService(service){
00048
00049
00050
00051 theSmoothingStep = parameterSet.getParameter<bool>("DoSmoothing");
00052 if(theSmoothingStep)
00053 theSmootherName = parameterSet.getParameter<string>("Smoother");
00054
00055
00056 theUpdatingAtVtx = parameterSet.getParameter<bool>("VertexConstraint");
00057
00058
00059 theBeamSpotInputTag = parameterSet.getParameter<edm::InputTag>("beamSpot");
00060
00061
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
00095 auto_ptr<reco::TrackCollection> trackCollection(new reco::TrackCollection());
00096
00097 reco::TrackRefProd trackCollectionRefProd = event.getRefBeforePut<reco::TrackCollection>(instance);
00098
00099
00100 auto_ptr<reco::TrackCollection> updatedAtVtxTrackCollection(new reco::TrackCollection());
00101
00102 reco::TrackRefProd trackUpdatedCollectionRefProd;
00103 if(theUpdatingAtVtx) trackUpdatedCollectionRefProd = event.getRefBeforePut<reco::TrackCollection>(instance+"UpdatedAtVtx");
00104
00105
00106 auto_ptr<reco:: TrackToTrackMap> trackToTrackmap(new reco::TrackToTrackMap);
00107
00108
00109 auto_ptr<reco::TrackExtraCollection> trackExtraCollection(new reco::TrackExtraCollection() );
00110
00111 reco::TrackExtraRefProd trackExtraCollectionRefProd = event.getRefBeforePut<reco::TrackExtraCollection>(instance);
00112
00113
00114 auto_ptr<TrackingRecHitCollection> recHitCollection(new TrackingRecHitCollection() );
00115
00116 TrackingRecHitRefProd recHitCollectionRefProd = event.getRefBeforePut<TrackingRecHitCollection>(instance);
00117
00118
00119 auto_ptr<vector<Trajectory> > trajectoryCollection(new vector<Trajectory>);
00120
00121
00122 std::auto_ptr<TrajTrackAssociationCollection> trajTrackMap( new TrajTrackAssociationCollection() );
00123
00124
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
00181 Trajectory::RecHitContainer transHits = trajectory.recHits();
00182
00183 if ( trajectory.direction() == oppositeToMomentum)
00184 reverse(transHits.begin(),transHits.end());
00185
00186
00187
00188 pair<bool,reco::Track> resultOfTrackExtrapAtPCA = buildTrackAtPCA(trajectory, *beamSpot);
00189
00190
00191 if(!resultOfTrackExtrapAtPCA.first) {
00192 delete *rawTrajectory;
00193 continue;
00194 }
00195
00196
00197 reco::Track &track = resultOfTrackExtrapAtPCA.second;
00198
00199
00200 reco::TrackExtra trackExtra = buildTrackExtra( trajectory );
00201
00202
00203 reco::TrackExtraRef trackExtraRef(trackExtraCollectionRefProd, trackExtraIndex++ );
00204
00205
00206 track.setExtra(trackExtraRef);
00207
00208
00209 pair<bool,reco::Track> updateResult(false,reco::Track());
00210
00211 if(theUpdatingAtVtx){
00212
00213 updateResult = buildTrackUpdatedAtPCA(track, *beamSpot);
00214
00215 if(!updateResult.first) ++trackIndex;
00216 else{
00217
00218
00219 updateResult.second.setExtra(trackExtraRef);
00220
00221
00222 trackToTrackmap->insert(reco::TrackRef(trackCollectionRefProd,trackIndex++),
00223 reco::TrackRef(trackUpdatedCollectionRefProd,trackUpdatedIndex++));
00224 }
00225 }
00226
00227
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 );
00234 recHitCollection->push_back( singleHit );
00235
00236 trackExtra.add(TrackingRecHitRef(recHitCollectionRefProd, recHitsIndex++ ));
00237 }
00238
00239
00240 trackExtraCollection->push_back(trackExtra);
00241
00242
00243 trackCollection->push_back(track);
00244 iTkRef++;
00245 LogTrace(metname) << "Debug Track being loaded pt "<< track.pt();
00246
00247 if(theUpdatingAtVtx && updateResult.first)
00248 updatedAtVtxTrackCollection->push_back(updateResult.second);
00249
00250
00251
00252
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
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
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
00299 auto_ptr<reco::MuonTrackLinksCollection> trackLinksCollection(new reco::MuonTrackLinksCollection());
00300
00301
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
00312 if(thePutTkTrackFlag){
00313
00314 TrajectoryContainer trackerTrajs;
00315 loadTracks(trackerTrajs, event, theL2SeededTkLabel, theSmoothTkTrackFlag);
00316 }
00317
00318 return event.put(trackLinksCollection);
00319 }
00320
00321
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
00336
00337
00338
00339
00340
00341 }
00342
00343
00344
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
00365
00366
00367 for (CandidateContainer::const_iterator it = muonCands.begin(); it != muonCands.end(); ++it, ++candposition) {
00368
00369
00370
00371
00372
00373
00374 if(combTksVec[candposition]) {
00375 reco::TrackRef combinedTR(combinedTracks, position++);
00376
00377
00378
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 {
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
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
00419 auto_ptr<reco::TrackCollection> trackCollection(new reco::TrackCollection());
00420
00421 reco::TrackRefProd trackCollectionRefProd = event.getRefBeforePut<reco::TrackCollection>(instance);
00422
00423
00424 auto_ptr<reco:: TrackToTrackMap> trackToTrackmap(new reco::TrackToTrackMap);
00425
00426
00427 auto_ptr<reco::TrackExtraCollection> trackExtraCollection(new reco::TrackExtraCollection() );
00428
00429 reco::TrackExtraRefProd trackExtraCollectionRefProd = event.getRefBeforePut<reco::TrackExtraCollection>(instance);
00430
00431
00432 auto_ptr<TrackingRecHitCollection> recHitCollection(new TrackingRecHitCollection() );
00433
00434 TrackingRecHitRefProd recHitCollectionRefProd = event.getRefBeforePut<TrackingRecHitCollection>(instance);
00435
00436
00437 auto_ptr<vector<Trajectory> > trajectoryCollection(new vector<Trajectory>);
00438
00439
00440 std::auto_ptr<TrajTrackAssociationCollection> trajTrackMap( new TrajTrackAssociationCollection() );
00441
00442
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
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
00501 Trajectory::RecHitContainer transHits = trajectory.recHits();
00502
00503 if ( trajectory.direction() == oppositeToMomentum)
00504 reverse(transHits.begin(),transHits.end());
00505
00506
00507
00508 pair<bool,reco::Track> resultOfTrackExtrapAtPCA = buildTrackAtPCA(trajectory, *beamSpot);
00509
00510
00511 if(!resultOfTrackExtrapAtPCA.first) {
00512
00513 delete *rawTrajectory;
00514 continue;
00515 }
00516
00517
00518 reco::Track &track = resultOfTrackExtrapAtPCA.second;
00519
00520
00521 reco::TrackExtra trackExtra = buildTrackExtra( trajectory );
00522
00523
00524 reco::TrackExtraRef trackExtraRef(trackExtraCollectionRefProd, trackExtraIndex++ );
00525
00526
00527 track.setExtra(trackExtraRef);
00528
00529
00530 trackToTrackmap->insert(glbRef,
00531 reco::TrackRef(trackCollectionRefProd,trackIndex++));
00532
00533
00534 pair<bool,reco::Track> updateResult(false,reco::Track());
00535
00536
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 );
00543 recHitCollection->push_back( singleHit );
00544
00545 trackExtra.add(TrackingRecHitRef(recHitCollectionRefProd, recHitsIndex++ ));
00546 }
00547
00548
00549 trackExtraCollection->push_back(trackExtra);
00550
00551
00552 trackCollection->push_back(track);
00553 iTkRef++;
00554 LogTrace(metname) << "Debug Track being loaded pt "<< track.pt();
00555
00556
00557
00558
00559 delete *rawTrajectory;
00560
00561 if(theTrajectoryFlag) tjTkMap[iTjRef-1] = iTkRef-1;
00562 }
00563
00564
00565
00566
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
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
00603 TrajectoryStateOnSurface innerTSOS = trajectory.geometricalInnermostState();
00604
00605
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
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
00697
00698
00699
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
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 }