00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "DataFormats/EgammaCandidates/interface/SiStripElectronFwd.h"
00018 #include "RecoEgamma/EgammaElectronAlgos/interface/SiStripElectronAlgo.h"
00019 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00020
00021
00022 #include "DataFormats/TrajectorySeed/interface/PropagationDirection.h"
00023 #include "RecoTracker/TrackProducer/interface/TrackingRecHitLessFromGlobalPosition.h"
00024
00025 #include "DataFormats/TrackerCommon/interface/TrackerTopology.h"
00026 #include "Geometry/Records/interface/IdealGeometryRecord.h"
00027 #include "DataFormats/SiStripDetId/interface/StripSubdetector.h"
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 namespace {
00038 struct CompareHits {
00039 CompareHits( const TrackingRecHitLessFromGlobalPosition& iLess ) :
00040 less_(iLess) {}
00041 bool operator()(const TrackingRecHit* iLHS, const TrackingRecHit* iRHS) {
00042 return less_(*iLHS,*iRHS);
00043 }
00044
00045 TrackingRecHitLessFromGlobalPosition less_;
00046 };
00047 }
00048
00049
00050
00051
00052
00053 SiStripElectronAlgo::SiStripElectronAlgo(unsigned int maxHitsOnDetId,
00054 double originUncertainty,
00055 double phiBandWidth,
00056 double maxNormResid,
00057 unsigned int minHits,
00058 double maxReducedChi2)
00059 : maxHitsOnDetId_(maxHitsOnDetId)
00060 , originUncertainty_(originUncertainty)
00061 , phiBandWidth_(phiBandWidth)
00062 , maxNormResid_(maxNormResid)
00063 , minHits_(minHits)
00064 , maxReducedChi2_(maxReducedChi2)
00065 {
00066 }
00067
00068
00069
00070
00071
00072
00073 SiStripElectronAlgo::~SiStripElectronAlgo()
00074 {
00075 }
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 void SiStripElectronAlgo::prepareEvent(const edm::ESHandle<TrackerGeometry>& tracker,
00094 const edm::Handle<SiStripRecHit2DCollection>& rphiHits,
00095 const edm::Handle<SiStripRecHit2DCollection>& stereoHits,
00096 const edm::Handle<SiStripMatchedRecHit2DCollection>& matchedHits,
00097 const edm::ESHandle<MagneticField>& magneticField)
00098 {
00099 LogDebug("") << " In prepareEvent " ;
00100
00101 tracker_p_ = tracker.product();
00102 rphiHits_p_ = rphiHits.product();
00103 stereoHits_p_ = stereoHits.product();
00104 matchedHits_p_ = matchedHits.product();
00105 magneticField_p_ = magneticField.product();
00106
00107 rphiHits_hp_ = &rphiHits;
00108 stereoHits_hp_ = &stereoHits;
00109
00110
00111 rphiKey_.clear();
00112 stereoKey_.clear();
00113
00114 hitUsed_.clear();
00115 matchedHitUsed_.clear();
00116
00117 unsigned int counter = 0;
00118 for (SiStripRecHit2DCollection::DataContainer::const_iterator it = rphiHits_p_->data().begin(); it != rphiHits_p_->data().end(); ++it) {
00119 rphiKey_[&(*it)] = counter;
00120 hitUsed_[&(*it)] = false;
00121 counter++;
00122 }
00123
00124 counter = 0;
00125 for (SiStripRecHit2DCollection::DataContainer::const_iterator it = stereoHits_p_->data().begin(); it != stereoHits_p_->data().end(); ++it) {
00126 stereoKey_[&(*it)] = counter;
00127 hitUsed_[&(*it)] = false;
00128 counter++;
00129 }
00130
00131 counter = 0;
00132 for (SiStripMatchedRecHit2DCollection::DataContainer::const_iterator it = matchedHits_p_->data().begin(); it != matchedHits_p_->data().end(); ++it) {
00133 matchedKey_[&(*it)] = counter;
00134 matchedHitUsed_[&(*it)] = false;
00135 counter++;
00136 }
00137
00138 LogDebug("") << " Leaving prepareEvent " ;
00139 }
00140
00141
00142
00143
00144
00145 bool SiStripElectronAlgo::findElectron(reco::SiStripElectronCollection& electronOut,
00146 TrackCandidateCollection& trackCandidateOut,
00147 const reco::SuperClusterRef& superclusterIn,
00148 const TrackerTopology *tTopo)
00149 {
00150
00151 bool electronSuccess = projectPhiBand(-1., superclusterIn, tTopo);
00152 bool positronSuccess = projectPhiBand( 1., superclusterIn, tTopo);
00153
00154
00155 if ((electronSuccess && !positronSuccess) ||
00156 (electronSuccess && positronSuccess && redchi2_neg_ <= redchi2_pos_)) {
00157
00158
00159 AlgebraicSymMatrix55 errors;
00160 errors(0,0) = 3.;
00161 errors(1,1) = 0.01;
00162 errors(2,2) = 0.0001;
00163 errors(3,3) = 0.01;
00164 errors(4,4) = 0.01;
00165
00166 #ifdef EDM_ML_DEBUG
00167
00168 std::ostringstream debugstr6;
00169 debugstr6 << " HERE BEFORE SORT electron case " << " \n" ;
00170 for (std::vector<const TrackingRecHit*>::iterator itHit=outputHits_neg_.begin();
00171 itHit != outputHits_neg_.end(); ++itHit) {
00172 debugstr6 <<" HIT "<<((*itHit)->geographicalId()).rawId()<<" \n"
00173 <<" Local Position: "<<(*itHit)->localPosition()<<" \n"
00174 <<" Global Rho: "
00175 <<(((TrackingGeometry*)(tracker_p_))->idToDet((*itHit)->geographicalId())->surface().toGlobal((*itHit)->localPosition()).perp())
00176 <<" Phi "
00177 <<(((TrackingGeometry*)(tracker_p_))->idToDet((*itHit)->geographicalId())->surface().toGlobal((*itHit)->localPosition()).phi())
00178 << " Z "
00179 <<(((TrackingGeometry*)(tracker_p_))->idToDet((*itHit)->geographicalId())->surface().toGlobal((*itHit)->localPosition()).z())<< " \n";
00180 }
00181
00182
00183
00184
00185
00186 debugstr6 << " Calling sort alongMomentum " << " \n";
00187 #endif
00188
00189 std::sort(outputHits_neg_.begin(), outputHits_neg_.end(),
00190 CompareHits(TrackingRecHitLessFromGlobalPosition(((TrackingGeometry*)(tracker_p_)), alongMomentum)));
00191
00192 #ifdef EDM_ML_DEBUG
00193 debugstr6 << " Done with sort " << " \n";
00194
00195 debugstr6 << " HERE AFTER SORT electron case " << " \n";
00196 for (std::vector<const TrackingRecHit*>::iterator itHit=outputHits_neg_.begin();
00197 itHit != outputHits_neg_.end(); ++itHit) {
00198 debugstr6 <<" HIT "<<((*itHit)->geographicalId()).rawId()<<" \n"
00199 <<" Local Position: "<<(*itHit)->localPosition()<<" \n"
00200 <<" Global Rho: "
00201 <<(((TrackingGeometry*)(tracker_p_))->idToDet((*itHit)->geographicalId())->surface().toGlobal((*itHit)->localPosition()).perp())
00202 <<" Phi "
00203 <<(((TrackingGeometry*)(tracker_p_))->idToDet((*itHit)->geographicalId())->surface().toGlobal((*itHit)->localPosition()).phi())
00204 << " Z "
00205 <<(((TrackingGeometry*)(tracker_p_))->idToDet((*itHit)->geographicalId())->surface().toGlobal((*itHit)->localPosition()).z())<< " \n";;
00206 }
00207
00208
00209 LogDebug("")<< debugstr6.str();
00210 #endif
00211
00212
00213 edm::OwnVector<TrackingRecHit> hits;
00214 for(std::vector<const TrackingRecHit*>::iterator itHit =outputHits_neg_.begin();
00215 itHit != outputHits_neg_.end();
00216 ++itHit) {
00217 hits.push_back( (*itHit)->clone());
00218 if( !(hitUsed_.find(*itHit) != hitUsed_.end()) ) {
00219 LogDebug("") << " Assert failure " ;
00220 assert(hitUsed_.find(*itHit) != hitUsed_.end());
00221 }
00222 hitUsed_[*itHit] = true;
00223 }
00224
00225 TrajectoryStateOnSurface state(
00226 GlobalTrajectoryParameters(position_neg_, momentum_neg_, -1, magneticField_p_),
00227 CurvilinearTrajectoryError(errors),
00228 tracker_p_->idToDet(innerhit_neg_->geographicalId())->surface());
00229
00230
00231 PTrajectoryStateOnDet const & PTraj = trajectoryStateTransform::persistentState(state, innerhit_neg_->geographicalId().rawId());
00232 TrajectorySeed trajectorySeed(PTraj, hits, alongMomentum);
00233 trackCandidateOut.push_back(TrackCandidate(hits, trajectorySeed, PTraj));
00234
00235 electronOut.push_back(reco::SiStripElectron(superclusterIn,
00236 -1,
00237 outputRphiHits_neg_,
00238 outputStereoHits_neg_,
00239 phiVsRSlope_neg_,
00240 slope_neg_,
00241 intercept_neg_ + superclusterIn->position().phi(),
00242 chi2_neg_,
00243 ndof_neg_,
00244 correct_pT_neg_,
00245 pZ_neg_,
00246 zVsRSlope_neg_,
00247 numberOfStereoHits_neg_,
00248 numberOfBarrelRphiHits_neg_,
00249 numberOfEndcapZphiHits_neg_));
00250
00251 return true;
00252 }
00253
00254
00255 if ((!electronSuccess && positronSuccess) ||
00256 (electronSuccess && positronSuccess && redchi2_neg_ > redchi2_pos_)) {
00257
00258
00259 AlgebraicSymMatrix55 errors;
00260 errors(0,0) = 3.;
00261 errors(1,1) = 0.01;
00262 errors(2,2) = 0.0001;
00263 errors(3,3) = 0.01;
00264 errors(4,4) = 0.01;
00265
00266 #ifdef EDM_ML_DEBUG
00267
00268 std::ostringstream debugstr7;
00269 debugstr7 << " HERE BEFORE SORT Positron case " << " \n";
00270 for (std::vector<const TrackingRecHit*>::iterator itHit = outputHits_pos_.begin();
00271 itHit != outputHits_pos_.end(); ++itHit) {
00272 debugstr7 <<" HIT "<<((*itHit)->geographicalId()).rawId()<<" \n"
00273 <<" Local Position: "<<(*itHit)->localPosition()<<" \n"
00274 <<" Global Rho: "
00275 <<(((TrackingGeometry*)(tracker_p_))->idToDet((*itHit)->geographicalId())->surface().toGlobal((*itHit)->localPosition()).perp())
00276 <<" Phi "
00277 <<(((TrackingGeometry*)(tracker_p_))->idToDet((*itHit)->geographicalId())->surface().toGlobal((*itHit)->localPosition()).phi())
00278 << " Z "
00279 <<(((TrackingGeometry*)(tracker_p_))->idToDet((*itHit)->geographicalId())->surface().toGlobal((*itHit)->localPosition()).z())<< " \n";
00280 }
00281
00282
00283 debugstr7 << " Calling sort alongMomentum " << " \n";
00284 #endif
00285
00286 std::sort(outputHits_pos_.begin(), outputHits_pos_.end(),
00287 CompareHits(TrackingRecHitLessFromGlobalPosition(((TrackingGeometry*)(tracker_p_)), alongMomentum)));
00288
00289 #ifdef EDM_ML_DEBUG
00290 debugstr7 << " Done with sort " << " \n";
00291
00292
00293 debugstr7 << " HERE AFTER SORT Positron case " << " \n";
00294 for (std::vector<const TrackingRecHit*>::iterator itHit = outputHits_pos_.begin();
00295 itHit != outputHits_pos_.end(); ++itHit) {
00296 debugstr7 <<" HIT "<<((*itHit)->geographicalId()).rawId()<<" \n"
00297 <<" Local Position: "<<(*itHit)->localPosition()<<" \n"
00298 <<" Global Rho: "
00299 <<(((TrackingGeometry*)(tracker_p_))->idToDet((*itHit)->geographicalId())->surface().toGlobal((*itHit)->localPosition()).perp())
00300 <<" Phi "
00301 <<(((TrackingGeometry*)(tracker_p_))->idToDet((*itHit)->geographicalId())->surface().toGlobal((*itHit)->localPosition()).phi())
00302 << " Z "
00303 <<(((TrackingGeometry*)(tracker_p_))->idToDet((*itHit)->geographicalId())->surface().toGlobal((*itHit)->localPosition()).z())<< " \n";
00304 }
00305
00306 LogDebug("") << debugstr7.str();
00307 #endif
00308
00309
00310 edm::OwnVector<TrackingRecHit> hits;
00311 for(std::vector<const TrackingRecHit*>::iterator itHit =outputHits_pos_.begin();
00312 itHit != outputHits_pos_.end();
00313 ++itHit) {
00314 hits.push_back( (*itHit)->clone());
00315 assert(hitUsed_.find(*itHit) != hitUsed_.end());
00316 hitUsed_[*itHit] = true;
00317 }
00318
00319 TrajectoryStateOnSurface state(
00320 GlobalTrajectoryParameters(position_pos_, momentum_pos_, 1, magneticField_p_),
00321 CurvilinearTrajectoryError(errors),
00322 tracker_p_->idToDet(innerhit_pos_->geographicalId())->surface());
00323
00324
00325 PTrajectoryStateOnDet const & PTraj = trajectoryStateTransform::persistentState(state, innerhit_pos_->geographicalId().rawId());
00326 TrajectorySeed trajectorySeed(PTraj, hits, alongMomentum);
00327 trackCandidateOut.push_back(TrackCandidate(hits, trajectorySeed, PTraj));
00328
00329 electronOut.push_back(reco::SiStripElectron(superclusterIn,
00330 1,
00331 outputRphiHits_pos_,
00332 outputStereoHits_pos_,
00333 phiVsRSlope_pos_,
00334 slope_pos_,
00335 intercept_pos_ + superclusterIn->position().phi(),
00336 chi2_pos_,
00337 ndof_pos_,
00338 correct_pT_pos_,
00339 pZ_pos_,
00340 zVsRSlope_pos_,
00341 numberOfStereoHits_pos_,
00342 numberOfBarrelRphiHits_pos_,
00343 numberOfEndcapZphiHits_pos_));
00344
00345 return true;
00346 }
00347
00348 return false;
00349 }
00350
00351
00352
00353
00354
00355 void SiStripElectronAlgo::coarseHitSelection(std::vector<const SiStripRecHit2D*>& hitPointersOut,
00356 const TrackerTopology *tTopo,
00357 bool stereo, bool endcap)
00358 {
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368 SiStripRecHit2DCollection::const_iterator itdet = (stereo ? stereoHits_p_->begin() : rphiHits_p_->begin());
00369 SiStripRecHit2DCollection::const_iterator eddet = (stereo ? stereoHits_p_->end() : rphiHits_p_->end() );
00370 for (; itdet != eddet; ++itdet) {
00371
00372 SiStripRecHit2DCollection::DetSet hits = *itdet;
00373 DetId id(hits.detId());
00374
00375
00376 unsigned int numberOfHits = hits.size();
00377
00378
00379
00380
00381 if (numberOfHits <= maxHitsOnDetId_) {
00382 for (SiStripRecHit2DCollection::DetSet::const_iterator hit = hits.begin();
00383 hit != hits.end(); ++hit) {
00384
00385 if(!(*hit).isValid()) {
00386 LogDebug("") << " InValid hit skipped in coarseHitSelection " << std::endl ;
00387 continue ;
00388 }
00389 std::string theDet = "null";
00390 int theLayer = -999;
00391 bool isStereoDet = false ;
00392 if(tracker_p_->idToDetUnit(hit->geographicalId())->type().subDetector() == GeomDetEnumerators::TIB) {
00393 theDet = "TIB" ;
00394 theLayer = tTopo->tibLayer(id);
00395 if(tTopo->tibStereo(id)==1) { isStereoDet = true ; }
00396 } else if
00397 (tracker_p_->idToDetUnit(hit->geographicalId())->type().subDetector() == GeomDetEnumerators::TOB) {
00398 theDet = "TOB" ;
00399 theLayer = tTopo->tobLayer(id);
00400 if(tTopo->tobStereo(id)==1) { isStereoDet = true ; }
00401 }else if
00402 (tracker_p_->idToDetUnit(hit->geographicalId())->type().subDetector() == GeomDetEnumerators::TID) {
00403 theDet = "TID" ;
00404 theLayer = tTopo->tidWheel(id);
00405 if(tTopo->tidStereo(id)==1) { isStereoDet = true ; }
00406 }else if
00407 (tracker_p_->idToDetUnit(hit->geographicalId())->type().subDetector() == GeomDetEnumerators::TEC) {
00408 theDet = "TEC" ;
00409 theLayer = tTopo->tecWheel(id);
00410 if(tTopo->tecStereo(id)==1) { isStereoDet = true ; }
00411 } else {
00412 LogDebug("") << " UHOH BIG PROBLEM - Unrecognized SI Layer" ;
00413 LogDebug("") << " Det "<< theDet << " Lay " << theLayer ;
00414 assert(1!=1) ;
00415 }
00416
00417 if ((endcap && stereo && (theDet=="TID" || theDet== "TEC") && isStereoDet ) ||
00418 (endcap && !stereo && (theDet=="TID" || theDet== "TEC") && !isStereoDet ) ||
00419 (!endcap && stereo && (theDet=="TIB" || theDet=="TOB") && isStereoDet ) ||
00420 (!endcap && !stereo && (theDet=="TIB" || theDet=="TOB" )&& !isStereoDet )
00421 ) {
00422
00423
00424 hitPointersOut.push_back(&(*hit));
00425
00426 }
00427 }
00428 }
00429 }
00430 }
00431
00432
00433
00434 void SiStripElectronAlgo::coarseMatchedHitSelection(std::vector<const SiStripMatchedRecHit2D*>& coarseMatchedHitPointersOut)
00435 {
00436
00437
00438 SiStripMatchedRecHit2DCollection::const_iterator itdet = matchedHits_p_->begin(), eddet = matchedHits_p_->end();
00439 for (; itdet != eddet; ++itdet) {
00440
00441
00442 SiStripMatchedRecHit2DCollection::DetSet hits = *itdet ;
00443
00444
00445 unsigned int numberOfHits = 0;
00446 for (SiStripMatchedRecHit2DCollection::DetSet::const_iterator hit = hits.begin(); hit != hits.end(); ++hit) {
00447 if ( !((hit->geographicalId()).subdetId() == StripSubdetector::TIB) &&
00448 !( (hit->geographicalId()).subdetId() == StripSubdetector::TOB )) { break;}
00449 numberOfHits++;
00450 if (numberOfHits > maxHitsOnDetId_) { break; }
00451 }
00452
00453
00454 if (numberOfHits <= maxHitsOnDetId_) {
00455 for (SiStripMatchedRecHit2DCollection::DetSet::const_iterator hit = hits.begin(); hit != hits.end(); ++hit) {
00456 if(!(*hit).isValid()) {
00457 LogDebug("") << " InValid hit skipped in coarseMatchedHitSelection " << std::endl ;
00458 continue ;
00459 }
00460 if ( !((hit->geographicalId()).subdetId() == StripSubdetector::TIB) &&
00461 !( (hit->geographicalId()).subdetId() == StripSubdetector::TOB )) { break;}
00462
00463 coarseMatchedHitPointersOut.push_back(&(*hit));
00464 }
00465
00466 }
00467 }
00468
00469
00470 }
00471
00472
00473
00474
00475
00476
00477
00478 bool SiStripElectronAlgo::projectPhiBand(float chargeHypothesis, const reco::SuperClusterRef& superclusterIn,
00479 const TrackerTopology *tTopo)
00480 {
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497 static const double rphiHitSmallestError = 0.0001 ;
00498 static const double stereoHitSmallestError = 0.0001 ;
00499
00500
00501
00502
00503 static const double stereoPitchAngle = 0.100 ;
00504 static const double cos2SiPitchAngle = cos(stereoPitchAngle)*cos(stereoPitchAngle) ;
00505 static const double sin2SiPitchAngle = sin(stereoPitchAngle)*sin(stereoPitchAngle) ;
00506
00507
00508 static const double rphiErrFudge = 0.0200 ;
00509 static const double stereoErrFudge = 0.0200 ;
00510
00511
00512 static const double chi2HitMax = 25.0 ;
00513
00514
00515 static const unsigned int nHitsLeftMinimum = 3 ;
00516
00517
00518 std::vector<const SiStripRecHit2D*> stereoHits;
00519 std::vector<const SiStripRecHit2D*> rphiBarrelHits;
00520 std::vector<const SiStripRecHit2D*> zphiEndcapHits;
00521
00522
00523 coarseHitSelection(stereoHits, tTopo, true, false);
00524
00525
00526
00527
00528
00529 std::ostringstream debugstr1;
00530 debugstr1 << " Getting barrel rphi hits " << " \n" ;
00531
00532 coarseHitSelection(rphiBarrelHits, tTopo, false, false);
00533
00534
00535
00536
00537 debugstr1 << " Getting matched hits " << " \n" ;
00538 std::vector<const SiStripMatchedRecHit2D*> matchedHits;
00539 coarseMatchedHitSelection(matchedHits);
00540
00541
00542
00543 double energy = superclusterIn->energy();
00544 double pT = energy * superclusterIn->position().rho()/sqrt(superclusterIn->x()*superclusterIn->x() +
00545 superclusterIn->y()*superclusterIn->y() +
00546 superclusterIn->z()*superclusterIn->z());
00547
00548 double phiVsRSlope = -3.00e-3 * chargeHypothesis * magneticField_p_->inTesla(GlobalPoint(superclusterIn->x(), superclusterIn->y(), 0.)).z() / pT / 2.;
00549
00550
00551 const double scr = superclusterIn->position().rho();
00552 const double scz = superclusterIn->position().z();
00553
00554
00555 std::vector<bool> uselist;
00556 std::vector<double> rlist, philist, w2list;
00557 std::vector<int> typelist;
00558 std::vector<const SiStripRecHit2D*> hitlist;
00559
00560 std::vector<bool> matcheduselist;
00561 std::vector<const SiStripMatchedRecHit2D*> matchedhitlist;
00562
00563
00564 double zSlopeFitNumer = 0.;
00565 double zSlopeFitDenom = 0.;
00566
00567
00568 debugstr1 << " There are a total of " << stereoHits.size() << " stereoHits in this event " << " \n"
00569 << " There are a total of " << rphiBarrelHits.size() << " rphiBarrelHits in this event " << " \n"
00570 << " There are a total of " << zphiEndcapHits.size() << " zphiEndcapHits in this event " << " \n\n";
00571
00572
00573 LogDebug("") << debugstr1.str() ;
00574
00576
00577
00578
00579
00580
00581 LogDebug("") << " Loop over matched hits " << " \n";
00582
00583 for (std::vector<const SiStripMatchedRecHit2D*>::const_iterator hit = matchedHits.begin() ;
00584 hit != matchedHits.end() ; ++ hit) {
00585
00586 assert(matchedHitUsed_.find(*hit) != matchedHitUsed_.end());
00587
00588 if (!matchedHitUsed_[*hit]) {
00589
00590
00591 GlobalPoint position = tracker_p_->idToDet((*hit)->geographicalId())->surface().toGlobal((*hit)->localPosition());
00592 double r = sqrt(position.x()*position.x() + position.y()*position.y());
00593 double phi = unwrapPhi(position.phi() - superclusterIn->position().phi());
00594 double z = position.z();
00595
00596
00597
00598 if ((-originUncertainty_ + (scz + originUncertainty_)*(r/scr)) < z && z < (originUncertainty_ + (scz - originUncertainty_)*(r/scr))) {
00599
00600
00601 if (unwrapPhi((r-scr)*phiVsRSlope - phiBandWidth_) < phi && phi < unwrapPhi((r-scr)*phiVsRSlope + phiBandWidth_)) {
00602
00603
00604 matcheduselist.push_back(true);
00605 matchedhitlist.push_back(*hit);
00606
00607
00608
00609
00610 zSlopeFitNumer += -(scr - r) * (z - scz);
00611 zSlopeFitDenom += (scr - r) * (scr - r);
00612
00613 }
00614 }
00615 }
00616 }
00617
00618
00619 double zVsRSlope;
00620 if (zSlopeFitDenom > 0.) {
00621 zVsRSlope = zSlopeFitNumer / zSlopeFitDenom;
00622 }
00623 else {
00624
00625 zVsRSlope = scz/scr;
00626 }
00627
00628
00629 LogDebug("") << " Loop over stereo hits" << " \n";
00630
00631
00632 unsigned int numberOfStereoHits = 0;
00633 for (std::vector<const SiStripRecHit2D*>::const_iterator hit = stereoHits.begin(); hit != stereoHits.end(); ++hit) {
00634 assert(hitUsed_.find(*hit) != hitUsed_.end());
00635
00636
00637 GlobalPoint position = tracker_p_->idToDet((*hit)->geographicalId())->surface().toGlobal((*hit)->localPosition());
00638 double r_stereo = sqrt(position.x()*position.x() + position.y()*position.y());
00639 double phi_stereo = unwrapPhi(position.phi() - superclusterIn->position().phi());
00640
00641
00642
00643 double r_stereo_err = sqrt((*hit)->localPositionError().xx()*cos2SiPitchAngle +
00644 (*hit)->localPositionError().yy()*sin2SiPitchAngle ) ;
00645
00646
00647
00648
00649
00650 if(r_stereo_err > stereoHitSmallestError ) {
00651 r_stereo_err = sqrt(r_stereo_err*r_stereo_err+stereoErrFudge*stereoErrFudge);
00652
00653 OmniClusterRef const & stereocluster=(*hit)->omniClusterRef();
00654
00655 bool thisHitIsMatched = false ;
00656
00657 if (!hitUsed_[*hit]) {
00658
00659 unsigned int matcheduselist_size = matcheduselist.size();
00660 for (unsigned int i = 0; i < matcheduselist_size; i++) {
00661 if (matcheduselist[i]) {
00662 OmniClusterRef const & mystereocluster = matchedhitlist[i]->stereoClusterRef();
00663 if( stereocluster == mystereocluster ) {
00664 thisHitIsMatched = true ;
00665
00666
00667 }
00668 }
00669 }
00670
00671 if(thisHitIsMatched) {
00672
00673 uselist.push_back(true);
00674 rlist.push_back(r_stereo);
00675 philist.push_back(phi_stereo);
00676 w2list.push_back(1./(r_stereo_err/r_stereo)/(r_stereo_err/r_stereo));
00677 typelist.push_back(0);
00678 hitlist.push_back(*hit);
00679 }
00680 }
00681
00682 }
00683
00684 }
00685
00686 LogDebug("") << " There are " << uselist.size() << " good hits after stereo loop " ;
00687
00688
00689
00690 LogDebug("") << " Looping over barrel rphi hits " ;
00691 unsigned int rphiMatchedCounter = 0 ;
00692 unsigned int rphiUnMatchedCounter = 0 ;
00693 unsigned int numberOfBarrelRphiHits = 0;
00694 for (std::vector<const SiStripRecHit2D*>::const_iterator hit = rphiBarrelHits.begin(); hit != rphiBarrelHits.end(); ++hit) {
00695 assert(hitUsed_.find(*hit) != hitUsed_.end());
00696
00697 GlobalPoint position = tracker_p_->idToDet((*hit)->geographicalId())->surface().toGlobal((*hit)->localPosition());
00698 double r = sqrt(position.x()*position.x() + position.y()*position.y());
00699 double phi = unwrapPhi(position.phi() - superclusterIn->position().phi());
00700 double z = position.z();
00701 double r_mono_err = sqrt((*hit)->localPositionError().xx()) ;
00702
00703
00704 if( r_mono_err > rphiHitSmallestError) {
00705
00706 r_mono_err=sqrt(r_mono_err*r_mono_err+rphiErrFudge*rphiErrFudge);
00707
00708 OmniClusterRef const & monocluster=(*hit)->omniClusterRef();
00709
00710
00711 if (!hitUsed_[*hit]) {
00712 if( (tracker_p_->idToDetUnit((*hit)->geographicalId())->type().subDetector() == GeomDetEnumerators::TIB &&
00713 (tTopo->tibLayer((*hit)->geographicalId())==1 || tTopo->tibLayer((*hit)->geographicalId())==2)) ||
00714 (tracker_p_->idToDetUnit((*hit)->geographicalId())->type().subDetector() == GeomDetEnumerators::TOB
00715 && (tTopo->tobLayer((*hit)->geographicalId())==1 || tTopo->tobLayer((*hit)->geographicalId())==2)) ) {
00716 bool thisHitIsMatched = false ;
00717 unsigned int matcheduselist_size = matcheduselist.size();
00718 for (unsigned int i = 0; i < matcheduselist_size; i++) {
00719 if (matcheduselist[i]) {
00720 OmniClusterRef const & mymonocluster = matchedhitlist[i]->monoClusterRef();
00721 if( monocluster == mymonocluster ) {
00722 thisHitIsMatched = true ;
00723 }
00724 }
00725 }
00726
00727
00728 if( thisHitIsMatched ) {
00729
00730 uselist.push_back(true);
00731 rlist.push_back(r);
00732 philist.push_back(phi);
00733 w2list.push_back(1./(r_mono_err/r)/(r_mono_err/r));
00734 typelist.push_back(1);
00735 hitlist.push_back(*hit);
00736 rphiMatchedCounter++;
00737 }
00738
00739 } else {
00740
00741
00742
00743 double zFit = zVsRSlope * (r - scr) + scz;
00744
00745
00746
00747 if ((tracker_p_->idToDetUnit((*hit)->geographicalId())->type().subDetector() == GeomDetEnumerators::TIB &&
00748 std::abs(z - zFit) < 12.) ||
00749 (tracker_p_->idToDetUnit((*hit)->geographicalId())->type().subDetector() == GeomDetEnumerators::TOB &&
00750 std::abs(z - zFit) < 20.) ) {
00751
00752
00753 if (unwrapPhi((r-scr)*phiVsRSlope - phiBandWidth_) < phi && phi < unwrapPhi((r-scr)*phiVsRSlope + phiBandWidth_)) {
00754
00755
00756 uselist.push_back(true);
00757 rlist.push_back(r);
00758 philist.push_back(phi);
00759 w2list.push_back(1./(r_mono_err/r)/(r_mono_err/r));
00760 typelist.push_back(1);
00761 hitlist.push_back(*hit);
00762 rphiUnMatchedCounter++;
00763
00764 }
00765 }
00766 }
00767 }
00768 }
00769 }
00770
00771 LogDebug("") << " There are " << rphiMatchedCounter <<" matched rphi hits";
00772 LogDebug("") << " There are " << rphiUnMatchedCounter <<" unmatched rphi hits";
00773 LogDebug("") << " There are " << uselist.size() << " good stereo+rphi hits " ;
00774
00775
00776
00777
00778
00779
00781
00782
00783 LogDebug("") << " Looping over barrel zphi hits " ;
00784
00785
00786 unsigned int numberOfEndcapZphiHits = 0;
00787 for (std::vector<const SiStripRecHit2D*>::const_iterator hit = zphiEndcapHits.begin();
00788 hit != zphiEndcapHits.end(); ++hit) {
00789 assert(hitUsed_.find(*hit) != hitUsed_.end());
00790 if (!hitUsed_[*hit]) {
00791
00792 GlobalPoint position = tracker_p_->idToDet((*hit)->geographicalId())->surface().toGlobal((*hit)->localPosition());
00793 double z = position.z();
00794 double phi = unwrapPhi(position.phi() - superclusterIn->position().phi());
00795
00796
00797
00798 double rFit = (z - scz)/zVsRSlope + scr;
00799
00800
00801
00802
00803
00804
00805 if (rFit > 0. &&
00806 unwrapPhi((rFit-scr)*phiVsRSlope - phiBandWidth_) < phi && phi < unwrapPhi((rFit-scr)*phiVsRSlope + phiBandWidth_)) {
00807
00808
00809 uselist.push_back(true);
00810 rlist.push_back(rFit);
00811 philist.push_back(phi);
00812 w2list.push_back(1./(0.05/rFit)/(0.05/rFit));
00813 typelist.push_back(2);
00814 hitlist.push_back(*hit);
00815
00816 }
00817 }
00818 }
00819
00820 LogDebug("") << " There are " << uselist.size() << " good stereo+rphi+zphi hits " ;
00822
00823 #ifdef EDM_ML_DEBUG
00824 std::ostringstream debugstr5;
00825 debugstr5 << " List of hits before uniqification " << " \n" ;
00826 for (unsigned int i = 0; i < uselist.size(); i++) {
00827 if ( uselist[i] ) {
00828 const SiStripRecHit2D* hit = hitlist[i];
00829 debugstr5 << " DetID " << ((hit)->geographicalId()).rawId()
00830 << " R " << rlist[i]
00831 << " Phi " << philist[i]
00832 << " Weight " << w2list[i]
00833 << " PhiPred " << (rlist[i]-scr)*phiVsRSlope
00834 << " Chi2 " << (philist[i]-(rlist[i]-scr)*phiVsRSlope)*(philist[i]-(rlist[i]-scr)*phiVsRSlope)*w2list[i]
00835 << " \n" ;
00836 }
00837 }
00838 debugstr5 << " \n\n\n" ;
00839
00840 debugstr5 << " Counting number of unique detectors " << " \n" ;
00841
00842 debugstr5 << " These are all the detectors with hits " << " \n";
00843 #endif
00844
00845
00846 std::vector<uint32_t> detIdList ;
00847
00848 for (unsigned int i = 0; i < uselist.size(); i++) {
00849 if (uselist[i]) {
00850 const SiStripRecHit2D* hit = hitlist[i];
00851 uint32_t detIDUsed = ((hit)->geographicalId()).rawId() ;
00852 #ifdef EDM_ML_DEBUG
00853 debugstr5<< " DetId " << detIDUsed << "\n";
00854 #endif
00855 detIdList.push_back(detIDUsed) ;
00856 }
00857 }
00858
00859 #ifdef EDM_ML_DEBUG
00860 debugstr5 << " There are " << detIdList.size() << " hits on detectors \n";
00861 #endif
00862
00863 std::sort(detIdList.begin(), detIdList.end());
00864 detIdList.erase(
00865 std::unique(detIdList.begin(), detIdList.end()), detIdList.end());
00866 #ifdef EDM_ML_DEBUG
00867 debugstr5 << " There are " << detIdList.size() << " unique detectors \n";
00868 #endif
00869
00870
00871
00872 #ifdef EDM_ML_DEBUG
00873 debugstr5 << " Looping over detectors to choose best hit " << " \n";
00874 #endif
00875
00876 for (unsigned int idet = 0 ; idet < detIdList.size() ; idet++ ) {
00877 for (unsigned int i = 0; i+1 < uselist.size(); i++) {
00878 if (uselist[i]) {
00879
00880 const SiStripRecHit2D* hit1 = hitlist[i];
00881 double r_hit1 = rlist[i];
00882 double phi_hit1 = philist[i];
00883 double w2_hit1 = w2list[i] ;
00884 double phi_pred1 = (r_hit1-scr)*phiVsRSlope ;
00885 double chi1 = (phi_hit1-phi_pred1)*(phi_hit1-phi_pred1)*w2_hit1;
00886 if(detIdList[idet]== ((hit1)->geographicalId()).rawId()) {
00887 for (unsigned int j = i+1; j < uselist.size(); j++) {
00888 if (uselist[j]) {
00889 const SiStripRecHit2D* hit2 = hitlist[j];
00890 if(detIdList[idet]== ((hit2)->geographicalId()).rawId()) {
00891 #ifdef EDM_ML_DEBUG
00892 debugstr5 << " Found 2 hits on same Si Detector "
00893 << ((hit2)->geographicalId()).rawId() << "\n";
00894 #endif
00895
00896 double r_hit2 = rlist[j];
00897 double phi_hit2 = philist[j];
00898 double w2_hit2 = w2list[j] ;
00899 double phi_pred2 = (r_hit2-scr)*phiVsRSlope ;
00900 double chi2 = (phi_hit2-phi_pred2)*(phi_hit2-phi_pred2)*w2_hit2;
00901 #ifdef EDM_ML_DEBUG
00902 debugstr5 << " Chi1 " << chi1 << " Chi2 " << chi2 <<"\n";
00903 #endif
00904 if( chi1< chi2 ){
00905 uselist[j] = 0;
00906 }else{
00907 uselist[i] = 0;
00908 }
00909
00910 }
00911 }
00912 }
00913
00914 }
00915 }
00916 }
00917
00918
00919 }
00920
00921
00922
00923
00924 for ( unsigned int i = 0; i < uselist.size(); i++ ) {
00925 if ( uselist[i] ) {
00926 double localchi2 = (philist[i]-(rlist[i]-scr)*phiVsRSlope)*(philist[i]-(rlist[i]-scr)*phiVsRSlope)*w2list[i] ;
00927 if(localchi2 > chi2HitMax ) {
00928 #ifdef EDM_ML_DEBUG
00929 const SiStripRecHit2D* hit = hitlist[i];
00930 debugstr5 << " Throwing out "
00931 <<" DetID " << ((hit)->geographicalId()).rawId()
00932 << " R " << rlist[i]
00933 << " Phi " << philist[i]
00934 << " Weight " << w2list[i]
00935 << " PhiPred " << (rlist[i]-scr)*phiVsRSlope
00936 << " Chi2 " << (philist[i]-(rlist[i]-scr)*phiVsRSlope)*(philist[i]-(rlist[i]-scr)*phiVsRSlope)*w2list[i]
00937 << " \n" ;
00938 #endif
00939 uselist[i]=0 ;
00940 }
00941 }
00942 }
00943
00944 #ifdef EDM_ML_DEBUG
00945 debugstr5 << " List of hits after uniqification " << " \n" ;
00946 for (unsigned int i = 0; i < uselist.size(); i++) {
00947 if ( uselist[i] ) {
00948 const SiStripRecHit2D* hit = hitlist[i];
00949 debugstr5 << " DetID " << ((hit)->geographicalId()).rawId()
00950 << " R " << rlist[i]
00951 << " Phi " << philist[i]
00952 << " Weight " << w2list[i]
00953 << " PhiPred " << (rlist[i]-scr)*phiVsRSlope
00954 << " Chi2 " << (philist[i]-(rlist[i]-scr)*phiVsRSlope)*(philist[i]-(rlist[i]-scr)*phiVsRSlope)*w2list[i]
00955 << " \n" ;
00956 }
00957 }
00958 debugstr5 << " \n\n\n" ;
00959 #endif
00960
00961
00962 unsigned int nHitsLeft =0;
00963 for (unsigned int i = 0; i < uselist.size(); i++) {
00964 if ( uselist[i] ) {
00965 nHitsLeft++;
00966 }
00967 }
00968 if(nHitsLeft < nHitsLeftMinimum ) {
00969 #ifdef EDM_ML_DEBUG
00970 debugstr5 << " Too few hits "<< nHitsLeft
00971 << " left - return false " << " \n";
00972 #endif
00973 return false ;
00974 }
00975 #ifdef EDM_ML_DEBUG
00976 LogDebug("") << debugstr5.str();
00977 #endif
00978
00979
00980
00981 bool done = false;
00982 double intercept = 0 ;
00983 double slope = 0 ;
00984 double chi2 = 0;
00985
00986 std::ostringstream debugstr4;
00987 debugstr4 <<" Calc of phi(r) "<<" \n";
00988
00989 while (!done) {
00990
00991
00992
00993
00994
00995
00996 double phiBar = 0.;
00997 double phiBarOld = 0.;
00998 double rBar = 0.;
00999 double rBarOld = 0.;
01000 double r2Bar = 0.;
01001 double r2BarOld = 0.;
01002 double phirBar = 0.;
01003 double phirBarOld = 0.;
01004 double totalWeight = 0.;
01005 double totalWeightOld = 0.;
01006 unsigned int uselist_size = uselist.size();
01007 for (unsigned int i = 0; i < uselist_size; i++) {
01008 if (uselist[i]) {
01009 double r = rlist[i];
01010 double phi = philist[i];
01011 double weight2 = w2list[i];
01012
01013 totalWeight = totalWeightOld + weight2 ;
01014
01015
01016
01017
01018 double totalWeightRatio = totalWeightOld/totalWeight ;
01019 double localWeightRatio = weight2/totalWeight ;
01020
01021 phiBar = phiBarOld*totalWeightRatio + phi*localWeightRatio ;
01022 rBar = rBarOld*totalWeightRatio + r*localWeightRatio ;
01023 r2Bar= r2BarOld*totalWeightRatio + r*r*localWeightRatio ;
01024 phirBar = phirBarOld*totalWeightRatio + phi*r*localWeightRatio ;
01025
01026 totalWeightOld = totalWeight ;
01027 phiBarOld = phiBar ;
01028 rBarOld = rBar ;
01029 r2BarOld = r2Bar ;
01030 phirBarOld = phirBar ;
01031 #ifdef EDM_ML_DEBUG
01032 debugstr4 << " totalWeight " << totalWeight
01033 << " totalWeightRatio " << totalWeightRatio
01034 << " localWeightRatio "<< localWeightRatio
01035 << " phiBar " << phiBar
01036 << " rBar " << rBar
01037 << " r2Bar " << r2Bar
01038 << " phirBar " << phirBar
01039 << " \n ";
01040 #endif
01041
01042 }
01043 }
01044 slope = (phirBar-phiBar*rBar)/(r2Bar-rBar*rBar);
01045 intercept = phiBar-slope*rBar ;
01046
01047 debugstr4 << " end of loop slope " << slope
01048 << " intercept " << intercept << " \n";
01049
01050
01051 chi2 = 0.;
01052 double biggest_normresid = -1.;
01053 unsigned int biggest_index = 0;
01054 for (unsigned int i = 0; i < uselist_size; i++) {
01055 if (uselist[i]) {
01056 double r = rlist[i];
01057 double phi = philist[i];
01058 double weight2 = w2list[i];
01059
01060 double normresid = weight2 * (phi - intercept - slope*r)*(phi - intercept - slope*r);
01061 chi2 += normresid;
01062
01063 if (normresid > biggest_normresid) {
01064 biggest_normresid = normresid;
01065 biggest_index = i;
01066 }
01067 }
01068 }
01069
01070 if (biggest_normresid > maxNormResid_) {
01071 #ifdef EDM_ML_DEBUG
01072 debugstr4 << "Dropping hit from fit due to Chi2 " << " \n" ;
01073 const SiStripRecHit2D* hit = hitlist[biggest_index];
01074 debugstr4 << " DetID " << ((hit)->geographicalId()).rawId()
01075 << " R " << rlist[biggest_index]
01076 << " Phi " << philist[biggest_index]
01077 << " Weight " << w2list[biggest_index]
01078 << " PhiPred " << (rlist[biggest_index]-scr)*phiVsRSlope
01079 << " Chi2 " << (philist[biggest_index]-(rlist[biggest_index]-scr)*phiVsRSlope)*(philist[biggest_index]-(rlist[biggest_index]-scr)*phiVsRSlope)*w2list[biggest_index]
01080 << " normresid " << biggest_normresid
01081 << " \n\n";
01082 #endif
01083 uselist[biggest_index] = false;
01084 }
01085 else {
01086 done = true;
01087 }
01088 }
01089 #ifdef EDM_ML_DEBUG
01090 debugstr4 <<" Fit "
01091 << " Intercept " << intercept
01092 << " slope " << slope
01093 << " chi2 " << chi2
01094 << " \n" ;
01095
01096 LogDebug("") << debugstr4.str() ;
01097 #endif
01098
01099
01100
01101
01102 const SiStripRecHit2D* innerhit = (SiStripRecHit2D*)(0);
01103 double innerhitRadius = -1.;
01104
01105
01106 std::vector<const TrackingRecHit*> outputHits;
01107
01108 std::vector<SiStripRecHit2D> outputRphiHits;
01109 std::vector<SiStripRecHit2D> outputStereoHits;
01110
01111 typedef edm::Ref<SiStripRecHit2DCollection,SiStripRecHit2D> SiStripRecHit2DRef;
01112
01113
01114 for (unsigned int i = 0; i < uselist.size(); i++) {
01115 if (uselist[i]) {
01116 double r = rlist[i];
01117 const SiStripRecHit2D* hit = hitlist[i];
01118
01119
01120 if (innerhit == (SiStripRecHit2D*)(0) || r < innerhitRadius) {
01121 innerhit = hit;
01122 innerhitRadius = r;
01123 }
01124
01125 if (typelist[i] == 0) {
01126 numberOfStereoHits++;
01127
01128
01129 outputHits.push_back(hit);
01130 outputStereoHits.push_back(*hit);
01131 }
01132 else if (typelist[i] == 1) {
01133 numberOfBarrelRphiHits++;
01134
01135
01136 outputHits.push_back(hit);
01137 outputRphiHits.push_back(*hit);
01138 }
01139 else if (typelist[i] == 2) {
01140 numberOfEndcapZphiHits++;
01141
01142
01143 outputHits.push_back(hit);
01144 outputRphiHits.push_back(*hit);
01145 }
01146 }
01147 }
01148
01149 unsigned int totalNumberOfHits = numberOfStereoHits + numberOfBarrelRphiHits + numberOfEndcapZphiHits;
01150 double reducedChi2 = (totalNumberOfHits > 2 ? chi2 / (totalNumberOfHits - 2) : 1e10);
01151
01152
01153 if (totalNumberOfHits >= minHits_ && reducedChi2 <= maxReducedChi2_) {
01154
01155 GlobalPoint position = tracker_p_->idToDet(innerhit->geographicalId())->surface().toGlobal(innerhit->localPosition());
01156
01157
01158
01159
01160
01161 double correct_pT = pT * phiVsRSlope / slope;
01162
01163
01164 double phi = intercept + slope*sqrt(position.x()*position.x() + position.y()*position.y()) + superclusterIn->position().phi();
01165
01166
01167 double pZ = correct_pT * zVsRSlope;
01168
01169
01170 GlobalVector momentum = GlobalVector(correct_pT*cos(phi), correct_pT*sin(phi), pZ);
01171
01172 if (chargeHypothesis > 0.) {
01173 redchi2_pos_ = chi2 / double(totalNumberOfHits - 2);
01174 position_pos_ = position;
01175 momentum_pos_ = momentum;
01176 innerhit_pos_ = innerhit;
01177 outputHits_pos_ = outputHits;
01178 outputRphiHits_pos_ = outputRphiHits;
01179 outputStereoHits_pos_ = outputStereoHits;
01180 phiVsRSlope_pos_ = phiVsRSlope;
01181 slope_pos_ = slope;
01182 intercept_pos_ = intercept;
01183 chi2_pos_ = chi2;
01184 ndof_pos_ = totalNumberOfHits - 2;
01185 correct_pT_pos_ = correct_pT;
01186 pZ_pos_ = pZ;
01187 zVsRSlope_pos_ = zVsRSlope;
01188 numberOfStereoHits_pos_ = numberOfStereoHits;
01189 numberOfBarrelRphiHits_pos_ = numberOfBarrelRphiHits;
01190 numberOfEndcapZphiHits_pos_ = numberOfEndcapZphiHits;
01191 }
01192 else {
01193 redchi2_neg_ = chi2 / double(totalNumberOfHits - 2);
01194 position_neg_ = position;
01195 momentum_neg_ = momentum;
01196 innerhit_neg_ = innerhit;
01197 outputHits_neg_ = outputHits;
01198 outputRphiHits_neg_ = outputRphiHits;
01199 outputStereoHits_neg_ = outputStereoHits;
01200 phiVsRSlope_neg_ = phiVsRSlope;
01201 slope_neg_ = slope;
01202 intercept_neg_ = intercept;
01203 chi2_neg_ = chi2;
01204 ndof_neg_ = totalNumberOfHits - 2;
01205 correct_pT_neg_ = correct_pT;
01206 pZ_neg_ = pZ;
01207 zVsRSlope_neg_ = zVsRSlope;
01208 numberOfStereoHits_neg_ = numberOfStereoHits;
01209 numberOfBarrelRphiHits_neg_ = numberOfBarrelRphiHits;
01210 numberOfEndcapZphiHits_neg_ = numberOfEndcapZphiHits;
01211 }
01212
01213 LogDebug("") << " return from projectFindBand with True \n" << std::endl ;
01214 return true;
01215 }
01216
01217
01218 LogDebug("") << " return from projectFindBand with False \n" << std::endl ;
01219 return false;
01220 }
01221
01222
01223
01224
01225
01226
01227
01228
01229