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 int *labels, int 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 ret_set = NULL;
00202 for (i = 0; i < nlab; i++) {
00203 cur_set = cpl_frameset_extract(frameset,labels,i);
00204 if (cur_set == NULL)
00205 break;
00206 cur_frame = cpl_frameset_get_frame(cur_set,0);
00207 cur_tag = (char *)cpl_frame_get_tag(cur_frame);
00208 if (!strcmp(cur_tag,tag)) {
00209 ret_set = cur_set;
00210 break;
00211 }
00212 cpl_frameset_delete(cur_set);
00213 }
00214 return(ret_set);
00215 }
00216
00217
00244
00245
00246 extern cpl_frame *vircam_frameset_subgroup_1(cpl_frameset *frameset,
00247 int *labels, int nlab,
00248 const char *tag) {
00249 cpl_frameset *cur_set;
00250 cpl_frame *cur_frame,*new_frame;
00251
00252 if ((cur_set = vircam_frameset_subgroup(frameset,labels,nlab,tag)) == NULL) {
00253 return(NULL);
00254 } else {
00255 cur_frame = cpl_frameset_get_frame(cur_set,0);
00256 new_frame = cpl_frame_duplicate(cur_frame);
00257 cpl_frameset_delete(cur_set);
00258 return(new_frame);
00259 }
00260 }
00261
00262
00282
00283
00284 extern int vircam_frameset_fexists (cpl_frameset *frameset) {
00285 int nf,i,nerr;
00286 cpl_frame *cur;
00287 const char *fname;
00288 const char *fctid = "vircam_frameset_fexists";
00289
00290
00291
00292 if (frameset == NULL) {
00293 cpl_msg_error(fctid,"Input frameset is NULL");
00294 return(VIR_FATAL);
00295 }
00296
00297
00298
00299 nf = cpl_frameset_get_size(frameset);
00300 if (nf == 0) {
00301 cpl_msg_error(fctid,"Input frameset has size of zero");
00302 return(VIR_FATAL);
00303 }
00304
00305
00306
00307 nerr = 0;
00308 for (i = 0; i < nf; i++) {
00309 cur = cpl_frameset_get_frame(frameset,i);
00310 fname = cpl_frame_get_filename(cur);
00311 if (access(fname,F_OK) != 0) {
00312 cpl_msg_error(fctid,"File: %s doesn't exist",fname);
00313 nerr++;
00314 }
00315 }
00316
00317
00318
00319 if (nerr != 0)
00320 return(VIR_FATAL);
00321 else
00322 return(VIR_OK);
00323 }
00324
00325
00350
00351
00352 extern void vircam_exten_range(int inexten, const cpl_frame *fr, int *out1,
00353 int *out2) {
00354 int nvircam = 16,n,nmax;
00355 const char *fctid = "vircam_exten_range";
00356
00357
00358
00359 n = cpl_frame_get_nextensions(fr);
00360
00361
00362
00363
00364 if (n < nvircam) {
00365 cpl_msg_warning(fctid,"Only %d extensions out of %d are present",
00366 n,nvircam);
00367 nmax = n;
00368 } else {
00369 nmax = nvircam;
00370 }
00371
00372
00373
00374
00375 if (inexten == 0) {
00376 *out1 = 1;
00377 *out2 = nmax;
00378
00379
00380
00381 } else {
00382
00383 if (inexten > nmax) {
00384 cpl_msg_error(fctid,"Requested extension %d is not present",
00385 inexten);
00386 *out1 = -1;
00387 *out2 = -1;
00388 } else {
00389 *out1 = inexten;
00390 *out2 = inexten;
00391 }
00392 }
00393 return;
00394 }
00395
00396
00422
00423
00424 extern void vircam_madfit(int npts, float *xdata, float *ydata,
00425 float *intercept, float *slope) {
00426 int j;
00427 float sx,sy,sxx,sxy,det,aa,bb,temp,chisq,sigb,b1,f1,b2,f2,f;
00428
00429
00430
00431 sx = 0.0;
00432 sy = 0.0;
00433 sxx = 0.0;
00434 sxy = 0.0;
00435 for (j = 0; j < npts; j++) {
00436 sx += xdata[j];
00437 sy += ydata[j];
00438 sxx += xdata[j]*xdata[j];
00439 sxy += xdata[j]*ydata[j];
00440 }
00441 det = (float)npts*sxx - sx*sx;
00442 if (det == 0.0) {
00443 *slope = 0.0;
00444 *intercept = 0.0;
00445 return;
00446 }
00447 aa = (sxx*sy - sx*sxy)/det;
00448 bb = ((float)npts*sxy - sx*sy)/det;
00449 chisq = 0.0;
00450 for (j = 0; j < npts; j++) {
00451 temp = ydata[j] - (aa + bb*xdata[j]);
00452 chisq += temp*temp;
00453 }
00454 sigb = sqrt(chisq/det);
00455 if (sigb == 0.0) {
00456 *slope = bb;
00457 *intercept = aa;
00458 return;
00459 }
00460
00461
00462
00463 b1 = bb;
00464 f1 = madfunc(npts,xdata,ydata,b1);
00465 b2 = bb + ((f1 > 0.0) ? fabs(3.0*sigb) : -fabs(3.0*sigb));
00466 f2 = madfunc(npts,xdata,ydata,b2);
00467 while (f1*f2 > 0.0) {
00468 bb = 2.0*b2 - b1;
00469 b1 = b2;
00470 f1 = f2;
00471 b2 = bb;
00472 f2 = madfunc(npts,xdata,ydata,b2);
00473 }
00474
00475
00476
00477 sigb = 0.01*sigb;
00478 while (fabs(b2 - b1) > sigb) {
00479 bb = 0.5*(b1 + b2);
00480 if (bb == b1 || bb == b2)
00481 break;
00482 f = madfunc(npts,xdata,ydata,bb);
00483 if (f*f1 >= 0.0) {
00484 f1 = f;
00485 b1 = bb;
00486 } else {
00487 f2 = f;
00488 b2 = bb;
00489 }
00490 }
00491 *intercept = aa;
00492 *slope = bb;
00493 }
00494
00495
00518
00519
00520
00521 static float madfunc(int npts, float *xt, float *yt, float b) {
00522 float *arr,aa,d,sum;
00523 int j;
00524
00525 arr = cpl_malloc(npts*sizeof(*arr));
00526 for (j = 0; j < npts; j++)
00527 arr[j] = yt[j] - b*xt[j];
00528 aa = vircam_med(arr,NULL,(long)npts);
00529 sum = 0.0;
00530 for (j = 0; j < npts; j++) {
00531 d = yt[j] - (b*xt[j] + aa);
00532 sum += d > 0.0 ? xt[j] : -xt[j];
00533 }
00534 cpl_free(arr);
00535 return(sum);
00536 }
00537
00538
00565
00566
00567 extern void vircam_linfit(int npts, double *xdata, double *ydata,
00568 double *intercept, double *slope, double *sig) {
00569 int j;
00570 double sx,sy,sxx,sxy,det,aa,bb,temp,sum,sumsq;
00571
00572
00573
00574 sx = 0.0;
00575 sy = 0.0;
00576 sxx = 0.0;
00577 sxy = 0.0;
00578 for (j = 0; j < npts; j++) {
00579 sx += xdata[j];
00580 sy += ydata[j];
00581 sxx += xdata[j]*xdata[j];
00582 sxy += xdata[j]*ydata[j];
00583 }
00584 det = (double)npts*sxx - sx*sx;
00585 if (det == 0.0) {
00586 *slope = 0.0;
00587 *intercept = 0.0;
00588 *sig = 0.0;
00589 return;
00590 }
00591
00592
00593
00594 aa = (sxx*sy - sx*sxy)/det;
00595 bb = ((double)npts*sxy - sx*sy)/det;
00596
00597
00598
00599 sum = 0.0;
00600 sumsq = 0.0;
00601 for (j = 0; j < npts; j++) {
00602 temp = ydata[j] - (aa + bb*xdata[j]);
00603 sum += temp;
00604 sumsq += temp*temp;
00605 }
00606 sum /= (double)npts;
00607
00608
00609
00610 *sig = sqrt(sumsq/(double)npts - sum*sum);
00611 *slope = bb;
00612 *intercept = aa;
00613 }
00614
00615
00639
00640
00641 extern int vircam_solve_gauss(double **a, double *b, int m) {
00642 double temp,big,pivot,rmax;
00643 int i,iu,j,k,jl,ib,ir;
00644 int l = 0;
00645
00646 iu = m - 1;
00647 for (i = 0; i < iu; i++) {
00648 big = 0.0;
00649
00650
00651
00652 for (k = i; k < m; k++) {
00653 rmax = fabs(a[i][k]);
00654 if (rmax > big) {
00655 big = rmax;
00656 l = k;
00657 }
00658 }
00659
00660
00661
00662 if (big == 0.0) {
00663 for (ib = 0; ib < m; ib++)
00664 b[ib] = 0.0;
00665 cpl_msg_error("vircam_solve_gauss","Zero Determinant\n");
00666 return(VIR_FATAL);
00667 }
00668
00669 if (i != l) {
00670
00671
00672
00673 for (j = 0; j < m; j++) {
00674 temp = a[j][i];
00675 a[j][i] = a[j][l];
00676 a[j][l] = temp;
00677 }
00678 temp = b[i];
00679 b[i] = b[l];
00680 b[l] = temp;
00681 }
00682
00683
00684
00685
00686 pivot = a[i][i];
00687 jl = i+1;
00688
00689 for (j = jl; j < m; j++) {
00690 temp = a[i][j]/pivot;
00691 b[j] -= temp*b[i];
00692 for (k = i; k < m; k++)
00693 a[k][j] -= temp*a[k][i];
00694 }
00695 }
00696
00697
00698
00699 for (i = 0; i < m; i++) {
00700 ir = m - 1 - i;
00701 if (a[ir][ir] != 0.0) {
00702 temp = b[ir];
00703 if (ir != m - 1) {
00704 for (j = 1; j <= i; j++) {
00705 k = m - j;
00706 temp -= a[k][ir]*b[k];
00707 }
00708 }
00709 b[ir] = temp/a[ir][ir];
00710 } else
00711 b[ir] = 0.0;
00712 }
00713 return(VIR_OK);
00714 }
00715
00716
00754
00755
00756 extern int vircam_polyfit(const cpl_array *xarray, const cpl_array *yarray,
00757 int ncoefs, int ilim, int niter, float lclip,
00758 float hclip, cpl_array **polycf, double *sigfit) {
00759 const char *fctid = "vircam_polyfit";
00760 int npts,iter,i,j,nnew,k,retval,n;
00761 double *xdata,*ydata,*pdata,*res,**a,*b,temp,sum,sumsq,val;
00762 double lcut,hcut;
00763 unsigned char *pm;
00764
00765
00766
00767 *polycf = NULL;
00768 *sigfit = -1.0;
00769
00770
00771
00772 npts = cpl_array_get_size(xarray);
00773
00774
00775
00776 if (npts < ncoefs) {
00777 cpl_msg_warning(fctid,"Not data for fit, Npts = %d, Ncoefs = %d",
00778 npts,ncoefs);
00779 return(VIR_FATAL);
00780 }
00781
00782
00783
00784 a = cpl_malloc(ncoefs*sizeof(double *));
00785 b = cpl_calloc(ncoefs,sizeof(double));
00786 for (i = 0; i < ncoefs; i++)
00787 a[i] = cpl_calloc(ncoefs,sizeof(double));
00788 pm = cpl_calloc(npts,sizeof(unsigned char));
00789 res = cpl_malloc(npts*sizeof(double));
00790
00791
00792
00793 xdata = (double *)cpl_array_get_data_double_const(xarray);
00794 ydata = (double *)cpl_array_get_data_double_const(yarray);
00795
00796
00797
00798 *polycf = cpl_array_new(ncoefs,CPL_TYPE_DOUBLE);
00799 pdata = cpl_array_get_data_double(*polycf);
00800
00801
00802
00803 for (iter = 0; iter <= niter; iter++) {
00804
00805
00806
00807 for (i = 0; i < ncoefs; i++) {
00808 for (j = 0; j < ncoefs; j++)
00809 a[i][j] = 0.0;
00810 b[i] = 0.0;
00811 }
00812 nnew = 0;
00813
00814
00815
00816 for (i = 0; i < npts; i++) {
00817 if (pm[i] == 1)
00818 continue;
00819 for (k = 0; k < ncoefs; k++) {
00820 temp = 1.0;
00821 if (k + ilim != 0)
00822 temp = pow(xdata[i],(double)(k+ilim));
00823 b[k] += ydata[i]*temp;
00824 for (j = 0; j <= k; j++) {
00825 temp = 1.0;
00826 if (k + j + 2*ilim != 0)
00827 temp = pow(xdata[i],(double)(k+j+2*ilim));
00828 a[j][k] += temp;
00829 }
00830 }
00831 }
00832 for (k = 1; k < ncoefs; k++)
00833 for (j = 0; j < k; j++)
00834 a[k][j] = a[j][k];
00835
00836
00837
00838 retval = vircam_solve_gauss(a,b,ncoefs);
00839 if (retval != VIR_OK) {
00840 cpl_msg_warning(fctid,"Fit failed");
00841 freearray(*polycf);
00842 freespace2(a,ncoefs);
00843 freespace(b);
00844 freespace(pm);
00845 freespace(res);
00846 return(VIR_FATAL);
00847 }
00848
00849
00850
00851 for (i = 0; i < ncoefs; i++)
00852 pdata[i] = b[i];
00853
00854
00855
00856 sum = 0.0;
00857 sumsq = 0.0;
00858 n = 0;
00859 for (i = 0; i < npts; i++) {
00860 if (pm[i] == 1)
00861 continue;
00862 val = 0.0;
00863 for (j = 0; j < ncoefs; j++)
00864 val += pdata[j]*pow(xdata[i],(double)j+ilim);
00865 res[i] = val - ydata[i];
00866 sum += res[i];
00867 sumsq += pow(res[i],2.0);
00868 n++;
00869 }
00870 sum /= (double)n;
00871 *sigfit = sqrt(sumsq/(double)n - sum*sum);
00872
00873
00874
00875 lcut = sum - lclip*(*sigfit);
00876 hcut = sum + hclip*(*sigfit);
00877 if (iter < niter) {
00878 for (i = 0; i < npts; i++) {
00879 if (pm[i] == 1)
00880 continue;
00881 if (res[i] > hcut || res[i] < lcut) {
00882 nnew++;
00883 pm[i] = 1;
00884 }
00885 }
00886 }
00887
00888
00889
00890 if (nnew == 0)
00891 break;
00892 }
00893
00894
00895
00896 freespace2(a,ncoefs);
00897 freespace(b);
00898 freespace(pm);
00899 freespace(res);
00900 return(VIR_OK);
00901 }
00902
00903
00944
00945
00946 extern void vircam_difference_image(cpl_image *master, cpl_image *prog,
00947 unsigned char *bpm, cpl_table *chantab,
00948 int ncells, int oper, float *global_diff,
00949 float *global_rms, cpl_image **diffim,
00950 cpl_table **diffimstats) {
00951 float *ddata,*work,mean,sig,med,mad;
00952 long nx,ny,npts;
00953 int nrows,i,nc1,nc2,nr,ixmin,ixmax,iymin,iymax,cnum,cx,cy,idx,idy;
00954 int icx,icy,indy1,indy2,indx1,indx2,jp,jcx,jj,jcy,ii,ncx,ncy;
00955 const char *fctid = "vircam_difference_image";
00956
00957
00958
00959 *diffim = NULL;
00960 *diffimstats = NULL;
00961 *global_diff = 0.0;
00962 *global_rms = 0.0;
00963
00964
00965
00966 if (prog == NULL || master == NULL)
00967 return;
00968
00969
00970
00971 switch (oper) {
00972 case 1:
00973 *diffim = cpl_image_subtract_create(prog,master);
00974 break;
00975 case 2:
00976 *diffim = cpl_image_divide_create(prog,master);
00977 break;
00978 default:
00979 *diffim = NULL;
00980 cpl_msg_error(fctid,"Invalid operation requested %d",oper);
00981 break;
00982 }
00983 if (*diffim == NULL)
00984 return;
00985
00986
00987
00988 ddata = cpl_image_get_data_float(*diffim);
00989 nx = cpl_image_get_size_x(*diffim);
00990 ny = cpl_image_get_size_y(*diffim);
00991 npts = nx*ny;
00992 vircam_medmad(ddata,bpm,npts,global_diff,global_rms);
00993 *global_rms *= 1.48;
00994
00995
00996
00997 if (chantab == NULL)
00998 return;
00999
01000
01001
01002
01003 if (! cpl_table_has_column(chantab,"ixmin") ||
01004 ! cpl_table_has_column(chantab,"ixmax") ||
01005 ! cpl_table_has_column(chantab,"iymin") ||
01006 ! cpl_table_has_column(chantab,"iymax") ||
01007 ! cpl_table_has_column(chantab,"channum")) {
01008 cpl_msg_error(fctid,"Channel table is missing one of the required columns");
01009
01010 return;
01011 }
01012
01013
01014
01015 switch (ncells) {
01016 case 1:
01017 nc1 = 1;
01018 nc2 = 1;
01019 break;
01020 case 2:
01021 nc1 = 2;
01022 nc2 = 1;
01023 break;
01024 case 4:
01025 nc1 = 4;
01026 nc2 = 1;
01027 break;
01028 case 8:
01029 nc1 = 8;
01030 nc2 = 1;
01031 break;
01032 case 16:
01033 nc1 = 16;
01034 nc2 = 1;
01035 break;
01036 case 32:
01037 nc1 = 16;
01038 nc2 = 2;
01039 break;
01040 case 64:
01041 nc1 = 32;
01042 nc2 = 2;
01043 break;
01044 default:
01045 nc1 = 32;
01046 nc2 = 2;
01047 break;
01048 }
01049
01050
01051
01052 nrows = cpl_table_count_selected(chantab);
01053 *diffimstats = vircam_create_diffimg_stats(nrows*nc1*nc2);
01054
01055
01056
01057 nr = 0;
01058 for (i = 0; i < nrows; i++) {
01059 ixmin = cpl_table_get_int(chantab,"ixmin",i,NULL);
01060 ixmax = cpl_table_get_int(chantab,"ixmax",i,NULL);
01061 iymin = cpl_table_get_int(chantab,"iymin",i,NULL);
01062 iymax = cpl_table_get_int(chantab,"iymax",i,NULL);
01063 cnum = cpl_table_get_int(chantab,"channum",i,NULL);
01064
01065
01066
01067
01068
01069
01070 cx = ixmax - ixmin + 1;
01071 cy = iymax - iymin + 1;
01072 if (cx > cy) {
01073 ncx = max(nc1,nc2);
01074 ncy = min(nc1,nc2);
01075 } else if (cx < cy) {
01076 ncy = max(nc1,nc2);
01077 ncx = min(nc1,nc2);
01078 } else {
01079 ncx = max(nc1,nc2);
01080 ncy = min(nc1,nc2);
01081 }
01082
01083
01084
01085 idy = cy/ncy;
01086 idx = cx/ncx;
01087 work = cpl_malloc(idx*idy*sizeof(*work));
01088
01089
01090
01091 for (icy = 0; icy < ncy; icy++) {
01092 indy1 = idy*icy;
01093 indy2 = min(iymax,indy1+idy-1);
01094 for (icx = 0; icx < ncx; icx++) {
01095 indx1 = idx*icx;
01096 indx2 = min(ixmax,indx1+idx-1);
01097 jp = 0;
01098 for (jcy = indy1; jcy < indy2; jcy++) {
01099 jj = jcy*nx;
01100 for (jcx = indx1; jcx < indx2; jcx++) {
01101 ii = jj + jcx;
01102 if (bpm != NULL && bpm[ii] == 0)
01103 work[jp++] = ddata[ii];
01104 }
01105 }
01106 (void)vircam_meansig(work,NULL,(long)jp,&mean,&sig);
01107 (void)vircam_medmad(work,NULL,(long)jp,&med,&mad);
01108 cpl_table_set_int(*diffimstats,"xmin",nr,indx1+1);
01109 cpl_table_set_int(*diffimstats,"xmax",nr,indx2+1);
01110 cpl_table_set_int(*diffimstats,"ymin",nr,indy1+1);
01111 cpl_table_set_int(*diffimstats,"ymax",nr,indy2+1);
01112 cpl_table_set_int(*diffimstats,"chan",nr,cnum);
01113 cpl_table_set_float(*diffimstats,"mean",nr,mean);
01114 cpl_table_set_float(*diffimstats,"median",nr,med);
01115 cpl_table_set_float(*diffimstats,"variance",nr,(sig*sig));
01116 cpl_table_set_float(*diffimstats,"mad",nr++,mad);
01117 }
01118 }
01119 cpl_free(work);
01120 }
01121 }
01122
01123
01140
01141
01142 cpl_table *vircam_create_diffimg_stats(int nrows) {
01143 cpl_table *diffimstats;
01144
01145 diffimstats = cpl_table_new(nrows);
01146 cpl_table_new_column(diffimstats,"xmin",CPL_TYPE_INT);
01147 cpl_table_set_column_unit(diffimstats,"xmin","pixels");
01148 cpl_table_new_column(diffimstats,"xmax",CPL_TYPE_INT);
01149 cpl_table_set_column_unit(diffimstats,"xmax","pixels");
01150 cpl_table_new_column(diffimstats,"ymin",CPL_TYPE_INT);
01151 cpl_table_set_column_unit(diffimstats,"ymin","pixels");
01152 cpl_table_new_column(diffimstats,"ymax",CPL_TYPE_INT);
01153 cpl_table_set_column_unit(diffimstats,"ymax","pixels");
01154 cpl_table_new_column(diffimstats,"chan",CPL_TYPE_INT);
01155 cpl_table_set_column_unit(diffimstats,"chan","pixels");
01156 cpl_table_new_column(diffimstats,"mean",CPL_TYPE_FLOAT);
01157 cpl_table_set_column_unit(diffimstats,"mean","ADU");
01158 cpl_table_new_column(diffimstats,"median",CPL_TYPE_FLOAT);
01159 cpl_table_set_column_unit(diffimstats,"median","ADU");
01160 cpl_table_new_column(diffimstats,"variance",CPL_TYPE_FLOAT);
01161 cpl_table_set_column_unit(diffimstats,"variance","ADU**2");
01162 cpl_table_new_column(diffimstats,"mad",CPL_TYPE_FLOAT);
01163 cpl_table_set_column_unit(diffimstats,"mad","ADU");
01164 return(diffimstats);
01165 }
01166
01167
01168
01192
01193
01194 extern void vircam_sort(float **a, int n, int m) {
01195 int increment,i,j,k;
01196 float *t;
01197
01198 t = cpl_malloc(m*sizeof(*t));
01199
01200 increment = n/2;
01201 while (increment > 0) {
01202 for (i = increment; i < n; i++) {
01203 j = i;
01204 for (k = 0; k < m; k++)
01205 t[k] = a[k][i];
01206 while ((j >= increment) && (a[0][j-increment] > t[0])) {
01207 for (k = 0; k < m; k++)
01208 a[k][j] = a[k][j-increment];
01209 j = j - increment;
01210 }
01211 for (k = 0; k < m; k++)
01212 a[k][j] = t[k];
01213 }
01214 if (increment == 2)
01215 increment = 1;
01216 else
01217 increment = (int)((float)increment/2.2);
01218 }
01219 cpl_free(t);
01220 }
01221
01222
01239
01240
01241 extern long vircam_getnpts(cpl_image *in) {
01242 int nx,ny;
01243 long npts;
01244 const char *fctid = "vircam_getnpts";
01245
01246 if ((nx = cpl_image_get_size_x(in)) == -1) {
01247 cpl_msg_error(fctid,"NULL image input");
01248 return(0);
01249 }
01250 if ((ny = cpl_image_get_size_y(in)) == -1) {
01251 cpl_msg_error(fctid,"NULL image input");
01252 return(0);
01253 }
01254 npts = (long)nx*ny;
01255 return(npts);
01256 }
01257
01258
01289
01290
01291 extern int vircam_fndmatch(float x, float y, float *xlist, float *ylist,
01292 int nlist, float err) {
01293 int isp,ifp,indx,i;
01294 float errsq,errmin,dx,dy,poserr;
01295
01296
01297
01298 isp = 0;
01299 ifp = nlist - 1;
01300 errsq = err*err;
01301 indx = (isp + ifp)/2;
01302 while (ifp-isp >= 2) {
01303 if (ylist[indx] < y - err) {
01304 isp = indx;
01305 indx = (indx+ifp)/2;
01306 } else if (ylist[indx] > y - err) {
01307 ifp = indx;
01308 indx = (indx+isp)/2;
01309 } else {
01310 isp = indx;
01311 break;
01312 }
01313 }
01314
01315
01316
01317 indx = -1;
01318 errmin = errsq;
01319 for (i = isp; i < nlist; i++) {
01320 if (ylist[i] > y+err)
01321 break;
01322 dx = x - xlist[i];
01323 dy = y - ylist[i];
01324 poserr = dx*dx + dy*dy;
01325 if (poserr < errsq) {
01326 if (poserr <= errmin) {
01327 indx = i;
01328 errmin = poserr;
01329 }
01330 }
01331 }
01332 return(indx);
01333 }
01334
01335
01354
01355
01356 extern int *vircam_dummy_confidence(long n) {
01357 int *cdata,i;
01358
01359 cdata = cpl_malloc(n*sizeof(*cdata));
01360 for (i = 0; i < n; i++)
01361 cdata[i] = 100;
01362 return(cdata);
01363 }
01364
01365
01388
01389
01390 extern int vircam_compare_dims(cpl_image *im1, cpl_image *im2) {
01391
01392 if ((cpl_image_get_size_x(im1) != cpl_image_get_size_x(im2)) ||
01393 cpl_image_get_size_y(im1) != cpl_image_get_size_y(im2))
01394 return(VIR_FATAL);
01395 else
01396 return(VIR_OK);
01397 }
01398
01399
01420
01421
01422 extern void vircam_prov(cpl_propertylist *p, vir_fits **inlist, int n) {
01423 int i;
01424 char keyword[SZKEY],value[SZVAL],*fn,*base;
01425
01426
01427
01428 cpl_propertylist_erase_regexp(p,"ESO DRS PROV*",0);
01429
01430
01431
01432 for (i = 0; i < n; i++) {
01433 (void)snprintf(keyword,SZKEY,"ESO DRS PROV%04d",i+1);
01434 fn = cpl_strdup(vircam_fits_get_fullname(inlist[i]));
01435 base = basename(fn);
01436 (void)snprintf(value,SZVAL,"%s",base);
01437 cpl_free(fn);
01438 cpl_propertylist_update_string(p,keyword,value);
01439 (void)snprintf(value,SZVAL,"Input file # %d",i+1);
01440 cpl_propertylist_set_comment(p,keyword,value);
01441 }
01442 }
01443
01444
01462
01463
01464 extern void vircam_merge_propertylists(cpl_propertylist *p1,
01465 cpl_propertylist *p2) {
01466 int i;
01467 const char *name;
01468
01469
01470
01471 if (p1 == NULL || p2 == NULL)
01472 return;
01473
01474
01475
01476
01477
01478 for (i = 0; i < cpl_propertylist_get_size(p2); i++) {
01479 name = cpl_property_get_name(cpl_propertylist_get(p2,i));
01480 if (cpl_propertylist_has(p1,name))
01481 cpl_propertylist_erase(p1,name);
01482 }
01483 cpl_propertylist_append(p1,p2);
01484
01485 }
01486
01487
01488
01489
01508
01509
01510 extern void vircam_dummy_property(cpl_propertylist *p) {
01511
01512
01513
01514 if (p == NULL)
01515 return;
01516
01517
01518
01519 cpl_propertylist_update_bool(p,"ESO DRS IMADUMMY",TRUE);
01520 cpl_propertylist_set_comment(p,"ESO DRS IMADUMMY",
01521 "This is a dummy product");
01522 return;
01523 }
01524
01525
01541
01542
01543 extern int vircam_is_dummy(cpl_propertylist *p) {
01544
01545
01546
01547 if (p == NULL)
01548 return(0);
01549
01550
01551
01552 return(cpl_propertylist_has(p,"ESO DRS IMADUMMY"));
01553 }
01554
01555
01593
01594
01595 extern void vircam_overexp(vir_fits **fitslist, int *n, int ndit, float lthr,
01596 float hthr, int ditch, float *minv, float *maxv,
01597 float *avev) {
01598 int i,m;
01599 cpl_image *im;
01600 double val,dndit,sum;
01601
01602
01603
01604 dndit = (double)ndit;
01605 m = 0;
01606 *minv = 1.0e10;
01607 *maxv = -1.0e10;
01608 sum = 0.0;
01609 for (i = 0; i < *n; i++) {
01610 im = vircam_fits_get_image(fitslist[i]);
01611 val = cpl_image_get_median_window(im,500,500,1000,1000);
01612 val /= ndit;
01613 *minv = min(*minv,val);
01614 *maxv = max(*maxv,val);
01615 sum += val;
01616 if (val > lthr && val < hthr) {
01617 fitslist[m++] = fitslist[i];
01618 } else {
01619 if (ditch)
01620 vircam_fits_delete(fitslist[i]);
01621 }
01622 }
01623 for (i = m; i < *n; i++)
01624 fitslist[i] = NULL;
01625 *avev = sum/(double)*n;
01626 *n = m;
01627 }
01628
01629
01646
01647
01648 extern cpl_image *vircam_dummy_image(vir_fits *model) {
01649 cpl_image *im;
01650
01651
01652
01653 im = cpl_image_duplicate(vircam_fits_get_image(model));
01654
01655
01656
01657 cpl_image_multiply_scalar(im,0.0);
01658
01659
01660
01661 return(im);
01662 }
01663
01664
01681
01682
01683 extern cpl_table *vircam_dummy_catalogue(int type) {
01684
01685 cattype = type;
01686 tabinit(NULL);
01687 return(tab);
01688 }
01689
01690
01691
01708
01709
01710 extern cpl_table *vircam_illcor_newtab(int nrows) {
01711 cpl_table *illcor;
01712 int i;
01713
01714
01715
01716 illcor = cpl_table_new(nrows);
01717 for (i = 0; i < NI_COLS; i++)
01718 cpl_table_new_column(illcor,illcor_cols[i],CPL_TYPE_FLOAT);
01719 return(illcor);
01720 }
01721
01722
01746
01747
01748 extern void vircam_timestamp(char *out, int n) {
01749 struct timeval tv;
01750 struct tm *tm;
01751 float sec;
01752
01753
01754
01755 (void)gettimeofday(&tv,NULL);
01756 tm = gmtime(&(tv.tv_sec));
01757 sec = (float)tm->tm_sec + 1.0e-6*(float)tv.tv_usec;
01758
01759
01760
01761 (void)snprintf(out,n,"%04d-%02d-%02dT%02d:%02d:%07.4f",1900+tm->tm_year,
01762 tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,sec);
01763 }
01764
01765
01794
01795
01796 extern void vircam_backmap(vir_fits *in, vir_mask *mask, int nbsize,
01797 cpl_image **out, float *med) {
01798 int i,j,nx,ny,ifracx,ifracy,nbsizx,nbsizy,nbx,nby,*nps,jx,jy;
01799 int jy1,jy2,np,nout,jyp1,jxp1,jz1,jz2,jz3,jz4,nbsize2;
01800 float fracx,fracy,*bmap,**rowpoints,*data,*ptr,dely,delx,t1,t2;
01801 unsigned char *bpm;
01802
01803
01804
01805 nx = cpl_image_get_size_x(vircam_fits_get_image(in));
01806 ny = cpl_image_get_size_y(vircam_fits_get_image(in));
01807 fracx = ((float)nx)/((float)nbsize);
01808 fracy = ((float)ny)/((float)nbsize);
01809 ifracx = (int)(fracx + 0.1);
01810 ifracy = (int)(fracy + 0.1);
01811 nbsizx = nx/ifracx;
01812 nbsizy = ny/ifracy;
01813 nbsize = max(vircam_nint(0.9*nbsize),min(nbsize,min(nbsizx,nbsizy)));
01814 nbsize = min(nx,min(ny,nbsize));
01815 nbsize2 = nbsize/2;
01816
01817
01818
01819 nbx = nx/nbsize;
01820 nby = ny/nbsize;
01821
01822
01823
01824 bmap = cpl_malloc(nbx*nby*sizeof(float));
01825 rowpoints = cpl_malloc(nbx*sizeof(float *));
01826 nps = cpl_malloc(nbx*sizeof(int));
01827
01828
01829
01830 data = cpl_image_get_data_float(vircam_fits_get_image(in));
01831 bpm = vircam_mask_get_data(mask);
01832
01833
01834
01835 *med = vircam_med(data,bpm,(long)(nx*ny));
01836
01837
01838
01839
01840
01841 for (i = 0; i < nbx; i++)
01842 rowpoints[i] = cpl_malloc(nbsize*nbsize*sizeof(float));
01843
01844
01845
01846
01847 for (jy = 0; jy < nby; jy++) {
01848 jy1 = jy*nbsize;
01849 jy2 = min((jy+1)*nbsize - 1,ny-1);
01850
01851
01852
01853 for (jx = 0; jx < nbx; jx++)
01854 nps[jx] = 0;
01855
01856
01857
01858
01859
01860 for (j = jy1; j <= jy2; j++) {
01861 for (i = 0; i < nx; i++) {
01862 jx = min(nbx-1,i/nbsize);
01863 if (bpm[j*nx + i] == 0) {
01864 ptr = rowpoints[jx];
01865 np = nps[jx];
01866 ptr[np++] = data[j*nx + i];
01867 nps[jx] = np;
01868 }
01869 }
01870 }
01871
01872
01873
01874 for (jx = 0; jx < nbx; jx++) {
01875 bmap[jy*nbx+jx] = vircam_med(rowpoints[jx],NULL,(long)(nps[jx]));
01876 if (bmap[jy*nbx+jx] != CX_MAXFLOAT) {
01877 bmap[jy*nbx+jx] -= *med;
01878 } else {
01879 bmap[jy*nbx+jx] = 0.0;
01880 }
01881 }
01882 }
01883
01884
01885
01886 for (jx = 0; jx < nbx; jx++)
01887 freespace(rowpoints[jx]);
01888 freespace(rowpoints);
01889 freespace(nps);
01890
01891
01892
01893 *out = cpl_image_new(nx,ny,CPL_TYPE_FLOAT);
01894 ptr = cpl_image_get_data_float(*out);
01895
01896
01897
01898
01899 nout = 0;
01900 for (j = 1; j <= ny; j++) {
01901 jy = (j + nbsize2)/nbsize;
01902 jyp1 = jy + 1;
01903 jy = min(nby,max(1,jy));
01904 jyp1 = min(nby,jyp1);
01905 dely = (float)(j - nbsize*jy + nbsize2)/(float)nbsize;
01906 dely = max(0.0,min(1.0,dely));
01907 for (i = 1; i <= nx; i++) {
01908 jx = (i + nbsize2)/nbsize;
01909 jxp1 = jx + 1;
01910 jx = min(nbx,max(1,jx));
01911 jxp1 = min(nbx,jxp1);
01912 delx = (float)(i - nbsize*jx + nbsize2)/(float)nbsize;
01913 delx = max(0.0,min(1.0,delx));
01914 jz1 = (jy - 1)*nbx + jx;
01915 jz2 = (jyp1 - 1)*nbx + jx;
01916 if (jx == nbx) {
01917 jz3 = jz1;
01918 jz4 = jz2;
01919 } else {
01920 jz3 = jz1 + 1;
01921 jz4 = jz2 + 1;
01922 }
01923 t1 = (1.0 - delx)*bmap[jz1-1] + delx*bmap[jz3-1];
01924 t2 = (1.0 - delx)*bmap[jz2-1] + delx*bmap[jz4-1];
01925 ptr[nout++] = (1.0 - dely)*t1 + dely*t2;
01926 }
01927 }
01928
01929
01930
01931 freespace(bmap)
01932 }
01933
01934
01955
01956
01957 extern int vircam_findcol(cpl_propertylist *p, const char *col) {
01958
01959 if (!strcmp(col,"X")) {
01960 if (cpl_propertylist_has(p,"ESO DRS XCOL"))
01961 return(cpl_propertylist_get_int(p,"ESO DRS XCOL"));
01962 else
01963 return(-1);
01964 } else if (!strcmp(col,"Y")) {
01965 if (cpl_propertylist_has(p,"ESO DRS YCOL"))
01966 return(cpl_propertylist_get_int(p,"ESO DRS YCOL"));
01967 else
01968 return(-1);
01969 }
01970 return(-1);
01971 }
01972
01973
01994
01995
01996 extern void vircam_rename_property(cpl_propertylist *p, const char *oldname,
01997 char *newname) {
01998 cpl_propertylist *temp;
01999 cpl_property *property;
02000
02001
02002
02003
02004
02005
02006 if (! cpl_propertylist_has(p,oldname))
02007 return;
02008 temp = cpl_propertylist_new();
02009 cpl_propertylist_copy_property(temp,p,oldname);
02010 property = cpl_propertylist_get(temp,0);
02011
02012
02013
02014 cpl_property_set_name(property,newname);
02015
02016
02017
02018 cpl_propertylist_append(p,temp);
02019 cpl_propertylist_erase(p,oldname);
02020 cpl_propertylist_delete(temp);
02021 }
02022
02023
02051
02052
02053 extern int vircam_catpars(cpl_frame *indx, char **catpath, char **catname) {
02054 cpl_propertylist *p;
02055 char *fname;
02056 int status;
02057 const char *fctid = "vircam_catpars",*unk = "unknown";
02058
02059
02060
02061 *catpath = NULL;
02062 *catname = NULL;
02063
02064
02065
02066 fname = cpl_strdup(cpl_frame_get_filename(indx));
02067 if (access((const char *)fname,R_OK) != 0) {
02068 cpl_msg_error(fctid,"Can't access index file %s",fname);
02069 cpl_free(fname);
02070 return(VIR_FATAL);
02071 }
02072 *catpath = cpl_strdup(dirname(fname));
02073
02074
02075
02076
02077 if ((p = cpl_propertylist_load(cpl_frame_get_filename(indx),0)) == NULL) {
02078 freespace(*catpath);
02079 cpl_msg_error(fctid,"Can't load index file header %s",
02080 cpl_frame_get_filename(indx));
02081 cpl_free(fname);
02082 return(VIR_FATAL);
02083 }
02084
02085
02086
02087
02088 if (cpl_propertylist_has(p,"CATNAME")) {
02089 *catname = cpl_strdup(cpl_propertylist_get_string(p,"CATNAME"));
02090 status = VIR_OK;
02091 } else {
02092 *catname = cpl_strdup(unk);
02093 cpl_msg_warning(fctid,"Property CATNAME not in index file header %s",
02094 cpl_frame_get_filename(indx));
02095 status = VIR_WARN;
02096 }
02097 cpl_free(fname);
02098 freepropertylist(p);
02099
02100
02101
02102 return(status);
02103 }
02104
02105
02136
02137
02138 extern int vircam_gaincor_calc(cpl_frame *frame, int *n, float **cors,
02139 int *status) {
02140 float sum,val;
02141 int i,ngood;
02142 unsigned char *iflag;
02143 cpl_propertylist *p;
02144
02145
02146
02147 if (*status != VIR_OK)
02148 return(*status);
02149
02150
02151
02152
02153
02154 *n = cpl_frame_get_nextensions(frame);
02155 *cors = cpl_malloc(*n*sizeof(float));
02156 iflag = cpl_calloc(*n,sizeof(iflag));
02157
02158
02159
02160 sum = 0.0;
02161 ngood = 0;
02162 for (i = 0; i < *n; i++) {
02163 p = cpl_propertylist_load(cpl_frame_get_filename(frame),i+1);
02164 if (cpl_propertylist_has(p,"ESO DRS IMADUMMY")) {
02165 iflag[i] = 1;
02166 } else if (! cpl_propertylist_has(p,"ESO DRS MEDFLAT")) {
02167 iflag[i] = 1;
02168 } else {
02169 val = cpl_propertylist_get_double(p,"ESO DRS MEDFLAT");
02170 if (val == 0.0) {
02171 iflag[i] = 1;
02172 } else {
02173 sum += val;
02174 (*cors)[i] = val;
02175 ngood++;
02176 }
02177 }
02178 cpl_propertylist_delete(p);
02179 }
02180
02181
02182
02183
02184
02185
02186 if (ngood > 0)
02187 sum /= (float)ngood;
02188 for (i = 0; i < *n; i++) {
02189 if (iflag[i] == 0) {
02190 (*cors)[i] = sum/(*cors)[i];
02191 } else {
02192 (*cors)[i] = 1.0;
02193 }
02194 }
02195 cpl_free(iflag);
02196
02197
02198
02199 GOOD_STATUS
02200 }
02201
02202
02228
02229
02230 extern int vircam_check_crval(cpl_propertylist *phu, cpl_propertylist *ehu) {
02231 double crval1,crval2;
02232 cpl_property *p;
02233
02234
02235
02236
02237 if ((vircam_pfits_get_crval1(ehu,&crval1) != VIR_OK) ||
02238 (vircam_pfits_get_crval2(ehu,&crval2) != VIR_OK))
02239 return(VIR_FATAL);
02240
02241
02242
02243
02244
02245
02246
02247
02248
02249 if (fabs(crval1) < 1.0e-6 && fabs(crval2) < 1.0e-6) {
02250 if ((vircam_pfits_get_ra(phu,&crval1) != VIR_OK) ||
02251 (vircam_pfits_get_dec(phu,&crval2) != VIR_OK))
02252 return(VIR_FATAL);
02253 p = cpl_propertylist_get_property(ehu,"CRVAL1");
02254 cpl_property_set_name(p,"OLDCR1");
02255 p = cpl_propertylist_get_property(ehu,"CRVAL2");
02256 cpl_property_set_name(p,"OLDCR2");
02257 cpl_propertylist_insert_after_double(ehu,"OLDCR2","CRVAL1",crval1);
02258 cpl_propertylist_insert_after_double(ehu,"CRVAL1","CRVAL2",crval2);
02259 cpl_propertylist_erase(ehu,"OLDCR1");
02260 cpl_propertylist_erase(ehu,"OLDCR2");
02261 }
02262
02263
02264
02265 return(VIR_OK);
02266 }
02267
02270
02271
02272
02273
02274
02275
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