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 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
00227 trackExtra.add(TrackingRecHitRef(recHitCollectionRefProd, recHitsIndex++ ));
00228 }
00229
00230
00231 trackExtraCollection->push_back(trackExtra);
00232
00233
00234 trackCollection->push_back(track);
00235 iTkRef++;
00236 LogTrace(metname) << "Debug Track being loaded pt "<< track.pt();
00237
00238 if(theUpdatingAtVtx && updateResult.first)
00239 updatedAtVtxTrackCollection->push_back(updateResult.second);
00240
00241
00242
00243
00244 delete *rawTrajectory;
00245
00246 if(theTrajectoryFlag) tjTkMap[iTjRef-1] = iTkRef-1;
00247 }
00248
00249
00250
00251
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
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
00289 auto_ptr<reco::MuonTrackLinksCollection> trackLinksCollection(new reco::MuonTrackLinksCollection());
00290
00291
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
00302 if(thePutTkTrackFlag){
00303
00304 TrajectoryContainer trackerTrajs;
00305 loadTracks(trackerTrajs, event, theL2SeededTkLabel, theSmoothTkTrackFlag);
00306 }
00307
00308 return event.put(trackLinksCollection);
00309 }
00310
00311
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
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
00334
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
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
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
00383 auto_ptr<reco::TrackCollection> trackCollection(new reco::TrackCollection());
00384
00385 reco::TrackRefProd trackCollectionRefProd = event.getRefBeforePut<reco::TrackCollection>(instance);
00386
00387
00388 auto_ptr<reco:: TrackToTrackMap> trackToTrackmap(new reco::TrackToTrackMap);
00389
00390
00391 auto_ptr<reco::TrackExtraCollection> trackExtraCollection(new reco::TrackExtraCollection() );
00392
00393 reco::TrackExtraRefProd trackExtraCollectionRefProd = event.getRefBeforePut<reco::TrackExtraCollection>(instance);
00394
00395
00396 auto_ptr<TrackingRecHitCollection> recHitCollection(new TrackingRecHitCollection() );
00397
00398 TrackingRecHitRefProd recHitCollectionRefProd = event.getRefBeforePut<TrackingRecHitCollection>(instance);
00399
00400
00401 auto_ptr<vector<Trajectory> > trajectoryCollection(new vector<Trajectory>);
00402
00403
00404 std::auto_ptr<TrajTrackAssociationCollection> trajTrackMap( new TrajTrackAssociationCollection() );
00405
00406
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
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
00465 Trajectory::RecHitContainer transHits = trajectory.recHits();
00466
00467 if ( trajectory.direction() == oppositeToMomentum)
00468 reverse(transHits.begin(),transHits.end());
00469
00470
00471
00472 pair<bool,reco::Track> resultOfTrackExtrapAtPCA = buildTrackAtPCA(trajectory, *beamSpot);
00473
00474
00475 if(!resultOfTrackExtrapAtPCA.first) {
00476
00477 delete *rawTrajectory;
00478 continue;
00479 }
00480
00481
00482 reco::Track &track = resultOfTrackExtrapAtPCA.second;
00483
00484
00485 reco::TrackExtra trackExtra = buildTrackExtra( trajectory );
00486
00487
00488 reco::TrackExtraRef trackExtraRef(trackExtraCollectionRefProd, trackExtraIndex++ );
00489
00490
00491 track.setExtra(trackExtraRef);
00492
00493
00494 trackToTrackmap->insert(glbRef,
00495 reco::TrackRef(trackCollectionRefProd,trackIndex++));
00496
00497
00498 pair<bool,reco::Track> updateResult(false,reco::Track());
00499
00500
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);
00506 recHitCollection->push_back( singleHit );
00507
00508 trackExtra.add(TrackingRecHitRef(recHitCollectionRefProd, recHitsIndex++ ));
00509 }
00510
00511
00512 trackExtraCollection->push_back(trackExtra);
00513
00514
00515 trackCollection->push_back(track);
00516 iTkRef++;
00517 LogTrace(metname) << "Debug Track being loaded pt "<< track.pt();
00518
00519
00520
00521
00522 delete *rawTrajectory;
00523
00524 if(theTrajectoryFlag) tjTkMap[iTjRef-1] = iTkRef-1;
00525 }
00526
00527
00528
00529
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
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
00566 TrajectoryStateOnSurface innerTSOS = trajectory.geometricalInnermostState();
00567
00568
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
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
00660
00661
00662
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
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 }