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