3 #include "SpectralPlotTool.h" 7 #include "geos/geom/Polygon.h" 8 #include "geos/geom/CoordinateArraySequence.h" 9 #include "geos/geom/Point.h" 13 #include <QHBoxLayout> 14 #include <QGridLayout> 17 #include <QMessageBox> 18 #include <QPushButton> 25 #include "SpectralPlotTool.h" 29 #include "RubberBandComboBox.h" 30 #include "RubberBandTool.h" 104 selectCurvesDialog->setWindowTitle(
"Select Curves to Plot");
106 QGridLayout *layout =
new QGridLayout;
108 QLabel *header =
new QLabel(
"Select which curves to plot when new data is " 110 layout->addWidget(header, 0, 0, 1, 2, Qt::AlignHCenter);
122 foreach (
QAction *action, actions) {
123 QLabel *label =
new QLabel(action->text());
124 layout->addWidget(label, row, 0, 1, 1);
126 QCheckBox *actionCheckbox =
new QCheckBox;
127 actionCheckbox->setChecked(action->isChecked());
128 connect(actionCheckbox, SIGNAL(stateChanged(
int)),
129 action, SLOT(toggle()));
130 layout->addWidget(actionCheckbox, row, 1, 1, 1, Qt::AlignRight);
135 QPushButton *okButton =
new QPushButton(
"Ok");
136 connect(okButton, SIGNAL(clicked()),
137 selectCurvesDialog, SLOT(close()));
138 layout->addWidget(okButton, row, 0, 1, 2);
140 selectCurvesDialog->setLayout(layout);
141 selectCurvesDialog->exec();
156 QString text =
"<b>Function:</b> Create a spectral plot using statistics across a spectrum " 173 wrapper->setContextMenuPolicy(Qt::ActionsContextMenu);
220 QPushButton *plotCurvesButton =
new QPushButton(
"Select Curves to Plot");
221 connect(plotCurvesButton, SIGNAL(clicked()),
224 QHBoxLayout *layout =
new QHBoxLayout(wrapper);
225 layout->setMargin(0);
228 layout->addWidget(plotCurvesButton);
229 layout->addWidget(abstractToolWidgets);
230 layout->addStretch(1);
231 wrapper->setLayout(layout);
264 bool supportsWavelength =
true;
271 supportsWavelength = supportsWavelength &&
272 pvl.
findObject(
"IsisCube").hasGroup(
"BandBin");
274 if (supportsWavelength) {
276 supportsWavelength = supportsWavelength &&
278 bandBin[
"Center"].size() == bandCount;
282 if (supportsWavelength) {
304 qobject_cast<
QWidget *>(parent()));
338 if (rubberBandTool()->isValid()) {
342 QMessageBox::information(NULL,
"Error",
343 "The selected Area contains no valid pixels",
355 if (activeViewport && rubberBandTool()->isValid()) {
372 stdErr1Data, stdErr2Data, wavelengthData;
377 for (
int index = 0; index < labels.size(); index++) {
379 !
IsSpecial(plotStats[index].Minimum()) &&
380 !
IsSpecial(plotStats[index].Maximum())) {
381 avgData.append(QPointF(labels[index], plotStats[index].
Average()));
382 minData.append(QPointF(labels[index], plotStats[index].Minimum()));
383 maxData.append(QPointF(labels[index], plotStats[index].Maximum()));
385 if (!
IsSpecial(plotStats[index].StandardDeviation())) {
386 std1Data.append(QPointF(labels[index],
388 plotStats[index].StandardDeviation()));
389 std2Data.append(QPointF(labels[index],
391 plotStats[index].StandardDeviation()));
393 double standardError = plotStats[index].StandardDeviation() /
394 sqrt(plotStats[index].ValidPixels());
396 stdErr1Data.append(QPointF(labels[index],
399 stdErr2Data.append(QPointF(labels[index],
406 if (labels.size() > 0) {
411 (*m_avgCurves)[viewport]->setData(
new QwtPointSeriesData(avgData));
412 (*m_avgCurves)[viewport]->setSource(viewport, rubberBandPoints);
416 (*m_minCurves)[viewport]->setData(
new QwtPointSeriesData(minData));
417 (*m_minCurves)[viewport]->setSource(viewport, rubberBandPoints);
421 (*m_maxCurves)[viewport]->setData(
new QwtPointSeriesData(maxData));
422 (*m_maxCurves)[viewport]->setSource(viewport, rubberBandPoints);
426 (*m_stdDev1Curves)[viewport]->setData(
427 new QwtPointSeriesData(std1Data));
428 (*m_stdDev1Curves)[viewport]->setSource(viewport,
433 (*m_stdDev2Curves)[viewport]->setData(
434 new QwtPointSeriesData(std2Data));
435 (*m_stdDev2Curves)[viewport]->setSource(viewport,
440 (*m_stdErr1Curves)[viewport]->setData(
441 new QwtPointSeriesData(stdErr1Data));
442 (*m_stdErr1Curves)[viewport]->setSource(viewport,
447 (*m_stdErr2Curves)[viewport]->setData(
448 new QwtPointSeriesData(stdErr2Data));
449 (*m_stdErr2Curves)[viewport]->setSource(viewport,
472 QPen avgPen(Qt::white);
474 avgPen.setStyle(Qt::SolidLine);
476 QPen minMaxPen(Qt::cyan);
478 minMaxPen.setWidth(1);
479 minMaxPen.setStyle(Qt::SolidLine);
481 QPen stdDevPen(Qt::red);
482 stdDevPen.setWidth(1);
484 stdDevPen.setStyle(Qt::SolidLine);
486 QPen stdErrPen(Qt::green);
487 stdErrPen.setWidth(1);
489 stdErrPen.setStyle(Qt::SolidLine);
493 (!(*m_avgCurves)[viewport] ||
494 (*m_avgCurves)[viewport]->xUnits() != targetUnits)) {
498 targetWindow->
add(plotCurve);
502 (!(*m_minCurves)[viewport] ||
503 (*m_minCurves)[viewport]->xUnits() != targetUnits)) {
507 targetWindow->
add(plotCurve);
511 (!(*m_maxCurves)[viewport] ||
512 (*m_maxCurves)[viewport]->xUnits() != targetUnits)) {
516 targetWindow->
add(plotCurve);
520 (!(*m_stdDev1Curves)[viewport] ||
521 (*m_stdDev1Curves)[viewport]->xUnits() != targetUnits)) {
525 targetWindow->
add(plotCurve);
529 (!(*m_stdDev2Curves)[viewport] ||
530 (*m_stdDev2Curves)[viewport]->xUnits() != targetUnits)) {
534 targetWindow->
add(plotCurve);
538 (!(*m_stdErr1Curves)[viewport] ||
539 (*m_stdErr1Curves)[viewport]->xUnits() != targetUnits)) {
543 targetWindow->
add(plotCurve);
547 (!(*m_stdErr2Curves)[viewport] ||
548 (*m_stdErr2Curves)[viewport]->xUnits() != targetUnits)) {
552 targetWindow->
add(plotCurve);
574 if (vertices.size() < 1)
return;
576 double ss, sl, es, el, x, y;
577 std::vector <int> x_contained, y_contained;
580 viewport->
viewportToCube(vertices[0].x(), vertices[0].y(), ss, sl);
581 viewport->
viewportToCube(vertices[2].x(), vertices[2].y(), es, el);
591 int samps = ( std::abs(es - ss) + 1) ;
596 if (rubberBandTool()->currentMode() == RubberBandTool::PolygonMode) {
598 geos::geom::CoordinateSequence *pts =
new geos::geom::CoordinateArraySequence();
599 for (
int i = 0; i < vertices.size(); i++) {
602 pts->add(geos::geom::Coordinate(x, y));
607 pts->add(geos::geom::Coordinate(x, y));
609 geos::geom::Polygon *poly = globalFactory.createPolygon(
610 globalFactory.createLinearRing(pts), NULL);
612 const geos::geom::Envelope *envelope = poly->getEnvelopeInternal();
615 for (
int y = (
int)round(envelope->getMinY());
616 y <= (int)round(envelope->getMaxY()); y++) {
617 for (
int x = (
int)round(envelope->getMinX());
618 x <= (int)round(envelope->getMaxX()); x++) {
620 geos::geom::Coordinate c(x, y);
621 geos::geom::Point *p = globalFactory.createPoint(c);
623 bool contains = p->within(poly);
627 x_contained.push_back(x);
628 y_contained.push_back(y);
639 for (
int band = 1; band <= cube->
bandCount(); band++) {
643 if (rubberBandTool()->currentMode() == RubberBandTool::RectangleMode) {
644 for (
int line = (
int)std::min(sl, el); line <= (int)std::max(sl, el); line++) {
653 if (rubberBandTool()->currentMode() == RubberBandTool::PolygonMode) {
654 for (
unsigned int j = 0; j < x_contained.size(); j++) {
667 labels.push_back(band);
670 if (pvl.
findObject(
"IsisCube").hasGroup(
"BandBin")) {
674 if (wavelength.
size() > (band - 1)) {
675 labels.push_back(
toDouble(wavelength[band-1]));
682 data.push_back(stats);
685 data.push_back(stats);
Cube display widget for certain Isis MDI applications.
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
double * DoubleBuffer() const
Returns the value of the shape buffer.
const double Null
Value for an Isis Null pixel.
The data is a Cube DN value.
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.
Buffer for containing a three dimensional section of an image.
int toInt(const QString &string)
Global function to convert from a string to an integer.
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.
The data is a wavelength.
double toDouble(const QString &string)
Global function to convert from a string to a double.
This class is used to accumulate statistics on double arrays.
int size() const
Returns the number of values stored in this keyword.
Contains multiple PvlContainers.
This is a plot curve with information relating it to a particular cube or region of a cube...
A single keyword-value pair.
PlotCurve::Units xAxisUnits() const
This is the data-type of the curves' x data in this plot window.
void read(Blob &blob) const
This method will read data from the specified Blob object.
bool IsSpecial(const double d)
Returns if the input pixel is special.
Container for cube-like labels.
PvlKeyword & findKeyword(const QString &name)
Find a keyword with a specified name.
Pvl * label() const
Returns a pointer to the IsisLabel object associated with the cube.
static QString defaultWindowTitle()
This is the typical suffix for plot windows, it's here in case we want to update all plot windows to ...
Namespace for ISIS/Bullet specific routines.
virtual int bandCount() const
Returns the number of virtual bands for the cube.
void replot()
Reset the scale of the plot, replot it and emit plot changed.
The data is a band number.
void AddData(const double *data, const unsigned int count)
Add an array of doubles to the accumulators and counters.
virtual void add(CubePlotCurve *pc)
This method adds the curves to the plot.
void viewportToCube(int x, int y, double &sample, double &line) const
Turns a viewport into a cube.
double Average() const
Computes and returns the average.
Units
These are all the possible units for the x or y data in a plot curve.
Functor for reduce using average functionality.
IO Handler for Isis Cubes.