|
Isis 3.0 Object Programmers' Reference |
Home |
00001 #include "IsisDebug.h" 00002 #include "ScatterPlotData.h" 00003 00004 #include <algorithm> 00005 00006 #include <qwt_double_range.h> 00007 00008 #include <QtCore> 00009 00010 #include "Brick.h" 00011 #include "SpecialPixel.h" 00012 00013 namespace Isis { 00028 ScatterPlotData::ScatterPlotData( 00029 Cube *xCube, int xCubeBand, int xBinCount, 00030 Cube *yCube, int yCubeBand, int yBinCount, 00031 QwtInterval sampleRange, QwtInterval lineRange) : QwtRasterData(), 00032 m_xDnToBinStretch(new Stretch), m_yDnToBinStretch(new Stretch), 00033 m_counts( 00034 new QVector< QVector<int> >(yBinCount, QVector<int>(xBinCount))), 00035 m_alarmedBins(new QMap<int, bool>) { 00036 int startLine = qRound(lineRange.minValue()); 00037 int endLine = qRound(lineRange.maxValue()); 00038 ASSERT(xCube->lineCount() == yCube->lineCount()); 00039 00040 Histogram *xCubeHist = new Histogram(*xCube, xCubeBand, NULL, 00041 sampleRange.minValue(), lineRange.minValue(), 00042 sampleRange.maxValue(), lineRange.maxValue(), 00043 xBinCount, true); 00044 m_xCubeMin = xCubeHist->Minimum(); 00045 m_xCubeMax = xCubeHist->Maximum(); 00046 00047 00048 Histogram *yCubeHist = new Histogram(*yCube, yCubeBand, NULL, 00049 sampleRange.minValue(), lineRange.minValue(), 00050 sampleRange.maxValue(), lineRange.maxValue(), 00051 yBinCount, true); 00052 m_yCubeMin = yCubeHist->Minimum(); 00053 m_yCubeMax = yCubeHist->Maximum(); 00054 00055 00056 m_xDnToBinStretch->AddPair(m_xCubeMin, 0); 00057 m_xDnToBinStretch->AddPair(m_xCubeMax, xBinCount - 1); 00058 00059 m_yDnToBinStretch->AddPair(m_yCubeMin, 0); 00060 m_yDnToBinStretch->AddPair(m_yCubeMax, yBinCount - 1); 00061 00062 m_maxCount = 0; 00063 00064 Brick brick1((int)(sampleRange.maxValue() - sampleRange.minValue() + 1), 00065 1, 1, xCube->pixelType()); 00066 Brick brick2((int)(sampleRange.maxValue() - sampleRange.minValue() + 1), 00067 1, 1, yCube->pixelType()); 00068 ASSERT(xCube->sampleCount() == yCube->sampleCount()); 00069 ASSERT(brick1.size() == brick2.size()); 00070 00071 for (int line = startLine; line <= endLine; line++) { 00072 brick1.SetBasePosition(qRound(sampleRange.minValue()), line, xCubeBand); 00073 xCube->read(brick1); 00074 00075 brick2.SetBasePosition(qRound(sampleRange.minValue()), line, yCubeBand); 00076 yCube->read(brick2); 00077 00078 for (int i = 0; i < brick1.size(); i++) { 00079 double xDn = brick1[i]; 00080 double yDn = brick2[i]; 00081 00082 if (!IsSpecial(xDn) && !IsSpecial(yDn)) { 00083 double x = m_xDnToBinStretch->Map(xDn); 00084 double y = m_yDnToBinStretch->Map(yDn); 00085 00086 if (!IsSpecial(x) && !IsSpecial(y)) { 00087 int roundedX = qRound(x); 00088 int roundedY = qRound(y); 00089 00090 if (roundedX >= 0 && roundedX < xBinCount && 00091 roundedY >= 0 && roundedY < yBinCount) { 00092 int value = (*m_counts)[roundedY][roundedX] + 1; 00093 (*m_counts)[roundedY][roundedX] = value; 00094 00095 m_maxCount = qMax(m_maxCount, value); 00096 } 00097 } 00098 } 00099 } 00100 } 00101 00102 setInterval(Qt::XAxis, QwtInterval(m_xCubeMin, m_xCubeMax)); 00103 setInterval(Qt::YAxis, QwtInterval(m_yCubeMin, m_yCubeMax)); 00104 setInterval(Qt::ZAxis, QwtInterval(0, m_maxCount)); 00105 } 00106 00107 00114 ScatterPlotData::ScatterPlotData(const ScatterPlotData &other) { 00115 m_xDnToBinStretch.reset(new Stretch(*other.m_xDnToBinStretch)); 00116 m_yDnToBinStretch.reset(new Stretch(*other.m_yDnToBinStretch)); 00117 m_counts.reset(new QVector< QVector<int> >(*other.m_counts)); 00118 m_alarmedBins.reset(new QMap< int, bool>(*other.m_alarmedBins)); 00119 m_maxCount = other.m_maxCount; 00120 m_xCubeMin = other.m_xCubeMin; 00121 m_xCubeMax = other.m_xCubeMax; 00122 m_yCubeMin = other.m_yCubeMin; 00123 m_yCubeMax = other.m_yCubeMax; 00124 } 00125 00126 00131 ScatterPlotData::~ScatterPlotData() { 00132 } 00133 00134 00140 QwtRasterData *ScatterPlotData::copy() const { 00141 return new ScatterPlotData(*this); 00142 } 00143 00144 00154 double ScatterPlotData::value(double x, double y) const { 00155 double value = 0; 00156 00157 QPair<int, int> indices = binXYIndices(x, y); 00158 int index = binIndex(indices.first, indices.second); 00159 00160 if (index != -1 && (*m_alarmedBins)[index]) 00161 value = m_maxCount; 00162 else 00163 value = binCount(indices.first, indices.second); 00164 00165 return value; 00166 } 00167 00168 00174 double ScatterPlotData::xCubeMin() const { 00175 return m_xCubeMin; 00176 } 00177 00178 00184 double ScatterPlotData::xCubeMax() const { 00185 return m_xCubeMax; 00186 } 00187 00188 00194 double ScatterPlotData::yCubeMin() const { 00195 return m_yCubeMin; 00196 } 00197 00198 00204 double ScatterPlotData::yCubeMax() const { 00205 return m_yCubeMax; 00206 } 00207 00208 00214 void ScatterPlotData::swap(ScatterPlotData &other) { 00215 m_xDnToBinStretch.swap(other.m_xDnToBinStretch); 00216 m_yDnToBinStretch.swap(other.m_yDnToBinStretch); 00217 m_counts.swap(other.m_counts); 00218 m_alarmedBins.swap(other.m_alarmedBins); 00219 std::swap(m_maxCount, other.m_maxCount); 00220 std::swap(m_xCubeMin, other.m_xCubeMin); 00221 std::swap(m_xCubeMax, other.m_xCubeMax); 00222 std::swap(m_yCubeMin, other.m_yCubeMin); 00223 std::swap(m_yCubeMax, other.m_yCubeMax); 00224 } 00225 00226 00234 QPair<double, double> ScatterPlotData::binXY(int index) const { 00235 QPair<int, int> indices = binXYIndices(index); 00236 int xIndex = indices.first; 00237 int yIndex = indices.second; 00238 00239 if (xIndex != -1 && yIndex != -1) { 00240 int xSize = 0; 00241 int ySize = m_counts->size(); 00242 00243 // Assume square 2D structurs 00244 if (ySize > 0) 00245 xSize = (*m_counts)[0].size(); 00246 00247 double percentAcrossXRange = ((double)xIndex / (double)xSize); 00248 double xDnValue = m_xCubeMin + 00249 percentAcrossXRange * (m_xCubeMax - m_xCubeMin); 00250 00251 double percentAcrossYRange = ((double)yIndex / (double)ySize); 00252 double yDnValue = m_yCubeMin + 00253 percentAcrossYRange * (m_yCubeMax - m_yCubeMin); 00254 00255 return QPair<double, double>(xDnValue, yDnValue); 00256 } 00257 00258 00259 IString msg = "Bin at index [" + IString(index) + "] not found. " 00260 "There are [" + IString(numberOfBins()) + "] bins"; 00261 throw IException(IException::Programmer, msg, _FILEINFO_); 00262 } 00263 00264 00271 int ScatterPlotData::binCount(int binIndex) const { 00272 QPair<int, int> indices = binXYIndices(binIndex); 00273 return binCount(indices.first, indices.second); 00274 } 00275 00276 00282 int ScatterPlotData::numberOfBins() const { 00283 int xSize = 0; 00284 int ySize = m_counts->size(); 00285 00286 // Assume square 2D structurs 00287 if (ySize > 0) 00288 xSize = (*m_counts)[0].size(); 00289 00290 return xSize * ySize; 00291 } 00292 00293 00299 QVector<double> ScatterPlotData::discreteXValues() const { 00300 QVector<double> xValues; 00301 00302 int ySize = m_counts->size(); 00303 if (ySize) { 00304 int xSize = (*m_counts)[0].size(); 00305 xValues.resize(xSize); 00306 00307 for (int xIndex = 0; xIndex < xSize; xIndex++) { 00308 double percentAcrossXRange = ((double)xIndex / (double)xSize); 00309 xValues[xIndex] = m_xCubeMin + 00310 percentAcrossXRange * (m_xCubeMax - m_xCubeMin); 00311 } 00312 } 00313 00314 return xValues; 00315 } 00316 00317 00325 void ScatterPlotData::alarm(double x, double y) { 00326 int binToAlarm = binIndex(x, y); 00327 if (binToAlarm != -1) 00328 (*m_alarmedBins)[binToAlarm] = true; 00329 } 00330 00331 00335 void ScatterPlotData::clearAlarms() { 00336 m_alarmedBins->clear(); 00337 } 00338 00339 00346 QRectF ScatterPlotData::pixelHint(const QRectF &area) const { 00347 QRectF hint; 00348 00349 if (m_xDnToBinStretch->Pairs() > 1 && m_yDnToBinStretch->Pairs() > 1) { 00350 hint = QRectF( 00351 QPointF(m_xCubeMin, m_yCubeMin), 00352 QSizeF(m_xDnToBinStretch->Input(1) - m_xDnToBinStretch->Input(0), 00353 m_yDnToBinStretch->Input(1) - m_yDnToBinStretch->Input(1))); 00354 } 00355 00356 return hint; 00357 } 00358 00359 00367 ScatterPlotData &ScatterPlotData::operator=(const ScatterPlotData &other) { 00368 ScatterPlotData tmp(other); 00369 00370 swap(tmp); 00371 00372 return *this; 00373 } 00374 00375 00383 int ScatterPlotData::binCount(int xIndex, int yIndex) const { 00384 int count = 0; 00385 00386 if (yIndex >= 0 && yIndex < m_counts->size()) { 00387 if (xIndex >= 0 && xIndex < (*m_counts)[yIndex].size()) { 00388 count = (*m_counts)[yIndex][xIndex]; 00389 } 00390 } 00391 00392 return count; 00393 } 00394 00395 00404 int ScatterPlotData::binIndex(int xIndex, int yIndex) const { 00405 int xSize = 0; 00406 int ySize = m_counts->size(); 00407 00408 // Assume square 2D structurs 00409 if (ySize > 0) 00410 xSize = (*m_counts)[0].size(); 00411 00412 int index = -1; 00413 if ((xIndex >= 0 && xIndex < xSize) && (yIndex >= 0 && yIndex < ySize)) 00414 index = xSize * yIndex + xIndex; 00415 00416 return index; 00417 } 00418 00419 00427 int ScatterPlotData::binIndex(double x, double y) const { 00428 QPair<int, int> indices = binXYIndices(x, y); 00429 return binIndex(indices.first, indices.second); 00430 } 00431 00432 00439 QPair<int, int> ScatterPlotData::binXYIndices(int binIndex) const { 00440 int xSize = 0; 00441 int ySize = m_counts->size(); 00442 00443 // Assume square 2D structurs 00444 if (ySize > 0) 00445 xSize = (*m_counts)[0].size(); 00446 00447 int yIndex = (binIndex / xSize); 00448 binIndex -= yIndex * xSize; 00449 00450 int xIndex = binIndex; 00451 00452 if (xIndex < 0 || yIndex < 0 || xIndex >= xSize || yIndex >= ySize) { 00453 IString msg = "Bin at index [" + IString(binIndex) + "] not found. " 00454 "There are [" + IString(numberOfBins()) + "] bins"; 00455 throw IException(IException::Programmer, msg, _FILEINFO_); 00456 } 00457 00458 return QPair<int, int>(xIndex, yIndex); 00459 } 00460 00461 00469 QPair<int, int> ScatterPlotData::binXYIndices(double x, double y) const { 00470 QPair<int, int> indices(-1, -1); 00471 00472 if (m_counts->size() && m_counts->at(0).size()) { 00473 double xBinPosition = m_xDnToBinStretch->Map(x); 00474 double yBinPosition = m_yDnToBinStretch->Map(y); 00475 00476 if (!IsSpecial(xBinPosition) && !IsSpecial(yBinPosition)) { 00477 int discreteXBin = qRound(xBinPosition); 00478 int discreteYBin = qRound(yBinPosition); 00479 00480 if (discreteXBin >= 0 && discreteXBin < m_counts->at(0).size() && 00481 discreteYBin >= 0 && discreteYBin < m_counts->size()) { 00482 indices = QPair<int, int>(discreteXBin, discreteYBin); 00483 } 00484 } 00485 } 00486 00487 return indices; 00488 } 00489 } 00490