Isis 3.0 Programmer Reference
Back | Home
ScatterPlotData.cpp
1 #include "IsisDebug.h"
2 #include "ScatterPlotData.h"
3 
4 #include <algorithm>
5 
6 #include <QtCore>
7 
8 #include "Brick.h"
9 #include "SpecialPixel.h"
10 
11 namespace Isis {
27  Cube *xCube, int xCubeBand, int xBinCount,
28  Cube *yCube, int yCubeBand, int yBinCount,
29  QwtInterval sampleRange, QwtInterval lineRange) : QwtRasterData(),
30  m_xDnToBinStretch(new Stretch), m_yDnToBinStretch(new Stretch),
31  m_counts(
32  new QVector< QVector<int> >(yBinCount, QVector<int>(xBinCount))),
33  m_alarmedBins(new QMap<int, bool>) {
34  int startLine = qRound(lineRange.minValue());
35  int endLine = qRound(lineRange.maxValue());
36  ASSERT(xCube->lineCount() == yCube->lineCount());
37 
38  Histogram *xCubeHist = new Histogram(*xCube, xCubeBand, NULL,
39  sampleRange.minValue(), lineRange.minValue(),
40  sampleRange.maxValue(), lineRange.maxValue(),
41  xBinCount, true);
42  m_xCubeMin = xCubeHist->Minimum();
43  m_xCubeMax = xCubeHist->Maximum();
44 
45 
46  Histogram *yCubeHist = new Histogram(*yCube, yCubeBand, NULL,
47  sampleRange.minValue(), lineRange.minValue(),
48  sampleRange.maxValue(), lineRange.maxValue(),
49  yBinCount, true);
50  m_yCubeMin = yCubeHist->Minimum();
51  m_yCubeMax = yCubeHist->Maximum();
52 
53 
54  m_xDnToBinStretch->AddPair(m_xCubeMin, 0);
55  m_xDnToBinStretch->AddPair(m_xCubeMax, xBinCount - 1);
56 
57  m_yDnToBinStretch->AddPair(m_yCubeMin, 0);
58  m_yDnToBinStretch->AddPair(m_yCubeMax, yBinCount - 1);
59 
60  m_maxCount = 0;
61 
62  Brick brick1((int)(sampleRange.maxValue() - sampleRange.minValue() + 1),
63  1, 1, xCube->pixelType());
64  Brick brick2((int)(sampleRange.maxValue() - sampleRange.minValue() + 1),
65  1, 1, yCube->pixelType());
66  ASSERT(xCube->sampleCount() == yCube->sampleCount());
67  ASSERT(brick1.size() == brick2.size());
68 
69  for (int line = startLine; line <= endLine; line++) {
70  brick1.SetBasePosition(qRound(sampleRange.minValue()), line, xCubeBand);
71  xCube->read(brick1);
72 
73  brick2.SetBasePosition(qRound(sampleRange.minValue()), line, yCubeBand);
74  yCube->read(brick2);
75 
76  for (int i = 0; i < brick1.size(); i++) {
77  double xDn = brick1[i];
78  double yDn = brick2[i];
79 
80  if (!IsSpecial(xDn) && !IsSpecial(yDn)) {
81  double x = m_xDnToBinStretch->Map(xDn);
82  double y = m_yDnToBinStretch->Map(yDn);
83 
84  if (!IsSpecial(x) && !IsSpecial(y)) {
85  int roundedX = qRound(x);
86  int roundedY = qRound(y);
87 
88  if (roundedX >= 0 && roundedX < xBinCount &&
89  roundedY >= 0 && roundedY < yBinCount) {
90  int value = (*m_counts)[roundedY][roundedX] + 1;
91  (*m_counts)[roundedY][roundedX] = value;
92 
93  m_maxCount = qMax(m_maxCount, value);
94  }
95  }
96  }
97  }
98  }
99 
100  setInterval(Qt::XAxis, QwtInterval(m_xCubeMin, m_xCubeMax));
101  setInterval(Qt::YAxis, QwtInterval(m_yCubeMin, m_yCubeMax));
102  setInterval(Qt::ZAxis, QwtInterval(0, m_maxCount));
103  }
104 
105 
113  m_xDnToBinStretch.reset(new Stretch(*other.m_xDnToBinStretch));
114  m_yDnToBinStretch.reset(new Stretch(*other.m_yDnToBinStretch));
115  m_counts.reset(new QVector< QVector<int> >(*other.m_counts));
116  m_alarmedBins.reset(new QMap< int, bool>(*other.m_alarmedBins));
117  m_maxCount = other.m_maxCount;
118  m_xCubeMin = other.m_xCubeMin;
119  m_xCubeMax = other.m_xCubeMax;
120  m_yCubeMin = other.m_yCubeMin;
121  m_yCubeMax = other.m_yCubeMax;
122  }
123 
124 
130  }
131 
132 
139  return new ScatterPlotData(*this);
140  }
141 
142 
152  double ScatterPlotData::value(double x, double y) const {
153  double value = 0;
154 
155  QPair<int, int> indices = binXYIndices(x, y);
156  int index = binIndex(indices.first, indices.second);
157 
158  if (index != -1 && (*m_alarmedBins)[index])
159  value = m_maxCount;
160  else
161  value = binCount(indices.first, indices.second);
162 
163  return value;
164  }
165 
166 
172  double ScatterPlotData::xCubeMin() const {
173  return m_xCubeMin;
174  }
175 
176 
182  double ScatterPlotData::xCubeMax() const {
183  return m_xCubeMax;
184  }
185 
186 
192  double ScatterPlotData::yCubeMin() const {
193  return m_yCubeMin;
194  }
195 
196 
202  double ScatterPlotData::yCubeMax() const {
203  return m_yCubeMax;
204  }
205 
206 
215  m_counts.swap(other.m_counts);
216  m_alarmedBins.swap(other.m_alarmedBins);
217  std::swap(m_maxCount, other.m_maxCount);
218  std::swap(m_xCubeMin, other.m_xCubeMin);
219  std::swap(m_xCubeMax, other.m_xCubeMax);
220  std::swap(m_yCubeMin, other.m_yCubeMin);
221  std::swap(m_yCubeMax, other.m_yCubeMax);
222  }
223 
224 
233  QPair<int, int> indices = binXYIndices(index);
234  int xIndex = indices.first;
235  int yIndex = indices.second;
236 
237  if (xIndex != -1 && yIndex != -1) {
238  int xSize = 0;
239  int ySize = m_counts->size();
240 
241  // Assume square 2D structurs
242  if (ySize > 0)
243  xSize = (*m_counts)[0].size();
244 
245  double percentAcrossXRange = ((double)xIndex / (double)xSize);
246  double xDnValue = m_xCubeMin +
247  percentAcrossXRange * (m_xCubeMax - m_xCubeMin);
248 
249  double percentAcrossYRange = ((double)yIndex / (double)ySize);
250  double yDnValue = m_yCubeMin +
251  percentAcrossYRange * (m_yCubeMax - m_yCubeMin);
252 
253  return QPair<double, double>(xDnValue, yDnValue);
254  }
255 
256 
257  QString msg = "Bin at index [" + QString::number(index) + "] not found. "
258  "There are [" + QString::number(numberOfBins()) + "] bins";
260  }
261 
262 
269  int ScatterPlotData::binCount(int binIndex) const {
270  QPair<int, int> indices = binXYIndices(binIndex);
271  return binCount(indices.first, indices.second);
272  }
273 
274 
281  int xSize = 0;
282  int ySize = m_counts->size();
283 
284  // Assume square 2D structurs
285  if (ySize > 0)
286  xSize = (*m_counts)[0].size();
287 
288  return xSize * ySize;
289  }
290 
291 
298  QVector<double> xValues;
299 
300  int ySize = m_counts->size();
301  if (ySize) {
302  int xSize = (*m_counts)[0].size();
303  xValues.resize(xSize);
304 
305  for (int xIndex = 0; xIndex < xSize; xIndex++) {
306  double percentAcrossXRange = ((double)xIndex / (double)xSize);
307  xValues[xIndex] = m_xCubeMin +
308  percentAcrossXRange * (m_xCubeMax - m_xCubeMin);
309  }
310  }
311 
312  return xValues;
313  }
314 
315 
323  void ScatterPlotData::alarm(double x, double y) {
324  int binToAlarm = binIndex(x, y);
325  if (binToAlarm != -1)
326  (*m_alarmedBins)[binToAlarm] = true;
327  }
328 
329 
334  m_alarmedBins->clear();
335  }
336 
337 
344  QRectF ScatterPlotData::pixelHint(const QRectF &area) const {
345  QRectF hint;
346 
347  if (m_xDnToBinStretch->Pairs() > 1 && m_yDnToBinStretch->Pairs() > 1) {
348  hint = QRectF(
349  QPointF(m_xCubeMin, m_yCubeMin),
350  QSizeF(m_xDnToBinStretch->Input(1) - m_xDnToBinStretch->Input(0),
351  m_yDnToBinStretch->Input(1) - m_yDnToBinStretch->Input(1)));
352  }
353 
354  return hint;
355  }
356 
357 
366  ScatterPlotData tmp(other);
367 
368  swap(tmp);
369 
370  return *this;
371  }
372 
373 
381  int ScatterPlotData::binCount(int xIndex, int yIndex) const {
382  int count = 0;
383 
384  if (yIndex >= 0 && yIndex < m_counts->size()) {
385  if (xIndex >= 0 && xIndex < (*m_counts)[yIndex].size()) {
386  count = (*m_counts)[yIndex][xIndex];
387  }
388  }
389 
390  return count;
391  }
392 
393 
402  int ScatterPlotData::binIndex(int xIndex, int yIndex) const {
403  int xSize = 0;
404  int ySize = m_counts->size();
405 
406  // Assume square 2D structurs
407  if (ySize > 0)
408  xSize = (*m_counts)[0].size();
409 
410  int index = -1;
411  if ((xIndex >= 0 && xIndex < xSize) && (yIndex >= 0 && yIndex < ySize))
412  index = xSize * yIndex + xIndex;
413 
414  return index;
415  }
416 
417 
425  int ScatterPlotData::binIndex(double x, double y) const {
426  QPair<int, int> indices = binXYIndices(x, y);
427  return binIndex(indices.first, indices.second);
428  }
429 
430 
438  int xSize = 0;
439  int ySize = m_counts->size();
440 
441  // Assume square 2D structurs
442  if (ySize > 0)
443  xSize = (*m_counts)[0].size();
444 
445  int yIndex = (binIndex / xSize);
446  binIndex -= yIndex * xSize;
447 
448  int xIndex = binIndex;
449 
450  if (xIndex < 0 || yIndex < 0 || xIndex >= xSize || yIndex >= ySize) {
451  QString msg = "Bin at index [" + QString::number(binIndex) + "] not found. "
452  "There are [" + QString::number(numberOfBins()) + "] bins";
454  }
455 
456  return QPair<int, int>(xIndex, yIndex);
457  }
458 
459 
467  QPair<int, int> ScatterPlotData::binXYIndices(double x, double y) const {
468  QPair<int, int> indices(-1, -1);
469 
470  if (m_counts->size() && m_counts->at(0).size()) {
471  double xBinPosition = m_xDnToBinStretch->Map(x);
472  double yBinPosition = m_yDnToBinStretch->Map(y);
473 
474  if (!IsSpecial(xBinPosition) && !IsSpecial(yBinPosition)) {
475  int discreteXBin = qRound(xBinPosition);
476  int discreteYBin = qRound(yBinPosition);
477 
478  if (discreteXBin >= 0 && discreteXBin < m_counts->at(0).size() &&
479  discreteYBin >= 0 && discreteYBin < m_counts->size()) {
480  indices = QPair<int, int>(discreteXBin, discreteYBin);
481  }
482  }
483  }
484 
485  return indices;
486  }
487 }
488 
int m_maxCount
The maximum value in m_counts, stored for efficiency.
QVector< double > discreteXValues() const
Get a list of all of the x-bin center values for this scatter plot.
ScatterPlotData(Cube *xCube, int xCubeBand, int xBinCount, Cube *yCube, int yCubeBand, int yBinCount, QwtInterval sampleRange, QwtInterval lineRange)
ScatterPlotDataConstructor.
virtual double value(double x, double y) const
This gets called every time the scatter plot is re-drawn.
PixelType pixelType() const
Definition: Cube.cpp:1355
double yCubeMax() const
Return the max DN value for the y-axis cube&#39;s data range.
int numberOfBins() const
Get the total number of bins (bin count in x * bin count in y).
double m_xCubeMax
The maximum DN value for the x cube.
double Minimum() const
Returns the absolute minimum double found in all data passed through the AddData method.
Definition: Statistics.cpp:399
double m_yCubeMin
The minimum DN value for the y cube.
Buffer for containing a three dimensional section of an image.
Definition: Brick.h:60
double xCubeMin() const
Return the min DN value for the x-axis cube&#39;s data range.
int binIndex(int xIndex, int yIndex) const
Get the single-index position given an x/y index position.
void read(Blob &blob) const
This method will read data from the specified Blob object.
Definition: Cube.cpp:686
This error is for when a programmer made an API call that was illegal.
Definition: IException.h:154
QPair< int, int > binXYIndices(int binIndex) const
Get the 2D index index position given a 1D (flat) index position.
~ScatterPlotData()
Destructor.
double yCubeMin() const
Return the min DN value for the y-axis cube&#39;s data range.
QRectF pixelHint(const QRectF &area) const
This is a hint given to qwt for how to render a pixel in the spectrogram.
int sampleCount() const
Definition: Cube.cpp:1404
double xCubeMax() const
Return the max DN value for the y-axis cube&#39;s data range.
Container of a cube histogram.
Definition: Histogram.h:78
Pixel value mapper.
Definition: Stretch.h:72
void alarm(double x, double y)
Alarm the bin (highlight it) at the given x/y DN value.
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:38
int binCount(int binIndex) const
Get the count (number of values) which fall into the bin at index.
double Maximum() const
Returns the absolute maximum double found in all data passed through the AddData method.
Definition: Statistics.cpp:420
bool IsSpecial(const double d)
Returns if the input pixel is special.
Definition: SpecialPixel.h:199
double m_yCubeMax
The maximum DN value for the y cube.
virtual QwtRasterData * copy() const
Returns a copy of the ScatterPlotData object.
QScopedPointer< Stretch > m_xDnToBinStretch
Stretch 1.
QScopedPointer< QVector< QVector< int > > > m_counts
The bin counts stored by 2D (x/y) index position.
This is the QwtRasterData for a scatter plot.
ScatterPlotData & operator=(const ScatterPlotData &other)
Take the data from other and copy it into this.
void clearAlarms()
Forget all alarmed bins (viewport-&gt;plot).
QScopedPointer< QMap< int, bool > > m_alarmedBins
map from bin index to alarm state (true for alarmed)
void swap(ScatterPlotData &other)
This is part of the copy-and-swap paradigm.
QScopedPointer< Stretch > m_yDnToBinStretch
Stretch 2.
Isis exception class.
Definition: IException.h:99
QPair< double, double > binXY(int binIndex) const
Get the center X/Y Dn values for the bin at index.
int lineCount() const
Definition: Cube.cpp:1331
IO Handler for Isis Cubes.
Definition: Cube.h:158
double m_xCubeMin
The minimum DN value for the x cube.

U.S. Department of the Interior | U.S. Geological Survey
ISIS | Privacy & Disclaimers | Astrogeology Research Program
To contact us, please post comments and questions on the ISIS Support Center
File Modified: 07/12/2023 23:28:44