vircam_photcal.c

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

Generated on 15 Mar 2012 for VIRCAM Pipeline by  doxygen 1.6.1