bool ResamplerPlugIn::execute(PlugInArgList* pInArgList, PlugInArgList* pOutArgList) { VERIFY(pInArgList != NULL && pOutArgList != NULL); ProgressTracker progress(pInArgList->getPlugInArgValue<Progress>(Executable::ProgressArg()), "Executing Spectral Resampler.", "spectral", "{88CD3E49-A522-431A-AE2A-96A6B2EB4012}"); Service<DesktopServices> pDesktop; const DataElement* pElement(NULL); std::string waveFilename; // get default resampling options from user config std::string resampleMethod = ResamplerOptions::getSettingResamplerMethod(); double dropOutWindow = ResamplerOptions::getSettingDropOutWindow(); double fwhm = ResamplerOptions::getSettingFullWidthHalfMax(); bool useFillValue = ResamplerOptions::getSettingUseFillValue(); double fillValue = ResamplerOptions::getSettingSignatureFillValue(); std::vector<Signature*> originalSignatures; std::auto_ptr<std::vector<Signature*> > pResampledSignatures(new std::vector<Signature*>); std::string errorMsg; if (isBatch()) { VERIFY(pInArgList->getPlugInArgValue("Signatures to resample", originalSignatures)); if (originalSignatures.empty()) { Signature* pSignature = pInArgList->getPlugInArgValue<Signature>("Signature to resample"); if (pSignature != NULL) { originalSignatures.push_back(pSignature); } } if (originalSignatures.empty()) { progress.report("No signatures are available to be resampled.", 0, ERRORS, true); return false; } pElement = pInArgList->getPlugInArgValue<DataElement>("Data element wavelength source"); Filename* pWaveFilename = pInArgList->getPlugInArgValue<Filename>("Wavelengths Filename"); if (pWaveFilename != NULL) { waveFilename = pWaveFilename->getFullPathAndName(); } VERIFY(pInArgList->getPlugInArgValue("Resampling Method", resampleMethod)); VERIFY(pInArgList->getPlugInArgValue("Drop out window", dropOutWindow)); VERIFY(pInArgList->getPlugInArgValue("FWHM", fwhm)); VERIFY(pInArgList->getPlugInArgValue("Use fill value", useFillValue)); VERIFY(pInArgList->getPlugInArgValue("Fill value", fillValue)); } else { ResamplerPlugInDlg dlg(pDesktop->getMainWidget()); if (dlg.exec() == QDialog::Rejected) { progress.report("User canceled resampling.", 0, ABORT, true); progress.upALevel(); return false; } originalSignatures = dlg.getSignaturesToResample(); resampleMethod = dlg.getResamplingMethod(); dropOutWindow = dlg.getDropOutWindow(); fwhm = dlg.getFWHM(); useFillValue = dlg.getUseFillValue(); fillValue = dlg.getFillValue(); pElement = dlg.getWavelengthsElement(); waveFilename = dlg.getWavelengthsFilename(); } std::string resampledTo; FactoryResource<Wavelengths> pWavelengths; if (pElement != NULL) // try loading wavelengths from user specified data element { if (getWavelengthsFromElement(pElement, pWavelengths.get(), errorMsg) == false) { progress.report(errorMsg, 0, ERRORS, true); return false; } resampledTo = pElement->getName(); } else if (waveFilename.empty() == false) // if no user provided raster, look for a wavelengths file { if (QFile::exists(QString::fromStdString(waveFilename))) { if (getWavelengthsFromFile(waveFilename, pWavelengths.get(), errorMsg) == false) { progress.report(errorMsg, 0, ERRORS, true); return false; } } else { errorMsg = "The wavelengths file \"" + waveFilename + "\" could not be found."; progress.report(errorMsg, 0, ERRORS, true); return false; } resampledTo = waveFilename; } else // if no wavelength source provided, look for raster in current active spatial data view { SpatialDataView* pView = dynamic_cast<SpatialDataView*>(pDesktop->getCurrentWorkspaceWindowView()); if (pView != NULL) { LayerList* pLayerList = pView->getLayerList(); if (pLayerList != NULL) { pElement = pLayerList->getPrimaryRasterElement(); pWavelengths->initializeFromDynamicObject(pElement->getMetadata(), false); if (pWavelengths->isEmpty()) { progress.report("No target wavelengths are available for resampling the signatures.", 0, ERRORS, true); return false; } resampledTo = pElement->getName(); } } } PlugInResource pPlugIn("Resampler"); Resampler* pResampler = dynamic_cast<Resampler*>(pPlugIn.get()); if (pResampler == NULL) { progress.report("The \"Resampler\" plug-in is not available so the signatures can not be resampled.", 0, ERRORS, true); return false; } std::string dataName("Reflectance"); std::string wavelengthName("Wavelength"); // save user config settings - Resampler doesn't have interface to set them separately from user config std::string configMethod = ResamplerOptions::getSettingResamplerMethod(); ResamplerOptions::setSettingResamplerMethod(resampleMethod); double configDropout = ResamplerOptions::getSettingDropOutWindow(); ResamplerOptions::setSettingDropOutWindow(dropOutWindow); double configFwhm = ResamplerOptions::getSettingFullWidthHalfMax(); ResamplerOptions::setSettingFullWidthHalfMax(fwhm); std::vector<double> toWavelengths = pWavelengths->getCenterValues(); std::vector<double> toFwhm = pWavelengths->getFwhm(); if (toFwhm.size() != toWavelengths.size()) { toFwhm.clear(); // Resampler will use the default config setting fwhm if this vector is empty } unsigned int numSigs = originalSignatures.size(); unsigned int numSigsResampled(0); progress.report("Begin resampling signatures...", 0, NORMAL); for (unsigned int index = 0; index < numSigs; ++index) { if (isAborted()) { progress.report("Resampling aborted by user", 100 * index / numSigs, ABORT, true); return false; } if (originalSignatures[index] == NULL) { continue; } // check if signature has target wavelength centers and doesn't need to be resampled if (needToResample(originalSignatures[index], pWavelengths.get()) == false) { pResampledSignatures->push_back(originalSignatures[index]); ++numSigsResampled; continue; } DataVariant var = originalSignatures[index]->getData(dataName); if (var.isValid() == false) { continue; } std::vector<double> fromData; if (!var.getValue(fromData)) { continue; } var = originalSignatures[index]->getData(wavelengthName); if (var.isValid() == false) { continue; } std::vector<double> fromWavelengths; if (!var.getValue(fromWavelengths)) { continue; } std::string resampledSigName = originalSignatures[index]->getName() + "_resampled"; int suffix(2); ModelResource<Signature> pSignature(resampledSigName, NULL); // probably not needed but just in case resampled name already used while (pSignature.get() == NULL) { pSignature = ModelResource<Signature>(resampledSigName + StringUtilities::toDisplayString(suffix), NULL); ++suffix; } if (resampledTo.empty() == false) { DynamicObject* pMetaData = pSignature->getMetadata(); if (pMetaData != NULL) { pMetaData->setAttribute(CommonSignatureMetadataKeys::ResampledTo(), resampledTo); } } std::vector<double> toData; std::vector<int> toBands; if (pResampler->execute(fromData, toData, fromWavelengths, toWavelengths, toFwhm, toBands, errorMsg)) { if (toWavelengths.size() != toBands.size()) { if (toBands.size() < 2) // no need to try if only one point { continue; } if (useFillValue) { std::vector<double> values(toWavelengths.size(), fillValue); for (unsigned int i = 0; i < toBands.size(); ++i) { values[static_cast<unsigned int>(toBands[i])] = toData[i]; } toData.swap(values); DynamicObject* pMetaData = pSignature->getMetadata(); if (pMetaData != NULL) { pMetaData->setAttribute(CommonSignatureMetadataKeys::FillValue(), fillValue); } } else { std::vector<double> wavelengths(toBands.size()); for (unsigned int i = 0; i < toBands.size(); ++i) { wavelengths[i] = toWavelengths[static_cast<unsigned int>(toBands[i])]; } toWavelengths.swap(wavelengths); } } pSignature->setData(dataName, toData); pSignature->setData(wavelengthName, toWavelengths); SignatureDataDescriptor* pDesc = dynamic_cast<SignatureDataDescriptor*>(pSignature->getDataDescriptor()); if (pDesc == NULL) { continue; } pDesc->setUnits(dataName, originalSignatures[index]->getUnits(dataName)); pResampledSignatures->push_back(pSignature.release()); ++numSigsResampled; } std::string progressStr = QString("Resampled signature %1 of %2 signatures").arg(index + 1).arg(numSigs).toStdString(); progress.report(progressStr, (index + 1) * 100 / numSigs, NORMAL); } // reset config options ResamplerOptions::setSettingResamplerMethod(configMethod); ResamplerOptions::setSettingDropOutWindow(configDropout); ResamplerOptions::setSettingFullWidthHalfMax(configFwhm); if (numSigsResampled == numSigs) { progress.report("Complete", 100, NORMAL); progress.upALevel(); } else { errorMsg = QString("Only %1 of the %2 signatures were successfully resampled.").arg( numSigsResampled).arg(numSigs).toStdString(); progress.report(errorMsg, 100, WARNING, true); } VERIFY(pOutArgList->setPlugInArgValue("Resampled signatures", pResampledSignatures.release())); return true; }
void SpectralLibraryMatchResults::createAverageSignature() { Service<DesktopServices> pDesktop; const RasterElement* pRaster = getRasterElementForCurrentPage(); if (pRaster == NULL) { pDesktop->showMessageBox("Spectral Library Match", "Unable to determine the RasterElement for the current page."); return; } std::vector<Signature*> signatures = getSelectedSignatures(); if (signatures.empty()) { pDesktop->showMessageBox("Spectral Library Match", "No signatures are selected for use in generating an average signature."); return; } // now need to get the resampled sigs from the library SpectralLibraryManager* pLibMgr(NULL); std::vector<PlugIn*> plugIns = Service<PlugInManagerServices>()->getPlugInInstances(SpectralLibraryMatch::getNameLibraryManagerPlugIn()); if (!plugIns.empty()) { pLibMgr = dynamic_cast<SpectralLibraryManager*>(plugIns.front()); } if (pLibMgr == NULL) { pDesktop->showMessageBox("Spectral Library Match", "Unable to access the Spectral Library Manager."); return; } const RasterDataDescriptor* pDesc = dynamic_cast<const RasterDataDescriptor*>(pRaster->getDataDescriptor()); if (pDesc == NULL) { pDesktop->showMessageBox("Spectral Library Match", "Unable to access the RasterDataDescriptor for the RasterElement of the current page."); return; } unsigned int numBands = pDesc->getBandCount(); std::vector<double> averageValues(numBands, 0); std::vector<double> values; for (std::vector<Signature*>::iterator it = signatures.begin(); it != signatures.end(); ++it) { if (pLibMgr->getResampledSignatureValues(pRaster, *it, values) == false) { pDesktop->showMessageBox("Spectral Library Match", "Unable to access the resampled signature values for " + (*it)->getDisplayName(true)); return; } for (unsigned int band = 0; band < numBands; ++band) { averageValues[band] += values[band]; } } unsigned int numSigs = signatures.size(); for (unsigned int band = 0; band < numBands; ++band) { averageValues[band] /= static_cast<double>(numSigs); } QString avgName = QInputDialog::getText(pDesktop->getMainWidget(), "Spectral Library Match", "Enter the name to use for the average signature:"); if (avgName.isEmpty()) { return; } ModelResource<Signature> pAvgSig(avgName.toStdString(), const_cast<RasterElement*>(pRaster)); pAvgSig->setData("Reflectance", averageValues); const DynamicObject* pMetaData = pRaster->getMetadata(); FactoryResource<Wavelengths> pWavelengths; pWavelengths->initializeFromDynamicObject(pMetaData, false); const std::vector<double>& centerValues = pWavelengths->getCenterValues(); pAvgSig->setData("Wavelength", centerValues); SignatureDataDescriptor* pSigDesc = dynamic_cast<SignatureDataDescriptor*>(pAvgSig->getDataDescriptor()); VERIFYNRV(pSigDesc != NULL); FactoryResource<Units> pUnits; const Units* pRasterUnits = pDesc->getUnits(); pUnits->setUnitName(pRasterUnits->getUnitName()); pUnits->setUnitType(pRasterUnits->getUnitType()); pUnits->setScaleFromStandard(1.0); // the rescaled values are already corrected for the original scaling factor pUnits->setRangeMin(pRasterUnits->getRangeMin()); pUnits->setRangeMax(pRasterUnits->getRangeMax()); pSigDesc->setUnits("Reflectance", pUnits.get()); pAvgSig.release(); }
bool SpectralLibraryManager::generateResampledLibrary(const RasterElement* pRaster) { VERIFY(pRaster != NULL); // check that lib sigs are in same units as the raster element const RasterDataDescriptor* pDesc = dynamic_cast<const RasterDataDescriptor*>(pRaster->getDataDescriptor()); VERIFY(pDesc != NULL); const Units* pUnits = pDesc->getUnits(); if (pDesc->getUnits()->getUnitType() != mLibraryUnitType) { if (Service<DesktopServices>()->showMessageBox("Mismatched Units", "The data are not in the " "same units as the spectral library.\n Do you want to continue anyway?", "Yes", "No") == 1) { return false; } } FactoryResource<Wavelengths> pWavelengths; pWavelengths->initializeFromDynamicObject(pRaster->getMetadata(), false); // populate the library with the resampled signatures PlugInResource pPlugIn("Resampler"); Resampler* pResampler = dynamic_cast<Resampler*>(pPlugIn.get()); VERIFY(pResampler != NULL); if (pWavelengths->getNumWavelengths() != pDesc->getBandCount()) { mpProgress->updateProgress("Wavelength information in metadata does not match the number of bands " "in the raster element", 0, ERRORS); return false; } // get resample suitable signatures - leave out signatures that don't cover the spectral range of the data std::vector<std::vector<double> > resampledData; resampledData.reserve(mSignatures.size()); std::vector<Signature*> resampledSignatures; resampledSignatures.reserve(mSignatures.size()); std::vector<std::string> unsuitableSignatures; std::vector<double> sigValues; std::vector<double> sigWaves; std::vector<double> rasterWaves = pWavelengths->getCenterValues(); std::vector<double> rasterFwhm = pWavelengths->getFwhm(); std::vector<double> resampledValues; std::vector<int> bandIndex; DataVariant data; for (std::vector<Signature*>::const_iterator it = mSignatures.begin(); it != mSignatures.end(); ++it) { data = (*it)->getData(SpectralLibraryMatch::getNameSignatureWavelengthData()); VERIFY(data.isValid()); VERIFY(data.getValue(sigWaves)); resampledValues.clear(); data = (*it)->getData(SpectralLibraryMatch::getNameSignatureAmplitudeData()); VERIFY(data.isValid()); VERIFY(data.getValue(sigValues)); double scaleFactor = (*it)->getUnits( SpectralLibraryMatch::getNameSignatureAmplitudeData())->getScaleFromStandard(); for (std::vector<double>::iterator sit = sigValues.begin(); sit != sigValues.end(); ++sit) { *sit *= scaleFactor; } std::string msg; if (pResampler->execute(sigValues, resampledValues, sigWaves, rasterWaves, rasterFwhm, bandIndex, msg) == false || resampledValues.size() != rasterWaves.size()) { unsuitableSignatures.push_back((*it)->getName()); continue; } resampledData.push_back(resampledValues); resampledSignatures.push_back(*it); } if (resampledSignatures.empty()) { std::string errMsg = "None of the signatures in the library cover the spectral range of the data."; if (mpProgress != NULL) { mpProgress->updateProgress(errMsg, 0, ERRORS); return false; } } if (unsuitableSignatures.empty() == false) { std::string warningMsg = "The following library signatures do not cover the spectral range of the data:\n"; for (std::vector<std::string>::iterator it = unsuitableSignatures.begin(); it != unsuitableSignatures.end(); ++it) { warningMsg += *it + "\n"; } warningMsg += "These signatures will not be searched for in the data."; Service<DesktopServices>()->showMessageBox("SpectralLibraryManager", warningMsg); StepResource pStep("Spectral LibraryManager", "spectral", "64B6C87A-A6C3-4378-9B6E-221D89D8707B"); pStep->finalize(Message::Unresolved, warningMsg); } std::string libName = "Resampled Spectral Library"; // Try to get the resampled lib element in case session was restored. If NULL, create a new raster element with // num rows = num valid signatures, num cols = 1, num bands = pRaster num bands RasterElement* pLib = dynamic_cast<RasterElement*>(Service<ModelServices>()->getElement(libName, TypeConverter::toString<RasterElement>(), pRaster)); if (pLib != NULL) { // check that pLib has same number of sigs as SpectralLibraryManager RasterDataDescriptor* pLibDesc = dynamic_cast<RasterDataDescriptor*>(pLib->getDataDescriptor()); VERIFY(pLibDesc != NULL); if (pLibDesc->getRowCount() != mSignatures.size()) { mpProgress->updateProgress("An error occurred during session restore and some signatures were not restored." " Check the spectral library before using.", 0, ERRORS); Service<ModelServices>()->destroyElement(pLib); pLib = NULL; } } bool isNewElement(false); if (pLib == NULL) { pLib = RasterUtilities::createRasterElement(libName, static_cast<unsigned int>(resampledData.size()), 1, pDesc->getBandCount(), FLT8BYTES, BIP, true, const_cast<RasterElement*>(pRaster)); isNewElement = true; } if (pLib == NULL) { mpProgress->updateProgress("Error occurred while trying to create the resampled spectral library", 0, ERRORS); return false; } RasterDataDescriptor* pLibDesc = dynamic_cast<RasterDataDescriptor*>(pLib->getDataDescriptor()); VERIFY(pLibDesc != NULL); // copy resampled data into new element if (isNewElement) { FactoryResource<DataRequest> pRequest; pRequest->setWritable(true); pRequest->setRows(pLibDesc->getActiveRow(0), pLibDesc->getActiveRow(pLibDesc->getRowCount()-1), 1); DataAccessor acc = pLib->getDataAccessor(pRequest.release()); for (std::vector<std::vector<double> >::iterator sit = resampledData.begin(); sit != resampledData.end(); ++sit) { VERIFY(acc->isValid()); void* pData = acc->getColumn(); memcpy(acc->getColumn(), &(sit->begin()[0]), pLibDesc->getBandCount() * sizeof(double)); acc->nextRow(); } // set wavelength info in resampled library pWavelengths->applyToDynamicObject(pLib->getMetadata()); FactoryResource<Units> libUnits; libUnits->setUnitType(mLibraryUnitType); libUnits->setUnitName(StringUtilities::toDisplayString<UnitType>(mLibraryUnitType)); pLibDesc->setUnits(libUnits.get()); } pLib->attach(SIGNAL_NAME(Subject, Deleted), Slot(this, &SpectralLibraryManager::resampledElementDeleted)); mLibraries[pRaster] = pLib; mResampledSignatures[pLib] = resampledSignatures; const_cast<RasterElement*>(pRaster)->attach(SIGNAL_NAME(Subject, Deleted), Slot(this, &SpectralLibraryManager::elementDeleted)); return true; }
bool ImporterShell::validate(const DataDescriptor* pDescriptor, string& errorMessage) const { mValidationError = ValidationTest(); // Check for no validation int validationTest = getValidationTest(pDescriptor); if (validationTest == NO_VALIDATION) { return true; } // Always validate the data descriptor and file descriptor if (pDescriptor == NULL) { errorMessage = "The data set information is invalid."; return false; } const FileDescriptor* pFileDescriptor = pDescriptor->getFileDescriptor(); if (pFileDescriptor == NULL) { errorMessage = "The data set does not contain valid file information."; return false; } // Existing file const string& filename = pFileDescriptor->getFilename(); if (validationTest & EXISTING_FILE) { // Valid filename if (filename.empty() == true) { errorMessage = "The filename is invalid."; mValidationError = EXISTING_FILE; return false; } // Existing file LargeFileResource file(true); if (!file.open(filename.c_str(), O_RDONLY | O_BINARY, S_IREAD)) { errorMessage = "The file: " + filename + " does not exist."; mValidationError = EXISTING_FILE; return false; } } // Existing data element if (validationTest & NO_EXISTING_DATA_ELEMENT) { const string& name = pDescriptor->getName(); const string& type = pDescriptor->getType(); DataElement* pParent = pDescriptor->getParent(); Service<ModelServices> pModel; if (pModel->getElement(name, type, pParent) != NULL) { errorMessage = "The data set currently exists. It may have already been imported."; mValidationError = NO_EXISTING_DATA_ELEMENT; return false; } } // Valid classification Service<UtilityServices> pUtilities; if (validationTest & VALID_CLASSIFICATION) { // Existing Classification object const Classification* pClassification = pDescriptor->getClassification(); if (pClassification == NULL) { errorMessage = "The required classification does not exist."; mValidationError = VALID_CLASSIFICATION; return false; } // Unauthorized classification level on the system - warn the user, but continue to load the file FactoryResource<Classification> pSystemClassification; pSystemClassification->setLevel(pUtilities->getDefaultClassification()); if (pClassification->hasGreaterLevel(pSystemClassification.get()) == true) { errorMessage = "THIS FILE CONTAINS CLASSIFIED INFORMATION WHICH SHOULD NOT BE PROCESSED ON THIS SYSTEM!\n" "THIS MAY CONSTITUTE A SECURITY VIOLATION WHICH SHOULD BE REPORTED TO YOUR SECURITY OFFICER!\n"; StepResource pStep("Validate", "app", "1A881267-6A96-4eb2-A9D3-7D30334B0A0B", errorMessage); } } // Valid metadata if (validationTest & VALID_METADATA) { if (pDescriptor->getMetadata() == NULL) { errorMessage = "The required metadata does not exist."; mValidationError = VALID_METADATA; return false; } } // Processing location if (validationTest & VALID_PROCESSING_LOCATION) { if (isProcessingLocationSupported(pDescriptor->getProcessingLocation()) == false) { errorMessage = "The specified processing location is not supported."; mValidationError = VALID_PROCESSING_LOCATION; return false; } } // If no RasterDataDescriptor or RasterFileDescriptor tests are performed, end here if (validationTest < RASTER_SIZE) { return true; } // Since raster tests have been specified, always validate the raster data descriptor and raster file descriptor const RasterDataDescriptor* pRasterDescriptor = dynamic_cast<const RasterDataDescriptor*>(pDescriptor); if (pRasterDescriptor == NULL) { errorMessage = "The data set does not contain raster information."; return false; } const RasterFileDescriptor* pRasterFileDescriptor = dynamic_cast<const RasterFileDescriptor*>(pRasterDescriptor->getFileDescriptor()); if (pRasterFileDescriptor == NULL) { errorMessage = "The file does not contain valid raster data."; return false; } // Raster size if (validationTest & RASTER_SIZE) { // Data set size unsigned int loadedRows = pRasterDescriptor->getRowCount(); unsigned int loadedColumns = pRasterDescriptor->getColumnCount(); unsigned int loadedBands = pRasterDescriptor->getBandCount(); if ((loadedRows == 0) || (loadedColumns == 0) || (loadedBands == 0)) { errorMessage = "The data set is empty. Check the size of the rows, columns, and bands."; mValidationError = RASTER_SIZE; return false; } // Pixel size if (pRasterFileDescriptor->getBitsPerElement() == 0) { errorMessage = "The number of bits per element is invalid."; mValidationError = RASTER_SIZE; return false; } } // Data type if (validationTest & VALID_DATA_TYPE) { const std::vector<EncodingType>& dataTypes = pRasterDescriptor->getValidDataTypes(); if (std::find(dataTypes.begin(), dataTypes.end(), pRasterDescriptor->getDataType()) == dataTypes.end()) { errorMessage = "The data type is not valid for this data set."; mValidationError = VALID_DATA_TYPE; return false; } } // Header bytes if (validationTest & NO_HEADER_BYTES) { if (pRasterFileDescriptor->getHeaderBytes() > 0) { errorMessage = "The file has an invalid number of header bytes."; mValidationError = NO_HEADER_BYTES; return false; } } // Preline and postline bytes if (validationTest & NO_PRE_POST_LINE_BYTES) { if ((pRasterFileDescriptor->getPrelineBytes() > 0) || (pRasterFileDescriptor->getPostlineBytes() > 0)) { errorMessage = "The file has an invalid number of preline and/or postline bytes."; mValidationError = NO_PRE_POST_LINE_BYTES; return false; } } // Preband and postband bytes if (validationTest & NO_PRE_POST_BAND_BYTES) { if ((pRasterFileDescriptor->getPrebandBytes() > 0) || (pRasterFileDescriptor->getPostbandBytes() > 0)) { errorMessage = "The file has an invalid number of preband and/or postband bytes."; mValidationError = NO_PRE_POST_BAND_BYTES; return false; } } // Trailer bytes if (validationTest & NO_TRAILER_BYTES) { if (pRasterFileDescriptor->getTrailerBytes() > 0) { errorMessage = "The file has an invalid number of trailer bytes."; mValidationError = NO_TRAILER_BYTES; return false; } } // File size int64_t requiredSize = RasterUtilities::calculateFileSize(pRasterFileDescriptor); if ((validationTest & FILE_SIZE) == FILE_SIZE) { // Existing file LargeFileResource file; VERIFY(file.open(filename, O_RDONLY | O_BINARY, S_IREAD) == true); // File size if (requiredSize < 0) { errorMessage = "Unable to determine the required file size."; mValidationError = FILE_SIZE; return false; } if (file.fileLength() < requiredSize) { errorMessage = "The size of the file does not match the current parameters."; mValidationError = FILE_SIZE; return false; } } // Band files const vector<const Filename*>& bandFiles = pRasterFileDescriptor->getBandFiles(); if (validationTest & NO_BAND_FILES) { if (bandFiles.empty() == false) { errorMessage = "This data set cannot have band data in multiple files."; mValidationError = NO_BAND_FILES; return false; } } // Existing band files and band file sizes if (validationTest & EXISTING_BAND_FILES) { // Enough band files for all bands unsigned int numBands = pRasterFileDescriptor->getBandCount(); if (bandFiles.size() < numBands) { errorMessage = "The number of band files specified is less than the total number of bands to be loaded."; mValidationError = EXISTING_BAND_FILES; return false; } // Invalid file for imported bands for (vector<const Filename*>::size_type i = 0; i < bandFiles.size(); ++i) { const Filename* pFilename = bandFiles[i]; if (pFilename == NULL) { stringstream streamMessage; streamMessage << "Band filename " << i + 1 << " is missing."; errorMessage = streamMessage.str(); mValidationError = EXISTING_BAND_FILES; return false; } // Invalid filename string bandFilename = pFilename->getFullPathAndName(); if (bandFilename.empty() == true) { stringstream streamMessage; streamMessage << "Band filename " << i + 1 << " is invalid."; errorMessage = streamMessage.str(); mValidationError = EXISTING_BAND_FILES; return false; } // Existing file LargeFileResource bandFile; if (!bandFile.open(bandFilename, O_RDONLY | O_BINARY, S_IREAD)) { stringstream streamMessage; streamMessage << "Band file " << i + 1 << " does not exist."; errorMessage = streamMessage.str(); mValidationError = EXISTING_BAND_FILES; return false; } // File size if ((validationTest & BAND_FILE_SIZES) == BAND_FILE_SIZES) { if (requiredSize < 0) { errorMessage = "Unable to determine the required band file size."; mValidationError = BAND_FILE_SIZES; return false; } if (bandFile.fileLength() < requiredSize) { stringstream streamMessage; streamMessage << "The size of band file " << i + 1 << " does not match the required size " "for the current parameters."; errorMessage = streamMessage.str(); mValidationError = BAND_FILE_SIZES; return false; } } } } // Band names const DynamicObject* pMetadata = pRasterDescriptor->getMetadata(); if ((validationTest & VALID_BAND_NAMES) == VALID_BAND_NAMES) { VERIFY(pMetadata != NULL); string namesPath[] = { SPECIAL_METADATA_NAME, BAND_METADATA_NAME, NAMES_METADATA_NAME, END_METADATA_NAME }; // If band names are present in the metadata, check the number of names against the number of bands // If band names are not present in the metadata, then succeed const vector<string>* pBandNames = dv_cast<vector<string> >(&pMetadata->getAttributeByPath(namesPath)); if (pBandNames != NULL) { if (pBandNames->size() != pRasterFileDescriptor->getBandCount()) { errorMessage = "The number of band names in the metadata does not match the number of bands."; mValidationError = VALID_BAND_NAMES; return false; } } } // Wavelengths if ((validationTest & VALID_WAVELENGTHS) == VALID_WAVELENGTHS) { VERIFY(pMetadata != NULL); // If wavelengths are present in the metadata, check the number of wavelengths against the number of bands // If wavelengths are not present in the metadata, then succeed FactoryResource<Wavelengths> pWavelengths; if (pWavelengths->initializeFromDynamicObject(pMetadata, false) == true) { if (pWavelengths->getNumWavelengths() != pRasterFileDescriptor->getBandCount()) { errorMessage = "The number of wavelengths in the metadata does not match the number of bands."; mValidationError = VALID_WAVELENGTHS; return false; } } } // Interleave conversions if (validationTest & NO_INTERLEAVE_CONVERSIONS) { InterleaveFormatType dataInterleave = pRasterDescriptor->getInterleaveFormat(); InterleaveFormatType fileInterleave = pRasterFileDescriptor->getInterleaveFormat(); if ((pRasterFileDescriptor->getBandCount() > 1) && (dataInterleave != fileInterleave)) { errorMessage = "Interleave format conversions are not supported."; mValidationError = NO_INTERLEAVE_CONVERSIONS; return false; } } // Skip factors if (validationTest & NO_ROW_SKIP_FACTOR) { if (pRasterDescriptor->getRowSkipFactor() > 0) { errorMessage = "Row skip factors are not supported."; mValidationError = NO_ROW_SKIP_FACTOR; return false; } } if (validationTest & NO_COLUMN_SKIP_FACTOR) { if (pRasterDescriptor->getColumnSkipFactor() > 0) { errorMessage = "Column skip factors are not supported."; mValidationError = NO_COLUMN_SKIP_FACTOR; return false; } } // Subsets if (validationTest & NO_ROW_SUBSETS) { if (pRasterDescriptor->getRowCount() != pRasterFileDescriptor->getRowCount()) { errorMessage = "Row subsets are not supported."; mValidationError = NO_ROW_SUBSETS; return false; } } if (validationTest & NO_COLUMN_SUBSETS) { if (pRasterDescriptor->getColumnCount() != pRasterFileDescriptor->getColumnCount()) { errorMessage = "Column subsets are not supported."; mValidationError = NO_COLUMN_SUBSETS; return false; } } if (validationTest & NO_BAND_SUBSETS) { if (pRasterDescriptor->getBandCount() != pRasterFileDescriptor->getBandCount()) { errorMessage = "Band subsets are not supported."; mValidationError = NO_BAND_SUBSETS; return false; } } // Available memory if (validationTest & AVAILABLE_MEMORY) { unsigned int loadedRows = pRasterDescriptor->getRowCount(); unsigned int loadedColumns = pRasterDescriptor->getColumnCount(); unsigned int loadedBands = pRasterDescriptor->getBandCount(); unsigned int bytesPerElement = pRasterDescriptor->getBytesPerElement(); uint64_t dataSize = loadedRows * loadedColumns * loadedBands * bytesPerElement; uint64_t maxMemoryAvail = pUtilities->getMaxMemoryBlockSize(); #if PTR_SIZE > 4 uint64_t totalRam = pUtilities->getTotalPhysicalMemory(); if (totalRam < maxMemoryAvail) { maxMemoryAvail = totalRam; } #endif if (dataSize > maxMemoryAvail) { errorMessage = "The data set cannot be loaded into memory. Use a different " "processing location or specify a subset."; mValidationError = AVAILABLE_MEMORY; return false; } } return true; }