MOONS Pipeline Reference Manual 0.13.1
moo_rbn_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_rbn_single.h"
31#include "moo_fits.h"
32#include "moo_qc.h"
33#include "moo_badpix.h"
34#include "moo_fibres_table.h"
35/*----------------------------------------------------------------------------*/
51/*----------------------------------------------------------------------------*/
52
55/*-----------------------------------------------------------------------------
56 Function codes
57 -----------------------------------------------------------------------------*/
58
59/*----------------------------------------------------------------------------*/
67/*----------------------------------------------------------------------------*/
68moo_rbn_single *
70{
71 moo_rbn_single *res = cpl_calloc(1, sizeof(moo_rbn_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_rbn_single_delete(moo_rbn_single *self)
93{
94 if (self != NULL) {
95 if (self->header != NULL) {
96 cpl_propertylist_delete(self->header);
97 }
98 if (self->image != NULL) {
99 hdrl_image_delete(self->image);
100 }
101 if (self->qual != NULL) {
102 cpl_image_delete(self->qual);
103 }
104 cpl_free(self);
105 }
106}
107
108/*----------------------------------------------------------------------------*/
119/*----------------------------------------------------------------------------*/
120moo_rbn_single *
121moo_rbn_single_create(const char *filename, moo_detector_type type)
122{
123 cpl_ensure(filename != NULL, CPL_ERROR_NULL_INPUT, NULL);
124
125 moo_rbn_single *single = NULL;
126 cpl_propertylist *header = NULL;
127
128 const char *extname = moo_detector_get_name(type);
129
130 header = moo_fits_load_extension_header(filename, NULL, extname);
131 if (header != NULL) {
132 int naxis = moo_pfits_get_naxis(header);
133 if (naxis > 0) {
134 single = moo_rbn_single_new(type);
135 single->filename = filename;
136 cpl_propertylist_append(single->header, header);
137 }
138 cpl_propertylist_delete(header);
139 }
140 return single;
141}
142
143/*----------------------------------------------------------------------------*/
152/*----------------------------------------------------------------------------*/
153void
154moo_rbn_single_save(const moo_rbn_single *self,
155 const char *filename,
157{
158 const char *extname = moo_detector_get_name(type);
159 if (self != NULL) {
160 if (self->image != NULL) {
161 moo_fits_write_extension_image(hdrl_image_get_image(self->image),
162 filename, NULL, extname,
163 CPL_TYPE_FLOAT, self->header);
164
165 cpl_propertylist *err_header = cpl_propertylist_new();
166 moo_pfits_append_hduclass_error(err_header, type, -1, self->header);
167
168 moo_fits_write_extension_image(hdrl_image_get_error(self->image),
169 filename, MOO_RBN_SINGLE_ERR,
170 extname, MOO_RBN_SINGLE_ERR_TYPE,
171 err_header);
172 cpl_propertylist_delete(err_header);
173 cpl_propertylist *qual_header = cpl_propertylist_new();
174 moo_pfits_append_hduclass_quality(qual_header, type, -1,
175 self->header, self->badpix_mask);
176 moo_fits_write_extension_image(self->qual, filename,
177 MOO_RBN_SINGLE_QUAL, extname,
178 MOO_RBN_SINGLE_QUAL_TYPE,
179 qual_header);
180 cpl_propertylist_delete(qual_header);
181 }
182 }
183 else {
184 cpl_propertylist *h = cpl_propertylist_new();
185 cpl_propertylist_append_string(h, MOO_PFITS_EXTNAME, extname);
186 cpl_propertylist_save(h, filename, CPL_IO_EXTEND);
187 cpl_propertylist_delete(h);
188
189 moo_fits_write_extension_image(NULL, filename, MOO_RBN_SINGLE_ERR,
190 extname, MOO_RBN_SINGLE_ERR_TYPE, NULL);
191 moo_fits_write_extension_image(NULL, filename, MOO_RBN_SINGLE_QUAL,
192 extname, MOO_RBN_SINGLE_QUAL_TYPE, NULL);
193 }
194}
195
196/*----------------------------------------------------------------------------*/
212/*----------------------------------------------------------------------------*/
213cpl_error_code
214moo_rbn_single_set_wcs1(moo_rbn_single *self,
215 double crpix1,
216 double crval1,
217 double cd1_1,
218 const char *ctype1,
219 const char *cunit1)
220{
221 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
222 cpl_ensure_code(self->header != NULL, CPL_ERROR_ILLEGAL_INPUT);
223
224 cpl_error_code code = CPL_ERROR_NONE;
225 code =
226 cpl_propertylist_append_double(self->header, MOO_PFITS_CRPIX1, crpix1);
227 cpl_ensure_code(code == CPL_ERROR_NONE, code);
228 code =
229 cpl_propertylist_append_double(self->header, MOO_PFITS_CRVAL1, crval1);
230 cpl_ensure_code(code == CPL_ERROR_NONE, code);
231 code = cpl_propertylist_append_double(self->header, MOO_PFITS_CD1_1, cd1_1);
232 cpl_ensure_code(code == CPL_ERROR_NONE, code);
233 code =
234 cpl_propertylist_append_string(self->header, MOO_PFITS_CTYPE1, ctype1);
235 cpl_ensure_code(code == CPL_ERROR_NONE, code);
236 code =
237 cpl_propertylist_append_string(self->header, MOO_PFITS_CUNIT1, cunit1);
238 cpl_ensure_code(code == CPL_ERROR_NONE, code);
239
240 return code;
241}
242
243/*----------------------------------------------------------------------------*/
253/*----------------------------------------------------------------------------*/
254hdrl_image *
255moo_rbn_single_get_image(moo_rbn_single *self)
256{
257 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
258
259 return self->image;
260}
261/*----------------------------------------------------------------------------*/
271/*----------------------------------------------------------------------------*/
272cpl_image *
273moo_rbn_single_get_data(moo_rbn_single *self)
274{
275 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
276
277 cpl_image *res = NULL;
278
279 if (self->image != NULL) {
280 res = hdrl_image_get_image(self->image);
281 }
282 return res;
283}
284
285/*----------------------------------------------------------------------------*/
296/*----------------------------------------------------------------------------*/
297cpl_image *
298moo_rbn_single_get_errs(moo_rbn_single *self)
299{
300 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
301
302 cpl_image *res = NULL;
303
304 if (self->image != NULL) {
305 res = hdrl_image_get_error(self->image);
306 }
307 return res;
308}
309
310/*----------------------------------------------------------------------------*/
320/*----------------------------------------------------------------------------*/
321cpl_image *
322moo_rbn_single_get_qual(moo_rbn_single *self)
323{
324 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
325 cpl_ensure(self->filename != NULL, CPL_ERROR_NULL_INPUT, NULL);
326 cpl_ensure(self->extname != NULL, CPL_ERROR_NULL_INPUT, NULL);
327
328 if (self->qual == NULL) {
329 self->qual =
330 moo_fits_load_extension_image(self->filename, MOO_RBN_SINGLE_QUAL,
331 self->extname,
332 MOO_RBN_SINGLE_QUAL_TYPE);
333 }
334 return self->qual;
335}
336
337/*----------------------------------------------------------------------------*/
348/*----------------------------------------------------------------------------*/
349cpl_propertylist *
350moo_rbn_single_get_header(moo_rbn_single *self)
351{
352 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
353
354 if (self->header == NULL && self->extname != NULL &&
355 self->filename != NULL) {
356 self->header =
357 moo_fits_load_extension_header(self->filename, NULL, self->extname);
358 if (self->header == NULL) {
359 self->header = cpl_propertylist_new();
360 }
361 }
362 return self->header;
363}
364
365/*----------------------------------------------------------------------------*/
374/*----------------------------------------------------------------------------*/
375cpl_error_code
376moo_rbn_single_load(moo_rbn_single *self, unsigned int level)
377{
378 if (self != NULL) {
379 if ((self->filename != NULL) && (self->extname != NULL)) {
380 if (self->header == NULL) {
381 cpl_size extnum =
382 cpl_fits_find_extension(self->filename, self->extname);
383 if (extnum > 0) {
384 self->header =
385 cpl_propertylist_load(self->filename, extnum);
386 }
387 }
388 if (self->qual == NULL) {
389 self->qual =
390 moo_fits_load_extension_image(self->filename,
391 MOO_RBN_SINGLE_QUAL,
392 self->extname, CPL_TYPE_INT);
393 }
394 if (self->image == NULL) {
395 cpl_image *data = NULL;
396 cpl_image *err = NULL;
397
398 data = moo_fits_load_extension_image(self->filename, NULL,
399 self->extname,
400 CPL_TYPE_DOUBLE);
401 err = moo_fits_load_extension_image(self->filename,
402 MOO_RBN_SINGLE_ERR,
403 self->extname,
404 CPL_TYPE_DOUBLE);
405
406 if (data != NULL && err != NULL) {
407 self->image = hdrl_image_create(data, err);
408 cpl_image_delete(data);
409 cpl_image_delete(err);
410 }
411 }
412 }
413
414 cpl_mask *mask = hdrl_image_get_mask(self->image);
415 moo_badpix_to_mask(self->qual, mask, level);
416 }
417 return CPL_ERROR_NONE;
418}
419
420
421/*----------------------------------------------------------------------------*/
430/*----------------------------------------------------------------------------*/
431double
432moo_rbn_single_compute_snr(moo_rbn_single *self,
433 int rbn_idx,
434 moo_sky_lines_list *skylines)
435{
436 double snr = 0.0;
437 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, 0.0);
438
439 hdrl_image *himg = moo_rbn_single_get_image(self);
440 cpl_propertylist *header = moo_rbn_single_get_header(self);
441
442 int nx = hdrl_image_get_size_x(himg);
443 double crpix1 = moo_pfits_get_crpix1(header);
444 double cd1_1 = moo_pfits_get_cd1_1(header);
445 double crval1 = moo_pfits_get_crval1(header);
446 double wmin = (0.5 - crpix1) * cd1_1 + crval1;
447 double wmax = (nx + 0.5 - crpix1) * cd1_1 + crval1;
448
449 double *zwmin = NULL;
450 double *zwmax = NULL;
451 cpl_array *sel = NULL;
452 moo_sky_lines_list_get_free_zones(skylines, wmin, wmax, &zwmin, &zwmax,
453 &sel);
454 int size = cpl_array_get_size(sel);
455 cpl_vector *data = NULL;
456 for (int i = 0; i < size; i++) {
457 int idx = cpl_array_get_cplsize(sel, i, NULL);
458 double cmin = zwmin[idx];
459 double cmax = zwmax[idx];
460 int start = (cmin - crval1) / cd1_1 + crpix1;
461 int stop = (cmax - crval1) / cd1_1 + crpix1;
462
463 hdrl_image *fimg =
464 hdrl_image_extract(himg, start, rbn_idx, stop, rbn_idx);
465 hdrl_image_reject_value(fimg, CPL_VALUE_NAN);
466 cpl_image *img = hdrl_image_get_image(fimg);
467 cpl_image *error = hdrl_image_get_error(fimg);
468 cpl_image_reject_value(error, CPL_VALUE_NAN | CPL_VALUE_ZERO);
469
470 int enx = cpl_image_get_size_x(error);
471 int enbrej = cpl_image_count_rejected(error);
472
473 if (enx > enbrej) {
474 cpl_image_divide(img, error);
475 cpl_vector *row = cpl_vector_new_from_image_row(img, 1);
476 if (data == NULL) {
477 data = cpl_vector_duplicate(row);
478 }
479 else {
480 int vsize = cpl_vector_get_size(data);
481 int row_size = cpl_vector_get_size(row);
482 cpl_vector_set_size(data, vsize + row_size);
483 for (int j = 0; j < row_size; j++) {
484 double v = cpl_vector_get(row, j);
485 cpl_vector_set(data, j + vsize, v);
486 }
487 }
488 cpl_vector_delete(row);
489 }
490 hdrl_image_delete(fimg);
491 }
492 if (data != NULL) {
493 snr = cpl_vector_get_median(data);
494 }
495 else {
496 snr = NAN;
497 }
498
499 cpl_vector_delete(data);
500 cpl_array_delete(sel);
501
502 return snr;
503}
504
505/*----------------------------------------------------------------------------*/
517/*----------------------------------------------------------------------------*/
518cpl_error_code
519moo_rbn_single_dump(const moo_rbn_single *self, FILE *stream)
520{
521 cpl_ensure_code(stream != NULL, CPL_ERROR_NULL_INPUT);
522
523 if (self != NULL) {
524 fprintf(stream, "---MOO_RBN_SINGLE\n");
525 fprintf(stream, "extname %s\n", self->extname);
526 fprintf(stream, "filename %s\n", self->filename);
527 fprintf(stream, "image: ");
528 if (self->image != NULL) {
529 cpl_image_dump_structure(hdrl_image_get_image(self->image), stream);
530 }
531 else {
532 fprintf(stream, "null\n");
533 }
534 fprintf(stream, "header %p\n", (void *)self->header);
535 fprintf(stream, "qual: ");
536 if (self->qual != NULL) {
537 cpl_image_dump_structure(self->qual, stream);
538 }
539 else {
540 fprintf(stream, "null\n");
541 }
542 }
543
544 return CPL_ERROR_NONE;
545}
546
547/*----------------------------------------------------------------------------*/
557/*----------------------------------------------------------------------------*/
558cpl_error_code
559moo_rbn_single_free(moo_rbn_single *self)
560{
561 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
562
563 if (self->filename != NULL && self->extname != NULL) {
564 if (self->header != NULL) {
565 cpl_propertylist_delete(self->header);
566 self->header = NULL;
567 }
568 if (self->image != NULL) {
569 hdrl_image_delete(self->image);
570 self->image = NULL;
571 }
572 if (self->qual != NULL) {
573 cpl_image_delete(self->qual);
574 self->qual = NULL;
575 }
576 }
577 return CPL_ERROR_NONE;
578}
579/*----------------------------------------------------------------------------*/
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
hdrl_image * moo_rbn_single_get_image(moo_rbn_single *self)
Get image of RBN_SINGLE.
moo_rbn_single * moo_rbn_single_create(const char *filename, moo_detector_type type)
Create a new moo_rbn_single with the given filename and type.
void moo_rbn_single_save(const moo_rbn_single *self, const char *filename, moo_detector_type type)
Save a moo_rbn_single to a FITS file.
cpl_propertylist * moo_rbn_single_get_header(moo_rbn_single *self)
Get header of rbn single.
moo_rbn_single * moo_rbn_single_new(moo_detector_type type)
Create a new moo_rbn_single.
void moo_rbn_single_delete(moo_rbn_single *self)
Delete a moo_rbn_single.
cpl_error_code moo_rbn_single_dump(const moo_rbn_single *self, FILE *stream)
Dump structural information of a Single DET.
cpl_error_code moo_rbn_single_load(moo_rbn_single *self, unsigned int level)
load the data of a moo_rbn_single
cpl_image * moo_rbn_single_get_data(moo_rbn_single *self)
Get image of data.
double moo_rbn_single_compute_snr(moo_rbn_single *self, int rbn_idx, moo_sky_lines_list *skylines)
Compute SNR for a given target.
cpl_error_code moo_rbn_single_free(moo_rbn_single *self)
Free memory associate to this single RBN.
cpl_error_code moo_rbn_single_set_wcs1(moo_rbn_single *self, double crpix1, double crval1, double cd1_1, const char *ctype1, const char *cunit1)
Set the WCS1 of the extension.
cpl_image * moo_rbn_single_get_qual(moo_rbn_single *self)
Get image of qual.
cpl_image * moo_rbn_single_get_errs(moo_rbn_single *self)
Get image of errs.
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