visir_util_weight2error.c

00001 /* $Id: visir_util_weight2error.c,v 1.6 2011/09/26 09:23:27 llundin Exp $
00002  *
00003  * This file is part of the VISIR Pipeline
00004  * Copyright (C) 2011 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/09/26 09:23:27 $
00024  * $Revision: 1.6 $
00025  * $Name: visir-3_5_0 $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 /*-----------------------------------------------------------------------------
00033                                 Includes
00034  -----------------------------------------------------------------------------*/
00035 
00036 #include "visir_recipe.h"
00037 
00038 /*-----------------------------------------------------------------------------
00039                                 Defines
00040  -----------------------------------------------------------------------------*/
00041 
00042 #define RECIPE_STRING   "visir_util_weight2error"
00043 
00044 
00045 /*-----------------------------------------------------------------------------
00046                             Private Functions prototypes
00047  -----------------------------------------------------------------------------*/
00048 
00049 static cpl_error_code visir_util_weight2error_one(cpl_frameset *,
00050                                                   irplib_framelist *,
00051                                                   const cpl_frame *, int,
00052                                                   const cpl_parameterlist *);
00053 
00054 VISIR_RECIPE_DEFINE(visir_util_weight2error, 0,
00055                     "Conversion of a swarp weight map to an error map",
00056                     "The files listed in the Set Of Frames (sof-file) "
00057                     "must be tagged:\n"
00058                     "VISIR-weight-map.fits " VISIR_UTIL_WEIGHT2ERROR "\n"
00059                     "VISIR-bpm-file.fits " VISIR_CALIB_BPM " (optional)\n"
00060                     "\nThe product(s) will have a FITS card\n"
00061                     "'HIERARCH ESO PRO CATG' with a value of:\n"
00062                     VISIR_UTIL_WEIGHT2ERROR_PROCATG);
00063 
00064 /*----------------------------------------------------------------------------*/
00068 /*----------------------------------------------------------------------------*/
00069 
00070 /*-----------------------------------------------------------------------------
00071                                 Functions code
00072  -----------------------------------------------------------------------------*/
00073 
00074 /*----------------------------------------------------------------------------*/
00081 /*----------------------------------------------------------------------------*/
00082 static int visir_util_weight2error(cpl_frameset            * framelist,
00083                                    const cpl_parameterlist * parlist)
00084 {
00085 #ifdef _OPENMP
00086     cpl_errorstate     cleanstate = cpl_errorstate_get();
00087 #endif
00088     cpl_error_code     didfail = CPL_ERROR_NONE;
00089     irplib_framelist * allframes = NULL;
00090     irplib_framelist * rawframes = NULL;
00091     const cpl_frame  * bpmframe  = NULL;
00092     int                i, n;
00093     
00094 
00095     /* Identify the RAW and CALIB frames in the input frameset */
00096     skip_if (visir_dfs_set_groups(framelist));
00097 
00098     /* Objects observation */
00099     allframes = irplib_framelist_cast(framelist);
00100     skip_if(allframes == NULL);
00101     rawframes = irplib_framelist_extract(allframes, VISIR_UTIL_WEIGHT2ERROR);
00102     skip_if (rawframes == NULL);
00103     bpmframe = cpl_frameset_find_const(framelist, VISIR_CALIB_BPM);
00104 
00105     any_if("Propagating error");
00106     
00107     n = irplib_framelist_get_size(rawframes);
00108 #ifdef _OPENMP
00109 #pragma omp parallel for private(i)
00110 #endif
00111     for (i = 0; i < n; i++) {
00112         if (!didfail) {
00113 
00114             /* The total number of iterations must be pre-determined for the
00115                parallelism to work. In case of an error we can therefore not
00116                break, so instead we skip immediately to the next iteration.
00117                FIXME: This check on didfail does not guarantee that only one
00118                iteration can cause an error to be dumped, but it is not
00119                worse than checking on a thread-local state, e.g. errori. */
00120 
00121             if (visir_util_weight2error_one(framelist, rawframes, bpmframe,
00122                                             i, parlist)) {
00123                 const cpl_error_code errori = cpl_error_set_where(cpl_func);
00124 #ifdef _OPENMP
00125                 /* Cannot access these errors after the join,
00126                    so dump them now. :-(((((((((((((((((((( */
00127                 cpl_errorstate_dump(cleanstate, CPL_FALSE, NULL);
00128                 cpl_errorstate_set(cleanstate);
00129 #pragma omp critical(visir_util_weight2error)
00130 #endif
00131                 didfail = errori;
00132             }
00133         }
00134     }
00135 
00136     error_if(didfail, didfail, "Failed to convert data in %d frame(s)", n);
00137 
00138     end_skip;
00139 
00140     irplib_framelist_delete(allframes);
00141     irplib_framelist_delete(rawframes);
00142 
00143     return cpl_error_get_code();
00144 }
00145 
00146 
00147 /*----------------------------------------------------------------------------*/
00157 /*----------------------------------------------------------------------------*/
00158 static
00159 cpl_error_code visir_util_weight2error_one(cpl_frameset * framelist,
00160                                            irplib_framelist * rawframes,
00161                                            const cpl_frame * bpmframe, int i,
00162                                            const cpl_parameterlist * parlist)
00163 {
00164 
00165     const int          n = irplib_framelist_get_size(rawframes);
00166     cpl_errorstate     prestate   = cpl_errorstate_get();
00167     cpl_frameset     * products   = cpl_frameset_new();
00168     cpl_frameset     * usedframes = cpl_frameset_new();
00169     const cpl_frame  * frame      = irplib_framelist_get_const(rawframes, i);
00170     const char       * filename   = cpl_frame_get_filename(frame);
00171     const int          nexp       = cpl_fits_count_extensions(filename);
00172     cpl_imagelist    * map        = NULL;
00173     const char       * bpmname    = bpmframe ? cpl_frame_get_filename(bpmframe)
00174         : NULL;
00175     const int          mext       = bpmname ? cpl_fits_count_extensions(bpmname) : -1;
00176     cpl_image        * ibpm       = NULL;
00177     cpl_image        * ione       = NULL;
00178     cpl_image        * idiv       = NULL;
00179     cpl_mask         * bpm        = NULL;
00180     cpl_mask         * bpmi       = NULL;
00181     cpl_propertylist * plist      = NULL;
00182     char             * proname    = NULL;
00183     int                iexp;
00184 
00185     cpl_msg_info(cpl_func, "Converting %d Data unit(s) in frame %d/%d",
00186                  1+nexp, 1+i, n);
00187 
00188     any_if("Propagating error");
00189 
00190     if (bpmname != NULL) {
00191         error_if(mext != 1 && mext != nexp, CPL_ERROR_INCOMPATIBLE_INPUT,
00192                  "Raw file %s has %d extension(s) <=> %d extension(s) of bpm-"
00193                  "file %s", filename, nexp, mext, bpmname);
00194     }
00195 
00196     for (iexp = 0; iexp <= nexp; iexp++) {
00197 
00198         cpl_propertylist_delete(plist);
00199         plist = cpl_propertylist_load(filename, iexp);
00200 
00201         skip_if(plist == NULL);
00202 
00203         cpl_imagelist_delete(map);
00204         map = cpl_imagelist_load(filename, CPL_TYPE_FLOAT, iexp);
00205         if (!cpl_errorstate_is_equal(prestate)) {
00206             cpl_errorstate_set(prestate);
00207         } else {
00208             /* FIXME: Use cpl_imagelist_power(map, -0.5);
00209                once DFS10528 is fixed */
00210             int j;
00211             const int m = cpl_imagelist_get_size(map);
00212 
00213             if (iexp <= mext) {
00214                 cpl_image_delete(ibpm);
00215                 ibpm = cpl_image_load(bpmname, CPL_TYPE_UNSPECIFIED, 0, iexp);
00216                 cpl_mask_delete(bpm);
00217                 bpm = cpl_mask_threshold_image_create(ibpm, 0.5, DBL_MAX);
00218                 skip_if(bpm == NULL);
00219             }
00220 
00221             for (j = 0; j < m; j++) {
00222                 cpl_image * imap = cpl_imagelist_get(map, j);
00223 
00224                 /* Reject anything non-positive */
00225                 cpl_mask_delete(bpmi);
00226                 bpmi = cpl_mask_threshold_image_create(imap, 0.0, DBL_MAX);
00227                 bug_if(cpl_mask_not(bpmi));
00228 
00229                 /* Reject also any a-priori bad pixels */
00230                 if (bpm)
00231                     skip_if(cpl_mask_or(bpmi, bpm));
00232 
00233                 bug_if(cpl_image_reject_from_mask(imap, bpmi));
00234                 /* FIXME: Protect cpl_image_power() from any bad input pixels */
00235                 bug_if(cpl_image_fill_rejected(imap, 1.0));
00236 
00237                 bug_if(cpl_image_power(imap, 0.5));
00238 
00239                 if (ione == NULL) {
00240                     ione = cpl_image_new(cpl_image_get_size_x(imap),
00241                                          cpl_image_get_size_y(imap),
00242                                          CPL_TYPE_FLOAT);
00243                     cpl_image_add_scalar(ione, 1.0);
00244 
00245                 }
00246 
00247                 idiv = cpl_image_divide_create(ione, imap);
00248 
00249                 /* Division should not create bad pixels, but just be sure */
00250                 if (cpl_image_get_bpm_const(idiv))
00251                     bug_if(cpl_mask_or(bpmi, cpl_image_get_bpm_const(idiv)));
00252 
00253                 bug_if(cpl_image_reject_from_mask(idiv, bpmi));
00254 
00255                 bug_if(cpl_image_fill_rejected(idiv, FLT_MAX));
00256                 /* Replace image in list */
00257                 cpl_imagelist_set(map, idiv, j);
00258                 idiv = NULL;
00259             }
00260         }
00261 
00262         if (iexp == 0) {
00263 
00264             bug_if(cpl_frameset_insert(usedframes, cpl_frame_duplicate
00265                                        (frame)));
00266             if (bpmframe != NULL)
00267                 bug_if(cpl_frameset_insert(usedframes, cpl_frame_duplicate
00268                                            (bpmframe)));
00269 
00270             cpl_free(proname);
00271             proname = cpl_sprintf(RECIPE_STRING "_%d" CPL_DFS_FITS, 1+i);
00272             if (map == NULL) {
00273                 skip_if(irplib_dfs_save_propertylist(products, parlist,
00274                                                      usedframes, RECIPE_STRING,
00275                                                 VISIR_UTIL_WEIGHT2ERROR_PROCATG,
00276                                                      plist, NULL,
00277                                                      visir_pipe_id,
00278                                                      proname));
00279             } else {
00280                 skip_if(irplib_dfs_save_imagelist(products, parlist,
00281                                                   usedframes, map,
00282                                                   CPL_BPP_IEEE_FLOAT,
00283                                                   RECIPE_STRING,
00284                                                 VISIR_UTIL_WEIGHT2ERROR_PROCATG,
00285                                                   plist, NULL,
00286                                                   visir_pipe_id, proname));
00287             }
00288         } else {
00289             if (map == NULL) {
00290                 skip_if(cpl_propertylist_save(plist, proname, CPL_IO_EXTEND));
00291             } else {
00292                 skip_if(cpl_imagelist_save(map, proname, CPL_BPP_IEEE_FLOAT,
00293                                            plist, CPL_IO_EXTEND));
00294             }
00295         }
00296     }
00297 
00298     for (frame = cpl_frameset_get_first_const(products);
00299          frame != NULL;
00300          frame = cpl_frameset_get_next_const(products)) {
00301         cpl_frame * copy = cpl_frame_duplicate(frame);
00302         cpl_error_code error;
00303 
00304 #ifdef _OPENMP
00305 #pragma omp critical(visir_util_weight2error_one)
00306 #endif
00307         error = cpl_frameset_insert(framelist, copy);
00308 
00309         if (error) break;
00310     }
00311     bug_if(frame != NULL);
00312 
00313     end_skip;
00314 
00315     cpl_free(proname);
00316     cpl_image_delete(ione);
00317     cpl_image_delete(idiv);
00318     cpl_image_delete(ibpm);
00319     cpl_mask_delete(bpm);
00320     cpl_mask_delete(bpmi);
00321     cpl_imagelist_delete(map);
00322     cpl_propertylist_delete(plist);
00323     cpl_frameset_delete(usedframes);
00324     cpl_frameset_delete(products);
00325 
00326     return cpl_error_get_code();
00327 
00328 }
00329 
00330 

Generated on Mon Feb 6 15:23:49 2012 for VISIR Pipeline Reference Manual by  doxygen 1.5.8