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::DataContainer::const_iterator it = rphiHits_p_->data().begin(); it != rphiHits_p_->data().end(); ++it) {
00124 rphiKey_[&(*it)] = counter;
00125 hitUsed_[&(*it)] = false;
00126 counter++;
00127 }
00128
00129 counter = 0;
00130 for (SiStripRecHit2DCollection::DataContainer::const_iterator it = stereoHits_p_->data().begin(); it != stereoHits_p_->data().end(); ++it) {
00131 stereoKey_[&(*it)] = counter;
00132 hitUsed_[&(*it)] = false;
00133 counter++;
00134 }
00135
00136 counter = 0;
00137 for (SiStripMatchedRecHit2DCollection::DataContainer::const_iterator it = matchedHits_p_->data().begin(); it != matchedHits_p_->data().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 SiStripRecHit2DCollection::const_iterator itdet = (stereo ? stereoHits_p_->begin() : rphiHits_p_->begin());
00370 SiStripRecHit2DCollection::const_iterator eddet = (stereo ? stereoHits_p_->end() : rphiHits_p_->end() );
00371 for (; itdet != eddet; ++itdet) {
00372
00373 SiStripRecHit2DCollection::DetSet hits = *itdet;
00374 DetId id(hits.detId());
00375
00376
00377 unsigned int numberOfHits = hits.size();
00378
00379
00380
00381
00382 if (numberOfHits <= maxHitsOnDetId_) {
00383 for (SiStripRecHit2DCollection::DetSet::const_iterator hit = hits.begin();
00384 hit != hits.end(); ++hit) {
00385
00386 if(!(*hit).isValid()) {
00387 LogDebug("") << " InValid hit skipped in coarseHitSelection " << std::endl ;
00388 continue ;
00389 }
00390 std::string theDet = "null";
00391 int theLayer = -999;
00392 bool isStereoDet = false ;
00393 if(tracker_p_->idToDetUnit(hit->geographicalId())->type().subDetector() == GeomDetEnumerators::TIB) {
00394 theDet = "TIB" ;
00395 theLayer = TIBDetId(id).layer();
00396 if(TIBDetId(id).stereo()==1) { isStereoDet = true ; }
00397 } else if
00398 (tracker_p_->idToDetUnit(hit->geographicalId())->type().subDetector() == GeomDetEnumerators::TOB) {
00399 theDet = "TOB" ;
00400 theLayer = TOBDetId(id).layer();
00401 if(TOBDetId(id).stereo()==1) { isStereoDet = true ; }
00402 }else if
00403 (tracker_p_->idToDetUnit(hit->geographicalId())->type().subDetector() == GeomDetEnumerators::TID) {
00404 theDet = "TID" ;
00405 theLayer = TIDDetId(id).wheel();
00406 if(TIDDetId(id).stereo()==1) { isStereoDet = true ; }
00407 }else if
00408 (tracker_p_->idToDetUnit(hit->geographicalId())->type().subDetector() == GeomDetEnumerators::TEC) {
00409 theDet = "TEC" ;
00410 theLayer = TECDetId(id).wheel();
00411 if(TECDetId(id).stereo()==1) { isStereoDet = true ; }
00412 } else {
00413 LogDebug("") << " UHOH BIG PROBLEM - Unrecognized SI Layer" ;
00414 LogDebug("") << " Det "<< theDet << " Lay " << theLayer ;
00415 assert(1!=1) ;
00416 }
00417
00418 if ((endcap && stereo && (theDet=="TID" || theDet== "TEC") && isStereoDet ) ||
00419 (endcap && !stereo && (theDet=="TID" || theDet== "TEC") && !isStereoDet ) ||
00420 (!endcap && stereo && (theDet=="TIB" || theDet=="TOB") && isStereoDet ) ||
00421 (!endcap && !stereo && (theDet=="TIB" || theDet=="TOB" )&& !isStereoDet )
00422 ) {
00423
00424
00425 hitPointersOut.push_back(&(*hit));
00426
00427 }
00428 }
00429 }
00430 }
00431 }
00432
00433
00434
00435 void SiStripElectronAlgo::coarseMatchedHitSelection(std::vector<const SiStripMatchedRecHit2D*>& coarseMatchedHitPointersOut)
00436 {
00437
00438
00439 SiStripMatchedRecHit2DCollection::const_iterator itdet = matchedHits_p_->begin(), eddet = matchedHits_p_->end();
00440 for (; itdet != eddet; ++itdet) {
00441
00442
00443 SiStripMatchedRecHit2DCollection::DetSet hits = *itdet ;
00444
00445
00446 unsigned int numberOfHits = 0;
00447 for (SiStripMatchedRecHit2DCollection::DetSet::const_iterator hit = hits.begin(); hit != hits.end(); ++hit) {
00448 if ( !((hit->geographicalId()).subdetId() == StripSubdetector::TIB) &&
00449 !( (hit->geographicalId()).subdetId() == StripSubdetector::TOB )) { break;}
00450 numberOfHits++;
00451 if (numberOfHits > maxHitsOnDetId_) { break; }
00452 }
00453
00454
00455 if (numberOfHits <= maxHitsOnDetId_) {
00456 for (SiStripMatchedRecHit2DCollection::DetSet::const_iterator hit = hits.begin(); hit != hits.end(); ++hit) {
00457 if(!(*hit).isValid()) {
00458 LogDebug("") << " InValid hit skipped in coarseMatchedHitSelection " << std::endl ;
00459 continue ;
00460 }
00461 if ( !((hit->geographicalId()).subdetId() == StripSubdetector::TIB) &&
00462 !( (hit->geographicalId()).subdetId() == StripSubdetector::TOB )) { break;}
00463
00464 coarseMatchedHitPointersOut.push_back(&(*hit));
00465 }
00466
00467 }
00468 }
00469
00470
00471 }
00472
00473
00474
00475
00476
00477
00478
00479 bool SiStripElectronAlgo::projectPhiBand(float chargeHypothesis, const reco::SuperClusterRef& superclusterIn)
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, true, false);
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 const SiStripRecHit2D::ClusterRef & stereocluster=(*hit)->cluster();
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 const SiStripRecHit2D::ClusterRef & mystereocluster = matchedhitlist[i]->stereoHit()->cluster();
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 const SiStripRecHit2D::ClusterRef & monocluster=(*hit)->cluster();
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 const SiStripRecHit2D::ClusterRef & mymonocluster = matchedhitlist[i]->monoHit()->cluster();
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 std::ostringstream debugstr5;
00823 debugstr5 << " List of hits before uniqification " << " \n" ;
00824 for (unsigned int i = 0; i < uselist.size(); i++) {
00825 if ( uselist[i] ) {
00826 const SiStripRecHit2D* hit = hitlist[i];
00827 debugstr5 << " DetID " << ((hit)->geographicalId()).rawId()
00828 << " R " << rlist[i]
00829 << " Phi " << philist[i]
00830 << " Weight " << w2list[i]
00831 << " PhiPred " << (rlist[i]-scr)*phiVsRSlope
00832 << " Chi2 " << (philist[i]-(rlist[i]-scr)*phiVsRSlope)*(philist[i]-(rlist[i]-scr)*phiVsRSlope)*w2list[i]
00833 << " \n" ;
00834 }
00835 }
00836 debugstr5 << " \n\n\n" ;
00837
00838 debugstr5 << " Counting number of unique detectors " << " \n" ;
00839
00840 debugstr5 << " These are all the detectors with hits " << " \n";
00841
00842
00843 std::vector<uint32_t> detIdList ;
00844
00845 for (unsigned int i = 0; i < uselist.size(); i++) {
00846 if (uselist[i]) {
00847 const SiStripRecHit2D* hit = hitlist[i];
00848 uint32_t detIDUsed = ((hit)->geographicalId()).rawId() ;
00849 debugstr5<< " DetId " << detIDUsed << "\n";
00850 detIdList.push_back(detIDUsed) ;
00851 }
00852 }
00853 debugstr5 << " There are " << detIdList.size() << " hits on detectors \n";
00854
00855 std::sort(detIdList.begin(), detIdList.end());
00856 detIdList.erase(
00857 std::unique(detIdList.begin(), detIdList.end()), detIdList.end());
00858
00859 debugstr5 << " There are " << detIdList.size() << " unique detectors \n";
00860
00861
00862
00863
00864
00865 debugstr5 << " Looping over detectors to choose best hit " << " \n";
00866
00867 for (unsigned int idet = 0 ; idet < detIdList.size() ; idet++ ) {
00868 for (unsigned int i = 0; i+1 < uselist.size(); i++) {
00869 if (uselist[i]) {
00870
00871 const SiStripRecHit2D* hit1 = hitlist[i];
00872 double r_hit1 = rlist[i];
00873 double phi_hit1 = philist[i];
00874 double w2_hit1 = w2list[i] ;
00875 double phi_pred1 = (r_hit1-scr)*phiVsRSlope ;
00876 double chi1 = (phi_hit1-phi_pred1)*(phi_hit1-phi_pred1)*w2_hit1;
00877 if(detIdList[idet]== ((hit1)->geographicalId()).rawId()) {
00878 for (unsigned int j = i+1; j < uselist.size(); j++) {
00879 if (uselist[j]) {
00880 const SiStripRecHit2D* hit2 = hitlist[j];
00881 if(detIdList[idet]== ((hit2)->geographicalId()).rawId()) {
00882 debugstr5 << " Found 2 hits on same Si Detector "
00883 << ((hit2)->geographicalId()).rawId() << "\n";
00884
00885 double r_hit2 = rlist[j];
00886 double phi_hit2 = philist[j];
00887 double w2_hit2 = w2list[j] ;
00888 double phi_pred2 = (r_hit2-scr)*phiVsRSlope ;
00889 double chi2 = (phi_hit2-phi_pred2)*(phi_hit2-phi_pred2)*w2_hit2;
00890 debugstr5 << " Chi1 " << chi1 << " Chi2 " << chi2 <<"\n";
00891 if( chi1< chi2 ){
00892 uselist[j] = 0;
00893 }else{
00894 uselist[i] = 0;
00895 }
00896
00897 }
00898 }
00899 }
00900
00901 }
00902 }
00903 }
00904
00905
00906 }
00907
00908
00909
00910
00911 for ( unsigned int i = 0; i < uselist.size(); i++ ) {
00912 if ( uselist[i] ) {
00913 const SiStripRecHit2D* hit = hitlist[i];
00914 double localchi2 = (philist[i]-(rlist[i]-scr)*phiVsRSlope)*(philist[i]-(rlist[i]-scr)*phiVsRSlope)*w2list[i] ;
00915 if(localchi2 > chi2HitMax ) {
00916 debugstr5 << " Throwing out "
00917 <<" DetID " << ((hit)->geographicalId()).rawId()
00918 << " R " << rlist[i]
00919 << " Phi " << philist[i]
00920 << " Weight " << w2list[i]
00921 << " PhiPred " << (rlist[i]-scr)*phiVsRSlope
00922 << " Chi2 " << (philist[i]-(rlist[i]-scr)*phiVsRSlope)*(philist[i]-(rlist[i]-scr)*phiVsRSlope)*w2list[i]
00923 << " \n" ;
00924 uselist[i]=0 ;
00925 }
00926 }
00927 }
00928
00929 debugstr5 << " List of hits after uniqification " << " \n" ;
00930 for (unsigned int i = 0; i < uselist.size(); i++) {
00931 if ( uselist[i] ) {
00932 const SiStripRecHit2D* hit = hitlist[i];
00933 debugstr5 << " DetID " << ((hit)->geographicalId()).rawId()
00934 << " R " << rlist[i]
00935 << " Phi " << philist[i]
00936 << " Weight " << w2list[i]
00937 << " PhiPred " << (rlist[i]-scr)*phiVsRSlope
00938 << " Chi2 " << (philist[i]-(rlist[i]-scr)*phiVsRSlope)*(philist[i]-(rlist[i]-scr)*phiVsRSlope)*w2list[i]
00939 << " \n" ;
00940 }
00941 }
00942 debugstr5 << " \n\n\n" ;
00943
00944
00945
00946 unsigned int nHitsLeft =0;
00947 for (unsigned int i = 0; i < uselist.size(); i++) {
00948 if ( uselist[i] ) {
00949 nHitsLeft++;
00950 }
00951 }
00952 if(nHitsLeft < nHitsLeftMinimum ) {
00953 debugstr5 << " Too few hits "<< nHitsLeft
00954 << " left - return false " << " \n";
00955 return false ;
00956 }
00957 LogDebug("") << debugstr5.str();
00958
00960
00961
00962 bool done = false;
00963 double intercept = 0 ;
00964 double slope = 0 ;
00965 double chi2 = 0;
00966
00967 std::ostringstream debugstr4;
00968 debugstr4 <<" Calc of phi(r) "<<" \n";
00969
00970 while (!done) {
00971
00972
00973
00974
00975
00976
00977 double phiBar = 0.;
00978 double phiBarOld = 0.;
00979 double rBar = 0.;
00980 double rBarOld = 0.;
00981 double r2Bar = 0.;
00982 double r2BarOld = 0.;
00983 double phirBar = 0.;
00984 double phirBarOld = 0.;
00985 double totalWeight = 0.;
00986 double totalWeightOld = 0.;
00987 unsigned int uselist_size = uselist.size();
00988 for (unsigned int i = 0; i < uselist_size; i++) {
00989 if (uselist[i]) {
00990 double r = rlist[i];
00991 double phi = philist[i];
00992 double weight2 = w2list[i];
00993
00994 totalWeight = totalWeightOld + weight2 ;
00995
00996
00997
00998
00999 double totalWeightRatio = totalWeightOld/totalWeight ;
01000 double localWeightRatio = weight2/totalWeight ;
01001
01002 phiBar = phiBarOld*totalWeightRatio + phi*localWeightRatio ;
01003 rBar = rBarOld*totalWeightRatio + r*localWeightRatio ;
01004 r2Bar= r2BarOld*totalWeightRatio + r*r*localWeightRatio ;
01005 phirBar = phirBarOld*totalWeightRatio + phi*r*localWeightRatio ;
01006
01007 totalWeightOld = totalWeight ;
01008 phiBarOld = phiBar ;
01009 rBarOld = rBar ;
01010 r2BarOld = r2Bar ;
01011 phirBarOld = phirBar ;
01012
01013 debugstr4 << " totalWeight " << totalWeight
01014 << " totalWeightRatio " << totalWeightRatio
01015 << " localWeightRatio "<< localWeightRatio
01016 << " phiBar " << phiBar
01017 << " rBar " << rBar
01018 << " r2Bar " << r2Bar
01019 << " phirBar " << phirBar
01020 << " \n ";
01021
01022
01023 }
01024 }
01025 slope = (phirBar-phiBar*rBar)/(r2Bar-rBar*rBar);
01026 intercept = phiBar-slope*rBar ;
01027
01028 debugstr4 << " end of loop slope " << slope
01029 << " intercept " << intercept << " \n";
01030
01031
01032 chi2 = 0.;
01033 double biggest_normresid = -1.;
01034 unsigned int biggest_index = 0;
01035 for (unsigned int i = 0; i < uselist_size; i++) {
01036 if (uselist[i]) {
01037 double r = rlist[i];
01038 double phi = philist[i];
01039 double weight2 = w2list[i];
01040
01041 double normresid = weight2 * (phi - intercept - slope*r)*(phi - intercept - slope*r);
01042 chi2 += normresid;
01043
01044 if (normresid > biggest_normresid) {
01045 biggest_normresid = normresid;
01046 biggest_index = i;
01047 }
01048 }
01049 }
01050
01051 if (biggest_normresid > maxNormResid_) {
01052 debugstr4 << "Dropping hit from fit due to Chi2 " << " \n" ;
01053 const SiStripRecHit2D* hit = hitlist[biggest_index];
01054 debugstr4 << " DetID " << ((hit)->geographicalId()).rawId()
01055 << " R " << rlist[biggest_index]
01056 << " Phi " << philist[biggest_index]
01057 << " Weight " << w2list[biggest_index]
01058 << " PhiPred " << (rlist[biggest_index]-scr)*phiVsRSlope
01059 << " Chi2 " << (philist[biggest_index]-(rlist[biggest_index]-scr)*phiVsRSlope)*(philist[biggest_index]-(rlist[biggest_index]-scr)*phiVsRSlope)*w2list[biggest_index]
01060 << " normresid " << biggest_normresid
01061 << " \n\n";
01062 uselist[biggest_index] = false;
01063 }
01064 else {
01065 done = true;
01066 }
01067 }
01068
01069 debugstr4 <<" Fit "
01070 << " Intercept " << intercept
01071 << " slope " << slope
01072 << " chi2 " << chi2
01073 << " \n" ;
01074
01075 LogDebug("") << debugstr4.str() ;
01076
01077
01078
01079
01080
01081 const SiStripRecHit2D* innerhit = (SiStripRecHit2D*)(0);
01082 double innerhitRadius = -1.;
01083
01084
01085 std::vector<const TrackingRecHit*> outputHits;
01086
01087 std::vector<SiStripRecHit2D> outputRphiHits;
01088 std::vector<SiStripRecHit2D> outputStereoHits;
01089
01090 typedef edm::Ref<SiStripRecHit2DCollection,SiStripRecHit2D> SiStripRecHit2DRef;
01091
01092
01093 for (unsigned int i = 0; i < uselist.size(); i++) {
01094 if (uselist[i]) {
01095 double r = rlist[i];
01096 const SiStripRecHit2D* hit = hitlist[i];
01097
01098
01099 if (innerhit == (SiStripRecHit2D*)(0) || r < innerhitRadius) {
01100 innerhit = hit;
01101 innerhitRadius = r;
01102 }
01103
01104 if (typelist[i] == 0) {
01105 numberOfStereoHits++;
01106
01107
01108 outputHits.push_back(hit);
01109 outputStereoHits.push_back(*hit);
01110 }
01111 else if (typelist[i] == 1) {
01112 numberOfBarrelRphiHits++;
01113
01114
01115 outputHits.push_back(hit);
01116 outputRphiHits.push_back(*hit);
01117 }
01118 else if (typelist[i] == 2) {
01119 numberOfEndcapZphiHits++;
01120
01121
01122 outputHits.push_back(hit);
01123 outputRphiHits.push_back(*hit);
01124 }
01125 }
01126 }
01127
01128 unsigned int totalNumberOfHits = numberOfStereoHits + numberOfBarrelRphiHits + numberOfEndcapZphiHits;
01129 double reducedChi2 = (totalNumberOfHits > 2 ? chi2 / (totalNumberOfHits - 2) : 1e10);
01130
01131
01132 if (totalNumberOfHits >= minHits_ && reducedChi2 <= maxReducedChi2_) {
01133
01134 GlobalPoint position = tracker_p_->idToDet(innerhit->geographicalId())->surface().toGlobal(innerhit->localPosition());
01135
01136
01137
01138
01139
01140 double correct_pT = pT * phiVsRSlope / slope;
01141
01142
01143 double phi = intercept + slope*sqrt(position.x()*position.x() + position.y()*position.y()) + superclusterIn->position().phi();
01144
01145
01146 double pZ = correct_pT * zVsRSlope;
01147
01148
01149 GlobalVector momentum = GlobalVector(correct_pT*cos(phi), correct_pT*sin(phi), pZ);
01150
01151 if (chargeHypothesis > 0.) {
01152 redchi2_pos_ = chi2 / double(totalNumberOfHits - 2);
01153 position_pos_ = position;
01154 momentum_pos_ = momentum;
01155 innerhit_pos_ = innerhit;
01156 outputHits_pos_ = outputHits;
01157 outputRphiHits_pos_ = outputRphiHits;
01158 outputStereoHits_pos_ = outputStereoHits;
01159 phiVsRSlope_pos_ = phiVsRSlope;
01160 slope_pos_ = slope;
01161 intercept_pos_ = intercept;
01162 chi2_pos_ = chi2;
01163 ndof_pos_ = totalNumberOfHits - 2;
01164 correct_pT_pos_ = correct_pT;
01165 pZ_pos_ = pZ;
01166 zVsRSlope_pos_ = zVsRSlope;
01167 numberOfStereoHits_pos_ = numberOfStereoHits;
01168 numberOfBarrelRphiHits_pos_ = numberOfBarrelRphiHits;
01169 numberOfEndcapZphiHits_pos_ = numberOfEndcapZphiHits;
01170 }
01171 else {
01172 redchi2_neg_ = chi2 / double(totalNumberOfHits - 2);
01173 position_neg_ = position;
01174 momentum_neg_ = momentum;
01175 innerhit_neg_ = innerhit;
01176 outputHits_neg_ = outputHits;
01177 outputRphiHits_neg_ = outputRphiHits;
01178 outputStereoHits_neg_ = outputStereoHits;
01179 phiVsRSlope_neg_ = phiVsRSlope;
01180 slope_neg_ = slope;
01181 intercept_neg_ = intercept;
01182 chi2_neg_ = chi2;
01183 ndof_neg_ = totalNumberOfHits - 2;
01184 correct_pT_neg_ = correct_pT;
01185 pZ_neg_ = pZ;
01186 zVsRSlope_neg_ = zVsRSlope;
01187 numberOfStereoHits_neg_ = numberOfStereoHits;
01188 numberOfBarrelRphiHits_neg_ = numberOfBarrelRphiHits;
01189 numberOfEndcapZphiHits_neg_ = numberOfEndcapZphiHits;
01190 }
01191
01192 LogDebug("") << " return from projectFindBand with True \n" << std::endl ;
01193 return true;
01194 }
01195
01196
01197 LogDebug("") << " return from projectFindBand with False \n" << std::endl ;
01198 return false;
01199 }
01200
01201
01202
01203
01204
01205
01206
01207
01208