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 ((const char *)message != NULL) 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 ((const char *)message != NULL) 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 *dummy = NULL;
309 cpl_table *overscans = NULL;
311 cpl_propertylist *header = NULL;
312 cpl_propertylist *qclist = NULL;
318 const char *arc_tag =
"FLUX_ARC_LSS";
319 const char *flat_tag =
"FLUX_FLAT_LSS";
323 const char *exposure_tag;
324 const char *flux_tag =
"FLUX_LAMP_LSS";
331 double flux, flux_err;
334 char *instrume = NULL;
335 char *pipefile = NULL;
338 snprintf(version, 80,
"%s-%s", PACKAGE, PACKAGE_VERSION);
340 cpl_msg_set_indentation(2);
346 cpl_msg_info(recipe,
"Recipe %s configuration parameters:", recipe);
347 cpl_msg_indent_more();
354 if (cpl_error_get_code())
355 fors_sumflux_exit(
"Failure getting the configuration parameters");
357 if (xlow > xhig || ylow > yhig || xhig < 0 || yhig < 0)
358 fors_sumflux_exit(
"Invalid integration region");
365 cpl_msg_indent_less();
366 cpl_msg_info(recipe,
"Check input set-of-frames:");
367 cpl_msg_indent_more();
370 cpl_msg_warning(cpl_func,
"Input frames are not from the same chip");
372 nframes = cpl_frameset_count_tags(frameset, arc_tag)
373 + cpl_frameset_count_tags(frameset, flat_tag);
376 fors_sumflux_exit(
"Missing input LSS calibration exposures");
379 cpl_msg_error(recipe,
"Too many LSS calibration exposures found (%d). "
380 "Just one is required.", nframes);
381 fors_sumflux_exit(NULL);
384 if (cpl_frameset_count_tags(frameset, arc_tag) > 0)
385 exposure_tag = arc_tag;
387 exposure_tag = flat_tag;
406 cpl_msg_indent_less();
407 cpl_msg_info(recipe,
"Load %s frame...", exposure_tag);
408 cpl_msg_indent_more();
410 exposure =
dfs_load_image(frameset, exposure_tag, CPL_TYPE_FLOAT, 0, 0);
411 if (exposure == NULL)
412 fors_sumflux_exit(
"Cannot load input frame");
421 fors_sumflux_exit(
"Cannot load input frame header");
423 time = cpl_propertylist_get_double(header,
"EXPTIME");
425 if (cpl_error_get_code() != CPL_ERROR_NONE)
426 fors_sumflux_exit(
"Missing keyword EXPTIME in input frame header");
428 instrume = (
char *)cpl_propertylist_get_string(header,
"INSTRUME");
429 if (instrume == NULL)
430 fors_sumflux_exit(
"Missing keyword INSTRUME in input frame header");
431 instrume = cpl_strdup(instrume);
433 if (instrume[4] ==
'1')
434 snprintf(version, 80,
"%s/%s",
"fors1", VERSION);
435 if (instrume[4] ==
'2')
436 snprintf(version, 80,
"%s/%s",
"fors2", VERSION);
438 rebin = cpl_propertylist_get_int(header,
"ESO DET WIN1 BINX");
440 if (cpl_error_get_code() != CPL_ERROR_NONE)
441 fors_sumflux_exit(
"Missing keyword ESO DET WIN1 BINX in input "
444 rebin *= cpl_propertylist_get_int(header,
"ESO DET WIN1 BINY");
446 if (cpl_error_get_code() != CPL_ERROR_NONE)
447 fors_sumflux_exit(
"Missing keyword ESO DET WIN1 BINY in input "
452 "One readout pixel corresponds to %d chip pixels", rebin);
455 gain = cpl_propertylist_get_double(header,
"ESO DET OUT1 CONAD");
457 if (cpl_error_get_code() != CPL_ERROR_NONE)
458 fors_sumflux_exit(
"Missing keyword ESO DET OUT1 CONAD in arc lamp "
461 cpl_msg_info(recipe,
"The gain factor is: %.2f e-/ADU", gain);
471 switch (instrume[4]) {
474 cpl_msg_info(recipe,
"Remove low-flux region level...");
475 if (exposure_tag == flat_tag) {
476 overscans = cpl_table_new(2);
477 cpl_table_new_column(overscans,
"xlow", CPL_TYPE_INT);
478 cpl_table_new_column(overscans,
"ylow", CPL_TYPE_INT);
479 cpl_table_new_column(overscans,
"xhig", CPL_TYPE_INT);
480 cpl_table_new_column(overscans,
"yhig", CPL_TYPE_INT);
482 nx = cpl_image_get_size_x(exposure);
483 ny = cpl_image_get_size_y(exposure);
487 cpl_table_set_int(overscans,
"xlow", 0, 200);
488 cpl_table_set_int(overscans,
"ylow", 0, 0);
489 cpl_table_set_int(overscans,
"xhig", 0, nx);
490 cpl_table_set_int(overscans,
"yhig", 0, ny);
494 cpl_table_set_int(overscans,
"xlow", 1, 0);
495 cpl_table_set_int(overscans,
"ylow", 1, 0);
496 cpl_table_set_int(overscans,
"xhig", 1, 200);
497 cpl_table_set_int(overscans,
"yhig", 1, ny);
501 cpl_image_subtract(exposure, background);
502 cpl_image_delete(background);
505 cpl_msg_info(recipe,
"Remove bias, evaluated on overscan regions...");
510 cpl_msg_info(recipe,
"Remove bias, evaluated on overscan regions...");
514 cpl_msg_error(recipe,
"Invalid instrument name: %s", instrume);
515 fors_sumflux_exit(NULL);
520 cpl_table_delete(overscans); overscans = NULL;
521 cpl_image_delete(exposure); exposure = dummy;
523 if (exposure == NULL)
524 fors_sumflux_exit(
"Cannot remove bias from input frame");
527 nx = cpl_image_get_size_x(exposure);
528 ny = cpl_image_get_size_y(exposure);
536 if (xlow > nx || ylow > ny || xhig < 0 || yhig < 0)
537 fors_sumflux_exit(
"The integration region lays outside the CCD");
539 if (xlow == xhig || ylow == yhig)
540 fors_sumflux_exit(
"The integration area is zero");
542 norm_factor = rebin * time * (xhig - xlow) * (yhig - ylow);
544 flux = cpl_image_get_flux(exposure);
546 flux_err = sqrt(flux/gain);
554 flux_err /= norm_factor;
556 cpl_msg_info(recipe,
"Flux: %.4f +/- %.4f (ADU/s*pixel)", flux, flux_err);
558 cpl_image_divide_scalar(exposure, norm_factor);
567 qclist = cpl_propertylist_new();
572 "Product category", instrume))
573 fors_sumflux_exit(
"Cannot write product category to QC log file");
576 "DPR type", instrume))
577 fors_sumflux_exit(
"Missing keyword DPR TYPE in frame header");
580 "Template", instrume))
581 fors_sumflux_exit(
"Missing keyword TPL ID in frame header");
584 "Grism name", instrume))
585 fors_sumflux_exit(
"Missing keyword INS GRIS1 NAME in frame header");
588 "Grim identifier", instrume))
589 fors_sumflux_exit(
"Missing keyword INS GRIS1 ID in frame header");
591 if (cpl_propertylist_has(header,
"ESO INS FILT1 NAME"))
593 "Filter name", instrume);
596 "Collimator name", instrume))
597 fors_sumflux_exit(
"Missing keyword INS COLL NAME in frame header");
600 "Chip identifier", instrume))
601 fors_sumflux_exit(
"Missing keyword DET CHIP1 ID in frame header");
604 "arcsec",
"Slit width", instrume))
605 fors_sumflux_exit(
"Missing keyword ESO INS SLIT WID in frame header");
608 "Conversion from ADUs to electrons", instrume))
609 fors_sumflux_exit(
"Missing keyword ESO DET OUT1 CONAD in frame header");
612 "Binning factor along X", instrume))
613 fors_sumflux_exit(
"Missing keyword ESO DET WIN1 BINX in frame header");
616 "Binning factor along Y", instrume))
617 fors_sumflux_exit(
"Missing keyword ESO DET WIN1 BINY in frame header");
619 for (i = 1; i < 7; i++) {
620 snprintf(lamp, 20,
"ESO INS LAMP%d NAME", i);
621 if (cpl_propertylist_has(header, lamp))
623 "Name of lamp on", instrume);
627 "Archive name of input data", instrume))
628 fors_sumflux_exit(
"Missing keyword ARCFILE in frame header");
630 cpl_propertylist_delete(header); header = NULL;
632 pipefile = dfs_generate_filename(flux_tag);
634 "Pipeline product name", instrume))
635 fors_sumflux_exit(
"Cannot write PIPEFILE to QC log file");
636 cpl_free(pipefile); pipefile = NULL;
644 "Total lamp flux", instrume)) {
645 fors_sumflux_exit(
"Cannot write total lamp flux to QC log file");
650 "Error on lamp flux", instrume)) {
651 fors_sumflux_exit(
"Cannot write error on lamp flux to QC log file");
656 cpl_free(instrume); instrume = NULL;
659 parlist, recipe, version))
660 fors_sumflux_exit(NULL);
662 cpl_image_delete(exposure); exposure = NULL;
663 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.