7 #include "QuickFilter.h"
8 #include "IException.h"
27 QuickFilter::QuickFilter(
const int ns,
const int width,
31 string msg =
"Invalid value for [ns] in QuickFilter constructor";
32 throw IException(IException::Programmer, msg, _FILEINFO_);
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_);
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_);
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_);
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_);
58 p_sums =
new double[ns];
59 p_sumsqrs =
new double[ns];
60 p_counts =
new int[ns];
70 p_halfWidth = width / 2;
73 p_halfHeight = height / 2;
79 void QuickFilter::Reset() {
81 for(
int i = 0; i < p_ns; i++) {
97 QuickFilter::~QuickFilter() {
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_);
139 void QuickFilter::SetMinimumPixels(
const int pixels) {
141 string m =
"Pixels must be greater than or equal to zero in ";
142 m +=
"[QuickFilter::SetMinimumPixels]";
143 throw IException(IException::Programmer, m, _FILEINFO_);
145 p_minimumPixels = pixels;
146 if(p_minimumPixels > p_width * p_height) {
147 p_minimumPixels = p_width * p_height;
162 void QuickFilter::AddLine(
const double *buf) {
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_);
171 for(
int i = 0; i < p_ns; i++) {
173 if(buf[i] < p_minimum)
continue;
174 if(buf[i] > p_maximum)
continue;
176 p_sumsqrs[i] += buf[i] * buf[i];
188 void QuickFilter::RemoveLine(
const double *buf) {
189 for(
int i = 0; i < p_ns; i++) {
191 if(buf[i] < p_minimum)
continue;
192 if(buf[i] > p_maximum)
continue;
194 p_sumsqrs[i] -= buf[i] * buf[i];
213 double QuickFilter::Average(
const int index) {
218 if(p_lastCount < p_minimumPixels)
return Isis::NULL8;
219 if(p_lastCount <= 0)
return Isis::NULL8;
222 return p_lastSum / (double) p_lastCount;
236 double QuickFilter::Variance(
const int index) {
241 if(p_lastCount < p_minimumPixels)
return Isis::NULL8;
242 if(p_lastCount <= 1)
return Isis::NULL8;
245 double temp = p_lastCount * p_lastSumsqr - p_lastSum * p_lastSum;
246 if(temp < 0.0) temp = 0.0;
247 return temp / ((double)(p_lastCount - 1) * (double) p_lastCount);
260 int QuickFilter::Count(
const int index) {
273 int QuickFilter::Width()
const {
283 int QuickFilter::HalfWidth()
const {
292 int QuickFilter::Height()
const {
302 int QuickFilter::HalfHeight()
const {
311 int QuickFilter::Samples()
const {
320 double QuickFilter::Low()
const {
329 double QuickFilter::High()
const {
340 int QuickFilter::MinimumPixels()
const {
341 return p_minimumPixels;
352 void QuickFilter::Compute(
const int index) {
354 if(index == p_lastIndex)
return;
357 int start = index - p_halfWidth;
358 int stop = index + p_halfWidth;
361 if(index == p_lastIndex + 1) {
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];
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];
382 for(
int i = start; i <= stop; i++) {
388 j = p_ns - (i - p_ns + 2);
391 p_lastSum += p_sums[j];
392 p_lastSumsqr += p_sumsqrs[j];
393 p_lastCount += p_counts[j];