00001 #include <RecoMuon/L3TrackFinder/interface/MuonRoadTrajectoryBuilder.h>
00002
00012 #include <FWCore/MessageLogger/interface/MessageLogger.h>
00013
00014 #include <DataFormats/GeometrySurface/interface/TkRotation.h>
00015 #include <DataFormats/GeometryCommonDetAlgo/interface/ErrorFrameTransformer.h>
00016 #include <DataFormats/GeometryVector/interface/LocalPoint.h>
00017 #include <DataFormats/GeometryVector/interface/LocalVector.h>
00018 #include <DataFormats/GeometrySurface/interface/BoundPlane.h>
00019 #include <DataFormats/GeometrySurface/interface/OpenBounds.h>
00020 #include <DataFormats/GeometrySurface/interface/SimpleDiskBounds.h>
00021
00022
00023 #include <DataFormats/TrajectoryState/interface/PTrajectoryStateOnDet.h>
00024 #include <DataFormats/DetId/interface/DetId.h>
00025
00026 #include <TrackingTools/TransientTrackingRecHit/interface/GenericTransientTrackingRecHit.h>
00027 #include <TrackingTools/MeasurementDet/interface/MeasurementDet.h>
00028 #include <TrackingTools/KalmanUpdators/interface/KFUpdator.h>
00029
00030
00031 #include <TrackingTools/TrackFitters/interface/KFTrajectorySmoother.h>
00032
00033 #include <RecoTracker/TkDetLayers/interface/GeometricSearchTracker.h>
00034 #include <RecoTracker/Record/interface/CkfComponentsRecord.h>
00035
00036 #include <DataFormats/TrackerRecHit2D/interface/SiStripRecHit2D.h>
00037 #include <DataFormats/TrackerRecHit2D/interface/SiStripMatchedRecHit2D.h>
00038
00039
00040 MuonRoadTrajectoryBuilder::MuonRoadTrajectoryBuilder(const edm::ParameterSet & iConfig,
00041 const MeasurementTracker * mt,
00042 const MagneticField * f,
00043 const Propagator * p):
00044 theRoadEstimator(0),theHitEstimator(0),theUpdator(0),theSmoother(0)
00045 {
00046
00047 theMeasurementTracker = mt;
00048 theField = f;
00049 thePropagator = p;
00050
00051 theCategory = "Muon|RecoMuon|MuonRoadTrajectoryBuilder";
00052
00053
00054
00055
00056
00057
00058
00059 double chi2R=iConfig.getParameter<double>("maxChi2Road");
00060 theRoadEstimator = new Chi2MeasurementEstimator(chi2R,sqrt(chi2R));
00061 double chi2H=iConfig.getParameter<double>("maxChi2Hit");
00062 theHitEstimator = new Chi2MeasurementEstimator(chi2H,sqrt(chi2H));
00063
00064
00065 theUpdator= new KFUpdator();
00066
00067
00068 theMaxTrajectories = iConfig.getParameter<unsigned int>("maxTrajectories");
00069
00070
00071 theDynamicMaxNumberOfHitPerModule = iConfig.getParameter<bool>("dynamicMaxNumberOfHitPerModule");
00072 theNumberOfHitPerModuleDefault = iConfig.getParameter<unsigned int>("numberOfHitPerModule");
00073 theMaxTrajectoriesThreshold = iConfig.getParameter<std::vector<unsigned int> >("maxTrajectoriesThreshold");
00074 theNumberOfHitPerModuleThreshold = iConfig.getParameter<std::vector<unsigned int> >("numberOfHitPerModuleThreshold");
00075
00076
00077 theBranchonfirstlayer=true;
00078 theCarriedIPatfirstlayer=false;
00079 theCarriedIPatfirstlayerModule =true;
00080
00081
00082 theMinNumberOfHitOnCandidate = iConfig.getParameter<unsigned int>("minNumberOfHitOnCandidate");
00083
00084
00085 theOutputAllTraj = iConfig.getParameter<bool>("outputAllTraj");
00086
00087 if (!theSmoother)
00088 theSmoother = new KFTrajectorySmoother(thePropagator,theUpdator,theRoadEstimator);
00089 }
00090
00091
00092 MuonRoadTrajectoryBuilder::~MuonRoadTrajectoryBuilder()
00093 {
00094 edm::LogInfo(theCategory)<<"cleaning the object";
00095 if (theRoadEstimator) delete theRoadEstimator;
00096 if (theHitEstimator) delete theHitEstimator;
00097 if (theUpdator) delete theUpdator;
00098 if (theSmoother) delete theSmoother;
00099 }
00100
00101 void MuonRoadTrajectoryBuilder::setEvent(const edm::Event & iEvent) const {
00102 theMeasurementTracker->update(iEvent);
00103 }
00104
00105
00106
00107
00108 bool trajectoryOrder(const MuonRoadTrajectoryBuilder::trajectory & traj1, const MuonRoadTrajectoryBuilder::trajectory & traj2)
00109 {
00110
00111 unsigned int s1=traj1.measurements.size();
00112 unsigned int s2=traj2.measurements.size();
00113 if (s1>s2) return true;
00114 else {
00115 if (s1==s2) return (traj1.chi2<traj2.chi2);
00116 else return false; }}
00117
00118
00119 void MuonRoadTrajectoryBuilder::trajectories(const TrajectorySeed & seed, TrajectoryContainer &ret) const
00120 {
00121 LogDebug(theCategory)<<"makeTrajectories START";
00122
00123 makeTrajectories(seed,ret);
00124 }
00125
00126
00127 std::vector<Trajectory> MuonRoadTrajectoryBuilder::trajectories(const TrajectorySeed & seed) const
00128 {
00129 LogDebug(theCategory)<<"makeTrajectories START";
00130
00131
00132 std::vector<Trajectory> result;
00133
00134
00135 makeTrajectories(seed,result);
00136
00137
00138 return result;
00139 }
00140
00141
00142
00143 void MuonRoadTrajectoryBuilder::makeTrajectories(const TrajectorySeed & seed, std::vector<Trajectory> & result,int version) const
00144 { if (version==0) { makeTrajectories_0(seed,result);}
00145 else if (version==1) { makeTrajectories_1(seed,result);}}
00146
00147
00148
00149
00150 void MuonRoadTrajectoryBuilder::makeTrajectories_0(const TrajectorySeed & seed, std::vector<Trajectory> & result) const
00151 {
00152 Trajectory basicTrajectory(seed,alongMomentum);
00153
00154
00155
00156
00157 PTrajectoryStateOnDet PTstart=seed.startingState();
00158 DetId detId(PTstart.detId());
00159 const BoundPlane * surface =(&theMeasurementTracker->geomTracker()->idToDet(detId)->surface());
00160
00161 TrajectoryStateOnSurface TSOS = theTransformer.transientState(PTstart,surface,theField);
00162 if (!TSOS.isValid()){ edm::LogError(theCategory)<<"TSOS from PTSOD is not valid.";return ;}
00163
00164 LogDebug(theCategory) <<"(detId.rawId()) "<<(detId.rawId())<<"(detId.subdetId()) "<<(detId.subdetId())
00165 <<"(TSOS.globalPosition()) "<<(TSOS.globalPosition())
00166 <<"(TSOS.globalMomentum()) "<<(TSOS.globalMomentum());
00167
00168
00169
00170
00171
00172 theFirstlayer=true;
00173 theNumberOfHitPerModule = theNumberOfHitPerModuleDefault;
00174
00175 int Nhits=0;
00176 GlobalPoint position;
00177 double z=0,r=0;
00178
00179 TrajectoryCollectionFPair Trajectories;
00180
00181 Trajectories.head().push_back(trajectory());
00182 trajectory & initial = *Trajectories.head().rbegin();
00183 initial.TSOS=TSOS;
00184 initial.traj=basicTrajectory;
00185
00186
00187
00188
00189 std::vector<BarrelDetLayer*> tiblc = theMeasurementTracker->geometricSearchTracker()->tibLayers();
00190 std::vector<BarrelDetLayer*> toblc = theMeasurementTracker->geometricSearchTracker()->tobLayers();
00191 std::vector<ForwardDetLayer*> tidlc[2];
00192 tidlc[0]=theMeasurementTracker->geometricSearchTracker()->negTidLayers();
00193 tidlc[1]=theMeasurementTracker->geometricSearchTracker()->posTidLayers();
00194 std::vector<ForwardDetLayer*> teclc[2];
00195 teclc[0]=theMeasurementTracker->geometricSearchTracker()->negTecLayers();
00196 teclc[1]=theMeasurementTracker->geometricSearchTracker()->posTecLayers();
00197 const int Ntib=tiblc.size();
00198 const int Ntob=toblc.size();
00199 const int Ntid=tidlc[0].size();
00200
00201
00202 const int Ntec=teclc[0].size();
00203
00204 LogDebug(theCategory)<<"(Ntib) "<<(Ntib)<<"(Ntob) "<<(Ntob)<<"(Ntid) "<<(Ntid)<<"(Ntec) "<<(Ntec);
00205
00206 const SimpleDiskBounds * sdbounds=0;
00207
00208 position = TSOS.globalPosition();
00209 z = position.z();
00210 r = position.perp();
00211
00212
00213 enum PART { fault , PXB, PXF, TIB , TID , TOB , TEC};
00214 PART whichpart = fault;
00215 switch(detId.subdetId()){
00216 case 1: {whichpart=PXB;break;}
00217 case 2: {whichpart=PXF;break;}
00218
00219 case 3: {whichpart=TIB;break;}
00220 case 4: {whichpart=TID;break;}
00221 case 5: {whichpart=TOB;break;}
00222 case 6: {whichpart=TEC;break;}}
00223
00224 bool inapart=true;
00225 bool firstRound =true;
00226 int indexinpart=0;
00227
00228 while(inapart){
00229
00230
00231 if (!checkStep(Trajectories.head())) break;
00232
00233
00234 switch (whichpart){
00235
00236 case fault: {edm::LogError(theCategory)<<"something's wrong with the seed";return;}
00237 case PXB: {edm::LogError(theCategory)<<"PXB no yet implemented";return;}
00238 case PXF: {edm::LogError(theCategory)<<"PXF no yet implemented";return;}
00239
00240
00241 case TIB:{
00242 if (indexinpart==Ntib){whichpart = TOB; indexinpart=-1;break; }
00243
00244 LogDebug(theCategory)<<"within TIB "<<indexinpart+1;
00245
00246
00247 if (!firstRound) TSOS = thePropagator->propagate(*TSOS.freeState(),tiblc[indexinpart]->surface());
00248 if (!TSOS.isValid()) {;break;}
00249
00250 z=TSOS.globalPosition().z();
00251
00252
00253 if (fabs(z) > fabs(tidlc[(z>0)][0]->surface().position().z()))
00254 {
00255 LogDebug(theCategory)<<"|z| ("<<z<<") bigger than the TID min z("<<tidlc[(z>0)][0]->surface().position().z()<<"): go to TID";
00256 whichpart = TID; indexinpart=-1; break;}
00257 else { Nhits+=GatherHits(TSOS,tiblc[indexinpart],Trajectories);}
00258 break;}
00259
00260
00261 case TID: {
00262 if (indexinpart==Ntid){ whichpart = TEC; indexinpart=-1; break;}
00263
00264 LogDebug(theCategory)<<"within TID "<<indexinpart+1;
00265
00266
00267 if (!firstRound) TSOS = thePropagator->propagate(*TSOS.freeState(),tidlc[(z>0)][indexinpart]->surface());
00268 if (!TSOS.isValid()){break;}
00269
00270 position = TSOS.globalPosition();
00271 z = position.z();
00272 r = position.perp();
00273
00274 sdbounds = dynamic_cast<const SimpleDiskBounds *>(&tidlc[(z>0)][indexinpart]->surface().bounds());
00275 if (!sdbounds){edm::LogError(theCategory)<<" detlayer bounds are not SimpleDiskBounds in tid geometry";return;}
00276
00277
00278 if (r < sdbounds->innerRadius())
00279 {
00280 LogDebug(theCategory)<<"radius ("<<r<<") smaller than the TID disk inner radius ("<<sdbounds->innerRadius()<<"): next disk please";
00281 break;}
00282 else if (r >sdbounds->outerRadius())
00283 {
00284 LogDebug(theCategory)<<"radius ("<<r<<") bigger than the TID disk outer radius("<<sdbounds->outerRadius()<<"): go to TOB";
00285 whichpart = TOB; indexinpart=-1;break;}
00286 else {
00287 LogDebug(theCategory)<<"collecting hits";
00288 Nhits+=GatherHits(TSOS,tidlc[(z>0)][indexinpart],Trajectories);}
00289 break;}
00290
00291
00292 case TOB: {
00293 if (indexinpart==Ntob){ inapart=false;break;}
00294
00295 LogDebug(theCategory)<<"within TOB "<<indexinpart+1;
00296
00297
00298 if (!firstRound) TSOS = thePropagator->propagate(*TSOS.freeState(),toblc[indexinpart]->surface());
00299 if (!TSOS.isValid()) {break;}
00300
00301 z = TSOS.globalPosition().z();
00302
00303
00304 if (fabs(z) > fabs(teclc[(z>0)][0]->surface().position().z()))
00305 {
00306 LogDebug(theCategory)<<"|z| ("<<z<<") bigger than the TOB layer max z ("<< teclc[(z>0)][0]->surface().position().z()<<"): go to TEC";
00307 whichpart = TEC; indexinpart=-1;break;}
00308 else {Nhits+=GatherHits(TSOS,toblc[indexinpart],Trajectories);}
00309 break;}
00310
00311
00312 case TEC: {
00313 if (indexinpart==Ntec){inapart=false;break;}
00314
00315 LogDebug(theCategory)<<"within TEC "<<indexinpart+1;
00316
00317
00318 if (!firstRound) TSOS = thePropagator->propagate(*TSOS.freeState(),teclc[(z>0)][indexinpart]->surface());
00319 if (!TSOS.isValid()) {break;}
00320
00321 position = TSOS.globalPosition();
00322 z = position.z();
00323 r = position.perp();
00324
00325 sdbounds = dynamic_cast<const SimpleDiskBounds *>(&teclc[(z>0)][indexinpart]->surface().bounds());
00326 if (!sdbounds) {edm::LogError(theCategory)<<" detlayer bounds are not SimpleDiskBounds in tec geometry";return;}
00327
00328
00329 if (r < sdbounds->innerRadius())
00330 {
00331 LogDebug(theCategory)<<"radius ("<<r<<") smaller than the TEC disk inner radius ("<<sdbounds->innerRadius()<<"): next disk please";
00332 break;}
00333 else if (r > sdbounds->outerRadius())
00334 {
00335 LogDebug(theCategory)<<"radius ("<<r<<") bigger than the TEC disk outer radius ("<<sdbounds->outerRadius()<<"): I can stop here";
00336 inapart=false;break;}
00337 else {Nhits+=GatherHits(TSOS,teclc[(z>0)][indexinpart],Trajectories);}
00338
00339 break;}
00340
00341 }
00342 indexinpart++;
00343 firstRound=false;
00344 }
00345
00346
00347 LogDebug(theCategory)<<"propagating through layers is done";
00348
00349
00350
00351
00352 edm::LogInfo(theCategory)<<"found: "
00353 <<Nhits<<" hits in the road for this seed \n"
00354 << Trajectories.head().size()<<" possible trajectory(ies)";
00355
00356 if (Trajectories.head().size() == 0) {edm::LogError(theCategory)<<" no possible trajectory found"; return;}
00357
00358
00359 Trajectories.head().sort(trajectoryOrder);
00360
00361
00362 if (theOutputAllTraj) {
00363
00364
00365 for (TrajectoryCollection::iterator tit = Trajectories.head().begin(); tit!=Trajectories.head().end();tit++)
00366 {if (tit->measurements.size()>= theMinNumberOfHitOnCandidate){result.push_back(smooth(tit->traj));}}
00367 }
00368 else{
00369
00370 trajectory & best = (*Trajectories.head().begin());
00371 if (best.measurements.size()< theMinNumberOfHitOnCandidate){edm::LogError(theCategory)<<"best trajectory does not have enough ("<<best.measurements.size()<<") hits on it (<"<<theMinNumberOfHitOnCandidate<<")"; return;}
00372
00373 result.push_back(smooth(best.traj));}
00374
00375 edm::LogInfo(theCategory)<<result.size()<<" trajectory(ies) output";
00376 }
00377
00378
00379 bool trajectorymeasurementOrder(const TrajectoryMeasurement & meas_1 ,const TrajectoryMeasurement & meas_2 )
00380 {
00381
00382 GlobalVector d= (meas_2.predictedState().globalPosition() - meas_1.predictedState().globalPosition()).unit();
00383
00384 GlobalVector u1= meas_1.predictedState().globalDirection().unit();
00385 GlobalVector u2= meas_2.predictedState().globalDirection().unit();
00386 GlobalVector u =(u1+u2)/2.;
00387 return d.dot(u) > 0;
00388 }
00389 bool trajectorymeasurementInverseOrder(const TrajectoryMeasurement & meas_1 ,const TrajectoryMeasurement & meas_2 )
00390 {return trajectorymeasurementOrder(meas_2,meas_1);}
00391
00392
00393
00394 void MuonRoadTrajectoryBuilder::cleanTrajectory(Trajectory & traj) const {
00395
00396 Trajectory::DataContainer meas =traj.measurements();
00397
00398 const DetLayer* lastDetLayer =0;
00399 Trajectory::DataContainer::iterator mit = meas.begin();
00400 while (mit!=meas.end()){
00401 {
00402 const DetLayer * detLayer = theMeasurementTracker->geometricSearchTracker()->detLayer(mit->recHit()->det()->geographicalId());
00403 LogDebug(theCategory)<<"(mit->recHit()->det()->geographicalId().rawId()) "<<(mit->recHit()->det()->geographicalId().rawId())
00404 <<"(detLayer) "<<(detLayer)<<"(lastDetLayer) "<<(lastDetLayer);
00405
00406 if (detLayer==lastDetLayer)
00407 {
00408 mit=meas.erase(mit);
00409 }
00410 else {mit++;}
00411 lastDetLayer=detLayer;
00412 }
00413 Trajectory newTraj(traj.seed(),traj.direction());
00414 for (Trajectory::DataContainer::iterator mit=meas.begin();mit!=meas.end();++mit)
00415 {newTraj.push(*mit);}
00416 traj=newTraj;
00417 }
00418 }
00419
00420
00421 void sortTrajectoryMeasurements(Trajectory & traj){
00422 Trajectory::DataContainer meas =traj.measurements();
00423
00424
00425
00426 if (traj.direction() == oppositeToMomentum)
00427 {std::sort(meas.begin(),meas.end(),trajectorymeasurementInverseOrder);}
00428 else
00429 {std::sort(meas.begin(),meas.end(),trajectorymeasurementOrder);}
00430
00431
00432 Trajectory newTraj(traj.seed(),traj.direction());
00433 for (Trajectory::DataContainer::iterator mit=meas.begin();mit!=meas.end();++mit)
00434 {newTraj.push(*mit);}
00435
00436
00437 traj = newTraj;
00438 }
00439
00440 Trajectory MuonRoadTrajectoryBuilder::smooth(Trajectory & traj) const {
00441
00442
00443 sortTrajectoryMeasurements(traj);
00444
00445 std::vector<Trajectory> ret=theSmoother->trajectories(traj);
00446
00447 if (ret.empty()){
00448 edm::LogError(theCategory)<<"smoother returns an empty vector of trajectories: try cleaning first and resmooth";
00449 cleanTrajectory(traj);
00450 ret=theSmoother->trajectories(traj);
00451 }
00452
00453 if (ret.empty()){edm::LogError(theCategory)<<"smoother returns an empty vector of trajectories.";
00454 return traj;}
00455 else{return (ret.front());}
00456 }
00457
00458
00459 int MuonRoadTrajectoryBuilder::GatherHits( const TrajectoryStateOnSurface & step,const DetLayer * thislayer , TrajectoryCollectionFPair & Trajectories) const
00460 {
00461 TrajectoryStateOnSurface restep;
00462 bool atleastoneadded=false;
00463 int Nhits=0;
00464
00465
00466 std::vector<DetLayer::DetWithState> compatible =thislayer->compatibleDets( step, *thePropagator , *theRoadEstimator);
00467
00468
00469 for (std::vector< DetLayer::DetWithState > ::iterator dws = compatible.begin();dws != compatible.end();dws++)
00470 {
00471 const DetId presentdetid = dws->first->geographicalId();
00472 restep = dws->second;
00473
00474
00475 LogDebug(theCategory)<<((dws->first->components ().size()!=0) ? "double sided layer":"single sided layer")
00476 <<"(presentdetid.rawId()) "<<(presentdetid.rawId());
00477
00478
00479 TransientTrackingRecHit::ConstRecHitContainer thoseHits = theMeasurementTracker->idToDet(presentdetid)->recHits(restep);
00480 int additionalHits =0;
00481
00482 LogDebug(theCategory)<<"(thoseHits.size()) "<<(thoseHits.size());
00483
00484 if (thoseHits.size()>theNumberOfHitPerModule)
00485 { edm::LogInfo(theCategory)<<"more than "<<theNumberOfHitPerModule
00486 <<" compatible hits ("<<thoseHits.size()<<")on module "<<presentdetid.rawId()
00487 <<", skip it";continue; }
00488
00489
00490 for (TransientTrackingRecHit::ConstRecHitContainer::const_iterator iTThit = thoseHits.begin();iTThit != thoseHits.end(); iTThit++)
00491 {
00492 if (!(*iTThit)->isValid()){edm::LogInfo(theCategory)<<"rec hit not valid on module "<<presentdetid.rawId() <<". I skip it"; continue;}
00493
00494 LogDebug(theCategory)<<((dynamic_cast<const SiStripMatchedRecHit2D *>((*iTThit)->hit())!=0) ? "matched rechit" : " r-phi rechit");
00495
00496
00497 const BoundPlane & surface = (*iTThit)->det()->surface();
00498
00499
00500 MeasurementEstimator::HitReturnType est_road = theRoadEstimator->estimate(restep,**iTThit);
00501
00502 LogDebug(theCategory)<<"(restep.globalPosition().perp()) "<<(restep.globalPosition().perp())<<"(restep.globalPosition().mag()) "<<(restep.globalPosition().mag())
00503 <<"road step parameters at module: \n"<<restep
00504 << "(est_road.first) "<<(est_road.first)<<"(est_road.second) "<<(est_road.second);
00505
00506
00507 if (est_road.first)
00508 {
00509 Nhits++;
00510 additionalHits++;
00511 atleastoneadded=true;
00512
00513 LogDebug(theCategory)<<"hit is consistent with road"<<"(presentdetid.rawId()) "<<(presentdetid.rawId())
00514 <<"loop over previous trajectories\n"
00515 <<"(Trajectories.tail().size()) "<<(Trajectories.tail().size())<<"(Trajectories.head().size()) "<<(Trajectories.head().size());
00516
00517
00518
00519 for ( TrajectoryCollection::iterator traj =Trajectories.head().begin();traj != Trajectories.head().end(); traj++)
00520 {
00521
00522 const TrajectoryStateOnSurface & previousState = traj->TSOS;
00523 if (!previousState.isValid())
00524 {edm::LogError(theCategory)<<"previous free state is invalid at trajectory update, this is WRONG"; continue;}
00525 const FreeTrajectoryState & previousFreestate = *previousState.freeState();
00526
00527
00528 TrajectoryStateOnSurface predictedState = thePropagator->propagate(previousFreestate,surface);
00529 if (!predictedState.isValid()){edm::LogError(theCategory)
00530 <<"predicted state is not valid at trajectory update, rechit surface cannot be reached by the previous updated state.";continue;}
00531
00532 MeasurementEstimator::HitReturnType est ;
00533 est= theHitEstimator->estimate(predictedState,**iTThit);
00534
00535 LogDebug(theCategory)<<"(est.first) "<<(est.first)<<"(est.second) "<<(est.second);
00536
00537
00538 if (est.first )
00539 {
00540
00541 const TrajectoryStateOnSurface & updatedState = theUpdator->update(predictedState,**iTThit);
00542 if (!updatedState.isValid()){edm::LogError(theCategory)<<"updated state is not valid, this is really wrong";continue;}
00543
00544 LogDebug(theCategory)<<"updating a previous state with a rechit";
00545
00546
00547 Trajectories.tail().push_back(*traj);
00548 trajectory & combined = (*Trajectories.tail().rbegin());
00549 combined.duplicate =false;
00550
00551
00552 combined.chi2 += est_road.second;
00553
00554 combined.lastmissed=false;
00555 combined.missedinarow=0;
00556
00557 combined.measurements.push_back(TrajectoryMeasurement(updatedState,*iTThit));
00558 TrajectoryMeasurement & trajMeasurement = (*combined.measurements.rbegin());
00559
00560 combined.TSOS = updatedState;
00561
00562 combined.traj.push(trajMeasurement,est.second);
00563
00564 LogDebug(theCategory)<<"(combined.traj.foundHits()) "<<(combined.traj.foundHits())
00565 <<"muon measurement on previous module: \n"<<traj->TSOS
00566 <<"muon measurement before update: \n"<<predictedState
00567 <<"muon measurement after update: \n"<<updatedState;
00568
00569 }
00570 else
00571 {
00572 LogDebug(theCategory)<<"hit failed chi2 test for trajectories update\n"<<"(traj->duplicate) "<<(traj->duplicate);
00573
00574 if (!traj->duplicate){
00575 Trajectories.tail().push_back(*traj);
00576 trajectory & copied = (*Trajectories.tail().rbegin());
00577 copied.missed++;
00578 copied.lastmissed=true;
00579 copied.missedinarow++;
00580 traj->duplicate =true;
00581 }
00582 }
00583 }
00584 }
00585 }
00586
00587
00588
00589
00590 if (Trajectories.tail().size()!=0)
00591 {
00592
00593
00594 if (!theFirstlayer || theBranchonfirstlayer)
00595 {
00596 LogDebug(theCategory)<<"swapping trajectory list index";
00597
00598
00599 if (theFirstlayer && theCarriedIPatfirstlayerModule)
00600 {
00601 LogDebug(theCategory)<<"push front <IP> to next list of trajectories";
00602
00603 Trajectories.tail().push_front(*Trajectories.head().begin());
00604 trajectory & pushed = *Trajectories.tail().begin();
00605 pushed.missed+=additionalHits;
00606 pushed.lastmissed = ( additionalHits!=0);
00607 pushed.missedinarow++;
00608 }
00609
00610
00611
00612 Trajectories.head().clear();
00613
00614
00615 Trajectories.flip();
00616 }
00617 }
00618 }
00619
00620
00621
00622
00623 if(theFirstlayer && atleastoneadded )
00624 {
00625 theFirstlayer =false;
00626 if (!theBranchonfirstlayer)
00627 {
00628 LogDebug(theCategory)<<"swapping trajectory list index (end of first layer)";
00629
00630
00631
00632 if (theCarriedIPatfirstlayer)
00633 {Trajectories.tail().push_front(*Trajectories.head().begin());}
00634
00635
00636
00637 Trajectories.head().clear();
00638
00639 Trajectories.flip();
00640 }
00641 else
00642 {
00643
00644
00645
00646 if (!theCarriedIPatfirstlayer && theCarriedIPatfirstlayerModule){
00647
00648 LogDebug(theCategory)<<"pop up <IP> from trajectories";
00649
00650 Trajectories.head().pop_front(); }
00651 }
00652
00653
00654
00655
00656 if (Trajectories.head().size()>=2)
00657 {checkDuplicate(Trajectories.head());}
00658
00659 }
00660 return Nhits;
00661
00662 }
00663
00664
00665 bool MuonRoadTrajectoryBuilder::checkStep(TrajectoryCollection & collection) const
00666 {
00667
00668 if (theDynamicMaxNumberOfHitPerModule) {
00669 for (unsigned int vit = 0; vit!= theMaxTrajectoriesThreshold.size() ; vit++){
00670 if (collection.size() >theMaxTrajectoriesThreshold[vit]){
00671 theNumberOfHitPerModule= theNumberOfHitPerModuleThreshold[vit];}
00672 else
00673 break;}}
00674
00675
00676 if ( collection.size() > theMaxTrajectories) {
00677
00678 collection.sort(trajectoryOrder);
00679 unsigned int prevSize=collection.size();
00680 collection.resize(theMaxTrajectories);
00681 edm::LogInfo(theCategory)
00682 <<" too many possible trajectories ("<<prevSize
00683 <<"), reduce the possibilities to "<<theMaxTrajectories<<" bests.";
00684 }
00685 return true;
00686 }
00687
00688 void MuonRoadTrajectoryBuilder::checkDuplicate(TrajectoryCollection & collection) const
00689 {
00690 LogDebug(theCategory)<<"checking for duplicates here. list size: "<<collection.size();
00691
00692
00693 TrajectoryCollection::iterator traj1 = collection.begin();
00694 while(traj1 != collection.end())
00695 {
00696 LogDebug(theCategory)<<"";
00697
00698
00699 TrajectoryCollection::iterator traj2 = traj1;
00700 traj2++;
00701 bool traj1_removed=false;
00702 while( traj2 != collection.end())
00703 {
00704 if (traj2 == traj1 ) continue;
00705
00706
00707 std::list <TrajectoryMeasurement >::reverse_iterator h1 = traj1->measurements.rbegin();
00708 std::list <TrajectoryMeasurement >::reverse_iterator h2 = traj2->measurements.rbegin();
00709
00710 bool break_different = false;
00711 while (h1 != traj1->measurements.rend() && h2!=traj2->measurements.rend())
00712 {
00713 TransientTrackingRecHit::ConstRecHitPointer hit1 = h1->recHit();
00714 TransientTrackingRecHit::ConstRecHitPointer hit2 = h2->recHit();
00715
00716 LogDebug(theCategory)<<"(hit1->geographicalId().rawId()) "<<(hit1->geographicalId().rawId())<<"(hit1->globalPosition()) "<<(hit1->globalPosition())
00717 <<"(hit2->geographicalId().rawId()) "<<(hit2->geographicalId().rawId())<<"(hit2->globalPosition()) "<<(hit2->globalPosition());
00718
00719 if (hit1 == hit2){ h1++;h2++; continue;}
00720 else{break_different =true;
00721
00722 LogDebug(theCategory)<<"list of hits are different";
00723
00724 break;}
00725 }
00726 if (!break_different)
00727
00728
00729 {
00730 LogDebug(theCategory)<<"list of hits are identical/subset. remove one of them.";
00731
00732
00733
00734 if (h1 != traj1->measurements.rend())
00735 {
00736 LogDebug(theCategory)<<"I removed traj2";
00737
00738 traj2=collection.erase(traj2);
00739 }
00740 else
00741 {
00742 LogDebug(theCategory)<<"I removed traj1. and decrement traj2";
00743
00744 traj1=collection.erase(traj1);
00745
00746 traj1_removed=true;
00747 break;
00748 }
00749 }
00750 else
00751 {traj2++; }
00752 }
00753 if (!traj1_removed)
00754 {
00755 traj1++;}
00756 }
00757 }
00758
00759
00760
00761
00762 void MuonRoadTrajectoryBuilder::makeTrajectories_1(const TrajectorySeed & seed, std::vector<Trajectory> & result) const
00763 {
00764 Trajectory basicTrajectory(seed,alongMomentum);
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780 }
00781