00001 #include "RecoMuon/CosmicMuonProducer/interface/CosmicMuonTrajectoryBuilder.h"
00013 #include "FWCore/Framework/interface/Frameworkfwd.h"
00014 #include "FWCore/Framework/interface/MakerMacros.h"
00015
00016
00017 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h"
00018 #include "Geometry/CommonDetUnit/interface/GeomDet.h"
00019 #include "TrackingTools/PatternTools/interface/Trajectory.h"
00020 #include "TrackingTools/GeomPropagators/interface/Propagator.h"
00021 #include "DataFormats/TrajectorySeed/interface/TrajectorySeed.h"
00022 #include "FWCore/Framework/interface/Event.h"
00023 #include "FWCore/Framework/interface/EventSetup.h"
00024 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00025 #include "FWCore/Utilities/interface/InputTag.h"
00026 #include "TrackingTools/DetLayers/interface/DetLayer.h"
00027 #include "RecoMuon/Navigation/interface/DirectMuonNavigation.h"
00028 #include "RecoMuon/MeasurementDet/interface/MuonDetLayerMeasurements.h"
00029 #include "RecoMuon/TrackingTools/interface/MuonBestMeasurementFinder.h"
00030 #include "RecoMuon/TrackingTools/interface/MuonTrajectoryUpdator.h"
00031 #include "RecoMuon/TrackingTools/interface/MuonServiceProxy.h"
00032 #include "RecoMuon/TrackingTools/interface/MuonPatternRecoDumper.h"
00033 #include "RecoMuon/TransientTrackingRecHit/interface/MuonTransientTrackingRecHit.h"
00034 #include "DataFormats/MuonDetId/interface/MuonSubdetId.h"
00035 #include "DataFormats/GeometrySurface/interface/PlaneBuilder.h"
00036 #include "DataFormats/GeometryCommonDetAlgo/interface/PerpendicularBoundPlaneBuilder.h"
00037 #include "RecoMuon/Records/interface/MuonRecoGeometryRecord.h"
00038 #include "DataFormats/CSCRecHit/interface/CSCRecHit2D.h"
00039 #include "DataFormats/DTRecHit/interface/DTRecHit1D.h"
00040
00041 #include <algorithm>
00042
00043 using namespace edm;
00044 using namespace std;
00045
00046 CosmicMuonTrajectoryBuilder::CosmicMuonTrajectoryBuilder(const edm::ParameterSet& par, const MuonServiceProxy* service) : theService(service) {
00047
00048 thePropagatorName = par.getParameter<string>("Propagator");
00049
00050 bool enableDTMeasurement = par.getParameter<bool>("EnableDTMeasurement");
00051 bool enableCSCMeasurement = par.getParameter<bool>("EnableCSCMeasurement");
00052 bool enableRPCMeasurement = par.getParameter<bool>("EnableRPCMeasurement");
00053
00054
00055 InputTag DTRecSegmentLabel = par.getParameter<InputTag>("DTRecSegmentLabel");
00056
00057
00058 InputTag CSCRecSegmentLabel = par.getParameter<InputTag>("CSCRecSegmentLabel");
00059
00060
00061 InputTag RPCRecSegmentLabel = par.getParameter<InputTag>("RPCRecSegmentLabel");
00062
00063 theLayerMeasurements= new MuonDetLayerMeasurements(DTRecSegmentLabel,
00064 CSCRecSegmentLabel,
00065 RPCRecSegmentLabel,
00066 enableDTMeasurement,
00067 enableCSCMeasurement,
00068 enableRPCMeasurement);
00069
00070 ParameterSet muonUpdatorPSet = par.getParameter<ParameterSet>("MuonTrajectoryUpdatorParameters");
00071
00072 theNavigation = 0;
00073 theUpdator = new MuonTrajectoryUpdator(muonUpdatorPSet, insideOut);
00074
00075 theBestMeasurementFinder = new MuonBestMeasurementFinder();
00076
00077 ParameterSet muonBackwardUpdatorPSet = par.getParameter<ParameterSet>("BackwardMuonTrajectoryUpdatorParameters");
00078
00079 theBKUpdator = new MuonTrajectoryUpdator(muonBackwardUpdatorPSet, outsideIn);
00080
00081 theTraversingMuonFlag = par.getParameter<bool>("BuildTraversingMuon");
00082
00083 theStrict1LegFlag = par.getParameter<bool>("Strict1Leg");
00084
00085 ParameterSet smootherPSet = par.getParameter<ParameterSet>("MuonSmootherParameters");
00086
00087 theNavigationPSet = par.getParameter<ParameterSet>("MuonNavigationParameters");
00088
00089 theSmoother = new CosmicMuonSmoother(smootherPSet,theService);
00090
00091 theNTraversing = 0;
00092 theNSuccess = 0;
00093 theCacheId_DG = 0;
00094 category_ = "Muon|RecoMuon|CosmicMuon|CosmicMuonTrajectoryBuilder";
00095
00096 }
00097
00098
00099 CosmicMuonTrajectoryBuilder::~CosmicMuonTrajectoryBuilder() {
00100
00101 LogTrace(category_)<< "CosmicMuonTrajectoryBuilder dtor called";
00102 if (theUpdator) delete theUpdator;
00103 if (theBKUpdator) delete theBKUpdator;
00104 if (theLayerMeasurements) delete theLayerMeasurements;
00105 if (theSmoother) delete theSmoother;
00106 if (theNavigation) delete theNavigation;
00107 delete theBestMeasurementFinder;
00108
00109 LogTrace(category_)<< "CosmicMuonTrajectoryBuilder Traversing: "<<theNSuccess<<"/"<<theNTraversing;
00110
00111 }
00112
00113
00114 void CosmicMuonTrajectoryBuilder::setEvent(const edm::Event& event) {
00115
00116 theLayerMeasurements->setEvent(event);
00117
00118
00119 unsigned long long newCacheId_DG = theService->eventSetup().get<MuonRecoGeometryRecord>().cacheIdentifier();
00120 if ( newCacheId_DG != theCacheId_DG ) {
00121 LogTrace(category_) << "Muon Reco Geometry changed!";
00122 theCacheId_DG = newCacheId_DG;
00123 if (theNavigation) delete theNavigation;
00124 theNavigation = new DirectMuonNavigation(theService->detLayerGeometry(), theNavigationPSet);
00125 }
00126
00127
00128
00129
00130 }
00131
00132
00133 MuonTrajectoryBuilder::TrajectoryContainer
00134 CosmicMuonTrajectoryBuilder::trajectories(const TrajectorySeed& seed) {
00135
00136 vector<Trajectory*> trajL = vector<Trajectory*>();
00137
00138 MuonPatternRecoDumper debug;
00139
00140 PTrajectoryStateOnDet ptsd1(seed.startingState());
00141 DetId did(ptsd1.detId());
00142 const BoundPlane& bp = theService->trackingGeometry()->idToDet(did)->surface();
00143 TrajectoryStateOnSurface lastTsos = trajectoryStateTransform::transientState(ptsd1,&bp,&*theService->magneticField());
00144 LogTrace(category_) << "Seed: mom "<<lastTsos.globalMomentum()
00145 <<"pos: " <<lastTsos.globalPosition();
00146 LogTrace(category_) << "Seed: mom eta "<<lastTsos.globalMomentum().eta()
00147 <<"pos eta: " <<lastTsos.globalPosition().eta();
00148
00149 bool beamhaloFlag = ( (did.subdetId() == MuonSubdetId::CSC) && fabs(lastTsos.globalMomentum().eta()) > 4.0);
00150
00151 vector<const DetLayer*> navLayers;
00152
00153 if (did.subdetId() == MuonSubdetId::DT) {
00154
00155 navLayers = navigation()->compatibleLayers(*(lastTsos.freeState()), alongMomentum);
00156 }
00157 else if (beamhaloFlag || (theTraversingMuonFlag && theStrict1LegFlag)) {
00158
00159 navLayers = navigation()->compatibleEndcapLayers(*(lastTsos.freeState()), alongMomentum);
00160 } else {
00161 navLayers = navigation()->compatibleLayers(*(lastTsos.freeState()), alongMomentum);
00162 }
00163
00164 LogTrace(category_) <<"found "<<navLayers.size()<<" compatible DetLayers for the Seed";
00165
00166 if (navLayers.empty()) return trajL;
00167
00168 vector<DetWithState> detsWithStates;
00169 LogTrace(category_) << "Compatible layers: ";
00170 for ( vector<const DetLayer*>::const_iterator layer = navLayers.begin();
00171 layer != navLayers.end(); layer++) {
00172 LogTrace(category_) << debug.dumpMuonId((*layer)->basicComponents().front()->geographicalId())
00173 << debug.dumpLayer(*layer);
00174 }
00175
00176 detsWithStates = navLayers.front()->compatibleDets(lastTsos, *propagator(), *(updator()->estimator()));
00177 LogTrace(category_) << "Number of compatible dets: " << detsWithStates.size() << endl;
00178
00179 if ( !detsWithStates.empty() ) {
00180
00181 if ( detsWithStates.front().second.isValid() ) {
00182 LogTrace(category_) << "New starting TSOS is on det: " << endl;
00183 LogTrace(category_) << debug.dumpMuonId(detsWithStates.front().first->geographicalId())
00184 << debug.dumpLayer(navLayers.front());
00185 lastTsos = detsWithStates.front().second;
00186 LogTrace(category_) << "Seed after extrapolation: mom " << lastTsos.globalMomentum()
00187 << "pos: " << lastTsos.globalPosition();
00188 }
00189 }
00190 detsWithStates.clear();
00191 if ( !lastTsos.isValid() ) return trajL;
00192
00193 TrajectoryStateOnSurface secondLast = lastTsos;
00194
00195 lastTsos.rescaleError(10.0);
00196
00197 Trajectory* theTraj = new Trajectory(seed,alongMomentum);
00198
00199 navLayers.clear();
00200
00201 if (fabs(lastTsos.globalMomentum().eta()) < 1.0) {
00202
00203 navLayers = navigation()->compatibleLayers(*(lastTsos.freeState()), alongMomentum);
00204 } else if (beamhaloFlag || (theTraversingMuonFlag && theStrict1LegFlag)) {
00205
00206 navLayers = navigation()->compatibleEndcapLayers(*(lastTsos.freeState()), alongMomentum);
00207 } else {
00208 navLayers = navigation()->compatibleLayers(*(lastTsos.freeState()), alongMomentum);
00209 }
00210
00211
00212 int DTChamberUsedBack = 0;
00213 int CSCChamberUsedBack = 0;
00214 int RPCChamberUsedBack = 0;
00215 int TotalChamberUsedBack = 0;
00216 MuonTransientTrackingRecHit::MuonRecHitContainer allUnusedHits;
00217 vector<TrajectoryMeasurement> measL;
00218
00219 LogTrace(category_) << "Begin forward fit " << navLayers.size();
00220
00221 for ( vector<const DetLayer*>::const_iterator rnxtlayer = navLayers.begin(); rnxtlayer!= navLayers.end(); ++rnxtlayer) {
00222 LogTrace(category_) << "new layer ";
00223 measL.clear();
00224 LogTrace(category_) << debug.dumpMuonId((*rnxtlayer)->basicComponents().front()->geographicalId())
00225 << debug.dumpLayer(*rnxtlayer);
00226 LogTrace(category_) << "from lastTsos " << lastTsos.globalMomentum()<< " at " <<lastTsos.globalPosition();
00227
00228 measL = findBestMeasurements(*rnxtlayer, lastTsos, propagator(), (updator()->estimator()));
00229
00230 if ( measL.empty() && (fabs(theService->magneticField()->inTesla(GlobalPoint(0,0,0)).z()) < 0.01) && (theService->propagator("StraightLinePropagator").isValid() ) ) {
00231 LogTrace(category_) << "try straight line propagator ";
00232 measL = findBestMeasurements(*rnxtlayer, lastTsos, &*theService->propagator("StraightLinePropagator"), (updator()->estimator()));
00233 }
00234 if ( measL.empty() ) continue;
00235
00236 for (vector<TrajectoryMeasurement>::const_iterator theMeas = measL.begin(); theMeas != measL.end(); ++theMeas) {
00237 pair<bool,TrajectoryStateOnSurface> result = updator()->update((&*theMeas), *theTraj, propagator());
00238
00239 if (result.first ) {
00240 LogTrace(category_) << "update ok ";
00241 incrementChamberCounters((*rnxtlayer), DTChamberUsedBack, CSCChamberUsedBack, RPCChamberUsedBack, TotalChamberUsedBack);
00242 secondLast = lastTsos;
00243 if ( (!theTraj->empty()) && result.second.isValid() ) {
00244 lastTsos = result.second;
00245 LogTrace(category_) << "get new lastTsos here " << lastTsos.globalMomentum() << " at " << lastTsos.globalPosition();
00246 } else if ((theMeas)->predictedState().isValid()) lastTsos = (theMeas)->predictedState();
00247 }
00248 }
00249 }
00250 measL.clear();
00251 while (!theTraj->empty()) {
00252 theTraj->pop();
00253 }
00254
00255 if (!theTraj->isValid() || TotalChamberUsedBack < 2 || (DTChamberUsedBack+CSCChamberUsedBack) == 0 || !lastTsos.isValid()) {
00256 delete theTraj;
00257 return trajL;
00258 }
00259 delete theTraj;
00260
00261
00262
00263 DTChamberUsedBack = 0;
00264 CSCChamberUsedBack = 0;
00265 RPCChamberUsedBack = 0;
00266 TotalChamberUsedBack = 0;
00267
00268 Trajectory myTraj(seed, oppositeToMomentum);
00269
00270
00271
00272 GlobalPoint lastPos = lastTsos.globalPosition();
00273 GlobalPoint secondLastPos = secondLast.globalPosition();
00274 GlobalVector momDir = secondLastPos - lastPos;
00275
00276 if ( lastPos.basicVector().dot(momDir.basicVector()) > 0 ) {
00277
00278 theBKUpdator->setFitDirection(insideOut);
00279 } else theBKUpdator->setFitDirection(outsideIn);
00280
00281 if (fabs(lastTsos.globalMomentum().eta()) < 1.0) {
00282
00283 navLayers = navigation()->compatibleLayers(*(lastTsos.freeState()), oppositeToMomentum);
00284 } else if (beamhaloFlag || (theTraversingMuonFlag && theStrict1LegFlag)) {
00285
00286 std::reverse(navLayers.begin(), navLayers.end());
00287 } else {
00288 navLayers = navigation()->compatibleLayers(*(lastTsos.freeState()), oppositeToMomentum);
00289 }
00290
00291 LogTrace(category_) << "Begin backward refitting, with " << navLayers.size() << " layers" << endl;
00292
00293 for (vector<const DetLayer*>::const_iterator rnxtlayer = navLayers.begin();
00294 rnxtlayer!= navLayers.end(); ++rnxtlayer) {
00295
00296 measL.clear();
00297
00298 measL = findBestMeasurements(*rnxtlayer, lastTsos, propagator(), (backwardUpdator()->estimator()));
00299
00300 if ( measL.empty() ) {
00301 MuonTransientTrackingRecHit::MuonRecHitContainer tmpHits = theLayerMeasurements->recHits(*rnxtlayer);
00302 for (MuonRecHitContainer::const_iterator ihit = tmpHits.begin();
00303 ihit != tmpHits.end(); ++ihit ) {
00304 allUnusedHits.push_back(*ihit);
00305 }
00306 continue;
00307 }
00308
00309 for (vector<TrajectoryMeasurement>::const_iterator theMeas = measL.begin(); theMeas != measL.end(); ++theMeas) {
00310
00311
00312 if (rnxtlayer != navLayers.begin()) {
00313
00314 vector<const DetLayer*>::const_iterator lastlayer = rnxtlayer;
00315 lastlayer--;
00316
00317 if ( (*rnxtlayer)->location() != (*lastlayer)->location() ) {
00318
00319 lastPos = lastTsos.globalPosition();
00320 GlobalPoint thisPos = (theMeas)->predictedState().globalPosition();
00321 GlobalVector momDir = thisPos - lastPos;
00322
00323
00324 if ( momDir.mag() > 0.01 ) {
00325 if ( thisPos.basicVector().dot(momDir.basicVector()) > 0 ) {
00326 theBKUpdator->setFitDirection(insideOut);
00327 } else theBKUpdator->setFitDirection(outsideIn);
00328 }
00329 }
00330 if ( ((*lastlayer)->location() == GeomDetEnumerators::endcap) &&
00331 ((*rnxtlayer)->location() == GeomDetEnumerators::endcap) &&
00332 (lastTsos.globalPosition().z() * (theMeas)->predictedState().globalPosition().z() < 0) ) {
00333 theBKUpdator->setFitDirection(insideOut);
00334 }
00335 }
00336
00337
00338
00339
00340 pair<bool,TrajectoryStateOnSurface> bkresult
00341 = backwardUpdator()->update((&*theMeas), myTraj, propagator());
00342
00343 if (bkresult.first ) {
00344
00345 incrementChamberCounters((*rnxtlayer), DTChamberUsedBack, CSCChamberUsedBack, RPCChamberUsedBack, TotalChamberUsedBack);
00346
00347 if ( theTraversingMuonFlag ) {
00348
00349 MuonRecHitContainer tmpUnusedHits = unusedHits(*rnxtlayer,*theMeas);
00350 allUnusedHits.insert(allUnusedHits.end(),tmpUnusedHits.begin(),tmpUnusedHits.end());
00351 }
00352 if ( (!myTraj.empty()) && bkresult.second.isValid() )
00353 lastTsos = bkresult.second;
00354 else if ((theMeas)->predictedState().isValid())
00355 lastTsos = (theMeas)->predictedState();
00356 }
00357 }
00358 }
00359
00360 for ( vector<Trajectory*>::iterator t = trajL.begin(); t != trajL.end(); ++t ) delete *t;
00361
00362 trajL.clear();
00363
00364 if (( !myTraj.isValid() ) || ( myTraj.empty() ) || ( (selfDuplicate(myTraj)) )|| TotalChamberUsedBack < 2 || (DTChamberUsedBack+CSCChamberUsedBack) < 1) {
00365 return trajL;
00366 }
00367
00368 if ( theTraversingMuonFlag && ( allUnusedHits.size() >= 2 )) {
00369
00370 LogTrace(category_)<<"Building trajectory in second hemisphere...";
00371 buildSecondHalf(myTraj);
00372
00373
00374 if ( theStrict1LegFlag && !utilities()->isTraversing(myTraj) ) {trajL.clear(); return trajL;}
00375 } else if (theStrict1LegFlag && theTraversingMuonFlag) {trajL.clear(); return trajL;}
00376
00377 LogTrace(category_) <<" traj ok ";
00378
00379
00380 if (beamhaloFlag) estimateDirection(myTraj);
00381 if ( myTraj.empty() ) return trajL;
00382
00383
00384 vector<Trajectory> smoothed = theSmoother->trajectories(myTraj);
00385
00386 if ( !smoothed.empty() && smoothed.front().foundHits()> 3 ) {
00387 LogTrace(category_) <<" Smoothed successfully.";
00388 myTraj = smoothed.front();
00389 }
00390 else {
00391 LogTrace(category_) <<" Smooth failed.";
00392 }
00393
00394 LogTrace(category_) <<"first "<< myTraj.firstMeasurement().updatedState()
00395 <<"\n last "<<myTraj.lastMeasurement().updatedState();
00396 if ( myTraj.direction() == alongMomentum ) LogTrace(category_)<<"alongMomentum";
00397 else if (myTraj.direction() == oppositeToMomentum ) LogTrace(category_)<<"oppositeMomentum";
00398 else LogTrace(category_)<<"anyDirection";
00399
00400 if (!beamhaloFlag) {
00401 if ( myTraj.lastMeasurement().updatedState().globalMomentum().y() > 0 ) {
00402 LogTrace(category_)<<"flip trajectory ";
00403 flipTrajectory(myTraj);
00404 }
00405
00406 if ( ( myTraj.direction() == alongMomentum &&
00407 (myTraj.firstMeasurement().updatedState().globalPosition().y()
00408 < myTraj.lastMeasurement().updatedState().globalPosition().y()))
00409 || (myTraj.direction() == oppositeToMomentum &&
00410 (myTraj.firstMeasurement().updatedState().globalPosition().y()
00411 > myTraj.lastMeasurement().updatedState().globalPosition().y())) ) {
00412 LogTrace(category_)<<"reverse propagation direction";
00413 reverseTrajectoryPropagationDirection(myTraj);
00414 }
00415 }
00416
00417 if ( !myTraj.isValid() ) return trajL;
00418
00419
00420 PropagationDirection dir = myTraj.direction();
00421 GlobalVector dirFromPos = myTraj.measurements().back().recHit()->globalPosition() - myTraj.measurements().front().recHit()->globalPosition();
00422
00423 if ( theStrict1LegFlag && !utilities()->isTraversing(myTraj) ) {trajL.clear(); return trajL;}
00424
00425 LogTrace(category_)<< "last hit " <<myTraj.measurements().back().recHit()->globalPosition()<<endl;
00426 LogTrace(category_)<< "first hit " <<myTraj.measurements().front().recHit()->globalPosition()<<endl;
00427
00428 LogTrace(category_)<< "last tsos " <<myTraj.measurements().back().updatedState().globalPosition()<<" mom "<<myTraj.measurements().back().updatedState().globalMomentum()<<endl;
00429 LogTrace(category_)<< "first tsos " <<myTraj.measurements().front().updatedState().globalPosition()<<" mom "<<myTraj.measurements().front().updatedState().globalMomentum()<<endl;
00430
00431 PropagationDirection propDir =
00432 ( dirFromPos.basicVector().dot(myTraj.firstMeasurement().updatedState().globalMomentum().basicVector()) > 0) ? alongMomentum : oppositeToMomentum;
00433 LogTrace(category_)<<" dir "<<dir <<" propDir "<<propDir<<endl;
00434
00435 LogTrace(category_)<<"chi2 "<<myTraj.chiSquared() <<endl;
00436
00437 if (dir != propDir ) {
00438 LogTrace(category_)<< "reverse propagation direction ";
00439 reverseTrajectoryPropagationDirection(myTraj);
00440 }
00441 if ( myTraj.empty() ) return trajL;
00442
00443 trajL.push_back(new Trajectory(myTraj));
00444 navLayers.clear();
00445 return trajL;
00446 }
00447
00448
00449
00450
00451
00452 MuonTransientTrackingRecHit::MuonRecHitContainer
00453 CosmicMuonTrajectoryBuilder::unusedHits(const DetLayer* layer, const TrajectoryMeasurement& meas) const {
00454
00455 MuonTransientTrackingRecHit::MuonRecHitContainer tmpHits = theLayerMeasurements->recHits(layer);
00456 MuonRecHitContainer result;
00457 for (MuonRecHitContainer::const_iterator ihit = tmpHits.begin();
00458 ihit != tmpHits.end(); ++ihit ) {
00459 if ((*ihit)->geographicalId() != meas.recHit()->geographicalId() ){
00460 result.push_back(*ihit);
00461 LogTrace(category_) << "Unused hit: " << (*ihit)->globalPosition() << endl;
00462 }
00463 }
00464
00465 return result;
00466
00467 }
00468
00469
00470
00471
00472
00473 void CosmicMuonTrajectoryBuilder::build(const TrajectoryStateOnSurface& ts,
00474 const NavigationDirection& startingDir,
00475 Trajectory& traj) {
00476
00477 if ( !ts.isValid() ) return;
00478
00479 FreeTrajectoryState* fts = ts.freeState();
00480 if ( !fts ) return;
00481
00482 vector<const DetLayer*> navLayers;
00483
00484 if (fabs(fts->momentum().basicVector().eta()) < 1.0) {
00485
00486 if (fts->position().basicVector().dot(fts->momentum().basicVector())>0){
00487 navLayers = navigation()->compatibleLayers((*fts), alongMomentum);
00488 } else {
00489 navLayers = navigation()->compatibleLayers((*fts), oppositeToMomentum);
00490 }
00491
00492 } else if (theTraversingMuonFlag && theStrict1LegFlag) {
00493
00494 if (fts->position().basicVector().dot(fts->momentum().basicVector())>0){
00495 navLayers = navigation()->compatibleEndcapLayers((*fts), alongMomentum);
00496 } else {
00497 navLayers = navigation()->compatibleEndcapLayers((*fts), oppositeToMomentum);
00498 }
00499 } else {
00500
00501 if (fts->position().basicVector().dot(fts->momentum().basicVector())>0){
00502 navLayers = navigation()->compatibleLayers((*fts), alongMomentum);
00503 } else {
00504 navLayers = navigation()->compatibleLayers((*fts), oppositeToMomentum);
00505 }
00506
00507 }
00508
00509 if (navLayers.empty()) return;
00510
00511 theBKUpdator->setFitDirection(startingDir);
00512
00513 int DTChamberUsedBack = 0;
00514 int CSCChamberUsedBack = 0;
00515 int RPCChamberUsedBack = 0;
00516 int TotalChamberUsedBack = 0;
00517
00518 TrajectoryStateOnSurface lastTsos =
00519 (traj.lastMeasurement().updatedState().globalPosition().y() <
00520 traj.firstMeasurement().updatedState().globalPosition().y()) ?
00521 propagatorAlong()->propagate((*fts),navLayers.front()->surface()) : propagatorOpposite()->propagate((*fts),navLayers.front()->surface());
00522
00523 if ( !lastTsos.isValid() ) {
00524 LogTrace(category_)<<"propagation failed from fts to inner cylinder";
00525 return;
00526 }
00527 LogTrace(category_)<<"tsos "<<lastTsos.globalPosition();
00528 lastTsos.rescaleError(10.);
00529 vector<TrajectoryMeasurement> measL;
00530 for (vector<const DetLayer*>::const_iterator rnxtlayer = navLayers.begin();
00531 rnxtlayer!= navLayers.end(); ++rnxtlayer) {
00532
00533 measL.clear();
00534 measL = findBestMeasurements(*rnxtlayer, lastTsos, propagator(), (backwardUpdator()->estimator()));
00535
00536 if ( measL.empty() ) continue;
00537
00538 for (vector<TrajectoryMeasurement>::const_iterator theMeas = measL.begin(); theMeas != measL.end(); ++theMeas) {
00539
00540 pair<bool,TrajectoryStateOnSurface> bkresult
00541 = backwardUpdator()->update((&*theMeas), traj, propagator());
00542 if (bkresult.first ) {
00543 LogTrace(category_)<<"update ok : "<<(theMeas)->recHit()->globalPosition() ;
00544
00545 incrementChamberCounters((*rnxtlayer), DTChamberUsedBack, CSCChamberUsedBack, RPCChamberUsedBack, TotalChamberUsedBack);
00546
00547 if ( (!traj.empty()) && bkresult.second.isValid() )
00548 lastTsos = bkresult.second;
00549 else if ((theMeas)->predictedState().isValid())
00550 lastTsos = (theMeas)->predictedState();
00551 }
00552 }
00553 }
00554 navLayers.clear();
00555 updator()->makeFirstTime();
00556 backwardUpdator()->makeFirstTime();
00557
00558 measL.clear();
00559
00560 return;
00561
00562 }
00563
00564
00565
00566
00567
00568
00569 void CosmicMuonTrajectoryBuilder::buildSecondHalf(Trajectory& traj) {
00570
00571 if ( (traj.firstMeasurement().recHit()->globalPosition().perp()
00572 < traj.lastMeasurement().recHit()->globalPosition().perp()) ) {
00573 LogTrace(category_)<<"inside-out: reverseTrajectory";
00574 reverseTrajectory(traj);
00575 }
00576 if (traj.empty()) return;
00577 TrajectoryStateOnSurface tsos = traj.lastMeasurement().updatedState();
00578 if ( !tsos.isValid() ) tsos = traj.lastMeasurement().predictedState();
00579 LogTrace(category_)<<"last tsos on traj: pos: "<< tsos.globalPosition()<<" mom: "<< tsos.globalMomentum();
00580 if ( !tsos.isValid() ) {
00581 LogTrace(category_)<<"last tsos on traj invalid";
00582 return;
00583 }
00584
00585 build(intermediateState(tsos),insideOut,traj);
00586
00587 return;
00588
00589 }
00590
00591
00592
00593
00594
00595 TrajectoryStateOnSurface CosmicMuonTrajectoryBuilder::intermediateState(const TrajectoryStateOnSurface& tsos) const {
00596
00597 PerpendicularBoundPlaneBuilder planeBuilder;
00598 GlobalPoint pos(0.0, 0.0, 0.0);
00599 BoundPlane* SteppingPlane = planeBuilder(pos,tsos.globalDirection());
00600
00601 TrajectoryStateOnSurface predTsos = propagator()->propagate(tsos, *SteppingPlane);
00602 if ( predTsos.isValid() )
00603 LogTrace(category_)<<"intermediateState: a intermediate state: pos: "<<predTsos.globalPosition() << "mom: " << predTsos.globalMomentum();
00604
00605 return predTsos;
00606
00607 }
00608
00609
00610
00611
00612
00613 void CosmicMuonTrajectoryBuilder::selectHits(MuonTransientTrackingRecHit::MuonRecHitContainer& hits) const {
00614
00615 if ( hits.size() < 2 ) return;
00616
00617 MuonRecHitContainer tmp;
00618 vector<bool> keep(hits.size(),true);
00619 int i(0);
00620 int j(0);
00621
00622 for (MuonRecHitContainer::const_iterator ihit = hits.begin();
00623 ihit != hits.end(); ++ihit ) {
00624 if ( !keep[i] ) { i++; continue; };
00625 j = i + 1;
00626 for (MuonRecHitContainer::const_iterator ihit2 = ihit + 1;
00627 ihit2 != hits.end(); ++ihit2 ) {
00628 if ( !keep[j] ) { j++; continue; }
00629 if ((*ihit)->geographicalId() == (*ihit2)->geographicalId() ) {
00630 if ( (*ihit)->dimension() > (*ihit2)->dimension() ) {
00631 keep[j] = false;
00632 } else if ( (*ihit)->dimension() < (*ihit2)->dimension() ) {
00633 keep[i] = false;
00634 } else {
00635 if ( (*ihit)->transientHits().size()>(*ihit2)->transientHits().size() ) {
00636 keep[j] = false;
00637 } else if ( (*ihit)->transientHits().size()<(*ihit2)->transientHits().size() ) {
00638 keep[i] = false;
00639 }
00640 else if ( (*ihit)->degreesOfFreedom() != 0 && (*ihit2)->degreesOfFreedom() != 0) {
00641 if (((*ihit)->chi2()/(*ihit)->degreesOfFreedom()) > ((*ihit2)->chi2()/(*ihit)->degreesOfFreedom())) keep[i] = false;
00642 else keep[j] = false;
00643 }
00644 }
00645 }
00646 j++;
00647 }
00648 i++;
00649 }
00650
00651 i = 0;
00652 for (MuonRecHitContainer::const_iterator ihit = hits.begin();
00653 ihit != hits.end(); ++ihit ) {
00654 if (keep[i] ) tmp.push_back(*ihit);
00655 i++;
00656 }
00657
00658 hits.clear();
00659 hits.swap(tmp);
00660
00661 return;
00662
00663 }
00664
00665
00666
00667
00668
00669 bool CosmicMuonTrajectoryBuilder::selfDuplicate(const Trajectory& traj) const {
00670
00671 TransientTrackingRecHit::ConstRecHitContainer hits = traj.recHits();
00672
00673 if (traj.empty()) return true;
00674
00675 bool result = false;
00676 for (ConstRecHitContainer::const_iterator ir = hits.begin(); ir != hits.end(); ir++ ) {
00677 if ( !(*ir)->isValid() ) continue;
00678 for (ConstRecHitContainer::const_iterator ir2 = ir+1; ir2 != hits.end(); ir2++ ) {
00679 if ( !(*ir2)->isValid() ) continue;
00680 if ( (*ir) == (*ir2) ) result = true;
00681 }
00682 }
00683
00684 return result;
00685
00686 }
00687
00688
00689
00690
00691
00692
00693 void CosmicMuonTrajectoryBuilder::reverseTrajectory(Trajectory& traj) const {
00694
00695 PropagationDirection newDir = (traj.firstMeasurement().recHit()->globalPosition().y()
00696 < traj.lastMeasurement().recHit()->globalPosition().y())
00697 ? oppositeToMomentum : alongMomentum;
00698 Trajectory newTraj(traj.seed(), newDir);
00699
00700 const std::vector<TrajectoryMeasurement>& meas = traj.measurements();
00701
00702 for (std::vector<TrajectoryMeasurement>::const_reverse_iterator itm = meas.rbegin();
00703 itm != meas.rend(); ++itm ) {
00704 newTraj.push(*itm);
00705 }
00706 traj = newTraj;
00707
00708 }
00709
00710
00711
00712
00713
00714 void CosmicMuonTrajectoryBuilder::flipTrajectory(Trajectory& traj) const {
00715
00716 TrajectoryStateOnSurface lastTSOS = traj.lastMeasurement().updatedState();
00717 if ( !lastTSOS.isValid() ) {
00718 LogTrace(category_) << "Error: last TrajectoryState invalid.";
00719 }
00720 TransientTrackingRecHit::ConstRecHitContainer hits = traj.recHits();
00721 std::reverse(hits.begin(), hits.end());
00722
00723 LogTrace(category_) << "last tsos before flipping "<<lastTSOS;
00724 utilities()->reverseDirection(lastTSOS,&*theService->magneticField());
00725 LogTrace(category_) << "last tsos after flipping "<<lastTSOS;
00726
00727 vector<Trajectory> refittedback = theSmoother->fit(traj.seed(),hits,lastTSOS);
00728 if ( refittedback.empty() ) {
00729 LogTrace(category_) <<"flipTrajectory fail. "<<endl;
00730 return;
00731 }
00732 LogTrace(category_) <<"flipTrajectory: first "<< refittedback.front().firstMeasurement().updatedState()
00733 <<"\nflipTrajectory: last "<<refittedback.front().lastMeasurement().updatedState();
00734
00735 traj = refittedback.front();
00736
00737 return;
00738
00739 }
00740
00741
00742
00743
00744
00745 void CosmicMuonTrajectoryBuilder::reverseTrajectoryPropagationDirection(Trajectory& traj) const {
00746
00747 if ( traj.direction() == anyDirection ) return;
00748 PropagationDirection newDir = (traj.direction() == alongMomentum)? oppositeToMomentum : alongMomentum;
00749 Trajectory newTraj(traj.seed(), newDir);
00750 const std::vector<TrajectoryMeasurement>& meas = traj.measurements();
00751
00752 for (std::vector<TrajectoryMeasurement>::const_iterator itm = meas.begin(); itm != meas.end(); ++itm) {
00753 newTraj.push(*itm);
00754 }
00755
00756 while (!traj.empty()) {
00757 traj.pop();
00758 }
00759
00760 traj = newTraj;
00761
00762 }
00763
00764
00765
00766
00767
00768 void CosmicMuonTrajectoryBuilder::estimateDirection(Trajectory& traj) const {
00769
00770 TransientTrackingRecHit::ConstRecHitContainer hits = traj.recHits();
00771
00772 TrajectoryStateOnSurface firstTSOS = traj.firstMeasurement().updatedState();
00773
00774 TrajectoryStateOnSurface lastTSOS = traj.lastMeasurement().updatedState();
00775
00776 if ( !firstTSOS.isValid() || !lastTSOS.isValid() ) return;
00777
00778 LogTrace(category_) <<"Two ends of the traj "<<firstTSOS.globalPosition()
00779 <<", "<<lastTSOS.globalPosition();
00780
00781 LogTrace(category_) <<"Their mom: "<<firstTSOS.globalMomentum()
00782 <<", "<<lastTSOS.globalMomentum();
00783
00784 LogTrace(category_) <<"Their mom eta: "<<firstTSOS.globalMomentum().eta()
00785 <<", "<<lastTSOS.globalMomentum().eta();
00786
00787
00788
00789
00790 if ( fabs(firstTSOS.globalMomentum().eta()) > fabs(lastTSOS.globalMomentum().eta()) ) {
00791
00792 vector<Trajectory> refitted = theSmoother->trajectories(traj.seed(),hits,firstTSOS);
00793 if ( !refitted.empty() ) traj = refitted.front();
00794
00795 } else {
00796 std::reverse(hits.begin(), hits.end());
00797 utilities()->reverseDirection(lastTSOS,&*theService->magneticField());
00798 vector<Trajectory> refittedback = theSmoother->trajectories(traj.seed(),hits,lastTSOS);
00799 if ( !refittedback.empty() ) traj = refittedback.front();
00800
00801 }
00802
00803 return;
00804
00805 }
00806
00807
00808
00809
00810
00811 void CosmicMuonTrajectoryBuilder::getDirectionByTime(Trajectory& traj) const {
00812
00813 TransientTrackingRecHit::ConstRecHitContainer hits = traj.recHits();
00814 LogTrace(category_) << "getDirectionByTime"<<endl;
00815 for (TransientTrackingRecHit::ConstRecHitContainer::const_iterator ir = hits.begin(); ir != hits.end(); ir++ ) {
00816 if ( !(*ir)->isValid() ) {
00817 LogTrace(category_) << "invalid RecHit"<<endl;
00818 continue;
00819 }
00820
00821 const GlobalPoint& pos = (*ir)->globalPosition();
00822 LogTrace(category_)
00823 << "pos" << pos
00824 << "radius " << pos.perp()
00825 << " dim " << (*ir)->dimension()
00826 << " det " << (*ir)->det()->geographicalId().det()
00827 << " sub det " << (*ir)->det()->subDetector()<<endl;
00828
00829 if ((*ir)->det()->geographicalId().det() == 2 && (*ir)->det()->subDetector() == 6) {
00830
00831
00832 CSCRecHit2DCollection::range thisrange = cschits_->get(CSCDetId((*ir)->geographicalId()));
00833 for (CSCRecHit2DCollection::const_iterator rechit = thisrange.first; rechit!=thisrange.second;++rechit) {
00834 if ((*rechit).isValid()) LogTrace(category_)<<"csc from collection tpeak "<<(*rechit).tpeak();
00835 }
00836 }
00837 if ((*ir)->det()->geographicalId().det() == 2 && (*ir)->det()->subDetector() == 7) {
00838
00839
00840 DTRecHitCollection::range thisrange = dthits_->get(DTLayerId((*ir)->geographicalId()));
00841 for (DTRecHitCollection::const_iterator rechit = thisrange.first; rechit!=thisrange.second;++rechit) {
00842 if ((*rechit).isValid()) LogTrace(category_)<<"dt from collection digitime "<<(*rechit).digiTime();
00843 }
00844 }
00845 }
00846
00847 return;
00848
00849 }
00850
00851
00852
00853
00854
00855 std::vector<TrajectoryMeasurement>
00856 CosmicMuonTrajectoryBuilder::findBestMeasurements(const DetLayer* layer,
00857 const TrajectoryStateOnSurface& tsos,
00858 const Propagator* propagator,
00859 const MeasurementEstimator* estimator) {
00860
00861 std::vector<TrajectoryMeasurement> result;
00862 std::vector<TrajectoryMeasurement> measurements;
00863
00864 if ( layer->hasGroups() ) {
00865 std::vector<TrajectoryMeasurementGroup> measurementGroups =
00866 theLayerMeasurements->groupedMeasurements(layer, tsos, *propagator, *estimator);
00867
00868 for (std::vector<TrajectoryMeasurementGroup>::const_iterator tmGroupItr = measurementGroups.begin();
00869 tmGroupItr != measurementGroups.end(); ++tmGroupItr) {
00870
00871 measurements = tmGroupItr->measurements();
00872 const TrajectoryMeasurement* bestMeasurement
00873 = theBestMeasurementFinder->findBestMeasurement(measurements, propagator);
00874
00875 if (bestMeasurement) result.push_back(*bestMeasurement);
00876 }
00877 }
00878 else {
00879 measurements = theLayerMeasurements->measurements(layer, tsos, *propagator, *estimator);
00880 const TrajectoryMeasurement* bestMeasurement
00881 = theBestMeasurementFinder->findBestMeasurement(measurements, propagator);
00882
00883 if (bestMeasurement) result.push_back(*bestMeasurement);
00884 }
00885 measurements.clear();
00886
00887 return result;
00888
00889 }
00890
00891
00892
00893
00894
00895 void CosmicMuonTrajectoryBuilder::incrementChamberCounters(const DetLayer* layer,
00896 int& dtChambers,
00897 int& cscChambers,
00898 int& rpcChambers,
00899 int& totalChambers) {
00900
00901 if (layer->subDetector()==GeomDetEnumerators::DT) dtChambers++;
00902 else if (layer->subDetector()==GeomDetEnumerators::CSC) cscChambers++;
00903 else if (layer->subDetector()==GeomDetEnumerators::RPCBarrel || layer->subDetector()==GeomDetEnumerators::RPCEndcap) rpcChambers++;
00904 totalChambers++;
00905
00906 }
00907
00908
00909
00910
00911
00912 double CosmicMuonTrajectoryBuilder::t0(const DTRecSegment4D* dtseg) const {
00913
00914 if ( (dtseg == 0) || (!dtseg->hasPhi()) ) return 0;
00915
00916 double result = 0;
00917 if ( dtseg->phiSegment() == 0 ) return 0;
00918 int phiHits = dtseg->phiSegment()->specificRecHits().size();
00919 LogTrace(category_) << "phiHits " << phiHits;
00920 if ( phiHits > 5 ) {
00921 if(dtseg->phiSegment()->ist0Valid()) result = dtseg->phiSegment()->t0();
00922 if (dtseg->phiSegment()->ist0Valid()){
00923 LogTrace(category_) << " Phi t0: " << dtseg->phiSegment()->t0() << " hits: " << phiHits;
00924 } else {
00925 LogTrace(category_) << " Phi t0 is invalid: " << dtseg->phiSegment()->t0() << " hits: " << phiHits;
00926 }
00927 }
00928
00929 return result;
00930
00931 }
00932
00933
00934
00935
00936
00937 PropagationDirection CosmicMuonTrajectoryBuilder::checkDirectionByT0(const DTRecSegment4D* dtseg1,
00938 const DTRecSegment4D* dtseg2) const {
00939
00940 LogTrace(category_) << "comparing dtseg: " << dtseg1 << " " << dtseg2 << endl;
00941 if (dtseg1 == dtseg2 || t0(dtseg1) == t0(dtseg2)) return anyDirection;
00942
00943 PropagationDirection result =
00944 ( t0(dtseg1) < t0(dtseg2) ) ? alongMomentum : oppositeToMomentum;
00945
00946 return result;
00947
00948 }