irplib_detmon_body.h
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #define TYPE_ADD(a) CONCAT2X(a, CPL_TYPE)
00029
00030 static cpl_error_code
00031 TYPE_ADD(irplib_ksigma_clip)(const CPL_TYPE * pi,
00032 int llx,
00033 int lly,
00034 int urx,
00035 int ury,
00036 int nx,
00037 double var_sum,
00038 int npixs,
00039 double kappa,
00040 int nclip,
00041 double tolerance,
00042 double * mean,
00043 double * stdev)
00044 {
00045 int pos0 = (llx - 1) + (lly - 1) * nx;
00046 double nb = (double) npixs;
00047
00048 double lo_cut = *mean - kappa * (*stdev);
00049 double hi_cut = *mean + kappa * (*stdev);
00050
00051 double lo_cut_p = lo_cut;
00052 double hi_cut_p = hi_cut;
00053
00054 double c_var_sum;
00055 double c_mean = 0;
00056 double c_stdev = 0;
00057
00058 int iclip;
00059
00060 for (iclip = 0; iclip < nclip; iclip++) {
00061 int pos = pos0;
00062 int i, j;
00063
00064 c_var_sum = var_sum;
00065 c_mean = *mean;
00066 c_stdev = *stdev;
00067
00068 for (j = lly - 1; j < ury; j++, pos += (nx - urx + llx - 1)) {
00069 for (i = llx - 1; i < urx; i++, pos++) {
00070 if (pi[pos] > hi_cut || pi[pos] < lo_cut) {
00071 const double delta = (double)pi[pos] - c_mean;
00072
00073 c_var_sum -= nb * delta * delta / (nb - 1.0);
00074 c_mean -= delta / (nb - 1.0);
00075 nb = nb - 1.0;
00076 }
00077 }
00078 }
00079
00080 if (nb == 1.0) {
00081 cpl_msg_error(cpl_func, "Only 1 good pixel remaining.\n"
00082 "Cannot compute stdev at iteration %d", iclip);
00083 cpl_error_set(cpl_func, CPL_ERROR_DIVISION_BY_ZERO);
00084 } else {
00085 c_stdev = sqrt(c_var_sum / (nb - 1.0));
00086 }
00087
00088 lo_cut = c_mean - kappa * c_stdev;
00089 hi_cut = c_mean + kappa * c_stdev;
00090
00091 if(fabs(lo_cut - lo_cut_p) < tolerance &&
00092 fabs(hi_cut - hi_cut_p) < tolerance) {
00093 break;
00094 } else {
00095 lo_cut_p = lo_cut;
00096 hi_cut_p = hi_cut;
00097 }
00098 }
00099
00100 *mean = c_mean;
00101 *stdev = c_stdev;
00102
00103 return cpl_error_get_code();
00104 }