|
IIINSTRUMENT Pipeline Reference Manual
0.0.9
|
00001 /* $Id: rrrecipe.c,v 1.33 2013-03-26 17:00:45 jtaylor Exp $ 00002 * 00003 * This file is part of the IIINSTRUMENT Pipeline 00004 * Copyright (C) 2002,2003 European Southern Observatory 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00019 */ 00020 00021 /* 00022 * $Author: jtaylor $ 00023 * $Date: 2013-03-26 17:00:45 $ 00024 * $Revision: 1.33 $ 00025 * $Name: not supported by cvs2svn $ 00026 */ 00027 00028 #ifdef HAVE_CONFIG_H 00029 #include <config.h> 00030 #endif 00031 00032 /*----------------------------------------------------------------------------- 00033 Includes 00034 -----------------------------------------------------------------------------*/ 00035 00036 #include "iiinstrument_utils.h" 00037 #include "iiinstrument_pfits.h" 00038 #include "iiinstrument_dfs.h" 00039 00040 #include <cpl.h> 00041 00042 /*----------------------------------------------------------------------------- 00043 Plugin registration 00044 -----------------------------------------------------------------------------*/ 00045 00046 int cpl_plugin_get_info(cpl_pluginlist * list); 00047 00048 /*----------------------------------------------------------------------------- 00049 Private function prototypes 00050 -----------------------------------------------------------------------------*/ 00051 00052 static int rrrecipe_create(cpl_plugin *); 00053 static int rrrecipe_exec(cpl_plugin *); 00054 static int rrrecipe_destroy(cpl_plugin *); 00055 static int rrrecipe(cpl_frameset *, const cpl_parameterlist *); 00056 00057 /*----------------------------------------------------------------------------- 00058 Static variables 00059 -----------------------------------------------------------------------------*/ 00060 00061 static char rrrecipe_description[] = 00062 "This example text is used to describe the recipe.\n" 00063 "The description should include the required FITS-files and\n" 00064 "their associated tags, e.g.\n" 00065 "IIINSTRUMENT-RRRECIPE-raw-file.fits " RRRECIPE_RAW "\n" 00066 "and any optional files, e.g.\n" 00067 "IIINSTRUMENT-RRRECIPE-flat-file.fits " IIINSTRUMENT_CALIB_FLAT "\n" 00068 "\n" 00069 "Additionally, it should describe functionality of the expected output." 00070 "\n"; 00071 00072 /*----------------------------------------------------------------------------- 00073 Function code 00074 -----------------------------------------------------------------------------*/ 00075 00076 /*----------------------------------------------------------------------------*/ 00086 /*----------------------------------------------------------------------------*/ 00087 int cpl_plugin_get_info(cpl_pluginlist * list) 00088 { 00089 cpl_recipe * recipe = cpl_calloc(1, sizeof *recipe ); 00090 cpl_plugin * plugin = &recipe->interface; 00091 00092 if (cpl_plugin_init(plugin, 00093 CPL_PLUGIN_API, 00094 IIINSTRUMENT_BINARY_VERSION, 00095 CPL_PLUGIN_TYPE_RECIPE, 00096 "rrrecipe", 00097 "Short description of rrrecipe", 00098 rrrecipe_description, 00099 "Firstname Lastname", 00100 PACKAGE_BUGREPORT, 00101 iiinstrument_get_license(), 00102 rrrecipe_create, 00103 rrrecipe_exec, 00104 rrrecipe_destroy)) { 00105 cpl_msg_error(cpl_func, "Plugin initialization failed"); 00106 (void)cpl_error_set_where(cpl_func); 00107 return 1; 00108 } 00109 00110 if (cpl_pluginlist_append(list, plugin)) { 00111 cpl_msg_error(cpl_func, "Error adding plugin to list"); 00112 (void)cpl_error_set_where(cpl_func); 00113 return 1; 00114 } 00115 00116 return 0; 00117 } 00118 00119 /*----------------------------------------------------------------------------*/ 00127 /*----------------------------------------------------------------------------*/ 00128 static int rrrecipe_create(cpl_plugin * plugin) 00129 { 00130 cpl_recipe * recipe; 00131 cpl_parameter * p; 00132 00133 /* Do not create the recipe if an error code is already set */ 00134 if (cpl_error_get_code() != CPL_ERROR_NONE) { 00135 cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s", 00136 cpl_func, __LINE__, cpl_error_get_where()); 00137 return (int)cpl_error_get_code(); 00138 } 00139 00140 if (plugin == NULL) { 00141 cpl_msg_error(cpl_func, "Null plugin"); 00142 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT); 00143 } 00144 00145 /* Verify plugin type */ 00146 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) { 00147 cpl_msg_error(cpl_func, "Plugin is not a recipe"); 00148 cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH); 00149 } 00150 00151 /* Get the recipe */ 00152 recipe = (cpl_recipe *)plugin; 00153 00154 /* Create the parameters list in the cpl_recipe object */ 00155 recipe->parameters = cpl_parameterlist_new(); 00156 if (recipe->parameters == NULL) { 00157 cpl_msg_error(cpl_func, "Parameter list allocation failed"); 00158 cpl_ensure_code(0, (int)CPL_ERROR_ILLEGAL_OUTPUT); 00159 } 00160 00161 /* Fill the parameters list */ 00162 /* --stropt */ 00163 p = cpl_parameter_new_value("iiinstrument.rrrecipe.str_option", 00164 CPL_TYPE_STRING, "the string option", 00165 "iiinstrument.rrrecipe", "NONE"); 00166 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "stropt"); 00167 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00168 cpl_parameterlist_append(recipe->parameters, p); 00169 00170 p = cpl_parameter_new_value("iiinstrument.rrrecipe.file_option", 00171 CPL_TYPE_STRING, "the string option", 00172 "iiinstrument.rrrecipe", "NONE"); 00173 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "fileopt"); 00174 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00175 cpl_parameterlist_append(recipe->parameters, p); 00176 00177 /* --boolopt */ 00178 p = cpl_parameter_new_value("iiinstrument.rrrecipe.bool_option", 00179 CPL_TYPE_BOOL, "a flag", 00180 "iiinstrument.rrrecipe", TRUE); 00181 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "boolopt"); 00182 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00183 cpl_parameterlist_append(recipe->parameters, p); 00184 00185 p = cpl_parameter_new_value("iiinstrument.rrrecipe.int_option", 00186 CPL_TYPE_INT, "a flag", 00187 "iiinstrument.rrrecipe", 3); 00188 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "intopt"); 00189 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00190 cpl_parameterlist_append(recipe->parameters, p); 00191 00192 p = cpl_parameter_new_range("iiinstrument.rrrecipe.range_option", CPL_TYPE_DOUBLE, 00193 "This is a value range of type double", 00194 "Example", 0.5, 0.0, 1.0); 00195 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "rangeopt"); 00196 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00197 cpl_parameterlist_append(recipe->parameters, p); 00198 00199 p = cpl_parameter_new_enum("iiinstrument.rrrecipe.enum_option", CPL_TYPE_STRING, 00200 "This is an enumeration of type " "string", 00201 "Example", "first", 3, "first", "second", "third"); 00202 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "enumopt"); 00203 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00204 cpl_parameterlist_append(recipe->parameters, p); 00205 00206 00207 return 0; 00208 } 00209 00210 /*----------------------------------------------------------------------------*/ 00216 /*----------------------------------------------------------------------------*/ 00217 static int rrrecipe_exec(cpl_plugin * plugin) 00218 { 00219 00220 cpl_recipe * recipe; 00221 int recipe_status; 00222 cpl_errorstate initial_errorstate = cpl_errorstate_get(); 00223 00224 /* Return immediately if an error code is already set */ 00225 if (cpl_error_get_code() != CPL_ERROR_NONE) { 00226 cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s", 00227 cpl_func, __LINE__, cpl_error_get_where()); 00228 return (int)cpl_error_get_code(); 00229 } 00230 00231 if (plugin == NULL) { 00232 cpl_msg_error(cpl_func, "Null plugin"); 00233 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT); 00234 } 00235 00236 /* Verify plugin type */ 00237 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) { 00238 cpl_msg_error(cpl_func, "Plugin is not a recipe"); 00239 cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH); 00240 } 00241 00242 /* Get the recipe */ 00243 recipe = (cpl_recipe *)plugin; 00244 00245 /* Verify parameter and frame lists */ 00246 if (recipe->parameters == NULL) { 00247 cpl_msg_error(cpl_func, "Recipe invoked with NULL parameter list"); 00248 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT); 00249 } 00250 if (recipe->frames == NULL) { 00251 cpl_msg_error(cpl_func, "Recipe invoked with NULL frame set"); 00252 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT); 00253 } 00254 00255 /* Invoke the recipe */ 00256 recipe_status = rrrecipe(recipe->frames, recipe->parameters); 00257 00258 /* Ensure DFS-compliance of the products */ 00259 if (cpl_dfs_update_product_header(recipe->frames)) { 00260 if (!recipe_status) recipe_status = (int)cpl_error_get_code(); 00261 } 00262 00263 if (!cpl_errorstate_is_equal(initial_errorstate)) { 00264 /* Dump the error history since recipe execution start. 00265 At this point the recipe cannot recover from the error */ 00266 cpl_errorstate_dump(initial_errorstate, CPL_FALSE, NULL); 00267 } 00268 00269 return recipe_status; 00270 } 00271 00272 /*----------------------------------------------------------------------------*/ 00278 /*----------------------------------------------------------------------------*/ 00279 static int rrrecipe_destroy(cpl_plugin * plugin) 00280 { 00281 cpl_recipe * recipe; 00282 00283 if (plugin == NULL) { 00284 cpl_msg_error(cpl_func, "Null plugin"); 00285 cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT); 00286 } 00287 00288 /* Verify plugin type */ 00289 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) { 00290 cpl_msg_error(cpl_func, "Plugin is not a recipe"); 00291 cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH); 00292 } 00293 00294 /* Get the recipe */ 00295 recipe = (cpl_recipe *)plugin; 00296 00297 cpl_parameterlist_delete(recipe->parameters); 00298 00299 return 0; 00300 } 00301 00302 /*----------------------------------------------------------------------------*/ 00309 /*----------------------------------------------------------------------------*/ 00310 static int rrrecipe(cpl_frameset * frameset, 00311 const cpl_parameterlist * parlist) 00312 { 00313 const cpl_parameter * param; 00314 const char * str_option; 00315 int bool_option; 00316 const cpl_frame * rawframe; 00317 const cpl_frame * flat; 00318 double qc_param; 00319 cpl_propertylist * plist; 00320 cpl_propertylist * applist; 00321 cpl_image * image; 00322 00323 /* Use the errorstate to detect an error in a function that does not 00324 return an error code. */ 00325 cpl_errorstate prestate = cpl_errorstate_get(); 00326 00327 /* HOW TO RETRIEVE INPUT PARAMETERS */ 00328 /* --stropt */ 00329 param = cpl_parameterlist_find_const(parlist, 00330 "iiinstrument.rrrecipe.str_option"); 00331 str_option = cpl_parameter_get_string(param); 00332 00333 /* --boolopt */ 00334 param = cpl_parameterlist_find_const(parlist, 00335 "iiinstrument.rrrecipe.bool_option"); 00336 bool_option = cpl_parameter_get_bool(param); 00337 00338 if (!cpl_errorstate_is_equal(prestate)) { 00339 return (int)cpl_error_set_message(cpl_func, cpl_error_get_code(), 00340 "Could not retrieve the input " 00341 "parameters"); 00342 } 00343 00344 /* Identify the RAW and CALIB frames in the input frameset */ 00345 cpl_ensure_code(iiinstrument_dfs_set_groups(frameset) == CPL_ERROR_NONE, 00346 cpl_error_get_code()); 00347 00348 /* HOW TO ACCESS INPUT DATA */ 00349 /* - A required file */ 00350 rawframe = cpl_frameset_find_const(frameset, RRRECIPE_RAW); 00351 if (rawframe == NULL) { 00352 /* cpl_frameset_find_const() does not set an error code, when a frame 00353 is not found, so we will set one here. */ 00354 return (int)cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND, 00355 "SOF does not have any file tagged " 00356 "with %s", RRRECIPE_RAW); 00357 } 00358 /* - A recommended file */ 00359 flat = cpl_frameset_find(frameset, IIINSTRUMENT_CALIB_FLAT); 00360 if (flat == NULL) { 00361 cpl_msg_warning(cpl_func, "SOF does not have any file tagged with %s", 00362 IIINSTRUMENT_CALIB_FLAT); 00363 } 00364 00365 /* HOW TO GET THE VALUE OF A FITS KEYWORD */ 00366 /* - Load only DETector related keys */ 00367 plist = cpl_propertylist_load_regexp(cpl_frame_get_filename(rawframe), 00368 0, "ESO DET ", 0); 00369 if (plist == NULL) { 00370 /* In this case an error message is added to the error propagation */ 00371 return (int)cpl_error_set_message(cpl_func, cpl_error_get_code(), 00372 "Could not read the FITS header"); 00373 } 00374 00375 qc_param = iiinstrument_pfits_get_dit(plist); 00376 cpl_propertylist_delete(plist); 00377 00378 /* Check for a change in the CPL error state */ 00379 /* - if it did change then propagate the error and return */ 00380 cpl_ensure_code(cpl_errorstate_is_equal(prestate), cpl_error_get_code()); 00381 00382 /* NOW PERFORMING THE DATA REDUCTION */ 00383 /* Let's just load an image for the example */ 00384 image = cpl_image_load(cpl_frame_get_filename(rawframe), CPL_TYPE_FLOAT, 0, 00385 0); 00386 if (image == NULL) { 00387 return (int)cpl_error_set_message(cpl_func, cpl_error_get_code(), 00388 "Could not load the image"); 00389 } 00390 00391 applist = cpl_propertylist_new(); 00392 00393 /* Add the product category */ 00394 cpl_propertylist_append_string(applist, CPL_DFS_PRO_CATG, 00395 RRRECIPE_OUT_PROCATG); 00396 00397 /* Add a QC parameter */ 00398 cpl_propertylist_append_double(applist, "ESO QC QCPARAM", qc_param); 00399 00400 /* HOW TO SAVE A DFS-COMPLIANT PRODUCT TO DISK */ 00401 if (cpl_dfs_save_image(frameset, NULL, parlist, frameset, NULL, image, 00402 CPL_BPP_IEEE_FLOAT, "rrrecipe", applist, 00403 NULL, PACKAGE "/" PACKAGE_VERSION, 00404 "rrrecipe.fits")) { 00405 /* Propagate the error */ 00406 (void)cpl_error_set_where(cpl_func); 00407 } 00408 00409 cpl_image_delete(image); 00410 cpl_propertylist_delete(applist); 00411 00412 return (int)cpl_error_get_code(); 00413 }
1.7.6.1