Go to the documentation of this file.00001 #ifndef PhiBorderFinder_H
00002 #define PhiBorderFinder_H
00003
00014 #include <Geometry/CommonDetUnit/interface/GeomDet.h>
00015
00016 #include <DataFormats/GeometrySurface/interface/BoundingBox.h>
00017 #include <DataFormats/GeometrySurface/interface/GeometricSorting.h>
00018
00019 #include <DataFormats/GeometryVector/interface/Pi.h>
00020 #include <Utilities/General/interface/precomputed_value_sort.h>
00021 #include <TrackingTools/DetLayers/interface/simple_stat.h>
00022 #include <FWCore/Utilities/interface/Exception.h>
00023
00024
00025 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00026
00027 #include <vector>
00028
00029 class PhiBorderFinder {
00030 public:
00031
00032 typedef DetRod Det;
00033 typedef geomsort::ExtractPhi<Det,float> DetPhi;
00034
00035
00036 PhiBorderFinder(std::vector<const Det*> theDets)
00037 : theNbins(theDets.size()), isPhiPeriodic_(false), isPhiOverlapping_(false) {
00038 precomputed_value_sort(theDets.begin(), theDets.end(), DetPhi());
00039
00040 const std::string metname = "Muon|RecoMuon|RecoMuonDetLayers|PhiBorderFinder";
00041
00042 double step = 2.*Geom::pi()/theNbins;
00043
00044 LogTrace(metname) << "RecoMuonDetLayers::PhiBorderFinder "
00045 << "step w: " << step << " # of bins: " << theNbins;
00046
00047 std::vector<double> spread(theNbins);
00048 std::vector<std::pair<double,double> > phiEdge;
00049 phiEdge.reserve(theNbins);
00050 thePhiBorders.reserve(theNbins);
00051 thePhiBins.reserve(theNbins);
00052 for ( unsigned int i = 0; i < theNbins; i++ ) {
00053 thePhiBins.push_back(theDets[i]->position().phi());
00054 spread.push_back(theDets[i]->position().phi()
00055 - (theDets[0]->position().phi() + i*step));
00056
00057 LogTrace(metname) << "bin: " << i << " phi bin: " << thePhiBins[i]
00058 << " spread: " << spread[i];
00059
00060
00061 ConstReferenceCountingPointer<BoundPlane> plane =
00062 dynamic_cast<const BoundPlane*>(&theDets[i]->surface());
00063 if (plane==0) {
00064
00065 throw cms::Exception("UnexpectedState") << ("PhiBorderFinder: det surface is not a BoundPlane");
00066 }
00067
00068 std::vector<GlobalPoint> dc =
00069 BoundingBox().corners(*plane);
00070
00071 float phimin(999.), phimax(-999.);
00072 for (std::vector<GlobalPoint>::const_iterator pt=dc.begin();
00073 pt!=dc.end(); pt++) {
00074 float phi = (*pt).phi();
00075
00076 if (phi < phimin) phimin = phi;
00077 if (phi > phimax) phimax = phi;
00078 }
00079 if (phimin*phimax < 0. &&
00080 phimax - phimin > Geom::pi()) {
00081
00082 std::swap(phimin,phimax);
00083 }
00084 phiEdge.push_back(std::pair<double,double>(phimin,phimax));
00085 }
00086
00087 for (unsigned int i = 0; i < theNbins; i++) {
00088
00089
00090 double firstPhi = positiveRange(phiEdge[i].first);
00091 double secondPhi = positiveRange(phiEdge[binIndex(i-1)].second);
00092
00093
00094 Geom::Phi<double> firstEdge(firstPhi);
00095 Geom::Phi<double> secondEdge(secondPhi);
00096
00097
00098
00099 Geom::Phi<double> mean((firstEdge.value() + secondEdge.value())/2.);
00100
00101
00102 if ( phiEdge[i].first * phiEdge[binIndex(i-1)].second < 0 &&
00103 fabs(firstPhi-secondPhi) < Geom::pi() )
00104 mean = Geom::pi() - mean;
00105
00106 thePhiBorders.push_back(mean);
00107 }
00108
00109 for (unsigned int i = 0; i < theNbins; i++) {
00110 if (Geom::Phi<double>(phiEdge[i].first)
00111 - Geom::Phi<double>(phiEdge[binIndex(i-1)].second) < 0) {
00112 isPhiOverlapping_ = true;
00113 break;
00114 }
00115 }
00116
00117 double rms = stat_RMS(spread);
00118 if ( rms < 0.01*step) {
00119 isPhiPeriodic_ = true;
00120 }
00121
00122
00123 if (thePhiBorders.size() != theNbins || thePhiBins.size() != theNbins)
00124
00125 throw cms::Exception("UnexpectedState") << "PhiBorderFinder: consistency error";
00126 }
00127
00128
00129 virtual ~PhiBorderFinder(){};
00130
00131 inline unsigned int nBins() {return theNbins;}
00132
00134 inline bool isPhiPeriodic() const { return isPhiPeriodic_; }
00135
00137 inline bool isPhiOverlapping() const { return isPhiOverlapping_; }
00138
00141 inline const std::vector<double>& phiBorders() const { return thePhiBorders; }
00142
00144 inline const std::vector<double>& phiBins() const { return thePhiBins; }
00145
00146
00147
00148
00149 private:
00150 unsigned int theNbins;
00151 bool isPhiPeriodic_;
00152 bool isPhiOverlapping_;
00153 std::vector<double> thePhiBorders;
00154 std::vector<double> thePhiBins;
00155
00156 inline double positiveRange (double phi) const
00157 {
00158 return (phi > 0) ? phi : phi + Geom::twoPi();
00159 }
00160
00161 int binIndex( int i) const {
00162 int ind = i % (int)theNbins;
00163 return (ind < 0) ? ind+theNbins : ind;
00164 }
00165
00166
00167 };
00168 #endif
00169