MOONS Pipeline Reference Manual 0.13.1
moo_remove_crh.c
1/*
2 * This file is part of the MOONS Pipeline
3 * Copyright (C) 2002-2016 European Southern Observatory
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20#ifdef HAVE_CONFIG_H
21#include <config.h>
22#endif
23
24/*-----------------------------------------------------------------------------
25 Includes
26 -----------------------------------------------------------------------------*/
27#include <math.h>
28#include <string.h>
29#include <cpl.h>
30#include <hdrl.h>
31#include "moo_utils.h"
32#include "moo_dfs.h"
33#include "moo_pfits.h"
34#include "moo_qc.h"
35#include "moo_params.h"
36#include "moo_badpix.h"
37#include "moo_single.h"
38#include "moo_det.h"
39#include "moo_detlist.h"
40#include "moo_remove_crh.h"
41/*----------------------------------------------------------------------------*/
46/*----------------------------------------------------------------------------*/
47
50/*-----------------------------------------------------------------------------
51 Function codes
52 -----------------------------------------------------------------------------*/
53
54/*----------------------------------------------------------------------------*/
66/*----------------------------------------------------------------------------*/
67static cpl_image *
68_moo_qual_fromlist(cpl_imagelist *list)
69{
70 cpl_ensure(list, CPL_ERROR_NULL_INPUT, NULL);
71
72 int size = cpl_imagelist_get_size(list);
73 cpl_ensure(size > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
74
75 const cpl_image *qimg = cpl_imagelist_get_const(list, 0);
76
77 if (size > 1) {
78 int k;
79
80 int nx = cpl_image_get_size_x(qimg);
81 int ny = cpl_image_get_size_y(qimg);
82 const int *qdata = cpl_image_get_data_int_const(qimg);
83
84 for (k = 1; k < size; k++) {
85 cpl_image *qimg2 = cpl_imagelist_get(list, k);
86 int *qdata2 = cpl_image_get_data_int(qimg2);
87 for (int i = 0; i < nx * ny; i++) {
88 if (qdata[i] != qdata2[i]) {
89 cpl_msg_error("moo_remove_crh",
90 "QUAL of first frame and %d are not equal",
91 k);
92 }
93 }
94 }
95 }
96 return cpl_image_duplicate(qimg);
97}
98
99static moo_single *
100_moo_remove_CRH_collapse_median(hdrl_imagelist *list,
101 cpl_imagelist *quallist,
103 int num)
104{
105 moo_single *single = NULL;
106 int j;
107 cpl_ensure(list != NULL, CPL_ERROR_ILLEGAL_INPUT, NULL);
108
109 int size = hdrl_imagelist_get_size(list);
110
111 if (size > 0) {
112 hdrl_image *res = NULL;
113 cpl_image *contrib = NULL;
114 hdrl_imagelist_collapse_median(list, &res, &contrib);
115 for (j = 0; j < size; j++) {
116 hdrl_imagelist_unset(list, 0);
117 }
118
119 cpl_image *qual = _moo_qual_fromlist(quallist);
120 single = moo_single_new(type, num);
121 single->qual = qual;
122 single->image = res;
123
124 for (j = 0; j < size; j++) {
125 cpl_imagelist_unset(quallist, 0);
126 }
127
128 cpl_image_delete(contrib);
129 }
130
131 return single;
132}
133
134static moo_single *
135_moo_remove_CRH_collapse_mean(hdrl_imagelist *list,
136 cpl_imagelist *quallist,
138 int num)
139{
140 moo_single *single = NULL;
141 int j;
142 cpl_ensure(list != NULL, CPL_ERROR_ILLEGAL_INPUT, NULL);
143
144 int size = hdrl_imagelist_get_size(list);
145
146 if (size > 0) {
147 hdrl_image *res = NULL;
148 cpl_image *contrib = NULL;
149 hdrl_imagelist_collapse_mean(list, &res, &contrib);
150
151 for (j = 0; j < size; j++) {
152 hdrl_imagelist_unset(list, 0);
153 }
154
155 cpl_image *qual = _moo_qual_fromlist(quallist);
156
157 single = moo_single_new(type, num);
158 single->qual = qual;
159 single->image = res;
160
161 for (j = 0; j < size; j++) {
162 cpl_imagelist_unset(quallist, 0);
163 }
164 cpl_image_delete(contrib);
165 }
166 return single;
167}
168
169/*----------------------------------------------------------------------------*/
188/*----------------------------------------------------------------------------*/
189static moo_single *
190_moo_remove_CRH_collapse_sigclip(hdrl_imagelist *list,
191 cpl_imagelist *quallist,
192 moo_masklist *cosmiclist,
193 double kappa,
194 int niter,
195 int *nbcrh,
197 int num)
198{
199 cpl_ensure(nbcrh != NULL, CPL_ERROR_ILLEGAL_INPUT, NULL);
200 cpl_ensure(list != NULL, CPL_ERROR_ILLEGAL_INPUT, NULL);
201 cpl_ensure(quallist != NULL, CPL_ERROR_ILLEGAL_INPUT, NULL);
202
203 moo_single *single = NULL;
204 int j, k;
205
206 int size = hdrl_imagelist_get_size(list);
207 int nbcosmics = 0;
208 float avg_cosmics = 0.0;
209
210 if (size > 0) {
211 hdrl_image *res = NULL;
212 cpl_image *rejhigh = NULL;
213 cpl_image *contrib = NULL;
214
215 int sizex = hdrl_imagelist_get_size_x(list);
216 int sizey = hdrl_imagelist_get_size_y(list);
217
218 if (cosmiclist != NULL) {
219 for (int i = 0; i < size; i++) {
220 moo_mask *mask = moo_masklist_get(cosmiclist, i);
221 moo_mask_set(mask, type, num, cpl_mask_new(sizex, sizey));
222 }
223 }
224 moo_try_check(hdrl_imagelist_collapse_sigclip(list, kappa, kappa, niter,
225 &res, &contrib, NULL,
226 &rejhigh),
227 " ");
228#if MOO_DEBUG_REMOVE_CRH
229 {
230 const char *extname = moo_detector_get_extname(type, num);
231 char *name = cpl_sprintf("contrib_%s.fits", extname);
232 cpl_image_save(contrib, name, CPL_TYPE_INT, NULL, CPL_IO_CREATE);
233 cpl_free(name);
234
235 name = cpl_sprintf("rejhigh_%s.fits", extname);
236 cpl_image_save(rejhigh, name, CPL_TYPE_DOUBLE, NULL, CPL_IO_CREATE);
237 cpl_free(name);
238 }
239#endif
240 const double *high_data = cpl_image_get_data_double_const(rejhigh);
241
242 cpl_image *qual = _moo_qual_fromlist(quallist);
243 for (j = 0; j < sizex * sizey; j++) {
244 if (cosmiclist != NULL) {
245 for (k = 0; k < size; k++) {
246 const hdrl_image *himage =
247 hdrl_imagelist_get_const(list, k);
248 const cpl_image *image = hdrl_image_get_image_const(himage);
249 const double *img_data =
250 cpl_image_get_data_double_const(image);
251 cpl_image *qimg = cpl_imagelist_get(quallist, k);
252 cpl_mask *mask =
253 moo_masklist_get_mask(cosmiclist, k, type, num);
254 cpl_binary *mdata = cpl_mask_get_data(mask);
255 int *qdata = cpl_image_get_data_int(qimg);
256
257 double val = img_data[j];
258 double high = high_data[j];
259
260 if (val > high) {
261 nbcosmics++;
262 qdata[j] |= MOO_BADPIX_COSMIC_UNREMOVED;
263 mdata[j] = CPL_BINARY_1;
264 }
265 }
266 }
267 }
268 for (j = 0; j < size; j++) {
269 hdrl_imagelist_unset(list, 0);
270 }
271 *nbcrh = nbcosmics;
272 avg_cosmics = (float)nbcosmics / (float)size;
273 cpl_msg_indent_more();
274 if (cosmiclist != NULL) {
275 const char *extname = moo_detector_get_extname(type, num);
276 cpl_msg_info(__func__,
277 "%s: found %d cosmics in total (avg %.1f / frame) ",
278 extname, nbcosmics, avg_cosmics);
279 }
280 cpl_msg_indent_less();
281 single = moo_single_new(type, num);
282 moo_qc_set_ncrh(single->header, nbcosmics);
283 moo_qc_set_ncrh_avg(single->header, avg_cosmics);
284 single->qual = qual;
285 single->image = res;
286#if MOO_DEBUG_REMOVE_CRH
287 for (j = 0; j < size; j++) {
288 {
289 char *name = cpl_sprintf("qual_%s_%d.fits", extname, j);
290 cpl_image_save(cpl_imagelist_get(quallist, j), name,
291 CPL_TYPE_INT, NULL, CPL_IO_CREATE);
292 cpl_free(name);
293 }
294 }
295#endif
296 for (j = 0; j < size; j++) {
297 cpl_imagelist_unset(quallist, 0);
298 }
299
300
301 cpl_image_delete(rejhigh);
302 cpl_image_delete(contrib);
303 }
304moo_try_cleanup:
305 return single;
306}
307
308
309static moo_single *
310_moo_remove_CRH_collapse(hdrl_imagelist *list,
311 cpl_imagelist *quallist,
312 moo_masklist *cosmiclist,
313 moo_crh_params *params,
314 int *nbcrh,
316 int num)
317{
318 moo_single *single = NULL;
319
320
321 if (strcmp(params->method, MOO_CRH_METHOD_MEDIAN) == 0) {
322 single = _moo_remove_CRH_collapse_median(list, quallist, type, num);
323 }
324 else if (strcmp(params->method, MOO_CRH_METHOD_MEAN) == 0) {
325 single = _moo_remove_CRH_collapse_mean(list, quallist, type, num);
326 }
327 else {
328 single = _moo_remove_CRH_collapse_sigclip(list, quallist, cosmiclist,
329 params->kappa, params->niter,
330 nbcrh, type, num);
331 }
332 return single;
333}
334
335
336static cpl_error_code
337_moo_copy_header_kw(cpl_propertylist *res_header,
338 const cpl_propertylist *orig_header)
339{
340 cpl_ensure_code(res_header != NULL, CPL_ERROR_NULL_INPUT);
341 cpl_ensure_code(orig_header != NULL, CPL_ERROR_NULL_INPUT);
342
343 cpl_propertylist_copy_property_regexp(res_header, orig_header, "ESO DET *",
344 0);
345 cpl_propertylist_copy_property_regexp(res_header, orig_header, "HDU*", 0);
346 cpl_propertylist_copy_property(res_header, orig_header, MOO_PFITS_BUNIT);
347 cpl_propertylist_copy_property(res_header, orig_header, MOO_PFITS_ERRDATA);
348 cpl_propertylist_copy_property(res_header, orig_header, MOO_PFITS_QUALDATA);
349 cpl_propertylist_copy_property(res_header, orig_header, MOO_PFITS_CRPIX1);
350 cpl_propertylist_copy_property(res_header, orig_header, MOO_PFITS_CRPIX2);
351 cpl_propertylist_copy_property(res_header, orig_header, MOO_PFITS_CRVAL1);
352 cpl_propertylist_copy_property(res_header, orig_header, MOO_PFITS_CRVAL2);
353 cpl_propertylist_copy_property(res_header, orig_header, MOO_PFITS_CTYPE1);
354 cpl_propertylist_copy_property(res_header, orig_header, MOO_PFITS_CTYPE2);
355 cpl_propertylist_copy_property(res_header, orig_header, MOO_PFITS_CD1_1);
356 cpl_propertylist_copy_property(res_header, orig_header, MOO_PFITS_CD1_2);
357 cpl_propertylist_copy_property(res_header, orig_header, MOO_PFITS_CUNIT1);
358 cpl_propertylist_copy_property(res_header, orig_header, MOO_PFITS_CD2_1);
359 cpl_propertylist_copy_property(res_header, orig_header, MOO_PFITS_CD2_2);
360 return cpl_error_get_code();
361}
362
363static cpl_error_code
364_moo_remove_crh_single(moo_detlist *detlist,
365 moo_masklist *cosmiclist,
366 moo_det *orig_det,
368 int num,
369 unsigned int badpix_level,
370 moo_crh_params *params,
371 moo_det *res,
372 int *nbcrh_total)
373{
374 cpl_error_code status = CPL_ERROR_NONE;
375 int nbcrh = 0;
376 moo_single *single = NULL;
377
378
379 moo_detlist_load_single(detlist, type, num, badpix_level);
380 hdrl_imagelist *list = moo_detlist_get_image(detlist, type, num);
381 cpl_imagelist *qlist = moo_detlist_get_single_qual(detlist, type, num);
382
383 single = _moo_remove_CRH_collapse(list, qlist, cosmiclist, params, &nbcrh,
384 type, num);
385 if (single != NULL) {
386 cpl_propertylist *header = NULL;
387
388 moo_try_check(header = moo_det_get_single_header(orig_det, type, num),
389 " ");
390 moo_try_check(_moo_copy_header_kw(single->header, header), " ");
391 *nbcrh_total += nbcrh;
392 }
393moo_try_cleanup:
394 moo_det_set_single(res, type, num, single);
395 cpl_imagelist_unwrap(qlist);
396 hdrl_imagelist_unwrap(list);
397 moo_detlist_free_single(detlist, type, num);
398 return status;
399}
400/*----------------------------------------------------------------------------*/
425/*----------------------------------------------------------------------------*/
426moo_det *
427moo_remove_CRH(moo_detlist *detlist,
428 moo_masklist *cosmiclist,
429 moo_crh_params *params)
430{
431 moo_det *dres = NULL;
432 cpl_ensure(detlist != NULL, CPL_ERROR_NULL_INPUT, NULL);
433 cpl_ensure(detlist->size > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
434 cpl_ensure(params != NULL, CPL_ERROR_NULL_INPUT, NULL);
435
436 cpl_errorstate prestate = cpl_errorstate_get();
437
438 if (strcmp(params->method, MOO_CRH_METHOD_MEDIAN) == 0) {
439 cpl_msg_info(__func__, "Computing median of %d frames",
440 (int)detlist->size);
441 }
442 else if (strcmp(params->method, MOO_CRH_METHOD_MEAN) == 0) {
443 cpl_msg_info(__func__, "Computing mean of %d frames",
444 (int)detlist->size);
445 }
446 else {
447 cpl_msg_info(__func__, "Computing sigma clip of %d frames",
448 (int)detlist->size);
449 }
450
451 int badpix_level = MOO_BADPIX_GOOD;
452
453 moo_det *orig_det = moo_detlist_get(detlist, 0);
454 dres = moo_det_new();
455 dres->primary_header = cpl_propertylist_duplicate(orig_det->primary_header);
456 cpl_propertylist_erase_regexp(dres->primary_header, "ESO QC FRAME RAW", 0);
457 moo_qc_set_ncom(dres->primary_header, detlist->size);
458 cpl_errorstate prev_state = cpl_errorstate_get();
459 dres->fibre_table = cpl_table_duplicate(moo_det_get_fibre_table(orig_det));
460
461 if (!cpl_errorstate_is_equal(prev_state)) {
462 cpl_msg_info(__func__, "DET input files do not have a fibre table.");
463 cpl_errorstate_set(prev_state);
464 }
465
466 int nbcrh_total = 0;
467 for (int num = 1; num <= 2; num++) {
468 moo_try_check(_moo_remove_crh_single(detlist, cosmiclist, orig_det,
469 MOO_TYPE_RI, num, badpix_level,
470 params, dres, &nbcrh_total),
471 " ");
472 moo_try_check(_moo_remove_crh_single(detlist, cosmiclist, orig_det,
473 MOO_TYPE_YJ, num, badpix_level,
474 params, dres, &nbcrh_total),
475 " ");
476 moo_try_check(_moo_remove_crh_single(detlist, cosmiclist, orig_det,
477 MOO_TYPE_H, num, badpix_level,
478 params, dres, &nbcrh_total),
479 " ");
480 }
481
482 if (strcmp(params->method, MOO_CRH_METHOD_SIGCLIP) == 0) {
483 moo_qc_set_ncrh_tot(dres->primary_header, nbcrh_total);
484 }
485
486moo_try_cleanup:
487 if (!cpl_errorstate_is_equal(prestate)) {
488 cpl_msg_error(__func__, "Error in remove CRH");
489 cpl_errorstate_dump(prestate, CPL_FALSE, cpl_errorstate_dump_one);
490 moo_det_delete(dres);
491 dres = NULL;
492 }
493 return dres;
494}
#define MOO_BADPIX_COSMIC_UNREMOVED
Definition: moo_badpix.h:42
#define MOO_BADPIX_GOOD
Definition: moo_badpix.h:36
moo_det * moo_det_new(void)
Create a new moo_det.
Definition: moo_det.c:71
cpl_table * moo_det_get_fibre_table(moo_det *self)
Get the FIBRE TABLE in DET.
Definition: moo_det.c:424
void moo_det_delete(moo_det *self)
Delete a moo_det.
Definition: moo_det.c:472
const char * moo_detector_get_extname(moo_detector_type type, int ntas)
Get the extension name of a detector.
Definition: moo_detector.c:137
enum _moo_detector_type_ moo_detector_type
The type code type.
Definition: moo_detector.h:64
@ MOO_TYPE_YJ
Definition: moo_detector.h:50
@ MOO_TYPE_H
Definition: moo_detector.h:54
@ MOO_TYPE_RI
Definition: moo_detector.h:46
hdrl_imagelist * moo_detlist_get_image(const moo_detlist *self, moo_detector_type type, int num)
Get the all the images of the type part in the detlist.
Definition: moo_detlist.c:225
cpl_error_code moo_detlist_free_single(const moo_detlist *self, moo_detector_type type, int num)
Free the type part for all DET in the detlist.
Definition: moo_detlist.c:143
cpl_imagelist * moo_detlist_get_single_qual(const moo_detlist *self, moo_detector_type type, int num)
Get the type QUAL part for all DET in the detlist.
Definition: moo_detlist.c:320
cpl_error_code moo_detlist_load_single(const moo_detlist *self, moo_detector_type type, int num, int level)
Load the type part for all DET in the detlist.
Definition: moo_detlist.c:107
moo_det * moo_detlist_get(moo_detlist *self, int i)
Get the DET at the position i in the list.
Definition: moo_detlist.c:196
cpl_error_code moo_mask_set(moo_mask *self, moo_detector_type type, int num, cpl_mask *mask)
Set the cpl_mask associated to given type,num.
Definition: moo_mask.c:103
moo_mask * moo_masklist_get(moo_masklist *self, int i)
Get the MASK at the position i in the list.
Definition: moo_masklist.c:121
cpl_mask * moo_masklist_get_mask(moo_masklist *self, int i, moo_detector_type type, int num)
Get the CPL_MASK at the position i,type,num in the list.
Definition: moo_masklist.c:147
moo_single * moo_single_new(moo_detector_type type, int ntas)
Create a new moo_single.
Definition: moo_single.c:73
moo_det * moo_remove_CRH(moo_detlist *detlist, moo_masklist *cosmiclist, moo_crh_params *params)
Remove CRH in single frames or in a combination of multiple frames.
cpl_error_code moo_qc_set_ncrh(cpl_propertylist *plist, int val)
Set the QC.NCRH value.
Definition: moo_qc.c:62
cpl_error_code moo_qc_set_ncrh_tot(cpl_propertylist *plist, int val)
Set the QC.NCRH.TOT value.
Definition: moo_qc.c:91
cpl_error_code moo_qc_set_ncrh_avg(cpl_propertylist *plist, float val)
Set the QC.NCRH value.
Definition: moo_qc.c:120
cpl_error_code moo_qc_set_ncom(cpl_propertylist *plist, int val)
Set the QC.NCOM value.
Definition: moo_qc.c:149