MUSE Pipeline Reference Manual  0.18.1
muse_processinginfo.c
1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set sw=2 sts=2 et cin: */
3 /*
4  *
5  * This file is part of the MUSE Instrument Pipeline
6  * Copyright (C) 2005-2011 European Southern Observatory
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21  */
22 
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 
27 /*----------------------------------------------------------------------------*
28  * Includes *
29  *----------------------------------------------------------------------------*/
30 #include <stdio.h>
31 #include <string.h>
32 #include <math.h>
33 #include <cpl.h>
34 
35 #include "muse_processing.h"
36 
37 #include "muse_utils.h"
38 
39 /*---------------------------------------------------------------------------*/
43 /*---------------------------------------------------------------------------*/
44 
47 /*----------------------------------------------------------------------------*
48  * Static variables *
49  *----------------------------------------------------------------------------*/
50 /*---------------------------------------------------------------------------*/
54 /*---------------------------------------------------------------------------*/
55 typedef struct muse_processinginfo_s {
56  struct muse_processinginfo_s *prev;
57  struct muse_processinginfo_s *next;
58  cpl_recipe *plugin;
59  cpl_recipeconfig *recipeconfig;
61  muse_processing_prepare_header_func *prepare_header;
63  muse_processing_get_frame_level_func *get_frame_level;
65  muse_processing_get_frame_mode_func *get_frame_mode;
67 
68 /*---------------------------------------------------------------------------*/
72 /*---------------------------------------------------------------------------*/
74 
75 /*---------------------------------------------------------------------------*/
79 /*---------------------------------------------------------------------------*/
80 
81 static muse_processinginfo_t *
82 muse_processinginfo_get(const cpl_recipe *aRecipe) {
83  if (muse_processinginfo != NULL) {
85  for (m = muse_processinginfo; m != NULL; m = m->next) {
86  if (m->plugin == aRecipe) {
87  return m;
88  }
89  }
90  }
91  return NULL;
92 }
93 
94 /*---------------------------------------------------------------------------*/
106 /*---------------------------------------------------------------------------*/
107 void
109 ( cpl_recipe *plugin,
110  cpl_recipeconfig *recipeconfig,
111  muse_processing_prepare_header_func *prepare_header,
112  muse_processing_get_frame_level_func *get_frame_level,
113  muse_processing_get_frame_mode_func *get_frame_mode) {
114 
116  if (muse_processinginfo == NULL) {
117  muse_processinginfo = cpl_calloc(1, sizeof(muse_processinginfo_t));
119  } else {
120  while (m->next != NULL) {
121  m = m->next;
122  }
123  m->next = cpl_calloc(1, sizeof(muse_processinginfo_t));
124  m->next->prev = m;
125  m = m->next;
126  }
127  m->plugin = plugin;
128  m->recipeconfig = recipeconfig;
129  m->prepare_header = prepare_header;
130  m->get_frame_level = get_frame_level;
131  m->get_frame_mode = get_frame_mode;
132 }
133 
134 /*---------------------------------------------------------------------------*/
142 /*---------------------------------------------------------------------------*/
143 void
144 muse_processinginfo_delete(cpl_recipe *aRecipe) {
146  if (m == NULL) {
147  return;
148  }
149  if (m == muse_processinginfo) {
150  muse_processinginfo = m->next;
151  if (muse_processinginfo != NULL) {
152  muse_processinginfo->prev = NULL;
153  }
154  } else {
155  m->prev->next = m->next;
156  if (m->next != NULL) {
157  m->next->prev = m->prev;
158  }
159  }
160  cpl_recipeconfig_delete(m->recipeconfig);
161  cpl_free(m);
162 }
163 
164 /*---------------------------------------------------------------------------*/
172 /*---------------------------------------------------------------------------*/
173 cpl_error_code muse_processing_prepare_header(const cpl_recipe *aRecipe,
174  const char *aFrametag,
175  cpl_propertylist *aHeader) {
177  return (m != NULL)? (* m->prepare_header)(aFrametag, aHeader): CPL_ERROR_NONE;
178 }
179 
180 /*---------------------------------------------------------------------------*/
187 /*---------------------------------------------------------------------------*/
188 cpl_frame_level
189 muse_processing_get_frame_level(const cpl_recipe *aRecipe,
190  const char *aFrametag) {
192  return (m != NULL)? (* m->get_frame_level)(aFrametag): CPL_FRAME_LEVEL_NONE;
193 }
194 
195 /*---------------------------------------------------------------------------*/
202 /*---------------------------------------------------------------------------*/
203 int
204 muse_processing_get_frame_mode(const cpl_recipe *aRecipe,
205  const char *aFrametag) {
207  return (m != NULL)?(* m->get_frame_mode)(aFrametag): MUSE_FRAME_MODE_ALL;
208 }
209 
210 /*---------------------------------------------------------------------------*/
216 /*---------------------------------------------------------------------------*/
217 cpl_recipeconfig *
218 muse_processing_get_recipeconfig(cpl_recipe *aRecipe) {
220  return (m != NULL)?m->recipeconfig: NULL;
221 }
222 
223 /*---------------------------------------------------------------------------*/
239 /*---------------------------------------------------------------------------*/
240 cpl_error_code
241 muse_processing_prepare_property(cpl_propertylist *aHeader, const char *aName,
242  cpl_type aType, const char *aDescription)
243 {
244  cpl_ensure_code(aHeader, CPL_ERROR_NULL_INPUT);
245  cpl_ensure_code(aName, CPL_ERROR_NULL_INPUT);
246 
247  cpl_error_code rc = CPL_ERROR_NONE;
248 
249  cpl_propertylist *list = cpl_propertylist_new();
250  cpl_propertylist_copy_property_regexp(list, aHeader, aName, 0);
251  if (cpl_propertylist_is_empty(list)) {
252  cpl_propertylist_delete(list);
253 
254  // The tag MUSE PRIVATE DOCUMENTATION is set in xmldoc.c and checked
255  // here:
256  // If it is not set (the normal case in a recipe), just an error
257  // message is generated in case of a missing header.
258  if (!cpl_propertylist_has(aHeader, "MUSE PRIVATE DOCUMENTATION")) {
259  cpl_msg_warning(__func__, "Property %s (%s) not used", aName,
260  aDescription);
261  return CPL_ERROR_DATA_NOT_FOUND;
262  }
263  // If this property is set (if the function is used from
264  // muse_xmldoc), then we add missing headers with some default
265  // values.
266  switch(aType) {
267  case CPL_TYPE_FLOAT:
268  cpl_propertylist_append_float(aHeader, aName, NAN);
269  break;
270  case CPL_TYPE_DOUBLE:
271  cpl_propertylist_append_double(aHeader, aName, NAN);
272  break;
273  case CPL_TYPE_STRING:
274  cpl_propertylist_append_string(aHeader, aName, "");
275  break;
276  case CPL_TYPE_INT:
277  cpl_propertylist_append_int(aHeader, aName, INT_MAX);
278  break;
279  case CPL_TYPE_LONG:
280  cpl_propertylist_append_long(aHeader, aName, LONG_MAX);
281  break;
282  case CPL_TYPE_BOOL:
283  cpl_propertylist_append_bool(aHeader, aName, FALSE);
284  break;
285  default:
286  return CPL_ERROR_INVALID_TYPE;
287  }
288 
289  /* XXX ugly: copied code from below for the moment to keep the case *
290  * of the documentation working */
291  cpl_property *property = cpl_propertylist_get_property(aHeader, aName);
292  if (aDescription != NULL && strlen(aDescription)>0) {
293  rc = cpl_property_set_comment(property, aDescription);
294  }
295  cpl_type type = cpl_property_get_type(property);
296  if (type != aType) {
297  cpl_msg_warning(__func__, "Type of property %s is %s but should be %s",
298  aName, cpl_type_get_name(type), cpl_type_get_name(aType));
299  return CPL_ERROR_TYPE_MISMATCH;
300  }
301  return CPL_ERROR_NONE;
302  } /* empty list of properties of regexp search */
303 
304  /* loop through the properties that matched the regular expressions */
305  int i;
306  for (i = 0; i < cpl_propertylist_get_size(list); i++) {
307  cpl_property *prop = cpl_propertylist_get(list, i);
308  cpl_property *property =
309  cpl_propertylist_get_property(aHeader, cpl_property_get_name(prop));
310  if (aDescription != NULL && strlen(aDescription)>0) {
311  rc = cpl_property_set_comment(property, aDescription);
312  }
313  cpl_type type = cpl_property_get_type(property);
314  if (type != aType) {
315  cpl_msg_warning(__func__, "Type of property %s is %s but should be %s",
316  aName, cpl_type_get_name(type), cpl_type_get_name(aType));
317  cpl_propertylist_delete(list);
318  return CPL_ERROR_TYPE_MISMATCH;
319  }
320  } /* for i (all regexp-found properties) */
321  cpl_propertylist_delete(list);
322  return rc;
323 }
324 
int muse_processing_get_frame_mode(const cpl_recipe *aRecipe, const char *aFrametag)
Get the mode for a product frame with a certain tag.
cpl_error_code muse_processing_prepare_header(const cpl_recipe *aRecipe, const char *aFrametag, cpl_propertylist *aHeader)
Prepare and check a FITS header for a certain frame tag.
struct muse_processinginfo_s muse_processinginfo_t
cpl_frame_level muse_processing_get_frame_level(const cpl_recipe *aRecipe, const char *aFrametag)
Get the level for a product frame with a certain tag.
void muse_processinginfo_delete(cpl_recipe *aRecipe)
Clear all information from the processing info and from the recipe config.
cpl_recipeconfig * muse_processing_get_recipeconfig(cpl_recipe *aRecipe)
Get the recipe (frame) configuration.
void muse_processinginfo_register(cpl_recipe *plugin, cpl_recipeconfig *recipeconfig, muse_processing_prepare_header_func *prepare_header, muse_processing_get_frame_level_func *get_frame_level, muse_processing_get_frame_mode_func *get_frame_mode)
Register extended functionalities for MUSE recipes.
static muse_processinginfo_t * muse_processinginfo_get(const cpl_recipe *aRecipe)
Get processinginfo for a certain recipe.
static muse_processinginfo_t * muse_processinginfo
cpl_error_code muse_processing_prepare_property(cpl_propertylist *aHeader, const char *aName, cpl_type aType, const char *aDescription)
Prepare and check the specified property.