FORS Pipeline Reference Manual  5.2.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, "LAMP_MXU" ) == 0 ||
277  strcmp(tag, "LAMP_MOS" ) == 0 ||
278  strcmp(tag, "LAMP_LSS" ) == 0 ||
279  strcmp(tag, "SCREEN_FLAT_PMOS") == 0 ||
280  strcmp(tag, "STANDARD_PMOS" ) == 0 ||
281  strcmp(tag, "SCIENCE_PMOS" ) == 0 ||
282  strcmp(tag, "SCIENCE_MOS" ) == 0 ||
283  strcmp(tag, "SCIENCE_MXU" ) == 0 ||
284  strcmp(tag, "SCIENCE_LSS" ) == 0 ||
285  strcmp(tag, "STANDARD_MOS" ) == 0 ||
286  strcmp(tag, "STANDARD_MXU" ) == 0 ||
287  strcmp(tag, "STANDARD_LSS" ) == 0 ||
288  strcmp(tag, SCIENCE_IMG ) == 0 ||
289  strcmp(tag, "SCREEN_FLAT_MXU" ) == 0 ||
290  strcmp(tag, "SCREEN_FLAT_MOS" ) == 0 ||
291  strcmp(tag, "SCREEN_FLAT_LSS" ) == 0 ) {
292  cpl_frame_set_group(f, CPL_FRAME_GROUP_RAW);
293  }
294  else if (strcmp(tag, MASTER_BIAS ) == 0 ||
295  strcmp(tag, MASTER_DARK ) == 0 ||
296  strcmp(tag, MASTER_SCREEN_FLAT_IMG ) == 0 ||
297  strcmp(tag, MASTER_SKY_FLAT_IMG ) == 0 ||
298  strcmp(tag, ALIGNED_PHOT ) == 0 ||
299  strcmp(tag, "MASTER_NORM_FLAT_PMOS" ) == 0 ||
300  strcmp(tag, "DISP_COEFF_PMOS" ) == 0 ||
301  strcmp(tag, "CURV_COEFF_PMOS" ) == 0 ||
302  strcmp(tag, "SLIT_LOCATION_PMOS" ) == 0 ||
303  strcmp(tag, "MASTER_NORM_FLAT_MOS" ) == 0 ||
304  strcmp(tag, "MASTER_NORM_FLAT_MXU" ) == 0 ||
305  strcmp(tag, "MASTER_NORM_FLAT_LSS" ) == 0 ||
306  strcmp(tag, "MASTER_NORM_FLAT_LONG_MOS" ) == 0 ||
307  strcmp(tag, "SLIT_LOCATION_MOS" ) == 0 ||
308  strcmp(tag, "SLIT_LOCATION_MXU" ) == 0 ||
309  strcmp(tag, "SLIT_LOCATION_LSS" ) == 0 ||
310  strcmp(tag, "SLIT_LOCATION_LONG_MOS" ) == 0 ||
311  strcmp(tag, "CURV_COEFF_MOS" ) == 0 ||
312  strcmp(tag, "CURV_COEFF_MXU" ) == 0 ||
313  strcmp(tag, "CURV_COEFF_LSS" ) == 0 ||
314  strcmp(tag, "DISP_COEFF_MOS" ) == 0 ||
315  strcmp(tag, "DISP_COEFF_MXU" ) == 0 ||
316  strcmp(tag, "DISP_COEFF_LSS" ) == 0 ||
317  strcmp(tag, "DISP_COEFF_LONG_MOS" ) == 0 ||
318  strcmp(tag, "FLAT_SED_MOS" ) == 0 ||
319  strcmp(tag, "FLAT_SED_MXU" ) == 0 ||
320  strcmp(tag, "FLAT_SED_LSS" ) == 0 ||
321  strcmp(tag, "FLAT_SED_LONG_MOS" ) == 0 ||
322  /* static calibration */
323  strcmp(tag, FLX_STD_IMG ) == 0 ||
324  strcmp(tag, "EXTINCT_TABLE" ) == 0 ||
325  strcmp(tag, "MASTER_LINECAT" ) == 0 ||
326  strcmp(tag, "MASTER_DISTORTION_TABLE" ) == 0 ||
327  strcmp(tag, "GLOBAL_DISTORTION_TABLE" ) == 0 ||
328  strcmp(tag, "RETARDER_WAVEPLATE_CHROMATISM") == 0 ||
329  strcmp(tag, "GRISM_TABLE" ) == 0 ||
330  strcmp(tag, "STD_PMOS_TABLE" ) == 0 ||
331  strcmp(tag, "TELLURIC_CONTAMINATION" ) == 0 ||
332  strcmp(tag, "STD_FLUX_TABLE" ) == 0 ||
333  strcmp(tag, "SPECPHOT_TABLE" ) == 0 ||
334  strcmp(tag, PHOT_TABLE ) == 0) {
335  cpl_frame_set_group(f, CPL_FRAME_GROUP_CALIB);
336  }
337  else {
338  cpl_msg_warning(cpl_func, "Unrecognized frame tag: '%s'",
339  tag);
340  }
341  }
342  }
343 
344  return;
345 }
346 
347 /*----------------------------------------------------------------------------*/
348 #undef cleanup
349 #define cleanup
350 
358 /*----------------------------------------------------------------------------*/
359 const char *
360 fors_dfs_pipeline_version(const cpl_propertylist *header,
361  const char **instrument_version)
362 {
363  const char *instrume = NULL;
364 
365  instrume = cpl_propertylist_get_string(header,
366  FORS_PFITS_INSTRUME);
367  assure( !cpl_error_get_code(), return NULL,
368  "Missing keyword %s in input header", FORS_PFITS_INSTRUME);
369 
370  assure( strlen(instrume) >= 5, return NULL,
371  "%s keyword must be 'fors1' or 'fors2', not '%s'",
372  FORS_PFITS_INSTRUME, instrume);
373 
374  assure( instrume[4] == '1' || instrume[4] == '2', return NULL,
375  "Unrecognized %s: %s", FORS_PFITS_INSTRUME, instrume);
376 
377  if (instrument_version != NULL) {
378  *instrument_version = cpl_sprintf("%s", instrume);
379  }
380 
381  return cpl_sprintf("fors%c/%s", instrume[4], PACKAGE_VERSION);
382 }
383 
384 /*----------------------------------------------------------------------------*/
406 /*----------------------------------------------------------------------------*/
407 int dfs_get_parameter_int(cpl_parameterlist *parlist, const char *name,
408  const cpl_table *defaults)
409 {
410  const char *func = "dfs_get_parameter_int";
411 
412  const char *alias;
413  cpl_parameter *param;
414 
415 
416  if (parlist == NULL) {
417  cpl_msg_error(func, "Missing input parameter list");
418  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
419  return 0;
420  }
421 
422  if (name == NULL) {
423  cpl_msg_error(func, "Missing input parameter name");
424  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
425  return 0;
426  }
427 
428  param = cpl_parameterlist_find(parlist, name);
429 
430  if (param == NULL) {
431  cpl_msg_error(func, "Wrong parameter name: %s", name);
432  cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
433  return 0;
434  }
435 
436  if (cpl_parameter_get_type(param) != CPL_TYPE_INT) {
437  cpl_msg_error(func, "Unexpected type for parameter "
438  "\"%s\": it should be integer", name);
439  cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
440  return 0;
441  }
442 
443  alias = cpl_parameter_get_alias(param, CPL_PARAMETER_MODE_CLI);
444 
445 // if (defaults && cpl_parameter_get_default_flag(param) == 0) {
446  if (defaults &&
447  cpl_parameter_get_default_int(param) == cpl_parameter_get_int(param)) {
448 
449  if (cpl_table_has_column(defaults, alias)) {
450  if (cpl_table_get_column_type(defaults, alias) != CPL_TYPE_INT) {
451  cpl_msg_error(func, "Unexpected type for GRISM_TABLE "
452  "column \"%s\": it should be integer", alias);
453  cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
454  return 0;
455  }
456  if (cpl_table_is_valid(defaults, alias, 0)) {
457  cpl_parameter_set_int(param, cpl_table_get_int(defaults,
458  alias, 0, NULL));
459  }
460  else {
461  cpl_msg_error(func, "Invalid parameter value in table "
462  "column \"%s\"", alias);
463  cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
464  return 0;
465  }
466  }
467  else {
468  cpl_msg_warning(func, "Parameter \"%s\" not found in GRISM_TABLE "
469  "- using recipe default", alias);
470  }
471  }
472 
473  cpl_msg_info(func, "%s: %d", alias, cpl_parameter_get_int(param));
474 
475  return cpl_parameter_get_int(param);
476 
477 }
478 
479 /*----------------------------------------------------------------------------*/
501 /*----------------------------------------------------------------------------*/
502 double dfs_get_parameter_double(cpl_parameterlist *parlist,
503  const char *name, const cpl_table *defaults)
504 {
505  const char *func = "dfs_get_parameter_double";
506 
507  const char *alias;
508  cpl_parameter *param;
509 
510 
511  if (parlist == NULL) {
512  cpl_msg_error(func, "Missing input parameter list");
513  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
514  return 0;
515  }
516 
517  if (name == NULL) {
518  cpl_msg_error(func, "Missing input parameter name");
519  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
520  return 0;
521  }
522 
523  param = cpl_parameterlist_find(parlist, name);
524 
525  if (param == NULL) {
526  cpl_msg_error(func, "Wrong parameter name: %s", name);
527  cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
528  return 0;
529  }
530 
531  if (cpl_parameter_get_type(param) != CPL_TYPE_DOUBLE) {
532  cpl_msg_error(func, "Unexpected type for parameter "
533  "\"%s\": it should be double", name);
534  cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
535  return 0;
536  }
537 
538  alias = cpl_parameter_get_alias(param, CPL_PARAMETER_MODE_CLI);
539 
540 // if (defaults && cpl_parameter_get_default_flag(param) == 0) {
541  if (defaults &&
542  cpl_parameter_get_default_double(param) ==
543  cpl_parameter_get_double(param)) {
544 
545  if (cpl_table_has_column(defaults, alias)) {
546  if (cpl_table_get_column_type(defaults, alias) != CPL_TYPE_DOUBLE) {
547  cpl_msg_error(func, "Unexpected type for GRISM_TABL "
548  "column \"%s\": it should be double", alias);
549  cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
550  return 0;
551  }
552  if (cpl_table_is_valid(defaults, alias, 0)) {
553  cpl_parameter_set_double(param, cpl_table_get_double(defaults,
554  alias, 0, NULL));
555  }
556  else {
557  cpl_msg_error(func, "Invalid parameter value in table "
558  "column \"%s\"", alias);
559  cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
560  return 0;
561  }
562  }
563  else {
564  cpl_msg_warning(func, "Parameter \"%s\" not found in GRISM_TABLE "
565  "- using recipe default", alias);
566  }
567  }
568 
569  cpl_msg_info(func, "%s: %f", alias, cpl_parameter_get_double(param));
570 
571  return cpl_parameter_get_double(param);
572 
573 }
574 
575 /*----------------------------------------------------------------------------*/
597 /*----------------------------------------------------------------------------*/
598 const char *dfs_get_parameter_string(cpl_parameterlist *parlist,
599  const char *name,
600  const cpl_table *defaults)
601 {
602  const char *func = "dfs_get_parameter_string";
603 
604  const char *alias;
605  cpl_parameter *param;
606 
607 
608  if (parlist == NULL) {
609  cpl_msg_error(func, "Missing input parameter list");
610  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
611  return 0;
612  }
613 
614  if (name == NULL) {
615  cpl_msg_error(func, "Missing input parameter name");
616  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
617  return 0;
618  }
619 
620  param = cpl_parameterlist_find(parlist, name);
621 
622  if (param == NULL) {
623  cpl_msg_error(func, "Wrong parameter name: %s", name);
624  cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
625  return 0;
626  }
627 
628  if (cpl_parameter_get_type(param) != CPL_TYPE_STRING) {
629  cpl_msg_error(func, "Unexpected type for parameter "
630  "\"%s\": it should be string", name);
631  cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
632  return 0;
633  }
634 
635  alias = cpl_parameter_get_alias(param, CPL_PARAMETER_MODE_CLI);
636 
637 // if (defaults && cpl_parameter_get_default_flag(param) == 0) {
638  if (defaults &&
639  strcmp(cpl_parameter_get_default_string(param),
640  cpl_parameter_get_string(param)) == 0) {
641 
642  if (cpl_table_has_column(defaults, alias)) {
643  if (cpl_table_get_column_type(defaults, alias) != CPL_TYPE_STRING) {
644  cpl_msg_error(func, "Unexpected type for GRISM_TABLE "
645  "column \"%s\": it should be string", alias);
646  cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
647  return 0;
648  }
649  if (cpl_table_is_valid(defaults, alias, 0)) {
650  cpl_parameter_set_string(param, cpl_table_get_string(defaults,
651  alias, 0));
652  }
653  else {
654  cpl_msg_error(func, "Invalid parameter value in table "
655  "column \"%s\"", alias);
656  cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
657  return 0;
658  }
659  }
660  else {
661  cpl_msg_warning(func, "Parameter \"%s\" not found in GRISM_TABLE "
662  "- using recipe default", alias);
663  }
664  }
665 
666  cpl_msg_info(func, "%s: %s", alias, cpl_parameter_get_string(param));
667 
668  return cpl_parameter_get_string(param);
669 
670 }
671 
672 /*----------------------------------------------------------------------------*/
694 /*----------------------------------------------------------------------------*/
695 int dfs_get_parameter_bool(cpl_parameterlist *parlist, const char *name,
696  const cpl_table *defaults)
697 {
698  const char *func = "dfs_get_parameter_bool";
699 
700  const char *alias;
701  cpl_parameter *param;
702  int value;
703 
704 
705  if (parlist == NULL) {
706  cpl_msg_error(func, "Missing input parameter list");
707  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
708  return 0;
709  }
710 
711  if (name == NULL) {
712  cpl_msg_error(func, "Missing input parameter name");
713  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
714  return 0;
715  }
716 
717  param = cpl_parameterlist_find(parlist, name);
718 
719  if (param == NULL) {
720  cpl_msg_error(func, "Wrong parameter name: %s", name);
721  cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
722  return 0;
723  }
724 
725  if (cpl_parameter_get_type(param) != CPL_TYPE_BOOL) {
726  cpl_msg_error(func, "Unexpected type for parameter "
727  "\"%s\": it should be boolean", name);
728  cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
729  return 0;
730  }
731 
732  alias = cpl_parameter_get_alias(param, CPL_PARAMETER_MODE_CLI);
733 
734 // if (defaults && cpl_parameter_get_default_flag(param) == 0) {
735  if (defaults &&
736  cpl_parameter_get_default_bool(param) ==
737  cpl_parameter_get_bool(param)) {
738 
739  if (cpl_table_has_column(defaults, alias)) {
740  if (cpl_table_get_column_type(defaults, alias) != CPL_TYPE_INT) {
741  cpl_msg_error(func, "Unexpected type for GRISM_TABLE "
742  "column \"%s\": it should be integer", alias);
743  cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
744  return 0;
745  }
746  if (cpl_table_is_valid(defaults, alias, 0)) {
747  value = cpl_table_get_int(defaults, alias, 0, NULL);
748  if (value < 0 || value > 1) {
749  cpl_msg_error(func, "Illegal parameter value in table "
750  "column \"%s\": it should be either 0 or 1",
751  alias);
752  cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
753  return 0;
754  }
755  cpl_parameter_set_bool(param, value);
756  }
757  else {
758  cpl_msg_error(func, "Invalid parameter value in table "
759  "column \"%s\"", alias);
760  cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
761  return 0;
762  }
763  }
764  else {
765  cpl_msg_warning(func, "Parameter \"%s\" not found in GRISM_TABLE "
766  "- using recipe default", alias);
767  }
768  }
769 
770  value = cpl_parameter_get_bool(param);
771 
772  if (value) {
773  cpl_msg_info(func, "%s: TRUE", alias);
774  }
775  else {
776  cpl_msg_info(func, "%s: FALSE", alias);
777  }
778 
779  return value;
780 
781 }
782 
783 /*----------------------------------------------------------------------------*/
787 /*----------------------------------------------------------------------------*/
788 int dfs_get_parameter_bool_const(const cpl_parameterlist *parlist, const char *name)
789 {
790  return dfs_get_parameter_bool((cpl_parameterlist *)parlist, name, NULL);
791 }
792 
793 /*----------------------------------------------------------------------------*/
797 /*----------------------------------------------------------------------------*/
798 int dfs_get_parameter_int_const(const cpl_parameterlist *parlist, const char *name)
799 {
800  return dfs_get_parameter_int((cpl_parameterlist *)parlist, name, NULL);
801 }
802 
803 /*----------------------------------------------------------------------------*/
807 /*----------------------------------------------------------------------------*/
808 double dfs_get_parameter_double_const(const cpl_parameterlist *parlist, const char *name)
809 {
810  return dfs_get_parameter_double((cpl_parameterlist *)parlist, name, NULL);
811 }
812 
813 /*----------------------------------------------------------------------------*/
817 /*----------------------------------------------------------------------------*/
818 const char *dfs_get_parameter_string_const(const cpl_parameterlist *parlist, const char *name)
819 {
820  return dfs_get_parameter_string((cpl_parameterlist *)parlist, name, NULL);
821 }
822 
823 /*----------------------------------------------------------------------------*/
851 /*----------------------------------------------------------------------------*/
852 cpl_image *dfs_load_image(cpl_frameset *frameset, const char *category,
853  cpl_type type, int ext, int calib)
854 {
855  const char *func = "dfs_load_image";
856 
857  cpl_frame *frame = NULL;
858  cpl_image *image = NULL;
859 
860 
861  frame = cpl_frameset_find(frameset, category);
862 
863  if (frame) {
864  image = cpl_image_load(cpl_frame_get_filename(frame), type, 0, ext);
865  if (image == NULL) {
866  cpl_msg_error(cpl_error_get_where(),"%s", cpl_error_get_message());
867  cpl_msg_error(func, "Cannot load image %s",
868  cpl_frame_get_filename(frame));
869  }
870  else {
871  if (calib)
872  cpl_frame_set_group(frame, CPL_FRAME_GROUP_CALIB);
873  else
874  cpl_frame_set_group(frame, CPL_FRAME_GROUP_RAW);
875  }
876  }
877 
878  return image;
879 }
880 
881 /*----------------------------------------------------------------------------*/
907 /*----------------------------------------------------------------------------*/
908 cpl_table *dfs_load_table(cpl_frameset *frameset, const char *category, int ext)
909 {
910  const char *func = "dfs_load_table";
911 
912  cpl_frame *frame = NULL;
913  cpl_table *table = NULL;
914 
915 
916  frame = cpl_frameset_find(frameset, category);
917 
918  if (frame) {
919  table = cpl_table_load(cpl_frame_get_filename(frame), ext, 1);
920  if (table == NULL) {
921  cpl_msg_error(cpl_error_get_where(), "%s", cpl_error_get_message());
922  cpl_msg_error(func, "Cannot load table %s",
923  cpl_frame_get_filename(frame));
924  }
925  }
926 
927  return table;
928 }
929 
930 /*----------------------------------------------------------------------------*/
955 /*----------------------------------------------------------------------------*/
956 cpl_propertylist *dfs_load_header(cpl_frameset *frameset,
957  const char *category, int ext)
958 {
959  const char *func = "dfs_load_header";
960 
961  cpl_frame *frame = NULL;
962  cpl_propertylist *plist = NULL;
963 
964 
965  frame = cpl_frameset_find(frameset, category);
966 
967  if (frame) {
968  plist = cpl_propertylist_load(cpl_frame_get_filename(frame), ext);
969  if (plist == NULL) {
970  cpl_msg_error(cpl_error_get_where(), "%s", cpl_error_get_message());
971  cpl_msg_error(func, "Cannot load header from %s",
972  cpl_frame_get_filename(frame));
973  }
974  }
975 
976  return plist;
977 }
978 
979 /*----------------------------------------------------------------------------*/
986 /*----------------------------------------------------------------------------*/
987 static void
988 dfs_save(cpl_frameset *frameset, const void *object, fors_type type,
989  const char *category, cpl_propertylist *header,
990  cpl_propertylist *extra_header,
991  const cpl_parameterlist *parlist, const char *recipename,
992  const cpl_frame *inherit_frame)
993 {
994  char *filename;
995  cpl_frame *frame;
996  cpl_propertylist *plist;
997  const char *version = NULL;
998  cpl_propertylist *raw_header = NULL;
999 
1000 
1001  if (category == NULL || frameset == NULL || object == NULL ||
1002  inherit_frame == NULL) {
1003  cpl_msg_error(cpl_error_get_where(), "%s", cpl_error_get_message());
1004  cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
1005  return;
1006  }
1007 
1008  if (type == FORS_TYPE_TABLE) {
1009  cpl_msg_debug(cpl_func, "Saving %s table to disk...", category);
1010  }
1011  else {
1012  cpl_msg_debug(cpl_func, "Saving %s image to disk...", category);
1013  }
1014 
1015  /* Read instrument version from raw frame */
1016  {
1017  const char *raw_filename =
1018  cpl_frame_get_filename(inherit_frame);
1019 
1020  raw_header = cpl_propertylist_load(raw_filename, 0);
1021  if (raw_header == NULL) {
1022  cpl_msg_error(cpl_func, "Could not read %s primary header", raw_filename);
1023  return;
1024  }
1025 
1026  version = fors_dfs_pipeline_version(raw_header, NULL);
1027  cpl_propertylist_delete(raw_header);
1028 
1029  if (cpl_error_get_code() != CPL_ERROR_NONE) {
1030  cpl_msg_error(cpl_func, "Could not identify instrument version from %s header",
1031  raw_filename);
1032  return;
1033  }
1034  }
1035 
1036  filename = cpl_calloc(strlen(category) + 6, sizeof(char));
1037 
1038  strlower(strcpy(filename, category));
1039  strcat(filename, ".fits");
1040 
1041  frame = cpl_frame_new();
1042 
1043  cpl_frame_set_filename(frame, filename);
1044  cpl_frame_set_tag(frame, category);
1045  cpl_frame_set_type(frame, CPL_FRAME_TYPE_ANY);
1046  cpl_frame_set_group(frame, CPL_FRAME_GROUP_PRODUCT);
1047  cpl_frame_set_level(frame, CPL_FRAME_LEVEL_FINAL);
1048  if (cpl_error_get_code()) {
1049  cpl_msg_error(cpl_error_get_where(), "%s", cpl_error_get_message());
1050  cpl_msg_error(cpl_func, "Cannot initialise the product frame");
1051  cpl_frame_delete(frame);
1052  cpl_free(filename);
1053  cpl_free((void *)version);
1054  return;
1055  }
1056 
1057 
1058  /*
1059  * Produce DFS compliant FITS header for product
1060  */
1061 
1062  if (header == NULL)
1063  plist = cpl_propertylist_new();
1064  else
1065  plist = cpl_propertylist_duplicate(header);
1066 
1067  if (cpl_dfs_setup_product_header(plist, frame, frameset, parlist,
1068  recipename, version, "PRO-1.15",
1069  inherit_frame)) {
1070  cpl_msg_error(cpl_func, "Error found in %s: %s",
1071  cpl_error_get_where(), cpl_error_get_message());
1072  cpl_msg_error(cpl_func, "Problem with product %s FITS header definition",
1073  category);
1074  cpl_propertylist_delete(plist);
1075  cpl_frame_delete(frame);
1076  cpl_free(filename);
1077  cpl_free((void *)version);
1078  return;
1079  }
1080 
1081  cpl_free((void *)version);
1082 
1083  /*
1084  * Write to disk
1085  */
1086 
1087  if (type == FORS_TYPE_IMAGE_ERR) {
1088  fors_image_save((fors_image *)object, plist, extra_header, filename);
1089  }
1090  else if (type == FORS_TYPE_IMAGE) {
1091  cpl_image_save((cpl_image *)object, filename, CPL_BPP_IEEE_FLOAT, plist,
1092  CPL_IO_DEFAULT);
1093  }
1094  else {
1095  cpl_table_save((cpl_table *)object,
1096  plist, NULL, filename, CPL_IO_DEFAULT);
1097  }
1098 
1099  if (cpl_error_get_code() != CPL_ERROR_NONE) {
1100  cpl_msg_error(cpl_func, "Error found in %s: %s",
1101  cpl_error_get_where(), cpl_error_get_message());
1102  cpl_msg_error(cpl_func, "Cannot save product %s to disk", filename);
1103  cpl_propertylist_delete(plist);
1104  cpl_frame_delete(frame);
1105  cpl_free(filename);
1106  return;
1107  }
1108 
1109  cpl_propertylist_delete(plist);
1110 
1111  cpl_free(filename);
1112 
1113  cpl_frameset_insert(frameset, frame);
1114 
1115  return;
1116 }
1117 
1118 /*----------------------------------------------------------------------------*/
1139 /*----------------------------------------------------------------------------*/
1140 void
1141 fors_dfs_save_image(cpl_frameset *frameset, const cpl_image *image,
1142  const char *category, cpl_propertylist *header,
1143  const cpl_parameterlist *parlist, const char *recipename,
1144  const cpl_frame *inherit_frame)
1145 {
1146  dfs_save(frameset, image, FORS_TYPE_IMAGE,
1147  category, header, NULL,
1148  parlist, recipename,
1149  inherit_frame);
1150 }
1151 
1152 /*----------------------------------------------------------------------------*/
1174 /*----------------------------------------------------------------------------*/
1175 void
1176 fors_dfs_save_image_mask(cpl_frameset *frameset, const cpl_image *image,
1177  const cpl_image *mask, const char *category,
1178  cpl_propertylist *header,
1179  const cpl_parameterlist *parlist, const char *recipename,
1180  const cpl_frame *inherit_frame)
1181 {
1182  char *filename;
1183  cpl_propertylist * extension_header;
1184 
1185  dfs_save(frameset, image, FORS_TYPE_IMAGE,
1186  category, header, NULL,
1187  parlist, recipename,
1188  inherit_frame);
1189 
1190  extension_header = cpl_propertylist_new();
1191  cpl_propertylist_append_string(extension_header,
1192  "EXTNAME", "IMAGE.BPM");
1193 
1194  filename = cpl_calloc(strlen(category) + 6, sizeof(char));
1195 
1196  strlower(strcpy(filename, category));
1197  strcat(filename, ".fits");
1198 
1199  cpl_image_save(mask, filename, CPL_BPP_IEEE_FLOAT, extension_header,
1200  CPL_IO_EXTEND);
1201  cpl_propertylist_delete(extension_header);
1202  cpl_free(filename);
1203 
1204 }
1205 
1206 /*----------------------------------------------------------------------------*/
1227 /*----------------------------------------------------------------------------*/
1228 void
1229 fors_dfs_save_image_err(cpl_frameset *frameset, const fors_image *image,
1230  const char *category, cpl_propertylist *header,
1231  cpl_propertylist *err_header,
1232  const cpl_parameterlist *parlist, const char *recipename,
1233  const cpl_frame *inherit_frame)
1234 {
1235  dfs_save(frameset, image, FORS_TYPE_IMAGE_ERR,
1236  category, header, err_header,
1237  parlist, recipename,
1238  inherit_frame);
1239 }
1240 
1241 /*----------------------------------------------------------------------------*/
1264 /*----------------------------------------------------------------------------*/
1265 void
1266 fors_dfs_save_image_err_mask(cpl_frameset *frameset, const fors_image *image,
1267  const cpl_image *mask, const char *category,
1268  cpl_propertylist *header,
1269  const cpl_parameterlist *parlist, const char *recipename,
1270  const cpl_frame *inherit_frame)
1271 {
1272  char *filename;
1273  cpl_propertylist * extension_header;
1274 
1275  dfs_save(frameset, image, FORS_TYPE_IMAGE_ERR,
1276  category, header, NULL,
1277  parlist, recipename,
1278  inherit_frame);
1279 
1280  extension_header = cpl_propertylist_new();
1281  cpl_propertylist_append_string(extension_header,
1282  "EXTNAME", "IMAGE.BPM");
1283 
1284  filename = cpl_calloc(strlen(category) + 6, sizeof(char));
1285 
1286  strlower(strcpy(filename, category));
1287  strcat(filename, ".fits");
1288 
1289  cpl_image_save(mask, filename, CPL_BPP_IEEE_FLOAT, extension_header,
1290  CPL_IO_EXTEND);
1291  cpl_propertylist_delete(extension_header);
1292  cpl_free(filename);
1293 }
1294 
1295 #undef cleanup
1296 #define cleanup \
1297 do { \
1298  cpl_propertylist_delete(wcs_header); \
1299 } while (0)
1300 
1305 void fors_dfs_add_wcs(cpl_propertylist *header, const cpl_frame *frame,
1306  const fors_setting *setting)
1307 {
1308  bool invert = false;
1309  int extension = 0;
1310 
1311  cpl_propertylist *wcs_header =
1312  cpl_propertylist_load_regexp(cpl_frame_get_filename(frame),
1313  extension, WCS_KEYS, invert);
1314 
1315  cpl_propertylist_copy_property_regexp(header, wcs_header, ".*", invert);
1316 
1317  double crpix1 = cpl_propertylist_get_double(header, FORS_PFITS_CRPIX1);
1318 
1319  assure( !cpl_error_get_code(), return,
1320  "Could not read %s from %s", FORS_PFITS_CRPIX1,
1321  cpl_frame_get_filename(frame));
1322 
1323  double crpix2 = cpl_propertylist_get_double(header, FORS_PFITS_CRPIX2);
1324 
1325  assure( !cpl_error_get_code(), return,
1326  "Could not read %s from %s", FORS_PFITS_CRPIX2,
1327  cpl_frame_get_filename(frame));
1328 
1329  cpl_propertylist_update_double(header, FORS_PFITS_CRPIX1,
1330  crpix1 - setting->prescan_x);
1331 
1332  cpl_propertylist_update_double(header, FORS_PFITS_CRPIX2,
1333  crpix2 - setting->prescan_y);
1334 
1335 
1336  cleanup;
1337  return;
1338 }
1339 
1340 /*----------------------------------------------------------------------------*/
1341 #undef cleanup
1342 #define cleanup \
1343 do { \
1344  cpl_propertylist_delete(time_header); \
1345 } while (0)
1346 
1358 /*----------------------------------------------------------------------------*/
1359 void fors_dfs_add_exptime(cpl_propertylist *header, const cpl_frame *frame,
1360  double exptime)
1361 {
1362  bool invert = false;
1363  int extension = 0;
1364 
1365  cpl_propertylist *time_header = NULL;
1366 
1367  if (frame) {
1368 
1369  time_header =
1370  cpl_propertylist_load_regexp(cpl_frame_get_filename(frame),
1371  extension, "EXPTIME", invert);
1372 
1373  if (time_header) {
1374  cpl_propertylist_copy_property_regexp(header,
1375  time_header, ".*", invert);
1376  }
1377  else {
1378  cpl_error_reset();
1379  }
1380  }
1381  else {
1382  while (cpl_propertylist_erase(header, "EXPTIME"));
1383  cpl_propertylist_update_double(header, "EXPTIME", exptime);
1384  }
1385 
1386  cleanup;
1387  return;
1388 }
1389 
1390 /*----------------------------------------------------------------------------*/
1397 /*----------------------------------------------------------------------------*/
1398 void
1399 fors_dfs_save_table(cpl_frameset *frameset, const cpl_table *table,
1400  const char *category, cpl_propertylist *header,
1401  const cpl_parameterlist *parlist, const char *recipename,
1402  const cpl_frame *inherit_frame)
1403 {
1404  dfs_save(frameset, table, FORS_TYPE_TABLE,
1405  category, header, NULL,
1406  parlist, recipename,
1407  inherit_frame);
1408 }
1409 
1410 /*----------------------------------------------------------------------------*/
1442 /*----------------------------------------------------------------------------*/
1443 int dfs_save_image(cpl_frameset *frameset, const cpl_image *image,
1444  const char *category, cpl_propertylist *header,
1445  const cpl_parameterlist *parlist, const char *recipename,
1446  const char *version)
1447 {
1448  const char *func = "dfs_save_image";
1449 
1450  char *filename;
1451  cpl_frame *frame;
1452  cpl_propertylist *plist;
1453 
1454 
1455  if (category == NULL || frameset == NULL || image == NULL) {
1456  cpl_msg_error(cpl_func, "Error found in %s: %s",
1457  cpl_error_get_where(), cpl_error_get_message());
1458  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
1459  return -1;
1460  }
1461 
1462  cpl_msg_info(func, "Saving %s image to disk...", category);
1463 
1464  filename = cpl_calloc(strlen(category) + 6, sizeof(char));
1465 
1466  strlower(strcpy(filename, category));
1467  strcat(filename, ".fits");
1468 
1469  frame = cpl_frame_new();
1470 
1471  cpl_frame_set_filename(frame, filename);
1472  cpl_frame_set_tag(frame, category);
1473  cpl_frame_set_type(frame, CPL_FRAME_TYPE_IMAGE);
1474  cpl_frame_set_group(frame, CPL_FRAME_GROUP_PRODUCT);
1475  cpl_frame_set_level(frame, CPL_FRAME_LEVEL_FINAL);
1476  if (cpl_error_get_code()) {
1477  cpl_msg_error(cpl_func, "Error found in %s: %s",
1478  cpl_error_get_where(), cpl_error_get_message());
1479  cpl_msg_error(func, "Cannot initialise the product frame");
1480  cpl_frame_delete(frame);
1481  cpl_free(filename);
1482  return -1;
1483  }
1484 
1485 
1486  /*
1487  * Produce DFS compliant FITS header for image
1488  */
1489 
1490  if (header == NULL)
1491  plist = cpl_propertylist_new();
1492  else
1493  plist = header;
1494 
1495  if (cpl_dfs_setup_product_header(plist, frame, frameset, parlist,
1496  recipename, version, "PRO-1.15", NULL)) {
1497  cpl_msg_error(cpl_func, "Error found in %s: %s",
1498  cpl_error_get_where(), cpl_error_get_message());
1499  cpl_msg_error(func, "Problem with product %s FITS header definition",
1500  category);
1501  if (header == NULL)
1502  cpl_propertylist_delete(plist);
1503  cpl_frame_delete(frame);
1504  cpl_free(filename);
1505  return -1;
1506  }
1507 
1508  /*
1509  * Write image to disk
1510  */
1511 
1512  if (cpl_image_save(image, filename, CPL_BPP_IEEE_FLOAT, plist,
1513  CPL_IO_DEFAULT)) {
1514  cpl_msg_error(cpl_func, "Error found in %s: %s",
1515  cpl_error_get_where(), cpl_error_get_message());
1516  cpl_msg_error(func, "Cannot save product %s to disk", filename);
1517  if (header == NULL)
1518  cpl_propertylist_delete(plist);
1519  cpl_frame_delete(frame);
1520  cpl_free(filename);
1521  return -1;
1522  }
1523 
1524  if (header == NULL)
1525  cpl_propertylist_delete(plist);
1526 
1527  cpl_free(filename);
1528 
1529  cpl_frameset_insert(frameset, frame);
1530 
1531  return 0;
1532 }
1533 
1534 /*----------------------------------------------------------------------------*/
1566 /*----------------------------------------------------------------------------*/
1567 int dfs_save_table(cpl_frameset *frameset, const cpl_table *table,
1568  const char *category, cpl_propertylist *header,
1569  const cpl_parameterlist *parlist, const char *recipename,
1570  const char *version)
1571 {
1572  const char *func = "dfs_save_table";
1573 
1574  char *filename;
1575  cpl_frame *frame;
1576  cpl_propertylist *plist;
1577 
1578 
1579  if (category == NULL || frameset == NULL || table == NULL) {
1580  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
1581  cpl_msg_error(cpl_func, "Error found in %s: %s",
1582  cpl_error_get_where(), cpl_error_get_message());
1583  return -1;
1584  }
1585 
1586  cpl_msg_info(func, "Saving %s table to disk...", category);
1587 
1588  filename = cpl_calloc(strlen(category) + 6, sizeof(char));
1589 
1590  strlower(strcpy(filename, category));
1591 
1592  strcat(filename, ".fits");
1593 
1594  frame = cpl_frame_new();
1595 
1596  cpl_frame_set_filename(frame, filename);
1597  cpl_frame_set_tag(frame, category);
1598  cpl_frame_set_type(frame, CPL_FRAME_TYPE_TABLE);
1599  cpl_frame_set_group(frame, CPL_FRAME_GROUP_PRODUCT);
1600  cpl_frame_set_level(frame, CPL_FRAME_LEVEL_FINAL);
1601  if (cpl_error_get_code()) {
1602  cpl_msg_error(cpl_func, "Error found in %s: %s",
1603  cpl_error_get_where(), cpl_error_get_message());
1604  cpl_msg_error(func, "Cannot initialise the product frame");
1605  cpl_frame_delete(frame);
1606  cpl_free(filename);
1607  return -1;
1608  }
1609 
1610 
1611  /*
1612  * Produce DFS compliant FITS header for table
1613  */
1614 
1615  if (header == NULL)
1616  plist = cpl_propertylist_new();
1617  else
1618  plist = header;
1619 
1620  if (cpl_dfs_setup_product_header(plist, frame, frameset, parlist,
1621  recipename, version, "PRO-1.15", NULL)) {
1622  cpl_msg_error(cpl_func, "Error found in %s: %s",
1623  cpl_error_get_where(), cpl_error_get_message());
1624  cpl_msg_error(func, "Problem with product %s FITS header definition",
1625  category);
1626  if (header == NULL)
1627  cpl_propertylist_delete(plist);
1628  cpl_frame_delete(frame);
1629  cpl_free(filename);
1630  return -1;
1631  }
1632 
1633  /*
1634  * Write table to disk
1635  */
1636 
1637  if (cpl_table_save(table, plist, NULL, filename, CPL_IO_DEFAULT)) {
1638  cpl_msg_error(cpl_func, "Error found in %s: %s",
1639  cpl_error_get_where(), cpl_error_get_message());
1640  cpl_msg_error(func, "Cannot save product %s to disk", filename);
1641  if (header == NULL)
1642  cpl_propertylist_delete(plist);
1643  cpl_frame_delete(frame);
1644  cpl_free(filename);
1645  return -1;
1646  }
1647 
1648  if (header == NULL)
1649  cpl_propertylist_delete(plist);
1650  cpl_free(filename);
1651 
1652  cpl_frameset_insert(frameset, frame);
1653 
1654  return 0;
1655 }
1656 
1657 /*----------------------------------------------------------------------------*/
1674 /*----------------------------------------------------------------------------*/
1675 int dfs_equal_keyword(cpl_frameset *frameset, const char *keyword)
1676 {
1677  const char *func = "dfs_equal_keyword";
1678 
1679  cpl_frame *frame;
1680  cpl_propertylist *reference;
1681  cpl_type rtype;
1682  cpl_type type;
1683  const char *rstring;
1684  const char *string;
1685  int rintero;
1686  int intero;
1687  int found;
1688 
1689 
1690  if (frameset == NULL || keyword == NULL) {
1691  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
1692  return 0;
1693  }
1694 
1695  if (cpl_frameset_is_empty(frameset)) {
1696  cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
1697  return 0;
1698  }
1699 
1700  frame = cpl_frameset_get_first(frameset);
1701 
1702  found = 0;
1703 
1704  while (frame) {
1705 
1706  reference = cpl_propertylist_load(cpl_frame_get_filename(frame), 0);
1707  if (cpl_error_get_code() == CPL_ERROR_BAD_FILE_FORMAT) {
1708  cpl_error_reset();
1709  frame = cpl_frameset_get_next(frameset);
1710  continue;
1711  }
1712 
1713  if (cpl_propertylist_has(reference, keyword)) {
1714  rtype = cpl_propertylist_get_type(reference, keyword);
1715 
1716  if (rtype == CPL_TYPE_STRING) {
1717  found = 1;
1718  rstring = cpl_strdup(cpl_propertylist_get_string(reference,
1719  keyword));
1720  cpl_propertylist_delete(reference);
1721  break;
1722  }
1723 
1724  if (rtype == CPL_TYPE_INT) {
1725  found = 1;
1726  rintero = cpl_propertylist_get_int(reference, keyword);
1727  cpl_propertylist_delete(reference);
1728  break;
1729  }
1730 
1731  cpl_propertylist_delete(reference);
1732  return 0;
1733  }
1734 
1735  cpl_propertylist_delete(reference);
1736 
1737  frame = cpl_frameset_get_next(frameset);
1738  }
1739 
1740 
1741  if (!found)
1742  return 1;
1743 
1744  frame = cpl_frameset_get_first(frameset);
1745 
1746  while (frame) {
1747 
1748  reference = cpl_propertylist_load(cpl_frame_get_filename(frame), 0);
1749  if (cpl_error_get_code() == CPL_ERROR_BAD_FILE_FORMAT) {
1750  cpl_error_reset();
1751  frame = cpl_frameset_get_next(frameset);
1752  continue;
1753  }
1754 
1755  if (cpl_propertylist_has(reference, keyword)) {
1756 
1757  type = cpl_propertylist_get_type(reference, keyword);
1758 
1759  if (rtype != type) {
1760  cpl_propertylist_delete(reference);
1761  return 0;
1762  }
1763 
1764  if (rtype == CPL_TYPE_STRING) {
1765  string = cpl_propertylist_get_string(reference,
1766  keyword);
1767  if (strncmp(rstring, string, 15)) {
1768  cpl_propertylist_delete(reference);
1769  return 0;
1770  }
1771  }
1772 
1773  if (rtype == CPL_TYPE_INT) {
1774  intero = cpl_propertylist_get_int(reference, keyword);
1775  if (rintero - intero) {
1776  cpl_propertylist_delete(reference);
1777  return 0;
1778  }
1779  }
1780  }
1781 
1782  cpl_propertylist_delete(reference);
1783 
1784  frame = cpl_frameset_get_next(frameset);
1785  }
1786 
1787  if (rtype == CPL_TYPE_STRING)
1788  cpl_free((void *)rstring);
1789 
1790  return 1;
1791 
1792 }
1793 
1803 cpl_error_code dfs_save_table_ext(cpl_table * table,
1804  const char * tag,
1805  cpl_propertylist * extheader)
1806 {
1807  char * filename = cpl_calloc(strlen(tag) + 6, sizeof(char));
1808  cpl_propertylist * header;
1809 
1810  if (extheader) {
1811  header = cpl_propertylist_duplicate(extheader);
1812 
1813  cpl_propertylist_erase_regexp(header,
1814  "^ESO DPR |^ARCFILE$|^ORIGFILE$", 0);
1815  } else {
1816  header = NULL;
1817  }
1818 
1819  strlower(strcpy(filename, tag));
1820  strcat(filename, ".fits");
1821 
1822  if (cpl_table_save(table, NULL, header, filename, CPL_IO_EXTEND)) {
1823  cpl_free(filename);
1824  cpl_ensure_code(0, CPL_ERROR_FILE_IO);
1825  }
1826 
1827  cpl_propertylist_delete(header);
1828  cpl_free(filename);
1829 
1830  return CPL_ERROR_NONE;
1831 }
1832 
1842 cpl_error_code dfs_save_image_ext(cpl_image * image,
1843  const char * tag,
1844  cpl_propertylist * extheader)
1845 {
1846  char * filename = cpl_calloc(strlen(tag) + 6, sizeof(char));
1847 
1848  cpl_propertylist * header;
1849 
1850  if (extheader) {
1851  header = cpl_propertylist_duplicate(extheader);
1852 
1853  cpl_propertylist_erase_regexp(header,
1854  "^ESO DPR |^ARCFILE$|^ORIGFILE$", 0);
1855  } else {
1856  header = NULL;
1857  }
1858 
1859  strlower(strcpy(filename, tag));
1860  strcat(filename, ".fits");
1861 
1862  if (cpl_image_save(image, filename, CPL_BPP_IEEE_FLOAT,
1863  header, CPL_IO_EXTEND)) {
1864  cpl_free(filename);
1865  cpl_ensure_code(0, CPL_ERROR_FILE_IO);
1866  }
1867 
1868  cpl_propertylist_delete(header);
1869  cpl_free(filename);
1870 
1871  return CPL_ERROR_NONE;
1872 }
1873 
1885 cpl_error_code dfs_save_image_null(cpl_frameset * frameset,
1886  cpl_parameterlist * parlist,
1887  const char * tag,
1888  const char * recipename,
1889  const char * version)
1890 {
1891 
1892  char * filename = cpl_calloc(strlen(tag) + 6, sizeof(char));
1893 
1894  cpl_error_code error;
1895 
1896  cpl_propertylist * pro = cpl_propertylist_new();
1897 
1898  cpl_propertylist_append_string(pro, "ESO PRO CATG", tag);
1899 
1900  strlower(strcpy(filename, tag));
1901  strcat(filename, ".fits");
1902 
1903  error = cpl_dfs_save_image(frameset, NULL, parlist, frameset, NULL, NULL,
1904  CPL_BPP_IEEE_FLOAT, recipename, pro,
1905  NULL, version, filename);
1906 
1907  cpl_free(filename);
1908  cpl_propertylist_delete(pro);
1909 
1910  return error;
1911 }
1912 
1913 
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:1266
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:852
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:598
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:956
void fors_dfs_add_exptime(cpl_propertylist *header, const cpl_frame *frame, double exptime)
Add keyword EXPTIME to header.
Definition: fors_dfs.c:1359
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:1885
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:1842
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:1141
static void dfs_save(cpl_frameset *frameset, const void *object, fors_type type, const char *category, cpl_propertylist *header, cpl_propertylist *extra_header, const cpl_parameterlist *parlist, const char *recipename, const cpl_frame *inherit_frame)
Save DFS product.
Definition: fors_dfs.c:988
#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:695
int dfs_equal_keyword(cpl_frameset *frameset, const char *keyword)
Saving table data of given category.
Definition: fors_dfs.c:1675
int dfs_get_parameter_int_const(const cpl_parameterlist *parlist, const char *name)
Definition: fors_dfs.c:798
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:1803
int dfs_get_parameter_bool_const(const cpl_parameterlist *parlist, const char *name)
Definition: fors_dfs.c:788
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:1399
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:1176
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:1443
cpl_table * dfs_load_table(cpl_frameset *frameset, const char *category, int ext)
Loading table data of given category.
Definition: fors_dfs.c:908
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:407
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:1567
const char * dfs_get_parameter_string_const(const cpl_parameterlist *parlist, const char *name)
Definition: fors_dfs.c:818
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:502
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:360
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:1305
void fors_image_save(const fors_image *image, const cpl_propertylist *header, const cpl_propertylist *err_header, const char *filename)
Save image.
Definition: fors_image.c:375
double dfs_get_parameter_double_const(const cpl_parameterlist *parlist, const char *name)
Definition: fors_dfs.c:808
void fors_dfs_save_image_err(cpl_frameset *frameset, const fors_image *image, const char *category, cpl_propertylist *header, cpl_propertylist *err_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:1229