00001
00012 #ifdef _MSC_VER
00013
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
00277
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
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;
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
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
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
00507
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
00518
00519
00520
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 }