GIRAFFE Pipeline Reference Manual

gistandard.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 
36 #include <cpl_recipe.h>
37 #include <cpl_plugininfo.h>
38 #include <cpl_parameterlist.h>
39 #include <cpl_frameset.h>
40 #include <cpl_msg.h>
41 
42 #include "gialias.h"
43 #include "giframe.h"
44 #include "gifibers.h"
45 #include "gifiberutils.h"
46 #include "gislitgeometry.h"
47 #include "gipsfdata.h"
48 #include "gibias.h"
49 #include "gidark.h"
50 #include "giextract.h"
51 #include "giflat.h"
52 #include "gitransmission.h"
53 #include "girebinning.h"
54 #include "gifov.h"
55 #include "gifxcalibration.h"
56 #include "gimessages.h"
57 #include "gierror.h"
58 #include "giqclog.h"
59 #include "giutils.h"
60 
61 
62 static cxint gistandard(cpl_parameterlist* config, cpl_frameset* set);
63 static cxint giqcstandard(cpl_frameset* set);
64 
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 gistandard_create(cpl_plugin* plugin)
74 {
75 
76  cpl_recipe* recipe = (cpl_recipe*)plugin;
77 
78  cpl_parameter* p = NULL;
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  /* Bias removal */
99 
100  giraffe_bias_config_add(recipe->parameters);
101 
102  /* Dark subtraction */
103 
104  /* TBD */
105 
106  /* Spectrum extraction */
107 
108  giraffe_extract_config_add(recipe->parameters);
109 
110  /* Flat fielding and relative fiber transmission correction */
111 
112  giraffe_flat_config_add(recipe->parameters);
113 
114  p = cpl_parameterlist_find(recipe->parameters, "giraffe.flat.apply");
115  cx_assert(p != NULL);
116 
117  cpl_parameter_set_default_bool(p, FALSE);
118 
119  /* Spectrum rebinning */
120 
121  giraffe_rebin_config_add(recipe->parameters);
122 
123  p = cpl_parameterlist_find(recipe->parameters,
124  "giraffe.rebinning.range");
125  cx_assert(p != NULL);
126 
127  cpl_parameter_set_default_string(p, "common");
128 
129  /* Image reconstruction (IFU and Argus only) */
130 
131  giraffe_fov_config_add(recipe->parameters);
132 
133  /* Flux calibration */
134 
135  giraffe_fxcalibration_config_add(recipe->parameters);
136 
137  return 0;
138 
139 }
140 
141 
142 /*
143  * Execute the plugin instance given by the interface.
144  */
145 
146 static cxint
147 gistandard_exec(cpl_plugin* plugin)
148 {
149 
150  cxint status = 0;
151 
152  cpl_recipe* recipe = (cpl_recipe*)plugin;
153 
154 
155  cx_assert(recipe->parameters != NULL);
156  cx_assert(recipe->frames != NULL);
157 
158  status = gistandard(recipe->parameters, recipe->frames);
159 
160  if (status != 0) {
161  return 1;
162  }
163 
164  status = giqcstandard(recipe->frames);
165 
166  if (status != 0) {
167  return 1;
168  }
169 
170  return 0;
171 
172 }
173 
174 
175 static cxint
176 gistandard_destroy(cpl_plugin* plugin)
177 {
178 
179  cpl_recipe* recipe = (cpl_recipe*)plugin;
180 
181 
182  /*
183  * We just destroy what was created during the plugin initialization
184  * phase, i.e. the parameter list. The frame set is managed by the
185  * application which called us, so we must not touch it,
186  */
187 
188  cpl_parameterlist_delete(recipe->parameters);
189 
190  giraffe_error_clear();
191 
192  return 0;
193 
194 }
195 
196 
197 /*
198  * The actual recipe starts here.
199  */
200 
201 static cxint
202 gistandard(cpl_parameterlist* config, cpl_frameset* set)
203 {
204 
205  const cxchar* const _id = "gistandard";
206 
207 
208  const cxchar* filename = NULL;
209 
210  cxint status = 0;
211 
212  cxlong i;
213  cxlong nstandard = 0;
214 
215  cxdouble exptime = 0.;
216 
217  cx_slist* slist = NULL;
218 
219  cpl_propertylist* properties = NULL;
220 
221  cpl_matrix* biasareas = NULL;
222 
223  cpl_frame* standard_frame = NULL;
224  cpl_frame* mbias_frame = NULL;
225  cpl_frame* mdark_frame = NULL;
226  cpl_frame* bpixel_frame = NULL;
227  cpl_frame* slight_frame = NULL;
228  cpl_frame* locy_frame = NULL;
229  cpl_frame* locw_frame = NULL;
230  cpl_frame* flat_frame = NULL;
231  cpl_frame* psfdata_frame = NULL;
232  cpl_frame* grating_frame = NULL;
233  cpl_frame* slit_frame = NULL;
234  cpl_frame* wcal_frame = NULL;
235  cpl_frame* rstandard_frame = NULL;
236  cpl_frame* sext_frame = NULL;
237  cpl_frame* rbin_frame = NULL;
238  cpl_frame* atmext_frame = NULL;
239  cpl_frame* flxstd_frame = NULL;
240  cpl_frame* rsp_frame = NULL;
241 
242  GiImage* mbias = NULL;
243  GiImage* mdark = NULL;
244  GiImage* bpixel = NULL;
245  GiImage* slight = NULL;
246  GiImage* sstandard = NULL;
247  GiImage* rstandard = NULL;
248 
249  GiTable* fibers = NULL;
250  GiTable* slitgeometry = NULL;
251  GiTable* grating = NULL;
252  GiTable* wcalcoeff = NULL;
253  GiTable* atmext = NULL;
254  GiTable* flxstd = NULL;
255  GiTable* refflx = NULL;
256 
257  GiLocalization* localization = NULL;
258  GiExtraction* extraction = NULL;
259  GiRebinning* rebinning = NULL;
260  GiResponse* response = NULL;
261 
262  GiBiasConfig* bias_config = NULL;
263  GiExtractConfig* extract_config = NULL;
264  GiFlatConfig* flat_config = NULL;
265  GiRebinConfig* rebin_config = NULL;
266  GiFxCalibrationConfig* fxcal_config = NULL;
267 
268 
269  GiInstrumentMode mode;
270 
271  GiRecipeInfo info = {(cxchar*)_id, 1, NULL};
272 
273  GiGroupInfo groups[] = {
274  {GIFRAME_STANDARD, CPL_FRAME_GROUP_RAW},
275  {GIFRAME_BADPIXEL_MAP, CPL_FRAME_GROUP_CALIB},
276  {GIFRAME_BIAS_MASTER, CPL_FRAME_GROUP_CALIB},
277  {GIFRAME_DARK_MASTER, CPL_FRAME_GROUP_CALIB},
278  {GIFRAME_FIBER_FLAT_EXTSPECTRA, CPL_FRAME_GROUP_CALIB},
279  {GIFRAME_FIBER_FLAT_EXTERRORS, CPL_FRAME_GROUP_CALIB},
280  {GIFRAME_SCATTERED_LIGHT_MODEL, CPL_FRAME_GROUP_CALIB},
281  {GIFRAME_LOCALIZATION_CENTROID, CPL_FRAME_GROUP_CALIB},
282  {GIFRAME_LOCALIZATION_WIDTH, CPL_FRAME_GROUP_CALIB},
283  {GIFRAME_PSF_CENTROID, CPL_FRAME_GROUP_CALIB},
284  {GIFRAME_PSF_WIDTH, CPL_FRAME_GROUP_CALIB},
285  {GIFRAME_PSF_DATA, CPL_FRAME_GROUP_CALIB},
286  {GIFRAME_WAVELENGTH_SOLUTION, CPL_FRAME_GROUP_CALIB},
287  {GIFRAME_SLITSETUP, CPL_FRAME_GROUP_CALIB},
288  {GIFRAME_SLITMASTER, CPL_FRAME_GROUP_CALIB},
289  {GIFRAME_GRATING, CPL_FRAME_GROUP_CALIB},
290  {GIFRAME_EXTINCTION, CPL_FRAME_GROUP_CALIB},
291  {GIFRAME_FLUX_STANDARDS, 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  /*
316  * Verify the frame set contents
317  */
318 
319  nstandard = cpl_frameset_count_tags(set, GIFRAME_STANDARD);
320 
321  if (nstandard < 1) {
322  cpl_msg_error(_id, "Too few (%ld) raw frames (%s) present in "
323  "frame set! Aborting ...", nstandard, GIFRAME_STANDARD);
324  return 1;
325  }
326 
327  locy_frame = cpl_frameset_find(set, GIFRAME_PSF_CENTROID);
328 
329  if (locy_frame == NULL) {
330 
331  locy_frame = cpl_frameset_find(set, GIFRAME_LOCALIZATION_CENTROID);
332 
333  if (locy_frame == NULL) {
334  cpl_msg_info(_id, "No master localization (centroid position) "
335  "present in frame set. Aborting ...");
336  return 1;
337  }
338 
339  }
340 
341  locw_frame = cpl_frameset_find(set, GIFRAME_PSF_WIDTH);
342 
343  if (locw_frame == NULL) {
344 
345  locw_frame = cpl_frameset_find(set, GIFRAME_LOCALIZATION_WIDTH);
346 
347  if (locw_frame == NULL) {
348  cpl_msg_info(_id, "No master localization (spectrum width) "
349  "present in frame set. Aborting ...");
350  return 1;
351  }
352 
353  }
354 
355  flat_frame = cpl_frameset_find(set, GIFRAME_FIBER_FLAT_EXTSPECTRA);
356 
357  if (flat_frame == NULL) {
358 
359  cpl_msg_error(_id, "No extracted flat field spectra frame present in frame set. "
360  "Aborting ...");
361  return 1;
362 
363  }
364 
365  grating_frame = cpl_frameset_find(set, GIFRAME_GRATING);
366 
367  if (!grating_frame) {
368  cpl_msg_error(_id, "No grating data present in frame set. "
369  "Aborting ...");
370  return 1;
371  }
372 
373  slit_frame = giraffe_get_slitgeometry(set);
374 
375  if (!slit_frame) {
376  cpl_msg_error(_id, "No slit geometry present in frame set. "
377  "Aborting ...");
378  return 1;
379  }
380 
381  wcal_frame = cpl_frameset_find(set, GIFRAME_WAVELENGTH_SOLUTION);
382 
383  if (!wcal_frame) {
384  cpl_msg_error(_id, "No dispersion solution present in frame set. "
385  "Aborting ...");
386  return 1;
387  }
388 
389  atmext_frame = cpl_frameset_find(set, GIFRAME_EXTINCTION);
390 
391  if (!atmext_frame) {
392  cpl_msg_error(_id, "No atmospheric extinction table present in "
393  "frame set. Aborting ...");
394  return 1;
395  }
396 
397  flxstd_frame = cpl_frameset_find(set, GIFRAME_FLUX_STANDARDS);
398 
399  if (!flxstd_frame) {
400  cpl_msg_error(_id, "No flux standards present in frame set. "
401  "Aborting ...");
402  return 1;
403  }
404 
405  bpixel_frame = cpl_frameset_find(set, GIFRAME_BADPIXEL_MAP);
406 
407  if (!bpixel_frame) {
408  cpl_msg_info(_id, "No bad pixel map present in frame set.");
409  }
410 
411  mbias_frame = cpl_frameset_find(set, GIFRAME_BIAS_MASTER);
412 
413  if (!mbias_frame) {
414  cpl_msg_info(_id, "No master bias present in frame set.");
415  }
416 
417  mdark_frame = cpl_frameset_find(set, GIFRAME_DARK_MASTER);
418 
419  if (!mdark_frame) {
420  cpl_msg_info(_id, "No master dark present in frame set.");
421  }
422 
423  slight_frame = cpl_frameset_find(set, GIFRAME_SCATTERED_LIGHT_MODEL);
424 
425  if (!slight_frame) {
426  cpl_msg_info(_id, "No scattered light model present in frame set.");
427  }
428 
429  psfdata_frame = cpl_frameset_find(set, GIFRAME_PSF_DATA);
430 
431  if (!psfdata_frame) {
432  cpl_msg_info(_id, "No PSF profile parameters present in frame set.");
433  }
434 
435 
436  /*
437  * Load raw images
438  */
439 
440  slist = cx_slist_new();
441 
442  standard_frame = cpl_frameset_find(set, GIFRAME_STANDARD);
443 
444  for (i = 0; i < nstandard; i++) {
445 
446  filename = cpl_frame_get_filename(standard_frame);
447 
448  GiImage* raw = giraffe_image_new(CPL_TYPE_DOUBLE);
449 
450 
451  status = giraffe_image_load(raw, filename, 0);
452 
453  if (status) {
454  cpl_msg_error(_id, "Cannot load raw standard frame from '%s'. "
455  "Aborting ...", filename);
456 
457  cx_slist_destroy(slist, (cx_free_func) giraffe_image_delete);
458 
459  return 1;
460  }
461 
462  cx_slist_push_back(slist, raw);
463 
464  standard_frame = cpl_frameset_find(set, NULL);
465 
466  }
467 
468  nstandard = (cxint)cx_slist_size(slist);
469  sstandard = cx_slist_pop_front(slist);
470 
471  properties = giraffe_image_get_properties(sstandard);
472  cx_assert(properties != NULL);
473 
474  if (nstandard > 1) {
475 
476  /*
477  * Create a stacked image from the list of raw images.
478  * Each raw image is disposed when it is no longer needed.
479  */
480 
481  cpl_msg_info(_id, "Averaging standard star observations ...");
482 
483  exptime = cpl_propertylist_get_double(properties, GIALIAS_EXPTIME);
484 
485  for (i = 1; i < nstandard; i++) {
486 
487  cpl_propertylist* _properties;
488 
489  GiImage* standard = cx_slist_pop_front(slist);
490 
491 
492  cpl_image_add(giraffe_image_get(sstandard),
493  giraffe_image_get(standard));
494 
495  _properties = giraffe_image_get_properties(standard);
496  cx_assert(_properties != NULL);
497 
498  exptime += cpl_propertylist_get_double(_properties,
499  GIALIAS_EXPTIME);
500 
501  giraffe_image_delete(standard);
502 
503  }
504 
505  cpl_image_divide_scalar(giraffe_image_get(sstandard), nstandard);
506  }
507 
508  cx_assert(cx_slist_empty(slist));
509  cx_slist_delete(slist);
510  slist = NULL;
511 
512 
513  if (nstandard > 1) {
514 
515  /*
516  * Update stacked standard star image properties
517  */
518 
519  cpl_msg_info(_id, "Updating stacked standard star image "
520  "properties ...");
521 
522  cpl_propertylist_set_double(properties, GIALIAS_EXPTIME,
523  exptime / nstandard);
524 
525  cpl_propertylist_append_double(properties, GIALIAS_EXPTTOT, exptime);
526  cpl_propertylist_set_comment(properties, GIALIAS_EXPTTOT,
527  "Total exposure time of all frames "
528  "combined");
529 
530  cpl_propertylist_append_int(properties, GIALIAS_DATANCOM, nstandard);
531  cpl_propertylist_set_comment(properties, GIALIAS_DATANCOM, "Number of "
532  "frames combined");
533 
534  cpl_propertylist_erase(properties, GIALIAS_TPLEXPNO);
535 
536  }
537 
538 
539  /*
540  * Prepare for bias subtraction
541  */
542 
543  bias_config = giraffe_bias_config_create(config);
544 
545  /*
546  * Setup user defined areas to use for the bias computation
547  */
548 
549  if (bias_config->method == GIBIAS_METHOD_MASTER ||
550  bias_config->method == GIBIAS_METHOD_ZMASTER) {
551 
552  if (!mbias_frame) {
553  cpl_msg_error(_id, "Missing master bias frame! Selected bias "
554  "removal method requires a master bias frame!");
555 
556  giraffe_bias_config_destroy(bias_config);
557  giraffe_image_delete(sstandard);
558 
559  return 1;
560  }
561  else {
562  filename = cpl_frame_get_filename(mbias_frame);
563 
564 
565  mbias = giraffe_image_new(CPL_TYPE_DOUBLE);
566  status = giraffe_image_load(mbias, filename, 0);
567 
568  if (status) {
569  cpl_msg_error(_id, "Cannot load master bias from '%s'. "
570  "Aborting ...", filename);
571 
572  giraffe_bias_config_destroy(bias_config);
573  giraffe_image_delete(sstandard);
574 
575  return 1;
576  }
577  }
578  }
579 
580 
581  /*
582  * Load bad pixel map if it is present in the frame set.
583  */
584 
585  if (bpixel_frame) {
586 
587  filename = cpl_frame_get_filename(bpixel_frame);
588 
589 
590  bpixel = giraffe_image_new(CPL_TYPE_INT);
591  status = giraffe_image_load(bpixel, filename, 0);
592 
593  if (status) {
594  cpl_msg_error(_id, "Cannot load bad pixel map from '%s'. "
595  "Aborting ...", filename);
596 
597  giraffe_image_delete(bpixel);
598  bpixel = NULL;
599 
600  if (mbias != NULL) {
601  giraffe_image_delete(mbias);
602  mbias = NULL;
603  }
604 
605  giraffe_bias_config_destroy(bias_config);
606  bias_config = NULL;
607 
608  giraffe_image_delete(sstandard);
609  sstandard = NULL;
610 
611  return 1;
612  }
613 
614  }
615 
616 
617  /*
618  * Compute and remove the bias from the stacked flat field frame.
619  */
620 
621  rstandard = giraffe_image_new(CPL_TYPE_DOUBLE);
622 
623  status = giraffe_bias_remove(rstandard, sstandard, mbias, bpixel,
624  biasareas, bias_config);
625 
626  giraffe_image_delete(sstandard);
627 
628  if (mbias) {
629  giraffe_image_delete(mbias);
630  mbias = NULL;
631  }
632 
633  giraffe_bias_config_destroy(bias_config);
634 
635  if (status) {
636  cpl_msg_error(_id, "Bias removal failed. Aborting ...");
637 
638  giraffe_image_delete(rstandard);
639  rstandard = NULL;
640 
641  if (bpixel != NULL) {
642  giraffe_image_delete(bpixel);
643  bpixel = NULL;
644  }
645 
646  return 1;
647  }
648 
649 
650  /*
651  * Load master dark if it is present in the frame set and correct
652  * the master flat field for the dark current.
653  */
654 
655  if (mdark_frame) {
656 
657  GiDarkConfig dark_config = {GIDARK_METHOD_ZMASTER, 0.};
658 
659 
660  cpl_msg_info(_id, "Correcting for dark current ...");
661 
662  filename = cpl_frame_get_filename(mdark_frame);
663 
664  mdark = giraffe_image_new(CPL_TYPE_DOUBLE);
665  status = giraffe_image_load(mdark, filename, 0);
666 
667  if (status != 0) {
668  cpl_msg_error(_id, "Cannot load master dark from '%s'. "
669  "Aborting ...", filename);
670 
671  giraffe_image_delete(rstandard);
672  rstandard = NULL;
673 
674  if (bpixel != NULL) {
675  giraffe_image_delete(bpixel);
676  bpixel = NULL;
677  }
678 
679  return 1;
680  }
681 
682  status = giraffe_subtract_dark(rstandard, mdark, bpixel, NULL,
683  &dark_config);
684 
685  if (status != 0) {
686  cpl_msg_error(_id, "Dark subtraction failed! Aborting ...");
687 
688  giraffe_image_delete(mdark);
689  mdark = NULL;
690 
691  giraffe_image_delete(rstandard);
692  rstandard = NULL;
693 
694  if (bpixel != NULL) {
695  giraffe_image_delete(bpixel);
696  bpixel = NULL;
697  }
698 
699  return 1;
700  }
701 
702  giraffe_image_delete(mdark);
703  mdark = NULL;
704 
705  }
706 
707 
708  /*
709  * Update the reduced standard star observation properties, save the
710  * reduced standard star frame and register it as product.
711  */
712 
713  cpl_msg_info(_id, "Writing pre-processed standard star image ...");
714 
715  giraffe_image_add_info(rstandard, &info, set);
716 
717  rstandard_frame = giraffe_frame_create_image(rstandard,
718  GIFRAME_STANDARD_REDUCED,
719  CPL_FRAME_LEVEL_INTERMEDIATE,
720  TRUE, TRUE);
721 
722  if (rstandard_frame == NULL) {
723  cpl_msg_error(_id, "Cannot create local file! Aborting ...");
724 
725  giraffe_image_delete(rstandard);
726 
727  return 1;
728  }
729 
730  cpl_frameset_insert(set, rstandard_frame);
731 
732 
733  /*
734  * Determine fiber setup
735  */
736 
737  standard_frame = cpl_frameset_find(set, GIFRAME_STANDARD);
738 
739  cpl_msg_info(_id, "Building fiber setup for frame '%s'.",
740  cpl_frame_get_filename(standard_frame));
741 
742  fibers = giraffe_fibers_setup(standard_frame, locy_frame);
743 
744  if (!fibers) {
745  cpl_msg_error(_id, "Cannot create fiber setup for frame '%s'! "
746  "Aborting ...", cpl_frame_get_filename(standard_frame));
747 
748  if (bpixel) {
749  giraffe_image_delete(bpixel);
750  bpixel = NULL;
751  }
752 
753  giraffe_image_delete(rstandard);
754 
755  return 1;
756  }
757 
758  cpl_msg_info(_id, "Fiber reference setup taken from localization "
759  "frame '%s'.", cpl_frame_get_filename(locy_frame));
760 
761 
762  /*
763  * Load fiber localization
764  */
765 
766  localization = giraffe_localization_new();
767 
768  filename = cpl_frame_get_filename(locy_frame);
769  status = 0;
770 
771  localization->locy = giraffe_image_new(CPL_TYPE_DOUBLE);
772  status = giraffe_image_load(localization->locy, filename, 0);
773 
774  if (status) {
775  cpl_msg_error(_id, "Cannot load localization (centroid "
776  "position) frame from '%s'. Aborting ...",
777  filename);
778 
779  giraffe_localization_destroy(localization);
780 
781  if (bpixel) {
782  giraffe_image_delete(bpixel);
783  bpixel = NULL;
784  }
785 
786  giraffe_table_delete(fibers);
787  giraffe_image_delete(rstandard);
788 
789  return 1;
790  }
791 
792 
793  filename = cpl_frame_get_filename(locw_frame);
794  status = 0;
795 
796  localization->locw = giraffe_image_new(CPL_TYPE_DOUBLE);
797  status = giraffe_image_load(localization->locw, filename, 0);
798 
799  if (status) {
800  cpl_msg_error(_id, "Cannot load localization (spectrum width) "
801  "frame from '%s'. Aborting ...", filename);
802 
803  giraffe_localization_destroy(localization);
804 
805  if (bpixel) {
806  giraffe_image_delete(bpixel);
807  bpixel = NULL;
808  }
809 
810  giraffe_table_delete(fibers);
811  giraffe_image_delete(rstandard);
812 
813  return 1;
814  }
815 
816 
817  /*
818  * Spectrum extraction
819  */
820 
821  if (slight_frame) {
822 
823  filename = cpl_frame_get_filename(slight_frame);
824 
825 
826  slight = giraffe_image_new(CPL_TYPE_DOUBLE);
827  status = giraffe_image_load(slight, filename, 0);
828 
829  if (status) {
830  cpl_msg_error(_id, "Cannot load scattered light model from '%s'. "
831  "Aborting ...", filename);
832 
833  giraffe_image_delete(slight);
834 
835  giraffe_localization_destroy(localization);
836 
837  if (bpixel) {
838  giraffe_image_delete(bpixel);
839  bpixel = NULL;
840  }
841 
842  giraffe_table_delete(fibers);
843  giraffe_image_delete(rstandard);
844 
845  return 1;
846 
847  }
848 
849  }
850 
851 
852  extract_config = giraffe_extract_config_create(config);
853 
854  if ((extract_config->emethod == GIEXTRACT_OPTIMAL) ||
855  (extract_config->emethod == GIEXTRACT_HORNE)) {
856 
857  if (psfdata_frame == NULL) {
858 
859  const cxchar* emethod = "Optimal";
860 
861  if (extract_config->emethod == GIEXTRACT_HORNE) {
862  emethod = "Horne";
863  }
864 
865  cpl_msg_error(_id, "%s spectrum extraction requires PSF "
866  "profile data. Aborting ...", emethod);
867 
868  giraffe_extract_config_destroy(extract_config);
869  extract_config = NULL;
870 
871  if (slight != NULL) {
872  giraffe_image_delete(slight);
873  slight = NULL;
874  }
875 
876  giraffe_localization_destroy(localization);
877  localization = NULL;
878 
879  if (bpixel) {
880  giraffe_image_delete(bpixel);
881  bpixel = NULL;
882  }
883 
884  giraffe_table_delete(fibers);
885  fibers = NULL;
886 
887  giraffe_image_delete(rstandard);
888  rstandard = NULL;
889 
890  return 1;
891 
892  }
893  else {
894 
895  filename = cpl_frame_get_filename(psfdata_frame);
896  status = 0;
897 
898  localization->psf = giraffe_psfdata_new();
899  status = giraffe_psfdata_load(localization->psf, filename);
900 
901  if (status) {
902  cpl_msg_error(_id, "Cannot load PSF profile data frame from "
903  "'%s'. Aborting ...", filename);
904 
905  giraffe_extract_config_destroy(extract_config);
906  extract_config = NULL;
907 
908  if (slight != NULL) {
909  giraffe_image_delete(slight);
910  slight = NULL;
911  }
912 
913  giraffe_localization_destroy(localization);
914  localization = NULL;
915 
916  if (bpixel) {
917  giraffe_image_delete(bpixel);
918  bpixel = NULL;
919  }
920 
921  giraffe_table_delete(fibers);
922  fibers = NULL;
923 
924  giraffe_image_delete(rstandard);
925  rstandard = NULL;
926 
927  return 1;
928 
929  }
930 
931  }
932 
933  }
934 
935 
936  extraction = giraffe_extraction_new();
937 
938  status = giraffe_extract_spectra(extraction, rstandard, fibers,
939  localization, bpixel, slight,
940  extract_config);
941 
942  if (status) {
943  cpl_msg_error(_id, "Spectrum extraction failed! Aborting ...");
944 
945  giraffe_extraction_destroy(extraction);
946  giraffe_extract_config_destroy(extract_config);
947 
948  giraffe_image_delete(slight);
949 
950  giraffe_localization_destroy(localization);
951 
952  if (bpixel) {
953  giraffe_image_delete(bpixel);
954  bpixel = NULL;
955  }
956 
957  giraffe_table_delete(fibers);
958  giraffe_image_delete(rstandard);
959 
960  return 1;
961  }
962 
963  giraffe_image_delete(slight);
964  slight = NULL;
965 
966  if (bpixel) {
967  giraffe_image_delete(bpixel);
968  bpixel = NULL;
969  }
970 
971  giraffe_image_delete(rstandard);
972  rstandard = NULL;
973 
974  giraffe_extract_config_destroy(extract_config);
975 
976 
977  /*
978  * Get the relative fiber transmission data from the extracted flat
979  * field and add it to the fiber table.
980  */
981 
982  filename = cpl_frame_get_filename(flat_frame);
983 
984  cpl_msg_info(_id, "Loading relative fiber transmission data from '%s'.",
985  filename);
986 
987  status = giraffe_transmission_attach(fibers, filename);
988 
989  if (status != 0) {
990 
991  giraffe_extraction_destroy(extraction);
992  giraffe_localization_destroy(localization);
993 
994  giraffe_table_delete(grating);
995  giraffe_table_delete(fibers);
996 
997  cpl_msg_error(_id, "Cannot load relative fiber transmission data "
998  "from '%s'. Aborting ...", filename);
999 
1000  return 1;
1001 
1002  }
1003 
1004 
1005  /*
1006  * Apply flat field and/or the relative fiber transmission correction.
1007  */
1008 
1009  flat_config = giraffe_flat_config_create(config);
1010 
1011  if (flat_config->apply == TRUE) {
1012 
1013  const cpl_frame* flat_errors_frame = NULL;
1014 
1015  GiImage* flat = NULL;
1016  GiImage* errors = NULL;
1017 
1018 
1019  filename = cpl_frame_get_filename(flat_frame);
1020 
1021  flat = giraffe_image_new(CPL_TYPE_DOUBLE);
1022  status = giraffe_image_load(flat, filename, 0);
1023 
1024  if (status) {
1025  cpl_msg_error(_id, "Cannot load flat field spectra from '%s'. "
1026  "Aborting ...", filename);
1027 
1028  giraffe_image_delete(flat);
1029 
1030  giraffe_flat_config_destroy(flat_config);
1031 
1032  giraffe_extraction_destroy(extraction);
1033  giraffe_localization_destroy(localization);
1034 
1035  giraffe_table_delete(grating);
1036  giraffe_table_delete(fibers);
1037 
1038  return 1;
1039  }
1040 
1041 
1042  flat_errors_frame =
1043  cpl_frameset_find(set, GIFRAME_FIBER_FLAT_EXTERRORS);
1044 
1045  if (flat_errors_frame == NULL) {
1046  cpl_msg_warning(_id, "Missing flat field spectra errors "
1047  "frame!");
1048  }
1049  else {
1050 
1051  filename = cpl_frame_get_filename(flat_errors_frame);
1052 
1053  errors = giraffe_image_new(CPL_TYPE_DOUBLE);
1054  status = giraffe_image_load(errors, filename, 0);
1055 
1056  if (status) {
1057  cpl_msg_error(_id, "Cannot load flat field spectra "
1058  "errors from '%s'. Aborting ...",
1059  filename);
1060 
1061  giraffe_image_delete(errors);
1062  giraffe_image_delete(flat);
1063 
1064  giraffe_flat_config_destroy(flat_config);
1065 
1066  giraffe_extraction_destroy(extraction);
1067  giraffe_localization_destroy(localization);
1068 
1069  giraffe_table_delete(grating);
1070  giraffe_table_delete(fibers);
1071 
1072  return 1;
1073  }
1074 
1075  }
1076 
1077  cpl_msg_info(_id, "Applying flat field correction ...");
1078 
1079  status = giraffe_flat_apply(extraction, fibers, flat, errors,
1080  flat_config);
1081 
1082  if (status) {
1083  cpl_msg_error(_id, "Flat field correction failed! "
1084  "Aborting ...");
1085 
1086  giraffe_image_delete(errors);
1087  giraffe_image_delete(flat);
1088 
1089  giraffe_flat_config_destroy(flat_config);
1090 
1091  giraffe_extraction_destroy(extraction);
1092  giraffe_localization_destroy(localization);
1093 
1094  giraffe_table_delete(grating);
1095  giraffe_table_delete(fibers);
1096 
1097  return 1;
1098  }
1099 
1100  giraffe_image_delete(errors);
1101  errors = NULL;
1102 
1103  giraffe_image_delete(flat);
1104  flat = NULL;
1105 
1106  }
1107 
1108  if (flat_config->transmission == TRUE) {
1109 
1110  cpl_msg_info(_id, "Applying relative fiber transmission "
1111  "correction");
1112 
1113  status = giraffe_transmission_apply(extraction, fibers);
1114 
1115  if (status) {
1116 
1117  cpl_msg_error(_id, "Relative transmission correction failed! "
1118  "Aborting ...");
1119 
1120  giraffe_flat_config_destroy(flat_config);
1121  flat_config = NULL;
1122 
1123  giraffe_extraction_destroy(extraction);
1124  giraffe_localization_destroy(localization);
1125 
1126  giraffe_table_delete(grating);
1127  giraffe_table_delete(fibers);
1128 
1129  return 1;
1130 
1131  }
1132 
1133  }
1134 
1135  giraffe_flat_config_destroy(flat_config);
1136  flat_config = NULL;
1137 
1138 
1139  /*
1140  * Save the spectrum extraction results and register them as
1141  * products.
1142  */
1143 
1144  cpl_msg_info(_id, "Writing extracted spectra ...");
1145 
1146  /* Extracted spectra */
1147 
1148  giraffe_image_add_info(extraction->spectra, &info, set);
1149 
1150  sext_frame = giraffe_frame_create_image(extraction->spectra,
1151  GIFRAME_STANDARD_EXTSPECTRA,
1152  CPL_FRAME_LEVEL_FINAL,
1153  TRUE, TRUE);
1154 
1155  if (sext_frame == NULL) {
1156  cpl_msg_error(_id, "Cannot create local file! Aborting ...");
1157 
1158  giraffe_extraction_destroy(extraction);
1159  giraffe_localization_destroy(localization);
1160 
1161  giraffe_table_delete(grating);
1162  giraffe_table_delete(fibers);
1163 
1164  return 1;
1165  }
1166 
1167  status = giraffe_fiberlist_attach(sext_frame, fibers);
1168 
1169  if (status) {
1170  cpl_msg_error(_id, "Cannot attach fiber setup to local file '%s'! "
1171  "Aborting ...", cpl_frame_get_filename(sext_frame));
1172 
1173  cpl_frame_delete(sext_frame);
1174 
1175  giraffe_extraction_destroy(extraction);
1176  giraffe_localization_destroy(localization);
1177 
1178  giraffe_table_delete(grating);
1179  giraffe_table_delete(fibers);
1180 
1181  return 1;
1182  }
1183 
1184  cpl_frameset_insert(set, sext_frame);
1185 
1186  /* Extracted spectra errors */
1187 
1188  giraffe_image_add_info(extraction->error, &info, set);
1189 
1190  sext_frame = giraffe_frame_create_image(extraction->error,
1191  GIFRAME_STANDARD_EXTERRORS,
1192  CPL_FRAME_LEVEL_FINAL,
1193  TRUE, TRUE);
1194 
1195  if (sext_frame == NULL) {
1196  cpl_msg_error(_id, "Cannot create local file! Aborting ...");
1197 
1198  giraffe_extraction_destroy(extraction);
1199  giraffe_localization_destroy(localization);
1200 
1201  giraffe_table_delete(grating);
1202  giraffe_table_delete(fibers);
1203 
1204  return 1;
1205  }
1206 
1207  status = giraffe_fiberlist_attach(sext_frame, fibers);
1208 
1209  if (status) {
1210  cpl_msg_error(_id, "Cannot attach fiber setup to local file '%s'! "
1211  "Aborting ...", cpl_frame_get_filename(sext_frame));
1212 
1213  cpl_frame_delete(sext_frame);
1214 
1215  giraffe_extraction_destroy(extraction);
1216  giraffe_localization_destroy(localization);
1217 
1218  giraffe_table_delete(grating);
1219  giraffe_table_delete(fibers);
1220 
1221  return 1;
1222  }
1223 
1224  cpl_frameset_insert(set, sext_frame);
1225 
1226  /* Extracted spectra pixels */
1227 
1228  if (extraction->npixels != NULL) {
1229 
1230  giraffe_image_add_info(extraction->npixels, &info, set);
1231 
1232  sext_frame = giraffe_frame_create_image(extraction->npixels,
1233  GIFRAME_STANDARD_EXTPIXELS,
1234  CPL_FRAME_LEVEL_FINAL,
1235  TRUE, TRUE);
1236 
1237  if (sext_frame == NULL) {
1238  cpl_msg_error(_id, "Cannot create local file! Aborting ...");
1239 
1240  giraffe_extraction_destroy(extraction);
1241  giraffe_localization_destroy(localization);
1242 
1243  giraffe_table_delete(grating);
1244  giraffe_table_delete(fibers);
1245 
1246  return 1;
1247  }
1248 
1249  status = giraffe_fiberlist_attach(sext_frame, fibers);
1250 
1251  if (status) {
1252  cpl_msg_error(_id, "Cannot attach fiber setup to local file "
1253  "'%s'! Aborting ...",
1254  cpl_frame_get_filename(sext_frame));
1255 
1256  cpl_frame_delete(sext_frame);
1257 
1258  giraffe_extraction_destroy(extraction);
1259  giraffe_localization_destroy(localization);
1260 
1261  giraffe_table_delete(grating);
1262  giraffe_table_delete(fibers);
1263 
1264  return 1;
1265  }
1266 
1267  cpl_frameset_insert(set, sext_frame);
1268 
1269  }
1270 
1271  /* Extracted spectra centroids */
1272 
1273  giraffe_image_add_info(extraction->centroid, &info, set);
1274 
1275  sext_frame = giraffe_frame_create_image(extraction->centroid,
1276  GIFRAME_STANDARD_EXTTRACE,
1277  CPL_FRAME_LEVEL_FINAL,
1278  TRUE, TRUE);
1279 
1280  if (sext_frame == NULL) {
1281  cpl_msg_error(_id, "Cannot create local file! Aborting ...");
1282 
1283  giraffe_extraction_destroy(extraction);
1284  giraffe_localization_destroy(localization);
1285 
1286  giraffe_table_delete(grating);
1287  giraffe_table_delete(fibers);
1288 
1289  return 1;
1290  }
1291 
1292  status = giraffe_fiberlist_attach(sext_frame, fibers);
1293 
1294  if (status) {
1295  cpl_msg_error(_id, "Cannot attach fiber setup to local file '%s'! "
1296  "Aborting ...", cpl_frame_get_filename(sext_frame));
1297 
1298  cpl_frame_delete(sext_frame);
1299 
1300  giraffe_extraction_destroy(extraction);
1301  giraffe_localization_destroy(localization);
1302 
1303  giraffe_table_delete(grating);
1304  giraffe_table_delete(fibers);
1305 
1306  return 1;
1307  }
1308 
1309  cpl_frameset_insert(set, sext_frame);
1310 
1311  /* Extraction model spectra */
1312 
1313  if (extraction->model != NULL) {
1314 
1315  giraffe_image_add_info(extraction->model, &info, set);
1316 
1317  sext_frame = giraffe_frame_create_image(extraction->model,
1318  GIFRAME_STANDARD_EXTMODEL,
1319  CPL_FRAME_LEVEL_FINAL,
1320  TRUE, TRUE);
1321 
1322  if (sext_frame == NULL) {
1323  cpl_msg_error(_id, "Cannot create local file! Aborting ...");
1324 
1325  giraffe_extraction_destroy(extraction);
1326  giraffe_localization_destroy(localization);
1327 
1328  giraffe_table_delete(grating);
1329  giraffe_table_delete(fibers);
1330 
1331  return 1;
1332  }
1333 
1334  status = giraffe_fiberlist_attach(sext_frame, fibers);
1335 
1336  if (status != 0) {
1337  cpl_msg_error(_id, "Cannot attach fiber setup to local file '%s'! "
1338  "Aborting ...", cpl_frame_get_filename(sext_frame));
1339 
1340  cpl_frame_delete(sext_frame);
1341 
1342  giraffe_extraction_destroy(extraction);
1343  giraffe_localization_destroy(localization);
1344 
1345  giraffe_table_delete(grating);
1346  giraffe_table_delete(fibers);
1347 
1348  return 1;
1349  }
1350 
1351  cpl_frameset_insert(set, sext_frame);
1352 
1353  }
1354 
1355 
1356  /*
1357  * Load dispersion solution
1358  */
1359 
1360 
1361  filename = (cxchar *)cpl_frame_get_filename(wcal_frame);
1362 
1363  wcalcoeff = giraffe_table_new();
1364  status = giraffe_table_load(wcalcoeff, filename, 1, NULL);
1365 
1366  if (status) {
1367  cpl_msg_error(_id, "Cannot load dispersion solution from "
1368  "'%s'. Aborting ...", filename);
1369 
1370  giraffe_extraction_destroy(extraction);
1371  giraffe_localization_destroy(localization);
1372 
1373  giraffe_table_delete(wcalcoeff);
1374 
1375  giraffe_table_delete(grating);
1376  giraffe_table_delete(fibers);
1377 
1378  return 1;
1379  }
1380 
1381 
1382  /*
1383  * Load grating data
1384  */
1385 
1386  filename = (cxchar *)cpl_frame_get_filename(grating_frame);
1387 
1388  status = 0;
1389 
1390  grating = giraffe_table_new();
1391  status = giraffe_table_load(grating, filename, 1, NULL);
1392 
1393  if (status) {
1394  cpl_msg_error(_id, "Cannot load grating data from '%s'. "
1395  "Aborting ...", filename);
1396 
1397  giraffe_extraction_destroy(extraction);
1398  giraffe_localization_destroy(localization);
1399 
1400  giraffe_table_delete(wcalcoeff);
1401 
1402  giraffe_table_delete(grating);
1403  giraffe_table_delete(fibers);
1404 
1405  return 1;
1406  }
1407 
1408 
1409  /*
1410  * Load slit geometry data
1411  */
1412 
1413 
1414  filename = (cxchar *)cpl_frame_get_filename(slit_frame);
1415 
1416  slitgeometry = giraffe_slitgeometry_load(fibers, filename, 1, NULL);
1417 
1418  if (slitgeometry == NULL) {
1419  cpl_msg_error(_id, "Cannot load slit geometry data from '%s'. "
1420  "Aborting ...", filename);
1421 
1422  giraffe_table_delete(wcalcoeff);
1423 
1424  giraffe_extraction_destroy(extraction);
1425  giraffe_localization_destroy(localization);
1426 
1427  giraffe_table_delete(wcalcoeff);
1428 
1429  giraffe_table_delete(grating);
1430  giraffe_table_delete(fibers);
1431 
1432  return 1;
1433  }
1434  else {
1435 
1436  /*
1437  * Check whether the contains the positions for all fibers
1438  * provided by the fiber setup. If this is not the case
1439  * this is an error.
1440  */
1441 
1442  if (giraffe_fiberlist_compare(slitgeometry, fibers) != 1) {
1443  cpl_msg_error(_id, "Slit geometry data from '%s' is not "
1444  "applicable for current fiber setup! "
1445  "Aborting ...", filename);
1446 
1447  giraffe_table_delete(slitgeometry);
1448  giraffe_table_delete(wcalcoeff);
1449 
1450  giraffe_extraction_destroy(extraction);
1451  giraffe_localization_destroy(localization);
1452 
1453  giraffe_table_delete(wcalcoeff);
1454 
1455  giraffe_table_delete(grating);
1456  giraffe_table_delete(fibers);
1457 
1458  return 1;
1459  }
1460 
1461  }
1462 
1463 
1464  /*
1465  * Spectrum rebinning
1466  */
1467 
1468  cpl_msg_info(_id, "Spectrum rebinning");
1469 
1470  rebin_config = giraffe_rebin_config_create(config);
1471 
1472  rebinning = giraffe_rebinning_new();
1473 
1474  status = 0;
1475 
1476  status = giraffe_rebin_spectra(rebinning, extraction, fibers,
1477  localization, grating, slitgeometry,
1478  wcalcoeff, rebin_config);
1479 
1480  if (status) {
1481  cpl_msg_error(_id, "Rebinning of standard spectra failed! "
1482  "Aborting...");
1483 
1484  giraffe_rebinning_destroy(rebinning);
1485 
1486  giraffe_extraction_destroy(extraction);
1487  giraffe_localization_destroy(localization);
1488 
1489  giraffe_table_delete(wcalcoeff);
1490 
1491  giraffe_table_delete(slitgeometry);
1492  giraffe_table_delete(grating);
1493  giraffe_table_delete(fibers);
1494 
1495  giraffe_rebin_config_destroy(rebin_config);
1496 
1497  return 1;
1498 
1499  }
1500 
1501  giraffe_extraction_destroy(extraction);
1502  extraction = NULL;
1503 
1504  giraffe_localization_destroy(localization);
1505  localization = NULL;
1506 
1507  giraffe_rebin_config_destroy(rebin_config);
1508  rebin_config = NULL;
1509 
1510 
1511  /*
1512  * Save and register the results of the spectrum rebinning.
1513  */
1514 
1515  /* Rebinned spectra */
1516 
1517  giraffe_image_add_info(rebinning->spectra, &info, set);
1518 
1519  rbin_frame = giraffe_frame_create_image(rebinning->spectra,
1520  GIFRAME_STANDARD_RBNSPECTRA,
1521  CPL_FRAME_LEVEL_FINAL,
1522  TRUE, TRUE);
1523 
1524  if (rbin_frame == NULL) {
1525  cpl_msg_error(_id, "Cannot create local file! Aborting ...");
1526 
1527  giraffe_rebinning_destroy(rebinning);
1528 
1529  giraffe_table_delete(wcalcoeff);
1530 
1531  giraffe_table_delete(slitgeometry);
1532  giraffe_table_delete(grating);
1533  giraffe_table_delete(fibers);
1534 
1535  return 1;
1536  }
1537 
1538  status = giraffe_fiberlist_attach(rbin_frame, fibers);
1539 
1540  if (status) {
1541  cpl_msg_error(_id, "Cannot attach fiber setup to local "
1542  "file '%s'! Aborting ...",
1543  cpl_frame_get_filename(rbin_frame));
1544 
1545  giraffe_rebinning_destroy(rebinning);
1546  giraffe_table_delete(wcalcoeff);
1547 
1548  giraffe_table_delete(slitgeometry);
1549  giraffe_table_delete(grating);
1550  giraffe_table_delete(fibers);
1551 
1552  cpl_frame_delete(rbin_frame);
1553 
1554  return 1;
1555  }
1556 
1557  cpl_frameset_insert(set, rbin_frame);
1558 
1559  /* Rebinned spectra errors */
1560 
1561  giraffe_image_add_info(rebinning->errors, &info, set);
1562 
1563  rbin_frame = giraffe_frame_create_image(rebinning->errors,
1564  GIFRAME_STANDARD_RBNERRORS,
1565  CPL_FRAME_LEVEL_FINAL,
1566  TRUE, TRUE);
1567 
1568  if (rbin_frame == NULL) {
1569  cpl_msg_error(_id, "Cannot create local file! Aborting ...");
1570 
1571  giraffe_rebinning_destroy(rebinning);
1572 
1573  giraffe_table_delete(wcalcoeff);
1574 
1575  giraffe_table_delete(slitgeometry);
1576  giraffe_table_delete(grating);
1577  giraffe_table_delete(fibers);
1578 
1579  return 1;
1580  }
1581 
1582  status = giraffe_fiberlist_attach(rbin_frame, fibers);
1583 
1584  if (status) {
1585  cpl_msg_error(_id, "Cannot attach fiber setup to local "
1586  "file '%s'! Aborting ...",
1587  cpl_frame_get_filename(rbin_frame));
1588 
1589  giraffe_rebinning_destroy(rebinning);
1590 
1591  giraffe_table_delete(wcalcoeff);
1592 
1593  giraffe_table_delete(slitgeometry);
1594  giraffe_table_delete(grating);
1595  giraffe_table_delete(fibers);
1596 
1597  cpl_frame_delete(rbin_frame);
1598 
1599  return 1;
1600  }
1601 
1602  cpl_frameset_insert(set, rbin_frame);
1603 
1604 
1605  /*
1606  * Optional image and data cube construction (only for IFU and Argus)
1607  */
1608 
1609  properties = giraffe_image_get_properties(rebinning->spectra);
1610  mode = giraffe_get_mode(properties);
1611 
1612 
1613  if (mode == GIMODE_IFU || mode == GIMODE_ARGUS) {
1614 
1615  cpl_frame* rimg_frame = NULL;
1616 
1617  GiFieldOfView* fov = NULL;
1618 
1619  GiFieldOfViewConfig* fov_config = NULL;
1620 
1621  GiFieldOfViewCubeFormat cube_format = GIFOV_FORMAT_ESO3D;
1622 
1623 
1624  fov_config = giraffe_fov_config_create(config);
1625 
1626  cube_format = fov_config->format;
1627 
1628 
1629  cpl_msg_info(_id, "Reconstructing image and data cube from rebinned "
1630  "spectra ...");
1631 
1632  fov = giraffe_fov_new();
1633 
1634  status = giraffe_fov_build(fov, rebinning, fibers, wcalcoeff, grating,
1635  slitgeometry, fov_config);
1636 
1637  if (status) {
1638 
1639  if (status == -2) {
1640  cpl_msg_warning(_id, "No reconstructed image was built. "
1641  "Fiber list has no fiber position "
1642  "information.");
1643  }
1644  else {
1645  cpl_msg_error(_id, "Image reconstruction failed! Aborting...");
1646 
1647  giraffe_fov_delete(fov);
1648  giraffe_rebinning_destroy(rebinning);
1649 
1650  giraffe_table_delete(wcalcoeff);
1651 
1652  giraffe_table_delete(slitgeometry);
1653  giraffe_table_delete(grating);
1654  giraffe_table_delete(fibers);
1655 
1656  giraffe_fov_config_destroy(fov_config);
1657 
1658  return 1;
1659  }
1660 
1661  }
1662 
1663  giraffe_fov_config_destroy(fov_config);
1664 
1665 
1666  /*
1667  * Save and register the results of the image reconstruction.
1668  */
1669 
1670  /* Reconstructed image */
1671 
1672  giraffe_image_add_info(fov->fov.spectra, &info, set);
1673 
1674  rimg_frame = giraffe_frame_create_image(fov->fov.spectra,
1675  GIFRAME_STANDARD_RCSPECTRA,
1676  CPL_FRAME_LEVEL_FINAL,
1677  TRUE, TRUE);
1678 
1679  if (rimg_frame == NULL) {
1680  cpl_msg_error(_id, "Cannot create local file! Aborting ...");
1681 
1682  giraffe_fov_delete(fov);
1683  giraffe_rebinning_destroy(rebinning);
1684 
1685  giraffe_table_delete(wcalcoeff);
1686 
1687  giraffe_table_delete(slitgeometry);
1688  giraffe_table_delete(grating);
1689  giraffe_table_delete(fibers);
1690 
1691  return 1;
1692  }
1693 
1694  cpl_frameset_insert(set, rimg_frame);
1695 
1696 
1697  /* Reconstructed image errors */
1698 
1699  giraffe_image_add_info(fov->fov.errors, &info, set);
1700 
1701  rimg_frame = giraffe_frame_create_image(fov->fov.errors,
1702  GIFRAME_STANDARD_RCERRORS,
1703  CPL_FRAME_LEVEL_FINAL,
1704  TRUE, TRUE);
1705 
1706  if (rimg_frame == NULL) {
1707  cpl_msg_error(_id, "Cannot create local file! Aborting ...");
1708 
1709  giraffe_fov_delete(fov);
1710  giraffe_rebinning_destroy(rebinning);
1711 
1712  giraffe_table_delete(wcalcoeff);
1713 
1714  giraffe_table_delete(slitgeometry);
1715  giraffe_table_delete(grating);
1716  giraffe_table_delete(fibers);
1717 
1718  return 1;
1719  }
1720 
1721  cpl_frameset_insert(set, rimg_frame);
1722 
1723 
1724  /* Save data cubes according to format selection */
1725 
1726  if (cube_format == GIFOV_FORMAT_SINGLE) {
1727 
1728  /* Spectrum cube */
1729 
1730  if (fov->cubes.spectra != NULL) {
1731 
1732  cxint component = 0;
1733 
1734  GiFrameCreator creator = (GiFrameCreator) giraffe_fov_save_cubes;
1735 
1736 
1737  properties = giraffe_image_get_properties(rebinning->spectra);
1738  properties = cpl_propertylist_duplicate(properties);
1739 
1740  giraffe_add_frameset_info(properties, set, info.sequence);
1741 
1742  rimg_frame = giraffe_frame_create(GIFRAME_STANDARD_CUBE_SPECTRA,
1743  CPL_FRAME_LEVEL_FINAL,
1744  properties,
1745  fov,
1746  &component,
1747  creator);
1748 
1749  cpl_propertylist_delete(properties);
1750  properties = NULL;
1751 
1752  if (rimg_frame == NULL) {
1753  cpl_msg_error(_id, "Cannot create local file! Aborting ...");
1754 
1755  giraffe_fov_delete(fov);
1756  fov = NULL;
1757 
1758  giraffe_rebinning_destroy(rebinning);
1759  rebinning = NULL;
1760 
1761  giraffe_table_delete(wcalcoeff);
1762  wcalcoeff = NULL;
1763 
1764  giraffe_table_delete(slitgeometry);
1765  slitgeometry = NULL;
1766 
1767  giraffe_table_delete(grating);
1768  grating = NULL;
1769 
1770  giraffe_table_delete(fibers);
1771  fibers = NULL;
1772 
1773  return 1;
1774  }
1775 
1776  status = giraffe_fiberlist_attach(rimg_frame, fibers);
1777 
1778  if (status != 0) {
1779  cpl_msg_error(_id, "Cannot attach fiber setup to local "
1780  "file '%s'! Aborting ...",
1781  cpl_frame_get_filename(rimg_frame));
1782 
1783  cpl_frame_delete(rimg_frame);
1784 
1785  giraffe_fov_delete(fov);
1786  fov = NULL;
1787 
1788  giraffe_rebinning_destroy(rebinning);
1789  rebinning = NULL;
1790 
1791  giraffe_table_delete(wcalcoeff);
1792  wcalcoeff = NULL;
1793 
1794  giraffe_table_delete(slitgeometry);
1795  slitgeometry = NULL;
1796 
1797  giraffe_table_delete(grating);
1798  grating = NULL;
1799 
1800  giraffe_table_delete(fibers);
1801  fibers = NULL;
1802 
1803  return 1;
1804  }
1805 
1806  cpl_frameset_insert(set, rimg_frame);
1807 
1808  }
1809 
1810  /* Error cube */
1811 
1812  if (fov->cubes.errors != NULL) {
1813 
1814  cxint component = 1;
1815 
1816  GiFrameCreator creator = (GiFrameCreator) giraffe_fov_save_cubes;
1817 
1818 
1819  properties = giraffe_image_get_properties(rebinning->errors);
1820  properties = cpl_propertylist_duplicate(properties);
1821 
1822  giraffe_add_frameset_info(properties, set, info.sequence);
1823 
1824  rimg_frame = giraffe_frame_create(GIFRAME_STANDARD_CUBE_ERRORS,
1825  CPL_FRAME_LEVEL_FINAL,
1826  properties,
1827  fov,
1828  &component,
1829  creator);
1830 
1831  cpl_propertylist_delete(properties);
1832  properties = NULL;
1833 
1834  if (rimg_frame == NULL) {
1835  cpl_msg_error(_id, "Cannot create local file! Aborting ...");
1836 
1837  giraffe_fov_delete(fov);
1838  fov = NULL;
1839 
1840  giraffe_rebinning_destroy(rebinning);
1841  rebinning = NULL;
1842 
1843  giraffe_table_delete(wcalcoeff);
1844  wcalcoeff = NULL;
1845 
1846  giraffe_table_delete(slitgeometry);
1847  slitgeometry = NULL;
1848 
1849  giraffe_table_delete(grating);
1850  grating = NULL;
1851 
1852  giraffe_table_delete(fibers);
1853  fibers = NULL;
1854 
1855  return 1;
1856  }
1857 
1858  status = giraffe_fiberlist_attach(rimg_frame, fibers);
1859 
1860  if (status != 0) {
1861  cpl_msg_error(_id, "Cannot attach fiber setup to local "
1862  "file '%s'! Aborting ...",
1863  cpl_frame_get_filename(rimg_frame));
1864 
1865  cpl_frame_delete(rimg_frame);
1866 
1867  giraffe_fov_delete(fov);
1868  fov = NULL;
1869 
1870  giraffe_rebinning_destroy(rebinning);
1871  rebinning = NULL;
1872 
1873  giraffe_table_delete(wcalcoeff);
1874  wcalcoeff = NULL;
1875 
1876  giraffe_table_delete(slitgeometry);
1877  slitgeometry = NULL;
1878 
1879  giraffe_table_delete(grating);
1880  grating = NULL;
1881 
1882  giraffe_table_delete(fibers);
1883  fibers = NULL;
1884 
1885  return 1;
1886  }
1887 
1888  cpl_frameset_insert(set, rimg_frame);
1889  }
1890 
1891  }
1892  else {
1893 
1894  /* Data Cube (ESO 3D format) */
1895 
1896  GiFrameCreator creator = (GiFrameCreator) giraffe_fov_save_cubes_eso3d;
1897 
1898  properties = giraffe_image_get_properties(rebinning->spectra);
1899  properties = cpl_propertylist_duplicate(properties);
1900 
1901  giraffe_add_frameset_info(properties, set, info.sequence);
1902 
1903  rimg_frame = giraffe_frame_create(GIFRAME_STANDARD_CUBE,
1904  CPL_FRAME_LEVEL_FINAL,
1905  properties,
1906  fov,
1907  NULL,
1908  creator);
1909 
1910  cpl_propertylist_delete(properties);
1911  properties = NULL;
1912 
1913  if (rimg_frame == NULL) {
1914  cpl_msg_error(_id, "Cannot create local file! Aborting ...");
1915 
1916  giraffe_fov_delete(fov);
1917  fov = NULL;
1918 
1919  giraffe_rebinning_destroy(rebinning);
1920  rebinning = NULL;
1921 
1922  giraffe_table_delete(wcalcoeff);
1923  wcalcoeff = NULL;
1924 
1925  giraffe_table_delete(slitgeometry);
1926  slitgeometry = NULL;
1927 
1928  giraffe_table_delete(grating);
1929  grating = NULL;
1930 
1931  giraffe_table_delete(fibers);
1932  fibers = NULL;
1933 
1934  return 1;
1935  }
1936 
1937  status = giraffe_fiberlist_attach(rimg_frame, fibers);
1938 
1939  if (status != 0) {
1940  cpl_msg_error(_id, "Cannot attach fiber setup to local "
1941  "file '%s'! Aborting ...",
1942  cpl_frame_get_filename(rimg_frame));
1943 
1944  cpl_frame_delete(rimg_frame);
1945 
1946  giraffe_fov_delete(fov);
1947  fov = NULL;
1948 
1949  giraffe_rebinning_destroy(rebinning);
1950  rebinning = NULL;
1951 
1952  giraffe_table_delete(wcalcoeff);
1953  wcalcoeff = NULL;
1954 
1955  giraffe_table_delete(slitgeometry);
1956  slitgeometry = NULL;
1957 
1958  giraffe_table_delete(grating);
1959  grating = NULL;
1960 
1961  giraffe_table_delete(fibers);
1962  fibers = NULL;
1963 
1964  return 1;
1965  }
1966 
1967  cpl_frameset_insert(set, rimg_frame);
1968 
1969  }
1970 
1971  giraffe_fov_delete(fov);
1972  fov = NULL;
1973 
1974  }
1975 
1976 
1977  /*
1978  * Response computation
1979  */
1980 
1981  cpl_msg_info(_id, "Computing instrument response function...");
1982 
1983  filename = cpl_frame_get_filename(flxstd_frame);
1984 
1985  flxstd = giraffe_table_new();
1986  status = giraffe_table_load(flxstd, filename, 1, NULL);
1987 
1988  if (status != 0) {
1989  cpl_msg_error(_id, "Cannot load flux standards catalog from "
1990  "'%s'. Aborting ...", filename);
1991 
1992  giraffe_rebinning_destroy(rebinning);
1993  rebinning = NULL;
1994 
1995  giraffe_table_delete(wcalcoeff);
1996  wcalcoeff = NULL;
1997 
1998  giraffe_table_delete(slitgeometry);
1999  slitgeometry = NULL;
2000 
2001  giraffe_table_delete(grating);
2002  grating = NULL;
2003 
2004  giraffe_table_delete(fibers);
2005  fibers = NULL;
2006 
2007  return 1;
2008  }
2009 
2010 
2011  /*
2012  * Search the flux standard catalog for the observed flux standard
2013  * object.
2014  */
2015 
2016  refflx = giraffe_select_flux_standard(flxstd, rebinning->spectra, 1.);
2017 
2018  if (refflx == NULL) {
2019  cpl_msg_error(_id, "No matching flux standard found in the "
2020  "catalog '%s'! Aborting ...", filename);
2021 
2022  giraffe_table_delete(flxstd);
2023  flxstd = NULL;
2024 
2025  giraffe_rebinning_destroy(rebinning);
2026  rebinning = NULL;
2027 
2028  giraffe_table_delete(wcalcoeff);
2029  wcalcoeff = NULL;
2030 
2031  giraffe_table_delete(slitgeometry);
2032  slitgeometry = NULL;
2033 
2034  giraffe_table_delete(grating);
2035  grating = NULL;
2036 
2037  giraffe_table_delete(fibers);
2038  fibers = NULL;
2039 
2040  return 1;
2041  }
2042 
2043  giraffe_table_delete(flxstd);
2044  flxstd = NULL;
2045 
2046 
2047  filename = cpl_frame_get_filename(atmext_frame);
2048 
2049  atmext = giraffe_table_new();
2050  status = giraffe_table_load(atmext, filename, 1, NULL);
2051 
2052  if (status != 0) {
2053  cpl_msg_error(_id, "Cannot load atmospheric extinction data from "
2054  "'%s'. Aborting ...", filename);
2055 
2056  giraffe_table_delete(refflx);
2057  refflx = NULL;
2058 
2059  giraffe_rebinning_destroy(rebinning);
2060  rebinning = NULL;
2061 
2062  giraffe_table_delete(wcalcoeff);
2063  wcalcoeff = NULL;
2064 
2065  giraffe_table_delete(slitgeometry);
2066  slitgeometry = NULL;
2067 
2068  giraffe_table_delete(grating);
2069  grating = NULL;
2070 
2071  giraffe_table_delete(fibers);
2072  fibers = NULL;
2073 
2074  return 1;
2075  }
2076 
2077 
2078  fxcal_config = giraffe_fxcalibration_config_create(config);
2079 
2080  response = giraffe_response_new();
2081 
2082  status = giraffe_calibrate_flux(response, rebinning, fibers, NULL,
2083  refflx, atmext, fxcal_config);
2084 
2085  if (status != 0) {
2086 
2087  cpl_msg_error(_id, "Instrument resonse computation failed!");
2088 
2089  giraffe_response_delete(response);
2090  response = NULL;
2091 
2093  fxcal_config = NULL;
2094 
2095  giraffe_table_delete(atmext);
2096  atmext = NULL;
2097 
2098  giraffe_table_delete(refflx);
2099  refflx = NULL;
2100 
2101  giraffe_rebinning_destroy(rebinning);
2102  rebinning = NULL;
2103 
2104  giraffe_table_delete(wcalcoeff);
2105  wcalcoeff = NULL;
2106 
2107  giraffe_table_delete(slitgeometry);
2108  slitgeometry = NULL;
2109 
2110  giraffe_table_delete(grating);
2111  grating = NULL;
2112 
2113  giraffe_table_delete(fibers);
2114  fibers = NULL;
2115 
2116  return 1;
2117 
2118  }
2119 
2121  fxcal_config = NULL;
2122 
2123  giraffe_table_delete(refflx);
2124  refflx = NULL;
2125 
2126  giraffe_table_delete(atmext);
2127  atmext = NULL;
2128 
2129 
2130  /*
2131  * Save and register the instrument response product
2132  */
2133 
2134  giraffe_image_add_info(response->response, &info, set);
2135 
2136  rsp_frame = giraffe_frame_create_image(response->response,
2137  GIFRAME_INSTRUMENT_RESPONSE,
2138  CPL_FRAME_LEVEL_FINAL,
2139  TRUE, TRUE);
2140 
2141  if (rsp_frame == NULL) {
2142 
2143  cpl_msg_error(_id, "Cannot create local file! Aborting ...");
2144 
2145  giraffe_response_delete(response);
2146  response = NULL;
2147 
2148  giraffe_rebinning_destroy(rebinning);
2149  rebinning = NULL;
2150 
2151  giraffe_table_delete(wcalcoeff);
2152  wcalcoeff = NULL;
2153 
2154  giraffe_table_delete(slitgeometry);
2155  slitgeometry = NULL;
2156 
2157  giraffe_table_delete(grating);
2158  grating = NULL;
2159 
2160  giraffe_table_delete(fibers);
2161  fibers = NULL;
2162 
2163  return 1;
2164 
2165  }
2166 
2167  cpl_frameset_insert(set, rsp_frame);
2168 
2169 
2170  /*
2171  * Save and register the efficiency curve product
2172  */
2173 
2174  giraffe_table_add_info(response->efficiency, &info, set);
2175 
2176  rsp_frame = giraffe_frame_create_table(response->efficiency,
2177  GIFRAME_EFFICIENCY_CURVE,
2178  CPL_FRAME_LEVEL_FINAL,
2179  TRUE, TRUE);
2180 
2181  if (rsp_frame == NULL) {
2182 
2183  cpl_msg_error(_id, "Cannot create local file! Aborting ...");
2184 
2185  giraffe_response_delete(response);
2186  response = NULL;
2187 
2188  giraffe_rebinning_destroy(rebinning);
2189  rebinning = NULL;
2190 
2191  giraffe_table_delete(wcalcoeff);
2192  wcalcoeff = NULL;
2193 
2194  giraffe_table_delete(slitgeometry);
2195  slitgeometry = NULL;
2196 
2197  giraffe_table_delete(grating);
2198  grating = NULL;
2199 
2200  giraffe_table_delete(fibers);
2201  fibers = NULL;
2202 
2203  return 1;
2204 
2205  }
2206 
2207  cpl_frameset_insert(set, rsp_frame);
2208 
2209  giraffe_response_delete(response);
2210  response = NULL;
2211 
2212 
2213  /*
2214  * Cleanup
2215  */
2216 
2217  giraffe_table_delete(wcalcoeff);
2218 
2219  giraffe_table_delete(slitgeometry);
2220  giraffe_table_delete(grating);
2221  giraffe_table_delete(fibers);
2222 
2223  giraffe_rebinning_destroy(rebinning);
2224 
2225  return 0;
2226 
2227 }
2228 
2229 
2230 static cxint
2231 giqcstandard(cpl_frameset* set)
2232 {
2233 
2234  const cxchar* const fctid = "giqcstandard";
2235 
2236 
2237  const cxdouble saturation = 60000.;
2238  const cxdouble wlscale = 0.1;
2239 
2240  cxint i = 0;
2241  cxint status = 0;
2242  cxint nbin = 0;
2243  cxint npixel = 0;
2244  cxint nsaturated = 0;
2245 
2246  const cxdouble* pixels = NULL;
2247 
2248  cxdouble wlmin = 0.;
2249  cxdouble wlmax = 0.;
2250  cxdouble efficiency = 0.;
2251 
2252  cpl_propertylist* properties = NULL;
2253  cpl_propertylist* _properties = NULL;
2254  cpl_propertylist* qclog = NULL;
2255 
2256  cpl_frame* rframe = NULL;
2257  cpl_frame* pframe = NULL;
2258 
2259  cpl_image* _rimage = NULL;
2260 
2261  cpl_table* _ptable = NULL;
2262 
2263  GiImage* rimage = NULL;
2264 
2265  GiTable* ptable = NULL;
2266 
2267  GiPaf* qc = NULL;
2268 
2269 
2270  cpl_msg_info(fctid, "Computing QC1 parameters ...");
2271 
2272  qc = giraffe_qclog_open(0);
2273 
2274  if (qc == NULL) {
2275  cpl_msg_error(fctid, "Cannot create QC1 log!");
2276  return 1;
2277  }
2278 
2279  qclog = giraffe_paf_get_properties(qc);
2280  cx_assert(qclog != NULL);
2281 
2282 
2283  /*
2284  * Process efficiency table
2285  */
2286 
2287  pframe = giraffe_get_frame(set, GIFRAME_EFFICIENCY_CURVE,
2288  CPL_FRAME_GROUP_PRODUCT);
2289 
2290  if (pframe == NULL) {
2291  cpl_msg_error(fctid, "Missing product frame (%s)",
2292  GIFRAME_EFFICIENCY_CURVE);
2293 
2294  giraffe_paf_delete(qc);
2295  qc = NULL;
2296 
2297  return 1;
2298  }
2299 
2300  cpl_msg_info(fctid, "Processing product frame '%s' (%s)",
2301  cpl_frame_get_filename(pframe), cpl_frame_get_tag(pframe));
2302 
2303  ptable = giraffe_table_new();
2304  status = giraffe_table_load(ptable, cpl_frame_get_filename(pframe), 1,
2305  "EFFICIENCY_CURVE");
2306 
2307  if (status != 0) {
2308  cpl_msg_error(fctid, "Could not load efficiency table '%s'! "
2309  "Aborting ...", cpl_frame_get_filename(pframe));
2310 
2311  giraffe_table_delete(ptable);
2312  ptable = NULL;
2313 
2314  giraffe_paf_delete(qc);
2315  qc = NULL;
2316 
2317  return 1;
2318  }
2319 
2320 
2321  /*
2322  * Load first raw image as reference
2323  */
2324 
2325  rframe = cpl_frameset_find(set, GIFRAME_STANDARD);
2326 
2327  if (rframe == NULL) {
2328  cpl_msg_error(fctid, "Missing raw frame (%s)", GIFRAME_STANDARD);
2329 
2330  giraffe_table_delete(ptable);
2331  ptable = NULL;
2332 
2333  giraffe_paf_delete(qc);
2334  qc = NULL;
2335 
2336  return 1;
2337  }
2338 
2339  rimage = giraffe_image_new(CPL_TYPE_DOUBLE);
2340  status = giraffe_image_load(rimage, cpl_frame_get_filename(rframe), 0);
2341 
2342  if (status != 0) {
2343  cpl_msg_error(fctid, "Could not load standard star observation '%s'!",
2344  cpl_frame_get_filename(rframe));
2345 
2346  giraffe_image_delete(rimage);
2347  rimage = NULL;
2348 
2349  giraffe_table_delete(ptable);
2350  ptable = NULL;
2351 
2352  giraffe_paf_delete(qc);
2353  qc = NULL;
2354 
2355  return 1;
2356 
2357  }
2358 
2359  _rimage = giraffe_image_get(rimage);
2360  cx_assert(_rimage != NULL);
2361 
2362  properties = giraffe_image_get_properties(rimage);
2363  cx_assert(properties != NULL);
2364 
2365  giraffe_propertylist_copy(qclog, "ARCFILE", properties, GIALIAS_ARCFILE);
2366  giraffe_propertylist_copy(qclog, "TPL.ID", properties, GIALIAS_TPLID);
2367 
2368  cpl_propertylist_update_string(qclog, "PRO.CATG",
2369  cpl_frame_get_tag(pframe));
2370  cpl_propertylist_set_comment(qclog, "PRO.CATG",
2371  "Pipeline product category");
2372 
2373 
2374  /*
2375  * Count the number of saturated pixels in the raw frame
2376  */
2377 
2378  pixels = cpl_image_get_data(_rimage);
2379  npixel = cpl_image_get_size_x(_rimage) * cpl_image_get_size_y(_rimage);
2380 
2381  _rimage = NULL;
2382 
2383  for (i = 0; i < npixel; i++) {
2384  if (pixels[i] > saturation) {
2385  ++nsaturated;
2386  }
2387  }
2388 
2389  pixels = NULL;
2390 
2391  giraffe_image_delete(rimage);
2392  rimage = NULL;
2393 
2394 
2395  /*
2396  * Compute mean efficiency from a wavelength range around the
2397  * central wavelength.
2398  */
2399 
2400  _ptable = giraffe_table_get(ptable);
2401  cx_assert(_ptable != NULL);
2402 
2403  properties = giraffe_table_get_properties(ptable);
2404  cx_assert(properties != NULL);
2405 
2406  if (cpl_propertylist_has(properties, GIALIAS_GRATWLEN) == FALSE) {
2407 
2408  giraffe_table_delete(ptable);
2409  ptable = NULL;
2410 
2411  giraffe_paf_delete(qc);
2412  qc = NULL;
2413 
2414  cpl_msg_error(fctid, "Missing property '%s'", GIALIAS_GRATWLEN);
2415 
2416  return 1;
2417 
2418  }
2419  else {
2420 
2421  cxdouble wlband = 0.;
2422  cxdouble wl0 = cpl_propertylist_get_double(properties,
2423  GIALIAS_GRATWLEN);
2424 
2425 
2426  wlmin = cpl_propertylist_get_double(properties, GIALIAS_BINWLMIN);
2427  wlmax = cpl_propertylist_get_double(properties, GIALIAS_BINWLMAX);
2428 
2429  cx_assert((wlmin < wl0) && (wl0 < wlmax));
2430 
2431  wlband = wlscale * fabs(wlmax - wlmin);
2432 
2433  wlmin = CX_MAX(wlmin, (wl0 - wlband));
2434  wlmax = CX_MIN(wlmax, (wl0 + wlband));
2435 
2436  cpl_msg_info(fctid, "Computing spectrograph efficiency from "
2437  "wavelength range ]%.1f, %.1f[", wlmin, wlmax);
2438 
2439  }
2440 
2441  nbin = 0;
2442 
2443  for (i = 0; i < cpl_table_get_nrow(_ptable); ++i) {
2444 
2445  cxdouble wavelength = cpl_table_get_double(_ptable, "WLEN", i, NULL);
2446 
2447  if ((wavelength > wlmin) && (wavelength < wlmax)) {
2448 
2449  efficiency += cpl_table_get_double(_ptable, "EFFICIENCY",
2450  i, NULL);
2451  ++nbin;
2452 
2453  }
2454 
2455  }
2456 
2457  efficiency /= (cxdouble)nbin;
2458 
2459 
2460  cpl_propertylist_update_int(properties, GIALIAS_QCNSAT, nsaturated);
2461  cpl_propertylist_set_comment(properties, GIALIAS_QCNSAT, "Number of "
2462  "saturated pixels in the first raw frame");
2463 
2464  giraffe_propertylist_copy(qclog, "QC.OUT1.NSAT.RAW", properties,
2465  GIALIAS_QCNSAT);
2466 
2467 
2468  cpl_propertylist_update_double(properties, GIALIAS_QCEFFICIENCY,
2469  efficiency);
2470  cpl_propertylist_set_comment(properties, GIALIAS_QCEFFICIENCY,
2471  "Efficiency of the spectrograph.");
2472 
2473  giraffe_propertylist_copy(qclog, "QC.EFFICIENCY.MEAN", properties,
2474  GIALIAS_QCEFFICIENCY);
2475 
2476 
2477  if (cpl_propertylist_has(properties, GIALIAS_SKY_LEVEL) == TRUE) {
2478 
2479  cxdouble mean_sky = cpl_propertylist_get_double(properties,
2480  GIALIAS_SKY_LEVEL);
2481 
2482  cpl_propertylist_update_double(properties, GIALIAS_QCSKYLEVEL,
2483  mean_sky);
2484  cpl_propertylist_set_comment(properties, GIALIAS_QCSKYLEVEL,
2485  "Mean sky level [ADU]");
2486 
2487  giraffe_propertylist_copy(qclog, "QC.SKY.MEAN", properties,
2488  GIALIAS_QCSKYLEVEL);
2489 
2490  }
2491 
2492 
2493  /*
2494  * Write QC1 log and save updated product.
2495  */
2496 
2497  _properties = cpl_propertylist_duplicate(properties);
2498 
2499  cpl_propertylist_erase_regexp(_properties, "ESO QC.*", 0);
2500 
2501  cpl_image_save(NULL, cpl_frame_get_filename(pframe), CPL_BPP_8_UNSIGNED,
2502  _properties, CPL_IO_CREATE);
2503 
2504  cpl_propertylist_delete(_properties);
2505  _properties = NULL;
2506 
2507  giraffe_table_attach(ptable, cpl_frame_get_filename(pframe), 1, NULL);
2508 
2509  giraffe_table_delete(ptable);
2510  ptable = NULL;
2511 
2512  giraffe_qclog_close(qc);
2513  qc = NULL;
2514 
2515  return 0;
2516 
2517 }
2518 
2519 
2520 /*
2521  * Build table of contents, i.e. the list of available plugins, for
2522  * this module. This function is exported.
2523  */
2524 
2525 int
2526 cpl_plugin_get_info(cpl_pluginlist* list)
2527 {
2528 
2529  cpl_recipe* recipe = cx_calloc(1, sizeof *recipe);
2530  cpl_plugin* plugin = &recipe->interface;
2531 
2532 
2533  cpl_plugin_init(plugin,
2534  CPL_PLUGIN_API,
2535  GIRAFFE_BINARY_VERSION,
2536  CPL_PLUGIN_TYPE_RECIPE,
2537  "gistandard",
2538  "Process a spectro-photometric standard star "
2539  "observation and compute the instrument response curve.",
2540  "For detailed information please refer to the "
2541  "GIRAFFE pipeline user manual.\nIt is available at "
2542  "http://www.eso.org/pipelines.",
2543  "Giraffe Pipeline",
2544  PACKAGE_BUGREPORT,
2546  gistandard_create,
2547  gistandard_exec,
2548  gistandard_destroy);
2549 
2550  cpl_pluginlist_append(list, plugin);
2551 
2552  return 0;
2553 
2554 }

This file is part of the GIRAFFE Pipeline Reference Manual 2.12.
Documentation copyright © 2002-2006 European Southern Observatory.
Generated on Mon Mar 24 2014 11:43:53 by doxygen 1.8.2 written by Dimitri van Heesch, © 1997-2004