profit.c 146 KB
Newer Older
3001
/****** profit_surface ****************************************************
3002
PROTO	void profit_surface(profitstruct *profit, obj2struct *obj2)
3003
3004
PURPOSE	Compute surface brightnesses from the unconvolved object model.
INPUT	Pointer to the profile-fitting structure,
3005
	Pointer to obj2 structure.
3006
3007
3008
OUTPUT	-.
NOTES	-.
AUTHOR	E. Bertin (IAP)
3009
VERSION	06/09/2011
3010
 ***/
3011
void	 profit_surface(profitstruct *profit, obj2struct *obj2)
3012
  {
3013
   profitstruct	hdprofit;
3014
   double	dsum,dhsum,dsumoff, dhval, frac, seff;
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
   float	*spix, *spixt,
		val,vmax,
		scalefac, imsizefac, flux, lost, sum, lostfluxfrac;
   int		i,p, imax, npix, neff;

/* Allocate "high-definition" raster only to make measurements */
  hdprofit.modnaxisn[0] = hdprofit.modnaxisn[1] = PROFIT_HIDEFRES;
  npix = hdprofit.nmodpix = hdprofit.modnaxisn[0]*hdprofit.modnaxisn[1];
/* Find best image size factor from fitting results */
  imsizefac = 2.0*profit_minradius(profit, PROFIT_REFFFAC)/profit->pixstep
	/ (float)profit->modnaxisn[0];
  if (imsizefac<0.01)
    imsizefac = 0.01;
  else if (imsizefac>100.0)
    imsizefac = 100.0;
  scalefac = (float)hdprofit.modnaxisn[0] / (float)profit->modnaxisn[0]
	/ imsizefac;
  hdprofit.pixstep = profit->pixstep / scalefac;
3033
  hdprofit.fluxfac = 1.0/(hdprofit.pixstep*hdprofit.pixstep);
3034
3035
3036
3037
3038
  QCALLOC(hdprofit.modpix, float,npix*sizeof(float));

  for (p=0; p<profit->nparam; p++)
    profit->param[p] = profit->paraminit[p];
  lost = sum = 0.0;
3039

3040
3041
3042
3043
3044
3045
3046
3047
  for (p=0; p<profit->nprof; p++)
    {
    sum += (flux = prof_add(&hdprofit, profit->prof[p],0));
    lost += flux*profit->prof[p]->lostfluxfrac;
    }
  lostfluxfrac = sum > 0.0? lost / sum : 0.0;
/*
char filename[256];
3048
checkstruct *check;
3049
3050
3051
3052
3053
3054
3055
3056
3057
sprintf(filename, "raster_%02d.fits", the_gal);
check=initcheck(filename, CHECK_OTHER, 0);
check->width = hdprofit.modnaxisn[0];
check->height = hdprofit.modnaxisn[1];
reinitcheck(the_field, check);
memcpy(check->pix,hdprofit.modpix,check->npix*sizeof(float));
reendcheck(the_field, check);
endcheck(check);
*/
3058
3059
  if (FLAG(obj2.fluxeff_prof))
    {
3060
3061
3062
/*-- Sort model pixel values */
    spix = NULL;			/* to avoid gcc -Wall warnings */
    QMEMCPY(hdprofit.modpix, spix, float, npix);
3063
    fqmedian(spix, npix);
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
/*-- Build a cumulative distribution */
    dsum = 0.0;
    spixt = spix;
    for (i=npix; i--;)
      dsum += (double)*(spixt++);
/*-- Find matching surface brightness */
    if (lostfluxfrac > 1.0)
      lostfluxfrac = 0.0;
    dhsum = 0.5 * dsum / (1.0-lostfluxfrac);
    dsum = lostfluxfrac * dsum / (1.0-lostfluxfrac);
    neff = 0;
    spixt = spix;
    for (i=npix; i--;)
      if ((dsum += (double)*(spixt++)) >= dhsum)
        {
        neff = i;
        break;
        }
    dhval = (double)*(spixt-1);
    seff = neff;
    dsumoff = 0.0;
    if (spixt>=spix+2)
      if (dhval > 0.0 && (frac = (dsum - dhsum) / dhval) < 1.0)
        {
        seff += frac;
        dsumoff = frac*dhval;
        dhval = dsumoff + (1.0 - frac)*(double)*(spixt-2);
        }
    obj2->fluxeff_prof = dhval;
    if (FLAG(obj2.fluxmean_prof))
      {
      dsum = dsumoff;
      for (i=neff; i--;)
        dsum += (double)*(spixt++);
      obj2->fluxmean_prof = seff > 0.0? dsum / seff : 0.0;
      }
3100
3101
3102
    free(spix);
    }

3103
/* Compute model peak */
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
  if (FLAG(obj2.peak_prof))
    {
/*-- Find position of maximum pixel in current hi-def raster */
    imax = 0;
    vmax = -BIG;
    spixt = hdprofit.modpix;
    for (i=npix; i--;)
      if ((val=*(spixt++))>vmax)
        {
        vmax = val;
        imax = i;
        }
    imax = npix-1 - imax;
    obj2->peak_prof = hdprofit.modpix[imax];
3118
3119
    }

3120
3121
/* Free hi-def model raster */
  free(hdprofit.modpix);
3122
3123
3124
3125
3126

  return;
  }


