FORS Pipeline Reference Manual  5.0.1
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, "MASTER_NORM_FLAT_LONG_MOS" ) == 0 ||
304  strcmp(tag, "SLIT_LOCATION_MOS" ) == 0 ||
305  strcmp(tag, "SLIT_LOCATION_MXU" ) == 0 ||
306  strcmp(tag, "SLIT_LOCATION_LSS" ) == 0 ||
307  strcmp(tag, "SLIT_LOCATION_LONG_MOS" ) == 0 ||
308  strcmp(tag, "CURV_COEFF_MOS" ) == 0 ||
309  strcmp(tag, "CURV_COEFF_MXU" ) == 0 ||
310  strcmp(tag, "CURV_COEFF_LSS" ) == 0 ||
311  strcmp(tag, "DISP_COEFF_MOS" ) == 0 ||
312  strcmp(tag, "DISP_COEFF_MXU" ) == 0 ||
313  strcmp(tag, "DISP_COEFF_LSS" ) == 0 ||
314  strcmp(tag, "DISP_COEFF_LONG_MOS" ) == 0 ||
315  strcmp(tag, "FLAT_SED_MOS" ) == 0 ||
316  strcmp(tag, "FLAT_SED_MXU" ) == 0 ||
317  strcmp(tag, "FLAT_SED_LSS" ) == 0 ||
318  strcmp(tag, "FLAT_SED_LONG_MOS" ) == 0 ||
319  /* static calibration */
320  strcmp(tag, FLX_STD_IMG ) == 0 ||
321  strcmp(tag, "EXTINCT_TABLE" ) == 0 ||
322  strcmp(tag, "MASTER_LINECAT" ) == 0 ||
323  strcmp(tag, "MASTER_DISTORTION_TABLE" ) == 0 ||
324  strcmp(tag, "GLOBAL_DISTORTION_TABLE" ) == 0 ||
325  strcmp(tag, "RETARDER_WAVEPLATE_CHROMATISM") == 0 ||
326  strcmp(tag, "GRISM_TABLE" ) == 0 ||
327  strcmp(tag, "STD_PMOS_TABLE" ) == 0 ||
328  strcmp(tag, "TELLURIC_CONTAMINATION" ) == 0 ||
329  strcmp(tag, "STD_FLUX_TABLE" ) == 0 ||
330  strcmp(tag, "SPECPHOT_TABLE" ) == 0 ||
331  strcmp(tag, PHOT_TABLE ) == 0) {
332  cpl_frame_set_group(f, CPL_FRAME_GROUP_CALIB);
333  }
334  else {
335  cpl_msg_warning(cpl_func, "Unrecognized frame tag: '%s'",
336  tag);
337  }
338  }
339  }
340 
341  return;
342 }
343 
344 /*----------------------------------------------------------------------------*/
345 #undef cleanup
346 #define cleanup
347 
355 /*----------------------------------------------------------------------------*/
356 const char *
357 fors_dfs_pipeline_version(const cpl_propertylist *header,
358  const char **instrument_version)
359 {
360  const char *instrume = NULL;
361 
362  instrume = cpl_propertylist_get_string(header,
363  FORS_PFITS_INSTRUME);
364  assure( !cpl_error_get_code(), return NULL,
365  "Missing keyword %s in input header", FORS_PFITS_INSTRUME);
366 
367  assure( strlen(instrume) >= 5, return NULL,
368  "%s keyword must be 'fors1' or 'fors2', not '%s'",
369  FORS_PFITS_INSTRUME, instrume);
370 
371  assure( instrume[4] == '1' || instrume[4] == '2', return NULL,
372  "Unrecognized %s: %s", FORS_PFITS_INSTRUME, instrume);
373 
374  if (instrument_version != NULL) {
375  *instrument_version = cpl_sprintf("%s", instrume);
376  }
377 
378  return cpl_sprintf("fors%c/%s", instrume[4], PACKAGE_VERSION);
379 }
380 
381 /*----------------------------------------------------------------------------*/
403 /*----------------------------------------------------------------------------*/
404 int dfs_get_parameter_int(cpl_parameterlist *parlist, const char *name,
405  const cpl_table *defaults)
406 {
407  const char *func = "dfs_get_parameter_int";
408 
409  const char *alias;
410  cpl_parameter *param;
411 
412 
413  if (parlist == NULL) {
414  cpl_msg_error(func, "Missing input parameter list");
415  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
416  return 0;
417  }
418 
419  if (name == NULL) {
420  cpl_msg_error(func, "Missing input parameter name");
421  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
422  return 0;
423  }
424 
425  param = cpl_parameterlist_find(parlist, name);
426 
427  if (param == NULL) {
428  cpl_msg_error(func, "Wrong parameter name: %s", name);
429  cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
430  return 0;
431  }
432 
433  if (cpl_parameter_get_type(param) != CPL_TYPE_INT) {
434  cpl_msg_error(func, "Unexpected type for parameter "
435  "\"%s\": it should be integer", name);
436  cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
437  return 0;
438  }
439 
440  alias = cpl_parameter_get_alias(param, CPL_PARAMETER_MODE_CLI);
441 
442 // if (defaults && cpl_parameter_get_default_flag(param) == 0) {
443  if (defaults &&
444  cpl_parameter_get_default_int(param) == cpl_parameter_get_int(param)) {
445 
446  if (cpl_table_has_column(defaults, alias)) {
447  if (cpl_table_get_column_type(defaults, alias) != CPL_TYPE_INT) {
448  cpl_msg_error(func, "Unexpected type for GRISM_TABLE "
449  "column \"%s\": it should be integer", alias);
450  cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
451  return 0;
452  }
453  if (cpl_table_is_valid(defaults, alias, 0)) {
454  cpl_parameter_set_int(param, cpl_table_get_int(defaults,
455  alias, 0, NULL));
456  }
457  else {
458  cpl_msg_error(func, "Invalid parameter value in table "
459  "column \"%s\"", alias);
460  cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
461  return 0;
462  }
463  }
464  else {
465  cpl_msg_warning(func, "Parameter \"%s\" not found in GRISM_TABLE "
466  "- using recipe default", alias);
467  }
468  }
469 
470  cpl_msg_info(func, "%s:", alias);
471  cpl_msg_info(func, "%s: %d",
472  cpl_parameter_get_help(param), cpl_parameter_get_int(param));
473 
474  return cpl_parameter_get_int(param);
475 
476 }
477 
478 /*----------------------------------------------------------------------------*/
500 /*----------------------------------------------------------------------------*/
501 double dfs_get_parameter_double(cpl_parameterlist *parlist,
502  const char *name, const cpl_table *defaults)
503 {
504  const char *func = "dfs_get_parameter_double";
505 
506  const char *alias;
507  cpl_parameter *param;
508 
509 
510  if (parlist == NULL) {
511  cpl_msg_error(func, "Missing input parameter list");
512  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
513  return 0;
514  }
515 
516  if (name == NULL) {
517  cpl_msg_error(func, "Missing input parameter name");
518  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
519  return 0;
520  }
521 
522  param = cpl_parameterlist_find(parlist, name);
523 
524  if (param == NULL) {
525  cpl_msg_error(func, "Wrong parameter name: %s", name);
526  cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
527  return 0;
528  }
529 
530  if (cpl_parameter_get_type(param) != CPL_TYPE_DOUBLE) {
531  cpl_msg_error(func, "Unexpected type for parameter "
532  "\"%s\": it should be double", name);
533  cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
534  return 0;
535  }
536 
537  alias = cpl_parameter_get_alias(param, CPL_PARAMETER_MODE_CLI);
538 
539 // if (defaults && cpl_parameter_get_default_flag(param) == 0) {
540  if (defaults &&
541  cpl_parameter_get_default_double(param) ==
542  cpl_parameter_get_double(param)) {
543 
544  if (cpl_table_has_column(defaults, alias)) {
545  if (cpl_table_get_column_type(defaults, alias) != CPL_TYPE_DOUBLE) {
546  cpl_msg_error(func, "Unexpected type for GRISM_TABL "
547  "column \"%s\": it should be double", alias);
548  cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
549  return 0;
550  }
551  if (cpl_table_is_valid(defaults, alias, 0)) {
552  cpl_parameter_set_double(param, cpl_table_get_double(defaults,
553  alias, 0, NULL));
554  }
555  else {
556  cpl_msg_error(func, "Invalid parameter value in table "
557  "column \"%s\"", alias);
558  cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
559  return 0;
560  }
561  }
562  else {
563  cpl_msg_warning(func, "Parameter \"%s\" not found in GRISM_TABLE "
564  "- using recipe default", alias);
565  }
566  }
567 
568  cpl_msg_info(func, "%s:", alias);
569  cpl_msg_info(func, "%s: %f",
570  cpl_parameter_get_help(param), cpl_parameter_get_double(param));
571 
572  return cpl_parameter_get_double(param);
573 
574 }
575 
576 /*----------------------------------------------------------------------------*/
598 /*----------------------------------------------------------------------------*/
599 const char *dfs_get_parameter_string(cpl_parameterlist *parlist,
600  const char *name,
601  const cpl_table *defaults)
602 {
603  const char *func = "dfs_get_parameter_string";
604 
605  const char *alias;
606  cpl_parameter *param;
607 
608 
609  if (parlist == NULL) {
610  cpl_msg_error(func, "Missing input parameter list");
611  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
612  return 0;
613  }
614 
615  if (name == NULL) {
616  cpl_msg_error(func, "Missing input parameter name");
617  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
618  return 0;
619  }
620 
621  param = cpl_parameterlist_find(parlist, name);
622 
623  if (param == NULL) {
624  cpl_msg_error(func, "Wrong parameter name: %s", name);
625  cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
626  return 0;
627  }
628 
629  if (cpl_parameter_get_type(param) != CPL_TYPE_STRING) {
630  cpl_msg_error(func, "Unexpected type for parameter "
631  "\"%s\": it should be string", name);
632  cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
633  return 0;
634  }
635 
636  alias = cpl_parameter_get_alias(param, CPL_PARAMETER_MODE_CLI);
637 
638 // if (defaults && cpl_parameter_get_default_flag(param) == 0) {
639  if (defaults &&
640  strcmp(cpl_parameter_get_default_string(param),
641  cpl_parameter_get_string(param)) == 0) {
642 
643  if (cpl_table_has_column(defaults, alias)) {
644  if (cpl_table_get_column_type(defaults, alias) != CPL_TYPE_STRING) {
645  cpl_msg_error(func, "Unexpected type for GRISM_TABLE "
646  "column \"%s\": it should be string", alias);
647  cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
648  return 0;
649  }
650  if (cpl_table_is_valid(defaults, alias, 0)) {
651  cpl_parameter_set_string(param, cpl_table_get_string(defaults,
652  alias, 0));
653  }
654  else {
655  cpl_msg_error(func, "Invalid parameter value in table "
656  "column \"%s\"", alias);
657  cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
658  return 0;
659  }
660  }
661  else {
662  cpl_msg_warning(func, "Parameter \"%s\" not found in GRISM_TABLE "
663  "- using recipe default", alias);
664  }
665  }
666 
667  cpl_msg_info(func, "%s:", alias);
668  cpl_msg_info(func, "%s: %s", cpl_parameter_get_help(param),
669  cpl_parameter_get_string(param));
670 
671  return cpl_parameter_get_string(param);
672 
673 }
674 
675 /*----------------------------------------------------------------------------*/
697 /*----------------------------------------------------------------------------*/
698 int dfs_get_parameter_bool(cpl_parameterlist *parlist, const char *name,
699  const cpl_table *defaults)
700 {
701  const char *func = "dfs_get_parameter_bool";
702 
703  const char *alias;
704  cpl_parameter *param;
705  int value;
706 
707 
708  if (parlist == NULL) {
709  cpl_msg_error(func, "Missing input parameter list");
710  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
711  return 0;
712  }
713 
714  if (name == NULL) {
715  cpl_msg_error(func, "Missing input parameter name");
716  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
717  return 0;
718  }
719 
720  param = cpl_parameterlist_find(parlist, name);
721 
722  if (param == NULL) {
723  cpl_msg_error(func, "Wrong parameter name: %s", name);
724  cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
725  return 0;
726  }
727 
728  if (cpl_parameter_get_type(param) != CPL_TYPE_BOOL) {
729  cpl_msg_error(func, "Unexpected type for parameter "
730  "\"%s\": it should be boolean", name);
731  cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
732  return 0;
733  }
734 
735  alias = cpl_parameter_get_alias(param, CPL_PARAMETER_MODE_CLI);
736 
737 // if (defaults && cpl_parameter_get_default_flag(param) == 0) {
738  if (defaults &&
739  cpl_parameter_get_default_bool(param) ==
740  cpl_parameter_get_bool(param)) {
741 
742  if (cpl_table_has_column(defaults, alias)) {
743  if (cpl_table_get_column_type(defaults, alias) != CPL_TYPE_INT) {
744  cpl_msg_error(func, "Unexpected type for GRISM_TABLE "
745  "column \"%s\": it should be integer", alias);
746  cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
747  return 0;
748  }
749  if (cpl_table_is_valid(defaults, alias, 0)) {
750  value = cpl_table_get_int(defaults, alias, 0, NULL);
751  if (value < 0 || value > 1) {
752  cpl_msg_error(func, "Illegal parameter value in table "
753  "column \"%s\": it should be either 0 or 1",
754  alias);
755  cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
756  return 0;
757  }
758  cpl_parameter_set_bool(param, value);
759  }
760  else {
761  cpl_msg_error(func, "Invalid parameter value in table "
762  "column \"%s\"", alias);
763  cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
764  return 0;
765  }
766  }
767  else {
768  cpl_msg_warning(func, "Parameter \"%s\" not found in GRISM_TABLE "
769  "- using recipe default", alias);
770  }
771  }
772 
773  value = cpl_parameter_get_bool(param);
774 
775  if (value) {
776  cpl_msg_info(func, "%s:", alias);
777  cpl_msg_info(func, "%s: TRUE", cpl_parameter_get_help(param));
778  }
779  else {
780  cpl_msg_info(func, "%s:", alias);
781  cpl_msg_info(func, "%s: FALSE", cpl_parameter_get_help(param));
782  }
783 
784  return value;
785 
786 }
787 
788 /*----------------------------------------------------------------------------*/
792 /*----------------------------------------------------------------------------*/
793 int dfs_get_parameter_bool_const(const cpl_parameterlist *parlist, const char *name)
794 {
795  return dfs_get_parameter_bool((cpl_parameterlist *)parlist, name, NULL);
796 }
797 
798 /*----------------------------------------------------------------------------*/
802 /*----------------------------------------------------------------------------*/
803 int dfs_get_parameter_int_const(const cpl_parameterlist *parlist, const char *name)
804 {
805  return dfs_get_parameter_int((cpl_parameterlist *)parlist, name, NULL);
806 }
807 
808 /*----------------------------------------------------------------------------*/
812 /*----------------------------------------------------------------------------*/
813 double dfs_get_parameter_double_const(const cpl_parameterlist *parlist, const char *name)
814 {
815  return dfs_get_parameter_double((cpl_parameterlist *)parlist, name, NULL);
816 }
817 
818 /*----------------------------------------------------------------------------*/
822 /*----------------------------------------------------------------------------*/
823 const char *dfs_get_parameter_string_const(const cpl_parameterlist *parlist, const char *name)
824 {
825  return dfs_get_parameter_string((cpl_parameterlist *)parlist, name, NULL);
826 }
827 
828 /*----------------------------------------------------------------------------*/
856 /*----------------------------------------------------------------------------*/
857 cpl_image *dfs_load_image(cpl_frameset *frameset, const char *category,
858  cpl_type type, int ext, int calib)
859 {
860  const char *func = "dfs_load_image";
861 
862  cpl_frame *frame = NULL;
863  cpl_image *image = NULL;
864 
865 
866  frame = cpl_frameset_find(frameset, category);
867 
868  if (frame) {
869  image = cpl_image_load(cpl_frame_get_filename(frame), type, 0, ext);
870  if (image == NULL) {
871  cpl_msg_error(cpl_error_get_where(),"%s", cpl_error_get_message());
872  cpl_msg_error(func, "Cannot load image %s",
873  cpl_frame_get_filename(frame));
874  }
875  else {
876  if (calib)
877  cpl_frame_set_group(frame, CPL_FRAME_GROUP_CALIB);
878  else
879  cpl_frame_set_group(frame, CPL_FRAME_GROUP_RAW);
880  }
881  }
882 
883  return image;
884 }
885 
886 /*----------------------------------------------------------------------------*/
912 /*----------------------------------------------------------------------------*/
913 cpl_table *dfs_load_table(cpl_frameset *frameset, const char *category, int ext)
914 {
915  const char *func = "dfs_load_table";
916 
917  cpl_frame *frame = NULL;
918  cpl_table *table = NULL;
919 
920 
921  frame = cpl_frameset_find(frameset, category);
922 
923  if (frame) {
924  table = cpl_table_load(cpl_frame_get_filename(frame), ext, 1);
925  if (table == NULL) {
926  cpl_msg_error(cpl_error_get_where(), "%s", cpl_error_get_message());
927  cpl_msg_error(func, "Cannot load table %s",
928  cpl_frame_get_filename(frame));
929  }
930  }
931 
932  return table;
933 }
934 
935 /*----------------------------------------------------------------------------*/
960 /*----------------------------------------------------------------------------*/
961 cpl_propertylist *dfs_load_header(cpl_frameset *frameset,
962  const char *category, int ext)
963 {
964  const char *func = "dfs_load_header";
965 
966  cpl_frame *frame = NULL;
967  cpl_propertylist *plist = NULL;
968 
969 
970  frame = cpl_frameset_find(frameset, category);
971 
972  if (frame) {
973  plist = cpl_propertylist_load(cpl_frame_get_filename(frame), ext);
974  if (plist == NULL) {
975  cpl_msg_error(cpl_error_get_where(), "%s", cpl_error_get_message());
976  cpl_msg_error(func, "Cannot load header from %s",
977  cpl_frame_get_filename(frame));
978  }
979  }
980 
981  return plist;
982 }
983 
984 /*----------------------------------------------------------------------------*/
991 /*----------------------------------------------------------------------------*/
992 static void
993 dfs_save(cpl_frameset *frameset, const void *object, fors_type type,
994  const char *category, cpl_propertylist *header,
995  const cpl_parameterlist *parlist, const char *recipename,
996  const cpl_frame *inherit_frame)
997 {
998  char *filename;
999  cpl_frame *frame;
1000  cpl_propertylist *plist;
1001  const char *version = NULL;
1002  cpl_propertylist *raw_header = NULL;
1003 
1004 
1005  if (category == NULL || frameset == NULL || object == NULL ||
1006  inherit_frame == NULL) {
1007  cpl_msg_error(cpl_error_get_where(), "%s", cpl_error_get_message());
1008  cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
1009  return;
1010  }
1011 
1012  if (type == FORS_TYPE_TABLE) {
1013  cpl_msg_debug(cpl_func, "Saving %s table to disk...", category);
1014  }
1015  else {
1016  cpl_msg_debug(cpl_func, "Saving %s image to disk...", category);
1017  }
1018 
1019  /* Read instrument version from raw frame */
1020  {
1021  const char *raw_filename =
1022  cpl_frame_get_filename(inherit_frame);
1023 
1024  raw_header = cpl_propertylist_load(raw_filename, 0);
1025  if (cpl_error_get_code() != CPL_ERROR_NONE) {
1026  cpl_msg_error(cpl_func, "Could not read %s primary header", raw_filename);
1027  return;
1028  }
1029 
1030  version = fors_dfs_pipeline_version(raw_header, NULL);
1031  cpl_propertylist_delete(raw_header);
1032 
1033  if (cpl_error_get_code() != CPL_ERROR_NONE) {
1034  cpl_msg_error(cpl_func, "Could not identify instrument version from %s header",
1035  raw_filename);
1036  return;
1037  }
1038  }
1039 
1040  filename = cpl_calloc(strlen(category) + 6, sizeof(char));
1041 
1042  strlower(strcpy(filename, category));
1043  strcat(filename, ".fits");
1044 
1045  frame = cpl_frame_new();
1046 
1047  cpl_frame_set_filename(frame, filename);
1048  cpl_frame_set_tag(frame, category);
1049  cpl_frame_set_type(frame, CPL_FRAME_TYPE_ANY);
1050  cpl_frame_set_group(frame, CPL_FRAME_GROUP_PRODUCT);
1051  cpl_frame_set_level(frame, CPL_FRAME_LEVEL_FINAL);
1052  if (cpl_error_get_code()) {
1053  cpl_msg_error(cpl_error_get_where(), "%s", cpl_error_get_message());
1054  cpl_msg_error(cpl_func, "Cannot initialise the product frame");
1055  cpl_frame_delete(frame);
1056  cpl_free(filename);
1057  cpl_free((void *)version);
1058  return;
1059  }
1060 
1061 
1062  /*
1063  * Produce DFS compliant FITS header for product
1064  */
1065 
1066  if (header == NULL)
1067  plist = cpl_propertylist_new();
1068  else
1069  plist = header;
1070 
1071  if (cpl_dfs_setup_product_header(plist, frame, frameset, parlist,
1072  recipename, version, "PRO-1.15",
1073  inherit_frame)) {
1074  cpl_msg_error(cpl_func, "Error found in %s: %s",
1075  cpl_error_get_where(), cpl_error_get_message());
1076  cpl_msg_error(cpl_func, "Problem with product %s FITS header definition",
1077  category);
1078  if (header == NULL)
1079  cpl_propertylist_delete(plist);
1080  cpl_frame_delete(frame);
1081  cpl_free(filename);
1082  cpl_free((void *)version);
1083  return;
1084  }
1085 
1086  cpl_free((void *)version);
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  cpl_free(filename);
1210 
1211 }
1212 
1213 /*----------------------------------------------------------------------------*/
1234 /*----------------------------------------------------------------------------*/
1235 void
1236 fors_dfs_save_image_err(cpl_frameset *frameset, const fors_image *image,
1237  const char *category, cpl_propertylist *header,
1238  const cpl_parameterlist *parlist, const char *recipename,
1239  const cpl_frame *inherit_frame)
1240 {
1241  dfs_save(frameset, image, FORS_TYPE_IMAGE_ERR,
1242  category, header,
1243  parlist, recipename,
1244  inherit_frame);
1245 }
1246 
1247 /*----------------------------------------------------------------------------*/
1270 /*----------------------------------------------------------------------------*/
1271 void
1272 fors_dfs_save_image_err_mask(cpl_frameset *frameset, const fors_image *image,
1273  const cpl_image *mask, const char *category,
1274  cpl_propertylist *header,
1275  const cpl_parameterlist *parlist, const char *recipename,
1276  const cpl_frame *inherit_frame)
1277 {
1278  char *filename;
1279  cpl_propertylist * extension_header;
1280 
1281  dfs_save(frameset, image, FORS_TYPE_IMAGE_ERR,
1282  category, header,
1283  parlist, recipename,
1284  inherit_frame);
1285 
1286  extension_header = cpl_propertylist_new();
1287  cpl_propertylist_append_string(extension_header,
1288  "EXTNAME", "IMAGE.BPM");
1289 
1290  filename = cpl_calloc(strlen(category) + 6, sizeof(char));
1291 
1292  strlower(strcpy(filename, category));
1293  strcat(filename, ".fits");
1294 
1295  cpl_image_save(mask, filename, CPL_BPP_IEEE_FLOAT, extension_header,
1296  CPL_IO_EXTEND);
1297  cpl_propertylist_delete(extension_header);
1298  cpl_free(filename);
1299 }
1300 
1301 #undef cleanup
1302 #define cleanup \
1303 do { \
1304  cpl_propertylist_delete(wcs_header); \
1305 } while (0)
1306 
1311 void fors_dfs_add_wcs(cpl_propertylist *header, const cpl_frame *frame,
1312  const fors_setting *setting)
1313 {
1314  bool invert = false;
1315  int extension = 0;
1316 
1317  cpl_propertylist *wcs_header =
1318  cpl_propertylist_load_regexp(cpl_frame_get_filename(frame),
1319  extension, WCS_KEYS, invert);
1320 
1321  cpl_propertylist_copy_property_regexp(header, wcs_header, ".*", invert);
1322 
1323  double crpix1 = cpl_propertylist_get_double(header, FORS_PFITS_CRPIX1);
1324 
1325  assure( !cpl_error_get_code(), return,
1326  "Could not read %s from %s", FORS_PFITS_CRPIX1,
1327  cpl_frame_get_filename(frame));
1328 
1329  double crpix2 = cpl_propertylist_get_double(header, FORS_PFITS_CRPIX2);
1330 
1331  assure( !cpl_error_get_code(), return,
1332  "Could not read %s from %s", FORS_PFITS_CRPIX2,
1333  cpl_frame_get_filename(frame));
1334 
1335  cpl_propertylist_update_double(header, FORS_PFITS_CRPIX1,
1336  crpix1 - setting->prescan_x);
1337 
1338  cpl_propertylist_update_double(header, FORS_PFITS_CRPIX2,
1339  crpix2 - setting->prescan_y);
1340 
1341 
1342  cleanup;
1343  return;
1344 }
1345 
1346 /*----------------------------------------------------------------------------*/
1347 #undef cleanup
1348 #define cleanup \
1349 do { \
1350  cpl_propertylist_delete(time_header); \
1351 } while (0)
1352 
1364 /*----------------------------------------------------------------------------*/
1365 void fors_dfs_add_exptime(cpl_propertylist *header, const cpl_frame *frame,
1366  double exptime)
1367 {
1368  bool invert = false;
1369  int extension = 0;
1370 
1371  cpl_propertylist *time_header = NULL;
1372 
1373  if (frame) {
1374 
1375  time_header =
1376  cpl_propertylist_load_regexp(cpl_frame_get_filename(frame),
1377  extension, "EXPTIME", invert);
1378 
1379  if (time_header) {
1380  cpl_propertylist_copy_property_regexp(header,
1381  time_header, ".*", invert);
1382  }
1383  else {
1384  cpl_error_reset();
1385  }
1386  }
1387  else {
1388  while (cpl_propertylist_erase(header, "EXPTIME"));
1389  cpl_propertylist_update_double(header, "EXPTIME", exptime);
1390  }
1391 
1392  cleanup;
1393  return;
1394 }
1395 
1396 /*----------------------------------------------------------------------------*/
1403 /*----------------------------------------------------------------------------*/
1404 void
1405 fors_dfs_save_table(cpl_frameset *frameset, const cpl_table *table,
1406  const char *category, cpl_propertylist *header,
1407  const cpl_parameterlist *parlist, const char *recipename,
1408  const cpl_frame *inherit_frame)
1409 {
1410  dfs_save(frameset, table, FORS_TYPE_TABLE,
1411  category, header,
1412  parlist, recipename,
1413  inherit_frame);
1414 }
1415 
1416 /*----------------------------------------------------------------------------*/
1448 /*----------------------------------------------------------------------------*/
1449 int dfs_save_image(cpl_frameset *frameset, const cpl_image *image,
1450  const char *category, cpl_propertylist *header,
1451  const cpl_parameterlist *parlist, const char *recipename,
1452  const char *version)
1453 {
1454  const char *func = "dfs_save_image";
1455 
1456  char *filename;
1457  cpl_frame *frame;
1458  cpl_propertylist *plist;
1459 
1460 
1461  if (category == NULL || frameset == NULL || image == NULL) {
1462  cpl_msg_error(cpl_func, "Error found in %s: %s",
1463  cpl_error_get_where(), cpl_error_get_message());
1464  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
1465  return -1;
1466  }
1467 
1468  cpl_msg_info(func, "Saving %s image to disk...", category);
1469 
1470  filename = cpl_calloc(strlen(category) + 6, sizeof(char));
1471 
1472  strlower(strcpy(filename, category));
1473  strcat(filename, ".fits");
1474 
1475  frame = cpl_frame_new();
1476 
1477  cpl_frame_set_filename(frame, filename);
1478  cpl_frame_set_tag(frame, category);
1479  cpl_frame_set_type(frame, CPL_FRAME_TYPE_IMAGE);
1480  cpl_frame_set_group(frame, CPL_FRAME_GROUP_PRODUCT);
1481  cpl_frame_set_level(frame, CPL_FRAME_LEVEL_FINAL);
1482  if (cpl_error_get_code()) {
1483  cpl_msg_error(cpl_func, "Error found in %s: %s",
1484  cpl_error_get_where(), cpl_error_get_message());
1485  cpl_msg_error(func, "Cannot initialise the product frame");
1486  cpl_frame_delete(frame);
1487  cpl_free(filename);
1488  return -1;
1489  }
1490 
1491 
1492  /*
1493  * Produce DFS compliant FITS header for image
1494  */
1495 
1496  if (header == NULL)
1497  plist = cpl_propertylist_new();
1498  else
1499  plist = header;
1500 
1501  if (cpl_dfs_setup_product_header(plist, frame, frameset, parlist,
1502  recipename, version, "PRO-1.15", NULL)) {
1503  cpl_msg_error(cpl_func, "Error found in %s: %s",
1504  cpl_error_get_where(), cpl_error_get_message());
1505  cpl_msg_error(func, "Problem with product %s FITS header definition",
1506  category);
1507  if (header == NULL)
1508  cpl_propertylist_delete(plist);
1509  cpl_frame_delete(frame);
1510  cpl_free(filename);
1511  return -1;
1512  }
1513 
1514  /*
1515  * Write image to disk
1516  */
1517 
1518  if (cpl_image_save(image, filename, CPL_BPP_IEEE_FLOAT, plist,
1519  CPL_IO_DEFAULT)) {
1520  cpl_msg_error(cpl_func, "Error found in %s: %s",
1521  cpl_error_get_where(), cpl_error_get_message());
1522  cpl_msg_error(func, "Cannot save product %s to disk", filename);
1523  if (header == NULL)
1524  cpl_propertylist_delete(plist);
1525  cpl_frame_delete(frame);
1526  cpl_free(filename);
1527  return -1;
1528  }
1529 
1530  if (header == NULL)
1531  cpl_propertylist_delete(plist);
1532 
1533  cpl_free(filename);
1534 
1535  cpl_frameset_insert(frameset, frame);
1536 
1537  return 0;
1538 }
1539 
1540 /*----------------------------------------------------------------------------*/
1572 /*----------------------------------------------------------------------------*/
1573 int dfs_save_table(cpl_frameset *frameset, const cpl_table *table,
1574  const char *category, cpl_propertylist *header,
1575  const cpl_parameterlist *parlist, const char *recipename,
1576  const char *version)
1577 {
1578  const char *func = "dfs_save_table";
1579 
1580  char *filename;
1581  cpl_frame *frame;
1582  cpl_propertylist *plist;
1583 
1584 
1585  if (category == NULL || frameset == NULL || table == NULL) {
1586  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
1587  cpl_msg_error(cpl_func, "Error found in %s: %s",
1588  cpl_error_get_where(), cpl_error_get_message());
1589  return -1;
1590  }
1591 
1592  cpl_msg_info(func, "Saving %s table to disk...", category);
1593 
1594  filename = cpl_calloc(strlen(category) + 6, sizeof(char));
1595 
1596  strlower(strcpy(filename, category));
1597 
1598  strcat(filename, ".fits");
1599 
1600  frame = cpl_frame_new();
1601 
1602  cpl_frame_set_filename(frame, filename);
1603  cpl_frame_set_tag(frame, category);
1604  cpl_frame_set_type(frame, CPL_FRAME_TYPE_TABLE);
1605  cpl_frame_set_group(frame, CPL_FRAME_GROUP_PRODUCT);
1606  cpl_frame_set_level(frame, CPL_FRAME_LEVEL_FINAL);
1607  if (cpl_error_get_code()) {
1608  cpl_msg_error(cpl_func, "Error found in %s: %s",
1609  cpl_error_get_where(), cpl_error_get_message());
1610  cpl_msg_error(func, "Cannot initialise the product frame");
1611  cpl_frame_delete(frame);
1612  cpl_free(filename);
1613  return -1;
1614  }
1615 
1616 
1617  /*
1618  * Produce DFS compliant FITS header for table
1619  */
1620 
1621  if (header == NULL)
1622  plist = cpl_propertylist_new();
1623  else
1624  plist = header;
1625 
1626  if (cpl_dfs_setup_product_header(plist, frame, frameset, parlist,
1627  recipename, version, "PRO-1.15", NULL)) {
1628  cpl_msg_error(cpl_func, "Error found in %s: %s",
1629  cpl_error_get_where(), cpl_error_get_message());
1630  cpl_msg_error(func, "Problem with product %s FITS header definition",
1631  category);
1632  if (header == NULL)
1633  cpl_propertylist_delete(plist);
1634  cpl_frame_delete(frame);
1635  cpl_free(filename);
1636  return -1;
1637  }
1638 
1639  /*
1640  * Write table to disk
1641  */
1642 
1643  if (cpl_table_save(table, plist, NULL, filename, CPL_IO_DEFAULT)) {
1644  cpl_msg_error(cpl_func, "Error found in %s: %s",
1645  cpl_error_get_where(), cpl_error_get_message());
1646  cpl_msg_error(func, "Cannot save product %s to disk", filename);
1647  if (header == NULL)
1648  cpl_propertylist_delete(plist);
1649  cpl_frame_delete(frame);
1650  cpl_free(filename);
1651  return -1;
1652  }
1653 
1654  if (header == NULL)
1655  cpl_propertylist_delete(plist);
1656  cpl_free(filename);
1657 
1658  cpl_frameset_insert(frameset, frame);
1659 
1660  return 0;
1661 }
1662 
1663 /*----------------------------------------------------------------------------*/
1680 /*----------------------------------------------------------------------------*/
1681 int dfs_equal_keyword(cpl_frameset *frameset, const char *keyword)
1682 {
1683  const char *func = "dfs_equal_keyword";
1684 
1685  cpl_frame *frame;
1686  cpl_propertylist *reference;
1687  cpl_type rtype;
1688  cpl_type type;
1689  const char *rstring;
1690  const char *string;
1691  int rintero;
1692  int intero;
1693  int found;
1694 
1695 
1696  if (frameset == NULL || keyword == NULL) {
1697  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
1698  return 0;
1699  }
1700 
1701  if (cpl_frameset_is_empty(frameset)) {
1702  cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
1703  return 0;
1704  }
1705 
1706  frame = cpl_frameset_get_first(frameset);
1707 
1708  found = 0;
1709 
1710  while (frame) {
1711 
1712  reference = cpl_propertylist_load(cpl_frame_get_filename(frame), 0);
1713  if (cpl_error_get_code() == CPL_ERROR_BAD_FILE_FORMAT) {
1714  cpl_error_reset();
1715  frame = cpl_frameset_get_next(frameset);
1716  continue;
1717  }
1718 
1719  if (cpl_propertylist_has(reference, keyword)) {
1720  rtype = cpl_propertylist_get_type(reference, keyword);
1721 
1722  if (rtype == CPL_TYPE_STRING) {
1723  found = 1;
1724  rstring = cpl_strdup(cpl_propertylist_get_string(reference,
1725  keyword));
1726  cpl_propertylist_delete(reference);
1727  break;
1728  }
1729 
1730  if (rtype == CPL_TYPE_INT) {
1731  found = 1;
1732  rintero = cpl_propertylist_get_int(reference, keyword);
1733  cpl_propertylist_delete(reference);
1734  break;
1735  }
1736 
1737  cpl_propertylist_delete(reference);
1738  return 0;
1739  }
1740 
1741  cpl_propertylist_delete(reference);
1742 
1743  frame = cpl_frameset_get_next(frameset);
1744  }
1745 
1746 
1747  if (!found)
1748  return 1;
1749 
1750  frame = cpl_frameset_get_first(frameset);
1751 
1752  while (frame) {
1753 
1754  reference = cpl_propertylist_load(cpl_frame_get_filename(frame), 0);
1755  if (cpl_error_get_code() == CPL_ERROR_BAD_FILE_FORMAT) {
1756  cpl_error_reset();
1757  frame = cpl_frameset_get_next(frameset);
1758  continue;
1759  }
1760 
1761  if (cpl_propertylist_has(reference, keyword)) {
1762 
1763  type = cpl_propertylist_get_type(reference, keyword);
1764 
1765  if (rtype != type) {
1766  cpl_propertylist_delete(reference);
1767  return 0;
1768  }
1769 
1770  if (rtype == CPL_TYPE_STRING) {
1771  string = cpl_propertylist_get_string(reference,
1772  keyword);
1773  if (strncmp(rstring, string, 15)) {
1774  cpl_propertylist_delete(reference);
1775  return 0;
1776  }
1777  }
1778 
1779  if (rtype == CPL_TYPE_INT) {
1780  intero = cpl_propertylist_get_int(reference, keyword);
1781  if (rintero - intero) {
1782  cpl_propertylist_delete(reference);
1783  return 0;
1784  }
1785  }
1786  }
1787 
1788  cpl_propertylist_delete(reference);
1789 
1790  frame = cpl_frameset_get_next(frameset);
1791  }
1792 
1793  if (rtype == CPL_TYPE_STRING)
1794  cpl_free((void *)rstring);
1795 
1796  return 1;
1797 
1798 }
1799 
1809 cpl_error_code dfs_save_table_ext(cpl_table * table,
1810  const char * tag,
1811  cpl_propertylist * extheader)
1812 {
1813  char * filename = cpl_calloc(strlen(tag) + 6, sizeof(char));
1814  cpl_propertylist * header;
1815 
1816  if (extheader) {
1817  header = cpl_propertylist_duplicate(extheader);
1818 
1819  cpl_propertylist_erase_regexp(header,
1820  "^ESO DPR |^ARCFILE$|^ORIGFILE$", 0);
1821  } else {
1822  header = NULL;
1823  }
1824 
1825  strlower(strcpy(filename, tag));
1826  strcat(filename, ".fits");
1827 
1828  if (cpl_table_save(table, NULL, header, filename, CPL_IO_EXTEND)) {
1829  cpl_free(filename);
1830  cpl_ensure_code(0, CPL_ERROR_FILE_IO);
1831  }
1832 
1833  cpl_propertylist_delete(header);
1834  cpl_free(filename);
1835 
1836  return CPL_ERROR_NONE;
1837 }
1838 
1848 cpl_error_code dfs_save_image_ext(cpl_image * image,
1849  const char * tag,
1850  cpl_propertylist * extheader)
1851 {
1852  char * filename = cpl_calloc(strlen(tag) + 6, sizeof(char));
1853 
1854  cpl_propertylist * header;
1855 
1856  if (extheader) {
1857  header = cpl_propertylist_duplicate(extheader);
1858 
1859  cpl_propertylist_erase_regexp(header,
1860  "^ESO DPR |^ARCFILE$|^ORIGFILE$", 0);
1861  } else {
1862  header = NULL;
1863  }
1864 
1865  strlower(strcpy(filename, tag));
1866  strcat(filename, ".fits");
1867 
1868  if (cpl_image_save(image, filename, CPL_BPP_IEEE_FLOAT,
1869  header, CPL_IO_EXTEND)) {
1870  cpl_free(filename);
1871  cpl_ensure_code(0, CPL_ERROR_FILE_IO);
1872  }
1873 
1874  cpl_propertylist_delete(header);
1875  cpl_free(filename);
1876 
1877  return CPL_ERROR_NONE;
1878 }
1879 
1891 cpl_error_code dfs_save_image_null(cpl_frameset * frameset,
1892  cpl_parameterlist * parlist,
1893  const char * tag,
1894  const char * recipename,
1895  const char * version)
1896 {
1897 
1898  char * filename = cpl_calloc(strlen(tag) + 6, sizeof(char));
1899 
1900  cpl_error_code error;
1901 
1902  cpl_propertylist * pro = cpl_propertylist_new();
1903 
1904  cpl_propertylist_append_string(pro, "ESO PRO CATG", tag);
1905 
1906  strlower(strcpy(filename, tag));
1907  strcat(filename, ".fits");
1908 
1909  error = cpl_dfs_save_image(frameset, NULL, parlist, frameset, NULL, NULL,
1910  CPL_BPP_IEEE_FLOAT, recipename, pro,
1911  NULL, version, filename);
1912 
1913  cpl_free(filename);
1914  cpl_propertylist_delete(pro);
1915 
1916  return error;
1917 }
1918 
1919 
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:1272
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:857
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:599
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:961
void fors_dfs_add_exptime(cpl_propertylist *header, const cpl_frame *frame, double exptime)
Add keyword EXPTIME to header.
Definition: fors_dfs.c:1365
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:1891
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:1848
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:993
#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:698
int dfs_equal_keyword(cpl_frameset *frameset, const char *keyword)
Saving table data of given category.
Definition: fors_dfs.c:1681
int dfs_get_parameter_int_const(const cpl_parameterlist *parlist, const char *name)
Definition: fors_dfs.c:803
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:1809
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:1236
int dfs_get_parameter_bool_const(const cpl_parameterlist *parlist, const char *name)
Definition: fors_dfs.c:793
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:1405
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:1449
cpl_table * dfs_load_table(cpl_frameset *frameset, const char *category, int ext)
Loading table data of given category.
Definition: fors_dfs.c:913
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:404
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:1573
const char * dfs_get_parameter_string_const(const cpl_parameterlist *parlist, const char *name)
Definition: fors_dfs.c:823
void fors_image_save(const fors_image *image, const cpl_propertylist *header, const char *filename)
Save image.
Definition: fors_image.c:377
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:501
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:357
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:1311
double dfs_get_parameter_double_const(const cpl_parameterlist *parlist, const char *name)
Definition: fors_dfs.c:813