VIRCAM Pipeline  2.3.12
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 
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(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 
371 static 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 
406 static 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_table * casu_tfits_get_table(casu_tfits *p)
Definition: casu_tfits.c:364
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
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