36 #include "omega_recipe.h"
66 static int omega_qcheck_create(cpl_plugin *) ;
67 static int omega_qcheck_exec(cpl_plugin *) ;
68 static int omega_qcheck_destroy(cpl_plugin *) ;
69 static int omega_qcheck(cpl_frameset *,cpl_parameterlist *) ;
74 static void omega_qcheck_init(
void);
75 static void omega_qcheck_tidy(
void);
97 cpl_frameset *domelist;
98 omega_fits *domefits1;
109 #define RECIPE "omega_qcheck"
122 cpl_recipe * recipe = cpl_calloc(1,
sizeof(*recipe)) ;
123 cpl_plugin * plugin = &recipe->interface ;
125 cpl_plugin_init(plugin,
127 OMEGA_BINARY_VERSION,
128 CPL_PLUGIN_TYPE_RECIPE,
130 "OMEGA - Generates a quick check on the detector responsivity for each chip.",
131 "The recipe takes as input exactly one raw domeflat frame, and \n"
132 "a master bias. Optionally, an overscan correction mode can be set. \n"
133 "The default is to apply no overscan correction.",
139 omega_qcheck_destroy) ;
141 cpl_pluginlist_append(list, plugin) ;
156 static int omega_qcheck_create(cpl_plugin * plugin)
162 if (cpl_error_get_code() != CPL_ERROR_NONE) {
163 cpl_msg_error(cpl_func,
"%s():%d: An error is already set: %s",
164 cpl_func, __LINE__, cpl_error_get_where());
165 return (
int)cpl_error_get_code();
168 if (plugin == NULL) {
169 cpl_msg_error(cpl_func,
"Null plugin");
170 cpl_ensure_code(0, (
int)CPL_ERROR_NULL_INPUT);
174 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
175 cpl_msg_error(cpl_func,
"Plugin is not a recipe");
176 cpl_ensure_code(0, (
int)CPL_ERROR_TYPE_MISMATCH);
180 recipe = (cpl_recipe *)plugin;
183 recipe->parameters = cpl_parameterlist_new() ;
186 p = cpl_parameter_new_value(
"omega.omega_qcheck.ExtensionNumber",
188 "FITS extension number to load (1 to 32). (-1 == all)",
192 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"ext") ;
193 cpl_parameterlist_append(recipe->parameters, p) ;
196 p = cpl_parameter_new_range(
"omega.omega_qcheck.OverscanMethod",
198 "Overscan Correction Method (0 to 6):\n"
199 "0 = no overscan correction;\n"
200 "1 = use median of prescan in X;\n"
201 "2 = use median of overscan in X;\n"
202 "3 = use median on prescan in Y;\n"
203 "4 = use median of overscan in Y;\n"
204 "5 = per-row subtraction of the median of row in prescan regions of X;\n"
205 "6 = per-row subtraction of the median of row in overscan regions of X\n",
209 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"oc-meth") ;
210 cpl_parameterlist_append(recipe->parameters, p) ;
212 p = cpl_parameter_new_value(
"omega.omega_qcheck.PAF",
214 "Boolean value to create PAF files. 1(Yes), 0(No)",
218 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"paf") ;
219 cpl_parameterlist_append(recipe->parameters, p) ;
221 p = cpl_parameter_new_value(
"omega.omega_qcheck.rej_threshold",
223 "The rejection threshold for outlying pixels",
227 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"rej-thre") ;
228 cpl_parameterlist_append(recipe->parameters, p) ;
230 p = cpl_parameter_new_value(
"omega.omega_qcheck.NumberIter",
232 "The maximum number of iterations",
236 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"niter") ;
237 cpl_parameterlist_append(recipe->parameters, p) ;
251 static int omega_qcheck_exec(cpl_plugin * plugin)
257 if (cpl_error_get_code() != CPL_ERROR_NONE) {
258 cpl_msg_error(cpl_func,
"%s():%d: An error is already set: %s",
259 cpl_func, __LINE__, cpl_error_get_where());
260 return (
int)cpl_error_get_code();
263 if (plugin == NULL) {
264 cpl_msg_error(cpl_func,
"Null plugin");
265 cpl_ensure_code(0, (
int)CPL_ERROR_NULL_INPUT);
269 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
270 cpl_msg_error(cpl_func,
"Plugin is not a recipe");
271 cpl_ensure_code(0, (
int)CPL_ERROR_TYPE_MISMATCH);
275 recipe = (cpl_recipe *)plugin;
278 if (recipe->parameters == NULL) {
279 cpl_msg_error(cpl_func,
"Recipe invoked with NULL parameter list");
280 cpl_ensure_code(0, (
int)CPL_ERROR_NULL_INPUT);
282 if (recipe->frames == NULL) {
283 cpl_msg_error(cpl_func,
"Recipe invoked with NULL frame set");
284 cpl_ensure_code(0, (
int)CPL_ERROR_NULL_INPUT);
288 recipe_status = omega_qcheck(recipe->frames, recipe->parameters);
291 if (cpl_dfs_update_product_header(recipe->frames)) {
292 if (!recipe_status) recipe_status = (int)cpl_error_get_code();
296 return recipe_status;
306 static int omega_qcheck_destroy(cpl_plugin * plugin)
308 cpl_recipe * recipe = (cpl_recipe *)plugin ;
310 if (plugin == NULL) {
311 cpl_msg_error(cpl_func,
"Null plugin");
312 cpl_ensure_code(0, (
int)CPL_ERROR_NULL_INPUT);
316 if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
317 cpl_msg_error(cpl_func,
"Plugin is not a recipe");
318 cpl_ensure_code(0, (
int)CPL_ERROR_TYPE_MISMATCH);
322 recipe = (cpl_recipe *)plugin;
324 cpl_parameterlist_delete(recipe->parameters);
345 static int omega_qcheck(cpl_frameset *set, cpl_parameterlist *pars)
348 int j,jst,jfn,oscan1,isfirst;
350 cpl_frame *mbias_frame;
351 const cpl_frame *frame1;
352 cpl_image *mbias_image;
353 cpl_image *trim_raw1;
354 cpl_frame *product_frame;
356 cpl_propertylist *qclist,*alist;
362 cpl_msg_error (cpl_func,
"Parameters list not found");
366 if (cpl_frameset_is_empty(set) == 1) {
367 cpl_msg_error (cpl_func,
"Frameset not found");
375 par = cpl_parameterlist_find(pars,
"omega.omega_qcheck.ExtensionNumber") ;
376 omega_qcheck_config.extnum = cpl_parameter_get_int(par) ;
378 par = cpl_parameterlist_find(pars,
"omega.omega_qcheck.OverscanMethod") ;
379 omega_qcheck_config.oc = cpl_parameter_get_int(par) ;
381 par = cpl_parameterlist_find(pars,
"omega.omega_qcheck.NumberIter") ;
382 omega_qcheck_config.niter = cpl_parameter_get_int(par) ;
384 par = cpl_parameterlist_find(pars,
"omega.omega_qcheck.rej_threshold") ;
385 omega_qcheck_config.rejt = cpl_parameter_get_double(par) ;
387 par = cpl_parameterlist_find(pars,
"omega.omega_qcheck.PAF") ;
388 omega_qcheck_config.paf = cpl_parameter_get_bool(par) ;
391 if (oc_dfs_set_groups(set)) {
392 cpl_msg_error(cpl_func,
"Cannot identify RAW and CALIB frames") ;
402 cpl_msg_error(cpl_func,
"Cannot labelise the input frameset");
407 LIFETEST_RAW)) == NULL) {
408 cpl_msg_error(cpl_func,
"Cannot find dome frame in input frameset");
412 if (cpl_frameset_get_size(ps.domelist) < 1) {
413 cpl_msg_error(cpl_func,
"Need exactly 1 (%s) frame to run this recipe",LIFETEST_RAW);
419 frame1 = cpl_frameset_get_position_const(ps.domelist,0);
420 cpl_msg_info (cpl_func,
"Using %s frame: %s",LIFETEST_RAW,cpl_frame_get_filename(frame1));
422 mbias_frame = cpl_frameset_find(set, OMEGA_CALIB_BIAS);
423 if (mbias_frame == NULL) {
424 cpl_msg_error (cpl_func,
"No Master Bias is present in frame set");
429 cpl_msg_info(cpl_func,
"Using %s %s",OMEGA_CALIB_BIAS, cpl_frame_get_filename(mbias_frame));
433 if(omega_qcheck_config.extnum == 0){
434 cpl_msg_error(cpl_func,
"Unsupported extension request, %d",omega_qcheck_config.extnum);
439 for (j = jst; j <= jfn; j++) {
440 cpl_msg_info(cpl_func,
"Working on extension %d",j);
441 isfirst = (j == jst);
442 omega_qcheck_config.mean = 0.0;
443 omega_qcheck_config.median = 0.0;
444 omega_qcheck_config.stdev = 0.0;
462 if(oscan1 != omega_qcheck_config.oc) {
463 cpl_msg_warning (cpl_func,
"Overscan correction mode for Master Bias (oc = %d) differs from "
464 "the one used here (oc = %d)", oscan1, omega_qcheck_config.oc);
468 mbias_image = cpl_image_load(cpl_frame_get_filename(mbias_frame), CPL_TYPE_FLOAT, 0, j);
469 if (mbias_image == NULL) {
470 cpl_msg_error(cpl_func,
"Cannot load MASTER BIAS");
478 if(trim_raw1 == NULL){
479 cpl_msg_error(cpl_func,
"Cannot trim input image");
480 freeimage(mbias_image);
485 cpl_image_subtract(trim_raw1, mbias_image);
486 freeimage(mbias_image);
489 ps.stats =
omega_iter_stat_opts(trim_raw1,NULL,omega_qcheck_config.rejt,omega_qcheck_config.niter);
490 if(ps.stats != NULL){
491 omega_qcheck_config.mean = cpl_stats_get_mean(ps.stats);
492 omega_qcheck_config.median = cpl_stats_get_median(ps.stats);
493 omega_qcheck_config.stdev = cpl_stats_get_stdev(ps.stats);
496 cpl_msg_warning(cpl_func,
"Cannot calculate statistics iteratively");
500 freeimage(trim_raw1);
504 ps.result = cpl_table_new(1);
505 cpl_table_new_column(ps.result,
"MEAN", CPL_TYPE_DOUBLE);
506 cpl_table_new_column(ps.result,
"MEDIAN", CPL_TYPE_DOUBLE);
507 cpl_table_new_column(ps.result,
"STDEV", CPL_TYPE_DOUBLE);
508 cpl_table_set_double(ps.result,
"MEAN", 0, omega_qcheck_config.mean);
509 cpl_table_set_double(ps.result,
"MEDIAN", 0, omega_qcheck_config.median);
510 cpl_table_set_double(ps.result,
"STDEV", 0, omega_qcheck_config.stdev);
513 qclist = cpl_propertylist_new();
514 cpl_propertylist_append_double(qclist,
"ESO QC QUICK CHECK MEAN",
515 omega_qcheck_config.mean) ;
516 cpl_propertylist_set_comment(qclist,
"ESO QC QUICK CHECK MEAN",
"Mean of difference");
518 cpl_propertylist_append_double(qclist,
"ESO QC QUICK CHECK MEDIAN",
519 omega_qcheck_config.median) ;
520 cpl_propertylist_set_comment(qclist,
"ESO QC QUICK CHECK MEDIAN",
"Median of difference");
522 cpl_propertylist_append_double(qclist,
"ESO QC QUICK CHECK STDEV",
523 omega_qcheck_config.stdev) ;
524 cpl_propertylist_set_comment(qclist,
"ESO QC QUICK CHECK STDEV",
"Standard deviation of difference");
527 ps.proname = cpl_sprintf(
"%s_%s.fits", INSTRUME,LTEST_PROCATG);
532 alist=cpl_propertylist_load_regexp(cpl_frame_get_filename(frame1),j,
"EXTNAME",0);
533 if(
omega_save_table(ps.result,set,pars,alist,qclist,ps.proname,RECIPE,product_frame,
534 NULL,isfirst) == -1){
535 cpl_msg_error(cpl_func,
"Cannot save the product");
536 cpl_propertylist_delete(alist);
541 cpl_propertylist_delete(alist);
550 freetable(ps.result);
552 freefits(ps.domefits1);
566 static void omega_qcheck_init(
void) {
577 static void omega_qcheck_tidy(
void) {
578 freespace(ps.labels);
579 freeframeset(ps.domelist);
580 freefits(ps.domefits1);
582 freespace(ps.proname);
583 freetable(ps.result);
int omega_pfits_get_overscan(const cpl_frame *frame, int xn)
Get the DRS keyword of the overscan method used to reduce the image.
cpl_stats * omega_iter_stat_opts(cpl_image *img, cpl_vector *zone, double threshold, int iter)
Compute statistics of an image iteratively.
void omega_extensions(const cpl_frame *frame, int inexten, int *out1, int *out2)
int omega_save_table(const cpl_table *tbl, cpl_frameset *set, const cpl_parameterlist *pars, cpl_propertylist *alist, const cpl_propertylist *qclist, const char *name, const char *recipe, cpl_frame *frame, const cpl_frame *inherit, int isfirst)
Save a table as a DFS compliant product.
int omega_compare_tags(const cpl_frame *frame1, const cpl_frame *frame2)
int cpl_plugin_get_info(cpl_pluginlist *list)
Build the list of available plugins, for this module.
omega_fits * omega_fits_load(const cpl_frame *inframe, cpl_type type, int extnum)
cpl_image * omega_trim_oscan_correct(omega_fits *ofits, int oscan)
This method loads a raw image, trims it and (optionally) performs an overscan correction, using the statistics of the pre and overscan regions. This can be done with a single value for the whole image or on a per-row basis.
const char * omega_get_license(void)
Get the pipeline copyright and license.
cpl_frame * omega_product_frame(const char *filename, const char *tag, cpl_frame_type type)
Setup a frame to save a product.
cpl_frameset * omega_frameset_subgroup(cpl_frameset *frameset, cpl_size *labels, cpl_size nlab, const char *tag)