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.