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

Generated for HippoDraw Class Library by doxygen