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 availble 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 scale = 1.;
1921 cxdouble mean = 0.;
1922 cxdouble rms = 0.;
1923 cxdouble diff = 0.;
1924 cxdouble* _pdata = NULL;
1925 cxdouble* _tdata = NULL;
1926
1927 cpl_propertylist* properties = NULL;
1928 cpl_propertylist* qclog = NULL;
1929
1930 cpl_frame* rframe = NULL;
1931 cpl_frame* pframe = NULL;
1932
1933 cpl_image* _rimage = NULL;
1934 cpl_image* _pimage = NULL;
1935 cpl_image* _test = NULL;
1936
1937 cpl_table* _ptable = NULL;
1938
1939 GiImage* rimage = NULL;
1940 GiImage* pimage = NULL;
1941
1942 GiTable* ptable = NULL;
1943
1944 GiPaf* qc = NULL;
1945
1946 GiWindow w = {0, 0, 0, 0};
1947
1948
1949
1950 cpl_msg_info(fctid, "Computing QC1 parameters ...");
1951
1952 qc = giraffe_qclog_open(0);
1953
1954 if (qc == NULL) {
1955 cpl_msg_error(fctid, "Cannot create QC1 log!");
1956 return 1;
1957 }
1958
1959 qclog = giraffe_paf_get_properties(qc);
1960 cx_assert(qclog != NULL);
1961
1962
1963 /*
1964 * Compute lamp efficiencies from the rebinned frame if
1965 * it is available. If not the efficiencies are set to 0.
1966 */
1967
1968 pframe = giraffe_get_frame(set, GIFRAME_FIBER_FLAT_EXTSPECTRA,
1969 CPL_FRAME_GROUP_PRODUCT);
1970
1971 if (pframe == NULL) {
1972
1973 cpl_msg_warning(fctid, "Product '%s' not found.",
1974 GIFRAME_FIBER_FLAT_EXTSPECTRA);
1975
1976 cpl_msg_warning(fctid, "Setting lamp efficiencies (%s, %s) to 0.",
1977 GIALIAS_QCLAMP, GIALIAS_QCLAMP_SIMCAL);
1978
1979 efficiency[0] = 0.;
1980 efficiency[1] = 0.;
1981
1982 }
1983
1984
1985 pimage = giraffe_image_new(CPL_TYPE_DOUBLE);
1986 status = giraffe_image_load(pimage, cpl_frame_get_filename(pframe), 0);
1987
1988 if (status != 0) {
1989 cpl_msg_error(fctid, "Could not load extracted spectra '%s'!",
1990 cpl_frame_get_filename(pframe));
1991
1992 giraffe_image_delete(pimage);
1993 pimage = NULL;
1994
1995 giraffe_paf_delete(qc);
1996 qc = NULL;
1997
1998 return 1;
1999 }
2000
2001 _pimage = giraffe_image_get(pimage);
2002 cx_assert(_pimage != NULL);
2003
2004
2005 ptable = giraffe_table_new();
2006 status = giraffe_table_load(ptable, cpl_frame_get_filename(pframe), 1,
2007 NULL);
2008
2009 if (status != 0) {
2010 cpl_msg_error(fctid, "Could not load extracted spectra fiber setup!");
2011
2012 giraffe_table_delete(ptable);
2013 ptable = NULL;
2014
2015 giraffe_image_delete(pimage);
2016 pimage = NULL;
2017
2018 giraffe_paf_delete(qc);
2019 qc = NULL;
2020
2021 return 1;
2022 }
2023
2024 _ptable = giraffe_table_get(ptable);
2025 cx_assert(_ptable != NULL);
2026
2027 if (cpl_table_has_column(_ptable, "RP") == FALSE) {
2028
2029 cpl_msg_warning(fctid, "Column 'RP' not found in fiber setup table!");
2030 cpl_msg_warning(fctid, "Setting lamp efficiencies (%s, %s) to 0.",
2031 GIALIAS_QCLAMP, GIALIAS_QCLAMP_SIMCAL);
2032
2033 efficiency[0] = 0.;
2034 efficiency[1] = 0.;
2035
2036 }
2037 else {
2038
2039 properties = giraffe_image_get_properties(pimage);
2040 cx_assert(properties != NULL);
2041
2042 if (cpl_propertylist_has(properties, GIALIAS_EXPTIME) == FALSE) {
2043
2044 cpl_msg_warning(fctid, "Property '%s' not found in '%s'.",
2045 GIALIAS_EXPTIME, cpl_frame_get_filename(rframe));
2046 cpl_msg_warning(fctid, "Setting lamp efficiencies (%s, %s) to 0.",
2047 GIALIAS_QCLAMP, GIALIAS_QCLAMP_SIMCAL);
2048
2049 efficiency[0] = 0.;
2050 efficiency[1] = 0.;
2051
2052 }
2053 else {
2054
2055 cxbool scaled = cpl_propertylist_has(properties,
2056 GIALIAS_FLAT_SCALE);
2057
2058 cxint fiber = 0;
2059 cxint nb = cpl_image_get_size_y(_pimage);
2060 cxint nf[2] = {0, 0};
2061
2062 cxdouble exptime = cpl_propertylist_get_double(properties,
2063 GIALIAS_EXPTIME);
2064 cxdouble* _sum = NULL;
2065
2066 cpl_image* sum = NULL;
2067
2068
2069 if (scaled == TRUE) {
2070
2071 scale = cpl_propertylist_get_double(properties,
2072 GIALIAS_FLAT_SCALE);
2073 cpl_image_multiply_scalar(_pimage, scale);
2074
2075
2076 }
2077
2078 sum = cpl_image_collapse_create(_pimage, 0);
2079 _sum = cpl_image_get_data_double(sum);
2080
2081 for (fiber = 0; fiber < cpl_table_get_nrow(_ptable); ++fiber) {
2082
2083 cxint rp = cpl_table_get_int(_ptable, "RP", fiber, NULL);
2084
2085 if (rp == -1) {
2086 efficiency[1] += _sum[fiber];
2087 ++nf[1];
2088 }
2089 else {
2090 efficiency[0] += _sum[fiber];
2091 ++nf[0];
2092 }
2093
2094 }
2095
2096 _sum = NULL;
2097
2098 cpl_image_delete(sum);
2099 sum = NULL;
2100
2101 if (nf[0] == 0) {
2102 cpl_msg_warning(fctid, "No OzPoz fibers found in the "
2103 "current fiber setup.");
2104 cpl_msg_warning(fctid, "Setting lamp efficiency (%s) to 0.",
2105 GIALIAS_QCLAMP);
2106 efficiency[0] = 0.;
2107 }
2108 else {
2109 efficiency[0] /= nf[0] * nb * exptime;
2110 }
2111
2112 if (nf[1] == 0) {
2113 cpl_msg_warning(fctid, "No simultaneous calibration fibers "
2114 "found in the current fiber setup.");
2115 cpl_msg_warning(fctid, "Setting lamp efficiency (%s) to 0.",
2116 GIALIAS_QCLAMP_SIMCAL);
2117 efficiency[1] = 0.;
2118 }
2119 else {
2120 efficiency[1] /= nf[1] * nb * exptime;
2121 }
2122
2123 }
2124
2125 properties = NULL;
2126
2127 }
2128
2129 _ptable = NULL;
2130 _pimage = NULL;
2131
2132 giraffe_table_delete(ptable);
2133 ptable = NULL;
2134
2135 giraffe_image_delete(pimage);
2136 pimage = NULL;
2137
2138
2139 /*
2140 * Process master flat field
2141 */
2142
2143
2144 pframe = giraffe_get_frame(set, GIFRAME_FIBER_FLAT_MASTER,
2145 CPL_FRAME_GROUP_PRODUCT);
2146
2147 if (pframe == NULL) {
2148 cpl_msg_error(fctid, "Missing product frame (%s)",
2149 GIFRAME_FIBER_FLAT_MASTER);
2150
2151 giraffe_paf_delete(qc);
2152 qc = NULL;
2153
2154 return 1;
2155 }
2156
2157 cpl_msg_info(fctid, "Processing product frame '%s' (%s)",
2158 cpl_frame_get_filename(pframe), cpl_frame_get_tag(pframe));
2159
2160 pimage = giraffe_image_new(CPL_TYPE_DOUBLE);
2161 status = giraffe_image_load(pimage, cpl_frame_get_filename(pframe), 0);
2162
2163 if (status != 0) {
2164 cpl_msg_error(fctid, "Could not load master flat field '%s'!",
2165 cpl_frame_get_filename(pframe));
2166
2167 giraffe_image_delete(pimage);
2168 pimage = NULL;
2169
2170 giraffe_paf_delete(qc);
2171 qc = NULL;
2172
2173 return 1;
2174 }
2175
2176
2177 /*
2178 * Load first raw image as reference
2179 */
2180
2181 rframe = cpl_frameset_find(set, GIFRAME_FIBER_FLAT);
2182
2183 if (rframe == NULL) {
2184 cpl_msg_error(fctid, "Missing raw frame (%s)", GIFRAME_FIBER_FLAT);
2185
2186 giraffe_image_delete(pimage);
2187 pimage = NULL;
2188
2189 giraffe_paf_delete(qc);
2190 qc = NULL;
2191
2192 return 1;
2193 }
2194
2195 rimage = giraffe_image_new(CPL_TYPE_DOUBLE);
2196 status = giraffe_image_load(rimage, cpl_frame_get_filename(rframe), 0);
2197
2198 if (status != 0) {
2199
2200 cpl_msg_error(fctid, "Could not load flat field '%s'!",
2201 cpl_frame_get_filename(rframe));
2202
2203 giraffe_image_delete(rimage);
2204 rimage = NULL;
2205
2206 giraffe_image_delete(pimage);
2207 pimage = NULL;
2208
2209 giraffe_paf_delete(qc);
2210 qc = NULL;
2211
2212 return 1;
2213
2214 }
2215
2216 _rimage = giraffe_image_get(rimage);
2217 cx_assert(_rimage != NULL);
2218
2219 properties = giraffe_image_get_properties(rimage);
2220 cx_assert(properties != NULL);
2221
2222 giraffe_propertylist_copy(qclog, "ARCFILE", properties, GIALIAS_ARCFILE);
2223 giraffe_propertylist_copy(qclog, "TPL.ID", properties, GIALIAS_TPLID);
2224 giraffe_propertylist_copy(qclog, "INS.EXP.MODE", properties,
2225 GIALIAS_SETUPNAME);
2226 giraffe_propertylist_copy(qclog, "INS.SLIT.NAME", properties,
2227 GIALIAS_SLITNAME);
2228 giraffe_propertylist_copy(qclog, "INS.GRAT.WLEN", properties,
2229 GIALIAS_GRATWLEN);
2230 giraffe_propertylist_copy(qclog, "DPR.TYPE", properties, GIALIAS_DPRTYPE);
2231
2232 cpl_propertylist_update_string(qclog, "PRO.CATG",
2233 cpl_frame_get_tag(pframe));
2234 cpl_propertylist_set_comment(qclog, "PRO.CATG",
2235 "Pipeline product category");
2236
2237 properties = giraffe_image_get_properties(pimage);
2238 cx_assert(properties != NULL);
2239
2240 giraffe_propertylist_copy(qclog, "PRO.DATAAVG", properties,
2241 GIALIAS_DATAMEAN);
2242 giraffe_propertylist_copy(qclog, "PRO.DATARMS", properties,
2243 GIALIAS_DATASIG);
2244 giraffe_propertylist_copy(qclog, "PRO.DATAMED", properties,
2245 GIALIAS_DATAMEDI);
2246 giraffe_propertylist_copy(qclog, "PRO.DATANCOM", properties,
2247 GIALIAS_DATANCOM);
2248
2249
2250 /*
2251 * Compute mean level of the first raw frame and count the number
2252 * of saturated pixels.
2253 */
2254
2255 properties = giraffe_image_get_properties(rimage);
2256 cx_assert(properties != NULL);
2257
2258 if (cpl_propertylist_has(properties, GIALIAS_OVSCX) == TRUE) {
2259
2260 cxint _ox = cpl_propertylist_get_int(properties, GIALIAS_OVSCX);
2261 cxint _nx = cpl_image_get_size_x(_rimage) - 2 * CX_MAX(0, _ox) - 1;
2262
2263 w.x0 = CX_MAX(0, _ox) + 1;
2264 w.x1 = w.x0 + _nx;
2265
2266 }
2267
2268 if (cpl_propertylist_has(properties, GIALIAS_OVSCY) == TRUE) {
2269
2270 cxint _oy = cpl_propertylist_get_int(properties, GIALIAS_OVSCY);
2271 cxint _ny = cpl_image_get_size_y(_rimage) - 2 * CX_MAX(0, _oy) - 1;
2272
2273 w.y0 = CX_MAX(0, _oy) + 1;
2274 w.y1 = w.y0 + _ny;
2275
2276 }
2277
2278 mean = cpl_image_get_mean_window(_rimage, w.x0, w.y0, w.x1, w.y1);
2279
2280 pixels = cpl_image_get_data(_rimage);
2281 npixel = cpl_image_get_size_x(_rimage) * cpl_image_get_size_y(_rimage);
2282
2283 for (i = 0; i < npixel; i++) {
2284 if (pixels[i] > saturation) {
2285 ++nsaturated;
2286 }
2287 }
2288
2289
2290 properties = giraffe_image_get_properties(pimage);
2291 cx_assert(properties != NULL);
2292
2293 cpl_propertylist_update_double(properties, GIALIAS_QCMEAN, mean);
2294 cpl_propertylist_set_comment(properties, GIALIAS_QCMEAN, "Mean level of "
2295 "first raw frame");
2296
2297 giraffe_propertylist_copy(qclog, "QC.OUT1.MEAN.RAW", properties,
2298 GIALIAS_QCMEAN);
2299
2300
2301 cpl_propertylist_update_int(properties, GIALIAS_QCNSAT, nsaturated);
2302 cpl_propertylist_set_comment(properties, GIALIAS_QCNSAT, "Number of "
2303 "saturated pixels in the first raw frame");
2304
2305 giraffe_propertylist_copy(qclog, "QC.OUT1.NSAT.RAW", properties,
2306 GIALIAS_QCNSAT);
2307
2308
2309 /*
2310 * Calibration lamp monitoring
2311 */
2312
2313 cpl_propertylist_update_double(properties, GIALIAS_QCLAMP, efficiency[0]);
2314 cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP,
2315 "Calibration lamp efficiency");
2316
2317 giraffe_propertylist_copy(qclog, "QC.LAMP.EFFIC", properties,
2318 GIALIAS_QCLAMP);
2319
2320 cpl_propertylist_update_double(properties, GIALIAS_QCLAMP_SIMCAL,
2321 efficiency[1]);
2322 cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP_SIMCAL,
2323 "SIMCAL lamp efficiency");
2324
2325 giraffe_propertylist_copy(qclog, "QC.LAMP.EFFIC1", properties,
2326 GIALIAS_QCLAMP_SIMCAL);
2327
2328
2329 /*
2330 * Write QC1 log and save updated master flat field.
2331 */
2332
2333 giraffe_image_save(pimage, cpl_frame_get_filename(pframe));
2334
2335 giraffe_image_delete(pimage);
2336 pimage = NULL;
2337
2338 giraffe_qclog_close(qc);
2339 qc = NULL;
2340
2341
2342 /*
2343 * Process fiber localization centroid
2344 */
2345
2346 qc = giraffe_qclog_open(1);
2347
2348 if (qc == NULL) {
2349 cpl_msg_error(fctid, "Cannot create QC1 log!");
2350
2351 giraffe_image_delete(rimage);
2352 rimage = NULL;
2353
2354 return 1;
2355 }
2356
2357 qclog = giraffe_paf_get_properties(qc);
2358 cx_assert(qclog != NULL);
2359
2360 pframe = giraffe_get_frame(set, GIFRAME_LOCALIZATION_CENTROID,
2361 CPL_FRAME_GROUP_PRODUCT);
2362
2363 if (pframe == NULL) {
2364 cpl_msg_error(fctid, "Missing product frame (%s)",
2365 GIFRAME_LOCALIZATION_CENTROID);
2366
2367 giraffe_paf_delete(qc);
2368 qc = NULL;
2369
2370 giraffe_image_delete(rimage);
2371 rimage = NULL;
2372
2373 return 1;
2374 }
2375
2376 cpl_msg_info(fctid, "Processing product frame '%s' (%s)",
2377 cpl_frame_get_filename(pframe), cpl_frame_get_tag(pframe));
2378
2379
2380 pimage = giraffe_image_new(CPL_TYPE_DOUBLE);
2381 status = giraffe_image_load(pimage, cpl_frame_get_filename(pframe), 0);
2382
2383 if (status != 0) {
2384 cpl_msg_error(fctid, "Could not load localization centroids '%s'!",
2385 cpl_frame_get_filename(pframe));
2386
2387 giraffe_image_delete(pimage);
2388 pimage = NULL;
2389
2390 giraffe_image_delete(rimage);
2391 rimage = NULL;
2392
2393 giraffe_paf_delete(qc);
2394 qc = NULL;
2395
2396 return 1;
2397 }
2398
2399 ptable = giraffe_table_new();
2400 status = giraffe_table_load(ptable, cpl_frame_get_filename(pframe), 1,
2401 NULL);
2402
2403 if (status != 0) {
2404 cpl_msg_error(fctid, "Could not load localization centroids '%s'!",
2405 cpl_frame_get_filename(pframe));
2406
2407 giraffe_table_delete(ptable);
2408 ptable = NULL;
2409
2410 giraffe_image_delete(pimage);
2411 pimage = NULL;
2412
2413 giraffe_image_delete(rimage);
2414 rimage = NULL;
2415
2416 giraffe_paf_delete(qc);
2417 qc = NULL;
2418
2419 return 1;
2420 }
2421
2422 properties = giraffe_image_get_properties(rimage);
2423 cx_assert(properties != NULL);
2424
2425 giraffe_propertylist_copy(qclog, "ARCFILE", properties, GIALIAS_ARCFILE);
2426 giraffe_propertylist_copy(qclog, "TPL.ID", properties, GIALIAS_TPLID);
2427 giraffe_propertylist_copy(qclog, "INS.EXP.MODE", properties,
2428 GIALIAS_SETUPNAME);
2429 giraffe_propertylist_copy(qclog, "INS.SLIT.NAME", properties,
2430 GIALIAS_SLITNAME);
2431 giraffe_propertylist_copy(qclog, "INS.GRAT.WLEN", properties,
2432 GIALIAS_GRATWLEN);
2433 giraffe_propertylist_copy(qclog, "DPR.TYPE", properties, GIALIAS_DPRTYPE);
2434
2435 cpl_propertylist_update_string(qclog, "PRO.CATG",
2436 cpl_frame_get_tag(pframe));
2437 cpl_propertylist_set_comment(qclog, "PRO.CATG",
2438 "Pipeline product category");
2439
2440 properties = giraffe_image_get_properties(pimage);
2441 cx_assert(properties != NULL);
2442
2443 giraffe_propertylist_copy(qclog, "PRO.DATAAVG", properties,
2444 GIALIAS_DATAMEAN);
2445 giraffe_propertylist_copy(qclog, "PRO.DATARMS", properties,
2446 GIALIAS_DATASIG);
2447 giraffe_propertylist_copy(qclog, "PRO.DATAMED", properties,
2448 GIALIAS_DATAMEDI);
2449 giraffe_propertylist_copy(qclog, "PRO.DATANCOM", properties,
2450 GIALIAS_DATANCOM);
2451 giraffe_propertylist_copy(qclog, "PRO.SLIT.NFIBRES", properties,
2452 GIALIAS_NFIBERS);
2453
2454
2455 /*
2456 * Calibration lamp monitoring
2457 */
2458
2459 cpl_propertylist_update_double(properties, GIALIAS_QCLAMP, efficiency[0]);
2460 cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP,
2461 "Calibration lamp efficiency");
2462
2463 giraffe_propertylist_copy(qclog, "QC.LAMP.EFFIC", properties,
2464 GIALIAS_QCLAMP);
2465
2466 cpl_propertylist_update_double(properties, GIALIAS_QCLAMP_SIMCAL,
2467 efficiency[1]);
2468 cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP_SIMCAL,
2469 "SIMCAL lamp efficiency");
2470
2471 giraffe_propertylist_copy(qclog, "QC.LAMP.EFFIC1", properties,
2472 GIALIAS_QCLAMP_SIMCAL);
2473
2474
2475 /* Fiber signal curvature RMS */
2476
2477 _pimage = giraffe_image_get(pimage);
2478
2479 _test = cpl_image_collapse_create(_pimage, 0);
2480 cpl_image_divide_scalar(_test, cpl_image_get_size_y(_pimage));
2481
2482 _pdata = cpl_image_get_data(_pimage);
2483 _tdata = cpl_image_get_data(_test);
2484
2485 rms = 0.;
2486
2487 nx = cpl_image_get_size_x(_pimage);
2488 ny = cpl_image_get_size_y(_pimage);
2489
2490 for (i = 0; i < nx; i++) {
2491
2492 cxint j;
2493
2494 cxdouble _rms = 0.;
2495
2496
2497 for (j = 0; j < ny; j++) {
2498 _rms += pow(_pdata[j * nx + i] - _tdata[i], 2.);
2499 }
2500
2501 rms += sqrt(_rms / (ny - 1));
2502
2503 }
2504
2505 rms /= nx;
2506
2507 cpl_image_delete(_test);
2508 _test = NULL;
2509
2510 cpl_propertylist_update_double(properties, GIALIAS_QCLCRMS, rms);
2511 cpl_propertylist_set_comment(properties, GIALIAS_QCLCRMS,
2512 "Mean fibre signal curvature");
2513
2514 giraffe_propertylist_copy(qclog, "QC.FIBRE.CENTROID.RMS", properties,
2515 GIALIAS_QCLCRMS);
2516
2517
2518 /* Difference of fiber signal curvature */
2519
2520 diff = 0.;
2521
2522 for (i = 0; i < nx; i++) {
2523
2524 cxdouble min = cpl_image_get_min_window(_pimage,
2525 i + 1, 1, i + 1, ny);
2526 cxdouble max = cpl_image_get_max_window(_pimage,
2527 i + 1, 1, i + 1, ny);
2528
2529 diff += max - min;
2530
2531 }
2532
2533 diff /= nx;
2534
2535 cpl_propertylist_update_double(properties, GIALIAS_QCLCDIFF, diff);
2536 cpl_propertylist_set_comment(properties, GIALIAS_QCLCDIFF,
2537 "Mean difference of fibre signal "
2538 "curvature");
2539
2540 giraffe_propertylist_copy(qclog, "QC.FIBRE.CENTROID.DIFF", properties,
2541 GIALIAS_QCLCDIFF);
2542
2543
2544 status = giraffe_image_save(pimage, cpl_frame_get_filename(pframe));
2545
2546 if (status != 0) {
2547 cpl_msg_error(fctid, "Could not save localization centroids '%s'!",
2548 cpl_frame_get_filename(pframe));
2549
2550 giraffe_table_delete(ptable);
2551 ptable = NULL;
2552
2553 giraffe_image_delete(pimage);
2554 pimage = NULL;
2555
2556 giraffe_image_delete(rimage);
2557 rimage = NULL;
2558
2559 giraffe_paf_delete(qc);
2560 qc = NULL;
2561
2562 return 1;
2563 }
2564
2565 status = giraffe_table_attach(ptable, cpl_frame_get_filename(pframe),
2566 1, NULL);
2567
2568 if (status != 0) {
2569 cpl_msg_error(fctid, "Could not save localization centroids '%s'!",
2570 cpl_frame_get_filename(pframe));
2571
2572 giraffe_table_delete(ptable);
2573 ptable = NULL;
2574
2575 giraffe_image_delete(pimage);
2576 pimage = NULL;
2577
2578 giraffe_image_delete(rimage);
2579 rimage = NULL;
2580
2581 giraffe_paf_delete(qc);
2582 qc = NULL;
2583
2584 return 1;
2585 }
2586
2587 giraffe_image_delete(pimage);
2588 pimage = NULL;
2589
2590 giraffe_table_delete(ptable);
2591 ptable = NULL;
2592
2593 giraffe_qclog_close(qc);
2594 qc = NULL;
2595
2596
2597 /*
2598 * Process fiber localization width
2599 */
2600
2601 qc = giraffe_qclog_open(2);
2602
2603 if (qc == NULL) {
2604 cpl_msg_error(fctid, "Cannot create QC1 log!");
2605
2606 giraffe_image_delete(rimage);
2607 rimage = NULL;
2608
2609 return 1;
2610 }
2611
2612 qclog = giraffe_paf_get_properties(qc);
2613 cx_assert(qclog != NULL);
2614
2615 pframe = giraffe_get_frame(set, GIFRAME_LOCALIZATION_WIDTH,
2616 CPL_FRAME_GROUP_PRODUCT);
2617
2618 if (pframe == NULL) {
2619 cpl_msg_error(fctid, "Missing product frame (%s)",
2620 GIFRAME_LOCALIZATION_WIDTH);
2621
2622 giraffe_paf_delete(qc);
2623 qc = NULL;
2624
2625 giraffe_image_delete(rimage);
2626 rimage = NULL;
2627
2628 return 1;
2629 }
2630
2631 cpl_msg_info(fctid, "Processing product frame '%s' (%s)",
2632 cpl_frame_get_filename(pframe), cpl_frame_get_tag(pframe));
2633
2634
2635 pimage = giraffe_image_new(CPL_TYPE_DOUBLE);
2636 status = giraffe_image_load(pimage, cpl_frame_get_filename(pframe), 0);
2637
2638 if (status != 0) {
2639 cpl_msg_error(fctid, "Could not load localization widths '%s'!",
2640 cpl_frame_get_filename(pframe));
2641
2642 giraffe_image_delete(pimage);
2643 pimage = NULL;
2644
2645 giraffe_image_delete(rimage);
2646 rimage = NULL;
2647
2648 giraffe_paf_delete(qc);
2649 qc = NULL;
2650
2651 return 1;
2652 }
2653
2654 ptable = giraffe_table_new();
2655 status = giraffe_table_load(ptable, cpl_frame_get_filename(pframe), 1,
2656 NULL);
2657
2658 if (status != 0) {
2659 cpl_msg_error(fctid, "Could not load localization widths '%s'!",
2660 cpl_frame_get_filename(pframe));
2661
2662 giraffe_table_delete(ptable);
2663 ptable = NULL;
2664
2665 giraffe_image_delete(pimage);
2666 pimage = NULL;
2667
2668 giraffe_image_delete(rimage);
2669 rimage = NULL;
2670
2671 giraffe_paf_delete(qc);
2672 qc = NULL;
2673
2674 return 1;
2675 }
2676
2677 properties = giraffe_image_get_properties(rimage);
2678 cx_assert(properties != NULL);
2679
2680 giraffe_propertylist_copy(qclog, "ARCFILE", properties, GIALIAS_ARCFILE);
2681 giraffe_propertylist_copy(qclog, "TPL.ID", properties, GIALIAS_TPLID);
2682 giraffe_propertylist_copy(qclog, "INS.EXP.MODE", properties,
2683 GIALIAS_SETUPNAME);
2684 giraffe_propertylist_copy(qclog, "INS.SLIT.NAME", properties,
2685 GIALIAS_SLITNAME);
2686 giraffe_propertylist_copy(qclog, "INS.GRAT.WLEN", properties,
2687 GIALIAS_GRATWLEN);
2688 giraffe_propertylist_copy(qclog, "DPR.TYPE", properties, GIALIAS_DPRTYPE);
2689
2690 cpl_propertylist_update_string(qclog, "PRO.CATG",
2691 cpl_frame_get_tag(pframe));
2692 cpl_propertylist_set_comment(qclog, "PRO.CATG",
2693 "Pipeline product category");
2694
2695 properties = giraffe_image_get_properties(pimage);
2696 cx_assert(properties != NULL);
2697
2698 giraffe_propertylist_copy(qclog, "PRO.DATAAVG", properties,
2699 GIALIAS_DATAMEAN);
2700 giraffe_propertylist_copy(qclog, "PRO.DATARMS", properties,
2701 GIALIAS_DATASIG);
2702 giraffe_propertylist_copy(qclog, "PRO.DATAMED", properties,
2703 GIALIAS_DATAMEDI);
2704 giraffe_propertylist_copy(qclog, "PRO.DATANCOM", properties,
2705 GIALIAS_DATANCOM);
2706 giraffe_propertylist_copy(qclog, "PRO.SLIT.NFIBRES", properties,
2707 GIALIAS_NFIBERS);
2708
2709
2710 /*
2711 * Calibration lamp monitoring
2712 */
2713
2714 cpl_propertylist_update_double(properties, GIALIAS_QCLAMP, efficiency[0]);
2715 cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP,
2716 "Calibration lamp efficiency");
2717
2718 giraffe_propertylist_copy(qclog, "QC.LAMP.EFFIC", properties,
2719 GIALIAS_QCLAMP);
2720
2721 cpl_propertylist_update_double(properties, GIALIAS_QCLAMP_SIMCAL,
2722 efficiency[1]);
2723 cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP_SIMCAL,
2724 "SIMCAL lamp efficiency");
2725
2726 giraffe_propertylist_copy(qclog, "QC.LAMP.EFFIC1", properties,
2727 GIALIAS_QCLAMP_SIMCAL);
2728
2729
2730 /* Compute fiber width statistics, i.e. the mean width and its RMS */
2731
2732 _pimage = giraffe_image_get(pimage);
2733
2734 _test = cpl_image_collapse_create(_pimage, 0);
2735 cpl_image_divide_scalar(_test, cpl_image_get_size_y(_pimage));
2736
2737 _pdata = cpl_image_get_data(_pimage);
2738 _tdata = cpl_image_get_data(_test);
2739
2740 mean = 0.;
2741 rms = 0.;
2742
2743 nx = cpl_image_get_size_x(_pimage);
2744 ny = cpl_image_get_size_y(_pimage);
2745
2746 for (i = 0; i < nx; i++) {
2747
2748 cxint j;
2749
2750 cxdouble _rms = 0.;
2751
2752
2753 for (j = 0; j < ny; j++) {
2754 _rms += pow(_pdata[j * nx + i] - _tdata[i], 2.);
2755 }
2756
2757 mean += _tdata[i];
2758 rms += sqrt(_rms / (ny - 1));
2759
2760 }
2761
2762 mean /= nx;
2763 rms /= nx;
2764
2765 cpl_image_delete(_test);
2766 _test = NULL;
2767
2768
2769 cpl_propertylist_update_double(properties, GIALIAS_QCLWAVG, mean);
2770 cpl_propertylist_set_comment(properties, GIALIAS_QCLWAVG,
2771 "Mean fibre half width");
2772
2773 giraffe_propertylist_copy(qclog, "QC.FIBRE.WIDTH.MEAN", properties,
2774 GIALIAS_QCLWAVG);
2775
2776 cpl_propertylist_update_double(properties, GIALIAS_QCLWRMS, rms);
2777 cpl_propertylist_set_comment(properties, GIALIAS_QCLWRMS,
2778 "RMS of fibre half width");
2779
2780 giraffe_propertylist_copy(qclog, "QC.FIBRE.WIDTH.RMS", properties,
2781 GIALIAS_QCLWRMS);
2782
2783
2784 status = giraffe_image_save(pimage, cpl_frame_get_filename(pframe));
2785
2786 if (status != 0) {
2787 cpl_msg_error(fctid, "Could not save localization widths '%s'!",
2788 cpl_frame_get_filename(pframe));
2789
2790 giraffe_table_delete(ptable);
2791 ptable = NULL;
2792
2793 giraffe_image_delete(pimage);
2794 pimage = NULL;
2795
2796 giraffe_image_delete(rimage);
2797 rimage = NULL;
2798
2799 giraffe_paf_delete(qc);
2800 qc = NULL;
2801
2802 return 1;
2803 }
2804
2805 status = giraffe_table_attach(ptable, cpl_frame_get_filename(pframe),
2806 1, NULL);
2807
2808 if (status != 0) {
2809 cpl_msg_error(fctid, "Could not save localization widths '%s'!",
2810 cpl_frame_get_filename(pframe));
2811
2812 giraffe_table_delete(ptable);
2813 ptable = NULL;
2814
2815 giraffe_image_delete(pimage);
2816 pimage = NULL;
2817
2818 giraffe_image_delete(rimage);
2819 rimage = NULL;
2820
2821 giraffe_paf_delete(qc);
2822 qc = NULL;
2823
2824 return 1;
2825 }
2826
2827 giraffe_image_delete(pimage);
2828 pimage = NULL;
2829
2830 giraffe_table_delete(ptable);
2831 ptable = NULL;
2832
2833 giraffe_qclog_close(qc);
2834 qc = NULL;
2835
2836
2837 /*
2838 * Process extracted flat field spectra
2839 */
2840
2841 qc = giraffe_qclog_open(3);
2842
2843 if (qc == NULL) {
2844 cpl_msg_error(fctid, "Cannot create QC1 log!");
2845
2846 giraffe_image_delete(rimage);
2847 rimage = NULL;
2848
2849 return 1;
2850 }
2851
2852 qclog = giraffe_paf_get_properties(qc);
2853 cx_assert(qclog != NULL);
2854
2855 pframe = giraffe_get_frame(set, GIFRAME_FIBER_FLAT_EXTSPECTRA,
2856 CPL_FRAME_GROUP_PRODUCT);
2857
2858 if (pframe == NULL) {
2859 cpl_msg_error(fctid, "Missing product frame (%s)",
2860 GIFRAME_FIBER_FLAT_EXTSPECTRA);
2861
2862 giraffe_paf_delete(qc);
2863 qc = NULL;
2864
2865 giraffe_image_delete(rimage);
2866 rimage = NULL;
2867
2868 return 1;
2869 }
2870
2871 cpl_msg_info(fctid, "Processing product frame '%s' (%s)",
2872 cpl_frame_get_filename(pframe), cpl_frame_get_tag(pframe));
2873
2874
2875 pimage = giraffe_image_new(CPL_TYPE_DOUBLE);
2876 status = giraffe_image_load(pimage, cpl_frame_get_filename(pframe), 0);
2877
2878 if (status != 0) {
2879 cpl_msg_error(fctid, "Could not load extracted flat field spectra "
2880 "'%s'!", cpl_frame_get_filename(pframe));
2881
2882 giraffe_image_delete(pimage);
2883 pimage = NULL;
2884
2885 giraffe_image_delete(rimage);
2886 rimage = NULL;
2887
2888 giraffe_paf_delete(qc);
2889 qc = NULL;
2890
2891 return 1;
2892 }
2893
2894 ptable = giraffe_table_new();
2895 status = giraffe_table_load(ptable, cpl_frame_get_filename(pframe), 1,
2896 NULL);
2897
2898 if (status != 0) {
2899 cpl_msg_error(fctid, "Could not load extracted flat field spectra "
2900 "'%s'!", cpl_frame_get_filename(pframe));
2901
2902 giraffe_table_delete(ptable);
2903 ptable = NULL;
2904
2905 giraffe_image_delete(pimage);
2906 pimage = NULL;
2907
2908 giraffe_image_delete(rimage);
2909 rimage = NULL;
2910
2911 giraffe_paf_delete(qc);
2912 qc = NULL;
2913
2914 return 1;
2915 }
2916
2917 properties = giraffe_image_get_properties(rimage);
2918 cx_assert(properties != NULL);
2919
2920 giraffe_propertylist_copy(qclog, "ARCFILE", properties, GIALIAS_ARCFILE);
2921 giraffe_propertylist_copy(qclog, "TPL.ID", properties, GIALIAS_TPLID);
2922 giraffe_propertylist_copy(qclog, "INS.EXP.MODE", properties,
2923 GIALIAS_SETUPNAME);
2924 giraffe_propertylist_copy(qclog, "INS.SLIT.NAME", properties,
2925 GIALIAS_SLITNAME);
2926 giraffe_propertylist_copy(qclog, "INS.GRAT.WLEN", properties,
2927 GIALIAS_GRATWLEN);
2928 giraffe_propertylist_copy(qclog, "DPR.TYPE", properties, GIALIAS_DPRTYPE);
2929
2930 cpl_propertylist_update_string(qclog, "PRO.CATG",
2931 cpl_frame_get_tag(pframe));
2932 cpl_propertylist_set_comment(qclog, "PRO.CATG",
2933 "Pipeline product category");
2934
2935 properties = giraffe_image_get_properties(pimage);
2936 cx_assert(properties != NULL);
2937
2938 giraffe_propertylist_copy(qclog, "PRO.DATAAVG", properties,
2939 GIALIAS_DATAMEAN);
2940 giraffe_propertylist_copy(qclog, "PRO.DATARMS", properties,
2941 GIALIAS_DATASIG);
2942 giraffe_propertylist_copy(qclog, "PRO.DATAMED", properties,
2943 GIALIAS_DATAMEDI);
2944 giraffe_propertylist_copy(qclog, "PRO.DATANCOM", properties,
2945 GIALIAS_DATANCOM);
2946 giraffe_propertylist_copy(qclog, "PRO.SLIT.NFIBRES", properties,
2947 GIALIAS_NFIBERS);
2948
2949
2950 /*
2951 * Calibration lamp monitoring
2952 */
2953
2954 cpl_propertylist_update_double(properties, GIALIAS_QCLAMP, efficiency[0]);
2955 cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP,
2956 "Calibration lamp efficiency");
2957
2958 giraffe_propertylist_copy(qclog, "QC.LAMP.EFFIC", properties,
2959 GIALIAS_QCLAMP);
2960
2961 cpl_propertylist_update_double(properties, GIALIAS_QCLAMP_SIMCAL,
2962 efficiency[1]);
2963 cpl_propertylist_set_comment(properties, GIALIAS_QCLAMP_SIMCAL,
2964 "SIMCAL lamp efficiency");
2965
2966 giraffe_propertylist_copy(qclog, "QC.LAMP.EFFIC1", properties,
2967 GIALIAS_QCLAMP_SIMCAL);
2968
2969
2970 _ptable = giraffe_table_get(ptable);
2971
2972 if (cpl_table_has_column(_ptable, "TRANSMISSION") == FALSE) {
2973 cpl_msg_warning(fctid, "Relative fiber transmission not available! "
2974 "QC parameter computation skipped.");
2975 }
2976 else {
2977
2978 const cxdouble low = 0.5;
2979 const cxdouble high = 2.0;
2980
2981 cxint nf = 0;
2982
2983 cxdouble t = 0.;
2984 cxdouble dt = 0.;
2985
2986 cpl_table* ttable = NULL;
2987
2988
2989 rms = 0.;
2990
2991 cpl_table_unselect_all(_ptable);
2992
2993 cpl_table_or_selected_int(_ptable, "RP", CPL_GREATER_THAN, 0);
2994 cpl_table_and_selected_double(_ptable, "TRANSMISSION",
2995 CPL_GREATER_THAN, low);
2996 cpl_table_and_selected_double(_ptable, "TRANSMISSION",
2997 CPL_LESS_THAN, high);
2998
2999 ttable = cpl_table_extract_selected(_ptable);
3000
3001 nf = cpl_table_get_nrow(ttable);
3002 if (ttable == NULL || nf <= 0) {
3003 cpl_msg_warning(fctid, "No fiber found within transmission "
3004 "range ]%.2f, %.2f[", low, high);
3005
3006 }
3007 else {
3008
3009 t = cpl_table_get_column_median(ttable, "TRANSMISSION");
3010
3011 if (nf > 1) {
3012
3013 for (i = 0; i < cpl_table_get_nrow(ttable); i++) {
3014
3015 cxdouble _t = cpl_table_get_double(ttable,
3016 "TRANSMISSION", i, NULL);
3017 rms += pow(_t - t, 2.);
3018
3019 }
3020
3021 rms = sqrt(rms / (cpl_table_get_nrow(ttable) - 1));
3022
3023 }
3024 else {
3025 rms = 0.;
3026 }
3027
3028
3029 }
3030
3031 if (!cpl_table_has_column(_ptable, "DTRANSMISSION")) {
3032 cpl_msg_warning(fctid, "Relative fiber transmission error not "
3033 "available! QC parameter computation skipped.");
3034 }
3035 else {
3036
3037 cx_assert(cpl_table_has_column(ttable, "DTRANSMISSION") != 0);
3038 dt = cpl_table_get_column_median(ttable, "DTRANSMISSION");
3039
3040 }
3041
3042 cpl_table_delete(ttable);
3043 ttable = NULL;
3044
3045
3046 cpl_propertylist_update_double(properties, GIALIAS_QCTRMED, t);
3047 cpl_propertylist_set_comment(properties, GIALIAS_QCTRMED, "Median of "
3048 "relative fibre transmission");
3049
3050 giraffe_propertylist_copy(qclog, "QC.FIBRE.TRANS.MEDIAN", properties,
3051 GIALIAS_QCTRMED);
3052
3053
3054 cpl_propertylist_update_double(properties, GIALIAS_QCTRRMS, rms);
3055 cpl_propertylist_set_comment(properties, GIALIAS_QCTRRMS, "RMS of "
3056 "relative fibre transmission");
3057
3058 giraffe_propertylist_copy(qclog, "QC.FIBRE.TRANS.RMS", properties,
3059 GIALIAS_QCTRRMS);
3060
3061
3062 cpl_propertylist_update_double(properties, GIALIAS_QCTRERR, dt);
3063 cpl_propertylist_set_comment(properties, GIALIAS_QCTRERR, "Median of "
3064 "relative fibre transmission error");
3065
3066 giraffe_propertylist_copy(qclog, "QC.FIBRE.TRANS.ERROR", properties,
3067 GIALIAS_QCTRERR);
3068
3069
3070 //FIXME: Check whether this number is useful!
3071#if 0
3072 cpl_propertylist_update_int(properties, GIALIAS_QCTRNF, nf);
3073 cpl_propertylist_set_comment(properties, GIALIAS_QCTRNF, "Number "
3074 "of fibres used for median transmission computation.");
3075
3076 giraffe_propertylist_copy(qclog, "QC.FIBRE.TRANS.NFIBRES",
3077 properties, GIALIAS_QCTRNF);
3078#endif
3079 cpl_msg_debug(fctid, "%d fibers used for median transmission "
3080 "computation.", nf);
3081
3082 }
3083
3084 status = giraffe_image_save(pimage, cpl_frame_get_filename(pframe));
3085
3086 if (status != 0) {
3087 cpl_msg_error(fctid, "Could not save extracted flat field spectra "
3088 "'%s'!", cpl_frame_get_filename(pframe));
3089
3090 giraffe_table_delete(ptable);
3091 ptable = NULL;
3092
3093 giraffe_image_delete(pimage);
3094 pimage = NULL;
3095
3096 giraffe_image_delete(rimage);
3097 rimage = NULL;
3098
3099 giraffe_paf_delete(qc);
3100 qc = NULL;
3101
3102 return 1;
3103 }
3104
3105 status = giraffe_table_attach(ptable, cpl_frame_get_filename(pframe),
3106 1, NULL);
3107
3108 if (status != 0) {
3109 cpl_msg_error(fctid, "Could not save extracted flat field spectra "
3110 "'%s'!", cpl_frame_get_filename(pframe));
3111
3112 giraffe_table_delete(ptable);
3113 ptable = NULL;
3114
3115 giraffe_image_delete(pimage);
3116 pimage = NULL;
3117
3118 giraffe_image_delete(rimage);
3119 rimage = NULL;
3120
3121 giraffe_paf_delete(qc);
3122 qc = NULL;
3123
3124 return 1;
3125 }
3126
3127 giraffe_image_delete(pimage);
3128 pimage = NULL;
3129
3130 giraffe_table_delete(ptable);
3131 ptable = NULL;
3132
3133 giraffe_qclog_close(qc);
3134 qc = NULL;
3135
3136
3137 /*
3138 * Cleanup
3139 */
3140
3141 giraffe_image_delete(rimage);
3142
3143 return 0;
3144
3145}
3146
3147
3148/*
3149 * Build table of contents, i.e. the list of available plugins, for
3150 * this module. This function is exported.
3151 */
3152
3153int
3154cpl_plugin_get_info(cpl_pluginlist* list)
3155{
3156
3157 cpl_recipe* recipe = cx_calloc(1, sizeof *recipe);
3158 cpl_plugin* plugin = &recipe->interface;
3159
3160
3161 cpl_plugin_init(plugin,
3162 CPL_PLUGIN_API,
3163 GIRAFFE_BINARY_VERSION,
3164 CPL_PLUGIN_TYPE_RECIPE,
3165 "gimasterflat",
3166 "Create the fiber master flat field and the "
3167 "localization mask.",
3168 "For detailed information please refer to the "
3169 "GIRAFFE pipeline user manual.\nIt is available at "
3170 "http://www.eso.org/pipelines.",
3171 "Giraffe Pipeline",
3172 PACKAGE_BUGREPORT,
3174 gimasterflat_create,
3175 gimasterflat_exec,
3176 gimasterflat_destroy);
3177
3178 cpl_pluginlist_append(list, plugin);
3179
3180 return 0;
3181
3182}
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:913
cxint giraffe_fiberlist_attach(cpl_frame *frame, GiTable *fibers)
Attach a fiber table to a frame.
Definition: gifiberutils.c:845
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:1104
const cxchar * giraffe_get_license(void)
Get the pipeline copyright and license.
Definition: giutils.c:418

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