GRAVI Pipeline Reference Manual 1.9.3
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
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 (cpl_table_has_column(detector_table, "LEFT") )
1291 {
1292 bias_method = "MASKED_MEDIAN_PER_COLUMN";
1293 cpl_msg_info (cpl_func, "New data format found. "
1294 "Using MASKED_MEDIAN_PER_COLUMNM bias method");
1295 }
1296 else
1297 {
1298 bias_method = "MEDIAN";
1299 cpl_msg_info (cpl_func, "Old data format found. "
1300 "Using MEDIAN bias method");
1301 }
1302 /* Case --bias-method=MASKED_MEDIAN_PER_COLUMN */
1303 if ( !strcmp (bias_method, "MASKED_MEDIAN_PER_COLUMN")) {
1304
1305 /* gravi_msg_warning ("FIXME","Bias method MASKED_MEDIAN_PER_COLUMN is experimental"); */
1306
1307 /* Build the mask of supposedly illuminated pixels */
1308 cpl_mask * mask;
1309 mask = gravi_data_create_bias_mask (detector_table, nx, ny);
1310
1311 /* Save the mask in data */
1312 cpl_image * mask_img = cpl_image_new_from_mask (mask);
1313 gravi_data_add_img (data, NULL, "BIAS_MASK_SC", mask_img);
1314
1315 /* Loop on frames */
1316 for (cpl_size f = 0; f < nframe; f++) {
1317 cpl_image * frame = cpl_imagelist_get (imglist, f);
1318
1319 /* Get the overal shape in the vertical direction
1320 by the mean of bias pixels. To help the median.
1321 This is still not tested */
1322 // cpl_size nbias_x = 4;
1323 // cpl_image * collapse_x;
1324 // collapse_x = gravi_image_collapse_median_x (frame, nbias_x + 1, nx - nbias_x);
1325 // cpl_image_subtract_scalar (collapse_x, cpl_image_get_median (collapse_x));
1326
1327 /* Remove this value to all pixels of the line */
1328 // gravi_image_subtract_collapse (frame, collapse_x, 1);
1329 // CPLCHECK_MSG ("Cannot remove x shape");
1330
1331 /* Set the illuminated pixels as 'bad pixels', store
1332 the current bad-pixel map in case it exists */
1333 cpl_mask * thismask = cpl_mask_duplicate (mask);
1334 cpl_mask * bpm = cpl_image_set_bpm (frame, thismask);
1335 FREE (cpl_mask_delete, bpm);
1336
1337 /* Compute median along the y direction */
1338 cpl_image * collapse_y;
1339 collapse_y = cpl_image_collapse_median_create (frame, 0, 0, 0);
1340
1341 /* Set back the bpm immediately, otherwise following
1342 operations are not running on masked pixels */
1343 thismask = cpl_image_set_bpm (frame, bpm);
1344 FREE (cpl_mask_delete, thismask);
1345
1346 /* Remove this value to all pixels of the column */
1347 gravi_image_subtract_collapse (frame, collapse_y, 0);
1348
1349 /* Re-add the crude bias shape in the y direction. Ideally we
1350 would like to remove it entirely, but the SNR is too low.
1351 This is still not tested */
1352 // cpl_image_multiply_scalar (mean_collapse_x, -1.0);
1353 // gravi_image_subtract_collapse (frame, mean_collapse_x, 1);
1354
1355 /* For QC */
1356 cpl_vector_set (bias_list, f, cpl_image_get_mean (collapse_y));
1357
1358 /* Delete data */
1359 // FREE (cpl_image_delete, collapse_x);
1360 FREE (cpl_image_delete, collapse_y);
1361
1362 CPLCHECK_MSG ("Cannot remove the bias");
1363 } /* End loop on frames */
1364
1365 FREE (cpl_mask_delete, mask);
1366 }
1367 /* Case HIGH spectral resolution and
1368 * --bias-method=MEDIAN_PER_COLUMN */
1369 else if ( !strcmp(resolution, "HIGH") && !strcmp (bias_method,
1370 "MEDIAN_PER_COLUMN")) {
1371 /* TODO High - the n first lines of Image is bias
1372 * Use the median of the bias-pixel
1373 * per column !! not correct should do like for MED and LOW */
1374
1375 gravi_msg_warning ("FIXME","Remove bias per column is experimental (HIGH)");
1376
1377 cpl_vector * bias = cpl_vector_new (nx);
1378 cpl_vector * bias_column = cpl_vector_new (n_bias_line*2);
1379
1380 /* Loop on frames */
1381 for (cpl_size f = 0; f < nframe; f++) {
1382 cpl_image * frame = cpl_imagelist_get (imglist, f);
1383
1384 /* Loop on columns */
1385 for (cpl_size x = 0; x < nx; x++) {
1386 cpl_size bias_index=0;
1387
1388 /* Get the bias pixels of the first lines */
1389 for (cpl_size y = 0; y < n_bias_line; y++) {
1390 double value = cpl_image_get (frame, x+1, y+1, &nv);
1391 cpl_vector_set (bias_column, bias_index++, value);
1392 CPLCHECK_MSG ("Cannot get the bias pixels");
1393 }
1394
1395 /* Get the bias pixels of the last lines */
1396 for (cpl_size y = 0; y < n_bias_line; y++) {
1397 double value = cpl_image_get (frame, x+1, ny-y, &nv);
1398 cpl_vector_set (bias_column, bias_index++, value);
1399 CPLCHECK_MSG ("Cannot get the bias pixels");
1400 }
1401
1402 /* Compute the bias of this column, and save it */
1403 double bias_med = cpl_vector_get_median (bias_column);
1404 cpl_vector_set (bias, x, bias_med);
1405
1406 /* Remove the bias from this column */
1407 for (cpl_size y = 0; y < ny; y++) {
1408 double value = cpl_image_get (frame, x+1, y+1, &nv);
1409 cpl_image_set (frame, x+1, y+1, value - bias_med);
1410 CPLCHECK_MSG ("Cannot set the bias corrected pixels");
1411 }
1412 } /* End loop on columns */
1413
1414 /* Remove the median of bias pixels to image */
1415 double bias_mean = cpl_vector_get_mean (bias);
1416 cpl_vector_set (bias_list, f, bias_mean);
1417 }
1418 FREE (cpl_vector_delete, bias);
1419 FREE (cpl_vector_delete, bias_column);
1420 }
1421 /* Case HIGH spectral resolution
1422 * and --bias-method=MEDIAN */
1423 else if ( !strcmp(resolution, "HIGH") ) {
1424 /* High Resolution - the first 4 columns
1425 * are for bias. FIXME: make sure this is also true in
1426 * in HIGH-COMBINED */
1427
1428 cpl_vector * bias = cpl_vector_new (nx_bias_hr * ny);
1429
1430 /* Loop on frames */
1431 for (cpl_size f = 0; f < nframe; f++) {
1432 cpl_image * frame = cpl_imagelist_get (imglist, f);
1433
1434 /* Get the bias pixels */
1435 for (cpl_size x = 0; x < nx_bias_hr; x++)
1436 for (cpl_size y = 0; y < ny; y++) {
1437 cpl_vector_set (bias, x * ny + y, cpl_image_get (frame, x+1, y+1, &nv));
1438 CPLCHECK_MSG ("Cannot get the bias pixels");
1439 }
1440
1441 /* Remove the median of bias pixels to image */
1442 double bias_med = cpl_vector_get_median (bias);
1443 cpl_vector_set (bias_list, f, bias_med);
1444 cpl_image_subtract_scalar (frame, bias_med);
1445 CPLCHECK_MSG ("Cannot subtract bias");
1446 }
1447 FREE (cpl_vector_delete, bias);
1448 }
1449 /* Case LOW or MEDIUM spectral resolution
1450 * and --bias-method=MEDIAN_PER_COLUMN */
1451 else if ( !strcmp (bias_method,
1452 "MEDIAN_PER_COLUMN")) {
1453 /* Low and Medium - the n_bias_line between
1454 * each region is bias. Use the median of the bias-pixel
1455 * per column !!*/
1456
1457 gravi_msg_warning ("FIXME","Remove bias per column is experimental (LOW, MEDIUM)");
1458
1459 cpl_vector * bias = cpl_vector_new (nx);
1460// cpl_vector * bias_column = cpl_vector_new (nreg);
1461 cpl_vector * bias_column = cpl_vector_new ((nreg-1)*n_bias_line);
1462 cpl_vector * bias_coord = cpl_vector_new ((nreg-1)*n_bias_line);
1463
1464 /* Loop on frames */
1465 for (cpl_size f = 0; f < nframe; f++) {
1466 cpl_image * frame = cpl_imagelist_get (imglist, f);
1467
1468 /* Loop on columns */
1469 for (cpl_size x = 0; x < nx; x++) {
1470 cpl_size bias_index=0;
1471
1472 /* Get the bias pixels of this column */
1473/* commented to try a new implementation
1474 for (cpl_size y = 0; y < nreg; y++) {
1475 double value = cpl_image_get (frame, x+1, (y+1)*ny_reg_mr+1, &nv);
1476 cpl_vector_set (bias_column, y, value);
1477 CPLCHECK_MSG ("Cannot get the bias pixels");
1478 }
1479*/
1480 for (cpl_size reg = 0; reg < nreg-1; reg++) {
1481 int starty=gravi_data_get_dark_pos(detector_table, reg)-n_bias_line/2;
1482 for (cpl_size y = 0; y < n_bias_line; y++){
1483 double value = cpl_image_get (frame, x+1, starty+y+1, &nv);
1484 cpl_vector_set (bias_column, bias_index, value);
1485 cpl_vector_set (bias_coord, bias_index++, starty+y);
1486 }
1487 CPLCHECK_MSG ("Cannot get the bias pixels");
1488 }
1489
1490 /* Compute the bias of this column, and save it */
1491 double bias_med = gravi_vector_get_mean_clip (bias_column, 0.05, 3.0);
1492 cpl_vector_set (bias, x, bias_med);
1493
1494 /* Remove the bias from this column */
1495 for (cpl_size y = 0; y < ny; y++) {
1496 double value = cpl_image_get (frame, x+1, y+1, &nv);
1497 cpl_image_set (frame, x+1, y+1, value - bias_med);
1498 CPLCHECK_MSG ("Cannot set the bias corrected pixels");
1499 }
1500 } /* End loop on columns */
1501
1502 /* Remove the median of bias pixels to image */
1503 double bias_mean = cpl_vector_get_mean (bias);
1504 cpl_vector_set (bias_list, f, bias_mean);
1505 }
1506 FREE (cpl_vector_delete, bias);
1507 FREE (cpl_vector_delete, bias_column);
1508 }
1509 /* Case LOW or MEDIUM spectral resolution and
1510 * --bias-method=MEDIAN */
1511 else {
1512 /* Low and Medium - the first line of
1513 * each region is bias */
1514
1515 cpl_vector * bias = cpl_vector_new (nx * nreg);
1516
1517 /* Loop on frames */
1518 for (cpl_size f = 0; f < nframe; f++) {
1519 cpl_image * frame = cpl_imagelist_get (imglist, f);
1520
1521 /* Get the bias pixels */
1522 for (cpl_size x = 0; x < nx; x++)
1523 for (cpl_size y = 0; y < nreg; y++) {
1524 cpl_vector_set (bias, x * nreg + y, cpl_image_get (frame, x+1, (y+1)*ny_reg_mr+1, &nv));
1525 CPLCHECK_MSG ("Cannot get the bias pixels");
1526 }
1527
1528 /* Remove the median of bias pixels to image */
1529 double bias_med = cpl_vector_get_median (bias);
1530 cpl_vector_set (bias_list, f, bias_med);
1531 cpl_image_subtract_scalar (frame, bias_med);
1532 CPLCHECK_MSG ("Cannot subtract bias");
1533 }
1534 FREE (cpl_vector_delete, bias);
1535 }
1536
1537
1538 /* Re-install the median */
1539 //cpl_imagelist_add_image (imglist, median_img);
1540 //FREE (cpl_image_delete, median_img);
1541 //CPLCHECK_MSG ("Cannot add the median image");
1542
1543 /* Add some QC */
1544 cpl_propertylist_update_double (header, "ESO QC PIXBIAS AVG", cpl_vector_get_mean (bias_list));
1545 cpl_propertylist_set_comment (header, "ESO QC PIXBIAS AVG", "[adu] avg over the bias pixel");
1546
1547 cpl_propertylist_update_double (header, "ESO QC PIXBIAS RMS", cpl_vector_get_stdev (bias_list));
1548 cpl_propertylist_set_comment (header, "ESO QC PIXBIAS RMS", "[adu] rms over frames");
1549 cpl_vector_delete (bias_list);
1550
1552 return CPL_ERROR_NONE;
1553}
1554
1555/*----------------------------------------------------------------------------*/
1556
1557/* Return the first extension exactly matching EXTNAME=name */
1558inline static int _gravi_data_find (const gravi_data *self, const char *name)
1559{
1560 int ext = 0;
1561 while (ext < self->nb_ext){
1562 cpl_propertylist *p = self->exts_hdrs[ext];
1563 const char *key = cpl_propertylist_get_string (p, "EXTNAME");
1564 if (strcmp(key, name) == 0) break;
1565 ext ++;
1566 }
1567 return ext;
1568}
1569
1570
1571/*---------------------------------------------------------------------------*/
1585/*---------------------------------------------------------------------------*/
1586
1588 gravi_data * input,
1589 const char * name,
1590 const char * insname)
1591{
1592 cpl_ensure_code (output, CPL_ERROR_NULL_INPUT);
1593 cpl_ensure_code (input, CPL_ERROR_NULL_INPUT);
1594 cpl_ensure_code (name, CPL_ERROR_NULL_INPUT);
1595 cpl_ensure_code (insname, CPL_ERROR_NULL_INPUT);
1596
1597 int n = gravi_data_get_size (input);
1598 for (int j = 0; j < n; j++){
1599
1600 cpl_propertylist * plist = gravi_data_get_plist_x (input, j);
1601
1602 if (!cpl_propertylist_has (plist, "EXTNAME")) continue;
1603 if (!cpl_propertylist_has (plist, "INSNAME")) continue;
1604
1605 const char * plist_name = gravi_pfits_get_extname (plist);
1606 const char * plist_insname = gravi_pfits_get_insname (plist);
1607
1608 CPLCHECK_MSG ("Cannot get input data");
1609
1610 if (plist_name == NULL) continue;
1611
1612 if (!(strcmp (plist_name, name)) &&
1613 !(strcmp (plist_insname, insname))) {
1614 int type_data = gravi_pfits_get_extension_type (plist);
1615
1616 if (type_data == 2) {
1617 gravi_data_add_table (output, cpl_propertylist_duplicate (plist), NULL,
1618 cpl_table_duplicate (gravi_data_get_table_x (input, j)));
1619 }
1620 else if (type_data == 3) {
1621 gravi_data_add_cube (output, cpl_propertylist_duplicate (plist), NULL,
1622 cpl_imagelist_duplicate (gravi_data_get_cube_x (input, j)));
1623 }
1624
1625 CPLCHECK_MSG ("Cannot copy extension");
1626 }
1627 }
1628
1629 return CPL_ERROR_NONE;
1630}
1631
1632/*---------------------------------------------------------------------------*/
1645/*---------------------------------------------------------------------------*/
1646
1647cpl_error_code gravi_data_copy_ext_i (gravi_data * output,
1648 gravi_data * input,
1649 cpl_size num)
1650{
1651 cpl_ensure_code (output, CPL_ERROR_NULL_INPUT);
1652 cpl_ensure_code (input, CPL_ERROR_NULL_INPUT);
1653 cpl_ensure_code (num>=0, CPL_ERROR_ILLEGAL_INPUT);
1654 cpl_ensure_code (num<input->nb_ext, CPL_ERROR_ILLEGAL_INPUT);
1655
1656 cpl_propertylist * plist = gravi_data_get_plist_x (input, num);
1657 int type_data = gravi_pfits_get_extension_type (plist);
1658
1659 if (type_data == 2)
1660 {
1661 gravi_data_add_table (output, cpl_propertylist_duplicate (plist), NULL,
1662 cpl_table_duplicate (gravi_data_get_table_x (input, num)));
1663 }
1664 else if (type_data == 3)
1665 {
1666 gravi_data_add_cube (output, cpl_propertylist_duplicate (plist), NULL,
1667 cpl_imagelist_duplicate (gravi_data_get_cube_x (input, num)));
1668 }
1669
1670 CPLCHECK_MSG ("Cannot copy extension");
1671
1672 return CPL_ERROR_NONE;
1673}
1674
1675/*---------------------------------------------------------------------------*/
1688/*---------------------------------------------------------------------------*/
1689
1690cpl_error_code gravi_data_copy_ext (gravi_data * output,
1691 gravi_data * input,
1692 const char * name)
1693{
1694 cpl_ensure_code (output, CPL_ERROR_NULL_INPUT);
1695 cpl_ensure_code (input, CPL_ERROR_NULL_INPUT);
1696 cpl_ensure_code (name, CPL_ERROR_NULL_INPUT);
1697
1698 int n = gravi_data_get_size (input);
1699 for (int j = 0; j < n; j++){
1700
1701 cpl_propertylist * plist = gravi_data_get_plist_x (input, j);
1702 const char * plist_name = gravi_pfits_get_extname (plist);
1703
1704 CPLCHECK_MSG ("Cannot get input data");
1705
1706 if (plist_name == NULL) continue;
1707
1708 if (!(strcmp (plist_name, name))) {
1709 int type_data = gravi_pfits_get_extension_type (plist);
1710
1711 if (type_data == 2) {
1712 gravi_data_add_table (output, cpl_propertylist_duplicate (plist), NULL,
1713 cpl_table_duplicate (gravi_data_get_table_x (input, j)));
1714 }
1715 else if (type_data == 3) {
1716 gravi_data_add_cube (output, cpl_propertylist_duplicate (plist), NULL,
1717 cpl_imagelist_duplicate (gravi_data_get_cube_x (input, j)));
1718 }
1719
1720 CPLCHECK_MSG ("Cannot copy extension");
1721 }
1722 }
1723
1724 return CPL_ERROR_NONE;
1725}
1726
1727/*---------------------------------------------------------------------------*/
1739/*---------------------------------------------------------------------------*/
1740
1741cpl_error_code gravi_data_move_ext (gravi_data * output,
1742 gravi_data * input,
1743 const char * name)
1744{
1746 cpl_ensure_code (output, CPL_ERROR_NULL_INPUT);
1747 cpl_ensure_code (input, CPL_ERROR_NULL_INPUT);
1748 cpl_ensure_code (name, CPL_ERROR_NULL_INPUT);
1749
1750 int n = gravi_data_get_size (input);
1751
1752 int jnew = 0;
1753 for (int j = 0; j < n; j++){
1754
1755 cpl_propertylist * plist = gravi_data_get_plist_x (input, j);
1756 const char * plist_name = gravi_pfits_get_extname (plist);
1757 CPLCHECK_MSG ("Cannot get input");
1758
1759 /* Case we need to move this extension */
1760 if ( (plist_name!=NULL) &&
1761 !(strcmp (plist_name, name))) {
1762
1763 cpl_msg_info (cpl_func, "Move extension %s", plist_name);
1764 int type_data = gravi_pfits_get_extension_type (plist);
1765 if (type_data == 2) {
1766 gravi_data_add_table (output, plist, NULL,
1767 gravi_data_get_table_x (input, j));
1768 }
1769 else if (type_data == 3) {
1770 gravi_data_add_cube (output, plist, NULL,
1771 gravi_data_get_cube_x (input, j));
1772 }
1773 CPLCHECK_MSG ("Cannot move extension");
1774
1775 } else {
1776
1777 /* Move pointer in the input */
1778 input->exts_hdrs[jnew] = input->exts_hdrs[j];
1779 input->exts_imgl[jnew] = input->exts_imgl[j];
1780 input->exts_tbs[jnew] = input->exts_tbs[j];
1781 jnew ++;
1782 }
1783
1784 } /* End loop on extension */
1785
1786 /* Cleanup input further away */
1787 input->nb_ext = jnew;
1788 for (int j = input->nb_ext; j < GRAVI_DATA_SIZE; j++) {
1789 input->exts_hdrs[j] = NULL;
1790 input->exts_imgl[j] = NULL;
1791 input->exts_tbs[j] = NULL;
1792 }
1793
1795 return CPL_ERROR_NONE;
1796}
1797
1798/*---------------------------------------------------------------------------*/
1806/*---------------------------------------------------------------------------*/
1807
1808int gravi_data_has_extension (gravi_data * raw_calib, const char * ext_name)
1809{
1810 cpl_ensure (raw_calib, CPL_ERROR_NULL_INPUT, 0);
1811 cpl_ensure (ext_name, CPL_ERROR_NULL_INPUT, 0);
1812
1813 int test = 1;
1814 int ext = _gravi_data_find (raw_calib, ext_name);
1815
1816 if (ext == raw_calib->nb_ext) {
1817 test = 0;
1818 }
1819
1820 return test;
1821}
1822
1823/*---------------------------------------------------------------------------*/
1831/*---------------------------------------------------------------------------*/
1832
1833int gravi_data_has_type (gravi_data * self, const char * type)
1834{
1835 cpl_ensure (self, CPL_ERROR_NULL_INPUT, -1);
1836 cpl_ensure (type, CPL_ERROR_NULL_INPUT, -1);
1837 cpl_ensure (strlen (type)>1, CPL_ERROR_ILLEGAL_INPUT, -1);
1838
1839 int counter = 0;
1840
1841 /* Loop on extension */
1842 for (int ext = 0; ext < gravi_data_get_size (self) ; ext ++) {
1843
1844 cpl_propertylist * plist = gravi_data_get_plist_x (self, ext);
1845
1846 /* Check if EXTNAME or INSNAME contains the 'type'
1847 * Warning that the number of extension is changed in the loop */
1848 if ( (cpl_propertylist_has (plist, "INSNAME") &&
1849 strstr (gravi_pfits_get_insname (plist), type) ) ||
1850 (cpl_propertylist_has (plist, "EXTNAME") &&
1851 strstr (gravi_pfits_get_extname (plist), type) ) )
1852 {
1853 cpl_msg_debug (cpl_func,"Find '%s' ", gravi_pfits_get_extname (plist));
1854 counter ++;
1855 }
1856 }
1857 return counter;
1858}
1859
1860/*---------------------------------------------------------------------------*/
1874/*---------------------------------------------------------------------------*/
1875
1876cpl_propertylist * gravi_data_get_plist_x (gravi_data* self, int i)
1877{
1878 cpl_ensure (self, CPL_ERROR_NULL_INPUT, NULL);
1879 cpl_ensure (i>=0, CPL_ERROR_ILLEGAL_INPUT, NULL);
1880 cpl_ensure (i<self->nb_ext, CPL_ERROR_ILLEGAL_INPUT, NULL);
1881
1882 return self->exts_hdrs[i];
1883}
1884
1885/*---------------------------------------------------------------------------*/
1899/*---------------------------------------------------------------------------*/
1900
1901cpl_table * gravi_data_get_table_x (gravi_data* self, int i)
1902{
1903 cpl_ensure (self, CPL_ERROR_NULL_INPUT, NULL);
1904 cpl_ensure (i>=0, CPL_ERROR_ILLEGAL_INPUT, NULL);
1905 cpl_ensure (i<self->nb_ext, CPL_ERROR_ILLEGAL_INPUT, NULL);
1906
1907 return self->exts_tbs[i];
1908}
1909
1910/*---------------------------------------------------------------------------*/
1924/*---------------------------------------------------------------------------*/
1925
1926cpl_imagelist * gravi_data_get_cube_x (gravi_data* self, int i)
1927{
1928 cpl_ensure (self, CPL_ERROR_NULL_INPUT, NULL);
1929 cpl_ensure (i>=0, CPL_ERROR_ILLEGAL_INPUT, NULL);
1930 cpl_ensure (i<self->nb_ext, CPL_ERROR_ILLEGAL_INPUT, NULL);
1931
1932 return self->exts_imgl[i];
1933}
1934
1935/*---------------------------------------------------------------------------*/
1950/*---------------------------------------------------------------------------*/
1951
1953 const char * extname,
1954 const char * insname)
1955{
1956 cpl_ensure (self, CPL_ERROR_NULL_INPUT, NULL);
1957 cpl_ensure (extname, CPL_ERROR_NULL_INPUT, NULL);
1958 cpl_ensure (insname, CPL_ERROR_NULL_INPUT, NULL);
1959
1960 int nb_ext = self->nb_ext;
1961 int pos = -1;
1962 for (int i = 0; i < nb_ext; i++){
1963
1964 if (cpl_propertylist_has (self->exts_hdrs[i], "INSNAME")){
1965 if ((!strcmp (gravi_pfits_get_insname (self->exts_hdrs[i]), insname)) &&
1966 (!strcmp (gravi_pfits_get_extname (self->exts_hdrs[i]), extname))){
1967 pos = i;
1968 break;
1969 }
1970 }
1971 }
1972
1973 if (pos < 0){
1974 cpl_msg_warning(cpl_func, "The extention %s doesn't exist "
1975 "with the insname %s",
1976 extname, insname);
1977 return NULL;
1978 }
1979
1980 return self->exts_tbs[pos];
1981}
1982
1983/*---------------------------------------------------------------------------*/
1999/*---------------------------------------------------------------------------*/
2000
2001cpl_propertylist * gravi_data_get_oi_plist (gravi_data * self,
2002 const char * extname,
2003 const char * insname)
2004{
2005 cpl_ensure (self, CPL_ERROR_NULL_INPUT, NULL);
2006 cpl_ensure (extname, CPL_ERROR_NULL_INPUT, NULL);
2007 cpl_ensure (insname, CPL_ERROR_NULL_INPUT, NULL);
2008
2009 int nb_ext = self->nb_ext;
2010 int pos = -1;
2011 for (int i = 0; i < nb_ext; i++){
2012 if (cpl_propertylist_has (self->exts_hdrs[i], "INSNAME")){
2013 if ((!strcmp (gravi_pfits_get_insname (self->exts_hdrs[i]), insname)) &&
2014 (!strcmp (gravi_pfits_get_extname (self->exts_hdrs[i]), extname))){
2015 pos = i;
2016 break;
2017 }
2018 }
2019 }
2020
2021 if (pos < -1){
2022 cpl_msg_warning(cpl_func, "The extention %s doesn't exist "
2023 "with the insname %s",
2024 extname, insname);
2025 return NULL;
2026 }
2027
2028 return self->exts_hdrs[pos];
2029}
2030
2031/*---------------------------------------------------------------------------*/
2047/*---------------------------------------------------------------------------*/
2048
2049cpl_propertylist * gravi_data_get_plist (gravi_data * self,
2050 const char * extname)
2051{
2052 cpl_ensure (self, CPL_ERROR_NULL_INPUT, NULL);
2053 cpl_ensure (extname, CPL_ERROR_NULL_INPUT, NULL);
2054
2055 if (!strcmp(extname, GRAVI_PRIMARY_HDR_EXT))
2056 return self->primary_hdr;
2057
2058 int pos = _gravi_data_find(self, extname);
2059
2060 cpl_ensure (pos<self->nb_ext, CPL_ERROR_ILLEGAL_INPUT, NULL);
2061
2062 return self->exts_hdrs[pos];
2063}
2064
2065/*---------------------------------------------------------------------------*/
2075{
2076 cpl_ensure (self, CPL_ERROR_NULL_INPUT, NULL);
2077 return self->extra_primary_hdr;
2078}
2079
2080/*---------------------------------------------------------------------------*/
2094/*---------------------------------------------------------------------------*/
2095
2096cpl_table * gravi_data_get_table (gravi_data* self, const char * extname)
2097{
2098 cpl_ensure (self, CPL_ERROR_NULL_INPUT, NULL);
2099 cpl_ensure (extname, CPL_ERROR_NULL_INPUT, NULL);
2100
2101 int pos = _gravi_data_find(self, extname);
2102
2103 cpl_ensure (pos<self->nb_ext, CPL_ERROR_ILLEGAL_INPUT, NULL);
2104
2105 if ((self->exts_tbs[pos] == NULL) ||
2106 (gravi_pfits_get_extension_type (self->exts_hdrs[pos]) != 2)){
2107 cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
2108 "No BINTABLE at the extension %s", extname);
2109 return NULL;
2110 }
2111
2112 return self->exts_tbs[pos];
2113}
2114
2115/*---------------------------------------------------------------------------*/
2129/*---------------------------------------------------------------------------*/
2130
2131cpl_imagelist * gravi_data_get_cube (gravi_data* self, const char * extname)
2132{
2133 cpl_ensure (self, CPL_ERROR_NULL_INPUT, NULL);
2134 cpl_ensure (extname, CPL_ERROR_NULL_INPUT, NULL);
2135
2136 int pos = _gravi_data_find(self, extname);
2137
2138 cpl_ensure (pos<self->nb_ext, CPL_ERROR_ILLEGAL_INPUT, NULL);
2139
2140 if ((self->exts_imgl[pos] == NULL) ||
2141 (gravi_pfits_get_extension_type (self->exts_hdrs[pos]) != 3)){
2142 cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
2143 "No IMAGE at the extension %s", extname);
2144 return NULL;
2145 }
2146
2147 return self->exts_imgl[pos];
2148}
2149
2150/*----------------------------------------------------------------------------*/
2159/*----------------------------------------------------------------------------*/
2160
2161cpl_error_code gravi_data_erase_x (gravi_data * self, int pos)
2162{
2163 cpl_ensure_code (self, CPL_ERROR_NULL_INPUT);
2164 cpl_ensure_code (pos>-1, CPL_ERROR_ILLEGAL_INPUT);
2165
2166 /* Delete data or move pointers */
2167 int comp = 0;
2168 for (int i = 0; i < self->nb_ext; i++) {
2169 if (i != pos){
2170 self->exts_hdrs[comp] = self->exts_hdrs[i];
2171 self->exts_tbs[comp] = self->exts_tbs[i];
2172 self->exts_imgl[comp] = self->exts_imgl[i];
2173 comp++;
2174 }
2175 else{
2176 if ((gravi_pfits_get_extension_type (self->exts_hdrs[pos]) == 2))
2177 FREE (cpl_table_delete, self->exts_tbs[i]);
2178 else if (gravi_pfits_get_extension_type (self->exts_hdrs[pos]) == 3)
2179 FREE (cpl_imagelist_delete, self->exts_imgl[i]);
2180 CPLCHECK_MSG("Cannot delete data");
2181
2182 FREE (cpl_propertylist_delete, self->exts_hdrs[i]);
2183 CPLCHECK_MSG("Cannot delete header");
2184 }
2185 }
2186
2187 /* Cleanup further away */
2188 for (int i = comp ; i<GRAVI_DATA_SIZE; i++) {
2189 self->exts_hdrs[i] = NULL;
2190 self->exts_tbs[i] = NULL;
2191 self->exts_imgl[i] = NULL;
2192 }
2193
2194 /* Change number of extension */
2195 self->nb_ext = comp;
2196
2197 return CPL_ERROR_NONE;
2198}
2199
2200/*----------------------------------------------------------------------------*/
2210/*----------------------------------------------------------------------------*/
2211
2212cpl_error_code gravi_data_erase (gravi_data * self, const char * extname)
2213{
2214 cpl_ensure_code (self, CPL_ERROR_NULL_INPUT);
2215 cpl_ensure_code (extname, CPL_ERROR_NULL_INPUT);
2216
2217 /* Find the position of the property list */
2218 int pos = _gravi_data_find(self, extname);
2219
2220 /* Check pos */
2221 if (pos == self->nb_ext) {
2222 cpl_msg_info (cpl_func,"Cannot delete '%s' (not found)",extname);
2223 return CPL_ERROR_NONE;
2224 } else {
2225 cpl_msg_info (cpl_func,"Delete '%s' found in ext[%i] (over %i) ",extname, pos, self->nb_ext);
2226 }
2227
2228 /* Erase */
2229 gravi_data_erase_x (self, pos);
2230
2231 CPLCHECK_MSG ("Cannot erase this extension name");
2232 return CPL_ERROR_NONE;
2233}
2234
2235/*----------------------------------------------------------------------------*/
2245/*----------------------------------------------------------------------------*/
2246
2247cpl_error_code gravi_data_erase_type (gravi_data * self, const char * type)
2248{
2249 cpl_ensure_code (self, CPL_ERROR_NULL_INPUT);
2250 cpl_ensure_code (type, CPL_ERROR_NULL_INPUT);
2251 cpl_ensure_code (strlen (type)>1, CPL_ERROR_ILLEGAL_INPUT);
2252
2253 /* Loop on extension */
2254 for (int ext = 0; ext < gravi_data_get_size (self) ; ext ++) {
2255
2256 cpl_propertylist * plist = gravi_data_get_plist_x (self, ext);
2257
2258 /* Check if EXTNAME or INSNAME contains the 'type'
2259 * Warning that the number of extension is changed in the loop */
2260 if ( (cpl_propertylist_has (plist, "INSNAME") &&
2261 strstr (gravi_pfits_get_insname (plist), type) ) ||
2262 (cpl_propertylist_has (plist, "EXTNAME") &&
2263 strstr (gravi_pfits_get_extname (plist), type) ) )
2264 {
2265 cpl_msg_info (cpl_func,"Delete '%s' ", gravi_pfits_get_extname (plist));
2266 gravi_data_erase_x (self, ext);
2267 ext--;
2268
2269 CPLCHECK_MSG ("Cannot erase this type");
2270 }
2271 }
2272 return CPL_ERROR_NONE;
2273}
2274
2275/*----------------------------------------------------------------------------*/
2287/*----------------------------------------------------------------------------*/
2288
2289cpl_error_code gravi_data_add_table (gravi_data * self,
2290 cpl_propertylist * plist,
2291 const char * extname,
2292 cpl_table * table)
2293{
2294 cpl_ensure_code (self, CPL_ERROR_NULL_INPUT);
2295 cpl_ensure_code (table, CPL_ERROR_NULL_INPUT);
2296
2297 /* Set the header */
2298 if (plist == NULL) plist = cpl_propertylist_new ();
2299 if (extname != NULL) cpl_propertylist_update_string (plist, "EXTNAME", extname);
2300
2301 /* Add header */
2302 cpl_propertylist_update_string (plist, "XTENSION", "BINTABLE");
2303 self->exts_hdrs[self->nb_ext] = plist;
2304
2305 /* Add an EXTNAME to UNKNOWN */
2306 if (!cpl_propertylist_has(plist, "EXTNAME") ) {
2307 cpl_msg_error (cpl_func,"FIXME: set a table without EXTNAME !!");
2308 cpl_propertylist_update_string (plist, "EXTNAME", "UNKNOWN");
2309 }
2310
2311 /* OIFITS: add OI_REVN to OI_* tables */
2312 const char * plist_name = 0;
2313 if (cpl_propertylist_has (plist, "EXTNAME"))
2314 plist_name = gravi_pfits_get_extname (plist);
2315
2316 if (plist_name && !(strcmp(plist_name, GRAVI_OI_ARRAY_EXT) &&
2317 strcmp (plist_name, GRAVI_OI_TARGET_EXT) &&
2318 strcmp (plist_name, GRAVI_OI_WAVELENGTH_EXT) &&
2319 strcmp (plist_name, GRAVI_OI_T3_EXT) &&
2320 strcmp (plist_name, GRAVI_OI_VIS2_EXT) &&
2321 strcmp (plist_name, GRAVI_OI_VIS_EXT))) {
2322 cpl_propertylist_update_int (plist, "OI_REVN", 2);
2323 }
2324 if (plist_name && !(strcmp(plist_name, GRAVI_OI_FLUX_EXT))) {
2325 cpl_propertylist_update_int (plist, "OI_REVN", 1);
2326 }
2327 /* OIFITS: check is saved as short */
2329
2330 self->exts_tbs[self->nb_ext] = table;
2331 self->exts_imgl[self->nb_ext] = NULL;
2332
2333 self->nb_ext ++;
2334
2335 CPLCHECK_MSG ("Cannot add the table");
2336 return CPL_ERROR_NONE;
2337}
2338
2339/*----------------------------------------------------------------------------*/
2351/*----------------------------------------------------------------------------*/
2352
2353cpl_error_code gravi_data_add_cube (gravi_data * self,
2354 cpl_propertylist * plist,
2355 const char * extname,
2356 cpl_imagelist * imglist)
2357{
2358
2359 cpl_ensure_code (self, CPL_ERROR_NULL_INPUT);
2360 cpl_ensure_code (imglist, CPL_ERROR_NULL_INPUT);
2361
2362 if (plist == NULL) plist = cpl_propertylist_new ();
2363 if (extname != NULL) cpl_propertylist_update_string (plist, "EXTNAME", extname);
2364
2365 /* Add header */
2366 self->exts_hdrs[self->nb_ext] = plist;
2367 cpl_propertylist_update_string (self->exts_hdrs[self->nb_ext],"XTENSION", "IMAGE");
2368
2369 /* Add data */
2370 self->exts_imgl[self->nb_ext] = (imglist);
2371 self->exts_tbs[self->nb_ext] = NULL;
2372
2373 self->nb_ext ++;
2374
2375 CPLCHECK_MSG ("Cannot add the cube");
2376 return CPL_ERROR_NONE;
2377
2378}
2379
2380/*----------------------------------------------------------------------------*/
2392/*----------------------------------------------------------------------------*/
2393
2394cpl_error_code gravi_data_add_img (gravi_data * self,
2395 cpl_propertylist * plist,
2396 const char * extname,
2397 cpl_image * image) {
2398
2399 cpl_ensure_code (self, CPL_ERROR_NULL_INPUT);
2400 cpl_ensure_code (image, CPL_ERROR_NULL_INPUT);
2401
2402 if (plist == NULL) plist = cpl_propertylist_new ();
2403 if (extname != NULL) cpl_propertylist_update_string (plist, "EXTNAME", extname);
2404
2405 /* Add header */
2406 self->exts_hdrs[self->nb_ext] = plist;
2407 cpl_propertylist_update_string (self->exts_hdrs[self->nb_ext],"XTENSION", "IMAGE");
2408
2409 /* Convert to imagelist */
2410 cpl_imagelist * imglist = cpl_imagelist_new ();
2411 cpl_imagelist_set (imglist, image, 0);
2412
2413 /* Add data */
2414 self->exts_imgl[self->nb_ext] = (imglist);
2415 self->exts_tbs[self->nb_ext] = NULL;
2416
2417 self->nb_ext ++;
2418
2419 CPLCHECK_MSG ("Cannot add the image");
2420 return CPL_ERROR_NONE;
2421}
2422
2423/*---------------------------------------------------------------------------*/
2433/*---------------------------------------------------------------------------*/
2434
2436{
2438 cpl_ensure_code (data, CPL_ERROR_NULL_INPUT);
2439
2440 cpl_table * new_oimet_table;
2441
2442 /* Loop on extension in file ?? */
2443 for (int i = 0; i < gravi_data_get_size (data); i++) {
2444
2445 /* Keep OI_ARRAY, OI_TARGET and OI_VIS_ACQ */
2446 cpl_propertylist * plist = gravi_data_get_plist_x (data, i);
2447 const char * plist_name = gravi_pfits_get_extname (plist);
2448 if (!(strcmp (plist_name, GRAVI_OI_ARRAY_EXT)) ||
2449 !(strcmp (plist_name, GRAVI_OI_TARGET_EXT)) ||
2450 !(strcmp (plist_name, GRAVI_OI_WAVELENGTH_EXT)) ||
2451 !(strcmp (plist_name, GRAVI_OI_VIS_ACQ_EXT)) ) {
2452 cpl_msg_debug (cpl_func,"NAME: %s kept", plist_name);
2453 continue;
2454 }
2455
2456 /* Keep all INSNAME_SC and ACQ camera mean image */
2457 if (cpl_propertylist_has (plist, "INSNAME") &&
2458 ( (!strcmp (gravi_pfits_get_insname (plist), INSNAME_SC_P1)) ||
2460 (!strcmp (gravi_pfits_get_insname (plist), INSNAME_SC)) ||
2461 (!strcmp (gravi_pfits_get_insname (plist), INSNAME_ACQ)) )) {
2462 cpl_msg_debug (cpl_func,"NAME: %s kept", plist_name);
2463 continue;
2464 }
2465
2466 if (!(strcmp (plist_name, GRAVI_OI_VIS_MET_EXT)))
2467 {
2468
2469 cpl_table * old_oimet_table = gravi_data_get_table_x (data, i);
2470
2471 CPLCHECK_MSG ("Cannot read OI_MET table");
2472 cpl_size length = cpl_table_get_nrow (old_oimet_table);
2473 new_oimet_table = cpl_table_new(length);
2474
2475 CPLCHECK_MSG ("Cannot create new OI_MET table");
2476 int nb_names = 6;
2477 const char *names[] = {"TIME", "PHASE_FC_DRS", "PHASE_TELFC_CORR", "OPD_TELFC_CORR_XY","OPD_FC_CORR","OPD_TELFC_MCORR"};
2478 for (int j =0; j<nb_names;j++)
2479 {
2480 cpl_msg_info(cpl_func,"duplicating columns %s",names[j]);
2481 cpl_table_duplicate_column (new_oimet_table, names[j], old_oimet_table, names[j]);
2482 CPLCHECK_MSG ("Failed at duplicating column to new OI_VIS_MET table");
2483 }
2484 }
2485
2486 /* Delete */
2487 cpl_msg_debug (cpl_func,"NAME: %s deleted", plist_name);
2488 FREE (cpl_propertylist_delete, data->exts_hdrs[i]);
2489 FREE (cpl_table_delete, data->exts_tbs[i]);
2490 FREE (cpl_imagelist_delete, data->exts_imgl[i]);
2491 }
2492
2493 /* storing new OI_MET table */
2494 if (new_oimet_table != NULL)
2495 gravi_data_add_table (data, NULL, GRAVI_OI_VIS_MET_EXT, new_oimet_table);
2496
2497 /* Loop on extension in file to move the
2498 * extension consecutively */
2499 int j = 0;
2500 for (int i = 0; i < gravi_data_get_size (data); i++) {
2501 /* This one exist, copy in last place */
2502 if (data->exts_hdrs[i] || data->exts_tbs[i] || data->exts_imgl[i]) {
2503 if ( i!=j ) {
2504 data->exts_hdrs[j] = data->exts_hdrs[i]; data->exts_hdrs[i] = NULL;
2505 data->exts_tbs[j] = data->exts_tbs[i]; data->exts_tbs[i] = NULL;
2506 data->exts_imgl[j] = data->exts_imgl[i]; data->exts_imgl[i] = NULL;
2507 }
2508 j++;
2509 }
2510 }
2511
2512 data->nb_ext = j;
2513
2515 return CPL_ERROR_NONE;
2516}
2517
2518/*---------------------------------------------------------------------------*/
2529/*---------------------------------------------------------------------------*/
2530
2532{
2534 cpl_ensure_code (data, CPL_ERROR_NULL_INPUT);
2535
2536 char qc_msg[80];
2537
2538 /* Add the QC parameter, start with 0 warning */
2539 cpl_propertylist * header = gravi_data_get_header (data);
2540 cpl_propertylist_append_int (header, "ESO QC CHECK FLAGS", 0);
2541
2542 /* Check number of extensions */
2543 int nb_ext = 12;
2544 const char *extname[] = {"ARRAY_DESCRIPTION", "ARRAY_GEOMETRY", "OPTICAL_TRAIN",
2545 "IMAGING_DATA_ACQ", "ACQ_ABS_REF_POSITION",
2546 "OPDC", "FDDL", "METROLOGY",
2547 "IMAGING_DATA_SC","IMAGING_DETECTOR_SC",
2548 "IMAGING_DATA_FT","IMAGING_DETECTOR_FT"};
2549
2550 for (int ext = 0; ext< nb_ext; ext++) {
2551
2552 /* Check if existing */
2553 if ( !gravi_data_has_extension (data, extname[ext]) ) {
2554 sprintf (qc_msg, "%s is missing", extname[ext]);
2555 gravi_pfits_add_check (header, qc_msg);
2556 continue;
2557 }
2558
2559 cpl_propertylist * plist;
2560 plist = gravi_data_get_plist (data, extname[ext]);
2561
2562 /* Check the frame counter if it has one */
2563 if (cpl_propertylist_has (plist, "ESO DET FRAM NO")) {
2564 int frame_no = cpl_propertylist_get_int (plist, "ESO DET FRAM NO");
2565 int naxis_3 = cpl_propertylist_get_int (plist, "NAXIS3");
2566 if ( frame_no != naxis_3) {
2567 sprintf (qc_msg, "%s is missing DITs", extname[ext]);
2568 gravi_pfits_add_check (header, qc_msg);
2569 }
2570 }
2571 }
2572
2573 CPLCHECK_MSG ("Cannot check consistency of tables...");
2574
2575
2576
2577 /* Build the time of the first and last frame of SC in
2578 * [us] with respect to PRC.ACQ.START. We need RMN data over
2579 * the entire first and last DITs of SC */
2580 int ndit = cpl_propertylist_get_int (header, "ESO DET2 NDIT");
2581 double scdit = gravi_pfits_get_dit_sc (header);
2582 double start_sc = gravi_pfits_get_time_sc (header, 0) - scdit/2. * 1e6;
2583 double end_sc = gravi_pfits_get_time_sc (header, ndit-1) + scdit/2. * 1e6;
2584
2585 cpl_msg_debug (cpl_func,"start = %8.0f and end = %10.0f (%s [us] from PCR.ACQ.START)",
2586 start_sc, end_sc, "SC");
2587
2588 /* Check the TIME content of RMN tables */
2589 int nb_ext_rmn = 4;
2590 const char *ext_rmn[] = {"OPDC", "FDDL", "METROLOGY", "IMAGING_DATA_FT"};
2591
2592 for (int ext = 0; ext< nb_ext_rmn; ext++) {
2593
2594 /* Get this RMN table */
2595 if (!gravi_data_has_extension (data, ext_rmn[ext])) continue;
2596 cpl_table * table = gravi_data_get_table (data, ext_rmn[ext]);
2597
2598 /* Get the first and last time sample, in [us] */
2599 double min_table = cpl_table_get_column_min (table, "TIME");
2600 double max_table = cpl_table_get_column_max (table, "TIME");
2601
2602 cpl_msg_debug (cpl_func,"start = %8.0f and end = %10.0f (%s [us] from PCR.ACQ.START)",
2603 min_table, max_table, ext_rmn[ext]);
2604
2605 /* Check if it covers the SC data */
2606 if ( min_table > start_sc) {
2607 sprintf (qc_msg, "%s starts *after* the science exposure", ext_rmn[ext]);
2608 gravi_pfits_add_check (header, qc_msg);
2609 }
2610 if ( max_table < end_sc) {
2611 sprintf (qc_msg, "%s finish *before* the science exposure", ext_rmn[ext]);
2612 gravi_pfits_add_check (header, qc_msg);
2613 }
2614
2615 /* Get data */
2616 cpl_size nrow = cpl_table_get_nrow (table);
2617 int * time = cpl_table_get_data_int (table, "TIME");
2618 CPLCHECK_MSG ("Cannot get data");
2619
2620 /* Compute the median step, over the first 10000 samples */
2621 cpl_size nsamp = CPL_MIN (10000, nrow-1);
2622 cpl_array * delta = cpl_array_new (nsamp, CPL_TYPE_INT);
2623 for (cpl_size row = 0; row < nsamp ; row++) {
2624 cpl_array_set_int (delta, row, time[row+1] - time[row]);
2625 }
2626 double median_delta = cpl_array_get_median (delta);
2627 FREE (cpl_array_delete, delta);
2628
2629 /* Check missing samples (delta > 1.5 * median) */
2630 int nwrong = 0;
2631 int nwrong_warning = 0;
2632 if (!strcmp (ext_rmn[ext], "OPDC")) nwrong_warning = 2;
2633 for (cpl_size row = 0; row < nrow-1 ; row++) {
2634 double current_delta = time[row+1] - time[row];
2635 if (current_delta > 1.5 * median_delta) nwrong ++;
2636 }
2637 if (nwrong > nwrong_warning) {
2638 sprintf (qc_msg, "%s has %i wrong steps", ext_rmn[ext], nwrong);
2639 gravi_pfits_add_check (header, qc_msg);
2640 }
2641
2642 } /* End loop on RMN tables */
2643
2644 CPLCHECK_MSG ("Cannot check consistency of RMN tables...");
2645
2647 return CPL_ERROR_NONE;
2648}
2649
2650/*---------------------------------------------------------------------------*/
2662/*---------------------------------------------------------------------------*/
2663
2664cpl_table ** gravi_data_get_oiwave_tables (gravi_data * data, int type_data, int npol)
2665{
2666 cpl_ensure (data, CPL_ERROR_NULL_INPUT, NULL);
2667 cpl_ensure (npol == 1 || npol == 2, CPL_ERROR_ILLEGAL_INPUT, NULL);
2668 cpl_ensure (type_data == GRAVI_SC || type_data == GRAVI_FT, CPL_ERROR_ILLEGAL_INPUT, NULL);
2669
2670 cpl_table ** oiwave_tables = cpl_calloc (npol, sizeof(cpl_table *));
2671 for (int pol = 0; pol < npol; pol++)
2672 oiwave_tables[pol] = gravi_data_get_oi_wave (data, type_data, pol, npol);
2673
2674 return oiwave_tables;
2675}
2676
2677
2678
#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:95
#define GRAVI_OI_VIS_ACQ_EXT
Definition: gravi_pfits.h:89
#define GRAVI_OI_VIS_MET_EXT
Definition: gravi_pfits.h:88
#define GRAVI_OI_TARGET_EXT
Definition: gravi_pfits.h:86
#define GRAVI_OI_ARRAY_EXT
Definition: gravi_pfits.h:83
#define INSNAME_SC_P2
Definition: gravi_pfits.h:195
#define GRAVI_SC
Definition: gravi_pfits.h:165
#define GRAVI_OI_VIS_EXT
Definition: gravi_pfits.h:92
#define INSNAME_SC
Definition: gravi_pfits.h:197
#define INSNAME_ACQ
Definition: gravi_pfits.h:199
#define GRAVI_OI_FLUX_EXT
Definition: gravi_pfits.h:93
#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:94
#define INSNAME_SC_P1
Definition: gravi_pfits.h:194
#define GRAVI_IMAGING_DETECTOR_SC_EXT
Definition: gravi_pfits.h:81
#define GRAVI_FT
Definition: gravi_pfits.h:166
#define GRAVI_OI_WAVELENGTH_EXT
Definition: gravi_pfits.h:91
#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:1921
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:2642
int gravi_table_are_equal(cpl_table *first, cpl_table *second)
Check if two tables have the same content.
Definition: gravi_cpl.c:1585
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.
Definition: gravi_data.c:2212
cpl_propertylist * gravi_data_get_oi_plist(gravi_data *self, const char *extname, const char *insname)
Get the propertylist from EXTNAME and INSNAME.
Definition: gravi_data.c:2001
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.
Definition: gravi_data.c:2353
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
Definition: gravi_data.c:1102
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
Definition: gravi_data.c:1131
cpl_imagelist * gravi_data_get_cube_x(gravi_data *self, int i)
Get the cube of an extension by position.
Definition: gravi_data.c:1926
cpl_propertylist * gravi_data_get_extra_primary_header(gravi_data *self)
Get the propertylist for additional keywords to the primary header.
Definition: gravi_data.c:2074
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.
Definition: gravi_data.c:2435
cpl_propertylist * gravi_data_get_plist(gravi_data *self, const char *extname)
Get the propertylist from EXTNAME.
Definition: gravi_data.c:2049
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.
Definition: gravi_data.c:2289
static int _gravi_data_find(const gravi_data *self, const char *name)
Definition: gravi_data.c:1558
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.
Definition: gravi_data.c:2394
cpl_error_code gravi_data_erase_type(gravi_data *self, const char *type)
Erase all extension related to an instrument (SC, FT, MET...)
Definition: gravi_data.c:2247
cpl_error_code gravi_data_copy_ext_i(gravi_data *output, gravi_data *input, cpl_size num)
Copy extensions from one data to another.
Definition: gravi_data.c:1647
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.
Definition: gravi_data.c:1232
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.
Definition: gravi_data.c:2664
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.
Definition: gravi_data.c:2131
int gravi_data_has_extension(gravi_data *raw_calib, const char *ext_name)
Check if data has extension with given EXTNAME.
Definition: gravi_data.c:1808
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'.
Definition: gravi_data.c:1833
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.
Definition: gravi_data.c:2096
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.
Definition: gravi_data.c:1952
cpl_error_code gravi_remove_cosmicrays_sc(cpl_imagelist *imglist_sc)
Remove cosmic rays via filtering through images.
Definition: gravi_calib.c:2661
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.
Definition: gravi_data.c:1741
cpl_error_code gravi_data_erase_x(gravi_data *self, int pos)
Erase an extension by its position.
Definition: gravi_data.c:2161
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.
Definition: gravi_data.c:1876
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.
Definition: gravi_data.c:1690
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.
Definition: gravi_data.c:1587
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.
Definition: gravi_data.c:2531
cpl_table * gravi_data_get_table_x(gravi_data *self, int i)
Get the table of an extension by position.
Definition: gravi_data.c:1901
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:1537
int gravi_param_get_bool_default(const cpl_parameterlist *parlist, const char *name, int def)
Definition: gravi_dfs.c:1487
const char * gravi_param_get_string_default(const cpl_parameterlist *parlist, const char *name, const char *def)
Definition: gravi_dfs.c:1499
const char * gravi_pfits_get_insname(const cpl_propertylist *plist)
Definition: gravi_pfits.c:915
cpl_propertylist * gravi_plist_get_oifits_keywords(cpl_propertylist *header)
Create OIFITS keywords to satisfy standar.
Definition: gravi_pfits.c:1004
const char * gravi_pfits_get_pola_mode(const cpl_propertylist *plist, int type_data)
Definition: gravi_pfits.c:169
cpl_error_code gravi_pfits_add_check(cpl_propertylist *header, const char *msg)
Add a QC.CHECK keyword to the header.
Definition: gravi_pfits.c:1643
int gravi_pfits_get_extension_type(const cpl_propertylist *plist)
Definition: gravi_pfits.c:271
const char * gravi_pfits_get_spec_res(const cpl_propertylist *plist)
Definition: gravi_pfits.c:162
double gravi_pfits_get_dit_sc(const cpl_propertylist *plist)
Definition: gravi_pfits.c:664
const char * gravi_pfits_get_resolution(const cpl_propertylist *plist)
Definition: gravi_pfits.c:155
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.
Definition: gravi_pfits.c:710
cpl_error_code gravi_pfits_add_pipe_build(cpl_propertylist *header)
Add the ESO PRO REC# PIPE LAST_BUILD in header.
Definition: gravi_pfits.c:1683
const char * gravi_pfits_get_extname(const cpl_propertylist *plist)
Definition: gravi_pfits.c:140
cpl_error_code gravi_msg_warning(const char *component, const char *msg)
Definition: gravi_utils.c:127
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