22#include "hdrl_cat_conf.h"
24#include "hdrl_cat_apio.h"
25#include "hdrl_cat_apline.h"
26#include "hdrl_cat_table.h"
27#include "hdrl_cat_background.h"
28#include "hdrl_cat_terminate.h"
33#define STUPID_VALUE -1000
38static double *g_smoothed = NULL;
39static double *g_smoothedc = NULL;
40static unsigned char *g_mflag = NULL;
41static double *g_indata = NULL;
42static double *g_confdata = NULL;
43static double *g_confsqrt = NULL;
46static cpl_size g_freeconf = 0;
48static double g_weights[NW*NW];
55static void crweights(
double filtfwhm);
56static void convolve( cpl_size ir );
57static void clean_up( cpl_table *tab );
113 hdrl_casu_fits *infile, hdrl_casu_fits *conf, cpl_size ipix,
114 double threshold, cpl_size icrowd,
double rcore,
115 cpl_size bkg_subtr, cpl_size nbsize,
116 cpl_size cattype,
double filtfwhm,
double gain,
117 double saturation, hdrl_casu_result *res)
120 res->catalogue = NULL;
123 double fconst = CPL_MATH_LOG2E;
124 cpl_size nobjects = 0;
127 cpl_table *tab = NULL;
130 if ((g_indata = cpl_image_get_data_double(map)) == NULL) {
132 cpl_error_set_message(cpl_func, CPL_ERROR_NULL_INPUT,
133 "hdrl_cat_catalogue_conf - Error getting image data");
134 return CPL_ERROR_NULL_INPUT;
137 g_nx = cpl_image_get_size_x(map);
138 g_ny = cpl_image_get_size_y(map);
140 cpl_size npts = g_nx * g_ny;
141 cpl_size npix = g_nx * g_ny;
148 if ((g_confdata = cpl_image_get_data(cmap)) == NULL) {
150 cpl_error_set_message(cpl_func, CPL_ERROR_NULL_INPUT,
151 "hdrl_cat_catalogue_conf - Error getting confidence map data");
152 return CPL_ERROR_NULL_INPUT;
155 cpl_size nxc = cpl_image_get_size_x(cmap);
156 cpl_size nyc = cpl_image_get_size_y(cmap);
157 if ((g_nx != nxc) || (g_ny != nyc)) {
159 cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT,
160 "hdrl_cat_catalogue_conf - Input image and confidence dimensions don't match");
161 return CPL_ERROR_INCOMPATIBLE_INPUT;
166 g_confdata = cpl_malloc(npts *
sizeof(*g_confdata));
167 for (cpl_size i = 0; i < npts; i++) {
175 g_mflag = cpl_calloc(npix,
sizeof(*g_mflag));
181 g_ap.conframe = cmap;
185 g_ap.indata = g_indata;
186 g_ap.confdata = g_confdata;
189 g_ap.mflag = g_mflag;
191 g_ap.filtfwhm = filtfwhm;
192 g_ap.icrowd = icrowd;
193 g_ap.fconst = fconst;
198 hdrl_tabinit(&g_ap, &hdrl_xcol, &hdrl_ycol, cattype, &tab, res);
201 for (cpl_size i = 0; i < npix; i++) {
202 if (g_confdata[i] == 0) {
203 g_mflag[i] = MF_ZEROCONF;
204 }
else if (g_indata[i] < STUPID_VALUE) {
205 g_mflag[i] = MF_STUPID_VALUE;
207 g_mflag[i] = MF_CLEANPIX;
212 for (cpl_size i = 0; i < npix ; i++) {
213 if (g_mflag[i] == MF_CLEANPIX && g_indata[i] > saturation) {
214 g_mflag[i] = MF_SATURATED;
219 if (
hdrl_background(&g_ap, nbsize, bkg_subtr, res) != CPL_ERROR_NONE) {
221 return cpl_error_get_code();
229 return cpl_error_get_code();
234 for (cpl_size i = 0; i < g_nx * g_ny; i++) {
235 g_indata[i] -= skymed;
240 double thresh = threshold * skysig;
241 if (!bkg_subtr && thresh < skymed) {
243 cpl_error_set_message(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT,
244 "Bad background corrected input. Background estimation disabled "
245 "but image median larger than threshold * sigma.");
246 return CPL_ERROR_INCOMPATIBLE_INPUT;
250 double xintmin = 1.5 * thresh * (double)ipix;
253 double offset = log(thresh)*fconst;
256 g_smoothed = cpl_malloc(g_nx *
sizeof(*g_smoothed));
257 g_smoothedc = cpl_malloc(g_nx *
sizeof(*g_smoothedc));
260 cpl_size mulpix = CPL_MAX(8, 2 * ipix);
263 g_ap.mulpix = mulpix;
264 g_ap.areal_offset = offset;
265 g_ap.thresh = thresh;
266 g_ap.xintmin = xintmin;
270 g_ap.background = skymed;
271 g_ap.saturation = saturation - skymed;
273 g_ap.background = 0.;
274 g_ap.saturation = saturation;
279 cpl_size nw2 = NW / 2;
282 g_confsqrt = cpl_malloc(g_nx * NW *
sizeof(*g_confsqrt));
283 for (cpl_size j = 0; j < NW; j++) {
284 for (cpl_size i = 0; i < g_nx; i++) {
285 g_confsqrt[j * g_nx + i] = sqrt(0.01 * (
double)(g_confdata[j * g_nx + i]));
290 for (cpl_size j = nw2; j < g_ny-nw2; j++) {
292 double *current = g_indata + j * g_nx;
297 memmove(g_confsqrt, g_confsqrt + g_nx, g_nx * (NW - 1) *
sizeof(*g_confsqrt));
300 for (cpl_size i = 0; i < g_nx; i++) {
301 g_confsqrt[(NW - 1) * g_nx + i] = sqrt(0.01 * (
double)(g_confdata[(j + nw2) * g_nx + i]));
306 double *currentc = g_confsqrt + nw2 * g_nx;
310 hdrl_apline(&g_ap, current, currentc, g_smoothed, g_smoothedc, j, NULL);
313 if (g_ap.ibstack > g_ap.maxbl - g_ap.lsiz)
hdrl_apfu(&g_ap);
314 if (g_ap.ipstack > g_ap.maxpa * 3 / 4 )
hdrl_apfu(&g_ap);
317 if (g_ap.ipstack > 1) {
323 cpl_table_set_size(tab, nobjects);
327 return cpl_error_get_code();
335 cpl_propertylist_update_double(extra,
"ESO QC SATURATION", g_ap.saturation);
336 cpl_propertylist_update_double(extra,
"ESO QC MEAN_SKY", g_ap.background);
337 cpl_propertylist_update_double(extra,
"ESO QC SKY_NOISE", g_ap.sigma);
339 cpl_propertylist_set_comment( extra,
"ESO QC SATURATION",
"[adu] Saturation level");
340 cpl_propertylist_set_comment( extra,
"ESO QC MEAN_SKY",
"[adu] Median sky brightness");
341 cpl_propertylist_set_comment( extra,
"ESO QC SKY_NOISE",
"[adu] Pixel noise at sky level");
345 cpl_propertylist_update_double(extra,
"ESO DRS THRESHOL", g_ap.thresh);
346 cpl_propertylist_update_int( extra,
"ESO DRS MINPIX", g_ap.ipnop);
347 cpl_propertylist_update_int( extra,
"ESO DRS CROWDED", g_ap.icrowd);
348 cpl_propertylist_update_double(extra,
"ESO DRS RCORE", g_ap.rcore);
349 cpl_propertylist_update_double(extra,
"ESO DRS SEEING", g_ap.fwhm);
350 cpl_propertylist_update_double(extra,
"ESO DRS FILTFWHM", g_ap.filtfwhm);
351 cpl_propertylist_update_int( extra,
"ESO DRS XCOL", hdrl_xcol);
352 cpl_propertylist_update_int( extra,
"ESO DRS YCOL", hdrl_ycol);
353 cpl_propertylist_update_int( extra,
"ESO DRS NXOUT", g_nx);
354 cpl_propertylist_update_int( extra,
"ESO DRS NYOUT", g_ny);
356 cpl_propertylist_set_comment( extra,
"ESO DRS THRESHOL",
"[adu] Isophotal analysis threshold");
357 cpl_propertylist_set_comment( extra,
"ESO DRS MINPIX",
"[pixels] Minimum size for images");
358 cpl_propertylist_set_comment( extra,
"ESO DRS CROWDED",
"Crowded field analysis flag");
359 cpl_propertylist_set_comment( extra,
"ESO DRS RCORE",
"[pixels] Core radius for default profile fit");
360 cpl_propertylist_set_comment( extra,
"ESO DRS SEEING",
"[pixels] Average FWHM");
361 cpl_propertylist_set_comment( extra,
"ESO DRS FILTFWHM",
"[pixels] FWHM of smoothing kernel");
362 cpl_propertylist_set_comment( extra,
"ESO DRS XCOL",
"Column for X position");
363 cpl_propertylist_set_comment( extra,
"ESO DRS YCOL",
"Column for Y position");
364 cpl_propertylist_set_comment( extra,
"ESO DRS NXOUT",
"X Dimension of input image");
365 cpl_propertylist_set_comment( extra,
"ESO DRS NYOUT",
"Y Dimension of input image");
372 return CPL_ERROR_NONE;
387static void crweights(
double filtfwhm)
390 cpl_size nw2 = NW / 2;
393 double gsigsq = 1. / (2. * pow(CPL_MAX(1., (
double)filtfwhm) / 2.35, 2.));
398 for (cpl_size i = -nw2; i <= nw2; i++) {
400 double di = (double)i;
403 for (cpl_size j = -nw2; j <= nw2; j++) {
405 double dj = (double)j;
410 g_weights[n] = exp(-(di + dj));
412 renorm += g_weights[n];
418 for (cpl_size i = -nw2; i <= nw2; i++) {
419 for (cpl_size j = -nw2; j <= nw2; j++) {
423 g_weights[nn] /= renorm;
438static void convolve(cpl_size ir)
441 for (cpl_size i = 0; i < g_nx; i++) {
448 cpl_size nw2 = NW / 2;
451 for (cpl_size ix = nw2; ix < g_nx - nw2; ix++) {
458 for (cpl_size jy = ir - nw2; jy <= ir + nw2; jy++) {
461 double *cdata = g_confsqrt + (jy - ir + nw2) * g_nx;
462 double *idata = g_indata + jy * g_nx;
464 for (cpl_size jx = ix - nw2; jx <= ix + nw2; jx++) {
468 sum += g_weights[n] * idata[jx];
469 sumc += g_weights[n] * idata[jx] * cdata[jx];
473 g_smoothed[ix] = sum;
474 g_smoothedc[ix] = sumc;
486static void clean_up(cpl_table *tab) {
488 if (tab) cpl_table_delete(tab);
491 if (g_confdata) {cpl_free(g_confdata); g_confdata = NULL;}
494 if (g_confsqrt ) {cpl_free(g_confsqrt); g_confsqrt = NULL;}
495 if (g_smoothed ) {cpl_free(g_smoothed); g_smoothed = NULL;}
496 if (g_smoothedc) {cpl_free(g_smoothedc); g_smoothedc = NULL;}
497 if (g_mflag ) {cpl_free(g_mflag); g_mflag = NULL;}
cpl_error_code hdrl_catalogue_conf(hdrl_casu_fits *infile, hdrl_casu_fits *conf, cpl_size ipix, double threshold, cpl_size icrowd, double rcore, cpl_size bkg_subtr, cpl_size nbsize, cpl_size cattype, double filtfwhm, double gain, double saturation, hdrl_casu_result *res)
Do source extraction.
void hdrl_apinit(ap_t *ap)
Initialize the ap structure.
void hdrl_apclose(ap_t *ap)
Close ap structure.
void hdrl_apline(ap_t *ap, double dat[], double conf[], double smoothed[], double smoothedc[], cpl_size j, unsigned char *bpm)
Detect objects on a line of data.
cpl_error_code hdrl_background(ap_t *ap, cpl_size nbsize, cpl_size bkg_subtr, hdrl_casu_result *res)
Model and create background map.
cpl_error_code hdrl_backstats(ap_t *ap, double *skymed, double *skysig)
Work out robust background estimate over a whole input image.
cpl_image * hdrl_casu_fits_get_image(hdrl_casu_fits *p)
Get the CPL image from the hdrl_casu_fits object.
hdrl_casu_tfits * hdrl_casu_tfits_wrap(cpl_table *tab, cpl_propertylist *ehu)
Wrap an table in a hdrl_casu_tfits wrapper.
cpl_propertylist * hdrl_casu_fits_get_ehu(hdrl_casu_fits *p)
Get the propertylist for the extension header for a given hdrl_casu_fits image.
cpl_error_code hdrl_do_seeing(ap_t *ap, cpl_size nobjects, cpl_table *tab)
Do seeing estimate.
cpl_error_code hdrl_tabinit(ap_t *ap, cpl_size *xcol, cpl_size *ycol, hdrl_catalogue_options cattype, cpl_table **tab, hdrl_casu_result *res)
Initialize catalogues.
void hdrl_apfu(ap_t *ap)
Get rid of the largest contributor in an ap structure.
void hdrl_terminate(ap_t *ap, double gain, cpl_size *nobjects, cpl_table *tab, hdrl_casu_result *res)
Check for objects that have terminated.