VIRCAM Pipeline  1.3.3
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) 2013 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: 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 "vircam_mods.h"
39 #include "vircam_tfits.h"
40 #include "vircam_wcsutils.h"
41 #include "vircam_utils.h"
42 #include "vircam_stats.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 
50 typedef 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 
61 const char *apcorkeys[NAPCOR] = {"APCOR1","APCOR2","APCOR3","APCOR4","APCOR5",
62  "APCOR6","APCOR7"};
63 
64 static int gettabinfo(cpl_propertylist *plist, tables *tab, double *mjdobs);
65 static void tidytabs(tables maintab, tables *tabs);
66 
69 /*---------------------------------------------------------------------------*/
106 /*---------------------------------------------------------------------------*/
107 
108 extern int vircam_grout(vir_tfits *intab, cpl_frameset *input_cats,
109  cpl_frameset *input_confs, vir_tfits **outtab,
110  int *status) {
111  int retval,i,j,m,nrows,*conf_data,k,ix,iy,ind,k2,nc,mjd_day;
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  vir_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 != VIR_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(vircam_tfits_get_ehu(intab),"ESO DRS GROUTED")) {
140  *outtab = vircam_tfits_duplicate(intab);
141  return(*status);
142  }
143 
144  /* Make a copy of the input table which will then be updated */
145 
146  *outtab = vircam_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(vircam_tfits_get_ehu(*outtab),&maintab,&mjdobs);
157  if (retval != VIR_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(vircam_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(vircam_tfits_get_table(*outtab),
182  "X_coordinate");
183  yptr = cpl_table_get_data_float(vircam_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_frame(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 != VIR_OK) {
199  freespace(dspace);
200  freespace(mjds);
201  freetfits(*outtab);
202  freepropertylist(plist);
203  return(VIR_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  }
210  }
211 
212  /* Loop for each stack image extension */
213 
214  m = -1;
215  for (i = 0; i < NPAWS; i++) {
216  fr = cpl_frameset_get_frame(input_confs,i);
217  for (j = 0; j < NEXTN; j++) {
218  conf_fits = vircam_fits_load(fr,CPL_TYPE_INT,j+1);
219  conf_data = cpl_image_get_data_int(vircam_fits_get_image(conf_fits));
220  m++;
221  delta_mag = maintab.magzpt - pawtabs[m].magzpt;
222 
223  /* Shift the tile object coordinates to the reference frame of
224  the current pawprint */
225 
226  vircam_xytoxy_list(maintab.wcs,pawtabs[m].wcs,nrows,x,y,x2,y2);
227 
228  /* Loop through each object now and see if it's on this image.
229  If it is, then work out the contribution to the flux correction
230  that you get from the current image */
231 
232  xmax = (float)pawtabs[m].nxout - 0.5;
233  ymax = (float)pawtabs[m].nyout;
234  for (k = 0; k < nrows; k++) {
235  if (x2[k] >= 0.5 && x2[k] < xmax &&
236  y2[k] >= 0.5 && y2[k] < ymax) {
237  ix = (int)(x2[k] + 0.5) - 1;
238  iy = (int)(y2[k] + 0.5) - 1;
239  ind = iy*pawtabs[m].nxout + ix;
240  confwt = (float)max(1.0,conf_data[ind]);
241  mjds[k] += confwt*pawtabs[m].mjdobs;
242  cnumb[k] += confwt;
243  for (k2 = 0; k2 < NAPCOR; k2++) {
244  expon = 0.4*(double)(pawtabs[m].apcors[k2] -
245  maintab.apcors[k2] + delta_mag);
246  fluxcor[k2*nrows+k] += confwt*pow(10.0,expon);
247  }
248  }
249  }
250  freefits(conf_fits);
251  }
252  }
253 
254  /* Get pointers to each of the fluxes and their errors */
255 
256  for (i = 0; i < NAPCOR+1; i++) {
257  fluxes[i] = cpl_table_get_data_float(vircam_tfits_get_table(*outtab),
258  fluxcols[i]);
259  fluxerrs[i] = cpl_table_get_data_float(vircam_tfits_get_table(*outtab),
260  errcols[i]);
261  }
262 
263  /* Now normalise the flux corrections and apply them */
264 
265  for (k = 0; k < nrows; k++) {
266  for (k2 = 0; k2 < NAPCOR; k2++) {
267  if (cnumb[k] != 0.0)
268  scale = fluxcor[k2*nrows+k]/cnumb[k];
269  else
270  scale = 1.0;
271  fluxes[k2][k] *= scale;
272  fluxerrs[k2][k] *= scale;
273  if (k2 == 0) {
274  fluxes[NAPCOR][k] *= scale;
275  fluxerrs[NAPCOR][k] *= scale;
276  }
277  }
278  if (cnumb[k] != 0.0)
279  mjds[k] /= cnumb[k];
280  }
281 
282  /* Ok, we now have altered the fluxes, create a column for the MJD. Find
283  the first column with the 'Blank' in its name. Then map the data array
284  to it and copy the mjd array. */
285 
286  colnames_array = cpl_table_get_column_names(vircam_tfits_get_table(*outtab));
287  colnames = cpl_array_get_data_string(colnames_array);
288  nc = cpl_array_get_size(colnames_array);
289  i = 0;
290  while (i < nc && strncmp(colnames[i],"Blank",5))
291  i++;
292  if (i < nc) {
293  cpl_table_name_column(vircam_tfits_get_table(*outtab),colnames[i],
294  "MJDoff");
295  cpl_table_set_column_unit(vircam_tfits_get_table(*outtab),"MJDoff",
296  "Minutes");
297  data = cpl_table_get_data_float(vircam_tfits_get_table(*outtab),
298  "MJDoff");
299  memmove(data,mjds,nrows*sizeof(float));
300  }
301  cpl_array_delete(colnames_array);
302 
303  /* Set up some header items */
304 
305  plist = vircam_tfits_get_ehu(*outtab);
306  cpl_propertylist_append_bool(plist,"ESO DRS GROUTED",1);
307  cpl_propertylist_set_comment(plist,"ESO DRS GROUTED",
308  "Table has been grouted");
309  cpl_propertylist_append_float(plist,"MJD_DAY",mjd_day);
310  cpl_propertylist_set_comment(plist,"MJD_DAY","MJD day");
311 
312  /* Add a card with the mean magnitude zeropoint for each input pawprint */
313 
314  msg[0] = '\0';
315  m = 0;
316  for (i = 0; i < NPAWS; i++) {
317  for (j = 0; j < NEXTN; j++)
318  work[j] = pawtabs[m++].magzpt;
319  delta_mag = vircam_med(work,NULL,NEXTN);
320  (void)sprintf(sval,"%0.3f ",delta_mag);
321  (void)strcat(msg,sval);
322  }
323  cpl_propertylist_append_string(plist,"ESO DRS PAWMAGZP",msg);
324  cpl_propertylist_set_comment(plist,"ESO DRS PAWMAGZP",
325  "Mag Zpt of input pawprints");
326 
327  /* Add a card with the mean ellipticity for each input pawprint */
328 
329  msg[0] = '\0';
330  m = 0;
331  for (i = 0; i < NPAWS; i++) {
332  for (j = 0; j < NEXTN; j++)
333  work[j] = pawtabs[m++].ellipt;
334  delta_mag = vircam_med(work,NULL,NEXTN);
335  (void)sprintf(sval,"%0.3f ",delta_mag);
336  (void)strcat(msg,sval);
337  }
338  cpl_propertylist_append_string(plist,"ESO DRS PAWELLPT",msg);
339  cpl_propertylist_set_comment(plist,"ESO DRS PAWELLPT",
340  "Median paw ELLIPTIC");
341 
342  /* Add a card with the median seeing for each of the pawprints */
343 
344  m = 0;
345  msg[0] = '\0';
346  for (i = 0; i < NPAWS; i++) {
347  for (j = 0; j < NEXTN; j++)
348  work[j] = pawtabs[m++].seeing;
349  delta_mag = vircam_med(work,NULL,NEXTN);
350  (void)sprintf(sval,"%0.3f ",delta_mag);
351  (void)strcat(msg,sval);
352  }
353  cpl_propertylist_append_string(plist,"ESO DRS PAWSEENG",msg);
354  cpl_propertylist_set_comment(plist,"ESO DRS PAWSEENG",
355  "[arcsec] Median paw SEEING");
356 
357  /* Free up some memory */
358 
359  freespace(fspace);
360  freespace(dspace);
361  tidytabs(maintab,pawtabs);
362 
363  /* Get out of here */
364 
365  *status = VIR_OK;
366  return(*status);
367 }
368 
369 
370 static int gettabinfo(cpl_propertylist *plist, tables *tab, double *mjdobs) {
371  int i;
372 
373  /* Get the WCS from the propertylist */
374 
375  tab->wcs = cpl_wcs_new_from_propertylist(plist);
376 
377  /* Get the aperture corrections */
378 
379  for (i = 0; i < NAPCOR; i++)
380  tab->apcors[i] = cpl_propertylist_get_float(plist,apcorkeys[i]);
381 
382  /* Get the magnitude zero point */
383 
384  tab->magzpt = cpl_propertylist_get_float(plist,"ESO QC MAGZPT");
385 
386  /* And the seeing */
387 
388  tab->seeing = cpl_propertylist_get_float(plist,"ESO DRS SEEING");
389 
390  /* And the ellipticity */
391 
392  tab->ellipt = cpl_propertylist_get_float(plist,"ESO QC ELLIPTICITY");
393 
394  /* And the mean MJD of the pawprint */
395 
396  *mjdobs = cpl_propertylist_get_float(plist,"MJD_MEAN");
397 
398  /* Finally the image sizes */
399 
400  tab->nxout = cpl_propertylist_get_int(plist,"ESO DRS NXOUT");
401  tab->nyout = cpl_propertylist_get_int(plist,"ESO DRS NYOUT");
402  return(VIR_OK);
403 }
404 
405 static void tidytabs(tables maintab, tables *tabs) {
406  int i;
407 
408  freewcs(maintab.wcs);
409  for (i = 0; i < NEXTN*NPAWS; i++)
410  freewcs(tabs[i].wcs);
411 }
412 
415 /*
416 
417 $Log: not supported by cvs2svn $
418 
419 */