Skip to content

Commit c661dd5

Browse files
committed
added tutorial on using dicomweb
see details in https://learn.canceridc.dev/data/downloading-data/dicomweb-access
1 parent 9bfd4bc commit c661dd5

File tree

1 file changed

+322
-0
lines changed

1 file changed

+322
-0
lines changed
Lines changed: 322 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,322 @@
1+
{
2+
"nbformat": 4,
3+
"nbformat_minor": 0,
4+
"metadata": {
5+
"colab": {
6+
"provenance": [],
7+
"toc_visible": true,
8+
"include_colab_link": true
9+
},
10+
"kernelspec": {
11+
"name": "python3",
12+
"display_name": "Python 3"
13+
},
14+
"language_info": {
15+
"name": "python"
16+
}
17+
},
18+
"cells": [
19+
{
20+
"cell_type": "markdown",
21+
"metadata": {
22+
"id": "view-in-github",
23+
"colab_type": "text"
24+
},
25+
"source": [
26+
"<a href=\"https://colab.research.google.com/github/ImagingDataCommons/IDC-Tutorials/blob/master/notebooks/advanced_topics/idc_dicomweb_access.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
27+
]
28+
},
29+
{
30+
"cell_type": "markdown",
31+
"source": [
32+
"# IDC DICOMweb data access for pathology whole-slide images\n",
33+
"\n",
34+
"This notebook accompanies the documentation article [IDC DICOMweb data access\n",
35+
"](tbd) for the NCI Imaging Data Commons, which describes how one can access IDC pathology data using DICOMweb.\n",
36+
"\n",
37+
"This notebook solely replicates the content of the code cells from the documentation article above for convenience. Please read the actual article for details!\n",
38+
"\n",
39+
"Questions? Ask those at the IDC forum here: https://discourse.canceridc.dev.\n",
40+
"\n",
41+
"-----\n",
42+
"Created: July 2025"
43+
],
44+
"metadata": {
45+
"id": "JLAWcB6NSqBG"
46+
}
47+
},
48+
{
49+
"cell_type": "code",
50+
"source": [
51+
"%%capture\n",
52+
"!pip install idc-index --upgrade\n",
53+
"!pip install wsidicom\n",
54+
"!pip install ez-wsi-dicomweb"
55+
],
56+
"metadata": {
57+
"collapsed": true,
58+
"id": "qw8w0h0CzSDK"
59+
},
60+
"execution_count": null,
61+
"outputs": []
62+
},
63+
{
64+
"cell_type": "markdown",
65+
"source": [
66+
"## Unique identifiers: locating the relevant slides"
67+
],
68+
"metadata": {
69+
"id": "1NbBaRk5B15N"
70+
}
71+
},
72+
{
73+
"cell_type": "code",
74+
"source": [
75+
"from idc_index import IDCClient\n",
76+
"\n",
77+
"# Instantiate the client\n",
78+
"idc_client = IDCClient()\n",
79+
"idc_client.fetch_index('sm_index')\n",
80+
"\n",
81+
"\n",
82+
"# Filter the slides\n",
83+
"query = \"\"\"\n",
84+
"SELECT index.StudyInstanceUID, sm_index.SeriesInstanceUID\n",
85+
"FROM sm_index\n",
86+
"JOIN index ON sm_index.SeriesInstanceUID = index.SeriesInstanceUID\n",
87+
"WHERE Modality = 'SM' AND primaryAnatomicStructure_CodeMeaning = 'Pancreas'\n",
88+
"\"\"\"\n",
89+
"\n",
90+
"pancreas_slides = idc_client.sql_query(query)\n",
91+
"\n",
92+
"sample_study_uid = pancreas_slides['StudyInstanceUID'][0]\n",
93+
"sample_series_uid = pancreas_slides['SeriesInstanceUID'][0]\n",
94+
"sample_study_uid, sample_series_uid"
95+
],
96+
"metadata": {
97+
"id": "FFaUM4k4B8Ce"
98+
},
99+
"execution_count": null,
100+
"outputs": []
101+
},
102+
{
103+
"cell_type": "markdown",
104+
"source": [
105+
"## wsidicom"
106+
],
107+
"metadata": {
108+
"id": "yv07GVcvKlOr"
109+
}
110+
},
111+
{
112+
"cell_type": "code",
113+
"source": [
114+
"from dicomweb_client.api import DICOMwebClient\n",
115+
"from dicomweb_client.ext.gcp.session_utils import create_session_from_gcp_credentials"
116+
],
117+
"metadata": {
118+
"id": "hiX_D1uvK0b9"
119+
},
120+
"execution_count": null,
121+
"outputs": []
122+
},
123+
{
124+
"cell_type": "markdown",
125+
"source": [
126+
"###If accessing Google-maintained DICOM store run the following cell"
127+
],
128+
"metadata": {
129+
"id": "zv49l-rd9WJd"
130+
}
131+
},
132+
{
133+
"cell_type": "code",
134+
"source": [
135+
"# If accessing the Google-maintained DICOM store, you need to authenticate with your Google credentials first\n",
136+
"from google.colab import auth\n",
137+
"auth.authenticate_user()\n",
138+
"\n",
139+
"# Create session and build path to DICOM store\n",
140+
"session = create_session_from_gcp_credentials()\n",
141+
"\n",
142+
"# Set-up a DICOMwebClient using the dicomweb_client library\n",
143+
"google_dicom_store_url = 'https://healthcare.googleapis.com/v1/projects/nci-idc-data/locations/us-central1/datasets/idc/dicomStores/idc-store-v20/dicomWeb'\n",
144+
"dw_client = DICOMwebClient(\n",
145+
" url=google_dicom_store_url,\n",
146+
" session = session\n",
147+
")"
148+
],
149+
"metadata": {
150+
"id": "5O__Mxb2NdcM"
151+
},
152+
"execution_count": null,
153+
"outputs": []
154+
},
155+
{
156+
"cell_type": "markdown",
157+
"source": [
158+
"###If accessing IDC-maintained DICOM store run the following cell"
159+
],
160+
"metadata": {
161+
"id": "a_FjalAa9dNk"
162+
}
163+
},
164+
{
165+
"cell_type": "code",
166+
"source": [
167+
"# Set-up a DICOMwebClient using the dicomweb_client library\n",
168+
"idc_dicom_store_url = 'https://proxy.imaging.datacommons.cancer.gov/current/viewer-only-no-downloads-see-tinyurl-dot-com-slash-3j3d9jyp/dicomWeb'\n",
169+
"dw_client = DICOMwebClient(url=idc_dicom_store_url)"
170+
],
171+
"metadata": {
172+
"id": "OIuQct5m1pmM"
173+
},
174+
"execution_count": null,
175+
"outputs": []
176+
},
177+
{
178+
"cell_type": "markdown",
179+
"source": [
180+
"### Access"
181+
],
182+
"metadata": {
183+
"id": "e97NkrwOKq6G"
184+
}
185+
},
186+
{
187+
"cell_type": "code",
188+
"execution_count": null,
189+
"metadata": {
190+
"id": "vwySAwarzLjP"
191+
},
192+
"outputs": [],
193+
"source": [
194+
"import wsidicom\n",
195+
"import matplotlib.pyplot as plt"
196+
]
197+
},
198+
{
199+
"cell_type": "code",
200+
"source": [
201+
"# Wrap into wsidicom client\n",
202+
"wsidicom_client = wsidicom.WsiDicomWebClient(dw_client)\n",
203+
"\n",
204+
"# Open the slide via DICOMweb interface of wsidicom\n",
205+
"slide = wsidicom.WsiDicom.open_web(wsidicom_client,\n",
206+
" study_uid = sample_study_uid,\n",
207+
" series_uids = sample_series_uid\n",
208+
")\n",
209+
"# Investigate existing levels and their dimensions\n",
210+
"print(slide)"
211+
],
212+
"metadata": {
213+
"id": "1HDlzeVJ2Wqr"
214+
},
215+
"execution_count": null,
216+
"outputs": []
217+
},
218+
{
219+
"cell_type": "code",
220+
"source": [
221+
"# Access and visualize 500x500px subregion at level 4, starting from pixel (1000,1000)\n",
222+
"region = slide.read_region(location=(1000, 1000), level=4, size=(500, 500))\n",
223+
"plt.imshow(region)\n",
224+
"plt.show()"
225+
],
226+
"metadata": {
227+
"id": "Jo3cwjp0GTpm"
228+
},
229+
"execution_count": null,
230+
"outputs": []
231+
},
232+
{
233+
"cell_type": "markdown",
234+
"source": [
235+
"## ez-wsi-dicomweb"
236+
],
237+
"metadata": {
238+
"id": "kOWYqh04STgt"
239+
}
240+
},
241+
{
242+
"cell_type": "code",
243+
"source": [
244+
"from ez_wsi_dicomweb import dicomweb_credential_factory\n",
245+
"from ez_wsi_dicomweb import dicom_slide\n",
246+
"from ez_wsi_dicomweb import local_dicom_slide_cache_types\n",
247+
"from ez_wsi_dicomweb import dicom_web_interface\n",
248+
"from ez_wsi_dicomweb import patch_generator\n",
249+
"from ez_wsi_dicomweb import pixel_spacing\n",
250+
"from ez_wsi_dicomweb.ml_toolkit import dicom_path"
251+
],
252+
"metadata": {
253+
"id": "2f0qtLvUKmdB"
254+
},
255+
"execution_count": null,
256+
"outputs": []
257+
},
258+
{
259+
"cell_type": "code",
260+
"source": [
261+
"from google.colab import auth\n",
262+
"auth.authenticate_user()\n",
263+
"\n",
264+
"google_dicom_store_url = 'https://healthcare.googleapis.com/v1/projects/nci-idc-data/locations/us-central1/datasets/idc/dicomStores/idc-store-v21/dicomWeb'\n",
265+
"\n",
266+
"series_path_str = (\n",
267+
" f'{google_dicom_store_url}'\n",
268+
" f'/studies/{sample_study_uid}'\n",
269+
" f'/series/{sample_series_uid}'\n",
270+
")\n",
271+
"series_path = dicom_path.FromString(series_path_str)\n",
272+
"dcf = dicomweb_credential_factory.CredentialFactory()\n",
273+
"dwi = dicom_web_interface.DicomWebInterface(dcf)\n",
274+
"\n",
275+
"ds = dicom_slide.DicomSlide(\n",
276+
" dwi=dwi,\n",
277+
" path=series_path,\n",
278+
" enable_client_slide_frame_decompression = True\n",
279+
" )\n",
280+
"\n",
281+
"# Enable slide frame cache. More information: https://github.com/GoogleCloudPlatform/EZ-WSI-DICOMweb/blob/main/ez_wsi_demo.ipynb\n",
282+
"ds.init_slide_frame_cache(\n",
283+
" optimization_hint=local_dicom_slide_cache_types.CacheConfigOptimizationHint.MINIMIZE_LATENCY\n",
284+
" )"
285+
],
286+
"metadata": {
287+
"id": "DE8jWIbsS6lk"
288+
},
289+
"execution_count": null,
290+
"outputs": []
291+
},
292+
{
293+
"cell_type": "code",
294+
"source": [
295+
"# Investigate existing levels and their dimensions\n",
296+
"for level in ds.levels:\n",
297+
" print(f'Level {level.level_index} has pixel dimensions (row, col): {level.height, level.width}')"
298+
],
299+
"metadata": {
300+
"id": "CzSufDglVc78"
301+
},
302+
"execution_count": null,
303+
"outputs": []
304+
},
305+
{
306+
"cell_type": "code",
307+
"source": [
308+
"# Access and visualize 500x500px subregion at level 3, starting from pixel (1000,1000)\n",
309+
"\n",
310+
"level = ds.get_level_by_index(3)\n",
311+
"region = ds.get_patch(level=level, x=1000, y=1000, width=500, height=500).image_bytes()\n",
312+
"plt.imshow(region)\n",
313+
"plt.show()"
314+
],
315+
"metadata": {
316+
"id": "oH-b-ntlUB1O"
317+
},
318+
"execution_count": null,
319+
"outputs": []
320+
}
321+
]
322+
}

0 commit comments

Comments
 (0)