Design and Architecture of Imfit¶
General design and operation of imfit¶
The basic operation of imfit, as implemented in imfit_main.cpp, is:
Process command-line options
Read and process configuration file
Optional data-image characteristics (A/D gain, read noise, original-sky background)
Specifications of the model: functions, initial parameter values and limits
Read in user-supplied data from images
Image to be fit
Mask image, if any
Noise/error/weight image, if any
PSF image(s), if any
Create ModelObject instance and supply it with data
List of image functions to use
The ModelObject instance will then instantiate corresponding FunctionObject instances
PSF image data (if supplied by user)
Image to be fit
Data image characteristics
Oversampled PSF image (if supplied by user)
Mask image data (if supplied by user)
Type of fit statistic to be calculated
Noise/error/weight image data (if supplied by user)
Call FinalSetup() method on the ModelObject instance
Do the fit
Set up initial parameter vector and parameter-limits structure (mp_par structure)
Call the user-specified solver (Levenberg-Marquardt is default)
Print summary of fit
Optionally, do bootstrap resampling to get parameter uncertainty estimates
Save results
Save best-fitting parameter values
Optionally, save best-fitting model image and/or residual image
General design and operation of makeimage¶
The operation of makeimage is similar to (but simpler than) imfit.
The key difference in terms of generating the model image is that the user must specify the size of the output image, since there is no data image to use as a reference. There are three ways to do this:
Command-line options (
--ncols
,--nrows
)Specification within the configuration file (lines beginning NROWS and NCOLS)
Use a reference image (
--refimage
command-line option)
The basic operation of makeimage, as implemented in makeimage_main.cpp, is:
Process command-line options
Read and process configuration file
Specifications of the model: functions and parameter values
Optional image-size specifications
Read in PSF image(s), if supplied
Create ModelObject instance and supply it with data
Give it list of image functions to use
PSF image data (if supplied by user)
Dimensions of model image
Oversampled PSF data (if supplied by user)
Create model image:
Set up parameter vector
Call CreateModelImage() method of ModelObject instance, passing in the parameter vector
Save the image
Generate string vector of comments for image header
Call SaveVectorAsImage() function (image_io.h).
The ModelObject Class¶
The heart of Imfit is the ModelObject class. This is instantiated once in each program, and holds (among other things) the following objects and data (“imfit only” denotes data used in imfit or imfit-mcmc, but not needed when used in makeimage)
Model image pixel values
Vector of FunctionObject instances which define the model
Array of parameter values for the model
Image pixel data for PSFs, if any
Convolver objects(s) for PSF convolution
imfit only: Data image pixel values
imfit only: other characteristics of data image (size, gain, read noise, etc.)
imfit only: Error image (either supplied by user or internally generated)
imfit only: Mask image, if supplied by user
imfit only: Internal weight image (from combination of error image and weight image).
Not all of these data members are initialized or used – for example, none of the data-related (“imfit only”) members are used by makeimage, and the error image is not generated or used if a fit uses Poisson-based statistics instead of chi^2.
The main functionality of the class includes:
Generating a model image using the vector of FunctionObjects and the current array of parameter values
Generating individual-function model images (i.e., the
--output-functions
option of makeimage)Computing individual-function and total fluxes for current model
Computing deviances vector between current model image and data image (for use by Levenberg-Marquardt solver)
Computing the fit statistic (chi^2, etc.) from comparison of the current model image and the data image
Printing current parameter values
Generating a bootstrap resampling pixel-index vector when bootstrap resampling is being done
FunctionObject Classes¶
A model image is the sum of individual model images computed using single image functions, each of which is an instance of a FunctionObject subclass. For example, a model which is the sum of a central point source, a Sersic bulge, and an exponential disk would be the sum of individual images created with the PointSource, Sersic, and Exponential classes. Multiple instances of each class can be used.
Each image function is a subclass of the abstract base class FunctionObject. The main methods of this class are:
Setup() – Called by ModelObject to pass in the current parameter vector at the beginning of the computation of a model image; this allows the image function to store the relevant parameter values and do any useful computations that don’t depend on pixel position.
GetValue() – Called by ModelObject once for each pixel in the model image, to pass in the current pixel values (x,y); the image function uses these to compute and return the appropriate intensity value for that pixel.
Constructing a model image¶
The actual generation of pixel values in the model image depends on the vector of FunctionObjects and the current array of corresponding parameter values. (And, of course, convolution with a PSF if that is requested.) The FunctionObjects vector contains instantiations of one or more classes (e.g., Gaussian, Exponential, Sersic, ExponentialDisk3D) which are subclasses of the abstract base class FunctionObject (defined in function_object.h).
When a model image is constructed, the first step is to call the Setup() method on each FunctionObject and pass in the corresponding parameter values. This enables the FunctionObject instances to do any initial computations which don’t depend on actual location within the image.
The value of an individual pixel in the model image is obtained by iterating over the individual FunctionObjects, calling its GetValue() method with the current pixel coordinates (x,y), and adding up all the return values. This all takes place within a loop which iterates over all the pixels in the model image; this loop is wrapped in OpenMP directives to allow parallelization across multiple CPU cores.