MapMatrixProjector.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 "MapMatrixProjector.h"
00018 
00019 #include "axes/AxisModelBase.h"
00020 
00021 #include "datasrcs/DataPointTuple.h"
00022 #include "datasrcs/RTuple.h"
00023 
00024 #include <algorithm>
00025 #include <numeric>
00026 
00027 #include <cfloat>
00028 #include <climits>
00029 #include <cmath>
00030 
00031 #include <cassert>
00032 
00033 using namespace hippodraw;
00034 
00035 #ifdef ITERATOR_MEMBER_DEFECT
00036 using namespace std;
00037 #else
00038 using std::abs;
00039 using std::accumulate;
00040 using std::find;
00041 using std::max;
00042 using std::min;
00043 using std::sqrt;
00044 using std::string;
00045 using std::vector;
00046 #endif
00047 
00048 MapMatrixProjector::MapMatrixProjector ( )
00049   : NTupleProjector ( 2 ),
00050     m_x_label ( "x" ),
00051     m_y_label ( "y" ),
00052     m_cols ( 0 ),
00053     m_rows ( 0 ),
00054     m_x_step ( 1.0 ),
00055     m_y_step ( 1.0 ),
00056     m_x_origin ( 0.0 ),
00057     m_y_origin ( 0.0 ),
00058     m_null_value ( 0.0 ),
00059     m_transpose ( false )
00060 {
00061   m_binding_options.push_back ( "Z" );
00062   m_min_bindings = 1;
00063   addPointReps();
00064 }
00065 
00070 MapMatrixProjector::
00071 MapMatrixProjector ( const MapMatrixProjector & projector )
00072   : ProjectorBase ( projector ),
00073     NTupleProjector( projector ),
00074     m_x_label ( projector.m_x_label ),
00075     m_y_label ( projector.m_y_label ),
00076     m_cols ( projector.m_cols ),
00077     m_rows ( projector.m_rows ),
00078     m_x_step ( projector.m_x_step ),
00079     m_y_step ( projector.m_y_step ),
00080     m_x_origin ( projector.m_x_origin ),
00081     m_y_origin ( projector.m_y_origin ),
00082     m_null_value ( projector.m_null_value ),
00083     m_transpose ( projector.m_transpose )
00084 {  
00085   addPointReps();
00086 }
00087 
00088 ProjectorBase * MapMatrixProjector::clone()
00089 {
00090   return new MapMatrixProjector( *this );
00091 }
00092 
00093 void
00094 MapMatrixProjector::
00095 setNumberOfBins ( hippodraw::Axes::Type axis, unsigned int number )
00096 {
00097   assert ( axis == Axes::X || axis == Axes::Y );
00098 
00099   if ( axis == Axes::X ) m_cols = number;
00100   else m_rows = number;
00101 }
00102 
00103 int
00104 MapMatrixProjector::
00105 getNumberOfBins ( hippodraw::Axes::Type axis ) const
00106 {
00107   assert ( axis != Axes::Z );
00108   int bins = axis == Axes::X ? m_cols : m_rows;
00109 
00110   return bins;
00111 }
00112 
00113 const Range &
00114 MapMatrixProjector::
00115 setBinWidth ( hippodraw::Axes::Type axis, double step )
00116 {
00117   if ( axis == Axes::X ) {
00118     m_x_step = step;
00119   }
00120   else if ( axis == Axes::Y ) {
00121     m_y_step = step;
00122   }
00123   else if ( axis == Axes::Z ) {
00124     m_scale_factor = step;
00125   }
00126 
00127   return getRange ( axis );
00128 }
00129 
00130 double
00131 MapMatrixProjector::
00132 getBinWidth ( hippodraw::Axes::Type axis ) const
00133 {
00134   if ( axis == Axes::X ) {
00135     return m_x_step;
00136   }
00137   if ( axis == Axes::Y ) {
00138     return m_y_step;
00139   }
00140   if ( axis == Axes::Z ) {
00141     return m_scale_factor;
00142   }
00143   assert ( false );
00144   return 0.0;
00145 }
00146 
00147 void 
00148 MapMatrixProjector::
00149 setOffset ( hippodraw::Axes::Type axis, double origin )
00150 {
00151   if ( axis == Axes::X ) {
00152     m_x_origin = origin;
00153     return;
00154   }
00155   if ( axis == Axes::Y ) {
00156     m_y_origin = origin;
00157     return;
00158   }
00159   assert ( false );
00160 }
00161 
00162 double
00163 MapMatrixProjector::
00164 getOffset ( hippodraw::Axes::Type axis ) const
00165 {
00166   if ( axis == Axes::X ) {
00167     return m_x_origin;
00168   }
00169   if ( axis == Axes::Y ) {
00170     return m_y_origin;
00171   }
00172   assert ( false );
00173   return 0.0;
00174 }
00175 
00176 bool
00177 MapMatrixProjector::
00178 inRange ( int row ) const
00179 {
00180   return inRangeWithZ ( row, true );
00181 }
00182 
00183 bool
00184 MapMatrixProjector::
00185 inRangeWithZ ( int row, bool use_z ) const
00186 {
00187   bool accept = true;
00188 
00189   std::size_t cindex = calcColumnIndex ( row );
00190   double lvalue = m_x_origin + cindex * m_x_step;
00191   const Range & x_range = m_x_axis -> getRange ( false );
00192   bool in = x_range.includes ( lvalue ) ||
00193             x_range.includes ( lvalue + m_x_step );
00194   accept &= in;
00195 
00196   if ( accept ) {
00197     std::size_t rindex = calcRowIndex ( row );
00198     double bvalue = m_y_origin + rindex * m_y_step;
00199     const Range & y_range = m_y_axis -> getRange ( false );
00200     in = y_range.includes ( bvalue ) ||
00201          y_range.includes ( bvalue + m_y_step );
00202     accept &= in;
00203   }
00204 
00205   if ( accept && use_z == true ) {
00206     const Range & z_range = m_z_axis->getRange ( false );
00207     double value = m_ntuple -> valueAt ( row, m_columns[0] );
00208     accept &= z_range.includes ( value );
00209   }
00210 
00211   return accept;
00212 }
00213 
00214 void MapMatrixProjector::changedNTuple()
00215 {
00216   unsigned int cols = m_ntuple->columns () - 1;
00217   if ( m_columns[0] > cols ) m_columns[0] = cols;
00218   if ( m_columns[1] > cols ) m_columns[1] = UINT_MAX;
00219 }
00220 
00221 Range MapMatrixProjector::valueRange () const
00222 {
00223   return dataRangeOn ( Axes::Z );
00224 }
00225 
00226 namespace dp = hippodraw::DataPoint3DTuple;
00227 
00228 Range
00229 MapMatrixProjector::
00230 dataRangeOnValue () const
00231 {
00232   MapMatrixProjector * mmp = const_cast < MapMatrixProjector *> ( this );
00233   mmp -> prepareValues ();
00234   if ( m_proj_values -> empty () ) {
00235     return Range ( 0.0, 1.0, 0.5 );
00236   }
00237   const vector < double > & values = m_proj_values -> getColumn ( dp::Z );
00238 
00239   return Range ( values );
00240 }
00241 
00242 Range
00243 MapMatrixProjector::
00244 dataRangeOn ( hippodraw::Axes::Type axis ) const
00245 {
00246   assert ( axis == Axes::X || axis == Axes::Y || axis == Axes::Z );
00247 
00248   Range range;
00249 
00250   if ( axis == Axes::X ) {
00251     double len = m_x_origin + m_cols * m_x_step;
00252     if ( m_x_step < 0. ) {
00253       range.setRange ( len, m_x_origin, - m_x_step );
00254     } else {
00255       range.setRange ( m_x_origin, len, m_x_step );
00256     }
00257   }
00258 
00259   if ( axis == Axes::Y ) {
00260     double len = m_y_origin + m_rows * m_y_step;
00261     if ( m_y_step < 0. ) {
00262       range.setRange ( len, m_y_origin, - m_y_step );
00263     }
00264     else {
00265       range.setRange ( m_y_origin, len, m_y_step );
00266     }
00267   }
00268 
00269   if ( axis == Axes::Z ) {
00270     range = dataRangeOnValue ();
00271   }
00272 
00273   return range;
00274 }
00275 
00276 /* @bug @@@@ This method can create low range > high range from
00277    transform log log */
00278 Range
00279 MapMatrixProjector::
00280 preferredRange ( Axes::Type axis ) const
00281 {
00282   Range range;
00283   double low = DBL_MAX;
00284   double pos = DBL_MAX;
00285   double high = -DBL_MIN;
00286  
00287   if ( axis == Axes::Z ) {
00288     std::size_t rows = m_ntuple -> rows ();
00289     unsigned int used = 0;
00290     for ( unsigned int row = 0; row < rows; row++ ) {
00291       bool accept = inRangeWithZ ( row, false );
00292       if ( accept ) {
00293         double value = m_ntuple -> valueAt ( row, m_columns[0] );
00294         low = std::min ( low, value );
00295         if ( value > 0 ) {
00296           pos = std::min ( pos, value );
00297         }
00298         high = std::max ( high, value );
00299         used++;
00300       }
00301     }
00302     range.setRange ( low, high, pos );
00303   }
00304   else {
00305     range = ProjectorBase::preferredRange ( axis );
00306   }
00307 
00308   return range;
00309 }
00310 double
00311 MapMatrixProjector::
00312 getPosOn ( hippodraw::Axes::Type axis ) const
00313 {
00314   assert ( axis == Axes::X || axis == Axes::Y || axis == Axes::Z );
00315 
00316   if ( axis == Axes::X ) {
00317     return 0.5 * std::abs ( m_x_step );
00318   }
00319   if ( axis == Axes::Y ) {
00320     return 0.5 * std::abs ( m_y_step );
00321   }
00322   if ( m_columns[1] == UINT_MAX ) {
00323     return getPos ( m_columns[0] );
00324   }
00325   //It has to be Y with an error.
00326   return getPosWithError ( m_columns[0], m_columns[1] );
00327 }
00328 
00329 const string & MapMatrixProjector::getXLabel() const
00330 {
00331   return m_x_label;
00332 }
00333 
00334 const string & MapMatrixProjector::getYLabel ( bool ) const
00335 {
00336   return m_y_label;
00337 }
00338 
00339 const string &
00340 MapMatrixProjector::
00341 getZLabel () const
00342 {
00343   return m_ntuple->getLabelAt( m_columns[0] );
00344 }
00345 
00346 
00351 double
00352 MapMatrixProjector::
00353 getAverage ( hippodraw::Axes::Type axis ) const
00354 {
00355   MapMatrixProjector * p = const_cast < MapMatrixProjector * > ( this );
00356   p -> prepareValues ();
00357 
00358   unsigned int col = 3;    // bad value
00359   switch ( axis ) {
00360       
00361   case Axes::X:
00362     col = dp::X;
00363     break;
00364     
00365   case Axes::Y:
00366     col = dp::Y;
00367       break;
00368     
00369   case Axes::Z:
00370     col = dp::Z;
00371     break;
00372 
00373   default:
00374     break;
00375   }
00376   assert ( col < 3 );
00377 
00378   const DataSource * ntuple = getProjectedValues ();
00379   const vector < double > & data = ntuple -> getColumn ( col );
00380 
00381   unsigned int size = ntuple -> rows ();
00382 
00383   double sum = 0.0;
00384   sum = accumulate ( data.begin(), data.end(), sum );
00385 
00386   return sum / size;
00387 }
00388 
00389 void MapMatrixProjector::addPointReps()
00390 {
00391   m_pointreps.push_back ( "ColorBox" );
00392   m_pointreps.push_back ( "Contour" );
00393 }
00394 
00395 void
00396 MapMatrixProjector::
00397 setNTuple ( const DataSource * ntuple ) 
00398 {
00399   NTupleProjector::setNTuple ( ntuple );
00400 
00401   unsigned int size = ntuple->rows ();
00402   double s = static_cast < double > ( size );
00403   double side = sqrt ( s );
00404 
00405   m_rows = static_cast < unsigned int > ( side );
00406   m_cols = static_cast < unsigned int > ( side );
00407 
00408   setDirty ();
00409 }
00410 
00411 void
00412 MapMatrixProjector::
00413 matrixTranspose ( bool yes )
00414 {
00415   m_transpose = yes;
00416 }
00417 
00422 double
00423 MapMatrixProjector::
00424 getZValue ( double x, double y ) const
00425 {
00426   double xx = ( x - m_x_origin ) / m_x_step;
00427   double yy = ( y - m_y_origin ) / m_y_step;
00428 
00429   unsigned int i_x = static_cast < unsigned int> ( xx );
00430   unsigned int i_y = static_cast < unsigned int> ( yy );
00431 
00432   unsigned int row;
00433   if ( m_transpose ) {
00434     row = i_x + m_cols * i_y; 
00435   }
00436   else {
00437     row = i_x * m_rows + i_y;
00438   }
00439 
00440   unsigned int size = m_ntuple -> rows ();
00441   double value = 0.0;
00442 
00443   if ( row < size ) {
00444     value = m_ntuple -> valueAt ( row, m_columns[0] );
00445   }
00446   return value;
00447 }
00448 
00449 DataSource *
00450 MapMatrixProjector::
00451 createNTuple () const
00452 {
00453   unsigned int z_err = m_columns[1];
00454 
00455   unsigned int columns = 6;
00456   RTuple * ntuple = new RTuple ( columns );
00457 
00458   // using setLabelAt save 2KB compared to setLabels()
00459   ntuple -> setLabelAt ( getXLabel (), 0 );
00460   ntuple -> setLabelAt ( getYLabel ( false ), 1 );
00461   ntuple -> setLabelAt ( getZLabel (), 2 );
00462   ntuple -> setLabelAt ( "Width",      3 );
00463   ntuple -> setLabelAt ( "Height",     4 );
00464   if ( z_err < UINT_MAX ) {
00465     ntuple -> setLabelAt ( m_ntuple -> getLabelAt ( z_err ), 5 );
00466   }
00467   else {
00468     ntuple -> setLabelAt ( "Error", 5 );
00469   }
00470 
00471   fillProjectedValues ( ntuple );
00472 
00473   return ntuple;
00474 }
00475 
00479 void
00480 MapMatrixProjector::
00481 fillProjectedValues ( DataSource * ntuple, bool ) const // in_range ) const
00482 {
00483   ntuple -> clear();
00484 
00485   double width_x = m_x_step;
00486   double next_x = m_x_origin + 0.5 * width_x;
00487 
00488   vector < double > row ( dp::SIZE );
00489   row[dp::XERR] = abs ( m_x_step );
00490   row[dp::YERR] = abs ( m_y_step );
00491   row[dp::ZERR] = 1.0;
00492 
00493   unsigned int l = 0;
00494   for ( unsigned int i = 0; i < m_cols; i++ ) {
00495 
00496     double x = next_x;
00497     next_x += width_x;
00498 
00499     double width_y = m_y_step;
00500     double next_y = m_y_origin + 0.5 * width_y;
00501 
00502     for ( unsigned int j = 0; j < m_rows; j++ ) {
00503       double y = next_y;
00504       next_y += width_y;
00505 
00506       // Calculate our own inex to get value because calling
00507       // getValueAt takes too long
00508       int index;
00509       if ( m_transpose ) {
00510         index = i + m_cols * j;
00511       }
00512       else {
00513         index = i * m_rows + j;
00514       }
00515       double value = m_ntuple -> valueAt ( index, m_columns [0] );
00516    
00517 //       if ( acceptRow ( l ) == false ||
00518 //         ( in_range == true && inRange ( l ) == false ) ) {
00519 //      l++;o
00520 //      continue;
00521 //       }
00522       if ( acceptRow ( l, m_cut_list ) == true ) {
00523         row[dp::Z] = value;
00524       }
00525       else {
00526         row[dp::Z] = m_null_value;
00527       }
00528       row[dp::X] = x;
00529       row[dp::Y] = y;
00530 
00531       ntuple -> addRow ( row );
00532       l++;
00533     }
00534   }
00535 
00536   vector < unsigned int > shape ( 3 );
00537   shape[0] = m_cols;
00538   shape[1] = m_rows;
00539   shape[2] = dp::SIZE;
00540 
00541   ntuple -> setShape ( shape );
00542 }
00543 
00544 void
00545 MapMatrixProjector::
00546 prepareValues ()
00547 {
00548   if ( m_proj_values == 0 ) {
00549     m_proj_values = createNTuple ();
00550   }
00551   else {
00552     if ( isDirty () ) {
00553       fillProjectedValues ( m_proj_values, true );
00554     }
00555   }
00556 
00557   setDirty ( false );
00558 }
00559 
00560 bool
00561 MapMatrixProjector::
00562 isImageConvertable () const
00563 {
00564   return true;
00565 }

Generated for HippoDraw Class Library by doxygen