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(xsh_ksigma_clip)(const CPL_TYPE * pi,
00032 cpl_binary* pm,
00033 int llx,
00034 int lly,
00035 int urx,
00036 int ury,
00037 int nx,
00038 double var_sum,
00039 int npixs,
00040 double kappa,
00041 int nclip,
00042 double tolerance,
00043 double * mean,
00044 double * stdev)
00045 {
00046 int pos0 = (llx - 1) + (lly - 1) * nx;
00047 double nb = (double) npixs;
00048
00049 double lo_cut = *mean - kappa * (*stdev);
00050 double hi_cut = *mean + kappa * (*stdev);
00051
00052 double lo_cut_p = lo_cut;
00053 double hi_cut_p = hi_cut;
00054
00055 double c_var_sum;
00056 double c_mean = 0;
00057 double c_stdev = 0;
00058
00059 int iclip;
00060
00061 for (iclip = 0; iclip < nclip; iclip++) {
00062 int pos = pos0;
00063 int i, j;
00064
00065 c_var_sum = var_sum;
00066 c_mean = *mean;
00067 c_stdev = *stdev;
00068 nb = npixs;
00069
00070 for (j = lly - 1; j < ury; j++, pos += (nx - urx + llx - 1)) {
00071 for (i = llx - 1; i < urx; i++, pos++) {
00072 if ( (pi[pos] > hi_cut || pi[pos] < lo_cut) &&
00073 (pm[pos] == CPL_BINARY_1) ) {
00074 const double delta = (double)pi[pos] - c_mean;
00075
00076 c_var_sum -= nb * delta * delta / (nb - 1.0);
00077 c_mean -= delta / (nb - 1.0);
00078 nb = nb - 1.0;
00079 }
00080 }
00081 }
00082 if (nb == 1.0 || c_var_sum < 0.0) {
00083 cpl_msg_error(cpl_func, "Iteration %d: Too many pixels were "
00084 "removed. This may cause unexpected behaviour. "
00085 "Please set a lower number of iterations "
00086 "or increase the value of kappa\n", iclip);
00087 cpl_msg_error(cpl_func,"iclip=%d nb=%g c_var_sum=%g",
00088 iclip,nb,c_var_sum);
00089 cpl_error_set(cpl_func, CPL_ERROR_DIVISION_BY_ZERO);
00090 } else {
00091 c_stdev = sqrt(c_var_sum / (nb - 1.0));
00092 }
00093
00094 lo_cut = c_mean - kappa * c_stdev;
00095 hi_cut = c_mean + kappa * c_stdev;
00096
00097 if(fabs(lo_cut - lo_cut_p) < tolerance &&
00098 fabs(hi_cut - hi_cut_p) < tolerance) {
00099 break;
00100 } else {
00101 lo_cut_p = lo_cut;
00102 hi_cut_p = hi_cut;
00103 }
00104
00105 }
00106
00107 *mean = c_mean;
00108 *stdev = c_stdev;
00109
00110 return cpl_error_get_code();
00111 }