VIRCAM Pipeline  1.3.4
vircam_dark_combine.c
1 /* $Id: vircam_dark_combine.c,v 1.70 2012-01-16 12:32:17 jim Exp $
2  *
3  * This file is part of the VIRCAM Pipeline
4  * Copyright (C) 2005 Cambridge Astronomy Survey Unit
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  */
20 
21 /*
22  * $Author: jim $
23  * $Date: 2012-01-16 12:32:17 $
24  * $Revision: 1.70 $
25  * $Name: not supported by cvs2svn $
26  */
27 
28 /* Includes */
29 
30 #ifdef HAVE_CONFIG_H
31 #include <config.h>
32 #endif
33 
34 #include <stdio.h>
35 #include <cpl.h>
36 #include <math.h>
37 
38 #include "vircam_utils.h"
39 #include "vircam_pfits.h"
40 #include "vircam_dfs.h"
41 #include "vircam_mods.h"
42 #include "vircam_stats.h"
43 #include "vircam_fits.h"
44 #include "vircam_mask.h"
45 #include "vircam_channel.h"
46 #include "vircam_dfs.h"
47 #include "vircam_paf.h"
48 #include "vircam_wcsutils.h"
49 
50 /* Define values for bit mask that flags dummy results */
51 
52 #define MEANDARK 1
53 #define DIFFIMG 2
54 #define STATS_TAB 4
55 
56 /* Function prototypes */
57 
58 static int vircam_dark_combine_create(cpl_plugin *) ;
59 static int vircam_dark_combine_exec(cpl_plugin *) ;
60 static int vircam_dark_combine_destroy(cpl_plugin *) ;
61 static int vircam_dark_combine(cpl_parameterlist *, cpl_frameset *) ;
62 static int vircam_dark_combine_save(cpl_frameset *framelist,
63  cpl_parameterlist *parlist);
64 static void vircam_dark_combine_dummy_products(void);
65 static void vircam_dark_combine_hotpix(void);
66 static void vircam_dark_combine_normal(int jext, float exptime);
67 static int vircam_dark_combine_lastbit(int jext, cpl_frameset *framelist,
68  cpl_parameterlist *parlist);
69 static void vircam_dark_combine_init(void);
70 static void vircam_dark_combine_tidy(int level);
71 
72 /* Static global variables */
73 
74 static struct {
75 
76  /* Input */
77 
78  int combtype;
79  int scaletype;
80  int xrej;
81  float thresh;
82  int ncells;
83  int extenum;
84 
85  /* Output */
86 
87  float particle_rate;
88  float darkmed;
89  float darkrms;
90  float darkdiff_med;
91  float darkdiff_rms;
92  float striperms;
93  int nhot;
94  float hotfrac;
95  float ron12;
96 
97 } vircam_dark_combine_config;
98 
99 
100 static struct {
101  cpl_size *labels;
102  cpl_frameset *darklist;
103  vir_fits **darks;
104  int ndarks;
105  vir_fits **good;
106  int ngood;
107  cpl_frame *master_dark;
108  vir_mask *master_mask;
109  cpl_frame *chantab;
110  cpl_image *outimage;
111  cpl_propertylist *drs;
112  unsigned char *rejmask;
113  unsigned char *rejplus;
114  vir_fits *mdimage;
115  cpl_image *diffimg;
116  cpl_table *diffimstats;
117  cpl_propertylist *phupaf;
118 } ps;
119 
120 static cpl_frame *product_frame_mean_dark = NULL;
121 static cpl_frame *product_frame_diffimg = NULL;
122 static cpl_frame *product_frame_diffimg_stats = NULL;
123 static int isfirst;
124 static int we_expect;
125 static int we_get;
126 
127 static char vircam_dark_combine_description[] =
128 "vircam_dark_combine -- VIRCAM dark combine recipe.\n\n"
129 "Combine a list of dark frames into a mean dark frame. Optionally compare \n"
130 "the output frame to a master dark frame\n\n"
131 "The program accepts the following files in the SOF:\n\n"
132 " Tag Description\n"
133 " -----------------------------------------------------------------------\n"
134 " %-21s A list of raw dark images\n"
135 " %-21s Optional reference dark frame\n"
136 " %-21s Optional master bad pixel map or\n"
137 " %-21s Optional master confidence map\n"
138 " %-21s Optional channel table or\n"
139 " %-21s Optional initial channel table\n"
140 "If no master dark frame is made available, then no comparison will be done\n"
141 "This means there will be no output difference image. If a master dark is\n"
142 "available, but no channel table is, then a difference image will be formed\n"
143 "but no stats will be written."
144 "\n";
145 
274 /* Function code */
275 
276 
277 /*---------------------------------------------------------------------------*/
285 /*---------------------------------------------------------------------------*/
286 
287 int cpl_plugin_get_info(cpl_pluginlist *list) {
288  cpl_recipe *recipe = cpl_calloc(1,sizeof(*recipe));
289  cpl_plugin *plugin = &recipe->interface;
290  char alldesc[SZ_ALLDESC];
291  (void)snprintf(alldesc,SZ_ALLDESC,vircam_dark_combine_description,
292  VIRCAM_DARK_RAW,VIRCAM_REF_DARK,VIRCAM_CAL_BPM,
293  VIRCAM_CAL_CONF,VIRCAM_CAL_CHANTAB,VIRCAM_CAL_CHANTAB_INIT);
294 
295  cpl_plugin_init(plugin,
296  CPL_PLUGIN_API,
297  VIRCAM_BINARY_VERSION,
298  CPL_PLUGIN_TYPE_RECIPE,
299  "vircam_dark_combine",
300  "VIRCAM dark combination recipe",
301  alldesc,
302  "Jim Lewis",
303  "jrl@ast.cam.ac.uk",
305  vircam_dark_combine_create,
306  vircam_dark_combine_exec,
307  vircam_dark_combine_destroy);
308 
309  cpl_pluginlist_append(list,plugin);
310 
311  return(0);
312 }
313 
314 /*---------------------------------------------------------------------------*/
323 /*---------------------------------------------------------------------------*/
324 
325 static int vircam_dark_combine_create(cpl_plugin *plugin) {
326  cpl_recipe *recipe;
327  cpl_parameter *p;
328 
329  /* Get the recipe out of the plugin */
330 
331  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
332  recipe = (cpl_recipe *)plugin;
333  else
334  return(-1);
335 
336  /* Create the parameters list in the cpl_recipe object */
337 
338  recipe->parameters = cpl_parameterlist_new();
339 
340  /* Fill in the parameters. First the combination type */
341 
342  p = cpl_parameter_new_range("vircam.vircam_dark_combine.combtype",
343  CPL_TYPE_INT,
344  "1 == Median,\n 2 == Mean",
345  "vircam.vircam_dark_combine",
346  1,1,2);
347  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"combtype");
348  cpl_parameterlist_append(recipe->parameters,p);
349 
350  /* The requested scaling */
351 
352  p = cpl_parameter_new_range("vircam.vircam_dark_combine.scaletype",
353  CPL_TYPE_INT,
354  "0 == none,\n 1 == additive offset,\n 2 == multiplicative offset,\n 3 == exposure time scaling + additive offset",
355  "vircam.vircam_dark_combine",
356  1,0,3);
357  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"scaletype");
358  cpl_parameterlist_append(recipe->parameters,p);
359 
360  /* Extra rejection cycle */
361 
362  p = cpl_parameter_new_value("vircam.vircam_dark_combine.xrej",
363  CPL_TYPE_BOOL,
364  "True if using extra rejection cycle",
365  "vircam.vircam_dark_combine",
366  TRUE);
367  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"xrej");
368  cpl_parameterlist_append(recipe->parameters,p);
369 
370  /* Rejection threshold */
371 
372  p = cpl_parameter_new_value("vircam.vircam_dark_combine.thresh",
373  CPL_TYPE_DOUBLE,
374  "Rejection threshold in sigma above background",
375  "vircam.vircam_dark_combine",5.0);
376  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"thresh");
377  cpl_parameterlist_append(recipe->parameters,p);
378 
379  /* How many cells to divide each data channel */
380 
381  p = cpl_parameter_new_enum("vircam.vircam_dark_combine.ncells",
382  CPL_TYPE_INT,
383  "Number of cells for data channel stats",
384  "vircam.vircam_dark_combine",8,7,1,2,4,8,
385  16,32,64);
386  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"ncells");
387  cpl_parameterlist_append(recipe->parameters,p);
388 
389  /* Extension number of input frames to use */
390 
391  p = cpl_parameter_new_range("vircam.vircam_dark_combine.extenum",
392  CPL_TYPE_INT,
393  "Extension number to be done, 0 == all",
394  "vircam.vircam_dark_combine",
395  1,0,16);
396  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"ext");
397  cpl_parameterlist_append(recipe->parameters,p);
398 
399  /* Get out of here */
400 
401  return(0);
402 }
403 
404 
405 /*---------------------------------------------------------------------------*/
411 /*---------------------------------------------------------------------------*/
412 
413 static int vircam_dark_combine_exec(cpl_plugin *plugin) {
414  cpl_recipe *recipe;
415 
416  /* Get the recipe out of the plugin */
417 
418  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
419  recipe = (cpl_recipe *)plugin;
420  else
421  return(-1);
422 
423  return(vircam_dark_combine(recipe->parameters,recipe->frames));
424 }
425 
426 /*---------------------------------------------------------------------------*/
432 /*---------------------------------------------------------------------------*/
433 
434 static int vircam_dark_combine_destroy(cpl_plugin *plugin) {
435  cpl_recipe *recipe ;
436 
437  /* Get the recipe out of the plugin */
438 
439  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
440  recipe = (cpl_recipe *)plugin;
441  else
442  return(-1);
443 
444  cpl_parameterlist_delete(recipe->parameters);
445  return(0);
446 }
447 
448 /*---------------------------------------------------------------------------*/
455 /*---------------------------------------------------------------------------*/
456 
457 static int vircam_dark_combine(cpl_parameterlist *parlist,
458  cpl_frameset *framelist) {
459  const char *fctid="vircam_dark_combine";
460  const char *fname;
461  int j,jst,jfn,retval,status,live,nx,ny;
462  cpl_size nlab;
463  long i;
464  float exptime;
465  vir_fits *ff;
466  cpl_parameter *p;
467  cpl_propertylist *plist;
468 
469  /* Check validity of input frameset */
470 
471  if (framelist == NULL || cpl_frameset_get_size(framelist) <= 0) {
472  cpl_msg_error(fctid,"Input framelist NULL or has no input data");
473  return(-1);
474  }
475 
476  /* Check the files in the frameset */
477 
478  if (vircam_frameset_fexists(framelist) != VIR_OK) {
479  cpl_msg_error(fctid,"Input frameset is missing files. Check SOF");
480  return(-1);
481  }
482 
483  /* Initialise some things */
484 
485  vircam_dark_combine_init();
486  we_expect |= MEANDARK;
487 
488  /* Get the parameters */
489 
490  p = cpl_parameterlist_find(parlist,"vircam.vircam_dark_combine.combtype");
491  vircam_dark_combine_config.combtype = cpl_parameter_get_int(p);
492  p = cpl_parameterlist_find(parlist,"vircam.vircam_dark_combine.scaletype");
493  vircam_dark_combine_config.scaletype = cpl_parameter_get_int(p);
494  p = cpl_parameterlist_find(parlist,"vircam.vircam_dark_combine.xrej");
495  vircam_dark_combine_config.xrej = cpl_parameter_get_bool(p);
496  p = cpl_parameterlist_find(parlist,"vircam.vircam_dark_combine.thresh");
497  vircam_dark_combine_config.thresh = (float)cpl_parameter_get_double(p);
498  p = cpl_parameterlist_find(parlist,"vircam.vircam_dark_combine.ncells");
499  vircam_dark_combine_config.ncells = cpl_parameter_get_int(p);
500  p = cpl_parameterlist_find(parlist,"vircam.vircam_dark_combine.extenum");
501  vircam_dark_combine_config.extenum = cpl_parameter_get_int(p);
502 
503  /* Sort out raw from calib frames */
504 
505  if (vircam_dfs_set_groups(framelist) != VIR_OK) {
506  cpl_msg_error(fctid,"Cannot identify RAW and CALIB frames");
507  vircam_dark_combine_tidy(2);
508  return(-1);
509  }
510 
511  /* Get a list of the frame labels */
512 
513  if ((ps.labels = cpl_frameset_labelise(framelist,vircam_compare_tags,
514  &nlab)) == NULL) {
515  cpl_msg_error(fctid,"Cannot labelise the input frames");
516  vircam_dark_combine_tidy(2);
517  return(-1);
518  }
519 
520  /* Get the dark frames */
521 
522  if ((ps.darklist = vircam_frameset_subgroup(framelist,ps.labels,nlab,
523  VIRCAM_DARK_RAW)) == NULL) {
524  cpl_msg_error(fctid,"Cannot find dark frames in input frameset");
525  vircam_dark_combine_tidy(2);
526  return(-1);
527  }
528  ps.ndarks = cpl_frameset_get_size(ps.darklist);
529 
530  /* Get the exposure time from the first dark frame in the list */
531 
532  fname = cpl_frame_get_filename(cpl_frameset_get_first(ps.darklist));
533  plist = cpl_propertylist_load(fname,0);
534  if (vircam_pfits_get_exptime(plist,&exptime) != VIR_OK) {
535  cpl_msg_warning(fctid,"Unable to get exposure time for %s",fname);
536  exptime = 1.0;
537  }
538  cpl_propertylist_delete(plist);
539 
540  /* Check to see if there is a master dark frame */
541 
542  if ((ps.master_dark = vircam_frameset_subgroup_1(framelist,ps.labels,nlab,
543  VIRCAM_REF_DARK)) == NULL)
544  cpl_msg_info(fctid,"No master dark found -- no difference image will be formed");
545  else
546  we_expect |= DIFFIMG;
547 
548  /* Check to see if there is a master bad pixel map. If there isn't one
549  then look for a confidence map */
550 
551  ps.master_mask = vircam_mask_define(framelist,ps.labels,nlab);
552 
553  /* Check to see if there is a channel table */
554 
555  if ((ps.chantab = vircam_frameset_subgroup_1(framelist,ps.labels,nlab,
556  VIRCAM_CAL_CHANTAB)) == NULL) {
557  if ((ps.chantab = vircam_frameset_subgroup_1(framelist,ps.labels,nlab,
558  VIRCAM_CAL_CHANTAB_INIT)) == NULL)
559  cpl_msg_info(fctid,"No channel table found -- no difference image stats will be done");
560  } else if (we_expect & DIFFIMG)
561  we_expect |= STATS_TAB;
562 
563  /* Now, how many image extensions do we want to do? If the extension
564  number is zero, then we loop for all possible extensions. If it
565  isn't then we just do the extension specified */
566 
567  vircam_exten_range(vircam_dark_combine_config.extenum,
568  (const cpl_frame *)cpl_frameset_get_frame(ps.darklist,0),
569  &jst,&jfn);
570  if (jst == -1 || jfn == -1) {
571  cpl_msg_error(fctid,"Unable to continue");
572  vircam_dark_combine_tidy(2);
573  return(-1);
574  }
575 
576  /* Get some space for the good frames */
577 
578  ps.good = cpl_malloc(ps.ndarks*sizeof(vir_fits *));
579 
580  /* Now loop for all the extension... */
581 
582  for (j = jst; j <= jfn; j++) {
583  status = VIR_OK;
584  we_get = 0;
585  isfirst = (j == jst);
586 
587  /* Load up the images. If they won't load then signal a major error,
588  create some dummy products and save them. */
589 
590  ps.darks = vircam_fits_load_list(ps.darklist,CPL_TYPE_FLOAT,j);
591  if (ps.darks == NULL) {
592  cpl_msg_info(fctid,
593  "Extension %" CPL_SIZE_FORMAT " darks wouldn't load",
594  (cpl_size)j);
595  retval = vircam_dark_combine_lastbit(j,framelist,parlist);
596  if (retval != 0)
597  return(-1);
598  continue;
599  }
600 
601  /* Are any of these dark frames good? */
602 
603  ps.ngood = 0;
604  for (i = 0; i < ps.ndarks; i++) {
605  ff = ps.darks[i];
607  if (! live) {
608  cpl_msg_info(fctid,"Detector flagged dead %s",
610  vircam_fits_set_error(ff,VIR_FATAL);
611  } else {
612  ps.good[ps.ngood] = ff;
613  ps.ngood += 1;
614  }
615  }
616 
617  /* If there are no good images, then signal that we need to
618  create some dummy products and move on */
619 
620  if (ps.ngood == 0) {
621  cpl_msg_info(fctid,"All images flagged bad for this extension");
622  retval = vircam_dark_combine_lastbit(j,framelist,parlist);
623  if (retval != 0)
624  return(-1);
625  continue;
626  }
627 
628  /* Load the master mask extension */
629 
630  nx = (int)cpl_image_get_size_x(vircam_fits_get_image(ps.good[0]));
631  ny = (int)cpl_image_get_size_y(vircam_fits_get_image(ps.good[0]));
632  retval = vircam_mask_load(ps.master_mask,j,nx,ny);
633  if (retval == VIR_FATAL) {
634  cpl_msg_info(fctid,
635  "Unable to load mask image %s[%" CPL_SIZE_FORMAT "]",
636  vircam_mask_get_filename(ps.master_mask),(cpl_size)j);
637  cpl_msg_info(fctid,"Forcing all pixels to be good from now on");
638  vircam_mask_force(ps.master_mask,nx,ny);
639  }
640 
641  /* Call the combine module. If it fails, then signal that
642  all products will be dummies */
643 
644  cpl_msg_info(fctid,"Doing combination for extension %" CPL_SIZE_FORMAT,
645  (cpl_size)j);
646  (void)vircam_imcombine(ps.good,ps.ngood,
647  vircam_dark_combine_config.combtype,
648  vircam_dark_combine_config.scaletype,
649  vircam_dark_combine_config.xrej,
650  vircam_dark_combine_config.thresh,
651  &(ps.outimage),&(ps.rejmask),
652  &(ps.rejplus),&(ps.drs),&status);
653  if (status == VIR_OK) {
654  we_get |= MEANDARK;
655  vircam_dark_combine_hotpix();
656  vircam_dark_combine_normal(j,exptime);
657  }
658 
659  /* Create any dummies and save the products */
660 
661  retval = vircam_dark_combine_lastbit(j,framelist,parlist);
662  if (retval != 0)
663  return(-1);
664  }
665  vircam_dark_combine_tidy(2);
666  return(0);
667 }
668 
669 
670 /*---------------------------------------------------------------------------*/
677 /*---------------------------------------------------------------------------*/
678 
679 static int vircam_dark_combine_save(cpl_frameset *framelist,
680  cpl_parameterlist *parlist) {
681  cpl_propertylist *plist,*elist,*p,*pafprop;
682  int status;
683  const char *fctid = "vircam_dark_combine_save";
684  const char *outfile = "darkcomb.fits";
685  const char *outdiff = "darkdiff.fits";
686  const char *outdimst = "darkdifftab.fits";
687  const char *outfilepaf = "darkcomb";
688  const char *outdiffpaf = "darkdiff";
689  const char *recipeid = "vircam_dark_combine";
690 
691  /* If we need to make a PHU then do that now. */
692 
693  if (isfirst) {
694 
695  /* Create a new product frame object and define some tags */
696 
697  product_frame_mean_dark = cpl_frame_new();
698  cpl_frame_set_filename(product_frame_mean_dark,outfile);
699  cpl_frame_set_tag(product_frame_mean_dark,VIRCAM_PRO_DARK);
700  cpl_frame_set_type(product_frame_mean_dark,CPL_FRAME_TYPE_IMAGE);
701  cpl_frame_set_group(product_frame_mean_dark,CPL_FRAME_GROUP_PRODUCT);
702  cpl_frame_set_level(product_frame_mean_dark,CPL_FRAME_LEVEL_FINAL);
703 
704  /* Base the header on the first image in the input framelist */
705 
706  plist = vircam_fits_get_phu(ps.darks[0]);
707  ps.phupaf = vircam_paf_phu_items(plist);
708  if (ps.master_dark != NULL) {
709  cpl_propertylist_update_string(ps.phupaf,"REF_DARK",
710  cpl_frame_get_filename(ps.master_dark));
711  cpl_propertylist_set_comment(ps.phupaf,"REF_DARK",
712  "Reference dark used");
713  }
714  vircam_dfs_set_product_primary_header(plist,product_frame_mean_dark,
715  framelist,parlist,
716  (char *)recipeid,"PRO-1.15",
717  NULL,0);
718 
719  /* 'Save' the PHU image */
720 
721  if (cpl_image_save(NULL,outfile,CPL_TYPE_UCHAR,plist,
722  CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
723  cpl_msg_error(fctid,"Cannot save product PHU");
724  cpl_frame_delete(product_frame_mean_dark);
725  return(-1);
726  }
727  cpl_frameset_insert(framelist,product_frame_mean_dark);
728 
729  /* Create a new product frame object for the difference image */
730 
731  if (we_expect & DIFFIMG) {
732  product_frame_diffimg = cpl_frame_new();
733  cpl_frame_set_filename(product_frame_diffimg,outdiff);
734  cpl_frame_set_tag(product_frame_diffimg,VIRCAM_PRO_DIFFIMG_DARK);
735  cpl_frame_set_type(product_frame_diffimg,CPL_FRAME_TYPE_IMAGE);
736  cpl_frame_set_group(product_frame_diffimg,CPL_FRAME_GROUP_PRODUCT);
737  cpl_frame_set_level(product_frame_diffimg,CPL_FRAME_LEVEL_FINAL);
738 
739  /* Base the header on the first image in the input framelist */
740 
741  plist = vircam_fits_get_phu(ps.darks[0]);
742  vircam_dfs_set_product_primary_header(plist,product_frame_diffimg,
743  framelist,parlist,
744  (char *)recipeid,
745  "PRO-1.15",NULL,0);
746 
747  /* 'Save' the PHU image */
748 
749  if (cpl_image_save(NULL,outdiff,CPL_TYPE_UCHAR,plist,
750  CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
751  cpl_msg_error(fctid,"Cannot save product PHU");
752  cpl_frame_delete(product_frame_diffimg);
753  return(-1);
754  }
755  cpl_frameset_insert(framelist,product_frame_diffimg);
756  }
757 
758  /* Create a new product frame object for the difference image stats
759  table */
760 
761  if (we_expect & STATS_TAB) {
762  product_frame_diffimg_stats = cpl_frame_new();
763  cpl_frame_set_filename(product_frame_diffimg_stats,outdimst);
764  cpl_frame_set_tag(product_frame_diffimg_stats,
765  VIRCAM_PRO_DIFFIMG_DARK_STATS);
766  cpl_frame_set_type(product_frame_diffimg_stats,
767  CPL_FRAME_TYPE_TABLE);
768  cpl_frame_set_group(product_frame_diffimg_stats,
769  CPL_FRAME_GROUP_PRODUCT);
770  cpl_frame_set_level(product_frame_diffimg_stats,
771  CPL_FRAME_LEVEL_FINAL);
772 
773  /* Base the header on the first image in the input framelist */
774 
775  plist = vircam_fits_get_phu(ps.darks[0]);
777  product_frame_diffimg_stats,
778  framelist,parlist,
779  (char *)recipeid,
780  "PRO-1.15",NULL,0);
781 
782  /* Fiddle with the extension header now */
783 
784  elist = vircam_fits_get_ehu(ps.darks[0]);
785  p = cpl_propertylist_duplicate(elist);
786  vircam_merge_propertylists(p,ps.drs);
787  if (! (we_get & STATS_TAB))
789  vircam_dfs_set_product_exten_header(p,product_frame_diffimg_stats,
790  framelist,parlist,
791  (char *)recipeid,
792  "PRO-1.15",NULL);
793  status = VIR_OK;
794  vircam_removewcs(p,&status);
795 
796  /* And finally save the difference image stats table */
797 
798  if (cpl_table_save(ps.diffimstats,plist,p,outdimst,
799  CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
800  cpl_msg_error(fctid,"Cannot save product table extension");
801  cpl_frame_delete(product_frame_diffimg_stats);
802  cpl_propertylist_delete(p);
803  return(-1);
804  }
805  cpl_propertylist_delete(p);
806  cpl_frameset_insert(framelist,product_frame_diffimg_stats);
807  }
808  }
809 
810  /* Get the extension property list */
811 
812  plist = vircam_fits_get_ehu(ps.darks[0]);
813  cpl_propertylist_update_int(plist,"ESO PRO DATANCOM",ps.ngood);
814 
815  /* Fiddle with the header now */
816 
817  vircam_merge_propertylists(plist,ps.drs);
818  p = cpl_propertylist_duplicate(plist);
819  if (! (we_get & MEANDARK))
821  vircam_dfs_set_product_exten_header(p,product_frame_mean_dark,
822  framelist,parlist,
823  (char *)recipeid,"PRO-1.15",NULL);
824 
825  /* Now save the mean dark image extension */
826 
827  cpl_propertylist_update_float(p,"ESO QC DARKMED",
828  vircam_dark_combine_config.darkmed);
829  cpl_propertylist_set_comment(p,"ESO QC DARKMED",
830  "Median of mean dark frame");
831  cpl_propertylist_update_float(p,"ESO QC DARKRMS",
832  vircam_dark_combine_config.darkrms);
833  cpl_propertylist_set_comment(p,"ESO QC DARKRMS",
834  "RMS of mean dark frame");
835  cpl_propertylist_update_float(p,"ESO QC PARTICLE_RATE",
836  vircam_dark_combine_config.particle_rate);
837  cpl_propertylist_set_comment(p,"ESO QC PARTICLE_RATE",
838  "[N/(detector*sec)] Particle rate");
839  cpl_propertylist_update_float(p,"ESO QC STRIPERMS",
840  vircam_dark_combine_config.striperms);
841  cpl_propertylist_set_comment(p,"ESO QC STRIPERMS","RMS of stripe pattern");
842  cpl_propertylist_update_int(p,"ESO QC NHOTPIX",
843  vircam_dark_combine_config.nhot);
844  cpl_propertylist_set_comment(p,"ESO QC NHOTPIX","Number of hot pixels");
845  cpl_propertylist_update_float(p,"ESO QC HOTFRAC",
846  vircam_dark_combine_config.hotfrac);
847  cpl_propertylist_set_comment(p,"ESO QC HOTFRAC","Hot pixel fraction");
848  cpl_propertylist_update_float(p,"ESO QC RON12",
849  vircam_dark_combine_config.ron12);
850  cpl_propertylist_set_comment(p,"ESO QC RON12",
851  "[ADU] Estimate of readnoise + stripe RMS");
852  if (cpl_image_save(ps.outimage,outfile,CPL_TYPE_FLOAT,p,
853  CPL_IO_EXTEND) != CPL_ERROR_NONE) {
854  cpl_msg_error(fctid,"Cannot save product image extension");
855  cpl_propertylist_delete(p);
856  return(-1);
857  }
858 
859  /* Write out PAF for mean image */
860 
861  pafprop = vircam_paf_req_items(p);
862  vircam_merge_propertylists(pafprop,ps.phupaf);
863  vircam_paf_append(pafprop,p,"ESO DET NDIT");
864  vircam_paf_append(pafprop,p,"ESO PRO CATG");
865  vircam_paf_append(pafprop,p,"ESO PRO DATANCOM");
866  if (vircam_paf_print((char *)outfilepaf,"VIRCAM/vircam_dark_combine",
867  "QC file",pafprop) != VIR_OK)
868  cpl_msg_warning(fctid,"Unable to save PAF for mean dark");
869  cpl_propertylist_delete(pafprop);
870  cpl_propertylist_delete(p);
871 
872  /* Now save the dark difference image extension */
873 
874  if (we_expect & DIFFIMG) {
875  p = cpl_propertylist_duplicate(plist);
876  if (! (we_get & DIFFIMG))
878  cpl_propertylist_update_float(p,"ESO QC DARKDIFF_MED",
879  vircam_dark_combine_config.darkdiff_med);
880  cpl_propertylist_set_comment(p,"ESO QC DARKDIFF_MED",
881  "Median of dark difference image");
882  cpl_propertylist_update_float(p,"ESO QC DARKDIFF_RMS",
883  vircam_dark_combine_config.darkdiff_rms);
884  cpl_propertylist_set_comment(p,"ESO QC DARKDIFF_RMS",
885  "RMS of dark difference image");
886  vircam_dfs_set_product_exten_header(p,product_frame_diffimg,
887  framelist,parlist,
888  (char *)recipeid,
889  "PRO-1.15",NULL);
890  if (cpl_image_save(ps.diffimg,outdiff,CPL_TYPE_FLOAT,p,
891  CPL_IO_EXTEND) != CPL_ERROR_NONE) {
892  cpl_msg_error(fctid,"Cannot save product image extension");
893  cpl_propertylist_delete(p);
894  return(-1);
895  }
896 
897  /* Now write PAF for difference image */
898 
899  pafprop = vircam_paf_req_items(p);
900  vircam_paf_append(pafprop,p,"ESO PRO CATG");
901  vircam_merge_propertylists(pafprop,ps.phupaf);
902  if (vircam_paf_print((char *)outdiffpaf,"VIRCAM/vircam_dark_combine",
903  "QC file",pafprop) != VIR_OK)
904  cpl_msg_warning(fctid,"Unable to save PAF for difference image");
905  cpl_propertylist_delete(pafprop);
906  cpl_propertylist_delete(p);
907  }
908 
909  /* Now any further difference image stats tables */
910 
911  if (! isfirst && (we_expect & STATS_TAB)) {
912  p = cpl_propertylist_duplicate(plist);
913  if (! (we_get & STATS_TAB))
915  vircam_dfs_set_product_exten_header(p,product_frame_diffimg_stats,
916  framelist,parlist,
917  (char *)recipeid,
918  "PRO-1.15",NULL);
919  status = VIR_OK;
920  vircam_removewcs(p,&status);
921  if (cpl_table_save(ps.diffimstats,NULL,p,outdimst,CPL_IO_EXTEND)
922  != CPL_ERROR_NONE) {
923  cpl_msg_error(fctid,"Cannot save product table extension");
924  cpl_propertylist_delete(p);
925  return(-1);
926  }
927  cpl_propertylist_delete(p);
928  }
929 
930  return(0);
931 }
932 
933 /*---------------------------------------------------------------------------*/
937 /*---------------------------------------------------------------------------*/
938 
939 static void vircam_dark_combine_dummy_products(void) {
940 
941  /* See if you even need to be here */
942 
943  if (we_get == we_expect)
944  return;
945 
946  /* We always expect a mean frame. If we don't have one, then create
947  a dummy */
948 
949  if (! (we_get & MEANDARK)) {
950  ps.outimage = vircam_dummy_image(ps.darks[0]);
951 
952  /* Set up the QC parameters */
953 
954  vircam_dark_combine_config.particle_rate = 0.0;
955  vircam_dark_combine_config.darkmed = 0.0;
956  vircam_dark_combine_config.darkrms = 0.0;
957  vircam_dark_combine_config.nhot = 0;
958  vircam_dark_combine_config.hotfrac = 0.0;
959  vircam_dark_combine_config.striperms = 0.0;
960  vircam_dark_combine_config.ron12 = 0.0;
961  }
962 
963  /* Do the difference image */
964 
965  if ((we_expect & DIFFIMG) && ! (we_get & DIFFIMG)) {
966  vircam_dark_combine_config.darkdiff_med = 0.0;
967  vircam_dark_combine_config.darkdiff_rms = 0.0;
968  ps.diffimg = vircam_dummy_image(ps.darks[0]);
969  }
970 
971  /* If a difference image stats table is required, then do that now */
972 
973  if ((we_expect & STATS_TAB) && ! (we_get & STATS_TAB))
974  ps.diffimstats = vircam_create_diffimg_stats(0);
975 
976  return;
977 }
978 
979 /*---------------------------------------------------------------------------*/
983 /*---------------------------------------------------------------------------*/
984 
985 static void vircam_dark_combine_hotpix(void) {
986  int i,nx,ny,status,nh,nhot,j;
987  long npts;
988  cpl_image *im;
989  unsigned char *bpm;
990  float med,mad,lowcut,highcut,*data;
991  vir_fits *f;
992 
993  /* Get some workspace to hold the bad pixel mask */
994 
995  im = vircam_fits_get_image(ps.good[0]);
996  nx = (int)cpl_image_get_size_x(im);
997  ny = (int)cpl_image_get_size_y(im);
998  npts = (long)(nx*ny);
999  bpm = cpl_calloc(npts,sizeof(*bpm));
1000 
1001  /* Create a difference image for each of the good frames and
1002  destripe it. */
1003 
1004  for (i = 0; i < ps.ngood; i++) {
1005  f = vircam_fits_duplicate(ps.good[i]);
1006  im = vircam_fits_get_image(f);
1007  cpl_image_subtract(im,ps.outimage);
1008  status = VIR_OK;
1009  vircam_destripe(f,NULL,&status);
1010  if (i == 0) {
1011  vircam_dark_combine_config.striperms =
1012  cpl_propertylist_get_float(vircam_fits_get_ehu(f),
1013  "ESO DRS STRIPERMS");
1014  }
1015 
1016  /* Work out the stats of the difference image. Define a lower and
1017  upper cut. NB: a lower cut is needed since we are doing stats
1018  on a difference image and hot pixels will appear as either
1019  bright or dark. Dead pixels will probably correct properly and
1020  hence shouldn't be flagged using this procedure. */
1021 
1022  data = cpl_image_get_data_float(im);
1023  vircam_medmad(data,NULL,npts,&med,&mad);
1024  lowcut = med - 1.48*mad*vircam_dark_combine_config.thresh;
1025  highcut = med + 1.48*mad*vircam_dark_combine_config.thresh;
1026  for (j = 0; j < npts; j++)
1027  if (data[j] > highcut || data[j] < lowcut)
1028  bpm[j] += 1;
1029 
1030  /* Get rid of temporary image */
1031 
1032  vircam_fits_delete(f);
1033  }
1034 
1035  /* Define a pixel as hot so long as it is discordant on at least half of
1036  the frames */
1037 
1038  nh = (ps.ngood + 1)/2;
1039  nhot = 0;
1040  for (j = 0; j < npts; j++)
1041  if (bpm[j] >= nh)
1042  nhot++;
1043 
1044  /* Do a difference image of the first two darks and work out the RMS */
1045 
1046  im = cpl_image_subtract_create(vircam_fits_get_image(ps.good[0]),
1047  vircam_fits_get_image(ps.good[1]));
1048  data = cpl_image_get_data_float(im);
1049  vircam_medmad(data,bpm,npts,&med,&mad);
1050  mad *= 1.48/CPL_MATH_SQRT2;
1051  vircam_dark_combine_config.ron12 = mad;
1052  cpl_image_delete(im);
1053 
1054  /* Clean up... */
1055 
1056  cpl_free(bpm);
1057 
1058  /* Set QC parameters */
1059 
1060  vircam_dark_combine_config.nhot = nhot;
1061  vircam_dark_combine_config.hotfrac = (float)nhot/(float)npts;
1062 }
1063 
1064 
1065 /*---------------------------------------------------------------------------*/
1071 /*---------------------------------------------------------------------------*/
1072 
1073 static void vircam_dark_combine_normal(int jext, float exptime) {
1074  int nx,ny,ndiff,ncells;
1075  long npi,i;
1076  unsigned char *bpm;
1077  float med,sig,*idata,grms,gdiff;
1078  const char *fctid="vircam_dark_combine_normal";
1079  cpl_table *ctable;
1080  cpl_propertylist *p;
1081 
1082  /* Load up the bad pixel mask */
1083 
1084  nx = (int)cpl_image_get_size_x(ps.outimage);
1085  ny = (int)cpl_image_get_size_y(ps.outimage);
1086  npi = nx*ny;
1087  vircam_dark_combine_config.particle_rate = 0;
1088  bpm = vircam_mask_get_data(ps.master_mask);
1089 
1090  /* Now find out how many 'good' pixels were rejected for
1091  being too high during the combination phase */
1092 
1093  ndiff = 0;
1094  for (i = 0; i < npi; i++)
1095  if ((ps.rejplus)[i] > 0 && bpm[i] == 0)
1096  ndiff += (ps.rejplus)[i];
1097  vircam_dark_combine_config.particle_rate =
1098  (float)ndiff/(exptime*(float)(ps.ndarks));
1099 
1100  /* Work out the RMS of the mean dark frame */
1101 
1102  idata = cpl_image_get_data(ps.outimage);
1103  vircam_medmad(idata,bpm,npi,&med,&sig);
1104  sig *= 1.48;
1105  vircam_dark_combine_config.darkmed = med;
1106  vircam_dark_combine_config.darkrms = sig;
1107 
1108  /* Load up the master dark */
1109 
1110  if (ps.master_dark != NULL) {
1111  ps.mdimage = vircam_fits_load(ps.master_dark,CPL_TYPE_FLOAT,jext);
1112  if (ps.mdimage == NULL)
1113  cpl_msg_info(fctid,
1114  "Master dark extension %" CPL_SIZE_FORMAT " won't load",
1115  (cpl_size)jext);
1116  else if (vircam_is_dummy(vircam_fits_get_ehu(ps.mdimage))) {
1117  cpl_msg_info(fctid,
1118  "Master dark extension %" CPL_SIZE_FORMAT " is a dummy!",
1119  (cpl_size)jext);
1120  freefits(ps.mdimage);
1121  }
1122  } else
1123  ps.mdimage = NULL;
1124 
1125  /* Load up the channel table */
1126 
1127  if (ps.chantab != NULL) {
1128  ctable = cpl_table_load(cpl_frame_get_filename(ps.chantab),jext,0);
1129  if (ctable == NULL) {
1130  cpl_error_reset();
1131  cpl_msg_info(fctid,
1132  "Channel table extension %" CPL_SIZE_FORMAT " won't load",
1133  (cpl_size)jext);
1134  } else if (vircam_chantab_verify(ctable) != VIR_OK) {
1135  cpl_msg_info(fctid,
1136  "Channel table extension %" CPL_SIZE_FORMAT " has errors",
1137  (cpl_size)jext);
1138  freetable(ctable);
1139  } else {
1140  p = cpl_propertylist_load(cpl_frame_get_filename(ps.chantab),
1141  (cpl_size)jext);
1142  if (vircam_is_dummy(p)) {
1143  cpl_msg_info(fctid,
1144  "Channel table extensions %" CPL_SIZE_FORMAT " is a dummy",
1145  (cpl_size)jext);
1146  freetable(ctable);
1147  }
1148  freepropertylist(p);
1149  }
1150  } else
1151  ctable = NULL;
1152 
1153  /* Form the difference image. NB: the difference image routine
1154  copes if the input mean image and or the channel tables are
1155  null. Thus if either or both are null because of a failure
1156  to load then the routine will do as much as it can and return
1157  allowing you to fill in the rest with dummy products */
1158 
1159  vircam_dark_combine_config.darkdiff_med = 0.0;
1160  vircam_dark_combine_config.darkdiff_rms = 0.0;
1161  ncells = vircam_dark_combine_config.ncells;
1163  ps.outimage,bpm,ctable,ncells,1,
1164  &gdiff,&grms,&(ps.diffimg),
1165  &(ps.diffimstats));
1166  vircam_mask_clear(ps.master_mask);
1167  vircam_dark_combine_config.darkdiff_med = gdiff;
1168  vircam_dark_combine_config.darkdiff_rms = grms;
1169  freetable(ctable);
1170  if (ps.diffimg != NULL)
1171  we_get |= DIFFIMG;
1172  if (ps.diffimstats != NULL)
1173  we_get |= STATS_TAB;
1174  return;
1175 }
1176 
1177 /*---------------------------------------------------------------------------*/
1185 /*---------------------------------------------------------------------------*/
1186 
1187 static int vircam_dark_combine_lastbit(int jext, cpl_frameset *framelist,
1188  cpl_parameterlist *parlist) {
1189  int retval;
1190  const char *fctid="vircam_dark_combine_lastbit";
1191 
1192  /* Make whatever dummy products you need */
1193 
1194  vircam_dark_combine_dummy_products();
1195 
1196  /* Save everything */
1197 
1198  cpl_msg_info(fctid,"Saving products for extension %" CPL_SIZE_FORMAT,
1199  (cpl_size)jext);
1200  retval = vircam_dark_combine_save(framelist,parlist);
1201  if (retval != 0) {
1202  vircam_dark_combine_tidy(2);
1203  return(-1);
1204  }
1205 
1206  /* Free some stuff up */
1207 
1208  vircam_dark_combine_tidy(1);
1209  return(0);
1210 }
1211 
1212 /*---------------------------------------------------------------------------*/
1216 /*---------------------------------------------------------------------------*/
1217 
1218 static void vircam_dark_combine_init(void) {
1219  ps.labels = NULL;
1220  ps.darklist = NULL;
1221  ps.darks = NULL;
1222  ps.ndarks = 0;
1223  ps.good = NULL;
1224  ps.ngood = 0;
1225  ps.master_dark = NULL;
1226  ps.master_mask = NULL;
1227  ps.chantab = NULL;
1228  ps.outimage = NULL;
1229  ps.drs = NULL;
1230  ps.rejmask = NULL;
1231  ps.rejplus = NULL;
1232  ps.mdimage = NULL;
1233  ps.diffimg = NULL;
1234  ps.diffimstats = NULL;
1235  ps.phupaf = NULL;
1236  we_expect = 0;
1237  we_get = 0;
1238 }
1239 
1240 /*---------------------------------------------------------------------------*/
1244 /*---------------------------------------------------------------------------*/
1245 
1246 static void vircam_dark_combine_tidy(int level) {
1247 
1248  freeimage(ps.outimage);
1249  freefitslist(ps.darks,ps.ndarks);
1250  freepropertylist(ps.drs);
1251  freefits(ps.mdimage);
1252  freeimage(ps.diffimg);
1253  freetable(ps.diffimstats);
1254  freespace(ps.rejmask);
1255  freespace(ps.rejplus);
1256  if (level == 1)
1257  return;
1258  freespace(ps.labels);
1259  freeframeset(ps.darklist);
1260  freespace(ps.good);
1261  freeframe(ps.master_dark);
1262  freemask(ps.master_mask);
1263  freeframe(ps.chantab);
1264  freepropertylist(ps.phupaf);
1265 }
1266 
1269 /*
1270 
1271 $Log: not supported by cvs2svn $
1272 Revision 1.69 2012/01/15 17:40:09 jim
1273 Minor modifications to take into accout the changes in cpl API for v6
1274 
1275 Revision 1.68 2011/05/09 09:58:10 jim
1276 Cosmetic changes to stop compiler warnings
1277 
1278 Revision 1.67 2010/09/10 11:25:39 jim
1279 Removed some unnecessary declarations
1280 
1281 Revision 1.66 2010/09/09 12:14:05 jim
1282 Does a difference image of the first two darks to get an estimate of the
1283 readnoise in ADU. Also estimates stripe RMS from the difference image
1284 
1285 Revision 1.65 2010/03/21 06:48:21 jim
1286 Fixed bug where DATANCOM wasn't being updated in all products
1287 
1288 Revision 1.64 2010/03/09 14:27:40 jim
1289 Now updates ESO PRO DATANCOM to reflect the number of images used
1290 
1291 Revision 1.63 2010/02/05 09:42:22 jim
1292 Fixed call to non-existent cpl routine
1293 
1294 Revision 1.62 2010/01/31 18:52:43 jim
1295 Reference dark image written to paf
1296 
1297 Revision 1.61 2009/09/09 09:50:21 jim
1298 Modified to try and get headers right
1299 
1300 Revision 1.60 2008/12/05 13:28:32 jim
1301 Fixed save routine so that the correct version of PRO CATG is written to the
1302 paf file
1303 
1304 Revision 1.59 2008/10/01 04:59:13 jim
1305 Added call to vircam_frameset_fexists to check input frameset
1306 
1307 Revision 1.58 2008/09/30 11:33:23 jim
1308 Added PRO CATG to pafs
1309 
1310 Revision 1.57 2007/10/19 09:25:09 jim
1311 Fixed problems with missing includes
1312 
1313 Revision 1.56 2007/10/15 12:53:26 jim
1314 Modified for compatibiliity with cpl_4.0
1315 
1316 Revision 1.55 2007/07/18 15:35:41 jim
1317 Added better error handling for missing or corrupt mask extensions
1318 
1319 Revision 1.54 2007/07/09 13:21:37 jim
1320 Modified to use new vircam_exten_range and to fix comment on particle_rate
1321 QC parameter
1322 
1323 Revision 1.53 2007/04/30 09:40:17 jim
1324 Added more stuff to paf files
1325 
1326 Revision 1.52 2007/04/04 10:36:18 jim
1327 Modified to use new dfs tags
1328 
1329 Revision 1.51 2007/03/29 12:19:38 jim
1330 Little changes to improve documentation
1331 
1332 Revision 1.50 2007/03/02 12:37:16 jim
1333 Removed WCS stuff from table headers
1334 
1335 Revision 1.49 2007/03/01 12:41:48 jim
1336 Modified slightly after code checking
1337 
1338 Revision 1.48 2007/02/25 06:26:35 jim
1339 Plugged a few memory leaks
1340 
1341 Revision 1.47 2007/02/19 10:03:02 jim
1342 Fixed small memory leak
1343 
1344 Revision 1.46 2007/02/15 12:17:33 jim
1345 Fixed typo
1346 
1347 Revision 1.45 2007/02/15 11:54:09 jim
1348 Modified to make a distinction between initial channel table and one that
1349 has the proper linearity information
1350 
1351 Revision 1.44 2007/02/15 06:59:37 jim
1352 Added ability to write QC paf files
1353 
1354 Revision 1.43 2007/02/09 14:49:05 jim
1355 Added QC parameter NHOTPIX and HOTFRAC and routine vircam_dark_combine_hotpix
1356 
1357 Revision 1.42 2007/02/07 10:12:39 jim
1358 Removed calls to vircam_ndit_correct as this is now no longer necessary
1359 
1360 Revision 1.41 2007/02/06 13:11:11 jim
1361 Fixed entry for PRO dictionary in cpl_dfs_set_product_header
1362 
1363 Revision 1.40 2007/02/05 14:14:05 jim
1364 Input master frame is now tagged as REFERENCE. QC removed from stats table
1365 headers
1366 
1367 Revision 1.39 2006/12/13 13:14:38 jim
1368 Fixed badly scaled sigma
1369 
1370 Revision 1.38 2006/12/12 11:30:13 jim
1371 Added QC STRIPERMS calculation
1372 
1373 Revision 1.37 2006/11/27 12:13:21 jim
1374 Swapped calls to cpl_propertylist_append to cpl_propertylist_update
1375 
1376 Revision 1.36 2006/09/29 11:19:30 jim
1377 changed aliases on parameter names
1378 
1379 Revision 1.35 2006/09/09 16:49:39 jim
1380 Header comment update
1381 
1382 Revision 1.34 2006/08/27 20:30:02 jim
1383 Major mods to structure of the main processing routine to deal with missing
1384 and dummy frames. Deals better with lower level failures too
1385 
1386 Revision 1.33 2006/06/20 19:07:00 jim
1387 Corrects for ndit != 1
1388 
1389 Revision 1.32 2006/06/15 09:58:57 jim
1390 Minor changes to docs
1391 
1392 Revision 1.31 2006/06/06 13:01:39 jim
1393 Fixed so that the QC parameters go into the correct headers
1394 
1395 Revision 1.30 2006/05/17 14:43:58 jim
1396 Fixed problem in save routine which messed up the PRO CATG keywords
1397 
1398 Revision 1.29 2006/05/16 13:58:47 jim
1399 Fixed memory leaks that occur from not closing images at the end of
1400 the image extension loop
1401 
1402 Revision 1.28 2006/05/04 11:53:14 jim
1403 Fixed the way the _save routine works to be more consistent with the
1404 standard CPL way of doing things
1405 
1406 Revision 1.27 2006/04/27 09:46:01 jim
1407 Modified DFS frame types to conform to new dictionary
1408 
1409 Revision 1.26 2006/04/25 13:45:56 jim
1410 Fixed to adhere to new calling sequence for vircam_dfs routines
1411 
1412 Revision 1.25 2006/04/24 13:46:35 jim
1413 A bit more error trapping in case fits structures can't be loaded
1414 
1415 Revision 1.24 2006/03/22 12:13:51 jim
1416 Modified to use new vircam_mask capability
1417 
1418 Revision 1.23 2006/03/15 10:43:40 jim
1419 Fixed a few things
1420 
1421 Revision 1.22 2006/03/08 14:32:35 jim
1422 Lots of little mods
1423 
1424 Revision 1.21 2006/03/03 14:29:06 jim
1425 Now calls routines with vir_fits.
1426 
1427 Revision 1.19 2006/02/27 14:05:07 jim
1428 Fixed screwup
1429 
1430 Revision 1.18 2006/02/27 13:51:17 jim
1431 new routine
1432 
1433 Revision 1.17 2006/02/22 10:01:38 jim
1434 Modified to use new version of vircam_imcombine
1435 
1436 Revision 1.16 2006/02/18 11:50:43 jim
1437 Modified the way the dfs product keywords are written using the vircam
1438 routines, rather than the cpl routine that doesn't understand image
1439 extensions
1440 
1441 Revision 1.15 2006/01/23 10:35:21 jim
1442 Now allows both BPM or CPM to be used for masking
1443 
1444 Revision 1.14 2005/12/14 22:19:11 jim
1445 fixed docs
1446 
1447 Revision 1.13 2005/12/12 14:16:20 jim
1448 Fixed typo that caused compilation error
1449 
1450 Revision 1.12 2005/12/09 09:47:57 jim
1451 Many changes to add more documentation
1452 
1453 Revision 1.11 2005/12/02 10:45:37 jim
1454 The tags used in the sof are now written to the description string in the
1455 constructor. This is so that if they change in the vircam_dfs.h file, they
1456 aren't then hardcopied into each of the recipes...
1457 
1458 Revision 1.10 2005/12/01 16:25:48 jim
1459 Made the routine a bit more forgiving if certain master calibration files
1460 were missing. Now does as much as it can with the info it has
1461 
1462 Revision 1.9 2005/11/25 09:56:14 jim
1463 Tidied up some more documentation
1464 
1465 Revision 1.8 2005/11/23 14:57:40 jim
1466 A bit of tidying in response to splint messages
1467 
1468 Revision 1.7 2005/11/08 12:47:44 jim
1469 Made garbage collection a little better
1470 
1471 Revision 1.6 2005/11/07 13:14:41 jim
1472 Added better garbage collection and fixed a few bugs
1473 
1474 Revision 1.5 2005/11/03 15:16:28 jim
1475 Lots of changes mainly to strengthen error reporting
1476 
1477 Revision 1.4 2005/10/14 13:22:12 jim
1478 Added lots of QC checking and diagnostics, so it pretty much does what the
1479 docs say it should
1480 
1481 Revision 1.3 2005/09/20 15:07:45 jim
1482 Fixed a few bugs and added a few things
1483 
1484 Revision 1.2 2005/08/09 10:24:37 jim
1485 Replaced dodgy calls to cpl_msg_err with correct cpl_msg_error
1486 
1487 Revision 1.1.1.1 2005/08/05 08:29:09 jim
1488 Initial import
1489 
1490 
1491 */
const char * vircam_get_license(void)
Definition: vircam_utils.c:92
void vircam_mask_force(vir_mask *m, int nx, int ny)
Definition: vircam_mask.c:385
int vircam_compare_tags(const cpl_frame *frame1, const cpl_frame *frame2)
Definition: vircam_utils.c:141
int vircam_chantab_verify(cpl_table *intab)
int vircam_is_dummy(cpl_propertylist *p)
void vircam_merge_propertylists(cpl_propertylist *p1, cpl_propertylist *p2)
vir_fits ** vircam_fits_load_list(cpl_frameset *f, cpl_type type, int exten)
Definition: vircam_fits.c:231
cpl_frame * vircam_frameset_subgroup_1(cpl_frameset *frameset, cpl_size *labels, cpl_size nlab, const char *tag)
Definition: vircam_utils.c:247
void vircam_mask_clear(vir_mask *m)
Definition: vircam_mask.c:349
cpl_image * vircam_dummy_image(vir_fits *model)
int vircam_pfits_get_exptime(const cpl_propertylist *plist, float *exptime)
Get the value of exposure time.
Definition: vircam_pfits.c:245
void vircam_fits_delete(vir_fits *p)
Definition: vircam_fits.c:277
int vircam_mask_load(vir_mask *m, int nexten, int nx, int ny)
Definition: vircam_mask.c:210
char * vircam_fits_get_fullname(vir_fits *p)
Definition: vircam_fits.c:560
int vircam_destripe(vir_fits *in, vir_mask *inbpm, int *status)
Remove stripes from the background of an image.
unsigned char * vircam_mask_get_data(vir_mask *m)
Definition: vircam_mask.c:535
cpl_image * vircam_fits_get_image(vir_fits *p)
Definition: vircam_fits.c:349
cpl_table * vircam_create_diffimg_stats(int nrows)
cpl_frameset * vircam_frameset_subgroup(cpl_frameset *frameset, cpl_size *labels, cpl_size nlab, const char *tag)
Definition: vircam_utils.c:193
void vircam_dfs_set_product_exten_header(cpl_propertylist *plist, cpl_frame *frame, cpl_frameset *frameset, cpl_parameterlist *parlist, char *recipeid, const char *dict, cpl_frame *inherit)
Definition: vircam_dfs.c:273
void vircam_dfs_set_product_primary_header(cpl_propertylist *plist, cpl_frame *frame, cpl_frameset *frameset, cpl_parameterlist *parlist, char *recipeid, const char *dict, cpl_frame *inherit, int synch)
Definition: vircam_dfs.c:203
int vircam_fits_set_error(vir_fits *p, int status)
Definition: vircam_fits.c:627
void vircam_medmad(float *data, unsigned char *bpm, long np, float *med, float *mad)
Definition: vircam_stats.c:625
vir_fits * vircam_fits_duplicate(vir_fits *in)
Definition: vircam_fits.c:159
void vircam_dummy_property(cpl_propertylist *p)
cpl_propertylist * vircam_fits_get_phu(vir_fits *p)
Definition: vircam_fits.c:416
vir_fits * vircam_fits_load(cpl_frame *frame, cpl_type type, int nexten)
Definition: vircam_fits.c:80
cpl_propertylist * vircam_fits_get_ehu(vir_fits *p)
Definition: vircam_fits.c:457
int vircam_frameset_fexists(cpl_frameset *frameset)
Definition: vircam_utils.c:285
const char * vircam_mask_get_filename(vir_mask *m)
Definition: vircam_mask.c:438
vir_mask * vircam_mask_define(cpl_frameset *framelist, cpl_size *labels, cpl_size nlab)
Definition: vircam_mask.c:86
int vircam_pfits_get_detlive(const cpl_propertylist *plist, int *detlive)
Get the value of DET_LIVE.
Definition: vircam_pfits.c:624
int vircam_imcombine(vir_fits **fset, int nfits, int combtype, int scaletype, int xrej, float thresh, cpl_image **outimage, unsigned char **rejmask, unsigned char **rejplus, cpl_propertylist **drs, int *status)
Stack images into a mean or median image with rejection.
void vircam_exten_range(int inexten, const cpl_frame *fr, int *out1, int *out2)
Definition: vircam_utils.c:353
void vircam_difference_image(cpl_image *master, cpl_image *prog, unsigned char *bpm, cpl_table *chantab, int ncells, int oper, float *global_diff, float *global_rms, cpl_image **diffim, cpl_table **diffimstats)
Definition: vircam_utils.c:950
int vircam_removewcs(cpl_propertylist *p, int *status)
int vircam_dfs_set_groups(cpl_frameset *set)
Definition: vircam_dfs.c:87