FORS Pipeline Reference Manual  4.12.5
fors_dfs.c
1 /* $Id: fors_dfs.c,v 1.47 2013-10-09 15:58:42 cgarcia Exp $
2  *
3  * This file is part of the FORS library
4  * Copyright (C) 2002-2010 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 /*
22  * $Author: cgarcia $
23  * $Date: 2013-10-09 15:58:42 $
24  * $Revision: 1.47 $
25  * $Name: not supported by cvs2svn $
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 
32 #include <fors_dfs.h>
33 
34 #include <fors_utils.h>
35 #include <fors_image.h>
36 #include <fors_pfits.h>
37 
38 #include <cpl.h>
39 
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <ctype.h>
43 #include <stdbool.h>
44 #include <string.h>
45 #include <unistd.h>
46 
47 /*----------------------------------------------------------------------------*/
54 /*----------------------------------------------------------------------------*/
55 
58 #define WCS_KEYS "^((CRVAL|CRPIX|CTYPE|CDELT)[0-9]|RADECSYS|CD[0-9]_[0-9])$"
59 
60 /*------------------------------------------------------------------------------
61  Prototypes
62  -----------------------------------------------------------------------------*/
63 /*------------------------------------------------------------------------------
64  Implementation
65  -----------------------------------------------------------------------------*/
66 
67 /*----------------------------------------------------------------------------*/
68 /*----------------------------------------------------------------------------*/
69 static char *strlower(char *s)
70 {
71 
72  char *t = s;
73 
74  while (*t) {
75  *t = tolower(*t);
76  t++;
77  }
78 
79  return s;
80 
81 }
82 
83 /*----------------------------------------------------------------------------*/
84 /*----------------------------------------------------------------------------*/
85 char *dfs_generate_filename(const char *category)
86 {
87  char *filename = cpl_calloc(strlen(category) + 6, sizeof(char));
88 
89  strlower(strcpy(filename, category));
90  strcat(filename, ".fits");
91 
92  return filename;
93 }
94 
95 /*----------------------------------------------------------------------------*/
106 /*----------------------------------------------------------------------------*/
107 static void
108 errorstate_dump_one(unsigned self, unsigned first, unsigned last)
109 {
110 
111  const cpl_boolean is_reverse = first > last ? CPL_TRUE : CPL_FALSE;
112  const unsigned newest = is_reverse ? first : last;
113  const unsigned oldest = is_reverse ? last : first;
114  const char * revmsg = is_reverse ? " in reverse order" : "";
115 
116  /* Cannot use internal CPL functions
117  cx_assert( oldest <= self );
118  cx_assert( newest >= self ); */
119 
120  if (newest == 0) {
121  cpl_msg_info(cpl_func, "No error(s) to dump");
122  /* cx_assert( oldest == 0); */
123  } else {
124  /* cx_assert( oldest > 0);
125  cx_assert( newest >= oldest); */
126  if (self == first) {
127  if (oldest == 1) {
128  cpl_msg_debug(cpl_func, "Dumping all %u error(s)%s:", newest,
129  revmsg);
130  } else {
131  cpl_msg_error(cpl_func, "Dumping the %u most recent error(s) "
132  "out of a total of %u errors%s:",
133  newest - oldest + 1, newest, revmsg);
134  }
135  }
136 
137  const char *message_from_cpl = cpl_error_get_message();
138 
139  if (message_from_cpl == NULL) {
140  /* This should never happen */
141  cpl_msg_error(cpl_func, "Unspecified error");
142  }
143 
144  /* Skip the standard (non-informative) CPL message string,
145  which usually terminates with ': '
146 
147  If no user-defined error message is given,
148  print the CPL standard message
149  */
150  while (*message_from_cpl != '\0' && *message_from_cpl != ':') {
151  message_from_cpl += 1;
152  }
153 
154  if (*message_from_cpl != '\0') {
155  message_from_cpl += 1;
156 
157  if (*message_from_cpl == ' ') message_from_cpl++;
158 
159  if (*message_from_cpl != '\0') {
160  /* Still something left of the string */
161  cpl_msg_error(cpl_func, "%s [%s]", message_from_cpl,
162  cpl_error_get_where());
163  }
164  else {
165  cpl_msg_error(cpl_func, "%s [%s]",
166  cpl_error_get_message(), cpl_error_get_where());
167  }
168  }
169  else {
170  /* Found no ':' is CPL message string */
171  cpl_msg_error(cpl_func, "%s [%s]",
172  cpl_error_get_message(), cpl_error_get_where());
173  }
174  }
175 
176  return;
177 }
178 
179 
180 /*----------------------------------------------------------------------------*/
190 /*----------------------------------------------------------------------------*/
191 void fors_begin(cpl_frameset *frames,
192  const char *description_short)
193 {
194  cpl_msg_info(cpl_func, "%s", PACKAGE_STRING);
195  cpl_msg_info(cpl_func, "%s", description_short);
196 
197  fors_dfs_set_groups(frames);
198  cpl_msg_info(cpl_func, "Input frame%s:",
199  cpl_frameset_get_size(frames) != 1 ? "s" : "");
200  fors_frameset_print(frames);
201 
202  return;
203 }
204 
205 /*----------------------------------------------------------------------------*/
218 /*----------------------------------------------------------------------------*/
219 int fors_end(const cpl_frameset *frames, cpl_errorstate before_exec)
220 {
221  if (cpl_error_get_code() == CPL_ERROR_NONE) {
222 
223  const cpl_frame *f;
224 
225  cpl_msg_info(cpl_func, "Product frame%s:",
226  cpl_frameset_get_size(frames) != 1 ? "s" : "");
227 
228  for (f = cpl_frameset_get_first_const(frames);
229  f != NULL;
230  f = cpl_frameset_get_next_const(frames)) {
231  if (cpl_frame_get_group(f) == CPL_FRAME_GROUP_PRODUCT) {
232  fors_frame_print(f);
233  }
234  }
235 
236  /* Shut up EsoRex */
237  //cpl_msg_set_level(CPL_MSG_WARNING);
238  return 0;
239  }
240  else {
241 
242  cpl_errorstate_dump(before_exec, CPL_FALSE, errorstate_dump_one);
243 
244  return 1;
245  }
246 }
247 
248 #undef cleanup
249 #define cleanup
250 /*----------------------------------------------------------------------------*/
255 /*----------------------------------------------------------------------------*/
256 void
257 fors_dfs_set_groups(cpl_frameset * set)
258 {
259  cpl_frame *f;
260 
261  assure( set != NULL, return, NULL );
262 
263  for (f = cpl_frameset_get_first(set);
264  f != NULL;
265  f = cpl_frameset_get_next(set)) {
266 
267  const char *tag = cpl_frame_get_tag(f);
268 
269  if (tag != NULL) {
270  if (strcmp(tag, BIAS ) == 0 ||
271  strcmp(tag, DARK ) == 0 ||
272  strcmp(tag, SCREEN_FLAT_IMG ) == 0 ||
273  strcmp(tag, SKY_FLAT_IMG ) == 0 ||
274  strcmp(tag, STANDARD_IMG ) == 0 ||
275  strcmp(tag, "LAMP_PMOS" ) == 0 ||
276  strcmp(tag, "SCREEN_FLAT_PMOS") == 0 ||
277  strcmp(tag, "STANDARD_PMOS" ) == 0 ||
278  strcmp(tag, "SCIENCE_PMOS" ) == 0 ||
279  strcmp(tag, "SCIENCE_MOS" ) == 0 ||
280  strcmp(tag, "SCIENCE_MXU" ) == 0 ||
281  strcmp(tag, "SCIENCE_LSS" ) == 0 ||
282  strcmp(tag, "STANDARD_MOS" ) == 0 ||
283  strcmp(tag, "STANDARD_MXU" ) == 0 ||
284  strcmp(tag, "STANDARD_LSS" ) == 0 ||
285  strcmp(tag, SCIENCE_IMG ) == 0 ||
286  strcmp(tag, "SCREEN_FLAT_MXU" ) == 0 ||
287  strcmp(tag, "SCREEN_FLAT_MOS" ) == 0 ||
288  strcmp(tag, "SCREEN_FLAT_LSS" ) == 0 ) {
289  cpl_frame_set_group(f, CPL_FRAME_GROUP_RAW);
290  }
291  else if (strcmp(tag, MASTER_BIAS ) == 0 ||
292  strcmp(tag, MASTER_DARK ) == 0 ||
293  strcmp(tag, MASTER_SCREEN_FLAT_IMG ) == 0 ||
294  strcmp(tag, MASTER_SKY_FLAT_IMG ) == 0 ||
295  strcmp(tag, ALIGNED_PHOT ) == 0 ||
296  strcmp(tag, "MASTER_NORM_FLAT_PMOS" ) == 0 ||
297  strcmp(tag, "DISP_COEFF_PMOS" ) == 0 ||
298  strcmp(tag, "CURV_COEFF_PMOS" ) == 0 ||
299  strcmp(tag, "SLIT_LOCATION_PMOS" ) == 0 ||
300  strcmp(tag, "MASTER_NORM_FLAT_MOS" ) == 0 ||
301  strcmp(tag, "MASTER_NORM_FLAT_MXU" ) == 0 ||
302  strcmp(tag, "MASTER_NORM_FLAT_LSS" ) == 0 ||
303  strcmp(tag, "SLIT_LOCATION_MOS" ) == 0 ||
304  strcmp(tag, "SLIT_LOCATION_MXU" ) == 0 ||
305  strcmp(tag, "SLIT_LOCATION_LSS" ) == 0 ||
306  strcmp(tag, "CURV_COEFF_MOS" ) == 0 ||
307  strcmp(tag, "CURV_COEFF_MXU" ) == 0 ||
308  strcmp(tag, "CURV_COEFF_LSS" ) == 0 ||
309  strcmp(tag, "DISP_COEFF_MOS" ) == 0 ||
310  strcmp(tag, "DISP_COEFF_MXU" ) == 0 ||
311  strcmp(tag, "DISP_COEFF_LSS" ) == 0 ||
312  /* static calibration */
313  strcmp(tag, FLX_STD_IMG ) == 0 ||
314  strcmp(tag, "MASTER_LINECAT" ) == 0 ||
315  strcmp(tag, "MASTER_DISTORTION_TABLE" ) == 0 ||
316  strcmp(tag, "RETARDER_WAVEPLATE_CHROMATISM") == 0 ||
317  strcmp(tag, "GRISM_TABLE" ) == 0 ||
318  strcmp(tag, "STD_PMOS_TABLE" ) == 0 ||
319  strcmp(tag, PHOT_TABLE ) == 0) {
320  cpl_frame_set_group(f, CPL_FRAME_GROUP_CALIB);
321  }
322  else {
323  cpl_msg_warning(cpl_func, "Unrecognized frame tag: '%s'",
324  tag);
325  }
326  }
327  }
328 
329  return;
330 }
331 
332 /*----------------------------------------------------------------------------*/
333 #undef cleanup
334 #define cleanup
335 
343 /*----------------------------------------------------------------------------*/
344 const char *
345 fors_dfs_pipeline_version(const cpl_propertylist *header,
346  const char **instrument_version)
347 {
348  const char *instrume = NULL;
349 
350  instrume = cpl_propertylist_get_string(header,
351  FORS_PFITS_INSTRUME);
352  assure( !cpl_error_get_code(), return NULL,
353  "Missing keyword %s in input header", FORS_PFITS_INSTRUME);
354 
355  assure( strlen(instrume) >= 5, return NULL,
356  "%s keyword must be 'fors1' or 'fors2', not '%s'",
357  FORS_PFITS_INSTRUME, instrume);
358 
359  assure( instrume[4] == '1' || instrume[4] == '2', return NULL,
360  "Unrecognized %s: %s", FORS_PFITS_INSTRUME, instrume);
361 
362  if (instrument_version != NULL) {
363  *instrument_version = cpl_sprintf("%s", instrume);
364  }
365 
366  return cpl_sprintf("fors%c/%s", instrume[4], PACKAGE_VERSION);
367 }
368 
369 /*----------------------------------------------------------------------------*/
391 /*----------------------------------------------------------------------------*/
392 int dfs_get_parameter_int(cpl_parameterlist *parlist, const char *name,
393  const cpl_table *defaults)
394 {
395  const char *func = "dfs_get_parameter_int";
396 
397  const char *alias;
398  cpl_parameter *param;
399 
400 
401  if (parlist == NULL) {
402  cpl_msg_error(func, "Missing input parameter list");
403  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
404  return 0;
405  }
406 
407  if (name == NULL) {
408  cpl_msg_error(func, "Missing input parameter name");
409  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
410  return 0;
411  }
412 
413  param = cpl_parameterlist_find(parlist, name);
414 
415  if (param == NULL) {
416  cpl_msg_error(func, "Wrong parameter name: %s", name);
417  cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
418  return 0;
419  }
420 
421  if (cpl_parameter_get_type(param) != CPL_TYPE_INT) {
422  cpl_msg_error(func, "Unexpected type for parameter "
423  "\"%s\": it should be integer", name);
424  cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
425  return 0;
426  }
427 
428  alias = cpl_parameter_get_alias(param, CPL_PARAMETER_MODE_CLI);
429 
430 // if (defaults && cpl_parameter_get_default_flag(param) == 0) {
431  if (defaults &&
432  cpl_parameter_get_default_int(param) == cpl_parameter_get_int(param)) {
433 
434  if (cpl_table_has_column(defaults, alias)) {
435  if (cpl_table_get_column_type(defaults, alias) != CPL_TYPE_INT) {
436  cpl_msg_error(func, "Unexpected type for GRISM_TABLE "
437  "column \"%s\": it should be integer", alias);
438  cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
439  return 0;
440  }
441  if (cpl_table_is_valid(defaults, alias, 0)) {
442  cpl_parameter_set_int(param, cpl_table_get_int(defaults,
443  alias, 0, NULL));
444  }
445  else {
446  cpl_msg_error(func, "Invalid parameter value in table "
447  "column \"%s\"", alias);
448  cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
449  return 0;
450  }
451  }
452  else {
453  cpl_msg_warning(func, "Parameter \"%s\" not found in GRISM_TABLE "
454  "- using recipe default", alias);
455  }
456  }
457 
458  cpl_msg_info(func, "%s:", alias);
459  cpl_msg_info(func, "%s: %d",
460  cpl_parameter_get_help(param), cpl_parameter_get_int(param));
461 
462  return cpl_parameter_get_int(param);
463 
464 }
465 
466 /*----------------------------------------------------------------------------*/
488 /*----------------------------------------------------------------------------*/
489 double dfs_get_parameter_double(cpl_parameterlist *parlist,
490  const char *name, const cpl_table *defaults)
491 {
492  const char *func = "dfs_get_parameter_double";
493 
494  const char *alias;
495  cpl_parameter *param;
496 
497 
498  if (parlist == NULL) {
499  cpl_msg_error(func, "Missing input parameter list");
500  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
501  return 0;
502  }
503 
504  if (name == NULL) {
505  cpl_msg_error(func, "Missing input parameter name");
506  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
507  return 0;
508  }
509 
510  param = cpl_parameterlist_find(parlist, name);
511 
512  if (param == NULL) {
513  cpl_msg_error(func, "Wrong parameter name: %s", name);
514  cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
515  return 0;
516  }
517 
518  if (cpl_parameter_get_type(param) != CPL_TYPE_DOUBLE) {
519  cpl_msg_error(func, "Unexpected type for parameter "
520  "\"%s\": it should be double", name);
521  cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
522  return 0;
523  }
524 
525  alias = cpl_parameter_get_alias(param, CPL_PARAMETER_MODE_CLI);
526 
527 // if (defaults && cpl_parameter_get_default_flag(param) == 0) {
528  if (defaults &&
529  cpl_parameter_get_default_double(param) ==
530  cpl_parameter_get_double(param)) {
531 
532  if (cpl_table_has_column(defaults, alias)) {
533  if (cpl_table_get_column_type(defaults, alias) != CPL_TYPE_DOUBLE) {
534  cpl_msg_error(func, "Unexpected type for GRISM_TABL "
535  "column \"%s\": it should be double", alias);
536  cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
537  return 0;
538  }
539  if (cpl_table_is_valid(defaults, alias, 0)) {
540  cpl_parameter_set_double(param, cpl_table_get_double(defaults,
541  alias, 0, NULL));
542  }
543  else {
544  cpl_msg_error(func, "Invalid parameter value in table "
545  "column \"%s\"", alias);
546  cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
547  return 0;
548  }
549  }
550  else {
551  cpl_msg_warning(func, "Parameter \"%s\" not found in GRISM_TABLE "
552  "- using recipe default", alias);
553  }
554  }
555 
556  cpl_msg_info(func, "%s:", alias);
557  cpl_msg_info(func, "%s: %f",
558  cpl_parameter_get_help(param), cpl_parameter_get_double(param));
559 
560  return cpl_parameter_get_double(param);
561 
562 }
563 
564 /*----------------------------------------------------------------------------*/
586 /*----------------------------------------------------------------------------*/
587 const char *dfs_get_parameter_string(cpl_parameterlist *parlist,
588  const char *name,
589  const cpl_table *defaults)
590 {
591  const char *func = "dfs_get_parameter_string";
592 
593  const char *alias;
594  cpl_parameter *param;
595 
596 
597  if (parlist == NULL) {
598  cpl_msg_error(func, "Missing input parameter list");
599  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
600  return 0;
601  }
602 
603  if (name == NULL) {
604  cpl_msg_error(func, "Missing input parameter name");
605  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
606  return 0;
607  }
608 
609  param = cpl_parameterlist_find(parlist, name);
610 
611  if (param == NULL) {
612  cpl_msg_error(func, "Wrong parameter name: %s", name);
613  cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
614  return 0;
615  }
616 
617  if (cpl_parameter_get_type(param) != CPL_TYPE_STRING) {
618  cpl_msg_error(func, "Unexpected type for parameter "
619  "\"%s\": it should be string", name);
620  cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
621  return 0;
622  }
623 
624  alias = cpl_parameter_get_alias(param, CPL_PARAMETER_MODE_CLI);
625 
626 // if (defaults && cpl_parameter_get_default_flag(param) == 0) {
627  if (defaults &&
628  strcmp(cpl_parameter_get_default_string(param),
629  cpl_parameter_get_string(param)) == 0) {
630 
631  if (cpl_table_has_column(defaults, alias)) {
632  if (cpl_table_get_column_type(defaults, alias) != CPL_TYPE_STRING) {
633  cpl_msg_error(func, "Unexpected type for GRISM_TABLE "
634  "column \"%s\": it should be string", alias);
635  cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
636  return 0;
637  }
638  if (cpl_table_is_valid(defaults, alias, 0)) {
639  cpl_parameter_set_string(param, cpl_table_get_string(defaults,
640  alias, 0));
641  }
642  else {
643  cpl_msg_error(func, "Invalid parameter value in table "
644  "column \"%s\"", alias);
645  cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
646  return 0;
647  }
648  }
649  else {
650  cpl_msg_warning(func, "Parameter \"%s\" not found in GRISM_TABLE "
651  "- using recipe default", alias);
652  }
653  }
654 
655  cpl_msg_info(func, "%s:", alias);
656  cpl_msg_info(func, "%s: %s", cpl_parameter_get_help(param),
657  cpl_parameter_get_string(param));
658 
659  return cpl_parameter_get_string(param);
660 
661 }
662 
663 /*----------------------------------------------------------------------------*/
685 /*----------------------------------------------------------------------------*/
686 int dfs_get_parameter_bool(cpl_parameterlist *parlist, const char *name,
687  const cpl_table *defaults)
688 {
689  const char *func = "dfs_get_parameter_bool";
690 
691  const char *alias;
692  cpl_parameter *param;
693  int value;
694 
695 
696  if (parlist == NULL) {
697  cpl_msg_error(func, "Missing input parameter list");
698  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
699  return 0;
700  }
701 
702  if (name == NULL) {
703  cpl_msg_error(func, "Missing input parameter name");
704  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
705  return 0;
706  }
707 
708  param = cpl_parameterlist_find(parlist, name);
709 
710  if (param == NULL) {
711  cpl_msg_error(func, "Wrong parameter name: %s", name);
712  cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
713  return 0;
714  }
715 
716  if (cpl_parameter_get_type(param) != CPL_TYPE_BOOL) {
717  cpl_msg_error(func, "Unexpected type for parameter "
718  "\"%s\": it should be boolean", name);
719  cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
720  return 0;
721  }
722 
723  alias = cpl_parameter_get_alias(param, CPL_PARAMETER_MODE_CLI);
724 
725 // if (defaults && cpl_parameter_get_default_flag(param) == 0) {
726  if (defaults &&
727  cpl_parameter_get_default_bool(param) ==
728  cpl_parameter_get_bool(param)) {
729 
730  if (cpl_table_has_column(defaults, alias)) {
731  if (cpl_table_get_column_type(defaults, alias) != CPL_TYPE_INT) {
732  cpl_msg_error(func, "Unexpected type for GRISM_TABLE "
733  "column \"%s\": it should be integer", alias);
734  cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
735  return 0;
736  }
737  if (cpl_table_is_valid(defaults, alias, 0)) {
738  value = cpl_table_get_int(defaults, alias, 0, NULL);
739  if (value < 0 || value > 1) {
740  cpl_msg_error(func, "Illegal parameter value in table "
741  "column \"%s\": it should be either 0 or 1",
742  alias);
743  cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
744  return 0;
745  }
746  cpl_parameter_set_bool(param, value);
747  }
748  else {
749  cpl_msg_error(func, "Invalid parameter value in table "
750  "column \"%s\"", alias);
751  cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
752  return 0;
753  }
754  }
755  else {
756  cpl_msg_warning(func, "Parameter \"%s\" not found in GRISM_TABLE "
757  "- using recipe default", alias);
758  }
759  }
760 
761  value = cpl_parameter_get_bool(param);
762 
763  if (value) {
764  cpl_msg_info(func, "%s:", alias);
765  cpl_msg_info(func, "%s: TRUE", cpl_parameter_get_help(param));
766  }
767  else {
768  cpl_msg_info(func, "%s:", alias);
769  cpl_msg_info(func, "%s: FALSE", cpl_parameter_get_help(param));
770  }
771 
772  return value;
773 
774 }
775 
776 /*----------------------------------------------------------------------------*/
780 /*----------------------------------------------------------------------------*/
781 int dfs_get_parameter_bool_const(const cpl_parameterlist *parlist, const char *name)
782 {
783  return dfs_get_parameter_bool((cpl_parameterlist *)parlist, name, NULL);
784 }
785 
786 /*----------------------------------------------------------------------------*/
790 /*----------------------------------------------------------------------------*/
791 int dfs_get_parameter_int_const(const cpl_parameterlist *parlist, const char *name)
792 {
793  return dfs_get_parameter_int((cpl_parameterlist *)parlist, name, NULL);
794 }
795 
796 /*----------------------------------------------------------------------------*/
800 /*----------------------------------------------------------------------------*/
801 double dfs_get_parameter_double_const(const cpl_parameterlist *parlist, const char *name)
802 {
803  return dfs_get_parameter_double((cpl_parameterlist *)parlist, name, NULL);
804 }
805 
806 /*----------------------------------------------------------------------------*/
810 /*----------------------------------------------------------------------------*/
811 const char *dfs_get_parameter_string_const(const cpl_parameterlist *parlist, const char *name)
812 {
813  return dfs_get_parameter_string((cpl_parameterlist *)parlist, name, NULL);
814 }
815 
816 /*----------------------------------------------------------------------------*/
844 /*----------------------------------------------------------------------------*/
845 cpl_image *dfs_load_image(cpl_frameset *frameset, const char *category,
846  cpl_type type, int ext, int calib)
847 {
848  const char *func = "dfs_load_image";
849 
850  cpl_frame *frame = NULL;
851  cpl_image *image = NULL;
852 
853 
854  frame = cpl_frameset_find(frameset, category);
855 
856  if (frame) {
857  image = cpl_image_load(cpl_frame_get_filename(frame), type, 0, ext);
858  if (image == NULL) {
859  cpl_msg_error(cpl_error_get_where(),"%s", cpl_error_get_message());
860  cpl_msg_error(func, "Cannot load image %s",
861  cpl_frame_get_filename(frame));
862  }
863  else {
864  if (calib)
865  cpl_frame_set_group(frame, CPL_FRAME_GROUP_CALIB);
866  else
867  cpl_frame_set_group(frame, CPL_FRAME_GROUP_RAW);
868  }
869  }
870 
871  return image;
872 }
873 
874 /*----------------------------------------------------------------------------*/
900 /*----------------------------------------------------------------------------*/
901 cpl_table *dfs_load_table(cpl_frameset *frameset, const char *category, int ext)
902 {
903  const char *func = "dfs_load_table";
904 
905  cpl_frame *frame = NULL;
906  cpl_table *table = NULL;
907 
908 
909  frame = cpl_frameset_find(frameset, category);
910 
911  if (frame) {
912  table = cpl_table_load(cpl_frame_get_filename(frame), ext, 1);
913  if (table == NULL) {
914  cpl_msg_error(cpl_error_get_where(), "%s", cpl_error_get_message());
915  cpl_msg_error(func, "Cannot load table %s",
916  cpl_frame_get_filename(frame));
917  }
918  else
919  cpl_frame_set_group(frame, CPL_FRAME_GROUP_CALIB);
920  }
921 
922  return table;
923 }
924 
925 /*----------------------------------------------------------------------------*/
950 /*----------------------------------------------------------------------------*/
951 cpl_propertylist *dfs_load_header(cpl_frameset *frameset,
952  const char *category, int ext)
953 {
954  const char *func = "dfs_load_header";
955 
956  cpl_frame *frame = NULL;
957  cpl_propertylist *plist = NULL;
958 
959 
960  frame = cpl_frameset_find(frameset, category);
961 
962  if (frame) {
963  plist = cpl_propertylist_load(cpl_frame_get_filename(frame), ext);
964  if (plist == NULL) {
965  cpl_msg_error(cpl_error_get_where(), "%s", cpl_error_get_message());
966  cpl_msg_error(func, "Cannot load header from %s",
967  cpl_frame_get_filename(frame));
968  }
969  }
970 
971  return plist;
972 }
973 
974 /*----------------------------------------------------------------------------*/
981 /*----------------------------------------------------------------------------*/
982 static void
983 dfs_save(cpl_frameset *frameset, const void *object, fors_type type,
984  const char *category, cpl_propertylist *header,
985  const cpl_parameterlist *parlist, const char *recipename,
986  const cpl_frame *inherit_frame)
987 {
988  char *filename;
989  cpl_frame *frame;
990  cpl_propertylist *plist;
991  const char *version = NULL;
992  cpl_propertylist *raw_header = NULL;
993 
994 
995  if (category == NULL || frameset == NULL || object == NULL ||
996  inherit_frame == NULL) {
997  cpl_msg_error(cpl_error_get_where(), "%s", cpl_error_get_message());
998  cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
999  return;
1000  }
1001 
1002  if (type == FORS_TYPE_TABLE) {
1003  cpl_msg_debug(cpl_func, "Saving %s table to disk...", category);
1004  }
1005  else {
1006  cpl_msg_debug(cpl_func, "Saving %s image to disk...", category);
1007  }
1008 
1009  /* Read instrument version from raw frame */
1010  {
1011  const char *raw_filename =
1012  cpl_frame_get_filename(inherit_frame);
1013 
1014  raw_header = cpl_propertylist_load(raw_filename, 0);
1015  if (cpl_error_get_code() != CPL_ERROR_NONE) {
1016  cpl_msg_error(cpl_func, "Could not read %s primary header", raw_filename);
1017  return;
1018  }
1019 
1020  version = fors_dfs_pipeline_version(raw_header, NULL);
1021  cpl_propertylist_delete(raw_header);
1022 
1023  if (cpl_error_get_code() != CPL_ERROR_NONE) {
1024  cpl_msg_error(cpl_func, "Could not identify instrument version from %s header",
1025  raw_filename);
1026  return;
1027  }
1028  }
1029 
1030  filename = cpl_calloc(strlen(category) + 6, sizeof(char));
1031 
1032  strlower(strcpy(filename, category));
1033  strcat(filename, ".fits");
1034 
1035  frame = cpl_frame_new();
1036 
1037  cpl_frame_set_filename(frame, filename);
1038  cpl_frame_set_tag(frame, category);
1039  cpl_frame_set_type(frame, CPL_FRAME_TYPE_ANY);
1040  cpl_frame_set_group(frame, CPL_FRAME_GROUP_PRODUCT);
1041  cpl_frame_set_level(frame, CPL_FRAME_LEVEL_FINAL);
1042  if (cpl_error_get_code()) {
1043  cpl_msg_error(cpl_error_get_where(), "%s", cpl_error_get_message());
1044  cpl_msg_error(cpl_func, "Cannot initialise the product frame");
1045  cpl_frame_delete(frame);
1046  cpl_free(filename);
1047  cpl_free((void *)version);
1048  return;
1049  }
1050 
1051 
1052  /*
1053  * Produce DFS compliant FITS header for product
1054  */
1055 
1056  if (header == NULL)
1057  plist = cpl_propertylist_new();
1058  else
1059  plist = header;
1060 
1061  if (cpl_dfs_setup_product_header(plist, frame, frameset, parlist,
1062  recipename, version, "PRO-1.15",
1063  inherit_frame)) {
1064  cpl_msg_error(cpl_func, "Error found in %s: %s",
1065  cpl_error_get_where(), cpl_error_get_message());
1066  cpl_msg_error(cpl_func, "Problem with product %s FITS header definition",
1067  category);
1068  if (header == NULL)
1069  cpl_propertylist_delete(plist);
1070  cpl_frame_delete(frame);
1071  cpl_free(filename);
1072  cpl_free((void *)version);
1073  return;
1074  }
1075 
1076  cpl_free((void *)version);
1077 
1078 /* CPL3.0
1079  cpl_propertylist_erase_regexp(plist, "^ESO DET OUT1 OVSC*", 0);
1080  cpl_propertylist_erase_regexp(plist, "^ESO DET OUT1 PRSC*", 0);
1081 */
1082 /* CPL2.0 */
1083  cpl_propertylist_erase(plist, "ESO DET OUT1 OVSCX");
1084  cpl_propertylist_erase(plist, "ESO DET OUT1 PRSCX");
1085  cpl_propertylist_erase(plist, "ESO DET OUT1 OVSCY");
1086  cpl_propertylist_erase(plist, "ESO DET OUT1 PRSCY");
1087 
1088  /*
1089  * Write to disk
1090  */
1091 
1092  if (type == FORS_TYPE_IMAGE_ERR) {
1093  fors_image_save((fors_image *)object, plist, filename);
1094  }
1095  else if (type == FORS_TYPE_IMAGE) {
1096  cpl_image_save((cpl_image *)object, filename, CPL_BPP_IEEE_FLOAT, plist,
1097  CPL_IO_DEFAULT);
1098  }
1099  else {
1100  cpl_table_save((cpl_table *)object,
1101  plist, NULL, filename, CPL_IO_DEFAULT);
1102  }
1103 
1104  if (cpl_error_get_code() != CPL_ERROR_NONE) {
1105  cpl_msg_error(cpl_func, "Error found in %s: %s",
1106  cpl_error_get_where(), cpl_error_get_message());
1107  cpl_msg_error(cpl_func, "Cannot save product %s to disk", filename);
1108  if (header == NULL)
1109  cpl_propertylist_delete(plist);
1110  cpl_frame_delete(frame);
1111  cpl_free(filename);
1112  return;
1113  }
1114 
1115  if (header == NULL)
1116  cpl_propertylist_delete(plist);
1117 
1118  cpl_free(filename);
1119 
1120  cpl_frameset_insert(frameset, frame);
1121 
1122  return;
1123 }
1124 
1125 /*----------------------------------------------------------------------------*/
1146 /*----------------------------------------------------------------------------*/
1147 void
1148 fors_dfs_save_image(cpl_frameset *frameset, const cpl_image *image,
1149  const char *category, cpl_propertylist *header,
1150  const cpl_parameterlist *parlist, const char *recipename,
1151  const cpl_frame *inherit_frame)
1152 {
1153  dfs_save(frameset, image, FORS_TYPE_IMAGE,
1154  category, header,
1155  parlist, recipename,
1156  inherit_frame);
1157 }
1158 
1159 /*----------------------------------------------------------------------------*/
1181 /*----------------------------------------------------------------------------*/
1182 void
1183 fors_dfs_save_image_mask(cpl_frameset *frameset, const cpl_image *image,
1184  const cpl_image *mask, const char *category,
1185  cpl_propertylist *header,
1186  const cpl_parameterlist *parlist, const char *recipename,
1187  const cpl_frame *inherit_frame)
1188 {
1189  char *filename;
1190  cpl_propertylist * extension_header;
1191 
1192  dfs_save(frameset, image, FORS_TYPE_IMAGE,
1193  category, header,
1194  parlist, recipename,
1195  inherit_frame);
1196 
1197  extension_header = cpl_propertylist_new();
1198  cpl_propertylist_append_string(extension_header,
1199  "EXTNAME", "IMAGE.BPM");
1200 
1201  filename = cpl_calloc(strlen(category) + 6, sizeof(char));
1202 
1203  strlower(strcpy(filename, category));
1204  strcat(filename, ".fits");
1205 
1206  cpl_image_save(mask, filename, CPL_BPP_IEEE_FLOAT, extension_header,
1207  CPL_IO_EXTEND);
1208  cpl_propertylist_delete(extension_header);
1209 
1210 }
1211 
1212 /*----------------------------------------------------------------------------*/
1233 /*----------------------------------------------------------------------------*/
1234 void
1235 fors_dfs_save_image_err(cpl_frameset *frameset, const fors_image *image,
1236  const char *category, cpl_propertylist *header,
1237  const cpl_parameterlist *parlist, const char *recipename,
1238  const cpl_frame *inherit_frame)
1239 {
1240  dfs_save(frameset, image, FORS_TYPE_IMAGE_ERR,
1241  category, header,
1242  parlist, recipename,
1243  inherit_frame);
1244 }
1245 
1246 /*----------------------------------------------------------------------------*/
1269 /*----------------------------------------------------------------------------*/
1270 void
1271 fors_dfs_save_image_err_mask(cpl_frameset *frameset, const fors_image *image,
1272  const cpl_image *mask, const char *category,
1273  cpl_propertylist *header,
1274  const cpl_parameterlist *parlist, const char *recipename,
1275  const cpl_frame *inherit_frame)
1276 {
1277  char *filename;
1278  cpl_propertylist * extension_header;
1279 
1280  dfs_save(frameset, image, FORS_TYPE_IMAGE_ERR,
1281  category, header,
1282  parlist, recipename,
1283  inherit_frame);
1284 
1285  extension_header = cpl_propertylist_new();
1286  cpl_propertylist_append_string(extension_header,
1287  "EXTNAME", "IMAGE.BPM");
1288 
1289  filename = cpl_calloc(strlen(category) + 6, sizeof(char));
1290 
1291  strlower(strcpy(filename, category));
1292  strcat(filename, ".fits");
1293 
1294  cpl_image_save(mask, filename, CPL_BPP_IEEE_FLOAT, extension_header,
1295  CPL_IO_EXTEND);
1296  cpl_propertylist_delete(extension_header);
1297 }
1298 
1299 #undef cleanup
1300 #define cleanup \
1301 do { \
1302  cpl_propertylist_delete(wcs_header); \
1303 } while (0)
1304 
1309 void fors_dfs_add_wcs(cpl_propertylist *header, const cpl_frame *frame,
1310  const fors_setting *setting)
1311 {
1312  bool invert = false;
1313  int extension = 0;
1314 
1315  cpl_propertylist *wcs_header =
1316  cpl_propertylist_load_regexp(cpl_frame_get_filename(frame),
1317  extension, WCS_KEYS, invert);
1318 
1319  cpl_propertylist_copy_property_regexp(header, wcs_header, ".*", invert);
1320 
1321  double crpix1 = cpl_propertylist_get_double(header, FORS_PFITS_CRPIX1);
1322 
1323  assure( !cpl_error_get_code(), return,
1324  "Could not read %s from %s", FORS_PFITS_CRPIX1,
1325  cpl_frame_get_filename(frame));
1326 
1327  double crpix2 = cpl_propertylist_get_double(header, FORS_PFITS_CRPIX2);
1328 
1329  assure( !cpl_error_get_code(), return,
1330  "Could not read %s from %s", FORS_PFITS_CRPIX2,
1331  cpl_frame_get_filename(frame));
1332 
1333  cpl_propertylist_update_double(header, FORS_PFITS_CRPIX1,
1334  crpix1 - setting->prescan_x);
1335 
1336  cpl_propertylist_update_double(header, FORS_PFITS_CRPIX2,
1337  crpix2 - setting->prescan_y);
1338 
1339 
1340  cleanup;
1341  return;
1342 }
1343 
1344 /*----------------------------------------------------------------------------*/
1345 #undef cleanup
1346 #define cleanup \
1347 do { \
1348  cpl_propertylist_delete(time_header); \
1349 } while (0)
1350 
1362 /*----------------------------------------------------------------------------*/
1363 void fors_dfs_add_exptime(cpl_propertylist *header, const cpl_frame *frame,
1364  double exptime)
1365 {
1366  bool invert = false;
1367  int extension = 0;
1368 
1369  cpl_propertylist *time_header = NULL;
1370 
1371  if (frame) {
1372 
1373  time_header =
1374  cpl_propertylist_load_regexp(cpl_frame_get_filename(frame),
1375  extension, "EXPTIME", invert);
1376 
1377  if (time_header) {
1378  cpl_propertylist_copy_property_regexp(header,
1379  time_header, ".*", invert);
1380  }
1381  else {
1382  cpl_error_reset();
1383  }
1384  }
1385  else {
1386  while (cpl_propertylist_erase(header, "EXPTIME"));
1387  cpl_propertylist_update_double(header, "EXPTIME", exptime);
1388  }
1389 
1390  cleanup;
1391  return;
1392 }
1393 
1394 /*----------------------------------------------------------------------------*/
1401 /*----------------------------------------------------------------------------*/
1402 void
1403 fors_dfs_save_table(cpl_frameset *frameset, const cpl_table *table,
1404  const char *category, cpl_propertylist *header,
1405  const cpl_parameterlist *parlist, const char *recipename,
1406  const cpl_frame *inherit_frame)
1407 {
1408  dfs_save(frameset, table, FORS_TYPE_TABLE,
1409  category, header,
1410  parlist, recipename,
1411  inherit_frame);
1412 }
1413 
1414 /*----------------------------------------------------------------------------*/
1446 /*----------------------------------------------------------------------------*/
1447 int dfs_save_image(cpl_frameset *frameset, const cpl_image *image,
1448  const char *category, cpl_propertylist *header,
1449  const cpl_parameterlist *parlist, const char *recipename,
1450  const char *version)
1451 {
1452  const char *func = "dfs_save_image";
1453 
1454  char *filename;
1455  cpl_frame *frame;
1456  cpl_propertylist *plist;
1457 
1458 
1459  if (category == NULL || frameset == NULL || image == NULL) {
1460  cpl_msg_error(cpl_func, "Error found in %s: %s",
1461  cpl_error_get_where(), cpl_error_get_message());
1462  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
1463  return -1;
1464  }
1465 
1466  cpl_msg_info(func, "Saving %s image to disk...", category);
1467 
1468  filename = cpl_calloc(strlen(category) + 6, sizeof(char));
1469 
1470  strlower(strcpy(filename, category));
1471  strcat(filename, ".fits");
1472 
1473  frame = cpl_frame_new();
1474 
1475  cpl_frame_set_filename(frame, filename);
1476  cpl_frame_set_tag(frame, category);
1477  cpl_frame_set_type(frame, CPL_FRAME_TYPE_IMAGE);
1478  cpl_frame_set_group(frame, CPL_FRAME_GROUP_PRODUCT);
1479  cpl_frame_set_level(frame, CPL_FRAME_LEVEL_FINAL);
1480  if (cpl_error_get_code()) {
1481  cpl_msg_error(cpl_func, "Error found in %s: %s",
1482  cpl_error_get_where(), cpl_error_get_message());
1483  cpl_msg_error(func, "Cannot initialise the product frame");
1484  cpl_frame_delete(frame);
1485  cpl_free(filename);
1486  return -1;
1487  }
1488 
1489 
1490  /*
1491  * Produce DFS compliant FITS header for image
1492  */
1493 
1494  if (header == NULL)
1495  plist = cpl_propertylist_new();
1496  else
1497  plist = header;
1498 
1499  if (cpl_dfs_setup_product_header(plist, frame, frameset, parlist,
1500  recipename, version, "PRO-1.15", NULL)) {
1501  cpl_msg_error(cpl_func, "Error found in %s: %s",
1502  cpl_error_get_where(), cpl_error_get_message());
1503  cpl_msg_error(func, "Problem with product %s FITS header definition",
1504  category);
1505  if (header == NULL)
1506  cpl_propertylist_delete(plist);
1507  cpl_frame_delete(frame);
1508  cpl_free(filename);
1509  return -1;
1510  }
1511 
1512  cpl_propertylist_erase_regexp(plist, "^ESO DET OUT1 OVSC*", 0);
1513  cpl_propertylist_erase_regexp(plist, "^ESO DET OUT1 PRSC*", 0);
1514 
1515  /*
1516  * Write image to disk
1517  */
1518 
1519  if (cpl_image_save(image, filename, CPL_BPP_IEEE_FLOAT, plist,
1520  CPL_IO_DEFAULT)) {
1521  cpl_msg_error(cpl_func, "Error found in %s: %s",
1522  cpl_error_get_where(), cpl_error_get_message());
1523  cpl_msg_error(func, "Cannot save product %s to disk", filename);
1524  if (header == NULL)
1525  cpl_propertylist_delete(plist);
1526  cpl_frame_delete(frame);
1527  cpl_free(filename);
1528  return -1;
1529  }
1530 
1531  if (header == NULL)
1532  cpl_propertylist_delete(plist);
1533 
1534  cpl_free(filename);
1535 
1536  cpl_frameset_insert(frameset, frame);
1537 
1538  return 0;
1539 }
1540 
1541 /*----------------------------------------------------------------------------*/
1573 /*----------------------------------------------------------------------------*/
1574 int dfs_save_table(cpl_frameset *frameset, const cpl_table *table,
1575  const char *category, cpl_propertylist *header,
1576  const cpl_parameterlist *parlist, const char *recipename,
1577  const char *version)
1578 {
1579  const char *func = "dfs_save_table";
1580 
1581  char *filename;
1582  cpl_frame *frame;
1583  cpl_propertylist *plist;
1584 
1585 
1586  if (category == NULL || frameset == NULL || table == NULL) {
1587  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
1588  cpl_msg_error(cpl_func, "Error found in %s: %s",
1589  cpl_error_get_where(), cpl_error_get_message());
1590  return -1;
1591  }
1592 
1593  cpl_msg_info(func, "Saving %s table to disk...", category);
1594 
1595  filename = cpl_calloc(strlen(category) + 6, sizeof(char));
1596 
1597  strlower(strcpy(filename, category));
1598 
1599  strcat(filename, ".fits");
1600 
1601  frame = cpl_frame_new();
1602 
1603  cpl_frame_set_filename(frame, filename);
1604  cpl_frame_set_tag(frame, category);
1605  cpl_frame_set_type(frame, CPL_FRAME_TYPE_TABLE);
1606  cpl_frame_set_group(frame, CPL_FRAME_GROUP_PRODUCT);
1607  cpl_frame_set_level(frame, CPL_FRAME_LEVEL_FINAL);
1608  if (cpl_error_get_code()) {
1609  cpl_msg_error(cpl_func, "Error found in %s: %s",
1610  cpl_error_get_where(), cpl_error_get_message());
1611  cpl_msg_error(func, "Cannot initialise the product frame");
1612  cpl_frame_delete(frame);
1613  cpl_free(filename);
1614  return -1;
1615  }
1616 
1617 
1618  /*
1619  * Produce DFS compliant FITS header for table
1620  */
1621 
1622  if (header == NULL)
1623  plist = cpl_propertylist_new();
1624  else
1625  plist = header;
1626 
1627  if (cpl_dfs_setup_product_header(plist, frame, frameset, parlist,
1628  recipename, version, "PRO-1.15", NULL)) {
1629  cpl_msg_error(cpl_func, "Error found in %s: %s",
1630  cpl_error_get_where(), cpl_error_get_message());
1631  cpl_msg_error(func, "Problem with product %s FITS header definition",
1632  category);
1633  if (header == NULL)
1634  cpl_propertylist_delete(plist);
1635  cpl_frame_delete(frame);
1636  cpl_free(filename);
1637  return -1;
1638  }
1639 
1640  cpl_propertylist_erase_regexp(plist, "^ESO DET OUT1 OVSC*", 0);
1641  cpl_propertylist_erase_regexp(plist, "^ESO DET OUT1 PRSC*", 0);
1642 
1643  /*
1644  * Write table to disk
1645  */
1646 
1647  if (cpl_table_save(table, plist, NULL, filename, CPL_IO_DEFAULT)) {
1648  cpl_msg_error(cpl_func, "Error found in %s: %s",
1649  cpl_error_get_where(), cpl_error_get_message());
1650  cpl_msg_error(func, "Cannot save product %s to disk", filename);
1651  if (header == NULL)
1652  cpl_propertylist_delete(plist);
1653  cpl_frame_delete(frame);
1654  cpl_free(filename);
1655  return -1;
1656  }
1657 
1658  if (header == NULL)
1659  cpl_propertylist_delete(plist);
1660  cpl_free(filename);
1661 
1662  cpl_frameset_insert(frameset, frame);
1663 
1664  return 0;
1665 }
1666 
1667 /*----------------------------------------------------------------------------*/
1684 /*----------------------------------------------------------------------------*/
1685 int dfs_equal_keyword(cpl_frameset *frameset, const char *keyword)
1686 {
1687  const char *func = "dfs_equal_keyword";
1688 
1689  cpl_frame *frame;
1690  cpl_propertylist *reference;
1691  cpl_type rtype;
1692  cpl_type type;
1693  const char *rstring;
1694  const char *string;
1695  int rintero;
1696  int intero;
1697  int found;
1698 
1699 
1700  if (frameset == NULL || keyword == NULL) {
1701  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
1702  return 0;
1703  }
1704 
1705  if (cpl_frameset_is_empty(frameset)) {
1706  cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
1707  return 0;
1708  }
1709 
1710  frame = cpl_frameset_get_first(frameset);
1711 
1712  found = 0;
1713 
1714  while (frame) {
1715 
1716  reference = cpl_propertylist_load(cpl_frame_get_filename(frame), 0);
1717  if (cpl_error_get_code() == CPL_ERROR_BAD_FILE_FORMAT) {
1718  cpl_error_reset();
1719  frame = cpl_frameset_get_next(frameset);
1720  continue;
1721  }
1722 
1723  if (cpl_propertylist_has(reference, keyword)) {
1724  rtype = cpl_propertylist_get_type(reference, keyword);
1725 
1726  if (rtype == CPL_TYPE_STRING) {
1727  found = 1;
1728  rstring = cpl_strdup(cpl_propertylist_get_string(reference,
1729  keyword));
1730  cpl_propertylist_delete(reference);
1731  break;
1732  }
1733 
1734  if (rtype == CPL_TYPE_INT) {
1735  found = 1;
1736  rintero = cpl_propertylist_get_int(reference, keyword);
1737  cpl_propertylist_delete(reference);
1738  break;
1739  }
1740 
1741  cpl_propertylist_delete(reference);
1742  return 0;
1743  }
1744 
1745  cpl_propertylist_delete(reference);
1746 
1747  frame = cpl_frameset_get_next(frameset);
1748  }
1749 
1750 
1751  if (!found)
1752  return 1;
1753 
1754  frame = cpl_frameset_get_first(frameset);
1755 
1756  while (frame) {
1757 
1758  reference = cpl_propertylist_load(cpl_frame_get_filename(frame), 0);
1759  if (cpl_error_get_code() == CPL_ERROR_BAD_FILE_FORMAT) {
1760  cpl_error_reset();
1761  frame = cpl_frameset_get_next(frameset);
1762  continue;
1763  }
1764 
1765  if (cpl_propertylist_has(reference, keyword)) {
1766 
1767  type = cpl_propertylist_get_type(reference, keyword);
1768 
1769  if (rtype != type) {
1770  cpl_propertylist_delete(reference);
1771  return 0;
1772  }
1773 
1774  if (rtype == CPL_TYPE_STRING) {
1775  string = cpl_propertylist_get_string(reference,
1776  keyword);
1777  if (strncmp(rstring, string, 15)) {
1778  cpl_propertylist_delete(reference);
1779  return 0;
1780  }
1781  }
1782 
1783  if (rtype == CPL_TYPE_INT) {
1784  intero = cpl_propertylist_get_int(reference, keyword);
1785  if (rintero - intero) {
1786  cpl_propertylist_delete(reference);
1787  return 0;
1788  }
1789  }
1790  }
1791 
1792  cpl_propertylist_delete(reference);
1793 
1794  frame = cpl_frameset_get_next(frameset);
1795  }
1796 
1797  if (rtype == CPL_TYPE_STRING)
1798  cpl_free((void *)rstring);
1799 
1800  return 1;
1801 
1802 }
1803 
1813 cpl_error_code dfs_save_table_ext(cpl_table * table,
1814  const char * tag,
1815  cpl_propertylist * extheader)
1816 {
1817  char * filename = cpl_calloc(strlen(tag) + 6, sizeof(char));
1818  cpl_propertylist * header;
1819 
1820  if (extheader) {
1821  header = cpl_propertylist_duplicate(extheader);
1822 
1823  cpl_propertylist_erase_regexp(header,
1824  "^ESO DPR |^ARCFILE$|^ORIGFILE$", 0);
1825  } else {
1826  header = NULL;
1827  }
1828 
1829  strlower(strcpy(filename, tag));
1830  strcat(filename, ".fits");
1831 
1832  if (cpl_table_save(table, NULL, header, filename, CPL_IO_EXTEND)) {
1833  cpl_free(filename);
1834  cpl_ensure_code(0, CPL_ERROR_FILE_IO);
1835  }
1836 
1837  cpl_propertylist_delete(header);
1838  cpl_free(filename);
1839 
1840  return CPL_ERROR_NONE;
1841 }
1842 
1852 cpl_error_code dfs_save_image_ext(cpl_image * image,
1853  const char * tag,
1854  cpl_propertylist * extheader)
1855 {
1856  char * filename = cpl_calloc(strlen(tag) + 6, sizeof(char));
1857 
1858  cpl_propertylist * header;
1859 
1860  if (extheader) {
1861  header = cpl_propertylist_duplicate(extheader);
1862 
1863  cpl_propertylist_erase_regexp(header,
1864  "^ESO DPR |^ARCFILE$|^ORIGFILE$", 0);
1865  } else {
1866  header = NULL;
1867  }
1868 
1869  strlower(strcpy(filename, tag));
1870  strcat(filename, ".fits");
1871 
1872  if (cpl_image_save(image, filename, CPL_BPP_IEEE_FLOAT,
1873  header, CPL_IO_EXTEND)) {
1874  cpl_free(filename);
1875  cpl_ensure_code(0, CPL_ERROR_FILE_IO);
1876  }
1877 
1878  cpl_propertylist_delete(header);
1879  cpl_free(filename);
1880 
1881  return CPL_ERROR_NONE;
1882 }
1883 
1895 cpl_error_code dfs_save_image_null(cpl_frameset * frameset,
1896  cpl_parameterlist * parlist,
1897  const char * tag,
1898  const char * recipename,
1899  const char * version)
1900 {
1901  const char * regexp = "ESO DET OUT1 OVSCX|"
1902  "ESO DET OUT1 PRSCX|"
1903  "ESO DET OUT1 OVSCY|"
1904  "ESO DET OUT1 PRSCY";
1905 
1906  char * filename = cpl_calloc(strlen(tag) + 6, sizeof(char));
1907 
1908  cpl_error_code error;
1909 
1910  cpl_propertylist * pro = cpl_propertylist_new();
1911 
1912  cpl_propertylist_append_string(pro, "ESO PRO CATG", tag);
1913 
1914  strlower(strcpy(filename, tag));
1915  strcat(filename, ".fits");
1916 
1917  error = cpl_dfs_save_image(frameset, NULL, parlist, frameset, NULL, NULL,
1918  CPL_BPP_IEEE_FLOAT, recipename, pro,
1919  regexp, version, filename);
1920 
1921  cpl_free(filename);
1922  cpl_propertylist_delete(pro);
1923 
1924  return error;
1925 }
1926 
1927 
static void errorstate_dump_one(unsigned self, unsigned first, unsigned last)
Dump a single CPL error.
Definition: fors_dfs.c:108
void fors_dfs_save_image_err_mask(cpl_frameset *frameset, const fors_image *image, const cpl_image *mask, const char *category, cpl_propertylist *header, const cpl_parameterlist *parlist, const char *recipename, const cpl_frame *inherit_frame)
Save DFS product (image) with it error data and a bad pixel mask.
Definition: fors_dfs.c:1271
int fors_end(const cpl_frameset *frames, cpl_errorstate before_exec)
End recipe execution.
Definition: fors_dfs.c:219
cpl_image * dfs_load_image(cpl_frameset *frameset, const char *category, cpl_type type, int ext, int calib)
Loading image data of given category.
Definition: fors_dfs.c:845
const char * dfs_get_parameter_string(cpl_parameterlist *parlist, const char *name, const cpl_table *defaults)
Reading a recipe string parameter value.
Definition: fors_dfs.c:587
void fors_frameset_print(const cpl_frameset *frames)
Print a frame set.
Definition: fors_utils.c:393
cpl_propertylist * dfs_load_header(cpl_frameset *frameset, const char *category, int ext)
Loading header associated to data of given category.
Definition: fors_dfs.c:951
void fors_dfs_add_exptime(cpl_propertylist *header, const cpl_frame *frame, double exptime)
Add keyword EXPTIME to header.
Definition: fors_dfs.c:1363
cpl_error_code dfs_save_image_null(cpl_frameset *frameset, cpl_parameterlist *parlist, const char *tag, const char *recipename, const char *version)
Save a product with an empty primary extension.
Definition: fors_dfs.c:1895
cpl_error_code dfs_save_image_ext(cpl_image *image, const char *tag, cpl_propertylist *extheader)
Save an image in a extension.
Definition: fors_dfs.c:1852
void fors_begin(cpl_frameset *frames, const char *description_short)
Start recipe execution.
Definition: fors_dfs.c:191
void fors_dfs_save_image(cpl_frameset *frameset, const cpl_image *image, const char *category, cpl_propertylist *header, const cpl_parameterlist *parlist, const char *recipename, const cpl_frame *inherit_frame)
Save DFS product (image)
Definition: fors_dfs.c:1148
static void dfs_save(cpl_frameset *frameset, const void *object, fors_type type, const char *category, cpl_propertylist *header, const cpl_parameterlist *parlist, const char *recipename, const cpl_frame *inherit_frame)
Save DFS product.
Definition: fors_dfs.c:983
#define assure(EXPR)
Definition: list.c:101
void fors_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
Definition: fors_dfs.c:257
int dfs_get_parameter_bool(cpl_parameterlist *parlist, const char *name, const cpl_table *defaults)
Reading a recipe boolean parameter value.
Definition: fors_dfs.c:686
int dfs_equal_keyword(cpl_frameset *frameset, const char *keyword)
Saving table data of given category.
Definition: fors_dfs.c:1685
int dfs_get_parameter_int_const(const cpl_parameterlist *parlist, const char *name)
Definition: fors_dfs.c:791
cpl_error_code dfs_save_table_ext(cpl_table *table, const char *tag, cpl_propertylist *extheader)
Save a table in a extension (different from the first one)
Definition: fors_dfs.c:1813
void fors_dfs_save_image_err(cpl_frameset *frameset, const fors_image *image, const char *category, cpl_propertylist *header, const cpl_parameterlist *parlist, const char *recipename, const cpl_frame *inherit_frame)
Save DFS product (image) with it error data.
Definition: fors_dfs.c:1235
int dfs_get_parameter_bool_const(const cpl_parameterlist *parlist, const char *name)
Definition: fors_dfs.c:781
void fors_dfs_save_table(cpl_frameset *frameset, const cpl_table *table, const char *category, cpl_propertylist *header, const cpl_parameterlist *parlist, const char *recipename, const cpl_frame *inherit_frame)
Save DFS product (table)
Definition: fors_dfs.c:1403
void fors_dfs_save_image_mask(cpl_frameset *frameset, const cpl_image *image, const cpl_image *mask, const char *category, cpl_propertylist *header, const cpl_parameterlist *parlist, const char *recipename, const cpl_frame *inherit_frame)
Save DFS product (image)
Definition: fors_dfs.c:1183
int dfs_save_image(cpl_frameset *frameset, const cpl_image *image, const char *category, cpl_propertylist *header, const cpl_parameterlist *parlist, const char *recipename, const char *version)
Saving image data of given category.
Definition: fors_dfs.c:1447
cpl_table * dfs_load_table(cpl_frameset *frameset, const char *category, int ext)
Loading table data of given category.
Definition: fors_dfs.c:901
int dfs_get_parameter_int(cpl_parameterlist *parlist, const char *name, const cpl_table *defaults)
Reading a recipe integer parameter value.
Definition: fors_dfs.c:392
int dfs_save_table(cpl_frameset *frameset, const cpl_table *table, const char *category, cpl_propertylist *header, const cpl_parameterlist *parlist, const char *recipename, const char *version)
Saving table data of given category.
Definition: fors_dfs.c:1574
const char * dfs_get_parameter_string_const(const cpl_parameterlist *parlist, const char *name)
Definition: fors_dfs.c:811
void fors_image_save(const fors_image *image, const cpl_propertylist *header, const char *filename)
Save image.
Definition: fors_image.c:383
double dfs_get_parameter_double(cpl_parameterlist *parlist, const char *name, const cpl_table *defaults)
Reading a recipe double parameter value.
Definition: fors_dfs.c:489
void fors_frame_print(const cpl_frame *f)
Print a frame.
Definition: fors_utils.c:427
const char * fors_dfs_pipeline_version(const cpl_propertylist *header, const char **instrument_version)
Get pipeline and instrument versions.
Definition: fors_dfs.c:345
void fors_dfs_add_wcs(cpl_propertylist *header, const cpl_frame *frame, const fors_setting *setting)
add WCS keywords to header
Definition: fors_dfs.c:1309
double dfs_get_parameter_double_const(const cpl_parameterlist *parlist, const char *name)
Definition: fors_dfs.c:801