00001
00012 #ifdef _MSC_VER
00013
00014 #include "msdevstudio/MSconfig.h"
00015 #endif
00016
00017 #include "Map2Projector.h"
00018
00019 #include "axes/Range.h"
00020 #include "axes/AxisModelBase.h"
00021
00022 #include "datasrcs/DataPointTuple.h"
00023 #include "datasrcs/NTuple.h"
00024
00025 #include <algorithm>
00026
00027 #include <cfloat>
00028
00029 #include <cassert>
00030
00031 using namespace hippodraw;
00032
00033 #ifdef ITERATOR_MEMBER_DEFECT
00034 using namespace std;
00035 #else
00036 using std::find;
00037 using std::max;
00038 using std::min;
00039 using std::string;
00040 using std::vector;
00041 #endif
00042
00043 Map2Projector::Map2Projector ( )
00044 : NTupleProjector ( 4 ),
00045 m_x_option ( "X error (optional)" ),
00046 m_y_option ( "Y error (optional)" )
00047 {
00048 m_binding_options.push_back ( "X" );
00049 m_binding_options.push_back ( "Y" );
00050 m_min_bindings = 2;
00051 addPointReps();
00052 }
00053
00058 Map2Projector::
00059 Map2Projector ( const Map2Projector & projector )
00060 : ProjectorBase ( projector ),
00061 NTupleProjector ( projector )
00062 {
00063 addPointReps();
00064 }
00065
00066
00067
00068 Map2Projector::~Map2Projector()
00069 {
00070 }
00071
00072 ProjectorBase * Map2Projector::clone()
00073 {
00074 return new Map2Projector( *this );
00075 }
00076
00077 void Map2Projector::setXErrorOption ( bool enable )
00078 {
00079 const string name ( m_x_option );
00080 vector< string >:: iterator first
00081 = find ( m_binding_options.begin (),
00082 m_binding_options.end (),
00083 name );
00084
00085 if ( first != m_binding_options.end () && !enable ) {
00086 m_binding_options.erase ( first );
00087 m_columns[2] = UINT_MAX;
00088 }
00089 else if ( enable ) {
00090 m_binding_options.push_back ( name );
00091 }
00092 }
00093
00096 void Map2Projector::setYErrorOption ( bool enable )
00097 {
00098 const string name ( m_y_option );
00099 vector< string >:: iterator first
00100 = find ( m_binding_options.begin (),
00101 m_binding_options.end (),
00102 name );
00103 if ( first != m_binding_options.end () && !enable ) {
00104 m_binding_options.erase ( first );
00105 m_columns[3] = UINT_MAX;
00106 }
00107 else if ( enable ) {
00108 m_binding_options.push_back ( name );
00109 }
00110 }
00111
00112 void Map2Projector::changedNTuple()
00113 {
00114 unsigned int cols = m_ntuple->columns () - 1;
00115 if ( m_columns[0] > cols ) m_columns[0] = cols;
00116 if ( m_columns[1] > cols ) m_columns[1] = cols;
00117 if ( m_columns[2] > cols ) m_columns[2] = UINT_MAX;
00118 if ( m_columns[3] > cols ) m_columns[3] = UINT_MAX;
00119 }
00120
00121 Range Map2Projector::valueRange () const
00122 {
00123 return dataRangeOn ( Axes::Y );
00124 }
00125
00126 Range
00127 Map2Projector::
00128 dataRangeOn ( hippodraw::Axes::Type axis ) const
00129 {
00130 assert ( axis == Axes::X || axis == Axes::Y );
00131
00132 if ( axis == Axes::X ) {
00133 if ( m_columns[2] == UINT_MAX ) {
00134 return dataRange ( m_columns[0] );
00135 } else {
00136 return dataRangeWithError ( m_columns[0], m_columns[2] );
00137 }
00138 }
00139
00140 if ( m_columns[3] == UINT_MAX ) {
00141 return dataRange ( m_columns[1] );
00142 }
00143
00144 return dataRangeWithError ( m_columns[1], m_columns[3] );
00145 }
00146
00147 double
00148 Map2Projector::
00149 getPosOn ( hippodraw::Axes::Type axis ) const
00150 {
00151 assert ( axis == Axes::X || axis == Axes::Y );
00152
00153 if ( axis == Axes::X ) {
00154 if ( m_columns[2] == UINT_MAX ) {
00155 return getPos ( m_columns[0] );
00156 } else {
00157 return getPosWithError ( m_columns[0], m_columns[2] );
00158 }
00159 }
00160
00161 if ( m_columns[3] == UINT_MAX ) {
00162 return getPos ( m_columns[1] );
00163 }
00164
00165 return getPosWithError ( m_columns[1], m_columns[3] );
00166 }
00167
00168 void Map2Projector::addPointReps()
00169 {
00170 m_pointreps.push_back ( "Symbol" );
00171 m_pointreps.push_back ( "Line" );
00172 m_pointreps.push_back ( "Column" );
00173 }
00174
00175 namespace dp = hippodraw::DataPoint2DTuple;
00176
00177 DataSource *
00178 Map2Projector::
00179 createNTuple () const
00180 {
00181
00182 unsigned int x_col = m_columns[0];
00183 unsigned int y_col = m_columns[1];
00184
00185 unsigned int x_err = m_columns[2];
00186 unsigned int y_err = m_columns[3];
00187
00188 unsigned int columns = 4;
00189 NTuple * ntuple = new NTuple ( columns );
00190
00191 vector < string > labels;
00192 labels.push_back ( m_ntuple -> getLabelAt ( x_col ) );
00193 labels.push_back ( m_ntuple -> getLabelAt ( y_col ) );
00194
00195 if ( x_err < UINT_MAX ) {
00196 labels.push_back ( m_ntuple -> getLabelAt ( x_err ) );
00197 } else {
00198 labels.push_back ( dp::WIDTH );
00199 }
00200
00201 if ( y_err < UINT_MAX ) {
00202 labels.push_back ( m_ntuple -> getLabelAt ( y_err ) );
00203 } else {
00204 labels.push_back ( dp::ERROR );
00205 }
00206 ntuple->setLabels ( labels );
00207
00208 unsigned int size = m_ntuple -> rows ();
00209 ntuple -> reserve ( size );
00210
00211 fillProjectedValues ( ntuple );
00212
00213 return ntuple;
00214 }
00215
00223 void
00224 Map2Projector::
00225 fillProjectedValues ( DataSource * ntuple, bool in_range ) const
00226 {
00227 ntuple -> clear ();
00228
00229 unsigned int x_col = m_columns[0];
00230 unsigned int y_col = m_columns[1];
00231
00232 unsigned int x_err = m_columns[2];
00233 unsigned int y_err = m_columns[3];
00234
00235 const vector < string > & labels = m_ntuple -> getLabels ();
00236 unsigned int size = labels.size();
00237 if ( size > 2 ) {
00238 if ( x_err == UINT_MAX &&
00239 labels [ dp::XERR ] == dp::WIDTH ) x_err = dp::XERR;
00240 if ( size > 3 ) {
00241 if ( y_err == UINT_MAX &&
00242 labels [ dp::YERR ] == dp::ERROR ) y_err = dp::YERR;
00243 }
00244 }
00245 size = m_ntuple -> rows ();
00246 vector < double > row ( dp::SIZE );
00247 for ( unsigned int i = 0; i < size; i++ ) {
00248 if ( acceptRow ( i, m_cut_list ) == false ||
00249
00250 inRange ( i ) == false ) continue;
00251 row[dp::X] = m_ntuple -> valueAt ( i, x_col );
00252 row[dp::Y] = m_ntuple -> valueAt ( i, y_col );
00253
00254
00255 double xe
00256 = x_err < UINT_MAX ? m_ntuple -> valueAt ( i, x_err ) : 0.0;
00257 double ye
00258 = y_err < UINT_MAX ? m_ntuple -> valueAt( i, y_err ) : 0.0;
00259
00260 row[dp::XERR] = xe;
00261 row[dp::YERR] = ye;
00262
00263 ntuple -> addRow ( row );
00264 }
00265 }
00266
00267 bool
00268 Map2Projector::
00269 inRange ( int row ) const
00270 {
00271 unsigned int x_col = m_columns[0];
00272 double x_val = m_ntuple -> valueAt ( row, x_col );
00273 const Range & x_range = m_x_axis -> getRange ( false );
00274 bool x_ok = x_range.includes ( x_val );
00275 if ( x_ok == false ) {
00276 unsigned int xe_col = m_columns[2];
00277 if ( xe_col < UINT_MAX ) {
00278 double x_err = m_ntuple -> valueAt ( row, xe_col );
00279 x_ok |= x_range.includes ( x_val + x_err );
00280 x_ok |= x_range.includes ( x_val - x_err );
00281 }
00282 }
00283
00284 unsigned int y_col = m_columns[1];
00285 double y_val = m_ntuple -> valueAt ( row, y_col );
00286 const Range & y_range = m_y_axis -> getRange ( false );
00287 bool y_ok = y_range.includes ( y_val );
00288 if ( y_ok == false ) {
00289 unsigned int ye_col = m_columns[3];
00290 if ( ye_col < UINT_MAX ) {
00291 double y_err = m_ntuple -> valueAt ( row, ye_col );
00292 y_ok |= y_range.includes ( y_val + y_err );
00293 y_ok |= y_range.includes ( y_val - y_err );
00294 }
00295 }
00296
00297 return x_ok && y_ok;
00298 }
00299
00300
00301 void
00302 Map2Projector::
00303 prepareValues ()
00304 {
00305 if ( m_proj_values == 0 ) {
00306 m_proj_values = createNTuple ();
00307 }
00308 else if ( isDirty () ) {
00309 fillProjectedValues ( m_proj_values, false );
00310 }
00311
00312 setDirty ( false );
00313 }