00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifdef HAVE_CONFIG_H
00031 #include <config.h>
00032 #endif
00033
00034 #include <math.h>
00035
00036 #include <cpl.h>
00037 #include <string.h>
00038
00039 #include "vircam_mods.h"
00040 #include "vircam_stats.h"
00041 #include "vircam_utils.h"
00042
00043 #define NX 2048
00044 #define NY 2048
00045 #define NGRIDMAX 31
00046
00047 static cpl_table *vircam_mkmstd_table(cpl_table *objtab, cpl_table *stdstab);
00048
00051
00099
00100
00101 extern int vircam_matchxy(cpl_table *progtab, cpl_table *template, float srad,
00102 float *xoffset, float *yoffset, int *nm,
00103 int *status) {
00104 cpl_propertylist *p;
00105 float *xprog,*yprog,*xtemp,*ytemp,aveden,errlim,xoffbest,yoffbest,xoff;
00106 float yoff,x,y,*xoffs,*yoffs;
00107 const char *fctid = "vircam_matchxy";
00108 int nprog,ntemp,ngrid,ngrid2,ibest,ig,jg,nmatch,k,jm;
00109
00110
00111
00112 *xoffset = 0.0;
00113 *yoffset = 0.0;
00114 *nm = 0;
00115 if (*status != VIR_OK)
00116 return(*status);
00117
00118
00119
00120 nprog = cpl_table_get_nrow(progtab);
00121 ntemp = cpl_table_get_nrow(template);
00122 if (nprog == 0) {
00123 cpl_msg_warning(fctid,"Program table has no rows");
00124 WARN_RETURN
00125 } else if (ntemp == 0) {
00126 cpl_msg_warning(fctid,"Template table has no rows");
00127 WARN_RETURN
00128 }
00129
00130
00131
00132 p = cpl_propertylist_new();
00133 cpl_propertylist_append_bool(p,"Y_coordinate",0);
00134 if (cpl_table_sort(progtab,p) != CPL_ERROR_NONE) {
00135 cpl_propertylist_delete(p);
00136 FATAL_ERROR
00137 }
00138 if (cpl_table_sort(template,p) != CPL_ERROR_NONE) {
00139 cpl_propertylist_delete(p);
00140 FATAL_ERROR
00141 }
00142 cpl_propertylist_delete(p);
00143
00144
00145
00146 xprog = cpl_table_get_data_float(progtab,"X_coordinate");
00147 yprog = cpl_table_get_data_float(progtab,"Y_coordinate");
00148 xtemp = cpl_table_get_data_float(template,"X_coordinate");
00149 ytemp = cpl_table_get_data_float(template,"Y_coordinate");
00150 if (xprog == NULL || yprog == NULL || xtemp == NULL || ytemp == NULL)
00151 FATAL_ERROR
00152
00153
00154
00155 aveden = (float)ntemp/(float)(NX*NY);
00156 errlim = 1.0/sqrt(4.0*M_PI*aveden);
00157 errlim = min(errlim,5.0);
00158 ngrid = (int)(srad/errlim);
00159 ngrid = (ngrid/2)*2 + 1;
00160 ngrid = max(5,min(NGRIDMAX,ngrid));
00161 ngrid2 = ngrid/2 + 1;
00162
00163
00164
00165 ibest = 0;
00166 xoffbest = 0.0;
00167 yoffbest = 0.0;
00168 for (ig = -ngrid2; ig <= ngrid2; ig++) {
00169 xoff = (float)ig*errlim*M_SQRT2;
00170 for (jg = -ngrid2; jg <= ngrid2; jg++) {
00171 yoff = (float)jg*errlim*M_SQRT2;
00172 nmatch = 0;
00173 for (k = 0; k < nprog; k++) {
00174 x = xprog[k] + xoff;
00175 y = yprog[k] + yoff;
00176 if (vircam_fndmatch(x,y,xtemp,ytemp,ntemp,errlim) > -1)
00177 nmatch++;
00178 }
00179 if (nmatch > ibest) {
00180 ibest = nmatch;
00181 xoffbest = xoff;
00182 yoffbest = yoff;
00183 }
00184 }
00185 }
00186
00187
00188
00189
00190 xoffs = cpl_malloc(nprog*sizeof(*xoffs));
00191 yoffs = cpl_malloc(nprog*sizeof(*yoffs));
00192
00193
00194
00195 nmatch = 0;
00196 for (k = 0; k < nprog; k++) {
00197 x = xprog[k] + xoffbest;
00198 y = yprog[k] + yoffbest;
00199 jm = vircam_fndmatch(x,y,xtemp,ytemp,ntemp,errlim);
00200 if (jm > -1) {
00201 xoffs[nmatch] = xtemp[jm] - xprog[k];
00202 yoffs[nmatch] = ytemp[jm] - yprog[k];
00203 nmatch++;
00204 }
00205 }
00206 if (nmatch > 0) {
00207 *xoffset = vircam_med(xoffs,NULL,nmatch);
00208 *yoffset = vircam_med(yoffs,NULL,nmatch);
00209 } else {
00210 *xoffset = 0.0;
00211 *yoffset = 0.0;
00212 }
00213 *nm = nmatch;
00214
00215
00216
00217 freespace(xoffs);
00218 freespace(yoffs);
00219 GOOD_STATUS
00220 }
00221
00222
00267
00268
00269 extern int vircam_matchstds(cpl_table *objtab, cpl_table *stdstab, float srad,
00270 cpl_table **outtab, int *status) {
00271 const char *fctid = "vircam_matchstds";
00272 char *colname;
00273 int nobj,nstd,ngrid,ngrid2,ibest,ig,jg,nmatch,k,*matches,jm,l,dont,null;
00274 float *xstd,*ystd,*xobj,*yobj,aveden,errlim,xoffbest,yoffbest,*xoffs;
00275 float *yoffs,x,y,x2,y2,r2,x1,y1,r1,xoffmed,sigx,yoffmed,sigy,xoff,yoff;
00276 cpl_propertylist *p;
00277 cpl_table *mstds;
00278
00279
00280
00281 *outtab = NULL;
00282 if (*status != VIR_OK)
00283 return(*status);
00284
00285
00286
00287 nobj = cpl_table_get_nrow(objtab);
00288 nstd = cpl_table_get_nrow(stdstab);
00289 if (nobj == 0) {
00290 cpl_msg_warning(fctid,"Object table has no rows");
00291 mstds = vircam_mkmstd_table(objtab,stdstab);
00292 *outtab = cpl_table_extract_selected(mstds);
00293 cpl_table_delete(mstds);
00294 WARN_RETURN
00295 } else if (nstd == 0) {
00296 cpl_msg_warning(fctid,"Standards RA/DEC table has no rows");
00297 mstds = vircam_mkmstd_table(objtab,stdstab);
00298 *outtab = cpl_table_extract_selected(mstds);
00299 cpl_table_delete(mstds);
00300 WARN_RETURN
00301 }
00302
00303
00304
00305 p = cpl_propertylist_new();
00306 cpl_propertylist_append_bool(p,"Y_coordinate",0);
00307 if (cpl_table_sort(objtab,p) != CPL_ERROR_NONE) {
00308 cpl_propertylist_delete(p);
00309 FATAL_ERROR
00310 }
00311 cpl_propertylist_erase(p,"Y_coordinate");
00312 cpl_propertylist_append_bool(p,"ypredict",0);
00313 if (cpl_table_sort(stdstab,p) != CPL_ERROR_NONE) {
00314 cpl_propertylist_delete(p);
00315 FATAL_ERROR
00316 }
00317 cpl_propertylist_delete(p);
00318
00319
00320
00321 xobj = cpl_table_get_data_float(objtab,"X_coordinate");
00322 yobj = cpl_table_get_data_float(objtab,"Y_coordinate");
00323 xstd = cpl_table_get_data_float(stdstab,"xpredict");
00324 ystd = cpl_table_get_data_float(stdstab,"ypredict");
00325 if (xstd == NULL || ystd == NULL || xobj == NULL || yobj == NULL)
00326 FATAL_ERROR
00327
00328
00329
00330 aveden = (float)nstd/(float)(NX*NY);
00331 errlim = 1.0/sqrt(4.0*M_PI*aveden);
00332 errlim = min(errlim,5.0);
00333 ngrid = (int)(srad/errlim);
00334 ngrid = (ngrid/2)*2 + 1;
00335 ngrid = max(5,min(NGRIDMAX,ngrid));
00336 ngrid2 = ngrid/2 + 1;
00337
00338
00339
00340 ibest = 0;
00341 xoffbest = 0.0;
00342 yoffbest = 0.0;
00343 for (ig = -ngrid2; ig <= ngrid2; ig++) {
00344 xoff = (float)ig*errlim*M_SQRT2;
00345 for (jg = -ngrid2; jg <= ngrid2; jg++) {
00346 yoff = (float)jg*errlim*M_SQRT2;
00347 nmatch = 0;
00348 for (k = 0; k < nobj; k++) {
00349 x = xobj[k] + xoff;
00350 y = yobj[k] + yoff;
00351 if (vircam_fndmatch(x,y,xstd,ystd,nstd,errlim) > -1)
00352 nmatch++;
00353 }
00354 if (nmatch > ibest) {
00355 ibest = nmatch;
00356 xoffbest = xoff;
00357 yoffbest = yoff;
00358 }
00359 }
00360 }
00361
00362
00363
00364
00365 xoffs = cpl_malloc(nstd*sizeof(*xoffs));
00366 yoffs = cpl_malloc(nstd*sizeof(*yoffs));
00367 matches = cpl_malloc(nstd*sizeof(*matches));
00368 for (k = 0; k < nstd; k++)
00369 matches[k] = -1;
00370
00371
00372
00373 nmatch = 0;
00374 for (k = 0; k < nstd; k++) {
00375 x = xstd[k] - xoffbest;
00376 y = ystd[k] - yoffbest;
00377 jm = vircam_fndmatch(x,y,xobj,yobj,nobj,errlim);
00378 if (jm > -1) {
00379 dont = 0;
00380 x2 = xobj[jm] - x;
00381 y2 = yobj[jm] - y;
00382 r2 = sqrt(x2*x2 + y2*y2);
00383 for (l = 0; l < nstd; l++) {
00384 if (matches[l] == jm) {
00385 x1 = xobj[jm] - (xstd[l] - xoffbest);
00386 y1 = yobj[jm] - (ystd[l] - yoffbest);
00387 r1 = sqrt(x1*x1 + y1*y1);
00388 if (r2 < r1)
00389 matches[l] = -1;
00390 else
00391 dont = 1;
00392 break;
00393 }
00394 }
00395 if (dont == 0)
00396 matches[k] = jm;
00397 }
00398 }
00399
00400
00401
00402 for (k = 0; k < nstd; k++) {
00403 jm = matches[k];
00404 if (jm != -1) {
00405 xoffs[nmatch] = xobj[jm] - xstd[k];
00406 yoffs[nmatch] = yobj[jm] - ystd[k];
00407 nmatch++;
00408 }
00409 }
00410 if (nmatch == 0) {
00411 xoffmed = 0.0;
00412 sigx = 1.0;
00413 yoffmed = 0.0;
00414 sigy = 1.0;
00415 } else {
00416 vircam_medmad(xoffs,NULL,nmatch,&xoffmed,&sigx);
00417 sigx *= 1.48;
00418 vircam_medmad(yoffs,NULL,nmatch,&yoffmed,&sigy);
00419 sigy *= 1.48;
00420 }
00421
00422
00423
00424
00425 errlim = 3.0*max(sigx,sigy);
00426 for (k = 0; k < nstd; k++)
00427 matches[k] = -1;
00428 for (k = 0; k < nstd; k++) {
00429 x = xstd[k] + xoffmed;
00430 y = ystd[k] + yoffmed;
00431 jm = vircam_fndmatch(x,y,xobj,yobj,nobj,errlim);
00432 if (jm > -1) {
00433 dont = 0;
00434 x2 = xobj[jm] - x;
00435 y2 = yobj[jm] - y;
00436 r2 = sqrt(x2*x2 + y2*y2);
00437 for (l = 0; l < nstd; l++) {
00438 if (matches[l] == jm) {
00439 x1 = xobj[jm] - (xstd[l] + xoffmed);
00440 y1 = yobj[jm] - (ystd[l] + yoffmed);
00441 r1 = sqrt(x1*x1 + y1*y1);
00442 if (r2 < r1)
00443 matches[l] = -1;
00444 else
00445 dont = 1;
00446
00447 }
00448 }
00449 if (dont == 0)
00450 matches[k] = jm;
00451 }
00452 }
00453 jm = matches[1];
00454
00455
00456
00457
00458
00459 mstds = cpl_table_duplicate(stdstab);
00460 colname = (char *)cpl_table_get_column_name(objtab);
00461 while (colname != NULL) {
00462 if (strcmp(colname,"RA") && strcmp(colname,"DEC"))
00463 cpl_table_new_column(mstds,colname,
00464 cpl_table_get_column_type(objtab,colname));
00465 colname = (char *)cpl_table_get_column_name(NULL);
00466 }
00467 cpl_table_unselect_all(mstds);
00468
00469
00470
00471 for (k = 0; k < nstd; k++) {
00472 jm = matches[k];
00473 if (jm != -1) {
00474 colname = (char *)cpl_table_get_column_name(objtab);
00475 while (colname != NULL) {
00476 if (!strcmp(colname,"RA") || !strcmp(colname,"DEC")) {
00477 colname = (char *)cpl_table_get_column_name(NULL);
00478 continue;
00479 }
00480 null = 0;
00481 switch (cpl_table_get_column_type(objtab,colname)) {
00482 case CPL_TYPE_INT:
00483 cpl_table_set_int(mstds,colname,k,
00484 cpl_table_get_int(objtab,colname,jm,
00485 &null));
00486 break;
00487 case CPL_TYPE_FLOAT:
00488 cpl_table_set_float(mstds,colname,k,
00489 cpl_table_get_float(objtab,colname,jm,
00490 &null));
00491 break;
00492 case CPL_TYPE_DOUBLE:
00493 cpl_table_set_double(mstds,colname,k,
00494 cpl_table_get_double(objtab,colname,
00495 jm,&null));
00496 break;
00497 default:
00498 cpl_table_set_float(mstds,colname,k,
00499 cpl_table_get_float(objtab,colname,jm,
00500 &null));
00501 break;
00502 }
00503 colname = (char *)cpl_table_get_column_name(NULL);
00504 }
00505 cpl_table_select_row(mstds,k);
00506 }
00507 }
00508
00509
00510
00511 *outtab = cpl_table_extract_selected(mstds);
00512 cpl_table_delete(mstds);
00513
00514
00515
00516 freespace(matches);
00517 freespace(xoffs);
00518 freespace(yoffs);
00519 GOOD_STATUS
00520 }
00521
00522
00542
00543
00544 static cpl_table *vircam_mkmstd_table(cpl_table *objtab, cpl_table *stdstab) {
00545 cpl_table *mstds;
00546 char *colname;
00547
00548
00549
00550 mstds = cpl_table_duplicate(stdstab);
00551
00552
00553
00554
00555 colname = (char *)cpl_table_get_column_name(objtab);
00556 while (colname != NULL) {
00557 if (strcmp(colname,"RA") && strcmp(colname,"DEC"))
00558 cpl_table_new_column(mstds,colname,
00559 cpl_table_get_column_type(objtab,colname));
00560 colname = (char *)cpl_table_get_column_name(NULL);
00561 }
00562 cpl_table_unselect_all(mstds);
00563
00564
00565
00566 return(mstds);
00567 }
00568
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615