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