Newer
Older
***/
void profit_resetparam(profitstruct *profit, paramenum paramtype)
{
obj2struct *obj2;
float param, parammin,parammax, range;
Emmanuel Bertin
committed
parfitenum fittype;
obj2 = profit->obj2;
param = parammin = parammax = 0.0; /* Avoid gcc -Wall warnings*/
switch(paramtype)
{
case PARAM_BACK:
Emmanuel Bertin
committed
fittype = PARFIT_LINBOUND;
parammin = -6.0*profit->guesssigbkg;
parammax = 6.0*profit->guesssigbkg;
Emmanuel Bertin
committed
fittype = PARFIT_LINBOUND;
param = profit->guessdx;
Emmanuel Bertin
committed
range = profit->guessradius*4.0;
if (range>profit->objnaxisn[0]*2.0)
range = profit->objnaxisn[0]*2.0;
parammin = -range;
parammax = range;
Emmanuel Bertin
committed
fittype = PARFIT_LINBOUND;
param = profit->guessdy;
Emmanuel Bertin
committed
range = profit->guessradius*4.0;
if (range>profit->objnaxisn[1]*2)
range = profit->objnaxisn[1]*2;
parammin = -range;
parammax = range;
Emmanuel Bertin
committed
fittype = PARFIT_LOGBOUND;
param = profit->guessflux/profit->nprof;
parammin = 0.00001*profit->guessfluxmax;
parammax = 10.0*profit->guessfluxmax;
Emmanuel Bertin
committed
fittype = PARFIT_LOGBOUND;
param = profit->guessflux/profit->nprof;
parammin = 0.00001*profit->guessfluxmax;
parammax = 10.0*profit->guessfluxmax;
Emmanuel Bertin
committed
fittype = PARFIT_LOGBOUND;
param = FLAG(obj2.prof_disk_flux)? profit->guessradius
: profit->guessradius/sqrtf(profit->guessaspect);
parammin = 0.01;
Emmanuel Bertin
committed
parammax = param * 10.0;
Emmanuel Bertin
committed
fittype = PARFIT_LOGBOUND;
param = FLAG(obj2.prof_disk_flux)? 1.0 : profit->guessaspect;
parammin = FLAG(obj2.prof_disk_flux)? 0.5 : 0.01;
parammax = FLAG(obj2.prof_disk_flux)? 2.0 : 100.0;
Emmanuel Bertin
committed
fittype = PARFIT_UNBOUND;
param = profit->guessposang;
parammin = 90.0;
parammax = 90.0;
Emmanuel Bertin
committed
fittype = PARFIT_LINBOUND;
parammin = FLAG(obj2.prof_disk_flux)? 1.0 : 0.3;
parammax = 10.0;
break;
case PARAM_DISK_FLUX:
Emmanuel Bertin
committed
fittype = PARFIT_LOGBOUND;
param = profit->guessflux/profit->nprof;
parammin = 0.00001*profit->guessfluxmax;
parammax = 10.0*profit->guessfluxmax;
break;
case PARAM_DISK_SCALE: /* From scalelength to Re */
Emmanuel Bertin
committed
fittype = PARFIT_LOGBOUND;
param = profit->guessradius/(1.67835*sqrtf(profit->guessaspect));
Emmanuel Bertin
committed
parammin = 0.01/1.67835;
parammax = param * 10.0;
Emmanuel Bertin
committed
fittype = PARFIT_LOGBOUND;
param = profit->guessaspect;
Emmanuel Bertin
committed
fittype = PARFIT_UNBOUND;
param = profit->guessposang;
parammin = 90.0;
parammax = 90.0;
Emmanuel Bertin
committed
fittype = PARFIT_LOGBOUND;
param = profit->guessflux/profit->nprof;
parammin = 0.00001*profit->guessfluxmax;
parammax = 10.0*profit->guessfluxmax;
Emmanuel Bertin
committed
fittype = PARFIT_LINBOUND;
param = 0.5;
parammin = 0.0;
parammax = 1.0;
break;
case PARAM_ARMS_SCALE:
Emmanuel Bertin
committed
fittype = PARFIT_LINBOUND;
param = 1.0;
parammin = 0.5;
parammax = 10.0;
break;
case PARAM_ARMS_START:
Emmanuel Bertin
committed
fittype = PARFIT_LINBOUND;
param = 0.5;
parammin = 0.0;
parammax = 3.0;
break;
case PARAM_ARMS_PITCH:
Emmanuel Bertin
committed
fittype = PARFIT_LINBOUND;
param = 20.0;
parammin = 5.0;
parammax = 50.0;
break;
case PARAM_ARMS_PITCHVAR:
Emmanuel Bertin
committed
fittype = PARFIT_LINBOUND;
param = 0.0;
parammin = -1.0;
parammax = 1.0;
break;
// if ((profit->spirindex=profit_spiralindex(profit, obj, obj2)) > 0.0)
// {
// param = -param;
// parammin = -parammax;
// parammax = -parammin;
// }
// printf("spiral index: %g \n", profit->spirindex);
// break;
case PARAM_ARMS_POSANG:
Emmanuel Bertin
committed
fittype = PARFIT_UNBOUND;
param = 0.0;
parammin = 0.0;
parammax = 0.0;
break;
case PARAM_ARMS_WIDTH:
Emmanuel Bertin
committed
fittype = PARFIT_LINBOUND;
param = 3.0;
parammin = 1.5;
parammax = 11.0;
break;
case PARAM_BAR_FLUX:
Emmanuel Bertin
committed
fittype = PARFIT_LOGBOUND;
param = profit->guessflux/profit->nprof;
parammin = 0.00001*profit->guessfluxmax;
parammax = 4.0*profit->guessfluxmax;
Emmanuel Bertin
committed
fittype = PARFIT_LOGBOUND;
param = 0.3;
parammin = 0.2;
parammax = 0.5;
break;
case PARAM_BAR_POSANG:
Emmanuel Bertin
committed
fittype = PARFIT_UNBOUND;
Emmanuel Bertin
committed
parammin = 90.0;
parammax = 90.0;
Emmanuel Bertin
committed
fittype = PARFIT_LOGBOUND;
param = profit->guessflux/profit->nprof;
parammin = 0.00001*profit->guessfluxmax;
parammax = 4.0*profit->guessfluxmax;
Emmanuel Bertin
committed
fittype = PARFIT_LINBOUND;
param = 0.3;
parammin = 0.0;
parammax = 0.5;
break;
case PARAM_INRING_ASPECT:
Emmanuel Bertin
committed
fittype = PARFIT_LOGBOUND;
param = 0.8;
parammin = 0.4;
parammax = 1.0;
break;
case PARAM_OUTRING_FLUX:
Emmanuel Bertin
committed
fittype = PARFIT_LOGBOUND;
param = profit->guessflux/profit->nprof;
parammin = 0.00001*profit->guessfluxmax;
parammax = 4.0*profit->guessfluxmax;
Emmanuel Bertin
committed
fittype = PARFIT_LINBOUND;
param = 4.0;
parammin = 3.5;
parammax = 6.0;
break;
case PARAM_OUTRING_WIDTH:
Emmanuel Bertin
committed
fittype = PARFIT_LINBOUND;
param = 0.3;
parammin = 0.0;
parammax = 0.5;
break;
default:
error(EXIT_FAILURE, "*Internal Error*: Unknown profile parameter in ",
"profit_resetparam()");
break;
}
if (parammin!=parammax && (param<=parammin || param>=parammax))
param = (parammin+parammax)/2.0;
Emmanuel Bertin
committed
else if (parammin==0.0 && parammax==0.0)
parammax = 1.0;
Emmanuel Bertin
committed
profit_setparam(profit, paramtype, param, parammin, parammax, fittype);
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
return;
}
/****** profit_resetparams ****************************************************
PROTO void profit_resetparams(profitstruct *profit)
PURPOSE Set the initial, lower and upper boundary values of profile parameters.
INPUT Pointer to the profit structure.
OUTPUT -.
NOTES -.
AUTHOR E. Bertin (IAP)
VERSION 18/09/2008
***/
void profit_resetparams(profitstruct *profit)
{
int p;
for (p=0; p<PARAM_NPARAM; p++)
profit_resetparam(profit, (paramenum)p);
return;
}
/****** profit_setparam ****************************************************
PROTO void profit_setparam(profitstruct *profit, paramenum paramtype,
Emmanuel Bertin
committed
float param, float parammin, float parammax,
parfitenum parfittype)
PURPOSE Set the actual, lower and upper boundary values of a profile parameter.
INPUT Pointer to the profit structure,
Emmanuel Bertin
committed
parameter index,
actual value,
lower boundary to the parameter,
upper boundary to the parameter,
parameter fitting type.
OUTPUT RETURN_OK if the parameter is registered, RETURN_ERROR otherwise.
AUTHOR E. Bertin (IAP)
Emmanuel Bertin
committed
VERSION 20/05/2011
***/
int profit_setparam(profitstruct *profit, paramenum paramtype,
Emmanuel Bertin
committed
float param, float parammin,float parammax,
parfitenum parfittype)
int index;
/* Check whether the parameter has already be registered */
if ((paramptr=profit->paramlist[(int)paramtype]))
{
index = profit->paramindex[(int)paramtype];
profit->paraminit[index] = param;
profit->parammin[index] = parammin;
profit->parammax[index] = parammax;
Emmanuel Bertin
committed
profit->parfittype[index] = parfittype;
return RETURN_OK;
}
else
return RETURN_ERROR;
}
/****** profit_boundtounbound *************************************************
Emmanuel Bertin
committed
PROTO int profit_boundtounbound(profitstruct *profit,
float *param, double *dparam, int index)
PURPOSE Convert parameters from bounded to unbounded space.
INPUT Pointer to the profit structure,
input array of single precision parameters,
output (incomplete) array of double precision parameters,
parameter selection index (<0 = all parameters)
Emmanuel Bertin
committed
OUTPUT Number of free parameters.
Emmanuel Bertin
committed
VERSION 20/05/2011
Emmanuel Bertin
committed
int profit_boundtounbound(profitstruct *profit,
float *param, double *dparam, int index)
Emmanuel Bertin
committed
double num,den, tparam;
if (index<0)
{
pstart = 0;
np = profit->nparam;
}
else
{
pstart = index;
np = pstart+1;
}
f = 0;
for (p=pstart ; p<np; p++)
Emmanuel Bertin
committed
switch(profit->parfittype[p])
Emmanuel Bertin
committed
case PARFIT_FIXED:
break;
case PARFIT_UNBOUND:
if (profit->parammax[p] > 0.0 || profit->parammax[p] < 0.0)
dparam[f] = param[p-pstart] / profit->parammax[p];
f++;
break;
case PARFIT_LINBOUND:
tparam = param[p-pstart];
num = tparam - profit->parammin[p];
den = profit->parammax[p] - tparam;
dparam[f] = num>1e-50? (den>1e-50? log(num/den): 50.0) : -50.0;
Emmanuel Bertin
committed
f++;
break;
case PARFIT_LOGBOUND:
tparam = log(param[p-pstart]);
num = tparam - log(profit->parammin[p]);
den = log(profit->parammax[p]) - tparam;
dparam[f] = num>1e-50? (den>1e-50? log(num/den): 50.0) : -50.0;
f++;
break;
default:
error(EXIT_FAILURE,
"*Internal Error*: Unknown parameter fitting type in ",
"profit_boundtounbound()");
Emmanuel Bertin
committed
return f;
}
/****** profit_unboundtobound *************************************************
Emmanuel Bertin
committed
PROTO int profit_unboundtobound(profitstruct *profit,
double *dparam, float *param, int index)
PURPOSE Convert parameters from unbounded to bounded space.
INPUT Pointer to the profit structure,
input (incomplete) array of double precision parameters,
output array of single precision parameters.
parameter selection index (<0 = all parameters)
Emmanuel Bertin
committed
OUTPUT Number of free parameters.
Emmanuel Bertin
committed
VERSION 20/05/2011
Emmanuel Bertin
committed
int profit_unboundtobound(profitstruct *profit,
double *dparam, float *param, int index)
if (index<0)
{
pstart = 0;
np = profit->nparam;
}
else
{
pstart = index;
np = pstart+1;
}
f = 0;
for (p=pstart; p<np; p++)
Emmanuel Bertin
committed
switch(profit->parfittype[p])
Emmanuel Bertin
committed
case PARFIT_FIXED:
param[p-pstart] = profit->paraminit[p];
break;
case PARFIT_UNBOUND:
param[p-pstart] = dparam[f]*profit->parammax[p];
f++;
break;
case PARFIT_LINBOUND:
param[p-pstart] = (profit->parammax[p] - profit->parammin[p])
/ (1.0 + exp(-(dparam[f]>50.0? 50.0
: (dparam[f]<-50.0? -50.0: dparam[f]))))
Emmanuel Bertin
committed
+ profit->parammin[p];
f++;
break;
case PARFIT_LOGBOUND:
param[p-pstart] = exp(log(profit->parammax[p]/profit->parammin[p])
/ (1.0 + exp(-(dparam[f]>50.0? 50.0
: (dparam[f]<-50.0? -50.0: dparam[f])))))
*profit->parammin[p];
f++;
break;
default:
error(EXIT_FAILURE,
"*Internal Error*: Unknown parameter fitting type in ",
"profit_unboundtobound()");
Emmanuel Bertin
committed
return f;
}
/****** profit_covarunboundtobound ********************************************
Emmanuel Bertin
committed
PROTO int profit_covarunboundtobound(profitstruct *profit,
double *dcovar, float *covar)
PURPOSE Convert covariance matrix from unbounded to bounded space.
INPUT Pointer to the profit structure,
input (incomplete) matrix of double precision covariances,
output matrix of single precision covariances.
Emmanuel Bertin
committed
OUTPUT Number of parameters that hit a boundary.
Emmanuel Bertin
committed
VERSION 20/05/2011
Emmanuel Bertin
committed
int profit_covarunboundtobound(profitstruct *profit,
double *dcovar, float *covar)
Emmanuel Bertin
committed
double *dxdy,
xmmin,maxmx, maxmmin;
float *x,*xmin,*xmax;
Emmanuel Bertin
committed
parfitenum *fittype;
Emmanuel Bertin
committed
f,f1,f2, p,p1,p2, nfree, nparam, nmin,nmax;
Emmanuel Bertin
committed
fittype = profit->parfittype;
QMALLOC16(dxdy, double, PARAM_NPARAM);
x = profit->paraminit;
xmin = profit->parammin;
xmax = profit->parammax;
Emmanuel Bertin
committed
nmin = nmax = 0;
Emmanuel Bertin
committed
switch(fittype[p])
Emmanuel Bertin
committed
case PARFIT_FIXED:
break;
case PARFIT_UNBOUND:
dxdy[f++] = xmax[p];
Emmanuel Bertin
committed
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
break;
case PARFIT_LINBOUND:
xmmin = x[p] - xmin[p];
maxmx = xmax[p] - x[p];
maxmmin = xmax[p] - xmin[p];
dxdy[f++] = xmmin * maxmx / maxmmin;
if (xmmin<0.001*maxmmin)
nmin++;
else if (maxmx<0.001*maxmmin)
nmax++;
break;
case PARFIT_LOGBOUND:
xmmin = log(x[p]/xmin[p]);
maxmx = log(xmax[p]/x[p]);
maxmmin = log(xmax[p]/xmin[p]);
dxdy[f++] = x[p] * xmmin * maxmx / maxmmin;
if (xmmin<0.001*maxmmin)
nmin++;
else if (maxmx<0.001*maxmmin)
nmax++;
break;
default:
error(EXIT_FAILURE,
"*Internal Error*: Unknown parameter fitting type in ",
"profit_boundtounbound()");
Emmanuel Bertin
committed
nfree = f;
memset(profit->covar, 0, nparam*nparam*sizeof(float));
f2 = 0;
Emmanuel Bertin
committed
if (fittype[p2]!=PARFIT_FIXED)
{
f1 = 0;
for (p1=0; p1<nparam; p1++)
Emmanuel Bertin
committed
if (fittype[p1]!=PARFIT_FIXED)
{
covar[p2*nparam+p1] = (float)(dcovar[f2*nfree+f1]*dxdy[f1]*dxdy[f2]);
f1++;
}
f2++;
}
}
Emmanuel Bertin
committed
profit->nlimmin = nmin;
profit->nlimmax = nmax;
return nmin+nmax;
}
/****** prof_init *************************************************************
PROTO profstruct prof_init(profitstruct *profit, unsigned int modeltype)
PURPOSE Allocate and initialize a new profile structure.
INPUT Pointer to the profile-fitting structure,
OUTPUT A pointer to an allocated prof structure.
NOTES -.
AUTHOR E. Bertin (IAP)
VERSION 08/12/2011
profstruct *prof_init(profitstruct *profit, unsigned int modeltype)
rmax2, re2, dy2,r2, scale, zero, k,n, hinvn;
int width,height, ixc,iyc, ix,iy, nsub,
d,s;
QCALLOC(prof, profstruct, 1);
prof->code = modeltype;
switch(modeltype)
case MODEL_BACK:
prof->name = "background offset";
prof->naxis = 2;
prof->pix = NULL;
profit_addparam(profit, PARAM_BACK, &prof->flux);
prof->typscale = 1.0;
break;
case MODEL_DIRAC:
prof->name = "point source";
prof->naxis = 2;
prof->naxisn[0] = PROFIT_MAXMODSIZE;
prof->naxisn[1] = PROFIT_MAXMODSIZE;
prof->naxisn[2] = 1;
prof->npix = prof->naxisn[0]*prof->naxisn[1]*prof->naxisn[2];
QMALLOC(prof->pix, float, prof->npix);
prof->typscale = 1.0;
profit_addparam(profit, PARAM_X, &prof->x[0]);
profit_addparam(profit, PARAM_Y, &prof->x[1]);
profit_addparam(profit, PARAM_DIRAC_FLUX, &prof->flux);
break;
case MODEL_SERSIC:
prof->name = "Sersic spheroid";
prof->naxis = 2;
prof->naxisn[0] = PROFIT_MAXMODSIZE;
prof->naxisn[1] = PROFIT_MAXMODSIZE;
prof->naxisn[2] = 1;
prof->npix = prof->naxisn[0]*prof->naxisn[1]*prof->naxisn[2];
QMALLOC(prof->pix, float, prof->npix);
prof->typscale = 1.0;
profit_addparam(profit, PARAM_X, &prof->x[0]);
profit_addparam(profit, PARAM_Y, &prof->x[1]);
profit_addparam(profit, PARAM_SPHEROID_FLUX, &prof->flux);
profit_addparam(profit, PARAM_SPHEROID_REFF, &prof->scale);
profit_addparam(profit, PARAM_SPHEROID_ASPECT, &prof->aspect);
profit_addparam(profit, PARAM_SPHEROID_POSANG, &prof->posangle);
profit_addparam(profit, PARAM_SPHEROID_SERSICN, &prof->extra[0]);
break;
case MODEL_DEVAUCOULEURS:
prof->name = "de Vaucouleurs spheroid";
prof->naxisn[0] = PROFIT_MAXMODSIZE;
prof->naxisn[1] = PROFIT_MAXMODSIZE;
prof->naxisn[2] = 1;
prof->npix = prof->naxisn[0]*prof->naxisn[1]*prof->naxisn[2];
QMALLOC(prof->pix, float, prof->npix);
prof->typscale = 1.0;
profit_addparam(profit, PARAM_X, &prof->x[0]);
profit_addparam(profit, PARAM_Y, &prof->x[1]);
profit_addparam(profit, PARAM_SPHEROID_FLUX, &prof->flux);
profit_addparam(profit, PARAM_SPHEROID_REFF, &prof->scale);
profit_addparam(profit, PARAM_SPHEROID_ASPECT, &prof->aspect);
profit_addparam(profit, PARAM_SPHEROID_POSANG, &prof->posangle);
break;
case MODEL_EXPONENTIAL:
prof->name = "exponential disk";
prof->naxisn[0] = PROFIT_MAXMODSIZE;
prof->naxisn[1] = PROFIT_MAXMODSIZE;
prof->naxisn[2] = 1;
prof->npix = prof->naxisn[0]*prof->naxisn[1]*prof->naxisn[2];
QMALLOC(prof->pix, float, prof->npix);
prof->typscale = 1.0;
profit_addparam(profit, PARAM_X, &prof->x[0]);
profit_addparam(profit, PARAM_Y, &prof->x[1]);
profit_addparam(profit, PARAM_DISK_FLUX, &prof->flux);
profit_addparam(profit, PARAM_DISK_SCALE, &prof->scale);
profit_addparam(profit, PARAM_DISK_ASPECT, &prof->aspect);
profit_addparam(profit, PARAM_DISK_POSANG, &prof->posangle);
break;
case MODEL_ARMS:
prof->name = "spiral arms";
prof->naxisn[0] = PROFIT_MAXMODSIZE;
prof->naxisn[1] = PROFIT_MAXMODSIZE;
prof->naxisn[2] = 1;
prof->npix = prof->naxisn[0]*prof->naxisn[1]*prof->naxisn[2];
QMALLOC(prof->pix, float, prof->npix);
prof->typscale = 1.0;
profit_addparam(profit, PARAM_X, &prof->x[0]);
profit_addparam(profit, PARAM_Y, &prof->x[1]);
profit_addparam(profit, PARAM_DISK_SCALE, &prof->scale);
profit_addparam(profit, PARAM_DISK_ASPECT, &prof->aspect);
profit_addparam(profit, PARAM_DISK_POSANG, &prof->posangle);
profit_addparam(profit, PARAM_ARMS_FLUX, &prof->flux);
profit_addparam(profit, PARAM_ARMS_QUADFRAC, &prof->featfrac);
// profit_addparam(profit, PARAM_ARMS_SCALE, &prof->featscale);
profit_addparam(profit, PARAM_ARMS_START, &prof->featstart);
profit_addparam(profit, PARAM_ARMS_PITCH, &prof->featpitch);
// profit_addparam(profit, PARAM_ARMS_PITCHVAR, &prof->featpitchvar);
profit_addparam(profit, PARAM_ARMS_POSANG, &prof->featposang);
// profit_addparam(profit, PARAM_ARMS_WIDTH, &prof->featwidth);
break;
case MODEL_BAR:
prof->name = "bar";
prof->naxisn[0] = PROFIT_MAXMODSIZE;
prof->naxisn[1] = PROFIT_MAXMODSIZE;
prof->naxisn[2] = 1;
prof->npix = prof->naxisn[0]*prof->naxisn[1]*prof->naxisn[2];
QMALLOC(prof->pix, float, prof->npix);
prof->typscale = 1.0;
profit_addparam(profit, PARAM_X, &prof->x[0]);
profit_addparam(profit, PARAM_Y, &prof->x[1]);
profit_addparam(profit, PARAM_DISK_SCALE, &prof->scale);
profit_addparam(profit, PARAM_DISK_ASPECT, &prof->aspect);
profit_addparam(profit, PARAM_DISK_POSANG, &prof->posangle);
profit_addparam(profit, PARAM_ARMS_START, &prof->featstart);
profit_addparam(profit, PARAM_BAR_FLUX, &prof->flux);
profit_addparam(profit, PARAM_BAR_ASPECT, &prof->feataspect);
profit_addparam(profit, PARAM_ARMS_POSANG, &prof->featposang);
break;
case MODEL_INRING:
prof->name = "inner ring";
prof->naxisn[0] = PROFIT_MAXMODSIZE;
prof->naxisn[1] = PROFIT_MAXMODSIZE;
prof->naxisn[2] = 1;
prof->npix = prof->naxisn[0]*prof->naxisn[1]*prof->naxisn[2];
QMALLOC(prof->pix, float, prof->npix);
prof->typscale = 1.0;
profit_addparam(profit, PARAM_X, &prof->x[0]);
profit_addparam(profit, PARAM_Y, &prof->x[1]);
profit_addparam(profit, PARAM_DISK_SCALE, &prof->scale);
profit_addparam(profit, PARAM_DISK_ASPECT, &prof->aspect);
profit_addparam(profit, PARAM_DISK_POSANG, &prof->posangle);
profit_addparam(profit, PARAM_ARMS_START, &prof->featstart);
profit_addparam(profit, PARAM_INRING_FLUX, &prof->flux);
profit_addparam(profit, PARAM_INRING_WIDTH, &prof->featwidth);
profit_addparam(profit, PARAM_INRING_ASPECT, &prof->feataspect);
break;
case MODEL_OUTRING:
prof->name = "outer ring";
prof->naxisn[0] = PROFIT_MAXMODSIZE;
prof->naxisn[1] = PROFIT_MAXMODSIZE;
prof->naxisn[2] = 1;
prof->npix = prof->naxisn[0]*prof->naxisn[1]*prof->naxisn[2];
QMALLOC(prof->pix, float, prof->npix);
prof->typscale = 1.0;
profit_addparam(profit, PARAM_X, &prof->x[0]);
profit_addparam(profit, PARAM_Y, &prof->x[1]);
profit_addparam(profit, PARAM_DISK_SCALE, &prof->scale);
profit_addparam(profit, PARAM_DISK_ASPECT, &prof->aspect);
profit_addparam(profit, PARAM_DISK_POSANG, &prof->posangle);
profit_addparam(profit, PARAM_OUTRING_START, &prof->featstart);
profit_addparam(profit, PARAM_OUTRING_FLUX, &prof->flux);
profit_addparam(profit, PARAM_OUTRING_WIDTH, &prof->featwidth);
break;
case MODEL_TABULATED: /* An example of tabulated profile */
prof->name = "tabulated model";
width = prof->naxisn[0] = PROFIT_MAXMODSIZE;
height = prof->naxisn[1] = PROFIT_MAXMODSIZE;
nsub = prof->naxisn[2] = PROFIT_MAXSMODSIZE;
prof->npix = prof->naxisn[0]*prof->naxisn[1]*prof->naxisn[2];
QMALLOC(prof->pix, float, prof->npix);
ixc = width/2;
iyc = height/2;
rmax2 = (ixc - 1.0)*(ixc - 1.0);
re2 = width/64.0;
prof->typscale = re2;
re2 *= re2;
zero = prof->extrazero[0] = 0.2;
scale = prof->extrascale[0]= 8.0/PROFIT_MAXSMODSIZE;
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
pix = prof->pix;
for (s=0; s<nsub; s++)
{
n = s*scale + zero;
hinvn = 0.5/n;
k = -1.0/3.0 + 2.0*n + 4.0/(405.0*n) + 46.0/(25515.0*n*n)
+ 131.0/(1148175*n*n*n);
for (iy=0; iy<height; iy++)
{
dy2 = (iy-iyc)*(iy-iyc);
for (ix=0; ix<width; ix++)
{
r2 = dy2 + (ix-ixc)*(ix-ixc);
*(pix++) = (r2<rmax2)? exp(-k*pow(r2/re2,hinvn)) : 0.0;
}
}
}
profit_addparam(profit, PARAM_X, &prof->x[0]);
profit_addparam(profit, PARAM_Y, &prof->x[1]);
profit_addparam(profit, PARAM_SPHEROID_FLUX, &prof->flux);
profit_addparam(profit, PARAM_SPHEROID_REFF, &prof->scale);
profit_addparam(profit, PARAM_SPHEROID_ASPECT, &prof->aspect);
profit_addparam(profit, PARAM_SPHEROID_POSANG, &prof->posangle);
profit_addparam(profit, PARAM_SPHEROID_SERSICN, &prof->extra[0]);
break;
default:
error(EXIT_FAILURE, "*Internal Error*: Unknown profile in ",
"prof_init()");
break;
}
{
prof->kernelnlines = 1;
for (d=0; d<prof->naxis; d++)
{
prof->interptype[d] = INTERP_BILINEAR;
prof->kernelnlines *=
(prof->kernelwidth[d] = interp_kernwidth[prof->interptype[d]]);
}
prof->kernelnlines /= prof->kernelwidth[0];
Emmanuel Bertin
committed
QMALLOC16(prof->kernelbuf, float, prof->kernelnlines);
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
}
return prof;
}
/****** prof_end **************************************************************
PROTO void prof_end(profstruct *prof)
PURPOSE End (deallocate) a profile structure.
INPUT Prof structure.
OUTPUT -.
NOTES -.
AUTHOR E. Bertin (IAP)
VERSION 09/04/2007
***/
void prof_end(profstruct *prof)
{
if (prof->pix)
{
free(prof->pix);
free(prof->kernelbuf);
}
free(prof);
return;
}
/****** prof_add **************************************************************
PROTO float prof_add(profitstruct *profit, profstruct *prof,
int extfluxfac_flag)
INPUT Profile-fitting structure,
profile structure,
flag (0 if flux correction factor is to be computed internally)
OUTPUT Total (asymptotic) flux contribution.
Emmanuel Bertin
committed
VERSION 25/07/2011
float prof_add(profitstruct *profit, profstruct *prof, int extfluxfac_flag)
Emmanuel Bertin
committed
double xscale, yscale, saspect, ctheta,stheta, flux, scaling, bn, n,
dx1cout,dx2cout, ddx1[36],ddx2[36];
float posin[PROFIT_MAXEXTRA], posout[2], dnaxisn[2],
fluxfac, amp,cd11,cd12,cd21,cd22, dx1,dx2,
x1,x10,x2, x1cin,x2cin, x1cout,x2cout, x1max,x2max, x1in,x2in,
k, hinvn, x1t,x2t, ca,sa, u,umin,
armamp,arm2amp, armrdphidr, armrdphidrvar, posang,
width, invwidth2,
r,r2,rmin, r2minxin,r2minxout, rmax, r2max,
r2max1, r2max2, r2min, invr2xdif,
val, theta, thresh, ra,rb, num,num2,den, ang,angstep,
invn, dr, krpinvn,dkrpinvn, rs,rs2,
Emmanuel Bertin
committed
a11,a12,a21,a22, invdet, dca,dsa, a0,a2,a3, p1,p2,
krspinvn, ekrspinvn, selem;
int npix, threshflag,
a,d,e,i, ix1,ix2, ix1max,ix2max, nang, nx2,
Emmanuel Bertin
committed
npix2;
npix = profit->nmodpix;
if (prof->code==MODEL_BACK)
{
amp = fabs(*prof->flux);
pixout = profit->modpix;
for (i=npix; i--;)
*(pixout++) += amp;
prof->lostfluxfrac = 0.0;
return 0.0;
}
scaling = profit->pixstep / prof->typscale;
if (prof->code!=MODEL_DIRAC)
{
/*-- Compute Profile CD matrix */
ctheta = cos(*prof->posangle*DEG);
stheta = sin(*prof->posangle*DEG);
saspect = fabs(*prof->aspect);
xscale = (*prof->scale==0.0)?
0.0 : fabs(scaling / (*prof->scale*prof->typscale));
yscale = (*prof->scale*saspect == 0.0)?
0.0 : fabs(scaling / (*prof->scale*prof->typscale*saspect));
cd11 = (float)(xscale*ctheta);
cd12 = (float)(xscale*stheta);
cd21 = (float)(-yscale*stheta);
cd22 = (float)(yscale*ctheta);
dx1 = 0.0; /* Shifting operations have been moved to profit_resample() */
dx2 = 0.0; /* Shifting operations have been moved to profit_resample() */
x1cout = (float)(profit->modnaxisn[0]/2);
x2cout = (float)(profit->modnaxisn[1]/2);
/*-- Compute the largest r^2 that fits in the frame */
num = cd11*cd22-cd12*cd21;
x1max = x1cout - 1.0;
x2max = x2cout - 1.0;
den = fabs(cd12*cd12+cd22*cd22);
num2 = x1max*x1max*num;
r2max1 = num2<PROFIT_MAXR2MAX*den? num2 / den : PROFIT_MAXR2MAX;
den = fabs(cd11*cd11+cd21*cd21);
num2 = x2max*x2max*num;
r2max2 = num2<PROFIT_MAXR2MAX*den? num2 / den : PROFIT_MAXR2MAX;
r2max = (r2max1 < r2max2? r2max1 : r2max2);
Emmanuel Bertin
committed
rmax = sqrtf(r2max);
memset(prof->pix, 0, profit->nmodpix);
prof->pix[profit->modnaxisn[0]/2
+ (profit->modnaxisn[1]/2)*profit->modnaxisn[0]] = 1.0;
prof->lostfluxfrac = 0.0;
threshflag = 0;
break;
case MODEL_SERSIC:
case MODEL_DEVAUCOULEURS:
case MODEL_EXPONENTIAL:
Emmanuel Bertin
committed
/*---- Compute sharp/smooth transition radius */
rs = PROFIT_SMOOTHR*(xscale>yscale?xscale:yscale);
if (rs<=0)
rs = 1.0;
rs2 = rs*rs;
/*---- The consequence of sampling on flux is compensated by PSF normalisation*/
if (prof->code==MODEL_EXPONENTIAL)
Emmanuel Bertin
committed
bn = n = 1.0;
else if (prof->code==MODEL_DEVAUCOULEURS)
Emmanuel Bertin
committed
{
n = 4.0;
bn = 7.66924944;
}
else
{
n = fabs(*prof->extra[0]);
bn = 2.0*n - 1.0/3.0 + 4.0/(405.0*n) + 46.0/(25515.0*n*n)
+ 131.0/(1148175*n*n*n); /* Ciotti & Bertin 1999 */
Emmanuel Bertin
committed
}
invn = 1.0/n;
Emmanuel Bertin
committed
k = -bn;
/*---- Compute central polynomial terms */
krspinvn = prof->code==MODEL_EXPONENTIAL? -rs : k*expf(logf(rs)*invn);
Emmanuel Bertin
committed
ekrspinvn = expf(krspinvn);
p2 = krspinvn*invn*invn;
p1 = krspinvn*p2;
a0 = (1+(1.0/6.0)*(p1+(1.0-5.0*n)*p2))*ekrspinvn;
a2 = (-1.0/2.0)*(p1+(1.0-3.0*n)*p2)/rs2*ekrspinvn;
a3 = (1.0/3.0)*(p1+(1.0-2.0*n)*p2)/(rs2*rs)*ekrspinvn;
/*---- Compute the smooth part of the profile */
x10 = -x1cout - dx1;
x2 = -x2cout - dx2;
if (prof->code==MODEL_EXPONENTIAL)
Emmanuel Bertin
committed
for (ix2=nx2; ix2--; x2+=1.0)
Emmanuel Bertin
committed
x1 = x10;
for (ix1=profit->modnaxisn[0]; ix1--; x1+=1.0)
Emmanuel Bertin
committed
x1in = cd12*x2 + cd11*x1;
x2in = cd22*x2 + cd21*x1;
ra = x1in*x1in+x2in*x2in;
if (ra>r2max)
Emmanuel Bertin
committed
*(pixin++) = 0.0;
continue;
Emmanuel Bertin
committed
val = ra<rs2? a0+ra*(a2+a3*sqrtf(ra)) : expf(-sqrtf(ra));
*(pixin++) = val;
Emmanuel Bertin
committed
else
for (ix2=nx2; ix2--; x2+=1.0)
Emmanuel Bertin
committed
x1 = x10;
for (ix1=profit->modnaxisn[0]; ix1--; x1+=1.0)
{
Emmanuel Bertin
committed
x1in = cd12*x2 + cd11*x1;
x2in = cd22*x2 + cd21*x1;
ra = x1in*x1in+x2in*x2in;
if (ra>r2max)
Emmanuel Bertin
committed
*(pixin++) = 0.0;
continue;
Emmanuel Bertin
committed
val = ra<rs2? a0+ra*(a2+a3*sqrtf(ra)) : expf(k*expf(logf(ra)*hinvn));
*(pixin++) = val;
/*---- Copy the symmetric part */
if ((npix2=(profit->modnaxisn[1]-nx2)*profit->modnaxisn[0]) > 0)
{
pixin2 = pixin - profit->modnaxisn[0] - 1;
if (!(profit->modnaxisn[0]&1))
{
*(pixin++) = 0.0;
npix2--;
}
for (i=npix2; i--;)
*(pixin++) = *(pixin2--);
}
Emmanuel Bertin
committed
/*---- Compute the sharp part of the profile */
ix1max = profit->modnaxisn[0];
ix2max = profit->modnaxisn[1];
dx1cout = x1cout + 0.4999999;
dx2cout = x2cout + 0.4999999;
invdet = 1.0/fabsf(cd11*cd22 - cd12*cd21);
a11 = cd22*invdet;
a12 = -cd12*invdet;
a21 = -cd21*invdet;
a22 = cd11*invdet;
nang = 72 / 2; /* 36 angles; only half of them are computed*/
angstep = PI/nang;
ang = 0.0;
for (a=0; a<nang; a++)
Emmanuel Bertin
committed
sincosf(ang, &dsa, &dca);
#else
dsa = sinf(ang);
dca = cosf(ang);
#endif
ddx1[a] = a11*dsa+a12*dca;
ddx2[a] = a21*dsa+a22*dca;
Emmanuel Bertin
committed
ang += angstep;
Emmanuel Bertin
committed
r = DEXPF(-4.0);
dr = DEXPF(0.05);
selem = 0.5*angstep*(dr - 1.0/dr)/(xscale*yscale);
krpinvn = k*DEXPF(-4.0*invn);
dkrpinvn = DEXPF(0.05*invn);
pixin = prof->pix;
for (; r<rs; r *= dr)
Emmanuel Bertin
committed
r2 = r*r;
val = (expf(krpinvn) - (a0 + r2*(a2+a3*r)))*r2*selem;
for (a=0; a<nang; a++)
Emmanuel Bertin
committed
ix1 = (int)(dx1cout + r*ddx1[a]);
ix2 = (int)(dx2cout + r*ddx2[a]);
if (ix1>=0 && ix1<ix1max && ix2>=0 && ix2<ix2max)
pixin[ix2*ix1max+ix1] += val;
ix1 = (int)(dx1cout - r*ddx1[a]);
ix2 = (int)(dx2cout - r*ddx2[a]);
if (ix1>=0 && ix1<ix1max && ix2>=0 && ix2<ix2max)
pixin[ix2*ix1max+ix1] += val;
Emmanuel Bertin
committed
krpinvn *= dkrpinvn;
Emmanuel Bertin
committed
prof->lostfluxfrac = prof->code==MODEL_EXPONENTIAL?
Emmanuel Bertin
committed
(1.0 + rmax)*exp(-rmax)
:1.0 - prof_gammainc(2.0*n, bn*pow(r2max, hinvn));
threshflag = 0;
r2min = *prof->featstart**prof->featstart;
r2minxin = r2min * (1.0 - PROFIT_BARXFADE) * (1.0 - PROFIT_BARXFADE);
r2minxout = r2min * (1.0 + PROFIT_BARXFADE) * (1.0 + PROFIT_BARXFADE);
if ((invr2xdif = (r2minxout - r2minxin)) > 0.0)
invr2xdif = 1.0 / invr2xdif;
else
invr2xdif = 1.0;
umin = 0.5*logf(r2minxin + 0.00001);
arm2amp = *prof->featfrac;