UVES Pipeline Reference Manual  5.4.6
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 
30 static cpl_error_code
31 TYPE_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 }