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 = (int)cpl_table_get_nrow(progtab);
00125 ntemp = (int)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((cpl_size)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",(cpl_size)nmatch,
00233 xtemp[jm]);
00234 cpl_table_set_float(*outtab,"Y_coordinate_1",(cpl_size)nmatch,
00235 ytemp[jm]);
00236 cpl_table_set_float(*outtab,"X_coordinate_2",(cpl_size)nmatch,
00237 xprog[k]);
00238 cpl_table_set_float(*outtab,"Y_coordinate_2",(cpl_size)nmatch,
00239 yprog[k]);
00240 nmatch++;
00241 }
00242 }
00243 cpl_table_set_size(*outtab,(cpl_size)nmatch);
00244
00245
00246
00247 freespace(xoffs);
00248 freespace(yoffs);
00249 GOOD_STATUS
00250 }
00251
00252
00297
00298
00299 extern int vircam_matchstds(cpl_table *objtab, cpl_table *stdstab, float srad,
00300 cpl_table **outtab, int *status) {
00301 const char *fctid = "vircam_matchstds";
00302 char *colname;
00303 int nobj,nstd,ngrid,ngrid2,ibest,ig,jg,nmatch,k,*matches,jm,l,dont,null;
00304 float *xstd,*ystd,*xobj,*yobj,aveden,errlim,xoffbest,yoffbest,*xoffs;
00305 float *yoffs,x,y,xx2,yy2,r2,xx1,yy1,r1,xoffmed,sigx,yoffmed,sigy,xoff,yoff;
00306 cpl_propertylist *p;
00307 cpl_table *mstds;
00308
00309
00310
00311 *outtab = NULL;
00312 if (*status != VIR_OK)
00313 return(*status);
00314
00315
00316
00317 nobj = (int)cpl_table_get_nrow(objtab);
00318 nstd = (int)cpl_table_get_nrow(stdstab);
00319 if (nobj == 0) {
00320 cpl_msg_warning(fctid,"Object table has no rows");
00321 mstds = vircam_mkmstd_table(objtab,stdstab);
00322 *outtab = cpl_table_extract_selected(mstds);
00323 cpl_table_delete(mstds);
00324 WARN_RETURN
00325 } else if (nstd == 0) {
00326 cpl_msg_warning(fctid,"Standards RA/DEC table has no rows");
00327 mstds = vircam_mkmstd_table(objtab,stdstab);
00328 *outtab = cpl_table_extract_selected(mstds);
00329 cpl_table_delete(mstds);
00330 WARN_RETURN
00331 }
00332
00333
00334
00335 p = cpl_propertylist_new();
00336 cpl_propertylist_append_bool(p,"Y_coordinate",0);
00337 if (cpl_table_sort(objtab,p) != CPL_ERROR_NONE) {
00338 cpl_propertylist_delete(p);
00339 FATAL_ERROR
00340 }
00341 cpl_propertylist_erase(p,"Y_coordinate");
00342 cpl_propertylist_append_bool(p,"ypredict",0);
00343 if (cpl_table_sort(stdstab,p) != CPL_ERROR_NONE) {
00344 cpl_propertylist_delete(p);
00345 FATAL_ERROR
00346 }
00347 cpl_propertylist_delete(p);
00348
00349
00350
00351 xobj = cpl_table_get_data_float(objtab,"X_coordinate");
00352 yobj = cpl_table_get_data_float(objtab,"Y_coordinate");
00353 xstd = cpl_table_get_data_float(stdstab,"xpredict");
00354 ystd = cpl_table_get_data_float(stdstab,"ypredict");
00355 if (xstd == NULL || ystd == NULL || xobj == NULL || yobj == NULL)
00356 FATAL_ERROR
00357
00358
00359
00360 aveden = (float)max(nstd,nobj)/(float)(NX*NY);
00361 errlim = 1.0/sqrt(4.0*CPL_MATH_PI*aveden);
00362 errlim = min(errlim,15.0);
00363 ngrid = (int)(srad/errlim);
00364 ngrid = (ngrid/2)*2 + 1;
00365 ngrid = max(5,min(NGRIDMAX_STD,ngrid));
00366 ngrid2 = ngrid/2 + 1;
00367
00368
00369
00370 ibest = 0;
00371 xoffbest = 0.0;
00372 yoffbest = 0.0;
00373 for (ig = -ngrid2; ig <= ngrid2; ig++) {
00374 xoff = (float)ig*errlim*CPL_MATH_SQRT2;
00375 for (jg = -ngrid2; jg <= ngrid2; jg++) {
00376 yoff = (float)jg*errlim*CPL_MATH_SQRT2;
00377 nmatch = 0;
00378 for (k = 0; k < nobj; k++) {
00379 x = xobj[k] + xoff;
00380 y = yobj[k] + yoff;
00381 if (vircam_fndmatch(x,y,xstd,ystd,nstd,errlim) > -1)
00382 nmatch++;
00383 }
00384 if (nmatch > ibest) {
00385 ibest = nmatch;
00386 xoffbest = xoff;
00387 yoffbest = yoff;
00388 }
00389 }
00390 }
00391
00392
00393
00394
00395 xoffs = cpl_malloc(nstd*sizeof(*xoffs));
00396 yoffs = cpl_malloc(nstd*sizeof(*yoffs));
00397 matches = cpl_malloc(nstd*sizeof(*matches));
00398 for (k = 0; k < nstd; k++)
00399 matches[k] = -1;
00400
00401
00402
00403 nmatch = 0;
00404 for (k = 0; k < nstd; k++) {
00405 x = xstd[k] - xoffbest;
00406 y = ystd[k] - yoffbest;
00407 jm = vircam_fndmatch(x,y,xobj,yobj,nobj,errlim);
00408 if (jm > -1) {
00409 dont = 0;
00410 xx2 = xobj[jm] - x;
00411 yy2 = yobj[jm] - y;
00412 r2 = sqrt(xx2*xx2 + yy2*yy2);
00413 for (l = 0; l < nstd; l++) {
00414 if (matches[l] == jm) {
00415 xx1 = xobj[jm] - (xstd[l] - xoffbest);
00416 yy1 = yobj[jm] - (ystd[l] - yoffbest);
00417 r1 = sqrt(xx1*xx1 + yy1*yy1);
00418 if (r2 < r1)
00419 matches[l] = -1;
00420 else
00421 dont = 1;
00422 break;
00423 }
00424 }
00425 if (dont == 0)
00426 matches[k] = jm;
00427 }
00428 }
00429
00430
00431
00432 for (k = 0; k < nstd; k++) {
00433 jm = matches[k];
00434 if (jm != -1) {
00435 xoffs[nmatch] = xobj[jm] - xstd[k];
00436 yoffs[nmatch] = yobj[jm] - ystd[k];
00437 nmatch++;
00438 }
00439 }
00440 if (nmatch == 0) {
00441 xoffmed = 0.0;
00442 sigx = 1.0;
00443 yoffmed = 0.0;
00444 sigy = 1.0;
00445 } else {
00446 vircam_medmad(xoffs,NULL,nmatch,&xoffmed,&sigx);
00447 sigx *= 1.48;
00448 vircam_medmad(yoffs,NULL,nmatch,&yoffmed,&sigy);
00449 sigy *= 1.48;
00450 }
00451
00452
00453
00454
00455 errlim = 3.0*max(sigx,sigy);
00456 for (k = 0; k < nstd; k++)
00457 matches[k] = -1;
00458 for (k = 0; k < nstd; k++) {
00459 x = xstd[k] + xoffmed;
00460 y = ystd[k] + yoffmed;
00461 jm = vircam_fndmatch(x,y,xobj,yobj,nobj,errlim);
00462 if (jm > -1) {
00463 dont = 0;
00464 xx2 = xobj[jm] - x;
00465 yy2 = yobj[jm] - y;
00466 r2 = sqrt(xx2*xx2 + yy2*yy2);
00467 for (l = 0; l < nstd; l++) {
00468 if (matches[l] == jm) {
00469 xx1 = xobj[jm] - (xstd[l] + xoffmed);
00470 yy1 = yobj[jm] - (ystd[l] + yoffmed);
00471 r1 = sqrt(xx1*xx1 + yy1*yy1);
00472 if (r2 < r1)
00473 matches[l] = -1;
00474 else
00475 dont = 1;
00476
00477 }
00478 }
00479 if (dont == 0)
00480 matches[k] = jm;
00481 }
00482 }
00483 jm = matches[1];
00484
00485
00486
00487
00488
00489 mstds = cpl_table_duplicate(stdstab);
00490 colname = (char *)cpl_table_get_column_name(objtab);
00491 while (colname != NULL) {
00492 if (strcmp(colname,"RA") && strcmp(colname,"DEC"))
00493 cpl_table_new_column(mstds,colname,
00494 cpl_table_get_column_type(objtab,colname));
00495 colname = (char *)cpl_table_get_column_name(NULL);
00496 }
00497 cpl_table_unselect_all(mstds);
00498
00499
00500
00501 for (k = 0; k < nstd; k++) {
00502 jm = matches[k];
00503 if (jm != -1) {
00504 colname = (char *)cpl_table_get_column_name(objtab);
00505 while (colname != NULL) {
00506 if (!strcmp(colname,"RA") || !strcmp(colname,"DEC")) {
00507 colname = (char *)cpl_table_get_column_name(NULL);
00508 continue;
00509 }
00510 null = 0;
00511 switch (cpl_table_get_column_type(objtab,colname)) {
00512 case CPL_TYPE_INT:
00513 cpl_table_set_int(mstds,colname,(cpl_size)k,
00514 cpl_table_get_int(objtab,colname,
00515 (cpl_size)jm,&null));
00516 break;
00517 case CPL_TYPE_FLOAT:
00518 cpl_table_set_float(mstds,colname,(cpl_size)k,
00519 cpl_table_get_float(objtab,colname,
00520 (cpl_size)jm,&null));
00521 break;
00522 case CPL_TYPE_DOUBLE:
00523 cpl_table_set_double(mstds,colname,(cpl_size)k,
00524 cpl_table_get_double(objtab,colname,
00525 (cpl_size)jm,&null));
00526 break;
00527 default:
00528 cpl_table_set_float(mstds,colname,(cpl_size)k,
00529 cpl_table_get_float(objtab,colname,
00530 (cpl_size)jm,&null));
00531 break;
00532 }
00533 colname = (char *)cpl_table_get_column_name(NULL);
00534 }
00535 cpl_table_select_row(mstds,(cpl_size)k);
00536 }
00537 }
00538
00539
00540
00541 *outtab = cpl_table_extract_selected(mstds);
00542 cpl_table_delete(mstds);
00543
00544
00545
00546 freespace(matches);
00547 freespace(xoffs);
00548 freespace(yoffs);
00549 GOOD_STATUS
00550 }
00551
00552 extern int vircam_tpoffset(cpl_table *progtab, cpl_table *template,
00553 const cpl_wcs *progwcs, const cpl_wcs *tempwcs,
00554 float srad, double *xoffset, double *yoffset,
00555 int *nm, float *xoff_pix, float *yoff_pix,
00556 int *status) {
00557 int nprog,ntemp,nmatch,k,jm;
00558 const char *fctid = "vircam_tpoffset";
00559 float *xprog,*yprog,*xtemp,*ytemp,x,y,xoff,yoff;
00560 double *xoffs,*yoffs;
00561 cpl_matrix *in,*outt,*outp;
00562 cpl_array *st;
00563 cpl_table *outxy;
00564
00565
00566
00567 *xoffset = 0.0;
00568 *yoffset = 0.0;
00569 *xoff_pix = 0.0;
00570 *yoff_pix = 0.0;
00571 *nm = 0;
00572 if (*status != VIR_OK)
00573 return(*status);
00574
00575
00576
00577 (void)vircam_matchxy(progtab,template,srad,&xoff,&yoff,&nmatch,&outxy,
00578 status);
00579 freetable(outxy);
00580 if (*status != VIR_OK) {
00581 cpl_msg_warning(fctid,"Error getting xy offset");
00582 FATAL_ERROR
00583 }
00584 *xoff_pix = xoff;
00585 *yoff_pix = yoff;
00586
00587
00588
00589
00590 nprog = (int)cpl_table_get_nrow(progtab);
00591 ntemp = (int)cpl_table_get_nrow(template);
00592 xprog = cpl_table_get_data_float(progtab,"X_coordinate");
00593 yprog = cpl_table_get_data_float(progtab,"Y_coordinate");
00594 xtemp = cpl_table_get_data_float(template,"X_coordinate");
00595 ytemp = cpl_table_get_data_float(template,"Y_coordinate");
00596
00597
00598
00599
00600 xoffs = cpl_malloc(nprog*sizeof(*xoffs));
00601 yoffs = cpl_malloc(nprog*sizeof(*yoffs));
00602 in = cpl_matrix_new(1,2);
00603
00604
00605
00606 nmatch = 0;
00607 for (k = 0; k < nprog; k++) {
00608 x = xprog[k] + xoff;
00609 y = yprog[k] + yoff;
00610 jm = vircam_fndmatch(x,y,xtemp,ytemp,ntemp,0.5);
00611 if (jm > -1) {
00612 cpl_matrix_set(in,0,0,(double)xtemp[jm]);
00613 cpl_matrix_set(in,0,1,(double)ytemp[jm]);
00614 cpl_wcs_convert(tempwcs,in,&outt,&st,CPL_WCS_PHYS2WORLD);
00615 cpl_array_delete(st);
00616 cpl_matrix_set(in,0,0,(double)xprog[k]);
00617 cpl_matrix_set(in,0,1,(double)yprog[k]);
00618 cpl_wcs_convert(progwcs,in,&outp,&st,CPL_WCS_PHYS2WORLD);
00619 cpl_array_delete(st);
00620 xoffs[nmatch] = cpl_matrix_get(outt,0,0) - cpl_matrix_get(outp,0,0);
00621 yoffs[nmatch] = cpl_matrix_get(outt,0,1) - cpl_matrix_get(outp,0,1);
00622 nmatch++;
00623 cpl_matrix_delete(outt);
00624 cpl_matrix_delete(outp);
00625 }
00626 }
00627 if (nmatch > 0) {
00628 *xoffset = vircam_dmed(xoffs,NULL,nmatch);
00629 *yoffset = vircam_dmed(yoffs,NULL,nmatch);
00630 } else {
00631 *xoffset = 0.0;
00632 *yoffset = 0.0;
00633 }
00634 *nm = nmatch;
00635
00636
00637
00638 cpl_matrix_delete(in);
00639 freespace(xoffs);
00640 freespace(yoffs);
00641 return(VIR_OK);
00642 }
00643
00644
00664
00665
00666 static cpl_table *vircam_mkmstd_table(cpl_table *objtab, cpl_table *stdstab) {
00667 cpl_table *mstds;
00668 char *colname;
00669
00670
00671
00672 mstds = cpl_table_duplicate(stdstab);
00673
00674
00675
00676
00677 colname = (char *)cpl_table_get_column_name(objtab);
00678 while (colname != NULL) {
00679 if (strcmp(colname,"RA") && strcmp(colname,"DEC"))
00680 cpl_table_new_column(mstds,colname,
00681 cpl_table_get_column_type(objtab,colname));
00682 colname = (char *)cpl_table_get_column_name(NULL);
00683 }
00684 cpl_table_unselect_all(mstds);
00685
00686
00687
00688 return(mstds);
00689 }
00690
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
00761
00762
00763
00764
00765
00766
00767