Isis 3 Programmer Reference
Cube.cpp
1
6/* SPDX-License-Identifier: CC0-1.0 */
7#include "Cube.h"
8
9#include <sstream>
10#include <unistd.h>
11
12#include <QDebug>
13#include <QDir>
14#include <QFile>
15#include <QFileInfo>
16#include <QMutex>
17
18#include "Application.h"
19#include "Blob.h"
20#include "Camera.h"
21#include "CameraFactory.h"
22#include "CubeAttribute.h"
23#include "CubeBsqHandler.h"
24#include "CubeTileHandler.h"
25#include "CubeStretch.h"
26#include "Endian.h"
27#include "FileName.h"
28#include "History.h"
29#include "ImageHistogram.h"
30#include "ImagePolygon.h"
31#include "IException.h"
32#include "LineManager.h"
33#include "Message.h"
34#include "OriginalLabel.h"
35#include "OriginalXmlLabel.h"
36#include "Preference.h"
37#include "ProgramLauncher.h"
38#include "Projection.h"
39#include "SpecialPixel.h"
40#include "Statistics.h"
41#include "Table.h"
42#include "TProjection.h"
43#include "Longitude.h"
44
45using namespace std;
46
47namespace Isis {
50 construct();
51 }
52
61 Cube::Cube(const FileName &fileName, QString access) {
62 construct();
63 open(fileName.toString(), access);
64 }
65
75 void Cube::fromLabel(const FileName &fileName, Pvl &label, QString access) {
77 create(fileName.expanded());
78
79 PvlObject cubeLabel = label.findObject("IsisCube");
80 for (auto grpIt = cubeLabel.beginGroup(); grpIt!= cubeLabel.endGroup(); grpIt++) {
81 putGroup(*grpIt);
82 }
83
84 close();
85 open(fileName.toString(), access);
86 }
87
98 void Cube::fromIsd(const FileName &fileName, Pvl &label, nlohmann::json &isd, QString access) {
99 fromLabel(fileName, label, access);
100 attachSpiceFromIsd(isd);
101
102 close();
103 open(fileName.toString(), access);
104 }
105
116 void Cube::fromIsd(const FileName &fileName, FileName &labelFile, FileName &isdFile, QString access) {
117 std::ifstream isdStream(isdFile.expanded().toStdString());
118 std::ifstream labelStream(labelFile.expanded().toStdString());
119
120 if (isdStream.fail()) {
121 QString msg = QString("failed to open isd stream: %1").arg(isdFile.expanded());
122 throw IException(IException::Io, msg,
123 isdFile.baseName().toStdString().c_str(), 153);
124 }
125
126 if (labelStream.fail()) {
127 QString msg = "failed to open file stream";
128 throw IException(IException::Io, msg,
129 fileName.baseName().toStdString().c_str(), 153);
130 }
131
132 Pvl label;
133 nlohmann::json isd;
134
135 try {
136 labelStream >> label;
137 }
138 catch (std::exception &ex) {
139 QString msg = QString("Failed to open label file, %1, %2").arg(labelFile.expanded()).arg(ex.what());
140 throw IException(IException::Io, msg,
141 fileName.baseName().toStdString().c_str(), 153);
142 }
143
144
145 try {
146 isdStream >> isd;
147 }
148 catch (std::exception &ex) {
149 QString msg = QString("Failed to open ISD file, %1, %2").arg(isdFile.expanded()).arg(ex.what());
150 throw IException(IException::Io, msg,
151 fileName.baseName().toStdString().c_str(), 145);
152 }
153
154 fromIsd(fileName, label, isd, access);
155 reopen("rw");
156 }
157
160 close();
161
162 delete m_mutex;
163 m_mutex = NULL;
164
165 delete m_camera;
166 m_camera = NULL;
167
168
169 delete m_projection;
170 m_projection = NULL;
171
174 }
175
176
182 bool Cube::isOpen() const {
183 bool open = (m_ioHandler != NULL);
184
185 return open;
186 }
187
188
197 bool Cube::isProjected() const {
198 return label()->findObject("IsisCube").hasGroup("Mapping");
199 }
200
201
208 bool Cube::isReadOnly() const {
209 bool readOnly = false;
210
211 if (!isOpen()) {
212 QString msg = "No cube opened";
213 throw IException(IException::Programmer, msg, _FILEINFO_);
214 }
215
216 if ((m_labelFile->openMode() & QIODevice::ReadWrite) != QIODevice::ReadWrite)
217 readOnly = true;
218
219 return readOnly;
220 }
221
222
230 bool Cube::isReadWrite() const {
231 return !isReadOnly();
232 }
233
234
243 bool Cube::labelsAttached() const {
244 return m_attached;
245 }
246
247
255 void Cube::close(bool removeIt) {
256 if (isOpen() && isReadWrite())
257 writeLabels();
258
259 cleanUp(removeIt);
260 }
261
262
271 Cube *Cube::copy(FileName newFile, const CubeAttributeOutput &newFileAttributes) {
272 if (!isOpen()) {
274 QObject::tr("Cube::copy requires the originating cube to be open"),
275 _FILEINFO_);
276 }
277
278
279 Cube *result = new Cube;
280
281 if (newFileAttributes.labelAttachment() != ExternalLabel) {
283 result->setByteOrder(newFileAttributes.byteOrder());
284 result->setFormat(newFileAttributes.fileFormat());
285
286 if (newFileAttributes.labelAttachment() == DetachedLabel) {
287 result->setLabelsAttached(false);
288 }
289
290 if (newFileAttributes.propagatePixelType()) {
291 result->setPixelType(pixelType());
292 }
293 else {
294 result->setPixelType(newFileAttributes.pixelType());
295 }
296
297 if (newFileAttributes.propagateMinimumMaximum()) {
298 if(result->pixelType() == Isis::Real) {
299 result->setBaseMultiplier(0.0, 1.0);
300 }
301 else if(result->pixelType() >= pixelType()) {
302 result->setBaseMultiplier(base(), multiplier());
303 }
304 else {
305 QString msg =
306 QObject::tr("Cannot reduce the output PixelType for [%1] from [%2] without output "
307 "pixel range").arg(newFile.original()).arg(fileName());
308 throw IException(IException::User, msg, _FILEINFO_);
309 }
310 }
311 else {
312 // Not propagating so either the user entered or the programmer did
313 result->setMinMax(newFileAttributes.minimum(), newFileAttributes.maximum());
314 }
315
316 result->setLabelSize(labelSize(true) + (1024 * 6));
317 }
318 else {
319 if (isReadWrite()) {
320 writeLabels();
321 m_ioHandler->clearCache(true);
322 }
323
324 result->setExternalDnData(fileName());
325 }
326
327 // Allocate the cube
328 result->create(newFile.expanded());
329
330 PvlObject &isisCube = label()->findObject("IsisCube");
331 PvlObject &outIsisCube = result->label()->findObject("IsisCube");
332 for(int i = 0; i < isisCube.groups(); i++) {
333 outIsisCube.addGroup(isisCube.group(i));
334 }
335
336 if (label()->hasObject("NaifKeywords")) {
337 result->label()->addObject(
338 label()->findObject("NaifKeywords"));
339 }
340
341 for (int i = 0; i < m_label->objects(); i++) {
342 PvlObject &obj = m_label->object(i);
343 if (obj.isNamed("Table") || obj.isNamed("Polygon") || obj.isNamed("OriginalLabel") ||
344 obj.isNamed("History")) {
345 Isis::Blob t((QString)obj["Name"], obj.name());
346 read(t);
347 result->write(t);
348 }
349 }
350
351 if (newFileAttributes.labelAttachment() != ExternalLabel) {
353 sampleCount(), 1, 1,
354 pixelType());
356 sampleCount(), 1, 1,
357 result->pixelType());
358
359 input.begin();
360 output.begin();
361
362 while (!input.end()) {
363 read(input);
364 output.Copy(input, false);
365
366 result->write(output);
367
368 input.next();
369 output.next();
370 }
371 }
372
373// Just in case the orig label doesn't work... here's original code:
374// if((p_propagateOriginalLabel) && (InputCubes.size() > 0)) {
375// Isis::Pvl &inlab = *InputCubes[0]->label();
376// for(int i = 0; i < inlab.objects(); i++) {
377// if(inlab.Object(i).isNamed("OriginalLabel")) {
378// Isis::OriginalLabel ol;
379// InputCubes[0]->read(ol);
380// cube->write(ol);
381// }
382// }
383// }
384
385 return result;
386 }
387
388
409 void Cube::create(const QString &cubeFileName) {
410 // Already opened?
411 if (isOpen()) {
412 string msg = "You already have a cube opened";
413 throw IException(IException::Programmer, msg, _FILEINFO_);
414 }
415
416 if (m_samples < 1 || m_lines < 1 || m_bands < 1) {
417 QString msg = "Number of samples [" + toString(m_samples) +
418 "], lines [" + toString(m_lines) + "], or bands [" + toString(m_bands) +
419 "] cannot be less than 1";
420 throw IException(IException::Programmer, msg, _FILEINFO_);
421 }
422
423 if (m_pixelType == None) {
425 QString("Cannot create the cube [%1] with a pixel type set to None")
426 .arg(cubeFileName),
427 _FILEINFO_);
428 }
429
430 if (m_storesDnData) {
431 // Make sure the cube is not going to exceed the maximum size preference
432 BigInt size = (BigInt)m_samples * m_lines *
434
435 size = size / 1024; // kb
436 size = size / 1024; // mb
437 size = size / 1024; // gb
438
439 int maxSizePreference = 0;
440
441 maxSizePreference =
442 Preference::Preferences().findGroup("CubeCustomization")["MaximumSize"];
443
444 if (size > maxSizePreference) {
445 QString msg;
446 msg += "The cube you are attempting to create [" + cubeFileName + "] is ["
447 + toString(size) + "GB]. This is larger than the current allowed "
448 "size of [" + toString(maxSizePreference) + "GB]. The cube "
449 "dimensions were (S,L,B) [" + toString(m_samples) + ", " +
450 toString(m_lines) + ", " + toString(m_bands) + "] with [" +
451 toString(SizeOf(m_pixelType)) + "] bytes per pixel. If you still "
452 "wish to create this cube, the maximum value can be changed in your personal "
453 "preference file located in [~/.Isis/IsisPreferences] within the group "
454 "CubeCustomization, keyword MaximumSize. If you do not have an ISISPreference file, "
455 "please refer to the documentation 'Environment and Preference Setup'. Error ";
456 throw IException(IException::User, msg, _FILEINFO_);
457 }
458 }
459
460 // Expand output name
461 FileName cubFile(cubeFileName);
462 PvlObject isiscube("IsisCube");
463 PvlObject core("Core");
464
465 if (m_storesDnData) {
466 cubFile = cubFile.addExtension("cub");
467
468 // See if we have attached or detached labels
469 if (m_attached) {
470 // StartByte is 1-based (why!!) so we need to do + 1
471 core += PvlKeyword("StartByte", toString(m_labelBytes + 1));
472 m_labelFileName = new FileName(cubFile);
473 m_dataFileName = new FileName(cubFile);
474 m_labelFile = new QFile(m_labelFileName->expanded());
475 }
476 else {
477 core += PvlKeyword("StartByte", toString(1));
478 core += PvlKeyword("^Core", cubFile.name());
479 m_dataFileName = new FileName(cubFile);
480 m_dataFile = new QFile(realDataFileName().expanded());
481
482 FileName labelFileName(cubFile);
483 labelFileName = labelFileName.setExtension("lbl");
484 m_labelFileName = new FileName(labelFileName);
485 m_labelFile = new QFile(m_labelFileName->expanded());
486 }
487
488 // Create the size of the core
489 PvlGroup dims("Dimensions");
490 dims += PvlKeyword("Samples", toString(m_samples));
491 dims += PvlKeyword("Lines", toString(m_lines));
492 dims += PvlKeyword("Bands", toString(m_bands));
493 core.addGroup(dims);
494
495 // Create the pixel type
496 PvlGroup ptype("Pixels");
497 ptype += PvlKeyword("Type", PixelTypeName(m_pixelType));
498
499 // And the byte ordering
500 ptype += PvlKeyword("ByteOrder", ByteOrderName(m_byteOrder));
501 ptype += PvlKeyword("Base", toString(m_base));
502 ptype += PvlKeyword("Multiplier", toString(m_multiplier));
503 core.addGroup(ptype);
504 }
505 else {
506 cubFile = cubFile.addExtension("ecub");
507
508 core += PvlKeyword("^DnFile", m_dataFileName->original());
509// m_dataFileName = new FileName(cubFile);
510 m_dataFile = new QFile(realDataFileName().expanded());
511
512 m_labelFileName = new FileName(cubFile);
513 m_labelFile = new QFile(cubFile.expanded());
514 }
515
516 isiscube.addObject(core);
517
518 m_label = new Pvl;
519 m_label->addObject(isiscube);
520
521 // Setup storage reserved for the label
522 PvlObject lbl("Label");
523 lbl += PvlKeyword("Bytes", toString(m_labelBytes));
524 m_label->addObject(lbl);
525
526 const PvlGroup &pref =
527 Preference::Preferences().findGroup("CubeCustomization");
528 bool overwrite = pref["Overwrite"][0].toUpper() == "ALLOW";
529 if (!overwrite && m_labelFile->exists() && m_labelFile->size()) {
530 QString msg = "Cube file [" + m_labelFileName->original() + "] exists, " +
531 "user preference does not allow overwrite";
532 throw IException(IException::User, msg, _FILEINFO_);
533 }
534
535 if (!m_labelFile->open(QIODevice::Truncate | QIODevice::ReadWrite)) {
536 QString msg = "Failed to create [" + m_labelFile->fileName() + "]. ";
537 msg += "Verify the output path exists and you have permission to write to the path.";
538 cleanUp(false);
539 throw IException(IException::Io, msg, _FILEINFO_);
540 }
541
542 if (m_dataFile) {
543 if (m_storesDnData && !m_dataFile->open(QIODevice::Truncate | QIODevice::ReadWrite)) {
544 QString msg = "Failed to create [" + m_dataFile->fileName() + "]. ";
545 msg += "Verify the output path exists and you have permission to write to the path.";
546 cleanUp(false);
547 throw IException(IException::Io, msg, _FILEINFO_);
548 }
549 else if (!m_storesDnData && !m_dataFile->open(QIODevice::ReadOnly)) {
550 QString msg = "Failed to open [" + m_dataFile->fileName() + "] for reading. ";
551 msg += "Verify the output path exists and you have permission to read from the path.";
552 cleanUp(false);
553 throw IException(IException::Io, msg, _FILEINFO_);
554 }
555 }
556
557 bool dataAlreadyOnDisk = m_storesDnData ? false : true;
558
559 if (m_format == Bsq) {
561 dataAlreadyOnDisk);
562 }
563 else {
565 dataAlreadyOnDisk);
566 }
567
568 if (m_storesDnData)
570
571 // Write the labels
572 writeLabels();
573 }
574
575
598 const QString &cubeFileName, const CubeAttributeOutput &att) {
599
600 setByteOrder(att.byteOrder());
601 setFormat(att.fileFormat());
602 setLabelsAttached(att.labelAttachment() == AttachedLabel);
603 if (!att.propagatePixelType())
604 setPixelType(att.pixelType());
605 setMinMax(att.minimum(), att.maximum());
606
607 // Allocate the cube
608 create(cubeFileName);
609 }
610
611
622 void Cube::open(const QString &cubeFileName, QString access) {
623
624 // Already opened?
625 if (isOpen()) {
626 string msg = "You already have a cube opened";
627 throw IException(IException::Programmer, msg, _FILEINFO_);
628 }
629
630 initLabelFromFile(cubeFileName, (access == "rw"));
631
632 try {
633 Isis::CubeAttributeInput att(cubeFileName);
634 if(att.bands().size() != 0) {
635 vector<QString> bands = att.bands();
636 setVirtualBands(bands);
637 }
638 } catch(IException& e) {
639 // Either the cube is an output cube that has already been opened or
640 // there is an exception parsing and adding an attribute
641 }
642
643 // Figure out the name of the data file
644 try {
645 PvlObject &core = m_label->findObject("IsisCube").findObject("Core");
646 // Detached labels
647 if (core.hasKeyword("^Core")) {
648 FileName temp(core["^Core"][0]);
649
650 if (!temp.originalPath().startsWith("/")) {
651 m_dataFileName = new FileName(m_labelFileName->path() + "/" + temp.original());
652 }
653 else {
654 m_dataFileName = new FileName(temp);
655 }
656
657 m_attached = false;
658 m_storesDnData = true;
659
660 m_dataFile = new QFile(realDataFileName().expanded());
661 }
662 // External cube files (ecub), ecub contains all labels and SPICE blobs, history
663 else if (core.hasKeyword("^DnFile")) {
664 FileName dataFileName(core["^DnFile"][0]);
665
666 if (dataFileName.originalPath() == ".") {
667 m_dataFileName = new FileName(m_labelFileName->path() + "/" + dataFileName.name());
668 }
669 else {
670 m_dataFileName = new FileName(dataFileName);
671 }
672
673 m_attached = true;
674 m_storesDnData = false;
676 m_dataFile = new QFile(realDataFileName().expanded());
677 }
678 // Typical cube containing labels, SPICE, history and dn data
679 else {
681 m_attached = true;
682 m_storesDnData = true;
683 }
684 }
685 catch (IException &e) {
686 cleanUp(false);
687 throw;
688 }
689
690 if (access == "r") {
691 if (!m_labelFile->open(QIODevice::ReadOnly)) {
692 QString msg = "Failed to open [" + m_labelFile->fileName() + "] with "
693 "read only access";
694 cleanUp(false);
695 throw IException(IException::Io, msg, _FILEINFO_);
696 }
697
698 if (m_dataFile) {
699 if (!m_dataFile->open(QIODevice::ReadOnly)) {
700 QString msg = "Failed to open [" + m_dataFile->fileName() + "] with "
701 "read only access";
702 cleanUp(false);
703 throw IException(IException::Io, msg, _FILEINFO_);
704 }
705 }
706 }
707
708 else if (access == "rw") {
709 if (!m_labelFile->open(QIODevice::ReadWrite)) {
710 QString msg = "Failed to open [" + m_labelFile->fileName() + "] with "
711 "read/write access";
712 cleanUp(false);
713 throw IException(IException::Io, msg, _FILEINFO_);
714 }
715
716 if (m_dataFile) {
717 if (m_storesDnData && !m_dataFile->open(QIODevice::ReadWrite)) {
718 QString msg = "Failed to open [" + m_dataFile->fileName() + "] with "
719 "read/write access";
720 cleanUp(false);
721 throw IException(IException::Io, msg, _FILEINFO_);
722 }
723 else if (!m_storesDnData && !m_dataFile->open(QIODevice::ReadOnly)) {
724 QString msg = "Failed to open [" + m_dataFile->fileName() + "] with "
725 "read access";
726 cleanUp(false);
727 throw IException(IException::Io, msg, _FILEINFO_);
728 }
729 }
730 }
731 else {
732 QString msg = "Unknown value for access [" + access + "]. Expected 'r' "
733 " or 'rw'";
734 cleanUp(false);
735 throw IException(IException::Programmer, msg, _FILEINFO_);
736 }
737
739
740 // Determine the number of bytes in the label
741 if (m_attached) {
742 m_labelBytes = m_label->findObject("Label")["Bytes"];
743 }
744 else {
745 m_labelBytes = labelSize(true);
746 }
747
748 QPair<bool, Pvl *> dataLabel = qMakePair(false, m_label);
749 if (!m_storesDnData) {
750 dataLabel = qMakePair(true, new Pvl(m_dataFileName->expanded()));
751 }
752
753 // Now examine the format to see which type of handler to create
754 if (m_format == Bsq) {
756 realDataFileLabel(), true);
757 }
758 else {
760 realDataFileLabel(), true);
761 }
762
763 if (dataLabel.first) {
764 delete dataLabel.second;
765 dataLabel.second = NULL;
766 }
767
769 }
770
771
780 void Cube::reopen(QString access) {
781 if (!m_labelFile) {
782 QString msg = "Cube has not been opened yet. The filename to re-open is "
783 "unknown";
784 throw IException(IException::Programmer, msg, _FILEINFO_);
785 }
786
787 // Preserve filename and virtual bands when re-opening
788 FileName filename = *m_labelFileName;
789 QList<int> virtualBandList;
790
792 virtualBandList = *m_virtualBandList;
793
794 close();
795 open(filename.expanded(), access);
796
797 if (virtualBandList.size()) {
799 *m_virtualBandList = virtualBandList;
800 else
801 m_virtualBandList = new QList<int>(virtualBandList);
802 }
803 }
804
805
813 void Cube::read(Blob &blob, const std::vector<PvlKeyword> keywords) const {
814 if (!isOpen()) {
815 string msg = "The cube is not opened so you can't read a blob from it";
816 throw IException(IException::Programmer, msg, _FILEINFO_);
817 }
818
819 FileName cubeFile = *m_labelFileName;
820 if (m_tempCube)
821 cubeFile = *m_tempCube;
822
823 QMutexLocker locker(m_mutex);
824 QMutexLocker locker2(m_ioHandler->dataFileMutex());
825 blob.Read(cubeFile.toString(), *label(), keywords);
826 }
827
828
835 void Cube::read(Buffer &bufferToFill) const {
836 if (!isOpen()) {
837 string msg = "Try opening a file before you read it";
838 throw IException(IException::Programmer, msg, _FILEINFO_);
839 }
840
841 QMutexLocker locker(m_mutex);
842 m_ioHandler->read(bufferToFill);
843 }
844
845
853 History Cube::readHistory(const QString &name) const {
854 Blob historyBlob(name, "History");
855 try {
856 // read history from cube, if it exists.
857 read(historyBlob);
858 }
859 catch (IException &) {
860 // if the history does not exist in the cube, this function creates it.
861 }
862 History history(historyBlob);
863 return history;
864 }
865
866
873 Blob footprintBlob("Footprint", "Polygon");
874 try {
875 // read history from cube, if it exists.
876 read(footprintBlob);
877 }
878 catch (IException &e) {
879 QString msg = "Footprintinit must be run prior to reading the footprint";
880 msg += " with POLYGON=TRUE for cube [" + fileName() + "]";
881 throw IException(e, IException::User, msg, _FILEINFO_);
882 }
883 ImagePolygon footprint(footprintBlob);
884 return footprint;
885 }
886
887
895 OriginalLabel Cube::readOriginalLabel(const QString &name) const {
896 Blob origLabelBlob(name, "OriginalLabel");
897 try {
898 read(origLabelBlob);
899 }
900 catch (IException &e){
901 QString msg = "Unable to locate OriginalLabel in " + fileName();
902 throw IException(e, IException::User, msg, _FILEINFO_);
903 }
904 OriginalLabel origLabel(origLabelBlob);
905 return origLabel;
906 }
907
908
918 CubeStretch Cube::readCubeStretch(QString name, const std::vector<PvlKeyword> keywords) const {
919 Blob stretchBlob(name, "Stretch");
920 try {
921 read(stretchBlob, keywords);
922 }
923 catch (IException &e){
924 QString msg = "Unable to locate Stretch information in " + fileName();
925 throw IException(e, IException::User, msg, _FILEINFO_);
926 }
927 CubeStretch cubeStretch(stretchBlob);
928 return stretchBlob;
929 }
930
931
938 Blob origXmlLabelBlob("IsisCube", "OriginalXmlLabel");
939 try {
940 read(origXmlLabelBlob);
941 }
942 catch (IException &e){
943 QString msg = "Unable to locate OriginalXmlLabel in " + fileName();
944 throw IException(e, IException::User, msg, _FILEINFO_);
945 }
946 OriginalXmlLabel origXmlLabel(origXmlLabelBlob);
947 return origXmlLabel;
948 }
949
950
958 Table Cube::readTable(const QString &name) {
959 Blob tableBlob(name, "Table");
960 try {
961 read(tableBlob);
962 }
963 catch (IException &e) {
964 QString msg = "Failed to read table [" + name + "] from cube [" + fileName() + "].";
965 throw IException(e, IException::Programmer, msg, _FILEINFO_);
966 }
967 return Table(tableBlob);
968 }
969
970
977 void Cube::write(Blob &blob, bool overwrite) {
978 if (!isOpen()) {
979 string msg = "The cube is not opened so you can't write a blob to it";
980 throw IException(IException::Programmer, msg, _FILEINFO_);
981 }
982
983 if (!m_labelFile->isWritable()) {
984 string msg = "The cube must be opened in read/write mode, not readOnly";
985 throw IException(IException::Programmer, msg, _FILEINFO_);
986 }
987
988 // Write an attached blob
989 if (m_attached) {
990 QMutexLocker locker(m_mutex);
991 QMutexLocker locker2(m_ioHandler->dataFileMutex());
992
993 // Compute the number of bytes in the cube + label bytes and if the
994 // endpos of the file // is not greater than this then seek to that position.
995 fstream stream(m_labelFileName->expanded().toLatin1().data(),
996 ios::in | ios::out | ios::binary);
997 stream.seekp(0, ios::end);
998
999 // End byte = end byte of the file (aka eof position, file size)
1000 streampos endByte = stream.tellp();
1001 // maxbyte = position after the cube DN data and labels
1002 streampos maxbyte = (streampos) m_labelBytes;
1003
1004 if (m_storesDnData) {
1005 maxbyte += (streampos) m_ioHandler->getDataSize();
1006 }
1007
1008 // If EOF is too early, allocate space up to where we want the blob
1009 if (endByte < maxbyte) {
1010 stream.seekp(maxbyte, ios::beg);
1011 }
1012
1013 // Use default argument of "" for detached stream
1014 blob.Write(*m_label, stream, "", overwrite);
1015 }
1016
1017 // Write a detached blob
1018 else {
1019 FileName blobFileName = fileName();
1020 blobFileName = blobFileName.removeExtension();
1021 blobFileName = blobFileName.addExtension(blob.Type());
1022 blobFileName = blobFileName.addExtension(blob.Name());
1023 QString blobFile(blobFileName.expanded());
1024 ios::openmode flags = ios::in | ios::binary | ios::out | ios::trunc;
1025 fstream detachedStream;
1026 detachedStream.open(blobFile.toLatin1().data(), flags);
1027 if (!detachedStream) {
1028 QString message = "Unable to open data file [" +
1029 blobFileName.expanded() + "]";
1030 throw IException(IException::Io, message, _FILEINFO_);
1031 }
1032
1033 blob.Write(*m_label, detachedStream, blobFileName.name());
1034 }
1035 }
1036
1037
1045 Blob labelBlob = lab.toBlob();
1046 write(labelBlob);
1047 }
1048
1049
1057 Blob labelBlob = lab.toBlob();
1058 write(labelBlob);
1059 }
1060
1061
1070 void Cube::write(const Table &table) {
1071 Blob tableBlob = table.toBlob();
1072 write(tableBlob);
1073 }
1074
1075
1084 void Cube::write(const CubeStretch &cubeStretch) {
1085 Blob cubeStretchBlob = cubeStretch.toBlob();
1086 write(cubeStretchBlob);
1087 }
1088
1089
1100 void Cube::write(History &history, const QString &name) {
1101 Blob histBlob = history.toBlob(name);
1102 write(histBlob);
1103 }
1104
1105
1112 void Cube::write(const ImagePolygon &polygon) {
1113 Blob polyBlob = polygon.toBlob();
1114 write(polyBlob);
1115 }
1116
1117
1124 void Cube::write(Buffer &bufferToWrite) {
1125 if (!isOpen()) {
1126 string msg = "Tried to write to a cube before opening/creating it";
1127 throw IException(IException::Programmer, msg, _FILEINFO_);
1128 }
1129
1130 if (isReadOnly()) {
1131 QString msg = "Cannot write to the cube [" + (QString)QFileInfo(fileName()).fileName() +
1132 "] because it is opened read-only";
1133 throw IException(IException::Programmer, msg, _FILEINFO_);
1134 }
1135
1136 if (!m_storesDnData) {
1137 QString msg = "The cube [" + QFileInfo(fileName()).fileName() +
1138 "] does not support storing DN data because it is using an external file for DNs";
1139 throw IException(IException::Unknown, msg, _FILEINFO_);
1140 }
1141
1142 QMutexLocker locker(m_mutex);
1143 m_ioHandler->write(bufferToWrite);
1144 }
1145
1146
1157 void Cube::setBaseMultiplier(double base, double mult) {
1158 openCheck();
1159 m_base = base;
1160 m_multiplier = mult;
1161 }
1162
1163
1174 void Cube::setMinMax(double min, double max) {
1175 openCheck();
1176
1177 m_base = 0.0;
1178 m_multiplier = 1.0;
1179
1180 double x1, x2;
1181 if (m_pixelType == UnsignedByte) {
1182 x1 = VALID_MIN1;
1183 x2 = VALID_MAX1;
1184 m_multiplier = (max - min) / (x2 - x1);
1185 m_base = min - m_multiplier * x1;
1186 }
1187 else if (m_pixelType == SignedWord) {
1188 x1 = VALID_MIN2;
1189 x2 = VALID_MAX2;
1190 m_multiplier = (max - min) / (x2 - x1);
1191 m_base = min - m_multiplier * x1;
1192 }
1193 else if (m_pixelType == UnsignedWord) {
1194 x1 = VALID_MINU2;
1195 x2 = VALID_MAXU2;
1196 m_multiplier = (max - min) / (x2 - x1);
1197 m_base = min - m_multiplier * x1;
1198 }
1199 }
1200
1201
1209 openCheck();
1211 }
1212
1213
1223 void Cube::setDimensions(int ns, int nl, int nb) {
1224 openCheck();
1225 if ((ns < 1) || (nl < 1) || (nb < 1)) {
1226 string msg = "SetDimensions: Invalid number of sample, lines or bands";
1227 throw IException(IException::Programmer, msg, _FILEINFO_);
1228 }
1229 m_samples = ns;
1230 m_lines = nl;
1231 m_bands = nb;
1232 }
1233
1234
1240 void Cube::setExternalDnData(FileName cubeFileWithDnData) {
1241 try {
1242 initLabelFromFile(cubeFileWithDnData, false);
1244
1245 delete m_label;
1246 m_label = NULL;
1247 }
1248 catch (IException &) {
1249 delete m_label;
1250 m_label = NULL;
1251 throw;
1252 }
1253
1254 m_storesDnData = false;
1255 m_dataFileName = new FileName(cubeFileWithDnData);
1256
1257 delete m_labelFile;
1258 m_labelFile = NULL;
1259
1260 delete m_labelFileName;
1261 m_labelFileName = NULL;
1262 }
1263
1264
1273 openCheck();
1274 m_format = format;
1275 }
1276
1277
1284 void Cube::setLabelsAttached(bool attach) {
1285 openCheck();
1286 m_attached = attach;
1287 }
1288
1289
1297 void Cube::setLabelSize(int labelBytes) {
1298 openCheck();
1299 m_labelBytes = labelBytes;
1300 }
1301
1302
1311 openCheck();
1313 }
1314
1315
1327 void Cube::setVirtualBands(const QList<QString> &vbands) {
1328 openCheck();
1330 m_virtualBandList->clear();
1331 else
1332 m_virtualBandList = new QList<int>;
1333
1334 if (vbands.size() > 0) {
1335 QListIterator<QString> it(vbands);
1336 while (it.hasNext()) {
1337 m_virtualBandList->append(toInt(it.next()));
1338 }
1339 }
1340 else {
1341 delete m_virtualBandList;
1342 m_virtualBandList = NULL;
1343 }
1344
1345 if (m_ioHandler) {
1347 }
1348 }
1349
1350
1357 void Cube::setVirtualBands(const std::vector<QString> &vbands) {
1358 QList<QString> realVBands;
1359
1360 for(unsigned int i = 0; i < vbands.size(); i++)
1361 realVBands << vbands[i];
1362
1363 setVirtualBands(realVBands);
1364 }
1365
1366
1373 if (!isOpen()) {
1375 QString("Cannot relocate the DN data to [%1] for an external cube label "
1376 "file which is not open.")
1377 .arg(dnDataFile.original()),
1378 _FILEINFO_);
1379 }
1380
1381
1382 if (m_storesDnData) {
1384 QString("The cube [%1] stores DN data. It cannot be relocated to [%2] - "
1385 "this is only supported for external cube label files.")
1386 .arg(m_labelFileName->original()).arg(dnDataFile.original()),
1387 _FILEINFO_);
1388 }
1389
1390 m_label->findObject("IsisCube").findObject("Core").findKeyword("^DnFile")[0] =
1391 dnDataFile.original();
1392 reopen(m_labelFile->isWritable()? "rw" : "r");
1393 }
1394
1395
1396// void Cube::relocateDnData(FileName externalLabelFile, FileName dnDataFile) {
1397// try {
1398// Pvl externalLabelData(externalLabelFile.expanded());
1399// externalLabelData.FindObject("IsisCube").FindObject("Core").FindKeyword("^DnFile")[0] =
1400// dnDataFile.original();
1401// }
1402// catch (IException &e) {
1403// throw IException(e, IException::Io,
1404// QString("File [%1] does not appear to be an external cube label file")
1405// .arg(externalLabelFile.original().ToQt()),
1406// _FILEINFO_);
1407// }
1408// }
1409
1410
1416 int Cube::bandCount() const {
1417 int numBands = m_bands;
1419 numBands = m_virtualBandList->size();
1420 return numBands;
1421 }
1422
1423
1433 double Cube::base() const {
1434 return m_base;
1435 }
1436
1437
1446 return m_byteOrder;
1447 }
1448
1449
1458 if (m_camera == NULL && isOpen()) {
1460 }
1461 return m_camera;
1462 }
1463
1464
1465 void Cube::attachSpiceFromIsd(nlohmann::json isd) {
1466 PvlKeyword lkKeyword("LeapSecond");
1467 PvlKeyword pckKeyword("TargetAttitudeShape");
1468 PvlKeyword targetSpkKeyword("TargetPosition");
1469 PvlKeyword ckKeyword("InstrumentPointing");
1470 PvlKeyword ikKeyword("Instrument");
1471 PvlKeyword sclkKeyword("SpacecraftClock");
1472 PvlKeyword spkKeyword("InstrumentPosition");
1473 PvlKeyword iakKeyword("InstrumentAddendum");
1474 PvlKeyword demKeyword("ShapeModel");
1475 PvlKeyword exkKeyword("Extra");
1476
1477 Spice spice(*this->label(), isd);
1478 Table ckTable = spice.instrumentRotation()->Cache("InstrumentPointing");
1479 ckTable.Label() += PvlKeyword("Kernels");
1480
1481 for (int i = 0; i < ckKeyword.size(); i++)
1482 ckTable.Label()["Kernels"].addValue(ckKeyword[i]);
1483
1484 this->write(ckTable);
1485
1486 Table spkTable = spice.instrumentPosition()->Cache("InstrumentPosition");
1487 spkTable.Label() += PvlKeyword("Kernels");
1488 for (int i = 0; i < spkKeyword.size(); i++)
1489 spkTable.Label()["Kernels"].addValue(spkKeyword[i]);
1490
1491 this->write(spkTable);
1492
1493 Table bodyTable = spice.bodyRotation()->Cache("BodyRotation");
1494 bodyTable.Label() += PvlKeyword("Kernels");
1495 for (int i = 0; i < targetSpkKeyword.size(); i++)
1496 bodyTable.Label()["Kernels"].addValue(targetSpkKeyword[i]);
1497
1498 for (int i = 0; i < pckKeyword.size(); i++)
1499 bodyTable.Label()["Kernels"].addValue(pckKeyword[i]);
1500
1501 bodyTable.Label() += PvlKeyword("SolarLongitude",
1502 toString(spice.solarLongitude().degrees()));
1503 this->write(bodyTable);
1504
1505 Table sunTable = spice.sunPosition()->Cache("SunPosition");
1506 sunTable.Label() += PvlKeyword("Kernels");
1507 for (int i = 0; i < targetSpkKeyword.size(); i++)
1508 sunTable.Label()["Kernels"].addValue(targetSpkKeyword[i]);
1509
1510 this->write(sunTable);
1511
1512 PvlGroup currentKernels = this->group("Kernels");
1513
1514 Pvl *label = this->label();
1515 int i = 0;
1516 while (i < label->objects()) {
1517 PvlObject currObj = label->object(i);
1518 if (currObj.isNamed("NaifKeywords")) {
1519 label->deleteObject(i);
1520 }
1521 else {
1522 i ++;
1523 }
1524 }
1525
1526 *(this->label()) += spice.getStoredNaifKeywords();
1527
1528 // Access the camera here while all of the kernels are still loaded.
1529 // This needs to be done for some cameras that need loaded spice data
1530 // to actually create the camera model. (KaguyaTC for example)
1531 this->camera();
1532 }
1533
1534
1542 if (!isOpen()) {
1544 "An external cube label file must be opened in order to use "
1545 "Cube::getExternalCubeFileName",
1546 _FILEINFO_);
1547 }
1548
1549 if (storesDnData()) {
1551 "Cube::getExternalCubeFileName can only be called on an external cube label "
1552 "file",
1553 _FILEINFO_);
1554 }
1555
1556
1557 PvlObject &core = m_label->findObject("IsisCube").findObject("Core");
1558
1559 return core["^DnFile"][0];
1560 }
1561
1562
1569 QString Cube::fileName() const {
1570 if (isOpen())
1571 return m_labelFileName->expanded();
1572 else
1573 return "";
1574 }
1575
1576
1582 return m_format;
1583 }
1584
1585
1605 Histogram *Cube::histogram(const int &band, QString msg) {
1606 return histogram(band, ValidMinimum, ValidMaximum, msg);
1607 }
1608
1609
1635 Histogram *Cube::histogram(const int &band, const double &validMin,
1636 const double &validMax, QString msg) {
1637 // Make sure cube is open
1638 if ( !isOpen() ) {
1639 QString msg = "Cannot create histogram object for an unopened cube";
1640 throw IException(IException::Programmer, msg, _FILEINFO_);
1641 }
1642
1643 // Make sure band is valid
1644 if ((band < 0) || (band > bandCount())) {
1645 QString msg = "Invalid band in [CubeInfo::Histogram]";
1646 throw IException(IException::Programmer, msg, _FILEINFO_);
1647 }
1648
1649 int bandStart = band;
1650 int bandStop = band;
1651 int maxSteps = lineCount();
1652 if (band == 0) {
1653 bandStart = 1;
1654 bandStop = bandCount();
1655 maxSteps = lineCount() * bandCount();
1656 }
1657
1658 Progress progress;
1659 Histogram *hist = new ImageHistogram(*this, band, &progress);
1660 LineManager line(*this);
1661
1662 // This range is for throwing out data; the default parameters are OK always
1663 //hist->SetValidRange(validMin, validMax);
1664
1665 // We now need to know the binning range - ValidMinimum/Maximum are no longer
1666 // acceptable, default to the bin range start/end.
1667 double binMin = validMin;
1668 double binMax = validMax;
1669 if (binMin == ValidMinimum) {
1670 binMin = hist->BinRangeStart();
1671 }
1672
1673 if (binMax == ValidMaximum) {
1674 binMax = hist->BinRangeEnd();
1675 }
1676
1677 //hist->SetBinRange(binMin, binMax);
1678 hist->SetValidRange(binMin,binMax);
1679
1680 // Loop and get the histogram
1681 progress.SetText(msg);
1682 progress.SetMaximumSteps(maxSteps);
1683 progress.CheckStatus();
1684
1685 for(int useBand = bandStart ; useBand <= bandStop ; useBand++) {
1686 for(int i = 1; i <= lineCount(); i++) {
1687 line.SetLine(i, useBand);
1688 read(line);
1689 hist->AddData(line.DoubleBuffer(), line.size());
1690 progress.CheckStatus();
1691 }
1692 }
1693
1694 return hist;
1695 }
1696
1697
1707 Pvl *Cube::label() const {
1708 return m_label;
1709 }
1710
1711
1719 int Cube::labelSize(bool actual) const {
1720 int labelSize = m_labelBytes;
1721
1722 if (actual && m_label) {
1723 ostringstream s;
1724 s << *m_label << endl;
1725 labelSize = s.tellp();
1726 }
1727 else if (actual) {
1728 labelSize = 0;
1729 }
1730
1731 return labelSize;
1732 }
1733
1734
1740 int Cube::lineCount() const {
1741 return m_lines;
1742 }
1743
1744
1754 double Cube::multiplier() const {
1755 return m_multiplier;
1756 }
1757
1758
1765 return m_pixelType;
1766 }
1767
1768
1779 int Cube::physicalBand(const int &virtualBand) const {
1780 int physicalBand = virtualBand;
1781
1782 if (m_virtualBandList) {
1783 if ((virtualBand < 1) ||
1784 (virtualBand > m_virtualBandList->size())) {
1785 QString msg = "Out of array bounds [" + toString(virtualBand) + "]";
1786 throw IException(IException::Programmer, msg, _FILEINFO_);
1787 }
1788 physicalBand = m_virtualBandList->at(virtualBand - 1);
1789 }
1790
1791 return physicalBand;
1792 }
1793
1794
1801 if (m_projection == NULL && isOpen()) {
1803 }
1804 return m_projection;
1805 }
1806
1807
1813 int Cube::sampleCount() const {
1814 return m_samples;
1815 }
1816
1817
1836 Statistics *Cube::statistics(const int &band, QString msg) {
1837 return statistics(band, ValidMinimum, ValidMaximum, msg);
1838 }
1839
1840
1857 Statistics *Cube::statistics(const int &band, const double &validMin,
1858 const double &validMax, QString msg) {
1859 // Make sure cube is open
1860 if ( !isOpen() ) {
1861 QString msg = "Cannot create statistics object for an unopened cube";
1862 throw IException(IException::Programmer, msg, _FILEINFO_);
1863 }
1864
1865 // Make sure band is valid
1866 if ((band < 0) || (band > bandCount())) {
1867 string msg = "Invalid band in [CubeInfo::Statistics]";
1868 throw IException(IException::Programmer, msg, _FILEINFO_);
1869 }
1870
1871 // Construct a line buffer manager and a statistics object
1872 LineManager line(*this);
1873 Statistics *stats = new Statistics();
1874
1875 stats->SetValidRange(validMin, validMax);
1876
1877 int bandStart = band;
1878 int bandStop = band;
1879 int maxSteps = lineCount();
1880 if (band == 0) {
1881 bandStart = 1;
1882 bandStop = bandCount();
1883 maxSteps = lineCount() * bandCount();
1884 }
1885
1886 Progress progress;
1887 progress.SetText(msg);
1888 progress.SetMaximumSteps(maxSteps);
1889 progress.CheckStatus();
1890
1891 // Loop and get the statistics for a good minimum/maximum
1892 for(int useBand = bandStart ; useBand <= bandStop ; useBand++) {
1893 for(int i = 1; i <= lineCount(); i++) {
1894 line.SetLine(i, useBand);
1895 read(line);
1896 stats->AddData(line.DoubleBuffer(), line.size());
1897 progress.CheckStatus();
1898 }
1899 }
1900
1901 return stats;
1902 }
1903
1904
1910 bool Cube::storesDnData() const {
1911 return m_storesDnData;
1912 }
1913
1914
1929
1930 if (isOpen() && m_ioHandler) {
1931 m_ioHandler->addCachingAlgorithm(algorithm);
1932 }
1933 else if (!isOpen()) {
1934 QString msg = "Cannot add a caching algorithm until the cube is open";
1935 throw IException(IException::Programmer, msg, _FILEINFO_);
1936 }
1937 }
1938
1945 if (m_ioHandler) {
1946 QMutexLocker locker(m_mutex);
1948 }
1949 }
1950
1951
1961 bool Cube::deleteBlob(QString BlobName, QString BlobType) {
1962 for(int i = 0; i < m_label->objects(); i++) {
1963 PvlObject obj = m_label->object(i);
1964 if (obj.name().compare(BlobType) == 0) {
1965 if (obj.findKeyword("Name")[0] == BlobName) {
1967 return true;
1968 }
1969 }
1970 }
1971 return false;
1972 }
1973
1974
1983 void Cube::deleteGroup(const QString &group) {
1984 PvlObject &isiscube = label()->findObject("IsisCube");
1985 if (!isiscube.hasGroup(group)) return;
1986 isiscube.deleteGroup(group);
1987 }
1988
1989
1997 PvlGroup &Cube::group(const QString &group) const {
1998 PvlObject &isiscube = label()->findObject("IsisCube");
1999 return isiscube.findGroup(group);
2000 }
2001
2002
2010 bool Cube::hasGroup(const QString &group) const {
2011 const PvlObject &isiscube = label()->findObject("IsisCube");
2012 if (isiscube.hasGroup(group)) return true;
2013 return false;
2014 }
2015
2016
2025 bool Cube::hasBlob(const QString &name, const QString &type) {
2026 for(int o = 0; o < label()->objects(); o++) {
2027 PvlObject &obj = label()->object(o);
2028 if (obj.isNamed(type)) {
2029 if (obj.hasKeyword("Name")) {
2030 QString temp = (QString) obj["Name"];
2031 temp = temp.toUpper();
2032 QString temp2 = name;
2033 temp2 = temp2.toUpper();
2034 if (temp == temp2) return true;
2035 }
2036 }
2037 }
2038 return false;
2039 }
2040
2041
2049 bool Cube::hasTable(const QString &name) {
2050 return hasBlob(name, "Table");
2051 }
2052
2053
2062 void Cube::putGroup(const PvlGroup &group) {
2063 if (isReadOnly()) {
2064 QString msg = "Cannot add a group to the label of cube [" + (QString)QFileInfo(fileName()).fileName() +
2065 "] because it is opened read-only";
2066 throw IException(IException::Programmer, msg, _FILEINFO_);
2067 return;
2068 }
2069
2070 PvlObject &isiscube = label()->findObject("IsisCube");
2071 if (isiscube.hasGroup(group.name())) {
2072 isiscube.findGroup(group.name()) = group;
2073 }
2074 else {
2075 isiscube.addGroup(group);
2076 }
2077 }
2078
2079
2085 PvlObject &core = m_label->findObject("IsisCube").findObject("Core");
2086
2087 // Prune the band bin group if it exists
2088 if (m_label->findObject("IsisCube").hasGroup("BandBin")) {
2089 PvlGroup &bandBin = m_label->findObject("IsisCube").findGroup("BandBin");
2090 for (int k = 0;k < bandBin.keywords();k++) {
2091 if (bandBin[k].size() == m_bands && m_virtualBandList) {
2092 PvlKeyword temp = bandBin[k];
2093 bandBin[k].clear();
2094 for (int i = 0;i < m_virtualBandList->size();i++) {
2095 int physicalBand = m_virtualBandList->at(i) - 1;
2096 bandBin[k].addValue(temp[physicalBand], temp.unit(physicalBand));
2097 }
2098 }
2099 }
2100 }
2101
2102 // Change the number of bands in the labels of the cube
2103 if (m_virtualBandList && core.hasGroup("Dimensions")) core.findGroup("Dimensions")["Bands"] = toString(m_virtualBandList->size());
2104 }
2105
2106
2112 void Cube::cleanUp(bool removeIt) {
2113 if (m_ioHandler) {
2114 delete m_ioHandler;
2115 m_ioHandler = NULL;
2116 }
2117
2118 // Always remove a temporary file
2119 if (m_tempCube) {
2120 QFile::remove(m_tempCube->expanded());
2121 removeIt = false; // dont remove originals
2122
2123 delete m_tempCube;
2124 m_tempCube = NULL;
2125 }
2126
2127 if (removeIt) {
2128 QFile::remove(m_labelFileName->expanded());
2129
2131 QFile::remove(m_dataFileName->expanded());
2132 }
2133
2134 delete m_labelFile;
2135 m_labelFile = NULL;
2136
2137 delete m_dataFile;
2138 m_dataFile = NULL;
2139
2140 delete m_labelFileName;
2141 m_labelFileName = NULL;
2142
2143 delete m_dataFileName;
2144 m_dataFileName = NULL;
2145
2146 delete m_label;
2147 m_label = NULL;
2148
2149 delete m_virtualBandList;
2150 m_virtualBandList = NULL;
2151
2152 initialize();
2153 }
2154
2155
2161 m_labelFile = NULL;
2162 m_dataFile = NULL;
2163 m_ioHandler = NULL;
2164 m_mutex = NULL;
2165
2166 m_camera = NULL;
2167 m_projection = NULL;
2168
2169 m_labelFileName = NULL;
2170 m_dataFileName = NULL;
2171 m_tempCube = NULL;
2172 m_formatTemplateFile = NULL;
2173 m_label = NULL;
2174
2175 m_virtualBandList = NULL;
2176
2177 m_mutex = new QMutex();
2179 new FileName("$ISISROOT/appdata/templates/labels/CubeFormatTemplate.pft");
2180
2181 initialize();
2182 }
2183
2184
2191 QFile *Cube::dataFile() const {
2192 if (m_dataFile)
2193 return m_dataFile;
2194 else
2195 return m_labelFile;
2196 }
2197
2198
2207 FileName result;
2208
2209 // Attached, stores DN data - normal cube
2210 if (m_attached && m_storesDnData) {
2211 result = *m_labelFileName;
2212 }
2213 // Detached, stores DN data - standard detached cube
2214 else if (!m_attached && m_storesDnData) {
2215 result = *m_dataFileName;
2216 }
2217 // External cube - go look at our external file
2218 else if (!m_storesDnData) {
2219 FileName guess = *m_dataFileName;
2220 QDir dir(guess.toString());
2221
2222 // If path is relative and there is a labelFileName, start in directory of the ecub, then
2223 // cd to the directory containing the DnFile, since it is relative to the location of the ecub.
2224 // We need to turn the relative path into an absolute path.
2225 if (dir.isRelative() && m_labelFileName) {
2226 QDir dir2(m_labelFileName->originalPath());
2227 dir2.cd(guess.path());
2228 guess = dir2.absolutePath() + "/" + guess.name();
2229 }
2230 do {
2231 Pvl guessLabel(guess.expanded());
2232
2233 PvlObject &core = guessLabel.findObject("IsisCube").findObject("Core");
2234
2235 if (core.hasKeyword("^DnFile")) {
2236 FileName currentGuess = guess;
2237 guess = core["^DnFile"][0];
2238
2239 if (!guess.path().startsWith("/")) {
2240 guess = currentGuess.path() + "/" + guess.original();
2241 }
2242 }
2243 else if (core.hasKeyword("^Core")) {
2244 result = core["^Core"][0];
2245 }
2246 else {
2247 result = guess;
2248 }
2249 }
2250 while (result.name() == "");
2251 }
2252
2253 return result;
2254 }
2255
2256
2269 m_byteOrder = Lsb;
2270 if (IsBigEndian())
2271 m_byteOrder = Msb;
2272 m_format = Tile;
2273 m_pixelType = Real;
2274
2275 m_attached = true;
2276 m_storesDnData = true;
2277 m_labelBytes = 65536;
2278
2279 m_samples = 0;
2280 m_lines = 0;
2281 m_bands = 0;
2282
2283 m_base = 0.0;
2284 m_multiplier = 1.0;
2285 }
2286
2287
2293 void Cube::initCoreFromLabel(const Pvl &label) {
2294 const PvlObject &core = label.findObject("IsisCube").findObject("Core");
2295
2296 if (!core.hasKeyword("^DnFile")) {
2297 // Dimensions
2298 const PvlGroup &dims = core.findGroup("Dimensions");
2299 m_samples = dims["Samples"];
2300 m_lines = dims["Lines"];
2301 m_bands = dims["Bands"];
2302
2303 // Stored pixel information
2304 const PvlGroup &pixelsGroup = core.findGroup("Pixels");
2305 m_byteOrder = ByteOrderEnumeration(pixelsGroup["ByteOrder"]);
2306 m_base = pixelsGroup["Base"];
2307 m_multiplier = pixelsGroup["Multiplier"];
2308 m_pixelType = PixelTypeEnumeration(pixelsGroup["Type"]);
2309
2310 // Now examine the format to see which type of handler to create
2311 if ((QString) core["Format"] == "BandSequential") {
2312 m_format = Bsq;
2313 }
2314 else {
2315 m_format = Tile;
2316 }
2317 }
2318 else {
2319 FileName temp(core["^DnFile"][0]);
2320 if (!temp.expanded().startsWith("/")) {
2321 temp = FileName(m_labelFileName->path() + "/" + temp.original());
2322 }
2323
2324 initCoreFromLabel(Pvl(temp.toString()));
2325 }
2326 }
2327
2328
2337 void Cube::initLabelFromFile(FileName labelFileName, bool readWrite) {
2338
2339 try {
2340 if (labelFileName.fileExists()) {
2341 m_label = new Pvl(labelFileName.expanded());
2342 if (!m_label->objects()) {
2343 throw IException();
2344 }
2345 }
2346 }
2347 catch(IException &) {
2348 if (m_label) {
2349 delete m_label;
2350 m_label = NULL;
2351 }
2352 }
2353
2354 try {
2355 if (!m_label) {
2356 FileName tmp(labelFileName);
2357 tmp = tmp.addExtension("cub");
2358 if (tmp.fileExists()) {
2359 m_label = new Pvl(tmp.expanded());
2360 if (!m_label->objects()) {
2361 throw IException();
2362 }
2363 labelFileName = tmp;
2364 }
2365 }
2366 }
2367 catch(IException &e) {
2368 if (m_label) {
2369 delete m_label;
2370 m_label = NULL;
2371 }
2372 }
2373
2374 try {
2375 if (!m_label) {
2376 FileName tmp(labelFileName);
2377 tmp = tmp.setExtension("lbl");
2378 if (tmp.fileExists()) {
2379 m_label = new Pvl(tmp.expanded());
2380 if (!m_label->objects()) {
2381 throw IException();
2382 }
2383 labelFileName = tmp;
2384 }
2385 }
2386 }
2387 catch(IException &e) {
2388 if (m_label) {
2389 delete m_label;
2390 m_label = NULL;
2391 }
2392 }
2393
2394 try {
2395 if (!m_label) {
2396 FileName tmp(labelFileName);
2397 tmp = tmp.addExtension("ecub");
2398 if (tmp.fileExists()) {
2399 m_label = new Pvl(tmp.expanded());
2400 if (!m_label->objects()) {
2401 throw IException();
2402 }
2403 labelFileName = tmp;
2404 }
2405 }
2406 }
2407 catch(IException &e) {
2408 if (m_label) {
2409 delete m_label;
2410 m_label = NULL;
2411 }
2412 }
2413
2414 if (!m_label) {
2415 QString msg = Message::FileOpen(labelFileName.original());
2416 throw IException(IException::Io, msg, _FILEINFO_);
2417 }
2418
2419 m_labelFileName = new FileName(labelFileName);
2420
2421 // See if this is an old Isis cube format. If so then we will
2422 // need to internalize a new label
2423 if (m_label->hasKeyword("CCSD3ZF0000100000001NJPL3IF0PDS200000001")) {
2424 if (!readWrite) {
2426 }
2427 else {
2428 QString msg = "Can not open [" + m_labelFileName->original() + "]"
2429 " because it is an ISIS2 cube.";
2430 cleanUp(false);
2431 throw IException(IException::Io, msg, _FILEINFO_);
2432 }
2433 }
2434 else {
2435 m_labelFile = new QFile(m_labelFileName->expanded());
2436 }
2437 }
2438
2439
2444 if (isOpen()) {
2445 string msg = "Sorry you can't do a SetMethod after the cube is opened";
2446 throw IException(IException::Programmer, msg, _FILEINFO_);
2447 }
2448 }
2449
2450
2457 Pvl label = *m_label;
2458 PvlObject *core = NULL;
2459
2460 do {
2461 core = &label.findObject("IsisCube").findObject("Core");
2462
2463 if (core->hasKeyword("^DnFile")) {
2464
2465 FileName temp((*core)["^DnFile"][0]);
2466 if (!temp.expanded().startsWith("/")) {
2467 temp = realDataFileName();
2468 }
2469
2470 label = Pvl(temp.toString());
2471 core = NULL;
2472 }
2473 }
2474 while (!core);
2475
2476 return label;
2477 }
2478
2479
2486 void Cube::reformatOldIsisLabel(const QString &oldCube) {
2487 QString parameters = "from=" + oldCube;
2488 FileName oldName(oldCube);
2489 FileName tempCube = FileName::createTempFile("Temporary_" + oldName.name() + ".cub");
2490 parameters += " to=" + tempCube.expanded();
2491
2492 if (iApp == NULL) {
2493 QString command = "$ISISROOT/bin/pds2isis " + parameters;
2495 }
2496 else {
2497 QString prog = "pds2isis";
2498 ProgramLauncher::RunIsisProgram(prog, parameters);
2499 }
2500
2501 m_tempCube = new FileName(tempCube);
2503 m_labelFile = new QFile(m_tempCube->expanded());
2504 }
2505
2506
2516 void Cube::latLonRange(double &minLatitude, double &maxLatitude, double &minLongitude, double &
2517 maxLongitude) {
2518 Camera *cam;
2519 TProjection *proj;
2520
2521 bool isGood = false;
2522 bool useProj = true;
2523
2524 if (hasGroup("Instrument")) {
2525 useProj = false;
2526 }
2527
2528 // setup camera or projection
2529 if (useProj) {
2530 try {
2531 proj = (TProjection *) projection();
2532 }
2533 catch(IException &e) {
2534 QString msg = "Cannot calculate lat/lon range without a camera or projection";
2535 throw IException(e, IException::User, msg, _FILEINFO_);
2536 }
2537 }
2538 else {
2539 try {
2540 cam = camera();
2541 }
2542 catch(IException &e) {
2543 QString msg = "Unable to create camera when calculating a lat/lon range.";
2544 throw IException(e, IException::User, msg, _FILEINFO_);
2545 }
2546 }
2547
2548 // Iterate over all samp/line combos in cube
2549 minLatitude = 99999;
2550 minLongitude = 99999;
2551 maxLatitude = -99999;
2552 maxLongitude = -99999;
2553
2554 for (double sample = 0.5; sample < sampleCount() + 0.5; sample++) {
2555 // Checks to see if the point is in outer space
2556 for (double line = 0.5; line < lineCount() + 0.5; line++) {
2557 if (useProj) {
2558 isGood = proj->SetWorld(sample, line);
2559 }
2560 else {
2561 isGood = cam->SetImage(sample, line);
2562 }
2563
2564 double lat, lon;
2565 if (isGood) {
2566 if (useProj) {
2567 lat = proj->UniversalLatitude();
2568 lon = proj->UniversalLongitude();
2569 }
2570 else {
2571 lat = cam->UniversalLatitude();
2572 lon = cam->UniversalLongitude();
2573 }
2574
2575 // update mix/max lat/lons
2576 if (lat < minLatitude) {
2577 minLatitude = lat;
2578 }
2579 else if (lat > maxLatitude) {
2580 maxLatitude = lat;
2581 }
2582
2583 if (lon < minLongitude) {
2584 minLongitude = lon;
2585 }
2586 else if (lon > maxLongitude) {
2587 maxLongitude = lon;
2588 }
2589 }
2590 }
2591 }
2592 if ( (minLatitude == 99999) || (minLongitude == 99999) || (maxLatitude == -99999) ||
2593 (maxLongitude == -99999) ) {
2594 QString msg = "Unable to calculate a minimum or maximum latitutde or longitude.";
2595 throw IException(IException::Unknown, msg, _FILEINFO_);
2596 }
2597 }
2598
2604 if (!isOpen()) {
2605 string msg = "Cube must be opened first before writing labels";
2606 throw IException(IException::Programmer, msg, _FILEINFO_);
2607 }
2608
2609 // Set the pvl's format template
2610 m_label->setFormatTemplate(m_formatTemplateFile->original());
2611
2612 // Write them with attached data
2613 if (m_attached) {
2614 QMutexLocker locker(m_mutex);
2615 QMutexLocker locker2(m_ioHandler->dataFileMutex());
2616
2617 ostringstream temp;
2618 temp << *m_label << endl;
2619 string tempstr = temp.str();
2620 if ((int) tempstr.length() < m_labelBytes) {
2621 QByteArray labelArea(m_labelBytes, '\0');
2622 QByteArray labelUnpaddedContents(tempstr.c_str(), tempstr.length());
2623 labelArea.replace(0, labelUnpaddedContents.size(), labelUnpaddedContents);
2624 // Rewrite the label area
2625 m_labelFile->seek(0);
2626 m_labelFile->write(labelArea);
2627 }
2628 else {
2629 locker2.unlock();
2630 QString msg = "Label space is full in [" +
2631 (QString)FileName(*m_labelFileName).name() +
2632 "] unable to write labels";
2633 cleanUp(false);
2634 throw IException(IException::Io, msg, _FILEINFO_);
2635 }
2636 }
2637
2638 // or detached label
2639 else {
2641 }
2642 }
2643}
Buffer for reading and writing cube data.
Definition Buffer.h:53
int size() const
Returns the total number of pixels in the shape buffer.
Definition Buffer.h:97
double * DoubleBuffer() const
Returns the value of the shape buffer.
Definition Buffer.h:138
Manages a Buffer over a cube.
static Camera * Create(Cube &cube)
Creates a Camera object using Pvl Specifications.
Manipulate and parse attributes of input cube filenames.
Manipulate and parse attributes of output cube filenames.
IO Handler for Isis Cubes using the BSQ format.
This is the parent of the caching algorithms.
IO Handler for Isis Cubes.
Definition Cube.h:168
void addCachingAlgorithm(CubeCachingAlgorithm *)
This will add the given caching algorithm to the list of attempted caching algorithms.
Definition Cube.cpp:1928
void clearIoCache()
This will clear excess RAM used for quicker IO in the cube.
Definition Cube.cpp:1944
bool hasTable(const QString &name)
Check to see if the cube contains a pvl table by the provided name.
Definition Cube.cpp:2049
QFile * m_dataFile
This is only sometimes allocated.
Definition Cube.h:361
Pvl realDataFileLabel() const
Function to read data from a cube label and return it as a PVL object.
Definition Cube.cpp:2456
ImagePolygon readFootprint() const
Read the footprint polygon for the Cube.
Definition Cube.cpp:872
Cube()
Constructs a Cube object.
Definition Cube.cpp:49
void setPixelType(PixelType pixelType)
Used prior to the Create method, this will specify the output pixel type.
Definition Cube.cpp:1310
void latLonRange(double &minLatitude, double &maxLatitude, double &minLongitude, double &maxLongitude)
Returns the latitude and longitude range for the Cube.
Definition Cube.cpp:2516
void deleteGroup(const QString &group)
Deletes a group from the cube labels.
Definition Cube.cpp:1983
void reformatOldIsisLabel(const QString &oldCube)
This is a helper, used by open(...), that handles opening Isis 2 cubes as if they were Isis cubes.
Definition Cube.cpp:2486
void setFormat(Format format)
Used prior to the Create method, this will specify the format of the cube, either band,...
Definition Cube.cpp:1272
bool deleteBlob(QString BlobName, QString BlobType)
This method will delete a blob label object from the cube as specified by the Blob type and name.
Definition Cube.cpp:1961
int m_bands
The band count of the open cube or the cube that will be created.
Definition Cube.h:438
void initialize()
This sets Cube to its default state: Native byte order Format = Tile PixelType = Real (4 bytes per pi...
Definition Cube.cpp:2268
Format format() const
Definition Cube.cpp:1581
PixelType m_pixelType
This is the pixel type on disk.
Definition Cube.h:388
void relocateDnData(FileName dnDataFile)
Relocates the DN data for a cube to an external cube label file.
Definition Cube.cpp:1372
void construct()
Initialize members from their initial undefined states.
Definition Cube.cpp:2160
int m_labelBytes
The maximum allowed size of the label; the allocated space.
Definition Cube.h:429
virtual Histogram * histogram(const int &band=1, QString msg="Gathering histogram")
This method returns a pointer to a Histogram object which allows the program to obtain and use variou...
Definition Cube.cpp:1605
int lineCount() const
Definition Cube.cpp:1740
void initLabelFromFile(FileName labelFileName, bool readWrite)
This function initializes the Cube label from a file passed as a parameter.
Definition Cube.cpp:2337
double multiplier() const
Returns the multiplier value for converting 8-bit/16-bit pixels to 32-bit.
Definition Cube.cpp:1754
CubeIoHandler * m_ioHandler
This does the heavy lifting for cube DN IO and is always allocated when isOpen() is true.
Definition Cube.h:367
FileName realDataFileName() const
This gets the file name of the file which actually contains the DN data.
Definition Cube.cpp:2206
void setLabelsAttached(bool attached)
Use prior to calling create, this sets whether or not to use separate label and data files.
Definition Cube.cpp:1284
CubeStretch readCubeStretch(QString name="CubeStretch", const std::vector< PvlKeyword > keywords=std::vector< PvlKeyword >()) const
Read a Stretch from a cube.
Definition Cube.cpp:918
Statistics * statistics(const int &band=1, QString msg="Gathering statistics")
This method returns a pointer to a Statistics object which allows the program to obtain and use vario...
Definition Cube.cpp:1836
void setDimensions(int ns, int nl, int nb)
Used prior to the Create method to specify the size of the cube.
Definition Cube.cpp:1223
Camera * camera()
Return a camera associated with the cube.
Definition Cube.cpp:1457
FileName externalCubeFileName() const
If this is an external cube label file, this will give you the cube dn file that this label reference...
Definition Cube.cpp:1541
PvlGroup & group(const QString &group) const
Read a group from the cube into a Label.
Definition Cube.cpp:1997
double m_base
The base of the open cube or the cube that will be created; does not apply if m_pixelType is Real.
Definition Cube.h:444
int sampleCount() const
Definition Cube.cpp:1813
bool m_attached
True if labels are attached.
Definition Cube.h:416
void putGroup(const PvlGroup &group)
Adds a group in a Label to the cube.
Definition Cube.cpp:2062
bool m_storesDnData
True (most common case) when the cube DN data is inside the file we're writing to.
Definition Cube.h:423
bool isOpen() const
Test if a cube file has been opened/created.
Definition Cube.cpp:182
void setBaseMultiplier(double base, double mult)
Used prior to the Create method, this will specify the base and multiplier for converting 8-bit/16-bi...
Definition Cube.cpp:1157
bool isReadOnly() const
Test if the opened cube is read-only, that is write operations will fail if this is true.
Definition Cube.cpp:208
int m_lines
The line count of the open cube or the cube that will be created.
Definition Cube.h:435
double base() const
Returns the base value for converting 8-bit/16-bit pixels to 32-bit.
Definition Cube.cpp:1433
void fromIsd(const FileName &fileName, Pvl &label, nlohmann::json &isd, QString access)
Initialize Cube data from a PVL label and JSON ISD.
Definition Cube.cpp:98
void setMinMax(double min, double max)
Used prior to the Create method, this will compute a good base and multiplier value given the minimum...
Definition Cube.cpp:1174
QFile * dataFile() const
This returns the QFile with cube DN data in it.
Definition Cube.cpp:2191
Cube * copy(FileName newFile, const CubeAttributeOutput &newFileAttributes)
Copies the cube to the new fileName.
Definition Cube.cpp:271
void create(const QString &cfile)
This method will create an isis cube for writing.
Definition Cube.cpp:409
FileName * m_tempCube
If open was called with an Isis 2 cube, then this will be the name of the imported ISIS cube.
Definition Cube.h:410
bool hasBlob(const QString &name, const QString &type)
Check to see if the cube contains a BLOB.
Definition Cube.cpp:2025
void cleanUp(bool remove)
This clears all of the allocated memory associated with an open cube.
Definition Cube.cpp:2112
ByteOrder byteOrder() const
Returns the byte order/endian-ness of the cube file.
Definition Cube.cpp:1445
ByteOrder m_byteOrder
The byte order of the opened cube; if there is no open cube then this is the byte order that will be ...
Definition Cube.h:374
QFile * m_labelFile
This is the file that contains the labels always; if labels are attached then this contains the file ...
Definition Cube.h:355
bool labelsAttached() const
Test if labels are attached.
Definition Cube.cpp:243
void open(const QString &cfile, QString access="r")
This method will open an existing isis cube for reading or reading/writing.
Definition Cube.cpp:622
PixelType pixelType() const
Definition Cube.cpp:1764
bool storesDnData() const
This method returns a boolean value.
Definition Cube.cpp:1910
void setVirtualBands(const QList< QString > &vbands)
This allows the programmer to specify a subset of bands to work with.
Definition Cube.cpp:1327
FileName * m_formatTemplateFile
Label pvl format template file (describes how to format labels)
Definition Cube.h:413
Pvl * m_label
The label if IsOpen(), otherwise NULL.
Definition Cube.h:426
void read(Blob &blob, const std::vector< PvlKeyword > keywords=std::vector< PvlKeyword >()) const
This method will read data from the specified Blob object.
Definition Cube.cpp:813
bool isProjected() const
Returns true if the labels of the cube appear to have a valid mapping group.
Definition Cube.cpp:197
OriginalLabel readOriginalLabel(const QString &name="IsisCube") const
Read the original PDS3 label from a cube.
Definition Cube.cpp:895
Format
These are the possible storage formats of ISIS cubes.
Definition Cube.h:179
@ Tile
Cubes are stored in tile format, that is the order of the pixels in the file (on disk) is BSQ within ...
Definition Cube.h:233
@ Bsq
Cubes are stored in band-sequential format, that is the order of the pixels in the file (on disk) is:
Definition Cube.h:200
virtual int physicalBand(const int &virtualBand) const
This method will return the physical band number given a virtual band number.
Definition Cube.cpp:1779
Table readTable(const QString &name)
Read a Table from the cube.
Definition Cube.cpp:958
Camera * m_camera
Camera allocated from the camera() method.
Definition Cube.h:394
bool hasGroup(const QString &group) const
Return if the cube has a specified group in the labels.
Definition Cube.cpp:2010
void setLabelSize(int labelBytes)
Used prior to the Create method, this will allocate a specific number of bytes in the label area for ...
Definition Cube.cpp:1297
OriginalXmlLabel readOriginalXmlLabel() const
Read the original PDS4 label from a cube.
Definition Cube.cpp:937
virtual QString fileName() const
Returns the opened cube's filename.
Definition Cube.cpp:1569
void fromLabel(const FileName &fileName, Pvl &label, QString access)
Initialize Cube data from a PVL label.
Definition Cube.cpp:75
virtual ~Cube()
Destroys the Cube object.
Definition Cube.cpp:159
QList< int > * m_virtualBandList
If allocated, converts from physical on-disk band # to virtual band #.
Definition Cube.h:453
void write(Blob &blob, bool overwrite=true)
This method will write a blob of data (e.g.
Definition Cube.cpp:977
bool isReadWrite() const
Test if the opened cube is read-write, that is read and write operations should succeed if this is tr...
Definition Cube.cpp:230
FileName * m_labelFileName
The full filename of the label file (.lbl or .cub)
Definition Cube.h:400
void setExternalDnData(FileName cubeFileWithDnData)
Used to set external dn data to cube.
Definition Cube.cpp:1240
void close(bool remove=false)
Closes the cube and updates the labels.
Definition Cube.cpp:255
History readHistory(const QString &name="IsisCube") const
Read the History from the Cube.
Definition Cube.cpp:853
void writeLabels()
Write the Pvl labels to the cube's label file.
Definition Cube.cpp:2603
QMutex * m_mutex
Basic thread-safety mutex; this class is not optimized for threads.
Definition Cube.h:391
void initCoreFromLabel(const Pvl &label)
This function initializes the Cube core from a Pvl Label passed as a parameter.
Definition Cube.cpp:2293
int labelSize(bool actual=false) const
Returns the number of bytes used by the label.
Definition Cube.cpp:1719
int m_samples
The sample count of the open cube or the cube that will be created.
Definition Cube.h:432
void openCheck()
Throw an exception if the cube is not open.
Definition Cube.cpp:2443
Projection * projection()
Definition Cube.cpp:1800
double m_multiplier
The multiplier of the open cube or the cube that will be created; does not apply if m_pixelType is Re...
Definition Cube.h:450
virtual int bandCount() const
Returns the number of virtual bands for the cube.
Definition Cube.cpp:1416
Pvl * label() const
Returns a pointer to the IsisLabel object associated with the cube.
Definition Cube.cpp:1707
void reopen(QString access="r")
This method will reopen an isis sube for reading or reading/writing.
Definition Cube.cpp:780
Projection * m_projection
Projection allocated from the projection() method.
Definition Cube.h:397
void setByteOrder(ByteOrder byteOrder)
Used prior to the Create method, this will specify the byte order of pixels, either least or most sig...
Definition Cube.cpp:1208
FileName * m_dataFileName
The full filename of the data file (.cub)
Definition Cube.h:403
void applyVirtualBandsToLabel()
Applies virtual bands to label.
Definition Cube.cpp:2084
Format m_format
If isOpen() then this is the IO format that the cube uses.
Definition Cube.h:381
void clearCache(bool blockForWriteCache=true) const
Free all cube chunks (cached cube data) from memory and write them to disk.
void addCachingAlgorithm(CubeCachingAlgorithm *algorithm)
This will add the given caching algorithm to the list of attempted caching algorithms.
QMutex * dataFileMutex()
Get the mutex that this IO handler is using around I/Os on the given data file.
void read(Buffer &bufferToFill) const
Read cube data from disk into the buffer.
void write(const Buffer &bufferToWrite)
Write buffer data into the cube data on disk.
void setVirtualBands(const QList< int > *virtualBandList)
This changes the virtual band list.
virtual void updateLabels(Pvl &labels)=0
Function to update the labels with a Pvl object.
BigInt getDataSize() const
Stores stretch information for a cube.
Definition CubeStretch.h:27
IO Handler for Isis Cubes using the tile format.
File name manipulation and expansion.
Definition FileName.h:100
QString path() const
Returns the path of the file name.
Definition FileName.cpp:103
QString name() const
Returns the name of the file excluding the path and the attributes in the file name.
Definition FileName.cpp:162
QString expanded() const
Returns a QString of the full file name including the file path, excluding the attributes.
Definition FileName.cpp:196
static FileName createTempFile(FileName templateFileName="$TEMPORARY/temp")
Creates a temporary file and returns a FileName object created using the temporary file.
Definition FileName.cpp:478
QString original() const
Returns the full file name including the file path.
Definition FileName.cpp:212
QString originalPath() const
Returns the path of the original file name.
Definition FileName.cpp:84
QString toString() const
Returns a QString of the full file name including the file path, excluding the attributes with any Is...
Definition FileName.cpp:515
Container of a cube histogram.
Definition Histogram.h:74
Blob toBlob(const QString &name="IsisCube")
Converts a history object into a new blob object.
Definition History.cpp:79
Isis exception class.
Definition IException.h:91
@ Unknown
A type of error that cannot be classified as any of the other error types.
Definition IException.h:118
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
Definition IException.h:126
@ Programmer
This error is for when a programmer made an API call that was illegal.
Definition IException.h:146
@ Io
A type of error that occurred when performing an actual I/O operation.
Definition IException.h:155
Container of a cube histogram.
Create cube polygons, read/write polygons to blobs.
Buffer manager, for moving through a cube in lines.
Definition LineManager.h:39
bool SetLine(const int line, const int band=1)
Positions the buffer at the requested line and returns a status indicator if the set was succesful or...
Read and store original labels.
Read and store original Xml labels.
static void RunIsisProgram(QString isisProgramName, QString arguments)
Executes the Isis program with the given arguments.
static void RunSystemCommand(QString commandLine)
This runs arbitrary system commands.
Program progress reporter.
Definition Progress.h:42
void SetMaximumSteps(const int steps)
This sets the maximum number of steps in the process.
Definition Progress.cpp:85
void SetText(const QString &text)
Changes the value of the text string reported just before 0% processed.
Definition Progress.cpp:61
void CheckStatus()
Checks and updates the status.
Definition Progress.cpp:105
static Isis::Projection * CreateFromCube(Isis::Cube &cube)
This method is a helper method.
Base class for Map Projections.
Definition Projection.h:155
QString name() const
Returns the container name.
Contains multiple PvlContainers.
Definition PvlGroup.h:41
Container for cube-like labels.
Definition Pvl.h:119
void write(const QString &file)
Opens and writes PVL information to a file and handles the end of line sequence.
Definition Pvl.cpp:130
A single keyword-value pair.
Definition PvlKeyword.h:87
void clear()
Clears all values and units for this PvlKeyword object.
Contains Pvl Groups and Pvl Objects.
Definition PvlObject.h:61
bool hasKeyword(const QString &kname, FindOptions opts) const
See if a keyword is in the current PvlObject, or deeper inside other PvlObjects and Pvlgroups within ...
PvlObjectIterator findObject(const QString &name, PvlObjectIterator beg, PvlObjectIterator end)
Find the index of object with a specified name, between two indexes.
Definition PvlObject.h:276
void deleteObject(const QString &name)
Remove an object from the current PvlObject.
int objects() const
Returns the number of objects.
Definition PvlObject.h:221
PvlObject & object(const int index)
Return the object at the specified index.
void addObject(const PvlObject &object)
Add a PvlObject.
Definition PvlObject.h:309
Obtain SPICE information for a spacecraft.
Definition Spice.h:283
This class is used to accumulate statistics on double arrays.
Definition Statistics.h:94
Base class for Map TProjections.
Class for storing Table blobs information.
Definition Table.h:61
PvlObject & Label()
The Table's label.
Definition Table.cpp:260
Blob toBlob() const
Serialze the Table to a Blob that can be written to a file.
Definition Table.cpp:414
ByteOrder
Tests the current architecture for byte order.
Definition Endian.h:42
QString FileOpen(const QString &filename)
This error should be used when a file could not be opened.
Definition FileOpen.cpp:11
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
int SizeOf(Isis::PixelType pixelType)
Returns the number of bytes of the specified PixelType.
Definition PixelType.h:46
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition IString.cpp:211
int toInt(const QString &string)
Global function to convert from a string to an integer.
Definition IString.cpp:93
const double ValidMaximum
The maximum valid double value for Isis pixels.
bool IsBigEndian()
Definition Endian.h:105
Isis::PixelType PixelTypeEnumeration(const QString &type)
Returns PixelType enumeration given a string.
Definition PixelType.h:89
@ ExternalLabel
The label is pointing to an external DN file - the label is also external to the data.
@ AttachedLabel
The input label is embedded in the image file.
@ DetachedLabel
The input label is in a separate data file from the image.
long long int BigInt
Big int.
Definition Constants.h:49
const double ValidMinimum
The minimum valid double value for Isis pixels.
QString PixelTypeName(Isis::PixelType pixelType)
Returns string name of PixelType enumeration entered as input parameter.
Definition PixelType.h:66
PixelType
Enumerations for Isis Pixel Types.
Definition PixelType.h:27
Namespace for the standard library.