Emmanuel Bertin's avatar
Emmanuel Bertin committed
3127
3128
/****** profit_addparam *******************************************************
PROTO	void profit_addparam(profitstruct *profit, paramenum paramindex,
3129
		float **param)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3130
3131
3132
3133
3134
3135
3136
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)
3137
VERSION	29/03/2010
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3138
3139
 ***/
void	profit_addparam(profitstruct *profit, paramenum paramindex,
3140
		float **param)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3141
3142
3143
3144
3145
3146
3147
3148
3149
  {
/* 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];
3150
3151
    profit->paramindex[paramindex] = profit->nparam;
    profit->paramrevindex[profit->nparam++] = paramindex;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
    }

  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.
3163
OUTPUT	.
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3164
3165
NOTES	-.
AUTHOR	E. Bertin (IAP)
3166
VERSION	24/04/2013
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3167
3168
3169
3170
 ***/
void	profit_resetparam(profitstruct *profit, paramenum paramtype)
  {
   obj2struct	*obj2;
3171
   float	param, parammin,parammax, range, priorcen,priorsig;
3172
   parfitenum	fittype;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3173
3174

  obj2 = profit->obj2;
3175
  param = parammin = parammax = priorcen = priorsig = 0.0;
3176

Emmanuel Bertin's avatar
Emmanuel Bertin committed
3177
3178
3179
  switch(paramtype)
    {
    case PARAM_BACK:
3180
      fittype = PARFIT_LINBOUND;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3181
      param = 0.0;
3182
3183
      parammin = -6.0*profit->guesssigbkg;
      parammax =  6.0*profit->guesssigbkg;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3184
3185
      break;
    case PARAM_X:
3186
      fittype = PARFIT_LINBOUND;
3187
      param = profit->guessdx;
3188
      range = profit->guessradius*4.0;
3189
3190
      if (range>profit->objnaxisn[0]*profit->subsamp*2.0)
        range = profit->objnaxisn[0]*profit->subsamp*2.0;
3191
3192
      parammin = -range;
      parammax =  range;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3193
3194
      break;
    case PARAM_Y:
3195
      fittype = PARFIT_LINBOUND;
3196
      param = profit->guessdy;
3197
      range = profit->guessradius*4.0;
3198
3199
      if (range>profit->objnaxisn[1]*profit->subsamp*2.0)
        range = profit->objnaxisn[1]*profit->subsamp*2.0;
3200
3201
      parammin = -range;
      parammax =  range;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3202
      break;
3203
    case PARAM_DIRAC_FLUX:
3204
3205
3206
3207
      fittype = PARFIT_LOGBOUND;
      param = profit->guessflux/profit->nprof;
      parammin = 0.00001*profit->guessfluxmax;
      parammax = 10.0*profit->guessfluxmax;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3208
      break;
3209
    case PARAM_SPHEROID_FLUX:
3210
3211
3212
3213
      fittype = PARFIT_LOGBOUND;
      param = profit->guessflux/profit->nprof;
      parammin = 0.00001*profit->guessfluxmax;
      parammax = 10.0*profit->guessfluxmax;
3214
      break;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3215
    case PARAM_SPHEROID_REFF:
3216
3217
      fittype = PARFIT_LOGBOUND;
      param = FLAG(obj2.prof_disk_flux)? profit->guessradius
3218
			: profit->guessradius/sqrtf(profit->guessaspect);
3219
      parammin = 0.01;
3220
      parammax = param * 10.0;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3221
3222
      break;
    case PARAM_SPHEROID_ASPECT:
3223
      fittype = PARFIT_LOGBOUND;
3224
      param = FLAG(obj2.prof_disk_flux)? 1.0 : profit->guessaspect;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3225
      parammin = FLAG(obj2.prof_disk_flux)? 0.5 : 0.01;
3226
      parammax = FLAG(obj2.prof_disk_flux)? 2.0 : 100.0;
3227
3228
      priorcen = 0.3;
      priorsig = 0.0 /*0.4*/;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3229
3230
      break;
    case PARAM_SPHEROID_POSANG:
3231
      fittype = PARFIT_UNBOUND;
3232
      param = profit->guessposang;
3233
3234
      parammin = 90.0;
      parammax =  90.0;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3235
3236
      break;
    case PARAM_SPHEROID_SERSICN:
3237
      fittype = PARFIT_LINBOUND;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3238
      param = 4.0;
3239
      parammin = FLAG(obj2.prof_disk_flux)? 1.0 : 0.3;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3240
      parammax = 10.0;
3241
3242
      priorcen = 1.0;
      priorsig = 0.0 /*2.0*/;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3243
3244
      break;
    case PARAM_DISK_FLUX:
3245
3246
3247
3248
      fittype = PARFIT_LOGBOUND;
      param = profit->guessflux/profit->nprof;
      parammin = 0.00001*profit->guessfluxmax;
      parammax = 10.0*profit->guessfluxmax;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3249
3250
      break;
    case PARAM_DISK_SCALE:	/* From scalelength to Re */
3251
      fittype = PARFIT_LOGBOUND;
3252
      param = profit->guessradius/(1.67835*sqrtf(profit->guessaspect));
3253
3254
      parammin = 0.01/1.67835;
      parammax = param * 10.0;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3255
3256
      break;
    case PARAM_DISK_ASPECT:
3257
      fittype = PARFIT_LOGBOUND;
3258
      param = profit->guessaspect;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3259
      parammin = 0.01;
3260
      parammax = 100.0;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3261
3262
      break;
    case PARAM_DISK_POSANG:
3263
      fittype = PARFIT_UNBOUND;
3264
      param = profit->guessposang;
3265
3266
      parammin = 90.0;
      parammax =  90.0;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3267
3268
      break;
    case PARAM_ARMS_FLUX:
3269
3270
3271
3272
      fittype = PARFIT_LOGBOUND;
      param = profit->guessflux/profit->nprof;
      parammin = 0.00001*profit->guessfluxmax;
      parammax = 10.0*profit->guessfluxmax;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3273
3274
      break;
    case PARAM_ARMS_QUADFRAC:
3275
      fittype = PARFIT_LINBOUND;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3276
3277
3278
3279
3280
      param = 0.5;
      parammin = 0.0;
      parammax = 1.0;
      break;
    case PARAM_ARMS_SCALE:
3281
      fittype = PARFIT_LINBOUND;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3282
3283
3284
3285
3286
      param = 1.0;
      parammin = 0.5;
      parammax = 10.0;
      break;
    case PARAM_ARMS_START:
3287
      fittype = PARFIT_LINBOUND;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3288
3289
3290
3291
3292
      param = 0.5;
      parammin = 0.0;
      parammax = 3.0;
      break;
    case PARAM_ARMS_PITCH:
3293
      fittype = PARFIT_LINBOUND;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3294
3295
3296
3297
3298
      param = 20.0;
      parammin = 5.0;
      parammax = 50.0;
      break;
    case PARAM_ARMS_PITCHVAR:
3299
      fittype = PARFIT_LINBOUND;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
      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:
3313
      fittype = PARFIT_UNBOUND;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3314
3315
3316
3317
3318
      param = 0.0;
      parammin = 0.0;
      parammax = 0.0;
      break;
    case PARAM_ARMS_WIDTH:
3319
      fittype = PARFIT_LINBOUND;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3320
3321
3322
3323
3324
      param = 3.0;
      parammin = 1.5;
      parammax = 11.0;
      break;
    case PARAM_BAR_FLUX:
3325
3326
3327
3328
      fittype = PARFIT_LOGBOUND;
      param = profit->guessflux/profit->nprof;
      parammin = 0.00001*profit->guessfluxmax;
      parammax = 4.0*profit->guessfluxmax;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3329
3330
      break;
    case PARAM_BAR_ASPECT:
3331
      fittype = PARFIT_LOGBOUND;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3332
3333
3334
3335
3336
      param = 0.3;
      parammin = 0.2;
      parammax = 0.5;
      break;
    case PARAM_BAR_POSANG:
3337
      fittype = PARFIT_UNBOUND;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3338
      param = 0.0;
3339
3340
      parammin = 90.0;
      parammax = 90.0;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3341
3342
      break;
    case PARAM_INRING_FLUX:
3343
3344
3345
3346
      fittype = PARFIT_LOGBOUND;
      param = profit->guessflux/profit->nprof;
      parammin = 0.00001*profit->guessfluxmax;
      parammax = 4.0*profit->guessfluxmax;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3347
3348
      break;
    case PARAM_INRING_WIDTH:
3349
      fittype = PARFIT_LINBOUND;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3350
3351
3352
3353
3354
      param = 0.3;
      parammin = 0.0;
      parammax = 0.5;
      break;
    case PARAM_INRING_ASPECT:
3355
      fittype = PARFIT_LOGBOUND;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3356
3357
3358
3359
3360
      param = 0.8;
      parammin = 0.4;
      parammax = 1.0;
      break;
    case PARAM_OUTRING_FLUX:
3361
3362
3363
3364
      fittype = PARFIT_LOGBOUND;
      param = profit->guessflux/profit->nprof;
      parammin = 0.00001*profit->guessfluxmax;
      parammax = 4.0*profit->guessfluxmax;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3365
3366
      break;
    case PARAM_OUTRING_START:
3367
      fittype = PARFIT_LINBOUND;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3368
3369
3370
3371
3372
      param = 4.0;
      parammin = 3.5;
      parammax = 6.0;
      break;
    case PARAM_OUTRING_WIDTH:
3373
      fittype = PARFIT_LINBOUND;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
      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;
3386
3387
  else if (parammin==0.0 && parammax==0.0)
    parammax = 1.0;
3388
3389
  profit_setparam(profit, paramtype, param, parammin, parammax, fittype,
	priorcen, priorsig);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417

  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,
3418
		float param, float parammin, float parammax,
3419
3420
		parfitenum parfittype,
		float priorcen, float priorsig)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3421
3422
PURPOSE	Set the actual, lower and upper boundary values of a profile parameter.
INPUT	Pointer to the profit structure,
3423
3424
3425
3426
3427
	parameter index,
	actual value,
	lower boundary to the parameter,
	upper boundary to the parameter,
	parameter fitting type.
3428
3429
	prior central value,
	prior standard deviation.
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3430
3431
OUTPUT	RETURN_OK if the parameter is registered, RETURN_ERROR otherwise.
AUTHOR	E. Bertin (IAP)
3432
VERSION	16/01/2013
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3433
3434
 ***/
int	profit_setparam(profitstruct *profit, paramenum paramtype,
3435
		float param, float parammin,float parammax,
3436
3437
		parfitenum parfittype,
		float priorcen, float priorsig)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3438
  {
3439
   double	dtemp;
3440
   float	*paramptr;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3441
3442
3443
3444
3445
   int		index;

/* Check whether the parameter has already be registered */
  if ((paramptr=profit->paramlist[(int)paramtype]))
    {
3446
    index = profit->paramindex[(int)paramtype];
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3447
3448
3449
    profit->paraminit[index] = param;
    profit->parammin[index] = parammin;
    profit->parammax[index] = parammax;
3450
    profit->parfittype[index] = parfittype;
3451
3452
    profit_boundtounbound(profit, &priorcen, &profit->dparampcen[index], index);
    profit->dparampsig[index] = priorsig;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3453
3454
3455
3456
3457
3458
3459
3460
    return RETURN_OK;
    }
  else
    return RETURN_ERROR;
  }

  
/****** profit_boundtounbound *************************************************
3461
PROTO	int profit_boundtounbound(profitstruct *profit,
3462
				float *param, double *dparam, int index)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3463
PURPOSE	Convert parameters from bounded to unbounded space.
3464
3465
3466
3467
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)
3468
OUTPUT	Number of free parameters.
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3469
3470
NOTES	-.
AUTHOR	E. Bertin (IAP)
3471
VERSION	20/05/2011
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3472
 ***/
3473
int	profit_boundtounbound(profitstruct *profit,
3474
				float *param, double *dparam, int index)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3475
  {
3476
   double	num,den, tparam;
3477
   int		f,p, pstart,np;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3478

3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
  if (index<0)
    {
    pstart = 0;
    np = profit->nparam;
    }
  else
    {
    pstart = index;
    np = pstart+1;
    }

  f = 0;
  for (p=pstart ; p<np; p++)
3492
    switch(profit->parfittype[p])
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3493
      {
3494
3495
3496
3497
3498
3499
3500
3501
3502
      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];
3503
3504
3505
        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;
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
        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's avatar
Emmanuel Bertin committed
3519
3520
      }

3521
  return f;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3522
3523
3524
3525
  }


/****** profit_unboundtobound *************************************************
3526
PROTO	int profit_unboundtobound(profitstruct *profit,
3527
				double *dparam, float *param, int index)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3528
PURPOSE	Convert parameters from unbounded to bounded space.
3529
3530
3531
3532
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)
3533
OUTPUT	Number of free parameters.
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3534
3535
NOTES	-.
AUTHOR	E. Bertin (IAP)
3536
VERSION	20/05/2011
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3537
 ***/
3538
int	profit_unboundtobound(profitstruct *profit,
3539
				double *dparam, float *param, int index)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3540
  {
3541
   int		f,p, pstart,np;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3542

3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
  if (index<0)
    {
    pstart = 0;
    np = profit->nparam;
    }
  else
    {
    pstart = index;
    np = pstart+1;
    }

  f = 0;
  for (p=pstart; p<np; p++)
3556
    switch(profit->parfittype[p])
3557
      {
3558
3559
3560
3561
3562
3563
3564
3565
3566
      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])
3567
3568
		/ (1.0 + exp(-(dparam[f]>50.0? 50.0
				: (dparam[f]<-50.0? -50.0: dparam[f]))))
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
		+ 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()");
3583
      }
