Isis 3 Programmer Reference
Reduce.cpp
1 
6 /* SPDX-License-Identifier: CC0-1.0 */
7 #include "Reduce.h"
8 #include "IString.h"
9 #include "SpecialPixel.h"
10 #include "SubArea.h"
11 
12 using namespace std;
13 
14 namespace Isis {
32  Reduce::Reduce(Isis::Cube *pInCube, const double sampleScale, const double lineScale)
33  {
34  // Input Cube
35  mInCube = pInCube;
36 
37  mdLine = 1;
38  miBandIndex = 1;
39  // Set input image area to defaults
40  miStartSample = 1;
41  miEndSample = mInCube->sampleCount();
42  miStartLine = 1;
43  miEndLine = mInCube->lineCount();
44 
45  miInputSamples= mInCube->sampleCount();
46  miInputLines = mInCube->lineCount();
47  miInputBands = mInCube->bandCount();
48 
49  // Save off the sample and mdLine magnification
50  mdSampleScale = sampleScale;
51  mdLineScale = lineScale;
52 
53  // Calculate output size based on the sample and line scales
54  miOutputSamples = (int)((double)miInputSamples / mdSampleScale + 0.5);
55  miOutputLines = (int)((double)miInputLines / mdLineScale + 0.5);
56 
57  // Initialize the input portal
58  m_iPortal = new Isis::Portal(miInputSamples, 1, mInCube->pixelType());
59  }
60 
66  Reduce::~Reduce(){
67  delete(m_iPortal);
68  }
69 
87  void Reduce::setInputBoundary(int startSample, int endSample, int startLine, int endLine){
88  miStartSample = startSample;
89  miEndSample = endSample;
90  miInputSamples = endSample - startSample + 1;
91 
92  miStartLine = startLine;
93  miEndLine = endLine;
94  miInputLines = endLine - startLine + 1;
95  mdLine = miStartLine;
96 
97  // Calculate output size based on the sample and line scales
98  miOutputSamples = (int)((double)miInputSamples / mdSampleScale + 0.5);
99  miOutputLines = (int)((double)miInputLines / mdLineScale + 0.5);
100  }
101 
112  Isis::PvlGroup Reduce::UpdateOutputLabel(Isis::Cube *pOutCube)
113  {
114  // Construct a label with the results
115  // This is the Results group that will go into the application
116  // log file. This group must be created by the calling application.
117  // Information will be added to it if the Mapping or Instrument
118  // groups are deleted from the output image label
119  PvlGroup resultsGrp("Results");
120  resultsGrp += PvlKeyword("InputLines", toString(miInputLines));
121  resultsGrp += PvlKeyword("InputSamples", toString(miInputSamples));
122  resultsGrp += PvlKeyword("StartingLine", toString(miStartLine));
123  resultsGrp += PvlKeyword("StartingSample", toString(miStartSample));
124  resultsGrp += PvlKeyword("EndingLine", toString(miEndLine));
125  resultsGrp += PvlKeyword("EndingSample", toString(miEndSample));
126  resultsGrp += PvlKeyword("LineIncrement", toString(mdLineScale));
127  resultsGrp += PvlKeyword("SampleIncrement", toString(mdSampleScale));
128  resultsGrp += PvlKeyword("OutputLines", toString(miOutputLines));
129  resultsGrp += PvlKeyword("OutputSamples", toString(miOutputSamples));
130 
131  Isis::SubArea subArea;
132  subArea.SetSubArea(mInCube->lineCount(), mInCube->sampleCount(), miStartLine, miStartSample,
133  miEndLine, miEndSample, mdLineScale, mdSampleScale);
134  subArea.UpdateLabel(mInCube, pOutCube, resultsGrp);
135 
136  return resultsGrp;
137  }
138 
145  void Nearest::operator()(Isis::Buffer & out) const
146  {
147  int readLine = (int)(mdLine + 0.5);
148 
149  m_iPortal->SetPosition(miStartSample, readLine, miBandIndex);
150  mInCube->read(*m_iPortal);
151 
152  // Scale down buffer
153  for(int os = 0; os < miOutputSamples; os++) {
154  out[os] = (*m_iPortal)[(int)((double) os * mdSampleScale)];
155  }
156 
157  if(out.Line() == miOutputLines) {
158  miBandIndex++;
159  mdLine = 1;
160  }
161  else {
162  mdLine += mdLineScale;
163  }
164  }
165 
172  void Average::operator() (Isis::Buffer & out) const
173  {
174  double rline = (double)out.Line() * mdLineScale;
175 
176  if(out.Line() == 1 && out.Band() == 1) {
177  mdIncTab = new double[miOutputSamples];
178  mdSum = new double[miOutputSamples];
179  mdNpts = new double[miOutputSamples];
180  mdSum2 = new double[miOutputSamples];
181  mdNpts2 = new double[miOutputSamples];
182 
183  // Fill mdIncTab and Initialize buffers for first band
184  for(int osamp = 0; osamp < miOutputSamples; osamp++) {
185  mdIncTab[osamp] = ((double)osamp + 1.) * mdSampleScale;
186  mdSum[osamp] = 0.0;
187  mdNpts[osamp] = 0.0;
188  mdSum2[osamp] = 0.0;
189  mdNpts2[osamp] = 0.0;
190  }
191  mdIncTab[miOutputSamples-1] = miInputSamples;
192  }
193 
194  while(mdLine <= rline) {
195  if((int)mdLine <= miInputLines) {
196  m_iPortal->SetPosition(miStartSample, mdLine, miBandIndex);
197  mInCube->read(*m_iPortal);
198  }
199  int isamp = 1;
200  for(int osamp = 0; osamp < out.size(); osamp++) {
201  while((double)isamp <= mdIncTab[osamp]) {
202  // If Pixel is valid add it to mdSum
203  if(IsValidPixel((*m_iPortal)[isamp-1])) {
204  mdSum[osamp] += (*m_iPortal)[isamp-1];
205  mdNpts[osamp] += 1.0;
206  }
207  isamp++;
208  }
209 
210  double sdel = (double) isamp - mdIncTab[osamp];
211  if(isamp > miInputSamples) continue;
212 
213  if(IsValidPixel((*m_iPortal)[isamp-1])) {
214  mdSum[osamp] += (*m_iPortal)[isamp-1] * (1.0 - sdel);
215  mdNpts[osamp] += (1.0 - sdel);
216  if(osamp + 1 < miOutputSamples) {
217  mdSum[osamp+1] += (*m_iPortal)[isamp-1] * sdel;
218  mdNpts[osamp+1] += sdel;
219  }
220  }
221  isamp++;
222  }
223  mdLine++;
224  }
225 
226  if(mdLine <= miInputLines) {
227  m_iPortal->SetPosition(miStartSample, mdLine, miBandIndex);
228  mInCube->read(*m_iPortal);
229  }
230  double ldel = (double)mdLine - rline;
231  double ldel2 = 1.0 - ldel;
232  int isamp = 1;
233  for(int osamp = 0; osamp < miOutputSamples; osamp++) {
234  while(isamp <= mdIncTab[osamp]) {
235  if(IsValidPixel((*m_iPortal)[isamp-1])) {
236  mdSum[osamp] += (*m_iPortal)[isamp-1] * ldel2;
237  mdNpts[osamp] += ldel2;
238  mdSum2[osamp] += (*m_iPortal)[isamp-1] * ldel;
239  mdNpts2[osamp] += ldel;
240  }
241  isamp++;
242  }
243 
244  double sdel = (double) isamp - mdIncTab[osamp];
245  if(isamp > miInputSamples) continue;
246  if(IsValidPixel((*m_iPortal)[isamp-1])) {
247  mdSum[osamp] += (*m_iPortal)[isamp-1] * (1.0 - sdel) * ldel2;
248  mdNpts[osamp] += (1.0 - sdel) * ldel2;
249  if(osamp + 1 < miOutputSamples) {
250  mdSum[osamp+1] += (*m_iPortal)[isamp-1] * sdel * ldel2;
251  mdNpts[osamp+1] += sdel * ldel2;
252  }
253  mdSum2[osamp] += (*m_iPortal)[isamp-1] * (1.0 - sdel) * ldel;
254  mdNpts2[osamp] += (1.0 - sdel) * ldel;
255  if(osamp + 1 < miOutputSamples) {
256  mdSum2[osamp+1] += (*m_iPortal)[isamp-1] * sdel * ldel;
257  mdNpts2[osamp+1] += sdel * ldel;
258  }
259  }
260  isamp++;
261  }
262 
263  if(mdLine < miInputLines) mdLine++;
264 
265  double npix = mdSampleScale * mdLineScale;
266  for(int osamp = 0; osamp < miOutputSamples; osamp++) {
267  if(mdNpts[osamp] > npix * mdValidPer) {
268  out[osamp] = mdSum[osamp] / mdNpts[osamp];
269  }
270  else {
271  if(msReplaceMode == "NEAREST") {
272  out[osamp] = (*m_iPortal)[(int)(mdIncTab[osamp] + 0.5) - 1];
273  }
274  else {
275  out[osamp] = Isis::Null;
276  }
277  }
278  mdSum[osamp] = mdSum2[osamp];
279  mdNpts[osamp] = mdNpts2[osamp];
280  mdSum2[osamp] = 0.0;
281  mdNpts2[osamp] = 0.0;
282  }
283 
284  if(out.Line() == miOutputLines && out.Band() != miInputBands) {
285  miBandIndex++;
286  mdLine = 1;
287  for(int osamp = 0; osamp < miOutputSamples; osamp++) {
288  mdSum[osamp] = 0.0;
289  mdNpts[osamp] = 0.0;
290  mdSum2[osamp] = 0.0;
291  mdNpts2[osamp] = 0.0;
292  }
293  }
294 
295  if(out.Line() == miOutputLines && out.Band() == miInputBands) {
296  delete [] mdIncTab;
297  delete [] mdSum;
298  delete [] mdNpts;
299  delete [] mdSum2;
300  delete [] mdNpts2;
301  }
302  }
303 }
Isis::Portal
Buffer for containing a two dimensional section of an image.
Definition: Portal.h:36
Isis::SubArea::SetSubArea
void SetSubArea(const int orignl, const int origns, const int sl, const int ss, const int el, const int es, const double linc, const double sinc)
Defines the subarea.
Definition: SubArea.cpp:60
Isis::PvlKeyword
A single keyword-value pair.
Definition: PvlKeyword.h:82
Isis::toString
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition: IString.cpp:211
Isis::Buffer
Buffer for reading and writing cube data.
Definition: Buffer.h:53
Isis::SubArea::UpdateLabel
void UpdateLabel(Cube *icube, Cube *ocube, PvlGroup &results)
Modifies a label for a file containing a subarea.
Definition: SubArea.cpp:126
Isis::PvlGroup
Contains multiple PvlContainers.
Definition: PvlGroup.h:41
Isis::Cube::sampleCount
int sampleCount() const
Definition: Cube.cpp:1807
Isis::Cube
IO Handler for Isis Cubes.
Definition: Cube.h:167
Isis::Null
const double Null
Value for an Isis Null pixel.
Definition: SpecialPixel.h:95
Isis::Buffer::Band
int Band(const int index=0) const
Returns the band position associated with a shape buffer index.
Definition: Buffer.cpp:162
std
Namespace for the standard library.
Isis::IsValidPixel
bool IsValidPixel(const double d)
Returns if the input pixel is valid.
Definition: SpecialPixel.h:223
Isis::SubArea
Apply corrections to a cube label for subarea extraction.
Definition: SubArea.h:47
Isis::Buffer::size
int size() const
Returns the total number of pixels in the shape buffer.
Definition: Buffer.h:97
Isis::Buffer::Line
int Line(const int index=0) const
Returns the line position associated with a shape buffer index.
Definition: Buffer.cpp:145
Isis
This is free and unencumbered software released into the public domain.
Definition: Apollo.h:16