MOONS Pipeline Reference Manual 0.13.1
moo_sci_single.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 <cpl.h>
29#include "moo_pfits.h"
30#include "moo_sci_single.h"
31#include "moo_fits.h"
32#include "moo_qc.h"
33#include "moo_badpix.h"
34#include "moo_utils.h"
35/*----------------------------------------------------------------------------*/
51/*----------------------------------------------------------------------------*/
52
55/*-----------------------------------------------------------------------------
56 Function codes
57 -----------------------------------------------------------------------------*/
58
59/*----------------------------------------------------------------------------*/
67/*----------------------------------------------------------------------------*/
68moo_sci_single *
70{
71 moo_sci_single *res = cpl_calloc(1, sizeof(moo_sci_single));
72 res->badpix_mask = MOO_BADPIX_GOOD;
73 res->type = type;
74 const char *extname = moo_detector_get_name(type);
75 res->extname = extname;
76 res->header = cpl_propertylist_new();
77 return res;
78}
79
80/*----------------------------------------------------------------------------*/
89/*----------------------------------------------------------------------------*/
90
91void
92moo_sci_single_delete(moo_sci_single *self)
93{
94 if (self != NULL) {
95 if (self->header != NULL) {
96 cpl_propertylist_delete(self->header);
97 self->header = NULL;
98 }
99 if (self->image != NULL) {
100 hdrl_image_delete(self->image);
101 }
102 if (self->qual != NULL) {
103 cpl_image_delete(self->qual);
104 }
105 if (self->sky != NULL) {
106 cpl_image_delete(self->sky);
107 }
108 cpl_free(self);
109 }
110}
111
112
113/*----------------------------------------------------------------------------*/
122/*----------------------------------------------------------------------------*/
123void
124moo_sci_single_save(moo_sci_single *self,
125 const char *filename,
127{
128 const char *extname = moo_detector_get_name(type);
129
130 if (self != NULL && self->image != NULL) {
131 moo_fits_write_extension_image(hdrl_image_get_image(self->image),
132 filename, NULL, extname,
133 MOO_SCI_SINGLE_DATA_TYPE, self->header);
134
135 cpl_propertylist *err_header = cpl_propertylist_new();
136 moo_pfits_append_hduclass_error(err_header, type, -1, self->header);
137
138 moo_fits_write_extension_image(hdrl_image_get_error(self->image),
139 filename, MOO_SCI_SINGLE_ERR, extname,
140 MOO_SCI_SINGLE_ERR_TYPE, err_header);
141 cpl_propertylist_delete(err_header);
142 cpl_propertylist *qual_header = cpl_propertylist_new();
143 moo_pfits_append_hduclass_quality(qual_header, type, -1, self->header,
144 self->badpix_mask);
145 moo_fits_write_extension_image(self->qual, filename,
146 MOO_SCI_SINGLE_QUAL, extname,
147 MOO_SCI_SINGLE_QUAL_TYPE, qual_header);
148 cpl_propertylist_delete(qual_header);
149 }
150 else {
151 cpl_propertylist *h = cpl_propertylist_new();
152 cpl_propertylist_append_string(h, MOO_PFITS_EXTNAME, extname);
153 cpl_propertylist_save(h, filename, CPL_IO_EXTEND);
154 cpl_propertylist_delete(h);
155
156 moo_fits_write_extension_image(NULL, filename, MOO_SCI_SINGLE_ERR,
157 extname, MOO_SCI_SINGLE_ERR_TYPE, NULL);
158 moo_fits_write_extension_image(NULL, filename, MOO_SCI_SINGLE_QUAL,
159 extname, MOO_SCI_SINGLE_QUAL_TYPE, NULL);
160 }
161
162 if (self != NULL && self->sky != NULL) {
163 cpl_propertylist *sky_header = cpl_propertylist_new();
164 cpl_propertylist_copy_property(sky_header, self->header,
165 MOO_PFITS_BUNIT);
166 cpl_propertylist_copy_property(sky_header, self->header,
167 MOO_PFITS_CRPIX1);
168 cpl_propertylist_copy_property(sky_header, self->header,
169 MOO_PFITS_CRVAL1);
170 cpl_propertylist_copy_property(sky_header, self->header,
171 MOO_PFITS_CD1_1);
172 cpl_propertylist_copy_property(sky_header, self->header,
173 MOO_PFITS_CTYPE1);
174 cpl_propertylist_copy_property(sky_header, self->header,
175 MOO_PFITS_CUNIT1);
176 /*
177 cpl_propertylist_append_double(res->header,MOO_PFITS_CRPIX2,MOO_EXT_SINGLE_CRPIX2);
178 cpl_propertylist_append_double(res->header,MOO_PFITS_CRVAL2,MOO_EXT_SINGLE_CRVAL2);
179 cpl_propertylist_append_double(res->header,MOO_PFITS_CDELT2,MOO_EXT_SINGLE_CDELT2);
180 cpl_propertylist_append_string(res->header,MOO_PFITS_CTYPE2,MOO_EXT_SINGLE_CTYPE2);
181*/
182 moo_fits_write_extension_image(self->sky, filename, MOO_SCI_SINGLE_SKY,
183 extname, CPL_TYPE_FLOAT, sky_header);
184 cpl_propertylist_delete(sky_header);
185 }
186 else {
187 moo_fits_write_extension_image(NULL, filename, MOO_SCI_SINGLE_SKY,
188 extname, MOO_SCI_SINGLE_ERR_TYPE, NULL);
189 }
190}
191
192/*----------------------------------------------------------------------------*/
203/*----------------------------------------------------------------------------*/
204moo_sci_single *
205moo_sci_single_create(const char *filename, moo_detector_type type)
206{
207 cpl_ensure(filename != NULL, CPL_ERROR_NULL_INPUT, NULL);
208
209 moo_sci_single *single = NULL;
210 cpl_propertylist *header = NULL;
211
212 const char *extname = moo_detector_get_name(type);
213
214 header = moo_fits_load_extension_header(filename, NULL, extname);
215 if (header != NULL) {
216 int naxis = moo_pfits_get_naxis(header);
217 if (naxis > 0) {
218 single = moo_sci_single_new(type);
219 single->filename = filename;
220 cpl_propertylist_append(single->header, header);
221 }
222 cpl_propertylist_delete(header);
223 }
224 return single;
225}
226
227/*----------------------------------------------------------------------------*/
235/*----------------------------------------------------------------------------*/
236cpl_error_code
237moo_sci_single_load(moo_sci_single *self, unsigned int level)
238{
239 if (self != NULL) {
240 if ((self->filename != NULL) && (self->extname != NULL)) {
241 if (self->header == NULL) {
242 cpl_size extnum =
243 cpl_fits_find_extension(self->filename, self->extname);
244 if (extnum > 0) {
245 self->header =
246 cpl_propertylist_load(self->filename, extnum);
247 }
248 }
249 if (self->qual == NULL) {
250 self->qual =
251 moo_fits_load_extension_image(self->filename,
252 MOO_SCI_SINGLE_QUAL,
253 self->extname, CPL_TYPE_INT);
254 }
255 if (self->image == NULL) {
256 cpl_image *data = NULL;
257 cpl_image *err = NULL;
258
259 data = moo_fits_load_extension_image(self->filename, NULL,
260 self->extname,
261 CPL_TYPE_DOUBLE);
262 err = moo_fits_load_extension_image(self->filename,
263 MOO_SCI_SINGLE_ERR,
264 self->extname,
265 CPL_TYPE_DOUBLE);
266
267 if (data != NULL && err != NULL) {
268 self->image = hdrl_image_create(data, err);
269 cpl_image_delete(data);
270 cpl_image_delete(err);
271 }
272 }
273 self->sky = moo_sci_single_get_sky(self);
274 }
275
276 cpl_mask *mask = hdrl_image_get_mask(self->image);
277 moo_badpix_to_mask(self->qual, mask, level);
278 }
279 return CPL_ERROR_NONE;
280}
281
282/*----------------------------------------------------------------------------*/
292/*----------------------------------------------------------------------------*/
293hdrl_image *
294moo_sci_single_get_image(moo_sci_single *self)
295{
296 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
297
298 return self->image;
299}
300
301/*----------------------------------------------------------------------------*/
312/*----------------------------------------------------------------------------*/
313cpl_propertylist *
314moo_sci_single_get_header(moo_sci_single *self)
315{
316 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
317
318 if (self->header == NULL && self->filename != NULL &&
319 self->extname != NULL) {
320 self->header =
321 moo_fits_load_extension_header(self->filename, NULL, self->extname);
322 if (self->header == NULL) {
323 self->header = cpl_propertylist_new();
324 }
325 }
326 return self->header;
327}
328
329/*----------------------------------------------------------------------------*/
340/*----------------------------------------------------------------------------*/
341cpl_image *
342moo_sci_single_get_sky(moo_sci_single *self)
343{
344 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
345
346 if (self->sky == NULL && self->filename != NULL && self->extname != NULL) {
347 self->sky =
348 moo_fits_load_extension_image(self->filename, MOO_SCI_SINGLE_SKY,
349 self->extname, CPL_TYPE_DOUBLE);
350 }
351 return self->sky;
352}
353
354/*----------------------------------------------------------------------------*/
364/*----------------------------------------------------------------------------*/
365cpl_image *
366moo_sci_single_get_qual(moo_sci_single *self)
367{
368 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
369
370 if (self->qual == NULL) {
371 cpl_ensure(self->filename != NULL, CPL_ERROR_NULL_INPUT, NULL);
372 cpl_ensure(self->extname != NULL, CPL_ERROR_NULL_INPUT, NULL);
373 self->qual =
374 moo_fits_load_extension_image(self->filename, MOO_SCI_SINGLE_QUAL,
375 self->extname,
376 MOO_SCI_SINGLE_QUAL_TYPE);
377 }
378 return self->qual;
379}
380
381/*----------------------------------------------------------------------------*/
390/*----------------------------------------------------------------------------*/
391double
392moo_sci_single_compute_snr(moo_sci_single *self,
393 int targ_idx,
394 moo_sky_lines_list *skylines)
395{
396 double snr = NAN;
397
398 double *zwmin = NULL;
399 double *zwmax = NULL;
400 cpl_array *sel = NULL;
401 cpl_vector *data = NULL;
402 hdrl_image *fimg = NULL;
403 cpl_vector *row = NULL;
404
405 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, 0.0);
406 cpl_errorstate prev_state = cpl_errorstate_get();
407
408 hdrl_image *himg = moo_sci_single_get_image(self);
409 cpl_propertylist *header = moo_sci_single_get_header(self);
410 int nx = hdrl_image_get_size_x(himg);
411 double crpix1 = moo_pfits_get_crpix1(header);
412 double cd1_1 = moo_pfits_get_cd1_1(header);
413 double crval1 = moo_pfits_get_crval1(header);
414 double wmin = (0.5 - crpix1) * cd1_1 + crval1;
415 double wmax = (nx + 0.5 - crpix1) * cd1_1 + crval1;
416
417
418 moo_try_check(moo_sky_lines_list_get_free_zones(skylines, wmin, wmax,
419 &zwmin, &zwmax, &sel),
420 " ");
421 int size = cpl_array_get_size(sel);
422
423 for (int i = 0; i < size; i++) {
424 int idx = cpl_array_get_cplsize(sel, i, NULL);
425 double cmin = zwmin[idx];
426 double cmax = zwmax[idx];
427 int start = (cmin - crval1) / cd1_1 + crpix1;
428 int stop = (cmax - crval1) / cd1_1 + crpix1;
429 fimg = hdrl_image_extract(himg, start, targ_idx, stop, targ_idx);
430 hdrl_image_reject_value(fimg, CPL_VALUE_NAN);
431 cpl_image *img = hdrl_image_get_image(fimg);
432 cpl_image *error = hdrl_image_get_error(fimg);
433 cpl_image_reject_value(error, CPL_VALUE_NAN | CPL_VALUE_ZERO);
434 cpl_image_divide(img, error);
435 row = cpl_vector_new_from_image_row(img, 1);
436 if (data == NULL) {
437 data = cpl_vector_duplicate(row);
438 }
439 else {
440 int vsize = cpl_vector_get_size(data);
441 int row_size = cpl_vector_get_size(row);
442 cpl_vector_set_size(data, vsize + row_size);
443 for (int j = 0; j < row_size; j++) {
444 double v = cpl_vector_get(row, j);
445 cpl_vector_set(data, j + vsize, v);
446 }
447 }
448 cpl_vector_delete(row);
449 hdrl_image_delete(fimg);
450 fimg = NULL;
451 row = NULL;
452 }
453 snr = cpl_vector_get_median(data);
454
455moo_try_cleanup:
456 if (!cpl_errorstate_is_equal(prev_state)) {
457 cpl_vector_delete(row);
458 hdrl_image_delete(fimg);
459 snr = NAN;
460 cpl_msg_error(__func__, "Can't compute snr for target %d", targ_idx);
461 cpl_errorstate_set(prev_state);
462 }
463 cpl_vector_delete(data);
464 cpl_array_delete(sel);
465 return snr;
466}
467/*----------------------------------------------------------------------------*/
cpl_error_code moo_badpix_to_mask(cpl_image *badpix, cpl_mask *mask, unsigned int level)
Apply the badpix map on the given mask.
Definition: moo_badpix.c:58
#define MOO_BADPIX_GOOD
Definition: moo_badpix.h:36
const char * moo_detector_get_name(moo_detector_type type)
Get the extension name of a detector.
Definition: moo_detector.c:183
enum _moo_detector_type_ moo_detector_type
The type code type.
Definition: moo_detector.h:64
cpl_error_code moo_fits_write_extension_image(cpl_image *image, const char *filename, const char *name, const char *detectorname, cpl_type type, cpl_propertylist *header)
Write an image as extension in FITS file.
Definition: moo_fits.c:123
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
void moo_sci_single_save(moo_sci_single *self, const char *filename, moo_detector_type type)
Save a moo_sci_single to a FITS file.
moo_sci_single * moo_sci_single_new(moo_detector_type type)
Create a new moo_sci_single.
void moo_sci_single_delete(moo_sci_single *self)
Delete a moo_sci_single.
cpl_image * moo_sci_single_get_sky(moo_sci_single *self)
Get sky of sci single.
hdrl_image * moo_sci_single_get_image(moo_sci_single *self)
Get image of SCI_SINGLE.
cpl_image * moo_sci_single_get_qual(moo_sci_single *self)
Get image of qual.
cpl_error_code moo_sci_single_load(moo_sci_single *self, unsigned int level)
Load a moo_sci_single from the filename.
cpl_propertylist * moo_sci_single_get_header(moo_sci_single *self)
Get header of sci single.
double moo_sci_single_compute_snr(moo_sci_single *self, int targ_idx, moo_sky_lines_list *skylines)
Compute SNR for a given target.
moo_sci_single * moo_sci_single_create(const char *filename, moo_detector_type type)
Create a new moo_sci_single with the given filename and type.
cpl_error_code moo_sky_lines_list_get_free_zones(moo_sky_lines_list *self, double wmin, double wmax, double **zwmin, double **zwmax, cpl_array **sel)
Get free zones for a specific wave range.
double moo_pfits_get_cd1_1(const cpl_propertylist *plist)
find out the CD1_1 value
Definition: moo_pfits.c:1256
cpl_error_code moo_pfits_append_hduclass_quality(cpl_propertylist *plist, moo_detector_type type, int ntas, const cpl_propertylist *sci_header, int mask)
Set the HDUCLASS QUALITY Keyword.
Definition: moo_pfits.c:1591
cpl_error_code moo_pfits_append_hduclass_error(cpl_propertylist *plist, moo_detector_type type, int ntas, const cpl_propertylist *sci_header)
Set the HDUCLASS ERROR Keyword.
Definition: moo_pfits.c:1537
double moo_pfits_get_crval1(const cpl_propertylist *plist)
find out the CRVAL1 value
Definition: moo_pfits.c:1176
double moo_pfits_get_crpix1(const cpl_propertylist *plist)
find out the CRPIX1 value
Definition: moo_pfits.c:1196
int moo_pfits_get_naxis(const cpl_propertylist *plist)
find out the NAXIS value
Definition: moo_pfits.c:980