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