visir_util_convert_pos.c

00001 /* $Id: visir_util_convert_pos.c,v 1.60 2012/02/02 10:26:53 jtaylor Exp $
00002  *
00003  * This file is part of the VISIR 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: jtaylor $
00023  * $Date: 2012/02/02 10:26:53 $
00024  * $Revision: 1.60 $
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_convert_pos"
00043 
00044 #define FLUX_COL    "FLUX_AUTO"
00045 #define X_COL       "XWIN_IMAGE"
00046 #define Y_COL       "YWIN_IMAGE"
00047 
00048 #define VISIR_FLUX      "FLXSCALE"
00049 #define VISIR_DRS_FLUX  "ESO DRS FLXSCALE"
00050 #define VISIR_FLUX_COMM "The relative flux (to the 1st source flux)"
00051 #define VISIR_DRS_SNR   "ESO DRS SNR"
00052 #define VISIR_DRS_SNR_COMM "The signal-to-noise ratio for the extracted source"
00053 #define SQR(a) ((a)*(a))
00054 
00055 
00056 /*-----------------------------------------------------------------------------
00057                             Private Functions prototypes
00058  -----------------------------------------------------------------------------*/
00059 
00060 static cpl_error_code visir_util_convert_pos_inv(cpl_frameset *, double *,
00061                                                 const irplib_framelist *,
00062                                                 const irplib_framelist *,
00063                                                 const cpl_mask *, int,
00064                                                 const cpl_parameterlist *);
00065 
00066 static cpl_error_code visir_util_convert_pos_one(cpl_frameset *, double *,
00067                                                  const irplib_framelist *,
00068                                                  const irplib_framelist *, int,
00069                                                  const cpl_parameterlist *);
00070 
00071 static cpl_error_code visir_util_convert_pos_save(cpl_frameset *,
00072                                                   double, double,
00073                                                   int, int, int,
00074                                                   const char *,
00075                                                   const char *,
00076                                                   const cpl_frameset      *,
00077                                                   const cpl_image         *,
00078                                                   const cpl_propertylist  *,
00079                                                   const cpl_parameterlist *);
00080 
00081 cpl_recipe_define(visir_util_convert_pos, VISIR_BINARY_VERSION,
00082                   "Lars Lundin", PACKAGE_BUGREPORT, "2011",
00083                   "Conversion of object position(s) from matching "
00084                   "pairs of nodded object files + sextractor tables",
00085                   "The files listed in the Set Of Frames (sof-file) "
00086                   "must be tagged:\n"
00087                   "Sextractor-object-file.fits " VISIR_UTIL_CONVERT_RAW "\n"
00088                   "Sextractor-table-file.fits "  VISIR_UTIL_CONVERT_TAB
00089                   "\nThe table must include these columns, all with numerical"
00090                   " data: " X_COL ", " Y_COL ", " FLUX_COL ".\nSuch a table "
00091                   "can be created by the source extractor software sextractor"
00092                   ".\n\n"
00093                   "In addition to containing pairs of object- and table-files"
00094                   " the SOF may also contain only object-files.\n"
00095                   "In this case the object files must be tagged with: "
00096                   VISIR_UTIL_CONVERT_RAW ".\n"
00097                   "\nFor each input object frame one or more products will be"
00098                   " created with updated WCS-ccordinates (CRPIX[12]).\n"
00099                   "When the object frame is matched with a table-frame, one "
00100                   "product will be created for each row in the table.\nSuch "
00101                   "products will be created in order of decreasing object "
00102                   "brightness.\n"
00103                   "\nWhen the object frames are pairs of 4-beam-frames, "
00104                   "the position (centroid) of the "
00105                   "brightest object in the 4-beam-frame will be written into "
00106                   "the first product.\nThe nodding and chopping throw will "
00107                   "determine the position written into the second product "
00108                   "based on the raw-frame and the position written into the "
00109                   "two products based on the matching off-frame.\n"
00110                   "When the object frames are pairs of 4-beam-frames, "
00111                   "the recipe also supports updating "
00112                   "the WCS-coordinates of an auxiliary frame (e.g. error map)"
00113                   " for each object.\n\nIf present these "
00114                   "auxiliary frames must be tagged:\n"
00115                   "Object-auxiliary.fits " VISIR_UTIL_CONVERT_POS_AUX
00116                   " (optional).\n"
00117                   "\nThe primary product(s) will have a FITS card\n"
00118                   "'HIERARCH " CPL_DFS_PRO_CATG "' with a value of:\n"
00119                   VISIR_UTIL_CONVERT_PROCATG "\n"
00120                   "If created, the auxiliary products will have a FITS "
00121                   "card\n'HIERARCH " CPL_DFS_PRO_CATG "' with a value of:\n"
00122                   VISIR_UTIL_CONVERT_AUX_PROCATG "\n"
00123                   );
00124 
00125 typedef struct {
00126     cpl_size zoom;
00127     cpl_size radius;
00128     cpl_vector * xyprofile;
00129 } visir_zoom_info;
00130 
00131 /*----------------------------------------------------------------------------*/
00135 /*----------------------------------------------------------------------------*/
00136 
00137 /*-----------------------------------------------------------------------------
00138                                 Functions code
00139  -----------------------------------------------------------------------------*/
00140 
00141 
00142 static cpl_image *
00143 zoom_img(const cpl_image * img, const visir_zoom_info zoom_info)
00144 {
00145     const cpl_size radius = zoom_info.radius;
00146     const cpl_size nx = cpl_image_get_size_x(img);
00147     const cpl_size ny = cpl_image_get_size_y(img);
00148     const cpl_size zoom = zoom_info.zoom;
00149     const cpl_vector * xyprofile = zoom_info.xyprofile;
00150     cpl_image * new;
00151     double * pndata;
00152 
00153     if (zoom_info.zoom == 1)
00154         return cpl_image_duplicate(img);
00155 
00156     new = cpl_image_new(nx*zoom, ny*zoom, CPL_TYPE_DOUBLE);
00157 
00158     pndata = cpl_image_get_data(new);
00159 
00160     for (cpl_size iv = 0; iv < ny * zoom; iv++) {
00161         for (cpl_size iu = 0; iu < nx * zoom; iu++) {
00162             double confidence;
00163 
00164             double value =
00165                 cpl_image_get_interpolated(img,
00166                                            (double)(iu+1.) / zoom,
00167                                            (double)(iv+1.) / zoom,
00168                                            xyprofile, radius,
00169                                            xyprofile, radius,
00170                                            &confidence);
00171             if (confidence >= 0)
00172                 pndata[iu + iv * (nx * zoom)] = value;
00173             else {
00174                 cpl_msg_error(cpl_func, "Interpolation failure");
00175                 cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
00176                 return NULL;
00177             }
00178         }
00179     }
00180 
00181     return new;
00182 }
00183 
00184 /*----------------------------------------------------------------------------*/
00192 /*----------------------------------------------------------------------------*/
00193 static cpl_error_code
00194 visir_util_convert_pos_fill_parameterlist(cpl_parameterlist * self)
00195 {
00196     const char * context = PACKAGE "." RECIPE_STRING;
00197     cpl_error_code err;
00198 
00199     cpl_ensure_code(self, CPL_ERROR_NULL_INPUT);
00200 
00201     /* Fill the parameters list */
00202 
00203     err =
00204         irplib_parameterlist_set_double(self, PACKAGE, RECIPE_STRING, "eccmax",
00205                                       0.25, NULL, context,
00206                        "The maximum eccentricity allowed in the combination "
00207                        "of the three (in parallel nod/chopping) or four (in "
00208                        "perpendicular nod/chopping) beams. In parallel mode, "
00209                        "three perfectly aligned points spaced with the "
00210                        "chopnod throw will have eccentricity 0, while in "
00211                        "perpedicular mode a square with the chopnod throw as "
00212                        "the side length will have eccentricity 0"
00213                                       );
00214     cpl_ensure_code(!err, err);
00215 
00216     err =
00217         irplib_parameterlist_set_int(self, PACKAGE, RECIPE_STRING, "naverage",
00218                                      1, NULL, context,
00219                        "Number of plains to average before searching for the "
00220                        "beam positions.");
00221     cpl_ensure_code(!err, err);
00222 
00223     err =
00224         irplib_parameterlist_set_bool(self, PACKAGE, RECIPE_STRING, "xcorrelate",
00225                                      CPL_FALSE, NULL, context,
00226                        "Shift beam positions by cross correlating images.");
00227     cpl_ensure_code(!err, err);
00228 
00229     err =
00230         irplib_parameterlist_set_bool(self, PACKAGE, RECIPE_STRING, "brightest",
00231                                      CPL_TRUE, NULL, context,
00232                        "Shift beam positions by brightest pixel.");
00233     cpl_ensure_code(!err, err);
00234 
00235     err =
00236         irplib_parameterlist_set_int(self, PACKAGE, RECIPE_STRING, "window",
00237                                      64, NULL, context,
00238                        "Window around detected beams to use for cross "
00239                        "correlation.");
00240     cpl_ensure_code(!err, err);
00241 
00242     return CPL_ERROR_NONE;
00243 }
00244 
00245 /*----------------------------------------------------------------------------*/
00252 /*----------------------------------------------------------------------------*/
00253 static int visir_util_convert_pos(cpl_frameset            * framelist,
00254                                   const cpl_parameterlist * parlist)
00255 {
00256     cpl_errorstate     cleanstate = cpl_errorstate_get();
00257     cpl_error_code     errori     = CPL_ERROR_NONE;
00258     irplib_framelist * allframes = NULL;
00259     irplib_framelist * rawframes = NULL;
00260     irplib_framelist * tabframes = NULL;
00261     irplib_framelist * invframes = NULL;
00262     irplib_framelist * auxframes = NULL;
00263     irplib_framelist * auxinvframes = NULL;
00264     cpl_mask         * bpm = NULL;
00265     double             flux1      = 0.0;
00266     const cpl_boolean  only_obj =
00267         cpl_frameset_find_const(framelist, VISIR_UTIL_CONVERT_TAB)
00268         ? CPL_FALSE : CPL_TRUE;
00269     int                i, n;
00270     
00271 
00272     /* Identify the RAW and TAB frames in the input frameset */
00273     skip_if (visir_dfs_set_groups(framelist));
00274 
00275     /* Objects observation */
00276     allframes = irplib_framelist_cast(framelist);
00277     skip_if(allframes == NULL);
00278 
00279     rawframes = irplib_framelist_extract(allframes, VISIR_UTIL_CONVERT_RAW);
00280     skip_if(rawframes == NULL);
00281 
00282     n = irplib_framelist_get_size(rawframes);
00283 
00284     if (only_obj) {
00285         if (cpl_frameset_find_const(framelist, VISIR_UTIL_CONVERT_POS_AUX)) {
00286             auxframes = irplib_framelist_extract(allframes,
00287                                                  VISIR_UTIL_CONVERT_POS_AUX);
00288             error_if(irplib_framelist_get_size(auxframes) != n,
00289                      CPL_ERROR_INCOMPATIBLE_INPUT, "%d auxiliary frame(s) does "
00290                      "not match the %d 4-beam-frame(s)",
00291                      irplib_framelist_get_size(auxframes), n);
00292         }
00293     } else {
00294         tabframes = irplib_framelist_extract(allframes, VISIR_UTIL_CONVERT_TAB);
00295         skip_if_lt(irplib_framelist_get_size(tabframes), n, "table-frames to "
00296                    "match the object frames");
00297     }
00298 
00299     if (cpl_frameset_find_const(framelist, VISIR_CALIB_STATIC_MASK)) {
00300         irplib_framelist * bpmframes =
00301             irplib_framelist_extract(allframes, VISIR_CALIB_STATIC_MASK);
00302         if (irplib_framelist_get_size(bpmframes) == 1) {
00303             const cpl_frame * bpmframe =
00304                 irplib_framelist_get_const(bpmframes, 0);
00305             const char * bpmname = cpl_frame_get_filename(bpmframe);
00306             cpl_image * bpmimg  =
00307                 cpl_image_load(bpmname, CPL_TYPE_UNSPECIFIED, 0, 0);
00308             bpm = cpl_mask_threshold_image_create(bpmimg, 0.1, DBL_MAX);
00309             cpl_image_delete(bpmimg);
00310 
00311             errori = cpl_error_set_where(cpl_func);
00312             error_if(errori, errori, "Could not load bad pixel map");
00313             cpl_msg_info(cpl_func, "Loaded bad pixel map");
00314         }
00315         irplib_framelist_delete(bpmframes);
00316     }
00317 
00318     for (i = 0; i < n; i++) {
00319         cpl_msg_info(cpl_func, "Converting frame %d/%d", 1+i, n);
00320 
00321         if (irplib_framelist_load_propertylist(rawframes, i, 0, "^("
00322                                                IRPLIB_PFITS_WCS_REGEXP "|"
00323                                                VISIR_PFITS_STRING_PIXSCALE
00324                                                "|"
00325                                                VISIR_PFITS_STRING_CHOPNOD_DIR
00326                                                "|"
00327                                                VISIR_PFITS_DOUBLE_CHOP_THROW
00328                                                ")$",
00329                                                CPL_FALSE)
00330             || (only_obj
00331                 ? visir_util_convert_pos_inv(framelist, &flux1, rawframes,
00332                                              auxframes, bpm, i, parlist)
00333                 : visir_util_convert_pos_one(framelist, &flux1, rawframes,
00334                                              tabframes, i, parlist))) {
00335             errori = cpl_error_set_where(cpl_func);
00336             if (errori != CPL_ERROR_NONE)
00337                 break;
00338         }
00339     }
00340     cpl_errorstate_dump(cleanstate, CPL_FALSE, NULL);
00341     cpl_errorstate_set(cleanstate);
00342 
00343     error_if(errori, errori, "Failed to process %d frame(s)", n);
00344 
00345     end_skip;
00346 
00347     irplib_framelist_delete(allframes);
00348     irplib_framelist_delete(rawframes);
00349     irplib_framelist_delete(invframes);
00350     irplib_framelist_delete(auxframes);
00351     irplib_framelist_delete(auxinvframes);
00352     irplib_framelist_delete(tabframes);
00353     cpl_mask_delete(bpm);
00354 
00355     return cpl_error_get_code();
00356 }
00357 
00358 
00359 /*----------------------------------------------------------------------------*/
00365 /*----------------------------------------------------------------------------*/
00366 static cpl_error_code
00367 save_image(const cpl_propertylist * plist, cpl_propertylist * updlist,
00368            cpl_frameset * products, cpl_frameset * usedframes,
00369            const cpl_parameterlist * parlist,
00370            cpl_image * image,
00371            const char * name, const char * auxname,
00372            const char * beamstr,
00373            int iframe, int iext, int proext,
00374            double xpos, double ypos,
00375            double relflux)
00376 {
00377     cpl_propertylist * extplist = NULL;
00378     bug_if(cpl_propertylist_copy_property_regexp(updlist, plist, "^("
00379                                                  IRPLIB_PFITS_WCS_REGEXP ")$",
00380                                                  CPL_FALSE));
00381 
00382     if (iext > 0) {
00383         /* Overwrite default with WCS of current extension, if it has any */
00384         cpl_propertylist_delete(extplist);
00385         extplist = cpl_propertylist_load_regexp(name, iext, "^("
00386                                                 IRPLIB_PFITS_WCS_REGEXP ")$",
00387                                                 CPL_FALSE);
00388         any_if("WCS keys could not be read from extension %d of %s",
00389                iext, name);
00390         bug_if(cpl_propertylist_append(updlist, extplist));
00391     }
00392 
00393     bug_if(cpl_propertylist_append_double(updlist, VISIR_DRS_FLUX,relflux));
00394     bug_if(cpl_propertylist_append_double(updlist, VISIR_FLUX,    relflux));
00395 
00396     /* Comments copied from actual header */
00397     bug_if(cpl_propertylist_set_comment(updlist, VISIR_DRS_FLUX,
00398                                         VISIR_FLUX_COMM));
00399     bug_if(cpl_propertylist_set_comment(updlist, VISIR_FLUX,
00400                                         VISIR_FLUX_COMM));
00401 
00402 
00403     skip_if(visir_util_convert_pos_save(products, xpos, ypos, iext, proext,
00404                                         iframe, beamstr, auxname, usedframes,
00405                                         image, updlist, parlist));
00406 
00407     end_skip;
00408     cpl_propertylist_delete(extplist);
00409 
00410     return cpl_error_get_code();
00411 }
00412 
00413 
00414 /*----------------------------------------------------------------------------*/
00427 /*----------------------------------------------------------------------------*/
00428 static
00429 cpl_error_code visir_util_convert_pos_inv(cpl_frameset * framelist,
00430                                          double * pflux1,
00431                                          const irplib_framelist * rawframes,
00432                                          const irplib_framelist * auxframes,
00433                                          const cpl_mask * bpm,
00434                                          int iframe,
00435                                          const cpl_parameterlist * parlist)
00436 {
00437 
00438     const cpl_propertylist * plist =
00439         irplib_framelist_get_propertylist_const(rawframes, iframe);
00440     cpl_propertylist * updlist    = cpl_propertylist_new();
00441     const cpl_frame  * frame;
00442     cpl_frameset     * products   = cpl_frameset_new();
00443     cpl_frameset     * usedframes = cpl_frameset_new();
00444     const cpl_frame * rawframe = irplib_framelist_get_const(rawframes, iframe);
00445     const cpl_frame * auxframe = auxframes ?
00446         irplib_framelist_get_const(auxframes, iframe) : NULL;
00447 
00448     const char * rawname = cpl_frame_get_filename(rawframe);
00449     const char * auxname = auxframes == NULL ? NULL
00450         : cpl_frame_get_filename(auxframe);
00451 
00452     const cpl_size next = cpl_fits_count_extensions(rawname);
00453     int proext = -1; /* Last extension where an image (product) was saved */
00454     cpl_imagelist * poslist = cpl_imagelist_new();
00455     cpl_imagelist * invlist = cpl_imagelist_new();
00456     int naverage = irplib_parameterlist_get_int(parlist, PACKAGE,
00457                                                 RECIPE_STRING, "naverage");
00458     double       x4[4];
00459     double       y4[4];
00460     int          index = 0;
00461     cpl_boolean  bfirst = CPL_FALSE;
00462     cpl_image * shifted_avg[] = { NULL, NULL, NULL, NULL };
00463     double first_x[4];
00464     double first_y[4];
00465     int fcount[4] = {0,0,0,0};
00466     int window = irplib_parameterlist_get_int(parlist, PACKAGE,
00467                                               RECIPE_STRING, "window");
00468     cpl_boolean bxcorr =
00469         irplib_parameterlist_get_bool(parlist, PACKAGE,
00470                                       RECIPE_STRING, "xcorrelate");
00471 
00472     cpl_boolean bmaxpos =
00473         irplib_parameterlist_get_bool(parlist, PACKAGE,
00474                                       RECIPE_STRING, "brightest");
00475 
00476     error_if(bmaxpos && bxcorr, CPL_ERROR_INCOMPATIBLE_INPUT, "choose one");
00477 
00478 
00479     if (naverage <= 0)
00480         naverage = 1;
00481     else if (naverage > next)
00482         naverage = next;
00483 
00484     bug_if(rawframes == NULL);
00485     bug_if(pflux1    == NULL);
00486     bug_if(parlist   == NULL);
00487 
00488     bug_if(cpl_frameset_insert(usedframes, cpl_frame_duplicate(rawframe)));
00489     if (auxframe != NULL) {
00490         bug_if(cpl_frameset_insert(usedframes, cpl_frame_duplicate(auxframe)));
00491     }
00492 
00493     /* Loop over all extensions */
00494 
00495     for (int iext = - naverage / 2; iext <= next - naverage / 2; iext++) {
00496         int iloaded = iext + naverage / 2;
00497         cpl_errorstate prestate = cpl_errorstate_get();
00498         double relflux, flux;
00499         cpl_image * rawload, * invload;
00500         cpl_size nx, ny;
00501 
00502 
00503         visir_chopnod_mode mode;
00504         cpl_image * avraw, * avinv;
00505         if (iloaded <= next) {
00506 
00507             rawload = cpl_image_load(rawname, CPL_TYPE_UNSPECIFIED, 0, iloaded);
00508             if (bpm)
00509                 cpl_image_reject_from_mask(rawload, bpm);
00510             invload = cpl_image_duplicate(rawload);
00511             cpl_image_multiply_scalar(invload, -1);
00512 
00513             if (!cpl_errorstate_is_equal(prestate)) {
00514                 /* If load fails on one, it must fail on both */
00515                 if (rawload != NULL || invload != NULL) {
00516                     any_if("One HDU has image data, the other does not");
00517                 }
00518 
00519                 /* Recover from the error */
00520                 cpl_msg_info(cpl_func, "No image-data in extension %d", iloaded);
00521                 cpl_errorstate_set(prestate);
00522                 index++;
00523                 continue;
00524             }
00525         }
00526         nx = cpl_image_get_size_x(rawload);
00527         ny = cpl_image_get_size_y(rawload);
00528 
00529         bug_if(cpl_imagelist_get_size(poslist) != cpl_imagelist_get_size(invlist));
00530 
00531         if (cpl_imagelist_get_size(poslist) == naverage) {
00532             cpl_image_delete(cpl_imagelist_unset(poslist, 0));
00533             cpl_image_delete(cpl_imagelist_unset(invlist, 0));
00534         }
00535         cpl_imagelist_set(poslist, rawload,
00536                           cpl_imagelist_get_size(poslist));
00537         cpl_imagelist_set(invlist, invload,
00538                           cpl_imagelist_get_size(invlist));
00539 
00540         /* skip incomplete averages, positions set
00541          * to first complete one later */
00542         if (cpl_imagelist_get_size(poslist) != naverage)
00543             continue;
00544 
00545         // FIXME: use a weighted average
00546         // rolling average might be needed for larger lists
00547             /* fill bad pixels so they aren't
00548              * considered as apertures in overall negative images*/
00549         avraw = cpl_imagelist_collapse_create(poslist);
00550         skip_if(cpl_detector_interpolate_rejected(avraw));
00551         avinv = cpl_imagelist_collapse_create(invlist);
00552         skip_if(cpl_detector_interpolate_rejected(avinv));
00553         cpl_propertylist_empty(updlist);
00554 
00555         mode = visir_img_find_beam(updlist, avraw, avinv, plist,
00556                                    parlist, RECIPE_STRING, x4, y4);
00557 
00558         if (bxcorr && shifted_avg[0] == NULL)
00559             for (int a = 0; a < 4; a++) {
00560                 /* FIXME: handle 3 beam */
00561                 shifted_avg[a] =
00562                     cpl_image_extract(avraw,
00563                                       CX_MAX(1, x4[a] - window/2),
00564                                       CX_MAX(1, y4[a] - window/2),
00565                                       CX_MIN(nx, x4[a] + window/2),
00566                                       CX_MIN(ny, y4[a] + window/2));
00567                 bug_if(shifted_avg[a] == NULL);
00568                 cpl_image_abs(shifted_avg[a]);
00569                 first_x[a] = x4[a];
00570                 first_y[a] = y4[a];
00571             }
00572 
00573         skip_if(mode == VISIR_CHOPNOD_AUTO);
00574 
00575         flux = cpl_propertylist_get_double(updlist, "ESO QC ONEBEAM FLUX");
00576         skip_if(0);
00577 
00578         if (*pflux1 != 0.0) {
00579             relflux = flux / *pflux1;
00580         } else {
00581             *pflux1 = flux;
00582             relflux = 1.0;
00583         }
00584 
00585         bug_if(iext <= 0);
00586 
00587         for (int j = 0; j <= naverage; j++) {
00588             cpl_image * rawimage, * invimage;
00589             /* first value */
00590             if (!bfirst) {
00591                 if (j > naverage / 2) {
00592                     bfirst = CPL_TRUE;
00593                     break;
00594                 }
00595                 rawimage = cpl_imagelist_get(poslist, j);
00596                 invimage = cpl_imagelist_get(invlist, j);
00597                 cpl_msg_info(cpl_func, "Incomplete average, assuming values of"
00598                              " nearest complete average");
00599             }
00600             /* last value */
00601             else if (iloaded >= next) {
00602                 if (j + naverage / 2 >= naverage)
00603                     break;
00604                 rawimage = cpl_imagelist_get(poslist, j + naverage / 2);
00605                 invimage = cpl_imagelist_get(invlist, j + naverage / 2);
00606                 cpl_msg_info(cpl_func, "Incomplete average, assuming values of"
00607                              " nearest complete average");
00608             }
00609             else {
00610                 rawimage = cpl_imagelist_get(poslist, naverage / 2);
00611                 invimage = cpl_imagelist_get(invlist, naverage / 2);
00612                 j += next; /* break after saving */
00613             }
00614             skip_if(cpl_detector_interpolate_rejected(rawimage));
00615             skip_if(cpl_detector_interpolate_rejected(invimage));
00616 
00617             if (bxcorr) {
00618                 cpl_msg_info(cpl_func, "Cross-Correlation");
00619 #ifdef _OPENMP
00620 #pragma omp parallel for
00621 #endif
00622                 for (int a = 0; a < 4; a++) {
00623                     double xshift = 0, yshift = 0;
00624                     cpl_image * img =
00625                         cpl_image_extract(avraw,
00626                                           CX_MAX(1, first_x[a] - window/2),
00627                                           CX_MAX(1, first_y[a] - window/2),
00628                                           CX_MIN(nx, first_x[a] + window/2),
00629                                           CX_MIN(ny, first_y[a] + window/2));
00630                     cpl_image_abs(img);
00631                     visir_fftxcorrelate(shifted_avg[a], img, CPL_TRUE, &xshift, &yshift);
00632                     // FIXME: parameter value? skip the complete image
00633                     if (sqrt(SQR(xshift) + SQR(yshift)) > 5)
00634                         xshift = yshift = 0;
00635                     x4[a] = first_x[a] + xshift;
00636                     y4[a] = first_y[a] + yshift;
00637                     // FIXME: bad, add a subpixel shift or drop when first image good
00638                     cpl_image_shift(img, -round(xshift), -round(yshift));
00639                     cpl_image_multiply_scalar(shifted_avg[a], fcount[a]++);
00640                     cpl_image_add(shifted_avg[a], img);
00641                     cpl_image_divide_scalar(shifted_avg[a], fcount[a]);
00642                     cpl_msg_info(cpl_func, "%d: %f %f", a, x4[a], y4[a]);
00643                     cpl_image_delete(img);
00644                 }
00645             }
00646             if (bmaxpos) {
00647                 cpl_msg_info(cpl_func, "Brightest pixel");
00648 #ifdef _OPENMP
00649 #pragma omp parallel for
00650 #endif
00651                 for (int a = 0; a < 4; a++) {
00652                     cpl_size xshift = 0, yshift = 0;
00653                     double xsub, ysub;
00654                     double xlow = (int)(x4[a] - window / 2);
00655                     double ylow = (int)(y4[a] - window / 2);
00656                     cpl_image * img =
00657                         cpl_image_extract(avraw,
00658                                           CX_MAX(1, xlow),
00659                                           CX_MAX(1, ylow),
00660                                           CX_MIN(nx, x4[a] + window/2),
00661                                           CX_MIN(ny, y4[a] + window/2));
00662                     cpl_image_abs(img);
00663                     cpl_image_get_maxpos(img, &xshift, &yshift);
00664                     visir_get_subpixel_maxpos(img, xshift, yshift, &xsub, &ysub);
00665                     if (sqrt(SQR(xshift + xsub - (x4[a] - xlow)) +
00666                              SQR(yshift + ysub - (y4[a] - ylow))) < 5) {
00667                         x4[a] = xlow + xshift + xsub;
00668                         y4[a] = ylow + yshift + ysub;
00669                     }
00670                     cpl_msg_info(cpl_func, "%d: %f %f", a, x4[a], y4[a]);
00671                     cpl_image_delete(img);
00672                 }
00673             }
00674 
00675             cpl_msg_info(cpl_func, "On-object in frame %d extension %d has "
00676                          "max-flux=%g at (%g,%g)", 1+iframe, index,
00677                          flux, x4[0], y4[0]);
00678 
00679 
00680             /* The A-on-frame */
00681             skip_if(save_image(plist, updlist, products, usedframes, parlist,
00682                                rawimage, rawname, auxname, "A_on",
00683                                iframe, index, proext, x4[0], y4[0], relflux));
00684 
00685             if(mode == VISIR_CHOPNOD_PERPENDICULAR) {
00686 
00687                 /* The B-off-frame */
00688                 skip_if(save_image(plist, updlist, products, usedframes, parlist,
00689                                    rawimage, rawname, auxname, "B_off",
00690                                    iframe, index, proext, x4[1], y4[1], relflux));
00691 
00692                 /* The B-on-frame */
00693                 skip_if(save_image(plist, updlist, products, usedframes, parlist,
00694                                    invimage, rawname, auxname, "B_on",
00695                                    iframe, index, proext, x4[3], y4[3], relflux));
00696 
00697 
00698                 /* The A-off-frame */
00699                 skip_if(save_image(plist, updlist, products, usedframes, parlist,
00700                                    invimage, rawname, auxname, "A_off",
00701                                    iframe, index, proext, x4[2], y4[2], relflux));
00702 
00703             } else {
00704 
00705                 /* FIXME: check if index <-> beam assignment is correct */
00706                 /* The B-off-frame */
00707                 skip_if(save_image(plist, updlist, products, usedframes, parlist,
00708                                    rawimage, rawname, auxname, "B_off",
00709                                    iframe, index, proext, x4[2], y4[2], relflux));
00710 
00711 
00712                 /* The B-on-frame */
00713                 skip_if(save_image(plist, updlist, products, usedframes, parlist,
00714                                    invimage, rawname, auxname, "B_on",
00715                                    iframe, index, proext,x4[1], y4[1], relflux));
00716 
00717             }
00718 
00719 
00720 
00721             proext = index++; /* An image (product) was created/appended */
00722         }
00723         cpl_image_delete(avraw);
00724         cpl_image_delete(avinv);
00725     }
00726 
00727     for (frame = cpl_frameset_get_first_const(products);
00728          frame != NULL;
00729          frame = cpl_frameset_get_next_const(products)) {
00730         cpl_frame * copy = cpl_frame_duplicate(frame);
00731         cpl_error_code error;
00732 
00733         error = cpl_frameset_insert(framelist, copy);
00734 
00735         if (error) break;
00736     }
00737     bug_if(frame != NULL);
00738 
00739     end_skip;
00740 
00741     cpl_imagelist_delete(poslist);
00742     cpl_imagelist_delete(invlist);
00743 
00744     cpl_propertylist_delete(updlist);
00745     cpl_frameset_delete(usedframes);
00746     cpl_frameset_delete(products);
00747     for (int i = 0; i < 4; i++)
00748         cpl_image_delete(shifted_avg[i]);
00749 
00750     return cpl_error_get_code();
00751 }
00752 
00753 
00754 /*----------------------------------------------------------------------------*/
00765 /*----------------------------------------------------------------------------*/
00766 static
00767 cpl_error_code visir_util_convert_pos_one(cpl_frameset * framelist,
00768                                           double * pflux1,
00769                                           const irplib_framelist * rawframes,
00770                                           const irplib_framelist * tabframes,
00771                                           int i,
00772                                           const cpl_parameterlist * parlist)
00773 {
00774 
00775     cpl_propertylist * updlist = cpl_propertylist_duplicate
00776         (irplib_framelist_get_propertylist_const(rawframes, i));
00777     const cpl_frame  * frame;
00778     cpl_frameset     * products   = cpl_frameset_new();
00779     cpl_frameset     * usedframes = cpl_frameset_new();
00780     cpl_propertylist * plsort = cpl_propertylist_new();
00781     const char    * imgname = cpl_frame_get_filename(irplib_framelist_get_const
00782                                                       (rawframes, i));
00783     const char    * tabname = cpl_frame_get_filename(irplib_framelist_get_const
00784                                                       (tabframes, i));
00785     cpl_table     * table = cpl_table_load(tabname, 1, 0);
00786     cpl_image     * image = cpl_image_load(imgname, CPL_TYPE_UNSPECIFIED, 0, 0);
00787     char          * proname = NULL;
00788     const cpl_size  nobjs = cpl_table_get_nrow(table);
00789 
00790     skip_if(0);
00791     bug_if(pflux1 == NULL);
00792 
00793     skip_if_lt(nobjs, 1, "row(s) in table of extracted sources with "
00794                "column " FLUX_COL ": %s", tabname);
00795 
00796     bug_if(cpl_frameset_insert(usedframes, cpl_frame_duplicate
00797                                (irplib_framelist_get_const(rawframes, i))));
00798     bug_if(cpl_frameset_insert(usedframes, cpl_frame_duplicate
00799                                (irplib_framelist_get_const(tabframes, i))));
00800 
00801     for (cpl_size iobj = 0; iobj < nobjs; iobj++) {
00802         cpl_size maxpos;
00803         double   xpos, ypos, relflux, flux;
00804 
00805         cpl_free(proname);
00806         proname = cpl_sprintf(RECIPE_STRING "_%d_%d" CPL_DFS_FITS,
00807                               (int)(1+i), (int)(1+iobj));
00808 
00809         skip_if(cpl_table_get_column_maxpos(table, FLUX_COL, &maxpos));
00810 
00811         xpos = cpl_table_get(table, X_COL,    maxpos, NULL);
00812         ypos = cpl_table_get(table, Y_COL,    maxpos, NULL);
00813         flux = cpl_table_get(table, FLUX_COL, maxpos, NULL);
00814 
00815         /* Flag as processed */
00816         bug_if(cpl_table_set_invalid(table, FLUX_COL, maxpos));
00817 
00818         if (*pflux1 != 0.0) {
00819             relflux = flux / *pflux1;
00820         } else {
00821             *pflux1 = flux;
00822             relflux = 1.0;
00823         }
00824 
00825         cpl_msg_info(cpl_func, "Row %d/%d in frame %d: (%g,%g)", 1+(int)maxpos,
00826                      (int)nobjs, (int)(1+i), xpos, ypos);
00827 
00828         bug_if(cpl_propertylist_append_double(updlist, "CRPIX1",      xpos));
00829         bug_if(cpl_propertylist_append_double(updlist, "CRPIX2",      ypos));
00830         bug_if(cpl_propertylist_append_double(updlist, VISIR_DRS_FLUX,relflux));
00831         bug_if(cpl_propertylist_append_double(updlist, VISIR_FLUX,    relflux));
00832 
00833         if (iobj == 0) {
00834             /* Comments copied from actual header */
00835             bug_if(cpl_propertylist_set_comment(updlist, "CRPIX1", "Windowed "
00836                                                 "position estimate along x"));
00837             bug_if(cpl_propertylist_set_comment(updlist, "CRPIX2", "Windowed "
00838                                                 "position estimate along y"));
00839             bug_if(cpl_propertylist_set_comment(updlist, VISIR_DRS_FLUX,
00840                                                 VISIR_FLUX_COMM));
00841             bug_if(cpl_propertylist_set_comment(updlist, VISIR_FLUX,
00842                                                 VISIR_FLUX_COMM));
00843         }
00844 
00845         skip_if(irplib_dfs_save_image(products, parlist, usedframes, image,
00846                                       CPL_BPP_IEEE_FLOAT, RECIPE_STRING,
00847                                       VISIR_UTIL_CONVERT_PROCATG, updlist,
00848                                       NULL, visir_pipe_id, proname));
00849 
00850     }
00851 
00852     /* Failure here is a bug */
00853     skip_if_lt(cpl_table_count_invalid(table, FLUX_COL), nobjs,
00854                "processed objects from table %s", tabname);
00855 
00856     for (frame = cpl_frameset_get_first_const(products);
00857          frame != NULL;
00858          frame = cpl_frameset_get_next_const(products)) {
00859         cpl_frame * copy = cpl_frame_duplicate(frame);
00860         cpl_error_code error;
00861 
00862         error = cpl_frameset_insert(framelist, copy);
00863 
00864         if (error) break;
00865     }
00866     bug_if(frame != NULL);
00867 
00868     end_skip;
00869 
00870     cpl_image_delete(image);
00871     cpl_table_delete(table);
00872     cpl_free(proname);
00873     cpl_propertylist_delete(updlist);
00874     cpl_propertylist_delete(plsort);
00875     cpl_frameset_delete(usedframes);
00876     cpl_frameset_delete(products);
00877 
00878     return cpl_error_get_code();
00879 }
00880 
00881 /*----------------------------------------------------------------------------*/
00898 /*----------------------------------------------------------------------------*/
00899 static
00900 cpl_error_code visir_util_convert_pos_save(cpl_frameset * framelist,
00901                                            double xpos, double ypos,
00902                                            int iext, int proext, int i,
00903                                            const char * beamstr,
00904                                            const char * auxrawname,
00905                                            const cpl_frameset      * usedframes,
00906                                            const cpl_image         * image,
00907                                            const cpl_propertylist  * applist,
00908                                            const cpl_parameterlist * parlist)
00909 {
00910 
00911     char       * proname =
00912         cpl_sprintf(RECIPE_STRING "_%d_%s" CPL_DFS_FITS, 1+i, beamstr);
00913     char       * auxproname = cpl_sprintf(RECIPE_STRING "_%d_%s_aux"
00914                                           CPL_DFS_FITS, 1+i, beamstr);
00915     cpl_propertylist * plempty = cpl_propertylist_new();
00916     cpl_propertylist * updlist = cpl_propertylist_duplicate(applist);
00917     cpl_image        * auximage = NULL;
00918 
00919 
00920     bug_if(proext >= iext);
00921     bug_if(framelist  == NULL);
00922     bug_if(beamstr    == NULL);
00923     bug_if(usedframes == NULL);
00924     bug_if(image      == NULL);
00925     bug_if(applist    == NULL);
00926     bug_if(parlist    == NULL);
00927 
00928     bug_if(cpl_propertylist_append_double(updlist, "CRPIX1", xpos));
00929     bug_if(cpl_propertylist_append_double(updlist, "CRPIX2", ypos));
00930 
00931     /* Comments copied from actual header */
00932     bug_if(cpl_propertylist_set_comment(updlist, "CRPIX1", "Windowed "
00933                                         "position estimate along x"));
00934     bug_if(cpl_propertylist_set_comment(updlist, "CRPIX2", "Windowed "
00935                                         "position estimate along y"));
00936 
00937     if (iext == 0) {
00938         skip_if(irplib_dfs_save_image(framelist, parlist, usedframes,
00939                                       image, CPL_BPP_IEEE_FLOAT, RECIPE_STRING,
00940                                       VISIR_UTIL_CONVERT_PROCATG, updlist,
00941                                       NULL, visir_pipe_id, proname));
00942         if (auxrawname != NULL) {
00943             auximage = cpl_image_load(auxrawname, CPL_TYPE_UNSPECIFIED, 0,
00944                                       iext);
00945             skip_if(auximage == NULL);
00946             skip_if(irplib_dfs_save_image(framelist, parlist, usedframes,
00947                                           auximage, CPL_BPP_IEEE_FLOAT,
00948                                           RECIPE_STRING,
00949                                           VISIR_UTIL_CONVERT_AUX_PROCATG,
00950                                           updlist, NULL, visir_pipe_id,
00951                                           auxproname));
00952         }
00953     } else {
00954         int jext;
00955 
00956         for (jext = 1 + proext; jext < iext; jext++) {
00957             if (jext == 0) {
00958                 skip_if(irplib_dfs_save_propertylist(framelist, parlist,
00959                                                      usedframes, RECIPE_STRING,
00960                                                      VISIR_UTIL_CONVERT_PROCATG,
00961                                                      NULL, NULL, visir_pipe_id,
00962                                                      proname));
00963                 if (auxrawname != NULL) {
00964                     skip_if(irplib_dfs_save_propertylist(framelist, parlist,
00965                                                          usedframes,
00966                                                          RECIPE_STRING,
00967                                                  VISIR_UTIL_CONVERT_AUX_PROCATG,
00968                                                          NULL, NULL,
00969                                                          visir_pipe_id,
00970                                                          auxproname));
00971                 }
00972             } else {
00973                 /* FIXME: Copy unused/unmodified extension header ? */
00974                 skip_if(cpl_propertylist_save(plempty, proname,
00975                                               CPL_IO_EXTEND));
00976                 if (auxrawname != NULL) {
00977                     skip_if(cpl_propertylist_save(plempty, auxproname,
00978                                                   CPL_IO_EXTEND));
00979                 }
00980             }
00981         }
00982         skip_if(cpl_image_save(image, proname, CPL_BPP_IEEE_FLOAT,
00983                                updlist, CPL_IO_EXTEND));
00984         if (auxrawname != NULL) {
00985             auximage = cpl_image_load(auxrawname, CPL_TYPE_UNSPECIFIED, 0,
00986                                       iext);
00987             skip_if(auximage == NULL);
00988             skip_if(cpl_image_save(auximage, auxproname, CPL_BPP_IEEE_FLOAT,
00989                                    updlist, CPL_IO_EXTEND));
00990         }
00991     }
00992 
00993     end_skip;
00994 
00995     cpl_image_delete(auximage);
00996     cpl_free(proname);
00997     cpl_free(auxproname);
00998     cpl_propertylist_delete(plempty);
00999     cpl_propertylist_delete(updlist);
01000 
01001     return CPL_ERROR_NONE;
01002 }

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