1#include "SpectralPlotTool.h"
5#include "geos/geom/Polygon.h"
6#include "geos/geom/CoordinateSequence.h"
7#include "geos/geom/Point.h"
20#include "CubePlotCurve.h"
21#include "InterestOperator.h"
22#include "MdiCubeViewport.h"
23#include "SpectralPlotTool.h"
24#include "SpectralPlotWindow.h"
25#include "PolygonTools.h"
27#include "RubberBandComboBox.h"
28#include "RubberBandTool.h"
29#include "Statistics.h"
101 selectCurvesDialog->setWindowTitle(
"Select Curves to Plot");
103 QGridLayout *layout =
new QGridLayout;
105 QLabel *header =
new QLabel(
"Select which curves to plot when new data is "
107 layout->addWidget(header, 0, 0, 1, 2, Qt::AlignHCenter);
109 QList<QAction *> actions;
119 foreach (
QAction *action, actions) {
120 QLabel *label =
new QLabel(action->text());
121 layout->addWidget(label, row, 0, 1, 1);
123 QCheckBox *actionCheckbox =
new QCheckBox;
124 actionCheckbox->setChecked(action->isChecked());
125 connect(actionCheckbox, SIGNAL(stateChanged(
int)),
126 action, SLOT(toggle()));
127 layout->addWidget(actionCheckbox, row, 1, 1, 1, Qt::AlignRight);
132 QPushButton *okButton =
new QPushButton(
"Ok");
133 connect(okButton, SIGNAL(clicked()),
134 selectCurvesDialog, SLOT(close()));
135 layout->addWidget(okButton, row, 0, 1, 2);
137 selectCurvesDialog->setLayout(layout);
138 selectCurvesDialog->exec();
153 QString text =
"<b>Function:</b> Create a spectral plot using statistics across a spectrum "
170 wrapper->setContextMenuPolicy(Qt::ActionsContextMenu);
217 QPushButton *plotCurvesButton =
new QPushButton(
"Select Curves to Plot");
218 connect(plotCurvesButton, SIGNAL(clicked()),
221 QHBoxLayout *layout =
new QHBoxLayout(wrapper);
222 layout->setMargin(0);
225 layout->addWidget(plotCurvesButton);
226 layout->addWidget(abstractToolWidgets);
227 layout->addStretch(1);
228 wrapper->setLayout(layout);
261 bool supportsWavelength =
true;
264 int bandCount = cvp->cube()->bandCount();
267 Pvl &pvl = *cvp->cube()->label();
268 supportsWavelength = supportsWavelength &&
269 pvl.
findObject(
"IsisCube").hasGroup(
"BandBin");
271 if (supportsWavelength) {
272 PvlGroup &bandBin = pvl.findObject(
"IsisCube").findGroup(
"BandBin");
273 supportsWavelength = supportsWavelength &&
275 bandBin[
"Center"].size() == bandCount;
279 if (supportsWavelength) {
301 qobject_cast<QWidget *>(parent()));
335 if (rubberBandTool()->isValid()) {
339 QMessageBox::information(NULL,
"Error",
340 "The selected Area contains no valid pixels",
352 if (activeViewport && rubberBandTool()->isValid()) {
357 if (targetWindow->xAxisUnits() !=
365 QVector<double> labels;
368 QVector<QPointF> avgData, minData, maxData, std1Data, std2Data,
369 stdErr1Data, stdErr2Data, wavelengthData;
370 QVector<Statistics> plotStats;
374 for (
int index = 0; index < labels.size(); index++) {
376 !
IsSpecial(plotStats[index].Minimum()) &&
377 !
IsSpecial(plotStats[index].Maximum())) {
378 avgData.append(QPointF(labels[index], plotStats[index].
Average()));
379 minData.append(QPointF(labels[index], plotStats[index].Minimum()));
380 maxData.append(QPointF(labels[index], plotStats[index].Maximum()));
382 if (!
IsSpecial(plotStats[index].StandardDeviation())) {
383 std1Data.append(QPointF(labels[index],
385 plotStats[index].StandardDeviation()));
386 std2Data.append(QPointF(labels[index],
388 plotStats[index].StandardDeviation()));
390 double standardError = plotStats[index].StandardDeviation() /
391 sqrt(plotStats[index].ValidPixels());
393 stdErr1Data.append(QPointF(labels[index],
396 stdErr2Data.append(QPointF(labels[index],
403 if (labels.size() > 0) {
404 QList<QPoint> rubberBandPoints = rubberBandTool()->
vertices();
408 (*m_avgCurves)[viewport]->setData(
new QwtPointSeriesData(avgData));
409 (*m_avgCurves)[viewport]->setSource(viewport, rubberBandPoints);
413 (*m_minCurves)[viewport]->setData(
new QwtPointSeriesData(minData));
414 (*m_minCurves)[viewport]->setSource(viewport, rubberBandPoints);
418 (*m_maxCurves)[viewport]->setData(
new QwtPointSeriesData(maxData));
419 (*m_maxCurves)[viewport]->setSource(viewport, rubberBandPoints);
423 (*m_stdDev1Curves)[viewport]->setData(
424 new QwtPointSeriesData(std1Data));
425 (*m_stdDev1Curves)[viewport]->setSource(viewport,
430 (*m_stdDev2Curves)[viewport]->setData(
431 new QwtPointSeriesData(std2Data));
432 (*m_stdDev2Curves)[viewport]->setSource(viewport,
437 (*m_stdErr1Curves)[viewport]->setData(
438 new QwtPointSeriesData(stdErr1Data));
439 (*m_stdErr1Curves)[viewport]->setSource(viewport,
444 (*m_stdErr2Curves)[viewport]->setData(
445 new QwtPointSeriesData(stdErr2Data));
446 (*m_stdErr2Curves)[viewport]->setSource(viewport,
452 targetWindow->replot();
469 QPen avgPen(Qt::white);
471 avgPen.setStyle(Qt::SolidLine);
473 QPen minMaxPen(Qt::cyan);
475 minMaxPen.setWidth(1);
476 minMaxPen.setStyle(Qt::SolidLine);
478 QPen stdDevPen(Qt::red);
479 stdDevPen.setWidth(1);
481 stdDevPen.setStyle(Qt::SolidLine);
483 QPen stdErrPen(Qt::green);
484 stdErrPen.setWidth(1);
486 stdErrPen.setStyle(Qt::SolidLine);
491 (*
m_avgCurves)[viewport]->xUnits() != targetUnits)) {
495 targetWindow->add(plotCurve);
500 (*
m_minCurves)[viewport]->xUnits() != targetUnits)) {
504 targetWindow->add(plotCurve);
509 (*
m_maxCurves)[viewport]->xUnits() != targetUnits)) {
513 targetWindow->add(plotCurve);
522 targetWindow->add(plotCurve);
531 targetWindow->add(plotCurve);
540 targetWindow->add(plotCurve);
549 targetWindow->add(plotCurve);
567 QVector<Statistics> &data,
569 QList<QPoint> vertices = rubberBandTool()->
vertices();
571 if (vertices.size() < 1)
return;
573 double ss, sl, es, el, x, y;
574 std::vector <int> x_contained, y_contained;
577 viewport->
viewportToCube(vertices[0].x(), vertices[0].y(), ss, sl);
578 viewport->
viewportToCube(vertices[2].x(), vertices[2].y(), es, el);
588 int samps = ( std::abs(es - ss) + 1) ;
593 if (rubberBandTool()->currentMode() == RubberBandTool::PolygonMode) {
595 geos::geom::CoordinateSequence pts;
596 for (
int i = 0; i < vertices.size(); i++) {
599 pts.add(geos::geom::Coordinate(x, y));
604 pts.add(geos::geom::Coordinate(x, y));
606 geos::geom::Polygon *poly = globalFactory->createPolygon(
607 globalFactory->createLinearRing(pts)).release();
609 const geos::geom::Envelope *envelope = poly->getEnvelopeInternal();
612 for (
int y = (
int)round(envelope->getMinY());
613 y <= (int)round(envelope->getMaxY()); y++) {
614 for (
int x = (
int)round(envelope->getMinX());
615 x <= (int)round(envelope->getMaxX()); x++) {
617 geos::geom::Coordinate c(x, y);
618 geos::geom::Point *p = globalFactory->createPoint(c).release();
620 bool contains = p->within(poly);
624 x_contained.push_back(x);
625 y_contained.push_back(y);
636 for (
int band = 1; band <= cube->
bandCount(); band++) {
640 if (rubberBandTool()->currentMode() == RubberBandTool::RectangleMode) {
641 for (
int line = (
int)std::min(sl, el); line <= (int)std::max(sl, el); line++) {
643 brick->SetBasePosition(std::min(ss, es), line, band);
645 stats.AddData(brick->DoubleBuffer(), samps);
650 if (rubberBandTool()->currentMode() == RubberBandTool::PolygonMode) {
651 for (
unsigned int j = 0; j < x_contained.size(); j++) {
653 brick->SetBasePosition(x_contained[j], y_contained[j], band);
655 stats.AddData(*brick->DoubleBuffer());
664 labels.push_back(band);
667 if (pvl.findObject(
"IsisCube").hasGroup(
"BandBin")) {
668 PvlGroup &bandBin = pvl.findObject(
"IsisCube").findGroup(
"BandBin");
669 if (bandBin.hasKeyword(
"Center")) {
670 PvlKeyword &wavelength = bandBin.findKeyword(
"Center");
671 if (wavelength.size() > (band - 1)) {
672 labels.push_back(
toDouble(wavelength[band-1]));
678 if (stats.Average() ==
Null) {
679 data.push_back(stats);
682 data.push_back(stats);
Functor for reduce using average functionality.
Buffer for containing a three dimensional section of an image.
IO Handler for Isis Cubes.
void read(Blob &blob, const std::vector< PvlKeyword > keywords=std::vector< PvlKeyword >()) const
This method will read data from the specified Blob object.
virtual int bandCount() const
Returns the number of virtual bands for the cube.
Pvl * label() const
Returns a pointer to the IsisLabel object associated with the cube.
This is a plot curve with information relating it to a particular cube or region of a cube.
void viewportToCube(int x, int y, double &sample, double &line) const
Turns a viewport into a cube.
Cube display widget for certain Isis MDI applications.
Units
These are all the possible units for the x or y data in a plot curve.
@ Band
The data is a band number.
@ CubeDN
The data is a Cube DN value.
@ Wavelength
The data is a wavelength.
static QString defaultWindowTitle()
This is the typical suffix for plot windows, it's here in case we want to update all plot windows to ...
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
Contains multiple PvlContainers.
Container for cube-like labels.
A single keyword-value pair.
PvlObjectIterator findObject(const QString &name, PvlObjectIterator beg, PvlObjectIterator end)
Find the index of object with a specified name, between two indexes.
Combo box for choosing a rubber band type.
This class is used to accumulate statistics on double arrays.
This is free and unencumbered software released into the public domain.
This is free and unencumbered software released into the public domain.
int toInt(const QString &string)
Global function to convert from a string to an integer.
const double Null
Value for an Isis Null pixel.
bool IsSpecial(const double d)
Returns if the input pixel is special.
double toDouble(const QString &string)
Global function to convert from a string to a double.