MOONS Pipeline Reference Manual 0.13.2
moo_ext.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 "moo_pfits.h"
31#include "moo_fits.h"
32#include "moo_badpix.h"
33#include "moo_qc.h"
34#include "moo_utils.h"
35#include "moo_ext.h"
36#include "moo_fibres_table.h"
37/*----------------------------------------------------------------------------*/
51/*----------------------------------------------------------------------------*/
52
55/*-----------------------------------------------------------------------------
56 Function codes
57 -----------------------------------------------------------------------------*/
58
59/*----------------------------------------------------------------------------*/
67/*----------------------------------------------------------------------------*/
68moo_ext *
70{
71 moo_ext *res = cpl_calloc(1, sizeof(moo_ext));
72 return res;
73}
74
75/*----------------------------------------------------------------------------*/
84/*----------------------------------------------------------------------------*/
85moo_ext *
86moo_ext_create(const cpl_frame *frame)
87{
88 cpl_ensure(frame != NULL, CPL_ERROR_NULL_INPUT, NULL);
89
90 cpl_errorstate prev_state = cpl_errorstate_get();
91 moo_ext *res = moo_ext_new();
92 const char *filename = cpl_frame_get_filename(frame);
93 res->filename = filename;
94 res->primary_header = cpl_propertylist_load(filename, 0);
95
96 res->ri[0] = moo_ext_single_create(filename, MOO_TYPE_RI, 1);
97 res->yj[0] = moo_ext_single_create(filename, MOO_TYPE_YJ, 1);
98 res->h[0] = moo_ext_single_create(filename, MOO_TYPE_H, 1);
99 res->ri[1] = moo_ext_single_create(filename, MOO_TYPE_RI, 2);
100 res->yj[1] = moo_ext_single_create(filename, MOO_TYPE_YJ, 2);
101 res->h[1] = moo_ext_single_create(filename, MOO_TYPE_H, 2);
102
103 if (!cpl_errorstate_is_equal(prev_state)) {
104 cpl_errorstate_set(prev_state);
105 cpl_msg_error("moo_ext", "Can't create EXT from file : %s", filename);
106 moo_ext_delete(res);
107 res = NULL;
108 }
109 return res;
110}
111
112/*----------------------------------------------------------------------------*/
124/*----------------------------------------------------------------------------*/
125cpl_error_code
126moo_ext_load(moo_ext *self, unsigned int level)
127{
128 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
129
130 for (int i = 0; i < 2; i++) {
131 moo_ext_single_load(self->ri[i], level);
132 moo_ext_single_load(self->yj[i], level);
133 moo_ext_single_load(self->h[i], level);
134 }
135
136 return CPL_ERROR_NONE;
137}
138/*----------------------------------------------------------------------------*/
154/*----------------------------------------------------------------------------*/
155moo_ext_single *
158 int num,
159 unsigned int level)
160{
161 moo_ext_single *res = NULL;
162
163 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
164 cpl_ensure(num >= 1 && num <= 2, CPL_ERROR_ILLEGAL_INPUT, NULL);
165
166 switch (type) {
167 case MOO_TYPE_RI:
168 moo_ext_single_load(self->ri[num - 1], level);
169 res = self->ri[num - 1];
170 break;
171 case MOO_TYPE_YJ:
172 moo_ext_single_load(self->yj[num - 1], level);
173 res = self->yj[num - 1];
174 break;
175 case MOO_TYPE_H:
176 moo_ext_single_load(self->h[num - 1], level);
177 res = self->h[num - 1];
178 break;
179 default:
180 res = NULL;
181 break;
182 }
183 return res;
184}
185/*----------------------------------------------------------------------------*/
197/*----------------------------------------------------------------------------*/
198moo_ext_single *
199moo_ext_get_single(moo_ext *self, moo_detector_type type, int ntas)
200{
201 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
202
203 switch (type) {
204 case MOO_TYPE_RI:
205 return self->ri[ntas - 1];
206 break;
207 case MOO_TYPE_YJ:
208 return self->yj[ntas - 1];
209 break;
210 case MOO_TYPE_H:
211 return self->h[ntas - 1];
212 break;
213 default:
214 return NULL;
215 }
216}
217/*----------------------------------------------------------------------------*/
229/*----------------------------------------------------------------------------*/
230cpl_error_code
231moo_ext_set_single(moo_ext *self,
233 int ntas,
234 moo_ext_single *single)
235{
236 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
237 cpl_ensure_code(ntas >= 1 && ntas <= 2, CPL_ERROR_ILLEGAL_INPUT);
238
239 cpl_error_code status = CPL_ERROR_NONE;
240 cpl_errorstate prev_state = cpl_errorstate_get();
241
242 switch (type) {
243 case MOO_TYPE_RI:
244 self->ri[ntas - 1] = single;
245 break;
246 case MOO_TYPE_YJ:
247 self->yj[ntas - 1] = single;
248 break;
249 case MOO_TYPE_H:
250 self->h[ntas - 1] = single;
251 break;
252 }
253 if (!cpl_errorstate_is_equal(prev_state)) {
254 cpl_msg_error("moo_ext", "Error for adding ext to %s (%d)",
255 self->filename, cpl_error_get_code());
256 status = cpl_error_get_code();
257 cpl_errorstate_set(prev_state);
258 }
259 return status;
260}
261
262/*----------------------------------------------------------------------------*/
274/*----------------------------------------------------------------------------*/
275cpl_error_code
276moo_ext_add_single(moo_ext *self,
277 moo_ext_single *single,
279 int ntas)
280{
281 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
282 cpl_ensure_code(self->filename != NULL, CPL_ERROR_NULL_INPUT);
283 cpl_error_code status = CPL_ERROR_NONE;
284 cpl_errorstate prev_state = cpl_errorstate_get();
285 moo_ext_set_single(self, type, ntas, single);
286 moo_ext_single_save(single, self->filename, type, ntas);
287 if (!cpl_errorstate_is_equal(prev_state)) {
288 const char *extname = moo_detector_get_extname(type, ntas);
289 cpl_msg_error("moo_ext", "Error for adding single to %s %s (%s)",
290 self->filename, extname,
291 cpl_error_get_message_default(cpl_error_get_code()));
292 status = cpl_error_get_code();
293 }
294 return status;
295}
296
297/*----------------------------------------------------------------------------*/
307/*----------------------------------------------------------------------------*/
308cpl_error_code
309moo_ext_add_fibre_table(moo_ext *self, cpl_table *fibre_table)
310{
311 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
312 cpl_ensure_code(self->filename != NULL, CPL_ERROR_NULL_INPUT);
313 cpl_ensure_code(fibre_table != NULL, CPL_ERROR_NULL_INPUT);
314
315 cpl_error_code status = CPL_ERROR_NONE;
316 cpl_errorstate prev_state = cpl_errorstate_get();
317 self->fibre_table = fibre_table;
318
319 cpl_propertylist *h = cpl_propertylist_new();
320 cpl_propertylist_append_string(h, MOO_PFITS_EXTNAME,
321 MOO_FIBRES_TABLE_EXTNAME);
322 cpl_table_save(self->fibre_table, h, h, self->filename, CPL_IO_EXTEND);
323 cpl_propertylist_delete(h);
324
325 if (!cpl_errorstate_is_equal(prev_state)) {
326 cpl_msg_error("moo_loc", "Error for adding fibre table to %s (%d)",
327 self->filename, cpl_error_get_code());
328 status = cpl_error_get_code();
329 cpl_errorstate_set(prev_state);
330 }
331 return status;
332}
333/*----------------------------------------------------------------------------*/
342/*----------------------------------------------------------------------------*/
343cpl_table *
345{
346 cpl_ensure(self != NULL, CPL_ERROR_NULL_INPUT, NULL);
347
348 if (self->fibre_table == NULL && self->filename != NULL) {
349 cpl_size qnum =
350 cpl_fits_find_extension(self->filename, MOO_FIBRES_TABLE_EXTNAME);
351 if (qnum > 0) {
352 self->fibre_table = cpl_table_load(self->filename, qnum, 0);
353 }
354 }
355 return self->fibre_table;
356}
357
358/*----------------------------------------------------------------------------*/
367/*----------------------------------------------------------------------------*/
368
369void
370moo_ext_delete(moo_ext *self)
371{
372 if (self != NULL) {
373 int i;
374 if (self->primary_header != NULL) {
375 cpl_propertylist_delete(self->primary_header);
376 }
377 for (i = 0; i < 2; i++) {
378 if (self->ri[i] != NULL) {
379 moo_ext_single_delete(self->ri[i]);
380 }
381 if (self->yj[i] != NULL) {
382 moo_ext_single_delete(self->yj[i]);
383 }
384 if (self->h[i] != NULL) {
385 moo_ext_single_delete(self->h[i]);
386 }
387 }
388 if (self->fibre_table != NULL) {
389 cpl_table_delete(self->fibre_table);
390 }
391 cpl_free(self);
392 }
393}
394/*----------------------------------------------------------------------------*/
404/*----------------------------------------------------------------------------*/
405void
406moo_ext_save(moo_ext *self, const char *filename)
407{
408 if (self != NULL) {
409 cpl_propertylist_save(self->primary_header, filename, CPL_IO_CREATE);
410 int i;
411 for (i = 0; i < 2; i++) {
412 moo_ext_single_save(self->ri[i], filename, MOO_TYPE_RI, i + 1);
413 moo_ext_single_save(self->yj[i], filename, MOO_TYPE_YJ, i + 1);
414 moo_ext_single_save(self->h[i], filename, MOO_TYPE_H, i + 1);
415 }
416
417 if (self->fibre_table != NULL) {
418 cpl_propertylist *h = cpl_propertylist_new();
419 cpl_propertylist_append_string(h, MOO_PFITS_EXTNAME,
420 MOO_FIBRES_TABLE_EXTNAME);
421 cpl_table_save(self->fibre_table, h, h, filename, CPL_IO_EXTEND);
422 cpl_propertylist_delete(h);
423 }
424 }
425}
426
427/*----------------------------------------------------------------------------*/
439/*----------------------------------------------------------------------------*/
440cpl_error_code
441moo_ext_dump(const moo_ext *self, FILE *stream)
442{
443 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
444 cpl_ensure_code(stream != NULL, CPL_ERROR_NULL_INPUT);
445
446 fprintf(stream, "---MOO_EXT\n");
447 fprintf(stream, "filename %s\n", self->filename);
448 int i;
449 for (i = 0; i < 2; i++) {
450 if (self->ri[i] != NULL) {
451 moo_ext_single_dump(self->ri[i], stream);
452 }
453 if (self->yj[i] != NULL) {
454 moo_ext_single_dump(self->yj[i], stream);
455 }
456 if (self->h[i] != NULL) {
457 moo_ext_single_dump(self->h[i], stream);
458 }
459 }
460 if (self->fibre_table) {
461 fprintf(stream, "fibre table %p\n", self->fibre_table);
462 }
463
464 return CPL_ERROR_NONE;
465}
466
467/*----------------------------------------------------------------------------*/
484/*----------------------------------------------------------------------------*/
485cpl_error_code
486moo_ext_free_single(moo_ext *self, moo_detector_type type, int num)
487{
488 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
489 cpl_ensure_code(num >= 1, CPL_ERROR_ILLEGAL_INPUT);
490 cpl_ensure_code(num <= 2, CPL_ERROR_ACCESS_OUT_OF_RANGE);
491
492 cpl_error_code status = CPL_ERROR_NONE;
493
494 moo_ext_single *single = moo_ext_get_single(self, type, num);
495 if (single != NULL) {
496 status = moo_ext_single_free(single);
497 }
498 return status;
499}
500
501/*----------------------------------------------------------------------------*/
512/*----------------------------------------------------------------------------*/
513cpl_error_code
514moo_ext_sum(moo_ext *self, moo_ext *ext)
515{
516 cpl_ensure_code(self != NULL, CPL_ERROR_ILLEGAL_INPUT);
517 cpl_ensure_code(ext != NULL, CPL_ERROR_ILLEGAL_INPUT);
518
519 int i;
520 for (i = 0; i < 2; i++) {
521 moo_ext_single *ri = self->ri[i];
522 moo_ext_single *extri = ext->ri[i];
523 if (ri != NULL) {
524 moo_ext_single_sum(ri, extri);
525 }
526 moo_ext_single *yj = self->yj[i];
527 if (yj != NULL) {
528 moo_ext_single *extyj = ext->yj[i];
529 moo_ext_single_sum(yj, extyj);
530 }
531 moo_ext_single *h = self->h[i];
532 if (h != NULL) {
533 moo_ext_single *exth = ext->h[i];
534 moo_ext_single_sum(h, exth);
535 }
536 }
537 return CPL_ERROR_NONE;
538}
539
540/*----------------------------------------------------------------------------*/
551/*----------------------------------------------------------------------------*/
552cpl_error_code
554 moo_map *wmap,
555 moo_spectral_format *sformat,
556 moo_sky_lines_list *skylines)
557{
558 cpl_ensure_code(self != NULL, CPL_ERROR_NULL_INPUT);
559 cpl_ensure_code(wmap != NULL, CPL_ERROR_NULL_INPUT);
560 cpl_ensure_code(skylines != NULL, CPL_ERROR_NULL_INPUT);
561
562 cpl_table *fibre_table = moo_ext_get_fibre_table(self);
563 moo_qc_set_snr_range(self->primary_header, MOONS_QC_SNR_RANGE_OHFREEZONE);
564 const char *snrs[] = { MOO_FIBRES_TABLE_MEDSNR_RI_EXT,
565 MOO_FIBRES_TABLE_MEDSNR_YJ_EXT,
566 MOO_FIBRES_TABLE_MEDSNR_H_EXT };
567
568 const char *dersnrs[] = { MOO_FIBRES_TABLE_DERSNR_RI_EXT,
569 MOO_FIBRES_TABLE_DERSNR_YJ_EXT,
570 MOO_FIBRES_TABLE_DERSNR_H_EXT };
571
572 int nrow = cpl_table_get_nrow(fibre_table);
573
574 for (int t = 0; t < nrow; t++) {
575 int indexext =
576 cpl_table_get_int(fibre_table, MOO_FIBRES_TABLE_INDEXEXT, t, NULL);
577 int health =
578 cpl_table_get_int(fibre_table, MOO_FIBRES_TABLE_HEALTH, t, NULL);
579 const int spectro =
580 cpl_table_get_int(fibre_table, MOO_FIBRES_TABLE_SPECTRO, t, NULL);
581 int num = 1;
582 if (spectro == MOO_FIBRES_TABLE_SPECTRO_2) {
583 num = 2;
584 }
585 if (health > 0) {
586 for (int i = 0; i < 3; i++) {
587 moo_ext_single *single =
589 moo_spectral_format_info *sinfo =
590 moo_spectral_format_get(sformat, i, num);
591 cpl_image *smap = wmap->data[i + (num - 1) * 3];
592 if (single != NULL) {
593 double snr = 0.0;
594 double der_snr = 0.0;
595 snr = moo_ext_single_compute_snr(single, indexext, smap,
596 sinfo, skylines, &der_snr);
597
598 moo_try_check(cpl_table_set_float(fibre_table, snrs[i], t,
599 snr),
600 " ");
601 moo_try_check(cpl_table_set_float(fibre_table, dersnrs[i],
602 t, der_snr),
603 " ");
604 }
606 sinfo = NULL;
607 }
608 }
609 }
610
611moo_try_cleanup:
612 return CPL_ERROR_NONE;
613}
#define MOO_BADPIX_GOOD
Definition: moo_badpix.h:36
cpl_error_code moo_ext_free_single(moo_ext *self, moo_detector_type type, int num)
Free the given type part in EXT.
Definition: moo_ext.c:486
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
double moo_ext_single_compute_snr(moo_ext_single *self, int ext_idx, cpl_image *wmap, moo_spectral_format_info *sinfo, moo_sky_lines_list *skylines, double *dersnr)
Compute SNR for a given target.
cpl_error_code moo_ext_single_load(moo_ext_single *self, unsigned int level)
load a moo_ext_single using the level for badpixel
cpl_error_code moo_ext_single_free(moo_ext_single *self)
Free memory associate to this single EXT.
void moo_ext_single_delete(moo_ext_single *self)
Delete a moo_ext_single.
moo_ext_single * moo_ext_single_create(const char *filename, moo_detector_type type, int ntas)
Create a new moo_ext_single from the given EXT filename.
void moo_ext_single_save(const moo_ext_single *self, const char *filename, moo_detector_type type, int ntas)
Save a moo_ext_single to a FITS file.
cpl_error_code moo_ext_single_dump(const moo_ext_single *self, FILE *stream)
Dump structural information of EXT_SINGLE.
cpl_error_code moo_ext_single_sum(moo_ext_single *a, moo_ext_single *b)
Add two single EXT.
moo_ext_single * moo_ext_get_single(moo_ext *self, moo_detector_type type, int ntas)
Get a EXT single from EXT.
Definition: moo_ext.c:199
moo_ext * moo_ext_new(void)
Create a new moo_ext.
Definition: moo_ext.c:69
cpl_error_code moo_ext_add_fibre_table(moo_ext *self, cpl_table *fibre_table)
Add fibre table to EXT filename and update moo_ext structure.
Definition: moo_ext.c:309
cpl_error_code moo_ext_set_single(moo_ext *self, moo_detector_type type, int ntas, moo_ext_single *single)
assign moo_ext_single structure in moo_ext structure
Definition: moo_ext.c:231
cpl_error_code moo_ext_add_single(moo_ext *self, moo_ext_single *single, moo_detector_type type, int ntas)
Add EXT_SINGLE extension to EXT filename and update moo_ext structure.
Definition: moo_ext.c:276
moo_ext_single * moo_ext_load_single(moo_ext *self, moo_detector_type type, int num, unsigned int level)
Load the type part in EXT and return it.
Definition: moo_ext.c:156
cpl_error_code moo_ext_load(moo_ext *self, unsigned int level)
Load all parts in EXT.
Definition: moo_ext.c:126
moo_ext * moo_ext_create(const cpl_frame *frame)
Create a new empty EXT filename.
Definition: moo_ext.c:86
cpl_error_code moo_ext_sum(moo_ext *self, moo_ext *ext)
Sum EXT structure.
Definition: moo_ext.c:514
cpl_table * moo_ext_get_fibre_table(moo_ext *self)
Get the FIBRE TABLE in EXT.
Definition: moo_ext.c:344
cpl_error_code moo_ext_dump(const moo_ext *self, FILE *stream)
Dump structural information of EXT.
Definition: moo_ext.c:441
void moo_ext_save(moo_ext *self, const char *filename)
Save a moo_ext to a FITS file.
Definition: moo_ext.c:406
void moo_ext_delete(moo_ext *self)
Delete a moo_ext.
Definition: moo_ext.c:370
cpl_error_code moo_ext_compute_snr(moo_ext *self, moo_map *wmap, moo_spectral_format *sformat, moo_sky_lines_list *skylines)
Compute SNR for all fibres EXT.
Definition: moo_ext.c:553
void moo_spectral_format_info_delete(moo_spectral_format_info *self)
Delete a moo_spectral_format_info.
moo_spectral_format_info * moo_spectral_format_get(moo_spectral_format *self, moo_detector_type type, int ntas)
Get the spectral format information for a given ARM.
cpl_error_code moo_qc_set_snr_range(cpl_propertylist *plist, const char *val)
Set the QC.SNR.RANGE value.
Definition: moo_qc.c:2238