00001
00012 #ifdef HAVE_CONFIG_H
00013 #include "config.h"
00014 #else
00015
00016 #ifdef _MSC_VER
00017
00018 #include "msdevstudio/MSconfig.h"
00019 #endif
00020
00021 #endif
00022
00023 #include "Bins2DBase.h"
00024
00025 #include "BinnerAxis.h"
00026
00027 #include "datasrcs/NTuple.h"
00028
00029 #include <numeric>
00030
00031 using namespace hippodraw;
00032
00033 using std::string;
00034 using std::vector;
00035
00036 #include <cassert>
00037
00038 Bins2DBase::Bins2DBase ( const char * name )
00039 : BinsBase ( name ),
00040 binner_axisX ( 0 ),
00041 binner_axisY ( 0 )
00042 {
00043 }
00044
00045 Bins2DBase::Bins2DBase ( const Bins2DBase & binner )
00046 : BinsBase( binner ),
00047 binner_axisX ( 0 ),
00048 binner_axisY ( 0 ),
00049 m_data ( binner.m_data )
00050 {
00051 if ( binner.binner_axisX != 0 ) {
00052 binner_axisX = binner.binner_axisX->clone ();
00053 }
00054
00055 if ( binner.binner_axisY != 0 ) {
00056 binner_axisY = binner.binner_axisY->clone ();
00057 }
00058
00059 m_values_dirty = true;
00060 }
00061
00062 Bins2DBase::~Bins2DBase ()
00063 {
00064 if ( binner_axisX ) delete binner_axisX;
00065 if ( binner_axisY ) delete binner_axisY;
00066 }
00067
00068 int
00069 Bins2DBase::
00070 getNumberOfAxes () const
00071 {
00072 return 2;
00073 }
00074
00075 void Bins2DBase::resize ()
00076 {
00077 int nbx = numberOfBins ( Axes::X );
00078 int nby = numberOfBins ( Axes::Y );
00079
00080 if ( nbx == 0 ||
00081 nby == 0 ) return;
00082
00083 resize ( nbx, nby );
00084 }
00085
00086 const BinnerAxis *
00087 Bins2DBase::
00088 getBinnerOn ( hippodraw::Axes::Type axis ) const
00089 {
00090 assert ( axis == Axes::X ||
00091 axis == Axes::Y );
00092
00093 if ( axis == Axes::X ) return binner_axisX;
00094
00095 return binner_axisY;
00096 }
00097
00098
00099 void
00100 Bins2DBase::
00101 setBinnerOn ( BinnerAxis * binner, hippodraw::Axes::Type axis )
00102 {
00103 assert ( axis == Axes::X || axis == Axes::Y );
00104
00105 if ( axis == Axes::X ) {
00106 if ( binner_axisX ) delete binner_axisX;
00107 binner_axisX = binner;
00108 }
00109 else {
00110 if ( binner_axisY ) delete binner_axisY;
00111 binner_axisY = binner;
00112 }
00113 resize ();
00114
00115 m_values_dirty = true;
00116 }
00117
00118 double
00119 Bins2DBase::
00120 getLow ( hippodraw::Axes::Type axis ) const
00121 {
00122 if ( axis == Axes::X ) return binner_axisX->axisGetLow();
00123 if ( axis == Axes::Y ) return binner_axisY->axisGetLow();
00124
00125 assert ( false );
00126 return 0.0;
00127 }
00128
00129 void
00130 Bins2DBase::
00131 setNumberOfBins ( hippodraw::Axes::Type axis, int nb )
00132 {
00133 assert ( axis == Axes::X || axis == Axes::Y );
00134
00135 if ( axis == Axes::X ) {
00136 binner_axisX->axisSetNumberOfBins( nb );
00137
00138 if ( numberOfBins ( Axes::Y ) > 0 ) {
00139 setNumberOfBins ( Axes::Y, numberOfBins ( Axes::Y ) );
00140 }
00141 }
00142 else {
00143 binner_axisY->axisSetNumberOfBins ( nb );
00144 }
00145
00146 m_num_bins = numberOfBins ( Axes::X ) * numberOfBins ( Axes::Y );
00147 }
00148
00149 int Bins2DBase::numberOfBins() const
00150 {
00151 return m_num_bins;
00152 }
00153
00154 int
00155 Bins2DBase::
00156 numberOfBins ( hippodraw::Axes::Type axis) const
00157 {
00158 assert ( axis == Axes::X || axis == Axes::Y );
00159
00160 if ( axis == Axes::X &&
00161 binner_axisX != 0 ) return binner_axisX->axisNumberOfBins();
00162
00163 if ( binner_axisY != 0 ) return binner_axisY->axisNumberOfBins();
00164
00165 return 0;
00166 }
00167
00168 int Bins2DBase::binNumberX( double x ) const
00169 {
00170 return binner_axisX->axisBinNumber( x );
00171 }
00172
00173 int Bins2DBase::binNumberY( double y ) const
00174 {
00175 return binner_axisY->axisBinNumber( y );
00176 }
00177
00178 double
00179 Bins2DBase::
00180 binWidth ( hippodraw::Axes::Type axis ) const
00181 {
00182 assert ( axis == Axes::X || axis == Axes::Y );
00183
00184 if ( axis == Axes::X ) return binner_axisX->getConstWid();
00185
00186 return binner_axisY->getConstWid ();
00187 }
00188
00189 double Bins2DBase::binWidthX ( int i ) const
00190 {
00191 return binner_axisX->axisBinWidth( i );
00192 }
00193
00194 double Bins2DBase::binWidthY ( int i ) const
00195 {
00196 return binner_axisY->axisBinWidth( i );
00197 }
00198
00199 bool
00200 Bins2DBase::hasEqualWidths () const
00201 {
00202 return binner_axisX->hasEqualWidths () && binner_axisY->hasEqualWidths ();
00203 }
00204
00205 double
00206 Bins2DBase::scaleFactor () const
00207 {
00208 if ( binner_axisX->hasEqualWidths () == false ||
00209 binner_axisY->hasEqualWidths () == false ) {
00210 return 1.0;
00211 }
00212
00213 double width_x = binner_axisX->axisBinWidth ( 1 );
00214 double width_y = binner_axisY->axisBinWidth ( 1 );
00215
00216 return width_x * width_y;
00217 }
00218
00219 const Range &
00220 Bins2DBase::
00221 setBinWidth ( hippodraw::Axes::Type axis, double width )
00222 {
00223 assert ( axis == Axes::X || axis == Axes::Y );
00224 assert ( width > 0.0 );
00225
00226 BinnerAxis * binner = 0;
00227 if ( axis == Axes::X ) binner = binner_axisX;
00228 else binner = binner_axisY;
00229
00230 const Range & range = binner->setBinWidth ( width );
00231
00232 resize ();
00233 m_values_dirty = true;
00234
00235 return range;
00236 }
00237
00238 double
00239 Bins2DBase::calcBinWidth ( const std::string & axis,
00240 int parm,
00241 bool dragging ) const
00242 {
00243 double new_width = -1.0;
00244
00245 if ( axis == "X" ) {
00246 new_width = binner_axisX->calcBinWidth ( parm, dragging );
00247 }
00248 else {
00249 new_width = binner_axisY->calcBinWidth ( parm, dragging );
00250 }
00251
00252 return new_width;
00253 }
00254
00255
00256 double
00257 Bins2DBase::calcOffset ( const std::string & axis,
00258 int parm,
00259 bool dragging ) const
00260 {
00261 if ( axis == "X" ) {
00262 return binner_axisX->calcOffset ( parm, dragging );
00263 }
00264
00265 return binner_axisY->calcOffset ( parm, dragging );
00266 }
00267
00268 double
00269 Bins2DBase::
00270 getOffset ( hippodraw::Axes::Type axis ) const
00271 {
00272 assert ( axis == Axes::X || axis == Axes::Y );
00273
00274 if( axis == Axes::X ) return binner_axisX->getOffset();
00275
00276 return binner_axisY->getOffset();
00277 }
00278
00279 void
00280 Bins2DBase::
00281 setOffset ( hippodraw::Axes::Type axis, double offset )
00282 {
00283 assert ( axis == Axes::X || axis == Axes::Y );
00284
00285 BinnerAxis * binner = 0;
00286 if ( axis == Axes::X ) binner = binner_axisX;
00287 else binner = binner_axisY;
00288
00289 binner->setOffset( offset );
00290
00291 m_values_dirty = true;
00292 }
00293
00294 const Range &
00295 Bins2DBase::
00296 setRange ( hippodraw::Axes::Type axis, const Range & range, bool hold_width )
00297 {
00298 assert ( axis == Axes::X || axis == Axes::Y );
00299
00300 BinnerAxis * binner = 0;
00301 if ( axis == Axes::X ) {
00302 binner = binner_axisX;
00303 } else {
00304 binner = binner_axisY;
00305 }
00306 const Range & new_range = binner->setRange ( range, hold_width );
00307 resize ();
00308
00309 return new_range;
00310 }
00311
00312
00313 const Range &
00314 Bins2DBase::
00315 getRange ( hippodraw::Axes::Type axis )
00316 {
00317 assert ( axis == Axes::X || axis == Axes::Y );
00318
00319 BinnerAxis * binner = 0;
00320 if ( axis == Axes::X ) {
00321 binner = binner_axisX;
00322 } else {
00323 binner = binner_axisY;
00324 }
00325
00326 return binner->getRange();
00327 }
00328
00329
00335 void
00336 Bins2DBase::resize ( int nx, int ny )
00337 {
00338
00339 Bins2DBase::setNumberOfBins ( Axes::Y, 0 );
00340
00341 setNumberOfBins ( Axes::X, nx );
00342 setNumberOfBins ( Axes::Y, ny );
00343
00344 m_values_dirty = true;
00345 }
00346
00347 int Bins2DBase::getNumberOfEntries () const
00348 {
00349 double sum = 0.0;
00350 for ( unsigned int i = 1; i < m_data.size () -1; i++ ) {
00351 sum += std::accumulate ( m_data[i].begin()+1, m_data[i].end()-1, 0.0 );
00352 }
00353
00354 return static_cast < int > ( sum );
00355 }
00356
00357 NTuple *
00358 Bins2DBase::
00359 prepareNTuple ( unsigned int rows ) const
00360 {
00361 unsigned int columns = 6;
00362 NTuple * ntuple = new NTuple ( columns );
00363 ntuple -> reserve ( rows );
00364
00365 vector < string > labels;
00366 labels.push_back ( "X" );
00367 labels.push_back ( "Y" );
00368 labels.push_back ( "Value" );
00369 labels.push_back ( "Width" );
00370 labels.push_back ( "Height" );
00371 labels.push_back ( "Error" );
00372
00373 ntuple->setLabels ( labels );
00374
00375 return ntuple;
00376 }