vircam_photcal.c

00001 /* $Id: vircam_photcal.c,v 1.29 2007/10/25 17:34:01 jim Exp $
00002  *
00003  * This file is part of the VIRCAM Pipeline
00004  * Copyright (C) 2005 Cambridge Astronomy Survey Unit
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: jim $
00023  * $Date: 2007/10/25 17:34:01 $
00024  * $Revision: 1.29 $
00025  * $Name:  $
00026  */
00027 
00028 /* Includes */
00029 
00030 #ifdef HAVE_CONFIG_H
00031 #include <config.h>
00032 #endif
00033 
00034 #include <cpl.h>
00035 #include <math.h>
00036 #include <string.h>
00037 
00038 #include "vircam_mods.h"
00039 #include "vircam_utils.h"
00040 #include "vircam_pfits.h"
00041 #include "vircam_stats.h"
00042 #include "vircam_fits.h"
00043 
00044 typedef struct {
00045     char *filt;
00046     char **columns;
00047     int ncolumns;
00048     float extinct;
00049     float *coloureq;
00050     float offset;
00051     int nmags;
00052 } photstrct;
00053 
00054 static photstrct p;
00055 
00056 #define NOMPIXSIZE 0.34
00057 #define INITALLOC 1024
00058 #define SZBUF 1024
00059 
00060 static double pixsize (cpl_propertylist *plist);
00061 static int vircam_phot_open(cpl_table *phottab, char *filt);
00062 static void vircam_phot_close(void);
00063 static int extract_columns(cpl_table *tab);
00064 static int extract_coleq(cpl_table *tab);
00065 
00068 /*---------------------------------------------------------------------------*/
00150 /*---------------------------------------------------------------------------*/
00151 
00152 extern int vircam_photcal(vir_fits **images, cpl_table **mstds, 
00153                           cpl_propertylist **pl, int nimages, char *filt, 
00154                           cpl_table *phottab, int *status) {
00155     float **stdmagptr,*resall3,*resall5,cdfudge,saturate,apcor3,apcor5,exptime;
00156     float airmass,*catcore3,*catcore5,*resim3,*resim5,cf,fluxmag3,fluxmag5;
00157     float refmag,extinct,dm3,dm5,med3,mad,cut,lcut,hcut,med5,sig3,sig5;
00158     float rcore,lim3,lim5;
00159     int nresall,nalloc_resall,i,j,k,ncat,nresim;
00160     char junk[SZBUF];
00161     const char *fctid = "vircam_photcal";
00162     vir_fits *im;
00163     cpl_propertylist *ehu_im,*ehu_cat;
00164     cpl_table *stds,*cl;
00165 
00166     /* Inherited status */
00167 
00168     if (*status != VIR_OK)
00169         return(*status);
00170 
00171     /* Check for nonsense errors */
00172 
00173     if (nimages <= 0) {
00174         cpl_msg_error(fctid,"No images included in photometric calibration");
00175         FATAL_ERROR
00176     }
00177 
00178     /* Set up the structure that will give us the colour equations for
00179        this filter later on */
00180 
00181     if (vircam_phot_open(phottab,filt) != VIR_OK)
00182         FATAL_ERROR
00183 
00184     /* Get a workspace to hold the pointers to the magnitude columns */
00185 
00186     stdmagptr = cpl_malloc(p.ncolumns*sizeof(float *));
00187 
00188     /* Get some workspace to hold all the zeropoints for all the images
00189        in the input list. This is an initial allocation and more can be
00190        made available later if needed */
00191 
00192     resall3 = cpl_malloc(INITALLOC*sizeof(float));
00193     resall5 = cpl_malloc(INITALLOC*sizeof(float));
00194     nresall = 0;
00195     nalloc_resall = INITALLOC;
00196 
00197     /* Loop for the input images and catalogues. Create some shorthand
00198        variables and work out what the zeropoint fudge factor will be 
00199        based on the sampling of the current frame and the nominal sampling
00200        of a VIRCAM image */
00201 
00202     for (i = 0; i < nimages; i++) {
00203         im = images[i];
00204         ehu_im = vircam_fits_get_ehu(im);
00205         stds = mstds[i];
00206         ehu_cat = pl[i];
00207         cdfudge = 2.5*log10((double)pixsize(ehu_im)/NOMPIXSIZE);
00208 
00209         /* Now for the input catalogues. Start by getting some useful info
00210            from the header */
00211 
00212         saturate = cpl_propertylist_get_float(ehu_cat,"ESO QC SATURATION");
00213         apcor3 = cpl_propertylist_get_float(ehu_cat,"APCOR3");
00214         apcor5 = cpl_propertylist_get_float(ehu_cat,"APCOR5");
00215         rcore = cpl_propertylist_get_float(ehu_cat,"ESO DRS RCORE");
00216         (void)vircam_pfits_get_exptime(ehu_cat,&exptime);
00217         (void)vircam_pfits_get_airmass(vircam_fits_get_phu(im),&airmass);
00218         if (cpl_error_get_code() != CPL_ERROR_NONE) {
00219             cpl_msg_error(fctid,"Unable to get header info for %s",
00220                           vircam_fits_get_fullname(im));
00221             cpl_error_reset();
00222             continue;
00223         }
00224 
00225         /* Get objects that are not saturated and aren't too elliptical */
00226 
00227         cpl_table_select_all(stds);  
00228         cpl_table_and_selected_float(stds,"Ellipticity",CPL_LESS_THAN,0.5);
00229         cpl_table_and_selected_float(stds,"Peak_height",CPL_LESS_THAN,
00230                                      saturate);
00231         if (cpl_error_get_code() != CPL_ERROR_NONE) {
00232             cpl_msg_error(fctid,"Unable select data from matched stds tab %s",
00233                           vircam_fits_get_fullname(im));
00234             cpl_error_reset();
00235             continue;
00236         }
00237 
00238         /* Get all objects where the magnitude errors are less than 0.1 */
00239 
00240         for (j = 0; j < p.ncolumns; j++) {
00241             (void)snprintf(junk,SZBUF,"%ssig",(p.columns)[j]);
00242             cpl_table_and_selected_float(stds,junk,CPL_LESS_THAN,0.1);
00243         }
00244 
00245         /* Now extract all those that have passed the test. If none are left
00246            then issue a warning and move on to the next one */
00247 
00248         cl = cpl_table_extract_selected(stds);
00249         ncat = cpl_table_get_nrow(cl);
00250         if (ncat == 0) {
00251             cpl_msg_error(fctid,"No good standards available for %s",
00252                          vircam_fits_get_fullname(im));
00253             cpl_table_delete(cl);
00254             cpl_error_reset();
00255             continue;
00256         }
00257 
00258         /* Dereference some of the columns */
00259 
00260         catcore3 = cpl_table_get_data_float(cl,"Aper_flux_3");
00261         catcore5 = cpl_table_get_data_float(cl,"Aper_flux_5");
00262         for (j = 0; j < p.ncolumns; j++) 
00263             stdmagptr[j] = cpl_table_get_data_float(cl,(p.columns)[j]);
00264 
00265         /* Get some workspace for the results arrays for this image */
00266 
00267         resim3 = cpl_malloc(ncat*sizeof(float));
00268         resim5 = cpl_malloc(ncat*sizeof(float));
00269         nresim = 0;
00270 
00271         /* Loop for all the standards */
00272 
00273         extinct = p.extinct*(airmass - 1.0);
00274         for (j = 0; j < ncat; j++) {
00275             
00276             /* Do core magnitude calculation */
00277 
00278             cf = catcore3[j]/exptime;
00279             if (cf < 1.0)
00280                 cf = 1.0;
00281             fluxmag3 = 2.5*log10((double)cf) + apcor3;
00282             cf = catcore5[j]/exptime;
00283             if (cf < 1.0)
00284                 cf = 1.0;
00285             fluxmag5 = 2.5*log10((double)cf) + apcor5;
00286 
00287             /* Work out a reference magnitude */
00288 
00289             refmag = p.offset;
00290             for (k = 0; k < p.nmags; k++) 
00291                 refmag += ((p.coloureq)[k]*stdmagptr[k][j]);
00292 
00293             /* Work out zero points and store them away for later */
00294 
00295             dm3 = refmag + fluxmag3 + extinct;
00296             dm5 = refmag + fluxmag5 + extinct;
00297             resim3[nresim] = dm3 + cdfudge;
00298             resim5[nresim++] = dm5 + cdfudge;
00299             resall3[nresall] = dm3 + cdfudge;
00300             resall5[nresall++] = dm5 + cdfudge;
00301             if (nresall == nalloc_resall) {
00302                 nalloc_resall += INITALLOC;
00303                 resall3 = cpl_realloc(resall3,nalloc_resall*sizeof(float));
00304                 resall5 = cpl_realloc(resall5,nalloc_resall*sizeof(float));
00305             }
00306         }
00307 
00308         /* Ok, what is the mean zeropoint for this image? */
00309 
00310         (void)vircam_medmad(resim3,NULL,(long)nresim,&med3,&mad);
00311         cut = max(3.0*1.48*mad,0.1);
00312         lcut = med3 - cut;
00313         hcut = med3 + cut;
00314         (void)vircam_meansigcut(resim3,NULL,nresim,lcut,hcut,&med3,&sig3);
00315         (void)vircam_medmad(resim5,NULL,(long)nresim,&med5,&mad);
00316         cut = max(3.0*1.48*mad,0.1);
00317         lcut = med5 - cut;
00318         hcut = med5 + cut;
00319         (void)vircam_meansigcut(resim5,NULL,nresim,lcut,hcut,&med5,&sig5);
00320 
00321         /* Delete some workspace */
00322 
00323         freespace(resim3);
00324         freespace(resim5);
00325         freetable(cl);
00326 
00327         /* Calculate the limiting magnitudes */
00328 
00329         lim3 = med3 - 2.5*log10((5.0*sig3*rcore*sqrt(M_PI))/exptime) -
00330             apcor3 - extinct;
00331         lim5 = med5 - 2.5*log10((5.0*sig5*rcore*sqrt(M_PI))/exptime) -
00332             apcor5 - extinct;
00333         
00334         /* Write these results to the header of the image and the catalogue.
00335            First the QC headers for the image. These are not allowed to be
00336            copied into the catalogue headers...*/
00337 
00338         cpl_propertylist_update_float(ehu_im,"ESO QC MAGZPT",med3);
00339         cpl_propertylist_set_comment(ehu_im,"ESO QC MAGZPT",
00340                                      "[mag] photometric zeropoint");
00341         cpl_propertylist_update_float(ehu_im,"ESO QC MAGZERR",sig3);
00342         cpl_propertylist_set_comment(ehu_im,"ESO QC MAGZERR",
00343                                      "[mag] photometric zeropoint error");
00344         cpl_propertylist_update_int(ehu_im,"ESO QC MAGNZPT",nresim);
00345         cpl_propertylist_set_comment(ehu_im,"ESO QC MAGNZPT",
00346                                      "number of stars in magzpt calc");
00347         cpl_propertylist_update_float(ehu_im,"ESO QC LIMITING_MAG",lim3);
00348         cpl_propertylist_set_comment(ehu_im,"ESO QC LIMITING_MAG",
00349                                      "[mag] 5 sigma limiting mag.");
00350         
00351         /* Now the DRS headers for the image */
00352 
00353         cpl_propertylist_update_int(ehu_im,"ESO DRS MAGNZPTIM",nresim);
00354         cpl_propertylist_set_comment(ehu_im,"ESO DRS MAGNZPTIM",
00355                                      "number of stars in image magzpt calc");
00356 
00357         cpl_propertylist_update_float(ehu_im,"ESO DRS ZPIM1",med3);
00358         cpl_propertylist_set_comment(ehu_im,"ESO DRS ZPIM1",
00359                                      "[mag] zeropoint 1*rcore this image only");
00360         cpl_propertylist_update_float(ehu_im,"ESO DRS ZPSIGIM1",sig3);
00361         cpl_propertylist_set_comment(ehu_im,"ESO DRS ZPSIGIM1",
00362                                      "[mag] zeropoint sigma 1*rcore this image only");
00363         cpl_propertylist_update_float(ehu_im,"ESO DRS LIMIT_MAG1",lim3);
00364         cpl_propertylist_set_comment(ehu_im,"ESO DRS LIMIT_MAG1",
00365                                      "[mag] 5 sigma limiting mag 1*rcore.");
00366         cpl_propertylist_update_float(ehu_im,"ESO DRS ZPIM2",med5);
00367         cpl_propertylist_set_comment(ehu_im,"ESO DRS ZPIM2",
00368                                      "[mag] zeropoint 2*rcore this image only");
00369         cpl_propertylist_update_float(ehu_im,"ESO DRS ZPSIGIM2",sig5);
00370         cpl_propertylist_set_comment(ehu_im,"ESO DRS ZPSIGIM2",
00371                                      "[mag] zeropoint sigma 2*rcore this image only");
00372         cpl_propertylist_update_float(ehu_im,"ESO DRS LIMIT_MAG2",lim5);
00373         cpl_propertylist_set_comment(ehu_im,"ESO DRS LIMIT_MAG2",
00374                                      "[mag] 5 sigma limiting mag core5.");
00375         cpl_propertylist_update_float(ehu_im,"ESO DRS EXTINCT",p.extinct);
00376         cpl_propertylist_set_comment(ehu_im,"ESO DRS EXTINCT",
00377                                      "[mag] Assumed extinction.");
00378 
00379         /* And for the catalogue */
00380 
00381         cpl_propertylist_update_int(ehu_cat,"ESO DRS MAGNZPTIM",nresim);
00382         cpl_propertylist_set_comment(ehu_cat,"ESO DRS MAGNZPTIM",
00383                                      "number of stars in image magzpt calc");
00384 
00385         cpl_propertylist_update_float(ehu_cat,"ESO DRS ZPIM1",med3);
00386         cpl_propertylist_set_comment(ehu_cat,"ESO DRS ZPIM1",
00387                                      "[mag] zeropoint 1*rcore this image only");
00388         cpl_propertylist_update_float(ehu_cat,"ESO DRS ZPSIGIM1",sig3);
00389         cpl_propertylist_set_comment(ehu_cat,"ESO DRS ZPSIGIM1",
00390                                      "[mag] zeropoint sigma 1*rcore this image only");
00391         cpl_propertylist_update_float(ehu_cat,"ESO DRS LIMIT_MAG1",lim3);
00392         cpl_propertylist_set_comment(ehu_cat,"ESO DRS LIMIT_MAG1",
00393                                      "[mag] 5 sigma limiting mag 1*rcore.");
00394         cpl_propertylist_update_float(ehu_cat,"ESO DRS ZPIM2",med5);
00395         cpl_propertylist_set_comment(ehu_cat,"ESO DRS ZPIM2",
00396                                      "[mag] zeropoint 2*rcore this image only");
00397         cpl_propertylist_update_float(ehu_cat,"ESO DRS ZPSIGIM2",sig5);
00398         cpl_propertylist_set_comment(ehu_cat,"ESO DRS ZPSIGIM2",
00399                                      "[mag] zeropoint sigma 2*rcore this image only");
00400         cpl_propertylist_update_float(ehu_cat,"ESO DRS LIMIT_MAG2",lim5);
00401         cpl_propertylist_set_comment(ehu_cat,"ESO DRS LIMIT_MAG2",
00402                                      "[mag] 5 sigma limiting mag 2*rcore.");
00403         cpl_propertylist_update_float(ehu_im,"ESO DRS EXTINCT",p.extinct);
00404         cpl_propertylist_set_comment(ehu_im,"ESO DRS EXTINCT",
00405                                      "[mag] Assumed extinction.");
00406 
00407     }
00408 
00409     /* Ok, what is the mean zeropoint for all images? */
00410 
00411     if (nresall > 0) {
00412         (void)vircam_medmad(resall3,NULL,(long)nresall,&med3,&mad);
00413         cut = max(3.0*1.48*mad,0.1);
00414         lcut = med3 - cut;
00415         hcut = med3 + cut;
00416         (void)vircam_meansigcut(resall3,NULL,nresall,lcut,hcut,&med3,&sig3);
00417         (void)vircam_medmad(resall5,NULL,(long)nresall,&med5,&mad);
00418         cut = max(3.0*1.48*mad,0.1);
00419         lcut = med5 - cut;
00420         hcut = med5 + cut;
00421         (void)vircam_meansigcut(resall5,NULL,nresall,lcut,hcut,&med5,&sig5);
00422     }
00423 
00424     /* Delete some workspace */
00425 
00426     freespace(resall3);
00427     freespace(resall5);
00428     freespace(stdmagptr);
00429     vircam_phot_close();
00430 
00431     /* Write these results to the header of the images and the catalogues. 
00432        First the images */
00433 
00434     if (nresall > 0) {
00435         for (i = 0; i < nimages; i++) {
00436             im = images[i];
00437             ehu_im = vircam_fits_get_ehu(im);
00438             stds = mstds[i];
00439             ehu_cat = pl[i];
00440             cpl_propertylist_update_int(ehu_im,"ESO DRS MAGNZPTALL",nresall);
00441             cpl_propertylist_set_comment(ehu_im,"ESO DRS MAGNZPTALL",
00442                                          "number of stars in all magzpt calc");
00443             cpl_propertylist_update_float(ehu_im,"ESO DRS ZPALL1",med3);
00444             cpl_propertylist_set_comment(ehu_im,"ESO DRS ZPALL1",
00445                                          "[mag] zeropoint 1*rcore all group images");
00446             cpl_propertylist_update_float(ehu_im,"ESO DRS ZPSIGALL1",sig3);
00447             cpl_propertylist_set_comment(ehu_im,"ESO DRS ZPSIGALL1",
00448                                          "[mag] zeropoint sigma 1*rcore all group images");
00449             cpl_propertylist_update_float(ehu_im,"ESO DRS ZPALL2",med5);
00450             cpl_propertylist_set_comment(ehu_im,"ESO DRS ZPALL2",
00451                                          "[mag] zeropoint 2*rcore all group images");
00452             cpl_propertylist_update_float(ehu_im,"ESO DRS ZPSIGALL2",sig5);
00453             cpl_propertylist_set_comment(ehu_im,"ESO DRS ZPSIGALL2",
00454                                          "[mag] zeropoint sigma 2*rcore all group images");
00455 
00456             /* Now the catalogues */
00457 
00458             cpl_propertylist_update_int(ehu_cat,"ESO DRS MAGNZPTALL",nresall);
00459             cpl_propertylist_set_comment(ehu_cat,"ESO DRS MAGNZPTALL",
00460                                          "number of stars in all magzpt calc");
00461             cpl_propertylist_update_float(ehu_cat,"ESO DRS ZPALL1",med3);
00462             cpl_propertylist_set_comment(ehu_cat,"ESO DRS ZPALL1",
00463                                          "[mag] zeropoint 1*rcore all group images");
00464             cpl_propertylist_update_float(ehu_cat,"ESO DRS ZPSIGALL1",sig3);
00465             cpl_propertylist_set_comment(ehu_cat,"ESO DRS ZPSIGALL1",
00466                                          "[mag] zeropoint sigma 1*rcore all group images");
00467             cpl_propertylist_update_float(ehu_cat,"ESO DRS ZPALL2",med5);
00468             cpl_propertylist_set_comment(ehu_cat,"ESO DRS ZPALL2",
00469                                          "[mag] zeropoint 2*rcore all group images");
00470             cpl_propertylist_update_float(ehu_cat,"ESO DRS ZPSIGALL2",sig5);
00471             cpl_propertylist_set_comment(ehu_cat,"ESO DRS ZPSIGALL2",
00472                                          "[mag] zeropoint sigma 2*rcore all group images");
00473         }
00474     }
00475 
00476     /* Get out of here */
00477 
00478     GOOD_STATUS
00479 
00480 }
00481 
00482 /*---------------------------------------------------------------------------*/
00533 /*---------------------------------------------------------------------------*/
00534 
00535 extern int vircam_illum(vir_fits **images, cpl_table **mstds, 
00536                         cpl_propertylist **pl, int nimages, char *filt,
00537                         cpl_table *phottab, int nbsize, cpl_table **illcor, 
00538                         float *illcor_rms,int *status) {
00539     const char *fctid = "vircam_illum";
00540     char junk[SZBUF];
00541     float **stdmagptr,fracx,fracy,**results,cdfudge,saturate,apcor3,exptime;
00542     float airmass,*catcore3,*xx,*yy,extinct,cf,fluxmag3,refmag,dm3,med,mad;
00543     float xmin,xmax,ymin,ymax,*resall,medall,lcut,hcut,sig,cut,*good;
00544     int nx,ny,ifracx,ifracy,nbsizx,nbsizy,nbx,nby,*nres,*nall,i,j,ncat,k;
00545     int ix,iy,ind,nresall,nallocall,ngood;
00546     vir_fits *im;
00547     cpl_propertylist *ehu_im,*ehu_cat;
00548     cpl_table *stds,*cl;
00549 
00550     /* Inherited status */
00551 
00552     *illcor = NULL;
00553     *illcor_rms = 0.0;
00554     if (*status != VIR_OK)
00555         return(*status);
00556 
00557     /* Check for nonsense errors */
00558 
00559     if (nimages <= 0) {
00560         cpl_msg_error(fctid,"No images included in photometric calibration");
00561         FATAL_ERROR
00562     }
00563 
00564     /* Set up the structure that will give us the colour equations for
00565        this filter later on */
00566 
00567     if (vircam_phot_open(phottab,filt) != VIR_OK)
00568         FATAL_ERROR
00569 
00570     /* Get a workspace to hold the pointers to the magnitude columns */
00571 
00572     stdmagptr = cpl_malloc(p.ncolumns*sizeof(float *));
00573 
00574     /* Check to see if nbsize is close to exact divisor */
00575 
00576     nx = cpl_image_get_size_x(vircam_fits_get_image(images[0]));
00577     ny = cpl_image_get_size_y(vircam_fits_get_image(images[0]));
00578     fracx = ((float)nx)/((float)nbsize);
00579     fracy = ((float)ny)/((float)nbsize);
00580     ifracx = (int)(fracx + 0.1);
00581     ifracy = (int)(fracy + 0.1);
00582     nbsizx = nx/ifracx;
00583     nbsizy = ny/ifracy;
00584     nbsize = max(vircam_nint(0.9*nbsize),min(nbsize,min(nbsizx,nbsizy)));
00585     nbsize = min(nx,min(ny,nbsize)); /* trap for small maps */
00586 
00587     /* Divide the map into partitions */
00588 
00589     nbx = nx/nbsize;
00590     nby = ny/nbsize;
00591 
00592     /* Get some workspace to hold all the zeropoints for all the images
00593        in the input list. This is an initial allocation and more can be
00594        made available later if needed */
00595 
00596     results = cpl_malloc(nbx*nby*sizeof(float *));
00597     good = cpl_malloc(nbx*nby*sizeof(float));
00598     nres = cpl_calloc(nbx*nby,sizeof(int));
00599     nall = cpl_malloc(nbx*nby*sizeof(int));
00600     for (i = 0; i < nbx*nby; i++) {
00601         results[i] = cpl_malloc(INITALLOC*sizeof(float));
00602         nall[i] = INITALLOC;
00603     }
00604     resall = cpl_malloc(INITALLOC*sizeof(float));
00605     nresall = 0;
00606     nallocall = INITALLOC;
00607 
00608     /* Set up the output illumination correction table */
00609 
00610     *illcor = vircam_illcor_newtab(nbx*nby);
00611     
00612     /* Loop for the input images and catalogues. Create some shorthand
00613        variables and work out what the zeropoint fudge factor will be 
00614        based on the sampling of the current frame and the nominal sampling
00615        of a VIRCAM image */
00616 
00617     for (i = 0; i < nimages; i++) {
00618         im = images[i];
00619         ehu_im = vircam_fits_get_ehu(im);
00620         stds = mstds[i];
00621         if (stds == NULL)
00622             continue;
00623         ehu_cat = pl[i];
00624         cdfudge = 2.5*log10((double)pixsize(ehu_im)/NOMPIXSIZE);
00625 
00626         /* Now for the input catalogues. Start by getting some useful info
00627            from the header */
00628 
00629         saturate = cpl_propertylist_get_float(ehu_cat,"ESO QC SATURATION");
00630         apcor3 = cpl_propertylist_get_float(ehu_cat,"APCOR3");
00631         (void)vircam_pfits_get_exptime(vircam_fits_get_phu(im),&exptime);
00632         (void)vircam_pfits_get_airmass(vircam_fits_get_phu(im),&airmass);
00633         if (cpl_error_get_code() != CPL_ERROR_NONE) {
00634             cpl_msg_error(fctid,"Unable to get header info for %s",
00635                           vircam_fits_get_fullname(im));
00636             cpl_error_reset();
00637             continue;
00638         }
00639 
00640         /* Get objects that are not saturated and aren't too elliptical */
00641 
00642         cpl_table_select_all(stds);  
00643         cpl_table_and_selected_float(stds,"Ellipticity",CPL_LESS_THAN,0.5);
00644         cpl_table_and_selected_float(stds,"Peak_height",CPL_LESS_THAN,
00645                                      saturate);
00646         if (cpl_error_get_code() != CPL_ERROR_NONE) {
00647             cpl_msg_error(fctid,"Unable select data from matched stds tab %s",
00648                           vircam_fits_get_fullname(im));
00649             cpl_error_reset();
00650             continue;
00651         }
00652 
00653         /* Get all objects where the magnitude errors are less than 0.1 */
00654 
00655         for (j = 0; j < p.ncolumns; j++) {
00656             (void)snprintf(junk,SZBUF,"%ssig",(p.columns)[j]);
00657             cpl_table_and_selected_float(stds,junk,CPL_LESS_THAN,0.1);
00658         }
00659 
00660         /* Now extract all those that have passed the test. If none are left
00661            then issue a warning and move on to the next one */
00662 
00663         cl = cpl_table_extract_selected(stds);
00664         ncat = cpl_table_get_nrow(cl);
00665         if (ncat == 0) {
00666             cpl_msg_error(fctid,"No good standards available for %s",
00667                          vircam_fits_get_fullname(im));
00668             cpl_table_delete(cl);
00669             cpl_error_reset();
00670             continue;
00671         }
00672 
00673         /* Dereference some of the columns */
00674 
00675         catcore3 = cpl_table_get_data_float(cl,"Aper_flux_3");
00676         xx = cpl_table_get_data_float(cl,"X_coordinate");
00677         yy = cpl_table_get_data_float(cl,"Y_coordinate");
00678         for (j = 0; j < p.ncolumns; j++) 
00679             stdmagptr[j] = cpl_table_get_data_float(cl,(p.columns)[j]);
00680 
00681         /* Loop for all the standards */
00682 
00683         extinct = p.extinct*(airmass - 1.0);
00684         for (j = 0; j < ncat; j++) {
00685             
00686             /* Do core magnitude calculation */
00687 
00688             cf = catcore3[j]/exptime;
00689             if (cf < 1.0)
00690                 cf = 1.0;
00691             fluxmag3 = 2.5*log10((double)cf) + apcor3;
00692 
00693             /* Work out a reference magnitude */
00694 
00695             refmag = p.offset;
00696             for (k = 0; k < p.nmags; k++) 
00697                 refmag += ((p.coloureq)[k]*stdmagptr[k][j]);
00698 
00699             /* Work out zero point */
00700 
00701             dm3 = refmag + fluxmag3 + extinct + cdfudge;
00702 
00703             /* What cell does this belong to? */
00704 
00705             ix = (int)(xx[j]/(float)nbsize);
00706             iy = (int)(yy[j]/(float)nbsize);
00707             ind = iy*nbx + ix;
00708             if (nres[ind] == nall[ind] - 1) {
00709                 results[ind] = cpl_realloc(results[ind],
00710                                         (nall[ind]+INITALLOC)*sizeof(float));
00711                 nall[ind] += INITALLOC;
00712             }
00713             results[ind][nres[ind]] = dm3;
00714             nres[ind] += 1;
00715 
00716             /* Add this into the global solution too */
00717 
00718             if (nresall == nallocall) {
00719                 resall = cpl_realloc(resall,(nallocall+INITALLOC)*sizeof(float));
00720                 nallocall += INITALLOC;
00721             }
00722             resall[nresall++] = dm3;
00723         }
00724 
00725         /* Get rid of the table subset */
00726 
00727         freetable(cl);
00728     }
00729 
00730     /* What is the global zero point ? */
00731 
00732     if (nresall != 0) {
00733         (void)vircam_medmad(resall,NULL,(long)nresall,&medall,&mad);
00734         cut = max(3.0*1.48*mad,0.1);
00735         lcut = medall - cut;
00736         hcut = medall + cut;
00737         (void)vircam_meansigcut(resall,NULL,(long)nresall,lcut,hcut,
00738                                 &medall,&sig);
00739     }
00740 
00741     /* Ok, what is the mean zeropoint for each cell. Do all of this stuff
00742        even if nresall == 0 so that we at least have a table with all
00743        zeros at the end of this */
00744 
00745     ngood = 0;
00746     for (i = 0; i < nbx*nby; i++) {
00747         if (nres[i] > 0) {
00748             (void)vircam_medmad(results[i],NULL,(long)nres[i],&med,&mad);
00749             cut = max(3.0*1.48*mad,0.3);
00750             lcut = med - cut;
00751             hcut = med + cut;
00752             (void)vircam_meansigcut(results[i],NULL,(long)nres[i],lcut,hcut,
00753                                     &med,&sig);
00754             med -= medall;
00755             good[ngood++] = med;
00756         } else {
00757             med = -99.0;
00758         }
00759 
00760         /* Where are we in the map? */
00761 
00762         iy = i/nbx;
00763         ix = i - iy*nbx;
00764         xmin = ix*nbsize;
00765         xmax = xmin + nbsize - 1;
00766         if (ix == nbx)
00767             xmax = nx;
00768         ymin = iy*nbsize;
00769         ymax = ymin + nbsize - 1;
00770         if (iy == nby)
00771             ymax = ny;
00772 
00773         /* Write out the results into illumination table */
00774 
00775         cpl_table_set_float(*illcor,"xmin",i,xmin);
00776         cpl_table_set_float(*illcor,"xmax",i,xmax);
00777         cpl_table_set_float(*illcor,"ymin",i,ymin);
00778         cpl_table_set_float(*illcor,"ymax",i,ymax);
00779         cpl_table_set_float(*illcor,"illcor",i,med);
00780     }
00781 
00782     /* Get the RMS of the map */
00783 
00784     if (ngood > 0)
00785         vircam_medsig(good,NULL,(long)ngood,&med,illcor_rms);
00786     else
00787         *illcor_rms = 0.0;
00788     
00789     /* Delete some workspace */
00790 
00791     for (i = 0; i < nbx*nby; i++)
00792         freespace(results[i]);
00793     freespace(results);
00794     freespace(nres);
00795     freespace(nall);
00796     freespace(stdmagptr);
00797     freespace(resall);
00798     freespace(good);
00799     vircam_phot_close();
00800 
00801     /* Set out the appropriate return status */
00802 
00803     if (nresall != 0)
00804         GOOD_STATUS
00805     else 
00806         WARN_RETURN
00807 
00808 }
00809 
00810 /*---------------------------------------------------------------------------*/
00827 /*---------------------------------------------------------------------------*/
00828 
00829 static double pixsize (cpl_propertylist *plist) {
00830     double cd1_1,cd1_2,pix;
00831 
00832     if (vircam_pfits_get_cd11(plist,&cd1_1) != VIR_OK ||
00833         vircam_pfits_get_cd12(plist,&cd1_2) != VIR_OK) {
00834         pix = NOMPIXSIZE;
00835     } else {
00836         pix = sqrt(cd1_1*cd1_1 + cd1_2*cd1_2);
00837     }
00838     return(pix);
00839 }
00840     
00841 /*---------------------------------------------------------------------------*/
00864 /*---------------------------------------------------------------------------*/
00865 
00866 static int vircam_phot_open(cpl_table *phottab, char *filt) {
00867     const char *fctid = "vircam_phot_open";
00868     int ns,null,nerr;
00869     cpl_table *subset;
00870     const char *req_cols[5] = {"filter","extinction","offset","columns",
00871                                "coleq"};
00872 
00873     /* Initialise a few things */
00874 
00875     p.coloureq = NULL;
00876     p.columns = NULL;
00877     p.nmags = 0;
00878     p.ncolumns = 0;
00879     p.offset = 0.0;
00880 
00881     /* Check the table and make sure it has all the required columns */
00882 
00883     nerr = 0;
00884     for (ns = 0; ns < 5; ns++) {
00885         if (! cpl_table_has_column(phottab,req_cols[ns])) {
00886             cpl_msg_error(fctid,"Photometry table missing column %s",
00887                           req_cols[ns]);
00888             nerr++;
00889         }
00890     }
00891     if (nerr > 0)
00892         return(VIR_FATAL);
00893 
00894     /* Search the table and find the rows that matches the filter */
00895 
00896     ns = cpl_table_and_selected_string(phottab,"filter",CPL_EQUAL_TO,filt);
00897     if (ns <= 0) {
00898         cpl_msg_error(fctid,"Unable to match photometry table to filter %s",
00899                       filt);
00900         return(VIR_FATAL);
00901     } else if (ns > 1) {
00902         cpl_msg_error(fctid,"More than one row matches filter %s",filt);
00903     }
00904 
00905     /* Read the information from the selected row */
00906 
00907     subset = cpl_table_extract_selected(phottab);
00908     p.filt = (char *)cpl_table_get_string(subset,"filter",0);
00909     p.extinct = cpl_table_get_float(subset,"extinction",0,&null);
00910     p.offset = cpl_table_get_float(subset,"offset",0,&null);
00911     if (extract_columns(subset) != VIR_OK) {
00912         freetable(subset);
00913         return(VIR_FATAL);
00914     }
00915     if (extract_coleq(subset) != VIR_OK) {
00916         freetable(subset);
00917         return(VIR_FATAL);
00918     }
00919     freetable(subset);
00920 
00921     /* Get out of here */
00922 
00923     return(VIR_OK);
00924 }
00925     
00926 
00927 /*---------------------------------------------------------------------------*/
00941 /*---------------------------------------------------------------------------*/
00942 
00943 static void vircam_phot_close(void) {
00944     int j;
00945 
00946     for (j = 0; j < p.ncolumns; j++)
00947         freespace((p.columns)[j]);
00948     freespace(p.columns);
00949     freespace(p.coloureq);
00950 }
00951 
00952 /*---------------------------------------------------------------------------*/
00969 /*---------------------------------------------------------------------------*/
00970 
00971 static int extract_columns(cpl_table *tab) {
00972     int nv,i,j;
00973     char *v,*w;
00974 
00975     /* Get the relevant value from the table */
00976 
00977     v = cpl_strdup(cpl_table_get_string(tab,"columns",0));
00978 
00979     /* Count the number of commas in the string to see how many 
00980        columns there are */
00981 
00982     nv = 1;
00983     j = strlen(v);
00984     for (i = 0; i < j; i++)
00985         if (v[i] == ',')
00986             nv++;
00987     p.ncolumns = nv;
00988 
00989     /* Now parse the string into the column names */
00990 
00991     p.columns = cpl_malloc(nv*sizeof(char *));
00992     for (i = 0; i < nv; i++) {
00993         if (i == 0) 
00994             w = strtok(v,",");
00995         else
00996             w = strtok(NULL,",");
00997         (p.columns)[i] = cpl_strdup(w);
00998     }
00999     freespace(v);
01000     return(VIR_OK);
01001 }
01002 
01003 /*---------------------------------------------------------------------------*/
01020 /*---------------------------------------------------------------------------*/
01021 
01022 static int extract_coleq(cpl_table *tab) {
01023     int nv,i,j;
01024     char *v,*w;
01025 
01026     /* Get the relevant value from the table */
01027 
01028     v = cpl_strdup(cpl_table_get_string(tab,"coleq",0));
01029 
01030     /* Count the number of commas in the string to see how many 
01031        columns there are */
01032 
01033     nv = 1;
01034     j = strlen(v);
01035     for (i = 0; i < j; i++)
01036         if (v[i] == ',')
01037             nv++;
01038     p.nmags = nv;
01039 
01040     /* Now parse the string into the colour equation values */
01041 
01042     p.coloureq = cpl_malloc(nv*sizeof(float));
01043     for (i = 0; i < nv; i++) {
01044         if (i == 0) 
01045             w = strtok(v,",");
01046         else
01047             w = strtok(NULL,",");
01048         (p.coloureq)[i] = (float)atof(w);
01049     }
01050     freespace(v);
01051     return(VIR_OK);
01052 }
01053 
01056 /*
01057 
01058 $Log: vircam_photcal.c,v $
01059 Revision 1.29  2007/10/25 17:34:01  jim
01060 Modified to remove lint warnings
01061 
01062 Revision 1.28  2007/10/19 06:55:06  jim
01063 Modifications made to use new method for directing the recipes to the
01064 standard catalogues using the sof
01065 
01066 Revision 1.27  2007/05/15 08:52:01  jim
01067 Fixed little bug in the clipping for the final magnitude zeropoint
01068 
01069 Revision 1.26  2007/05/02 09:12:02  jim
01070 Added extinction to DRS
01071 
01072 Revision 1.25  2007/03/29 12:19:39  jim
01073 Little changes to improve documentation
01074 
01075 Revision 1.24  2007/03/06 11:56:56  jim
01076 Removed some QC parameters from the catalogues
01077 
01078 Revision 1.23  2007/03/01 12:42:42  jim
01079 Modified slightly after code checking
01080 
01081 Revision 1.22  2007/02/25 06:34:20  jim
01082 Plugged memory leak
01083 
01084 Revision 1.21  2007/01/08 19:11:34  jim
01085 Fixed incorrect FITS key comments
01086 
01087 Revision 1.20  2006/12/19 13:30:34  jim
01088 Initialise the output
01089 
01090 Revision 1.19  2006/12/04 21:07:47  jim
01091 Null value in illumination correction is changed to -99.0
01092 
01093 Revision 1.18  2006/12/01 14:10:06  jim
01094 trivial change to docs
01095 
01096 Revision 1.17  2006/11/28 22:10:22  jim
01097 Added illcor_rms to calling sequence of vircam_illum
01098 
01099 Revision 1.16  2006/11/28 20:53:08  jim
01100 Added vircam_illum
01101 
01102 Revision 1.15  2006/11/27 12:03:12  jim
01103 changed calls from cpl_propertylist_append to cpl_propertylist_update
01104 
01105 Revision 1.14  2006/11/10 10:13:58  jim
01106 Fixed error in docs
01107 
01108 Revision 1.13  2006/10/02 13:47:33  jim
01109 Added missing .h file to include list
01110 
01111 Revision 1.12  2006/07/04 09:19:05  jim
01112 replaced all sprintf statements with snprintf
01113 
01114 Revision 1.11  2006/07/03 09:33:18  jim
01115 Fixed a few things to keep the compiler happy
01116 
01117 Revision 1.10  2006/06/13 14:09:09  jim
01118 Better explanation of photcal tables might be wrong
01119 
01120 Revision 1.9  2006/06/12 11:30:55  jim
01121 Removed zeropoint column from photcal table
01122 
01123 Revision 1.8  2006/06/09 11:26:26  jim
01124 Small changes to keep lint happy
01125 
01126 Revision 1.7  2006/06/06 13:07:14  jim
01127 Modified some DRS keyword names
01128 
01129 Revision 1.6  2006/05/31 14:23:32  jim
01130 Fixed error message reset call
01131 
01132 Revision 1.5  2006/05/31 11:40:09  jim
01133 Added more QC and DRS parameters. Also added calculation of limiting
01134 magnitudes. Tidied up some more docs
01135 
01136 Revision 1.4  2006/05/30 14:27:54  jim
01137 Added illcor parameter to call for photcal
01138 
01139 Revision 1.3  2006/05/26 15:05:09  jim
01140 Fixed lots of little bugs
01141 
01142 Revision 1.2  2006/05/18 09:48:28  jim
01143 Added docs
01144 
01145 Revision 1.1  2006/05/17 12:05:30  jim
01146 new file
01147 
01148 
01149 */

Generated on Wed Apr 10 04:01:56 2013 for VIRCAM Pipeline by  doxygen 1.5.1