37 static int fors_wave_calib_create(cpl_plugin *);
38 static int fors_wave_calib_exec(cpl_plugin *);
39 static int fors_wave_calib_destroy(cpl_plugin *);
40 static int fors_wave_calib(cpl_parameterlist *, cpl_frameset *);
42 static char fors_wave_calib_description[] =
43 "This recipe is used to wavelength calibrate MOS/MXU slit spectra contained\n"
44 "in the rectified arc lamp exposure produced with recipe fors_extract_slits.\n"
45 "A pattern-matching algorithm is applied as in recipe fors_detect_spectra.\n"
46 "The input spatial map is used in the production of the wavelength map.\n"
48 "Use recipe fors_wave_calib_lss for LSS data, or for MOS/MXU data where all\n"
49 "slits have the same offset. For more details on this data reduction strategy\n"
50 "please refer to the FORS Pipeline User's Manual.\n"
52 "Note that specifying an input GRISM_TABLE will set some of the recipe\n"
53 "configuration parameters to default values valid for a particular grism.\n"
55 "In the table below the MXU acronym can be alternatively read as MOS.\n\n"
57 " DO category: Type: Explanation: Required:\n"
58 " SPATIAL_MAP_MXU Calib Spatial map Y\n"
59 " RECTIFIED_LAMP_MXU Calib Rectified arc exposure Y\n"
60 " SLIT_LOCATION_MXU Calib Slit location table Y\n"
61 " CURV_COEFF_MXU Calib Spectral curvature Y\n"
62 " MASTER_LINECAT Calib Line catalog Y\n"
63 " GRISM_TABLE Calib Grism table .\n\n"
65 " DO category: Data type: Explanation:\n"
66 " REDUCED_LAMP_MXU FITS image Calibrated arc lamp exposure\n"
67 " DISP_COEFF_MXU FITS table Inverse dispersion coefficients\n"
68 " DISP_RESIDUALS_MXU FITS image Image of modeling residuals\n"
69 " WAVELENGTH_MAP_MXU FITS image Wavelengths mapped on CCD\n"
70 " SPECTRAL_RESOLUTION_MXU FITS table Spectral resolution table\n\n";
72 #define fors_wave_calib_exit(message) \
74 if ((const char *)message != NULL) cpl_msg_error(recipe, message); \
75 cpl_image_delete(spectra); \
76 cpl_image_delete(spatial); \
77 cpl_image_delete(rainbow); \
78 cpl_image_delete(residual); \
79 cpl_image_delete(rectified); \
80 cpl_image_delete(wavemap); \
81 cpl_table_delete(grism_table); \
82 cpl_table_delete(wavelengths); \
83 cpl_table_delete(maskslits); \
84 cpl_table_delete(idscoeff); \
85 cpl_table_delete(restab); \
86 cpl_table_delete(slits); \
87 cpl_table_delete(polytraces); \
88 cpl_vector_delete(lines); \
89 cpl_propertylist_delete(header); \
90 cpl_propertylist_delete(save_header); \
91 cpl_msg_indent_less(); \
95 #define fors_wave_calib_exit_memcheck(message) \
97 if ((const char *)message != NULL) cpl_msg_info(recipe, message); \
98 printf("free spectra (%p)\n", spectra); \
99 cpl_image_delete(spectra); \
100 printf("free spatial (%p)\n", spatial); \
101 cpl_image_delete(spatial); \
102 printf("free rainbow (%p)\n", rainbow); \
103 cpl_image_delete(rainbow); \
104 printf("free residual (%p)\n", residual); \
105 cpl_image_delete(residual); \
106 printf("free rectified (%p)\n", rectified); \
107 cpl_image_delete(rectified); \
108 printf("free wavemap (%p)\n", wavemap); \
109 cpl_image_delete(wavemap); \
110 printf("free grism_table (%p)\n", grism_table); \
111 cpl_table_delete(grism_table); \
112 printf("free wavelengths (%p)\n", wavelengths); \
113 cpl_table_delete(wavelengths); \
114 printf("free maskslits (%p)\n", maskslits); \
115 cpl_table_delete(maskslits); \
116 printf("free idscoeff (%p)\n", idscoeff); \
117 cpl_table_delete(idscoeff); \
118 printf("free restab (%p)\n", restab); \
119 cpl_table_delete(restab); \
120 printf("free slits (%p)\n", slits); \
121 cpl_table_delete(slits); \
122 printf("free polytraces (%p)\n", polytraces); \
123 cpl_table_delete(polytraces); \
124 printf("free lines (%p)\n", lines); \
125 cpl_vector_delete(lines); \
126 printf("free header (%p)\n", header); \
127 cpl_propertylist_delete(header); \
128 printf("free save_header (%p)\n", save_header); \
129 cpl_propertylist_delete(save_header); \
130 cpl_msg_indent_less(); \
148 cpl_recipe *recipe = cpl_calloc(1,
sizeof *recipe );
149 cpl_plugin *plugin = &recipe->interface;
151 cpl_plugin_init(plugin,
154 CPL_PLUGIN_TYPE_RECIPE,
156 "Derive dispersion relation from rectified arc lamp frame",
157 fors_wave_calib_description,
160 "This file is currently part of the FORS Instrument Pipeline\n"
161 "Copyright (C) 2002-2010 European Southern Observatory\n\n"
162 "This program is free software; you can redistribute it and/or modify\n"
163 "it under the terms of the GNU General Public License as published by\n"
164 "the Free Software Foundation; either version 2 of the License, or\n"
165 "(at your option) any later version.\n\n"
166 "This program is distributed in the hope that it will be useful,\n"
167 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
168 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
169 "GNU General Public License for more details.\n\n"
170 "You should have received a copy of the GNU General Public License\n"
171 "along with this program; if not, write to the Free Software Foundation,\n"
172 "Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n",
173 fors_wave_calib_create,
174 fors_wave_calib_exec,
175 fors_wave_calib_destroy);
177 cpl_pluginlist_append(list, plugin);
193 static int fors_wave_calib_create(cpl_plugin *plugin)
202 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
203 recipe = (cpl_recipe *)plugin;
211 recipe->parameters = cpl_parameterlist_new();
217 p = cpl_parameter_new_value(
"fors.fors_wave_calib.dispersion",
219 "Expected spectral dispersion (Angstrom/pixel)",
220 "fors.fors_wave_calib",
222 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"dispersion");
223 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
224 cpl_parameterlist_append(recipe->parameters, p);
230 p = cpl_parameter_new_value(
"fors.fors_wave_calib.peakdetection",
232 "Initial peak detection threshold (ADU)",
233 "fors.fors_wave_calib",
235 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"peakdetection");
236 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
237 cpl_parameterlist_append(recipe->parameters, p);
243 p = cpl_parameter_new_value(
"fors.fors_wave_calib.wdegree",
245 "Degree of wavelength calibration polynomial",
246 "fors.fors_wave_calib",
248 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"wdegree");
249 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
250 cpl_parameterlist_append(recipe->parameters, p);
256 p = cpl_parameter_new_value(
"fors.fors_wave_calib.wradius",
258 "Search radius if iterating pattern-matching "
259 "with first-guess method",
260 "fors.fors_wave_calib",
262 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"wradius");
263 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
264 cpl_parameterlist_append(recipe->parameters, p);
270 p = cpl_parameter_new_value(
"fors.fors_wave_calib.wreject",
272 "Rejection threshold in dispersion "
273 "relation fit (pixel)",
274 "fors.fors_wave_calib",
276 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"wreject");
277 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
278 cpl_parameterlist_append(recipe->parameters, p);
284 p = cpl_parameter_new_value(
"fors.fors_wave_calib.wcolumn",
286 "Name of line catalog table column "
288 "fors.fors_wave_calib",
290 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"wcolumn");
291 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
292 cpl_parameterlist_append(recipe->parameters, p);
298 p = cpl_parameter_new_value(
"fors.fors_wave_calib.startwavelength",
300 "Start wavelength in spectral extraction",
301 "fors.fors_wave_calib",
303 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"startwavelength");
304 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
305 cpl_parameterlist_append(recipe->parameters, p);
311 p = cpl_parameter_new_value(
"fors.fors_wave_calib.endwavelength",
313 "End wavelength in spectral extraction",
314 "fors.fors_wave_calib",
316 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"endwavelength");
317 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
318 cpl_parameterlist_append(recipe->parameters, p);
332 static int fors_wave_calib_exec(cpl_plugin *plugin)
336 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
337 recipe = (cpl_recipe *)plugin;
341 return fors_wave_calib(recipe->parameters, recipe->frames);
353 static int fors_wave_calib_destroy(cpl_plugin *plugin)
357 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
358 recipe = (cpl_recipe *)plugin;
362 cpl_parameterlist_delete(recipe->parameters);
377 static int fors_wave_calib(cpl_parameterlist *parlist,
378 cpl_frameset *frameset)
381 const char *recipe =
"fors_wave_calib";
389 double peakdetection;
394 double startwavelength;
395 double endwavelength;
401 cpl_image *spectra = NULL;
402 cpl_image *spatial = NULL;
403 cpl_image *rectified = NULL;
404 cpl_image *wavemap = NULL;
405 cpl_image *rainbow = NULL;
406 cpl_image *residual = NULL;
407 cpl_image *bimage = NULL;
408 cpl_table *grism_table = NULL;
409 cpl_table *wavelengths = NULL;
410 cpl_table *slits = NULL;
411 cpl_table *polytraces = NULL;
412 cpl_table *idscoeff = NULL;
413 cpl_table *maskslits = NULL;
414 cpl_table *restab = NULL;
415 cpl_vector *lines = NULL;
416 cpl_propertylist *header = NULL;
417 cpl_propertylist *save_header = NULL;
425 const char *reduced_lamp_tag;
426 const char *wavelength_map_tag;
427 const char *spatial_map_tag;
428 const char *disp_residuals_tag;
429 const char *disp_coeff_tag;
430 const char *curv_coeff_tag;
431 const char *slit_location_tag;
432 const char *spectral_resolution_tag;
436 int treat_as_lss = 0;
443 double *fiterror = NULL;
444 int *fitlines = NULL;
448 int nslits_out_det = 0;
451 char *instrume = NULL;
454 cpl_msg_set_indentation(2);
460 cpl_msg_info(recipe,
"Recipe %s configuration parameters:", recipe);
461 cpl_msg_indent_more();
463 if (cpl_frameset_count_tags(frameset,
"GRISM_TABLE") > 1)
464 fors_wave_calib_exit(
"Too many in input: GRISM_TABLE");
469 "fors.fors_wave_calib.dispersion", grism_table);
471 if (dispersion <= 0.0)
472 fors_wave_calib_exit(
"Invalid spectral dispersion value");
475 "fors.fors_wave_calib.peakdetection", grism_table);
476 if (peakdetection <= 0.0)
477 fors_wave_calib_exit(
"Invalid peak detection level");
480 "fors.fors_wave_calib.wdegree", grism_table);
483 fors_wave_calib_exit(
"Invalid polynomial degree");
486 fors_wave_calib_exit(
"Max allowed polynomial degree is 5");
489 "fors.fors_wave_calib.wradius", NULL);
492 fors_wave_calib_exit(
"Invalid search radius");
495 "fors.fors_wave_calib.wreject", NULL);
498 fors_wave_calib_exit(
"Invalid rejection threshold");
501 "fors.fors_wave_calib.wcolumn", NULL);
504 "fors.fors_wave_calib.startwavelength", grism_table);
505 if (startwavelength > 1.0)
506 if (startwavelength < 3000.0 || startwavelength > 13000.0)
507 fors_wave_calib_exit(
"Invalid wavelength");
510 "fors.fors_wave_calib.endwavelength", grism_table);
511 if (endwavelength > 1.0) {
512 if (endwavelength < 3000.0 || endwavelength > 13000.0)
513 fors_wave_calib_exit(
"Invalid wavelength");
514 if (startwavelength < 1.0)
515 fors_wave_calib_exit(
"Invalid wavelength interval");
518 if (startwavelength > 1.0)
519 if (endwavelength - startwavelength <= 0.0)
520 fors_wave_calib_exit(
"Invalid wavelength interval");
522 cpl_table_delete(grism_table); grism_table = NULL;
524 if (cpl_error_get_code())
525 fors_wave_calib_exit(
"Failure reading the configuration parameters");
528 cpl_msg_indent_less();
529 cpl_msg_info(recipe,
"Check input set-of-frames:");
530 cpl_msg_indent_more();
532 if (cpl_frameset_count_tags(frameset,
"MASTER_LINECAT") == 0)
533 fors_wave_calib_exit(
"Missing required input: MASTER_LINECAT");
535 if (cpl_frameset_count_tags(frameset,
"MASTER_LINECAT") > 1)
536 fors_wave_calib_exit(
"Too many in input: MASTER_LINECAT");
538 lamp_mxu = cpl_frameset_count_tags(frameset,
"RECTIFIED_LAMP_MXU");
539 lamp_mos = cpl_frameset_count_tags(frameset,
"RECTIFIED_LAMP_MOS");
541 narc = lamp_mxu + lamp_mos;
544 fors_wave_calib_exit(
"Missing input rectified arc lamp frame");
547 cpl_msg_error(recipe,
"Too many input rectified arc lamp frames "
549 fors_wave_calib_exit(NULL);
555 arc_tag =
"RECTIFIED_LAMP_MXU";
556 slit_location_tag =
"SLIT_LOCATION_MXU";
557 spatial_map_tag =
"SPATIAL_MAP_MXU";
558 reduced_lamp_tag =
"REDUCED_LAMP_MXU";
559 disp_residuals_tag =
"DISP_RESIDUALS_MXU";
560 disp_coeff_tag =
"DISP_COEFF_MXU";
561 curv_coeff_tag =
"CURV_COEFF_MXU";
562 wavelength_map_tag =
"WAVELENGTH_MAP_MXU";
563 spectral_resolution_tag =
"SPECTRAL_RESOLUTION_MXU";
567 arc_tag =
"RECTIFIED_LAMP_MOS";
568 slit_location_tag =
"SLIT_LOCATION_MOS";
569 spatial_map_tag =
"SPATIAL_MAP_MOS";
570 reduced_lamp_tag =
"REDUCED_LAMP_MOS";
571 disp_residuals_tag =
"DISP_RESIDUALS_MOS";
572 disp_coeff_tag =
"DISP_COEFF_MOS";
573 curv_coeff_tag =
"CURV_COEFF_MXU";
574 wavelength_map_tag =
"WAVELENGTH_MAP_MOS";
575 spectral_resolution_tag =
"SPECTRAL_RESOLUTION_MOS";
579 nref = cpl_frameset_count_tags(frameset, spatial_map_tag);
582 fors_wave_calib_exit(
"Missing input spatial map");
585 cpl_msg_error(recipe,
"Too many input spatial maps (%d > 1)", nref);
586 fors_wave_calib_exit(NULL);
589 nref = cpl_frameset_count_tags(frameset, slit_location_tag);
592 fors_wave_calib_exit(
"Missing input slit location table");
595 cpl_msg_error(recipe,
"Too many input slit location tables (%d > 1)",
597 fors_wave_calib_exit(NULL);
600 nref = cpl_frameset_count_tags(frameset, curv_coeff_tag);
603 fors_wave_calib_exit(
"Missing input spectral curvature table");
606 cpl_msg_error(recipe,
"Too many input spectral curvature tables "
608 fors_wave_calib_exit(NULL);
613 cpl_msg_warning(cpl_func,
"Input frames are not from the same grism");
616 cpl_msg_warning(cpl_func,
"Input frames are not from the same filter");
619 cpl_msg_warning(cpl_func,
"Input frames are not from the same chip");
630 fors_wave_calib_exit(
"Cannot load arc lamp header");
632 instrume = (
char *)cpl_propertylist_get_string(header,
"INSTRUME");
633 if (instrume == NULL)
634 fors_wave_calib_exit(
"Missing keyword INSTRUME in arc lamp header");
636 if (instrume[4] ==
'1')
637 snprintf(version, 80,
"%s/%s",
"fors1", VERSION);
638 if (instrume[4] ==
'2')
639 snprintf(version, 80,
"%s/%s",
"fors2", VERSION);
641 reference = cpl_propertylist_get_double(header,
"ESO INS GRIS1 WLEN");
643 if (cpl_error_get_code() != CPL_ERROR_NONE)
644 fors_wave_calib_exit(
"Missing keyword ESO INS GRIS1 WLEN "
645 "in arc lamp frame header");
647 if (reference < 3000.0)
650 if (reference < 3000.0 || reference > 13000.0) {
651 cpl_msg_error(recipe,
"Invalid central wavelength %.2f read from "
652 "keyword ESO INS GRIS1 WLEN in arc lamp frame header",
654 fors_wave_calib_exit(NULL);
657 cpl_msg_info(recipe,
"The central wavelength is: %.2f", reference);
659 rebin = cpl_propertylist_get_int(header,
"ESO DET WIN1 BINX");
661 if (cpl_error_get_code() != CPL_ERROR_NONE)
662 fors_wave_calib_exit(
"Missing keyword ESO DET WIN1 BINX "
663 "in arc lamp frame header");
667 cpl_msg_warning(recipe,
"The rebin factor is %d, and therefore the "
668 "working dispersion used is %f A/pixel", rebin,
673 cpl_msg_info(recipe,
"Produce mask slit position table...");
686 treat_as_lss = fors_mos_is_lss_like(maskslits, nslits_out_det);
688 cpl_table_delete(maskslits); maskslits = NULL;
691 cpl_msg_error(recipe,
"All slits have the same offset: %.2f mm\n"
692 "The LSS data reduction strategy must be applied: "
693 "please use recipe fors_wave_calib_lss", mxpos);
694 fors_wave_calib_exit(NULL);
698 cpl_msg_indent_less();
699 cpl_msg_info(recipe,
"Load arc lamp exposure...");
700 cpl_msg_indent_more();
702 spectra =
dfs_load_image(frameset, arc_tag, CPL_TYPE_FLOAT, 0, 0);
705 fors_wave_calib_exit(
"Cannot load arc lamp exposure");
708 cpl_msg_indent_less();
709 cpl_msg_info(recipe,
"Load input line catalog...");
710 cpl_msg_indent_more();
714 if (wavelengths == NULL)
715 fors_wave_calib_exit(
"Cannot load line catalog");
722 nlines = cpl_table_get_nrow(wavelengths);
725 fors_wave_calib_exit(
"Empty input line catalog");
727 if (cpl_table_has_column(wavelengths, wcolumn) != 1) {
728 cpl_msg_error(recipe,
"Missing column %s in input line catalog table",
730 fors_wave_calib_exit(NULL);
733 line = cpl_malloc(nlines *
sizeof(
double));
735 for (i = 0; i < nlines; i++)
736 line[i] = cpl_table_get(wavelengths, wcolumn, i, NULL);
738 cpl_table_delete(wavelengths); wavelengths = NULL;
740 lines = cpl_vector_wrap(nlines, line);
743 cpl_msg_indent_less();
744 cpl_msg_info(recipe,
"Load slit location table...");
745 cpl_msg_indent_more();
750 fors_wave_calib_exit(
"Cannot load slit location table");
753 cpl_msg_indent_less();
754 cpl_msg_info(recipe,
"Subtract background from input arc exposure...");
755 cpl_msg_indent_more();
758 cpl_image_subtract(spectra, bimage);
759 cpl_image_delete(bimage);
762 cpl_msg_indent_less();
763 cpl_msg_info(recipe,
"Perform wavelength calibration...");
764 cpl_msg_indent_more();
766 nx = cpl_image_get_size_x(spectra);
767 ny = cpl_image_get_size_y(spectra);
769 idscoeff = cpl_table_new(ny);
770 rainbow = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
771 residual = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
772 fiterror = cpl_calloc(ny,
sizeof(
double));
773 fitlines = cpl_calloc(ny,
sizeof(
int));
776 dispersion, peakdetection,
777 wradius, wdegree, wreject,
778 reference, &startwavelength,
779 &endwavelength, fitlines,
780 fiterror, idscoeff, rainbow,
781 residual, NULL, NULL);
783 cpl_image_delete(spectra); spectra = NULL;
785 if (rectified == NULL)
786 fors_wave_calib_exit(
"Wavelength calibration failure");
788 save_header = cpl_propertylist_new();
789 cpl_propertylist_update_double(save_header,
"CRPIX1", 1.0);
790 cpl_propertylist_update_double(save_header,
"CRPIX2", 1.0);
791 cpl_propertylist_update_double(save_header,
"CRVAL1",
792 startwavelength + dispersion/2);
793 cpl_propertylist_update_double(save_header,
"CRVAL2", 1.0);
796 cpl_propertylist_update_double(save_header,
"CD1_1", dispersion);
797 cpl_propertylist_update_double(save_header,
"CD1_2", 0.0);
798 cpl_propertylist_update_double(save_header,
"CD2_1", 0.0);
799 cpl_propertylist_update_double(save_header,
"CD2_2", 1.0);
800 cpl_propertylist_update_string(save_header,
"CTYPE1",
"LINEAR");
801 cpl_propertylist_update_string(save_header,
"CTYPE2",
"PIXEL");
802 cpl_propertylist_update_int(save_header,
"ESO PRO DATANCOM", 1);
804 if (
dfs_save_image(frameset, rectified, reduced_lamp_tag, save_header,
805 parlist, recipe, version))
806 fors_wave_calib_exit(NULL);
808 cpl_propertylist_delete(save_header); save_header = NULL;
809 save_header = cpl_propertylist_new();
811 cpl_propertylist_update_double(save_header,
"CRPIX2", 1.0);
812 cpl_propertylist_update_double(save_header,
"CRVAL2", 1.0);
814 cpl_propertylist_update_double(save_header,
"CD1_1", 1.0);
815 cpl_propertylist_update_double(save_header,
"CD1_2", 0.0);
816 cpl_propertylist_update_double(save_header,
"CD2_1", 0.0);
817 cpl_propertylist_update_double(save_header,
"CD2_2", 1.0);
818 cpl_propertylist_update_string(save_header,
"CTYPE1",
"LINEAR");
819 cpl_propertylist_update_string(save_header,
"CTYPE2",
"PIXEL");
821 if (
dfs_save_image(frameset, residual, disp_residuals_tag, save_header,
822 parlist, recipe, version))
823 fors_wave_calib_exit(NULL);
825 cpl_propertylist_delete(save_header); save_header = NULL;
826 cpl_image_delete(residual); residual = NULL;
828 cpl_table_wrap_double(idscoeff, fiterror,
"error"); fiterror = NULL;
829 cpl_table_set_column_unit(idscoeff,
"error",
"pixel");
830 cpl_table_wrap_int(idscoeff, fitlines,
"nlines"); fitlines = NULL;
832 for (i = 0; i < ny; i++)
833 if (!cpl_table_is_valid(idscoeff,
"c0", i))
834 cpl_table_set_invalid(idscoeff,
"error", i);
837 parlist, recipe, version))
838 fors_wave_calib_exit(NULL);
843 cpl_msg_info(recipe,
"Mean residual: %f pixel", mean_rms);
845 mean_rms = cpl_table_get_column_mean(idscoeff,
"error");
847 cpl_msg_info(recipe,
"Mean model accuracy: %f pixel (%f A)",
848 mean_rms, mean_rms * dispersion);
850 cpl_table_delete(idscoeff); idscoeff = NULL;
859 cpl_vector_delete(lines); lines = NULL;
860 cpl_image_delete(rectified); rectified = NULL;
863 cpl_msg_info(recipe,
"Mean spectral resolution: %.2f",
864 cpl_table_get_column_mean(restab,
"resolution"));
865 cpl_msg_info(recipe,
"Mean reference lines FWHM: %.2f +/- %.2f pixel",
866 cpl_table_get_column_mean(restab,
"fwhm") / dispersion,
867 cpl_table_get_column_mean(restab,
"fwhm_rms") / dispersion);
869 if (
dfs_save_table(frameset, restab, spectral_resolution_tag, NULL,
870 parlist, recipe, version))
871 fors_wave_calib_exit(NULL);
873 cpl_table_delete(restab); restab = NULL;
876 fors_wave_calib_exit(
"Cannot compute the spectral resolution table");
879 cpl_msg_indent_less();
880 cpl_msg_info(recipe,
"Load spatial map image...");
881 cpl_msg_indent_more();
883 spatial =
dfs_load_image(frameset, spatial_map_tag, CPL_TYPE_FLOAT, 0, 0);
886 fors_wave_calib_exit(
"Cannot load spatial map");
888 cpl_msg_indent_less();
889 cpl_msg_info(recipe,
"Load spectral curvature table...");
890 cpl_msg_indent_more();
894 if (polytraces == NULL)
895 fors_wave_calib_exit(
"Cannot load spectral curvature table");
898 reference, startwavelength, endwavelength,
901 cpl_image_delete(rainbow); rainbow = NULL;
902 cpl_image_delete(spatial); spatial = NULL;
903 cpl_table_delete(slits); slits = NULL;
904 cpl_table_delete(polytraces); polytraces = NULL;
907 parlist, recipe, version))
908 fors_wave_calib_exit(NULL);
910 cpl_image_delete(wavemap); wavemap = NULL;
911 cpl_propertylist_delete(header); header = 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.
const char * dfs_get_parameter_string(cpl_parameterlist *parlist, const char *name, const cpl_table *defaults)
Reading a recipe string parameter value.
double mos_distortions_rms(cpl_image *rectified, cpl_vector *lines, double wavestart, double dispersion, int radius, int highres)
Estimate the spectral distortion modeling goodness.
cpl_propertylist * dfs_load_header(cpl_frameset *frameset, const char *category, int ext)
Loading header associated to data of given category.
cpl_table * mos_load_slits_fors_mxu(cpl_propertylist *header)
Create slit location table from FITS header of FORS2-MXU data.
cpl_image * mos_map_wavelengths(cpl_image *spatial, cpl_image *calibration, cpl_table *slits, cpl_table *polytraces, double reference, double blue, double red, double dispersion)
Remapping of spatially rectified wavelengths to original CCD pixels.
cpl_table * mos_load_slits_fors_mos(cpl_propertylist *header, int *nslits_out_det)
Create slit location table from FITS header of FORS1/2 MOS data.
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.
cpl_table * dfs_load_table(cpl_frameset *frameset, const char *category, int ext)
Loading table data of given category.
cpl_image * mos_wavelength_calibration_final(cpl_image *image, cpl_table *slits, cpl_vector *lines, double dispersion, float level, int sradius, int order, double reject, double refwave, double *wavestart, double *waveend, int *nlines, double *error, cpl_table *idscoeff, cpl_image *calibration, cpl_image *residuals, cpl_table *restable, cpl_table *detected_lines)
Derive wavelength calibration from a rectified arc lamp or sky exposure.
int dfs_get_parameter_int(cpl_parameterlist *parlist, const char *name, const cpl_table *defaults)
Reading a recipe integer parameter value.
int dfs_save_table(cpl_frameset *frameset, const cpl_table *table, const char *category, cpl_propertylist *header, const cpl_parameterlist *parlist, const char *recipename, const char *version)
Saving table data of given category.
cpl_table * mos_resolution_table(cpl_image *image, double startwave, double dispersion, int saturation, cpl_vector *lines)
Compute mean spectral resolution at a given arc lamp line.
double dfs_get_parameter_double(cpl_parameterlist *parlist, const char *name, const cpl_table *defaults)
Reading a recipe double parameter value.
cpl_image * mos_arc_background(cpl_image *image, int msize, int fsize)
Background determination on emission line spectrum (arc)