profit.c 146 KB
Newer Older
3001
3002
NOTES	-.
AUTHOR	E. Bertin (IAP)
3003
VERSION	06/09/2011
3004
 ***/
3005
void	 profit_surface(profitstruct *profit, obj2struct *obj2)
3006
  {
3007
   profitstruct	hdprofit;
3008
   double	dsum,dhsum,dsumoff, dhval, frac, seff;
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
   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;
3027
  hdprofit.fluxfac = 1.0/(hdprofit.pixstep*hdprofit.pixstep);
3028
3029
3030
3031
3032
  QCALLOC(hdprofit.modpix, float,npix*sizeof(float));

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

3034
3035
3036
3037
3038
3039
3040
3041
  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];
3042
checkstruct *check;
3043
3044
3045
3046
3047
3048
3049
3050
3051
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);
*/
3052
3053
  if (FLAG(obj2.fluxeff_prof))
    {
3054
3055
3056
/*-- Sort model pixel values */
    spix = NULL;			/* to avoid gcc -Wall warnings */
    QMEMCPY(hdprofit.modpix, spix, float, npix);
3057
    fqmedian(spix, npix);
3058
3059
3060
3061
3062
3063
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
/*-- 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;
      }
3094
3095
3096
    free(spix);
    }

3097
/* Compute model peak */
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
  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];
3112
3113
    }

3114
3115
/* Free hi-def model raster */
  free(hdprofit.modpix);
3116
3117
3118
3119
3120

  return;
  }


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

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

  obj2 = profit->obj2;
3169
  param = parammin = parammax = priorcen = priorsig = 0.0;
3170

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

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

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

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

3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
  if (index<0)
    {
    pstart = 0;
    np = profit->nparam;
    }
  else
    {
    pstart = index;
    np = pstart+1;
    }

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

3515
  return f;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3516
3517
3518
3519
  }


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

3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
  if (index<0)
    {
    pstart = 0;
    np = profit->nparam;
    }
  else
    {
    pstart = index;
    np = pstart+1;
    }

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


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

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

3647
3648
  nfree = f;

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

  free(dxdy);

3668
3669
3670
3671
  profit->nlimmin = nmin;
  profit->nlimmax = nmax;

  return nmin+nmax;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3672
3673
3674
3675
  }


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

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

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

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

3964
  npix = profit->nmodpix;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3965

3966
  if (prof->code==MODEL_BACK)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3967
3968
3969
3970
3971
    {
    amp = fabs(*prof->flux);
    pixout = profit->modpix;
    for (i=npix; i--;)
      *(pixout++) += amp;
3972
3973
    prof->lostfluxfrac = 0.0;
    return 0.0;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3974
3975
3976
3977
    }

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

3978
  if (prof->code!=MODEL_DIRAC)
3979
3980
3981
3982
3983
3984
    {
/*-- 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
3985
		0.0 : fabs(scaling / (*prof->scale*prof->typscale));
3986
    yscale = (*prof->scale*saspect == 0.0)?
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3987
		0.0 : fabs(scaling / (*prof->scale*prof->typscale*saspect));
3988
3989
3990
3991
    cd11 = (float)(xscale*ctheta);
    cd12 = (float)(xscale*stheta);
    cd21 = (float)(-yscale*stheta);
    cd22 = (float)(yscale*ctheta);
3992
3993
3994
3995
3996
    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);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3997
    nx2 = profit->modnaxisn[1]/2 + 1;
3998
3999
4000

/*-- Compute the largest r^2 that fits in the frame */
    num = cd11*cd22-cd12*cd21;
For faster browsing, not all history is shown. View entire blame