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