VIRCAM Pipeline  1.3.4
vircam/vircam_interleave.c
1 /* $Id: vircam_interleave.c,v 1.17 2012-01-15 17:40:09 jim Exp $
2  *
3  * This file is part of the VIRCAM Pipeline
4  * Copyright (C) 2005 Cambridge Astronomy Survey Unit
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  */
20 
21 /*
22  * $Author: jim $
23  * $Date: 2012-01-15 17:40:09 $
24  * $Revision: 1.17 $
25  * $Name: not supported by cvs2svn $
26  */
27 
28 /* Includes */
29 
30 #ifdef HAVE_CONFIG_H
31 #include <config.h>
32 #endif
33 
34 #include <cpl.h>
35 #include "vircam_utils.h"
36 #include "vircam_wcsutils.h"
37 #include "vircam_fits.h"
38 #include "vircam_mods.h"
39 
40 static float *odata = NULL;
41 static int *ocdata = NULL;
42 static cpl_propertylist *pp = NULL;
43 static int outok = 0;
44 static float *xoff = NULL;
45 static float *yoff = NULL;
46 static float *backmeds = NULL;
47 
48 static void tidy(void);
49 
52 /*---------------------------------------------------------------------------*/
115 /*---------------------------------------------------------------------------*/
116 
117 extern int vircam_interleave(vir_fits **infiles, int ninputs,
118  vir_fits **inconfs, int nconfs, int nsteps,
119  cpl_propertylist **p, cpl_image **outimage,
120  cpl_image **outconf, int *status) {
121  const char *fctid = "vircam_interleave";
122  char timestamp[25];
123  int i,j,k,nxo,nyo,itx,nx,ny,jindex,joindex;
124  int iindex,outindex,*icdata,ival;
125  float minoff,minzero,*idata,fval;
126  double offs[2],fnm;
127  cpl_image *inimg,*icimg;
128  cpl_propertylist *ehu,*p2;
129 
130  /* Inherited status */
131 
132  *outimage = NULL;
133  *outconf = NULL;
134  *p = NULL;
135  if (*status != VIR_OK)
136  return(*status);
137 
138  /* Look to see how many files there are */
139 
140  if (ninputs == 0) {
141  cpl_msg_error(fctid,"No input files to interleave");
142  tidy();
143  FATAL_ERROR
144  }
145 
146  /* Do we have any input confidence maps? If we don't then just get
147  on with life. If there aren't the same number of confidence maps
148  as input files, then just use the first one. Otherwise use all
149  that are there */
150 
151  if (inconfs == NULL) {
152  nconfs = 0;
153  } else {
154  if (nconfs != ninputs)
155  nconfs = 1;
156  }
157 
158  /* Get the propertylist from the first file in the frameset. We need
159  this because we need to reset the WCS for the output frame */
160 
161  pp = cpl_propertylist_duplicate(vircam_fits_get_ehu(infiles[0]));
162 
163  /* Get the information we need from the extension propertylists. Force
164  the offsets to be the exact fraction the should be. */
165 
166  xoff = cpl_malloc(ninputs*sizeof(float));
167  yoff = cpl_malloc(ninputs*sizeof(float));
168  backmeds = cpl_malloc(ninputs*sizeof(float));
169  fnm = (double)nsteps;
170  for (i = 0; i < ninputs; i++) {
171  ehu = vircam_fits_get_ehu(infiles[i]);
172  xoff[i] = (float)cpl_propertylist_get_double(ehu,"ESO DRS XOFFMICRO");
173  fval = xoff[i] - (int)xoff[i];
174  ival = vircam_nint(fval*fnm);
175  xoff[i] = (int)xoff[i] + (float)ival/fnm;
176  yoff[i] = (float)cpl_propertylist_get_double(ehu,"ESO DRS YOFFMICRO");
177  fval = yoff[i] - (int)yoff[i];
178  ival = vircam_nint(fval*fnm);
179  yoff[i] = (int)yoff[i] + (float)ival/fnm;
180  backmeds[i] = cpl_propertylist_get_float(ehu,"ESO DRS BACKMED");
181  }
182 
183  /* Normalise the x and y offsets so that they have a minimum of zero */
184 
185  minoff = xoff[0];
186  for (i = 1; i < ninputs; i++)
187  minoff = min(minoff,xoff[i]);
188  for (i = 0; i < ninputs; i++)
189  xoff[i] -= minoff;
190  offs[0] = (double)minoff;
191  minoff = yoff[0];
192  for (i = 1; i < ninputs; i++)
193  minoff = min(minoff,yoff[i]);
194  for (i = 0; i < ninputs; i++)
195  yoff[i] -= minoff;
196  offs[1] = (double)minoff;
197 
198  /* Normalise the background offsets to a minimum of zero */
199 
200  minzero = backmeds[0];
201  for (i = 1; i < ninputs; i++)
202  minzero = min(minzero,backmeds[i]);
203  for (i = 0; i < ninputs; i++)
204  backmeds[i] -= minzero;
205 
206  /* How big does the output image need to be? */
207 
208  nxo = 0;
209  nyo = 0;
210  for (i = 0; i < ninputs; i++) {
211  itx = (int)((float)nsteps*((float)cpl_image_get_size_x(vircam_fits_get_image(infiles[i])) + xoff[i]) + 0.5) - 1;
212  nxo = max(nxo,itx);
213  itx = (int)((float)nsteps*((float)cpl_image_get_size_y(vircam_fits_get_image(infiles[i])) + yoff[i]) + 0.5) - 1;
214  nyo = max(nyo,itx);
215  }
216 
217  /* Right, get some memory for the output array(s) */
218 
219  odata = cpl_calloc(nxo*nyo,sizeof(*odata));
220  if (nconfs > 0)
221  ocdata = cpl_calloc(nxo*nyo,sizeof(*ocdata));
222 
223  /* Right, now loop through all the images and deposit the pixels into
224  the correct location in the output image. First get the data for the
225  current image and (if used) the current confidence map */
226 
227  for (i = 0; i < ninputs; i++) {
228  inimg = vircam_fits_get_image(infiles[i]);
229  if (nconfs == 1)
230  icimg = vircam_fits_get_image(inconfs[0]);
231  else
232  icimg = vircam_fits_get_image(inconfs[i]);
233  idata = cpl_image_get_data_float(inimg);
234  if (idata == NULL) {
235  cpl_msg_error(fctid,
236  "Unable to map data for image %" CPL_SIZE_FORMAT,
237  (cpl_size)i);
238  tidy();
239  FATAL_ERROR
240  }
241  if (nconfs == 0) {
242  icdata = NULL;
243  } else {
244  icdata = cpl_image_get_data_int(icimg);
245  if (icdata == NULL) {
246  cpl_msg_error(fctid,
247  "Unable to map data for confidence map %" CPL_SIZE_FORMAT,
248  (cpl_size)i);
249  tidy();
250  FATAL_ERROR
251  }
252  }
253 
254  /* Now distribute the data */
255 
256  nx = (int)cpl_image_get_size_x(inimg);
257  ny = (int)cpl_image_get_size_y(inimg);
258  for (j = 0; j < ny; j++) {
259  jindex = j*nx;
260  joindex = nxo*((int)(((float)j + yoff[i])*fnm + 0.5));
261  for (k = 0; k < nx; k++) {
262  iindex = jindex + k;
263  outindex = joindex + (int)(((float)k + xoff[i])*fnm + 0.5);
264  if (outindex < 0 || outindex >= nxo*nyo) {
265  cpl_msg_error(fctid,
266  "Programming error -- output index out of bounds %" CPL_SIZE_FORMAT,
267  (cpl_size)outindex);
268  tidy();
269  FATAL_ERROR
270  }
271  odata[outindex] = idata[iindex] - backmeds[i];
272  if (ocdata != NULL)
273  ocdata[outindex] = icdata[iindex];
274  }
275  }
276  }
277 
278 
279  /* Update the propertylist to rescale the CD matrix and the CRPIX vector.
280  The latter must also be offset by the minimum shift introduced during
281  the interleaving */
282 
283  fnm = 1.0/fnm;
284  if (vircam_crpixshift(pp,fnm,offs) != VIR_OK) {
285  tidy();
286  FATAL_ERROR
287  }
288  if (vircam_rescalecd(pp,fnm) != VIR_OK) {
289  tidy();
290  FATAL_ERROR
291  }
292 
293  /* Add the provenance information to the output header */
294 
295  vircam_prov(pp,infiles,ninputs);
296 
297  /* Wrap the data in a cpl_image */
298 
299  *outimage = cpl_image_wrap_float((cpl_size)nxo,(cpl_size)nyo,odata);
300  *outconf = cpl_image_wrap_int((cpl_size)nxo,(cpl_size)nyo,ocdata);
301 
302  /* Add a timestamp to the primary propertylist */
303 
304  vircam_timestamp(timestamp,25);
305  p2 = vircam_fits_get_phu(infiles[0]);
306  cpl_propertylist_update_string(p2,"VIR_TIME",timestamp);
307  cpl_propertylist_set_comment(p2,"VIR_TIME",
308  "Timestamp for matching to conf map");
309 
310  /* Get out of here */
311 
312  *p = pp;
313  outok = 1;
314  tidy();
315  GOOD_STATUS
316 }
317 
318 static void tidy(void) {
319  if (! outok) {
320  freespace(odata);
321  freespace(ocdata);
322  freepropertylist(pp)
323  }
324  freespace(xoff);
325  freespace(yoff);
326  freespace(backmeds);
327 }
328 
331 /*
332 
333 $Log: not supported by cvs2svn $
334 Revision 1.16 2007/05/15 08:54:32 jim
335 Decreased size of output map by 1 pixel
336 
337 Revision 1.15 2007/03/29 12:19:39 jim
338 Little changes to improve documentation
339 
340 Revision 1.14 2007/03/22 10:58:46 jim
341 Force offsets to be the exact fraction that they should be
342 
343 Revision 1.13 2007/03/01 12:42:41 jim
344 Modified slightly after code checking
345 
346 Revision 1.12 2006/11/27 12:04:53 jim
347 Changed call from cpl_propertylist_append to cpl_propertylist_update
348 
349 Revision 1.11 2006/10/02 13:47:33 jim
350 Added missing .h file to include list
351 
352 Revision 1.10 2006/07/11 14:54:41 jim
353 The output propertylist is now a duplicate to avoid possible clash when
354 freeing up memory
355 
356 Revision 1.9 2006/07/07 09:33:20 jim
357 Changed datatype of x,y offset properties
358 
359 Revision 1.8 2006/06/06 13:06:23 jim
360 Adds VIR_TIME to primary header
361 
362 Revision 1.7 2006/05/15 12:58:53 jim
363 fixed a small typo in docs
364 
365 Revision 1.6 2006/03/23 21:18:50 jim
366 Minor changes mainly to comment headers
367 
368 Revision 1.5 2006/03/22 13:58:32 jim
369 Cosmetic fixes to keep lint happy
370 
371 Revision 1.4 2006/03/08 14:32:22 jim
372 Lots of little modifications
373 
374 Revision 1.3 2006/03/01 10:31:29 jim
375 Now uses new vir_fits objects
376 
377 Revision 1.2 2006/02/22 14:09:02 jim
378 Fixed missing entry in docs
379 
380 Revision 1.1 2006/02/18 11:53:40 jim
381 new file
382 
383 
384 */
cpl_image * vircam_fits_get_image(vir_fits *p)
Definition: vircam_fits.c:349
int vircam_rescalecd(cpl_propertylist *p, double scalefac)
void vircam_timestamp(char *out, int n)
int vircam_crpixshift(cpl_propertylist *p, double scalefac, double sh[])
cpl_propertylist * vircam_fits_get_phu(vir_fits *p)
Definition: vircam_fits.c:416
cpl_propertylist * vircam_fits_get_ehu(vir_fits *p)
Definition: vircam_fits.c:457
int vircam_interleave(vir_fits **infiles, int ninputs, vir_fits **inconfs, int nconfs, int nsteps, cpl_propertylist **p, cpl_image **outimage, cpl_image **outconf, int *status)
Interleave a set of microstepped observations.
void vircam_prov(cpl_propertylist *p, vir_fits **inlist, int n)