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

Generated for HippoDraw Class Library by doxygen