Skip to content

Commit 00d0a48

Browse files
Merge pull request #176 from AnthonyAndroulakis/afni
Add afni.ipynb notebook example
2 parents 2017312 + 077b2b3 commit 00d0a48

File tree

13 files changed

+620
-31
lines changed

13 files changed

+620
-31
lines changed

docs/source/api.rst

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,22 @@
11
API Documentation
22
=================
33

4-
.. autoclass:: ipyniivue.widget.NiiVue
4+
.. autoclass:: ipyniivue.NiiVue
55
:members:
66
:undoc-members:
77
:show-inheritance:
88

9-
.. autoclass:: ipyniivue.widget.Volume
9+
.. autoclass:: ipyniivue.Volume
1010
:members:
1111
:undoc-members:
1212
:show-inheritance:
1313

14-
.. autoclass:: ipyniivue.widget.Mesh
14+
.. autoclass:: ipyniivue.Mesh
1515
:members:
1616
:undoc-members:
1717
:show-inheritance:
1818

19-
.. autoclass:: ipyniivue.widget.MeshLayer
20-
:members:
21-
:undoc-members:
22-
:show-inheritance:
23-
24-
.. autoclass:: ipyniivue.traits.ColorMap
25-
:members:
26-
:undoc-members:
27-
:show-inheritance:
28-
29-
.. autoclass:: ipyniivue.traits.LUT
19+
.. autoclass:: ipyniivue.MeshLayer
3020
:members:
3121
:undoc-members:
3222
:show-inheritance:

docs/source/enums.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Enums
22
=====
33

4-
.. currentmodule:: ipyniivue.constants
4+
.. currentmodule:: ipyniivue
55

66
.. autoclass:: DragMode
77
:members:

docs/source/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@ A Jupyter Widget for Niivue based on anywidget.
1010
install
1111
api
1212
options
13+
traits
1314
enums
1415
contributing

docs/source/traits.rst

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Traits
2+
======
3+
4+
.. currentmodule:: ipyniivue
5+
6+
.. autoclass:: ColorMap
7+
:members:
8+
:undoc-members:
9+
:show-inheritance:
10+
11+
.. autoclass:: LUT
12+
:members:
13+
:undoc-members:
14+
:show-inheritance:
15+
16+
.. autoclass:: Graph
17+
:members:
18+
:undoc-members:
19+
:show-inheritance:

examples/afni.ipynb

