naco_spc_combine.c

00001 /* $Id: naco_spc_combine.c,v 1.28 2011-12-22 11:21:03 llundin Exp $
00002  *
00003  * This file is part of the NACO Pipeline
00004  * Copyright (C) 2002,2003 European Southern Observatory
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., 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: llundin $
00023  * $Date: 2011-12-22 11:21:03 $
00024  * $Revision: 1.28 $
00025  * $Name: not supported by cvs2svn $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 /*-----------------------------------------------------------------------------
00033                                 Includes
00034  -----------------------------------------------------------------------------*/
00035 
00036 #include "naco_recipe.h"
00037 #include "irplib_distortion.h"
00038 
00039 #include "naco_spc.h"
00040 
00041 #include <string.h>
00042 
00043 /*-----------------------------------------------------------------------------
00044                             Recipe defines
00045  -----------------------------------------------------------------------------*/
00046 
00047 #define RECIPE_STRING   "naco_spc_combine"
00048 
00049 /*-----------------------------------------------------------------------------
00050                             Private Functions prototypes
00051  -----------------------------------------------------------------------------*/
00052 
00053 
00054 static cpl_error_code naco_spc_combine_qc(cpl_propertylist *,
00055                                           cpl_propertylist *,
00056                                           const irplib_framelist *);
00057 
00058 static cpl_error_code naco_spc_combine_save(cpl_frameset *,
00059                                             const cpl_parameterlist *,
00060                                             const cpl_propertylist *,
00061                                             const cpl_propertylist *,
00062                                             const cpl_image *,
00063                                             const cpl_image *,
00064                                             const cpl_bivector *,
00065                                             const cpl_imagelist *,
00066                                             const irplib_framelist *);
00067 
00068 static cpl_error_code naco_framelist_fill_onoff_offset(cpl_vector *,
00069                                                        cpl_vector *,
00070                                                        const irplib_framelist *);
00071 
00072 NACO_RECIPE_DEFINE(naco_spc_combine,
00073                    NACO_PARAM_XTMIN | NACO_PARAM_XTMAX |
00074                    NACO_PARAM_PLOT | NACO_PARAM_SAVE,
00075                    "Combination of spectroscopic science data",
00076                    RECIPE_STRING
00077                    " -- NACO Combination of spectroscopic science data.\n" 
00078                    "The files listed in the Set Of Frames (sof-file) "
00079                    "must be tagged:\n" 
00080                    "NACO-raw-file.fits " NACO_SPC_NOD_RAW " or\n"
00081                    "NACO-flat-file.fits " NACO_CALIB_SPCFLAT " (optional).\n"
00082                    "For nodded frames (" NACO_SPC_NOD_RAW ") there must be "
00083                    "an identical number of exposures on each side of the "
00084                    "center, these pairs of nodded exposures should preferably "
00085                    "be taken with one immediately after the other. More "
00086                    "precisely, the i'th A-FRAME will be paired with the i'th "
00087                    "B-frame");
00088 
00089 #if 0
00090                    "For each " NACO_SPC_JITTER_RAW " frame a "
00091                    "NACO-raw-file.fits " NACO_SPC_JITTER_SKY "may be "
00092                    "provided as well.\n"
00093 #endif
00094 
00095 /*----------------------------------------------------------------------------*/
00099 /*----------------------------------------------------------------------------*/
00100 
00101 /*-----------------------------------------------------------------------------
00102                                 Functions code
00103  -----------------------------------------------------------------------------*/
00104 
00105 /*----------------------------------------------------------------------------*/
00112 /*----------------------------------------------------------------------------*/
00113 static int naco_spc_combine(cpl_frameset            * framelist,
00114                             const cpl_parameterlist * parlist)
00115 {
00116     cpl_errorstate     cleanstate = cpl_errorstate_get();
00117     irplib_framelist * allframes = NULL;
00118     irplib_framelist * rawframes = NULL;
00119     irplib_framelist * skyframes = NULL;
00120     const char       * flat;
00121     cpl_image        * flatimg   = NULL;
00122     cpl_propertylist * qclist    = cpl_propertylist_new();
00123     cpl_propertylist * paflist   = cpl_propertylist_new();
00124     cpl_propertylist * onoffkeys = cpl_propertylist_new();
00125     cpl_imagelist    * objimages = cpl_imagelist_new();
00126     cpl_imagelist    * offimages = cpl_imagelist_new();
00127     cpl_stats        * stats     = NULL;
00128     cpl_bivector     * offcorr   = NULL;
00129     cpl_image       ** saapair   = NULL;
00130     cpl_vector       * offcorx;
00131     cpl_vector       * offcory;
00132     int                npairs;
00133     int                nx, ny;
00134     const int          nplot
00135         = naco_parameterlist_get_int(parlist, RECIPE_STRING, NACO_PARAM_PLOT);
00136     const int          xtmin
00137         = naco_parameterlist_get_int(parlist, RECIPE_STRING, NACO_PARAM_XTMIN);
00138     const int          xtmax
00139         = naco_parameterlist_get_int(parlist, RECIPE_STRING, NACO_PARAM_XTMAX);
00140 
00141 
00142     skip_if(0);
00143     error_if(xtmin < 1, CPL_ERROR_ILLEGAL_INPUT,
00144              "xtmin=%d is less than 1", xtmin);
00145     error_if(xtmin > xtmax, CPL_ERROR_ILLEGAL_INPUT,
00146              "xtmin = %d is greater than xtmax=%d", xtmin, xtmax);    
00147 
00148     /* Identify the RAW and CALIB frames in the input frameset */
00149     skip_if (naco_dfs_set_groups(framelist));
00150 
00151     allframes = irplib_framelist_cast(framelist);
00152     skip_if(allframes == NULL);
00153 
00154     rawframes = irplib_framelist_extract_regexp(allframes, "^("
00155                                                 NACO_SPC_NOD_RAW "|"
00156                                                 NACO_SPC_JITTER_RAW ")$",
00157                                                 CPL_FALSE);
00158     skip_if(rawframes == NULL);
00159 
00160     skip_if(irplib_framelist_load_propertylist(rawframes, 0, 0, "^("
00161                                                IRPLIB_PFITS_WCS_REGEXP "|"
00162                                                NACO_PFITS_REGEXP_SPC_COMBINE_PAF
00163                                                ")$", CPL_FALSE));
00164 
00165     nx = irplib_pfits_get_int
00166         (irplib_framelist_get_propertylist_const(rawframes, 0), "NAXIS1");
00167     ny = irplib_pfits_get_int
00168         (irplib_framelist_get_propertylist_const(rawframes, 0), "NAXIS2");
00169 
00170     error_if(xtmax > nx, CPL_ERROR_ILLEGAL_INPUT,
00171              "xtmax=%d exceeds the image size of %d", xtmax, nx);
00172 
00173     skip_if(irplib_framelist_load_propertylist_all(rawframes, 0, "^("
00174                                                    NACO_PFITS_REGEXP_SPC_COMBINE
00175                                                    ")$", CPL_FALSE));
00176 
00177     /* Optional flatfield calibration file */
00178     flat = irplib_frameset_find_file(framelist, NACO_CALIB_SPCFLAT);
00179 
00180     if (flat != NULL) {
00181         flatimg = cpl_image_load(flat, CPL_TYPE_FLOAT, 0, 0);
00182         skip_if (flatimg == NULL);
00183 
00184         error_if(cpl_image_get_size_x(flatimg) != nx,
00185                  CPL_ERROR_INCOMPATIBLE_INPUT, "Flat image has NAXIS1=%d, not "
00186                  "%d", (int)cpl_image_get_size_x(flatimg), nx);
00187         error_if(cpl_image_get_size_y(flatimg) != ny,
00188                  CPL_ERROR_INCOMPATIBLE_INPUT, "Flat image has NAXIS2=%d, not "
00189                  "%d", (int)cpl_image_get_size_y(flatimg), ny);
00190     }
00191 
00192     if (cpl_frameset_find(framelist, NACO_SPC_JITTER_RAW)) {
00193 
00194         /* Jittered frames processed here */
00195 
00196         skip_if (cpl_frameset_find(framelist, NACO_SPC_NOD_RAW));
00197         skyframes = irplib_framelist_extract(allframes, NACO_SPC_JITTER_SKY);
00198         if (skyframes == NULL) {
00199             irplib_error_recover(cleanstate, "No sky frames");
00200         } else {
00201             skip_if(irplib_framelist_load_propertylist_all
00202                     (skyframes, 0, "^("
00203                      NACO_PFITS_REGEXP_SPC_COMBINE
00204                      ")$", CPL_FALSE));
00205         }
00206 
00207         bug_if(1);
00208     } else {
00209 
00210         /* Nodded frames processed here */
00211 
00212         skip_if (cpl_frameset_find(framelist, NACO_SPC_JITTER_RAW));
00213 
00214         /* On-frames have positive CUMOFFSETX, off-frames have negative */
00215         bug_if(cpl_propertylist_append_int(onoffkeys,
00216                                            NACO_PFITS_DOUBLE_CUMOFFSETX, 1));
00217 
00218         skip_if(naco_imagelist_load_diff(objimages, rawframes, onoffkeys));
00219 
00220         npairs = cpl_imagelist_get_size(objimages);
00221 
00222         error_if(2 * npairs < irplib_framelist_get_size(rawframes),
00223                  CPL_ERROR_ILLEGAL_INPUT,
00224                  "The %d frames contain only %d pair(s) of on/off frames",
00225                  irplib_framelist_get_size(rawframes), npairs);
00226 
00227         cpl_msg_info(cpl_func, "Loaded %d nodded images", npairs);
00228 
00229         if (flatimg) {
00230             cpl_msg_info(cpl_func, "Flat-fielding %d nodded images", npairs);
00231             skip_if(cpl_imagelist_divide_image(objimages, flatimg));
00232         }
00233 
00234         bug_if(naco_imagelist_append_invert(objimages));
00235 
00236         offcorr = cpl_bivector_new(2 * npairs);
00237         offcorx = cpl_bivector_get_x(offcorr);
00238         offcory = cpl_bivector_get_y(offcorr);
00239 
00240         /* The same reordering is done for the offsets */
00241         skip_if(naco_framelist_fill_onoff_offset(offcorx, offcory, rawframes));
00242 
00243 
00244     }
00245 
00246     if (cpl_msg_get_level() <= CPL_MSG_DEBUG) {
00247         cpl_bivector_dump(offcorr, stdout);
00248     }
00249 
00250     skip_if(naco_vector_correlate_imagelist_1d(offcorx, offcorx, CPL_FALSE,
00251                                                objimages));
00252 
00253     skip_if(naco_vector_correlate_imagelist_1d(offcory, offcory, CPL_TRUE,
00254                                                objimages));
00255 
00256 
00257     if (cpl_msg_get_level() <= CPL_MSG_INFO) {
00258         cpl_bivector_dump(offcorr, stdout);
00259     }
00260 
00261     /* The offset are relative to the 1st frame */
00262     bug_if(cpl_vector_set(offcorx, 0, 0.0));
00263     bug_if(cpl_vector_set(offcory, 0, 0.0));
00264 
00265     saapair = cpl_geom_img_offset_saa(objimages, offcorr, CPL_KERNEL_DEFAULT,
00266                                       0, 0, CPL_GEOM_FIRST, NULL, NULL);
00267     skip_if(saapair == NULL);
00268 
00269 
00270     /* bug_if(cpl_image_threshold(saapair[0], 0.0, FLT_MAX, 0.0, 0.0)); */
00271 
00272     if (nplot > 0) {
00273       cpl_errorstate prestate = cpl_errorstate_get();
00274       cpl_image * img1d = cpl_image_collapse_window_create(saapair[0], xtmin, 1,
00275                                                            xtmax, ny, 1);
00276 
00277       cpl_plot_image_col("set grid;", "t '1D-Spectrum' w linespoints", "",
00278                          img1d, 1, 1, 1);
00279 
00280       cpl_image_delete(img1d);
00281 
00282       img1d = cpl_image_collapse_window_create(saapair[0], xtmin, 1, xtmax,
00283                                                ny, 0);
00284 
00285       cpl_plot_image_row("set grid;", "t '1D-Profile' w linespoints", "",
00286                          img1d, 1, 1, 1);
00287 
00288       cpl_image_delete(img1d);
00289       if (!cpl_errorstate_is_equal(prestate)) {
00290         cpl_errorstate_set(prestate);
00291       }
00292     }
00293 
00294     stats = cpl_stats_new_from_image(saapair[0], CPL_STATS_ALL);
00295     bug_if(stats == NULL);
00296 
00297     if (cpl_msg_get_level() <= CPL_MSG_INFO) {
00298         cpl_stats_dump(stats, CPL_STATS_ALL, stdout);
00299     }
00300 
00301     skip_if(naco_spc_combine_qc(qclist, paflist, rawframes));
00302 
00303     /* PRO.CATG */
00304     bug_if (cpl_propertylist_append_string(paflist, CPL_DFS_PRO_CATG,
00305                                            NACO_SPC_NOD_COMBINE));
00306 
00307     skip_if(naco_spc_combine_save(framelist, parlist, qclist, paflist,
00308                                   saapair[0], saapair[1], offcorr, objimages,
00309                                   rawframes));
00310     
00311     end_skip;
00312 
00313     if (saapair != NULL) {
00314         cpl_image_delete(saapair[0]);
00315         cpl_image_delete(saapair[1]);
00316         cpl_free(saapair);
00317     }
00318     cpl_bivector_delete(offcorr);
00319     cpl_stats_delete(stats);
00320     cpl_imagelist_delete(objimages);
00321     cpl_imagelist_delete(offimages);
00322     cpl_image_delete(flatimg);
00323     irplib_framelist_delete(allframes);
00324     irplib_framelist_delete(rawframes);
00325     irplib_framelist_delete(skyframes);
00326     cpl_propertylist_delete(onoffkeys);
00327     cpl_propertylist_delete(qclist);
00328     cpl_propertylist_delete(paflist);
00329 
00330     return cpl_error_get_code();
00331 }
00332 
00333 
00334 /*----------------------------------------------------------------------------*/
00342 /*----------------------------------------------------------------------------*/
00343 static cpl_error_code naco_spc_combine_qc(cpl_propertylist       * qclist,
00344                                           cpl_propertylist       * paflist,
00345                                           const irplib_framelist * rawframes)
00346 {
00347 
00348     const cpl_propertylist * reflist
00349         = irplib_framelist_get_propertylist_const(rawframes, 0);
00350     const char pafcopy[] = "^(" NACO_PFITS_REGEXP_SPCWAVE_PAF ")$";
00351     const char * filter;
00352 
00353     bug_if (0);
00354 
00355     filter = naco_pfits_get_filter(reflist);
00356     skip_if(filter == NULL);
00357 
00358     bug_if(cpl_propertylist_append_string(qclist, "ESO QC FILTER OBS", filter));
00359 
00360     /* THE PAF FILE FOR QC PARAMETERS */
00361     skip_if (cpl_propertylist_copy_property_regexp(paflist, reflist, pafcopy,
00362                                                    0));
00363     skip_if (cpl_propertylist_append(paflist, qclist));
00364 
00365     bug_if (cpl_propertylist_copy_property_regexp(qclist, reflist, "^("
00366                                                   IRPLIB_PFITS_WCS_REGEXP "|"
00367                                                   IRPLIB_PFITS_REGEXP_RECAL_LAMP
00368                                                   ")$", 0));
00369     end_skip;
00370 
00371     return cpl_error_get_code();
00372 }
00373 
00374 /*----------------------------------------------------------------------------*/
00388 /*----------------------------------------------------------------------------*/
00389 static cpl_error_code naco_spc_combine_save(cpl_frameset           * set_tot,
00390                                             const cpl_parameterlist* parlist,
00391                                             const cpl_propertylist * qclist,
00392                                             const cpl_propertylist * paflist,
00393                                             const cpl_image        * combined,
00394                                             const cpl_image        * contrib,
00395                                             const cpl_bivector     * offcorr,
00396                                             const cpl_imagelist    * objimages,
00397                                             const irplib_framelist * rawframes)
00398 {
00399     const int          nsave
00400         = naco_parameterlist_get_int(parlist, RECIPE_STRING, NACO_PARAM_SAVE);
00401     cpl_frameset * proframes = irplib_frameset_cast(rawframes);
00402     cpl_table    * offtable  = NULL;
00403     cpl_propertylist * xtlist = cpl_propertylist_new();
00404 
00405     /* This will catch rawframes == NULL */
00406     bug_if(cpl_propertylist_append_string(xtlist, "EXTNAME",
00407                                           "Contribution Map"));
00408 
00409     /* The combined image */
00410     skip_if (irplib_dfs_save_image(set_tot, parlist, proframes, combined,
00411                                CPL_BPP_IEEE_FLOAT, RECIPE_STRING,
00412                                NACO_SPC_NOD_COMBINE, qclist, NULL,
00413                                naco_pipe_id, RECIPE_STRING CPL_DFS_FITS));
00414 
00415 
00416     /* Append the contribution map */
00417     skip_if (cpl_image_save(contrib, RECIPE_STRING CPL_DFS_FITS,
00418                             CPL_BPP_16_UNSIGNED, xtlist, CPL_IO_EXTEND));
00419 
00420 
00421     /* Append the combination offsets as a table */
00422     offtable = cpl_table_new(cpl_bivector_get_size(offcorr));
00423     bug_if(0);
00424     bug_if(cpl_table_wrap_double
00425            (offtable, (double*)cpl_bivector_get_x_data_const(offcorr),
00426             "OFFSETX"));
00427 
00428     bug_if(cpl_table_wrap_double
00429            (offtable, (double*)cpl_bivector_get_y_data_const(offcorr),
00430             "OFFSETY"));
00431 
00432     bug_if(cpl_table_set_column_unit(offtable, "OFFSETX", "pixel"));
00433     bug_if(cpl_table_set_column_unit(offtable, "OFFSETY", "pixel"));
00434 
00435     bug_if(cpl_propertylist_set_string(xtlist, "EXTNAME",
00436                                        "Image combination shifts"));
00437 
00438     skip_if(cpl_table_save(offtable, NULL, xtlist, RECIPE_STRING CPL_DFS_FITS,
00439                            CPL_IO_EXTEND));
00440 
00441     if (nsave > 0) {
00442 
00443         skip_if(irplib_dfs_save_imagelist(set_tot, parlist, proframes, objimages,
00444                                        CPL_BPP_IEEE_FLOAT, RECIPE_STRING,
00445                                        NACO_SPC_NOD_SUBTRACT, qclist, NULL,
00446                                        naco_pipe_id, RECIPE_STRING
00447                                        "_subtracted" CPL_DFS_FITS));
00448 
00449 
00450     }
00451 
00452 
00453 #ifdef NACO_SAVE_PAF
00454     /* The PAF */
00455     skip_if (cpl_dfs_save_paf("NACO", RECIPE_STRING, paflist,
00456                               RECIPE_STRING CPL_DFS_PAF));
00457 #else
00458     bug_if(paflist == NULL);
00459 #endif
00460 
00461     end_skip;
00462 
00463     cpl_propertylist_delete(xtlist);
00464 
00465     cpl_frameset_delete(proframes);
00466     if (offtable != NULL) {
00467         (void)cpl_table_unwrap(offtable, "OFFSETX");
00468         (void)cpl_table_unwrap(offtable, "OFFSETY");
00469         cpl_table_delete(offtable);
00470     }
00471 
00472     return cpl_error_get_code();
00473 
00474 }
00475 
00476 
00477 /*----------------------------------------------------------------------------*/
00492 /*----------------------------------------------------------------------------*/
00493 static
00494 cpl_error_code naco_framelist_fill_onoff_offset(cpl_vector * offset,
00495                                                 cpl_vector * offsety,
00496                                                 const irplib_framelist * self)
00497 {
00498     const int nframes = irplib_framelist_get_size(self);
00499     int       i;
00500 
00501 
00502     skip_if (0);
00503     skip_if (self    == NULL);
00504     skip_if (offset == NULL);
00505 
00506     skip_if (irplib_framelist_contains(self, NACO_PFITS_DOUBLE_CUMOFFSETX,
00507                                        CPL_TYPE_DOUBLE, CPL_FALSE, 0.0));
00508 
00509     bug_if(cpl_vector_set_size(offset, nframes));
00510 
00511     if (offsety != NULL) {
00512         skip_if (irplib_framelist_contains(self, NACO_PFITS_DOUBLE_CUMOFFSETY,
00513                                            CPL_TYPE_DOUBLE, CPL_FALSE, 0.0));
00514         bug_if(cpl_vector_set_size(offsety, nframes));
00515     }
00516 
00517    
00518     for (i = 0; i < nframes; i += 2) {
00519         const cpl_propertylist * plist1
00520             = irplib_framelist_get_propertylist_const(self, i);
00521         const cpl_propertylist * plist2
00522             = irplib_framelist_get_propertylist_const(self, i+1);
00523 
00524         const double xoff1
00525             = irplib_pfits_get_double(plist1, NACO_PFITS_DOUBLE_CUMOFFSETX);
00526         const double xoff2
00527             = irplib_pfits_get_double(plist2, NACO_PFITS_DOUBLE_CUMOFFSETX);
00528         int i0, i1;
00529 
00530         if (xoff1 > xoff2) {
00531             i0 = i/2;
00532             i1 = i/2 + nframes/2;
00533         } else {
00534             i1 = i/2;
00535             i0 = i/2 + nframes/2;
00536         }
00537         bug_if(cpl_vector_set(offset, i0,   xoff1));
00538         bug_if(cpl_vector_set(offset, i1,   xoff2));
00539 
00540         if (offsety != NULL) {
00541             const double yoff1
00542                 = irplib_pfits_get_double(plist1, NACO_PFITS_DOUBLE_CUMOFFSETY);
00543             const double yoff2
00544                 = irplib_pfits_get_double(plist2, NACO_PFITS_DOUBLE_CUMOFFSETY);
00545 
00546             bug_if(cpl_vector_set(offsety, i0,   yoff1));
00547             bug_if(cpl_vector_set(offsety, i1,   yoff2));
00548         }
00549     }
00550 
00551     end_skip;
00552 
00553     return cpl_error_get_code();
00554 
00555 }
00556 
Generated on Mon Feb 17 15:01:44 2014 for NACO Pipeline Reference Manual by  doxygen 1.6.3