65 static cpl_apertures *
66 image_fwhm_cplapertures_extract(cpl_image *aImage, cpl_vector *aSigmas,
69 cpl_ensure(aImage && aSigmas, CPL_ERROR_NULL_INPUT, NULL);
70 cpl_apertures *aperts = NULL;
71 cpl_errorstate prestate = cpl_errorstate_get();
72 cpl_size i, n = cpl_vector_get_size(aSigmas);
73 for (i = 0; i < n; i++) {
74 const double sigma = cpl_vector_get(aSigmas, i);
80 double mdev, median = cpl_image_get_median_dev(aImage, &mdev),
81 threshold = median + sigma * mdev;
83 cpl_mask *selection = cpl_mask_threshold_image_create(aImage, threshold,
86 cpl_image *labels = cpl_image_labelise_mask_create(selection, &nlabels);
87 cpl_mask_delete(selection);
89 aperts = cpl_apertures_new_from_image(aImage, labels);
90 cpl_image_delete(labels);
96 cpl_ensure(aperts, CPL_ERROR_DATA_NOT_FOUND, NULL);
98 cpl_errorstate_set(prestate);
105 #define PRINT_USAGE(rc) \
106 fprintf(stderr, "Usage: %s [ -s sigma ] [ -x extindex | -n extname] " \
107 "IMAGE\n", argv[0]); \
108 cpl_end(); return (rc);
110 int main(
int argc,
char **argv)
112 cpl_init(CPL_INIT_DEFAULT);
126 for (i = 1; i < argc; i++) {
127 if (strncmp(argv[i],
"-s", 3) == 0) {
131 sigma = atof(argv[i]);
138 }
else if (strncmp(argv[i],
"-x", 3) == 0) {
142 iext = atoi(argv[i]);
149 }
else if (strncmp(argv[i],
"-n", 3) == 0) {
157 }
else if (strncmp(argv[i],
"-", 1) == 0) {
166 if (extname && iext >= 0) {
170 int next = cpl_fits_count_extensions(iname);
175 iext = cpl_fits_find_extension(iname, extname);
177 cpl_image *image = NULL;
179 image = cpl_image_load(iname, CPL_TYPE_UNSPECIFIED, 0, iext);
181 cpl_errorstate ps = cpl_errorstate_get();
183 image = cpl_image_load(iname, CPL_TYPE_UNSPECIFIED, 0, ++iext);
184 }
while (!image && iext <= next);
185 cpl_errorstate_set(ps);
190 cpl_propertylist *header = cpl_propertylist_load(iname, iext);
191 int nx = cpl_image_get_size_x(image),
192 ny = cpl_image_get_size_y(image);
193 char *extdisp = NULL;
194 if (cpl_propertylist_has(header,
"EXTNAME")) {
195 extdisp = cpl_strdup(cpl_propertylist_get_string(header,
"EXTNAME"));
197 extdisp = cpl_sprintf(
"%d", iext);
200 cpl_image_reject_value(image, CPL_VALUE_NAN);
201 int nrej = cpl_image_count_rejected(image);
202 printf(
"# Input image \"%s[%s]\" (size %dx%d, rejected %d)\n", iname, extdisp,
206 cpl_vector *vsigmas = NULL;
208 vsigmas = cpl_vector_new(1);
209 cpl_vector_set(vsigmas, 0, sigma);
211 vsigmas = cpl_vector_new(6);
212 cpl_vector_set(vsigmas, 0, 50.);
213 cpl_vector_set(vsigmas, 1, 30.);
214 cpl_vector_set(vsigmas, 2, 20.);
215 cpl_vector_set(vsigmas, 3, 10.);
216 cpl_vector_set(vsigmas, 4, 8.);
217 cpl_vector_set(vsigmas, 5, 5.);
219 cpl_size isigma = -1;
220 cpl_errorstate prestate = cpl_errorstate_get();
221 cpl_apertures *apertures = image_fwhm_cplapertures_extract(image, vsigmas, &isigma);
222 if (!apertures || !cpl_errorstate_is_equal(prestate)) {
223 cpl_image_delete(image);
224 fprintf(stderr,
"%s: no sources found for FWHM measurement down to %.1f "
225 "sigma limit!\n", argv[0],
226 cpl_vector_get(vsigmas, cpl_vector_get_size(vsigmas) - 1));
227 cpl_vector_delete(vsigmas);
230 int ndet = cpl_apertures_get_size(apertures);
231 printf(
"# %s: computing FWHM QC parameters for %d source%s found down to the "
232 "%.1f sigma threshold\n", argv[0], ndet, ndet == 1 ?
"" :
"s",
233 cpl_vector_get(vsigmas, isigma));
234 cpl_vector_delete(vsigmas);
238 double cd11 = kMuseSpaxelSizeX_WFM, cd12 = 0., cd21 = 0.,
239 cd22 = kMuseSpaxelSizeY_WFM;
240 cpl_wcs *wcs = cpl_wcs_new_from_propertylist(header);
242 !strncasecmp(cpl_propertylist_get_string(header,
"CTYPE1"),
"PIXEL", 5)) {
243 printf(
"# %s: FWHM parameter estimation (%d sources): simple conversion "
244 "to arcsec (CTYPE=%s/%s)!\n", argv[0], ndet,
245 cpl_propertylist_get_string(header,
"CTYPE1"),
246 cpl_propertylist_get_string(header,
"CTYPE2"));
248 cd11 = kMuseSpaxelSizeX_WFM;
249 cd22 = kMuseSpaxelSizeY_WFM;
252 const cpl_matrix *cd = cpl_wcs_get_cd(wcs);
254 cd11 = fabs(cpl_matrix_get(cd, 0, 0)) * 3600.,
255 cd12 = fabs(cpl_matrix_get(cd, 0, 1)) * 3600.,
256 cd21 = fabs(cpl_matrix_get(cd, 1, 0)) * 3600.,
257 cd22 = fabs(cpl_matrix_get(cd, 1, 1)) * 3600.;
258 printf(
"# %s: FWHM parameter estimation (%d sources): full "
259 "conversion to arcsec (CD=%.2f,%.2f,%.2f,%.2f)\n", argv[0], ndet,
260 cd11, cd12, cd21, cd22);
265 cpl_vector *vfwhm = cpl_vector_new(ndet),
266 *vgfwhm = cpl_vector_new(ndet);
267 printf(
"#index xPOS yPOS xFWHM yFWHM xgFWHM ygFWHM\n");
269 for (n = 1; n <= ndet; n++) {
270 double xcen = cpl_apertures_get_centroid_x(apertures, n),
271 ycen = cpl_apertures_get_centroid_y(apertures, n);
272 if (xcen < 2 || nx - xcen < 2 || ycen < 2 || ny - ycen < 2) {
273 fprintf(stderr,
"#bad %4d %7.3f %7.3f too close to the edge\n",
280 cpl_image_get_fwhm(image, lround(xcen), lround(ycen), &xfwhm, &yfwhm);
283 cpl_array *params = cpl_array_new(7, CPL_TYPE_DOUBLE);
284 cpl_array_set_double(params, 0, cpl_apertures_get_min(apertures, n));
285 cpl_array_set_double(params, 1, cpl_apertures_get_flux(apertures, n));
286 cpl_array_set_double(params, 2, 0);
287 cpl_array_set_double(params, 3, xcen);
288 cpl_array_set_double(params, 4, ycen);
289 cpl_array_set_double(params, 5, xfwhm > 0 ? xfwhm / CPL_MATH_FWHM_SIG : 1.);
290 cpl_array_set_double(params, 6, yfwhm > 0 ? yfwhm / CPL_MATH_FWHM_SIG : 1.);
291 cpl_size xsize = cpl_apertures_get_right(apertures, n)
292 - cpl_apertures_get_left(apertures, n) + 1,
293 ysize = cpl_apertures_get_top(apertures, n)
294 - cpl_apertures_get_bottom(apertures, n) + 1;
295 xsize = xsize < 4 ? 4 : xsize;
296 ysize = ysize < 4 ? 4 : ysize;
297 cpl_error_code rc = cpl_fit_image_gaussian(image, NULL,
298 cpl_apertures_get_pos_x(apertures, n),
299 cpl_apertures_get_pos_y(apertures, n),
300 xsize, ysize, params, NULL, NULL,
301 NULL, NULL, NULL, NULL, NULL, NULL,
303 double xgfwhm = cpl_array_get(params, 5, NULL) * CPL_MATH_FWHM_SIG,
304 ygfwhm = cpl_array_get(params, 6, NULL) * CPL_MATH_FWHM_SIG;
305 cpl_array_delete(params);
307 #define MAX_AXIS_RATIO 5.
308 #define MAX_FWHM_RATIO 4.
309 if (rc != CPL_ERROR_NONE || xgfwhm > nx || ygfwhm > ny ||
310 fabs(xgfwhm/ygfwhm) > MAX_AXIS_RATIO || fabs(ygfwhm/xgfwhm) > MAX_AXIS_RATIO ||
311 fabs(xgfwhm/xfwhm) > MAX_FWHM_RATIO || fabs(ygfwhm/yfwhm) > MAX_FWHM_RATIO ||
312 fabs(xfwhm/xgfwhm) > MAX_FWHM_RATIO || fabs(yfwhm/ygfwhm) > MAX_FWHM_RATIO) {
313 fprintf(stderr,
"#bad %4d %7.3f %7.3f %5.2f %5.2f %5.2f %5.2f "
314 "rc = %d: %s\n", n, xcen, ycen, xfwhm, yfwhm, xgfwhm, ygfwhm,
315 rc, cpl_error_get_message());
321 xfwhm = cd11 * xfwhm + cd12 * yfwhm;
322 yfwhm = cd22 * yfwhm + cd21 * xfwhm;
323 xgfwhm = cd11 * xgfwhm + cd12 * ygfwhm;
324 ygfwhm = cd22 * ygfwhm + cd21 * xgfwhm;
325 printf(
"%6d %7.3f %7.3f %5.2f %5.2f %5.2f %5.2f\n",
326 n, xcen, ycen, xfwhm, yfwhm, xgfwhm, ygfwhm);
329 cpl_vector_set(vfwhm, idx, (xfwhm + yfwhm) / 2.);
330 cpl_vector_set(vgfwhm, idx++, (xgfwhm + ygfwhm) / 2.);
332 cpl_apertures_delete(apertures);
333 cpl_vector_set_size(vfwhm, idx);
334 cpl_vector_set_size(vgfwhm, idx);
335 printf(
"#Summary:\n#\tdirect FWHM %.3f +/- %.3f (%.3f) arcsec\n"
336 "#\tGaussian FWHM %.3f +/- %.3f (%.3f) arcsec\n", cpl_vector_get_mean(vfwhm),
337 cpl_vector_get_stdev(vfwhm), cpl_vector_get_median(vfwhm),
338 cpl_vector_get_mean(vgfwhm), cpl_vector_get_stdev(vgfwhm),
339 cpl_vector_get_median(vgfwhm));
340 cpl_vector_delete(vfwhm);
341 cpl_vector_delete(vgfwhm);
343 cpl_image_delete(image);
muse_ins_mode muse_pfits_get_mode(const cpl_propertylist *aHeaders)
find out the observation mode