3584
3585
 
  return f;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3586
3587
3588
3589
  }


/****** profit_covarunboundtobound ********************************************
3590
PROTO	int profit_covarunboundtobound(profitstruct *profit,
3591
				double *dcovar, float *covar)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3592
PURPOSE	Convert covariance matrix from unbounded to bounded space.
3593
3594
3595
INPUT	Pointer to the profit structure,
	input (incomplete) matrix of double precision covariances,
	output matrix of single precision covariances.
3596
OUTPUT	Number of parameters that hit a boundary.
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3597
3598
NOTES	-.
AUTHOR	E. Bertin (IAP)
3599
VERSION	20/05/2011
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3600
 ***/
3601
int	profit_covarunboundtobound(profitstruct *profit,
3602
				double *dcovar, float *covar)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3603
  {
3604
3605
   double	*dxdy,
		xmmin,maxmx, maxmmin;
3606
   float	*x,*xmin,*xmax;
3607
   parfitenum	*fittype;
3608
   int		*fflag,
3609
		f,f1,f2, p,p1,p2, nfree, nparam, nmin,nmax;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3610
3611

  nparam = profit->nparam;
3612
3613
  fittype = profit->parfittype;
  QMALLOC16(dxdy, double, PARAM_NPARAM);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3614
3615
3616
  x = profit->paraminit;
  xmin = profit->parammin;
  xmax = profit->parammax;
3617
  nmin = nmax = 0;
3618
  f = 0;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3619
  for (p=0; p<profit->nparam; p++)
3620
    switch(fittype[p])
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3621
      {
3622
3623
3624
      case PARFIT_FIXED:
        break;
      case PARFIT_UNBOUND:
3625
        dxdy[f++] = xmax[p];
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
        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's avatar
Emmanuel Bertin committed
3651
3652
      }

3653
3654
  nfree = f;

3655
3656
  memset(profit->covar, 0, nparam*nparam*sizeof(float));
  f2 = 0;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3657
  for (p2=0; p2<nparam; p2++)
3658
    {
3659
    if (fittype[p2]!=PARFIT_FIXED)
3660
3661
3662
      {
      f1 = 0;
      for (p1=0; p1<nparam; p1++)
3663
        if (fittype[p1]!=PARFIT_FIXED)
3664
3665
3666
3667
3668
3669
3670
          {
          covar[p2*nparam+p1] = (float)(dcovar[f2*nfree+f1]*dxdy[f1]*dxdy[f2]);
          f1++;
          }
      f2++;
      }
    }
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3671
3672
3673

  free(dxdy);

3674
3675
3676
3677
  profit->nlimmin = nmin;
  profit->nlimmax = nmax;

  return nmin+nmax;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3678
3679
3680
3681
  }


