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.