From b25f054aa13227593e928d7b7d0a3bd40b9b4812 Mon Sep 17 00:00:00 2001 From: christinawilliams Date: Fri, 9 Jan 2026 22:10:10 +0000 Subject: [PATCH 01/14] cutout updates --- .../103_4_Small_Image_Cutout.ipynb | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb b/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb index cd98dae..c56c06f 100644 --- a/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb +++ b/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb @@ -702,12 +702,18 @@ " session=get_pyvo_auth())\n", "\n", "spherePoint = geom.SpherePoint(target_ra*geom.degrees, target_dec*geom.degrees)\n", - "Radius = 0.01 * u.deg\n", + "Radius = 0.01 #* u.deg\n", + "\n", + "#sq4.circle = (spherePoint.getRa().asDegrees() * u.deg,\n", + "# spherePoint.getDec().asDegrees() * u.deg,\n", + "# Radius)\n", "\n", - "sq4.circle = (spherePoint.getRa().asDegrees() * u.deg,\n", - " spherePoint.getDec().asDegrees() * u.deg,\n", + "# units are also not needed here, seems to default to degrees\n", + "sq4.circle = (target_ra,# * u.deg,\n", + " target_dec,# * u.deg,\n", " Radius)\n", "\n", + "\n", "cutout_bytes = sq4.execute_stream().read()\n", "sq4.raise_if_error()\n" ] @@ -727,8 +733,8 @@ "metadata": {}, "outputs": [], "source": [ - "mem = MemFileManager(len(cutout_bytes))\n", - "mem.setData(cutout_bytes, len(cutout_bytes))\n" + "#mem = MemFileManager(len(cutout_bytes))\n", + "#mem.setData(cutout_bytes, len(cutout_bytes))\n" ] }, { @@ -764,11 +770,11 @@ "metadata": {}, "outputs": [], "source": [ - "hdul = fits.open(io.BytesIO(data))\n", - "hdul.info()\n", + "#hdul = fits.open(io.BytesIO(data))\n", + "#hdul.info()\n", "\n", - "image_hdu = hdul[1]\n", - "image_data = image_hdu.data\n" + "#image_hdu = hdul[1]\n", + "#image_data = image_hdu.data\n" ] }, { @@ -786,7 +792,7 @@ "metadata": {}, "outputs": [], "source": [ - "image = afwImage.ImageF(image_data.astype(\"float32\"))\n" + "image = afwImage.ImageF(mem) #image_data.astype(\"float32\"))\n" ] }, { From ec33e5f86486e00412ce042b0266019798f152c7 Mon Sep 17 00:00:00 2001 From: christinawilliams Date: Mon, 12 Jan 2026 20:19:47 +0000 Subject: [PATCH 02/14] cutout updates --- .../103_4_Small_Image_Cutout.ipynb | 263 +++++++++++------- 1 file changed, 162 insertions(+), 101 deletions(-) diff --git a/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb b/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb index c56c06f..aae5e99 100644 --- a/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb +++ b/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb @@ -101,7 +101,7 @@ "\n", "import lsst.afw.display as afwDisplay\n", "import lsst.afw.image as afwImage\n", - "from lsst.afw.image import ExposureF\n", + "from lsst.afw.image import ExposureF, ImageF, MaskedImageF\n", "from lsst.afw.fits import MemFileManager\n", "\n", "\n", @@ -328,9 +328,9 @@ "id": "d945e191-7ee4-458a-bb0f-fb00cd219e30", "metadata": {}, "source": [ - "Lastly, call the Rubin Image Cutout Service. This notebook demonstrates two types of cutout services: `cutout-sync` which, by default, returns just the image extension of the LSST imaging; `cutout-sync-exposure`, which returns the full set of metadata and image extensions that are contained in the `ExposureF` data type. This section will demonstrate the use of `cutout-sync-exposure` and Section 4 below will demonstrate the other. \n", + "Lastly, call the Rubin Image Cutout Service. This notebook demonstrates three types of cutout services: `cutout-sync` which, by default, returns just the image extension of the LSST imaging; `cutout-sync-exposure`, which returns the full set of metadata and image extensions that are contained in the `ExposureF` data type, and `cutout-sync-mask` which returns the mask extension. This section will demonstrate the use of the default cutout service, `cutout-sync`, and Section 4 below will demonstrate the other two. \n", "\n", - "To use the cutout service in this example, the IVOA procedure `cutout-sync-exposure` is called using `get_adhocservice_by_id`. It is done by feeding the data link created above (called `dl_result`) to `from_resource`. Since the Rubin DP1 imaging is proprietary it is necessary to again provide the authorization for the current RSP session. Do this using the `get_pyvo_auth` function." + "To use the cutout service in this example, the IVOA procedure `cutout-sync` is called using `get_adhocservice_by_id`. It is done by feeding the data link created above (called `dl_result`) to `from_resource`. Since the Rubin DP1 imaging is proprietary it is necessary to again provide the authorization for the current RSP session. Do this using the `get_pyvo_auth` function." ] }, { @@ -354,7 +354,9 @@ "\n", "### 3.1. Define cutout center and edge\n", "\n", - "Only two shape definitions are supported: a circle function, and a polygon function can be used to define the cutout dimensions. These shape definitions do not produce circle or polygon cutouts, but rather are methods for defining the edges of cutouts with 4 sides. In the case of circle, the resulting cutout is always a square, with edge size that is the same as the circle diameter. In the case of a polygon, either a square or a rectangular cutout will result, depending on whether the length and width edge dimensions are different values. Only cutouts with 4 corners and 90 degree angles are supported. " + "Only two shape definitions are supported: a circle function, and a polygon function can be used to define the cutout dimensions. These shape definitions do not produce circle or polygon cutouts, but rather are methods for defining the edges of cutouts with 4 sides. In the case of circle, the resulting cutout is always a square, with edge size that is the same as the circle diameter. In the case of a polygon, either a square or a rectangular cutout will result, depending on whether the length and width edge dimensions are different values. Only cutouts with 4 corners and 90 degree angles are supported. \n", + "\n", + "`.circle` defaults to assuming the units are degrees; this notebook demonstrates its use when specifying the units with astropy." ] }, { @@ -364,11 +366,12 @@ "metadata": {}, "outputs": [], "source": [ - "spherePoint = geom.SpherePoint(target_ra*geom.degrees, target_dec*geom.degrees)\n", + "cutout_ra = target_ra * u.deg\n", + "cutout_dec = target_dec * u.deg\n", + "\n", "Radius = 0.01 * u.deg\n", - "sq.circle = (spherePoint.getRa().asDegrees() * u.deg,\n", - " spherePoint.getDec().asDegrees() * u.deg,\n", - " Radius)" + "\n", + "sq.circle = (cutout_ra, cutout_dec, Radius)" ] }, { @@ -390,9 +393,10 @@ "source": [ "cutout_bytes = sq.execute_stream().read()\n", "sq.raise_if_error()\n", + "\n", "mem = MemFileManager(len(cutout_bytes))\n", "mem.setData(cutout_bytes, len(cutout_bytes))\n", - "exposure = ExposureF(mem)\n" + "image = ImageF(mem)" ] }, { @@ -412,7 +416,7 @@ "source": [ "display = afwDisplay.Display()\n", "display.scale('asinh', 'zscale')\n", - "display.image(exposure.image)\n", + "display.image(image)\n", "plt.show()" ] }, @@ -450,10 +454,10 @@ "# with open(sodaCutout, 'bw') as f:\n", "# f.write(sq.execute_stream().read())\n", "\n", - "# cutout = ExposureF(sodaCutout)\n", + "# cutout = ImageF(sodaCutout)\n", "# display = afwDisplay.Display()\n", "# display.scale('asinh', 'zscale')\n", - "# display.image(cutout.image)\n", + "# display.image(cutout)\n", "# plt.show()" ] }, @@ -463,23 +467,7 @@ "metadata": {}, "source": [ "Future planned options for the Rubin cutout service, including the potential to retrieve other image formats such as jpeg, are listed at the Rubin Science Platform image cutout implementation strategy document.\n", - "\n", - "**Note:** `ExposureF` contains multiple Header-Data Units (HDUs) with extensive exposure metadata. To reduce file size, one option is to save only the image, mask, and variance planes, along with the WCS recorded in the Primary HDU. This can be done by writing `exposure.maskedImage`-a three-plane object containing the image, mask, and variance-into a FITS file using `writeFitsImage`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "de03af16-26d1-4268-998b-43f33bb35a67", - "metadata": {}, - "outputs": [], - "source": [ - "# fits.info(sodaCutout)\n", - "\n", - "# sodaCutout_small = os.path.join(tempdir, 'cutout-circle_small.fits')\n", - "# afwDisplay.writeFitsImage(sodaCutout_small,\n", - "# exposure.maskedImage,\n", - "# wcs=exposure.wcs)" + "\n" ] }, { @@ -506,26 +494,26 @@ "outputs": [], "source": [ "sqp = SodaQuery.from_resource(dl_result,\n", - " dl_result.get_adhocservice_by_id(\"cutout-sync-exposure\"),\n", + " dl_result.get_adhocservice_by_id(\"cutout-sync\"),\n", " session=get_pyvo_auth())\n", "\n", "ra_edge = 0.02 * u.deg\n", "de_edge = 0.005 * u.deg\n", "\n", - "sqp.polygon = (spherePoint.getRa().asDegrees() * u.deg - ra_edge,\n", - " spherePoint.getDec().asDegrees() * u.deg - de_edge,\n", - " spherePoint.getRa().asDegrees() * u.deg - ra_edge,\n", - " spherePoint.getDec().asDegrees() * u.deg + de_edge,\n", - " spherePoint.getRa().asDegrees() * u.deg + ra_edge,\n", - " spherePoint.getDec().asDegrees() * u.deg + de_edge,\n", - " spherePoint.getRa().asDegrees() * u.deg + ra_edge,\n", - " spherePoint.getDec().asDegrees() * u.deg - de_edge)\n", + "sqp.polygon = (cutout_ra - ra_edge,\n", + " cutout_dec - de_edge,\n", + " cutout_ra - ra_edge,\n", + " cutout_dec + de_edge,\n", + " cutout_ra + ra_edge,\n", + " cutout_dec + de_edge,\n", + " cutout_ra + ra_edge,\n", + " cutout_dec - de_edge)\n", "\n", "cutout_bytes = sqp.execute_stream().read()\n", "sqp.raise_if_error()\n", "mem = MemFileManager(len(cutout_bytes))\n", "mem.setData(cutout_bytes, len(cutout_bytes))\n", - "polygon = ExposureF(mem)" + "polygon = ImageF(mem)" ] }, { @@ -537,7 +525,7 @@ "source": [ "display = afwDisplay.Display()\n", "display.scale('asinh', 'zscale')\n", - "display.mtv(polygon.image)\n", + "display.mtv(polygon)\n", "plt.show()" ] }, @@ -569,24 +557,24 @@ "outputs": [], "source": [ "sq2 = SodaQuery.from_resource(dl_result,\n", - " dl_result.get_adhocservice_by_id(\"cutout-sync-exposure\"),\n", + " dl_result.get_adhocservice_by_id(\"cutout-sync\"),\n", " session=get_pyvo_auth())\n", "\n", "edge1 = Radius\n", "edge2 = Radius\n", "\n", - "sq2.polygon = (spherePoint.getRa().asDegrees() * u.deg - edge1,\n", - " spherePoint.getDec().asDegrees() * u.deg - edge2,\n", - " spherePoint.getRa().asDegrees() * u.deg - edge1,\n", - " spherePoint.getDec().asDegrees() * u.deg + edge2,\n", - " spherePoint.getRa().asDegrees() * u.deg + edge1,\n", - " spherePoint.getDec().asDegrees() * u.deg + edge2)\n", + "sq2.polygon = (cutout_ra - edge1,\n", + " cutout_dec - edge2,\n", + " cutout_ra - edge1,\n", + " cutout_dec + edge2,\n", + " cutout_ra + edge1,\n", + " cutout_dec + edge2)\n", "\n", "cutout_bytes = sq2.execute_stream().read()\n", "sq2.raise_if_error()\n", "mem = MemFileManager(len(cutout_bytes))\n", "mem.setData(cutout_bytes, len(cutout_bytes))\n", - "exposure2 = ExposureF(mem)" + "polygon2 = ImageF(mem)" ] }, { @@ -604,27 +592,28 @@ "metadata": {}, "outputs": [], "source": [ + "spherePoint = geom.SpherePoint(target_ra*geom.degrees, target_dec*geom.degrees)\n", "a = Angle(spherePoint.getDec().asDegrees(), u.deg)\n", "cosd = np.cos(a.radian)\n", "\n", "sq3 = SodaQuery.from_resource(dl_result,\n", - " dl_result.get_adhocservice_by_id(\"cutout-sync-exposure\"),\n", + " dl_result.get_adhocservice_by_id(\"cutout-sync\"),\n", " session=get_pyvo_auth())\n", "\n", - "sq3.polygon = (spherePoint.getRa().asDegrees() * u.deg - edge1/cosd,\n", - " spherePoint.getDec().asDegrees() * u.deg - edge2,\n", - " spherePoint.getRa().asDegrees() * u.deg - edge1/cosd,\n", - " spherePoint.getDec().asDegrees() * u.deg + edge2,\n", - " spherePoint.getRa().asDegrees() * u.deg + edge1/cosd,\n", - " spherePoint.getDec().asDegrees() * u.deg + edge2,\n", - " spherePoint.getRa().asDegrees() * u.deg + edge1/cosd,\n", - " spherePoint.getDec().asDegrees() * u.deg - edge2)\n", + "sq3.polygon = (cutout_ra - edge1/cosd,\n", + " cutout_dec - edge2,\n", + " cutout_ra - edge1/cosd,\n", + " cutout_dec + edge2,\n", + " cutout_ra + edge1/cosd,\n", + " cutout_dec + edge2,\n", + " cutout_ra + edge1/cosd,\n", + " cutout_dec - edge2)\n", "\n", "cutout_bytes = sq3.execute_stream().read()\n", "sq3.raise_if_error()\n", "mem = MemFileManager(len(cutout_bytes))\n", "mem.setData(cutout_bytes, len(cutout_bytes))\n", - "exposure3 = ExposureF(mem)" + "polygon3 = ImageF(mem)" ] }, { @@ -647,17 +636,17 @@ "plt.sca(ax[0])\n", "display1 = afwDisplay.Display(frame=fig)\n", "display1.scale('linear', 'zscale')\n", - "display1.mtv(exposure.image, title='Cutout defined with circle')\n", + "display1.mtv(image, title='Cutout defined with circle')\n", "\n", "plt.sca(ax[1])\n", "display2 = afwDisplay.Display(frame=fig)\n", "display2.scale('linear', 'zscale')\n", - "display2.mtv(exposure2.image, title='Cutout defined with polygon')\n", + "display2.mtv(polygon2, title='Cutout defined with polygon')\n", "\n", "plt.sca(ax[2])\n", "display3 = afwDisplay.Display(frame=fig)\n", "display3.scale('linear', 'zscale')\n", - "display3.mtv(exposure3.image, title='Polygon including cos(dec)')\n", + "display3.mtv(polygon3, title='Polygon including cos(dec)')\n", "plt.tight_layout()\n", "plt.show()" ] @@ -683,11 +672,20 @@ "id": "99e75a7a-348e-409e-88f6-871b68a4e9dc", "metadata": {}, "source": [ - "## 4. Single extension image cutouts\n", + "## 4. Other image cutout types\n", "\n", - "As mentioned in Section 3, there are three types of cutout services: `cutout-sync-exposure` to return an `ExposureF` type image with all LSST image extensions (demonstrated above); `cutout-sync` which returns just the image extension. The latter will be demonstrated below.\n", + "As mentioned in Section 3, there are three types of cutout services. Demonstrated above is the default `cutout-sync` which returns just the image extension. The cells below demonstrate both the `cutout-sync-exposure` service that returns an `ExposureF` type image with all LSST image extensions (Section 4.1) and the `cutout-sync-mask` service that returns an `MaskedImageF` type containing the LSST image mask (Section 4.2). \n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "a9c8f2cf-f3ca-49af-979e-ee6e8195e034", + "metadata": {}, + "source": [ + "### 4.1 ExposureF cutouts\n", "\n", - "First, reuse the data link `dl_result` that was defined in Section 3 to define a new cutout, this time using `cutout-sync`. Call this soda query `sq4` to differentiate from the earlier ones. Define the cutout as a square subtended by a circle of radius 0.01 degrees, as done in Section 3.\n" + "First, reuse the data link `dl_result` that was defined in Section 3 to define a new cutout, this time using `cutout-sync-exposure` service. Call this soda query `sqE` to differentiate from the earlier ones. Define the cutout as a square subtended by a circle of radius 0.01 degrees, as done in Section 3.\n" ] }, { @@ -697,25 +695,16 @@ "metadata": {}, "outputs": [], "source": [ - "sq4 = SodaQuery.from_resource(dl_result,\n", - " dl_result.get_adhocservice_by_id(\"cutout-sync\"),\n", - " session=get_pyvo_auth())\n", - "\n", - "spherePoint = geom.SpherePoint(target_ra*geom.degrees, target_dec*geom.degrees)\n", - "Radius = 0.01 #* u.deg\n", - "\n", - "#sq4.circle = (spherePoint.getRa().asDegrees() * u.deg,\n", - "# spherePoint.getDec().asDegrees() * u.deg,\n", - "# Radius)\n", + "del mem\n", "\n", - "# units are also not needed here, seems to default to degrees\n", - "sq4.circle = (target_ra,# * u.deg,\n", - " target_dec,# * u.deg,\n", - " Radius)\n", + "sqE = SodaQuery.from_resource(dl_result,\n", + " dl_result.get_adhocservice_by_id(\"cutout-sync-exposure\"),\n", + " session=get_pyvo_auth())\n", "\n", + "sqE.circle = (cutout_ra, cutout_dec, Radius)\n", "\n", - "cutout_bytes = sq4.execute_stream().read()\n", - "sq4.raise_if_error()\n" + "cutout_bytes = sqE.execute_stream().read()\n", + "sqE.raise_if_error()\n" ] }, { @@ -733,86 +722,158 @@ "metadata": {}, "outputs": [], "source": [ - "#mem = MemFileManager(len(cutout_bytes))\n", - "#mem.setData(cutout_bytes, len(cutout_bytes))\n" + "mem = MemFileManager(len(cutout_bytes))\n", + "mem.setData(cutout_bytes, len(cutout_bytes))\n" + ] + }, + { + "cell_type": "markdown", + "id": "c0eea8e5-ae86-456d-9d67-798557a4a707", + "metadata": {}, + "source": [ + "To enable image display, first store the bytes from `mem` as an LSST `ExposureF` object. The image extension can then be accessed using the `.image` method." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "78e1c658-916c-4a73-8c0b-a50d281f4764", + "metadata": {}, + "outputs": [], + "source": [ + "exposure = ExposureF(mem)\n" ] }, { "cell_type": "markdown", - "id": "2ae72a88-8002-46b5-8eee-164a2c903314", + "id": "6a19e7cd-4096-44b9-832f-baa6b6c40482", "metadata": {}, "source": [ - "Use the `getData` method from the `MemFileManager` class to return and store the bytes associated with the cutout. " + "Display the image cutout." ] }, { "cell_type": "code", "execution_count": null, - "id": "ed3f7908-a256-42f5-939f-61f38645c7ca", + "id": "1aa9009a-b493-41ea-bc3c-e0c79adef913", "metadata": {}, "outputs": [], "source": [ - "data = mem.getData()" + "display = afwDisplay.Display()\n", + "display.scale('asinh', 'zscale')\n", + "display.image(exposure.image)\n", + "plt.show()" ] }, { "cell_type": "markdown", - "id": "441a49fb-42be-4f37-853e-141419f1da14", + "id": "ceec7aac-0d64-4397-99df-4450e0098f91", "metadata": {}, "source": [ - "Use the astropy.io fits package to access the bytes and store in an HDUList object. Then, the image extension `image_hdu`, and pixel values `image_data` (a numpy array) can be accessed similar to opening a fits file. " + "Option to save the entire ExposureF to a fitsfile. " ] }, { "cell_type": "code", "execution_count": null, - "id": "d23a0397-6500-4e36-b956-7917ed6a7173", + "id": "68c12665-780f-4c47-a16f-e5fd81bc5b77", "metadata": {}, "outputs": [], "source": [ - "#hdul = fits.open(io.BytesIO(data))\n", - "#hdul.info()\n", + "# tempdir = os.path.join(os.getenv('HOME'), 'cutouts_temp/')\n", + "# if not os.path.exists(tempdir):\n", + "# os.makedirs(tempdir)\n", + "# print('Created ', tempdir)\n", + "# else:\n", + "# print('Directory already existed: ', tempdir)\n", "\n", - "#image_hdu = hdul[1]\n", - "#image_data = image_hdu.data\n" + "# sodaCutout = os.path.join(tempdir, 'cutout-circle.fits')\n", + "# with open(sodaCutout, 'bw') as f:\n", + "# f.write(sq.execute_stream().read())" ] }, { "cell_type": "markdown", - "id": "c0eea8e5-ae86-456d-9d67-798557a4a707", + "id": "1d11f7ee-260e-4f52-87fb-e55db25d5d53", "metadata": {}, "source": [ - "To enable image display, first store `image_data` as an LSST `ImageF` object." + "**Note:** `ExposureF` contains multiple Header-Data Units (HDUs) with extensive exposure metadata. To reduce file size, one option is to save only the image, mask, and variance planes, along with the WCS recorded in the Primary HDU. This can be done by writing `exposure.maskedImage`-a three-plane object containing the image, mask, and variance-into a FITS file using `writeFitsImage`." ] }, { "cell_type": "code", "execution_count": null, - "id": "78e1c658-916c-4a73-8c0b-a50d281f4764", + "id": "7b0a245e-3fce-4b35-9ed8-69763b7f1dac", "metadata": {}, "outputs": [], "source": [ - "image = afwImage.ImageF(mem) #image_data.astype(\"float32\"))\n" + "# fits.info(sodaCutout)\n", + "\n", + "# sodaCutout_small = os.path.join(tempdir, 'cutout-circle_small.fits')\n", + "# afwDisplay.writeFitsImage(sodaCutout_small,\n", + "# exposure.maskedImage,\n", + "# wcs=exposure.wcs)" ] }, { "cell_type": "markdown", - "id": "6a19e7cd-4096-44b9-832f-baa6b6c40482", + "id": "1fcde65c-8ba1-4ffc-9501-08c01e331e81", "metadata": {}, "source": [ - "Display the image cutout." + "### 4.1 Mask cutouts\n", + "\n", + "Again, reuse the data link `dl_result` that was defined in Section 3 to define a new cutout, this time using `cutout-sync-maskedimage` service. The returned Call this soda query `sqM` to differentiate from the earlier ones. Define the cutout as a square subtended by a circle of radius 0.01 degrees, as done in Section 3.\n" ] }, { "cell_type": "code", "execution_count": null, - "id": "1aa9009a-b493-41ea-bc3c-e0c79adef913", + "id": "0d86fbef-65fe-44d2-bed4-4b6b4ad3a8d9", "metadata": {}, "outputs": [], "source": [ + "#del mem\n", + "\n", + "sqM = SodaQuery.from_resource(dl_result,\n", + " dl_result.get_adhocservice_by_id(\"cutout-sync-maskedimage\"),\n", + " session=get_pyvo_auth())\n", + "\n", + "sqM.circle = (cutout_ra, cutout_dec, Radius)\n", + "\n", + "cutout_bytes = sqM.execute_stream().read()\n", + "sqM.raise_if_error()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6e9b2366-7051-4766-83a9-2e8e6a6c6b4b", + "metadata": {}, + "outputs": [], + "source": [ + "mem = MemFileManager(len(cutout_bytes))\n", + "mem.setData(cutout_bytes, len(cutout_bytes))\n" + ] + }, + { + "cell_type": "markdown", + "id": "ee886dbe-b264-400d-a7c4-68fa659c739e", + "metadata": {}, + "source": [ + "To enable image display, first store the bytes from `mem` as an LSST `MaskedImageF` object. In addition to the mask, it also contains the image and variance extensions, which can then be accessed using the `.image` or `.variance` attribute." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "178a5016-7490-4410-bda6-8e1885cc03a6", + "metadata": {}, + "outputs": [], + "source": [ + "mask = MaskedImageF(mem)\n", "display = afwDisplay.Display()\n", "display.scale('asinh', 'zscale')\n", - "display.image(image)\n", + "display.image(mask)\n", "plt.show()" ] }, From 190d06e16106a2f867c526c622a0c3a747e42287 Mon Sep 17 00:00:00 2001 From: christinawilliams Date: Mon, 12 Jan 2026 20:28:38 +0000 Subject: [PATCH 03/14] cutout updates --- .../103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb b/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb index aae5e99..2941f9e 100644 --- a/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb +++ b/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb @@ -481,7 +481,7 @@ "\n", "POLYGON=12 34 14 34 14 36 12 36\n", "\n", - "Since the center of the cutout is already defined in RA and Dec in the cells above (`spherePoint`), this example will define each x,y set as RA+/-edge and Dec+/-edge.\n", + "Since the center of the cutout is already defined in unit degrees in the cells above, this example will define each x,y set as RA+/-edge and Dec+/-edge.\n", "\n", "> **Warning:** Visit images are rotated, and although it is the \"Declination edge\" that is defined to be smaller, that corresponds to the x-axis when the cutout is displayed below, due to image rotation." ] From 314d35b1db24182e79f272879d8648e4f0225a12 Mon Sep 17 00:00:00 2001 From: christinawilliams Date: Tue, 13 Jan 2026 00:23:33 +0000 Subject: [PATCH 04/14] updating --- .../103_4_Small_Image_Cutout.ipynb | 33 +++++++++++++++++-- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb b/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb index 2941f9e..b75b942 100644 --- a/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb +++ b/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb @@ -341,7 +341,7 @@ "outputs": [], "source": [ "sq = SodaQuery.from_resource(dl_result,\n", - " dl_result.get_adhocservice_by_id(\"cutout-sync-exposure\"),\n", + " dl_result.get_adhocservice_by_id(\"cutout-sync\"),\n", " session=get_pyvo_auth())" ] }, @@ -381,7 +381,27 @@ "source": [ "### 3.2. Retrieve the cutout\n", "\n", - "The recommended method is to recieve the cutout into memory in the `ExposureF` format." + "The recommended method is to receive the cutout into memory in the `ImageF` format." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6cd941c5-7e03-4c1b-a327-03f5ebc578f1", + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "cutout_bytes = sq.execute_stream().read()\n", + "sq.raise_if_error()\n", + "\n", + "hdul = fits.open(io.BytesIO(cutout_bytes))\n", + "hdul.info()\n", + "hdul[1].header\n", + "#image_hdu = hdul[1]\n", + "#print(hdul[0].data)\n", + "#image_data = image_hdu.data\n", + "#print(image_hdu.data)" ] }, { @@ -391,12 +411,19 @@ "metadata": {}, "outputs": [], "source": [ + "from lsst.afw.image import DecoratedImageF\n", + "from lsst.afw.geom import SkyWcs\n", + "#from lsst.daf.persistence import MemFileManager\n", + "\n", + "\n", "cutout_bytes = sq.execute_stream().read()\n", "sq.raise_if_error()\n", "\n", "mem = MemFileManager(len(cutout_bytes))\n", "mem.setData(cutout_bytes, len(cutout_bytes))\n", - "image = ImageF(mem)" + "image = ExposureF.readFits(mem)\n", + "\n", + "xx = image.getMetadata()" ] }, { From 77607f64745d417e078dce90e58f4924c28ed4de Mon Sep 17 00:00:00 2001 From: christinawilliams Date: Tue, 13 Jan 2026 19:14:51 +0000 Subject: [PATCH 05/14] updating --- .../103_4_Small_Image_Cutout.ipynb | 99 +++++++++++++++---- 1 file changed, 81 insertions(+), 18 deletions(-) diff --git a/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb b/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb index b75b942..e741a2c 100644 --- a/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb +++ b/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb @@ -379,9 +379,10 @@ "id": "30640af4-a75c-4132-8f2e-692fcf9694eb", "metadata": {}, "source": [ - "### 3.2. Retrieve the cutout\n", + "### 3.2. Retrieve the cutout with astropy\n", "\n", - "The recommended method is to receive the cutout into memory in the `ImageF` format." + "The format of the default cutout is a 2-extension fits: the primary HDU (extension 0) has the headers describing the data set, and the secondary HDU (extension 1) has only the header that describes the pixel data ctaonine\n", + "\n" ] }, { @@ -391,39 +392,101 @@ "metadata": {}, "outputs": [], "source": [ - "\n", "cutout_bytes = sq.execute_stream().read()\n", "sq.raise_if_error()\n", "\n", - "hdul = fits.open(io.BytesIO(cutout_bytes))\n", + "hdul = fits.open(io.BytesIO(cutout_bytes))\n" + ] + }, + { + "cell_type": "markdown", + "id": "87c5e852-f42c-403f-b357-130a69b2b2e5", + "metadata": {}, + "source": [ + "Explore the extensions" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "00b1efae-7b59-422b-9708-1036120c4d8d", + "metadata": {}, + "outputs": [], + "source": [ "hdul.info()\n", - "hdul[1].header\n", - "#image_hdu = hdul[1]\n", - "#print(hdul[0].data)\n", + "primary_hdu = hdul[0]\n", + "image_hdu = hdul[1]\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "da4cc3eb-16e3-44c7-9cf7-0d8214bc0671", + "metadata": {}, + "outputs": [], + "source": [ + "# option to print primary HDU header (very long). data is empty\n", + "#print(hdul[0].header)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "27361386-c8c3-4205-b112-6058d96d3377", + "metadata": {}, + "outputs": [], + "source": [ "#image_data = image_hdu.data\n", - "#print(image_hdu.data)" + "#print(image_hdu.data)\n", + "\n", + "print(image_hdu.header)" + ] + }, + { + "cell_type": "markdown", + "id": "88be8f44-3226-4fda-97eb-ea0b272a88ec", + "metadata": {}, + "source": [ + "Demonstrate plot the cutout using astropy with WCS info included." ] }, { "cell_type": "code", "execution_count": null, - "id": "2e7173c4-5030-4420-b215-e275534cb083", + "id": "0b755176-ce5f-4238-9cd9-4798a0dfe133", "metadata": {}, "outputs": [], "source": [ - "from lsst.afw.image import DecoratedImageF\n", - "from lsst.afw.geom import SkyWcs\n", - "#from lsst.daf.persistence import MemFileManager\n", + "import matplotlib.pyplot as plt\n", + "from astropy.wcs import WCS\n", "\n", + "wcs = WCS(image_hdu.header)\n", + "fig = plt.figure(figsize=(8, 6))\n", + "ax = fig.add_subplot(111, projection=wcs)\n", "\n", - "cutout_bytes = sq.execute_stream().read()\n", - "sq.raise_if_error()\n", + "ax.imshow(image_hdu.data, cmap='gray', norm='asinh', origin='lower')\n" + ] + }, + { + "cell_type": "markdown", + "id": "9be31876-1afa-4610-aaec-cc3497ad6930", + "metadata": {}, + "source": [ + "### 3.3 Retrieve the cutout with LSST\n", "\n", + "The cutout can be read into memory in the LSST pipelines `ImageF` format, but does not include the WCS information." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2e7173c4-5030-4420-b215-e275534cb083", + "metadata": {}, + "outputs": [], + "source": [ "mem = MemFileManager(len(cutout_bytes))\n", "mem.setData(cutout_bytes, len(cutout_bytes))\n", - "image = ExposureF.readFits(mem)\n", - "\n", - "xx = image.getMetadata()" + "image = ImageF(mem)" ] }, { @@ -431,7 +494,7 @@ "id": "324be87a-337b-4db7-b57d-842f14614613", "metadata": {}, "source": [ - "Display the image extension of the `ExposureF` cutout." + "Display the `ImageF` cutout." ] }, { From 3da9d2a52ea0952ccb3cc5cc55a626db3a36a946 Mon Sep 17 00:00:00 2001 From: christinawilliams Date: Tue, 13 Jan 2026 19:56:13 +0000 Subject: [PATCH 06/14] updating --- .../103_4_Small_Image_Cutout.ipynb | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb b/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb index e741a2c..e879f80 100644 --- a/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb +++ b/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb @@ -436,10 +436,11 @@ "metadata": {}, "outputs": [], "source": [ + "# option to print the \n", "#image_data = image_hdu.data\n", "#print(image_hdu.data)\n", "\n", - "print(image_hdu.header)" + "#print(image_hdu.header)" ] }, { @@ -461,12 +462,22 @@ "from astropy.wcs import WCS\n", "\n", "wcs = WCS(image_hdu.header)\n", - "fig = plt.figure(figsize=(8, 6))\n", - "ax = fig.add_subplot(111, projection=wcs)\n", + "fig = plt.figure(figsize=(6, 6))\n", "\n", + "ax = fig.add_subplot(111, projection=wcs)\n", "ax.imshow(image_hdu.data, cmap='gray', norm='asinh', origin='lower')\n" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "28eca147-61db-48ce-ad94-9066567246af", + "metadata": {}, + "outputs": [], + "source": [ + "> **Figure 1:** The cutout image, displayed in sky coordinateas using astropy in grayscale with a scale bar at right.\n" + ] + }, { "cell_type": "markdown", "id": "9be31876-1afa-4610-aaec-cc3497ad6930", @@ -515,7 +526,7 @@ "id": "458a4d25-ca95-4f92-b76e-986b7a03b320", "metadata": {}, "source": [ - "> **Figure 1:** The cutout image, displayed in grayscale with a scale bar at right.\n", + "> **Figure 2:** The cutout image, displayed in pixel coordinates using LSST pipeline tools in grayscale with a scale bar at right.\n", "\n", "#### 3.2.1. Option to save cutout to disk\n", "\n", @@ -523,7 +534,7 @@ "\n", "The cutouts saved to disk with the following commands will be stored in a temporary folder in the user's home directory.\n", "\n", - "After saving the cutout as a FITS file, read it in as an `ExposureF` and display it." + "After saving the cutout as a FITS file, read it in as an `ImageF` and display it." ] }, { From 229ecc84944ae29d1aff8832996b8f882d3eb413 Mon Sep 17 00:00:00 2001 From: christinawilliams Date: Tue, 13 Jan 2026 20:05:36 +0000 Subject: [PATCH 07/14] updating --- .../103_4_Small_Image_Cutout.ipynb | 39 +++++++++++-------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb b/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb index e879f80..7b41e8c 100644 --- a/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb +++ b/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb @@ -104,7 +104,6 @@ "from lsst.afw.image import ExposureF, ImageF, MaskedImageF\n", "from lsst.afw.fits import MemFileManager\n", "\n", - "\n", "from lsst.rsp.utils import get_pyvo_auth\n", "from lsst.rsp.service import get_siav2_service\n", "\n", @@ -115,7 +114,7 @@ "from astropy import units as u\n", "from astropy.coordinates import Angle\n", "from astropy.time import Time\n", - "\n", + "from astropy.wcs import WCS\n", "from astropy.io import fits\n", "import io\n" ] @@ -381,7 +380,7 @@ "source": [ "### 3.2. Retrieve the cutout with astropy\n", "\n", - "The format of the default cutout is a 2-extension fits: the primary HDU (extension 0) has the headers describing the data set, and the secondary HDU (extension 1) has only the header that describes the pixel data ctaonine\n", + "The format of the default cutout is a 2-extension fits: the primary (extension 0) header data unit (HDU) has the header describing the data set, and the secondary HDU (extension 1) has only the header that describes the pixel data (i.e. science image).\n", "\n" ] }, @@ -403,7 +402,7 @@ "id": "87c5e852-f42c-403f-b357-130a69b2b2e5", "metadata": {}, "source": [ - "Explore the extensions" + "Explore the format of the returned HDU extensions. There are two HDUs, where the second one labeled Image (extension 1) contains the image pixels and WCS header." ] }, { @@ -436,7 +435,7 @@ "metadata": {}, "outputs": [], "source": [ - "# option to print the \n", + "# option to print the header for the image extension\n", "#image_data = image_hdu.data\n", "#print(image_hdu.data)\n", "\n", @@ -458,9 +457,6 @@ "metadata": {}, "outputs": [], "source": [ - "import matplotlib.pyplot as plt\n", - "from astropy.wcs import WCS\n", - "\n", "wcs = WCS(image_hdu.header)\n", "fig = plt.figure(figsize=(6, 6))\n", "\n", @@ -469,13 +465,19 @@ ] }, { - "cell_type": "code", - "execution_count": null, - "id": "28eca147-61db-48ce-ad94-9066567246af", - "metadata": {}, - "outputs": [], + "cell_type": "markdown", + "id": "ca5f197f-24a9-4440-8c8e-9f3398ebea26", + "metadata": { + "execution": { + "iopub.execute_input": "2026-01-13T19:56:44.392687Z", + "iopub.status.busy": "2026-01-13T19:56:44.392329Z", + "iopub.status.idle": "2026-01-13T19:56:44.396918Z", + "shell.execute_reply": "2026-01-13T19:56:44.395598Z", + "shell.execute_reply.started": "2026-01-13T19:56:44.392670Z" + } + }, "source": [ - "> **Figure 1:** The cutout image, displayed in sky coordinateas using astropy in grayscale with a scale bar at right.\n" + "> **Figure 1:** The cutout image, displayed in sky coordinateas using astropy.\n" ] }, { @@ -635,7 +637,7 @@ "id": "c83e5413-2edf-41fd-8542-b622ba8324b0", "metadata": {}, "source": [ - "> **Figure 2:** A rectangular polygon cutout from a rotated `visit_image`." + "> **Figure 3:** A rectangular polygon cutout from a rotated `visit_image`." ] }, { @@ -757,7 +759,7 @@ "id": "dfc8a459-e168-40ab-81a5-1148e7536455", "metadata": {}, "source": [ - "> **Figure 3:** A comparison of a cutout generated with the circle function (same as Figure 1; left panel) with a cutout defined using the `polygon` functionality defined using the same edge size (middle panel). The right panel uses `polygon` but accounts for the $cos({\\rm dec})$ term, to replicate the same cutout that was made using circle." + "> **Figure 4:** A comparison of a cutout generated with the circle function (same as Figure 1; left panel) with a cutout defined using the `polygon` functionality defined using the same edge size (middle panel). The right panel uses `polygon` but accounts for the $cos({\\rm dec})$ term, to replicate the same cutout that was made using circle." ] }, { @@ -871,6 +873,9 @@ "id": "ceec7aac-0d64-4397-99df-4450e0098f91", "metadata": {}, "source": [ + "> **Figure 5:** The cutout image retrieved in ExposureF format, displayed in pixel coordinates using LSST pipeline tools in grayscale with a scale bar at right.\n", + "\n", + "\n", "Option to save the entire ExposureF to a fitsfile. " ] }, @@ -988,6 +993,8 @@ "id": "acbe9638-e7b7-4229-8301-3f57eb0b0c5b", "metadata": {}, "source": [ + "> **Figure 6:** The cutout image retrieved in MaskedImageF format, displayed in pixel coordinates using LSST pipeline tools in grayscale with a scale bar at right. Mask is plotted on top of the image pixels in colors. \n", + "\n", "## 5. Exercise for the learner\n", "\n", "Reproduce the cutout below, whose center is (ra, dec) = 59.1, -48.8 with 0.06 degrees on a side.\n", From a48384e322a748305e4a7136d5d7f234f9b4b1f1 Mon Sep 17 00:00:00 2001 From: christinawilliams Date: Tue, 13 Jan 2026 20:13:22 +0000 Subject: [PATCH 08/14] updating --- .../103_4_Small_Image_Cutout.ipynb | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb b/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb index 7b41e8c..a90dae9 100644 --- a/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb +++ b/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb @@ -447,7 +447,7 @@ "id": "88be8f44-3226-4fda-97eb-ea0b272a88ec", "metadata": {}, "source": [ - "Demonstrate plot the cutout using astropy with WCS info included." + "Plot the cutout using astropy tools, with WCS info from the image header used to plot in sky coordinates." ] }, { @@ -458,8 +458,8 @@ "outputs": [], "source": [ "wcs = WCS(image_hdu.header)\n", - "fig = plt.figure(figsize=(6, 6))\n", "\n", + "fig = plt.figure(figsize=(6, 6))\n", "ax = fig.add_subplot(111, projection=wcs)\n", "ax.imshow(image_hdu.data, cmap='gray', norm='asinh', origin='lower')\n" ] @@ -477,7 +477,7 @@ } }, "source": [ - "> **Figure 1:** The cutout image, displayed in sky coordinateas using astropy.\n" + "> **Figure 1:** The cutout image, displayed in sky coordinates using astropy.\n" ] }, { @@ -798,8 +798,6 @@ "metadata": {}, "outputs": [], "source": [ - "del mem\n", - "\n", "sqE = SodaQuery.from_resource(dl_result,\n", " dl_result.get_adhocservice_by_id(\"cutout-sync-exposure\"),\n", " session=get_pyvo_auth())\n", @@ -938,8 +936,6 @@ "metadata": {}, "outputs": [], "source": [ - "#del mem\n", - "\n", "sqM = SodaQuery.from_resource(dl_result,\n", " dl_result.get_adhocservice_by_id(\"cutout-sync-maskedimage\"),\n", " session=get_pyvo_auth())\n", From 11203ed66b68e69adedf272b48ec82282925b78c Mon Sep 17 00:00:00 2001 From: christinawilliams Date: Tue, 13 Jan 2026 21:40:51 +0000 Subject: [PATCH 09/14] updating --- .../103_4_Small_Image_Cutout.ipynb | 97 ++++++++++++++----- 1 file changed, 74 insertions(+), 23 deletions(-) diff --git a/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb b/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb index a90dae9..2a9b1ce 100644 --- a/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb +++ b/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb @@ -327,7 +327,7 @@ "id": "d945e191-7ee4-458a-bb0f-fb00cd219e30", "metadata": {}, "source": [ - "Lastly, call the Rubin Image Cutout Service. This notebook demonstrates three types of cutout services: `cutout-sync` which, by default, returns just the image extension of the LSST imaging; `cutout-sync-exposure`, which returns the full set of metadata and image extensions that are contained in the `ExposureF` data type, and `cutout-sync-mask` which returns the mask extension. This section will demonstrate the use of the default cutout service, `cutout-sync`, and Section 4 below will demonstrate the other two. \n", + "Lastly, call the Rubin Image Cutout Service. This notebook demonstrates three types of cutout services: `cutout-sync` which, by default, returns just the image extension of the LSST imaging; `cutout-sync-exposure`, which returns the full set of metadata and image extensions that are contained in the `ExposureF` data type, and `cutout-sync-mask` which returns the mask extension with the science and variance images (`MaskedImageF` data type). This section will demonstrate the use of the default cutout service, `cutout-sync`, and Section 4 below will demonstrate the other two. \n", "\n", "To use the cutout service in this example, the IVOA procedure `cutout-sync` is called using `get_adhocservice_by_id`. It is done by feeding the data link created above (called `dl_result`) to `from_resource`. Since the Rubin DP1 imaging is proprietary it is necessary to again provide the authorization for the current RSP session. Do this using the `get_pyvo_auth` function." ] @@ -370,7 +370,10 @@ "\n", "Radius = 0.01 * u.deg\n", "\n", - "sq.circle = (cutout_ra, cutout_dec, Radius)" + "sq.circle = (cutout_ra, cutout_dec, Radius)\n", + "\n", + "cutout_bytes = sq.execute_stream().read()\n", + "sq.raise_if_error()" ] }, { @@ -391,9 +394,6 @@ "metadata": {}, "outputs": [], "source": [ - "cutout_bytes = sq.execute_stream().read()\n", - "sq.raise_if_error()\n", - "\n", "hdul = fits.open(io.BytesIO(cutout_bytes))\n" ] }, @@ -418,28 +418,22 @@ ] }, { - "cell_type": "code", - "execution_count": null, - "id": "da4cc3eb-16e3-44c7-9cf7-0d8214bc0671", + "cell_type": "markdown", + "id": "a5a6be22-ebe9-4fab-ac3a-cecd2126994b", "metadata": {}, - "outputs": [], "source": [ - "# option to print primary HDU header (very long). data is empty\n", - "#print(hdul[0].header)\n" + "Below, store the headers with optional print (in particular the primary header is very long)." ] }, { "cell_type": "code", "execution_count": null, - "id": "27361386-c8c3-4205-b112-6058d96d3377", + "id": "da4cc3eb-16e3-44c7-9cf7-0d8214bc0671", "metadata": {}, "outputs": [], "source": [ - "# option to print the header for the image extension\n", - "#image_data = image_hdu.data\n", - "#print(image_hdu.data)\n", - "\n", - "#print(image_hdu.header)" + "primary_header = hdul[0].header\n", + "image_header = hdul[1].header\n" ] }, { @@ -457,7 +451,7 @@ "metadata": {}, "outputs": [], "source": [ - "wcs = WCS(image_hdu.header)\n", + "wcs = WCS(image_header)\n", "\n", "fig = plt.figure(figsize=(6, 6))\n", "ax = fig.add_subplot(111, projection=wcs)\n", @@ -485,7 +479,7 @@ "id": "9be31876-1afa-4610-aaec-cc3497ad6930", "metadata": {}, "source": [ - "### 3.3 Retrieve the cutout with LSST\n", + "### 3.3. Retrieve the cutout with LSST\n", "\n", "The cutout can be read into memory in the LSST pipelines `ImageF` format, but does not include the WCS information." ] @@ -530,7 +524,7 @@ "source": [ "> **Figure 2:** The cutout image, displayed in pixel coordinates using LSST pipeline tools in grayscale with a scale bar at right.\n", "\n", - "#### 3.2.1. Option to save cutout to disk\n", + "#### 3.3.1. Option to save cutout to disk\n", "\n", "The cutout can be saved to disk as a FITS file with the `f.write()` function.\n", "\n", @@ -578,7 +572,7 @@ "id": "a1af5867-6da1-40f0-99ce-703938338ce4", "metadata": {}, "source": [ - "### 3.3. Use polygon to define shape\n", + "### 3.4. Use polygon to define shape\n", "\n", "It is also possible to define the cutout geometry using a polygon, which enables the cutout to be rectangular, but not necessarily be square. For this, use `polygon`, which takes as input the four corners in celestial coordinates. A minimum of 3 vertices are required (the line from the last vertex back to the first is implicit) Vertices must be ordered in the counter-clockwise direction. For example: a polygon is defined as a set of 4 (x,y) coordinates from (12,34) to (14,34) to (14,36) to (12,36) and (implicitly) back to (12,34) as:\n", "\n", @@ -645,7 +639,7 @@ "id": "9041e6f0-e9bc-46df-a9b8-ad0c61deb6bb", "metadata": {}, "source": [ - "### 3.4. Correcting for cos(d)\n", + "### 3.5. Correcting for cos(d)\n", "\n", "There is an important difference to note between the circle and polygon shape definitions. The angular distance on the sky that defines the circular cutout size already accounts for the difference in angular distance in the RA direction is smaller by a factor of cos(declination), where declination is in units radians. The difference increases with higher declination. However, the polygon definition does not automatically account for this cosine factor. Thus, circle and polygon cutout definitions using the same cutout edge length will not match size in the RA direction. The 2 cells below demonstrate how to make this correction to the polygon cutout definition to create symmetric cutouts with polygon. Here, reset the edge sizes to be the same as `Radius` from the circle definition above.\n", "\n", @@ -919,12 +913,69 @@ "# wcs=exposure.wcs)" ] }, + { + "cell_type": "markdown", + "id": "6daa6bf2-4e4d-46de-92df-a350c2edd67d", + "metadata": {}, + "source": [ + "### 4.2 Computation time\n", + "\n", + "Below, check the time difference between retrieving the default cutout (the slimmer image extension only), vs the full ExposureF image content and metadata.\n", + "\n", + "Weirdly these are not that different..." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "75a430e1-0394-4b57-be28-11c4d38a0976", + "metadata": {}, + "outputs": [], + "source": [ + "%%time\n", + "\n", + "sqE = SodaQuery.from_resource(dl_result,\n", + " dl_result.get_adhocservice_by_id(\"cutout-sync-exposure\"),\n", + " session=get_pyvo_auth())\n", + "\n", + "sqE.circle = (cutout_ra, cutout_dec, Radius)\n", + "\n", + "cutout_bytes = sqE.execute_stream().read()\n", + "sqE.raise_if_error()\n", + "\n", + "mem = MemFileManager(len(cutout_bytes))\n", + "mem.setData(cutout_bytes, len(cutout_bytes))\n", + "\n", + "exposure = ExposureF(mem)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "87b8a98b-09cb-43fc-a053-21107077d310", + "metadata": {}, + "outputs": [], + "source": [ + "%%time\n", + "sq = SodaQuery.from_resource(dl_result,\n", + " dl_result.get_adhocservice_by_id(\"cutout-sync\"),\n", + " session=get_pyvo_auth())\n", + "\n", + "sq.circle = (cutout_ra, cutout_dec, Radius)\n", + "\n", + "cutout_bytes = sq.execute_stream().read()\n", + "sq.raise_if_error()\n", + "mem = MemFileManager(len(cutout_bytes))\n", + "mem.setData(cutout_bytes, len(cutout_bytes))\n", + "image = ImageF(mem)" + ] + }, { "cell_type": "markdown", "id": "1fcde65c-8ba1-4ffc-9501-08c01e331e81", "metadata": {}, "source": [ - "### 4.1 Mask cutouts\n", + "### 4.3 Mask cutouts\n", "\n", "Again, reuse the data link `dl_result` that was defined in Section 3 to define a new cutout, this time using `cutout-sync-maskedimage` service. The returned Call this soda query `sqM` to differentiate from the earlier ones. Define the cutout as a square subtended by a circle of radius 0.01 degrees, as done in Section 3.\n" ] From 0493f5ec8fcd3894cdb7836f27015c0ea60571fa Mon Sep 17 00:00:00 2001 From: christinawilliams Date: Thu, 15 Jan 2026 16:41:58 +0000 Subject: [PATCH 10/14] updating --- .../103_4_Small_Image_Cutout.ipynb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb b/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb index 2a9b1ce..a752ae3 100644 --- a/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb +++ b/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb @@ -383,6 +383,8 @@ "source": [ "### 3.2. Retrieve the cutout with astropy\n", "\n", + "Move this to be the secondary. with LSST should be first \n", + "\n", "The format of the default cutout is a 2-extension fits: the primary (extension 0) header data unit (HDU) has the header describing the data set, and the secondary HDU (extension 1) has only the header that describes the pixel data (i.e. science image).\n", "\n" ] @@ -782,7 +784,9 @@ "source": [ "### 4.1 ExposureF cutouts\n", "\n", - "First, reuse the data link `dl_result` that was defined in Section 3 to define a new cutout, this time using `cutout-sync-exposure` service. Call this soda query `sqE` to differentiate from the earlier ones. Define the cutout as a square subtended by a circle of radius 0.01 degrees, as done in Section 3.\n" + "First, reuse the data link `dl_result` that was defined in Section 3 to define a new cutout, this time using `cutout-sync-exposure` service. Call this soda query `sqE` to differentiate from the earlier ones. Define the cutout as a square subtended by a circle of radius 0.01 degrees, as done in Section 3.\n", + "\n", + "Somewhere show how to get WCS\n" ] }, { @@ -922,7 +926,7 @@ "\n", "Below, check the time difference between retrieving the default cutout (the slimmer image extension only), vs the full ExposureF image content and metadata.\n", "\n", - "Weirdly these are not that different..." + "Weirdly these are not that different... take this out and don't say anything about time." ] }, { From 7cd702116bdaae215c63a76e5a1c905b30ef3a76 Mon Sep 17 00:00:00 2001 From: christinawilliams Date: Thu, 15 Jan 2026 16:50:00 +0000 Subject: [PATCH 11/14] updating --- .../103_4_Small_Image_Cutout.ipynb | 263 +++++++----------- 1 file changed, 101 insertions(+), 162 deletions(-) diff --git a/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb b/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb index a752ae3..219f462 100644 --- a/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb +++ b/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb @@ -22,7 +22,7 @@ "Data Release: DP1
\n", "Container Size: large
\n", "LSST Science Pipelines version: r29.2.0
\n", - "Last verified to run: 2025-12-16
\n", + "Last verified to run: 2026-01-15
\n", "Repository: github.com/lsst/tutorial-notebooks
" ] }, @@ -378,195 +378,194 @@ }, { "cell_type": "markdown", - "id": "30640af4-a75c-4132-8f2e-692fcf9694eb", + "id": "9be31876-1afa-4610-aaec-cc3497ad6930", "metadata": {}, "source": [ - "### 3.2. Retrieve the cutout with astropy\n", - "\n", - "Move this to be the secondary. with LSST should be first \n", + "### 3.2. Retrieve the cutout with LSST\n", "\n", - "The format of the default cutout is a 2-extension fits: the primary (extension 0) header data unit (HDU) has the header describing the data set, and the secondary HDU (extension 1) has only the header that describes the pixel data (i.e. science image).\n", - "\n" + "The cutout can be read into memory in the LSST pipelines `ImageF` format, but does not include the WCS information." ] }, { "cell_type": "code", "execution_count": null, - "id": "6cd941c5-7e03-4c1b-a327-03f5ebc578f1", + "id": "2e7173c4-5030-4420-b215-e275534cb083", "metadata": {}, "outputs": [], "source": [ - "hdul = fits.open(io.BytesIO(cutout_bytes))\n" + "mem = MemFileManager(len(cutout_bytes))\n", + "mem.setData(cutout_bytes, len(cutout_bytes))\n", + "image = ImageF(mem)" ] }, { "cell_type": "markdown", - "id": "87c5e852-f42c-403f-b357-130a69b2b2e5", + "id": "324be87a-337b-4db7-b57d-842f14614613", "metadata": {}, "source": [ - "Explore the format of the returned HDU extensions. There are two HDUs, where the second one labeled Image (extension 1) contains the image pixels and WCS header." + "Display the `ImageF` cutout." ] }, { "cell_type": "code", "execution_count": null, - "id": "00b1efae-7b59-422b-9708-1036120c4d8d", + "id": "dda20882-a6c3-44ad-9f99-5cb730dd8392", "metadata": {}, "outputs": [], "source": [ - "hdul.info()\n", - "primary_hdu = hdul[0]\n", - "image_hdu = hdul[1]\n" + "display = afwDisplay.Display()\n", + "display.scale('asinh', 'zscale')\n", + "display.image(image)\n", + "plt.show()" ] }, { "cell_type": "markdown", - "id": "a5a6be22-ebe9-4fab-ac3a-cecd2126994b", + "id": "458a4d25-ca95-4f92-b76e-986b7a03b320", "metadata": {}, "source": [ - "Below, store the headers with optional print (in particular the primary header is very long)." + "> **Figure 1:** The cutout image, displayed in pixel coordinates using LSST pipeline tools in grayscale with a scale bar at right.\n", + "\n", + "#### 3.2.1. Option to save cutout to disk\n", + "\n", + "The cutout can be saved to disk as a FITS file with the `f.write()` function.\n", + "\n", + "The cutouts saved to disk with the following commands will be stored in a temporary folder in the user's home directory.\n", + "\n", + "After saving the cutout as a FITS file, read it in as an `ImageF` and display it." ] }, { "cell_type": "code", "execution_count": null, - "id": "da4cc3eb-16e3-44c7-9cf7-0d8214bc0671", + "id": "a928ffaf-7cbd-41b5-8ea8-ee0f71172878", "metadata": {}, "outputs": [], "source": [ - "primary_header = hdul[0].header\n", - "image_header = hdul[1].header\n" + "# tempdir = os.path.join(os.getenv('HOME'), 'cutouts_temp/')\n", + "# if not os.path.exists(tempdir):\n", + "# os.makedirs(tempdir)\n", + "# print('Created ', tempdir)\n", + "# else:\n", + "# print('Directory already existed: ', tempdir)\n", + "\n", + "# sodaCutout = os.path.join(tempdir, 'cutout-circle.fits')\n", + "# with open(sodaCutout, 'bw') as f:\n", + "# f.write(sq.execute_stream().read())\n", + "\n", + "# cutout = ImageF(sodaCutout)\n", + "# display = afwDisplay.Display()\n", + "# display.scale('asinh', 'zscale')\n", + "# display.image(cutout)\n", + "# plt.show()" ] }, { "cell_type": "markdown", - "id": "88be8f44-3226-4fda-97eb-ea0b272a88ec", + "id": "48c472a9-b2d1-4a61-a606-9da1aa38dea8", "metadata": {}, "source": [ - "Plot the cutout using astropy tools, with WCS info from the image header used to plot in sky coordinates." + "Future planned options for the Rubin cutout service, including the potential to retrieve other image formats such as jpeg, are listed at the Rubin Science Platform image cutout implementation strategy document.\n", + "\n" ] }, { - "cell_type": "code", - "execution_count": null, - "id": "0b755176-ce5f-4238-9cd9-4798a0dfe133", + "cell_type": "markdown", + "id": "30640af4-a75c-4132-8f2e-692fcf9694eb", "metadata": {}, - "outputs": [], "source": [ - "wcs = WCS(image_header)\n", + "### 3.3. Retrieve the cutout with astropy\n", "\n", - "fig = plt.figure(figsize=(6, 6))\n", - "ax = fig.add_subplot(111, projection=wcs)\n", - "ax.imshow(image_hdu.data, cmap='gray', norm='asinh', origin='lower')\n" + "Move this to be the secondary. with LSST should be first \n", + "\n", + "The format of the default cutout is a 2-extension fits: the primary (extension 0) header data unit (HDU) has the header describing the data set, and the secondary HDU (extension 1) has only the header that describes the pixel data (i.e. science image).\n" ] }, { - "cell_type": "markdown", - "id": "ca5f197f-24a9-4440-8c8e-9f3398ebea26", - "metadata": { - "execution": { - "iopub.execute_input": "2026-01-13T19:56:44.392687Z", - "iopub.status.busy": "2026-01-13T19:56:44.392329Z", - "iopub.status.idle": "2026-01-13T19:56:44.396918Z", - "shell.execute_reply": "2026-01-13T19:56:44.395598Z", - "shell.execute_reply.started": "2026-01-13T19:56:44.392670Z" - } - }, + "cell_type": "code", + "execution_count": null, + "id": "6cd941c5-7e03-4c1b-a327-03f5ebc578f1", + "metadata": {}, + "outputs": [], "source": [ - "> **Figure 1:** The cutout image, displayed in sky coordinates using astropy.\n" + "hdul = fits.open(io.BytesIO(cutout_bytes))\n" ] }, { "cell_type": "markdown", - "id": "9be31876-1afa-4610-aaec-cc3497ad6930", + "id": "87c5e852-f42c-403f-b357-130a69b2b2e5", "metadata": {}, "source": [ - "### 3.3. Retrieve the cutout with LSST\n", - "\n", - "The cutout can be read into memory in the LSST pipelines `ImageF` format, but does not include the WCS information." + "Explore the format of the returned HDU extensions. There are two HDUs, where the second one labeled Image (extension 1) contains the image pixels and WCS header." ] }, { "cell_type": "code", "execution_count": null, - "id": "2e7173c4-5030-4420-b215-e275534cb083", + "id": "00b1efae-7b59-422b-9708-1036120c4d8d", "metadata": {}, "outputs": [], "source": [ - "mem = MemFileManager(len(cutout_bytes))\n", - "mem.setData(cutout_bytes, len(cutout_bytes))\n", - "image = ImageF(mem)" + "hdul.info()\n", + "primary_hdu = hdul[0]\n", + "image_hdu = hdul[1]\n" ] }, { "cell_type": "markdown", - "id": "324be87a-337b-4db7-b57d-842f14614613", + "id": "a5a6be22-ebe9-4fab-ac3a-cecd2126994b", "metadata": {}, "source": [ - "Display the `ImageF` cutout." + "Below, store the headers with optional print (in particular the primary header is very long)." ] }, { "cell_type": "code", "execution_count": null, - "id": "dda20882-a6c3-44ad-9f99-5cb730dd8392", + "id": "da4cc3eb-16e3-44c7-9cf7-0d8214bc0671", "metadata": {}, "outputs": [], "source": [ - "display = afwDisplay.Display()\n", - "display.scale('asinh', 'zscale')\n", - "display.image(image)\n", - "plt.show()" + "primary_header = hdul[0].header\n", + "image_header = hdul[1].header\n" ] }, { "cell_type": "markdown", - "id": "458a4d25-ca95-4f92-b76e-986b7a03b320", + "id": "88be8f44-3226-4fda-97eb-ea0b272a88ec", "metadata": {}, "source": [ - "> **Figure 2:** The cutout image, displayed in pixel coordinates using LSST pipeline tools in grayscale with a scale bar at right.\n", - "\n", - "#### 3.3.1. Option to save cutout to disk\n", - "\n", - "The cutout can be saved to disk as a FITS file with the `f.write()` function.\n", - "\n", - "The cutouts saved to disk with the following commands will be stored in a temporary folder in the user's home directory.\n", - "\n", - "After saving the cutout as a FITS file, read it in as an `ImageF` and display it." + "Plot the cutout using astropy tools, with WCS info from the image header used to plot in sky coordinates." ] }, { "cell_type": "code", "execution_count": null, - "id": "a928ffaf-7cbd-41b5-8ea8-ee0f71172878", + "id": "0b755176-ce5f-4238-9cd9-4798a0dfe133", "metadata": {}, "outputs": [], "source": [ - "# tempdir = os.path.join(os.getenv('HOME'), 'cutouts_temp/')\n", - "# if not os.path.exists(tempdir):\n", - "# os.makedirs(tempdir)\n", - "# print('Created ', tempdir)\n", - "# else:\n", - "# print('Directory already existed: ', tempdir)\n", - "\n", - "# sodaCutout = os.path.join(tempdir, 'cutout-circle.fits')\n", - "# with open(sodaCutout, 'bw') as f:\n", - "# f.write(sq.execute_stream().read())\n", + "wcs = WCS(image_header)\n", "\n", - "# cutout = ImageF(sodaCutout)\n", - "# display = afwDisplay.Display()\n", - "# display.scale('asinh', 'zscale')\n", - "# display.image(cutout)\n", - "# plt.show()" + "fig = plt.figure(figsize=(6, 6))\n", + "ax = fig.add_subplot(111, projection=wcs)\n", + "ax.imshow(image_hdu.data, cmap='gray', norm='asinh', origin='lower')\n" ] }, { "cell_type": "markdown", - "id": "48c472a9-b2d1-4a61-a606-9da1aa38dea8", - "metadata": {}, + "id": "ca5f197f-24a9-4440-8c8e-9f3398ebea26", + "metadata": { + "execution": { + "iopub.execute_input": "2026-01-13T19:56:44.392687Z", + "iopub.status.busy": "2026-01-13T19:56:44.392329Z", + "iopub.status.idle": "2026-01-13T19:56:44.396918Z", + "shell.execute_reply": "2026-01-13T19:56:44.395598Z", + "shell.execute_reply.started": "2026-01-13T19:56:44.392670Z" + } + }, "source": [ - "Future planned options for the Rubin cutout service, including the potential to retrieve other image formats such as jpeg, are listed at the Rubin Science Platform image cutout implementation strategy document.\n", - "\n" + "> **Figure 2:** The cutout image, displayed in sky coordinates using astropy.\n" ] }, { @@ -659,15 +658,12 @@ " dl_result.get_adhocservice_by_id(\"cutout-sync\"),\n", " session=get_pyvo_auth())\n", "\n", - "edge1 = Radius\n", - "edge2 = Radius\n", - "\n", - "sq2.polygon = (cutout_ra - edge1,\n", - " cutout_dec - edge2,\n", - " cutout_ra - edge1,\n", - " cutout_dec + edge2,\n", - " cutout_ra + edge1,\n", - " cutout_dec + edge2)\n", + "sq2.polygon = (cutout_ra - Radius,\n", + " cutout_dec - Radius,\n", + " cutout_ra - Radius,\n", + " cutout_dec + Radius,\n", + " cutout_ra + Radius,\n", + " cutout_dec + Radius)\n", "\n", "cutout_bytes = sq2.execute_stream().read()\n", "sq2.raise_if_error()\n", @@ -699,14 +695,14 @@ " dl_result.get_adhocservice_by_id(\"cutout-sync\"),\n", " session=get_pyvo_auth())\n", "\n", - "sq3.polygon = (cutout_ra - edge1/cosd,\n", - " cutout_dec - edge2,\n", - " cutout_ra - edge1/cosd,\n", - " cutout_dec + edge2,\n", - " cutout_ra + edge1/cosd,\n", - " cutout_dec + edge2,\n", - " cutout_ra + edge1/cosd,\n", - " cutout_dec - edge2)\n", + "sq3.polygon = (cutout_ra - Radius/cosd,\n", + " cutout_dec - Radius,\n", + " cutout_ra - Radius/cosd,\n", + " cutout_dec + Radius,\n", + " cutout_ra + Radius/cosd,\n", + " cutout_dec + Radius,\n", + " cutout_ra + Radius/cosd,\n", + " cutout_dec - Radius)\n", "\n", "cutout_bytes = sq3.execute_stream().read()\n", "sq3.raise_if_error()\n", @@ -917,69 +913,12 @@ "# wcs=exposure.wcs)" ] }, - { - "cell_type": "markdown", - "id": "6daa6bf2-4e4d-46de-92df-a350c2edd67d", - "metadata": {}, - "source": [ - "### 4.2 Computation time\n", - "\n", - "Below, check the time difference between retrieving the default cutout (the slimmer image extension only), vs the full ExposureF image content and metadata.\n", - "\n", - "Weirdly these are not that different... take this out and don't say anything about time." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "75a430e1-0394-4b57-be28-11c4d38a0976", - "metadata": {}, - "outputs": [], - "source": [ - "%%time\n", - "\n", - "sqE = SodaQuery.from_resource(dl_result,\n", - " dl_result.get_adhocservice_by_id(\"cutout-sync-exposure\"),\n", - " session=get_pyvo_auth())\n", - "\n", - "sqE.circle = (cutout_ra, cutout_dec, Radius)\n", - "\n", - "cutout_bytes = sqE.execute_stream().read()\n", - "sqE.raise_if_error()\n", - "\n", - "mem = MemFileManager(len(cutout_bytes))\n", - "mem.setData(cutout_bytes, len(cutout_bytes))\n", - "\n", - "exposure = ExposureF(mem)\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "87b8a98b-09cb-43fc-a053-21107077d310", - "metadata": {}, - "outputs": [], - "source": [ - "%%time\n", - "sq = SodaQuery.from_resource(dl_result,\n", - " dl_result.get_adhocservice_by_id(\"cutout-sync\"),\n", - " session=get_pyvo_auth())\n", - "\n", - "sq.circle = (cutout_ra, cutout_dec, Radius)\n", - "\n", - "cutout_bytes = sq.execute_stream().read()\n", - "sq.raise_if_error()\n", - "mem = MemFileManager(len(cutout_bytes))\n", - "mem.setData(cutout_bytes, len(cutout_bytes))\n", - "image = ImageF(mem)" - ] - }, { "cell_type": "markdown", "id": "1fcde65c-8ba1-4ffc-9501-08c01e331e81", "metadata": {}, "source": [ - "### 4.3 Mask cutouts\n", + "### 4.2 Mask cutouts\n", "\n", "Again, reuse the data link `dl_result` that was defined in Section 3 to define a new cutout, this time using `cutout-sync-maskedimage` service. The returned Call this soda query `sqM` to differentiate from the earlier ones. Define the cutout as a square subtended by a circle of radius 0.01 degrees, as done in Section 3.\n" ] From 335b860f53f8e73d4616331945a3559be3b161ee Mon Sep 17 00:00:00 2001 From: christinawilliams Date: Thu, 15 Jan 2026 19:10:24 +0000 Subject: [PATCH 12/14] updating --- .../103_4_Small_Image_Cutout.ipynb | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb b/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb index 219f462..dfe86b2 100644 --- a/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb +++ b/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb @@ -100,7 +100,6 @@ "import matplotlib.pyplot as plt\n", "\n", "import lsst.afw.display as afwDisplay\n", - "import lsst.afw.image as afwImage\n", "from lsst.afw.image import ExposureF, ImageF, MaskedImageF\n", "from lsst.afw.fits import MemFileManager\n", "\n", @@ -476,8 +475,6 @@ "source": [ "### 3.3. Retrieve the cutout with astropy\n", "\n", - "Move this to be the secondary. with LSST should be first \n", - "\n", "The format of the default cutout is a 2-extension fits: the primary (extension 0) header data unit (HDU) has the header describing the data set, and the secondary HDU (extension 1) has only the header that describes the pixel data (i.e. science image).\n" ] }, @@ -516,7 +513,7 @@ "id": "a5a6be22-ebe9-4fab-ac3a-cecd2126994b", "metadata": {}, "source": [ - "Below, store the headers with optional print (in particular the primary header is very long)." + "Below, store the headers to allow the option to print (note that the primary header is very long)." ] }, { @@ -549,7 +546,7 @@ "\n", "fig = plt.figure(figsize=(6, 6))\n", "ax = fig.add_subplot(111, projection=wcs)\n", - "ax.imshow(image_hdu.data, cmap='gray', norm='asinh', origin='lower')\n" + "ax.imshow(image_hdu.data, cmap='gray', norm='asinh', origin='lower')\n" ] }, { @@ -839,6 +836,25 @@ "exposure = ExposureF(mem)\n" ] }, + { + "cell_type": "markdown", + "id": "19815771-fabd-44b1-b359-c1a2f99fcb04", + "metadata": {}, + "source": [ + "The WCS information can be obtained using the getWcs method. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d0d058d6-1cad-4ca4-866b-841baba94220", + "metadata": {}, + "outputs": [], + "source": [ + "exposureWCS = WCS(exposure.getWcs().getFitsMetadata())\n", + "print(exposureWCS)" + ] + }, { "cell_type": "markdown", "id": "6a19e7cd-4096-44b9-832f-baa6b6c40482", From 8a5a86f02332d636901fd77245271e8053c1780b Mon Sep 17 00:00:00 2001 From: christinawilliams Date: Thu, 15 Jan 2026 19:11:17 +0000 Subject: [PATCH 13/14] updating --- .../103_4_Small_Image_Cutout.ipynb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb b/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb index dfe86b2..de07721 100644 --- a/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb +++ b/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb @@ -777,9 +777,7 @@ "source": [ "### 4.1 ExposureF cutouts\n", "\n", - "First, reuse the data link `dl_result` that was defined in Section 3 to define a new cutout, this time using `cutout-sync-exposure` service. Call this soda query `sqE` to differentiate from the earlier ones. Define the cutout as a square subtended by a circle of radius 0.01 degrees, as done in Section 3.\n", - "\n", - "Somewhere show how to get WCS\n" + "First, reuse the data link `dl_result` that was defined in Section 3 to define a new cutout, this time using `cutout-sync-exposure` service. Call this soda query `sqE` to differentiate from the earlier ones. Define the cutout as a square subtended by a circle of radius 0.01 degrees, as done in Section 3.\n" ] }, { From 3a7ba342e3727349be86b44323d2b78eff189aec Mon Sep 17 00:00:00 2001 From: christinawilliams Date: Thu, 15 Jan 2026 19:16:46 +0000 Subject: [PATCH 14/14] updating --- .../103_4_Small_Image_Cutout.ipynb | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb b/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb index de07721..aece252 100644 --- a/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb +++ b/DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb @@ -552,15 +552,7 @@ { "cell_type": "markdown", "id": "ca5f197f-24a9-4440-8c8e-9f3398ebea26", - "metadata": { - "execution": { - "iopub.execute_input": "2026-01-13T19:56:44.392687Z", - "iopub.status.busy": "2026-01-13T19:56:44.392329Z", - "iopub.status.idle": "2026-01-13T19:56:44.396918Z", - "shell.execute_reply": "2026-01-13T19:56:44.395598Z", - "shell.execute_reply.started": "2026-01-13T19:56:44.392670Z" - } - }, + "metadata": {}, "source": [ "> **Figure 2:** The cutout image, displayed in sky coordinates using astropy.\n" ]