visir_img_phot.c

00001 /* $Id: visir_img_phot.c,v 1.157 2009/03/09 14:11:06 llundin 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: llundin $
00023  * $Date: 2009/03/09 14:11:06 $
00024  * $Revision: 1.157 $
00025  * $Name: visir-3_2_2 $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 
00033 /*-----------------------------------------------------------------------------
00034                                 Includes
00035  -----------------------------------------------------------------------------*/
00036 
00037 #include <string.h>
00038 #include <float.h>
00039 
00040 #include "visir_recipe.h"
00041 #include "irplib_strehl.h"
00042 
00043 /*-----------------------------------------------------------------------------
00044                                 Define   
00045  -----------------------------------------------------------------------------*/
00046 
00047 #define VISIR_IMG_PHOT_POS_WARN         10.0
00048 #define VISIR_IMG_PHOT_POS_ERROR        25.0
00049 #define VISIR_IMG_PHOT_POS_UNCERTAINTY  10.0
00050 #define STREHL_M1                       8.0
00051 #define STREHL_M2                       1.1
00052 #define STREHL_BOX_SIZE                 64
00053 #define STREHL_STAR_RADIUS              2.0
00054 #define STREHL_BG_R1                    2.0
00055 #define STREHL_BG_R2                    3.0
00056 
00057 #define RECIPE_STRING "visir_img_phot"
00058 
00059 
00060 /* FITS keys to be loaded for all raw files */
00061 #define RECIPE_KEYS_REGEXP_ALL \
00062         VISIR_PFITS_REGEXP_IMG_RECOMBINE \
00063     "|" VISIR_PFITS_REGEXP_IMG_SENSIT
00064 
00065 /* FITS keys to be loaded for first raw file */
00066 #define RECIPE_KEYS_REGEXP               \
00067         RECIPE_KEYS_REGEXP_ALL           \
00068     "|" VISIR_PFITS_IMG_PHOT_COPY        \
00069     "|" VISIR_PFITS_REGEXP_IMG_PHOT_PAF
00070 
00071 /* FITS keys to be loaded for first raw file, in case WCS is used */
00072 #define RECIPE_KEYS_REGEXP_WCS \
00073         RECIPE_KEYS_REGEXP \
00074     "|" IRPLIB_PFITS_WCS_REGEXP
00075 
00076 
00077 /*-----------------------------------------------------------------------------
00078                             Private Functions prototypes
00079  -----------------------------------------------------------------------------*/
00080 
00081 static double visir_img_phot_eccent_four(const cpl_apertures *, int, int,
00082                                          const cpl_apertures *, int, int);
00083 
00084 #ifdef VISIR_IMG_PHOT_USE_ECCENT_THREE
00085 static double visir_img_phot_eccent_three(const cpl_apertures *, int,
00086                                           const cpl_apertures *, int, int);
00087 #endif
00088 
00089 static double visir_img_phot_jy_from_cat(const char *, const char *, double,
00090                                          double, const char *);
00091 static int visir_img_phot_sensit(const cpl_image *, const irplib_framelist *,
00092                                  const char *);
00093 static int visir_img_phot_flux_three(const cpl_image *);
00094 static int visir_img_phot_flux_four(const cpl_image *);
00095 static int visir_img_phot_flux(const cpl_image *, double, double, int, int, int,
00096                                double *, double *, double *, double *, double*);
00097 
00098 static cpl_error_code visir_get_filter_infos(const char *, double *, double *);
00099 
00100 static cpl_error_code visir_img_phot_qc(cpl_propertylist *,
00101                                         cpl_propertylist *,
00102                                         cpl_boolean,
00103                                         const irplib_framelist *);
00104 
00105 static cpl_error_code visir_img_phot_save(cpl_frameset *,
00106                                           const cpl_parameterlist *,
00107                                           const cpl_propertylist *,
00108                                           const cpl_propertylist *,
00109                                           const cpl_image *,
00110                                           const cpl_image *);
00111 
00112 VISIR_RECIPE_DEFINE(visir_img_phot,
00113                     VISIR_PARAM_RADII | VISIR_PARAM_JYVAL |
00114                     VISIR_PARAM_REFINE | VISIR_PARAM_XCORR |
00115                     VISIR_PARAM_OFFSETS | VISIR_PARAM_OBJECTS |
00116                     VISIR_PARAM_NODPOS |  VISIR_PARAM_AUTOBPM |
00117                     VISIR_PARAM_GLITCH | VISIR_PARAM_PURGE |
00118                     VISIR_PARAM_UNION  | VISIR_PARAM_REJECT |
00119                     VISIR_PARAM_COMBINE |
00120                     VISIR_PARAM_STRIPITE | VISIR_PARAM_STRIPMOR |
00121                     VISIR_PARAM_PLOT,
00122                     "Sensitivity computation",
00123                     "This recipe computes the conversion factor and the "
00124                     "sentitivity of a\n"
00125                     "standard star. It uses a standard star catalog.\n"
00126                     "The files listed in the Set Of Frames (sof-file) "
00127                     "must be tagged:\n"
00128                     "VISIR-std-star-observation.fits " VISIR_IMG_PHOT_RAW
00129                     "\n"
00130                     "VISIR-Imaging-Standard-Star-Catalog.fits "
00131                     VISIR_IMA_STD_CAT_PROCATG "\n"
00132                     MAN_VISIR_CALIB_BPM_IMG);
00133 
00134 /*-----------------------------------------------------------------------------
00135                             Static variables
00136  -----------------------------------------------------------------------------*/
00137 
00138 static const int fits_strlen = IRPLIB_FITS_STRLEN;
00139 
00140 static struct {
00141     /* Inputs */
00142     double      jy_val;
00143     int         r0_max;
00144     int         r1;
00145     int         r2;
00146 
00147     /* Outputs */
00148     double      exptime;
00149     double      pscale;
00150     char        star_name[IRPLIB_FITS_STRLEN];
00151     char        filter[IRPLIB_FITS_STRLEN];
00152     double      bg_sigma;
00153     double      flux_snr;
00154     double      flux_snr_noise;
00155     double      flux_tot;
00156     double      fwhm_x;
00157     double      fwhm_y;
00158     double      fwhm_x_pos1;
00159     double      fwhm_y_pos1;
00160     double      fwhm_x_pos2;
00161     double      fwhm_y_pos2;
00162     double      fwhm_x_neg1;
00163     double      fwhm_y_neg1;
00164     double      fwhm_x_neg2;
00165     double      fwhm_y_neg2;
00166     double      sensitivity;
00167     double      conversion;
00168     double      strehl;
00169     double      strehl_err;
00170 } visir_img_phot_config;
00171 
00172 
00173 /*----------------------------------------------------------------------------*/
00177 /*----------------------------------------------------------------------------*/
00178 
00179 /*-----------------------------------------------------------------------------
00180                                 Functions code
00181  -----------------------------------------------------------------------------*/
00182 
00183 /*----------------------------------------------------------------------------*/
00190 /*----------------------------------------------------------------------------*/
00191 static int visir_img_phot(cpl_frameset            * framelist,
00192                           const cpl_parameterlist * parlist)
00193 {
00194     cpl_errorstate cleanstate = cpl_errorstate_get();
00195     irplib_framelist * allframes = NULL;
00196     irplib_framelist * rawframes = NULL;
00197     cpl_propertylist * qclist    = cpl_propertylist_new();
00198     cpl_propertylist * paflist   = cpl_propertylist_new();
00199     const char      *  badpix;
00200     const char      *  star_cat;
00201     const char      *  flat;
00202     cpl_image       ** combined = NULL;
00203     const char      *  sval;
00204     cpl_boolean        drop_wcs;
00205     const char       * keys_regexp =  "^(" RECIPE_KEYS_REGEXP_WCS ")$";
00206     const char * combine_string;
00207     cpl_geom_combine combine_mode;
00208 
00209 
00210 
00211     visir_img_phot_config.exptime = -1.0;
00212     visir_img_phot_config.pscale = -1.0;
00213     visir_img_phot_config.star_name[0] = (char)0;
00214     visir_img_phot_config.filter[0] = (char)0;
00215     visir_img_phot_config.bg_sigma = -1.0;
00216     visir_img_phot_config.flux_snr = -1.0;
00217     visir_img_phot_config.flux_snr_noise = -1.0;
00218     visir_img_phot_config.flux_tot = -1.0;
00219     visir_img_phot_config.fwhm_x = -1.0;
00220     visir_img_phot_config.fwhm_y = -1.0;
00221     visir_img_phot_config.fwhm_x_pos1 = -1.0;
00222     visir_img_phot_config.fwhm_y_pos1 = -1.0;
00223     visir_img_phot_config.fwhm_x_pos2 = -1.0;
00224     visir_img_phot_config.fwhm_y_pos2 = -1.0;
00225     visir_img_phot_config.fwhm_x_neg1 = -1.0;
00226     visir_img_phot_config.fwhm_y_neg1 = -1.0;
00227     visir_img_phot_config.fwhm_x_neg2 = -1.0;
00228     visir_img_phot_config.fwhm_y_neg2 = -1.0;
00229     visir_img_phot_config.sensitivity = -1.0;
00230     visir_img_phot_config.conversion = -1.0;
00231     visir_img_phot_config.strehl = -1.0;
00232     visir_img_phot_config.strehl_err = -1.0;
00233 
00234     /* Retrieve input parameters */
00235     combine_string = visir_parameterlist_get_string(parlist, RECIPE_STRING,
00236                                                     VISIR_PARAM_COMBINE);
00237 
00238     bug_if (combine_string == NULL);
00239 
00240     if (combine_string[0] == 'u')
00241         combine_mode = CPL_GEOM_UNION;
00242     else if (combine_string[0] == 'f')
00243         combine_mode = CPL_GEOM_FIRST;
00244     else if (combine_string[0] == 'i')
00245         combine_mode = CPL_GEOM_INTERSECT;
00246     else
00247         skip_if(1);
00248 
00249 
00250     visir_img_phot_config.jy_val = 
00251         visir_parameterlist_get_double(parlist, RECIPE_STRING, VISIR_PARAM_JYVAL);
00252     skip_if (0);
00253 
00254     sval = visir_parameterlist_get_string(parlist, RECIPE_STRING, VISIR_PARAM_RADII);
00255     skip_if (sval == NULL);
00256 
00257     skip_if (sscanf(sval, "%d %d %d",
00258                     &visir_img_phot_config.r0_max,
00259                     &visir_img_phot_config.r1,
00260                     &visir_img_phot_config.r2) != 3);
00261 
00262     /* Identify the RAW and CALIB frames in the input frameset */
00263     skip_if (visir_dfs_set_groups(framelist));
00264 
00265     /* Objects observation */
00266     allframes = irplib_framelist_cast(framelist);
00267     skip_if(allframes == NULL);
00268     rawframes = irplib_framelist_extract(allframes, VISIR_IMG_PHOT_RAW);
00269 
00270     skip_if (rawframes == NULL);
00271 
00272     irplib_framelist_empty(allframes);
00273 
00274     skip_if(irplib_framelist_load_propertylist(rawframes, 0, 0, keys_regexp,
00275                                                CPL_FALSE));
00276 
00277     skip_if(irplib_framelist_load_propertylist_all(rawframes, 0, "^("
00278                                                    RECIPE_KEYS_REGEXP_ALL
00279                                                    ")$", CPL_FALSE));
00280 
00281     skip_if(visir_dfs_check_framelist_tag(rawframes));
00282     
00283     /* Standard star catalog */
00284     star_cat = irplib_frameset_find_file(framelist, VISIR_CALIB_STDSTAR_IMG);
00285     if (star_cat == NULL) {
00286          cpl_msg_error(cpl_func, "The input files has no star catalog tagged "
00287                        "%s", VISIR_CALIB_STDSTAR_IMG);
00288          visir_error_set(CPL_ERROR_DATA_NOT_FOUND);
00289          skip_if(1);
00290     }
00291 
00292     /* Bad pixels calibration file */
00293     badpix = irplib_frameset_find_file(framelist, VISIR_CALIB_BPM);
00294 
00295     /* Flatfield calibration file */
00296     flat = irplib_frameset_find_file(framelist, VISIR_CALIB_FLAT);
00297 
00298 
00299     /* DIT must be present every where */  
00300     skip_if(irplib_framelist_contains(rawframes, VISIR_PFITS_DOUBLE_DIT,
00301                                       CPL_TYPE_DOUBLE, CPL_FALSE, 0.0));
00302     if(irplib_framelist_contains(rawframes, VISIR_PFITS_DOUBLE_DIT,
00303                                  CPL_TYPE_DOUBLE, CPL_TRUE, 1e-5)) {
00304         /* Allow 0.1 ms difference - or warn */
00305         /* FIXME: The recipe does not properly handle non-uniform DITSs */  
00306         visir_error_reset("DIT differs by more than %g", 1e-5);
00307     }
00308 
00309     /* FIXME: Verify the angular distance */
00310     skip_if(irplib_framelist_contains(rawframes, VISIR_PFITS_DOUBLE_RA,
00311                                       CPL_TYPE_DOUBLE, CPL_FALSE, 0.0));
00312 
00313     /* FIXME: Allow 1 degree difference */
00314     skip_if(irplib_framelist_contains(rawframes, VISIR_PFITS_DOUBLE_DEC,
00315                                       CPL_TYPE_DOUBLE, CPL_TRUE, 1.0));
00316 
00317     skip_if(irplib_framelist_contains(rawframes, VISIR_PFITS_INT_CHOP_NCYCLES,
00318                                       CPL_TYPE_INT, CPL_TRUE, 0.0));
00319 
00320     skip_if(irplib_framelist_contains(rawframes, VISIR_PFITS_INT_NDIT,
00321                                       CPL_TYPE_INT, CPL_TRUE, 0.0));
00322 
00323     skip_if(irplib_framelist_contains(rawframes, VISIR_PFITS_STRING_STARNAME,
00324                                       CPL_TYPE_STRING, CPL_TRUE, 0.0));
00325 
00326     skip_if(irplib_framelist_contains(rawframes, VISIR_PFITS_STRING_INSMODE,
00327                                       CPL_TYPE_STRING, CPL_TRUE, 0.0));
00328 
00329     if (strncmp("IMG", visir_pfits_get_insmode(
00330                     irplib_framelist_get_propertylist_const(rawframes, 0)),
00331                 6) == 0) {
00332         skip_if(irplib_framelist_contains(rawframes, VISIR_PFITS_STRING_FILTER1,
00333                                           CPL_TYPE_STRING, CPL_TRUE, 0.0));
00334     } else {
00335         skip_if(irplib_framelist_contains(rawframes, VISIR_PFITS_STRING_FILTER2,
00336                                           CPL_TYPE_STRING, CPL_TRUE, 0.0));
00337     }
00338 
00339     skip_if(irplib_framelist_contains(rawframes, VISIR_PFITS_STRING_PIXSCALE,
00340                                       CPL_TYPE_STRING, CPL_TRUE, 0.0));
00341 
00342     /* Combine the frames */
00343     cpl_msg_info(cpl_func, "Combining the images");
00344     combined = visir_img_recombine(RECIPE_STRING, parlist, rawframes, badpix, flat,
00345                                    combine_mode, &drop_wcs, CPL_FALSE, 0.0, 0);
00346 
00347     if (combined == NULL) {
00348         cpl_msg_error(cpl_func, "Could not combine the input frames");
00349         skip_if(1);
00350     }
00351     
00352     /* Compute the background values of the HCYCLE frames */
00353     skip_if(visir_qc_append_background(qclist, rawframes, 0, 0));
00354 
00355     /* Compute here the sensitivity */
00356     cpl_msg_info(cpl_func, "Computing the sensitivity");
00357     if (visir_img_phot_sensit(combined[0], rawframes, star_cat)) {
00358         cpl_msg_error(cpl_func, "Could not compute sensitivity: '%s' in %s",
00359                         cpl_error_get_message(), cpl_error_get_where());
00360         skip_if(1);
00361     }
00362 
00363     skip_if (visir_img_phot_qc(qclist, paflist, drop_wcs, rawframes));
00364     irplib_framelist_empty(rawframes);
00365 
00366     /* PRO.CATG */
00367     bug_if (cpl_propertylist_append_string(paflist, CPL_DFS_PRO_CATG,
00368                                            VISIR_IMG_PHOT_COMBINED_PROCATG));
00369 
00370     /* Save the combined image and contribution map */
00371     cpl_msg_info(cpl_func, "Saving the combined image and contribution map");
00372     skip_if (visir_img_phot_save(framelist, parlist, qclist, paflist,
00373                             combined[0], combined[1]));
00374 
00375     end_skip;
00376 
00377     cpl_propertylist_delete(paflist);
00378     cpl_propertylist_delete(qclist);
00379     irplib_framelist_delete(allframes);
00380     irplib_framelist_delete(rawframes);
00381 
00382     if (combined) {
00383         cpl_image_delete(combined[0]);
00384         cpl_image_delete(combined[1]);
00385         cpl_free(combined);
00386     }
00387 
00388     return cpl_error_get_code();
00389 
00390 }
00391  
00392 /*----------------------------------------------------------------------------*/
00413 /*----------------------------------------------------------------------------*/
00414 static int visir_img_phot_sensit(const cpl_image * combined,
00415                                  const irplib_framelist * rawframes,
00416                                  const char * star_cat)
00417 {
00418     cpl_errorstate cleanstate = cpl_errorstate_get();
00419     const cpl_propertylist * plist = NULL;
00420     double             exptime;
00421     double             dit;
00422     int                ndit;
00423     int                ncycles, nnod;
00424     double             ra, dec;
00425     const char       * sval;
00426     double             f2;
00427 
00428 
00429     skip_if (0);
00430  
00431     plist = irplib_framelist_get_propertylist_const(rawframes, 0);
00432     skip_if (0);
00433 
00434     /* Get the total exposure time */
00435     /* DIT */
00436     dit = visir_pfits_get_dit(plist);
00437     /* NDIT */
00438     ndit = visir_pfits_get_ndit(plist);
00439     /* NNOD */
00440     nnod = irplib_framelist_get_size(rawframes);
00441     /* Number of chopping cycles */
00442     ncycles = visir_pfits_get_chop_ncycles(plist);
00443 
00444     /* Exptime * 2 because of chopping */
00445     exptime = 2 * dit * ndit * nnod * ncycles;
00446     visir_img_phot_config.exptime = exptime;
00447 
00448     if (exptime <= 0 || cpl_error_get_code()) {
00449         cpl_msg_error(cpl_func, "Illegal exposure time "
00450                       "(dit=%g:ndit=%d:ncycles=%d:nnod=%d): %g",
00451                       dit, ndit, ncycles, nnod, exptime);
00452         skip_if(1);
00453     }
00454 
00455     /* Copy the standard star name */
00456     skip_if ((sval = visir_pfits_get_starname(plist)) == NULL);
00457     (void) strncpy(visir_img_phot_config.star_name, sval, fits_strlen);
00458 
00459     /* Copy the filter name */
00460     skip_if ((sval = visir_pfits_get_filter(plist)) == NULL);
00461     (void)strncpy(visir_img_phot_config.filter, sval, fits_strlen);
00462    
00463     /* Get RA / DEC */
00464     ra  = visir_pfits_get_ra(plist);
00465     skip_if (0);
00466     dec = visir_pfits_get_dec(plist);
00467     skip_if (0);
00468 
00469     /* Get the pixel scale */
00470     sval = visir_pfits_get_pixscale(plist);
00471     skip_if (0);
00472 
00473     visir_img_phot_config.pscale = atof(sval);
00474     
00475     /* Get the JY value from the catalog if not user provided */
00476     if (visir_img_phot_config.jy_val < -998) {
00477         visir_img_phot_config.jy_val =
00478             visir_img_phot_jy_from_cat(star_cat, visir_img_phot_config.filter,
00479                                        ra,dec, visir_img_phot_config.star_name);
00480         skip_if (visir_img_phot_config.jy_val < -998);
00481     }
00482     
00483     /* Display the result */
00484     cpl_msg_info(cpl_func, "Star %s with filter %s : %g Jy",
00485             visir_img_phot_config.star_name,
00486             visir_img_phot_config.filter,
00487             visir_img_phot_config.jy_val);
00488    
00489     /* Compute the background signa */
00490     visir_img_phot_config.bg_sigma = visir_img_phot_sigma_clip(combined);
00491     skip_if (0);
00492     
00493     /* Get the flux and flux noise and fwhm */
00494     cpl_msg_info(cpl_func, "Compute the star flux");
00495     sval = visir_pfits_get_chopnod_dir(plist);
00496 #if 1
00497     if (sval != NULL && !strcmp(sval, "PERPENDICULAR")) {
00498         /* 4 sources */
00499         skip_if (visir_img_phot_flux_four(combined));
00500     } else if (sval != NULL && !strcmp(sval, "PARALLEL")) {
00501         /* 3 sources */
00502         skip_if (visir_img_phot_flux_three(combined));
00503     } else {
00504         if (sval == NULL) {
00505             visir_error_reset("Could not get FITS key");
00506         } else {
00507             cpl_msg_warning(cpl_func, "Unknown chopping direction: %s", sval);
00508         }
00509         cpl_msg_warning(cpl_func, "Proceeding as if FITS card %s had value %s",
00510                         "ESO SEQ CHOPNOD DIR", "PERPENDICULAR");
00511         if (visir_img_phot_flux_four(combined)) {
00512             visir_error_reset("Proceeding as if FITS card %s had value %s",
00513                               "ESO SEQ CHOPNOD DIR", "PARALLEL");
00514             skip_if (visir_img_phot_flux_three(combined));
00515         }        
00516     }
00517 #else
00518     if (sval == NULL) {
00519         visir_error_reset("Could not get chopping direction");
00520         if (visir_img_phot_flux_three(combined)) {
00521             cpl_msg_error(cpl_func, "Could not compute the flux");
00522             skip_if(1);
00523         }
00524     } else if (!strcmp(sval, "PARALLEL")) {
00525         /* 3 sources */
00526         if (visir_img_phot_flux_three(combined)) {
00527             cpl_msg_error(cpl_func, "Could not compute the flux");
00528             skip_if(1);
00529         }
00530     } else {
00531         /* Default is 4 sources */
00532         if (strcmp(sval, "PERPENDICULAR"))
00533             cpl_msg_warning(cpl_func, "Unknown chopping direction: %s", sval);
00534         if (visir_img_phot_flux_four(combined)) {
00535             cpl_msg_error(cpl_func, "Could not compute the flux");
00536             skip_if(1);
00537         }
00538     }
00539 #endif
00540 
00541     /* Compute the sensitivity and the conversion factor */
00542 
00543     skip_if ( visir_img_phot_config.flux_snr == 0 );
00544     skip_if ( visir_img_phot_config.flux_snr_noise == 0 );
00545     skip_if ( visir_img_phot_config.jy_val == 0 );
00546 
00547     f2  = visir_img_phot_config.flux_snr / visir_img_phot_config.flux_snr_noise;
00548     f2 *= sqrt(3600/visir_img_phot_config.exptime);
00549     visir_img_phot_config.sensitivity = visir_img_phot_config.jy_val*1000*10/f2;
00550     visir_img_phot_config.conversion = visir_img_phot_config.flux_tot /
00551         visir_img_phot_config.jy_val;
00552 
00553     end_skip;
00554 
00555     cpl_msg_info(cpl_func, "Sensitivity : %g", visir_img_phot_config.sensitivity);
00556     cpl_msg_info(cpl_func, "Conversion  : %g", visir_img_phot_config.conversion);
00557     cpl_msg_info(cpl_func, "Strehl      : %g", visir_img_phot_config.strehl);
00558     cpl_msg_info(cpl_func, "Strehl error: %g", visir_img_phot_config.strehl_err);
00559 
00560     return cpl_error_get_code();
00561 }
00562  
00563 /*----------------------------------------------------------------------------*/
00573 /*----------------------------------------------------------------------------*/
00574 static double visir_img_phot_jy_from_cat(
00575         const char * star_cat,
00576         const char * filter,
00577         double       ra,
00578         double       dec,
00579         const char * star_name) 
00580 {
00581     cpl_table    * tab = NULL;
00582     cpl_vector   * v_ra = NULL;
00583     cpl_vector   * v_dec = NULL;
00584     const char   * stdstar; 
00585     int            nb_stars;
00586     const double   max_radius = VISIR_STAR_MAX_RADIUS;
00587     double         value = -999;
00588     double         jy;
00589     double         dist;
00590     int            min_dist_ind;
00591 
00592 
00593     skip_if( 0 );
00594     skip_if( star_cat  == NULL );
00595     skip_if( star_name == NULL );
00596     skip_if( filter    == NULL );
00597   
00598     /* Open the star catalog */
00599     if ((tab = cpl_table_load(star_cat, 1, 1)) == NULL) {
00600         cpl_msg_error(cpl_func, "Could not load the star catalog: %s",
00601                       star_cat);
00602         skip_if(1);
00603     }
00604 
00605     /* Check that the filter is in the table */
00606     if (!cpl_table_has_column(tab, filter)) {
00607         cpl_msg_error(cpl_func, "Catalog %s has no column for filter: %s",
00608                       star_cat, filter);
00609         visir_error_set(CPL_ERROR_DATA_NOT_FOUND);
00610         skip_if(1);
00611     }
00612 
00613     if (!cpl_table_has_column(tab, "STARS")) {
00614         cpl_msg_error(cpl_func, "Catalog %s does not have a column labeled %s",
00615                       star_cat, "STARS");
00616         visir_error_set(CPL_ERROR_BAD_FILE_FORMAT);
00617         skip_if(1);
00618     }
00619 
00620     nb_stars = cpl_table_get_nrow(tab);
00621     skip_if (nb_stars < 1);
00622 
00623     /* Get the RA and DEC columns */
00624     v_ra = cpl_vector_wrap(nb_stars, cpl_table_get_data_double(tab, "RA"));
00625     skip_if( v_ra == NULL);
00626 
00627     v_dec = cpl_vector_wrap(nb_stars, cpl_table_get_data_double(tab, "DEC"));
00628     skip_if( v_dec == NULL);
00629 
00630     min_dist_ind = visir_star_find(v_ra, v_dec, ra, dec, max_radius, &dist);
00631 
00632     if (min_dist_ind < 0) {
00633         cpl_msg_error(cpl_func, "Observation target '%s' was not found among "
00634                       "the %d entries in the standard star catalog %s",
00635                       star_name, nb_stars, star_cat);
00636         skip_if(1);
00637     }
00638 
00639     stdstar = cpl_table_get_string(tab, "STARS", min_dist_ind);
00640     skip_if ( stdstar == NULL );
00641 
00642     jy = cpl_table_get(tab, filter, min_dist_ind, NULL);
00643     skip_if( 0 );
00644 
00645     value = jy;
00646 
00647     if (strcmp(stdstar, star_name) != 0 && dist > 0.0) {
00648         /* The names do not match, nor does the location (exactly) */
00649         cpl_msg_warning(cpl_func, "The standard star '%s' at (RA,DEC)=(%g,%g) "
00650                         "in the FITS header is closest to the catalog star "
00651                         "'%s' at (RA,DEC)=(%g,%g) at distance %g degrees",
00652                         star_name, ra, dec, stdstar,
00653                         cpl_vector_get(v_ra,  min_dist_ind),
00654                         cpl_vector_get(v_dec, min_dist_ind), dist);
00655     } else if (dist > 0.0) {
00656         /* The names match, but the location does not (exactly) */
00657         cpl_msg_warning(cpl_func, "The location of the standard star '%s' in "
00658                         "the FITS header (RA,DEC)=(%g,%g) and the catalog "
00659                         "(RA,DEC)=(%g,%g) differ by %g degrees", stdstar, ra,
00660                         dec, cpl_vector_get(v_ra,  min_dist_ind),
00661                         cpl_vector_get(v_dec, min_dist_ind), dist);
00662     } else if (strcmp(stdstar, star_name) != 0) {
00663         /* The names do not match, but the location does */
00664         cpl_msg_warning(cpl_func, "The name of the standard star at (RA,DEC)="
00665                         "(%g,%g) in the FITS header '%s' and the catalog '%s' "
00666                         "are different", ra, dec, star_name, stdstar);
00667     } else {
00668         cpl_msg_info(cpl_func, "Standard star is '%s' at (RA, DEC)=(%g,%g)",
00669                      stdstar, ra, dec);
00670  
00671         if (cpl_msg_get_level() <= CPL_MSG_DEBUG)
00672             cpl_table_dump(tab, min_dist_ind, 1, stdout);
00673     }
00674 
00675     cpl_msg_info(cpl_func, "The standard star '%s' has %g Jy through filter %s",
00676                  stdstar, value, filter);
00677  
00678     end_skip;
00679 
00680     cpl_table_delete(tab);
00681     cpl_vector_unwrap(v_ra);
00682     cpl_vector_unwrap(v_dec);
00683 
00684     return value;
00685 }
00686 
00687 /*----------------------------------------------------------------------------*/
00696 /*----------------------------------------------------------------------------*/
00697 static int visir_img_phot_flux_three(const cpl_image * combined)
00698 {
00699     cpl_errorstate cleanstate = cpl_errorstate_get();
00700     cpl_image       *   min_combined = NULL;
00701     cpl_apertures   *   appos = NULL;
00702     cpl_apertures   *   apneg = NULL;
00703     cpl_vector      *   sigmas = NULL;
00704     double              psigmas[] = {5, 2, 1, 0.5};
00705     double              x[3];
00706     double              y[3];
00707     double              flux_snr[3];
00708     double              flux_snr_noise[3];
00709     double              flux_tot[3];
00710     double              fwhm_x[3];
00711     double              fwhm_y[3];
00712     double              dist1, dist2;
00713     int                 ngood_fwhm;
00714     double              lam, dlam;
00715     double              star_bg,star_peak,star_flux,psf_peak,psf_flux,bg_noise;
00716     double              eccmin = DBL_MAX;
00717     const int           nsigmas = sizeof(psigmas)/sizeof(double);
00718     int                 isigma;
00719 #ifdef VISIR_IMG_PHOT_USE_ECCENT_THREE
00720     int                 ipos, ineg1, ineg2;
00721 #endif
00722     int                 iappos, iapneg2[2];
00723     int                 i;
00724 
00725 
00726     if (cpl_error_get_code()) return cpl_error_get_code();
00727 
00728     cpl_ensure_code(combined != NULL, CPL_ERROR_NULL_INPUT);
00729 
00730     cpl_msg_info(cpl_func, "Detecting the 3-source star using %d sigma-levels "
00731                  "ranging from %g down to %g", nsigmas, psigmas[0],
00732                  psigmas[nsigmas-1]);
00733 
00734     sigmas = cpl_vector_new(1);
00735     min_combined = cpl_image_multiply_scalar_create(combined, -1.0);
00736     bug_if(0);
00737     for (isigma = 0; isigma < nsigmas; isigma++) {
00738 
00739         /* FIXME: Why ?! */
00740         irplib_error_recover(cleanstate, "Resetting error (why?)");
00741 
00742         bug_if(cpl_vector_set(sigmas, 0, psigmas[isigma]));
00743 
00744         /* Detect where the POSITIVE star is */
00745         cpl_apertures_delete(appos);
00746         appos = cpl_apertures_extract(combined, sigmas, NULL);
00747         if (appos == NULL) {
00748             cpl_msg_warning(cpl_func, "Found no positive star at sigma=%g",
00749                             psigmas[isigma]);
00750             continue;
00751         }
00752 
00753         /* Detect where the NEGATIVE stars are */
00754         cpl_apertures_delete(apneg);
00755         apneg = cpl_apertures_extract(min_combined, sigmas, NULL);
00756         if (apneg == NULL) {
00757             cpl_msg_warning(cpl_func, "Found no negative stars at sigma=%g",
00758                             psigmas[isigma]);
00759             continue;
00760         }
00761         if (cpl_apertures_get_size(apneg) < 2) {
00762             cpl_msg_warning(cpl_func, "Found just 1 negative star at sigma=%g, "
00763                             "need two", psigmas[isigma]);
00764             continue;
00765         }
00766 
00767         cpl_msg_info(cpl_func, "Found positive and negative stars at sigma=%g",
00768                      psigmas[isigma]);
00769         break;
00770     }
00771 
00772     skip_if(appos == NULL);
00773     skip_if(apneg == NULL);
00774     skip_if (cpl_apertures_get_size(apneg) < 2);
00775 
00776     if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
00777         cpl_apertures_dump(appos, stdout);
00778         cpl_apertures_dump(apneg, stdout);
00779     }
00780 
00781 #ifndef VISIR_IMG_PHOT_USE_ECCENT_THREE
00782     bug_if(irplib_apertures_find_max_flux(appos, &iappos, 1));
00783     bug_if(irplib_apertures_find_max_flux(apneg, iapneg2, 2));
00784 #else
00785     if (cpl_apertures_get_size(appos) > 1 || cpl_apertures_get_size(apneg) > 2)
00786         cpl_msg_info(cpl_func, "Selecting from %d positive and %d negative "
00787                      "stars 3 stars on a vertical line",
00788                      cpl_apertures_get_size(appos),
00789                      cpl_apertures_get_size(apneg));
00790 
00791     for (ipos = 1; ipos <= cpl_apertures_get_size(appos); ipos++) {
00792         for (ineg1 = 2; ineg1 <= cpl_apertures_get_size(apneg); ineg1++) {
00793             for (ineg2 = 1; ineg2 < ineg1; ineg2++) {
00794                 const double ecc = visir_img_phot_eccent_three(appos, ipos,
00795                                                                apneg,
00796                                                                ineg1, ineg2);
00797                 if (ecc < eccmin) {
00798                     if (eccmin < DBL_MAX)
00799                         cpl_msg_debug(cpl_func, "Found star positions with "
00800                                       "reduced mis-alignment [pixel]: "
00801                                       "%g < %g", ecc, eccmin);
00802                     eccmin = ecc;
00803                     iappos = ipos;
00804                     iapneg2[0] = ineg1;
00805                     iapneg2[1] = ineg2;
00806                 }
00807             }
00808         }
00809     }
00810 
00811     /* Star 1 should have largest flux */
00812     if (cpl_apertures_get_flux(apneg, iapneg2[0]) <
00813         cpl_apertures_get_flux(apneg, iapneg2[1])) {
00814         const int tmp = iapneg2[0];
00815         iapneg2[0] = iapneg2[1];
00816         iapneg2[1] = tmp;
00817     }
00818 
00819 #endif
00820 
00821     x[0] = cpl_apertures_get_centroid_x(appos, iappos);
00822     y[0] = cpl_apertures_get_centroid_y(appos, iappos);
00823 
00824     x[1] = cpl_apertures_get_centroid_x(apneg, iapneg2[0]);
00825     y[1] = cpl_apertures_get_centroid_y(apneg, iapneg2[0]);
00826     x[2] = cpl_apertures_get_centroid_x(apneg, iapneg2[1]);
00827     y[2] = cpl_apertures_get_centroid_y(apneg, iapneg2[1]);
00828 
00829     cpl_apertures_delete(appos);
00830     cpl_apertures_delete(apneg);
00831     appos = NULL;
00832     apneg = NULL;
00833 
00834     cpl_msg_info(cpl_func, "Positive star at position %g %g", x[0], y[0]);
00835     cpl_msg_info(cpl_func, "Negative star 1 at position %g %g", x[1], y[1]);
00836     cpl_msg_info(cpl_func, "Negative star 2 at position %g %g", x[2], y[2]);
00837 
00838     dist1 = sqrt((x[1]-x[0])*(x[1]-x[0])+(y[1]-y[0])*(y[1]-y[0]));
00839     dist2 = sqrt((x[2]-x[0])*(x[2]-x[0])+(y[2]-y[0])*(y[2]-y[0]));
00840     cpl_msg_info(cpl_func, "Star 1 Pos/Neg Distance: %g", dist1);
00841     cpl_msg_info(cpl_func, "Star 2 Pos/Neg Distance: %g", dist2);
00842 
00843 
00844     if (eccmin < DBL_MAX) {
00845         cpl_msg_info(cpl_func, "The deviation from a vertical line by "
00846                      "the three stars [pixel]: %g", eccmin);
00847         if (eccmin > VISIR_IMG_PHOT_POS_WARN) {
00848             if (eccmin > VISIR_IMG_PHOT_POS_ERROR) {
00849                 cpl_msg_error(cpl_func, "The deviation from a vertical line"
00850                               " by the three stars exceed %g, the detected "
00851                               "objects are wrong", VISIR_IMG_PHOT_POS_ERROR);
00852                 skip_if(1);
00853             }
00854             cpl_msg_warning(cpl_func, "The deviation from a vertical line "
00855                             "by the three stars exceed %g, the detected "
00856                             "objects may be wrong", VISIR_IMG_PHOT_POS_WARN);
00857         }
00858     }
00859 
00860     /* FIXME: Pick other object instead, and lower sigma if needed */
00861     if ((int)x[0]-IRPLIB_STREHL_BORDER <= 0 ||
00862         (int)y[0]-IRPLIB_STREHL_BORDER <= 0 ||
00863         (int)x[0]+IRPLIB_STREHL_BORDER > cpl_image_get_size_x(combined) || 
00864         (int)y[0]+IRPLIB_STREHL_BORDER > cpl_image_get_size_y(combined)) {
00865         cpl_msg_error(cpl_func, "Positive star at (%g,%g) is less than %d "
00866                       "pixels from the image border", x[0], y[0],
00867                       1+IRPLIB_STREHL_BORDER);
00868         skip_if(1);
00869     }
00870 
00871     /* FIXME: Useful ? */
00872     /* Verify the stars positions */
00873     if (fabs(dist1-dist2) > VISIR_IMG_PHOT_POS_UNCERTAINTY) {
00874         cpl_msg_error(cpl_func, "Too large Pos/Neg Distance between the two "
00875                       "stars: %g > %g", fabs(dist1-dist2),
00876                       VISIR_IMG_PHOT_POS_UNCERTAINTY);
00877         skip_if(1);
00878     }
00879 
00880     /* Photometry on positive stars */
00881     skip_if (visir_img_phot_flux(combined,
00882             x[0], y[0],
00883             visir_img_phot_config.r0_max,
00884             visir_img_phot_config.r1,
00885             visir_img_phot_config.r2,
00886             &(flux_snr[0]),
00887             &(flux_snr_noise[0]),
00888             &(flux_tot[0]),
00889             &(fwhm_x[0]),
00890             &(fwhm_y[0])));
00891 
00892     /* Photometry on negative stars */
00893     for (i=1 ; i<3 ; i++)
00894         skip_if (visir_img_phot_flux(min_combined,
00895                 x[i], y[i],
00896                 visir_img_phot_config.r0_max,
00897                 visir_img_phot_config.r1,
00898                 visir_img_phot_config.r2,
00899                 &(flux_snr[i]),
00900                 &(flux_snr_noise[i]),
00901                 &(flux_tot[i]),
00902                 &(fwhm_x[i]),
00903                 &(fwhm_y[i])));
00904 
00905     cpl_image_delete(min_combined);
00906     min_combined = NULL;
00907     
00908     /* Compute the results */
00909     /* Flux */
00910     visir_img_phot_config.flux_snr = 0.0;
00911     for (i=0 ; i<3 ; i++) visir_img_phot_config.flux_snr += flux_snr[i];
00912 
00913     /* Flux noise */
00914     visir_img_phot_config.flux_snr_noise = 0.0;
00915     for (i=0 ; i<3 ; i++) visir_img_phot_config.flux_snr_noise +=
00916         flux_snr_noise[i]*flux_snr_noise[i];
00917     visir_img_phot_config.flux_snr_noise = 
00918         sqrt(visir_img_phot_config.flux_snr_noise);
00919 
00920     /* Total flux */
00921     visir_img_phot_config.flux_tot = 0.0;
00922     for (i=0 ; i<3 ; i++) visir_img_phot_config.flux_tot += flux_tot[i];
00923     
00924     /* FWHM */
00925     ngood_fwhm = 0;
00926     visir_img_phot_config.fwhm_x = 0.0;
00927     for (i=0 ; i<3 ; i++) {
00928         if (fwhm_x[i] > 0.0) {
00929             visir_img_phot_config.fwhm_x += fwhm_x[i];
00930             ngood_fwhm ++;
00931         }
00932     }
00933     if (ngood_fwhm > 0) visir_img_phot_config.fwhm_x /= ngood_fwhm;
00934     else visir_img_phot_config.fwhm_x = -1.0;
00935     ngood_fwhm = 0;
00936     visir_img_phot_config.fwhm_y = 0.0;
00937     for (i=0 ; i<3 ; i++) {
00938         if (fwhm_y[i] > 0.0) {
00939             visir_img_phot_config.fwhm_y += fwhm_y[i];
00940             ngood_fwhm ++;
00941         }
00942     }
00943     if (ngood_fwhm > 0) visir_img_phot_config.fwhm_y /= ngood_fwhm;
00944     else visir_img_phot_config.fwhm_y = -1.0;
00945     visir_img_phot_config.fwhm_x_pos1 = fwhm_x[0];
00946     visir_img_phot_config.fwhm_y_pos1 = fwhm_y[0];
00947     visir_img_phot_config.fwhm_x_neg1 = fwhm_x[1];
00948     visir_img_phot_config.fwhm_y_neg1 = fwhm_y[1];
00949     visir_img_phot_config.fwhm_x_neg2 = fwhm_x[2];
00950     visir_img_phot_config.fwhm_y_neg2 = fwhm_y[2];
00951 
00952     /* Get lam and dlam from the filter name for the Strehl computation */
00953     if (visir_get_filter_infos(visir_img_phot_config.filter, &lam, &dlam)) {
00954         cpl_msg_error(cpl_func, "Could not get info for filter: %s",
00955                 visir_img_phot_config.filter);
00956         skip_if(1);
00957     }
00958     
00959     /* Strehl computation */
00960     if (irplib_strehl_compute(combined, STREHL_M1, STREHL_M2, lam, dlam, 
00961                 visir_img_phot_config.pscale,
00962                 STREHL_BOX_SIZE, x[0], y[0], STREHL_STAR_RADIUS,
00963                 STREHL_BG_R1, STREHL_BG_R2, -1, -1, 
00964                 &(visir_img_phot_config.strehl), 
00965                 &(visir_img_phot_config.strehl_err),
00966                 &star_bg, &star_peak, &star_flux, &psf_peak, &psf_flux,
00967                 &bg_noise)) {
00968         cpl_msg_error(cpl_func, "Could not compute the strehl: '%s' in %s",
00969                         cpl_error_get_message(), cpl_error_get_where());
00970         skip_if(1);
00971     }
00972 
00973 
00974     end_skip;
00975 
00976     cpl_apertures_delete(appos);
00977     cpl_apertures_delete(apneg);
00978     cpl_vector_delete(sigmas);
00979     cpl_image_delete(min_combined);
00980     
00981     return cpl_error_get_code();
00982 }
00983 
00984 /*----------------------------------------------------------------------------*/
00993 /*----------------------------------------------------------------------------*/
00994 static int visir_img_phot_flux_four(const cpl_image * combined)
00995 {
00996     cpl_errorstate cleanstate = cpl_errorstate_get();
00997     cpl_image       *   min_combined = NULL;
00998     cpl_apertures   *   appos = NULL;
00999     cpl_apertures   *   apneg = NULL;
01000     cpl_vector      *   sigmas = NULL;
01001     double              psigmas[] = {5, 2, 1, 0.5};
01002     double              x[4];
01003     double              y[4];
01004     double              flux_snr[4];
01005     double              flux_snr_noise[4];
01006     double              flux_tot[4];
01007     double              fwhm_x[4];
01008     double              fwhm_y[4];
01009     double              dist1, dist2;
01010     int                 ngood_fwhm;
01011     double              lam, dlam;
01012     double              star_bg,star_peak,star_flux,psf_peak,psf_flux,bg_noise;
01013     double              eccmin = DBL_MAX;
01014     const int           nsigmas = sizeof(psigmas)/sizeof(double);
01015     int                 isigma;
01016     int                 ipos1, ipos2, ineg1, ineg2;
01017     int                 i;
01018     int                 iappos2[] = {0, 0}; /* Avoid (false) uninit warning */
01019     int                 iapneg2[] = {0, 0}; /* Avoid (false) uninit warning */
01020 
01021 
01022     if (cpl_error_get_code()) return cpl_error_get_code();
01023 
01024     cpl_ensure_code(combined != NULL, CPL_ERROR_NULL_INPUT);
01025 
01026     cpl_msg_info(cpl_func, "Detecting the 4-source star using %d sigma-levels "
01027                  "ranging from %g down to %g", nsigmas, psigmas[0],
01028                  psigmas[nsigmas-1]);
01029 
01030     sigmas = cpl_vector_new(1);
01031     min_combined = cpl_image_multiply_scalar_create(combined, -1.0);
01032     bug_if(0);
01033     for (isigma = 0; isigma < nsigmas; isigma++) {
01034 
01035         /* FIXME: Why ?! */
01036         irplib_error_recover(cleanstate, "Resetting error (why?)");
01037 
01038         bug_if(cpl_vector_set(sigmas, 0, psigmas[isigma]));
01039 
01040         /* Detect where the POSITIVE stars are */
01041         cpl_apertures_delete(appos);
01042         appos = cpl_apertures_extract(combined, sigmas, NULL);
01043         if (appos == NULL) {
01044             cpl_msg_warning(cpl_func, "Found no positive stars at sigma=%g",
01045                             psigmas[isigma]);
01046             continue;
01047         }
01048         if (cpl_apertures_get_size(appos) < 2) {
01049             cpl_msg_warning(cpl_func, "Found just 1 positive star at sigma=%g, "
01050                             "need two", psigmas[isigma]);
01051             continue;
01052         }
01053 
01054         /* Detect where the NEGATIVE stars are */
01055         cpl_apertures_delete(apneg);
01056         apneg = cpl_apertures_extract(min_combined, sigmas, NULL);
01057         if (apneg == NULL) {
01058             cpl_msg_warning(cpl_func, "Found no negative stars at sigma=%g",
01059                             psigmas[isigma]);
01060             continue;
01061         }
01062         if (cpl_apertures_get_size(apneg) < 2) {
01063             cpl_msg_warning(cpl_func, "Found just 1 negative star at sigma=%g, "
01064                             "need two", psigmas[isigma]);
01065             continue;
01066         }
01067 
01068         cpl_msg_info(cpl_func, "Found positive and negative stars at sigma=%g",
01069                      psigmas[isigma]);
01070         break;
01071     }
01072 
01073     skip_if(appos == NULL);
01074     skip_if(apneg == NULL);
01075     skip_if (cpl_apertures_get_size(appos) < 2);
01076     skip_if (cpl_apertures_get_size(apneg) < 2);
01077 
01078     if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
01079         cpl_apertures_dump(appos, stdout);
01080         cpl_apertures_dump(apneg, stdout);
01081     }
01082 
01083     if (cpl_apertures_get_size(appos) > 2 || cpl_apertures_get_size(apneg) > 2)
01084         cpl_msg_info(cpl_func, "Selecting from %d positive and %d negative "
01085                      "stars two pairs that outline a square",
01086                      cpl_apertures_get_size(appos),
01087                      cpl_apertures_get_size(apneg));
01088 
01089     for (ipos1 = 2; ipos1 <= cpl_apertures_get_size(appos); ipos1++) {
01090         for (ipos2 = 1; ipos2 < ipos1; ipos2++) {
01091             for (ineg1 = 2; ineg1 <= cpl_apertures_get_size(apneg); ineg1++) {
01092                 for (ineg2 = 1; ineg2 < ineg1; ineg2++) {
01093                     const double ecc = visir_img_phot_eccent_four(appos, ipos1,
01094                                                                   ipos2, apneg,
01095                                                                   ineg1, ineg2);
01096 
01097                     if (ecc < eccmin) {
01098                         if (eccmin < DBL_MAX)
01099                             cpl_msg_debug(cpl_func, "Found star positions with "
01100                                          "reduced non-square-ness [pixel]: "
01101                                          "%g < %g", ecc, eccmin);
01102                         eccmin = ecc;
01103                         iappos2[0] = ipos1;
01104                         iappos2[1] = ipos2;
01105                         iapneg2[0] = ineg1;
01106                         iapneg2[1] = ineg2;
01107                     }
01108                 }
01109             }
01110         }
01111     }
01112 
01113     /* Star 1 should have largest flux */
01114     if (cpl_apertures_get_flux(appos, iappos2[0]) <
01115         cpl_apertures_get_flux(appos, iappos2[1])) {
01116         const int tmp = iappos2[0];
01117         iappos2[0] = iappos2[1];
01118         iappos2[1] = tmp;
01119     }
01120     if (cpl_apertures_get_flux(apneg, iapneg2[0]) <
01121         cpl_apertures_get_flux(apneg, iapneg2[1])) {
01122         const int tmp = iapneg2[0];
01123         iapneg2[0] = iapneg2[1];
01124         iapneg2[1] = tmp;
01125     }
01126 
01127 
01128     x[0] = cpl_apertures_get_centroid_x(appos, iappos2[0]);
01129     y[0] = cpl_apertures_get_centroid_y(appos, iappos2[0]);
01130     x[1] = cpl_apertures_get_centroid_x(appos, iappos2[1]);
01131     y[1] = cpl_apertures_get_centroid_y(appos, iappos2[1]);
01132 
01133     x[2] = cpl_apertures_get_centroid_x(apneg, iapneg2[0]);
01134     y[2] = cpl_apertures_get_centroid_y(apneg, iapneg2[0]);
01135     x[3] = cpl_apertures_get_centroid_x(apneg, iapneg2[1]);
01136     y[3] = cpl_apertures_get_centroid_y(apneg, iapneg2[1]);
01137 
01138     cpl_apertures_delete(appos);
01139     cpl_apertures_delete(apneg);
01140     appos = NULL;
01141     apneg = NULL;
01142 
01143     cpl_msg_info(cpl_func, "Positive star 1 at position %g %g", x[0], y[0]);
01144     cpl_msg_info(cpl_func, "Positive star 2 at position %g %g", x[1], y[1]);
01145 
01146     cpl_msg_info(cpl_func, "Negative star 1 at position %g %g", x[2], y[2]);
01147     cpl_msg_info(cpl_func, "Negative star 2 at position %g %g", x[3], y[3]);
01148 
01149     /* FIXME: Useful ?  - change to 1D-distances  - and move into sigma loop */
01150     dist1 = sqrt((x[2]-x[0])*(x[2]-x[0])+(y[2]-y[0])*(y[2]-y[0]));
01151     dist2 = sqrt((x[3]-x[1])*(x[3]-x[1])+(y[3]-y[1])*(y[3]-y[1]));
01152     cpl_msg_info(cpl_func, "Star 1 Pos/Neg Distance: %g", dist1);
01153     cpl_msg_info(cpl_func, "Star 2 Pos/Neg Distance: %g", dist2);
01154 
01155     if (eccmin < DBL_MAX) {
01156         cpl_msg_info(cpl_func, "The deviation from a horizontal square by "
01157                      "the two star pairs [pixel]: %g", eccmin);
01158         if (eccmin > VISIR_IMG_PHOT_POS_WARN) {
01159             if (eccmin > VISIR_IMG_PHOT_POS_ERROR) {
01160                 cpl_msg_error(cpl_func, "The deviation from a horizontal square"
01161                               " by the two star pairs exceed %g, the detected "
01162                               "objects are wrong", VISIR_IMG_PHOT_POS_ERROR);
01163                 skip_if(1);
01164             }
01165             cpl_msg_warning(cpl_func, "The deviation from a horizontal square "
01166                             "by the two star pairs exceed %g, the detected "
01167                             "objects may be wrong", VISIR_IMG_PHOT_POS_WARN);
01168         }
01169     }
01170 
01171     if ((int)x[0]-IRPLIB_STREHL_BORDER <= 0 ||
01172         (int)y[0]-IRPLIB_STREHL_BORDER <= 0 ||
01173         (int)x[0]+IRPLIB_STREHL_BORDER > cpl_image_get_size_x(combined) || 
01174         (int)y[0]+IRPLIB_STREHL_BORDER > cpl_image_get_size_y(combined)) {
01175         cpl_msg_error(cpl_func, "Positive star 1 at (%g,%g) is less than %d "
01176                       "pixels from the image border", x[0], y[0],
01177                       1+IRPLIB_STREHL_BORDER);
01178         skip_if(1);
01179     }
01180 
01181     /* Verify the stars positions */
01182     if (fabs(dist1-dist2) > VISIR_IMG_PHOT_POS_UNCERTAINTY) {
01183         cpl_msg_error(cpl_func, "Too large Pos/Neg Distance between the two "
01184                       "stars: %g > %g", fabs(dist1-dist2),
01185                       VISIR_IMG_PHOT_POS_UNCERTAINTY);
01186         skip_if(1);
01187     }
01188 
01189     /* Photometry on positive stars */
01190     for (i=0 ; i<2 ; i++)
01191         skip_if (visir_img_phot_flux(combined,
01192                 x[i], y[i],
01193                 visir_img_phot_config.r0_max,
01194                 visir_img_phot_config.r1,
01195                 visir_img_phot_config.r2,
01196                 &(flux_snr[i]),
01197                 &(flux_snr_noise[i]),
01198                 &(flux_tot[i]),
01199                 &(fwhm_x[i]),
01200                 &(fwhm_y[i])));
01201 
01202     /* Photometry on negative stars */
01203     for (i=2 ; i<4 ; i++)
01204         skip_if (visir_img_phot_flux(min_combined,
01205                 x[i], y[i],
01206                 visir_img_phot_config.r0_max,
01207                 visir_img_phot_config.r1,
01208                 visir_img_phot_config.r2,
01209                 &(flux_snr[i]),
01210                 &(flux_snr_noise[i]),
01211                 &(flux_tot[i]),
01212                 &(fwhm_x[i]),
01213                 &(fwhm_y[i])));
01214 
01215     cpl_image_delete(min_combined);
01216     min_combined = NULL;
01217     
01218     /* Compute the results */
01219     /* Flux */
01220     visir_img_phot_config.flux_snr = 0.0;
01221     for (i=0 ; i<4 ; i++) visir_img_phot_config.flux_snr += flux_snr[i];
01222 
01223     /* Flux noise */
01224     visir_img_phot_config.flux_snr_noise = 0.0;
01225     for (i=0 ; i<4 ; i++) visir_img_phot_config.flux_snr_noise +=
01226         flux_snr_noise[i]*flux_snr_noise[i];
01227     visir_img_phot_config.flux_snr_noise = 
01228         sqrt(visir_img_phot_config.flux_snr_noise);
01229 
01230     /* Total flux */
01231     visir_img_phot_config.flux_tot = 0.0;
01232     for (i=0 ; i<4 ; i++) visir_img_phot_config.flux_tot += flux_tot[i];
01233     
01234     /* FWHM */
01235     ngood_fwhm = 0;
01236     visir_img_phot_config.fwhm_x = 0.0;
01237     for (i=0 ; i<4 ; i++) {
01238         if (fwhm_x[i] > 0.0) {
01239             visir_img_phot_config.fwhm_x += fwhm_x[i];
01240             ngood_fwhm ++;
01241         }
01242     }
01243     if (ngood_fwhm > 0) visir_img_phot_config.fwhm_x /= ngood_fwhm;
01244     else visir_img_phot_config.fwhm_x = -1.0;
01245     ngood_fwhm = 0;
01246     visir_img_phot_config.fwhm_y = 0.0;
01247     for (i=0 ; i<4 ; i++) {
01248         if (fwhm_y[i] > 0.0) {
01249             visir_img_phot_config.fwhm_y += fwhm_y[i];
01250             ngood_fwhm ++;
01251         }
01252     }
01253     if (ngood_fwhm > 0) visir_img_phot_config.fwhm_y /= ngood_fwhm;
01254     else visir_img_phot_config.fwhm_y = -1.0;
01255     visir_img_phot_config.fwhm_x_pos1 = fwhm_x[0];
01256     visir_img_phot_config.fwhm_y_pos1 = fwhm_y[0];
01257     visir_img_phot_config.fwhm_x_pos2 = fwhm_x[1];
01258     visir_img_phot_config.fwhm_y_pos2 = fwhm_y[1];
01259     visir_img_phot_config.fwhm_x_neg1 = fwhm_x[2];
01260     visir_img_phot_config.fwhm_y_neg1 = fwhm_y[2];
01261     visir_img_phot_config.fwhm_x_neg2 = fwhm_x[3];
01262     visir_img_phot_config.fwhm_y_neg2 = fwhm_y[3];
01263 
01264     /* Get lam and dlam from the filter name for the Strehl computation */
01265     if (visir_get_filter_infos(visir_img_phot_config.filter, &lam, &dlam)) {
01266         cpl_msg_error(cpl_func, "Central wavelength and width is missing for "
01267                       "filter: %s", visir_img_phot_config.filter);
01268         skip_if(1);
01269     }
01270     
01271     /* Strehl computation */
01272     if (irplib_strehl_compute(combined, STREHL_M1, STREHL_M2, lam, dlam, 
01273                 visir_img_phot_config.pscale,
01274                 STREHL_BOX_SIZE, x[0], y[0], STREHL_STAR_RADIUS,
01275                 STREHL_BG_R1, STREHL_BG_R2, -1, -1, 
01276                 &(visir_img_phot_config.strehl), 
01277                 &(visir_img_phot_config.strehl_err),
01278                 &star_bg, &star_peak, &star_flux, &psf_peak, &psf_flux,
01279                 &bg_noise)) {
01280         cpl_msg_error(cpl_func, "Could not compute the strehl: '%s' in %s",
01281                         cpl_error_get_message(), cpl_error_get_where());
01282         skip_if(1);
01283     }
01284     
01285 
01286     end_skip;
01287 
01288     cpl_apertures_delete(appos);
01289     cpl_apertures_delete(apneg);
01290     cpl_vector_delete(sigmas);
01291     cpl_image_delete(min_combined);
01292     
01293     return cpl_error_get_code();
01294 
01295 }
01296 
01297 
01298 /*----------------------------------------------------------------------------*/
01314 /*----------------------------------------------------------------------------*/
01315 static double visir_img_phot_eccent_four(const cpl_apertures * appos,
01316                                          int ipos1, int ipos2,
01317                                          const cpl_apertures * apneg,
01318                                          int ineg1, int ineg2)
01319 {
01320 
01321     /* NB: Lower left pixel is (1, 1) */
01322 
01323     /* The two positive points */
01324     const double xp1 = cpl_apertures_get_centroid_x(appos, ipos1);
01325     const double xp2 = cpl_apertures_get_centroid_x(appos, ipos2);
01326     const double yp1 = cpl_apertures_get_centroid_y(appos, ipos1);
01327     const double yp2 = cpl_apertures_get_centroid_y(appos, ipos2);
01328 
01329     /* The leftmost positive point */
01330     const double xpl = xp1 < xp2 ? xp1 : xp2;
01331     const double ypl = xp1 < xp2 ? yp1 : yp2;
01332 
01333     /* The rightmost positive point */
01334     const double xpr = xp1 < xp2 ? xp2 : xp1;
01335     const double ypr = xp1 < xp2 ? yp2 : yp1;
01336 
01337     /* The two negative points */
01338     const double xn1 = cpl_apertures_get_centroid_x(apneg, ineg1);
01339     const double yn1 = cpl_apertures_get_centroid_y(apneg, ineg1);
01340     const double xn2 = cpl_apertures_get_centroid_x(apneg, ineg2);
01341     const double yn2 = cpl_apertures_get_centroid_y(apneg, ineg2);
01342 
01343     /* The leftmost negative point */
01344     const double xln = xn1 < xn2 ? xn1 : xn2;
01345     const double yln = xn1 < xn2 ? yn1 : yn2;
01346 
01347     /* The rightmost engative point */
01348     const double xrn = xn1 < xn2 ? xn2 : xn1;
01349     const double yrn = xn1 < xn2 ? yn2 : yn1;
01350 
01351     const double lx1 = xrn - xpl; /* The length of the top x-side */
01352     const double lx2 = xpr - xln; /* The length of the bottom x-side */
01353     const double ly1 = ypl - yln; /* The length of the left y-side */
01354     const double ly2 = yrn - ypr; /* The length of the right y-side */
01355 
01356     const double lmean = 0.25 * ( lx1 + lx2 + ly1 + ly2);
01357 
01358     const double dx1 = lx1 - lmean;
01359     const double dx2 = lx2 - lmean;
01360     const double dy1 = ly1 - lmean;
01361     const double dy2 = ly2 - lmean;
01362 
01363     const double ey1 = yrn - ypl; /* The displacement in the top x-side */
01364     const double ey2 = ypr - yln; /* The displacement in the bottom x-side */
01365     const double ex1 = xpl - xln; /* The displacement in the left y-side */
01366     const double ex2 = xpr - xrn; /* The displacement in the right y-side */
01367 
01368     const double result = sqrt(dx1 * dx1 + dx2 * dx2 + dy1 * dy1 + dy2 * dy2 +
01369                                ex1 * ex1 + ex2 * ex2 + ey1 * ey1 + ey2 * ey2);
01370 
01371 
01372     bug_if(0);
01373 
01374     bug_if(appos == apneg);
01375     bug_if(ipos1 == ipos2);
01376     bug_if(ineg1 == ineg2);
01377 
01378     end_skip;    
01379 
01380     return result;
01381   
01382 
01383 }
01384 
01385 #ifdef VISIR_IMG_PHOT_USE_ECCENT_THREE
01386 /*----------------------------------------------------------------------------*/
01401 /*----------------------------------------------------------------------------*/
01402 static double visir_img_phot_eccent_three(const cpl_apertures * appos,
01403                                           int ipos,
01404                                           const cpl_apertures * apneg,
01405                                           int ineg1, int ineg2)
01406 {
01407 
01408     /* NB: Lower left pixel is (1, 1) */
01409 
01410     /* The positive point */
01411     const double xp = cpl_apertures_get_centroid_x(appos, ipos);
01412     const double yp = cpl_apertures_get_centroid_y(appos, ipos);
01413 
01414     /* The two negative points */
01415     const double xn1 = cpl_apertures_get_centroid_x(apneg, ineg1);
01416     const double yn1 = cpl_apertures_get_centroid_y(apneg, ineg1);
01417     const double xn2 = cpl_apertures_get_centroid_x(apneg, ineg2);
01418     const double yn2 = cpl_apertures_get_centroid_y(apneg, ineg2);
01419 
01420     /* The bottom negative point */
01421     const double xnb = xn1 < xn2 ? xn1 : xn2;
01422     const double ynb = xn1 < xn2 ? yn1 : yn2;
01423 
01424     /* The top engative point */
01425     const double xnt = xn1 < xn2 ? xn2 : xn1;
01426     const double ynt = xn1 < xn2 ? yn2 : yn1;
01427 
01428     const double l1  = ynt - yp;  /* The length of the top line */
01429     const double l2  = yp  - ynb; /* The length of the bottom line */
01430     const double ln  = ynt - ynb; /* The length of the top to bottom line */
01431 
01432     const double lmean = 0.25 * ( l1 + l2 + ln);
01433 
01434     const double d1 = l1 - lmean;
01435     const double d2 = l2 - lmean;
01436     const double dn = 0.5 * ln - lmean;
01437 
01438     const double e1 = xp - xnt; /* The displacement in the top line */
01439     const double e2 = xp - xnb; /* The displacement in the bottom line */
01440 
01441     const double result = sqrt(d1 * d1 + d2 * d2 + dn * dn + e1 * e1 + e2 * e2);
01442 
01443 
01444     bug_if(0);
01445 
01446     bug_if(appos == apneg);
01447     bug_if(ineg1 == ineg2);
01448 
01449     end_skip;    
01450 
01451     return result;
01452   
01453 
01454 }
01455 
01456 #endif
01457  
01458 /*----------------------------------------------------------------------------*/
01477 /*----------------------------------------------------------------------------*/
01478 static int visir_img_phot_flux(
01479         const cpl_image * combined,
01480         double          x_pos,
01481         double          y_pos,
01482         int             r0_max,
01483         int             r1,
01484         int             r2,
01485         double      *   flux_snr,
01486         double      *   flux_snr_noise,
01487         double      *   flux_tot,
01488         double      *   fwhm_x,
01489         double      *   fwhm_y)
01490 {
01491     cpl_apertures   *   apert = NULL;
01492     cpl_image       *   labels;
01493     cpl_image       *   bg_subtracted = NULL;
01494     cpl_vector      *   r0 = NULL;
01495     cpl_vector      *   fl = NULL;
01496     cpl_vector      *   fl_noise = NULL;
01497     cpl_vector      *   snr = NULL;
01498     double              bg, fl_val;
01499     double              max_val = 0.0; /* Avoid (false) uninit warning */
01500     int                 max_ind = 0;   /* Avoid (false) uninit warning */
01501     int                 i;
01502     int                 nx, ny;
01503 
01504 
01505     if (cpl_error_get_code()) return cpl_error_get_code();
01506 
01507     cpl_ensure_code(combined != NULL, CPL_ERROR_NULL_INPUT);
01508     cpl_ensure_code(r0_max > 0,       CPL_ERROR_ILLEGAL_INPUT);
01509 
01510     nx = cpl_image_get_size_x(combined);
01511     ny = cpl_image_get_size_y(combined);
01512 
01513     /* Create the label image defining the background ring */
01514     if ((labels = visir_create_ring_intimage(nx, ny, 
01515             (int)x_pos, (int)y_pos, r1, r2)) == NULL) {
01516         cpl_msg_error(cpl_func, "Could not create a ring image");
01517         skip_if(1);
01518     }
01519     /* Compute the background */
01520     apert = cpl_apertures_new_from_image(combined, labels);
01521     cpl_image_delete(labels);
01522     labels = NULL;
01523     bg = cpl_apertures_get_median(apert, 1);
01524     cpl_apertures_delete(apert);
01525     apert = NULL;
01526     cpl_msg_info(cpl_func, "Background : %g", bg);
01527    
01528     /* Create the label image defining the total star disk */
01529     if ((labels = visir_create_disk_intimage(nx, ny, 
01530             (int)x_pos, (int)y_pos, r0_max)) == NULL) {
01531         cpl_msg_error(cpl_func, "Could not create a disk image");
01532         skip_if(1);
01533     }
01534 
01535     /* Compute the total flux and the associated error */
01536 
01537     bg_subtracted = cpl_image_subtract_scalar_create(combined, bg);
01538 
01539     apert = cpl_apertures_new_from_image(bg_subtracted, labels);
01540     cpl_image_delete(labels);
01541     labels = NULL;
01542     *flux_tot = cpl_apertures_get_flux(apert, 1);
01543     cpl_apertures_delete(apert);
01544     apert = NULL;
01545     cpl_msg_info(cpl_func, "Star total flux (error): %g", *flux_tot);
01546     
01547     /* Create and fill r0 */
01548     r0 = cpl_vector_new(r0_max);
01549     for (i=0 ; i<r0_max ; i++) cpl_vector_set(r0, i, i+1);
01550 
01551     /* Create fl, fl_noise */
01552     fl = cpl_vector_new(r0_max);
01553     fl_noise = cpl_vector_new(r0_max);
01554     
01555     /* For each radius, compute fl and fl_noise */
01556     for (i=0 ; i<r0_max ; i++) {
01557         /* Create the label image defining the current star disk */
01558         if ((labels = visir_create_disk_intimage(nx, ny, 
01559                 (int)x_pos, (int)y_pos, (int)cpl_vector_get(r0, i))) == NULL) {
01560             cpl_msg_error(cpl_func, "Could not create a disk image: %d", i);
01561             break;
01562         }
01563         /* Compute the statistics on the zone defined by the labels */
01564         apert = cpl_apertures_new_from_image(bg_subtracted, labels);
01565         /* FIXME: apert == NULL ? */
01566         cpl_image_delete(labels);
01567         labels = NULL;
01568         fl_val = cpl_apertures_get_flux(apert, 1);
01569         cpl_vector_set(fl, i, fl_val);
01570         cpl_vector_set(fl_noise, i, visir_img_phot_config.bg_sigma * 
01571                 sqrt((double)cpl_apertures_get_npix(apert, 1)));
01572         cpl_apertures_delete(apert);
01573         apert = NULL;
01574     }
01575     skip_if( 0 );
01576 
01577     /* Compute the flux (and error) for the best signal to noise */
01578     snr = cpl_vector_duplicate(fl);
01579     cpl_vector_divide(snr, fl_noise);
01580     for (i=0 ; i<r0_max ; i++) {
01581         if (i == 0 || max_val < cpl_vector_get(snr, i)) {
01582             max_val = cpl_vector_get(snr, i);
01583             max_ind = i;
01584         }
01585     }
01586     *flux_snr = cpl_vector_get(fl, max_ind);
01587     *flux_snr_noise = cpl_vector_get(fl_noise, max_ind);
01588     cpl_msg_info(cpl_func, "Best SNR star flux : %g for radius %g",
01589             *flux_snr, cpl_vector_get(r0, max_ind));
01590     
01591     /* Compute the FWHM */
01592     skip_if (cpl_image_get_fwhm(bg_subtracted, (int)x_pos, (int)y_pos, fwhm_x,
01593                                 fwhm_y));
01594 
01595     cpl_msg_info(cpl_func, "FWHM : %g in x ; %g in y ", *fwhm_x, *fwhm_y);
01596 
01597     skip_if ( *fwhm_x <= 0.0 );
01598     skip_if ( *fwhm_y <= 0.0 );
01599 
01600     end_skip;
01601 
01602     cpl_apertures_delete(apert);
01603     cpl_image_delete(labels);
01604     cpl_image_delete(bg_subtracted);
01605 
01606     cpl_vector_delete(r0);
01607     cpl_vector_delete(fl);
01608     cpl_vector_delete(snr);
01609     cpl_vector_delete(fl_noise);
01610 
01611     return cpl_error_get_code();
01612 }
01613 
01614 
01615 /*----------------------------------------------------------------------------*/
01626 /*----------------------------------------------------------------------------*/
01627 static cpl_error_code visir_get_filter_infos(
01628         const char  *   f,
01629         double      *   pcwlen,
01630         double      *   pdwlen)
01631 {
01632 
01633     double cwlen = -1;
01634     double dwlen = -1;
01635 
01636 
01637     skip_if (f      == NULL);
01638     skip_if (pcwlen == NULL);
01639     skip_if (pdwlen == NULL);
01640 
01641     skip_if (!strcmp(f, "MV"));
01642 
01643     if (!strcmp(f, "N-BAND")) { cwlen = 10.56;dwlen = 5.37;}
01644     else if (!strcmp(f, "SIC"))    { cwlen = 11.848;dwlen = 2.34;}
01645     else if (!strcmp(f, "PAH1_1")) { cwlen = 8.19;dwlen = 0.15;}
01646     else if (!strcmp(f, "PAH1"))   { cwlen = 8.586;dwlen = 0.421;}
01647     else if (!strcmp(f, "ARIII"))  { cwlen = 8.992;dwlen = 0.138;}
01648     else if (!strcmp(f, "SIV_1"))  { cwlen = 10.02;dwlen = 0.18;}
01649     else if (!strcmp(f, "SIV"))    { cwlen = 10.485;dwlen = 0.159;}
01650     else if (!strcmp(f, "PAH2_1")) { cwlen = 10.76;dwlen = 0.69;}
01651     else if (!strcmp(f, "SIV_2"))  { cwlen = 11.1;dwlen = 0.19;}
01652     else if (!strcmp(f, "PAH2"))   { cwlen = 11.254;dwlen = 0.594;}
01653     else if (!strcmp(f, "PAH2_2")) { cwlen = 12.13;dwlen = 0.37;}
01654     else if (!strcmp(f, "NEII_1")) { cwlen = 12.51;dwlen = 0.18;}
01655     else if (!strcmp(f, "NEII"))   { cwlen = 12.805;dwlen = 0.21;}
01656     else if (!strcmp(f, "NEII_2")) { cwlen = 13.036;dwlen = 0.219;}
01657     else if (!strcmp(f, "Q0"))     { cwlen = 16.554;dwlen = 0.398;}
01658     else if (!strcmp(f, "QH2"))    { cwlen = 17.11;dwlen = 0.398;}
01659     else if (!strcmp(f, "Q1"))     { cwlen = 17.653;dwlen = 0.83;}
01660     else if (!strcmp(f, "Q2"))     { cwlen = 18.718;dwlen = 0.878;}
01661     else if (!strcmp(f, "Q3"))     { cwlen = 19.5;dwlen = 0.4;}
01662     else if (!strcmp(f, "Q4"))     { cwlen = 20.5;dwlen = 1.0;}
01663     else if (!strcmp(f, "Q7"))     { cwlen = 23.1;dwlen = 0.8;}
01664     else if (!strcmp(f, "Q8"))     { cwlen = 24.5;dwlen = 0.8;}
01665     else if (!strcmp(f, "N-SW-spec"))   { cwlen = 8.85;dwlen = 2.7;}
01666     else if (!strcmp(f, "H2S4-spec"))   { cwlen = 8.12;dwlen = 0.3;}
01667     else if (!strcmp(f, "ARIII-spec"))  { cwlen = 8.44;dwlen = 0.78;}
01668     else if (!strcmp(f, "NEII_2-spec")) { cwlen = 12.805;dwlen = 0.2;}
01669     else if (!strcmp(f, "H2S3-spec"))   { cwlen = 9.62;dwlen = 0.2;}
01670     else if (!strcmp(f, "H2S1-spec"))   { cwlen = 17.0;dwlen = 0.4;}
01671 
01672     /* The width of each new, below filter is the Full Width at Half Maximum */
01673 
01674     else if (!strcmp(f, "J7.9"))   { cwlen =  (7.483 +  8.035)/2.0;
01675     dwlen =  8.035 -  7.483;}
01676     else if (!strcmp(f, "J8.9"))   { cwlen =  (8.338 +  9.068)/2.0;
01677     dwlen =  9.068 -  8.338;}
01678     else if (!strcmp(f, "J9.8"))   { cwlen =  (9.123 + 10.059)/2.0;
01679     dwlen = 10.059 -  9.123;}
01680     else if (!strcmp(f, "J12.2"))  { cwlen = (11.700 + 12.216)/2.0;
01681     dwlen = 12.216 - 11.700;}
01682     else if (!strcmp(f, "B8.7"))   { cwlen =  (8.436 +  9.410)/2.0;
01683     dwlen =  9.410 -  8.436;}
01684     else if (!strcmp(f, "B9.7"))   { cwlen =  (9.402 + 10.242)/2.0;
01685     dwlen = 10.242 -  9.402;}
01686     else if (!strcmp(f, "B10.7"))  { cwlen =  (9.970 + 11.338)/2.0;
01687     dwlen = 11.338 -  9.970;}
01688     else if (!strcmp(f, "B11.7"))  { cwlen = (11.098 + 11.950)/2.0;
01689     dwlen = 11.950 - 11.098;}
01690     else if (!strcmp(f, "B12.4"))  { cwlen = (11.971 + 12.961)/2.0;
01691     dwlen = 12.961 - 11.971;}
01692 
01693     *pcwlen = cwlen;
01694     *pdwlen = dwlen;
01695 
01696     skip_if (cwlen <= 0);
01697     skip_if (dwlen <= 0);
01698 
01699     end_skip;
01700 
01701     return cpl_error_get_code();
01702 }
01703 
01704 /*----------------------------------------------------------------------------*/
01713 /*----------------------------------------------------------------------------*/
01714 static cpl_error_code visir_img_phot_qc(cpl_propertylist       * qclist,
01715                                         cpl_propertylist       * paflist,
01716                                         cpl_boolean              drop_wcs,
01717                                         const irplib_framelist * rawframes)
01718 {
01719 
01720     const cpl_propertylist * reflist
01721         = irplib_framelist_get_propertylist_const(rawframes, 0);
01722     const char             * pafcopy
01723         = "^(" VISIR_PFITS_REGEXP_IMG_PHOT_PAF ")$";
01724 
01725 
01726     bug_if (cpl_propertylist_copy_property_regexp(paflist, reflist, pafcopy,
01727                                                   0));
01728 
01729     /* QC.EXPTIME */
01730     bug_if (cpl_propertylist_append_double(qclist, "ESO QC EXPTIME", 
01731             visir_img_phot_config.exptime));
01732     /* QC.JYVAL */
01733     bug_if (cpl_propertylist_append_double(qclist, "ESO QC JYVAL", 
01734             visir_img_phot_config.jy_val));
01735     /* QC.STARNAME */
01736     bug_if (cpl_propertylist_append_string(qclist, "ESO QC STARNAME",
01737             visir_img_phot_config.star_name));
01738     /* QC.FILTER */
01739     bug_if (cpl_propertylist_append_string(qclist, "ESO QC FILTER",
01740             visir_img_phot_config.filter));
01741 
01742     /* QC.BACKGD.SIGMA */
01743     bug_if (cpl_propertylist_append_double(qclist, "ESO QC BACKGD SIGMA",
01744             visir_img_phot_config.bg_sigma));
01745     /* QC.FLUXTOT */
01746     bug_if (cpl_propertylist_append_double(qclist, "ESO QC FLUXTOT",
01747             visir_img_phot_config.flux_tot));
01748     /* QC.FLUXSNR */
01749     bug_if (cpl_propertylist_append_double(qclist, "ESO QC FLUXSNR",
01750             visir_img_phot_config.flux_snr));
01751     /* QC.FLUXSNR.NOISE */
01752     bug_if (cpl_propertylist_append_double(qclist, "ESO QC FLUXSNR NOISE",
01753             visir_img_phot_config.flux_snr_noise));
01754     /* QC.FWHMX */
01755     bug_if (cpl_propertylist_append_double(qclist, "ESO QC FWHMX",
01756             visir_img_phot_config.fwhm_x));
01757     /* QC.FWHMY */
01758     bug_if (cpl_propertylist_append_double(qclist, "ESO QC FWHMY",
01759             visir_img_phot_config.fwhm_y));
01760     /* QC.FWHMX.POS1 */
01761     bug_if (cpl_propertylist_append_double(qclist, "ESO QC FWHMX POS1",
01762             visir_img_phot_config.fwhm_x_pos1));
01763     /* QC.FWHMY.POS1 */
01764     bug_if (cpl_propertylist_append_double(qclist, "ESO QC FWHMY POS1",
01765             visir_img_phot_config.fwhm_y_pos1));
01766     /* QC.FWHMX.POS2 */
01767     bug_if (cpl_propertylist_append_double(qclist, "ESO QC FWHMX POS2",
01768             visir_img_phot_config.fwhm_x_pos2));
01769     /* QC.FWHMY.POS2 */
01770     bug_if (cpl_propertylist_append_double(qclist, "ESO QC FWHMY POS2",
01771             visir_img_phot_config.fwhm_y_pos2));
01772     /* QC.FWHMX.NEG1 */
01773     bug_if (cpl_propertylist_append_double(qclist, "ESO QC FWHMX NEG1",
01774             visir_img_phot_config.fwhm_x_neg1));
01775     /* QC.FWHMY.NEG1 */
01776     bug_if (cpl_propertylist_append_double(qclist, "ESO QC FWHMY NEG1",
01777             visir_img_phot_config.fwhm_y_neg1));
01778     /* QC.FWHMX.NEG2 */
01779     bug_if (cpl_propertylist_append_double(qclist, "ESO QC FWHMX NEG2",
01780             visir_img_phot_config.fwhm_x_neg2));
01781     /* QC.FWHMY.NEG2 */
01782     bug_if (cpl_propertylist_append_double(qclist, "ESO QC FWHMY NEG2",
01783             visir_img_phot_config.fwhm_y_neg2));
01784     /* QC.SENSIT */
01785     bug_if (cpl_propertylist_append_double(qclist, "ESO QC SENSIT",
01786             visir_img_phot_config.sensitivity));
01787     /* QC.CONVER */
01788     bug_if (cpl_propertylist_append_double(qclist, "ESO QC CONVER",
01789             visir_img_phot_config.conversion));
01790     /* QC.STREHL */
01791     bug_if (cpl_propertylist_append_double(qclist, "ESO QC STREHL",
01792             visir_img_phot_config.strehl));
01793     /* QC.STREHL.ERROR */
01794     bug_if (cpl_propertylist_append_double(qclist, "ESO QC STREHL ERROR",
01795             visir_img_phot_config.strehl_err));
01796 
01797     /* QC.CAPA */
01798     skip_if (visir_qc_append_capa(qclist, rawframes));
01799 
01800     bug_if (cpl_propertylist_append(paflist, qclist));
01801 
01802     if (drop_wcs) {
01803         cpl_propertylist * pcopy = cpl_propertylist_new();
01804         const cpl_error_code error
01805             = cpl_propertylist_copy_property_regexp(pcopy, reflist, "^("
01806                                                     IRPLIB_PFITS_WCS_REGEXP
01807                                                     ")$", 0);
01808         if (!error && cpl_propertylist_get_size(pcopy) > 0) {
01809             cpl_msg_warning(cpl_func, "Combined image will have no WCS "
01810                             "coordinates");
01811         }
01812         cpl_propertylist_delete(pcopy);
01813         bug_if(0);
01814 
01815         bug_if(cpl_propertylist_copy_property_regexp(qclist, reflist, "^("
01816                                                      VISIR_PFITS_IMG_PHOT_COPY
01817                                                      ")$", 0));
01818     } else {
01819         bug_if(cpl_propertylist_copy_property_regexp(qclist, reflist, "^("
01820                                                      VISIR_PFITS_IMG_PHOT_COPY
01821                                                      "|" IRPLIB_PFITS_WCS_REGEXP
01822                                                      ")$", 0));
01823     }
01824 
01825     bug_if (irplib_pfits_set_airmass(qclist, rawframes));
01826 
01827     end_skip;
01828     
01829     return cpl_error_get_code();
01830 
01831 }
01832  
01833 /*----------------------------------------------------------------------------*/
01844 /*----------------------------------------------------------------------------*/
01845 static cpl_error_code visir_img_phot_save(cpl_frameset            * set,
01846                                           const cpl_parameterlist * parlist,
01847                                           const cpl_propertylist  * qclist,
01848                                           const cpl_propertylist  * paflist,
01849                                           const cpl_image         * combined,
01850                                           const cpl_image         * contrib)
01851 {
01852 
01853     bug_if (0);
01854 
01855     /* SAVE THE COMBINED IMAGE */
01856     skip_if (irplib_dfs_save_image(set, parlist, set, combined, CPL_BPP_IEEE_FLOAT,
01857                                RECIPE_STRING, VISIR_IMG_PHOT_COMBINED_PROCATG,
01858                                qclist, NULL, visir_pipe_id,
01859                                RECIPE_STRING CPL_DFS_FITS));
01860 
01861     /* THE CONTRIBUTION MAP */
01862     skip_if (irplib_dfs_save_image(set, parlist, set, contrib, CPL_BPP_32_SIGNED,
01863                                RECIPE_STRING, VISIR_IMG_PHOT_CONTRIB_PROCATG,
01864                                qclist, NULL, visir_pipe_id,
01865                                RECIPE_STRING "_contrib" CPL_DFS_FITS));
01866 
01867     /* THE PAF FILE FOR QC PARAMETERS */
01868 
01869     skip_if (cpl_dfs_save_paf("VISIR", RECIPE_STRING, paflist,
01870                              RECIPE_STRING CPL_DFS_PAF));
01871 
01872     end_skip;
01873 
01874     return cpl_error_get_code();
01875 
01876 }

Generated on Fri Jul 3 11:15:23 2009 for VISIR Pipeline Reference Manual by  doxygen 1.5.8