Newer
Older
}
/****** profit_addparam *******************************************************
PROTO void profit_addparam(profitstruct *profit, paramenum paramindex,
PURPOSE Add a profile parameter to the list of fitted items.
INPUT Pointer to the profit structure,
Parameter index,
Pointer to the parameter pointer.
OUTPUT -.
NOTES -.
AUTHOR E. Bertin (IAP)
***/
void profit_addparam(profitstruct *profit, paramenum paramindex,
{
/* Check whether the parameter has already be registered */
if (profit->paramlist[paramindex])
/*-- Yes */
*param = profit->paramlist[paramindex];
else
/*-- No */
{
*param = profit->paramlist[paramindex] = &profit->param[profit->nparam];
profit->paramindex[paramindex] = profit->nparam;
profit->paramrevindex[profit->nparam++] = paramindex;
}
return;
}
/****** profit_resetparam ****************************************************
PROTO void profit_resetparam(profitstruct *profit, paramenum paramtype)
PURPOSE Set the initial, lower and upper boundary values of a profile parameter.
INPUT Pointer to the profit structure,
Parameter index.
Emmanuel Bertin
committed
OUTPUT .
Emmanuel Bertin
committed
VERSION 15/01/2013
***/
void profit_resetparam(profitstruct *profit, paramenum paramtype)
{
obj2struct *obj2;
Emmanuel Bertin
committed
float param, parammin,parammax, range, priorcen,priorsig;
Emmanuel Bertin
committed
parfitenum fittype;
Emmanuel Bertin
committed
param = parammin = parammax = priorcen = priorsig = 0.0;
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;
Emmanuel Bertin
committed
if (range>profit->objnaxisn[0]*profit->subsamp*2.0)
range = profit->objnaxisn[0]*profit->subsamp*2.0;
parammin = -range;
parammax = range;
Emmanuel Bertin
committed
fittype = PARFIT_LINBOUND;
param = profit->guessdy;
Emmanuel Bertin
committed
range = profit->guessradius*4.0;
Emmanuel Bertin
committed
if (range>profit->objnaxisn[1]*profit->subsamp*2)
range = profit->objnaxisn[1]*profit->subsamp*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
priorcen = 0.3;
priorsig = 0.0 /*0.4*/;
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;
Emmanuel Bertin
committed
priorcen = 1.0;
priorsig = 0.0 /*2.0*/;
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,
priorcen, priorsig);
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
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,
Emmanuel Bertin
committed
parfitenum parfittype,
float priorcen, float priorsig)
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.
Emmanuel Bertin
committed
prior central value,
prior standard deviation.
OUTPUT RETURN_OK if the parameter is registered, RETURN_ERROR otherwise.
AUTHOR E. Bertin (IAP)
Emmanuel Bertin
committed
VERSION 16/01/2013
***/
int profit_setparam(profitstruct *profit, paramenum paramtype,
Emmanuel Bertin
committed
float param, float parammin,float parammax,
Emmanuel Bertin
committed
parfitenum parfittype,
float priorcen, float priorsig)
Emmanuel Bertin
committed
double dtemp;
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;
Emmanuel Bertin
committed
profit_boundtounbound(profit, &priorcen, &profit->dparampcen[index], index);
profit->dparampsig[index] = priorsig;
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
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
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;
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
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);
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
}
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 13/02/2013
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;