00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifdef HAVE_CONFIG_H
00021 #include <config.h>
00022 #endif
00023
00024
00025
00026
00027
00028
00029 #include "visir_recipe.h"
00030 #include "visir_pfits.h"
00031 #include "irplib_strehl.h"
00032 #include "irplib_framelist.h"
00033
00034 #include <string.h>
00035 #include <float.h>
00036
00037 #define SQR(a) ((a) * (a))
00038
00039
00040
00041
00042
00043 #define VISIR_IMG_PHOT_POS_WARN 10.0
00044 #define VISIR_IMG_PHOT_POS_ERROR 25.0
00045 #define VISIR_IMG_PHOT_POS_UNCERTAINTY 10.0
00046 #define STREHL_M1 8.0
00047 #define STREHL_M2 1.1
00048 #define STREHL_BOX_SIZE 64
00049 #define STREHL_STAR_RADIUS 2.0
00050 #define STREHL_BG_R1 2.0
00051 #define STREHL_BG_R2 3.0
00052
00053 #define RECIPE_STRING "visir_old_img_phot"
00054
00055 #define RECIPE_SAVE_STRING "visir_img_phot"
00056
00057
00058
00059 #define RECIPE_KEYS_REGEXP_ALL \
00060 VISIR_PFITS_REGEXP_IMG_RECOMBINE \
00061 "|" VISIR_PFITS_REGEXP_IMG_SENSIT
00062
00063
00064 #define RECIPE_KEYS_REGEXP \
00065 RECIPE_KEYS_REGEXP_ALL \
00066 "|" VISIR_PFITS_IMG_PHOT_COPY \
00067 "|" VISIR_PFITS_REGEXP_IMG_PHOT_PAF
00068
00069
00070 #define RECIPE_KEYS_REGEXP_WCS \
00071 RECIPE_KEYS_REGEXP \
00072 "|" IRPLIB_PFITS_WCS_REGEXP
00073
00074
00075
00076
00077
00078
00079 typedef struct beamshape_ {
00080
00081 double fwhm_x, fwhm_y;
00082
00083 double peak, peak_err;
00084 double major, major_err;
00085 double minor, minor_err;
00086 double angle, angle_err;
00087 } beamshape_t;
00088
00089
00090 static double visir_img_phot_eccent_four(const cpl_apertures *, int, int,
00091 const cpl_apertures *, int, int);
00092
00093 static int visir_img_phot_flux_one(const cpl_image *, const cpl_image *,
00094 const cpl_image *, const cpl_propertylist *);
00095 #ifdef VISIR_IMG_PHOT_USE_ECCENT_THREE
00096 static double visir_img_phot_eccent_three(const cpl_apertures *, int,
00097 const cpl_apertures *, int, int);
00098 #endif
00099
00100 static double visir_img_phot_jy_from_cat(const char *, const char *, double,
00101 double, const char *);
00102 static int visir_img_phot_sensit(const cpl_image *, const cpl_image *,
00103 const cpl_image *, const irplib_framelist *,
00104 const char *, cpl_boolean, cpl_propertylist *);
00105 static int visir_img_phot_flux_three(const cpl_image *);
00106 static int visir_img_phot_flux_four(const cpl_image *);
00107 static int visir_img_phot_flux(const cpl_image *, const cpl_image *,
00108 const cpl_image *, double,
00109 double, int, int, int, double *,
00110 double *, int *, double *, beamshape_t *);
00111
00112 static cpl_error_code visir_get_filter_infos(const char *, double *, double *);
00113
00114 static cpl_error_code visir_img_phot_qc(cpl_propertylist *,
00115 cpl_boolean,
00116 const irplib_framelist *);
00117
00118 static cpl_error_code visir_img_phot_save(cpl_frameset *,
00119 const cpl_parameterlist *,
00120 const cpl_propertylist *,
00121 const cpl_image *,
00122 const cpl_image *,
00123 const cpl_image *,
00124 const cpl_image *,
00125 const cpl_image *);
00126
00127 static char * visir_img_phot_filter2label(const char *);
00128
00129 #ifdef VISIR_CHAIN
00130 #define cpl_plugin_get_info visir_old_img_phot_get_info
00131 #endif
00132 VISIR_RECIPE_DEFINE(visir_old_img_phot,
00133 VISIR_PARAM_RADII | VISIR_PARAM_JYVAL |
00134 VISIR_PARAM_REFINE | VISIR_PARAM_XCORR |
00135 VISIR_PARAM_OFFSETS | VISIR_PARAM_OBJECTS |
00136 VISIR_PARAM_NODPOS | VISIR_PARAM_AUTOBPM |
00137 VISIR_PARAM_GLITCH | VISIR_PARAM_PURGE |
00138 VISIR_PARAM_UNION | VISIR_PARAM_REJECT |
00139 VISIR_PARAM_COMBINE | VISIR_PARAM_ECCMAX |
00140 VISIR_PARAM_STRIPITE | VISIR_PARAM_STRIPMOR |
00141 VISIR_PARAM_PLOT,
00142 "Old DRS detector: Sensitivity computation",
00143 "This recipe computes the conversion factor and the "
00144 "sentitivity of a\n"
00145 "standard star. It requires a standard star catalog.\n"
00146 "The files listed in the Set Of Frames (sof-file) "
00147 "must be tagged:\n"
00148 "VISIR-std-star-observation.fits " VISIR_IMG_PHOT_RAW
00149 "\n"
00150 "VISIR-Imaging-Standard-Star-Catalog.fits "
00151 VISIR_IMA_STD_CAT_PROCATG "\n"
00152 "\n"
00153 "The primary product will have a FITS card\n"
00154 "'HIERARCH " CPL_DFS_PRO_CATG "' with a string value of\n"
00155 "'" VISIR_IMG_PHOT_COMBINED_PROCATG "'\n"
00156 " and the corresponding beam-collapsed product will "
00157 "have a FITS card\n"
00158 "'HIERARCH " CPL_DFS_PRO_CATG "' with a value of\n"
00159 VISIR_IMG_PHOT_ONEBEAM_PROCATG
00160 "\n"
00161 MAN_VISIR_CALIB_BPM_IMG);
00162
00163
00164
00165
00166
00167 static const int fits_strlen = IRPLIB_FITS_STRLEN;
00168
00169 static struct {
00170
00171 double jy_val;
00172 int r0_max;
00173 int r1;
00174 int r2;
00175
00176
00177 double exptime;
00178 double pscale;
00179 char star_name[IRPLIB_FITS_STRLEN+1];
00180 char filter[IRPLIB_FITS_STRLEN+1];
00181 double bg_sigma;
00182 double flux_snr;
00183 double flux_snr_noise;
00184 int flux_snr_radius[4];
00185 double flux_tot;
00186 double nelec;
00187 double nphot;
00188 beamshape_t beamshape;
00189 double fwhm_x_pos1;
00190 double fwhm_y_pos1;
00191 double fwhm_x_pos2;
00192 double fwhm_y_pos2;
00193 double fwhm_x_neg1;
00194 double fwhm_y_neg1;
00195 double fwhm_x_neg2;
00196 double fwhm_y_neg2;
00197 double sensitivity;
00198 double area_sensit;
00199 double conversion;
00200 double strehl;
00201 double strehl_err;
00202 } visir_img_phot_config;
00203
00204
00205
00209
00210
00211
00212
00213
00214
00215
00216 static cpl_error_code
00217 propagate_qc_header(cpl_propertylist * qclist, const cpl_propertylist * ppqc)
00218 {
00219 double d;
00220 int i;
00221 const char * s;
00222
00223 s = cpl_propertylist_get_string(ppqc, "BUNIT");
00224 cpl_propertylist_append_string(qclist, "BUNIT", s);
00225
00226 s = cpl_propertylist_get_string(ppqc, "ESO DRS CATG");
00227 cpl_propertylist_append_string(qclist, "ESO DRS CATG", s);
00228
00229 d = cpl_propertylist_get_double(ppqc, "ESO QC BACKGD MEAN");
00230 cpl_propertylist_append_double(qclist, "ESO QC BACKGD MEAN", d);
00231
00232 d = cpl_propertylist_get_double(ppqc, "ESO QC EXPTIME EFFECTIVE");
00233 cpl_propertylist_append_double(qclist, "ESO QC EXPTIME EFFECTIVE", d);
00234
00235 if (cpl_propertylist_has(ppqc, "ESO QC EXECTIME")) {
00236 d = cpl_propertylist_get_double(ppqc, "ESO QC EXECTIME");
00237 cpl_propertylist_append_double(qclist, "ESO QC EXECTIME", d);
00238 }
00239
00240 i = cpl_propertylist_get_int(ppqc, "ESO QC NIMAGES TOTAL");
00241 cpl_propertylist_append_int(qclist, "ESO QC NIMAGES TOTAL", i);
00242
00243 i = cpl_propertylist_get_int(ppqc, "ESO QC NIMAGES EFFECTIVE");
00244 cpl_propertylist_append_int(qclist, "ESO QC NIMAGES EFFECTIVE", i);
00245
00246 s = cpl_propertylist_get_string(ppqc, "ESO QC BEAMID");
00247 cpl_propertylist_append_string(qclist, "ESO QC BEAMID", s);
00248
00249 error_if(strcmp(s, "UNDEFINED") == 0, CPL_ERROR_ILLEGAL_INPUT,
00250 "Object detection was not successful, "
00251 "please provide visir_util_detect_position with the object "
00252 "positions to allow photometry");
00253 if (strcmp(s, "COMBINED") != 0) {
00254 d = cpl_propertylist_get_double(ppqc, "ESO QC BEAMX");
00255 cpl_propertylist_append_double(qclist, "ESO QC BEAMX", d);
00256
00257 d = cpl_propertylist_get_double(ppqc, "ESO QC BEAMY");
00258 cpl_propertylist_append_double(qclist, "ESO QC BEAMY", d);
00259 }
00260
00261 end_skip;
00262
00263 return cpl_error_get_code();
00264 }
00265
00266
00267
00274
00275 static int visir_old_img_phot(cpl_frameset * framelist,
00276 const cpl_parameterlist * parlist)
00277 {
00278 cpl_errorstate cleanstate = cpl_errorstate_get();
00279 irplib_framelist * allframes = NULL;
00280 irplib_framelist * rawframes = NULL;
00281 cpl_propertylist * ppqc = NULL;
00282 cpl_propertylist * qclist = NULL;
00283 const char * badpix;
00284 const char * star_cat;
00285 const char * flat;
00286 cpl_image * weights = NULL;
00287 cpl_image * contrib = NULL;
00288 cpl_image ** combined = NULL;
00289 cpl_image ** beam1 = NULL;
00290 const char * sval;
00291 cpl_boolean drop_wcs = CPL_FALSE;
00292 const char * keys_regexp = "^(" RECIPE_KEYS_REGEXP_WCS
00293 "|"VISIR_PFITS_REGEXP_DIT
00294 "|ESO OBS.*)$";
00295 const char * combine_string;
00296 cpl_geom_combine combine_mode;
00297 cpl_boolean one_beam = CPL_FALSE;
00298 const char * dit_key = VISIR_PFITS_DOUBLE_DIT;
00299
00300
00301
00302 visir_img_phot_config.exptime = -1.0;
00303 visir_img_phot_config.pscale = -1.0;
00304 visir_img_phot_config.star_name[0] = (char)0;
00305 visir_img_phot_config.filter[0] = (char)0;
00306 visir_img_phot_config.bg_sigma = -1.0;
00307 visir_img_phot_config.flux_snr = -1.0;
00308 visir_img_phot_config.flux_snr_noise = -1.0;
00309 visir_img_phot_config.flux_snr_radius[0] = -1;
00310 visir_img_phot_config.flux_snr_radius[1] = -1;
00311 visir_img_phot_config.flux_snr_radius[2] = -1;
00312 visir_img_phot_config.flux_snr_radius[3] = -1;
00313 visir_img_phot_config.flux_tot = -1.0;
00314 visir_img_phot_config.nelec = -1.0;
00315 visir_img_phot_config.nphot = -1.0;
00316 visir_img_phot_config.beamshape =
00317 (beamshape_t){.fwhm_x = -1., .fwhm_y = -1.,
00318 .peak = -1., .peak_err = 0.,
00319 .major = -1., .major_err = 0.,
00320 .minor = -1., .minor_err = 0.,
00321 .angle = -1., .angle_err = 0.};
00322 visir_img_phot_config.fwhm_x_pos1 = -1.0;
00323 visir_img_phot_config.fwhm_y_pos1 = -1.0;
00324 visir_img_phot_config.fwhm_x_pos2 = -1.0;
00325 visir_img_phot_config.fwhm_y_pos2 = -1.0;
00326 visir_img_phot_config.fwhm_x_neg1 = -1.0;
00327 visir_img_phot_config.fwhm_y_neg1 = -1.0;
00328 visir_img_phot_config.fwhm_x_neg2 = -1.0;
00329 visir_img_phot_config.fwhm_y_neg2 = -1.0;
00330 visir_img_phot_config.sensitivity = -1.0;
00331 visir_img_phot_config.area_sensit = -1.0;
00332 visir_img_phot_config.conversion = -1.0;
00333 visir_img_phot_config.strehl = -1.0;
00334 visir_img_phot_config.strehl_err = -1.0;
00335
00336
00337 combine_string = visir_parameterlist_get_string(parlist, RECIPE_STRING,
00338 VISIR_PARAM_COMBINE);
00339
00340 bug_if (combine_string == NULL);
00341
00342 if (combine_string[0] == 'u')
00343 combine_mode = CPL_GEOM_UNION;
00344 else if (combine_string[0] == 'f')
00345 combine_mode = CPL_GEOM_FIRST;
00346 else if (combine_string[0] == 'i')
00347 combine_mode = CPL_GEOM_INTERSECT;
00348 else
00349 skip_if(1);
00350
00351
00352 visir_img_phot_config.jy_val =
00353 visir_parameterlist_get_double(parlist, RECIPE_STRING, VISIR_PARAM_JYVAL);
00354 skip_if (0);
00355
00356 sval = visir_parameterlist_get_string(parlist, RECIPE_STRING, VISIR_PARAM_RADII);
00357 skip_if (sval == NULL);
00358
00359 skip_if (sscanf(sval, "%d%*c%d%*c%d",
00360 &visir_img_phot_config.r0_max,
00361 &visir_img_phot_config.r1,
00362 &visir_img_phot_config.r2) != 3);
00363
00364
00365 skip_if (visir_dfs_set_groups(framelist));
00366
00367
00368 allframes = irplib_framelist_cast(framelist);
00369 skip_if(allframes == NULL);
00370 {
00371 rawframes = irplib_framelist_extract(allframes, VISIR_IMG_PHOT_RAW);
00372 if (rawframes == NULL) {
00373 cpl_errorstate_set(cleanstate);
00374 rawframes = irplib_framelist_extract(allframes,
00375 VISIR_IMG_CAL_PHOT_PP);
00376 skip_if (rawframes == NULL);
00377 const char * fn =
00378 irplib_frameset_find_file(framelist, VISIR_UTIL_QC_PROCATG);
00379 if(fn == NULL) {
00380 cpl_msg_error(cpl_func, "The input files has no header tagged "
00381 "%s", VISIR_UTIL_QC_PROCATG);
00382 visir_error_set(CPL_ERROR_DATA_NOT_FOUND);
00383 skip_if(1);
00384 }
00385 ppqc = cpl_propertylist_load(fn, 0);
00386 one_beam = CPL_TRUE;
00387 }
00388 }
00389
00390 skip_if (rawframes == NULL);
00391
00392 irplib_framelist_empty(allframes);
00393
00394 skip_if(irplib_framelist_load_propertylist(rawframes, 0, 0, keys_regexp,
00395 CPL_FALSE));
00396 qclist = cpl_propertylist_duplicate(irplib_framelist_get_propertylist(rawframes, 0));
00397 if (ppqc)
00398 skip_if(propagate_qc_header(qclist, ppqc));
00399
00400 skip_if(irplib_framelist_load_propertylist_all(rawframes, 0, "^("
00401 RECIPE_KEYS_REGEXP_ALL
00402 "|"VISIR_PFITS_REGEXP_DIT
00403 ")$", CPL_FALSE));
00404
00405 skip_if(visir_dfs_check_framelist_tag(rawframes));
00406
00407 if (cpl_propertylist_has(irplib_framelist_get_propertylist(rawframes, 0),
00408 VISIR_PFITS_DOUBLE_SEQ1_DIT))
00409 dit_key = VISIR_PFITS_DOUBLE_SEQ1_DIT;
00410 skip_if(0);
00411
00412
00413 star_cat = irplib_frameset_find_file(framelist, VISIR_CALIB_STDSTAR_IMG);
00414 if (star_cat == NULL) {
00415 cpl_msg_error(cpl_func, "The input files has no star catalog tagged "
00416 "%s", VISIR_CALIB_STDSTAR_IMG);
00417 visir_error_set(CPL_ERROR_DATA_NOT_FOUND);
00418 skip_if(1);
00419 }
00420
00421
00422 badpix = irplib_frameset_find_file(framelist, VISIR_CALIB_BPM);
00423
00424
00425 flat = irplib_frameset_find_file(framelist, VISIR_CALIB_FLAT);
00426
00427
00428
00429 skip_if(irplib_framelist_contains(rawframes, dit_key,
00430 CPL_TYPE_DOUBLE, CPL_FALSE, 0.0));
00431 if(irplib_framelist_contains(rawframes, dit_key,
00432 CPL_TYPE_DOUBLE, CPL_TRUE, 1e-5)) {
00433
00434
00435 visir_error_reset("DIT differs by more than %g", 1e-5);
00436 }
00437
00438
00439 skip_if(irplib_framelist_contains(rawframes, VISIR_PFITS_DOUBLE_RA,
00440 CPL_TYPE_DOUBLE, CPL_FALSE, 0.0));
00441
00442
00443 skip_if(irplib_framelist_contains(rawframes, VISIR_PFITS_DOUBLE_DEC,
00444 CPL_TYPE_DOUBLE, CPL_TRUE, 1.0));
00445
00446 skip_if(irplib_framelist_contains(rawframes, VISIR_PFITS_INT_CHOP_NCYCLES,
00447 CPL_TYPE_INT, CPL_TRUE, 0.0));
00448
00449 skip_if(irplib_framelist_contains(rawframes, VISIR_PFITS_INT_NDIT,
00450 CPL_TYPE_INT, CPL_TRUE, 0.0));
00451
00452 skip_if(irplib_framelist_contains(rawframes, VISIR_PFITS_STRING_STARNAME,
00453 CPL_TYPE_STRING, CPL_TRUE, 0.0));
00454
00455 skip_if(irplib_framelist_contains(rawframes, VISIR_PFITS_STRING_INSMODE,
00456 CPL_TYPE_STRING, CPL_TRUE, 0.0));
00457
00458 if (strncmp("IMG", visir_pfits_get_insmode(
00459 irplib_framelist_get_propertylist_const(rawframes, 0)),
00460 6) == 0) {
00461 skip_if(irplib_framelist_contains(rawframes, VISIR_PFITS_STRING_FILTER1,
00462 CPL_TYPE_STRING, CPL_TRUE, 0.0));
00463 } else {
00464 skip_if(irplib_framelist_contains(rawframes, VISIR_PFITS_STRING_FILTER2,
00465 CPL_TYPE_STRING, CPL_TRUE, 0.0));
00466 }
00467
00468 skip_if(irplib_framelist_contains(rawframes, VISIR_PFITS_STRING_PIXSCALE,
00469 CPL_TYPE_STRING, CPL_TRUE, 0.0));
00470
00471
00472 {
00473 const char * prew =
00474 irplib_frameset_find_file(framelist, "WEIGHT_MAP");
00475 if (prew) {
00476 cpl_msg_info(cpl_func, "Loading weight map %s", prew);
00477 weights = cpl_image_load(prew, CPL_TYPE_UNSPECIFIED, 0, 0);
00478 }
00479 }
00480
00481 {
00482 const char * prec =
00483 irplib_frameset_find_file(framelist, "CONTRIBUTION_MAP");
00484 if (prec) {
00485 cpl_msg_info(cpl_func, "Loading contribution map %s", prec);
00486 contrib = cpl_image_load(prec, CPL_TYPE_INT, 0, 0);
00487 }
00488 }
00489
00490 skip_if(0);
00491
00492 cpl_msg_info(cpl_func, "Combining the images");
00493 {
00494 const char * pre =
00495 irplib_frameset_find_file(framelist, VISIR_IMG_CAL_PHOT_PP);
00496 if (pre) {
00497 combined = cpl_calloc(2, sizeof(combined[0]));
00498 combined[0] = cpl_image_load(pre, CPL_TYPE_UNSPECIFIED, 0, 0);
00499 combined[1] = contrib ? cpl_image_duplicate(contrib) : NULL;
00500 if (combined[0] == NULL) {
00501 cpl_msg_error(cpl_func, "Could not load the input frames");
00502 skip_if(1);
00503 }
00504 if (weights) {
00505 cpl_mask * m = cpl_mask_threshold_image_create(weights, -1,
00506 FLT_EPSILON);
00507 cpl_image_reject_from_mask(combined[0], m);
00508 cpl_mask_delete(m);
00509 }
00510 }
00511 else {
00512 combined = visir_img_recombine(RECIPE_STRING, parlist, rawframes,
00513 badpix, flat, combine_mode,
00514 &drop_wcs, CPL_FALSE, 0.0, 0);
00515 if (combined == NULL) {
00516 cpl_msg_error(cpl_func, "Could not combine the input frames");
00517 skip_if(1);
00518 }
00519 beam1 = visir_img_collapse_beam(qclist, combined[0], parlist, RECIPE_STRING,
00520 VISIR_CHOPNOD_AUTO,
00521 irplib_framelist_get_propertylist_const
00522 (rawframes, 0));
00523 if (beam1 == NULL)
00524 irplib_error_recover(cleanstate, "Could not collapse the "
00525 "beams of the combined image");
00526
00527
00528
00529 skip_if(visir_qc_append_background(qclist, rawframes, 0, 0));
00530 }
00531 }
00532
00533
00534 cpl_msg_info(cpl_func, "Computing the sensitivity");
00535 if (visir_img_phot_sensit(combined[0], weights, contrib, rawframes,
00536 star_cat, one_beam, ppqc)) {
00537 cpl_msg_error(cpl_func, "Could not compute sensitivity: '%s' in %s",
00538 cpl_error_get_message(), cpl_error_get_where());
00539 skip_if(1);
00540 }
00541
00542 skip_if (visir_img_phot_qc(qclist, drop_wcs, rawframes));
00543 irplib_framelist_empty(rawframes);
00544
00545
00546 if (beam1 == NULL) {
00547 cpl_msg_info(cpl_func, "Saving the combined image with its contribution "
00548 "map");
00549 skip_if (visir_img_phot_save(framelist, parlist, qclist, combined[0],
00550 combined[1], NULL, NULL, weights));
00551 } else {
00552 cpl_msg_info(cpl_func, "Saving the combined and the beam-combined "
00553 "images with their contribution maps");
00554 skip_if (visir_img_phot_save(framelist, parlist, qclist, combined[0],
00555 combined[1], beam1[0], beam1[1], weights));
00556 }
00557
00558 end_skip;
00559
00560 cpl_propertylist_delete(qclist);
00561 irplib_framelist_delete(allframes);
00562 irplib_framelist_delete(rawframes);
00563 cpl_propertylist_delete(ppqc);
00564 cpl_image_delete(weights);
00565 cpl_image_delete(contrib);
00566
00567 if (combined) {
00568 cpl_image_delete(combined[0]);
00569 cpl_image_delete(combined[1]);
00570 cpl_free(combined);
00571 }
00572
00573 if (beam1) {
00574 cpl_image_delete(beam1[0]);
00575 cpl_image_delete(beam1[1]);
00576 cpl_free(beam1);
00577 }
00578
00579 return cpl_error_get_code();
00580
00581 }
00582
00583
00608
00609 static int visir_img_phot_sensit(const cpl_image * combined,
00610 const cpl_image * weights,
00611 const cpl_image * contrib,
00612 const irplib_framelist * rawframes,
00613 const char * star_cat,
00614 cpl_boolean one_beam,
00615 cpl_propertylist * ppqc)
00616 {
00617 cpl_errorstate cleanstate = cpl_errorstate_get();
00618 const cpl_propertylist * plist = NULL;
00619 double ra, dec;
00620 const char * sval;
00621 double f2;
00622
00623
00624 skip_if (0);
00625
00626 plist = irplib_framelist_get_propertylist_const(rawframes, 0);
00627 skip_if (0);
00628
00629
00630 {
00631 double exptime;
00632
00633 if (ppqc)
00634 exptime = cpl_propertylist_get_double(ppqc, "ESO QC EXPTIME TOTAL");
00635 else {
00636 const int nnod = irplib_framelist_get_size(rawframes);
00637 exptime = visir_utils_get_exptime(nnod, plist);
00638 }
00639 visir_img_phot_config.exptime = exptime;
00640
00641 if (exptime <= 0 || cpl_error_get_code()) {
00642 cpl_msg_error(cpl_func, "Illegal exposure time: %g", exptime);
00643 skip_if(1);
00644 }
00645 }
00646
00647
00648 skip_if ((sval = visir_pfits_get_starname(plist)) == NULL);
00649 (void) strncpy(visir_img_phot_config.star_name, sval, fits_strlen);
00650
00651
00652 skip_if ((sval = visir_pfits_get_filter(plist)) == NULL);
00653 (void)strncpy(visir_img_phot_config.filter, sval, fits_strlen);
00654
00655
00656 ra = visir_pfits_get_ra(plist);
00657 skip_if (0);
00658 dec = visir_pfits_get_dec(plist);
00659 skip_if (0);
00660
00661
00662 visir_img_phot_config.pscale = visir_pfits_get_pixscale(plist);
00663
00664
00665 if (visir_img_phot_config.jy_val < -998) {
00666 visir_img_phot_config.jy_val =
00667 visir_img_phot_jy_from_cat(star_cat, visir_img_phot_config.filter,
00668 ra,dec, visir_img_phot_config.star_name);
00669 skip_if (visir_img_phot_config.jy_val < -998);
00670 }
00671
00672
00673 cpl_msg_info(cpl_func, "Star %s with filter %s : %g Jy",
00674 visir_img_phot_config.star_name,
00675 visir_img_phot_config.filter,
00676 visir_img_phot_config.jy_val);
00677
00678
00679 visir_img_phot_config.bg_sigma = visir_img_phot_sigma_clip(combined);
00680 skip_if (0);
00681
00682
00683 cpl_msg_info(cpl_func, "Compute the star flux");
00684 sval = visir_pfits_get_chopnod_dir(plist);
00685 #if 1
00686 if (one_beam) {
00687 skip_if (visir_img_phot_flux_one(combined, weights, contrib, plist));
00688 }
00689 else if (sval != NULL && !strcmp(sval, "PERPENDICULAR")) {
00690
00691 skip_if (visir_img_phot_flux_four(combined));
00692 } else if (sval != NULL && !strcmp(sval, "PARALLEL")) {
00693
00694 skip_if (visir_img_phot_flux_three(combined));
00695 } else {
00696 if (sval == NULL) {
00697 visir_error_reset("Could not get FITS key");
00698 } else {
00699 cpl_msg_warning(cpl_func, "Unknown chopping direction: %s", sval);
00700 }
00701 cpl_msg_warning(cpl_func, "Proceeding as if FITS card %s had value %s",
00702 "ESO SEQ CHOPNOD DIR", "PERPENDICULAR");
00703 if (visir_img_phot_flux_four(combined)) {
00704 visir_error_reset("Proceeding as if FITS card %s had value %s",
00705 "ESO SEQ CHOPNOD DIR", "PARALLEL");
00706 skip_if (visir_img_phot_flux_three(combined));
00707 }
00708 }
00709 #else
00710 if (sval == NULL) {
00711 visir_error_reset("Could not get chopping direction");
00712 if (visir_img_phot_flux_three(combined)) {
00713 cpl_msg_error(cpl_func, "Could not compute the flux");
00714 skip_if(1);
00715 }
00716 } else if (!strcmp(sval, "PARALLEL")) {
00717
00718 if (visir_img_phot_flux_three(combined)) {
00719 cpl_msg_error(cpl_func, "Could not compute the flux");
00720 skip_if(1);
00721 }
00722 } else {
00723
00724 if (strcmp(sval, "PERPENDICULAR"))
00725 cpl_msg_warning(cpl_func, "Unknown chopping direction: %s", sval);
00726 if (visir_img_phot_flux_four(combined)) {
00727 cpl_msg_error(cpl_func, "Could not compute the flux");
00728 skip_if(1);
00729 }
00730 }
00731 #endif
00732
00733
00734
00735 {
00736 double fluxSI = visir_img_phot_config.jy_val * 1e-26;
00737 double dit = visir_pfits_get_dit(plist);;
00738
00739 double area = (8.2/2.) * (8.2/2.) * CPL_MATH_PI;
00740 const char * filter = visir_pfits_get_filter(plist);
00741 double wl;
00742
00743 double bandwidth;
00744 double gain = 20.;
00745
00746 if (ppqc && cpl_propertylist_has(ppqc, "ESO DET CHIP1 GAIN"))
00747 gain = cpl_propertylist_get_double(ppqc, "ESO DET CHIP1 GAIN");
00748 else if (ppqc && cpl_propertylist_has(ppqc, "ESO DET CHIP GAIN"))
00749 gain = cpl_propertylist_get_double(ppqc, "ESO DET CHIP GAIN");
00750 else
00751 cpl_msg_warning(cpl_func, "ESO DET CHIP1 GAIN not found, "
00752 "assuming %g", gain);
00753
00754 if (filter && !visir_get_filter_infos(filter, &wl, &bandwidth)) {
00755
00756 double bwh, ptot, ephot;
00757 wl *= 1e-6;
00758 bandwidth *= 1e-6;
00759
00760 bwh = CPL_PHYS_C / (wl * wl) * bandwidth;
00761
00762 ptot = fluxSI * area * bwh;
00763
00764 ephot = CPL_PHYS_H * CPL_PHYS_C / wl;
00765
00766 visir_img_phot_config.nelec = visir_img_phot_config.flux_tot * gain;
00767 visir_img_phot_config.nphot = ptot / ephot * dit;
00768 }
00769 else
00770 cpl_msg_warning(cpl_func, "Unknown filter: %s", filter);
00771 }
00772
00773
00774
00775 skip_if ( visir_img_phot_config.flux_snr == 0 );
00776 skip_if ( visir_img_phot_config.flux_snr_noise == 0 );
00777 skip_if ( visir_img_phot_config.jy_val == 0 );
00778
00779 f2 = visir_img_phot_config.flux_snr / visir_img_phot_config.flux_snr_noise;
00780 f2 *= sqrt(3600/visir_img_phot_config.exptime);
00781 visir_img_phot_config.sensitivity = visir_img_phot_config.jy_val*1000*10/f2;
00782
00783 visir_img_phot_config.conversion = visir_img_phot_config.flux_tot /
00784 visir_img_phot_config.jy_val /
00785 (ppqc ? visir_pfits_get_img_weight(ppqc) : 1.);
00786
00787
00788 visir_img_phot_config.area_sensit =
00789 visir_img_phot_config.sensitivity *
00790 sqrt((1. / SQR(visir_img_phot_config.pscale)) /
00791 SQR(visir_img_phot_config.flux_snr_radius[0]));
00792
00793 end_skip;
00794
00795 cpl_msg_info(cpl_func, "Sensitivity : %g", visir_img_phot_config.sensitivity);
00796 cpl_msg_info(cpl_func, "Conversion : %g", visir_img_phot_config.conversion);
00797 cpl_msg_info(cpl_func, "Strehl : %g", visir_img_phot_config.strehl);
00798 cpl_msg_info(cpl_func, "Strehl error: %g", visir_img_phot_config.strehl_err);
00799 cpl_msg_info(cpl_func, "Exposure : %g s", visir_img_phot_config.exptime);
00800
00801 return cpl_error_get_code();
00802 }
00803
00804
00814
00815 static double visir_img_phot_jy_from_cat(
00816 const char * star_cat,
00817 const char * filter,
00818 double ra,
00819 double dec,
00820 const char * star_name)
00821 {
00822 cpl_table * tab = NULL;
00823 cpl_vector * v_ra = NULL;
00824 cpl_vector * v_dec = NULL;
00825 const char * stdstar;
00826 char * label = NULL;
00827 int nb_stars;
00828 const double max_radius = VISIR_STAR_MAX_RADIUS;
00829 double value = -999;
00830 double jy;
00831 double dist;
00832 int min_dist_ind;
00833
00834
00835 skip_if( 0 );
00836 skip_if( star_cat == NULL );
00837 skip_if( star_name == NULL );
00838 skip_if( filter == NULL );
00839
00840 label = visir_img_phot_filter2label(filter);
00841 skip_if(label == NULL);
00842
00843
00844 if ((tab = cpl_table_load(star_cat, 1, 1)) == NULL) {
00845 cpl_error_set_message(cpl_func, cpl_error_get_code(),
00846 "Could not load the star catalog: %s",
00847 star_cat);
00848 skip_if(1);
00849 }
00850
00851
00852 if (!cpl_table_has_column(tab, label)) {
00853 cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
00854 "Catalog %s has no column for filter: %s",
00855 star_cat, filter);
00856 skip_if(1);
00857 }
00858
00859 if (!cpl_table_has_column(tab, "STARS")) {
00860 cpl_error_set_message(cpl_func, CPL_ERROR_BAD_FILE_FORMAT,
00861 "Catalog %s does not have a column labeled %s",
00862 star_cat, "STARS");
00863 skip_if(1);
00864 }
00865
00866 nb_stars = cpl_table_get_nrow(tab);
00867 skip_if (nb_stars < 1);
00868
00869
00870 v_ra = cpl_vector_wrap(nb_stars, cpl_table_get_data_double(tab, "RA"));
00871 skip_if( v_ra == NULL);
00872
00873 v_dec = cpl_vector_wrap(nb_stars, cpl_table_get_data_double(tab, "DEC"));
00874 skip_if( v_dec == NULL);
00875
00876 min_dist_ind = visir_star_find(v_ra, v_dec, ra, dec, max_radius, &dist);
00877
00878 if (min_dist_ind < 0) {
00879 cpl_error_set_message(cpl_func, cpl_error_get_code(),
00880 "Observation target '%s' was not found among "
00881 "the %d entries in the standard star catalog %s",
00882 star_name, nb_stars, star_cat);
00883 skip_if(1);
00884 }
00885
00886 stdstar = cpl_table_get_string(tab, "STARS", min_dist_ind);
00887 skip_if ( stdstar == NULL );
00888
00889 int null;
00890 jy = cpl_table_get(tab, label, min_dist_ind, &null);
00891 skip_if( 0 );
00892
00893 if (null || isnan(jy)) {
00894 cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
00895 "Catalog does not contain a value for %s in "
00896 "filter %s", star_name, filter);
00897 skip_if(1);
00898 }
00899
00900 value = jy;
00901
00902 if (strcmp(stdstar, star_name) != 0 && dist > 0.0) {
00903
00904 cpl_msg_warning(cpl_func, "The standard star '%s' at (RA,DEC)=(%g,%g) "
00905 "in the FITS header is closest to the catalog star "
00906 "'%s' at (RA,DEC)=(%g,%g) at distance %g degrees",
00907 star_name, ra, dec, stdstar,
00908 cpl_vector_get(v_ra, min_dist_ind),
00909 cpl_vector_get(v_dec, min_dist_ind), dist);
00910 } else if (dist > 0.0) {
00911
00912 cpl_msg_warning(cpl_func, "The location of the standard star '%s' in "
00913 "the FITS header (RA,DEC)=(%g,%g) and the catalog "
00914 "(RA,DEC)=(%g,%g) differ by %g degrees", stdstar, ra,
00915 dec, cpl_vector_get(v_ra, min_dist_ind),
00916 cpl_vector_get(v_dec, min_dist_ind), dist);
00917 } else if (strcmp(stdstar, star_name) != 0) {
00918
00919 cpl_msg_warning(cpl_func, "The name of the standard star at (RA,DEC)="
00920 "(%g,%g) in the FITS header '%s' and the catalog '%s' "
00921 "are different", ra, dec, star_name, stdstar);
00922 } else {
00923 cpl_msg_info(cpl_func, "Standard star is '%s' at (RA, DEC)=(%g,%g)",
00924 stdstar, ra, dec);
00925
00926 if (cpl_msg_get_level() <= CPL_MSG_DEBUG)
00927 cpl_table_dump(tab, min_dist_ind, 1, stdout);
00928 }
00929
00930 cpl_msg_info(cpl_func, "The standard star '%s' has %g Jy through filter %s",
00931 stdstar, value, filter);
00932
00933 end_skip;
00934
00935 cpl_free(label);
00936 cpl_table_delete(tab);
00937 cpl_vector_unwrap(v_ra);
00938 cpl_vector_unwrap(v_dec);
00939
00940 return value;
00941 }
00942
00943
00952
00953 static int visir_img_phot_flux_three(const cpl_image * combined)
00954 {
00955 cpl_errorstate cleanstate = cpl_errorstate_get();
00956 cpl_image * min_combined = NULL;
00957 cpl_apertures * appos = NULL;
00958 cpl_apertures * apneg = NULL;
00959 cpl_vector * sigmas = NULL;
00960 double psigmas[] = {5, 2, 1, 0.5};
00961 double x[3];
00962 double y[3];
00963 double flux_snr[3];
00964 double flux_snr_noise[3];
00965 int flux_snr_radius[3];
00966 double flux_tot[3];
00967 beamshape_t beamshapes[3];
00968 double dist1, dist2;
00969 int ngood_fwhm;
00970 double lam, dlam;
00971 double star_bg,star_peak,star_flux,psf_peak,psf_flux,bg_noise;
00972 double eccmin = DBL_MAX;
00973 const int nsigmas = sizeof(psigmas)/sizeof(double);
00974 int isigma;
00975 #ifdef VISIR_IMG_PHOT_USE_ECCENT_THREE
00976 int ipos, ineg1, ineg2;
00977 #endif
00978 int iappos, iapneg2[2];
00979 int i;
00980
00981
00982 if (cpl_error_get_code()) return cpl_error_get_code();
00983
00984 cpl_ensure_code(combined != NULL, CPL_ERROR_NULL_INPUT);
00985
00986 cpl_msg_info(cpl_func, "Detecting the 3-source star using %d sigma-levels "
00987 "ranging from %g down to %g", nsigmas, psigmas[0],
00988 psigmas[nsigmas-1]);
00989
00990 sigmas = cpl_vector_new(1);
00991 min_combined = cpl_image_multiply_scalar_create(combined, -1.0);
00992 bug_if(0);
00993 for (isigma = 0; isigma < nsigmas; isigma++) {
00994
00995
00996 irplib_error_recover(cleanstate, "Resetting error (why?)");
00997
00998 bug_if(cpl_vector_set(sigmas, 0, psigmas[isigma]));
00999
01000
01001 cpl_apertures_delete(appos);
01002 appos = cpl_apertures_extract(combined, sigmas, NULL);
01003 if (appos == NULL) {
01004 cpl_msg_warning(cpl_func, "Found no positive star at sigma=%g",
01005 psigmas[isigma]);
01006 continue;
01007 }
01008
01009
01010 cpl_apertures_delete(apneg);
01011 apneg = cpl_apertures_extract(min_combined, sigmas, NULL);
01012 if (apneg == NULL) {
01013 cpl_msg_warning(cpl_func, "Found no negative stars at sigma=%g",
01014 psigmas[isigma]);
01015 continue;
01016 }
01017 if (cpl_apertures_get_size(apneg) < 2) {
01018 cpl_msg_warning(cpl_func, "Found just 1 negative star at sigma=%g, "
01019 "need two", psigmas[isigma]);
01020 continue;
01021 }
01022
01023 cpl_msg_info(cpl_func, "Found positive and negative stars at sigma=%g",
01024 psigmas[isigma]);
01025 break;
01026 }
01027
01028 skip_if(appos == NULL);
01029 skip_if(apneg == NULL);
01030 skip_if (cpl_apertures_get_size(apneg) < 2);
01031
01032 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
01033 cpl_apertures_dump(appos, stdout);
01034 cpl_apertures_dump(apneg, stdout);
01035 }
01036
01037 #ifndef VISIR_IMG_PHOT_USE_ECCENT_THREE
01038 bug_if(irplib_apertures_find_max_flux(appos, &iappos, 1));
01039 bug_if(irplib_apertures_find_max_flux(apneg, iapneg2, 2));
01040 #else
01041 if (cpl_apertures_get_size(appos) > 1 || cpl_apertures_get_size(apneg) > 2)
01042 cpl_msg_info(cpl_func, "Selecting from %d positive and %d negative "
01043 "stars 3 stars on a vertical line",
01044 cpl_apertures_get_size(appos),
01045 cpl_apertures_get_size(apneg));
01046
01047 for (ipos = 1; ipos <= cpl_apertures_get_size(appos); ipos++) {
01048 for (ineg1 = 2; ineg1 <= cpl_apertures_get_size(apneg); ineg1++) {
01049 for (ineg2 = 1; ineg2 < ineg1; ineg2++) {
01050 const double ecc = visir_img_phot_eccent_three(appos, ipos,
01051 apneg,
01052 ineg1, ineg2);
01053 if (ecc < eccmin) {
01054 if (eccmin < DBL_MAX)
01055 cpl_msg_debug(cpl_func, "Found star positions with "
01056 "reduced mis-alignment [pixel]: "
01057 "%g < %g", ecc, eccmin);
01058 eccmin = ecc;
01059 iappos = ipos;
01060 iapneg2[0] = ineg1;
01061 iapneg2[1] = ineg2;
01062 }
01063 }
01064 }
01065 }
01066
01067
01068 if (cpl_apertures_get_flux(apneg, iapneg2[0]) <
01069 cpl_apertures_get_flux(apneg, iapneg2[1])) {
01070 const int tmp = iapneg2[0];
01071 iapneg2[0] = iapneg2[1];
01072 iapneg2[1] = tmp;
01073 }
01074
01075 #endif
01076
01077 x[0] = cpl_apertures_get_centroid_x(appos, iappos);
01078 y[0] = cpl_apertures_get_centroid_y(appos, iappos);
01079
01080 x[1] = cpl_apertures_get_centroid_x(apneg, iapneg2[0]);
01081 y[1] = cpl_apertures_get_centroid_y(apneg, iapneg2[0]);
01082 x[2] = cpl_apertures_get_centroid_x(apneg, iapneg2[1]);
01083 y[2] = cpl_apertures_get_centroid_y(apneg, iapneg2[1]);
01084
01085 cpl_apertures_delete(appos);
01086 cpl_apertures_delete(apneg);
01087 appos = NULL;
01088 apneg = NULL;
01089
01090 cpl_msg_info(cpl_func, "Positive star at position %g %g", x[0], y[0]);
01091 cpl_msg_info(cpl_func, "Negative star 1 at position %g %g", x[1], y[1]);
01092 cpl_msg_info(cpl_func, "Negative star 2 at position %g %g", x[2], y[2]);
01093
01094 dist1 = sqrt((x[1]-x[0])*(x[1]-x[0])+(y[1]-y[0])*(y[1]-y[0]));
01095 dist2 = sqrt((x[2]-x[0])*(x[2]-x[0])+(y[2]-y[0])*(y[2]-y[0]));
01096 cpl_msg_info(cpl_func, "Star 1 Pos/Neg Distance: %g", dist1);
01097 cpl_msg_info(cpl_func, "Star 2 Pos/Neg Distance: %g", dist2);
01098
01099
01100 if (eccmin < DBL_MAX) {
01101 cpl_msg_info(cpl_func, "The deviation from a vertical line by "
01102 "the three stars [pixel]: %g", eccmin);
01103 if (eccmin > VISIR_IMG_PHOT_POS_WARN) {
01104 if (eccmin > VISIR_IMG_PHOT_POS_ERROR) {
01105 cpl_msg_error(cpl_func, "The deviation from a vertical line"
01106 " by the three stars exceed %g, the detected "
01107 "objects are wrong", VISIR_IMG_PHOT_POS_ERROR);
01108 skip_if(1);
01109 }
01110 cpl_msg_warning(cpl_func, "The deviation from a vertical line "
01111 "by the three stars exceed %g, the detected "
01112 "objects may be wrong", VISIR_IMG_PHOT_POS_WARN);
01113 }
01114 }
01115
01116
01117 if ((int)x[0]-IRPLIB_STREHL_BORDER <= 0 ||
01118 (int)y[0]-IRPLIB_STREHL_BORDER <= 0 ||
01119 (int)x[0]+IRPLIB_STREHL_BORDER > cpl_image_get_size_x(combined) ||
01120 (int)y[0]+IRPLIB_STREHL_BORDER > cpl_image_get_size_y(combined)) {
01121 cpl_msg_error(cpl_func, "Positive star at (%g,%g) is less than %d "
01122 "pixels from the image border", x[0], y[0],
01123 1+IRPLIB_STREHL_BORDER);
01124 skip_if(1);
01125 }
01126
01127
01128
01129 if (fabs(dist1-dist2) > VISIR_IMG_PHOT_POS_UNCERTAINTY) {
01130 cpl_msg_error(cpl_func, "Too large Pos/Neg Distance between the two "
01131 "stars: %g > %g", fabs(dist1-dist2),
01132 VISIR_IMG_PHOT_POS_UNCERTAINTY);
01133 skip_if(1);
01134 }
01135
01136
01137 skip_if (visir_img_phot_flux(combined, NULL, NULL,
01138 x[0], y[0],
01139 visir_img_phot_config.r0_max,
01140 visir_img_phot_config.r1,
01141 visir_img_phot_config.r2,
01142 &(flux_snr[0]),
01143 &(flux_snr_noise[0]),
01144 &(flux_snr_radius[0]),
01145 &(flux_tot[0]),
01146 &(beamshapes[0])));
01147
01148
01149 for (i=1 ; i<3 ; i++)
01150 skip_if (visir_img_phot_flux(min_combined, NULL, NULL,
01151 x[i], y[i],
01152 visir_img_phot_config.r0_max,
01153 visir_img_phot_config.r1,
01154 visir_img_phot_config.r2,
01155 &(flux_snr[i]),
01156 &(flux_snr_noise[i]),
01157 &(flux_snr_radius[i]),
01158 &(flux_tot[i]),
01159 &(beamshapes[i])));
01160
01161 cpl_image_delete(min_combined);
01162 min_combined = NULL;
01163
01164
01165
01166 visir_img_phot_config.flux_snr = 0.0;
01167 for (i=0 ; i<3 ; i++) visir_img_phot_config.flux_snr += flux_snr[i];
01168
01169
01170 visir_img_phot_config.flux_snr_noise = 0.0;
01171 for (i=0 ; i<3 ; i++) visir_img_phot_config.flux_snr_noise +=
01172 flux_snr_noise[i]*flux_snr_noise[i];
01173 visir_img_phot_config.flux_snr_noise =
01174 sqrt(visir_img_phot_config.flux_snr_noise);
01175
01176 for (i=0 ; i<3 ; i++)
01177 visir_img_phot_config.flux_snr_radius[i] = flux_snr_radius[i];
01178
01179
01180 visir_img_phot_config.flux_tot = 0.0;
01181 for (i=0 ; i<3 ; i++) visir_img_phot_config.flux_tot += flux_tot[i];
01182
01183
01184 ngood_fwhm = 0;
01185 visir_img_phot_config.beamshape.fwhm_x = 0.0;
01186 for (i=0 ; i<3 ; i++) {
01187 if (beamshapes[i].fwhm_x > 0.0) {
01188 visir_img_phot_config.beamshape.fwhm_x += beamshapes[i].fwhm_x;
01189 ngood_fwhm ++;
01190 }
01191 }
01192 if (ngood_fwhm > 0) visir_img_phot_config.beamshape.fwhm_x /= ngood_fwhm;
01193 else visir_img_phot_config.beamshape.fwhm_x = -1.0;
01194 ngood_fwhm = 0;
01195 visir_img_phot_config.beamshape.fwhm_y = 0.0;
01196 for (i=0 ; i<3 ; i++) {
01197 if (beamshapes[i].fwhm_y > 0.0) {
01198 visir_img_phot_config.beamshape.fwhm_y += beamshapes[i].fwhm_y;
01199 ngood_fwhm ++;
01200 }
01201 }
01202 if (ngood_fwhm > 0) visir_img_phot_config.beamshape.fwhm_y /= ngood_fwhm;
01203 else visir_img_phot_config.beamshape.fwhm_y = -1.0;
01204 visir_img_phot_config.fwhm_x_pos1 = beamshapes[0].fwhm_x;
01205 visir_img_phot_config.fwhm_y_pos1 = beamshapes[0].fwhm_y;
01206 visir_img_phot_config.fwhm_x_neg1 = beamshapes[1].fwhm_x;
01207 visir_img_phot_config.fwhm_y_neg1 = beamshapes[1].fwhm_y;
01208 visir_img_phot_config.fwhm_x_neg2 = beamshapes[2].fwhm_x;
01209 visir_img_phot_config.fwhm_y_neg2 = beamshapes[2].fwhm_y;
01210
01211
01212 if (visir_get_filter_infos(visir_img_phot_config.filter, &lam, &dlam)) {
01213 cpl_msg_error(cpl_func, "Could not get info for filter: %s",
01214 visir_img_phot_config.filter);
01215 skip_if(1);
01216 }
01217
01218
01219 cpl_errorstate errstate = cpl_errorstate_get();
01220 if (irplib_strehl_compute(combined, STREHL_M1, STREHL_M2, lam, dlam,
01221 visir_img_phot_config.pscale,
01222 STREHL_BOX_SIZE, x[0], y[0], STREHL_STAR_RADIUS,
01223 STREHL_BG_R1, STREHL_BG_R2, -1, -1,
01224 &(visir_img_phot_config.strehl),
01225 &(visir_img_phot_config.strehl_err),
01226 &star_bg, &star_peak, &star_flux, &psf_peak, &psf_flux,
01227 &bg_noise)) {
01228 cpl_msg_error(cpl_func, "Could not compute the strehl: '%s' in %s",
01229 cpl_error_get_message(), cpl_error_get_where());
01230 cpl_errorstate_set(errstate);
01231 }
01232
01233
01234 end_skip;
01235
01236 cpl_apertures_delete(appos);
01237 cpl_apertures_delete(apneg);
01238 cpl_vector_delete(sigmas);
01239 cpl_image_delete(min_combined);
01240
01241 return cpl_error_get_code();
01242 }
01243
01244 static int visir_img_phot_flux_one(const cpl_image * combined,
01245 const cpl_image * weights,
01246 const cpl_image * contrib,
01247 const cpl_propertylist * plist)
01248 {
01249 double x;
01250 double y;
01251 double flux_snr;
01252 double flux_snr_noise;
01253 int flux_snr_radius;
01254 double flux_tot;
01255 beamshape_t beamshape;
01256 double lam, dlam;
01257 double star_bg,star_peak,star_flux,psf_peak,psf_flux,bg_noise;
01258
01259 if (cpl_error_get_code()) return cpl_error_get_code();
01260
01261 cpl_ensure_code(combined != NULL, CPL_ERROR_NULL_INPUT);
01262
01263 x = cpl_propertylist_get_double(plist, "CRPIX1");
01264 y = cpl_propertylist_get_double(plist, "CRPIX2");
01265 {
01266
01267
01268
01269
01270 cpl_size yp, xp;
01271 cpl_image_get_maxpos_window(combined,
01272 CX_MAX(1, x - 5), CX_MAX(1, y - 5),
01273 CX_MIN(cpl_image_get_size_x(combined), x + 5),
01274 CX_MIN(cpl_image_get_size_y(combined), y + 5), &xp, &yp);
01275 x = xp;
01276 y = yp;
01277 }
01278
01279 cpl_msg_info(cpl_func, "Positive star 1 at position %g %g", x, y);
01280
01281 if ((int)x-IRPLIB_STREHL_BORDER <= 0 ||
01282 (int)y-IRPLIB_STREHL_BORDER <= 0) {
01283 cpl_msg_error(cpl_func, "Positive star 1 at (%g,%g) is less than %d "
01284 "pixels from the image border", x, y,
01285 1+IRPLIB_STREHL_BORDER);
01286 skip_if(1);
01287 }
01288
01289
01290 skip_if (visir_img_phot_flux(combined, weights, contrib,
01291 x, y,
01292 visir_img_phot_config.r0_max,
01293 visir_img_phot_config.r1,
01294 visir_img_phot_config.r2,
01295 &(flux_snr),
01296 &(flux_snr_noise),
01297 &(flux_snr_radius),
01298 &(flux_tot),
01299 &(beamshape)));
01300
01301
01302
01303
01304 visir_img_phot_config.flux_snr = flux_snr;
01305
01306
01307 visir_img_phot_config.flux_snr_noise = flux_snr_noise;
01308
01309 visir_img_phot_config.flux_snr_radius[0] = flux_snr_radius;
01310
01311
01312 visir_img_phot_config.flux_tot = flux_tot;
01313
01314
01315 visir_img_phot_config.beamshape = beamshape;
01316 visir_img_phot_config.fwhm_x_pos1 = beamshape.fwhm_x;
01317 visir_img_phot_config.fwhm_y_pos1 = beamshape.fwhm_y;
01318
01319
01320 if (visir_get_filter_infos(visir_img_phot_config.filter, &lam, &dlam)) {
01321 cpl_msg_error(cpl_func, "Central wavelength and width is missing for "
01322 "filter: %s", visir_img_phot_config.filter);
01323 skip_if(1);
01324 }
01325
01326
01327 cpl_errorstate errstate = cpl_errorstate_get();
01328 if (irplib_strehl_compute(combined, STREHL_M1, STREHL_M2, lam, dlam,
01329 visir_img_phot_config.pscale,
01330 STREHL_BOX_SIZE, x, y, STREHL_STAR_RADIUS,
01331 STREHL_BG_R1, STREHL_BG_R2, -1, -1,
01332 &(visir_img_phot_config.strehl),
01333 &(visir_img_phot_config.strehl_err),
01334 &star_bg, &star_peak, &star_flux, &psf_peak, &psf_flux,
01335 &bg_noise)) {
01336 cpl_msg_error(cpl_func, "Could not compute the strehl: '%s' in %s",
01337 cpl_error_get_message(), cpl_error_get_where());
01338 cpl_errorstate_set(errstate);
01339 }
01340
01341
01342 end_skip;
01343
01344 return cpl_error_get_code();
01345
01346 }
01347
01348
01357
01358 static int visir_img_phot_flux_four(const cpl_image * combined)
01359 {
01360 cpl_errorstate cleanstate = cpl_errorstate_get();
01361 cpl_image * min_combined = NULL;
01362 cpl_apertures * appos = NULL;
01363 cpl_apertures * apneg = NULL;
01364 cpl_vector * sigmas = NULL;
01365 double psigmas[] = {5, 2, 1, 0.5};
01366 double x[4];
01367 double y[4];
01368 double flux_snr[4];
01369 double flux_snr_noise[4];
01370 int flux_snr_radius[4];
01371 double flux_tot[4];
01372 beamshape_t beamshapes[4];
01373 double dist1, dist2;
01374 int ngood_fwhm;
01375 double lam, dlam;
01376 double star_bg,star_peak,star_flux,psf_peak,psf_flux,bg_noise;
01377 double eccmin = DBL_MAX;
01378 const int nsigmas = sizeof(psigmas)/sizeof(double);
01379 int isigma;
01380 int ipos1, ipos2, ineg1, ineg2;
01381 int i;
01382 int iappos2[] = {0, 0};
01383 int iapneg2[] = {0, 0};
01384
01385
01386 if (cpl_error_get_code()) return cpl_error_get_code();
01387
01388 cpl_ensure_code(combined != NULL, CPL_ERROR_NULL_INPUT);
01389
01390 cpl_msg_info(cpl_func, "Detecting the 4-source star using %d sigma-levels "
01391 "ranging from %g down to %g", nsigmas, psigmas[0],
01392 psigmas[nsigmas-1]);
01393
01394 sigmas = cpl_vector_new(1);
01395 min_combined = cpl_image_multiply_scalar_create(combined, -1.0);
01396 bug_if(0);
01397 for (isigma = 0; isigma < nsigmas; isigma++) {
01398
01399
01400 irplib_error_recover(cleanstate, "Resetting error (why?)");
01401
01402 bug_if(cpl_vector_set(sigmas, 0, psigmas[isigma]));
01403
01404
01405 cpl_apertures_delete(appos);
01406 appos = cpl_apertures_extract(combined, sigmas, NULL);
01407 if (appos == NULL) {
01408 cpl_msg_warning(cpl_func, "Found no positive stars at sigma=%g",
01409 psigmas[isigma]);
01410 continue;
01411 }
01412 if (cpl_apertures_get_size(appos) < 2) {
01413 cpl_msg_warning(cpl_func, "Found just 1 positive star at sigma=%g, "
01414 "need two", psigmas[isigma]);
01415 continue;
01416 }
01417
01418
01419 cpl_apertures_delete(apneg);
01420 apneg = cpl_apertures_extract(min_combined, sigmas, NULL);
01421 if (apneg == NULL) {
01422 cpl_msg_warning(cpl_func, "Found no negative stars at sigma=%g",
01423 psigmas[isigma]);
01424 continue;
01425 }
01426 if (cpl_apertures_get_size(apneg) < 2) {
01427 cpl_msg_warning(cpl_func, "Found just 1 negative star at sigma=%g, "
01428 "need two", psigmas[isigma]);
01429 continue;
01430 }
01431
01432 cpl_msg_info(cpl_func, "Found positive and negative stars at sigma=%g",
01433 psigmas[isigma]);
01434 break;
01435 }
01436
01437 skip_if(appos == NULL);
01438 skip_if(apneg == NULL);
01439 skip_if (cpl_apertures_get_size(appos) < 2);
01440 skip_if (cpl_apertures_get_size(apneg) < 2);
01441
01442 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
01443 cpl_apertures_dump(appos, stdout);
01444 cpl_apertures_dump(apneg, stdout);
01445 }
01446
01447 if (cpl_apertures_get_size(appos) > 2 || cpl_apertures_get_size(apneg) > 2)
01448 cpl_msg_info(cpl_func, "Selecting from %d positive and %d negative "
01449 "stars two pairs that outline a square",
01450 (int)cpl_apertures_get_size(appos),
01451 (int)cpl_apertures_get_size(apneg));
01452
01453 for (ipos1 = 2; ipos1 <= cpl_apertures_get_size(appos); ipos1++) {
01454 for (ipos2 = 1; ipos2 < ipos1; ipos2++) {
01455 for (ineg1 = 2; ineg1 <= cpl_apertures_get_size(apneg); ineg1++) {
01456 for (ineg2 = 1; ineg2 < ineg1; ineg2++) {
01457 const double ecc = visir_img_phot_eccent_four(appos, ipos1,
01458 ipos2, apneg,
01459 ineg1, ineg2);
01460
01461 if (ecc < eccmin) {
01462 if (eccmin < DBL_MAX)
01463 cpl_msg_debug(cpl_func, "Found star positions with "
01464 "reduced non-square-ness [pixel]: "
01465 "%g < %g", ecc, eccmin);
01466 eccmin = ecc;
01467 iappos2[0] = ipos1;
01468 iappos2[1] = ipos2;
01469 iapneg2[0] = ineg1;
01470 iapneg2[1] = ineg2;
01471 }
01472 }
01473 }
01474 }
01475 }
01476
01477
01478 if (cpl_apertures_get_flux(appos, iappos2[0]) <
01479 cpl_apertures_get_flux(appos, iappos2[1])) {
01480 const int tmp = iappos2[0];
01481 iappos2[0] = iappos2[1];
01482 iappos2[1] = tmp;
01483 }
01484 if (cpl_apertures_get_flux(apneg, iapneg2[0]) <
01485 cpl_apertures_get_flux(apneg, iapneg2[1])) {
01486 const int tmp = iapneg2[0];
01487 iapneg2[0] = iapneg2[1];
01488 iapneg2[1] = tmp;
01489 }
01490
01491
01492 x[0] = cpl_apertures_get_centroid_x(appos, iappos2[0]);
01493 y[0] = cpl_apertures_get_centroid_y(appos, iappos2[0]);
01494 x[1] = cpl_apertures_get_centroid_x(appos, iappos2[1]);
01495 y[1] = cpl_apertures_get_centroid_y(appos, iappos2[1]);
01496
01497 x[2] = cpl_apertures_get_centroid_x(apneg, iapneg2[0]);
01498 y[2] = cpl_apertures_get_centroid_y(apneg, iapneg2[0]);
01499 x[3] = cpl_apertures_get_centroid_x(apneg, iapneg2[1]);
01500 y[3] = cpl_apertures_get_centroid_y(apneg, iapneg2[1]);
01501
01502 cpl_apertures_delete(appos);
01503 cpl_apertures_delete(apneg);
01504 appos = NULL;
01505 apneg = NULL;
01506
01507 cpl_msg_info(cpl_func, "Positive star 1 at position %g %g", x[0], y[0]);
01508 cpl_msg_info(cpl_func, "Positive star 2 at position %g %g", x[1], y[1]);
01509
01510 cpl_msg_info(cpl_func, "Negative star 1 at position %g %g", x[2], y[2]);
01511 cpl_msg_info(cpl_func, "Negative star 2 at position %g %g", x[3], y[3]);
01512
01513
01514 dist1 = sqrt((x[2]-x[0])*(x[2]-x[0])+(y[2]-y[0])*(y[2]-y[0]));
01515 dist2 = sqrt((x[3]-x[1])*(x[3]-x[1])+(y[3]-y[1])*(y[3]-y[1]));
01516 cpl_msg_info(cpl_func, "Star 1 Pos/Neg Distance: %g", dist1);
01517 cpl_msg_info(cpl_func, "Star 2 Pos/Neg Distance: %g", dist2);
01518
01519 if (eccmin < DBL_MAX) {
01520 cpl_msg_info(cpl_func, "The deviation from a horizontal square by "
01521 "the two star pairs [pixel]: %g", eccmin);
01522 if (eccmin > VISIR_IMG_PHOT_POS_WARN) {
01523 if (eccmin > VISIR_IMG_PHOT_POS_ERROR) {
01524 cpl_msg_error(cpl_func, "The deviation from a horizontal square"
01525 " by the two star pairs exceed %g, the detected "
01526 "objects are wrong", VISIR_IMG_PHOT_POS_ERROR);
01527 skip_if(1);
01528 }
01529 cpl_msg_warning(cpl_func, "The deviation from a horizontal square "
01530 "by the two star pairs exceed %g, the detected "
01531 "objects may be wrong", VISIR_IMG_PHOT_POS_WARN);
01532 }
01533 }
01534
01535 if ((int)x[0]-IRPLIB_STREHL_BORDER <= 0 ||
01536 (int)y[0]-IRPLIB_STREHL_BORDER <= 0 ||
01537 (int)x[0]+IRPLIB_STREHL_BORDER > cpl_image_get_size_x(combined) ||
01538 (int)y[0]+IRPLIB_STREHL_BORDER > cpl_image_get_size_y(combined)) {
01539 cpl_msg_error(cpl_func, "Positive star 1 at (%g,%g) is less than %d "
01540 "pixels from the image border", x[0], y[0],
01541 1+IRPLIB_STREHL_BORDER);
01542 skip_if(1);
01543 }
01544
01545
01546 if (fabs(dist1-dist2) > VISIR_IMG_PHOT_POS_UNCERTAINTY) {
01547 cpl_msg_error(cpl_func, "Too large Pos/Neg Distance between the two "
01548 "stars: %g > %g", fabs(dist1-dist2),
01549 VISIR_IMG_PHOT_POS_UNCERTAINTY);
01550 skip_if(1);
01551 }
01552
01553
01554 for (i=0 ; i<2 ; i++)
01555 skip_if (visir_img_phot_flux(combined, NULL, NULL,
01556 x[i], y[i],
01557 visir_img_phot_config.r0_max,
01558 visir_img_phot_config.r1,
01559 visir_img_phot_config.r2,
01560 &(flux_snr[i]),
01561 &(flux_snr_noise[i]),
01562 &(flux_snr_radius[i]),
01563 &(flux_tot[i]),
01564 &(beamshapes[i])));
01565
01566
01567 for (i=2 ; i<4 ; i++)
01568 skip_if (visir_img_phot_flux(min_combined, NULL, NULL,
01569 x[i], y[i],
01570 visir_img_phot_config.r0_max,
01571 visir_img_phot_config.r1,
01572 visir_img_phot_config.r2,
01573 &(flux_snr[i]),
01574 &(flux_snr_noise[i]),
01575 &(flux_snr_radius[i]),
01576 &(flux_tot[i]),
01577 &(beamshapes[i])));
01578
01579 cpl_image_delete(min_combined);
01580 min_combined = NULL;
01581
01582
01583
01584 visir_img_phot_config.flux_snr = 0.0;
01585 for (i=0 ; i<4 ; i++) visir_img_phot_config.flux_snr += flux_snr[i];
01586
01587
01588 visir_img_phot_config.flux_snr_noise = 0.0;
01589 for (i=0 ; i<4 ; i++) visir_img_phot_config.flux_snr_noise +=
01590 flux_snr_noise[i]*flux_snr_noise[i];
01591 visir_img_phot_config.flux_snr_noise =
01592 sqrt(visir_img_phot_config.flux_snr_noise);
01593
01594 for (i=0 ; i<4 ; i++)
01595 visir_img_phot_config.flux_snr_radius[i] = flux_snr_radius[i];
01596
01597
01598 visir_img_phot_config.flux_tot = 0.0;
01599 for (i=0 ; i<4 ; i++) visir_img_phot_config.flux_tot += flux_tot[i];
01600
01601
01602 ngood_fwhm = 0;
01603 visir_img_phot_config.beamshape.fwhm_x = 0.0;
01604 for (i=0 ; i<4 ; i++) {
01605 if (beamshapes[i].fwhm_x > 0.0) {
01606 visir_img_phot_config.beamshape.fwhm_x += beamshapes[i].fwhm_x;
01607 ngood_fwhm ++;
01608 }
01609 }
01610 if (ngood_fwhm > 0) visir_img_phot_config.beamshape.fwhm_x /= ngood_fwhm;
01611 else visir_img_phot_config.beamshape.fwhm_x = -1.0;
01612 ngood_fwhm = 0;
01613 visir_img_phot_config.beamshape.fwhm_y = 0.0;
01614 for (i=0 ; i<4 ; i++) {
01615 if (beamshapes[i].fwhm_y > 0.0) {
01616 visir_img_phot_config.beamshape.fwhm_y += beamshapes[i].fwhm_y;
01617 ngood_fwhm ++;
01618 }
01619 }
01620 if (ngood_fwhm > 0) visir_img_phot_config.beamshape.fwhm_y /= ngood_fwhm;
01621 else visir_img_phot_config.beamshape.fwhm_y = -1.0;
01622 visir_img_phot_config.fwhm_x_pos1 = beamshapes[0].fwhm_x;
01623 visir_img_phot_config.fwhm_y_pos1 = beamshapes[0].fwhm_y;
01624 visir_img_phot_config.fwhm_x_pos2 = beamshapes[1].fwhm_x;
01625 visir_img_phot_config.fwhm_y_pos2 = beamshapes[1].fwhm_y;
01626 visir_img_phot_config.fwhm_x_neg1 = beamshapes[2].fwhm_x;
01627 visir_img_phot_config.fwhm_y_neg1 = beamshapes[2].fwhm_y;
01628 visir_img_phot_config.fwhm_x_neg2 = beamshapes[3].fwhm_x;
01629 visir_img_phot_config.fwhm_y_neg2 = beamshapes[3].fwhm_y;
01630
01631
01632 if (visir_get_filter_infos(visir_img_phot_config.filter, &lam, &dlam)) {
01633 cpl_msg_error(cpl_func, "Central wavelength and width is missing for "
01634 "filter: %s", visir_img_phot_config.filter);
01635 skip_if(1);
01636 }
01637
01638
01639 cpl_errorstate errstate = cpl_errorstate_get();
01640 if (irplib_strehl_compute(combined, STREHL_M1, STREHL_M2, lam, dlam,
01641 visir_img_phot_config.pscale,
01642 STREHL_BOX_SIZE, x[0], y[0], STREHL_STAR_RADIUS,
01643 STREHL_BG_R1, STREHL_BG_R2, -1, -1,
01644 &(visir_img_phot_config.strehl),
01645 &(visir_img_phot_config.strehl_err),
01646 &star_bg, &star_peak, &star_flux, &psf_peak, &psf_flux,
01647 &bg_noise)) {
01648 cpl_msg_error(cpl_func, "Could not compute the strehl: '%s' in %s",
01649 cpl_error_get_message(), cpl_error_get_where());
01650 cpl_errorstate_set(errstate);
01651 }
01652
01653
01654 end_skip;
01655
01656 cpl_apertures_delete(appos);
01657 cpl_apertures_delete(apneg);
01658 cpl_vector_delete(sigmas);
01659 cpl_image_delete(min_combined);
01660
01661 return cpl_error_get_code();
01662
01663 }
01664
01665
01666
01682
01683 static double visir_img_phot_eccent_four(const cpl_apertures * appos,
01684 int ipos1, int ipos2,
01685 const cpl_apertures * apneg,
01686 int ineg1, int ineg2)
01687 {
01688
01689
01690
01691
01692 const double xp1 = cpl_apertures_get_centroid_x(appos, ipos1);
01693 const double xp2 = cpl_apertures_get_centroid_x(appos, ipos2);
01694 const double yp1 = cpl_apertures_get_centroid_y(appos, ipos1);
01695 const double yp2 = cpl_apertures_get_centroid_y(appos, ipos2);
01696
01697
01698 const double xpl = xp1 < xp2 ? xp1 : xp2;
01699 const double ypl = xp1 < xp2 ? yp1 : yp2;
01700
01701
01702 const double xpr = xp1 < xp2 ? xp2 : xp1;
01703 const double ypr = xp1 < xp2 ? yp2 : yp1;
01704
01705
01706 const double xn1 = cpl_apertures_get_centroid_x(apneg, ineg1);
01707 const double yn1 = cpl_apertures_get_centroid_y(apneg, ineg1);
01708 const double xn2 = cpl_apertures_get_centroid_x(apneg, ineg2);
01709 const double yn2 = cpl_apertures_get_centroid_y(apneg, ineg2);
01710
01711
01712 const double xln = xn1 < xn2 ? xn1 : xn2;
01713 const double yln = xn1 < xn2 ? yn1 : yn2;
01714
01715
01716 const double xrn = xn1 < xn2 ? xn2 : xn1;
01717 const double yrn = xn1 < xn2 ? yn2 : yn1;
01718
01719 const double lx1 = xrn - xpl;
01720 const double lx2 = xpr - xln;
01721 const double ly1 = ypl - yln;
01722 const double ly2 = yrn - ypr;
01723
01724 const double lmean = 0.25 * ( lx1 + lx2 + ly1 + ly2);
01725
01726 const double dx1 = lx1 - lmean;
01727 const double dx2 = lx2 - lmean;
01728 const double dy1 = ly1 - lmean;
01729 const double dy2 = ly2 - lmean;
01730
01731 const double ey1 = yrn - ypl;
01732 const double ey2 = ypr - yln;
01733 const double ex1 = xpl - xln;
01734 const double ex2 = xpr - xrn;
01735
01736 const double result = sqrt(dx1 * dx1 + dx2 * dx2 + dy1 * dy1 + dy2 * dy2 +
01737 ex1 * ex1 + ex2 * ex2 + ey1 * ey1 + ey2 * ey2);
01738
01739
01740 bug_if(0);
01741
01742 bug_if(appos == apneg);
01743 bug_if(ipos1 == ipos2);
01744 bug_if(ineg1 == ineg2);
01745
01746 end_skip;
01747
01748 return result;
01749
01750
01751 }
01752
01753 #ifdef VISIR_IMG_PHOT_USE_ECCENT_THREE
01754
01769
01770 static double visir_img_phot_eccent_three(const cpl_apertures * appos,
01771 int ipos,
01772 const cpl_apertures * apneg,
01773 int ineg1, int ineg2)
01774 {
01775
01776
01777
01778
01779 const double xp = cpl_apertures_get_centroid_x(appos, ipos);
01780 const double yp = cpl_apertures_get_centroid_y(appos, ipos);
01781
01782
01783 const double xn1 = cpl_apertures_get_centroid_x(apneg, ineg1);
01784 const double yn1 = cpl_apertures_get_centroid_y(apneg, ineg1);
01785 const double xn2 = cpl_apertures_get_centroid_x(apneg, ineg2);
01786 const double yn2 = cpl_apertures_get_centroid_y(apneg, ineg2);
01787
01788
01789 const double xnb = xn1 < xn2 ? xn1 : xn2;
01790 const double ynb = xn1 < xn2 ? yn1 : yn2;
01791
01792
01793 const double xnt = xn1 < xn2 ? xn2 : xn1;
01794 const double ynt = xn1 < xn2 ? yn2 : yn1;
01795
01796 const double l1 = ynt - yp;
01797 const double l2 = yp - ynb;
01798 const double ln = ynt - ynb;
01799
01800 const double lmean = 0.25 * ( l1 + l2 + ln);
01801
01802 const double d1 = l1 - lmean;
01803 const double d2 = l2 - lmean;
01804 const double dn = 0.5 * ln - lmean;
01805
01806 const double e1 = xp - xnt;
01807 const double e2 = xp - xnb;
01808
01809 const double result = sqrt(d1 * d1 + d2 * d2 + dn * dn + e1 * e1 + e2 * e2);
01810
01811
01812 bug_if(0);
01813
01814 bug_if(appos == apneg);
01815 bug_if(ineg1 == ineg2);
01816
01817 end_skip;
01818
01819 return result;
01820
01821
01822 }
01823
01824 #endif
01825
01826
01848
01849 static int visir_img_phot_flux(
01850 const cpl_image * combined,
01851 const cpl_image * weights_,
01852 const cpl_image * contrib,
01853 double x_pos,
01854 double y_pos,
01855 int r0_max,
01856 int r1,
01857 int r2,
01858 double * flux_snr,
01859 double * flux_snr_noise,
01860 int * flux_snr_radius,
01861 double * flux_tot,
01862 beamshape_t * beamshape)
01863 {
01864 cpl_apertures * apert = NULL;
01865 cpl_image * labels;
01866 cpl_image * bg_subtracted = NULL;
01867 cpl_vector * r0 = NULL;
01868 cpl_vector * fl = NULL;
01869 cpl_vector * fl_noise = NULL;
01870 cpl_vector * snr = NULL;
01871 double bg;
01872 double max_val = 0.0;
01873 int max_ind = 0;
01874 int i;
01875 cpl_size nx, ny;
01876 int max_contrib = 1;
01877 cpl_image * weights = weights_ == NULL ?
01878 NULL : cpl_image_duplicate(weights_);
01879
01880
01881 if (cpl_error_get_code()) return cpl_error_get_code();
01882
01883 cpl_ensure_code(combined != NULL, CPL_ERROR_NULL_INPUT);
01884 cpl_ensure_code(r0_max > 0, CPL_ERROR_ILLEGAL_INPUT);
01885
01886 nx = cpl_image_get_size_x(combined);
01887 ny = cpl_image_get_size_y(combined);
01888
01889 if (weights) {
01890 cpl_ensure_code(nx == cpl_image_get_size_x(weights) &&
01891 ny == cpl_image_get_size_y(weights),
01892 CPL_ERROR_ILLEGAL_INPUT);
01893 }
01894
01895 if (contrib) {
01896 cpl_ensure_code(nx == cpl_image_get_size_x(contrib) &&
01897 ny == cpl_image_get_size_y(contrib),
01898 CPL_ERROR_ILLEGAL_INPUT);
01899 max_contrib = cpl_image_get_max(contrib);
01900 cpl_ensure_code(max_contrib >= 1, CPL_ERROR_ILLEGAL_INPUT);
01901 }
01902
01903
01904 if ((labels = visir_create_ring_intimage(nx, ny,
01905 (int)x_pos, (int)y_pos, r1, r2)) == NULL) {
01906 cpl_msg_error(cpl_func, "Could not create a ring image");
01907 skip_if(1);
01908 }
01909
01910 apert = cpl_apertures_new_from_image(combined, labels);
01911 cpl_image_delete(labels);
01912 labels = NULL;
01913 bg = cpl_apertures_get_median(apert, 1);
01914 cpl_apertures_delete(apert);
01915 apert = NULL;
01916 cpl_msg_info(cpl_func, "Background : %g", bg);
01917
01918
01919 if ((labels = visir_create_disk_intimage(nx, ny,
01920 (int)x_pos, (int)y_pos, r0_max)) == NULL) {
01921 cpl_msg_error(cpl_func, "Could not create a disk image");
01922 skip_if(1);
01923 }
01924
01925
01926
01927 bg_subtracted = cpl_image_subtract_scalar_create(combined, bg);
01928
01929
01930 if (contrib) {
01931 cpl_image * scale = cpl_image_cast(contrib, CPL_TYPE_DOUBLE);
01932 cpl_image_power(scale, -1);
01933 cpl_image_multiply_scalar(scale, max_contrib);
01934 cpl_image_multiply(bg_subtracted, scale);
01935 if (weights)
01936 cpl_image_multiply(weights, scale);
01937 cpl_image_delete(scale);
01938 }
01939
01940 apert = cpl_apertures_new_from_image(bg_subtracted, labels);
01941 cpl_image_delete(labels);
01942 labels = NULL;
01943 *flux_tot = cpl_apertures_get_flux(apert, 1);
01944 cpl_apertures_delete(apert);
01945 apert = NULL;
01946 cpl_msg_info(cpl_func, "Star total flux (error): %g", *flux_tot);
01947
01948
01949 r0 = cpl_vector_new(r0_max);
01950 for (i=0 ; i<r0_max ; i++) cpl_vector_set(r0, i, i+1);
01951
01952
01953 fl = cpl_vector_new(r0_max);
01954 fl_noise = cpl_vector_new(r0_max);
01955
01956
01957 for (i=0 ; i<r0_max ; i++) {
01958 float fl_val = 0.f, fl_noise_val = 0.f;
01959
01960 if ((labels = visir_create_disk_intimage(nx, ny,
01961 (int)x_pos, (int)y_pos, (int)cpl_vector_get(r0, i))) == NULL) {
01962 cpl_msg_error(cpl_func, "Could not create a disk image: %d", i);
01963 break;
01964 }
01965
01966 if (weights) {
01967 double sum = 0, esum = 0;
01968 int d;
01969 for (int ix = 1; ix < 1 + nx; ix++) {
01970 for (int iy = 1; iy < 1 + ny; iy++) {
01971 if (!cpl_image_get(labels, ix, iy, &d) || d)
01972 continue;
01973
01974 sum += cpl_image_get(bg_subtracted, ix, iy, &d);
01975
01976
01977 esum += (1. / cpl_image_get(weights, ix, iy, &d));
01978 }
01979 }
01980 fl_val = sum;
01981 fl_noise_val = sqrt(esum);
01982 }
01983 else {
01984 cpl_apertures * pert =
01985 cpl_apertures_new_from_image(bg_subtracted, labels);
01986
01987 fl_val = cpl_apertures_get_flux(pert, 1);
01988 fl_noise_val = visir_img_phot_config.bg_sigma *
01989 sqrt((double)cpl_apertures_get_npix(pert, 1));
01990 cpl_apertures_delete(pert);
01991 }
01992
01993
01994 cpl_image_delete(labels);
01995 labels = NULL;
01996 cpl_vector_set(fl, i, fl_val);
01997 cpl_vector_set(fl_noise, i, fl_noise_val);
01998 }
01999 skip_if( 0 );
02000
02001
02002 snr = cpl_vector_duplicate(fl);
02003 cpl_vector_divide(snr, fl_noise);
02004 for (i=0 ; i<r0_max ; i++) {
02005 if (i == 0 || max_val < cpl_vector_get(snr, i)) {
02006 max_val = cpl_vector_get(snr, i);
02007 max_ind = i;
02008 }
02009 }
02010 *flux_snr = cpl_vector_get(fl, max_ind);
02011 *flux_snr_noise = cpl_vector_get(fl_noise, max_ind);
02012 *flux_snr_radius = (int)cpl_vector_get(r0, max_ind);
02013 cpl_msg_info(cpl_func, "Best SNR star flux : %g (%g) for radius %d <= %d "
02014 " [pixel]", *flux_snr, *flux_snr_noise,
02015 (int)cpl_vector_get(r0, max_ind),
02016 (int)cpl_vector_get(r0, r0_max-1));
02017
02018 if (cpl_msg_get_level() <= CPL_MSG_DEBUG) {
02019 cpl_matrix * mdump = cpl_matrix_new(1+r0_max, 3);
02020 for (i = 0; i < r0_max; i++) {
02021 cpl_matrix_set(mdump, i+1, 0, cpl_vector_get(fl, i));
02022 cpl_matrix_set(mdump, i+1, 1, cpl_vector_get(fl_noise, i));
02023 cpl_matrix_set(mdump, i+1, 2, cpl_vector_get(snr, i));
02024 }
02025 cpl_msg_debug(cpl_func, "Flux, flux-noise and S/N for radii out to %d",
02026 (int)cpl_vector_get(r0, r0_max-1));
02027
02028 cpl_matrix_dump(mdump, stdout);
02029 cpl_matrix_delete(mdump);
02030 }
02031
02032 *beamshape = (beamshape_t){.fwhm_x = -1., .fwhm_y = -1.,
02033 .peak = -1., .peak_err = 0.,
02034 .major = -1., .major_err = 0.,
02035 .minor = -1., .minor_err = 0.,
02036 .angle = -1., .angle_err = 0.};
02037
02038
02039 skip_if (cpl_image_get_fwhm(bg_subtracted, (int)x_pos, (int)y_pos, &beamshape->fwhm_x,
02040 &beamshape->fwhm_y));
02041
02042 skip_if ( beamshape->fwhm_x <= 0.0 );
02043 skip_if ( beamshape->fwhm_y <= 0.0 );
02044
02045 cpl_errorstate cleanstate = cpl_errorstate_get();
02046
02047 if (fit_2d_gauss(bg_subtracted, weights, (cpl_size)x_pos, (cpl_size)y_pos,
02048 beamshape->fwhm_x, beamshape->fwhm_y,
02049 &beamshape->peak, &beamshape->peak_err,
02050 &beamshape->major, &beamshape->major_err,
02051 &beamshape->minor, &beamshape->minor_err,
02052 &beamshape->angle, &beamshape->angle_err) == CPL_ERROR_NONE) {
02053 cpl_msg_info(cpl_func, "Peak: %g +- %g, FWHM : %g +- %g major ; %g +- %g minor, "
02054 "angle %g +- %g", beamshape->peak, beamshape->peak_err,
02055 beamshape->major, beamshape->major_err,
02056 beamshape->minor, beamshape->minor_err, beamshape->angle *
02057 CPL_MATH_DEG_RAD, beamshape->angle_err *
02058 CPL_MATH_DEG_RAD);
02059 }
02060 else {
02061 cpl_msg_warning(cpl_func, "2D gauss fit failed, approximate FWHM : %g"
02062 "in x ; %g in y ", beamshape->fwhm_x, beamshape->fwhm_y);
02063 cpl_errorstate_set(cleanstate);
02064 }
02065
02066 end_skip;
02067
02068 cpl_apertures_delete(apert);
02069 cpl_image_delete(labels);
02070 cpl_image_delete(bg_subtracted);
02071 cpl_image_delete(weights);
02072
02073 cpl_vector_delete(r0);
02074 cpl_vector_delete(fl);
02075 cpl_vector_delete(snr);
02076 cpl_vector_delete(fl_noise);
02077
02078 return cpl_error_get_code();
02079 }
02080
02081
02082
02093
02094 static cpl_error_code visir_get_filter_infos(
02095 const char * f,
02096 double * pcwlen,
02097 double * pdwlen)
02098 {
02099
02100 double cwlen = -1;
02101 double dwlen = -1;
02102
02103 cpl_ensure_code(f, CPL_ERROR_NULL_INPUT);
02104 cpl_ensure_code(pcwlen, CPL_ERROR_NULL_INPUT);
02105 cpl_ensure_code(pdwlen, CPL_ERROR_NULL_INPUT);
02106
02107 skip_if (!strcmp(f, "MV"));
02108
02109 if (!strcmp(f, "N-BAND") || !strcmp(f, "N_BAND"))
02110 { cwlen = 10.56; dwlen = 5.37;}
02111 else if (!strcmp(f, "SIC")) { cwlen = 11.848;dwlen = 2.34;}
02112 else if (!strcmp(f, "PAH1_1")) { cwlen = 8.19;dwlen = 0.15;}
02113 else if (!strcmp(f, "PAH1")) { cwlen = 8.586;dwlen = 0.421;}
02114 else if (!strcmp(f, "ARIII")) { cwlen = 8.992;dwlen = 0.138;}
02115 else if (!strcmp(f, "SIV_1")) { cwlen = 10.02;dwlen = 0.18;}
02116 else if (!strcmp(f, "SIV")) { cwlen = 10.485;dwlen = 0.159;}
02117 else if (!strcmp(f, "PAH2_1")) { cwlen = 10.76;dwlen = 0.69;}
02118 else if (!strcmp(f, "SIV_2")) { cwlen = 11.1;dwlen = 0.19;}
02119 else if (!strcmp(f, "PAH2")) { cwlen = 11.254;dwlen = 0.594;}
02120 else if (!strcmp(f, "PAH2_2")) { cwlen = 12.13;dwlen = 0.37;}
02121 else if (!strcmp(f, "NEII_1")) { cwlen = 12.51;dwlen = 0.18;}
02122 else if (!strcmp(f, "NEII")) { cwlen = 12.805;dwlen = 0.21;}
02123 else if (!strcmp(f, "NEII_2")) { cwlen = 13.036;dwlen = 0.219;}
02124 else if (!strcmp(f, "Q0")) { cwlen = 16.554;dwlen = 0.398;}
02125 else if (!strcmp(f, "QH2")) { cwlen = 17.11;dwlen = 0.398;}
02126 else if (!strcmp(f, "Q1")) { cwlen = 17.653;dwlen = 0.83;}
02127 else if (!strcmp(f, "Q2")) { cwlen = 18.718;dwlen = 0.878;}
02128 else if (!strcmp(f, "Q3")) { cwlen = 19.5;dwlen = 0.4;}
02129 else if (!strcmp(f, "Q4")) { cwlen = 20.5;dwlen = 1.0;}
02130 else if (!strcmp(f, "Q7")) { cwlen = 23.1;dwlen = 0.8;}
02131 else if (!strcmp(f, "Q8")) { cwlen = 24.5;dwlen = 0.8;}
02132
02133 else if (!strcmp(f, "10_5_4QP")) { cwlen = 10.5;dwlen =0.1;}
02134 else if (!strcmp(f, "11_3_4QP")) { cwlen = 11.3;dwlen =0.1;}
02135 else if (!strcmp(f, "12_4_AGP")) { cwlen = 12.4;dwlen =0.1;}
02136 else if (!strcmp(f, "N-SW-spec") || !strcmp(f, "N_SW_spec"))
02137 { cwlen = 8.85; dwlen = 2.7;}
02138 else if (!strcmp(f, "H2S4-spec") || !strcmp(f, "H2S4_spec"))
02139 { cwlen = 8.12; dwlen = 0.3;}
02140 else if (!strcmp(f, "ARIII-spec") || !strcmp(f, "ARIII_spec"))
02141 { cwlen = 8.44; dwlen = 0.78;}
02142 else if (!strcmp(f, "NEII_2-spec") || !strcmp(f, "NEII_2_spec"))
02143 { cwlen = 12.805; dwlen = 0.2;}
02144 else if (!strcmp(f, "H2S3-spec") || !strcmp(f, "H2S3_spec"))
02145 { cwlen = 9.62; dwlen = 0.2;}
02146 else if (!strcmp(f, "H2S1-spec") || !strcmp(f, "H2S1_spec"))
02147 { cwlen = 17.0;dwlen = 0.4;}
02148 else if (!strcmp(f, "M-BAND") || !strcmp(f, "M_BAND"))
02149 { cwlen = 4.82;dwlen = 0.35;}
02150
02151
02152
02153 else if (!strcmp(f, "J7.9") || !strcmp(f, "J7_9"))
02154 { cwlen = (7.483 + 8.035)/2.0;
02155 dwlen = 8.035 - 7.483;}
02156 else if (!strcmp(f, "J8.9") || !strcmp(f, "J8_9"))
02157 { cwlen = (8.338 + 9.068)/2.0;
02158 dwlen = 9.068 - 8.338;}
02159 else if (!strcmp(f, "J9.8") || !strcmp(f, "J9_8"))
02160 { cwlen = (9.123 + 10.059)/2.0;
02161 dwlen = 10.059 - 9.123;}
02162 else if (!strcmp(f, "J12.2") || !strcmp(f, "J12_2"))
02163 { cwlen = (11.700 + 12.216)/2.0;
02164 dwlen = 12.216 - 11.700;}
02165 else if (!strcmp(f, "B8.7") || !strcmp(f, "B8_7"))
02166 { cwlen = (8.436 + 9.410)/2.0;
02167 dwlen = 9.410 - 8.436;}
02168 else if (!strcmp(f, "B9.7") || !strcmp(f, "B9_7"))
02169 { cwlen = (9.402 + 10.242)/2.0;
02170 dwlen = 10.242 - 9.402;}
02171 else if (!strcmp(f, "B10.7") || !strcmp(f, "B10_7"))
02172 { cwlen = (9.970 + 11.338)/2.0;
02173 dwlen = 11.338 - 9.970;}
02174 else if (!strcmp(f, "B11.7") || !strcmp(f, "B11_7"))
02175 { cwlen = (11.098 + 11.950)/2.0;
02176 dwlen = 11.950 - 11.098;}
02177 else if (!strcmp(f, "B12.4") || !strcmp(f, "B12_4"))
02178 { cwlen = (11.971 + 12.961)/2.0;
02179 dwlen = 12.961 - 11.971;}
02180
02181 *pcwlen = cwlen;
02182 *pdwlen = dwlen;
02183
02184 cpl_ensure_code(cwlen > 0, CPL_ERROR_DATA_NOT_FOUND);
02185 cpl_ensure_code(dwlen > 0, CPL_ERROR_DATA_NOT_FOUND);
02186
02187 end_skip;
02188
02189 return cpl_error_get_code();
02190 }
02191
02192
02200
02201 static cpl_error_code visir_img_phot_qc(cpl_propertylist * qclist,
02202 cpl_boolean drop_wcs,
02203 const irplib_framelist * rawframes)
02204 {
02205
02206 const cpl_propertylist * reflist
02207 = irplib_framelist_get_propertylist_const(rawframes, 0);
02208
02209
02210
02211 bug_if (cpl_propertylist_append_double(qclist, "ESO QC EXPTIME",
02212 visir_img_phot_config.exptime));
02213
02214 bug_if (cpl_propertylist_append_double(qclist, "ESO QC JYVAL",
02215 visir_img_phot_config.jy_val));
02216
02217 bug_if (cpl_propertylist_append_string(qclist, "ESO QC STARNAME",
02218 visir_img_phot_config.star_name));
02219
02220 bug_if (cpl_propertylist_append_string(qclist, "ESO QC FILTER",
02221 visir_img_phot_config.filter));
02222
02223
02224 bug_if (cpl_propertylist_append_double(qclist, "ESO QC NELEC",
02225 visir_img_phot_config.nelec));
02226
02227 bug_if (cpl_propertylist_append_double(qclist, "ESO QC NPHOT",
02228 visir_img_phot_config.nphot));
02229
02230 bug_if (cpl_propertylist_append_double(qclist, "ESO QC BACKGD SIGMA",
02231 visir_img_phot_config.bg_sigma));
02232
02233 bug_if (cpl_propertylist_append_double(qclist, "ESO QC FLUXTOT",
02234 visir_img_phot_config.flux_tot));
02235
02236 bug_if (cpl_propertylist_append_double(qclist, "ESO QC FLUXSNR",
02237 visir_img_phot_config.flux_snr));
02238
02239 bug_if (cpl_propertylist_append_double(qclist, "ESO QC FLUXSNR NOISE",
02240 visir_img_phot_config.flux_snr_noise));
02241
02242 for (int i = 0; i < 4; i++) {
02243 const int r = visir_img_phot_config.flux_snr_radius[i];
02244 char buffer[100];
02245 sprintf(buffer, "ESO QC FLUXSNR RADIUS%d", i + 1);
02246 bug_if (cpl_propertylist_append_int(qclist, buffer, r));
02247 }
02248
02249 bug_if (cpl_propertylist_append_double(qclist, "ESO QC FWHMX",
02250 visir_img_phot_config.beamshape.fwhm_x));
02251
02252 bug_if (cpl_propertylist_append_double(qclist, "ESO QC FWHMY",
02253 visir_img_phot_config.beamshape.fwhm_y));
02254 bug_if (cpl_propertylist_append_double(qclist, "ESO QC GAUSSFIT FWHM_MAX",
02255 visir_img_phot_config.beamshape.major));
02256 cpl_propertylist_set_comment(qclist, "ESO QC GAUSSFIT FWHM_MAX",
02257 "major axis [pix]");
02258 bug_if (cpl_propertylist_append_double(qclist, "ESO QC GAUSSFIT FWHM_MAX_ERR",
02259 visir_img_phot_config.beamshape.major_err));
02260 bug_if (cpl_propertylist_append_double(qclist, "ESO QC GAUSSFIT FWHM_MIN",
02261 visir_img_phot_config.beamshape.minor));
02262 cpl_propertylist_set_comment(qclist, "ESO QC GAUSSFIT FWHM_MIN",
02263 "minor axis [pix]");
02264 bug_if (cpl_propertylist_append_double(qclist, "ESO QC GAUSSFIT FWHM_MIN_ERR",
02265 visir_img_phot_config.beamshape.minor_err));
02266 bug_if (cpl_propertylist_append_double(qclist, "ESO QC GAUSSFIT ANGLE",
02267 visir_img_phot_config.beamshape.angle * CPL_MATH_DEG_RAD));
02268 cpl_propertylist_set_comment(qclist, "ESO QC GAUSSFIT ANGLE",
02269 "[deg]");
02270 bug_if (cpl_propertylist_append_double(qclist, "ESO QC GAUSSFIT ANGLE_ERR",
02271 visir_img_phot_config.beamshape.angle_err * CPL_MATH_DEG_RAD));
02272 bug_if (cpl_propertylist_append_double(qclist, "ESO QC GAUSSFIT PEAK",
02273 visir_img_phot_config.beamshape.peak));
02274 bug_if (cpl_propertylist_append_double(qclist, "ESO QC GAUSSFIT PEAK_ERR",
02275 visir_img_phot_config.beamshape.peak_err));
02276
02277 bug_if (cpl_propertylist_append_double(qclist, "ESO QC FWHMX POS1",
02278 visir_img_phot_config.fwhm_x_pos1));
02279
02280 bug_if (cpl_propertylist_append_double(qclist, "ESO QC FWHMY POS1",
02281 visir_img_phot_config.fwhm_y_pos1));
02282
02283 bug_if (cpl_propertylist_append_double(qclist, "ESO QC FWHMX POS2",
02284 visir_img_phot_config.fwhm_x_pos2));
02285
02286 bug_if (cpl_propertylist_append_double(qclist, "ESO QC FWHMY POS2",
02287 visir_img_phot_config.fwhm_y_pos2));
02288
02289 bug_if (cpl_propertylist_append_double(qclist, "ESO QC FWHMX NEG1",
02290 visir_img_phot_config.fwhm_x_neg1));
02291
02292 bug_if (cpl_propertylist_append_double(qclist, "ESO QC FWHMY NEG1",
02293 visir_img_phot_config.fwhm_y_neg1));
02294
02295 bug_if (cpl_propertylist_append_double(qclist, "ESO QC FWHMX NEG2",
02296 visir_img_phot_config.fwhm_x_neg2));
02297
02298 bug_if (cpl_propertylist_append_double(qclist, "ESO QC FWHMY NEG2",
02299 visir_img_phot_config.fwhm_y_neg2));
02300
02301 bug_if (cpl_propertylist_append_double(qclist, "ESO QC SENSIT",
02302 visir_img_phot_config.sensitivity));
02303
02304 bug_if (cpl_propertylist_append_double(qclist, "ESO QC AREA SENSIT",
02305 visir_img_phot_config.area_sensit));
02306 cpl_propertylist_set_comment(qclist, "ESO QC AREA SENSIT",
02307 "scaled to noise of 1 arcsecond");
02308
02309 bug_if (cpl_propertylist_append_double(qclist, "ESO QC CONVER",
02310 visir_img_phot_config.conversion));
02311
02312 bug_if (cpl_propertylist_append_double(qclist, "ESO QC STREHL",
02313 visir_img_phot_config.strehl));
02314
02315 bug_if (cpl_propertylist_append_double(qclist, "ESO QC STREHL ERROR",
02316 visir_img_phot_config.strehl_err));
02317
02318
02319 skip_if (visir_qc_append_capa(qclist, rawframes));
02320
02321 if (drop_wcs) {
02322 cpl_propertylist * pcopy = cpl_propertylist_new();
02323 const cpl_error_code error
02324 = cpl_propertylist_copy_property_regexp(pcopy, reflist, "^("
02325 IRPLIB_PFITS_WCS_REGEXP
02326 ")$", 0);
02327 if (!error && cpl_propertylist_get_size(pcopy) > 0) {
02328 cpl_msg_warning(cpl_func, "Combined image will have no WCS "
02329 "coordinates");
02330 }
02331 cpl_propertylist_delete(pcopy);
02332 bug_if(0);
02333
02334 bug_if(cpl_propertylist_copy_property_regexp(qclist, reflist, "^("
02335 VISIR_PFITS_IMG_PHOT_COPY
02336 ")$", 0));
02337 } else {
02338 bug_if(cpl_propertylist_copy_property_regexp(qclist, reflist, "^("
02339 VISIR_PFITS_IMG_PHOT_COPY
02340 "|" IRPLIB_PFITS_WCS_REGEXP
02341 ")$", 0));
02342 }
02343
02344 bug_if (irplib_pfits_set_airmass(qclist, rawframes));
02345
02346 end_skip;
02347
02348 return cpl_error_get_code();
02349
02350 }
02351
02352
02364
02365 static cpl_error_code visir_img_phot_save(cpl_frameset * self,
02366 const cpl_parameterlist * parlist,
02367 const cpl_propertylist * qclist,
02368 const cpl_image * combined,
02369 const cpl_image * contrib,
02370 const cpl_image * beam1,
02371 const cpl_image * beam1i,
02372 const cpl_image * weights)
02373 {
02374
02375 cpl_propertylist * xtlist = cpl_propertylist_new();
02376 const char * procatg = VISIR_IMG_PHOT_COMBINED_PROCATG;
02377
02378 bug_if (0);
02379
02380 if (weights) {
02381 const char * s = cpl_propertylist_get_string(qclist, "ESO QC BEAMID");
02382 bug_if(s == NULL);
02383
02384 if (strcmp(s, "COMBINED") == 0)
02385 procatg = VISIR_IMG_PHOT_COMBINED_PROCATG;
02386 else
02387 procatg = VISIR_IMG_PHOT_ONEBEAM_PROCATG;
02388 }
02389
02390
02391 skip_if (irplib_dfs_save_image(self, parlist, self, combined,
02392 CPL_BPP_IEEE_FLOAT, RECIPE_SAVE_STRING,
02393 procatg, qclist, NULL, visir_pipe_id,
02394 RECIPE_SAVE_STRING CPL_DFS_FITS));
02395
02396 if (!weights) {
02397
02398 bug_if(cpl_propertylist_append_string(xtlist, "EXTNAME",
02399 "Contribution Map"));
02400 skip_if (cpl_image_save(contrib, RECIPE_SAVE_STRING CPL_DFS_FITS,
02401 CPL_BPP_16_UNSIGNED, xtlist, CPL_IO_EXTEND));
02402 }
02403
02404 if (beam1 != NULL) {
02405 bug_if(weights);
02406
02407 skip_if (irplib_dfs_save_image(self, parlist, self, beam1,
02408 CPL_BPP_IEEE_FLOAT, RECIPE_SAVE_STRING,
02409 VISIR_IMG_PHOT_ONEBEAM_PROCATG, qclist,
02410 NULL, visir_pipe_id,
02411 RECIPE_SAVE_STRING "_onebeam" CPL_DFS_FITS));
02412
02413
02414 skip_if (cpl_image_save(beam1i, RECIPE_SAVE_STRING "_onebeam" CPL_DFS_FITS,
02415 CPL_BPP_8_UNSIGNED, xtlist, CPL_IO_EXTEND));
02416 }
02417
02418 end_skip;
02419
02420 cpl_propertylist_delete(xtlist);
02421
02422 return cpl_error_get_code();
02423
02424 }
02425
02426
02436
02437 static char * visir_img_phot_filter2label(const char * self)
02438 {
02439
02440 char * label = NULL;
02441 char * p;
02442
02443 bug_if(self == NULL);
02444
02445 label = cpl_strdup(self);
02446
02447 for (p = label; *p != (char)0; p++) {
02448 if (*p == '.' || *p == '-') *p = '_';
02449 }
02450
02451 end_skip;
02452
02453 return label;
02454
02455 }