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 <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
00276
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
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;
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
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
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
00506
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
00517
00518
00519
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 }