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