vircam_interleave.c

00001 /* $Id: vircam_interleave.c,v 1.17 2012/01/15 17:40:09 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: 2012/01/15 17:40:09 $
00024  * $Revision: 1.17 $
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 "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,
00236                           "Unable to map data for image %" CPL_SIZE_FORMAT,
00237                           (cpl_size)i);
00238             tidy();
00239             FATAL_ERROR
00240         }
00241         if (nconfs == 0) {
00242             icdata = NULL;
00243         } else {
00244             icdata = cpl_image_get_data_int(icimg);
00245             if (icdata == NULL) {
00246                 cpl_msg_error(fctid,
00247                               "Unable to map data for confidence map %" CPL_SIZE_FORMAT,
00248                               (cpl_size)i);
00249                 tidy();
00250                 FATAL_ERROR
00251             }
00252         }
00253 
00254         /* Now distribute the data */
00255 
00256         nx = (int)cpl_image_get_size_x(inimg);
00257         ny = (int)cpl_image_get_size_y(inimg);
00258         for (j = 0; j < ny; j++) {
00259             jindex = j*nx;
00260             joindex = nxo*((int)(((float)j + yoff[i])*fnm + 0.5));
00261             for (k = 0; k < nx; k++) {
00262                 iindex = jindex + k;
00263                 outindex = joindex + (int)(((float)k + xoff[i])*fnm + 0.5);
00264                 if (outindex < 0 || outindex >= nxo*nyo) {
00265                     cpl_msg_error(fctid,
00266                                   "Programming error -- output index out of bounds %" CPL_SIZE_FORMAT,
00267                                   (cpl_size)outindex);
00268                     tidy();
00269                     FATAL_ERROR
00270                 }
00271                 odata[outindex] = idata[iindex] - backmeds[i];
00272                 if (ocdata != NULL)
00273                     ocdata[outindex] = icdata[iindex];
00274             }
00275         }
00276     }
00277 
00278 
00279     /* Update the propertylist to rescale the CD matrix and the CRPIX vector.
00280        The latter must also be offset by the minimum shift introduced during
00281        the interleaving */
00282 
00283     fnm = 1.0/fnm;
00284     if (vircam_crpixshift(pp,fnm,offs) != VIR_OK) {
00285         tidy();
00286         FATAL_ERROR
00287     }
00288     if (vircam_rescalecd(pp,fnm) != VIR_OK) {
00289         tidy();
00290         FATAL_ERROR
00291     }
00292 
00293     /* Add the provenance information to the output header */
00294 
00295     vircam_prov(pp,infiles,ninputs);
00296 
00297     /* Wrap the data in a cpl_image */
00298 
00299     *outimage = cpl_image_wrap_float((cpl_size)nxo,(cpl_size)nyo,odata);
00300     *outconf = cpl_image_wrap_int((cpl_size)nxo,(cpl_size)nyo,ocdata);
00301 
00302     /* Add a timestamp to the primary propertylist */
00303 
00304     vircam_timestamp(timestamp,25);
00305     p2 = vircam_fits_get_phu(infiles[0]);
00306     cpl_propertylist_update_string(p2,"VIR_TIME",timestamp);
00307     cpl_propertylist_set_comment(p2,"VIR_TIME",
00308                                  "Timestamp for matching to conf map");
00309 
00310     /* Get out of here */
00311 
00312     *p = pp;
00313     outok = 1;
00314     tidy();
00315     GOOD_STATUS
00316 }
00317 
00318 static void tidy(void) {
00319     if (! outok) {
00320         freespace(odata);
00321         freespace(ocdata);
00322         freepropertylist(pp)
00323     }
00324     freespace(xoff);
00325     freespace(yoff);
00326     freespace(backmeds);
00327 }
00328 
00331 /*
00332 
00333 $Log: vircam_interleave.c,v $
00334 Revision 1.17  2012/01/15 17:40:09  jim
00335 Minor modifications to take into accout the changes in cpl API for v6
00336 
00337 Revision 1.16  2007/05/15 08:54:32  jim
00338 Decreased size of output map by 1 pixel
00339 
00340 Revision 1.15  2007/03/29 12:19:39  jim
00341 Little changes to improve documentation
00342 
00343 Revision 1.14  2007/03/22 10:58:46  jim
00344 Force offsets to be the exact fraction that they should be
00345 
00346 Revision 1.13  2007/03/01 12:42:41  jim
00347 Modified slightly after code checking
00348 
00349 Revision 1.12  2006/11/27 12:04:53  jim
00350 Changed call from cpl_propertylist_append to cpl_propertylist_update
00351 
00352 Revision 1.11  2006/10/02 13:47:33  jim
00353 Added missing .h file to include list
00354 
00355 Revision 1.10  2006/07/11 14:54:41  jim
00356 The output propertylist is now a duplicate to avoid possible clash when
00357 freeing up memory
00358 
00359 Revision 1.9  2006/07/07 09:33:20  jim
00360 Changed datatype of x,y offset properties
00361 
00362 Revision 1.8  2006/06/06 13:06:23  jim
00363 Adds VIR_TIME to primary header
00364 
00365 Revision 1.7  2006/05/15 12:58:53  jim
00366 fixed a small typo in docs
00367 
00368 Revision 1.6  2006/03/23 21:18:50  jim
00369 Minor changes mainly to comment headers
00370 
00371 Revision 1.5  2006/03/22 13:58:32  jim
00372 Cosmetic fixes to keep lint happy
00373 
00374 Revision 1.4  2006/03/08 14:32:22  jim
00375 Lots of little modifications
00376 
00377 Revision 1.3  2006/03/01 10:31:29  jim
00378 Now uses new vir_fits objects
00379 
00380 Revision 1.2  2006/02/22 14:09:02  jim
00381 Fixed missing entry in docs
00382 
00383 Revision 1.1  2006/02/18 11:53:40  jim
00384 new file
00385 
00386 
00387 */

Generated on 15 Mar 2012 for VIRCAM Pipeline by  doxygen 1.6.1