00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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
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
00152
00153
00154 recipe->parameters = cpl_parameterlist_new();
00155
00156
00157
00158
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
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
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
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
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
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
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
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
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
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
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 }