diff --git a/CHANGES.rst b/CHANGES.rst index 9569b69fb..882d91991 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -75,7 +75,7 @@ scripts source_detection ---------------- -- Support for PSF fitting (optional) for accurate centroids. [#841] +- Support for PSF fitting (optional) for accurate centroids. [#841, #984] - Save source catalog to a structured array. [#987] diff --git a/docs/conf.py b/docs/conf.py index f49764ae1..eeb0eedf4 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -69,6 +69,8 @@ def check_sphinx_version(expected_version): "matplotlib": ("http://matplotlib.org/", None), "gwcs": ("https://gwcs.readthedocs.io/en/latest/", None), "astropy": ("https://docs.astropy.org/en/stable/", None), + "photutils": ("https://photutils.readthedocs.io/en/stable/", None), + "webbpsf": ("https://webbpsf.readthedocs.io/en/latest/", None), } if sys.version_info[0] == 2: diff --git a/docs/roman/source_detection/arguments.rst b/docs/roman/source_detection/arguments.rst index edffce08e..7323cca7f 100644 --- a/docs/roman/source_detection/arguments.rst +++ b/docs/roman/source_detection/arguments.rst @@ -1,11 +1,13 @@ Arguments ========= + The source detection fitting step has several arguments. These can be specified by the user by passing them to the step in a Python session, or setting them in a parameter file. * ``--kernel_fwhm``: A parameter for DAOStarFinder: size of Gaussian kernel in - pixels. Default is 2.0. + pixels. By default the FWHM is assumed to be the diffraction + limited PSF, given the filter used for this observation. * ``--sharplo``: A parameter for DAOStarFinder: lower bound for sharpness. Default is 0.0. * ``--sharphi``: A parameter for DAOStarFinder: upper bound for sharpness. @@ -42,7 +44,7 @@ in a parameter file. * ``--bkg_boxsize``: If using `calc_threshold_img` size of box in pixels for 2D background / threshold images and if using calc_threshold_2d, the size of the box used when detecting - sources. Default is 3. + sources. Default is 9. * ``--bkg_sigma``: If using `calc_threshold_img`, n sigma for sigma clipping for background calculation. Default is 2.0. * ``--bkg_filter_size``: If using `calc_threshold_img` or `calc_threshold_2d`, @@ -55,3 +57,5 @@ in a parameter file. will be saved as a numpy array with four dimensions. In order, these represent source ID, x centroid position, y centroid position, and flux. +* ``--fit_psf``: If True, fit a PSF model to each detected source for more precise + source centroids and fluxes. diff --git a/docs/roman/source_detection/description.rst b/docs/roman/source_detection/description.rst index 9f8a07963..21b37c150 100644 --- a/docs/roman/source_detection/description.rst +++ b/docs/roman/source_detection/description.rst @@ -3,14 +3,35 @@ Description The source detection step produces catalogs of point-like sources for use by the Tweakreg step for image alignment. It uses DAOStarFinder to detect point sources -in the image. +in the image, with an option to subsequently fit PSF models to the detected +sources for more precise centroids and fluxes. +Detecting Sources +----------------- + +Sources are detected using `~photutils.detection.DAOStarFinder` from +`photutils `_, which is an +implementation of the method `DAOFIND` from +`Stetson (1987) `_. +The algorithm can be provided limits on the source flux, radius, roundness, +sharpness, and background. + +PSF Fitting +----------- + +Star finding algorithms like `~photutils.detection.DAOStarFinder` provide +approximate stellar centroids. More precise centroids may be inferred by +fitting model PSFs to the observations. Setting the SourceDetectionStep's +option `fit_psf` to True will generate model Roman PSFs with +`WebbPSF `_, and fit +those models to each of the sources detected by +`~photutils.detection.DAOStarFinder`. More details are in :doc:`psf`. Outputs / Returns -================= +----------------- By default, the resulting source catalog will be temporarily attached to the -output ImageModel in the `meta.source_catalog.tweakreg_catalog` attribute as 4D +output ImageModel in the `meta.source_catalog.tweakreg_catalog` attribute as numpy array representing, in order, source ID, x centroid position, y centroid position, and flux. This catalog will then be deleted from the model in the Tweakreg step. @@ -28,7 +49,7 @@ only be saved if it does not contain an attached catalog - to do this, use the separately. Options for Thresholding -======================== +------------------------ The DAOStarFinder routine detects point-like sources in an image that are above a certain, specified floating point threshold. This step provides several options @@ -44,10 +65,10 @@ threshold value for the entire image based on the sigma-clipped average (mean, median, or mode) background level of the whole image. Other Options -============= +------------- Limiting maximum number of sources ----------------------------------- +++++++++++++++++++++++++++++++++++ By default, all detected sources will be returned in the final output catalog. If you wish to limit the number of sources, this can be done with the diff --git a/docs/roman/source_detection/index.rst b/docs/roman/source_detection/index.rst index 2dc35264f..31aa52bfd 100644 --- a/docs/roman/source_detection/index.rst +++ b/docs/roman/source_detection/index.rst @@ -9,5 +9,8 @@ Source Detection description.rst arguments.rst + psf.rst .. automodapi:: romancal.source_detection + +.. automodapi:: romancal.lib.psf diff --git a/docs/roman/source_detection/psf.rst b/docs/roman/source_detection/psf.rst new file mode 100644 index 000000000..56f4af506 --- /dev/null +++ b/docs/roman/source_detection/psf.rst @@ -0,0 +1,29 @@ +PSF Fitting +=========== + +A few PSF fitting utilities are included to interface between observations +within Roman datamodels and methods within dependencies that generate and +fit PSF models to observations. + +Create PSF models +----------------- + +`~romancal.lib.psf.create_gridded_psf_model` computes a gridded PSF model for +a given detector using `~webbpsf.gridded_library.CreatePSFLibrary` from +`WebbPSF `_. The defaults are chosen to +balance more accurate PSF models with the cost of increased runtime. For +further reading on the WebbPSF approach to ePSFs, see the WebbPSF docs on +`Using PSF Grids `_. + +Fit model PSFs to an ImageModel +------------------------------- + +Once PSF models are generated, you can fit those models to observations +in an ImageModel with `~romancal.lib.psf.fit_psf_to_image_model` using +`photutils `_. +By default the fits are done with `~photutils.psf.PSFPhotometry`, and +crowded fields may benefit from using `~photutils.psf.IterativePSFPhotometry`. +For neighboring sources that are near one another on the detector, grouping +the sources and fitting their PSFs simultaneously improves the fit quality. +Initial guesses for target centroids can be given or source +detection can be performed with, e.g., `~photutils.detection.DAOStarFinder`. diff --git a/romancal/lib/psf.py b/romancal/lib/psf.py index 99e4733a7..227d6c4b2 100644 --- a/romancal/lib/psf.py +++ b/romancal/lib/psf.py @@ -24,6 +24,12 @@ from romancal.lib.dqflags import pixel as roman_dq_flag_map +__all__ = [ + "create_gridded_psf_model", + "fit_psf_to_image_model", + "dq_to_boolean_mask", +] + # set loggers to debug level by default: log = logging.getLogger(__name__) log.setLevel(logging.DEBUG) @@ -68,7 +74,7 @@ def create_gridded_psf_model( ): """ Compute a gridded PSF model for one SCA via - `webbpsf.gridded_library.CreatePSFLibrary`. + `~webbpsf.gridded_library.CreatePSFLibrary`. Parameters ---------- @@ -210,7 +216,7 @@ def fit_psf_to_image_model( exclude_out_of_bounds=True, ): """ - Fit PSF models to an ImageModel. + Fit PSF models to an ``ImageModel``. Parameters ----------