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