/****** prof_init *************************************************************
3682
PROTO	profstruct prof_init(profitstruct *profit, unsigned int modeltype)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3683
3684
PURPOSE	Allocate and initialize a new profile structure.
INPUT	Pointer to the profile-fitting structure,
3685
	model type.
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3686
3687
3688
OUTPUT	A pointer to an allocated prof structure.
NOTES	-.
AUTHOR	E. Bertin (IAP)
3689
VERSION	08/12/2011
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3690
 ***/
3691
profstruct	*prof_init(profitstruct *profit, unsigned int modeltype)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3692
3693
  {
   profstruct	*prof;
3694
   float	*pix,
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3695
3696
3697
3698
3699
		rmax2, re2, dy2,r2, scale, zero, k,n, hinvn;
   int		width,height, ixc,iyc, ix,iy, nsub,
		d,s;

  QCALLOC(prof, profstruct, 1);
3700
3701
  prof->code = modeltype;
  switch(modeltype)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3702
    {
3703
3704
    case MODEL_BACK:
      prof->name = "background offset";
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3705
3706
3707
3708
3709
      prof->naxis = 2;
      prof->pix = NULL;
      profit_addparam(profit, PARAM_BACK, &prof->flux);
      prof->typscale = 1.0;
      break;
3710
3711
    case MODEL_DIRAC:
      prof->name = "point source";
3712
3713
3714
3715
3716
      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];
3717
      QMALLOC(prof->pix, float, prof->npix);
3718
3719
3720
3721
3722
      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;
3723
3724
    case MODEL_SERSIC:
      prof->name = "Sersic spheroid";
3725
3726
3727
3728
3729
3730
      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);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3731
