41#include "eris_nix_casu_match.h"
50#include "casu_stats.h"
51#include "catalogue/casu_utils.h"
56#define NGRIDMAX_STD 31
58static cpl_table *casu_mkmstd_table(cpl_table *objtab, cpl_table *stdstab);
113int eris_nix_casu_matchstds(cpl_table *objtab, cpl_table *stdstab,
float srad,
114 float min_errlim, cpl_table **outtab,
116 const char *fctid =
"eris_casu_matchstds";
118 int nobj,nstd,ngrid,ngrid2,ibest,ig,jg,nmatch,k,*matches,jm,l,dont,null,k2;
119 float *xstd,*ystd,*xobj,*yobj,aveden,errlim,xoffbest,yoffbest,*xoffs;
120 float *yoffs,x,y,xx2,yy2,r2,xx1,yy1,r1,xoffmed,sigx,yoffmed,sigy,xoff,yoff;
128 if (*status != CASU_OK)
133 nobj = (int)cpl_table_get_nrow(objtab);
134 nstd = (int)cpl_table_get_nrow(stdstab);
136 cpl_msg_warning(fctid,
"Object table has no rows");
137 mstds = casu_mkmstd_table(objtab,stdstab);
138 *outtab = cpl_table_extract_selected(mstds);
139 cpl_table_delete(mstds);
141 }
else if (nstd == 0) {
142 cpl_msg_warning(fctid,
"Standards RA/DEC table has no rows");
143 mstds = casu_mkmstd_table(objtab,stdstab);
144 *outtab = cpl_table_extract_selected(mstds);
145 cpl_table_delete(mstds);
151 p = cpl_propertylist_new();
152 cpl_propertylist_append_bool(p,
"Y_coordinate",0);
153 if (cpl_table_sort(objtab,p) != CPL_ERROR_NONE) {
154 cpl_propertylist_delete(p);
157 cpl_propertylist_erase(p,
"Y_coordinate");
158 cpl_propertylist_append_bool(p,
"ypredict",0);
159 if (cpl_table_sort(stdstab,p) != CPL_ERROR_NONE) {
160 cpl_propertylist_delete(p);
163 cpl_propertylist_delete(p);
167 xobj = cpl_table_get_data_float(objtab,
"X_coordinate");
168 yobj = cpl_table_get_data_float(objtab,
"Y_coordinate");
169 xstd = cpl_table_get_data_float(stdstab,
"xpredict");
170 ystd = cpl_table_get_data_float(stdstab,
"ypredict");
171 if (xstd == NULL || ystd == NULL || xobj == NULL || yobj == NULL)
178 aveden = (float)max(nstd,nobj)/(float)(NX*NY);
180 errlim = 1.0/sqrt(4.0*CPL_MATH_PI*aveden);
194 cpl_msg_info(cpl_func,
"min_errlim %4.2f", min_errlim);
195 errlim = min(errlim,min_errlim);
197 ngrid = (int)(srad/errlim);
198 ngrid = (ngrid/2)*2 + 1;
200 ngrid = max(5,min(NGRIDMAX_STD,ngrid));
201 ngrid2 = ngrid/2 + 1;
203 cpl_msg_info(fctid,
"Search radius is %f pixels. Using a %d x %d grid, with error limit of %f", srad, ngrid, ngrid, errlim);
210 for (ig = -ngrid2; ig <= ngrid2; ig++) {
211 xoff = (float)ig*errlim*CPL_MATH_SQRT2;
212 for (jg = -ngrid2; jg <= ngrid2; jg++) {
213 yoff = (float)jg*errlim*CPL_MATH_SQRT2;
215 for (k = 0; k < nobj; k++) {
218 if (casu_fndmatch(x,y,xstd,ystd,nstd,errlim) > -1)
221 if (nmatch > ibest) {
232 xoffs = cpl_malloc(nstd*
sizeof(*xoffs));
233 yoffs = cpl_malloc(nstd*
sizeof(*yoffs));
234 matches = cpl_malloc(nstd*
sizeof(*matches));
235 for (k = 0; k < nstd; k++)
241 for (k = 0; k < nstd; k++) {
242 x = xstd[k] - xoffbest;
243 y = ystd[k] - yoffbest;
244 jm = casu_fndmatch(x,y,xobj,yobj,nobj,errlim);
249 r2 = sqrt(xx2*xx2 + yy2*yy2);
250 for (l = 0; l < nstd; l++) {
251 if (matches[l] == jm) {
252 xx1 = xobj[jm] - (xstd[l] - xoffbest);
253 yy1 = yobj[jm] - (ystd[l] - yoffbest);
254 r1 = sqrt(xx1*xx1 + yy1*yy1);
269 for (k = 0; k < nstd; k++) {
272 xoffs[nmatch] = xobj[jm] - xstd[k];
273 yoffs[nmatch] = yobj[jm] - ystd[k];
283 casu_medmad(xoffs,NULL,nmatch,&xoffmed,&sigx);
285 casu_medmad(yoffs,NULL,nmatch,&yoffmed,&sigy);
289 cpl_msg_info(fctid,
"Median offset x=%f y=%f, sigx=%f sigy=%f", xoffmed, yoffmed, sigx, sigy);
294 errlim = 3.0*max(sigx,sigy);
295 for (k = 0; k < nstd; k++)
297 for (k = 0; k < nstd; k++) {
298 x = xstd[k] + xoffmed;
299 y = ystd[k] + yoffmed;
300 jm = casu_fndmatch(x,y,xobj,yobj,nobj,errlim);
305 r2 = sqrt(xx2*xx2 + yy2*yy2);
306 for (l = 0; l < nstd; l++) {
307 if (matches[l] == jm) {
308 xx1 = xobj[jm] - (xstd[l] + xoffmed);
309 yy1 = yobj[jm] - (ystd[l] + yoffmed);
310 r1 = sqrt(xx1*xx1 + yy1*yy1);
328 mstds = cpl_table_duplicate(stdstab);
329 colnames = cpl_table_get_column_names(objtab);
330 ig = (int)cpl_array_get_size(colnames);
331 for (k = 0; k < ig; k++) {
332 colname = (
char *)cpl_array_get_string(colnames,(cpl_size)k);
333 if (strcasecmp(colname,
"RA") && strcasecmp(colname,
"DEC"))
334 cpl_table_new_column(mstds,colname,
335 cpl_table_get_column_type(objtab,colname));
337 cpl_table_unselect_all(mstds);
338 cpl_array_delete(colnames);
345 colnames = cpl_table_get_column_names(objtab);
346 ig = (int)cpl_array_get_size(colnames);
347 for (k = 0; k < nstd; k++) {
350 for (k2 = 0; k2 < ig; k2++) {
351 colname = (
char *)cpl_array_get_string(colnames,
353 if (!strcasecmp(colname,
"RA") || !strcasecmp(colname,
"DEC"))
356 switch (cpl_table_get_column_type(objtab,colname)) {
358 cpl_table_set_int(mstds,colname,(cpl_size)k,
359 cpl_table_get_int(objtab,colname,
360 (cpl_size)jm,&null));
363 cpl_table_set_float(mstds,colname,(cpl_size)k,
364 cpl_table_get_float(objtab,colname,
365 (cpl_size)jm,&null));
367 case CPL_TYPE_DOUBLE:
368 cpl_table_set_double(mstds,colname,(cpl_size)k,
369 cpl_table_get_double(objtab,colname,
370 (cpl_size)jm,&null));
372 case CPL_TYPE_STRING:
373 cpl_table_set_string(mstds,colname,(cpl_size)k,
374 cpl_table_get_string(objtab,colname,
378 cpl_msg_info(fctid,
"Ignoring column %s of type %d", colname, cpl_table_get_column_type(objtab,colname));
382 cpl_table_select_row(mstds,(cpl_size)k);
385 cpl_array_delete(colnames);
389 *outtab = cpl_table_extract_selected(mstds);
390 cpl_table_delete(mstds);
423static cpl_table *casu_mkmstd_table(cpl_table *objtab, cpl_table *stdstab) {
431 mstds = cpl_table_duplicate(stdstab);
436 colnames = cpl_table_get_column_names((
const cpl_table *)objtab);
437 ncol = cpl_array_get_size(colnames);
438 for (i = 0; i < ncol; i++) {
439 colname = (
char *)cpl_array_get_string(colnames,i);
440 if (strcmp(colname,
"RA") && strcmp(colname,
"DEC"))
441 cpl_table_new_column(mstds,colname,
442 cpl_table_get_column_type(objtab,colname));
444 cpl_array_delete(colnames);
445 cpl_table_unselect_all(mstds);