VIRCAM Pipeline 2.3.15
imcore_radii.c
1/* $Id: imcore_radii.c,v 1.2 2015/08/07 13:06:54 jim Exp $
2 *
3 * This file is part of the CASU Pipeline utilities
4 * Copyright (C) 2015 European Southern Observatory
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21/*
22 * $Author: jim $
23 * $Date: 2015/08/07 13:06:54 $
24 * $Revision: 1.2 $
25 * $Name: $
26 */
27
28#include <stdio.h>
29#include <math.h>
30
31#include "imcore.h"
32#include "imcore_radii.h"
33#include "floatmath.h"
34#include "util.h"
35#include "ap.h"
36
37static float fraction (float x, float y, float r_out);
38
41/*---------------------------------------------------------------------------*/
74/*---------------------------------------------------------------------------*/
75
76extern float imcore_halflight(float rcores[], float cflux[], float halflight,
77 float peak, int naper) {
78 float delr,halfrad;
79 int i,gotone;
80
81 /* Work out the half-light value from either isophotal flux or the
82 flux at Rcore. The find out roughly where the curve of growth
83 exceeds this */
84
85 gotone = 0;
86 for (i = 0; i < naper; i++) {
87 if (cflux[i] > halflight) {
88 gotone = 1;
89 break;
90 }
91 }
92 if (! gotone)
93 i = naper - 1;
94
95 /* Now work out what the radius of half light is */
96
97 if (i == 0) {
98 delr = (cflux[i] - halflight)/MAX(1.0,cflux[i]-peak);
99 halfrad = rcores[0]*(1.0 - delr) + delr*sqrt(1.0/CPL_MATH_PI);
100 } else {
101 delr = (cflux[i] - halflight)/MAX(1.0,(cflux[i] - cflux[i-1]));
102 halfrad = rcores[i-1]*delr + rcores[i]*(1.0-delr);
103 }
104 return(halfrad);
105}
106
107/*---------------------------------------------------------------------------*/
140/*---------------------------------------------------------------------------*/
141
142extern float imcore_exprad(float thresh, float peak, float areal0,
143 float rcores[], int naper) {
144 float pk,r_t,rad;
145
146 /* Work out the radius... */
147
148 pk = MAX(1.5*thresh,peak);
149 r_t = sqrtf(areal0/CPL_MATH_PI);
150 rad = 5.0*r_t/logf(pk/thresh);
151 rad = MAX(r_t,MIN(5.0*r_t,MIN(rad,rcores[naper-1])));
152 return(rad);
153}
154
155/*---------------------------------------------------------------------------*/
186/*---------------------------------------------------------------------------*/
187
188extern float imcore_kronrad(float areal0, float rcores[], float cflux[],
189 int naper) {
190 int i,imax;
191 float r_t,rad,wt,sum;
192
193 /* Work out the radius... */
194
195 r_t = sqrtf(areal0/CPL_MATH_PI);
196 rad = 0.5*rcores[0]*cflux[0];
197 sum = cflux[0];
198 imax = MIN(naper,7);
199 for (i = 1; i < imax; i++) {
200 wt = MAX(0.0,cflux[i]-cflux[i-1]);
201 rad += 0.5*(rcores[i] + rcores[i-1])*wt;
202 sum += wt;
203 }
204 rad /= sum;
205 rad = MAX(r_t,MIN(5.0*r_t,MIN(2.0*rad,rcores[naper-1])));
206 return(rad);
207}
208
209/*---------------------------------------------------------------------------*/
240/*---------------------------------------------------------------------------*/
241
242extern float imcore_petrad (float areal0, float rcores[], float cflux[],
243 int naper) {
244 int j;
245 float eta,r_t,etaold,r1,r2,r3,r4,r5,r_petr;
246
247 /* Work out petrosian radius */
248
249 r_t = sqrtf(areal0/CPL_MATH_PI);
250 eta = 1.0;
251 etaold = eta;
252 j = 1;
253 while (eta > 0.2 && j < naper) {
254 etaold = eta;
255 r1 = rcores[j]*rcores[j]/(rcores[j-1]*rcores[j-1]) - 1.0;
256 r2 = cflux[j]/cflux[j-1] - 1.0;
257 eta = r2/r1;
258 j++;
259 }
260 if (j == naper) {
261 r_petr = rcores[naper-1];
262 } else {
263 r1 = rcores[j]*rcores[j];
264 r2 = rcores[j-1]*rcores[j-1];
265 r3 = rcores[j-2]*rcores[j-2];
266 r4 = (etaold - 0.2)/(etaold - eta);
267 r5 = (0.2 - eta)/(etaold - eta);
268 r_petr = r4*sqrt(0.5*(r1 + r2)) + r5*sqrt(0.5*(r2 + r3));
269 }
270 r_petr = MAX(r_t,MIN(5.0*r_t,MIN(2.0*r_petr,rcores[naper-1])));
271 return(r_petr);
272}
273
274/*---------------------------------------------------------------------------*/
314/*---------------------------------------------------------------------------*/
315
316void imcore_flux(ap_t *ap, float parm[IMNUM][NPAR], int nbit, float apers[],
317 float fluxes[], int nr, float rcores[], float rfluxes[]) {
318 float *map,t,xj,yj,sumiso,sumcf,delr;
319 unsigned char *mflag,mf;
320 long nx,ny;
321 int xmin,xmax,ymin,ymax,ix1,ix2,iy1,iy2,i,j,kk,n;
322
323 /* Set up some local variables */
324
325 map = ap->indata;
326 mflag = ap->mflag;
327 nx = ap->lsiz;
328 ny = ap->csiz;
329
330 /* Section for nbit == 1 */
331
332 if (nbit == 1) {
333
334 /* Generate image-blend outer boundaries */
335
336 xmin = parm[0][1] - apers[0] - 0.5;
337 xmax = parm[0][1] + apers[0] + 0.5;
338 ymin = parm[0][2] - apers[0] - 0.5;
339 ymax = parm[0][2] + apers[0] + 0.5;
340 ix1 = MAX(0,(int)xmin-1);
341 ix2 = MIN(nx-1,(int)xmax);
342 iy1 = MAX(0,(int)ymin-1);
343 iy2 = MIN(ny-1,(int)ymax);
344
345 /* Now go through pixel region and add up the contributions inside
346 the aperture */
347
348 fluxes[0] = 0.0;
349 for(j = iy1; j <= iy2; j++) {
350 kk = j*nx;
351 for(i = ix1; i <= ix2; i++) {
352 mf = mflag[kk+i];
353 if (mf == MF_CLEANPIX || mf == MF_OBJPIX ||
354 mf == MF_SATURATED) {
355 t = map[kk+i];
356 xj = (float)i - parm[0][1] + 1.0;
357 yj = (float)j - parm[0][2] + 1.0;
358 fluxes[0] += fraction(xj,yj,apers[0])*t;
359 }
360 }
361 }
362 if (fluxes[0] <= 0)
363 fluxes[0] = parm[0][0];
364
365 /* Section for blended images */
366
367 } else {
368
369 /* Interpolate circular aperture fluxes */
370
371 sumiso = 0.0;
372 sumcf = 0.0;
373 for (j = 0; j < nbit; j++) {
374 sumiso += parm[j][0];
375 n = 1;
376 while (rcores[n] < apers[j] && n < nr-1)
377 n++;
378 delr = (rcores[n] - apers[j])/(rcores[n] - rcores[n-1]);
379 fluxes[j] = rfluxes[j*nr+n]*(1.0 - delr) + rfluxes[j*nr+n-1]*delr;
380 sumcf += fluxes[j];
381 }
382
383 /* Constrain the result so that the ratios are the same as for the
384 isophotal fluxes */
385
386 for (j = 0; j < nbit; j++) {
387 fluxes[j] = sumcf*parm[j][0]/MAX(1.0,sumiso);
388 if (fluxes[j] < 0.0)
389 fluxes[j] = parm[j][0];
390 }
391 }
392}
393
396/* returns fraction of pixel bounded by 0 - r_out
397 * x,y coordinates relative to centre
398 * Uses linear approximation ok if pixel located >>1 away from centre */
399
400static float fraction (float x, float y, float r_out) {
401 float r,t,x_a,x_b,frac,tanao2,cosa,tanp2a,sqrt2o2;
402
403 r = sqrtf(x*x + y*y);
404 sqrt2o2 = 0.5*CPL_MATH_SQRT2;
405
406 /* is it worth bothering? */
407
408 if(r > r_out+sqrt2o2)
409 return(0.0);
410
411 /* is it trivially all in? */
412
413 if(r < r_out-sqrt2o2)
414 return(1.0);
415
416 /* bugger - have to do some work then ... ok first ...
417 * use 8-fold symmetry to convert to 0-45 degree range */
418
419 x = fabsf(x);
420 y = fabsf(y);
421 if(y > x) {
422 t = x;
423 x = y;
424 y = t;
425 }
426
427 /* If the angles are too close to cardinal points, then fudge something */
428
429 if (x > 0.0 && y > 0.0) {
430 tanao2 = 0.5*y/x;
431 tanp2a = x/y;
432 cosa = x/sqrt(x*x + y*y);
433 } else {
434 tanao2 = 0.00005;
435 tanp2a = 10000.0;
436 cosa = 1.0;
437 }
438
439 /* only outer radius - compute linear intersections top and bot of pixel */
440
441 x_a = x - tanao2 + (r_out - r)/cosa;
442 if(x_a < x+0.5) {
443
444 /* intersects */
445
446 x_b = x + tanao2 + (r_out - r)/cosa;
447
448 /* three cases to consider */
449
450 if(x_a < x-0.5)
451 frac = 0.5*MAX(0.0,x_b-(x-0.5))*MAX(0.0,x_b-(x-0.5))*tanp2a;
452 else {
453 if(x_b > x+0.5)
454 frac = 1.0 - 0.5*(x+0.5-x_a)*(x+0.5-x_a)*tanp2a;
455 else
456 frac = 0.5-(x-x_a)+0.5*(x_b-x_a);
457 }
458 } else /* missed entirely */
459 frac = 1.0;
460
461 return(frac);
462}
463
464/*
465
466$Log: imcore_radii.c,v $
467Revision 1.2 2015/08/07 13:06:54 jim
468Fixed copyright to ESO
469
470Revision 1.1.1.1 2015/06/12 10:44:32 jim
471Initial import
472
473Revision 1.3 2015/03/12 09:16:51 jim
474Modified to remove some compiler moans
475
476Revision 1.2 2014/04/09 09:09:51 jim
477Detabbed
478
479Revision 1.1.1.1 2013/08/27 12:07:48 jim
480Imported
481
482
483*/
float imcore_exprad(float thresh, float peak, float areal0, float rcores[], int naper)
Work out the exponential radius for an object.
Definition: imcore_radii.c:142
void imcore_flux(ap_t *ap, float parm[IMNUM][NPAR], int nbit, float apers[], float fluxes[], int nr, float rcores[], float rfluxes[])
Work out the fluxes for special radii.
Definition: imcore_radii.c:316
float imcore_kronrad(float areal0, float rcores[], float cflux[], int naper)
Work out the Kron radius for an object.
Definition: imcore_radii.c:188
float imcore_petrad(float areal0, float rcores[], float cflux[], int naper)
Work out the Petrosian.
Definition: imcore_radii.c:242
float imcore_halflight(float rcores[], float cflux[], float halflight, float peak, int naper)
Work out the half-light radius for an object.
Definition: imcore_radii.c:76