Skip to content

Commit

Permalink
MRathon deliverable - NeuroLibre-ready setup (#12)
Browse files Browse the repository at this point in the history
* 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 <ingmatteomancini@gmail.com>
Co-authored-by: Alexandre D'Astous <po09i@hotmail.com>
  • Loading branch information
3 people authored Jul 23, 2024
1 parent ae8f177 commit 1db50ed
Show file tree
Hide file tree
Showing 16 changed files with 377 additions and 1 deletion.
43 changes: 43 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: deploy-book

# Only run this when the v2 branch changes
on:
push:
branches:
- main
# If your git repository has the Jupyter Book within some-subfolder next to
# unrelated files, you can make this run only if a file within that specific
# folder has been modified.
# paths:
# - source/**

# This job installs dependencies, build the book, and pushes it to `gh-pages`
jobs:
deploy-book:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2

# Install dependencies
- name: Set up Python 3.8
uses: actions/setup-python@v1
with:
python-version: 3.8

- name: Install dependencies
run: |
pip install -r binder/requirements.txt
- name: Postbuild
run: |
chmod +xxx binder/postBuild
binder/postBuild
# Build the book
- name: Build the book
run: |
jupyter-book build content/index.ipynb --builder singlehtml
# Push the book's HTML to github-pages
- name: GitHub Pages action
uses: peaceiris/actions-gh-pages@v3.6.1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./content/_build/_page/index/singlehtml
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
.DS_Store
.ipynb_checkpoints
.ipynb_checkpoints
content/_build/
Empty file added binder/postBuild
Empty file.
6 changes: 6 additions & 0 deletions binder/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
jupyter-book==0.13.0
lxml_html_clean
nibabel
pandas
plotly
scipy
1 change: 1 addition & 0 deletions binder/runtime.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
python-3.8
37 changes: 37 additions & 0 deletions content/_config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Book settings
# Learn more at https://jupyterbook.org/customize/config.html

title: B0 mapping
logo: logo.png

# Force re-execution of notebooks on each build.
# See https://jupyterbook.org/content/execute.html
execute:
execute_notebooks: force

launch_buttons:
notebook_interface: "jupyterlab"

# Information about where the book exists on the web
repository:
url: https://github.com/qMRLab/qMRI-MOOC_B0-module # Online location of your book
path_to_book: content # Optional path to your book, relative to the repository root
branch: main # Which branch of the repository should be used when creating links (optional)

only_build_toc_files: true

execute:
timeout: 600

sphinx:
local_extensions : # A list of local extensions to load by sphinx specified by "name: path" items
recursive_update : false # A boolean indicating whether to overwrite the Sphinx config (true) or recursively update
config : # key-value pairs to directly over-ride the Sphinx configuration
bibtex_reference_style: author_year
bibtex_default_style: plain
bibtex_tooltips: true
html_static_path: ['_static']
html_css_files: ['custom.css']

bibtex_bibfiles:
- ../paper.bib
52 changes: 52 additions & 0 deletions content/_static/custom.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
p {
text-align: justify;
}
a {
color: #870000!important;
}
a:hover {
color: brick!important;
}
a:visited {
color: #6f42c1!important;
}
body, h1, h2, h3, h4, h5 {
font-family: 'STIX Two Text';
}
h1 {
color: #342727!important;
}
.caption {
text-align:justify;
line-height:1.25;
font-size:80%
}

#site-navigation {
display: none;
}

#main-content{
margin: 0 auto;
}


.fa, .far, .fas {
color: red;
}

.header-article::after{
content: url('https://neurolibre.org/assets/joss2-b7ea8dd1f24ce2b0825db17e3495576253ba4c64df3384a66354713d76c40a75.svg');
width: 150px;
height: 80px;
position: relative;
right: 10px;
}

.header-article::before{
content: url('https://raw.githubusercontent.com/neurolibre/brand/b5e10e051a0059824ca2f4204e1288927e551d49/svg/neurolibre_logo.svg');
width: 33px;
height: 33px;
position: absolute;
left: 10px;
}
5 changes: 5 additions & 0 deletions content/_toc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Table of contents
# Learn more at https://jupyterbook.org/customize/toc.html

format: jb-article
root: paper
File renamed without changes.
File renamed without changes.
File renamed without changes.
14 changes: 14 additions & 0 deletions content/figure.html

Large diffs are not rendered by default.