Lines changed: 280 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,280 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"id": "8ac54f8d-2d2c-4e57-a8a1-a1a1463b6451",
6+
"metadata": {},
7+
"source": [
8+
"# Import necessary modules"
9+
]
10+
},
11+
{
12+
"cell_type": "code",
13+
"execution_count": null,
14+
"id": "e57b7f74-2402-4580-a3c9-bd1dbb3b8cdc",
15+
"metadata": {},
16+
"outputs": [],
17+
"source": [
18+
"import asyncio\n",
19+
"import pathlib\n",
20+
"\n",
21+
"import ipywidgets as widgets\n",
22+
"from IPython.display import display\n",
23+
"\n",
24+
"import ipyniivue\n",
25+
"from ipyniivue import NiiVue, ShowRender, SliceType, download_dataset"
26+
]
27+
},
28+
{
29+
"cell_type": "markdown",
30+
"id": "b000ac63-b5b8-4258-b1be-e83868675c25",
31+
"metadata": {},
32+
"source": [
33+
"# Download required data"
34+
]
35+
},
36+
{
37+
"cell_type": "code",
38+
"execution_count": null,
39+
"id": "8f176e83",
40+
"metadata": {},
41+
"outputs": [],
42+
"source": [
43+
"DATA_FOLDER = pathlib.Path(ipyniivue.__file__).parent / \"images\"\n",
44+
"\n",
45+
"download_dataset(\n",
46+
" api_url=\"https://niivue.com/demos/images/\",\n",
47+
" dest_folder=DATA_FOLDER,\n",
48+
" files=[\n",
49+
" \"example4d+orig.HEAD\",\n",
50+
" \"example4d+orig.BRIK.gz\",\n",
51+
" ],\n",
52+
")"
53+
]
54+
},
55+
{
56+
"cell_type": "markdown",
57+
"id": "a3678fb5-65b1-4528-9a74-d7f27c62c8df",
58+
"metadata": {},
59+
"source": [
60+
"# Create the NiiVue widget"
61+
]
62+
},
63+
{
64+
"cell_type": "code",
65+
"execution_count": null,
66+
"id": "a873dc99-8c09-4518-a053-c6a4720aff8d",
67+
"metadata": {},
68+
"outputs": [],
69+
"source": [
70+
"nv = NiiVue()\n",
71+
"\n",
72+
"nv.set_radiological_convention(False)\n",
73+
"nv.set_slice_type(SliceType.MULTIPLANAR)\n",
74+
"nv.opts.multiplanar_show_render = ShowRender.ALWAYS\n",
75+
"\n",
76+
"# Configure graph values\n",
77+
"nv.graph.auto_size_multiplanar = True\n",
78+
"nv.graph.normalize_values = False\n",
79+
"nv.graph.opacity = 1.0\n",
80+
"\n",
81+
"# Load 4D volume with paired HEAD and BRIK files\n",
82+
"nv.load_volumes(\n",
83+
" [\n",
84+
" {\n",
85+
" \"path\": DATA_FOLDER / \"example4d+orig.HEAD\",\n",
86+
" \"paired_img_path\": DATA_FOLDER / \"example4d+orig.BRIK.gz\",\n",
87+
" \"colormap\": \"gray\",\n",
88+
" \"opacity\": 1.0,\n",
89+
" \"visible\": True,\n",
90+
" },\n",
91+
" ]\n",
92+
")"
93+
]
94+
},
95+
{
96+
"cell_type": "markdown",
97+
"id": "dd0e9aee-0bdb-4eba-829c-e6e5acd68835",
98+
"metadata": {},
99+
"source": [
100+
"# Create other buttons/checkboxes"
101+
]
102+
},
103+
{
104+
"cell_type": "code",
105+
"execution_count": null,
106+
"id": "3fd88e96-ca86-4b36-92eb-1e1f2d80f8ed",
107+
"metadata": {},
108+
"outputs": [],
109+
"source": [
110+
"display_frame = widgets.Label(value=\"Volume: 0\")\n",
111+
"\n",
112+
"normalize_checkbox = widgets.Checkbox(\n",
113+
" value=False,\n",
114+
" description=\"Normalize Graph\",\n",
115+
")\n",
116+
"\n",
117+
"prev_button = widgets.Button(description=\"Back\")\n",
118+
"next_button = widgets.Button(description=\"Forward\")"
119+
]
120+
},
121+
{
122+
"cell_type": "markdown",
123+
"id": "111a97d2-714e-47ae-81b8-80c44f6726a9",
124+
"metadata": {},
125+
"source": [
126+
"# Implement the callbacks"
127+
]
128+
},
129+
{
130+
"cell_type": "code",
131+
"execution_count": null,
132+
"id": "167128f8-a16a-43bd-803f-da10f08c0d4d",
133+
"metadata": {},
134+
"outputs": [],
135+
"source": [
136+
"def on_normalize_change(change):\n",
137+
" \"\"\"Normalize graph.\"\"\"\n",
138+
" nv.graph.normalize_values = change[\"new\"]\n",
139+
"\n",
140+
"\n",
141+
"normalize_checkbox.observe(on_normalize_change, names=\"value\")\n",
142+
"\n",
143+
"\n",
144+
"def on_prev_button_clicked(b):\n",
145+
" \"\"\"Decrement the frame index.\"\"\"\n",
146+
" if nv.volumes:\n",
147+
" current_frame = nv.volumes[0].frame4D\n",
148+
" new_frame = max(current_frame - 1, 0)\n",
149+
" nv.volumes[0].frame4D = new_frame\n",
150+
" display_frame.value = f\"Volume: {new_frame}\"\n",
151+
"\n",
152+
"\n",
153+
"def on_next_button_clicked(b):\n",
154+
" \"\"\"Increment the frame index.\"\"\"\n",
155+
" if nv.volumes:\n",
156+
" current_frame = nv.volumes[0].frame4D\n",
157+
" n_frames = nv.volumes[0].n_frame4D\n",
158+
" new_frame = min(current_frame + 1, n_frames - 1)\n",
159+
" nv.volumes[0].frame4D = new_frame\n",
160+
" display_frame.value = f\"Volume: {new_frame}\"\n",
161+
"\n",
162+
"\n",
163+
"prev_button.on_click(on_prev_button_clicked)\n",
164+
"next_button.on_click(on_next_button_clicked)"
165+
]
166+
},
167+
{
168+
"cell_type": "markdown",
169+
"id": "b310d908-6f11-4d66-83fa-117af002799e",
170+
"metadata": {},
171+
"source": [
172+
"# Create animate button"
173+
]
174+
},
175+
{
176+
"cell_type": "code",
177+
"execution_count": null,
178+
"id": "24726cb0-0d09-4e98-a16c-630d3b746cd3",
179+
"metadata": {},
180+
"outputs": [],
181+
"source": [
182+
"animate_button = widgets.Button(description=\"Animate\")\n",
183+
"\n",
184+
"animation_running = False\n",
185+
"animation_task = None\n",
186+
"\n",
187+
"\n",
188+
"async def animate_frames():\n",
189+
" \"\"\"Animation loop.\"\"\"\n",
190+
" global animation_running\n",
191+
" if not nv.volumes:\n",
192+
" return\n",
193+
" n_frames = nv.volumes[0].n_frame4D\n",
194+
" try:\n",
195+
" while animation_running:\n",
196+
" current_frame = nv.volumes[0].frame4D\n",
197+
" current_frame = (current_frame + 1) % n_frames\n",
198+
" nv.volumes[0].frame4D = current_frame\n",
199+
" display_frame.value = f\"Volume: {current_frame}\"\n",
200+
" await asyncio.sleep(0.1)\n",
201+
" except asyncio.CancelledError:\n",
202+
" pass\n",
203+
"\n",
204+
"\n",
205+
"def on_animate_button_clicked(b):\n",
206+
" \"\"\"Define 'Animate' button click handler.\"\"\"\n",
207+
" global animation_running, animation_task\n",
208+
" if not animation_running:\n",
209+
" # Start animation\n",
210+
" animation_running = True\n",
211+
" animate_button.description = \"Stop\"\n",
212+
" # Schedule the animation coroutine and store the future\n",
213+
" animation_task = asyncio.ensure_future(animate_frames())\n",
214+
" else:\n",
215+
" # Stop animation\n",
216+
" animation_running = False\n",
217+
" animate_button.description = \"Animate\"\n",
218+
" # Cancel the running task if it's active\n",
219+
" if animation_task is not None:\n",
220+
" animation_task.cancel()\n",
221+
" animation_task = None\n",
222+
"\n",
223+
"\n",
224+
"animate_button.on_click(on_animate_button_clicked)"
225+
]
226+
},
227+
{
228+
"cell_type": "markdown",
229+
"id": "5f6f5a15-6b36-4312-b735-10e185900c19",
230+
"metadata": {},
231+
"source": [
232+
"# Reset frame index on image loaded"
233+
]
234+
},
235+
{
236+
"cell_type": "code",
237+
"execution_count": null,
238+
"id": "71ba69a0-6fe0-48a7-a03b-29822e24d676",
239+
"metadata": {},
240+
"outputs": [],
241+
"source": [
242+
"@nv.on_image_loaded\n",
243+
"def update_number_of_frames(volume):\n",
244+
" \"\"\"Reset to first frame.\"\"\"\n",
245+
" nv.volumes[0].frame4D = 0\n",
246+
" display_frame.value = \"Volume: 0\""
247+
]
248+
},
249+
{
250+
"cell_type": "markdown",
251+
"id": "906aee0a-cb57-46b6-9808-a8ac5443a408",
252+
"metadata": {},
253+
"source": [
254+
"# Display all"
255+
]
256+
},
257+
{
258+
"cell_type": "code",
259+
"execution_count": null,
260+
"id": "44999f74-851a-40c7-aee1-84a65aeb69b0",
261+
"metadata": {},
262+
"outputs": [],
263+
"source": [
264+
"controls = widgets.HBox(\n",
265+
" [\n",
266+
" normalize_checkbox,\n",
267+
" prev_button,\n",
268+
" next_button,\n",
269+
" animate_button,\n",
270+
" ]\n",
271+
")\n",
272+
"\n",
273+
"display(widgets.VBox([controls, display_frame, nv]))"
274+
]
275+
}
276+
],
277+
"metadata": {},
278+
"nbformat": 4,
279+
"nbformat_minor": 5
280+
}

examples/mesh.matcap.ipynb

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,17 @@
5252
"\n",
5353
"# Matcaps\n",
5454
"download_dataset(\n",
55-
" api_url=\"https://api.github.com/repos/niivue/niivue/contents/packages/niivue/demos/matcaps\",\n",
55+
" api_url=\"https://niivue.com/demos/matcaps\",\n",
5656
" dest_folder=DATA_FOLDER / \"matcaps\",\n",
57+
" files=[\n",
58+
" \"Shiny.jpg\",\n",
59+
" \"Cortex.jpg\",\n",
60+
" \"Cream.jpg\",\n",
61+
" \"Fuzzy.jpg\",\n",
62+
" \"Peach.jpg\",\n",
63+
" \"Plastic.jpg\",\n",
64+
" \"Gold.jpg\",\n",
65+
" ],\n",
5766
")"
5867
]
5968
},
@@ -197,7 +206,11 @@
197206
]
198207
}
199208
],
200-
"metadata": {},
209+
"metadata": {
210+
"language_info": {
211+
"name": "python"
212+
}
213+
},
201214
"nbformat": 4,
202215
"nbformat_minor": 5
203216
}

0 commit comments

Comments
 (0)