Skip to content

Commit 3407d7a

Browse files
Merge pull request #104 from lsst/tickets/SP-2732
Tickets/sp 2732
2 parents 3a0318e + 108ffc4 commit 3407d7a

6 files changed

Lines changed: 161 additions & 40 deletions

File tree

DP0.2/13a_Image_Cutout_SciDemo.ipynb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"<img align=\"left\" src = https://project.lsst.org/sites/default/files/Rubin-O-Logo_0.png width=250 style=\"padding: 10px\" alt=\"Rubin Observatory logo, a graphical representation of turning stars into data.\">\n",
1111
"<br>\n",
1212
"Contact author: Christina Williams <br>\n",
13-
"Last verified to run: 2025-09-02 <br>\n",
13+
"Last verified to run: 2025-12-15 <br>\n",
1414
"LSST Science Pipelines version: r29.2.0 <br>\n",
1515
"Container Size: medium <br>\n",
1616
"Targeted learning level: beginner <br>"
@@ -445,7 +445,7 @@
445445
" # from_resource: creates a instance from\n",
446446
" # a number of records and a Datalink Resource.\n",
447447
" sq = SodaQuery.from_resource(dl,\n",
448-
" dl.get_adhocservice_by_id(\"cutout-sync\"),\n",
448+
" dl.get_adhocservice_by_id(\"cutout-sync-exposure\"),\n",
449449
" session=auth_session)\n",
450450
"\n",
451451
" sq.circle = (spherePoint.getRa().asDegrees() * u.deg,\n",
@@ -753,7 +753,7 @@
753753
"outputs": [],
754754
"source": [
755755
"sq = SodaQuery.from_resource(dl_results,\n",
756-
" dl_results.get_adhocservice_by_id(\"cutout-sync\"),\n",
756+
" dl_results.get_adhocservice_by_id(\"cutout-sync-exposure\"),\n",
757757
" session=auth_session)"
758758
]
759759
},
@@ -916,7 +916,7 @@
916916
"outputs": [],
917917
"source": [
918918
"sq2 = SodaQuery.from_resource(dl_results,\n",
919-
" dl_results.get_adhocservice_by_id(\"cutout-sync\"),\n",
919+
" dl_results.get_adhocservice_by_id(\"cutout-sync-exposure\"),\n",
920920
" session=auth_session)\n",
921921
"sphereRadius1 = 0.03 * u.deg\n",
922922
"sphereRadius2 = 0.01 * u.deg\n",

DP0.2/18_Galaxy_Photometry.ipynb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"<img align=\"left\" src = https://noirlab.edu/public/media/archives/logos/svg/logo250.svg width=250 style=\"background-color:white; padding:10px\" alt=\"Rubin Observatory logo, a graphical representation of turning stars into data.\">\n",
1414
"</div>\n",
1515
"Contact author(s): Christina Williams <br>\n",
16-
"Last verified to run: 2025-09-02 <br>\n",
16+
"Last verified to run: 2025-12-14 <br>\n",
1717
"LSST Science Pipelines version: r29.2.0 <br>\n",
1818
"Container Size: medium <br>"
1919
]
@@ -327,7 +327,7 @@
327327
" session=auth_session)\n",
328328
"\n",
329329
" sq = SodaQuery.from_resource(dl,\n",
330-
" dl.get_adhocservice_by_id(\"cutout-sync\"),\n",
330+
" dl.get_adhocservice_by_id(\"cutout-sync-exposure\"),\n",
331331
" session=auth_session)\n",
332332
"\n",
333333
" sq.circle = (spherePoint.getRa().asDegrees() * u.deg,\n",

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

