GIRAFFE Pipeline Reference Manual

giwavecalibration.c
1/*
2 * This file is part of the GIRAFFE Pipeline
3 * Copyright (C) 2002-2019 European Southern Observatory
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#ifdef HAVE_CONFIG_H
21# include <config.h>
22#endif
23
24#include <math.h>
25
26#include <cxtypes.h>
27#include <cxmessages.h>
28
29#include <cpl_recipe.h>
30#include <cpl_plugininfo.h>
31#include <cpl_parameterlist.h>
32#include <cpl_frameset.h>
33#include <cpl_propertylist.h>
34
35#include "gialias.h"
36#include "gierror.h"
37#include "giframe.h"
38#include "giwindow.h"
39#include "gifibers.h"
40#include "gislitgeometry.h"
41#include "gipsfdata.h"
42#include "gifiberutils.h"
43#include "gibias.h"
44#include "giextract.h"
45#include "giqclog.h"
46#include "giutils.h"
47#include "giwlcalibration.h"
48#include "girebinning.h"
49#include "gisgcalibration.h"
50
51
52static cxint giwavecalibration(cpl_parameterlist* config, cpl_frameset* set);
53static cxint giqcwavecalibration(cpl_frameset* set);
54
55
56/*
57 * Create the recipe instance, i.e. setup the parameter list for this
58 * recipe and make it availble to the application using the interface.
59 */
60
61static cxint
62giwavecalibration_create(cpl_plugin* plugin)
63{
64
65 cpl_recipe* recipe = (cpl_recipe*)plugin;
66
67 cpl_parameter* p;
68
69
70 giraffe_error_init();
71
72
73 /*
74 * We have to provide the options we accept to the application. We
75 * need to setup our parameter list and hook it into the recipe
76 * interface.
77 */
78
79 recipe->parameters = cpl_parameterlist_new();
80 cx_assert(recipe->parameters != NULL);
81
82 /*
83 * Fill the parameter list.
84 */
85
86 /* Bias Removal */
87
88 giraffe_bias_config_add(recipe->parameters);
89
90 /* Flat Fielding */
91 /* Not Yet Implemented */
92
93 /* Spectrum Extraction */
94
95 giraffe_extract_config_add(recipe->parameters);
96
97 /* Wavelength Calibration */
98
99 giraffe_wlcalibration_config_add(recipe->parameters);
100
101 /* Arc-lamp spectrum rebinning */
102
103 p = cpl_parameter_new_value("giraffe.wcal.rebin",
104 CPL_TYPE_BOOL,
105 "Rebin extracted arc-lamp spectra.",
106 "giraffe.wcal",
107 TRUE);
108
109 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "wcal-rebin");
110 cpl_parameterlist_append(recipe->parameters, p);
111
112 giraffe_rebin_config_add(recipe->parameters);
113
114 /* Slit geometry calibration */
115
116 p = cpl_parameter_new_value("giraffe.wcal.slitgeometry",
117 CPL_TYPE_BOOL,
118 "Controls the slit geometry calibration.",
119 "giraffe.wcal",
120 FALSE);
121
122 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "wcal-slit");
123 cpl_parameterlist_append(recipe->parameters, p);
124
125 giraffe_sgcalibration_config_add(recipe->parameters);
126
127 return 0;
128
129}
130
131/*
132 * Execute the plugin instance given by the interface.
133 */
134
135static cxint
136giwavecalibration_exec(cpl_plugin* plugin)
137{
138
139 cpl_recipe* recipe = (cpl_recipe*)plugin;
140
141 cxint status = 0;
142
143
144 if (recipe->parameters == NULL || recipe->frames == NULL) {
145 return 1;
146 }
147
148 status = giwavecalibration(recipe->parameters, recipe->frames);
149
150 if (status != 0) {
151 return 1;
152 }
153
154 status = giqcwavecalibration(recipe->frames);
155
156 if (status != 0) {
157 return 1;
158 }
159
160 return 0;
161
162}
163
164
165static cxint
166giwavecalibration_destroy(cpl_plugin* plugin)
167{
168
169 cpl_recipe* recipe = (cpl_recipe*)plugin;
170
171
172 /*
173 * We just destroy what was created during the plugin initialization
174 * phase, i.e. the parameter list. The frame set is managed by the
175 * application which called us, so we must not touch it,
176 */
177
178 cpl_parameterlist_delete(recipe->parameters); recipe->parameters = NULL;
179
180 giraffe_error_clear();
181
182 return 0;
183
184}
185
186/*
187 * The actual recipe starts here.
188 */
189
190static cxint
191giwavecalibration(cpl_parameterlist* config, cpl_frameset* set)
192{
193
194 const cxchar* const fctid = "giwavecalibration";
195
196
197 const cxchar* filename = NULL;
198
199 cxbool rebin = FALSE;
200 cxbool slitgeometry = FALSE;
201
202 cxint status = 0;
203 cxint narcspectrum = 0;
204
205 const cpl_propertylist* properties = NULL;
206
207 cpl_frame* arcspec_frame = NULL;
208 cpl_frame* bpixel_frame = NULL;
209 cpl_frame* mbias_frame = NULL;
210 cpl_frame* mlocy_frame = NULL;
211 cpl_frame* mlocw_frame = NULL;
212 cpl_frame* psfdata_frame = NULL;
213 cpl_frame* slight_frame = NULL;
214 cpl_frame* grating_frame = NULL;
215 cpl_frame* slitgeo_frame = NULL;
216 cpl_frame* lines_frame = NULL;
217 cpl_frame* wcal_frame = NULL;
218 cpl_frame* ldata_frame = NULL;
219 cpl_frame* scal_frame = NULL;
220 cpl_frame* sext_frame = NULL;
221
222 cpl_parameter* p = NULL;
223
224 cpl_matrix* biasareas = NULL;
225
226 GiImage* arcspectrum = NULL;
227 GiImage* bsarcspectrum = NULL;
228 GiImage* slight = NULL;
229 GiImage* mbias = NULL;
230 GiImage* bpixel = NULL;
231
232 GiLocalization* localization = NULL;
233 GiExtraction* extraction = NULL;
234 GiRebinning* rebinning = NULL;
235 GiWCalData* wlsolution = NULL;
236
237 GiTable* fibers = NULL;
238 GiTable* grating = NULL;
239 GiTable* slitgeo = NULL;
240 GiTable* wavelengths = NULL;
241 GiTable* wcal_initial = NULL;
242
243// GiWcalSolution* wcal_solution = NULL;
244
245 GiBiasConfig* bias_config = NULL;
246 GiExtractConfig* extract_config = NULL;
247 GiWCalConfig* wcal_config = NULL;
248
249 GiFrameCreator creator = NULL;
250
251 GiRecipeInfo info = {(cxchar*)fctid, 1, NULL, config};
252
253 GiGroupInfo groups[] = {
254 {GIFRAME_ARC_SPECTRUM, CPL_FRAME_GROUP_RAW},
255 {GIFRAME_BADPIXEL_MAP, CPL_FRAME_GROUP_CALIB},
256 {GIFRAME_BIAS_MASTER, CPL_FRAME_GROUP_CALIB},
257 {GIFRAME_SCATTERED_LIGHT_MODEL, CPL_FRAME_GROUP_CALIB},
258 {GIFRAME_LOCALIZATION_CENTROID, CPL_FRAME_GROUP_CALIB},
259 {GIFRAME_LOCALIZATION_WIDTH, CPL_FRAME_GROUP_CALIB},
260 {GIFRAME_PSF_CENTROID, CPL_FRAME_GROUP_CALIB},
261 {GIFRAME_PSF_WIDTH, CPL_FRAME_GROUP_CALIB},
262 {GIFRAME_PSF_DATA, CPL_FRAME_GROUP_CALIB},
263 {GIFRAME_WAVELENGTH_SOLUTION, CPL_FRAME_GROUP_CALIB},
264 {GIFRAME_SLITSETUP, CPL_FRAME_GROUP_CALIB},
265 {GIFRAME_SLITMASTER, CPL_FRAME_GROUP_CALIB},
266 {GIFRAME_GRATING, CPL_FRAME_GROUP_CALIB},
267 {GIFRAME_LINE_CATALOG, CPL_FRAME_GROUP_CALIB},
268 {GIFRAME_LINE_MASK, CPL_FRAME_GROUP_CALIB},
269 {NULL, CPL_FRAME_GROUP_NONE}
270 };
271
272
273
274 if (!config) {
275 cpl_msg_error(fctid, "Invalid parameter list! Aborting ...");
276 return 1;
277 }
278
279 if (!set) {
280 cpl_msg_error(fctid, "Invalid frame set! Aborting ...");
281 return 1;
282 }
283
284 p = cpl_parameterlist_find(config, "giraffe.wcal.rebin");
285
286 if (p != NULL) {
287 rebin = cpl_parameter_get_bool(p);
288 }
289
290 p = cpl_parameterlist_find(config, "giraffe.wcal.slitgeometry");
291
292 if (p != NULL) {
293 slitgeometry = cpl_parameter_get_bool(p);
294 }
295
296 status = giraffe_frameset_set_groups(set, groups);
297
298 if (status != 0) {
299 cpl_msg_error(fctid, "Setting frame group information failed!");
300 return 1;
301 }
302
303
304 /*************************************************************************
305 Preprocessing
306 *************************************************************************/
307
308 cpl_msg_info(fctid, "Recipe Step : Initialization");
309
310 /*
311 * Verify the frame set contents
312 */
313
314 narcspectrum = cpl_frameset_count_tags(set, GIFRAME_ARC_SPECTRUM);
315
316 if (narcspectrum > 1) {
317 cpl_msg_error(fctid, "Only one arc spectrum frame allowed! "
318 "Aborting...");
319 return 1;
320 }
321 else if (narcspectrum < 1) {
322 cpl_msg_error(fctid, "Arc spectrum frame is missing! "
323 "Aborting...");
324 return 1;
325 }
326
327 arcspec_frame = cpl_frameset_find(set, GIFRAME_ARC_SPECTRUM);
328 bpixel_frame = cpl_frameset_find(set, GIFRAME_BADPIXEL_MAP);
329
330 if (!bpixel_frame) {
331 cpl_msg_info(fctid, "No bad pixel map present in frame set.");
332 }
333
334 mbias_frame = cpl_frameset_find(set, GIFRAME_BIAS_MASTER);
335
336 if (!mbias_frame) {
337 cpl_msg_info(fctid, "No master bias present in frame set.");
338 }
339
340 mlocy_frame = cpl_frameset_find(set, GIFRAME_PSF_CENTROID);
341
342 if (mlocy_frame == NULL) {
343
344 mlocy_frame = cpl_frameset_find(set, GIFRAME_LOCALIZATION_CENTROID);
345
346 if (mlocy_frame == NULL) {
347 cpl_msg_info(fctid, "No master localization (centroid position) "
348 "present in frame set. Aborting ...");
349 return 1;
350 }
351
352 }
353
354 mlocw_frame = cpl_frameset_find(set, GIFRAME_PSF_WIDTH);
355
356 if (mlocw_frame == NULL) {
357
358 mlocw_frame = cpl_frameset_find(set, GIFRAME_LOCALIZATION_WIDTH);
359
360 if (mlocw_frame == NULL) {
361 cpl_msg_info(fctid, "No master localization (spectrum width) "
362 "present in frame set. Aborting ...");
363 return 1;
364 }
365
366 }
367
368 psfdata_frame = cpl_frameset_find(set, GIFRAME_PSF_DATA);
369
370 if (!psfdata_frame) {
371 cpl_msg_info(fctid, "No PSF profile parameters present in frame set.");
372 }
373
374 slight_frame = cpl_frameset_find(set, GIFRAME_SCATTERED_LIGHT_MODEL);
375
376 if (!slight_frame) {
377 cpl_msg_info(fctid, "No scattered light model present in frame set.");
378 }
379
380 grating_frame = cpl_frameset_find(set, GIFRAME_GRATING);
381
382 if (!grating_frame) {
383 cpl_msg_error(fctid, "No grating table present in frame set, "
384 "aborting...");
385 return 1;
386 }
387
388 slitgeo_frame = giraffe_get_slitgeometry(set);
389
390 if (!slitgeo_frame) {
391 cpl_msg_error(fctid, "No slit geometry table present in frame "
392 "set, aborting...");
393 return 1;
394 }
395
396 lines_frame = cpl_frameset_find(set, GIFRAME_LINE_CATALOG);
397
398 if (!lines_frame) {
399 cpl_msg_error(fctid, "No wavelength table present in frame set, "
400 "aborting...");
401 return 1;
402 }
403
404 wcal_frame = cpl_frameset_find(set, GIFRAME_WAVELENGTH_SOLUTION);
405
406 if (!wcal_frame) {
407 cpl_msg_info(fctid, "No wavelength solution present in frame set.");
408 }
409
410 scal_frame = cpl_frameset_find(set, GIFRAME_LINE_MASK);
411
412 if (!scal_frame) {
413
414 if (slitgeometry == TRUE) {
415 cpl_msg_error(fctid, "No line mask present in frame "
416 "set. Aborting ...");
417 return 1;
418 }
419 else {
420 cpl_msg_info(fctid, "No slit geometry mask present in frame "
421 "set.");
422 }
423
424 }
425
426
427 /*************************************************************************
428 Processing
429 *************************************************************************/
430
431 /*
432 * Load bad pixel map if it is present in the frame set.
433 */
434
435 if (bpixel_frame) {
436
437 filename = cpl_frame_get_filename(bpixel_frame);
438
439 bpixel = giraffe_image_new(CPL_TYPE_INT);
440 status = giraffe_image_load(bpixel, filename, 0);
441
442 if (status) {
443 cpl_msg_error(fctid, "Cannot load bad pixel map from '%s'. "
444 "Aborting ...", filename);
445
446 giraffe_image_delete(bpixel);
447 return 1;
448 }
449 }
450
451
452 /*
453 * Load arc spectrum
454 */
455
456 status = 0;
457 filename = cpl_frame_get_filename(arcspec_frame);
458
459 arcspectrum = giraffe_image_new(CPL_TYPE_DOUBLE);
460 status = giraffe_image_load(arcspectrum, filename, 0);
461
462 if (status) {
463 cpl_msg_error(fctid, "Cannot load arc spectrum from '%s'. "
464 "Aborting...", filename);
465
466 giraffe_image_delete(bpixel);
467 giraffe_image_delete(arcspectrum);
468 return 1;
469 }
470
471
472 /*
473 * Prepare bias subtraction
474 */
475
476 cpl_msg_info(fctid, "Recipe Step : Bias Removal");
477
478 bias_config = giraffe_bias_config_create(config);
479
480 /*
481 * Setup user defined areas to use for the bias computation
482 */
483
484 if (bias_config->method == GIBIAS_METHOD_MASTER ||
485 bias_config->method == GIBIAS_METHOD_ZMASTER) {
486
487 if (!mbias_frame) {
488 cpl_msg_error(fctid, "Missing master bias frame! Selected bias "
489 "removal method requires a master bias "
490 "frame!");
491
492 giraffe_image_delete(bpixel);
493 giraffe_image_delete(arcspectrum);
494 giraffe_bias_config_destroy(bias_config);
495
496 return 1;
497 }
498 else {
499
500 status = 0;
501 filename = cpl_frame_get_filename(mbias_frame);
502
503 mbias = giraffe_image_new(CPL_TYPE_DOUBLE);
504 status = giraffe_image_load(mbias, filename, 0);
505
506 if (status) {
507 cpl_msg_error(fctid, "Cannot load master bias from '%s'. "
508 "Aborting ...", filename);
509
510 giraffe_image_delete(bpixel);
511 giraffe_image_delete(arcspectrum);
513 giraffe_bias_config_destroy(bias_config);
514
515 return 1;
516 }
517 }
518 }
519
520
521 /*
522 * Compute and remove the bias from the stacked flat field frame.
523 */
524
525 bsarcspectrum = giraffe_image_new(CPL_TYPE_DOUBLE);
526
527 status = giraffe_bias_remove(bsarcspectrum, arcspectrum, mbias, bpixel,
528 biasareas, bias_config);
529
530 giraffe_image_delete(arcspectrum);
531 arcspectrum = NULL;
532
533 if (mbias) {
535 mbias = NULL;
536 }
537
538 giraffe_bias_config_destroy(bias_config);
539 bias_config = NULL;
540
541 if (status) {
542 cpl_msg_error(fctid, "Bias removal failed. Aborting ...");
543
544 giraffe_image_delete(bpixel);
545 giraffe_image_delete(bsarcspectrum);
546 return 1;
547 }
548
549
550 /*
551 * Determine fiber setup
552 */
553
554 cpl_msg_info(fctid, "Recipe Step : Fiber Setup");
555
556 cpl_msg_info(fctid, "Building fiber setup for frame '%s'.",
557 cpl_frame_get_filename(arcspec_frame));
558
559 fibers = giraffe_fibers_setup(arcspec_frame, mlocy_frame);
560
561 if (!fibers) {
562 cpl_msg_error(fctid, "Cannot create fiber setup for frame '%s'! "
563 "Aborting ...", cpl_frame_get_filename(arcspec_frame));
564
565 giraffe_image_delete(bpixel);
566 giraffe_image_delete(bsarcspectrum);
567
568 return 1;
569 }
570
571 cpl_msg_info(fctid, "Fiber reference setup taken from localization "
572 "frame '%s'.", cpl_frame_get_filename(mlocy_frame));
573
574
575 /*
576 * Load spectrum localization.
577 */
578
579 localization = giraffe_localization_new();
580
581 filename = cpl_frame_get_filename(mlocy_frame);
582 status = 0;
583
584 localization->locy = giraffe_image_new(CPL_TYPE_DOUBLE);
585 status = giraffe_image_load(localization->locy, filename, 0);
586
587 if (status) {
588 cpl_msg_error(fctid, "Cannot load localization (centroid "
589 "position) frame from '%s'. Aborting ...",
590 filename);
591
592 giraffe_localization_destroy(localization);
593 giraffe_image_delete(bpixel);
594 giraffe_image_delete(bsarcspectrum);
595 giraffe_table_delete(fibers);
596
597 return 1;
598
599 }
600
601
602 filename = cpl_frame_get_filename(mlocw_frame);
603 status = 0;
604
605 localization->locw = giraffe_image_new(CPL_TYPE_DOUBLE);
606 status = giraffe_image_load(localization->locw, filename, 0);
607
608 if (status) {
609 cpl_msg_error(fctid, "Cannot load localization (spectrum width) "
610 "frame from '%s'. Aborting ...", filename);
611
612 giraffe_localization_destroy(localization);
613 giraffe_image_delete(bpixel);
614 giraffe_image_delete(bsarcspectrum);
615 giraffe_table_delete(fibers);
616
617 return 1;
618
619 }
620
621
622 /*
623 * Perform spectrum extraction on the master flat field.
624 */
625
626 cpl_msg_info(fctid, "Recipe Step : Spectrum Extraction");
627
628 if (slight_frame) {
629
630 filename = cpl_frame_get_filename(slight_frame);
631 status = 0;
632
633 slight = giraffe_image_new(CPL_TYPE_DOUBLE);
634 status = giraffe_image_load(slight, filename, 0);
635
636 if (status) {
637 cpl_msg_error(fctid, "Cannot load scattered light model from "
638 "'%s'. Aborting ...", filename);
639
640 giraffe_image_delete(bpixel);
641 giraffe_image_delete(bsarcspectrum);
642 giraffe_table_delete(fibers);
643 giraffe_localization_destroy(localization);
644 giraffe_image_delete(slight);
645
646 return 1;
647
648 }
649
650 }
651
652 extract_config = giraffe_extract_config_create(config);
653
654 if ((extract_config->emethod == GIEXTRACT_OPTIMAL) ||
655 (extract_config->emethod == GIEXTRACT_HORNE)) {
656
657 if (psfdata_frame == NULL) {
658
659 const cxchar* emethod = "Optimal";
660
661 if (extract_config->emethod == GIEXTRACT_HORNE) {
662 emethod = "Horne";
663 }
664
665 cpl_msg_error(fctid, "%s spectrum extraction requires PSF "
666 "profile data. Aborting ...", emethod);
667
668 giraffe_extract_config_destroy(extract_config);
669 extract_config = NULL;
670
671 if (slight != NULL) {
672 giraffe_image_delete(slight);
673 slight = NULL;
674 }
675
676 giraffe_localization_destroy(localization);
677 localization = NULL;
678
679 if (bpixel) {
680 giraffe_image_delete(bpixel);
681 bpixel = NULL;
682 }
683
684 giraffe_table_delete(fibers);
685 fibers = NULL;
686
687 giraffe_image_delete(bsarcspectrum);
688 bsarcspectrum = NULL;
689
690 return 1;
691
692 }
693 else {
694
695 filename = cpl_frame_get_filename(psfdata_frame);
696 status = 0;
697
698 localization->psf = giraffe_psfdata_new();
699 status = giraffe_psfdata_load(localization->psf, filename);
700
701 if (status) {
702 cpl_msg_error(fctid, "Cannot load PSF profile data frame from "
703 "'%s'. Aborting ...", filename);
704
705 giraffe_extract_config_destroy(extract_config);
706 extract_config = NULL;
707
708 if (slight != NULL) {
709 giraffe_image_delete(slight);
710 slight = NULL;
711 }
712
713 giraffe_localization_destroy(localization);
714 localization = NULL;
715
716 if (bpixel) {
717 giraffe_image_delete(bpixel);
718 bpixel = NULL;
719 }
720
721 giraffe_table_delete(fibers);
722 fibers = NULL;
723
724 giraffe_image_delete(bsarcspectrum);
725 bsarcspectrum = NULL;
726
727 return 1;
728
729 }
730
731 }
732
733 }
734
735
736 extraction = giraffe_extraction_new();
737
738 status = giraffe_extract_spectra(extraction, bsarcspectrum, fibers,
739 localization, bpixel, slight,
740 extract_config);
741
742 if (status) {
743 cpl_msg_error(fctid, "Spectrum extraction failed! Aborting ...");
744
745 giraffe_image_delete(bpixel);
746 giraffe_image_delete(bsarcspectrum);
747 giraffe_table_delete(fibers);
748 giraffe_localization_destroy(localization);
749 giraffe_image_delete(slight);
750 giraffe_extract_config_destroy(extract_config);
751 giraffe_extraction_destroy(extraction);
752
753 return 1;
754 }
755
756 giraffe_image_delete(slight);
757 slight = NULL;
758
759 giraffe_image_delete(bpixel);
760 bpixel = NULL;
761
762 giraffe_image_delete(bsarcspectrum);
763 bsarcspectrum = NULL;
764
765 giraffe_extract_config_destroy(extract_config);
766 extract_config = NULL;
767
768 /*
769 * Save the spectrum extraction results and register them as
770 * products.
771 */
772
773 cpl_msg_info(fctid, "Writing extracted spectra ...");
774
775 /* Extracted spectra */
776
777 giraffe_image_add_info(extraction->spectra, &info, set);
778
779 sext_frame = giraffe_frame_create_image(extraction->spectra,
780 GIFRAME_ARC_LAMP_EXTSPECTRA,
781 CPL_FRAME_LEVEL_INTERMEDIATE,
782 TRUE, TRUE);
783
784 if (sext_frame == NULL) {
785 cpl_msg_error(fctid, "Cannot create local file! Aborting ...");
786
787 giraffe_table_delete(fibers);
788
789 giraffe_localization_destroy(localization);
790 giraffe_extraction_destroy(extraction);
791
792 return 1;
793 }
794
795 status = giraffe_fiberlist_attach(sext_frame, fibers);
796
797 if (status) {
798 cpl_msg_error(fctid, "Cannot attach fiber setup to local file '%s'! "
799 "Aborting ...", cpl_frame_get_filename(sext_frame));
800
801 cpl_frame_delete(sext_frame);
802
803 giraffe_table_delete(fibers);
804
805 giraffe_localization_destroy(localization);
806 giraffe_extraction_destroy(extraction);
807
808 return 1;
809 }
810
811 cpl_frameset_insert(set, sext_frame);
812
813 /* Extracted spectra errors */
814
815 giraffe_image_add_info(extraction->error, &info, set);
816
817 sext_frame = giraffe_frame_create_image(extraction->error,
818 GIFRAME_ARC_LAMP_EXTERRORS,
819 CPL_FRAME_LEVEL_INTERMEDIATE,
820 TRUE, TRUE);
821
822 if (sext_frame == NULL) {
823 cpl_msg_error(fctid, "Cannot create local file! Aborting ...");
824
825 giraffe_table_delete(fibers);
826
827 giraffe_localization_destroy(localization);
828 giraffe_extraction_destroy(extraction);
829
830 return 1;
831 }
832
833 status = giraffe_fiberlist_attach(sext_frame, fibers);
834
835 if (status) {
836 cpl_msg_error(fctid, "Cannot attach fiber setup to local file '%s'! "
837 "Aborting ...", cpl_frame_get_filename(sext_frame));
838
839 cpl_frame_delete(sext_frame);
840
841 giraffe_table_delete(fibers);
842
843 giraffe_localization_destroy(localization);
844 giraffe_extraction_destroy(extraction);
845
846 return 1;
847 }
848
849 cpl_frameset_insert(set, sext_frame);
850
851 /* Extracted spectra pixels */
852
853 if (extraction->npixels != NULL) {
854
855 giraffe_image_add_info(extraction->npixels, &info, set);
856
857 sext_frame = giraffe_frame_create_image(extraction->npixels,
858 GIFRAME_ARC_LAMP_EXTPIXELS,
859 CPL_FRAME_LEVEL_INTERMEDIATE,
860 TRUE, TRUE);
861
862 if (sext_frame == NULL) {
863 cpl_msg_error(fctid, "Cannot create local file! Aborting ...");
864
865 giraffe_table_delete(fibers);
866
867 giraffe_localization_destroy(localization);
868 giraffe_extraction_destroy(extraction);
869
870 return 1;
871 }
872
873 status = giraffe_fiberlist_attach(sext_frame, fibers);
874
875 if (status) {
876 cpl_msg_error(fctid, "Cannot attach fiber setup to local file '%s'! "
877 "Aborting ...", cpl_frame_get_filename(sext_frame));
878
879 cpl_frame_delete(sext_frame);
880
881 giraffe_table_delete(fibers);
882
883 giraffe_localization_destroy(localization);
884 giraffe_extraction_destroy(extraction);
885
886 return 1;
887 }
888
889 cpl_frameset_insert(set, sext_frame);
890
891 }
892
893 /* Extracted spectra centroids */
894
895 giraffe_image_add_info(extraction->centroid, &info, set);
896
897 sext_frame = giraffe_frame_create_image(extraction->centroid,
898 GIFRAME_ARC_LAMP_EXTTRACE,
899 CPL_FRAME_LEVEL_INTERMEDIATE,
900 TRUE, TRUE);
901
902 if (sext_frame == NULL) {
903 cpl_msg_error(fctid, "Cannot create local file! Aborting ...");
904
905 giraffe_table_delete(fibers);
906
907 giraffe_localization_destroy(localization);
908 giraffe_extraction_destroy(extraction);
909
910 return 1;
911 }
912
913 status = giraffe_fiberlist_attach(sext_frame, fibers);
914
915 if (status) {
916 cpl_msg_error(fctid, "Cannot attach fiber setup to local file '%s'! "
917 "Aborting ...", cpl_frame_get_filename(sext_frame));
918
919 cpl_frame_delete(sext_frame);
920
921 giraffe_table_delete(fibers);
922
923 giraffe_localization_destroy(localization);
924 giraffe_extraction_destroy(extraction);
925
926 return 1;
927 }
928
929 cpl_frameset_insert(set, sext_frame);
930
931 /* Extraction model spectra */
932
933 if (extraction->model != NULL) {
934
935 giraffe_image_add_info(extraction->model, &info, set);
936
937 sext_frame = giraffe_frame_create_image(extraction->model,
938 GIFRAME_ARC_LAMP_EXTMODEL,
939 CPL_FRAME_LEVEL_FINAL,
940 TRUE, TRUE);
941
942 if (sext_frame == NULL) {
943 cpl_msg_error(fctid, "Cannot create local file! Aborting ...");
944
945 giraffe_table_delete(fibers);
946
947 giraffe_localization_destroy(localization);
948 giraffe_extraction_destroy(extraction);
949
950 return 1;
951 }
952
953 status = giraffe_fiberlist_attach(sext_frame, fibers);
954
955 if (status != 0) {
956 cpl_msg_error(fctid, "Cannot attach fiber setup to local file '%s'! "
957 "Aborting ...", cpl_frame_get_filename(sext_frame));
958
959 cpl_frame_delete(sext_frame);
960
961 giraffe_table_delete(fibers);
962
963 giraffe_localization_destroy(localization);
964 giraffe_extraction_destroy(extraction);
965
966 return 1;
967 }
968
969 cpl_frameset_insert(set, sext_frame);
970
971 }
972
973 /*
974 * Perform Wavelength Calibration
975 */
976
977 cpl_msg_info(fctid, "Recipe Step : Wavelength Calibration");
978
979 filename = cpl_frame_get_filename(grating_frame);
980 status = 0;
981
982 grating = giraffe_table_new();
983 status = giraffe_table_load(grating, filename, 1, NULL);
984
985 if (status) {
986 cpl_msg_error(fctid, "Cannot load grating table from '%s'. "
987 "Aborting ...", filename);
988
989 giraffe_table_delete(fibers);
990 giraffe_localization_destroy(localization);
991 giraffe_extraction_destroy(extraction);
992
993 return 1;
994 }
995
996
997 filename = cpl_frame_get_filename(slitgeo_frame);
998
999 slitgeo = giraffe_slitgeometry_load(fibers, filename, 1, NULL);
1000
1001 if (slitgeo == NULL) {
1002 cpl_msg_error(fctid, "Cannot load slit geometry table from '%s'. "
1003 "Aborting ...", filename);
1004
1005 giraffe_table_delete(fibers);
1006 giraffe_localization_destroy(localization);
1007 giraffe_extraction_destroy(extraction);
1008 giraffe_table_delete(grating);
1009
1010 return 1;
1011 }
1012 else {
1013
1014 /*
1015 * Check whether the contains the positions for all fibers
1016 * provided by the fiber setup. If this is not the case
1017 * this is an error.
1018 */
1019
1020 if (giraffe_fiberlist_compare(slitgeo, fibers) != 1) {
1021 cpl_msg_error(fctid, "Slit geometry data from '%s' is not "
1022 "applicable for current fiber setup! "
1023 "Aborting ...", filename);
1024
1025 giraffe_table_delete(slitgeo);
1026 giraffe_table_delete(fibers);
1027 giraffe_localization_destroy(localization);
1028 giraffe_extraction_destroy(extraction);
1029 giraffe_table_delete(grating);
1030
1031 return 1;
1032 }
1033
1034 }
1035
1036
1037 filename = cpl_frame_get_filename(lines_frame);
1038 status = 0;
1039
1040 wavelengths = giraffe_table_new();
1041 status = giraffe_table_load(wavelengths, filename, 1, NULL);
1042
1043 if (status) {
1044 cpl_msg_error(fctid, "Cannot load arc-line data from '%s'. "
1045 "Aborting ...", filename);
1046
1047 giraffe_table_delete(fibers);
1048 giraffe_localization_destroy(localization);
1049 giraffe_extraction_destroy(extraction);
1050 giraffe_table_delete(grating);
1051 giraffe_table_delete(slitgeo);
1052
1053 return 1;
1054
1055 }
1056
1057 if (wcal_frame != NULL) {
1058
1059 wcal_initial = giraffe_table_new();
1060
1061 filename = cpl_frame_get_filename(wcal_frame);
1062 status = giraffe_table_load(wcal_initial, filename, 1, NULL);
1063
1064 if (status) {
1065 cpl_msg_error(fctid, "Cannot load initial wavelength solution "
1066 "from '%s'. Aborting ...", filename);
1067
1068 giraffe_table_delete(wcal_initial);
1069
1070 giraffe_table_delete(fibers);
1071 giraffe_localization_destroy(localization);
1072 giraffe_extraction_destroy(extraction);
1073 giraffe_table_delete(grating);
1074 giraffe_table_delete(slitgeo);
1075
1076 return 1;
1077
1078 }
1079
1080 }
1081
1082 wcal_config = giraffe_wlcalibration_config_create(config);
1083
1084 if (wcal_config == NULL) {
1085
1086 cpl_msg_error(fctid, "Could not create wavelength calibration "
1087 "setup: error parsing configuration parameters! "
1088 "Aborting ...");
1089 giraffe_table_delete(fibers);
1090 giraffe_localization_destroy(localization);
1091 giraffe_extraction_destroy(extraction);
1092 giraffe_table_delete(grating);
1093 giraffe_table_delete(slitgeo);
1094 giraffe_table_delete(wavelengths);
1095 giraffe_table_delete(wcal_initial);
1096
1097 return 1;
1098
1099 }
1100
1101 wlsolution = giraffe_wcaldata_new();
1102
1103 status = giraffe_calibrate_wavelength(wlsolution, extraction,
1104 localization, fibers, slitgeo,
1105 grating, wavelengths, wcal_initial,
1106 wcal_config);
1107
1108 if (status) {
1109 cpl_msg_error(fctid, "Error during wavelength calibration, "
1110 "aborting...");
1111
1112 giraffe_table_delete(fibers);
1113 giraffe_localization_destroy(localization);
1114 giraffe_extraction_destroy(extraction);
1115 giraffe_table_delete(grating);
1116 giraffe_table_delete(slitgeo);
1117 giraffe_table_delete(wavelengths);
1118 giraffe_table_delete(wcal_initial);
1119
1120 giraffe_wcaldata_delete(wlsolution);
1122
1123 return 1;
1124
1125 }
1126
1128 wcal_config = NULL;
1129
1130 giraffe_table_delete(wcal_initial);
1131 wcal_initial = NULL;
1132
1133 giraffe_table_delete(wavelengths);
1134 wavelengths = NULL;
1135
1136
1137 /*
1138 * Save and register the wavelength calibration results.
1139 */
1140
1141 /* Coefficients of the x-residuals fit */
1142
1143 giraffe_table_add_info(wlsolution->coeffs, &info, set);
1144
1145 wcal_frame = giraffe_frame_create_table(wlsolution->coeffs,
1146 GIFRAME_WAVELENGTH_SOLUTION,
1147 CPL_FRAME_LEVEL_FINAL,
1148 TRUE, TRUE);
1149
1150 if (wcal_frame == NULL) {
1151
1152 cpl_msg_error(fctid, "Cannot create local file! Aborting ...");
1153
1154 giraffe_table_delete(fibers);
1155 giraffe_localization_destroy(localization);
1156 giraffe_extraction_destroy(extraction);
1157 giraffe_table_delete(grating);
1158 giraffe_table_delete(slitgeo);
1159
1160 giraffe_wcaldata_delete(wlsolution);
1161
1162 return 1;
1163
1164 }
1165
1166 cpl_frameset_insert(set, wcal_frame);
1167
1168 /* Lines data */
1169
1170 properties = giraffe_table_get_properties(wlsolution->coeffs);
1171 creator = (GiFrameCreator)giraffe_linedata_writer;
1172
1173 ldata_frame = giraffe_frame_create(GIFRAME_LINE_DATA,
1174 CPL_FRAME_LEVEL_FINAL,
1175 properties, wlsolution->linedata,
1176 NULL,
1177 creator);
1178
1179 if (ldata_frame == NULL) {
1180
1181 cpl_msg_error(fctid, "Cannot create local file! Aborting ...");
1182
1183 giraffe_table_delete(fibers);
1184 giraffe_localization_destroy(localization);
1185 giraffe_extraction_destroy(extraction);
1186 giraffe_table_delete(grating);
1187 giraffe_table_delete(slitgeo);
1188
1189 giraffe_wcaldata_delete(wlsolution);
1190
1191 properties = NULL;
1192
1193 return 1;
1194
1195 }
1196
1197 properties = NULL;
1198
1199 giraffe_linedata_delete(wlsolution->linedata);
1200 wlsolution->linedata = NULL;
1201
1202 cpl_frameset_insert(set, ldata_frame);
1203
1204
1205 /*
1206 * Optional slit geometry calibration. Note that this step requires a
1207 * rebinned arc-lamp frame as input!
1208 */
1209
1210 if (slitgeometry == TRUE) {
1211
1212 cpl_frame* slit_frame = NULL;
1213
1214 GiSGCalConfig* scal_config = NULL;
1215
1216 GiTable* mask = NULL;
1217 GiTable* slit = NULL;
1218
1219
1220 cpl_msg_info(fctid, "Calibrating slit geometry ...");
1221
1222 scal_config = giraffe_sgcalibration_config_create(config);
1223
1224
1225 filename = cpl_frame_get_filename(scal_frame);
1226
1227 mask = giraffe_table_new();
1228 status = giraffe_table_load(mask, filename, 1, NULL);
1229
1230 if (status != 0) {
1231 cpl_msg_error(fctid, "Cannot load slit geometry mask from '%s'. "
1232 "Aborting ...", filename);
1233
1235
1237
1238 giraffe_wcaldata_delete(wlsolution);
1239
1240 giraffe_localization_destroy(localization);
1241 giraffe_extraction_destroy(extraction);
1242
1243 giraffe_table_delete(fibers);
1244 giraffe_table_delete(grating);
1245 giraffe_table_delete(slitgeo);
1246
1247 return 1;
1248
1249 }
1250
1251 slit = giraffe_table_new();
1252
1253 status = giraffe_calibrate_slit(slit, extraction, localization, fibers,
1254 wlsolution->coeffs, slitgeo, grating,
1255 mask, scal_config);
1256
1257 if (status != 0) {
1258 cpl_msg_error(fctid, "Slit geometry calibration failed! "
1259 "Aborting ...");
1260
1262
1265
1266 giraffe_wcaldata_delete(wlsolution);
1267
1268 giraffe_localization_destroy(localization);
1269 giraffe_extraction_destroy(extraction);
1270
1271 giraffe_table_delete(fibers);
1272 giraffe_table_delete(grating);
1273 giraffe_table_delete(slitgeo);
1274
1275 return 1;
1276
1277 }
1278
1279
1280 /*
1281 * Save and register the slit geometry calibration results.
1282 */
1283
1284
1285 giraffe_table_add_info(slit, &info, set);
1286
1287 slit_frame = giraffe_slitgeometry_save(slit);
1288
1289 if (!slit_frame) {
1290
1291 cpl_msg_error(fctid, "Cannot create local file! Aborting ...");
1292
1294
1297
1298 giraffe_wcaldata_delete(wlsolution);
1299
1300 giraffe_localization_destroy(localization);
1301 giraffe_extraction_destroy(extraction);
1302
1303 giraffe_table_delete(fibers);
1304 giraffe_table_delete(grating);
1305 giraffe_table_delete(slitgeo);
1306
1307 return 1;
1308 }
1309
1310 cpl_frameset_insert(set, slit_frame);
1311
1314
1315
1316 /*
1317 * Replace the slit geometry table with the new one.
1318 */
1319
1320 giraffe_table_delete(slitgeo);
1321 slitgeo = slit;
1322
1323 }
1324
1325
1326 /*
1327 * Optional rebinning of the previously extracted arc-lamp spectra.
1328 */
1329
1330 if (rebin == TRUE) {
1331
1332 cpl_frame* rbin_frame = NULL;
1333
1334 GiRebinConfig* rebin_config;
1335
1336
1337 cpl_msg_info(fctid, "Recipe Step : Spectrum Rebinning");
1338
1339 rebin_config = giraffe_rebin_config_create(config);
1340
1341 rebinning = giraffe_rebinning_new();
1342
1343 status = giraffe_rebin_spectra(rebinning, extraction, fibers,
1344 localization, grating, slitgeo,
1345 wlsolution->coeffs, rebin_config);
1346
1347 if (status) {
1348 cpl_msg_error(fctid, "Rebinning of arc-lamp spectra failed! "
1349 "Aborting...");
1350
1351 giraffe_wcaldata_delete(wlsolution);
1352
1353 giraffe_rebinning_destroy(rebinning);
1354 giraffe_localization_destroy(localization);
1355 giraffe_extraction_destroy(extraction);
1356
1357 giraffe_table_delete(grating);
1358 giraffe_table_delete(slitgeo);
1359 giraffe_table_delete(fibers);
1360
1361 giraffe_rebin_config_destroy(rebin_config);
1362
1363 return 1;
1364
1365 }
1366
1367 giraffe_rebin_config_destroy(rebin_config);
1368
1369 /*
1370 * Save and register the results of the spectrum rebinning.
1371 */
1372
1373 /* Rebinned spectra */
1374
1375 giraffe_image_add_info(rebinning->spectra, &info, set);
1376
1377 rbin_frame = giraffe_frame_create_image(rebinning->spectra,
1378 GIFRAME_ARC_LAMP_RBNSPECTRA,
1379 CPL_FRAME_LEVEL_FINAL,
1380 TRUE, TRUE);
1381
1382 if (rbin_frame == NULL) {
1383
1384 cpl_msg_error(fctid, "Cannot create local file! Aborting ...");
1385
1386 giraffe_wcaldata_delete(wlsolution);
1387
1388 giraffe_rebinning_destroy(rebinning);
1389 giraffe_localization_destroy(localization);
1390 giraffe_extraction_destroy(extraction);
1391
1392 giraffe_table_delete(grating);
1393 giraffe_table_delete(slitgeo);
1394 giraffe_table_delete(fibers);
1395
1396 return 1;
1397
1398 }
1399
1400 status = giraffe_fiberlist_attach(rbin_frame, fibers);
1401
1402 if (status) {
1403 cpl_msg_error(fctid, "Cannot attach fiber setup to local "
1404 "file '%s'! Aborting ...",
1405 cpl_frame_get_filename(rbin_frame));
1406
1407 giraffe_wcaldata_delete(wlsolution);
1408
1409 giraffe_rebinning_destroy(rebinning);
1410 giraffe_localization_destroy(localization);
1411 giraffe_extraction_destroy(extraction);
1412
1413 giraffe_table_delete(grating);
1414 giraffe_table_delete(slitgeo);
1415 giraffe_table_delete(fibers);
1416
1417 cpl_frame_delete(rbin_frame);
1418
1419 return 1;
1420
1421 }
1422
1423 cpl_frameset_insert(set, rbin_frame);
1424
1425 /* Rebinned spectra errors */
1426
1427 giraffe_image_add_info(rebinning->errors, &info, set);
1428
1429 rbin_frame = giraffe_frame_create_image(rebinning->errors,
1430 GIFRAME_ARC_LAMP_RBNERRORS,
1431 CPL_FRAME_LEVEL_FINAL,
1432 TRUE, TRUE);
1433
1434 if (rbin_frame == NULL) {
1435
1436 cpl_msg_error(fctid, "Cannot create local file! Aborting ...");
1437
1438 giraffe_wcaldata_delete(wlsolution);
1439
1440 giraffe_rebinning_destroy(rebinning);
1441 giraffe_localization_destroy(localization);
1442 giraffe_extraction_destroy(extraction);
1443
1444 giraffe_table_delete(grating);
1445 giraffe_table_delete(slitgeo);
1446 giraffe_table_delete(fibers);
1447
1448 return 1;
1449
1450 }
1451
1452 status = giraffe_fiberlist_attach(rbin_frame, fibers);
1453
1454 if (status) {
1455
1456 cpl_msg_error(fctid, "Cannot attach fiber setup to local "
1457 "file '%s'! Aborting ...",
1458 cpl_frame_get_filename(rbin_frame));
1459
1460 giraffe_wcaldata_delete(wlsolution);
1461
1462 giraffe_rebinning_destroy(rebinning);
1463 giraffe_localization_destroy(localization);
1464 giraffe_extraction_destroy(extraction);
1465
1466 giraffe_table_delete(grating);
1467 giraffe_table_delete(slitgeo);
1468 giraffe_table_delete(fibers);
1469
1470 cpl_frame_delete(rbin_frame);
1471
1472 return 1;
1473
1474 }
1475
1476 cpl_frameset_insert(set, rbin_frame);
1477
1478 }
1479
1480
1481 /*
1482 * Postprocessing
1483 */
1484
1485 giraffe_table_delete(fibers);
1486 fibers = NULL;
1487
1488 giraffe_localization_destroy(localization);
1489 localization = NULL;
1490
1491 giraffe_extraction_destroy(extraction);
1492 extraction = NULL;
1493
1494 if (rebinning != NULL) {
1495 giraffe_rebinning_destroy(rebinning);
1496 rebinning = NULL;
1497 }
1498
1499 giraffe_table_delete(grating);
1500 grating = NULL;
1501
1502 giraffe_table_delete(slitgeo);
1503 slitgeo = NULL;
1504
1505 giraffe_wcaldata_delete(wlsolution);
1506 wlsolution = NULL;
1507
1508 return 0;
1509
1510}
1511
1512
1513static cxint
1514giqcwavecalibration(cpl_frameset* set)
1515{
1516
1517 const cxchar* const fctid = "giqcwavecalibration";
1518
1519
1520 cxint i = 0;
1521 cxint j = 0;
1522 cxint nx = 0;
1523 cxint ny = 0;
1524 cxint npixel = 0;
1525 cxint nsaturated = 0;
1526 cxint status = 0;
1527
1528 const cxdouble rmsscale = 3.;
1529 const cxdouble saturation = 60000.;
1530 const cxdouble* pixels = NULL;
1531
1532 cxdouble efficiency[2] = {0., 0.};
1533 cxdouble wlcenter = 0.;
1534 cxdouble mean = 0.;
1535 cxdouble rms = 0.;
1536 cxdouble pixel2nm = 1.;
1537 cxdouble fwhm_domain[2] = {0., 100.};
1538 cxdouble* _tdata = NULL;
1539
1540 cpl_propertylist* properties = NULL;
1541 cpl_propertylist* qclog = NULL;
1542
1543 cpl_frame* rframe = NULL;
1544 cpl_frame* pframe = NULL;
1545
1546 const cpl_image* _rimage = NULL;
1547 const cpl_image* _pimage = NULL;
1548
1549 cpl_image* _test = NULL;
1550 cpl_image* _test0 = NULL;
1551 cpl_image* _test1 = NULL;
1552
1553 cpl_table* _ptable = NULL;
1554
1555 GiImage* rimage = NULL;
1556 GiImage* pimage = NULL;
1557
1558 GiTable* ptable = NULL;
1559
1560 GiLineData* plines = NULL;
1561
1562 GiPaf* qc = NULL;
1563
1564 GiWindow w;
1565
1566
1567
1568 cpl_msg_info(fctid, "Computing QC1 parameters ...");
1569
1570
1571 /*
1572 * Compute lamp efficiencies from the rebinned frame if
1573 * it is available. If not the efficiencies are set to 0.
1574 */
1575
1576 pframe = giraffe_get_frame(set, GIFRAME_ARC_LAMP_EXTSPECTRA,
1577 CPL_FRAME_GROUP_PRODUCT);
1578
1579 if (pframe == NULL) {
1580
1581 cpl_msg_warning(fctid, "Product '%s' not found.",
1582 GIFRAME_ARC_LAMP_EXTSPECTRA);
1583
1584 cpl_msg_warning(fctid, "Setting lamp efficiencies (%s, %s) to 0.",
1585 GIALIAS_QCLAMP, GIALIAS_QCLAMP_SIMCAL);
1586
1587 efficiency[0] = 0.;
1588 efficiency[1] = 0.;
1589
1590 }
1591
1592
1593 pimage = giraffe_image_new(CPL_TYPE_DOUBLE);
1594 status = giraffe_image_load(pimage, cpl_frame_get_filename(pframe), 0);
1595
1596 if (status != 0) {
1597 cpl_msg_error(fctid, "Could not load extracted spectra '%s'!",
1598 cpl_frame_get_filename(pframe));
1599
1600 giraffe_image_delete(pimage);
1601 pimage = NULL;
1602
1603 giraffe_paf_delete(qc);
1604 qc = NULL;
1605
1606 return 1;
1607 }
1608
1609 _pimage = giraffe_image_get(pimage);
1610 cx_assert(_pimage != NULL);
1611
1612
1613 ptable = giraffe_table_new();
1614 status = giraffe_table_load(ptable, cpl_frame_get_filename(pframe), 1,
1615 NULL);
1616
1617 if (status != 0) {
1618 cpl_msg_error(fctid, "Could not load extracted spectra fiber setup!");
1619
1620 giraffe_table_delete(ptable);
1621 ptable = NULL;
1622
1623 giraffe_image_delete(pimage);
1624 pimage = NULL;
1625
1626 giraffe_paf_delete(qc);
1627 qc = NULL;
1628
1629 return 1;
1630 }
1631
1632 _ptable = giraffe_table_get(ptable);
1633 cx_assert(_ptable != NULL);
1634
1635 if (cpl_table_has_column(_ptable, "RP") == FALSE) {
1636
1637 cpl_msg_warning(fctid, "Column 'RP' not found in fiber setup table!");
1638 cpl_msg_warning(fctid, "Setting lamp efficiencies (%s, %s) to 0.",
1639 GIALIAS_QCLAMP, GIALIAS_QCLAMP_SIMCAL);
1640
1641 efficiency[0] = 0.;
1642 efficiency[1] = 0.;
1643
1644 }
1645 else {
1646
1647 properties = giraffe_image_get_properties(pimage);
1648 cx_assert(properties != NULL);
1649
1650 if (cpl_propertylist_has(properties, GIALIAS_EXPTIME) == FALSE) {
1651
1652 cpl_msg_warning(fctid, "Property '%s' not found in '%s'.",
1653 GIALIAS_EXPTIME, cpl_frame_get_filename(rframe));
1654 cpl_msg_warning(fctid, "Setting lamp efficiencies (%s, %s) to 0.",
1655 GIALIAS_QCLAMP, GIALIAS_QCLAMP_SIMCAL);
1656
1657 efficiency[0] = 0.;
1658 efficiency[1] = 0.;
1659
1660 }
1661 else {
1662
1663 cxint fiber = 0;
1664 cxint nb = cpl_image_get_size_y(_pimage);
1665 cxint nf[2] = {0, 0};
1666
1667 cxdouble exptime = cpl_propertylist_get_double(properties,
1668 GIALIAS_EXPTIME);
1669 cxdouble* _sum = NULL;
1670
1671 cpl_image* sum = NULL;
1672
1673
1674 sum = cpl_image_collapse_create(_pimage, 0);
1675 _sum = cpl_image_get_data_double(sum);
1676
1677 for (fiber = 0; fiber < cpl_table_get_nrow(_ptable); ++fiber) {
1678
1679 cxint rp = cpl_table_get_int(_ptable, "RP", fiber, NULL);
1680
1681 if (rp == -1) {
1682 efficiency[1] += _sum[fiber];
1683 ++nf[1];
1684 }
1685 else {
1686 efficiency[0] += _sum[fiber];
1687 ++nf[0];
1688 }
1689
1690 }
1691
1692 _sum = NULL;
1693
1694 cpl_image_delete(sum);
1695 sum = NULL;
1696
1697 if (nf[0] == 0) {
1698 cpl_msg_warning(fctid, "No OzPoz fibers found in the "
1699 "current fiber setup.");
1700 cpl_msg_warning(fctid, "Setting lamp efficiency (%s) to 0.",
1701 GIALIAS_QCLAMP);
1702 efficiency[0] = 0.;
1703 }
1704 else {
1705 efficiency[0] /= nf[0] * nb * exptime;
1706 }
1707
1708 if (nf[1] == 0) {
1709 cpl_msg_warning(fctid, "No simultaneous calibration fibers "
1710 "found in the current fiber setup.");
1711 cpl_msg_warning(fctid, "Setting lamp efficiency (%s) to 0.",
1712 GIALIAS_QCLAMP_SIMCAL);
1713 efficiency[1] = 0.;
1714 }
1715 else {
1716 efficiency[1] /= nf[1] * nb * exptime;
1717 }
1718
1719 }
1720
1721 properties = NULL;
1722
1723 }
1724
1725 _ptable = NULL;
1726 _pimage = NULL;
1727
1728 giraffe_table_delete(ptable);
1729 ptable = NULL;
1730
1731 giraffe_image_delete(pimage);
1732 pimage = NULL;
1733
1734
1735 /*
1736 * Load first raw image as reference
1737 */
1738
1739 rframe = cpl_frameset_find(set, GIFRAME_ARC_SPECTRUM);
1740
1741 if (rframe == NULL) {
1742 cpl_msg_error(fctid, "Missing raw frame (%s)", GIFRAME_ARC_SPECTRUM);
1743
1744 giraffe_paf_delete(qc);
1745 qc = NULL;
1746
1747 return 1;
1748 }
1749
1750 cpl_msg_info(fctid, "Processing reference frame '%s' (%s)",
1751 cpl_frame_get_filename(rframe), cpl_frame_get_tag(rframe));
1752
1753 rimage = giraffe_image_new(CPL_TYPE_DOUBLE);
1754 status = giraffe_image_load(rimage, cpl_frame_get_filename(rframe), 0);
1755
1756 if (status != 0) {
1757
1758 cpl_msg_error(fctid, "Could not load arc-lamp spectra '%s'!",
1759 cpl_frame_get_filename(rframe));
1760
1761 giraffe_image_delete(rimage);
1762 rimage = NULL;
1763
1764 giraffe_paf_delete(qc);
1765 qc = NULL;
1766
1767 return 1;
1768
1769 }
1770
1771 _rimage = giraffe_image_get(rimage);
1772 cx_assert(_rimage != NULL);
1773
1774
1775 /*
1776 * Compute mean level of the first raw frame and count the number
1777 * of saturated pixels.
1778 */
1779
1780 properties = giraffe_image_get_properties(rimage);
1781 cx_assert(properties != NULL);
1782
1783 if (cpl_propertylist_has(properties, GIALIAS_OVSCX)) {
1784
1785 cxint _ox = cpl_propertylist_get_int(properties, GIALIAS_OVSCX);
1786 cxint _nx = cpl_image_get_size_x(_rimage) - 2 * CX_MAX(0, _ox) - 1;
1787
1788 w.x0 = CX_MAX(0, _ox) + 1;
1789 w.x1 = w.x0 + _nx;
1790
1791 }
1792
1793 if (cpl_propertylist_has(properties, GIALIAS_OVSCY)) {
1794
1795 cxint _oy = cpl_propertylist_get_int(properties, GIALIAS_OVSCY);
1796 cxint _ny = cpl_image_get_size_y(_rimage) - 2 * CX_MAX(0, _oy) - 1;
1797
1798 w.y0 = CX_MAX(0, _oy) + 1;
1799 w.y1 = w.y0 + _ny;
1800
1801 }
1802
1803 mean = cpl_image_get_mean_window(_rimage, w.x0, w.y0, w.x1, w.y1);
1804
1805 pixels = cpl_image_get_data_const(_rimage);
1806 npixel = cpl_image_get_size_x(_rimage) * cpl_image_get_size_y(_rimage);
1807
1808 for (i = 0; i < npixel; i++) {
1809 if (pixels[i] > saturation) {
1810 ++nsaturated;
1811 }
1812 }
1813
1814
1815 /*
1816 * Process dispersion solution
1817 */
1818
1819 qc = giraffe_qclog_open(0);
1820
1821 if (qc == NULL) {
1822 cpl_msg_error(fctid, "Cannot create QC1 log!");
1823
1824 giraffe_image_delete(rimage);
1825 rimage = NULL;
1826
1827 return 1;
1828 }
1829
1830 qclog = giraffe_paf_get_properties(qc);
1831 cx_assert(qclog != NULL);
1832
1833 pframe = giraffe_get_frame(set, GIFRAME_WAVELENGTH_SOLUTION,
1834 CPL_FRAME_GROUP_PRODUCT);
1835
1836 if (pframe == NULL) {
1837 cpl_msg_error(fctid, "Missing product frame (%s)",
1838 GIFRAME_WAVELENGTH_SOLUTION);
1839
1840 giraffe_paf_delete(qc);
1841 qc = NULL;
1842
1843 giraffe_image_delete(rimage);
1844 rimage = NULL;
1845
1846 return 1;
1847 }
1848
1849 cpl_msg_info(fctid, "Processing product frame '%s' (%s)",
1850 cpl_frame_get_filename(pframe), cpl_frame_get_tag(pframe));
1851
1852 ptable = giraffe_table_new();
1853 status = giraffe_table_load(ptable, cpl_frame_get_filename(pframe), 1,
1854 NULL);
1855
1856 if (status != 0) {
1857 cpl_msg_error(fctid, "Could not load dispersion solution '%s'!",
1858 cpl_frame_get_filename(pframe));
1859
1860 giraffe_table_delete(ptable);
1861 ptable = NULL;
1862
1863 giraffe_image_delete(rimage);
1864 rimage = NULL;
1865
1866 giraffe_paf_delete(qc);
1867 qc = NULL;
1868
1869 return 1;
1870 }
1871
1872 properties = giraffe_image_get_properties(rimage);
1873 cx_assert(properties != NULL);
1874
1875 giraffe_propertylist_copy(qclog, "ARCFILE", properties, GIALIAS_ARCFILE);
1876 giraffe_propertylist_copy(qclog, "TPL.ID", properties, GIALIAS_TPLID);
1877 giraffe_propertylist_copy(qclog, "INS.EXP.MODE", properties,
1878 GIALIAS_SETUPNAME);
1879 giraffe_propertylist_copy(qclog, "INS.SLIT.NAME", properties,
1880 GIALIAS_SLITNAME);
1881 giraffe_propertylist_copy(qclog, "INS.GRAT.NAME", properties,
1882 GIALIAS_GRATNAME);
1883 giraffe_propertylist_copy(qclog, "INS.GRAT.WLEN", properties,
1884 GIALIAS_GRATWLEN);
1885 giraffe_propertylist_copy(qclog, "INS.GRAT.ENC", properties,
1886 GIALIAS_GRATPOS);
1887
1888 cpl_propertylist_update_string(qclog, "PRO.CATG",
1889 cpl_frame_get_tag(pframe));
1890 cpl_propertylist_set_comment(qclog, "PRO.CATG",
1891 "Pipeline product category");
1892
1893 properties = giraffe_table_get_properties(ptable);
1894 cx_assert(properties != NULL);
1895
1896 giraffe_propertylist_copy(qclog, "PRO.WSOL.RMS", properties,
1897 GIALIAS_WSOL_RMS);
1898 giraffe_propertylist_copy(qclog, "PRO.WSOL.NLINES", properties,
1899 GIALIAS_WSOL_NLINES);
1900 giraffe_propertylist_copy(qclog, "PRO.WSOL.NACCEPT", properties,
1901 GIALIAS_WSOL_NACCEPT);
1902 giraffe_propertylist_copy(qclog, "PRO.WSOL.NREJECT", properties,
1903 GIALIAS_WSOL_NREJECT);
1904 giraffe_propertylist_copy(qclog, "PRO.SLIT.NFIBRES", properties,
1905 GIALIAS_NFIBERS);
1906
1907
1908 giraffe_table_delete(ptable);
1909 ptable = NULL;
1910
1911 giraffe_qclog_close(qc);
1912 qc = NULL;
1913
1914
1915 /*
1916 * Process rebinned arc-lamp spectrum
1917 */
1918
1919 qc = giraffe_qclog_open(1);
1920
1921 if (qc == NULL) {
1922 cpl_msg_error(fctid, "Cannot create QC1 log!");
1923 return 1;
1924 }
1925
1926 qclog = giraffe_paf_get_properties(qc);
1927 cx_assert(qclog != NULL);
1928
1929 pframe = giraffe_get_frame(set, GIFRAME_ARC_LAMP_RBNSPECTRA,
1930 CPL_FRAME_GROUP_PRODUCT);
1931
1932 if (pframe == NULL) {
1933 cpl_msg_error(fctid, "Missing product frame (%s)",
1934 GIFRAME_ARC_LAMP_RBNSPECTRA);
1935
1936 giraffe_image_delete(rimage);
1937 rimage = NULL;
1938
1939 giraffe_paf_delete(qc);
1940 qc = NULL;
1941
1942 return 1;
1943 }
1944
1945 cpl_msg_info(fctid, "Processing product frame '%s' (%s)",
1946 cpl_frame_get_filename(pframe), cpl_frame_get_tag(pframe));
1947
1948 pimage = giraffe_image_new(CPL_TYPE_DOUBLE);
1949 status = giraffe_image_load(pimage, cpl_frame_get_filename(pframe), 0);
1950
1951 if (status != 0) {
1952 cpl_msg_error(fctid, "Could not load rebinned arc-lamp spectra '%s'!",
1953 cpl_frame_get_filename(pframe));
1954
1955 giraffe_image_delete(pimage);
1956 pimage = NULL;
1957
1958 giraffe_image_delete(rimage);
1959 rimage = NULL;
1960
1961 giraffe_paf_delete(qc);
1962 qc = NULL;
1963
1964 return 1;
1965 }
1966
1967 ptable = giraffe_table_new();
1968 status = giraffe_table_load(ptable, cpl_frame_get_filename(pframe), 1,
1969 NULL);
1970
1971 if (status != 0) {
1972 cpl_msg_error(fctid, "Could not load rebinned arc-lamp spectra '%s'!",
1973 cpl_frame_get_filename(pframe));
1974
1975 giraffe_table_delete(ptable);
1976 ptable = NULL;
1977
1978 giraffe_image_delete(pimage);
1979 pimage = NULL;
1980
1981 giraffe_image_delete(rimage);
1982 rimage = NULL;
1983
1984 giraffe_paf_delete(qc);
1985 qc = NULL;
1986
1987 return 1;
1988 }
1989
1990 properties = giraffe_image_get_properties(rimage);
1991 cx_assert(properties != NULL);
1992
1993 giraffe_propertylist_copy(qclog, "ARCFILE", properties, GIALIAS_ARCFILE);
1994 giraffe_propertylist_copy(qclog, "TPL.ID", properties, GIALIAS_TPLID);
1995 giraffe_propertylist_copy(qclog, "INS.EXP.MODE", properties,
1996 GIALIAS_SETUPNAME);
1997 giraffe_propertylist_copy(qclog, "INS.SLIT.NAME", properties,
1998 GIALIAS_SLITNAME);
1999 giraffe_propertylist_copy(qclog, "INS.GRAT.NAME", properties,
2000 GIALIAS_GRATNAME);
2001 giraffe_propertylist_copy(qclog, "INS.GRAT.WLEN", properties,
2002 GIALIAS_GRATWLEN);
2003
2004 cpl_propertylist_update_string(qclog, "PRO.CATG",
2005 cpl_frame_get_tag(pframe));
2006 cpl_propertylist_set_comment(qclog, "PRO.CATG",
2007 "Pipeline product category");
2008
2009 properties = giraffe_image_get_properties(pimage);
2010 cx_assert(properties != NULL);
2011
2012 giraffe_propertylist_copy(qclog, "PRO.DATAAVG", properties,
2013 GIALIAS_DATAMEAN);
2014 giraffe_propertylist_copy(qclog, "PRO.DATARMS", properties,
2015 GIALIAS_DATASIG);
2016 giraffe_propertylist_copy(qclog, "PRO.DATAMED", properties,
2017 GIALIAS_DATAMEDI);
2018 giraffe_propertylist_copy(qclog, "PRO.SLIT.NFIBRES", properties,
2019 GIALIAS_NFIBERS);
2020
2021
2022 cpl_propertylist_update_double(properties, GIALIAS_QCMEAN, mean);
2023 cpl_propertylist_set_comment(properties, GIALIAS_QCMEAN, "Mean level of "
2024 "first raw frame");
2025
2026 giraffe_propertylist_copy(qclog, "QC.OUT1.MEAN.RAW", properties,
2027 GIALIAS_QCMEAN);
2028
2029
2030 cpl_propertylist_update_int(properties, GIALIAS_QCNSAT, nsaturated);
2031 cpl_propertylist_set_comment(properties, GIALIAS_QCNSAT, "Number of "
2032 "saturated pixels in the first raw frame");
2033
2034 giraffe_propertylist_copy(qclog, "QC.OUT1.NSAT.RAW", properties,
2035 GIALIAS_QCNSAT);
2036
2037
2038 /*
2039 * Calibration lamp monitoring
2040 */
2041
2042 cpl_propertylist_update_double(properties, GIALIAS_QCLAMP, efficiency[0]);
2043 cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP,
2044 "Calibration lamp efficiency");
2045
2046 giraffe_propertylist_copy(qclog, "QC.LAMP.EFFIC", properties,
2047 GIALIAS_QCLAMP);
2048
2049 cpl_propertylist_update_double(properties, GIALIAS_QCLAMP_SIMCAL,
2050 efficiency[1]);
2051 cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP_SIMCAL,
2052 "SIMCAL lamp efficiency");
2053
2054 giraffe_propertylist_copy(qclog, "QC.LAMP.EFFIC1", properties,
2055 GIALIAS_QCLAMP_SIMCAL);
2056
2057
2058 /* Compute rebinned emission line straightness. */
2059
2060 _pimage = giraffe_image_get(pimage);
2061
2062 _test = cpl_image_duplicate(_pimage);
2063 _tdata = cpl_image_get_data(_test);
2064
2065 nx = cpl_image_get_size_x(_test);
2066 ny = cpl_image_get_size_y(_test);
2067
2068 for (i = 0; i < nx * ny; i++) {
2069 _tdata[i] = _tdata[i] > 0. ? log(_tdata[i]) : 0.;
2070 }
2071
2072 _tdata = NULL;
2073
2074 _test0 = cpl_image_extract(_test, 4, 1, 4, ny);
2075
2076 _test1 = cpl_image_collapse_create(_test, 1);
2077 cpl_image_divide_scalar(_test1, nx);
2078
2079 cpl_image_delete(_test);
2080 _test = NULL;
2081
2082
2083 _test = cpl_image_subtract_create(_test0, _test1);
2084
2085 cpl_image_delete(_test0);
2086 _test0 = NULL;
2087
2088 cpl_image_delete(_test1);
2089 _test1 = NULL;
2090
2091
2092 _tdata = cpl_image_get_data(_test);
2093
2094 rms = 0;
2095
2096 for (i = 0; i < ny; i++) {
2097 _tdata[i] = exp(_tdata[i]);
2098 rms += pow(_tdata[i], 2.);
2099 }
2100
2101 rms = sqrt(rms / (ny - 1));
2102
2103 cpl_image_delete(_test);
2104 _test = NULL;
2105
2106 cpl_propertylist_update_double(properties, GIALIAS_QCRBRMS, rms);
2107 cpl_propertylist_set_comment(properties, GIALIAS_QCRBRMS,
2108 "RMS of rebinned arc-lamp spectra");
2109
2110 giraffe_propertylist_copy(qclog, "QC.WSOL.REBIN.RMS", properties,
2111 GIALIAS_QCRBRMS);
2112
2113
2114 status = giraffe_image_save(pimage, cpl_frame_get_filename(pframe));
2115
2116 if (status != 0) {
2117 cpl_msg_error(fctid, "Could not save rebinned arc-lamp spectra "
2118 "'%s'!", cpl_frame_get_filename(pframe));
2119
2120 giraffe_table_delete(ptable);
2121 ptable = NULL;
2122
2123 giraffe_image_delete(pimage);
2124 pimage = NULL;
2125
2126 giraffe_image_delete(rimage);
2127 rimage = NULL;
2128
2129 giraffe_paf_delete(qc);
2130 qc = NULL;
2131
2132 return 1;
2133 }
2134
2135 status = giraffe_table_attach(ptable, cpl_frame_get_filename(pframe),
2136 1, NULL);
2137
2138 if (status != 0) {
2139 cpl_msg_error(fctid, "Could not save rebinned arc-lamp spectra "
2140 "'%s'!", cpl_frame_get_filename(pframe));
2141
2142 giraffe_table_delete(ptable);
2143 ptable = NULL;
2144
2145 giraffe_image_delete(pimage);
2146 pimage = NULL;
2147
2148 giraffe_image_delete(rimage);
2149 rimage = NULL;
2150
2151 giraffe_paf_delete(qc);
2152 qc = NULL;
2153
2154 return 1;
2155 }
2156
2157 giraffe_image_delete(pimage);
2158 pimage = NULL;
2159
2160 giraffe_table_delete(ptable);
2161 ptable = NULL;
2162
2163 giraffe_qclog_close(qc);
2164 qc = NULL;
2165
2166
2167 /*
2168 * Process line data
2169 */
2170
2171 qc = giraffe_qclog_open(2);
2172
2173 if (qc == NULL) {
2174 cpl_msg_error(fctid, "Cannot create QC1 log!");
2175 return 1;
2176 }
2177
2178 qclog = giraffe_paf_get_properties(qc);
2179 cx_assert(qclog != NULL);
2180
2181 pframe = giraffe_get_frame(set, GIFRAME_LINE_DATA,
2182 CPL_FRAME_GROUP_PRODUCT);
2183
2184 if (pframe == NULL) {
2185 cpl_msg_error(fctid, "Missing product frame (%s)",
2186 GIFRAME_LINE_DATA);
2187
2188 giraffe_image_delete(rimage);
2189 rimage = NULL;
2190
2191 giraffe_paf_delete(qc);
2192 qc = NULL;
2193
2194 return 1;
2195 }
2196
2197 cpl_msg_info(fctid, "Processing product frame '%s' (%s)",
2198 cpl_frame_get_filename(pframe), cpl_frame_get_tag(pframe));
2199
2200
2201 /*
2202 * Load line data
2203 */
2204
2205 plines = giraffe_linedata_new();
2206
2207 status = giraffe_linedata_load(plines, cpl_frame_get_filename(pframe));
2208
2209 if (status != 0) {
2210 cpl_msg_error(fctid, "Could not load line data '%s'!",
2211 cpl_frame_get_filename(pframe));
2212
2213 giraffe_linedata_delete(plines);
2214 plines = NULL;
2215
2216 giraffe_image_delete(rimage);
2217 rimage = NULL;
2218
2219 giraffe_paf_delete(qc);
2220 qc = NULL;
2221
2222 return 1;
2223 }
2224
2225 properties = giraffe_image_get_properties(rimage);
2226 cx_assert(properties != NULL);
2227
2228 giraffe_propertylist_copy(qclog, "ARCFILE", properties, GIALIAS_ARCFILE);
2229 giraffe_propertylist_copy(qclog, "TPL.ID", properties, GIALIAS_TPLID);
2230 giraffe_propertylist_copy(qclog, "INS.EXP.MODE", properties,
2231 GIALIAS_SETUPNAME);
2232 giraffe_propertylist_copy(qclog, "INS.SLIT.NAME", properties,
2233 GIALIAS_SLITNAME);
2234 giraffe_propertylist_copy(qclog, "INS.GRAT.NAME", properties,
2235 GIALIAS_GRATNAME);
2236 giraffe_propertylist_copy(qclog, "INS.GRAT.WLEN", properties,
2237 GIALIAS_GRATWLEN);
2238
2239 cpl_propertylist_update_string(qclog, "PRO.CATG",
2240 cpl_frame_get_tag(pframe));
2241 cpl_propertylist_set_comment(qclog, "PRO.CATG",
2242 "Pipeline product category");
2243
2244
2245 _pimage = giraffe_linedata_get_data(plines, "FWHM");
2246
2247 if (_pimage == NULL) {
2248 cpl_msg_error(fctid, "FWHM line data not found!");
2249
2250 giraffe_linedata_delete(plines);
2251 plines = NULL;
2252
2253 giraffe_image_delete(rimage);
2254 rimage = NULL;
2255
2256 giraffe_paf_delete(qc);
2257 qc = NULL;
2258
2259 return 1;
2260 }
2261
2262 nx = cpl_image_get_size_x(_pimage);
2263 ny = cpl_image_get_size_y(_pimage);
2264
2265 pixels = cpl_image_get_data_const(_pimage);
2266
2267 for (j = 0; j < 2; ++j) {
2268
2269 register cxint ndata = nx * ny;
2270
2271 npixel = 0;
2272 mean = 0.;
2273 rms = 0.;
2274
2275 for (i = 0; i < ndata; ++i) {
2276
2277 if ((pixels[i] >= fwhm_domain[0]) &&
2278 (pixels[i] < fwhm_domain[1])) {
2279 mean += pixels[i];
2280 ++npixel;
2281 }
2282
2283 }
2284
2285 if (npixel == 0) {
2286 cpl_msg_error(fctid, "All line FWHM data are invalid!");
2287
2288 giraffe_linedata_delete(plines);
2289 plines = NULL;
2290
2291 giraffe_image_delete(rimage);
2292 rimage = NULL;
2293
2294 giraffe_paf_delete(qc);
2295 qc = NULL;
2296
2297 return 1;
2298 }
2299
2300 mean /= npixel;
2301
2302 for (i = 0; i < ndata; ++i) {
2303
2304 if ((pixels[i] >= fwhm_domain[0]) &&
2305 (pixels[i] < fwhm_domain[1])) {
2306 rms += pow(pixels[i] - mean, 2.);
2307 }
2308
2309 }
2310
2311 if (npixel > 1) {
2312 rms = sqrt(rms / (npixel - 1));
2313 }
2314
2315 fwhm_domain[0] = CX_MAX(mean - rmsscale * rms, 0.);
2316 fwhm_domain[1] = CX_MIN(mean + rmsscale * rms, 100.);
2317
2318 }
2319
2320
2321 properties = cpl_propertylist_load_regexp(cpl_frame_get_filename(pframe),
2322 0, "^COMMENT$", TRUE);
2323
2324 cx_assert(properties != NULL);
2325
2326 if (cpl_propertylist_has(properties, GIALIAS_GRATWLEN) == FALSE) {
2327 cpl_msg_error(fctid, "Grating central wavelength property '%s' not "
2328 "found!", GIALIAS_GRATWLEN);
2329
2330 cpl_propertylist_delete(properties);
2331 properties = NULL;
2332
2333 giraffe_linedata_delete(plines);
2334 plines = NULL;
2335
2336 giraffe_image_delete(rimage);
2337 rimage = NULL;
2338
2339 giraffe_paf_delete(qc);
2340 qc = NULL;
2341
2342 return 1;
2343 }
2344
2345 if (cpl_propertylist_has(properties, GIALIAS_WSOL_SCALE) == FALSE) {
2346 cpl_msg_error(fctid, "Line data property '%s' not found!",
2347 GIALIAS_WSOL_SCALE);
2348
2349 cpl_propertylist_delete(properties);
2350 properties = NULL;
2351
2352 giraffe_linedata_delete(plines);
2353 plines = NULL;
2354
2355 giraffe_image_delete(rimage);
2356 rimage = NULL;
2357
2358 giraffe_paf_delete(qc);
2359 qc = NULL;
2360
2361 return 1;
2362 }
2363
2364 wlcenter = cpl_propertylist_get_double(properties, GIALIAS_GRATWLEN);
2365 pixel2nm = cpl_propertylist_get_double(properties, GIALIAS_WSOL_SCALE);
2366
2367 mean *= pixel2nm;
2368 rms *= pixel2nm;
2369
2370 cpl_propertylist_update_double(properties, GIALIAS_QCRESOLAVG, mean);
2371 cpl_propertylist_set_comment(properties, GIALIAS_QCRESOLAVG,
2372 "Average line FWHM [nm]");
2373
2374 cpl_propertylist_update_double(properties, GIALIAS_QCRESOLRMS, rms);
2375 cpl_propertylist_set_comment(properties, GIALIAS_QCRESOLRMS,
2376 "RMS of line FWHM [nm]");
2377
2378 cpl_propertylist_update_int(properties, GIALIAS_QCRESOLTOT, nx * ny);
2379 cpl_propertylist_set_comment(properties, GIALIAS_QCRESOLTOT,
2380 "Total number of lines available for FWHM RMS "
2381 "computation");
2382
2383 cpl_propertylist_update_int(properties, GIALIAS_QCRESOLLIN, npixel);
2384 cpl_propertylist_set_comment(properties, GIALIAS_QCRESOLLIN,
2385 "Number of lines used for FWHM RMS "
2386 "computation");
2387
2388 cpl_propertylist_update_double(properties, GIALIAS_QCRESOLPWR,
2389 wlcenter / mean);
2390 cpl_propertylist_set_comment(properties, GIALIAS_QCRESOLPWR,
2391 "Resolving power");
2392
2393 giraffe_propertylist_copy(qclog, "QC.RESOL.MEAN", properties,
2394 GIALIAS_QCRESOLAVG);
2395 giraffe_propertylist_copy(qclog, "QC.RESOL.RMS", properties,
2396 GIALIAS_QCRESOLRMS);
2397 giraffe_propertylist_copy(qclog, "QC.RESOL.NTOTAL", properties,
2398 GIALIAS_QCRESOLTOT);
2399 giraffe_propertylist_copy(qclog, "QC.RESOL.NLINES", properties,
2400 GIALIAS_QCRESOLLIN);
2401 giraffe_propertylist_copy(qclog, "QC.RESOL.POWER", properties,
2402 GIALIAS_QCRESOLPWR);
2403
2404
2405 status = giraffe_linedata_save(plines, properties,
2406 cpl_frame_get_filename(pframe));
2407
2408 if (status != 0) {
2409 cpl_msg_error(fctid, "Could not save line data "
2410 "'%s'!", cpl_frame_get_filename(pframe));
2411
2412 cpl_propertylist_delete(properties);
2413 properties = NULL;
2414
2415 giraffe_linedata_delete(plines);
2416 plines = NULL;
2417
2418 giraffe_image_delete(rimage);
2419 rimage = NULL;
2420
2421 giraffe_paf_delete(qc);
2422 qc = NULL;
2423
2424 return 1;
2425 }
2426
2427 cpl_propertylist_delete(properties);
2428 properties = NULL;
2429
2430 giraffe_qclog_close(qc);
2431 qc = NULL;
2432
2433
2434 /*
2435 * Cleanup
2436 */
2437
2438 giraffe_image_delete(rimage);
2439
2440 return 0;
2441
2442}
2443
2444
2445/*
2446 * Build table of contents, i.e. the list of available plugins, for
2447 * this module. This function is exported.
2448 */
2449
2450int
2451cpl_plugin_get_info(cpl_pluginlist* list)
2452{
2453
2454 cpl_recipe* recipe = cx_calloc(1, sizeof *recipe);
2455 cpl_plugin* plugin = &recipe->interface;
2456
2457 cpl_plugin_init(plugin,
2458 CPL_PLUGIN_API,
2459 GIRAFFE_BINARY_VERSION,
2460 CPL_PLUGIN_TYPE_RECIPE,
2461 "giwavecalibration",
2462 "Compute dispersion solution from an arc-lamp spectrum.",
2463 "For detailed information please refer to the "
2464 "GIRAFFE pipeline user manual.\nIt is available at "
2465 "http://www.eso.org/pipelines.",
2466 "Giraffe Pipeline",
2467 PACKAGE_BUGREPORT,
2469 giwavecalibration_create,
2470 giwavecalibration_exec,
2471 giwavecalibration_destroy);
2472
2473 cpl_pluginlist_append(list, plugin);
2474
2475 return 0;
2476
2477}
GiBiasConfig * giraffe_bias_config_create(cpl_parameterlist *list)
Creates a setup structure for a bias removal task.
Definition: gibias.c:3438
void giraffe_bias_config_add(cpl_parameterlist *list)
Adds parameters for the bias removal.
Definition: gibias.c:3597
cxint giraffe_bias_remove(GiImage *result, const GiImage *raw, const GiImage *master_bias, const GiImage *bad_pixels, const cpl_matrix *biaslimits, const GiBiasConfig *config)
Removes the bias from an image.
Definition: gibias.c:3106
void giraffe_bias_config_destroy(GiBiasConfig *config)
Destroys a bias removal setup structure.
Definition: gibias.c:3569
void giraffe_extract_config_add(cpl_parameterlist *list)
Adds parameters for the spectrum extraction.
Definition: giextract.c:3504
cxint giraffe_extract_spectra(GiExtraction *result, GiImage *image, GiTable *fibers, GiLocalization *sloc, GiImage *bpixel, GiImage *slight, GiExtractConfig *config)
Extracts the spectra from a preprocessed frame.
Definition: giextract.c:2475
GiExtractConfig * giraffe_extract_config_create(cpl_parameterlist *list)
Creates a setup structure for the spectrum extraction.
Definition: giextract.c:3400
void giraffe_extract_config_destroy(GiExtractConfig *config)
Destroys a spectrum extraction setup structure.
Definition: giextract.c:3474
GiTable * giraffe_fibers_setup(const cpl_frame *frame, const cpl_frame *reference)
Setup a fiber list.
Definition: gifibers.c:218
cxint giraffe_fiberlist_compare(const GiTable *fibers, const GiTable *reference)
Compare two fiber lists.
Definition: gifiberutils.c:913
cxint giraffe_fiberlist_attach(cpl_frame *frame, GiTable *fibers)
Attach a fiber table to a frame.
Definition: gifiberutils.c:845
cpl_frame * giraffe_get_frame(const cpl_frameset *set, const cxchar *tag, cpl_frame_group group)
Get a frame from a frame set.
Definition: giframe.c:728
cpl_frame * giraffe_frame_create(const cxchar *tag, cpl_frame_level level, const cpl_propertylist *properties, cxcptr object, cxcptr data, GiFrameCreator creator)
Create a product frame using a provided frame creator.
Definition: giframe.c:237
cpl_frame * giraffe_frame_create_image(GiImage *image, const cxchar *tag, cpl_frame_level level, cxbool save, cxbool update)
Create an image product frame.
Definition: giframe.c:393
cpl_frame * giraffe_get_slitgeometry(const cpl_frameset *set)
Get the slit geometry frame from a frame set.
Definition: giframe.c:775
cpl_frame * giraffe_frame_create_table(GiTable *table, const cxchar *tag, cpl_frame_level level, cxbool save, cxbool update)
Create a table product frame.
Definition: giframe.c:532
cpl_image * giraffe_image_get(const GiImage *self)
Gets the image data.
Definition: giimage.c:218
cpl_propertylist * giraffe_image_get_properties(const GiImage *self)
Get the properties of an image.
Definition: giimage.c:282
void giraffe_image_delete(GiImage *self)
Destroys an image.
Definition: giimage.c:181
cxint giraffe_image_add_info(GiImage *image, const GiRecipeInfo *info, const cpl_frameset *set)
Add additional frame information to an image.
Definition: giimage.c:773
cxint giraffe_image_save(GiImage *self, const cxchar *filename)
Write a Giraffe image to a file.
Definition: giimage.c:570
GiImage * giraffe_image_new(cpl_type type)
Creates an empty image container.
Definition: giimage.c:65
cxint giraffe_image_load(GiImage *self, const cxchar *filename, cxint position)
Gets image data and properties from a file.
Definition: giimage.c:536
void giraffe_rebin_config_destroy(GiRebinConfig *config)
Destroys a spectrum extraction setup structure.
Definition: girebinning.c:4925
cxint giraffe_rebin_spectra(GiRebinning *rebinning, const GiExtraction *extraction, const GiTable *fibers, const GiLocalization *localization, const GiTable *grating, const GiTable *slitgeo, const GiTable *solution, const GiRebinConfig *config)
Rebin an Extracted Spectra Frame and associated Errors Frame.
Definition: girebinning.c:4051
GiRebinConfig * giraffe_rebin_config_create(cpl_parameterlist *list)
Creates a setup structure for the rebinning.
Definition: girebinning.c:4825
GiRebinning * giraffe_rebinning_new(void)
Create an empty rebinning results container.
Definition: girebinning.c:4693
void giraffe_rebinning_destroy(GiRebinning *rebinning)
Destroys a rebinning results container and its contents.
Definition: girebinning.c:4787
void giraffe_rebin_config_add(cpl_parameterlist *list)
Adds parameters for the rebinning.
Definition: girebinning.c:4949
GiSGCalConfig * giraffe_sgcalibration_config_create(cpl_parameterlist *list)
Creates a setup structure for the slit geometry calibration.
void giraffe_sgcalibration_config_destroy(GiSGCalConfig *config)
Destroys a sgcalibration field setup structure.
void giraffe_sgcalibration_config_add(cpl_parameterlist *list)
Adds parameters for the sgcalibration correction computation.
cxint giraffe_calibrate_slit(GiTable *result, const GiExtraction *extraction, const GiLocalization *localization, const GiTable *fibers, const GiTable *wlsolution, const GiTable *slitgeometry, const GiTable *grating, const GiTable *mask, const GiSGCalConfig *config)
Compute a slit geometry corresponding to the given rebinned spectrum.
GiTable * giraffe_slitgeometry_load(const GiTable *fibers, const cxchar *filename, cxint pos, const cxchar *tag)
Load the slit geometry information for a given fiber setup.
GiTable * giraffe_table_new(void)
Creates a new, empty Giraffe table.
Definition: gitable.c:85
cxint giraffe_table_load(GiTable *self, const cxchar *filename, cxint position, const cxchar *id)
Reads a data set from a file into a Giraffe table.
Definition: gitable.c:562
cxint giraffe_table_attach(GiTable *self, const cxchar *filename, cxint position, const cxchar *id)
Attach a Giraffe table to a file.
Definition: gitable.c:749
void giraffe_table_delete(GiTable *self)
Destroys a Giraffe table.
Definition: gitable.c:154
cpl_table * giraffe_table_get(const GiTable *self)
Get the table data from a Giraffe table.
Definition: gitable.c:433
cpl_propertylist * giraffe_table_get_properties(const GiTable *self)
Gets the table properties.
Definition: gitable.c:489
cxint giraffe_table_add_info(GiTable *table, const GiRecipeInfo *info, const cpl_frameset *set)
Add additional frame information to a table.
Definition: gitable.c:836
cxint giraffe_propertylist_copy(cpl_propertylist *self, const cxchar *name, const cpl_propertylist *other, const cxchar *othername)
Copy a property from one list to another.
Definition: giutils.c:1104
const cxchar * giraffe_get_license(void)
Get the pipeline copyright and license.
Definition: giutils.c:418
void giraffe_wlcalibration_config_add(cpl_parameterlist *list)
Adds parameters for the wavelength calibration.
cxint giraffe_calibrate_wavelength(GiWCalData *result, GiExtraction *extraction, GiLocalization *localization, GiTable *fibers, GiTable *slitgeometry, GiTable *grating, GiTable *lines, GiTable *initial, GiWCalConfig *config)
Compute the wavelength solution for the given extracted arc-lamp spectra.
GiWCalConfig * giraffe_wlcalibration_config_create(cpl_parameterlist *list)
Creates a setup structure for the wavelength calibration.
void giraffe_wlcalibration_config_destroy(GiWCalConfig *config)
Destroys a wavelength calibration setup structure.
Slit geometry calibration configuration data structure.
Wavelength calibration configuration data structure.

This file is part of the GIRAFFE Pipeline Reference Manual 2.16.12.
Documentation copyright © 2002-2006 European Southern Observatory.
Generated on Fri Feb 21 2025 12:08:13 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2004