VIRCAM Pipeline 2.3.15
vircam_grout.c
1/* $Id: vircam_grout.c,v 1.1 2013-10-15 16:30:07 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: 2013-10-15 16:30:07 $
24 * $Revision: 1.1 $
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 <math.h>
36#include <string.h>
37
38#include <casu_utils.h>
39#include <casu_wcsutils.h>
40#include <casu_stats.h>
41
42#include "vircam_mods.h"
43
44/* This is specifically for VIRCAM files. Only correct the first 7 apertures */
45
46#define NPAWS 6
47#define NEXTN 16
48#define NAPCOR 7
49
50typedef struct {
51 cpl_wcs *wcs;
52 int nxout;
53 int nyout;
54 float apcors[NAPCOR];
55 float magzpt;
56 float seeing;
57 float ellipt;
58 float mjdobs;
59} tables;
60
61const char *apcorkeys[NAPCOR] = {"APCOR1","APCOR2","APCOR3","APCOR4","APCOR5",
62 "APCOR6","APCOR7"};
63
64static int gettabinfo(cpl_propertylist *plist, tables *tab, double *mjdobs);
65static void tidytabs(tables maintab, tables *tabs);
66
69/*---------------------------------------------------------------------------*/
106/*---------------------------------------------------------------------------*/
107
108extern int vircam_grout(casu_tfits *intab, cpl_frameset *input_cats,
109 cpl_frameset *input_confs, casu_tfits **outtab,
110 int *status) {
111 int retval,i,j,m,nrows,*conf_data,k,ix,iy,ind,k2,nc,mjd_day = 0;
112 tables maintab,pawtabs[NPAWS*NEXTN];
113 double *x,*y,*x2,*y2,expon,*dspace,mjdobs;
114 cpl_array *colnames_array;
115 cpl_frame *fr;
116 cpl_propertylist *plist;
117 casu_fits *conf_fits;
118 float delta_mag,xmax,ymax,*mjds,*cnumb,*fspace,*fluxcor,*fluxes[NAPCOR+1];
119 float *fluxerrs[NAPCOR+1],work[NEXTN],confwt,scale,*xptr,*yptr,*data;
120 char **colnames,msg[81],sval[81];
121 const char *fluxcols[NAPCOR+1] = {"Aper_flux_1","Aper_flux_2",
122 "Aper_flux_3","Aper_flux_4",
123 "Aper_flux_5","Aper_flux_6",
124 "Aper_flux_7","Peak_height"};
125 const char *errcols[NAPCOR+1] = {"Aper_flux_1_err","Aper_flux_2_err",
126 "Aper_flux_3_err","Aper_flux_4_err",
127 "Aper_flux_5_err","Aper_flux_6_err",
128 "Aper_flux_7_err","Peak_height_err"};
129
130 /* Inherited status */
131
132 *outtab = NULL;
133 if (*status != CASU_OK)
134 return(*status);
135
136 /* Make sure that this table hasn't already been grouted. If it has
137 then just return with a copy of the input table */
138
139 if (cpl_propertylist_has(casu_tfits_get_ehu(intab),"ESO DRS GROUTED")) {
140 *outtab = casu_tfits_duplicate(intab);
141 return(*status);
142 }
143
144 /* Make a copy of the input table which will then be updated */
145
146 *outtab = casu_tfits_duplicate(intab);
147
148 /* Initialise the WCS structures */
149
150 maintab.wcs = NULL;
151 for (i = 0; i < NPAWS*NEXTN; i++)
152 pawtabs[i].wcs = NULL;
153
154 /* Read the WCS, apcors, etc from the input table */
155
156 retval = gettabinfo(casu_tfits_get_ehu(*outtab),&maintab,&mjdobs);
157 if (retval != CASU_OK) {
158 *status = retval;
159 return(*status);
160 }
161
162 /* Get some space to use for coordinate transformations */
163
164 nrows = (int)cpl_table_get_nrow(casu_tfits_get_table(*outtab));
165 dspace = cpl_malloc(4*nrows*sizeof(double));
166 x = dspace;
167 y = dspace + nrows;
168 x2 = dspace + 2*nrows;
169 y2 = dspace + 3*nrows;
170
171 /* Get some space for an MJD column and for summations */
172
173 fspace = cpl_calloc((2+NAPCOR)*nrows,sizeof(float));
174 mjds = fspace;
175 cnumb = fspace + nrows;
176 fluxcor = fspace + 2*nrows;
177
178 /* Get the coordinate information from the input table and convert to
179 double */
180
181 xptr = cpl_table_get_data_float(casu_tfits_get_table(*outtab),
182 "X_coordinate");
183 yptr = cpl_table_get_data_float(casu_tfits_get_table(*outtab),
184 "Y_coordinate");
185 for (i = 0; i < nrows; i++) {
186 x[i] = (double)xptr[i];
187 y[i] = (double)yptr[i];
188 }
189
190 /* Now read all the necessary information about the input tables */
191
192 m = 0;
193 for (i = 0; i < NPAWS; i++) {
194 fr = cpl_frameset_get_position(input_cats,i);
195 for (j = 0; j < NEXTN; j++) {
196 plist = cpl_propertylist_load(cpl_frame_get_filename(fr),j+1);
197 retval = gettabinfo(plist,&(pawtabs[m]),&mjdobs);
198 if (retval != CASU_OK) {
199 freespace(dspace);
200 freespace(mjds);
201 freetfits(*outtab);
202 freepropertylist(plist);
203 return(CASU_FATAL);
204 }
205 if (i == 0 && j == 0)
206 mjd_day = (int)mjdobs;
207 pawtabs[m].mjdobs = (float)(1440.0*(mjdobs - (double)mjd_day));
208 m++;
209 freepropertylist(plist);
210 }
211 }
212
213 /* Loop for each stack image extension */
214
215 m = -1;
216 for (i = 0; i < NPAWS; i++) {
217 fr = cpl_frameset_get_position(input_confs,i);
218 for (j = 0; j < NEXTN; j++) {
219 conf_fits = casu_fits_load(fr,CPL_TYPE_INT,j+1);
220 conf_data = cpl_image_get_data_int(casu_fits_get_image(conf_fits));
221 m++;
222 delta_mag = maintab.magzpt - pawtabs[m].magzpt;
223
224 /* Shift the tile object coordinates to the reference frame of
225 the current pawprint */
226
227 casu_xytoxy_list(maintab.wcs,pawtabs[m].wcs,nrows,x,y,x2,y2);
228
229 /* Loop through each object now and see if it's on this image.
230 If it is, then work out the contribution to the flux correction
231 that you get from the current image */
232
233 xmax = (float)pawtabs[m].nxout - 0.5;
234 ymax = (float)pawtabs[m].nyout;
235 for (k = 0; k < nrows; k++) {
236 if (x2[k] >= 0.5 && x2[k] < xmax &&
237 y2[k] >= 0.5 && y2[k] < ymax) {
238 ix = (int)(x2[k] + 0.5) - 1;
239 iy = (int)(y2[k] + 0.5) - 1;
240 ind = iy*pawtabs[m].nxout + ix;
241 confwt = (float)max(1.0,conf_data[ind]);
242 mjds[k] += confwt*pawtabs[m].mjdobs;
243 cnumb[k] += confwt;
244 for (k2 = 0; k2 < NAPCOR; k2++) {
245 expon = 0.4*(double)(pawtabs[m].apcors[k2] -
246 maintab.apcors[k2] + delta_mag);
247 fluxcor[k2*nrows+k] += confwt*pow(10.0,expon);
248 }
249 }
250 }
251 freefits(conf_fits);
252 }
253 }
254
255 /* Get pointers to each of the fluxes and their errors */
256
257 for (i = 0; i < NAPCOR+1; i++) {
258 fluxes[i] = cpl_table_get_data_float(casu_tfits_get_table(*outtab),
259 fluxcols[i]);
260 fluxerrs[i] = cpl_table_get_data_float(casu_tfits_get_table(*outtab),
261 errcols[i]);
262 }
263
264 /* Now normalise the flux corrections and apply them */
265
266 for (k = 0; k < nrows; k++) {
267 for (k2 = 0; k2 < NAPCOR; k2++) {
268 if (cnumb[k] != 0.0)
269 scale = fluxcor[k2*nrows+k]/cnumb[k];
270 else
271 scale = 1.0;
272 fluxes[k2][k] *= scale;
273 fluxerrs[k2][k] *= scale;
274 if (k2 == 0) {
275 fluxes[NAPCOR][k] *= scale;
276 fluxerrs[NAPCOR][k] *= scale;
277 }
278 }
279 if (cnumb[k] != 0.0)
280 mjds[k] /= cnumb[k];
281 }
282
283 /* Ok, we now have altered the fluxes, create a column for the MJD. Find
284 the first column with the 'Blank' in its name. Then map the data array
285 to it and copy the mjd array. */
286
287 colnames_array = cpl_table_get_column_names(casu_tfits_get_table(*outtab));
288 colnames = cpl_array_get_data_string(colnames_array);
289 nc = cpl_array_get_size(colnames_array);
290 i = 0;
291 while (i < nc && strncmp(colnames[i],"Blank",5))
292 i++;
293 if (i < nc) {
294 cpl_table_name_column(casu_tfits_get_table(*outtab),colnames[i],
295 "MJDoff");
296 cpl_table_set_column_unit(casu_tfits_get_table(*outtab),"MJDoff",
297 "Minutes");
298 data = cpl_table_get_data_float(casu_tfits_get_table(*outtab),
299 "MJDoff");
300 memmove(data,mjds,nrows*sizeof(float));
301 }
302 cpl_array_delete(colnames_array);
303
304 /* Set up some header items */
305
306 plist = casu_tfits_get_ehu(*outtab);
307 cpl_propertylist_append_bool(plist,"ESO DRS GROUTED",1);
308 cpl_propertylist_set_comment(plist,"ESO DRS GROUTED",
309 "Table has been grouted");
310 cpl_propertylist_append_float(plist,"MJD_DAY",mjd_day);
311 cpl_propertylist_set_comment(plist,"MJD_DAY","MJD day");
312
313 /* Add a card with the mean magnitude zeropoint for each input pawprint */
314
315 msg[0] = '\0';
316 m = 0;
317 for (i = 0; i < NPAWS; i++) {
318 for (j = 0; j < NEXTN; j++)
319 work[j] = pawtabs[m++].magzpt;
320 delta_mag = casu_med(work,NULL,NEXTN);
321 (void)sprintf(sval,"%0.3f ",delta_mag);
322 (void)strcat(msg,sval);
323 }
324 cpl_propertylist_append_string(plist,"ESO DRS PAWMAGZP",msg);
325 cpl_propertylist_set_comment(plist,"ESO DRS PAWMAGZP",
326 "Mag Zpt of input pawprints");
327
328 /* Add a card with the mean ellipticity for each input pawprint */
329
330 msg[0] = '\0';
331 m = 0;
332 for (i = 0; i < NPAWS; i++) {
333 for (j = 0; j < NEXTN; j++)
334 work[j] = pawtabs[m++].ellipt;
335 delta_mag = casu_med(work,NULL,NEXTN);
336 (void)sprintf(sval,"%0.3f ",delta_mag);
337 (void)strcat(msg,sval);
338 }
339 cpl_propertylist_append_string(plist,"ESO DRS PAWELLPT",msg);
340 cpl_propertylist_set_comment(plist,"ESO DRS PAWELLPT",
341 "Median paw ELLIPTIC");
342
343 /* Add a card with the median seeing for each of the pawprints */
344
345 m = 0;
346 msg[0] = '\0';
347 for (i = 0; i < NPAWS; i++) {
348 for (j = 0; j < NEXTN; j++)
349 work[j] = pawtabs[m++].seeing;
350 delta_mag = casu_med(work,NULL,NEXTN);
351 (void)sprintf(sval,"%0.3f ",delta_mag);
352 (void)strcat(msg,sval);
353 }
354 cpl_propertylist_append_string(plist,"ESO DRS PAWSEENG",msg);
355 cpl_propertylist_set_comment(plist,"ESO DRS PAWSEENG",
356 "[arcsec] Median paw SEEING");
357
358 /* Free up some memory */
359
360 freespace(fspace);
361 freespace(dspace);
362 tidytabs(maintab,pawtabs);
363
364 /* Get out of here */
365
366 *status = CASU_OK;
367 return(*status);
368}
369
370
371static int gettabinfo(cpl_propertylist *plist, tables *tab, double *mjdobs) {
372 int i;
373
374 /* Get the WCS from the propertylist */
375
376 tab->wcs = cpl_wcs_new_from_propertylist(plist);
377
378 /* Get the aperture corrections */
379
380 for (i = 0; i < NAPCOR; i++)
381 tab->apcors[i] = cpl_propertylist_get_float(plist,apcorkeys[i]);
382
383 /* Get the magnitude zero point */
384
385 tab->magzpt = cpl_propertylist_get_float(plist,"ESO QC MAGZPT");
386
387 /* And the seeing */
388
389 tab->seeing = cpl_propertylist_get_float(plist,"ESO DRS SEEING");
390
391 /* And the ellipticity */
392
393 tab->ellipt = cpl_propertylist_get_float(plist,"ESO QC ELLIPTICITY");
394
395 /* And the mean MJD of the pawprint */
396
397 *mjdobs = cpl_propertylist_get_float(plist,"MJD_MEAN");
398
399 /* Finally the image sizes */
400
401 tab->nxout = cpl_propertylist_get_int(plist,"ESO DRS NXOUT");
402 tab->nyout = cpl_propertylist_get_int(plist,"ESO DRS NYOUT");
403 return(CASU_OK);
404}
405
406static void tidytabs(tables maintab, tables *tabs) {
407 int i;
408
409 freewcs(maintab.wcs);
410 for (i = 0; i < NEXTN*NPAWS; i++)
411 freewcs(tabs[i].wcs);
412}
413
416/*
417
418$Log: not supported by cvs2svn $
419
420*/
cpl_image * casu_fits_get_image(casu_fits *p)
Definition: casu_fits.c:436
casu_fits * casu_fits_load(cpl_frame *frame, cpl_type type, int nexten)
Definition: casu_fits.c:80
float casu_med(float *data, unsigned char *bpm, long npts)
Definition: casu_stats.c:89
cpl_propertylist * casu_tfits_get_ehu(casu_tfits *p)
Definition: casu_tfits.c:473
casu_tfits * casu_tfits_duplicate(casu_tfits *in)
Definition: casu_tfits.c:196
cpl_table * casu_tfits_get_table(casu_tfits *p)
Definition: casu_tfits.c:364
void casu_xytoxy_list(cpl_wcs *wcs1, cpl_wcs *wcs2, int nc, double *x_1, double *y_1, double *x_2, double *y_2)
int vircam_grout(casu_tfits *intab, cpl_frameset *input_cats, cpl_frameset *input_confs, casu_tfits **outtab, int *status)
Correct input tile catalogues.
Definition: vircam_grout.c:108