19 #include "Application.h"
22 #include "CameraFactory.h"
23 #include "CubeAttribute.h"
24 #include "CubeBsqHandler.h"
25 #include "CubeTileHandler.h"
26 #include "CubeStretch.h"
30 #include "ImageHistogram.h"
31 #include "ImagePolygon.h"
32 #include "IException.h"
33 #include "LineManager.h"
35 #include "OriginalLabel.h"
36 #include "OriginalXmlLabel.h"
37 #include "Preference.h"
38 #include "ProgramLauncher.h"
39 #include "Projection.h"
40 #include "SpecialPixel.h"
41 #include "Statistics.h"
43 #include "TProjection.h"
44 #include "Longitude.h"
62 Cube::Cube(
const FileName &fileName, QString access) {
76 void Cube::fromLabel(
const FileName &fileName,
Pvl &label, QString access) {
77 initCoreFromLabel(label);
99 void Cube::fromIsd(
const FileName &fileName,
Pvl &label, nlohmann::json &isd, QString access) {
100 fromLabel(fileName, label, access);
101 attachSpiceFromIsd(isd);
118 std::ifstream isdStream(isdFile.
expanded().toStdString());
119 std::ifstream labelStream(labelFile.
expanded().toStdString());
121 if (isdStream.fail()) {
122 QString msg = QString(
"failed to open isd stream: %1").arg(isdFile.
expanded());
124 isdFile.
baseName().toStdString().c_str(), 153);
127 if (labelStream.fail()) {
128 QString msg =
"failed to open file stream";
130 fileName.
baseName().toStdString().c_str(), 153);
137 labelStream >> label;
139 catch (std::exception &ex) {
140 QString msg = QString(
"Failed to open label file, %1, %2").arg(labelFile.
expanded()).arg(ex.what());
142 fileName.
baseName().toStdString().c_str(), 153);
149 catch (std::exception &ex) {
150 QString msg = QString(
"Failed to open ISD file, %1, %2").arg(isdFile.
expanded()).arg(ex.what());
152 fileName.
baseName().toStdString().c_str(), 145);
155 fromIsd(fileName, label, isd, access);
173 delete m_formatTemplateFile;
174 m_formatTemplateFile = NULL;
183 bool Cube::isOpen()
const {
184 bool open = (m_ioHandler != NULL);
186 ASSERT(open == (
bool)m_labelFile);
187 ASSERT(open == (
bool)m_labelFileName);
188 ASSERT(open == (
bool)m_label);
202 bool Cube::isProjected()
const {
203 return label()->findObject(
"IsisCube").hasGroup(
"Mapping");
213 bool Cube::isReadOnly()
const {
214 bool readOnly =
false;
217 QString msg =
"No cube opened";
218 throw IException(IException::Programmer, msg, _FILEINFO_);
221 if ((m_labelFile->openMode() & QIODevice::ReadWrite) != QIODevice::ReadWrite)
235 bool Cube::isReadWrite()
const {
236 return !isReadOnly();
248 bool Cube::labelsAttached()
const {
260 void Cube::close(
bool removeIt) {
261 if (isOpen() && isReadWrite())
279 QObject::tr(
"Cube::copy requires the originating cube to be open"),
287 result->
setDimensions(sampleCount(), lineCount(), bandCount());
306 else if(result->
pixelType() >= pixelType()) {
311 QObject::tr(
"Cannot reduce the output PixelType for [%1] from [%2] without output "
312 "pixel range").arg(newFile.
original()).arg(fileName());
313 throw IException(IException::User, msg, _FILEINFO_);
326 m_ioHandler->clearCache(
true);
337 for(
int i = 0; i < isisCube.
groups(); i++) {
341 if (label()->hasObject(
"NaifKeywords")) {
343 label()->findObject(
"NaifKeywords"));
346 for (
int i = 0; i < m_label->objects(); i++) {
360 BufferManager output(sampleCount(), lineCount(), bandCount(),
367 while (!input.
end()) {
369 output.
Copy(input,
false);
371 result->
write(output);
414 void Cube::create(
const QString &cubeFileName) {
417 string msg =
"You already have a cube opened";
418 throw IException(IException::Programmer, msg, _FILEINFO_);
421 if (m_samples < 1 || m_lines < 1 || m_bands < 1) {
422 QString msg =
"Number of samples [" +
toString(m_samples) +
424 "] cannot be less than 1";
425 throw IException(IException::Programmer, msg, _FILEINFO_);
428 if (m_pixelType == None) {
430 QString(
"Cannot create the cube [%1] with a pixel type set to None")
435 if (m_storesDnData) {
444 int maxSizePreference = 0;
447 Preference::Preferences().findGroup(
"CubeCustomization")[
"MaximumSize"];
449 if (size > maxSizePreference) {
451 msg +=
"The cube you are attempting to create [" + cubeFileName +
"] is ["
452 +
toString(size) +
"GB]. This is larger than the current allowed "
453 "size of [" +
toString(maxSizePreference) +
"GB]. The cube "
454 "dimensions were (S,L,B) [" +
toString(m_samples) +
", " +
456 toString(
SizeOf(m_pixelType)) +
"] bytes per pixel. If you still "
457 "wish to create this cube, the maximum value can be changed in your personal "
458 "preference file located in [~/.Isis/IsisPreferences] within the group "
459 "CubeCustomization, keyword MaximumSize. If you do not have an ISISPreference file, "
460 "please refer to the documentation \"Environment and Preference Setup\". Error ";
461 throw IException(IException::User, msg, _FILEINFO_);
470 if (m_storesDnData) {
477 m_labelFileName =
new FileName(cubFile);
478 m_dataFileName =
new FileName(cubFile);
479 m_labelFile =
new QFile(m_labelFileName->expanded());
484 m_dataFileName =
new FileName(cubFile);
485 m_dataFile =
new QFile(realDataFileName().expanded());
489 m_labelFileName =
new FileName(labelFileName);
490 m_labelFile =
new QFile(m_labelFileName->expanded());
505 ptype +=
PvlKeyword(
"ByteOrder", ByteOrderName(m_byteOrder));
513 ASSERT(m_dataFileName);
515 core +=
PvlKeyword(
"^DnFile", m_dataFileName->original());
517 m_dataFile =
new QFile(realDataFileName().expanded());
519 m_labelFileName =
new FileName(cubFile);
520 m_labelFile =
new QFile(cubFile.
expanded());
531 m_label->addObject(lbl);
534 Preference::Preferences().findGroup(
"CubeCustomization");
535 bool overwrite = pref[
"Overwrite"][0].toUpper() ==
"ALLOW";
536 if (!overwrite && m_labelFile->exists() && m_labelFile->size()) {
537 QString msg =
"Cube file [" + m_labelFileName->original() +
"] exists, " +
538 "user preference does not allow overwrite";
539 throw IException(IException::User, msg, _FILEINFO_);
542 if (!m_labelFile->open(QIODevice::Truncate | QIODevice::ReadWrite)) {
543 QString msg =
"Failed to create [" + m_labelFile->fileName() +
"]. ";
544 msg +=
"Verify the output path exists and you have permission to write to the path.";
546 throw IException(IException::Io, msg, _FILEINFO_);
550 if (m_storesDnData && !m_dataFile->open(QIODevice::Truncate | QIODevice::ReadWrite)) {
551 QString msg =
"Failed to create [" + m_dataFile->fileName() +
"]. ";
552 msg +=
"Verify the output path exists and you have permission to write to the path.";
554 throw IException(IException::Io, msg, _FILEINFO_);
556 else if (!m_storesDnData && !m_dataFile->open(QIODevice::ReadOnly)) {
557 QString msg =
"Failed to open [" + m_dataFile->fileName() +
"] for reading. ";
558 msg +=
"Verify the output path exists and you have permission to read from the path.";
560 throw IException(IException::Io, msg, _FILEINFO_);
564 bool dataAlreadyOnDisk = m_storesDnData ? false :
true;
566 if (m_format == Bsq) {
567 m_ioHandler =
new CubeBsqHandler(dataFile(), m_virtualBandList, realDataFileLabel(),
571 m_ioHandler =
new CubeTileHandler(dataFile(), m_virtualBandList, realDataFileLabel(),
576 m_ioHandler->updateLabels(*m_label);
615 create(cubeFileName);
627 void Cube::open(
const QString &cubeFileName, QString access) {
631 string msg =
"You already have a cube opened";
632 throw IException(IException::Programmer, msg, _FILEINFO_);
635 initLabelFromFile(cubeFileName, (access ==
"rw"));
645 m_dataFileName =
new FileName(m_labelFileName->path() +
"/" + temp.
original());
648 m_dataFileName =
new FileName(temp);
652 m_storesDnData =
true;
654 m_dataFile =
new QFile(realDataFileName().expanded());
658 FileName dataFileName(core[
"^DnFile"][0]);
661 m_dataFileName =
new FileName(m_labelFileName->path() +
"/" + dataFileName.
name());
664 m_dataFileName =
new FileName(dataFileName);
668 m_storesDnData =
false;
669 *m_dataFileName =
FileName(realDataFileName().expanded());
670 m_dataFile =
new QFile(realDataFileName().expanded());
674 m_dataFileName =
new FileName(*m_labelFileName);
676 m_storesDnData =
true;
685 if (!m_labelFile->open(QIODevice::ReadOnly)) {
686 QString msg =
"Failed to open [" + m_labelFile->fileName() +
"] with "
689 throw IException(IException::Io, msg, _FILEINFO_);
693 if (!m_dataFile->open(QIODevice::ReadOnly)) {
694 QString msg =
"Failed to open [" + m_dataFile->fileName() +
"] with "
697 throw IException(IException::Io, msg, _FILEINFO_);
702 else if (access ==
"rw") {
703 if (!m_labelFile->open(QIODevice::ReadWrite)) {
704 QString msg =
"Failed to open [" + m_labelFile->fileName() +
"] with "
707 throw IException(IException::Io, msg, _FILEINFO_);
711 if (m_storesDnData && !m_dataFile->open(QIODevice::ReadWrite)) {
712 QString msg =
"Failed to open [" + m_dataFile->fileName() +
"] with "
715 throw IException(IException::Io, msg, _FILEINFO_);
717 else if (!m_storesDnData && !m_dataFile->open(QIODevice::ReadOnly)) {
718 QString msg =
"Failed to open [" + m_dataFile->fileName() +
"] with "
721 throw IException(IException::Io, msg, _FILEINFO_);
726 QString msg =
"Unknown value for access [" + access +
"]. Expected 'r' "
729 throw IException(IException::Programmer, msg, _FILEINFO_);
732 initCoreFromLabel(*m_label);
736 m_labelBytes = m_label->findObject(
"Label")[
"Bytes"];
739 m_labelBytes = labelSize(
true);
743 if (!m_storesDnData) {
744 dataLabel = qMakePair(
true,
new Pvl(m_dataFileName->expanded()));
748 if (m_format == Bsq) {
750 realDataFileLabel(),
true);
754 realDataFileLabel(),
true);
757 if (dataLabel.first) {
758 delete dataLabel.second;
759 dataLabel.second = NULL;
762 applyVirtualBandsToLabel();
774 void Cube::reopen(QString access) {
776 QString msg =
"Cube has not been opened yet. The filename to re-open is "
778 throw IException(IException::Programmer, msg, _FILEINFO_);
782 FileName filename = *m_labelFileName;
785 if (m_virtualBandList)
786 virtualBandList = *m_virtualBandList;
791 if (virtualBandList.size()) {
792 if (m_virtualBandList)
793 *m_virtualBandList = virtualBandList;
795 m_virtualBandList =
new QList<int>(virtualBandList);
807 void Cube::read(
Blob &blob,
const std::vector<PvlKeyword> keywords)
const {
809 string msg =
"The cube is not opened so you can't read a blob from it";
810 throw IException(IException::Programmer, msg, _FILEINFO_);
813 FileName cubeFile = *m_labelFileName;
815 cubeFile = *m_tempCube;
817 QMutexLocker locker(m_mutex);
818 QMutexLocker locker2(m_ioHandler->dataFileMutex());
829 void Cube::read(
Buffer &bufferToFill)
const {
831 string msg =
"Try opening a file before you read it";
832 throw IException(IException::Programmer, msg, _FILEINFO_);
835 QMutexLocker locker(m_mutex);
836 m_ioHandler->read(bufferToFill);
847 History Cube::readHistory(
const QString &name)
const {
848 Blob historyBlob(name,
"History");
867 Blob footprintBlob(
"Footprint",
"Polygon");
873 QString msg =
"Footprintinit must be run prior to reading the footprint";
874 msg +=
" with POLYGON=TRUE for cube [" + fileName() +
"]";
875 throw IException(e, IException::User, msg, _FILEINFO_);
890 Blob origLabelBlob(name,
"OriginalLabel");
895 QString msg =
"Unable to locate OriginalLabel in " + fileName();
896 throw IException(e, IException::User, msg, _FILEINFO_);
912 CubeStretch Cube::readCubeStretch(QString name,
const std::vector<PvlKeyword> keywords)
const {
913 Blob stretchBlob(name,
"Stretch");
915 read(stretchBlob, keywords);
918 QString msg =
"Unable to locate Stretch information in " + fileName();
919 throw IException(e, IException::User, msg, _FILEINFO_);
932 Blob origXmlLabelBlob(
"IsisCube",
"OriginalXmlLabel");
934 read(origXmlLabelBlob);
937 QString msg =
"Unable to locate OriginalXmlLabel in " + fileName();
938 throw IException(e, IException::User, msg, _FILEINFO_);
952 Table Cube::readTable(
const QString &name) {
953 Blob tableBlob(name,
"Table");
958 QString msg =
"Failed to read table [" + name +
"] from cube [" + fileName() +
"].";
959 throw IException(e, IException::Programmer, msg, _FILEINFO_);
961 return Table(tableBlob);
971 void Cube::write(
Blob &blob,
bool overwrite) {
973 string msg =
"The cube is not opened so you can't write a blob to it";
974 throw IException(IException::Programmer, msg, _FILEINFO_);
977 if (!m_labelFile->isWritable()) {
978 string msg =
"The cube must be opened in read/write mode, not readOnly";
979 throw IException(IException::Programmer, msg, _FILEINFO_);
984 QMutexLocker locker(m_mutex);
985 QMutexLocker locker2(m_ioHandler->dataFileMutex());
989 fstream stream(m_labelFileName->expanded().toLatin1().data(),
990 ios::in | ios::out | ios::binary);
991 stream.seekp(0, ios::end);
994 streampos endByte = stream.tellp();
996 streampos maxbyte = (streampos) m_labelBytes;
998 if (m_storesDnData) {
999 maxbyte += (streampos) m_ioHandler->getDataSize();
1003 if (endByte < maxbyte) {
1004 stream.seekp(maxbyte, ios::beg);
1008 blob.
Write(*m_label, stream,
"", overwrite);
1013 FileName blobFileName = fileName();
1017 QString blobFile(blobFileName.
expanded());
1018 ios::openmode flags = ios::in | ios::binary | ios::out | ios::trunc;
1019 fstream detachedStream;
1020 detachedStream.open(blobFile.toLatin1().data(), flags);
1021 if (!detachedStream) {
1022 QString message =
"Unable to open data file [" +
1024 throw IException(IException::Io, message, _FILEINFO_);
1027 blob.
Write(*m_label, detachedStream, blobFileName.
name());
1080 write(cubeStretchBlob);
1094 void Cube::write(
History &history,
const QString &name) {
1120 string msg =
"Tried to write to a cube before opening/creating it";
1121 throw IException(IException::Programmer, msg, _FILEINFO_);
1125 QString msg =
"Cannot write to the cube [" + (QString)QFileInfo(fileName()).fileName() +
1126 "] because it is opened read-only";
1127 throw IException(IException::Programmer, msg, _FILEINFO_);
1130 if (!m_storesDnData) {
1131 QString msg =
"The cube [" + QFileInfo(fileName()).fileName() +
1132 "] does not support storing DN data because it is using an external file for DNs";
1133 throw IException(IException::Unknown, msg, _FILEINFO_);
1136 QMutexLocker locker(m_mutex);
1137 m_ioHandler->write(bufferToWrite);
1151 void Cube::setBaseMultiplier(
double base,
double mult) {
1154 m_multiplier = mult;
1168 void Cube::setMinMax(
double min,
double max) {
1175 if (m_pixelType == UnsignedByte) {
1178 m_multiplier = (max - min) / (x2 - x1);
1179 m_base = min - m_multiplier * x1;
1181 else if (m_pixelType == SignedWord) {
1184 m_multiplier = (max - min) / (x2 - x1);
1185 m_base = min - m_multiplier * x1;
1187 else if (m_pixelType == UnsignedWord) {
1190 m_multiplier = (max - min) / (x2 - x1);
1191 m_base = min - m_multiplier * x1;
1204 m_byteOrder = byteOrder;
1217 void Cube::setDimensions(
int ns,
int nl,
int nb) {
1219 if ((ns < 1) || (nl < 1) || (nb < 1)) {
1220 string msg =
"SetDimensions: Invalid number of sample, lines or bands";
1221 throw IException(IException::Programmer, msg, _FILEINFO_);
1234 void Cube::setExternalDnData(
FileName cubeFileWithDnData) {
1236 initLabelFromFile(cubeFileWithDnData,
false);
1237 initCoreFromLabel(*m_label);
1248 m_storesDnData =
false;
1249 m_dataFileName =
new FileName(cubeFileWithDnData);
1254 delete m_labelFileName;
1255 m_labelFileName = NULL;
1278 void Cube::setLabelsAttached(
bool attach) {
1280 m_attached = attach;
1291 void Cube::setLabelSize(
int labelBytes) {
1293 m_labelBytes = labelBytes;
1306 m_pixelType = pixelType;
1323 if (m_virtualBandList)
1324 m_virtualBandList->clear();
1328 if (vbands.size() > 0) {
1329 QListIterator<QString> it(vbands);
1330 while (it.hasNext()) {
1331 m_virtualBandList->append(
toInt(it.next()));
1335 delete m_virtualBandList;
1336 m_virtualBandList = NULL;
1340 m_ioHandler->setVirtualBands(m_virtualBandList);
1351 void Cube::setVirtualBands(
const std::vector<QString> &vbands) {
1354 for(
unsigned int i = 0; i < vbands.size(); i++)
1355 realVBands << vbands[i];
1357 setVirtualBands(realVBands);
1369 QString(
"Cannot relocate the DN data to [%1] for an external cube label "
1370 "file which is not open.")
1376 if (m_storesDnData) {
1378 QString(
"The cube [%1] stores DN data. It cannot be relocated to [%2] - "
1379 "this is only supported for external cube label files.")
1380 .arg(m_labelFileName->original()).arg(dnDataFile.
original()),
1384 m_label->findObject(
"IsisCube").findObject(
"Core").findKeyword(
"^DnFile")[0] =
1386 reopen(m_labelFile->isWritable()?
"rw" :
"r");
1410 int Cube::bandCount()
const {
1411 int numBands = m_bands;
1412 if (m_virtualBandList)
1413 numBands = m_virtualBandList->size();
1427 double Cube::base()
const {
1452 if (m_camera == NULL && isOpen()) {
1453 m_camera = CameraFactory::Create(*
this);
1459 void Cube::attachSpiceFromIsd(nlohmann::json isd) {
1461 PvlKeyword pckKeyword(
"TargetAttitudeShape");
1462 PvlKeyword targetSpkKeyword(
"TargetPosition");
1471 Spice spice(*this->label(), isd);
1472 Table ckTable = spice.instrumentRotation()->Cache(
"InstrumentPointing");
1475 for (
int i = 0; i < ckKeyword.size(); i++)
1476 ckTable.
Label()[
"Kernels"].addValue(ckKeyword[i]);
1478 this->write(ckTable);
1480 Table spkTable = spice.instrumentPosition()->Cache(
"InstrumentPosition");
1482 for (
int i = 0; i < spkKeyword.size(); i++)
1483 spkTable.
Label()[
"Kernels"].addValue(spkKeyword[i]);
1485 this->write(spkTable);
1487 Table bodyTable = spice.bodyRotation()->Cache(
"BodyRotation");
1489 for (
int i = 0; i < targetSpkKeyword.size(); i++)
1490 bodyTable.
Label()[
"Kernels"].addValue(targetSpkKeyword[i]);
1492 for (
int i = 0; i < pckKeyword.size(); i++)
1493 bodyTable.
Label()[
"Kernels"].addValue(pckKeyword[i]);
1496 toString(spice.solarLongitude().degrees()));
1497 this->write(bodyTable);
1499 Table sunTable = spice.sunPosition()->Cache(
"SunPosition");
1501 for (
int i = 0; i < targetSpkKeyword.size(); i++)
1502 sunTable.
Label()[
"Kernels"].addValue(targetSpkKeyword[i]);
1504 this->write(sunTable);
1506 PvlGroup currentKernels = this->group(
"Kernels");
1508 Pvl *label = this->label();
1510 while (i < label->objects()) {
1512 if (currObj.
isNamed(
"NaifKeywords")) {
1520 *(this->label()) += spice.getStoredNaifKeywords();
1538 "An external cube label file must be opened in order to use "
1539 "Cube::getExternalCubeFileName",
1543 if (storesDnData()) {
1545 "Cube::getExternalCubeFileName can only be called on an external cube label "
1553 return core[
"^DnFile"][0];
1563 QString Cube::fileName()
const {
1565 return m_labelFileName->expanded();
1629 Histogram *Cube::histogram(
const int &band,
const double &validMin,
1630 const double &validMax, QString msg) {
1633 QString msg =
"Cannot create histogram object for an unopened cube";
1634 throw IException(IException::Programmer, msg, _FILEINFO_);
1638 if ((band < 0) || (band > bandCount())) {
1639 QString msg =
"Invalid band in [CubeInfo::Histogram]";
1640 throw IException(IException::Programmer, msg, _FILEINFO_);
1643 int bandStart = band;
1644 int bandStop = band;
1645 int maxSteps = lineCount();
1648 bandStop = bandCount();
1649 maxSteps = lineCount() * bandCount();
1661 double binMin = validMin;
1662 double binMax = validMax;
1664 binMin = hist->BinRangeStart();
1668 binMax = hist->BinRangeEnd();
1679 for(
int useBand = bandStart ; useBand <= bandStop ; useBand++) {
1680 for(
int i = 1; i <= lineCount(); i++) {
1713 int Cube::labelSize(
bool actual)
const {
1714 int labelSize = m_labelBytes;
1716 if (actual && m_label) {
1718 s << *m_label << endl;
1719 labelSize = s.tellp();
1734 int Cube::lineCount()
const {
1748 double Cube::multiplier()
const {
1749 return m_multiplier;
1773 int Cube::physicalBand(
const int &virtualBand)
const {
1774 int physicalBand = virtualBand;
1776 if (m_virtualBandList) {
1777 if ((virtualBand < 1) ||
1778 (virtualBand > m_virtualBandList->size())) {
1779 QString msg =
"Out of array bounds [" +
toString(virtualBand) +
"]";
1780 throw IException(IException::Programmer, msg, _FILEINFO_);
1782 physicalBand = m_virtualBandList->at(virtualBand - 1);
1785 return physicalBand;
1795 if (m_projection == NULL && isOpen()) {
1796 m_projection = ProjectionFactory::CreateFromCube(*label());
1798 return m_projection;
1807 int Cube::sampleCount()
const {
1851 Statistics *Cube::statistics(
const int &band,
const double &validMin,
1852 const double &validMax, QString msg) {
1855 QString msg =
"Cannot create statistics object for an unopened cube";
1856 throw IException(IException::Programmer, msg, _FILEINFO_);
1860 if ((band < 0) || (band > bandCount())) {
1861 string msg =
"Invalid band in [CubeInfo::Statistics]";
1862 throw IException(IException::Programmer, msg, _FILEINFO_);
1869 stats->SetValidRange(validMin, validMax);
1871 int bandStart = band;
1872 int bandStop = band;
1873 int maxSteps = lineCount();
1876 bandStop = bandCount();
1877 maxSteps = lineCount() * bandCount();
1886 for(
int useBand = bandStart ; useBand <= bandStop ; useBand++) {
1887 for(
int i = 1; i <= lineCount(); i++) {
1904 bool Cube::storesDnData()
const {
1905 return m_storesDnData;
1924 if (isOpen() && m_ioHandler) {
1925 m_ioHandler->addCachingAlgorithm(algorithm);
1927 else if (!isOpen()) {
1928 QString msg =
"Cannot add a caching algorithm until the cube is open";
1929 throw IException(IException::Programmer, msg, _FILEINFO_);
1938 void Cube::clearIoCache() {
1940 QMutexLocker locker(m_mutex);
1941 m_ioHandler->clearCache();
1955 bool Cube::deleteBlob(QString BlobName, QString BlobType) {
1956 for(
int i = 0; i < m_label->objects(); i++) {
1958 if (obj.
name().compare(BlobType) == 0) {
1977 void Cube::deleteGroup(
const QString &group) {
1979 if (!isiscube.
hasGroup(group))
return;
2004 bool Cube::hasGroup(
const QString &group)
const {
2006 if (isiscube.
hasGroup(group))
return true;
2019 bool Cube::hasBlob(
const QString &name,
const QString &type) {
2020 for(
int o = 0; o < label()->
objects(); o++) {
2024 QString temp = (QString) obj[
"Name"];
2025 temp = temp.toUpper();
2026 QString temp2 = name;
2027 temp2 = temp2.toUpper();
2028 if (temp == temp2)
return true;
2043 bool Cube::hasTable(
const QString &name) {
2044 return hasBlob(name,
"Table");
2058 QString msg =
"Cannot add a group to the label of cube [" + (QString)QFileInfo(fileName()).fileName() +
2059 "] because it is opened read-only";
2060 throw IException(IException::Programmer, msg, _FILEINFO_);
2078 void Cube::applyVirtualBandsToLabel() {
2082 if (m_label->findObject(
"IsisCube").hasGroup(
"BandBin")) {
2083 PvlGroup &bandBin = m_label->findObject(
"IsisCube").findGroup(
"BandBin");
2084 for (
int k = 0;k < bandBin.
keywords();k++) {
2085 if (bandBin[k].size() == m_bands && m_virtualBandList) {
2088 for (
int i = 0;i < m_virtualBandList->size();i++) {
2089 int physicalBand = m_virtualBandList->at(i) - 1;
2090 bandBin[k].addValue(temp[physicalBand], temp.
unit(physicalBand));
2097 if (m_virtualBandList && core.
hasGroup(
"Dimensions")) core.
findGroup(
"Dimensions")[
"Bands"] =
toString(m_virtualBandList->size());
2106 void Cube::cleanUp(
bool removeIt) {
2114 QFile::remove(m_tempCube->expanded());
2122 QFile::remove(m_labelFileName->expanded());
2124 if (*m_labelFileName != *m_dataFileName)
2125 QFile::remove(m_dataFileName->expanded());
2134 delete m_labelFileName;
2135 m_labelFileName = NULL;
2137 delete m_dataFileName;
2138 m_dataFileName = NULL;
2143 delete m_virtualBandList;
2144 m_virtualBandList = NULL;
2154 void Cube::construct() {
2161 m_projection = NULL;
2163 m_labelFileName = NULL;
2164 m_dataFileName = NULL;
2166 m_formatTemplateFile = NULL;
2169 m_virtualBandList = NULL;
2171 m_mutex =
new QMutex();
2172 m_formatTemplateFile =
2173 new FileName(
"$ISISROOT/appdata/templates/labels/CubeFormatTemplate.pft");
2185 QFile *Cube::dataFile()
const {
2204 if (m_attached && m_storesDnData) {
2205 ASSERT(m_labelFileName);
2206 result = *m_labelFileName;
2209 else if (!m_attached && m_storesDnData) {
2210 ASSERT(m_dataFileName);
2211 result = *m_dataFileName;
2214 else if (!m_storesDnData) {
2215 ASSERT(m_dataFileName);
2222 if (dir.isRelative() && m_labelFileName) {
2223 QDir dir2(m_labelFileName->originalPath());
2224 dir2.cd(guess.
path());
2225 guess = dir2.absolutePath() +
"/" + guess.
name();
2234 guess = core[
"^DnFile"][0];
2236 if (!guess.
path().startsWith(
"/")) {
2241 result = core[
"^Core"][0];
2247 while (result.
name() ==
"");
2265 void Cube::initialize() {
2273 m_storesDnData =
true;
2274 m_labelBytes = 65536;
2290 void Cube::initCoreFromLabel(
const Pvl &label) {
2296 m_samples = dims[
"Samples"];
2297 m_lines = dims[
"Lines"];
2298 m_bands = dims[
"Bands"];
2302 m_byteOrder = ByteOrderEnumeration(pixelsGroup[
"ByteOrder"]);
2303 m_base = pixelsGroup[
"Base"];
2304 m_multiplier = pixelsGroup[
"Multiplier"];
2308 if ((QString) core[
"Format"] ==
"BandSequential") {
2317 if (!temp.
expanded().startsWith(
"/")) {
2334 void Cube::initLabelFromFile(
FileName labelFileName,
bool readWrite) {
2335 ASSERT(!m_labelFileName);
2340 if (!m_label->objects()) {
2358 if (!m_label->objects()) {
2361 labelFileName = tmp;
2378 if (!m_label->objects()) {
2381 labelFileName = tmp;
2398 if (!m_label->objects()) {
2401 labelFileName = tmp;
2413 QString msg = Message::FileOpen(labelFileName.
original());
2414 throw IException(IException::Io, msg, _FILEINFO_);
2417 m_labelFileName =
new FileName(labelFileName);
2421 if (m_label->hasKeyword(
"CCSD3ZF0000100000001NJPL3IF0PDS200000001")) {
2423 reformatOldIsisLabel(m_labelFileName->expanded());
2426 QString msg =
"Can not open [" + m_labelFileName->original() +
"]"
2427 " because it is an ISIS2 cube.";
2429 throw IException(IException::Io, msg, _FILEINFO_);
2433 m_labelFile =
new QFile(m_labelFileName->expanded());
2441 void Cube::openCheck() {
2443 string msg =
"Sorry you can't do a SetMethod after the cube is opened";
2444 throw IException(IException::Programmer, msg, _FILEINFO_);
2454 Pvl Cube::realDataFileLabel()
const {
2455 Pvl label = *m_label;
2459 core = &label.
findObject(
"IsisCube").findObject(
"Core");
2463 FileName temp((*core)[
"^DnFile"][0]);
2464 if (!temp.
expanded().startsWith(
"/")) {
2465 temp = realDataFileName();
2484 void Cube::reformatOldIsisLabel(
const QString &oldCube) {
2485 QString parameters =
"from=" + oldCube;
2487 FileName tempCube = FileName::createTempFile(
"Temporary_" + oldName.
name() +
".cub");
2488 parameters +=
" to=" + tempCube.
expanded();
2491 QString command =
"$ISISROOT/bin/pds2isis " + parameters;
2492 ProgramLauncher::RunSystemCommand(command);
2495 QString prog =
"pds2isis";
2496 ProgramLauncher::RunIsisProgram(prog, parameters);
2499 m_tempCube =
new FileName(tempCube);
2500 *m_label =
Pvl(m_tempCube->toString());
2501 m_labelFile =
new QFile(m_tempCube->expanded());
2514 void Cube::latLonRange(
double &minLatitude,
double &maxLatitude,
double &minLongitude,
double &
2519 bool isGood =
false;
2520 bool useProj =
true;
2522 if (hasGroup(
"Instrument")) {
2532 QString msg =
"Cannot calculate lat/lon range without a camera or projection";
2533 throw IException(e, IException::User, msg, _FILEINFO_);
2541 QString msg =
"Unable to create camera when calculating a lat/lon range.";
2542 throw IException(e, IException::User, msg, _FILEINFO_);
2547 minLatitude = 99999;
2548 minLongitude = 99999;
2549 maxLatitude = -99999;
2550 maxLongitude = -99999;
2552 for (
double sample = 0.5; sample < sampleCount() + 0.5; sample++) {
2554 for (
double line = 0.5; line < lineCount() + 0.5; line++) {
2556 isGood = proj->
SetWorld(sample, line);
2559 isGood = cam->
SetImage(sample, line);
2574 if (lat < minLatitude) {
2577 else if (lat > maxLatitude) {
2581 if (lon < minLongitude) {
2584 else if (lon > maxLongitude) {
2590 if ( (minLatitude == 99999) || (minLongitude == 99999) || (maxLatitude == -99999) ||
2591 (maxLongitude == -99999) ) {
2592 QString msg =
"Unable to calculate a minimum or maximum latitutde or longitude.";
2593 throw IException(IException::Unknown, msg, _FILEINFO_);
2601 void Cube::writeLabels() {
2603 string msg =
"Cube must be opened first before writing labels";
2604 throw IException(IException::Programmer, msg, _FILEINFO_);
2608 m_label->setFormatTemplate(m_formatTemplateFile->original());
2612 QMutexLocker locker(m_mutex);
2613 QMutexLocker locker2(m_ioHandler->dataFileMutex());
2616 temp << *m_label << endl;
2617 string tempstr = temp.str();
2618 if ((
int) tempstr.length() < m_labelBytes) {
2619 QByteArray labelArea(m_labelBytes,
'\0');
2620 QByteArray labelUnpaddedContents(tempstr.c_str(), tempstr.length());
2621 labelArea.replace(0, labelUnpaddedContents.size(), labelUnpaddedContents);
2623 m_labelFile->seek(0);
2624 m_labelFile->write(labelArea);
2628 QString msg =
"Label space is full in [" +
2630 "] unable to write labels";
2632 throw IException(IException::Io, msg, _FILEINFO_);
2638 m_label->write(m_labelFileName->expanded());