3732
3733
3734
3735
3736
3737
3738
3739
      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;
3740
3741
    case MODEL_DEVAUCOULEURS:
      prof->name = "de Vaucouleurs spheroid";
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3742
      prof->naxis = 2;
3743
3744
3745
3746
      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];
3747
      QMALLOC(prof->pix, float, prof->npix);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3748
3749
3750
3751
3752
3753
3754
3755
      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;
3756
3757
    case MODEL_EXPONENTIAL:
      prof->name = "exponential disk";
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3758
      prof->naxis = 2;
3759
3760
3761
3762
      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];
3763
      QMALLOC(prof->pix, float, prof->npix);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3764
3765
3766
3767
3768
3769
3770
3771
      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;
3772
3773
    case MODEL_ARMS:
      prof->name = "spiral arms";
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3774
      prof->naxis = 2;
3775
3776
3777
3778
      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];
3779
      QMALLOC(prof->pix, float, prof->npix);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
      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;
3795
3796
    case MODEL_BAR:
      prof->name = "bar";
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3797
      prof->naxis = 2;
3798
3799
3800
3801
      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];
3802
      QMALLOC(prof->pix, float, prof->npix);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
      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;
3814
3815
    case MODEL_INRING:
      prof->name = "inner ring";
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3816
      prof->naxis = 2;
