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"
87 rubberBandTool()->setDrawActiveViewportOnly(
false);
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);
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;
268 supportsWavelength = supportsWavelength &&
269 pvl.
findObject(
"IsisCube").hasGroup(
"BandBin");
271 if (supportsWavelength) {
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()) {
369 stdErr1Data, stdErr2Data, wavelengthData;
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,
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);
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++) {
650 if (rubberBandTool()->currentMode() == RubberBandTool::PolygonMode) {
651 for (
unsigned int j = 0; j < x_contained.size(); j++) {
664 labels.push_back(band);
667 if (pvl.
findObject(
"IsisCube").hasGroup(
"BandBin")) {
671 if (wavelength.
size() > (band - 1)) {
672 labels.push_back(
toDouble(wavelength[band-1]));
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.
void SetBasePosition(const int start_sample, const int start_line, const int start_band)
This method is used to set the base position of the shape buffer.
double * DoubleBuffer() const
Returns the value of the shape buffer.
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.
virtual void add(CubePlotCurve *pc)
This method adds the curves to the plot.
static QString defaultWindowTitle()
This is the typical suffix for plot windows, it's here in case we want to update all plot windows to ...
void replot()
Reset the scale of the plot, replot it and emit plot changed.
PlotCurve::Units xAxisUnits() const
This is the data-type of the curves' x data in this plot window.
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
PvlKeyword & findKeyword(const QString &name)
Find a keyword with a specified name.
Contains multiple PvlContainers.
Container for cube-like labels.
A single keyword-value pair.
int size() const
Returns the number of values stored in this keyword.
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.
double Average() const
Computes and returns the average.
void AddData(const double *data, const unsigned int count)
Add an array of doubles to the accumulators and counters.
This is free and unencumbered software released into the public domain.
This is free and unencumbered software released into the public domain.
This is free and unencumbered software released into the public domain.
This is free and unencumbered software released into the public domain.
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.