CR2RE Pipeline Reference Manual 1.6.2
irplib_ksigma_clip_body.h
1/* $Id: irplib_ksigma_clip_body.h,v 1.1 2011-11-02 13:18:28 amodigli Exp $
2 *
3 * This file is part of the irplib package
4 * Copyright (C) 2002,2003 European Southern Observatory
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
19 */
20
21/*
22 * $Author: amodigli $
23 * $Date: 2011-11-02 13:18:28 $
24 * $Revision: 1.1 $
25 * $Name: not supported by cvs2svn $
26 */
27
28#define TYPE_ADD(a) CONCAT2X(a, CPL_TYPE)
29
30static cpl_error_code
31TYPE_ADD(irplib_ksigma_clip)(const CPL_TYPE * pi,
32 int llx,
33 int lly,
34 int urx,
35 int ury,
36 int nx,
37 double var_sum,
38 int npixs,
39 double kappa,
40 int nclip,
41 double tolerance,
42 double * mean,
43 double * stdev)
44{
45 int pos0 = (llx - 1) + (lly - 1) * nx; /* 1st pixel to process */
46 double nb = (double) npixs; /* Non-bad pixels in window */
47
48 double lo_cut = *mean - kappa * (*stdev);
49 double hi_cut = *mean + kappa * (*stdev);
50
51 double lo_cut_p = lo_cut;
52 double hi_cut_p = hi_cut;
53
54 double c_mean = 0; /* Set to zero in case loop body not executed. */
55 double c_stdev = 0; /* Set to zero in case loop body not executed. */
56
57 int iclip;
58
59 for (iclip = 0; iclip < nclip; iclip++) {
60 int pos = pos0;
61 int i, j;
62 double c_var_sum;
63
64 c_var_sum = var_sum;
65 c_mean = *mean;
66 c_stdev = *stdev;
67 nb = npixs;
68
69 for (j = lly - 1; j < ury; j++, pos += (nx - urx + llx - 1)) {
70 for (i = llx - 1; i < urx; i++, pos++) {
71 if (pi[pos] > hi_cut || pi[pos] < lo_cut) {
72 const double delta = (double)pi[pos] - c_mean;
73
74 c_var_sum -= nb * delta * delta / (nb - 1.0);
75 c_mean -= delta / (nb - 1.0);
76 nb = nb - 1.0;
77 }
78 }
79 }
80
81 if (nb == 1.0 || c_var_sum < 0.0) {
82 cpl_msg_error(cpl_func, "Iteration %d: Too many pixels were "
83 "removed. This may cause unexpected behaviour. "
84 "Please set a lower number of iterations "
85 "or increase the value of kappa\n", iclip);
86 cpl_error_set(cpl_func, CPL_ERROR_DIVISION_BY_ZERO);
87 } else {
88 c_stdev = sqrt(c_var_sum / (nb - 1.0));
89 }
90
91 lo_cut = c_mean - kappa * c_stdev;
92 hi_cut = c_mean + kappa * c_stdev;
93
94 if(fabs(lo_cut - lo_cut_p) < tolerance &&
95 fabs(hi_cut - hi_cut_p) < tolerance) {
96 break;
97 } else {
98 lo_cut_p = lo_cut;
99 hi_cut_p = hi_cut;
100 }
101 }
102
103 *mean = c_mean;
104 *stdev = c_stdev;
105
106 return cpl_error_get_code();
107}