3817
3818
3819
3820
      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];
3821
      QMALLOC(prof->pix, float, prof->npix);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
      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;
3833
3834
    case MODEL_OUTRING:
      prof->name = "outer ring";
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3835
      prof->naxis = 2;
3836
3837
3838
3839
      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];
3840
      QMALLOC(prof->pix, float, prof->npix);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
      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;
3851
3852
    case MODEL_TABULATED:	/* An example of tabulated profile */
      prof->name = "tabulated model";
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3853
      prof->naxis = 3;
3854
3855
3856
3857
3858
      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);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3859
3860
3861
3862
3863
3864
3865
      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;
3866
      scale = prof->extrascale[0]= 8.0/PROFIT_MAXSMODSIZE;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
      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;
    }

3898
  if (prof->naxis>2)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3899
3900
3901
3902
3903
3904
3905
3906
3907
    {
    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];
3908
    QMALLOC16(prof->kernelbuf, float, prof->kernelnlines);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
    }

  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 **************************************************************
3938
3939
PROTO	float prof_add(profitstruct *profit, profstruct *prof,
		int extfluxfac_flag)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3940
PURPOSE	Add a model profile to an image.
3941
3942
3943
3944
INPUT	Profile-fitting structure,
	profile structure,
	flag (0 if flux correction factor is to be computed internally) 
