HOW-TO Use Galfit in Astro-WISE¶
Introduction¶
GALFIT is a galaxy/point source fitting algorithm that fits 2-D parameterized, axisymmetric, functions directly to images (Peng, Ho, Impey, & Rix 2002, AJ, 124: 266). The program has been developed by Chien Peng who maintains a Galfit homepage.
Astro-WISE implementation¶
The program Galfit (version 2.0.3b Feb 2005) has been incorporated into Astro-WISE. This is done by providing a Python wrapper around the Galfit program which stores the Galfit input and output to the Astro-WISE database.
The main classes in the Galfit object model for Astro-WISE (i.e. those classes that are stored in the database, and must be queried on to get results) are these:
- GalFitModel: The main Galfit class. Conceptually this is the model of a single galaxy. It contains methods to create a model image, residual image etc. Additionally it contains a list of GalFitComponents (see below), which together constitute the model of the galaxy.
- GalFitComponent: parent class for GalFitSersic, GalFitDevauc, GalFitSky, etc.
- GalFitSersic: stores the parameters of the Sersic function, contains initial values, final values, and errors of fitted parameters, as well as a switch which defines whether the parameter was fixed or free in the fit (see Table 1).
- GalFitDevauc, GalFitSky, etc.: analogous to GalFitSersic
- GalFitList: used as a tool to link a certain group of GalFitModels together through an identifier, and optionally a name.
- GalFitParameters: stores the global configuration parameters (named A-S in the Galfit configuration file), see Table 2 for Astro-WISE names.
- GalFitConstraint, GalFitAbsConstraint, GalFitDiffConstraint, etc.: controls and stores constraints on fitted parameters
The input which Galfit needs to run are an image of the object to be fitted, information on the 2-D profile to be fitted and various parameters which configure how to perform the fitting. The galaxy images to be fitted by Galfit are defined via a SourceList ID (SLID) and the source IDs (SID) of sources in it. For each source a cut-out of the image is made, centered on the source position which is then fed to Galfit.
The 2-D parameterized functions (e.g., a sersic profile) that can be fitted to this cut-out image are called “components” in Astro-WISE. The components that currently can be fitted in Astro-WISE are listed in Table 1.
Table 1: The result of each profile that is fitted by Galfit is stored in a GalFitComponent subclass. Col.(1): The 2-D profile. Col.(2): the name as given as input to the task/DPU. Col.(3): the name of the class. Col.(4) names of the profile parameter names. Col.(5): description of the profile parameters.
profile | profile name | class name | parameters [1] | parameter |
---|---|---|---|---|
for task/DPU | description | |||
x | position x [pixel] | |||
y | position y [pixel] | |||
common parameters for all functions, except Sky | posang | position angle (PA) | ||
[Degrees: Up=0, Left=90] | ||||
ratio | axis ratio (b/a) | |||
shape | diskiness/boxiness | |||
De Vaucouleurs | devauc | GalFitDevauc | as Sersic (N=4) | |
Exponential Disk | expdisk | GalFitExpdisk | as Sersic (N=1) | |
Gaussian | gaussian | GalFitGaussian | mag | total magnitude |
fwhm | FWHM of Gaussian | |||
Modified King | king | GalFitKing | mu | surface brightness |
Rc | core radius | |||
Rt | truncation radius | |||
alpha | sharpness of transition alpha | |||
Moffat | moffat | GalFitMoffat | mag | total magnitude |
fwhm | FWHM of Gaussian | |||
pow | value of powerlaw | |||
Nuker | nuker | GalFitNuker | mu | surface brightness |
Rb | radius at which mu is determined | |||
alpha | sharpness of transition | |||
beta | outer powerlaw slope | |||
gamma | inner powerlaw slope | |||
Sersic | sersic | GalFitSersic | mag | total magnitude |
reff | effective radius (\(R_e\)) [pixels] | |||
N | sersic index (deVauc=4) | |||
Sky background | sky | GalFitSky | value | sky background [ADU counts] |
grad_x | dsky/dx (sky gradient in x) | |||
grad_y | dsky/dy (sky gradient in y) | |||
Ferrer | ferrer | GalFitFerrer [2] | ||
Isophote | isophote | GalFitIsophote [2] | ||
Powersic | powersic | GalFitPowersic [2] | ||
Psf | psf | GalFitPsf [2] |
[1] | All parameters come in four variants e.g.: x (best-fit), ix (initial value), dx (error), free_x (fit/fix) |
[2] | (1, 2, 3, 4) Not implemented yet |
Running GalFit¶
For example to fit a sersic profile plus a sky background to 4 sources from the sourcelist with SLID=57424 which have SID=7,3,9,33 using the cpu on your own machine, enter at the awe-prompt:
# Import the class GalFitTask:
from astro.recipes.GalFit import GalFitTask
task = GalFitTask(instrument='WFI', slid=57424, sids=[7,3,9,33],
models=[{'name:'sersic'}, {'name':'sky'}], commit=1)
task.execute()
the same input as above but using the cpus of the parallel cluster of computers:
# Import Processor class: needed to run processes on parallel cluster:
from astro.recipes.mods.dpu import Processor
# Import Environment class: needed to run processes on parallel cluster:
from common.config.Environment import Env
# Instantiate an object of class dpu: needed to run processes on parallel cluster:
dpu = Processor(Env['dpu_name'])
# Run GalFit (see previous example for explanation of parameters):
dpu.run('GalFit', i='WFI', slid=57424, sids=[1,3,9,33], m=[{'name':'sersic'},\
{'name':'sky'}], C=1)
Working with GalFitList¶
The GalFitList class is intended as a simple way to group GalFitModels (and GalFitComponents). The way to use this class is to first create and commit one, and then specify its GalFitList identifier GFLID when running the GalFit task on the DPU or locally:
# Create the GalFitList object
l = GalFitList()
l.name = 'test-run-1'
l.make()
l.commit()
# [schmidt] 16:27:12 - Set GalFitList identifier GFLID to 100231
# Refer to the GalFitList object by specifying its GFLID, as reported
# after committing the GalFitList (see above).
dpu.run('GalFit', i='WFI', slid=75637, sids=range(10,20), gflid=100231, C=1)
Now it is easy to query on the group of GalFitModels you called “test-run-1” and inspect their residual images:
query = GalFitModel.GFLID == 100211
for model in query: model.get_residual()
This will create all residual images, which can then be inspected with a FITS viewer.
Querying the database for GalFitModel results¶
To print the results from the fit made above for source with SID=7 enter at the awe-prompt:
# Import the class GalFitComponent which is defined in GalFitModel:
from astro.main.GalFitModel import GalFitComponent
# Query the database for the GalFitComponents which contain the results
# for source with SID=3 in SourceList with SLID=57424 which
# were fitted with a sersic profile:
query = (GalFitComponent.name == 'sersic') &
(GalFitComponent.SLID==57424) &
(GalFitComponent.SID==3)
# Loop over the results in the query:
for c in query:
# Print x position and the effective radius:
print(c.SID, c.GFID, c.x, c.reff, c.N, c.iN, c.iratio, c.ishape)
To print the results from the fit made above enter at the awe-prompt in a script:
# Import the class GalFitComponent which is defined in GalFitModel:
from astro.main.GalFitModel import GalFitComponent
# Query the database for the GalFitComponents which contain the results
# for those sources in SourceList with SLID=57424 which
# were fitted with a sersic profile:
query = (GalFitComponent.name == 'sersic') & (GalFitComponent.SLID==57424)
# Loop over the results in the query:
for c in query:
# Print x position and the effective radius:
print(c.SID, c.GFID, c.x, c.reff, c.N, c.iN, c.iratio, c.ishape)
If you have run Galfit with different parameters various times on the same set of sources. Print the results for the last run.
# Define three sources by tuples of SLID, SID, here sources 31, 52, 73 from
# SourceList with SLID=57424
mysources = [(57424, 31), (57424, 52), (57424, 73)]
models = []
for slid, sid in mysources:
q = (GalFitModel.SLID == slid) & (GalFitModel.SID == sid)
model = q.max('GFID')
models.append(model)
for m in models:
m.show_model_parameters()
To get a listing of all parameters of a Sersic profile:
# Import all classes defined in GalFitModel (GalFitSersic being one of them):
from astro.main.GalFitModel import *
# Prints a listing of all parameters of a Sersic profile:
GalFitSersic.get_persistent_properties()
Configuring GalFitModel¶
While it is possible to configure GalFitModel manually, a configuration is determined automatically when no configuration is specified. The following steps can be distinguished in this process:
- Based on the Sextractor parameters of the source you derive a GalFitModel for, a region is extracted from the larger image the SourceList is made from. The size of the region is related to the semi-major axis of the source (Sextractor “A” parameter).
- Pixelscale and magnitude zeropoint are obtained from the AstrometricParameters resp. SourceList objects.
- By default a Sersic and Sky profile are fit to the modelled source.
- The initial parameters of the specified models are set based on the Sextractor parameters. For a Sersic profile the initial magnitude value (imag) is set to MAG_ISO in the SourceList. Similarly the Xpos and Ypos parameters are used to define the initial position.
- Neighbouring sources that are both close and bright enough to influence the fit are detected and assigned their own Sersic profile.
Galfit’s configuration file can be considered as consisting of two separate parts. One part is a number of general configuration parameters, such as the input and output files, pixelscales etc. The other part is an arbitrarily large collection of initial values of functions (e.g. Sersic, Nuker, King) that are fit to the galaxy and potentially other sources in its neighbourhood.
Configuring general process parameters of GalFitModel¶
Table 2: Overview of GalFitParameters
parameter name | description | type | default/range |
---|---|---|---|
data | Input data image (FITS file) | str | galfitdata.fits [3] |
model | Output data image (FITS file) | str | galfitmodel.fits [4] |
badpixels | filename of bad pixels file | str | [5] |
sigma | filename of sigma image | str | [6] |
constraints | filename of constraints file | str | [7] |
psf | filename of PSF image | str | “” |
conv_x | size in x of convolution window | float | 0.0 |
conv_y | size in y of convolution window | float | 0.0 |
display | type of display (regular, curses, both) | str | regular |
fit_xmin | subsection of input FITS file to fit | int | 0 [8] |
fit_xmax | subsection of input FITS file to fit | int | 0 [8] |
fit_ymin | subsection of input FITS file to fit | int | 0 [8] |
fit_ymax | subsection of input FITS file to fit | int | 0 [8] |
interactive | modify/create objects interactively | int | 0 [9] |
no_fit | do not fit, just output model image | int | 0 |
pixelscale_x | pixel scale in x [arcsec/pixel] | float | 0.0 [10] |
pixelscale_y | pixel scale in y [arcsec/pixel] | float | 0.0 [10] |
subsampling | PSF fine sampling factor relative to data | float | 1.0 |
zeropoint | photometric zeropoint | float | 0.0 [11] |
region_xmin | subsection of FITS file to extract | int | 0 [12] |
region_xmax | subsection of FITS file to extract | int | 0 [12] |
region_ymin | subsection of FITS file to extract | int | 0 [12] |
region_ymax | subsection of FITS file to extract | int | 0 [12] |
[3] | Dependent on SourceList.frame.filename in the awclass hierarchy |
[4] | Dependent on filename of ``data’ |
[5] | Derived from weight map |
[6] | Derived from weight map. Caveat: ReducedScienceFrames which are not calibrated with Astro-WISE ingested, but ingested into the system as a ReducedScienceFrame by users can contain weight image formats which differ from the standard. The ACS ReducedScienceFrames are an example. Users can obtain correct sigma images in such cases by adapting GalFitModel.py. |
[7] | Not currently supported |
[8] | (1, 2, 3, 4) The entire region defined by region_* parameters is fit by default |
[9] | Galfit interactive mode is not supported |
[10] | (1, 2) Derived from AstrometricParameters object |
[11] | Derived from SourceList/sextractor input |
[12] | (1, 2, 3, 4) This is not a Galfit parameter, it is used in Astro-WISE to select the region in the image that was input of the SourceList |
To get a listing of all general parameters of Galfit (which are contained in the class GalFitModel, see also Table 2) type the following lines in the AWE prompt:
# Import the class Pars.
from astro.util.Pars import Pars
# Make an object which contains the general process parameters for GalFit.
p = Pars(GalFitModel)
p.show()
This uses the general method to show process parameters as discussed in the process parameters howto (see HOW-TO Configure process parameters).
This how-to also explains how to use this method to set parameters for Galfit. Here is nevertheless one example. To set the cut-out region around the source which will be modeled by Galfit, one should specify a dictionary:
p = {'GalFitModel.process_params.region_xmin': 1,
{'GalFitModel.process_params.region_xmax': 10,
{'GalFitModel.process_params.region_ymin': 1,
{'GalFitModel.process_params.region_ymax': 10}
To get the necessary coordinates, these values have to be offset by the source position. From the source parameters retrieve the Xpos and Ypos of the source:
sl = (SourceList.SLID == 57424)[0]
xpos = sl.sources[10]['Xpos']
ypos = sl.sources[10]['Ypos']
then determine the region you want around this source and fill in as above. The dictionary specified above can be given to the DPU to change the process parameters:
dpu.run('GalFit', i='WFI', slid=57424, sids=[1,3,9,33], m=[{'name':'sersic'},
{'name':'sky'}], p=p, C=1)
or to the Task:
task = GalFitTask(instrument='WFI', slid=57424, sids=[1,3,9,33],
models=[{'name':'sersic'}, {'name':'sky'}], pars=p, commit=1)
task.execute()
The following commands clarify the correspondence between the names of parameters in the original C code of Galfit and the names given in the Astro-WISEimplementation. The class of a specific profile (e.g., GalFitSersic) contains the mapping of parameters specifically for that profile. The class GalFitParameters contains the mapping of general parameters.
# Import all classes defined in GalFitModel:
from astro.main.GalFitModel import *
GalFitParameters.CONFIG_FILE_MAP
GalFitSersic.CONFIG_FILE_MAP
A dictionary is returned which has as key the parameters name in the original C code and as value the name in the Astro-WISE implementation.
Configuring initial fitting parameters of model components¶
To set the initial fit parameters and/or fix parameters, their names and values must be specified in the list of dictionaries given in the “models” (task level) or “m” (dpu level) argument:
# Task level:
task = GalFitTask(instrument='WFI', slid=57424, sids=[1,3,9,33],
models=[{'name':'sersic', 'iN':1.5, 'free_N':0},
{'name':'sky'}], commit=1)
task.execute()
# DPU level:
dpu.run('GalFit', i='WFI', slid=57424, sids=[1,3,9,33], m=[{'name':'sersic',
'iN':1.5, 'free_N':0}, {'name':'sky'}], C=1)
Constraining the fit parameters¶
Fit parameters can be constrained in 4 different ways by Galfit. These different constraints are represented by 4 Python classes:
- GalFitAbsConstraint: This constraint constrains a parameter between two values.
- GalFitRelConstraint: This constraint constrains a parameter between a range around the initial value.
- GalFitDiffConstraint: This constraint constrains the difference between the same parameter for two different objects/components.
- GalFitRatioConstraint: This constraint constrains the ratio of the same parameter for two different objects/components.
A list of constraints can be specified in the task as follows:
# Task level:
task = GalFitTask(instrument='WFI', slid=57424, sids=[1,3,9,33],
constraints=[{'name':'abs', 'comp':1, 'param': 'x',
'min':13, 'max':13}], commit=1)
# DPU level:
dpu.run('GalFit', i='WFI', slid=57424, sids=[1,3,9,33], cs=[{'name':'abs',
'comp':1, 'param': 'x', 'min':13, 'max':13}], C=1)
task.execute()
In other words, a constraint can be defined in a dictionary, which maps the properties of the constraint object. A list of such dictionaries represents a list of constraints.
Using a PSF image¶
In the configuration file of Galfit a PSF image filename can be specified. Galfit uses this image to convolve the model before comparing it to the data. PSF image files are represented by the PSFImage class.
There are two ways to create PSFImages:
- Use TinyTim to create it. TinyTim can only be used to create PSF images for the ACS wide-field camera of the HST. See the TinyTim howto (section [tinytim]).
- Use an existing PSF image file and store it.
Here is how you can store an existing PSF image:
p = PSFImage(pathname='my_psf_image.fits')
p.make()
p.store()
p.commit()
This will update the filename of the PSF image to be unique.
Now using the stored PSFImage is done by specifying its filename in the appropriate process parameter. The presence of the filename in the process parameters object triggers a query to find the specified file in the database:
task = GalFitTask(instrument='ACS', slid=110521, sids=[50],
pars={'GalFitModel.process_params.psf': 'Cal-EHELMICH-----
--------TinyTim---PSF-54227.5867871-83e1bd5c6e15be667a
3cc511ccca13a6ee043514.fits'}, commit=1)
task.execute()
Description of useful methods of GalFitModel¶
get_model()
Creates the model image and returns it as a BaseFrame object.
get_residual()
Creates the residual image and returns it as a BaseFrame object.
get_science()
Extracts and downloads the region in the science image for which the model was derived, and returns it as a BaseFrame object.
get_weight()
Extracts and downloads the region in the weight image for which the model was derived and returns it as a BaseFrame object.
show_model_parameters()
Display a list of all ellipse parameters.
get_model_parameters()
Returns a list of dictionaries of all components. I.e. each item of the list is a dictionary which contains the description of one GalFitComponent.
Caveats¶
Automatically generated sigma images incorrect.
ReducedScienceFrames which are not calibrated with Astro-WISE ingested, but ingested into the system as a ReducedScienceFrame by users can contain weight image formats which differ from the standard. The ACS ReducedScienceFrames are an example. Users can obtain correct sigma images in such cases by adapting GalFitModel.py.