From 005c700b0da632094bcb134c2150aa0ba8600212 Mon Sep 17 00:00:00 2001 From: christinawilliams Date: Thu, 24 Apr 2025 17:19:56 +0000 Subject: [PATCH 1/3] adding tutorial 18 --- DP0.2/18_Galaxy_Photometry.ipynb | 1054 ++++++++++++++++++++++++++++++ 1 file changed, 1054 insertions(+) create mode 100644 DP0.2/18_Galaxy_Photometry.ipynb diff --git a/DP0.2/18_Galaxy_Photometry.ipynb b/DP0.2/18_Galaxy_Photometry.ipynb new file mode 100644 index 00000000..92150a61 --- /dev/null +++ b/DP0.2/18_Galaxy_Photometry.ipynb @@ -0,0 +1,1054 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "id": "749b0ddf", + "metadata": { + "tags": [] + }, + "source": [ + "# DP0.2 Notebook 18 Galaxy Photometry\n", + "
\n", + "\"Rubin\n", + "
\n", + "Contact author(s): Christina Williams
\n", + "Last verified to run: 2025-04-22
\n", + "LSST Science Pipelines version: Weekly 2025_09
\n", + "Container Size: medium
" + ] + }, + { + "cell_type": "markdown", + "id": "2963cbac-4ecd-4694-bea3-c111f527e51b", + "metadata": {}, + "source": [ + "**Description:** Explore the available measurements of galaxy photometry produced by the LSST pipelines and their applications." + ] + }, + { + "cell_type": "markdown", + "id": "80a0baf5-51ad-40ec-8991-060a7b27c289", + "metadata": {}, + "source": [ + "**Skills:** Basic understanding of photometric measurement methods typically used to characterize galaxies." + ] + }, + { + "cell_type": "markdown", + "id": "393da88f-7978-4920-aa4a-a9830df6eed9", + "metadata": {}, + "source": [ + "**LSST Data Products:** objectTable" + ] + }, + { + "cell_type": "markdown", + "id": "5c67fab9-136a-4adc-bb42-142b91ab69dd", + "metadata": {}, + "source": [ + "**Packages:** `lsst.afw`, `astropy`, `photutils`, `scipy.stats`" + ] + }, + { + "cell_type": "markdown", + "id": "8f72b27f", + "metadata": {}, + "source": [ + "**Credit:**\n", + "This notebook benefitted from earlier exploration of simulated data and notebook development by Melissa Graham and Dan Taranu, helpful discussions with Jim Bosch, and ideas from Douglas Tucker. " + ] + }, + { + "cell_type": "markdown", + "id": "28e91cbf-ab7f-4e26-9276-b00299d6065e", + "metadata": {}, + "source": [ + "**Get Support:**\n", + "Find DP0-related documentation and resources at dp0.lsst.io.\n", + "Questions are welcome as new topics in the \n", + "Support - Data Preview 0 Category \n", + "of the Rubin Community Forum. \n", + "Rubin staff will respond to all questions posted there." + ] + }, + { + "cell_type": "markdown", + "id": "cfc73be0", + "metadata": {}, + "source": [ + "# 1. Introduction\n", + "\n", + "Photometry is the measurement of how much light is apparent from astronomical sources. The amount of light arriving on the telescope from the object is typically referred to as the flux density, or apparent magnitude (depending on units). Flux density is defined as the amount of energy arriving on the telescope per unit area, per unit time, per unit frequency (or wavelength) of the light.\n", + "\n", + "The LSST Science Pipelines makes a variety of photometric measurements for point-like and extended sources. This notebook will teach the user about the automated photometry measurements that are measured on the deepCoadd images and appear in the Object Catalog as part of the LSST pipelines data products. The focus will be on galaxies, and thus is distinct from the demonstrations in DP0.2 Tutorial Notebooks 12a (about PSF data products) and 12b (a PSF science demo).\n", + "\n", + "Please note that these explanations are specific to DP0.2: the `objectTable` contents and definitions are still subject to change for DP1. The photometry in the catalog are flux densities in units of nano-Jansky [nJy]. 1 Jy = 10^{-23} ergs/s/cm^2/Hz.\n" + ] + }, + { + "cell_type": "markdown", + "id": "7eb3ba1f-659f-4cb0-acad-52690f60a485", + "metadata": { + "execution": { + "iopub.execute_input": "2024-12-02T22:37:09.704845Z", + "iopub.status.busy": "2024-12-02T22:37:09.704072Z", + "iopub.status.idle": "2024-12-02T22:37:10.367698Z", + "shell.execute_reply": "2024-12-02T22:37:10.366983Z", + "shell.execute_reply.started": "2024-12-02T22:37:09.704824Z" + } + }, + "source": [ + "## 1.1 Types of photometry measurements in the Object Table\n", + "\n", + "Schema for the object catalog for DP0.2 is available here.\n", + "\n", + "Numerous photometry measurements are produced by the LSST Pipelines. Two types of photometry are there. The first are total fluxes (see Section 1.1.1), which aim to approximate (or model) all of the light coming from objects. Measurements that approximate total flux are \"Composite Model\" (cModel) fluxes. The second class of fluxes are measured inside an on-sky aperture but not corrected for flux that may fall outside: thus they are apparent fluxes but do not recover the intrisic (total) flux (see Section 1.1.2). The apparent fluxes are optimized for other purposes, such as for measuring accurate light profiles or accurate colors.\n", + "\n", + "### 1.1.1 Total fluxes\n", + "\n", + "\n", + "#### Composite Model (CModel) fluxes\n", + "\n", + "Similar in nature to those measured for SDSS (information available here). \n", + "\n", + "\n", + "In short, it is the linear combination of the best fit exponential (disk or D) and de Vaucouleurs (bulge or B) profiles. \n", + "\n", + "```\n", + "_cModelFlux : Flux from the final cmodel fit. Forced on -band.\n", + "_cModelFluxErr : Uncertainty of _cModelFlux\n", + "_cModel_flag : Failure flag for _cModelFlux\n", + "```\n", + "\n", + "For most cases the \"fixed\" cModel photometry (as listed above) are preferred to that measured with more degrees of freedom labeled `_free_cModelFlux`. The difference is that the fixed ones above uses a reference band (recorded as `refBand` in the schema) where the galaxy is well detected to determine the other parameters, which are then fixed when fitting for the flux in the other bands. The `_free_cModelFlux` measurement allows all parameters to be free and independent in each filter. The fixed `_cModelFlux` measurements are generally recommended for galaxy science applications where total flux measurements are needed (e.g. for intrinsic luminosity or mass).\n", + "\n", + "### 1.1.2 Apparent fluxes (i.e. not corrected to the total flux)\n", + " \n", + "#### Kron fluxes\n", + "\n", + "A decent summary of Kron fluxes in the NED documentation. The aperture used for the fluxes is 2.5 x R1 where R1 is the luminosity weighted radius (also called \"first moment\"; Kron et al. 1980).\n", + "\n", + "```\n", + "_kronFlux : Flux from Kron Flux algorithm. Measured on -band.\n", + "_kronFluxErr : Uncertainty of _kronFlux.\n", + "_kronFlux_flag : Failure flag for _kronFlux.\n", + "```\n", + "\n", + "The Kron radius, `_kronRad`, is also available. In this case of LSST pipeline output, the Kron flux is not corrected for light that is emitted outside of the Kron aperture. While in many cases it will collect the majority of light, it will not be as accurate as the cModel for science cases requiring total flux.\n", + "\n", + "\n", + "#### Aperture fluxes\n", + "This contains the enclosed flux inside a given aperture (they are not corrected to total fluxes using an aperture correction that accounts for the flux falling outside the aperture). Fixed aperture size refers to the aperture radius in pixels.\n", + "\n", + "```\n", + "_apFlux : Flux within -pixel aperture. Forced on -band.\n", + "_apFluxErr : Uncertainty of _apFlux.\n", + "_apFluxFlag : Failure flag for _apFlux.\n", + "```\n", + "\n", + "For DP0.2, the apertures are 3, 6, 9, 12, 17, 25, 35, 50, and 70 pixels. In the column name, apertures are `03`, `06`, `09`, `12`, and so on. While aperture fluxes are not corrected for the loss outside the aperture, if the aperture size is much larger than the galaxy size then it will approximate the total flux of the galaxy. The general application of these measurements are for measuring radial profiles (see Section 4 below).\n", + "\n", + "#### GaaP fluxes\n", + "\n", + "These are the Gaussian-aperture-and-PSF flux that is defined in Kuijken et al. 2008. The main goal of this method is to measure accurate colors while accounting for the different spatial resolution between filters. This is sometimes achieved in other datasets by convolving all images to the largest PSF, but this process of PSF-matching is computationally very time consuming for large images, thus motivating GaaP as a faster alternative. It is not a measure of total flux in a filter. Several measurement apertures are available. \n", + "\n", + "**Aperture**\n", + "\n", + "```\n", + "_gaapFlux : GaaP flux with aperture after multiplying the seeing aperture. Forced on -band.\n", + "_gaapFluxErr : Uncertainty of _gaapFlux.\n", + "```\n", + "\n", + "Where the measurement apertures are 0.5, 0.7, 1.0, 1.5, 2.5, and 3.0 arcseconds. In the column name `` appears as `0p5`, `0p7`, etc. Multiplying by the \"seeing aperture\" refers to convolving the PSF with a kernel so that the PSF is as if the seeing were 1.15 arcseconds. This has the effect of smearing the images of all filters consistently so that the colors are accurate.\n", + "\n", + "For photometric redshifts, and other analysis where accurate colors are important, it is recommended to use the GaaP fluxes with 1.0 aperture (optimal aperture was found to not perform as well, and should not be used). \n", + "\n", + "#### PSF fluxes\n", + "\n", + "Fluxes derived using the model point-spread function (PSF) of the image. Since PSF fluxes are designed for unresolved sources (not the majority of galaxies) this notebook will not explore science applications for this type of photometry. Interested users can find more information in the PSF Tutorial notebooks 12a and 12b. \n", + "\n", + "```\n", + "_psfFlux : Flux derived from linear least-squares fit of PSF model. Forced on -band.\n", + "_psfFluxErr : Uncertainty of _psfFlux.\n", + "_psfFlux_flag : Failure flag for _psfFlux.\n", + "\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "id": "dc36f107", + "metadata": {}, + "source": [ + "## 1.2 Import packages\n" + ] + }, + { + "cell_type": "markdown", + "id": "ccb4fe61-835a-47ac-a691-e086ce766e79", + "metadata": {}, + "source": [ + "`numpy` is a fundamental package for scientific computing with arrays in Python\n", + "(numpy.org).\n", + "\n", + "`matplotlib` is a comprehensive library for creating static, animated, and\n", + "interactive visualizations in Python \n", + "(matplotlib.org; \n", + "matplotlib gallery).\n", + "\n", + "`scipy.stats` contains statistical packages, this notebook will use binned_statistic to calculate running medians.\n", + "\n", + "From the `lsst` package, modules for accessing the TAP service, and image display functions from `afw` are imported (pipelines.lsst.io). Also import some geometric functions to help plot photometric apertures.\n", + "\n", + "From the `pyvo` package, import some functions that will enable using the image cutout tool.\n", + "\n", + "Finally, from `astropy` and `photutils` import packages to enable plotting images and drawing shapes on images with WCS information." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2dbc75bd-a802-4576-8628-4e0088942303", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "from scipy.stats import binned_statistic\n", + "\n", + "import lsst.geom as geom\n", + "import lsst.resources\n", + "import lsst.afw.display as afwDisplay\n", + "from lsst.afw.image import ExposureF\n", + "from lsst.rsp import get_tap_service\n", + "from lsst.afw.fits import MemFileManager\n", + "import lsst.afw.geom.ellipses as ellipses\n", + "\n", + "from pyvo.dal.adhoc import DatalinkResults, SodaQuery\n", + "import uuid\n", + "\n", + "from astropy import units as u\n", + "from astropy.coordinates import SkyCoord\n", + "from astropy.wcs import WCS\n", + "from photutils.aperture import SkyCircularAperture, SkyEllipticalAperture\n" + ] + }, + { + "cell_type": "markdown", + "id": "c217adff-25ed-4fce-95e7-8aa04630f6cc", + "metadata": {}, + "source": [ + "## 1.3 Define functions and parameters\n", + "\n", + "\n", + "### 1.3.1 Define some plotting defaults" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0d2ecffa-a837-4d10-be95-616c95fda15f", + "metadata": {}, + "outputs": [], + "source": [ + "afwDisplay.setDefaultBackend('matplotlib')\n", + "\n", + "plt.style.use('tableau-colorblind10')\n" + ] + }, + { + "cell_type": "markdown", + "id": "30e18bb8-9839-4961-b4f5-fa9d76a0cf7e", + "metadata": {}, + "source": [ + "### 1.3.2 Initialize the TAP service" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "61fe2c71-2684-483f-aa0d-5cb0d77bd758", + "metadata": {}, + "outputs": [], + "source": [ + "service = get_tap_service(\"tap\")" + ] + }, + { + "cell_type": "markdown", + "id": "5e6352ac-09dd-4be0-bff3-379860c12a69", + "metadata": {}, + "source": [ + "### 1.3.3 Define a shortcut function to generate an image cutout using the cutout tool\n", + "Further information about the cutout tool can be found in DP0.2 tutorial notebook 13a that demonstrates the Rubin image cutout service. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "07bba696-f49c-46e3-b867-61063195be99", + "metadata": {}, + "outputs": [], + "source": [ + "def make_image_cutout(tap_service, ra, dec, cutout_size=0.01):\n", + " \"\"\"\n", + " Wrapper function to generate a cutout using the cutout tool\n", + "\n", + " Parameters\n", + " ----------\n", + " tap_service : an instance of the TAP service\n", + " ra, dec : 'float'\n", + " the ra and dec of the cutout center\n", + " cutout_size : 'float', optional\n", + " edge length in degrees of the cutout\n", + "\n", + " Returns\n", + " -------\n", + " mem : 'object'\n", + " An lsst.afw.fits._fits.MemFileManager object containing the\n", + " cutout image bytes returned by the cutout tool. The \n", + " cutout image bytes can be accessed as an LSST awf image \n", + " exposure class format such as: cutout = ExposureF(mem)\n", + " \"\"\"\n", + "\n", + " spherePoint = geom.SpherePoint(ra*geom.degrees, dec*geom.degrees)\n", + " coord = SkyCoord(ra=ra*u.degree, dec=dec*u.degree, frame='icrs')\n", + "\n", + " band = 'i'\n", + "\n", + " query = \"SELECT access_format, access_url, dataproduct_subtype, \" + \\\n", + " \"lsst_patch, lsst_tract, lsst_band, s_ra, s_dec \" + \\\n", + " \"FROM ivoa.ObsCore WHERE dataproduct_type = 'image' \" + \\\n", + " \"AND obs_collection = 'LSST.DP02' \" + \\\n", + " \"AND dataproduct_subtype = 'lsst.deepCoadd_calexp' \" + \\\n", + " \"AND lsst_band = \" + \"'\" + str(band) + \"' \" + \\\n", + " \"AND CONTAINS(POINT('ICRS', \" + str(coord.ra.value) + \\\n", + " \", \" + str(coord.dec.value) + \"), \" + \\\n", + " \"s_region) = 1\"\n", + "\n", + " results = tap_service.search(query)\n", + "\n", + " dataLinkUrl = results[0].getdataurl()\n", + " auth_session = service._session\n", + " dl = DatalinkResults.from_result_url(dataLinkUrl,\n", + " session=auth_session)\n", + "\n", + " sq = SodaQuery.from_resource(dl,\n", + " dl.get_adhocservice_by_id(\"cutout-sync\"),\n", + " session=auth_session)\n", + "\n", + " sq.circle = (spherePoint.getRa().asDegrees() * u.deg,\n", + " spherePoint.getDec().asDegrees() * u.deg,\n", + " cutout_size * u.deg)\n", + " cutout_bytes = sq.execute_stream().read()\n", + " mem = MemFileManager(len(cutout_bytes))\n", + " mem.setData(cutout_bytes, len(cutout_bytes))\n", + "\n", + " return mem" + ] + }, + { + "cell_type": "markdown", + "id": "ec51ac0b", + "metadata": { + "tags": [] + }, + "source": [ + "# 2. Integrated photometry of galaxies using the LSST pipeline\n", + "\n", + "This section will explore integrated photometry measurements, and provide some guidance for which are optimal for certain science applications using galaxies. \n" + ] + }, + { + "cell_type": "markdown", + "id": "9547e659-fd0e-432c-af25-968cc9ebea9d", + "metadata": {}, + "source": [ + "## 2.2 Photometry measurements in objectTable\n", + "\n", + "First, see what is available in the object catalog by querying the `tap_schema` columns, and printing all the parameters available related to \"Flux\" measured in the i-band (as an example). For clarity, the return also omits errors and flags associated with the photometric measurements outlined in section 1.1. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "999d12f2-b84b-4a80-a7fd-f7f111674470", + "metadata": {}, + "outputs": [], + "source": [ + "query = \"SELECT column_name, datatype, description, unit \" \\\n", + " \"FROM tap_schema.columns \" \\\n", + " \"WHERE table_name = 'dp02_dc2_catalogs.Object'\"\n", + "\n", + "results = service.search(query).to_table()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3c0a793b-f6b1-4e39-99a2-1fd5b26fe4ae", + "metadata": {}, + "outputs": [], + "source": [ + "search_string = 'Flux'\n", + "band = 'i_'\n", + "exclude1 = 'Err'\n", + "exclude2 = 'flag'\n", + "for cname in results['column_name']:\n", + " if cname.find(search_string) > -1 and cname.find(band) > -1 and \\\n", + " cname.find(exclude1) == -1 and cname.find(exclude2) == -1:\n", + "\n", + " print(cname)" + ] + }, + { + "cell_type": "markdown", + "id": "caf9008d-e3aa-4908-bf32-a27cbe890a4f", + "metadata": {}, + "source": [ + "## 2.3 Compare photometric measurements\n", + "\n", + "### 2.3.1 Identify a galaxy sample to investigate photometry\n", + "\n", + "Below, query the DP0.2 `objectTable` for a selection of photometric measurements. This section will focus on 4 measurements: total flux from cModel (sum of bulge and disk sersic compoents fitted to the galaxy); and apparent fluxes measured as Kron (typically includes more than 90% of intrinsic light), GaaP (which is optimized for measuring accurate colors between bands), and aperture photometry (flux measured inside circles of varying size).\n", + "\n", + "First, focus on a known part of the simulation to contain a galaxy cluster (also seen in DP0.2 notebook tutorial 03a). Limit the search to contain galaxies using the `i_extendedness` flag (which will exclude point sources), and to those objects that are unique in the `objectTable` (by setting `detect_isPrimary` = True). Further, identify objects which have been detected at high signal to noise > 20 and whose photometric measurements have not been flagged as having an issue (`i_kronFlux_flag` or `i_cModel_flag` = 0 means the photometry is ok). " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "14450d07-0c29-4342-91f2-72ccc4cecfb0", + "metadata": {}, + "outputs": [], + "source": [ + "cluster_RA = 55.7506834813934\n", + "cluster_dec = -32.28892993702273\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0d82dd79-a4d7-4428-a77c-1ed2bb717486", + "metadata": {}, + "outputs": [], + "source": [ + "query = \"SELECT obj.objectId, obj.coord_ra, obj.coord_dec, \" + \\\n", + " \"obj.detect_fromBlend, obj.detect_isIsolated, \" + \\\n", + " \"obj.i_blendedness, obj.i_extendedness, \" + \\\n", + " \"obj.i_kronFlux, obj.i_kronFluxErr, obj.i_kronRad, \" + \\\n", + " \"obj.i_cModelFlux, obj.i_cModelFluxErr, obj.i_gaap1p0Flux, \" + \\\n", + " \"obj.g_gaap1p0Flux, \" + \\\n", + " \"obj.i_kronFlux_flag, obj.i_cModel_flag, \" + \\\n", + " \"obj.shape_xx, obj.shape_xy, obj.shape_yy, \" + \\\n", + " \"obj.i_ap03Flux, obj.i_ap06Flux, obj.i_ap09Flux, obj.i_ap12Flux, \" + \\\n", + " \"obj.i_ap17Flux, obj.i_ap25Flux, obj.i_ap35Flux, obj.i_ap50Flux \" + \\\n", + " \"FROM dp02_dc2_catalogs.Object AS obj \" + \\\n", + " \"WHERE (obj.detect_isPrimary = 1) AND \" + \\\n", + " \"(obj.i_cModelFlux/obj.i_cModelFluxErr > 20) AND \" + \\\n", + " \"(obj.i_extendedness = 1) AND \" + \\\n", + " \"(obj.i_kronFlux_flag = 0) AND (obj.i_cModel_flag = 0) AND \" + \\\n", + " \"CONTAINS(POINT('ICRS', obj.coord_ra, obj.coord_dec), \" + \\\n", + " \"CIRCLE('ICRS',\"+str(cluster_RA)+\",\"+str(cluster_dec)+\", 0.1)) = 1 \"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e75ee4db-e4b9-4ff2-ba07-1f7f34a8d44b", + "metadata": {}, + "outputs": [], + "source": [ + "job = service.submit_job(query)\n", + "job.run()\n", + "job.wait(phases=['COMPLETED', 'ERROR'])\n", + "print('Job phase is', job.phase)" + ] + }, + { + "cell_type": "markdown", + "id": "6d90ce60-2dc7-432d-bf12-1679cd43c3f3", + "metadata": {}, + "source": [ + "Print the results of the search query." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "02ea5eb7-bac9-4c9f-90e4-626a69340b41", + "metadata": {}, + "outputs": [], + "source": [ + "results = job.fetch_result()\n", + "tab = results.to_table()\n", + "tab" + ] + }, + { + "cell_type": "markdown", + "id": "e6a27a39-ed2b-49fe-ac6d-51ae4c300bfc", + "metadata": {}, + "source": [ + "Below, store the Kron Radius, which is a good proxy for the size of the galaxy light profile. Then convert the fluxes (units $nJy$) extracted from the `objectTable` into AB magnitudes using: $m_{AB} = -2.5log( f_{nJy}) + 31.4$ (see e.g. AB Magnitudes Wikipedia page for the conversion between flux in Jy and AB magnitudes).\n", + "\n", + "> **Warning:** The following cell will produce warnings for invalid value encountered in log10, which happens if the source flux is negative. This occasionally happens from aperture photometry if the included pixels inside the aperture have negative values and can be safely ignored for this example. The log10 will return a NaN which can be filtered out later." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e8b4a64a-6565-4d7d-ae48-0a666c41101e", + "metadata": {}, + "outputs": [], + "source": [ + "i_kronRad = tab['i_kronRad']\n", + "\n", + "cmodel_mag = -2.50 * np.log10(tab['i_cModelFlux']) + 31.4\n", + "kron_mag = -2.50 * np.log10(tab['i_kronFlux']) + 31.4\n", + "gaap_mag = -2.50 * np.log10(tab['i_gaap1p0Flux']) + 31.4\n", + "\n", + "ap06_mag = -2.50 * np.log10(tab['i_ap06Flux']) + 31.4\n", + "ap09_mag = -2.50 * np.log10(tab['i_ap09Flux']) + 31.4\n", + "ap17_mag = -2.50 * np.log10(tab['i_ap17Flux']) + 31.4\n", + "ap12_mag = -2.50 * np.log10(tab['i_ap12Flux']) + 31.4\n", + "ap35_mag = -2.50 * np.log10(tab['i_ap35Flux']) + 31.4" + ] + }, + { + "cell_type": "markdown", + "id": "85f65eb7-c0c6-45bf-8ff4-4e73b5e9e075", + "metadata": {}, + "source": [ + "### 2.3.2 Compare aperture photometry to cModel total fluxes\n", + "\n", + "This section will make several plots that shows how the different photometric measurements compare. Note that cModel is the total flux integrated from a model fit to the galaxy light profile, while Kron, GaaP, and aperture photometry are all measures of light within a fixed aperture. \n", + "\n", + "\n", + "#### 2.3.2.1 Aperture photometry\n", + "\n", + "Generally, magnitudes measured using aperture photometry in the LSST pipeline are larger (i.e. fainter) than those measured from cModel, because the fixed circular aperture systematically underestimates the flux in the galaxy wings (and the lost flux increases as the intrinsic size of the galaxy increases, e.g. as traced by the Kron radius)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d72bd736-3fb0-40b6-a607-a583ab4773ea", + "metadata": {}, + "outputs": [], + "source": [ + "fig, (ax, ax2) = plt.subplots(ncols=2, nrows=1,\n", + " width_ratios=[0.8, 0.2], figsize=(10, 6))\n", + "\n", + "ylims = [-1.5, 1.5]\n", + "ax.plot(i_kronRad, (cmodel_mag-ap06_mag), '^', alpha=.3,\n", + " label='6-pixel aperture', color='red')\n", + "ax.plot(i_kronRad, (cmodel_mag-ap09_mag), 's', alpha=.3,\n", + " label='9-pixel aperture', color='orange')\n", + "ax.plot(i_kronRad, (cmodel_mag-ap12_mag), 'o', alpha=.3,\n", + " label='12-pixel aperture', color='green')\n", + "ax.plot(i_kronRad, (cmodel_mag-ap17_mag), '.', alpha=.3,\n", + " label='17-pixel aperture', color='blue')\n", + "\n", + "ax2.hist((cmodel_mag-ap17_mag), edgecolor='blue', orientation=\"horizontal\",\n", + " bins=np.linspace(ylims[0], ylims[1], 40), align='mid',\n", + " histtype=\"step\", stacked=True, fill=False)\n", + "ax2.hist((cmodel_mag-ap12_mag), edgecolor='green', orientation=\"horizontal\",\n", + " bins=np.linspace(ylims[0], ylims[1], 40), align='mid',\n", + " histtype=\"step\", stacked=True, fill=False)\n", + "ax2.hist((cmodel_mag-ap09_mag), edgecolor='orange', orientation=\"horizontal\",\n", + " bins=np.linspace(ylims[0], ylims[1], 40), align='mid',\n", + " histtype=\"step\", stacked=True, fill=False)\n", + "ax2.hist((cmodel_mag-ap06_mag), edgecolor='red', orientation=\"horizontal\",\n", + " bins=np.linspace(ylims[0], ylims[1], 40), align='mid',\n", + " histtype=\"step\", stacked=True, fill=False)\n", + "\n", + "ax2.set_ylim(ylims)\n", + "ax.axhline(0, linestyle='--')\n", + "ax.set_xlabel('Kron Radius [i-band; pixels]')\n", + "ax.set_ylabel('cModel mag - Aperture mag')\n", + "ax.set_ylim(ylims)\n", + "ax.set_xlim([2, 10])\n", + "ax.legend()\n" + ] + }, + { + "cell_type": "markdown", + "id": "0e6cc869-a275-48b0-9ac8-febec0428e07", + "metadata": {}, + "source": [ + "> Figure 1: A comparison of the difference between cModel photometry and aperture photometry measured by the LSST pipelines for four different aperture sizes as a function of galaxy size (as measured using the Kron radius). The left panel shows the scatter plot of difference in photometry vs Kron radius, and the right panel shows a histogram of these values that demonstrate that larger aperture sizes have photometry that is closer to the cModel. The right panel shows histograms of the data in the left panel, where the colors indicate for the same data in each panel." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "709a40cf-df65-42ff-8a30-c787bcd79499", + "metadata": {}, + "outputs": [], + "source": [ + "fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(7, 6))\n", + "ylims = [-1.2, 1.2]\n", + "bins = np.arange(16, 27, 1)\n", + "\n", + "ax.plot(cmodel_mag, (cmodel_mag-ap06_mag), '^', alpha=.1,\n", + " label='cModel 6-pix aperture', color='red')\n", + "x = cmodel_mag\n", + "y = (cmodel_mag-ap06_mag)\n", + "bin_mean, bin_edge, binnum = binned_statistic(x, y,\n", + " statistic='median', bins=bins)\n", + "binctr = bin_edge[:-1] + (bin_edge[1:]-bin_edge[:-1])/2\n", + "ax.plot(binctr, bin_mean, color='red', lw=2, label='bin median', zorder=10)\n", + "\n", + "ax.plot(cmodel_mag, (cmodel_mag-ap09_mag), 's', alpha=.1,\n", + " label='cModel 9-pix aperture', color='orange')\n", + "x = cmodel_mag\n", + "y = (cmodel_mag-ap09_mag)\n", + "bin_mean, bin_edge, binnum = binned_statistic(x, y,\n", + " statistic='median', bins=bins)\n", + "binctr = bin_edge[:-1] + (bin_edge[1:]-bin_edge[:-1])/2\n", + "ax.plot(binctr, bin_mean, color='orange', lw=2,\n", + " label='bin median', zorder=10)\n", + "\n", + "ax.plot(cmodel_mag, (cmodel_mag-ap12_mag), 'o', alpha=.1,\n", + " label='cModel 12-pix aperture', color='green')\n", + "x = cmodel_mag\n", + "y = (cmodel_mag-ap12_mag)\n", + "bin_mean, bin_edge, binnum = binned_statistic(x, y,\n", + " statistic='median', bins=bins)\n", + "binctr = bin_edge[:-1] + (bin_edge[1:]-bin_edge[:-1])/2\n", + "ax.plot(binctr, bin_mean, color='green', lw=2,\n", + " label='bin median', zorder=10)\n", + "\n", + "ax.plot(cmodel_mag, (cmodel_mag-ap17_mag), '.', alpha=.1,\n", + " label='cModel 17-pix aperture', color='blue')\n", + "x = cmodel_mag\n", + "y = (cmodel_mag-ap17_mag)\n", + "bin_mean, bin_edge, binnum = binned_statistic(x, y,\n", + " statistic='median', bins=bins)\n", + "binctr = bin_edge[:-1] + (bin_edge[1:]-bin_edge[:-1])/2\n", + "ax.plot(binctr, bin_mean, color='blue', lw=2,\n", + " label='bin median', zorder=10)\n", + "\n", + "ax.axhline(0, linestyle='--')\n", + "ax.set_xlabel('cModel Magnitude')\n", + "ax.set_ylabel('cModel mag - Aperture mag')\n", + "ax.set_ylim([-1, 1])\n", + "ax.legend()\n" + ] + }, + { + "cell_type": "markdown", + "id": "eca1c28b-ac37-43b3-965d-1d03210b0b65", + "metadata": {}, + "source": [ + "> Figure 2: A similar comparison of the difference between cModel photometry and aperture photometry measured by the LSST pipelines for four different aperture sizes, this time as a function of cModel magnitude. Running median is included." + ] + }, + { + "cell_type": "markdown", + "id": "cef81cea-b352-4196-a4d0-c5b4ad80bd00", + "metadata": {}, + "source": [ + "These two figures show that the aperture photometry typically under-estimates the flux relative to the total flux estimated using cModel. As expected, there is a general trend for larger apertures to get closer to the total flux from cModel for large galaxies (i.e. whose Kron Radius is larger). There is also a general trend for the aperture photometry to be less discrepant at fainter magnitudes, since faint galaxies tend to be small.\n", + "\n", + "\n", + "### 2.3.3 Compare Kron and GaaP photometry to cModel\n", + "\n", + "In the next cell, compare the cModel instead to the Kron and GaaP measures." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "05e30151-1346-425a-a86f-f2a7c945a45c", + "metadata": {}, + "outputs": [], + "source": [ + "fig, (ax, ax2) = plt.subplots(ncols=2, nrows=1,\n", + " width_ratios=[0.8, 0.2], figsize=(10, 6))\n", + "ylims = [-2, 2]\n", + "\n", + "ax.plot(i_kronRad, (cmodel_mag-gaap_mag), 's', alpha=.3,\n", + " label='gaap1p0', color='orange')\n", + "\n", + "ax.plot(i_kronRad, (cmodel_mag-kron_mag), 'o', alpha=.3,\n", + " label='Kron', color='blue')\n", + "\n", + "ax2.hist((cmodel_mag-gaap_mag), orientation=\"horizontal\",\n", + " bins=np.linspace(ylims[0], ylims[1], 40), align='mid',\n", + " histtype=\"step\", color='orange', stacked=True, fill=False, label='gaap1p0')\n", + "ax2.hist((cmodel_mag-kron_mag), orientation=\"horizontal\",\n", + " bins=np.linspace(ylims[0], ylims[1], 40), align='mid',\n", + " histtype=\"step\", color='blue', stacked=True, fill=False, label='Kron')\n", + "\n", + "ax2.set_ylim(ylims)\n", + "ax.axhline(0, linestyle='--', color='r')\n", + "ax.set_xlabel('Kron Radius [i-band; pixels]')\n", + "ax.set_ylabel('cModel mag - Other mag')\n", + "ax.set_ylim(ylims)\n", + "ax.set_xlim([2, 15])\n", + "ax.legend()\n", + "ax2.legend()\n" + ] + }, + { + "cell_type": "markdown", + "id": "d12083d6-6006-4c67-b140-c7683516d7ab", + "metadata": {}, + "source": [ + "> Figure 3: The left panel figure shows the i-band magnitude difference between cModel and Kron (orange circles) and between cModel and gaap1p0 (blue squares) vs the Kron radius (a proxy for galaxy size) for the galaxies in the query. The dashed line indicates where the two magnitudes would have the same value. The gaap1p0 magnitude always underestimates the flux, while the Kron magnitude approaches the cModel magnitude for smaller, more compact galaxies. The right panel shows the histogram of the magnitude differences in the left panel, illustrating that while cModel - Kron magnitudes are similar on average (blue histogram) the gaap1p0 systematically underestimates the flux relative to cModel (orange histogram). \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "75923fd5-65fa-409e-a292-63e706ab4da5", + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(7, 6))\n", + "ylims = [-1.2, 1.2]\n", + "\n", + "ax.plot(cmodel_mag, (cmodel_mag-kron_mag), 's', alpha=.3,\n", + " label='cModel-Kron', color='blue')\n", + "x = cmodel_mag\n", + "y = (cmodel_mag-kron_mag)\n", + "bin_mean, bin_edge, binnum = binned_statistic(x, y,\n", + " statistic='median', bins=bins)\n", + "binctr = bin_edge[:-1] + (bin_edge[1:]-bin_edge[:-1])/2\n", + "ax.plot(binctr, bin_mean, color='k', lw=3, label=None, zorder=10)\n", + "ax.plot(binctr, bin_mean, color='blue', lw=2, label='bin median', zorder=11)\n", + "\n", + "ax.plot(cmodel_mag, (cmodel_mag-gaap_mag), 'o', alpha=.3,\n", + " label='cModel - gaap1p0', color='orange')\n", + "\n", + "x = cmodel_mag\n", + "y = (cmodel_mag-gaap_mag)\n", + "bin_mean, bin_edge, binnum = binned_statistic(x, y,\n", + " statistic='median', bins=bins)\n", + "binctr = bin_edge[:-1] + (bin_edge[1:]-bin_edge[:-1])/2\n", + "ax.plot(binctr, bin_mean, color='k', lw=3, label=None, zorder=10)\n", + "ax.plot(binctr, bin_mean, color='orange', lw=2, label='bin median', zorder=11)\n", + "\n", + "ax.axhline(0, linestyle='--')\n", + "ax.set_xlabel('cModel Magnitude')\n", + "ax.set_ylabel('cModel mag - Other mag')\n", + "ax.set_ylim([-1, 1])\n", + "ax.legend()" + ] + }, + { + "cell_type": "markdown", + "id": "b30953c9-2c2d-4569-a96b-3b558b0b672f", + "metadata": {}, + "source": [ + "> Figure 4: The figure shows the i-band magnitude difference between cModel and Kron (blue squares) and between cModel and gaap1p0 (orange circles) vs the cModel magnitude for the galaxies in the query. The lines correspond to the running median in magnitude bins to illustrate the trend. The dashed line indicates where the two magnitudes would have the same value. The gaap1p0 magnitude always underestimates the flux, while the Kron magnitude approaches the cModel magnitude for fainter galaxies." + ] + }, + { + "cell_type": "markdown", + "id": "9aec6b4b-ada8-429d-a65f-c076d8d26872", + "metadata": {}, + "source": [ + "The above plots show the parameter space where Kron fluxes do not correspond well with total fluxes (as measured by cModel). This indcates that Kron fluxes will underestimate the total fluxes in the regime of bright magnitudes and large Kron radius. Generally, cModel is recommended over Kron.\n", + "\n", + "As explained in Section 1, GaaP fluxes are not meant to measure total fluxes (from these plots it is clear there is a strong discrepancy with cModel) but GaaP measurements are the best and most robust for measuring robust integrated colors between different filters. Thus GaaP measurements should be used for Spectral Energy Distribution (SED) or photometric redshift modeling, or for color selections." + ] + }, + { + "cell_type": "markdown", + "id": "48d5bfb6-dc27-4ed8-b615-78216710912e", + "metadata": {}, + "source": [ + "# 3. Visualize photometric measurements\n", + "\n", + "Here make a cutout of a large galaxy in the cluster and compare the photometric aperture sizes of the different photometric measurements. The cell below also demonstrates how to reconstruct the Kron aperture using the corresponding shape parameters in the `objectTable`. The position angle `theta` is defined in radians counterclockwise from the x-axis. This cell will plot for an elongated edge-on galaxy (`objectId` of 1909948454470183768) to ensure that the visualization emphasizes the difference between the elliptical Kron aperture to the circular aperture. \n", + "\n", + "Alternatively, it is possible to pick a different bright object that has large size using the command\n", + "\n", + "`wh = np.where((tab['i_kronRad'] > 8) & (cmodel_mag < 20))[0]`\n", + "\n", + "Note that the pixel scale of the LSST data is 0.2 arcseconds per pixel. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "49387e7a-9e0d-4e00-a2b9-8767ab667929", + "metadata": {}, + "outputs": [], + "source": [ + "wh = np.where((tab['objectId'] == 1909948454470183768))[0]\n", + "indx = 0\n", + "\n", + "arcsec_per_pix = 0.2\n", + "\n", + "mem = make_image_cutout(service, tab['coord_ra'][wh][indx],\n", + " tab['coord_dec'][wh][indx], cutout_size=0.005)\n", + "\n", + "cutout = ExposureF(mem)\n", + "\n", + "axes = ellipses.Axes(ellipses.Quadrupole(tab['shape_xx'][wh][indx],\n", + " tab['shape_yy'][wh][indx],\n", + " tab['shape_xy'][wh][indx]))\n", + "Rmaj = axes.getA()\n", + "Rmin = axes.getB()\n", + "theta = axes.getTheta()\n", + "\n", + "plt.subplot(projection=WCS(cutout.getWcs().getFitsMetadata()))\n", + "extent = (cutout.getBBox().beginX, cutout.getBBox().endX,\n", + " cutout.getBBox().beginY, cutout.getBBox().endY)\n", + "\n", + "plt.imshow(cutout.image.array, vmin=.1, vmax=0.8,\n", + " extent=extent, origin='lower', cmap='gray')\n", + "\n", + "coord = SkyCoord(ra=tab['coord_ra'][wh][indx]*u.degree,\n", + " dec=tab['coord_dec'][wh][indx]*u.degree, frame='icrs')\n", + "\n", + "aperture = SkyCircularAperture(coord, r=17 * arcsec_per_pix * u.arcsec)\n", + "pix_aperture = aperture.to_pixel(WCS(cutout.getWcs().getFitsMetadata()))\n", + "pix_aperture.plot(color='r', lw=3, label='17 pixel aperture')\n", + "\n", + "aperture = SkyCircularAperture(coord, r=35 * arcsec_per_pix * u.arcsec)\n", + "pix_aperture = aperture.to_pixel(WCS(cutout.getWcs().getFitsMetadata()))\n", + "pix_aperture.plot(color='g', lw=3, label='35 pixel aperture')\n", + "\n", + "aperture = SkyEllipticalAperture(coord,\n", + " 2.5 * Rmaj * arcsec_per_pix * u.arcsec,\n", + " 2.5 * Rmin * arcsec_per_pix * u.arcsec,\n", + " theta=(np.pi/2 + theta) * u.rad)\n", + "\n", + "pix_aperture = aperture.to_pixel(WCS(cutout.getWcs().getFitsMetadata()))\n", + "pix_aperture.plot(color='b', lw=3, label='Kron')\n", + "plt.legend()\n", + "\n", + "print(\"Kron magnitude = \", kron_mag[wh][indx])\n", + "print(\"17-pix Aperture mag = \", ap17_mag[wh][indx])\n", + "print(\"35-pix Aperture mag = \", ap35_mag[wh][indx])\n", + "print(\"cModel mag = \", cmodel_mag[wh][indx])\n" + ] + }, + { + "cell_type": "markdown", + "id": "7476643c-50e3-418e-9d31-704e3f060bc9", + "metadata": {}, + "source": [ + "> Figure 5: An i-band image cutout of an example galaxy (grayscale). The photometric apertures are overplotted including Kron (blue), the 17 pixel aperture (red) and the 35 pixel aperture (green). None of the apertures enclose all of the flux visible from the galaxy, which is why the photometry measures less flux than the total flux from cModel." + ] + }, + { + "cell_type": "markdown", + "id": "125bf616-aad9-4291-85fe-503b68f0d539", + "metadata": {}, + "source": [ + "The above figure shows more clearly that there is some fraction of the galaxy's light excluded by each of these photometric apertures. Further, printing the different photometry measurements illustrates how these assumed apertures will change the measured flux (compared to the total flux measured by cModel, which approximates the total magnitude using sersic models for the light profile). " + ] + }, + { + "cell_type": "markdown", + "id": "ec25172d-0f22-41c0-8b40-5bd1bc4133eb", + "metadata": {}, + "source": [ + "# 4. Application of GaaP Photometry: galaxy colors\n", + "\n", + "This section demonstrates using GaaP photometry to calculate accurate galaxy colors to identify different types of galaxies. First, define magnitudes from u, g, r, and i band photometry. The second cell will then compare the colors of galaxies that overlap the galaxy cluster with that in the field. In clusters, galaxies tend to be old, red elliptical galaxies and thus exhibit a well defined red sequence in color space. \n", + "\n", + "For comparison, search for and plot galaxies from a random location that will be dominated by bluer star forming galaxies\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2526bac6-67a5-4836-b910-6f64052fa205", + "metadata": {}, + "outputs": [], + "source": [ + "random_RA = 56.7506834813934\n", + "random_dec = -31.28892993702273\n", + "\n", + "query = \"SELECT obj.objectId, obj.coord_ra, obj.coord_dec, \" + \\\n", + " \"obj.detect_fromBlend, obj.detect_isIsolated, \" + \\\n", + " \"obj.i_blendedness, obj.i_extendedness, \" + \\\n", + " \"obj.i_kronFlux, obj.i_kronFluxErr, obj.i_kronRad, \" + \\\n", + " \"obj.i_cModelFlux, obj.i_cModelFluxErr, obj.i_gaap1p0Flux, \" + \\\n", + " \"obj.g_gaap1p0Flux, \" + \\\n", + " \"obj.i_kronFlux_flag, obj.i_cModel_flag \" + \\\n", + " \"FROM dp02_dc2_catalogs.Object AS obj \" + \\\n", + " \"WHERE (obj.detect_isPrimary = 1) AND \" + \\\n", + " \"(obj.i_cModelFlux/obj.i_cModelFluxErr > 20) AND \" + \\\n", + " \"(obj.i_extendedness = 1) AND \" + \\\n", + " \"(obj.i_kronFlux_flag = 0) AND (obj.i_cModel_flag = 0) AND \" + \\\n", + " \"CONTAINS(POINT('ICRS', obj.coord_ra, obj.coord_dec), \" + \\\n", + " \"CIRCLE('ICRS',\"+str(random_RA)+\",\"+str(random_dec)+\", 0.1)) = 1 \"\n", + "\n", + "job = service.submit_job(query)\n", + "job.run()\n", + "job.wait(phases=['COMPLETED', 'ERROR'])\n", + "print('Job phase is', job.phase)\n", + "\n", + "results = job.fetch_result()\n", + "tab2 = results.to_table()\n" + ] + }, + { + "cell_type": "markdown", + "id": "f5bcc8d3-3607-492f-93d2-79f239321307", + "metadata": {}, + "source": [ + "First, calculate the magnitudes of galaxies in the 'random' location (outside the galaxy cluster) and also the magnitudes for the other filters near the galaxy cluster from the query performed in Section 2. This will enable plotting their colors.\n", + "\n", + "> **Warning:** Like in Section 2.3, the following cell will produce warnings for invalid value encountered in log10, which happens if the source flux is negative. This happens for a small number of objects and since the goal of the plot is to see the distribution of the majority of sources, the warning can be safely ignored. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6e1be2f4-74b1-4d73-87bd-fb6d08d2a6c2", + "metadata": {}, + "outputs": [], + "source": [ + "i_random_gaap_mag = -2.50 * np.log10(tab2['i_gaap1p0Flux']) + 31.4\n", + "g_random_gaap_mag = -2.50 * np.log10(tab2['g_gaap1p0Flux']) + 31.4\n", + "\n", + "g_cluster_gaap_mag = -2.50 * np.log10(tab['g_gaap1p0Flux']) + 31.4\n", + "i_cluster_gaap_mag = -2.50 * np.log10(tab['i_gaap1p0Flux']) + 31.4\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6d53c736-3a5a-4390-9aaf-0c748e4fa08a", + "metadata": {}, + "outputs": [], + "source": [ + "fig, (ax, ax1) = plt.subplots(ncols=1, nrows=2, figsize=(10, 6))\n", + "\n", + "ax.plot(i_random_gaap_mag, (g_random_gaap_mag-i_random_gaap_mag),\n", + " '.', alpha=.1, color='blue', label='Field Galaxies')\n", + "ax.set_xlabel('i-band Magnitude [GaaP]')\n", + "ax.set_ylabel('g-i color')\n", + "ax.set_ylim([-1, 4])\n", + "ax.legend()\n", + "\n", + "ax1.plot(i_cluster_gaap_mag, (g_cluster_gaap_mag-i_cluster_gaap_mag),\n", + " '.', alpha=.1, color='red', label='Cluster Galaxies')\n", + "ax1.set_xlabel('i-band Magnitude [GaaP]')\n", + "ax1.set_ylabel('g-i color')\n", + "ax1.set_ylim([-1, 4])\n", + "ax1.legend()" + ] + }, + { + "cell_type": "markdown", + "id": "07a4487a-b8d6-4e1c-bbb7-045175c2928a", + "metadata": {}, + "source": [ + "> Figure 6: The g − i vs. i color-magnitude diagram for galaxies selected in the queries. Top panel shows the galaxies selected from in a random field of DP0.2 that does not contain a galaxy cluster. The bottom panel shows galaxies from a field with a galaxy cluster. The cluster galaxies appear as a \"red sequence\" with red i-g colors, because the Balmer / 4000 Angstrom break spectral feature that traces older stars sits between the bands." + ] + }, + { + "cell_type": "markdown", + "id": "69a95a3b-09c7-4ab8-939a-1816d33c8578", + "metadata": {}, + "source": [ + "A very nice red sequence appears from the red, old galaxies in the cluster! " + ] + }, + { + "cell_type": "markdown", + "id": "714badaa-834d-4050-82a6-ffcac245ae5c", + "metadata": {}, + "source": [ + "# 5. Application of aperture photometry: radial profile\n", + "\n", + "A science application for the aperture photometry is easy visualization of the radial profile of galaxies. In the cell below, make this plot for both a large galaxy (first) and a smaller galaxy of similar brightness (second). The query looks for bright galaxies whose cModel magnitude ~ 20. Dividing the aperture flux by the surface area of the aperture yields the surface brightness, which can be plotted as a function of radius from the center of the galaxy to compare radial light profiles." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "432db690-be7e-43bf-a640-a80af727652b", + "metadata": {}, + "outputs": [], + "source": [ + "wh = np.where((tab['i_kronRad'] > 8) & (cmodel_mag > 19.9)\n", + " & (cmodel_mag < 20.1))[0]\n", + "indx = 2\n", + "\n", + "rad = np.array([3, 6, 9, 12, 17, 25, 35, 50]) * arcsec_per_pix\n", + "area = np.pi * rad**2\n", + "profile = np.array([tab['i_ap03Flux'][wh][indx], tab['i_ap06Flux'][wh][indx],\n", + " tab['i_ap09Flux'][wh][indx], tab['i_ap12Flux'][wh][indx],\n", + " tab['i_ap17Flux'][wh][indx], tab['i_ap25Flux'][wh][indx],\n", + " tab['i_ap35Flux'][wh][indx],\n", + " tab['i_ap50Flux'][wh][indx]]) / area\n", + "\n", + "plt.plot(rad, profile,\n", + " label='Large Radius R='\n", + " + str(round(i_kronRad[wh][indx]*arcsec_per_pix, 2)))\n", + "plt.xlabel('Aperture Radius [arcsec]')\n", + "plt.ylabel(r'Surface Brightness [nJy arcsec$^{-2}$]')\n", + "\n", + "wh2 = np.where((tab['i_kronRad'] < 8) & (tab['i_kronRad'] > 5)\n", + " & (cmodel_mag > 19.9) & (cmodel_mag < 20.1))[0]\n", + "\n", + "indx = 1\n", + "\n", + "profile = np.array([tab['i_ap03Flux'][wh2][indx], tab['i_ap06Flux'][wh2][indx],\n", + " tab['i_ap09Flux'][wh2][indx], tab['i_ap12Flux'][wh2][indx],\n", + " tab['i_ap17Flux'][wh2][indx], tab['i_ap25Flux'][wh2][indx],\n", + " tab['i_ap35Flux'][wh2][indx],\n", + " tab['i_ap50Flux'][wh2][indx]])/area\n", + "\n", + "plt.plot(rad, profile,\n", + " label='Small Radius R='\n", + " + str(round(i_kronRad[wh2][indx]*arcsec_per_pix, 2)))\n", + "plt.legend()\n", + "plt.yscale('log')" + ] + }, + { + "cell_type": "markdown", + "id": "81f960b3-0661-4a57-8e39-05c403b77afd", + "metadata": {}, + "source": [ + "> Figure 7: Plot demonstrating the use of aperture photometry to plot the surface brightness profile (as a function of aperture radius) for a galaxy with large Kron radius (blue) and small Kron radius (orange). " + ] + }, + { + "cell_type": "markdown", + "id": "6f271dc2-4d44-41b2-b620-062750deb7b3", + "metadata": {}, + "source": [ + "# 6. Exercise for the learner\n", + "\n", + "Compare the `_free_cModelFlux` measurements to `_cModelFlux` in the filters that are not the reference band where the `_cModelFlux` was measured (i.e. `refBand`). Investigate how leaving the cModel measurements free differs from the one measured with parameters fixed to the `refBand`, as a function of decreasing signal to noise. As an additional exercise, check how the signal to noise in colors measured using `_gaap1p0Flux` values compare to those measured with the larger 3.0\" aperture, `_gaap3p0Flux`, where the larger aperture may increase the noise. " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "LSST", + "language": "python", + "name": "lsst" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.9" + }, + "toc-autonumbering": false + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 140569ac4a7b160c32cc5c415adf006ff716c0cd Mon Sep 17 00:00:00 2001 From: christinawilliams Date: Thu, 24 Apr 2025 17:24:57 +0000 Subject: [PATCH 2/3] adding tutorial 18 --- DP0.2/18_Galaxy_Photometry.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DP0.2/18_Galaxy_Photometry.ipynb b/DP0.2/18_Galaxy_Photometry.ipynb index 92150a61..921fb8fe 100644 --- a/DP0.2/18_Galaxy_Photometry.ipynb +++ b/DP0.2/18_Galaxy_Photometry.ipynb @@ -13,7 +13,7 @@ "\"Rubin\n", "\n", "Contact author(s): Christina Williams
\n", - "Last verified to run: 2025-04-22
\n", + "Last verified to run: 2025-04-24
\n", "LSST Science Pipelines version: Weekly 2025_09
\n", "Container Size: medium
" ] From eb7214bae91c3cc667684c252c105f34f2ede468 Mon Sep 17 00:00:00 2001 From: christinawilliams Date: Thu, 24 Apr 2025 17:54:59 +0000 Subject: [PATCH 3/3] adding tutorial 18 --- DP0.2/18_Galaxy_Photometry.ipynb | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/DP0.2/18_Galaxy_Photometry.ipynb b/DP0.2/18_Galaxy_Photometry.ipynb index 921fb8fe..9d837d0e 100644 --- a/DP0.2/18_Galaxy_Photometry.ipynb +++ b/DP0.2/18_Galaxy_Photometry.ipynb @@ -89,15 +89,7 @@ { "cell_type": "markdown", "id": "7eb3ba1f-659f-4cb0-acad-52690f60a485", - "metadata": { - "execution": { - "iopub.execute_input": "2024-12-02T22:37:09.704845Z", - "iopub.status.busy": "2024-12-02T22:37:09.704072Z", - "iopub.status.idle": "2024-12-02T22:37:10.367698Z", - "shell.execute_reply": "2024-12-02T22:37:10.366983Z", - "shell.execute_reply.started": "2024-12-02T22:37:09.704824Z" - } - }, + "metadata": {}, "source": [ "## 1.1 Types of photometry measurements in the Object Table\n", "\n",