187 changes: 187 additions & 0 deletions content/index.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# MRathon 2024 - NeuroLibre preprint project\n",
"\n",
"Hello world!\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Figure 1"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"hide_input",
"remove_output"
]
},
"outputs": [],
"source": [
"import numpy as np\n",
"from scipy.fft import fftn, ifftn, fftshift\n",
"import plotly.express as px\n",
"import plotly.graph_objects as go\n",
"from plotly.subplots import make_subplots\n",
"from IPython.display import display, HTML\n",
"from plotly.offline import init_notebook_mode, iplot, plot\n",
"\n",
"init_notebook_mode(connected=True)\n",
"vol_size = (128, 128, 128)\n",
"vol_centre = (vol_size[1] // 2, vol_size[2] // 2)\n",
"offset = (10, 20)\n",
"radius_inner = 10\n",
"radius_outer = 40\n",
"cylinder_base = np.zeros(vol_size)\n",
"cylinder_internal = np.zeros(vol_size)\n",
"\n",
"x = np.arange(-vol_size[1]//2,vol_size[1]//2,dtype=float)\n",
"y = x\n",
"z = x\n",
"X,Y,Z = np.meshgrid(x,y,z)\n",
"\n",
"cylinder_base[X**2+Y**2<=radius_outer**2] = 1\n",
"\n",
"cylinder_internal[(X-offset[0])**2+(Y-offset[1])**2<=radius_inner**2] += 0.1\n",
"\n",
"kx = X\n",
"ky = Y\n",
"kz = Z\n",
"KK = (kx**2 + ky**2 + kz**2)\n",
"KK[KK==0] = np.nan\n",
"dipole_kernel = 2./3 - (kx**2)/(KK)\n",
"dipole_kernel[(kx**2 + ky**2 + kz**2) == 0] = 0\n",
"\n",
"fieldmap = np.real(ifftn(fftshift(dipole_kernel) * (fftn(cylinder_internal))))\n",
"\n",
"idx = 64\n",
"\n",
"fig = make_subplots(rows=1, cols=3, shared_xaxes=False, horizontal_spacing=0.1,\n",
" subplot_titles=(\"Geometry\",\n",
" \"Dipole kernel\",\n",
" \"Fieldmap\"),\n",
" specs=[[{\"type\": \"Heatmap\"}, {\"type\": \"Heatmap\"}, {\"type\": \"Heatmap\"}]])\n",
"fig.add_trace(go.Heatmap(z=cylinder_base[:,:,idx]+cylinder_internal[:,:,64], colorscale='gray'), 1, 1)\n",
"fig.add_trace(go.Heatmap(z=dipole_kernel[:,:,idx], colorscale='gray'), 1, 2)\n",
"fig.add_trace(go.Heatmap(z=fieldmap[:,:,idx], colorscale='gray'), 1, 3)\n",
"\n",
"plot(fig, filename = 'geometry.html')\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"remove_input",
"report_output"
]
},
"outputs": [],
"source": [
"display(HTML('geometry.html'))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Figure 2"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"hide_input",
"remove_output"
]
},
"outputs": [],
"source": [
"fig = go.Figure()\n",
"\n",
"echo_times = [10, 30, 50]\n",
"for step in echo_times:\n",
" fig.add_trace(\n",
" go.Heatmap(\n",
" visible=False,\n",
" z=(fieldmap[:,:,idx]*step) % np.pi,\n",
" colorscale='gray'))\n",
"\n",
"fig.data[0].visible = True\n",
"\n",
"# Create and add slider\n",
"steps = []\n",
"for i in range(len(fig.data)):\n",
" step = dict(\n",
" method=\"update\",\n",
" args=[{\"visible\": [False] * len(fig.data)},\n",
" {\"title\": \"TE=\" + str(echo_times[i]) + \" ms\"}], # layout attribute\n",
" )\n",
" step[\"args\"][0][\"visible\"][i] = True # Toggle i'th trace to \"visible\"\n",
" steps.append(step)\n",
"\n",
"sliders = [dict(\n",
" active=10,\n",
" currentvalue={\"prefix\": \"Frequency: \"},\n",
" pad={\"t\": 50},\n",
" steps=steps\n",
")]\n",
"\n",
"fig.update_layout(\n",
" sliders=sliders\n",
")\n",
"\n",
"plot(fig, filename = 'cylinder.html')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"remove_input",
"report_output"
]
},
"outputs": [],
"source": [
"display(HTML('cylinder.html'))"
]
}
],
"metadata": {
"celltoolbar": "Tags",
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.13"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
Binary file added content/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions paper.bib
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

29 changes: 29 additions & 0 deletions paper.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
title: B0 mapping

tags:
- NeuroLibre
authors:
- name: MRathon Group
orcid:
affiliation: 1

affiliations:
- name: Singapore
index: 1


date: 3 May 2024
bibliography: paper.bib

---

# Summary

# Statement of need

# Figures

# Acknowledgements

## References

0 comments on commit 1db50ed

Please sign in to comment.