MeshProjector.cxx

Go to the documentation of this file.
00001 
00012 #ifdef _MSC_VER
00013 // Include max() and min() missing from Microsoft Visual C++.
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 // For some reason, implementing empty destructor decrease code size
00069 // by 5 kbytes.
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     // has to be Z
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 ) {     // Was m_columns[2], should be a bug
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 ) {     // Was m_coloumns[3], should be a bug
00185       return getPos ( m_columns[1] );
00186     }
00187     else {
00188       return getPosWithError ( m_columns[1], m_columns[4] );
00189     }
00190   }
00191   // has to be Z
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];        // Was 3, should be a bug
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" ); // for 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       // Assume (x,y) can not be in another box
00403       break;
00404     }
00405   }
00406 
00407   return retval;
00408   
00409   
00410   /* TO REMOVE: Old algorithm, search for the nestest data point.
00411      
00412   const Range & xr = m_x_axis->getRange ( true );
00413   const Range & yr = m_y_axis->getRange ( true );
00414   
00415   double xe = 0.1 * xr.length();
00416   double ye = 0.1 * yr.length();
00417   double distanceSquare = xe*xe+ye*ye;
00418   
00419   if ( (x-xs[i])*(x-xs[i])+(y-ys[i])*(y-ys[i]) < distanceSquare)  {
00420   // Update the nearest point info.
00421   distanceSquare = (x-xs[i])*(x-xs[i])+(y-ys[i])*(y-ys[i]); 
00422   retval = zs[i]; 
00423   }
00424   */
00425 }

Generated for HippoDraw Class Library by doxygen