00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <muse.h>
00023 #include <string.h>
00024 #include <strings.h>
00025
00026
00062
00063
00066
00067 static cpl_apertures *
00068 image_fwhm_cplapertures_extract(cpl_image *aImage, cpl_vector *aSigmas,
00069 cpl_size *aIndex)
00070 {
00071 cpl_ensure(aImage && aSigmas, CPL_ERROR_NULL_INPUT, NULL);
00072 cpl_apertures *aperts = NULL;
00073 cpl_errorstate prestate = cpl_errorstate_get();
00074 cpl_size i, n = cpl_vector_get_size(aSigmas);
00075 for (i = 0; i < n; i++) {
00076 const double sigma = cpl_vector_get(aSigmas, i);
00077 if (sigma <= 0.0) {
00078 break;
00079 }
00080
00081
00082 double mdev, median = cpl_image_get_median_dev(aImage, &mdev),
00083 threshold = median + sigma * mdev;
00084
00085 cpl_mask *selection = cpl_mask_threshold_image_create(aImage, threshold,
00086 DBL_MAX);
00087 cpl_size nlabels;
00088 cpl_image *labels = cpl_image_labelise_mask_create(selection, &nlabels);
00089 cpl_mask_delete(selection);
00090
00091 aperts = cpl_apertures_new_from_image(aImage, labels);
00092 cpl_image_delete(labels);
00093
00094 if (aperts) {
00095 break;
00096 }
00097 }
00098 cpl_ensure(aperts, CPL_ERROR_DATA_NOT_FOUND, NULL);
00099
00100 cpl_errorstate_set(prestate);
00101 if (aIndex) {
00102 *aIndex = i;
00103 }
00104 return aperts;
00105 }
00106
00107 #define PRINT_USAGE(rc) \
00108 fprintf(stderr, "Usage: %s [ -s sigma ] [ -x extindex | -n extname] " \
00109 "IMAGE\n", argv[0]); \
00110 cpl_end(); return (rc);
00111
00112 int main(int argc, char **argv)
00113 {
00114 cpl_init(CPL_INIT_DEFAULT);
00115 muse_processing_recipeinfo(NULL);
00116
00117 if (argc <= 1) {
00118
00119 PRINT_USAGE(1);
00120 }
00121
00122 char *iname = NULL,
00123 *extname = NULL;
00124 double sigma = -1;
00125 int iext = -1;
00126
00127
00128 int i;
00129 for (i = 1; i < argc; i++) {
00130 if (strncmp(argv[i], "-s", 3) == 0) {
00131
00132 i++;
00133 if (i < argc) {
00134 sigma = atof(argv[i]);
00135 if (sigma <= 0.) {
00136 PRINT_USAGE(3);
00137 }
00138 } else {
00139 PRINT_USAGE(2);
00140 }
00141 } else if (strncmp(argv[i], "-x", 3) == 0) {
00142
00143 i++;
00144 if (i < argc) {
00145 iext = atoi(argv[i]);
00146 if (iext < 0) {
00147 PRINT_USAGE(5);
00148 }
00149 } else {
00150 PRINT_USAGE(4);
00151 }
00152 } else if (strncmp(argv[i], "-n", 3) == 0) {
00153
00154 i++;
00155 if (i < argc) {
00156 extname = argv[i];
00157 } else {
00158 PRINT_USAGE(6);
00159 }
00160 } else if (strncmp(argv[i], "-", 1) == 0) {
00161 PRINT_USAGE(9);
00162 } else {
00163 if (iname) {
00164 break;
00165 }
00166 iname = argv[i] ;
00167 }
00168 }
00169 if (extname && iext >= 0) {
00170 PRINT_USAGE(7);
00171 }
00172
00173 int next = cpl_fits_count_extensions(iname);
00174 if (next < 0) {
00175 PRINT_USAGE(10);
00176 }
00177 if (extname) {
00178 iext = cpl_fits_find_extension(iname, extname);
00179 }
00180 cpl_image *image = NULL;
00181 if (iext >= 0) {
00182 image = cpl_image_load(iname, CPL_TYPE_UNSPECIFIED, 0, iext);
00183 } else {
00184 cpl_errorstate ps = cpl_errorstate_get();
00185 do {
00186 image = cpl_image_load(iname, CPL_TYPE_UNSPECIFIED, 0, ++iext);
00187 } while (!image && iext <= next);
00188 cpl_errorstate_set(ps);
00189 }
00190 if (!image) {
00191 PRINT_USAGE(11);
00192 }
00193 cpl_propertylist *header = cpl_propertylist_load(iname, iext);
00194 int nx = cpl_image_get_size_x(image),
00195 ny = cpl_image_get_size_y(image);
00196 char *extdisp = NULL;
00197 if (cpl_propertylist_has(header, "EXTNAME")) {
00198 extdisp = cpl_strdup(cpl_propertylist_get_string(header, "EXTNAME"));
00199 } else {
00200 extdisp = cpl_sprintf("%d", iext);
00201 }
00202
00203 cpl_image_reject_value(image, CPL_VALUE_NAN);
00204 int nrej = cpl_image_count_rejected(image);
00205 printf("# Input image \"%s[%s]\" (size %dx%d, rejected %d)\n", iname, extdisp,
00206 nx, ny, nrej);
00207 cpl_free(extdisp);
00208
00209 cpl_vector *vsigmas = NULL;
00210 if (sigma > 0) {
00211 vsigmas = cpl_vector_new(1);
00212 cpl_vector_set(vsigmas, 0, sigma);
00213 } else {
00214 vsigmas = cpl_vector_new(6);
00215 cpl_vector_set(vsigmas, 0, 50.);
00216 cpl_vector_set(vsigmas, 1, 30.);
00217 cpl_vector_set(vsigmas, 2, 20.);
00218 cpl_vector_set(vsigmas, 3, 10.);
00219 cpl_vector_set(vsigmas, 4, 8.);
00220 cpl_vector_set(vsigmas, 5, 5.);
00221 }
00222 cpl_size isigma = -1;
00223 cpl_errorstate prestate = cpl_errorstate_get();
00224 cpl_apertures *apertures = image_fwhm_cplapertures_extract(image, vsigmas, &isigma);
00225 if (!apertures || !cpl_errorstate_is_equal(prestate)) {
00226 cpl_image_delete(image);
00227 fprintf(stderr, "%s: no sources found for FWHM measurement down to %.1f "
00228 "sigma limit!\n", argv[0],
00229 cpl_vector_get(vsigmas, cpl_vector_get_size(vsigmas) - 1));
00230 cpl_vector_delete(vsigmas);
00231 return 20;
00232 }
00233 int ndet = cpl_apertures_get_size(apertures);
00234 printf("# %s: computing FWHM QC parameters for %d source%s found down to the "
00235 "%.1f sigma threshold\n", argv[0], ndet, ndet == 1 ? "" : "s",
00236 cpl_vector_get(vsigmas, isigma));
00237 cpl_vector_delete(vsigmas);
00238
00239
00240
00241 double cd11 = kMuseSpaxelSizeX_WFM, cd12 = 0., cd21 = 0.,
00242 cd22 = kMuseSpaxelSizeY_WFM;
00243 cpl_wcs *wcs = cpl_wcs_new_from_propertylist(header);
00244 if (!wcs ||
00245 !strncasecmp(muse_pfits_get_ctype(header, 1), "PIXEL", 5)) {
00246 printf("# %s: FWHM parameter estimation (%d sources): simple conversion "
00247 "to arcsec (CTYPE=%s/%s)!\n", argv[0], ndet,
00248 muse_pfits_get_ctype(header, 1),
00249 muse_pfits_get_ctype(header, 2));
00250 if (muse_pfits_get_mode(header) > MUSE_MODE_WFM_AO_N) {
00251 cd11 = kMuseSpaxelSizeX_NFM;
00252 cd22 = kMuseSpaxelSizeY_NFM;
00253 }
00254 } else {
00255 const cpl_matrix *cd = cpl_wcs_get_cd(wcs);
00256
00257 cd11 = fabs(cpl_matrix_get(cd, 0, 0)) * 3600.,
00258 cd12 = fabs(cpl_matrix_get(cd, 0, 1)) * 3600.,
00259 cd21 = fabs(cpl_matrix_get(cd, 1, 0)) * 3600.,
00260 cd22 = fabs(cpl_matrix_get(cd, 1, 1)) * 3600.;
00261 printf("# %s: FWHM parameter estimation (%d sources): full "
00262 "conversion to arcsec (CD=%.2f,%.2f,%.2f,%.2f)\n", argv[0], ndet,
00263 cd11, cd12, cd21, cd22);
00264 }
00265 cpl_wcs_delete(wcs);
00266
00267
00268 cpl_vector *vfwhm = cpl_vector_new(ndet),
00269 *vgfwhm = cpl_vector_new(ndet);
00270 printf("#index xPOS yPOS xFWHM yFWHM xgFWHM ygFWHM\n");
00271 int n, idx = 0;
00272 for (n = 1; n <= ndet; n++) {
00273 double xcen = cpl_apertures_get_centroid_x(apertures, n),
00274 ycen = cpl_apertures_get_centroid_y(apertures, n);
00275 if (xcen < 2 || nx - xcen < 2 || ycen < 2 || ny - ycen < 2) {
00276 fprintf(stderr, "#bad %4d %7.3f %7.3f too close to the edge\n",
00277 n, xcen, ycen);
00278 fflush(NULL);
00279 continue;
00280 }
00281
00282 double xfwhm, yfwhm;
00283 cpl_image_get_fwhm(image, lround(xcen), lround(ycen), &xfwhm, &yfwhm);
00284
00285
00286 cpl_array *params = cpl_array_new(7, CPL_TYPE_DOUBLE);
00287 cpl_array_set_double(params, 0, cpl_apertures_get_min(apertures, n));
00288 cpl_array_set_double(params, 1, cpl_apertures_get_flux(apertures, n));
00289 cpl_array_set_double(params, 2, 0);
00290 cpl_array_set_double(params, 3, xcen);
00291 cpl_array_set_double(params, 4, ycen);
00292 cpl_array_set_double(params, 5, xfwhm > 0 ? xfwhm / CPL_MATH_FWHM_SIG : 1.);
00293 cpl_array_set_double(params, 6, yfwhm > 0 ? yfwhm / CPL_MATH_FWHM_SIG : 1.);
00294 cpl_size xsize = cpl_apertures_get_right(apertures, n)
00295 - cpl_apertures_get_left(apertures, n) + 1,
00296 ysize = cpl_apertures_get_top(apertures, n)
00297 - cpl_apertures_get_bottom(apertures, n) + 1;
00298 xsize = xsize < 4 ? 4 : xsize;
00299 ysize = ysize < 4 ? 4 : ysize;
00300 cpl_error_code rc = cpl_fit_image_gaussian(image, NULL,
00301 cpl_apertures_get_pos_x(apertures, n),
00302 cpl_apertures_get_pos_y(apertures, n),
00303 xsize, ysize, params, NULL, NULL,
00304 NULL, NULL, NULL, NULL, NULL, NULL,
00305 NULL);
00306 double xgfwhm = cpl_array_get(params, 5, NULL) * CPL_MATH_FWHM_SIG,
00307 ygfwhm = cpl_array_get(params, 6, NULL) * CPL_MATH_FWHM_SIG;
00308 cpl_array_delete(params);
00309
00310 #define MAX_AXIS_RATIO 5.
00311 #define MAX_FWHM_RATIO 4.
00312 if (rc != CPL_ERROR_NONE || xgfwhm > nx || ygfwhm > ny ||
00313 fabs(xgfwhm/ygfwhm) > MAX_AXIS_RATIO || fabs(ygfwhm/xgfwhm) > MAX_AXIS_RATIO ||
00314 fabs(xgfwhm/xfwhm) > MAX_FWHM_RATIO || fabs(ygfwhm/yfwhm) > MAX_FWHM_RATIO ||
00315 fabs(xfwhm/xgfwhm) > MAX_FWHM_RATIO || fabs(yfwhm/ygfwhm) > MAX_FWHM_RATIO) {
00316 fprintf(stderr, "#bad %4d %7.3f %7.3f %5.2f %5.2f %5.2f %5.2f "
00317 "rc = %d: %s\n", n, xcen, ycen, xfwhm, yfwhm, xgfwhm, ygfwhm,
00318 rc, cpl_error_get_message());
00319 fflush(NULL);
00320 continue;
00321 }
00322
00323
00324 xfwhm = cd11 * xfwhm + cd12 * yfwhm;
00325 yfwhm = cd22 * yfwhm + cd21 * xfwhm;
00326 xgfwhm = cd11 * xgfwhm + cd12 * ygfwhm;
00327 ygfwhm = cd22 * ygfwhm + cd21 * xgfwhm;
00328 printf("%6d %7.3f %7.3f %5.2f %5.2f %5.2f %5.2f\n",
00329 n, xcen, ycen, xfwhm, yfwhm, xgfwhm, ygfwhm);
00330 fflush(stdout);
00331
00332 cpl_vector_set(vfwhm, idx, (xfwhm + yfwhm) / 2.);
00333 cpl_vector_set(vgfwhm, idx++, (xgfwhm + ygfwhm) / 2.);
00334 }
00335 cpl_apertures_delete(apertures);
00336 cpl_vector_set_size(vfwhm, idx);
00337 cpl_vector_set_size(vgfwhm, idx);
00338 printf("#Summary:\n#\tdirect FWHM %.3f +/- %.3f (%.3f) arcsec\n"
00339 "#\tGaussian FWHM %.3f +/- %.3f (%.3f) arcsec\n", cpl_vector_get_mean(vfwhm),
00340 cpl_vector_get_stdev(vfwhm), cpl_vector_get_median(vfwhm),
00341 cpl_vector_get_mean(vgfwhm), cpl_vector_get_stdev(vgfwhm),
00342 cpl_vector_get_median(vgfwhm));
00343 cpl_vector_delete(vfwhm);
00344 cpl_vector_delete(vgfwhm);
00345
00346 cpl_image_delete(image);
00347 cpl_end();
00348 return 0;
00349 }
00350