Commit 3b348a94 authored by Emmanuel Bertin's avatar Emmanuel Bertin
Browse files

Changed trunk directory name

parents
/*
globals.h
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: SExtractor
*
* Author: E.BERTIN (IAP)
*
* Contents: global declarations.
*
* Last modify: 14/07/2006
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
#include "types.h"
/*----------------------- miscellaneous variables ---------------------------*/
sexcatstruct thecat;
picstruct thefield1,thefield2, thewfield1,thewfield2;
objstruct flagobj;
obj2struct flagobj2;
extern obj2struct outobj2;
float ctg[37], stg[37];
char gstr[MAXCHAR];
/*------------------------------- functions ---------------------------------*/
extern void allocparcelout(void),
analyse(picstruct *, picstruct *, int, objliststruct *),
blankit(char *, int),
endcat(char *error),
reendcat(void),
closecheck(void),
copydata(picstruct *, int, int),
endfield(picstruct *),
endobject(picstruct *, picstruct *, picstruct *, picstruct *,
int, objliststruct *),
examineiso(picstruct *, picstruct *, objstruct *,
pliststruct *),
flagcleancrowded(int, objliststruct *),
freeparcelout(void),
getnnw(void),
initcat(void),
reinitcat(picstruct *),
initglob(void),
makeit(void),
mergeobject(objstruct *, objstruct *),
neurinit(void),
neurclose(void),
neurresp(double *, double *),
preanalyse(int, objliststruct *, int),
readcatparams(char *),
readdata(picstruct *, PIXTYPE *, int),
readidata(picstruct *, FLAGTYPE *, int),
readimagehead(picstruct *),
readprefs(char *, char **, char **, int),
scanimage(picstruct *, picstruct *, picstruct **, int,
picstruct *, picstruct *),
sexcircle(PIXTYPE *bmp, int, int, double, double, double,
PIXTYPE),
sexdraw(PIXTYPE *bmp, int, int, double, double, PIXTYPE),
sexellips(PIXTYPE *bmp, int, int, double, double, double,
double, double, PIXTYPE, int),
sexmove(double, double),
updateparamflags(void),
useprefs(void),
writecat(int, objliststruct *),
write_error(char *msg1, char *msg2),
write_vo_fields(FILE *file);
extern float hmedian(float *, int);
extern int addobj(int, objliststruct *, objliststruct *),
belong(int, objliststruct *, int, objliststruct *),
gatherup(objliststruct *, objliststruct *),
parcelout(objliststruct *, objliststruct *);
extern void *loadstrip(picstruct *, picstruct *);
extern char *readfitshead(FILE *, char *, int *);
extern picstruct *inheritfield(picstruct *infield, int flags),
*newfield(char *, int , int);
/*
graph.c
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: SExtractor
*
* Author: E.BERTIN (IAP)
*
* Contents: simple graphical functions.
*
* Last modify: 13/12/2002
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <math.h>
#include <stdlib.h>
#include "define.h"
#include "globals.h"
double sexx1, sexy1;
/********************************* sexmove **********************************/
/*
Move function (related to sexdraw)..
*/
void sexmove(double x, double y)
{
sexx1 = x;
sexy1 = y;
return;
}
/********************************* sexdraw **********************************/
/*
Draw a line in a PIXTYPE bitmap.
*/
void sexdraw(PIXTYPE *bmp, int w, int h, double sexx2, double sexy2,
PIXTYPE val)
{
double dx,dy, slope;
int ix1,iy1, ix2,iy2, ix,iy;
dx = sexx2-sexx1;
dy = sexy2-sexy1;
if (fabs(dx) > fabs(dy))
{
slope = dy/dx;
ix1 = RINT(sexx1);
ix2 = RINT(sexx2);
if (ix2>ix1)
{
for (ix=ix1+1; ix<=ix2; ix++)
if (ix>=0 && ix<w)
{
iy = RINT(sexy1+(ix-sexx1)*slope);
if (iy>=0 && iy<h)
bmp[ix+w*iy] += val;
}
}
else
{
for (ix=ix1-1; ix>=ix2; ix--)
if (ix>=0 && ix<w)
{
iy = RINT(sexy1+(ix-sexx1)*slope);
if (iy>=0 && iy<h)
bmp[ix+w*iy] += val;
}
}
}
else
{
slope = dx/(dy == 0.0? 1.0:dy);
iy1 = RINT(sexy1);
iy2 = RINT(sexy2);
if (iy2>iy1)
{
for (iy=iy1+1; iy<=iy2; iy++)
if (iy>=0 && iy<h)
{
ix = RINT(sexx1+(iy-sexy1)*slope);
if (ix>=0 && ix<w)
bmp[ix+w*iy] += val;
}
}
else
for (iy=iy1-1; iy>=iy2; iy--)
{
if (iy>=0 && iy<h)
{
ix = RINT(sexx1+(iy-sexy1)*slope);
if (ix>=0 && ix<w)
bmp[ix+w*iy] += val;
}
}
}
sexx1 = sexx2;
sexy1 = sexy2;
return;
}
/******************************** sexcircle *********************************/
/*
Draw a circle in a PIXTYPE bitmap.
*/
void sexcircle(PIXTYPE *bmp, int w, int h, double x, double y, double r,
PIXTYPE val)
{
int i;
sexmove(x+r, y);
for (i=0; i<37; i++)
sexdraw(bmp,w,h, x+r*ctg[i], y+r*stg[i], val);
return;
}
/******************************** sexellips *********************************/
/*
Draw an ellips in a PIXTYPE bitmap.
*/
void sexellips(PIXTYPE *bmp, int w, int h, double x, double y, double a,
double b, double theta, PIXTYPE val, int dotflag)
{
int i;
double ct, st;
ct = cos(PI*theta/180);
st = sin(PI*theta/180);
sexmove(x+a*ct, y+a*st);
for (i=1; i<37; i++)
if (dotflag && !(i&1))
sexmove(x + a*ctg[i]*ct - b*stg[i]*st,
y + a*ctg[i]*st + b*stg[i]*ct);
else
sexdraw(bmp,w,h, x + a*ctg[i]*ct - b*stg[i]*st,
y + a*ctg[i]*st + b*stg[i]*ct, val);
return;
}
/*
growth.c
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: SExtractor
*
* Author: E.BERTIN (IAP)
*
* Contents: Make growth curves.
*
* Last modify: 15/02/2005
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "define.h"
#include "globals.h"
#include "prefs.h"
#include "growth.h"
/*------------------------------- variables ---------------------------------*/
static double *growth;
static int ngrowth;
static obj2struct *obj2 = &outobj2;
/******************************** initgrowth *********************************/
/*
Allocate memory for growth curve stuff.
*/
void initgrowth()
{
QMALLOC(growth, double, GROWTH_NSTEP);
/* Quick (and dirty) fix to allow FLUX_RADIUS support */
if (FLAG(obj2.flux_radius) && !prefs.flux_radiussize)
{
QCALLOC(obj2->flux_radius, float, 1);
}
return;
}
/******************************** endgrowth **********************************/
/*
Free memory occupied by growth curve stuff.
*/
void endgrowth()
{
free(growth);
if (FLAG(obj2.flux_radius) && !prefs.flux_radiussize)
free(obj2->flux_radius);
return;
}
/****************************** makeavergrowth *******************************/
/*
Build growth curve based on averages.
*/
void makeavergrowth(picstruct *field, picstruct *wfield, objstruct *obj)
{
float *fgrowth;
double *growtht,
dx,dx1,dy,dy2,mx,my, r2,r,rlim, d, rextlim2, raper,
offsetx,offsety,scalex,scaley,scale2, ngamma, locarea,
tv, sigtv, area, pix, var, gain, dpos,step,step2, dg,
stepdens, backnoise2, prevbinmargin, nextbinmargin;
int i,j,n, x,y, x2,y2, xmin,xmax,ymin,ymax, sx,sy, w,h,
fymin,fymax, pflag,corrflag, ipos;
LONG pos;
PIXTYPE *strip,*stript, *wstrip,*wstript,
pdbkg, wthresh;
if (wfield)
wthresh = wfield->weight_thresh;
else
wthresh = 0.0; /* To avoid gcc -Wall warnings */
/* Clear the growth-curve buffer */
memset(growth, 0, (size_t)(GROWTH_NSTEP*sizeof(double)));
mx = obj->mx;
my = obj->my;
w = field->width;
h = field->stripheight;
fymin = field->ymin;
fymax = field->ymax;
pflag = (prefs.detect_type==PHOTO)? 1:0;
corrflag = (prefs.mask_type==MASK_CORRECT);
var = backnoise2 = field->backsig*field->backsig;
gain = prefs.gain;
/* Integration radius */
rlim = GROWTH_NSIG*obj->a;
if (rlim<prefs.autoaper[0])
rlim = prefs.autoaper[0];
raper = rlim+1.5; /* margin for interpolation */
/* External radius */
rextlim2 = raper*raper;
stepdens = GROWTH_NSTEP/rlim;
/* It is useless to oversample too much! */
if (0/*stepdens>GROWTH_OVERSAMP*/)
{
ngrowth = (int)(rlim*GROWTH_OVERSAMP);
stepdens = ngrowth/rlim;
}
else
ngrowth = GROWTH_NSTEP;
step = 1/stepdens;
/* Critical distances (in pixels) from bin boundaries */
prevbinmargin = 0.75; /* > 1/sqrt(2) */
nextbinmargin = step - 0.75; /* <step - sqrt(2) */
/* For photographic data */
if (pflag)
{
ngamma = field->ngamma;
pdbkg = exp(obj->dbkg/ngamma);
}
else
{
ngamma = 0.0;
pdbkg = 0.0;
}
tv = sigtv = area = 0.0;
scaley = scalex = 1.0/GROWTH_OVERSAMP;
scale2 = scalex*scaley;
offsetx = 0.5*(scalex-1.0);
offsety = 0.5*(scaley-1.0);
xmin = (int)(mx-raper+0.499999);
xmax = (int)(mx+raper+1.499999);
ymin = (int)(my-raper+0.499999);
ymax = (int)(my+raper+1.499999);
if (xmin < 0)
{
xmin = 0;
obj->flag |= OBJ_APERT_PB;
}
if (xmax > w)
{
xmax = w;
obj->flag |= OBJ_APERT_PB;
}
if (ymin < fymin)
{
ymin = fymin;
obj->flag |= OBJ_APERT_PB;
}
if (ymax > fymax)
{
ymax = fymax;
obj->flag |= OBJ_APERT_PB;
}
strip = field->strip;
wstrip = wstript = NULL; /* To avoid gcc -Wall warnings */
if (wfield)
wstrip = wfield->strip;
for (y=ymin; y<ymax; y++)
{
stript = strip + (pos = (y%h)*w + xmin);
if (wfield)
wstript = wstrip + pos;
for (x=xmin; x<xmax; x++, stript++, wstript++)
{
dx = x - mx;
dy = y - my;
if ((r2=dx*dx+dy*dy)<rextlim2)
{
/*------ Here begin tests for pixel and/or weight overflows. Things are a */
/*------ bit intricated to have it running as fast as possible in the most */
/*------ common cases */
if ((pix=*stript)<=-BIG || (wfield && (var=*wstript)>=wthresh))
{
if (corrflag
&& (x2=(int)(2*mx+0.49999-x))>=0 && x2<w
&& (y2=(int)(2*my+0.49999-y))>=fymin && y2<fymax
&& (pix=*(strip + (pos = (y2%h)*w + x2)))>-BIG)
{
if (wfield)
{
var = *(wstrip + pos);
if (var>=wthresh)
pix = var = 0.0;
}
}
else
{
pix = 0.0;
if (wfield)
var = 0.0;
}
}
if (pflag)
pix = exp(pix/ngamma) - pdbkg;
/*------ Check if oversampling is needed (close enough to a bin boundary) */
d = fmod(r=sqrt(r2),step);
if (d<prevbinmargin || d>nextbinmargin)
{
dx += offsetx;
dy += offsety;
locarea = 0.0;
for (sy=GROWTH_OVERSAMP; sy--; dy+=scaley)
{
dx1 = dx;
dy2 = dy*dy;
for (sx=GROWTH_OVERSAMP; sx--; dx1+=scalex)
{
j = (int)(sqrt(dx1*dx1+dy2)*stepdens);
if (j<ngrowth)
{
growth[j] += scale2*pix;
locarea += scale2;
}
}
}
}
else
{
j = (int)(r*stepdens);
if (j<ngrowth)
{
growth[j] += pix;
locarea = 1.0;
}
}
area += locarea;
/*
if (pflag)
sigtv += var*locarea*pix*pix;
else
sigtv += var*locarea;
tv += locarea*pix;
if (wfield && pix>0.0 && gain>0.0)
sigtv += pix/gain*var/backnoise2;
*/
}
}
}
/*
if (pflag)
{
tv = ngamma*(tv-area*exp(obj->dbkg/ngamma));
sigtv /= ngamma*ngamma;
}
else
{
tv -= area*obj->dbkg;
if (!wfield && gain > 0.0 && tv>0.0)
sigtv += tv/gain;
}
*/
/* Integrate the growth curve */
pix = 0.0;
growtht = growth;
for (i=ngrowth; i--;)
{
*growtht += pix;
pix = *(growtht++);
}
/* Now let's remap the growth-curve to match user's choice */
if (FLAG(obj2.flux_growth))
{
n = prefs.flux_growthsize;
if (FLAG(obj2.flux_growthstep))
obj2->flux_growthstep = rlim/n;
fgrowth = obj2->flux_growth;
step2 = (double)GROWTH_NSTEP/n;
j = 1;
for (i=n; i--; j++)
{
ipos = (int)(dpos=step2*j-0.99999);
if (dpos<0.0)
*(fgrowth++) = (float)(*growth*(0.99999+dpos));
else
{
growtht = growth + ipos;
*(fgrowth++) = (float)(*growtht+(*(growtht+1)-*growtht)*(dpos-ipos));
}
}
}
if (FLAG(obj2.mag_growth))
{
n = prefs.mag_growthsize;
if (FLAG(obj2.mag_growthstep))
obj2->mag_growthstep = rlim/n;
fgrowth = obj2->mag_growth;
step2 = (double)GROWTH_NSTEP/n;
j = 1;
for (i=n; i--; j++)
{
ipos = (int)(dpos=step2*j-0.99999);
if (dpos<0.0)
pix = *growth*(0.99999+dpos);
else
{
growtht = growth + ipos;
pix = *growtht+(*(growtht+1)-*growtht)*(dpos-ipos);
}
*(fgrowth++) = pix>0.0?(prefs.mag_zeropoint-2.5*log10(pix)):99.0;
}
}
if (FLAG(obj2.flux_radius))
{
n = ngrowth-1;
for (j=0; j<prefs.nflux_frac; j++)
{
tv = prefs.flux_frac[j]*obj2->flux_auto;
growtht = growth-1;
for (i=0; i<n && *(++growtht)<tv; i++);
obj2->flux_radius[j] = step
*(i? ((dg=*growtht - *(growtht-1)) != 0.0 ?
i + (tv - *(growtht-1))/dg
: i)
: (*growth !=0.0 ?tv/(*growth) : 0.0));
}
}
/* Specific to Half-light radius used by other parameters */
if (FLAG(obj2.hl_radius))
{
n = ngrowth-1;
tv = 0.5*obj2->flux_auto;
growtht = growth-1;
for (i=0; i<n && *(++growtht)<tv; i++);
obj2->hl_radius = step*(i? ((dg=*growtht - *(growtht-1)) != 0.0 ?
i + (tv - *(growtht-1))/dg
: i)
: (*growth !=0.0 ?tv/(*growth) : 0.0));
}
return;
}
/*
growth.h
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: SExtractor
*
* Author: E.BERTIN, IAP & Leiden observatory
*
* Contents: Include file for growth.c.
*
* Last modify: 04/05/98
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
/*----------------------------- Internal constants --------------------------*/
#define GROWTH_NSTEP 64 /* number of growth curve samples */
#define GROWTH_OVERSAMP 5 /* pixel oversampling in each dimension */
#define GROWTH_NSIG 3*MARGIN_SCALE /* MAG_AUTO analysis range (number */
/* of sigma) */
/* NOTES:
One must have: GROWTH_SAMP >= 1
GROWTH_OVERSAMP >= 1
GROWTH_OVERSAMPRADIUS >= 0
GROWTH_NSIG > 0.0
*/
/*------------------------------- functions ---------------------------------*/
extern void endgrowth(void),
initgrowth(void),
makeavergrowth(picstruct *field, picstruct *wfield,
objstruct *obj);
/*
image.c
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: SExtractor
*
* Author: E.BERTIN (IAP)
*
* Contents: Function related to image manipulations.
*
* Last modify: 13/12/2002
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include "define.h"
#include "globals.h"
#include "prefs.h"
#include "image.h"
static float interpm[INTERPW*INTERPH];
/********************************* copyimage *********************************/
/*
Copy a small part of the image. Image parts which lie outside boundaries are
set to -BIG.
*/
int copyimage(picstruct *field, PIXTYPE *dest, int w,int h, int ix,int iy)
{
PIXTYPE *destt;
int i,y, xmin,xmax,ymin,ymax,w2;
/* First put the retina background to -BIG */
destt = dest;
for (i=w*h; i--;)
*(destt++) = -BIG;
/* Don't go further if out of frame!! */
if (ix<0 || ix>=field->width || iy<field->ymin || iy>=field->ymax)
return RETURN_ERROR;
/* Set the image boundaries */
w2 = w;
ymin = iy-h/2;
ymax = ymin + h;
if (ymin<field->ymin)
{
dest += (field->ymin-ymin)*w;
ymin = field->ymin;
}
if (ymax>field->ymax)
ymax = field->ymax;
xmin = ix-w/2;
xmax = xmin + w;
if (xmax>field->width)
{
w2 -= xmax-field->width;
xmax = field->width;
}
if (xmin<0)
{
dest += -xmin;
w2 -= -xmin;
xmin = 0;
}
/* Copy the right pixels to the destination */
for (y=ymin; y<ymax; y++, dest += w)
memcpy(dest, &PIX(field, xmin, y), w2*sizeof(PIXTYPE));
return RETURN_OK;
}
/********************************* addimage **********************************/
/*
Add a PSF to a part of the image (with a multiplicative factor).
Outside boundaries are taken into account.
*/
void addimage(picstruct *field, float *psf,
int w,int h, int ix,int iy, float amplitude)
{
PIXTYPE *pix;
int x,y, xmin,xmax,ymin,ymax,w2, dwpsf;
/* Set the image boundaries */
w2 = w;
ymin = iy-h/2;
ymax = ymin + h;
if (ymin<field->ymin)
{
psf += (field->ymin-ymin)*w;
ymin = field->ymin;
}
if (ymax>field->ymax)
ymax = field->ymax;
xmin = ix-w/2;
xmax = xmin + w;
if (xmax>field->width)
{
w2 -= xmax-field->width;
xmax = field->width;
}
if (xmin<0)
{
psf += -xmin;
w2 -= -xmin;
xmin = 0;
}
dwpsf = w-w2;
/* Subtract the right pixels to the destination */
for (y=ymin; y<ymax; y++, psf += dwpsf)
{
pix = &PIX(field, xmin, y);
for (x=w2; x--;)
*(pix++) += amplitude**(psf++);
}
return;
}
/***************************** copyimage_center ******************************/
/*
Copy a small part of the image and recenter it through sinc interpolation.
Image parts which lie outside boundaries are set to 0.
*/
int copyimage_center(picstruct *field, PIXTYPE *dest, int w,int h,
float x,float y)
{
PIXTYPE *s,*s0, *dt,*dt0,*dt2;
float *m,
dx,dy, ddx0,ddx,ddy,sum, fy, mval;
int i,ix,iy, idmx,idmy, mx,my, xmin,ymin,xmin2,x0,y0,y2, w2,h2,
sw,sh, idx,idy;
dx = x - (ix=(int)x);
dy = y - (iy=(int)y);
/* Initialize destination buffer to zero */
memset(dest, 0, w*h*sizeof(PIXTYPE));
/* Don't go further if out of frame!! */
if (ix<0 || ix>=field->width || iy<field->ymin || iy>=field->ymax)
return RETURN_ERROR;
/* Compute the interpolation mask */
ddx0 = -(idmx=(INTERPW-(dx>0.0?1:0))/2)-dx;
ddy = -(idmy=(INTERPH-(dy>0.0?1:0))/2)-dy;
sum = 0.0;
m = interpm;
for (my=INTERPH; my--; ddy+=1.0)
{
ddx = ddx0;
fy = INTERPF(ddy);
for (mx=INTERPW; mx--;ddx+=1.0)
sum += *(m++) = fy*INTERPF(ddx);
}
/* Normalize it */
m = interpm;
for (i=INTERPW*INTERPH; i--;)
*(m++) /= sum;
/* Do the interpolation */
m = interpm;
xmin = ix - w/2 - idmx;
ymin = iy - h/2 - idmy;
sw = field->width;
sh = field->stripheight;
for (my=INTERPH; my--; ymin++)
{
/*-- Set the image boundaries in y */
if ((idy = field->ymin-ymin) > 0)
{
dt0 = dest + w*idy;
y0 = field->ymin;
h2 = (idy<h ? (h - idy) : 0);
}
else
{
dt0 = dest;
y0 = ymin;
h2 = h;
}
if ((idy = field->ymax - y0) < h2)
h2 = idy;
xmin2 = xmin;
for (mx=INTERPW; mx--; xmin2++)
{
mval = *(m++);
/*---- Set the image boundaries in x */
if (xmin2 < 0)
{
dt = dt0 - xmin2;
x0 = 0;
if ((w2 = w + xmin2) < 0)
w2 = 0;
}
else
{
dt = dt0;
x0 = xmin2;
w2 = w;
}
if ((idx = sw - x0) < w2)
w2 = idx;
if (h2 >= 0 && w2 >= 0)
{
s0 = field->strip + x0;
y2 = y0;
for (iy=h2; iy--; dt+=w)
{
dt2 = dt;
s = s0+sw*((y2++)%sh);
for (ix=w2; ix--;)
*(dt2++) += mval**(s++);
}
}
}
}
return RETURN_OK;
}
/****************************** addimage_center ******************************/
/*
Add a vignet to an image (with a multiplicative factor), recentered through
sinc interpolation.
*/
void addimage_center(picstruct *field, float *psf, int w,int h,
float x,float y, float amplitude)
{
PIXTYPE *s,*s0, *dt,*dt0,*dt2;
float *m,
dx,dy, ddx0,ddx,ddy,sum, fy, mval;
int i,ix,iy, idmx,idmy, mx,my, xmin,ymin,xmin2,x0,y0,y2, w2,h2,
sw,sh, idx,idy;
/*
QMALLOC(psf2, float, w*h);
copyimage_center(field, psf2, w, h, x, y)
dt = psf;
dt2 = psf2;
for (i=w*h; i--; dt++)
*dt = amplitude*(dt++) - *(dt2++);
free(psf2);
*/
dx = x - (ix=(int)x);
dy = y - (iy=(int)y);
/* Don't go further if out of frame!! */
if (ix<0 || ix>=field->width || iy<field->ymin || iy>=field->ymax)
return;
/* Compute the interpolation mask */
ddx0 = -(idmx=(INTERPW-(dx>0.0?1:0))/2)-dx;
ddy = -(idmy=(INTERPH-(dy>0.0?1:0))/2)-dy;
sum = 0.0;
m = interpm;
for (my=INTERPH; my--; ddy+=1.0)
{
ddx = ddx0;
fy = INTERPF(ddy);
for (mx=INTERPW; mx--;ddx+=1.0)
sum += *(m++) = fy*INTERPF(ddx);
}
/* Normalize it */
m = interpm;
for (i=INTERPW*INTERPH; i--;)
*(m++) /= sum;
/* Do the interpolation */
m = interpm;
xmin = ix - w/2 - idmx;
ymin = iy - h/2 - idmy;
sw = field->width;
sh = field->stripheight;
for (my=INTERPH; my--; ymin++)
{
/*-- Set the image boundaries in y */
if ((idy = field->ymin-ymin) > 0)
{
dt0 = psf + w*idy;
y0 = field->ymin;
h2 = (idy<h ? (h - idy) : 0);
}
else
{
dt0 = psf;
y0 = ymin;
h2 = h;
}
if ((idy = field->ymax - y0) < h2)
h2 = idy;
xmin2 = xmin;
for (mx=INTERPW; mx--; xmin2++)
{
mval = *(m++);
/*---- Set the image boundaries in x */
if (xmin2 < 0)
{
dt = dt0 - xmin2;
x0 = 0;
if ((w2 = w + xmin2) < 0)
w2 = 0;
}
else
{
dt = dt0;
x0 = xmin2;
w2 = w;
}
if ((idx = sw - x0) < w2)
w2 = idx;
if (h2 >= 0 && w2 >= 0)
{
s0 = field->strip + x0;
y2 = y0;
for (iy=h2; iy--; dt+=w)
{
dt2 = dt;
s = s0+sw*((y2++)%sh);
for (ix=w2; ix--;)
*(s++) += amplitude*mval**(dt2++);
}
}
}
}
return;
}
/********************************* blankimage *******************************/
/*
Blank a small part of the image according to a mask.
*/
void blankimage(picstruct *field, PIXTYPE *mask, int w,int h,
int xmin,int ymin, PIXTYPE val)
{
PIXTYPE *pixt;
int x,y, xmax,ymax,w2;
/* Don't go further if out of frame!! */
if (xmin+w<0 || xmin>=field->width
|| ymin+h<field->ymin || ymin>=field->ymax)
return;
/* Set the image boundaries */
w2 = w;
ymax = ymin + h;
if (ymin<field->ymin)
{
mask += (field->ymin-ymin)*w;
ymin = field->ymin;
}
if (ymax>field->yblank)
ymax = field->yblank;
xmax = xmin + w;
if (xmax>field->width)
{
w2 -= xmax-field->width;
xmax = field->width;
}
if (xmin<0)
{
mask += -xmin;
w2 -= -xmin;
xmin = 0;
}
w -= w2;
/* Blank the right pixels in the image */
for (y=ymin; y<ymax; y++, mask += w)
{
pixt = &PIX(field, xmin,y);
for (x=w2; x--; pixt++)
if (*(mask++) > -BIG)
*pixt = val;
}
return;
}
/********************************* pasteimage *******************************/
/*
Paste a mask onto an image.
*/
void pasteimage(picstruct *field, PIXTYPE *mask, int w,int h,
int xmin,int ymin)
{
PIXTYPE *pixt, val;
int x,y, xmax,ymax,w2;
/* Don't go further if out of frame!! */
if (xmin+w<0 || xmin>=field->width
|| ymin+h<field->ymin || ymin>=field->ymax)
return;
/* Set the image boundaries */
w2 = w;
ymax = ymin + h;
if (ymin<field->ymin)
{
mask += (field->ymin-ymin)*w;
ymin = field->ymin;
}
if (ymax>field->ymax)
ymax = field->ymax;
xmax = xmin + w;
if (xmax>field->width)
{
w2 -= xmax-field->width;
xmax = field->width;
}
if (xmin<0)
{
mask += -xmin;
w2 -= -xmin;
xmin = 0;
}
w -= w2;
/* Blank the right pixels in the image */
for (y=ymin; y<ymax; y++, mask += w)
{
pixt = &PIX(field, xmin,y);
for (x=w2; x--; pixt++)
if ((val = *(mask++)) > -BIG)
*pixt = val;
}
return;
}
/****************************** vignet_resample ******************************/
/*
Scale and shift a small image through sinc interpolation.
Image parts which lie outside boundaries are set to 0.
*/
int vignet_resample(double *pix1, int w1, int h1,
double *pix2, int w2, int h2,
double dx, double dy, double step2)
{
double *mask,*maskt, xc1,xc2,yc1,yc2, xs1,ys1, x1,y1, x,y, dxm,dym,
val,
*pix12, *pixin,*pixin0, *pixout,*pixout0;
int i,j,k,n,t, *start,*startt, *nmask,*nmaskt,
ixs2,iys2, ix2,iy2, dix2,diy2, nx2,ny2, iys1a, ny1, hmw,hmh,
ix,iy, ix1,iy1;
/* Initialize destination buffer to zero */
memset(pix2, 0, w2*h2*sizeof(double));
xc1 = (double)(w1/2); /* Im1 center x-coord*/
xc2 = (double)(w2/2); /* Im2 center x-coord*/
xs1 = xc1 + dx - xc2*step2; /* Im1 start x-coord */
if ((int)xs1 >= w1)
return RETURN_ERROR;
ixs2 = 0; /* Int part of Im2 start x-coord */
if (xs1<0.0)
{
dix2 = (int)(1-xs1/step2);
/*-- Simply leave here if the images do not overlap in x */
if (dix2 >= w2)
return RETURN_ERROR;
ixs2 += dix2;
xs1 += dix2*step2;
}
nx2 = (int)((w1-1-xs1)/step2+1);/* nb of interpolated Im2 pixels along x */
if (nx2>(ix2=w2-ixs2))
nx2 = ix2;
if (nx2<=0)
return RETURN_ERROR;
yc1 = (double)(h1/2); /* Im1 center y-coord */
yc2 = (double)(h2/2); /* Im2 center y-coord */
ys1 = yc1 + dy - yc2*step2; /* Im1 start y-coord */
if ((int)ys1 >= h1)
return RETURN_ERROR;
iys2 = 0; /* Int part of Im2 start y-coord */
if (ys1<0.0)
{
diy2 = (int)(1-ys1/step2);
/*-- Simply leave here if the images do not overlap in y */
if (diy2 >= h2)
return RETURN_ERROR;
iys2 += diy2;
ys1 += diy2*step2;
}
ny2 = (int)((h1-1-ys1)/step2+1);/* nb of interpolated Im2 pixels along y */
if (ny2>(iy2=h2-iys2))
ny2 = iy2;
if (ny2<=0)
return RETURN_ERROR;
/* Set the yrange for the x-resampling with some margin for interpolation */
iys1a = (int)ys1; /* Int part of Im1 start y-coord with margin */
hmh = INTERPH/2 - 1; /* Interpolant start */
if (iys1a<0 || ((iys1a -= hmh)< 0))
iys1a = 0;
ny1 = (int)(ys1+ny2*step2)+INTERPW-hmh; /* Interpolated Im1 y size */
if (ny1>h1) /* with margin */
ny1 = h1;
/* Express everything relative to the effective Im1 start (with margin) */
ny1 -= iys1a;
ys1 -= (double)iys1a;
/* Allocate interpolant stuff for the x direction */
QMALLOC(mask, double, nx2*INTERPW); /* Interpolation masks */
QMALLOC(nmask, int, nx2); /* Interpolation mask sizes */
QMALLOC(start, int, nx2); /* Int part of Im1 conv starts */
/* Compute the local interpolant and data starting points in x */
hmw = INTERPW/2 - 1;
x1 = xs1;
maskt = mask;
nmaskt = nmask;
startt = start;
for (j=nx2; j--; x1+=step2)
{
ix = (ix1=(int)x1) - hmw;
dxm = ix1 - x1 - hmw; /* starting point in the interpolation func */
if (ix < 0)
{
n = INTERPW+ix;
dxm -= (double)ix;
ix = 0;
}
else
n = INTERPW;
if (n>(t=w1-ix))
n=t;
*(startt++) = ix;
*(nmaskt++) = n;
for (x=dxm, i=n; i--; x+=1.0)
*(maskt++) = INTERPF(x);
}
QCALLOC(pix12, double, nx2*ny1); /* Intermediary frame-buffer */
/* Make the interpolation in x (this includes transposition) */
pixin0 = pix1+iys1a*w1;
pixout0 = pix12;
for (k=ny1; k--; pixin0+=w1, pixout0++)
{
maskt = mask;
nmaskt = nmask;
startt = start;
pixout = pixout0;
for (j=nx2; j--; pixout+=ny1)
{
pixin = pixin0+*(startt++);
val = 0.0;
for (i=*(nmaskt++); i--;)
val += *(maskt++)**(pixin++);
*pixout = val;
}
}
/* Reallocate interpolant stuff for the y direction */
QREALLOC(mask, double, ny2*INTERPH); /* Interpolation masks */
QREALLOC(nmask, int, ny2); /* Interpolation mask sizes */
QREALLOC(start, int, ny2); /* Int part of Im1 conv starts */
/* Compute the local interpolant and data starting points in y */
hmh = INTERPH/2 - 1;
y1 = ys1;
maskt = mask;
nmaskt = nmask;
startt = start;
for (j=ny2; j--; y1+=step2)
{
iy = (iy1=(int)y1) - hmh;
dym = iy1 - y1 - hmh; /* starting point in the interpolation func */
if (iy < 0)
{
n = INTERPH+iy;
dym -= (double)iy;
iy = 0;
}
else
n = INTERPH;
if (n>(t=ny1-iy))
n=t;
*(startt++) = iy;
*(nmaskt++) = n;
for (y=dym, i=n; i--; y+=1.0)
*(maskt++) = INTERPF(y);
}
/* Make the interpolation in y and transpose once again */
pixin0 = pix12;
pixout0 = pix2+ixs2+iys2*w2;
for (k=nx2; k--; pixin0+=ny1, pixout0++)
{
maskt = mask;
nmaskt = nmask;
startt = start;
pixout = pixout0;
for (j=ny2; j--; pixout+=w2)
{
pixin = pixin0+*(startt++);
val = 0.0;
for (i=*(nmaskt++); i--;)
val += *(maskt++)**(pixin++);
*pixout = val;
}
}
/* Free memory */
free(pix12);
free(mask);
free(nmask);
free(start);
return RETURN_OK;
}
/*
image.h
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: SExtractor
*
* Author: E.BERTIN (IAP)
*
* Contents: Include file for image.c.
*
* Last modify: 29/08/98
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
/*----------------------------- Internal constants --------------------------*/
#define INTERPW 6 /* Interpolation function range (x) */
#define INTERPH 6 /* Interpolation function range (y) */
#define INTERPF(x) (x==0.0?1.0:sin(PI*x)*sin(PI*x/3.0)/(PI*PI/3.0*x*x))
/* Lanczos approximation */
/*--------------------------- structure definitions -------------------------*/
/*----------------------------- Global variables ----------------------------*/
/*------------------------------- functions ---------------------------------*/
extern void addimage(picstruct *field, float *psf,
int w,int h, int ix,int iy, float amplitude),
addimage_center(picstruct *field, float *psf,
int w,int h, float x, float y, float amplitude),
blankimage(picstruct *, PIXTYPE *, int,int, int,int, PIXTYPE),
pasteimage(picstruct *, PIXTYPE *, int ,int, int, int);
extern int copyimage(picstruct *, PIXTYPE *, int, int, int, int),
copyimage_center(picstruct *, PIXTYPE *, int,int, float,float),
vignet_resample(double *pix1, int w1, int h1, double *pix2,
int w2, int h2, double dx, double dy, double step2);
/*
interpolate.c
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: SExtractor
*
* Author: E.BERTIN (IAP)
*
* Contents: Interpolation of input data.
*
* Last modify: 26/11/2003
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <string.h>
#include "define.h"
#include "globals.h"
#include "field.h"
#include "interpolate.h"
/****************************** init_interpolate ****************************/
/*
Init resources required for data interpolation.
*/
void init_interpolate(picstruct *field, int xtimeout, int ytimeout)
{
QMALLOC(field->interp_backup, PIXTYPE, field->width);
/* ytimeout < 0 means we don't need a timeout buffer (it won't be used) */
if (ytimeout>=0)
{
QMALLOC(field->interp_ytimeoutbuf, int, field->width);
memset(field->interp_ytimeoutbuf, 0, (size_t)(field->width*sizeof(int)));
}
field->interp_xtimeout = xtimeout;
field->interp_ytimeout = ytimeout;
field->interp_flag = 1;
return;
}
/******************************** interpolate *******************************/
/*
Interpolate (crudely) input data.
*/
void interpolate(picstruct *field, picstruct *wfield,
PIXTYPE *data, PIXTYPE *wdata)
{
PIXTYPE *backup,*wbackup,
thresh;
int *ytimeout,
xtimeout,xtimeout0,ytimeout0, allflag, i;
thresh = wfield->weight_thresh;
backup = field->interp_backup;
wbackup = wfield->interp_backup;
ytimeout = wfield->interp_ytimeoutbuf;
xtimeout0 = wfield->interp_xtimeout;
ytimeout0 = wfield->interp_ytimeout;
xtimeout = 0; /* Start as if the previous pixel was already interpolated */
allflag = field->interp_flag;
for (i=field->width; i--; ytimeout++)
{
/*-- Check if interpolation is needed */
if (*wdata>=thresh) /* It's a variance map: the bigger the worse */
{
/*---- Check if the previous pixel was already interpolated */
if (!xtimeout)
{
if (*ytimeout)
{
(*ytimeout)--;
*wdata = *wbackup;
if (allflag)
*data = *backup;
}
}
else
{
xtimeout--;
*wdata = *(wdata-1);
if (allflag)
*data = *(data-1);
}
}
else
{
xtimeout = xtimeout0;
*ytimeout = ytimeout0;
}
*(wbackup++) = *(wdata++);
if (allflag)
*(backup++) = *(data++);
}
return;
}
/******************************* end_interpolate ****************************/
/*
Free memory allocated for data interpolation.
*/
void end_interpolate(picstruct *field)
{
free(field->interp_backup);
free(field->interp_ytimeoutbuf);
return;
}
/*
interpolate.h
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: SExtractor
*
* Author: E.BERTIN (IAP, Leiden observatory & ESO)
*
* Contents: Include file for interpolate.c.
*
* Last modify: 29/04/98
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
/*---------------------------------- protos --------------------------------*/
extern void end_interpolate(picstruct *field),
init_interpolate(picstruct *field,
int xtimeout, int ytimeout),
interpolate(picstruct *field, picstruct *wfield,
PIXTYPE *data, PIXTYPE *wdata);
/*
key.h
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: SExtractor
*
* Author: E.BERTIN (IAP)
*
* Contents: Keyword structure.
*
* Last modify: 14/12/2004
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
/*--------------------------------- constants -------------------------------*/
#define FIND_STRICT 0
#define FIND_NOSTRICT 1
/*--------------------------- structure definitions -------------------------*/
/* Preference keyword */
typedef struct
{
char name[32];
enum {P_FLOAT, P_INT, P_STRING, P_BOOL, P_KEY, P_INTLIST, P_FLOATLIST,
P_BOOLLIST, P_KEYLIST, P_STRINGLIST} type;
void *ptr; /* Pointer to the keyword value */
int imin, imax; /* Range for int's */
double dmin, dmax; /* Range for doubles */
char keylist[32][32]; /* List of keywords */
int nlistmin; /* Minimum number of list members */
int nlistmax; /* Maximum number of list members */
int *nlistptr; /* Ptr to store the nb of read params*/
int flag;
} pkeystruct;
/*---------------------------------- protos --------------------------------*/
int findkeys(char *str, char key[][32], int mode);
/*
ldactoasc.c
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: LDACtoASC
*
* Author: E.BERTIN (IAP)
*
* Contents: Convert LDAC binary format to ASCII.
*
* Last modify: 04/06/2007
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ldactoasc.h"
#include "fits/fitscat.h"
#define SYNTAX "ldactoasc catalog\n"
extern const char notokstr[];
/********************************** main ************************************/
int main(int argc, char *argv[])
{
catstruct *cat;
tabstruct *tab;
unsigned short ashort=1;
char catname[MAXCHAR];
int a, t, opt,opt2;
if (argc<2)
{
fprintf(OUTPUT, "\n %s Version %s (%s)\n",
BANNER, MYVERSION, DATE);
fprintf(OUTPUT, "\nFor information, please contact: %s\n", COPYRIGHT);
error(EXIT_SUCCESS, "SYNTAX: ", SYNTAX);
}
/* Test if byteswapping will be needed */
bswapflag = *((char *)&ashort);
/* Default parameters */
for (a=1; a<argc; a++)
{
if (*(argv[a]) == '-')
{
opt = (int)argv[a][1];
{
opt2 = (int)tolower((int)argv[a][2]);
if (opt == '-')
{
opt = opt2;
opt2 = (int)tolower((int)argv[a][3]);
}
switch(opt)
{
case 'v':
printf("%s version %s (%s)\n", BANNER,MYVERSION,DATE);
exit(EXIT_SUCCESS);
break;
case 'h':
fprintf(OUTPUT, "\nSYNTAX: %s", SYNTAX);
exit(EXIT_SUCCESS);
break;
default:
error(EXIT_SUCCESS, "SYNTAX: ", SYNTAX);
}
}
}
else
strcpy(catname, argv[a]);
}
if ((cat = read_cat(catname)))
{
tab = cat->tab;
for (t=cat->ntab; t--; tab=tab->nexttab)
if (!strcmp("LDAC_OBJECTS", tab->extname)
|| !strcmp("OBJECTS", tab->extname))
show_keys(tab, NULL, NULL, 0, NULL, stdout, 1, 1, 0, SHOW_ASCII);
free_cat(&cat, 1);
exit(EXIT_SUCCESS);
}
else
{
error(EXIT_FAILURE,"Cannot open ",catname);
return RETURN_ERROR;
}
}
/*
ldactoasc.h
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: LDACtoASC
*
* Author: E.BERTIN (IAP)
*
* Contents: global definitions.
*
* Last modify: 04/06/2007
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
/* Check if we are using a configure script here */
#ifndef HAVE_CONFIG_H
#define VERSION "1.x"
#define DATE "2007-06-04"
#define THREADS_NMAX 16 /* max. number of threads */
#endif
/*------------------------ what, who, when and where ------------------------*/
#define BANNER "LDACtoASC"
#ifdef USE_THREADS
#define MYVERSION VERSION "-MP"
#else
#define MYVERSION VERSION
#endif
#define COPYRIGHT "Emmanuel BERTIN <bertin@iap.fr>"
#define WEBSITE "http://terapix.iap.fr/soft/sextractor/"
#define INSTITUTE "TERAPIX team at IAP http://terapix.iap.fr"
/*----------------------------- Physical constants --------------------------*/
#ifndef PI
#define PI 3.1415926535898
#endif
/*----------------------------- Internal constants --------------------------*/
#define BIG 1e+30 /* a huge number */
#define TINY (1.0/BIG) /* a small number */
#define OUTPUT stdout /* where all msgs are sent */
#define MAXCHAR 512 /* max. number of characters */
#define MAXFILE 32768 /* max number of input files */
/*------------ Set defines according to machine's specificities -------------*/
#if 0
#define NO_ENVVAR
#endif
/*--------------------- in case of missing constants ------------------------*/
#ifndef SEEK_SET
#define SEEK_SET 0
#endif
#ifndef SEEK_CUR
#define SEEK_CUR 1
#endif
#ifndef EXIT_SUCCESS
#define EXIT_SUCCESS 0
#endif
#ifndef EXIT_FAILURE
#define EXIT_FAILURE -1
#endif
/*---------------------------- return messages ------------------------------*/
#define RETURN_OK 0
#define RETURN_ERROR (-1)
#define RETURN_FATAL_ERROR (-2)
/*------------------------------- Other Macros ------------------------------*/
#define DEXP(x) exp(2.30258509299*(x)) /* 10^x */
#define QFREAD(ptr, size, afile, fname) \
if (fread(ptr, (size_t)(size), (size_t)1, afile)!=1) \
error(EXIT_FAILURE, "*Error* while reading ", fname)
#define QFWRITE(ptr, size, afile, fname) \
if (fwrite(ptr, (size_t)(size), (size_t)1, afile)!=1) \
error(EXIT_FAILURE, "*Error* while writing ", fname)
#define QFSEEK(afile, offset, pos, fname) \
if (fseek(afile, (offset), pos)) \
error(EXIT_FAILURE,"*Error*: file positioning failed in ", \
fname)
#define QFTELL(pos, afile, fname) \
if ((pos=ftell(afile))==-1) \
error(EXIT_FAILURE,"*Error*: file position unknown in ", \
fname)
#define QCALLOC(ptr, typ, nel) \
{if (!(ptr = (typ *)calloc((size_t)(nel),sizeof(typ)))) \
error(EXIT_FAILURE, "Not enough memory for ", \
#ptr " (" #nel " elements) !");;}
#define QMALLOC(ptr, typ, nel) \
{if (!(ptr = (typ *)malloc((size_t)(nel)*sizeof(typ)))) \
error(EXIT_FAILURE, "Not enough memory for ", \
#ptr " (" #nel " elements) !");;}
#define QREALLOC(ptr, typ, nel) \
{if (!(ptr = (typ *)realloc(ptr, (size_t)(nel)*sizeof(typ)))) \
error(EXIT_FAILURE, "Not enough memory for ", \
#ptr " (" #nel " elements) !");;}
#define QMEMCPY(ptrin, ptrout, typ, nel) \
{if (ptrin) \
{if (!(ptrout = (typ *)malloc((size_t)(nel)*sizeof(typ)))) \
error(EXIT_FAILURE, "Not enough memory for ", \
#ptrout " (" #nel " elements) !"); \
memcpy(ptrout, ptrin, (size_t)(nel)*sizeof(typ));};;}
#define QPOPEN(file, cmdline, flag) \
{if (!(file=popen(cmdline, flag))) \
error(EXIT_FAILURE, "*Error*: cannot execute ", cmdline);;}
#define RINT(x) (int)(floor(x+0.5))
#define NPRINTF if (prefs.verbose_type == NORM) fprintf
#define NFPRINTF(w,x) {if (prefs.verbose_type == NORM) \
fprintf(w, "\33[1M> %s\n\33[1A",x);}
#define FPRINTF if (prefs.verbose_type == FULL) fprintf
#define QPRINTF if (prefs.verbose_type != QUIET) fprintf
#define QIPRINTF(w,x) {if (prefs.verbose_type == NORM) \
fprintf(w, "\33[7m%s\33[0m\n", x); \
else if (prefs.verbose_type == LOG) \
fprintf(w, "%s\n", x);}
#define QBPRINTF(w,x) {if (prefs.verbose_type == NORM) \
fprintf(w, "\33[01;31m%s\33[0m\n", x); \
else if (prefs.verbose_type == LOG) \
fprintf(w, "%s\n", x);}
/*
main.c
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: SExtractor
*
* Author: E.BERTIN (IAP)
*
* Contents: Command-line parsing.
*
* Last modify: 10/04/2007
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "define.h"
#include "globals.h"
#include "prefs.h"
#define SYNTAX \
EXECUTABLE " <image> [<image2>][-c <configuration_file>][-<keyword> <value>]\n" \
"> to dump a default configuration file: " EXECUTABLE " -d \n" \
"> to dump a default extended configuration file: " EXECUTABLE " -dd \n"
extern const char notokstr[];
/********************************** main ************************************/
int main(int argc, char *argv[])
{
int a, narg, nim, opt, opt2;
char **argkey, **argval, *str;
if (argc<2)
{
fprintf(OUTPUT, "\n %s version %s (%s)\n", BANNER,MYVERSION,DATE);
fprintf(OUTPUT, "\nby %s\n", COPYRIGHT);
fprintf(OUTPUT, "visit %s\n", WEBSITE);
error(EXIT_SUCCESS, "SYNTAX: ", SYNTAX);
}
QMALLOC(argkey, char *, argc);
QMALLOC(argval, char *, argc);
/*default parameters */
prefs.command_line = argv;
prefs.ncommand_line = argc;
prefs.pipe_flag = 0;
prefs.nimage_name = 1;
prefs.image_name[0] = "image";
strcpy(prefs.prefs_name, "default.sex");
narg = nim = 0;
for (a=1; a<argc; a++)
{
if (*(argv[a]) == '-')
{
opt = (int)argv[a][1];
if (strlen(argv[a])<4 || opt == '-')
{
opt2 = (int)tolower((int)argv[a][2]);
if (opt == '-')
{
opt = opt2;
opt2 = (int)tolower((int)argv[a][3]);
}
switch(opt)
{
case 'c':
if (a<(argc-1))
strcpy(prefs.prefs_name, argv[++a]);
break;
case 'd':
dumpprefs(opt2=='d' ? 1 : 0);
exit(EXIT_SUCCESS);
break;
case 'v':
printf("%s version %s (%s)\n", BANNER,MYVERSION,DATE);
exit(0);
break;
case 'h':
default:
error(EXIT_SUCCESS,"SYNTAX: ", SYNTAX);
}
}
else
{
/*------ Config parameters */
argkey[narg] = &argv[a][1];
argval[narg++] = argv[++a];
}
}
else
{
/*---- The input image filename(s) */
for(; (a<argc) && (*argv[a]!='-'); a++)
for (str=NULL;(str=strtok(str?NULL:argv[a], notokstr)); nim++)
if (nim<MAXIMAGE)
prefs.image_name[nim] = str;
else
error(EXIT_FAILURE, "*Error*: Too many input images: ", str);
prefs.nimage_name = nim;
a--;
}
}
readprefs(prefs.prefs_name, argkey, argval, narg);
free(argkey);
free(argval);
makeit();
endprefs();
NFPRINTF(OUTPUT, "");
NPRINTF(OUTPUT, "> All done (in %.0f s)\n", prefs.time_diff);
return EXIT_SUCCESS;
}
/*
makeit.c
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: SExtractor
*
* Author: E.BERTIN, IAP & Leiden observatory
*
* Contents: main program.
*
* Last modify: 31/07/2007
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "define.h"
#include "globals.h"
#include "prefs.h"
#include "fits/fitscat.h"
#include "assoc.h"
#include "back.h"
#include "check.h"
#include "field.h"
#include "filter.h"
#include "growth.h"
#include "interpolate.h"
#include "psf.h"
#include "som.h"
#include "weight.h"
#include "xml.h"
time_t thetimet, thetimet2;
/******************************** makeit *************************************/
/*
Manage the whole stuff.
*/
void makeit()
{
checkstruct *check;
picstruct *dfield, *field,*pffield[MAXFLAG], *wfield,*dwfield;
catstruct *imacat;
tabstruct *imatab;
static time_t thetime1, thetime2;
struct tm *tm;
int i, nok, ntab, next;
void *gptr, *sptr;
/* Install error logging */
error_installfunc(write_error);
/* Processing start date and time */
thetimet = time(NULL);
tm = localtime(&thetimet);
sprintf(prefs.sdate_start,"%04d-%02d-%02d",
tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday);
sprintf(prefs.stime_start,"%02d:%02d:%02d",
tm->tm_hour, tm->tm_min, tm->tm_sec);
NFPRINTF(OUTPUT, "");
QPRINTF(OUTPUT, "----- %s %s started on %s at %s with %d thread%s\n\n",
BANNER,
MYVERSION,
prefs.sdate_start,
prefs.stime_start,
prefs.nthreads,
prefs.nthreads>1? "s":"");
/* Initialize globals variables */
initglob();
NFPRINTF(OUTPUT, "Setting catalog parameters");
readcatparams(prefs.param_name);
useprefs(); /* update things accor. to prefs parameters */
if (prefs.psf_flag)
{
NFPRINTF(OUTPUT, "Reading PSF information");
thepsf = psf_load(prefs.psf_name[0]);
if (prefs.dpsf_flag)
ppsf = psf_load(prefs.psf_name[1]);
/*-- Need to check things up because of PSF context parameters */
updateparamflags();
useprefs();
}
if (prefs.filter_flag)
{
NFPRINTF(OUTPUT, "Reading detection filter");
getfilter(prefs.filter_name); /* get the detection filter */
}
if (FLAG(obj2.sprob))
{
NFPRINTF(OUTPUT, "Initializing Neural Network");
neurinit();
NFPRINTF(OUTPUT, "Reading Neural Network Weights");
getnnw();
}
if (prefs.somfit_flag)
{
int margin;
thesom = som_load(prefs.som_name);
if ((margin=(thesom->inputsize[1]+1)/2) > prefs.cleanmargin)
prefs.cleanmargin = margin;
if (prefs.somfit_vectorsize>thesom->neurdim)
{
prefs.somfit_vectorsize = thesom->neurdim;
sprintf(gstr,"%d", prefs.somfit_vectorsize);
warning("Dimensionality of the SOM-fit vector limited to ", gstr);
}
}
/* Prepare growth-curve buffer */
if (prefs.growth_flag)
initgrowth();
/* Compute the number of valid input extensions */
if (!(imacat = read_cat(prefs.image_name[0])))
error(EXIT_FAILURE, "*Error*: cannot open ", prefs.image_name[0]);
close_cat(imacat);
imatab = imacat->tab;
next = 0;
for (ntab = 0 ; ntab<imacat->ntab; ntab++, imatab = imatab->nexttab)
{
/*-- Check for the next valid image extension */
if ((imatab->naxis < 2)
|| !strncmp(imatab->xtension, "BINTABLE", 8)
|| !strncmp(imatab->xtension, "ASCTABLE", 8))
continue;
next++;
}
thecat.next = next;
/*-- Init the CHECK-images */
if (prefs.check_flag)
{
checkenum c;
NFPRINTF(OUTPUT, "Initializing check-image(s)");
for (i=0; i<prefs.ncheck_type; i++)
if ((c=prefs.check_type[i]) != CHECK_NONE)
{
if (prefs.check[c])
error(EXIT_FAILURE,"*Error*: 2 CHECK_IMAGEs cannot have the same ",
" CHECK_IMAGE_TYPE");
prefs.check[c] = initcheck(prefs.check_name[i], prefs.check_type[i],
next);
}
}
NFPRINTF(OUTPUT, "Initializing catalog");
initcat();
/* Initialize XML data */
if (prefs.xml_flag || prefs.cat_type==ASCII_VO)
init_xml(next);
/* Go through all images */
nok = -1;
for (ntab = 0 ; ntab<imacat->ntab; ntab++, imatab = imatab->nexttab)
{
/*-- Check for the next valid image extension */
if ((imatab->naxis < 2)
|| !strncmp(imatab->xtension, "BINTABLE", 8)
|| !strncmp(imatab->xtension, "ASCTABLE", 8))
continue;
nok++;
/*-- Initial time measurement*/
time(&thetime1);
thecat.currext = nok+1;
dfield = field = wfield = dwfield = NULL;
if (prefs.dimage_flag)
{
/*---- Init the Detection and Measurement-images */
dfield = newfield(prefs.image_name[0], DETECT_FIELD, nok);
field = newfield(prefs.image_name[1], MEASURE_FIELD, nok);
if ((field->width!=dfield->width) || (field->height!=dfield->height))
error(EXIT_FAILURE, "*Error*: Frames have different sizes","");
/*---- Prepare interpolation */
if (prefs.dweight_flag && prefs.interp_type[0] == INTERP_ALL)
init_interpolate(dfield, -1, -1);
if (prefs.interp_type[1] == INTERP_ALL)
init_interpolate(field, -1, -1);
}
else
{
field = newfield(prefs.image_name[0], DETECT_FIELD | MEASURE_FIELD, nok);
/*-- Prepare interpolation */
if ((prefs.dweight_flag || prefs.weight_flag)
&& prefs.interp_type[0] == INTERP_ALL)
init_interpolate(field, -1, -1); /* 0.0 or anything else */
}
/*---- Prepare photometry Measurements: gain and saturation definition */
if (fitsread(field->fitshead, prefs.gain_key, &gptr, H_FLOAT, T_DOUBLE)
==RETURN_OK)
prefs.gain = *(double *)&gptr;
if (fitsread(field->fitshead, prefs.satur_key, &sptr, H_FLOAT, T_DOUBLE)
==RETURN_OK)
prefs.satur_level = *(double *)&sptr;
/*-- Init the WEIGHT-images */
if (prefs.dweight_flag || prefs.weight_flag)
{
weightenum wtype;
PIXTYPE interpthresh;
if (prefs.nweight_type>1)
{
/*------ Double-weight-map mode */
if (prefs.weight_type[1] != WEIGHT_NONE)
{
/*-------- First: the "measurement" weights */
wfield = newweight(prefs.wimage_name[1],field,prefs.weight_type[1],
nok);
wtype = prefs.weight_type[1];
interpthresh = prefs.weight_thresh[1];
/*-------- Convert the interpolation threshold to variance units */
weight_to_var(wfield, &interpthresh, 1);
wfield->weight_thresh = interpthresh;
if (prefs.interp_type[1] != INTERP_NONE)
init_interpolate(wfield,
prefs.interp_xtimeout[1], prefs.interp_ytimeout[1]);
}
/*------ The "detection" weights */
if (prefs.weight_type[0] != WEIGHT_NONE)
{
interpthresh = prefs.weight_thresh[0];
if (prefs.weight_type[0] == WEIGHT_FROMINTERP)
{
dwfield=newweight(prefs.wimage_name[0],wfield,prefs.weight_type[0],
nok);
weight_to_var(wfield, &interpthresh, 1);
}
else
{
dwfield = newweight(prefs.wimage_name[0], dfield?dfield:field,
prefs.weight_type[0], nok);
weight_to_var(dwfield, &interpthresh, 1);
}
dwfield->weight_thresh = interpthresh;
if (prefs.interp_type[0] != INTERP_NONE)
init_interpolate(dwfield,
prefs.interp_xtimeout[0], prefs.interp_ytimeout[0]);
}
}
else
{
/*------ Single-weight-map mode */
wfield = newweight(prefs.wimage_name[0], dfield?dfield:field,
prefs.weight_type[0], nok);
wtype = prefs.weight_type[0];
interpthresh = prefs.weight_thresh[0];
/*------ Convert the interpolation threshold to variance units */
weight_to_var(wfield, &interpthresh, 1);
wfield->weight_thresh = interpthresh;
if (prefs.interp_type[0] != INTERP_NONE)
init_interpolate(wfield,
prefs.interp_xtimeout[0], prefs.interp_ytimeout[0]);
}
}
/*-- Init the FLAG-images */
for (i=0; i<prefs.nimaflag; i++)
{
pffield[i] = newfield(prefs.fimage_name[i], FLAG_FIELD, nok);
if ((pffield[i]->width!=field->width)
|| (pffield[i]->height!=field->height))
error(EXIT_FAILURE,
"*Error*: Incompatible FLAG-map size in ", prefs.fimage_name[i]);
}
/*-- Compute background maps for `standard' fields */
QPRINTF(OUTPUT, dfield? "Measurement image:"
: "Detection+Measurement image: ");
makeback(field, wfield);
QPRINTF(OUTPUT, (dfield || (dwfield&&dwfield->flags^INTERP_FIELD))? "(M) "
"Background: %-10g RMS: %-10g / Threshold: %-10g \n"
: "(M+D) "
"Background: %-10g RMS: %-10g / Threshold: %-10g \n",
field->backmean, field->backsig, (field->flags & DETECT_FIELD)?
field->dthresh: field->thresh);
if (dfield)
{
QPRINTF(OUTPUT, "Detection image: ");
makeback(dfield, dwfield? dwfield
: (prefs.weight_type[0] == WEIGHT_NONE?NULL:wfield));
QPRINTF(OUTPUT, "(D) "
"Background: %-10g RMS: %-10g / Threshold: %-10g \n",
dfield->backmean, dfield->backsig, dfield->dthresh);
}
else if (dwfield && dwfield->flags^INTERP_FIELD)
{
makeback(field, dwfield);
QPRINTF(OUTPUT, "(D) "
"Background: %-10g RMS: %-10g / Threshold: %-10g \n",
field->backmean, field->backsig, field->dthresh);
}
/*-- For interpolated weight-maps, copy the background structure */
if (dwfield && dwfield->flags&(INTERP_FIELD|BACKRMS_FIELD))
copyback(dwfield->reffield, dwfield);
if (wfield && wfield->flags&(INTERP_FIELD|BACKRMS_FIELD))
copyback(wfield->reffield, wfield);
/*-- Prepare learn and/or associations */
if (prefs.assoc_flag)
init_assoc(field); /* initialize assoc tasks */
/*-- Update the CHECK-images */
if (prefs.check_flag)
for (i=0; i<MAXCHECK; i++)
if ((check=prefs.check[i]))
reinitcheck(field, check);
/*-- Initialize PSF contexts and workspace */
if (prefs.psf_flag)
{
psf_readcontext(thepsf, field);
psf_init(thepsf);
if (prefs.dpsf_flag)
{
psf_readcontext(thepsf, dfield);
psf_init(thepsf); /*?*/
}
}
/*-- Copy field structures to static ones (for catalog info) */
if (dfield)
{
thefield1 = *field;
thefield2 = *dfield;
}
else
thefield1 = thefield2 = *field;
if (wfield)
{
thewfield1 = *wfield;
thewfield2 = dwfield? *dwfield: *wfield;
}
else if (dwfield)
thewfield2 = *dwfield;
reinitcat(field);
/*-- Start the extraction pipeline */
NFPRINTF(OUTPUT, "Scanning image");
scanimage(field, dfield, pffield, prefs.nimaflag, wfield, dwfield);
/*-- Finish the current CHECK-image processing */
if (prefs.check_flag)
for (i=0; i<MAXCHECK; i++)
if ((check=prefs.check[i]))
reendcheck(field, check);
/*-- Final time measurements*/
if (time(&thetime2)!=-1)
{
if (!strftime(thecat.ext_date, 12, "%d/%m/%Y", localtime(&thetime2)))
error(EXIT_FAILURE, "*Internal Error*: Date string too long ","");
if (!strftime(thecat.ext_time, 10, "%H:%M:%S", localtime(&thetime2)))
error(EXIT_FAILURE, "*Internal Error*: Time/date string too long ","");
thecat.ext_elapsed = difftime(thetime2, thetime1);
}
reendcat();
/* Update XML data */
if (prefs.xml_flag || prefs.cat_type==ASCII_VO)
update_xml(&thecat, dfield? dfield:field, field,
dwfield? dwfield:wfield, wfield);
/*-- Close ASSOC routines */
end_assoc(field);
for (i=0; i<prefs.nimaflag; i++)
endfield(pffield[i]);
endfield(field);
if (dfield)
endfield(dfield);
if (wfield)
endfield(wfield);
if (dwfield)
endfield(dwfield);
QPRINTF(OUTPUT, "Objects: detected %-8d / sextracted %-8d \n",
thecat.ndetect, thecat.ntotal);
}
if (nok<0)
error(EXIT_FAILURE, "Not enough valid FITS image extensions in ",
prefs.image_name[0]);
free_cat(&imacat, 1);
NFPRINTF(OUTPUT, "Closing files");
/* End CHECK-image processing */
if (prefs.check_flag)
for (i=0; i<MAXCHECK; i++)
{
if ((check=prefs.check[i]))
endcheck(check);
prefs.check[i] = NULL;
}
if (prefs.filter_flag)
endfilter();
if (prefs.somfit_flag)
som_end(thesom);
if (prefs.growth_flag)
endgrowth();
if (prefs.psf_flag)
psf_end(thepsf,thepsfit); /*?*/
if (prefs.dpsf_flag)
psf_end(ppsf,ppsfit);
if (FLAG(obj2.sprob))
neurclose();
/* Processing end date and time */
thetimet2 = time(NULL);
tm = localtime(&thetimet2);
sprintf(prefs.sdate_end,"%04d-%02d-%02d",
tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday);
sprintf(prefs.stime_end,"%02d:%02d:%02d",
tm->tm_hour, tm->tm_min, tm->tm_sec);
prefs.time_diff = difftime(thetimet2, thetimet);
/* Write XML */
if (prefs.xml_flag)
write_xml(prefs.xml_name);
endcat((char *)NULL);
if (prefs.xml_flag || prefs.cat_type==ASCII_VO)
end_xml();
return;
}
/******************************** initglob ***********************************/
/*
Initialize a few global variables
*/
void initglob()
{
int i;
for (i=0; i<37; i++)
{
ctg[i] = cos(i*PI/18);
stg[i] = sin(i*PI/18);
}
return;
}
/****** write_error ********************************************************
PROTO int write_error(char *msg1, char *msg2)
PURPOSE Manage files in case of a catched error
INPUT a character string,
another character string
OUTPUT RETURN_OK if everything went fine, RETURN_ERROR otherwise.
NOTES -.
AUTHOR E. Bertin (IAP)
VERSION 14/07/2006
***/
void write_error(char *msg1, char *msg2)
{
char error[MAXCHAR];
sprintf(error, "%s%s", msg1,msg2);
if (prefs.xml_flag)
write_xmlerror(prefs.xml_name, error);
/* Also close existing catalog */
endcat(error);
end_xml();
return;
}
/*
manobjlist.c
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: SExtractor
*
* Author: E.BERTIN (IAP)
*
* Contents: functions for the management of object lists.
*
* Last modify: 26/11/2003
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <string.h>
#include "define.h"
#include "globals.h"
#include "plist.h"
/********************************* belong ************************************/
/*
say if an object is "included" in another.
*/
int belong(int corenb, objliststruct *coreobjlist,
int shellnb, objliststruct *shellobjlist)
{
objstruct *cobj = &(coreobjlist->obj[corenb]),
*sobj = &(shellobjlist->obj[shellnb]);
pliststruct *cpl = coreobjlist->plist, *spl = shellobjlist->plist, *pixt;
int xc=PLIST(cpl+cobj->firstpix,x), yc=PLIST(cpl+cobj->firstpix,y);
for (pixt = spl+sobj->firstpix; pixt>=spl; pixt = spl+PLIST(pixt,nextpix))
if ((PLIST(pixt,x) == xc) && (PLIST(pixt,y) == yc))
return 1;
return 0;
}
/********************************* addobj ************************************/
/*
Add an object to an objlist.
*/
int addobj(int objnb, objliststruct *objl1, objliststruct *objl2)
{
objstruct *objl2obj;
pliststruct *plist1 = objl1->plist, *plist2 = objl2->plist;
int fp, i, j, npx, objnb2;
j = (fp = objl2->npix)*plistsize;
objnb2 = objl2->nobj;
/* Update the object list */
if (objl2->nobj)
{
if (!(objl2obj = (objstruct *)realloc(objl2->obj,
(++objl2->nobj) * sizeof(objstruct))))
goto exit_addobj;
}
else
if (!(objl2obj = (objstruct *)malloc((++objl2->nobj)*sizeof(objstruct))))
goto exit_addobj;
/* Update the pixel list */
npx = objl1->obj[objnb].fdnpix;
if (fp)
{
if (!(plist2 = (pliststruct *)realloc(plist2,
(objl2->npix+=npx) * plistsize)))
goto exit_addobj;
}
else
if (!(plist2=(pliststruct *)malloc((objl2->npix=npx)*plistsize)))
goto exit_addobj;
objl2->obj = objl2obj;
objl2->plist = plist2;
plist2 += j;
for(i=objl1->obj[objnb].firstpix; i!=-1; i=PLIST(plist1+i,nextpix))
{
memcpy(plist2, plist1+i, (size_t)plistsize);
PLIST(plist2,nextpix) = (j+=plistsize);
plist2 += plistsize;
}
PLIST(plist2-=plistsize, nextpix) = -1;
objl2->obj[objnb2] = objl1->obj[objnb];
objl2->obj[objnb2].firstpix = fp*plistsize;
objl2->obj[objnb2].lastpix = j-plistsize;
return objnb2;
exit_addobj:
objl2->nobj--;
objl2->npix = fp;
return RETURN_FATAL_ERROR;
}
/*
misc.c
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: SExtractor
*
* Author: E.BERTIN (IAP)
*
* Contents: miscellaneous functions.
*
* Last modify: 13/12/2002
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "define.h"
#include "globals.h"
/******************************** hmedian ***********************************/
/*
Median using Heapsort algorithm (for float arrays) (based on Num.Rec algo.).
Warning: changes the order of data!
*/
float hmedian(float *ra, int n)
{
int l, j, ir, i;
float rra;
if (n<2)
return *ra;
ra--;
for (l = ((ir=n)>>1)+1;;)
{
if (l>1)
rra = ra[--l];
else
{
rra = ra[ir];
ra[ir] = ra[1];
if (--ir == 1)
{
ra[1] = rra;
return n&1? ra[n/2+1] : (float)((ra[n/2]+ra[n/2+1])/2.0);
}
}
for (j = (i=l)<<1; j <= ir;)
{
if (j < ir && ra[j] < ra[j+1])
++j;
if (rra < ra[j])
{
ra[i] = ra[j];
j += (i=j);
}
else
j = ir + 1;
}
ra[i] = rra;
}
/* (the 'return' is inside the loop!!) */
}
/*
neurro.c
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: A program using neural networks.
*
* Author: E.BERTIN (IAP)
*
* Contents: run only version of the neural network.
*
* Last modify: 26/11/2003
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "define.h"
#include "globals.h"
#include "prefs.h"
#include "neurro.h"
brainstruct *brain;
/******************************** neurinit **********************************/
/*
Initialization of the "brain".
*/
void neurinit()
{
QMALLOC(brain, brainstruct, 1);
return;
}
/********************************* neurend **********************************/
/*
Close the "brain".
*/
void neurclose()
{
free(brain);
return;
}
/******************************** neurresp **********************************/
/*
Neural network response to an input vector.
*/
void neurresp(double *input, double *output)
{
int i, j, l, lastlay = brain->layersnb-1;
double neursum;
for (i=0; i<brain->nn[0]; i++)
brain->n[0][i] = input[i]*brain->inscale[i] + brain->inbias[i];
for (l=0; l<lastlay; l++)
for (j=0; j<brain->nn[l+1]; j++)
{
neursum = brain->b[l][j];
for (i=0; i<brain->nn[l]; i++)
neursum += brain->w[l][i][j] * brain->n[l][i];
brain->n[l+1][j] = f(neursum);
}
for (i=0; i<brain->nn[lastlay]; i++)
output[i] = (brain->n[lastlay][i]-brain->outbias[i])
/ brain->outscale[i];
return;
}
/************************************ f *************************************/
/*
Sigmoid function for a neural network.
*/
double f(double x)
{
return 1.0 / (1.0 + exp(-x));
}
/********************************* getnnw ***********************************/
/*
Read the NNW table that contains the weights.
*/
void getnnw()
{
FILE *infile;
int i, j, k, step;
char str[MAXCHAR], *sstr, *null;
if ((infile = fopen(prefs.nnw_name,"r")) == NULL)
error(EXIT_FAILURE,"*ERROR*: can't read ", prefs.nnw_name);
fgets(str, MAXCHAR, infile);
if (strncmp(str,"NNW",3))
error(EXIT_FAILURE, prefs.nnw_name, " is NOT a NNW table!");
step = 1;
i=j=0; /* To avoid gcc -Wall warnings */
while (fgets(str, MAXCHAR, infile))
{
sstr = &str[(int)strspn(str," \t")];
if (sstr[0]!=(char)'#' && sstr[0]!=(char)'\n')
{
null = sstr;
switch(step)
{
case 1: brain->layersnb = atoi(strtok(sstr, " \t\n"));
for (i=0; i<brain->layersnb; i++)
brain->nn[i] = atoi(strtok(NULL, " \t\n"));
step++;
break;
case 2: for (i=0; i<brain->nn[0]; i++)
{
brain->inbias[i] = atof(strtok(null, " \t\n"));
null = NULL;
}
step++;
break;
case 3: for (i=0; i<brain->nn[0]; i++)
{
brain->inscale[i] = atof(strtok(null, " \t\n"));
null = NULL;
}
i=j=0;
step++;
break;
case 4: if (j == brain->nn[i+1])
{
j = 0;
i++;
}
if (i < brain->layersnb-1)
{
for (k=0; k<brain->nn[i]; k++)
{
brain->w[i][k][j] = atof(strtok(null, " \t\n"));
null = NULL;
}
brain->b[i][j] = atof(strtok(NULL, " \t\n"));
j++;
break;
}
else
step++;
case 5: for (i=0; i<brain->nn[brain->layersnb-1]; i++)
{
brain->outbias[i] = atof(strtok(null, " \t\n"));
null = NULL;
}
step++;
break;
case 6: for (i=0; i<brain->nn[brain->layersnb-1]; i++)
{
brain->outscale[i] = atof(strtok(null, " \t\n"));
null = NULL;
}
step++;
break;
default:error(EXIT_FAILURE, "*Error*: inconsistency in ", prefs.nnw_name);
}
}
}
fclose(infile);
return;
}
/*
neurro.h
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: neurro.c
*
* Author: E.BERTIN, Institut d'Astrophysique de Paris.
*
* Contents: global definitions.
*
* Last modify: 30/03/95
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
/*--------------------------- Neural Network parameters ---------------------*/
#define LAYERS 3 /* max. number of hidden+i/o layers */
#define CONNEX LAYERS-1
#define NEURONS 10 /* maximum number of neurons/layer */
/*------------------------------- structures --------------------------------*/
typedef struct
{
int layersnb;
int nn[LAYERS];
double inbias[NEURONS];
double inscale[NEURONS];
double outbias[NEURONS];
double outscale[NEURONS];
double ni[NEURONS];
double no[NEURONS];
double n[LAYERS][NEURONS];
double w[CONNEX][NEURONS][NEURONS];
double b[CONNEX][NEURONS];
} brainstruct;
/*------------------------------- globals ----------------------------------*/
extern double f(double);
/*
param.h
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: SExtractor
*
* Author: E.BERTIN (IAP)
*
* Contents: parameter list for catalog data.
*
* Last modify: 28/09/2006
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
objstruct outobj;
obj2struct outobj2;
/*--------------------------------- initialization --------------------------*/
keystruct objkey[] = {
{"NUMBER", "Running object number",
&outobj.number, H_INT, T_LONG, "%10d", "",
"meta.record", ""},
{"EXT_NUMBER", "FITS extension number",
&outobj2.ext_number, H_INT, T_SHORT, "%3d", "",
"meta.id;meta.dataset", ""},
{"FLUX_ISO", "Isophotal flux",
&outobj2.flux_iso, H_FLOAT, T_FLOAT, "%12.7g", "count",
"phot.flux", "ct"},
{"FLUXERR_ISO", "RMS error for isophotal flux",
&outobj2.fluxerr_iso, H_FLOAT, T_FLOAT, "%12.7g", "count",
"stat.stdev;phot.flux", "ct"},
{"MAG_ISO", "Isophotal magnitude",
&outobj2.mag_iso, H_FLOAT, T_FLOAT, "%8.4f", "mag",
"phot.mag", "mag"},
{"MAGERR_ISO", "RMS error for isophotal magnitude",
&outobj2.magerr_iso, H_FLOAT, T_FLOAT, "%8.4f", "mag",
"stat.stdev;phot.mag", "mag"},
{"FLUX_ISOCOR", "Corrected isophotal flux",
&outobj2.flux_isocor, H_FLOAT, T_FLOAT, "%12.7g", "count",
"phot.flux", "ct"},
{"FLUXERR_ISOCOR", "RMS error for corrected isophotal flux",
&outobj2.fluxerr_isocor, H_FLOAT, T_FLOAT, "%12.7g", "count",
"stat.stdev;phot.flux", "ct"},
{"MAG_ISOCOR", "Corrected isophotal magnitude",
&outobj2.mag_isocor, H_FLOAT, T_FLOAT, "%8.4f", "mag",
"phot.mag", "mag"},
{"MAGERR_ISOCOR", "RMS error for corrected isophotal magnitude",
&outobj2.magerr_isocor, H_FLOAT, T_FLOAT, "%8.4f", "mag",
"stat.stdev;phot.mag", "mag"},
{"FLUX_APER", "Flux vector within fixed circular aperture(s)",
&outobj2.flux_aper, H_FLOAT, T_FLOAT, "%12.7g", "count",
"phot.flux", "ct", 1, &prefs.flux_apersize},
{"FLUXERR_APER", "RMS error vector for aperture flux(es)",
&outobj2.fluxerr_aper, H_FLOAT, T_FLOAT, "%12.7g", "count",
"stat.stdev;phot.flux", "ct", 1, &prefs.fluxerr_apersize},
{"MAG_APER", "Fixed aperture magnitude vector",
&outobj2.mag_aper, H_FLOAT, T_FLOAT, "%8.4f", "mag",
"phot.mag", "mag", 1, &prefs.mag_apersize},
{"MAGERR_APER", "RMS error vector for fixed aperture mag.",
&outobj2.magerr_aper, H_FLOAT, T_FLOAT, "%8.4f", "mag",
"stat.stdev;phot.mag", "mag", 1, &prefs.magerr_apersize},
{"FLUX_AUTO", "Flux within a Kron-like elliptical aperture",
&outobj2.flux_auto, H_FLOAT, T_FLOAT, "%12.7g", "count",
"phot.flux;meta.main", "ct"},
{"FLUXERR_AUTO", "RMS error for AUTO flux",
&outobj2.fluxerr_auto, H_FLOAT, T_FLOAT, "%12.7g", "count",
"stat.stdev;phot.flux;meta.main", "ct"},
{"MAG_AUTO", "Kron-like elliptical aperture magnitude",
&outobj2.mag_auto, H_FLOAT, T_FLOAT, "%8.4f", "mag",
"phot.mag;meta.main", "mag"},
{"MAGERR_AUTO", "RMS error for AUTO magnitude",
&outobj2.magerr_auto, H_FLOAT, T_FLOAT, "%8.4f", "mag",
"stat.stdev;phot.mag;meta.main", "mag"},
{"FLUX_PETRO", "Flux within a Petrosian-like elliptical aperture",
&outobj2.flux_petro, H_FLOAT, T_FLOAT, "%12.7g", "count",
"phot.flux", "ct"},
{"FLUXERR_PETRO", "RMS error for PETROsian flux",
&outobj2.fluxerr_petro, H_FLOAT, T_FLOAT, "%12.7g", "count",
"stat.stdev;phot.flux", "ct"},
{"MAG_PETRO", "Petrosian-like elliptical aperture magnitude",
&outobj2.mag_petro, H_FLOAT, T_FLOAT, "%8.4f", "mag",
"phot.mag", "mag"},
{"MAGERR_PETRO", "RMS error for PETROsian magnitude",
&outobj2.magerr_petro, H_FLOAT, T_FLOAT, "%8.4f", "mag",
"stat.stdev;phot.mag", "mag"},
{"FLUX_BEST", "Best of FLUX_AUTO and FLUX_ISOCOR",
&outobj2.flux_best, H_FLOAT, T_FLOAT, "%12.7g", "count",
"phot.flux", "ct"},
{"FLUXERR_BEST", "RMS error for BEST flux",
&outobj2.fluxerr_best, H_FLOAT, T_FLOAT, "%12.7g", "count",
"stat.stdev;phot.flux", "ct"},
{"MAG_BEST", "Best of MAG_AUTO and MAG_ISOCOR",
&outobj2.mag_best, H_FLOAT, T_FLOAT, "%8.4f", "mag",
"phot.mag", "mag"},
{"MAGERR_BEST", "RMS error for MAG_BEST",
&outobj2.magerr_best, H_FLOAT, T_FLOAT, "%8.4f", "mag",
"stat.stdev;phot.mag", "mag"},
{"FLUX_PROFILE", "Flux weighted by the FILTERed profile",
&outobj2.flux_prof, H_FLOAT, T_FLOAT, "%12.7g", "count"
"phot.flux", "ct"},
{"FLUXERR_PROFILE", "RMS error for PROFILE flux",
&outobj2.fluxerr_prof, H_FLOAT, T_FLOAT, "%12.7g", "count",
"stat.stdev;phot.flux", "ct"},
{"MAG_PROFILE", "Magnitude weighted by the FILTERed profile",
&outobj2.mag_prof, H_FLOAT, T_FLOAT, "%8.4f", "mag",
"phot.mag", "mag"},
{"MAGERR_PROFILE", "RMS error for MAG_PROFILE",
&outobj2.magerr_prof, H_FLOAT, T_FLOAT, "%8.4f", "mag",
"stat.stdev;phot.mag", "mag"},
{"FLUX_WIN", "Gaussian-weighted flux",
&outobj2.flux_win, H_FLOAT, T_FLOAT, "%12.7g", "count",
"phot.flux", "ct"},
{"FLUXERR_WIN", "RMS error for WIN flux",
&outobj2.fluxerr_win, H_FLOAT, T_FLOAT, "%12.7g", "count",
"stat.stdev;phot.flux", "ct"},
{"MAG_WIN", "Gaussian-weighted magnitude",
&outobj2.mag_win, H_FLOAT, T_FLOAT, "%8.4f", "mag",
"phot.mag", "mag"},
{"MAGERR_WIN", "RMS error for MAG_WIN",
&outobj2.magerr_win, H_FLOAT, T_FLOAT, "%8.4f", "mag",
"stat.stdev;phot.mag", "mag"},
{"FLUX_SOMFIT", "Flux derived from SOM fit",
&outobj2.flux_somfit, H_FLOAT, T_FLOAT, "%12.7g", "count",
"phot.flux", "ct"},
{"FLUXERR_SOMFIT", "RMS error for SOMFIT flux",
&outobj2.fluxerr_somfit, H_FLOAT, T_FLOAT, "%12.7g", "count",
"stat.stdev;phot.flux", "ct"},
{"MAG_SOMFIT", "Magnitude derived from SOM fit",
&outobj2.mag_somfit, H_FLOAT, T_FLOAT, "%8.4f", "mag",
"phot.mag", "mag"},
{"MAGERR_SOMFIT", "Magnitude error derived from SOM fit",
&outobj2.magerr_somfit, H_FLOAT, T_FLOAT, "%8.4f", "mag",
"stat.stdev;phot.mag", "mag"},
{"ERROR_SOMFIT", "Reduced Chi-square error of the SOM fit",
&outobj2.stderr_somfit, H_FLOAT, T_FLOAT, "%10.4g", "",
"stat.fit.chi2", ""},
{"VECTOR_SOMFIT", "Position vector of the winning SOM node",
&outobj2.vector_somfit, H_FLOAT, T_FLOAT, "%5.2f", "",
"src.morph.param", "", 1, &prefs.somfit_vectorsize},
{"FLUX_GALFIT", "Flux derived from the galaxy fit",
&outobj2.flux_galfit, H_FLOAT, T_FLOAT, "%12.7g", "count",
"phot.flux;stat.fit.param", "ct"},
/*
{"FLUXERR_GALFIT", "RMS error for GALFIT flux",
&outobj2.fluxerr_galfit, H_FLOAT, T_FLOAT, "%12.7g", "count"},
*/
{"MAG_GALFIT", "Magnitude derived from galaxy fit",
&outobj2.mag_galfit, H_FLOAT, T_FLOAT, "%8.4f", "mag",
"phot.mag;stat.fit.param", "mag"},
/*
{"MAGERR_GALFIT", "Magnitude error derived from galaxy fit",
&outobj2.magerr_galfit, H_FLOAT, T_FLOAT, "%8.4f", "mag"},
{"ERROR_GALFIT", "Reduced Chi-square error of the galaxy fit",
&outobj2.stderr_galfit, H_FLOAT, T_FLOAT, "%10g", ""},
*/
{"GALDANG_IMAGE", "Galaxy disk position angle from the galaxy fit",
&outobj2.gdposang, H_FLOAT, T_FLOAT, "%5.1f", "deg",
"pos.posAng;stat.fit.param", "deg"},
{"GALDSCALE_IMAGE", "Galaxy disk-scale from the galaxy fit",
&outobj2.gdscale, H_FLOAT, T_FLOAT, "%9.3f", "pixel",
"src.morph.scLength;stat.fit.param", "pix"},
{"GALDASPEC_IMAGE", "Galaxy disk aspect ratio from the galaxy fit",
&outobj2.gdaspect, H_FLOAT, T_FLOAT, "%5.3f", "",
"phys.size.axisRatio;stat.fit.param", ""},
{"GALDE1_IMAGE", "Galaxy disk ellipticity #1 from the galaxy fit",
&outobj2.gde1, H_FLOAT, T_FLOAT, "%6.4f", "",
"src.ellipticity", ""},
{"GALDE2_IMAGE", "Galaxy disk ellipticity #2 from the galaxy fit",
&outobj2.gde2, H_FLOAT, T_FLOAT, "%6.4f", "",
"src.ellipticity", ""},
{"GALBRATIO_IMAGE", "Galaxy bulge ratio from the galaxy fit",
&outobj2.gbratio, H_FLOAT, T_FLOAT, "%5.3f", "",
"src.morph.param;stat.fit.param", ""},
{"GALBANG_IMAGE", "Galaxy bulge position angle from the galaxy fit",
&outobj2.gbposang, H_FLOAT, T_FLOAT, "%5.1f", "deg",
"pos.posAng;stat.fit.param", "deg"},
{"GALBSCALE_IMAGE", "Galaxy bulge-scale from the galaxy fit",
&outobj2.gbscale, H_FLOAT, T_FLOAT, "%9.3f", "pixel",
"src.morph.scLength;stat.fit.param", "pix"},
{"GALBASPEC_IMAGE", "Galaxy bulge aspect ratio from the galaxy fit",
&outobj2.gbaspect, H_FLOAT, T_FLOAT, "%5.3f", "",
"phys.size.axisRatio;stat.fit.param", ""},
{"KRON_RADIUS", "Kron apertures in units of A or B",
&outobj2.kronfactor, H_FLOAT, T_FLOAT, "%5.2f", "",
"arith.factor;arith.ratio", ""},
{"PETRO_RADIUS", "Petrosian apertures in units of A or B",
&outobj2.petrofactor, H_FLOAT, T_FLOAT, "%5.2f", "",
"arith.factor;arith.ratio", ""},
{"BACKGROUND", "Background at centroid position",
&outobj.bkg, H_FLOAT, T_FLOAT, "%12.7g", "count",
"instr.skyLevel", "ct"},
{"THRESHOLD", "Detection threshold above background",
&outobj.dthresh, H_FLOAT, T_FLOAT, "%12.7g", "count",
"instr.sensitivity;phot.flux.sb", "ct"},
{"FLUX_MAX", "Peak flux above background",
&outobj.peak, H_FLOAT, T_FLOAT, "%12.7g", "count",
"phot.flux.sb;stat.max", "ct"},
{"ISOAREA_IMAGE", "Isophotal area above Analysis threshold",
&outobj.npix, H_INT, T_LONG, "%9d", "pixel**2",
"phys.area", "pix2"},
{"ISOAREAF_IMAGE", "Isophotal area (filtered) above Detection threshold",
&outobj.fdnpix, H_INT, T_LONG, "%9d", "pixel**2",
"phys.area", "pix2"},
{"XMIN_IMAGE", "Minimum x-coordinate among detected pixels",
&outobj.xmin, H_INT, T_LONG, "%10d", "pixel",
"pos.cartesian.x;stat.min", "pix"},
{"YMIN_IMAGE", "Minimum y-coordinate among detected pixels",
&outobj.ymin, H_INT, T_LONG, "%10d", "pixel",
"pos.cartesian.y;stat.min", "pix"},
{"XMAX_IMAGE", "Maximum x-coordinate among detected pixels",
&outobj.xmax, H_INT, T_LONG, "%10d", "pixel",
"pos.cartesian.x;stat.max", "pix"},
{"YMAX_IMAGE", "Maximum y-coordinate among detected pixels",
&outobj.ymax, H_INT, T_LONG, "%10d", "pixel",
"pos.cartesian.y;stat.max", "pix"},
{"XPEAK_IMAGE", "x-coordinate of the brightest pixel",
&outobj.peakx, H_INT, T_LONG, "%10d", "pixel",
"pos.cartesian.x", "pix"},
{"YPEAK_IMAGE", "y-coordinate of the brightest pixel",
&outobj.peaky, H_INT, T_LONG, "%10d", "pixel",
"pos.cartesian.y", "pix"},
{"XPEAK_WORLD", "World-x coordinate of the brightest pixel",
&outobj2.peakxw, H_FLOAT, T_DOUBLE, "%15.10e", "deg",
"pos.eq.ra", "deg"},
{"YPEAK_WORLD", "World-y coordinate of the brightest pixel",
&outobj2.peakyw, H_FLOAT, T_DOUBLE, "%15.10e", "deg",
"pos.eq.dec", "deg"},
{"ALPHAPEAK_SKY", "Right ascension of brightest pix (native)",
&outobj2.peakalphas, H_FLOAT, T_DOUBLE, "%11.7f", "deg",
"pos.eq.ra", "deg"},
{"DELTAPEAK_SKY", "Declination of brightest pix (native)",
&outobj2.peakdeltas, H_FLOAT, T_DOUBLE, "%+11.7f", "deg",
"pos.eq.dec", "deg"},
{"ALPHAPEAK_J2000", "Right ascension of brightest pix (J2000)",
&outobj2.peakalpha2000, H_FLOAT, T_DOUBLE, "%11.7f", "deg",
"pos.eq.ra", "deg"},
{"DELTAPEAK_J2000", "Declination of brightest pix (J2000)",
&outobj2.peakdelta2000, H_FLOAT, T_DOUBLE, "%+11.7f", "deg",
"pos.eq.dec", "deg"},
{"ALPHAPEAK_B1950", "Right ascension of brightest pix (B1950)",
&outobj2.peakalpha1950, H_FLOAT, T_DOUBLE, "%11.7f", "deg",
"pos.eq.ra", "deg"},
{"DELTAPEAK_B1950", "Declination of brightest pix (B1950)",
&outobj2.peakdelta1950, H_FLOAT, T_DOUBLE, "%+11.7f", "deg",
"pos.eq.dec", "deg"},
{"X_IMAGE", "Object position along x",
&outobj2.sposx, H_FLOAT, T_FLOAT, "%10.3f", "pixel",
"pos.cartesian.x;pos.barycenter;instr.det;meta.main", "pix"},
{"Y_IMAGE", "Object position along y",
&outobj2.sposy, H_FLOAT, T_FLOAT, "%10.3f", "pixel",
"pos.cartesian.y;pos.barycenter;instr.det;meta.main", "pix"},
{"X_IMAGE_DBL", "Object position along x (double precision)",
&outobj2.posx, H_FLOAT, T_DOUBLE, "%10.3f", "pixel",
"pos.cartesian.x;pos.barycenter;instr.det", "pix"},
{"Y_IMAGE_DBL", "Object position along y (double precision)",
&outobj2.posy, H_FLOAT, T_DOUBLE, "%10.3f", "pixel",
"pos.cartesian.x;pos.barycenter;instr.det", "pix"},
{"X_WORLD", "Barycenter position along world x axis",
&outobj2.mxw, H_FLOAT, T_DOUBLE, "%15.10e", "deg",
"pos.eq.ra", "deg"},
{"Y_WORLD", "Barycenter position along world y axis",
&outobj2.myw, H_FLOAT, T_DOUBLE, "%15.10e", "deg",
"pos.eq.dec", "deg"},
{"X_MAMA", "Barycenter position along MAMA x axis",
&outobj2.mamaposx, H_FLOAT, T_DOUBLE, "%8.1f", "m**(-6)",
"pos.cartesian.x;instr.det;pos.barycenter", "um"},
{"Y_MAMA", "Barycenter position along MAMA y axis",
&outobj2.mamaposy, H_FLOAT, T_DOUBLE, "%8.1f", "m**(-6)",
"pos.cartesian.y;instr.det;pos.barycenter", "um"},
{"ALPHA_SKY", "Right ascension of barycenter (native)",
&outobj2.alphas, H_FLOAT, T_DOUBLE, "%11.7f", "deg",
"pos.eq.ra;pos.barycenter", "deg"},
{"DELTA_SKY", "Declination of barycenter (native)",
&outobj2.deltas, H_FLOAT, T_DOUBLE, "%+11.7f", "deg",
"pos.eq.dec;pos.barycenter", "deg"},
{"ALPHA_J2000", "Right ascension of barycenter (J2000)",
&outobj2.alpha2000, H_FLOAT, T_DOUBLE, "%11.7f", "deg",
"pos.eq.ra;pos.barycenter;meta.main", "deg"},
{"DELTA_J2000", "Declination of barycenter (J2000)",
&outobj2.delta2000, H_FLOAT, T_DOUBLE, "%+11.7f", "deg",
"pos.eq.dec;pos.barycenter;meta.main", "deg"},
{"ALPHA_B1950", "Right ascension of barycenter (B1950)",
&outobj2.alpha1950, H_FLOAT, T_DOUBLE, "%11.7f", "deg",
"pos.eq.ra;pos.barycenter", "deg"},
{"DELTA_B1950", "Declination of barycenter (B1950)",
&outobj2.delta1950, H_FLOAT, T_DOUBLE, "%+11.7f", "deg",
"pos.eq.dec;pos.barycenter", "deg"},
{"X2_IMAGE", "Variance along x",
&outobj.mx2, H_EXPO, T_DOUBLE, "%15.10e", "pixel**2",
"src.impactParam;instr.det", "pix2"},
{"Y2_IMAGE", "Variance along y",
&outobj.my2, H_EXPO, T_DOUBLE, "%15.10e", "pixel**2",
"src.impactParam;instr.det", "pix2"},
{"XY_IMAGE", "Covariance between x and y",
&outobj.mxy, H_EXPO, T_DOUBLE, "%15.10e", "pixel**2",
"src.impactParam;instr.det", "pix2"},
{"X2_WORLD", "Variance along X-WORLD (alpha)",
&outobj2.mx2w, H_EXPO, T_DOUBLE, "%15.10e", "deg**2",
"src.impactParam", "deg2"},
{"Y2_WORLD", "Variance along Y-WORLD (delta)",
&outobj2.my2w, H_EXPO, T_DOUBLE, "%15.10e", "deg**2",
"src.impactParam", "deg2"},
{"XY_WORLD", "Covariance between X-WORLD and Y-WORLD",
&outobj2.mxyw, H_EXPO, T_DOUBLE, "%15.10e", "deg**2",
"src.impactParam", "deg2"},
{"CXX_IMAGE", "Cxx object ellipse parameter",
&outobj.cxx, H_EXPO, T_FLOAT, "%12.7e", "pixel**(-2)",
"src.impactParam;instr.det", "pix-2"},
{"CYY_IMAGE", "Cyy object ellipse parameter",
&outobj.cyy, H_EXPO, T_FLOAT, "%12.7e", "pixel**(-2)",
"src.impactParam;instr.det", "pix-2"},
{"CXY_IMAGE", "Cxy object ellipse parameter",
&outobj.cxy, H_EXPO, T_FLOAT, "%12.7e", "pixel**(-2)",
"src.impactParam;instr.det", "pix-2"},
{"CXX_WORLD", "Cxx object ellipse parameter (WORLD units)",
&outobj2.cxxw, H_EXPO, T_FLOAT, "%12.7e", "deg**(-2)",
"src.impactParam", "deg-2"},
{"CYY_WORLD", "Cyy object ellipse parameter (WORLD units)",
&outobj2.cyyw, H_EXPO, T_FLOAT, "%12.7e", "deg**(-2)",
"src.impactParam", "deg-2"},
{"CXY_WORLD", "Cxy object ellipse parameter (WORLD units)",
&outobj2.cxyw, H_EXPO, T_FLOAT, "%12.7e", "deg**(-2)",
"src.impactParam", "deg-2"},
{"A_IMAGE", "Profile RMS along major axis",
&outobj.a, H_FLOAT, T_FLOAT, "%9.3f", "pixel",
"phys.size.smajAxis;instr.det;meta.main", "pix"},
{"B_IMAGE", "Profile RMS along minor axis",
&outobj.b, H_FLOAT, T_FLOAT, "%9.3f", "pixel",
"phys.size.sminAxis;instr.det;meta.main", "pix"},
{"THETA_IMAGE", "Position angle (CCW/x)",
&outobj.theta, H_FLOAT, T_FLOAT, "%5.1f", "deg",
"pos.posAng;instr.det;meta.main", "deg"},
{"A_WORLD", "Profile RMS along major axis (world units)",
&outobj2.aw, H_FLOAT, T_FLOAT, "%12.7g", "deg",
"phys.size.smajAxis;meta.main", "deg"},
{"B_WORLD", "Profile RMS along minor axis (world units)",
&outobj2.bw, H_FLOAT, T_FLOAT, "%12.7g", "deg",
"phys.size.sminAxis;meta.main", "deg"},
{"THETA_WORLD", "Position angle (CCW/world-x)",
&outobj2.thetaw, H_FLOAT, T_FLOAT, "%5.1f", "deg",
"pos.posAng", "deg"},
{"THETA_SKY", "Position angle (east of north) (native)",
&outobj2.thetas, H_FLOAT, T_FLOAT, "%+6.2f", "deg",
"pos.posAng", "deg"},
{"THETA_J2000", "Position angle (east of north) (J2000)",
&outobj2.theta2000, H_FLOAT, T_FLOAT, "%+6.2f", "deg",
"pos.posAng;meta.main", "deg"},
{"THETA_B1950", "Position angle (east of north) (B1950)",
&outobj2.theta1950, H_FLOAT, T_FLOAT, "%+6.2f", "deg",
"pos.posAng", "deg"},
{"ERRX2_IMAGE", "Variance of position along x",
&outobj.poserr_mx2, H_EXPO, T_DOUBLE, "%15.10e", "pixel**2",
"stat.variance;pos.errorEllipse;instr.det", "pix2"},
{"ERRY2_IMAGE", "Variance of position along y",
&outobj.poserr_my2, H_EXPO, T_DOUBLE, "%15.10e", "pixel**2",
"stat.variance;pos.errorEllipse;instr.det", "pix2"},
{"ERRXY_IMAGE", "Covariance of position between x and y",
&outobj.poserr_mxy, H_EXPO, T_DOUBLE, "%15.10e", "pixel**2",
"stat.covariance;pos.errorEllipse;instr.det", "pix2"},
{"ERRX2_WORLD", "Variance of position along X-WORLD (alpha)",
&outobj2.poserr_mx2w, H_EXPO, T_DOUBLE, "%15.10e", "deg**2",
"stat.variance;pos.errorEllipse", "deg2"},
{"ERRY2_WORLD", "Variance of position along Y-WORLD (delta)",
&outobj2.poserr_my2w, H_EXPO, T_DOUBLE, "%15.10e", "deg**2",
"stat.variance;pos.errorEllipse", "deg2"},
{"ERRXY_WORLD", "Covariance of position X-WORLD/Y-WORLD",
&outobj2.poserr_mxyw, H_EXPO, T_DOUBLE, "%15.10e", "deg**2",
"stat.covariance;pos.errorEllipse", "deg2"},
{"ERRCXX_IMAGE", "Cxx error ellipse parameter",
&outobj2.poserr_cxx, H_EXPO, T_FLOAT, "%12.7g", "pixel**(-2)",
"src.impactParam;pos.errorEllipse;instr.det", "pix-2"},
{"ERRCYY_IMAGE", "Cyy error ellipse parameter",
&outobj2.poserr_cyy, H_EXPO, T_FLOAT, "%12.7g", "pixel**(-2)",
"src.impactParam;pos.errorEllipse;instr.det", "pix-2"},
{"ERRCXY_IMAGE", "Cxy error ellipse parameter",
&outobj2.poserr_cxy, H_EXPO, T_FLOAT, "%12.7g", "pixel**(-2)",
"src.impactParam;pos.errorEllipse;instr.det", "pix-2"},
{"ERRCXX_WORLD", "Cxx error ellipse parameter (WORLD units)",
&outobj2.poserr_cxxw, H_EXPO, T_FLOAT, "%12.7g", "deg**(-2)",
"src.impactParam;pos.errorEllipse", "deg-2"},
{"ERRCYY_WORLD", "Cyy error ellipse parameter (WORLD units)",
&outobj2.poserr_cyyw, H_EXPO, T_FLOAT, "%12.7g", "deg**(-2)",
"src.impactParam;pos.errorEllipse", "deg-2"},
{"ERRCXY_WORLD", "Cxy error ellipse parameter (WORLD units)",
&outobj2.poserr_cxyw, H_EXPO, T_FLOAT, "%12.7g", "deg**(-2)",
"src.impactParam;pos.errorEllipse", "deg-2"},
{"ERRA_IMAGE", "RMS position error along major axis",
&outobj2.poserr_a, H_FLOAT, T_FLOAT, "%8.4f", "pixel"
"stat.stdev;stat.max;pos.errorEllipse;instr.det;meta.main", "pix"},
{"ERRB_IMAGE", "RMS position error along minor axis",
&outobj2.poserr_b, H_FLOAT, T_FLOAT, "%8.4f", "pixel",
"stat.stdev;stat.min;pos.errorEllipse;instr.det;meta.main", "pix"},
{"ERRTHETA_IMAGE", "Error ellipse position angle (CCW/x)",
&outobj2.poserr_theta, H_FLOAT, T_FLOAT, "%5.1f", "deg",
"pos.posAng;pos.errorEllipse;instr.det;meta.main", "deg"},
{"ERRA_WORLD", "World RMS position error along major axis",
&outobj2.poserr_aw, H_FLOAT, T_FLOAT, "%12.7g", "deg",
"stat.stdev;stat.max;pos.errorEllipse;meta.main", "deg"},
{"ERRB_WORLD", "World RMS position error along minor axis",
&outobj2.poserr_bw, H_FLOAT, T_FLOAT, "%12.7g", "deg",
"stat.stdev;stat.min;pos.errorEllipse;meta.main", "deg"},
{"ERRTHETA_WORLD", "Error ellipse pos. angle (CCW/world-x)",
&outobj2.poserr_thetaw, H_FLOAT, T_FLOAT, "%5.1f", "deg",
"pos.posAng;pos.errorEllipse", "deg"},
{"ERRTHETA_SKY", "Native error ellipse pos. angle (east of north)",
&outobj2.poserr_thetas, H_FLOAT, T_FLOAT, "%5.1f", "deg",
"pos.posAng;pos.errorEllipse", "deg"},
{"ERRTHETA_J2000", "J2000 error ellipse pos. angle (east of north)",
&outobj2.poserr_theta2000, H_FLOAT, T_FLOAT, "%5.1f", "deg",
"pos.posAng;pos.errorEllipse;meta.main", "deg"},
{"ERRTHETA_B1950", "B1950 error ellipse pos. angle (east of north)",
&outobj2.poserr_theta1950, H_FLOAT, T_FLOAT, "%5.1f", "deg",
"pos.posAng;pos.errorEllipse", "deg"},
{"XWIN_IMAGE", "Windowed position estimate along x",
&outobj2.winpos_x, H_FLOAT, T_DOUBLE, "%10.3f", "pixel",
"pos.cartesian.x;instr.det", "pix"},
{"YWIN_IMAGE", "Windowed position estimate along y",
&outobj2.winpos_y, H_FLOAT, T_DOUBLE, "%10.3f", "pixel",
"pos.cartesian.y;instr.det", "pix"},
{"XWIN_WORLD", "Windowed position along world x axis",
&outobj2.winpos_xw, H_FLOAT, T_DOUBLE, "%15.10e", "deg",
"pos.eq.ra", "deg"},
{"YWIN_WORLD", "Windowed position along world y axis",
&outobj2.winpos_yw, H_FLOAT, T_DOUBLE, "%15.10e", "deg",
"pos.eq.dec", "deg"},
{"ALPHAWIN_SKY", "Windowed right ascension (native)",
&outobj2.winpos_alphas, H_FLOAT, T_DOUBLE, "%11.7f", "deg",
"pos.eq.ra", "deg"},
{"DELTAWIN_SKY", "Windowed declination (native)",
&outobj2.winpos_deltas, H_FLOAT, T_DOUBLE, "%+11.7f", "deg",
"pos.eq.dec", "deg"},
{"ALPHAWIN_J2000", "Windowed right ascension (J2000)",
&outobj2.winpos_alpha2000, H_FLOAT, T_DOUBLE, "%11.7f", "deg",
"pos.eq.ra", "deg"},
{"DELTAWIN_J2000", "windowed declination (J2000)",
&outobj2.winpos_delta2000, H_FLOAT, T_DOUBLE, "%+11.7f", "deg",
"pos.eq.dec", "deg"},
{"ALPHAWIN_B1950", "Windowed right ascension (B1950)",
&outobj2.winpos_alpha1950, H_FLOAT, T_DOUBLE, "%11.7f", "deg",
"pos.eq.ra", "deg"},
{"DELTAWIN_B1950", "Windowed declination (B1950)",
&outobj2.winpos_delta1950, H_FLOAT, T_DOUBLE, "%+11.7f", "deg",
"pos.eq.deg", "deg"},
{"X2WIN_IMAGE", "Windowed variance along x",
&outobj2.win_mx2, H_EXPO, T_DOUBLE, "%15.10e", "pixel**2",
"src.impactParam;instr.det", "pix2"},
{"Y2WIN_IMAGE", "Windowed variance along y",
&outobj2.win_my2, H_EXPO, T_DOUBLE, "%15.10e", "pixel**2",
"src.impactParam;instr.det", "pix2"},
{"XYWIN_IMAGE", "Windowed covariance between x and y",
&outobj2.win_mxy, H_EXPO, T_DOUBLE, "%15.10e", "pixel**2",
"src.impactParam;instr.det", "pix2"},
{"X2WIN_WORLD", "Windowed variance along X-WORLD (alpha)",
&outobj2.win_mx2w, H_EXPO, T_DOUBLE, "%15.10e", "deg**2",
"src.impactParam", "deg2"},
{"Y2WIN_WORLD", "Windowed variance along Y-WORLD (delta)",
&outobj2.win_my2w, H_EXPO, T_DOUBLE, "%15.10e", "deg**2",
"src.impactParam", "deg2"},
{"XYWIN_WORLD", "Windowed covariance between X-WORLD and Y-WORLD",
&outobj2.win_mxyw, H_EXPO, T_DOUBLE, "%15.10e", "deg**2",
"src.impactParam", "deg2"},
{"CXXWIN_IMAGE", "Windowed Cxx object ellipse parameter",
&outobj2.win_cxx, H_EXPO, T_FLOAT, "%12.7e", "pixel**(-2)",
"src.impactParam;instr.det", "pix-2"},
{"CYYWIN_IMAGE", "Windowed Cyy object ellipse parameter",
&outobj2.win_cyy, H_EXPO, T_FLOAT, "%12.7e", "pixel**(-2)",
"src.impactParam;instr.det", "pix-2"},
{"CXYWIN_IMAGE", "Windowed Cxy object ellipse parameter",
&outobj2.win_cxy, H_EXPO, T_FLOAT, "%12.7e", "pixel**(-2)",
"src.impactParam;instr.det", "pix-2"},
{"CXXWIN_WORLD", "Windowed Cxx object ellipse parameter (WORLD units)",
&outobj2.win_cxxw, H_EXPO, T_FLOAT, "%12.7e", "deg**(-2)",
"src.impactParam", "deg-2"},
{"CYYWIN_WORLD", "Windowed Cyy object ellipse parameter (WORLD units)",
&outobj2.win_cyyw, H_EXPO, T_FLOAT, "%12.7e", "deg**(-2)",
"src.impactParam", "deg-2"},
{"CXYWIN_WORLD", "Windowed Cxy object ellipse parameter (WORLD units)",
&outobj2.win_cxyw, H_EXPO, T_FLOAT, "%12.7e", "deg**(-2)",
"src.impactParam", "deg-2"},
{"AWIN_IMAGE", "Windowed profile RMS along major axis",
&outobj2.win_a, H_FLOAT, T_FLOAT, "%9.3f", "pixel",
"phys.size.smajAxis;instr.det", "pix"},
{"BWIN_IMAGE", "Windowed profile RMS along minor axis",
&outobj2.win_b, H_FLOAT, T_FLOAT, "%9.3f", "pixel",
"phys.size.sminAxis;instr.det", "pix"},
{"THETAWIN_IMAGE", "Windowed position angle (CCW/x)",
&outobj2.win_theta, H_FLOAT, T_FLOAT, "%5.1f", "deg",
"pos.posAng;instr.det", "deg"},
{"AWIN_WORLD", "Windowed profile RMS along major axis (world units)",
&outobj2.win_aw, H_FLOAT, T_FLOAT, "%12.7g", "deg",
"phys.size.smajAxis", "deg"},
{"BWIN_WORLD", "Windowed profile RMS along minor axis (world units)",
&outobj2.win_bw, H_FLOAT, T_FLOAT, "%12.7g", "deg",
"phys.size.sminAxis", "deg"},
{"THETAWIN_WORLD", "Windowed position angle (CCW/world-x)",
&outobj2.win_thetaw, H_FLOAT, T_FLOAT, "%5.1f", "deg",
"pos.posAng", "deg"},
{"THETAWIN_SKY", "Windowed position angle (east of north) (native)",
&outobj2.win_thetas, H_FLOAT, T_FLOAT, "%+6.2f", "deg",
"pos.posAng", "deg"},
{"THETAWIN_J2000", "Windowed position angle (east of north) (J2000)",
&outobj2.win_theta2000, H_FLOAT, T_FLOAT, "%+6.2f", "deg",
"pos.posAng", "deg"},
{"THETAWIN_B1950", "Windowed position angle (east of north) (B1950)",
&outobj2.win_theta1950, H_FLOAT, T_FLOAT, "%+6.2f", "deg",
"pos.posAng", "deg"},
{"ERRX2WIN_IMAGE", "Variance of windowed pos along x",
&outobj2.winposerr_mx2, H_EXPO, T_DOUBLE, "%15.10e", "pixel**2",
"stat.variance;pos.errorEllipse;instr.det", "pix2"},
{"ERRY2WIN_IMAGE", "Variance of windowed pos along y",
&outobj2.winposerr_my2, H_EXPO, T_DOUBLE, "%15.10e", "pixel**2",
"stat.variance;pos.errorEllipse;instr.det", "pix2"},
{"ERRXYWIN_IMAGE", "Covariance of windowed pos between x and y",
&outobj2.winposerr_mxy, H_EXPO, T_DOUBLE, "%15.10e", "pixel**2",
"stat.covariance;pos.errorEllipse;instr.det", "pix2"},
{"ERRX2WIN_WORLD", "Variance of windowed pos along X-WORLD (alpha)",
&outobj2.winposerr_mx2w, H_EXPO, T_DOUBLE, "%15.10e", "deg**2",
"stat.variance;pos.errorEllipse", "deg2"},
{"ERRY2WIN_WORLD", "Variance of windowed pos along Y-WORLD (delta)",
&outobj2.winposerr_my2w, H_EXPO, T_DOUBLE, "%15.10e", "deg**2",
"stat.variance;pos.errorEllipse", "deg2"},
{"ERRXYWIN_WORLD", "Covariance of windowed pos X-WORLD/Y-WORLD",
&outobj2.winposerr_mxyw, H_EXPO, T_DOUBLE, "%15.10e", "deg**2",
"stat.covariance;pos.errorEllipse", "deg2"},
{"ERRCXXWIN_IMAGE", "Cxx windowed error ellipse parameter",
&outobj2.winposerr_cxx, H_EXPO, T_FLOAT, "%12.7g", "pixel**(-2)",
"src.impactParam;pos.errorEllipse;instr.det", "pix-2"},
{"ERRCYYWIN_IMAGE", "Cyy windowed error ellipse parameter",
&outobj2.winposerr_cyy, H_EXPO, T_FLOAT, "%12.7g", "pixel**(-2)",
"src.impactParam;pos.errorEllipse;instr.det", "pix-2"},
{"ERRCXYWIN_IMAGE", "Cxy windowed error ellipse parameter",
&outobj2.winposerr_cxy, H_EXPO, T_FLOAT, "%12.7g", "pixel**(-2)",
"src.impactParam;pos.errorEllipse;instr.det", "pix-2"},
{"ERRCXXWIN_WORLD", "Cxx windowed error ellipse parameter (WORLD units)",
&outobj2.winposerr_cxxw, H_EXPO, T_FLOAT, "%12.7g", "deg**(-2)",
"src.impactParam;pos.errorEllipse", "deg-2"},
{"ERRCYYWIN_WORLD", "Cyy windowed error ellipse parameter (WORLD units)",
&outobj2.winposerr_cyyw, H_EXPO, T_FLOAT, "%12.7g", "deg**(-2)",
"src.impactParam;pos.errorEllipse", "deg-2"},
{"ERRCXYWIN_WORLD", "Cxy windowed error ellipse parameter (WORLD units)",
&outobj2.winposerr_cxyw, H_EXPO, T_FLOAT, "%12.7g", "deg**(-2)",
"src.impactParam;pos.errorEllipse", "deg-2"},
{"ERRAWIN_IMAGE", "RMS windowed pos error along major axis",
&outobj2.winposerr_a, H_FLOAT, T_FLOAT, "%8.4f", "pixel",
"stat.stdev;stat.max;pos.errorEllipse;instr.det", "pix"},
{"ERRBWIN_IMAGE", "RMS windowed pos error along minor axis",
&outobj2.winposerr_b, H_FLOAT, T_FLOAT, "%8.4f", "pixel",
"stat.stdev;stat.min;pos.errorEllipse;instr.det", "pix"},
{"ERRTHETAWIN_IMAGE", "Windowed error ellipse pos angle (CCW/x)",
&outobj2.winposerr_theta, H_FLOAT, T_FLOAT, "%5.1f", "deg",
"pos.posAng;pos.errorEllipse;instr.det", "deg"},
{"ERRAWIN_WORLD", "World RMS windowed pos error along major axis",
&outobj2.winposerr_aw, H_FLOAT, T_FLOAT, "%12.7g", "deg",
"stat.stdev;stat.max;pos.errorEllipse", "deg"},
{"ERRBWIN_WORLD", "World RMS windowed pos error along minor axis",
&outobj2.winposerr_bw, H_FLOAT, T_FLOAT, "%12.7g", "deg",
"stat.stdev;stat.min;pos.errorEllipse", "deg"},
{"ERRTHETAWIN_WORLD", "Windowed error ellipse pos. angle (CCW/world-x)",
&outobj2.winposerr_thetaw, H_FLOAT, T_FLOAT, "%5.1f", "deg",
"pos.posAng;pos.errorEllipse", "deg"},
{"ERRTHETAWIN_SKY", "Native windowed error ellipse pos. angle (east of north)",
&outobj2.winposerr_thetas, H_FLOAT, T_FLOAT, "%5.1f", "deg",
"pos.posAng;pos.errorEllipse", "deg"},
{"ERRTHETAWIN_J2000", "J2000 windowed error ellipse pos. angle (east of north)",
&outobj2.winposerr_theta2000, H_FLOAT, T_FLOAT, "%5.1f", "deg",
"pos.posAng;pos.errorEllipse", "deg"},
{"ERRTHETAWIN_B1950", "B1950 windowed error ellipse pos. angle (east of north)",
&outobj2.winposerr_theta1950, H_FLOAT, T_FLOAT, "%5.1f", "deg",
"pos.posAng;pos.errorEllipse", "deg"},
{"NITER_WIN", "Number of iterations for WIN centering",
&outobj2.winpos_niter, H_INT, T_SHORT, "%3d", "",
"meta.number", ""},
{"MU_THRESHOLD", "Detection threshold above background",
&outobj2.threshmu, H_FLOAT, T_FLOAT, "%8.4f", "mag * arcsec**(-2)",
"instr.sensitivity;phot.mag.sb", "mag.arcsec-2"},
{"MU_MAX", "Peak surface brightness above background",
&outobj2.maxmu, H_FLOAT, T_FLOAT, "%8.4f", "mag * arcsec**(-2)",
"phot.mag.sb;stat.max", "mag.arcsec-2"},
{"ISOAREA_WORLD", "Isophotal area above Analysis threshold",
&outobj2.npixw, H_FLOAT, T_FLOAT, "%12.7g", "deg**2",
"phys.angArea", "deg2"},
{"ISOAREAF_WORLD", "Isophotal area (filtered) above Detection threshold",
&outobj2.fdnpixw, H_FLOAT, T_FLOAT, "%12.7g", "deg**2",
"phys.angArea", "deg2"},
{"ISO0", "Isophotal area at level 0",
&outobj.iso[0], H_INT, T_LONG, "%8d", "pixel**2",
"phys.area;instr.det", "pix2"},
{"ISO1", "Isophotal area at level 1",
&outobj.iso[1], H_INT, T_LONG, "%8d", "pixel**2",
"phys.area;instr.det", "pix2"},
{"ISO2", "Isophotal area at level 2",
&outobj.iso[2], H_INT, T_LONG, "%8d", "pixel**2",
"phys.area;instr.det", "pix2"},
{"ISO3", "Isophotal area at level 3",
&outobj.iso[3], H_INT, T_LONG, "%8d", "pixel**2",
"phys.area;instr.det", "pix2"},
{"ISO4", "Isophotal area at level 4",
&outobj.iso[4], H_INT, T_LONG, "%8d", "pixel**2",
"phys.area;instr.det", "pix2"},
{"ISO5", "Isophotal area at level 5",
&outobj.iso[5], H_INT, T_LONG, "%8d", "pixel**2",
"phys.area;instr.det", "pix2"},
{"ISO6", "Isophotal area at level 6",
&outobj.iso[6], H_INT, T_LONG, "%8d", "pixel**2",
"phys.area;instr.det", "pix2"},
{"ISO7", "Isophotal area at level 7",
&outobj.iso[7], H_INT, T_LONG, "%8d", "pixel**2",
"phys.area;instr.det", "pix2"},
{"FLAGS", "Extraction flags",
&outobj.flag, H_INT, T_SHORT, "%3d", "",
"meta.code.qual", ""},
{"FLAGS_WEIGHT", "Weighted extraction flags",
&outobj.wflag, H_INT, T_SHORT, "%1d", "",
"meta.code.qual", ""},
{"FLAGS_WIN", "Flags for WINdowed parameters",
&outobj2.win_flag, H_INT, T_SHORT, "%3d", "",
"meta.code.qual", ""},
{"IMAFLAGS_ISO", "FLAG-image flags OR'ed over the iso. profile",
outobj.imaflag, H_INT, T_LONG, "%9u", "",
"meta.code.qual", "", 1, &prefs.imaflag_size},
{"NIMAFLAGS_ISO", "Number of flagged pixels entering IMAFLAGS_ISO",
outobj.imanflag, H_INT, T_LONG, "%9d", "",
"meta.number", "", 1, &prefs.imanflag_size},
{"FWHM_IMAGE", "FWHM assuming a gaussian core",
&outobj.fwhm, H_FLOAT, T_FLOAT, "%8.2f", "pixel",
"phys.size.diameter;instr.det.psf", "pix"},
{"FWHM_WORLD", "FWHM assuming a gaussian core",
&outobj2.fwhmw, H_FLOAT, T_FLOAT, "%12.7g", "deg",
"phys.angSize;instr.det.psf", "deg"},
{"ELONGATION", "A_IMAGE/B_IMAGE",
&outobj2.elong, H_FLOAT, T_FLOAT, "%8.3f", "",
"src.ellipticity;arith.ratio;instr.det", ""},
{"ELLIPTICITY", "1 - B_IMAGE/A_IMAGE",
&outobj2.ellip, H_FLOAT, T_FLOAT, "%8.3f", "",
"src.ellipticity;instr.det ", ""},
{"POLAR_IMAGE", "(A_IMAGE^2 - B_IMAGE^2)/(A_IMAGE^2 + B_IMAGE^2)",
&outobj2.polar, H_FLOAT, T_FLOAT, "%7.5f", "",
"src.ellipticity;instr.det", ""},
{"POLAR_WORLD", "(A_WORLD^2 - B_WORLD^2)/(A_WORLD^2 + B_WORLD^2)",
&outobj2.polarw, H_FLOAT, T_FLOAT, "%7.5f", "",
"src.ellipticity", ""},
{"POLARWIN_IMAGE", "(AWIN^2 - BWIN^2)/(AWIN^2 + BWIN^2)",
&outobj2.win_polar, H_FLOAT, T_FLOAT, "%7.5f", "",
"src.ellipticity;instr.det", ""},
{"POLARWIN_WORLD", "(AWIN^2 - BWIN^2)/(AWIN^2 + BWIN^2)",
&outobj2.win_polarw, H_FLOAT, T_FLOAT, "%7.5f", "",
"src.ellipticity", ""},
{"CLASS_STAR", "S/G classifier output",
&outobj2.sprob, H_FLOAT, T_FLOAT, "%5.2f", "",
"src.class.starGalaxy", ""},
{"VIGNET", "Pixel data around detection",
&outobj2.vignet, H_FLOAT, T_FLOAT, "%12.7g", "count",
"obs.image", "ct", 2, prefs.vignetsize},
{"VIGNET_SHIFT", "Pixel data around detection, corrected for shift",
&outobj2.vigshift, H_FLOAT, T_FLOAT, "%12.7g", "count",
"obs.image", "ct", 2, prefs.vigshiftsize},
{"VECTOR_ASSOC", "ASSOCiated parameter vector",
&outobj2.assoc, H_FLOAT, T_FLOAT, "%12.7g", "",
"src", "", 1, &prefs.assoc_size},
{"NUMBER_ASSOC", "Number of ASSOCiated IDs",
&outobj2.assoc_number, H_INT, T_LONG, "%10d", "",
"meta.number;src", ""},
{"THRESHOLDMAX", "Maximum threshold possible for detection",
&outobj.dthresh, H_FLOAT, T_FLOAT, "%12.7g", "count",
"phot.flux.sb;stat.max", "ct"},
{"FLUX_GROWTH", "Cumulated growth-curve",
&outobj2.flux_growth, H_FLOAT, T_FLOAT, "%12.7g", "count",
"phot.count", "ct", 1, &prefs.flux_growthsize},
{"FLUX_GROWTHSTEP", "Step for growth-curves",
&outobj2.flux_growthstep, H_FLOAT, T_FLOAT, "%10.3f", "pixel",
"pos.distance", "pix"},
{"MAG_GROWTH", "Cumulated magnitude growth-curve",
&outobj2.mag_growth, H_FLOAT, T_FLOAT, "%8.4f", "mag",
"phot.mag", "mag", 1, &prefs.mag_growthsize},
{"MAG_GROWTHSTEP", "Step for growth-curves",
&outobj2.mag_growthstep, H_FLOAT, T_FLOAT, "%10.3f", "pixel",
"pos.distance", "pix"},
{"FLUX_RADIUS", "Fraction-of-light radii",
&outobj2.flux_radius, H_FLOAT, T_FLOAT, "%10.3f", "pixel",
"phys.size.radius;instr.det", "pix", 1, &prefs.flux_radiussize},
{"XPSF_IMAGE", "X coordinate from PSF-fitting",
&outobj2.x_psf, H_FLOAT, T_FLOAT, "%10.3f", "pixel",
"pos.cartesian.x;stat.fit.param;instr.det", "pix", 1, &prefs.psf_xsize},
{"YPSF_IMAGE", "Y coordinate from PSF-fitting",
&outobj2.y_psf, H_FLOAT, T_FLOAT, "%10.3f", "pixel",
"pos.cartesian.y;stat.fit.param;instr.det", "pix", 1, &prefs.psf_ysize},
{"XPSF_WORLD", "PSF position along world x axis",
&outobj2.xw_psf, H_FLOAT, T_DOUBLE, "%15.10e", "deg",
"pos.eq.ra;stat.fit.param", "deg", 1, &prefs.psf_xwsize},
{"YPSF_WORLD", "PSF position along world y axis",
&outobj2.yw_psf, H_FLOAT, T_DOUBLE, "%15.10e", "deg",
"pos.eq.dec;stat.fit.param", "deg", 1, &prefs.psf_ywsize},
{"ALPHAPSF_SKY", "Right ascension of the fitted PSF (native)",
&outobj2.alphas_psf, H_FLOAT, T_DOUBLE, "%11.7f", "deg",
"pos.eq.ra;stat.fit.param", "deg", 1, &prefs.psf_alphassize},
{"DELTAPSF_SKY", "Declination of the fitted PSF (native)",
&outobj2.deltas_psf, H_FLOAT, T_DOUBLE, "%+11.7f", "deg",
"pos.eq.dec;stat.fit.param", "deg", 1, &prefs.psf_deltassize},
{"ALPHAPSF_J2000", "Right ascension of the fitted PSF (J2000)",
&outobj2.alpha2000_psf, H_FLOAT, T_DOUBLE, "%11.7f", "deg",
"pos.eq.ra;stat.fit.param", "deg", 1, &prefs.psf_alpha2000size},
{"DELTAPSF_J2000", "Declination of the fitted PSF (J2000)",
&outobj2.delta2000_psf, H_FLOAT, T_DOUBLE, "%+11.7f", "deg",
"pos.eq.dec;stat.fit.param", "deg", 1, &prefs.psf_delta2000size},
{"ALPHAPSF_B1950", "Right ascension of the fitted PSF (B1950)",
&outobj2.alpha1950_psf, H_FLOAT, T_DOUBLE, "%11.7f", "deg",
"pos.eq.ra;stat.fit.param", "deg", 1, &prefs.psf_alpha1950size},
{"DELTAPSF_B1950", "Declination of the fitted PSF (B1950)",
&outobj2.delta1950_psf, H_FLOAT, T_DOUBLE, "%+11.7f", "deg",
"pos.eq.dec;stat.fit.param", "deg", 1, &prefs.psf_delta1950size},
{"FLUX_PSF", "Flux from PSF-fitting",
&outobj2.flux_psf, H_FLOAT, T_FLOAT, "%12.7g", "count",
"phot.count;stat.fit.param", "ct", 1, &prefs.psf_fluxsize},
{"FLUXERR_PSF", "RMS flux error for PSF-fitting",
&outobj2.fluxerr_psf, H_FLOAT, T_FLOAT, "%12.7g", "count",
"stat.stdev;phot.count", "ct", 1, &prefs.psf_fluxerrsize},
{"MAG_PSF", "Magnitude from PSF-fitting",
&outobj2.mag_psf, H_FLOAT, T_FLOAT, "%8.4f", "mag",
"phot.mag", "mag", 1, &prefs.psf_magsize},
{"MAGERR_PSF", "RMS magnitude error from PSF-fitting",
&outobj2.magerr_psf, H_FLOAT, T_FLOAT, "%8.4f", "mag",
"stat.stdev;phot.mag", "mag", 1, &prefs.psf_magsize},
{"NITER_PSF", "Number of iterations for PSF-fitting",
&outobj2.niter_psf, H_INT, T_SHORT, "%3d", "",
"meta.number", ""},
{"CHI2_PSF", "Reduced chi2 from PSF-fitting",
&outobj2.chi2_psf, H_FLOAT, T_FLOAT, "%9.4g", "",
"stat.fit.chi2", ""},
{"ERRX2PSF_IMAGE", "Variance of PSF position along x",
&outobj2.poserrmx2_psf, H_EXPO, T_DOUBLE, "%15.10e", "pixel**2",
"stat.variance;pos.errorEllipse;instr.det", "pix2"},
{"ERRY2PSF_IMAGE", "Variance of PSF position along y",
&outobj2.poserrmy2_psf, H_EXPO, T_DOUBLE, "%15.10e", "pixel**2",
"stat.variance;pos.errorEllipse;instr.det", "pix2"},
{"ERRXYPSF_IMAGE", "Covariance of PSF position between x and y",
&outobj2.poserrmxy_psf, H_EXPO, T_DOUBLE, "%15.10e", "pixel**2",
"stat.covariance;pos.errorEllipse;instr.det", "pix2"},
{"ERRX2PSF_WORLD", "Variance of PSF position along X-WORLD (alpha)",
&outobj2.poserrmx2w_psf, H_EXPO, T_DOUBLE, "%15.10e", "deg**2",
"stat.variance;pos.errorEllipse", "deg2"},
{"ERRY2PSF_WORLD", "Variance of PSF position along Y-WORLD (delta)",
&outobj2.poserrmy2w_psf, H_EXPO, T_DOUBLE, "%15.10e", "deg**2",
"stat.variance;pos.errorEllipse", "deg2"},
{"ERRXYPSF_WORLD", "Covariance of PSF position X-WORLD/Y-WORLD",
&outobj2.poserrmxyw_psf, H_EXPO, T_DOUBLE, "%15.10e", "deg**2",
"stat.covariance;pos.errorEllipse", "deg2"},
{"ERRCXXPSF_IMAGE", "Cxx PSF error ellipse parameter",
&outobj2.poserrcxx_psf, H_EXPO, T_FLOAT, "%12.7g", "pixel**(-2)",
"src.impactParam;pos.errorEllipse;instr.det", "pix-2"},
{"ERRCYYPSF_IMAGE", "Cyy PSF error ellipse parameter",
&outobj2.poserrcyy_psf, H_EXPO, T_FLOAT, "%12.7g", "pixel**(-2)",
"src.impactParam;pos.errorEllipse;instr.det", "pix-2"},
{"ERRCXYPSF_IMAGE", "Cxy PSF error ellipse parameter",
&outobj2.poserrcxy_psf, H_EXPO, T_FLOAT, "%12.7g", "pixel**(-2)",
"src.impactParam;pos.errorEllipse;instr.det", "pix-2"},
{"ERRCXXPSF_WORLD", "Cxx PSF error ellipse parameter (WORLD units)",
&outobj2.poserrcxxw_psf, H_EXPO, T_FLOAT, "%12.7g", "deg**(-2)",
"src.impactParam;pos.errorEllipse", "deg-2"},
{"ERRCYYPSF_WORLD", "Cyy PSF error ellipse parameter (WORLD units)",
&outobj2.poserrcyyw_psf, H_EXPO, T_FLOAT, "%12.7g", "deg**(-2)",
"src.impactParam;pos.errorEllipse", "deg-2"},
{"ERRCXYPSF_WORLD", "Cxy PSF error ellipse parameter (WORLD units)",
&outobj2.poserrcxyw_psf, H_EXPO, T_FLOAT, "%12.7g", "deg**(-2)",
"src.impactParam;pos.errorEllipse", "deg-2"},
{"ERRAPSF_IMAGE", "PSF RMS position error along major axis",
&outobj2.poserra_psf, H_FLOAT, T_FLOAT, "%8.4f", "pixel",
"stat.stdev;stat.max;pos.errorEllipse;instr.det", "pix"},
{"ERRBPSF_IMAGE", "PSF RMS position error along minor axis",
&outobj2.poserrb_psf, H_FLOAT, T_FLOAT, "%8.4f", "pixel",
"stat.stdev;stat.min;pos.errorEllipse;instr.det", "pix"},
{"ERRTHTPSF_IMAGE", "PSF error ellipse position angle (CCW/x)",
&outobj2.poserrtheta_psf, H_FLOAT, T_FLOAT, "%5.1f", "deg",
"pos.posAng;pos.errorEllipse;instr.det", "deg"},
{"ERRAPSF_WORLD", "World PSF RMS position error along major axis",
&outobj2.poserraw_psf, H_FLOAT, T_FLOAT, "%12.7g", "pixel",
"stat.stdev;stat.max;pos.errorEllipse", "deg"},
{"ERRBPSF_WORLD", "World PSF RMS position error along minor axis",
&outobj2.poserrbw_psf, H_FLOAT, T_FLOAT, "%12.7g", "pixel",
"stat.stdev;stat.min;pos.errorEllipse", "deg"},
{"ERRTHTPSF_WORLD", "PSF error ellipse pos. angle (CCW/world-x)",
&outobj2.poserrthetaw_psf, H_FLOAT, T_FLOAT, "%5.1f", "deg",
"pos.posAng;pos.errorEllipse", "deg"},
{"ERRTHTPSF_SKY", "Native PSF error ellipse pos. angle (east of north)",
&outobj2.poserrthetas_psf, H_FLOAT, T_FLOAT, "%5.1f", "deg",
"pos.posAng;pos.errorEllipse", "deg"},
{"ERRTHTPSF_J2000", "J2000 PSF error ellipse pos. angle (east of north)",
&outobj2.poserrtheta2000_psf, H_FLOAT, T_FLOAT, "%5.1f", "deg",
"pos.posAng;pos.errorEllipse", "deg"},
{"ERRTHTPSF_B1950", "B1950 PSF error ellipse pos. angle (east of north)",
&outobj2.poserrtheta1950_psf, H_FLOAT, T_FLOAT, "%5.1f", "deg",
"pos.posAng;pos.errorEllipse", "deg"},
{"X2PC_IMAGE", "PC variance along x",
&outobj2.mx2_pc, H_EXPO, T_DOUBLE, "%15.10e", "pixel**2",
"src.impactParam;instr.det", "pix2"},
{"Y2PC_IMAGE", "PC variance along y",
&outobj2.my2_pc, H_EXPO, T_DOUBLE, "%15.10e", "pixel**2",
"src.impactParam;instr.det", "pix2"},
{"XYPC_IMAGE", "PC covariance between x and y",
&outobj2.mxy_pc, H_EXPO, T_DOUBLE, "%15.10e", "pixel**2",
"src.impactParam;instr.det", "pix2"},
{"APC_IMAGE", "PC profile RMS along major axis",
&outobj2.a_pc, H_FLOAT, T_FLOAT, "%8.2f", "pixel",
"phys.size.smajAxis;instr.det", "pix"},
{"BPC_IMAGE", "PC profile RMS along minor axis",
&outobj2.b_pc, H_FLOAT, T_FLOAT, "%8.2f", "pixel",
"phys.size.sminAxis;instr.det", "pix"},
{"THETAPC_IMAGE", "PC position angle (CCW/x)",
&outobj2.theta_pc, H_FLOAT, T_FLOAT, "%5.1f", "deg",
"pos.posAng;instr.det", "deg"},
{"PC", "Principal components",
&outobj2.vector_pc, H_FLOAT, T_FLOAT, "%15.10e", "",
"src.morph.param", "", 1, &prefs.pc_vectorsize},
/*
{"RETINOUT", T_FLOAT, &outobj.retinout, "%13g "},
*/
{""}
};
/*
pc.c
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: SExtractor
*
* Author: E.BERTIN (IAP)
*
* Contents: Stuff related to Principal Component Analysis (PCA).
*
* Last modify: 27/11/2003
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "define.h"
#include "globals.h"
#include "prefs.h"
#include "fits/fitscat.h"
#include "check.h"
#include "image.h"
#include "poly.h"
#include "psf.h"
static obj2struct *obj2 = &outobj2;
/****** pc_end ***************************************************************
PROTO void pc_end(pcstruct *pc)
PURPOSE Free a PC structure and everything it contains.
INPUT pcstruct pointer.
OUTPUT -.
NOTES -.
AUTHOR E. Bertin (IAP, Leiden observatory & ESO)
VERSION 15/07/99
***/
void pc_end(pcstruct *pc)
{
int i;
free(pc->maskcomp);
free(pc->omaskcomp);
free(pc->omasksize);
free(pc->maskcurr);
free(pc->masksize);
free(pc->mx2);
free(pc->my2);
free(pc->mxy);
free(pc->flux);
free(pc->bt);
if (pc->code)
{
free(pc->code->pc);
for (i=0; i<pc->code->nparam;i++)
free(pc->code->param[i]);
free(pc->code->param);
free(pc->code);
}
free(pc);
return;
}
/********************************** pc_load **********************************/
/*
Load the PC data from a FITS file.
*/
pcstruct *pc_load(catstruct *cat)
{
pcstruct *pc;
tabstruct *tab;
keystruct *key;
codestruct *code;
char *head, str[80], *ci, *filename;
int i, ncode,nparam;
if (!(tab = name_to_tab(cat, "PC_DATA", 0)))
return NULL;
filename = cat->filename;
/* OK, we now allocate memory for the PC structure itself */
QCALLOC(pc, pcstruct, 1);
/* Store a short copy of the PC filename */
if ((ci=strrchr(filename, '/')))
strcpy(pc->name, ci+1);
else
strcpy(pc->name, filename);
/* Load important scalars (which are stored as FITS keywords) */
head = tab->headbuf;
/* Dimensionality of the PC mask */
if (fitsread(head, "PCNAXIS", &pc->maskdim, H_INT, T_LONG) != RETURN_OK)
return NULL;
if (pc->maskdim<2 || pc->maskdim>4)
error(EXIT_FAILURE, "*Error*: wrong dimensionality for the PC "
"mask in ", filename);
QMALLOC(pc->masksize, int, pc->maskdim);
for (i=0; i<pc->maskdim; i++)
pc->masksize[i] = 1;
pc->masknpix = 1;
for (i=0; i<pc->maskdim; i++)
{
sprintf(str, "PCAXIS%1d ", i+1);
if (fitsread(head, str, &pc->masksize[i], H_INT,T_LONG) != RETURN_OK)
goto headerror;
pc->masknpix *= pc->masksize[i];
}
pc->npc = pc->masksize[pc->maskdim-1];
ncode = 0;
fitsread(head, "NCODE", &ncode, H_INT, T_LONG);
fitsread(head, "NCODEPAR", &nparam, H_INT, T_LONG);
/* Load the PC mask data */
key = read_key(tab, "PC_CONVMASK");
pc->maskcomp = key->ptr;
key = read_key(tab, "PC_MASK");
pc->omaskcomp = key->ptr;
pc->omaskdim = key->naxis;
pc->omasknpix = 1;
QMALLOC(pc->omasksize, int, pc->omaskdim);
for (i=0; i<pc->omaskdim; i++)
pc->omasknpix *= (pc->omasksize[i] = key->naxisn[i]);
key = read_key(tab, "PC_MX2");
pc->mx2 = key->ptr;
key = read_key(tab, "PC_MY2");
pc->my2 = key->ptr;
key = read_key(tab, "PC_MXY");
pc->mxy = key->ptr;
key = read_key(tab, "PC_FLUX");
pc->flux = key->ptr;
key = read_key(tab, "PC_BRATIO");
pc->bt = key->ptr;
if (ncode)
{
QMALLOC(pc->code, codestruct, 1);
code = pc->code;
QMALLOC(code->param, float *, nparam);
QMALLOC(code->parammod, int, nparam);
code->ncode = ncode;
code->nparam = nparam;
key = read_key(tab, "CODE_PC");
code->pc = (float *)key->ptr;
for (i=0; i<nparam; i++)
{
sprintf(str, "CODE_P%d", i+1);
key = read_key(tab, str);
code->param[i] = (float *)key->ptr;
sprintf(str, "CODE_M%d", i+1);
fitsread(head, str, &code->parammod[i], H_INT, T_LONG);
}
}
QMALLOC(pc->maskcurr, double, pc->masksize[0]*pc->masksize[1]*pc->npc);
/* But don't touch my arrays!! */
blank_keys(tab);
return pc;
headerror:
error(EXIT_FAILURE, "*Error*: Incorrect or obsolete PC data in ", filename);
return NULL;
}
/********************************** pc_fit **********************************/
/*
Fit the PC data to the current data.
*/
void pc_fit(psfstruct *psf, double *data, double *weight,
int width, int height,int ix, int iy,
double dx, double dy, int npc, float backrms)
{
pcstruct *pc;
checkstruct *check;
codestruct *code;
double *basis,*basis0, *cpix,*cpix0, *pcshift,*wpcshift,
*spix,*wspix, *w, *sumopc,*sumopct, *checkbuf,
*sol,*solt, *datat,
*mx2t, *my2t, *mxyt,
val,val2, xm2,ym2,xym,flux, temp,temp2, theta, pmx2,pmy2,
wnorm, ellip, norm, snorm;
float **param, *ppix, *ospix, *cpc,*cpc2, *fparam,
pixstep, fval, fvalmax, fscale, dparam;
int *parammod,
c,n,p, npix,npix2,nopix, ncoeff, nparam, nmax,nmax2, ncode;
pc = psf->pc;
/* Build the "local PCs", using the basis func. coeffs computed in psf_fit() */
if (npc > pc->npc)
npc = pc->npc;
npix = pc->masksize[0]*pc->masksize[1];
npix2 = width*height;
ncoeff = psf->poly->ncoeff;
pixstep = 1.0/psf->pixstep;
dx *= pixstep;
dy *= pixstep;
memset(pc->maskcurr, 0, npix*npc*sizeof(double));
basis0 = psf->poly->basis;
cpix0 = pc->maskcurr;
ppix = pc->maskcomp;
/* Sum each (PSF-dependent) component */
for (c=npc; c--; cpix0 += npix)
{
basis = basis0;
for (n = ncoeff; n--;)
{
cpix = cpix0;
val = *(basis++);
for (p=npix; p--;)
*(cpix++) += val*(double)*(ppix++);
}
}
/* Allocate memory for temporary buffers */
QMALLOC(pcshift, double, npix2*npc);
QMALLOC(wpcshift, double, npix2*npc);
QMALLOC(sol, double, npc);
/* Now shift and scale to the right position, and weight the PCs */
cpix = pc->maskcurr;
spix = pcshift;
wspix = wpcshift;
for (c=npc; c--; cpix += npix)
{
vignet_resample(cpix, pc->masksize[0], pc->masksize[1],
spix, width, height, -dx, -dy, pixstep);
w = weight;
for (p=npix2; p--;)
*(wspix++) = *(spix++)**(w++);
}
/* Compute the weight normalization */
wnorm = 0.0;
w = weight;
for (p=npix2; p--;)
{
val = *(w++);
wnorm += val*val;
}
/* Scalar product of data and (approximately orthogonal) basis functions */
wspix = wpcshift;
solt = sol;
snorm = 0.0;
for (c=npc; c--;)
{
datat = data;
val = 0.0;
for (p=npix2; p--;)
val += *(datat++)**(wspix++);
val2 = *(solt++) = val*npix2/wnorm;
snorm += val2*val2;
}
/* Normalize solution vector */
snorm = sqrt(snorm);
solt = sol;
for (c=npc; c--;)
*(solt++) /= snorm;
if ((code = pc->code))
{
ncode = code->ncode;
/*-- Codebook search */
cpc = code->pc;
fvalmax = -BIG;
nmax = 0;
for (n=ncode; n--;)
{
fval = 0.0;
solt = sol;
for (p=npc; p--;)
fval += *(solt++)**(cpc++);
if (fval>fvalmax)
{
fvalmax = fval;
nmax = n;
}
}
nmax = ncode - 1 - nmax;
/*-- Interpolation */
param = code->param;
parammod = code->parammod;
nparam = code->nparam;
QMALLOC(fparam, float, nparam);
for (p=0; p<nparam; p++)
{
dparam = 0.0;
if (parammod[p])
{
val2 = 0.0;
if ((nmax2 = nmax+parammod[p]) < ncode)
{
cpc = code->pc+npc*nmax;
cpc2 = code->pc+npc*nmax2;
solt = sol;
norm = 0.0;
for (c=npc; c--;)
{
val = *(cpc2++)-*cpc;
val2 += val*(*(solt++) - *(cpc++));
norm += val*val;
}
if (norm>0.0)
dparam = val2/norm*(param[p][nmax2]-param[p][nmax]);
else
val2 = 0.0;
}
/*------ If dot product negative of something went wrong, try other side */
if (val2<=0.0 && (nmax2 = nmax-parammod[p]) >= 0)
{
cpc = code->pc+npc*nmax;
cpc2 = code->pc+npc*nmax2;
solt = sol;
norm = val2 = 0.0;
for (c=npc; c--;)
{
val = *(cpc2++)-*cpc;
val2 += val*(*(solt++) - *(cpc++));
norm += val*val;
}
if (norm>0.0)
dparam = val2/norm*(param[p][nmax2]-param[p][nmax]);
}
fparam[p] = param[p][nmax] + dparam;
}
}
solt = sol;
cpc = code->pc+npc*nmax;
fscale = fvalmax*code->param[0][nmax]*snorm;
for (p=npc; p--;)
*(solt++) = fscale**(cpc++);
/*-- Copy the derived physical quantities to output parameters */
/*-- (subject to changes) */
obj2->flux_galfit = fscale;
obj2->gdposang = fparam[1];
if (obj2->gdposang>90.0)
obj2->gdposang -= 180.0;
else if (obj2->gdposang<-90.0)
obj2->gdposang += 180.0;
obj2->gdscale = fparam[2];
obj2->gdaspect = fparam[3];
ellip = (1.0 - obj2->gdaspect)/(1.0 + obj2->gdaspect);
obj2->gde1 = (float)(ellip*cos(2*obj2->gdposang*PI/180.0));
obj2->gde2 = (float)(ellip*sin(2*obj2->gdposang*PI/180.0));
/*---- Copy the best-fitting PCs to the VECTOR_PC output vector */
if (FLAG(obj2.vector_pc))
{
solt = sol;
ppix = obj2->vector_pc;
for (c=prefs.pc_vectorsize>npc?npc:prefs.pc_vectorsize; c--;)
*(ppix++) = *(solt++);
}
free(fparam);
}
xm2 = ym2 = xym = flux = 0.0;
solt = sol;
mx2t = pc->mx2;
my2t = pc->my2;
mxyt = pc->mxy;
for (c=npc; c--;)
{
val = *(solt++);
xm2 += val**(mx2t++);
ym2 += val**(my2t++);
xym += val**(mxyt++);
}
obj2->mx2_pc = xm2;
obj2->my2_pc = ym2;
obj2->mxy_pc = xym;
if (FLAG(obj2.a_pc))
{
/* Handle fully correlated x/y (which cause a singularity...) */
if ((temp2=xm2*ym2-xym*xym)<0.00694)
{
xm2 += 0.0833333;
ym2 += 0.0833333;
temp2 = xm2*ym2-xym*xym;
}
if ((fabs(temp=xm2-ym2)) > 0.0)
theta = atan2(2.0 * xym,temp) / 2.0;
else
theta = PI/4.0;
temp = sqrt(0.25*temp*temp+xym*xym);
pmy2 = pmx2 = 0.5*(xm2+ym2);
pmx2 += temp;
pmy2 -= temp;
obj2->a_pc = (float)sqrt(pmx2);
obj2->b_pc = (float)sqrt(pmy2);
obj2->theta_pc = (float)(theta*180.0/PI);
}
/* CHECK-Images */
if (prefs.check[CHECK_SUBPCPROTOS] || prefs.check[CHECK_PCPROTOS])
{
spix = pcshift;
solt = sol;
for (c=npc; c--; solt++)
{
ppix = checkmask;
for (p=npix2; p--;)
*(ppix++) = (PIXTYPE)*(spix++);
if ((check = prefs.check[CHECK_SUBPCPROTOS]))
addcheck(check, checkmask, width,height, ix,iy, -*solt);
if ((check = prefs.check[CHECK_PCPROTOS]))
addcheck(check, checkmask, width,height, ix,iy, *solt);
}
}
if ((check = prefs.check[CHECK_PCOPROTOS]))
{
/*- Reconstruct the unconvolved profile */
nopix = pc->omasksize[0]*pc->omasksize[1];
QCALLOC(sumopc, double, nopix);
solt = sol;
ospix = pc->omaskcomp;
for (c=npc; c--;)
{
val = *(solt++);
sumopct = sumopc;
for (p=nopix; p--;)
*(sumopct++) += val*(double)*(ospix++);
}
QMALLOC(checkbuf, double, npix2);
vignet_resample(sumopc, pc->omasksize[0], pc->omasksize[1],
checkbuf, width, height, -dx, -dy, pixstep);
ppix = checkmask;
spix = checkbuf;
for (p=npix2; p--;)
*(ppix++) = (PIXTYPE)*(spix++);
addcheck(check, checkmask, width,height, ix,iy, 1.0);
free(checkbuf);
free(sumopc);
}
/* Free memory */
free(pcshift);
free(wpcshift);
free(sol);
return;
}
/*
photom.c
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: SExtractor
*
* Author: E.BERTIN (IAP)
*
* Contents: Compute magnitudes and other photometrical parameters.
*
* Last modify: 24/08/2005
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <math.h>
#include <stdlib.h>
#include "define.h"
#include "globals.h"
#include "prefs.h"
#include "photom.h"
#include "plist.h"
static obj2struct *obj2 = &outobj2;
/***************************** computeaperflux********************************/
/*
Compute the total flux within a circular aperture.
*/
void computeaperflux(picstruct *field, picstruct *wfield,
objstruct *obj, int i)
{
float r2, raper,raper2, rintlim,rintlim2,rextlim2,
mx,my,dx,dx1,dy,dy2,
offsetx,offsety,scalex,scaley,scale2, ngamma, locarea;
double tv, sigtv, area, pix, var, backnoise2, gain;
int x,y, x2,y2, xmin,xmax,ymin,ymax, sx,sy, w,h,
fymin,fymax, pflag,corrflag, gainflag;
long pos;
PIXTYPE *strip,*stript, *wstrip,*wstript,
wthresh = 0.0;
if (wfield)
wthresh = wfield->weight_thresh;
wstrip = wstript = NULL;
mx = obj->mx;
my = obj->my;
w = field->width;
h = field->stripheight;
fymin = field->ymin;
fymax = field->ymax;
ngamma = field->ngamma;
pflag = (prefs.detect_type==PHOTO)? 1:0;
corrflag = (prefs.mask_type==MASK_CORRECT);
gainflag = wfield && prefs.weightgain_flag;
var = backnoise2 = field->backsig*field->backsig;
gain = prefs.gain;
/* Integration radius */
raper = prefs.apert[i]/2.0;
raper2 = raper*raper;
/* Internal radius of the oversampled annulus (<r-sqrt(2)/2) */
rintlim = raper - 0.75;
rintlim2 = (rintlim>0.0)? rintlim*rintlim: 0.0;
/* External radius of the oversampled annulus (>r+sqrt(2)/2) */
rextlim2 = (raper + 0.75)*(raper + 0.75);
tv = sigtv = area = 0.0;
scaley = scalex = 1.0/APER_OVERSAMP;
scale2 = scalex*scaley;
offsetx = 0.5*(scalex-1.0);
offsety = 0.5*(scaley-1.0);
xmin = (int)(mx-raper+0.499999);
xmax = (int)(mx+raper+1.499999);
ymin = (int)(my-raper+0.499999);
ymax = (int)(my+raper+1.499999);
if (xmin < 0)
{
xmin = 0;
obj->flag |= OBJ_APERT_PB;
}
if (xmax > w)
{
xmax = w;
obj->flag |= OBJ_APERT_PB;
}
if (ymin < fymin)
{
ymin = fymin;
obj->flag |= OBJ_APERT_PB;
}
if (ymax > fymax)
{
ymax = fymax;
obj->flag |= OBJ_APERT_PB;
}
strip = field->strip;
if (wfield)
wstrip = wfield->strip;
for (y=ymin; y<ymax; y++)
{
stript = strip + (pos = (y%h)*w + xmin);
if (wfield)
wstript = wstrip + pos;
for (x=xmin; x<xmax; x++, stript++, wstript++)
{
dx = x - mx;
dy = y - my;
if ((r2=dx*dx+dy*dy) < rextlim2)
{
if (r2> rintlim2)
{
dx += offsetx;
dy += offsety;
locarea = 0.0;
for (sy=APER_OVERSAMP; sy--; dy+=scaley)
{
dx1 = dx;
dy2 = dy*dy;
for (sx=APER_OVERSAMP; sx--; dx1+=scalex)
if (dx1*dx1+dy2<raper2)
locarea += scale2;
}
}
else
locarea = 1.0;
area += locarea;
/*------ Here begin tests for pixel and/or weight overflows. Things are a */
/*------ bit intricated to have it running as fast as possible in the most */
/*------ common cases */
if ((pix=*stript)<=-BIG || (wfield && (var=*wstript)>=wthresh))
{
if (corrflag
&& (x2=(int)(2*mx+0.49999-x))>=0 && x2<w
&& (y2=(int)(2*my+0.49999-y))>=fymin && y2<fymax
&& (pix=*(strip + (pos = (y2%h)*w + x2)))>-BIG)
{
if (wfield)
{
var = *(wstrip + pos);
if (var>=wthresh)
pix = var = 0.0;
}
}
else
{
pix = 0.0;
if (wfield)
var = 0.0;
}
}
if (pflag)
{
pix=exp(pix/ngamma);
sigtv += var*locarea*pix*pix;
}
else
sigtv += var*locarea;
tv += locarea*pix;
if (gainflag && pix>0.0 && gain>0.0)
sigtv += pix/gain*var/backnoise2;
}
}
}
if (pflag)
{
tv = ngamma*(tv-area*exp(obj->dbkg/ngamma));
sigtv /= ngamma*ngamma;
}
else
{
tv -= area*obj->dbkg;
if (!gainflag && gain > 0.0 && tv>0.0)
sigtv += tv/gain;
}
if (i<prefs.flux_apersize)
obj2->flux_aper[i] = tv;
if (i<prefs.fluxerr_apersize)
obj2->fluxerr_aper[i] = sqrt(sigtv);
if (i<prefs.mag_apersize)
obj2->mag_aper[i] = tv>0.0? -2.5*log10(tv) + prefs.mag_zeropoint : 99.0;
if (i<prefs.magerr_apersize)
obj2->magerr_aper[i] = tv>0.0? 1.086*sqrt(sigtv)/tv:99.0;
return;
}
/***************************** computepetroflux ******************************/
/*
Compute the total flux within an automatic elliptical aperture.
*/
void computepetroflux(picstruct *field, picstruct *dfield, picstruct *wfield,
picstruct *dwfield, objstruct *obj)
{
double sigtv, tv, r1, v1,var,gain,backnoise2, muden,munum;
float bkg, ngamma, mx,my, dx,dy, cx2,cy2,cxy, r2,
klim, klim2,kmin,kmin2,kmax,kmax2,kstep,kmea,kmea2,
dxlim, dylim;
int area,areab, areaden, areanum,
x,y, x2,y2, xmin,xmax,ymin,ymax,
fymin,fymax, w,h,
pflag, corrflag, gainflag, pos;
PIXTYPE *strip,*stript, *dstrip,*dstript, *wstrip,*wstript,
*dwstrip,*dwstript,
pix, wthresh=0.0, dwthresh=0.0;
/* Let's initialize some variables */
if (!dfield)
dfield = field;
if (dwfield)
dwthresh = dwfield->weight_thresh;
wstrip = dwstrip = NULL;
if (wfield)
wthresh = wfield->weight_thresh;
wstript = dwstript = NULL;
w = field->width;
h = field->stripheight;
fymin = field->ymin;
fymax = field->ymax;
ngamma = field->ngamma;
bkg = (double)obj->dbkg;
mx = obj->mx;
my = obj->my;
var = backnoise2 = field->backsig*field->backsig;
gain = prefs.gain;
pflag = (prefs.detect_type==PHOTO)? 1:0;
corrflag = (prefs.mask_type==MASK_CORRECT);
gainflag = wfield && prefs.weightgain_flag;
/* First step: find the extent of the ellipse (the Petrosian factor) */
/* Clip boundaries in x and y */
/* We first check that the search ellipse is large enough... */
if (PETRO_NSIG*sqrt(obj->a*obj->b)>prefs.autoaper[0]/2.0)
{
cx2 = obj->cxx;
cy2 = obj->cyy;
cxy = obj->cxy;
dxlim = cx2 - cxy*cxy/(4.0*cy2);
dxlim = dxlim>0.0 ? PETRO_NSIG/sqrt(dxlim) : 0.0;
dylim = cy2 - cxy*cxy/(4.0*cx2);
dylim = dylim > 0.0 ? PETRO_NSIG/sqrt(dylim) : 0.0;
klim2 = PETRO_NSIG*PETRO_NSIG;
}
else
/*-- ...if not, use the circular aperture provided by the user */
{
cx2 = cy2 = 1.0;
cxy = 0.0;
dxlim = dylim = prefs.autoaper[0]/2.0;
klim2 = dxlim*dxlim;
}
if ((xmin = RINT(mx-dxlim)) < 0)
{
xmin = 0;
obj->flag |= OBJ_APERT_PB;
}
if ((xmax = RINT(mx+dxlim)+1) > w)
{
xmax = w;
obj->flag |= OBJ_APERT_PB;
}
if ((ymin = RINT(my-dylim)) < field->ymin)
{
ymin = field->ymin;
obj->flag |= OBJ_APERT_PB;
}
if ((ymax = RINT(my+dylim)+1) > field->ymax)
{
ymax = field->ymax;
obj->flag |= OBJ_APERT_PB;
}
dstrip = dfield->strip;
if (dwfield)
dwstrip = dwfield->strip;
klim = sqrt(klim2);
kstep = klim/20.0;
area = areab = areanum = areaden = 0;
munum = muden = 0.0;
kmea = 0.0;
for (kmin=kstep; (kmax=kmin*1.2)<klim; kmin += kstep)
{
kmea = (kmin+kmax)/2.0;
kmea2 = kmea*kmea;
kmin2 = kmin*kmin;
kmax2 = kmax*kmax;
v1 = r1 = 0.0;
area = areab = areanum = areaden = 0;
munum = muden = 0.0;
for (y=ymin; y<ymax; y++)
{
dstript = dstrip + (pos = xmin + (y%h)*w);
if (dwfield)
dwstript = dwstrip + pos;
for (x=xmin; x<xmax; x++, dstript++, dwstript++)
{
dx = x - mx;
dy = y - my;
if ((r2=cx2*dx*dx + cy2*dy*dy + cxy*dx*dy) <= kmax2)
{
if ((pix=*dstript)>-BIG && (!dwfield || (dwfield&&*dwstript<dwthresh)))
{
area++;
if (r2>=kmin2)
{
munum += pix;
areanum++;
}
if (r2<kmea2)
{
muden += pix;
areaden++;
}
}
else
areab++;
}
}
}
if (areanum && areaden)
{
munum /= (double)areanum;
muden /= (double)areaden;
if (munum<muden*0.2)
break;
}
}
area += areab;
if (area)
{
/*-- Go further only if some pixels are available !! */
if (areanum && areaden && munum && muden)
{
obj2->petrofactor = prefs.petroparam[0]*kmea;
if (obj2->petrofactor < prefs.petroparam[1])
obj2->petrofactor = prefs.petroparam[1];
}
else
obj2->petrofactor = prefs.petroparam[1];
/*-- Flag if the Petrosian photometry can be strongly affected by neighhours */
if ((float)areab/area > CROWD_THRESHOLD)
obj->flag |= OBJ_CROWDED;
/*-- Second step: integrate within the ellipse */
/*-- Clip boundaries in x and y (bis) */
/*-- We first check that the derived ellipse is large enough... */
if (obj2->petrofactor*sqrt(obj->a*obj->b)>prefs.autoaper[1]/2.0)
{
cx2 = obj->cxx;
cy2 = obj->cyy;
cxy = obj->cxy;
dxlim = cx2 - cxy*cxy/(4.0*cy2);
dxlim = dxlim>0.0 ? obj2->petrofactor/sqrt(dxlim) : 0.0;
dylim = cy2 - cxy*cxy/(4.0*cx2);
dylim = dylim > 0.0 ? obj2->petrofactor/sqrt(dylim) : 0.0;
klim2 = obj2->petrofactor*obj2->petrofactor;
}
else
/*---- ...if not, use the circular aperture provided by the user */
{
cx2 = cy2 = 1.0;
cxy = 0.0;
dxlim = dylim = prefs.autoaper[1]/2.0;
klim2 = dxlim*dxlim;
obj2->petrofactor = 0.0;
}
if ((xmin = RINT(mx-dxlim)) < 0)
{
xmin = 0;
obj->flag |= OBJ_APERT_PB;
}
if ((xmax = RINT(mx+dxlim)+1) > w)
{
xmax = w;
obj->flag |= OBJ_APERT_PB;
}
if ((ymin = RINT(my-dylim)) < field->ymin)
{
ymin = field->ymin;
obj->flag |= OBJ_APERT_PB;
}
if ((ymax = RINT(my+dylim)+1) > field->ymax)
{
ymax = field->ymax;
obj->flag |= OBJ_APERT_PB;
}
area = areab = 0;
tv = sigtv = 0.0;
strip = field->strip;
if (wfield)
wstrip = wfield->strip;
for (y=ymin; y<ymax; y++)
{
stript = strip + (pos = xmin + (y%h)*w);
if (wfield)
wstript = wstrip + pos;
for (x=xmin; x<xmax; x++, stript++, wstript++)
{
dx = x - mx;
dy = y - my;
if ((cx2*dx*dx + cy2*dy*dy + cxy*dx*dy) <= klim2)
{
area++;
/*-------- Here begin tests for pixel and/or weight overflows. Things are a */
/*-------- bit intricated to have it running as fast as possible in the most */
/*-------- common cases */
if ((pix=*stript)<=-BIG || (wfield && (var=*wstript)>=wthresh))
{
areab++;
if (corrflag
&& (x2=(int)(2*mx+0.49999-x))>=0 && x2<w
&& (y2=(int)(2*my+0.49999-y))>=fymin && y2<fymax
&& (pix=*(strip + (pos = (y2%h)*w + x2)))>-BIG)
{
if (wfield)
{
var = *(wstrip + pos);
if (var>=wthresh)
pix = var = 0.0;
}
}
else
{
pix = 0.0;
if (wfield)
var = 0.0;
}
}
if (pflag)
{
pix = exp(pix/ngamma);
sigtv += var*pix*pix;
}
else
sigtv += var;
tv += pix;
if (gainflag && pix>0.0 && gain>0.0)
sigtv += pix/gain*var/backnoise2;
}
}
}
/*-- Flag if the Petrosian photometry can be strongly affected by neighhours */
if ((float)areab > CROWD_THRESHOLD*area)
obj->flag |= OBJ_CROWDED;
if (pflag)
{
tv = ngamma*(tv-area*exp(bkg/ngamma));
sigtv /= ngamma*ngamma;
}
else
{
tv -= area*bkg;
if (!gainflag && gain > 0.0 && tv>0.0)
sigtv += tv/gain;
}
}
else
/*-- No available pixels: set the flux to zero */
tv = sigtv = 0.0;
obj2->flux_petro = tv;
obj2->fluxerr_petro = sqrt(sigtv);
if (FLAG(obj2.mag_petro))
obj2->mag_petro = obj2->flux_petro>0.0?
-2.5*log10(obj2->flux_petro) + prefs.mag_zeropoint
:99.0;
if (FLAG(obj2.magerr_petro))
obj2->magerr_petro = obj2->flux_petro>0.0?
1.086*obj2->fluxerr_petro/obj2->flux_petro
:99.0;
if (tv<=0.0)
obj2->petrofactor = 0.0;
return;
}
/***************************** computeautoflux********************************/
/*
Compute the total flux within an automatic elliptical aperture.
*/
void computeautoflux(picstruct *field, picstruct *dfield, picstruct *wfield,
picstruct *dwfield, objstruct *obj)
{
double sigtv, tv, r1, v1,var,gain,backnoise2;
float bkg, ngamma, mx,my, dx,dy, cx2,cy2,cxy, r2,klim2,
dxlim, dylim;
int area,areab, x,y, x2,y2, xmin,xmax,ymin,ymax,
fymin,fymax, w,h,
pflag, corrflag, gainflag, pos;
PIXTYPE *strip,*stript, *dstrip,*dstript, *wstrip,*wstript,
*dwstrip,*dwstript,
pix, wthresh=0.0, dwthresh=0.0;
/* Let's initialize some variables */
if (!dfield)
dfield = field;
if (dwfield)
dwthresh = dwfield->weight_thresh;
wstrip = dwstrip = NULL;
if (wfield)
wthresh = wfield->weight_thresh;
wstript = dwstript = NULL;
w = field->width;
h = field->stripheight;
fymin = field->ymin;
fymax = field->ymax;
ngamma = field->ngamma;
bkg = (double)obj->dbkg;
mx = obj->mx;
my = obj->my;
var = backnoise2 = field->backsig*field->backsig;
gain = prefs.gain;
pflag = (prefs.detect_type==PHOTO)? 1:0;
corrflag = (prefs.mask_type==MASK_CORRECT);
gainflag = wfield && prefs.weightgain_flag;
/* First step: find the extent of the ellipse (the kron factor r1) */
/* Clip boundaries in x and y */
/* We first check that the search ellipse is large enough... */
if (KRON_NSIG*sqrt(obj->a*obj->b)>prefs.autoaper[0]/2.0)
{
cx2 = obj->cxx;
cy2 = obj->cyy;
cxy = obj->cxy;
dxlim = cx2 - cxy*cxy/(4.0*cy2);
dxlim = dxlim>0.0 ? KRON_NSIG/sqrt(dxlim) : 0.0;
dylim = cy2 - cxy*cxy/(4.0*cx2);
dylim = dylim > 0.0 ? KRON_NSIG/sqrt(dylim) : 0.0;
klim2 = KRON_NSIG*KRON_NSIG;
}
else
/*-- ...if not, use the circular aperture provided by the user */
{
cx2 = cy2 = 1.0;
cxy = 0.0;
dxlim = dylim = prefs.autoaper[0]/2.0;
klim2 = dxlim*dxlim;
}
if ((xmin = RINT(mx-dxlim)) < 0)
{
xmin = 0;
obj->flag |= OBJ_APERT_PB;
}
if ((xmax = RINT(mx+dxlim)+1) > w)
{
xmax = w;
obj->flag |= OBJ_APERT_PB;
}
if ((ymin = RINT(my-dylim)) < field->ymin)
{
ymin = field->ymin;
obj->flag |= OBJ_APERT_PB;
}
if ((ymax = RINT(my+dylim)+1) > field->ymax)
{
ymax = field->ymax;
obj->flag |= OBJ_APERT_PB;
}
v1 = r1 = 0.0;
area = areab = 0;
dstrip = dfield->strip;
if (dwfield)
dwstrip = dwfield->strip;
for (y=ymin; y<ymax; y++)
{
dstript = dstrip + (pos = xmin + (y%h)*w);
if (dwfield)
dwstript = dwstrip + pos;
for (x=xmin; x<xmax; x++, dstript++, dwstript++)
{
dx = x - mx;
dy = y - my;
if ((r2=cx2*dx*dx + cy2*dy*dy + cxy*dx*dy) <= klim2)
{
if ((pix=*dstript)>-BIG && (!dwfield || (dwfield&&*dwstript<dwthresh)))
{
area++;
r1 += sqrt(r2)*pix;
v1 += pix;
}
else
areab++;
}
}
}
area += areab;
if (area)
{
/*-- Go further only if some pixels are available !! */
if (r1>0.0 && v1>0.0)
{
obj2->kronfactor = prefs.autoparam[0]*r1/v1;
if (obj2->kronfactor < prefs.autoparam[1])
obj2->kronfactor = prefs.autoparam[1];
}
else
obj2->kronfactor = prefs.autoparam[1];
/*-- Flag if the Kron photometry can be strongly affected by neighhours */
if ((float)areab/area > CROWD_THRESHOLD)
obj->flag |= OBJ_CROWDED;
/*-- Second step: integrate within the ellipse */
/*-- Clip boundaries in x and y (bis) */
/*-- We first check that the derived ellipse is large enough... */
if (obj2->kronfactor*sqrt(obj->a*obj->b)>prefs.autoaper[1]/2.0)
{
cx2 = obj->cxx;
cy2 = obj->cyy;
cxy = obj->cxy;
dxlim = cx2 - cxy*cxy/(4.0*cy2);
dxlim = dxlim>0.0 ? obj2->kronfactor/sqrt(dxlim) : 0.0;
dylim = cy2 - cxy*cxy/(4.0*cx2);
dylim = dylim > 0.0 ? obj2->kronfactor/sqrt(dylim) : 0.0;
klim2 = obj2->kronfactor*obj2->kronfactor;
}
else
/*---- ...if not, use the circular aperture provided by the user */
{
cx2 = cy2 = 1.0;
cxy = 0.0;
dxlim = dylim = prefs.autoaper[1]/2.0;
klim2 = dxlim*dxlim;
obj2->kronfactor = 0.0;
}
if ((xmin = RINT(mx-dxlim)) < 0)
{
xmin = 0;
obj->flag |= OBJ_APERT_PB;
}
if ((xmax = RINT(mx+dxlim)+1) > w)
{
xmax = w;
obj->flag |= OBJ_APERT_PB;
}
if ((ymin = RINT(my-dylim)) < field->ymin)
{
ymin = field->ymin;
obj->flag |= OBJ_APERT_PB;
}
if ((ymax = RINT(my+dylim)+1) > field->ymax)
{
ymax = field->ymax;
obj->flag |= OBJ_APERT_PB;
}
area = areab = 0;
tv = sigtv = 0.0;
strip = field->strip;
if (wfield)
wstrip = wfield->strip;
for (y=ymin; y<ymax; y++)
{
stript = strip + (pos = xmin + (y%h)*w);
if (wfield)
wstript = wstrip + pos;
for (x=xmin; x<xmax; x++, stript++, wstript++)
{
dx = x - mx;
dy = y - my;
if ((cx2*dx*dx + cy2*dy*dy + cxy*dx*dy) <= klim2)
{
area++;
/*-------- Here begin tests for pixel and/or weight overflows. Things are a */
/*-------- bit intricated to have it running as fast as possible in the most */
/*-------- common cases */
if ((pix=*stript)<=-BIG || (wfield && (var=*wstript)>=wthresh))
{
areab++;
if (corrflag
&& (x2=(int)(2*mx+0.49999-x))>=0 && x2<w
&& (y2=(int)(2*my+0.49999-y))>=fymin && y2<fymax
&& (pix=*(strip + (pos = (y2%h)*w + x2)))>-BIG)
{
if (wfield)
{
var = *(wstrip + pos);
if (var>=wthresh)
pix = var = 0.0;
}
}
else
{
pix = 0.0;
if (wfield)
var = 0.0;
}
}
if (pflag)
{
pix = exp(pix/ngamma);
sigtv += var*pix*pix;
}
else
sigtv += var;
tv += pix;
if (gainflag && pix>0.0 && gain>0.0)
sigtv += pix/gain*var/backnoise2;
}
}
}
/*-- Flag if the Kron photometry can be strongly affected by neighhours */
if ((float)areab > CROWD_THRESHOLD*area)
obj->flag |= OBJ_CROWDED;
if (pflag)
{
tv = ngamma*(tv-area*exp(bkg/ngamma));
sigtv /= ngamma*ngamma;
}
else
{
tv -= area*bkg;
if (!gainflag && gain > 0.0 && tv>0.0)
sigtv += tv/gain;
}
}
else
/*-- No available pixels: set the flux to zero */
tv = sigtv = 0.0;
obj2->flux_auto = tv;
obj2->fluxerr_auto = sqrt(sigtv);
if (FLAG(obj2.mag_auto))
obj2->mag_auto = obj2->flux_auto>0.0?
-2.5*log10(obj2->flux_auto) + prefs.mag_zeropoint
:99.0;
if (FLAG(obj2.magerr_auto))
obj2->magerr_auto = obj2->flux_auto>0.0?
1.086*obj2->fluxerr_auto/obj2->flux_auto
:99.0;
if (tv<=0.0)
obj2->kronfactor = 0.0;
return;
}
/****************************** computeisocorflux ****************************/
/*
Compute the (corrected) isophotal flux.
*/
void computeisocorflux(picstruct *field, objstruct *obj)
{
double ati;
ati = (obj->flux>0.0)? (obj->fdnpix*obj->dthresh/obj->flux) : 0.0;
if (ati>1.0)
ati = 1.0;
else if (ati<0.0)
ati = 0.0;
obj2->flux_isocor = obj->flux/(1.0-0.196099*ati-0.751208*ati*ati);
if (FLAG(obj2.fluxerr_isocor))
{
if (obj->flux>0.0)
{
double dati, sigtv;
sigtv = obj->fluxerr/(obj->flux*obj->flux);
dati = obj->fdnpix?ati*sqrt(sigtv+1.0/obj->fdnpix): 0.0;
dati = 0.196099*dati + 0.751208*2*ati*dati;
obj2->fluxerr_isocor = sqrt(sigtv+dati*dati)*obj->flux;
}
else
obj2->fluxerr_isocor = sqrt(obj->fluxerr);
}
return;
}
/******************************* computemags *********************************/
/*
Compute magnitude parameters.
*/
void computemags(picstruct *field, objstruct *obj)
{
/* Mag. isophotal */
if (FLAG(obj2.mag_iso))
obj2->mag_iso = obj2->flux_iso>0.0?
-2.5*log10(obj2->flux_iso) + prefs.mag_zeropoint
:99.0;
if (FLAG(obj2.magerr_iso))
obj2->magerr_iso = obj2->flux_iso>0.0?
1.086*obj2->fluxerr_iso/obj2->flux_iso
:99.0;
/* Mag. isophotal corrected */
if (FLAG(obj2.mag_isocor))
obj2->mag_isocor = obj2->flux_isocor>0.0?
-2.5*log10(obj2->flux_isocor) + prefs.mag_zeropoint
:99.0;
if (FLAG(obj2.magerr_isocor))
obj2->magerr_isocor = obj2->flux_isocor>0.0?
1.086*obj2->fluxerr_isocor/obj2->flux_isocor
:99.0;
/* Choose the ``best'' flux according to the local crowding */
if (FLAG(obj2.flux_best))
{
if (obj->flag&OBJ_CROWDED)
{
obj2->flux_best = obj2->flux_isocor;
obj2->fluxerr_best = obj2->fluxerr_isocor;
}
else
{
obj2->flux_best = obj2->flux_auto;
obj2->fluxerr_best = obj2->fluxerr_auto;
}
}
/* Mag. Best */
if (FLAG(obj2.mag_best))
obj2->mag_best = obj2->flux_best>0.0?
-2.5*log10(obj2->flux_best) + prefs.mag_zeropoint
:99.0;
if (FLAG(obj2.magerr_best))
obj2->magerr_best = obj2->flux_best>0.0?
1.086*obj2->fluxerr_best/obj2->flux_best
:99.0;
/* Mag. SOM-fit */
if (FLAG(obj2.mag_somfit))
obj2->mag_somfit = obj2->flux_somfit>0.0?
-2.5*log10(obj2->flux_somfit) + prefs.mag_zeropoint
:99.0;
if (FLAG(obj2.magerr_somfit))
obj2->magerr_somfit = obj2->flux_somfit>0.0?
1.086*obj2->fluxerr_somfit/obj2->flux_somfit
:99.0;
/* Mag. PROFILE */
if (FLAG(obj2.mag_prof))
obj2->mag_prof = obj2->flux_prof>0.0?
-2.5*log10(obj2->flux_prof) + prefs.mag_zeropoint
:99.0;
if (FLAG(obj2.magerr_prof))
obj2->magerr_prof = obj2->flux_prof>0.0?
1.086*obj2->fluxerr_prof/obj2->flux_prof
:99.0;
/* Mag. WINdowed */
if (FLAG(obj2.mag_win))
obj2->mag_win = obj2->flux_win>0.0?
-2.5*log10(obj2->flux_win) + prefs.mag_zeropoint
:99.0;
if (FLAG(obj2.magerr_win))
obj2->magerr_win = obj2->flux_win>0.0?
1.086*obj2->fluxerr_win/obj2->flux_win
:99.0;
/* Mag. GALFIT */
if (FLAG(obj2.mag_galfit))
obj2->mag_galfit = obj2->flux_galfit>0.0?
-2.5*log10(obj2->flux_galfit) + prefs.mag_zeropoint
:99.0;
if (FLAG(obj2.magerr_galfit))
obj2->magerr_galfit = obj2->flux_galfit>0.0?
1.086*obj2->fluxerr_galfit/obj2->flux_galfit
:99.0;
/* SB units */
if (FLAG(obj2.maxmu))
outobj2.maxmu = obj->peak > 0.0 ?
-2.5*log10((obj->peak)
/ (field->pixscale * field->pixscale)) + prefs.mag_zeropoint
: 99.0;
if (FLAG(obj2.threshmu))
obj2->threshmu = obj->thresh > 0.0 ?
-2.5*log10((obj->thresh)
/ (field->pixscale * field->pixscale)) + prefs.mag_zeropoint
: 99.0;
return;
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment