Loading [MathJax]/jax/output/NativeMML/config.js
Isis 3 Programmer Reference
Reduce.cpp
1
5
6/* SPDX-License-Identifier: CC0-1.0 */
7#include "Reduce.h"
8#include "IString.h"
9#include "SpecialPixel.h"
10#include "SubArea.h"
11
12using namespace std;
13
14namespace 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
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;
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
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,
134 subArea.UpdateLabel(mInCube, pOutCube, resultsGrp);
135
136 return resultsGrp;
137 }
138
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 {
163 }
164 }
165
173 {
174 // Index of the last input line that corresponds to this output line.
175 double rline = (double)out.Line() * mdLineScale;
176
177 if(out.Line() == 1 && out.Band() == 1) {
178 // Index of the last input sample that corresponds to the output sample.
179 mdIncTab = new double[miOutputSamples];
180 mdSum = new double[miOutputSamples];
181 mdNpts = new double[miOutputSamples];
182 mdSum2 = new double[miOutputSamples];
183 mdNpts2 = new double[miOutputSamples];
184
185 // Fill mdIncTab and Initialize buffers for first band
186 for(int osamp = 0; osamp < miOutputSamples; osamp++) {
187 mdIncTab[osamp] = ((double)osamp + 1.) * mdSampleScale;
188 mdSum[osamp] = 0.0;
189 mdNpts[osamp] = 0.0;
190 mdSum2[osamp] = 0.0;
191 mdNpts2[osamp] = 0.0;
192 }
193 mdIncTab[miOutputSamples-1] = miInputSamples;
194 }
195
196 unordered_map<QString, int> specialPixelCounts[miOutputSamples];
197
198 while(mdLine < rline) {
199 if((int)mdLine <= miInputLines) {
201 mInCube->read(*m_iPortal);
202 }
203 int isamp = 1;
204 for(int osamp = 0; osamp < out.size(); osamp++) {
205 while((double)isamp <= mdIncTab[osamp]) {
206 // If Pixel is valid add it to mdSum
207 if(IsValidPixel((*m_iPortal)[isamp-1])) {
208 mdSum[osamp] += (*m_iPortal)[isamp-1];
209 mdNpts[osamp] += 1.0;
210 }
211 if (IsSpecial((*m_iPortal)[isamp-1])) {
212 specialPixelCounts[osamp][PixelToString((*m_iPortal)[isamp-1])]++;
213 }
214 isamp++;
215 }
216
217 double sdel = (double) isamp - mdIncTab[osamp];
218 if(isamp > miInputSamples) continue;
219
220 if(IsValidPixel((*m_iPortal)[isamp-1])) {
221 mdSum[osamp] += (*m_iPortal)[isamp-1] * (1.0 - sdel);
222 mdNpts[osamp] += (1.0 - sdel);
223 if(osamp + 1 < miOutputSamples) {
224 mdSum[osamp+1] += (*m_iPortal)[isamp-1] * sdel;
225 mdNpts[osamp+1] += sdel;
226 }
227 }
228 if (IsSpecial((*m_iPortal)[isamp-1])) {
229 specialPixelCounts[osamp][PixelToString((*m_iPortal)[isamp-1])]++;
230 if(osamp+1 <= miOutputSamples){
231 specialPixelCounts[osamp+1][PixelToString((*m_iPortal)[isamp-1])]++;
232 }
233 }
234 isamp++;
235 }
236 mdLine++;
237 }
238
239 if(mdLine <= miInputLines) {
241 mInCube->read(*m_iPortal);
242 }
243 double ldel = (double)mdLine - rline;
244 double ldel2 = 1.0 - ldel;
245 int isamp = 1;
246 for(int osamp = 0; osamp < miOutputSamples; osamp++) {
247 while(isamp <= mdIncTab[osamp]) {
248 if(IsValidPixel((*m_iPortal)[isamp-1])) {
249 mdSum[osamp] += (*m_iPortal)[isamp-1] * ldel2;
250 mdNpts[osamp] += ldel2;
251 mdSum2[osamp] += (*m_iPortal)[isamp-1] * ldel;
252 mdNpts2[osamp] += ldel;
253 }
254 if (IsSpecial((*m_iPortal)[isamp-1])) {
255 specialPixelCounts[osamp][PixelToString((*m_iPortal)[isamp-1])]++;
256 }
257 isamp++;
258 }
259
260 double sdel = (double) isamp - mdIncTab[osamp];
261 if(isamp > miInputSamples) continue;
262 if(IsValidPixel((*m_iPortal)[isamp-1])) {
263 mdSum[osamp] += (*m_iPortal)[isamp-1] * (1.0 - sdel) * ldel2;
264 mdNpts[osamp] += (1.0 - sdel) * ldel2;
265 if(osamp + 1 < miOutputSamples) {
266 mdSum[osamp+1] += (*m_iPortal)[isamp-1] * sdel * ldel2;
267 mdNpts[osamp+1] += sdel * ldel2;
268 }
269 mdSum2[osamp] += (*m_iPortal)[isamp-1] * (1.0 - sdel) * ldel;
270 mdNpts2[osamp] += (1.0 - sdel) * ldel;
271 if(osamp + 1 < miOutputSamples) {
272 mdSum2[osamp+1] += (*m_iPortal)[isamp-1] * sdel * ldel;
273 mdNpts2[osamp+1] += sdel * ldel;
274 }
275 }
276 if (IsSpecial((*m_iPortal)[isamp-1])) {
277 specialPixelCounts[osamp][PixelToString((*m_iPortal)[isamp-1])]++;
278 if(osamp+1 <= miOutputSamples){
279 specialPixelCounts[osamp+1][PixelToString((*m_iPortal)[isamp-1])]++;
280 }
281 }
282 isamp++;
283 }
284
285 if(mdLine < miInputLines) mdLine++;
286
287 double npix = mdSampleScale * mdLineScale;
288 for(int osamp = 0; osamp < miOutputSamples; osamp++) {
289 if(mdNpts[osamp] > npix * mdValidPer) {
290 out[osamp] = mdSum[osamp] / mdNpts[osamp];
291 }
292 else {
293 if(msReplaceMode == "NEAREST") {
294 out[osamp] = (*m_iPortal)[(int)(mdIncTab[osamp] + 0.5) - 1];
295 }
296 else if (msReplaceMode == "MAJORITY") {
297 // Iterate over the map and compare element counts
298 // Map iterator yields a pair: pair.first == pixel names, pair.second == pixel count.
299 auto mode = std::max_element(specialPixelCounts[osamp].begin(),
300 specialPixelCounts[osamp].end(),
301 [](const pair<QString, int> &a, const pair<QString, int> &b) {return a.second < b.second;});
302 out[osamp] = StringToPixel(mode->first);
303 }
304 else {
305 out[osamp] = Isis::Null;
306 }
307 }
308 mdSum[osamp] = mdSum2[osamp];
309 mdNpts[osamp] = mdNpts2[osamp];
310 mdSum2[osamp] = 0.0;
311 mdNpts2[osamp] = 0.0;
312 }
313
314 // If this is the last line of the band, reset stats and increment band
315 if(out.Line() == miOutputLines && out.Band() != miInputBands) {
316 miBandIndex++;
317 mdLine = 1;
318 for(int osamp = 0; osamp < miOutputSamples; osamp++) {
319 mdSum[osamp] = 0.0;
320 mdNpts[osamp] = 0.0;
321 mdSum2[osamp] = 0.0;
322 mdNpts2[osamp] = 0.0;
323 }
324 }
325
326 if(out.Line() == miOutputLines && out.Band() == miInputBands) {
327 delete [] mdIncTab;
328 delete [] mdSum;
329 delete [] mdNpts;
330 delete [] mdSum2;
331 delete [] mdNpts2;
332 }
333 }
334}
void operator()(Isis::Buffer &out) const
Operator () overload.
Definition Reduce.cpp:172
double mdValidPer
Valid Percentage.
Definition Reduce.h:121
QString msReplaceMode
Replace Mode (scale/total)
Definition Reduce.h:122
Buffer for reading and writing cube data.
Definition Buffer.h:53
int size() const
Returns the total number of pixels in the shape buffer.
Definition Buffer.h:97
int Line(const int index=0) const
Returns the line position associated with a shape buffer index.
Definition Buffer.cpp:145
int Band(const int index=0) const
Returns the band position associated with a shape buffer index.
Definition Buffer.cpp:162
IO Handler for Isis Cubes.
Definition Cube.h:168
void operator()(Isis::Buffer &out) const
Operator () overload.
Definition Reduce.cpp:145
Buffer for containing a two dimensional section of an image.
Definition Portal.h:36
Contains multiple PvlContainers.
Definition PvlGroup.h:41
A single keyword-value pair.
Definition PvlKeyword.h:87
double mdSampleScale
Sample scale.
Definition Reduce.h:64
int miInputSamples
Input Samples.
Definition Reduce.h:73
~Reduce()
Destructor.
Definition Reduce.cpp:66
int miEndSample
Input end sample.
Definition Reduce.h:67
int miStartSample
Input start sample.
Definition Reduce.h:66
int miInputLines
Input Lines.
Definition Reduce.h:74
Reduce(Isis::Cube *pInCube, const double sampleScale, const double lineScale)
Constructor.
Definition Reduce.cpp:32
int miStartLine
Input start line.
Definition Reduce.h:68
int miEndLine
Input end line.
Definition Reduce.h:69
double mdLine
Line index.
Definition Reduce.h:70
double mdLineScale
Line scale.
Definition Reduce.h:65
Isis::PvlGroup UpdateOutputLabel(Isis::Cube *pOutCube)
Create label for the reduced output image.
Definition Reduce.cpp:112
int miBandIndex
Band Index.
Definition Reduce.h:76
int miOutputSamples
Output Samples.
Definition Reduce.h:71
int miOutputLines
Output Lines.
Definition Reduce.h:72
void setInputBoundary(int startSample, int endSample, int startLine, int endLine)
Parameters to input image sub area.
Definition Reduce.cpp:87
int miInputBands
Input Bands.
Definition Reduce.h:75
Isis::Cube * mInCube
Input image.
Definition Reduce.h:63
Isis::Portal * m_iPortal
Input portal.
Definition Reduce.h:77
Apply corrections to a cube label for subarea extraction.
Definition SubArea.h:47
void UpdateLabel(Cube *icube, Cube *ocube, PvlGroup &results)
Modifies a label for a file containing a subarea.
Definition SubArea.cpp:126
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
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
double StringToPixel(const QString &str)
Takes the name of the pixel type as a string and returns a double pixel value.
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition IString.cpp:211
bool IsValidPixel(const double d)
Returns if the input pixel is valid.
const double Null
Value for an Isis Null pixel.
bool IsSpecial(const double d)
Returns if the input pixel is special.
QString PixelToString(double d, double precision=8)
Takes a double pixel value and returns the name of the pixel type as a string.
Namespace for the standard library.