CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/RecoMuon/DetLayers/src/RBorderFinder.h

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 //#include <iostream>
00023 
00024 class RBorderFinder {
00025 public:
00026   
00027   typedef ForwardDetRing Det; //FIXME!!!
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) { // Trivial case
00046       isRPeriodic_ = true; // meaningless in this case
00047       theRBorders.push_back(disks.front()->innerRadius());
00048       theRBins.push_back((disks.front()->outerRadius()+disks.front()->innerRadius()));
00049 //       std::cout << "RBorderFinder:  theNbins " << theNbins << std::endl
00050 //              << " C: " << theRBins[0]
00051 //              << " Border: " << theRBorders[0] << std::endl;
00052     } else { // More than 1 bin
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         // Average borders of previous and next bins
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 //       std::cout << "RBorderFinder:  theNbins " << theNbins
00089 //              << " step: " << step << " RMS " << rms << std::endl;
00090 //       for (int idbg = 0; idbg < theNbins; idbg++) {
00091 //      std::cout << "L: " << REdge[idbg].first
00092 //                << " C: " << theRBins[idbg]
00093 //                << " R: " << REdge[idbg].second
00094 //                << " Border: " << theRBorders[idbg]
00095 //                << " SP: " << spread[idbg] << std::endl;
00096 //       }
00097     }
00098 
00099     //Check that everything is proper
00100     if ((int)theRBorders.size() != theNbins || (int)theRBins.size() != theNbins) 
00101       throw cms::Exception("UnexpectedState") << "RBorderFinder consistency error";
00102 }
00103 
00104   // Construct from a std::vector of Det*. 
00105   // Not tested, and do not work if the Dets are rings since 
00106   // position().perp() gives 0...
00107 //   RBorderFinder(std::vector<Det*> theDets) 
00108 //     : theNbins(theDets.size()), isRPeriodic_(false), isROverlapping_(false)
00109 //   {
00110 //     sort(theDets.begin(), theDets.end(), DetLessR());
00111 
00112 //     double step = (theDets.back()->position().perp() -
00113 //                 theDets.front()->position().perp())/(theNbins-1);
00114 //     std::vector<double> spread(theNbins);
00115 //     std::vector<std::pair<double,double> > REdge;
00116 //     REdge.reserve(theNbins);
00117 //     theRBorders.reserve(theNbins);
00118 //     theRBins.reserve(theNbins);
00119 //     for ( int i = 0; i < theNbins; i++ ) {
00120 //       theRBins.push_back(theDets[i]->position().perp());
00121 //       spread.push_back(theDets[i]->position().perp()
00122 //      - (theDets[0]->position().perp() + i*step));
00123 
00124 //       const BoundPlane * plane = 
00125 //      dynamic_cast<const BoundPlane*>(&theDets[i]->surface());
00126 //       if (plane==0) {
00127 //      throw DetLogicError("RBorderFinder: det surface is not a BoundPlane");
00128 //       }
00129       
00130 //       std::vector<GlobalPoint> dc = 
00131 //      BoundingBox().corners(*plane);
00132 
00133 //       float rmin(dc.front().perp());
00134 //       float rmax(rmin); 
00135 //       for (std::vector<GlobalPoint>::const_iterator pt=dc.begin();
00136 //         pt!=dc.end(); pt++) {
00137 //      float r = (*pt).perp(); 
00138 //      //      float z = pt->z();
00139 //      rmin = min( rmin, r);
00140 //      rmax = max( rmax, r);
00141 //       }
00142 
00143 //       // in addition to the corners we have to check the middle of the 
00144 //       // det +/- length/2 since the min (max) radius for typical fw dets
00145 //       // is reached there 
00146 //       float rdet = theDets[i]->position().perp();
00147 //       float len = theDets[i]->surface().bounds().length();
00148 //       rmin = min( rmin, rdet-len/2.F);
00149 // //   theRmax = max( theRmax, rdet+len/2.F);
00150 
00151 //       REdge.push_back(make_std::pair(rmin,rmax));
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   //  inline std::vector<double> etaBorders() {}
00173   //  inline std::vector<double> zBorders() {}
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