GIRAFFE Pipeline Reference Manual

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

This file is part of the GIRAFFE Pipeline Reference Manual 2.14.
Documentation copyright © 2002-2006 European Southern Observatory.
Generated on Wed Mar 11 2015 13:19:41 by doxygen 1.8.9.1 written by Dimitri van Heesch, © 1997-2004