Loading [MathJax]/jax/output/NativeMML/config.js
Isis 3 Programmer Reference
Cube.cpp
1
5
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
102 PvlGroup &instGrp = label.findGroup("Instrument", Pvl::Traverse);
103 if (isd.contains("line_scan_rate") && (QString)instGrp["InstrumentId"] == "HRSC") {
104 attachLineScanTableFromIsd(isd);
105 }
106
107 attachSpiceFromIsd(isd);
108
109 close();
110 open(fileName.toString(), access);
111 }
112
123 void Cube::fromIsd(const FileName &fileName, FileName &labelFile, FileName &isdFile, QString access) {
124 std::ifstream isdStream(isdFile.expanded().toStdString());
125 std::ifstream labelStream(labelFile.expanded().toStdString());
126
127 if (isdStream.fail()) {
128 QString msg = QString("failed to open isd stream: %1").arg(isdFile.expanded());
129 throw IException(IException::Io, msg,
130 isdFile.baseName().toStdString().c_str(), 153);
131 }
132
133 if (labelStream.fail()) {
134 QString msg = "failed to open file stream";
135 throw IException(IException::Io, msg,
136 fileName.baseName().toStdString().c_str(), 153);
137 }
138
139 Pvl label;
140 nlohmann::json isd;
141
142 try {
143 labelStream >> label;
144 }
145 catch (std::exception &ex) {
146 QString msg = QString("Failed to open label file, %1, %2").arg(labelFile.expanded()).arg(ex.what());
147 throw IException(IException::Io, msg,
148 fileName.baseName().toStdString().c_str(), 153);
149 }
150
151
152 try {
153 isdStream >> isd;
154 }
155 catch (std::exception &ex) {
156 QString msg = QString("Failed to open ISD file, %1, %2").arg(isdFile.expanded()).arg(ex.what());
157 throw IException(IException::Io, msg,
158 fileName.baseName().toStdString().c_str(), 145);
159 }
160
161 fromIsd(fileName, label, isd, access);
162 reopen("rw");
163 }
164
167 close();
168
169 delete m_mutex;
170 m_mutex = NULL;
171
172 delete m_camera;
173 m_camera = NULL;
174
175
176 delete m_projection;
177 m_projection = NULL;
178
181 }
182
183
189 bool Cube::isOpen() const {
190 bool open = (m_ioHandler != NULL);
191
192 return open;
193 }
194
195
204 bool Cube::isProjected() const {
205 return label()->findObject("IsisCube").hasGroup("Mapping");
206 }
207
208
215 bool Cube::isReadOnly() const {
216 bool readOnly = false;
217
218 if (!isOpen()) {
219 QString msg = "No cube opened";
220 throw IException(IException::Programmer, msg, _FILEINFO_);
221 }
222
223 if ((m_labelFile->openMode() & QIODevice::ReadWrite) != QIODevice::ReadWrite)
224 readOnly = true;
225
226 return readOnly;
227 }
228
229
237 bool Cube::isReadWrite() const {
238 return !isReadOnly();
239 }
240
241
250 bool Cube::labelsAttached() const {
251 return m_attached;
252 }
253
254
262 void Cube::close(bool removeIt) {
263 if (isOpen() && isReadWrite())
264 writeLabels();
265
266 cleanUp(removeIt);
267 }
268
269
278 Cube *Cube::copy(FileName newFile, const CubeAttributeOutput &newFileAttributes) {
279 if (!isOpen()) {
281 QObject::tr("Cube::copy requires the originating cube to be open"),
282 _FILEINFO_);
283 }
284
285
286 Cube *result = new Cube;
287
288 if (newFileAttributes.labelAttachment() != ExternalLabel) {
290 result->setByteOrder(newFileAttributes.byteOrder());
291 result->setFormat(newFileAttributes.fileFormat());
292
293 if (newFileAttributes.labelAttachment() == DetachedLabel) {
294 result->setLabelsAttached(false);
295 }
296
297 if (newFileAttributes.propagatePixelType()) {
298 result->setPixelType(pixelType());
299 }
300 else {
301 result->setPixelType(newFileAttributes.pixelType());
302 }
303
304 if (newFileAttributes.propagateMinimumMaximum()) {
305 if(result->pixelType() == Isis::Real) {
306 result->setBaseMultiplier(0.0, 1.0);
307 }
308 else if(result->pixelType() >= pixelType()) {
309 result->setBaseMultiplier(base(), multiplier());
310 }
311 else {
312 QString msg =
313 QObject::tr("Cannot reduce the output PixelType for [%1] from [%2] without output "
314 "pixel range").arg(newFile.original()).arg(fileName());
315 throw IException(IException::User, msg, _FILEINFO_);
316 }
317 }
318 else {
319 // Not propagating so either the user entered or the programmer did
320 result->setMinMax(newFileAttributes.minimum(), newFileAttributes.maximum());
321 }
322
323 result->setLabelSize(labelSize(true) + (1024 * 6));
324 }
325 else {
326 if (isReadWrite()) {
327 writeLabels();
328 m_ioHandler->clearCache(true);
329 }
330
331 result->setExternalDnData(fileName());
332 }
333
334 // Allocate the cube
335 result->create(newFile.expanded());
336
337 PvlObject &isisCube = label()->findObject("IsisCube");
338 PvlObject &outIsisCube = result->label()->findObject("IsisCube");
339 for(int i = 0; i < isisCube.groups(); i++) {
340 outIsisCube.addGroup(isisCube.group(i));
341 }
342
343 if (label()->hasObject("NaifKeywords")) {
344 result->label()->addObject(
345 label()->findObject("NaifKeywords"));
346 }
347
348 for (int i = 0; i < m_label->objects(); i++) {
349 PvlObject &obj = m_label->object(i);
350 if (obj.isNamed("Table") || obj.isNamed("Polygon") || obj.isNamed("OriginalLabel") ||
351 obj.isNamed("History")) {
352 Isis::Blob t((QString)obj["Name"], obj.name());
353 read(t);
354 result->write(t);
355 }
356 }
357
358 if (newFileAttributes.labelAttachment() != ExternalLabel) {
360 sampleCount(), 1, 1,
361 pixelType());
363 sampleCount(), 1, 1,
364 result->pixelType());
365
366 input.begin();
367 output.begin();
368
369 while (!input.end()) {
370 read(input);
371 output.Copy(input, false);
372
373 result->write(output);
374
375 input.next();
376 output.next();
377 }
378 }
379
380// Just in case the orig label doesn't work... here's original code:
381// if((p_propagateOriginalLabel) && (InputCubes.size() > 0)) {
382// Isis::Pvl &inlab = *InputCubes[0]->label();
383// for(int i = 0; i < inlab.objects(); i++) {
384// if(inlab.Object(i).isNamed("OriginalLabel")) {
385// Isis::OriginalLabel ol;
386// InputCubes[0]->read(ol);
387// cube->write(ol);
388// }
389// }
390// }
391
392 return result;
393 }
394
395
416 void Cube::create(const QString &cubeFileName) {
417 // Already opened?
418 if (isOpen()) {
419 string msg = "You already have a cube opened";
420 throw IException(IException::Programmer, msg, _FILEINFO_);
421 }
422
423 if (m_samples < 1 || m_lines < 1 || m_bands < 1) {
424 QString msg = "Number of samples [" + toString(m_samples) +
425 "], lines [" + toString(m_lines) + "], or bands [" + toString(m_bands) +
426 "] cannot be less than 1";
427 throw IException(IException::Programmer, msg, _FILEINFO_);
428 }
429
430 if (m_pixelType == None) {
432 QString("Cannot create the cube [%1] with a pixel type set to None")
433 .arg(cubeFileName),
434 _FILEINFO_);
435 }
436
437 if (m_storesDnData) {
438 // Make sure the cube is not going to exceed the maximum size preference
439 BigInt size = (BigInt)m_samples * m_lines *
441
442 size = size / 1024; // kb
443 size = size / 1024; // mb
444 size = size / 1024; // gb
445
446 int maxSizePreference = 0;
447
448 maxSizePreference =
449 Preference::Preferences().findGroup("CubeCustomization")["MaximumSize"];
450
451 if (size > maxSizePreference) {
452 QString msg;
453 msg += "The cube you are attempting to create [" + cubeFileName + "] is ["
454 + toString(size) + "GB]. This is larger than the current allowed "
455 "size of [" + toString(maxSizePreference) + "GB]. The cube "
456 "dimensions were (S,L,B) [" + toString(m_samples) + ", " +
457 toString(m_lines) + ", " + toString(m_bands) + "] with [" +
458 toString(SizeOf(m_pixelType)) + "] bytes per pixel. If you still "
459 "wish to create this cube, the maximum value can be changed in your personal "
460 "preference file located in [~/.Isis/IsisPreferences] within the group "
461 "CubeCustomization, keyword MaximumSize. If you do not have an ISISPreference file, "
462 "please refer to the documentation 'Environment and Preference Setup'. Error ";
463 throw IException(IException::User, msg, _FILEINFO_);
464 }
465 }
466
467 // Expand output name
468 FileName cubFile(cubeFileName);
469 PvlObject isiscube("IsisCube");
470 PvlObject core("Core");
471
472 if (m_storesDnData) {
473 cubFile = cubFile.addExtension("cub");
474
475 // See if we have attached or detached labels
476 if (m_attached) {
477 // StartByte is 1-based (why!!) so we need to do + 1
478 core += PvlKeyword("StartByte", toString(m_labelBytes + 1));
479 m_labelFileName = new FileName(cubFile);
480 m_dataFileName = new FileName(cubFile);
481 m_labelFile = new QFile(m_labelFileName->expanded());
482 }
483 else {
484 core += PvlKeyword("StartByte", toString(1));
485 core += PvlKeyword("^Core", cubFile.name());
486 m_dataFileName = new FileName(cubFile);
487 m_dataFile = new QFile(realDataFileName().expanded());
488
489 FileName labelFileName(cubFile);
490 labelFileName = labelFileName.setExtension("lbl");
491 m_labelFileName = new FileName(labelFileName);
492 m_labelFile = new QFile(m_labelFileName->expanded());
493 }
494
495 // Create the size of the core
496 PvlGroup dims("Dimensions");
497 dims += PvlKeyword("Samples", toString(m_samples));
498 dims += PvlKeyword("Lines", toString(m_lines));
499 dims += PvlKeyword("Bands", toString(m_bands));
500 core.addGroup(dims);
501
502 // Create the pixel type
503 PvlGroup ptype("Pixels");
504 ptype += PvlKeyword("Type", PixelTypeName(m_pixelType));
505
506 // And the byte ordering
507 ptype += PvlKeyword("ByteOrder", ByteOrderName(m_byteOrder));
508 ptype += PvlKeyword("Base", toString(m_base));
509 ptype += PvlKeyword("Multiplier", toString(m_multiplier));
510 core.addGroup(ptype);
511 }
512 else {
513 cubFile = cubFile.addExtension("ecub");
514
515 core += PvlKeyword("^DnFile", m_dataFileName->original());
516// m_dataFileName = new FileName(cubFile);
517 m_dataFile = new QFile(realDataFileName().expanded());
518
519 m_labelFileName = new FileName(cubFile);
520 m_labelFile = new QFile(cubFile.expanded());
521 }
522
523 isiscube.addObject(core);
524
525 m_label = new Pvl;
526 m_label->addObject(isiscube);
527
528 // Setup storage reserved for the label
529 PvlObject lbl("Label");
530 lbl += PvlKeyword("Bytes", toString(m_labelBytes));
531 m_label->addObject(lbl);
532
533 const PvlGroup &pref =
534 Preference::Preferences().findGroup("CubeCustomization");
535 bool overwrite = pref["Overwrite"][0].toUpper() == "ALLOW";
536 if (!overwrite && m_labelFile->exists() && m_labelFile->size()) {
537 QString msg = "Cube file [" + m_labelFileName->original() + "] exists, " +
538 "user preference does not allow overwrite";
539 throw IException(IException::User, msg, _FILEINFO_);
540 }
541
542 if (!m_labelFile->open(QIODevice::Truncate | QIODevice::ReadWrite)) {
543 QString msg = "Failed to create [" + m_labelFile->fileName() + "]. ";
544 msg += "Verify the output path exists and you have permission to write to the path.";
545 cleanUp(false);
546 throw IException(IException::Io, msg, _FILEINFO_);
547 }
548
549 if (m_dataFile) {
550 if (m_storesDnData && !m_dataFile->open(QIODevice::Truncate | QIODevice::ReadWrite)) {
551 QString msg = "Failed to create [" + m_dataFile->fileName() + "]. ";
552 msg += "Verify the output path exists and you have permission to write to the path.";
553 cleanUp(false);
554 throw IException(IException::Io, msg, _FILEINFO_);
555 }
556 else if (!m_storesDnData && !m_dataFile->open(QIODevice::ReadOnly)) {
557 QString msg = "Failed to open [" + m_dataFile->fileName() + "] for reading. ";
558 msg += "Verify the output path exists and you have permission to read from the path.";
559 cleanUp(false);
560 throw IException(IException::Io, msg, _FILEINFO_);
561 }
562 }
563
564 bool dataAlreadyOnDisk = m_storesDnData ? false : true;
565
566 if (m_format == Bsq) {
568 dataAlreadyOnDisk);
569 }
570 else {
572 dataAlreadyOnDisk);
573 }
574
575 if (m_storesDnData)
576 m_ioHandler->updateLabels(*m_label);
577
578 // Write the labels
579 writeLabels();
580 }
581
582
605 const QString &cubeFileName, const CubeAttributeOutput &att) {
606
607 setByteOrder(att.byteOrder());
608 setFormat(att.fileFormat());
609 setLabelsAttached(att.labelAttachment() == AttachedLabel);
610 if (!att.propagatePixelType())
611 setPixelType(att.pixelType());
612 setMinMax(att.minimum(), att.maximum());
613
614 // Allocate the cube
615 create(cubeFileName);
616 }
617
618
629 void Cube::open(const QString &cubeFileName, QString access) {
630
631 // Already opened?
632 if (isOpen()) {
633 string msg = "You already have a cube opened";
634 throw IException(IException::Programmer, msg, _FILEINFO_);
635 }
636
637 initLabelFromFile(cubeFileName, (access == "rw"));
638
639 try {
640 Isis::CubeAttributeInput att(cubeFileName);
641 if(att.bands().size() != 0) {
642 vector<QString> bands = att.bands();
643 setVirtualBands(bands);
644 }
645 } catch(IException& e) {
646 // Either the cube is an output cube that has already been opened or
647 // there is an exception parsing and adding an attribute
648 }
649
650 // Figure out the name of the data file
651 try {
652 PvlObject &core = m_label->findObject("IsisCube").findObject("Core");
653 // Detached labels
654 if (core.hasKeyword("^Core")) {
655 FileName temp(core["^Core"][0]);
656
657 if (!temp.originalPath().startsWith("/")) {
658 m_dataFileName = new FileName(m_labelFileName->path() + "/" + temp.original());
659 }
660 else {
661 m_dataFileName = new FileName(temp);
662 }
663
664 m_attached = false;
665 m_storesDnData = true;
666
667 m_dataFile = new QFile(realDataFileName().expanded());
668 }
669 // External cube files (ecub), ecub contains all labels and SPICE blobs, history
670 else if (core.hasKeyword("^DnFile")) {
671 FileName dataFileName(core["^DnFile"][0]);
672
673 if (dataFileName.originalPath() == ".") {
674 m_dataFileName = new FileName(m_labelFileName->path() + "/" + dataFileName.name());
675 }
676 else {
677 m_dataFileName = new FileName(dataFileName);
678 }
679
680 m_attached = true;
681 m_storesDnData = false;
683 m_dataFile = new QFile(realDataFileName().expanded());
684 }
685 // Typical cube containing labels, SPICE, history and dn data
686 else {
688 m_attached = true;
689 m_storesDnData = true;
690 }
691 }
692 catch (IException &e) {
693 cleanUp(false);
694 throw;
695 }
696
697 if (access == "r") {
698 if (!m_labelFile->open(QIODevice::ReadOnly)) {
699 QString msg = "Failed to open [" + m_labelFile->fileName() + "] with "
700 "read only access";
701 cleanUp(false);
702 throw IException(IException::Io, msg, _FILEINFO_);
703 }
704
705 if (m_dataFile) {
706 if (!m_dataFile->open(QIODevice::ReadOnly)) {
707 QString msg = "Failed to open [" + m_dataFile->fileName() + "] with "
708 "read only access";
709 cleanUp(false);
710 throw IException(IException::Io, msg, _FILEINFO_);
711 }
712 }
713 }
714
715 else if (access == "rw") {
716 if (!m_labelFile->open(QIODevice::ReadWrite)) {
717 QString msg = "Failed to open [" + m_labelFile->fileName() + "] with "
718 "read/write access";
719 cleanUp(false);
720 throw IException(IException::Io, msg, _FILEINFO_);
721 }
722
723 if (m_dataFile) {
724 if (m_storesDnData && !m_dataFile->open(QIODevice::ReadWrite)) {
725 QString msg = "Failed to open [" + m_dataFile->fileName() + "] with "
726 "read/write access";
727 cleanUp(false);
728 throw IException(IException::Io, msg, _FILEINFO_);
729 }
730 else if (!m_storesDnData && !m_dataFile->open(QIODevice::ReadOnly)) {
731 QString msg = "Failed to open [" + m_dataFile->fileName() + "] with "
732 "read access";
733 cleanUp(false);
734 throw IException(IException::Io, msg, _FILEINFO_);
735 }
736 }
737 }
738 else {
739 QString msg = "Unknown value for access [" + access + "]. Expected 'r' "
740 " or 'rw'";
741 cleanUp(false);
742 throw IException(IException::Programmer, msg, _FILEINFO_);
743 }
744
746
747 // Determine the number of bytes in the label
748 if (m_attached) {
749 m_labelBytes = m_label->findObject("Label")["Bytes"];
750 }
751 else {
752 m_labelBytes = labelSize(true);
753 }
754
755 QPair<bool, Pvl *> dataLabel = qMakePair(false, m_label);
756 if (!m_storesDnData) {
757 dataLabel = qMakePair(true, new Pvl(m_dataFileName->expanded()));
758 }
759
760 // Now examine the format to see which type of handler to create
761 if (m_format == Bsq) {
763 realDataFileLabel(), true);
764 }
765 else {
767 realDataFileLabel(), true);
768 }
769
770 if (dataLabel.first) {
771 delete dataLabel.second;
772 dataLabel.second = NULL;
773 }
774
776 }
777
778
787 void Cube::reopen(QString access) {
788 if (!m_labelFile) {
789 QString msg = "Cube has not been opened yet. The filename to re-open is "
790 "unknown";
791 throw IException(IException::Programmer, msg, _FILEINFO_);
792 }
793
794 // Preserve filename and virtual bands when re-opening
795 FileName filename = *m_labelFileName;
796 QList<int> virtualBandList;
797
799 virtualBandList = *m_virtualBandList;
800
801 close();
802 open(filename.expanded(), access);
803
804 if (virtualBandList.size()) {
806 *m_virtualBandList = virtualBandList;
807 else
808 m_virtualBandList = new QList<int>(virtualBandList);
809 }
810 }
811
812
820 void Cube::read(Blob &blob, const std::vector<PvlKeyword> keywords) const {
821 if (!isOpen()) {
822 string msg = "The cube is not opened so you can't read a blob from it";
823 throw IException(IException::Programmer, msg, _FILEINFO_);
824 }
825
826 FileName cubeFile = *m_labelFileName;
827 if (m_tempCube)
828 cubeFile = *m_tempCube;
829
830 QMutexLocker locker(m_mutex);
831 QMutexLocker locker2(m_ioHandler->dataFileMutex());
832 blob.Read(cubeFile.toString(), *label(), keywords);
833 }
834
835
842 void Cube::read(Buffer &bufferToFill) const {
843 if (!isOpen()) {
844 string msg = "Try opening a file before you read it";
845 throw IException(IException::Programmer, msg, _FILEINFO_);
846 }
847
848 QMutexLocker locker(m_mutex);
849 m_ioHandler->read(bufferToFill);
850 }
851
852
860 History Cube::readHistory(const QString &name) const {
861 Blob historyBlob(name, "History");
862 try {
863 // read history from cube, if it exists.
864 read(historyBlob);
865 }
866 catch (IException &) {
867 // if the history does not exist in the cube, this function creates it.
868 }
869 History history(historyBlob);
870 return history;
871 }
872
873
880 Blob footprintBlob("Footprint", "Polygon");
881 try {
882 // read history from cube, if it exists.
883 read(footprintBlob);
884 }
885 catch (IException &e) {
886 QString msg = "Footprintinit must be run prior to reading the footprint";
887 msg += " with POLYGON=TRUE for cube [" + fileName() + "]";
888 throw IException(e, IException::User, msg, _FILEINFO_);
889 }
890 ImagePolygon footprint(footprintBlob);
891 return footprint;
892 }
893
894
902 OriginalLabel Cube::readOriginalLabel(const QString &name) const {
903 Blob origLabelBlob(name, "OriginalLabel");
904 try {
905 read(origLabelBlob);
906 }
907 catch (IException &e){
908 QString msg = "Unable to locate OriginalLabel in " + fileName();
909 throw IException(e, IException::User, msg, _FILEINFO_);
910 }
911 OriginalLabel origLabel(origLabelBlob);
912 return origLabel;
913 }
914
915
925 CubeStretch Cube::readCubeStretch(QString name, const std::vector<PvlKeyword> keywords) const {
926 Blob stretchBlob(name, "Stretch");
927 try {
928 read(stretchBlob, keywords);
929 }
930 catch (IException &e){
931 QString msg = "Unable to locate Stretch information in " + fileName();
932 throw IException(e, IException::User, msg, _FILEINFO_);
933 }
934 CubeStretch cubeStretch(stretchBlob);
935 return stretchBlob;
936 }
937
938
945 Blob origXmlLabelBlob("IsisCube", "OriginalXmlLabel");
946 try {
947 read(origXmlLabelBlob);
948 }
949 catch (IException &e){
950 QString msg = "Unable to locate OriginalXmlLabel in " + fileName();
951 throw IException(e, IException::User, msg, _FILEINFO_);
952 }
953 OriginalXmlLabel origXmlLabel(origXmlLabelBlob);
954 return origXmlLabel;
955 }
956
957
965 Table Cube::readTable(const QString &name) {
966 Blob tableBlob(name, "Table");
967 try {
968 read(tableBlob);
969 }
970 catch (IException &e) {
971 QString msg = "Failed to read table [" + name + "] from cube [" + fileName() + "].";
972 throw IException(e, IException::Programmer, msg, _FILEINFO_);
973 }
974 return Table(tableBlob);
975 }
976
977
984 void Cube::write(Blob &blob, bool overwrite) {
985 if (!isOpen()) {
986 string msg = "The cube is not opened so you can't write a blob to it";
987 throw IException(IException::Programmer, msg, _FILEINFO_);
988 }
989
990 if (!m_labelFile->isWritable()) {
991 string msg = "The cube must be opened in read/write mode, not readOnly";
992 throw IException(IException::Programmer, msg, _FILEINFO_);
993 }
994
995 // Write an attached blob
996 if (m_attached) {
997 QMutexLocker locker(m_mutex);
998 QMutexLocker locker2(m_ioHandler->dataFileMutex());
999
1000 // Compute the number of bytes in the cube + label bytes and if the
1001 // endpos of the file // is not greater than this then seek to that position.
1002 fstream stream(m_labelFileName->expanded().toLatin1().data(),
1003 ios::in | ios::out | ios::binary);
1004 stream.seekp(0, ios::end);
1005
1006 // End byte = end byte of the file (aka eof position, file size)
1007 streampos endByte = stream.tellp();
1008 // maxbyte = position after the cube DN data and labels
1009 streampos maxbyte = (streampos) m_labelBytes;
1010
1011 if (m_storesDnData) {
1012 maxbyte += (streampos) m_ioHandler->getDataSize();
1013 }
1014
1015 // If EOF is too early, allocate space up to where we want the blob
1016 if (endByte < maxbyte) {
1017 stream.seekp(maxbyte, ios::beg);
1018 }
1019
1020 // Use default argument of "" for detached stream
1021 blob.Write(*m_label, stream, "", overwrite);
1022 }
1023
1024 // Write a detached blob
1025 else {
1026 FileName blobFileName = fileName();
1027 blobFileName = blobFileName.removeExtension();
1028 blobFileName = blobFileName.addExtension(blob.Type());
1029 blobFileName = blobFileName.addExtension(blob.Name());
1030 QString blobFile(blobFileName.expanded());
1031 ios::openmode flags = ios::in | ios::binary | ios::out | ios::trunc;
1032 fstream detachedStream;
1033 detachedStream.open(blobFile.toLatin1().data(), flags);
1034 if (!detachedStream) {
1035 QString message = "Unable to open data file [" +
1036 blobFileName.expanded() + "]";
1037 throw IException(IException::Io, message, _FILEINFO_);
1038 }
1039
1040 blob.Write(*m_label, detachedStream, blobFileName.name());
1041 }
1042 }
1043
1044
1052 Blob labelBlob = lab.toBlob();
1053 write(labelBlob);
1054 }
1055
1056
1064 Blob labelBlob = lab.toBlob();
1065 write(labelBlob);
1066 }
1067
1068
1077 void Cube::write(const Table &table) {
1078 Blob tableBlob = table.toBlob();
1079 write(tableBlob);
1080 }
1081
1082
1091 void Cube::write(const CubeStretch &cubeStretch) {
1092 Blob cubeStretchBlob = cubeStretch.toBlob();
1093 write(cubeStretchBlob);
1094 }
1095
1096
1107 void Cube::write(History &history, const QString &name) {
1108 Blob histBlob = history.toBlob(name);
1109 write(histBlob);
1110 }
1111
1112
1119 void Cube::write(const ImagePolygon &polygon) {
1120 Blob polyBlob = polygon.toBlob();
1121 write(polyBlob);
1122 }
1123
1124
1131 void Cube::write(Buffer &bufferToWrite) {
1132 if (!isOpen()) {
1133 string msg = "Tried to write to a cube before opening/creating it";
1134 throw IException(IException::Programmer, msg, _FILEINFO_);
1135 }
1136
1137 if (isReadOnly()) {
1138 QString msg = "Cannot write to the cube [" + (QString)QFileInfo(fileName()).fileName() +
1139 "] because it is opened read-only";
1140 throw IException(IException::Programmer, msg, _FILEINFO_);
1141 }
1142
1143 if (!m_storesDnData) {
1144 QString msg = "The cube [" + QFileInfo(fileName()).fileName() +
1145 "] does not support storing DN data because it is using an external file for DNs";
1146 throw IException(IException::Unknown, msg, _FILEINFO_);
1147 }
1148
1149 QMutexLocker locker(m_mutex);
1150 m_ioHandler->write(bufferToWrite);
1151 }
1152
1153
1164 void Cube::setBaseMultiplier(double base, double mult) {
1165 openCheck();
1166 m_base = base;
1167 m_multiplier = mult;
1168 }
1169
1170
1181 void Cube::setMinMax(double min, double max) {
1182 openCheck();
1183
1184 m_base = 0.0;
1185 m_multiplier = 1.0;
1186
1187 double x1, x2;
1188 if (m_pixelType == UnsignedByte) {
1189 x1 = VALID_MIN1;
1190 x2 = VALID_MAX1;
1191 m_multiplier = (max - min) / (x2 - x1);
1192 m_base = min - m_multiplier * x1;
1193 }
1194 else if (m_pixelType == SignedWord) {
1195 x1 = VALID_MIN2;
1196 x2 = VALID_MAX2;
1197 m_multiplier = (max - min) / (x2 - x1);
1198 m_base = min - m_multiplier * x1;
1199 }
1200 else if (m_pixelType == UnsignedWord) {
1201 x1 = VALID_MINU2;
1202 x2 = VALID_MAXU2;
1203 m_multiplier = (max - min) / (x2 - x1);
1204 m_base = min - m_multiplier * x1;
1205 }
1206 }
1207
1208
1219
1220
1230 void Cube::setDimensions(int ns, int nl, int nb) {
1231 openCheck();
1232 if ((ns < 1) || (nl < 1) || (nb < 1)) {
1233 string msg = "SetDimensions: Invalid number of sample, lines or bands";
1234 throw IException(IException::Programmer, msg, _FILEINFO_);
1235 }
1236 m_samples = ns;
1237 m_lines = nl;
1238 m_bands = nb;
1239 }
1240
1241
1247 void Cube::setExternalDnData(FileName cubeFileWithDnData) {
1248 try {
1249 initLabelFromFile(cubeFileWithDnData, false);
1251
1252 delete m_label;
1253 m_label = NULL;
1254 }
1255 catch (IException &) {
1256 delete m_label;
1257 m_label = NULL;
1258 throw;
1259 }
1260
1261 m_storesDnData = false;
1262 m_dataFileName = new FileName(cubeFileWithDnData);
1263
1264 delete m_labelFile;
1265 m_labelFile = NULL;
1266
1267 delete m_labelFileName;
1268 m_labelFileName = NULL;
1269 }
1270
1271
1280 openCheck();
1281 m_format = format;
1282 }
1283
1284
1291 void Cube::setLabelsAttached(bool attach) {
1292 openCheck();
1293 m_attached = attach;
1294 }
1295
1296
1304 void Cube::setLabelSize(int labelBytes) {
1305 openCheck();
1306 m_labelBytes = labelBytes;
1307 }
1308
1309
1321
1322
1335 openCheck();
1337 m_virtualBandList->clear();
1338 else
1340
1341 if (vbands.size() > 0) {
1342 QListIterator<QString> it(vbands);
1343 while (it.hasNext()) {
1344 m_virtualBandList->append(toInt(it.next()));
1345 }
1346 }
1347 else {
1348 delete m_virtualBandList;
1349 m_virtualBandList = NULL;
1350 }
1351
1352 if (m_ioHandler) {
1353 m_ioHandler->setVirtualBands(m_virtualBandList);
1354 }
1355 }
1356
1357
1364 void Cube::setVirtualBands(const std::vector<QString> &vbands) {
1365 QList<QString> realVBands;
1366
1367 for(unsigned int i = 0; i < vbands.size(); i++)
1368 realVBands << vbands[i];
1369
1370 setVirtualBands(realVBands);
1371 }
1372
1373
1380 if (!isOpen()) {
1382 QString("Cannot relocate the DN data to [%1] for an external cube label "
1383 "file which is not open.")
1384 .arg(dnDataFile.original()),
1385 _FILEINFO_);
1386 }
1387
1388
1389 if (m_storesDnData) {
1391 QString("The cube [%1] stores DN data. It cannot be relocated to [%2] - "
1392 "this is only supported for external cube label files.")
1393 .arg(m_labelFileName->original()).arg(dnDataFile.original()),
1394 _FILEINFO_);
1395 }
1396
1397 m_label->findObject("IsisCube").findObject("Core").findKeyword("^DnFile")[0] =
1398 dnDataFile.original();
1399 reopen(m_labelFile->isWritable()? "rw" : "r");
1400 }
1401
1402
1403// void Cube::relocateDnData(FileName externalLabelFile, FileName dnDataFile) {
1404// try {
1405// Pvl externalLabelData(externalLabelFile.expanded());
1406// externalLabelData.FindObject("IsisCube").FindObject("Core").FindKeyword("^DnFile")[0] =
1407// dnDataFile.original();
1408// }
1409// catch (IException &e) {
1410// throw IException(e, IException::Io,
1411// QString("File [%1] does not appear to be an external cube label file")
1412// .arg(externalLabelFile.original().ToQt()),
1413// _FILEINFO_);
1414// }
1415// }
1416
1417
1423 int Cube::bandCount() const {
1424 int numBands = m_bands;
1426 numBands = m_virtualBandList->size();
1427 return numBands;
1428 }
1429
1430
1440 double Cube::base() const {
1441 return m_base;
1442 }
1443
1444
1453 return m_byteOrder;
1454 }
1455
1456
1465 if (m_camera == NULL && isOpen()) {
1467 }
1468 return m_camera;
1469 }
1470
1471
1472 void Cube::attachSpiceFromIsd(nlohmann::json isd) {
1473 PvlKeyword lkKeyword("LeapSecond");
1474 PvlKeyword pckKeyword("TargetAttitudeShape");
1475 PvlKeyword targetSpkKeyword("TargetPosition");
1476 PvlKeyword ckKeyword("InstrumentPointing");
1477 PvlKeyword ikKeyword("Instrument");
1478 PvlKeyword sclkKeyword("SpacecraftClock");
1479 PvlKeyword spkKeyword("InstrumentPosition");
1480 PvlKeyword iakKeyword("InstrumentAddendum");
1481 PvlKeyword demKeyword("ShapeModel");
1482 PvlKeyword exkKeyword("Extra");
1483
1484 Spice spice(*this->label(), isd);
1485 Table ckTable = spice.instrumentRotation()->Cache("InstrumentPointing");
1486 ckTable.Label() += PvlKeyword("Kernels");
1487
1488 for (int i = 0; i < ckKeyword.size(); i++)
1489 ckTable.Label()["Kernels"].addValue(ckKeyword[i]);
1490
1491 this->write(ckTable);
1492
1493 Table spkTable = spice.instrumentPosition()->Cache("InstrumentPosition");
1494 spkTable.Label() += PvlKeyword("Kernels");
1495 for (int i = 0; i < spkKeyword.size(); i++)
1496 spkTable.Label()["Kernels"].addValue(spkKeyword[i]);
1497
1498 this->write(spkTable);
1499
1500 Table bodyTable = spice.bodyRotation()->Cache("BodyRotation");
1501 bodyTable.Label() += PvlKeyword("Kernels");
1502 for (int i = 0; i < targetSpkKeyword.size(); i++)
1503 bodyTable.Label()["Kernels"].addValue(targetSpkKeyword[i]);
1504
1505 for (int i = 0; i < pckKeyword.size(); i++)
1506 bodyTable.Label()["Kernels"].addValue(pckKeyword[i]);
1507
1508 bodyTable.Label() += PvlKeyword("SolarLongitude",
1509 toString(spice.solarLongitude().degrees()));
1510 this->write(bodyTable);
1511
1512 Table sunTable = spice.sunPosition()->Cache("SunPosition");
1513 sunTable.Label() += PvlKeyword("Kernels");
1514 for (int i = 0; i < targetSpkKeyword.size(); i++)
1515 sunTable.Label()["Kernels"].addValue(targetSpkKeyword[i]);
1516
1517 this->write(sunTable);
1518
1519 PvlGroup currentKernels = this->group("Kernels");
1520
1521 Pvl *label = this->label();
1522 int i = 0;
1523 while (i < label->objects()) {
1524 PvlObject currObj = label->object(i);
1525 if (currObj.isNamed("NaifKeywords")) {
1526 label->deleteObject(i);
1527 }
1528 else {
1529 i ++;
1530 }
1531 }
1532
1533 *(this->label()) += spice.getStoredNaifKeywords();
1534
1535 // Access the camera here while all of the kernels are still loaded.
1536 // This needs to be done for some cameras that need loaded spice data
1537 // to actually create the camera model. (KaguyaTC for example)
1538 this->camera();
1539 }
1540
1541 void Cube::attachLineScanTableFromIsd(nlohmann::json isd) {
1542 TableField ephTimeField("EphemerisTime", TableField::Double);
1543 TableField expTimeField("ExposureTime", TableField::Double);
1544 TableField lineStartField("LineStart", TableField::Integer);
1545
1546 TableRecord timesRecord;
1547 timesRecord += ephTimeField;
1548 timesRecord += expTimeField;
1549 timesRecord += lineStartField;
1550
1551 Table timesTable("LineScanTimes", timesRecord);
1552 for (size_t i = 0; i < isd["line_scan_rate"].size(); ++i) {
1553 timesRecord[0] = isd["line_scan_rate"][i][1].get<double>() + isd["center_ephemeris_time"].get<double>();
1554 timesRecord[1] = isd["line_scan_rate"][i][2].get<double>();
1555 timesRecord[2] = (int)(isd["line_scan_rate"][i][0].get<double>() + 0.5);
1556 timesTable += timesRecord;
1557 }
1558 this->write(timesTable);
1559 }
1560
1561
1569 if (!isOpen()) {
1571 "An external cube label file must be opened in order to use "
1572 "Cube::getExternalCubeFileName",
1573 _FILEINFO_);
1574 }
1575
1576 if (storesDnData()) {
1578 "Cube::getExternalCubeFileName can only be called on an external cube label "
1579 "file",
1580 _FILEINFO_);
1581 }
1582
1583
1584 PvlObject &core = m_label->findObject("IsisCube").findObject("Core");
1585
1586 return core["^DnFile"][0];
1587 }
1588
1589
1596 QString Cube::fileName() const {
1597 if (isOpen())
1598 return m_labelFileName->expanded();
1599 else
1600 return "";
1601 }
1602
1603
1609 return m_format;
1610 }
1611
1612
1632 Histogram *Cube::histogram(const int &band, QString msg) {
1633 return histogram(band, ValidMinimum, ValidMaximum, msg);
1634 }
1635
1636
1662 Histogram *Cube::histogram(const int &band, const double &validMin,
1663 const double &validMax, QString msg) {
1664 // Make sure cube is open
1665 if ( !isOpen() ) {
1666 QString msg = "Cannot create histogram object for an unopened cube";
1667 throw IException(IException::Programmer, msg, _FILEINFO_);
1668 }
1669
1670 // Make sure band is valid
1671 if ((band < 0) || (band > bandCount())) {
1672 QString msg = "Invalid band in [CubeInfo::Histogram]";
1673 throw IException(IException::Programmer, msg, _FILEINFO_);
1674 }
1675
1676 int bandStart = band;
1677 int bandStop = band;
1678 int maxSteps = lineCount();
1679 if (band == 0) {
1680 bandStart = 1;
1681 bandStop = bandCount();
1682 maxSteps = lineCount() * bandCount();
1683 }
1684
1685 Progress progress;
1686 Histogram *hist = new ImageHistogram(*this, band, &progress);
1687 LineManager line(*this);
1688
1689 // This range is for throwing out data; the default parameters are OK always
1690 //hist->SetValidRange(validMin, validMax);
1691
1692 // We now need to know the binning range - ValidMinimum/Maximum are no longer
1693 // acceptable, default to the bin range start/end.
1694 double binMin = validMin;
1695 double binMax = validMax;
1696 if (binMin == ValidMinimum) {
1697 binMin = hist->BinRangeStart();
1698 }
1699
1700 if (binMax == ValidMaximum) {
1701 binMax = hist->BinRangeEnd();
1702 }
1703
1704 //hist->SetBinRange(binMin, binMax);
1705 hist->SetValidRange(binMin,binMax);
1706
1707 // Loop and get the histogram
1708 progress.SetText(msg);
1709 progress.SetMaximumSteps(maxSteps);
1710 progress.CheckStatus();
1711
1712 for(int useBand = bandStart ; useBand <= bandStop ; useBand++) {
1713 for(int i = 1; i <= lineCount(); i++) {
1714 line.SetLine(i, useBand);
1715 read(line);
1716 hist->AddData(line.DoubleBuffer(), line.size());
1717 progress.CheckStatus();
1718 }
1719 }
1720
1721 return hist;
1722 }
1723
1724
1734 Pvl *Cube::label() const {
1735 return m_label;
1736 }
1737
1738
1746 int Cube::labelSize(bool actual) const {
1747 int labelSize = m_labelBytes;
1748
1749 if (actual && m_label) {
1750 ostringstream s;
1751 s << *m_label << endl;
1752 labelSize = s.tellp();
1753 }
1754 else if (actual) {
1755 labelSize = 0;
1756 }
1757
1758 return labelSize;
1759 }
1760
1761
1767 int Cube::lineCount() const {
1768 return m_lines;
1769 }
1770
1771
1781 double Cube::multiplier() const {
1782 return m_multiplier;
1783 }
1784
1785
1792 return m_pixelType;
1793 }
1794
1795
1806 int Cube::physicalBand(const int &virtualBand) const {
1807 int physicalBand = virtualBand;
1808
1809 if (m_virtualBandList) {
1810 if ((virtualBand < 1) ||
1811 (virtualBand > m_virtualBandList->size())) {
1812 QString msg = "Out of array bounds [" + toString(virtualBand) + "]";
1813 throw IException(IException::Programmer, msg, _FILEINFO_);
1814 }
1815 physicalBand = m_virtualBandList->at(virtualBand - 1);
1816 }
1817
1818 return physicalBand;
1819 }
1820
1821
1828 if (m_projection == NULL && isOpen()) {
1830 }
1831 return m_projection;
1832 }
1833
1834
1840 int Cube::sampleCount() const {
1841 return m_samples;
1842 }
1843
1844
1863 Statistics *Cube::statistics(const int &band, QString msg) {
1864 return statistics(band, ValidMinimum, ValidMaximum, msg);
1865 }
1866
1867
1884 Statistics *Cube::statistics(const int &band, const double &validMin,
1885 const double &validMax, QString msg) {
1886 // Make sure cube is open
1887 if ( !isOpen() ) {
1888 QString msg = "Cannot create statistics object for an unopened cube";
1889 throw IException(IException::Programmer, msg, _FILEINFO_);
1890 }
1891
1892 // Make sure band is valid
1893 if ((band < 0) || (band > bandCount())) {
1894 string msg = "Invalid band in [CubeInfo::Statistics]";
1895 throw IException(IException::Programmer, msg, _FILEINFO_);
1896 }
1897
1898 // Construct a line buffer manager and a statistics object
1899 LineManager line(*this);
1900 Statistics *stats = new Statistics();
1901
1902 stats->SetValidRange(validMin, validMax);
1903
1904 int bandStart = band;
1905 int bandStop = band;
1906 int maxSteps = lineCount();
1907 if (band == 0) {
1908 bandStart = 1;
1909 bandStop = bandCount();
1910 maxSteps = lineCount() * bandCount();
1911 }
1912
1913 Progress progress;
1914 progress.SetText(msg);
1915 progress.SetMaximumSteps(maxSteps);
1916 progress.CheckStatus();
1917
1918 // Loop and get the statistics for a good minimum/maximum
1919 for(int useBand = bandStart ; useBand <= bandStop ; useBand++) {
1920 for(int i = 1; i <= lineCount(); i++) {
1921 line.SetLine(i, useBand);
1922 read(line);
1923 stats->AddData(line.DoubleBuffer(), line.size());
1924 progress.CheckStatus();
1925 }
1926 }
1927
1928 return stats;
1929 }
1930
1931
1937 bool Cube::storesDnData() const {
1938 return m_storesDnData;
1939 }
1940
1941
1956
1957 if (isOpen() && m_ioHandler) {
1958 m_ioHandler->addCachingAlgorithm(algorithm);
1959 }
1960 else if (!isOpen()) {
1961 QString msg = "Cannot add a caching algorithm until the cube is open";
1962 throw IException(IException::Programmer, msg, _FILEINFO_);
1963 }
1964 }
1965
1972 if (m_ioHandler) {
1973 QMutexLocker locker(m_mutex);
1974 m_ioHandler->clearCache();
1975 }
1976 }
1977
1978
1988 bool Cube::deleteBlob(QString BlobName, QString BlobType) {
1989 for(int i = 0; i < m_label->objects(); i++) {
1990 PvlObject obj = m_label->object(i);
1991 if (obj.name().compare(BlobType) == 0) {
1992 if (obj.findKeyword("Name")[0] == BlobName) {
1993 m_label->deleteObject(i);
1994 return true;
1995 }
1996 }
1997 }
1998 return false;
1999 }
2000
2001
2010 void Cube::deleteGroup(const QString &group) {
2011 PvlObject &isiscube = label()->findObject("IsisCube");
2012 if (!isiscube.hasGroup(group)) return;
2013 isiscube.deleteGroup(group);
2014 }
2015
2016
2024 PvlGroup &Cube::group(const QString &group) const {
2025 PvlObject &isiscube = label()->findObject("IsisCube");
2026 return isiscube.findGroup(group);
2027 }
2028
2029
2037 bool Cube::hasGroup(const QString &group) const {
2038 const PvlObject &isiscube = label()->findObject("IsisCube");
2039 if (isiscube.hasGroup(group)) return true;
2040 return false;
2041 }
2042
2043
2052 bool Cube::hasBlob(const QString &name, const QString &type) {
2053 for(int o = 0; o < label()->objects(); o++) {
2054 PvlObject &obj = label()->object(o);
2055 if (obj.isNamed(type)) {
2056 if (obj.hasKeyword("Name")) {
2057 QString temp = (QString) obj["Name"];
2058 temp = temp.toUpper();
2059 QString temp2 = name;
2060 temp2 = temp2.toUpper();
2061 if (temp == temp2) return true;
2062 }
2063 }
2064 }
2065 return false;
2066 }
2067
2068
2076 bool Cube::hasTable(const QString &name) {
2077 return hasBlob(name, "Table");
2078 }
2079
2080
2090 if (isReadOnly()) {
2091 QString msg = "Cannot add a group to the label of cube [" + (QString)QFileInfo(fileName()).fileName() +
2092 "] because it is opened read-only";
2093 throw IException(IException::Programmer, msg, _FILEINFO_);
2094 return;
2095 }
2096
2097 PvlObject &isiscube = label()->findObject("IsisCube");
2098 if (isiscube.hasGroup(group.name())) {
2099 isiscube.findGroup(group.name()) = group;
2100 }
2101 else {
2102 isiscube.addGroup(group);
2103 }
2104 }
2105
2106
2112 PvlObject &core = m_label->findObject("IsisCube").findObject("Core");
2113
2114 // Prune the band bin group if it exists
2115 if (m_label->findObject("IsisCube").hasGroup("BandBin")) {
2116 PvlGroup &bandBin = m_label->findObject("IsisCube").findGroup("BandBin");
2117 for (int k = 0;k < bandBin.keywords();k++) {
2118 if (bandBin[k].size() == m_bands && m_virtualBandList) {
2119 PvlKeyword temp = bandBin[k];
2120 bandBin[k].clear();
2121 for (int i = 0;i < m_virtualBandList->size();i++) {
2122 int physicalBand = m_virtualBandList->at(i) - 1;
2123 bandBin[k].addValue(temp[physicalBand], temp.unit(physicalBand));
2124 }
2125 }
2126 }
2127 }
2128
2129 // Change the number of bands in the labels of the cube
2130 if (m_virtualBandList && core.hasGroup("Dimensions")) core.findGroup("Dimensions")["Bands"] = toString(m_virtualBandList->size());
2131 }
2132
2133
2139 void Cube::cleanUp(bool removeIt) {
2140 if (m_ioHandler) {
2141 delete m_ioHandler;
2142 m_ioHandler = NULL;
2143 }
2144
2145 // Always remove a temporary file
2146 if (m_tempCube) {
2147 QFile::remove(m_tempCube->expanded());
2148 removeIt = false; // dont remove originals
2149
2150 delete m_tempCube;
2151 m_tempCube = NULL;
2152 }
2153
2154 if (removeIt) {
2155 QFile::remove(m_labelFileName->expanded());
2156
2158 QFile::remove(m_dataFileName->expanded());
2159 }
2160
2161 delete m_labelFile;
2162 m_labelFile = NULL;
2163
2164 delete m_dataFile;
2165 m_dataFile = NULL;
2166
2167 delete m_labelFileName;
2168 m_labelFileName = NULL;
2169
2170 delete m_dataFileName;
2171 m_dataFileName = NULL;
2172
2173 delete m_label;
2174 m_label = NULL;
2175
2176 delete m_virtualBandList;
2177 m_virtualBandList = NULL;
2178
2179 initialize();
2180 }
2181
2182
2188 m_labelFile = NULL;
2189 m_dataFile = NULL;
2190 m_ioHandler = NULL;
2191 m_mutex = NULL;
2192
2193 m_camera = NULL;
2194 m_projection = NULL;
2195
2196 m_labelFileName = NULL;
2197 m_dataFileName = NULL;
2198 m_tempCube = NULL;
2199 m_formatTemplateFile = NULL;
2200 m_label = NULL;
2201
2202 m_virtualBandList = NULL;
2203
2204 m_mutex = new QMutex();
2206 new FileName("$ISISROOT/appdata/templates/labels/CubeFormatTemplate.pft");
2207
2208 initialize();
2209 }
2210
2211
2218 QFile *Cube::dataFile() const {
2219 if (m_dataFile)
2220 return m_dataFile;
2221 else
2222 return m_labelFile;
2223 }
2224
2225
2234 FileName result;
2235
2236 // Attached, stores DN data - normal cube
2237 if (m_attached && m_storesDnData) {
2238 result = *m_labelFileName;
2239 }
2240 // Detached, stores DN data - standard detached cube
2241 else if (!m_attached && m_storesDnData) {
2242 result = *m_dataFileName;
2243 }
2244 // External cube - go look at our external file
2245 else if (!m_storesDnData) {
2246 FileName guess = *m_dataFileName;
2247 QDir dir(guess.toString());
2248
2249 // If path is relative and there is a labelFileName, start in directory of the ecub, then
2250 // cd to the directory containing the DnFile, since it is relative to the location of the ecub.
2251 // We need to turn the relative path into an absolute path.
2252 if (dir.isRelative() && m_labelFileName) {
2253 QDir dir2(m_labelFileName->originalPath());
2254 dir2.cd(guess.path());
2255 guess = dir2.absolutePath() + "/" + guess.name();
2256 }
2257 do {
2258 Pvl guessLabel(guess.expanded());
2259
2260 PvlObject &core = guessLabel.findObject("IsisCube").findObject("Core");
2261
2262 if (core.hasKeyword("^DnFile")) {
2263 FileName currentGuess = guess;
2264 guess = core["^DnFile"][0];
2265
2266 if (!guess.path().startsWith("/")) {
2267 guess = currentGuess.path() + "/" + guess.original();
2268 }
2269 }
2270 else if (core.hasKeyword("^Core")) {
2271 result = core["^Core"][0];
2272 }
2273 else {
2274 result = guess;
2275 }
2276 }
2277 while (result.name() == "");
2278 }
2279
2280 return result;
2281 }
2282
2283
2296 m_byteOrder = Lsb;
2297 if (IsBigEndian())
2298 m_byteOrder = Msb;
2299 m_format = Tile;
2300 m_pixelType = Real;
2301
2302 m_attached = true;
2303 m_storesDnData = true;
2304 m_labelBytes = 65536;
2305
2306 m_samples = 0;
2307 m_lines = 0;
2308 m_bands = 0;
2309
2310 m_base = 0.0;
2311 m_multiplier = 1.0;
2312 }
2313
2314
2321 const PvlObject &core = label.findObject("IsisCube").findObject("Core");
2322
2323 if (!core.hasKeyword("^DnFile")) {
2324 // Dimensions
2325 const PvlGroup &dims = core.findGroup("Dimensions");
2326 m_samples = dims["Samples"];
2327 m_lines = dims["Lines"];
2328 m_bands = dims["Bands"];
2329
2330 // Stored pixel information
2331 const PvlGroup &pixelsGroup = core.findGroup("Pixels");
2332 m_byteOrder = ByteOrderEnumeration(pixelsGroup["ByteOrder"]);
2333 m_base = pixelsGroup["Base"];
2334 m_multiplier = pixelsGroup["Multiplier"];
2335 m_pixelType = PixelTypeEnumeration(pixelsGroup["Type"]);
2336
2337 // Now examine the format to see which type of handler to create
2338 if ((QString) core["Format"] == "BandSequential") {
2339 m_format = Bsq;
2340 }
2341 else {
2342 m_format = Tile;
2343 }
2344 }
2345 else {
2346 FileName temp(core["^DnFile"][0]);
2347 if (!temp.expanded().startsWith("/")) {
2348 temp = FileName(m_labelFileName->path() + "/" + temp.original());
2349 }
2350
2352 }
2353 }
2354
2355
2364 void Cube::initLabelFromFile(FileName labelFileName, bool readWrite) {
2365
2366 try {
2367 if (labelFileName.fileExists()) {
2368 m_label = new Pvl(labelFileName.expanded());
2369 if (!m_label->objects()) {
2370 throw IException();
2371 }
2372 }
2373 }
2374 catch(IException &) {
2375 if (m_label) {
2376 delete m_label;
2377 m_label = NULL;
2378 }
2379 }
2380
2381 try {
2382 if (!m_label) {
2383 FileName tmp(labelFileName);
2384 tmp = tmp.addExtension("cub");
2385 if (tmp.fileExists()) {
2386 m_label = new Pvl(tmp.expanded());
2387 if (!m_label->objects()) {
2388 throw IException();
2389 }
2390 labelFileName = tmp;
2391 }
2392 }
2393 }
2394 catch(IException &e) {
2395 if (m_label) {
2396 delete m_label;
2397 m_label = NULL;
2398 }
2399 }
2400
2401 try {
2402 if (!m_label) {
2403 FileName tmp(labelFileName);
2404 tmp = tmp.setExtension("lbl");
2405 if (tmp.fileExists()) {
2406 m_label = new Pvl(tmp.expanded());
2407 if (!m_label->objects()) {
2408 throw IException();
2409 }
2410 labelFileName = tmp;
2411 }
2412 }
2413 }
2414 catch(IException &e) {
2415 if (m_label) {
2416 delete m_label;
2417 m_label = NULL;
2418 }
2419 }
2420
2421 try {
2422 if (!m_label) {
2423 FileName tmp(labelFileName);
2424 tmp = tmp.addExtension("ecub");
2425 if (tmp.fileExists()) {
2426 m_label = new Pvl(tmp.expanded());
2427 if (!m_label->objects()) {
2428 throw IException();
2429 }
2430 labelFileName = tmp;
2431 }
2432 }
2433 }
2434 catch(IException &e) {
2435 if (m_label) {
2436 delete m_label;
2437 m_label = NULL;
2438 }
2439 }
2440
2441 if (!m_label) {
2442 QString msg = Message::FileOpen(labelFileName.original());
2443 throw IException(IException::Io, msg, _FILEINFO_);
2444 }
2445
2446 m_labelFileName = new FileName(labelFileName);
2447
2448 // See if this is an old Isis cube format. If so then we will
2449 // need to internalize a new label
2450 if (m_label->hasKeyword("CCSD3ZF0000100000001NJPL3IF0PDS200000001")) {
2451 if (!readWrite) {
2453 }
2454 else {
2455 QString msg = "Can not open [" + m_labelFileName->original() + "]"
2456 " because it is an ISIS2 cube.";
2457 cleanUp(false);
2458 throw IException(IException::Io, msg, _FILEINFO_);
2459 }
2460 }
2461 else {
2462 m_labelFile = new QFile(m_labelFileName->expanded());
2463 }
2464 }
2465
2466
2471 if (isOpen()) {
2472 string msg = "Sorry you can't do a SetMethod after the cube is opened";
2473 throw IException(IException::Programmer, msg, _FILEINFO_);
2474 }
2475 }
2476
2477
2484 Pvl label = *m_label;
2485 PvlObject *core = NULL;
2486
2487 do {
2488 core = &label.findObject("IsisCube").findObject("Core");
2489
2490 if (core->hasKeyword("^DnFile")) {
2491
2492 FileName temp((*core)["^DnFile"][0]);
2493 if (!temp.expanded().startsWith("/")) {
2494 temp = realDataFileName();
2495 }
2496
2497 label = Pvl(temp.toString());
2498 core = NULL;
2499 }
2500 }
2501 while (!core);
2502
2503 return label;
2504 }
2505
2506
2513 void Cube::reformatOldIsisLabel(const QString &oldCube) {
2514 QString parameters = "from=" + oldCube;
2515 FileName oldName(oldCube);
2516 FileName tempCube = FileName::createTempFile("Temporary_" + oldName.name() + ".cub");
2517 parameters += " to=" + tempCube.expanded();
2518
2519 if (iApp == NULL) {
2520 QString command = "$ISISROOT/bin/pds2isis " + parameters;
2522 }
2523 else {
2524 QString prog = "pds2isis";
2525 ProgramLauncher::RunIsisProgram(prog, parameters);
2526 }
2527
2528 m_tempCube = new FileName(tempCube);
2529 *m_label = Pvl(m_tempCube->toString());
2530 m_labelFile = new QFile(m_tempCube->expanded());
2531 }
2532
2533
2543 void Cube::latLonRange(double &minLatitude, double &maxLatitude, double &minLongitude, double &
2544 maxLongitude) {
2545 Camera *cam;
2546 TProjection *proj;
2547
2548 bool isGood = false;
2549 bool useProj = true;
2550
2551 if (hasGroup("Instrument")) {
2552 useProj = false;
2553 }
2554
2555 // setup camera or projection
2556 if (useProj) {
2557 try {
2558 proj = (TProjection *) projection();
2559 }
2560 catch(IException &e) {
2561 QString msg = "Cannot calculate lat/lon range without a camera or projection";
2562 throw IException(e, IException::User, msg, _FILEINFO_);
2563 }
2564 }
2565 else {
2566 try {
2567 cam = camera();
2568 }
2569 catch(IException &e) {
2570 QString msg = "Unable to create camera when calculating a lat/lon range.";
2571 throw IException(e, IException::User, msg, _FILEINFO_);
2572 }
2573 }
2574
2575 // Iterate over all samp/line combos in cube
2576 minLatitude = 99999;
2577 minLongitude = 99999;
2578 maxLatitude = -99999;
2579 maxLongitude = -99999;
2580
2581 for (double sample = 0.5; sample < sampleCount() + 0.5; sample++) {
2582 // Checks to see if the point is in outer space
2583 for (double line = 0.5; line < lineCount() + 0.5; line++) {
2584 if (useProj) {
2585 isGood = proj->SetWorld(sample, line);
2586 }
2587 else {
2588 isGood = cam->SetImage(sample, line);
2589 }
2590
2591 double lat, lon;
2592 if (isGood) {
2593 if (useProj) {
2594 lat = proj->UniversalLatitude();
2595 lon = proj->UniversalLongitude();
2596 }
2597 else {
2598 lat = cam->UniversalLatitude();
2599 lon = cam->UniversalLongitude();
2600 }
2601
2602 // update mix/max lat/lons
2603 if (lat < minLatitude) {
2604 minLatitude = lat;
2605 }
2606 else if (lat > maxLatitude) {
2607 maxLatitude = lat;
2608 }
2609
2610 if (lon < minLongitude) {
2611 minLongitude = lon;
2612 }
2613 else if (lon > maxLongitude) {
2614 maxLongitude = lon;
2615 }
2616 }
2617 }
2618 }
2619 if ( (minLatitude == 99999) || (minLongitude == 99999) || (maxLatitude == -99999) ||
2620 (maxLongitude == -99999) ) {
2621 QString msg = "Unable to calculate a minimum or maximum latitutde or longitude.";
2622 throw IException(IException::Unknown, msg, _FILEINFO_);
2623 }
2624 }
2625
2631 if (!isOpen()) {
2632 string msg = "Cube must be opened first before writing labels";
2633 throw IException(IException::Programmer, msg, _FILEINFO_);
2634 }
2635
2636 // Set the pvl's format template
2637 m_label->setFormatTemplate(m_formatTemplateFile->original());
2638
2639 // Write them with attached data
2640 if (m_attached) {
2641 QMutexLocker locker(m_mutex);
2642 QMutexLocker locker2(m_ioHandler->dataFileMutex());
2643
2644 ostringstream temp;
2645 temp << *m_label << endl;
2646 string tempstr = temp.str();
2647 if ((int) tempstr.length() < m_labelBytes) {
2648 QByteArray labelArea(m_labelBytes, '\0');
2649 QByteArray labelUnpaddedContents(tempstr.c_str(), tempstr.length());
2650 labelArea.replace(0, labelUnpaddedContents.size(), labelUnpaddedContents);
2651 // Rewrite the label area
2652 m_labelFile->seek(0);
2653 m_labelFile->write(labelArea);
2654 }
2655 else {
2656 locker2.unlock();
2657 QString msg = "Label space is full in [" +
2658 (QString)FileName(*m_labelFileName).name() +
2659 "] unable to write labels";
2660 cleanUp(false);
2661 throw IException(IException::Io, msg, _FILEINFO_);
2662 }
2663 }
2664
2665 // or detached label
2666 else {
2667 m_label->write(m_labelFileName->expanded());
2668 }
2669 }
2670}
void Read(const QString &file, const std::vector< PvlKeyword > keywords=std::vector< PvlKeyword >())
This method reads Pvl values from a specified file.
Definition Blob.cpp:255
void Write(const QString &file)
Write the blob data out to a file.
Definition Blob.cpp:417
QString Type() const
Accessor method that returns a string containing the Blob type.
Definition Blob.cpp:124
QString Name() const
Accessor method that returns a string containing the Blob name.
Definition Blob.cpp:133
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
void Copy(const Buffer &in, bool includeRawBuf=true)
Allows copying of the buffer contents to another Buffer.
Definition Buffer.cpp:255
Manages a Buffer over a cube.
bool begin()
Moves the shape buffer to the first position.
bool end() const
Returns true if the shape buffer has accessed the end of the cube.
bool next()
Moves the shape buffer to the next position.
static Camera * Create(Cube &cube)
Creates a Camera object using Pvl Specifications.
virtual bool SetImage(const double sample, const double line)
Sets the sample/line values of the image to get the lat/lon values.
Definition Camera.cpp:156
Manipulate and parse attributes of input cube filenames.
std::vector< QString > bands() const
Return a vector of the input bands specified.
Manipulate and parse attributes of output cube filenames.
double minimum() const
Return the output cube attribute minimum.
ByteOrder byteOrder() const
Return the byte order as an Isis::ByteOrder.
double maximum() const
Return the output cube attribute maximum.
bool propagateMinimumMaximum() const
Return true if the min/max are to be propagated from an input cube.
bool propagatePixelType() const
Return true if the pixel type is to be propagated from an input cube.
Cube::Format fileFormat() const
Return the file format an Cube::Format.
PixelType pixelType() const
Return the pixel type as an Isis::PixelType.
IO Handler for Isis Cubes using the BSQ format.
This is the parent of the caching algorithms.
void addCachingAlgorithm(CubeCachingAlgorithm *)
This will add the given caching algorithm to the list of attempted caching algorithms.
Definition Cube.cpp:1955
void clearIoCache()
This will clear excess RAM used for quicker IO in the cube.
Definition Cube.cpp:1971
bool hasTable(const QString &name)
Check to see if the cube contains a pvl table by the provided name.
Definition Cube.cpp:2076
QFile * m_dataFile
This is only sometimes allocated.
Definition Cube.h:362
Pvl realDataFileLabel() const
Function to read data from a cube label and return it as a PVL object.
Definition Cube.cpp:2483
ImagePolygon readFootprint() const
Read the footprint polygon for the Cube.
Definition Cube.cpp:879
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:1317
void latLonRange(double &minLatitude, double &maxLatitude, double &minLongitude, double &maxLongitude)
Returns the latitude and longitude range for the Cube.
Definition Cube.cpp:2543
void deleteGroup(const QString &group)
Deletes a group from the cube labels.
Definition Cube.cpp:2010
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:2513
void setFormat(Format format)
Used prior to the Create method, this will specify the format of the cube, either band,...
Definition Cube.cpp:1279
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:1988
int m_bands
The band count of the open cube or the cube that will be created.
Definition Cube.h:439
void initialize()
This sets Cube to its default state: Native byte order Format = Tile PixelType = Real (4 bytes per pi...
Definition Cube.cpp:2295
Format format() const
Definition Cube.cpp:1608
PixelType m_pixelType
This is the pixel type on disk.
Definition Cube.h:389
void relocateDnData(FileName dnDataFile)
Relocates the DN data for a cube to an external cube label file.
Definition Cube.cpp:1379
void construct()
Initialize members from their initial undefined states.
Definition Cube.cpp:2187
int m_labelBytes
The maximum allowed size of the label; the allocated space.
Definition Cube.h:430
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:1632
int lineCount() const
Definition Cube.cpp:1767
void initLabelFromFile(FileName labelFileName, bool readWrite)
This function initializes the Cube label from a file passed as a parameter.
Definition Cube.cpp:2364
double multiplier() const
Returns the multiplier value for converting 8-bit/16-bit pixels to 32-bit.
Definition Cube.cpp:1781
CubeIoHandler * m_ioHandler
This does the heavy lifting for cube DN IO and is always allocated when isOpen() is true.
Definition Cube.h:368
FileName realDataFileName() const
This gets the file name of the file which actually contains the DN data.
Definition Cube.cpp:2233
void setLabelsAttached(bool attached)
Use prior to calling create, this sets whether or not to use separate label and data files.
Definition Cube.cpp:1291
CubeStretch readCubeStretch(QString name="CubeStretch", const std::vector< PvlKeyword > keywords=std::vector< PvlKeyword >()) const
Read a Stretch from a cube.
Definition Cube.cpp:925
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:1863
void setDimensions(int ns, int nl, int nb)
Used prior to the Create method to specify the size of the cube.
Definition Cube.cpp:1230
Camera * camera()
Return a camera associated with the cube.
Definition Cube.cpp:1464
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:1568
PvlGroup & group(const QString &group) const
Read a group from the cube into a Label.
Definition Cube.cpp:2024
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:445
int sampleCount() const
Definition Cube.cpp:1840
bool m_attached
True if labels are attached.
Definition Cube.h:417
void putGroup(const PvlGroup &group)
Adds a group in a Label to the cube.
Definition Cube.cpp:2089
bool m_storesDnData
True (most common case) when the cube DN data is inside the file we're writing to.
Definition Cube.h:424
bool isOpen() const
Test if a cube file has been opened/created.
Definition Cube.cpp:189
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:1164
bool isReadOnly() const
Test if the opened cube is read-only, that is write operations will fail if this is true.
Definition Cube.cpp:215
int m_lines
The line count of the open cube or the cube that will be created.
Definition Cube.h:436
double base() const
Returns the base value for converting 8-bit/16-bit pixels to 32-bit.
Definition Cube.cpp:1440
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:1181
QFile * dataFile() const
This returns the QFile with cube DN data in it.
Definition Cube.cpp:2218
Cube * copy(FileName newFile, const CubeAttributeOutput &newFileAttributes)
Copies the cube to the new fileName.
Definition Cube.cpp:278
void create(const QString &cfile)
This method will create an isis cube for writing.
Definition Cube.cpp:416
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:411
bool hasBlob(const QString &name, const QString &type)
Check to see if the cube contains a BLOB.
Definition Cube.cpp:2052
void cleanUp(bool remove)
This clears all of the allocated memory associated with an open cube.
Definition Cube.cpp:2139
ByteOrder byteOrder() const
Returns the byte order/endian-ness of the cube file.
Definition Cube.cpp:1452
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:375
QFile * m_labelFile
This is the file that contains the labels always; if labels are attached then this contains the file ...
Definition Cube.h:356
bool labelsAttached() const
Test if labels are attached.
Definition Cube.cpp:250
void open(const QString &cfile, QString access="r")
This method will open an existing isis cube for reading or reading/writing.
Definition Cube.cpp:629
PixelType pixelType() const
Definition Cube.cpp:1791
bool storesDnData() const
This method returns a boolean value.
Definition Cube.cpp:1937
void setVirtualBands(const QList< QString > &vbands)
This allows the programmer to specify a subset of bands to work with.
Definition Cube.cpp:1334
FileName * m_formatTemplateFile
Label pvl format template file (describes how to format labels)
Definition Cube.h:414
Pvl * m_label
The label if IsOpen(), otherwise NULL.
Definition Cube.h:427
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:820
bool isProjected() const
Returns true if the labels of the cube appear to have a valid mapping group.
Definition Cube.cpp:204
OriginalLabel readOriginalLabel(const QString &name="IsisCube") const
Read the original PDS3 label from a cube.
Definition Cube.cpp:902
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:1806
Table readTable(const QString &name)
Read a Table from the cube.
Definition Cube.cpp:965
Camera * m_camera
Camera allocated from the camera() method.
Definition Cube.h:395
bool hasGroup(const QString &group) const
Return if the cube has a specified group in the labels.
Definition Cube.cpp:2037
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:1304
OriginalXmlLabel readOriginalXmlLabel() const
Read the original PDS4 label from a cube.
Definition Cube.cpp:944
virtual QString fileName() const
Returns the opened cube's filename.
Definition Cube.cpp:1596
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:166
QList< int > * m_virtualBandList
If allocated, converts from physical on-disk band # to virtual band #.
Definition Cube.h:454
void write(Blob &blob, bool overwrite=true)
This method will write a blob of data (e.g.
Definition Cube.cpp:984
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:237
FileName * m_labelFileName
The full filename of the label file (.lbl or .cub)
Definition Cube.h:401
void setExternalDnData(FileName cubeFileWithDnData)
Used to set external dn data to cube.
Definition Cube.cpp:1247
void close(bool remove=false)
Closes the cube and updates the labels.
Definition Cube.cpp:262
History readHistory(const QString &name="IsisCube") const
Read the History from the Cube.
Definition Cube.cpp:860
void writeLabels()
Write the Pvl labels to the cube's label file.
Definition Cube.cpp:2630
QMutex * m_mutex
Basic thread-safety mutex; this class is not optimized for threads.
Definition Cube.h:392
void initCoreFromLabel(const Pvl &label)
This function initializes the Cube core from a Pvl Label passed as a parameter.
Definition Cube.cpp:2320
int labelSize(bool actual=false) const
Returns the number of bytes used by the label.
Definition Cube.cpp:1746
int m_samples
The sample count of the open cube or the cube that will be created.
Definition Cube.h:433
void openCheck()
Throw an exception if the cube is not open.
Definition Cube.cpp:2470
Projection * projection()
Definition Cube.cpp:1827
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:451
virtual int bandCount() const
Returns the number of virtual bands for the cube.
Definition Cube.cpp:1423
Pvl * label() const
Returns a pointer to the IsisLabel object associated with the cube.
Definition Cube.cpp:1734
void reopen(QString access="r")
This method will reopen an isis sube for reading or reading/writing.
Definition Cube.cpp:787
Projection * m_projection
Projection allocated from the projection() method.
Definition Cube.h:398
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:1215
FileName * m_dataFileName
The full filename of the data file (.cub)
Definition Cube.h:404
void applyVirtualBandsToLabel()
Applies virtual bands to label.
Definition Cube.cpp:2111
Format m_format
If isOpen() then this is the IO format that the cube uses.
Definition Cube.h:382
Stores stretch information for a cube.
Definition CubeStretch.h:27
Isis::Blob toBlob() const
Serialize the CubeStretch to a Blob.
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
bool fileExists() const
Returns true if the file exists; false otherwise.
Definition FileName.cpp:449
FileName setExtension(const QString &extension) const
Sets all current file extensions to a new extension in the file name.
Definition FileName.cpp:265
QString baseName() const
Returns the name of the file without the path and without extensions.
Definition FileName.cpp:145
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
FileName removeExtension() const
Removes all extensions in the file name.
Definition FileName.cpp:246
FileName addExtension(const QString &extension) const
Adds a new extension to the file name.
Definition FileName.cpp:225
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
void SetValidRange(const double minimum=Isis::ValidMinimum, const double maximum=Isis::ValidMaximum)
Changes the range of the bins.
virtual void AddData(const double *data, const unsigned int count)
Add an array of doubles to the histogram counters.
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.
Blob toBlob() const
Serialize the ImagePolygon to a Blob.
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.
Isis::Blob toBlob()
Serialize the OriginalLabel data to a Blob.
Read and store original Xml labels.
Blob toBlob() const
Serialize the OriginalXmlLabel to a Blob.
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
virtual bool SetWorld(const double x, const double y)
This method is used to set a world coordinate.
void clear()
Clears PvlKeywords.
bool isNamed(const QString &match) const
Returns whether the given string is equal to the container name or not.
int keywords() const
Returns the number of keywords contained in the PvlContainer.
QString name() const
Returns the container name.
Contains multiple PvlContainers.
Definition PvlGroup.h:41
Container for cube-like labels.
Definition Pvl.h:119
A single keyword-value pair.
Definition PvlKeyword.h:87
QString unit(const int index=0) const
Returns the units of measurement of the element of the array of values for the object at the specifie...
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 ...
PvlGroupIterator beginGroup()
Returns the beginning group index.
Definition PvlObject.h:91
PvlGroup & group(const int index)
Return the group at the specified index.
int groups() const
Returns the number of groups contained.
Definition PvlObject.h:75
PvlObjectIterator findObject(const QString &name, PvlObjectIterator beg, PvlObjectIterator end)
Find the index of object with a specified name, between two indexes.
Definition PvlObject.h:274
void deleteObject(const QString &name)
Remove an object from the current PvlObject.
int objects() const
Returns the number of objects.
Definition PvlObject.h:219
PvlObject & object(const int index)
Return the object at the specified index.
bool hasGroup(const QString &name) const
Returns a boolean value based on whether the object has the specified group or not.
Definition PvlObject.h:210
@ Traverse
Search child objects.
Definition PvlObject.h:158
void addObject(const PvlObject &object)
Add a PvlObject.
Definition PvlObject.h:307
PvlKeyword & findKeyword(const QString &kname, FindOptions opts)
Finds a keyword in the current PvlObject, or deeper inside other PvlObjects and Pvlgroups within this...
void addGroup(const Isis::PvlGroup &group)
Add a group to the object.
Definition PvlObject.h:186
void deleteGroup(const QString &name)
Remove a group from the current PvlObject.
PvlGroupIterator endGroup()
Returns the ending group index.
Definition PvlObject.h:109
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition PvlObject.h:129
virtual double UniversalLatitude() const
Returns the planetocentric latitude, in degrees, at the surface intersection point in the body fixed ...
Definition Sensor.cpp:212
virtual double UniversalLongitude() const
Returns the positive east, 0-360 domain longitude, in degrees, at the surface intersection point in t...
Definition Sensor.cpp:235
Obtain SPICE information for a spacecraft.
Definition Spice.h:283
This class is used to accumulate statistics on double arrays.
Definition Statistics.h:93
void AddData(const double *data, const unsigned int count)
Add an array of doubles to the accumulators and counters.
Base class for Map TProjections.
virtual double UniversalLongitude()
This returns a universal longitude (positive east in 0 to 360 domain).
virtual double UniversalLatitude()
This returns a universal latitude (planetocentric).
@ Integer
The values in the field are 4 byte integers.
Definition TableField.h:53
@ Double
The values in the field are 8 byte doubles.
Definition TableField.h:54
Class for storing Table blobs information.
Definition Table.h:61
PvlObject & Label()
The Table's label.
Definition Table.cpp:318
Blob toBlob() const
Serialze the Table to a Blob that can be written to a file.
Definition Table.cpp:472
This is free and unencumbered software released into the public domain.
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.
This is free and unencumbered software released into the public domain.