File failed to load: https://isis.astrogeology.usgs.gov/6.0.0/Object/assets/jax/output/NativeMML/config.js
Isis 3 Programmer Reference
QuickFilter.cpp
1 
6 /* SPDX-License-Identifier: CC0-1.0 */
7 #include "QuickFilter.h"
8 #include "IException.h"
9 #include <float.h>
10 
11 using namespace std;
12 namespace Isis {
13 
27  QuickFilter::QuickFilter(const int ns, const int width,
28  const int height) {
29  // Error checks
30  if(ns <= 0) {
31  string msg = "Invalid value for [ns] in QuickFilter constructor";
32  throw IException(IException::Programmer, msg, _FILEINFO_);
33  }
34 
35  if(width < 1) {
36  string m = "[Width] must be must be greater than or equal to one in ";
37  m += "QuickFilter constructor";
38  throw IException(IException::Programmer, m, _FILEINFO_);
39  }
40  else if((width % 2) == 0) {
41  string m = "[Width] must be must be odd in ";
42  m += "QuickFilter constructor";
43  throw IException(IException::Programmer, m, _FILEINFO_);
44  }
45 
46  if(height < 1) {
47  string m = "[Height] must be must be greater than or equal to one in ";
48  m += "QuickFilter constructor";
49  throw IException(IException::Programmer, m, _FILEINFO_);
50  }
51  else if((height % 2) == 0) {
52  string m = "[Height] must be must be odd in ";
53  m += "QuickFilter constructor";
54  throw IException(IException::Programmer, m, _FILEINFO_);
55  }
56 
57  // Create buffers
58  p_sums = new double[ns];
59  p_sumsqrs = new double[ns];
60  p_counts = new int[ns];
61  p_ns = ns;
62 
63  // Set defaults for min/max and valid pixels
64  p_minimum = -DBL_MAX;
65  p_maximum = DBL_MAX;
66  p_minimumPixels = 0;
67 
68  // Set the boxcar size and compute half the size
69  p_width = width;
70  p_halfWidth = width / 2;
71 
72  p_height = height;
73  p_halfHeight = height / 2;
74 
75  Reset();
76  }
77 
79  void QuickFilter::Reset() {
80  // Initialize buffers
81  for(int i = 0; i < p_ns; i++) {
82  p_sums[i] = 0.0;
83  p_sumsqrs[i] = 0.0;
84  p_counts[i] = 0;
85 
86  }
87 
88  // Initialize sums for the last time Average/Variance/Count were called
89  p_lastSum = 0.0;
90  p_lastSumsqr = 0.0;
91  p_lastCount = 0;
92  p_lastIndex = -100;
93  p_linesAdded = 0;
94  }
95 
97  QuickFilter::~QuickFilter() {
98  delete [] p_sums;
99  delete [] p_counts;
100  delete [] p_sumsqrs;
101  }
102 
118  void QuickFilter::SetMinMax(const double minimum, const double maximum) {
119  if(minimum >= maximum) {
120  string m = "Minimum must be less than maximum in [QuickFilter::SetMinMax]";
121  throw IException(IException::Programmer, m, _FILEINFO_);
122  }
123 
124  p_minimum = minimum;
125  p_maximum = maximum;
126  p_lastIndex = -100;
127  }
128 
139  void QuickFilter::SetMinimumPixels(const int pixels) {
140  if(pixels < 0) {
141  string m = "Pixels must be greater than or equal to zero in ";
142  m += "[QuickFilter::SetMinimumPixels]";
143  throw IException(IException::Programmer, m, _FILEINFO_);
144  }
145  p_minimumPixels = pixels;
146  if(p_minimumPixels > p_width * p_height) {
147  p_minimumPixels = p_width * p_height;
148  }
149  }
150 
162  void QuickFilter::AddLine(const double *buf) {
163  // Check for adding too many lines
164  p_linesAdded++;
165  if(p_linesAdded > p_height) {
166  string m = "Number of lines added exceeds boxcar height ... ";
167  m += "use RemoveLine before AddLine";
168  throw IException(IException::Programmer, m, _FILEINFO_);
169  }
170 
171  for(int i = 0; i < p_ns; i++) {
172  if(Isis::IsValidPixel(buf[i])) {
173  if(buf[i] < p_minimum) continue;
174  if(buf[i] > p_maximum) continue;
175  p_sums[i] += buf[i];
176  p_sumsqrs[i] += buf[i] * buf[i];
177  p_counts[i]++;
178  p_lastIndex = -100;
179  }
180  }
181  }
182 
188  void QuickFilter::RemoveLine(const double *buf) {
189  for(int i = 0; i < p_ns; i++) {
190  if(Isis::IsValidPixel(buf[i])) {
191  if(buf[i] < p_minimum) continue;
192  if(buf[i] > p_maximum) continue;
193  p_sums[i] -= buf[i];
194  p_sumsqrs[i] -= buf[i] * buf[i];
195  p_counts[i]--;
196  p_lastIndex = -100;
197  }
198  }
199  p_linesAdded--;
200  }
201 
213  double QuickFilter::Average(const int index) {
214  // Move the boxcar if necessary
215  Compute(index);
216 
217  // Return NULL8 if we have invalid conditions
218  if(p_lastCount < p_minimumPixels) return Isis::NULL8;
219  if(p_lastCount <= 0) return Isis::NULL8;
220 
221  // Return the average
222  return p_lastSum / (double) p_lastCount;
223  }
224 
236  double QuickFilter::Variance(const int index) {
237  // Move the boxcar if necessary
238  Compute(index);
239 
240  // Return NULL8 if we have invalid conditions
241  if(p_lastCount < p_minimumPixels) return Isis::NULL8;
242  if(p_lastCount <= 1) return Isis::NULL8;
243 
244  // Return the variance
245  double temp = p_lastCount * p_lastSumsqr - p_lastSum * p_lastSum;
246  if(temp < 0.0) temp = 0.0; // This shouldn't happen unless roundoff occurs
247  return temp / ((double)(p_lastCount - 1) * (double) p_lastCount);
248  }
249 
260  int QuickFilter::Count(const int index) {
261  // Move the boxcar if necessary
262  Compute(index);
263 
264  // Return the valid count
265  return p_lastCount;
266  }
267 
273  int QuickFilter::Width() const {
274  return p_width;
275  }
276 
283  int QuickFilter::HalfWidth() const {
284  return p_halfWidth;
285  }
286 
292  int QuickFilter::Height() const {
293  return p_height;
294  }
295 
302  int QuickFilter::HalfHeight() const {
303  return p_halfHeight;
304  }
305 
311  int QuickFilter::Samples() const {
312  return p_ns;
313  }
314 
320  double QuickFilter::Low() const {
321  return p_minimum;
322  }
323 
329  double QuickFilter::High() const {
330  return p_maximum;
331  }
332 
340  int QuickFilter::MinimumPixels() const {
341  return p_minimumPixels;
342  }
343 
352  void QuickFilter::Compute(const int index) {
353  // If the index hasn't changed just return
354  if(index == p_lastIndex) return;
355 
356  // Determine start and stop indeces
357  int start = index - p_halfWidth;
358  int stop = index + p_halfWidth;
359 
360  // See if the index has increased by one
361  if(index == p_lastIndex + 1) {
362  // Remove one column
363  start--;
364  if(start < 0) start = -1 * start;
365  p_lastSum -= p_sums[start];
366  p_lastSumsqr -= p_sumsqrs[start];
367  p_lastCount -= p_counts[start];
368 
369  // Add another column
370  if(stop >= p_ns) stop = p_ns - (stop - p_ns + 2);
371  p_lastSum += p_sums[stop];
372  p_lastSumsqr += p_sumsqrs[stop];
373  p_lastCount += p_counts[stop];
374  }
375 
376  // Recompute everything
377  else {
378  p_lastSum = 0.0;
379  p_lastCount = 0;
380  p_lastSumsqr = 0.0;
381  int j;
382  for(int i = start; i <= stop; i++) {
383  j = i;
384  if(i < 0) {
385  j = -1 * i;
386  }
387  else if(i >= p_ns) {
388  j = p_ns - (i - p_ns + 2);
389  }
390 
391  p_lastSum += p_sums[j];
392  p_lastSumsqr += p_sumsqrs[j];
393  p_lastCount += p_counts[j];
394  }
395  }
396 
397  // Save the current index
398  p_lastIndex = index;
399  }
400 } // end namespace isis
Isis::IException
Isis exception class.
Definition: IException.h:91
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
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:10