38 static int fors_sumflux_create(cpl_plugin *);
39 static int fors_sumflux_exec(cpl_plugin *);
40 static int fors_sumflux_destroy(cpl_plugin *);
41 static int fors_sumflux(cpl_parameterlist *, cpl_frameset *);
43 static char fors_sumflux_description[] =
44 "This recipe is used to monitor any lamp flux on the CCD. The input raw\n"
45 "image should be either a FLUX_ARC_LSS or a FLUX_FLAT_LSS frame. After the\n"
46 "background subtraction the total signal is integrated and divided by the\n"
47 "exposure time and by the total number of CCD original pixels (keeping\n"
48 "into account a possible rebinned readout). In the case of FORS2 frames\n"
49 "the background is the median level evaluated from the available overscan\n"
50 "regions. In the case of FORS1 data, where overscan regions are missing,\n"
51 "the background is evaluated as the median level of the first 200 CCD columns\n"
52 "for flat field data, while for arc lamp data a background map evaluated\n"
53 "from the regions without spectral lines is computed and subtracted. The\n"
54 "background subtracted frame is written to output in all cases, and the QC\n"
55 "parameters QC LAMP FLUX and QC LAMP FLUXERR are computed.\n\n"
57 " DO category: Type: Explanation: Required:\n"
58 " FLUX_FLAT_LSS Raw Flat field exposure Y\n"
59 " or FLUX_ARC_LSS Raw Arc lamp exposure Y\n\n"
61 " DO category: Data type: Explanation:\n"
62 " FLUX_LAMP_LSS FITS image Background subtracted integration region\n\n";
64 #define fors_sumflux_exit(message) \
66 if (message) cpl_msg_error(recipe, message); \
69 cpl_image_delete(master_bias); \
70 cpl_image_delete(exposure); \
71 cpl_propertylist_delete(header); \
72 cpl_propertylist_delete(qclist); \
73 cpl_table_delete(overscans); \
74 cpl_msg_indent_less(); \
78 #define fors_sumflux_exit_memcheck(message) \
80 if (message) cpl_msg_info(recipe, message); \
83 cpl_image_delete(master_bias); \
84 cpl_image_delete(exposure); \
85 cpl_propertylist_delete(header); \
86 cpl_propertylist_delete(qclist); \
87 cpl_table_delete(overscans); \
88 cpl_msg_indent_less(); \
106 cpl_recipe *recipe = cpl_calloc(1,
sizeof *recipe );
107 cpl_plugin *plugin = &recipe->interface;
109 cpl_plugin_init(plugin,
112 CPL_PLUGIN_TYPE_RECIPE,
114 "Integrate flux from all or part of the input frame",
115 fors_sumflux_description,
118 "This file is currently part of the FORS Instrument Pipeline\n"
119 "Copyright (C) 2002-2010 European Southern Observatory\n\n"
120 "This program is free software; you can redistribute it and/or modify\n"
121 "it under the terms of the GNU General Public License as published by\n"
122 "the Free Software Foundation; either version 2 of the License, or\n"
123 "(at your option) any later version.\n\n"
124 "This program is distributed in the hope that it will be useful,\n"
125 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
126 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
127 "GNU General Public License for more details.\n\n"
128 "You should have received a copy of the GNU General Public License\n"
129 "along with this program; if not, write to the Free Software Foundation,\n"
130 "Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n",
133 fors_sumflux_destroy);
135 cpl_pluginlist_append(list, plugin);
151 static int fors_sumflux_create(cpl_plugin *plugin)
161 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
162 recipe = (cpl_recipe *)plugin;
170 recipe->parameters = cpl_parameterlist_new();
177 p = cpl_parameter_new_value(
"fors.fors_sumflux.xlow",
179 "X coordinate of lower left corner "
180 "of integration region (pixel)",
183 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"xlow");
184 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
185 cpl_parameterlist_append(recipe->parameters, p);
191 p = cpl_parameter_new_value(
"fors.fors_sumflux.ylow",
193 "Y coordinate of lower left corner "
194 "of integration region (pixel)",
197 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"ylow");
198 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
199 cpl_parameterlist_append(recipe->parameters, p);
205 p = cpl_parameter_new_value(
"fors.fors_sumflux.xhigh",
207 "X coordinate of upper right corner "
208 "of integration region (pixel) (0 = CCD size)",
211 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"xhigh");
212 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
213 cpl_parameterlist_append(recipe->parameters, p);
219 p = cpl_parameter_new_value(
"fors.fors_sumflux.yhigh",
221 "Y coordinate of upper right corner "
222 "of integration region (pixel) (0 = CCD size)",
225 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"yhigh");
226 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
227 cpl_parameterlist_append(recipe->parameters, p);
241 static int fors_sumflux_exec(cpl_plugin *plugin)
245 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
246 recipe = (cpl_recipe *)plugin;
250 return fors_sumflux(recipe->parameters, recipe->frames);
262 static int fors_sumflux_destroy(cpl_plugin *plugin)
266 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
267 recipe = (cpl_recipe *)plugin;
271 cpl_parameterlist_delete(recipe->parameters);
286 static int fors_sumflux(cpl_parameterlist *parlist, cpl_frameset *frameset)
289 const char *recipe =
"fors_sumflux";
305 cpl_image *master_bias = NULL;
306 cpl_image *exposure = NULL;
307 cpl_image *background = NULL;
308 cpl_image *dummy = NULL;
310 cpl_table *overscans = NULL;
312 cpl_propertylist *header = NULL;
313 cpl_propertylist *qclist = NULL;
319 const char *arc_tag =
"FLUX_ARC_LSS";
320 const char *flat_tag =
"FLUX_FLAT_LSS";
324 const char *exposure_tag;
325 const char *flux_tag =
"FLUX_LAMP_LSS";
332 double flux, flux_err;
335 char *instrume = NULL;
336 char *pipefile = NULL;
339 snprintf(version, 80,
"%s-%s", PACKAGE, PACKAGE_VERSION);
341 cpl_msg_set_indentation(2);
347 cpl_msg_info(recipe,
"Recipe %s configuration parameters:", recipe);
348 cpl_msg_indent_more();
355 if (cpl_error_get_code())
356 fors_sumflux_exit(
"Failure getting the configuration parameters");
358 if (xlow > xhig || ylow > yhig || xhig < 0 || yhig < 0)
359 fors_sumflux_exit(
"Invalid integration region");
366 cpl_msg_indent_less();
367 cpl_msg_info(recipe,
"Check input set-of-frames:");
368 cpl_msg_indent_more();
371 fors_sumflux_exit(
"Input frames are not from the same chip");
373 nframes = cpl_frameset_count_tags(frameset, arc_tag)
374 + cpl_frameset_count_tags(frameset, flat_tag);
377 fors_sumflux_exit(
"Missing input LSS calibration exposures");
380 cpl_msg_error(recipe,
"Too many LSS calibration exposures found (%d). "
381 "Just one is required.", nframes);
382 fors_sumflux_exit(NULL);
385 if (cpl_frameset_count_tags(frameset, arc_tag) > 0)
386 exposure_tag = arc_tag;
388 exposure_tag = flat_tag;
407 cpl_msg_indent_less();
408 cpl_msg_info(recipe,
"Load %s frame...", exposure_tag);
409 cpl_msg_indent_more();
411 exposure =
dfs_load_image(frameset, exposure_tag, CPL_TYPE_FLOAT, 0, 0);
412 if (exposure == NULL)
413 fors_sumflux_exit(
"Cannot load input frame");
422 fors_sumflux_exit(
"Cannot load input frame header");
424 time = cpl_propertylist_get_double(header,
"EXPTIME");
426 if (cpl_error_get_code() != CPL_ERROR_NONE)
427 fors_sumflux_exit(
"Missing keyword EXPTIME in input frame header");
429 instrume = (
char *)cpl_propertylist_get_string(header,
"INSTRUME");
430 if (instrume == NULL)
431 fors_sumflux_exit(
"Missing keyword INSTRUME in input frame header");
432 instrume = cpl_strdup(instrume);
434 if (instrume[4] ==
'1')
435 snprintf(version, 80,
"%s/%s",
"fors1", VERSION);
436 if (instrume[4] ==
'2')
437 snprintf(version, 80,
"%s/%s",
"fors2", VERSION);
439 rebin = cpl_propertylist_get_int(header,
"ESO DET WIN1 BINX");
441 if (cpl_error_get_code() != CPL_ERROR_NONE)
442 fors_sumflux_exit(
"Missing keyword ESO DET WIN1 BINX in input "
445 rebin *= cpl_propertylist_get_int(header,
"ESO DET WIN1 BINY");
447 if (cpl_error_get_code() != CPL_ERROR_NONE)
448 fors_sumflux_exit(
"Missing keyword ESO DET WIN1 BINY in input "
453 "One readout pixel corresponds to %d chip pixels", rebin);
456 gain = cpl_propertylist_get_double(header,
"ESO DET OUT1 CONAD");
458 if (cpl_error_get_code() != CPL_ERROR_NONE)
459 fors_sumflux_exit(
"Missing keyword ESO DET OUT1 CONAD in arc lamp "
462 cpl_msg_info(recipe,
"The gain factor is: %.2f e-/ADU", gain);
472 switch (instrume[4]) {
475 cpl_msg_info(recipe,
"Remove low-flux region level...");
476 if (exposure_tag == flat_tag) {
477 overscans = cpl_table_new(2);
478 cpl_table_new_column(overscans,
"xlow", CPL_TYPE_INT);
479 cpl_table_new_column(overscans,
"ylow", CPL_TYPE_INT);
480 cpl_table_new_column(overscans,
"xhig", CPL_TYPE_INT);
481 cpl_table_new_column(overscans,
"yhig", CPL_TYPE_INT);
483 nx = cpl_image_get_size_x(exposure);
484 ny = cpl_image_get_size_y(exposure);
488 cpl_table_set_int(overscans,
"xlow", 0, 200);
489 cpl_table_set_int(overscans,
"ylow", 0, 0);
490 cpl_table_set_int(overscans,
"xhig", 0, nx);
491 cpl_table_set_int(overscans,
"yhig", 0, ny);
495 cpl_table_set_int(overscans,
"xlow", 1, 0);
496 cpl_table_set_int(overscans,
"ylow", 1, 0);
497 cpl_table_set_int(overscans,
"xhig", 1, 200);
498 cpl_table_set_int(overscans,
"yhig", 1, ny);
502 cpl_image_subtract(exposure, background);
503 cpl_image_delete(background);
506 cpl_msg_info(recipe,
"Remove bias, evaluated on overscan regions...");
511 cpl_msg_info(recipe,
"Remove bias, evaluated on overscan regions...");
515 cpl_msg_error(recipe,
"Invalid instrument name: %s", instrume);
516 fors_sumflux_exit(NULL);
521 cpl_table_delete(overscans); overscans = NULL;
522 cpl_image_delete(exposure); exposure = dummy;
524 if (exposure == NULL)
525 fors_sumflux_exit(
"Cannot remove bias from input frame");
528 nx = cpl_image_get_size_x(exposure);
529 ny = cpl_image_get_size_y(exposure);
537 if (xlow > nx || ylow > ny || xhig < 0 || yhig < 0)
538 fors_sumflux_exit(
"The integration region lays outside the CCD");
540 if (xlow == xhig || ylow == yhig)
541 fors_sumflux_exit(
"The integration area is zero");
543 norm_factor = rebin * time * (xhig - xlow) * (yhig - ylow);
545 flux = cpl_image_get_flux(exposure);
547 flux_err = sqrt(flux/gain);
555 flux_err /= norm_factor;
557 cpl_msg_info(recipe,
"Flux: %.4f +/- %.4f (ADU/s*pixel)", flux, flux_err);
559 cpl_image_divide_scalar(exposure, norm_factor);
568 qclist = cpl_propertylist_new();
573 "Product category", instrume))
574 fors_sumflux_exit(
"Cannot write product category to QC log file");
577 "DPR type", instrume))
578 fors_sumflux_exit(
"Missing keyword DPR TYPE in frame header");
581 "Template", instrume))
582 fors_sumflux_exit(
"Missing keyword TPL ID in frame header");
585 "Grism name", instrume))
586 fors_sumflux_exit(
"Missing keyword INS GRIS1 NAME in frame header");
589 "Grim identifier", instrume))
590 fors_sumflux_exit(
"Missing keyword INS GRIS1 ID in frame header");
592 if (cpl_propertylist_has(header,
"ESO INS FILT1 NAME"))
594 "Filter name", instrume);
597 "Collimator name", instrume))
598 fors_sumflux_exit(
"Missing keyword INS COLL NAME in frame header");
601 "Chip identifier", instrume))
602 fors_sumflux_exit(
"Missing keyword DET CHIP1 ID in frame header");
605 "arcsec",
"Slit width", instrume))
606 fors_sumflux_exit(
"Missing keyword ESO INS SLIT WID in frame header");
609 "Conversion from ADUs to electrons", instrume))
610 fors_sumflux_exit(
"Missing keyword ESO DET OUT1 CONAD in frame header");
613 "Binning factor along X", instrume))
614 fors_sumflux_exit(
"Missing keyword ESO DET WIN1 BINX in frame header");
617 "Binning factor along Y", instrume))
618 fors_sumflux_exit(
"Missing keyword ESO DET WIN1 BINY in frame header");
620 for (i = 1; i < 7; i++) {
621 snprintf(lamp, 20,
"ESO INS LAMP%d NAME", i);
622 if (cpl_propertylist_has(header, lamp))
624 "Name of lamp on", instrume);
628 "Archive name of input data", instrume))
629 fors_sumflux_exit(
"Missing keyword ARCFILE in frame header");
631 cpl_propertylist_delete(header); header = NULL;
633 pipefile = dfs_generate_filename(flux_tag);
635 "Pipeline product name", instrume))
636 fors_sumflux_exit(
"Cannot write PIPEFILE to QC log file");
637 cpl_free(pipefile); pipefile = NULL;
645 "Total lamp flux", instrume)) {
646 fors_sumflux_exit(
"Cannot write total lamp flux to QC log file");
651 "Error on lamp flux", instrume)) {
652 fors_sumflux_exit(
"Cannot write error on lamp flux to QC log file");
657 cpl_free(instrume); instrume = NULL;
660 parlist, recipe, version))
661 fors_sumflux_exit(NULL);
663 cpl_image_delete(exposure); exposure = NULL;
664 cpl_propertylist_delete(qclist); qclist = NULL;
int cpl_plugin_get_info(cpl_pluginlist *list)
Build the list of available plugins, for this module.
cpl_image * dfs_load_image(cpl_frameset *frameset, const char *category, cpl_type type, int ext, int calib)
Loading image data of given category.
cpl_propertylist * dfs_load_header(cpl_frameset *frameset, const char *category, int ext)
Loading header associated to data of given category.
cpl_error_code fors_qc_write_qc_double(cpl_propertylist *header, double value, const char *name, const char *unit, const char *comment, const char *instrument)
Write an integer value to the active QC1 PAF object and to a header.
cpl_error_code fors_qc_keyword_to_paf(cpl_propertylist *header, const char *name, const char *unit, const char *comment, const char *instrument)
Copy a keyword value to the currently active QC1 PAF object.
cpl_error_code fors_qc_start_group(cpl_propertylist *header, const char *qcdic_version, const char *instrument)
Initiate a new QC1 group.
cpl_image * mos_remove_bias(cpl_image *image, cpl_image *bias, cpl_table *overscans)
Subtract the bias from a CCD exposure.
cpl_error_code fors_qc_write_string(const char *name, const char *value, const char *comment, const char *instrument)
Add string parameter to current QC1 group.
int dfs_equal_keyword(cpl_frameset *frameset, const char *keyword)
Saving table data of given category.
int dfs_save_image(cpl_frameset *frameset, const cpl_image *image, const char *category, cpl_propertylist *header, const cpl_parameterlist *parlist, const char *recipename, const char *version)
Saving image data of given category.
int dfs_get_parameter_int(cpl_parameterlist *parlist, const char *name, const cpl_table *defaults)
Reading a recipe integer parameter value.
cpl_error_code fors_qc_end_group(void)
Close current QC1 PAF file.
cpl_image * mos_arc_background(cpl_image *image, int msize, int fsize)
Background determination on emission line spectrum (arc)
cpl_table * mos_load_overscans_vimos(const cpl_propertylist *header, int check_consistency)
Get the overscan positions from FITS header of VIMOS data.