vircam_interleave.c

00001 /* $Id: vircam_interleave.c,v 1.16 2007/05/15 08:54:32 jim Exp $
00002  *
00003  * This file is part of the VIRCAM Pipeline
00004  * Copyright (C) 2005 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: 2007/05/15 08:54:32 $
00024  * $Revision: 1.16 $
00025  * $Name:  $
00026  */
00027 
00028 /* Includes */
00029 
00030 #ifdef HAVE_CONFIG_H
00031 #include <config.h>
00032 #endif
00033 
00034 #include <cpl.h>
00035 #include "vircam_utils.h"
00036 #include "vircam_wcsutils.h"
00037 #include "vircam_fits.h"
00038 #include "vircam_mods.h"
00039 
00040 static float *odata = NULL;
00041 static int *ocdata = NULL;
00042 static cpl_propertylist *pp = NULL;
00043 static int outok = 0;
00044 static float *xoff = NULL;
00045 static float *yoff = NULL;
00046 static float *backmeds = NULL;
00047 
00048 static void tidy(void);
00049 
00052 /*---------------------------------------------------------------------------*/
00115 /*---------------------------------------------------------------------------*/
00116 
00117 extern int vircam_interleave(vir_fits **infiles, int ninputs, 
00118                              vir_fits **inconfs, int nconfs, int nsteps, 
00119                              cpl_propertylist **p, cpl_image **outimage, 
00120                              cpl_image **outconf, int *status) {
00121     const char *fctid = "vircam_interleave";
00122     char timestamp[25];
00123     int i,j,k,nxo,nyo,itx,nx,ny,jindex,joindex;
00124     int iindex,outindex,*icdata,ival;
00125     float minoff,minzero,*idata,fval;
00126     double offs[2],fnm;
00127     cpl_image *inimg,*icimg;
00128     cpl_propertylist *ehu,*p2;
00129 
00130     /* Inherited status */
00131 
00132     *outimage = NULL;
00133     *outconf = NULL;
00134     *p = NULL;
00135     if (*status != VIR_OK)
00136         return(*status);
00137 
00138     /* Look to see how many files there are */
00139 
00140     if (ninputs == 0) {
00141         cpl_msg_error(fctid,"No input files to interleave");
00142         tidy();
00143         FATAL_ERROR
00144     }
00145 
00146     /* Do we have any input confidence maps? If we don't then just get
00147        on with life. If there aren't the same number of confidence maps
00148        as input files, then just use the first one. Otherwise use all
00149        that are there */
00150 
00151     if (inconfs == NULL) {
00152         nconfs = 0;
00153     } else {
00154         if (nconfs != ninputs) 
00155             nconfs = 1;
00156     }
00157 
00158     /* Get the propertylist from the first file in the frameset. We need
00159        this because we need to reset the WCS for the output frame */
00160 
00161     pp = cpl_propertylist_duplicate(vircam_fits_get_ehu(infiles[0]));
00162 
00163     /* Get the information we need from the extension propertylists. Force
00164        the offsets to be the exact fraction the should be. */
00165 
00166     xoff = cpl_malloc(ninputs*sizeof(float));
00167     yoff = cpl_malloc(ninputs*sizeof(float));
00168     backmeds = cpl_malloc(ninputs*sizeof(float));
00169     fnm = (double)nsteps;
00170     for (i = 0; i < ninputs; i++) {
00171         ehu = vircam_fits_get_ehu(infiles[i]);
00172         xoff[i] = (float)cpl_propertylist_get_double(ehu,"ESO DRS XOFFMICRO");
00173         fval = xoff[i] - (int)xoff[i];
00174         ival = vircam_nint(fval*fnm);
00175         xoff[i] = (int)xoff[i] + (float)ival/fnm;
00176         yoff[i] = (float)cpl_propertylist_get_double(ehu,"ESO DRS YOFFMICRO");
00177         fval = yoff[i] - (int)yoff[i];
00178         ival = vircam_nint(fval*fnm);
00179         yoff[i] = (int)yoff[i] + (float)ival/fnm;
00180         backmeds[i] = cpl_propertylist_get_float(ehu,"ESO DRS BACKMED");
00181     }
00182 
00183     /* Normalise the x and y offsets so that they have a minimum of zero */
00184 
00185     minoff = xoff[0];
00186     for (i = 1; i < ninputs; i++)
00187         minoff = min(minoff,xoff[i]);
00188     for (i = 0; i < ninputs; i++)
00189         xoff[i] -= minoff;
00190     offs[0] = (double)minoff;
00191     minoff = yoff[0];
00192     for (i = 1; i < ninputs; i++)
00193         minoff = min(minoff,yoff[i]);
00194     for (i = 0; i < ninputs; i++)
00195         yoff[i] -= minoff;
00196     offs[1] = (double)minoff;
00197 
00198     /* Normalise the background offsets to a minimum of zero */
00199 
00200     minzero = backmeds[0];
00201     for (i = 1; i < ninputs; i++)
00202         minzero = min(minzero,backmeds[i]);
00203     for (i = 0; i < ninputs; i++)
00204         backmeds[i] -= minzero;
00205 
00206     /* How big does the output image need to be? */
00207 
00208     nxo = 0;
00209     nyo = 0;
00210     for (i = 0; i < ninputs; i++) {
00211         itx = (int)((float)nsteps*((float)cpl_image_get_size_x(vircam_fits_get_image(infiles[i])) + xoff[i]) + 0.5) - 1;
00212         nxo = max(nxo,itx);
00213         itx = (int)((float)nsteps*((float)cpl_image_get_size_y(vircam_fits_get_image(infiles[i])) + yoff[i]) + 0.5) - 1;
00214         nyo = max(nyo,itx);
00215     }
00216 
00217     /* Right, get some memory for the output array(s) */
00218 
00219     odata = cpl_calloc(nxo*nyo,sizeof(*odata));
00220     if (nconfs > 0) 
00221         ocdata = cpl_calloc(nxo*nyo,sizeof(*ocdata));
00222 
00223     /* Right, now loop through all the images and deposit the pixels into
00224        the correct location in the output image. First get the data for the
00225        current image and (if used) the current confidence map */
00226 
00227     for (i = 0; i < ninputs; i++) {
00228         inimg = vircam_fits_get_image(infiles[i]);
00229         if (nconfs == 1) 
00230             icimg = vircam_fits_get_image(inconfs[0]);
00231         else
00232             icimg = vircam_fits_get_image(inconfs[i]);
00233         idata = cpl_image_get_data_float(inimg);
00234         if (idata == NULL) {
00235             cpl_msg_error(fctid,"Unable to map data for image %d",i);
00236             tidy();
00237             FATAL_ERROR
00238         }
00239         if (nconfs == 0) {
00240             icdata = NULL;
00241         } else {
00242             icdata = cpl_image_get_data_int(icimg);
00243             if (icdata == NULL) {
00244                 cpl_msg_error(fctid,
00245                               "Unable to map data for confidence map %d",i);
00246                 tidy();
00247                 FATAL_ERROR
00248             }
00249         }
00250 
00251         /* Now distribute the data */
00252 
00253         nx = cpl_image_get_size_x(inimg);
00254         ny = cpl_image_get_size_y(inimg);
00255         for (j = 0; j < ny; j++) {
00256             jindex = j*nx;
00257             joindex = nxo*((int)(((float)j + yoff[i])*fnm + 0.5));
00258             for (k = 0; k < nx; k++) {
00259                 iindex = jindex + k;
00260                 outindex = joindex + (int)(((float)k + xoff[i])*fnm + 0.5);
00261                 if (outindex < 0 || outindex >= nxo*nyo) {
00262                     cpl_msg_error(fctid,"Programming error -- output index out of bounds %d\n",outindex);
00263                     tidy();
00264                     FATAL_ERROR
00265                 }
00266                 odata[outindex] = idata[iindex] - backmeds[i];
00267                 if (ocdata != NULL)
00268                     ocdata[outindex] = icdata[iindex];
00269             }
00270         }
00271     }
00272 
00273 
00274     /* Update the propertylist to rescale the CD matrix and the CRPIX vector.
00275        The latter must also be offset by the minimum shift introduced during
00276        the interleaving */
00277 
00278     fnm = 1.0/fnm;
00279     if (vircam_crpixshift(pp,fnm,offs) != VIR_OK) {
00280         tidy();
00281         FATAL_ERROR
00282     }
00283     if (vircam_rescalecd(pp,fnm) != VIR_OK) {
00284         tidy();
00285         FATAL_ERROR
00286     }
00287 
00288     /* Add the provenance information to the output header */
00289 
00290     vircam_prov(pp,infiles,ninputs);
00291 
00292     /* Wrap the data in a cpl_image */
00293 
00294     *outimage = cpl_image_wrap_float(nxo,nyo,odata);
00295     *outconf = cpl_image_wrap_int(nxo,nyo,ocdata);
00296 
00297     /* Add a timestamp to the primary propertylist */
00298 
00299     vircam_timestamp(timestamp,25);
00300     p2 = vircam_fits_get_phu(infiles[0]);
00301     cpl_propertylist_update_string(p2,"VIR_TIME",timestamp);
00302     cpl_propertylist_set_comment(p2,"VIR_TIME",
00303                                  "Timestamp for matching to conf map");
00304 
00305     /* Get out of here */
00306 
00307     *p = pp;
00308     outok = 1;
00309     tidy();
00310     GOOD_STATUS
00311 }
00312 
00313 static void tidy(void) {
00314     if (! outok) {
00315         freespace(odata);
00316         freespace(ocdata);
00317         freepropertylist(pp)
00318     }
00319     freespace(xoff);
00320     freespace(yoff);
00321     freespace(backmeds);
00322 }
00323 
00326 /*
00327 
00328 $Log: vircam_interleave.c,v $
00329 Revision 1.16  2007/05/15 08:54:32  jim
00330 Decreased size of output map by 1 pixel
00331 
00332 Revision 1.15  2007/03/29 12:19:39  jim
00333 Little changes to improve documentation
00334 
00335 Revision 1.14  2007/03/22 10:58:46  jim
00336 Force offsets to be the exact fraction that they should be
00337 
00338 Revision 1.13  2007/03/01 12:42:41  jim
00339 Modified slightly after code checking
00340 
00341 Revision 1.12  2006/11/27 12:04:53  jim
00342 Changed call from cpl_propertylist_append to cpl_propertylist_update
00343 
00344 Revision 1.11  2006/10/02 13:47:33  jim
00345 Added missing .h file to include list
00346 
00347 Revision 1.10  2006/07/11 14:54:41  jim
00348 The output propertylist is now a duplicate to avoid possible clash when
00349 freeing up memory
00350 
00351 Revision 1.9  2006/07/07 09:33:20  jim
00352 Changed datatype of x,y offset properties
00353 
00354 Revision 1.8  2006/06/06 13:06:23  jim
00355 Adds VIR_TIME to primary header
00356 
00357 Revision 1.7  2006/05/15 12:58:53  jim
00358 fixed a small typo in docs
00359 
00360 Revision 1.6  2006/03/23 21:18:50  jim
00361 Minor changes mainly to comment headers
00362 
00363 Revision 1.5  2006/03/22 13:58:32  jim
00364 Cosmetic fixes to keep lint happy
00365 
00366 Revision 1.4  2006/03/08 14:32:22  jim
00367 Lots of little modifications
00368 
00369 Revision 1.3  2006/03/01 10:31:29  jim
00370 Now uses new vir_fits objects
00371 
00372 Revision 1.2  2006/02/22 14:09:02  jim
00373 Fixed missing entry in docs
00374 
00375 Revision 1.1  2006/02/18 11:53:40  jim
00376 new file
00377 
00378 
00379 */

Generated on Wed Apr 10 04:01:56 2013 for VIRCAM Pipeline by  doxygen 1.5.1