USGS

Isis 3.0 Object Programmers' Reference

Home

ScatterPlotData.cpp
1 #include "IsisDebug.h"
2 #include "ScatterPlotData.h"
3 
4 #include <algorithm>
5 
6 #include <qwt_double_range.h>
7 
8 #include <QtCore>
9 
10 #include "Brick.h"
11 #include "SpecialPixel.h"
12 
13 namespace Isis {
29  Cube *xCube, int xCubeBand, int xBinCount,
30  Cube *yCube, int yCubeBand, int yBinCount,
31  QwtInterval sampleRange, QwtInterval lineRange) : QwtRasterData(),
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  ASSERT(xCube->lineCount() == yCube->lineCount());
39 
40  Histogram *xCubeHist = new Histogram(*xCube, xCubeBand, NULL,
41  sampleRange.minValue(), lineRange.minValue(),
42  sampleRange.maxValue(), lineRange.maxValue(),
43  xBinCount, true);
44  m_xCubeMin = xCubeHist->Minimum();
45  m_xCubeMax = xCubeHist->Maximum();
46 
47 
48  Histogram *yCubeHist = new Histogram(*yCube, yCubeBand, NULL,
49  sampleRange.minValue(), lineRange.minValue(),
50  sampleRange.maxValue(), lineRange.maxValue(),
51  yBinCount, true);
52  m_yCubeMin = yCubeHist->Minimum();
53  m_yCubeMax = yCubeHist->Maximum();
54 
55 
56  m_xDnToBinStretch->AddPair(m_xCubeMin, 0);
57  m_xDnToBinStretch->AddPair(m_xCubeMax, xBinCount - 1);
58 
59  m_yDnToBinStretch->AddPair(m_yCubeMin, 0);
60  m_yDnToBinStretch->AddPair(m_yCubeMax, yBinCount - 1);
61 
62  m_maxCount = 0;
63 
64  Brick brick1((int)(sampleRange.maxValue() - sampleRange.minValue() + 1),
65  1, 1, xCube->pixelType());
66  Brick brick2((int)(sampleRange.maxValue() - sampleRange.minValue() + 1),
67  1, 1, yCube->pixelType());
68  ASSERT(xCube->sampleCount() == yCube->sampleCount());
69  ASSERT(brick1.size() == brick2.size());
70 
71  for (int line = startLine; line <= endLine; line++) {
72  brick1.SetBasePosition(qRound(sampleRange.minValue()), line, xCubeBand);
73  xCube->read(brick1);
74 
75  brick2.SetBasePosition(qRound(sampleRange.minValue()), line, yCubeBand);
76  yCube->read(brick2);
77 
78  for (int i = 0; i < brick1.size(); i++) {
79  double xDn = brick1[i];
80  double yDn = brick2[i];
81 
82  if (!IsSpecial(xDn) && !IsSpecial(yDn)) {
83  double x = m_xDnToBinStretch->Map(xDn);
84  double y = m_yDnToBinStretch->Map(yDn);
85 
86  if (!IsSpecial(x) && !IsSpecial(y)) {
87  int roundedX = qRound(x);
88  int roundedY = qRound(y);
89 
90  if (roundedX >= 0 && roundedX < xBinCount &&
91  roundedY >= 0 && roundedY < yBinCount) {
92  int value = (*m_counts)[roundedY][roundedX] + 1;
93  (*m_counts)[roundedY][roundedX] = value;
94 
95  m_maxCount = qMax(m_maxCount, value);
96  }
97  }
98  }
99  }
100  }
101 
102  setInterval(Qt::XAxis, QwtInterval(m_xCubeMin, m_xCubeMax));
103  setInterval(Qt::YAxis, QwtInterval(m_yCubeMin, m_yCubeMax));
104  setInterval(Qt::ZAxis, QwtInterval(0, m_maxCount));
105  }
106 
107 
115  m_xDnToBinStretch.reset(new Stretch(*other.m_xDnToBinStretch));
116  m_yDnToBinStretch.reset(new Stretch(*other.m_yDnToBinStretch));
117  m_counts.reset(new QVector< QVector<int> >(*other.m_counts));
118  m_alarmedBins.reset(new QMap< int, bool>(*other.m_alarmedBins));
119  m_maxCount = other.m_maxCount;
120  m_xCubeMin = other.m_xCubeMin;
121  m_xCubeMax = other.m_xCubeMax;
122  m_yCubeMin = other.m_yCubeMin;
123  m_yCubeMax = other.m_yCubeMax;
124  }
125 
126 
132  }
133 
134 
141  return new ScatterPlotData(*this);
142  }
143 
144 
154  double ScatterPlotData::value(double x, double y) const {
155  double value = 0;
156 
157  QPair<int, int> indices = binXYIndices(x, y);
158  int index = binIndex(indices.first, indices.second);
159 
160  if (index != -1 && (*m_alarmedBins)[index])
161  value = m_maxCount;
162  else
163  value = binCount(indices.first, indices.second);
164 
165  return value;
166  }
167 
168 
174  double ScatterPlotData::xCubeMin() const {
175  return m_xCubeMin;
176  }
177 
178 
184  double ScatterPlotData::xCubeMax() const {
185  return m_xCubeMax;
186  }
187 
188 
194  double ScatterPlotData::yCubeMin() const {
195  return m_yCubeMin;
196  }
197 
198 
204  double ScatterPlotData::yCubeMax() const {
205  return m_yCubeMax;
206  }
207 
208 
217  m_counts.swap(other.m_counts);
218  m_alarmedBins.swap(other.m_alarmedBins);
219  std::swap(m_maxCount, other.m_maxCount);
220  std::swap(m_xCubeMin, other.m_xCubeMin);
221  std::swap(m_xCubeMax, other.m_xCubeMax);
222  std::swap(m_yCubeMin, other.m_yCubeMin);
223  std::swap(m_yCubeMax, other.m_yCubeMax);
224  }
225 
226 
235  QPair<int, int> indices = binXYIndices(index);
236  int xIndex = indices.first;
237  int yIndex = indices.second;
238 
239  if (xIndex != -1 && yIndex != -1) {
240  int xSize = 0;
241  int ySize = m_counts->size();
242 
243  // Assume square 2D structurs
244  if (ySize > 0)
245  xSize = (*m_counts)[0].size();
246 
247  double percentAcrossXRange = ((double)xIndex / (double)xSize);
248  double xDnValue = m_xCubeMin +
249  percentAcrossXRange * (m_xCubeMax - m_xCubeMin);
250 
251  double percentAcrossYRange = ((double)yIndex / (double)ySize);
252  double yDnValue = m_yCubeMin +
253  percentAcrossYRange * (m_yCubeMax - m_yCubeMin);
254 
255  return QPair<double, double>(xDnValue, yDnValue);
256  }
257 
258 
259  IString msg = "Bin at index [" + IString(index) + "] not found. "
260  "There are [" + IString(numberOfBins()) + "] bins";
262  }
263 
264 
271  int ScatterPlotData::binCount(int binIndex) const {
272  QPair<int, int> indices = binXYIndices(binIndex);
273  return binCount(indices.first, indices.second);
274  }
275 
276 
283  int xSize = 0;
284  int ySize = m_counts->size();
285 
286  // Assume square 2D structurs
287  if (ySize > 0)
288  xSize = (*m_counts)[0].size();
289 
290  return xSize * ySize;
291  }
292 
293 
300  QVector<double> xValues;
301 
302  int ySize = m_counts->size();
303  if (ySize) {
304  int xSize = (*m_counts)[0].size();
305  xValues.resize(xSize);
306 
307  for (int xIndex = 0; xIndex < xSize; xIndex++) {
308  double percentAcrossXRange = ((double)xIndex / (double)xSize);
309  xValues[xIndex] = m_xCubeMin +
310  percentAcrossXRange * (m_xCubeMax - m_xCubeMin);
311  }
312  }
313 
314  return xValues;
315  }
316 
317 
325  void ScatterPlotData::alarm(double x, double y) {
326  int binToAlarm = binIndex(x, y);
327  if (binToAlarm != -1)
328  (*m_alarmedBins)[binToAlarm] = true;
329  }
330 
331 
336  m_alarmedBins->clear();
337  }
338 
339 
346  QRectF ScatterPlotData::pixelHint(const QRectF &area) const {
347  QRectF hint;
348 
349  if (m_xDnToBinStretch->Pairs() > 1 && m_yDnToBinStretch->Pairs() > 1) {
350  hint = QRectF(
351  QPointF(m_xCubeMin, m_yCubeMin),
352  QSizeF(m_xDnToBinStretch->Input(1) - m_xDnToBinStretch->Input(0),
353  m_yDnToBinStretch->Input(1) - m_yDnToBinStretch->Input(1)));
354  }
355 
356  return hint;
357  }
358 
359 
368  ScatterPlotData tmp(other);
369 
370  swap(tmp);
371 
372  return *this;
373  }
374 
375 
383  int ScatterPlotData::binCount(int xIndex, int yIndex) const {
384  int count = 0;
385 
386  if (yIndex >= 0 && yIndex < m_counts->size()) {
387  if (xIndex >= 0 && xIndex < (*m_counts)[yIndex].size()) {
388  count = (*m_counts)[yIndex][xIndex];
389  }
390  }
391 
392  return count;
393  }
394 
395 
404  int ScatterPlotData::binIndex(int xIndex, int yIndex) const {
405  int xSize = 0;
406  int ySize = m_counts->size();
407 
408  // Assume square 2D structurs
409  if (ySize > 0)
410  xSize = (*m_counts)[0].size();
411 
412  int index = -1;
413  if ((xIndex >= 0 && xIndex < xSize) && (yIndex >= 0 && yIndex < ySize))
414  index = xSize * yIndex + xIndex;
415 
416  return index;
417  }
418 
419 
427  int ScatterPlotData::binIndex(double x, double y) const {
428  QPair<int, int> indices = binXYIndices(x, y);
429  return binIndex(indices.first, indices.second);
430  }
431 
432 
440  int xSize = 0;
441  int ySize = m_counts->size();
442 
443  // Assume square 2D structurs
444  if (ySize > 0)
445  xSize = (*m_counts)[0].size();
446 
447  int yIndex = (binIndex / xSize);
448  binIndex -= yIndex * xSize;
449 
450  int xIndex = binIndex;
451 
452  if (xIndex < 0 || yIndex < 0 || xIndex >= xSize || yIndex >= ySize) {
453  IString msg = "Bin at index [" + IString(binIndex) + "] not found. "
454  "There are [" + IString(numberOfBins()) + "] bins";
456  }
457 
458  return QPair<int, int>(xIndex, yIndex);
459  }
460 
461 
469  QPair<int, int> ScatterPlotData::binXYIndices(double x, double y) const {
470  QPair<int, int> indices(-1, -1);
471 
472  if (m_counts->size() && m_counts->at(0).size()) {
473  double xBinPosition = m_xDnToBinStretch->Map(x);
474  double yBinPosition = m_yDnToBinStretch->Map(y);
475 
476  if (!IsSpecial(xBinPosition) && !IsSpecial(yBinPosition)) {
477  int discreteXBin = qRound(xBinPosition);
478  int discreteYBin = qRound(yBinPosition);
479 
480  if (discreteXBin >= 0 && discreteXBin < m_counts->at(0).size() &&
481  discreteYBin >= 0 && discreteYBin < m_counts->size()) {
482  indices = QPair<int, int>(discreteXBin, discreteYBin);
483  }
484  }
485  }
486 
487  return indices;
488  }
489 }
490