OUTPUT	Total (asymptotic) flux contribution.
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3945
3946
NOTES	-.
AUTHOR	E. Bertin (IAP)
3947
VERSION	13/02/2013
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3948
 ***/
3949
float	prof_add(profitstruct *profit, profstruct *prof, int extfluxfac_flag)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3950
  {
3951
3952
   double	xscale, yscale, saspect, ctheta,stheta, flux, scaling, bn, n,
		dx1cout,dx2cout, ddx1[36],ddx2[36];
3953
   float	posin[PROFIT_MAXEXTRA], posout[2], dnaxisn[2],
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3954
		*pixin, *pixin2, *pixout,
3955
3956
		fluxfac, amp,cd11,cd12,cd21,cd22, dx1,dx2,
		x1,x10,x2, x1cin,x2cin, x1cout,x2cout, x1max,x2max, x1in,x2in,
3957
		k, hinvn, x1t,x2t, ca,sa, u,umin,
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3958
3959
		armamp,arm2amp, armrdphidr, armrdphidrvar, posang,
		width, invwidth2,
3960
3961
		r,r2,rmin, r2minxin,r2minxout, rmax, r2max,
		r2max1, r2max2, r2min, invr2xdif,
3962
3963
		val, theta, thresh, ra,rb, num,num2,den, ang,angstep,
		invn, dr, krpinvn,dkrpinvn, rs,rs2,
3964
3965
3966
		a11,a12,a21,a22, invdet, dca,dsa, a0,a2,a3, p1,p2,
		krspinvn, ekrspinvn, selem;
   int		npix, threshflag,
3967
		a,d,e,i, ix1,ix2, ix1max,ix2max, nang, nx2,
3968
		npix2;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3969

3970
  npix = profit->nmodpix;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3971

3972
  if (prof->code==MODEL_BACK)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3973
3974
3975
3976
3977
    {
    amp = fabs(*prof->flux);
    pixout = profit->modpix;
    for (i=npix; i--;)
      *(pixout++) += amp;
3978
3979
    prof->lostfluxfrac = 0.0;
    return 0.0;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3980
3981
3982
3983
    }

  scaling = profit->pixstep / prof->typscale;

3984
  if (prof->code!=MODEL_DIRAC)
3985
3986
3987
3988
3989
3990
    {
/*-- Compute Profile CD matrix */
    ctheta = cos(*prof->posangle*DEG);
    stheta = sin(*prof->posangle*DEG);
    saspect = fabs(*prof->aspect);
    xscale = (*prof->scale==0.0)?
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3991
		0.0 : fabs(scaling / (*prof->scale*prof->typscale));
3992
    yscale = (*prof->scale*saspect == 0.0)?
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3993
		0.0 : fabs(scaling / (*prof->scale*prof->typscale*saspect));
3994
3995
3996
3997
    cd11 = (float)(xscale*ctheta);
    cd12 = (float)(xscale*stheta);
    cd21 = (float)(-yscale*stheta);
    cd22 = (float)(yscale*ctheta);
3998
3999
4000
    dx1 = 0.0;	/* Shifting operations have been moved to profit_resample() */
    dx2 = 0.0;	/* Shifting operations have been moved to profit_resample() */

For faster browsing, not all history is shown. View entire blame