vircam_sky.c

00001 /* $Id: vircam_sky.c,v 1.9 2012/01/27 12:25:10 jim Exp $
00002  *
00003  * This file is part of the VIRCAM Pipeline
00004  * Copyright (C) 2008 Cambridge Astronomy Survey Unit
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: jim $
00023  * $Date: 2012/01/27 12:25:10 $
00024  * $Revision: 1.9 $
00025  * $Name: vcam-1_3_0 $
00026  */
00027 
00028 /* Includes */
00029 
00030 #ifdef HAVE_CONFIG_H
00031 #include <config.h>
00032 #endif
00033 
00034 #include <cpl.h>
00035 #include <math.h>
00036 #include <string.h>
00037 
00038 #include "vircam_sky.h"
00039 #include "vircam_mask.h"
00040 #include "vircam_fits.h"
00041 #include "vircam_mods.h"
00042 #include "vircam_utils.h"
00043 #include "vircam_stats.h"
00044 #include "vircam_wcsutils.h"
00045 #include "vircam_pfits.h"
00046 
00047 typedef struct {
00048     vir_fits **in;
00049     int      n;
00050     int      nalloc;
00051     int      status;
00052     vir_fits *xsky;
00053 } xsky_struct;
00054 
00055 static void vircam_sky_mask_grow(cpl_image *dith, float rad);
00056 static float vircam_sky_med(vir_fits *sky);
00057 /* static void vircam_sky_combine(vir_fits **inlist, int nfiles,  */
00058 /*                             vir_fits **outsky); */
00059 static void vircam_sky_joffs(vir_fits **inlist, int nfiles, float **xoffs,
00060                              float **yoffs);
00061 
00064 /*---------------------------------------------------------------------------*/
00109 /*---------------------------------------------------------------------------*/
00110 
00111 extern int vircam_pawsky_mask(vir_fits **inlist, int nfiles, vir_fits *conf,
00112                               vir_mask *mask, vir_fits **skyout, int niter, 
00113                               int ipix, float thresh, int nbsize, float smkern, 
00114                               int *status) {
00115     int i,nx,ny,nbad0,lastone,iter,*confdata,npts,nbad_init,nbad,dbad;
00116     int xx1,xx2,yy1,yy2;
00117     const char *fctid = "vircam_pawsky_mask";
00118     cpl_image *dith,*dithc,*skyim,*im,*newim,*outim;
00119     cpl_mask *cplmask,*dithmask,*newmask,*curmask;
00120     vir_fits **list_ss,*dithf,*dithcf;
00121     unsigned char *inbpm,*rejmask,*rejplus;
00122     float medsky,*xoffs,*yoffs,mindx,mindy,fbad;
00123     cpl_propertylist *p,*drs;
00124 
00125     /* Inherited status */
00126 
00127     *skyout = NULL;
00128     if (*status != VIR_OK) 
00129         return(*status);
00130 
00131     /* If there aren't any images, then get out of here */
00132 
00133     if (nfiles == 0) {
00134         cpl_msg_error(fctid,"Sky correction impossible. No science frames");
00135         return(VIR_FATAL);
00136     }
00137 
00138     /* Wrap the input mask into a cpl_mask structure and use it to set the
00139        internal mask for each of the input images */
00140 
00141     inbpm = vircam_mask_get_data(mask);
00142     nx = vircam_mask_get_size_x(mask);
00143     ny = vircam_mask_get_size_y(mask);
00144     cplmask = cpl_mask_wrap((cpl_size)nx,(cpl_size)ny,(cpl_binary *)inbpm);
00145     for (i = 0; i < nfiles; i++)
00146         cpl_image_reject_from_mask(vircam_fits_get_image(inlist[i]),cplmask);
00147     cpl_mask_unwrap(cplmask);
00148 
00149     /* Do an initial sky combination */
00150 
00151 /*     vircam_sky_combine(inlist,nfiles,skyout); */
00152     vircam_imcombine(inlist,nfiles,1,1,0,2.0,&outim,&rejmask,
00153                      &rejplus,&drs,status);
00154     *skyout = vircam_fits_wrap(outim,inlist[0],NULL,NULL);    
00155     freespace(rejmask);
00156     freespace(rejplus);
00157     freepropertylist(drs);
00158 
00159     /* Clean up any blank bits */
00160 
00161     (void)vircam_inpaint(*skyout,nbsize,status);
00162 
00163     /* If this is the only iteration then get out of here now */
00164 
00165     if (niter == 0)
00166         return(*status);
00167 
00168     /* Work out the median sky, ignoring the bad bits */
00169 
00170     medsky = vircam_sky_med(*skyout);
00171 
00172     /* Get jitter offsets from wcs */
00173 
00174     vircam_sky_joffs(inlist,nfiles,&xoffs,&yoffs);
00175     mindx = xoffs[0];
00176     mindy = yoffs[0];
00177     for (i = 1; i < nfiles; i++) {
00178         mindx = min(mindx,xoffs[i]);
00179         mindy = min(mindy,yoffs[i]);
00180     }
00181 
00182     /* Do an initial subtraction */
00183 
00184     list_ss = cpl_malloc(nfiles*sizeof(vir_fits *));
00185     skyim = vircam_fits_get_image(*skyout);
00186     for (i = 0; i < nfiles; i++) {
00187         im = vircam_fits_get_image(inlist[i]);
00188         newim = cpl_image_subtract_create(im,skyim);
00189         cpl_image_add_scalar(newim,(double)medsky);
00190         list_ss[i] = vircam_fits_wrap(newim,inlist[i],NULL,NULL);
00191     }
00192 
00193     /* Set up some counters and begin the iteration loop */
00194 
00195     nbad0 = 0;
00196     lastone = 0;
00197     for (iter = 1; iter <= niter; iter++) {
00198         if (lastone)
00199             break;
00200         lastone = (iter == niter);
00201 
00202         /* Dither the sky subtracted input images */
00203 
00204         (void)vircam_imdither(list_ss,&conf,nfiles,1,5.0,5.0,&p,&dith,
00205                               &dithc,status);
00206         cpl_propertylist_delete(p);
00207 
00208         /* How many dead pixels are there in the dithered image? */
00209 
00210         confdata = cpl_image_get_data_int(dithc);
00211         npts = (int)cpl_image_get_size_x(dithc)*(int)cpl_image_get_size_y(dithc);
00212         nbad_init = 0;
00213         for (i = 0; i < npts; i++)
00214             if (confdata[i] == 0)
00215                 nbad_init++;
00216 
00217         /* Get rid of the sky subtracted images */
00218 
00219         for (i = 0; i < nfiles; i++)
00220             vircam_fits_delete(list_ss[i]);
00221 
00222         /* Wrap the result */
00223 
00224         dithf = vircam_fits_wrap(dith,inlist[0],NULL,NULL);
00225         dithcf = vircam_fits_wrap(dithc,conf,NULL,NULL);
00226 
00227         /* Now get a bad pixel mask from this dithered image */
00228 
00229         (void)vircam_opm(dithf,dithcf,ipix,thresh,nbsize,smkern,niter,status);
00230 
00231         /* How many flagged pixels are there, not counting the ones already
00232            flagged in the confidence map */
00233 
00234         nbad = (int)cpl_image_count_rejected((const cpl_image *)dith) - nbad_init;
00235         dbad = nbad - nbad0;
00236         fbad = (iter > 1 ? (float)abs(dbad)/(float)nbad0 : 10000.0);
00237         cpl_msg_info(fctid,
00238                      "   Iteration: %" CPL_SIZE_FORMAT ", Nreject: %" CPL_SIZE_FORMAT " %" CPL_SIZE_FORMAT,
00239                      (cpl_size)iter,(cpl_size)nbad,(cpl_size)nbad0);
00240         if (fbad < 0.025 || dbad < 0) {
00241             lastone = 1;
00242         } else {
00243             nbad0 = nbad;
00244         }
00245 
00246         /* Allow the mask to grow before the next iteration */
00247 
00248         vircam_sky_mask_grow(dith,2);
00249 
00250         /* Right, now decide which part of the mask belongs to each of the 
00251            input images and update the input mask. */
00252 
00253         dithmask = cpl_image_get_bpm(dith);
00254         for (i = 0; i < nfiles; i++) {
00255             xx1 = (int)(-mindx + xoffs[i] + 1.5);
00256             xx2 = xx1 + nx - 1;
00257             yy1 = (int)(-mindy + yoffs[i] + 1.5);
00258             yy2 = yy1 + ny - 1;
00259             newmask = cpl_mask_extract(dithmask,(cpl_size)xx1,(cpl_size)yy1,
00260                                        (cpl_size)xx2,(cpl_size)yy2);
00261             curmask = cpl_image_get_bpm(vircam_fits_get_image(inlist[i]));
00262             cpl_mask_or(curmask,newmask);
00263             cpl_mask_delete(newmask);
00264         }
00265 
00266         /* Delete the dither and its confidence map */
00267         
00268         vircam_fits_delete(dithf);
00269         vircam_fits_delete(dithcf);
00270 
00271         /* Do a new sky combination using these new object masks */
00272 
00273 /*      vircam_sky_combine(inlist,nfiles,skyout); */
00274         vircam_imcombine(inlist,nfiles,1,1,0,2.0,&outim,&rejmask,
00275                          &rejplus,&drs,status);
00276         *skyout = vircam_fits_wrap(outim,inlist[0],NULL,NULL);    
00277         freespace(rejmask);
00278         freespace(rejplus);
00279         freepropertylist(drs);
00280 
00281         /* Clean up any blank bits */
00282 
00283         (void)vircam_inpaint(*skyout,nbsize,status);
00284 
00285         /* Do the sky subtraction again so long as this isn't 
00286            the last iteration */
00287 
00288         if (! lastone) {
00289             skyim = vircam_fits_get_image(*skyout);
00290             for (i = 0; i < nfiles; i++) {
00291                 im = vircam_fits_get_image(inlist[i]);
00292                 newim = cpl_image_subtract_create(im,skyim);
00293                 cpl_image_add_scalar(newim,(double)medsky);
00294                 list_ss[i] = vircam_fits_wrap(newim,inlist[i],NULL,NULL);
00295             }
00296         }
00297     }
00298 
00299     /* Free up some workspace that we've collected along the way */
00300 
00301     freespace(xoffs);
00302     freespace(yoffs);
00303     freespace(list_ss);
00304     return(*status);
00305 }
00306 
00307 /*---------------------------------------------------------------------------*/
00340 /*---------------------------------------------------------------------------*/
00341 
00342 extern int vircam_tilesky(vir_fits **inlist, int nfiles, vir_mask *mask, 
00343                           vir_fits **skyout, int *status) { 
00344     int i,njit,nx,ny,ji,ns,npts,j;
00345     unsigned char *inbpm,*rejmask,*rejplus;
00346     cpl_mask *cplmask;
00347     xsky_struct *xskys;
00348     cpl_propertylist *drs;
00349     cpl_image *outim;
00350     cpl_binary *immask;
00351     vir_fits **xsky_fits;
00352     float *test,skymed,*odata,*idata,skysig;
00353     const char *fctid = "vircam_tilesky";
00354 
00355     /* Inherited status */
00356 
00357     *skyout = NULL;
00358     if (*status != VIR_OK) 
00359         return(*status);
00360 
00361     /* If there aren't any images, then get out of here */
00362 
00363     if (nfiles == 0) {
00364         cpl_msg_error(fctid,"Sky correction impossible. No science frames");
00365         return(VIR_FATAL);
00366     }
00367 
00368     /* Wrap the input mask into a cpl_mask structure and use it to set the
00369        internal mask for each of the input images */
00370 
00371     inbpm = vircam_mask_get_data(mask);
00372     nx = vircam_mask_get_size_x(mask);
00373     ny = vircam_mask_get_size_y(mask);
00374     npts = nx*ny;
00375     cplmask = cpl_mask_wrap((cpl_size)nx,(cpl_size)ny,(cpl_binary *)inbpm);
00376     for (i = 0; i < nfiles; i++)
00377         cpl_image_reject_from_mask(vircam_fits_get_image(inlist[i]),cplmask);
00378     cpl_mask_unwrap(cplmask);
00379 
00380     /* For each file, do a quickie background analysis and reject high
00381        pixels */
00382 
00383     test = cpl_malloc(nx*ny*sizeof(float));
00384     for (i = 0; i < nfiles; i++) {
00385         vircam_backmap(inlist[i],mask,64,&outim,&skymed);
00386         odata = cpl_image_get_data_float(outim);
00387         idata = cpl_image_get_data_float(vircam_fits_get_image(inlist[i]));
00388         for (j = 0; j < npts; j++) 
00389             test[j] = idata[j] - odata[j];
00390         vircam_qmedsig(test,inbpm,(long)npts,3.0,2,-65535.0,65535.0,&skymed,
00391                        &skysig);
00392         immask = cpl_mask_get_data(cpl_image_get_bpm(vircam_fits_get_image(inlist[i])));
00393         for (j = 0; j < npts; j++) 
00394             if (test[j] > (skymed + 1.5*skysig)) 
00395                 immask[j] = 1;
00396         cpl_image_delete(outim);
00397     }
00398     freespace(test);
00399 
00400     /* How many jitter steps are there? */
00401 
00402     (void)vircam_pfits_get_njsteps(vircam_fits_get_phu(inlist[0]),&njit);
00403 
00404     /* Allocate some workspce */
00405 
00406     xskys = cpl_malloc(njit*sizeof(xsky_struct));
00407     for (i = 0; i < njit; i++) {
00408         xskys[i].n = 0;
00409         xskys[i].in = cpl_malloc(8*sizeof(vir_fits *));
00410         xskys[i].nalloc = 8;
00411         xskys[i].xsky = NULL;
00412         xskys[i].status = VIR_OK;
00413     }
00414     xsky_fits = cpl_malloc(njit*sizeof(vir_fits *));
00415 
00416     /* Now loop through all the files and put them into the relevant 
00417        structure depending upon where they are in the jitter pattern.
00418        NB: We don't have to check on the status of the individual
00419        frames because only good frames should have been passed in by
00420        the calling routine. */
00421 
00422     for (i = 0; i < nfiles; i++) {
00423         (void)vircam_pfits_get_jitteri(vircam_fits_get_phu(inlist[i]),&ji);
00424         ji--;
00425         if (xskys[ji].n == xskys[ji].nalloc) {
00426             xskys[ji].in = cpl_realloc(xskys[ji].in,
00427                                        (xskys[ji].nalloc+8)*sizeof(vir_fits *));
00428             xskys[ji].nalloc += 8;
00429         }
00430         xskys[ji].in[xskys[ji].n] = inlist[i];
00431         xskys[ji].n += 1;
00432     }
00433     
00434     /* Now loop through each of these groups and form a sky file with
00435        rejection */
00436 
00437     ns = 0;
00438     for (i = 0; i < njit; i++) {
00439         *status = VIR_OK;
00440         if (xskys[i].n == 0) {
00441             xskys[i].xsky = NULL;
00442             continue;
00443         } else if (xskys[i].n == 1) {
00444             xskys[i].xsky = NULL;
00445             xsky_fits[ns++] = xskys[i].in[0];
00446             continue;
00447         }
00448         outim = NULL;
00449         (void)vircam_imcombine(xskys[i].in,xskys[i].n,1,1,0,1.0,&outim,&rejmask,
00450                                &rejplus,&drs,status);
00451         freespace(rejmask);
00452         freespace(rejplus);
00453         freepropertylist(drs);
00454         if (*status == VIR_OK) {
00455             xskys[i].xsky = vircam_fits_wrap(outim,xskys[i].in[0],NULL,NULL);
00456             xsky_fits[ns++] = xskys[i].xsky;
00457         } else {
00458             freeimage(outim);
00459         }
00460     }
00461 
00462     /* Now combine all the intermediate skies to form the final sky */
00463 
00464     if (ns != 0) {
00465         outim = NULL;
00466         (void)vircam_imcombine(xsky_fits,ns,1,1,0,1.0,&outim,&rejmask,&rejplus,
00467                                &drs,status);
00468         freespace(rejmask);
00469         freespace(rejplus);
00470         freepropertylist(drs);
00471         if (*status == VIR_OK) {
00472             *skyout = vircam_fits_wrap(outim,inlist[0],NULL,NULL);
00473         } else {
00474             freeimage(outim);
00475             *skyout = NULL;
00476         }
00477     } else {
00478         *skyout = NULL;
00479     }
00480 
00481     /* Tidy and exit */
00482 
00483     freespace(xsky_fits);
00484     for (i = 0; i < njit; i++) {
00485         freespace(xskys[i].in);
00486         freefits(xskys[i].xsky);
00487     }
00488     freespace(xskys);
00489     return(*status);
00490 }
00491 
00492 
00493 /*---------------------------------------------------------------------------*/
00511 /*---------------------------------------------------------------------------*/
00512 
00513 static void vircam_sky_mask_grow(cpl_image *dith, float rad) {
00514     cpl_binary *inmap,*outmap;
00515     int nx,ny,ir,i,j,indx,ixmin,ixmax,iymin,iymax,ii,jj,indx2;
00516     float dx,dy,radius;
00517 
00518     /* Get the input map */
00519 
00520     inmap = cpl_mask_get_data(cpl_image_get_bpm(dith));
00521     nx = (int)cpl_image_get_size_x(dith);
00522     ny = (int)cpl_image_get_size_y(dith);
00523 
00524     /* Get an output map of the same size. Copy the input map to it */
00525 
00526     outmap = cpl_malloc(nx*ny*sizeof(*outmap));
00527     memmove(outmap,inmap,nx*ny*sizeof(*inmap));
00528 
00529     /* What is the minimum cell size that we need to consider given the 
00530        input radius */
00531 
00532     ir = vircam_nint(rad);
00533 
00534     /* Right, loop through the input image. If the current input pixel is
00535        not flagged, then move on to the next one. If it is, then look at
00536        a cell around it. Find all the pixels in that cell that are within
00537        the grow radius and flag them */
00538 
00539     for (j = 0; j < ny; j++) {
00540         for (i = 0; i < nx; i++) {
00541             indx = j*nx + i;
00542             if (! inmap[indx])
00543                 continue;
00544             ixmin = max(0,i-ir);
00545             ixmax = min(nx-1,i+ir);
00546             iymin = max(0,j-ir);
00547             iymax = min(ny-1,j+ir);
00548             for (jj = iymin; jj <= iymax; jj++) {
00549                 dy = (float)(jj - j);
00550                 for (ii = ixmin; ii <= ixmax; ii++) {
00551                     dx = (float)(ii - i);
00552                     radius = (float)sqrt(pow(dx,2.0) + pow(dy,2.0));
00553                     if (radius <= rad) { 
00554                         indx2 = jj*nx + ii;
00555                         outmap[indx2] = 1;
00556                     }
00557                 }
00558             }
00559         }
00560     }
00561 
00562     /* Now move the result back into the input mask. Free up workspace
00563        and get out of here */
00564    
00565     memmove(inmap,outmap,nx*ny*sizeof(*inmap));
00566     cpl_free(outmap);
00567 }
00568 
00569 /*---------------------------------------------------------------------------*/
00587 /*---------------------------------------------------------------------------*/
00588 
00589 static float vircam_sky_med(vir_fits *sky) {
00590     int npts;
00591     float *data,med;
00592     unsigned char *bpm;
00593     cpl_image *skyim;
00594 
00595     /* Get the size of the data array */
00596 
00597     skyim = vircam_fits_get_image(sky);
00598     npts = (int)cpl_image_get_size_x(skyim)*(int)cpl_image_get_size_y(skyim);
00599 
00600     /* Get the data */
00601 
00602     data = cpl_image_get_data_float(skyim);
00603     bpm = (unsigned char *)cpl_mask_get_data(cpl_image_get_bpm(skyim));
00604 
00605     /* Get the median */
00606 
00607     med = vircam_med(data,bpm,(long)npts);
00608     return(med);
00609 }
00610 
00611 /*---------------------------------------------------------------------------*/
00631 /*---------------------------------------------------------------------------*/
00632 
00633 /* static void vircam_sky_combine(vir_fits **inlist, int nfiles,  */
00634 /*                             vir_fits **outsky) { */
00635 /*     float *back,*data,medback,**datas,*outdata,*buf; */
00636 /*     cpl_binary *outbpm,*mdata,**mdatas; */
00637 /*     cpl_image *im,*outim; */
00638 /*     cpl_mask *m; */
00639 /*     vir_fits *model; */
00640 /*     int i,j,n,nx,ny; */
00641 /*     long npts; */
00642 
00643 /*     /\* Initialise a few things *\/ */
00644 
00645 /*     model = inlist[0]; */
00646 /*     nx = cpl_image_get_size_x(vircam_fits_get_image(model)); */
00647 /*     ny = cpl_image_get_size_y(vircam_fits_get_image(model)); */
00648 /*     npts = (long)(nx*ny); */
00649 
00650 /*     /\* Get some workspace *\/ */
00651 
00652 /*     back = cpl_malloc(nfiles*sizeof(float)); */
00653 /*     datas = cpl_malloc(nfiles*sizeof(float *)); */
00654 /*     mdatas = cpl_malloc(nfiles*sizeof(float *)); */
00655 /*     buf = cpl_malloc(nfiles*sizeof(float)); */
00656 
00657 /*     /\* Get the background flux for each image, masking out bad pixels */
00658 /*        using the input masks. Work out the zero points that need to */
00659 /*        be applied to bring them to a common background *\/ */
00660 
00661 /*     for (i = 0; i < nfiles; i++) { */
00662 /*      im = vircam_fits_get_image(inlist[i]); */
00663 /*      datas[i] = cpl_image_get_data_float(im); */
00664 /*      data = datas[i]; */
00665 /*      mdatas[i] = cpl_mask_get_data(cpl_image_get_bpm(im)); */
00666 /*      mdata = mdatas[i]; */
00667 /*         back[i] = vircam_med(data,mdata,npts); */
00668 /*     } */
00669 /*     medback = vircam_med(back,NULL,nfiles); */
00670 /*     for (i = 0; i < nfiles; i++)  */
00671 /*      back[i] = medback - back[i]; */
00672 
00673 /*     /\* Create the output mask *\/ */
00674 
00675 /*     outbpm = cpl_malloc(nx*ny*sizeof(unsigned char)); */
00676 
00677 /*     /\* Create output image *\/ */
00678 
00679 /*     outim = cpl_image_new(nx,ny,CPL_TYPE_FLOAT); */
00680 /*     outdata = cpl_image_get_data_float(outim); */
00681 
00682 /*     /\* Right loop for each output pixel and do the median *\/ */
00683 
00684 /*     for (i = 0; i < npts; i++) { */
00685 /*      n = 0; */
00686 /*      for (j = 0; j < nfiles; j++) { */
00687 /*          if (mdatas[j][i] == 0)  */
00688 /*              buf[n++] = datas[j][i] + back[j]; */
00689 /*      } */
00690 /*      switch (n) { */
00691 /*      case 0: */
00692 /*          outdata[i] = 0; */
00693 /*          outbpm[i] = 1; */
00694 /*          break; */
00695 /*      case 1: */
00696 /*          outdata[i] = buf[0]; */
00697 /*          outbpm[i] = 0; */
00698 /*          break; */
00699 /*      default: */
00700 /*          outdata[i] = vircam_med(buf,NULL,n); */
00701 /*          outbpm[i] = 0; */
00702 /*          break; */
00703 /*      } */
00704 /*     } */
00705 
00706 /*     /\* Wrap the output image in a vir_fits structure *\/ */
00707 
00708 /*     *outsky = vircam_fits_wrap(outim,model,NULL,NULL);     */
00709 /*     m = cpl_mask_wrap(nx,ny,(cpl_binary *)outbpm); */
00710 /*     cpl_image_reject_from_mask(outim,(const cpl_mask *)m); */
00711 /*     cpl_mask_unwrap(m); */
00712 
00713 /*     /\* Free some workspace *\/ */
00714 
00715 /*     freespace(back); */
00716 /*     freespace(datas); */
00717 /*     freespace(mdatas); */
00718 /*     freespace(buf); */
00719 /*     freespace(outbpm); */
00720 /* }  */
00721 
00722 
00723 /*---------------------------------------------------------------------------*/
00745 /*---------------------------------------------------------------------------*/
00746 
00747 static void vircam_sky_joffs(vir_fits **inlist, int nfiles, float **xoffs,
00748                              float **yoffs) {
00749     float xoff,yoff;
00750     cpl_wcs *wcsref,*wcs;
00751     int refset,i,status;
00752     const double maxoffset = 2048;
00753     vir_fits *ff;
00754     const char *fctid = "vircam_sky_joffs";
00755 
00756     /* Get a bit of workspace to hold the offsets */
00757 
00758     *xoffs = cpl_malloc(nfiles*sizeof(float));
00759     *yoffs = cpl_malloc(nfiles*sizeof(float));
00760 
00761     /* Work out the jitter offsets from the WCS. First loop for each image */
00762 
00763     refset = 0;
00764     wcsref = NULL;
00765     for (i = 0; i < nfiles; i++) {
00766         ff = inlist[i];
00767         wcs = cpl_wcs_new_from_propertylist(vircam_fits_get_ehu(ff));
00768 
00769         /* If we can't get a WCS for this image, then signal that with
00770            a warning */
00771 
00772         if (wcs == NULL) {
00773             cpl_msg_warning(fctid,"Unable to get WCS for %s",
00774                             vircam_fits_get_filename(ff));
00775             (*xoffs)[i] = 0.0;
00776             (*yoffs)[i] = 0.0;
00777             vircam_fits_set_error(ff,VIR_WARN);
00778             continue;
00779         }
00780 
00781         /* Define the reference wcs pointer and set the first offset to zero */
00782 
00783         if (! refset) {
00784             (*xoffs)[0] = 0.0;
00785             (*yoffs)[0] = 0.0;
00786             refset = 1;
00787             wcsref = wcs;
00788             continue;
00789         }
00790 
00791         /* Work out the x,y offset */
00792 
00793         status = VIR_OK;
00794         (void)vircam_diffxywcs(wcs,wcsref,&xoff,&yoff,&status);
00795 
00796         /* Did it work? If not the set a warning status for this file */
00797 
00798         if (status != VIR_OK) {
00799             (*xoffs)[i] = 0.0;
00800             (*yoffs)[i] = 0.0;
00801             cpl_msg_warning(fctid,"Unable to WCS difference for %s",
00802                             vircam_fits_get_filename(ff));
00803         } else if (fabs((double)xoff) > maxoffset || 
00804                    fabs((double)yoff) > maxoffset) {
00805             vircam_fits_set_error(ff,VIR_FATAL);
00806             cpl_msg_error(fctid,"WCS offsets for %s are >%g: %g %g -- ignoring",
00807                           vircam_fits_get_filename(ff),maxoffset,xoff,yoff);
00808         } else {
00809             (*xoffs)[i] = xoff;
00810             (*yoffs)[i] = yoff;
00811         }
00812         cpl_wcs_delete(wcs);
00813     }
00814     if (wcsref != NULL) 
00815         cpl_wcs_delete(wcsref);
00816 
00817     /* Write the results to the headers */
00818 
00819     for (i = 0; i < nfiles; i++) {
00820         ff = inlist[i];
00821         cpl_propertylist_update_double(vircam_fits_get_ehu(ff),
00822                                        "ESO DRS XOFFDITHER",
00823                                        (double)(*xoffs)[i]);
00824         cpl_propertylist_update_double(vircam_fits_get_ehu(ff),
00825                                        "ESO DRS YOFFDITHER",
00826                                        (double)(*yoffs)[i]);
00827     }
00828 }
00829     
00832 /*
00833 
00834 $Log: vircam_sky.c,v $
00835 Revision 1.9  2012/01/27 12:25:10  jim
00836 Fixed some casts
00837 
00838 Revision 1.8  2012/01/15 17:40:09  jim
00839 Minor modifications to take into accout the changes in cpl API for v6
00840 
00841 Revision 1.7  2010/06/30 12:42:00  jim
00842 A few fixes to stop compiler compaints
00843 
00844 Revision 1.6  2009/02/23 10:46:26  jim
00845 Modified tilesky to try and get rid of some of the low level glow around
00846 bright and extended objects
00847 
00848 Revision 1.5  2009/02/20 11:01:13  jim
00849 Added vircam_tilesky. Commented out vircam_skycombine as it's not being
00850 used at present and it's generating a compiler error. May delete it
00851 completely later
00852 
00853 Revision 1.4  2008/11/25 06:23:09  jim
00854 Added some routine prologues
00855 
00856 Revision 1.3  2008/11/21 10:12:36  jim
00857 Fixed typo
00858 
00859 Revision 1.2  2008/10/24 10:57:19  jim
00860 Fixed bug in pawsky_mask so that the bad pixels in the confidence map are
00861 folded into the object mask
00862 
00863 Revision 1.1  2008/10/13 08:13:21  jim
00864 New entry
00865 
00866 */

Generated on 15 Mar 2012 for VIRCAM Pipeline by  doxygen 1.6.1