Skip to content

Commit

Permalink
Update NIRCam PSF photometry notebook
Browse files Browse the repository at this point in the history
  • Loading branch information
larrybradley committed Sep 15, 2023
1 parent af04c59 commit 4f1b8b1
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 69 deletions.
103 changes: 43 additions & 60 deletions notebooks/psf_photometry/NIRCam_PSF_Photometry_Example.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@
"os.environ[\"PYSYN_CDBS\"] = \"./grp/redcat/trds/\"\n",
"\n",
"# WEBBPSF Data\n",
"boxlink = 'https://stsci.box.com/shared/static/34o0keicz2iujyilg4uz617va46ks6u9.gz' \n",
"boxfile = './webbpsf-data/webbpsf-data-1.0.0.tar.gz'\n",
"boxlink = 'https://stsci.box.com/shared/static/qxpiaxsjwo15ml6m4pkhtk36c9jgj70k.gz'\n",
"boxfile = './webbpsf-data/webbpsf-data-1.2.1.tar.gz'\n",
"synphot_url = 'http://ssb.stsci.edu/trds/tarfiles/synphot5.tar.gz'\n",
"synphot_file = './synphot5.tar.gz'\n",
"\n",
Expand All @@ -94,8 +94,7 @@
" os.makedirs(synphot_folder)\n",
" urllib.request.urlretrieve(synphot_url, synphot_file)\n",
" gzf = tarfile.open(synphot_file)\n",
" gzf.extractall('./')\n",
"\n"
" gzf.extractall('./')"
]
},
{
Expand All @@ -111,46 +110,39 @@
"metadata": {},
"outputs": [],
"source": [
"import glob as glob\n",
"import os\n",
"import sys\n",
"import tarfile\n",
"import time\n",
"import urllib.request\n",
"\n",
"import jwst\n",
"import numpy as np\n",
"\n",
"import pandas as pd\n",
"\n",
"import glob as glob\n",
"\n",
"import jwst\n",
"from jwst.datamodels import ImageModel\n",
"\n",
"import tarfile\n",
"\n",
"import urllib.request\n",
"\n",
"from astropy import wcs\n",
"import webbpsf\n",
"from astropy import units as u\n",
"from astropy import wcs\n",
"from astropy.coordinates import SkyCoord, match_coordinates_sky\n",
"from astropy.io import fits\n",
"from astropy.visualization import (ZScaleInterval, SqrtStretch, ImageNormalize)\n",
"from astropy.visualization import simple_norm\n",
"from astropy.nddata import Cutout2D, NDData\n",
"from astropy.stats import gaussian_sigma_to_fwhm\n",
"from astropy.table import Table, QTable\n",
"from astropy.modeling.fitting import LevMarLSQFitter\n",
"from astropy.nddata import Cutout2D, NDData\n",
"from astropy.stats import gaussian_sigma_to_fwhm, sigma_clipped_stats\n",
"from astropy.table import QTable, Table\n",
"from astropy.visualization import (ImageNormalize, SqrtStretch, ZScaleInterval,\n",
" simple_norm)\n",
"from astropy.wcs.utils import pixel_to_skycoord\n",
"from astropy.coordinates import SkyCoord, match_coordinates_sky\n",
"from astropy.stats import sigma_clipped_stats\n",
"\n",
"from photutils import CircularAperture, EPSFBuilder, find_peaks, CircularAnnulus\n",
"from photutils.detection import DAOStarFinder, IRAFStarFinder\n",
"from photutils.psf import DAOGroup, IntegratedGaussianPRF, extract_stars, IterativelySubtractedPSFPhotometry\n",
"from photutils.background import MMMBackground, MADStdBackgroundRMS\n",
"from photutils.centroids import centroid_2dg\n",
"from photutils import aperture_photometry\n",
"\n",
"from ipywidgets import interact\n",
"\n",
"import webbpsf\n",
"from jwst.datamodels import ImageModel\n",
"from photutils.aperture import (CircularAnnulus, CircularAperture,\n",
" aperture_photometry)\n",
"from photutils.background import MADStdBackgroundRMS, MMMBackground\n",
"from photutils.centroids import centroid_2dg\n",
"from photutils.detection import DAOStarFinder, IRAFStarFinder, find_peaks\n",
"from photutils.psf import (DAOGroup, EPSFBuilder, IntegratedGaussianPRF,\n",
" IterativelySubtractedPSFPhotometry,\n",
" IterativePSFPhotometry, SourceGrouper,\n",
" extract_stars)\n",
"from webbpsf.utils import to_griddedpsfmodel"
]
},
Expand Down Expand Up @@ -252,7 +244,7 @@
" else:\n",
" d = d\n",
"\n",
" wv = np.float(f[1:3])\n",
" wv = float(f[1:3])\n",
"\n",
" if wv > 24: \n",
" ff_long.append(f)\n",
Expand Down Expand Up @@ -600,15 +592,10 @@
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Developer Note: Currently, display_psf_grid has a bug which has been fixed, but will not merged into the latest WebbPSF release until after commissioning. We have turned off this cell for the time being."
]
},
{
"cell_type": "markdown",
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"webbpsf.gridded_library.display_psf_grid(dict_psfs_webbpsf[dets_short[0]][filts_short[0]]['psf model grid'],\n",
" zoom_in=False, figsize=(14, 14))"
Expand All @@ -620,7 +607,7 @@
"source": [
"## II. Create the PSF model building an Effective PSF (ePSF)\n",
"\n",
"More information on the PhotUtils Effective PSF can be found [here](https://photutils.readthedocs.io/en/stable/epsf.html).\n",
"More information on the photutils Effective PSF can be found [here](https://photutils.readthedocs.io/en/stable/epsf.html).\n",
"\n",
"* Select the stars from the images we want to use for building the PSF. We use the [DAOStarFinder](https://photutils.readthedocs.io/en/stable/api/photutils.detection.DAOStarFinder.html) function to find bright stars in the images (setting a high detection threshold). [DAOStarFinder](https://photutils.readthedocs.io/en/stable/api/photutils.detection.DAOStarFinder.html#photutils.detection.DAOStarFinder) detects stars in an image using the DAOFIND ([Stetson 1987](https://ui.adsabs.harvard.edu/abs/1987PASP...99..191S/abstract)) algorithm. DAOFIND searches images for local density maxima that have a peak amplitude greater than `threshold` (approximately; threshold is applied to a convolved image) and have a size and shape similar to the defined 2D Gaussian kernel. \\\n",
" **Note**: The threshold and the maximum distance to the closest neighbour depend on the user science case (i.e.; number of stars in the field of view, crowding, number of bright sources, minimum number of stars required to build the ePSF, etc.) and must be modified accordingly. \n",
Expand Down Expand Up @@ -1005,7 +992,6 @@
" dict_phot[det][filt]['output photometry tables'] = {}\n",
"\n",
" for i in np.arange(0, len(dict_images[det][filt]['images']), 1):\n",
"\n",
" dict_phot[det][filt]['residual images'][i + 1] = None\n",
" dict_phot[det][filt]['output photometry tables'][i + 1] = None"
]
Expand Down Expand Up @@ -1055,7 +1041,7 @@
" daofind = DAOStarFinder(threshold=th * std + bkg, fwhm=sigma_psf, roundhi=1.0, roundlo=-1.0,\n",
" sharplo=0.30, sharphi=1.40)\n",
" \n",
" daogroup = DAOGroup(5.0 * sigma_psf)\n",
" grouper = SourceGrouper(5.0 * sigma_psf)\n",
" \n",
" # grid PSF\n",
"\n",
Expand All @@ -1078,19 +1064,21 @@
" print(\"Performing the photometry on image {number} of filter {f}, detector {d}\".format(number=i + 1, f=filt, d=det))\n",
" \n",
" tic = time.perf_counter()\n",
"\n",
" data_sub = data - mmm_bkg(data)\n",
" psf_shape = (11, 11)\n",
" \n",
" phot = IterativelySubtractedPSFPhotometry(finder=daofind, group_maker=daogroup,\n",
" bkg_estimator=mmm_bkg, psf_model=psf_model,\n",
" fitter=LevMarLSQFitter(),\n",
" niters=2, fitshape=(11, 11), aperture_radius=ap_radius[j])\n",
" result = phot(data)\n",
" phot = IterativePSFPhotometry(psf_model, psf_shape, daofind,\n",
" grouper=grouper, fitter=LevMarLSQFitter(),\n",
" maxiters=2, aperture_radius=ap_radius[j])\n",
" result = phot(data_sub)\n",
" \n",
" toc = time.perf_counter()\n",
" \n",
" print(\"Time needed to perform photometry on image {number}:\".format(number=i + 1), \"%.2f\" % ((toc - tic) / 3600), \"hours\")\n",
" print(\"Number of sources detected in image {number} for filter {f}:\".format(number=i + 1, f=filt), len(result))\n",
" \n",
" residual_image = phot.get_residual_image()\n",
" residual_image = phot.make_residual_image(data_sub, psf_shape)\n",
" \n",
" dict_phot[det][filt]['residual images'][i + 1] = residual_image\n",
" dict_phot[det][filt]['output photometry tables'][i + 1] = result\n",
Expand Down Expand Up @@ -1145,12 +1133,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"## Output Photometry Table\n",
"\n",
"\n",
"### Note for developer: \n",
"\n",
"It would be really useful, if PhotUtils can provide some diagnostics to identify the quality of the photometry in the final catalog for each source (similarly to all the other PSF photometry programs available)."
"## Output Photometry Table"
]
},
{
Expand Down Expand Up @@ -1922,7 +1905,7 @@
" else:\n",
" d = d\n",
"\n",
" wv = np.float(f[1:3])\n",
" wv = float(f[1:3])\n",
"\n",
" if wv > 24:\n",
" ff_long.append(f)\n",
Expand Down Expand Up @@ -2718,7 +2701,7 @@
"source": [
"## Final notes\n",
"\n",
"This notebook provides a general overview on how to perform PSF photometry using the [PhotUtils](https://photutils.readthedocs.io/en/stable/) package. The choice of the different parameters adopted in all the reduction steps as well as the choice of the PSF model depend on the specific user science case. Moreover, a detailed analysis that allow to provide recommendations on how to set those parameters and outline the differences in the output photometry when different PSF models are adopted (single vs PSF grid, number of PSFs in the grid, etc.) will be possible only when real data will be available after the instrument commissioning. In this context, we note that one of the selected ERS program (ERS 1334 - The Resolved Stellar Populations Early Release Science Program) will provide a fundamental test benchmark to explore how the different choices outlined above will impact the quality of the PSF photometry in a crowded stellar region."
"This notebook provides a general overview on how to perform PSF photometry using the [photutils](https://photutils.readthedocs.io/en/stable/) package. The choice of the different parameters adopted in all the reduction steps as well as the choice of the PSF model depend on the specific user science case. Moreover, a detailed analysis that allow to provide recommendations on how to set those parameters and outline the differences in the output photometry when different PSF models are adopted (single vs PSF grid, number of PSFs in the grid, etc.) will be possible only when real data will be available after the instrument commissioning. In this context, we note that one of the selected ERS program (ERS 1334 - The Resolved Stellar Populations Early Release Science Program) will provide a fundamental test benchmark to explore how the different choices outlined above will impact the quality of the PSF photometry in a crowded stellar region."
]
},
{
Expand Down Expand Up @@ -2757,7 +2740,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.10"
"version": "3.11.5"
}
},
"nbformat": 4,
Expand Down
18 changes: 9 additions & 9 deletions notebooks/psf_photometry/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
numpy>=1.22.4
pandas>=1.4.2
jwst==1.5.2
astropy>=5.1
photutils==1.4.0
ipywidgets>=7.7.0
webbpsf>=1.0.0
matplotlib>=3.5.2
stsynphot==1.1.0
numpy>=1.25.2
pandas>=2.1.0
jwst>=1.11.4
astropy>=5.3.3
photutils>=1.9.0
ipywidgets>=8.1.1
matplotlib>=3.7.2
webbpsf>=1.2.1
stsynphot>=1.2.0

0 comments on commit 4f1b8b1

Please sign in to comment.