00001
00002 #include "RecoTracker/CkfPattern/interface/GroupedCkfTrajectoryBuilder.h"
00003 #include "TrajectorySegmentBuilder.h"
00004
00005
00006 #include "TrackingTools/DetLayers/interface/DetLayer.h"
00007 #include "TrackingTools/PatternTools/interface/TrajMeasLessEstim.h"
00008
00009 #include "TrackingTools/KalmanUpdators/interface/KFUpdator.h"
00010 #include "TrackingTools/KalmanUpdators/interface/Chi2MeasurementEstimator.h"
00011 #include "TrackingTools/TrackFitters/interface/KFTrajectoryFitter.h"
00012 #include "RecoTracker/CkfPattern/interface/GroupedTrajCandLess.h"
00013 #include "TrackingTools/TrajectoryFiltering/interface/RegionalTrajectoryFilter.h"
00014 #include "TrackingTools/PatternTools/interface/TempTrajectory.h"
00015 #include "RecoTracker/MeasurementDet/interface/MeasurementTracker.h"
00016 #include "TrackingTools/MeasurementDet/interface/LayerMeasurements.h"
00017 #include "TrackingTools/Records/interface/TrackingComponentsRecord.h"
00018 #include "TrackingTools/DetLayers/interface/DetGroup.h"
00019 #include "RecoTracker/TkDetLayers/interface/GeometricSearchTracker.h"
00020 #include "TrackingTools/Records/interface/TransientRecHitRecord.h"
00021 #include "TrackingTools/TransientTrackingRecHit/interface/TransientTrackingRecHitBuilder.h"
00022 #include "TrackingTools/PatternTools/interface/TrajectoryMeasurement.h"
00023
00024 #include "TrackingTools/PatternTools/interface/TrajectoryStateUpdator.h"
00025 #include "TrackingTools/KalmanUpdators/interface/KFUpdator.h"
00026 #include "TrackingTools/PatternTools/interface/Trajectory.h"
00027 #include "TrackingTools/PatternTools/interface/TrajMeasLessEstim.h"
00028 #include "TrackingTools/TrajectoryState/interface/BasicSingleTrajectoryState.h"
00029 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00030 #include "TrackingTools/PatternTools/interface/TransverseImpactPointExtrapolator.h"
00031
00032
00033 #include "TrackingTools/TrajectoryCleaning/interface/TrajectoryCleanerBySharedHits.h"
00034
00035
00036 #include "TrackingTools/GeomPropagators/interface/HelixBarrelCylinderCrossing.h"
00037 #include "TrackingTools/GeomPropagators/interface/HelixBarrelPlaneCrossingByCircle.h"
00038 #include "TrackingTools/GeomPropagators/interface/HelixArbitraryPlaneCrossing.h"
00039
00040
00041 #include <algorithm>
00042
00043 using namespace std;
00044
00045
00046
00047
00048
00049 #ifdef STANDARD_INTERMEDIARYCLEAN
00050 #include "RecoTracker/CkfPattern/interface/IntermediateTrajectoryCleaner.h"
00051 #endif
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 GroupedCkfTrajectoryBuilder::
00067 GroupedCkfTrajectoryBuilder(const edm::ParameterSet& conf,
00068 const TrajectoryStateUpdator* updator,
00069 const Propagator* propagatorAlong,
00070 const Propagator* propagatorOpposite,
00071 const Chi2MeasurementEstimatorBase* estimator,
00072 const TransientTrackingRecHitBuilder* recHitBuilder,
00073 const MeasurementTracker* measurementTracker,
00074 const TrajectoryFilter* filter,
00075 const TrajectoryFilter* inOutFilter):
00076
00077
00078 BaseCkfTrajectoryBuilder(conf,
00079 updator, propagatorAlong,propagatorOpposite,
00080 estimator, recHitBuilder, measurementTracker, filter, inOutFilter)
00081 {
00082
00083
00084 theMaxCand = conf.getParameter<int>("maxCand");
00085
00086 theLostHitPenalty = conf.getParameter<double>("lostHitPenalty");
00087 theFoundHitBonus = conf.getParameter<double>("foundHitBonus");
00088 theIntermediateCleaning = conf.getParameter<bool>("intermediateCleaning");
00089 theAlwaysUseInvalid = conf.getParameter<bool>("alwaysUseInvalidHits");
00090 theLockHits = conf.getParameter<bool>("lockHits");
00091 theBestHitOnly = conf.getParameter<bool>("bestHitOnly");
00092 theMinNrOf2dHitsForRebuild = 2;
00093 theRequireSeedHitsInRebuild = conf.getParameter<bool>("requireSeedHitsInRebuild");
00094 theMinNrOfHitsForRebuild = max(0,conf.getParameter<int>("minNrOfHitsForRebuild"));
00095 maxPtForLooperReconstruction = conf.existsAs<double>("maxPtForLooperReconstruction") ?
00096 conf.getParameter<double>("maxPtForLooperReconstruction") : 0;
00097 maxDPhiForLooperReconstruction = conf.existsAs<double>("maxDPhiForLooperReconstruction") ?
00098 conf.getParameter<double>("maxDPhiForLooperReconstruction") : 2.0;
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 }
00113
00114
00115
00116
00117
00118
00119
00120
00121 GroupedCkfTrajectoryBuilder::TrajectoryContainer
00122 GroupedCkfTrajectoryBuilder::trajectories (const TrajectorySeed& seed) const
00123 {
00124 TrajectoryContainer ret;
00125 ret.reserve(10);
00126 buildTrajectories(seed, ret, 0);
00127 return ret;
00128 }
00129
00130 GroupedCkfTrajectoryBuilder::TrajectoryContainer
00131 GroupedCkfTrajectoryBuilder::trajectories (const TrajectorySeed& seed,
00132 const TrackingRegion& region) const
00133 {
00134 TrajectoryContainer ret;
00135 ret.reserve(10);
00136 RegionalTrajectoryFilter regionalCondition(region);
00137 buildTrajectories(seed, ret, ®ionalCondition);
00138 return ret;
00139 }
00140
00141 void
00142 GroupedCkfTrajectoryBuilder::trajectories (const TrajectorySeed& seed, GroupedCkfTrajectoryBuilder::TrajectoryContainer &ret) const
00143 {
00144 buildTrajectories(seed,ret,0);
00145 }
00146
00147 void
00148 GroupedCkfTrajectoryBuilder::trajectories (const TrajectorySeed& seed,
00149 GroupedCkfTrajectoryBuilder::TrajectoryContainer &ret,
00150 const TrackingRegion& region) const
00151 {
00152 RegionalTrajectoryFilter regionalCondition(region);
00153 buildTrajectories(seed,ret,®ionalCondition);
00154 }
00155
00156 void
00157 GroupedCkfTrajectoryBuilder::rebuildSeedingRegion(const TrajectorySeed& seed,
00158 TrajectoryContainer& result) const {
00159 TempTrajectory startingTraj = createStartingTrajectory( seed);
00160 TempTrajectoryContainer work;
00161
00162 TrajectoryContainer final;
00163
00164 work.reserve(result.size());
00165 for (TrajectoryContainer::iterator traj=result.begin();
00166 traj!=result.end(); ++traj) {
00167 if(traj->isValid()) work.push_back(TempTrajectory(*traj));
00168 }
00169
00170 rebuildSeedingRegion(startingTraj,work);
00171 final.reserve(work.size());
00172
00173 for (TempTrajectoryContainer::iterator traj=work.begin();
00174 traj!=work.end(); ++traj) {
00175 final.push_back(traj->toTrajectory());
00176 }
00177
00178 result.swap(final);
00179
00180 }
00181
00182 void
00183 GroupedCkfTrajectoryBuilder::buildTrajectories (const TrajectorySeed& seed,
00184 GroupedCkfTrajectoryBuilder::TrajectoryContainer &result,
00185 const TrajectoryFilter* regionalCondition) const
00186 {
00187
00188
00189
00190
00191 analyseSeed( seed);
00192
00193 TempTrajectory startingTraj = createStartingTrajectory( seed);
00194
00195 work_.clear();
00196 const bool inOut = true;
00197 groupedLimitedCandidates( startingTraj, regionalCondition, theForwardPropagator, inOut, work_);
00198 if ( work_.empty() ) return ;
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215 result.reserve(work_.size());
00216 for (TempTrajectoryContainer::const_iterator it = work_.begin(), ed = work_.end(); it != ed; ++it) {
00217 result.push_back( it->toTrajectory() );
00218 }
00219
00220 work_.clear();
00221 if (work_.capacity() > work_MaxSize_) { TempTrajectoryContainer().swap(work_); work_.reserve(work_MaxSize_/2); }
00222
00223 analyseResult(result);
00224
00225 LogDebug("CkfPattern")<< "GroupedCkfTrajectoryBuilder: returning result of size " << result.size();
00226
00227 }
00228
00229
00230 void
00231 GroupedCkfTrajectoryBuilder::groupedLimitedCandidates (TempTrajectory& startingTraj,
00232 const TrajectoryFilter* regionalCondition,
00233 const Propagator* propagator,
00234 bool inOut,
00235 TempTrajectoryContainer& result) const
00236 {
00237 unsigned int nIter=1;
00238 TempTrajectoryContainer candidates;
00239 TempTrajectoryContainer newCand;
00240 candidates.push_back( startingTraj);
00241
00242 while ( !candidates.empty()) {
00243
00244 newCand.clear();
00245 for (TempTrajectoryContainer::iterator traj=candidates.begin();
00246 traj!=candidates.end(); traj++) {
00247 if ( !advanceOneLayer(*traj, regionalCondition, propagator, inOut, newCand, result) ) {
00248 LogDebug("CkfPattern")<< "GCTB: terminating after advanceOneLayer==false";
00249 continue;
00250 }
00251
00252 LogDebug("CkfPattern")<<"newCand(1): after advanced one layer:\n"<<PrintoutHelper::dumpCandidates(newCand);
00253
00254 if ((int)newCand.size() > theMaxCand) {
00255
00256
00257 sort( newCand.begin(), newCand.end(), GroupedTrajCandLess(theLostHitPenalty,theFoundHitBonus));
00258 newCand.erase( newCand.begin()+theMaxCand, newCand.end());
00259 }
00260 LogDebug("CkfPattern")<<"newCand(2): after removing extra candidates.\n"<<PrintoutHelper::dumpCandidates(newCand);
00261 }
00262
00263 LogDebug("CkfPattern") << "newCand.size() at end = " << newCand.size();
00264
00265
00266
00267
00268
00269
00270
00271
00272 if (theIntermediateCleaning) {
00273 #ifdef STANDARD_INTERMEDIARYCLEAN
00274 IntermediateTrajectoryCleaner::clean(newCand);
00275 #else
00276 groupedIntermediaryClean(newCand);
00277 #endif
00278
00279 }
00280 candidates.swap(newCand);
00281
00282 LogDebug("CkfPattern") <<"candidates(3): "<<result.size()<<" candidates after "<<nIter++<<" groupedCKF iteration: \n"
00283 <<PrintoutHelper::dumpCandidates(result)
00284 <<"\n "<<candidates.size()<<" running candidates are: \n"
00285 <<PrintoutHelper::dumpCandidates(candidates);
00286 }
00287 }
00288
00289 std::string whatIsTheNextStep(TempTrajectory& traj , std::pair<TrajectoryStateOnSurface,std::vector<const DetLayer*> >& stateAndLayers){
00290 std::stringstream buffer;
00291 vector<const DetLayer*> & nl = stateAndLayers.second;
00292 #include "TrackingTools/DetLayers/interface/BarrelDetLayer.h"
00293 #include "TrackingTools/DetLayers/interface/ForwardDetLayer.h"
00294
00295
00296 const BarrelDetLayer* sbdl = dynamic_cast<const BarrelDetLayer*>(traj.lastLayer());
00297 const ForwardDetLayer* sfdl = dynamic_cast<const ForwardDetLayer*>(traj.lastLayer());
00298 if (sbdl) {
00299 buffer << "Started from " << traj.lastLayer() << " r=" << sbdl->specificSurface().radius()
00300 << " phi=" << sbdl->specificSurface().phi() << endl;
00301 } else if (sfdl) {
00302 buffer << "Started from " << traj.lastLayer() << " z " << sfdl->specificSurface().position().z()
00303 << " phi " << sfdl->specificSurface().phi() << endl;
00304 }
00305 buffer << "Trying to go to";
00306 for ( vector<const DetLayer*>::iterator il=nl.begin();
00307 il!=nl.end(); il++){
00308
00309 const BarrelDetLayer* bdl = dynamic_cast<const BarrelDetLayer*>(*il);
00310 const ForwardDetLayer* fdl = dynamic_cast<const ForwardDetLayer*>(*il);
00311
00312 if (bdl) buffer << " r " << bdl->specificSurface().radius() << endl;
00313 if (fdl) buffer << " z " << fdl->specificSurface().position().z() << endl;
00314
00315 }
00316 return buffer.str();
00317 }
00318
00319 std::string whatIsTheStateToUse(TrajectoryStateOnSurface &initial, TrajectoryStateOnSurface & stateToUse, const DetLayer * l){
00320 std::stringstream buffer;
00321 buffer << "GCTB: starting from "
00322 << " r / phi / z = " << stateToUse.globalPosition().perp()
00323 << " / " << stateToUse.globalPosition().phi()
00324 << " / " << stateToUse.globalPosition().z()
00325 << " , pt / phi / pz /charge = "
00326 << stateToUse.globalMomentum().perp() << " / "
00327 << stateToUse.globalMomentum().phi() << " / "
00328 << stateToUse.globalMomentum().z() << " / "
00329 << stateToUse.charge()
00330 << " for layer at "<< l << endl;
00331 buffer << " errors:";
00332 for ( int i=0; i<5; i++ ) buffer << " " << sqrt(stateToUse.curvilinearError().matrix()(i,i));
00333 buffer << endl;
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344 return buffer.str();
00345 }
00346
00347
00348 bool
00349 GroupedCkfTrajectoryBuilder::advanceOneLayer (TempTrajectory& traj,
00350 const TrajectoryFilter* regionalCondition,
00351 const Propagator* propagator,
00352 bool inOut,
00353 TempTrajectoryContainer& newCand,
00354 TempTrajectoryContainer& result) const
00355 {
00356 std::pair<TSOS,std::vector<const DetLayer*> > stateAndLayers = findStateAndLayers(traj);
00357 if(maxPtForLooperReconstruction>0){
00358 if(
00359
00360 traj.lastLayer()->location()==0 &&
00361 stateAndLayers.first.globalMomentum().perp()<maxPtForLooperReconstruction &&
00362 stateAndLayers.first.globalMomentum().perp()>0.3)
00363 stateAndLayers.second.push_back(traj.lastLayer());
00364 }
00365
00366 vector<const DetLayer*>::iterator layerBegin = stateAndLayers.second.begin();
00367 vector<const DetLayer*>::iterator layerEnd = stateAndLayers.second.end();
00368
00369
00370
00371
00372
00373
00374 LogDebug("CkfPattern")<<whatIsTheNextStep(traj, stateAndLayers);
00375
00376 bool foundSegments(false);
00377 bool foundNewCandidates(false);
00378 for ( vector<const DetLayer*>::iterator il=layerBegin;
00379 il!=layerEnd; il++) {
00380
00381 TSOS stateToUse = stateAndLayers.first;
00382
00383 double dPhiCacheForLoopersReconstruction(0);
00384 if ((*il)==traj.lastLayer()){
00385 if(maxPtForLooperReconstruction>0){
00386
00387
00388 const BarrelDetLayer* sbdl = dynamic_cast<const BarrelDetLayer*>(traj.lastLayer());
00389 if(sbdl){
00390 HelixBarrelCylinderCrossing cylinderCrossing(stateToUse.globalPosition(),
00391 stateToUse.globalMomentum(),
00392 stateToUse.transverseCurvature(),
00393 propagator->propagationDirection(),
00394 sbdl->specificSurface());
00395 if(!cylinderCrossing.hasSolution()) continue;
00396 GlobalPoint starting = stateToUse.globalPosition();
00397 GlobalPoint target1 = cylinderCrossing.position1();
00398 GlobalPoint target2 = cylinderCrossing.position2();
00399
00400 GlobalPoint farther = fabs(starting.phi()-target1.phi()) > fabs(starting.phi()-target2.phi()) ?
00401 target1 : target2;
00402
00403 const Bounds& bounds( sbdl->specificSurface().bounds());
00404 float length = bounds.length() / 2.f;
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420 if(fabs(farther.z())*0.95>length) continue;
00421
00422 Geom::Phi<double> tmpDphi = target1.phi()-target2.phi();
00423 if(fabs(tmpDphi)>maxDPhiForLooperReconstruction) continue;
00424 GlobalPoint target((target1.x()+target2.x())/2,
00425 (target1.y()+target2.y())/2,
00426 (target1.z()+target2.z())/2);
00427
00428
00429
00430
00431
00432 TransverseImpactPointExtrapolator extrapolator;
00433 stateToUse = extrapolator.extrapolate(stateToUse, target, *propagator);
00434 if (!stateToUse.isValid()) continue;
00435
00436
00437 dPhiCacheForLoopersReconstruction = fabs(tmpDphi);
00438 traj.incrementLoops();
00439 }else{
00440 continue;
00441 }
00442 }else{
00443
00444 LogDebug("CkfPattern")<<" self propagating in advanceOneLayer.\n from: \n"<<stateToUse;
00445
00446
00447 TransverseImpactPointExtrapolator middle;
00448 GlobalPoint center(0,0,0);
00449 stateToUse = middle.extrapolate(stateToUse, center, *theForwardPropagator);
00450
00451 if (!stateToUse.isValid()) continue;
00452 LogDebug("CkfPattern")<<"to: "<<stateToUse;
00453 }
00454 }
00455
00456 unsigned int maxCandidates = theMaxCand > 21 ? theMaxCand*2 : 42;
00457 TrajectorySegmentBuilder layerBuilder(theMeasurementTracker,
00458 theLayerMeasurements,
00459 **il,*propagator,
00460 *theUpdator,*theEstimator,
00461 theLockHits,theBestHitOnly, maxCandidates);
00462
00463 LogDebug("CkfPattern")<<whatIsTheStateToUse(stateAndLayers.first,stateToUse,*il);
00464
00465 TempTrajectoryContainer segments=
00466 layerBuilder.segments(stateToUse);
00467
00468 LogDebug("CkfPattern")<< "GCTB: number of segments = " << segments.size();
00469
00470 if ( !segments.empty() ) foundSegments = true;
00471
00472 for ( TempTrajectoryContainer::const_iterator is=segments.begin();
00473 is!=segments.end(); is++ ) {
00474
00475
00476
00477 const TempTrajectory::DataContainer & measurements = is->measurements();
00478 if ( !theAlwaysUseInvalid && is!=segments.begin() && measurements.size()==1 &&
00479 (measurements.front().recHit()->getType() == TrackingRecHit::missing) ) break;
00480
00481
00482
00483 TempTrajectory newTraj(traj);
00484 traj.setDPhiCacheForLoopersReconstruction(dPhiCacheForLoopersReconstruction);
00485
00486
00487 bool toBeRejected(false);
00488 for(const TempTrajectory::DataContainer::const_iterator revIt = measurements.rbegin();
00489 revIt!=measurements.rend(); --revIt){
00490 int tmpCounter(0);
00491 for(const TempTrajectory::DataContainer::const_iterator newTrajMeasIt = newTraj.measurements().rbegin();
00492 newTrajMeasIt != newTraj.measurements().rend(); --newTrajMeasIt){
00493
00494 if(revIt->recHit()->geographicalId()==newTrajMeasIt->recHit()->geographicalId()){
00495 toBeRejected=true;
00496 break;
00497 }
00498 tmpCounter++;
00499 }
00500 }
00501
00502 if(!toBeRejected){
00503
00504
00505
00506
00507
00508 }else{
00509
00510
00511
00512
00513
00514
00515 continue;
00516 }
00517
00518
00519
00520 newTraj.push(*is);
00521
00522
00523
00524 if ( toBeContinued(newTraj, inOut) ) {
00525
00526
00527 LogDebug("CkfPattern")<<"GCTB: adding updated trajectory to candidates: inOut="<<inOut<<" hits="<<newTraj.foundHits();
00528
00529 newCand.push_back(newTraj);
00530 foundNewCandidates = true;
00531 }
00532 else {
00533
00534
00535 LogDebug("CkfPattern")<< "GCTB: adding completed trajectory to results if passes cuts: inOut="<<inOut<<" hits="<<newTraj.foundHits();
00536
00537 addToResult(newTraj, result, inOut);
00538 }
00539 }
00540 }
00541
00542 if ( !foundSegments ){
00543 LogDebug("CkfPattern")<< "GCTB: adding input trajectory to result";
00544 addToResult(traj, result, inOut);
00545 }
00546 return foundNewCandidates;
00547 }
00548
00549
00550 void
00551 GroupedCkfTrajectoryBuilder::groupedIntermediaryClean (TempTrajectoryContainer& theTrajectories) const
00552 {
00553
00554
00555 if (theTrajectories.empty()) return;
00556
00557 int firstLayerSize, secondLayerSize;
00558 vector<const DetLayer*> firstLayers, secondLayers;
00559
00560 for (TempTrajectoryContainer::iterator firstTraj=theTrajectories.begin();
00561 firstTraj!=(theTrajectories.end()-1); firstTraj++) {
00562
00563 if ( (!firstTraj->isValid()) ||
00564 (!firstTraj->lastMeasurement().recHit()->isValid()) ) continue;
00565 const TempTrajectory::DataContainer & firstMeasurements = firstTraj->measurements();
00566 layers(firstMeasurements, firstLayers);
00567 firstLayerSize = firstLayers.size();
00568 if ( firstLayerSize<4 ) continue;
00569
00570 for (TempTrajectoryContainer::iterator secondTraj=(firstTraj+1);
00571 secondTraj!=theTrajectories.end(); secondTraj++) {
00572
00573 if ( (!secondTraj->isValid()) ||
00574 (!secondTraj->lastMeasurement().recHit()->isValid()) ) continue;
00575 const TempTrajectory::DataContainer & secondMeasurements = secondTraj->measurements();
00576 layers(secondMeasurements, secondLayers);
00577 secondLayerSize = secondLayers.size();
00578
00579
00580
00581 if ( firstLayerSize!=secondLayerSize ) continue;
00582 if ( firstLayers[0]!=secondLayers[0] ||
00583 firstLayers[1]!=secondLayers[1] ||
00584 firstLayers[2]!=secondLayers[2] ) continue;
00585
00586 TempTrajectory::DataContainer::const_iterator im1 = firstMeasurements.rbegin();
00587 TempTrajectory::DataContainer::const_iterator im2 = secondMeasurements.rbegin();
00588
00589
00590
00591 bool unequal(false);
00592 const DetLayer* layerPtr = firstLayers[0];
00593 while ( im1!=firstMeasurements.rend()&&im2!=secondMeasurements.rend() ) {
00594 if ( im1->layer()!=layerPtr || im2->layer()!=layerPtr ) break;
00595 if ( !(im1->recHit()->isValid()) || !(im2->recHit()->isValid()) ||
00596 !im1->recHit()->hit()->sharesInput(im2->recHit()->hit(), TrackingRecHit::some) ) {
00598 unequal = true;
00599 break;
00600 }
00601 --im1;
00602 --im2;
00603 }
00604 if ( im1==firstMeasurements.rend() || im2==secondMeasurements.rend() ||
00605 im1->layer()==layerPtr || im2->layer()==layerPtr || unequal ) continue;
00606
00607
00608
00609
00610 layerPtr = firstLayers[1];
00611 bool firstValid(true);
00612 while ( im1!=firstMeasurements.rend()&&im1->layer()==layerPtr ) {
00613 if ( !im1->recHit()->isValid() ) firstValid = false;
00614 --im1;
00615 }
00616 bool secondValid(true);
00617 while ( im2!=secondMeasurements.rend()&&im2->layer()==layerPtr ) {
00618 if ( !im2->recHit()->isValid() ) secondValid = false;
00619 --im2;
00620 }
00621 if ( !tkxor(firstValid,secondValid) ) continue;
00622
00623
00624
00625 unequal = false;
00626 layerPtr = firstLayers[2];
00627 while ( im1!=firstMeasurements.rend()&&im2!=secondMeasurements.rend() ) {
00628 if ( im1->layer()!=layerPtr || im2->layer()!=layerPtr ) break;
00629 if ( !(im1->recHit()->isValid()) || !(im2->recHit()->isValid()) ||
00630 !im1->recHit()->hit()->sharesInput(im2->recHit()->hit(), TrackingRecHit::some) ) {
00632 unequal = true;
00633 break;
00634 }
00635 --im1;
00636 --im2;
00637 }
00638 if ( im1==firstMeasurements.rend() || im2==secondMeasurements.rend() ||
00639 im1->layer()==layerPtr || im2->layer()==layerPtr || unequal ) continue;
00640
00641 if ( !firstValid ) {
00642 firstTraj->invalidate();
00643 break;
00644 }
00645 else {
00646 secondTraj->invalidate();
00647 break;
00648 }
00649 }
00650 }
00651
00652
00653
00654
00655
00656
00657
00658
00659 theTrajectories.erase(std::remove_if( theTrajectories.begin(),theTrajectories.end(),
00660 std::not1(std::mem_fun_ref(&TempTrajectory::isValid))),
00661
00662 theTrajectories.end());
00663 }
00664
00665 void
00666 GroupedCkfTrajectoryBuilder::layers (const TempTrajectory::DataContainer& measurements,
00667 vector<const DetLayer*> &result) const
00668 {
00669 result.clear();
00670
00671 if ( measurements.empty() ) return ;
00672
00673 result.push_back(measurements.back().layer());
00674 TempTrajectory::DataContainer::const_iterator ifirst = measurements.rbegin();
00675 --ifirst;
00676 for ( TempTrajectory::DataContainer::const_iterator im=ifirst;
00677 im!=measurements.rend(); --im ) {
00678 if ( im->layer()!=result.back() ) result.push_back(im->layer());
00679 }
00680
00681 for (vector<const DetLayer*>::const_iterator iter = result.begin(); iter != result.end(); iter++){
00682 if (!*iter) edm::LogWarning("CkfPattern")<< "Warning: null det layer!! ";
00683 }
00684 }
00685
00686 void
00687 GroupedCkfTrajectoryBuilder::rebuildSeedingRegion(TempTrajectory& startingTraj,
00688 TempTrajectoryContainer& result) const
00689 {
00690
00691
00692
00693
00694
00695 LogDebug("CkfPattern")<< "Starting to rebuild " << result.size() << " tracks";
00696
00697
00698
00699
00700 KFTrajectoryFitter fitter(&(*theBackwardPropagator),&updator(),&estimator());
00701
00702 TempTrajectoryContainer reFitted;
00703 TrajectorySeed::range rseedHits = startingTraj.seed().recHits();
00704 std::vector<const TrackingRecHit*> seedHits;
00705
00706
00707
00708
00709
00710
00711 unsigned int nSeed(rseedHits.second-rseedHits.first);
00712
00713 TempTrajectoryContainer rebuiltTrajectories;
00714 for ( TempTrajectoryContainer::iterator it=result.begin();
00715 it!=result.end(); it++ ) {
00716
00717
00718
00719
00720
00721 if ( it->measurements().size()<=startingTraj.measurements().size() ) {
00722 rebuiltTrajectories.push_back(*it);
00723 LogDebug("CkfPattern")<< "RebuildSeedingRegion skipped as in-out trajectory does not exceed seed size.";
00724 continue;
00725 }
00726
00727
00728
00729
00730
00731 backwardFit(*it,nSeed,fitter,reFitted,seedHits);
00732 if ( reFitted.size()!=1 ) {
00733 rebuiltTrajectories.push_back(*it);
00734 LogDebug("CkfPattern")<< "RebuildSeedingRegion skipped as backward fit failed";
00735
00736 continue;
00737 }
00738
00739
00740
00741
00742
00743 int nRebuilt =
00744 rebuildSeedingRegion (seedHits,reFitted.front(),rebuiltTrajectories);
00745
00746 if ( nRebuilt==0 ) it->invalidate();
00747
00748 if ( nRebuilt<=0 ) rebuiltTrajectories.push_back(*it);
00749
00750 }
00751
00752
00753
00754 result.swap(rebuiltTrajectories);
00755 result.erase(std::remove_if( result.begin(),result.end(),
00756 std::not1(std::mem_fun_ref(&TempTrajectory::isValid))),
00757 result.end());
00758 }
00759
00760 int
00761 GroupedCkfTrajectoryBuilder::rebuildSeedingRegion(const std::vector<const TrackingRecHit*>& seedHits,
00762 TempTrajectory& candidate,
00763 TempTrajectoryContainer& result) const
00764 {
00765
00766
00767
00768
00769
00770
00771
00772 TempTrajectoryContainer rebuiltTrajectories;
00773 #ifdef DBG2_GCTB
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797 cout << "Before backward building: #measurements = "
00798 << candidate.measurements().size() ;
00799 #endif
00800
00801
00802
00803
00804 const bool inOut = false;
00805 groupedLimitedCandidates(candidate, (const TrajectoryFilter*)0, theBackwardPropagator, inOut, rebuiltTrajectories);
00806
00807 LogDebug("CkfPattern")<<" After backward building: "<<PrintoutHelper::dumpCandidates(rebuiltTrajectories);
00808
00809
00810
00811
00812 int nrOfTrajectories(0);
00813 bool orig_ok = false;
00814
00815
00816 for ( TempTrajectoryContainer::iterator it=rebuiltTrajectories.begin();
00817 it!=rebuiltTrajectories.end(); it++ ) {
00818
00819 TempTrajectory::DataContainer newMeasurements(it->measurements());
00820
00821
00822
00823 if ( theRequireSeedHitsInRebuild ) {
00824 orig_ok = true;
00825
00826 if ( newMeasurements.size()<=candidate.measurements().size() ){
00827 LogDebug("CkfPattern") << "newMeasurements.size()<=candidate.measurements().size()";
00828 continue;
00829 }
00830
00831
00832
00833 if ( !verifyHits(newMeasurements.rbegin(),
00834 newMeasurements.size() - candidate.measurements().size(),
00835 seedHits) ){
00836 LogDebug("CkfPattern")<< "seed hits not found in rebuild";
00837 continue;
00838 }
00839 }
00840
00841
00842
00843 TempTrajectory reversedTrajectory(it->seed(),it->seed().direction());
00844 reversedTrajectory.setNLoops(it->nLoops());
00845 for (TempTrajectory::DataContainer::const_iterator im=newMeasurements.rbegin(), ed = newMeasurements.rend();
00846 im != ed; --im ) {
00847 reversedTrajectory.push(*im);
00848 }
00849
00850 result.push_back(reversedTrajectory);
00851 nrOfTrajectories++;
00852
00853 LogDebug("CkgPattern")<<"New traj direction = " << reversedTrajectory.direction()<<"\n"
00854 <<PrintoutHelper::dumpMeasurements(reversedTrajectory.measurements());
00855 }
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865 if ( (nrOfTrajectories == 0) && orig_ok ) {
00866 nrOfTrajectories = -1;
00867 }
00868 return nrOfTrajectories;
00869 }
00870
00871 void
00872 GroupedCkfTrajectoryBuilder::backwardFit (TempTrajectory& candidate, unsigned int nSeed,
00873 const TrajectoryFitter& fitter,
00874 TempTrajectoryContainer& fittedTracks,
00875 std::vector<const TrackingRecHit*>& remainingHits) const
00876 {
00877
00878
00879
00880 remainingHits.clear();
00881 fittedTracks.clear();
00882
00883
00884
00885
00886 if ( candidate.measurements().size()<=nSeed ) {
00887 fittedTracks.clear();
00888 return;
00889 }
00890
00891 LogDebug("CkfPattern")<<"nSeed " << nSeed << endl
00892 << "Old traj direction = " << candidate.direction() << endl
00893 <<PrintoutHelper::dumpMeasurements(candidate.measurements());
00894
00895
00896
00897
00898
00899
00900 TempTrajectory::DataContainer oldMeasurements(candidate.measurements());
00901
00902
00903
00904 unsigned int nHit(0);
00905
00906
00907
00908
00909 unsigned int nHitMin = max(candidate.foundHits()-nSeed,theMinNrOfHitsForRebuild);
00910
00911
00912 if (nHitMin<theMinNrOfHitsForRebuild){
00913 fittedTracks.clear();
00914 return;
00915 }
00916
00917 LogDebug("CkfPattern") <<"Sizes: " << oldMeasurements.size() << " / ";
00918
00919
00920
00921 Trajectory fwdTraj(candidate.seed(),oppositeDirection(candidate.direction()));
00922 fwdTraj.setNLoops(candidate.nLoops());
00923
00924
00925 std::vector<const DetLayer*> bwdDetLayer;
00926 for ( TempTrajectory::DataContainer::const_iterator im=oldMeasurements.rbegin();
00927 im!=oldMeasurements.rend(); --im) {
00928 const TrackingRecHit* hit = im->recHit()->hit();
00929
00930
00931
00932 if ( nHit<nHitMin ){
00933 fwdTraj.push(*im);
00934 bwdDetLayer.push_back(im->layer());
00935
00936
00937
00938 if ( hit->isValid() ) {
00939 nHit++;
00940
00941
00942
00943 }
00944 }
00945
00946
00947
00948
00949 else if ( hit->isValid() ) {
00950
00951 remainingHits.push_back(hit);
00952 }
00953 }
00954
00955
00956
00957 if ( nHit<nHitMin ){
00958 fittedTracks.clear();
00959 return;
00960 }
00961
00962
00963
00964 TrajectoryStateOnSurface firstTsos(fwdTraj.firstMeasurement().updatedState());
00965
00966 firstTsos.rescaleError(10.);
00967
00968 TrajectoryContainer bwdFitted(fitter.fit(
00969 TrajectorySeed(PTrajectoryStateOnDet(), TrajectorySeed::recHitContainer(), oppositeDirection(candidate.direction())),
00970 fwdTraj.recHits(),firstTsos));
00971 if (bwdFitted.size()){
00972 LogDebug("CkfPattern")<<"Obtained " << bwdFitted.size() << " bwdFitted trajectories with measurement size " << bwdFitted.front().measurements().size();
00973 TempTrajectory fitted(fwdTraj.seed(), fwdTraj.direction());
00974 fitted.setNLoops(fwdTraj.nLoops());
00975 vector<TM> tmsbf = bwdFitted.front().measurements();
00976 int iDetLayer=0;
00977
00978
00979
00980
00981 for ( vector<TM>::const_iterator im=tmsbf.begin();im!=tmsbf.end(); im++ ) {
00982 fitted.push(TM( (*im).forwardPredictedState(),
00983 (*im).backwardPredictedState(),
00984 (*im).updatedState(),
00985 (*im).recHit(),
00986 (*im).estimate(),
00987 bwdDetLayer[iDetLayer]));
00988
00989 LogDebug("CkfPattern")<<PrintoutHelper::dumpMeasurement(*im);
00990 iDetLayer++;
00991 }
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001 fittedTracks.push_back(fitted);
01002 }
01003
01004
01005
01006
01007
01008 }
01009
01010 bool
01011 GroupedCkfTrajectoryBuilder::verifyHits (TempTrajectory::DataContainer::const_iterator rbegin,
01012 size_t maxDepth,
01013 const std::vector<const TrackingRecHit*>& hits) const
01014 {
01015
01016
01017
01018 LogDebug("CkfPattern")<<"Checking for " << hits.size() << " hits in "
01019 << maxDepth << " measurements" << endl;
01020
01021 TempTrajectory::DataContainer::const_iterator rend = rbegin;
01022 while (maxDepth > 0) { --maxDepth; --rend; }
01023 for ( vector<const TrackingRecHit*>::const_iterator ir=hits.begin();
01024 ir!=hits.end(); ir++ ) {
01025
01026 bool foundHit(false);
01027 for ( TempTrajectory::DataContainer::const_iterator im=rbegin; im!=rend; --im ) {
01028 if ( im->recHit()->isValid() && (*ir)->sharesInput(im->recHit()->hit(), TrackingRecHit::some) ) {
01029 foundHit = true;
01030 break;
01031 }
01032 }
01033 if ( !foundHit ) return false;
01034 }
01035 return true;
01036 }
01037
01038
01039
01040