VIRCAM Pipeline  2.3.10
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) 2015 European Southern Observatory
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 <casu_utils.h>
36 #include <casu_wcsutils.h>
37 #include "vircam_mods.h"
38 #include "vircam_utils.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(casu_fits **infiles, int ninputs,
118  casu_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 != CASU_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(casu_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 = casu_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 = casu_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 = casu_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(casu_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(casu_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 = casu_fits_get_image(infiles[i]);
229  if (nconfs == 1)
230  icimg = casu_fits_get_image(inconfs[0]);
231  else
232  icimg = casu_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  /* Update the propertylist to rescale the CD matrix and the CRPIX vector.
279  The latter must also be offset by the minimum shift introduced during
280  the interleaving */
281 
282  fnm = 1.0/fnm;
283  if (casu_crpixshift(pp,fnm,offs) != CASU_OK) {
284  tidy();
285  FATAL_ERROR
286  }
287  if (casu_rescalecd(pp,fnm) != CASU_OK) {
288  tidy();
289  FATAL_ERROR
290  }
291 
292  /* Add the provenance information to the output header */
293 
294  casu_prov(pp,infiles,ninputs,1);
295 
296  /* Wrap the data in a cpl_image */
297 
298  *outimage = cpl_image_wrap_float((cpl_size)nxo,(cpl_size)nyo,odata);
299  *outconf = cpl_image_wrap_int((cpl_size)nxo,(cpl_size)nyo,ocdata);
300 
301  /* Add a timestamp to the primary propertylist */
302 
303  vircam_timestamp(timestamp,25);
304  p2 = casu_fits_get_phu(infiles[0]);
305  cpl_propertylist_update_string(p2,"VIR_TIME",timestamp);
306  cpl_propertylist_set_comment(p2,"VIR_TIME",
307  "Timestamp for matching to conf map");
308 
309  /* Get out of here */
310 
311  *p = pp;
312  outok = 1;
313  tidy();
314  GOOD_STATUS
315 }
316 
317 static void tidy(void) {
318  if (! outok) {
319  freespace(odata);
320  freespace(ocdata);
321  freepropertylist(pp)
322  }
323  freespace(xoff);
324  freespace(yoff);
325  freespace(backmeds);
326 }
327 
330 /*
331 
332 $Log: not supported by cvs2svn $
333 Revision 1.16 2007/05/15 08:54:32 jim
334 Decreased size of output map by 1 pixel
335 
336 Revision 1.15 2007/03/29 12:19:39 jim
337 Little changes to improve documentation
338 
339 Revision 1.14 2007/03/22 10:58:46 jim
340 Force offsets to be the exact fraction that they should be
341 
342 Revision 1.13 2007/03/01 12:42:41 jim
343 Modified slightly after code checking
344 
345 Revision 1.12 2006/11/27 12:04:53 jim
346 Changed call from cpl_propertylist_append to cpl_propertylist_update
347 
348 Revision 1.11 2006/10/02 13:47:33 jim
349 Added missing .h file to include list
350 
351 Revision 1.10 2006/07/11 14:54:41 jim
352 The output propertylist is now a duplicate to avoid possible clash when
353 freeing up memory
354 
355 Revision 1.9 2006/07/07 09:33:20 jim
356 Changed datatype of x,y offset properties
357 
358 Revision 1.8 2006/06/06 13:06:23 jim
359 Adds VIR_TIME to primary header
360 
361 Revision 1.7 2006/05/15 12:58:53 jim
362 fixed a small typo in docs
363 
364 Revision 1.6 2006/03/23 21:18:50 jim
365 Minor changes mainly to comment headers
366 
367 Revision 1.5 2006/03/22 13:58:32 jim
368 Cosmetic fixes to keep lint happy
369 
370 Revision 1.4 2006/03/08 14:32:22 jim
371 Lots of little modifications
372 
373 Revision 1.3 2006/03/01 10:31:29 jim
374 Now uses new vir_fits objects
375 
376 Revision 1.2 2006/02/22 14:09:02 jim
377 Fixed missing entry in docs
378 
379 Revision 1.1 2006/02/18 11:53:40 jim
380 new file
381 
382 
383 */
cpl_image * casu_fits_get_image(casu_fits *p)
Definition: casu_fits.c:436
cpl_propertylist * casu_fits_get_phu(casu_fits *p)
Definition: casu_fits.c:531
cpl_propertylist * casu_fits_get_ehu(casu_fits *p)
Definition: casu_fits.c:576
void casu_prov(cpl_propertylist *p, casu_fits **inlist, int n, int isextn)
Write provenance keywords.
Definition: casu_utils.c:287
int casu_rescalecd(cpl_propertylist *p, double scalefac)
int casu_crpixshift(cpl_propertylist *p, double scalefac, double sh[])
int vircam_interleave(casu_fits **infiles, int ninputs, casu_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_timestamp(char *out, int n)