Skip to content

Commit

Permalink
Add documentation for updated survey system (#294)
Browse files Browse the repository at this point in the history
* Add documentation for updated survey system

* Completed doc for new surveys

* Small tweaks

* Additional tweaks

* Corrected meas_band_name in intro notebook
  • Loading branch information
thuiop authored Apr 22, 2022
1 parent 7fa57fb commit 9d19924
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 395 deletions.
9 changes: 1 addition & 8 deletions docs/source/src/btk.survey.rst
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
btk.survey module
=========================
The survey module defines the :class:`~btk.survey.Survey` class as a namedtuple, which contains the information relevant to observing conditions for a given survey. A Survey contains several instances of :class:`~btk.survey.Filter`, which are also namedtuples containing information specific to each filter.
The survey module interfaces with the `galcheat <https://github.com/aboucaud/galcheat>`_ package ; this package contains various informations about different surveys, including LSST, HSC (wide-field survey), HST COSMOS... Those informations are stored in a galcheat :class:`~galcheat.survey.Survey` object, containing several galcheat :class:`~galcheat.filter.Filter` objects, which is retrieved in BTK to compute fluxes and noise levels (using functions which are available in galcheat). The main modifications made by BTK to the galcheat objects are adding the PSF to the Filter object, and making them editable. This is achieved by defining a BTK :class:`~bkt.survey.Survey` and a BTK :class:`~bkt.survey.Filter` objects, which directly inherit from the corresponding galcheat objects.

.. automodule:: btk.survey
:exclude-members: Survey, Filter

.. autoclass:: Survey
:exclude-members: airmass, filters, effective_area, mirror_diameter, zeropoint_airmass, pixel_scale, name, count, index

.. autoclass:: Filter
:exclude-members: exp_time, extinction, name, psf, sky_brightness, zeropoint, name, count, index
139 changes: 30 additions & 109 deletions docs/source/tutorials.rst
Original file line number Diff line number Diff line change
Expand Up @@ -143,134 +143,55 @@ As a reference, here is a (slightly) simplified version of the code for this sam

You can see that this function chooses random galaxies (after applying a magnitude cut), computes random shifts for the galaxies and returns the entries from the table, adding two columns corresponding to the shifts.

You may write more complex sampling functions to have more control over how the galaxies are drawn; more examples canbe found in the ``btk.sampling_functions`` file.
You may write more complex sampling functions to have more control over how the galaxies are drawn; more examples can be found in the ``btk.sampling_functions`` file.

Survey
.......

The BTK Survey object defines the observing conditions relative to a survey. It is based on the named tuple class, and contains various parameters (eg. pixel scale, effective_area), including a list of Filter objects. The Filter class is also a named tuple, and contains information concerning a specific filter in the survey (eg. exporesure time, psf). Numerous surveys are already implemented in BTK; we will import the LSST one for this tutorial.
BTK relies on the `galcheat <https://github.com/aboucaud/galcheat>`_ package, which contains several galcheat :class:`~galcheat.survey.Survey` instances, which store the parameters for different surveys (including LSST, HSC, HST COSMOS...). The parameters represent physical parameters of the survey (mirror size, pixel scale) ; each survey also contains several galcheat :class:`galcheat.filter.Filter` objects with the parameters specific to each filter (exposure time, zeropoint).
Those objects can easily be imported in BTK using the following function and the name of the survey. Internally, we use a :class:`btk.survey.Survey` and a corresponding :class:`btk.filter.Filter`, which can be modified by the user (galcheat objects cannot) and contain an additional PSF attribute.
For this tutorial, we will import the survey corresponding to LSST.

.. jupyter-execute::

LSST = btk.survey.get_surveys("LSST")

You may want to define your own survey if you wish to modify some parameters or use a survey which is not implemented in BTK. We advise you to take the code of an existing survey and modify it to your convenience. Here is the one for LSST:
Most attributes should be pretty straightforward to modify; please take a look at the `API <https://lsstdesc.org/BlendingToolKit/src/btk.survey.html>`_ for a more substantial description of the attributes. The `custom tutorial <https://github.com/LSSTDESC/BlendingToolKit/blob/main/notebooks/02b-custom-tutorial.ipynb>`_ also provides descriptions of the attributes and more information on how to customize surveys.

The `psf` attribute deserves an additionnal explanation: it corresponds to the PSF for each filter. It is added via the `get_surveys` function : the user may provide a `psf` argument, which should be a callable taking as argument a survey and a filter and returning a galsim object. For instance :

.. jupyter-execute::

from btk.survey import get_psf

_central_wavelength = {
"u": 3592.13,
"g": 4789.98,
"r": 6199.52,
"i": 7528.51,
"z": 8689.83,
"y": 9674.05,
}

LSST = btk.survey.Survey(
"LSST",
pixel_scale=0.2,
effective_area=32.4,
mirror_diameter=8.36,
airmass=1.2,
zeropoint_airmass=1.2,
filters=[
btk.survey.Filter(
name="u",
psf=get_psf(
mirror_diameter=8.36,
effective_area=32.4,
filt_wavelength=_central_wavelength["u"],
fwhm=0.859,
),
sky_brightness=22.9,
exp_time=1680,
zeropoint=26.40,
extinction=0.451,
),
btk.survey.Filter(
name="g",
psf=get_psf(
mirror_diameter=8.36,
effective_area=32.4,
filt_wavelength=_central_wavelength["g"],
fwhm=0.814,
),
sky_brightness=22.3,
exp_time=2400,
zeropoint=28.26,
extinction=0.163,
),
btk.survey.Filter(
name="r",
psf=get_psf(
mirror_diameter=8.36,
effective_area=32.4,
filt_wavelength=_central_wavelength["r"],
fwhm=0.781,
),
sky_brightness=21.2,
exp_time=5520,
zeropoint=28.10,
extinction=0.10,
),
btk.survey.Filter(
name="i",
psf=get_psf(
mirror_diameter=8.36,
effective_area=32.4,
filt_wavelength=_central_wavelength["i"],
fwhm=0.748,
),
sky_brightness=20.5,
exp_time=5520,
zeropoint=27.78,
extinction=0.07,
),
btk.survey.Filter(
name="z",
psf=get_psf(
mirror_diameter=8.36,
effective_area=32.4,
filt_wavelength=_central_wavelength["z"],
fwhm=0.725,
),
sky_brightness=19.6,
exp_time=4800,
zeropoint=27.39,
extinction=0.043,
),
btk.survey.Filter(
name="y",
psf=get_psf(
mirror_diameter=8.36,
effective_area=32.4,
filt_wavelength=_central_wavelength["y"],
fwhm=0.703,
),
sky_brightness=18.6,
exp_time=4800,
zeropoint=26.56,
extinction=0.138,
),
],
)
import galsim

Most attributes should be pretty straightforward to modify; please take a look at the `API <https://lsstdesc.org/BlendingToolKit/src/btk.survey.html>`_ for a more substantial description of the attributes. The `custom tutorial <https://github.com/LSSTDESC/BlendingToolKit/blob/main/notebooks/02b-custom-tutorial.ipynb>`_ also provides descriptions of the attributes and more information on how to customize surveys.
def custom_psf(survey,filtr):
return galsim.Kolmogorov(fwhm=filtr.psf_fwhm.to_value("arcsec"))

LSST_custom = btk.survey.get_surveys("LSST",custom_psf)

The `psf` attribute deserves an additionnal explanation: it corresponds to the PSF for each filter. It can be provided either directly as a Galsim model (eg ``galsim.Kolmogorov(fwhm=1.5)``) or as a function returning a Galsim model, for randomization purposes. For example:
If no `psf` argument is provided, a default PSF taking into account optical and atmospheric effects will be used.

A more advanced possibility is to have your `custom_psf` function return a callable which in turn returns a galsim object. This callable will be called for each batch, allowing the user to randomize the PSF for instance :

.. jupyter-execute::

def random_psf():
fwhm = np.random.uniform(1.5,1.7)
return galsim.Kolmogorov(fwhm)
def custom_psf(survey,filtr):
def random_psf():
return galsim.Kolmogorov(fwhm=filtr.psf_fwhm.to_value("arcsec")+np.random.uniform(-0.1,+0.1)) #Randomize the FWHM
return random_psf

LSST_custom = btk.survey.get_surveys("LSST",custom_psf)

Finally, we included the function `get_psf_from_file(psf_dir, pixel_scale)` to import a PSF from a FITS file (randomly if there are more than one file in the directory provided). It can be used as :

.. jupyter-execute::

You may want to use a function taking an argument to avoid rewriting the function for each filter; we advise using lambda functions to achieve this, eg ``get_u_psf = lambda: get_custom_psf(u_band_argument)``.
def custom_psf(survey,filtr):
def random_psf():
return get_psf_from_file(psf_dir, survey.pixel_scale) #psf_dir should be replaced by the directory containing the PSF for the given survey and filter
return random_psf

Finally, you can use the default function ``get_psf`` as demonstrated in the LSST Survey, to get a complex (not random) PSF, or use the function ``get_psf_from_file(psf_dir, pixel_scale)`` to import a PSF from a FITS file (randomly if there are more than one file in the directory provided). For more information on these functions take a look at the API.
LSST_custom = btk.survey.get_surveys("LSST",custom_psf)

Drawing the blends
...................
Expand Down
2 changes: 1 addition & 1 deletion docs/source/user_guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ The workflow is as follows:

3. *Specify the* :class:`~btk.sampling_functions.SamplingFunction`: A sampling function is a callable object, which takes into input a catalog and returns specific entries along with parameters for a given blend (such as object shifts in the stamp for instance). You may use the default class :class:`~btk.sampling_functions.DefaultSamplingFunction`, or define a new one if you want to have more control over how the galaxies are selected and the blends are defined. *NOTE:* The default sampling function performs a cut of ``ref_mag < 25.3``. Please take a look at our `tutorials <tutorials.html>`_ page for more details.

4. *Specify the* :class:`~btk.survey.Survey`. A survey is a namedtuple containing different attributes relating to the observing conditions of a given survey, such as the pixel scale, and several :class:`~btk.survey.Filter` instances, which are also namedtuples containing attributes corresponding to the different filters of the survey (e.g. the exposition time or the sky brightness). PSF information is also contained in each of the :class:`~btk.survey.Filter` instance. You may either use one of the default surveys already defined in ``conf/surveys`` (see the `tutorials page <tutorials.html>`_ for details) or define your own survey to have more control of the parameters (see the `cli <cli.html>`_ page for details). Images for several surveys may also be produced simultaneously by replacing the survey object by a list of survey objects.
4. *Choose a survey:* BTK now relies on the `galcheat <https://github.com/aboucaud/galcheat>`_ package. This package contains informations on various survey, including LSST, HSC and HSC COSMOS (among others). It provides this information as a :class:`~galcheat.survey.Survey` object, which can be easily imported in BTK using its name, via the `get_surveys` function. It is also pretty simple to tweak the parameters of the survey at this stage. The user can also provide a custom PSF at this point, either as a Galsim model or with a FITS file (there is also a possibility to randomize the PSF if needed), or use the default PSF provided by BTK.

5. *Draw blends*: Simulates scene of overlapping objects, convolved by the PSF and with pixel noise. This step is done by creating a :class:`~btk.draw_blends.DrawBlendsGenerator`-like object (e.g. :class:`~btk.draw_blends.WLDGenerator`), which is given the catalog, sampling function and survey created in step 2 to 4. It can then be called using ``next(draw_blends_generator)`` to get the results as a dictionary, including the blends with the key ``blend_images``, the isolated galaxy images with the key ``isolated_images`` and the blend parameters with the key ``blend_list``. In the case where multiple surveys were provided in step 4, each entry will instead take the form of a dictionary indexed by the survey names, with each value corresponding to the information for one of the surveys.

Expand Down
Loading

0 comments on commit 9d19924

Please sign in to comment.