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