Example #1
0
QWidget* ResultsExporter::getExportOptionsWidget(const PlugInArgList *pInArgList)
{
    const DataDescriptor* pDescriptor = NULL;
    if (pInArgList != NULL)
    {
        RasterElement* pElement = pInArgList->getPlugInArgValue<RasterElement>(Exporter::ExportItemArg());
        if (pElement != NULL)
        {
            pDescriptor = pElement->getDataDescriptor();
        }
    }
    if (mpOptionsWidget == NULL)
    {
        Service<DesktopServices> pDesktop;
        VERIFY(pDesktop.get() != NULL);

        mpOptionsWidget = new ResultsOptionsWidget(pDesktop->getMainWidget());
    }

    if (mpOptionsWidget != NULL)
    {
        const string& name = pDescriptor->getName();
        const string& type = pDescriptor->getType();
        DataElement* pParent = pDescriptor->getParent();

        RasterElement* pResults = dynamic_cast<RasterElement*>(mpModel->getElement(name, type, pParent));
        if (pResults != NULL)
        {
            PassArea passArea = MIDDLE;
            double dFirstThreshold = 0.0;
            double dSecondThreshold = 0.0;

            SpatialDataWindow* pWindow = dynamic_cast<SpatialDataWindow*>(mpDesktop->getCurrentWorkspaceWindow());
            if (pWindow != NULL)
            {
                SpatialDataView* pView = pWindow->getSpatialDataView();
                if (pView != NULL)
                {
                    LayerList* pLayerList = pView->getLayerList();
                    if (pLayerList != NULL)
                    {
                        ThresholdLayer* pThresholdLayer =
                            static_cast<ThresholdLayer*>(pLayerList->getLayer(THRESHOLD, pResults));
                        if (pThresholdLayer != NULL)
                        {
                            passArea = pThresholdLayer->getPassArea();
                            dFirstThreshold = pThresholdLayer->getFirstThreshold();
                            dSecondThreshold = pThresholdLayer->getSecondThreshold();
                        }
                        else
                        {
                            Statistics* pStatistics = pResults->getStatistics();
                            if (pStatistics != NULL)
                            {
                                dFirstThreshold = pStatistics->getMin();
                                dSecondThreshold = pStatistics->getMax();
                            }
                        }
                    }

                    LatLonLayer* pLatLonLayer = static_cast<LatLonLayer*>(pView->getTopMostLayer(LAT_LONG));
                    if (pLatLonLayer != NULL)
                    {
                        GeocoordType geocoordType = pLatLonLayer->getGeocoordType();
                        mpOptionsWidget->setGeocoordType(geocoordType);
                    }
                }
            }

            mpOptionsWidget->setPassArea(passArea);
            mpOptionsWidget->setFirstThreshold(dFirstThreshold);
            mpOptionsWidget->setSecondThreshold(dSecondThreshold);
        }
    }

    return mpOptionsWidget;
}
Example #2
0
   DataElement* createRasterElement(const char* pName, RasterElementArgs args)
   {
      if (pName == NULL || args.location > 2)
      {
         setLastError(SIMPLE_BAD_PARAMS);
         return NULL;
      }

      // Check for an existing element with the name
      if (getDataElement(pName, TypeConverter::toString<RasterElement>(), 0) != NULL)
      {
         setLastError(SIMPLE_EXISTS);
         return NULL;
      }

      RasterElement* pElement = RasterUtilities::createRasterElement(std::string(pName), args.numRows,
         args.numColumns, args.numBands, static_cast<EncodingTypeEnum>(args.encodingType),
         static_cast<InterleaveFormatTypeEnum>(args.interleaveFormat), args.location != 2, args.pParent);
      if (pElement == NULL)
      {
         switch (args.location)
         {
         case 0:
            pElement = RasterUtilities::createRasterElement(std::string(pName), args.numRows,
               args.numColumns, args.numBands, static_cast<EncodingTypeEnum>(args.encodingType),
               static_cast<InterleaveFormatTypeEnum>(args.interleaveFormat), false, args.pParent);
            if (pElement == NULL)
            {
               setLastError(SIMPLE_OTHER_FAILURE);
               return NULL;
            }
            break;
         case 1:
            setLastError(SIMPLE_NO_MEM);
            return NULL;
         case 2:
            setLastError(SIMPLE_OTHER_FAILURE);
            return NULL;
         default:
            setLastError(SIMPLE_BAD_PARAMS);
            return NULL;
         }
      }
      if (args.pBadValues != NULL && args.numBadValues > 0)
      {
         RasterDataDescriptor* pDesc = static_cast<RasterDataDescriptor*>(pElement->getDataDescriptor());
         if (pDesc != NULL)
         {
            std::vector<int> badValues;
            badValues.reserve(args.numBadValues);
            for (uint32_t idx = 0; idx < args.numBadValues; ++idx)
            {
               badValues.push_back(args.pBadValues[idx]);
            }
            pDesc->setBadValues(badValues);

            // set on the statistics objects
            const std::vector<DimensionDescriptor>& allBands = pDesc->getBands();
            for (std::vector<DimensionDescriptor>::const_iterator band = allBands.begin();
                 band != allBands.end(); ++band)
            {
               if (band->isValid())
               {
                  Statistics* pStats = pElement->getStatistics(*band);
                  if (pStats != NULL)
                  {
                     pStats->setBadValues(badValues);
                  }
               }
            }
            pElement->updateData();
         }
      }

      setLastError(SIMPLE_NO_ERROR);
      return pElement;
   }
