Skip to content

Commit 1db50ed

Browse files
mathieuboudreaumatteomancinipo09i
authored
MRathon deliverable - NeuroLibre-ready setup (#12)
* Moved notebooks to content folder * Added requirements.txt . * First draft of cylinder-based simulations. * Fixed requirements.txt . * Make template jupyter book files * Add empty binder files * Add github pages action * Add github pages action * Add jupyterbook requirement * Add missing xml req * Added first plots to cylinder simulations. * Add template plotly figure * Add neurolibre paper.md * Update requirements * Added slider-based figure. * Add interactive figures * Update main.yml * Delete cylinder_sim.ipynb * Update _config.yml * Remove html files --------- Co-authored-by: Matteo Mancini <[email protected]> Co-authored-by: Alexandre D'Astous <[email protected]>
1 parent ae8f177 commit 1db50ed

16 files changed

+377
-1
lines changed

.github/workflows/main.yml

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: deploy-book
2+
3+
# Only run this when the v2 branch changes
4+
on:
5+
push:
6+
branches:
7+
- main
8+
# If your git repository has the Jupyter Book within some-subfolder next to
9+
# unrelated files, you can make this run only if a file within that specific
10+
# folder has been modified.
11+
# paths:
12+
# - source/**
13+
14+
# This job installs dependencies, build the book, and pushes it to `gh-pages`
15+
jobs:
16+
deploy-book:
17+
runs-on: ubuntu-latest
18+
steps:
19+
- uses: actions/checkout@v2
20+
21+
# Install dependencies
22+
- name: Set up Python 3.8
23+
uses: actions/setup-python@v1
24+
with:
25+
python-version: 3.8
26+
27+
- name: Install dependencies
28+
run: |
29+
pip install -r binder/requirements.txt
30+
- name: Postbuild
31+
run: |
32+
chmod +xxx binder/postBuild
33+
binder/postBuild
34+
# Build the book
35+
- name: Build the book
36+
run: |
37+
jupyter-book build content/index.ipynb --builder singlehtml
38+
# Push the book's HTML to github-pages
39+
- name: GitHub Pages action
40+
uses: peaceiris/[email protected]
41+
with:
42+
github_token: ${{ secrets.GITHUB_TOKEN }}
43+
publish_dir: ./content/_build/_page/index/singlehtml

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
.DS_Store
2-
.ipynb_checkpoints
2+
.ipynb_checkpoints
3+
content/_build/

binder/postBuild

Whitespace-only changes.

binder/requirements.txt

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
jupyter-book==0.13.0
2+
lxml_html_clean
3+
nibabel
4+
pandas
5+
plotly
6+
scipy

binder/runtime.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
python-3.8

content/_config.yml

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Book settings
2+
# Learn more at https://jupyterbook.org/customize/config.html
3+
4+
title: B0 mapping
5+
logo: logo.png
6+
7+
# Force re-execution of notebooks on each build.
8+
# See https://jupyterbook.org/content/execute.html
9+
execute:
10+
execute_notebooks: force
11+
12+
launch_buttons:
13+
notebook_interface: "jupyterlab"
14+
15+
# Information about where the book exists on the web
16+
repository:
17+
url: https://github.com/qMRLab/qMRI-MOOC_B0-module # Online location of your book
18+
path_to_book: content # Optional path to your book, relative to the repository root
19+
branch: main # Which branch of the repository should be used when creating links (optional)
20+
21+
only_build_toc_files: true
22+
23+
execute:
24+
timeout: 600
25+
26+
sphinx:
27+
local_extensions : # A list of local extensions to load by sphinx specified by "name: path" items
28+
recursive_update : false # A boolean indicating whether to overwrite the Sphinx config (true) or recursively update
29+
config : # key-value pairs to directly over-ride the Sphinx configuration
30+
bibtex_reference_style: author_year
31+
bibtex_default_style: plain
32+
bibtex_tooltips: true
33+
html_static_path: ['_static']
34+
html_css_files: ['custom.css']
35+
36+
bibtex_bibfiles:
37+
- ../paper.bib

content/_static/custom.css

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
p {
2+
text-align: justify;
3+
}
4+
a {
5+
color: #870000!important;
6+
}
7+
a:hover {
8+
color: brick!important;
9+
}
10+
a:visited {
11+
color: #6f42c1!important;
12+
}
13+
body, h1, h2, h3, h4, h5 {
14+
font-family: 'STIX Two Text';
15+
}
16+
h1 {
17+
color: #342727!important;
18+
}
19+
.caption {
20+
text-align:justify;
21+
line-height:1.25;
22+
font-size:80%
23+
}
24+
25+
#site-navigation {
26+
display: none;
27+
}
28+
29+
#main-content{
30+
margin: 0 auto;
31+
}
32+
33+
34+
.fa, .far, .fas {
35+
color: red;
36+
}
37+
38+
.header-article::after{
39+
content: url('https://neurolibre.org/assets/joss2-b7ea8dd1f24ce2b0825db17e3495576253ba4c64df3384a66354713d76c40a75.svg');
40+
width: 150px;
41+
height: 80px;
42+
position: relative;
43+
right: 10px;
44+
}
45+
46+
.header-article::before{
47+
content: url('https://raw.githubusercontent.com/neurolibre/brand/b5e10e051a0059824ca2f4204e1288927e551d49/svg/neurolibre_logo.svg');
48+
width: 33px;
49+
height: 33px;
50+
position: absolute;
51+
left: 10px;
52+
}

