00001
00013 #ifdef _MSC_VER
00014
00015 #include "msdevstudio/MSconfig.h"
00016 #endif
00017
00018 #include "EqualEntriesHist1DProjector.h"
00019
00020 #include "axes/AxisModelBase.h"
00021 #include "datasrcs/DataPointTuple.h"
00022 #include "datasrcs/NTuple.h"
00023 #include "datasrcs/NTupleSorter.h"
00024
00025 #include <algorithm>
00026 #include <numeric>
00027
00028 #include <cfloat>
00029
00030 #include <cassert>
00031
00032 using namespace hippodraw;
00033
00034 #ifdef ITERATOR_MEMBER_DEFECT
00035 using namespace std;
00036 #else
00037 using std::accumulate;
00038 using std::find;
00039 using std::max;
00040 using std::min;
00041 using std::list;
00042 using std::string;
00043 using std::vector;
00044 #endif
00045
00046 EqualEntriesHist1DProjector::EqualEntriesHist1DProjector()
00047 : NTupleProjector ( 2 ),
00048 m_y_label ( "Density" ),
00049 m_bin_num (100),
00050 m_start_num (100)
00051 {
00052 m_binding_options.push_back ( "X" );
00053 m_binding_options.push_back ( "Weight (optional)" );
00054 m_min_bindings = 1;
00055 addPointReps();
00056 }
00057
00062 EqualEntriesHist1DProjector::
00063 EqualEntriesHist1DProjector ( const EqualEntriesHist1DProjector & projector )
00064 : NTupleProjector ( projector ),
00065 m_y_label ( projector.m_y_label ),
00066 m_bin_num ( projector.m_bin_num ),
00067 m_start_num ( projector.m_start_num )
00068 {
00069 addPointReps();
00070 }
00071
00072 ProjectorBase * EqualEntriesHist1DProjector::clone()
00073 {
00074 return new EqualEntriesHist1DProjector( *this );
00075 }
00076
00077 void EqualEntriesHist1DProjector::changedNTuple()
00078 {
00079 unsigned int cols = m_ntuple->columns () - 1;
00080 if ( m_columns[0] > cols ) {
00081 m_columns[0] = cols;
00082 }
00083 if ( m_columns[1] > cols ) m_columns[1] = UINT_MAX;
00084 }
00085
00086
00087 double
00088 EqualEntriesHist1DProjector::
00089 getPosOn ( hippodraw::Axes::Type axis ) const
00090 {
00091 assert ( axis == Axes::X || axis == Axes::Y );
00092
00093 if ( axis == Axes::X ) {
00094 return getPos ( m_columns[0] );
00095 }
00096
00097
00098 return 0;
00099
00100 }
00101
00102
00103 Range
00104 EqualEntriesHist1DProjector::
00105 dataRangeOn ( hippodraw::Axes::Type axis ) const
00106 {
00107 assert ( axis == Axes::X || axis == Axes::Y );
00108
00109 if ( axis == Axes::X ) {
00110 return dataRange ( m_columns[0] );
00111 }
00112
00113 return dataRangeOnValue ();
00114 }
00115
00116
00117 const string & EqualEntriesHist1DProjector::getYLabel ( bool density ) const
00118 {
00119 return m_y_label;
00120 }
00121
00122
00123 namespace dp = hippodraw::DataPoint2DTuple;
00124
00125
00126
00127 double
00128 EqualEntriesHist1DProjector::
00129 getAverage ( hippodraw::Axes::Type axis ) const
00130 {
00131 return 0;
00132 }
00133
00134
00135 int
00136 EqualEntriesHist1DProjector::
00137 getUnderflow () const
00138 {
00139 return 0;
00140 }
00141
00142 int
00143 EqualEntriesHist1DProjector::
00144 getOverflow () const
00145 {
00146 return 0;
00147 }
00148
00149
00150 DataSource *
00151 EqualEntriesHist1DProjector::
00152 createNTuple () const
00153 {
00154 unsigned int columns = 4;
00155 NTuple * ntuple = new NTuple ( columns );
00156
00157 vector < string > labels;
00158 labels.push_back ( "X" );
00159 labels.push_back ( "Value" );
00160 labels.push_back ( dp::WIDTH );
00161 labels.push_back ( dp::ERROR );
00162
00163 ntuple->setLabels ( labels );
00164
00165 fillProjectedValues ( ntuple );
00166
00167 return ntuple;
00168 }
00169
00170 void
00171 EqualEntriesHist1DProjector::
00172 fillProjectedValues ( DataSource * ntuple, bool ) const
00173 {
00174 ntuple -> clear();
00175
00176 vector < double > row ( dp::SIZE );
00177
00178 unsigned int x_col = m_columns[0];
00179 unsigned int size = m_ntuple -> rows ();
00180
00181
00182 vector < double > col = m_ntuple -> getColumn ( x_col );
00183 std::sort(col.begin(), col.end());
00184
00185
00186 unsigned int k=0;
00187 for ( unsigned int i = 0; i < m_bin_num; i++ ) {
00188
00189
00190 unsigned int j=1;
00191 row [dp::XERR] = col[k+size/m_bin_num]- col[k];
00192
00193
00194 if (i==m_bin_num-1) row[dp::XERR] = col[size-1]-col[k];
00195
00196
00197 while ((row[dp::XERR]==0) && (i!=m_bin_num-1)) {
00198 j++;
00199 i++;
00200 row[dp::XERR]=col[k+j*size/m_bin_num]-col[k];
00201 if ( i==m_bin_num-1 ) row[dp::XERR] = col[size-1]-col[k];
00202 }
00203
00204
00205 if ( row[dp::XERR]==0 ) return;
00206
00207
00208 row [dp::X] = col[k] + 0.5*row[dp::XERR];
00209
00210
00211 row [dp::Y] = size*j/m_bin_num/row[dp::XERR];
00212
00213
00214 row [dp::XERR] /= 2.0;
00215 row [dp::YERR] = 0;
00216
00217 ntuple -> addRow (row);
00218
00219
00220 k+=j*size/m_bin_num;
00221 }
00222
00223 }
00224
00225 void
00226 EqualEntriesHist1DProjector::
00227 prepareValues ()
00228 {
00229 adjustNumberOfBins();
00230 m_range = dataRange ( m_columns[0] );
00231
00232 if ( m_proj_values == 0 ) {
00233 m_proj_values = createNTuple ();
00234 } else {
00235 fillProjectedValues ( m_proj_values );
00236 }
00237
00238 setDirty ( false );
00239 }
00240
00241
00242 void
00243 EqualEntriesHist1DProjector::
00244 addPointReps()
00245 {
00246 m_pointreps.push_back ( "Column" );
00247 m_pointreps.push_back ( "FilledColumn" );
00248 m_pointreps.push_back ( "Symbol" );
00249 m_pointreps.push_back ( "Line" );
00250 }
00251
00252 bool EqualEntriesHist1DProjector::
00253 isAxisBinned ( const std::string & axis ) const
00254 {
00255 if ( axis == m_binding_options[0] ) {
00256 return true;
00257 }
00258 return false;
00259 }
00260
00261 Range
00262 EqualEntriesHist1DProjector::
00263 valueRange () const
00264 {
00265 return dataRangeOn ( Axes::Y );
00266 }
00267
00268 Range
00269 EqualEntriesHist1DProjector::
00270 dataRangeOnValue ( ) const
00271 {
00272 EqualEntriesHist1DProjector * p = const_cast < EqualEntriesHist1DProjector * > ( this );
00273 p->prepareValues ();
00274 if ( m_proj_values -> empty () ) {
00275 return Range ( 0.0, 1.0, 0.5 );
00276 }
00277
00278 const vector < double > & values = m_proj_values -> getColumn( dp::Y );
00279 return Range ( values );
00280 }
00281
00282 const Range &
00283 EqualEntriesHist1DProjector::
00284 setBinWidth( Axes::Type axis, int parm, bool dragging )
00285 {
00286 m_bin_num=m_start_num+parm-50;
00287 adjustNumberOfBins();
00288 setDirty(true);
00289
00290 if ( !dragging ) m_start_num = m_bin_num;
00291
00292 return m_range;
00293 }
00294
00295 const Range &
00296 EqualEntriesHist1DProjector::
00297 setBinWidth( Axes::Type axis, double number )
00298 {
00299 m_bin_num=(unsigned int) number;
00300 adjustNumberOfBins();
00301 setDirty(true);
00302
00303 return m_range;
00304 }
00305
00306 double
00307 EqualEntriesHist1DProjector::
00308 getBinWidth ( Axes::Type axis ) const
00309 {
00310 return (double)m_bin_num;
00311 }
00312
00313 void
00314 EqualEntriesHist1DProjector::
00315 adjustNumberOfBins()
00316 {
00317 unsigned int size = m_ntuple -> rows ();
00318 if ( size-1 < m_bin_num ) m_start_num = m_bin_num = size-1;
00319 if (m_bin_num < 1) m_bin_num = 1;
00320 }