IIINSTRUMENT Pipeline Reference Manual 1.3.13
detmon.c
1/* $Id: detmon.c,v 1.11 2013-07-19 12:00:24 jtaylor 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: jtaylor $
23 * $Date: 2013-07-19 12:00:24 $
24 * $Revision: 1.11 $
25 * $Name: not supported by cvs2svn $
26 */
27
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31
32/*---------------------------------------------------------------------------
33 Includes
34 ---------------------------------------------------------------------------*/
35
36#include "detmon.h"
37
38#include "irplib_ksigma_clip.h"
39#include "irplib_hist.h"
40#include "irplib_utils.h"
41
42#include <math.h>
43#include <string.h>
44#include <assert.h>
45#include <float.h>
46
47
49/*--------------------------------------------------------------------------*/
50
51/*
52 * @defgroup detmon Detector monitoring functions
53 */
54
55/*--------------------------------------------------------------------------*/
56
57/*---------------------------------------------------------------------------
58 Defines
59 ---------------------------------------------------------------------------*/
60
61/* Computes the square of an euclidean distance bet. 2 points */
62#define pdist(x1,y1,x2,y2) (((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2)))
63
64#define cpl_drand() ((double)rand()/(double)RAND_MAX)
65
66enum pixeltypes
67{
68 HOT = 0,
69 DEAD = 1,
70 NOISY = 2
71};
72
73enum stackingtypes
74{
75 MINMAX = 0,
76 MEAN = 1,
77 MEDIAN = 2,
78 KSIGMA = 3
79};
80
81enum readouts
82{
83 HORIZONTAL = 1,
84 VERTICAL = 2
85};
86
87#define NIR TRUE
88#define OPT FALSE
89
90/*---------------------------------------------------------------------------
91 Private function prototypes
92 ---------------------------------------------------------------------------*/
93
94/* Functions for RON/Bias recipe, detmon_ronbias() */
95
96cpl_error_code
97detmon_rm_bpixs(cpl_image **,
98 const double,
99 int ,
100 int );
101
102/*---------------------------------------------------------------------------*/
103
104/*
105 * @brief Fill input parameters values
106 * @param parlist parameters list
107 * @param recipe_name recipe name
108 * @param pipeline_name pipeline name
109 * @param npars number of parameters
110
111 * @return CPL_ERROR_NONE on success.
112 */
113
114/*---------------------------------------------------------------------------*/
115cpl_error_code
116detmon_fill_parlist(cpl_parameterlist * parlist,
117 const char *recipe_name,
118 const char *pipeline_name,
119 int npars, ...)
120{
121
122 va_list ap;
123
124 char *group_name;
125
126 int pars_counter = 0;
127
128 group_name = cpl_sprintf("%s.%s", pipeline_name, recipe_name);
129 assert(group_name != NULL);
130
131#define insert_par(PARNAME, PARDESC, PARVALUE, PARTYPE) \
132 do { \
133 char * par_name = cpl_sprintf("%s.%s", group_name, PARNAME); \
134 cpl_parameter * p; \
135 assert(par_name != NULL); \
136 p = cpl_parameter_new_value(par_name, PARTYPE, \
137 PARDESC, group_name, PARVALUE); \
138 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, PARNAME); \
139 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); \
140 cpl_parameterlist_append(parlist, p); \
141 cpl_free(par_name); \
142 } while(0);
143
144
145 va_start(ap, npars);
146
147 while(pars_counter < npars) {
148 char *name = va_arg(ap, char *);
149 char *desc = va_arg(ap, char *);
150 char *type = va_arg(ap, char *);
151
152 if(!strcmp(type, "CPL_TYPE_INT")) {
153 int v1 = va_arg(ap, int);
154
155 insert_par(name, desc, v1, CPL_TYPE_INT);
156 } else if(!strcmp(type, "CPL_TYPE_BOOL")) {
157 char *v2 = va_arg(ap, char *);
158
159 if(!strcmp(v2, "CPL_FALSE"))
160 insert_par(name, desc, CPL_FALSE, CPL_TYPE_BOOL);
161 if(!strcmp(v2, "CPL_TRUE"))
162 insert_par(name, desc, CPL_TRUE, CPL_TYPE_BOOL);
163 } else if(!strcmp(type, "CPL_TYPE_STRING")) {
164 char *v2 = va_arg(ap, char *);
165
166 insert_par(name, desc, v2, CPL_TYPE_STRING);
167 } else if(!strcmp(type, "CPL_TYPE_DOUBLE")) {
168 double v3 = va_arg(ap, double);
169 insert_par(name, desc, v3, CPL_TYPE_DOUBLE);
170 }
171
172 pars_counter++;
173 }
174
175 va_end(ap);
176
177 cpl_free(group_name);
178
179#undef insert_par
180 return 0;
181}
182
183/*---------------------------------------------------------------------------*/
184
185/*
186 * @brief Retrieve input int parameter
187 * @param pipeline_name Input image
188 * @param recipe_name Input image
189 * @param parlist Shift to apply on the x-axis
190 * @return CPL_ERROR_NONE on success.
191 */
192
193/*---------------------------------------------------------------------------*/
194int
195detmon_retrieve_par_int(const char *parn,
196 const char *pipeline_name,
197 const char *recipe_name,
198 const cpl_parameterlist * parlist)
199{
200 char *par_name;
201 const cpl_parameter *par;
202 int value;
203
204 par_name = cpl_sprintf("%s.%s.%s", pipeline_name, recipe_name, parn);
205 assert(par_name != NULL);
206 par = cpl_parameterlist_find_const(parlist, par_name);
207 value = cpl_parameter_get_int(par);
208 cpl_free(par_name);
209
210 return value;
211}
212
213/*---------------------------------------------------------------------------*/
214
215/*
216 * @brief Retrieve input double parameter
217 * @param pipeline_name Input image
218 * @param recipe_name Input image
219 * @param parlist Shift to apply on the x-axis
220 * @return CPL_ERROR_NONE on success.
221 */
222
223/*---------------------------------------------------------------------------*/
224double
225detmon_retrieve_par_double(const char *parn,
226 const char *pipeline_name,
227 const char *recipe_name,
228 const cpl_parameterlist * parlist)
229{
230 char *par_name;
231 const cpl_parameter *par;
232 double value;
233
234 par_name = cpl_sprintf("%s.%s.%s", pipeline_name, recipe_name, parn);
235 assert(par_name != NULL);
236 par = cpl_parameterlist_find_const(parlist, par_name);
237 value = cpl_parameter_get_double(par);
238 cpl_free(par_name);
239
240 return value;
241}
242
243
244/*---------------------------------------------------------------------------*/
245
246/*
247 * @brief Retrieve exposure time
248 * @param plist parameter list
249 * @return "EXPTIME" keyword value.
250 */
251
252/*---------------------------------------------------------------------------*/
253
254double
255irplib_pfits_get_exptime(const cpl_propertylist * plist)
256{
257 double exptime;
258
259 exptime = cpl_propertylist_get_double(plist, "EXPTIME");
260
261 return exptime;
262}
263
264/*---------------------------------------------------------------------------*/
265/*
266 * @brief Generate propertylist with product category, type, technique
267 * @param procatg product category
268 * @param protype product type
269 * @param protech product technique
270 * @param proscience switch to identify a science product
271 * @return filled cpl_propertylist (to be deallocated)
272 */
273/*---------------------------------------------------------------------------*/
274cpl_propertylist *
275detmon_fill_prolist(const char * procatg,
276 const char * protype,
277 const char * protech,
278 cpl_boolean proscience)
279{
280 cpl_propertylist * prolist = cpl_propertylist_new();
281
282 cpl_propertylist_append_string(prolist, CPL_DFS_PRO_CATG, procatg);
283 cpl_propertylist_append_bool(prolist, CPL_DFS_PRO_SCIENCE, proscience);
284 if (protype) {
285 cpl_propertylist_append_string(prolist, CPL_DFS_PRO_TYPE, protype);
286 }
287 if (protech) {
288 cpl_propertylist_append_string(prolist, CPL_DFS_PRO_TECH, protech);
289 }
290
291 return prolist;
292}
293
294/*---------------------------------------------------------------------------*/
295
296/*
297 * @brief Remove bad pixels
298 * @param image input/output image
299 * @param kappa kappa for kappa-sigma clip
300 * @param nffts number of fft
301 * @param nsamples number of sampling areas
302 * @return CPL_ERROR_NONE on success.
303 */
304
305/*---------------------------------------------------------------------------*/
306
307
308cpl_error_code
309detmon_rm_bpixs(cpl_image ** image,
310 const double kappa, int nffts, int nsamples)
311{
312 int i, j;
313
314 float *data = cpl_image_get_data_float(*image);
315 int k = 0;
316 for(i = 0; i < nffts; i++) {
317 for(j = 0; j < nsamples; j++) {
318 float neighbours = 0;
319 int nneighs = 0;
320 float average = 0;
321
322 /*
323 * Look for the way to optimize this:
324 * Some of the points added to neighbours coincide
325 * in one iteration and the following
326 */
327 if(i > 0) {
328 neighbours += *(data + (i - 1) * nsamples + j);
329 nneighs++;
330 }
331 if(i < nffts - 1) {
332 neighbours += *(data + (i + 1) * nsamples + j);
333 nneighs++;
334 }
335 if(j > 0) {
336 neighbours += *(data + i * nsamples + (j - 1));
337 nneighs++;
338 }
339 if(j < nsamples - 1) {
340 neighbours += *(data + i * nsamples + (j + 1));
341 nneighs++;
342 }
343 average = neighbours / nneighs;
344 if(average > 0) {
345 if(*(data + i * nsamples + j) < average * (-1 * kappa) ||
346 *(data + i * nsamples + j) > average * (kappa)) {
347 k++;
348 *(data + i * nsamples + j) = average;
349 }
350 }
351 if(average < 0) {
352 if(*(data + i * nsamples + j) > average * (-1 * kappa) ||
353 *(data + i * nsamples + j) < average * (kappa)) {
354 k++;
355 *(data + i * nsamples + j) = average;
356 }
357 }
358
359 }
360 }
361
362
363 return cpl_error_get_code();
364
365}
366
367void
368detmon_print_rec_status(void) {
369 if(cpl_error_get_code() != CPL_ERROR_NONE) {
370 /* cpl_msg_error(cpl_func,"Function status at %d",val); */
371 cpl_msg_error(cpl_func,"%s",(const char*) cpl_error_get_message());
372 cpl_msg_error(cpl_func,"%s",(const char*) cpl_error_get_where());
373 return;
374 }
375 return;
376}
377