GRAVI Pipeline Reference Manual 1.12.0
Loading...
Searching...
No Matches
gravi_data.c
Go to the documentation of this file.
1/* $Id: gravi_data_3.c, 2011/05/18 15:21:53 nazouaoui Exp $
2 *
3 * This file is part of the ESO Common Pipeline Library
4 * Copyright (C) 2001-2005 European Southern Observatory
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
34
35/*
36 * History :
37 * ekw 10/01/2019 Remove x in int gravi_data_get_dark_pos(cpl_table * detector_table, int reg, int x);
38 */
39/*-----------------------------------------------------------------------------
40 Includes
41 -----------------------------------------------------------------------------*/
42
43#include <cpl.h>
44#include <stdio.h>
45#include <string.h>
46#include <config.h>
47#include <ctype.h>
48#include <time.h>
49#include <math.h>
50#include <regex.h>
51
52#include "gravi_dfs.h"
53#include "gravi_data.h"
54#include "gravi_pfits.h"
55#include "gravi_utils.h"
56#include "gravi_cpl.h"
57
58/*-----------------------------------------------------------------------------
59 Defines
60 -----------------------------------------------------------------------------*/
61
62#define GRAVI_DATA_SIZE 30
63
65 cpl_propertylist * primary_hdr;
66 int nb_ext;
67 cpl_propertylist ** exts_hdrs;
68 cpl_imagelist ** exts_imgl;
69 cpl_table ** exts_tbs;
70 cpl_propertylist * extra_primary_hdr;
71};
72
73/* ----------------------------------------------------------------------------
74 Private prototypes
75 ---------------------------------------------------------------------------- */
76
77int gravi_data_is_oi_ext (cpl_propertylist * hdr);
78cpl_error_code gravi_data_check_savetypes(cpl_propertylist * hdr, cpl_table * oi_table);
79int gravi_data_get_dark_pos(cpl_table * detector_table, int reg);
80cpl_mask * gravi_data_create_bias_mask (cpl_table * detector_table, cpl_size nx, cpl_size ny);
81
82/* ----------------------------------------------------------------------------
83 Forward declarations
84 ---------------------------------------------------------------------------- */
85
86cpl_error_code gravi_remove_cosmicrays_sc (cpl_imagelist * imglist_sc);
87
88/*-----------------------------------------------------------------------------
89 Functions code
90 -----------------------------------------------------------------------------*/
91
92/*----------------------------------------------------------------------------*/
108/*----------------------------------------------------------------------------*/
109
111{
113 cpl_ensure (nb_ext==0, CPL_ERROR_ILLEGAL_INPUT, NULL);
114
115 gravi_data *self = cpl_malloc (sizeof (gravi_data));
116 self->primary_hdr = cpl_propertylist_new ();
117 self->extra_primary_hdr = cpl_propertylist_new ();
118 self->nb_ext = 0;
119
120 self->exts_hdrs = cpl_malloc (GRAVI_DATA_SIZE * sizeof(cpl_propertylist*));
121 self->exts_tbs = cpl_malloc (GRAVI_DATA_SIZE * sizeof(cpl_table*));
122 self->exts_imgl = cpl_malloc (GRAVI_DATA_SIZE * sizeof(cpl_imagelist*));
123
124 for(int i = 0; i < GRAVI_DATA_SIZE; i++){
125 self->exts_tbs[i] = NULL;
126 self->exts_hdrs[i] = NULL;
127 self->exts_imgl[i] = NULL;
128 }
129
131 return self;
132}
133
134/*----------------------------------------------------------------------------*/
144/*----------------------------------------------------------------------------*/
145
147{
149
150 if (self) {
151 /* Delete main header */
152 FREE (cpl_propertylist_delete, self->primary_hdr);
153 /* Delete data */
154 FREELOOP (cpl_propertylist_delete, self->exts_hdrs, GRAVI_DATA_SIZE);
155 FREELOOP (cpl_table_delete, self->exts_tbs, GRAVI_DATA_SIZE);
156 FREELOOP (cpl_imagelist_delete, self->exts_imgl, GRAVI_DATA_SIZE);
157 /* Delete computed header */
158 if(self->extra_primary_hdr != NULL)
159 FREE (cpl_propertylist_delete, self->extra_primary_hdr);
160 /* Delete structure */
161 FREE (cpl_free, self);
162 }
163
165 return;
166}
167
168/*----------------------------------------------------------------------------*/
172/*----------------------------------------------------------------------------*/
173
174int gravi_data_is_oi_ext (cpl_propertylist * hdr)
175{
176 if (hdr==NULL) { return 0; }
177 if (!cpl_propertylist_has (hdr, "EXTNAME")) { return 0; }
178 if (strncmp (gravi_pfits_get_extname (hdr), "OI_", 3)) { return 0; }
179 return 1;
180}
181
182/*----------------------------------------------------------------------------*/
196/*----------------------------------------------------------------------------*/
197
198cpl_error_code gravi_data_check_savetypes (cpl_propertylist * hdr, cpl_table * oi_table)
199{
200 cpl_ensure_code (hdr, CPL_ERROR_NULL_INPUT);
201 cpl_ensure_code (oi_table, CPL_ERROR_NULL_INPUT);
202
203 /* If not an OI_FITS table, nothing to do */
204 if (!gravi_data_is_oi_ext (hdr)) return CPL_ERROR_NONE;
205
206 if ( cpl_table_has_column (oi_table, "FLAG") ) {
207 cpl_table_set_column_savetype(oi_table, "FLAG", CPL_TYPE_BOOL);
208 }
209 if ( cpl_table_has_column (oi_table, "VISREFMAP") ) {
210 cpl_table_set_column_savetype(oi_table, "VISREFMAP", CPL_TYPE_BOOL);
211 }
212 if ( cpl_table_has_column (oi_table, "STA_INDEX") ) {
213 cpl_table_set_column_savetype(oi_table, "STA_INDEX", CPL_TYPE_SHORT);
214 }
215
216 if ( cpl_table_has_column (oi_table, "TARGET_ID") ) {
217 cpl_table_set_column_savetype(oi_table, "TARGET_ID", CPL_TYPE_SHORT);
218 }
219
220 if ( cpl_table_has_column (oi_table, "MNT_STA") ) {
221 cpl_table_set_column_savetype(oi_table, "MNT_STA", CPL_TYPE_SHORT);
222 }
223
224 /* Check errors */
225 if ( cpl_error_get_code() != CPL_ERROR_NONE ) {
226 cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
227 "Cannot reinstall the savetypes");
228 return cpl_error_get_code();
229 }
230
231 return CPL_ERROR_NONE;
232}
233
234/*----------------------------------------------------------------------------*/
248/*----------------------------------------------------------------------------*/
249
251{
253 cpl_ensure (self, CPL_ERROR_NULL_INPUT, NULL);
254
255 gravi_data * copy = gravi_data_new(0);
256 copy->nb_ext = self->nb_ext;
257
258 if (self->primary_hdr) {
259 cpl_propertylist_delete (copy->primary_hdr);
260 copy->primary_hdr = cpl_propertylist_duplicate(self->primary_hdr);
261 } else {
262 cpl_msg_warning (cpl_func,"a data without header shall not exist");
263 }
264
265 CPLCHECK_NUL ("Cannot duplicate header");
266
267 for (int i = 0; i < copy->nb_ext ; i++){
268 if (self->exts_hdrs[i])
269 copy->exts_hdrs[i] = cpl_propertylist_duplicate(self->exts_hdrs[i]);
270 if (self->exts_tbs[i]) {
271 copy->exts_tbs[i] = cpl_table_duplicate(self->exts_tbs[i]);
272 gravi_data_check_savetypes (copy->exts_hdrs[i], copy->exts_tbs[i]);
273 }
274 if (self->exts_imgl[i])
275 copy->exts_imgl[i] = cpl_imagelist_duplicate(self->exts_imgl[i]);
276
277 CPLCHECK_NUL ("Cannot duplicate extension");
278 }
279
280 if (self->extra_primary_hdr) {
281 cpl_propertylist_delete (copy->extra_primary_hdr);
282 copy->extra_primary_hdr = cpl_propertylist_duplicate(self->extra_primary_hdr);
283 }
285 return copy;
286}
287
288
289/*----------------------------------------------------------------------------*/
306/*----------------------------------------------------------------------------*/
307
308cpl_error_code gravi_data_append (gravi_data * first, const gravi_data * second, int force)
309{
311 cpl_ensure_code (first, CPL_ERROR_NULL_INPUT);
312 cpl_ensure_code (second, CPL_ERROR_NULL_INPUT);
313 cpl_ensure_code (first->nb_ext > 1, CPL_ERROR_INCOMPATIBLE_INPUT);
314 cpl_ensure_code (second->nb_ext > 1, CPL_ERROR_INCOMPATIBLE_INPUT);
315
316 cpl_msg_warning (cpl_func, "Append data: keep only the HEADER of the first data");
317 cpl_msg_warning (cpl_func, "Append data: FIXME: only works for OIFITS data");
318
319 cpl_size nb_ext = CPL_MIN(first->nb_ext, second->nb_ext);
320 for (int i = 0; i < nb_ext ; i++) {
321
322 /* Check EXTNAME */
323 const char * name1 = gravi_pfits_get_extname (first->exts_hdrs[i]);
324 const char * name2 = gravi_pfits_get_extname (second->exts_hdrs[i]);
325 cpl_ensure_code (!strcmp (name1, name2), CPL_ERROR_INCOMPATIBLE_INPUT);
326
327 /* These tables shall not be merged, but shall be equal */
328 if ( !strcmp (name1,"OI_WAVELENGTH") ||
329 !strcmp (name1, "OI_TARGET") ||
330 !strcmp (name1, "OI_ARRAY") ||
331 !strcmp (name1, "IMAGING_DETECTOR_SC") ||
332 !strcmp (name1, "IMAGING_DETECTOR_FT") ||
333 !strcmp (name1, "ARRAY_DESCRIPTION") ||
334 !strcmp (name1, "ARRAY_GEOMETRY") ||
335 !strcmp (name1, "OPTICAL_TRAIN") ) {
336 if (force) {
337 cpl_msg_info (cpl_func,"Don't check table %s", name1);
338 continue;
339 }
340
341 cpl_msg_info (cpl_func,"Check table %s", name1);
342 if ( !gravi_table_are_equal (first->exts_tbs[i], second->exts_tbs[i]) ) {
343 cpl_error_set_message (cpl_func, CPL_ERROR_ILLEGAL_INPUT, "Tables %s are different", name1);
344 return 0;
345 }
346 continue;
347 }
348
349 /* Append as table */
350 if ( first->exts_tbs[i] != NULL ) {
351 cpl_msg_info (cpl_func,"Merge table %s", name1);
352 cpl_table_insert (first->exts_tbs[i], second->exts_tbs[i], CPL_SIZE_MAX);
353
354 CPLCHECK_MSG ("Cannot append table");
355 continue;
356 }
357
358 /* Append as imagelist (duplicate each image) */
359 if ( first->exts_imgl[i] != NULL ) {
360 cpl_msg_info (cpl_func,"Merge imglist %s", name1);
361 cpl_size n_first = cpl_imagelist_get_size (first->exts_imgl[i]);
362 cpl_size n_second = cpl_imagelist_get_size (second->exts_imgl[i]);
363 CPLCHECK_MSG ("Cannot get the size of imglist");
364
365 for (cpl_size iimg = 0; iimg < n_second; iimg++) {
366 cpl_image * img = cpl_image_duplicate (cpl_imagelist_get (second->exts_imgl[i], iimg));
367 cpl_imagelist_set (first->exts_imgl[i], img, n_first + iimg);
368 }
369
370 CPLCHECK_MSG ("Cannot append imglist");
371 continue;
372 }
373
374 CPLCHECK_MSG ("Cannot append data");
375 }
376
377 /* Copy remaining extension second -> first */
378 for (int i = nb_ext; i < second->nb_ext; i++)
379 {
380 gravi_data_copy_ext_i (first, (gravi_data *)second, i);
381 }
382
384 return CPL_ERROR_NONE;
385}
386
387/*----------------------------------------------------------------------------*/
400/*----------------------------------------------------------------------------*/
401
402gravi_data * gravi_data_load (const char * filename)
403{
405 cpl_ensure (filename, CPL_ERROR_NULL_INPUT, NULL);
406
407 cpl_msg_debug (cpl_func, "Load file : %s", filename);
408
409 /* Find a number of extension on the FITS file */
410 int nb_ext = cpl_fits_count_extensions (filename);
411 if (nb_ext == -1){
412 cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT, "no extension in this file");
413 return NULL;
414 }
415
416 /* Create data */
417 gravi_data * self = gravi_data_new (0);
418
419 /* Load primary header */
420 cpl_propertylist * header = cpl_propertylist_load (filename, 0);
421 cpl_propertylist_append (self->primary_hdr, header);
422 FREE (cpl_propertylist_delete, header);
423
424 /* Loop on extensions */
425 for (int i = 0; i < nb_ext ; i++ ){
426
427 /* Load header of this extension */
428 self->exts_hdrs[i] = cpl_propertylist_load (filename, i+1);
429 CPLCHECK_NUL ("Cannot load header");
430
431 /* Load extension as table */
432 if (gravi_pfits_get_extension_type (self->exts_hdrs[i]) == 2) {
433 self->exts_tbs[i] = cpl_table_load (filename, i+1, 0);
434 gravi_data_check_savetypes (self->exts_hdrs[i], self->exts_tbs[i]);
435 CPLCHECK_NUL ("Cannot load bintable");
436 }
437 /* Load extension as imagelist */
438 else if (gravi_pfits_get_extension_type (self->exts_hdrs[i]) == 3) {
439 self->exts_imgl[i] = cpl_imagelist_load (filename,CPL_TYPE_DOUBLE,i+1);
440 CPLCHECK_NUL ("Cannot load imagelist");
441 }
442 /* error */
443 else {
444 cpl_error_set_message (cpl_func, CPL_ERROR_ILLEGAL_INPUT, "The dimension of the extension is wrong");
445 gravi_data_delete (self);
446 return NULL;
447 }
448
449 self->nb_ext ++;
450 }
451
453 return self;
454}
455
456/*----------------------------------------------------------------------------*/
473/*----------------------------------------------------------------------------*/
474gravi_data * gravi_data_load_ext(const char * filename,
475 const char * extensions_regexp)
476{
478 cpl_ensure (filename, CPL_ERROR_NULL_INPUT, NULL);
479
480 cpl_msg_debug (cpl_func, "Load file : %s", filename);
481
482 /* Find a number of extension on the FITS file */
483 int nb_ext = cpl_fits_count_extensions (filename);
484 if (nb_ext == -1){
485 cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT, "no extension in this file");
486 return NULL;
487 }
488
489 /* Create data */
490 gravi_data * self = gravi_data_new (0);
491
492 /* Load primary header */
493 cpl_propertylist * header = cpl_propertylist_load (filename, 0);
494 cpl_propertylist_append (self->primary_hdr, header);
495 FREE (cpl_propertylist_delete, header);
496
497 //Compile regular expression
498 regex_t filter;
499 int status = regcomp(&filter, extensions_regexp, REG_EXTENDED | REG_NOSUB);
500 if(status) {
501 cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
502 "Cannot interpret extension regular expression");
503 return NULL;
504 }
505
506 /* Loop on extensions */
507 int iext = 0;
508 for (int i = 0; i < nb_ext ; i++ ){
509
510 //Read the extension header
511 cpl_propertylist *proplist = cpl_propertylist_load (filename, i+1);
512 const char *extname = cpl_propertylist_get_string (proplist, "EXTNAME");
513 CPLCHECK_NUL ("Cannot load header");
514
515 //Check whether it is one of the required extensions
516 if (regexec(&filter, extname, 0, NULL, 0) == REG_NOMATCH)
517 {
518 cpl_propertylist_delete(proplist);
519 continue;
520 }
521 /* Load header of this extension */
522 self->exts_hdrs[iext] = proplist;
523
524 /* Load extension as table */
525 if (gravi_pfits_get_extension_type (self->exts_hdrs[iext]) == 2) {
526 self->exts_tbs[iext] = cpl_table_load (filename, i+1, 0);
527 gravi_data_check_savetypes (self->exts_hdrs[iext], self->exts_tbs[iext]);
528 CPLCHECK_NUL ("Cannot load bintable");
529 }
530 /* Load extension as imagelist */
531 else if (gravi_pfits_get_extension_type (self->exts_hdrs[iext]) == 3) {
532 self->exts_imgl[iext] = cpl_imagelist_load (filename,CPL_TYPE_DOUBLE,i+1);
533 CPLCHECK_NUL ("Cannot load imagelist");
534 }
535 /* error */
536 else {
537 cpl_error_set_message (cpl_func, CPL_ERROR_ILLEGAL_INPUT, "The dimension of the extension is wrong");
538 gravi_data_delete (self);
539 regfree(&filter);
540 return NULL;
541 }
542
543 self->nb_ext ++;
544 iext++;
545 }
546
547 regfree(&filter);
549 return self;
550}
551
552/*----------------------------------------------------------------------------*/
563/*----------------------------------------------------------------------------*/
564
565cpl_error_code gravi_data_dump_mode (gravi_data * data)
566{
567 cpl_ensure_code (data, CPL_ERROR_NULL_INPUT);
568 cpl_errorstate prestate = cpl_errorstate_get();
569
570 /* Dump minimum info */
571 cpl_propertylist * header = gravi_data_get_header (data);
572 const char * res = gravi_pfits_get_spec_res (header);
573 const char * scpol = gravi_pfits_get_pola_mode (header, GRAVI_SC);
574 const char * ftpol = gravi_pfits_get_pola_mode (header, GRAVI_FT);
575
576 if (cpl_errorstate_is_equal(prestate)) {
577 cpl_msg_info (cpl_func, "(insmode: %s %s %s)", res, scpol, ftpol);
578 } else {
579 cpl_errorstate_set (prestate);
580 }
581
582 return CPL_ERROR_NONE;
583}
584
585/*----------------------------------------------------------------------------*/
597/*----------------------------------------------------------------------------*/
598
600 cpl_frameset * used_frameset)
601{
602 cpl_ensure (frame, CPL_ERROR_NULL_INPUT, NULL);
603
604 const char * filename = cpl_frame_get_filename (frame);
605
606 cpl_msg_info (cpl_func, "Load file %s (%s)", FILESHORT(filename), cpl_frame_get_tag (frame));
607
608 if (used_frameset) cpl_frameset_insert (used_frameset, cpl_frame_duplicate (frame));
609
610 /* Load data */
611 gravi_data * data = gravi_data_load (filename);
612 CPLCHECK_NUL ("Cannot load data");
613
614 /* Dump minimum info */
616
617 return data;
618}
619
620/*----------------------------------------------------------------------------*/
633/*----------------------------------------------------------------------------*/
634
635int gravi_data_patch (gravi_data * file_to_patch,
636 cpl_frameset * patch_frameset)
637{
638 cpl_ensure (file_to_patch, CPL_ERROR_NULL_INPUT, 0);
639
640 cpl_frame * patch_frame = NULL;
641
642 if ( !cpl_frameset_is_empty (patch_frameset) )
643 patch_frame = cpl_frameset_get_position(patch_frameset, 0);
644
645 if (patch_frame) {
646 const char * filename = cpl_frame_get_filename (patch_frame);
647 CPLCHECK_INT("Cannot get finelame");
648 cpl_msg_info (cpl_func, "Patch the input file with %s", FILESHORT(filename));
649 cpl_propertylist * plist_patch = cpl_propertylist_load (filename, 0);
650 CPLCHECK_INT("Cannot load patch");
651 cpl_propertylist * plist_file_to_patch = gravi_data_get_plist_x(file_to_patch, 0);
652 CPLCHECK_INT("Cannot load data");
653
654 for (int i=0; i<cpl_propertylist_get_size(plist_patch); i++){
655 cpl_property * keyword = cpl_propertylist_get(plist_patch, i);
656 cpl_type type = cpl_property_get_type(keyword);
657 const char * p_name = cpl_property_get_name (keyword);
658 if ( (strstr(p_name, " QC ") != NULL) ||
659 (strstr(p_name, " TPL ") != NULL) ||
660 (strstr(p_name, " OCS ") != NULL) ||
661 (strstr(p_name, " OBS ") != NULL) ||
662 (strstr(p_name, " MET ") != NULL) ||
663 (strstr(p_name, " ISS ") != NULL) ||
664 (strstr(p_name, " INS ") != NULL) ||
665 (strstr(p_name, " FT ") != NULL) ||
666 (strstr(p_name, " FDDL ") != NULL) ||
667 (strstr(p_name, " ACQ ") != NULL) ) {
668 cpl_msg_info (cpl_func, "Patch the keyword %s", p_name);
669 switch (type) {
670 case CPL_TYPE_FLOAT :
671 cpl_propertylist_update_float(plist_file_to_patch, p_name, cpl_property_get_float(keyword));
672 break;
673 case CPL_TYPE_DOUBLE :
674 cpl_propertylist_update_double(plist_file_to_patch, p_name, cpl_property_get_double(keyword));
675 break;
676 case CPL_TYPE_INT :
677 cpl_propertylist_update_int(plist_file_to_patch, p_name, cpl_property_get_int(keyword));
678 break;
679 case CPL_TYPE_STRING :
680 cpl_propertylist_update_string(plist_file_to_patch, p_name, cpl_property_get_string(keyword));
681 break;
682 case CPL_TYPE_CHAR :
683 cpl_propertylist_update_char(plist_file_to_patch, p_name, cpl_property_get_char(keyword));
684 break;
685 case CPL_TYPE_BOOL :
686 cpl_propertylist_update_bool(plist_file_to_patch, p_name, cpl_property_get_bool(keyword));
687 break;
688 default :
689 cpl_msg_error (cpl_func,"'%s' is an invalid type of property",p_name);
690 cpl_error_set_message(cpl_func, CPL_ERROR_INVALID_TYPE,
691 "invalid type of property");
692 return 0;
693 }
694 }
695 }
696 FREE (cpl_propertylist_delete, plist_patch);
697 }
698return 1;
699}
700
701/*----------------------------------------------------------------------------*/
714/*----------------------------------------------------------------------------*/
715
717 cpl_frameset * used_frameset)
718{
719 cpl_ensure (frame, CPL_ERROR_NULL_INPUT, NULL);
720
721 const char * filename = cpl_frame_get_filename (frame);
722 cpl_msg_info (cpl_func, "Load RAW file %s (%s)", FILESHORT(filename), cpl_frame_get_tag (frame));
723
724 if (used_frameset) cpl_frameset_insert (used_frameset, cpl_frame_duplicate (frame));
725
726 /* Load data */
727 gravi_data * data = gravi_data_load (filename);
728 CPLCHECK_NUL ("Cannot load data");
729
730 /* Dump minimum info */
732
733 /* Check consistency */
735 CPLCHECK_NUL ("Cannot check data consistency");
736
737 /* Delete unused data so far */
738 // gravi_data_erase (data, GRAVI_IMAGING_DATA_ACQ_EXT);
739 // gravi_data_erase (data, "ACQ_ABS_REF_POSITION");
740 // CPLCHECK_NUL ("Cannot erase useless data");
741
742 return data;
743}
744
745/*----------------------------------------------------------------------------*/
759/*----------------------------------------------------------------------------*/
761 cpl_frameset * used_frameset,
762 const char * extensions_regexp)
763{
764 cpl_ensure (frame, CPL_ERROR_NULL_INPUT, NULL);
765
766 const char * filename = cpl_frame_get_filename (frame);
767 cpl_msg_info (cpl_func, "Load RAW file %s (%s)", FILESHORT(filename), cpl_frame_get_tag (frame));
768
769 if (used_frameset) cpl_frameset_insert (used_frameset, cpl_frame_duplicate (frame));
770
771 /* Load data */
772 gravi_data * data = gravi_data_load_ext(filename, extensions_regexp);
773 CPLCHECK_NUL ("Cannot load data");
774
775 /* Dump minimum info */
777
778 /* Check consistency */
779 //TODO: If not all extensions are loaded the consistency cannot be checked
780 //gravi_data_check_consistency (data);
781 CPLCHECK_NUL ("Cannot check data consistency");
782
783 return data;
784}
785
786/*----------------------------------------------------------------------------*/
794/*----------------------------------------------------------------------------*/
795
796cpl_error_code gravi_data_dump (gravi_data *self)
797{
798 cpl_ensure_code (self, CPL_ERROR_NULL_INPUT);
799
800 cpl_msg_info (cpl_func,"-------------------------");
801 cpl_msg_info (cpl_func,"POINTER: %p", self);
802 cpl_msg_info (cpl_func,"HEADER: %p", self->primary_hdr);
803 cpl_msg_info (cpl_func,"nb_ext = %i",self->nb_ext);
804
805 for (int i=0; i<self->nb_ext; i++){
806 cpl_msg_info (cpl_func,"%i: %s - %p %p %p", i,
807 gravi_pfits_get_extname (self->exts_hdrs[i]),
808 self->exts_hdrs[i],
809 self->exts_tbs[i],
810 self->exts_imgl[i]);
811 }
812 cpl_msg_info (cpl_func,"-------------------------");
813
814 return CPL_ERROR_NONE;
815}
816
817/*----------------------------------------------------------------------------*/
826/*----------------------------------------------------------------------------*/
827
829{
830 cpl_ensure (self, CPL_ERROR_ILLEGAL_INPUT, 0L);
831 return (int)self->nb_ext;
832}
833
834
835/*----------------------------------------------------------------------------*/
854/*----------------------------------------------------------------------------*/
855
856cpl_error_code gravi_data_save_data(gravi_data * self,
857 const char * filename,
858 unsigned mode)
859{
860 cpl_ensure_code (self, CPL_ERROR_NULL_INPUT);
861 cpl_ensure_code (filename, CPL_ERROR_NULL_INPUT);
862
863 cpl_propertylist *prim_hdr = cpl_propertylist_duplicate(self->primary_hdr);
864 if(self->extra_primary_hdr != NULL)
865 cpl_propertylist_append(prim_hdr, self->extra_primary_hdr);
866 /* Create the file and save the first property list and table field with
867 * primary header entries. */
868 if (self->exts_tbs[0] != NULL)
869 cpl_table_save(self->exts_tbs[0], prim_hdr,
870 self->exts_hdrs[0], filename, mode);
871 else if (self->exts_imgl[0] != NULL){
872 cpl_propertylist_save (prim_hdr, filename, mode);
873 cpl_imagelist_save (self->exts_imgl[0], filename,
874 CPL_TYPE_DOUBLE, self->exts_hdrs[0], CPL_IO_EXTEND);
875 }
876 else {
877 cpl_error_set_message(cpl_func, CPL_ERROR_NULL_INPUT,
878 "one of the inputs at least is NULL");
879 return CPL_ERROR_NULL_INPUT;
880 }
881
882
883 /* Save the remainging extension */
884 for (int i = 1; i < self->nb_ext; i++){
885
886 if (gravi_pfits_get_extension_type (self->exts_hdrs[i]) == 2)
887 cpl_table_save(self->exts_tbs[i], NULL,
888 self->exts_hdrs[i], filename, CPL_IO_EXTEND);
889 else if (gravi_pfits_get_extension_type (self->exts_hdrs[i]) == 3)
890 cpl_imagelist_save (self->exts_imgl[i], filename,
891 CPL_TYPE_DOUBLE, self->exts_hdrs[i], CPL_IO_EXTEND);
892 else {
893 cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
894 "The dimension of the extension is wrong");
895 gravi_data_delete(self);
896 return CPL_ERROR_ILLEGAL_INPUT;
897 }
898 }
899
900 return CPL_ERROR_NONE;
901}
902
903/*----------------------------------------------------------------------------*/
923/*----------------------------------------------------------------------------*/
924
925cpl_error_code gravi_data_save_new (gravi_data * self,
926 cpl_frameset * allframes,
927 const char * filename,
928 const char * suffix,
929 const cpl_parameterlist * parlist,
930 cpl_frameset * usedframes,
931 cpl_frame * frame,
932 const char * recipe,
933 cpl_propertylist * applist,
934 const char * proCatg)
935{
937 cpl_ensure_code (filename || frame, CPL_ERROR_NULL_INPUT);
938 cpl_ensure_code (self, CPL_ERROR_NULL_INPUT);
939 cpl_ensure_code (proCatg, CPL_ERROR_NULL_INPUT);
940
941 cpl_frameset * frameset;
942 int ext, i = 0, j = 0;
943
944 /* If the optional propertylist is not given, we simply
945 * extract the QC parameters from the saved product. */
946 if (applist == NULL) {
947 /* FIXME: Computed keywords might be either QC params in
948 the main header or keywords in extra_primary_hdr. In the future
949 only the later should be used */
950 applist = gravi_data_get_qc (self);
951 if(self->extra_primary_hdr != NULL)
952 cpl_propertylist_append(applist, self->extra_primary_hdr);
953 CPLCHECK_MSG ("Cannot get QC parameters");
954 } else {
955 applist = cpl_propertylist_duplicate (applist);
956 }
957
958 /* Add the product CATG to the header */
959 cpl_propertylist_append_string (applist, CPL_DFS_PRO_CATG, proCatg);
960 CPLCHECK_MSG ("Cannot add the CATG parameter");
961
962 /* Copy the DATE-OBS and NIGHT-OBS parameters if present */
963 cpl_propertylist * hdr = gravi_data_get_header (self);
964 if ( cpl_propertylist_has (hdr, GRAVI_NIGHT_OBS) ) {
965 cpl_propertylist_copy_property (applist, hdr, GRAVI_NIGHT_OBS);
966 CPLCHECK_MSG ("Cannot set NIGHT_OBS");
967 }
968 if ( cpl_propertylist_has (hdr, "DATE-OBS") ) {
969 cpl_propertylist_copy_property (applist, hdr, "DATE-OBS");
970 CPLCHECK_MSG ("Cannot set DATE-OBS");
971 }
972
973 /* Create keywords for OIFITS compliance if VIS product */
974 if (strstr (proCatg,"VIS") || strstr (proCatg,"TF")) {
975 cpl_propertylist * tmp = gravi_plist_get_oifits_keywords (hdr);
976 cpl_propertylist_append (applist, tmp);
977 FREE (cpl_propertylist_delete, tmp);
978 }
979
980 /* Add the PIPE LAST_BUILD keyword */
982
983 /* Select the name extension depending on this catg */
984 char catg_ext[800];
985 for(i = 0; proCatg[i]; i++) if (proCatg[i]!='_') { catg_ext[j] = tolower(proCatg[i]); j++; }
986 catg_ext[j] = '\0';
987
988
989 /* If filename is NULL */
990 if (filename == NULL && frame != NULL) {
991 filename = cpl_frame_get_filename (frame);
992 } else if (filename == NULL && frame == NULL) {
993 cpl_error_set_message(cpl_func, CPL_ERROR_NULL_INPUT, "Need a frame if filename is void");
994 return CPL_ERROR_NULL_INPUT;
995 }
996
997 /* Use either the input filename or a name based on recipe */
998 char * product_name = NULL;
999
1000 if ( cpl_parameterlist_find_const (parlist,"gravity.dfs.static-name") &&
1001 gravi_param_get_bool (parlist,"gravity.dfs.static-name")) {
1002
1003 /* Use the recipe name and add the selected catg_ext */
1004 if(suffix != NULL)
1005 product_name = cpl_sprintf ("%s_%s_%s.fits", recipe, catg_ext, suffix);
1006 else
1007 product_name = cpl_sprintf ("%s_%s.fits", recipe, catg_ext);
1008 }
1009 else {
1010
1011 /* Remove the extension (last '.') and add the selected catg_ext */
1012 char * filenoext = cpl_strdup (FILESHORT(filename));
1013 char * lastdot = strrchr (filenoext, '.');
1014 if (lastdot != NULL) *lastdot = '\0';
1015 product_name = cpl_sprintf ("%s_%s.fits", filenoext, catg_ext);
1016 FREE (cpl_free, filenoext);
1017 }
1018
1019 cpl_msg_info (cpl_func, "Save file to %s", product_name);
1020
1021 if (usedframes && frame==NULL) {
1022 /* frameset is only the usedframes */
1023 frameset = cpl_frameset_duplicate (usedframes);
1024 }
1025 else if (usedframes && frame) {
1026 /* frameset is the usedframes, and
1027 * frame is ensured to be the first */
1028 frameset = cpl_frameset_new ();
1029 cpl_frameset_insert (frameset, cpl_frame_duplicate (frame));
1030 for (int f = 0; f < cpl_frameset_get_size (usedframes); f++)
1031 if (strcmp (cpl_frame_get_filename (cpl_frameset_get_position (usedframes, f)), cpl_frame_get_filename (frame)))
1032 cpl_frameset_insert (frameset, cpl_frame_duplicate (cpl_frameset_get_position (usedframes, f)));
1033 }
1034 else if (usedframes==NULL && frame) {
1035 /* frameset is only the frame */
1036 frameset = cpl_frameset_new ();
1037 cpl_frameset_insert (frameset, cpl_frame_duplicate (frame));
1038 }
1039 else {
1040 /* This shall not happen */
1041 cpl_error_set_message(cpl_func, CPL_ERROR_NULL_INPUT, "Bug: need a frame or a usedframes");
1042 return CPL_ERROR_NULL_INPUT;
1043 }
1044
1045 /* add a diagnostic for invalid header values which cannot be saved, to tell which card was the problem */
1046 for (int i = 0; i < cpl_propertylist_get_size(applist); i++) {
1047 cpl_property *p = cpl_propertylist_get(applist, i);
1048 if (cpl_property_get_type(p) == CPL_TYPE_FLOAT) {
1049 const char *name = cpl_property_get_name(p);
1050 const float value = cpl_property_get_float(p);
1051 if (!isfinite(value)) {
1052 cpl_msg_error(cpl_func, "Card %s has invalid value %f", name, value);
1053 }
1054 } else if(cpl_property_get_type(p) == CPL_TYPE_DOUBLE) {
1055 const char *name = cpl_property_get_name(p);
1056 const double value = cpl_property_get_double(p);
1057 if (!isfinite(value)) {
1058 cpl_msg_error(cpl_func, "Card %s has invalid value %f", name, value);
1059 }
1060 }
1061 }
1062
1063 /* Save the primary header */
1064 cpl_dfs_save_propertylist (allframes, NULL, parlist,
1065 frameset, frame, recipe, applist,
1066 NULL, PACKAGE "/" PACKAGE_VERSION, product_name);
1067 CPLCHECK_MSG("Cannot save the first extension primary header");
1068
1069 /* Save the extensions */
1070 for (ext = 0; ext < self->nb_ext; ext ++)
1071 {
1072 if (self->exts_tbs[ext] != NULL)
1073 cpl_table_save (self->exts_tbs[ext], NULL,
1074 self->exts_hdrs[ext], product_name, CPL_IO_EXTEND);
1075 else if (self->exts_imgl[ext] != NULL)
1076 cpl_imagelist_save (self->exts_imgl[ext], product_name,
1077 cpl_image_get_type (cpl_imagelist_get (self->exts_imgl[ext], 0)),
1078 self->exts_hdrs[ext], CPL_IO_EXTEND);
1079 CPLCHECK_MSG("Cannot save the extension");
1080 }
1081
1082 FREE (cpl_frameset_delete, frameset);
1083 FREE (cpl_free, product_name);
1084 FREE (cpl_propertylist_delete, applist);
1085
1087 return CPL_ERROR_NONE;
1088}
1089
1090/*----------------------------------------------------------------------------*/
1101/*----------------------------------------------------------------------------*/
1102int gravi_data_get_dark_pos(cpl_table * detector_table, int reg)
1103{
1104 cpl_ensure_code (detector_table, CPL_ERROR_NULL_INPUT);
1105
1106 /* TODO, FIXME must use the new LEFT HALFLEFT
1107 * RIGHT HALFRIGHT column to interpolate the position */
1108 // int ref0_x = gravi_table_get_value (detector_table, "CENTER", reg, 0);
1109 int ref0_y = gravi_table_get_value (detector_table, "CENTER", reg, 1);
1110 int ref1_y = gravi_table_get_value (detector_table, "CENTER", reg+1, 1);
1111
1112 return (ref0_y+ref1_y)/2;
1113}
1114
1115/*----------------------------------------------------------------------------*/
1129/*----------------------------------------------------------------------------*/
1130
1131cpl_mask * gravi_data_create_bias_mask (cpl_table * detector_table,
1132 cpl_size nx, cpl_size ny)
1133{
1135 cpl_ensure (detector_table, CPL_ERROR_NULL_INPUT, NULL);
1136 cpl_ensure (nx > 2, CPL_ERROR_ILLEGAL_INPUT, NULL);
1137 cpl_ensure (ny > 2, CPL_ERROR_ILLEGAL_INPUT, NULL);
1138
1139 /* Get size */
1140 cpl_size nreg = cpl_table_get_nrow (detector_table);
1141 cpl_ensure (nreg == 24 || nreg == 48, CPL_ERROR_ILLEGAL_INPUT, NULL);
1142
1143 /* Define the mask with 0 everywhere */
1144 cpl_mask * mask = cpl_mask_new (nx, ny);
1145
1146 cpl_msg_info (cpl_func, "Create mask with size nx = %lli, ny = %lli", nx, ny);
1147
1148 /* In LOW and MEDIUM, we impose spectrum are horizontal.
1149 In HIGH, we allow for 0,1,2 order and enlarge the window */
1150 cpl_size mindeg = 0, maxdeg, hw;
1151 if (nx < 150) {maxdeg = 0; hw = 4;}
1152 else if (nx < 400) {maxdeg = 0; hw = 4;}
1153 else {maxdeg = 2; hw = 6;}
1154
1155 /* Names of columns */
1156 int nnames = 5;
1157 const char * names[] = {"LEFT","HALFLEFT","CENTER","HALFRIGHT","RIGHT"};
1158
1159 /* Check if these names exist */
1160 for (int n = 0; n < nnames; n++) {
1161
1162 if (cpl_table_has_column (detector_table, names[n]) == 0) {
1163 CPLCHECK_NUL ("Missing LEFT,HALFLEFT,CENTER,HALFRIGHT,RIGHT "
1164 "column in detector table (old data?), use another bias-method");
1165 }
1166 }
1167
1168 /* Prepare to fit the position from table */
1169 cpl_polynomial * fit = cpl_polynomial_new (1);
1170 cpl_matrix * xp = cpl_matrix_new (1,nnames);
1171 cpl_vector * yp = cpl_vector_new (nnames);
1172
1173 /* Loop on regions */
1174 for (cpl_size reg = 0; reg < nreg; reg++) {
1175
1176 /* Fill data for fit of the position from table */
1177 for (int n = 0; n < nnames; n++) {
1178 int x0 = gravi_table_get_value (detector_table, names[n], reg, 0) - 1;
1179 int y0 = gravi_table_get_value (detector_table, names[n], reg, 1) - 1;
1180 cpl_matrix_set (xp, 0, n, x0);
1181 cpl_vector_set (yp, n, y0);
1182 CPLCHECK_NUL ("Cannot get position from table");
1183 }
1184
1185 /* Solve polynomial */
1186 cpl_polynomial_fit (fit, xp, NULL, yp, NULL, CPL_FALSE, &mindeg, &maxdeg);
1187 CPLCHECK_NUL ("Cannot fit the expected position from table");
1188
1189 /* Evaluate polynomial for all column, and fill the pixels
1190 around expected spectrum position with 1 */
1191 for (cpl_size x = 0; x < nx ; x++) {
1192 cpl_size y0 = cpl_polynomial_eval_1d (fit, x, NULL);
1193 for (cpl_size y = y0-hw; y <= y0+hw; y++) {
1194 if ((y >= 0) && (y < ny))
1195 cpl_mask_set (mask, x+1, y+1, CPL_BINARY_1);
1196 CPLCHECK_NUL ("Cannot set mask");
1197 }
1198 }
1199 } /* End loop on regions */
1200
1201 /* Free data */
1202 FREE (cpl_polynomial_delete, fit);
1203 FREE (cpl_matrix_delete, xp);
1204 FREE (cpl_vector_delete, yp);
1205
1206 /* Return mask */
1208 return mask;
1209}
1210
1211/*----------------------------------------------------------------------------*/
1230/*----------------------------------------------------------------------------*/
1231
1233 const cpl_parameterlist * parlist)
1234{
1236 cpl_ensure_code (data, CPL_ERROR_NULL_INPUT);
1237
1238 int nv = 0;
1239
1240 /* Read header and number of regions */
1241 cpl_propertylist * header = gravi_data_get_header (data);
1242 cpl_table * detector_table = gravi_data_get_table (data, GRAVI_IMAGING_DETECTOR_SC_EXT);
1243 cpl_size nreg = cpl_table_get_nrow (detector_table);
1244 const char * resolution = gravi_pfits_get_resolution (header);
1245
1246 CPLCHECK_MSG ("Cannot get data");
1247
1248 /* Get the data as imagelist */
1249 cpl_imagelist * imglist = gravi_data_get_cube (data, GRAVI_IMAGING_DATA_SC_EXT);
1250 cpl_size nframe = cpl_imagelist_get_size (imglist);
1251 cpl_size nx = cpl_image_get_size_x (cpl_imagelist_get (imglist, 0));
1252 cpl_size ny = cpl_image_get_size_y (cpl_imagelist_get (imglist, 0));
1253
1254 CPLCHECK_MSG ("Cannot get data");
1255
1256 /* Remove cosmic rays if requested */
1257 if ( gravi_param_get_bool_default (parlist, "gravity.preproc.remove-cosmicrays", CPL_TRUE) )
1258 {
1260 CPLCHECK_MSG ("Cannot remove cosmic rays");
1261 }
1262 else
1263 {
1264 cpl_msg_info (cpl_func, "Skip gravi_remove_cosmicrays_sc");
1265 }
1266
1267 /* To save the list of bias correction */
1268 cpl_vector * bias_list = cpl_vector_new (nframe);
1269
1270 /* Some hardcoded information */
1271 cpl_size nx_bias_hr = 4;
1272 cpl_size ny_reg_mr = (ny - 1) / nreg;
1273 cpl_size n_bias_line = 5;
1274
1275 /* Compute the median image of the imagelist */
1276 // cpl_msg_info (cpl_func, "Remove spatial structure");
1277 // cpl_image * median_img = cpl_imagelist_collapse_sigclip_create (imglist, 5, 5, 0.6, CPL_COLLAPSE_MEDIAN_MEAN, NULL);
1278 // cpl_imagelist_subtract_image (imglist, median_img);
1279 // CPLCHECK_MSG ("Cannot remove the median image");
1280
1281 const char * bias_method = gravi_param_get_string_default (parlist,
1282 "gravity.preproc.bias-method","AUTO");
1283 // If bias_method is auto then verify the colums present in
1284 // the IMAGING_DETECTOR_SC extension. We check just for LEFT.
1285 // It is assumed that HALFLEFT, CENTER, HALFRIGHT, RIGHT
1286 // are also present in that case since they were added
1287 // together to the raw data.
1288 // If those keywords are present then we use MASKED_MEDIAN_PER_COLUMN
1289 // Otherwise we use MEDIAN
1290 if (!strcmp(bias_method, "AUTO"))
1291 {
1292 if (cpl_table_has_column(detector_table, "LEFT") )
1293 {
1294 bias_method = "MASKED_MEDIAN_PER_COLUMN";
1295 cpl_msg_info (cpl_func, "New data format found. "
1296 "Using MASKED_MEDIAN_PER_COLUMN bias method");
1297 }
1298 else
1299 {
1300 bias_method = "MEDIAN";
1301 cpl_msg_warning (cpl_func, "Old data format found (or data is missing columns in IMAGING_DETECTOR_SC). "
1302 "Using MEDIAN bias method");
1303 }
1304 }
1305 /* Case --bias-method=MASKED_MEDIAN_PER_COLUMN */
1306 if ( !strcmp (bias_method, "MASKED_MEDIAN_PER_COLUMN")) {
1307
1308 /* gravi_msg_warning ("FIXME","Bias method MASKED_MEDIAN_PER_COLUMN is experimental"); */
1309
1310 /* Build the mask of supposedly illuminated pixels */
1311 cpl_mask * mask;
1312 mask = gravi_data_create_bias_mask (detector_table, nx, ny);
1313
1314 /* Save the mask in data */
1315 cpl_image * mask_img = cpl_image_new_from_mask (mask);
1316 gravi_data_add_img (data, NULL, "BIAS_MASK_SC", mask_img);
1317
1318 /* Loop on frames */
1319 for (cpl_size f = 0; f < nframe; f++) {
1320 cpl_image * frame = cpl_imagelist_get (imglist, f);
1321
1322 /* Get the overal shape in the vertical direction
1323 by the mean of bias pixels. To help the median.
1324 This is still not tested */
1325 // cpl_size nbias_x = 4;
1326 // cpl_image * collapse_x;
1327 // collapse_x = gravi_image_collapse_median_x (frame, nbias_x + 1, nx - nbias_x);
1328 // cpl_image_subtract_scalar (collapse_x, cpl_image_get_median (collapse_x));
1329
1330 /* Remove this value to all pixels of the line */
1331 // gravi_image_subtract_collapse (frame, collapse_x, 1);
1332 // CPLCHECK_MSG ("Cannot remove x shape");
1333
1334 /* Set the illuminated pixels as 'bad pixels', store
1335 the current bad-pixel map in case it exists */
1336 cpl_mask * thismask = cpl_mask_duplicate (mask);
1337 cpl_mask * bpm = cpl_image_set_bpm (frame, thismask);
1338 FREE (cpl_mask_delete, bpm);
1339
1340 /* Compute median along the y direction */
1341 cpl_image * collapse_y;
1342 collapse_y = cpl_image_collapse_median_create (frame, 0, 0, 0);
1343
1344 /* Set back the bpm immediately, otherwise following
1345 operations are not running on masked pixels */
1346 thismask = cpl_image_set_bpm (frame, bpm);
1347 FREE (cpl_mask_delete, thismask);
1348
1349 /* Remove this value to all pixels of the column */
1350 gravi_image_subtract_collapse (frame, collapse_y, 0);
1351
1352 /* Re-add the crude bias shape in the y direction. Ideally we
1353 would like to remove it entirely, but the SNR is too low.
1354 This is still not tested */
1355 // cpl_image_multiply_scalar (mean_collapse_x, -1.0);
1356 // gravi_image_subtract_collapse (frame, mean_collapse_x, 1);
1357
1358 /* For QC */
1359 cpl_vector_set (bias_list, f, cpl_image_get_mean (collapse_y));
1360
1361 /* Delete data */
1362 // FREE (cpl_image_delete, collapse_x);
1363 FREE (cpl_image_delete, collapse_y);
1364
1365 CPLCHECK_MSG ("Cannot remove the bias");
1366 } /* End loop on frames */
1367
1368 FREE (cpl_mask_delete, mask);
1369 }
1370 /* Case HIGH spectral resolution and
1371 * --bias-method=MEDIAN_PER_COLUMN */
1372 else if ( !strcmp(resolution, "HIGH") && !strcmp (bias_method,
1373 "MEDIAN_PER_COLUMN")) {
1374 /* TODO High - the n first lines of Image is bias
1375 * Use the median of the bias-pixel
1376 * per column !! not correct should do like for MED and LOW */
1377
1378 gravi_msg_warning ("FIXME","Remove bias per column is experimental (HIGH)");
1379
1380 cpl_vector * bias = cpl_vector_new (nx);
1381 cpl_vector * bias_column = cpl_vector_new (n_bias_line*2);
1382
1383 /* Loop on frames */
1384 for (cpl_size f = 0; f < nframe; f++) {
1385 cpl_image * frame = cpl_imagelist_get (imglist, f);
1386
1387 /* Loop on columns */
1388 for (cpl_size x = 0; x < nx; x++) {
1389 cpl_size bias_index=0;
1390
1391 /* Get the bias pixels of the first lines */
1392 for (cpl_size y = 0; y < n_bias_line; y++) {
1393 double value = cpl_image_get (frame, x+1, y+1, &nv);
1394 cpl_vector_set (bias_column, bias_index++, value);
1395 CPLCHECK_MSG ("Cannot get the bias pixels");
1396 }
1397
1398 /* Get the bias pixels of the last lines */
1399 for (cpl_size y = 0; y < n_bias_line; y++) {
1400 double value = cpl_image_get (frame, x+1, ny-y, &nv);
1401 cpl_vector_set (bias_column, bias_index++, value);
1402 CPLCHECK_MSG ("Cannot get the bias pixels");
1403 }
1404
1405 /* Compute the bias of this column, and save it */
1406 double bias_med = cpl_vector_get_median (bias_column);
1407 cpl_vector_set (bias, x, bias_med);
1408
1409 /* Remove the bias from this column */
1410 for (cpl_size y = 0; y < ny; y++) {
1411 double value = cpl_image_get (frame, x+1, y+1, &nv);
1412 cpl_image_set (frame, x+1, y+1, value - bias_med);
1413 CPLCHECK_MSG ("Cannot set the bias corrected pixels");
1414 }
1415 } /* End loop on columns */
1416
1417 /* Remove the median of bias pixels to image */
1418 double bias_mean = cpl_vector_get_mean (bias);
1419 cpl_vector_set (bias_list, f, bias_mean);
1420 }
1421 FREE (cpl_vector_delete, bias);
1422 FREE (cpl_vector_delete, bias_column);
1423 }
1424 /* Case HIGH spectral resolution
1425 * and --bias-method=MEDIAN */
1426 else if ( !strcmp(resolution, "HIGH") ) {
1427 /* High Resolution - the first 4 columns
1428 * are for bias. FIXME: make sure this is also true in
1429 * in HIGH-COMBINED */
1430
1431 cpl_vector * bias = cpl_vector_new (nx_bias_hr * ny);
1432
1433 /* Loop on frames */
1434 for (cpl_size f = 0; f < nframe; f++) {
1435 cpl_image * frame = cpl_imagelist_get (imglist, f);
1436
1437 /* Get the bias pixels */
1438 for (cpl_size x = 0; x < nx_bias_hr; x++)
1439 for (cpl_size y = 0; y < ny; y++) {
1440 cpl_vector_set (bias, x * ny + y, cpl_image_get (frame, x+1, y+1, &nv));
1441 CPLCHECK_MSG ("Cannot get the bias pixels");
1442 }
1443
1444 /* Remove the median of bias pixels to image */
1445 double bias_med = cpl_vector_get_median (bias);
1446 cpl_vector_set (bias_list, f, bias_med);
1447 cpl_image_subtract_scalar (frame, bias_med);
1448 CPLCHECK_MSG ("Cannot subtract bias");
1449 }
1450 FREE (cpl_vector_delete, bias);
1451 }
1452 /* Case LOW or MEDIUM spectral resolution
1453 * and --bias-method=MEDIAN_PER_COLUMN */
1454 else if ( !strcmp (bias_method,
1455 "MEDIAN_PER_COLUMN")) {
1456 /* Low and Medium - the n_bias_line between
1457 * each region is bias. Use the median of the bias-pixel
1458 * per column !!*/
1459
1460 gravi_msg_warning ("FIXME","Remove bias per column is experimental (LOW, MEDIUM)");
1461
1462 cpl_vector * bias = cpl_vector_new (nx);
1463// cpl_vector * bias_column = cpl_vector_new (nreg);
1464 cpl_vector * bias_column = cpl_vector_new ((nreg-1)*n_bias_line);
1465 cpl_vector * bias_coord = cpl_vector_new ((nreg-1)*n_bias_line);
1466
1467 /* Loop on frames */
1468 for (cpl_size f = 0; f < nframe; f++) {
1469 cpl_image * frame = cpl_imagelist_get (imglist, f);
1470
1471 /* Loop on columns */
1472 for (cpl_size x = 0; x < nx; x++) {
1473 cpl_size bias_index=0;
1474
1475 /* Get the bias pixels of this column */
1476/* commented to try a new implementation
1477 for (cpl_size y = 0; y < nreg; y++) {
1478 double value = cpl_image_get (frame, x+1, (y+1)*ny_reg_mr+1, &nv);
1479 cpl_vector_set (bias_column, y, value);
1480 CPLCHECK_MSG ("Cannot get the bias pixels");
1481 }
1482*/
1483 for (cpl_size reg = 0; reg < nreg-1; reg++) {
1484 int starty=gravi_data_get_dark_pos(detector_table, reg)-n_bias_line/2;
1485 for (cpl_size y = 0; y < n_bias_line; y++){
1486 double value = cpl_image_get (frame, x+1, starty+y+1, &nv);
1487 cpl_vector_set (bias_column, bias_index, value);
1488 cpl_vector_set (bias_coord, bias_index++, starty+y);
1489 }
1490 CPLCHECK_MSG ("Cannot get the bias pixels");
1491 }
1492
1493 /* Compute the bias of this column, and save it */
1494 double bias_med = gravi_vector_get_mean_clip (bias_column, 0.05, 3.0);
1495 cpl_vector_set (bias, x, bias_med);
1496
1497 /* Remove the bias from this column */
1498 for (cpl_size y = 0; y < ny; y++) {
1499 double value = cpl_image_get (frame, x+1, y+1, &nv);
1500 cpl_image_set (frame, x+1, y+1, value - bias_med);
1501 CPLCHECK_MSG ("Cannot set the bias corrected pixels");
1502 }
1503 } /* End loop on columns */
1504
1505 /* Remove the median of bias pixels to image */
1506 double bias_mean = cpl_vector_get_mean (bias);
1507 cpl_vector_set (bias_list, f, bias_mean);
1508 }
1509 FREE (cpl_vector_delete, bias);
1510 FREE (cpl_vector_delete, bias_column);
1511 }
1512 /* Case LOW or MEDIUM spectral resolution and
1513 * --bias-method=MEDIAN */
1514 else {
1515 /* Low and Medium - the first line of
1516 * each region is bias */
1517
1518 cpl_vector * bias = cpl_vector_new (nx * nreg);
1519
1520 /* Loop on frames */
1521 for (cpl_size f = 0; f < nframe; f++) {
1522 cpl_image * frame = cpl_imagelist_get (imglist, f);
1523
1524 /* Get the bias pixels */
1525 for (cpl_size x = 0; x < nx; x++)
1526 for (cpl_size y = 0; y < nreg; y++) {
1527 cpl_vector_set (bias, x * nreg + y, cpl_image_get (frame, x+1, (y+1)*ny_reg_mr+1, &nv));
1528 CPLCHECK_MSG ("Cannot get the bias pixels");
1529 }
1530
1531 /* Remove the median of bias pixels to image */
1532 double bias_med = cpl_vector_get_median (bias);
1533 cpl_vector_set (bias_list, f, bias_med);
1534 cpl_image_subtract_scalar (frame, bias_med);
1535 CPLCHECK_MSG ("Cannot subtract bias");
1536 }
1537 FREE (cpl_vector_delete, bias);
1538 }
1539
1540
1541 /* Re-install the median */
1542 //cpl_imagelist_add_image (imglist, median_img);
1543 //FREE (cpl_image_delete, median_img);
1544 //CPLCHECK_MSG ("Cannot add the median image");
1545
1546 /* Add some QC */
1547 cpl_propertylist_update_double (header, "ESO QC PIXBIAS AVG", cpl_vector_get_mean (bias_list));
1548 cpl_propertylist_set_comment (header, "ESO QC PIXBIAS AVG", "[adu] avg over the bias pixel");
1549
1550 cpl_propertylist_update_double (header, "ESO QC PIXBIAS RMS", cpl_vector_get_stdev (bias_list));
1551 cpl_propertylist_set_comment (header, "ESO QC PIXBIAS RMS", "[adu] rms over frames");
1552 cpl_vector_delete (bias_list);
1553
1555 return CPL_ERROR_NONE;
1556}
1557
1558/*----------------------------------------------------------------------------*/
1559
1560/* Return the first extension exactly matching EXTNAME=name */
1561inline static int _gravi_data_find (const gravi_data *self, const char *name)
1562{
1563 int ext = 0;
1564 while (ext < self->nb_ext){
1565 cpl_propertylist *p = self->exts_hdrs[ext];
1566 const char *key = cpl_propertylist_get_string (p, "EXTNAME");
1567 if (strcmp(key, name) == 0) break;
1568 ext ++;
1569 }
1570 return ext;
1571}
1572
1573
1574/*---------------------------------------------------------------------------*/
1587
1588/*---------------------------------------------------------------------------*/
1589
1591 gravi_data * input,
1592 const char * name,
1593 const char * insname)
1594{
1595 cpl_ensure_code (output, CPL_ERROR_NULL_INPUT);
1596 cpl_ensure_code (input, CPL_ERROR_NULL_INPUT);
1597 cpl_ensure_code (name, CPL_ERROR_NULL_INPUT);
1598 cpl_ensure_code (insname, CPL_ERROR_NULL_INPUT);
1599
1600 int n = gravi_data_get_size (input);
1601 for (int j = 0; j < n; j++){
1602
1603 cpl_propertylist * plist = gravi_data_get_plist_x (input, j);
1604
1605 if (!cpl_propertylist_has (plist, "EXTNAME")) continue;
1606 if (!cpl_propertylist_has (plist, "INSNAME")) continue;
1607
1608 const char * plist_name = gravi_pfits_get_extname (plist);
1609 const char * plist_insname = gravi_pfits_get_insname (plist);
1610
1611 CPLCHECK_MSG ("Cannot get input data");
1612
1613 if (plist_name == NULL) continue;
1614
1615 if (!(strcmp (plist_name, name)) &&
1616 !(strcmp (plist_insname, insname))) {
1617 int type_data = gravi_pfits_get_extension_type (plist);
1618
1619 if (type_data == 2) {
1620 gravi_data_add_table (output, cpl_propertylist_duplicate (plist), NULL,
1621 cpl_table_duplicate (gravi_data_get_table_x (input, j)));
1622 }
1623 else if (type_data == 3) {
1624 gravi_data_add_cube (output, cpl_propertylist_duplicate (plist), NULL,
1625 cpl_imagelist_duplicate (gravi_data_get_cube_x (input, j)));
1626 }
1627
1628 CPLCHECK_MSG ("Cannot copy extension");
1629 }
1630 }
1631
1632 return CPL_ERROR_NONE;
1633}
1634
1635/*---------------------------------------------------------------------------*/
1647
1648/*---------------------------------------------------------------------------*/
1649
1650cpl_error_code gravi_data_copy_ext_i (gravi_data * output,
1651 gravi_data * input,
1652 cpl_size num)
1653{
1654 cpl_ensure_code (output, CPL_ERROR_NULL_INPUT);
1655 cpl_ensure_code (input, CPL_ERROR_NULL_INPUT);
1656 cpl_ensure_code (num>=0, CPL_ERROR_ILLEGAL_INPUT);
1657 cpl_ensure_code (num<input->nb_ext, CPL_ERROR_ILLEGAL_INPUT);
1658
1659 cpl_propertylist * plist = gravi_data_get_plist_x (input, num);
1660 int type_data = gravi_pfits_get_extension_type (plist);
1661
1662 if (type_data == 2)
1663 {
1664 gravi_data_add_table (output, cpl_propertylist_duplicate (plist), NULL,
1665 cpl_table_duplicate (gravi_data_get_table_x (input, num)));
1666 }
1667 else if (type_data == 3)
1668 {
1669 gravi_data_add_cube (output, cpl_propertylist_duplicate (plist), NULL,
1670 cpl_imagelist_duplicate (gravi_data_get_cube_x (input, num)));
1671 }
1672
1673 CPLCHECK_MSG ("Cannot copy extension");
1674
1675 return CPL_ERROR_NONE;
1676}
1677
1678/*---------------------------------------------------------------------------*/
1690
1691/*---------------------------------------------------------------------------*/
1692
1693cpl_error_code gravi_data_copy_ext (gravi_data * output,
1694 gravi_data * input,
1695 const char * name)
1696{
1697 cpl_ensure_code (output, CPL_ERROR_NULL_INPUT);
1698 cpl_ensure_code (input, CPL_ERROR_NULL_INPUT);
1699 cpl_ensure_code (name, CPL_ERROR_NULL_INPUT);
1700
1701 int n = gravi_data_get_size (input);
1702 for (int j = 0; j < n; j++){
1703
1704 cpl_propertylist * plist = gravi_data_get_plist_x (input, j);
1705 const char * plist_name = gravi_pfits_get_extname (plist);
1706
1707 CPLCHECK_MSG ("Cannot get input data");
1708
1709 if (plist_name == NULL) continue;
1710
1711 if (!(strcmp (plist_name, name))) {
1712 int type_data = gravi_pfits_get_extension_type (plist);
1713
1714 if (type_data == 2) {
1715 gravi_data_add_table (output, cpl_propertylist_duplicate (plist), NULL,
1716 cpl_table_duplicate (gravi_data_get_table_x (input, j)));
1717 }
1718 else if (type_data == 3) {
1719 gravi_data_add_cube (output, cpl_propertylist_duplicate (plist), NULL,
1720 cpl_imagelist_duplicate (gravi_data_get_cube_x (input, j)));
1721 }
1722
1723 CPLCHECK_MSG ("Cannot copy extension");
1724 }
1725 }
1726
1727 return CPL_ERROR_NONE;
1728}
1729
1730/*---------------------------------------------------------------------------*/
1742/*---------------------------------------------------------------------------*/
1743
1744cpl_error_code gravi_data_move_ext (gravi_data * output,
1745 gravi_data * input,
1746 const char * name)
1747{
1749 cpl_ensure_code (output, CPL_ERROR_NULL_INPUT);
1750 cpl_ensure_code (input, CPL_ERROR_NULL_INPUT);
1751 cpl_ensure_code (name, CPL_ERROR_NULL_INPUT);
1752
1753 int n = gravi_data_get_size (input);
1754
1755 int jnew = 0;
1756 for (int j = 0; j < n; j++){
1757
1758 cpl_propertylist * plist = gravi_data_get_plist_x (input, j);
1759 const char * plist_name = gravi_pfits_get_extname (plist);
1760 CPLCHECK_MSG ("Cannot get input");
1761
1762 /* Case we need to move this extension */
1763 if ( (plist_name!=NULL) &&
1764 !(strcmp (plist_name, name))) {
1765
1766 cpl_msg_info (cpl_func, "Move extension %s", plist_name);
1767 int type_data = gravi_pfits_get_extension_type (plist);
1768 if (type_data == 2) {
1769 gravi_data_add_table (output, plist, NULL,
1770 gravi_data_get_table_x (input, j));
1771 }
1772 else if (type_data == 3) {
1773 gravi_data_add_cube (output, plist, NULL,
1774 gravi_data_get_cube_x (input, j));
1775 }
1776 CPLCHECK_MSG ("Cannot move extension");
1777
1778 } else {
1779
1780 /* Move pointer in the input */
1781 input->exts_hdrs[jnew] = input->exts_hdrs[j];
1782 input->exts_imgl[jnew] = input->exts_imgl[j];
1783 input->exts_tbs[jnew] = input->exts_tbs[j];
1784 jnew ++;
1785 }
1786
1787 } /* End loop on extension */
1788
1789 /* Cleanup input further away */
1790 input->nb_ext = jnew;
1791 for (int j = input->nb_ext; j < GRAVI_DATA_SIZE; j++) {
1792 input->exts_hdrs[j] = NULL;
1793 input->exts_imgl[j] = NULL;
1794 input->exts_tbs[j] = NULL;
1795 }
1796
1798 return CPL_ERROR_NONE;
1799}
1800
1801/*---------------------------------------------------------------------------*/
1809/*---------------------------------------------------------------------------*/
1810
1811int gravi_data_has_extension (gravi_data * raw_calib, const char * ext_name)
1812{
1813 cpl_ensure (raw_calib, CPL_ERROR_NULL_INPUT, 0);
1814 cpl_ensure (ext_name, CPL_ERROR_NULL_INPUT, 0);
1815
1816 int test = 1;
1817 int ext = _gravi_data_find (raw_calib, ext_name);
1818
1819 if (ext == raw_calib->nb_ext) {
1820 test = 0;
1821 }
1822
1823 return test;
1824}
1825
1826/*---------------------------------------------------------------------------*/
1834/*---------------------------------------------------------------------------*/
1835
1836int gravi_data_has_type (gravi_data * self, const char * type)
1837{
1838 cpl_ensure (self, CPL_ERROR_NULL_INPUT, -1);
1839 cpl_ensure (type, CPL_ERROR_NULL_INPUT, -1);
1840 cpl_ensure (strlen (type)>1, CPL_ERROR_ILLEGAL_INPUT, -1);
1841
1842 int counter = 0;
1843
1844 /* Loop on extension */
1845 for (int ext = 0; ext < gravi_data_get_size (self) ; ext ++) {
1846
1847 cpl_propertylist * plist = gravi_data_get_plist_x (self, ext);
1848
1849 /* Check if EXTNAME or INSNAME contains the 'type'
1850 * Warning that the number of extension is changed in the loop */
1851 if ( (cpl_propertylist_has (plist, "INSNAME") &&
1852 strstr (gravi_pfits_get_insname (plist), type) ) ||
1853 (cpl_propertylist_has (plist, "EXTNAME") &&
1854 strstr (gravi_pfits_get_extname (plist), type) ) )
1855 {
1856 cpl_msg_debug (cpl_func,"Find '%s' ", gravi_pfits_get_extname (plist));
1857 counter ++;
1858 }
1859 }
1860 return counter;
1861}
1862
1863/*---------------------------------------------------------------------------*/
1877/*---------------------------------------------------------------------------*/
1878
1879cpl_propertylist * gravi_data_get_plist_x (gravi_data* self, int i)
1880{
1881 cpl_ensure (self, CPL_ERROR_NULL_INPUT, NULL);
1882 cpl_ensure (i>=0, CPL_ERROR_ILLEGAL_INPUT, NULL);
1883 cpl_ensure (i<self->nb_ext, CPL_ERROR_ILLEGAL_INPUT, NULL);
1884
1885 return self->exts_hdrs[i];
1886}
1887
1888/*---------------------------------------------------------------------------*/
1902/*---------------------------------------------------------------------------*/
1903
1904cpl_table * gravi_data_get_table_x (gravi_data* self, int i)
1905{
1906 cpl_ensure (self, CPL_ERROR_NULL_INPUT, NULL);
1907 cpl_ensure (i>=0, CPL_ERROR_ILLEGAL_INPUT, NULL);
1908 cpl_ensure (i<self->nb_ext, CPL_ERROR_ILLEGAL_INPUT, NULL);
1909
1910 return self->exts_tbs[i];
1911}
1912
1913/*---------------------------------------------------------------------------*/
1927/*---------------------------------------------------------------------------*/
1928
1929cpl_imagelist * gravi_data_get_cube_x (gravi_data* self, int i)
1930{
1931 cpl_ensure (self, CPL_ERROR_NULL_INPUT, NULL);
1932 cpl_ensure (i>=0, CPL_ERROR_ILLEGAL_INPUT, NULL);
1933 cpl_ensure (i<self->nb_ext, CPL_ERROR_ILLEGAL_INPUT, NULL);
1934
1935 return self->exts_imgl[i];
1936}
1937
1938/*---------------------------------------------------------------------------*/
1953/*---------------------------------------------------------------------------*/
1954
1956 const char * extname,
1957 const char * insname)
1958{
1959 cpl_ensure (self, CPL_ERROR_NULL_INPUT, NULL);
1960 cpl_ensure (extname, CPL_ERROR_NULL_INPUT, NULL);
1961 cpl_ensure (insname, CPL_ERROR_NULL_INPUT, NULL);
1962
1963 int nb_ext = self->nb_ext;
1964 int pos = -1;
1965 for (int i = 0; i < nb_ext; i++){
1966
1967 if (cpl_propertylist_has (self->exts_hdrs[i], "INSNAME")){
1968 if ((!strcmp (gravi_pfits_get_insname (self->exts_hdrs[i]), insname)) &&
1969 (!strcmp (gravi_pfits_get_extname (self->exts_hdrs[i]), extname))){
1970 pos = i;
1971 break;
1972 }
1973 }
1974 }
1975
1976 if (pos < 0){
1977 cpl_msg_warning(cpl_func, "The extention %s doesn't exist "
1978 "with the insname %s",
1979 extname, insname);
1980 return NULL;
1981 }
1982
1983 return self->exts_tbs[pos];
1984}
1985
1986/*---------------------------------------------------------------------------*/
2002/*---------------------------------------------------------------------------*/
2003
2004cpl_propertylist * gravi_data_get_oi_plist (gravi_data * self,
2005 const char * extname,
2006 const char * insname)
2007{
2008 cpl_ensure (self, CPL_ERROR_NULL_INPUT, NULL);
2009 cpl_ensure (extname, CPL_ERROR_NULL_INPUT, NULL);
2010 cpl_ensure (insname, CPL_ERROR_NULL_INPUT, NULL);
2011
2012 int nb_ext = self->nb_ext;
2013 int pos = -1;
2014 for (int i = 0; i < nb_ext; i++){
2015 if (cpl_propertylist_has (self->exts_hdrs[i], "INSNAME")){
2016 if ((!strcmp (gravi_pfits_get_insname (self->exts_hdrs[i]), insname)) &&
2017 (!strcmp (gravi_pfits_get_extname (self->exts_hdrs[i]), extname))){
2018 pos = i;
2019 break;
2020 }
2021 }
2022 }
2023
2024 if (pos < -1){
2025 cpl_msg_warning(cpl_func, "The extention %s doesn't exist "
2026 "with the insname %s",
2027 extname, insname);
2028 return NULL;
2029 }
2030
2031 return self->exts_hdrs[pos];
2032}
2033
2034/*---------------------------------------------------------------------------*/
2050/*---------------------------------------------------------------------------*/
2051
2052cpl_propertylist * gravi_data_get_plist (gravi_data * self,
2053 const char * extname)
2054{
2055 cpl_ensure (self, CPL_ERROR_NULL_INPUT, NULL);
2056 cpl_ensure (extname, CPL_ERROR_NULL_INPUT, NULL);
2057
2058 if (!strcmp(extname, GRAVI_PRIMARY_HDR_EXT))
2059 return self->primary_hdr;
2060
2061 int pos = _gravi_data_find(self, extname);
2062
2063 cpl_ensure (pos<self->nb_ext, CPL_ERROR_ILLEGAL_INPUT, NULL);
2064
2065 return self->exts_hdrs[pos];
2066}
2067
2068/*---------------------------------------------------------------------------*/
2078{
2079 cpl_ensure (self, CPL_ERROR_NULL_INPUT, NULL);
2080 return self->extra_primary_hdr;
2081}
2082
2083/*---------------------------------------------------------------------------*/
2097/*---------------------------------------------------------------------------*/
2098
2099cpl_table * gravi_data_get_table (gravi_data* self, const char * extname)
2100{
2101 cpl_ensure (self, CPL_ERROR_NULL_INPUT, NULL);
2102 cpl_ensure (extname, CPL_ERROR_NULL_INPUT, NULL);
2103
2104 int pos = _gravi_data_find(self, extname);
2105
2106 cpl_ensure (pos<self->nb_ext, CPL_ERROR_ILLEGAL_INPUT, NULL);
2107
2108 if ((self->exts_tbs[pos] == NULL) ||
2109 (gravi_pfits_get_extension_type (self->exts_hdrs[pos]) != 2)){
2110 cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
2111 "No BINTABLE at the extension %s", extname);
2112 return NULL;
2113 }
2114
2115 return self->exts_tbs[pos];
2116}
2117
2118/*---------------------------------------------------------------------------*/
2132/*---------------------------------------------------------------------------*/
2133
2134cpl_imagelist * gravi_data_get_cube (gravi_data* self, const char * extname)
2135{
2136 cpl_ensure (self, CPL_ERROR_NULL_INPUT, NULL);
2137 cpl_ensure (extname, CPL_ERROR_NULL_INPUT, NULL);
2138
2139 int pos = _gravi_data_find(self, extname);
2140
2141 cpl_ensure (pos<self->nb_ext, CPL_ERROR_ILLEGAL_INPUT, NULL);
2142
2143 if ((self->exts_imgl[pos] == NULL) ||
2144 (gravi_pfits_get_extension_type (self->exts_hdrs[pos]) != 3)){
2145 cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
2146 "No IMAGE at the extension %s", extname);
2147 return NULL;
2148 }
2149
2150 return self->exts_imgl[pos];
2151}
2152
2153/*----------------------------------------------------------------------------*/
2162/*----------------------------------------------------------------------------*/
2163
2164cpl_error_code gravi_data_erase_x (gravi_data * self, int pos)
2165{
2166 cpl_ensure_code (self, CPL_ERROR_NULL_INPUT);
2167 cpl_ensure_code (pos>-1, CPL_ERROR_ILLEGAL_INPUT);
2168
2169 /* Delete data or move pointers */
2170 int comp = 0;
2171 for (int i = 0; i < self->nb_ext; i++) {
2172 if (i != pos){
2173 self->exts_hdrs[comp] = self->exts_hdrs[i];
2174 self->exts_tbs[comp] = self->exts_tbs[i];
2175 self->exts_imgl[comp] = self->exts_imgl[i];
2176 comp++;
2177 }
2178 else{
2179 if ((gravi_pfits_get_extension_type (self->exts_hdrs[pos]) == 2))
2180 FREE (cpl_table_delete, self->exts_tbs[i]);
2181 else if (gravi_pfits_get_extension_type (self->exts_hdrs[pos]) == 3)
2182 FREE (cpl_imagelist_delete, self->exts_imgl[i]);
2183 CPLCHECK_MSG("Cannot delete data");
2184
2185 FREE (cpl_propertylist_delete, self->exts_hdrs[i]);
2186 CPLCHECK_MSG("Cannot delete header");
2187 }
2188 }
2189
2190 /* Cleanup further away */
2191 for (int i = comp ; i<GRAVI_DATA_SIZE; i++) {
2192 self->exts_hdrs[i] = NULL;
2193 self->exts_tbs[i] = NULL;
2194 self->exts_imgl[i] = NULL;
2195 }
2196
2197 /* Change number of extension */
2198 self->nb_ext = comp;
2199
2200 return CPL_ERROR_NONE;
2201}
2202
2203/*----------------------------------------------------------------------------*/
2213/*----------------------------------------------------------------------------*/
2214
2215cpl_error_code gravi_data_erase (gravi_data * self, const char * extname)
2216{
2217 cpl_ensure_code (self, CPL_ERROR_NULL_INPUT);
2218 cpl_ensure_code (extname, CPL_ERROR_NULL_INPUT);
2219
2220 /* Find the position of the property list */
2221 int pos = _gravi_data_find(self, extname);
2222
2223 /* Check pos */
2224 if (pos == self->nb_ext) {
2225 cpl_msg_info (cpl_func,"Cannot delete '%s' (not found)",extname);
2226 return CPL_ERROR_NONE;
2227 } else {
2228 cpl_msg_info (cpl_func,"Delete '%s' found in ext[%i] (over %i) ",extname, pos, self->nb_ext);
2229 }
2230
2231 /* Erase */
2232 gravi_data_erase_x (self, pos);
2233
2234 CPLCHECK_MSG ("Cannot erase this extension name");
2235 return CPL_ERROR_NONE;
2236}
2237
2238/*----------------------------------------------------------------------------*/
2248/*----------------------------------------------------------------------------*/
2249
2250cpl_error_code gravi_data_erase_type (gravi_data * self, const char * type)
2251{
2252 cpl_ensure_code (self, CPL_ERROR_NULL_INPUT);
2253 cpl_ensure_code (type, CPL_ERROR_NULL_INPUT);
2254 cpl_ensure_code (strlen (type)>1, CPL_ERROR_ILLEGAL_INPUT);
2255
2256 /* Loop on extension */
2257 for (int ext = 0; ext < gravi_data_get_size (self) ; ext ++) {
2258
2259 cpl_propertylist * plist = gravi_data_get_plist_x (self, ext);
2260
2261 /* Check if EXTNAME or INSNAME contains the 'type'
2262 * Warning that the number of extension is changed in the loop */
2263 if ( (cpl_propertylist_has (plist, "INSNAME") &&
2264 strstr (gravi_pfits_get_insname (plist), type) ) ||
2265 (cpl_propertylist_has (plist, "EXTNAME") &&
2266 strstr (gravi_pfits_get_extname (plist), type) ) )
2267 {
2268 cpl_msg_info (cpl_func,"Delete '%s' ", gravi_pfits_get_extname (plist));
2269 gravi_data_erase_x (self, ext);
2270 ext--;
2271
2272 CPLCHECK_MSG ("Cannot erase this type");
2273 }
2274 }
2275 return CPL_ERROR_NONE;
2276}
2277
2278/*----------------------------------------------------------------------------*/
2290/*----------------------------------------------------------------------------*/
2291
2292cpl_error_code gravi_data_add_table (gravi_data * self,
2293 cpl_propertylist * plist,
2294 const char * extname,
2295 cpl_table * table)
2296{
2297 cpl_ensure_code (self, CPL_ERROR_NULL_INPUT);
2298 cpl_ensure_code (table, CPL_ERROR_NULL_INPUT);
2299
2300 /* Set the header */
2301 if (plist == NULL) plist = cpl_propertylist_new ();
2302 if (extname != NULL) cpl_propertylist_update_string (plist, "EXTNAME", extname);
2303
2304 /* Add header */
2305 cpl_propertylist_update_string (plist, "XTENSION", "BINTABLE");
2306 self->exts_hdrs[self->nb_ext] = plist;
2307
2308 /* Add an EXTNAME to UNKNOWN */
2309 if (!cpl_propertylist_has(plist, "EXTNAME") ) {
2310 cpl_msg_error (cpl_func,"FIXME: set a table without EXTNAME !!");
2311 cpl_propertylist_update_string (plist, "EXTNAME", "UNKNOWN");
2312 }
2313
2314 /* OIFITS: add OI_REVN to OI_* tables */
2315 const char * plist_name = 0;
2316 if (cpl_propertylist_has (plist, "EXTNAME"))
2317 plist_name = gravi_pfits_get_extname (plist);
2318
2319 if (plist_name && !(strcmp(plist_name, GRAVI_OI_ARRAY_EXT) &&
2320 strcmp (plist_name, GRAVI_OI_TARGET_EXT) &&
2321 strcmp (plist_name, GRAVI_OI_WAVELENGTH_EXT) &&
2322 strcmp (plist_name, GRAVI_OI_T3_EXT) &&
2323 strcmp (plist_name, GRAVI_OI_VIS2_EXT) &&
2324 strcmp (plist_name, GRAVI_OI_VIS_EXT))) {
2325 cpl_propertylist_update_int (plist, "OI_REVN", 2);
2326 }
2327 if (plist_name && !(strcmp(plist_name, GRAVI_OI_FLUX_EXT))) {
2328 cpl_propertylist_update_int (plist, "OI_REVN", 1);
2329 }
2330 /* OIFITS: check is saved as short */
2332
2333 self->exts_tbs[self->nb_ext] = table;
2334 self->exts_imgl[self->nb_ext] = NULL;
2335
2336 self->nb_ext ++;
2337
2338 CPLCHECK_MSG ("Cannot add the table");
2339 return CPL_ERROR_NONE;
2340}
2341
2342/*----------------------------------------------------------------------------*/
2354/*----------------------------------------------------------------------------*/
2355
2356cpl_error_code gravi_data_add_cube (gravi_data * self,
2357 cpl_propertylist * plist,
2358 const char * extname,
2359 cpl_imagelist * imglist)
2360{
2361
2362 cpl_ensure_code (self, CPL_ERROR_NULL_INPUT);
2363 cpl_ensure_code (imglist, CPL_ERROR_NULL_INPUT);
2364
2365 if (plist == NULL) plist = cpl_propertylist_new ();
2366 if (extname != NULL) cpl_propertylist_update_string (plist, "EXTNAME", extname);
2367
2368 /* Add header */
2369 self->exts_hdrs[self->nb_ext] = plist;
2370 cpl_propertylist_update_string (self->exts_hdrs[self->nb_ext],"XTENSION", "IMAGE");
2371
2372 /* Add data */
2373 self->exts_imgl[self->nb_ext] = (imglist);
2374 self->exts_tbs[self->nb_ext] = NULL;
2375
2376 self->nb_ext ++;
2377
2378 CPLCHECK_MSG ("Cannot add the cube");
2379 return CPL_ERROR_NONE;
2380
2381}
2382
2383/*----------------------------------------------------------------------------*/
2395/*----------------------------------------------------------------------------*/
2396
2397cpl_error_code gravi_data_add_img (gravi_data * self,
2398 cpl_propertylist * plist,
2399 const char * extname,
2400 cpl_image * image) {
2401
2402 cpl_ensure_code (self, CPL_ERROR_NULL_INPUT);
2403 cpl_ensure_code (image, CPL_ERROR_NULL_INPUT);
2404
2405 if (plist == NULL) plist = cpl_propertylist_new ();
2406 if (extname != NULL) cpl_propertylist_update_string (plist, "EXTNAME", extname);
2407
2408 /* Add header */
2409 self->exts_hdrs[self->nb_ext] = plist;
2410 cpl_propertylist_update_string (self->exts_hdrs[self->nb_ext],"XTENSION", "IMAGE");
2411
2412 /* Convert to imagelist */
2413 cpl_imagelist * imglist = cpl_imagelist_new ();
2414 cpl_imagelist_set (imglist, image, 0);
2415
2416 /* Add data */
2417 self->exts_imgl[self->nb_ext] = (imglist);
2418 self->exts_tbs[self->nb_ext] = NULL;
2419
2420 self->nb_ext ++;
2421
2422 CPLCHECK_MSG ("Cannot add the image");
2423 return CPL_ERROR_NONE;
2424}
2425
2426/*---------------------------------------------------------------------------*/
2436/*---------------------------------------------------------------------------*/
2437
2439{
2441 cpl_ensure_code (data, CPL_ERROR_NULL_INPUT);
2442
2443 cpl_table * new_oimet_table;
2444
2445 /* Loop on extension in file ?? */
2446 for (int i = 0; i < gravi_data_get_size (data); i++) {
2447
2448 /* Keep OI_ARRAY, OI_TARGET and OI_VIS_ACQ */
2449 cpl_propertylist * plist = gravi_data_get_plist_x (data, i);
2450 const char * plist_name = gravi_pfits_get_extname (plist);
2451 if (!(strcmp (plist_name, GRAVI_OI_ARRAY_EXT)) ||
2452 !(strcmp (plist_name, GRAVI_OI_TARGET_EXT)) ||
2453 !(strcmp (plist_name, GRAVI_OI_WAVELENGTH_EXT)) ||
2454 !(strcmp (plist_name, GRAVI_OI_VIS_ACQ_EXT)) ) {
2455 cpl_msg_debug (cpl_func,"NAME: %s kept", plist_name);
2456 continue;
2457 }
2458
2459 /* Keep all INSNAME_SC and ACQ camera mean image */
2460 if (cpl_propertylist_has (plist, "INSNAME") &&
2461 ( (!strcmp (gravi_pfits_get_insname (plist), INSNAME_SC_P1)) ||
2463 (!strcmp (gravi_pfits_get_insname (plist), INSNAME_SC)) ||
2464 (!strcmp (gravi_pfits_get_insname (plist), INSNAME_ACQ)) )) {
2465 cpl_msg_debug (cpl_func,"NAME: %s kept", plist_name);
2466 continue;
2467 }
2468
2469 if (!(strcmp (plist_name, GRAVI_OI_VIS_MET_EXT)))
2470 {
2471
2472 cpl_table * old_oimet_table = gravi_data_get_table_x (data, i);
2473
2474 CPLCHECK_MSG ("Cannot read OI_MET table");
2475 cpl_size length = cpl_table_get_nrow (old_oimet_table);
2476 new_oimet_table = cpl_table_new(length);
2477
2478 CPLCHECK_MSG ("Cannot create new OI_MET table");
2479 int nb_names = 6;
2480 const char *names[] = {"TIME", "PHASE_FC_DRS", "PHASE_TELFC_CORR", "OPD_TELFC_CORR_XY","OPD_FC_CORR","OPD_TELFC_MCORR"};
2481 for (int j =0; j<nb_names;j++)
2482 {
2483 cpl_msg_info(cpl_func,"duplicating columns %s",names[j]);
2484 cpl_table_duplicate_column (new_oimet_table, names[j], old_oimet_table, names[j]);
2485 CPLCHECK_MSG ("Failed at duplicating column to new OI_VIS_MET table");
2486 }
2487 }
2488
2489 /* Delete */
2490 cpl_msg_debug (cpl_func,"NAME: %s deleted", plist_name);
2491 FREE (cpl_propertylist_delete, data->exts_hdrs[i]);
2492 FREE (cpl_table_delete, data->exts_tbs[i]);
2493 FREE (cpl_imagelist_delete, data->exts_imgl[i]);
2494 }
2495
2496 /* storing new OI_MET table */
2497 if (new_oimet_table != NULL)
2498 gravi_data_add_table (data, NULL, GRAVI_OI_VIS_MET_EXT, new_oimet_table);
2499
2500 /* Loop on extension in file to move the
2501 * extension consecutively */
2502 int j = 0;
2503 for (int i = 0; i < gravi_data_get_size (data); i++) {
2504 /* This one exist, copy in last place */
2505 if (data->exts_hdrs[i] || data->exts_tbs[i] || data->exts_imgl[i]) {
2506 if ( i!=j ) {
2507 data->exts_hdrs[j] = data->exts_hdrs[i]; data->exts_hdrs[i] = NULL;
2508 data->exts_tbs[j] = data->exts_tbs[i]; data->exts_tbs[i] = NULL;
2509 data->exts_imgl[j] = data->exts_imgl[i]; data->exts_imgl[i] = NULL;
2510 }
2511 j++;
2512 }
2513 }
2514
2515 data->nb_ext = j;
2516
2518 return CPL_ERROR_NONE;
2519}
2520
2521/*---------------------------------------------------------------------------*/
2532/*---------------------------------------------------------------------------*/
2533
2535{
2537 cpl_ensure_code (data, CPL_ERROR_NULL_INPUT);
2538
2539 char qc_msg[80];
2540
2541 /* Add the QC parameter, start with 0 warning */
2542 cpl_propertylist * header = gravi_data_get_header (data);
2543 cpl_propertylist_append_int (header, "ESO QC CHECK FLAGS", 0);
2544
2545 /* Check number of extensions */
2546 int nb_ext = 12;
2547 const char *extname[] = {"ARRAY_DESCRIPTION", "ARRAY_GEOMETRY", "OPTICAL_TRAIN",
2548 "IMAGING_DATA_ACQ", "ACQ_ABS_REF_POSITION",
2549 "OPDC", "FDDL", "METROLOGY",
2550 "IMAGING_DATA_SC","IMAGING_DETECTOR_SC",
2551 "IMAGING_DATA_FT","IMAGING_DETECTOR_FT"};
2552
2553 for (int ext = 0; ext< nb_ext; ext++) {
2554
2555 /* Check if existing */
2556 if ( !gravi_data_has_extension (data, extname[ext]) ) {
2557 sprintf (qc_msg, "%s is missing", extname[ext]);
2558 gravi_pfits_add_check (header, qc_msg);
2559 continue;
2560 }
2561
2562 cpl_propertylist * plist;
2563 plist = gravi_data_get_plist (data, extname[ext]);
2564
2565 /* Check the frame counter if it has one */
2566 if (cpl_propertylist_has (plist, "ESO DET FRAM NO")) {
2567 int frame_no = cpl_propertylist_get_int (plist, "ESO DET FRAM NO");
2568 int naxis_3 = cpl_propertylist_get_int (plist, "NAXIS3");
2569 if ( frame_no != naxis_3) {
2570 sprintf (qc_msg, "%s is missing DITs", extname[ext]);
2571 gravi_pfits_add_check (header, qc_msg);
2572 }
2573 }
2574 }
2575
2576 CPLCHECK_MSG ("Cannot check consistency of tables...");
2577
2578
2579
2580 /* Build the time of the first and last frame of SC in
2581 * [us] with respect to PRC.ACQ.START. We need RMN data over
2582 * the entire first and last DITs of SC */
2583 int ndit = cpl_propertylist_get_int (header, "ESO DET2 NDIT");
2584 double scdit = gravi_pfits_get_dit_sc (header);
2585 double start_sc = gravi_pfits_get_time_sc (header, 0) - scdit/2. * 1e6;
2586 double end_sc = gravi_pfits_get_time_sc (header, ndit-1) + scdit/2. * 1e6;
2587
2588 cpl_msg_debug (cpl_func,"start = %8.0f and end = %10.0f (%s [us] from PCR.ACQ.START)",
2589 start_sc, end_sc, "SC");
2590
2591 /* Check the TIME content of RMN tables */
2592 int nb_ext_rmn = 4;
2593 const char *ext_rmn[] = {"OPDC", "FDDL", "METROLOGY", "IMAGING_DATA_FT"};
2594
2595 for (int ext = 0; ext< nb_ext_rmn; ext++) {
2596
2597 /* Get this RMN table */
2598 if (!gravi_data_has_extension (data, ext_rmn[ext])) continue;
2599 cpl_table * table = gravi_data_get_table (data, ext_rmn[ext]);
2600
2601 /* Get the first and last time sample, in [us] */
2602 double min_table = cpl_table_get_column_min (table, "TIME");
2603 double max_table = cpl_table_get_column_max (table, "TIME");
2604
2605 cpl_msg_debug (cpl_func,"start = %8.0f and end = %10.0f (%s [us] from PCR.ACQ.START)",
2606 min_table, max_table, ext_rmn[ext]);
2607
2608 /* Check if it covers the SC data */
2609 if ( min_table > start_sc) {
2610 sprintf (qc_msg, "%s starts *after* the science exposure", ext_rmn[ext]);
2611 gravi_pfits_add_check (header, qc_msg);
2612 }
2613 if ( max_table < end_sc) {
2614 sprintf (qc_msg, "%s finish *before* the science exposure", ext_rmn[ext]);
2615 gravi_pfits_add_check (header, qc_msg);
2616 }
2617
2618 /* Get data */
2619 cpl_size nrow = cpl_table_get_nrow (table);
2620 int * time = cpl_table_get_data_int (table, "TIME");
2621 CPLCHECK_MSG ("Cannot get data");
2622
2623 /* Compute the median step, over the first 10000 samples */
2624 cpl_size nsamp = CPL_MIN (10000, nrow-1);
2625 cpl_array * delta = cpl_array_new (nsamp, CPL_TYPE_INT);
2626 for (cpl_size row = 0; row < nsamp ; row++) {
2627 cpl_array_set_int (delta, row, time[row+1] - time[row]);
2628 }
2629 double median_delta = cpl_array_get_median (delta);
2630 FREE (cpl_array_delete, delta);
2631
2632 /* Check missing samples (delta > 1.5 * median) */
2633 int nwrong = 0;
2634 int nwrong_warning = 0;
2635 if (!strcmp (ext_rmn[ext], "OPDC")) nwrong_warning = 2;
2636 for (cpl_size row = 0; row < nrow-1 ; row++) {
2637 double current_delta = time[row+1] - time[row];
2638 if (current_delta > 1.5 * median_delta) nwrong ++;
2639 }
2640 if (nwrong > nwrong_warning) {
2641 sprintf (qc_msg, "%s has %i wrong steps", ext_rmn[ext], nwrong);
2642 gravi_pfits_add_check (header, qc_msg);
2643 }
2644
2645 } /* End loop on RMN tables */
2646
2647 CPLCHECK_MSG ("Cannot check consistency of RMN tables...");
2648
2650 return CPL_ERROR_NONE;
2651}
2652
2653/*---------------------------------------------------------------------------*/
2665/*---------------------------------------------------------------------------*/
2666
2667cpl_table ** gravi_data_get_oiwave_tables (gravi_data * data, int type_data, int npol)
2668{
2669 cpl_ensure (data, CPL_ERROR_NULL_INPUT, NULL);
2670 cpl_ensure (npol == 1 || npol == 2, CPL_ERROR_ILLEGAL_INPUT, NULL);
2671 cpl_ensure (type_data == GRAVI_SC || type_data == GRAVI_FT, CPL_ERROR_ILLEGAL_INPUT, NULL);
2672
2673 cpl_table ** oiwave_tables = cpl_calloc (npol, sizeof(cpl_table *));
2674 for (int pol = 0; pol < npol; pol++)
2675 oiwave_tables[pol] = gravi_data_get_oi_wave (data, type_data, pol, npol);
2676
2677 return oiwave_tables;
2678}
2679
2680
2681
#define test(f, m, flag)
Definition gravi-test.h:87
#define GRAVI_PRIMARY_HDR_EXT
Definition gravi-test.h:212
#define gravi_table_get_value(table, name, row, value)
Definition gravi_cpl.h:49
typedefCPL_BEGIN_DECLS struct _gravi_data_ gravi_data
Definition gravi_data.h:39
#define gravi_data_get_header(data)
Definition gravi_data.h:75
#define gravi_data_get_oi_wave(data, type, pol, npol)
Definition gravi_data.h:45
#define gravi_data_get_qc(data)
Definition gravi_data.h:77
cpl_table_save(vis_met, NULL, NULL, "vismet.fits", CPL_IO_CREATE)
cpl_msg_debug(cpl_func, "Spectra has <50 pixels -> don't flat")
cpl_propertylist * header
Definition gravi_old.c:2004
cpl_propertylist * plist
Definition gravi_old.c:2000
cpl_msg_info(cpl_func, "Compute WAVE_SCAN for %s", GRAVI_TYPE(type_data))
cpl_propertylist_update_double(header, "ESO QC MINWAVE SC", cpl_propertylist_get_double(plist, "ESO QC MINWAVE SC"))
cpl_image_delete(flat_profiled)
#define GRAVI_OI_VIS2_EXT
Definition gravi_pfits.h:96
#define GRAVI_OI_VIS_ACQ_EXT
Definition gravi_pfits.h:90
#define GRAVI_OI_VIS_MET_EXT
Definition gravi_pfits.h:89
#define GRAVI_OI_TARGET_EXT
Definition gravi_pfits.h:87
#define GRAVI_OI_ARRAY_EXT
Definition gravi_pfits.h:84
#define INSNAME_SC_P2
#define GRAVI_SC
#define GRAVI_OI_VIS_EXT
Definition gravi_pfits.h:93
#define INSNAME_SC
#define INSNAME_ACQ
#define GRAVI_OI_FLUX_EXT
Definition gravi_pfits.h:94
#define GRAVI_NIGHT_OBS
Definition gravi_pfits.h:36
#define GRAVI_IMAGING_DATA_SC_EXT
Definition gravi_pfits.h:44
#define GRAVI_OI_T3_EXT
Definition gravi_pfits.h:95
#define INSNAME_SC_P1
#define GRAVI_IMAGING_DETECTOR_SC_EXT
Definition gravi_pfits.h:49
#define GRAVI_FT
#define GRAVI_OI_WAVELENGTH_EXT
Definition gravi_pfits.h:92
#define CPLCHECK_INT(msg)
Definition gravi_utils.h:51
#define gravi_msg_function_exit(flag)
Definition gravi_utils.h:85
#define FILESHORT(file)
Definition gravi_utils.h:75
#define FREE(function, variable)
Definition gravi_utils.h:69
#define CPLCHECK_NUL(msg)
Definition gravi_utils.h:48
#define gravi_msg_function_start(flag)
Definition gravi_utils.h:84
#define CPLCHECK_MSG(msg)
Definition gravi_utils.h:45
#define FREELOOP(function, variable, n)
Definition gravi_utils.h:72
cpl_error_code gravi_image_subtract_collapse(cpl_image *img, const cpl_image *collapse, int direction)
Definition gravi_cpl.c:1920
double gravi_vector_get_mean_clip(cpl_vector *vector_in, double percent, double nsigma)
Return the mean of a vector after extrema and RMS clipping.
Definition gravi_cpl.c:2641
int gravi_table_are_equal(cpl_table *first, cpl_table *second)
Check if two tables have the same content.
Definition gravi_cpl.c:1584
int gravi_data_patch(gravi_data *file_to_patch, cpl_frameset *patch_frameset)
Load a RAW FITS file and create a gravi_data.
Definition gravi_data.c:635
cpl_error_code gravi_data_erase(gravi_data *self, const char *extname)
Erase an extension by its EXTNAME.
cpl_propertylist * gravi_data_get_oi_plist(gravi_data *self, const char *extname, const char *insname)
Get the propertylist from EXTNAME and INSNAME.
gravi_data * gravi_data_duplicate(const gravi_data *self)
Create a copy of the gravi data.
Definition gravi_data.c:250
cpl_error_code gravi_data_add_cube(gravi_data *self, cpl_propertylist *plist, const char *extname, cpl_imagelist *imglist)
Add an IMAGE (imagelist) extension in gravi_data.
int gravi_data_get_dark_pos(cpl_table *detector_table, int reg)
retrun the position of the dark line on top of the region at x position
cpl_mask * gravi_data_create_bias_mask(cpl_table *detector_table, cpl_size nx, cpl_size ny)
return a mask with pixel to be possibly illuminated
cpl_imagelist * gravi_data_get_cube_x(gravi_data *self, int i)
Get the cube of an extension by position.
cpl_propertylist * gravi_data_get_extra_primary_header(gravi_data *self)
Get the propertylist for additional keywords to the primary header.
gravi_data * gravi_data_load_ext(const char *filename, const char *extensions_regexp)
Low-level function to load FITS file.
Definition gravi_data.c:474
#define GRAVI_DATA_SIZE
Definition gravi_data.c:62
gravi_data * gravi_data_load(const char *filename)
Low-level function to load FITS file.
Definition gravi_data.c:402
cpl_error_code gravi_data_clean_for_astro(gravi_data *data)
Clean the data to keep only OIFITS extensions related to SC.
cpl_propertylist * gravi_data_get_plist(gravi_data *self, const char *extname)
Get the propertylist from EXTNAME.
cpl_error_code gravi_data_check_savetypes(cpl_propertylist *hdr, cpl_table *oi_table)
Set the savetypes of the OIFITS table.
Definition gravi_data.c:198
gravi_data * gravi_data_new(int nb_ext)
Create an empty gravi_data.
Definition gravi_data.c:110
cpl_error_code gravi_data_add_table(gravi_data *self, cpl_propertylist *plist, const char *extname, cpl_table *table)
Add a BINTABLE extension in gravi_data.
static int _gravi_data_find(const gravi_data *self, const char *name)
cpl_error_code gravi_data_add_img(gravi_data *self, cpl_propertylist *plist, const char *extname, cpl_image *image)
Add an IMAGE (single image) extension in gravi_data.
cpl_error_code gravi_data_erase_type(gravi_data *self, const char *type)
Erase all extension related to an instrument (SC, FT, MET...)
cpl_error_code gravi_data_copy_ext_i(gravi_data *output, gravi_data *input, cpl_size num)
Copy extensions from one data to another.
gravi_data * gravi_data_load_frame(cpl_frame *frame, cpl_frameset *used_frameset)
Load a FITS file and create a gravi_data.
Definition gravi_data.c:599
cpl_error_code gravi_data_detector_cleanup(gravi_data *data, const cpl_parameterlist *parlist)
Perform self-bias correction to the SC raw data.
cpl_table ** gravi_data_get_oiwave_tables(gravi_data *data, int type_data, int npol)
Get pointer to the OI_WAVELENGTH tables of both polarisations.
cpl_error_code gravi_data_dump_mode(gravi_data *data)
Dump some information about data in messagin.
Definition gravi_data.c:565
cpl_imagelist * gravi_data_get_cube(gravi_data *self, const char *extname)
Return a pointer on an IMAGE extension by its EXTNAME.
int gravi_data_has_extension(gravi_data *raw_calib, const char *ext_name)
Check if data has extension with given EXTNAME.
int gravi_data_is_oi_ext(cpl_propertylist *hdr)
Check if EXTNAME starts with 'OI_' (OIFITS extension)
Definition gravi_data.c:174
int gravi_data_has_type(gravi_data *self, const char *type)
Return the number of ext whose EXTNAME and INSNAME match 'type'.
cpl_error_code gravi_data_save_data(gravi_data *self, const char *filename, unsigned mode)
Save a gravi data in a FITS file.
Definition gravi_data.c:856
cpl_table * gravi_data_get_table(gravi_data *self, const char *extname)
Return a pointer on a table extension by its EXTNAME.
cpl_table * gravi_data_get_oi_table(gravi_data *self, const char *extname, const char *insname)
Get an OI_FITS table from EXTNAME and INSNAME.
cpl_error_code gravi_remove_cosmicrays_sc(cpl_imagelist *imglist_sc)
Remove cosmic rays via filtering through images.
gravi_data * gravi_data_load_rawframe(cpl_frame *frame, cpl_frameset *used_frameset)
Load a RAW FITS file and create a gravi_data.
Definition gravi_data.c:716
cpl_error_code gravi_data_move_ext(gravi_data *output, gravi_data *input, const char *name)
Move extensions from one data to another.
cpl_error_code gravi_data_erase_x(gravi_data *self, int pos)
Erase an extension by its position.
cpl_error_code gravi_data_append(gravi_data *first, const gravi_data *second, int force)
Append a gravi_data into another existing one.
Definition gravi_data.c:308
cpl_error_code gravi_data_save_new(gravi_data *self, cpl_frameset *allframes, const char *filename, const char *suffix, const cpl_parameterlist *parlist, cpl_frameset *usedframes, cpl_frame *frame, const char *recipe, cpl_propertylist *applist, const char *proCatg)
Save a gravi data in a CPL-complian FITS file.
Definition gravi_data.c:925
cpl_propertylist * gravi_data_get_plist_x(gravi_data *self, int i)
Get the propertylist of an extension by position.
int gravi_data_get_size(const gravi_data *self)
Get the number of extension in a gravi_data.
Definition gravi_data.c:828
cpl_error_code gravi_data_copy_ext(gravi_data *output, gravi_data *input, const char *name)
Copy extensions from one data to another.
cpl_error_code gravi_data_dump(gravi_data *self)
Dump the overall structure of a gravi_data in stdout.
Definition gravi_data.c:796
cpl_error_code gravi_data_copy_ext_insname(gravi_data *output, gravi_data *input, const char *name, const char *insname)
Copy extensions from one data to another.
gravi_data * gravi_data_load_rawframe_ext(cpl_frame *frame, cpl_frameset *used_frameset, const char *extensions_regexp)
Load a RAW FITS file and create a gravi_data from specified extensions.
Definition gravi_data.c:760
cpl_error_code gravi_data_check_consistency(gravi_data *data)
Verify the integrity of RAW data.
cpl_table * gravi_data_get_table_x(gravi_data *self, int i)
Get the table of an extension by position.
void gravi_data_delete(gravi_data *self)
Delete a gravi data.
Definition gravi_data.c:146
int gravi_param_get_bool(const cpl_parameterlist *parlist, const char *name)
Definition gravi_dfs.c:1532
int gravi_param_get_bool_default(const cpl_parameterlist *parlist, const char *name, int def)
Definition gravi_dfs.c:1482
const char * gravi_param_get_string_default(const cpl_parameterlist *parlist, const char *name, const char *def)
Definition gravi_dfs.c:1494
const char * gravi_pfits_get_insname(const cpl_propertylist *plist)
cpl_propertylist * gravi_plist_get_oifits_keywords(cpl_propertylist *header)
Create OIFITS keywords to satisfy standar.
const char * gravi_pfits_get_pola_mode(const cpl_propertylist *plist, int type_data)
cpl_error_code gravi_pfits_add_check(cpl_propertylist *header, const char *msg)
Add a QC.CHECK keyword to the header.
int gravi_pfits_get_extension_type(const cpl_propertylist *plist)
const char * gravi_pfits_get_spec_res(const cpl_propertylist *plist)
double gravi_pfits_get_dit_sc(const cpl_propertylist *plist)
const char * gravi_pfits_get_resolution(const cpl_propertylist *plist)
double gravi_pfits_get_time_sc(const cpl_propertylist *header, cpl_size row)
Time of the middle of the SC exposure row in [us], counted from PRC.ACQ.START.
cpl_error_code gravi_pfits_add_pipe_build(cpl_propertylist *header)
Add the ESO PRO REC# PIPE LAST_BUILD in header.
const char * gravi_pfits_get_extname(const cpl_propertylist *plist)
cpl_error_code gravi_msg_warning(const char *component, const char *msg)
cpl_propertylist * extra_primary_hdr
Definition gravi_data.c:70
cpl_table ** exts_tbs
Definition gravi_data.c:69
cpl_propertylist ** exts_hdrs
Definition gravi_data.c:67
cpl_propertylist * primary_hdr
Definition gravi_data.c:65
cpl_imagelist ** exts_imgl
Definition gravi_data.c:68