GIRAFFE Pipeline Reference Manual

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

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