USGS

Isis 3.0 Object Programmers' Reference

Home

Reduce.cpp
1 #include "Reduce.h"
2 #include "IString.h"
3 #include "SpecialPixel.h"
4 #include "SubArea.h"
5 
6 using namespace std;
7 
8 namespace Isis {
26  Reduce::Reduce(Isis::Cube *pInCube, const double sampleScale, const double lineScale)
27  {
28  // Input Cube
29  mInCube = pInCube;
30 
31  mdLine = 1;
32  miBandIndex = 1;
33  // Set input image area to defaults
34  miStartSample = 1;
35  miEndSample = mInCube->sampleCount();
36  miStartLine = 1;
37  miEndLine = mInCube->lineCount();
38 
39  miInputSamples= mInCube->sampleCount();
40  miInputLines = mInCube->lineCount();
41  miInputBands = mInCube->bandCount();
42 
43  // Save off the sample and mdLine magnification
44  mdSampleScale = sampleScale;
45  mdLineScale = lineScale;
46 
47  // Calculate output size based on the sample and line scales
48  miOutputSamples = (int)((double)miInputSamples / mdSampleScale + 0.5);
49  miOutputLines = (int)((double)miInputLines / mdLineScale + 0.5);
50 
51  // Initialize the input portal
52  m_iPortal = new Isis::Portal(miInputSamples, 1, mInCube->pixelType());
53  }
54 
60  Reduce::~Reduce(){
61  delete(m_iPortal);
62  }
63 
81  void Reduce::setInputBoundary(int startSample, int endSample, int startLine, int endLine){
82  miStartSample = startSample;
83  miEndSample = endSample;
84  miInputSamples = endSample - startSample + 1;
85 
86  miStartLine = startLine;
87  miEndLine = endLine;
88  miInputLines = endLine - startLine + 1;
89  mdLine = miStartLine;
90 
91  // Calculate output size based on the sample and line scales
92  miOutputSamples = (int)((double)miInputSamples / mdSampleScale + 0.5);
93  miOutputLines = (int)((double)miInputLines / mdLineScale + 0.5);
94  }
95 
106  Isis::PvlGroup Reduce::UpdateOutputLabel(Isis::Cube *pOutCube)
107  {
108  // Construct a label with the results
109  // This is the Results group that will go into the application
110  // log file. This group must be created by the calling application.
111  // Information will be added to it if the Mapping or Instrument
112  // groups are deleted from the output image label
113  PvlGroup resultsGrp("Results");
114  resultsGrp += PvlKeyword("InputLines", toString(miInputLines));
115  resultsGrp += PvlKeyword("InputSamples", toString(miInputSamples));
116  resultsGrp += PvlKeyword("StartingLine", toString(miStartLine));
117  resultsGrp += PvlKeyword("StartingSample", toString(miStartSample));
118  resultsGrp += PvlKeyword("EndingLine", toString(miEndLine));
119  resultsGrp += PvlKeyword("EndingSample", toString(miEndSample));
120  resultsGrp += PvlKeyword("LineIncrement", toString(mdLineScale));
121  resultsGrp += PvlKeyword("SampleIncrement", toString(mdSampleScale));
122  resultsGrp += PvlKeyword("OutputLines", toString(miOutputLines));
123  resultsGrp += PvlKeyword("OutputSamples", toString(miOutputSamples));
124 
125  Isis::SubArea subArea;
126  subArea.SetSubArea(mInCube->lineCount(), mInCube->sampleCount(), miStartLine, miStartSample,
127  miEndLine, miEndSample, mdLineScale, mdSampleScale);
128  subArea.UpdateLabel(mInCube, pOutCube, resultsGrp);
129 
130  return resultsGrp;
131  }
132 
139  void Nearest::operator()(Isis::Buffer & out) const
140  {
141  int readLine = (int)(mdLine + 0.5);
142 
143  m_iPortal->SetPosition(miStartSample, readLine, miBandIndex);
144  mInCube->read(*m_iPortal);
145 
146  // Scale down buffer
147  for(int os = 0; os < miOutputSamples; os++) {
148  out[os] = (*m_iPortal)[(int)((double) os * mdSampleScale)];
149  }
150 
151  if(out.Line() == miOutputLines) {
152  miBandIndex++;
153  mdLine = 1;
154  }
155  else {
156  mdLine += mdLineScale;
157  }
158  }
159 
166  void Average::operator() (Isis::Buffer & out) const
167  {
168  double rline = (double)out.Line() * mdLineScale;
169 
170  if(out.Line() == 1 && out.Band() == 1) {
171  mdIncTab = new double[miOutputSamples];
172  mdSum = new double[miOutputSamples];
173  mdNpts = new double[miOutputSamples];
174  mdSum2 = new double[miOutputSamples];
175  mdNpts2 = new double[miOutputSamples];
176 
177  // Fill mdIncTab and Initialize buffers for first band
178  for(int osamp = 0; osamp < miOutputSamples; osamp++) {
179  mdIncTab[osamp] = ((double)osamp + 1.) * mdSampleScale;
180  mdSum[osamp] = 0.0;
181  mdNpts[osamp] = 0.0;
182  mdSum2[osamp] = 0.0;
183  mdNpts2[osamp] = 0.0;
184  }
185  mdIncTab[miOutputSamples-1] = miInputSamples;
186  }
187 
188  while(mdLine <= rline) {
189  if((int)mdLine <= miInputLines) {
190  m_iPortal->SetPosition(miStartSample, mdLine, miBandIndex);
191  mInCube->read(*m_iPortal);
192  }
193  int isamp = 1;
194  for(int osamp = 0; osamp < out.size(); osamp++) {
195  while((double)isamp <= mdIncTab[osamp]) {
196  // If Pixel is valid add it to mdSum
197  if(IsValidPixel((*m_iPortal)[isamp-1])) {
198  mdSum[osamp] += (*m_iPortal)[isamp-1];
199  mdNpts[osamp] += 1.0;
200  }
201  isamp++;
202  }
203 
204  double sdel = (double) isamp - mdIncTab[osamp];
205  if(isamp > miInputSamples) continue;
206 
207  if(IsValidPixel((*m_iPortal)[isamp-1])) {
208  mdSum[osamp] += (*m_iPortal)[isamp-1] * (1.0 - sdel);
209  mdNpts[osamp] += (1.0 - sdel);
210  if(osamp + 1 < miOutputSamples) {
211  mdSum[osamp+1] += (*m_iPortal)[isamp-1] * sdel;
212  mdNpts[osamp+1] += sdel;
213  }
214  }
215  isamp++;
216  }
217  mdLine++;
218  }
219 
220  if(mdLine <= miInputLines) {
221  m_iPortal->SetPosition(miStartSample, mdLine, miBandIndex);
222  mInCube->read(*m_iPortal);
223  }
224  double ldel = (double)mdLine - rline;
225  double ldel2 = 1.0 - ldel;
226  int isamp = 1;
227  for(int osamp = 0; osamp < miOutputSamples; osamp++) {
228  while(isamp <= mdIncTab[osamp]) {
229  if(IsValidPixel((*m_iPortal)[isamp-1])) {
230  mdSum[osamp] += (*m_iPortal)[isamp-1] * ldel2;
231  mdNpts[osamp] += ldel2;
232  mdSum2[osamp] += (*m_iPortal)[isamp-1] * ldel;
233  mdNpts2[osamp] += ldel;
234  }
235  isamp++;
236  }
237 
238  double sdel = (double) isamp - mdIncTab[osamp];
239  if(isamp > miInputSamples) continue;
240  if(IsValidPixel((*m_iPortal)[isamp-1])) {
241  mdSum[osamp] += (*m_iPortal)[isamp-1] * (1.0 - sdel) * ldel2;
242  mdNpts[osamp] += (1.0 - sdel) * ldel2;
243  if(osamp + 1 < miOutputSamples) {
244  mdSum[osamp+1] += (*m_iPortal)[isamp-1] * sdel * ldel2;
245  mdNpts[osamp+1] += sdel * ldel2;
246  }
247  mdSum2[osamp] += (*m_iPortal)[isamp-1] * (1.0 - sdel) * ldel;
248  mdNpts2[osamp] += (1.0 - sdel) * ldel;
249  if(osamp + 1 < miOutputSamples) {
250  mdSum2[osamp+1] += (*m_iPortal)[isamp-1] * sdel * ldel;
251  mdNpts2[osamp+1] += sdel * ldel;
252  }
253  }
254  isamp++;
255  }
256 
257  if(mdLine < miInputLines) mdLine++;
258 
259  double npix = mdSampleScale * mdLineScale;
260  for(int osamp = 0; osamp < miOutputSamples; osamp++) {
261  if(mdNpts[osamp] > npix * mdValidPer) {
262  out[osamp] = mdSum[osamp] / mdNpts[osamp];
263  }
264  else {
265  if(msReplaceMode == "NEAREST") {
266  out[osamp] = (*m_iPortal)[(int)(mdIncTab[osamp] + 0.5) - 1];
267  }
268  else {
269  out[osamp] = Isis::Null;
270  }
271  }
272  mdSum[osamp] = mdSum2[osamp];
273  mdNpts[osamp] = mdNpts2[osamp];
274  mdSum2[osamp] = 0.0;
275  mdNpts2[osamp] = 0.0;
276  }
277 
278  if(out.Line() == miOutputLines && out.Band() != miInputBands) {
279  miBandIndex++;
280  mdLine = 1;
281  for(int osamp = 0; osamp < miOutputSamples; osamp++) {
282  mdSum[osamp] = 0.0;
283  mdNpts[osamp] = 0.0;
284  mdSum2[osamp] = 0.0;
285  mdNpts2[osamp] = 0.0;
286  }
287  }
288 
289  if(out.Line() == miOutputLines && out.Band() == miInputBands) {
290  delete [] mdIncTab;
291  delete [] mdSum;
292  delete [] mdNpts;
293  delete [] mdSum2;
294  delete [] mdNpts2;
295  }
296  }
297 }