vircam_reset_combine.c

00001 /* $Id: vircam_reset_combine.c,v 1.58 2010/03/21 06:48:21 jim Exp $
00002  *
00003  * This file is part of the VIRCAM Pipeline
00004  * Copyright (C) 2005 Cambridge Astronomy Survey Unit
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: jim $
00023  * $Date: 2010/03/21 06:48:21 $
00024  * $Revision: 1.58 $
00025  * $Name: v1-1-0 $
00026  */
00027 
00028 /* Includes */
00029 
00030 #ifdef HAVE_CONFIG_H
00031 #include <config.h>
00032 #endif
00033 
00034 #include <stdio.h>
00035 #include <cpl.h>
00036 #include <math.h>
00037 
00038 #include "vircam_utils.h"
00039 #include "vircam_mask.h"
00040 #include "vircam_dfs.h"
00041 #include "vircam_mods.h"
00042 #include "vircam_stats.h"
00043 #include "vircam_fits.h"
00044 #include "vircam_pfits.h"
00045 #include "vircam_channel.h"
00046 #include "vircam_paf.h"
00047 #include "vircam_wcsutils.h"
00048 
00049 /* Define values for the bit mask that flags dummy results */
00050 
00051 #define MEANRESET    1
00052 #define DIFFIMG      2
00053 #define STATS_TAB    4
00054 
00055 /* Function prototypes */
00056 
00057 static int vircam_reset_combine_create(cpl_plugin *) ;
00058 static int vircam_reset_combine_exec(cpl_plugin *) ;
00059 static int vircam_reset_combine_destroy(cpl_plugin *) ;
00060 static int vircam_reset_combine(cpl_parameterlist *, cpl_frameset *) ;
00061 static int vircam_reset_combine_save(cpl_frameset *framelist, 
00062                                      cpl_parameterlist *parlist);
00063 static void vircam_reset_combine_dummy_products(void);
00064 static void vircam_reset_combine_normal(int jext);
00065 static int vircam_reset_combine_lastbit(int jext, cpl_frameset *framelist,
00066                                         cpl_parameterlist *parlist);
00067 static void vircam_reset_combine_init(void);
00068 static void vircam_reset_combine_tidy(int level);
00069 
00070 /* Static global variables */
00071 
00072 static struct {
00073 
00074     /* Input */
00075 
00076     int         combtype;
00077     int         scaletype;
00078     int         xrej;
00079     float       thresh;
00080     int         ncells;
00081     int         extenum;
00082 
00083     /* Output */
00084 
00085     float       resetmed;
00086     float       resetrms;
00087     float       resetdiff_med;
00088     float       resetdiff_rms;
00089 
00090 } vircam_reset_combine_config ;
00091 
00092 static struct {
00093     int              *labels;
00094     cpl_frameset     *resetlist;
00095     vir_fits         **resets;
00096     int              nresets;
00097     vir_fits         **good;
00098     int              ngood;
00099     cpl_frame        *master_reset;
00100     vir_mask         *master_mask;
00101     cpl_frame        *chantab;
00102     cpl_image        *outimage;
00103     cpl_propertylist *drs;
00104     unsigned char    *rejmask;
00105     unsigned char    *rejplus;
00106     vir_fits         *mrimage;
00107     cpl_image        *diffimg;
00108     cpl_table        *diffimstats;
00109     cpl_propertylist *phupaf;
00110 } ps;
00111 
00112 static int isfirst;
00113 static cpl_frame *product_frame_mean_reset = NULL;
00114 static cpl_frame *product_frame_diffimg = NULL;
00115 static cpl_frame *product_frame_diffimg_stats = NULL;
00116 static int we_expect;
00117 static int we_get;
00118 
00119 static char vircam_reset_combine_description[] =
00120 "vircam_reset_combine -- VIRCAM reset combine recipe.\n\n"
00121 "Combine a list of reset frames into a mean reset frame. Optionally compare \n"
00122 "the output frame to a master reset frame\n\n"
00123 "The program requires the following files in the SOF:\n\n"
00124 "    Tag                   Description\n"
00125 "    -----------------------------------------------------------------------\n"
00126 "    %-21s A list of raw reset images\n"
00127 "    %-21s Optional reference reset frame\n"
00128 "    %-21s Optional master bad pixel map or\n"
00129 "    %-21s Optional master confidence map\n"
00130 "    %-21s Optional channel table or\n"
00131 "    %-21s Optional initial channel table\n"
00132 "\n"
00133 "If no master reset frame is made available, then no comparison will be done\n"
00134 "This means there will be no output difference image. If a master reset is\n"
00135 "available, but no channel table is, then a difference image will be formed\n"
00136 "but no stats will be written."
00137 "\n";
00138 
00253 /* Function code */
00254 
00255 /*---------------------------------------------------------------------------*/
00263 /*---------------------------------------------------------------------------*/
00264 
00265 int cpl_plugin_get_info(cpl_pluginlist *list) {
00266     cpl_recipe  *recipe = cpl_calloc(1,sizeof(*recipe));
00267     cpl_plugin  *plugin = &recipe->interface;
00268     char alldesc[SZ_ALLDESC];
00269     (void)snprintf(alldesc,SZ_ALLDESC,vircam_reset_combine_description,
00270                    VIRCAM_RESET_RAW,VIRCAM_REF_RESET,VIRCAM_CAL_BPM,
00271                    VIRCAM_CAL_CONF,VIRCAM_CAL_CHANTAB,VIRCAM_CAL_CHANTAB_INIT);
00272 
00273     cpl_plugin_init(plugin,
00274                     CPL_PLUGIN_API,
00275                     VIRCAM_BINARY_VERSION,
00276                     CPL_PLUGIN_TYPE_RECIPE,
00277                     "vircam_reset_combine",
00278                     "VIRCAM reset combination recipe",
00279                     alldesc,
00280                     "Jim Lewis",
00281                     "jrl@ast.cam.ac.uk",
00282                     vircam_get_license(),
00283                     vircam_reset_combine_create,
00284                     vircam_reset_combine_exec,
00285                     vircam_reset_combine_destroy);
00286 
00287     cpl_pluginlist_append(list,plugin);
00288 
00289     return(0);
00290 }
00291 
00292 /*---------------------------------------------------------------------------*/
00301 /*---------------------------------------------------------------------------*/
00302 
00303 static int vircam_reset_combine_create(cpl_plugin *plugin) {
00304     cpl_recipe      *recipe;
00305     cpl_parameter   *p;
00306 
00307     /* Get the recipe out of the plugin */
00308 
00309     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00310         recipe = (cpl_recipe *)plugin;
00311     else 
00312         return(-1);
00313 
00314     /* Create the parameters list in the cpl_recipe object */
00315 
00316     recipe->parameters = cpl_parameterlist_new();
00317 
00318     /* Fill in the parameters. First the combination type */
00319 
00320     p = cpl_parameter_new_range("vircam.vircam_reset_combine.combtype",
00321                                 CPL_TYPE_INT,
00322                                 "1 == Median,\n 2 == Mean",
00323                                 "vircam.vircam_reset_combine",
00324                                 1,1,2);
00325     cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"combtype");
00326     cpl_parameterlist_append(recipe->parameters,p);
00327 
00328     /* The requested scaling */
00329 
00330     p = cpl_parameter_new_range("vircam.vircam_reset_combine.scaletype",
00331                                 CPL_TYPE_INT,
00332                                 "0 == none,\n 1 == additive offset,\n 2 == multiplicative offset,\n 3 == exposure time scaling + additive offset",
00333                                 "vircam.vircam_reset_combine",
00334                                 1,0,3);
00335     cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"scaletype");
00336     cpl_parameterlist_append(recipe->parameters,p);
00337     
00338     /* Extra rejection cycle */
00339 
00340     p = cpl_parameter_new_value("vircam.vircam_reset_combine.xrej",
00341                                 CPL_TYPE_BOOL,
00342                                 "True if using extra rejection cycle",
00343                                 "vircam.vircam_reset_combine",
00344                                 TRUE);
00345     cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"xrej");
00346     cpl_parameterlist_append(recipe->parameters,p);
00347 
00348     /* Rejection threshold */
00349 
00350     p = cpl_parameter_new_value("vircam.vircam_reset_combine.thresh",
00351                                 CPL_TYPE_DOUBLE,
00352                                 "Rejection threshold in sigma above background",
00353                                 "vircam.vircam_reset_combine",5.0);
00354     cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"thresh");
00355     cpl_parameterlist_append(recipe->parameters,p);
00356 
00357     /* How many cells to divide each data channel */
00358 
00359     p = cpl_parameter_new_enum("vircam.vircam_reset_combine.ncells",
00360                                CPL_TYPE_INT,
00361                                "Number of cells for data channel stats",
00362                                "vircam.vircam_reset_combine",8,7,1,2,4,8,
00363                                16,32,64);
00364     cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"ncells");
00365     cpl_parameterlist_append(recipe->parameters,p);
00366 
00367     /* Extension number of input frames to use */
00368 
00369     p = cpl_parameter_new_range("vircam.vircam_reset_combine.extenum",
00370                                 CPL_TYPE_INT,
00371                                 "Extension number to be done, 0 == all",
00372                                 "vircam.vircam_reset_combine",
00373                                 1,0,16);
00374     cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"ext");
00375     cpl_parameterlist_append(recipe->parameters,p);
00376         
00377     /* Get out of here */
00378 
00379     return(0);
00380 }
00381     
00382     
00383 /*---------------------------------------------------------------------------*/
00389 /*---------------------------------------------------------------------------*/
00390 
00391 static int vircam_reset_combine_exec(cpl_plugin *plugin) {
00392     cpl_recipe  *recipe;
00393 
00394     /* Get the recipe out of the plugin */
00395 
00396     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00397         recipe = (cpl_recipe *)plugin;
00398     else 
00399         return(-1);
00400 
00401     return(vircam_reset_combine(recipe->parameters,recipe->frames));
00402 }
00403                                 
00404 /*---------------------------------------------------------------------------*/
00410 /*---------------------------------------------------------------------------*/
00411 
00412 static int vircam_reset_combine_destroy(cpl_plugin *plugin) {
00413     cpl_recipe *recipe ;
00414 
00415     /* Get the recipe out of the plugin */
00416 
00417     if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00418         recipe = (cpl_recipe *)plugin;
00419     else 
00420         return(-1);
00421 
00422     cpl_parameterlist_delete(recipe->parameters);
00423     return(0);
00424 }
00425 
00426 /*---------------------------------------------------------------------------*/
00433 /*---------------------------------------------------------------------------*/
00434 
00435 static int vircam_reset_combine(cpl_parameterlist *parlist, 
00436                                 cpl_frameset *framelist) {
00437     const char *fctid="vircam_reset_combine";
00438     int nlab,j,jst,jfn,retval,status,i,live,nx,ny;
00439     cpl_parameter *p;
00440     vir_fits *ff;
00441 
00442     /* Check validity of input frameset */
00443 
00444     if (framelist == NULL || cpl_frameset_get_size(framelist) <= 0) {
00445         cpl_msg_error(fctid,"Input framelist NULL or has no input data\n");
00446         return(-1);
00447     }
00448 
00449     /* Check the files in the frameset */
00450 
00451     if (vircam_frameset_fexists(framelist) != VIR_OK) {
00452         cpl_msg_error(fctid,"Input frameset is missing files. Check SOF");
00453         return(-1);
00454     }
00455 
00456     /* Initialise a few things */
00457 
00458     vircam_reset_combine_init();
00459     we_expect |= MEANRESET;
00460 
00461     /* Get the parameters */
00462 
00463     p = cpl_parameterlist_find(parlist,"vircam.vircam_reset_combine.combtype");
00464     vircam_reset_combine_config.combtype = cpl_parameter_get_int(p);
00465     p = cpl_parameterlist_find(parlist,"vircam.vircam_reset_combine.scaletype");
00466     vircam_reset_combine_config.scaletype = cpl_parameter_get_int(p);
00467     p = cpl_parameterlist_find(parlist,"vircam.vircam_reset_combine.xrej");
00468     vircam_reset_combine_config.xrej = cpl_parameter_get_bool(p);
00469     p = cpl_parameterlist_find(parlist,"vircam.vircam_reset_combine.thresh");
00470     vircam_reset_combine_config.thresh = (float)cpl_parameter_get_double(p);
00471     p = cpl_parameterlist_find(parlist,"vircam.vircam_reset_combine.ncells");
00472     vircam_reset_combine_config.ncells = cpl_parameter_get_int(p);
00473     p = cpl_parameterlist_find(parlist,"vircam.vircam_reset_combine.extenum");
00474     vircam_reset_combine_config.extenum = cpl_parameter_get_int(p);
00475 
00476     /* Sort out raw from calib frames */
00477 
00478     if (vircam_dfs_set_groups(framelist) != VIR_OK) {
00479         cpl_msg_error(fctid,"Cannot identify RAW and CALIB frames");
00480         return(-1);
00481     }
00482 
00483     /* Get the reset frames */
00484 
00485     if ((ps.labels = cpl_frameset_labelise(framelist,vircam_compare_tags,
00486                                            &nlab)) == NULL) {
00487         cpl_msg_error(fctid,"Cannot labelise the input frames");
00488         return(-1);
00489     }
00490     if ((ps.resetlist = vircam_frameset_subgroup(framelist,ps.labels,nlab,
00491                                                  VIRCAM_RESET_RAW)) == NULL) {
00492         cpl_msg_error(fctid,"Cannot find reset frames in input frameset");
00493         return(-1);
00494     }
00495     ps.nresets = cpl_frameset_get_size(ps.resetlist);
00496         
00497     /* Check to see if there is a master reset frame */
00498 
00499     if ((ps.master_reset = vircam_frameset_subgroup_1(framelist,ps.labels,nlab,
00500                                                       VIRCAM_REF_RESET)) == NULL) 
00501         cpl_msg_info(fctid,"No master reset found -- no difference image will be formed");
00502     else
00503         we_expect |= DIFFIMG;
00504         
00505     /* Check to see if there is a master bad pixel map. If there isn't one 
00506        then look for a confidence map */
00507 
00508     ps.master_mask = vircam_mask_define(framelist,ps.labels,nlab);
00509 
00510     /* Check to see if there is a channel table */
00511 
00512     if ((ps.chantab = vircam_frameset_subgroup_1(framelist,ps.labels,nlab,
00513                                                  VIRCAM_CAL_CHANTAB)) == NULL) {
00514         if ((ps.chantab = vircam_frameset_subgroup_1(framelist,ps.labels,nlab,
00515                                                      VIRCAM_CAL_CHANTAB_INIT)) == NULL) 
00516             cpl_msg_info(fctid,"No channel table found -- no difference image stats will be done");
00517     } else if (we_expect & DIFFIMG) 
00518             we_expect |= STATS_TAB;
00519 
00520     /* Now, how many image extensions do we want to do? If the extension
00521        number is zero, then we loop for all possible extensions. If it
00522        isn't then we just do the extension specified */
00523 
00524     vircam_exten_range(vircam_reset_combine_config.extenum,
00525                        (const cpl_frame *)cpl_frameset_get_frame(ps.resetlist,0),
00526                        &jst,&jfn);
00527     if (jst == -1 || jfn == -1) {
00528         cpl_msg_error(fctid,"Unable to continue");
00529         vircam_reset_combine_tidy(2);
00530         return(-1);
00531     }
00532 
00533     /* Get some space for the good frames */
00534 
00535     ps.good = cpl_malloc(ps.nresets*sizeof(vir_fits *));
00536 
00537     /* Now loop for all the extension... */
00538 
00539     for (j = jst; j <= jfn; j++) {
00540         status = VIR_OK;
00541         we_get = 0;
00542         isfirst = (j == jst);
00543 
00544         /* Load up the images. If they won't load the signal a major error */
00545 
00546         ps.resets = vircam_fits_load_list(ps.resetlist,CPL_TYPE_FLOAT,j);
00547         if (ps.resets == NULL) {
00548             cpl_msg_info(fctid,"Extension %d resets wouldn't load",j);
00549             retval = vircam_reset_combine_lastbit(j,framelist,parlist);
00550             if (retval != 0)
00551                 return(-1);
00552             continue;
00553         }
00554 
00555         /* Are any of these reset images good? */
00556 
00557         ps.ngood = 0;
00558         for (i = 0; i < ps.nresets; i++) {
00559             ff = ps.resets[i];
00560             vircam_pfits_get_detlive(vircam_fits_get_ehu(ff),&live);
00561             if (! live) {
00562                 cpl_msg_info(fctid,"Detector flagged dead %s",
00563                              vircam_fits_get_fullname(ff));
00564                 vircam_fits_set_error(ff,VIR_FATAL);
00565             } else {
00566                 ps.good[ps.ngood] = ff;
00567                 ps.ngood += 1;
00568             }
00569         }
00570 
00571         /* If there are no good images, then signal that wee need to 
00572            create some dummy products and move on */
00573 
00574         if (ps.ngood == 0) {
00575             cpl_msg_info(fctid,"All images flagged bad for this extension");
00576             retval = vircam_reset_combine_lastbit(j,framelist,parlist);
00577             if (retval != 0)
00578                 return(-1);
00579             continue;
00580         }
00581 
00582         /* Load the mask */
00583 
00584         nx = cpl_image_get_size_x(vircam_fits_get_image(ps.good[0]));
00585         ny = cpl_image_get_size_y(vircam_fits_get_image(ps.good[0]));
00586         if (vircam_mask_load(ps.master_mask,j,nx,ny) == VIR_FATAL) {
00587             cpl_msg_info(fctid,"Unable to load mask image %s[%d]",
00588                          vircam_mask_get_filename(ps.master_mask),j);
00589             cpl_msg_info(fctid,"Forcing all pixels to be good from now on");
00590             vircam_mask_force(ps.master_mask,nx,ny);
00591         }
00592 
00593         /* Call the combine module. If it fails then signal that
00594            all products will be dummies */
00595 
00596         cpl_msg_info(fctid,"Doing combination for extension %d\n",j);
00597         (void)vircam_imcombine(ps.good,ps.ngood,
00598                                vircam_reset_combine_config.combtype,
00599                                vircam_reset_combine_config.scaletype,
00600                                vircam_reset_combine_config.xrej,
00601                                vircam_reset_combine_config.thresh,
00602                                &(ps.outimage),&(ps.rejmask),
00603                                &(ps.rejplus),&(ps.drs),&status);
00604         if (status == VIR_OK) {
00605             we_get |= MEANRESET;
00606             vircam_reset_combine_normal(j);
00607         }
00608 
00609         /* Create any dummies and save products */
00610 
00611         retval = vircam_reset_combine_lastbit(j,framelist,parlist);
00612         if (retval != 0)
00613             return(-1);
00614     }
00615     vircam_reset_combine_tidy(2);
00616     return(0);
00617 }
00618 
00619 /*---------------------------------------------------------------------------*/
00626 /*---------------------------------------------------------------------------*/
00627 
00628 static int vircam_reset_combine_save(cpl_frameset *framelist, 
00629                                      cpl_parameterlist *parlist) {
00630     cpl_propertylist *plist,*elist,*p,*pafprop;
00631     int status;
00632     const char *fctid = "vircam_reset_combine_save";
00633     const char *outfile = "resetcomb.fits";
00634     const char *outdiff = "resetdiff.fits";
00635     const char *outdimst = "resetdifftab.fits";
00636     const char *outfilepaf = "resetcomb";
00637     const char *outdiffpaf = "resetdiff";
00638     const char *recipeid = "vircam_reset_combine";
00639 
00640     /* If we need to make a PHU then do that now based on the first frame
00641        in the input frame list */
00642 
00643     if (isfirst) {
00644 
00645         /* Create a new product frame object and define some tags */
00646 
00647         product_frame_mean_reset = cpl_frame_new();
00648         cpl_frame_set_filename(product_frame_mean_reset,outfile);
00649         cpl_frame_set_tag(product_frame_mean_reset,VIRCAM_PRO_RESET);
00650         cpl_frame_set_type(product_frame_mean_reset,CPL_FRAME_TYPE_IMAGE);
00651         cpl_frame_set_group(product_frame_mean_reset,CPL_FRAME_GROUP_PRODUCT);
00652         cpl_frame_set_level(product_frame_mean_reset,CPL_FRAME_LEVEL_FINAL);
00653 
00654         /* Set up product phu */
00655 
00656         plist = vircam_fits_get_phu(ps.resets[0]);
00657         ps.phupaf = vircam_paf_phu_items(plist);
00658         if (ps.master_reset != NULL) {
00659             cpl_propertylist_update_string(ps.phupaf,"REF_RESET",
00660                                            cpl_frame_get_filename(ps.master_reset));
00661             cpl_propertylist_set_comment(ps.phupaf,"REF_RESET",
00662                                          "Reference reset used");
00663         }
00664         vircam_dfs_set_product_primary_header(plist,product_frame_mean_reset,
00665                                               framelist,parlist,
00666                                               (char *)recipeid,
00667                                               "PRO-1.15",NULL,0);
00668 
00669         /* 'Save' the PHU image */                       
00670 
00671         if (cpl_image_save(NULL,outfile,CPL_BPP_8_UNSIGNED,plist,
00672                            CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
00673             cpl_msg_error(fctid,"Cannot save product PHU");
00674             cpl_frame_delete(product_frame_mean_reset);
00675             return(-1);
00676         }
00677         cpl_frameset_insert(framelist,product_frame_mean_reset);
00678 
00679         /* Create a new product frame object for the difference image */
00680 
00681         if (we_expect & DIFFIMG) {
00682             product_frame_diffimg = cpl_frame_new();
00683             cpl_frame_set_filename(product_frame_diffimg,outdiff);
00684             cpl_frame_set_tag(product_frame_diffimg,
00685                               VIRCAM_PRO_DIFFIMG_RESET);
00686             cpl_frame_set_type(product_frame_diffimg,CPL_FRAME_TYPE_IMAGE);
00687             cpl_frame_set_group(product_frame_diffimg,CPL_FRAME_GROUP_PRODUCT);
00688             cpl_frame_set_level(product_frame_diffimg,CPL_FRAME_LEVEL_FINAL);
00689 
00690             /* Set up product phu */
00691 
00692             plist = vircam_fits_get_phu(ps.resets[0]);
00693             vircam_dfs_set_product_primary_header(plist,product_frame_diffimg,
00694                                                   framelist,parlist,
00695                                                   (char *)recipeid,
00696                                                   "PRO-1.15",NULL,0);
00697             /* 'Save' the PHU image */                   
00698 
00699             if (cpl_image_save(NULL,outdiff,CPL_BPP_8_UNSIGNED,plist,
00700                                CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
00701                 cpl_msg_error(fctid,"Cannot save product PHU");
00702                 cpl_frame_delete(product_frame_diffimg);
00703                 return(-1);
00704             }
00705             cpl_frameset_insert(framelist,product_frame_diffimg);
00706         }
00707 
00708         /* Create a new product frame object for the difference image stats 
00709            table */
00710 
00711         if (we_expect & STATS_TAB) {
00712             product_frame_diffimg_stats = cpl_frame_new();
00713             cpl_frame_set_filename(product_frame_diffimg_stats,outdimst);
00714             cpl_frame_set_tag(product_frame_diffimg_stats,
00715                               VIRCAM_PRO_DIFFIMG_RESET_STATS);
00716             cpl_frame_set_type(product_frame_diffimg_stats,
00717                                CPL_FRAME_TYPE_TABLE);
00718             cpl_frame_set_group(product_frame_diffimg_stats,
00719                                 CPL_FRAME_GROUP_PRODUCT);
00720             cpl_frame_set_level(product_frame_diffimg_stats,
00721                                 CPL_FRAME_LEVEL_FINAL);
00722 
00723             /* Set up product phu */
00724 
00725             plist = vircam_fits_get_phu(ps.resets[0]);
00726             vircam_dfs_set_product_primary_header(plist,
00727                                                   product_frame_diffimg_stats,
00728                                                   framelist,parlist,
00729                                                   (char *)recipeid,
00730                                                   "PRO-1.15",NULL,0);
00731 
00732             /* Fiddle with the extension header */
00733 
00734             elist = vircam_fits_get_ehu(ps.resets[0]);
00735             p = cpl_propertylist_duplicate(elist);
00736             vircam_merge_propertylists(p,ps.drs);
00737             if (! (we_get & STATS_TAB))
00738                 vircam_dummy_property(p);
00739             vircam_dfs_set_product_exten_header(p,product_frame_diffimg_stats,
00740                                                 framelist,parlist,
00741                                                 (char *)recipeid,
00742                                                 "PRO-1.15",NULL);
00743             status = VIR_OK;
00744             vircam_removewcs(p,&status);
00745             if (cpl_table_save(ps.diffimstats,plist,p,outdimst,
00746                                CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
00747                 cpl_msg_error(fctid,"Cannot save product table extension");
00748                 cpl_propertylist_delete(p);
00749                 return(-1);
00750             }
00751             cpl_propertylist_delete(p);
00752             cpl_frameset_insert(framelist,product_frame_diffimg_stats);
00753         }
00754     }
00755 
00756     /* Get the extension property list */ 
00757 
00758     plist = vircam_fits_get_ehu(ps.resets[0]);
00759     cpl_propertylist_update_int(plist,"ESO PRO DATANCOM",ps.ngood);
00760 
00761     /* Fiddle with the header now */
00762 
00763     vircam_merge_propertylists(plist,ps.drs);
00764     p = cpl_propertylist_duplicate(plist);
00765     if (! (we_get & MEANRESET))
00766         vircam_dummy_property(p);
00767     vircam_dfs_set_product_exten_header(p,product_frame_mean_reset,framelist,
00768                                         parlist,(char *)recipeid,"PRO-1.15",
00769                                         NULL);
00770 
00771     /* Now save the reset image extension */
00772 
00773     cpl_propertylist_update_float(p,"ESO QC RESETMED",
00774                                   vircam_reset_combine_config.resetmed);
00775     cpl_propertylist_set_comment(p,"ESO QC RESETMED",
00776                                  "Median of mean reset frame");
00777     cpl_propertylist_update_float(p,"ESO QC RESETRMS",
00778                                   vircam_reset_combine_config.resetrms);
00779     cpl_propertylist_set_comment(p,"ESO QC RESETRMS",
00780                                  "RMS of mean reset frame");
00781     if (cpl_image_save(ps.outimage,outfile,CPL_BPP_IEEE_FLOAT,p,
00782                        CPL_IO_EXTEND) != CPL_ERROR_NONE) {
00783         cpl_msg_error(fctid,"Cannot save product image extension");
00784         cpl_propertylist_delete(p);
00785         return(-1);
00786     }
00787 
00788     /* Write out PAF for mean image */
00789 
00790     pafprop = vircam_paf_req_items(p);
00791     vircam_merge_propertylists(pafprop,ps.phupaf);
00792     vircam_paf_append(pafprop,p,"ESO PRO CATG");
00793     vircam_paf_append(pafprop,p,"ESO PRO DATANCOM");
00794     if (vircam_paf_print((char *)outfilepaf,"VIRCAM/vircam_reset_combine",
00795                          "QC file",pafprop) != VIR_OK)
00796         cpl_msg_warning(fctid,"Unable to save PAF for mean reset");
00797     cpl_propertylist_delete(pafprop);
00798     cpl_propertylist_delete(p);
00799 
00800     /* Now save the reset difference image extension */
00801 
00802     if (we_expect & DIFFIMG) {
00803         p = cpl_propertylist_duplicate(plist);
00804         if (! (we_get & DIFFIMG))
00805             vircam_dummy_property(p);
00806         cpl_propertylist_update_float(p,"ESO QC RESETDIFF_MED",
00807                                       vircam_reset_combine_config.resetdiff_med);
00808         cpl_propertylist_set_comment(p,"ESO QC RESETDIFF_MED",
00809                                      "Median value of difference image");
00810         cpl_propertylist_update_float(p,"ESO QC RESETDIFF_RMS",
00811                                       vircam_reset_combine_config.resetdiff_rms);
00812         cpl_propertylist_set_comment(p,"ESO QC RESETDIFF_RMS",
00813                                      "RMS value of difference image");
00814         vircam_dfs_set_product_exten_header(p,product_frame_diffimg,
00815                                             framelist,parlist,(char *)recipeid,
00816                                             "PRO-1.15",NULL);
00817         if (cpl_image_save(ps.diffimg,outdiff,CPL_BPP_IEEE_FLOAT,p,
00818                            CPL_IO_EXTEND) != CPL_ERROR_NONE) {
00819             cpl_propertylist_delete(p);
00820             cpl_msg_error(fctid,"Cannot save product image extension");
00821             return(-1);
00822         }
00823         /* Write out PAF for difference image */
00824 
00825         pafprop = vircam_paf_req_items(p);
00826         vircam_merge_propertylists(pafprop,ps.phupaf);
00827         vircam_paf_append(pafprop,p,"ESO PRO CATG");
00828         if (vircam_paf_print((char *)outdiffpaf,"VIRCAM/vircam_reset_combine",
00829                              "QC file",pafprop) != VIR_OK)
00830             cpl_msg_warning(fctid,"Unable to save PAF for difference image");
00831         cpl_propertylist_delete(pafprop);
00832         cpl_propertylist_delete(p);
00833     }
00834 
00835     /* Now any further difference image stats tables */
00836 
00837     if (! isfirst && (we_expect & STATS_TAB)) {
00838         p = cpl_propertylist_duplicate(plist);
00839         if (! (we_get & STATS_TAB))
00840             vircam_dummy_property(p);
00841         vircam_dfs_set_product_exten_header(p,product_frame_diffimg_stats,
00842                                             framelist,parlist,(char *)recipeid,
00843                                             "PRO-1.15",NULL);
00844         status = VIR_OK;
00845         vircam_removewcs(p,&status);
00846         if (cpl_table_save(ps.diffimstats,NULL,p,outdimst,CPL_IO_EXTEND)
00847                            != CPL_ERROR_NONE) {
00848             cpl_msg_error(fctid,"Cannot save product table extension");
00849             cpl_propertylist_delete(p);
00850             return(-1);
00851         }       
00852         cpl_propertylist_delete(p);
00853     }
00854 
00855     return(0);
00856 }
00857 
00858 /*---------------------------------------------------------------------------*/
00862 /*---------------------------------------------------------------------------*/
00863 
00864 static void vircam_reset_combine_dummy_products(void) {
00865 
00866     /* See if you even need to be here */
00867 
00868     if (we_get == we_expect)
00869         return;
00870 
00871     /* First an output combined reset frame */
00872 
00873     if (! (we_get & MEANRESET)) {
00874         ps.outimage = vircam_dummy_image(ps.resets[0]);
00875 
00876         /* Set up the QC parameters */
00877 
00878         vircam_reset_combine_config.resetmed = 0.0;
00879         vircam_reset_combine_config.resetrms = 0.0;
00880     }
00881 
00882     /* Do the difference image */
00883 
00884     if ((we_expect & DIFFIMG) && ! (we_get & DIFFIMG)) {
00885         vircam_reset_combine_config.resetdiff_med = 0.0;
00886         vircam_reset_combine_config.resetdiff_rms = 0.0;
00887 
00888         /* Is a difference image required? If so then let's have it... */
00889 
00890         ps.diffimg = vircam_dummy_image(ps.resets[0]);
00891     }
00892 
00893     /* If a difference image stats table is required, then do that now */
00894 
00895     if ((we_expect & STATS_TAB) && ! (we_get & STATS_TAB)) 
00896         ps.diffimstats = vircam_create_diffimg_stats(0);
00897 
00898 
00899     return;
00900 }
00901 
00902 /*---------------------------------------------------------------------------*/
00907 /*---------------------------------------------------------------------------*/
00908 
00909 static void vircam_reset_combine_normal(int jext) {
00910     int nx,ny,ncells;
00911     long npi;
00912     unsigned char *bpm;
00913     float med,sig,*idata,grms,gdiff;
00914     const char *fctid="vircam_reset_combine_normal";
00915     cpl_table *ctable;
00916     cpl_propertylist *p;
00917 
00918     /* Load up the bad pixel mask */
00919 
00920     nx = cpl_image_get_size_x(ps.outimage);
00921     ny = cpl_image_get_size_y(ps.outimage);
00922     npi = nx*ny;
00923     bpm = vircam_mask_get_data(ps.master_mask);
00924 
00925     /* Work out the RMS of the mean reset frame */
00926 
00927     idata = cpl_image_get_data(ps.outimage);
00928     vircam_medmad(idata,bpm,npi,&med,&sig);
00929     sig *= 1.48;
00930     vircam_reset_combine_config.resetmed = med;
00931     vircam_reset_combine_config.resetrms = sig;
00932 
00933     /* Load up the master reset */
00934 
00935     if (ps.master_reset != NULL) {
00936         ps.mrimage = vircam_fits_load(ps.master_reset,CPL_TYPE_FLOAT,jext);
00937         if (ps.mrimage == NULL) 
00938             cpl_msg_info(fctid,"Master reset extension %d won't load",jext);
00939         else if (vircam_is_dummy(vircam_fits_get_ehu(ps.mrimage))) {
00940             cpl_msg_info(fctid,"Master reset extension %d is a dummy!",jext);
00941             freefits(ps.mrimage);
00942         }
00943     } else 
00944         ps.mrimage = NULL;
00945 
00946     /* Load up the channel table */
00947 
00948     if (ps.chantab != NULL) {
00949         ctable = cpl_table_load(cpl_frame_get_filename(ps.chantab),jext,0);
00950         if (ctable == NULL) {
00951             cpl_error_reset();
00952             cpl_msg_info(fctid,"Channel table extension %d won't load",jext);
00953         } else if (vircam_chantab_verify(ctable) != VIR_OK) {
00954             cpl_msg_info(fctid,"Channel table extension %d has errors",jext);
00955             freetable(ctable);
00956         } else { 
00957             p = cpl_propertylist_load(cpl_frame_get_filename(ps.chantab),jext);
00958             if (vircam_is_dummy(p)) {
00959                 cpl_msg_info(fctid,"Channel table extensions %d is a dummy",
00960                              jext);
00961                 freetable(ctable);
00962             }
00963             freepropertylist(p);
00964         }
00965     } else 
00966         ctable = NULL;
00967 
00968     /* Form the difference image. NB: the difference image routine
00969        copes if the input mean image and or the channel tables are
00970        null. Thus if either or both are null because of a failure
00971        to load then the routine will do as much as it can and return
00972        allowing you to fill in the rest with dummy products */
00973 
00974     vircam_reset_combine_config.resetdiff_med = 0.0;
00975     vircam_reset_combine_config.resetdiff_rms = 0.0;
00976     ncells = vircam_reset_combine_config.ncells;
00977     vircam_difference_image(vircam_fits_get_image(ps.mrimage),
00978                             ps.outimage,bpm,ctable,ncells,1,
00979                             &gdiff,&grms,&(ps.diffimg),
00980                             &(ps.diffimstats));
00981     vircam_mask_clear(ps.master_mask);
00982     vircam_reset_combine_config.resetdiff_med = gdiff;
00983     vircam_reset_combine_config.resetdiff_rms = grms;
00984     freetable(ctable);
00985     if (ps.diffimg != NULL)
00986         we_get |= DIFFIMG;
00987     if (ps.diffimstats != NULL)
00988         we_get |= STATS_TAB;
00989     return;
00990 }
00991 
00992 /*---------------------------------------------------------------------------*/
01000 /*---------------------------------------------------------------------------*/
01001 
01002 static int vircam_reset_combine_lastbit(int jext, cpl_frameset *framelist,
01003                                         cpl_parameterlist *parlist) {
01004     int retval;
01005     const char *fctid="vircam_reset_combine_lastbit";
01006 
01007     /* Make whatever dummy products you need */
01008 
01009     vircam_reset_combine_dummy_products();
01010 
01011     /* Save everything */
01012 
01013     cpl_msg_info(fctid,"Saving products for extension %d",jext);
01014     retval = vircam_reset_combine_save(framelist,parlist);
01015     if (retval != 0) {
01016         vircam_reset_combine_tidy(2);
01017         return(-1);
01018     }
01019 
01020     /* Free some stuff up */
01021 
01022     vircam_reset_combine_tidy(1);
01023     return(0);
01024 }
01025 
01026 /*---------------------------------------------------------------------------*/
01030 /*---------------------------------------------------------------------------*/
01031 
01032 static void vircam_reset_combine_init(void) {
01033     ps.labels = NULL;
01034     ps.resetlist = NULL;
01035     ps.resets = NULL;
01036     ps.nresets = 0;
01037     ps.good = NULL;
01038     ps.master_reset = NULL;
01039     ps.master_mask = NULL;
01040     ps.chantab = NULL;
01041     ps.outimage = NULL;
01042     ps.drs = NULL;
01043     ps.rejmask = NULL;
01044     ps.rejplus = NULL;
01045     ps.mrimage = NULL;
01046     ps.diffimg = NULL;
01047     ps.diffimstats = NULL;
01048     ps.phupaf = NULL;
01049 }
01050 
01051 /*---------------------------------------------------------------------------*/
01055 /*---------------------------------------------------------------------------*/
01056 
01057 static void vircam_reset_combine_tidy(int level) {
01058     freeimage(ps.outimage);
01059     freefitslist(ps.resets,ps.nresets);
01060     freespace(ps.rejmask);
01061     freespace(ps.rejplus);
01062     freepropertylist(ps.drs);
01063     freefits(ps.mrimage);
01064     freeimage(ps.diffimg);
01065     freetable(ps.diffimstats);
01066     if (level == 1)
01067         return;
01068     freespace(ps.labels);
01069     freeframeset(ps.resetlist);
01070     freeframe(ps.master_reset);
01071     freemask(ps.master_mask);
01072     freeframe(ps.chantab);
01073     freespace(ps.good);
01074     freepropertylist(ps.phupaf);
01075 }
01076 
01079 /*
01080 
01081 $Log: vircam_reset_combine.c,v $
01082 Revision 1.58  2010/03/21 06:48:21  jim
01083 Fixed bug where DATANCOM wasn't being updated in all products
01084 
01085 Revision 1.57  2010/03/09 14:27:40  jim
01086 Now updates ESO PRO DATANCOM to reflect the number of images used
01087 
01088 Revision 1.56  2010/02/05 09:42:22  jim
01089 Fixed call to non-existent cpl routine
01090 
01091 Revision 1.55  2010/01/31 18:54:01  jim
01092 Reference reset included in paf
01093 
01094 Revision 1.54  2009/09/09 09:50:21  jim
01095 Modified to try and get headers right
01096 
01097 Revision 1.53  2008/12/05 13:28:32  jim
01098 Fixed save routine so that the correct version of PRO CATG is written to the
01099 paf file
01100 
01101 Revision 1.52  2008/10/01 04:59:13  jim
01102 Added call to vircam_frameset_fexists to check input frameset
01103 
01104 Revision 1.51  2008/09/30 11:33:23  jim
01105 Added PRO CATG to pafs
01106 
01107 Revision 1.50  2007/10/19 09:25:09  jim
01108 Fixed problems with missing includes
01109 
01110 Revision 1.49  2007/10/15 12:53:26  jim
01111 Modified for compatibiliity with cpl_4.0
01112 
01113 Revision 1.48  2007/07/18 15:35:42  jim
01114 Added better error handling for missing or corrupt mask extensions
01115 
01116 Revision 1.47  2007/07/09 13:21:56  jim
01117 Modified to use new version of vircam_exten_range
01118 
01119 Revision 1.46  2007/04/04 10:36:18  jim
01120 Modified to use new dfs tags
01121 
01122 Revision 1.45  2007/03/29 12:19:39  jim
01123 Little changes to improve documentation
01124 
01125 Revision 1.44  2007/03/02 12:37:16  jim
01126 Removed WCS stuff from table headers
01127 
01128 Revision 1.43  2007/03/01 12:41:49  jim
01129 Modified slightly after code checking
01130 
01131 Revision 1.42  2007/02/25 06:27:41  jim
01132 plugged a few memory leaks
01133 
01134 Revision 1.41  2007/02/19 10:03:02  jim
01135 Fixed small memory leak
01136 
01137 Revision 1.40  2007/02/15 11:54:09  jim
01138 Modified to make a distinction between initial channel table and one that
01139 has the proper linearity information
01140 
01141 Revision 1.39  2007/02/15 06:59:38  jim
01142 Added ability to write QC paf files
01143 
01144 Revision 1.38  2007/02/06 13:11:12  jim
01145 Fixed entry for PRO dictionary in cpl_dfs_set_product_header
01146 
01147 Revision 1.37  2007/02/05 14:14:05  jim
01148 Input master frame is now tagged as REFERENCE. QC removed from stats table
01149 headers
01150 
01151 Revision 1.36  2007/01/09 11:39:02  jim
01152 Moved free for ps.good in tidy routine to the correct place
01153 
01154 Revision 1.35  2007/01/08 19:09:11  jim
01155 Fixed memory leak
01156 
01157 Revision 1.34  2006/12/13 13:19:52  jim
01158 Fixed problem with bad sigma estimate
01159 
01160 Revision 1.33  2006/12/08 11:39:27  jim
01161 Fixed bug where we_expect didn't check to see if the difference image was
01162 being produced before deciding whether or not a table would be produced.
01163 
01164 Revision 1.32  2006/11/27 12:15:08  jim
01165 changed calls to cpl_propertylist_append to cpl_propertylist_update
01166 
01167 Revision 1.31  2006/09/29 11:19:31  jim
01168 changed aliases on parameter names
01169 
01170 Revision 1.30  2006/09/09 16:49:40  jim
01171 Header comment update
01172 
01173 Revision 1.29  2006/08/27 20:30:02  jim
01174 Major mods to structure of the main processing routine to deal with missing
01175 and dummy frames. Deals better with lower level failures too
01176 
01177 Revision 1.28  2006/06/15 09:58:58  jim
01178 Minor changes to docs
01179 
01180 Revision 1.27  2006/06/09 11:26:25  jim
01181 Small changes to keep lint happy
01182 
01183 Revision 1.26  2006/06/06 13:01:40  jim
01184 Fixed so that the QC parameters go into the correct headers
01185 
01186 Revision 1.25  2006/05/17 14:43:58  jim
01187 Fixed problem in save routine which messed up the PRO CATG keywords
01188 
01189 Revision 1.24  2006/05/16 13:58:47  jim
01190 Fixed memory leaks that occur from not closing images at the end of
01191 the image extension loop
01192 
01193 Revision 1.23  2006/05/09 09:27:06  jim
01194 removed unecessary call to cpl_propertylist_delete
01195 
01196 Revision 1.22  2006/05/04 11:53:15  jim
01197 Fixed the way the _save routine works to be more consistent with the
01198 standard CPL way of doing things
01199 
01200 Revision 1.21  2006/04/27 09:46:01  jim
01201 Modified DFS frame types to conform to new dictionary
01202 
01203 Revision 1.20  2006/04/25 13:45:57  jim
01204 Fixed to adhere to new calling sequence for vircam_dfs routines
01205 
01206 Revision 1.19  2006/03/23 21:18:46  jim
01207 Minor changes mainly to comment headers
01208 
01209 Revision 1.18  2006/03/22 12:13:52  jim
01210 Modified to use new vircam_mask capability
01211 
01212 Revision 1.17  2006/03/15 10:43:40  jim
01213 Fixed a few things
01214 
01215 Revision 1.16  2006/03/08 14:32:35  jim
01216 Lots of little mods
01217 
01218 Revision 1.15  2006/03/03 14:29:06  jim
01219 Now calls routines with vir_fits.
01220 
01221 Revision 1.13  2006/02/22 10:01:38  jim
01222 Modified to use new version of vircam_imcombine
01223 
01224 Revision 1.12  2006/02/18 11:50:43  jim
01225 Modified the way the dfs product keywords are written using the vircam
01226 routines, rather than the cpl routine that doesn't understand image
01227 extensions
01228 
01229 Revision 1.11  2006/01/23 10:37:21  jim
01230 Now allows either a BPM or a CPM to be used as a mask
01231 
01232 Revision 1.10  2005/12/14 22:19:12  jim
01233 fixed docs
01234 
01235 Revision 1.9  2005/12/09 09:47:58  jim
01236 Many changes to add more documentation
01237 
01238 Revision 1.8  2005/12/02 10:45:38  jim
01239 The tags used in the sof are now written to the description string in the
01240 constructor. This is so that if they change in the vircam_dfs.h file, they
01241 aren't then hardcopied into each of the recipes...
01242 
01243 Revision 1.7  2005/12/01 16:25:48  jim
01244 Made the routine a bit more forgiving if certain master calibration files
01245 were missing. Now does as much as it can with the info it has
01246 
01247 Revision 1.6  2005/11/25 09:56:14  jim
01248 Tidied up some more documentation
01249 
01250 Revision 1.5  2005/11/23 14:57:40  jim
01251 A bit of tidying in response to splint messages
01252 
01253 Revision 1.4  2005/11/08 12:47:44  jim
01254 Made garbage collection a little better
01255 
01256 Revision 1.3  2005/11/07 13:13:43  jim
01257 Added some docs and calls to vircam_getnpts
01258 
01259 Revision 1.2  2005/11/03 15:16:28  jim
01260 Lots of changes mainly to strengthen error reporting
01261 
01262 Revision 1.1  2005/09/29 08:58:25  jim
01263 new routine
01264 
01265 
01266 
01267 */
01268 
01269 

Generated on 7 Feb 2011 for VIRCAM Pipeline by  doxygen 1.6.1