35 #include <cxmessages.h>
37 #include <cpl_recipe.h>
38 #include <cpl_plugininfo.h>
39 #include <cpl_parameterlist.h>
40 #include <cpl_frameset.h>
41 #include <cpl_propertylist.h>
48 #include "gislitgeometry.h"
49 #include "gipsfdata.h"
50 #include "gifiberutils.h"
52 #include "giextract.h"
55 #include "giwlcalibration.h"
56 #include "girebinning.h"
57 #include "gisgcalibration.h"
60 static cxint giwavecalibration(cpl_parameterlist* config, cpl_frameset*
set);
61 static cxint giqcwavecalibration(cpl_frameset*
set);
70 giwavecalibration_create(cpl_plugin* plugin)
73 cpl_recipe* recipe = (cpl_recipe*)plugin;
87 recipe->parameters = cpl_parameterlist_new();
88 cx_assert(recipe->parameters != NULL);
111 p = cpl_parameter_new_value(
"giraffe.wcal.rebin",
113 "Rebin extracted arc-lamp spectra.",
117 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"wcal-rebin");
118 cpl_parameterlist_append(recipe->parameters, p);
124 p = cpl_parameter_new_value(
"giraffe.wcal.slitgeometry",
126 "Controls the slit geometry calibration.",
130 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"wcal-slit");
131 cpl_parameterlist_append(recipe->parameters, p);
144 giwavecalibration_exec(cpl_plugin* plugin)
147 cpl_recipe* recipe = (cpl_recipe*)plugin;
152 if (recipe->parameters == NULL || recipe->frames == NULL) {
156 status = giwavecalibration(recipe->parameters, recipe->frames);
162 status = giqcwavecalibration(recipe->frames);
174 giwavecalibration_destroy(cpl_plugin* plugin)
177 cpl_recipe* recipe = (cpl_recipe*)plugin;
186 cpl_parameterlist_delete(recipe->parameters); recipe->parameters = NULL;
188 giraffe_error_clear();
199 giwavecalibration(cpl_parameterlist* config, cpl_frameset*
set)
202 const cxchar*
const fctid =
"giwavecalibration";
205 const cxchar* filename = NULL;
207 cxbool rebin = FALSE;
208 cxbool slitgeometry = FALSE;
211 cxint narcspectrum = 0;
213 const cpl_propertylist* properties = NULL;
215 cpl_frame* arcspec_frame = NULL;
216 cpl_frame* bpixel_frame = NULL;
217 cpl_frame* mbias_frame = NULL;
218 cpl_frame* mlocy_frame = NULL;
219 cpl_frame* mlocw_frame = NULL;
220 cpl_frame* psfdata_frame = NULL;
221 cpl_frame* slight_frame = NULL;
222 cpl_frame* grating_frame = NULL;
223 cpl_frame* slitgeo_frame = NULL;
224 cpl_frame* lines_frame = NULL;
225 cpl_frame* wcal_frame = NULL;
226 cpl_frame* ldata_frame = NULL;
227 cpl_frame* scal_frame = NULL;
228 cpl_frame* sext_frame = NULL;
230 cpl_parameter* p = NULL;
232 cpl_matrix* biasareas = NULL;
234 GiImage* arcspectrum = NULL;
235 GiImage* bsarcspectrum = NULL;
236 GiImage* slight = NULL;
237 GiImage* mbias = NULL;
238 GiImage* bpixel = NULL;
240 GiLocalization* localization = NULL;
241 GiExtraction* extraction = NULL;
242 GiRebinning* rebinning = NULL;
243 GiWCalData* wlsolution = NULL;
245 GiTable* fibers = NULL;
246 GiTable* grating = NULL;
247 GiTable* slitgeo = NULL;
248 GiTable* wavelengths = NULL;
249 GiTable* wcal_initial = NULL;
253 GiBiasConfig* bias_config = NULL;
254 GiExtractConfig* extract_config = NULL;
257 GiFrameCreator creator = NULL;
259 GiRecipeInfo info = {(cxchar*)fctid, 1, NULL};
261 GiGroupInfo groups[] = {
262 {GIFRAME_ARC_SPECTRUM, CPL_FRAME_GROUP_RAW},
263 {GIFRAME_BADPIXEL_MAP, CPL_FRAME_GROUP_CALIB},
264 {GIFRAME_BIAS_MASTER, CPL_FRAME_GROUP_CALIB},
265 {GIFRAME_SCATTERED_LIGHT_MODEL, CPL_FRAME_GROUP_CALIB},
266 {GIFRAME_LOCALIZATION_CENTROID, CPL_FRAME_GROUP_CALIB},
267 {GIFRAME_LOCALIZATION_WIDTH, CPL_FRAME_GROUP_CALIB},
268 {GIFRAME_PSF_CENTROID, CPL_FRAME_GROUP_CALIB},
269 {GIFRAME_PSF_WIDTH, CPL_FRAME_GROUP_CALIB},
270 {GIFRAME_PSF_DATA, CPL_FRAME_GROUP_CALIB},
271 {GIFRAME_WAVELENGTH_SOLUTION, CPL_FRAME_GROUP_CALIB},
272 {GIFRAME_SLITSETUP, CPL_FRAME_GROUP_CALIB},
273 {GIFRAME_SLITMASTER, CPL_FRAME_GROUP_CALIB},
274 {GIFRAME_GRATING, CPL_FRAME_GROUP_CALIB},
275 {GIFRAME_LINE_CATALOG, CPL_FRAME_GROUP_CALIB},
276 {GIFRAME_LINE_MASK, CPL_FRAME_GROUP_CALIB},
277 {NULL, CPL_FRAME_GROUP_NONE}
283 cpl_msg_error(fctid,
"Invalid parameter list! Aborting ...");
288 cpl_msg_error(fctid,
"Invalid frame set! Aborting ...");
292 p = cpl_parameterlist_find(config,
"giraffe.wcal.rebin");
295 rebin = cpl_parameter_get_bool(p);
298 p = cpl_parameterlist_find(config,
"giraffe.wcal.slitgeometry");
301 slitgeometry = cpl_parameter_get_bool(p);
304 status = giraffe_frameset_set_groups(
set, groups);
307 cpl_msg_error(fctid,
"Setting frame group information failed!");
316 cpl_msg_info(fctid,
"Recipe Step : Initialization");
322 narcspectrum = cpl_frameset_count_tags(
set, GIFRAME_ARC_SPECTRUM);
324 if (narcspectrum > 1) {
325 cpl_msg_error(fctid,
"Only one arc spectrum frame allowed! "
329 else if (narcspectrum < 1) {
330 cpl_msg_error(fctid,
"Arc spectrum frame is missing! "
335 arcspec_frame = cpl_frameset_find(
set, GIFRAME_ARC_SPECTRUM);
336 bpixel_frame = cpl_frameset_find(
set, GIFRAME_BADPIXEL_MAP);
339 cpl_msg_info(fctid,
"No bad pixel map present in frame set.");
342 mbias_frame = cpl_frameset_find(
set, GIFRAME_BIAS_MASTER);
345 cpl_msg_info(fctid,
"No master bias present in frame set.");
348 mlocy_frame = cpl_frameset_find(
set, GIFRAME_PSF_CENTROID);
350 if (mlocy_frame == NULL) {
352 mlocy_frame = cpl_frameset_find(
set, GIFRAME_LOCALIZATION_CENTROID);
354 if (mlocy_frame == NULL) {
355 cpl_msg_info(fctid,
"No master localization (centroid position) "
356 "present in frame set. Aborting ...");
362 mlocw_frame = cpl_frameset_find(
set, GIFRAME_PSF_WIDTH);
364 if (mlocw_frame == NULL) {
366 mlocw_frame = cpl_frameset_find(
set, GIFRAME_LOCALIZATION_WIDTH);
368 if (mlocw_frame == NULL) {
369 cpl_msg_info(fctid,
"No master localization (spectrum width) "
370 "present in frame set. Aborting ...");
376 psfdata_frame = cpl_frameset_find(
set, GIFRAME_PSF_DATA);
378 if (!psfdata_frame) {
379 cpl_msg_info(fctid,
"No PSF profile parameters present in frame set.");
382 slight_frame = cpl_frameset_find(
set, GIFRAME_SCATTERED_LIGHT_MODEL);
385 cpl_msg_info(fctid,
"No scattered light model present in frame set.");
388 grating_frame = cpl_frameset_find(
set, GIFRAME_GRATING);
390 if (!grating_frame) {
391 cpl_msg_error(fctid,
"No grating table present in frame set, "
398 if (!slitgeo_frame) {
399 cpl_msg_error(fctid,
"No slit geometry table present in frame "
404 lines_frame = cpl_frameset_find(
set, GIFRAME_LINE_CATALOG);
407 cpl_msg_error(fctid,
"No wavelength table present in frame set, "
412 wcal_frame = cpl_frameset_find(
set, GIFRAME_WAVELENGTH_SOLUTION);
415 cpl_msg_info(fctid,
"No wavelength solution present in frame set.");
418 scal_frame = cpl_frameset_find(
set, GIFRAME_LINE_MASK);
422 if (slitgeometry == TRUE) {
423 cpl_msg_error(fctid,
"No line mask present in frame "
424 "set. Aborting ...");
428 cpl_msg_info(fctid,
"No slit geometry mask present in frame "
445 filename = cpl_frame_get_filename(bpixel_frame);
451 cpl_msg_error(fctid,
"Cannot load bad pixel map from '%s'. "
452 "Aborting ...", filename);
465 filename = cpl_frame_get_filename(arcspec_frame);
471 cpl_msg_error(fctid,
"Cannot load arc spectrum from '%s'. "
472 "Aborting...", filename);
484 cpl_msg_info(fctid,
"Recipe Step : Bias Removal");
492 if (bias_config->method == GIBIAS_METHOD_MASTER ||
493 bias_config->method == GIBIAS_METHOD_ZMASTER) {
496 cpl_msg_error(fctid,
"Missing master bias frame! Selected bias "
497 "removal method requires a master bias "
509 filename = cpl_frame_get_filename(mbias_frame);
515 cpl_msg_error(fctid,
"Cannot load master bias from '%s'. "
516 "Aborting ...", filename);
536 biasareas, bias_config);
550 cpl_msg_error(fctid,
"Bias removal failed. Aborting ...");
562 cpl_msg_info(fctid,
"Recipe Step : Fiber Setup");
564 cpl_msg_info(fctid,
"Building fiber setup for frame '%s'.",
565 cpl_frame_get_filename(arcspec_frame));
570 cpl_msg_error(fctid,
"Cannot create fiber setup for frame '%s'! "
571 "Aborting ...", cpl_frame_get_filename(arcspec_frame));
579 cpl_msg_info(fctid,
"Fiber reference setup taken from localization "
580 "frame '%s'.", cpl_frame_get_filename(mlocy_frame));
587 localization = giraffe_localization_new();
589 filename = cpl_frame_get_filename(mlocy_frame);
596 cpl_msg_error(fctid,
"Cannot load localization (centroid "
597 "position) frame from '%s'. Aborting ...",
600 giraffe_localization_destroy(localization);
610 filename = cpl_frame_get_filename(mlocw_frame);
617 cpl_msg_error(fctid,
"Cannot load localization (spectrum width) "
618 "frame from '%s'. Aborting ...", filename);
620 giraffe_localization_destroy(localization);
634 cpl_msg_info(fctid,
"Recipe Step : Spectrum Extraction");
638 filename = cpl_frame_get_filename(slight_frame);
645 cpl_msg_error(fctid,
"Cannot load scattered light model from "
646 "'%s'. Aborting ...", filename);
651 giraffe_localization_destroy(localization);
662 if ((extract_config->emethod == GIEXTRACT_OPTIMAL) ||
663 (extract_config->emethod == GIEXTRACT_HORNE)) {
665 if (psfdata_frame == NULL) {
667 const cxchar* emethod =
"Optimal";
669 if (extract_config->emethod == GIEXTRACT_HORNE) {
673 cpl_msg_error(fctid,
"%s spectrum extraction requires PSF "
674 "profile data. Aborting ...", emethod);
677 extract_config = NULL;
679 if (slight != NULL) {
684 giraffe_localization_destroy(localization);
696 bsarcspectrum = NULL;
703 filename = cpl_frame_get_filename(psfdata_frame);
706 localization->psf = giraffe_psfdata_new();
707 status = giraffe_psfdata_load(localization->psf, filename);
710 cpl_msg_error(fctid,
"Cannot load PSF profile data frame from "
711 "'%s'. Aborting ...", filename);
714 extract_config = NULL;
716 if (slight != NULL) {
721 giraffe_localization_destroy(localization);
733 bsarcspectrum = NULL;
744 extraction = giraffe_extraction_new();
747 localization, bpixel, slight,
751 cpl_msg_error(fctid,
"Spectrum extraction failed! Aborting ...");
756 giraffe_localization_destroy(localization);
759 giraffe_extraction_destroy(extraction);
771 bsarcspectrum = NULL;
774 extract_config = NULL;
781 cpl_msg_info(fctid,
"Writing extracted spectra ...");
788 GIFRAME_ARC_LAMP_EXTSPECTRA,
789 CPL_FRAME_LEVEL_INTERMEDIATE,
792 if (sext_frame == NULL) {
793 cpl_msg_error(fctid,
"Cannot create local file! Aborting ...");
797 giraffe_localization_destroy(localization);
798 giraffe_extraction_destroy(extraction);
806 cpl_msg_error(fctid,
"Cannot attach fiber setup to local file '%s'! "
807 "Aborting ...", cpl_frame_get_filename(sext_frame));
809 cpl_frame_delete(sext_frame);
813 giraffe_localization_destroy(localization);
814 giraffe_extraction_destroy(extraction);
819 cpl_frameset_insert(
set, sext_frame);
826 GIFRAME_ARC_LAMP_EXTERRORS,
827 CPL_FRAME_LEVEL_INTERMEDIATE,
830 if (sext_frame == NULL) {
831 cpl_msg_error(fctid,
"Cannot create local file! Aborting ...");
835 giraffe_localization_destroy(localization);
836 giraffe_extraction_destroy(extraction);
844 cpl_msg_error(fctid,
"Cannot attach fiber setup to local file '%s'! "
845 "Aborting ...", cpl_frame_get_filename(sext_frame));
847 cpl_frame_delete(sext_frame);
851 giraffe_localization_destroy(localization);
852 giraffe_extraction_destroy(extraction);
857 cpl_frameset_insert(
set, sext_frame);
861 if (extraction->npixels != NULL) {
866 GIFRAME_ARC_LAMP_EXTPIXELS,
867 CPL_FRAME_LEVEL_INTERMEDIATE,
870 if (sext_frame == NULL) {
871 cpl_msg_error(fctid,
"Cannot create local file! Aborting ...");
875 giraffe_localization_destroy(localization);
876 giraffe_extraction_destroy(extraction);
884 cpl_msg_error(fctid,
"Cannot attach fiber setup to local file '%s'! "
885 "Aborting ...", cpl_frame_get_filename(sext_frame));
887 cpl_frame_delete(sext_frame);
891 giraffe_localization_destroy(localization);
892 giraffe_extraction_destroy(extraction);
897 cpl_frameset_insert(
set, sext_frame);
906 GIFRAME_ARC_LAMP_EXTTRACE,
907 CPL_FRAME_LEVEL_INTERMEDIATE,
910 if (sext_frame == NULL) {
911 cpl_msg_error(fctid,
"Cannot create local file! Aborting ...");
915 giraffe_localization_destroy(localization);
916 giraffe_extraction_destroy(extraction);
924 cpl_msg_error(fctid,
"Cannot attach fiber setup to local file '%s'! "
925 "Aborting ...", cpl_frame_get_filename(sext_frame));
927 cpl_frame_delete(sext_frame);
931 giraffe_localization_destroy(localization);
932 giraffe_extraction_destroy(extraction);
937 cpl_frameset_insert(
set, sext_frame);
941 if (extraction->model != NULL) {
946 GIFRAME_ARC_LAMP_EXTMODEL,
947 CPL_FRAME_LEVEL_FINAL,
950 if (sext_frame == NULL) {
951 cpl_msg_error(fctid,
"Cannot create local file! Aborting ...");
955 giraffe_localization_destroy(localization);
956 giraffe_extraction_destroy(extraction);
964 cpl_msg_error(fctid,
"Cannot attach fiber setup to local file '%s'! "
965 "Aborting ...", cpl_frame_get_filename(sext_frame));
967 cpl_frame_delete(sext_frame);
971 giraffe_localization_destroy(localization);
972 giraffe_extraction_destroy(extraction);
977 cpl_frameset_insert(
set, sext_frame);
985 cpl_msg_info(fctid,
"Recipe Step : Wavelength Calibration");
987 filename = cpl_frame_get_filename(grating_frame);
994 cpl_msg_error(fctid,
"Cannot load grating table from '%s'. "
995 "Aborting ...", filename);
998 giraffe_localization_destroy(localization);
999 giraffe_extraction_destroy(extraction);
1005 filename = cpl_frame_get_filename(slitgeo_frame);
1009 if (slitgeo == NULL) {
1010 cpl_msg_error(fctid,
"Cannot load slit geometry table from '%s'. "
1011 "Aborting ...", filename);
1014 giraffe_localization_destroy(localization);
1015 giraffe_extraction_destroy(extraction);
1029 cpl_msg_error(fctid,
"Slit geometry data from '%s' is not "
1030 "applicable for current fiber setup! "
1031 "Aborting ...", filename);
1035 giraffe_localization_destroy(localization);
1036 giraffe_extraction_destroy(extraction);
1045 filename = cpl_frame_get_filename(lines_frame);
1052 cpl_msg_error(fctid,
"Cannot load arc-line data from '%s'. "
1053 "Aborting ...", filename);
1056 giraffe_localization_destroy(localization);
1057 giraffe_extraction_destroy(extraction);
1065 if (wcal_frame != NULL) {
1069 filename = cpl_frame_get_filename(wcal_frame);
1073 cpl_msg_error(fctid,
"Cannot load initial wavelength solution "
1074 "from '%s'. Aborting ...", filename);
1079 giraffe_localization_destroy(localization);
1080 giraffe_extraction_destroy(extraction);
1091 cx_assert(wcal_config != NULL);
1093 wlsolution = giraffe_wcaldata_new();
1096 localization, fibers, slitgeo,
1097 grating, wavelengths, wcal_initial,
1101 cpl_msg_error(fctid,
"Error during wavelength calibration, "
1105 giraffe_localization_destroy(localization);
1106 giraffe_extraction_destroy(extraction);
1112 giraffe_wcaldata_delete(wlsolution);
1123 wcal_initial = NULL;
1138 GIFRAME_WAVELENGTH_SOLUTION,
1139 CPL_FRAME_LEVEL_FINAL,
1142 if (wcal_frame == NULL) {
1144 cpl_msg_error(fctid,
"Cannot create local file! Aborting ...");
1147 giraffe_localization_destroy(localization);
1148 giraffe_extraction_destroy(extraction);
1152 giraffe_wcaldata_delete(wlsolution);
1158 cpl_frameset_insert(
set, wcal_frame);
1163 creator = (GiFrameCreator)giraffe_linedata_writer;
1166 CPL_FRAME_LEVEL_FINAL,
1167 properties, wlsolution->linedata,
1171 if (ldata_frame == NULL) {
1173 cpl_msg_error(fctid,
"Cannot create local file! Aborting ...");
1176 giraffe_localization_destroy(localization);
1177 giraffe_extraction_destroy(extraction);
1181 giraffe_wcaldata_delete(wlsolution);
1191 giraffe_linedata_delete(wlsolution->linedata);
1192 wlsolution->linedata = NULL;
1194 cpl_frameset_insert(
set, ldata_frame);
1202 if (slitgeometry == TRUE) {
1204 cpl_frame* slit_frame = NULL;
1208 GiTable* mask = NULL;
1209 GiTable* slit = NULL;
1212 cpl_msg_info(fctid,
"Calibrating slit geometry ...");
1217 filename = cpl_frame_get_filename(scal_frame);
1223 cpl_msg_error(fctid,
"Cannot load slit geometry mask from '%s'. "
1224 "Aborting ...", filename);
1230 giraffe_wcaldata_delete(wlsolution);
1232 giraffe_localization_destroy(localization);
1233 giraffe_extraction_destroy(extraction);
1246 wlsolution->coeffs, slitgeo, grating,
1250 cpl_msg_error(fctid,
"Slit geometry calibration failed! "
1258 giraffe_wcaldata_delete(wlsolution);
1260 giraffe_localization_destroy(localization);
1261 giraffe_extraction_destroy(extraction);
1279 slit_frame = giraffe_slitgeometry_save(slit);
1283 cpl_msg_error(fctid,
"Cannot create local file! Aborting ...");
1290 giraffe_wcaldata_delete(wlsolution);
1292 giraffe_localization_destroy(localization);
1293 giraffe_extraction_destroy(extraction);
1302 cpl_frameset_insert(
set, slit_frame);
1322 if (rebin == TRUE) {
1324 cpl_frame* rbin_frame = NULL;
1326 GiRebinConfig* rebin_config;
1329 cpl_msg_info(fctid,
"Recipe Step : Spectrum Rebinning");
1336 localization, grating, slitgeo,
1337 wlsolution->coeffs, rebin_config);
1340 cpl_msg_error(fctid,
"Rebinning of arc-lamp spectra failed! "
1343 giraffe_wcaldata_delete(wlsolution);
1346 giraffe_localization_destroy(localization);
1347 giraffe_extraction_destroy(extraction);
1370 GIFRAME_ARC_LAMP_RBNSPECTRA,
1371 CPL_FRAME_LEVEL_FINAL,
1374 if (rbin_frame == NULL) {
1376 cpl_msg_error(fctid,
"Cannot create local file! Aborting ...");
1378 giraffe_wcaldata_delete(wlsolution);
1381 giraffe_localization_destroy(localization);
1382 giraffe_extraction_destroy(extraction);
1395 cpl_msg_error(fctid,
"Cannot attach fiber setup to local "
1396 "file '%s'! Aborting ...",
1397 cpl_frame_get_filename(rbin_frame));
1399 giraffe_wcaldata_delete(wlsolution);
1402 giraffe_localization_destroy(localization);
1403 giraffe_extraction_destroy(extraction);
1409 cpl_frame_delete(rbin_frame);
1415 cpl_frameset_insert(
set, rbin_frame);
1422 GIFRAME_ARC_LAMP_RBNERRORS,
1423 CPL_FRAME_LEVEL_FINAL,
1426 if (rbin_frame == NULL) {
1428 cpl_msg_error(fctid,
"Cannot create local file! Aborting ...");
1430 giraffe_wcaldata_delete(wlsolution);
1433 giraffe_localization_destroy(localization);
1434 giraffe_extraction_destroy(extraction);
1448 cpl_msg_error(fctid,
"Cannot attach fiber setup to local "
1449 "file '%s'! Aborting ...",
1450 cpl_frame_get_filename(rbin_frame));
1452 giraffe_wcaldata_delete(wlsolution);
1455 giraffe_localization_destroy(localization);
1456 giraffe_extraction_destroy(extraction);
1462 cpl_frame_delete(rbin_frame);
1468 cpl_frameset_insert(
set, rbin_frame);
1480 giraffe_localization_destroy(localization);
1481 localization = NULL;
1483 giraffe_extraction_destroy(extraction);
1486 if (rebinning != NULL) {
1497 giraffe_wcaldata_delete(wlsolution);
1506 giqcwavecalibration(cpl_frameset*
set)
1509 const cxchar*
const fctid =
"giqcwavecalibration";
1517 cxint nsaturated = 0;
1520 const cxdouble rmsscale = 3.;
1521 const cxdouble saturation = 60000.;
1522 const cxdouble* pixels = NULL;
1524 cxdouble efficiency[2] = {0., 0.};
1525 cxdouble wlcenter = 0.;
1528 cxdouble pixel2nm = 1.;
1529 cxdouble fwhm_domain[2] = {0., 100.};
1530 cxdouble* _tdata = NULL;
1532 cpl_propertylist* properties = NULL;
1533 cpl_propertylist* qclog = NULL;
1535 cpl_frame* rframe = NULL;
1536 cpl_frame* pframe = NULL;
1538 const cpl_image* _rimage = NULL;
1539 const cpl_image* _pimage = NULL;
1541 cpl_image* _test = NULL;
1542 cpl_image* _test0 = NULL;
1543 cpl_image* _test1 = NULL;
1545 cpl_table* _ptable = NULL;
1547 GiImage* rimage = NULL;
1548 GiImage* pimage = NULL;
1550 GiTable* ptable = NULL;
1552 GiLineData* plines = NULL;
1560 cpl_msg_info(fctid,
"Computing QC1 parameters ...");
1569 CPL_FRAME_GROUP_PRODUCT);
1571 if (pframe == NULL) {
1573 cpl_msg_warning(fctid,
"Product '%s' not found.",
1574 GIFRAME_ARC_LAMP_EXTSPECTRA);
1576 cpl_msg_warning(fctid,
"Setting lamp efficiencies (%s, %s) to 0.",
1577 GIALIAS_QCLAMP, GIALIAS_QCLAMP_SIMCAL);
1589 cpl_msg_error(fctid,
"Could not load extracted spectra '%s'!",
1590 cpl_frame_get_filename(pframe));
1595 giraffe_paf_delete(qc);
1602 cx_assert(_pimage != NULL);
1610 cpl_msg_error(fctid,
"Could not load extracted spectra fiber setup!");
1618 giraffe_paf_delete(qc);
1625 cx_assert(_ptable != NULL);
1627 if (cpl_table_has_column(_ptable,
"RP") == FALSE) {
1629 cpl_msg_warning(fctid,
"Column 'RP' not found in fiber setup table!");
1630 cpl_msg_warning(fctid,
"Setting lamp efficiencies (%s, %s) to 0.",
1631 GIALIAS_QCLAMP, GIALIAS_QCLAMP_SIMCAL);
1640 cx_assert(properties != NULL);
1642 if (cpl_propertylist_has(properties, GIALIAS_EXPTIME) == FALSE) {
1644 cpl_msg_warning(fctid,
"Property '%s' not found in '%s'.",
1645 GIALIAS_EXPTIME, cpl_frame_get_filename(rframe));
1646 cpl_msg_warning(fctid,
"Setting lamp efficiencies (%s, %s) to 0.",
1647 GIALIAS_QCLAMP, GIALIAS_QCLAMP_SIMCAL);
1656 cxint nb = cpl_image_get_size_y(_pimage);
1657 cxint nf[2] = {0, 0};
1659 cxdouble exptime = cpl_propertylist_get_double(properties,
1661 cxdouble* _sum = NULL;
1663 cpl_image* sum = NULL;
1666 sum = cpl_image_collapse_create(_pimage, 0);
1667 _sum = cpl_image_get_data_double(sum);
1669 for (fiber = 0; fiber < cpl_table_get_nrow(_ptable); ++fiber) {
1671 cxint rp = cpl_table_get_int(_ptable,
"RP", fiber, NULL);
1674 efficiency[1] += _sum[fiber];
1678 efficiency[0] += _sum[fiber];
1686 cpl_image_delete(sum);
1690 cpl_msg_warning(fctid,
"No OzPoz fibers found in the "
1691 "current fiber setup.");
1692 cpl_msg_warning(fctid,
"Setting lamp efficiency (%s) to 0.",
1697 efficiency[0] /= nf[0] * nb * exptime;
1701 cpl_msg_warning(fctid,
"No simultaneous calibration fibers "
1702 "found in the current fiber setup.");
1703 cpl_msg_warning(fctid,
"Setting lamp efficiency (%s) to 0.",
1704 GIALIAS_QCLAMP_SIMCAL);
1708 efficiency[1] /= nf[1] * nb * exptime;
1731 rframe = cpl_frameset_find(
set, GIFRAME_ARC_SPECTRUM);
1733 if (rframe == NULL) {
1734 cpl_msg_error(fctid,
"Missing raw frame (%s)", GIFRAME_ARC_SPECTRUM);
1736 giraffe_paf_delete(qc);
1742 cpl_msg_info(fctid,
"Processing reference frame '%s' (%s)",
1743 cpl_frame_get_filename(rframe), cpl_frame_get_tag(rframe));
1750 cpl_msg_error(fctid,
"Could not load arc-lamp spectra '%s'!",
1751 cpl_frame_get_filename(rframe));
1756 giraffe_paf_delete(qc);
1764 cx_assert(_rimage != NULL);
1773 cx_assert(properties != NULL);
1775 if (cpl_propertylist_has(properties, GIALIAS_OVSCX)) {
1777 cxint _ox = cpl_propertylist_get_int(properties, GIALIAS_OVSCX);
1778 cxint _nx = cpl_image_get_size_x(_rimage) - 2 * CX_MAX(0, _ox) - 1;
1780 w.x0 = CX_MAX(0, _ox) + 1;
1785 if (cpl_propertylist_has(properties, GIALIAS_OVSCY)) {
1787 cxint _oy = cpl_propertylist_get_int(properties, GIALIAS_OVSCY);
1788 cxint _ny = cpl_image_get_size_y(_rimage) - 2 * CX_MAX(0, _oy) - 1;
1790 w.y0 = CX_MAX(0, _oy) + 1;
1795 mean = cpl_image_get_mean_window(_rimage, w.x0, w.y0, w.x1, w.y1);
1797 pixels = cpl_image_get_data_const(_rimage);
1798 npixel = cpl_image_get_size_x(_rimage) * cpl_image_get_size_y(_rimage);
1800 for (i = 0; i < npixel; i++) {
1801 if (pixels[i] > saturation) {
1811 qc = giraffe_qclog_open(0);
1814 cpl_msg_error(fctid,
"Cannot create QC1 log!");
1822 qclog = giraffe_paf_get_properties(qc);
1823 cx_assert(qclog != NULL);
1826 CPL_FRAME_GROUP_PRODUCT);
1828 if (pframe == NULL) {
1829 cpl_msg_error(fctid,
"Missing product frame (%s)",
1830 GIFRAME_WAVELENGTH_SOLUTION);
1832 giraffe_paf_delete(qc);
1841 cpl_msg_info(fctid,
"Processing product frame '%s' (%s)",
1842 cpl_frame_get_filename(pframe), cpl_frame_get_tag(pframe));
1849 cpl_msg_error(fctid,
"Could not load dispersion solution '%s'!",
1850 cpl_frame_get_filename(pframe));
1858 giraffe_paf_delete(qc);
1865 cx_assert(properties != NULL);
1880 cpl_propertylist_update_string(qclog,
"PRO.CATG",
1881 cpl_frame_get_tag(pframe));
1882 cpl_propertylist_set_comment(qclog,
"PRO.CATG",
1883 "Pipeline product category");
1886 cx_assert(properties != NULL);
1891 GIALIAS_WSOL_NLINES);
1893 GIALIAS_WSOL_NACCEPT);
1895 GIALIAS_WSOL_NREJECT);
1903 giraffe_qclog_close(qc);
1911 qc = giraffe_qclog_open(1);
1914 cpl_msg_error(fctid,
"Cannot create QC1 log!");
1918 qclog = giraffe_paf_get_properties(qc);
1919 cx_assert(qclog != NULL);
1922 CPL_FRAME_GROUP_PRODUCT);
1924 if (pframe == NULL) {
1925 cpl_msg_error(fctid,
"Missing product frame (%s)",
1926 GIFRAME_ARC_LAMP_RBNSPECTRA);
1931 giraffe_paf_delete(qc);
1937 cpl_msg_info(fctid,
"Processing product frame '%s' (%s)",
1938 cpl_frame_get_filename(pframe), cpl_frame_get_tag(pframe));
1944 cpl_msg_error(fctid,
"Could not load rebinned arc-lamp spectra '%s'!",
1945 cpl_frame_get_filename(pframe));
1953 giraffe_paf_delete(qc);
1964 cpl_msg_error(fctid,
"Could not load rebinned arc-lamp spectra '%s'!",
1965 cpl_frame_get_filename(pframe));
1976 giraffe_paf_delete(qc);
1983 cx_assert(properties != NULL);
1996 cpl_propertylist_update_string(qclog,
"PRO.CATG",
1997 cpl_frame_get_tag(pframe));
1998 cpl_propertylist_set_comment(qclog,
"PRO.CATG",
1999 "Pipeline product category");
2002 cx_assert(properties != NULL);
2014 cpl_propertylist_update_double(properties, GIALIAS_QCMEAN, mean);
2015 cpl_propertylist_set_comment(properties, GIALIAS_QCMEAN,
"Mean level of "
2022 cpl_propertylist_update_int(properties, GIALIAS_QCNSAT, nsaturated);
2023 cpl_propertylist_set_comment(properties, GIALIAS_QCNSAT,
"Number of "
2024 "saturated pixels in the first raw frame");
2034 cpl_propertylist_update_double(properties, GIALIAS_QCLAMP, efficiency[0]);
2035 cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP,
2036 "Calibration lamp efficiency");
2041 cpl_propertylist_update_double(properties, GIALIAS_QCLAMP_SIMCAL,
2043 cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP_SIMCAL,
2044 "SIMCAL lamp efficiency");
2047 GIALIAS_QCLAMP_SIMCAL);
2054 _test = cpl_image_duplicate(_pimage);
2055 _tdata = cpl_image_get_data(_test);
2057 nx = cpl_image_get_size_x(_test);
2058 ny = cpl_image_get_size_y(_test);
2060 for (i = 0; i < nx * ny; i++) {
2061 _tdata[i] = _tdata[i] > 0. ? log(_tdata[i]) : 0.;
2066 _test0 = cpl_image_extract(_test, 4, 1, 4, ny);
2068 _test1 = cpl_image_collapse_create(_test, 1);
2069 cpl_image_divide_scalar(_test1, nx);
2071 cpl_image_delete(_test);
2075 _test = cpl_image_subtract_create(_test0, _test1);
2077 cpl_image_delete(_test0);
2080 cpl_image_delete(_test1);
2084 _tdata = cpl_image_get_data(_test);
2088 for (i = 0; i < ny; i++) {
2089 _tdata[i] = exp(_tdata[i]);
2090 rms += pow(_tdata[i], 2.);
2093 rms = sqrt(rms / (ny - 1));
2095 cpl_image_delete(_test);
2098 cpl_propertylist_update_double(properties, GIALIAS_QCRBRMS, rms);
2099 cpl_propertylist_set_comment(properties, GIALIAS_QCRBRMS,
2100 "RMS of rebinned arc-lamp spectra");
2109 cpl_msg_error(fctid,
"Could not save rebinned arc-lamp spectra "
2110 "'%s'!", cpl_frame_get_filename(pframe));
2121 giraffe_paf_delete(qc);
2131 cpl_msg_error(fctid,
"Could not save rebinned arc-lamp spectra "
2132 "'%s'!", cpl_frame_get_filename(pframe));
2143 giraffe_paf_delete(qc);
2155 giraffe_qclog_close(qc);
2163 qc = giraffe_qclog_open(2);
2166 cpl_msg_error(fctid,
"Cannot create QC1 log!");
2170 qclog = giraffe_paf_get_properties(qc);
2171 cx_assert(qclog != NULL);
2174 CPL_FRAME_GROUP_PRODUCT);
2176 if (pframe == NULL) {
2177 cpl_msg_error(fctid,
"Missing product frame (%s)",
2183 giraffe_paf_delete(qc);
2189 cpl_msg_info(fctid,
"Processing product frame '%s' (%s)",
2190 cpl_frame_get_filename(pframe), cpl_frame_get_tag(pframe));
2197 plines = giraffe_linedata_new();
2199 status = giraffe_linedata_load(plines, cpl_frame_get_filename(pframe));
2202 cpl_msg_error(fctid,
"Could not load line data '%s'!",
2203 cpl_frame_get_filename(pframe));
2205 giraffe_linedata_delete(plines);
2211 giraffe_paf_delete(qc);
2218 cx_assert(properties != NULL);
2231 cpl_propertylist_update_string(qclog,
"PRO.CATG",
2232 cpl_frame_get_tag(pframe));
2233 cpl_propertylist_set_comment(qclog,
"PRO.CATG",
2234 "Pipeline product category");
2237 _pimage = giraffe_linedata_get_data(plines,
"FWHM");
2239 if (_pimage == NULL) {
2240 cpl_msg_error(fctid,
"FWHM line data not found!");
2242 giraffe_linedata_delete(plines);
2248 giraffe_paf_delete(qc);
2254 nx = cpl_image_get_size_x(_pimage);
2255 ny = cpl_image_get_size_y(_pimage);
2257 pixels = cpl_image_get_data_const(_pimage);
2259 for (j = 0; j < 2; ++j) {
2261 register cxint ndata = nx * ny;
2267 for (i = 0; i < ndata; ++i) {
2269 if ((pixels[i] >= fwhm_domain[0]) &&
2270 (pixels[i] < fwhm_domain[1])) {
2278 cpl_msg_error(fctid,
"All line FWHM data are invalid!");
2280 giraffe_linedata_delete(plines);
2286 giraffe_paf_delete(qc);
2294 for (i = 0; i < ndata; ++i) {
2296 if ((pixels[i] >= fwhm_domain[0]) &&
2297 (pixels[i] < fwhm_domain[1])) {
2298 rms += pow(pixels[i] - mean, 2.);
2304 rms = sqrt(rms / (npixel - 1));
2307 fwhm_domain[0] = CX_MAX(mean - rmsscale * rms, 0.);
2308 fwhm_domain[1] = CX_MIN(mean + rmsscale * rms, 100.);
2313 properties = cpl_propertylist_load(cpl_frame_get_filename(pframe), 0);
2314 cx_assert(properties != NULL);
2316 if (cpl_propertylist_has(properties, GIALIAS_GRATWLEN) == FALSE) {
2317 cpl_msg_error(fctid,
"Grating central wavelength property '%s' not "
2318 "found!", GIALIAS_GRATWLEN);
2320 cpl_propertylist_delete(properties);
2323 giraffe_linedata_delete(plines);
2329 giraffe_paf_delete(qc);
2335 if (cpl_propertylist_has(properties, GIALIAS_WSOL_SCALE) == FALSE) {
2336 cpl_msg_error(fctid,
"Line data property '%s' not found!",
2337 GIALIAS_WSOL_SCALE);
2339 cpl_propertylist_delete(properties);
2342 giraffe_linedata_delete(plines);
2348 giraffe_paf_delete(qc);
2354 wlcenter = cpl_propertylist_get_double(properties, GIALIAS_GRATWLEN);
2355 pixel2nm = cpl_propertylist_get_double(properties, GIALIAS_WSOL_SCALE);
2360 cpl_propertylist_update_double(properties, GIALIAS_QCRESOLAVG, mean);
2361 cpl_propertylist_set_comment(properties, GIALIAS_QCRESOLAVG,
2362 "Average line FWHM [nm]");
2364 cpl_propertylist_update_double(properties, GIALIAS_QCRESOLRMS, rms);
2365 cpl_propertylist_set_comment(properties, GIALIAS_QCRESOLRMS,
2366 "RMS of line FWHM [nm]");
2368 cpl_propertylist_update_int(properties, GIALIAS_QCRESOLTOT, nx * ny);
2369 cpl_propertylist_set_comment(properties, GIALIAS_QCRESOLTOT,
2370 "Total number of lines available for FWHM RMS "
2373 cpl_propertylist_update_int(properties, GIALIAS_QCRESOLLIN, npixel);
2374 cpl_propertylist_set_comment(properties, GIALIAS_QCRESOLLIN,
2375 "Number of lines used for FWHM RMS "
2378 cpl_propertylist_update_double(properties, GIALIAS_QCRESOLPWR,
2380 cpl_propertylist_set_comment(properties, GIALIAS_QCRESOLPWR,
2384 GIALIAS_QCRESOLAVG);
2386 GIALIAS_QCRESOLRMS);
2388 GIALIAS_QCRESOLTOT);
2390 GIALIAS_QCRESOLLIN);
2392 GIALIAS_QCRESOLPWR);
2395 status = giraffe_linedata_save(plines, properties,
2396 cpl_frame_get_filename(pframe));
2399 cpl_msg_error(fctid,
"Could not save line data "
2400 "'%s'!", cpl_frame_get_filename(pframe));
2402 cpl_propertylist_delete(properties);
2405 giraffe_linedata_delete(plines);
2411 giraffe_paf_delete(qc);
2417 cpl_propertylist_delete(properties);
2420 giraffe_qclog_close(qc);
2441 cpl_plugin_get_info(cpl_pluginlist* list)
2444 cpl_recipe* recipe = cx_calloc(1,
sizeof *recipe);
2445 cpl_plugin* plugin = &recipe->interface;
2447 cpl_plugin_init(plugin,
2449 GIRAFFE_BINARY_VERSION,
2450 CPL_PLUGIN_TYPE_RECIPE,
2451 "giwavecalibration",
2452 "Compute dispersion solution from an arc-lamp spectrum.",
2453 "For detailed information please refer to the "
2454 "GIRAFFE pipeline user manual.\nIt is available at "
2455 "http://www.eso.org/pipelines.",
2459 giwavecalibration_create,
2460 giwavecalibration_exec,
2461 giwavecalibration_destroy);
2463 cpl_pluginlist_append(list, plugin);