imcore_radii.c

00001 /* $Id: imcore_radii.c,v 1.7 2010/09/09 12:09:57 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:09:57 $
00024  * $Revision: 1.7 $
00025  * $Name: vcam-1_3_2 $
00026  */
00027 
00028 #include <stdio.h>
00029 #include <math.h>
00030 
00031 #include "imcore.h"
00032 #include "imcore_radii.h"
00033 #include "floatmath.h"
00034 #include "util.h"
00035 #include "ap.h"
00036 
00037 static float fraction (float x, float y, float r_out);
00038 
00041 /*---------------------------------------------------------------------------*/
00074 /*---------------------------------------------------------------------------*/
00075 
00076 extern float imcore_exprad(float thresh, float peak, float areal0, 
00077                            float rcores[], int naper) {
00078     float pk,r_t,rad;
00079 
00080     /* Work out the radius... */
00081 
00082     pk = MAX(1.5*thresh,peak);
00083     r_t = sqrtf(areal0/CPL_MATH_PI);
00084     rad = 5.0*r_t/logf(pk/thresh);
00085     rad = MAX(r_t,MIN(5.0*r_t,MIN(rad,rcores[naper-1])));
00086     return(rad);
00087 }
00088     
00089 /*---------------------------------------------------------------------------*/
00120 /*---------------------------------------------------------------------------*/
00121 
00122 extern float imcore_kronrad(float areal0, float rcores[], float cflux[], 
00123                             int naper) {
00124     int i,imax;
00125     float r_t,rad,wt,sum;
00126 
00127     /* Work out the radius... */
00128 
00129     r_t = sqrtf(areal0/CPL_MATH_PI);
00130     rad = 0.5*rcores[0]*cflux[0];
00131     sum = cflux[0];
00132     imax = MIN(naper,7);
00133     for (i = 1; i < imax; i++) {
00134         wt = MAX(0.0,cflux[i]-cflux[i-1]);
00135         rad += 0.5*(rcores[i] + rcores[i-1])*wt;
00136         sum += wt;
00137     }
00138     rad /= sum;
00139     rad = MAX(r_t,MIN(5.0*r_t,MIN(2.0*rad,rcores[naper-1])));    
00140     return(rad);
00141 }
00142 
00143 /*---------------------------------------------------------------------------*/
00174 /*---------------------------------------------------------------------------*/
00175 
00176 extern float imcore_petrad (float areal0, float rcores[], float cflux[], 
00177                             int naper) {
00178     int j;
00179     float eta,r_t,etaold,r1,r2,r3,r4,r5,r_petr;
00180 
00181     /* Work out petrosian radius */
00182 
00183     r_t = sqrtf(areal0/CPL_MATH_PI);
00184     eta = 1.0;
00185     etaold = eta;
00186     j = 1;
00187     while (eta > 0.2 && j < naper) {
00188         etaold = eta;
00189         r1 = rcores[j]*rcores[j]/(rcores[j-1]*rcores[j-1]) - 1.0;
00190         r2 = cflux[j]/cflux[j-1] - 1.0;
00191         eta = r2/r1;
00192         j++;
00193     }
00194     if (j == naper) {
00195         r_petr = rcores[naper-1];
00196     } else {
00197         r1 = rcores[j]*rcores[j];
00198         r2 = rcores[j-1]*rcores[j-1];
00199         r3 = rcores[j-2]*rcores[j-2];
00200         r4 = (etaold - 0.2)/(etaold - eta);
00201         r5 = (0.2 - eta)/(etaold - eta);
00202         r_petr = r4*sqrt(0.5*(r1 + r2)) + r5*sqrt(0.5*(r2 + r3));
00203     }
00204     r_petr = MAX(r_t,MIN(5.0*r_t,MIN(2.0*r_petr,rcores[naper-1])));
00205     return(r_petr);
00206 }
00207 
00208 /*---------------------------------------------------------------------------*/
00248 /*---------------------------------------------------------------------------*/
00249 
00250 void imcore_flux(ap_t *ap, float parm[IMNUM][NPAR], int nbit, float apers[], 
00251                  float fluxes[], int nr, float rcores[], float rfluxes[]) {
00252     float *map,t,xj,yj,sumiso,sumcf,delr;
00253     unsigned char *mflag,mf;
00254     long nx,ny;
00255     int xmin,xmax,ymin,ymax,ix1,ix2,iy1,iy2,i,j,kk,n;
00256 
00257     /* Set up some local variables */
00258  
00259     map = ap->indata;
00260     mflag = ap->mflag;
00261     nx = ap->lsiz;
00262     ny = ap->csiz;
00263 
00264     /* Section for nbit == 1 */
00265 
00266     if (nbit == 1) {
00267 
00268         /* Generate image-blend outer boundaries */
00269 
00270         xmin = parm[0][1] - apers[0] - 0.5;
00271         xmax = parm[0][1] + apers[0] + 0.5;
00272         ymin = parm[0][2] - apers[0] - 0.5;
00273         ymax = parm[0][2] + apers[0] + 0.5;
00274         ix1 = MAX(0,(int)xmin-1);
00275         ix2 = MIN(nx-1,(int)xmax);
00276         iy1 = MAX(0,(int)ymin-1);
00277         iy2 = MIN(ny-1,(int)ymax);
00278 
00279         /* Now go through pixel region and add up the contributions inside
00280            the aperture */
00281 
00282         fluxes[0] = 0.0;
00283         for(j = iy1; j <= iy2; j++) {
00284             kk = j*nx;
00285             for(i = ix1; i <= ix2; i++) {
00286                 mf = mflag[kk+i];
00287                 if (mf == MF_CLEANPIX || mf == MF_OBJPIX || 
00288                     mf == MF_SATURATED) {
00289                     t = map[kk+i];   
00290                     xj = (float)i - parm[0][1] + 1.0;
00291                     yj = (float)j - parm[0][2] + 1.0;
00292                     fluxes[0] += fraction(xj,yj,apers[0])*t;
00293                 } 
00294             }
00295         }
00296         if (fluxes[0] <= 0) 
00297             fluxes[0] = parm[0][0];
00298         
00299     /* Section for blended images */
00300     
00301     } else {
00302     
00303         /* Interpolate circular aperture fluxes */
00304     
00305         sumiso = 0.0;
00306         sumcf = 0.0;
00307         for (j = 0; j < nbit; j++) {
00308             sumiso += parm[j][0];
00309             n = 1;
00310             while (rcores[n] < apers[j] && n < nr-1)
00311                 n++;
00312             delr = (rcores[n] - apers[j])/(rcores[n] - rcores[n-1]);
00313             fluxes[j] = rfluxes[j*nr+n]*(1.0 - delr) + rfluxes[j*nr+n-1]*delr;
00314             sumcf += fluxes[j];
00315         }
00316 
00317         /* Constrain the result so that the ratios are the same as for the
00318            isophotal fluxes */
00319 
00320         for (j = 0; j < nbit; j++) {
00321             fluxes[j] = sumcf*parm[j][0]/MAX(1.0,sumiso);
00322             if (fluxes[j] < 0.0)
00323                 fluxes[j] = parm[j][0];
00324         }
00325     }
00326 }
00327 
00330 /* returns fraction of pixel bounded by 0 -  r_out
00331  * x,y coordinates relative to centre
00332  * Uses linear approximation ok if pixel located >>1 away from centre */
00333 
00334 static float fraction (float x, float y, float r_out) {
00335     float r,t,x_a,x_b,frac,tanao2,cosa,tanp2a,sqrt2o2;
00336 
00337     r = sqrtf(x*x + y*y);
00338     sqrt2o2 = 0.5*CPL_MATH_SQRT2;
00339 
00340     /* is it worth bothering? */
00341 
00342     if(r > r_out+sqrt2o2) 
00343         return(0.0);
00344 
00345     /* is it trivially all in? */
00346 
00347     if(r < r_out-sqrt2o2) 
00348         return(1.0);
00349 
00350     /* bugger - have to do some work then ... ok first ...
00351      * use 8-fold symmetry to convert to 0-45 degree range */
00352 
00353     x = fabsf(x);
00354     y = fabsf(y);
00355     if(y > x) {
00356         t = x;
00357         x = y;
00358         y = t;
00359     }
00360 
00361     /* If the angles are too close to cardinal points, then fudge something */
00362 
00363     if (x > 0.0 && y > 0.0) {
00364         tanao2 = 0.5*y/x;
00365         tanp2a = x/y;
00366         cosa = x/sqrt(x*x + y*y);
00367     } else {
00368         tanao2 = 0.00005;
00369         tanp2a = 10000.0;
00370         cosa = 1.0;
00371     }
00372 
00373     /* only outer radius - compute linear intersections top and bot of pixel */
00374 
00375     x_a = x - tanao2 + (r_out - r)/cosa;
00376     if(x_a < x+0.5) {
00377 
00378         /* intersects */
00379 
00380         x_b = x + tanao2 + (r_out - r)/cosa;
00381 
00382         /* three cases to consider */
00383 
00384         if(x_a < x-0.5)
00385             frac = 0.5*MAX(0.0,x_b-(x-0.5))*MAX(0.0,x_b-(x-0.5))*tanp2a;
00386         else {
00387             if(x_b > x+0.5)
00388                 frac = 1.0 - 0.5*(x+0.5-x_a)*(x+0.5-x_a)*tanp2a;
00389             else
00390                 frac = 0.5-(x-x_a)+0.5*(x_b-x_a);
00391         }
00392     } else  /* missed entirely */
00393         frac = 1.0;
00394 
00395     return(frac);
00396 }
00397 
00398 /*
00399 
00400 $Log: imcore_radii.c,v $
00401 Revision 1.7  2010/09/09 12:09:57  jim
00402 Added docs
00403 
00404 Revision 1.6  2009/09/09 09:42:25  jim
00405 modified to use CPL defined macros for constants
00406 
00407 Revision 1.5  2009/02/20 10:49:58  jim
00408 Removed superfluous declarations
00409 
00410 Revision 1.4  2009/01/30 08:27:02  jim
00411 New version of imcore_flux and updated radius estimates
00412 
00413 Revision 1.3  2009/01/23 12:24:33  jim
00414 Fixed bugs in pixel flagging
00415 
00416 Revision 1.2  2008/10/24 10:59:17  jim
00417 Modified flux calculation so that inverse trig functions get sensible input
00418 
00419 Revision 1.1  2005/09/13 13:25:30  jim
00420 Initial entry after modifications to make cpl compliant
00421 
00422 
00423 */

Generated on 5 Mar 2013 for VIRCAM Pipeline by  doxygen 1.6.1