GIRAFFE Pipeline Reference Manual

gimasterdark.c
1 /* $Id$
2  *
3  * This file is part of the GIRAFFE Pipeline
4  * Copyright (C) 2002-2006 European Southern Observatory
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 /*
22  * $Author$
23  * $Date$
24  * $Revision$
25  * $Name$
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 # include <config.h>
30 #endif
31 
32 #include <math.h>
33 
34 #include <cxmessages.h>
35 #include <cxmemory.h>
36 #include <cxlist.h>
37 
38 #include <cpl_recipe.h>
39 #include <cpl_plugininfo.h>
40 #include <cpl_parameterlist.h>
41 #include <cpl_frameset.h>
42 #include <cpl_propertylist.h>
43 #include <cpl_vector.h>
44 #include <cpl_msg.h>
45 
46 #include "gialias.h"
47 #include "gierror.h"
48 #include "giframe.h"
49 #include "giimage.h"
50 #include "giwindow.h"
51 #include "gifibers.h"
52 #include "gibias.h"
53 #include "gimath.h"
54 #include "gistacking.h"
55 #include "giqclog.h"
56 #include "giutils.h"
57 
58 
59 static cxint gimasterdark(cpl_parameterlist*, cpl_frameset*);
60 static cxint giqcmasterdark(cpl_frameset*);
61 
62 
63 static cxint
64 _giraffe_clean_badpixels(GiImage* image, GiImage* bpixel)
65 {
66 
67  cxint i = 0;
68 
69  cxint nx_image = 0;
70  cxint ny_image = 0;
71  cxint ny_mask = 0;
72  cxint shift = 0;
73  cxint* _bpixel = NULL;
74 
75  cxdouble* _image = NULL;
76 
77  cpl_propertylist* properties = NULL;
78 
79 
80  cx_assert(image != NULL);
81  cx_assert(bpixel != NULL);
82 
83  nx_image = cpl_image_get_size_y(giraffe_image_get(image));
84  ny_image = cpl_image_get_size_x(giraffe_image_get(image));
85 
86  ny_mask = cpl_image_get_size_x(giraffe_image_get(bpixel));
87 
88  properties = giraffe_image_get_properties(bpixel);
89  shift = cpl_propertylist_get_int(properties, GIALIAS_PRSCX);
90 
91  _image = cpl_image_get_data_double(giraffe_image_get(image));
92  _bpixel = cpl_image_get_data_int(giraffe_image_get(bpixel));
93 
94  for (i = 0; i < nx_image; i++) {
95 
96  cxint j = 0;
97 
98  for (j = 0; j < ny_image; j++) {
99 
100  if (_bpixel[i * ny_mask + j + shift] != 0) {
101  _image[i * ny_image + j] = 0.;
102  }
103 
104  }
105 
106  }
107 
108  return 0;
109 
110 }
111 
112 
113 /*
114  * Create the recipe instance, i.e. setup the parameter list for this
115  * recipe and make it availble to the application using the interface.
116  */
117 
118 static cxint
119 gimasterdark_create(cpl_plugin* plugin)
120 {
121 
122  cpl_parameter* p = NULL;
123 
124  cpl_recipe* recipe = (cpl_recipe*)plugin;
125 
126 
127  giraffe_error_init();
128 
129 
130  /*
131  * We have to provide the option we accept to the application. We
132  * need to setup our parameter list and hook it into the recipe
133  * interface.
134  */
135 
136  recipe->parameters = cpl_parameterlist_new();
137  cx_assert(recipe->parameters != NULL);
138 
139  /*
140  * Fill the parameter list.
141  */
142 
143  /* Frame combination */
144 
145  giraffe_stacking_config_add(recipe->parameters);
146  p = cpl_parameterlist_find(recipe->parameters, "giraffe.stacking.method");
147 
148  if ( p != NULL) {
149  cpl_parameter_set_default_string(p, "median");
150  }
151 
152  /* Bias removal */
153 
154  giraffe_bias_config_add(recipe->parameters);
155 
156  return 0;
157 
158 }
159 
160 /*
161  * Execute the plugin instance given by the interface.
162  */
163 
164 static cxint
165 gimasterdark_exec(cpl_plugin* plugin)
166 {
167 
168  cpl_recipe* recipe = (cpl_recipe*)plugin;
169 
170  cxint status = 0;
171 
172 
173  if (recipe->parameters == NULL || recipe->frames == NULL) {
174  return 1;
175  }
176 
177  status = gimasterdark(recipe->parameters, recipe->frames);
178 
179  if (status != 0) {
180  return 1;
181  }
182 
183  status = giqcmasterdark(recipe->frames);
184 
185  if (status != 0) {
186  return 1;
187  }
188 
189  return 0;
190 
191 }
192 
193 
194 static cxint
195 gimasterdark_destroy(cpl_plugin* plugin)
196 {
197 
198  cpl_recipe* recipe = (cpl_recipe*)plugin;
199 
200 
201  /*
202  * We just destroy what was created during the plugin initialization
203  * phase, i.e. the parameter list. The frame set is managed by the
204  * application which called us, so we must not touch it,
205  */
206 
207  cpl_parameterlist_delete(recipe->parameters);
208 
209  giraffe_error_clear();
210 
211  return 0;
212 
213 }
214 
215 
216 /*
217  * The actual recipe starts here.
218  */
219 
220 static cxint
221 gimasterdark(cpl_parameterlist* config, cpl_frameset* set)
222 {
223 
224  const cxchar* const _id = "gimasterdark";
225 
226  cxint i = 0;
227  cxint status = 0;
228  cxint count = 0;
229 
230  cxdouble exptotal = 0.;
231 
232  cx_list* darks = NULL;
233 
234  cx_list_const_iterator position = NULL;
235 
236  cpl_matrix* bias_areas = NULL;
237 
238  cpl_frame* dark_frame = NULL;
239  cpl_frame* mbias_frame = NULL;
240  cpl_frame* bpixel_frame = NULL;
241  cpl_frame* mdark_frame = NULL;
242 
243  cpl_image* _dark = NULL;
244 
245  cpl_propertylist* properties = NULL;
246 
247 
248  GiImage* result = NULL;
249  GiImage* mbias = NULL;
250  GiImage* bpixel = NULL;
251  GiImage** stack = NULL;
252 
253  GiBiasConfig* bias_config = NULL;
254 
255  GiStackingConfig* stack_config = NULL;
256 
257  GiRecipeInfo info = {(cxchar*)_id, 1, NULL};
258 
259  GiGroupInfo groups[] = {
260  {GIFRAME_DARK, CPL_FRAME_GROUP_RAW},
261  {GIFRAME_BIAS_MASTER, CPL_FRAME_GROUP_CALIB},
262  {GIFRAME_BADPIXEL_MAP, CPL_FRAME_GROUP_CALIB},
263  {NULL, CPL_FRAME_GROUP_NONE}
264  };
265 
266 
267 
268  /*
269  * Set frame group information
270  */
271 
272  status = giraffe_frameset_set_groups(set, groups);
273 
274  if (status != 0) {
275  cpl_msg_error(_id, "Setting frame group information failed!");
276  return 1;
277  }
278 
279 
280  /*
281  * Count the number of available raw frames
282  */
283 
284  count = cpl_frameset_count_tags(set, GIFRAME_DARK);
285 
286  if (count == 0) {
287  cpl_msg_error(_id, "No raw dark frames found in frameset! "
288  "Aborting ...");
289  return 1;
290  }
291 
292 
293  /*
294  * Verify frameset contents
295  */
296 
297  mbias_frame = cpl_frameset_find(set, GIFRAME_BIAS_MASTER);
298 
299  if (!mbias_frame) {
300  cpl_msg_error(_id, "No master bias present in frame set. "
301  "Aborting ...");
302  return 1;
303  }
304 
305  bpixel_frame = cpl_frameset_find(set, GIFRAME_BADPIXEL_MAP);
306 
307  if (!bpixel_frame) {
308  cpl_msg_info(_id, "No bad pixel map present in frame set.");
309  }
310 
311 
312  /*
313  * Load the raw data frames
314  */
315 
316  cpl_msg_info(_id, "Loading dark frames ...");
317 
318  darks = cx_list_new();
319  dark_frame = cpl_frameset_find(set, GIFRAME_DARK);
320 
321  i = 0;
322 
323  while ((dark_frame != NULL ) && (i < count)) {
324 
325  const cxchar* const filename = cpl_frame_get_filename(dark_frame);
326 
327  GiImage* dark = giraffe_image_new(CPL_TYPE_DOUBLE);
328 
329 
330  status = giraffe_image_load(dark, filename, 0);
331 
332  if (status != 0) {
333  cpl_msg_error(_id, "Cannot load dark from '%s'. Aborting ...",
334  filename);
335 
336  cx_list_destroy(darks, (cx_free_func)giraffe_image_delete);
337  darks = NULL;
338 
339  return 1;
340  }
341 
342  cx_list_push_back(darks, dark);
343 
344  dark_frame = cpl_frameset_find(set, NULL);
345  ++i;
346 
347  }
348 
349  cx_assert(i == count);
350 
351 
352  /*
353  * Prepare for bias subtraction
354  */
355 
356  bias_config = giraffe_bias_config_create(config);
357 
358  /*
359  * Setup user defined areas to use for the bias computation
360  */
361 
362  if (bias_config->method == GIBIAS_METHOD_MASTER ||
363  bias_config->method == GIBIAS_METHOD_ZMASTER) {
364 
365  if (mbias_frame == NULL) {
366  cpl_msg_error(_id, "Missing master bias frame! Selected bias "
367  "removal method requires a master bias frame!");
368 
369  giraffe_bias_config_destroy(bias_config);
370  bias_config = NULL;
371 
372  cx_list_destroy(darks, (cx_free_func)giraffe_image_delete);
373  darks = NULL;
374 
375  return 1;
376  }
377  else {
378 
379  const cxchar* filename = cpl_frame_get_filename(mbias_frame);
380 
381 
382  mbias = giraffe_image_new(CPL_TYPE_DOUBLE);
383  status = giraffe_image_load(mbias, filename, 0);
384 
385  if (status != 0) {
386  cpl_msg_error(_id, "Cannot load master bias from '%s'. "
387  "Aborting ...", filename);
388 
389  giraffe_image_delete(mbias);
390  mbias = NULL;
391 
392  giraffe_bias_config_destroy(bias_config);
393  bias_config = NULL;
394 
395  cx_list_destroy(darks, (cx_free_func)giraffe_image_delete);
396  darks = NULL;
397 
398  return 1;
399  }
400 
401  }
402  }
403 
404 
405  /*
406  * Load bad pixel map if it is present in the frame set.
407  */
408 
409  if (bpixel_frame) {
410 
411  const cxchar* filename = cpl_frame_get_filename(bpixel_frame);
412 
413 
414  bpixel = giraffe_image_new(CPL_TYPE_INT);
415  status = giraffe_image_load(bpixel, filename, 0);
416 
417  if (status != 0) {
418  cpl_msg_error(_id, "Cannot load bad pixel map from '%s'. "
419  "Aborting ...", filename);
420 
421  if (mbias != NULL) {
422  giraffe_image_delete(mbias);
423  mbias = NULL;
424  }
425 
426  giraffe_bias_config_destroy(bias_config);
427  bias_config = NULL;
428 
429  cx_list_destroy(darks, (cx_free_func)giraffe_image_delete);
430  darks = NULL;
431 
432  return 1;
433  }
434 
435  }
436 
437 
438  /*
439  * Subtract the bias from each dark.
440  */
441 
442  for (i = 0; i < count; i++) {
443 
444  GiImage* dark = cx_list_pop_front(darks);
445  GiImage* rdark = giraffe_image_new(CPL_TYPE_DOUBLE);
446 
447 
448  status = giraffe_bias_remove(rdark, dark, mbias, bpixel, bias_areas,
449  bias_config);
450 
451  if (status != 0) {
452 
453  cx_list_push_front(darks, dark);
454 
455  giraffe_image_delete(rdark);
456  rdark = NULL;
457 
458  if (mbias != NULL) {
459  giraffe_image_delete(mbias);
460  mbias = NULL;
461  }
462 
463  giraffe_bias_config_destroy(bias_config);
464  bias_config = NULL;
465 
466  cx_list_destroy(darks, (cx_free_func)giraffe_image_delete);
467  darks = NULL;
468 
469  return 1;
470 
471  }
472 
473  giraffe_image_delete(dark);
474  dark = NULL;
475 
476  cx_list_push_back(darks, rdark);
477 
478  }
479 
480  if (mbias != NULL) {
481  giraffe_image_delete(mbias);
482  mbias = NULL;
483  }
484 
485  giraffe_bias_config_destroy(bias_config);
486  bias_config = NULL;
487 
488 
489  /*
490  * Scale each bias subtracted dark to 1 second exposure time.
491  * Compute total exposure time.
492  */
493 
494  position = cx_list_begin(darks);
495 
496  while (position != cx_list_end(darks)) {
497 
498  cxdouble exptime = 0.;
499 
500  GiImage* dark = cx_list_get(darks, position);
501 
502  properties = giraffe_image_get_properties(dark);
503  exptime = cpl_propertylist_get_double(properties, GIALIAS_EXPTIME);
504 
505  cpl_image_divide_scalar(giraffe_image_get(dark), exptime);
506  exptotal += exptime;
507 
508  cpl_propertylist_update_double(properties, GIALIAS_EXPTIME, 1.);
509 
510  position = cx_list_next(darks, position);
511 
512  }
513 
514 
515  /*
516  * Check that enough raw frames are present in the frameset
517  * for the selected frame combination method.
518  */
519 
520  stack_config = giraffe_stacking_config_create(config);
521 
522  count = cx_list_size(darks);
523 
524  if (count < stack_config->min_nr_frames) {
525 
526  cpl_msg_error(_id, "Not enough frames (%d). Stacking method '%d' "
527  "requires at least %d frames! Aborting...", count,
528  stack_config->stackmethod, stack_config->min_nr_frames);
529 
530  giraffe_stacking_config_destroy(stack_config);
531  stack_config = NULL;
532 
533  return 1;
534 
535  }
536 
537 
538  /*
539  * Combine the raw dark frames
540  */
541 
542  cpl_msg_info(_id, "Combining %d of %d dark frames.", i, count);
543 
544  stack = cx_calloc(count + 1, sizeof(GiImage*));
545 
546  i = 0;
547  position = cx_list_begin(darks);
548 
549  while (position != cx_list_end(darks)) {
550  stack[i] = cx_list_get(darks, position);
551  position = cx_list_next(darks, position);
552  ++i;
553  }
554 
555  result = giraffe_stacking_stack_images(stack, stack_config);
556 
557  if (result == NULL) {
558 
559  cpl_msg_error(_id, "Frame combination failed! Aborting ...");
560 
561  cx_free(stack);
562  stack = NULL;
563 
564  cx_list_destroy(darks, (cx_free_func)giraffe_image_delete);
565  darks = NULL;
566 
567  giraffe_stacking_config_destroy(stack_config);
568  stack_config = NULL;
569 
570  return 1;
571 
572  }
573 
574  properties = giraffe_image_get_properties(stack[0]);
575  giraffe_image_set_properties(result, properties);
576 
577  cx_free(stack);
578  stack = NULL;
579 
580  giraffe_stacking_config_destroy(stack_config);
581  stack_config = NULL;
582 
583  cx_list_destroy(darks, (cx_free_func)giraffe_image_delete);
584  darks = NULL;
585 
586 
587  /*
588  * Clean the bad pixels if a bad pixel map is present. The flux of
589  * bad pixels is simply set to 0.
590  */
591 
592  if (bpixel) {
593 
594  status = _giraffe_clean_badpixels(result, bpixel);
595 
596  if (status != 0) {
597 
598  cpl_msg_error(_id, "Bad pixel cleaning on master dark frame "
599  "failed!");
600 
601  giraffe_image_delete(result);
602  result = NULL;
603 
604  giraffe_image_delete(bpixel);
605  bpixel = NULL;
606 
607  return 1;
608 
609  }
610 
611  }
612 
613  giraffe_image_delete(bpixel);
614  bpixel = NULL;
615 
616 
617  /*
618  * Update master dark properties.
619  */
620 
621  cpl_msg_info(_id, "Writing master dark image ...");
622 
623  properties = giraffe_image_get_properties(result);
624  cx_assert(properties != NULL);
625 
626  cpl_propertylist_update_double(properties, GIALIAS_CRPIX1, 1.);
627 
628  cpl_propertylist_update_double(properties, GIALIAS_EXPTTOT, exptotal);
629  cpl_propertylist_update_int(properties, GIALIAS_DATANCOM, count);
630 
631  _dark = giraffe_image_get(result);
632 
633  cpl_propertylist_update_double(properties, GIALIAS_DARKVALUE,
634  cpl_image_get_mean(_dark));
635  cpl_propertylist_set_comment(properties, GIALIAS_DARKVALUE,
636  "Dark current in ADU/s");
637 
638  cpl_propertylist_erase(properties, GIALIAS_TPLEXPNO);
639 
640 
641  giraffe_image_add_info(result, &info, set);
642 
643  mdark_frame = giraffe_frame_create_image(result,
644  GIFRAME_DARK_MASTER,
645  CPL_FRAME_LEVEL_FINAL,
646  TRUE, TRUE);
647 
648  if (mdark_frame == NULL) {
649 
650  cpl_msg_error(_id, "Cannot create local file! Aborting ...");
651 
652  if (result != NULL) {
653  giraffe_image_delete(result);
654  }
655 
656  return 1;
657 
658  }
659 
660  cpl_frameset_insert(set, mdark_frame);
661 
662 
663  if (result != NULL) {
664  giraffe_image_delete(result);
665  }
666 
667  return 0;
668 
669 }
670 
671 
672 /*
673  * The quality control task starts here.
674  */
675 
676 static cxint
677 giqcmasterdark(cpl_frameset* set)
678 {
679 
680  const cxchar* const fctid = "giqcmasterdark";
681 
682  cxint status = 0;
683 
684  cxdouble mean = 0.;
685  cxdouble exptime = 1.;
686  cxdouble gflux = 0.;
687 
688  cpl_size gpx = 0;
689  cpl_size gpy = 0;
690 
691  cpl_propertylist* properties = NULL;
692  cpl_propertylist* qclog = NULL;
693 
694 
695  cpl_image* _mdark = NULL;
696 
697  cpl_frame* rframe = NULL;
698  cpl_frame* pframe = NULL;
699 
700  GiPaf* qc = NULL;
701 
702  GiImage* mdark = NULL;
703  GiImage* dark = NULL;
704 
705  GiWindow w = {10, 200, 2038, 3000};
706 
707 
708  cpl_msg_info(fctid, "Computing QC1 parameters ...");
709 
710  qc = giraffe_qclog_open(0);
711 
712  if (qc == NULL) {
713  cpl_msg_error(fctid, "Cannot create QC1 log!");
714  return 1;
715  }
716 
717  qclog = giraffe_paf_get_properties(qc);
718  cx_assert(qclog != NULL);
719 
720 
721  /*
722  * Process master dark
723  */
724 
725  pframe = giraffe_get_frame(set, GIFRAME_DARK_MASTER,
726  CPL_FRAME_GROUP_PRODUCT);
727 
728  if (pframe == NULL) {
729  cpl_msg_error(fctid, "Missing product frame (%s)",
730  GIFRAME_DARK_MASTER);
731 
732  giraffe_paf_delete(qc);
733  qc = NULL;
734 
735  return 1;
736  }
737 
738  cpl_msg_info(fctid, "Processing product frame '%s' (%s)",
739  cpl_frame_get_filename(pframe), cpl_frame_get_tag(pframe));
740 
741  mdark = giraffe_image_new(CPL_TYPE_DOUBLE);
742  status = giraffe_image_load(mdark, cpl_frame_get_filename(pframe), 0);
743 
744  if (status != 0) {
745  cpl_msg_error(fctid, "Could not load master dark '%s'! Aborting ...",
746  cpl_frame_get_filename(pframe));
747 
748  giraffe_image_delete(mdark);
749  mdark = NULL;
750 
751  giraffe_paf_delete(qc);
752  qc = NULL;
753 
754  return 1;
755  }
756 
757 
758  /*
759  * Load first raw image as reference
760  */
761 
762  rframe = cpl_frameset_find(set, GIFRAME_DARK);
763 
764  if (rframe == NULL) {
765  cpl_msg_error(fctid, "Missing raw frame (%s)", GIFRAME_DARK);
766 
767  giraffe_image_delete(mdark);
768  mdark = NULL;
769 
770  giraffe_paf_delete(qc);
771  qc = NULL;
772 
773  return 1;
774  }
775 
776  dark = giraffe_image_new(CPL_TYPE_DOUBLE);
777  status = giraffe_image_load(dark, cpl_frame_get_filename(rframe), 0);
778 
779  if (status != 0) {
780  cpl_msg_error(fctid, "Could not load dark '%s'!",
781  cpl_frame_get_filename(rframe));
782 
783  giraffe_image_delete(dark);
784  dark = NULL;
785 
786  giraffe_image_delete(mdark);
787  mdark = NULL;
788 
789  giraffe_paf_delete(qc);
790  qc = NULL;
791 
792  return 1;
793 
794  }
795 
796  properties = giraffe_image_get_properties(dark);
797  cx_assert(properties != NULL);
798 
799  giraffe_propertylist_copy(qclog, "ARCFILE", properties, GIALIAS_ARCFILE);
800  giraffe_propertylist_copy(qclog, "TPL.ID", properties, GIALIAS_TPLID);
801 
802  cpl_propertylist_update_string(qclog, "PRO.CATG",
803  cpl_frame_get_tag(pframe));
804  cpl_propertylist_set_comment(qclog, "PRO.CATG",
805  "Pipeline product category");
806 
807  properties = giraffe_image_get_properties(mdark);
808  cx_assert(properties != NULL);
809 
810  giraffe_propertylist_copy(qclog, "PRO.DATAAVG", properties,
811  GIALIAS_DATAMEAN);
812  giraffe_propertylist_copy(qclog, "PRO.DATARMS", properties,
813  GIALIAS_DATASIG);
814  giraffe_propertylist_copy(qclog, "PRO.DATAMED", properties,
815  GIALIAS_DATAMEDI);
816  giraffe_propertylist_copy(qclog, "PRO.DATANCOM", properties,
817  GIALIAS_DATANCOM);
818 
819 
820  /*
821  * Get 1 over exposure time in hours from the master dark frame
822  */
823 
824  if (cpl_propertylist_has(properties, GIALIAS_EXPTIME) == TRUE) {
825 
826  exptime = cpl_propertylist_get_double(properties, GIALIAS_EXPTIME);
827 
828  }
829 
830  exptime = 3600. / exptime;
831 
832 
833  /*
834  * Compute average dark value on a central window of the
835  * master dark frame. The window is used to exclude the
836  * glow feature in the upper part of the CCD.
837  */
838 
839  _mdark = giraffe_image_get(mdark);
840 
841  mean = cpl_image_get_mean_window(_mdark, w.x0, w.y0, w.x1, w.y1);
842 
843 
844  cpl_propertylist_update_double(properties, GIALIAS_QCMDARKAVG,
845  mean * exptime);
846  cpl_propertylist_set_comment(properties, GIALIAS_QCMDARKAVG,
847  "Mean master dark current (ADU/hr)");
848 
849  giraffe_propertylist_copy(qclog, "QC.DARK.CURRENT", properties,
850  GIALIAS_QCMDARKAVG);
851 
852  /*
853  * Monitoring the glow in the upper right part of the CCD
854  */
855 
856  w.x0 = 1350;
857  w.x1 = 2048;
858  w.y0 = 3800;
859  w.y1 = 4095;
860 
861  gflux = cpl_image_get_flux_window(_mdark, w.x0, w.y0, w.x1, w.y1);
862 
863  cpl_image_get_maxpos_window(_mdark, w.x0, w.y0, w.x1, w.y1, &gpx, &gpy);
864 
865 
866  cpl_propertylist_update_double(properties, GIALIAS_QCGLOWFLX, gflux);
867  cpl_propertylist_set_comment(properties, GIALIAS_QCGLOWFLX,
868  "Total flux of glow feature (ADU/s)");
869 
870  cpl_propertylist_update_int(properties, GIALIAS_QCGLOWX, (cxint)gpx);
871  cpl_propertylist_set_comment(properties, GIALIAS_QCGLOWX,
872  "X position of glow feature (pxl)");
873 
874  cpl_propertylist_update_int(properties, GIALIAS_QCGLOWY, (cxint)gpy);
875  cpl_propertylist_set_comment(properties, GIALIAS_QCGLOWY,
876  "X position of glow feature (pxl)");
877 
878  giraffe_propertylist_copy(qclog, "QC.GLOW.LEVEL", properties,
879  GIALIAS_QCGLOWFLX);
880  giraffe_propertylist_copy(qclog, "QC.GLOW.POSX", properties,
881  GIALIAS_QCGLOWX);
882  giraffe_propertylist_copy(qclog, "QC.GLOW.POSY", properties,
883  GIALIAS_QCGLOWY);
884 
885  /*
886  * Write QC1 log and save updated master dark.
887  */
888 
889  giraffe_image_save(mdark, cpl_frame_get_filename(pframe));
890 
891  giraffe_image_delete(mdark);
892  mdark = NULL;
893 
894  giraffe_qclog_close(qc);
895  qc = NULL;
896 
897  return 0;
898 
899 }
900 
901 
902 /*
903  * Build table of contents, i.e. the list of available plugins, for
904  * this module. This function is exported.
905  */
906 
907 int
908 cpl_plugin_get_info(cpl_pluginlist* list)
909 {
910 
911  cpl_recipe* recipe = cx_calloc(1, sizeof *recipe);
912  cpl_plugin* plugin = &recipe->interface;
913 
914 
915  cpl_plugin_init(plugin,
916  CPL_PLUGIN_API,
917  GIRAFFE_BINARY_VERSION,
918  CPL_PLUGIN_TYPE_RECIPE,
919  "gimasterdark",
920  "Creates a master dark image from a set of raw dark "
921  "frames.",
922  "For detailed information please refer to the "
923  "GIRAFFE pipeline user manual.\nIt is available at "
924  "http://www.eso.org/pipelines.",
925  "Giraffe Pipeline",
926  PACKAGE_BUGREPORT,
928  gimasterdark_create,
929  gimasterdark_exec,
930  gimasterdark_destroy);
931 
932  cpl_pluginlist_append(list, plugin);
933 
934  return 0;
935 
936 }

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