#include <RecoEgamma/EgammaElectronAlgos/interface/SiStripElectronAlgo.h>
Usage: <usage>
Definition at line 58 of file SiStripElectronAlgo.h.
SiStripElectronAlgo::SiStripElectronAlgo | ( | unsigned int | maxHitsOnDetId, | |
double | originUncertainty, | |||
double | phiBandWidth, | |||
double | maxNormResid, | |||
unsigned int | minHits, | |||
double | maxReducedChi2 | |||
) |
Definition at line 58 of file SiStripElectronAlgo.cc.
00064 : maxHitsOnDetId_(maxHitsOnDetId) 00065 , originUncertainty_(originUncertainty) 00066 , phiBandWidth_(phiBandWidth) 00067 , maxNormResid_(maxNormResid) 00068 , minHits_(minHits) 00069 , maxReducedChi2_(maxReducedChi2) 00070 { 00071 }
SiStripElectronAlgo::~SiStripElectronAlgo | ( | ) | [virtual] |
SiStripElectronAlgo::SiStripElectronAlgo | ( | const SiStripElectronAlgo & | ) | [private] |
void SiStripElectronAlgo::coarseBarrelMonoHitSelection | ( | std::vector< const SiStripRecHit2D * > & | monoHitPointersOut | ) | [private] |
void SiStripElectronAlgo::coarseEndcapMonoHitSelection | ( | std::vector< const SiStripRecHit2D * > & | monoHitPointersOut | ) | [private] |
void SiStripElectronAlgo::coarseHitSelection | ( | std::vector< const SiStripRecHit2D * > & | hitPointersOut, | |
bool | stereo, | |||
bool | endcap | |||
) | [private] |
Definition at line 357 of file SiStripElectronAlgo.cc.
References lat::endl(), false, edm::RangeMap< ID, C, P >::get(), id, edm::RangeMap< ID, C, P >::ids(), TrackerGeometry::idToDetUnit(), LogDebug, maxHitsOnDetId_, rphiHits_p_, stereoHits_p_, GeomDetEnumerators::TEC, theLayer, GeomDetEnumerators::TIB, GeomDetEnumerators::TID, GeomDetEnumerators::TOB, tracker_p_, and true.
Referenced by projectPhiBand().
00359 { 00360 // This function is not time-efficient. If you want to improve the 00361 // speed of the algorithm, you'll probably want to change this 00362 // function. There may be a more efficienct way to extract hits, 00363 // and it would definitely help to put a geographical cut on the 00364 // DetIds. (How does one determine the global position of a given 00365 // DetId? Is tracker_p_->idToDet(id)->surface().toGlobal(LocalPosition(0,0,0)) 00366 // expensive?) 00367 00368 // Loop over the detector ids 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 // Get the hits on this detector id 00373 SiStripRecHit2DCollection::range hits = (stereo ? stereoHits_p_->get(*id) : rphiHits_p_->get(*id)); 00374 00375 // Count the number of hits on this detector id 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 // Only take the hits if there aren't too many 00383 // (Would it be better to loop only once, fill a temporary list, 00384 // and copy that if numberOfHits <= maxHitsOnDetId_?) 00385 if (numberOfHits <= maxHitsOnDetId_) { 00386 for (SiStripRecHit2DCollection::const_iterator hit = hits.first; 00387 hit != hits.second; ++hit) { 00388 // check that hit is valid first ! 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(); // or ring ? 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(); // or ring or petal ? 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 } // end if this is the right subdetector 00431 } // end loop over hits 00432 } // end if this detector id doesn't have too many hits on it 00433 } // end loop over detector ids 00434 }
void SiStripElectronAlgo::coarseMatchedHitSelection | ( | std::vector< const SiStripMatchedRecHit2D * > & | coarseMatchedHitPointersOut | ) | [private] |
Definition at line 438 of file SiStripElectronAlgo.cc.
References lat::endl(), edm::RangeMap< ID, C, P >::get(), id, edm::RangeMap< ID, C, P >::ids(), LogDebug, matchedHits_p_, maxHitsOnDetId_, StripSubdetector::TIB, and StripSubdetector::TOB.
Referenced by projectPhiBand().
00439 { 00440 00441 // Loop over the detector ids 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 // Get the hits on this detector id 00446 SiStripMatchedRecHit2DCollection::range hits = matchedHits_p_->get(*id) ; 00447 00448 // Count the number of hits on this detector id 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 // Only take the hits if there aren't too many 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 } // end loop over hits 00469 00470 } // end if this detector id doesn't have too many hits on it 00471 } // end loop over detector ids 00472 00473 00474 }// end of matchedHitSelection
bool SiStripElectronAlgo::findElectron | ( | reco::SiStripElectronCollection & | electronOut, | |
TrackCandidateCollection & | trackCandidateOut, | |||
const reco::SuperClusterRef & | superclusterIn | |||
) |
Definition at line 150 of file SiStripElectronAlgo.cc.
References alongMomentum, chi2_neg_, chi2_pos_, correct_pT_neg_, correct_pT_pos_, HLT_VtxMuL3::errors, TrackingRecHit::geographicalId(), hitUsed_, TrackerGeometry::idToDet(), innerhit_neg_, innerhit_pos_, intercept_neg_, intercept_pos_, LogDebug, magneticField_p_, momentum_neg_, momentum_pos_, ndof_neg_, ndof_pos_, numberOfBarrelRphiHits_neg_, numberOfBarrelRphiHits_pos_, numberOfEndcapZphiHits_neg_, numberOfEndcapZphiHits_pos_, numberOfStereoHits_neg_, numberOfStereoHits_pos_, outputHits_neg_, outputHits_pos_, outputRphiHits_neg_, outputRphiHits_pos_, outputStereoHits_neg_, outputStereoHits_pos_, muonGeometry::perp(), phi, phiVsRSlope_neg_, phiVsRSlope_pos_, position_neg_, position_pos_, projectPhiBand(), edm::OwnVector< T, P >::push_back(), pZ_neg_, pZ_pos_, DetId::rawId(), redchi2_neg_, redchi2_pos_, slope_neg_, slope_pos_, python::multivaluedict::sort(), state, tracker_p_, z, zVsRSlope_neg_, and zVsRSlope_pos_.
Referenced by SiStripElectronProducer::produce().
00153 { 00154 // Try each of the two charge hypotheses, but only take one 00155 bool electronSuccess = projectPhiBand(-1., superclusterIn); 00156 bool positronSuccess = projectPhiBand( 1., superclusterIn); 00157 00158 // electron hypothesis did better than electron 00159 if ((electronSuccess && !positronSuccess) || 00160 (electronSuccess && positronSuccess && redchi2_neg_ <= redchi2_pos_)) { 00161 00162 // Initial uncertainty for tracking 00163 AlgebraicSymMatrix errors(5,1); // makes identity 5x5 matrix, indexed from (1,1) to (5,5) 00164 errors(1,1) = 3.; // uncertainty**2 in 1/momentum 00165 errors(2,2) = 0.01; // uncertainty**2 in lambda (lambda == pi/2 - polar angle theta) 00166 errors(3,3) = 0.0001; // uncertainty**2 in phi 00167 errors(4,4) = 0.01; // uncertainty**2 in x_transverse (where x is in cm) 00168 errors(5,5) = 0.01; // uncertainty**2 in y_transverse (where y is in cm) 00169 00170 // JED Debugging possible double hit sort problem 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 // end of dump 00185 00186 00187 00188 // JED call dump 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 // end of dump 00210 00211 LogDebug("")<< debugstr6.str(); 00212 00213 00214 //create an OwnVector needed by the classes which will be stored to the Event 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; // ShR: fix memory leak reported per perfrmance task force 00254 00255 return true; 00256 } 00257 00258 // positron hypothesis did better than electron 00259 if ((!electronSuccess && positronSuccess) || 00260 (electronSuccess && positronSuccess && redchi2_neg_ > redchi2_pos_)) { 00261 00262 // Initial uncertainty for tracking 00263 AlgebraicSymMatrix errors(5,1); // makes identity 5x5 matrix, indexed from (1,1) to (5,5) 00264 errors(1,1) = 3.; // uncertainty**2 in 1/momentum 00265 errors(2,2) = 0.01; // uncertainty**2 in lambda (lambda == pi/2 - polar angle theta) 00266 errors(3,3) = 0.0001; // uncertainty**2 in phi 00267 errors(4,4) = 0.01; // uncertainty**2 in x_transverse (where x is in cm) 00268 errors(5,5) = 0.01; // uncertainty**2 in y_transverse (where y is in cm) 00269 00270 // JED Debugging possible double hit sort problem 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 // end of dump 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 // JED Debugging possible double hit sort problem 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 // end of dump 00307 LogDebug("") << debugstr7.str(); 00308 00309 //create an OwnVector needed by the classes which will be stored to the Event 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; // JED: fix of 2nd memory leak reported per perfrmance task force 00346 00347 return true; 00348 } 00349 00350 return false; 00351 }
const SiStripElectronAlgo& SiStripElectronAlgo::operator= | ( | const SiStripElectronAlgo & | ) | [private] |
void SiStripElectronAlgo::prepareEvent | ( | const edm::ESHandle< TrackerGeometry > & | tracker, | |
const edm::Handle< SiStripRecHit2DCollection > & | rphiHits, | |||
const edm::Handle< SiStripRecHit2DCollection > & | stereoHits, | |||
const edm::Handle< SiStripMatchedRecHit2DCollection > & | matchedHits, | |||
const edm::ESHandle< MagneticField > & | magneticField | |||
) |
Referenced by SiStripElectronProducer::produce().
bool SiStripElectronAlgo::projectPhiBand | ( | float | chargeHypothesis, | |
const reco::SuperClusterRef & | superclusterIn | |||
) | [private] |
Definition at line 482 of file SiStripElectronAlgo.cc.
References chi2_neg_, chi2_pos_, coarseHitSelection(), coarseMatchedHitSelection(), correct_pT_neg_, correct_pT_pos_, funct::cos(), lat::endl(), relval_parameters_module::energy, false, TrackingRecHit::geographicalId(), hitUsed_, i, TrackerGeometry::idToDet(), TrackerGeometry::idToDetUnit(), innerhit_neg_, innerhit_pos_, intercept_neg_, intercept_pos_, MagneticField::inTesla(), j, BaseSiTrackerRecHit2DLocalPos::localPosition(), LogDebug, magneticField_p_, matchedHitUsed_, maxNormResid_, maxReducedChi2_, minHits_, momentum_neg_, momentum_pos_, ndof_neg_, ndof_pos_, numberOfBarrelRphiHits_neg_, numberOfBarrelRphiHits_pos_, numberOfEndcapZphiHits_neg_, numberOfEndcapZphiHits_pos_, numberOfStereoHits_neg_, numberOfStereoHits_pos_, originUncertainty_, outputHits_neg_, outputHits_pos_, outputRphiHits_neg_, outputRphiHits_pos_, outputStereoHits_neg_, outputStereoHits_pos_, PV3DBase< T, PVType, FrameType >::phi(), phi, phiBandWidth_, phiVsRSlope_neg_, phiVsRSlope_pos_, position_neg_, position_pos_, edm::RefVector< C, T, F >::push_back(), pZ_neg_, pZ_pos_, r, redchi2_neg_, redchi2_pos_, rphiHits_hp_, rphiKey_, funct::sin(), slope, slope_neg_, slope_pos_, python::multivaluedict::sort(), funct::sqrt(), stereoHits_hp_, stereoKey_, GeomDetEnumerators::TIB, GeomDetEnumerators::TOB, GeomDet::toGlobal(), tracker_p_, true, unwrapPhi(), PV3DBase< T, PVType, FrameType >::x(), PV3DBase< T, PVType, FrameType >::y(), PV3DBase< T, PVType, FrameType >::z(), z, zVsRSlope_neg_, and zVsRSlope_pos_.
Referenced by findElectron().
00483 { 00484 // This algorithm projects a phi band into the tracker three times: 00485 // (a) for all stereo hits, (b) for barrel rphi hits, and (c) for 00486 // endcap zphi hits. While accumulating stereo hits in step (a), 00487 // we fit r vs z to a line. This resolves the ambiguity in z for 00488 // rphi hits and the ambiguity in r for zphi hits. We can then cut 00489 // on the z of rphi hits (a little wider than one strip length), 00490 // and we can convert the z of zphi hits into r to apply the phi 00491 // band cut. (We don't take advantage of the endcap strips' 00492 // segmentation in r.) 00493 // 00494 // As we project a phi band into the tracker, we count hits within 00495 // that band and performs a linear fit for phi vs r. The number of 00496 // hits and reduced chi^2 from the fit are used to select a good 00497 // candidate. 00498 00499 // set limits on Si hits - smallest error that makes sense = 1 micron ? 00500 static const double rphiHitSmallestError = 0.0001 ; 00501 static const double stereoHitSmallestError = 0.0001 ; 00502 //not used since endcap is not implemented 00503 // static const double zphiHitSmallestError = 0.0001 ; 00504 00505 00506 static const double stereoPitchAngle = 0.100 ; // stereo angle in rad 00507 static const double cos2SiPitchAngle = cos(stereoPitchAngle)*cos(stereoPitchAngle) ; 00508 static const double sin2SiPitchAngle = sin(stereoPitchAngle)*sin(stereoPitchAngle) ; 00509 // overall misalignment fudge to be added in quad to position errors. 00510 // this is a rough approx to values reported in tracking meet 5/16/2007 00511 static const double rphiErrFudge = 0.0200 ; 00512 static const double stereoErrFudge = 0.0200 ; 00513 00514 // max chi2 of a hit on an SiDet relative to the prediction 00515 static const double chi2HitMax = 25.0 ; 00516 00517 // Minimum number of hits to consider on a candidate 00518 static const unsigned int nHitsLeftMinimum = 3 ; 00519 00520 // Create and fill vectors of pointers to hits 00521 std::vector<const SiStripRecHit2D*> stereoHits; 00522 std::vector<const SiStripRecHit2D*> rphiBarrelHits; 00523 std::vector<const SiStripRecHit2D*> zphiEndcapHits; 00524 00525 // stereo? endcap? 00526 coarseHitSelection(stereoHits, true, false); 00527 00528 // skip endcap stereo for now 00529 // LogDebug("") << " Getting endcap stereo hits " ; 00530 // coarseHitSelection(stereoHits, true, true); 00531 std::ostringstream debugstr1; 00532 debugstr1 << " Getting barrel rphi hits " << " \n" ; 00533 00534 coarseHitSelection(rphiBarrelHits, false, false); 00535 00536 // LogDebug("") << " Getting endcap zphi hits " ; 00537 // coarseHitSelection(zphiEndcapHits, false, true); 00538 00539 debugstr1 << " Getting matched hits " << " \n" ; 00540 std::vector<const SiStripMatchedRecHit2D*> matchedHits; 00541 coarseMatchedHitSelection(matchedHits); 00542 00543 00544 // Determine how to project from the supercluster into the tracker 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 // cf Jackson p. 581-2, a little geometry 00550 double phiVsRSlope = -3.00e-3 * chargeHypothesis * magneticField_p_->inTesla(GlobalPoint(superclusterIn->x(), superclusterIn->y(), 0.)).z() / pT / 2.; 00551 00552 // Shorthand for supercluster radius, z 00553 const double scr = superclusterIn->position().rho(); 00554 const double scz = superclusterIn->position().z(); 00555 00556 // These are used to fit all hits to a line in phi(r) 00557 std::vector<bool> uselist; 00558 std::vector<double> rlist, philist, w2list; 00559 std::vector<int> typelist; // stereo = 0, rphi barrel = 1, and zphi disk = 2 (only used in this function) 00560 std::vector<const SiStripRecHit2D*> hitlist; 00561 00562 std::vector<bool> matcheduselist; 00563 std::vector<const SiStripMatchedRecHit2D*> matchedhitlist; 00564 00565 // These are used to fit the stereo hits to a line in z(r), constrained to pass through supercluster 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 // Loop over all matched hits 00581 // make a list of good matched rechits. 00582 // in the stereo and rphi loops check to see if the hit is associated with a matchedhit 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 // Calculate the 3-D position of this hit 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()); // phi is relative to supercluster 00596 double z = position.z(); 00597 00598 // Cut a triangle in the z-r plane using the supercluster's eta/dip angle information 00599 // and the fact that the electron originated *near* the origin 00600 if ((-originUncertainty_ + (scz + originUncertainty_)*(r/scr)) < z && z < (originUncertainty_ + (scz - originUncertainty_)*(r/scr))) { 00601 00602 // Cut a narrow band around the supercluster's projection in phi 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 // Use this hit to fit z(r) 00612 zSlopeFitNumer += -(scr - r) * (z - scz); 00613 zSlopeFitDenom += (scr - r) * (scr - r); 00614 00615 } // end cut on phi band 00616 } // end cut on electron originating *near* the origin 00617 } // end assign disjoint sets of hits to electrons 00618 } // end loop over matched hits 00619 00620 // Calculate the linear fit for z(r) 00621 double zVsRSlope; 00622 if (zSlopeFitDenom > 0.) { 00623 zVsRSlope = zSlopeFitNumer / zSlopeFitDenom; 00624 } 00625 else { 00626 // zVsRSlope assumes electron is from origin if there were no stereo hits 00627 zVsRSlope = scz/scr; 00628 } 00629 00630 // // Loop over all stereo hits 00631 LogDebug("") << " Loop over stereo hits" << " \n"; 00632 00633 // check if the stereo hit is matched to one of the matched hit 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 // Calculate the 3-D position of this hit 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()); // phi is relative to supercluster 00642 // double z_stereo = position.z(); 00643 00644 // stereo is has a pitch of 100 mrad - so consider both components 00645 double r_stereo_err = sqrt((*hit)->localPositionError().xx()*cos2SiPitchAngle + 00646 (*hit)->localPositionError().yy()*sin2SiPitchAngle ) ; 00647 00648 00649 00650 // make sure that the error for this hit is sensible, ie > 1 micron 00651 // otherwise skip this hit 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 // LogDebug("")<< " This hit is matched " << tracker_p_->idToDet(matchedhitlist[i]->stereoHit()->geographicalId())->surface().toGlobal(matchedhitlist[i]->stereoHit()->localPosition()) << std::endl; 00668 // break ; 00669 } 00670 } // check if matcheduselist okay 00671 }// loop over matched hits 00672 00673 if(thisHitIsMatched) { 00674 // Use this hit to fit phi(r) 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)); // weight**2 == 1./uncertainty**2 00679 typelist.push_back(0); 00680 hitlist.push_back(*hit); 00681 } // thisHitIsMatched 00682 } // if(!hitUsed) 00683 00684 } // end of check on hit position error size 00685 00686 } // end loop over stereo hits 00687 00688 LogDebug("") << " There are " << uselist.size() << " good hits after stereo loop " ; 00689 00690 00691 // Loop over barrel rphi hits 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 // Calculate the 2.5-D position of this hit 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()); // phi is relative to supercluster 00702 double z = position.z(); 00703 double r_mono_err = sqrt((*hit)->localPositionError().xx()) ; 00704 00705 // only consider hits with errors that make sense 00706 if( r_mono_err > rphiHitSmallestError) { 00707 // inflate the reported error 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 } // check if matcheduselist okay 00727 }// loop over matched hits 00728 00729 00730 if( thisHitIsMatched ) { 00731 // Use this hit to fit phi(r) 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)); // weight**2 == 1./uncertainty**2 00736 typelist.push_back(1); 00737 hitlist.push_back(*hit); 00738 rphiMatchedCounter++; 00739 } // end of matched hit check 00740 00741 } else { 00742 00743 00744 // The expected z position of this hit, according to the z(r) fit 00745 double zFit = zVsRSlope * (r - scr) + scz; 00746 00747 // Cut on the Z of the strip 00748 // TIB strips are 11 cm long, TOB strips are 19 cm long (can I get these from a function?) 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 // Cut a narrow band around the supercluster's projection in phi 00755 if (unwrapPhi((r-scr)*phiVsRSlope - phiBandWidth_) < phi && phi < unwrapPhi((r-scr)*phiVsRSlope + phiBandWidth_)) { 00756 00757 // Use this hit to fit phi(r) 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)); // weight**2 == 1./uncertainty**2 00762 typelist.push_back(1); 00763 hitlist.push_back(*hit); 00764 rphiUnMatchedCounter++; 00765 00766 } // end cut on phi band 00767 } // end cut on strip z 00768 } // loop over TIB/TOB layer 1,2 00769 } // end assign disjoint sets of hits to electrons 00770 } // end of check on rphi hit position error size 00771 } // end loop over barrel rphi hits 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 // Loop over endcap zphi hits 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 // Calculate the 2.5-D position of this hit 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()); // phi is relative to supercluster 00797 // double r=sqrt(position.x()*position.x()+position.y()*position.y()) ; 00798 00799 // The expected r position of this hit, according to the z(r) fit 00800 double rFit = (z - scz)/zVsRSlope + scr; 00801 00802 // I don't know the r widths of the endcap strips, otherwise I 00803 // would apply a cut on r similar to the rphi z cut 00804 00805 // Cut a narrow band around the supercluster's projection in phi, 00806 // and be sure the hit isn't in a reflected band (extrapolation of large z differences into negative r) 00807 if (rFit > 0. && 00808 unwrapPhi((rFit-scr)*phiVsRSlope - phiBandWidth_) < phi && phi < unwrapPhi((rFit-scr)*phiVsRSlope + phiBandWidth_)) { 00809 00810 // Use this hit to fit phi(r) 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)); // weight**2 == 1./uncertainty**2 00815 typelist.push_back(2); 00816 hitlist.push_back(*hit); 00817 00818 } // end cut on phi band 00819 } // end assign disjoint sets of hits to electrons 00820 } // end loop over endcap zphi hits 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 // Loop over hits, and find the best hit for each SiDetUnit - keep only those 00845 // get a list of DetIds in uselist 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 // now sort and then uniq this list of detId 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 //now we have a list of unique detectors used 00865 00866 00867 00868 debugstr5 << " Looping over detectors to choose best hit " << " \n"; 00869 // Loop over detectors ID and hits to create list of hits on same DetId 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 // Get Chi2 of this hit relative to predicted hit 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 // Get Chi2 of this hit relative to predicted hit 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 } // end of Det check 00901 } // end of j- usehit check 00902 } // end of j hit list loop 00903 00904 } // end of detector check 00905 } // end of uselist check 00906 } // end of i-hit list loop 00907 00908 00909 } // end of DetId loop 00910 00911 00912 00913 // now let's through out hits with a predicted chi > chi2HitMax 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 // need to check that there are more than 2 hits left here! 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 // Calculate a linear phi(r) fit and drop hits until the biggest contributor to chi^2 is less than maxNormResid_ 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 // Use an iterative update of <psi>, <r> etc instead in an 00975 // attempt to minize divisions of large numbers 00976 // The linear fit psi = slope*r + intercept 00977 // slope is (<psi*r>-<psi>*<r>) / (<r^2>-<r>^2>) 00978 // intercept is <psi> - slope*<r> 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 //weight2 is 1/sigma^2. Typically sigma is 100micron pitch 01000 // over root(12) = 30 microns so weight2 is about 10^5-10^6 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 } // end of use hit loop 01027 } // end of hit loop to calculate a linear fit 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 // Calculate chi^2 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 } // end loop over hits to calculate chi^2 and find its biggest contributer 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 } // end loop over trial fits 01071 01072 debugstr4 <<" Fit " 01073 << " Intercept " << intercept 01074 << " slope " << slope 01075 << " chi2 " << chi2 01076 << " \n" ; 01077 01078 LogDebug("") << debugstr4.str() ; 01079 01080 01081 // Now we have intercept, slope, and chi2; uselist to tell us which hits are used, and hitlist for the hits 01082 01083 // Identify the innermost hit 01084 const SiStripRecHit2D* innerhit = (SiStripRecHit2D*)(0); 01085 double innerhitRadius = -1.; // meaningless until innerhit is defined 01086 01087 // Copy hits into an OwnVector, which we put in the TrackCandidate 01088 std::vector<const TrackingRecHit*> outputHits; 01089 // Reference rphi and stereo hits into RefVectors, which we put in the SiStripElectron 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 // Keep track of the innermost hit 01102 if (innerhit == (SiStripRecHit2D*)(0) || r < innerhitRadius) { 01103 innerhit = hit; 01104 innerhitRadius = r; 01105 } 01106 01107 if (typelist[i] == 0) { 01108 numberOfStereoHits++; 01109 01110 // Copy this hit for the TrajectorySeed 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 // Copy this hit for the TrajectorySeed 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 // Copy this hit for the TrajectorySeed 01125 outputHits.push_back(hit); 01126 outputRphiHits.push_back(SiStripRecHit2DRef(*rphiHits_hp_, rphiKey_[hit])); 01127 } 01128 } 01129 } // end loop over all hits, after having culled the ones with big residuals 01130 01131 unsigned int totalNumberOfHits = numberOfStereoHits + numberOfBarrelRphiHits + numberOfEndcapZphiHits; 01132 double reducedChi2 = (totalNumberOfHits > 2 ? chi2 / (totalNumberOfHits - 2) : 1e10); 01133 01134 // Select this candidate if it passes minHits_ and maxReducedChi2_ cuts 01135 if (totalNumberOfHits >= minHits_ && reducedChi2 <= maxReducedChi2_) { 01136 // GlobalTrajectoryParameters evaluated at the position of the innerhit 01137 GlobalPoint position = tracker_p_->idToDet(innerhit->geographicalId())->surface().toGlobal(innerhit->localPosition()); 01138 01139 // Use our phi(r) linear fit to correct pT (pT is inversely proportional to slope) 01140 // (By applying a correction instead of going back to first 01141 // principles, any correction to the phiVsRSlope definition 01142 // above will be automatically propagated here.) 01143 double correct_pT = pT * phiVsRSlope / slope; 01144 01145 // Our phi(r) linear fit returns phi relative to the supercluster phi for a given radius 01146 double phi = intercept + slope*sqrt(position.x()*position.x() + position.y()*position.y()) + superclusterIn->position().phi(); 01147 01148 // Our z(r) linear fit gives us a better measurement of eta/dip angle 01149 double pZ = correct_pT * zVsRSlope; 01150 01151 // Now we can construct a trajectory momentum out of linear fits to hits 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 } // end if this is a good electron candidate 01198 01199 // Signal for a failed electron candidate 01200 LogDebug("") << " return from projectFindBand with False \n" << std::endl ; 01201 return false; 01202 }
double SiStripElectronAlgo::unwrapPhi | ( | double | phi | ) | const [inline, private] |
Definition at line 110 of file SiStripElectronAlgo.h.
Referenced by projectPhiBand().
00110 { 00111 while (phi > M_PI) { phi -= 2.*M_PI; } 00112 while (phi < -M_PI) { phi += 2.*M_PI; } 00113 return phi; 00114 }
double SiStripElectronAlgo::chi2_neg_ [private] |
Definition at line 178 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().
double SiStripElectronAlgo::chi2_pos_ [private] |
Definition at line 158 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().
double SiStripElectronAlgo::correct_pT_neg_ [private] |
Definition at line 180 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().
double SiStripElectronAlgo::correct_pT_pos_ [private] |
Definition at line 160 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().
std::map<const TrackingRecHit*, bool> SiStripElectronAlgo::hitUsed_ [private] |
Definition at line 142 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().
const SiStripRecHit2D* SiStripElectronAlgo::innerhit_neg_ [private] |
Definition at line 171 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().
const SiStripRecHit2D* SiStripElectronAlgo::innerhit_pos_ [private] |
Definition at line 149 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().
double SiStripElectronAlgo::intercept_neg_ [private] |
Definition at line 177 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().
double SiStripElectronAlgo::intercept_pos_ [private] |
Definition at line 157 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().
const MagneticField* SiStripElectronAlgo::magneticField_p_ [private] |
Definition at line 131 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().
const edm::Handle<SiStripMatchedRecHit2DCollection>* SiStripElectronAlgo::matchedHits_hp_ [private] |
Definition at line 135 of file SiStripElectronAlgo.h.
const SiStripMatchedRecHit2DCollection* SiStripElectronAlgo::matchedHits_p_ [private] |
std::map<const TrackingRecHit*, bool> SiStripElectronAlgo::matchedHitUsed_ [private] |
std::map<const SiStripMatchedRecHit2D*, unsigned int> SiStripElectronAlgo::matchedKey_ [private] |
Definition at line 140 of file SiStripElectronAlgo.h.
unsigned int SiStripElectronAlgo::maxHitsOnDetId_ [private] |
Definition at line 119 of file SiStripElectronAlgo.h.
Referenced by coarseHitSelection(), and coarseMatchedHitSelection().
double SiStripElectronAlgo::maxNormResid_ [private] |
double SiStripElectronAlgo::maxReducedChi2_ [private] |
unsigned int SiStripElectronAlgo::minHits_ [private] |
Definition at line 170 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().
Definition at line 148 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().
int SiStripElectronAlgo::ndof_neg_ [private] |
Definition at line 179 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().
int SiStripElectronAlgo::ndof_pos_ [private] |
Definition at line 159 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().
unsigned SiStripElectronAlgo::numberOfBarrelRphiHits_neg_ [private] |
Definition at line 184 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().
unsigned int SiStripElectronAlgo::numberOfBarrelRphiHits_pos_ [private] |
Definition at line 165 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().
unsigned SiStripElectronAlgo::numberOfEndcapZphiHits_neg_ [private] |
Definition at line 185 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().
unsigned int SiStripElectronAlgo::numberOfEndcapZphiHits_pos_ [private] |
Definition at line 166 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().
unsigned int SiStripElectronAlgo::numberOfMatchedHits_pos_ [private] |
Definition at line 163 of file SiStripElectronAlgo.h.
unsigned SiStripElectronAlgo::numberOfStereoHits_neg_ [private] |
Definition at line 183 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().
unsigned int SiStripElectronAlgo::numberOfStereoHits_pos_ [private] |
Definition at line 164 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().
double SiStripElectronAlgo::originUncertainty_ [private] |
std::vector<const TrackingRecHit*> SiStripElectronAlgo::outputHits_neg_ [private] |
Definition at line 172 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().
std::vector<const TrackingRecHit*> SiStripElectronAlgo::outputHits_pos_ [private] |
Definition at line 150 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().
Definition at line 153 of file SiStripElectronAlgo.h.
Definition at line 173 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().
Definition at line 151 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().
Definition at line 174 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().
Definition at line 152 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().
double SiStripElectronAlgo::phiBandWidth_ [private] |
double SiStripElectronAlgo::phiVsRSlope_neg_ [private] |
Definition at line 175 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().
double SiStripElectronAlgo::phiVsRSlope_pos_ [private] |
Definition at line 155 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().
Definition at line 169 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().
Definition at line 147 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().
double SiStripElectronAlgo::pZ_neg_ [private] |
Definition at line 181 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().
double SiStripElectronAlgo::pZ_pos_ [private] |
Definition at line 161 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().
double SiStripElectronAlgo::redchi2_neg_ [private] |
Definition at line 168 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().
double SiStripElectronAlgo::redchi2_pos_ [private] |
Definition at line 146 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().
const edm::Handle<SiStripRecHit2DCollection>* SiStripElectronAlgo::rphiHits_hp_ [private] |
const SiStripRecHit2DCollection* SiStripElectronAlgo::rphiHits_p_ [private] |
std::map<const SiStripRecHit2D*, unsigned int> SiStripElectronAlgo::rphiKey_ [private] |
double SiStripElectronAlgo::slope_neg_ [private] |
Definition at line 176 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().
double SiStripElectronAlgo::slope_pos_ [private] |
Definition at line 156 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().
const edm::Handle<SiStripRecHit2DCollection>* SiStripElectronAlgo::stereoHits_hp_ [private] |
const SiStripRecHit2DCollection* SiStripElectronAlgo::stereoHits_p_ [private] |
std::map<const SiStripRecHit2D*, unsigned int> SiStripElectronAlgo::stereoKey_ [private] |
const TrackerGeometry* SiStripElectronAlgo::tracker_p_ [private] |
Definition at line 127 of file SiStripElectronAlgo.h.
Referenced by coarseHitSelection(), findElectron(), and projectPhiBand().
double SiStripElectronAlgo::zVsRSlope_neg_ [private] |
Definition at line 182 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().
double SiStripElectronAlgo::zVsRSlope_pos_ [private] |
Definition at line 162 of file SiStripElectronAlgo.h.
Referenced by findElectron(), and projectPhiBand().