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_XY 61
00046 #define NGRIDMAX_STD 31
00047
00048 static cpl_table *vircam_mkmstd_table(cpl_table *objtab, cpl_table *stdstab);
00049
00052
00102
00103
00104 extern int vircam_matchxy(cpl_table *progtab, cpl_table *template, float srad,
00105 float *xoffset, float *yoffset, int *nm,
00106 cpl_table **outtab, int *status) {
00107 cpl_propertylist *p;
00108 float *xprog,*yprog,*xtemp,*ytemp,aveden,errlim,xoffbest,yoffbest,xoff;
00109 float yoff,x,y,*xoffs,*yoffs;
00110 const char *fctid = "vircam_matchxy";
00111 int nprog,ntemp,ngrid,ngrid2,ibest,ig,jg,nmatch,k,jm;
00112
00113
00114
00115 *xoffset = 0.0;
00116 *yoffset = 0.0;
00117 *nm = 0;
00118 *outtab = NULL;
00119 if (*status != VIR_OK)
00120 return(*status);
00121
00122
00123
00124 nprog = cpl_table_get_nrow(progtab);
00125 ntemp = cpl_table_get_nrow(template);
00126 if (nprog == 0) {
00127 cpl_msg_warning(fctid,"Program table has no rows");
00128 WARN_RETURN
00129 } else if (ntemp == 0) {
00130 cpl_msg_warning(fctid,"Template table has no rows");
00131 WARN_RETURN
00132 }
00133
00134
00135
00136 p = cpl_propertylist_new();
00137 cpl_propertylist_append_bool(p,"Y_coordinate",0);
00138 if (cpl_table_sort(progtab,p) != CPL_ERROR_NONE) {
00139 cpl_propertylist_delete(p);
00140 FATAL_ERROR
00141 }
00142 if (cpl_table_sort(template,p) != CPL_ERROR_NONE) {
00143 cpl_propertylist_delete(p);
00144 FATAL_ERROR
00145 }
00146 cpl_propertylist_delete(p);
00147
00148
00149
00150 xprog = cpl_table_get_data_float(progtab,"X_coordinate");
00151 yprog = cpl_table_get_data_float(progtab,"Y_coordinate");
00152 xtemp = cpl_table_get_data_float(template,"X_coordinate");
00153 ytemp = cpl_table_get_data_float(template,"Y_coordinate");
00154 if (xprog == NULL || yprog == NULL || xtemp == NULL || ytemp == NULL)
00155 FATAL_ERROR
00156
00157
00158
00159 aveden = (float)ntemp/(float)(NX*NY);
00160 errlim = 1.0/sqrt(4.0*CPL_MATH_PI*aveden);
00161 errlim = min(errlim,15.0);
00162 ngrid = (int)(srad/errlim);
00163 ngrid = (ngrid/2)*2 + 1;
00164 ngrid = max(5,min(NGRIDMAX_XY,ngrid));
00165 ngrid2 = ngrid/2 + 1;
00166
00167
00168
00169 ibest = 0;
00170 xoffbest = 0.0;
00171 yoffbest = 0.0;
00172 for (ig = -ngrid2; ig <= ngrid2; ig++) {
00173 xoff = (float)ig*errlim*CPL_MATH_SQRT2;
00174 for (jg = -ngrid2; jg <= ngrid2; jg++) {
00175 yoff = (float)jg*errlim*CPL_MATH_SQRT2;
00176 nmatch = 0;
00177 for (k = 0; k < nprog; k++) {
00178 x = xprog[k] + xoff;
00179 y = yprog[k] + yoff;
00180 if (vircam_fndmatch(x,y,xtemp,ytemp,ntemp,errlim) > -1)
00181 nmatch++;
00182 }
00183 if (nmatch > ibest) {
00184 ibest = nmatch;
00185 xoffbest = xoff;
00186 yoffbest = yoff;
00187 }
00188 }
00189 }
00190
00191
00192
00193
00194 xoffs = cpl_malloc(nprog*sizeof(*xoffs));
00195 yoffs = cpl_malloc(nprog*sizeof(*yoffs));
00196
00197
00198
00199 nmatch = 0;
00200 for (k = 0; k < nprog; k++) {
00201 x = xprog[k] + xoffbest;
00202 y = yprog[k] + yoffbest;
00203 jm = vircam_fndmatch(x,y,xtemp,ytemp,ntemp,errlim);
00204 if (jm > -1) {
00205 xoffs[nmatch] = xtemp[jm] - xprog[k];
00206 yoffs[nmatch] = ytemp[jm] - yprog[k];
00207 nmatch++;
00208 }
00209 }
00210 if (nmatch > 0) {
00211 *xoffset = vircam_med(xoffs,NULL,nmatch);
00212 *yoffset = vircam_med(yoffs,NULL,nmatch);
00213 } else {
00214 *xoffset = 0.0;
00215 *yoffset = 0.0;
00216 }
00217 *nm = nmatch;
00218
00219
00220
00221 *outtab = cpl_table_new(nprog);
00222 cpl_table_new_column(*outtab,"X_coordinate_1",CPL_TYPE_FLOAT);
00223 cpl_table_new_column(*outtab,"Y_coordinate_1",CPL_TYPE_FLOAT);
00224 cpl_table_new_column(*outtab,"X_coordinate_2",CPL_TYPE_FLOAT);
00225 cpl_table_new_column(*outtab,"Y_coordinate_2",CPL_TYPE_FLOAT);
00226 nmatch = 0;
00227 for (k = 0; k < nprog; k++) {
00228 x = xprog[k] + *xoffset;
00229 y = yprog[k] + *yoffset;
00230 jm = vircam_fndmatch(x,y,xtemp,ytemp,ntemp,1.0);
00231 if (jm > -1) {
00232 cpl_table_set_float(*outtab,"X_coordinate_1",nmatch,xtemp[jm]);
00233 cpl_table_set_float(*outtab,"Y_coordinate_1",nmatch,ytemp[jm]);
00234 cpl_table_set_float(*outtab,"X_coordinate_2",nmatch,xprog[k]);
00235 cpl_table_set_float(*outtab,"Y_coordinate_2",nmatch,yprog[k]);
00236 nmatch++;
00237 }
00238 }
00239 cpl_table_set_size(*outtab,nmatch);
00240
00241
00242
00243 freespace(xoffs);
00244 freespace(yoffs);
00245 GOOD_STATUS
00246 }
00247
00248
00293
00294
00295 extern int vircam_matchstds(cpl_table *objtab, cpl_table *stdstab, float srad,
00296 cpl_table **outtab, int *status) {
00297 const char *fctid = "vircam_matchstds";
00298 char *colname;
00299 int nobj,nstd,ngrid,ngrid2,ibest,ig,jg,nmatch,k,*matches,jm,l,dont,null;
00300 float *xstd,*ystd,*xobj,*yobj,aveden,errlim,xoffbest,yoffbest,*xoffs;
00301 float *yoffs,x,y,xx2,yy2,r2,xx1,yy1,r1,xoffmed,sigx,yoffmed,sigy,xoff,yoff;
00302 cpl_propertylist *p;
00303 cpl_table *mstds;
00304
00305
00306
00307 *outtab = NULL;
00308 if (*status != VIR_OK)
00309 return(*status);
00310
00311
00312
00313 nobj = cpl_table_get_nrow(objtab);
00314 nstd = cpl_table_get_nrow(stdstab);
00315 if (nobj == 0) {
00316 cpl_msg_warning(fctid,"Object table has no rows");
00317 mstds = vircam_mkmstd_table(objtab,stdstab);
00318 *outtab = cpl_table_extract_selected(mstds);
00319 cpl_table_delete(mstds);
00320 WARN_RETURN
00321 } else if (nstd == 0) {
00322 cpl_msg_warning(fctid,"Standards RA/DEC table has no rows");
00323 mstds = vircam_mkmstd_table(objtab,stdstab);
00324 *outtab = cpl_table_extract_selected(mstds);
00325 cpl_table_delete(mstds);
00326 WARN_RETURN
00327 }
00328
00329
00330
00331 p = cpl_propertylist_new();
00332 cpl_propertylist_append_bool(p,"Y_coordinate",0);
00333 if (cpl_table_sort(objtab,p) != CPL_ERROR_NONE) {
00334 cpl_propertylist_delete(p);
00335 FATAL_ERROR
00336 }
00337 cpl_propertylist_erase(p,"Y_coordinate");
00338 cpl_propertylist_append_bool(p,"ypredict",0);
00339 if (cpl_table_sort(stdstab,p) != CPL_ERROR_NONE) {
00340 cpl_propertylist_delete(p);
00341 FATAL_ERROR
00342 }
00343 cpl_propertylist_delete(p);
00344
00345
00346
00347 xobj = cpl_table_get_data_float(objtab,"X_coordinate");
00348 yobj = cpl_table_get_data_float(objtab,"Y_coordinate");
00349 xstd = cpl_table_get_data_float(stdstab,"xpredict");
00350 ystd = cpl_table_get_data_float(stdstab,"ypredict");
00351 if (xstd == NULL || ystd == NULL || xobj == NULL || yobj == NULL)
00352 FATAL_ERROR
00353
00354
00355
00356 aveden = (float)max(nstd,nobj)/(float)(NX*NY);
00357 errlim = 1.0/sqrt(4.0*CPL_MATH_PI*aveden);
00358 errlim = min(errlim,15.0);
00359 ngrid = (int)(srad/errlim);
00360 ngrid = (ngrid/2)*2 + 1;
00361 ngrid = max(5,min(NGRIDMAX_STD,ngrid));
00362 ngrid2 = ngrid/2 + 1;
00363
00364
00365
00366 ibest = 0;
00367 xoffbest = 0.0;
00368 yoffbest = 0.0;
00369 for (ig = -ngrid2; ig <= ngrid2; ig++) {
00370 xoff = (float)ig*errlim*CPL_MATH_SQRT2;
00371 for (jg = -ngrid2; jg <= ngrid2; jg++) {
00372 yoff = (float)jg*errlim*CPL_MATH_SQRT2;
00373 nmatch = 0;
00374 for (k = 0; k < nobj; k++) {
00375 x = xobj[k] + xoff;
00376 y = yobj[k] + yoff;
00377 if (vircam_fndmatch(x,y,xstd,ystd,nstd,errlim) > -1)
00378 nmatch++;
00379 }
00380 if (nmatch > ibest) {
00381 ibest = nmatch;
00382 xoffbest = xoff;
00383 yoffbest = yoff;
00384 }
00385 }
00386 }
00387
00388
00389
00390
00391 xoffs = cpl_malloc(nstd*sizeof(*xoffs));
00392 yoffs = cpl_malloc(nstd*sizeof(*yoffs));
00393 matches = cpl_malloc(nstd*sizeof(*matches));
00394 for (k = 0; k < nstd; k++)
00395 matches[k] = -1;
00396
00397
00398
00399 nmatch = 0;
00400 for (k = 0; k < nstd; k++) {
00401 x = xstd[k] - xoffbest;
00402 y = ystd[k] - yoffbest;
00403 jm = vircam_fndmatch(x,y,xobj,yobj,nobj,errlim);
00404 if (jm > -1) {
00405 dont = 0;
00406 xx2 = xobj[jm] - x;
00407 yy2 = yobj[jm] - y;
00408 r2 = sqrt(xx2*xx2 + yy2*yy2);
00409 for (l = 0; l < nstd; l++) {
00410 if (matches[l] == jm) {
00411 xx1 = xobj[jm] - (xstd[l] - xoffbest);
00412 yy1 = yobj[jm] - (ystd[l] - yoffbest);
00413 r1 = sqrt(xx1*xx1 + yy1*yy1);
00414 if (r2 < r1)
00415 matches[l] = -1;
00416 else
00417 dont = 1;
00418 break;
00419 }
00420 }
00421 if (dont == 0)
00422 matches[k] = jm;
00423 }
00424 }
00425
00426
00427
00428 for (k = 0; k < nstd; k++) {
00429 jm = matches[k];
00430 if (jm != -1) {
00431 xoffs[nmatch] = xobj[jm] - xstd[k];
00432 yoffs[nmatch] = yobj[jm] - ystd[k];
00433 nmatch++;
00434 }
00435 }
00436 if (nmatch == 0) {
00437 xoffmed = 0.0;
00438 sigx = 1.0;
00439 yoffmed = 0.0;
00440 sigy = 1.0;
00441 } else {
00442 vircam_medmad(xoffs,NULL,nmatch,&xoffmed,&sigx);
00443 sigx *= 1.48;
00444 vircam_medmad(yoffs,NULL,nmatch,&yoffmed,&sigy);
00445 sigy *= 1.48;
00446 }
00447
00448
00449
00450
00451 errlim = 3.0*max(sigx,sigy);
00452 for (k = 0; k < nstd; k++)
00453 matches[k] = -1;
00454 for (k = 0; k < nstd; k++) {
00455 x = xstd[k] + xoffmed;
00456 y = ystd[k] + yoffmed;
00457 jm = vircam_fndmatch(x,y,xobj,yobj,nobj,errlim);
00458 if (jm > -1) {
00459 dont = 0;
00460 xx2 = xobj[jm] - x;
00461 yy2 = yobj[jm] - y;
00462 r2 = sqrt(xx2*xx2 + yy2*yy2);
00463 for (l = 0; l < nstd; l++) {
00464 if (matches[l] == jm) {
00465 xx1 = xobj[jm] - (xstd[l] + xoffmed);
00466 yy1 = yobj[jm] - (ystd[l] + yoffmed);
00467 r1 = sqrt(xx1*xx1 + yy1*yy1);
00468 if (r2 < r1)
00469 matches[l] = -1;
00470 else
00471 dont = 1;
00472
00473 }
00474 }
00475 if (dont == 0)
00476 matches[k] = jm;
00477 }
00478 }
00479 jm = matches[1];
00480
00481
00482
00483
00484
00485 mstds = cpl_table_duplicate(stdstab);
00486 colname = (char *)cpl_table_get_column_name(objtab);
00487 while (colname != NULL) {
00488 if (strcmp(colname,"RA") && strcmp(colname,"DEC"))
00489 cpl_table_new_column(mstds,colname,
00490 cpl_table_get_column_type(objtab,colname));
00491 colname = (char *)cpl_table_get_column_name(NULL);
00492 }
00493 cpl_table_unselect_all(mstds);
00494
00495
00496
00497 for (k = 0; k < nstd; k++) {
00498 jm = matches[k];
00499 if (jm != -1) {
00500 colname = (char *)cpl_table_get_column_name(objtab);
00501 while (colname != NULL) {
00502 if (!strcmp(colname,"RA") || !strcmp(colname,"DEC")) {
00503 colname = (char *)cpl_table_get_column_name(NULL);
00504 continue;
00505 }
00506 null = 0;
00507 switch (cpl_table_get_column_type(objtab,colname)) {
00508 case CPL_TYPE_INT:
00509 cpl_table_set_int(mstds,colname,k,
00510 cpl_table_get_int(objtab,colname,jm,
00511 &null));
00512 break;
00513 case CPL_TYPE_FLOAT:
00514 cpl_table_set_float(mstds,colname,k,
00515 cpl_table_get_float(objtab,colname,jm,
00516 &null));
00517 break;
00518 case CPL_TYPE_DOUBLE:
00519 cpl_table_set_double(mstds,colname,k,
00520 cpl_table_get_double(objtab,colname,
00521 jm,&null));
00522 break;
00523 default:
00524 cpl_table_set_float(mstds,colname,k,
00525 cpl_table_get_float(objtab,colname,jm,
00526 &null));
00527 break;
00528 }
00529 colname = (char *)cpl_table_get_column_name(NULL);
00530 }
00531 cpl_table_select_row(mstds,k);
00532 }
00533 }
00534
00535
00536
00537 *outtab = cpl_table_extract_selected(mstds);
00538 cpl_table_delete(mstds);
00539
00540
00541
00542 freespace(matches);
00543 freespace(xoffs);
00544 freespace(yoffs);
00545 GOOD_STATUS
00546 }
00547
00548 extern int vircam_tpoffset(cpl_table *progtab, cpl_table *template,
00549 const cpl_wcs *progwcs, const cpl_wcs *tempwcs,
00550 float srad, double *xoffset, double *yoffset,
00551 int *nm, float *xoff_pix, float *yoff_pix,
00552 int *status) {
00553 int nprog,ntemp,nmatch,k,jm;
00554 const char *fctid = "vircam_tpoffset";
00555 float *xprog,*yprog,*xtemp,*ytemp,x,y,xoff,yoff;
00556 double *xoffs,*yoffs;
00557 cpl_matrix *in,*outt,*outp;
00558 cpl_array *st;
00559 cpl_table *outxy;
00560
00561
00562
00563 *xoffset = 0.0;
00564 *yoffset = 0.0;
00565 *xoff_pix = 0.0;
00566 *yoff_pix = 0.0;
00567 *nm = 0;
00568 if (*status != VIR_OK)
00569 return(*status);
00570
00571
00572
00573 (void)vircam_matchxy(progtab,template,srad,&xoff,&yoff,&nmatch,&outxy,
00574 status);
00575 freetable(outxy);
00576 if (*status != VIR_OK) {
00577 cpl_msg_warning(fctid,"Error getting xy offset");
00578 FATAL_ERROR
00579 }
00580 *xoff_pix = xoff;
00581 *yoff_pix = yoff;
00582
00583
00584
00585
00586 nprog = cpl_table_get_nrow(progtab);
00587 ntemp = cpl_table_get_nrow(template);
00588 xprog = cpl_table_get_data_float(progtab,"X_coordinate");
00589 yprog = cpl_table_get_data_float(progtab,"Y_coordinate");
00590 xtemp = cpl_table_get_data_float(template,"X_coordinate");
00591 ytemp = cpl_table_get_data_float(template,"Y_coordinate");
00592
00593
00594
00595
00596 xoffs = cpl_malloc(nprog*sizeof(*xoffs));
00597 yoffs = cpl_malloc(nprog*sizeof(*yoffs));
00598 in = cpl_matrix_new(1,2);
00599
00600
00601
00602 nmatch = 0;
00603 for (k = 0; k < nprog; k++) {
00604 x = xprog[k] + xoff;
00605 y = yprog[k] + yoff;
00606 jm = vircam_fndmatch(x,y,xtemp,ytemp,ntemp,0.5);
00607 if (jm > -1) {
00608 cpl_matrix_set(in,0,0,(double)xtemp[jm]);
00609 cpl_matrix_set(in,0,1,(double)ytemp[jm]);
00610 cpl_wcs_convert(tempwcs,in,&outt,&st,CPL_WCS_PHYS2WORLD);
00611 cpl_array_delete(st);
00612 cpl_matrix_set(in,0,0,(double)xprog[k]);
00613 cpl_matrix_set(in,0,1,(double)yprog[k]);
00614 cpl_wcs_convert(progwcs,in,&outp,&st,CPL_WCS_PHYS2WORLD);
00615 cpl_array_delete(st);
00616 xoffs[nmatch] = cpl_matrix_get(outt,0,0) - cpl_matrix_get(outp,0,0);
00617 yoffs[nmatch] = cpl_matrix_get(outt,0,1) - cpl_matrix_get(outp,0,1);
00618 nmatch++;
00619 cpl_matrix_delete(outt);
00620 cpl_matrix_delete(outp);
00621 }
00622 }
00623 if (nmatch > 0) {
00624 *xoffset = vircam_dmed(xoffs,NULL,nmatch);
00625 *yoffset = vircam_dmed(yoffs,NULL,nmatch);
00626 } else {
00627 *xoffset = 0.0;
00628 *yoffset = 0.0;
00629 }
00630 *nm = nmatch;
00631
00632
00633
00634 cpl_matrix_delete(in);
00635 freespace(xoffs);
00636 freespace(yoffs);
00637 return(VIR_OK);
00638 }
00639
00640
00660
00661
00662 static cpl_table *vircam_mkmstd_table(cpl_table *objtab, cpl_table *stdstab) {
00663 cpl_table *mstds;
00664 char *colname;
00665
00666
00667
00668 mstds = cpl_table_duplicate(stdstab);
00669
00670
00671
00672
00673 colname = (char *)cpl_table_get_column_name(objtab);
00674 while (colname != NULL) {
00675 if (strcmp(colname,"RA") && strcmp(colname,"DEC"))
00676 cpl_table_new_column(mstds,colname,
00677 cpl_table_get_column_type(objtab,colname));
00678 colname = (char *)cpl_table_get_column_name(NULL);
00679 }
00680 cpl_table_unselect_all(mstds);
00681
00682
00683
00684 return(mstds);
00685 }
00686
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760