38 #include "vircam_sky.h"
39 #include "vircam_mask.h"
40 #include "vircam_fits.h"
41 #include "vircam_mods.h"
42 #include "vircam_utils.h"
43 #include "vircam_stats.h"
44 #include "vircam_wcsutils.h"
45 #include "vircam_pfits.h"
55 static void vircam_sky_mask_grow(cpl_image *dith,
float rad);
56 static float vircam_sky_med(vir_fits *sky);
57 static void vircam_sky_joffs(vir_fits **inlist,
int nfiles,
float **xoffs,
59 static void vircam_sky_xytoxy(cpl_wcs *inwcs, cpl_wcs *outwcs,
60 cpl_matrix *inxy, cpl_matrix **outxy);
112 vir_mask *mask, vir_fits **skyout,
int niter,
113 int ipix,
float thresh,
int nbsize,
float smkern,
115 int i,nx,ny,nbad0,lastone,iter,*confdata,npts,nbad_init,nbad,dbad;
117 const char *fctid =
"vircam_pawsky_mask";
118 cpl_image *dith,*dithc,*skyim,*im,*newim,*outim;
119 cpl_mask *cplmask,*dithmask,*newmask,*curmask;
120 vir_fits **list_ss,*dithf,*dithcf;
121 unsigned char *inbpm,*rejmask,*rejplus;
122 float medsky,*xoffs,*yoffs,mindx,mindy,fbad;
123 cpl_propertylist *p,*drs;
128 if (*status != VIR_OK)
134 cpl_msg_error(fctid,
"Sky correction impossible. No science frames");
144 cplmask = cpl_mask_wrap((cpl_size)nx,(cpl_size)ny,(cpl_binary *)inbpm);
145 for (i = 0; i < nfiles; i++)
147 cpl_mask_unwrap(cplmask);
152 &rejplus,&drs,status);
156 freepropertylist(drs);
169 medsky = vircam_sky_med(*skyout);
173 vircam_sky_joffs(inlist,nfiles,&xoffs,&yoffs);
176 for (i = 1; i < nfiles; i++) {
177 mindx = min(mindx,xoffs[i]);
178 mindy = min(mindy,yoffs[i]);
183 list_ss = cpl_malloc(nfiles*
sizeof(vir_fits *));
185 for (i = 0; i < nfiles; i++) {
187 newim = cpl_image_subtract_create(im,skyim);
188 cpl_image_add_scalar(newim,(
double)medsky);
197 for (iter = 1; iter <= niter; iter++) {
200 lastone = (iter == niter);
206 cpl_propertylist_delete(p);
210 confdata = cpl_image_get_data_int(dithc);
211 npts = (int)cpl_image_get_size_x(dithc)*(int)cpl_image_get_size_y(dithc);
213 for (i = 0; i < npts; i++)
214 if (confdata[i] == 0)
219 for (i = 0; i < nfiles; i++)
229 (void)
vircam_opm(dithf,dithcf,ipix,thresh,nbsize,smkern,niter,status);
234 nbad = (int)cpl_image_count_rejected((
const cpl_image *)dith) -
237 fbad = (iter > 1 ? (float)abs(dbad)/(float)nbad0 : 10000.0);
239 "Iteration: %" CPL_SIZE_FORMAT
", Nreject: %" CPL_SIZE_FORMAT
" %" CPL_SIZE_FORMAT,
240 (cpl_size)iter,(cpl_size)nbad,(cpl_size)nbad0);
241 if (fbad < 0.025 || dbad < 0) {
249 vircam_sky_mask_grow(dith,2);
254 dithmask = cpl_image_get_bpm(dith);
255 for (i = 0; i < nfiles; i++) {
256 xx1 = (int)(-mindx + xoffs[i] + 1.5);
258 yy1 = (int)(-mindy + yoffs[i] + 1.5);
260 newmask = cpl_mask_extract(dithmask,(cpl_size)xx1,(cpl_size)yy1,
261 (cpl_size)xx2,(cpl_size)yy2);
263 cpl_mask_or(curmask,newmask);
264 cpl_mask_delete(newmask);
275 &rejplus,&drs,status);
279 freepropertylist(drs);
290 for (i = 0; i < nfiles; i++) {
292 newim = cpl_image_subtract_create(im,skyim);
293 cpl_image_add_scalar(newim,(
double)medsky);
356 vir_mask *mask, vir_fits *objmask,
357 int nbsize, vir_fits **skyout,
int *status) {
358 const char *fctid =
"vircam_pawsky_mask_pre";
359 unsigned char *inbpm,*rejplus,*rejmask;
360 int nx,ny,npts,ncoor,i,j,nx_objmask,ny_objmask,k,kk,ix,iy,ind,*opm;
362 cpl_wcs *wcs_objmask,*wcs;
363 cpl_matrix *in_xy,*out_xy,*ddx,*ddx_out;
364 cpl_image *im,*outim;
365 cpl_propertylist *drs;
366 double *inxy_data,xx,yy,*ddx_data,shiftx,shifty;
371 if (*status != VIR_OK)
377 cpl_msg_error(fctid,
"Sky correction impossible. No science frames");
387 cplmask = cpl_mask_wrap((cpl_size)nx,(cpl_size)ny,(cpl_binary *)inbpm);
388 for (i = 0; i < nfiles; i++)
390 cpl_mask_unwrap(cplmask);
404 in_xy = cpl_matrix_new((cpl_size)npts,(cpl_size)ncoor);
408 inxy_data = cpl_matrix_get_data(in_xy);
410 for (j = 0; j < ny; j++) {
411 for (i = 0; i < nx; i++) {
412 inxy_data[k++] = (double)(i+1);
413 inxy_data[k++] = (double)(j+1);
419 ddx = cpl_matrix_new(1,2);
420 ddx_data = cpl_matrix_get_data(ddx);
429 for (k = 0; k < nfiles; k++) {
433 vircam_sky_xytoxy(wcs,wcs_objmask,in_xy,&out_xy);
434 vircam_sky_xytoxy(wcs,wcs_objmask,ddx,&ddx_out);
436 shiftx = cpl_matrix_get(out_xy,0,0) - cpl_matrix_get(ddx_out,0,0);
437 shifty = cpl_matrix_get(out_xy,0,1) - cpl_matrix_get(ddx_out,0,1);
439 for (j = 0; j < ny; j++) {
440 for (i = 0; i < nx; i++) {
441 xx = cpl_matrix_get(out_xy,kk,0) - shiftx;
442 yy = cpl_matrix_get(out_xy,kk,1) - shifty;
444 ix = vircam_nint(xx);
445 iy = vircam_nint(yy);
446 if (ix < 1 || ix > nx_objmask || iy < 1 || iy > ny_objmask)
448 ind = (iy-1)*nx_objmask + ix - 1;
450 cpl_image_reject(im,i+1,j+1);
453 cpl_matrix_delete(ddx_out);
455 cpl_matrix_delete(in_xy);
456 cpl_matrix_delete(out_xy);
457 cpl_wcs_delete(wcs_objmask);
462 &rejplus,&drs,status);
466 freepropertylist(drs);
513 vir_fits **skyout,
int *status) {
514 int i,njit,nx,ny,ji,ns,npts;
515 unsigned char *inbpm,*rejmask,*rejplus;
518 cpl_propertylist *drs;
520 vir_fits **xsky_fits;
521 const char *fctid =
"vircam_tilesky";
526 if (*status != VIR_OK)
532 cpl_msg_error(fctid,
"Sky correction impossible. No science frames");
543 cplmask = cpl_mask_wrap((cpl_size)nx,(cpl_size)ny,(cpl_binary *)inbpm);
544 for (i = 0; i < nfiles; i++)
546 cpl_mask_unwrap(cplmask);
574 xskys = cpl_malloc(njit*
sizeof(xsky_struct));
575 for (i = 0; i < njit; i++) {
577 xskys[i].in = cpl_malloc(8*
sizeof(vir_fits *));
579 xskys[i].xsky = NULL;
580 xskys[i].status = VIR_OK;
582 xsky_fits = cpl_malloc(njit*
sizeof(vir_fits *));
590 for (i = 0; i < nfiles; i++) {
593 if (xskys[ji].n == xskys[ji].nalloc) {
594 xskys[ji].in = cpl_realloc(xskys[ji].in,
595 (xskys[ji].nalloc+8)*
sizeof(vir_fits *));
596 xskys[ji].nalloc += 8;
598 xskys[ji].in[xskys[ji].n] = inlist[i];
606 for (i = 0; i < njit; i++) {
608 if (xskys[i].n == 0) {
609 xskys[i].xsky = NULL;
611 }
else if (xskys[i].n == 1) {
612 xskys[i].xsky = NULL;
613 xsky_fits[ns++] = xskys[i].in[0];
618 &rejplus,&drs,status);
621 freepropertylist(drs);
622 if (*status == VIR_OK) {
624 xsky_fits[ns++] = xskys[i].xsky;
638 freepropertylist(drs);
639 if (*status == VIR_OK) {
652 freespace(xsky_fits);
653 for (i = 0; i < njit; i++) {
654 freespace(xskys[i].in);
655 freefits(xskys[i].xsky);
682 static void vircam_sky_mask_grow(cpl_image *dith,
float rad) {
683 cpl_binary *inmap,*outmap;
684 int nx,ny,ir,i,j,indx,ixmin,ixmax,iymin,iymax,ii,jj,indx2;
689 inmap = cpl_mask_get_data(cpl_image_get_bpm(dith));
690 nx = (int)cpl_image_get_size_x(dith);
691 ny = (int)cpl_image_get_size_y(dith);
695 outmap = cpl_malloc(nx*ny*
sizeof(*outmap));
696 memmove(outmap,inmap,nx*ny*
sizeof(*inmap));
701 ir = vircam_nint(rad);
708 for (j = 0; j < ny; j++) {
709 for (i = 0; i < nx; i++) {
714 ixmax = min(nx-1,i+ir);
716 iymax = min(ny-1,j+ir);
717 for (jj = iymin; jj <= iymax; jj++) {
718 dy = (float)(jj - j);
719 for (ii = ixmin; ii <= ixmax; ii++) {
720 dx = (float)(ii - i);
721 radius = (float)sqrt(pow(dx,2.0) + pow(dy,2.0));
734 memmove(inmap,outmap,nx*ny*
sizeof(*inmap));
758 static float vircam_sky_med(vir_fits *sky) {
767 npts = (int)cpl_image_get_size_x(skyim)*(int)cpl_image_get_size_y(skyim);
771 data = cpl_image_get_data_float(skyim);
772 bpm = (
unsigned char *)cpl_mask_get_data(cpl_image_get_bpm(skyim));
805 static void vircam_sky_joffs(vir_fits **inlist,
int nfiles,
float **xoffs,
808 cpl_wcs *wcsref,*wcs;
810 const double maxoffset = 2048;
812 const char *fctid =
"vircam_sky_joffs";
816 *xoffs = cpl_malloc(nfiles*
sizeof(
float));
817 *yoffs = cpl_malloc(nfiles*
sizeof(
float));
823 for (i = 0; i < nfiles; i++) {
831 cpl_msg_warning(fctid,
"Unable to get WCS for %s",
856 if (status != VIR_OK) {
859 cpl_msg_warning(fctid,
"Unable to WCS difference for %s",
861 }
else if (fabs((
double)xoff) > maxoffset ||
862 fabs((
double)yoff) > maxoffset) {
864 cpl_msg_error(fctid,
"WCS offsets for %s are >%g: %g %g -- ignoring",
873 cpl_wcs_delete(wcsref);
877 for (i = 0; i < nfiles; i++) {
880 "ESO DRS XOFFDITHER",
881 (
double)(*xoffs)[i]);
883 "ESO DRS YOFFDITHER",
884 (
double)(*yoffs)[i]);
888 static void vircam_sky_xytoxy(cpl_wcs *inwcs, cpl_wcs *outwcs,
889 cpl_matrix *inxy, cpl_matrix **outxy) {
895 cpl_wcs_convert(inwcs,inxy,&radec,&wstatus,CPL_WCS_PHYS2WORLD);
896 cpl_array_delete(wstatus);
900 cpl_wcs_convert(outwcs,radec,outxy,&wstatus,CPL_WCS_WORLD2PHYS);
901 cpl_array_delete(wstatus);
902 cpl_matrix_delete(radec);
char * vircam_fits_get_filename(vir_fits *p)
int vircam_inpaint(vir_fits *in, int nbsize, int *status)
Inpaint pixels or patches in a map.
int vircam_pawsky_mask_pre(vir_fits **inlist, int nfiles, vir_fits *conf, vir_mask *mask, vir_fits *objmask, int nbsize, vir_fits **skyout, int *status)
Work out a masked sky estimate from an input jitter series.
vir_fits * vircam_fits_wrap(cpl_image *im, vir_fits *model, cpl_propertylist *phu, cpl_propertylist *ehu)
void vircam_fits_delete(vir_fits *p)
unsigned char * vircam_mask_get_data(vir_mask *m)
cpl_image * vircam_fits_get_image(vir_fits *p)
int vircam_imdither(vir_fits **inf, vir_fits **inconf, int nimages, int nconfs, float lthr, float hthr, cpl_propertylist **p, cpl_image **out, cpl_image **outc, int *status)
Dither a set of jittered observations.
int vircam_fits_set_error(vir_fits *p, int status)
int vircam_pawsky_mask(vir_fits **inlist, int nfiles, vir_fits *conf, vir_mask *mask, vir_fits **skyout, int niter, int ipix, float thresh, int nbsize, float smkern, int *status)
Work out a masked sky estimate from an input jitter series.
int vircam_pfits_get_njsteps(const cpl_propertylist *plist, int *njsteps)
Get the value of the number of observations in a jitter sequence.
float vircam_med(float *data, unsigned char *bpm, long npts)
int vircam_opm(vir_fits *infile, vir_fits *conf, int ipix, float threshold, int nbsize, float filtfwhm, int niter, int *status)
Generate an object mask from an input image.
cpl_propertylist * vircam_fits_get_phu(vir_fits *p)
cpl_propertylist * vircam_fits_get_ehu(vir_fits *p)
int vircam_mask_get_size_x(vir_mask *m)
int vircam_imcombine(vir_fits **fset, int nfits, int combtype, int scaletype, int xrej, float thresh, cpl_image **outimage, unsigned char **rejmask, unsigned char **rejplus, cpl_propertylist **drs, int *status)
Stack images into a mean or median image with rejection.
int vircam_tilesky(vir_fits **inlist, int nfiles, vir_mask *mask, vir_fits **skyout, int *status)
Work sky estimate from an input tile series.
int vircam_pfits_get_jitteri(const cpl_propertylist *plist, int *jitteri)
Get the position number of an observations in a jitter sequence.
int vircam_mask_get_size_y(vir_mask *m)
int vircam_diffxywcs(cpl_wcs *wcs, cpl_wcs *wcsref, float *xoff, float *yoff, int *status)