Newer
Older
/*
profit.c
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: SExtractor
*
* Authors: E.BERTIN (IAP)
*
* Contents: Fit an arbitrary profile combination to a detection.
*
* Last modify: 03/08/2010
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifndef HAVE_MATHIMF_H
#define _GNU_SOURCE
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "define.h"
#include "globals.h"
#include "prefs.h"
#include "fits/fitscat.h"
#include "levmar/lm.h"
#include "fft.h"
#include "fitswcs.h"
#include "check.h"
#include "pattern.h"
#include "psf.h"
#include "profit.h"
#define INTERPW 6 /* Interpolation function range (x) */
#define INTERPH 6 /* Interpolation function range (y) */
#define INTERPF(x) (x==0.0?1.0:sinf(PI*x)*sinf(PI*x/3.0)/(PI*PI/3.0*x*x))
/* Lanczos approximation */
static double prof_gammainc(double x, double a),
prof_gamma(double x);
static float prof_interpolate(profstruct *prof, float *posin);
static float interpolate_pix(float *posin, float *pix, int *naxisn,
static void make_kernel(float pos, float *kernel, interpenum interptype);
/*------------------------------- variables ---------------------------------*/
const char profname[][32]={"background offset", "Sersic spheroid",
"De Vaucouleurs spheroid", "exponential disk", "spiral arms",
"bar", "inner ring", "outer ring", "tabulated model",
""};
const int interp_kernwidth[5]={1,2,4,6,8};
const int flux_flag[PARAM_NPARAM] = {0,0,0,
1,0,0,0,0,
1,0,0,0,
1,0,0,0,0,0,0,0,
1,0,0,
1,0,0,
1,0,0
};
int theniter, the_gal;
/* "Local" global variables; it seems dirty but it simplifies a lot */
/* interfacing to the LM routines */
static picstruct *the_field, *the_wfield;
profitstruct *theprofit;
/****** profit_init ***********************************************************
PROTO profitstruct profit_init(psfstruct *psf)
PURPOSE Allocate and initialize a new profile-fitting structure.
INPUT Pointer to PSF structure.
OUTPUT A pointer to an allocated profit structure.
NOTES -.
AUTHOR E. Bertin (IAP)
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
***/
profitstruct *profit_init(psfstruct *psf)
{
profitstruct *profit;
int p, nprof,
backflag, spheroidflag, diskflag, barflag, armsflag;
QCALLOC(profit, profitstruct, 1);
profit->psf = psf;
profit->psfdft = NULL;
profit->nparam = 0;
QMALLOC(profit->prof, profstruct *, PROF_NPROF);
backflag = spheroidflag = diskflag = barflag = armsflag = 0;
nprof = 0;
for (p=0; p<PROF_NPROF; p++)
if (!backflag && FLAG(obj2.prof_offset_flux))
{
profit->prof[p] = prof_init(profit, PROF_BACK);
backflag = 1;
nprof++;
}
else if (!spheroidflag && FLAG(obj2.prof_spheroid_flux))
{
profit->prof[p] = prof_init(profit,
FLAG(obj2.prof_spheroid_sersicn)? PROF_SERSIC : PROF_DEVAUCOULEURS);
spheroidflag = 1;
nprof++;
}
else if (!diskflag && FLAG(obj2.prof_disk_flux))
{
profit->prof[p] = prof_init(profit, PROF_EXPONENTIAL);
diskflag = 1;
nprof++;
}
else if (diskflag && !barflag && FLAG(obj2.prof_bar_flux))
{
profit->prof[p] = prof_init(profit, PROF_BAR);
barflag = 1;
nprof++;
}
else if (barflag && !armsflag && FLAG(obj2.prof_arms_flux))
{
profit->prof[p] = prof_init(profit, PROF_ARMS);
armsflag = 1;
nprof++;
}
/* Allocate memory for the complete model */
QMALLOC16(profit->modpix, float, PROFIT_MAXMODSIZE*PROFIT_MAXMODSIZE);
QMALLOC16(profit->modpix2, float, PROFIT_MAXMODSIZE*PROFIT_MAXMODSIZE);
QMALLOC16(profit->cmodpix, float, PROFIT_MAXMODSIZE*PROFIT_MAXMODSIZE);
QMALLOC16(profit->psfpix, float, PROFIT_MAXMODSIZE*PROFIT_MAXMODSIZE);
QMALLOC16(profit->objpix, PIXTYPE, PROFIT_MAXOBJSIZE*PROFIT_MAXOBJSIZE);
QMALLOC16(profit->objweight, PIXTYPE, PROFIT_MAXOBJSIZE*PROFIT_MAXOBJSIZE);
QMALLOC16(profit->lmodpix, PIXTYPE, PROFIT_MAXOBJSIZE*PROFIT_MAXOBJSIZE);
QMALLOC16(profit->lmodpix2, PIXTYPE, PROFIT_MAXOBJSIZE*PROFIT_MAXOBJSIZE);
QMALLOC16(profit->resi, float, PROFIT_MAXOBJSIZE*PROFIT_MAXOBJSIZE);
Emmanuel Bertin
committed
QMALLOC16(profit->covar, float, profit->nparam*profit->nparam);
profit->oversamp = PROFIT_OVERSAMP;
profit->fluxfac = 1.0; /* Default */
return profit;
}
/****** profit_end ************************************************************
PROTO void prof_end(profstruct *prof)
PURPOSE End (deallocate) a profile-fitting structure.
INPUT Prof structure.
OUTPUT -.
NOTES -.
AUTHOR E. Bertin (IAP)
***/
void profit_end(profitstruct *profit)
{
int p;
for (p=0; p<profit->nprof; p++)
prof_end(profit->prof[p]);
free(profit->modpix);
free(profit->modpix2);
free(profit->cmodpix);
free(profit->psfpix);
free(profit->lmodpix);
free(profit->lmodpix2);
free(profit->objpix);
free(profit->objweight);
free(profit->resi);
free(profit->prof);
free(profit->covar);
free(profit->psfdft);
free(profit);
return;
}
/****** profit_fit ************************************************************
PROTO void profit_fit(profitstruct *profit, picstruct *field,
picstruct *wfield, objstruct *obj, obj2struct *obj2)
PURPOSE Fit profile(s) convolved with the PSF to a detected object.
INPUT Array of profile structures,
Number of profiles,
Pointer to the profile-fitting structure,
Pointer to the field,
Pointer to the field weight,
Pointer to the obj.
OUTPUT Pointer to an allocated fit structure (containing details about the
fit).
NOTES It is a modified version of the lm_minimize() of lmfit.
Loading
Loading full blame…