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 TrajectoryStateTransform transformer;
00232 PTrajectoryStateOnDet* PTraj = transformer.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 delete PTraj;
00253
00254 return true;
00255 }
00256
00257
00258 if ((!electronSuccess && positronSuccess) ||
00259 (electronSuccess && positronSuccess && redchi2_neg_ > redchi2_pos_)) {
00260
00261
00262 AlgebraicSymMatrix55 errors;
00263 errors(0,0) = 3.;
00264 errors(1,1) = 0.01;
00265 errors(2,2) = 0.0001;
00266 errors(3,3) = 0.01;
00267 errors(4,4) = 0.01;
00268
00269 #ifdef EDM_ML_DEBUG
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 #endif
00288
00289 std::sort(outputHits_pos_.begin(), outputHits_pos_.end(),
00290 CompareHits(TrackingRecHitLessFromGlobalPosition(((TrackingGeometry*)(tracker_p_)), alongMomentum)));
00291
00292 #ifdef EDM_ML_DEBUG
00293 debugstr7 << " Done with sort " << " \n";
00294
00295
00296 debugstr7 << " HERE AFTER SORT Positron case " << " \n";
00297 for (std::vector<const TrackingRecHit*>::iterator itHit = outputHits_pos_.begin();
00298 itHit != outputHits_pos_.end(); ++itHit) {
00299 debugstr7 <<" HIT "<<((*itHit)->geographicalId()).rawId()<<" \n"
00300 <<" Local Position: "<<(*itHit)->localPosition()<<" \n"
00301 <<" Global Rho: "
00302 <<(((TrackingGeometry*)(tracker_p_))->idToDet((*itHit)->geographicalId())->surface().toGlobal((*itHit)->localPosition()).perp())
00303 <<" Phi "
00304 <<(((TrackingGeometry*)(tracker_p_))->idToDet((*itHit)->geographicalId())->surface().toGlobal((*itHit)->localPosition()).phi())
00305 << " Z "
00306 <<(((TrackingGeometry*)(tracker_p_))->idToDet((*itHit)->geographicalId())->surface().toGlobal((*itHit)->localPosition()).z())<< " \n";
00307 }
00308
00309 LogDebug("") << debugstr7.str();
00310 #endif
00311
00312
00313 edm::OwnVector<TrackingRecHit> hits;
00314 for(std::vector<const TrackingRecHit*>::iterator itHit =outputHits_pos_.begin();
00315 itHit != outputHits_pos_.end();
00316 ++itHit) {
00317 hits.push_back( (*itHit)->clone());
00318 assert(hitUsed_.find(*itHit) != hitUsed_.end());
00319 hitUsed_[*itHit] = true;
00320 }
00321
00322 TrajectoryStateOnSurface state(
00323 GlobalTrajectoryParameters(position_pos_, momentum_pos_, 1, magneticField_p_),
00324 CurvilinearTrajectoryError(errors),
00325 tracker_p_->idToDet(innerhit_pos_->geographicalId())->surface());
00326
00327 TrajectoryStateTransform transformer;
00328 PTrajectoryStateOnDet* PTraj = transformer.persistentState(state, innerhit_pos_->geographicalId().rawId());
00329 TrajectorySeed trajectorySeed(*PTraj, hits, alongMomentum);
00330 trackCandidateOut.push_back(TrackCandidate(hits, trajectorySeed, *PTraj));
00331
00332 electronOut.push_back(reco::SiStripElectron(superclusterIn,
00333 1,
00334 outputRphiHits_pos_,
00335 outputStereoHits_pos_,
00336 phiVsRSlope_pos_,
00337 slope_pos_,
00338 intercept_pos_ + superclusterIn->position().phi(),
00339 chi2_pos_,
00340 ndof_pos_,
00341 correct_pT_pos_,
00342 pZ_pos_,
00343 zVsRSlope_pos_,
00344 numberOfStereoHits_pos_,
00345 numberOfBarrelRphiHits_pos_,
00346 numberOfEndcapZphiHits_pos_));
00347
00348 delete PTraj;
00349
00350 return true;
00351 }
00352
00353 return false;
00354 }
00355
00356
00357
00358
00359
00360 void SiStripElectronAlgo::coarseHitSelection(std::vector<const SiStripRecHit2D*>& hitPointersOut,
00361 bool stereo, bool endcap)
00362 {
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372 SiStripRecHit2DCollection::const_iterator itdet = (stereo ? stereoHits_p_->begin() : rphiHits_p_->begin());
00373 SiStripRecHit2DCollection::const_iterator eddet = (stereo ? stereoHits_p_->end() : rphiHits_p_->end() );
00374 for (; itdet != eddet; ++itdet) {
00375
00376 SiStripRecHit2DCollection::DetSet hits = *itdet;
00377 DetId id(hits.detId());
00378
00379
00380 unsigned int numberOfHits = hits.size();
00381
00382
00383
00384
00385 if (numberOfHits <= maxHitsOnDetId_) {
00386 for (SiStripRecHit2DCollection::DetSet::const_iterator hit = hits.begin();
00387 hit != hits.end(); ++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 SiStripMatchedRecHit2DCollection::const_iterator itdet = matchedHits_p_->begin(), eddet = matchedHits_p_->end();
00443 for (; itdet != eddet; ++itdet) {
00444
00445
00446 SiStripMatchedRecHit2DCollection::DetSet hits = *itdet ;
00447
00448
00449 unsigned int numberOfHits = 0;
00450 for (SiStripMatchedRecHit2DCollection::DetSet::const_iterator hit = hits.begin(); hit != hits.end(); ++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::DetSet::const_iterator hit = hits.begin(); hit != hits.end(); ++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
00532 std::ostringstream debugstr1;
00533 debugstr1 << " Getting barrel rphi hits " << " \n" ;
00534
00535 coarseHitSelection(rphiBarrelHits, false, false);
00536
00537
00538
00539
00540 debugstr1 << " Getting matched hits " << " \n" ;
00541 std::vector<const SiStripMatchedRecHit2D*> matchedHits;
00542 coarseMatchedHitSelection(matchedHits);
00543
00544
00545
00546 double energy = superclusterIn->energy();
00547 double pT = energy * superclusterIn->position().rho()/sqrt(superclusterIn->x()*superclusterIn->x() +
00548 superclusterIn->y()*superclusterIn->y() +
00549 superclusterIn->z()*superclusterIn->z());
00550
00551 double phiVsRSlope = -3.00e-3 * chargeHypothesis * magneticField_p_->inTesla(GlobalPoint(superclusterIn->x(), superclusterIn->y(), 0.)).z() / pT / 2.;
00552
00553
00554 const double scr = superclusterIn->position().rho();
00555 const double scz = superclusterIn->position().z();
00556
00557
00558 std::vector<bool> uselist;
00559 std::vector<double> rlist, philist, w2list;
00560 std::vector<int> typelist;
00561 std::vector<const SiStripRecHit2D*> hitlist;
00562
00563 std::vector<bool> matcheduselist;
00564 std::vector<const SiStripMatchedRecHit2D*> matchedhitlist;
00565
00566
00567 double zSlopeFitNumer = 0.;
00568 double zSlopeFitDenom = 0.;
00569
00570
00571 debugstr1 << " There are a total of " << stereoHits.size() << " stereoHits in this event " << " \n"
00572 << " There are a total of " << rphiBarrelHits.size() << " rphiBarrelHits in this event " << " \n"
00573 << " There are a total of " << zphiEndcapHits.size() << " zphiEndcapHits in this event " << " \n\n";
00574
00575
00576 LogDebug("") << debugstr1.str() ;
00577
00579
00580
00581
00582
00583
00584 LogDebug("") << " Loop over matched hits " << " \n";
00585
00586 for (std::vector<const SiStripMatchedRecHit2D*>::const_iterator hit = matchedHits.begin() ;
00587 hit != matchedHits.end() ; ++ hit) {
00588
00589 assert(matchedHitUsed_.find(*hit) != matchedHitUsed_.end());
00590
00591 if (!matchedHitUsed_[*hit]) {
00592
00593
00594 GlobalPoint position = tracker_p_->idToDet((*hit)->geographicalId())->surface().toGlobal((*hit)->localPosition());
00595 double r = sqrt(position.x()*position.x() + position.y()*position.y());
00596 double phi = unwrapPhi(position.phi() - superclusterIn->position().phi());
00597 double z = position.z();
00598
00599
00600
00601 if ((-originUncertainty_ + (scz + originUncertainty_)*(r/scr)) < z && z < (originUncertainty_ + (scz - originUncertainty_)*(r/scr))) {
00602
00603
00604 if (unwrapPhi((r-scr)*phiVsRSlope - phiBandWidth_) < phi && phi < unwrapPhi((r-scr)*phiVsRSlope + phiBandWidth_)) {
00605
00606
00607 matcheduselist.push_back(true);
00608 matchedhitlist.push_back(*hit);
00609
00610
00611
00612
00613 zSlopeFitNumer += -(scr - r) * (z - scz);
00614 zSlopeFitDenom += (scr - r) * (scr - r);
00615
00616 }
00617 }
00618 }
00619 }
00620
00621
00622 double zVsRSlope;
00623 if (zSlopeFitDenom > 0.) {
00624 zVsRSlope = zSlopeFitNumer / zSlopeFitDenom;
00625 }
00626 else {
00627
00628 zVsRSlope = scz/scr;
00629 }
00630
00631
00632 LogDebug("") << " Loop over stereo hits" << " \n";
00633
00634
00635 unsigned int numberOfStereoHits = 0;
00636 for (std::vector<const SiStripRecHit2D*>::const_iterator hit = stereoHits.begin(); hit != stereoHits.end(); ++hit) {
00637 assert(hitUsed_.find(*hit) != hitUsed_.end());
00638
00639
00640 GlobalPoint position = tracker_p_->idToDet((*hit)->geographicalId())->surface().toGlobal((*hit)->localPosition());
00641 double r_stereo = sqrt(position.x()*position.x() + position.y()*position.y());
00642 double phi_stereo = unwrapPhi(position.phi() - superclusterIn->position().phi());
00643
00644
00645
00646 double r_stereo_err = sqrt((*hit)->localPositionError().xx()*cos2SiPitchAngle +
00647 (*hit)->localPositionError().yy()*sin2SiPitchAngle ) ;
00648
00649
00650
00651
00652
00653 if(r_stereo_err > stereoHitSmallestError ) {
00654 r_stereo_err = sqrt(r_stereo_err*r_stereo_err+stereoErrFudge*stereoErrFudge);
00655
00656 const SiStripRecHit2D::ClusterRef & stereocluster=(*hit)->cluster();
00657
00658 bool thisHitIsMatched = false ;
00659
00660 if (!hitUsed_[*hit]) {
00661
00662 unsigned int matcheduselist_size = matcheduselist.size();
00663 for (unsigned int i = 0; i < matcheduselist_size; i++) {
00664 if (matcheduselist[i]) {
00665 const SiStripRecHit2D::ClusterRef & mystereocluster = matchedhitlist[i]->stereoHit()->cluster();
00666 if( stereocluster == mystereocluster ) {
00667 thisHitIsMatched = true ;
00668
00669
00670 }
00671 }
00672 }
00673
00674 if(thisHitIsMatched) {
00675
00676 uselist.push_back(true);
00677 rlist.push_back(r_stereo);
00678 philist.push_back(phi_stereo);
00679 w2list.push_back(1./(r_stereo_err/r_stereo)/(r_stereo_err/r_stereo));
00680 typelist.push_back(0);
00681 hitlist.push_back(*hit);
00682 }
00683 }
00684
00685 }
00686
00687 }
00688
00689 LogDebug("") << " There are " << uselist.size() << " good hits after stereo loop " ;
00690
00691
00692
00693 LogDebug("") << " Looping over barrel rphi hits " ;
00694 unsigned int rphiMatchedCounter = 0 ;
00695 unsigned int rphiUnMatchedCounter = 0 ;
00696 unsigned int numberOfBarrelRphiHits = 0;
00697 for (std::vector<const SiStripRecHit2D*>::const_iterator hit = rphiBarrelHits.begin(); hit != rphiBarrelHits.end(); ++hit) {
00698 assert(hitUsed_.find(*hit) != hitUsed_.end());
00699
00700 GlobalPoint position = tracker_p_->idToDet((*hit)->geographicalId())->surface().toGlobal((*hit)->localPosition());
00701 double r = sqrt(position.x()*position.x() + position.y()*position.y());
00702 double phi = unwrapPhi(position.phi() - superclusterIn->position().phi());
00703 double z = position.z();
00704 double r_mono_err = sqrt((*hit)->localPositionError().xx()) ;
00705
00706
00707 if( r_mono_err > rphiHitSmallestError) {
00708
00709 r_mono_err=sqrt(r_mono_err*r_mono_err+rphiErrFudge*rphiErrFudge);
00710
00711 const SiStripRecHit2D::ClusterRef & monocluster=(*hit)->cluster();
00712
00713
00714 if (!hitUsed_[*hit]) {
00715 if( (tracker_p_->idToDetUnit((*hit)->geographicalId())->type().subDetector() == GeomDetEnumerators::TIB &&
00716 (TIBDetId((*hit)->geographicalId()).layer()==1 || TIBDetId((*hit)->geographicalId()).layer()==2)) ||
00717 (tracker_p_->idToDetUnit((*hit)->geographicalId())->type().subDetector() == GeomDetEnumerators::TOB
00718 && (TOBDetId((*hit)->geographicalId()).layer()==1 || TOBDetId((*hit)->geographicalId()).layer()==2)) ) {
00719 bool thisHitIsMatched = false ;
00720 unsigned int matcheduselist_size = matcheduselist.size();
00721 for (unsigned int i = 0; i < matcheduselist_size; i++) {
00722 if (matcheduselist[i]) {
00723 const SiStripRecHit2D::ClusterRef & mymonocluster = matchedhitlist[i]->monoHit()->cluster();
00724 if( monocluster == mymonocluster ) {
00725 thisHitIsMatched = true ;
00726 }
00727 }
00728 }
00729
00730
00731 if( thisHitIsMatched ) {
00732
00733 uselist.push_back(true);
00734 rlist.push_back(r);
00735 philist.push_back(phi);
00736 w2list.push_back(1./(r_mono_err/r)/(r_mono_err/r));
00737 typelist.push_back(1);
00738 hitlist.push_back(*hit);
00739 rphiMatchedCounter++;
00740 }
00741
00742 } else {
00743
00744
00745
00746 double zFit = zVsRSlope * (r - scr) + scz;
00747
00748
00749
00750 if ((tracker_p_->idToDetUnit((*hit)->geographicalId())->type().subDetector() == GeomDetEnumerators::TIB &&
00751 std::abs(z - zFit) < 12.) ||
00752 (tracker_p_->idToDetUnit((*hit)->geographicalId())->type().subDetector() == GeomDetEnumerators::TOB &&
00753 std::abs(z - zFit) < 20.) ) {
00754
00755
00756 if (unwrapPhi((r-scr)*phiVsRSlope - phiBandWidth_) < phi && phi < unwrapPhi((r-scr)*phiVsRSlope + phiBandWidth_)) {
00757
00758
00759 uselist.push_back(true);
00760 rlist.push_back(r);
00761 philist.push_back(phi);
00762 w2list.push_back(1./(r_mono_err/r)/(r_mono_err/r));
00763 typelist.push_back(1);
00764 hitlist.push_back(*hit);
00765 rphiUnMatchedCounter++;
00766
00767 }
00768 }
00769 }
00770 }
00771 }
00772 }
00773
00774 LogDebug("") << " There are " << rphiMatchedCounter <<" matched rphi hits";
00775 LogDebug("") << " There are " << rphiUnMatchedCounter <<" unmatched rphi hits";
00776 LogDebug("") << " There are " << uselist.size() << " good stereo+rphi hits " ;
00777
00778
00779
00780
00781
00782
00784
00785
00786 LogDebug("") << " Looping over barrel zphi hits " ;
00787
00788
00789 unsigned int numberOfEndcapZphiHits = 0;
00790 for (std::vector<const SiStripRecHit2D*>::const_iterator hit = zphiEndcapHits.begin();
00791 hit != zphiEndcapHits.end(); ++hit) {
00792 assert(hitUsed_.find(*hit) != hitUsed_.end());
00793 if (!hitUsed_[*hit]) {
00794
00795 GlobalPoint position = tracker_p_->idToDet((*hit)->geographicalId())->surface().toGlobal((*hit)->localPosition());
00796 double z = position.z();
00797 double phi = unwrapPhi(position.phi() - superclusterIn->position().phi());
00798
00799
00800
00801 double rFit = (z - scz)/zVsRSlope + scr;
00802
00803
00804
00805
00806
00807
00808 if (rFit > 0. &&
00809 unwrapPhi((rFit-scr)*phiVsRSlope - phiBandWidth_) < phi && phi < unwrapPhi((rFit-scr)*phiVsRSlope + phiBandWidth_)) {
00810
00811
00812 uselist.push_back(true);
00813 rlist.push_back(rFit);
00814 philist.push_back(phi);
00815 w2list.push_back(1./(0.05/rFit)/(0.05/rFit));
00816 typelist.push_back(2);
00817 hitlist.push_back(*hit);
00818
00819 }
00820 }
00821 }
00822
00823 LogDebug("") << " There are " << uselist.size() << " good stereo+rphi+zphi hits " ;
00825
00826 #ifdef EDM_ML_DEBUG
00827 std::ostringstream debugstr5;
00828 debugstr5 << " List of hits before uniqification " << " \n" ;
00829 for (unsigned int i = 0; i < uselist.size(); i++) {
00830 if ( uselist[i] ) {
00831 const SiStripRecHit2D* hit = hitlist[i];
00832 debugstr5 << " DetID " << ((hit)->geographicalId()).rawId()
00833 << " R " << rlist[i]
00834 << " Phi " << philist[i]
00835 << " Weight " << w2list[i]
00836 << " PhiPred " << (rlist[i]-scr)*phiVsRSlope
00837 << " Chi2 " << (philist[i]-(rlist[i]-scr)*phiVsRSlope)*(philist[i]-(rlist[i]-scr)*phiVsRSlope)*w2list[i]
00838 << " \n" ;
00839 }
00840 }
00841 debugstr5 << " \n\n\n" ;
00842
00843 debugstr5 << " Counting number of unique detectors " << " \n" ;
00844
00845 debugstr5 << " These are all the detectors with hits " << " \n";
00846 #endif
00847
00848
00849 std::vector<uint32_t> detIdList ;
00850
00851 for (unsigned int i = 0; i < uselist.size(); i++) {
00852 if (uselist[i]) {
00853 const SiStripRecHit2D* hit = hitlist[i];
00854 uint32_t detIDUsed = ((hit)->geographicalId()).rawId() ;
00855 #ifdef EDM_ML_DEBUG
00856 debugstr5<< " DetId " << detIDUsed << "\n";
00857 #endif
00858 detIdList.push_back(detIDUsed) ;
00859 }
00860 }
00861
00862 #ifdef EDM_ML_DEBUG
00863 debugstr5 << " There are " << detIdList.size() << " hits on detectors \n";
00864 #endif
00865
00866 std::sort(detIdList.begin(), detIdList.end());
00867 detIdList.erase(
00868 std::unique(detIdList.begin(), detIdList.end()), detIdList.end());
00869 #ifdef EDM_ML_DEBUG
00870 debugstr5 << " There are " << detIdList.size() << " unique detectors \n";
00871 #endif
00872
00873
00874
00875 #ifdef EDM_ML_DEBUG
00876 debugstr5 << " Looping over detectors to choose best hit " << " \n";
00877 #endif
00878
00879 for (unsigned int idet = 0 ; idet < detIdList.size() ; idet++ ) {
00880 for (unsigned int i = 0; i+1 < uselist.size(); i++) {
00881 if (uselist[i]) {
00882
00883 const SiStripRecHit2D* hit1 = hitlist[i];
00884 double r_hit1 = rlist[i];
00885 double phi_hit1 = philist[i];
00886 double w2_hit1 = w2list[i] ;
00887 double phi_pred1 = (r_hit1-scr)*phiVsRSlope ;
00888 double chi1 = (phi_hit1-phi_pred1)*(phi_hit1-phi_pred1)*w2_hit1;
00889 if(detIdList[idet]== ((hit1)->geographicalId()).rawId()) {
00890 for (unsigned int j = i+1; j < uselist.size(); j++) {
00891 if (uselist[j]) {
00892 const SiStripRecHit2D* hit2 = hitlist[j];
00893 if(detIdList[idet]== ((hit2)->geographicalId()).rawId()) {
00894 #ifdef EDM_ML_DEBUG
00895 debugstr5 << " Found 2 hits on same Si Detector "
00896 << ((hit2)->geographicalId()).rawId() << "\n";
00897 #endif
00898
00899 double r_hit2 = rlist[j];
00900 double phi_hit2 = philist[j];
00901 double w2_hit2 = w2list[j] ;
00902 double phi_pred2 = (r_hit2-scr)*phiVsRSlope ;
00903 double chi2 = (phi_hit2-phi_pred2)*(phi_hit2-phi_pred2)*w2_hit2;
00904 #ifdef EDM_ML_DEBUG
00905 debugstr5 << " Chi1 " << chi1 << " Chi2 " << chi2 <<"\n";
00906 #endif
00907 if( chi1< chi2 ){
00908 uselist[j] = 0;
00909 }else{
00910 uselist[i] = 0;
00911 }
00912
00913 }
00914 }
00915 }
00916
00917 }
00918 }
00919 }
00920
00921
00922 }
00923
00924
00925
00926
00927 for ( unsigned int i = 0; i < uselist.size(); i++ ) {
00928 if ( uselist[i] ) {
00929 double localchi2 = (philist[i]-(rlist[i]-scr)*phiVsRSlope)*(philist[i]-(rlist[i]-scr)*phiVsRSlope)*w2list[i] ;
00930 if(localchi2 > chi2HitMax ) {
00931 #ifdef EDM_ML_DEBUG
00932 const SiStripRecHit2D* hit = hitlist[i];
00933 debugstr5 << " Throwing out "
00934 <<" DetID " << ((hit)->geographicalId()).rawId()
00935 << " R " << rlist[i]
00936 << " Phi " << philist[i]
00937 << " Weight " << w2list[i]
00938 << " PhiPred " << (rlist[i]-scr)*phiVsRSlope
00939 << " Chi2 " << (philist[i]-(rlist[i]-scr)*phiVsRSlope)*(philist[i]-(rlist[i]-scr)*phiVsRSlope)*w2list[i]
00940 << " \n" ;
00941 #endif
00942 uselist[i]=0 ;
00943 }
00944 }
00945 }
00946
00947 #ifdef EDM_ML_DEBUG
00948 debugstr5 << " List of hits after uniqification " << " \n" ;
00949 for (unsigned int i = 0; i < uselist.size(); i++) {
00950 if ( uselist[i] ) {
00951 const SiStripRecHit2D* hit = hitlist[i];
00952 debugstr5 << " DetID " << ((hit)->geographicalId()).rawId()
00953 << " R " << rlist[i]
00954 << " Phi " << philist[i]
00955 << " Weight " << w2list[i]
00956 << " PhiPred " << (rlist[i]-scr)*phiVsRSlope
00957 << " Chi2 " << (philist[i]-(rlist[i]-scr)*phiVsRSlope)*(philist[i]-(rlist[i]-scr)*phiVsRSlope)*w2list[i]
00958 << " \n" ;
00959 }
00960 }
00961 debugstr5 << " \n\n\n" ;
00962 #endif
00963
00964
00965 unsigned int nHitsLeft =0;
00966 for (unsigned int i = 0; i < uselist.size(); i++) {
00967 if ( uselist[i] ) {
00968 nHitsLeft++;
00969 }
00970 }
00971 if(nHitsLeft < nHitsLeftMinimum ) {
00972 #ifdef EDM_ML_DEBUG
00973 debugstr5 << " Too few hits "<< nHitsLeft
00974 << " left - return false " << " \n";
00975 #endif
00976 return false ;
00977 }
00978 #ifdef EDM_ML_DEBUG
00979 LogDebug("") << debugstr5.str();
00980 #endif
00981
00982
00983
00984 bool done = false;
00985 double intercept = 0 ;
00986 double slope = 0 ;
00987 double chi2 = 0;
00988
00989 std::ostringstream debugstr4;
00990 debugstr4 <<" Calc of phi(r) "<<" \n";
00991
00992 while (!done) {
00993
00994
00995
00996
00997
00998
00999 double phiBar = 0.;
01000 double phiBarOld = 0.;
01001 double rBar = 0.;
01002 double rBarOld = 0.;
01003 double r2Bar = 0.;
01004 double r2BarOld = 0.;
01005 double phirBar = 0.;
01006 double phirBarOld = 0.;
01007 double totalWeight = 0.;
01008 double totalWeightOld = 0.;
01009 unsigned int uselist_size = uselist.size();
01010 for (unsigned int i = 0; i < uselist_size; i++) {
01011 if (uselist[i]) {
01012 double r = rlist[i];
01013 double phi = philist[i];
01014 double weight2 = w2list[i];
01015
01016 totalWeight = totalWeightOld + weight2 ;
01017
01018
01019
01020
01021 double totalWeightRatio = totalWeightOld/totalWeight ;
01022 double localWeightRatio = weight2/totalWeight ;
01023
01024 phiBar = phiBarOld*totalWeightRatio + phi*localWeightRatio ;
01025 rBar = rBarOld*totalWeightRatio + r*localWeightRatio ;
01026 r2Bar= r2BarOld*totalWeightRatio + r*r*localWeightRatio ;
01027 phirBar = phirBarOld*totalWeightRatio + phi*r*localWeightRatio ;
01028
01029 totalWeightOld = totalWeight ;
01030 phiBarOld = phiBar ;
01031 rBarOld = rBar ;
01032 r2BarOld = r2Bar ;
01033 phirBarOld = phirBar ;
01034 #ifdef EDM_ML_DEBUG
01035 debugstr4 << " totalWeight " << totalWeight
01036 << " totalWeightRatio " << totalWeightRatio
01037 << " localWeightRatio "<< localWeightRatio
01038 << " phiBar " << phiBar
01039 << " rBar " << rBar
01040 << " r2Bar " << r2Bar
01041 << " phirBar " << phirBar
01042 << " \n ";
01043 #endif
01044
01045 }
01046 }
01047 slope = (phirBar-phiBar*rBar)/(r2Bar-rBar*rBar);
01048 intercept = phiBar-slope*rBar ;
01049
01050 debugstr4 << " end of loop slope " << slope
01051 << " intercept " << intercept << " \n";
01052
01053
01054 chi2 = 0.;
01055 double biggest_normresid = -1.;
01056 unsigned int biggest_index = 0;
01057 for (unsigned int i = 0; i < uselist_size; i++) {
01058 if (uselist[i]) {
01059 double r = rlist[i];
01060 double phi = philist[i];
01061 double weight2 = w2list[i];
01062
01063 double normresid = weight2 * (phi - intercept - slope*r)*(phi - intercept - slope*r);
01064 chi2 += normresid;
01065
01066 if (normresid > biggest_normresid) {
01067 biggest_normresid = normresid;
01068 biggest_index = i;
01069 }
01070 }
01071 }
01072
01073 if (biggest_normresid > maxNormResid_) {
01074 #ifdef EDM_ML_DEBUG
01075 debugstr4 << "Dropping hit from fit due to Chi2 " << " \n" ;
01076 const SiStripRecHit2D* hit = hitlist[biggest_index];
01077 debugstr4 << " DetID " << ((hit)->geographicalId()).rawId()
01078 << " R " << rlist[biggest_index]
01079 << " Phi " << philist[biggest_index]
01080 << " Weight " << w2list[biggest_index]
01081 << " PhiPred " << (rlist[biggest_index]-scr)*phiVsRSlope
01082 << " Chi2 " << (philist[biggest_index]-(rlist[biggest_index]-scr)*phiVsRSlope)*(philist[biggest_index]-(rlist[biggest_index]-scr)*phiVsRSlope)*w2list[biggest_index]
01083 << " normresid " << biggest_normresid
01084 << " \n\n";
01085 #endif
01086 uselist[biggest_index] = false;
01087 }
01088 else {
01089 done = true;
01090 }
01091 }
01092 #ifdef EDM_ML_DEBUG
01093 debugstr4 <<" Fit "
01094 << " Intercept " << intercept
01095 << " slope " << slope
01096 << " chi2 " << chi2
01097 << " \n" ;
01098
01099 LogDebug("") << debugstr4.str() ;
01100 #endif
01101
01102
01103
01104
01105 const SiStripRecHit2D* innerhit = (SiStripRecHit2D*)(0);
01106 double innerhitRadius = -1.;
01107
01108
01109 std::vector<const TrackingRecHit*> outputHits;
01110
01111 std::vector<SiStripRecHit2D> outputRphiHits;
01112 std::vector<SiStripRecHit2D> outputStereoHits;
01113
01114 typedef edm::Ref<SiStripRecHit2DCollection,SiStripRecHit2D> SiStripRecHit2DRef;
01115
01116
01117 for (unsigned int i = 0; i < uselist.size(); i++) {
01118 if (uselist[i]) {
01119 double r = rlist[i];
01120 const SiStripRecHit2D* hit = hitlist[i];
01121
01122
01123 if (innerhit == (SiStripRecHit2D*)(0) || r < innerhitRadius) {
01124 innerhit = hit;
01125 innerhitRadius = r;
01126 }
01127
01128 if (typelist[i] == 0) {
01129 numberOfStereoHits++;
01130
01131
01132 outputHits.push_back(hit);
01133 outputStereoHits.push_back(*hit);
01134 }
01135 else if (typelist[i] == 1) {
01136 numberOfBarrelRphiHits++;
01137
01138
01139 outputHits.push_back(hit);
01140 outputRphiHits.push_back(*hit);
01141 }
01142 else if (typelist[i] == 2) {
01143 numberOfEndcapZphiHits++;
01144
01145
01146 outputHits.push_back(hit);
01147 outputRphiHits.push_back(*hit);
01148 }
01149 }
01150 }
01151
01152 unsigned int totalNumberOfHits = numberOfStereoHits + numberOfBarrelRphiHits + numberOfEndcapZphiHits;
01153 double reducedChi2 = (totalNumberOfHits > 2 ? chi2 / (totalNumberOfHits - 2) : 1e10);
01154
01155
01156 if (totalNumberOfHits >= minHits_ && reducedChi2 <= maxReducedChi2_) {
01157
01158 GlobalPoint position = tracker_p_->idToDet(innerhit->geographicalId())->surface().toGlobal(innerhit->localPosition());
01159
01160
01161
01162
01163
01164 double correct_pT = pT * phiVsRSlope / slope;
01165
01166
01167 double phi = intercept + slope*sqrt(position.x()*position.x() + position.y()*position.y()) + superclusterIn->position().phi();
01168
01169
01170 double pZ = correct_pT * zVsRSlope;
01171
01172
01173 GlobalVector momentum = GlobalVector(correct_pT*cos(phi), correct_pT*sin(phi), pZ);
01174
01175 if (chargeHypothesis > 0.) {
01176 redchi2_pos_ = chi2 / double(totalNumberOfHits - 2);
01177 position_pos_ = position;
01178 momentum_pos_ = momentum;
01179 innerhit_pos_ = innerhit;
01180 outputHits_pos_ = outputHits;
01181 outputRphiHits_pos_ = outputRphiHits;
01182 outputStereoHits_pos_ = outputStereoHits;
01183 phiVsRSlope_pos_ = phiVsRSlope;
01184 slope_pos_ = slope;
01185 intercept_pos_ = intercept;
01186 chi2_pos_ = chi2;
01187 ndof_pos_ = totalNumberOfHits - 2;
01188 correct_pT_pos_ = correct_pT;
01189 pZ_pos_ = pZ;
01190 zVsRSlope_pos_ = zVsRSlope;
01191 numberOfStereoHits_pos_ = numberOfStereoHits;
01192 numberOfBarrelRphiHits_pos_ = numberOfBarrelRphiHits;
01193 numberOfEndcapZphiHits_pos_ = numberOfEndcapZphiHits;
01194 }
01195 else {
01196 redchi2_neg_ = chi2 / double(totalNumberOfHits - 2);
01197 position_neg_ = position;
01198 momentum_neg_ = momentum;
01199 innerhit_neg_ = innerhit;
01200 outputHits_neg_ = outputHits;
01201 outputRphiHits_neg_ = outputRphiHits;
01202 outputStereoHits_neg_ = outputStereoHits;
01203 phiVsRSlope_neg_ = phiVsRSlope;
01204 slope_neg_ = slope;
01205 intercept_neg_ = intercept;
01206 chi2_neg_ = chi2;
01207 ndof_neg_ = totalNumberOfHits - 2;
01208 correct_pT_neg_ = correct_pT;
01209 pZ_neg_ = pZ;
01210 zVsRSlope_neg_ = zVsRSlope;
01211 numberOfStereoHits_neg_ = numberOfStereoHits;
01212 numberOfBarrelRphiHits_neg_ = numberOfBarrelRphiHits;
01213 numberOfEndcapZphiHits_neg_ = numberOfEndcapZphiHits;
01214 }
01215
01216 LogDebug("") << " return from projectFindBand with True \n" << std::endl ;
01217 return true;
01218 }
01219
01220
01221 LogDebug("") << " return from projectFindBand with False \n" << std::endl ;
01222 return false;
01223 }
01224
01225
01226
01227
01228
01229
01230
01231
01232