FORS Pipeline Reference Manual  5.0.9
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:", alias);
474  cpl_msg_info(func, "%s: %d",
475  cpl_parameter_get_help(param), cpl_parameter_get_int(param));
476 
477  return cpl_parameter_get_int(param);
478 
479 }
480 
481 /*----------------------------------------------------------------------------*/
503 /*----------------------------------------------------------------------------*/
504 double dfs_get_parameter_double(cpl_parameterlist *parlist,
505  const char *name, const cpl_table *defaults)
506 {
507  const char *func = "dfs_get_parameter_double";
508 
509  const char *alias;
510  cpl_parameter *param;
511 
512 
513  if (parlist == NULL) {
514  cpl_msg_error(func, "Missing input parameter list");
515  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
516  return 0;
517  }
518 
519  if (name == NULL) {
520  cpl_msg_error(func, "Missing input parameter name");
521  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
522  return 0;
523  }
524 
525  param = cpl_parameterlist_find(parlist, name);
526 
527  if (param == NULL) {
528  cpl_msg_error(func, "Wrong parameter name: %s", name);
529  cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
530  return 0;
531  }
532 
533  if (cpl_parameter_get_type(param) != CPL_TYPE_DOUBLE) {
534  cpl_msg_error(func, "Unexpected type for parameter "
535  "\"%s\": it should be double", name);
536  cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
537  return 0;
538  }
539 
540  alias = cpl_parameter_get_alias(param, CPL_PARAMETER_MODE_CLI);
541 
542 // if (defaults && cpl_parameter_get_default_flag(param) == 0) {
543  if (defaults &&
544  cpl_parameter_get_default_double(param) ==
545  cpl_parameter_get_double(param)) {
546 
547  if (cpl_table_has_column(defaults, alias)) {
548  if (cpl_table_get_column_type(defaults, alias) != CPL_TYPE_DOUBLE) {
549  cpl_msg_error(func, "Unexpected type for GRISM_TABL "
550  "column \"%s\": it should be double", alias);
551  cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
552  return 0;
553  }
554  if (cpl_table_is_valid(defaults, alias, 0)) {
555  cpl_parameter_set_double(param, cpl_table_get_double(defaults,
556  alias, 0, NULL));
557  }
558  else {
559  cpl_msg_error(func, "Invalid parameter value in table "
560  "column \"%s\"", alias);
561  cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
562  return 0;
563  }
564  }
565  else {
566  cpl_msg_warning(func, "Parameter \"%s\" not found in GRISM_TABLE "
567  "- using recipe default", alias);
568  }
569  }
570 
571  cpl_msg_info(func, "%s:", alias);
572  cpl_msg_info(func, "%s: %f",
573  cpl_parameter_get_help(param), cpl_parameter_get_double(param));
574 
575  return cpl_parameter_get_double(param);
576 
577 }
578 
579 /*----------------------------------------------------------------------------*/
601 /*----------------------------------------------------------------------------*/
602 const char *dfs_get_parameter_string(cpl_parameterlist *parlist,
603  const char *name,
604  const cpl_table *defaults)
605 {
606  const char *func = "dfs_get_parameter_string";
607 
608  const char *alias;
609  cpl_parameter *param;
610 
611 
612  if (parlist == NULL) {
613  cpl_msg_error(func, "Missing input parameter list");
614  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
615  return 0;
616  }
617 
618  if (name == NULL) {
619  cpl_msg_error(func, "Missing input parameter name");
620  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
621  return 0;
622  }
623 
624  param = cpl_parameterlist_find(parlist, name);
625 
626  if (param == NULL) {
627  cpl_msg_error(func, "Wrong parameter name: %s", name);
628  cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
629  return 0;
630  }
631 
632  if (cpl_parameter_get_type(param) != CPL_TYPE_STRING) {
633  cpl_msg_error(func, "Unexpected type for parameter "
634  "\"%s\": it should be string", name);
635  cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
636  return 0;
637  }
638 
639  alias = cpl_parameter_get_alias(param, CPL_PARAMETER_MODE_CLI);
640 
641 // if (defaults && cpl_parameter_get_default_flag(param) == 0) {
642  if (defaults &&
643  strcmp(cpl_parameter_get_default_string(param),
644  cpl_parameter_get_string(param)) == 0) {
645 
646  if (cpl_table_has_column(defaults, alias)) {
647  if (cpl_table_get_column_type(defaults, alias) != CPL_TYPE_STRING) {
648  cpl_msg_error(func, "Unexpected type for GRISM_TABLE "
649  "column \"%s\": it should be string", alias);
650  cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
651  return 0;
652  }
653  if (cpl_table_is_valid(defaults, alias, 0)) {
654  cpl_parameter_set_string(param, cpl_table_get_string(defaults,
655  alias, 0));
656  }
657  else {
658  cpl_msg_error(func, "Invalid parameter value in table "
659  "column \"%s\"", alias);
660  cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
661  return 0;
662  }
663  }
664  else {
665  cpl_msg_warning(func, "Parameter \"%s\" not found in GRISM_TABLE "
666  "- using recipe default", alias);
667  }
668  }
669 
670  cpl_msg_info(func, "%s:", alias);
671  cpl_msg_info(func, "%s: %s", cpl_parameter_get_help(param),
672  cpl_parameter_get_string(param));
673 
674  return cpl_parameter_get_string(param);
675 
676 }
677 
678 /*----------------------------------------------------------------------------*/
700 /*----------------------------------------------------------------------------*/
701 int dfs_get_parameter_bool(cpl_parameterlist *parlist, const char *name,
702  const cpl_table *defaults)
703 {
704  const char *func = "dfs_get_parameter_bool";
705 
706  const char *alias;
707  cpl_parameter *param;
708  int value;
709 
710 
711  if (parlist == NULL) {
712  cpl_msg_error(func, "Missing input parameter list");
713  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
714  return 0;
715  }
716 
717  if (name == NULL) {
718  cpl_msg_error(func, "Missing input parameter name");
719  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
720  return 0;
721  }
722 
723  param = cpl_parameterlist_find(parlist, name);
724 
725  if (param == NULL) {
726  cpl_msg_error(func, "Wrong parameter name: %s", name);
727  cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
728  return 0;
729  }
730 
731  if (cpl_parameter_get_type(param) != CPL_TYPE_BOOL) {
732  cpl_msg_error(func, "Unexpected type for parameter "
733  "\"%s\": it should be boolean", name);
734  cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
735  return 0;
736  }
737 
738  alias = cpl_parameter_get_alias(param, CPL_PARAMETER_MODE_CLI);
739 
740 // if (defaults && cpl_parameter_get_default_flag(param) == 0) {
741  if (defaults &&
742  cpl_parameter_get_default_bool(param) ==
743  cpl_parameter_get_bool(param)) {
744 
745  if (cpl_table_has_column(defaults, alias)) {
746  if (cpl_table_get_column_type(defaults, alias) != CPL_TYPE_INT) {
747  cpl_msg_error(func, "Unexpected type for GRISM_TABLE "
748  "column \"%s\": it should be integer", alias);
749  cpl_error_set(func, CPL_ERROR_INVALID_TYPE);
750  return 0;
751  }
752  if (cpl_table_is_valid(defaults, alias, 0)) {
753  value = cpl_table_get_int(defaults, alias, 0, NULL);
754  if (value < 0 || value > 1) {
755  cpl_msg_error(func, "Illegal parameter value in table "
756  "column \"%s\": it should be either 0 or 1",
757  alias);
758  cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
759  return 0;
760  }
761  cpl_parameter_set_bool(param, value);
762  }
763  else {
764  cpl_msg_error(func, "Invalid parameter value in table "
765  "column \"%s\"", alias);
766  cpl_error_set(func, CPL_ERROR_ILLEGAL_INPUT);
767  return 0;
768  }
769  }
770  else {
771  cpl_msg_warning(func, "Parameter \"%s\" not found in GRISM_TABLE "
772  "- using recipe default", alias);
773  }
774  }
775 
776  value = cpl_parameter_get_bool(param);
777 
778  if (value) {
779  cpl_msg_info(func, "%s:", alias);
780  cpl_msg_info(func, "%s: TRUE", cpl_parameter_get_help(param));
781  }
782  else {
783  cpl_msg_info(func, "%s:", alias);
784  cpl_msg_info(func, "%s: FALSE", cpl_parameter_get_help(param));
785  }
786 
787  return value;
788 
789 }
790 
791 /*----------------------------------------------------------------------------*/
795 /*----------------------------------------------------------------------------*/
796 int dfs_get_parameter_bool_const(const cpl_parameterlist *parlist, const char *name)
797 {
798  return dfs_get_parameter_bool((cpl_parameterlist *)parlist, name, NULL);
799 }
800 
801 /*----------------------------------------------------------------------------*/
805 /*----------------------------------------------------------------------------*/
806 int dfs_get_parameter_int_const(const cpl_parameterlist *parlist, const char *name)
807 {
808  return dfs_get_parameter_int((cpl_parameterlist *)parlist, name, NULL);
809 }
810 
811 /*----------------------------------------------------------------------------*/
815 /*----------------------------------------------------------------------------*/
816 double dfs_get_parameter_double_const(const cpl_parameterlist *parlist, const char *name)
817 {
818  return dfs_get_parameter_double((cpl_parameterlist *)parlist, name, NULL);
819 }
820 
821 /*----------------------------------------------------------------------------*/
825 /*----------------------------------------------------------------------------*/
826 const char *dfs_get_parameter_string_const(const cpl_parameterlist *parlist, const char *name)
827 {
828  return dfs_get_parameter_string((cpl_parameterlist *)parlist, name, NULL);
829 }
830 
831 /*----------------------------------------------------------------------------*/
859 /*----------------------------------------------------------------------------*/
860 cpl_image *dfs_load_image(cpl_frameset *frameset, const char *category,
861  cpl_type type, int ext, int calib)
862 {
863  const char *func = "dfs_load_image";
864 
865  cpl_frame *frame = NULL;
866  cpl_image *image = NULL;
867 
868 
869  frame = cpl_frameset_find(frameset, category);
870 
871  if (frame) {
872  image = cpl_image_load(cpl_frame_get_filename(frame), type, 0, ext);
873  if (image == NULL) {
874  cpl_msg_error(cpl_error_get_where(),"%s", cpl_error_get_message());
875  cpl_msg_error(func, "Cannot load image %s",
876  cpl_frame_get_filename(frame));
877  }
878  else {
879  if (calib)
880  cpl_frame_set_group(frame, CPL_FRAME_GROUP_CALIB);
881  else
882  cpl_frame_set_group(frame, CPL_FRAME_GROUP_RAW);
883  }
884  }
885 
886  return image;
887 }
888 
889 /*----------------------------------------------------------------------------*/
915 /*----------------------------------------------------------------------------*/
916 cpl_table *dfs_load_table(cpl_frameset *frameset, const char *category, int ext)
917 {
918  const char *func = "dfs_load_table";
919 
920  cpl_frame *frame = NULL;
921  cpl_table *table = NULL;
922 
923 
924  frame = cpl_frameset_find(frameset, category);
925 
926  if (frame) {
927  table = cpl_table_load(cpl_frame_get_filename(frame), ext, 1);
928  if (table == NULL) {
929  cpl_msg_error(cpl_error_get_where(), "%s", cpl_error_get_message());
930  cpl_msg_error(func, "Cannot load table %s",
931  cpl_frame_get_filename(frame));
932  }
933  }
934 
935  return table;
936 }
937 
938 /*----------------------------------------------------------------------------*/
963 /*----------------------------------------------------------------------------*/
964 cpl_propertylist *dfs_load_header(cpl_frameset *frameset,
965  const char *category, int ext)
966 {
967  const char *func = "dfs_load_header";
968 
969  cpl_frame *frame = NULL;
970  cpl_propertylist *plist = NULL;
971 
972 
973  frame = cpl_frameset_find(frameset, category);
974 
975  if (frame) {
976  plist = cpl_propertylist_load(cpl_frame_get_filename(frame), ext);
977  if (plist == NULL) {
978  cpl_msg_error(cpl_error_get_where(), "%s", cpl_error_get_message());
979  cpl_msg_error(func, "Cannot load header from %s",
980  cpl_frame_get_filename(frame));
981  }
982  }
983 
984  return plist;
985 }
986 
987 /*----------------------------------------------------------------------------*/
994 /*----------------------------------------------------------------------------*/
995 static void
996 dfs_save(cpl_frameset *frameset, const void *object, fors_type type,
997  const char *category, cpl_propertylist *header,
998  cpl_propertylist *extra_header,
999  const cpl_parameterlist *parlist, const char *recipename,
1000  const cpl_frame *inherit_frame)
1001 {
1002  char *filename;
1003  cpl_frame *frame;
1004  cpl_propertylist *plist;
1005  const char *version = NULL;
1006  cpl_propertylist *raw_header = NULL;
1007 
1008 
1009  if (category == NULL || frameset == NULL || object == NULL ||
1010  inherit_frame == NULL) {
1011  cpl_msg_error(cpl_error_get_where(), "%s", cpl_error_get_message());
1012  cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
1013  return;
1014  }
1015 
1016  if (type == FORS_TYPE_TABLE) {
1017  cpl_msg_debug(cpl_func, "Saving %s table to disk...", category);
1018  }
1019  else {
1020  cpl_msg_debug(cpl_func, "Saving %s image to disk...", category);
1021  }
1022 
1023  /* Read instrument version from raw frame */
1024  {
1025  const char *raw_filename =
1026  cpl_frame_get_filename(inherit_frame);
1027 
1028  raw_header = cpl_propertylist_load(raw_filename, 0);
1029  if (raw_header == NULL) {
1030  cpl_msg_error(cpl_func, "Could not read %s primary header", raw_filename);
1031  return;
1032  }
1033 
1034  version = fors_dfs_pipeline_version(raw_header, NULL);
1035  cpl_propertylist_delete(raw_header);
1036 
1037  if (cpl_error_get_code() != CPL_ERROR_NONE) {
1038  cpl_msg_error(cpl_func, "Could not identify instrument version from %s header",
1039  raw_filename);
1040  return;
1041  }
1042  }
1043 
1044  filename = cpl_calloc(strlen(category) + 6, sizeof(char));
1045 
1046  strlower(strcpy(filename, category));
1047  strcat(filename, ".fits");
1048 
1049  frame = cpl_frame_new();
1050 
1051  cpl_frame_set_filename(frame, filename);
1052  cpl_frame_set_tag(frame, category);
1053  cpl_frame_set_type(frame, CPL_FRAME_TYPE_ANY);
1054  cpl_frame_set_group(frame, CPL_FRAME_GROUP_PRODUCT);
1055  cpl_frame_set_level(frame, CPL_FRAME_LEVEL_FINAL);
1056  if (cpl_error_get_code()) {
1057  cpl_msg_error(cpl_error_get_where(), "%s", cpl_error_get_message());
1058  cpl_msg_error(cpl_func, "Cannot initialise the product frame");
1059  cpl_frame_delete(frame);
1060  cpl_free(filename);
1061  cpl_free((void *)version);
1062  return;
1063  }
1064 
1065 
1066  /*
1067  * Produce DFS compliant FITS header for product
1068  */
1069 
1070  if (header == NULL)
1071  plist = cpl_propertylist_new();
1072  else
1073  plist = cpl_propertylist_duplicate(header);
1074 
1075  if (cpl_dfs_setup_product_header(plist, frame, frameset, parlist,
1076  recipename, version, "PRO-1.15",
1077  inherit_frame)) {
1078  cpl_msg_error(cpl_func, "Error found in %s: %s",
1079  cpl_error_get_where(), cpl_error_get_message());
1080  cpl_msg_error(cpl_func, "Problem with product %s FITS header definition",
1081  category);
1082  cpl_propertylist_delete(plist);
1083  cpl_frame_delete(frame);
1084  cpl_free(filename);
1085  cpl_free((void *)version);
1086  return;
1087  }
1088 
1089  cpl_free((void *)version);
1090 
1091  /*
1092  * Write to disk
1093  */
1094 
1095  if (type == FORS_TYPE_IMAGE_ERR) {
1096  fors_image_save((fors_image *)object, plist, extra_header, filename);
1097  }
1098  else if (type == FORS_TYPE_IMAGE) {
1099  cpl_image_save((cpl_image *)object, filename, CPL_BPP_IEEE_FLOAT, plist,
1100  CPL_IO_DEFAULT);
1101  }
1102  else {
1103  cpl_table_save((cpl_table *)object,
1104  plist, NULL, filename, CPL_IO_DEFAULT);
1105  }
1106 
1107  if (cpl_error_get_code() != CPL_ERROR_NONE) {
1108  cpl_msg_error(cpl_func, "Error found in %s: %s",
1109  cpl_error_get_where(), cpl_error_get_message());
1110  cpl_msg_error(cpl_func, "Cannot save product %s to disk", filename);
1111  cpl_propertylist_delete(plist);
1112  cpl_frame_delete(frame);
1113  cpl_free(filename);
1114  return;
1115  }
1116 
1117  cpl_propertylist_delete(plist);
1118 
1119  cpl_free(filename);
1120 
1121  cpl_frameset_insert(frameset, frame);
1122 
1123  return;
1124 }
1125 
1126 /*----------------------------------------------------------------------------*/
1147 /*----------------------------------------------------------------------------*/
1148 void
1149 fors_dfs_save_image(cpl_frameset *frameset, const cpl_image *image,
1150  const char *category, cpl_propertylist *header,
1151  const cpl_parameterlist *parlist, const char *recipename,
1152  const cpl_frame *inherit_frame)
1153 {
1154  dfs_save(frameset, image, FORS_TYPE_IMAGE,
1155  category, header, NULL,
1156  parlist, recipename,
1157  inherit_frame);
1158 }
1159 
1160 /*----------------------------------------------------------------------------*/
1182 /*----------------------------------------------------------------------------*/
1183 void
1184 fors_dfs_save_image_mask(cpl_frameset *frameset, const cpl_image *image,
1185  const cpl_image *mask, const char *category,
1186  cpl_propertylist *header,
1187  const cpl_parameterlist *parlist, const char *recipename,
1188  const cpl_frame *inherit_frame)
1189 {
1190  char *filename;
1191  cpl_propertylist * extension_header;
1192 
1193  dfs_save(frameset, image, FORS_TYPE_IMAGE,
1194  category, header, NULL,
1195  parlist, recipename,
1196  inherit_frame);
1197 
1198  extension_header = cpl_propertylist_new();
1199  cpl_propertylist_append_string(extension_header,
1200  "EXTNAME", "IMAGE.BPM");
1201 
1202  filename = cpl_calloc(strlen(category) + 6, sizeof(char));
1203 
1204  strlower(strcpy(filename, category));
1205  strcat(filename, ".fits");
1206 
1207  cpl_image_save(mask, filename, CPL_BPP_IEEE_FLOAT, extension_header,
1208  CPL_IO_EXTEND);
1209  cpl_propertylist_delete(extension_header);
1210  cpl_free(filename);
1211 
1212 }
1213 
1214 /*----------------------------------------------------------------------------*/
1235 /*----------------------------------------------------------------------------*/
1236 void
1237 fors_dfs_save_image_err(cpl_frameset *frameset, const fors_image *image,
1238  const char *category, cpl_propertylist *header,
1239  cpl_propertylist *err_header,
1240  const cpl_parameterlist *parlist, const char *recipename,
1241  const cpl_frame *inherit_frame)
1242 {
1243  dfs_save(frameset, image, FORS_TYPE_IMAGE_ERR,
1244  category, header, err_header,
1245  parlist, recipename,
1246  inherit_frame);
1247 }
1248 
1249 /*----------------------------------------------------------------------------*/
1272 /*----------------------------------------------------------------------------*/
1273 void
1274 fors_dfs_save_image_err_mask(cpl_frameset *frameset, const fors_image *image,
1275  const cpl_image *mask, const char *category,
1276  cpl_propertylist *header,
1277  const cpl_parameterlist *parlist, const char *recipename,
1278  const cpl_frame *inherit_frame)
1279 {
1280  char *filename;
1281  cpl_propertylist * extension_header;
1282 
1283  dfs_save(frameset, image, FORS_TYPE_IMAGE_ERR,
1284  category, header, NULL,
1285  parlist, recipename,
1286  inherit_frame);
1287 
1288  extension_header = cpl_propertylist_new();
1289  cpl_propertylist_append_string(extension_header,
1290  "EXTNAME", "IMAGE.BPM");
1291 
1292  filename = cpl_calloc(strlen(category) + 6, sizeof(char));
1293 
1294  strlower(strcpy(filename, category));
1295  strcat(filename, ".fits");
1296 
1297  cpl_image_save(mask, filename, CPL_BPP_IEEE_FLOAT, extension_header,
1298  CPL_IO_EXTEND);
1299  cpl_propertylist_delete(extension_header);
1300  cpl_free(filename);
1301 }
1302 
1303 #undef cleanup
1304 #define cleanup \
1305 do { \
1306  cpl_propertylist_delete(wcs_header); \
1307 } while (0)
1308 
1313 void fors_dfs_add_wcs(cpl_propertylist *header, const cpl_frame *frame,
1314  const fors_setting *setting)
1315 {
1316  bool invert = false;
1317  int extension = 0;
1318 
1319  cpl_propertylist *wcs_header =
1320  cpl_propertylist_load_regexp(cpl_frame_get_filename(frame),
1321  extension, WCS_KEYS, invert);
1322 
1323  cpl_propertylist_copy_property_regexp(header, wcs_header, ".*", invert);
1324 
1325  double crpix1 = cpl_propertylist_get_double(header, FORS_PFITS_CRPIX1);
1326 
1327  assure( !cpl_error_get_code(), return,
1328  "Could not read %s from %s", FORS_PFITS_CRPIX1,
1329  cpl_frame_get_filename(frame));
1330 
1331  double crpix2 = cpl_propertylist_get_double(header, FORS_PFITS_CRPIX2);
1332 
1333  assure( !cpl_error_get_code(), return,
1334  "Could not read %s from %s", FORS_PFITS_CRPIX2,
1335  cpl_frame_get_filename(frame));
1336 
1337  cpl_propertylist_update_double(header, FORS_PFITS_CRPIX1,
1338  crpix1 - setting->prescan_x);
1339 
1340  cpl_propertylist_update_double(header, FORS_PFITS_CRPIX2,
1341  crpix2 - setting->prescan_y);
1342 
1343 
1344  cleanup;
1345  return;
1346 }
1347 
1348 /*----------------------------------------------------------------------------*/
1349 #undef cleanup
1350 #define cleanup \
1351 do { \
1352  cpl_propertylist_delete(time_header); \
1353 } while (0)
1354 
1366 /*----------------------------------------------------------------------------*/
1367 void fors_dfs_add_exptime(cpl_propertylist *header, const cpl_frame *frame,
1368  double exptime)
1369 {
1370  bool invert = false;
1371  int extension = 0;
1372 
1373  cpl_propertylist *time_header = NULL;
1374 
1375  if (frame) {
1376 
1377  time_header =
1378  cpl_propertylist_load_regexp(cpl_frame_get_filename(frame),
1379  extension, "EXPTIME", invert);
1380 
1381  if (time_header) {
1382  cpl_propertylist_copy_property_regexp(header,
1383  time_header, ".*", invert);
1384  }
1385  else {
1386  cpl_error_reset();
1387  }
1388  }
1389  else {
1390  while (cpl_propertylist_erase(header, "EXPTIME"));
1391  cpl_propertylist_update_double(header, "EXPTIME", exptime);
1392  }
1393 
1394  cleanup;
1395  return;
1396 }
1397 
1398 /*----------------------------------------------------------------------------*/
1405 /*----------------------------------------------------------------------------*/
1406 void
1407 fors_dfs_save_table(cpl_frameset *frameset, const cpl_table *table,
1408  const char *category, cpl_propertylist *header,
1409  const cpl_parameterlist *parlist, const char *recipename,
1410  const cpl_frame *inherit_frame)
1411 {
1412  dfs_save(frameset, table, FORS_TYPE_TABLE,
1413  category, header, NULL,
1414  parlist, recipename,
1415  inherit_frame);
1416 }
1417 
1418 /*----------------------------------------------------------------------------*/
1450 /*----------------------------------------------------------------------------*/
1451 int dfs_save_image(cpl_frameset *frameset, const cpl_image *image,
1452  const char *category, cpl_propertylist *header,
1453  const cpl_parameterlist *parlist, const char *recipename,
1454  const char *version)
1455 {
1456  const char *func = "dfs_save_image";
1457 
1458  char *filename;
1459  cpl_frame *frame;
1460  cpl_propertylist *plist;
1461 
1462 
1463  if (category == NULL || frameset == NULL || image == NULL) {
1464  cpl_msg_error(cpl_func, "Error found in %s: %s",
1465  cpl_error_get_where(), cpl_error_get_message());
1466  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
1467  return -1;
1468  }
1469 
1470  cpl_msg_info(func, "Saving %s image to disk...", category);
1471 
1472  filename = cpl_calloc(strlen(category) + 6, sizeof(char));
1473 
1474  strlower(strcpy(filename, category));
1475  strcat(filename, ".fits");
1476 
1477  frame = cpl_frame_new();
1478 
1479  cpl_frame_set_filename(frame, filename);
1480  cpl_frame_set_tag(frame, category);
1481  cpl_frame_set_type(frame, CPL_FRAME_TYPE_IMAGE);
1482  cpl_frame_set_group(frame, CPL_FRAME_GROUP_PRODUCT);
1483  cpl_frame_set_level(frame, CPL_FRAME_LEVEL_FINAL);
1484  if (cpl_error_get_code()) {
1485  cpl_msg_error(cpl_func, "Error found in %s: %s",
1486  cpl_error_get_where(), cpl_error_get_message());
1487  cpl_msg_error(func, "Cannot initialise the product frame");
1488  cpl_frame_delete(frame);
1489  cpl_free(filename);
1490  return -1;
1491  }
1492 
1493 
1494  /*
1495  * Produce DFS compliant FITS header for image
1496  */
1497 
1498  if (header == NULL)
1499  plist = cpl_propertylist_new();
1500  else
1501  plist = header;
1502 
1503  if (cpl_dfs_setup_product_header(plist, frame, frameset, parlist,
1504  recipename, version, "PRO-1.15", NULL)) {
1505  cpl_msg_error(cpl_func, "Error found in %s: %s",
1506  cpl_error_get_where(), cpl_error_get_message());
1507  cpl_msg_error(func, "Problem with product %s FITS header definition",
1508  category);
1509  if (header == NULL)
1510  cpl_propertylist_delete(plist);
1511  cpl_frame_delete(frame);
1512  cpl_free(filename);
1513  return -1;
1514  }
1515 
1516  /*
1517  * Write image to disk
1518  */
1519 
1520  if (cpl_image_save(image, filename, CPL_BPP_IEEE_FLOAT, plist,
1521  CPL_IO_DEFAULT)) {
1522  cpl_msg_error(cpl_func, "Error found in %s: %s",
1523  cpl_error_get_where(), cpl_error_get_message());
1524  cpl_msg_error(func, "Cannot save product %s to disk", filename);
1525  if (header == NULL)
1526  cpl_propertylist_delete(plist);
1527  cpl_frame_delete(frame);
1528  cpl_free(filename);
1529  return -1;
1530  }
1531 
1532  if (header == NULL)
1533  cpl_propertylist_delete(plist);
1534 
1535  cpl_free(filename);
1536 
1537  cpl_frameset_insert(frameset, frame);
1538 
1539  return 0;
1540 }
1541 
1542 /*----------------------------------------------------------------------------*/
1574 /*----------------------------------------------------------------------------*/
1575 int dfs_save_table(cpl_frameset *frameset, const cpl_table *table,
1576  const char *category, cpl_propertylist *header,
1577  const cpl_parameterlist *parlist, const char *recipename,
1578  const char *version)
1579 {
1580  const char *func = "dfs_save_table";
1581 
1582  char *filename;
1583  cpl_frame *frame;
1584  cpl_propertylist *plist;
1585 
1586 
1587  if (category == NULL || frameset == NULL || table == NULL) {
1588  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
1589  cpl_msg_error(cpl_func, "Error found in %s: %s",
1590  cpl_error_get_where(), cpl_error_get_message());
1591  return -1;
1592  }
1593 
1594  cpl_msg_info(func, "Saving %s table to disk...", category);
1595 
1596  filename = cpl_calloc(strlen(category) + 6, sizeof(char));
1597 
1598  strlower(strcpy(filename, category));
1599 
1600  strcat(filename, ".fits");
1601 
1602  frame = cpl_frame_new();
1603 
1604  cpl_frame_set_filename(frame, filename);
1605  cpl_frame_set_tag(frame, category);
1606  cpl_frame_set_type(frame, CPL_FRAME_TYPE_TABLE);
1607  cpl_frame_set_group(frame, CPL_FRAME_GROUP_PRODUCT);
1608  cpl_frame_set_level(frame, CPL_FRAME_LEVEL_FINAL);
1609  if (cpl_error_get_code()) {
1610  cpl_msg_error(cpl_func, "Error found in %s: %s",
1611  cpl_error_get_where(), cpl_error_get_message());
1612  cpl_msg_error(func, "Cannot initialise the product frame");
1613  cpl_frame_delete(frame);
1614  cpl_free(filename);
1615  return -1;
1616  }
1617 
1618 
1619  /*
1620  * Produce DFS compliant FITS header for table
1621  */
1622 
1623  if (header == NULL)
1624  plist = cpl_propertylist_new();
1625  else
1626  plist = header;
1627 
1628  if (cpl_dfs_setup_product_header(plist, frame, frameset, parlist,
1629  recipename, version, "PRO-1.15", NULL)) {
1630  cpl_msg_error(cpl_func, "Error found in %s: %s",
1631  cpl_error_get_where(), cpl_error_get_message());
1632  cpl_msg_error(func, "Problem with product %s FITS header definition",
1633  category);
1634  if (header == NULL)
1635  cpl_propertylist_delete(plist);
1636  cpl_frame_delete(frame);
1637  cpl_free(filename);
1638  return -1;
1639  }
1640 
1641  /*
1642  * Write table to disk
1643  */
1644 
1645  if (cpl_table_save(table, plist, NULL, filename, CPL_IO_DEFAULT)) {
1646  cpl_msg_error(cpl_func, "Error found in %s: %s",
1647  cpl_error_get_where(), cpl_error_get_message());
1648  cpl_msg_error(func, "Cannot save product %s to disk", filename);
1649  if (header == NULL)
1650  cpl_propertylist_delete(plist);
1651  cpl_frame_delete(frame);
1652  cpl_free(filename);
1653  return -1;
1654  }
1655 
1656  if (header == NULL)
1657  cpl_propertylist_delete(plist);
1658  cpl_free(filename);
1659 
1660  cpl_frameset_insert(frameset, frame);
1661 
1662  return 0;
1663 }
1664 
1665 /*----------------------------------------------------------------------------*/
1682 /*----------------------------------------------------------------------------*/
1683 int dfs_equal_keyword(cpl_frameset *frameset, const char *keyword)
1684 {
1685  const char *func = "dfs_equal_keyword";
1686 
1687  cpl_frame *frame;
1688  cpl_propertylist *reference;
1689  cpl_type rtype;
1690  cpl_type type;
1691  const char *rstring;
1692  const char *string;
1693  int rintero;
1694  int intero;
1695  int found;
1696 
1697 
1698  if (frameset == NULL || keyword == NULL) {
1699  cpl_error_set(func, CPL_ERROR_NULL_INPUT);
1700  return 0;
1701  }
1702 
1703  if (cpl_frameset_is_empty(frameset)) {
1704  cpl_error_set(func, CPL_ERROR_DATA_NOT_FOUND);
1705  return 0;
1706  }
1707 
1708  frame = cpl_frameset_get_first(frameset);
1709 
1710  found = 0;
1711 
1712  while (frame) {
1713 
1714  reference = cpl_propertylist_load(cpl_frame_get_filename(frame), 0);
1715  if (cpl_error_get_code() == CPL_ERROR_BAD_FILE_FORMAT) {
1716  cpl_error_reset();
1717  frame = cpl_frameset_get_next(frameset);
1718  continue;
1719  }
1720 
1721  if (cpl_propertylist_has(reference, keyword)) {
1722  rtype = cpl_propertylist_get_type(reference, keyword);
1723 
1724  if (rtype == CPL_TYPE_STRING) {
1725  found = 1;
1726  rstring = cpl_strdup(cpl_propertylist_get_string(reference,
1727  keyword));
1728  cpl_propertylist_delete(reference);
1729  break;
1730  }
1731 
1732  if (rtype == CPL_TYPE_INT) {
1733  found = 1;
1734  rintero = cpl_propertylist_get_int(reference, keyword);
1735  cpl_propertylist_delete(reference);
1736  break;
1737  }
1738 
1739  cpl_propertylist_delete(reference);
1740  return 0;
1741  }
1742 
1743  cpl_propertylist_delete(reference);
1744 
1745  frame = cpl_frameset_get_next(frameset);
1746  }
1747 
1748 
1749  if (!found)
1750  return 1;
1751 
1752  frame = cpl_frameset_get_first(frameset);
1753 
1754  while (frame) {
1755 
1756  reference = cpl_propertylist_load(cpl_frame_get_filename(frame), 0);
1757  if (cpl_error_get_code() == CPL_ERROR_BAD_FILE_FORMAT) {
1758  cpl_error_reset();
1759  frame = cpl_frameset_get_next(frameset);
1760  continue;
1761  }
1762 
1763  if (cpl_propertylist_has(reference, keyword)) {
1764 
1765  type = cpl_propertylist_get_type(reference, keyword);
1766 
1767  if (rtype != type) {
1768  cpl_propertylist_delete(reference);
1769  return 0;
1770  }
1771 
1772  if (rtype == CPL_TYPE_STRING) {
1773  string = cpl_propertylist_get_string(reference,
1774  keyword);
1775  if (strncmp(rstring, string, 15)) {
1776  cpl_propertylist_delete(reference);
1777  return 0;
1778  }
1779  }
1780 
1781  if (rtype == CPL_TYPE_INT) {
1782  intero = cpl_propertylist_get_int(reference, keyword);
1783  if (rintero - intero) {
1784  cpl_propertylist_delete(reference);
1785  return 0;
1786  }
1787  }
1788  }
1789 
1790  cpl_propertylist_delete(reference);
1791 
1792  frame = cpl_frameset_get_next(frameset);
1793  }
1794 
1795  if (rtype == CPL_TYPE_STRING)
1796  cpl_free((void *)rstring);
1797 
1798  return 1;
1799 
1800 }
1801 
1811 cpl_error_code dfs_save_table_ext(cpl_table * table,
1812  const char * tag,
1813  cpl_propertylist * extheader)
1814 {
1815  char * filename = cpl_calloc(strlen(tag) + 6, sizeof(char));
1816  cpl_propertylist * header;
1817 
1818  if (extheader) {
1819  header = cpl_propertylist_duplicate(extheader);
1820 
1821  cpl_propertylist_erase_regexp(header,
1822  "^ESO DPR |^ARCFILE$|^ORIGFILE$", 0);
1823  } else {
1824  header = NULL;
1825  }
1826 
1827  strlower(strcpy(filename, tag));
1828  strcat(filename, ".fits");
1829 
1830  if (cpl_table_save(table, NULL, header, filename, CPL_IO_EXTEND)) {
1831  cpl_free(filename);
1832  cpl_ensure_code(0, CPL_ERROR_FILE_IO);
1833  }
1834 
1835  cpl_propertylist_delete(header);
1836  cpl_free(filename);
1837 
1838  return CPL_ERROR_NONE;
1839 }
1840 
1850 cpl_error_code dfs_save_image_ext(cpl_image * image,
1851  const char * tag,
1852  cpl_propertylist * extheader)
1853 {
1854  char * filename = cpl_calloc(strlen(tag) + 6, sizeof(char));
1855 
1856  cpl_propertylist * header;
1857 
1858  if (extheader) {
1859  header = cpl_propertylist_duplicate(extheader);
1860 
1861  cpl_propertylist_erase_regexp(header,
1862  "^ESO DPR |^ARCFILE$|^ORIGFILE$", 0);
1863  } else {
1864  header = NULL;
1865  }
1866 
1867  strlower(strcpy(filename, tag));
1868  strcat(filename, ".fits");
1869 
1870  if (cpl_image_save(image, filename, CPL_BPP_IEEE_FLOAT,
1871  header, CPL_IO_EXTEND)) {
1872  cpl_free(filename);
1873  cpl_ensure_code(0, CPL_ERROR_FILE_IO);
1874  }
1875 
1876  cpl_propertylist_delete(header);
1877  cpl_free(filename);
1878 
1879  return CPL_ERROR_NONE;
1880 }
1881 
1893 cpl_error_code dfs_save_image_null(cpl_frameset * frameset,
1894  cpl_parameterlist * parlist,
1895  const char * tag,
1896  const char * recipename,
1897  const char * version)
1898 {
1899 
1900  char * filename = cpl_calloc(strlen(tag) + 6, sizeof(char));
1901 
1902  cpl_error_code error;
1903 
1904  cpl_propertylist * pro = cpl_propertylist_new();
1905 
1906  cpl_propertylist_append_string(pro, "ESO PRO CATG", tag);
1907 
1908  strlower(strcpy(filename, tag));
1909  strcat(filename, ".fits");
1910 
1911  error = cpl_dfs_save_image(frameset, NULL, parlist, frameset, NULL, NULL,
1912  CPL_BPP_IEEE_FLOAT, recipename, pro,
1913  NULL, version, filename);
1914 
1915  cpl_free(filename);
1916  cpl_propertylist_delete(pro);
1917 
1918  return error;
1919 }
1920 
1921 
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:1274
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:860
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:602
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:964
void fors_dfs_add_exptime(cpl_propertylist *header, const cpl_frame *frame, double exptime)
Add keyword EXPTIME to header.
Definition: fors_dfs.c:1367
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:1893
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:1850
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:1149
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:996
#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:701
int dfs_equal_keyword(cpl_frameset *frameset, const char *keyword)
Saving table data of given category.
Definition: fors_dfs.c:1683
int dfs_get_parameter_int_const(const cpl_parameterlist *parlist, const char *name)
Definition: fors_dfs.c:806
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:1811
int dfs_get_parameter_bool_const(const cpl_parameterlist *parlist, const char *name)
Definition: fors_dfs.c:796
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:1407
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:1184
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:1451
cpl_table * dfs_load_table(cpl_frameset *frameset, const char *category, int ext)
Loading table data of given category.
Definition: fors_dfs.c:916
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:1575
const char * dfs_get_parameter_string_const(const cpl_parameterlist *parlist, const char *name)
Definition: fors_dfs.c:826
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:504
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:1313
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:816
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:1237