00001
00012 #ifdef _MSC_VER
00013
00014 #include "msdevstudio/MSconfig.h"
00015 #endif
00016
00017 #include "MeshProjector.h"
00018
00019 #include "axes/AxisModelBase.h"
00020 #include "axes/Range.h"
00021
00022 #include "datasrcs/DataPointTuple.h"
00023 #include "datasrcs/NTuple.h"
00024
00025 #include <algorithm>
00026 #include <cfloat>
00027
00028 #include <cassert>
00029
00030 using namespace hippodraw;
00031
00032 #ifdef ITERATOR_MEMBER_DEFECT
00033 using namespace std;
00034 #else
00035 using std::find;
00036 using std::max;
00037 using std::min;
00038 using std::string;
00039 using std::vector;
00040 #endif
00041
00042 MeshProjector::MeshProjector ( )
00043 : NTupleProjector ( 5 ),
00044 m_x_option ( "X width (optional)" ),
00045 m_y_option ( "Y width (optional)" )
00046 {
00047 m_binding_options.push_back ( "X" );
00048 m_binding_options.push_back ( "Y" );
00049 m_binding_options.push_back ( "Z" );
00050 m_binding_options.push_back ( "X width" );
00051 m_binding_options.push_back ( "Y width" );
00052 m_min_bindings = 5;
00053 addPointReps();
00054 }
00055
00060 MeshProjector::
00061 MeshProjector ( const MeshProjector & projector )
00062 : ProjectorBase ( projector ),
00063 NTupleProjector ( projector )
00064 {
00065 addPointReps();
00066 }
00067
00068
00069
00070 MeshProjector::~MeshProjector()
00071 {
00072 }
00073
00074 ProjectorBase * MeshProjector::clone()
00075 {
00076 return new MeshProjector( *this );
00077 }
00078
00079 void MeshProjector::setXErrorOption ( bool enable )
00080 {
00081 const string name ( m_x_option );
00082 vector< string >:: iterator first
00083 = find ( m_binding_options.begin (),
00084 m_binding_options.end (),
00085 name );
00086
00087 if ( first != m_binding_options.end () && !enable ) {
00088 m_binding_options.erase ( first );
00089 m_columns[3] = UINT_MAX;
00090 }
00091 else if ( enable ) {
00092 m_binding_options.push_back ( name );
00093 }
00094 }
00095
00098 void MeshProjector::setYErrorOption ( bool enable )
00099 {
00100 const string name ( m_y_option );
00101 vector< string >:: iterator first
00102 = find ( m_binding_options.begin (),
00103 m_binding_options.end (),
00104 name );
00105 if ( first != m_binding_options.end () && !enable ) {
00106 m_binding_options.erase ( first );
00107 m_columns[4] = UINT_MAX;
00108 }
00109 else if ( enable ) {
00110 m_binding_options.push_back ( name );
00111 }
00112 }
00113
00114 void MeshProjector::changedNTuple()
00115 {
00116 unsigned int cols = m_ntuple->columns () - 1;
00117 if ( m_columns[0] > cols ) m_columns[0] = cols;
00118 if ( m_columns[1] > cols ) m_columns[1] = cols;
00119 if ( m_columns[2] > cols ) m_columns[2] = cols;
00120 if ( m_columns[3] > cols ) m_columns[3] = cols;
00121 if ( m_columns[4] > cols ) m_columns[4] = cols;
00122 }
00123
00124 Range MeshProjector::valueRange () const
00125 {
00126 return dataRangeOn ( Axes::Z );
00127 }
00128
00129 Range
00130 MeshProjector::
00131 dataRangeOn ( hippodraw::Axes::Type axis ) const
00132 {
00133 assert ( axis == Axes::X || axis == Axes::Y || axis == Axes::Z );
00134
00135 if ( axis == Axes::X ) {
00136 if ( m_columns[3] == UINT_MAX ) {
00137 return dataRange ( m_columns[0] );
00138 } else {
00139 return dataRangeWithError ( m_columns[0], m_columns[3] );
00140 }
00141 }
00142 if ( axis == Axes::Y ) {
00143 if ( m_columns[4] == UINT_MAX ) {
00144 return dataRange ( m_columns[1] );
00145 }
00146 else {
00147 return dataRangeWithError ( m_columns[1], m_columns[4] );
00148 }
00149 }
00150
00151 return dataRangeOnValue ( );
00152 }
00153
00154 namespace dp = hippodraw::DataPoint3DTuple;
00155
00156 Range
00157 MeshProjector::
00158 dataRangeOnValue () const
00159 {
00160 MeshProjector * mp = const_cast < MeshProjector * > ( this );
00161 mp -> prepareValues ();
00162 if ( m_proj_values -> empty () ) {
00163 return Range ( 0.0, 1.0, 0.5 );
00164 }
00165 const vector < double > & values = m_proj_values -> getColumn ( dp::Z );
00166
00167 return Range ( values );
00168 }
00169
00170 double
00171 MeshProjector::
00172 getPosOn ( hippodraw::Axes::Type axis ) const
00173 {
00174 assert ( axis == Axes::X || axis == Axes::Y || axis == Axes::Z );
00175
00176 if ( axis == Axes::X ) {
00177 if ( m_columns[3] == UINT_MAX ) {
00178 return getPos ( m_columns[0] );
00179 } else {
00180 return getPosWithError ( m_columns[0], m_columns[3] );
00181 }
00182 }
00183 if ( axis == Axes::Y ) {
00184 if ( m_columns[4] == UINT_MAX ) {
00185 return getPos ( m_columns[1] );
00186 }
00187 else {
00188 return getPosWithError ( m_columns[1], m_columns[4] );
00189 }
00190 }
00191
00192 return getPos ( m_columns[2] );
00193 }
00194
00195 void MeshProjector::addPointReps()
00196 {
00197 m_pointreps.push_back ( "ColorBox" );
00198 }
00199
00200 DataSource *
00201 MeshProjector::
00202 createNTuple () const
00203 {
00204
00205 unsigned int x_col = m_columns[0];
00206 unsigned int y_col = m_columns[1];
00207 unsigned int z_col = m_columns[2];
00208
00209 unsigned int x_err = m_columns[3];
00210 unsigned int y_err = m_columns[4];
00211
00212 unsigned int columns = dp::SIZE;
00213 NTuple * ntuple = new NTuple ( columns );
00214
00215 vector < string > labels;
00216 labels.push_back ( m_ntuple -> getLabelAt ( x_col ) );
00217 labels.push_back ( m_ntuple -> getLabelAt ( y_col ) );
00218 labels.push_back ( m_ntuple -> getLabelAt ( z_col ) );
00219
00220 if ( x_err < UINT_MAX ) {
00221 labels.push_back ( m_ntuple -> getLabelAt ( x_err ) );
00222 } else {
00223 labels.push_back ( dp::XWIDTH );
00224 }
00225
00226 if ( y_err < UINT_MAX ) {
00227 labels.push_back ( m_ntuple -> getLabelAt ( y_err ) );
00228 } else {
00229 labels.push_back ( dp::YWIDTH );
00230 }
00231 labels.push_back ( " z error" );
00232
00233 ntuple->setLabels ( labels );
00234
00235 unsigned int size = m_ntuple -> rows ();
00236 ntuple -> reserve ( size );
00237
00238 fillProjectedValues ( ntuple );
00239
00240 return ntuple;
00241 }
00242
00250 void
00251 MeshProjector::
00252 fillProjectedValues ( DataSource * ntuple, bool in_range ) const
00253 {
00254 ntuple -> clear ();
00255
00256 unsigned int x_col = m_columns[0];
00257 unsigned int y_col = m_columns[1];
00258 unsigned int z_col = m_columns[2];
00259
00260 unsigned int x_err = m_columns[3];
00261 unsigned int y_err = m_columns[4];
00262
00263 const vector < string > & labels = m_ntuple -> getLabels ();
00264 unsigned int size = labels.size();
00265 if ( size > 3 ) {
00266 if ( x_err == UINT_MAX &&
00267 labels [ dp::XERR ] == dp::XWIDTH ) x_err = dp::XERR;
00268 if ( size > 3 ) {
00269 if ( y_err == UINT_MAX &&
00270 labels [ dp::YERR ] == dp::YWIDTH ) y_err = dp::YERR;
00271 }
00272 }
00273 size = m_ntuple -> rows ();
00274 vector < double > row ( dp::SIZE );
00275 for ( unsigned int i = 0; i < size; i++ ) {
00276 if ( acceptRow ( i, m_cut_list ) == false ||
00277 ( in_range == true && inRange ( i ) == false ) ) continue;
00278
00279 row[dp::X] = m_ntuple -> valueAt ( i, x_col );
00280 row[dp::Y] = m_ntuple -> valueAt ( i, y_col );
00281 row[dp::Z] = m_ntuple -> valueAt ( i, z_col );
00282
00283
00284 double xe
00285 = x_err < UINT_MAX ? m_ntuple -> valueAt ( i, x_err ) : 0.0;
00286 double ye
00287 = y_err < UINT_MAX ? m_ntuple -> valueAt( i, y_err ) : 0.0;
00288
00289 row[dp::XERR] = xe;
00290 row[dp::YERR] = ye;
00291
00292 ntuple -> addRow ( row );
00293 }
00294 }
00295
00296 void
00297 MeshProjector::
00298 prepareValues ()
00299 {
00300 if ( m_proj_values == 0 ) {
00301 m_proj_values = createNTuple ();
00302 }
00303 else if ( isDirty () ) {
00304 fillProjectedValues ( m_proj_values, true );
00305 }
00306
00307 setDirty ( false );
00308 }
00309
00310 bool
00311 MeshProjector::
00312 inRangeWithZ ( int row, bool with_z ) const
00313 {
00314 bool accept = true;
00315
00316 for ( unsigned int i = 0; i < 2; i++ ) {
00317 AxisModelBase * model = i == 0 ? m_x_axis : m_y_axis;
00318 const Range & range = model -> getRange ( false );
00319 unsigned int vcolumn = m_columns[i];
00320 unsigned int wcolumn = m_columns[i+3];
00321 double value = m_ntuple -> valueAt ( row, vcolumn );
00322 double width = m_ntuple -> valueAt ( row, wcolumn );
00323 bool in = range.includes ( value + width ) ||
00324 range.includes ( value - width );
00325 accept &= in;
00326 }
00327 if ( with_z ) {
00328 const Range & range = m_z_axis -> getRange ( false );
00329 double value = m_ntuple -> valueAt ( row, m_columns[2] );
00330 bool in = range.includes ( value );
00331 accept &= in;
00332 }
00333
00334 return accept;
00335 }
00336
00337 bool
00338 MeshProjector::
00339 inRange ( int row ) const
00340 {
00341 return inRangeWithZ ( row, true );
00342 }
00343
00344 Range
00345 MeshProjector::
00346 preferredRange ( Axes::Type axis ) const
00347 {
00348 Range range;
00349 double low = DBL_MAX;
00350 double pos = DBL_MAX;
00351 double high = -DBL_MIN;
00352 if ( axis == Axes::Z ) {
00353 std::size_t rows = m_ntuple -> rows ();
00354 for ( unsigned int row = 0; row < rows; row++ ) {
00355 bool accept = inRangeWithZ ( row, false );
00356 if ( accept ) {
00357 double value = m_ntuple -> valueAt ( row, m_columns[2] );
00358 low = std::min ( low, value );
00359 if ( value > 0 ) {
00360 pos = std::min ( pos, value );
00361 }
00362 high = std::max ( high, value );
00363 }
00364 }
00365 range.setRange ( low, high, pos );
00366 }
00367 else {
00368 range = ProjectorBase::preferredRange ( axis );
00369 }
00370
00371 return range;
00372 }
00373
00374
00375 const string & MeshProjector::getZLabel () const
00376 {
00377 return m_proj_values->getLabelAt ( dp::Z );
00378 }
00379
00380
00385 double MeshProjector::getZValue ( double x, double y ) const
00386 {
00387
00388 double retval = 0;
00389
00390 const vector < double > & xs = m_proj_values -> getColumn ( dp::X );
00391 const vector < double > & ys = m_proj_values -> getColumn ( dp::Y );
00392 const vector < double > & zs = m_proj_values -> getColumn ( dp::Z );
00393 const vector < double > & xerr = m_proj_values -> getColumn ( dp::XERR );
00394 const vector < double > & yerr = m_proj_values -> getColumn ( dp::YERR );
00395
00396 unsigned int size = xs.size();
00397 for ( unsigned int i = 0; i < size; i++ ) {
00398 if ( x>xs[i]-xerr[i] && x<xs[i]+xerr[i] &&
00399 y>ys[i]-yerr[i] && y<ys[i]+yerr[i] ) {
00400 retval = zs[i];
00401
00402
00403 break;
00404 }
00405 }
00406
00407 return retval;
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425 }