vircam_photcal.c

00001 /* $Id: vircam_photcal.c,v 1.36 2010/09/09 12:11:09 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: 2010/09/09 12:11:09 $
00024  * $Revision: 1.36 $
00025  * $Name: v1-1-0 $
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 static void write_hdr_1(cpl_propertylist *p, int nresim, float med3, float sig3,
00066                         float lim3, float med5, float sig5, float lim5,
00067                         float extinct, float skybrt, int ncut, int doqc);
00068 
00071 /*---------------------------------------------------------------------------*/
00155 /*---------------------------------------------------------------------------*/
00156 
00157 extern int vircam_photcal(vir_fits **images, cpl_table **mstds, 
00158                           cpl_propertylist **pl, int nimages, char *filt, 
00159                           cpl_table *phottab, int *status) {
00160     float **stdmagptr,*resall3,*resall5,cdfudge,saturate,apcor3,apcor5,exptime;
00161     float airmass,*catcore3,*catcore5,*resim3,*resim5,cf,fluxmag3,fluxmag5;
00162     float refmag,extinct,dm3,dm5,med3,mad,cut,lcut,hcut,med5,sig3,sig5;
00163     float rcore,lim3,lim5,dx,skylev,skbrt;
00164     int nresall,nalloc_resall,i,j,k,ncat,nresim,ncut;
00165     char junk[SZBUF];
00166     const char *fctid = "vircam_photcal";
00167     vir_fits *im;
00168     cpl_propertylist *ehu_im,*ehu_cat;
00169     cpl_table *stds,*cl;
00170 
00171     /* Inherited status */
00172 
00173     if (*status != VIR_OK)
00174         return(*status);
00175 
00176     /* Check for nonsense errors */
00177 
00178     if (nimages <= 0) {
00179         cpl_msg_error(fctid,"No images included in photometric calibration");
00180         FATAL_ERROR
00181     }
00182 
00183     /* Set up the structure that will give us the colour equations for
00184        this filter later on */
00185 
00186     if (vircam_phot_open(phottab,filt) != VIR_OK)
00187         FATAL_ERROR
00188 
00189     /* Get a workspace to hold the pointers to the magnitude columns */
00190 
00191     stdmagptr = cpl_malloc(p.ncolumns*sizeof(float *));
00192 
00193     /* Get some workspace to hold all the zeropoints for all the images
00194        in the input list. This is an initial allocation and more can be
00195        made available later if needed */
00196 
00197     resall3 = cpl_malloc(INITALLOC*sizeof(float));
00198     resall5 = cpl_malloc(INITALLOC*sizeof(float));
00199     nresall = 0;
00200     nalloc_resall = INITALLOC;
00201 
00202     /* Loop for the input images and catalogues. Create some shorthand
00203        variables and work out what the zeropoint fudge factor will be 
00204        based on the sampling of the current frame and the nominal sampling
00205        of a VIRCAM image */
00206 
00207     for (i = 0; i < nimages; i++) {
00208         im = images[i];
00209         ehu_im = vircam_fits_get_ehu(im);
00210         stds = mstds[i];
00211         ehu_cat = pl[i];
00212         cdfudge = 2.5*log10((double)pixsize(ehu_im)/NOMPIXSIZE);
00213 
00214         /* Are there any? */
00215 
00216         ncat = cpl_table_get_nrow(stds);
00217         if (ncat <= 3) {
00218             cpl_msg_warning(fctid,"Too few standards available");
00219             cpl_error_reset();
00220             write_hdr_1(ehu_im,ncat,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0,1);
00221             write_hdr_1(ehu_cat,ncat,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0,0);
00222             continue;
00223         }
00224 
00225         /* Now for the input catalogues. Start by getting some useful info
00226            from the header */
00227 
00228         saturate = cpl_propertylist_get_float(ehu_cat,"ESO QC SATURATION");
00229         apcor3 = cpl_propertylist_get_float(ehu_cat,"APCOR3");
00230         apcor5 = cpl_propertylist_get_float(ehu_cat,"APCOR5");
00231         rcore = cpl_propertylist_get_float(ehu_cat,"ESO DRS RCORE");
00232         skylev = cpl_propertylist_get_float(ehu_cat,"ESO DRS SKYLEVEL");
00233         dx = pixsize(ehu_im);
00234         (void)vircam_pfits_get_exptime(ehu_cat,&exptime);
00235         (void)vircam_pfits_get_airmass(vircam_fits_get_phu(im),&airmass);
00236         if (cpl_error_get_code() != CPL_ERROR_NONE) {
00237             cpl_msg_error(fctid,"Unable to get header info");
00238             cpl_error_reset();
00239             continue;
00240         }
00241 
00242         /* Get objects that are not saturated and aren't too elliptical */
00243 
00244         cpl_table_select_all(stds);  
00245         cpl_table_and_selected_float(stds,"Ellipticity",CPL_LESS_THAN,0.5);
00246         cpl_table_and_selected_float(stds,"Peak_height",CPL_LESS_THAN,
00247                                      saturate);
00248         if (cpl_error_get_code() != CPL_ERROR_NONE) {
00249             cpl_msg_error(fctid,"Unable select data from matched stds tab");
00250             cpl_error_reset();
00251             continue;
00252         }
00253 
00254         /* Get all objects where the magnitude errors are less than 0.1 */
00255 
00256         for (j = 0; j < p.ncolumns; j++) {
00257             (void)snprintf(junk,SZBUF,"%ssig",(p.columns)[j]);
00258             cpl_table_and_selected_float(stds,junk,CPL_LESS_THAN,0.1);
00259         }
00260 
00261         /* Now extract all those that have passed the test. If none are left
00262            then issue a warning and move on to the next one */
00263 
00264         cl = cpl_table_extract_selected(stds);
00265         ncat = cpl_table_get_nrow(cl);
00266         if (ncat <= 3) {
00267             cpl_msg_warning(fctid,"Too few good standards available");
00268             cpl_table_delete(cl);
00269             cpl_error_reset();
00270             write_hdr_1(ehu_im,ncat,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0,1);
00271             write_hdr_1(ehu_cat,ncat,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0,0);
00272             continue;
00273         }
00274 
00275         /* Dereference some of the columns */
00276 
00277         catcore3 = cpl_table_get_data_float(cl,"Aper_flux_3");
00278         catcore5 = cpl_table_get_data_float(cl,"Aper_flux_5");
00279         for (j = 0; j < p.ncolumns; j++) 
00280             stdmagptr[j] = cpl_table_get_data_float(cl,(p.columns)[j]);
00281 
00282         /* Get some workspace for the results arrays for this image */
00283 
00284         resim3 = cpl_malloc(ncat*sizeof(float));
00285         resim5 = cpl_malloc(ncat*sizeof(float));
00286         nresim = 0;
00287 
00288         /* Loop for all the standards */
00289 
00290         extinct = p.extinct*(airmass - 1.0);
00291         for (j = 0; j < ncat; j++) {
00292             
00293             /* Do core magnitude calculation */
00294 
00295             cf = catcore3[j]/exptime;
00296             if (cf < 1.0)
00297                 cf = 1.0;
00298             fluxmag3 = 2.5*log10((double)cf) + apcor3;
00299             cf = catcore5[j]/exptime;
00300             if (cf < 1.0)
00301                 cf = 1.0;
00302             fluxmag5 = 2.5*log10((double)cf) + apcor5;
00303 
00304             /* Work out a reference magnitude */
00305 
00306             refmag = p.offset;
00307             for (k = 0; k < p.nmags; k++) 
00308                 refmag += ((p.coloureq)[k]*stdmagptr[k][j]);
00309 
00310             /* Work out zero points and store them away for later */
00311 
00312             dm3 = refmag + fluxmag3 + extinct;
00313             dm5 = refmag + fluxmag5 + extinct;
00314             resim3[nresim] = dm3 + cdfudge;
00315             resim5[nresim++] = dm5 + cdfudge;
00316             resall3[nresall] = dm3 + cdfudge;
00317             resall5[nresall++] = dm5 + cdfudge;
00318             if (nresall == nalloc_resall) {
00319                 nalloc_resall += INITALLOC;
00320                 resall3 = cpl_realloc(resall3,nalloc_resall*sizeof(float));
00321                 resall5 = cpl_realloc(resall5,nalloc_resall*sizeof(float));
00322             }
00323         }
00324 
00325         /* Ok, what is the mean zeropoint for this image? */
00326 
00327         (void)vircam_medmad(resim3,NULL,(long)nresim,&med3,&mad);
00328         cut = max(3.0*1.48*mad,0.1);
00329         lcut = med3 - cut;
00330         hcut = med3 + cut;
00331         (void)vircam_meansigcut(resim3,NULL,nresim,lcut,hcut,&med3,&sig3);
00332         ncut = 0;
00333         for (j = 0; j < nresim; j++)
00334             if (resim3[j] < lcut || resim3[j] > hcut)
00335                 ncut++;
00336         (void)vircam_medmad(resim5,NULL,(long)nresim,&med5,&mad);
00337         cut = max(3.0*1.48*mad,0.1);
00338         lcut = med5 - cut;
00339         hcut = med5 + cut;
00340         (void)vircam_meansigcut(resim5,NULL,nresim,lcut,hcut,&med5,&sig5);
00341 
00342         /* Delete some workspace */
00343 
00344         freespace(resim3);
00345         freespace(resim5);
00346         freetable(cl);
00347 
00348         /* Calculate the limiting magnitudes */
00349 
00350         lim3 = med3 - 2.5*log10((5.0*sig3*rcore*sqrt(CPL_MATH_PI))/exptime) -
00351             apcor3 - extinct;
00352         lim5 = med5 - 2.5*log10((5.0*sig5*rcore*sqrt(CPL_MATH_PI))/exptime) -
00353             apcor5 - extinct;
00354 
00355         /* Calculate sky brightness */
00356 
00357         skbrt = lim3 - 2.5*log10(skylev/(exptime*dx*dx)) - extinct;
00358 
00359         /* Write out header stuff. First for the image and then for the
00360            catalogue. NB: QC is not allowed to appear in the catalogue */
00361 
00362         write_hdr_1(ehu_im,nresim,med3,sig3,lim3,med5,sig5,lim5,p.extinct,
00363                     skbrt,ncut,1);
00364         write_hdr_1(ehu_cat,nresim,med3,sig3,lim3,med5,sig5,lim5,p.extinct,
00365                     skbrt,ncut,0);
00366     }
00367 
00368     /* Ok, what is the mean zeropoint for all images? */
00369 
00370     if (nresall > 0) {
00371         (void)vircam_medmad(resall3,NULL,(long)nresall,&med3,&mad);
00372         cut = max(3.0*1.48*mad,0.1);
00373         lcut = med3 - cut;
00374         hcut = med3 + cut;
00375         (void)vircam_meansigcut(resall3,NULL,nresall,lcut,hcut,&med3,&sig3);
00376         (void)vircam_medmad(resall5,NULL,(long)nresall,&med5,&mad);
00377         cut = max(3.0*1.48*mad,0.1);
00378         lcut = med5 - cut;
00379         hcut = med5 + cut;
00380         (void)vircam_meansigcut(resall5,NULL,nresall,lcut,hcut,&med5,&sig5);
00381     } else {
00382         med3 = 0.0;
00383         sig3 = 0.0;
00384         med5 = 0.0;
00385         sig5 = 0.0;
00386     }
00387 
00388     /* Delete some workspace */
00389 
00390     freespace(resall3);
00391     freespace(resall5);
00392     freespace(stdmagptr);
00393     vircam_phot_close();
00394 
00395     /* Write these results to the header of the images and the catalogues. 
00396        First the images */
00397 
00398     for (i = 0; i < nimages; i++) {
00399         im = images[i];
00400         ehu_im = vircam_fits_get_ehu(im);
00401         stds = mstds[i];
00402         ehu_cat = pl[i];
00403         cpl_propertylist_update_int(ehu_im,"ESO DRS MAGNZPTALL",nresall);
00404         cpl_propertylist_set_comment(ehu_im,"ESO DRS MAGNZPTALL",
00405                                      "number of stars in all magzpt calc");
00406         cpl_propertylist_update_float(ehu_im,"ESO DRS ZPALL1",med3);
00407         cpl_propertylist_set_comment(ehu_im,"ESO DRS ZPALL1",
00408                                      "[mag] zeropoint 1*rcore all group images");
00409         cpl_propertylist_update_float(ehu_im,"ESO DRS ZPSIGALL1",sig3);
00410         cpl_propertylist_set_comment(ehu_im,"ESO DRS ZPSIGALL1",
00411                                      "[mag] zeropoint sigma 1*rcore all group images");
00412         cpl_propertylist_update_float(ehu_im,"ESO DRS ZPALL2",med5);
00413         cpl_propertylist_set_comment(ehu_im,"ESO DRS ZPALL2",
00414                                      "[mag] zeropoint 2*rcore all group images");
00415         cpl_propertylist_update_float(ehu_im,"ESO DRS ZPSIGALL2",sig5);
00416         cpl_propertylist_set_comment(ehu_im,"ESO DRS ZPSIGALL2",
00417                                      "[mag] zeropoint sigma 2*rcore all group images");
00418 
00419         /* Now the catalogues */
00420 
00421         cpl_propertylist_update_int(ehu_cat,"ESO DRS MAGNZPTALL",nresall);
00422         cpl_propertylist_set_comment(ehu_cat,"ESO DRS MAGNZPTALL",
00423                                      "number of stars in all magzpt calc");
00424         cpl_propertylist_update_float(ehu_cat,"ESO DRS ZPALL1",med3);
00425         cpl_propertylist_set_comment(ehu_cat,"ESO DRS ZPALL1",
00426                                      "[mag] zeropoint 1*rcore all group images");
00427         cpl_propertylist_update_float(ehu_cat,"ESO DRS ZPSIGALL1",sig3);
00428         cpl_propertylist_set_comment(ehu_cat,"ESO DRS ZPSIGALL1",
00429                                      "[mag] zeropoint sigma 1*rcore all group images");
00430         cpl_propertylist_update_float(ehu_cat,"ESO DRS ZPALL2",med5);
00431         cpl_propertylist_set_comment(ehu_cat,"ESO DRS ZPALL2",
00432                                      "[mag] zeropoint 2*rcore all group images");
00433         cpl_propertylist_update_float(ehu_cat,"ESO DRS ZPSIGALL2",sig5);
00434         cpl_propertylist_set_comment(ehu_cat,"ESO DRS ZPSIGALL2",
00435                                      "[mag] zeropoint sigma 2*rcore all group images");
00436     }
00437 
00438     /* Get out of here */
00439 
00440     GOOD_STATUS
00441 
00442 }
00443 
00444 /*---------------------------------------------------------------------------*/
00495 /*---------------------------------------------------------------------------*/
00496 
00497 extern int vircam_illum(vir_fits **images, cpl_table **mstds, 
00498                         cpl_propertylist **pl, int nimages, char *filt,
00499                         cpl_table *phottab, int nbsize, cpl_table **illcor, 
00500                         float *illcor_rms,int *status) {
00501     const char *fctid = "vircam_illum";
00502     char junk[SZBUF];
00503     float **stdmagptr,fracx,fracy,**results,cdfudge,saturate,apcor3,exptime;
00504     float airmass,*catcore3,*xx,*yy,extinct,cf,fluxmag3,refmag,dm3,med,mad;
00505     float xmin,xmax,ymin,ymax,*resall,medall,lcut,hcut,sig,cut,*good;
00506     int nx,ny,ifracx,ifracy,nbsizx,nbsizy,nbx,nby,*nres,*nall,i,j,ncat,k;
00507     int ix,iy,ind,nresall,nallocall,ngood;
00508     vir_fits *im;
00509     cpl_propertylist *ehu_im,*ehu_cat;
00510     cpl_table *stds,*cl;
00511 
00512     /* Inherited status */
00513 
00514     *illcor = NULL;
00515     *illcor_rms = 0.0;
00516     if (*status != VIR_OK)
00517         return(*status);
00518 
00519     /* Check for nonsense errors */
00520 
00521     if (nimages <= 0) {
00522         cpl_msg_error(fctid,"No images included in photometric calibration");
00523         FATAL_ERROR
00524     }
00525 
00526     /* Set up the structure that will give us the colour equations for
00527        this filter later on */
00528 
00529     if (vircam_phot_open(phottab,filt) != VIR_OK)
00530         FATAL_ERROR
00531 
00532     /* Get a workspace to hold the pointers to the magnitude columns */
00533 
00534     stdmagptr = cpl_malloc(p.ncolumns*sizeof(float *));
00535 
00536     /* Check to see if nbsize is close to exact divisor */
00537 
00538     nx = cpl_image_get_size_x(vircam_fits_get_image(images[0]));
00539     ny = cpl_image_get_size_y(vircam_fits_get_image(images[0]));
00540     fracx = ((float)nx)/((float)nbsize);
00541     fracy = ((float)ny)/((float)nbsize);
00542     ifracx = (int)(fracx + 0.1);
00543     ifracy = (int)(fracy + 0.1);
00544     nbsizx = nx/ifracx;
00545     nbsizy = ny/ifracy;
00546     nbsize = max(vircam_nint(0.9*nbsize),min(nbsize,min(nbsizx,nbsizy)));
00547     nbsize = min(nx,min(ny,nbsize)); /* trap for small maps */
00548 
00549     /* Divide the map into partitions */
00550 
00551     nbx = nx/nbsize;
00552     nby = ny/nbsize;
00553 
00554     /* Get some workspace to hold all the zeropoints for all the images
00555        in the input list. This is an initial allocation and more can be
00556        made available later if needed */
00557 
00558     results = cpl_malloc(nbx*nby*sizeof(float *));
00559     good = cpl_malloc(nbx*nby*sizeof(float));
00560     nres = cpl_calloc(nbx*nby,sizeof(int));
00561     nall = cpl_malloc(nbx*nby*sizeof(int));
00562     for (i = 0; i < nbx*nby; i++) {
00563         results[i] = cpl_malloc(INITALLOC*sizeof(float));
00564         nall[i] = INITALLOC;
00565     }
00566     resall = cpl_malloc(INITALLOC*sizeof(float));
00567     nresall = 0;
00568     nallocall = INITALLOC;
00569 
00570     /* Set up the output illumination correction table */
00571 
00572     *illcor = vircam_illcor_newtab(nbx*nby);
00573     
00574     /* Loop for the input images and catalogues. Create some shorthand
00575        variables and work out what the zeropoint fudge factor will be 
00576        based on the sampling of the current frame and the nominal sampling
00577        of a VIRCAM image */
00578 
00579     for (i = 0; i < nimages; i++) {
00580         im = images[i];
00581         ehu_im = vircam_fits_get_ehu(im);
00582         stds = mstds[i];
00583         if (stds == NULL)
00584             continue;
00585         ehu_cat = pl[i];
00586         cdfudge = 2.5*log10((double)pixsize(ehu_im)/NOMPIXSIZE);
00587 
00588         /* Now for the input catalogues. Start by getting some useful info
00589            from the header */
00590 
00591         saturate = cpl_propertylist_get_float(ehu_cat,"ESO QC SATURATION");
00592         apcor3 = cpl_propertylist_get_float(ehu_cat,"APCOR3");
00593         (void)vircam_pfits_get_exptime(vircam_fits_get_phu(im),&exptime);
00594         (void)vircam_pfits_get_airmass(vircam_fits_get_phu(im),&airmass);
00595         if (cpl_error_get_code() != CPL_ERROR_NONE) {
00596             cpl_msg_error(fctid,"Unable to get header info for %s",
00597                           vircam_fits_get_fullname(im));
00598             cpl_error_reset();
00599             continue;
00600         }
00601 
00602         /* Get objects that are not saturated and aren't too elliptical */
00603 
00604         cpl_table_select_all(stds);  
00605         cpl_table_and_selected_float(stds,"Ellipticity",CPL_LESS_THAN,0.5);
00606         cpl_table_and_selected_float(stds,"Peak_height",CPL_LESS_THAN,
00607                                      saturate);
00608         if (cpl_error_get_code() != CPL_ERROR_NONE) {
00609             cpl_msg_error(fctid,"Unable select data from matched stds tab %s",
00610                           vircam_fits_get_fullname(im));
00611             cpl_error_reset();
00612             continue;
00613         }
00614 
00615         /* Get all objects where the magnitude errors are less than 0.1 */
00616 
00617         for (j = 0; j < p.ncolumns; j++) {
00618             (void)snprintf(junk,SZBUF,"%ssig",(p.columns)[j]);
00619             cpl_table_and_selected_float(stds,junk,CPL_LESS_THAN,0.1);
00620         }
00621 
00622         /* Now extract all those that have passed the test. If none are left
00623            then issue a warning and move on to the next one */
00624 
00625         cl = cpl_table_extract_selected(stds);
00626         ncat = cpl_table_get_nrow(cl);
00627         if (ncat == 0) {
00628             cpl_msg_error(fctid,"No good standards available for %s",
00629                          vircam_fits_get_fullname(im));
00630             cpl_table_delete(cl);
00631             cpl_error_reset();
00632             continue;
00633         }
00634 
00635         /* Dereference some of the columns */
00636 
00637         catcore3 = cpl_table_get_data_float(cl,"Aper_flux_3");
00638         xx = cpl_table_get_data_float(cl,"X_coordinate");
00639         yy = cpl_table_get_data_float(cl,"Y_coordinate");
00640         for (j = 0; j < p.ncolumns; j++) 
00641             stdmagptr[j] = cpl_table_get_data_float(cl,(p.columns)[j]);
00642 
00643         /* Loop for all the standards */
00644 
00645         extinct = p.extinct*(airmass - 1.0);
00646         for (j = 0; j < ncat; j++) {
00647             
00648             /* Do core magnitude calculation */
00649 
00650             cf = catcore3[j]/exptime;
00651             if (cf < 1.0)
00652                 cf = 1.0;
00653             fluxmag3 = 2.5*log10((double)cf) + apcor3;
00654 
00655             /* Work out a reference magnitude */
00656 
00657             refmag = p.offset;
00658             for (k = 0; k < p.nmags; k++) 
00659                 refmag += ((p.coloureq)[k]*stdmagptr[k][j]);
00660 
00661             /* Work out zero point */
00662 
00663             dm3 = refmag + fluxmag3 + extinct + cdfudge;
00664 
00665             /* What cell does this belong to? */
00666 
00667             ix = (int)(xx[j]/(float)nbsize);
00668             iy = (int)(yy[j]/(float)nbsize);
00669             ind = iy*nbx + ix;
00670             if (nres[ind] == nall[ind] - 1) {
00671                 results[ind] = cpl_realloc(results[ind],
00672                                         (nall[ind]+INITALLOC)*sizeof(float));
00673                 nall[ind] += INITALLOC;
00674             }
00675             results[ind][nres[ind]] = dm3;
00676             nres[ind] += 1;
00677 
00678             /* Add this into the global solution too */
00679 
00680             if (nresall == nallocall) {
00681                 resall = cpl_realloc(resall,(nallocall+INITALLOC)*sizeof(float));
00682                 nallocall += INITALLOC;
00683             }
00684             resall[nresall++] = dm3;
00685         }
00686 
00687         /* Get rid of the table subset */
00688 
00689         freetable(cl);
00690     }
00691 
00692     /* What is the global zero point ? */
00693 
00694     if (nresall != 0) {
00695         (void)vircam_medmad(resall,NULL,(long)nresall,&medall,&mad);
00696         cut = max(3.0*1.48*mad,0.1);
00697         lcut = medall - cut;
00698         hcut = medall + cut;
00699         (void)vircam_meansigcut(resall,NULL,(long)nresall,lcut,hcut,
00700                                 &medall,&sig);
00701     }
00702 
00703     /* Ok, what is the mean zeropoint for each cell. Do all of this stuff
00704        even if nresall == 0 so that we at least have a table with all
00705        zeros at the end of this */
00706 
00707     ngood = 0;
00708     for (i = 0; i < nbx*nby; i++) {
00709         if (nres[i] > 0) {
00710             (void)vircam_medmad(results[i],NULL,(long)nres[i],&med,&mad);
00711             cut = max(3.0*1.48*mad,0.3);
00712             lcut = med - cut;
00713             hcut = med + cut;
00714             (void)vircam_meansigcut(results[i],NULL,(long)nres[i],lcut,hcut,
00715                                     &med,&sig);
00716             med -= medall;
00717             good[ngood++] = med;
00718         } else {
00719             med = -99.0;
00720         }
00721 
00722         /* Where are we in the map? */
00723 
00724         iy = i/nbx;
00725         ix = i - iy*nbx;
00726         xmin = ix*nbsize;
00727         xmax = xmin + nbsize - 1;
00728         if (ix == nbx)
00729             xmax = nx;
00730         ymin = iy*nbsize;
00731         ymax = ymin + nbsize - 1;
00732         if (iy == nby)
00733             ymax = ny;
00734 
00735         /* Write out the results into illumination table */
00736 
00737         cpl_table_set_float(*illcor,"xmin",i,xmin);
00738         cpl_table_set_float(*illcor,"xmax",i,xmax);
00739         cpl_table_set_float(*illcor,"ymin",i,ymin);
00740         cpl_table_set_float(*illcor,"ymax",i,ymax);
00741         cpl_table_set_float(*illcor,"illcor",i,med);
00742     }
00743 
00744     /* Get the RMS of the map */
00745 
00746     if (ngood > 0)
00747         vircam_medsig(good,NULL,(long)ngood,&med,illcor_rms);
00748     else
00749         *illcor_rms = 0.0;
00750     
00751     /* Delete some workspace */
00752 
00753     for (i = 0; i < nbx*nby; i++)
00754         freespace(results[i]);
00755     freespace(results);
00756     freespace(nres);
00757     freespace(nall);
00758     freespace(stdmagptr);
00759     freespace(resall);
00760     freespace(good);
00761     vircam_phot_close();
00762 
00763     /* Set out the appropriate return status */
00764 
00765     if (nresall != 0)
00766         GOOD_STATUS
00767     else 
00768         WARN_RETURN
00769 
00770 }
00771 
00772 /*---------------------------------------------------------------------------*/
00789 /*---------------------------------------------------------------------------*/
00790 
00791 static double pixsize (cpl_propertylist *plist) {
00792     double cd1_1,cd1_2,pix;
00793 
00794     if (vircam_pfits_get_cd11(plist,&cd1_1) != VIR_OK ||
00795         vircam_pfits_get_cd12(plist,&cd1_2) != VIR_OK) {
00796         pix = NOMPIXSIZE;
00797     } else {
00798         pix = 3600.0*sqrt(cd1_1*cd1_1 + cd1_2*cd1_2);
00799     }
00800     return(pix);
00801 }
00802     
00803 /*---------------------------------------------------------------------------*/
00826 /*---------------------------------------------------------------------------*/
00827 
00828 static int vircam_phot_open(cpl_table *phottab, char *filt) {
00829     const char *fctid = "vircam_phot_open";
00830     int ns,null,nerr;
00831     cpl_table *subset;
00832     const char *req_cols[5] = {"filter","extinction","offset","columns",
00833                                "coleq"};
00834 
00835     /* Initialise a few things */
00836 
00837     p.coloureq = NULL;
00838     p.columns = NULL;
00839     p.nmags = 0;
00840     p.ncolumns = 0;
00841     p.offset = 0.0;
00842 
00843     /* Check the table and make sure it has all the required columns */
00844 
00845     nerr = 0;
00846     for (ns = 0; ns < 5; ns++) {
00847         if (! cpl_table_has_column(phottab,req_cols[ns])) {
00848             cpl_msg_error(fctid,"Photometry table missing column %s",
00849                           req_cols[ns]);
00850             nerr++;
00851         }
00852     }
00853     if (nerr > 0)
00854         return(VIR_FATAL);
00855 
00856     /* Search the table and find the rows that matches the filter */
00857 
00858     ns = cpl_table_and_selected_string(phottab,"filter",CPL_EQUAL_TO,filt);
00859     if (ns <= 0) {
00860         cpl_msg_error(fctid,"Unable to match photometry table to filter %s",
00861                       filt);
00862         return(VIR_FATAL);
00863     } else if (ns > 1) {
00864         cpl_msg_error(fctid,"More than one row matches filter %s",filt);
00865     }
00866 
00867     /* Read the information from the selected row */
00868 
00869     subset = cpl_table_extract_selected(phottab);
00870     p.filt = (char *)cpl_table_get_string(subset,"filter",0);
00871     p.extinct = cpl_table_get_float(subset,"extinction",0,&null);
00872     p.offset = cpl_table_get_float(subset,"offset",0,&null);
00873     if (extract_columns(subset) != VIR_OK) {
00874         freetable(subset);
00875         return(VIR_FATAL);
00876     }
00877     if (extract_coleq(subset) != VIR_OK) {
00878         freetable(subset);
00879         return(VIR_FATAL);
00880     }
00881     freetable(subset);
00882 
00883     /* Get out of here */
00884 
00885     return(VIR_OK);
00886 }
00887     
00888 
00889 /*---------------------------------------------------------------------------*/
00903 /*---------------------------------------------------------------------------*/
00904 
00905 static void vircam_phot_close(void) {
00906     int j;
00907 
00908     for (j = 0; j < p.ncolumns; j++)
00909         freespace((p.columns)[j]);
00910     freespace(p.columns);
00911     freespace(p.coloureq);
00912 }
00913 
00914 /*---------------------------------------------------------------------------*/
00931 /*---------------------------------------------------------------------------*/
00932 
00933 static int extract_columns(cpl_table *tab) {
00934     int nv,i,j;
00935     char *v,*w;
00936 
00937     /* Get the relevant value from the table */
00938 
00939     v = cpl_strdup(cpl_table_get_string(tab,"columns",0));
00940 
00941     /* Count the number of commas in the string to see how many 
00942        columns there are */
00943 
00944     nv = 1;
00945     j = strlen(v);
00946     for (i = 0; i < j; i++)
00947         if (v[i] == ',')
00948             nv++;
00949     p.ncolumns = nv;
00950 
00951     /* Now parse the string into the column names */
00952 
00953     p.columns = cpl_malloc(nv*sizeof(char *));
00954     for (i = 0; i < nv; i++) {
00955         if (i == 0) 
00956             w = strtok(v,",");
00957         else
00958             w = strtok(NULL,",");
00959         (p.columns)[i] = cpl_strdup(w);
00960     }
00961     freespace(v);
00962     return(VIR_OK);
00963 }
00964 
00965 /*---------------------------------------------------------------------------*/
00982 /*---------------------------------------------------------------------------*/
00983 
00984 static int extract_coleq(cpl_table *tab) {
00985     int nv,i,j;
00986     char *v,*w;
00987 
00988     /* Get the relevant value from the table */
00989 
00990     v = cpl_strdup(cpl_table_get_string(tab,"coleq",0));
00991 
00992     /* Count the number of commas in the string to see how many 
00993        columns there are */
00994 
00995     nv = 1;
00996     j = strlen(v);
00997     for (i = 0; i < j; i++)
00998         if (v[i] == ',')
00999             nv++;
01000     p.nmags = nv;
01001 
01002     /* Now parse the string into the colour equation values */
01003 
01004     p.coloureq = cpl_malloc(nv*sizeof(float));
01005     for (i = 0; i < nv; i++) {
01006         if (i == 0) 
01007             w = strtok(v,",");
01008         else
01009             w = strtok(NULL,",");
01010         (p.coloureq)[i] = (float)atof(w);
01011     }
01012     freespace(v);
01013     return(VIR_OK);
01014 }
01015 
01016 static void write_hdr_1(cpl_propertylist *pl, int nresim, float med3, 
01017                         float sig3, float lim3, float med5, float sig5, 
01018                         float lim5, float extinct, float skybrt, int ncut,
01019                         int doqc) {
01020 
01021     /* Write these results to the header of the image and the catalogue.
01022        First the QC headers for the image. These are not allowed to be
01023        copied into the catalogue headers...*/
01024 
01025     if (doqc) {
01026         cpl_propertylist_update_float(pl,"ESO QC MAGZPT",med3);
01027         cpl_propertylist_set_comment(pl,"ESO QC MAGZPT",
01028                                      "[mag] photometric zeropoint");
01029         cpl_propertylist_update_float(pl,"ESO QC MAGZERR",sig3);
01030         cpl_propertylist_set_comment(pl,"ESO QC MAGZERR",
01031                                      "[mag] photometric zeropoint error");
01032         cpl_propertylist_update_int(pl,"ESO QC MAGNZPT",nresim);
01033         cpl_propertylist_set_comment(pl,"ESO QC MAGNZPT",
01034                                      "number of stars in magzpt calc");
01035         cpl_propertylist_update_int(pl,"ESO QC MAGNCUT",ncut);
01036         cpl_propertylist_set_comment(pl,"ESO QC MAGNCUT",
01037                                      "number of stars cut from magzpt calc");
01038         cpl_propertylist_update_float(pl,"ESO QC LIMITING_MAG",lim3);
01039         cpl_propertylist_set_comment(pl,"ESO QC LIMITING_MAG",
01040                                      "[mag] 5 sigma limiting mag.");
01041         cpl_propertylist_update_float(pl,"ESO QC SKYBRIGHT",skybrt);
01042         cpl_propertylist_set_comment(pl,"ESO QC SKYBRIGHT",
01043                                      "[mag/arcsec**2] sky brightness");
01044     }
01045 
01046     /* Now the DRS headers for the image */
01047 
01048     cpl_propertylist_update_int(pl,"ESO DRS MAGNZPTIM",nresim);
01049     cpl_propertylist_set_comment(pl,"ESO DRS MAGNZPTIM",
01050                                  "number of stars in image magzpt calc");
01051 
01052     cpl_propertylist_update_float(pl,"ESO DRS ZPIM1",med3);
01053     cpl_propertylist_set_comment(pl,"ESO DRS ZPIM1",
01054                                  "[mag] zeropoint 1*rcore this image only");
01055     cpl_propertylist_update_float(pl,"ESO DRS ZPSIGIM1",sig3);
01056     cpl_propertylist_set_comment(pl,"ESO DRS ZPSIGIM1",
01057                                  "[mag] zeropoint sigma 1*rcore this image only");
01058     cpl_propertylist_update_float(pl,"ESO DRS LIMIT_MAG1",lim3);
01059     cpl_propertylist_set_comment(pl,"ESO DRS LIMIT_MAG1",
01060                                  "[mag] 5 sigma limiting mag 1*rcore.");
01061     cpl_propertylist_update_float(pl,"ESO DRS ZPIM2",med5);
01062     cpl_propertylist_set_comment(pl,"ESO DRS ZPIM2",
01063                                  "[mag] zeropoint 2*rcore this image only");
01064     cpl_propertylist_update_float(pl,"ESO DRS ZPSIGIM2",sig5);
01065     cpl_propertylist_set_comment(pl,"ESO DRS ZPSIGIM2",
01066                                  "[mag] zeropoint sigma 2*rcore this image only");
01067     cpl_propertylist_update_float(pl,"ESO DRS LIMIT_MAG2",lim5);
01068     cpl_propertylist_set_comment(pl,"ESO DRS LIMIT_MAG2",
01069                                  "[mag] 5 sigma limiting mag core5.");
01070     cpl_propertylist_update_float(pl,"ESO DRS EXTINCT",extinct);
01071     cpl_propertylist_set_comment(pl,"ESO DRS EXTINCT",
01072                                  "[mag] Assumed extinction.");
01073     cpl_propertylist_update_float(pl,"ESO DRS SKYBRIGHT",skybrt);
01074     cpl_propertylist_set_comment(pl,"ESO DRS SKYBRIGHT",
01075                                  "[mag/arcsec**2] sky brightness");
01076 }
01077 
01080 /*
01081 
01082 $Log: vircam_photcal.c,v $
01083 Revision 1.36  2010/09/09 12:11:09  jim
01084 Fixed problems with docs that make doxygen barf
01085 
01086 Revision 1.35  2010/06/07 12:42:40  jim
01087 Modifications to get rid of compiler gripes
01088 
01089 Revision 1.34  2009/09/21 11:58:15  jim
01090 Calculates sky brightness now and writes to QC header
01091 
01092 Revision 1.33  2009/09/09 09:47:55  jim
01093 uses CPL defined macros for constants
01094 
01095 Revision 1.32  2008/11/26 18:21:46  jim
01096 Fixed bug in pixsize routine where there was a missing factor of 3600.0
01097 
01098 Revision 1.31  2008/11/25 06:21:56  jim
01099 nothing
01100 
01101 Revision 1.30  2008/11/24 21:31:23  jim
01102 Fixed to deal with situations with catalogues with no rows
01103 
01104 Revision 1.29  2007/10/25 17:34:01  jim
01105 Modified to remove lint warnings
01106 
01107 Revision 1.28  2007/10/19 06:55:06  jim
01108 Modifications made to use new method for directing the recipes to the
01109 standard catalogues using the sof
01110 
01111 Revision 1.27  2007/05/15 08:52:01  jim
01112 Fixed little bug in the clipping for the final magnitude zeropoint
01113 
01114 Revision 1.26  2007/05/02 09:12:02  jim
01115 Added extinction to DRS
01116 
01117 Revision 1.25  2007/03/29 12:19:39  jim
01118 Little changes to improve documentation
01119 
01120 Revision 1.24  2007/03/06 11:56:56  jim
01121 Removed some QC parameters from the catalogues
01122 
01123 Revision 1.23  2007/03/01 12:42:42  jim
01124 Modified slightly after code checking
01125 
01126 Revision 1.22  2007/02/25 06:34:20  jim
01127 Plugged memory leak
01128 
01129 Revision 1.21  2007/01/08 19:11:34  jim
01130 Fixed incorrect FITS key comments
01131 
01132 Revision 1.20  2006/12/19 13:30:34  jim
01133 Initialise the output
01134 
01135 Revision 1.19  2006/12/04 21:07:47  jim
01136 Null value in illumination correction is changed to -99.0
01137 
01138 Revision 1.18  2006/12/01 14:10:06  jim
01139 trivial change to docs
01140 
01141 Revision 1.17  2006/11/28 22:10:22  jim
01142 Added illcor_rms to calling sequence of vircam_illum
01143 
01144 Revision 1.16  2006/11/28 20:53:08  jim
01145 Added vircam_illum
01146 
01147 Revision 1.15  2006/11/27 12:03:12  jim
01148 changed calls from cpl_propertylist_append to cpl_propertylist_update
01149 
01150 Revision 1.14  2006/11/10 10:13:58  jim
01151 Fixed error in docs
01152 
01153 Revision 1.13  2006/10/02 13:47:33  jim
01154 Added missing .h file to include list
01155 
01156 Revision 1.12  2006/07/04 09:19:05  jim
01157 replaced all sprintf statements with snprintf
01158 
01159 Revision 1.11  2006/07/03 09:33:18  jim
01160 Fixed a few things to keep the compiler happy
01161 
01162 Revision 1.10  2006/06/13 14:09:09  jim
01163 Better explanation of photcal tables might be wrong
01164 
01165 Revision 1.9  2006/06/12 11:30:55  jim
01166 Removed zeropoint column from photcal table
01167 
01168 Revision 1.8  2006/06/09 11:26:26  jim
01169 Small changes to keep lint happy
01170 
01171 Revision 1.7  2006/06/06 13:07:14  jim
01172 Modified some DRS keyword names
01173 
01174 Revision 1.6  2006/05/31 14:23:32  jim
01175 Fixed error message reset call
01176 
01177 Revision 1.5  2006/05/31 11:40:09  jim
01178 Added more QC and DRS parameters. Also added calculation of limiting
01179 magnitudes. Tidied up some more docs
01180 
01181 Revision 1.4  2006/05/30 14:27:54  jim
01182 Added illcor parameter to call for photcal
01183 
01184 Revision 1.3  2006/05/26 15:05:09  jim
01185 Fixed lots of little bugs
01186 
01187 Revision 1.2  2006/05/18 09:48:28  jim
01188 Added docs
01189 
01190 Revision 1.1  2006/05/17 12:05:30  jim
01191 new file
01192 
01193 
01194 */

Generated on 7 Feb 2011 for VIRCAM Pipeline by  doxygen 1.6.1