File failed to load: https://isis.astrogeology.usgs.gov/6.0.0/Object/assets/jax/output/NativeMML/config.js
Isis 3 Programmer Reference
Stretch.cpp
1 
6 /* SPDX-License-Identifier: CC0-1.0 */
7 #include <iostream>
8 
9 #include <QDebug>
10 
11 #include "Stretch.h"
12 #include "Histogram.h"
13 #include "IString.h"
14 #include "SpecialPixel.h"
15 #include "IException.h"
16 #include "Pvl.h"
17 
18 using namespace std;
19 namespace Isis {
20 
25  Stretch::Stretch() {
26  p_null = Isis::NULL8;
27  p_lis = Isis::LOW_INSTR_SAT8;
28  p_lrs = Isis::LOW_REPR_SAT8;
29  p_his = Isis::HIGH_INSTR_SAT8;
30  p_hrs = Isis::HIGH_REPR_SAT8;
31  p_minimum = p_lrs;
32  p_maximum = p_hrs;
33  p_pairs = 0;
34  }
35 
36 
48  void Stretch::AddPair(const double input, const double output) {
49  if(p_pairs > 0) {
50  if(input <= p_input[p_pairs-1]) {
51  string msg = "Input pairs must be in ascending order";
52  throw IException(IException::Programmer, msg, _FILEINFO_);
53  }
54  }
55 
56  p_input.push_back(input);
57  p_output.push_back(output);
58  p_pairs++;
59  }
60 
69  double Stretch::Map(const double value) const {
70  // Check special pixels first
71  if(!Isis::IsValidPixel(value)) {
72  if(Isis::IsNullPixel(value)) return p_null;
73  if(Isis::IsHisPixel(value)) return p_his;
74  if(Isis::IsHrsPixel(value)) return p_hrs;
75  if(Isis::IsLisPixel(value)) return p_lis;
76  return p_lrs;
77  }
78 
79  // Check to see if we have any pairs
80  if(p_input.size() == 0) return value;
81 
82  // Check to see if outside the minimum and maximum next
83  if(value < p_input[0]) {
84  if(!Isis::IsValidPixel(p_minimum)) {
85  if(Isis::IsNullPixel(p_minimum)) return p_null;
86  if(Isis::IsHisPixel(p_minimum)) return p_his;
87  if(Isis::IsHrsPixel(p_minimum)) return p_hrs;
88  if(Isis::IsLisPixel(p_minimum)) return p_lis;
89  return p_lrs;
90  }
91  return p_minimum;
92  }
93 
94  if(value > p_input[p_pairs-1]) {
95  if(!Isis::IsValidPixel(p_maximum)) {
96  if(Isis::IsNullPixel(p_maximum)) return p_null;
97  if(Isis::IsHisPixel(p_maximum)) return p_his;
98  if(Isis::IsHrsPixel(p_maximum)) return p_hrs;
99  if(Isis::IsLisPixel(p_maximum)) return p_lis;
100  return p_lrs;
101  }
102  return p_maximum;
103  }
104 
105  // Check the end points
106  if(value == p_input[0]) return p_output[0];
107  if(value == p_input[p_pairs-1]) return p_output[p_pairs-1];
108 
109  // Ok find the surrounding pairs with a binary search
110  int start = 0;
111  int end = p_pairs - 1;
112  while(start != end) {
113  int middle = (start + end) / 2;
114 
115  if(middle == start) {
116  end = middle;
117  }
118  else if(value < p_input[middle]) {
119  end = middle;
120  }
121  else {
122  start = middle;
123  }
124  }
125 
126  end = start + 1;
127 
128  // Apply the stretch
129  double slope = (p_output[end] - p_output[start]) / (p_input[end] - p_input[start]);
130  return slope * (value - p_input[end]) + p_output[end];
131  }
132 
145  std::pair<double, double> Stretch::NextPair(QString &pairs) {
146  std::pair<double, double> io;
147  io.first = Null;
148  io.second = Null;
149 
150  pairs = pairs.simplified().trimmed();
151 
152  if (pairs.contains(":")) {
153  QStringList pairList = pairs.split(" ");
154 
155  QString firstPair = pairList.takeFirst();
156 
157  QStringList firstPairValues = firstPair.split(":");
158 
159  if (firstPairValues.count() == 2) {
160  io.first = toDouble(firstPairValues.first());
161  io.second = toDouble(firstPairValues.last());
162 
163  pairs = pairList.join(" ");
164  }
165  }
166 
167  return io;
168  }
169 
181  void Stretch::Parse(const QString &pairs) {
182  // Zero out the stretch arrays
183  p_input.clear();
184  p_output.clear();
185  p_pairs = 0;
186 
187  std::pair<double, double> pear;
188 
189  QString p = pairs.simplified().trimmed();
190  p.replace(QRegExp("[\\s]*:"), ":");
191  p.replace(QRegExp(":[\\s]*"), ":");
192  QStringList pairList = p.split(" ", QString::SkipEmptyParts);
193 
194  try {
195  foreach(QString singlePair, pairList) {
196  pear = Stretch::NextPair(singlePair);
197  Stretch::AddPair(pear.first, pear.second);
198  }
199  }
200  catch(IException &e) {
201  throw IException(e, IException::User, "Invalid stretch pairs [" + pairs + "]", _FILEINFO_);
202  }
203  }
204 
218  void Stretch::Parse(const QString &pairs, const Isis::Histogram *hist) {
219  // Zero out the stretch arrays
220  p_input.clear();
221  p_output.clear();
222  p_pairs = 0;
223 
224  QString p(pairs);
225  std::pair<double, double> pear;
226 
227  // need to save the input dn values in order to
228  // to detect collisions
229  std::vector<double> converted;
230 
231  try {
232  while(p.size() > 0) {
233  pear = Stretch::NextPair(p);
234  pear.first = hist->Percent(pear.first);
235 
236  // test for collision!
237  // if collision occurs then ignore this pair and move on
238  // to next pair
239  bool collision = false;
240  unsigned int k = 0;
241  while(!collision && k < converted.size()) {
242  if(pear.first == converted[k]) {
243  collision = true;
244  }
245  else {
246  k++;
247  }
248  }
249  if(!collision) {
250  Stretch::AddPair(pear.first, pear.second);
251  converted.push_back(pear.first);
252  }
253  }
254  }
255 
256  catch(IException &e) {
257  throw IException(e, IException::User, "Invalid stretch pairs [" +
258  pairs + "]", _FILEINFO_);
259  }
260  }
261 
262 
268  QString Stretch::Text() const {
269 
270  if(p_pairs < 0) return "";
271 
272  QString p("");
273  for(int i = 0; i < p_pairs; i++) {
274  p += toString(p_input[i]) + ":" + toString(p_output[i]) + " ";
275  }
276  return p.trimmed();
277  }
278 
287  double Stretch::Input(int index) const {
288  if(index >= p_pairs || index < 0) {
289  return -1;
290  }
291  return p_input[index];
292  }
293 
302  double Stretch::Output(int index) const {
303  if(index >= p_pairs || index < 0) {
304  return -1;
305  }
306  return p_output[index];
307  }
308 
323  void Stretch::Load(QString &file, QString &grpName) {
324  Pvl pvl(file);
325  Load(pvl, grpName);
326  }
327 
342  void Stretch::Load(Isis::Pvl &pvl, QString &grpName) {
343  PvlGroup grp = pvl.findGroup(grpName, Isis::PvlObject::Traverse);
344  PvlKeyword inputs = grp.findKeyword("Input");
345  PvlKeyword outputs = grp.findKeyword("Output");
346 
347  if(inputs.size() != outputs.size()) {
348  QString msg = "Invalid Pvl file: The number of Input values must equal the number of Output values";
349  throw IException(IException::User, msg, _FILEINFO_);
350  }
351  for(int i = 0; i < inputs.size(); i++) {
352  AddPair(toDouble(inputs[i]), toDouble(outputs[i]));
353  }
354  }
355 
356 
367  void Stretch::Save(QString &file, QString &grpName) {
368  Pvl p;
369  Save(p, grpName);
370  p.write(file);
371  }
372 
373  void Stretch::Save(Isis::Pvl &pvl, QString &grpName) {
374  PvlGroup *grp = new PvlGroup(grpName);
375  PvlKeyword inputs("Input");
376  PvlKeyword outputs("Output");
377  for(int i = 0; i < Pairs(); i++) {
378  inputs.addValue(toString(Input(i)));
379  outputs.addValue(toString(Output(i)));
380  }
381  grp->addKeyword(inputs);
382  grp->addKeyword(outputs);
383  pvl.addGroup(*grp);
384  }
385 
392  void Stretch::CopyPairs(const Stretch &other) {
393  this->p_pairs = other.p_pairs;
394  this->p_input = other.p_input;
395  this->p_output = other.p_output;
396  }
397 } // end namespace isis
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::Histogram::Percent
double Percent(const double percent) const
Computes and returns the value at X percent of the histogram.
Definition: Histogram.cpp:351
Isis::PvlKeyword
A single keyword-value pair.
Definition: PvlKeyword.h:82
Isis::PvlContainer::addKeyword
void addKeyword(const PvlKeyword &keyword, const InsertMode mode=Append)
Add a keyword to the container.
Definition: PvlContainer.cpp:202
Isis::Stretch
Pixel value mapper.
Definition: Stretch.h:58
Isis::IsNullPixel
bool IsNullPixel(const double d)
Returns if the input pixel is null.
Definition: SpecialPixel.h:235
Isis::IsHrsPixel
bool IsHrsPixel(const double d)
Returns if the input pixel is high representation saturation.
Definition: SpecialPixel.h:271
Isis::Pvl
Container for cube-like labels.
Definition: Pvl.h:119
Isis::Pvl::write
void write(const QString &file)
Opens and writes PVL information to a file and handles the end of line sequence.
Definition: Pvl.cpp:130
QStringList
Isis::toString
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition: IString.cpp:211
Isis::PvlObject::Traverse
@ Traverse
Search child objects.
Definition: PvlObject.h:158
Isis::PvlGroup
Contains multiple PvlContainers.
Definition: PvlGroup.h:41
Isis::Stretch::p_pairs
int p_pairs
Number of stretch pairs.
Definition: Stretch.h:62
Isis::Stretch::p_input
std::vector< double > p_input
Array for input side of stretch pairs.
Definition: Stretch.h:60
Isis::IException
Isis exception class.
Definition: IException.h:91
Isis::IsLisPixel
bool IsLisPixel(const double d)
Returns if the input pixel is low instrument saturation.
Definition: SpecialPixel.h:295
Isis::Null
const double Null
Value for an Isis Null pixel.
Definition: SpecialPixel.h:95
Isis::PvlObject::addGroup
void addGroup(const Isis::PvlGroup &group)
Add a group to the object.
Definition: PvlObject.h:186
Isis::IsHisPixel
bool IsHisPixel(const double d)
Returns if the input pixel is high instrument saturation.
Definition: SpecialPixel.h:283
Isis::toDouble
double toDouble(const QString &string)
Global function to convert from a string to a double.
Definition: IString.cpp:149
std
Namespace for the standard library.
Isis::Histogram
Container of a cube histogram.
Definition: Histogram.h:74
Isis::IsValidPixel
bool IsValidPixel(const double d)
Returns if the input pixel is valid.
Definition: SpecialPixel.h:223
Isis::PvlKeyword::size
int size() const
Returns the number of values stored in this keyword.
Definition: PvlKeyword.h:125
Isis::Stretch::p_output
std::vector< double > p_output
Array for output side of stretch pairs.
Definition: Stretch.h:61
Isis::PvlContainer::findKeyword
PvlKeyword & findKeyword(const QString &name)
Find a keyword with a specified name.
Definition: PvlContainer.cpp:62
Isis
This is free and unencumbered software released into the public domain.
Definition: Apollo.h:16

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: 07/13/2023 15:17:20