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