BinnerAxisLog.cxx

Go to the documentation of this file.
00001 
00012 #ifdef _MSC_VER
00013 #include "msdevstudio/MSconfig.h"
00014 #endif
00015 
00016 #include "binners/BinnerAxisLog.h"
00017 
00018 #include <algorithm>
00019 #include <stdexcept>
00020 
00021 #include <cmath>
00022 #include <cassert>
00023 
00024 
00025 #ifdef ITERATOR_MEMBER_DEFECT
00026 using namespace std;
00027 #else
00028 using std::max;
00029 using std::pow;
00030 using std::upper_bound;
00031 using std::vector;
00032 #endif
00033 
00034 using namespace hippodraw;
00035 
00036 BinnerAxisLog::
00037 BinnerAxisLog ()
00038   : BinnerAxis ( "BinnerLog" )
00039 {
00040 }
00041 
00042 BinnerAxisLog::BinnerAxisLog ( const BinnerAxisLog & binner )
00043   : BinnerAxis ( binner ),
00044     bins ( binner.bins )
00045 {
00046 }
00047 
00048 BinnerAxisLog::~BinnerAxisLog ()
00049 {
00050 }
00051 
00052 BinnerAxis *
00053 BinnerAxisLog::clone ()
00054 {
00055   return new BinnerAxisLog ( *this );
00056 }
00057 
00058 void
00059 BinnerAxisLog::axisSetNumberOfBins( int nb )
00060 {
00061   m_num_bins = nb;
00062 }
00063 
00064 int
00065 BinnerAxisLog::axisBinNumber ( double x ) const
00066 {
00067   vector<double>::const_iterator it
00068     = upper_bound ( bins.begin(), bins.end(), x );
00069   int i = it - bins.begin();
00070   if( i < 1 ) i = 0;
00071   if ( i > m_num_bins ) i = m_num_bins + 1;
00072 
00073   return i;
00074 }
00075 
00076 double
00077 BinnerAxisLog::
00078 getCoordinate ( int i ) const
00079 {
00080   assert ( i < m_num_bins && !( i < 0 ) );
00081 
00082   double low = bins[i];
00083   double high = bins[i+1];
00084 
00085   return sqrt(low*high);
00086 }
00087 
00088 double
00089 BinnerAxisLog::axisBinWidth ( int bins_number) const
00090 {
00091   bins_number = std::min ( bins_number, m_num_bins -1 );
00092   bins_number = std::max ( bins_number, 0 );
00093 
00094   double width = bins[bins_number+1] - bins[bins_number];
00095   assert ( width >= 0.0 );
00096 
00097   return width;
00098 }
00099 
00100 /* virtual */
00101 double
00102 BinnerAxisLog::getConstWid ( ) const
00103 {
00104   return m_width;
00105 }  
00106 
00107 double
00108 BinnerAxisLog::
00109 getBinWidth ( ) const
00110 {
00111   return m_width;
00112 }  
00113 
00114 void
00115 BinnerAxisLog::setConstWid ( )
00116 {
00117   m_width = calcWidthParm ( m_num_bins );
00118 }
00119 
00120 double
00121 BinnerAxisLog::calcWidthParm ( int num_bins ) const
00122 {
00123   double width_parm = 0;
00124   double low = m_range.low();
00125   double high = m_range.high();
00126   width_parm = log10 ( high / low ) / num_bins;
00127 
00128   return width_parm;
00129 }
00130 
00131 void
00132 BinnerAxisLog::setBins ()
00133 {
00134   double low = m_range.low ();
00135   assert ( low > 0.0 );
00136 
00137   vector<double>::iterator it = bins.begin();
00138   *it++ = low;
00139 
00140   for ( int i = 1; it != bins.end(); ++it, i++ ) {
00141     *it = low * pow ( 10.0, i * m_width );
00142   }
00143 }
00144 
00145 const Range &
00146 BinnerAxisLog::
00147 setRange ( const Range & range, bool hold_width )
00148 {
00149   m_range = range;
00150 
00151   if ( hold_width ) {
00152     m_num_bins = getNob ( range );
00153   }
00154   else {
00155     m_width = calcWidthParm ( m_num_bins );
00156   }
00157 
00158   double low = m_range.low ();
00159   double  high = 1.0;
00160   if (low <= 0) {
00161      low = m_range.high()/pow(10., m_num_bins*m_width);
00162      m_range.setLow(low);
00163   } else {
00164      high = low * pow ( 10.0, m_num_bins * m_width );
00165      m_range.setHigh(high);
00166   }
00167 
00168   if (high <= 0) { //sloppy, using high as a flag
00169      throw std::runtime_error("BinnerAxisLog::Range: attempt to set range "
00170                               "to negative values.");
00171   }
00172 
00173   bins.resize( m_num_bins + 1, 0.0 );
00174   setBins();
00175 
00176   return m_range;
00177 }
00178 
00179 const Range &
00180 BinnerAxisLog::setBinWidth ( double wid )
00181 {
00182   assert ( wid > 0.0 );
00183 
00184   m_width = wid;
00185   m_num_bins = getNob ( m_width );
00186 
00187   double low = m_range.low ();
00188   double high = low * pow ( 10.0, m_num_bins * wid );
00189   m_range.setHigh ( high );
00190   bins.resize( m_num_bins + 1, 0.0 );
00191   setBins();
00192 
00193   return m_range;
00194 }
00195 
00196 double
00197 BinnerAxisLog::calcOffset ( int parm, bool dragging ) const
00198 {
00199   setStartRange ( dragging );
00200 
00201   return ( parm - 50 ) / 50.0;
00202 }
00203 
00206 double
00207 BinnerAxisLog::getOffset () const
00208 {
00209   return m_offset;
00210 }
00211 
00212 const void
00213 BinnerAxisLog::setOffset ( double offset )
00214 {
00215   double oldoff = m_offset;
00216   m_offset = offset;
00217   double change = m_offset - oldoff;
00218 
00219   if( offset == 0.0 ) return; // resetting...
00220   double low = m_range_start.low ();
00221   double width = low * pow ( 10.0,  m_width ); // first bin width
00222   double woffset = width * change;
00223   double new_low = low * pow ( 10.0, woffset * m_width );
00224   double new_high = new_low * pow ( 10.0, ( bins.size() -1 ) * m_width );
00225 
00226   Range r( new_low, new_high );
00227   setRange( r );
00228 }
00229 
00230 double
00231 BinnerAxisLog::scaleFactorWid ( )
00232 {
00233   return 1.0;
00234 }
00235 
00236 int BinnerAxisLog::getNob ( const Range & range ) const
00237 {
00238   double low = range.low ();
00239   double high = range.high ();
00240   int tmp = static_cast< int > ( ceil ( log10 ( high/low ) /  
00241                                         m_width  ) );
00242 
00243   return tmp ? tmp : 1;
00244 }
00245 
00246 int BinnerAxisLog::getNob ( double wid ) const
00247 {
00248   double low = m_range.low ();
00249   double high = m_range.high ();
00250   int tmp = static_cast < int > ( ceil ( log10 ( high/low ) / 
00251                                           wid  ) );
00252   return tmp ? tmp : 1;
00253 }

Generated for HippoDraw Class Library by doxygen