Lines changed: 149 additions & 21 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-16 <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,9 @@
324328
"id": "d945e191-7ee4-458a-bb0f-fb00cd219e30",
325329
"metadata": {},
326330
"source": [
327-
"Lastly, call the Rubin Image Cutout Service. This is the IVOA procedure `cutout-sync` that 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."
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",
332+
"\n",
333+
"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."
328334
]
329335
},
330336
{
@@ -335,7 +341,7 @@
335341
"outputs": [],
336342
"source": [
337343
"sq = SodaQuery.from_resource(dl_result,\n",
338-
" dl_result.get_adhocservice_by_id(\"cutout-sync\"),\n",
344+
" dl_result.get_adhocservice_by_id(\"cutout-sync-exposure\"),\n",
339345
" session=get_pyvo_auth())"
340346
]
341347
},
@@ -386,15 +392,15 @@
386392
"sq.raise_if_error()\n",
387393
"mem = MemFileManager(len(cutout_bytes))\n",
388394
"mem.setData(cutout_bytes, len(cutout_bytes))\n",
389-
"exposure = ExposureF(mem)"
395+
"exposure = ExposureF(mem)\n"
390396
]
391397
},
392398
{
393399
"cell_type": "markdown",
394400
"id": "324be87a-337b-4db7-b57d-842f14614613",
395401
"metadata": {},
396402
"source": [
397-
"Display the cutout."
403+
"Display the image extension of the `ExposureF` cutout."
398404
]
399405
},
400406
{
@@ -468,8 +474,6 @@
468474
"metadata": {},
469475
"outputs": [],
470476
"source": [
471-
"# from astropy.io import fits\n",
472-
"\n",
473477
"# fits.info(sodaCutout)\n",
474478
"\n",
475479
"# sodaCutout_small = os.path.join(tempdir, 'cutout-circle_small.fits')\n",
@@ -502,7 +506,7 @@
502506
"outputs": [],
503507
"source": [
504508
"sqp = SodaQuery.from_resource(dl_result,\n",
505-
" dl_result.get_adhocservice_by_id(\"cutout-sync\"),\n",
509+
" dl_result.get_adhocservice_by_id(\"cutout-sync-exposure\"),\n",
506510
" session=get_pyvo_auth())\n",
507511
"\n",
508512
"ra_edge = 0.02 * u.deg\n",
@@ -565,7 +569,7 @@
565569
"outputs": [],
566570
"source": [
567571
"sq2 = SodaQuery.from_resource(dl_result,\n",
568-
" dl_result.get_adhocservice_by_id(\"cutout-sync\"),\n",
572+
" dl_result.get_adhocservice_by_id(\"cutout-sync-exposure\"),\n",
569573
" session=get_pyvo_auth())\n",
570574
"\n",
571575
"edge1 = Radius\n",
@@ -604,7 +608,7 @@
604608
"cosd = np.cos(a.radian)\n",
605609
"\n",
606610
"sq3 = SodaQuery.from_resource(dl_result,\n",
607-
" dl_result.get_adhocservice_by_id(\"cutout-sync\"),\n",
611+
" dl_result.get_adhocservice_by_id(\"cutout-sync-exposure\"),\n",
608612
" session=get_pyvo_auth())\n",
609613
"\n",
610614
"sq3.polygon = (spherePoint.getRa().asDegrees() * u.deg - edge1/cosd,\n",
@@ -674,6 +678,138 @@
674678
"The zooniverse package should be used instead of this procedure for citizen science applications. "
675679
]
676680
},
681+
{
682+
"cell_type": "markdown",
683+
"id": "99e75a7a-348e-409e-88f6-871b68a4e9dc",
684+
"metadata": {},
685+
"source": [
686+
"## 4. Single extension image cutouts\n",
687+
"\n",
688+
"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",
689+
"\n",
690+
"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"
691+
]
692+
},
693+
{
694+
"cell_type": "code",
695+
"execution_count": null,
696+
"id": "837fbd2a-c3e2-4ee3-a06d-69f4df50823b",
697+
"metadata": {},
698+
"outputs": [],
699+
"source": [
700+
"sq4 = SodaQuery.from_resource(dl_result,\n",
701+
" dl_result.get_adhocservice_by_id(\"cutout-sync\"),\n",
702+
" session=get_pyvo_auth())\n",
703+
"\n",
704+
"spherePoint = geom.SpherePoint(target_ra*geom.degrees, target_dec*geom.degrees)\n",
705+
"Radius = 0.01 * u.deg\n",
706+
"\n",
707+
"sq4.circle = (spherePoint.getRa().asDegrees() * u.deg,\n",
708+
" spherePoint.getDec().asDegrees() * u.deg,\n",
709+
" Radius)\n",
710+
"\n",
711+
"cutout_bytes = sq4.execute_stream().read()\n",
712+
"sq4.raise_if_error()\n"
713+
]
714+
},
715+
{
716+
"cell_type": "markdown",
717+
"id": "454a017b-df88-48cc-975e-cac4ff3a37b5",
718+
"metadata": {},
719+
"source": [
720+
"Receive the cutout into memory, as in Section 3."
721+
]
722+
},
723+
{
724+
"cell_type": "code",
725+
"execution_count": null,
726+
"id": "516dbd86-d573-4d81-a017-2ebbce8fb445",
727+
"metadata": {},
728+
"outputs": [],
729+
"source": [
730+
"mem = MemFileManager(len(cutout_bytes))\n",
731+
"mem.setData(cutout_bytes, len(cutout_bytes))\n"
732+
]
733+
},
734+
{
735+
"cell_type": "markdown",
736+
"id": "2ae72a88-8002-46b5-8eee-164a2c903314",
737+
"metadata": {},
738+
"source": [
739+
"Use the `getData` method from the `MemFileManager` class to return and store the bytes associated with the cutout. "
740+
]
741+
},
742+
{
743+
"cell_type": "code",
744+
"execution_count": null,
745+
"id": "ed3f7908-a256-42f5-939f-61f38645c7ca",
746+
"metadata": {},
747+
"outputs": [],
748+
"source": [
749+
"data = mem.getData()"
750+
]
751+
},
752+
{
753+
"cell_type": "markdown",
754+
"id": "441a49fb-42be-4f37-853e-141419f1da14",
755+
"metadata": {},
756+
"source": [
757+
"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. "
758+
]
759+
},
760+
{
761+
"cell_type": "code",
762+
"execution_count": null,
763+
"id": "d23a0397-6500-4e36-b956-7917ed6a7173",
764+
"metadata": {},
765+
"outputs": [],
766+
"source": [
767+
"hdul = fits.open(io.BytesIO(data))\n",
768+
"hdul.info()\n",
769+
"\n",
770+
"image_hdu = hdul[1]\n",
771+
"image_data = image_hdu.data\n"
772+
]
773+
},
774+
{
775+
"cell_type": "markdown",
776+
"id": "c0eea8e5-ae86-456d-9d67-798557a4a707",
777+
"metadata": {},
778+
"source": [
779+
"To enable image display, first store `image_data` as an LSST `ImageF` object."
780+
]
781+
},
782+
{
783+
"cell_type": "code",
784+
"execution_count": null,
785+
"id": "78e1c658-916c-4a73-8c0b-a50d281f4764",
786+
"metadata": {},
787+
"outputs": [],
788+
"source": [
789+
"image = afwImage.ImageF(image_data.astype(\"float32\"))\n"
790+
]
791+
},
792+
{
793+
"cell_type": "markdown",
794+
"id": "6a19e7cd-4096-44b9-832f-baa6b6c40482",
795+
"metadata": {},
796+
"source": [
797+
"Display the image cutout."
798+
]
799+
},
800+
{
801+
"cell_type": "code",
802+
"execution_count": null,
803+
"id": "1aa9009a-b493-41ea-bc3c-e0c79adef913",
804+
"metadata": {},
805+
"outputs": [],
806+
"source": [
807+
"display = afwDisplay.Display()\n",
808+
"display.scale('asinh', 'zscale')\n",
809+
"display.image(image)\n",
810+
"plt.show()"
811+
]
812+
},
677813
{
678814
"attachments": {
679815
"923e951d-30c0-4a8f-a1b0-8bb851f1cb5f.png": {
@@ -684,7 +820,7 @@
684820
"id": "acbe9638-e7b7-4229-8301-3f57eb0b0c5b",
685821
"metadata": {},
686822
"source": [
687-
"## 4. Exercise for the learner\n",
823+
"## 5. Exercise for the learner\n",
688824
"\n",
689825
"Reproduce the cutout below, whose center is (ra, dec) = 59.1, -48.8 with 0.06 degrees on a side.\n",
690826
"\n",
@@ -694,14 +830,6 @@
694830
"\n",
695831
"</div>\n"
696832
]
697-
},
698-
{
699-
"cell_type": "code",
700-
"execution_count": null,
701-
"id": "6b611f9f-aaa5-4e2b-b4a5-b7acc6aecbf9",
702-
"metadata": {},
703-
"outputs": [],
704-
"source": []
705833
}
706834
],
707835
"metadata": {

DP1/200_Data_Products/203_Maps/203_1_Survey_property_maps.ipynb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
"Data Release: <a href=\"https://dp1.lsst.io/\">Data Preview 1</a> <br>\n",
2323
"Container Size: large <br>\n",
2424
"LSST Science Pipelines version: r29.2.0 <br>\n",
25-
"Last verified to run: 2025-09-02 <br>\n",
25+
"Last verified to run: 2025-12-17 <br>\n",
2626
"Repository: <a href=\"https://github.com/lsst/tutorial-notebooks\">github.com/lsst/tutorial-notebooks</a> <br>"
2727
]
2828
},
@@ -653,6 +653,7 @@
653653
"metadata": {},
654654
"outputs": [],
655655
"source": [
656+
"# from astropy.wcs import WCS\n",
656657
"# temp = deep_coadd.image.array.flatten()\n",
657658
"# norm = ImageNormalize(temp, interval=ZScaleInterval(),\n",
658659
"# stretch=LinearStretch())\n",

DP1/300_Science_Demos/303_Galaxies/303_2_Galaxy_Shapes.ipynb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
"Data Release: <a href=\"https://dp1.lsst.io/\">Data Preview 1</a> <br>\n",
2323
"Container Size: Large <br>\n",
2424
"LSST Science Pipelines version: r29.2.0 <br>\n",
25-
"Last verified to run: 2025-09-02 <br>\n",
25+
"Last verified to run: 2025-12-11 <br>\n",
2626
"Repository: <a href=\"https://github.com/lsst/tutorial-notebooks\">github.com/lsst/tutorial-notebooks</a> <br>"
2727
]
2828
},
@@ -170,7 +170,7 @@
170170
" dl = DatalinkResults.from_result_url(datalink_url, session=get_pyvo_auth())\n",
171171
"\n",
172172
" sq = SodaQuery.from_resource(dl,\n",
173-
" dl.get_adhocservice_by_id(\"cutout-sync\"),\n",
173+
" dl.get_adhocservice_by_id(\"cutout-sync-exposure\"),\n",
174174
" session=get_pyvo_auth())\n",
175175
"\n",
176176
" sq.circle = (spherePoint.getRa().asDegrees() * u.deg,\n",

DP1/300_Science_Demos/306_Extragalactic_transients/306_2_Candidate_transient_identification.ipynb

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
"Data Release: <a href=\"https://dp1.lsst.io/\">Data Preview 1</a> <br>\n",
2323
"Container Size: large <br>\n",
2424
"LSST Science Pipelines version: r29.2.0 <br>\n",
25-
"Last verified to run: 2025-09-17 <br>\n",
25+
"Last verified to run: 2025-12-11 <br>\n",
2626
"Repository: <a href=\"https://github.com/lsst/tutorial-notebooks\">github.com/lsst/tutorial-notebooks</a> <br>"
2727
]
2828
},
@@ -587,7 +587,7 @@
587587
"source": [
588588
"def get_cutout(dl_result, spherePoint, session, fov):\n",
589589
" sq = SodaQuery.from_resource(dl_result,\n",
590-
" dl_result.get_adhocservice_by_id(\"cutout-sync\"),\n",
590+
" dl_result.get_adhocservice_by_id(\"cutout-sync-exposure\"),\n",
591591
" session=session)\n",
592592
" sphereRadius = fov * u.deg\n",
593593
" sq.circle = (spherePoint.getRa().asDegrees() * u.deg,\n",
@@ -839,14 +839,6 @@
839839
"source": [
840840
"> **Figure 4**: The cutout triplet for the first detection of this `DiaObject`, a candidate SN Ia."
841841
]
842-
},
843-
{
844-
"cell_type": "code",
845-
"execution_count": null,
846-
"id": "89ed684b-147e-4ed5-a340-205491c0f096",
847-
"metadata": {},
848-
"outputs": [],
849-
"source": []
850842
}
851843
],
852844
"metadata": {

0 commit comments

Comments
 (0)