Official websites use .gov
A .gov website belongs to an official government organization in the United States.

Secure .gov websites use HTTPS
A lock ( ) or https:// means you’ve safely connected to the .gov website. Share sensitive information only on official, secure websites.

Isis 3 Programmer Reference
CubeAttribute.cpp
1
5
6/* SPDX-License-Identifier: CC0-1.0 */
7#include "CubeAttribute.h"
8
9#include <iostream>
10
11#include <QDebug>
12#include <QRegularExpression>
13
14#include "FileName.h"
15#include "IException.h"
16#include "Preference.h"
17#include "SpecialPixel.h"
18
19
20using namespace std;
21
22namespace Isis {
23 //---------------------------------------------------------------------------
24 // CubeAttributeInput Implementation
25 //---------------------------------------------------------------------------
28
29
30 CubeAttributeInput::CubeAttributeInput(const FileName &fileName) :
31 CubeAttribute<CubeAttributeInput>(testers(), fileName) {
32 }
33
34
37
38
48// void CubeAttributeInput::Set(const FileName &fileName) {
49// Reset();
50//
51// QString str(fileName.attributes());
52//
53// // Get rid of any white space
54// str.ConvertWhiteSpace();
55// str.Compress();
56// str.Remove(" ");
57// str.UpCase();
58//
59// // Look at each comma delimited token
60// QString commaTok;
61// while((commaTok = str.Token(",")).length() > 0) {
62// // Is this token a range of bands
63// if (commaTok.find('-') != string::npos) {
64// QString dashTok;
65// int start = commaTok.Token("-").ToInteger();
66// int end = commaTok.Token("-").ToInteger();
67// int direction;
68// direction = (start <= end) ? 1 : -1;
69// // Save the entire range of bands
70// for (int band = start; band != end; band += direction) {
71// m_bands.push_back(Isis::QString(band));
72// }
73// m_bands.push_back(Isis::QString(end));
74// }
75// // This token is a single band specification
76// else {
77// m_bands.push_back(commaTok);
78// }
79// }
80// }
81
82
83 vector<QString> CubeAttributeInput::bands() const {
84 vector<QString> result;
85
86 QString str = toString().remove(QRegularExpression("^\\+"));
87
88 QStringList strSplit = str.split(",", Qt::SkipEmptyParts);
89 foreach (QString commaTok, strSplit) {
90 // Is this token a range of bands
91 if (commaTok.contains('-')) {
92 QString dashTok;
93 int start = toInt(commaTok.mid(0, commaTok.indexOf("-")));
94 int end = toInt(commaTok.mid(commaTok.indexOf("-") + 1));
95 int direction;
96 direction = (start <= end) ? 1 : -1;
97 // Save the entire range of bands
98 for (int band = start; band != end; band += direction) {
99 result.push_back(Isis::toString(band));
100 }
101 result.push_back(Isis::toString(end));
102 }
103 // This token is a single band specification
104 else {
105 result.push_back(commaTok);
106 }
107 }
108
109 return result;
110 }
111
112
114 return toString(bands());
115 }
116
117
118 void CubeAttributeInput::setBands(const vector<QString> &bands) {
120 }
121
122
123 bool CubeAttributeInput::isBandRange(QString attribute) const {
124 return QRegularExpression("[0-9,\\-]+").match(attribute).hasMatch();
125 }
126
127
128 QString CubeAttributeInput::toString(const vector<QString> &bands) {
129 QString result;
130 for (unsigned int i = 0; i < bands.size(); i++) {
131 if (i > 0)
132 result += ",";
133
134 result += bands[i];
135 }
136
137 return result;
138 }
139
140
141 QList<bool (CubeAttributeInput::*)(QString) const> CubeAttributeInput::testers() {
142 QList<bool (CubeAttributeInput::*)(QString) const> result;
143
144 result.append(&CubeAttributeInput::isBandRange);
145
146 return result;
147 }
148
149
150 //---------------------------------------------------------------------------
151 // CubeAttributeOutput Implementation
152 //---------------------------------------------------------------------------
155
156
158 : CubeAttribute<CubeAttributeOutput>(testers(), fileName) {
159 }
160
161
164
165
167 bool result = false;
168
169 QStringList pixelTypeAtts = attributeList(&CubeAttributeOutput::isPixelType);
170
171 if (pixelTypeAtts.isEmpty() || pixelTypeAtts.last() == "PROPAGATE")
172 result = true;
173
174 return result;
175 }
176
177
179 return attributeList(&CubeAttributeOutput::isRange).isEmpty();
180 }
181
182
184 bool result = false;
185
186 QStringList fileFormatAtts = attributeList(&CubeAttributeOutput::isFileFormat);
187
188 if (fileFormatAtts.isEmpty() || fileFormatAtts.last() == "PROPAGATE")
189 result = true;
190
191 return result;
192 }
193
194
195// void CubeAttributeOutput::Set(const FileName &fileName) {
196// Reset();
197//
198// Isis::QString str(fileName.attributes());
199//
200// // Remove any white space
201// str.ConvertWhiteSpace();
202// str.Compress();
203// str.Remove(" ");
204// str.UpCase();
205// str.TrimHead("+");
206//
207// // Look at each "+" separate attribute
208// Isis::QString tok;
209// while((tok = str.Token("+")).length() > 0) {
210//
211// // If there is a ":" in this token then it is assumed to be a min:max
212// if (tok.find(":") != string::npos) {
213//
214// // Pull out the minimum
215// Isis::QString colonTok = tok;
216// Isis::QString min = colonTok.Token(":");
217// if (min.length() > 0) {
218// m_minimum = min.ToDouble();
219// }
220// else {
221// m_minimum = 0.0;
222// }
223//
224// // Pull out the maximum
225// Isis::QString max = colonTok.Token(":");
226// if (max.length() > 0) {
227// m_maximum = max.ToDouble();
228// }
229// else {
230// m_maximum = 0.0;
231// }
232// m_rangeType = RangeSet;
233// }
234//
235// // Parse any pixel type attributes
236// else if (tok == "8BIT" || tok == "8-BIT" || tok == "UNSIGNEDBYTE") {
237// m_pixelType = Isis::UnsignedByte;
238// m_pixelTypeDef = "SET";
239// }
240// else if (tok == "16BIT" || tok == "16-BIT" || tok == "SIGNEDWORD") {
241// m_pixelType = Isis::SignedWord;
242// m_pixelTypeDef = "SET";
243// }
244// else if (tok == "32BIT" || tok == "32-BIT" || tok == "REAL") {
245// m_pixelType = Isis::Real;
246// m_pixelTypeDef = "SET";
247// }
248// else if (tok == "PROPAGATE") {
249// m_pixelType = Isis::None;
250// m_pixelTypeDef = "PROPAGATE";
251// }
252//
253// // Parse any file formats
254// else if (tok == "TILE") {
255// m_format = Cube::Tile;
256// }
257// else if (tok == "BSQ" || tok == "BANDSEQUENTIAL") {
258// m_format = Cube::Bsq;
259// }
260//
261// // Parse any byte order
262// else if (tok == "LSB") {
263// m_order = Isis::Lsb;
264// }
265// else if (tok == "MSB") {
266// m_order = Isis::Msb;
267// }
268//
269// // Parse any label type
270// else if (tok == "ATTACHED") {
271// m_labelAttachment = Isis::AttachedLabel;
272// }
273// else if (tok == "DETACHED") {
274// m_labelAttachment = Isis::DetachedLabel;
275// }
276// }
277// }
278
279
281 Cube::Format result = Cube::Tile;
282
283 QStringList formatList = attributeList(&CubeAttributeOutput::isFileFormat);
284
285 if (!formatList.isEmpty()) {
286 QString formatString = formatList.last();
287
288 if (formatString == "BSQ" || formatString == "BANDSEQUENTIAL")
289 result = Cube::Bsq;
290 else if(formatString == "GTIFF") {
291 result = Cube::GTiff;
292 }
293 }
294
295 return result;
296 }
297
298
300 return toString(fileFormat());
301 }
302
303
305 if (fmt == Cube::Tile) {
306 setAttribute("Tile", &CubeAttributeOutput::isFileFormat);
307 }
308 else if (fmt == Cube::Bsq) {
309 setAttribute("BandSequential", &CubeAttributeOutput::isFileFormat);
310 }
311 else if (fmt == Cube::GTiff) {
312 setAttribute("GTiff", &CubeAttributeOutput::isFileFormat);
313 }
314 else {
315 QString msg = "Unsupported format [" + toString(fmt) + "]";
316 IException(IException::Programmer, msg, _FILEINFO_);
317 }
318 }
319
320
322 double result = Null;
323
325 QString range = attributeList(&CubeAttributeOutput::isRange).last();
326
327 QStringList rangeList = range.split(":");
328 if (rangeList.count() == 2 && rangeList.first() != "")
329 result = toDouble(rangeList.first());
330 }
331
332 return result;
333 }
334
335
337 double result = Null;
338
340 QString range = attributeList(&CubeAttributeOutput::isRange).last();
341
342 QStringList rangeList = range.split(":");
343 if (rangeList.count() == 2 && rangeList.last() != "")
344 result = toDouble(rangeList.last());
345 }
346
347 return result;
348 }
349
350
352 if (!IsSpecial(min)) {
353 QString newRange = Isis::toString(min) + ":";
354
355 if (!IsSpecial(maximum()))
356 newRange += Isis::toString(maximum());
357
358 setAttribute(newRange, &CubeAttributeOutput::isRange);
359 }
360 else if (!IsSpecial(maximum())) {
361 setAttribute(":" + Isis::toString(maximum()), &CubeAttributeOutput::isRange);
362 }
363 else {
364 setAttribute("", &CubeAttributeOutput::isRange);
365 }
366 }
367
368
370 if (!IsSpecial(max)) {
371 QString newRange = ":" + Isis::toString(max);
372
373 if (!IsSpecial(minimum()))
374 newRange = Isis::toString(minimum()) + newRange;
375
376 setAttribute(newRange, &CubeAttributeOutput::isRange);
377 }
378 else if (!IsSpecial(minimum())) {
379 setAttribute(Isis::toString(minimum()) + ":", &CubeAttributeOutput::isRange);
380 }
381 else {
382 setAttribute("", &CubeAttributeOutput::isRange);
383 }
384 }
385
386
388 PixelType result = None;
389
390 if (!propagatePixelType()) {
391 QString pixelTypeAtt = attributeList(&CubeAttributeOutput::isPixelType).last();
392
393 if (pixelTypeAtt == "8BIT" || pixelTypeAtt == "8-BIT" || pixelTypeAtt == "UNSIGNEDBYTE") {
394 result = UnsignedByte;
395 }
396 else if (pixelTypeAtt == "16BIT" || pixelTypeAtt == "16-BIT" || pixelTypeAtt == "SIGNEDWORD") {
397 result = SignedWord;
398 }
399 else if (pixelTypeAtt == "16UBIT" || pixelTypeAtt == "16-UBIT" || pixelTypeAtt == "UNSIGNEDWORD") {
400 result = UnsignedWord;
401 }
402 else if (pixelTypeAtt == "32BIT" || pixelTypeAtt == "32-BIT" || pixelTypeAtt == "REAL") {
403 result = Real;
404 }
405 else if (pixelTypeAtt == "32UINT" || pixelTypeAtt == "32-UINT" || pixelTypeAtt == "UNSIGNEDINTEGER") {
406 result = UnsignedInteger;
407 }
408 else if (pixelTypeAtt == "32INT" || pixelTypeAtt == "32-INT" || pixelTypeAtt == "SIGNEDINTEGER") {
409 result = SignedInteger;
410 }
411 }
412
413 return result;
414 }
415
416
418 setAttribute(PixelTypeName(type), &CubeAttributeOutput::isPixelType);
419 }
420
421
423 setAttribute(LabelAttachmentName(attachment), &CubeAttributeOutput::isLabelAttachment);
424 }
425
426
427 Cube::LabelAttachment CubeAttributeOutput::labelAttachment() const {
429
430 QStringList labelAttachmentAtts = attributeList(&CubeAttributeOutput::isLabelAttachment);
431 if (!labelAttachmentAtts.isEmpty()) {
432 QString labelAttachmentAtt = labelAttachmentAtts.last();
433
434 if (labelAttachmentAtt == "DETACHED")
435 result = Cube::DetachedLabel;
436 else if (labelAttachmentAtt == "EXTERNAL")
437 result = Cube::ExternalLabel;
438 }
439
440 return result;
441 }
442
443
444 bool CubeAttributeOutput::isByteOrder(QString attribute) const {
445 return QRegularExpression("(M|L)SB").match(attribute).hasMatch();
446 }
447
448
449 bool CubeAttributeOutput::isFileFormat(QString attribute) const {
450 return QRegularExpression("(BANDSEQUENTIAL|BSQ|TILE|GTIFF)").match(attribute).hasMatch();
451 }
452
453
454 bool CubeAttributeOutput::isLabelAttachment(QString attribute) const {
455 return QRegularExpression("(ATTACHED|DETACHED|EXTERNAL)").match(attribute).hasMatch();
456 }
457
458
459 bool CubeAttributeOutput::isPixelType(QString attribute) const {
460 QString expressions = "(8-?BIT|16-?BIT|32-?BIT|UNSIGNEDBYTE|SIGNEDWORD|UNSIGNEDWORD|REAL";
461 expressions += "|32-?UINT|32-?INT|UNSIGNEDINTEGER|SIGNEDINTEGER)";
462 return QRegularExpression(expressions).match(attribute).hasMatch();
463
464 }
465
466
467 bool CubeAttributeOutput::isRange(QString attribute) const {
468 return QRegularExpression("[\\-+E0-9.]*:[\\-+E0-9.]*").match(attribute).hasMatch();
469 }
470
471
473 QString result;
474
475 if (format == Cube::Tile) {
476 result = "Tile";
477 }
478 else if (format == Cube::Bsq) {
479 result = "BandSequential";
480 }
481 else if (format == Cube::GTiff) {
482 result = "GTiff";
483 }
484 else {
485 QString msg = "Format [" + QString::number(format) + "] cannot be translated to string";
486 throw IException(IException::Programmer, msg, _FILEINFO_);
487 }
488
489 return result;
490 }
491
492
494 ByteOrder result = IsLsb()? Lsb : Msb;
495
496 QStringList byteOrderAtts = attributeList(&CubeAttributeOutput::isByteOrder);
497
498 if (!byteOrderAtts.isEmpty()) {
499 QString byteOrderAtt = byteOrderAtts.last();
500 result = (byteOrderAtt == "LSB")? Lsb : Msb;
501 }
502
503 return result;
504 }
505
506
508 return ByteOrderName(byteOrder());
509 }
510
511
512 void CubeAttributeOutput::setByteOrder(ByteOrder order) {
513 setAttribute((order == Msb)? "MSB" : "LSB",
514 &CubeAttributeOutput::isByteOrder);
515 }
516
517
518 QList<bool (CubeAttributeOutput::*)(QString) const> CubeAttributeOutput::testers() {
519 QList<bool (CubeAttributeOutput::*)(QString) const> result;
520
521 result.append(&CubeAttributeOutput::isByteOrder);
522 result.append(&CubeAttributeOutput::isFileFormat);
523 result.append(&CubeAttributeOutput::isLabelAttachment);
524 result.append(&CubeAttributeOutput::isPixelType);
525 result.append(&CubeAttributeOutput::isRange);
526
527 return result;
528 }
529}
QStringList attributeList(bool(CubeAttributeOutput::*tester)(QString) const) const
void setAttributes(const FileName &fileName)
void setAttribute(QString newValue, bool(CubeAttributeOutput::*tester)(QString) const)
CubeAttribute(QList< bool(CubeAttributeInput::*)(QString) const > testers)
Manipulate and parse attributes of input cube filenames.
void setBands(const std::vector< QString > &bands)
Set the band attribute according to the list of bands.
QString bandsString() const
Return a string representation of all the bands.
CubeAttributeInput()
Constructs an empty CubeAttributeInput.
~CubeAttributeInput()
Destroys the object.
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.
void setByteOrder(ByteOrder order)
Set the order according to the parameter order.
bool propagateFileFormat() const
Return true if the file format is to be propagated from an input cube.
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.
QString fileFormatString() const
Return the file format as a string.
void setLabelAttachment(Cube::LabelAttachment attachment)
Set the label attachment type to the parameter value.
QString byteOrderString() const
Return the byte order as a string.
CubeAttributeOutput()
Constructs an empty CubeAttributeOutput.
PixelType pixelType() const
Return the pixel type as an Isis::PixelType.
void setMinimum(double min)
Set the output cube attribute minimum.
void setMaximum(double max)
Set the output cube attribute maximum.
~CubeAttributeOutput()
Destroys the object.
void setPixelType(PixelType type)
Set the pixel type to that given by the parameter.
void setFileFormat(Cube::Format fmt)
Set the format to the fmt parameter.
LabelAttachment
Input cube label type tracker.
Definition Cube.h:245
@ ExternalLabel
The label is pointing to an external DN file - the label is also external to the data.
Definition Cube.h:254
@ AttachedLabel
The input label is embedded in the image file.
Definition Cube.h:246
@ DetachedLabel
The input label is in a separate data file from the image.
Definition Cube.h:247
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
This is free and unencumbered software released into the public domain.
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
QString toString(const LinearAlgebra::Vector &vector, int precision)
A global function to format LinearAlgebra::Vector as a QString with the given precision.
QString LabelAttachmentName(Cube::LabelAttachment labelType)
Return the string representation of the contents of a variable of type LabelAttachment.
Namespace for the standard library.