GIRAFFE Pipeline Reference Manual

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

This file is part of the GIRAFFE Pipeline Reference Manual 2.16.10.
Documentation copyright © 2002-2006 European Southern Observatory.
Generated on Thu Dec 15 2022 21:18:51 by doxygen 1.9.1 written by Dimitri van Heesch, © 1997-2004