Go to the documentation of this file.00001 #ifndef RBorderFinder_H
00002 #define RBorderFinder_H
00003
00013 #include <DataFormats/GeometrySurface/interface/BoundingBox.h>
00014 #include <DataFormats/GeometrySurface/interface/GeometricSorting.h>
00015
00016 #include <Utilities/General/interface/precomputed_value_sort.h>
00017 #include <Geometry/CommonDetUnit/interface/GeomDet.h>
00018 #include <TrackingTools/DetLayers/interface/simple_stat.h>
00019 #include <FWCore/Utilities/interface/Exception.h>
00020
00021 #include <vector>
00022
00023
00024 class RBorderFinder {
00025 public:
00026
00027 typedef ForwardDetRing Det;
00028 typedef geomsort::ExtractR<Det,float> DetR;
00029
00030 RBorderFinder(std::vector<const Det*> theDets)
00031 : theNbins(theDets.size()), isRPeriodic_(false), isROverlapping_(false)
00032 {
00033 precomputed_value_sort(theDets.begin(), theDets.end(), DetR());
00034
00035 std::vector<ConstReferenceCountingPointer<BoundDisk> > disks(theNbins);
00036 for ( int i = 0; i < theNbins; i++ ) {
00037 disks[i] =
00038 dynamic_cast<const BoundDisk*> (&(theDets[i]->surface()));
00039 if (disks[i]==0) {
00040 throw cms::Exception("UnexpectedState") << "RBorderFinder: implemented for BoundDisks only";
00041 }
00042 }
00043
00044
00045 if (theNbins==1) {
00046 isRPeriodic_ = true;
00047 theRBorders.push_back(disks.front()->innerRadius());
00048 theRBins.push_back((disks.front()->outerRadius()+disks.front()->innerRadius()));
00049
00050
00051
00052 } else {
00053 double step = (disks.back()->innerRadius() -
00054 disks.front()->innerRadius())/(theNbins-1);
00055 std::vector<double> spread;
00056 std::vector<std::pair<double,double> > REdge;
00057 REdge.reserve(theNbins);
00058 theRBorders.reserve(theNbins);
00059 theRBins.reserve(theNbins);
00060 spread.reserve(theNbins);
00061
00062 for ( int i = 0; i < theNbins; i++ ) {
00063 theRBins.push_back((disks[i]->outerRadius()+disks[i]->innerRadius())/2.);
00064 spread.push_back(theRBins.back() - (theRBins[0] + i*step));
00065 REdge.push_back(std::pair<double,double>(disks[i]->innerRadius(),
00066 disks[i]->outerRadius()));
00067 }
00068
00069 theRBorders.push_back(REdge[0].first);
00070 for (int i = 1; i < theNbins; i++) {
00071
00072 double br = (REdge[(i-1)].second + REdge[i].first)/2.;
00073 theRBorders.push_back(br);
00074 }
00075
00076 for (int i = 1; i < theNbins; i++) {
00077 if (REdge[i].first - REdge[i-1].second < 0) {
00078 isROverlapping_ = true;
00079 break;
00080 }
00081 }
00082
00083 double rms = stat_RMS(spread);
00084 if ( rms < 0.01*step) {
00085 isRPeriodic_ = true;
00086 }
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 }
00098
00099
00100 if ((int)theRBorders.size() != theNbins || (int)theRBins.size() != theNbins)
00101 throw cms::Exception("UnexpectedState") << "RBorderFinder consistency error";
00102 }
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157 virtual ~RBorderFinder(){};
00158
00160 inline bool isRPeriodic() const { return isRPeriodic_; }
00161
00163 inline bool isROverlapping() const { return isROverlapping_; }
00164
00167 inline std::vector<double> RBorders() const { return theRBorders; }
00168
00170 inline std::vector<double> RBins() const { return theRBins; }
00171
00172
00173
00174
00175
00176 private:
00177 int theNbins;
00178 bool isRPeriodic_;
00179 bool isROverlapping_;
00180 std::vector<double> theRBorders;
00181 std::vector<double> theRBins;
00182
00183 inline int binIndex( int i) const {
00184 return std::min( std::max( i, 0), theNbins-1);
00185 }
00186 };
00187 #endif
00188