GIRAFFE Pipeline Reference Manual

gimasterflat.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 <cxslist.h>
27#include <cxmessages.h>
28#include <cxmemory.h>
29
30#include <cpl_recipe.h>
31#include <cpl_plugininfo.h>
32#include <cpl_parameterlist.h>
33#include <cpl_frameset.h>
34#include <cpl_msg.h>
35
36#include "gialias.h"
37#include "gierror.h"
38#include "giframe.h"
39#include "giimage.h"
40#include "giwindow.h"
41#include "gifibers.h"
42#include "gifiberutils.h"
43#include "gislitgeometry.h"
44#include "gibias.h"
45#include "gidark.h"
46#include "gilocalize.h"
47#include "gipsf.h"
48#include "giextract.h"
49#include "gitransmission.h"
50#include "gislight.h"
51#include "giqclog.h"
52#include "giutils.h"
53
54
55static cxint gimasterflat(cpl_parameterlist* config, cpl_frameset* set);
56static cxint giqcmasterflat(cpl_frameset* set);
57
58
59/*
60 * Create the recipe instance, i.e. setup the parameter list for this
61 * recipe and make it available to the application using the interface.
62 */
63
64static cxint
65gimasterflat_create(cpl_plugin* plugin)
66{
67
68 cpl_recipe* recipe = (cpl_recipe*)plugin;
69
70 cpl_parameter* p;
71
72
73 giraffe_error_init();
74
75
76 /*
77 * We have to provide the option we accept to the application. We
78 * need to setup our parameter list and hook it into the recipe
79 * interface.
80 */
81
82 recipe->parameters = cpl_parameterlist_new();
83 cx_assert(recipe->parameters != NULL);
84
85
86 /*
87 * Fill the parameter list.
88 */
89
90 /* Fiber selection */
91
92 giraffe_fibers_config_add(recipe->parameters);
93
94 /* Bias removal */
95
96 giraffe_bias_config_add(recipe->parameters);
97
98 /* Dark subtraction */
99
100 /* TBD */
101
102 /* Spectrum localization */
103
104 giraffe_localize_config_add(recipe->parameters);
105
106 /* PSF fitting (accurate localization) */
107
108 giraffe_psf_config_add(recipe->parameters);
109
110 /* Spectrum extraction */
111
112 giraffe_extract_config_add(recipe->parameters);
113
114 /* Relative fiber transmission correction */
115
116 p = cpl_parameter_new_value("giraffe.masterflat.transmission",
117 CPL_TYPE_BOOL,
118 "Controls the relative fiber transmission "
119 "computation.",
120 "giraffe.masterflat",
121 TRUE);
122
123 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "transmission");
124 cpl_parameterlist_append(recipe->parameters, p);
125
126 giraffe_transmission_config_add(recipe->parameters);
127
128
129 p = cpl_parameter_new_value("giraffe.masterflat.slight",
130 CPL_TYPE_BOOL,
131 "Controls the scattered light model "
132 "computation.",
133 "giraffe.masterflat",
134 FALSE);
135 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "slight");
136 cpl_parameterlist_append(recipe->parameters, p);
137
138 giraffe_slight_config_add(recipe->parameters);
139
140 return 0;
141
142}
143
144
145/*
146 * Execute the plugin instance given by the interface.
147 */
148
149static cxint
150gimasterflat_exec(cpl_plugin* plugin)
151{
152
153 cpl_recipe* recipe = (cpl_recipe*)plugin;
154
155 cxint status = 0;
156
157
158 if (recipe->parameters == NULL || recipe->frames == NULL) {
159 return 1;
160 }
161
162 status = gimasterflat(recipe->parameters, recipe->frames);
163
164 if (status != 0) {
165 return 1;
166 }
167
168 status = giqcmasterflat(recipe->frames);
169
170 if (status != 0) {
171 return 1;
172 }
173
174 return 0;
175
176}
177
178
179static cxint
180gimasterflat_destroy(cpl_plugin* plugin)
181{
182
183 cpl_recipe* recipe = (cpl_recipe*)plugin;
184
185
186 /*
187 * We just destroy what was created during the plugin initialization
188 * phase, i.e. the parameter list. The frame set is managed by the
189 * application which called us, so we must not touch it,
190 */
191
192 cpl_parameterlist_delete(recipe->parameters);
193
194 giraffe_error_clear();
195
196 return 0;
197
198}
199
200
201/*
202 * The actual recipe starts here.
203 */
204
205static cxint
206gimasterflat(cpl_parameterlist* config, cpl_frameset* set)
207{
208
209 const cxchar* const _id = "gimasterflat";
210
211
212 cxbool transmission = FALSE;
213 cxbool slmodel = FALSE;
214
215 cxint status = 0;
216 cxint nflats;
217
218 cxlong i;
219
220 cxdouble exptime = 0.;
221 cxdouble mean = 0.;
222
223 cx_slist* flats = NULL;
224
225 cpl_parameter* p = NULL;
226
227 cpl_propertylist* properties = NULL;
228
229 cpl_matrix* biasareas = NULL;
230
231 cpl_frame* flat_frame = NULL;
232 cpl_frame* mbias_frame = NULL;
233 cpl_frame* mdark_frame = NULL;
234 cpl_frame* bpixel_frame = NULL;
235 cpl_frame* slight_frame = NULL;
236 cpl_frame* mlocy_frame = NULL;
237 cpl_frame* mlocw_frame = NULL;
238 cpl_frame* mlpsf_frame = NULL;
239 cpl_frame* mflat_frame = NULL;
240 cpl_frame* sloc_frame = NULL;
241 cpl_frame* ploc_frame = NULL;
242 cpl_frame* sext_frame = NULL;
243 cpl_frame* slit_frame = NULL;
244 cpl_frame* grating_frame = NULL;
245 cpl_frame* wcal_frame = NULL;
246
247 GiImage* bpixel = NULL;
248 GiImage* mbias = NULL;
249 GiImage* mdark = NULL;
250 GiImage* slight = NULL;
251 GiImage* sflat = NULL;
252 GiImage* mflat = NULL;
253
254 GiTable* fibers = NULL;
255 GiTable* grating = NULL;
256 GiTable* slitgeometry = NULL;
257 GiTable* wlsolution = NULL;
258
259 GiLocalization* sloc = NULL;
260 GiLocalization* ploc = NULL;
261 GiLocalization* mloc = NULL;
262
263 GiExtraction* extraction = NULL;
264
265 GiBiasConfig* bias_config = NULL;
266
267 GiFibersConfig* fibers_config = NULL;
268
269 GiLocalizeConfig* localize_config = NULL;
270
271 GiPsfConfig* psf_config = NULL;
272
273 GiExtractConfig* extract_config = NULL;
274
275 GiTransmissionConfig* transmission_config = NULL;
276
277 GiRecipeInfo info = {(cxchar*)_id, 1, NULL, config};
278
279 GiGroupInfo groups[] = {
280 {GIFRAME_FIBER_FLAT, CPL_FRAME_GROUP_RAW},
281 {GIFRAME_BADPIXEL_MAP, CPL_FRAME_GROUP_CALIB},
282 {GIFRAME_BIAS_MASTER, CPL_FRAME_GROUP_CALIB},
283 {GIFRAME_DARK_MASTER, CPL_FRAME_GROUP_CALIB},
284 {GIFRAME_SCATTERED_LIGHT_MODEL, CPL_FRAME_GROUP_CALIB},
285 {GIFRAME_LOCALIZATION_CENTROID, CPL_FRAME_GROUP_CALIB},
286 {GIFRAME_LOCALIZATION_WIDTH, CPL_FRAME_GROUP_CALIB},
287 {GIFRAME_PSF_DATA, CPL_FRAME_GROUP_CALIB},
288 {GIFRAME_WAVELENGTH_SOLUTION, CPL_FRAME_GROUP_CALIB},
289 {GIFRAME_SLITSETUP, CPL_FRAME_GROUP_CALIB},
290 {GIFRAME_SLITMASTER, CPL_FRAME_GROUP_CALIB},
291 {GIFRAME_GRATING, CPL_FRAME_GROUP_CALIB},
292 {NULL, CPL_FRAME_GROUP_NONE}
293 };
294
295
296
297 if (!config) {
298 cpl_msg_error(_id, "Invalid parameter list! Aborting ...");
299 return 1;
300 }
301
302 if (!set) {
303 cpl_msg_error(_id, "Invalid frame set! Aborting ...");
304 return 1;
305 }
306
307 status = giraffe_frameset_set_groups(set, groups);
308
309 if (status != 0) {
310 cpl_msg_error(_id, "Setting frame group information failed!");
311 return 1;
312 }
313
314
315 p = cpl_parameterlist_find(config, "giraffe.masterflat.transmission");
316
317 if (p != NULL) {
318 transmission = cpl_parameter_get_bool(p);
319 }
320
321 p = cpl_parameterlist_find(config, "giraffe.masterflat.slight");
322
323 if (p != NULL) {
324 slmodel = cpl_parameter_get_bool(p);
325 }
326
327
328 /*
329 * Verify the frame set contents
330 */
331
332 nflats = cpl_frameset_count_tags(set, GIFRAME_FIBER_FLAT);
333
334 if (nflats < 1) {
335 cpl_msg_error(_id, "Too few (%d) raw frames (%s) present in "
336 "frame set! Aborting ...", nflats, GIFRAME_FIBER_FLAT);
337 return 1;
338 }
339
340
341 bpixel_frame = cpl_frameset_find(set, GIFRAME_BADPIXEL_MAP);
342
343 if (!bpixel_frame) {
344 cpl_msg_info(_id, "No bad pixel map present in frame set.");
345 }
346
347 mbias_frame = cpl_frameset_find(set, GIFRAME_BIAS_MASTER);
348
349 if (!mbias_frame) {
350 cpl_msg_info(_id, "No master bias present in frame set.");
351 }
352
353 mdark_frame = cpl_frameset_find(set, GIFRAME_DARK_MASTER);
354
355 if (!mdark_frame) {
356 cpl_msg_info(_id, "No master dark present in frame set.");
357 }
358
359 mlocy_frame = cpl_frameset_find(set, GIFRAME_LOCALIZATION_CENTROID);
360
361 if (!mlocy_frame) {
362 cpl_msg_info(_id, "No master localization (centroid position) "
363 "present in frame set.");
364 }
365
366 mlocw_frame = cpl_frameset_find(set, GIFRAME_LOCALIZATION_WIDTH);
367
368 if (!mlocw_frame) {
369 cpl_msg_info(_id, "No master localization (spectrum width) "
370 "present in frame set.");
371 }
372
373 mlpsf_frame = cpl_frameset_find(set, GIFRAME_PSF_DATA);
374
375 if (!mlpsf_frame) {
376 cpl_msg_info(_id, "No master localization (PSF parameters) "
377 "present in frame set.");
378 }
379
380 slight_frame = cpl_frameset_find(set, GIFRAME_SCATTERED_LIGHT_MODEL);
381
382 if (!slight_frame) {
383 cpl_msg_info(_id, "No scattered light model present in frame set.");
384 }
385
386 grating_frame = cpl_frameset_find(set, GIFRAME_GRATING);
387
388 if (!grating_frame) {
389 cpl_msg_info(_id, "No grating data present in frame set. "
390 "Aborting ...");
391 return 1;
392 }
393
394 slit_frame = giraffe_get_slitgeometry(set);
395
396 if (!slit_frame) {
397 cpl_msg_info(_id, "No slitgeometry present in frame set. "
398 "Aborting ...");
399 return 1;
400 }
401
402 wcal_frame = cpl_frameset_find(set, GIFRAME_WAVELENGTH_SOLUTION);
403
404 if (!wcal_frame) {
405 cpl_msg_info(_id, "No wavelength solution present in frame set.");
406 }
407
408
409 /*
410 * Load raw images
411 */
412
413 flats = cx_slist_new();
414
415 flat_frame = cpl_frameset_find(set, GIFRAME_FIBER_FLAT);
416
417 for (i = 0; i < nflats; i++) {
418
419 const cxchar* filename = cpl_frame_get_filename(flat_frame);
420
421 GiImage* raw = giraffe_image_new(CPL_TYPE_DOUBLE);
422
423
424 status = giraffe_image_load(raw, filename, 0);
425
426 if (status) {
427 cpl_msg_error(_id, "Cannot load raw flat from '%s'. "
428 "Aborting ...", filename);
429
430 cx_slist_destroy(flats, (cx_free_func) giraffe_image_delete);
431
432 return 1;
433 }
434
435 cx_slist_push_back(flats, raw);
436
437 flat_frame = cpl_frameset_find(set, NULL);
438
439 }
440
441
442 /*
443 * Create a stacked flat field from the list of raw images. Each raw
444 * image is disposed when it is no longer needed.
445 */
446
447 // FIXME: For the moment we just do a simple averaging of all flats
448 // in the list, until the image combination is ported.
449
450 cpl_msg_info(_id, "Averaging flat field frames ...");
451
452 nflats = (cxint)cx_slist_size(flats);
453 sflat = cx_slist_pop_front(flats);
454
455 properties = giraffe_image_get_properties(sflat);
456 cx_assert(properties != NULL);
457
458 exptime = cpl_propertylist_get_double(properties, GIALIAS_EXPTIME);
459
460 for (i = 1; i < nflats; i++) {
461
462 cpl_propertylist* _properties;
463
464 GiImage* flat = cx_slist_pop_front(flats);
465
466
467 cpl_image_add(giraffe_image_get(sflat), giraffe_image_get(flat));
468
469 _properties = giraffe_image_get_properties(flat);
470 cx_assert(_properties != NULL);
471
472 exptime += cpl_propertylist_get_double(_properties, GIALIAS_EXPTIME);
473
475
476 }
477
478 cpl_image_divide_scalar(giraffe_image_get(sflat), nflats);
479
480 cx_assert(cx_slist_empty(flats));
481 cx_slist_delete(flats);
482 flats = NULL;
483
484
485 /*
486 * Update stacked flat field properties
487 */
488
489 cpl_msg_info(_id, "Updating stacked flat field image properties ...");
490
491 cpl_propertylist_update_double(properties, GIALIAS_EXPTIME,
492 exptime / nflats);
493
494 cpl_propertylist_update_double(properties, GIALIAS_EXPTTOT, exptime);
495 cpl_propertylist_set_comment(properties, GIALIAS_EXPTTOT,
496 "Total exposure time of all frames "
497 "combined");
498
499 cpl_propertylist_update_int(properties, GIALIAS_DATANCOM, nflats);
500 cpl_propertylist_set_comment(properties, GIALIAS_DATANCOM, "Number of "
501 "frames combined");
502
503 cpl_propertylist_erase(properties, GIALIAS_TPLEXPNO);
504
505
506 /*
507 * Prepare for bias subtraction
508 */
509
510 bias_config = giraffe_bias_config_create(config);
511
512 if (bias_config->method == GIBIAS_METHOD_MASTER ||
513 bias_config->method == GIBIAS_METHOD_ZMASTER) {
514
515 if (!mbias_frame) {
516 cpl_msg_error(_id, "Missing master bias frame! Selected bias "
517 "removal method requires a master bias frame!");
518
519 giraffe_bias_config_destroy(bias_config);
521
522 return 1;
523 }
524 else {
525 const cxchar* filename = cpl_frame_get_filename(mbias_frame);
526
527
528 mbias = giraffe_image_new(CPL_TYPE_DOUBLE);
529 status = giraffe_image_load(mbias, filename, 0);
530
531 if (status) {
532 cpl_msg_error(_id, "Cannot load master bias from '%s'. "
533 "Aborting ...", filename);
534
535 giraffe_bias_config_destroy(bias_config);
537
538 return 1;
539 }
540 }
541 }
542
543
544 /*
545 * Load bad pixel map if it is present in the frame set.
546 */
547
548 if (bpixel_frame) {
549
550 const cxchar* filename = cpl_frame_get_filename(bpixel_frame);
551
552
553 bpixel = giraffe_image_new(CPL_TYPE_INT);
554 status = giraffe_image_load(bpixel, filename, 0);
555
556 if (status) {
557 cpl_msg_error(_id, "Cannot load bad pixel map from '%s'. "
558 "Aborting ...", filename);
559
560 if (mbias != NULL) {
562 mbias = NULL;
563 }
564
565 giraffe_bias_config_destroy(bias_config);
567
568 return 1;
569 }
570
571 }
572
573
574 /*
575 * Compute and remove the bias from the stacked flat field frame.
576 */
577
578 mflat = giraffe_image_new(CPL_TYPE_DOUBLE);
579
580 status = giraffe_bias_remove(mflat, sflat, mbias, bpixel, biasareas,
581 bias_config);
582
584 sflat = NULL;
585
587 mbias = NULL;
588
589 giraffe_bias_config_destroy(bias_config);
590
591 if (status) {
592 cpl_msg_error(_id, "Bias removal failed. Aborting ...");
593
595 mflat = NULL;
596
597 if (bpixel != NULL) {
598 giraffe_image_delete(bpixel);
599 bpixel = NULL;
600 }
601
602 return 1;
603 }
604
605
606 /*
607 * Load master dark if it is present in the frame set and correct
608 * the master flat field for the dark current.
609 */
610
611 if (mdark_frame) {
612
613 const cxchar* filename = cpl_frame_get_filename(mdark_frame);
614
615 GiDarkConfig dark_config = {GIDARK_METHOD_ZMASTER, 0.};
616
617
618 mdark = giraffe_image_new(CPL_TYPE_DOUBLE);
619 status = giraffe_image_load(mdark, filename, 0);
620
621 if (status != 0) {
622 cpl_msg_error(_id, "Cannot load master dark from '%s'. "
623 "Aborting ...", filename);
624
626 mflat = NULL;
627
628 if (bpixel != NULL) {
629 giraffe_image_delete(bpixel);
630 bpixel = NULL;
631 }
632
633 return 1;
634 }
635
636 status = giraffe_subtract_dark(mflat, mdark, bpixel, NULL,
637 &dark_config);
638
639 if (status != 0) {
640 cpl_msg_error(_id, "Dark subtraction failed! Aborting ...");
641
643 mdark = NULL;
644
646 mflat = NULL;
647
648 if (bpixel != NULL) {
649 giraffe_image_delete(bpixel);
650 bpixel = NULL;
651 }
652
653 return 1;
654 }
655
657 mdark = NULL;
658
659 }
660
661
662 /*
663 * Update master flat field properties, save the master flat field frame
664 * and register it as product.
665 */
666
667 cpl_msg_info(_id, "Writing master flat field image ...");
668
669 giraffe_image_add_info(mflat, &info, set);
670
671 mflat_frame = giraffe_frame_create_image(mflat,
672 GIFRAME_FIBER_FLAT_MASTER,
673 CPL_FRAME_LEVEL_FINAL,
674 TRUE, TRUE);
675
676 if (mflat_frame == NULL) {
677 cpl_msg_error(_id, "Cannot create local file! Aborting ...");
678
680
681 if (bpixel) {
682 giraffe_image_delete(bpixel);
683 }
684
685 return 1;
686 }
687
688 cpl_frameset_insert(set, mflat_frame);
689
690
691 /*
692 * Determine fiber setup
693 */
694
695 cpl_msg_info(_id, "Recipe Step: Fiber setup");
696
697 fibers_config = giraffe_fibers_config_create(config);
698 flat_frame = cpl_frameset_find(set, GIFRAME_FIBER_FLAT);
699
700 cpl_msg_info(_id, "Building fiber setup for frame '%s'.",
701 cpl_frame_get_filename(flat_frame));
702
703 if (mlocy_frame == NULL) {
704
705 GiTable *active_fibers = NULL;
706
707 if (slit_frame != NULL) {
708
709 const cxchar *tag = cpl_frame_get_tag(slit_frame);
710 const cxchar *filename = cpl_frame_get_filename(slit_frame);
711
712 if (strcmp(tag, GIFRAME_SLITSETUP) == 0) {
713
714 active_fibers = giraffe_table_new();
715 status = giraffe_table_load(active_fibers,
716 cpl_frame_get_filename(slit_frame),
717 1, "SLIT_GEOMETRY_SETUP");
718
719 if (status) {
720 cpl_msg_error(_id, "Cannot load expected fiber setup from "
721 "slit geometry '%s'! Aborting ...", filename);
722
723 giraffe_table_delete(active_fibers);
725
726 if (bpixel) {
727 giraffe_image_delete(bpixel);
728 }
729
730 giraffe_fibers_config_destroy(fibers_config);
731
732 return 1;
733 }
734 }
735 }
736
737 fibers = giraffe_fibers_select(flat_frame, active_fibers,
738 fibers_config);
739
740 if (!fibers) {
741 cpl_msg_error(_id, "Cannot determine fiber setup from flat "
742 "field frame '%s'! Aborting ...",
743 cpl_frame_get_filename(flat_frame));
744
745 giraffe_table_delete(active_fibers);
747
748 if (bpixel) {
749 giraffe_image_delete(bpixel);
750 }
751
752 giraffe_fibers_config_destroy(fibers_config);
753
754 return 1;
755 }
756
757 giraffe_table_delete(active_fibers);
758 active_fibers = NULL;
759
760 cpl_msg_info(_id, "Fiber setup taken from flat field frame '%s'.",
761 cpl_frame_get_filename(flat_frame));
762
763 }
764 else {
765
766 cpl_msg_info(_id, "Fiber reference setup taken from localization "
767 "frame '%s'.", cpl_frame_get_filename(mlocy_frame));
768
769 fibers = giraffe_fibers_setup(flat_frame, mlocy_frame);
770
771 if (!fibers) {
772 cpl_msg_error(_id, "Cannot create fiber setup for frame '%s'! "
773 "Aborting ...", cpl_frame_get_filename(flat_frame));
774
776
777 if (bpixel) {
778 giraffe_image_delete(bpixel);
779 }
780
781 giraffe_fibers_config_destroy(fibers_config);
782
783 return 1;
784 }
785
786 }
787
788 giraffe_fibers_config_destroy(fibers_config);
789
790
791 /*
792 * Perform spectrum localization on the created master flat field.
793 */
794
795 if (mlocy_frame != NULL) {
796
797 const cxchar* filename = cpl_frame_get_filename(mlocy_frame);
798
799
800 mloc = giraffe_localization_new();
801 mloc->locy = giraffe_image_new(CPL_TYPE_DOUBLE);
802 status = giraffe_image_load(mloc->locy, filename, 0);
803
804 if (status) {
805 cpl_msg_error(_id, "Cannot load master localization centroids "
806 "from '%s'. Aborting ...", filename);
807
808 giraffe_localization_delete(mloc);
809 mloc = NULL;
810
811 giraffe_table_delete(fibers);
813
814 if (bpixel) {
815 giraffe_image_delete(bpixel);
816 }
817
818 giraffe_localize_config_destroy(localize_config);
819
820 return 1;
821 }
822
823 }
824
825 localize_config = giraffe_localize_config_create(config);
826
827 if (localize_config->full == FALSE) {
828
829 // FIXME: For the time being just release the memory acquired.
830 // In future the master localization has to be loaded here
831 // and its completeness has to be checked.
832
833 cpl_msg_error(_id, "Localization computation using only SIWC spectra "
834 "is not yet supported! Aborting ...");
835
836 giraffe_table_delete(fibers);
838
839 if (bpixel) {
840 giraffe_image_delete(bpixel);
841 }
842
843 giraffe_localize_config_destroy(localize_config);
844
845 return 1;
846
847 }
848
849 sloc = giraffe_localization_new();
850
851 status = giraffe_localize_spectra(sloc, mflat, fibers, mloc,
852 bpixel, localize_config);
853
854 if (status) {
855 cpl_msg_error(_id, "Spectrum localization failed! Aborting ...");
856
857
858 giraffe_localization_destroy(sloc);
859
860 if (mloc) {
861 giraffe_localization_destroy(mloc);
862 }
863
864 giraffe_table_delete(fibers);
866
867 if (bpixel) {
868 giraffe_image_delete(bpixel);
869 }
870
871 giraffe_localize_config_destroy(localize_config);
872
873 return 1;
874 }
875
876 giraffe_localize_config_destroy(localize_config);
877
878 if (mloc != NULL) {
879 giraffe_localization_destroy(mloc);
880 }
881
882
883 /*
884 * Save the computed localization and register its components as
885 * products.
886 */
887
888 cpl_msg_info(_id, "Writing fiber localization ...");
889
890
891 /* Localization centroids */
892
893 giraffe_image_add_info(sloc->locy, &info, set);
894
895 sloc_frame = giraffe_frame_create_image(sloc->locy,
896 GIFRAME_LOCALIZATION_CENTROID,
897 CPL_FRAME_LEVEL_FINAL,
898 TRUE, TRUE);
899
900 if (sloc_frame == NULL) {
901 cpl_msg_error(_id, "Cannot create local file! Aborting ...");
902
903 giraffe_localization_destroy(sloc);
904
905 giraffe_table_delete(fibers);
907
908 if (bpixel) {
909 giraffe_image_delete(bpixel);
910 }
911
912 return 1;
913 }
914
915 status = giraffe_fiberlist_attach(sloc_frame, fibers);
916
917 if (status) {
918 cpl_msg_error(_id, "Cannot attach fiber setup to local file '%s'! "
919 "Aborting ...", cpl_frame_get_filename(sloc_frame));
920
921 cpl_frame_delete(sloc_frame);
922
923 giraffe_localization_destroy(sloc);
924
925 giraffe_table_delete(fibers);
927
928 if (bpixel) {
929 giraffe_image_delete(bpixel);
930 }
931
932 return 1;
933 }
934
935 cpl_frameset_insert(set, sloc_frame);
936
937
938 /* Localization half-width */
939
940 giraffe_image_add_info(sloc->locw, &info, set);
941
942 sloc_frame = giraffe_frame_create_image(sloc->locw,
943 GIFRAME_LOCALIZATION_WIDTH,
944 CPL_FRAME_LEVEL_FINAL,
945 TRUE, TRUE);
946
947 if (sloc_frame == NULL) {
948 cpl_msg_error(_id, "Cannot create local file! Aborting ...");
949
950 giraffe_localization_destroy(sloc);
951
952 giraffe_table_delete(fibers);
954
955 if (bpixel) {
956 giraffe_image_delete(bpixel);
957 }
958
959 return 1;
960 }
961
962 status = giraffe_fiberlist_attach(sloc_frame, fibers);
963
964 if (status) {
965 cpl_msg_error(_id, "Cannot attach fiber setup to local file '%s'! "
966 "Aborting ...", cpl_frame_get_filename(sloc_frame));
967
968 cpl_frame_delete(sloc_frame);
969
970 giraffe_localization_destroy(sloc);
971
972 giraffe_table_delete(fibers);
974
975 if (bpixel) {
976 giraffe_image_delete(bpixel);
977 }
978
979 return 1;
980 }
981
982 cpl_frameset_insert(set, sloc_frame);
983
984 /* Localization fit coefficients */
985
986 if (sloc->locc) {
987
988 giraffe_table_add_info(sloc->locc, &info, set);
989
990 sloc_frame = giraffe_frame_create_table(sloc->locc,
991 GIFRAME_LOCALIZATION_FIT,
992 CPL_FRAME_LEVEL_FINAL,
993 TRUE, TRUE);
994
995 if (sloc_frame == NULL) {
996 cpl_msg_error(_id, "Cannot create local file! Aborting ...");
997
998 giraffe_localization_destroy(sloc);
999
1000 giraffe_table_delete(fibers);
1001 giraffe_image_delete(mflat);
1002
1003 if (bpixel) {
1004 giraffe_image_delete(bpixel);
1005 }
1006
1007 return 1;
1008 }
1009 }
1010
1011 cpl_frameset_insert(set, sloc_frame);
1012
1013
1014 /*
1015 * Remove the reference index from the fiber setup, since the just
1016 * created localization is now used as position reference of the fibers.
1017 */
1018
1020
1021
1022 /*
1023 * Compute localization mask from the PSF profile of the fibers
1024 */
1025
1026 psf_config = giraffe_psf_config_create(config);
1027
1028 if (psf_config == NULL) {
1029 cpl_msg_error(_id, "Invalid fiber profile fit configuration!");
1030
1031 giraffe_localization_destroy(sloc);
1032 sloc = NULL;
1033
1034 giraffe_table_delete(fibers);
1035 fibers = NULL;
1036
1037 giraffe_image_delete(mflat);
1038 mflat = NULL;
1039
1040 if (bpixel != NULL) {
1041 giraffe_image_delete(bpixel);
1042 bpixel = NULL;
1043 }
1044
1045 return 1;
1046
1047 }
1048
1049 ploc = giraffe_localization_new();
1050
1051 status = giraffe_compute_fiber_profiles(ploc, mflat, fibers, sloc,
1052 bpixel, psf_config);
1053
1054 if (status != 0) {
1055 cpl_msg_error(_id, "Fiber profile computation failed! Aborting ...");
1056
1057 giraffe_localization_destroy(ploc);
1058 ploc = NULL;
1059
1060 giraffe_psf_config_destroy(psf_config);
1061 psf_config = NULL;
1062
1063 giraffe_localization_destroy(sloc);
1064 sloc = NULL;
1065
1066 giraffe_table_delete(fibers);
1067 fibers = NULL;
1068
1069 giraffe_image_delete(mflat);
1070 mflat = NULL;
1071
1072 if (bpixel != NULL) {
1073 giraffe_image_delete(bpixel);
1074 bpixel = NULL;
1075 }
1076
1077 return 1;
1078
1079 }
1080
1081 giraffe_psf_config_destroy(psf_config);
1082 psf_config = NULL;
1083
1084 giraffe_localization_destroy(sloc);
1085 sloc = NULL;
1086
1087
1088 /*
1089 * Save the computed fiber traces and register its components as
1090 * products.
1091 */
1092
1093 cpl_msg_info(_id, "Writing fiber traces ...");
1094
1095
1096 /* Fiber profile centroids */
1097
1098 giraffe_image_add_info(ploc->locy, &info, set);
1099
1100 ploc_frame = giraffe_frame_create_image(ploc->locy,
1101 GIFRAME_PSF_CENTROID,
1102 CPL_FRAME_LEVEL_FINAL,
1103 TRUE, TRUE);
1104
1105 if (ploc_frame == NULL) {
1106 cpl_msg_error(_id, "Cannot create local file! Aborting ...");
1107
1108 giraffe_localization_destroy(ploc);
1109 ploc = NULL;
1110
1111 giraffe_table_delete(fibers);
1112 fibers = NULL;
1113
1114 giraffe_image_delete(mflat);
1115 mflat = NULL;
1116
1117 if (bpixel != NULL) {
1118 giraffe_image_delete(bpixel);
1119 bpixel = NULL;
1120 }
1121
1122 return 1;
1123 }
1124
1125 status = giraffe_fiberlist_attach(ploc_frame, fibers);
1126
1127 if (status != 0) {
1128 cpl_msg_error(_id, "Cannot attach fiber setup to local file '%s'! "
1129 "Aborting ...", cpl_frame_get_filename(ploc_frame));
1130
1131 cpl_frame_delete(ploc_frame);
1132
1133 giraffe_localization_destroy(ploc);
1134 ploc = NULL;
1135
1136 giraffe_table_delete(fibers);
1137 fibers = NULL;
1138
1139 giraffe_image_delete(mflat);
1140 mflat = NULL;
1141
1142 if (bpixel != NULL) {
1143 giraffe_image_delete(bpixel);
1144 bpixel = NULL;
1145 }
1146
1147 return 1;
1148 }
1149
1150 cpl_frameset_insert(set, ploc_frame);
1151
1152
1153 /* Fiber profile widths */
1154
1155 giraffe_image_add_info(ploc->locw, &info, set);
1156
1157 ploc_frame = giraffe_frame_create_image(ploc->locw,
1158 GIFRAME_PSF_WIDTH,
1159 CPL_FRAME_LEVEL_FINAL,
1160 TRUE, TRUE);
1161
1162 if (ploc_frame == NULL) {
1163 cpl_msg_error(_id, "Cannot create local file! Aborting ...");
1164
1165 giraffe_localization_destroy(ploc);
1166 ploc = NULL;
1167
1168 giraffe_table_delete(fibers);
1169 fibers = NULL;
1170
1171 giraffe_image_delete(mflat);
1172 mflat = NULL;
1173
1174 if (bpixel != NULL) {
1175 giraffe_image_delete(bpixel);
1176 bpixel = NULL;
1177 }
1178
1179 return 1;
1180 }
1181
1182 status = giraffe_fiberlist_attach(ploc_frame, fibers);
1183
1184 if (status != 0) {
1185 cpl_msg_error(_id, "Cannot attach fiber setup to local file '%s'! "
1186 "Aborting ...", cpl_frame_get_filename(ploc_frame));
1187
1188 cpl_frame_delete(ploc_frame);
1189
1190 giraffe_localization_destroy(ploc);
1191 ploc = NULL;
1192
1193 giraffe_table_delete(fibers);
1194 fibers = NULL;
1195
1196 giraffe_image_delete(mflat);
1197 mflat = NULL;
1198
1199 if (bpixel != NULL) {
1200 giraffe_image_delete(bpixel);
1201 bpixel = NULL;
1202 }
1203
1204 return 1;
1205 }
1206
1207 cpl_frameset_insert(set, ploc_frame);
1208
1209
1210 /* Fiber profile centroid and widths fit coefficients */
1211
1212 giraffe_table_add_info(ploc->locc, &info, set);
1213
1214 ploc_frame = giraffe_frame_create_table(ploc->locc,
1215 GIFRAME_PSF_FIT,
1216 CPL_FRAME_LEVEL_FINAL,
1217 TRUE, TRUE);
1218
1219 if (ploc_frame == NULL) {
1220 cpl_msg_error(_id, "Cannot create local file! Aborting ...");
1221
1222 giraffe_localization_destroy(ploc);
1223 ploc = NULL;
1224
1225 giraffe_table_delete(fibers);
1226 fibers = NULL;
1227
1228 giraffe_image_delete(mflat);
1229 mflat = NULL;
1230
1231 if (bpixel != NULL) {
1232 giraffe_image_delete(bpixel);
1233 bpixel = NULL;
1234 }
1235
1236 return 1;
1237 }
1238
1239 status = giraffe_fiberlist_attach(ploc_frame, fibers);
1240
1241 if (status != 0) {
1242 cpl_msg_error(_id, "Cannot attach fiber setup to local file '%s'! "
1243 "Aborting ...", cpl_frame_get_filename(ploc_frame));
1244
1245 cpl_frame_delete(ploc_frame);
1246
1247 giraffe_localization_destroy(ploc);
1248 ploc = NULL;
1249
1250 giraffe_table_delete(fibers);
1251 fibers = NULL;
1252
1253 giraffe_image_delete(mflat);
1254 mflat = NULL;
1255
1256 if (bpixel != NULL) {
1257 giraffe_image_delete(bpixel);
1258 bpixel = NULL;
1259 }
1260
1261 return 1;
1262 }
1263
1264 cpl_frameset_insert(set, ploc_frame);
1265
1266
1267 if (ploc->psf) {
1268
1269 GiFrameCreator creator = (GiFrameCreator) giraffe_psfdata_save;
1270
1271 properties = giraffe_image_get_properties(ploc->locy);
1272
1273 ploc_frame = giraffe_frame_create(GIFRAME_PSF_DATA,
1274 CPL_FRAME_LEVEL_FINAL,
1275 properties, ploc->psf,
1276 NULL,
1277 creator);
1278
1279 if (ploc_frame == NULL) {
1280 cpl_msg_error(_id, "Cannot create local file! Aborting ...");
1281
1282 giraffe_localization_destroy(ploc);
1283 ploc = NULL;
1284
1285 giraffe_table_delete(fibers);
1286 fibers = NULL;
1287
1288 giraffe_image_delete(mflat);
1289 mflat = NULL;
1290
1291 if (bpixel != NULL) {
1292 giraffe_image_delete(bpixel);
1293 bpixel = NULL;
1294 }
1295
1296 return 1;
1297 }
1298
1299 status = giraffe_fiberlist_attach(ploc_frame, fibers);
1300
1301 if (status != 0) {
1302 cpl_msg_error(_id, "Cannot attach fiber setup to local "
1303 "file '%s'! Aborting ...",
1304 cpl_frame_get_filename(ploc_frame));
1305
1306 cpl_frame_delete(ploc_frame);
1307
1308 giraffe_localization_destroy(ploc);
1309 ploc = NULL;
1310
1311 giraffe_table_delete(fibers);
1312 fibers = NULL;
1313
1314 giraffe_image_delete(mflat);
1315 mflat = NULL;
1316
1317 if (bpixel != NULL) {
1318 giraffe_image_delete(bpixel);
1319 bpixel = NULL;
1320 }
1321
1322 return 1;
1323 }
1324
1325 cpl_frameset_insert(set, ploc_frame);
1326
1327 }
1328
1329
1330 /*
1331 * Optional scattered light model computation
1332 */
1333
1334 // FIXME: Check whether scattered light modeling code should stay here!
1335
1336 if (slmodel == TRUE) {
1337
1338 cpl_frame* slmodel_frame = NULL;
1339
1340 GiSLightConfig* slight_config = NULL;
1341
1342
1343 cpl_msg_info(_id, "Computing scattered light model ...");
1344
1345 slight_config = giraffe_slight_config_create(config);
1346
1347 if (slight_config == NULL) {
1348 cpl_msg_error(_id, "Invalid scattered light model "
1349 "configuration!");
1350
1351 giraffe_table_delete(fibers);
1352 giraffe_image_delete(mflat);
1353
1354 if (bpixel) {
1355 giraffe_image_delete(bpixel);
1356 }
1357
1358 giraffe_localization_destroy(ploc);
1359 ploc = NULL;
1360
1361 return 1;
1362
1363 }
1364
1365 slight = giraffe_image_new(CPL_TYPE_DOUBLE);
1366
1367 status = giraffe_adjust_scattered_light(slight, mflat, ploc,
1368 bpixel, NULL, slight_config);
1369
1370 if (status != 0) {
1371 cpl_msg_error(_id, "Scattered light model computation failed! "
1372 "Aborting ...");
1373
1374 giraffe_image_delete(slight);
1375
1376 giraffe_slight_config_destroy(slight_config);
1377
1378 giraffe_table_delete(fibers);
1379 giraffe_image_delete(mflat);
1380
1381 if (bpixel != NULL) {
1382 giraffe_image_delete(bpixel);
1383 bpixel = NULL;
1384 }
1385
1386 giraffe_localization_destroy(ploc);
1387 ploc = NULL;
1388
1389 return 1;
1390 }
1391
1392
1393 giraffe_slight_config_destroy(slight_config);
1394 slight_config = NULL;
1395
1396
1397 /*
1398 * Save scattered light model
1399 */
1400
1401 cpl_msg_info(_id, "Writing scattered light model ...");
1402
1403 giraffe_image_add_info(slight, &info, set);
1404
1405 slmodel_frame =
1407 GIFRAME_SCATTERED_LIGHT_MODEL,
1408 CPL_FRAME_LEVEL_FINAL,
1409 TRUE, TRUE);
1410
1411 if (slmodel_frame == NULL) {
1412 cpl_msg_error(_id, "Cannot create local file! Aborting ...");
1413
1414 giraffe_image_delete(slight);
1415
1416 giraffe_table_delete(fibers);
1417 giraffe_image_delete(mflat);
1418
1419 if (bpixel != NULL) {
1420 giraffe_image_delete(bpixel);
1421 bpixel = NULL;
1422 }
1423
1424 giraffe_localization_destroy(ploc);
1425 ploc = NULL;
1426
1427 return 1;
1428 }
1429
1430 cpl_frameset_insert(set, slmodel_frame);
1431
1432 giraffe_image_delete(slight);
1433 slight = NULL;
1434
1435 }
1436
1437
1438 /*
1439 * Perform spectrum extraction on the master flat field.
1440 */
1441
1442 cpl_msg_info(_id, "Extracting spectra ...");
1443
1444 if (slight_frame != NULL) {
1445
1446 const cxchar* filename = cpl_frame_get_filename(slight_frame);
1447
1448
1449 slight = giraffe_image_new(CPL_TYPE_DOUBLE);
1450 status = giraffe_image_load(slight, filename, 0);
1451
1452 if (status != 0) {
1453 cpl_msg_error(_id, "Cannot load scattered light model from '%s'. "
1454 "Aborting ...", filename);
1455
1456 giraffe_image_delete(slight);
1457
1458 giraffe_table_delete(fibers);
1459 giraffe_image_delete(mflat);
1460
1461 if (bpixel != NULL) {
1462 giraffe_image_delete(bpixel);
1463 bpixel = NULL;
1464 }
1465
1466 giraffe_localization_destroy(ploc);
1467 ploc = NULL;
1468
1469 return 1;
1470
1471 }
1472
1473 }
1474
1475 extract_config = giraffe_extract_config_create(config);
1476
1477 extraction = giraffe_extraction_new();
1478
1479 status = giraffe_extract_spectra(extraction, mflat, fibers,
1480 ploc, bpixel, slight,
1481 extract_config);
1482
1483 if (status != 0) {
1484 cpl_msg_error(_id, "Spectrum extraction failed! Aborting ...");
1485
1486 giraffe_extraction_destroy(extraction);
1487
1488 giraffe_image_delete(slight);
1489
1490 giraffe_localization_destroy(ploc);
1491 ploc = NULL;
1492
1493 giraffe_table_delete(fibers);
1494 giraffe_image_delete(mflat);
1495
1496 if (bpixel != NULL) {
1497 giraffe_image_delete(bpixel);
1498 bpixel = NULL;
1499 }
1500
1501 giraffe_extract_config_destroy(extract_config);
1502
1503 return 1;
1504 }
1505
1506 giraffe_image_delete(slight);
1507 giraffe_image_delete(mflat);
1508
1509 if (bpixel != NULL) {
1510 giraffe_image_delete(bpixel);
1511 bpixel = NULL;
1512 }
1513
1514 giraffe_extract_config_destroy(extract_config);
1515
1516
1517 /*
1518 * Normalize extracted spectra and errors
1519 */
1520
1521 mean = cpl_image_get_mean(giraffe_image_get(extraction->spectra));
1522
1523 cpl_image_divide_scalar(giraffe_image_get(extraction->spectra), mean);
1524
1525 properties = giraffe_image_get_properties(extraction->spectra);
1526 cpl_propertylist_update_double(properties, GIALIAS_FLAT_SCALE, mean);
1527 cpl_propertylist_set_comment(properties, GIALIAS_FLAT_SCALE,
1528 "Flat field scale factor");
1529
1530
1531 cpl_image_divide_scalar(giraffe_image_get(extraction->error), mean);
1532
1533 properties = giraffe_image_get_properties(extraction->error);
1534 cpl_propertylist_update_double(properties, GIALIAS_FLAT_SCALE, mean);
1535 cpl_propertylist_set_comment(properties, GIALIAS_FLAT_SCALE,
1536 "Flat field scale factor");
1537
1538
1539 /*
1540 * Compute relative fiber transmission correction.
1541 */
1542
1543 if (transmission == TRUE) {
1544
1545 const cxchar* filename = NULL;
1546
1547
1548 transmission_config = giraffe_transmission_config_create(config);
1549
1550 cpl_msg_info(_id, "Computing relative fiber transmission ...");
1551
1552 filename = cpl_frame_get_filename(grating_frame);
1553
1554 grating = giraffe_table_new();
1555 status = giraffe_table_load(grating, filename, 1, NULL);
1556
1557 if (status != 0) {
1558 cpl_msg_error(_id, "Cannot load grating data from '%s'. "
1559 "Aborting ...", filename);
1560
1561 giraffe_table_delete(grating);
1562
1563 giraffe_transmission_config_destroy(transmission_config);
1564
1565 giraffe_extraction_destroy(extraction);
1566
1567 giraffe_localization_destroy(ploc);
1568 ploc = NULL;
1569
1570 giraffe_table_delete(fibers);
1571
1572 return 1;
1573 }
1574
1575
1576 filename = cpl_frame_get_filename(slit_frame);
1577
1578 slitgeometry = giraffe_slitgeometry_load(fibers, filename, 1, NULL);
1579
1580 if (slitgeometry == NULL) {
1581 cpl_msg_error(_id, "Cannot load slit geometry data from '%s'. "
1582 "Aborting ...", filename);
1583
1584 giraffe_table_delete(grating);
1585
1586 giraffe_transmission_config_destroy(transmission_config);
1587
1588 giraffe_extraction_destroy(extraction);
1589
1590 giraffe_localization_destroy(ploc);
1591 ploc = NULL;
1592
1593 giraffe_table_delete(fibers);
1594
1595 return 1;
1596 }
1597 else {
1598
1599 /*
1600 * Check whether the contains the positions for all fibers
1601 * provided by the fiber setup. If this is not the case
1602 * this is an error.
1603 */
1604
1605 if (giraffe_fiberlist_compare(slitgeometry, fibers) != 1) {
1606 cpl_msg_error(_id, "Slit geometry data from '%s' is not "
1607 "applicable for current fiber setup! "
1608 "Aborting ...", filename);
1609
1610 giraffe_table_delete(slitgeometry);
1611 giraffe_table_delete(grating);
1612
1613 giraffe_transmission_config_destroy(transmission_config);
1614
1615 giraffe_extraction_destroy(extraction);
1616
1617 giraffe_localization_destroy(ploc);
1618 ploc = NULL;
1619
1620 giraffe_table_delete(fibers);
1621
1622 return 1;
1623 }
1624
1625 }
1626
1627
1628 if (wcal_frame != NULL) {
1629
1630 filename = cpl_frame_get_filename(wcal_frame);
1631
1632 cpl_msg_info(_id, "Loading wavelength solution from '%s'",
1633 filename);
1634
1635 wlsolution = giraffe_table_new();
1636 status = giraffe_table_load(wlsolution, filename, 1, NULL);
1637
1638 if (status != 0) {
1639 cpl_msg_error(_id, "Cannot load wavelength solution from "
1640 "'%s'. Aborting ...", filename);
1641
1642 giraffe_table_delete(wlsolution);
1643 giraffe_table_delete(slitgeometry);
1644 giraffe_table_delete(grating);
1645
1646 giraffe_transmission_config_destroy(transmission_config);
1647
1648 giraffe_extraction_destroy(extraction);
1649
1650 giraffe_localization_destroy(ploc);
1651 ploc = NULL;
1652
1653 giraffe_table_delete(fibers);
1654
1655 return 1;
1656 }
1657
1658 }
1659
1660
1661 status = giraffe_transmission_compute(extraction, fibers,
1662 ploc, wlsolution,
1663 grating, slitgeometry);
1664
1665 if (status != 0) {
1666 cpl_msg_error(_id, "Relative transmission computation failed! "
1667 "Aborting ...");
1668
1669 if (wlsolution != NULL) {
1670 giraffe_table_delete(wlsolution);
1671 wlsolution = NULL;
1672 }
1673
1674 giraffe_table_delete(slitgeometry);
1675 giraffe_table_delete(grating);
1676
1677 giraffe_transmission_config_destroy(transmission_config);
1678
1679 giraffe_extraction_destroy(extraction);
1680
1681 giraffe_localization_destroy(ploc);
1682 ploc = NULL;
1683
1684 giraffe_table_delete(fibers);
1685
1686 return 1;
1687 }
1688
1689 if (wlsolution != NULL) {
1690 giraffe_table_delete(wlsolution);
1691 wlsolution = NULL;
1692 }
1693
1694 giraffe_table_delete(slitgeometry);
1695 giraffe_table_delete(grating);
1696
1697 giraffe_transmission_config_destroy(transmission_config);
1698
1699 }
1700
1701 giraffe_localization_destroy(ploc);
1702 ploc = NULL;
1703
1704
1705 /*
1706 * Save the spectrum extraction results and register them as
1707 * products.
1708 */
1709
1710 cpl_msg_info(_id, "Writing extracted spectra ...");
1711
1712 /* Extracted spectra */
1713
1714 giraffe_image_add_info(extraction->spectra, &info, set);
1715
1716 sext_frame = giraffe_frame_create_image(extraction->spectra,
1717 GIFRAME_FIBER_FLAT_EXTSPECTRA,
1718 CPL_FRAME_LEVEL_FINAL,
1719 TRUE, TRUE);
1720
1721 if (sext_frame == NULL) {
1722 cpl_msg_error(_id, "Cannot create local file! Aborting ...");
1723
1724 giraffe_extraction_destroy(extraction);
1725 giraffe_table_delete(fibers);
1726
1727 return 1;
1728 }
1729
1730 status = giraffe_fiberlist_attach(sext_frame, fibers);
1731
1732 if (status != 0) {
1733 cpl_msg_error(_id, "Cannot attach fiber setup to local file '%s'! "
1734 "Aborting ...", cpl_frame_get_filename(sext_frame));
1735
1736 cpl_frame_delete(sext_frame);
1737
1738 giraffe_extraction_destroy(extraction);
1739 giraffe_table_delete(fibers);
1740
1741 return 1;
1742 }
1743
1744 cpl_frameset_insert(set, sext_frame);
1745
1746 /* Extracted spectra errors */
1747
1748 giraffe_image_add_info(extraction->error, &info, set);
1749
1750 sext_frame = giraffe_frame_create_image(extraction->error,
1751 GIFRAME_FIBER_FLAT_EXTERRORS,
1752 CPL_FRAME_LEVEL_FINAL,
1753 TRUE, TRUE);
1754
1755 if (sext_frame == NULL) {
1756 cpl_msg_error(_id, "Cannot create local file! Aborting ...");
1757
1758 giraffe_extraction_destroy(extraction);
1759 giraffe_table_delete(fibers);
1760
1761 return 1;
1762 }
1763
1764 status = giraffe_fiberlist_attach(sext_frame, fibers);
1765
1766 if (status != 0) {
1767 cpl_msg_error(_id, "Cannot attach fiber setup to local file '%s'! "
1768 "Aborting ...", cpl_frame_get_filename(sext_frame));
1769
1770 cpl_frame_delete(sext_frame);
1771
1772 giraffe_extraction_destroy(extraction);
1773 giraffe_table_delete(fibers);
1774
1775 return 1;
1776 }
1777
1778 cpl_frameset_insert(set, sext_frame);
1779
1780 /* Extracted spectra pixels */
1781
1782 if (extraction->npixels != NULL) {
1783
1784 giraffe_image_add_info(extraction->npixels, &info, set);
1785
1786 sext_frame = giraffe_frame_create_image(extraction->npixels,
1787 GIFRAME_FIBER_FLAT_EXTPIXELS,
1788 CPL_FRAME_LEVEL_FINAL,
1789 TRUE, TRUE);
1790
1791 if (sext_frame == NULL) {
1792 cpl_msg_error(_id, "Cannot create local file! Aborting ...");
1793
1794 giraffe_extraction_destroy(extraction);
1795 giraffe_table_delete(fibers);
1796
1797 return 1;
1798 }
1799
1800 status = giraffe_fiberlist_attach(sext_frame, fibers);
1801
1802 if (status != 0) {
1803 cpl_msg_error(_id, "Cannot attach fiber setup to local file '%s'! "
1804 "Aborting ...", cpl_frame_get_filename(sext_frame));
1805
1806 cpl_frame_delete(sext_frame);
1807
1808 giraffe_extraction_destroy(extraction);
1809 giraffe_table_delete(fibers);
1810
1811 return 1;
1812 }
1813
1814 cpl_frameset_insert(set, sext_frame);
1815
1816 }
1817
1818 /* Extracted spectra centroids */
1819
1820 giraffe_image_add_info(extraction->centroid, &info, set);
1821
1822 sext_frame = giraffe_frame_create_image(extraction->centroid,
1823 GIFRAME_FIBER_FLAT_EXTTRACE,
1824 CPL_FRAME_LEVEL_FINAL,
1825 TRUE, TRUE);
1826
1827 if (sext_frame == NULL) {
1828 cpl_msg_error(_id, "Cannot create local file! Aborting ...");
1829
1830 giraffe_extraction_destroy(extraction);
1831 giraffe_table_delete(fibers);
1832
1833 return 1;
1834 }
1835
1836 status = giraffe_fiberlist_attach(sext_frame, fibers);
1837
1838 if (status != 0) {
1839 cpl_msg_error(_id, "Cannot attach fiber setup to local file '%s'! "
1840 "Aborting ...", cpl_frame_get_filename(sext_frame));
1841
1842 cpl_frame_delete(sext_frame);
1843
1844 giraffe_extraction_destroy(extraction);
1845 giraffe_table_delete(fibers);
1846
1847 return 1;
1848 }
1849
1850 cpl_frameset_insert(set, sext_frame);
1851
1852 /* Extraction model spectra */
1853
1854 if (extraction->model != NULL) {
1855
1856 giraffe_image_add_info(extraction->model, &info, set);
1857
1858 sext_frame = giraffe_frame_create_image(extraction->model,
1859 GIFRAME_FIBER_FLAT_EXTMODEL,
1860 CPL_FRAME_LEVEL_FINAL,
1861 TRUE, TRUE);
1862
1863 if (sext_frame == NULL) {
1864 cpl_msg_error(_id, "Cannot create local file! Aborting ...");
1865
1866 giraffe_extraction_destroy(extraction);
1867 giraffe_table_delete(fibers);
1868
1869 return 1;
1870 }
1871
1872 status = giraffe_fiberlist_attach(sext_frame, fibers);
1873
1874 if (status != 0) {
1875 cpl_msg_error(_id, "Cannot attach fiber setup to local file '%s'! "
1876 "Aborting ...", cpl_frame_get_filename(sext_frame));
1877
1878 cpl_frame_delete(sext_frame);
1879
1880 giraffe_extraction_destroy(extraction);
1881 giraffe_table_delete(fibers);
1882
1883 return 1;
1884 }
1885
1886 cpl_frameset_insert(set, sext_frame);
1887
1888 }
1889
1890
1891 /*
1892 * Cleanup
1893 */
1894
1895 giraffe_extraction_destroy(extraction);
1896 giraffe_table_delete(fibers);
1897
1898 return 0;
1899
1900}
1901
1902
1903static cxint
1904giqcmasterflat(cpl_frameset* set)
1905{
1906
1907 const cxchar* const fctid = "giqcmasterflat";
1908
1909
1910 cxint i = 0;
1911 cxint nx = 0;
1912 cxint ny = 0;
1913 cxint npixel = 0;
1914 cxint nsaturated = 0;
1915 cxint status = 0;
1916
1917 const cxdouble saturation = 60000.;
1918 const cxdouble* pixels = NULL;
1919 cxdouble efficiency[2] = {0., 0.};
1920 cxdouble qcfluxm = 0;
1921 cxdouble scale = 1.;
1922 cxdouble mean = 0.;
1923 cxdouble meanfull = 0.;
1924 cxdouble rms = 0.;
1925 cxdouble rms2 = 0.;
1926 cxdouble diff = 0.;
1927 cxdouble* _pdata = NULL;
1928 cxdouble* _tdata = NULL;
1929
1930 cpl_propertylist* properties = NULL;
1931 cpl_propertylist* qclog = NULL;
1932
1933 cpl_frame* rframe = NULL;
1934 cpl_frame* pframe = NULL;
1935
1936 cpl_image* _rimage = NULL;
1937 cpl_image* _pimage = NULL;
1938 cpl_image* _test = NULL;
1939
1940 cpl_table* _ptable = NULL;
1941
1942 GiImage* rimage = NULL;
1943 GiImage* pimage = NULL;
1944
1945 GiTable* ptable = NULL;
1946
1947 GiPaf* qc = NULL;
1948
1949 GiWindow w = {0, 0, 0, 0};
1950
1951 cxdouble fibmed = 0.;
1952
1953
1954
1955 cpl_msg_info(fctid, "Computing QC1 parameters ...");
1956
1957 qc = giraffe_qclog_open(0);
1958
1959 if (qc == NULL) {
1960 cpl_msg_error(fctid, "Cannot create QC1 log!");
1961 return 1;
1962 }
1963
1964 qclog = giraffe_paf_get_properties(qc);
1965 cx_assert(qclog != NULL);
1966
1967
1968 /*
1969 * Compute lamp efficiencies from the rebinned frame if
1970 * it is available. If not the efficiencies are set to 0.
1971 */
1972
1973 pframe = giraffe_get_frame(set, GIFRAME_FIBER_FLAT_EXTSPECTRA,
1974 CPL_FRAME_GROUP_PRODUCT);
1975
1976 if (pframe == NULL) {
1977
1978 cpl_msg_warning(fctid, "Product '%s' not found.",
1979 GIFRAME_FIBER_FLAT_EXTSPECTRA);
1980
1981 cpl_msg_warning(fctid, "Setting lamp efficiencies (%s, %s) to 0.",
1982 GIALIAS_QCLAMP, GIALIAS_QCLAMP_SIMCAL);
1983
1984 efficiency[0] = 0.;
1985 efficiency[1] = 0.;
1986
1987 }
1988
1989
1990 pimage = giraffe_image_new(CPL_TYPE_DOUBLE);
1991 status = giraffe_image_load(pimage, cpl_frame_get_filename(pframe), 0);
1992
1993 if (status != 0) {
1994 cpl_msg_error(fctid, "Could not load extracted spectra '%s'!",
1995 cpl_frame_get_filename(pframe));
1996
1997 giraffe_image_delete(pimage);
1998 pimage = NULL;
1999
2000 giraffe_paf_delete(qc);
2001 qc = NULL;
2002
2003 return 1;
2004 }
2005
2006 _pimage = giraffe_image_get(pimage);
2007 cx_assert(_pimage != NULL);
2008
2009
2010 ptable = giraffe_table_new();
2011 status = giraffe_table_load(ptable, cpl_frame_get_filename(pframe), 1,
2012 NULL);
2013
2014 if (status != 0) {
2015 cpl_msg_error(fctid, "Could not load extracted spectra fiber setup!");
2016
2017 giraffe_table_delete(ptable);
2018 ptable = NULL;
2019
2020 giraffe_image_delete(pimage);
2021 pimage = NULL;
2022
2023 giraffe_paf_delete(qc);
2024 qc = NULL;
2025
2026 return 1;
2027 }
2028
2029 _ptable = giraffe_table_get(ptable);
2030 cx_assert(_ptable != NULL);
2031
2032 if (cpl_table_has_column(_ptable, "RP") == FALSE) {
2033
2034 cpl_msg_warning(fctid, "Column 'RP' not found in fiber setup table!");
2035 cpl_msg_warning(fctid, "Setting lamp efficiencies (%s, %s) to 0.",
2036 GIALIAS_QCLAMP, GIALIAS_QCLAMP_SIMCAL);
2037
2038 efficiency[0] = 0.;
2039 efficiency[1] = 0.;
2040
2041 }
2042 else {
2043
2044 properties = giraffe_image_get_properties(pimage);
2045 cx_assert(properties != NULL);
2046
2047 if (cpl_propertylist_has(properties, GIALIAS_EXPTIME) == FALSE) {
2048
2049 cpl_msg_warning(fctid, "Property '%s' not found in '%s'.",
2050 GIALIAS_EXPTIME, cpl_frame_get_filename(rframe));
2051 cpl_msg_warning(fctid, "Setting lamp efficiencies (%s, %s) to 0.",
2052 GIALIAS_QCLAMP, GIALIAS_QCLAMP_SIMCAL);
2053
2054 efficiency[0] = 0.;
2055 efficiency[1] = 0.;
2056
2057 }
2058 else {
2059
2060 cxbool scaled = cpl_propertylist_has(properties,
2061 GIALIAS_FLAT_SCALE);
2062
2063 cxint fiber = 0;
2064 cxint nb = cpl_image_get_size_y(_pimage);
2065 cxint nf[2] = {0, 0};
2066
2067 cxdouble exptime = cpl_propertylist_get_double(properties,
2068 GIALIAS_EXPTIME);
2069 cxdouble* _sum = NULL;
2070
2071 cpl_image* sum = NULL;
2072
2073
2074 if (scaled == TRUE) {
2075
2076 scale = cpl_propertylist_get_double(properties,
2077 GIALIAS_FLAT_SCALE);
2078 cpl_image_multiply_scalar(_pimage, scale);
2079
2080
2081 }
2082
2083 sum = cpl_image_collapse_create(_pimage, 0);
2084 _sum = cpl_image_get_data_double(sum);
2085
2086 for (fiber = 0; fiber < cpl_table_get_nrow(_ptable); ++fiber) {
2087
2088 cxint rp = cpl_table_get_int(_ptable, "RP", fiber, NULL);
2089
2090 if (rp == -1) {
2091 efficiency[1] += _sum[fiber];
2092 ++nf[1];
2093 }
2094 else {
2095 efficiency[0] += _sum[fiber];
2096 ++nf[0];
2097 }
2098
2099 }
2100
2101 fibmed = cpl_image_get_median(sum) / scale / nb;
2102
2103 _sum = NULL;
2104
2105 cpl_image_delete(sum);
2106 sum = NULL;
2107
2108 if (nf[0] == 0) {
2109 cpl_msg_warning(fctid, "No OzPoz fibers found in the "
2110 "current fiber setup.");
2111 cpl_msg_warning(fctid, "Setting lamp efficiency (%s) to 0.",
2112 GIALIAS_QCLAMP);
2113 efficiency[0] = 0.;
2114 }
2115 else {
2116 efficiency[0] /= nf[0] * nb * exptime;
2117 }
2118
2119 if (nf[1] == 0) {
2120 cpl_msg_warning(fctid, "No simultaneous calibration fibers "
2121 "found in the current fiber setup.");
2122 cpl_msg_warning(fctid, "Setting lamp efficiency (%s) to 0.",
2123 GIALIAS_QCLAMP_SIMCAL);
2124 efficiency[1] = 0.;
2125 }
2126 else {
2127 efficiency[1] /= nf[1] * nb * exptime;
2128 }
2129
2130 }
2131
2132 properties = NULL;
2133
2134 }
2135
2136 _ptable = NULL;
2137 _pimage = NULL;
2138
2139 giraffe_table_delete(ptable);
2140 ptable = NULL;
2141
2142 giraffe_image_delete(pimage);
2143 pimage = NULL;
2144
2145
2146 /*
2147 * Process master flat field
2148 */
2149
2150
2151 pframe = giraffe_get_frame(set, GIFRAME_FIBER_FLAT_MASTER,
2152 CPL_FRAME_GROUP_PRODUCT);
2153
2154 if (pframe == NULL) {
2155 cpl_msg_error(fctid, "Missing product frame (%s)",
2156 GIFRAME_FIBER_FLAT_MASTER);
2157
2158 giraffe_paf_delete(qc);
2159 qc = NULL;
2160
2161 return 1;
2162 }
2163
2164 cpl_msg_info(fctid, "Processing product frame '%s' (%s)",
2165 cpl_frame_get_filename(pframe), cpl_frame_get_tag(pframe));
2166
2167 pimage = giraffe_image_new(CPL_TYPE_DOUBLE);
2168 status = giraffe_image_load(pimage, cpl_frame_get_filename(pframe), 0);
2169
2170 if (status != 0) {
2171 cpl_msg_error(fctid, "Could not load master flat field '%s'!",
2172 cpl_frame_get_filename(pframe));
2173
2174 giraffe_image_delete(pimage);
2175 pimage = NULL;
2176
2177 giraffe_paf_delete(qc);
2178 qc = NULL;
2179
2180 return 1;
2181 }
2182
2183
2184 /*
2185 * Load first raw image as reference
2186 */
2187
2188 rframe = cpl_frameset_find(set, GIFRAME_FIBER_FLAT);
2189
2190 if (rframe == NULL) {
2191 cpl_msg_error(fctid, "Missing raw frame (%s)", GIFRAME_FIBER_FLAT);
2192
2193 giraffe_image_delete(pimage);
2194 pimage = NULL;
2195
2196 giraffe_paf_delete(qc);
2197 qc = NULL;
2198
2199 return 1;
2200 }
2201
2202 rimage = giraffe_image_new(CPL_TYPE_DOUBLE);
2203 status = giraffe_image_load(rimage, cpl_frame_get_filename(rframe), 0);
2204
2205 if (status != 0) {
2206
2207 cpl_msg_error(fctid, "Could not load flat field '%s'!",
2208 cpl_frame_get_filename(rframe));
2209
2210 giraffe_image_delete(rimage);
2211 rimage = NULL;
2212
2213 giraffe_image_delete(pimage);
2214 pimage = NULL;
2215
2216 giraffe_paf_delete(qc);
2217 qc = NULL;
2218
2219 return 1;
2220
2221 }
2222
2223 _rimage = giraffe_image_get(rimage);
2224 cx_assert(_rimage != NULL);
2225
2226 properties = giraffe_image_get_properties(rimage);
2227 cx_assert(properties != NULL);
2228
2229 giraffe_propertylist_copy(qclog, "ARCFILE", properties, GIALIAS_ARCFILE);
2230 giraffe_propertylist_copy(qclog, "TPL.ID", properties, GIALIAS_TPLID);
2231 giraffe_propertylist_copy(qclog, "INS.EXP.MODE", properties,
2232 GIALIAS_SETUPNAME);
2233 giraffe_propertylist_copy(qclog, "INS.SLIT.NAME", properties,
2234 GIALIAS_SLITNAME);
2235 giraffe_propertylist_copy(qclog, "INS.GRAT.WLEN", properties,
2236 GIALIAS_GRATWLEN);
2237 giraffe_propertylist_copy(qclog, "DPR.TYPE", properties, GIALIAS_DPRTYPE);
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 const char * flattype = giraffe_get_flat_type(properties);
2245
2246 properties = giraffe_image_get_properties(pimage);
2247 cx_assert(properties != NULL);
2248
2249 giraffe_propertylist_copy(qclog, "PRO.DATAAVG", properties,
2250 GIALIAS_DATAMEAN);
2251 giraffe_propertylist_copy(qclog, "PRO.DATARMS", properties,
2252 GIALIAS_DATASIG);
2253 giraffe_propertylist_copy(qclog, "PRO.DATAMED", properties,
2254 GIALIAS_DATAMEDI);
2255 giraffe_propertylist_copy(qclog, "PRO.DATANCOM", properties,
2256 GIALIAS_DATANCOM);
2257
2258
2259 /*
2260 * Compute mean level of the first raw frame and count the number
2261 * of saturated pixels.
2262 */
2263
2264 properties = giraffe_image_get_properties(rimage);
2265 cx_assert(properties != NULL);
2266
2267 if (cpl_propertylist_has(properties, GIALIAS_OVSCX) == TRUE) {
2268
2269 cxint _ox = cpl_propertylist_get_int(properties, GIALIAS_OVSCX);
2270 cxint _nx = cpl_image_get_size_x(_rimage) - 2 * CX_MAX(0, _ox) - 1;
2271
2272 w.x0 = CX_MAX(0, _ox) + 1;
2273 w.x1 = w.x0 + _nx;
2274
2275 }
2276
2277 if (cpl_propertylist_has(properties, GIALIAS_OVSCY) == TRUE) {
2278
2279 cxint _oy = cpl_propertylist_get_int(properties, GIALIAS_OVSCY);
2280 cxint _ny = cpl_image_get_size_y(_rimage) - 2 * CX_MAX(0, _oy) - 1;
2281
2282 w.y0 = CX_MAX(0, _oy) + 1;
2283 w.y1 = w.y0 + _ny;
2284
2285 }
2286
2287 mean = cpl_image_get_mean_window(_rimage, w.x0, w.y0, w.x1, w.y1);
2288 meanfull = cpl_image_get_mean(_rimage);
2289
2290 if (cpl_propertylist_has(properties, GIALIAS_EXPTIME) == FALSE) {
2291 cpl_msg_warning(fctid, "Property '%s' not found in '%s'.",
2292 GIALIAS_EXPTIME, cpl_frame_get_filename(rframe));
2293 cpl_msg_warning(fctid, "Setting flux mean (%s) to 0.", GIALIAS_QCFLUXM);
2294 qcfluxm = 0.;
2295 }
2296 else {
2297 cxdouble exptime =
2298 cpl_propertylist_get_double(properties, GIALIAS_EXPTIME);
2299
2300 qcfluxm = meanfull / exptime;
2301 }
2302
2303
2304 pixels = cpl_image_get_data(_rimage);
2305 npixel = cpl_image_get_size_x(_rimage) * cpl_image_get_size_y(_rimage);
2306
2307 for (i = 0; i < npixel; i++) {
2308 if (pixels[i] > saturation) {
2309 ++nsaturated;
2310 }
2311 }
2312
2313
2314 properties = giraffe_image_get_properties(pimage);
2315 cx_assert(properties != NULL);
2316
2317 cpl_propertylist_update_double(properties, GIALIAS_QCMEAN, mean);
2318 cpl_propertylist_set_comment(properties, GIALIAS_QCMEAN, "Mean level of "
2319 "first raw");
2320
2321 giraffe_propertylist_copy(qclog, "QC.OUT1.MEAN.RAW", properties,
2322 GIALIAS_QCMEAN);
2323
2324 cpl_propertylist_update_double(properties, GIALIAS_QCRAWM, meanfull);
2325 cpl_propertylist_set_comment(properties, GIALIAS_QCRAWM, "Mean level of "
2326 "first raw full frame");
2327
2328 giraffe_propertylist_copy(qclog, "QC.RAW.MEAN", properties,
2329 GIALIAS_QCRAWM);
2330
2331 cpl_propertylist_update_double(properties, GIALIAS_QCFLUXM, qcfluxm);
2332 cpl_propertylist_set_comment(properties, GIALIAS_QCFLUXM, "Mean flux of "
2333 "first raw frame (ADU/s)");
2334
2335 giraffe_propertylist_copy(qclog, "QC.FLUX.MEAN", properties,
2336 GIALIAS_QCFLUXM);
2337
2338 if (flattype != NULL) {
2339 cpl_propertylist_update_string(properties, GIALIAS_QCFLAT, flattype);
2340 cpl_propertylist_set_comment(properties, GIALIAS_QCFLAT, "Type of "
2341 "flat field of first raw frame");
2342
2343 giraffe_propertylist_copy(qclog, "QC.FLAT.TYPE", properties,
2344 GIALIAS_QCFLAT);
2345 }
2346
2347
2348 cpl_propertylist_update_int(properties, GIALIAS_QCNSAT, nsaturated);
2349 cpl_propertylist_set_comment(properties, GIALIAS_QCNSAT, "Number of "
2350 "saturated pixels in the first raw frame");
2351
2352 giraffe_propertylist_copy(qclog, "QC.OUT1.NSAT.RAW", properties,
2353 GIALIAS_QCNSAT);
2354 giraffe_propertylist_copy(properties, GIALIAS_QCNUMSAT, properties,
2355 GIALIAS_QCNSAT);
2356
2357 cpl_propertylist_update_double(properties, GIALIAS_QCFIBMED, fibmed);
2358 cpl_propertylist_set_comment(properties, GIALIAS_QCFIBMED,
2359 "Median of per fibre mean values");
2360
2361 giraffe_propertylist_copy(qclog, "QC.FIB.MED", properties,
2362 GIALIAS_QCFIBMED);
2363
2364
2365 /*
2366 * Calibration lamp monitoring
2367 */
2368
2369 cpl_propertylist_update_double(properties, GIALIAS_QCLAMP, efficiency[0]);
2370 cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP,
2371 "Calibration lamp efficiency");
2372
2373 giraffe_propertylist_copy(qclog, "QC.LAMP.EFFIC", properties,
2374 GIALIAS_QCLAMP);
2375
2376 cpl_propertylist_update_double(properties, GIALIAS_QCLAMP_SIMCAL,
2377 efficiency[1]);
2378 cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP_SIMCAL,
2379 "SIMCAL lamp efficiency");
2380
2381 giraffe_propertylist_copy(qclog, "QC.LAMP.EFFIC1", properties,
2382 GIALIAS_QCLAMP_SIMCAL);
2383
2384
2385 /*
2386 * Write QC1 log and save updated master flat field.
2387 */
2388
2389 giraffe_image_save(pimage, cpl_frame_get_filename(pframe));
2390
2391 giraffe_image_delete(pimage);
2392 pimage = NULL;
2393
2394 giraffe_qclog_close(qc);
2395 qc = NULL;
2396
2397
2398 /*
2399 * Process fiber localization centroid
2400 */
2401
2402 qc = giraffe_qclog_open(1);
2403
2404 if (qc == NULL) {
2405 cpl_msg_error(fctid, "Cannot create QC1 log!");
2406
2407 giraffe_image_delete(rimage);
2408 rimage = NULL;
2409
2410 return 1;
2411 }
2412
2413 qclog = giraffe_paf_get_properties(qc);
2414 cx_assert(qclog != NULL);
2415
2416 pframe = giraffe_get_frame(set, GIFRAME_LOCALIZATION_CENTROID,
2417 CPL_FRAME_GROUP_PRODUCT);
2418
2419 if (pframe == NULL) {
2420 cpl_msg_error(fctid, "Missing product frame (%s)",
2421 GIFRAME_LOCALIZATION_CENTROID);
2422
2423 giraffe_paf_delete(qc);
2424 qc = NULL;
2425
2426 giraffe_image_delete(rimage);
2427 rimage = NULL;
2428
2429 return 1;
2430 }
2431
2432 cpl_msg_info(fctid, "Processing product frame '%s' (%s)",
2433 cpl_frame_get_filename(pframe), cpl_frame_get_tag(pframe));
2434
2435
2436 pimage = giraffe_image_new(CPL_TYPE_DOUBLE);
2437 status = giraffe_image_load(pimage, cpl_frame_get_filename(pframe), 0);
2438
2439 if (status != 0) {
2440 cpl_msg_error(fctid, "Could not load localization centroids '%s'!",
2441 cpl_frame_get_filename(pframe));
2442
2443 giraffe_image_delete(pimage);
2444 pimage = NULL;
2445
2446 giraffe_image_delete(rimage);
2447 rimage = NULL;
2448
2449 giraffe_paf_delete(qc);
2450 qc = NULL;
2451
2452 return 1;
2453 }
2454
2455 ptable = giraffe_table_new();
2456 status = giraffe_table_load(ptable, cpl_frame_get_filename(pframe), 1,
2457 NULL);
2458
2459 if (status != 0) {
2460 cpl_msg_error(fctid, "Could not load localization centroids '%s'!",
2461 cpl_frame_get_filename(pframe));
2462
2463 giraffe_table_delete(ptable);
2464 ptable = NULL;
2465
2466 giraffe_image_delete(pimage);
2467 pimage = NULL;
2468
2469 giraffe_image_delete(rimage);
2470 rimage = NULL;
2471
2472 giraffe_paf_delete(qc);
2473 qc = NULL;
2474
2475 return 1;
2476 }
2477
2478 properties = giraffe_image_get_properties(rimage);
2479 cx_assert(properties != NULL);
2480
2481 giraffe_propertylist_copy(qclog, "ARCFILE", properties, GIALIAS_ARCFILE);
2482 giraffe_propertylist_copy(qclog, "TPL.ID", properties, GIALIAS_TPLID);
2483 giraffe_propertylist_copy(qclog, "INS.EXP.MODE", properties,
2484 GIALIAS_SETUPNAME);
2485 giraffe_propertylist_copy(qclog, "INS.SLIT.NAME", properties,
2486 GIALIAS_SLITNAME);
2487 giraffe_propertylist_copy(qclog, "INS.GRAT.WLEN", properties,
2488 GIALIAS_GRATWLEN);
2489 giraffe_propertylist_copy(qclog, "DPR.TYPE", properties, GIALIAS_DPRTYPE);
2490
2491 cpl_propertylist_update_string(qclog, "PRO.CATG",
2492 cpl_frame_get_tag(pframe));
2493 cpl_propertylist_set_comment(qclog, "PRO.CATG",
2494 "Pipeline product category");
2495
2496 properties = giraffe_image_get_properties(pimage);
2497 cx_assert(properties != NULL);
2498
2499 giraffe_propertylist_copy(qclog, "PRO.DATAAVG", properties,
2500 GIALIAS_DATAMEAN);
2501 giraffe_propertylist_copy(qclog, "PRO.DATARMS", properties,
2502 GIALIAS_DATASIG);
2503 giraffe_propertylist_copy(qclog, "PRO.DATAMED", properties,
2504 GIALIAS_DATAMEDI);
2505 giraffe_propertylist_copy(qclog, "PRO.DATANCOM", properties,
2506 GIALIAS_DATANCOM);
2507 giraffe_propertylist_copy(qclog, "PRO.SLIT.NFIBRES", properties,
2508 GIALIAS_NFIBERS);
2509 giraffe_propertylist_copy(properties, GIALIAS_QCNUMFIB, properties,
2510 GIALIAS_NFIBERS);
2511
2512
2513 /*
2514 * Calibration lamp monitoring
2515 */
2516
2517 cpl_propertylist_update_double(properties, GIALIAS_QCLAMP, efficiency[0]);
2518 cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP,
2519 "Calibration lamp efficiency");
2520
2521 giraffe_propertylist_copy(qclog, "QC.LAMP.EFFIC", properties,
2522 GIALIAS_QCLAMP);
2523
2524 cpl_propertylist_update_double(properties, GIALIAS_QCLAMP_SIMCAL,
2525 efficiency[1]);
2526 cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP_SIMCAL,
2527 "SIMCAL lamp efficiency");
2528
2529 giraffe_propertylist_copy(qclog, "QC.LAMP.EFFIC1", properties,
2530 GIALIAS_QCLAMP_SIMCAL);
2531
2532
2533 /* Fiber signal curvature RMS */
2534
2535 _pimage = giraffe_image_get(pimage);
2536
2537 _test = cpl_image_collapse_create(_pimage, 0);
2538 cpl_image_divide_scalar(_test, cpl_image_get_size_y(_pimage));
2539
2540 _pdata = cpl_image_get_data(_pimage);
2541 _tdata = cpl_image_get_data(_test);
2542
2543 rms = 0.;
2544
2545 nx = cpl_image_get_size_x(_pimage);
2546 ny = cpl_image_get_size_y(_pimage);
2547
2548 cpl_vector* xoff = cpl_vector_new(nx-1);
2549
2550 double meanoff = 0.;
2551 int numout = 0;
2552
2553
2554 for (i = 0; i < nx; i++) {
2555
2556 cxint j;
2557
2558 cxdouble _rms = 0.;
2559
2560 cxdouble xmin = 1e6;
2561 cxdouble xmax = -1e6;
2562
2563 for (j = 0; j < ny; j++) {
2564 if (_pdata[j * nx + i] < xmin) {
2565 xmin = _pdata[j * nx + i];
2566 }
2567 if (_pdata[j * nx + i] > xmax) {
2568 xmax = _pdata[j * nx + i];
2569 }
2570 _rms += pow(_pdata[j * nx + i] - _tdata[i], 2.);
2571 }
2572
2573 rms += sqrt(_rms / (ny - 1));
2574
2575 }
2576
2577 for (i = 1; i < nx; i++) {
2578 double xoffi = _tdata[i] - _tdata[i-1];
2579 cpl_vector_set(xoff, i-1, xoffi);
2580 if(xoffi > 0. && xoffi < 30.){
2581 meanoff += xoffi;
2582 }
2583 }
2584
2585 meanoff /= nx-1;
2586
2587 for(i=0; i<nx-1; i++){
2588 double xoffi = cpl_vector_get(xoff, i) - meanoff;
2589 if(xoffi < - 1.5 || xoffi > 1.5){
2590 numout++;
2591 }
2592 }
2593
2594 rms /= nx;
2595
2596 cpl_image_delete(_test);
2597 _test = NULL;
2598
2599 cpl_vector_delete(xoff);
2600
2601 cpl_propertylist_update_double(properties, GIALIAS_QCLCRMS, rms);
2602 cpl_propertylist_set_comment(properties, GIALIAS_QCLCRMS,
2603 "Mean fibre signal curvature");
2604
2605 giraffe_propertylist_copy(qclog, "QC.FIBRE.CENTROID.RMS", properties,
2606 GIALIAS_QCLCRMS);
2607
2608 cpl_propertylist_update_double(properties, GIALIAS_QCXDMRMS, rms);
2609 cpl_propertylist_set_comment(properties, GIALIAS_QCXDMRMS,
2610 "STDEV fibre signal curvature");
2611
2612 giraffe_propertylist_copy(qclog, "QC.X.RMS", properties,
2613 GIALIAS_QCXDMRMS);
2614
2615 cpl_propertylist_update_double(properties, GIALIAS_QCNUMOUT, numout);
2616 cpl_propertylist_set_comment(properties, GIALIAS_QCNUMOUT,
2617 "Number of fibre pos outliers");
2618
2619 giraffe_propertylist_copy(qclog, "QC.NUM.OUT", properties,
2620 GIALIAS_QCNUMOUT);
2621
2622
2623 /* Difference of fiber signal curvature */
2624
2625 diff = 0.;
2626
2627 for (i = 0; i < nx; i++) {
2628
2629 cxdouble min = cpl_image_get_min_window(_pimage,
2630 i + 1, 1, i + 1, ny);
2631 cxdouble max = cpl_image_get_max_window(_pimage,
2632 i + 1, 1, i + 1, ny);
2633
2634 diff += max - min;
2635
2636 }
2637
2638 diff /= nx;
2639
2640 cpl_propertylist_update_double(properties, GIALIAS_QCLCDIFF, diff);
2641 cpl_propertylist_set_comment(properties, GIALIAS_QCLCDIFF,
2642 "Mean difference of fibre signal "
2643 "curvature");
2644
2645 giraffe_propertylist_copy(qclog, "QC.FIBRE.CENTROID.DIFF", properties,
2646 GIALIAS_QCLCDIFF);
2647
2648 cpl_propertylist_update_double(properties, GIALIAS_QCXDM, diff);
2649 cpl_propertylist_set_comment(properties, GIALIAS_QCXDM,
2650 "Mean difference of fibre signal "
2651 "curvature");
2652
2653 giraffe_propertylist_copy(qclog, "QC.XDIFF.MEAN", properties,
2654 GIALIAS_QCXDM);
2655
2656
2657 status = giraffe_image_save(pimage, cpl_frame_get_filename(pframe));
2658
2659 if (status != 0) {
2660 cpl_msg_error(fctid, "Could not save localization centroids '%s'!",
2661 cpl_frame_get_filename(pframe));
2662
2663 giraffe_table_delete(ptable);
2664 ptable = NULL;
2665
2666 giraffe_image_delete(pimage);
2667 pimage = NULL;
2668
2669 giraffe_image_delete(rimage);
2670 rimage = NULL;
2671
2672 giraffe_paf_delete(qc);
2673 qc = NULL;
2674
2675 return 1;
2676 }
2677
2678 status = giraffe_table_attach(ptable, cpl_frame_get_filename(pframe),
2679 1, NULL);
2680
2681 if (status != 0) {
2682 cpl_msg_error(fctid, "Could not save localization centroids '%s'!",
2683 cpl_frame_get_filename(pframe));
2684
2685 giraffe_table_delete(ptable);
2686 ptable = NULL;
2687
2688 giraffe_image_delete(pimage);
2689 pimage = NULL;
2690
2691 giraffe_image_delete(rimage);
2692 rimage = NULL;
2693
2694 giraffe_paf_delete(qc);
2695 qc = NULL;
2696
2697 return 1;
2698 }
2699
2700 giraffe_image_delete(pimage);
2701 pimage = NULL;
2702
2703 giraffe_table_delete(ptable);
2704 ptable = NULL;
2705
2706 giraffe_qclog_close(qc);
2707 qc = NULL;
2708
2709
2710 /*
2711 * Process fiber localization width
2712 */
2713
2714 qc = giraffe_qclog_open(2);
2715
2716 if (qc == NULL) {
2717 cpl_msg_error(fctid, "Cannot create QC1 log!");
2718
2719 giraffe_image_delete(rimage);
2720 rimage = NULL;
2721
2722 return 1;
2723 }
2724
2725 qclog = giraffe_paf_get_properties(qc);
2726 cx_assert(qclog != NULL);
2727
2728 pframe = giraffe_get_frame(set, GIFRAME_LOCALIZATION_WIDTH,
2729 CPL_FRAME_GROUP_PRODUCT);
2730
2731 if (pframe == NULL) {
2732 cpl_msg_error(fctid, "Missing product frame (%s)",
2733 GIFRAME_LOCALIZATION_WIDTH);
2734
2735 giraffe_paf_delete(qc);
2736 qc = NULL;
2737
2738 giraffe_image_delete(rimage);
2739 rimage = NULL;
2740
2741 return 1;
2742 }
2743
2744 cpl_msg_info(fctid, "Processing product frame '%s' (%s)",
2745 cpl_frame_get_filename(pframe), cpl_frame_get_tag(pframe));
2746
2747
2748 pimage = giraffe_image_new(CPL_TYPE_DOUBLE);
2749 status = giraffe_image_load(pimage, cpl_frame_get_filename(pframe), 0);
2750
2751 if (status != 0) {
2752 cpl_msg_error(fctid, "Could not load localization widths '%s'!",
2753 cpl_frame_get_filename(pframe));
2754
2755 giraffe_image_delete(pimage);
2756 pimage = NULL;
2757
2758 giraffe_image_delete(rimage);
2759 rimage = NULL;
2760
2761 giraffe_paf_delete(qc);
2762 qc = NULL;
2763
2764 return 1;
2765 }
2766
2767 ptable = giraffe_table_new();
2768 status = giraffe_table_load(ptable, cpl_frame_get_filename(pframe), 1,
2769 NULL);
2770
2771 if (status != 0) {
2772 cpl_msg_error(fctid, "Could not load localization widths '%s'!",
2773 cpl_frame_get_filename(pframe));
2774
2775 giraffe_table_delete(ptable);
2776 ptable = NULL;
2777
2778 giraffe_image_delete(pimage);
2779 pimage = NULL;
2780
2781 giraffe_image_delete(rimage);
2782 rimage = NULL;
2783
2784 giraffe_paf_delete(qc);
2785 qc = NULL;
2786
2787 return 1;
2788 }
2789
2790 properties = giraffe_image_get_properties(rimage);
2791 cx_assert(properties != NULL);
2792
2793 giraffe_propertylist_copy(qclog, "ARCFILE", properties, GIALIAS_ARCFILE);
2794 giraffe_propertylist_copy(qclog, "TPL.ID", properties, GIALIAS_TPLID);
2795 giraffe_propertylist_copy(qclog, "INS.EXP.MODE", properties,
2796 GIALIAS_SETUPNAME);
2797 giraffe_propertylist_copy(qclog, "INS.SLIT.NAME", properties,
2798 GIALIAS_SLITNAME);
2799 giraffe_propertylist_copy(qclog, "INS.GRAT.WLEN", properties,
2800 GIALIAS_GRATWLEN);
2801 giraffe_propertylist_copy(qclog, "DPR.TYPE", properties, GIALIAS_DPRTYPE);
2802
2803 cpl_propertylist_update_string(qclog, "PRO.CATG",
2804 cpl_frame_get_tag(pframe));
2805 cpl_propertylist_set_comment(qclog, "PRO.CATG",
2806 "Pipeline product category");
2807
2808 properties = giraffe_image_get_properties(pimage);
2809 cx_assert(properties != NULL);
2810
2811 giraffe_propertylist_copy(qclog, "PRO.DATAAVG", properties,
2812 GIALIAS_DATAMEAN);
2813 giraffe_propertylist_copy(qclog, "PRO.DATARMS", properties,
2814 GIALIAS_DATASIG);
2815 giraffe_propertylist_copy(qclog, "PRO.DATAMED", properties,
2816 GIALIAS_DATAMEDI);
2817 giraffe_propertylist_copy(qclog, "PRO.DATANCOM", properties,
2818 GIALIAS_DATANCOM);
2819 giraffe_propertylist_copy(qclog, "PRO.SLIT.NFIBRES", properties,
2820 GIALIAS_NFIBERS);
2821
2822
2823 /*
2824 * Calibration lamp monitoring
2825 */
2826
2827 cpl_propertylist_update_double(properties, GIALIAS_QCLAMP, efficiency[0]);
2828 cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP,
2829 "Calibration lamp efficiency");
2830
2831 giraffe_propertylist_copy(qclog, "QC.LAMP.EFFIC", properties,
2832 GIALIAS_QCLAMP);
2833
2834 cpl_propertylist_update_double(properties, GIALIAS_QCLAMP_SIMCAL,
2835 efficiency[1]);
2836 cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP_SIMCAL,
2837 "SIMCAL lamp efficiency");
2838
2839 giraffe_propertylist_copy(qclog, "QC.LAMP.EFFIC1", properties,
2840 GIALIAS_QCLAMP_SIMCAL);
2841
2842
2843 /* Compute fiber width statistics, i.e. the mean width and its RMS */
2844
2845 _pimage = giraffe_image_get(pimage);
2846
2847 _test = cpl_image_collapse_create(_pimage, 0);
2848 cpl_image_divide_scalar(_test, cpl_image_get_size_y(_pimage));
2849
2850 _pdata = cpl_image_get_data(_pimage);
2851 _tdata = cpl_image_get_data(_test);
2852
2853 mean = 0.;
2854 rms = 0.;
2855
2856 nx = cpl_image_get_size_x(_pimage);
2857 ny = cpl_image_get_size_y(_pimage);
2858
2859 /*
2860 * The term rms below calculates the average of the width rms per fiber
2861 * The term rms2 calculates the overall width stddev.
2862 */
2863
2864 for (i = 0; i < nx; i++) {
2865
2866 cxint j;
2867
2868 cxdouble _rms = 0.;
2869
2870
2871 for (j = 0; j < ny; j++) {
2872 _rms += pow(_pdata[j * nx + i] - _tdata[i], 2.);
2873 }
2874
2875 mean += _tdata[i];
2876 rms += sqrt(_rms / (ny - 1));
2877
2878 }
2879
2880 mean /= nx;
2881 rms /= nx;
2882
2883 rms2 = cpl_image_get_stdev(_pimage);
2884
2885 cpl_image_delete(_test);
2886 _test = NULL;
2887
2888
2889 cpl_propertylist_update_double(properties, GIALIAS_QCLWAVG, mean);
2890 cpl_propertylist_set_comment(properties, GIALIAS_QCLWAVG,
2891 "Mean fibre half width");
2892
2893 giraffe_propertylist_copy(qclog, "QC.FIBRE.WIDTH.MEAN", properties,
2894 GIALIAS_QCLWAVG);
2895
2896 cpl_propertylist_update_double(properties, GIALIAS_QCLWRMS, rms);
2897 cpl_propertylist_set_comment(properties, GIALIAS_QCLWRMS,
2898 "RMS of fibre half width");
2899
2900 giraffe_propertylist_copy(qclog, "QC.FIBRE.WIDTH.RMS", properties,
2901 GIALIAS_QCLWRMS);
2902
2903 cpl_propertylist_update_double(properties, GIALIAS_QCWMEAN, mean);
2904 cpl_propertylist_set_comment(properties, GIALIAS_QCWMEAN,
2905 "Mean fibre half width");
2906
2907 giraffe_propertylist_copy(qclog, "QC.WIDTH.MEAN", properties,
2908 GIALIAS_QCWMEAN);
2909
2910 cpl_propertylist_update_double(properties, GIALIAS_QCWRMS, rms2);
2911 cpl_propertylist_set_comment(properties, GIALIAS_QCWRMS,
2912 "RMS of fibre half width");
2913
2914 giraffe_propertylist_copy(qclog, "QC.WIDTH.RMS", properties,
2915 GIALIAS_QCWRMS);
2916
2917
2918 status = giraffe_image_save(pimage, cpl_frame_get_filename(pframe));
2919
2920 if (status != 0) {
2921 cpl_msg_error(fctid, "Could not save localization widths '%s'!",
2922 cpl_frame_get_filename(pframe));
2923
2924 giraffe_table_delete(ptable);
2925 ptable = NULL;
2926
2927 giraffe_image_delete(pimage);
2928 pimage = NULL;
2929
2930 giraffe_image_delete(rimage);
2931 rimage = NULL;
2932
2933 giraffe_paf_delete(qc);
2934 qc = NULL;
2935
2936 return 1;
2937 }
2938
2939 status = giraffe_table_attach(ptable, cpl_frame_get_filename(pframe),
2940 1, NULL);
2941
2942 if (status != 0) {
2943 cpl_msg_error(fctid, "Could not save localization widths '%s'!",
2944 cpl_frame_get_filename(pframe));
2945
2946 giraffe_table_delete(ptable);
2947 ptable = NULL;
2948
2949 giraffe_image_delete(pimage);
2950 pimage = NULL;
2951
2952 giraffe_image_delete(rimage);
2953 rimage = NULL;
2954
2955 giraffe_paf_delete(qc);
2956 qc = NULL;
2957
2958 return 1;
2959 }
2960
2961 giraffe_image_delete(pimage);
2962 pimage = NULL;
2963
2964 giraffe_table_delete(ptable);
2965 ptable = NULL;
2966
2967 giraffe_qclog_close(qc);
2968 qc = NULL;
2969
2970
2971 /*
2972 * Process extracted flat field spectra
2973 */
2974
2975 qc = giraffe_qclog_open(3);
2976
2977 if (qc == NULL) {
2978 cpl_msg_error(fctid, "Cannot create QC1 log!");
2979
2980 giraffe_image_delete(rimage);
2981 rimage = NULL;
2982
2983 return 1;
2984 }
2985
2986 qclog = giraffe_paf_get_properties(qc);
2987 cx_assert(qclog != NULL);
2988
2989 pframe = giraffe_get_frame(set, GIFRAME_FIBER_FLAT_EXTSPECTRA,
2990 CPL_FRAME_GROUP_PRODUCT);
2991
2992 if (pframe == NULL) {
2993 cpl_msg_error(fctid, "Missing product frame (%s)",
2994 GIFRAME_FIBER_FLAT_EXTSPECTRA);
2995
2996 giraffe_paf_delete(qc);
2997 qc = NULL;
2998
2999 giraffe_image_delete(rimage);
3000 rimage = NULL;
3001
3002 return 1;
3003 }
3004
3005 cpl_msg_info(fctid, "Processing product frame '%s' (%s)",
3006 cpl_frame_get_filename(pframe), cpl_frame_get_tag(pframe));
3007
3008
3009 pimage = giraffe_image_new(CPL_TYPE_DOUBLE);
3010 status = giraffe_image_load(pimage, cpl_frame_get_filename(pframe), 0);
3011
3012 if (status != 0) {
3013 cpl_msg_error(fctid, "Could not load extracted flat field spectra "
3014 "'%s'!", cpl_frame_get_filename(pframe));
3015
3016 giraffe_image_delete(pimage);
3017 pimage = NULL;
3018
3019 giraffe_image_delete(rimage);
3020 rimage = NULL;
3021
3022 giraffe_paf_delete(qc);
3023 qc = NULL;
3024
3025 return 1;
3026 }
3027
3028 ptable = giraffe_table_new();
3029 status = giraffe_table_load(ptable, cpl_frame_get_filename(pframe), 1,
3030 NULL);
3031
3032 if (status != 0) {
3033 cpl_msg_error(fctid, "Could not load extracted flat field spectra "
3034 "'%s'!", cpl_frame_get_filename(pframe));
3035
3036 giraffe_table_delete(ptable);
3037 ptable = NULL;
3038
3039 giraffe_image_delete(pimage);
3040 pimage = NULL;
3041
3042 giraffe_image_delete(rimage);
3043 rimage = NULL;
3044
3045 giraffe_paf_delete(qc);
3046 qc = NULL;
3047
3048 return 1;
3049 }
3050
3051 properties = giraffe_image_get_properties(rimage);
3052 cx_assert(properties != NULL);
3053
3054 giraffe_propertylist_copy(qclog, "ARCFILE", properties, GIALIAS_ARCFILE);
3055 giraffe_propertylist_copy(qclog, "TPL.ID", properties, GIALIAS_TPLID);
3056 giraffe_propertylist_copy(qclog, "INS.EXP.MODE", properties,
3057 GIALIAS_SETUPNAME);
3058 giraffe_propertylist_copy(qclog, "INS.SLIT.NAME", properties,
3059 GIALIAS_SLITNAME);
3060 giraffe_propertylist_copy(qclog, "INS.GRAT.WLEN", properties,
3061 GIALIAS_GRATWLEN);
3062 giraffe_propertylist_copy(qclog, "DPR.TYPE", properties, GIALIAS_DPRTYPE);
3063
3064 cpl_propertylist_update_string(qclog, "PRO.CATG",
3065 cpl_frame_get_tag(pframe));
3066 cpl_propertylist_set_comment(qclog, "PRO.CATG",
3067 "Pipeline product category");
3068
3069 properties = giraffe_image_get_properties(pimage);
3070 cx_assert(properties != NULL);
3071
3072 giraffe_propertylist_copy(qclog, "PRO.DATAAVG", properties,
3073 GIALIAS_DATAMEAN);
3074 giraffe_propertylist_copy(qclog, "PRO.DATARMS", properties,
3075 GIALIAS_DATASIG);
3076 giraffe_propertylist_copy(qclog, "PRO.DATAMED", properties,
3077 GIALIAS_DATAMEDI);
3078 giraffe_propertylist_copy(qclog, "PRO.DATANCOM", properties,
3079 GIALIAS_DATANCOM);
3080 giraffe_propertylist_copy(qclog, "PRO.SLIT.NFIBRES", properties,
3081 GIALIAS_NFIBERS);
3082
3083
3084 /*
3085 * Calibration lamp monitoring
3086 */
3087
3088 cpl_propertylist_update_double(properties, GIALIAS_QCLAMP, efficiency[0]);
3089 cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP,
3090 "Calibration lamp efficiency");
3091
3092 giraffe_propertylist_copy(qclog, "QC.LAMP.EFFIC", properties,
3093 GIALIAS_QCLAMP);
3094
3095 cpl_propertylist_update_double(properties, GIALIAS_QCLAMP_SIMCAL,
3096 efficiency[1]);
3097 cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP_SIMCAL,
3098 "SIMCAL lamp efficiency");
3099
3100 giraffe_propertylist_copy(qclog, "QC.LAMP.EFFIC1", properties,
3101 GIALIAS_QCLAMP_SIMCAL);
3102
3103
3104 _ptable = giraffe_table_get(ptable);
3105
3106 if (cpl_table_has_column(_ptable, "TRANSMISSION") == FALSE) {
3107 cpl_msg_warning(fctid, "Relative fiber transmission not available! "
3108 "QC parameter computation skipped.");
3109 }
3110 else {
3111
3112 const cxdouble low = 0.5;
3113 const cxdouble high = 2.0;
3114
3115 cxint nf = 0;
3116
3117 cxdouble t = 0.;
3118 cxdouble dt = 0.;
3119
3120 cpl_table* ttable = NULL;
3121
3122
3123 rms = 0.;
3124
3125 cpl_table_unselect_all(_ptable);
3126
3127 cpl_table_or_selected_int(_ptable, "RP", CPL_GREATER_THAN, 0);
3128 cpl_table_and_selected_double(_ptable, "TRANSMISSION",
3129 CPL_GREATER_THAN, low);
3130 cpl_table_and_selected_double(_ptable, "TRANSMISSION",
3131 CPL_LESS_THAN, high);
3132
3133 ttable = cpl_table_extract_selected(_ptable);
3134
3135 nf = cpl_table_get_nrow(ttable);
3136 if (ttable == NULL || nf <= 0) {
3137 cpl_msg_warning(fctid, "No fiber found within transmission "
3138 "range ]%.2f, %.2f[", low, high);
3139
3140 }
3141 else {
3142
3143 t = cpl_table_get_column_median(ttable, "TRANSMISSION");
3144
3145 if (nf > 1) {
3146
3147 for (i = 0; i < cpl_table_get_nrow(ttable); i++) {
3148
3149 cxdouble _t = cpl_table_get_double(ttable,
3150 "TRANSMISSION", i, NULL);
3151 rms += pow(_t - t, 2.);
3152
3153 }
3154
3155 rms = sqrt(rms / (cpl_table_get_nrow(ttable) - 1));
3156
3157 }
3158 else {
3159 rms = 0.;
3160 }
3161
3162
3163 }
3164
3165 if (!cpl_table_has_column(_ptable, "DTRANSMISSION")) {
3166 cpl_msg_warning(fctid, "Relative fiber transmission error not "
3167 "available! QC parameter computation skipped.");
3168 }
3169 else {
3170
3171 cx_assert(cpl_table_has_column(ttable, "DTRANSMISSION") != 0);
3172 dt = cpl_table_get_column_median(ttable, "DTRANSMISSION");
3173
3174 }
3175
3176 cpl_table_delete(ttable);
3177 ttable = NULL;
3178
3179
3180 cpl_propertylist_update_double(properties, GIALIAS_QCTRMED, t);
3181 cpl_propertylist_set_comment(properties, GIALIAS_QCTRMED, "Median of "
3182 "relative fibre transmission");
3183
3184 giraffe_propertylist_copy(qclog, "QC.FIBRE.TRANS.MEDIAN", properties,
3185 GIALIAS_QCTRMED);
3186
3187
3188 cpl_propertylist_update_double(properties, GIALIAS_QCTRRMS, rms);
3189 cpl_propertylist_set_comment(properties, GIALIAS_QCTRRMS, "RMS of "
3190 "relative fibre transmission");
3191
3192 giraffe_propertylist_copy(qclog, "QC.FIBRE.TRANS.RMS", properties,
3193 GIALIAS_QCTRRMS);
3194
3195
3196 cpl_propertylist_update_double(properties, GIALIAS_QCTRERR, dt);
3197 cpl_propertylist_set_comment(properties, GIALIAS_QCTRERR, "Median of "
3198 "relative fibre transmission error");
3199
3200 giraffe_propertylist_copy(qclog, "QC.FIBRE.TRANS.ERROR", properties,
3201 GIALIAS_QCTRERR);
3202
3203
3204 //FIXME: Check whether this number is useful!
3205#if 0
3206 cpl_propertylist_update_int(properties, GIALIAS_QCTRNF, nf);
3207 cpl_propertylist_set_comment(properties, GIALIAS_QCTRNF, "Number "
3208 "of fibres used for median transmission computation.");
3209
3210 giraffe_propertylist_copy(qclog, "QC.FIBRE.TRANS.NFIBRES",
3211 properties, GIALIAS_QCTRNF);
3212#endif
3213 cpl_msg_debug(fctid, "%d fibers used for median transmission "
3214 "computation.", nf);
3215
3216 }
3217
3218 status = giraffe_image_save(pimage, cpl_frame_get_filename(pframe));
3219
3220 if (status != 0) {
3221 cpl_msg_error(fctid, "Could not save extracted flat field spectra "
3222 "'%s'!", cpl_frame_get_filename(pframe));
3223
3224 giraffe_table_delete(ptable);
3225 ptable = NULL;
3226
3227 giraffe_image_delete(pimage);
3228 pimage = NULL;
3229
3230 giraffe_image_delete(rimage);
3231 rimage = NULL;
3232
3233 giraffe_paf_delete(qc);
3234 qc = NULL;
3235
3236 return 1;
3237 }
3238
3239 status = giraffe_table_attach(ptable, cpl_frame_get_filename(pframe),
3240 1, NULL);
3241
3242 if (status != 0) {
3243 cpl_msg_error(fctid, "Could not save extracted flat field spectra "
3244 "'%s'!", cpl_frame_get_filename(pframe));
3245
3246 giraffe_table_delete(ptable);
3247 ptable = NULL;
3248
3249 giraffe_image_delete(pimage);
3250 pimage = NULL;
3251
3252 giraffe_image_delete(rimage);
3253 rimage = NULL;
3254
3255 giraffe_paf_delete(qc);
3256 qc = NULL;
3257
3258 return 1;
3259 }
3260
3261 giraffe_image_delete(pimage);
3262 pimage = NULL;
3263
3264 giraffe_table_delete(ptable);
3265 ptable = NULL;
3266
3267 giraffe_qclog_close(qc);
3268 qc = NULL;
3269
3270
3271 /*
3272 * Cleanup
3273 */
3274
3275 giraffe_image_delete(rimage);
3276
3277 return 0;
3278
3279}
3280
3281
3282/*
3283 * Build table of contents, i.e. the list of available plugins, for
3284 * this module. This function is exported.
3285 */
3286
3287int
3288cpl_plugin_get_info(cpl_pluginlist* list)
3289{
3290
3291 cpl_recipe* recipe = cx_calloc(1, sizeof *recipe);
3292 cpl_plugin* plugin = &recipe->interface;
3293
3294
3295 cpl_plugin_init(plugin,
3296 CPL_PLUGIN_API,
3297 GIRAFFE_BINARY_VERSION,
3298 CPL_PLUGIN_TYPE_RECIPE,
3299 "gimasterflat",
3300 "Create the fiber master flat field and the "
3301 "localization mask.",
3302 "For detailed information please refer to the "
3303 "GIRAFFE pipeline user manual.\nIt is available at "
3304 "http://www.eso.org/pipelines.",
3305 "Giraffe Pipeline",
3306 PACKAGE_BUGREPORT,
3308 gimasterflat_create,
3309 gimasterflat_exec,
3310 gimasterflat_destroy);
3311
3312 cpl_pluginlist_append(list, plugin);
3313
3314 return 0;
3315
3316}
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
cxint giraffe_subtract_dark(GiImage *image, const GiImage *dark, const GiImage *bpixel, GiDarkResults *data, const GiDarkConfig *config)
Subtract the dark current from a bias corrected image.
Definition: gidark.c:478
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
GiFibersConfig * giraffe_fibers_config_create(cpl_parameterlist *list)
Creates a setup structure for the fiber selection.
Definition: gifibers.c:315
GiTable * giraffe_fibers_select(const cpl_frame *frame, const GiTable *reference, GiFibersConfig *config)
Selects the spectra to process.
Definition: gifibers.c:72
void giraffe_fibers_config_destroy(GiFibersConfig *config)
Destroys a fibers setup structure.
Definition: gifibers.c:363
void giraffe_fibers_config_add(cpl_parameterlist *list)
Adds parameters for the spectrum selection.
Definition: gifibers.c:391
cxint giraffe_fiberlist_compare(const GiTable *fibers, const GiTable *reference)
Compare two fiber lists.
Definition: gifiberutils.c:951
cxint giraffe_fiberlist_attach(cpl_frame *frame, GiTable *fibers)
Attach a fiber table to a frame.
Definition: gifiberutils.c:883
cxint giraffe_fiberlist_clear_index(GiTable *fibers)
Remove the reference index column from a fiber list.
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
GiLocalizeConfig * giraffe_localize_config_create(cpl_parameterlist *list)
Creates a setup structure for the spectrum localization.
Definition: gilocalize.c:3188
void giraffe_localize_config_destroy(GiLocalizeConfig *config)
Destroys a spectrum localization setup structure.
Definition: gilocalize.c:3295
void giraffe_localize_config_add(cpl_parameterlist *list)
Adds parameters for the spectrum localization.
Definition: gilocalize.c:3319
cxint giraffe_localize_spectra(GiLocalization *result, GiImage *image, GiTable *fibers, GiLocalization *master, GiImage *badpixels, GiLocalizeConfig *config)
Finds the location of spectra in a Giraffe observation.
Definition: gilocalize.c:2560
void giraffe_psf_config_destroy(GiPsfConfig *self)
Destroys a PSF profile fit setup object.
Definition: gipsf.c:3254
GiPsfConfig * giraffe_psf_config_create(cpl_parameterlist *list)
Creates a setup object for the PSF profile fit.
Definition: gipsf.c:3150
cxint giraffe_compute_fiber_profiles(GiLocalization *result, GiImage *image, GiTable *fibers, GiLocalization *master, GiImage *bpixel, GiPsfConfig *config)
Compute the position and width of the spectra from the fiber profile.
Definition: gipsf.c:2601
void giraffe_psf_config_add(cpl_parameterlist *list)
Adds parameters for the PSF profile computation of the fibers.
Definition: gipsf.c:3283
void giraffe_slight_config_add(cpl_parameterlist *list)
Adds parameters for the scattered light computation.
Definition: gislight.c:1601
cxint giraffe_adjust_scattered_light(GiImage *result, const GiImage *image, const GiLocalization *localization, const GiImage *bpixel, GiImage *phff, const GiSLightConfig *config)
Compute a scattered light model for a given image.
Definition: gislight.c:1197
void giraffe_slight_config_destroy(GiSLightConfig *config)
Destroys a scattered light setup structure.
Definition: gislight.c:1569
GiSLightConfig * giraffe_slight_config_create(cpl_parameterlist *list)
Creates a setup structure for the scattered light computation.
Definition: gislight.c:1379
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
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
GiTransmissionConfig * giraffe_transmission_config_create(cpl_parameterlist *list)
Creates a setup structure for the relative transmission computation.
void giraffe_transmission_config_add(cpl_parameterlist *list)
Adds parameters for the transmission correction computation.
void giraffe_transmission_config_destroy(GiTransmissionConfig *config)
Destroys a transmission field setup structure.
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:1106
const cxchar * giraffe_get_license(void)
Get the pipeline copyright and license.
Definition: giutils.c:420

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