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