MOONS Pipeline Reference Manual 0.13.2
moo_prepare.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_fits.h"
41#include "moo_detector.h"
42#include "moo_drl.h"
43#include "moo_prepare.h"
44/*----------------------------------------------------------------------------*/
49/*----------------------------------------------------------------------------*/
50
53/*-----------------------------------------------------------------------------
54 Function codes
55 -----------------------------------------------------------------------------*/
56
57static cpl_image *
58_moo_prepare_get_qual_extension(const char *filename,
59 const char *extname,
60 moo_outputs *outputs,
61 cpl_image *data,
63{
64 cpl_image *rqual = NULL;
65 cpl_image *qual = NULL;
66
67 if (data != NULL) {
68 int nx = cpl_image_get_size_x(data);
69 int ny = cpl_image_get_size_y(data);
70
71 if (filename != NULL) {
72 rqual = moo_fits_load_extension_image(filename, "QUAL", extname,
73 CPL_TYPE_INT);
74 int qnx = cpl_image_get_size_x(rqual);
75 int qny = cpl_image_get_size_y(rqual);
76
77 if (qnx == nx && qny == ny) {
78 qual = cpl_image_duplicate(rqual);
79 }
80 else {
81 qual = moo_outputs_create_det(outputs, rqual, nx, ny, type);
82 }
83 cpl_image_delete(rqual);
84 }
85 if (qual == NULL) {
86 qual = cpl_image_new(nx, ny, CPL_TYPE_INT);
87 }
88 }
89 return qual;
90}
91
92static cpl_error_code
93_moo_prepare_image_output(cpl_image *idata, moo_output out)
94{
95 cpl_ensure_code(idata != NULL, CPL_ERROR_NULL_INPUT);
96 int x = out.dx - 1;
97 int y = out.dy - 1;
98 int nx = out.nx;
99 int ny = out.ny;
100 double gain = out.gain;
101 /* ADU to e- */
102 int size_x = cpl_image_get_size_x(idata);
103
104 double *data = cpl_image_get_data_double(idata);
105
106 for (int j = y; j < (y + ny); j++) {
107 for (int i = x; i < (x + nx); i++) {
108 data[i + j * size_x] = MOO_TO_ELECTRON(data[i + j * size_x], gain);
109 }
110 }
111
112 return CPL_ERROR_NONE;
113}
114
115static cpl_error_code
116_moo_prepare_error_output(cpl_image *ierr,
117 cpl_image *idata,
118 cpl_image *ibias,
119 moo_output out)
120{
121 cpl_ensure_code(ierr != NULL, CPL_ERROR_NULL_INPUT);
122 int x = out.dx - 1;
123 int y = out.dy - 1;
124 int nx = out.nx;
125 int ny = out.ny;
126 double ron = out.ron;
127 double *err = cpl_image_get_data_double(ierr);
128 int size_x = cpl_image_get_size_x(ierr);
129 const double *data = cpl_image_get_data_double_const(idata);
130
131 if (ibias != NULL) {
132 const double *biasdata = cpl_image_get_data_double_const(ibias);
133 for (int j = y; j < (y + ny); j++) {
134 for (int i = x; i < (x + nx); i++) {
135 int idx = i + j * size_x;
136 err[idx] = sqrt(ron * ron + fabs(data[idx] - biasdata[idx]));
137 }
138 }
139 }
140 else {
141 for (int j = y; j < (y + ny); j++) {
142 for (int i = x; i < (x + nx); i++) {
143 int idx = i + j * size_x;
144 err[idx] = ron;
145 }
146 }
147 }
148
149 return CPL_ERROR_NONE;
150}
151
152static cpl_error_code
153_moo_prepare_single_adu(moo_single *single, const char *const qual_filename_rp)
154{
155 cpl_image *data = NULL;
156 cpl_image *rdata = NULL;
157 cpl_image *err = NULL;
158 cpl_image *qual_rp = NULL;
159 moo_outputs *outputs = NULL;
160
161 cpl_ensure_code(single != NULL, CPL_ERROR_NULL_INPUT);
162
163 const char *extname = single->extname;
164 int num = single->ntas;
165 /* header */
166 cpl_propertylist *header = moo_single_get_header(single);
167
168 cpl_propertylist_update_string(header, MOO_PFITS_BUNIT,
169 MOO_PREPARE_ADU_BUNIT);
170 moo_pfits_append_hduclass_data(header, single->type, num);
171 outputs = moo_outputs_load(header, single->type);
172
173 int nx = moo_pfits_get_det_chip_nx(header);
174 int ny = moo_pfits_get_det_chip_ny(header);
175 if (single->type != MOO_TYPE_RI) {
176 moo_outputs_get_det_size(outputs, &nx, &ny);
177 }
178 moo_try_check(rdata =
179 moo_fits_load_extension_image(single->filename, NULL,
180 extname, CPL_TYPE_DOUBLE),
181 " ");
182 data = moo_outputs_create_det(outputs, rdata, nx, ny, single->type);
183 cpl_msg_info("moo_prepare", " Creating %s", extname);
184 cpl_msg_info("moo_prepare", " Creating ERR_%s", extname);
185
186 err = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
187 single->image = hdrl_image_create(data, err);
188 cpl_msg_info("moo_prepare", " Creating QUAL_%s", extname);
189 moo_try_check(qual_rp = _moo_prepare_get_qual_extension(qual_filename_rp,
190 extname, outputs,
191 data, single->type),
192 " ");
193 single->qual = qual_rp;
194
195moo_try_cleanup:
196 cpl_image_delete(rdata);
197 cpl_image_delete(data);
198 cpl_image_delete(err);
199 moo_outputs_delete(outputs);
200 return CPL_ERROR_NONE;
201}
202
203static cpl_error_code
204_moo_prepare_single(moo_single *single,
205 const char *const qual_filename_nl,
206 const char *const masterbias_filename)
207{
208 cpl_image *data = NULL;
209 cpl_image *err = NULL;
210 cpl_image *biasdata = NULL;
211 cpl_image *qual_nl = NULL;
212 moo_outputs *outputs = NULL;
213
214 cpl_ensure_code(single != NULL, CPL_ERROR_NULL_INPUT);
215
216 const char *extname = single->extname;
217 /* header */
218 cpl_propertylist *header = moo_single_get_header(single);
219 if (!cpl_propertylist_has(header, MOO_PFITS_CDELT1)) {
220 double cd1_1 = moo_pfits_get_cd1_1(header);
221 cpl_propertylist_append_double(header, MOO_PFITS_CDELT1, cd1_1);
222 }
223 if (!cpl_propertylist_has(header, MOO_PFITS_CDELT2)) {
224 double cd2_2 = moo_pfits_get_cd2_2(header);
225 cpl_propertylist_append_double(header, MOO_PFITS_CDELT2, cd2_2);
226 }
227 cpl_propertylist_update_string(header, MOO_PFITS_BUNIT,
228 MOO_PREPARE_COUNT_BUNIT);
229
230 outputs = moo_outputs_load(header, single->type);
231
232 hdrl_image *image = moo_single_get_image(single);
233 data = hdrl_image_get_image(image);
234 err = hdrl_image_get_error(image);
235
236 cpl_msg_info("moo_prepare", " Creating %s", extname);
237
238 for (int i = 0; i < outputs->nb; i++) {
239 if (single->type == MOO_TYPE_RI) {
240 moo_pfits_set_det_outi_x(header, i + 1, outputs->outputs[i].dx);
241 moo_pfits_set_det_outi_y(header, i + 1, outputs->outputs[i].dy);
242 }
243 else {
244 moo_pfits_set_det_chip_outi_x(header, i + 1,
245 outputs->outputs[i].dx);
246 moo_pfits_set_det_chip_outi_y(header, i + 1,
247 outputs->outputs[i].dy);
248 }
249 _moo_prepare_image_output(data, outputs->outputs[i]);
250 }
251
252 cpl_msg_info("moo_prepare", " Creating ERR_%s", extname);
253
254 if (single->type == MOO_TYPE_RI) {
255 if (masterbias_filename != NULL) {
256 biasdata = moo_fits_load_extension_image(masterbias_filename, NULL,
257 extname, CPL_TYPE_DOUBLE);
258 }
259 }
260 else {
261 int nx = cpl_image_get_size_x(data);
262 int ny = cpl_image_get_size_y(data);
263 biasdata = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
264 }
265
266 for (int i = 0; i < outputs->nb; i++) {
267 _moo_prepare_error_output(err, data, biasdata, outputs->outputs[i]);
268 }
269
270 cpl_msg_info("moo_prepare", " Creating QUAL_%s", extname);
271 moo_try_check(qual_nl = _moo_prepare_get_qual_extension(qual_filename_nl,
272 extname, outputs,
273 data, single->type),
274 " ");
275
276 cpl_image_or(single->qual, single->qual, qual_nl);
277
278 if (single->type == MOO_TYPE_RI && masterbias_filename != NULL) {
279 cpl_image *bqual =
280 moo_fits_load_extension_image(masterbias_filename, "QUAL", extname,
281 CPL_TYPE_INT);
282 cpl_image_or(single->qual, single->qual, bqual);
283 cpl_image_delete(bqual);
284 }
285
286moo_try_cleanup:
287 if (biasdata != NULL) {
288 cpl_image_delete(biasdata);
289 }
290 cpl_image_delete(qual_nl);
291 moo_outputs_delete(outputs);
292 return CPL_ERROR_NONE;
293}
294
295
296/*----------------------------------------------------------------------------*/
322/*----------------------------------------------------------------------------*/
323moo_det *
324moo_prepare(const cpl_frame *rawframe,
325 const char *const badpixmask_rp,
326 const char *const badpixmask_nl,
327 const cpl_frame *masterbias,
328 const cpl_frame *cube_frame,
329 moo_prepare_params *params)
330{
331 moo_det *dres = NULL;
332
333 const char *masterbias_filename = NULL;
334
335 cpl_errorstate prestate = cpl_errorstate_get();
336
337 cpl_ensure(rawframe != NULL, CPL_ERROR_NULL_INPUT, NULL);
338
339 const char *filename = cpl_frame_get_filename(rawframe);
340 const char *tag = cpl_frame_get_tag(rawframe);
341 cpl_frame_group group = cpl_frame_get_group(rawframe);
342 cpl_ensure(filename != NULL, CPL_ERROR_NULL_INPUT, NULL);
343 cpl_ensure(tag != NULL, CPL_ERROR_NULL_INPUT, NULL);
344 cpl_ensure(group == CPL_FRAME_GROUP_RAW, CPL_ERROR_ILLEGAL_INPUT, NULL);
345 dres = moo_prepare_adu(rawframe, badpixmask_rp, params);
346 moo_try_check(moo_correct_detlin(dres, cube_frame), " ");
347#if DEBUG_PREPARE_ADU_LIN
348 {
349 moo_det_save(dres, "ADU_LIN.fits");
350 }
351#endif
352 cpl_msg_info(__func__, "Preparing %s", filename);
353
354 cpl_msg_indent_more();
355 if (badpixmask_nl != NULL) {
356 cpl_msg_info(__func__, "Using BP_MAP_NL %s", badpixmask_nl);
357 }
358
359 if (masterbias != NULL) {
360 masterbias_filename = cpl_frame_get_filename(masterbias);
361 cpl_msg_info(__func__, "Using MASTER_BIAS %s", masterbias_filename);
362 }
363 for (int i = 0; i < 3; i++) {
364 for (int j = 1; j <= 2; j++) {
365 moo_single *single = moo_det_get_single(dres, i, j);
366 if (single != NULL) {
367 int ignored = params->ignore_detector[i + (j - 1) * 3];
368 if (ignored == 0) {
369 moo_try_check(_moo_prepare_single(single, badpixmask_nl,
370 masterbias_filename),
371 "Error in %s",
373 }
374 }
375 }
376 }
377 cpl_msg_indent_less();
378#if DEBUG_PREPARE_ADU_LIN
379 {
380 moo_det_save(dres, "DET.fits");
381 }
382#endif
383moo_try_cleanup:
384 if (!cpl_errorstate_is_equal(prestate)) {
385 moo_det_delete(dres);
386 dres = NULL;
387 cpl_msg_error(__func__, "Error in prepare");
388 cpl_errorstate_dump(prestate, CPL_FALSE, cpl_errorstate_dump_one);
389 cpl_errorstate_set(prestate);
390 }
391 return dres;
392}
393
394static cpl_error_code
395_moo_create_primary_header(cpl_propertylist *header, const char *filename)
396{
397 cpl_error_code status = CPL_ERROR_NONE;
398
399 moo_try_check(status = moo_qc_set_is_linearcor(header, CPL_FALSE), " ");
400 moo_try_check(status = moo_qc_set_is_p2pcor(header, CPL_FALSE), " ");
401 moo_qc_set_frame_raw1(header, filename);
402moo_try_cleanup:
403 return status;
404}
405/*----------------------------------------------------------------------------*/
428/*----------------------------------------------------------------------------*/
429moo_det *
430moo_prepare_adu(const cpl_frame *rawframe,
431 const char *const badpixmask_rp,
432 moo_prepare_params *params)
433{
434 moo_det *dres = NULL;
435 int live = 0;
436 int clive = 0;
437 cpl_errorstate prestate = cpl_errorstate_get();
438
439 cpl_ensure(rawframe != NULL, CPL_ERROR_NULL_INPUT, NULL);
440
441 const char *filename = cpl_frame_get_filename(rawframe);
442 const char *tag = cpl_frame_get_tag(rawframe);
443 cpl_frame_group group = cpl_frame_get_group(rawframe);
444 cpl_ensure(filename != NULL, CPL_ERROR_NULL_INPUT, NULL);
445 cpl_ensure(tag != NULL, CPL_ERROR_NULL_INPUT, NULL);
446 cpl_ensure(group == CPL_FRAME_GROUP_RAW, CPL_ERROR_ILLEGAL_INPUT, NULL);
447
448 dres = moo_det_create(rawframe);
449 _moo_create_primary_header(dres->primary_header, filename);
450
451 cpl_msg_info(__func__, "Preparing in ADU %s", filename);
452 cpl_msg_indent_more();
453 if (badpixmask_rp != NULL) {
454 cpl_msg_info(__func__, "Using BP_MAP_RP %s", badpixmask_rp);
455 }
456
457 for (int i = 0; i < 3; i++) {
458 for (int j = 1; j <= 2; j++) {
459 moo_single *single = moo_det_get_single(dres, i, j);
460 int ignored = params->ignore_detector[i + (j - 1) * 3];
461 if (single != NULL) {
462 cpl_propertylist *header = moo_single_get_header(single);
463 moo_try_check(live = moo_pfits_get_live(header), " ");
464 ignored = ignored || !live;
465 moo_try_check(clive = moo_pfits_get_det_chip_live(header), " ");
466 ignored = ignored || !clive;
467 if (ignored == 0) {
468 moo_try_check(_moo_prepare_single_adu(single,
469 badpixmask_rp),
470 "Error in %s",
472 }
473 else {
474 moo_det_set_single(dres, i, j, NULL);
475 }
476 }
477 }
478 }
479
480 cpl_msg_indent_less();
481
482#if DEBUG_PREPARE_ADU
483
484 {
485 moo_det_save(dres, "ADU.fits");
486 }
487#endif
488
489moo_try_cleanup:
490 if (!cpl_errorstate_is_equal(prestate)) {
491 moo_det_delete(dres);
492 dres = NULL;
493 cpl_msg_error(__func__, "Error in prepare");
494 cpl_errorstate_dump(prestate, CPL_FALSE, cpl_errorstate_dump_one);
495 cpl_errorstate_set(prestate);
496 }
497 return dres;
498}
moo_det * moo_det_create(const cpl_frame *frame)
Create a new moo_det from the given DET frame.
Definition: moo_det.c:91
void moo_det_save(moo_det *self, const char *filename)
Save a moo_det to a FITS file.
Definition: moo_det.c:507
void moo_det_delete(moo_det *self)
Delete a moo_det.
Definition: moo_det.c:472
moo_single * moo_det_get_single(moo_det *self, moo_detector_type type, int num)
Get the type part in DET and return it.
Definition: moo_det.c:359
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_RI
Definition: moo_detector.h:46
cpl_image * moo_fits_load_extension_image(const char *filename, const char *name, const char *detectorname, cpl_type type)
Load an image from FITS file.
Definition: moo_fits.c:311
hdrl_image * moo_single_get_image(moo_single *self)
Get the IMAGE part (DATA,ERR) of single DET.
Definition: moo_single.c:330
moo_det * moo_prepare(const cpl_frame *rawframe, const char *const badpixmask_rp, const char *const badpixmask_nl, const cpl_frame *masterbias, const cpl_frame *cube_frame, moo_prepare_params *params)
This function transforms RAW frames in DET frames attaching the default bad pixel map and an error im...
Definition: moo_prepare.c:324
moo_det * moo_prepare_adu(const cpl_frame *rawframe, const char *const badpixmask_rp, moo_prepare_params *params)
This function transforms RAW frames in DET ADU frames attaching the default bad pixel.
Definition: moo_prepare.c:430
cpl_error_code moo_correct_detlin(moo_det *det, const cpl_frame *cube_frame)
Apply the detector linearity correction.
Definition: moo_drl.c:507
double moo_pfits_get_cd1_1(const cpl_propertylist *plist)
find out the CD1_1 value
Definition: moo_pfits.c:1256
int moo_pfits_get_det_chip_ny(const cpl_propertylist *plist)
find out the ESO DET CHIP NY value
Definition: moo_pfits.c:940
int moo_pfits_get_det_chip_live(const cpl_propertylist *plist)
find out the ESO DET CHIP LIVE value
Definition: moo_pfits.c:960
cpl_error_code moo_pfits_append_hduclass_data(cpl_propertylist *plist, moo_detector_type type, int ntas)
Set the HDUCLASS DATA Keyword.
Definition: moo_pfits.c:1504
int moo_pfits_get_live(const cpl_propertylist *plist)
find out the ESO DET LIVE value
Definition: moo_pfits.c:402
int moo_pfits_get_det_chip_nx(const cpl_propertylist *plist)
find out the ESO DET CHIP NX value
Definition: moo_pfits.c:920
cpl_image * moo_outputs_create_det(moo_outputs *self, cpl_image *raw, int nx, int ny, moo_detector_type dtype)
Create the DET data from RAW header and DATA.
Definition: moo_pfits.c:218
double moo_pfits_get_cd2_2(const cpl_propertylist *plist)
find out the CD2_2 value
Definition: moo_pfits.c:1276
cpl_error_code moo_qc_set_is_linearcor(cpl_propertylist *plist, cpl_boolean val)
Set the QC.IS.LINEARCOR value.
Definition: moo_qc.c:2381
cpl_error_code moo_qc_set_frame_raw1(cpl_propertylist *plist, const char *val)
Set the QC.FRAME.RAW1 value.
Definition: moo_qc.c:2280
cpl_error_code moo_qc_set_is_p2pcor(cpl_propertylist *plist, cpl_boolean val)
Set the QC.IS.P2PCOR value.
Definition: moo_qc.c:2416