Example #3
0
bool RasterTimingTest::execute(PlugInArgList* pInArgList, PlugInArgList* pOutArgList)
{
   if (isBatch())
   {
      VERIFY(pOutArgList != NULL);
   }
   Service<DesktopServices> pDesktop;
   SpatialDataView* pView = dynamic_cast<SpatialDataView*>(pDesktop->getCurrentWorkspaceWindowView());
   if (pView)
   {
      UndoLock lock(pView);

      RasterElement* pElement = pView->getLayerList()->getPrimaryRasterElement();
      RasterDataDescriptor* pDesc = dynamic_cast<RasterDataDescriptor*>(pElement->getDataDescriptor());
      int bands = pDesc->getBandCount();
      int frameNumber = 0;
      RasterLayer* pLayer = NULL;
      vector<Layer*> layers;
      pView->getLayerList()->getLayers(RASTER, layers);
      for (vector<Layer*>::iterator iter = layers.begin(); iter != layers.end(); ++iter)
      {
         RasterLayer* pRasterLayer = static_cast<RasterLayer*>(*iter);
         if (pRasterLayer != NULL)
         {
            RasterElement* pCurrentRasterElement = dynamic_cast<RasterElement*>(pRasterLayer->getDataElement());
            if (pCurrentRasterElement == pElement)
            {
               pLayer = pRasterLayer;
               break;
            }
         }
      }
      for (int i = 0; i < bands; ++i)
      {
         pElement->getStatistics(pDesc->getActiveBand(i))->getMin();
      }
      // set grayscale display mode
      DisplayMode initialDisplayMode = pLayer->getDisplayMode();
      pLayer->setDisplayMode(GRAYSCALE_MODE);
      const int frameiterations = 10000;
      clock_t startTime = clock();
      QWidget* pWidget = pView->getWidget();
      int i = 0;
      for (i = 0; i < frameiterations; ++i, ++frameNumber)
      {
         if (frameNumber >= bands)
         {
            frameNumber = 0;
         }

         pLayer->setDisplayedBand(GRAY, pDesc->getActiveBand(frameNumber));
         if (pWidget)
         {
            pWidget->repaint();
         }

         if ((i + 1) % (frameiterations / 100) == 0)
         {
            QString message = QString("Frame ") + QString::number(i+1) + QString(" of ") +
               QString::number(frameiterations);
            pDesktop->setStatusBarMessage(message.toStdString());
         }
         if ((i + 1) % 20 == 0)
         {
            clock_t stopTime = clock();
            double elapsedTime = static_cast<double>(stopTime - startTime) / CLOCKS_PER_SEC;
            if (elapsedTime > 30)
            {
               ++i;
               break;
            }
         }
      }
      clock_t stopTime = clock();
      double framesPerSec = i / (static_cast<double>(stopTime - startTime) / CLOCKS_PER_SEC);

      // restore display mode
      pLayer->setDisplayMode(initialDisplayMode);

      if (isBatch())
      {
         pOutArgList->setPlugInArgValue<double>("Framerate", &framesPerSec);
      }
      else
      {
         QMessageBox::information(pDesktop->getMainWidget(), "Frame Rate", 
            QString("The number of frames per second was: %1\nGPU Acceleration was%2 enabled\n").arg(framesPerSec)
                     .arg(pLayer->isGpuImageEnabled() ? "" : " not"));
      }

      return true;
   }

   return false;
}
Example #4
0
bool AceAlgorithm::processAll()
{
    auto_ptr<Wavelengths> pWavelengths;

    ProgressTracker progress(getProgress(), "Starting Ace", "spectral", "C4320027-6359-4F5B-8820-8BC72BF1B8F0");
    RasterElement* pElement = getRasterElement();
    if (pElement == NULL)
    {
        progress.report(ACEERR012, 0, ERRORS, true);
        return false;
    }

    const RasterDataDescriptor* pDescriptor = static_cast<RasterDataDescriptor*>(pElement->getDataDescriptor());
    VERIFY(pDescriptor != NULL);

    BitMaskIterator iter(getPixelsToProcess(), pElement);
    unsigned int numRows = iter.getNumSelectedRows();
    unsigned int numColumns = iter.getNumSelectedColumns();
    unsigned int numBands = pDescriptor->getBandCount();

    Opticks::PixelOffset layerOffset(iter.getColumnOffset(), iter.getRowOffset());

    // get cube wavelengths
    DynamicObject* pMetadata = pElement->getMetadata();
    if (pMetadata != NULL)
    {
        pWavelengths.reset(new Wavelengths(pMetadata));
        if (!pWavelengths->isEmpty() && (!pWavelengths->hasEndValues() || !pWavelengths->hasStartValues()))
        {
            pWavelengths->calculateFwhm();
        }
    }
    VERIFY(pWavelengths.get() != NULL);

    int sig_index = 0;
    bool bSuccess = true;

    if (mInputs.mSignatures.empty())
    {
        progress.report(ACEERR005, 0, ERRORS, true);
        return false;
    }

    int iSignatureCount = mInputs.mSignatures.size();

    // Create a vector for the signature names
    vector<string> sigNames;

    RasterElement* pResults = NULL;
    bool resultsIsTemp = false;

    Signature* pSignature = mInputs.mSignatures[sig_index];

    sigNames.push_back(pSignature->getName());
    std::string rname = mInputs.mResultsName;
    if (iSignatureCount > 1 && !mInputs.mbCreatePseudocolor)
    {
        rname += " " + sigNames.back();
    }
    else if (iSignatureCount > 1)
    {
        rname += "AceTemp";
        resultsIsTemp = true;
    }

    pResults = createResults(numRows, numColumns, rname);
    if (pResults == NULL)
    {
        return false;
    }

    vector<double> spectrumValues;
    vector<int> resampledBands;
    bSuccess = resampleSpectrum(pSignature, spectrumValues, *pWavelengths.get(), resampledBands);

    // Check for limited spectral coverage and warning log
    if (bSuccess && pWavelengths->hasCenterValues() &&
            resampledBands.size() != pWavelengths->getCenterValues().size())
    {
        QString buf = QString("Warning AceAlg014: The spectrum only provides spectral coverage for %1 of %2 bands.")
                      .arg(resampledBands.size()).arg(pWavelengths->getCenterValues().size());
        progress.report(buf.toStdString(), 0, WARNING, true);
    }

    BitMaskIterator iterChecker(getPixelsToProcess(), pElement);

    EncodingType type = pDescriptor->getDataType();
    switchOnEncoding(type, aceAlg, NULL, pElement, pResults, spectrumValues, mpProgress);

/////////////////////////////////////////////////////
    vector<ColorType> layerColors, excludeColors;
    excludeColors.push_back(ColorType(0, 0, 0));
    excludeColors.push_back(ColorType(255, 255, 255));
    ColorType::getUniqueColors(iSignatureCount, layerColors, excludeColors);

    ColorType color;
    if (0 <= static_cast<int>(layerColors.size()))
    {
        color = layerColors[0];
    }

    double dMaxValue = pResults->getStatistics()->getMax();

    // Displays results for current signature
    displayThresholdResults(pResults, color, UPPER, mInputs.mThreshold, dMaxValue, layerOffset);
//  displayThresholdResults(pResults, color, UPPER, 0.6, dMaxValue, layerOffset);
//////////////////////////////////////////////////////
    /*
       Service<DesktopServices> pDesktop;

       SpatialDataWindow* pWindow = static_cast<SpatialDataWindow*>(pDesktop->createWindow(rname,
    	   SPATIAL_DATA_WINDOW));

       SpatialDataView* pView = (pWindow == NULL) ? NULL : pWindow->getSpatialDataView();
       if (pView == NULL)
       {
    	   std::string msg = "Unable to create view.";
    	   progress.report(msg, 0, ERRORS, true);
    	   return false;
       }

       pView->setPrimaryRasterElement(pResults);
       pView->createLayer(RASTER, pResults);
    */
    return true;
}
Example #5
0
bool SioImporter::ensureStatisticsReadProperly(Progress *pProgress, std::ostream& failure)
{
   bool success = true;
   success &= setBatch();
   PlugInArgList* pInList = NULL;
   PlugInArgList* pOutList = NULL;
   isseas(getInputSpecification(pInList) != false, failure);
   isseas(getOutputSpecification(pOutList) != false, failure);
   PlugInArg* pRasterElementArg = NULL;
   isseas(pInList->getArg(Importer::ImportElementArg(), pRasterElementArg) != false, failure);

   string testFilePath = TestUtilities::getTestDataPath() + "tipjul5bands.sio";

   RasterElement* pRasterElement = NULL;
   if (success)
   {
      vector<ImportDescriptor*> descriptors = getImportDescriptors(testFilePath);
      if (descriptors.empty() == false)
      {
         ImportDescriptor* pImportDescriptor = descriptors.front();
         if (pImportDescriptor != NULL)
         {
            DataDescriptor* pDescriptor = pImportDescriptor->getDataDescriptor();
            if (pDescriptor != NULL)
            {
               Service<ModelServices> pModel;
               pRasterElement = dynamic_cast<RasterElement*>(pModel->createElement(pDescriptor));
               if (pRasterElement != NULL)
               {
                  pRasterElementArg->setActualValue(pRasterElement);
               }
            }
         }
      }
   }

   isseas(execute(pInList, pOutList) != false, failure);
   isseas(pRasterElement != NULL, failure);
   if (success)
   {
      RasterDataDescriptor* pDescriptor = dynamic_cast<RasterDataDescriptor*>(pRasterElement->getDataDescriptor());
      isseas(pDescriptor != NULL, failure);

      const vector<DimensionDescriptor>& loadedBands = pDescriptor->getBands();
      isseas(loadedBands.size() == 5, failure);
      int iNumBandsWithStats = 0;
      for (int i = 0; i < 5; ++i)
      {
         // we don't want to do an assert yet... only when we know 4 bands have computed statistics
         Statistics* pStatistics = pRasterElement->getStatistics(loadedBands[i]);
         if (pStatistics != NULL)
         {
            if (pStatistics->areStatisticsCalculated() == true)
            {
               if (success)
               {
                  iNumBandsWithStats++;
               }
            }
         }
      }

      // success of the band computation is dependent on 4 bands with statistics
      isseas(iNumBandsWithStats == 3, failure);
   }
   if (pRasterElement != NULL)
   {
      Service<ModelServices> pModel;
      pModel->destroyElement(pRasterElement);
      pRasterElement = NULL;
   }
   Service<PlugInManagerServices> pPim;
   if (pInList)
   {
      pPim->destroyPlugInArgList(pInList);
   }

   if (pOutList)
   {
      pPim->destroyPlugInArgList(pOutList);
   }

   return success;
}
Example #6
0
bool SioImporter::execute(PlugInArgList* pInArgList, PlugInArgList* pOutArgList)
{
   // Read the statistics from the file and set into the raster element
   RasterElement* pRaster = NULL;
   if (pInArgList != NULL)
   {
      pRaster = pInArgList->getPlugInArgValue<RasterElement>(Importer::ImportElementArg());
   }

   if (pRaster != NULL)
   {
      // Get the filename
      string filename = pRaster->getFilename();

      // Read the file
      FileResource pFile(filename.c_str(), "rb");

      SioFile sioFile;
      if (sioFile.deserialize(pFile.get()) == true)
      {
         if (sioFile.mOriginalVersion == 9 && isBatch())
         {
            //Since version 9 sio's are not officially supported
            //don't load them in batch to force users to load them
            //interactively which will show them the reason why.
            return false;
         }

         const RasterDataDescriptor* pDescriptor =
            dynamic_cast<const RasterDataDescriptor*>(pRaster->getDataDescriptor());

         if (pDescriptor != NULL && 
            RasterUtilities::isSubcube(pDescriptor, false) == false &&
            Service<SessionManager>()->isSessionLoading() == false)
         {
            const vector<DimensionDescriptor>& bands = pDescriptor->getBands();
            for (unsigned int i = 0; i < bands.size(); ++i)
            {
               Statistics* pStatistics = pRaster->getStatistics(bands[i]);
               if (pStatistics != NULL)
               {
                  // Bad values
                  if (i < sioFile.mBadValues.size())
                  {
                     vector<int> badValues = sioFile.mBadValues[i];
                     pStatistics->setBadValues(badValues);
                  }

                  // Min
                  if (i < sioFile.mStatMin.size())
                  {
                     double dMin = sioFile.mStatMin[i];
                     pStatistics->setMin(dMin);
                  }

                  // Max
                  if (i < sioFile.mStatMax.size())
                  {
                     double dMax = sioFile.mStatMax[i];
                     pStatistics->setMax(dMax);
                  }

                  // Average
                  if (i < sioFile.mStatAvg.size())
                  {
                     double dAverage = sioFile.mStatAvg[i];
                     pStatistics->setAverage(dAverage);
                  }

                  // Standard deviation
                  if (i < sioFile.mStatStdDev.size())
                  {
                     double dStdDev = sioFile.mStatStdDev[i];
                     pStatistics->setStandardDeviation(dStdDev);
                  }

                  // Percentiles
                  if (i < sioFile.mStatPercentile.size())
                  {
                     double* pPercentiles = sioFile.mStatPercentile[i];
                     pStatistics->setPercentiles(pPercentiles);
                  }

                  // Histogram
                  if ((i < sioFile.mStatBinCenter.size()) && (i < sioFile.mStatHistogram.size()))
                  {
                     double* pBinCenters = sioFile.mStatBinCenter[i];
                     unsigned int* pCounts = sioFile.mStatHistogram[i];
                     pStatistics->setHistogram(pBinCenters, pCounts);
                  }
               }
            }
         }
      }
   }

   return RasterElementImporterShell::execute(pInArgList, pOutArgList);
}
Example #7
0
File: Sam.cpp Project: yuguess/GSoC
bool SamAlgorithm::processAll()
{
   auto_ptr<Wavelengths> pWavelengths;

   ProgressTracker progress(getProgress(), "Starting SAM", "spectral", "C4320027-6359-4F5B-8820-8BC72BF1B8F0");
   progress.getCurrentStep()->addProperty("Interactive", isInteractive());

   RasterElement* pElement = getRasterElement();
   if (pElement == NULL)
   {
      progress.report(SAMERR012, 0, ERRORS, true);
      return false;
   }
   progress.getCurrentStep()->addProperty("Cube", pElement->getName());
   const RasterDataDescriptor* pDescriptor = static_cast<RasterDataDescriptor*>(pElement->getDataDescriptor());
   VERIFY(pDescriptor != NULL);

   BitMaskIterator iter(getPixelsToProcess(), pElement);
   unsigned int numRows = iter.getNumSelectedRows();
   unsigned int numColumns = iter.getNumSelectedColumns();
   unsigned int numBands = pDescriptor->getBandCount();
   Opticks::PixelOffset layerOffset(iter.getColumnOffset(), iter.getRowOffset());

   // get cube wavelengths
   DynamicObject* pMetadata = pElement->getMetadata();
   if (pMetadata != NULL)
   {
      pWavelengths.reset(new Wavelengths(pMetadata));
      if (!pWavelengths->isEmpty() && (!pWavelengths->hasEndValues() || !pWavelengths->hasStartValues()))
      {
         pWavelengths->calculateFwhm();
      }
   }
   VERIFY(pWavelengths.get() != NULL);

   int sig_index = 0;
   bool bSuccess = true;

   if (mInputs.mSignatures.empty())
   {
      progress.report(SAMERR005, 0, ERRORS, true);
      return false;
   }
   int iSignatureCount = mInputs.mSignatures.size();

   // Get colors for all the signatures
   vector<ColorType> layerColors, excludeColors;
   excludeColors.push_back(ColorType(0, 0, 0));
   excludeColors.push_back(ColorType(255, 255, 255));
   ColorType::getUniqueColors(iSignatureCount, layerColors, excludeColors);

   // Create a vector for the signature names
   vector<string> sigNames;

   // Create a pseudocolor results matrix if necessary
   RasterElement* pPseudocolorMatrix = NULL;
   RasterElement* pLowestSAMValueMatrix = NULL;
   // Check for multiple Signatures and if the user has selected
   // to combined multiple results in one pseudocolor output layer
   if (iSignatureCount > 1 && mInputs.mbCreatePseudocolor)
   {
      pPseudocolorMatrix = createResults(numRows, numColumns, mInputs.mResultsName);
      pLowestSAMValueMatrix = createResults(numRows, numColumns, "LowestSAMValue");

      if (pPseudocolorMatrix == NULL || pLowestSAMValueMatrix == NULL )
      {
         progress.report(SAMERR007, 0, ERRORS, true);
         return false;
      }

      FactoryResource<DataRequest> pseudoRequest;
      pseudoRequest->setWritable(true);
      string failedDataRequestErrorMessage =
         SpectralUtilities::getFailedDataRequestErrorMessage(pseudoRequest.get(), pPseudocolorMatrix);
      DataAccessor pseudoAccessor = pPseudocolorMatrix->getDataAccessor(pseudoRequest.release());
      if (!pseudoAccessor.isValid())
      {
         string msg = "Unable to access results.";
         if (!failedDataRequestErrorMessage.empty())
         {
            msg += "\n" + failedDataRequestErrorMessage;
         }

         progress.report(msg, 0, ERRORS, true);
         return false;
      }

      FactoryResource<DataRequest> lsvRequest;
      lsvRequest->setWritable(true);
      failedDataRequestErrorMessage =
         SpectralUtilities::getFailedDataRequestErrorMessage(lsvRequest.get(), pLowestSAMValueMatrix);
      DataAccessor lowestSamValueAccessor = pLowestSAMValueMatrix->getDataAccessor(lsvRequest.release());
      if (!lowestSamValueAccessor.isValid())
      {
         string msg = "Unable to access results.";
         if (!failedDataRequestErrorMessage.empty())
         {
            msg += "\n" + failedDataRequestErrorMessage;
         }

         progress.report(msg, 0, ERRORS, true);
         return false;
      }

      //Lets zero out all the results incase we connect to an existing matrix.
      float* pPseudoValue = NULL;
      float* pLowestValue = NULL;

      for (unsigned int row_ctr = 0; row_ctr < numRows; row_ctr++)
      {
         for (unsigned int col_ctr = 0; col_ctr < numColumns; col_ctr++)
         {
            if (!pseudoAccessor.isValid() || !lowestSamValueAccessor.isValid())
            {
               progress.report("Unable to access results.", 0, ERRORS, true);
               return false;
            }

            pLowestValue = reinterpret_cast<float*>(lowestSamValueAccessor->getColumn());
            pPseudoValue = reinterpret_cast<float*>(pseudoAccessor->getColumn());

            //Initialize the matrices
            *pPseudoValue = 0.0f;
            *pLowestValue = 180.0f;

            pseudoAccessor->nextColumn();
            lowestSamValueAccessor->nextColumn();
         }
         pseudoAccessor->nextRow();
         lowestSamValueAccessor->nextRow();
      }
   }

   RasterElement* pResults = NULL;
   bool resultsIsTemp = false;

   // Processes each selected signature one at a time and
   // accumulates results
   for (sig_index = 0; bSuccess && (sig_index < iSignatureCount) && !mAbortFlag; sig_index++)
   {
      // Get the spectrum
      Signature* pSignature = mInputs.mSignatures[sig_index];

      // Create the results matrix
      sigNames.push_back(pSignature->getName());
      std::string rname = mInputs.mResultsName;
      if (iSignatureCount > 1 && !mInputs.mbCreatePseudocolor)
      {
         rname += " " + sigNames.back();
      }
      else if (iSignatureCount > 1)
      {
         rname += "SamTemp";
         resultsIsTemp = true;
      }
      pResults = createResults(numRows, numColumns, rname);
      if (pResults == NULL)
      {
         bSuccess = false;
         break;
      }

      //Send the message to the progress object
      QString messageSigNumber = QString("Processing Signature %1 of %2 : SAM running on signature %3")
         .arg(sig_index+1).arg(iSignatureCount).arg(QString::fromStdString(sigNames.back()));
      string message = messageSigNumber.toStdString();

      vector<double> spectrumValues;
      vector<int> resampledBands;
      bSuccess = resampleSpectrum(pSignature, spectrumValues, *pWavelengths.get(), resampledBands);

      // Check for limited spectral coverage and warning log 
      if (bSuccess && pWavelengths->hasCenterValues() &&
         resampledBands.size() != pWavelengths->getCenterValues().size())
      {
         QString buf = QString("Warning SamAlg014: The spectrum only provides spectral coverage for %1 of %2 bands.")
            .arg(resampledBands.size()).arg(pWavelengths->getCenterValues().size());
         progress.report(buf.toStdString(), 0, WARNING, true);
      }

      if (bSuccess)
      {
         BitMaskIterator iterChecker(getPixelsToProcess(), pElement);

         SamAlgInput samInput(pElement, pResults, spectrumValues, &mAbortFlag, iterChecker, resampledBands);

         //Output Structure
         SamAlgOutput samOutput;

         // Reports current Spectrum SAM is running on
         mta::ProgressObjectReporter reporter(message, getProgress());

         // Initializes all threads
         mta::MultiThreadedAlgorithm<SamAlgInput, SamAlgOutput, SamThread>
            mtaSam(Service<ConfigurationSettings>()->getSettingThreadCount(),
            samInput, 
            samOutput, 
            &reporter);

         // Calculates spectral angle for current signature
         mtaSam.run();

         if (samInput.mpResultsMatrix == NULL)
         {
            Service<ModelServices>()->destroyElement(pResults);
            progress.report(SAMERR006, 0, ERRORS, true);
            mAbortFlag = false;
            return false;
         }

         if ((isInteractive() || mInputs.mbDisplayResults) && iSignatureCount > 1 && mInputs.mbCreatePseudocolor)
         {
            // Merges results in to one output layer if a Pseudocolor
            // output layer has been selected
            FactoryResource<DataRequest> pseudoRequest, currentRequest, lowestRequest;
            pseudoRequest->setWritable(true);
            string failedDataRequestErrorMessage =
               SpectralUtilities::getFailedDataRequestErrorMessage(pseudoRequest.get(), pPseudocolorMatrix);
            DataAccessor daPseudoAccessor = pPseudocolorMatrix->getDataAccessor(pseudoRequest.release());
            if (!daPseudoAccessor.isValid())
            {
               string msg = "Unable to access data.";
               if (!failedDataRequestErrorMessage.empty())
               {
                  msg += "\n" + failedDataRequestErrorMessage;
               }

               progress.report(msg, 0, ERRORS, true);
               return false;
            }

            DataAccessor daCurrentAccessor = pResults->getDataAccessor(currentRequest.release());

            lowestRequest->setWritable(true);
            failedDataRequestErrorMessage =
               SpectralUtilities::getFailedDataRequestErrorMessage(lowestRequest.get(), pLowestSAMValueMatrix);
            DataAccessor daLowestSAMValue = pLowestSAMValueMatrix->getDataAccessor(lowestRequest.release());
            if (!daLowestSAMValue.isValid())
            {
               string msg = "Unable to access data.";
               if (!failedDataRequestErrorMessage.empty())
               {
                  msg += "\n" + failedDataRequestErrorMessage;
               }

               progress.report(msg, 0, ERRORS, true);
               return false;
            }

            float* pPseudoValue = NULL;
            float* pCurrentValue = NULL;
            float* pLowestValue = NULL; 

            for (unsigned  int row_ctr = 0; row_ctr < numRows; row_ctr++)
            {
               for (unsigned  int col_ctr = 0; col_ctr < numColumns; col_ctr++)
               {
                  if (!daPseudoAccessor.isValid() || !daCurrentAccessor.isValid())
                  {
                     Service<ModelServices>()->destroyElement(pResults);
                     progress.report("Unable to access data.", 0, ERRORS, true);
                     return false;
                  }
                  daPseudoAccessor->toPixel(row_ctr, col_ctr);
                  daCurrentAccessor->toPixel(row_ctr, col_ctr);

                  pPseudoValue = reinterpret_cast<float*>(daPseudoAccessor->getColumn());
                  pCurrentValue = reinterpret_cast<float*>(daCurrentAccessor->getColumn());

                  daLowestSAMValue->toPixel(row_ctr, col_ctr);
                  pLowestValue = reinterpret_cast<float*>(daLowestSAMValue->getColumn());

                  if (*pCurrentValue <= mInputs.mThreshold)
                  {
                     if (*pCurrentValue < *pLowestValue)
                     {
                        *pPseudoValue = sig_index+1;
                        *pLowestValue = *pCurrentValue;
                     }
                  }
               }
            }
         }
         else
         {
            ColorType color;
            if (sig_index <= static_cast<int>(layerColors.size()))
            {
               color = layerColors[sig_index];
            }

            double dMaxValue = pResults->getStatistics()->getMax();

            // Displays results for current signature
            displayThresholdResults(pResults, color, LOWER, mInputs.mThreshold, dMaxValue, layerOffset);
         }

         //If we are on the last signature then destroy the lowest value Matrix
         if (sig_index == iSignatureCount-1)
         {
            if (pLowestSAMValueMatrix != NULL)
            {
               Service<ModelServices>()->destroyElement(pLowestSAMValueMatrix);
               pLowestSAMValueMatrix = NULL;
            }
         }
      }
   } //End of Signature Loop Counter

   if (resultsIsTemp || !bSuccess)
   {
      Service<ModelServices>()->destroyElement(pResults);
      pResults = NULL;
   }

   if (bSuccess)
   {
      // Displays final Pseudocolor output layer results
      if ((isInteractive() || mInputs.mbDisplayResults) && iSignatureCount > 1 && mInputs.mbCreatePseudocolor)
      {
         displayPseudocolorResults(pPseudocolorMatrix, sigNames, layerOffset);
      }
   }

   // Aborts gracefully after clean up
   if (mAbortFlag)
   {
      progress.abort();
      mAbortFlag = false;
      return false;
   }

   if (bSuccess)
   {
      if (pPseudocolorMatrix != NULL)
      {
         mpResults = pPseudocolorMatrix;
         mpResults->updateData();
      }
      else if (pResults != NULL)
      {
         mpResults = pResults;
         mpResults->updateData();
      }
      else
      {
         progress.report(SAMERR016, 0, ERRORS, true);
         return false;
      }
      progress.report(SAMNORM200, 100, NORMAL);
   }

   progress.getCurrentStep()->addProperty("Display Layer", mInputs.mbDisplayResults);
   progress.getCurrentStep()->addProperty("Threshold", mInputs.mThreshold);
   progress.upALevel();

   return bSuccess;
}