Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

BinnerAxisLog.cxx

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

Generated for HippoDraw-1.14.8.5 by doxygen 1.4.3