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