grale.grid
This module contains functions to create a subdivision grid that’s used in the lens inversion procedure. Apart from a uniformly subdivided grid, it is also possible to lay out the grid based on some kind of density map, using a finer subdivision where the integrated density is higher. This density could be the projected mass density of a gravitational lens, or even the observed light distribution in a FITS file.
Examples for how these functions can be used, can be found in the notebooks gridtests.ipynb and fittest.ipynb.
GridException
- exception grale.grid.GridException
An exception that’s generated when something goes wrong with the grid creation.
MultiGridCreator
- class grale.grid.MultiGridCreator(regionSize=None, regionCenter=None, multiRegionInfo=None, defaultRandomFraction=0.05)
This is a class to manage the grid creation for one or more regions. It allows you to first define the regions, and then ask for them to be subdivided uniformly (see
getUniformGrid()
) or using the subdivision algorithm (seegetSubdivisionGrid()
). It is used by theInversionWorkSpace
class to manage the inversion regions.- __init__(regionSize=None, regionCenter=None, multiRegionInfo=None, defaultRandomFraction=0.05)
Initializes the MultiGridCreator object.
Arguments:
regionSize and regionCenter: if these are specified, multiRegionInfo must be
None
, and they then specify a the size and center of a single square region that will be subdivided by other functions in the class. The regionCenter parameter is optional and defaults to (0, 0)multiRegionInfo: it is also possible to specify multiple square regions that should be subdivided at the same time, in a similar way (uniformly or using the subdivision algorithm). This should then be a list of dictionaries, each having a
"size"
key and optionally a"center"
key. The regionSize and regionCenter arguments should beNone
if this is used.defaultRandomFraction: each time
getUniformGrid()
orgetSubdivisionGrid()
is called, some random offset is added to the center(s) of the region(s). If this is a number, it specifies the fraction of the size that an offset can be. It is also possible to specify a function, which will be called with size and center of a region as its two arguments, and should return the size and center to actually use.
- getSubdivisionGrid(lensOrLensInfo, minSquares, maxSquares, startSubDiv=1, randomFraction=None, lensFilter=None, lensFilterParams={}, lensInfoFilter=None, lensInfoFilterParams={}, excludeFunction=None, checkSubDivFunction=None, renderer='default', feedbackObject='default')
Based on the region information supplied by the constructor or by
setRegionSize()
, this subdivides the regions using the algorithm fromcreateMultiSubdivisionGridForFunction()
, which inspects the density information from lensOrLensInfoArguments:
lensOrLensInfo: should either be a single
LensInfo
orDensInfo
instance, or a singlegravitational lens
model. If the latter is the case, for each region it will be converted to aLensInfo
object, to get information about the density.minSquares and maxSquares: construct a subdivision grid with a total number of grid cells between these bounds, as in
createMultiSubdivisionGridForFunction()
startSubDiv: in the subdivision procedure, each region will start from an NxN uniform subdivision, before refining regions with more mass. If this parameter is a single integer number N, the same NxN subdivision will be used for each region. It can also be a list of numbers, to start with different uniform subdivisions for each region.
randomFraction: if this is
None
, the default from the constructor is used, but here it can be overridden. See the constructor’s documentation for an explanation of its meaning.lensFilter: if specified, this function can be used to apply some kind of filtering on the lens model, in case lensOrLensInfo refers to a
gravitational lens
instance. The function will be called with three arguments plus the arguments specified in the lensFilterParams dictionary. The first three arguments are the lens model, the bottom-left corner of a region, and the top-right corner. The function should return another lens model.lensFilterParams: a dictionary with extra arguments for the previous function.
lensInfoFilter: similar to lensFilter, in case a
LensInfo
object is used. In this case there is only one mandatory argument, the LensInfo object itself. Extra keyword arguments can be provided using the following lensInfoFilterParams dictionary. The function should return another LensInfo object.lensInfoFilterParams: a dictionary with keyword arguments for the previous function.
excludeFunction: if specified, for each grid cell it will be called as
excludeFunction(cellCenter, cellSize, True)
for the initial uniform grids, and asexcludeFunction(cellCenter, cellSize, False)
for the next subdivision steps. If the function returnsTrue
then that particular cell will not be included in the final grid.checkSubDivFunction: if specified, when a cell is considered to be subdivided, this function is called with as its two arguments the cell’s center and size. If it returns
False
, no subdivision may take place.renderer: if a lens model is used as the lensOrLensInfo parameter, then for each region that’s present a mass map will be calculated. This specifies the
renderer
used for this calculation.feedbackObject: the
feedback
mechanism used by the previous renderer.
- getUniformGrid(subDiv, randomFraction=None, excludeFunction=None)
Based on the region information supplied by the constructor or by
setRegionSize()
, this subdivides the regions in a uniform way based on subDiv. If this is an integer number N, then each region will be subdivided into an NxN grid. Alternatively, this can be a list with one number per region, in case each region should be subdivided in a different way.If randomFraction is
None
, the default from the constructor is used, but here it can be overridden. See the constructor’s documentation for an explanation of its meaning.If excludeFunction is specified, for each grid cell it will be called as
excludeFunction(cellCenter, cellSize, True)
, and if the function returnsTrue
then that particular cell will not be included in the final grid.
- setRegionSize(regionSize=None, regionCenter=None, multiRegionInfo=None)
Allows you to update the regions that were set in the constructor. See the documentation there for the meaning of the parameters.
Core functions
- grale.grid.createUniformGrid(size, center, axisSubDivisions, excludeFunction=None)
Creates a uniform grid, centered on the X,Y coordinates in center and with width and height specified by size. The generated grid will be have axisSubDivisions cells in X and Y directions.
If excludeFunction is specified, for each grid cell it will be called as
excludeFunction(cellCenter, cellSize, True)
, and if the function returnsTrue
then that particular cell will not be included in the final grid.
- grale.grid.createMultiUniformGrid(uniformRegionInfo, excludeFunction=None)
This is a generalization of
createUniformGrid()
, to work with different regions that should each be uniformly subdivided. The uniformRegionInfo parameter should be a list of dictionaries, each having keys"size"
,"center"
and"axissubdiv"
, describing dimensions and subdivision of a particular region.If excludeFunction is specified, for each grid cell it will be called as
excludeFunction(cellCenter, cellSize, True)
, and if the function returnsTrue
then that particular cell will not be included in the final grid.
- grale.grid.createSubdivisionGridForFunction(targetDensityFunction, size, center, minSquares, maxSquares, startSubDiv=1, excludeFunction=None, maxIntegrationSubDiv=256, keepLarger=False, checkSubDivFunction=None)
Creates a grid of which the cell density is based on the values provided by a function targetDensityFunction, and do the refinement in such a way that the resulting number of grid cells is within the specified bounds. This is the core function that’s used by
createSubdivisionGrid()
andcreateSubdivisionGridForFITS()
, which themselves may me more straightforward to use for specific purposes.Arguments:
targetDensityFunction: a function which will be called with a (Ny,Nx,2) shaped NumPy array, describing X,Y coordinates on a 2D grid. The function must return an (Ny, Nx) shaped NumPy array containing the densities at the specified coordinates. Note that because the algorithm below will numerically integrate cells in the grid, it is probably not a good idea to let this function return negative values.
size and center: specifies the center X,Y coordinates of the grid, as well as the grid’s width and height.
minSquares and maxSquares: stop looking for the required grid refinement when the total number of grid cells lies between these values.
startSubDiv: by default, a single, large grid cell will be subdivided until the required refinement has been reached. By setting this option to 5 for example, you’d start from a uniform 5x5 grid, of which each cell will be refined further.
excludeFunction: if specified, for each grid cell it will be called as
excludeFunction(cellCenter, cellSize, True)
for the initial uniform grid (see startSubDiv), and asexcludeFunction(cellCenter, cellSize, False)
for the next subdivision steps. If the function returnsTrue
then that particular cell will not be included in the final grid.maxIntegrationSubDiv: to determine if a cell needs to be subdivided, the algorithm will integrate the contents numerically. This number specifies the maximum number of parts that are used for the entire size range. Smaller cells will be subdivided in fewer parts according to their size.
keepLarger: if
True
, after subdividing a grid cell, the original cell will also be kept in the list of cells.checkSubDivFunction: if specified, when a cell is considered to be subdivided, this function is called with as its two arguments the cell’s center and size. If it returns
False
, no subdivision may take place.
Refinement algorithm: in a helper routine, each cell will be split into four smaller cells whenever the integrated value of the cell exceeds some threshold. The main function then iteratively looks for an appropriate threshold, so that the final number of cells lies within the desired bounds.
- grale.grid.createMultiSubdivisionGridForFunction(targetDensityFunction, subdivRegionInfo, minSquares, maxSquares, excludeFunction=None, maxIntegrationSubDiv=256, keepLarger=False, checkSubDivFunction=None)
This is a generalization of
createSubdivisionGridForFunction()
, to allow the subdivision routine to work with several square regions at once. Most arguments are the same, but subdivRegionInfo now lists information about multiple regions.Arguments:
targetDensityFunction: a function which will be called with a (Ny,Nx,2) shaped NumPy array, describing X,Y coordinates on a 2D grid. The function must return an (Ny, Nx) shaped NumPy array containing the densities at the specified coordinates. Note that because the algorithm below will numerically integrate cells in the grid, it is probably not a good idea to let this function return negative values.
subdivRegionInfo: This specifies the different square regions that will be subdivided. It should be a list of dictionaries with the following keys:
"size"
,"center"
and optionally"startsubdiv"
. The first two describe the region itself; if the last one (defaults to 1) has value N, the subdivision process starts from a uniform NxN grid.minSquares and maxSquares: stop looking for the required grid refinement when the total number of grid cells (for all regions) lies between these values.
excludeFunction: if specified, for each grid cell it will be called as
excludeFunction(cellCenter, cellSize, True)
for the initial uniform grids (see"startsubdiv"
keys in subdivRegionInfo), and asexcludeFunction(cellCenter, cellSize, False)
for the next subdivision steps. If the function returnsTrue
then that particular cell will not be included in the final grid.maxIntegrationSubDiv: to determine if a cell needs to be subdivided, the algorithm will integrate the contents numerically. This number specifies the maximum number of parts that are used for the entire size range. Smaller cells will be subdivided in fewer parts according to their size.
keepLarger: if
True
, after subdividing a grid cell, the original cell will also be kept in the list of cells.checkSubDivFunction: if specified, when a cell is considered to be subdivided, this function is called with as its two arguments the cell’s center and size. If it returns
False
, no subdivision may take place.
The refinement algorithm is still the same as in
createSubdivisionGridForFunction()
: in a helper routine, each cell will be split into four smaller cells whenever the integrated value of the cell exceeds some threshold. The main function then iteratively looks for an appropriate threshold, so that the final number of cells lies within the desired bounds.
- grale.grid.createSubdivisionGridForFITS(fitsHDUEntry, centerRaDec, gridSize, gridCenter, minSquares, maxSquares, startSubDiv=1, excludeFunction=None, maxIntegrationSubDiv=256, keepLarger=False, ignoreOffset=True, useAbsoluteValues=True, checkSubDivFunction=None)
Creates a subdivision grid that’s based on an entry of a FITS file. It calls
createSubdivisionGridForFunction()
internally, where you can find the explanation of the algorithm used.Arguments:
fitsHDUEntry: the FITS entry on which the subdivision grid should be based
centerRaDec: use these RA,Dec coordinates to recalculate the coordinates in the FITS file, i.e. that specific point will be associated to the new (0,0) coordinate.
gridSize: the width and height of the grid, will be used as the size parameter in
createSubdivisionGridForFunction()
gridCenter: the center of the grid in the re-centered coordinates. Will be used as the center parameter in
createSubdivisionGridForFunction()
.minSquares, maxSquares, startSubDiv, excludeFunction, maxIntegrationSubDiv, keepLarger: see
createSubdivisionGridForFunction()
ignoreOffset: adds or subtracts a value from the data so that the minimum value becomes zero.
useAbsoluteValues: set to
False
to allow negative values (probably not a good idea).checkSubDivFunction: if specified, when a cell is considered to be subdivided, this function is called with as its two arguments the cell’s center and size. If it returns
False
, no subdivision may take place.
- grale.grid.createMultiSubdivisionGridForFITS(fitsHDUEntry, centerRaDec, subdivRegionInfo, minSquares, maxSquares, excludeFunction=None, maxIntegrationSubDiv=256, keepLarger=False, ignoreOffset=True, useAbsoluteValues=True, checkSubDivFunction=None)
This is a generalization of
createSubdivisionGridForFITS()
, callscreateMultiSubdivisionGridForFunction()
internally, where you can find the explanation of the algorithm used.Arguments:
fitsHDUEntry: the FITS entry on which the subdivision grid should be based
centerRaDec: use these RA,Dec coordinates to recalculate the coordinates in the FITS file, i.e. that specific point will be associated to the new (0,0) coordinate.
subdivRegionInfo, minSquares, maxSquares, excludeFunction, maxIntegrationSubDiv, keepLarger and checkSubDivFunction: see
createMultiSubdivisionGridForFunction()
ignoreOffset: adds or subtracts a value from the data so that the minimum value becomes zero.
useAbsoluteValues: set to
False
to allow negative values (probably not a good idea).
- grale.grid.createSubdivisionGrid(size, center, lensInfo, minSquares, maxSquares, startSubDiv=1, excludeFunction=None, maxIntegrationSubDiv=256, keepLarger=False, ignoreOffset=True, useAbsoluteValues=True, checkSubDivFunction=None)
Creates a subdivision grid that’s based on the specified gravitational lens information. Internally, the function
createSubdivisionGridForFunction()
is called, where you can find the explanation of the algorithm used.Arguments:
size: the width and height of the grid, will be used as the size parameter in
createSubdivisionGridForFunction()
center: the center of the grid in the re-centered coordinates. Will be used as the center parameter in
createSubdivisionGridForFunction()
.lensInfo: information about the gravitational lens, see
LensInfo
(orDensInfo
).minSquares, maxSquares, startSubDiv, excludeFunction, maxIntegrationSubDiv, keepLarger: see
createSubdivisionGridForFunction()
ignoreOffset: adds or subtracts a value from the data so that the minimum value becomes zero.
useAbsoluteValues: set to
False
to allow negative values (probably not a good idea).checkSubDivFunction: if specified, when a cell is considered to be subdivided, this function is called with as its two arguments the cell’s center and size. If it returns
False
, no subdivision may take place.
- grale.grid.createMultiSubdivisionGrid(subdivRegionInfo, lensInfo, minSquares, maxSquares, excludeFunction=None, maxIntegrationSubDiv=256, keepLarger=False, ignoreOffset=True, useAbsoluteValues=True, checkSubDivFunction=None)
This is a generalization of
createSubdivisionGrid()
, to work with several square regions at the same time. It creates a subdivision grid that’s based on the provided lens information; internally, the functioncreateMultiSubdivisionGridForFunction()
is called, where you can find the explanation of the algorithm used.Arguments:
subdivRegionInfo: specifies the regions, will be passed as the same parameter of
createMultiSubdivisionGridForFunction()
.lensInfo: information about the gravitational lens, can either be a single
LensInfo
(orDensInfo
) object, or a list of these, one for each region in the subdivRegionInfo list.minSquares, maxSquares, excludeFunction, maxIntegrationSubDiv, keepLarger and checkSubDivFunction: see
createSubdivisionGridForFunction()
.ignoreOffset: adds or subtracts a value from the data so that the minimum value becomes zero.
useAbsoluteValues: set to
False
to allow negative values (probably not a good idea).
- grale.grid.fractionalGridToRealGrid(grid)
Transforms the specified grid, which uses a grid center and fractional sizes and centers for the cells, to a straighforward list of cells, each having a regular center and size.
- grale.grid.fitMultiplePlummerLens(gridCells, Dd, targetDensityFunction, sizeFactor=1.7)
Fits a mass distribution based on multiple Plummer base functions that are arranged according to specified grid cells, to a specific target function. For each cell, the center of the cell and the centers of each side will be used to evaluate the target function. A least squares approach is then used to find the weigths of the basis functions that minimize the differences at these points.
The function returns an instance of the
MultiplePlummerLens
class.Examples can be found in the notebook fittest.ipynb.
Arguments:
gridCells: the grid to base the layout of the Plummer basis functions on
Dd: the angular diameter distance to be used when creating the
MultiplePlummerLens
instance.targetDensityFunction: a function which will be called with a (Ny,Nx,2) shaped NumPy array, describing X,Y coordinates on a 2D grid. The function must return an (Ny, Nx) shaped NumPy array containing the densities at the specified coordinates. Note that because the algorithm below will numerically integrate cells in the grid, it is probably not a good idea to let this function return negative values.
sizeFactor: a factor to be used to convert the size of a grid cell to the width of the Plummer basis function. For a cell with a size of 1 arcsec, a Plummer width of 1.7 arcsec will be used.