File failed to load: https://isis.astrogeology.usgs.gov/6.0.0/Object/assets/jax/output/NativeMML/config.js
Isis 3 Programmer Reference
Cube.cpp
1 
6 /* SPDX-License-Identifier: CC0-1.0 */
7 #include "IsisDebug.h"
8 #include "Cube.h"
9 
10 #include <sstream>
11 #include <unistd.h>
12 
13 #include <QDebug>
14 #include <QDir>
15 #include <QFile>
16 #include <QFileInfo>
17 #include <QMutex>
18 
19 #include "Application.h"
20 #include "Blob.h"
21 #include "Camera.h"
22 #include "CameraFactory.h"
23 #include "CubeAttribute.h"
24 #include "CubeBsqHandler.h"
25 #include "CubeTileHandler.h"
26 #include "CubeStretch.h"
27 #include "Endian.h"
28 #include "FileName.h"
29 #include "History.h"
30 #include "ImageHistogram.h"
31 #include "ImagePolygon.h"
32 #include "IException.h"
33 #include "LineManager.h"
34 #include "Message.h"
35 #include "OriginalLabel.h"
36 #include "OriginalXmlLabel.h"
37 #include "Preference.h"
38 #include "ProgramLauncher.h"
39 #include "Projection.h"
40 #include "SpecialPixel.h"
41 #include "Statistics.h"
42 #include "Table.h"
43 #include "TProjection.h"
44 #include "Longitude.h"
45 
46 using namespace std;
47 
48 namespace Isis {
50  Cube::Cube() {
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) {
77  initCoreFromLabel(label);
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 
160  Cube::~Cube() {
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 
173  delete m_formatTemplateFile;
174  m_formatTemplateFile = NULL;
175  }
176 
177 
183  bool Cube::isOpen() const {
184  bool open = (m_ioHandler != NULL);
185 
186  ASSERT(open == (bool)m_labelFile);
187  ASSERT(open == (bool)m_labelFileName);
188  ASSERT(open == (bool)m_label);
189 
190  return open;
191  }
192 
193 
202  bool Cube::isProjected() const {
203  return label()->findObject("IsisCube").hasGroup("Mapping");
204  }
205 
206 
213  bool Cube::isReadOnly() const {
214  bool readOnly = false;
215 
216  if (!isOpen()) {
217  QString msg = "No cube opened";
218  throw IException(IException::Programmer, msg, _FILEINFO_);
219  }
220 
221  if ((m_labelFile->openMode() & QIODevice::ReadWrite) != QIODevice::ReadWrite)
222  readOnly = true;
223 
224  return readOnly;
225  }
226 
227 
235  bool Cube::isReadWrite() const {
236  return !isReadOnly();
237  }
238 
239 
248  bool Cube::labelsAttached() const {
249  return m_attached;
250  }
251 
252 
260  void Cube::close(bool removeIt) {
261  if (isOpen() && isReadWrite())
262  writeLabels();
263 
264  cleanUp(removeIt);
265  }
266 
267 
276  Cube *Cube::copy(FileName newFile, const CubeAttributeOutput &newFileAttributes) {
277  if (!isOpen()) {
278  throw IException(IException::Unknown,
279  QObject::tr("Cube::copy requires the originating cube to be open"),
280  _FILEINFO_);
281  }
282 
283 
284  Cube *result = new Cube;
285 
286  if (newFileAttributes.labelAttachment() != ExternalLabel) {
287  result->setDimensions(sampleCount(), lineCount(), bandCount());
288  result->setByteOrder(newFileAttributes.byteOrder());
289  result->setFormat(newFileAttributes.fileFormat());
290 
291  if (newFileAttributes.labelAttachment() == DetachedLabel) {
292  result->setLabelsAttached(false);
293  }
294 
295  if (newFileAttributes.propagatePixelType()) {
296  result->setPixelType(pixelType());
297  }
298  else {
299  result->setPixelType(newFileAttributes.pixelType());
300  }
301 
302  if (newFileAttributes.propagateMinimumMaximum()) {
303  if(result->pixelType() == Isis::Real) {
304  result->setBaseMultiplier(0.0, 1.0);
305  }
306  else if(result->pixelType() >= pixelType()) {
307  result->setBaseMultiplier(base(), multiplier());
308  }
309  else {
310  QString msg =
311  QObject::tr("Cannot reduce the output PixelType for [%1] from [%2] without output "
312  "pixel range").arg(newFile.original()).arg(fileName());
313  throw IException(IException::User, msg, _FILEINFO_);
314  }
315  }
316  else {
317  // Not propagating so either the user entered or the programmer did
318  result->setMinMax(newFileAttributes.minimum(), newFileAttributes.maximum());
319  }
320 
321  result->setLabelSize(labelSize(true) + (1024 * 6));
322  }
323  else {
324  if (isReadWrite()) {
325  writeLabels();
326  m_ioHandler->clearCache(true);
327  }
328 
329  result->setExternalDnData(fileName());
330  }
331 
332  // Allocate the cube
333  result->create(newFile.expanded());
334 
335  PvlObject &isisCube = label()->findObject("IsisCube");
336  PvlObject &outIsisCube = result->label()->findObject("IsisCube");
337  for(int i = 0; i < isisCube.groups(); i++) {
338  outIsisCube.addGroup(isisCube.group(i));
339  }
340 
341  if (label()->hasObject("NaifKeywords")) {
342  result->label()->addObject(
343  label()->findObject("NaifKeywords"));
344  }
345 
346  for (int i = 0; i < m_label->objects(); i++) {
347  PvlObject &obj = m_label->object(i);
348  if (obj.isNamed("Table") || obj.isNamed("Polygon") || obj.isNamed("OriginalLabel") ||
349  obj.isNamed("History")) {
350  Isis::Blob t((QString)obj["Name"], obj.name());
351  read(t);
352  result->write(t);
353  }
354  }
355 
356  if (newFileAttributes.labelAttachment() != ExternalLabel) {
357  BufferManager input(sampleCount(), lineCount(), bandCount(),
358  sampleCount(), 1, 1,
359  pixelType());
360  BufferManager output(sampleCount(), lineCount(), bandCount(),
361  sampleCount(), 1, 1,
362  result->pixelType());
363 
364  input.begin();
365  output.begin();
366 
367  while (!input.end()) {
368  read(input);
369  output.Copy(input, false);
370 
371  result->write(output);
372 
373  input.next();
374  output.next();
375  }
376  }
377 
378 // Just in case the orig label doesn't work... here's original code:
379 // if((p_propagateOriginalLabel) && (InputCubes.size() > 0)) {
380 // Isis::Pvl &inlab = *InputCubes[0]->label();
381 // for(int i = 0; i < inlab.objects(); i++) {
382 // if(inlab.Object(i).isNamed("OriginalLabel")) {
383 // Isis::OriginalLabel ol;
384 // InputCubes[0]->read(ol);
385 // cube->write(ol);
386 // }
387 // }
388 // }
389 
390  return result;
391  }
392 
393 
414  void Cube::create(const QString &cubeFileName) {
415  // Already opened?
416  if (isOpen()) {
417  string msg = "You already have a cube opened";
418  throw IException(IException::Programmer, msg, _FILEINFO_);
419  }
420 
421  if (m_samples < 1 || m_lines < 1 || m_bands < 1) {
422  QString msg = "Number of samples [" + toString(m_samples) +
423  "], lines [" + toString(m_lines) + "], or bands [" + toString(m_bands) +
424  "] cannot be less than 1";
425  throw IException(IException::Programmer, msg, _FILEINFO_);
426  }
427 
428  if (m_pixelType == None) {
429  throw IException(IException::Unknown,
430  QString("Cannot create the cube [%1] with a pixel type set to None")
431  .arg(cubeFileName),
432  _FILEINFO_);
433  }
434 
435  if (m_storesDnData) {
436  // Make sure the cube is not going to exceed the maximum size preference
437  BigInt size = (BigInt)m_samples * m_lines *
438  (BigInt)m_bands * (BigInt)SizeOf(m_pixelType);
439 
440  size = size / 1024; // kb
441  size = size / 1024; // mb
442  size = size / 1024; // gb
443 
444  int maxSizePreference = 0;
445 
446  maxSizePreference =
447  Preference::Preferences().findGroup("CubeCustomization")["MaximumSize"];
448 
449  if (size > maxSizePreference) {
450  QString msg;
451  msg += "The cube you are attempting to create [" + cubeFileName + "] is ["
452  + toString(size) + "GB]. This is larger than the current allowed "
453  "size of [" + toString(maxSizePreference) + "GB]. The cube "
454  "dimensions were (S,L,B) [" + toString(m_samples) + ", " +
455  toString(m_lines) + ", " + toString(m_bands) + "] with [" +
456  toString(SizeOf(m_pixelType)) + "] bytes per pixel. If you still "
457  "wish to create this cube, the maximum value can be changed in your personal "
458  "preference file located in [~/.Isis/IsisPreferences] within the group "
459  "CubeCustomization, keyword MaximumSize. If you do not have an ISISPreference file, "
460  "please refer to the documentation \"Environment and Preference Setup\". Error ";
461  throw IException(IException::User, msg, _FILEINFO_);
462  }
463  }
464 
465  // Expand output name
466  FileName cubFile(cubeFileName);
467  PvlObject isiscube("IsisCube");
468  PvlObject core("Core");
469 
470  if (m_storesDnData) {
471  cubFile = cubFile.addExtension("cub");
472 
473  // See if we have attached or detached labels
474  if (m_attached) {
475  // StartByte is 1-based (why!!) so we need to do + 1
476  core += PvlKeyword("StartByte", toString(m_labelBytes + 1));
477  m_labelFileName = new FileName(cubFile);
478  m_dataFileName = new FileName(cubFile);
479  m_labelFile = new QFile(m_labelFileName->expanded());
480  }
481  else {
482  core += PvlKeyword("StartByte", toString(1));
483  core += PvlKeyword("^Core", cubFile.name());
484  m_dataFileName = new FileName(cubFile);
485  m_dataFile = new QFile(realDataFileName().expanded());
486 
487  FileName labelFileName(cubFile);
488  labelFileName = labelFileName.setExtension("lbl");
489  m_labelFileName = new FileName(labelFileName);
490  m_labelFile = new QFile(m_labelFileName->expanded());
491  }
492 
493  // Create the size of the core
494  PvlGroup dims("Dimensions");
495  dims += PvlKeyword("Samples", toString(m_samples));
496  dims += PvlKeyword("Lines", toString(m_lines));
497  dims += PvlKeyword("Bands", toString(m_bands));
498  core.addGroup(dims);
499 
500  // Create the pixel type
501  PvlGroup ptype("Pixels");
502  ptype += PvlKeyword("Type", PixelTypeName(m_pixelType));
503 
504  // And the byte ordering
505  ptype += PvlKeyword("ByteOrder", ByteOrderName(m_byteOrder));
506  ptype += PvlKeyword("Base", toString(m_base));
507  ptype += PvlKeyword("Multiplier", toString(m_multiplier));
508  core.addGroup(ptype);
509  }
510  else {
511  cubFile = cubFile.addExtension("ecub");
512 
513  ASSERT(m_dataFileName);
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) {
567  m_ioHandler = new CubeBsqHandler(dataFile(), m_virtualBandList, realDataFileLabel(),
568  dataAlreadyOnDisk);
569  }
570  else {
571  m_ioHandler = new CubeTileHandler(dataFile(), m_virtualBandList, realDataFileLabel(),
572  dataAlreadyOnDisk);
573  }
574 
575  if (m_storesDnData)
576  m_ioHandler->updateLabels(*m_label);
577 
578  // Write the labels
579  writeLabels();
580  }
581 
582 
604  void Cube::create(
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 
627  void Cube::open(const QString &cubeFileName, QString access) {
628  // Already opened?
629 
630  if (isOpen()) {
631  string msg = "You already have a cube opened";
632  throw IException(IException::Programmer, msg, _FILEINFO_);
633  }
634 
635  initLabelFromFile(cubeFileName, (access == "rw"));
636 
637  // Figure out the name of the data file
638  try {
639  PvlObject &core = m_label->findObject("IsisCube").findObject("Core");
640  // Detached labels
641  if (core.hasKeyword("^Core")) {
642  FileName temp(core["^Core"][0]);
643 
644  if (!temp.originalPath().startsWith("/")) {
645  m_dataFileName = new FileName(m_labelFileName->path() + "/" + temp.original());
646  }
647  else {
648  m_dataFileName = new FileName(temp);
649  }
650 
651  m_attached = false;
652  m_storesDnData = true;
653 
654  m_dataFile = new QFile(realDataFileName().expanded());
655  }
656  // External cube files (ecub), ecub contains all labels and SPICE blobs, history
657  else if (core.hasKeyword("^DnFile")) {
658  FileName dataFileName(core["^DnFile"][0]);
659 
660  if (dataFileName.originalPath() == ".") {
661  m_dataFileName = new FileName(m_labelFileName->path() + "/" + dataFileName.name());
662  }
663  else {
664  m_dataFileName = new FileName(dataFileName);
665  }
666 
667  m_attached = true;
668  m_storesDnData = false;
669  *m_dataFileName = FileName(realDataFileName().expanded());
670  m_dataFile = new QFile(realDataFileName().expanded());
671  }
672  // Typical cube containing labels, SPICE, history and dn data
673  else {
674  m_dataFileName = new FileName(*m_labelFileName);
675  m_attached = true;
676  m_storesDnData = true;
677  }
678  }
679  catch (IException &e) {
680  cleanUp(false);
681  throw;
682  }
683 
684  if (access == "r") {
685  if (!m_labelFile->open(QIODevice::ReadOnly)) {
686  QString msg = "Failed to open [" + m_labelFile->fileName() + "] with "
687  "read only access";
688  cleanUp(false);
689  throw IException(IException::Io, msg, _FILEINFO_);
690  }
691 
692  if (m_dataFile) {
693  if (!m_dataFile->open(QIODevice::ReadOnly)) {
694  QString msg = "Failed to open [" + m_dataFile->fileName() + "] with "
695  "read only access";
696  cleanUp(false);
697  throw IException(IException::Io, msg, _FILEINFO_);
698  }
699  }
700  }
701 
702  else if (access == "rw") {
703  if (!m_labelFile->open(QIODevice::ReadWrite)) {
704  QString msg = "Failed to open [" + m_labelFile->fileName() + "] with "
705  "read/write access";
706  cleanUp(false);
707  throw IException(IException::Io, msg, _FILEINFO_);
708  }
709 
710  if (m_dataFile) {
711  if (m_storesDnData && !m_dataFile->open(QIODevice::ReadWrite)) {
712  QString msg = "Failed to open [" + m_dataFile->fileName() + "] with "
713  "read/write access";
714  cleanUp(false);
715  throw IException(IException::Io, msg, _FILEINFO_);
716  }
717  else if (!m_storesDnData && !m_dataFile->open(QIODevice::ReadOnly)) {
718  QString msg = "Failed to open [" + m_dataFile->fileName() + "] with "
719  "read access";
720  cleanUp(false);
721  throw IException(IException::Io, msg, _FILEINFO_);
722  }
723  }
724  }
725  else {
726  QString msg = "Unknown value for access [" + access + "]. Expected 'r' "
727  " or 'rw'";
728  cleanUp(false);
729  throw IException(IException::Programmer, msg, _FILEINFO_);
730  }
731 
732  initCoreFromLabel(*m_label);
733 
734  // Determine the number of bytes in the label
735  if (m_attached) {
736  m_labelBytes = m_label->findObject("Label")["Bytes"];
737  }
738  else {
739  m_labelBytes = labelSize(true);
740  }
741 
742  QPair<bool, Pvl *> dataLabel = qMakePair(false, m_label);
743  if (!m_storesDnData) {
744  dataLabel = qMakePair(true, new Pvl(m_dataFileName->expanded()));
745  }
746 
747  // Now examine the format to see which type of handler to create
748  if (m_format == Bsq) {
749  m_ioHandler = new CubeBsqHandler(dataFile(), m_virtualBandList,
750  realDataFileLabel(), true);
751  }
752  else {
753  m_ioHandler = new CubeTileHandler(dataFile(), m_virtualBandList,
754  realDataFileLabel(), true);
755  }
756 
757  if (dataLabel.first) {
758  delete dataLabel.second;
759  dataLabel.second = NULL;
760  }
761 
762  applyVirtualBandsToLabel();
763  }
764 
765 
774  void Cube::reopen(QString access) {
775  if (!m_labelFile) {
776  QString msg = "Cube has not been opened yet. The filename to re-open is "
777  "unknown";
778  throw IException(IException::Programmer, msg, _FILEINFO_);
779  }
780 
781  // Preserve filename and virtual bands when re-opening
782  FileName filename = *m_labelFileName;
783  QList<int> virtualBandList;
784 
785  if (m_virtualBandList)
786  virtualBandList = *m_virtualBandList;
787 
788  close();
789  open(filename.expanded(), access);
790 
791  if (virtualBandList.size()) {
792  if (m_virtualBandList)
793  *m_virtualBandList = virtualBandList;
794  else
795  m_virtualBandList = new QList<int>(virtualBandList);
796  }
797  }
798 
799 
807  void Cube::read(Blob &blob, const std::vector<PvlKeyword> keywords) const {
808  if (!isOpen()) {
809  string msg = "The cube is not opened so you can't read a blob from it";
810  throw IException(IException::Programmer, msg, _FILEINFO_);
811  }
812 
813  FileName cubeFile = *m_labelFileName;
814  if (m_tempCube)
815  cubeFile = *m_tempCube;
816 
817  QMutexLocker locker(m_mutex);
818  QMutexLocker locker2(m_ioHandler->dataFileMutex());
819  blob.Read(cubeFile.toString(), *label(), keywords);
820  }
821 
822 
829  void Cube::read(Buffer &bufferToFill) const {
830  if (!isOpen()) {
831  string msg = "Try opening a file before you read it";
832  throw IException(IException::Programmer, msg, _FILEINFO_);
833  }
834 
835  QMutexLocker locker(m_mutex);
836  m_ioHandler->read(bufferToFill);
837  }
838 
839 
847  History Cube::readHistory(const QString &name) const {
848  Blob historyBlob(name, "History");
849  try {
850  // read history from cube, if it exists.
851  read(historyBlob);
852  }
853  catch (IException &) {
854  // if the history does not exist in the cube, this function creates it.
855  }
856  History history(historyBlob);
857  return history;
858  }
859 
860 
866  ImagePolygon Cube::readFootprint() const {
867  Blob footprintBlob("Footprint", "Polygon");
868  try {
869  // read history from cube, if it exists.
870  read(footprintBlob);
871  }
872  catch (IException &e) {
873  QString msg = "Footprintinit must be run prior to reading the footprint";
874  msg += " with POLYGON=TRUE for cube [" + fileName() + "]";
875  throw IException(e, IException::User, msg, _FILEINFO_);
876  }
877  ImagePolygon footprint(footprintBlob);
878  return footprint;
879  }
880 
881 
889  OriginalLabel Cube::readOriginalLabel(const QString &name) const {
890  Blob origLabelBlob(name, "OriginalLabel");
891  try {
892  read(origLabelBlob);
893  }
894  catch (IException &e){
895  QString msg = "Unable to locate OriginalLabel in " + fileName();
896  throw IException(e, IException::User, msg, _FILEINFO_);
897  }
898  OriginalLabel origLabel(origLabelBlob);
899  return origLabel;
900  }
901 
902 
912  CubeStretch Cube::readCubeStretch(QString name, const std::vector<PvlKeyword> keywords) const {
913  Blob stretchBlob(name, "Stretch");
914  try {
915  read(stretchBlob, keywords);
916  }
917  catch (IException &e){
918  QString msg = "Unable to locate Stretch information in " + fileName();
919  throw IException(e, IException::User, msg, _FILEINFO_);
920  }
921  CubeStretch cubeStretch(stretchBlob);
922  return stretchBlob;
923  }
924 
925 
931  OriginalXmlLabel Cube::readOriginalXmlLabel() const {
932  Blob origXmlLabelBlob("IsisCube", "OriginalXmlLabel");
933  try {
934  read(origXmlLabelBlob);
935  }
936  catch (IException &e){
937  QString msg = "Unable to locate OriginalXmlLabel in " + fileName();
938  throw IException(e, IException::User, msg, _FILEINFO_);
939  }
940  OriginalXmlLabel origXmlLabel(origXmlLabelBlob);
941  return origXmlLabel;
942  }
943 
944 
952  Table Cube::readTable(const QString &name) {
953  Blob tableBlob(name, "Table");
954  try {
955  read(tableBlob);
956  }
957  catch (IException &e) {
958  QString msg = "Failed to read table [" + name + "] from cube [" + fileName() + "].";
959  throw IException(e, IException::Programmer, msg, _FILEINFO_);
960  }
961  return Table(tableBlob);
962  }
963 
964 
971  void Cube::write(Blob &blob, bool overwrite) {
972  if (!isOpen()) {
973  string msg = "The cube is not opened so you can't write a blob to it";
974  throw IException(IException::Programmer, msg, _FILEINFO_);
975  }
976 
977  if (!m_labelFile->isWritable()) {
978  string msg = "The cube must be opened in read/write mode, not readOnly";
979  throw IException(IException::Programmer, msg, _FILEINFO_);
980  }
981 
982  // Write an attached blob
983  if (m_attached) {
984  QMutexLocker locker(m_mutex);
985  QMutexLocker locker2(m_ioHandler->dataFileMutex());
986 
987  // Compute the number of bytes in the cube + label bytes and if the
988  // endpos of the file // is not greater than this then seek to that position.
989  fstream stream(m_labelFileName->expanded().toLatin1().data(),
990  ios::in | ios::out | ios::binary);
991  stream.seekp(0, ios::end);
992 
993  // End byte = end byte of the file (aka eof position, file size)
994  streampos endByte = stream.tellp();
995  // maxbyte = position after the cube DN data and labels
996  streampos maxbyte = (streampos) m_labelBytes;
997 
998  if (m_storesDnData) {
999  maxbyte += (streampos) m_ioHandler->getDataSize();
1000  }
1001 
1002  // If EOF is too early, allocate space up to where we want the blob
1003  if (endByte < maxbyte) {
1004  stream.seekp(maxbyte, ios::beg);
1005  }
1006 
1007  // Use default argument of "" for detached stream
1008  blob.Write(*m_label, stream, "", overwrite);
1009  }
1010 
1011  // Write a detached blob
1012  else {
1013  FileName blobFileName = fileName();
1014  blobFileName = blobFileName.removeExtension();
1015  blobFileName = blobFileName.addExtension(blob.Type());
1016  blobFileName = blobFileName.addExtension(blob.Name());
1017  QString blobFile(blobFileName.expanded());
1018  ios::openmode flags = ios::in | ios::binary | ios::out | ios::trunc;
1019  fstream detachedStream;
1020  detachedStream.open(blobFile.toLatin1().data(), flags);
1021  if (!detachedStream) {
1022  QString message = "Unable to open data file [" +
1023  blobFileName.expanded() + "]";
1024  throw IException(IException::Io, message, _FILEINFO_);
1025  }
1026 
1027  blob.Write(*m_label, detachedStream, blobFileName.name());
1028  }
1029  }
1030 
1031 
1038  void Cube::write(OriginalLabel &lab) {
1039  Blob labelBlob = lab.toBlob();
1040  write(labelBlob);
1041  }
1042 
1043 
1050  void Cube::write(const OriginalXmlLabel &lab) {
1051  Blob labelBlob = lab.toBlob();
1052  write(labelBlob);
1053  }
1054 
1055 
1064  void Cube::write(const Table &table) {
1065  Blob tableBlob = table.toBlob();
1066  write(tableBlob);
1067  }
1068 
1069 
1078  void Cube::write(const CubeStretch &cubeStretch) {
1079  Blob cubeStretchBlob = cubeStretch.toBlob();
1080  write(cubeStretchBlob);
1081  }
1082 
1083 
1094  void Cube::write(History &history, const QString &name) {
1095  Blob histBlob = history.toBlob(name);
1096  write(histBlob);
1097  }
1098 
1099 
1106  void Cube::write(const ImagePolygon &polygon) {
1107  Blob polyBlob = polygon.toBlob();
1108  write(polyBlob);
1109  }
1110 
1111 
1118  void Cube::write(Buffer &bufferToWrite) {
1119  if (!isOpen()) {
1120  string msg = "Tried to write to a cube before opening/creating it";
1121  throw IException(IException::Programmer, msg, _FILEINFO_);
1122  }
1123 
1124  if (isReadOnly()) {
1125  QString msg = "Cannot write to the cube [" + (QString)QFileInfo(fileName()).fileName() +
1126  "] because it is opened read-only";
1127  throw IException(IException::Programmer, msg, _FILEINFO_);
1128  }
1129 
1130  if (!m_storesDnData) {
1131  QString msg = "The cube [" + QFileInfo(fileName()).fileName() +
1132  "] does not support storing DN data because it is using an external file for DNs";
1133  throw IException(IException::Unknown, msg, _FILEINFO_);
1134  }
1135 
1136  QMutexLocker locker(m_mutex);
1137  m_ioHandler->write(bufferToWrite);
1138  }
1139 
1140 
1151  void Cube::setBaseMultiplier(double base, double mult) {
1152  openCheck();
1153  m_base = base;
1154  m_multiplier = mult;
1155  }
1156 
1157 
1168  void Cube::setMinMax(double min, double max) {
1169  openCheck();
1170 
1171  m_base = 0.0;
1172  m_multiplier = 1.0;
1173 
1174  double x1, x2;
1175  if (m_pixelType == UnsignedByte) {
1176  x1 = VALID_MIN1;
1177  x2 = VALID_MAX1;
1178  m_multiplier = (max - min) / (x2 - x1);
1179  m_base = min - m_multiplier * x1;
1180  }
1181  else if (m_pixelType == SignedWord) {
1182  x1 = VALID_MIN2;
1183  x2 = VALID_MAX2;
1184  m_multiplier = (max - min) / (x2 - x1);
1185  m_base = min - m_multiplier * x1;
1186  }
1187  else if (m_pixelType == UnsignedWord) {
1188  x1 = VALID_MINU2;
1189  x2 = VALID_MAXU2;
1190  m_multiplier = (max - min) / (x2 - x1);
1191  m_base = min - m_multiplier * x1;
1192  }
1193  }
1194 
1195 
1202  void Cube::setByteOrder(ByteOrder byteOrder) {
1203  openCheck();
1204  m_byteOrder = byteOrder;
1205  }
1206 
1207 
1217  void Cube::setDimensions(int ns, int nl, int nb) {
1218  openCheck();
1219  if ((ns < 1) || (nl < 1) || (nb < 1)) {
1220  string msg = "SetDimensions: Invalid number of sample, lines or bands";
1221  throw IException(IException::Programmer, msg, _FILEINFO_);
1222  }
1223  m_samples = ns;
1224  m_lines = nl;
1225  m_bands = nb;
1226  }
1227 
1228 
1234  void Cube::setExternalDnData(FileName cubeFileWithDnData) {
1235  try {
1236  initLabelFromFile(cubeFileWithDnData, false);
1237  initCoreFromLabel(*m_label);
1238 
1239  delete m_label;
1240  m_label = NULL;
1241  }
1242  catch (IException &) {
1243  delete m_label;
1244  m_label = NULL;
1245  throw;
1246  }
1247 
1248  m_storesDnData = false;
1249  m_dataFileName = new FileName(cubeFileWithDnData);
1250 
1251  delete m_labelFile;
1252  m_labelFile = NULL;
1253 
1254  delete m_labelFileName;
1255  m_labelFileName = NULL;
1256  }
1257 
1258 
1266  void Cube::setFormat(Format format) {
1267  openCheck();
1268  m_format = format;
1269  }
1270 
1271 
1278  void Cube::setLabelsAttached(bool attach) {
1279  openCheck();
1280  m_attached = attach;
1281  }
1282 
1283 
1291  void Cube::setLabelSize(int labelBytes) {
1292  openCheck();
1293  m_labelBytes = labelBytes;
1294  }
1295 
1296 
1304  void Cube::setPixelType(PixelType pixelType) {
1305  openCheck();
1306  m_pixelType = pixelType;
1307  }
1308 
1309 
1321  void Cube::setVirtualBands(const QList<QString> &vbands) {
1322  openCheck();
1323  if (m_virtualBandList)
1324  m_virtualBandList->clear();
1325  else
1326  m_virtualBandList = new QList<int>;
1327 
1328  if (vbands.size() > 0) {
1329  QListIterator<QString> it(vbands);
1330  while (it.hasNext()) {
1331  m_virtualBandList->append(toInt(it.next()));
1332  }
1333  }
1334  else {
1335  delete m_virtualBandList;
1336  m_virtualBandList = NULL;
1337  }
1338 
1339  if (m_ioHandler) {
1340  m_ioHandler->setVirtualBands(m_virtualBandList);
1341  }
1342  }
1343 
1344 
1351  void Cube::setVirtualBands(const std::vector<QString> &vbands) {
1352  QList<QString> realVBands;
1353 
1354  for(unsigned int i = 0; i < vbands.size(); i++)
1355  realVBands << vbands[i];
1356 
1357  setVirtualBands(realVBands);
1358  }
1359 
1360 
1366  void Cube::relocateDnData(FileName dnDataFile) {
1367  if (!isOpen()) {
1368  throw IException(IException::Unknown,
1369  QString("Cannot relocate the DN data to [%1] for an external cube label "
1370  "file which is not open.")
1371  .arg(dnDataFile.original()),
1372  _FILEINFO_);
1373  }
1374 
1375 
1376  if (m_storesDnData) {
1377  throw IException(IException::Unknown,
1378  QString("The cube [%1] stores DN data. It cannot be relocated to [%2] - "
1379  "this is only supported for external cube label files.")
1380  .arg(m_labelFileName->original()).arg(dnDataFile.original()),
1381  _FILEINFO_);
1382  }
1383 
1384  m_label->findObject("IsisCube").findObject("Core").findKeyword("^DnFile")[0] =
1385  dnDataFile.original();
1386  reopen(m_labelFile->isWritable()? "rw" : "r");
1387  }
1388 
1389 
1390 // void Cube::relocateDnData(FileName externalLabelFile, FileName dnDataFile) {
1391 // try {
1392 // Pvl externalLabelData(externalLabelFile.expanded());
1393 // externalLabelData.FindObject("IsisCube").FindObject("Core").FindKeyword("^DnFile")[0] =
1394 // dnDataFile.original();
1395 // }
1396 // catch (IException &e) {
1397 // throw IException(e, IException::Io,
1398 // QString("File [%1] does not appear to be an external cube label file")
1399 // .arg(externalLabelFile.original().ToQt()),
1400 // _FILEINFO_);
1401 // }
1402 // }
1403 
1404 
1410  int Cube::bandCount() const {
1411  int numBands = m_bands;
1412  if (m_virtualBandList)
1413  numBands = m_virtualBandList->size();
1414  return numBands;
1415  }
1416 
1417 
1427  double Cube::base() const {
1428  return m_base;
1429  }
1430 
1431 
1439  ByteOrder Cube::byteOrder() const {
1440  return m_byteOrder;
1441  }
1442 
1443 
1451  Camera *Cube::camera() {
1452  if (m_camera == NULL && isOpen()) {
1453  m_camera = CameraFactory::Create(*this);
1454  }
1455  return m_camera;
1456  }
1457 
1458 
1459  void Cube::attachSpiceFromIsd(nlohmann::json isd) {
1460  PvlKeyword lkKeyword("LeapSecond");
1461  PvlKeyword pckKeyword("TargetAttitudeShape");
1462  PvlKeyword targetSpkKeyword("TargetPosition");
1463  PvlKeyword ckKeyword("InstrumentPointing");
1464  PvlKeyword ikKeyword("Instrument");
1465  PvlKeyword sclkKeyword("SpacecraftClock");
1466  PvlKeyword spkKeyword("InstrumentPosition");
1467  PvlKeyword iakKeyword("InstrumentAddendum");
1468  PvlKeyword demKeyword("ShapeModel");
1469  PvlKeyword exkKeyword("Extra");
1470 
1471  Spice spice(*this->label(), isd);
1472  Table ckTable = spice.instrumentRotation()->Cache("InstrumentPointing");
1473  ckTable.Label() += PvlKeyword("Kernels");
1474 
1475  for (int i = 0; i < ckKeyword.size(); i++)
1476  ckTable.Label()["Kernels"].addValue(ckKeyword[i]);
1477 
1478  this->write(ckTable);
1479 
1480  Table spkTable = spice.instrumentPosition()->Cache("InstrumentPosition");
1481  spkTable.Label() += PvlKeyword("Kernels");
1482  for (int i = 0; i < spkKeyword.size(); i++)
1483  spkTable.Label()["Kernels"].addValue(spkKeyword[i]);
1484 
1485  this->write(spkTable);
1486 
1487  Table bodyTable = spice.bodyRotation()->Cache("BodyRotation");
1488  bodyTable.Label() += PvlKeyword("Kernels");
1489  for (int i = 0; i < targetSpkKeyword.size(); i++)
1490  bodyTable.Label()["Kernels"].addValue(targetSpkKeyword[i]);
1491 
1492  for (int i = 0; i < pckKeyword.size(); i++)
1493  bodyTable.Label()["Kernels"].addValue(pckKeyword[i]);
1494 
1495  bodyTable.Label() += PvlKeyword("SolarLongitude",
1496  toString(spice.solarLongitude().degrees()));
1497  this->write(bodyTable);
1498 
1499  Table sunTable = spice.sunPosition()->Cache("SunPosition");
1500  sunTable.Label() += PvlKeyword("Kernels");
1501  for (int i = 0; i < targetSpkKeyword.size(); i++)
1502  sunTable.Label()["Kernels"].addValue(targetSpkKeyword[i]);
1503 
1504  this->write(sunTable);
1505 
1506  PvlGroup currentKernels = this->group("Kernels");
1507 
1508  Pvl *label = this->label();
1509  int i = 0;
1510  while (i < label->objects()) {
1511  PvlObject currObj = label->object(i);
1512  if (currObj.isNamed("NaifKeywords")) {
1513  label->deleteObject(i);
1514  }
1515  else {
1516  i ++;
1517  }
1518  }
1519 
1520  *(this->label()) += spice.getStoredNaifKeywords();
1521 
1522  // Access the camera here while all of the kernels are still loaded.
1523  // This needs to be done for some cameras that need loaded spice data
1524  // to actually create the camera model. (KaguyaTC for example)
1525  this->camera();
1526  }
1527 
1528 
1535  FileName Cube::externalCubeFileName() const {
1536  if (!isOpen()) {
1537  throw IException(IException::Unknown,
1538  "An external cube label file must be opened in order to use "
1539  "Cube::getExternalCubeFileName",
1540  _FILEINFO_);
1541  }
1542 
1543  if (storesDnData()) {
1544  throw IException(IException::Unknown,
1545  "Cube::getExternalCubeFileName can only be called on an external cube label "
1546  "file",
1547  _FILEINFO_);
1548  }
1549 
1550 
1551  PvlObject &core = m_label->findObject("IsisCube").findObject("Core");
1552 
1553  return core["^DnFile"][0];
1554  }
1555 
1556 
1563  QString Cube::fileName() const {
1564  if (isOpen())
1565  return m_labelFileName->expanded();
1566  else
1567  return "";
1568  }
1569 
1570 
1575  Cube::Format Cube::format() const {
1576  return m_format;
1577  }
1578 
1579 
1599  Histogram *Cube::histogram(const int &band, QString msg) {
1600  return histogram(band, ValidMinimum, ValidMaximum, msg);
1601  }
1602 
1603 
1629  Histogram *Cube::histogram(const int &band, const double &validMin,
1630  const double &validMax, QString msg) {
1631  // Make sure cube is open
1632  if ( !isOpen() ) {
1633  QString msg = "Cannot create histogram object for an unopened cube";
1634  throw IException(IException::Programmer, msg, _FILEINFO_);
1635  }
1636 
1637  // Make sure band is valid
1638  if ((band < 0) || (band > bandCount())) {
1639  QString msg = "Invalid band in [CubeInfo::Histogram]";
1640  throw IException(IException::Programmer, msg, _FILEINFO_);
1641  }
1642 
1643  int bandStart = band;
1644  int bandStop = band;
1645  int maxSteps = lineCount();
1646  if (band == 0) {
1647  bandStart = 1;
1648  bandStop = bandCount();
1649  maxSteps = lineCount() * bandCount();
1650  }
1651 
1652  Progress progress;
1653  Histogram *hist = new ImageHistogram(*this, band, &progress);
1654  LineManager line(*this);
1655 
1656  // This range is for throwing out data; the default parameters are OK always
1657  //hist->SetValidRange(validMin, validMax);
1658 
1659  // We now need to know the binning range - ValidMinimum/Maximum are no longer
1660  // acceptable, default to the bin range start/end.
1661  double binMin = validMin;
1662  double binMax = validMax;
1663  if (binMin == ValidMinimum) {
1664  binMin = hist->BinRangeStart();
1665  }
1666 
1667  if (binMax == ValidMaximum) {
1668  binMax = hist->BinRangeEnd();
1669  }
1670 
1671  //hist->SetBinRange(binMin, binMax);
1672  hist->SetValidRange(binMin,binMax);
1673 
1674  // Loop and get the histogram
1675  progress.SetText(msg);
1676  progress.SetMaximumSteps(maxSteps);
1677  progress.CheckStatus();
1678 
1679  for(int useBand = bandStart ; useBand <= bandStop ; useBand++) {
1680  for(int i = 1; i <= lineCount(); i++) {
1681  line.SetLine(i, useBand);
1682  read(line);
1683  hist->AddData(line.DoubleBuffer(), line.size());
1684  progress.CheckStatus();
1685  }
1686  }
1687 
1688  return hist;
1689  }
1690 
1691 
1701  Pvl *Cube::label() const {
1702  return m_label;
1703  }
1704 
1705 
1713  int Cube::labelSize(bool actual) const {
1714  int labelSize = m_labelBytes;
1715 
1716  if (actual && m_label) {
1717  ostringstream s;
1718  s << *m_label << endl;
1719  labelSize = s.tellp();
1720  }
1721  else if (actual) {
1722  labelSize = 0;
1723  }
1724 
1725  return labelSize;
1726  }
1727 
1728 
1734  int Cube::lineCount() const {
1735  return m_lines;
1736  }
1737 
1738 
1748  double Cube::multiplier() const {
1749  return m_multiplier;
1750  }
1751 
1752 
1758  PixelType Cube::pixelType() const {
1759  return m_pixelType;
1760  }
1761 
1762 
1773  int Cube::physicalBand(const int &virtualBand) const {
1774  int physicalBand = virtualBand;
1775 
1776  if (m_virtualBandList) {
1777  if ((virtualBand < 1) ||
1778  (virtualBand > m_virtualBandList->size())) {
1779  QString msg = "Out of array bounds [" + toString(virtualBand) + "]";
1780  throw IException(IException::Programmer, msg, _FILEINFO_);
1781  }
1782  physicalBand = m_virtualBandList->at(virtualBand - 1);
1783  }
1784 
1785  return physicalBand;
1786  }
1787 
1788 
1794  Projection *Cube::projection() {
1795  if (m_projection == NULL && isOpen()) {
1796  m_projection = ProjectionFactory::CreateFromCube(*label());
1797  }
1798  return m_projection;
1799  }
1800 
1801 
1807  int Cube::sampleCount() const {
1808  return m_samples;
1809  }
1810 
1811 
1830  Statistics *Cube::statistics(const int &band, QString msg) {
1831  return statistics(band, ValidMinimum, ValidMaximum, msg);
1832  }
1833 
1834 
1851  Statistics *Cube::statistics(const int &band, const double &validMin,
1852  const double &validMax, QString msg) {
1853  // Make sure cube is open
1854  if ( !isOpen() ) {
1855  QString msg = "Cannot create statistics object for an unopened cube";
1856  throw IException(IException::Programmer, msg, _FILEINFO_);
1857  }
1858 
1859  // Make sure band is valid
1860  if ((band < 0) || (band > bandCount())) {
1861  string msg = "Invalid band in [CubeInfo::Statistics]";
1862  throw IException(IException::Programmer, msg, _FILEINFO_);
1863  }
1864 
1865  // Construct a line buffer manager and a statistics object
1866  LineManager line(*this);
1867  Statistics *stats = new Statistics();
1868 
1869  stats->SetValidRange(validMin, validMax);
1870 
1871  int bandStart = band;
1872  int bandStop = band;
1873  int maxSteps = lineCount();
1874  if (band == 0) {
1875  bandStart = 1;
1876  bandStop = bandCount();
1877  maxSteps = lineCount() * bandCount();
1878  }
1879 
1880  Progress progress;
1881  progress.SetText(msg);
1882  progress.SetMaximumSteps(maxSteps);
1883  progress.CheckStatus();
1884 
1885  // Loop and get the statistics for a good minimum/maximum
1886  for(int useBand = bandStart ; useBand <= bandStop ; useBand++) {
1887  for(int i = 1; i <= lineCount(); i++) {
1888  line.SetLine(i, useBand);
1889  read(line);
1890  stats->AddData(line.DoubleBuffer(), line.size());
1891  progress.CheckStatus();
1892  }
1893  }
1894 
1895  return stats;
1896  }
1897 
1898 
1904  bool Cube::storesDnData() const {
1905  return m_storesDnData;
1906  }
1907 
1908 
1922  void Cube::addCachingAlgorithm(CubeCachingAlgorithm *algorithm) {
1923 
1924  if (isOpen() && m_ioHandler) {
1925  m_ioHandler->addCachingAlgorithm(algorithm);
1926  }
1927  else if (!isOpen()) {
1928  QString msg = "Cannot add a caching algorithm until the cube is open";
1929  throw IException(IException::Programmer, msg, _FILEINFO_);
1930  }
1931  }
1932 
1938  void Cube::clearIoCache() {
1939  if (m_ioHandler) {
1940  QMutexLocker locker(m_mutex);
1941  m_ioHandler->clearCache();
1942  }
1943  }
1944 
1945 
1955  bool Cube::deleteBlob(QString BlobName, QString BlobType) {
1956  for(int i = 0; i < m_label->objects(); i++) {
1957  PvlObject obj = m_label->object(i);
1958  if (obj.name().compare(BlobType) == 0) {
1959  if (obj.findKeyword("Name")[0] == BlobName) {
1960  m_label->deleteObject(i);
1961  return true;
1962  }
1963  }
1964  }
1965  return false;
1966  }
1967 
1968 
1977  void Cube::deleteGroup(const QString &group) {
1978  PvlObject &isiscube = label()->findObject("IsisCube");
1979  if (!isiscube.hasGroup(group)) return;
1980  isiscube.deleteGroup(group);
1981  }
1982 
1983 
1991  PvlGroup &Cube::group(const QString &group) const {
1992  PvlObject &isiscube = label()->findObject("IsisCube");
1993  return isiscube.findGroup(group);
1994  }
1995 
1996 
2004  bool Cube::hasGroup(const QString &group) const {
2005  const PvlObject &isiscube = label()->findObject("IsisCube");
2006  if (isiscube.hasGroup(group)) return true;
2007  return false;
2008  }
2009 
2010 
2019  bool Cube::hasBlob(const QString &name, const QString &type) {
2020  for(int o = 0; o < label()->objects(); o++) {
2021  PvlObject &obj = label()->object(o);
2022  if (obj.isNamed(type)) {
2023  if (obj.hasKeyword("Name")) {
2024  QString temp = (QString) obj["Name"];
2025  temp = temp.toUpper();
2026  QString temp2 = name;
2027  temp2 = temp2.toUpper();
2028  if (temp == temp2) return true;
2029  }
2030  }
2031  }
2032  return false;
2033  }
2034 
2035 
2043  bool Cube::hasTable(const QString &name) {
2044  return hasBlob(name, "Table");
2045  }
2046 
2047 
2056  void Cube::putGroup(const PvlGroup &group) {
2057  if (isReadOnly()) {
2058  QString msg = "Cannot add a group to the label of cube [" + (QString)QFileInfo(fileName()).fileName() +
2059  "] because it is opened read-only";
2060  throw IException(IException::Programmer, msg, _FILEINFO_);
2061  return;
2062  }
2063 
2064  PvlObject &isiscube = label()->findObject("IsisCube");
2065  if (isiscube.hasGroup(group.name())) {
2066  isiscube.findGroup(group.name()) = group;
2067  }
2068  else {
2069  isiscube.addGroup(group);
2070  }
2071  }
2072 
2073 
2078  void Cube::applyVirtualBandsToLabel() {
2079  PvlObject &core = m_label->findObject("IsisCube").findObject("Core");
2080 
2081  // Prune the band bin group if it exists
2082  if (m_label->findObject("IsisCube").hasGroup("BandBin")) {
2083  PvlGroup &bandBin = m_label->findObject("IsisCube").findGroup("BandBin");
2084  for (int k = 0;k < bandBin.keywords();k++) {
2085  if (bandBin[k].size() == m_bands && m_virtualBandList) {
2086  PvlKeyword temp = bandBin[k];
2087  bandBin[k].clear();
2088  for (int i = 0;i < m_virtualBandList->size();i++) {
2089  int physicalBand = m_virtualBandList->at(i) - 1;
2090  bandBin[k].addValue(temp[physicalBand], temp.unit(physicalBand));
2091  }
2092  }
2093  }
2094  }
2095 
2096  // Change the number of bands in the labels of the cube
2097  if (m_virtualBandList && core.hasGroup("Dimensions")) core.findGroup("Dimensions")["Bands"] = toString(m_virtualBandList->size());
2098  }
2099 
2100 
2106  void Cube::cleanUp(bool removeIt) {
2107  if (m_ioHandler) {
2108  delete m_ioHandler;
2109  m_ioHandler = NULL;
2110  }
2111 
2112  // Always remove a temporary file
2113  if (m_tempCube) {
2114  QFile::remove(m_tempCube->expanded());
2115  removeIt = false; // dont remove originals
2116 
2117  delete m_tempCube;
2118  m_tempCube = NULL;
2119  }
2120 
2121  if (removeIt) {
2122  QFile::remove(m_labelFileName->expanded());
2123 
2124  if (*m_labelFileName != *m_dataFileName)
2125  QFile::remove(m_dataFileName->expanded());
2126  }
2127 
2128  delete m_labelFile;
2129  m_labelFile = NULL;
2130 
2131  delete m_dataFile;
2132  m_dataFile = NULL;
2133 
2134  delete m_labelFileName;
2135  m_labelFileName = NULL;
2136 
2137  delete m_dataFileName;
2138  m_dataFileName = NULL;
2139 
2140  delete m_label;
2141  m_label = NULL;
2142 
2143  delete m_virtualBandList;
2144  m_virtualBandList = NULL;
2145 
2146  initialize();
2147  }
2148 
2149 
2154  void Cube::construct() {
2155  m_labelFile = NULL;
2156  m_dataFile = NULL;
2157  m_ioHandler = NULL;
2158  m_mutex = NULL;
2159 
2160  m_camera = NULL;
2161  m_projection = NULL;
2162 
2163  m_labelFileName = NULL;
2164  m_dataFileName = NULL;
2165  m_tempCube = NULL;
2166  m_formatTemplateFile = NULL;
2167  m_label = NULL;
2168 
2169  m_virtualBandList = NULL;
2170 
2171  m_mutex = new QMutex();
2172  m_formatTemplateFile =
2173  new FileName("$ISISROOT/appdata/templates/labels/CubeFormatTemplate.pft");
2174 
2175  initialize();
2176  }
2177 
2178 
2185  QFile *Cube::dataFile() const {
2186  if (m_dataFile)
2187  return m_dataFile;
2188  else
2189  return m_labelFile;
2190  }
2191 
2192 
2200  FileName Cube::realDataFileName() const {
2201  FileName result;
2202 
2203  // Attached, stores DN data - normal cube
2204  if (m_attached && m_storesDnData) {
2205  ASSERT(m_labelFileName);
2206  result = *m_labelFileName;
2207  }
2208  // Detached, stores DN data - standard detached cube
2209  else if (!m_attached && m_storesDnData) {
2210  ASSERT(m_dataFileName);
2211  result = *m_dataFileName;
2212  }
2213  // External cube - go look at our external file
2214  else if (!m_storesDnData) {
2215  ASSERT(m_dataFileName);
2216  FileName guess = *m_dataFileName;
2217  QDir dir(guess.toString());
2218 
2219  // If path is relative and there is a labelFileName, start in directory of the ecub, then
2220  // cd to the directory containing the DnFile, since it is relative to the location of the ecub.
2221  // We need to turn the relative path into an absolute path.
2222  if (dir.isRelative() && m_labelFileName) {
2223  QDir dir2(m_labelFileName->originalPath());
2224  dir2.cd(guess.path());
2225  guess = dir2.absolutePath() + "/" + guess.name();
2226  }
2227  do {
2228  Pvl guessLabel(guess.expanded());
2229 
2230  PvlObject &core = guessLabel.findObject("IsisCube").findObject("Core");
2231 
2232  if (core.hasKeyword("^DnFile")) {
2233  FileName currentGuess = guess;
2234  guess = core["^DnFile"][0];
2235 
2236  if (!guess.path().startsWith("/")) {
2237  guess = currentGuess.path() + "/" + guess.original();
2238  }
2239  }
2240  else if (core.hasKeyword("^Core")) {
2241  result = core["^Core"][0];
2242  }
2243  else {
2244  result = guess;
2245  }
2246  }
2247  while (result.name() == "");
2248  }
2249 
2250  return result;
2251  }
2252 
2253 
2265  void Cube::initialize() {
2266  m_byteOrder = Lsb;
2267  if (IsBigEndian())
2268  m_byteOrder = Msb;
2269  m_format = Tile;
2270  m_pixelType = Real;
2271 
2272  m_attached = true;
2273  m_storesDnData = true;
2274  m_labelBytes = 65536;
2275 
2276  m_samples = 0;
2277  m_lines = 0;
2278  m_bands = 0;
2279 
2280  m_base = 0.0;
2281  m_multiplier = 1.0;
2282  }
2283 
2284 
2290  void Cube::initCoreFromLabel(const Pvl &label) {
2291  const PvlObject &core = label.findObject("IsisCube").findObject("Core");
2292 
2293  if (!core.hasKeyword("^DnFile")) {
2294  // Dimensions
2295  const PvlGroup &dims = core.findGroup("Dimensions");
2296  m_samples = dims["Samples"];
2297  m_lines = dims["Lines"];
2298  m_bands = dims["Bands"];
2299 
2300  // Stored pixel information
2301  const PvlGroup &pixelsGroup = core.findGroup("Pixels");
2302  m_byteOrder = ByteOrderEnumeration(pixelsGroup["ByteOrder"]);
2303  m_base = pixelsGroup["Base"];
2304  m_multiplier = pixelsGroup["Multiplier"];
2305  m_pixelType = PixelTypeEnumeration(pixelsGroup["Type"]);
2306 
2307  // Now examine the format to see which type of handler to create
2308  if ((QString) core["Format"] == "BandSequential") {
2309  m_format = Bsq;
2310  }
2311  else {
2312  m_format = Tile;
2313  }
2314  }
2315  else {
2316  FileName temp(core["^DnFile"][0]);
2317  if (!temp.expanded().startsWith("/")) {
2318  temp = FileName(m_labelFileName->path() + "/" + temp.original());
2319  }
2320 
2321  initCoreFromLabel(Pvl(temp.toString()));
2322  }
2323  }
2324 
2325 
2334  void Cube::initLabelFromFile(FileName labelFileName, bool readWrite) {
2335  ASSERT(!m_labelFileName);
2336 
2337  try {
2338  if (labelFileName.fileExists()) {
2339  m_label = new Pvl(labelFileName.expanded());
2340  if (!m_label->objects()) {
2341  throw IException();
2342  }
2343  }
2344  }
2345  catch(IException &) {
2346  if (m_label) {
2347  delete m_label;
2348  m_label = NULL;
2349  }
2350  }
2351 
2352  try {
2353  if (!m_label) {
2354  FileName tmp(labelFileName);
2355  tmp = tmp.addExtension("cub");
2356  if (tmp.fileExists()) {
2357  m_label = new Pvl(tmp.expanded());
2358  if (!m_label->objects()) {
2359  throw IException();
2360  }
2361  labelFileName = tmp;
2362  }
2363  }
2364  }
2365  catch(IException &e) {
2366  if (m_label) {
2367  delete m_label;
2368  m_label = NULL;
2369  }
2370  }
2371 
2372  try {
2373  if (!m_label) {
2374  FileName tmp(labelFileName);
2375  tmp = tmp.setExtension("lbl");
2376  if (tmp.fileExists()) {
2377  m_label = new Pvl(tmp.expanded());
2378  if (!m_label->objects()) {
2379  throw IException();
2380  }
2381  labelFileName = tmp;
2382  }
2383  }
2384  }
2385  catch(IException &e) {
2386  if (m_label) {
2387  delete m_label;
2388  m_label = NULL;
2389  }
2390  }
2391 
2392  try {
2393  if (!m_label) {
2394  FileName tmp(labelFileName);
2395  tmp = tmp.addExtension("ecub");
2396  if (tmp.fileExists()) {
2397  m_label = new Pvl(tmp.expanded());
2398  if (!m_label->objects()) {
2399  throw IException();
2400  }
2401  labelFileName = tmp;
2402  }
2403  }
2404  }
2405  catch(IException &e) {
2406  if (m_label) {
2407  delete m_label;
2408  m_label = NULL;
2409  }
2410  }
2411 
2412  if (!m_label) {
2413  QString msg = Message::FileOpen(labelFileName.original());
2414  throw IException(IException::Io, msg, _FILEINFO_);
2415  }
2416 
2417  m_labelFileName = new FileName(labelFileName);
2418 
2419  // See if this is an old Isis cube format. If so then we will
2420  // need to internalize a new label
2421  if (m_label->hasKeyword("CCSD3ZF0000100000001NJPL3IF0PDS200000001")) {
2422  if (!readWrite) {
2423  reformatOldIsisLabel(m_labelFileName->expanded());
2424  }
2425  else {
2426  QString msg = "Can not open [" + m_labelFileName->original() + "]"
2427  " because it is an ISIS2 cube.";
2428  cleanUp(false);
2429  throw IException(IException::Io, msg, _FILEINFO_);
2430  }
2431  }
2432  else {
2433  m_labelFile = new QFile(m_labelFileName->expanded());
2434  }
2435  }
2436 
2437 
2441  void Cube::openCheck() {
2442  if (isOpen()) {
2443  string msg = "Sorry you can't do a SetMethod after the cube is opened";
2444  throw IException(IException::Programmer, msg, _FILEINFO_);
2445  }
2446  }
2447 
2448 
2454  Pvl Cube::realDataFileLabel() const {
2455  Pvl label = *m_label;
2456  PvlObject *core = NULL;
2457 
2458  do {
2459  core = &label.findObject("IsisCube").findObject("Core");
2460 
2461  if (core->hasKeyword("^DnFile")) {
2462 
2463  FileName temp((*core)["^DnFile"][0]);
2464  if (!temp.expanded().startsWith("/")) {
2465  temp = realDataFileName();
2466  }
2467 
2468  label = Pvl(temp.toString());
2469  core = NULL;
2470  }
2471  }
2472  while (!core);
2473 
2474  return label;
2475  }
2476 
2477 
2484  void Cube::reformatOldIsisLabel(const QString &oldCube) {
2485  QString parameters = "from=" + oldCube;
2486  FileName oldName(oldCube);
2487  FileName tempCube = FileName::createTempFile("Temporary_" + oldName.name() + ".cub");
2488  parameters += " to=" + tempCube.expanded();
2489 
2490  if (iApp == NULL) {
2491  QString command = "$ISISROOT/bin/pds2isis " + parameters;
2492  ProgramLauncher::RunSystemCommand(command);
2493  }
2494  else {
2495  QString prog = "pds2isis";
2496  ProgramLauncher::RunIsisProgram(prog, parameters);
2497  }
2498 
2499  m_tempCube = new FileName(tempCube);
2500  *m_label = Pvl(m_tempCube->toString());
2501  m_labelFile = new QFile(m_tempCube->expanded());
2502  }
2503 
2504 
2514  void Cube::latLonRange(double &minLatitude, double &maxLatitude, double &minLongitude, double &
2515  maxLongitude) {
2516  Camera *cam;
2517  TProjection *proj;
2518 
2519  bool isGood = false;
2520  bool useProj = true;
2521 
2522  if (hasGroup("Instrument")) {
2523  useProj = false;
2524  }
2525 
2526  // setup camera or projection
2527  if (useProj) {
2528  try {
2529  proj = (TProjection *) projection();
2530  }
2531  catch(IException &e) {
2532  QString msg = "Cannot calculate lat/lon range without a camera or projection";
2533  throw IException(e, IException::User, msg, _FILEINFO_);
2534  }
2535  }
2536  else {
2537  try {
2538  cam = camera();
2539  }
2540  catch(IException &e) {
2541  QString msg = "Unable to create camera when calculating a lat/lon range.";
2542  throw IException(e, IException::User, msg, _FILEINFO_);
2543  }
2544  }
2545 
2546  // Iterate over all samp/line combos in cube
2547  minLatitude = 99999;
2548  minLongitude = 99999;
2549  maxLatitude = -99999;
2550  maxLongitude = -99999;
2551 
2552  for (double sample = 0.5; sample < sampleCount() + 0.5; sample++) {
2553  // Checks to see if the point is in outer space
2554  for (double line = 0.5; line < lineCount() + 0.5; line++) {
2555  if (useProj) {
2556  isGood = proj->SetWorld(sample, line);
2557  }
2558  else {
2559  isGood = cam->SetImage(sample, line);
2560  }
2561 
2562  double lat, lon;
2563  if (isGood) {
2564  if (useProj) {
2565  lat = proj->UniversalLatitude();
2566  lon = proj->UniversalLongitude();
2567  }
2568  else {
2569  lat = cam->UniversalLatitude();
2570  lon = cam->UniversalLongitude();
2571  }
2572 
2573  // update mix/max lat/lons
2574  if (lat < minLatitude) {
2575  minLatitude = lat;
2576  }
2577  else if (lat > maxLatitude) {
2578  maxLatitude = lat;
2579  }
2580 
2581  if (lon < minLongitude) {
2582  minLongitude = lon;
2583  }
2584  else if (lon > maxLongitude) {
2585  maxLongitude = lon;
2586  }
2587  }
2588  }
2589  }
2590  if ( (minLatitude == 99999) || (minLongitude == 99999) || (maxLatitude == -99999) ||
2591  (maxLongitude == -99999) ) {
2592  QString msg = "Unable to calculate a minimum or maximum latitutde or longitude.";
2593  throw IException(IException::Unknown, msg, _FILEINFO_);
2594  }
2595  }
2596 
2601  void Cube::writeLabels() {
2602  if (!isOpen()) {
2603  string msg = "Cube must be opened first before writing labels";
2604  throw IException(IException::Programmer, msg, _FILEINFO_);
2605  }
2606 
2607  // Set the pvl's format template
2608  m_label->setFormatTemplate(m_formatTemplateFile->original());
2609 
2610  // Write them with attached data
2611  if (m_attached) {
2612  QMutexLocker locker(m_mutex);
2613  QMutexLocker locker2(m_ioHandler->dataFileMutex());
2614 
2615  ostringstream temp;
2616  temp << *m_label << endl;
2617  string tempstr = temp.str();
2618  if ((int) tempstr.length() < m_labelBytes) {
2619  QByteArray labelArea(m_labelBytes, '\0');
2620  QByteArray labelUnpaddedContents(tempstr.c_str(), tempstr.length());
2621  labelArea.replace(0, labelUnpaddedContents.size(), labelUnpaddedContents);
2622  // Rewrite the label area
2623  m_labelFile->seek(0);
2624  m_labelFile->write(labelArea);
2625  }
2626  else {
2627  locker2.unlock();
2628  QString msg = "Label space is full in [" +
2629  (QString)FileName(*m_labelFileName).name() +
2630  "] unable to write labels";
2631  cleanUp(false);
2632  throw IException(IException::Io, msg, _FILEINFO_);
2633  }
2634  }
2635 
2636  // or detached label
2637  else {
2638  m_label->write(m_labelFileName->expanded());
2639  }
2640  }
2641 }
Isis::ValidMaximum
const double ValidMaximum
The maximum valid double value for Isis pixels.
Definition: SpecialPixel.h:122
Isis::SizeOf
int SizeOf(Isis::PixelType pixelType)
Returns the number of bytes of the specified PixelType.
Definition: PixelType.h:46
Isis::FileName::originalPath
QString originalPath() const
Returns the path of the original file name.
Definition: FileName.cpp:84
Isis::OriginalLabel::toBlob
Isis::Blob toBlob()
Serialize the OriginalLabel data to a Blob.
Definition: OriginalLabel.cpp:82
Isis::Cube::Format
Format
These are the possible storage formats of ISIS cubes.
Definition: Cube.h:178
Isis::PvlObject::endGroup
PvlGroupIterator endGroup()
Returns the ending group index.
Definition: PvlObject.h:109
Isis::OriginalXmlLabel::toBlob
Blob toBlob() const
Serialize the OriginalXmlLabel to a Blob.
Definition: OriginalXmlLabel.cpp:78
Isis::Statistics
This class is used to accumulate statistics on double arrays.
Definition: Statistics.h:94
Isis::PvlObject::findGroup
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition: PvlObject.h:129
Isis::PvlObject::group
PvlGroup & group(const int index)
Return the group at the specified index.
Definition: PvlObject.cpp:452
Isis::DetachedLabel
@ DetachedLabel
The input label is in a separate data file from the image.
Definition: CubeAttribute.h:33
Isis::Statistics::AddData
void AddData(const double *data, const unsigned int count)
Add an array of doubles to the accumulators and counters.
Definition: Statistics.cpp:141
Isis::LineManager
Buffer manager, for moving through a cube in lines.
Definition: LineManager.h:39
Isis::PvlContainer::clear
void clear()
Clears PvlKeywords.
Definition: PvlContainer.h:91
Isis::PvlObject
Contains Pvl Groups and Pvl Objects.
Definition: PvlObject.h:61
Isis::Progress::CheckStatus
void CheckStatus()
Checks and updates the status.
Definition: Progress.cpp:105
Isis::PvlKeyword
A single keyword-value pair.
Definition: PvlKeyword.h:82
QList< int >
Isis::BufferManager::next
bool next()
Moves the shape buffer to the next position.
Definition: BufferManager.h:106
Isis::TProjection::UniversalLatitude
virtual double UniversalLatitude()
This returns a universal latitude (planetocentric).
Definition: TProjection.cpp:908
Isis::Blob::Type
QString Type() const
Accessor method that returns a string containing the Blob type.
Definition: Blob.cpp:124
Isis::Table::Label
PvlObject & Label()
The Table's label.
Definition: Table.cpp:260
Isis::Camera::SetImage
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:154
Isis::FileName::name
QString name() const
Returns the name of the file excluding the path and the attributes in the file name.
Definition: FileName.cpp:162
Isis::FileName
File name manipulation and expansion.
Definition: FileName.h:100
Isis::Progress::SetMaximumSteps
void SetMaximumSteps(const int steps)
This sets the maximum number of steps in the process.
Definition: Progress.cpp:85
Isis::Buffer::DoubleBuffer
double * DoubleBuffer() const
Returns the value of the shape buffer.
Definition: Buffer.h:138
Isis::ImagePolygon::toBlob
Blob toBlob() const
Serialize the ImagePolygon to a Blob.
Definition: ImagePolygon.cpp:1347
Isis::PvlObject::groups
int groups() const
Returns the number of groups contained.
Definition: PvlObject.h:75
Isis::FileName::fileExists
bool fileExists() const
Returns true if the file exists; false otherwise.
Definition: FileName.cpp:449
Isis::Cube::setLabelSize
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:1291
Isis::PvlObject::hasGroup
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
Isis::Pvl
Container for cube-like labels.
Definition: Pvl.h:119
Isis::PvlObject::objects
int objects() const
Returns the number of objects.
Definition: PvlObject.h:219
Isis::CubeAttributeOutput
Manipulate and parse attributes of output cube filenames.
Definition: CubeAttribute.h:473
Isis::PvlObject::addObject
void addObject(const PvlObject &object)
Add a PvlObject.
Definition: PvlObject.h:307
Isis::ImagePolygon
Create cube polygons, read/write polygons to blobs.
Definition: ImagePolygon.h:153
Isis::CubeStretch
Stores stretch information for a cube.
Definition: CubeStretch.h:27
Isis::Camera
Definition: Camera.h:236
Isis::PvlObject::object
PvlObject & object(const int index)
Return the object at the specified index.
Definition: PvlObject.cpp:489
Isis::toString
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition: IString.cpp:211
Isis::Blob::Name
QString Name() const
Accessor method that returns a string containing the Blob name.
Definition: Blob.cpp:133
Isis::BufferManager::begin
bool begin()
Moves the shape buffer to the first position.
Definition: BufferManager.h:96
Isis::BufferManager
Manages a Buffer over a cube.
Definition: BufferManager.h:52
Isis::ByteOrder
ByteOrder
Tests the current architecture for byte order.
Definition: Endian.h:42
Isis::Buffer
Buffer for reading and writing cube data.
Definition: Buffer.h:53
Isis::Blob::Write
void Write(const QString &file)
Write the blob data out to a file.
Definition: Blob.cpp:417
Isis::BufferManager::end
bool end() const
Returns true if the shape buffer has accessed the end of the cube.
Definition: BufferManager.h:115
Isis::FileName::baseName
QString baseName() const
Returns the name of the file without the path and without extensions.
Definition: FileName.cpp:145
Isis::AttachedLabel
@ AttachedLabel
The input label is embedded in the image file.
Definition: CubeAttribute.h:32
Isis::Blob::Read
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
Isis::FileName::expanded
QString expanded() const
Returns a QString of the full file name including the file path, excluding the attributes.
Definition: FileName.cpp:196
Isis::Buffer::Copy
void Copy(const Buffer &in, bool includeRawBuf=true)
Allows copying of the buffer contents to another Buffer.
Definition: Buffer.cpp:255
Isis::PvlGroup
Contains multiple PvlContainers.
Definition: PvlGroup.h:41
Isis::Sensor::UniversalLongitude
virtual double UniversalLongitude() const
Returns the positive east, 0-360 domain longitude, in degrees, at the surface intersection point in t...
Definition: Sensor.cpp:233
Isis::FileName::addExtension
FileName addExtension(const QString &extension) const
Adds a new extension to the file name.
Definition: FileName.cpp:225
Isis::Cube::setDimensions
void setDimensions(int ns, int nl, int nb)
Used prior to the Create method to specify the size of the cube.
Definition: Cube.cpp:1217
Isis::Cube::create
void create(const QString &cfile)
This method will create an isis cube for writing.
Definition: Cube.cpp:414
Isis::IsBigEndian
bool IsBigEndian()
Definition: Endian.h:105
Isis::PvlContainer::isNamed
bool isNamed(const QString &match) const
Returns whether the given string is equal to the container name or not.
Definition: PvlContainer.h:72
Isis::toInt
int toInt(const QString &string)
Global function to convert from a string to an integer.
Definition: IString.cpp:93
Isis::Histogram::AddData
virtual void AddData(const double *data, const unsigned int count)
Add an array of doubles to the histogram counters.
Definition: Histogram.cpp:232
Isis::TProjection
Base class for Map TProjections.
Definition: TProjection.h:166
Isis::Histogram::SetValidRange
void SetValidRange(const double minimum=Isis::ValidMinimum, const double maximum=Isis::ValidMaximum)
Changes the range of the bins.
Definition: Histogram.cpp:192
Isis::Progress::SetText
void SetText(const QString &text)
Changes the value of the text string reported just before 0% processed.
Definition: Progress.cpp:61
Isis::Table::toBlob
Blob toBlob() const
Serialze the Table to a Blob that can be written to a file.
Definition: Table.cpp:414
Isis::OriginalXmlLabel
Read and store original Xml labels.
Definition: OriginalXmlLabel.h:32
Isis::PvlObject::hasKeyword
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 ...
Definition: PvlObject.cpp:236
Isis::CubeCachingAlgorithm
This is the parent of the caching algorithms.
Definition: CubeCachingAlgorithm.h:31
Isis::CubeAttributeOutput::pixelType
PixelType pixelType() const
Return the pixel type as an Isis::PixelType.
Definition: CubeAttribute.cpp:360
Isis::Table
Class for storing Table blobs information.
Definition: Table.h:61
Isis::BigInt
long long int BigInt
Big int.
Definition: Constants.h:49
Isis::PvlObject::findObject
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
Isis::CubeAttributeOutput::propagateMinimumMaximum
bool propagateMinimumMaximum() const
Return true if the min/max are to be propagated from an input cube.
Definition: CubeAttribute.cpp:177
Isis::ImageHistogram
Container of a cube histogram.
Definition: ImageHistogram.h:40
Isis::Cube
IO Handler for Isis Cubes.
Definition: Cube.h:167
Isis::Cube::setExternalDnData
void setExternalDnData(FileName cubeFileWithDnData)
Used to set external dn data to cube.
Definition: Cube.cpp:1234
Isis::PvlContainer::name
QString name() const
Returns the container name.
Definition: PvlContainer.h:63
Isis::IException
Isis exception class.
Definition: IException.h:91
Isis::Projection::SetWorld
virtual bool SetWorld(const double x, const double y)
This method is used to set a world coordinate.
Definition: Projection.cpp:497
Isis::CubeTileHandler
IO Handler for Isis Cubes using the tile format.
Definition: CubeTileHandler.h:35
Isis::FileName::toString
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
Isis::Progress
Program progress reporter.
Definition: Progress.h:42
Isis::Spice
Obtain SPICE information for a spacecraft.
Definition: Spice.h:283
Isis::PvlObject::addGroup
void addGroup(const Isis::PvlGroup &group)
Add a group to the object.
Definition: PvlObject.h:186
Isis::Cube::setByteOrder
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:1202
Isis::FileName::removeExtension
FileName removeExtension() const
Removes all extensions in the file name.
Definition: FileName.cpp:246
Isis::PixelType
PixelType
Enumerations for Isis Pixel Types.
Definition: PixelType.h:27
Isis::LineManager::SetLine
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...
Definition: LineManager.cpp:44
Isis::CubeStretch::toBlob
Isis::Blob toBlob() const
Serialize the CubeStretch to a Blob.
Definition: CubeStretch.cpp:84
Isis::ValidMinimum
const double ValidMinimum
The minimum valid double value for Isis pixels.
Definition: SpecialPixel.h:87
std
Namespace for the standard library.
Isis::OriginalLabel
Read and store original labels.
Definition: OriginalLabel.h:35
Isis::Cube::pixelType
PixelType pixelType() const
Definition: Cube.cpp:1758
Isis::Histogram
Container of a cube histogram.
Definition: Histogram.h:74
Isis::CubeAttributeOutput::byteOrder
ByteOrder byteOrder() const
Return the byte order as an Isis::ByteOrder.
Definition: CubeAttribute.cpp:455
Isis::PvlObject::deleteObject
void deleteObject(const QString &name)
Remove an object from the current PvlObject.
Definition: PvlObject.cpp:366
QPair
This is free and unencumbered software released into the public domain.
Definition: CubeIoHandler.h:23
Isis::PixelTypeName
QString PixelTypeName(Isis::PixelType pixelType)
Returns string name of PixelType enumeration entered as input parameter.
Definition: PixelType.h:66
Isis::History::toBlob
Blob toBlob(const QString &name="IsisCube")
Converts a history object into a new blob object.
Definition: History.cpp:75
Isis::PvlObject::beginGroup
PvlGroupIterator beginGroup()
Returns the beginning group index.
Definition: PvlObject.h:91
Isis::Cube::label
Pvl * label() const
Returns a pointer to the IsisLabel object associated with the cube.
Definition: Cube.cpp:1701
Isis::Cube::write
void write(Blob &blob, bool overwrite=true)
This method will write a blob of data (e.g.
Definition: Cube.cpp:971
Isis::TProjection::UniversalLongitude
virtual double UniversalLongitude()
This returns a universal longitude (positive east in 0 to 360 domain).
Definition: TProjection.cpp:922
Isis::PixelTypeEnumeration
Isis::PixelType PixelTypeEnumeration(const QString &type)
Returns PixelType enumeration given a string.
Definition: PixelType.h:89
Isis::CubeAttributeOutput::maximum
double maximum() const
Return the output cube attribute maximum.
Definition: CubeAttribute.cpp:309
Isis::PvlKeyword::unit
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...
Definition: PvlKeyword.cpp:357
Isis::Buffer::size
int size() const
Returns the total number of pixels in the shape buffer.
Definition: Buffer.h:97
Isis::CubeAttributeOutput::minimum
double minimum() const
Return the output cube attribute minimum.
Definition: CubeAttribute.cpp:294
Isis::Cube::setFormat
void setFormat(Format format)
Used prior to the Create method, this will specify the format of the cube, either band,...
Definition: Cube.cpp:1266
Isis::PvlContainer::keywords
int keywords() const
Returns the number of keywords contained in the PvlContainer.
Definition: PvlContainer.h:86
Isis::Cube::setPixelType
void setPixelType(PixelType pixelType)
Used prior to the Create method, this will specify the output pixel type.
Definition: Cube.cpp:1304
Isis::PvlObject::findKeyword
PvlKeyword & findKeyword(const QString &kname, FindOptions opts)
Finds a keyword in the current PvlObject, or deeper inside other PvlObjects and Pvlgroups within this...
Definition: PvlObject.cpp:177
Isis::CubeBsqHandler
IO Handler for Isis Cubes using the BSQ format.
Definition: CubeBsqHandler.h:41
Isis::History
Definition: History.h:38
Isis::Cube::setBaseMultiplier
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:1151
Isis::FileName::original
QString original() const
Returns the full file name including the file path.
Definition: FileName.cpp:212
Isis::PvlObject::deleteGroup
void deleteGroup(const QString &name)
Remove a group from the current PvlObject.
Definition: PvlObject.cpp:408
Isis::Projection
Base class for Map Projections.
Definition: Projection.h:155
Isis::FileName::setExtension
FileName setExtension(const QString &extension) const
Sets all current file extensions to a new extension in the file name.
Definition: FileName.cpp:265
Isis::Blob
Definition: Blob.h:51
Isis::CubeAttributeOutput::fileFormat
Cube::Format fileFormat() const
Return the file format an Cube::Format.
Definition: CubeAttribute.cpp:267
Isis::Cube::setMinMax
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:1168
Isis::CubeAttributeOutput::propagatePixelType
bool propagatePixelType() const
Return true if the pixel type is to be propagated from an input cube.
Definition: CubeAttribute.cpp:165
Isis::ExternalLabel
@ ExternalLabel
The label is pointing to an external DN file - the label is also external to the data.
Definition: CubeAttribute.h:40
Isis::FileName::path
QString path() const
Returns the path of the file name.
Definition: FileName.cpp:103
Isis
This is free and unencumbered software released into the public domain.
Definition: Apollo.h:16
Isis::Cube::setLabelsAttached
void setLabelsAttached(bool attached)
Use prior to calling create, this sets whether or not to use separate label and data files.
Definition: Cube.cpp:1278
Isis::Sensor::UniversalLatitude
virtual double UniversalLatitude() const
Returns the planetocentric latitude, in degrees, at the surface intersection point in the body fixed ...
Definition: Sensor.cpp:210

U.S. Department of the Interior | U.S. Geological Survey
ISIS | Privacy & Disclaimers | Astrogeology Research Program
To contact us, please post comments and questions on the USGS Astrogeology Discussion Board
To report a bug, or suggest a feature go to: ISIS Github
File Modified: 03/21/2022 06:55:48