vircam_sky.c

00001 /* $Id: vircam_sky.c,v 1.7 2010/06/30 12:42:00 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: 2010/06/30 12:42:00 $
00024  * $Revision: 1.7 $
00025  * $Name: v1-1-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(nx,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 = cpl_image_get_size_x(dithc)*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 = 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,"   Iteration: %d, Nreject: %d %d",iter,nbad,
00238                      nbad0);
00239         if (fbad < 0.025 || dbad < 0) {
00240             lastone = 1;
00241         } else {
00242             nbad0 = nbad;
00243         }
00244 
00245         /* Allow the mask to grow before the next iteration */
00246 
00247         vircam_sky_mask_grow(dith,2);
00248 
00249         /* Right, now decide which part of the mask belongs to each of the 
00250            input images and update the input mask. */
00251 
00252         dithmask = cpl_image_get_bpm(dith);
00253         for (i = 0; i < nfiles; i++) {
00254             xx1 = (int)(-mindx + xoffs[i] + 1.5);
00255             xx2 = xx1 + nx - 1;
00256             yy1 = (int)(-mindy + yoffs[i] + 1.5);
00257             yy2 = yy1 + ny - 1;
00258             newmask = cpl_mask_extract(dithmask,xx1,yy1,xx2,yy2);
00259             curmask = cpl_image_get_bpm(vircam_fits_get_image(inlist[i]));
00260             cpl_mask_or(curmask,newmask);
00261             cpl_mask_delete(newmask);
00262         }
00263 
00264         /* Delete the dither and its confidence map */
00265         
00266         vircam_fits_delete(dithf);
00267         vircam_fits_delete(dithcf);
00268 
00269         /* Do a new sky combination using these new object masks */
00270 
00271 /*      vircam_sky_combine(inlist,nfiles,skyout); */
00272         vircam_imcombine(inlist,nfiles,1,1,0,2.0,&outim,&rejmask,
00273                          &rejplus,&drs,status);
00274         *skyout = vircam_fits_wrap(outim,inlist[0],NULL,NULL);    
00275         freespace(rejmask);
00276         freespace(rejplus);
00277         freepropertylist(drs);
00278 
00279         /* Clean up any blank bits */
00280 
00281         (void)vircam_inpaint(*skyout,nbsize,status);
00282 
00283         /* Do the sky subtraction again so long as this isn't 
00284            the last iteration */
00285 
00286         if (! lastone) {
00287             skyim = vircam_fits_get_image(*skyout);
00288             for (i = 0; i < nfiles; i++) {
00289                 im = vircam_fits_get_image(inlist[i]);
00290                 newim = cpl_image_subtract_create(im,skyim);
00291                 cpl_image_add_scalar(newim,(double)medsky);
00292                 list_ss[i] = vircam_fits_wrap(newim,inlist[i],NULL,NULL);
00293             }
00294         }
00295     }
00296 
00297     /* Free up some workspace that we've collected along the way */
00298 
00299     freespace(xoffs);
00300     freespace(yoffs);
00301     freespace(list_ss);
00302     return(*status);
00303 }
00304 
00305 /*---------------------------------------------------------------------------*/
00338 /*---------------------------------------------------------------------------*/
00339 
00340 extern int vircam_tilesky(vir_fits **inlist, int nfiles, vir_mask *mask, 
00341                           vir_fits **skyout, int *status) { 
00342     int i,njit,nx,ny,ji,ns,npts,j;
00343     unsigned char *inbpm,*rejmask,*rejplus;
00344     cpl_mask *cplmask;
00345     xsky_struct *xskys;
00346     cpl_propertylist *drs;
00347     cpl_image *outim;
00348     cpl_binary *immask;
00349     vir_fits **xsky_fits;
00350     float *test,skymed,*odata,*idata,skysig;
00351     const char *fctid = "vircam_tilesky";
00352 
00353     /* Inherited status */
00354 
00355     *skyout = NULL;
00356     if (*status != VIR_OK) 
00357         return(*status);
00358 
00359     /* If there aren't any images, then get out of here */
00360 
00361     if (nfiles == 0) {
00362         cpl_msg_error(fctid,"Sky correction impossible. No science frames");
00363         return(VIR_FATAL);
00364     }
00365 
00366     /* Wrap the input mask into a cpl_mask structure and use it to set the
00367        internal mask for each of the input images */
00368 
00369     inbpm = vircam_mask_get_data(mask);
00370     nx = vircam_mask_get_size_x(mask);
00371     ny = vircam_mask_get_size_y(mask);
00372     npts = nx*ny;
00373     cplmask = cpl_mask_wrap(nx,ny,(cpl_binary *)inbpm);
00374     for (i = 0; i < nfiles; i++)
00375         cpl_image_reject_from_mask(vircam_fits_get_image(inlist[i]),cplmask);
00376     cpl_mask_unwrap(cplmask);
00377 
00378     /* For each file, do a quickie background analysis and reject high
00379        pixels */
00380 
00381     test = cpl_malloc(nx*ny*sizeof(float));
00382     for (i = 0; i < nfiles; i++) {
00383         vircam_backmap(inlist[i],mask,64,&outim,&skymed);
00384         odata = cpl_image_get_data_float(outim);
00385         idata = cpl_image_get_data_float(vircam_fits_get_image(inlist[i]));
00386         for (j = 0; j < npts; j++) 
00387             test[j] = idata[j] - odata[j];
00388         vircam_qmedsig(test,inbpm,(long)npts,3.0,2,-65535.0,65535.0,&skymed,
00389                        &skysig);
00390         immask = cpl_mask_get_data(cpl_image_get_bpm(vircam_fits_get_image(inlist[i])));
00391         for (j = 0; j < npts; j++) 
00392             if (test[j] > (skymed + 1.5*skysig)) 
00393                 immask[j] = 1;
00394         cpl_image_delete(outim);
00395     }
00396     freespace(test);
00397 
00398     /* How many jitter steps are there? */
00399 
00400     (void)vircam_pfits_get_njsteps(vircam_fits_get_phu(inlist[0]),&njit);
00401 
00402     /* Allocate some workspce */
00403 
00404     xskys = cpl_malloc(njit*sizeof(xsky_struct));
00405     for (i = 0; i < njit; i++) {
00406         xskys[i].n = 0;
00407         xskys[i].in = cpl_malloc(8*sizeof(vir_fits *));
00408         xskys[i].nalloc = 8;
00409         xskys[i].xsky = NULL;
00410         xskys[i].status = VIR_OK;
00411     }
00412     xsky_fits = cpl_malloc(njit*sizeof(vir_fits *));
00413 
00414     /* Now loop through all the files and put them into the relevant 
00415        structure depending upon where they are in the jitter pattern.
00416        NB: We don't have to check on the status of the individual
00417        frames because only good frames should have been passed in by
00418        the calling routine. */
00419 
00420     for (i = 0; i < nfiles; i++) {
00421         (void)vircam_pfits_get_jitteri(vircam_fits_get_phu(inlist[i]),&ji);
00422         ji--;
00423         if (xskys[ji].n == xskys[ji].nalloc) {
00424             xskys[ji].in = cpl_realloc(xskys[ji].in,
00425                                        (xskys[ji].nalloc+8)*sizeof(vir_fits *));
00426             xskys[ji].nalloc += 8;
00427         }
00428         xskys[ji].in[xskys[ji].n] = inlist[i];
00429         xskys[ji].n += 1;
00430     }
00431     
00432     /* Now loop through each of these groups and form a sky file with
00433        rejection */
00434 
00435     ns = 0;
00436     for (i = 0; i < njit; i++) {
00437         *status = VIR_OK;
00438         if (xskys[i].n == 0) {
00439             xskys[i].xsky = NULL;
00440             continue;
00441         } else if (xskys[i].n == 1) {
00442             xskys[i].xsky = NULL;
00443             xsky_fits[ns++] = xskys[i].in[0];
00444             continue;
00445         }
00446         outim = NULL;
00447         (void)vircam_imcombine(xskys[i].in,xskys[i].n,1,1,0,1.0,&outim,&rejmask,
00448                                &rejplus,&drs,status);
00449         freespace(rejmask);
00450         freespace(rejplus);
00451         freepropertylist(drs);
00452         if (*status == VIR_OK) {
00453             xskys[i].xsky = vircam_fits_wrap(outim,xskys[i].in[0],NULL,NULL);
00454             xsky_fits[ns++] = xskys[i].xsky;
00455         } else {
00456             freeimage(outim);
00457         }
00458     }
00459 
00460     /* Now combine all the intermediate skies to form the final sky */
00461 
00462     if (ns != 0) {
00463         outim = NULL;
00464         (void)vircam_imcombine(xsky_fits,ns,1,1,0,1.0,&outim,&rejmask,&rejplus,
00465                                &drs,status);
00466         freespace(rejmask);
00467         freespace(rejplus);
00468         freepropertylist(drs);
00469         if (*status == VIR_OK) {
00470             *skyout = vircam_fits_wrap(outim,inlist[0],NULL,NULL);
00471         } else {
00472             freeimage(outim);
00473             *skyout = NULL;
00474         }
00475     } else {
00476         *skyout = NULL;
00477     }
00478 
00479     /* Tidy and exit */
00480 
00481     freespace(xsky_fits);
00482     for (i = 0; i < njit; i++) {
00483         freespace(xskys[i].in);
00484         freefits(xskys[i].xsky);
00485     }
00486     freespace(xskys);
00487     return(*status);
00488 }
00489 
00490 
00491 /*---------------------------------------------------------------------------*/
00509 /*---------------------------------------------------------------------------*/
00510 
00511 static void vircam_sky_mask_grow(cpl_image *dith, float rad) {
00512     cpl_binary *inmap,*outmap;
00513     int nx,ny,ir,i,j,indx,ixmin,ixmax,iymin,iymax,ii,jj,indx2;
00514     float dx,dy,radius;
00515 
00516     /* Get the input map */
00517 
00518     inmap = cpl_mask_get_data(cpl_image_get_bpm(dith));
00519     nx = cpl_image_get_size_x(dith);
00520     ny = cpl_image_get_size_y(dith);
00521 
00522     /* Get an output map of the same size. Copy the input map to it */
00523 
00524     outmap = cpl_malloc(nx*ny*sizeof(*outmap));
00525     memmove(outmap,inmap,nx*ny*sizeof(*inmap));
00526 
00527     /* What is the minimum cell size that we need to consider given the 
00528        input radius */
00529 
00530     ir = vircam_nint(rad);
00531 
00532     /* Right, loop through the input image. If the current input pixel is
00533        not flagged, then move on to the next one. If it is, then look at
00534        a cell around it. Find all the pixels in that cell that are within
00535        the grow radius and flag them */
00536 
00537     for (j = 0; j < ny; j++) {
00538         for (i = 0; i < nx; i++) {
00539             indx = j*nx + i;
00540             if (! inmap[indx])
00541                 continue;
00542             ixmin = max(0,i-ir);
00543             ixmax = min(nx-1,i+ir);
00544             iymin = max(0,j-ir);
00545             iymax = min(ny-1,j+ir);
00546             for (jj = iymin; jj <= iymax; jj++) {
00547                 dy = (float)(jj - j);
00548                 for (ii = ixmin; ii <= ixmax; ii++) {
00549                     dx = (float)(ii - i);
00550                     radius = (float)sqrt(pow(dx,2.0) + pow(dy,2.0));
00551                     if (radius <= rad) { 
00552                         indx2 = jj*nx + ii;
00553                         outmap[indx2] = 1;
00554                     }
00555                 }
00556             }
00557         }
00558     }
00559 
00560     /* Now move the result back into the input mask. Free up workspace
00561        and get out of here */
00562    
00563     memmove(inmap,outmap,nx*ny*sizeof(*inmap));
00564     cpl_free(outmap);
00565 }
00566 
00567 /*---------------------------------------------------------------------------*/
00585 /*---------------------------------------------------------------------------*/
00586 
00587 static float vircam_sky_med(vir_fits *sky) {
00588     int npts;
00589     float *data,med;
00590     unsigned char *bpm;
00591     cpl_image *skyim;
00592 
00593     /* Get the size of the data array */
00594 
00595     skyim = vircam_fits_get_image(sky);
00596     npts = cpl_image_get_size_x(skyim)*cpl_image_get_size_y(skyim);
00597 
00598     /* Get the data */
00599 
00600     data = cpl_image_get_data_float(skyim);
00601     bpm = (unsigned char *)cpl_mask_get_data(cpl_image_get_bpm(skyim));
00602 
00603     /* Get the median */
00604 
00605     med = vircam_med(data,bpm,(long)npts);
00606     return(med);
00607 }
00608 
00609 /*---------------------------------------------------------------------------*/
00629 /*---------------------------------------------------------------------------*/
00630 
00631 /* static void vircam_sky_combine(vir_fits **inlist, int nfiles,  */
00632 /*                             vir_fits **outsky) { */
00633 /*     float *back,*data,medback,**datas,*outdata,*buf; */
00634 /*     cpl_binary *outbpm,*mdata,**mdatas; */
00635 /*     cpl_image *im,*outim; */
00636 /*     cpl_mask *m; */
00637 /*     vir_fits *model; */
00638 /*     int i,j,n,nx,ny; */
00639 /*     long npts; */
00640 
00641 /*     /\* Initialise a few things *\/ */
00642 
00643 /*     model = inlist[0]; */
00644 /*     nx = cpl_image_get_size_x(vircam_fits_get_image(model)); */
00645 /*     ny = cpl_image_get_size_y(vircam_fits_get_image(model)); */
00646 /*     npts = (long)(nx*ny); */
00647 
00648 /*     /\* Get some workspace *\/ */
00649 
00650 /*     back = cpl_malloc(nfiles*sizeof(float)); */
00651 /*     datas = cpl_malloc(nfiles*sizeof(float *)); */
00652 /*     mdatas = cpl_malloc(nfiles*sizeof(float *)); */
00653 /*     buf = cpl_malloc(nfiles*sizeof(float)); */
00654 
00655 /*     /\* Get the background flux for each image, masking out bad pixels */
00656 /*        using the input masks. Work out the zero points that need to */
00657 /*        be applied to bring them to a common background *\/ */
00658 
00659 /*     for (i = 0; i < nfiles; i++) { */
00660 /*      im = vircam_fits_get_image(inlist[i]); */
00661 /*      datas[i] = cpl_image_get_data_float(im); */
00662 /*      data = datas[i]; */
00663 /*      mdatas[i] = cpl_mask_get_data(cpl_image_get_bpm(im)); */
00664 /*      mdata = mdatas[i]; */
00665 /*         back[i] = vircam_med(data,mdata,npts); */
00666 /*     } */
00667 /*     medback = vircam_med(back,NULL,nfiles); */
00668 /*     for (i = 0; i < nfiles; i++)  */
00669 /*      back[i] = medback - back[i]; */
00670 
00671 /*     /\* Create the output mask *\/ */
00672 
00673 /*     outbpm = cpl_malloc(nx*ny*sizeof(unsigned char)); */
00674 
00675 /*     /\* Create output image *\/ */
00676 
00677 /*     outim = cpl_image_new(nx,ny,CPL_TYPE_FLOAT); */
00678 /*     outdata = cpl_image_get_data_float(outim); */
00679 
00680 /*     /\* Right loop for each output pixel and do the median *\/ */
00681 
00682 /*     for (i = 0; i < npts; i++) { */
00683 /*      n = 0; */
00684 /*      for (j = 0; j < nfiles; j++) { */
00685 /*          if (mdatas[j][i] == 0)  */
00686 /*              buf[n++] = datas[j][i] + back[j]; */
00687 /*      } */
00688 /*      switch (n) { */
00689 /*      case 0: */
00690 /*          outdata[i] = 0; */
00691 /*          outbpm[i] = 1; */
00692 /*          break; */
00693 /*      case 1: */
00694 /*          outdata[i] = buf[0]; */
00695 /*          outbpm[i] = 0; */
00696 /*          break; */
00697 /*      default: */
00698 /*          outdata[i] = vircam_med(buf,NULL,n); */
00699 /*          outbpm[i] = 0; */
00700 /*          break; */
00701 /*      } */
00702 /*     } */
00703 
00704 /*     /\* Wrap the output image in a vir_fits structure *\/ */
00705 
00706 /*     *outsky = vircam_fits_wrap(outim,model,NULL,NULL);     */
00707 /*     m = cpl_mask_wrap(nx,ny,(cpl_binary *)outbpm); */
00708 /*     cpl_image_reject_from_mask(outim,(const cpl_mask *)m); */
00709 /*     cpl_mask_unwrap(m); */
00710 
00711 /*     /\* Free some workspace *\/ */
00712 
00713 /*     freespace(back); */
00714 /*     freespace(datas); */
00715 /*     freespace(mdatas); */
00716 /*     freespace(buf); */
00717 /*     freespace(outbpm); */
00718 /* }  */
00719 
00720 
00721 /*---------------------------------------------------------------------------*/
00743 /*---------------------------------------------------------------------------*/
00744 
00745 static void vircam_sky_joffs(vir_fits **inlist, int nfiles, float **xoffs,
00746                              float **yoffs) {
00747     float xoff,yoff;
00748     cpl_wcs *wcsref,*wcs;
00749     int refset,i,status;
00750     const double maxoffset = 2048;
00751     vir_fits *ff;
00752     const char *fctid = "vircam_sky_joffs";
00753 
00754     /* Get a bit of workspace to hold the offsets */
00755 
00756     *xoffs = cpl_malloc(nfiles*sizeof(float));
00757     *yoffs = cpl_malloc(nfiles*sizeof(float));
00758 
00759     /* Work out the jitter offsets from the WCS. First loop for each image */
00760 
00761     refset = 0;
00762     wcsref = NULL;
00763     for (i = 0; i < nfiles; i++) {
00764         ff = inlist[i];
00765         wcs = cpl_wcs_new_from_propertylist(vircam_fits_get_ehu(ff));
00766 
00767         /* If we can't get a WCS for this image, then signal that with
00768            a warning */
00769 
00770         if (wcs == NULL) {
00771             cpl_msg_warning(fctid,"Unable to get WCS for %s",
00772                             vircam_fits_get_filename(ff));
00773             (*xoffs)[i] = 0.0;
00774             (*yoffs)[i] = 0.0;
00775             vircam_fits_set_error(ff,VIR_WARN);
00776             continue;
00777         }
00778 
00779         /* Define the reference wcs pointer and set the first offset to zero */
00780 
00781         if (! refset) {
00782             (*xoffs)[0] = 0.0;
00783             (*yoffs)[0] = 0.0;
00784             refset = 1;
00785             wcsref = wcs;
00786             continue;
00787         }
00788 
00789         /* Work out the x,y offset */
00790 
00791         status = VIR_OK;
00792         (void)vircam_diffxywcs(wcs,wcsref,&xoff,&yoff,&status);
00793 
00794         /* Did it work? If not the set a warning status for this file */
00795 
00796         if (status != VIR_OK) {
00797             (*xoffs)[i] = 0.0;
00798             (*yoffs)[i] = 0.0;
00799             cpl_msg_warning(fctid,"Unable to WCS difference for %s",
00800                             vircam_fits_get_filename(ff));
00801         } else if (fabs((double)xoff) > maxoffset || 
00802                    fabs((double)yoff) > maxoffset) {
00803             vircam_fits_set_error(ff,VIR_FATAL);
00804             cpl_msg_error(fctid,"WCS offsets for %s are >%g: %g %g -- ignoring",
00805                           vircam_fits_get_filename(ff),maxoffset,xoff,yoff);
00806         } else {
00807             (*xoffs)[i] = xoff;
00808             (*yoffs)[i] = yoff;
00809         }
00810         cpl_wcs_delete(wcs);
00811     }
00812     if (wcsref != NULL) 
00813         cpl_wcs_delete(wcsref);
00814 
00815     /* Write the results to the headers */
00816 
00817     for (i = 0; i < nfiles; i++) {
00818         ff = inlist[i];
00819         cpl_propertylist_update_double(vircam_fits_get_ehu(ff),
00820                                        "ESO DRS XOFFDITHER",
00821                                        (double)(*xoffs)[i]);
00822         cpl_propertylist_update_double(vircam_fits_get_ehu(ff),
00823                                        "ESO DRS YOFFDITHER",
00824                                        (double)(*yoffs)[i]);
00825     }
00826 }
00827     
00830 /*
00831 
00832 $Log: vircam_sky.c,v $
00833 Revision 1.7  2010/06/30 12:42:00  jim
00834 A few fixes to stop compiler compaints
00835 
00836 Revision 1.6  2009/02/23 10:46:26  jim
00837 Modified tilesky to try and get rid of some of the low level glow around
00838 bright and extended objects
00839 
00840 Revision 1.5  2009/02/20 11:01:13  jim
00841 Added vircam_tilesky. Commented out vircam_skycombine as it's not being
00842 used at present and it's generating a compiler error. May delete it
00843 completely later
00844 
00845 Revision 1.4  2008/11/25 06:23:09  jim
00846 Added some routine prologues
00847 
00848 Revision 1.3  2008/11/21 10:12:36  jim
00849 Fixed typo
00850 
00851 Revision 1.2  2008/10/24 10:57:19  jim
00852 Fixed bug in pawsky_mask so that the bad pixels in the confidence map are
00853 folded into the object mask
00854 
00855 Revision 1.1  2008/10/13 08:13:21  jim
00856 New entry
00857 
00858 */

Generated on 7 Feb 2011 for VIRCAM Pipeline by  doxygen 1.6.1