CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/RecoTracker/RoadSearchSeedFinder/src/RoadSearchCircleSeed.cc

Go to the documentation of this file.
00001 //
00002 // Package:         RecoTracker/RoadSearchSeedFinder
00003 // Class:           RoadSearchCircleSeed
00004 // 
00005 // Description:     circle from three global points in 2D 
00006 //                  all data members restricted to 2 dimensions
00007 //
00008 // Original Author: Oliver Gutsche, gutsche@fnal.gov
00009 // Created:         Mon Jan 22 21:42:35 UTC 2007
00010 //
00011 // $Author: mkirn $
00012 // $Date: 2007/09/07 16:28:52 $
00013 // $Revision: 1.6 $
00014 //
00015 
00016 #include <cmath>
00017 
00018 #include "RecoTracker/RoadSearchSeedFinder/interface/RoadSearchCircleSeed.h"
00019 #include "RecoTracker/TkSeedGenerator/interface/FastCircle.h"
00020 
00021 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00022 
00023 #include "DataFormats/SiStripDetId/interface/StripSubdetector.h"
00024 
00025 RoadSearchCircleSeed::RoadSearchCircleSeed(const TrackingRecHit *hit1,
00026                                            const TrackingRecHit *hit2,
00027                                            const TrackingRecHit *hit3,
00028                                            GlobalPoint &point1,
00029                                            GlobalPoint &point2,
00030                                            GlobalPoint &point3) { 
00031 
00032   hits_.reserve(3);
00033   hits_.push_back(hit1);
00034   hits_.push_back(hit2);
00035   hits_.push_back(hit3);
00036 
00037   points_.reserve(3);
00038   points_.push_back(point1);
00039   points_.push_back(point2);
00040   points_.push_back(point3);
00041 
00042   FastCircle kreis(point1,
00043                    point2,
00044                    point3);
00045 
00046   if ( !kreis.isValid() ) {
00047     // line
00048     type_ = straightLine;
00049     inBarrel_ = true; // Not used for lines
00050     center_ = GlobalPoint(0,0,0);
00051     radius_ = 0;
00052     impactParameter_ = 0;
00053   } else {
00054     type_ = circle;
00055     inBarrel_        = calculateInBarrel();
00056     radius_          = kreis.rho();
00057     center_          = GlobalPoint(kreis.x0(),kreis.y0(),0);
00058     impactParameter_ = calculateImpactParameter(center_,radius_);
00059   }
00060 
00061 }
00062 
00063 RoadSearchCircleSeed::RoadSearchCircleSeed(const TrackingRecHit *hit1,
00064                                            const TrackingRecHit *hit2,
00065                                            GlobalPoint &point1,
00066                                            GlobalPoint &point2) { 
00067   //
00068   // straight line constructor
00069   //
00070 
00071   hits_.reserve(2);
00072   hits_.push_back(hit1);
00073   hits_.push_back(hit2);
00074 
00075   points_.reserve(2);
00076   points_.push_back(point1);
00077   points_.push_back(point2);
00078 
00079   type_ = straightLine;
00080   inBarrel_ = true; // Not used for lines
00081   center_ = GlobalPoint(0,0,0);
00082   radius_ = 0;
00083   impactParameter_ = 0;
00084 
00085 }
00086 
00087 RoadSearchCircleSeed::~RoadSearchCircleSeed() {
00088 }
00089 
00090 bool RoadSearchCircleSeed::calculateInBarrel() {
00091   //
00092   // returns true if all hits are in the barrel,
00093   // otherwise returns false
00094   //
00095 
00096   for (std::vector<const TrackingRecHit*>::const_iterator hit = hits_.begin();
00097        hit != hits_.end(); ++hit) {
00098     if ((*hit)->geographicalId().subdetId() == StripSubdetector::TEC) {
00099       return false;
00100     }
00101   }
00102   
00103   return true;
00104 }
00105 
00106 double RoadSearchCircleSeed::calculateImpactParameter(GlobalPoint &center,
00107                                                       double radius) {
00108   //
00109   // calculate impact parameter to (0,0,0) from center and radius of circle
00110   //
00111 
00112   double d = std::sqrt( center.x() * center.x() +
00113                         center.y() * center.y() );
00114 
00115   return std::abs(d-radius);
00116 }
00117 
00118 double RoadSearchCircleSeed::calculateEta(double theta) const {
00119   //
00120   // calculate eta from theta
00121   //
00122 
00123   return -1.*std::log(std::tan(theta/2.));
00124 }
00125 
00126 double RoadSearchCircleSeed::Theta() const {
00127   //
00128   // calculate the theta of the seed
00129   // by taking the average theta of all
00130   // the lines formed by combinations of
00131   // hits in the seed
00132   // 
00133   // Note:  A faster implementation would
00134   // calculate in the constructor, save, and
00135   // return the member here.  This implementation
00136   // minimizes the memory footprint.
00137   //
00138 
00139   // Form all the possible lines
00140   std::vector<LineRZ> lines;
00141   for (std::vector<GlobalPoint>::const_iterator point1 = points_.begin();
00142        point1 != points_.end(); ++point1) {
00143     for (std::vector<GlobalPoint>::const_iterator point2 = point1+1;
00144          point2 != points_.end(); ++point2) {
00145       lines.push_back(LineRZ(*point1, *point2));
00146     }
00147   }
00148   
00149   double netTheta = 0.;
00150   for (std::vector<LineRZ>::const_iterator line = lines.begin();
00151        line != lines.end(); ++line){
00152     netTheta += line->Theta();
00153   }
00154   return netTheta/(double)lines.size();
00155 }
00156 
00157 double RoadSearchCircleSeed::Phi0() const {
00158   //
00159   // calculate the angle in the x-y plane
00160   // of the momentum vector at the point of
00161   // closest approach to (0,0,0)
00162   //
00163   // Note:  A faster implementation would
00164   // calculate in the constructor, save, and
00165   // return the member here.  This implementation
00166   // minimizes the memory footprint.
00167   //
00168 
00169   // Calculate phi as the average phi of all
00170   // lines formed by combinations of hits if
00171   // this is a straight line
00172   if (type_ == straightLine) {
00173     std::vector<LineXY> lines;
00174     for (std::vector<GlobalPoint>::const_iterator point1 = points_.begin();
00175          point1 != points_.end(); ++point1) {
00176       for (std::vector<GlobalPoint>::const_iterator point2 = point1+1;
00177            point2 != points_.end(); ++point2) {
00178         lines.push_back(LineXY(*point1,*point2));
00179       }
00180     }
00181     double netPhi = 0.;
00182     for (std::vector<LineXY>::const_iterator line = lines.begin();
00183          line != lines.end(); ++line) {
00184       netPhi += line->Phi();
00185     }
00186     return netPhi/(double)lines.size();
00187   } // END calculation for linear seeds
00188 
00189   // This calculation is not valid for seeds which do not exit
00190   // the tracking detector (lines always exit)
00191   else if (2.*Radius()+ImpactParameter()<110) {
00192     return 100000.;
00193   }
00194 
00195   // circular seeds
00196   else {
00197     double phi = 100000.;
00198     double centerPhi = center_.barePhi();
00199 
00200     // Find the first hit in time, which determines the direction of
00201     // the momentum vector (tangent to the circle at the point of
00202     // closest approach, clockwise or counter-clockwise).
00203     // The first hit in time is always the hit with the smallest
00204     // value r as long as the track exits the tracking detector.
00205     GlobalPoint firstPoint = points_[0];
00206     for (unsigned int i=1; i<points_.size(); ++i) {
00207       if (firstPoint.perp() > points_[i].perp()) {
00208         firstPoint = points_[i];
00209       }
00210     }
00211     
00212     // Get the next hit, firstPoint is at the point of
00213     // closest approach and cannot be used to
00214     // determine the direction of the initial
00215     // momentum vector
00216     if (firstPoint.barePhi() == centerPhi) {
00217       GlobalPoint nextHit = points_[0];
00218       for (unsigned int i=1; i<points_.size(); ++i) {
00219         if (nextHit.perp()  == firstPoint.perp() || 
00220             (firstPoint.perp()!= points_[i].perp() &&
00221              nextHit.perp() >  points_[i].perp())) {
00222           nextHit = points_[i];
00223         }
00224       }
00225       firstPoint = nextHit;
00226     }
00227   
00228     // Find the direction of the momentum vector
00229     if (firstPoint.barePhi() > centerPhi) {
00230       // The momentum vector is tangent to
00231       // the track
00232       phi = centerPhi + Geom::pi()/2.;
00233       if (phi>Geom::pi()) {
00234         phi -= 2.*Geom::pi();
00235       }
00236     }
00237     // Other direction!
00238     else if (firstPoint.barePhi() < centerPhi) {
00239       // The momentum vector is tangent to
00240       // the track
00241       phi = centerPhi - Geom::pi()/2.;
00242       if (phi<-1.*Geom::pi()) {
00243         phi += 2.*Geom::pi();
00244       }
00245     }  
00246     return phi;
00247   } // END calculation for circular seeds
00248 }
00249 
00250 std::string RoadSearchCircleSeed::print() const {
00251   //
00252   // print function
00253   //
00254 
00255   std::ostringstream ost;
00256 
00257   if ( type_ == RoadSearchCircleSeed::straightLine ) {
00258     ost << "Straight Line: number of points: " << points_.size() << "\n";
00259     unsigned int counter = 0;
00260     for ( std::vector<GlobalPoint>::const_iterator point = points_.begin();
00261           point != points_.end();
00262           ++point ) {
00263       ++counter;
00264       ost << "    Point " << counter << ": " << point->x() << "," << point->y() << "\n";
00265     }
00266   } else {
00267     ost << "Circle: number of points: " << points_.size() << "\n";
00268     ost << "    Radius         : " << radius_  << "\n";
00269     ost << "    In the barrel  : " << inBarrel_ << "\n";
00270     ost << "    ImpactParameter: " << impactParameter_ << "\n";
00271     ost << "    Center         : " << center_.x() << "," << center_.y() << "\n";
00272     unsigned int counter = 0;
00273     for ( std::vector<GlobalPoint>::const_iterator point = points_.begin();
00274           point != points_.end();
00275           ++point ) {
00276       ++counter;
00277       ost << "    Point " << counter << "        : " << point->x() << "," << point->y() << "\n";
00278     }
00279   }
00280 
00281   return ost.str(); 
00282 }
00283 
00284 std::ostream& operator<<(std::ostream& ost, const RoadSearchCircleSeed & seed) {
00285   //
00286   // print operator
00287   //
00288 
00289   if ( seed.Type() == RoadSearchCircleSeed::straightLine ) {
00290     ost << "Straight Line: number of points: " << seed.Points().size() << "\n";
00291     unsigned int counter = 0;
00292     for ( std::vector<GlobalPoint>::const_iterator point = seed.Points().begin();
00293           point != seed.Points().end();
00294           ++point ) {
00295       ++counter;
00296       ost << "    Point " << counter << ": " << point->x() << "," << point->y() << "\n";
00297     }
00298   } else {
00299     ost << "Circle: number of points: " << seed.Points().size() << "\n";
00300     ost << "    Radius         : " << seed.Radius()  << "\n";
00301     ost << "    In the barrel  : " << seed.InBarrel() << "\n";
00302     ost << "    ImpactParameter: " << seed.ImpactParameter() << "\n";
00303     ost << "    Center         : " << seed.Center().x() << "," << seed.Center().y() << "\n";
00304     unsigned int counter = 0;
00305     for ( std::vector<GlobalPoint>::const_iterator point = seed.Points().begin();
00306           point != seed.Points().end();
00307           ++point ) {
00308       ++counter;
00309       ost << "    Point " << counter << "        : " << point->x() << "," << point->y() << "\n";
00310     }
00311   }
00312 
00313   return ost; 
00314 }
00315 
00316 bool RoadSearchCircleSeed::Compare(const RoadSearchCircleSeed *circle,
00317                                    double centerCut,
00318                                    double radiusCut,
00319                                    unsigned int differentHitsCut) const {
00320   //
00321   // compare this circle with the input circle
00322   // compare: percentage of center difference of center average
00323   // compare: percentage of radius difference of radius average
00324   // compare: number of hits which don't overlap between the two circles
00325   //
00326 
00327   // return value
00328   bool result = false;
00329 
00330   result = CompareRadius(circle,radiusCut);
00331   if ( result ) {
00332     result = CompareCenter(circle,centerCut);
00333     if ( result ) {
00334       result = CompareDifferentHits(circle,differentHitsCut);
00335     }
00336   }
00337 
00338   return result;
00339 
00340 }
00341 
00342 bool RoadSearchCircleSeed::CompareCenter(const RoadSearchCircleSeed *circle,
00343                                          double centerCut) const {
00344   //
00345   // compare this circle with the input circle
00346   // compare: percentage of center difference of center average
00347   //
00348 
00349   // return value
00350   bool result = false;
00351 
00352   double averageCenter = std::sqrt(((center_.x()+circle->Center().x())/2) *
00353                                    ((center_.x()+circle->Center().x())/2) +
00354                                    ((center_.y()+circle->Center().y())/2) *
00355                                    ((center_.y()+circle->Center().y())/2));
00356   double differenceCenter = std::sqrt((center_.x()-circle->Center().x()) *
00357                                       (center_.x()-circle->Center().x()) +
00358                                       (center_.y()-circle->Center().y()) *
00359                                       (center_.y()-circle->Center().y()));
00360 
00361   if ( differenceCenter/averageCenter <= centerCut ) {
00362     result = true;
00363   }
00364 
00365 //   edm::LogVerbatim("OLI") << "center difference: " << differenceCenter
00366 //                        << "center average: " << averageCenter
00367 //                        << "center percentage: " << differenceCenter/averageCenter
00368 //                        << " cut: " << centerCut
00369 //                        << " result: " << result;
00370 
00371   return result;
00372 
00373 }
00374 
00375 bool RoadSearchCircleSeed::CompareRadius(const RoadSearchCircleSeed *circle,
00376                                          double radiusCut) const {
00377   //
00378   // compare: percentage of center difference of center average
00379   // compare: percentage of radius difference of radius average
00380   //
00381 
00382   // return value
00383   bool result = false;
00384 
00385   double averageRadius = (radius_ + circle->Radius() ) /2;
00386   double differenceRadius = std::abs(radius_ - circle->Radius());
00387   
00388   if ( differenceRadius/averageRadius <= radiusCut ) {
00389     result = true;
00390   }
00391 
00392 //   edm::LogVerbatim("OLI") << "radius difference: " << differenceRadius
00393 //                        << " radius average: " << averageRadius
00394 //                        << " radius percentage: " << differenceRadius/averageRadius
00395 //                        << " cut: " << radiusCut
00396 //                        << " result: " << result;
00397 
00398   return result;
00399 
00400 }
00401 
00402 bool RoadSearchCircleSeed::CompareDifferentHits(const RoadSearchCircleSeed *circle,
00403                                                 unsigned int differentHitsCut) const {
00404   //
00405   // compare this circle with the input circle
00406   // compare: number of hits which don't overlap between the two circles
00407   //
00408 
00409   // return value
00410   bool result = false;
00411 
00412   // assume circles always have 3 hits
00413   unsigned int counter = 0;
00414   for ( std::vector<const TrackingRecHit*>::const_iterator hit1 = hits_.begin(),
00415           hit1End = hits_.end();
00416         hit1 != hit1End;
00417         ++hit1 ) {
00418     bool included = false;
00419     for ( std::vector<const TrackingRecHit*>::const_iterator hit2 = circle->begin_hits(),
00420             hit2End = circle->end_hits();
00421           hit2 != hit2End;
00422           ++hit2 ) {
00423       if ( *hit1 == *hit2 ) {
00424         included = true;
00425       }
00426     }
00427     if ( !included ) {
00428       ++counter;
00429     }
00430   }
00431 
00432   if ( counter <= differentHitsCut ) {
00433     result = true;
00434   }
00435 
00436 //   edm::LogVerbatim("OLI") << "hits: " << counter 
00437 //                        << " cut: " << differentHitsCut 
00438 //                        << " result: " << result;
00439 
00440   return result;
00441 
00442 }
00443 
00444 //
00445 // constructor
00446 //
00447 LineRZ::LineRZ(GlobalPoint point1, GlobalPoint point2)
00448 {
00449   theR_ = std::fabs(point1.perp()-point2.perp()); 
00450   theZ_ = std::fabs(point1.z()-point2.z());
00451   //If the line is pointing backwards in z
00452   if ((point1.perp() >= point2.perp() &&
00453        point1.z() < point2.z()) ||
00454       (point2.perp() >= point1.perp() &&
00455        point2.z() < point1.z()))
00456   {
00457     theZ_ = -1.*theZ_;
00458   }
00459 }
00460 
00461 //
00462 // destructor
00463 //
00464 LineRZ::~LineRZ()
00465 { }
00466 
00467 //
00468 // constructor
00469 //
00470 LineXY::LineXY(GlobalPoint point1, GlobalPoint point2)
00471 {
00472   theX_ = std::fabs(point1.x()-point2.x()); 
00473   theY_ = std::fabs(point1.y()-point2.y());
00474   //If the line is pointing backwards in x
00475   if ((point1.perp() >= point2.perp() &&
00476        point1.x() < point2.x()) ||
00477       (point2.perp() >= point1.perp() &&
00478        point2.x() < point1.x()))
00479   {
00480     theX_ = -1.*theX_;
00481   }
00482   //If the line is pointing backwards in y
00483   if ((point1.perp() >= point2.perp() &&
00484        point1.y() < point2.y()) ||
00485       (point2.perp() >= point1.perp() &&
00486        point2.y() < point1.y()))
00487   {
00488     theY_ = -1.*theY_;
00489   }
00490 }
00491 
00492 //
00493 // destructor
00494 //
00495 LineXY::~LineXY()
00496 { }