Skip to content

Commit 6c8252b

Browse files
updates to 103_4 nb
1 parent 219754b commit 6c8252b

1 file changed

Lines changed: 47 additions & 127 deletions

File tree

DP1/100_How_to_Use_RSP_Tools/103_Image_access_and_display/103_4_Small_Image_Cutout.ipynb

Lines changed: 47 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
"Data Release: DP1 <br>\n",
2323
"Container Size: large <br>\n",
2424
"LSST Science Pipelines version: r29.2.0 <br>\n",
25-
"Last verified to run: 2025-11-20 <br>\n",
25+
"Last verified to run: 2025-12-15 <br>\n",
2626
"Repository: <a href=\"https://github.com/lsst/tutorial-notebooks\">github.com/lsst/tutorial-notebooks</a> <br>"
2727
]
2828
},
@@ -98,12 +98,13 @@
9898
"source": [
9999
"import numpy as np\n",
100100
"import matplotlib.pyplot as plt\n",
101-
"import os\n",
102101
"\n",
103102
"import lsst.afw.display as afwDisplay\n",
103+
"import lsst.afw.image as afwImage\n",
104104
"from lsst.afw.image import ExposureF\n",
105105
"from lsst.afw.fits import MemFileManager\n",
106106
"\n",
107+
"\n",
107108
"from lsst.rsp.utils import get_pyvo_auth\n",
108109
"from lsst.rsp.service import get_siav2_service\n",
109110
"\n",
@@ -113,7 +114,10 @@
113114
"\n",
114115
"from astropy import units as u\n",
115116
"from astropy.coordinates import Angle\n",
116-
"from astropy.time import Time"
117+
"from astropy.time import Time\n",
118+
"\n",
119+
"from astropy.io import fits\n",
120+
"import io\n"
117121
]
118122
},
119123
{
@@ -324,7 +328,7 @@
324328
"id": "d945e191-7ee4-458a-bb0f-fb00cd219e30",
325329
"metadata": {},
326330
"source": [
327-
"Lastly, call the Rubin Image Cutout Service. Three types of cutout services exist: `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 contains just the mask extension. This section will demonstrate the use of `cutout-sync-exposure` and Section 4 below will demonstrate the other two. \n",
331+
"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",
328332
"\n",
329333
"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."
330334
]
@@ -681,31 +685,11 @@
681685
"id": "99e75a7a-348e-409e-88f6-871b68a4e9dc",
682686
"metadata": {},
683687
"source": [
684-
"## 4. Other cutout service data types\n",
685-
"\n",
686-
"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, and and `cutout-sync-mask` which contains just the mask extension. The latter 2 will be demonstrated below.\n",
687-
"\n",
688-
"### 4.1 Single extension image cutouts\n",
689-
"\n",
690-
"Below demonstrates how to retrieve single extension images using `cutout-sync`."
691-
]
692-
},
693-
{
694-
"cell_type": "code",
695-
"execution_count": null,
696-
"id": "c2c8ab4c-cd1d-4ae8-937d-b34a21035e1e",
697-
"metadata": {},
698-
"outputs": [],
699-
"source": [
700-
"from astropy.io import fits\n",
701-
"import io\n",
688+
"## 4. Single extension image cutouts\n",
702689
"\n",
703-
"print(results[0])\n",
704-
"datalink_url = results[0].access_url\n",
705-
"dl_result = DatalinkResults.from_result_url(datalink_url,\n",
706-
" session=get_pyvo_auth())\n",
690+
"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 2 will be demonstrated below.\n",
707691
"\n",
708-
"f\"Datalink status: {dl_result.status}. Datalink service url: {datalink_url}\"\n"
692+
"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"
709693
]
710694
},
711695
{
@@ -715,169 +699,113 @@
715699
"metadata": {},
716700
"outputs": [],
717701
"source": [
718-
"\n",
719-
"sq5 = SodaQuery.from_resource(dl_result,\n",
720-
" dl_result.get_adhocservice_by_id(\"cutout-sync\"),\n",
721-
" session=get_pyvo_auth())\n",
702+
"sq4 = SodaQuery.from_resource(dl_result,\n",
703+
" dl_result.get_adhocservice_by_id(\"cutout-sync\"),\n",
704+
" session=get_pyvo_auth())\n",
722705
"\n",
723706
"spherePoint = geom.SpherePoint(target_ra*geom.degrees, target_dec*geom.degrees)\n",
724707
"Radius = 0.01 * u.deg\n",
725-
"sq5.circle = (spherePoint.getRa().asDegrees() * u.deg,\n",
726-
" spherePoint.getDec().asDegrees() * u.deg,\n",
727-
" Radius)\n",
728708
"\n",
729-
"cutout_bytes = sq5.execute_stream().read()\n",
730-
"sq5.raise_if_error()\n"
709+
"sq4.circle = (spherePoint.getRa().asDegrees() * u.deg,\n",
710+
" spherePoint.getDec().asDegrees() * u.deg,\n",
711+
" Radius)\n",
712+
"\n",
713+
"cutout_bytes = sq4.execute_stream().read()\n",
714+
"sq4.raise_if_error()\n"
731715
]
732716
},
733717
{
734-
"cell_type": "code",
735-
"execution_count": null,
736-
"id": "516dbd86-d573-4d81-a017-2ebbce8fb445",
718+
"cell_type": "markdown",
719+
"id": "454a017b-df88-48cc-975e-cac4ff3a37b5",
737720
"metadata": {},
738-
"outputs": [],
739721
"source": [
740-
"mem = MemFileManager(len(cutout_bytes))\n",
741-
"mem.setData(cutout_bytes, len(cutout_bytes))\n",
742-
"\n"
722+
"Receive the cutout into memory, as in Section 3."
743723
]
744724
},
745725
{
746726
"cell_type": "code",
747727
"execution_count": null,
748-
"id": "ed3f7908-a256-42f5-939f-61f38645c7ca",
728+
"id": "516dbd86-d573-4d81-a017-2ebbce8fb445",
749729
"metadata": {},
750730
"outputs": [],
751731
"source": [
752-
"data = mem.getData() # returns `bytes`\n",
753-
"\n",
754-
"# this doesn't work\n",
755-
"import lsst.afw.image as afwImage\n",
756-
"\n",
757-
"#image = afwImage.ImageF(mem)\n"
732+
"mem = MemFileManager(len(cutout_bytes))\n",
733+
"mem.setData(cutout_bytes, len(cutout_bytes))\n"
758734
]
759735
},
760736
{
761-
"cell_type": "code",
762-
"execution_count": null,
763-
"id": "d23a0397-6500-4e36-b956-7917ed6a7173",
737+
"cell_type": "markdown",
738+
"id": "2ae72a88-8002-46b5-8eee-164a2c903314",
764739
"metadata": {},
765-
"outputs": [],
766740
"source": [
767-
"\n",
768-
"#data = mem.getData()\n",
769-
"hdul = fits.open(io.BytesIO(data))\n",
770-
"hdul.info()\n",
771-
"\n",
772-
"image_hdu = hdul[1] # IMAGE extension\n",
773-
"image_data = image_hdu.data # NumPy array\n",
774-
"#image = afwImage.ImageF(image_data)\n",
775-
"image = afwImage.ImageF(image_data.astype(\"float32\"))\n",
776-
"print(type(image_data)) # numpy.ndarray\n",
777-
"print(type(image)) # lsst.afw.image._image.ImageF\n"
741+
"Use the `getData` method from the `MemFileManager` class to return and store the bytes associated with the cutout. "
778742
]
779743
},
780744
{
781745
"cell_type": "code",
782746
"execution_count": null,
783-
"id": "1aa9009a-b493-41ea-bc3c-e0c79adef913",
747+
"id": "ed3f7908-a256-42f5-939f-61f38645c7ca",
784748
"metadata": {},
785749
"outputs": [],
786750
"source": [
787-
"\n",
788-
"display = afwDisplay.Display()\n",
789-
"display.scale('asinh', 'zscale')\n",
790-
"display.image(image)\n",
791-
"plt.show()"
751+
"data = mem.getData()\n"
792752
]
793753
},
794754
{
795755
"cell_type": "markdown",
796-
"id": "918e8779-2939-4978-9ec4-c8a4047f04e9",
756+
"id": "441a49fb-42be-4f37-853e-141419f1da14",
797757
"metadata": {},
798758
"source": [
799-
"### 4.2 Single extension mask cutouts\n",
800-
"\n",
801-
"Below demonstrates how to retrieve the corresponding mask using `cutout-sync-mask`."
759+
"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. "
802760
]
803761
},
804762
{
805763
"cell_type": "code",
806764
"execution_count": null,
807-
"id": "a1213ce5-9049-43ce-8032-f1ea2db9c576",
765+
"id": "d23a0397-6500-4e36-b956-7917ed6a7173",
808766
"metadata": {},
809767
"outputs": [],
810768
"source": [
769+
"hdul = fits.open(io.BytesIO(data))\n",
770+
"hdul.info()\n",
811771
"\n",
812-
"sq5 = SodaQuery.from_resource(dl_result,\n",
813-
" dl_result.get_adhocservice_by_id(\"cutout-sync-maskedimage\"),\n",
814-
" session=get_pyvo_auth())\n",
815-
"\n",
816-
"spherePoint = geom.SpherePoint(target_ra*geom.degrees, target_dec*geom.degrees)\n",
817-
"Radius = 0.01 * u.deg\n",
818-
"sq5.circle = (spherePoint.getRa().asDegrees() * u.deg,\n",
819-
" spherePoint.getDec().asDegrees() * u.deg,\n",
820-
" Radius)\n",
821-
"\n",
822-
"cutout_bytes = sq5.execute_stream().read()\n",
823-
"sq5.raise_if_error()\n"
772+
"image_hdu = hdul[1]\n",
773+
"image_data = image_hdu.data\n"
824774
]
825775
},
826776
{
827-
"cell_type": "code",
828-
"execution_count": null,
829-
"id": "a2f5ed28-c17d-451b-969c-b7d9186eeb23",
777+
"cell_type": "markdown",
778+
"id": "c0eea8e5-ae86-456d-9d67-798557a4a707",
830779
"metadata": {},
831-
"outputs": [],
832780
"source": [
833-
"mem = MemFileManager(len(cutout_bytes))\n",
834-
"mem.setData(cutout_bytes, len(cutout_bytes))\n",
835-
"\n"
781+
"To enable image display, first store `image_data` as an LSST `ImageF` object."
836782
]
837783
},
838784
{
839785
"cell_type": "code",
840786
"execution_count": null,
841-
"id": "770c6bc2-67f5-4d3f-9d3a-98cd27e28b35",
787+
"id": "78e1c658-916c-4a73-8c0b-a50d281f4764",
842788
"metadata": {},
843789
"outputs": [],
844790
"source": [
845-
"data = mem.getData() # returns `bytes`\n",
846-
"\n",
847-
"# this doesn't work\n",
848-
"import lsst.afw.image as afwImage\n",
849-
"\n",
850-
"#image = afwImage.ImageF(mem)\n"
791+
"image = afwImage.ImageF(image_data.astype(\"float32\"))\n"
851792
]
852793
},
853794
{
854-
"cell_type": "code",
855-
"execution_count": null,
856-
"id": "ba884db3-cd3e-45b9-bba0-ecd98cd95358",
795+
"cell_type": "markdown",
796+
"id": "6a19e7cd-4096-44b9-832f-baa6b6c40482",
857797
"metadata": {},
858-
"outputs": [],
859798
"source": [
860-
"\n",
861-
"#data = mem.getData()\n",
862-
"hdul = fits.open(io.BytesIO(data))\n",
863-
"hdul.info()\n",
864-
"\n",
865-
"image_hdu = hdul[2] # IMAGE extension\n",
866-
"image_data = image_hdu.data # NumPy array\n",
867-
"#image = afwImage.ImageF(image_data)\n",
868-
"image = afwImage.ImageF(image_data)#.astype(\"float32\"))\n",
869-
"print(type(image_data)) # numpy.ndarray\n",
870-
"print(type(image)) # lsst.afw.image._image.ImageF\n"
799+
"Display the image cutout."
871800
]
872801
},
873802
{
874803
"cell_type": "code",
875804
"execution_count": null,
876-
"id": "cceab1fb-7f66-4858-b46f-d71fddb50159",
805+
"id": "1aa9009a-b493-41ea-bc3c-e0c79adef913",
877806
"metadata": {},
878807
"outputs": [],
879808
"source": [
880-
"\n",
881809
"display = afwDisplay.Display()\n",
882810
"display.scale('asinh', 'zscale')\n",
883811
"display.image(image)\n",
@@ -904,14 +832,6 @@
904832
"\n",
905833
"</div>\n"
906834
]
907-
},
908-
{
909-
"cell_type": "code",
910-
"execution_count": null,
911-
"id": "6b611f9f-aaa5-4e2b-b4a5-b7acc6aecbf9",
912-
"metadata": {},
913-
"outputs": [],
914-
"source": []
915835
}
916836
],
917837
"metadata": {

0 commit comments

Comments
 (0)