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 <sys/time.h>
00035 #include <time.h>
00036 #include <libgen.h>
00037 #include <string.h>
00038 #include <unistd.h>
00039
00040 #include <cpl.h>
00041 #include <math.h>
00042
00043 #include "vircam_utils.h"
00044 #include "vircam_stats.h"
00045 #include "vircam_fits.h"
00046 #include "vircam_pfits.h"
00047 #include "catalogue/imcore.h"
00048
00049 #define SZKEY 32
00050 #define SZVAL 64
00051
00052
00053
00054 #define NI_COLS 5
00055 static const char *illcor_cols[NI_COLS] = {"xmin","xmax","ymin","ymax",
00056 "illcor"};
00057
00058
00059
00060 static float madfunc(int npts, float *xt, float *yt, float b);
00061
00075
00090
00091
00092 extern const char *vircam_get_license(void) {
00093 const char *vircam_license =
00094 "This file is part of the VIRCAM Instrument Pipeline\n"
00095 "Copyright (C) 2006 Cambridge Astronomy Survey Unit\n"
00096 "\n"
00097 "This program is free software; you can redistribute it and/or modify\n"
00098 "it under the terms of the GNU General Public License as published by\n"
00099 "the Free Software Foundation; either version 2 of the License, or\n"
00100 "(at your option) any later version.\n"
00101 "\n"
00102 "This program is distributed in the hope that it will be useful,\n"
00103 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
00104 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
00105 "GNU General Public License for more details.\n"
00106 "\n"
00107 "You should have received a copy of the GNU General Public License\n"
00108 "along with this program; if not, write to the Free Software\n"
00109 "Foundation, Inc., 59 Temple Place, Suite 330, Boston, \n"
00110 "MA 02111-1307 USA";
00111 return(vircam_license);
00112 }
00113
00114
00115
00139
00140
00141 extern int vircam_compare_tags(const cpl_frame *frame1,
00142 const cpl_frame *frame2) {
00143 char *v1,*v2;
00144
00145
00146
00147 if (frame1 == NULL || frame2 == NULL)
00148 return(-1);
00149
00150
00151
00152 if ((v1 = (char *)cpl_frame_get_tag(frame1)) == NULL)
00153 return(-1);
00154 if ((v2 = (char *)cpl_frame_get_tag(frame2)) == NULL)
00155 return(-1);
00156
00157
00158
00159 if (strcmp(v1,v2))
00160 return(0);
00161 else
00162 return(1);
00163 }
00164
00165
00191
00192
00193 extern cpl_frameset *vircam_frameset_subgroup(cpl_frameset *frameset,
00194 cpl_size *labels, cpl_size nlab,
00195 const char *tag) {
00196 int i;
00197 cpl_frameset *cur_set,*ret_set;
00198 cpl_frame *cur_frame;
00199 char *cur_tag;
00200
00201
00202 ret_set = NULL;
00203 for (i = 0; i < nlab; i++) {
00204 cur_set = cpl_frameset_extract(frameset,labels,(cpl_size)i);
00205 if (cur_set == NULL)
00206 break;
00207 cur_frame = cpl_frameset_get_frame(cur_set,0);
00208 cur_tag = (char *)cpl_frame_get_tag(cur_frame);
00209 if (!strcmp(cur_tag,tag)) {
00210 ret_set = cur_set;
00211 break;
00212 }
00213 cpl_frameset_delete(cur_set);
00214 }
00215 return(ret_set);
00216 }
00217
00218
00245
00246
00247 extern cpl_frame *vircam_frameset_subgroup_1(cpl_frameset *frameset,
00248 cpl_size *labels, cpl_size nlab,
00249 const char *tag) {
00250 cpl_frameset *cur_set;
00251 cpl_frame *cur_frame,*new_frame;
00252
00253 if ((cur_set = vircam_frameset_subgroup(frameset,labels,nlab,tag)) == NULL) {
00254 return(NULL);
00255 } else {
00256 cur_frame = cpl_frameset_get_frame(cur_set,0);
00257 new_frame = cpl_frame_duplicate(cur_frame);
00258 cpl_frameset_delete(cur_set);
00259 return(new_frame);
00260 }
00261 }
00262
00263
00283
00284
00285 extern int vircam_frameset_fexists (cpl_frameset *frameset) {
00286 int nf,i,nerr;
00287 cpl_frame *cur;
00288 const char *fname;
00289 const char *fctid = "vircam_frameset_fexists";
00290
00291
00292
00293 if (frameset == NULL) {
00294 cpl_msg_error(fctid,"Input frameset is NULL");
00295 return(VIR_FATAL);
00296 }
00297
00298
00299
00300 nf = cpl_frameset_get_size(frameset);
00301 if (nf == 0) {
00302 cpl_msg_error(fctid,"Input frameset has size of zero");
00303 return(VIR_FATAL);
00304 }
00305
00306
00307
00308 nerr = 0;
00309 for (i = 0; i < nf; i++) {
00310 cur = cpl_frameset_get_frame(frameset,i);
00311 fname = cpl_frame_get_filename(cur);
00312 if (access(fname,F_OK) != 0) {
00313 cpl_msg_error(fctid,"File: %s doesn't exist",fname);
00314 nerr++;
00315 }
00316 }
00317
00318
00319
00320 if (nerr != 0)
00321 return(VIR_FATAL);
00322 else
00323 return(VIR_OK);
00324 }
00325
00326
00351
00352
00353 extern void vircam_exten_range(int inexten, const cpl_frame *fr, int *out1,
00354 int *out2) {
00355 int nvircam = 16,n,nmax;
00356 const char *fctid = "vircam_exten_range";
00357
00358
00359
00360 n = cpl_frame_get_nextensions(fr);
00361
00362
00363
00364
00365 if (n < nvircam) {
00366 cpl_msg_warning(fctid,
00367 "Only %" CPL_SIZE_FORMAT " extensions out of %" CPL_SIZE_FORMAT " are present",
00368 (cpl_size)n,(cpl_size)nvircam);
00369 nmax = n;
00370 } else {
00371 nmax = nvircam;
00372 }
00373
00374
00375
00376
00377 if (inexten == 0) {
00378 *out1 = 1;
00379 *out2 = nmax;
00380
00381
00382
00383 } else {
00384
00385 if (inexten > nmax) {
00386 cpl_msg_error(fctid,
00387 "Requested extension %" CPL_SIZE_FORMAT " is not present",
00388 (cpl_size)inexten);
00389 *out1 = -1;
00390 *out2 = -1;
00391 } else {
00392 *out1 = inexten;
00393 *out2 = inexten;
00394 }
00395 }
00396 return;
00397 }
00398
00399
00425
00426
00427 extern void vircam_madfit(int npts, float *xdata, float *ydata,
00428 float *intercept, float *slope) {
00429 int j;
00430 float sx,sy,sxx,sxy,det,aa,bb,temp,chisq,sigb,b1,f1,b2,f2,f;
00431
00432
00433
00434 sx = 0.0;
00435 sy = 0.0;
00436 sxx = 0.0;
00437 sxy = 0.0;
00438 for (j = 0; j < npts; j++) {
00439 sx += xdata[j];
00440 sy += ydata[j];
00441 sxx += xdata[j]*xdata[j];
00442 sxy += xdata[j]*ydata[j];
00443 }
00444 det = (float)npts*sxx - sx*sx;
00445 if (det == 0.0) {
00446 *slope = 0.0;
00447 *intercept = 0.0;
00448 return;
00449 }
00450 aa = (sxx*sy - sx*sxy)/det;
00451 bb = ((float)npts*sxy - sx*sy)/det;
00452 chisq = 0.0;
00453 for (j = 0; j < npts; j++) {
00454 temp = ydata[j] - (aa + bb*xdata[j]);
00455 chisq += temp*temp;
00456 }
00457 sigb = sqrt(chisq/det);
00458 if (sigb == 0.0) {
00459 *slope = bb;
00460 *intercept = aa;
00461 return;
00462 }
00463
00464
00465
00466 b1 = bb;
00467 f1 = madfunc(npts,xdata,ydata,b1);
00468 b2 = bb + ((f1 > 0.0) ? fabs(3.0*sigb) : -fabs(3.0*sigb));
00469 f2 = madfunc(npts,xdata,ydata,b2);
00470 while (f1*f2 > 0.0) {
00471 bb = 2.0*b2 - b1;
00472 b1 = b2;
00473 f1 = f2;
00474 b2 = bb;
00475 f2 = madfunc(npts,xdata,ydata,b2);
00476 }
00477
00478
00479
00480 sigb = 0.01*sigb;
00481 while (fabs(b2 - b1) > sigb) {
00482 bb = 0.5*(b1 + b2);
00483 if (bb == b1 || bb == b2)
00484 break;
00485 f = madfunc(npts,xdata,ydata,bb);
00486 if (f*f1 >= 0.0) {
00487 f1 = f;
00488 b1 = bb;
00489 } else {
00490 f2 = f;
00491 b2 = bb;
00492 }
00493 }
00494 *intercept = aa;
00495 *slope = bb;
00496 }
00497
00498
00521
00522
00523
00524 static float madfunc(int npts, float *xt, float *yt, float b) {
00525 float *arr,aa,d,sum;
00526 int j;
00527
00528 arr = cpl_malloc(npts*sizeof(*arr));
00529 for (j = 0; j < npts; j++)
00530 arr[j] = yt[j] - b*xt[j];
00531 aa = vircam_med(arr,NULL,(long)npts);
00532 sum = 0.0;
00533 for (j = 0; j < npts; j++) {
00534 d = yt[j] - (b*xt[j] + aa);
00535 sum += d > 0.0 ? xt[j] : -xt[j];
00536 }
00537 cpl_free(arr);
00538 return(sum);
00539 }
00540
00541
00568
00569
00570 extern void vircam_linfit(int npts, double *xdata, double *ydata,
00571 double *intercept, double *slope, double *sig) {
00572 int j;
00573 double sx,sy,sxx,sxy,det,aa,bb,temp,sum,sumsq;
00574
00575
00576
00577 sx = 0.0;
00578 sy = 0.0;
00579 sxx = 0.0;
00580 sxy = 0.0;
00581 for (j = 0; j < npts; j++) {
00582 sx += xdata[j];
00583 sy += ydata[j];
00584 sxx += xdata[j]*xdata[j];
00585 sxy += xdata[j]*ydata[j];
00586 }
00587 det = (double)npts*sxx - sx*sx;
00588 if (det == 0.0) {
00589 *slope = 0.0;
00590 *intercept = 0.0;
00591 *sig = 0.0;
00592 return;
00593 }
00594
00595
00596
00597 aa = (sxx*sy - sx*sxy)/det;
00598 bb = ((double)npts*sxy - sx*sy)/det;
00599
00600
00601
00602 sum = 0.0;
00603 sumsq = 0.0;
00604 for (j = 0; j < npts; j++) {
00605 temp = ydata[j] - (aa + bb*xdata[j]);
00606 sum += temp;
00607 sumsq += temp*temp;
00608 }
00609 sum /= (double)npts;
00610
00611
00612
00613 *sig = sqrt(sumsq/(double)npts - sum*sum);
00614 *slope = bb;
00615 *intercept = aa;
00616 }
00617
00618
00642
00643
00644 extern int vircam_solve_gauss(double **a, double *b, int m) {
00645 double temp,big,pivot,rmax;
00646 int i,iu,j,k,jl,ib,ir;
00647 int l = 0;
00648
00649 iu = m - 1;
00650 for (i = 0; i < iu; i++) {
00651 big = 0.0;
00652
00653
00654
00655 for (k = i; k < m; k++) {
00656 rmax = fabs(a[i][k]);
00657 if (rmax > big) {
00658 big = rmax;
00659 l = k;
00660 }
00661 }
00662
00663
00664
00665 if (big == 0.0) {
00666 for (ib = 0; ib < m; ib++)
00667 b[ib] = 0.0;
00668 cpl_msg_error("vircam_solve_gauss","Zero Determinant\n");
00669 return(VIR_FATAL);
00670 }
00671
00672 if (i != l) {
00673
00674
00675
00676 for (j = 0; j < m; j++) {
00677 temp = a[j][i];
00678 a[j][i] = a[j][l];
00679 a[j][l] = temp;
00680 }
00681 temp = b[i];
00682 b[i] = b[l];
00683 b[l] = temp;
00684 }
00685
00686
00687
00688
00689 pivot = a[i][i];
00690 jl = i+1;
00691
00692 for (j = jl; j < m; j++) {
00693 temp = a[i][j]/pivot;
00694 b[j] -= temp*b[i];
00695 for (k = i; k < m; k++)
00696 a[k][j] -= temp*a[k][i];
00697 }
00698 }
00699
00700
00701
00702 for (i = 0; i < m; i++) {
00703 ir = m - 1 - i;
00704 if (a[ir][ir] != 0.0) {
00705 temp = b[ir];
00706 if (ir != m - 1) {
00707 for (j = 1; j <= i; j++) {
00708 k = m - j;
00709 temp -= a[k][ir]*b[k];
00710 }
00711 }
00712 b[ir] = temp/a[ir][ir];
00713 } else
00714 b[ir] = 0.0;
00715 }
00716 return(VIR_OK);
00717 }
00718
00719
00757
00758
00759 extern int vircam_polyfit(const cpl_array *xarray, const cpl_array *yarray,
00760 int ncoefs, int ilim, int niter, float lclip,
00761 float hclip, cpl_array **polycf, double *sigfit) {
00762 const char *fctid = "vircam_polyfit";
00763 int npts,iter,i,j,nnew,k,retval,n;
00764 double *xdata,*ydata,*pdata,*res,**a,*b,temp,sum,sumsq,val;
00765 double lcut,hcut;
00766 unsigned char *pm;
00767
00768
00769
00770 *polycf = NULL;
00771 *sigfit = -1.0;
00772
00773
00774
00775 npts = (int)cpl_array_get_size(xarray);
00776
00777
00778
00779 if (npts < ncoefs) {
00780 cpl_msg_warning(fctid,
00781 "Not data for fit, Npts = %" CPL_SIZE_FORMAT ", Ncoefs = %" CPL_SIZE_FORMAT,
00782 (cpl_size)npts,(cpl_size)ncoefs);
00783 return(VIR_FATAL);
00784 }
00785
00786
00787
00788 a = cpl_malloc(ncoefs*sizeof(double *));
00789 b = cpl_calloc(ncoefs,sizeof(double));
00790 for (i = 0; i < ncoefs; i++)
00791 a[i] = cpl_calloc(ncoefs,sizeof(double));
00792 pm = cpl_calloc(npts,sizeof(unsigned char));
00793 res = cpl_malloc(npts*sizeof(double));
00794
00795
00796
00797 xdata = (double *)cpl_array_get_data_double_const(xarray);
00798 ydata = (double *)cpl_array_get_data_double_const(yarray);
00799
00800
00801
00802 *polycf = cpl_array_new((cpl_size)ncoefs,CPL_TYPE_DOUBLE);
00803 pdata = cpl_array_get_data_double(*polycf);
00804
00805
00806
00807 for (iter = 0; iter <= niter; iter++) {
00808
00809
00810
00811 for (i = 0; i < ncoefs; i++) {
00812 for (j = 0; j < ncoefs; j++)
00813 a[i][j] = 0.0;
00814 b[i] = 0.0;
00815 }
00816 nnew = 0;
00817
00818
00819
00820 for (i = 0; i < npts; i++) {
00821 if (pm[i] == 1)
00822 continue;
00823 for (k = 0; k < ncoefs; k++) {
00824 temp = 1.0;
00825 if (k + ilim != 0)
00826 temp = pow(xdata[i],(double)(k+ilim));
00827 b[k] += ydata[i]*temp;
00828 for (j = 0; j <= k; j++) {
00829 temp = 1.0;
00830 if (k + j + 2*ilim != 0)
00831 temp = pow(xdata[i],(double)(k+j+2*ilim));
00832 a[j][k] += temp;
00833 }
00834 }
00835 }
00836 for (k = 1; k < ncoefs; k++)
00837 for (j = 0; j < k; j++)
00838 a[k][j] = a[j][k];
00839
00840
00841
00842 retval = vircam_solve_gauss(a,b,ncoefs);
00843 if (retval != VIR_OK) {
00844 cpl_msg_warning(fctid,"Fit failed");
00845 freearray(*polycf);
00846 freespace2(a,ncoefs);
00847 freespace(b);
00848 freespace(pm);
00849 freespace(res);
00850 return(VIR_FATAL);
00851 }
00852
00853
00854
00855 for (i = 0; i < ncoefs; i++)
00856 pdata[i] = b[i];
00857
00858
00859
00860 sum = 0.0;
00861 sumsq = 0.0;
00862 n = 0;
00863 for (i = 0; i < npts; i++) {
00864 if (pm[i] == 1)
00865 continue;
00866 val = 0.0;
00867 for (j = 0; j < ncoefs; j++)
00868 val += pdata[j]*pow(xdata[i],(double)j+ilim);
00869 res[i] = val - ydata[i];
00870 sum += res[i];
00871 sumsq += pow(res[i],2.0);
00872 n++;
00873 }
00874 sum /= (double)n;
00875 *sigfit = sqrt(sumsq/(double)n - sum*sum);
00876
00877
00878
00879 lcut = sum - lclip*(*sigfit);
00880 hcut = sum + hclip*(*sigfit);
00881 if (iter < niter) {
00882 for (i = 0; i < npts; i++) {
00883 if (pm[i] == 1)
00884 continue;
00885 if (res[i] > hcut || res[i] < lcut) {
00886 nnew++;
00887 pm[i] = 1;
00888 }
00889 }
00890 }
00891
00892
00893
00894 if (nnew == 0)
00895 break;
00896 }
00897
00898
00899
00900 freespace2(a,ncoefs);
00901 freespace(b);
00902 freespace(pm);
00903 freespace(res);
00904 return(VIR_OK);
00905 }
00906
00907
00948
00949
00950 extern void vircam_difference_image(cpl_image *master, cpl_image *prog,
00951 unsigned char *bpm, cpl_table *chantab,
00952 int ncells, int oper, float *global_diff,
00953 float *global_rms, cpl_image **diffim,
00954 cpl_table **diffimstats) {
00955 float *ddata,*work,mean,sig,med,mad;
00956 long nx,ny,npts;
00957 int nrows,i,nc1,nc2,nr,ixmin,ixmax,iymin,iymax,cnum,cx,cy,idx,idy;
00958 int icx,icy,indy1,indy2,indx1,indx2,jp,jcx,jj,jcy,ii,ncx,ncy;
00959 const char *fctid = "vircam_difference_image";
00960
00961
00962
00963 *diffim = NULL;
00964 *diffimstats = NULL;
00965 *global_diff = 0.0;
00966 *global_rms = 0.0;
00967
00968
00969
00970 if (prog == NULL || master == NULL)
00971 return;
00972
00973
00974
00975 switch (oper) {
00976 case 1:
00977 *diffim = cpl_image_subtract_create(prog,master);
00978 break;
00979 case 2:
00980 *diffim = cpl_image_divide_create(prog,master);
00981 break;
00982 default:
00983 *diffim = NULL;
00984 cpl_msg_error(fctid,"Invalid operation requested %" CPL_SIZE_FORMAT,
00985 (cpl_size)oper);
00986 break;
00987 }
00988 if (*diffim == NULL)
00989 return;
00990
00991
00992
00993 ddata = cpl_image_get_data_float(*diffim);
00994 nx = (int)cpl_image_get_size_x(*diffim);
00995 ny = (int)cpl_image_get_size_y(*diffim);
00996 npts = nx*ny;
00997 vircam_medmad(ddata,bpm,npts,global_diff,global_rms);
00998 *global_rms *= 1.48;
00999
01000
01001
01002 if (chantab == NULL)
01003 return;
01004
01005
01006
01007
01008 if (! cpl_table_has_column(chantab,"ixmin") ||
01009 ! cpl_table_has_column(chantab,"ixmax") ||
01010 ! cpl_table_has_column(chantab,"iymin") ||
01011 ! cpl_table_has_column(chantab,"iymax") ||
01012 ! cpl_table_has_column(chantab,"channum")) {
01013 cpl_msg_error(fctid,"Channel table is missing one of the required columns");
01014
01015 return;
01016 }
01017
01018
01019
01020 switch (ncells) {
01021 case 1:
01022 nc1 = 1;
01023 nc2 = 1;
01024 break;
01025 case 2:
01026 nc1 = 2;
01027 nc2 = 1;
01028 break;
01029 case 4:
01030 nc1 = 4;
01031 nc2 = 1;
01032 break;
01033 case 8:
01034 nc1 = 8;
01035 nc2 = 1;
01036 break;
01037 case 16:
01038 nc1 = 16;
01039 nc2 = 1;
01040 break;
01041 case 32:
01042 nc1 = 16;
01043 nc2 = 2;
01044 break;
01045 case 64:
01046 nc1 = 32;
01047 nc2 = 2;
01048 break;
01049 default:
01050 nc1 = 32;
01051 nc2 = 2;
01052 break;
01053 }
01054
01055
01056
01057 nrows = (int)cpl_table_count_selected(chantab);
01058 *diffimstats = vircam_create_diffimg_stats(nrows*nc1*nc2);
01059
01060
01061
01062 nr = 0;
01063 for (i = 0; i < nrows; i++) {
01064 ixmin = cpl_table_get_int(chantab,"ixmin",(cpl_size)i,NULL);
01065 ixmax = cpl_table_get_int(chantab,"ixmax",(cpl_size)i,NULL);
01066 iymin = cpl_table_get_int(chantab,"iymin",(cpl_size)i,NULL);
01067 iymax = cpl_table_get_int(chantab,"iymax",(cpl_size)i,NULL);
01068 cnum = cpl_table_get_int(chantab,"channum",(cpl_size)i,NULL);
01069
01070
01071
01072
01073
01074
01075 cx = ixmax - ixmin + 1;
01076 cy = iymax - iymin + 1;
01077 if (cx > cy) {
01078 ncx = max(nc1,nc2);
01079 ncy = min(nc1,nc2);
01080 } else if (cx < cy) {
01081 ncy = max(nc1,nc2);
01082 ncx = min(nc1,nc2);
01083 } else {
01084 ncx = max(nc1,nc2);
01085 ncy = min(nc1,nc2);
01086 }
01087
01088
01089
01090 idy = cy/ncy;
01091 idx = cx/ncx;
01092 work = cpl_malloc(idx*idy*sizeof(*work));
01093
01094
01095
01096 for (icy = 0; icy < ncy; icy++) {
01097 indy1 = idy*icy;
01098 indy2 = min(iymax,indy1+idy-1);
01099 for (icx = 0; icx < ncx; icx++) {
01100 indx1 = idx*icx;
01101 indx2 = min(ixmax,indx1+idx-1);
01102 jp = 0;
01103 for (jcy = indy1; jcy < indy2; jcy++) {
01104 jj = jcy*nx;
01105 for (jcx = indx1; jcx < indx2; jcx++) {
01106 ii = jj + jcx;
01107 if (bpm != NULL && bpm[ii] == 0)
01108 work[jp++] = ddata[ii];
01109 }
01110 }
01111 (void)vircam_meansig(work,NULL,(long)jp,&mean,&sig);
01112 (void)vircam_medmad(work,NULL,(long)jp,&med,&mad);
01113 cpl_table_set_int(*diffimstats,"xmin",(cpl_size)nr,indx1+1);
01114 cpl_table_set_int(*diffimstats,"xmax",(cpl_size)nr,indx2+1);
01115 cpl_table_set_int(*diffimstats,"ymin",(cpl_size)nr,indy1+1);
01116 cpl_table_set_int(*diffimstats,"ymax",(cpl_size)nr,indy2+1);
01117 cpl_table_set_int(*diffimstats,"chan",(cpl_size)nr,cnum);
01118 cpl_table_set_float(*diffimstats,"mean",(cpl_size)nr,mean);
01119 cpl_table_set_float(*diffimstats,"median",(cpl_size)nr,med);
01120 cpl_table_set_float(*diffimstats,"variance",(cpl_size)nr,
01121 (sig*sig));
01122 cpl_table_set_float(*diffimstats,"mad",(cpl_size)(nr++),mad);
01123 }
01124 }
01125 cpl_free(work);
01126 }
01127 }
01128
01129
01146
01147
01148 cpl_table *vircam_create_diffimg_stats(int nrows) {
01149 cpl_table *diffimstats;
01150
01151 diffimstats = cpl_table_new((cpl_size)nrows);
01152 cpl_table_new_column(diffimstats,"xmin",CPL_TYPE_INT);
01153 cpl_table_set_column_unit(diffimstats,"xmin","pixels");
01154 cpl_table_new_column(diffimstats,"xmax",CPL_TYPE_INT);
01155 cpl_table_set_column_unit(diffimstats,"xmax","pixels");
01156 cpl_table_new_column(diffimstats,"ymin",CPL_TYPE_INT);
01157 cpl_table_set_column_unit(diffimstats,"ymin","pixels");
01158 cpl_table_new_column(diffimstats,"ymax",CPL_TYPE_INT);
01159 cpl_table_set_column_unit(diffimstats,"ymax","pixels");
01160 cpl_table_new_column(diffimstats,"chan",CPL_TYPE_INT);
01161 cpl_table_set_column_unit(diffimstats,"chan","pixels");
01162 cpl_table_new_column(diffimstats,"mean",CPL_TYPE_FLOAT);
01163 cpl_table_set_column_unit(diffimstats,"mean","ADU");
01164 cpl_table_new_column(diffimstats,"median",CPL_TYPE_FLOAT);
01165 cpl_table_set_column_unit(diffimstats,"median","ADU");
01166 cpl_table_new_column(diffimstats,"variance",CPL_TYPE_FLOAT);
01167 cpl_table_set_column_unit(diffimstats,"variance","ADU**2");
01168 cpl_table_new_column(diffimstats,"mad",CPL_TYPE_FLOAT);
01169 cpl_table_set_column_unit(diffimstats,"mad","ADU");
01170 return(diffimstats);
01171 }
01172
01173
01174
01198
01199
01200 extern void vircam_sort(float **a, int n, int m) {
01201 int increment,i,j,k;
01202 float *t;
01203
01204 t = cpl_malloc(m*sizeof(*t));
01205
01206 increment = n/2;
01207 while (increment > 0) {
01208 for (i = increment; i < n; i++) {
01209 j = i;
01210 for (k = 0; k < m; k++)
01211 t[k] = a[k][i];
01212 while ((j >= increment) && (a[0][j-increment] > t[0])) {
01213 for (k = 0; k < m; k++)
01214 a[k][j] = a[k][j-increment];
01215 j = j - increment;
01216 }
01217 for (k = 0; k < m; k++)
01218 a[k][j] = t[k];
01219 }
01220 if (increment == 2)
01221 increment = 1;
01222 else
01223 increment = (int)((float)increment/2.2);
01224 }
01225 cpl_free(t);
01226 }
01227
01228
01245
01246
01247 extern long vircam_getnpts(cpl_image *in) {
01248 int nx,ny;
01249 long npts;
01250 const char *fctid = "vircam_getnpts";
01251
01252 if ((nx = (int)cpl_image_get_size_x(in)) == -1) {
01253 cpl_msg_error(fctid,"NULL image input");
01254 return(0);
01255 }
01256 if ((ny = (int)cpl_image_get_size_y(in)) == -1) {
01257 cpl_msg_error(fctid,"NULL image input");
01258 return(0);
01259 }
01260 npts = (long)nx*ny;
01261 return(npts);
01262 }
01263
01264
01295
01296
01297 extern int vircam_fndmatch(float x, float y, float *xlist, float *ylist,
01298 int nlist, float err) {
01299 int isp,ifp,indx,i;
01300 float errsq,errmin,dx,dy,poserr;
01301
01302
01303
01304 isp = 0;
01305 ifp = nlist - 1;
01306 errsq = err*err;
01307 indx = (isp + ifp)/2;
01308 while (ifp-isp >= 2) {
01309 if (ylist[indx] < y - err) {
01310 isp = indx;
01311 indx = (indx+ifp)/2;
01312 } else if (ylist[indx] > y - err) {
01313 ifp = indx;
01314 indx = (indx+isp)/2;
01315 } else {
01316 isp = indx;
01317 break;
01318 }
01319 }
01320
01321
01322
01323 indx = -1;
01324 errmin = errsq;
01325 for (i = isp; i < nlist; i++) {
01326 if (ylist[i] > y+err)
01327 break;
01328 dx = x - xlist[i];
01329 dy = y - ylist[i];
01330 poserr = dx*dx + dy*dy;
01331 if (poserr < errsq) {
01332 if (poserr <= errmin) {
01333 indx = i;
01334 errmin = poserr;
01335 }
01336 }
01337 }
01338 return(indx);
01339 }
01340
01341
01360
01361
01362 extern int *vircam_dummy_confidence(long n) {
01363 int *cdata,i;
01364
01365 cdata = cpl_malloc(n*sizeof(*cdata));
01366 for (i = 0; i < n; i++)
01367 cdata[i] = 100;
01368 return(cdata);
01369 }
01370
01371
01394
01395
01396 extern int vircam_compare_dims(cpl_image *im1, cpl_image *im2) {
01397
01398 if (cpl_image_get_size_x(im1) != cpl_image_get_size_x(im2) ||
01399 cpl_image_get_size_y(im1) != cpl_image_get_size_y(im2))
01400 return(VIR_FATAL);
01401 else
01402 return(VIR_OK);
01403 }
01404
01405
01426
01427
01428 extern void vircam_prov(cpl_propertylist *p, vir_fits **inlist, int n) {
01429 int i;
01430 char keyword[SZKEY],value[SZVAL],*fn,*base;
01431
01432
01433
01434 cpl_propertylist_erase_regexp(p,"ESO DRS PROV*",0);
01435
01436
01437
01438 for (i = 0; i < n; i++) {
01439 (void)snprintf(keyword,SZKEY,"ESO DRS PROV%04d",i+1);
01440 fn = cpl_strdup(vircam_fits_get_fullname(inlist[i]));
01441 base = basename(fn);
01442 (void)snprintf(value,SZVAL,"%s",base);
01443 cpl_free(fn);
01444 cpl_propertylist_update_string(p,keyword,value);
01445 (void)snprintf(value,SZVAL,"Input file # %d",i+1);
01446 cpl_propertylist_set_comment(p,keyword,value);
01447 }
01448 }
01449
01450
01468
01469
01470 extern void vircam_merge_propertylists(cpl_propertylist *p1,
01471 cpl_propertylist *p2) {
01472 int i;
01473 const char *name;
01474
01475
01476
01477 if (p1 == NULL || p2 == NULL)
01478 return;
01479
01480
01481
01482
01483
01484 for (i = 0; i < cpl_propertylist_get_size(p2); i++) {
01485 name = cpl_property_get_name(cpl_propertylist_get(p2,i));
01486 if (cpl_propertylist_has(p1,name))
01487 cpl_propertylist_erase(p1,name);
01488 }
01489 cpl_propertylist_append(p1,p2);
01490
01491 }
01492
01493
01494
01495
01514
01515
01516 extern void vircam_dummy_property(cpl_propertylist *p) {
01517
01518
01519
01520 if (p == NULL)
01521 return;
01522
01523
01524
01525 cpl_propertylist_update_bool(p,"ESO DRS IMADUMMY",TRUE);
01526 cpl_propertylist_set_comment(p,"ESO DRS IMADUMMY",
01527 "This is a dummy product");
01528 return;
01529 }
01530
01531
01547
01548
01549 extern int vircam_is_dummy(cpl_propertylist *p) {
01550
01551
01552
01553 if (p == NULL)
01554 return(0);
01555
01556
01557
01558 return(cpl_propertylist_has(p,"ESO DRS IMADUMMY"));
01559 }
01560
01561
01599
01600
01601 extern void vircam_overexp(vir_fits **fitslist, int *n, int ndit, float lthr,
01602 float hthr, int ditch, float *minv, float *maxv,
01603 float *avev) {
01604 int i,m;
01605 cpl_image *im;
01606 double val,dndit,sum;
01607
01608
01609
01610 dndit = (double)ndit;
01611 m = 0;
01612 *minv = 1.0e10;
01613 *maxv = -1.0e10;
01614 sum = 0.0;
01615 for (i = 0; i < *n; i++) {
01616 im = vircam_fits_get_image(fitslist[i]);
01617 val = cpl_image_get_median_window(im,500,500,1000,1000);
01618 val /= ndit;
01619 *minv = min(*minv,val);
01620 *maxv = max(*maxv,val);
01621 sum += val;
01622 if (val > lthr && val < hthr) {
01623 fitslist[m++] = fitslist[i];
01624 } else {
01625 if (ditch)
01626 vircam_fits_delete(fitslist[i]);
01627 }
01628 }
01629 for (i = m; i < *n; i++)
01630 fitslist[i] = NULL;
01631 *avev = sum/(double)*n;
01632 *n = m;
01633 }
01634
01635
01652
01653
01654 extern cpl_image *vircam_dummy_image(vir_fits *model) {
01655 cpl_image *im;
01656
01657
01658
01659 im = cpl_image_duplicate(vircam_fits_get_image(model));
01660
01661
01662
01663 cpl_image_multiply_scalar(im,0.0);
01664
01665
01666
01667 return(im);
01668 }
01669
01670
01687
01688
01689 extern cpl_table *vircam_dummy_catalogue(int type) {
01690
01691 cattype = type;
01692 tabinit(NULL);
01693 return(tab);
01694 }
01695
01696
01697
01714
01715
01716 extern cpl_table *vircam_illcor_newtab(int nrows) {
01717 cpl_table *illcor;
01718 int i;
01719
01720
01721
01722 illcor = cpl_table_new((cpl_size)nrows);
01723 for (i = 0; i < NI_COLS; i++)
01724 cpl_table_new_column(illcor,illcor_cols[i],CPL_TYPE_FLOAT);
01725 return(illcor);
01726 }
01727
01728
01752
01753
01754 extern void vircam_timestamp(char *out, int n) {
01755 struct timeval tv;
01756 struct tm *tm;
01757 float sec;
01758
01759
01760
01761 (void)gettimeofday(&tv,NULL);
01762 tm = gmtime(&(tv.tv_sec));
01763 sec = (float)tm->tm_sec + 1.0e-6*(float)tv.tv_usec;
01764
01765
01766
01767 (void)snprintf(out,n,"%04d-%02d-%02dT%02d:%02d:%07.4f",1900+tm->tm_year,
01768 tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,sec);
01769 }
01770
01771
01800
01801
01802 extern void vircam_backmap(vir_fits *in, vir_mask *mask, int nbsize,
01803 cpl_image **out, float *med) {
01804 int i,j,nx,ny,ifracx,ifracy,nbsizx,nbsizy,nbx,nby,*nps,jx,jy;
01805 int jy1,jy2,np,nout,jyp1,jxp1,jz1,jz2,jz3,jz4,nbsize2;
01806 float fracx,fracy,*bmap,**rowpoints,*data,*ptr,dely,delx,t1,t2;
01807 unsigned char *bpm;
01808
01809
01810
01811 nx = (int)cpl_image_get_size_x(vircam_fits_get_image(in));
01812 ny = (int)cpl_image_get_size_y(vircam_fits_get_image(in));
01813 fracx = ((float)nx)/((float)nbsize);
01814 fracy = ((float)ny)/((float)nbsize);
01815 ifracx = (int)(fracx + 0.1);
01816 ifracy = (int)(fracy + 0.1);
01817 nbsizx = nx/ifracx;
01818 nbsizy = ny/ifracy;
01819 nbsize = max(vircam_nint(0.9*nbsize),min(nbsize,min(nbsizx,nbsizy)));
01820 nbsize = min(nx,min(ny,nbsize));
01821 nbsize2 = nbsize/2;
01822
01823
01824
01825 nbx = nx/nbsize;
01826 nby = ny/nbsize;
01827
01828
01829
01830 bmap = cpl_malloc(nbx*nby*sizeof(float));
01831 rowpoints = cpl_malloc(nbx*sizeof(float *));
01832 nps = cpl_malloc(nbx*sizeof(int));
01833
01834
01835
01836 data = cpl_image_get_data_float(vircam_fits_get_image(in));
01837 bpm = vircam_mask_get_data(mask);
01838
01839
01840
01841 *med = vircam_med(data,bpm,(long)(nx*ny));
01842
01843
01844
01845
01846
01847 for (i = 0; i < nbx; i++)
01848 rowpoints[i] = cpl_malloc(nbsize*nbsize*sizeof(float));
01849
01850
01851
01852
01853 for (jy = 0; jy < nby; jy++) {
01854 jy1 = jy*nbsize;
01855 jy2 = min((jy+1)*nbsize - 1,ny-1);
01856
01857
01858
01859 for (jx = 0; jx < nbx; jx++)
01860 nps[jx] = 0;
01861
01862
01863
01864
01865
01866 for (j = jy1; j <= jy2; j++) {
01867 for (i = 0; i < nx; i++) {
01868 jx = min(nbx-1,i/nbsize);
01869 if (bpm[j*nx + i] == 0) {
01870 ptr = rowpoints[jx];
01871 np = nps[jx];
01872 ptr[np++] = data[j*nx + i];
01873 nps[jx] = np;
01874 }
01875 }
01876 }
01877
01878
01879
01880 for (jx = 0; jx < nbx; jx++) {
01881 bmap[jy*nbx+jx] = vircam_med(rowpoints[jx],NULL,(long)(nps[jx]));
01882 if (bmap[jy*nbx+jx] != CX_MAXFLOAT) {
01883 bmap[jy*nbx+jx] -= *med;
01884 } else {
01885 bmap[jy*nbx+jx] = 0.0;
01886 }
01887 }
01888 }
01889
01890
01891
01892 for (jx = 0; jx < nbx; jx++)
01893 freespace(rowpoints[jx]);
01894 freespace(rowpoints);
01895 freespace(nps);
01896
01897
01898
01899 *out = cpl_image_new((cpl_size)nx,(cpl_size)ny,CPL_TYPE_FLOAT);
01900 ptr = cpl_image_get_data_float(*out);
01901
01902
01903
01904
01905 nout = 0;
01906 for (j = 1; j <= ny; j++) {
01907 jy = (j + nbsize2)/nbsize;
01908 jyp1 = jy + 1;
01909 jy = min(nby,max(1,jy));
01910 jyp1 = min(nby,jyp1);
01911 dely = (float)(j - nbsize*jy + nbsize2)/(float)nbsize;
01912 dely = max(0.0,min(1.0,dely));
01913 for (i = 1; i <= nx; i++) {
01914 jx = (i + nbsize2)/nbsize;
01915 jxp1 = jx + 1;
01916 jx = min(nbx,max(1,jx));
01917 jxp1 = min(nbx,jxp1);
01918 delx = (float)(i - nbsize*jx + nbsize2)/(float)nbsize;
01919 delx = max(0.0,min(1.0,delx));
01920 jz1 = (jy - 1)*nbx + jx;
01921 jz2 = (jyp1 - 1)*nbx + jx;
01922 if (jx == nbx) {
01923 jz3 = jz1;
01924 jz4 = jz2;
01925 } else {
01926 jz3 = jz1 + 1;
01927 jz4 = jz2 + 1;
01928 }
01929 t1 = (1.0 - delx)*bmap[jz1-1] + delx*bmap[jz3-1];
01930 t2 = (1.0 - delx)*bmap[jz2-1] + delx*bmap[jz4-1];
01931 ptr[nout++] = (1.0 - dely)*t1 + dely*t2;
01932 }
01933 }
01934
01935
01936
01937 freespace(bmap)
01938 }
01939
01940
01961
01962
01963 extern int vircam_findcol(cpl_propertylist *p, const char *col) {
01964
01965 if (!strcmp(col,"X")) {
01966 if (cpl_propertylist_has(p,"ESO DRS XCOL"))
01967 return(cpl_propertylist_get_int(p,"ESO DRS XCOL"));
01968 else
01969 return(-1);
01970 } else if (!strcmp(col,"Y")) {
01971 if (cpl_propertylist_has(p,"ESO DRS YCOL"))
01972 return(cpl_propertylist_get_int(p,"ESO DRS YCOL"));
01973 else
01974 return(-1);
01975 }
01976 return(-1);
01977 }
01978
01979
02000
02001
02002 extern void vircam_rename_property(cpl_propertylist *p, const char *oldname,
02003 char *newname) {
02004 cpl_propertylist *temp;
02005 cpl_property *property;
02006
02007
02008
02009
02010
02011
02012 if (! cpl_propertylist_has(p,oldname))
02013 return;
02014 temp = cpl_propertylist_new();
02015 cpl_propertylist_copy_property(temp,p,oldname);
02016 property = cpl_propertylist_get(temp,0);
02017
02018
02019
02020 cpl_property_set_name(property,newname);
02021
02022
02023
02024 cpl_propertylist_append(p,temp);
02025 cpl_propertylist_erase(p,oldname);
02026 cpl_propertylist_delete(temp);
02027 }
02028
02029
02057
02058
02059 extern int vircam_catpars(cpl_frame *indx, char **catpath, char **catname) {
02060 cpl_propertylist *p;
02061 char *fname;
02062 int status;
02063 const char *fctid = "vircam_catpars",*unk = "unknown";
02064
02065
02066
02067 *catpath = NULL;
02068 *catname = NULL;
02069
02070
02071
02072 fname = cpl_strdup(cpl_frame_get_filename(indx));
02073 if (access((const char *)fname,R_OK) != 0) {
02074 cpl_msg_error(fctid,"Can't access index file %s",fname);
02075 cpl_free(fname);
02076 return(VIR_FATAL);
02077 }
02078 *catpath = cpl_strdup(dirname(fname));
02079
02080
02081
02082
02083 if ((p = cpl_propertylist_load(cpl_frame_get_filename(indx),0)) == NULL) {
02084 freespace(*catpath);
02085 cpl_msg_error(fctid,"Can't load index file header %s",
02086 cpl_frame_get_filename(indx));
02087 cpl_free(fname);
02088 return(VIR_FATAL);
02089 }
02090
02091
02092
02093
02094 if (cpl_propertylist_has(p,"CATNAME")) {
02095 *catname = cpl_strdup(cpl_propertylist_get_string(p,"CATNAME"));
02096 status = VIR_OK;
02097 } else {
02098 *catname = cpl_strdup(unk);
02099 cpl_msg_warning(fctid,"Property CATNAME not in index file header %s",
02100 cpl_frame_get_filename(indx));
02101 status = VIR_WARN;
02102 }
02103 cpl_free(fname);
02104 freepropertylist(p);
02105
02106
02107
02108 return(status);
02109 }
02110
02111
02142
02143
02144 extern int vircam_gaincor_calc(cpl_frame *frame, int *n, float **cors,
02145 int *status) {
02146 float sum,val;
02147 int i,ngood;
02148 unsigned char *iflag;
02149 cpl_propertylist *p;
02150
02151
02152
02153 if (*status != VIR_OK)
02154 return(*status);
02155
02156
02157
02158
02159
02160 *n = cpl_frame_get_nextensions(frame);
02161 *cors = cpl_malloc(*n*sizeof(float));
02162 iflag = cpl_calloc(*n,sizeof(iflag));
02163
02164
02165
02166 sum = 0.0;
02167 ngood = 0;
02168 for (i = 0; i < *n; i++) {
02169 p = cpl_propertylist_load(cpl_frame_get_filename(frame),(cpl_size)(i+1));
02170 if (cpl_propertylist_has(p,"ESO DRS IMADUMMY")) {
02171 iflag[i] = 1;
02172 } else if (! cpl_propertylist_has(p,"ESO DRS MEDFLAT")) {
02173 iflag[i] = 1;
02174 } else {
02175 val = cpl_propertylist_get_double(p,"ESO DRS MEDFLAT");
02176 if (val == 0.0) {
02177 iflag[i] = 1;
02178 } else {
02179 sum += val;
02180 (*cors)[i] = val;
02181 ngood++;
02182 }
02183 }
02184 cpl_propertylist_delete(p);
02185 }
02186
02187
02188
02189
02190
02191
02192 if (ngood > 0)
02193 sum /= (float)ngood;
02194 for (i = 0; i < *n; i++) {
02195 if (iflag[i] == 0) {
02196 (*cors)[i] = sum/(*cors)[i];
02197 } else {
02198 (*cors)[i] = 1.0;
02199 }
02200 }
02201 cpl_free(iflag);
02202
02203
02204
02205 GOOD_STATUS
02206 }
02207
02208
02234
02235
02236 extern int vircam_check_crval(cpl_propertylist *phu, cpl_propertylist *ehu) {
02237 double crval1,crval2;
02238 cpl_property *p;
02239
02240
02241
02242
02243 if ((vircam_pfits_get_crval1(ehu,&crval1) != VIR_OK) ||
02244 (vircam_pfits_get_crval2(ehu,&crval2) != VIR_OK))
02245 return(VIR_FATAL);
02246
02247
02248
02249
02250
02251
02252
02253
02254
02255 if (fabs(crval1) < 1.0e-6 && fabs(crval2) < 1.0e-6) {
02256 if ((vircam_pfits_get_ra(phu,&crval1) != VIR_OK) ||
02257 (vircam_pfits_get_dec(phu,&crval2) != VIR_OK))
02258 return(VIR_FATAL);
02259 p = cpl_propertylist_get_property(ehu,"CRVAL1");
02260 cpl_property_set_name(p,"OLDCR1");
02261 p = cpl_propertylist_get_property(ehu,"CRVAL2");
02262 cpl_property_set_name(p,"OLDCR2");
02263 cpl_propertylist_insert_after_double(ehu,"OLDCR2","CRVAL1",crval1);
02264 cpl_propertylist_insert_after_double(ehu,"CRVAL1","CRVAL2",crval2);
02265 cpl_propertylist_erase(ehu,"OLDCR1");
02266 cpl_propertylist_erase(ehu,"OLDCR2");
02267 }
02268
02269
02270
02271 return(VIR_OK);
02272 }
02273
02276
02277
02278
02279
02280
02281
02282
02283
02284
02285
02286
02287
02288
02289
02290
02291
02292
02293
02294
02295
02296
02297
02298
02299
02300
02301
02302
02303
02304
02305
02306
02307
02308
02309
02310
02311
02312
02313
02314
02315
02316
02317
02318
02319
02320
02321
02322
02323
02324
02325
02326
02327
02328
02329
02330
02331
02332
02333
02334
02335
02336
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350
02351
02352
02353
02354
02355
02356
02357
02358
02359
02360
02361
02362
02363
02364
02365
02366
02367
02368
02369
02370
02371
02372
02373
02374
02375
02376
02377
02378
02379
02380
02381
02382
02383
02384
02385
02386
02387
02388
02389
02390
02391
02392
02393
02394
02395
02396
02397
02398
02399
02400
02401
02402
02403
02404
02405
02406
02407
02408
02409
02410
02411
02412
02413
02414
02415
02416
02417
02418
02419
02420
02421
02422
02423
02424
02425
02426
02427
02428
02429
02430
02431
02432
02433
02434
02435
02436
02437
02438
02439
02440
02441
02442
02443
02444
02445
02446
02447
02448
02449
02450
02451
02452
02453
02454
02455
02456
02457
02458
02459
02460
02461
02462
02463
02464
02465
02466
02467
02468
02469
02470
02471
02472
02473
02474
02475
02476
02477
02478
02479
02480
02481
02482
02483
02484
02485
02486
02487
02488
02489
02490
02491
02492
02493
02494
02495
02496
02497
02498
02499
02500
02501
02502
02503
02504
02505
02506
02507
02508
02509
02510
02511
02512
02513
02514
02515
02516
02517
02518
02519
02520