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 #include <cpl.h>
00036 #include "vircam_mods.h"
00037 #include "vircam_utils.h"
00038 #include "vircam_fits.h"
00039 #include "vircam_stats.h"
00040 #include "vircam_pfits.h"
00041 #include "vircam_wcsutils.h"
00042 #include "vircam_tfits.h"
00043
00044 typedef struct {
00045 double crval[2];
00046 double crpix[2];
00047 double cd[4];
00048 double secd;
00049 double tand;
00050 double pv21;
00051 double pv23;
00052 double pv25;
00053 long nx;
00054 long ny;
00055 } mywcs;
00056
00057 typedef struct {
00058 int nx;
00059 int ny;
00060 vir_fits *fname;
00061 vir_fits *conf;
00062 float *data;
00063 int *cdata;
00064 cpl_binary *bpm;
00065 mywcs *vwcs;
00066 float xoff;
00067 float yoff;
00068 cpl_array *trans;
00069 float sky;
00070 float skydiff;
00071 float noise;
00072 float expscale;
00073 float weight;
00074 } dstrct;
00075
00076 static dstrct *fileptrs = NULL;
00077 static vir_fits *outfits = NULL;
00078 static vir_fits *outconf = NULL;
00079 static mywcs *outwcs = NULL;
00080
00081 static float lsig;
00082 static float hsig;
00083 static int nxo;
00084 static int nyo;
00085 static float *outdata;
00086 static int *outdatac;
00087 static int nim;
00088 static float sumweight;
00089
00090 static void outloc(mywcs *win, double xin, double yin, mywcs *wout,
00091 cpl_array *trans, double *xout, double *yout);
00092 static void backgrnd_ov(void);
00093 static void skyest(float *data, int *cdata, long npts, float thresh,
00094 float *skymed, float *skynoise);
00095 static cpl_array *transinit(void);
00096 static void fileptrs_close(void);
00097 static cpl_table *mknewtab(vir_tfits *catref, dstrct *dd);
00098 static void output_files(void);
00099 static int stack_nn(void);
00100 static int stack_lin(void);
00101 static void do_averages(int ncontrib, float *data, float *wconf, float *conf,
00102 unsigned char *id, float lclip, float hclip,
00103 float extra, short int *lowcl, short int *highcl,
00104 float *outval, float *outvalc);
00105 static mywcs *getwcsinfo(cpl_propertylist *plist);
00106 static void diffxy(mywcs *wref, mywcs *wprog, float *dx, float *dy);
00107 static void tidy(void);
00108
00111
00171
00172
00173 extern int vircam_imstack(vir_fits **inf, vir_fits **inconf, vir_tfits **cats,
00174 int nimages, int nconfs, float lthr, float hthr,
00175 int method, vir_fits **out, vir_fits **outc,
00176 int *status) {
00177
00178 int i,nm;
00179 dstrct *dd;
00180 float expref,exposure,xoff,yoff;
00181 cpl_matrix *in;
00182 vir_tfits *catref;
00183 cpl_table *newtab,*mtab;
00184 const char *fctid = "vircam_imstack";
00185
00186
00187
00188 *out = NULL;
00189 *outc = NULL;
00190 if (*status != VIR_OK)
00191 return(*status);
00192
00193
00194
00195 if (nimages == 0) {
00196 cpl_msg_error(fctid,"No input files to combine");
00197 tidy();
00198 FATAL_ERROR
00199 }
00200
00201
00202
00203 lsig = lthr;
00204 hsig = hthr;
00205 nim = nimages;
00206
00207
00208
00209 in = cpl_matrix_new(1,2);
00210 cpl_matrix_set(in,0,0,0.0);
00211 cpl_matrix_set(in,0,1,0.0);
00212
00213
00214
00215 fileptrs = cpl_malloc(nimages*sizeof(dstrct));
00216 (void)vircam_pfits_get_exptime(vircam_fits_get_phu(inf[0]),&exposure);
00217 expref = max(0.5,exposure);
00218 catref = NULL;
00219 for (i = 0; i < nimages; i++) {
00220 dd = fileptrs + i;
00221 dd->fname = inf[i];
00222 dd->data = cpl_image_get_data_float(vircam_fits_get_image(inf[i]));
00223 if (nconfs == 0) {
00224 dd->conf = NULL;
00225 } else if (nconfs == 1) {
00226 dd->conf = inconf[0];
00227 dd->cdata = cpl_image_get_data_int(vircam_fits_get_image(inconf[0]));
00228 } else {
00229 dd->conf = inconf[i];
00230 dd->cdata = cpl_image_get_data_int(vircam_fits_get_image(inconf[i]));
00231 }
00232 (void)vircam_pfits_get_exptime(vircam_fits_get_phu(dd->fname),&exposure);
00233 dd->expscale = exposure/expref;
00234
00235
00236
00237 cpl_image_accept_all(vircam_fits_get_image(inf[i]));
00238 dd->bpm = cpl_mask_get_data(cpl_image_get_bpm(vircam_fits_get_image(inf[i])));
00239
00240
00241
00242 dd->vwcs = getwcsinfo(vircam_fits_get_ehu(inf[i]));
00243
00244
00245
00246 dd->nx = (int)cpl_image_get_size_x(vircam_fits_get_image(dd->fname));
00247 dd->ny = (int)cpl_image_get_size_y(vircam_fits_get_image(dd->fname));
00248
00249
00250
00251
00252 if ((int)cpl_image_get_size_x(vircam_fits_get_image(dd->conf)) != dd->nx ||
00253 (int)cpl_image_get_size_y(vircam_fits_get_image(dd->conf)) != dd->ny) {
00254 cpl_msg_error(fctid,"Image %s and Confidence map %s don't match",
00255 vircam_fits_get_fullname(dd->fname),
00256 vircam_fits_get_fullname(dd->conf));
00257 cpl_matrix_delete(in);
00258 tidy();
00259 FATAL_ERROR
00260 }
00261
00262
00263
00264 diffxy(fileptrs->vwcs,dd->vwcs,&(dd->xoff),&(dd->yoff));
00265
00266
00267
00268
00269 if (cats != NULL) {
00270 if (catref == NULL && cats[i] != NULL)
00271 catref = cats[i];
00272 if (i == 0 || cats[i] == NULL) {
00273 dd->trans = transinit();
00274 } else {
00275 newtab = mknewtab(catref,dd);
00276 (void)vircam_matchxy(vircam_tfits_get_table(cats[i]),newtab,
00277 1024,&xoff,&yoff,&nm,&mtab,status);
00278 if (*status != VIR_OK) {
00279 freearray(dd->trans);
00280 dd->trans = transinit();
00281 *status = VIR_OK;
00282 } else {
00283 (void)vircam_platexy(mtab,6,&(dd->trans),status);
00284 }
00285 freetable(mtab);
00286 freetable(newtab);
00287 }
00288 } else {
00289 dd->trans = NULL;
00290 }
00291 }
00292 cpl_matrix_delete(in);
00293
00294
00295
00296 backgrnd_ov();
00297
00298
00299
00300 output_files();
00301
00302
00303
00304
00305
00306
00307 stack_nn();
00308
00309
00310
00311 switch (method) {
00312 case 0:
00313 break;
00314 case 1:
00315 stack_lin();
00316 break;
00317 default:
00318 break;
00319 }
00320
00321
00322
00323 vircam_prov(vircam_fits_get_ehu(outfits),inf,nimages);
00324
00325
00326
00327 *out = outfits;
00328 *outc = outconf;
00329 tidy();
00330 return(VIR_OK);
00331 }
00332
00333
00349
00350
00351 static int stack_lin(void) {
00352 cpl_image *outim,*outimc;
00353 double oxf,oyf;
00354 int npts,i,*cdata,ix,iy,ind1,ind,ox,oy,m,jj,ii,nn,nx,ny,n;
00355 float *workbufw,*data,wt,dx,dy,w[4],value,cval;
00356 float med,noise;
00357 dstrct *dd;
00358
00359
00360
00361 outim = vircam_fits_get_image(outfits);
00362 outimc = vircam_fits_get_image(outconf);
00363 nxo = (int)cpl_image_get_size_x(outim);
00364 nyo = (int)cpl_image_get_size_y(outim);
00365 npts = nxo*nyo;
00366
00367
00368
00369 workbufw = cpl_calloc(nxo*nyo,sizeof(*workbufw));
00370
00371
00372
00373 outdata = cpl_image_get_data_float(outim);
00374 outdatac = cpl_image_get_data_int(outimc);
00375
00376
00377
00378
00379 for (i = 0; i < npts; i++) {
00380 outdata[i] = 0.0;
00381 outdatac[i] = 0;
00382 }
00383
00384
00385
00386
00387 for (i = 0; i < nim; i++) {
00388 dd = fileptrs + i;
00389 data = dd->data;
00390 cdata = dd->cdata;
00391 wt = dd->weight;
00392 nx = dd->nx;
00393 ny = dd->ny;
00394
00395
00396
00397
00398 n = 0;
00399 for (iy = 0; iy < ny; iy++) {
00400 ind1 = iy*nx;
00401 for (ix = 0; ix < nx; ix++) {
00402 ind = ind1 + ix;
00403 outloc(dd->vwcs,(double)ix,(double)iy,outwcs,dd->trans,
00404 &oxf,&oyf);
00405 if (oxf < 0.0 || oyf < 0.0)
00406 continue;
00407 ox = (int)oxf;
00408 oy = (int)oyf;
00409 if ((dd->bpm)[ind] != 0)
00410 continue;
00411 if (ox < 0 || ox >= nxo || oy < 0 || oy >= nyo ||
00412 cdata[ind] == 0)
00413 continue;
00414 dx = oxf - ox;
00415 dy = oyf - oy;
00416 w[0] = (1.0-dx)*(1.0-dy);
00417 w[1] = dx*(1.0-dy);
00418 w[2] = dy*(1.0-dx);
00419 w[3] = dx*dy;
00420 m = 0;
00421 value = data[ind]*(dd->expscale) + dd->skydiff;
00422 cval = (float)cdata[ind];
00423 for (jj = 0; jj <= 1; jj++) {
00424 for (ii = 0; ii <= 1; ii++) {
00425 nn = (oy+jj)*nxo + ox + ii;
00426 if (nn >= npts || ox+ii >= nxo || oy+jj >= nyo)
00427 continue;
00428 outdata[nn] += w[m]*value*wt*cval;
00429 workbufw[nn] += w[m]*wt*cval;
00430 m++;
00431 }
00432 }
00433 }
00434 }
00435 }
00436
00437
00438
00439 for (i = 0; i < npts; i++) {
00440 if (workbufw[i] != 0.0)
00441 outdata[i] /= workbufw[i];
00442 else
00443 outdata[i] = fileptrs->sky;
00444 workbufw[i] /= sumweight;
00445 }
00446 vircam_qmedsig(workbufw,NULL,npts,3.0,2,0.0,65535.0,&med,&noise);
00447 for (i = 0; i < npts; i++) {
00448 workbufw[i] *= (100.0/med);
00449 outdatac[i] = max(0,min(1000,vircam_nint(workbufw[i])));
00450 }
00451 freespace(workbufw);
00452 return(VIR_OK);
00453 }
00454
00455
00471
00472
00473 static int stack_nn(void) {
00474 float *workbuf,*workbufc,*workbufw,lclip,hclip,*data,wt,med,noise,outvalc;
00475 float value,*dbuf,*wbuf,*cbuf,outval,avlev,avvar,*confwork;
00476 double oxf,oyf;
00477 int *iloc,i,npts,ix,iy,ind1,ind,ox,oy,nn,bufloc,ncontrib,*lbuf;
00478 int j,*cdata,nx,ny,n,nz;
00479 short int clipped_low,clipped_high;
00480 dstrct *dd;
00481 unsigned char *id,*clipmap,*cc,*cclast,*ibuf;
00482 short int *nbuf;
00483 cpl_image *outim,*outimc;
00484
00485
00486
00487 outim = vircam_fits_get_image(outfits);
00488 outimc = vircam_fits_get_image(outconf);
00489 nxo = (int)cpl_image_get_size_x(outim);
00490 nyo = (int)cpl_image_get_size_y(outim);
00491
00492
00493
00494 nz = nim + 2;
00495 workbuf = cpl_calloc(nz*nxo*nyo,sizeof(*workbuf));
00496 workbufc = cpl_calloc(nz*nxo*nyo,sizeof(*workbufc));
00497 workbufw = cpl_calloc(nz*nxo*nyo,sizeof(*workbufw));
00498 id = cpl_calloc(nz*nxo*nyo,sizeof(*id));
00499 iloc = cpl_calloc(nz*nxo*nyo,sizeof(*iloc));
00500 nbuf = cpl_calloc(nxo*nyo,sizeof(*nbuf));
00501 confwork = cpl_calloc(nxo*nyo,sizeof(*confwork));
00502
00503
00504
00505 clipmap = cpl_calloc(2*nxo,sizeof(*clipmap));
00506
00507
00508
00509 dbuf = cpl_calloc(2*nz,sizeof(*dbuf));
00510 wbuf = cpl_calloc(2*nz,sizeof(*wbuf));
00511 cbuf = cpl_calloc(2*nz,sizeof(*cbuf));
00512 ibuf = cpl_calloc(2*nz,sizeof(*ibuf));
00513 lbuf = cpl_calloc(2*nz,sizeof(*lbuf));
00514
00515
00516
00517 outdata = cpl_image_get_data_float(outim);
00518 outdatac = cpl_image_get_data_int(outimc);
00519
00520
00521
00522 lclip = fileptrs->sky - lsig*(fileptrs->noise);
00523 hclip = fileptrs->sky + hsig*(fileptrs->noise);
00524
00525
00526
00527
00528 for (i = 0; i < nim; i++) {
00529 dd = fileptrs + i;
00530 nx = dd->nx;
00531 ny = dd->ny;
00532 npts = nx*ny;
00533 data = dd->data;
00534 cdata = dd->cdata;
00535 wt = dd->weight;
00536
00537
00538
00539
00540 n = 0;
00541 for (iy = 0; iy < ny; iy++) {
00542 ind1 = iy*nx;
00543 for (ix = 0; ix < nx; ix++) {
00544 ind = ind1 + ix;
00545 outloc(dd->vwcs,(double)ix,(double)iy,outwcs,dd->trans,
00546 &oxf,&oyf);
00547 ox = vircam_nint(oxf) - 1;
00548 oy = vircam_nint(oyf) - 1;
00549 if (ox < 0 || ox >= nxo || oy < 0 || oy >= nyo ||
00550 cdata[ind] == 0)
00551 continue;
00552 nn = oy*nxo + ox;
00553 bufloc = oy*nxo*nz + ox*nz + nbuf[nn];
00554 value = data[ind]*(dd->expscale) + dd->skydiff;
00555 workbuf[bufloc] = value;
00556 workbufw[bufloc] = wt*(float)cdata[ind];
00557 workbufc[bufloc] = (float)cdata[ind];
00558 id[bufloc] = i;
00559 nbuf[nn] += 1;
00560 iloc[bufloc] = ind;
00561 }
00562 }
00563 }
00564
00565
00566
00567
00568 for (iy = 0; iy < nyo; iy++) {
00569 ind1 = iy*nxo;
00570 cc = clipmap + (iy % 2)*nxo;
00571 cclast = clipmap + ((iy-1) % 2)*nxo;
00572 for (ix = 0; ix < nxo; ix++) {
00573 ind = ind1 + ix;
00574 bufloc = iy*nxo*nz + ix*nz;
00575 ncontrib = nbuf[ind];
00576 if (ncontrib == 0) {
00577 outdata[ind] = fileptrs->sky;
00578 outdatac[ind] = 0;
00579 continue;
00580 }
00581 cc[ix] = 0;
00582
00583
00584
00585 for (i = 0; i < ncontrib; i++) {
00586 dbuf[i] = workbuf[bufloc+i];
00587 wbuf[i] = workbufw[bufloc+i];
00588 cbuf[i] = workbufc[bufloc+i];
00589 ibuf[i] = id[bufloc+i];
00590 lbuf[i] = iloc[bufloc+i];
00591 }
00592
00593
00594
00595 do_averages(ncontrib,dbuf,wbuf,cbuf,ibuf,lclip,hclip,0.0,
00596 &clipped_low,&clipped_high,&outval,&outvalc);
00597
00598
00599
00600 outdata[ind] = outval;
00601 confwork[ind] = outvalc;
00602 cc[ix] = (clipped_high >= 0);
00603 if (clipped_low >= 0)
00604 ((fileptrs+ibuf[clipped_low])->bpm)[lbuf[clipped_low]] = 2;
00605 if (clipped_high >= 0)
00606 ((fileptrs+ibuf[clipped_high])->bpm)[lbuf[clipped_high]] = 1;
00607 }
00608
00609
00610
00611
00612
00613 if (iy < 2)
00614 continue;
00615 for (ix = 1; ix < nxo-1; ix++) {
00616 if (! cclast[ix])
00617 continue;
00618 ind = (iy-1)*nxo + ix;
00619 bufloc = (iy-1)*nxo*nz + ix*nz;
00620 ncontrib = nbuf[ind];
00621 if (ncontrib == 0)
00622 continue;
00623 avlev = 0.0;
00624 for (i = -1; i <= 1; i++)
00625 for (j = -1; j <= 1; j++)
00626 avlev += outdata[ind + i*nxo + j];
00627 avlev /= 9.0;
00628 avvar = 0.0;
00629 for (i = -1; i <= 1; i++)
00630 for (j = -1; j <= 1; j++)
00631 avvar += (float)fabs(avlev - outdata[ind + i*nxo + j]);
00632 avvar /= 9.0;
00633 if (avlev <= hclip && avvar <= 2.0*(fileptrs->sky))
00634 continue;
00635
00636
00637
00638 for (i = 0; i < ncontrib; i++) {
00639 dbuf[i] = workbuf[bufloc+i];
00640 wbuf[i] = workbufw[bufloc+i];
00641 cbuf[i] = workbufc[bufloc+i];
00642 ibuf[i] = id[bufloc+i];
00643 lbuf[i] = iloc[bufloc+i];
00644 (fileptrs+ibuf[i])->bpm[lbuf[i]] = 0;
00645 }
00646
00647
00648
00649 do_averages(ncontrib,dbuf,wbuf,cbuf,ibuf,lclip,hclip,avvar,
00650 &clipped_low,&clipped_high,&outval,&outvalc);
00651
00652
00653
00654 outdata[ind] = outval;
00655 confwork[ind] = outvalc;
00656 if (clipped_low >= 0)
00657 ((fileptrs+ibuf[clipped_low])->bpm)[lbuf[clipped_low]] = 2;
00658 if (clipped_high >= 0)
00659 ((fileptrs+ibuf[clipped_high])->bpm)[lbuf[clipped_high]] = 1;
00660 }
00661 }
00662
00663
00664
00665 npts = nxo*nyo;
00666 vircam_qmedsig(confwork,NULL,npts,3.0,2,25.0,65535.0,&med,&noise);
00667 for (i = 0; i < npts; i++) {
00668 confwork[i] *= (100.0/med);
00669 outdatac[i] = max(0,min(1000,vircam_nint(confwork[i])));
00670 }
00671
00672
00673
00674 freespace(workbuf);
00675 freespace(workbufc);
00676 freespace(workbufw);
00677 freespace(confwork);
00678 freespace(id);
00679 freespace(iloc);
00680 freespace(nbuf);
00681 freespace(clipmap);
00682 freespace(dbuf);
00683 freespace(wbuf);
00684 freespace(cbuf);
00685 freespace(ibuf);
00686 freespace(lbuf);
00687 return(VIR_OK);
00688 }
00689
00690
00728
00729
00730 static void do_averages(int ncontrib, float *data, float *wconf, float *conf,
00731 unsigned char *id, float lclip, float hclip,
00732 float extra, short int *lowcl, short int *highcl,
00733 float *outval, float *outvalc) {
00734 float minval,maxval,sum,wsum,csum,reflev,clipval;
00735 int imax,imin,i;
00736
00737
00738
00739
00740 minval = 1.0e10;
00741 maxval = -1.0e10;
00742 sum = 0.0;
00743 wsum = 0.0;
00744 csum = 0.0;
00745 imin = -1;
00746 imax = -1;
00747 for (i = 0; i < ncontrib; i++) {
00748 sum += data[i]*wconf[i];
00749 wsum += wconf[i];
00750 csum += conf[i];
00751 if (data[i] > maxval) {
00752 maxval = data[i];
00753 imax = i;
00754 }
00755 if (data[i] < minval) {
00756 minval = data[i];
00757 imin = i;
00758 }
00759 }
00760
00761
00762
00763 if (wsum > 0.0) {
00764 *outval = sum/wsum;
00765 } else {
00766 *outval = fileptrs->sky;
00767 }
00768
00769
00770
00771 *highcl = -1;
00772 if (maxval > hclip && wsum > 150.0 && csum > 150.0 &&
00773 imin != -1 && imax != -1) {
00774 reflev = (sum - data[imax]*wconf[imax])/(wsum - wconf[imax]);
00775 clipval = reflev + hsig*(fileptrs+id[imax])->noise;
00776 clipval *= max(1.0,reflev)/max(1.0,(fileptrs+id[imax])->sky);
00777 clipval += extra;
00778
00779
00780
00781 if (maxval > clipval) {
00782 sum -= data[imax]*wconf[imax];
00783 wsum -= wconf[imax];
00784 *outval = reflev;
00785 *highcl = imax;
00786 }
00787 }
00788
00789
00790
00791 *lowcl = -1;
00792 if (minval < lclip && wsum > 150.0 && csum > 150.0 &&
00793 imin != -1 && imax != -1) {
00794 reflev = (sum - data[imin]*wconf[imin])/(wsum - wconf[imin]);
00795 clipval = reflev + hsig*(fileptrs+id[imin])->noise;
00796 clipval *= max(1.0,reflev)/max(1.0,(fileptrs+id[imin])->sky);
00797 if (minval < clipval) {
00798 sum -= data[imin]*wconf[imin];
00799 wsum -= wconf[imin];
00800 *outval = reflev;
00801 *lowcl = imin;
00802 }
00803 }
00804
00805
00806
00807 *outvalc = wsum/sumweight;
00808 }
00809
00810
00824
00825
00826 static void output_files(void) {
00827 cpl_image *newim,*newconf;
00828 double lowerleft[2],upperleft[2],lowerright[2],upperright[2],xout,yout;
00829 double xmin,ymin,sh[2];
00830 dstrct *dd;
00831 int i,ixo,iyo;
00832
00833
00834
00835
00836 lowerleft[0] = 1.0;
00837 lowerleft[1] = 1.0;
00838 upperleft[0] = 1.0;
00839 upperleft[1] = (double)fileptrs->ny;
00840 lowerright[0] = (double)fileptrs->nx;
00841 lowerright[1] = 1.0;
00842 upperright[0] = (double)fileptrs->nx;
00843 upperright[1] = (double)fileptrs->ny;
00844
00845
00846
00847 for (i = 1; i < nim; i++) {
00848 dd = fileptrs + i;
00849 outloc(dd->vwcs,(double)1.0,(double)1.0,fileptrs->vwcs,dd->trans,
00850 &xout,&yout);
00851 lowerleft[0] = min(lowerleft[0],xout);
00852 lowerleft[1] = min(lowerleft[1],yout);
00853 outloc(dd->vwcs,(double)1.0,(double)dd->ny,fileptrs->vwcs,dd->trans,
00854 &xout,&yout);
00855 upperleft[0] = min(upperleft[0],xout);
00856 upperleft[1] = max(upperleft[1],yout);
00857 outloc(dd->vwcs,(double)dd->nx,(double)1.0,fileptrs->vwcs,dd->trans,
00858 &xout,&yout);
00859 lowerright[0] = max(lowerright[0],xout);
00860 lowerright[1] = min(lowerright[1],yout);
00861 outloc(dd->vwcs,(double)dd->nx,(double)dd->ny,fileptrs->vwcs,dd->trans,
00862 &xout,&yout);
00863 upperright[0] = max(upperright[0],xout);
00864 upperright[1] = max(upperright[1],yout);
00865 }
00866
00867
00868
00869 ixo = vircam_nint(max(lowerright[0]-lowerleft[0],upperright[0]-upperleft[0])) + 1;
00870 iyo = vircam_nint(max(upperright[1]-lowerright[1],upperleft[1]-lowerleft[1])) + 1;
00871 xmin = min(lowerleft[0],upperleft[0]);
00872 ymin = min(lowerleft[1],lowerright[1]);
00873
00874
00875
00876 newim = cpl_image_new((cpl_size)ixo,(cpl_size)iyo,CPL_TYPE_FLOAT);
00877 outfits = vircam_fits_wrap(newim,fileptrs->fname,NULL,NULL);
00878 cpl_propertylist_update_int(vircam_fits_get_ehu(outfits),"NAXIS1",ixo);
00879 cpl_propertylist_update_int(vircam_fits_get_ehu(outfits),"NAXIS2",iyo);
00880
00881
00882
00883 sh[0] = xmin;
00884 sh[1] = ymin;
00885 (void)vircam_crpixshift(vircam_fits_get_ehu(outfits),1.0,sh);
00886 outwcs = getwcsinfo(vircam_fits_get_ehu(outfits));
00887
00888
00889
00890 newconf = cpl_image_new((cpl_size)ixo,(cpl_size)iyo,CPL_TYPE_INT);
00891 outconf = vircam_fits_wrap(newconf,outfits,NULL,NULL);
00892 }
00893
00894
00917
00918
00919 static void diffxy(mywcs *wref, mywcs *wprog, float *dx, float *dy) {
00920 double xref,yref,xprog,yprog;
00921
00922
00923
00924 xref = 0.5*(double)wref->nx;
00925 yref = 0.5*(double)wref->ny;
00926
00927
00928
00929 outloc(wref,xref,yref,wprog,NULL,&xprog,&yprog);
00930
00931
00932
00933 *dx = (float)(xref - xprog);
00934 *dy = (float)(yref - yprog);
00935 }
00936
00937
00966
00967
00968 static void outloc(mywcs *win, double xin, double yin, mywcs *wout,
00969 cpl_array *trans, double *xout, double *yout) {
00970 double xt,yt,xi,eta,r,rfac,aa,tandec,denom,rp,*tdata;
00971
00972
00973
00974
00975 xt = xin - win->crpix[0];
00976 yt = yin - win->crpix[1];
00977 xi = win->cd[0]*xt + win->cd[1]*yt;
00978 eta = win->cd[2]*xt + win->cd[3]*yt;
00979 r = sqrt(xi*xi + eta*eta);
00980 rfac = win->pv21 + win->pv23*pow(r,2.0) + win->pv25*pow(r,4.0);
00981 r /= rfac;
00982 rfac = win->pv21 + win->pv23*pow(r,2.0) + win->pv25*pow(r,4.0);
00983 xi /= rfac;
00984 eta /= rfac;
00985 aa = atan(xi*win->secd/(1.0-eta*win->tand));
00986 if (xi != 0.0)
00987 tandec = (eta+win->tand)*sin(aa)/(xi*win->secd);
00988 else
00989 tandec = (eta+win->tand)/(1.0 - eta*win->tand);
00990
00991
00992
00993 aa += (win->crval[0] - wout->crval[0]);
00994 denom = wout->tand*tandec + cos(aa);
00995 xi = wout->secd*sin(aa)/denom;
00996 eta = (tandec - wout->tand*cos(aa))/denom;
00997 rp = sqrt(xi*xi + eta*eta);
00998 rfac = wout->pv21 + wout->pv23*pow(rp,2.0) + wout->pv25*pow(rp,4.0);
00999 xi *= rfac;
01000 eta *= rfac;
01001 denom = wout->cd[0]*wout->cd[3] - wout->cd[1]*wout->cd[2];
01002 xt = (xi*wout->cd[3] - eta*wout->cd[1])/denom + wout->crpix[0];
01003 yt = (eta*wout->cd[0] - xi*wout->cd[2])/denom + wout->crpix[1];
01004
01005
01006
01007 if (trans != NULL) {
01008 tdata = cpl_array_get_data_double(trans);
01009 *xout = xt*tdata[0] + yt*tdata[1] + tdata[2];
01010 *yout = xt*tdata[3] + yt*tdata[4] + tdata[5];
01011 } else {
01012 *xout = xt;
01013 *yout = yt;
01014 }
01015 }
01016
01017
01033
01034
01035 static void backgrnd_ov(void) {
01036 int i,dx,dy,*cdata,n,jj,ind1,nx,ii,ind;
01037 long npts1,npts,start[2],end[2];
01038 dstrct *dd1,*dd2;
01039 float *data,sky1,skynoise1,sky2,skynoise2,frac;
01040
01041
01042
01043 dd1 = fileptrs;
01044 npts1 = dd1->nx*dd1->ny;
01045
01046
01047
01048 skyest(dd1->data,dd1->cdata,npts1,3.0,&sky1,&skynoise1);
01049 dd1->sky = sky1;
01050 dd1->noise = skynoise1;
01051 dd1->sky /= dd1->expscale;
01052 dd1->skydiff = 0.0;
01053 dd1->weight = 1.0;
01054 sumweight = 1.0;
01055
01056
01057
01058 for (i = 1; i < nim; i++) {
01059 dd2 = fileptrs + i;
01060
01061
01062
01063 dx = vircam_nint(dd2->xoff - dd1->xoff);
01064 dy = vircam_nint(dd2->yoff - dd1->yoff);
01065
01066
01067
01068
01069
01070
01071
01072 start[0] = max(0,-dx);
01073 start[1] = max(0,-dy);
01074 end[0] = min(dd1->nx-1,(dd1->nx)-dx-1);
01075 end[1] = min(dd1->ny-1,(dd1->ny)-dy-1);
01076 nx = dd1->nx;
01077
01078
01079
01080 npts = (end[0]-start[0]+1)*(end[1]-start[1]+1);
01081 frac = (float)npts/(float)npts1;
01082
01083
01084
01085
01086 if (frac >= 0.5) {
01087 data = cpl_malloc(npts*sizeof(*data));
01088 cdata = cpl_malloc(npts*sizeof(*cdata));
01089 n = 0;
01090 for (jj = start[1]; jj <= end[1]; jj++) {
01091 ind1 = jj*nx;
01092 for (ii = start[0]; ii <= end[0]; ii++) {
01093 ind = ind1 + ii;
01094 data[n] = (dd1->data)[ind];
01095 cdata[n++] = (dd1->cdata)[ind];
01096 }
01097 }
01098 skyest(data,cdata,npts,3.0,&sky1,&skynoise1);
01099 freespace(data);
01100 freespace(cdata);
01101 } else {
01102 sky1 = dd1->sky;
01103 }
01104
01105
01106
01107
01108 if (frac > 0.5) {
01109 start[0] = max(1,dx);
01110 start[1] = max(1,dy);
01111 end[0] = min(dd2->nx-1,(dd2->nx)+dx-1);
01112 end[1] = min(dd2->ny-1,(dd2->ny)+dy-1);
01113 nx = dd2->nx;
01114 npts = (end[0]-start[0]+1)*(end[1]-start[1]+1);
01115 data = cpl_malloc(npts*sizeof(*data));
01116 cdata = cpl_malloc(npts*sizeof(*cdata));
01117 n = 0;
01118 for (jj = start[1]; jj <= end[1]; jj++) {
01119 ind1 = jj*nx;
01120 for (ii = start[0]; ii <= end[0]; ii++) {
01121 ind = ind1 + ii;
01122 data[n] = dd2->data[ind];
01123 cdata[n++] = dd2->cdata[ind];
01124 }
01125 }
01126 skyest(data,cdata,npts,3.0,&sky2,&skynoise2);
01127 freespace(data);
01128 freespace(cdata);
01129 } else {
01130 npts = (dd2->nx)*(dd2->ny);
01131 skyest(dd2->data,dd2->cdata,npts,3.0,&sky2,&skynoise2);
01132 }
01133
01134
01135
01136 dd2->sky = sky2/dd2->expscale;
01137 dd2->skydiff = sky1 - sky2;
01138 dd2->noise = skynoise2;
01139 if (dd2->noise != 0.0 && dd2->sky != 0.0)
01140 dd2->weight = (float)(pow(dd1->noise,2.0)/pow(dd2->noise,2.0));
01141 else
01142 dd2->weight = 0.0;
01143 sumweight += dd2->weight;
01144 }
01145 }
01146
01147
01173
01174
01175 static void skyest(float *data, int *cdata, long npts, float thresh,
01176 float *skymed, float *skynoise) {
01177 unsigned char *bpm;
01178 int i;
01179
01180
01181
01182 bpm = cpl_calloc(npts,sizeof(*bpm));
01183 for (i = 0; i < npts; i++)
01184 bpm[i] = (cdata[i] == 0);
01185
01186
01187
01188 vircam_qmedsig(data,bpm,npts,thresh,2,-1000.0,65535.0,skymed,skynoise);
01189
01190
01191
01192 freespace(bpm);
01193 }
01194
01195
01217
01218
01219 static cpl_table *mknewtab(vir_tfits *catref, dstrct *dd) {
01220 cpl_table *newtab;
01221 double xx,yy,xx2,yy2;
01222 int nr,i;
01223 float *x,*y;
01224
01225
01226
01227 newtab = cpl_table_duplicate(vircam_tfits_get_table(catref));
01228 nr = (int)cpl_table_get_nrow(newtab);
01229
01230
01231
01232 x = cpl_table_get_data_float(newtab,"X_coordinate");
01233 y = cpl_table_get_data_float(newtab,"Y_coordinate");
01234
01235
01236
01237 for (i = 0; i < nr; i++) {
01238 xx = (double)x[i];
01239 yy = (double)y[i];
01240 outloc(fileptrs->vwcs,xx,yy,dd->vwcs,NULL,&xx2,&yy2);
01241 x[i] = (float)xx2;
01242 y[i] = (float)yy2;
01243 }
01244 return(newtab);
01245 }
01246
01247
01262
01263
01264 static cpl_array *transinit(void) {
01265 double *td;
01266 cpl_array *t;
01267
01268 t = cpl_array_new(6,CPL_TYPE_DOUBLE);
01269 td = cpl_array_get_data_double(t);
01270 td[0] = 1.0;
01271 td[1] = 0.0;
01272 td[2] = 0.0;
01273 td[3] = 0.0;
01274 td[4] = 1.0;
01275 td[5] = 0.0;
01276 return(t);
01277 }
01278
01279
01292
01293
01294 static void fileptrs_close(void) {
01295 int i;
01296
01297 for (i = 0; i < nim; i++) {
01298 freespace((fileptrs+i)->vwcs);
01299 freearray((fileptrs+i)->trans);
01300 }
01301 freespace(fileptrs);
01302 }
01303
01304
01320
01321
01322 static mywcs *getwcsinfo(cpl_propertylist *plist) {
01323 mywcs *w;
01324 int i;
01325
01326
01327
01328 w = cpl_malloc(sizeof(mywcs));
01329 (void)vircam_pfits_get_crval1(plist,&(w->crval[0]));
01330 (void)vircam_pfits_get_crval2(plist,&(w->crval[1]));
01331 (void)vircam_pfits_get_crpix1(plist,&(w->crpix[0]));
01332 (void)vircam_pfits_get_crpix2(plist,&(w->crpix[1]));
01333 (void)vircam_pfits_get_cd11(plist,&(w->cd[0]));
01334 (void)vircam_pfits_get_cd12(plist,&(w->cd[1]));
01335 (void)vircam_pfits_get_cd21(plist,&(w->cd[2]));
01336 (void)vircam_pfits_get_cd22(plist,&(w->cd[3]));
01337 (void)vircam_pfits_get_pv21(plist,&(w->pv21));
01338 (void)vircam_pfits_get_pv23(plist,&(w->pv23));
01339 (void)vircam_pfits_get_pv25(plist,&(w->pv25));
01340 (void)vircam_pfits_get_naxis1(plist,&(w->nx));
01341 (void)vircam_pfits_get_naxis2(plist,&(w->ny));
01342
01343
01344
01345 for (i = 0; i < 2; i++)
01346 w->crval[i] /= DEGRAD;
01347 for (i = 0; i < 4; i++)
01348 w->cd[i] /= DEGRAD;
01349
01350
01351
01352 w->tand = tan(w->crval[1]);
01353 w->secd = 1.0/cos(w->crval[1]);
01354
01355
01356
01357 return(w);
01358 }
01359
01360 static void tidy(void) {
01361 fileptrs_close();
01362 freespace(outwcs);
01363 }
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416