VIRCAM Pipeline 2.3.12
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
40static float *odata = NULL;
41static int *ocdata = NULL;
42static cpl_propertylist *pp = NULL;
43static int outok = 0;
44static float *xoff = NULL;
45static float *yoff = NULL;
46static float *backmeds = NULL;
47
48static void tidy(void);
49
52/*---------------------------------------------------------------------------*/
115/*---------------------------------------------------------------------------*/
116
117extern 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
317static 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 $
333Revision 1.16 2007/05/15 08:54:32 jim
334Decreased size of output map by 1 pixel
335
336Revision 1.15 2007/03/29 12:19:39 jim
337Little changes to improve documentation
338
339Revision 1.14 2007/03/22 10:58:46 jim
340Force offsets to be the exact fraction that they should be
341
342Revision 1.13 2007/03/01 12:42:41 jim
343Modified slightly after code checking
344
345Revision 1.12 2006/11/27 12:04:53 jim
346Changed call from cpl_propertylist_append to cpl_propertylist_update
347
348Revision 1.11 2006/10/02 13:47:33 jim
349Added missing .h file to include list
350
351Revision 1.10 2006/07/11 14:54:41 jim
352The output propertylist is now a duplicate to avoid possible clash when
353freeing up memory
354
355Revision 1.9 2006/07/07 09:33:20 jim
356Changed datatype of x,y offset properties
357
358Revision 1.8 2006/06/06 13:06:23 jim
359Adds VIR_TIME to primary header
360
361Revision 1.7 2006/05/15 12:58:53 jim
362fixed a small typo in docs
363
364Revision 1.6 2006/03/23 21:18:50 jim
365Minor changes mainly to comment headers
366
367Revision 1.5 2006/03/22 13:58:32 jim
368Cosmetic fixes to keep lint happy
369
370Revision 1.4 2006/03/08 14:32:22 jim
371Lots of little modifications
372
373Revision 1.3 2006/03/01 10:31:29 jim
374Now uses new vir_fits objects
375
376Revision 1.2 2006/02/22 14:09:02 jim
377Fixed missing entry in docs
378
379Revision 1.1 2006/02/18 11:53:40 jim
380new 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)