FORS Pipeline Reference Manual 4.9.9
|
00001 /* $Id: montecarlo.c,v 1.4 2010/09/14 07:38:16 cizzo Exp $ 00002 * 00003 * This file is part of the FORS Data Reduction Pipeline 00004 * Copyright (C) 2002-2010 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: cizzo $ 00023 * $Date: 2010/09/14 07:38:16 $ 00024 * $Revision: 1.4 $ 00025 * $Name: fors-4_9_9 $ 00026 */ 00027 00028 #ifdef HAVE_CONFIG_H 00029 #include <config.h> 00030 #endif 00031 00032 #include <string.h> 00033 #include <cpl.h> 00034 #include <moses.h> 00035 #include <fors_dfs.h> 00036 00037 static int montecarlo_create(cpl_plugin *); 00038 static int montecarlo_exec(cpl_plugin *); 00039 static int montecarlo_destroy(cpl_plugin *); 00040 static int montecarlo(cpl_parameterlist *, cpl_frameset *); 00041 00042 static char montecarlo_description[] = 00043 "This recipe is used to test the mos_montecarlo_polyfit() function.\n" 00044 "It accepts a table with columns x, y, y_err, derives the best polynomial\n" 00045 "fit y = p(x), and produces a table with the polynomial 1-sigma accuracy\n" 00046 "on the given set of x coordinates.\n" 00047 "Input files:\n\n" 00048 " DO category: Type: Explanation: Required:\n" 00049 " TABLE Raw Table to evaluate Y\n\n" 00050 "Output files:\n\n" 00051 " DO category: Data type: Explanation:\n" 00052 " MODEL_ERROR FITS image Model error at different x\n\n"; 00053 00054 #define montecarlo_exit(message) \ 00055 { \ 00056 if (message) cpl_msg_error(recipe, message); \ 00057 cpl_table_delete(table); \ 00058 cpl_table_delete(points); \ 00059 cpl_table_delete(model_error); \ 00060 cpl_polynomial_delete(p); \ 00061 cpl_msg_indent_less(); \ 00062 return -1; \ 00063 } 00064 00065 #define montecarlo_exit_memcheck(message) \ 00066 { \ 00067 if (message) cpl_msg_info(recipe, message); \ 00068 cpl_table_delete(table); \ 00069 cpl_table_delete(points); \ 00070 cpl_table_delete(model_error); \ 00071 cpl_polynomial_delete(p); \ 00072 cpl_msg_indent_less(); \ 00073 return 0; \ 00074 } 00075 00076 00088 int cpl_plugin_get_info(cpl_pluginlist *list) 00089 { 00090 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe ); 00091 cpl_plugin *plugin = &recipe->interface; 00092 00093 cpl_plugin_init(plugin, 00094 CPL_PLUGIN_API, 00095 FORS_BINARY_VERSION, 00096 CPL_PLUGIN_TYPE_RECIPE, 00097 "montecarlo", 00098 "Test function mos_montecarlo_polyfit()", 00099 montecarlo_description, 00100 "Carlo Izzo", 00101 PACKAGE_BUGREPORT, 00102 "This file is currently part of the FORS Instrument Pipeline\n" 00103 "Copyright (C) 2002-2010 European Southern Observatory\n\n" 00104 "This program is free software; you can redistribute it and/or modify\n" 00105 "it under the terms of the GNU General Public License as published by\n" 00106 "the Free Software Foundation; either version 2 of the License, or\n" 00107 "(at your option) any later version.\n\n" 00108 "This program is distributed in the hope that it will be useful,\n" 00109 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" 00110 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" 00111 "GNU General Public License for more details.\n\n" 00112 "You should have received a copy of the GNU General Public License\n" 00113 "along with this program; if not, write to the Free Software Foundation,\n" 00114 "Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n", 00115 montecarlo_create, 00116 montecarlo_exec, 00117 montecarlo_destroy); 00118 00119 cpl_pluginlist_append(list, plugin); 00120 00121 return 0; 00122 } 00123 00124 00135 static int montecarlo_create(cpl_plugin *plugin) 00136 { 00137 cpl_recipe *recipe; 00138 cpl_parameter *p; 00139 00140 00141 /* 00142 * Check that the plugin is part of a valid recipe 00143 */ 00144 00145 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00146 recipe = (cpl_recipe *)plugin; 00147 else 00148 return -1; 00149 00150 /* 00151 * Create the parameters list in the cpl_recipe object 00152 */ 00153 00154 recipe->parameters = cpl_parameterlist_new(); 00155 00156 00157 /* 00158 * Name of input table columns 00159 */ 00160 00161 p = cpl_parameter_new_value("fors.montecarlo.x", 00162 CPL_TYPE_STRING, 00163 "Name of independent variable column", 00164 "fors.montecarlo", 00165 "x"); 00166 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "x"); 00167 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00168 cpl_parameterlist_append(recipe->parameters, p); 00169 00170 p = cpl_parameter_new_value("fors.montecarlo.y", 00171 CPL_TYPE_STRING, 00172 "Name of dependent variable column", 00173 "fors.montecarlo", 00174 "y"); 00175 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "y"); 00176 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00177 cpl_parameterlist_append(recipe->parameters, p); 00178 00179 p = cpl_parameter_new_value("fors.montecarlo.sigma", 00180 CPL_TYPE_STRING, 00181 "Name of error column on dependent variable", 00182 "fors.montecarlo", 00183 ""); 00184 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "sigma"); 00185 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00186 cpl_parameterlist_append(recipe->parameters, p); 00187 00188 /* 00189 * Order of fitting polynomial 00190 */ 00191 00192 p = cpl_parameter_new_value("fors.montecarlo.order", 00193 CPL_TYPE_INT, 00194 "Order of fitting polynomial", 00195 "fors.montecarlo", 00196 1); 00197 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "order"); 00198 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00199 cpl_parameterlist_append(recipe->parameters, p); 00200 00201 /* 00202 * Origin of x for fit 00203 */ 00204 00205 p = cpl_parameter_new_value("fors.montecarlo.zero", 00206 CPL_TYPE_DOUBLE, 00207 "Origin of x for fit", 00208 "fors.montecarlo", 00209 0.0); 00210 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "zero"); 00211 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00212 cpl_parameterlist_append(recipe->parameters, p); 00213 00214 /* 00215 * Start x for evaluation 00216 */ 00217 00218 p = cpl_parameter_new_value("fors.montecarlo.start", 00219 CPL_TYPE_DOUBLE, 00220 "Start x for evaluation", 00221 "fors.montecarlo", 00222 0.0); 00223 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "start"); 00224 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00225 cpl_parameterlist_append(recipe->parameters, p); 00226 00227 /* 00228 * End x for evaluation 00229 */ 00230 00231 p = cpl_parameter_new_value("fors.montecarlo.end", 00232 CPL_TYPE_DOUBLE, 00233 "End x for evaluation", 00234 "fors.montecarlo", 00235 0.0); 00236 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "end"); 00237 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00238 cpl_parameterlist_append(recipe->parameters, p); 00239 00240 /* 00241 * Evaluation sampling 00242 */ 00243 00244 p = cpl_parameter_new_value("fors.montecarlo.step", 00245 CPL_TYPE_DOUBLE, 00246 "x sampling interval", 00247 "fors.montecarlo", 00248 0.0); 00249 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "step"); 00250 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00251 cpl_parameterlist_append(recipe->parameters, p); 00252 00253 /* 00254 * Statistical sample 00255 */ 00256 00257 p = cpl_parameter_new_value("fors.montecarlo.trials", 00258 CPL_TYPE_INT, 00259 "Size of statistical sample", 00260 "fors.montecarlo", 00261 100); 00262 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "trials"); 00263 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00264 cpl_parameterlist_append(recipe->parameters, p); 00265 00266 return 0; 00267 } 00268 00269 00278 static int montecarlo_exec(cpl_plugin *plugin) 00279 { 00280 cpl_recipe *recipe; 00281 00282 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00283 recipe = (cpl_recipe *)plugin; 00284 else 00285 return -1; 00286 00287 return montecarlo(recipe->parameters, recipe->frames); 00288 } 00289 00290 00299 static int montecarlo_destroy(cpl_plugin *plugin) 00300 { 00301 cpl_recipe *recipe; 00302 00303 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00304 recipe = (cpl_recipe *)plugin; 00305 else 00306 return -1; 00307 00308 cpl_parameterlist_delete(recipe->parameters); 00309 00310 return 0; 00311 } 00312 00313 00323 static int montecarlo(cpl_parameterlist *parlist, cpl_frameset *frameset) 00324 { 00325 00326 const char *recipe = "montecarlo"; 00327 00328 00329 /* 00330 * Input parameters 00331 */ 00332 00333 const char *x; 00334 const char *y; 00335 const char *sigma; 00336 int order; 00337 double start; 00338 double end; 00339 double step; 00340 int trials; 00341 double zero; 00342 00343 /* 00344 * CPL objects 00345 */ 00346 00347 cpl_table *table = NULL; 00348 cpl_table *model_error = NULL; 00349 cpl_table *points = NULL; 00350 cpl_polynomial *p = NULL; 00351 00352 /* 00353 * Auxiliary variables 00354 */ 00355 00356 char *version = "0.1"; 00357 char *table_tag = "TABLE"; 00358 char *model_error_tag = "MODEL_ERROR"; 00359 double *xdata; 00360 int ntables; 00361 int i, count; 00362 00363 00364 cpl_msg_set_indentation(2); 00365 00366 if (dfs_files_dont_exist(frameset)) 00367 montecarlo_exit(NULL); 00368 00369 00370 /* 00371 * Get configuration parameters 00372 */ 00373 00374 cpl_msg_info(recipe, "Recipe %s configuration parameters:", recipe); 00375 cpl_msg_indent_more(); 00376 00377 x = dfs_get_parameter_string(parlist, "fors.montecarlo.x", NULL); 00378 y = dfs_get_parameter_string(parlist, "fors.montecarlo.y", NULL); 00379 sigma = dfs_get_parameter_string(parlist, "fors.montecarlo.sigma", NULL); 00380 order = dfs_get_parameter_int(parlist, "fors.montecarlo.order", NULL); 00381 if (order < 0) 00382 montecarlo_exit("Invalid polynomial order"); 00383 start = dfs_get_parameter_double(parlist, "fors.montecarlo.start", NULL); 00384 end = dfs_get_parameter_double(parlist, "fors.montecarlo.end", NULL); 00385 if (end <= start) 00386 montecarlo_exit("Invalid interval"); 00387 step = dfs_get_parameter_double(parlist, "fors.montecarlo.step", NULL); 00388 if (step >= end - start || step <= 0.0) 00389 montecarlo_exit("Invalid step"); 00390 trials = dfs_get_parameter_int(parlist, "fors.montecarlo.trials", NULL); 00391 if (trials < 2) 00392 montecarlo_exit("At least 2 trials should be performed"); 00393 zero = dfs_get_parameter_double(parlist, "fors.montecarlo.zero", NULL); 00394 00395 if (cpl_error_get_code()) 00396 montecarlo_exit("Failure getting the configuration parameters"); 00397 00398 ntables = cpl_frameset_count_tags(frameset, table_tag); 00399 if (ntables == 0) { 00400 cpl_msg_error(recipe, "Missing required input: %s", table_tag); 00401 montecarlo_exit(NULL); 00402 } 00403 if (ntables > 1) { 00404 cpl_msg_error(recipe, "Too many in input: %s", table_tag); 00405 montecarlo_exit(NULL); 00406 } 00407 00408 table = dfs_load_table(frameset, table_tag, 1); 00409 points = cpl_table_new(cpl_table_get_nrow(table)); 00410 00411 if (cpl_table_has_column(table, x)) { 00412 cpl_table_move_column(points, x, table); 00413 if (!cpl_table_has_column(points, "x")) { 00414 cpl_table_name_column(points, x, "x"); 00415 } 00416 } 00417 else { 00418 cpl_msg_error(recipe, "Missing column: %s", x); 00419 montecarlo_exit(NULL); 00420 } 00421 00422 cpl_table_subtract_scalar(points, "x", zero); 00423 00424 if (cpl_table_has_column(table, y)) { 00425 cpl_table_move_column(points, y, table); 00426 if (!cpl_table_has_column(points, "y")) { 00427 cpl_table_name_column(points, y, "y"); 00428 } 00429 } 00430 else { 00431 cpl_msg_error(recipe, "Missing column: %s", y); 00432 montecarlo_exit(NULL); 00433 } 00434 00435 if (sigma[0] != '\0') { 00436 if (cpl_table_has_column(table, sigma)) { 00437 cpl_table_move_column(points, sigma, table); 00438 if (!cpl_table_has_column(points, "y_err")) { 00439 cpl_table_name_column(points, sigma, "y_err"); 00440 } 00441 } 00442 else { 00443 cpl_msg_error(recipe, "Missing column: %s", sigma); 00444 montecarlo_exit(NULL); 00445 } 00446 } 00447 00448 cpl_table_delete(table); table = NULL; 00449 cpl_table_erase_invalid(points); 00450 00451 count = 1; 00452 while (start + step*count <= end) 00453 count++; 00454 00455 model_error = cpl_table_new(count); 00456 cpl_table_new_column(model_error, "x", CPL_TYPE_DOUBLE); 00457 cpl_table_fill_column_window_double(model_error, "x", 0, count, 0.0); 00458 xdata = cpl_table_get_data_double(model_error, "x"); 00459 00460 for (i = 0; i < count; i++) 00461 xdata[i] = start + step*i - zero; 00462 00463 p = mos_montecarlo_polyfit(points, model_error, trials, order); 00464 00465 if (cpl_error_get_code() != CPL_ERROR_NONE) { 00466 cpl_msg_error(recipe, "%s", cpl_error_get_message()); 00467 montecarlo_exit(NULL); 00468 } 00469 00470 for (i = 0; i < count; i++) 00471 xdata[i] += zero; 00472 00473 cpl_polynomial_delete(p); p = NULL; 00474 cpl_table_delete(points); points = NULL; 00475 00476 if (dfs_save_table(frameset, model_error, model_error_tag, NULL, 00477 parlist, recipe, version)) 00478 montecarlo_exit(NULL); 00479 00480 cpl_table_delete(model_error); model_error = NULL; 00481 00482 return 0; 00483 }