content/_toc.yml

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Table of contents
2+
# Learn more at https://jupyterbook.org/customize/toc.html
3+
4+
format: jb-article
5+
root: paper
File renamed without changes.
File renamed without changes.
File renamed without changes.

content/figure.html

+14
Large diffs are not rendered by default.

content/index.ipynb

+187
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"# MRathon 2024 - NeuroLibre preprint project\n",
8+
"\n",
9+
"Hello world!\n"
10+
]
11+
},
12+
{
13+
"cell_type": "markdown",
14+
"metadata": {},
15+
"source": [
16+
"## Figure 1"
17+
]
18+
},
19+
{
20+
"cell_type": "code",
21+
"execution_count": null,
22+
"metadata": {
23+
"tags": [
24+
"hide_input",
25+
"remove_output"
26+
]
27+
},
28+
"outputs": [],
29+
"source": [
30+
"import numpy as np\n",
31+
"from scipy.fft import fftn, ifftn, fftshift\n",
32+
"import plotly.express as px\n",
33+
"import plotly.graph_objects as go\n",
34+
"from plotly.subplots import make_subplots\n",
35+
"from IPython.display import display, HTML\n",
36+
"from plotly.offline import init_notebook_mode, iplot, plot\n",
37+
"\n",
38+
"init_notebook_mode(connected=True)\n",
39+
"vol_size = (128, 128, 128)\n",
40+
"vol_centre = (vol_size[1] // 2, vol_size[2] // 2)\n",
41+
"offset = (10, 20)\n",
42+
"radius_inner = 10\n",
43+
"radius_outer = 40\n",
44+
"cylinder_base = np.zeros(vol_size)\n",
45+
"cylinder_internal = np.zeros(vol_size)\n",
46+
"\n",
47+
"x = np.arange(-vol_size[1]//2,vol_size[1]//2,dtype=float)\n",
48+
"y = x\n",
49+
"z = x\n",
50+
"X,Y,Z = np.meshgrid(x,y,z)\n",
51+
"\n",
52+
"cylinder_base[X**2+Y**2<=radius_outer**2] = 1\n",
53+
"\n",
54+
"cylinder_internal[(X-offset[0])**2+(Y-offset[1])**2<=radius_inner**2] += 0.1\n",
55+
"\n",
56+
"kx = X\n",
57+
"ky = Y\n",
58+
"kz = Z\n",
59+
"KK = (kx**2 + ky**2 + kz**2)\n",
60+
"KK[KK==0] = np.nan\n",
61+
"dipole_kernel = 2./3 - (kx**2)/(KK)\n",
62+
"dipole_kernel[(kx**2 + ky**2 + kz**2) == 0] = 0\n",
63+
"\n",
64+
"fieldmap = np.real(ifftn(fftshift(dipole_kernel) * (fftn(cylinder_internal))))\n",
65+
"\n",
66+
"idx = 64\n",
67+
"\n",
68+
"fig = make_subplots(rows=1, cols=3, shared_xaxes=False, horizontal_spacing=0.1,\n",
69+
" subplot_titles=(\"Geometry\",\n",
70+
" \"Dipole kernel\",\n",
71+
" \"Fieldmap\"),\n",
72+
" specs=[[{\"type\": \"Heatmap\"}, {\"type\": \"Heatmap\"}, {\"type\": \"Heatmap\"}]])\n",
73+
"fig.add_trace(go.Heatmap(z=cylinder_base[:,:,idx]+cylinder_internal[:,:,64], colorscale='gray'), 1, 1)\n",
74+
"fig.add_trace(go.Heatmap(z=dipole_kernel[:,:,idx], colorscale='gray'), 1, 2)\n",
75+
"fig.add_trace(go.Heatmap(z=fieldmap[:,:,idx], colorscale='gray'), 1, 3)\n",
76+
"\n",
77+
"plot(fig, filename = 'geometry.html')\n",
78+
"\n"
79+
]
80+
},
81+
{
82+
"cell_type": "code",
83+
"execution_count": null,
84+
"metadata": {
85+
"tags": [
86+
"remove_input",
87+
"report_output"
88+
]
89+
},
90+
"outputs": [],
91+
"source": [
92+
"display(HTML('geometry.html'))"
93+
]
94+
},
95+
{
96+
"cell_type": "markdown",
97+
"metadata": {},
98+
"source": [
99+
"## Figure 2"
100+
]
101+
},
102+
{
103+
"cell_type": "code",
104+
"execution_count": null,
105+
"metadata": {
106+
"tags": [
107+
"hide_input",
108+
"remove_output"
109+
]
110+
},
111+
"outputs": [],
112+
"source": [
113+
"fig = go.Figure()\n",
114+
"\n",
115+
"echo_times = [10, 30, 50]\n",
116+
"for step in echo_times:\n",
117+
" fig.add_trace(\n",
118+
" go.Heatmap(\n",
119+
" visible=False,\n",
120+
" z=(fieldmap[:,:,idx]*step) % np.pi,\n",
121+
" colorscale='gray'))\n",
122+
"\n",
123+
"fig.data[0].visible = True\n",
124+
"\n",
125+
"# Create and add slider\n",
126+
"steps = []\n",
127+
"for i in range(len(fig.data)):\n",
128+
" step = dict(\n",
129+
" method=\"update\",\n",
130+
" args=[{\"visible\": [False] * len(fig.data)},\n",
131+
" {\"title\": \"TE=\" + str(echo_times[i]) + \" ms\"}], # layout attribute\n",
132+
" )\n",
133+
" step[\"args\"][0][\"visible\"][i] = True # Toggle i'th trace to \"visible\"\n",
134+
" steps.append(step)\n",
135+
"\n",
136+
"sliders = [dict(\n",
137+
" active=10,\n",
138+
" currentvalue={\"prefix\": \"Frequency: \"},\n",
139+
" pad={\"t\": 50},\n",
140+
" steps=steps\n",
141+
")]\n",
142+
"\n",
143+
"fig.update_layout(\n",
144+
" sliders=sliders\n",
145+
")\n",
146+
"\n",
147+
"plot(fig, filename = 'cylinder.html')"
148+
]
149+
},
150+
{
151+
"cell_type": "code",
152+
"execution_count": null,
153+
"metadata": {
154+
"tags": [
155+
"remove_input",
156+
"report_output"
157+
]
158+
},
159+
"outputs": [],
160+
"source": [
161+
"display(HTML('cylinder.html'))"
162+
]
163+
}
164+
],
165+
"metadata": {
166+
"celltoolbar": "Tags",
167+
"kernelspec": {
168+
"display_name": "Python 3 (ipykernel)",
169+
"language": "python",
170+
"name": "python3"
171+
},
172+
"language_info": {
173+
"codemirror_mode": {
174+
"name": "ipython",
175+
"version": 3
176+
},
177+
"file_extension": ".py",
178+
"mimetype": "text/x-python",
179+
"name": "python",
180+
"nbconvert_exporter": "python",
181+
"pygments_lexer": "ipython3",
182+
"version": "3.9.13"
183+
}
184+
},
185+
"nbformat": 4,
186+
"nbformat_minor": 4
187+
}

content/logo.png

9.62 KB
Loading

paper.bib

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

paper.md

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---
2+
title: B0 mapping
3+
4+
tags:
5+
- NeuroLibre
6+
authors:
7+
- name: MRathon Group
8+
orcid:
9+
affiliation: 1
10+
11+
affiliations:
12+
- name: Singapore
13+
index: 1
14+
15+
16+
date: 3 May 2024
17+
bibliography: paper.bib
18+
19+
---
20+
21+
# Summary
22+
23+
# Statement of need
24+
25+
# Figures
26+
27+
# Acknowledgements
28+
29+
## References

0 commit comments

Comments
 (0)