Skip to content

Commit c90e6cf

Browse files
committed
Merge remote-tracking branch 'upstream/main'
2 parents dd449e9 + 243d1a7 commit c90e6cf

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+1228
-367
lines changed

.github/workflows/deploy-docs.yml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
deploy-book:
2424
runs-on: ubuntu-latest
2525
steps:
26-
- uses: actions/checkout@v3
26+
- uses: actions/checkout@v4
2727

2828
# Install dependencies
2929
- name: Set up Python 3.10
@@ -33,19 +33,21 @@ jobs:
3333

3434
- name: Install dependencies
3535
run: |
36-
pip install finufft ipywidgets
36+
pip install mri-nufft[finufft] ipywidgets
3737
pip install -e .[doc]
38+
pip install git+https://github.com/mind-inria/mri-nufft
3839
3940
# Build the book
4041
- name: Build the book
42+
continue-on-error: true
4143
run: |
4244
python -m sphinx docs docs_build
4345
4446
- name: Upload artifact
45-
uses: actions/upload-pages-artifact@v1
47+
uses: actions/upload-pages-artifact@v3
4648
with:
4749
path: 'docs_build/'
4850

4951
- name: Deploy to GitHub Pages
5052
id: deployment
51-
uses: actions/deploy-pages@v1
53+
uses: actions/deploy-pages@v4

.github/workflows/test.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,25 @@ jobs:
5050
- name: Codespell
5151
if: always()
5252
uses: codespell-project/actions-codespell@v2
53+
54+
build-docs:
55+
runs-on: ubuntu-latest
56+
steps:
57+
- uses: actions/checkout@v4
58+
- name: Set up Python ${{ matrix.python }}
59+
uses: actions/setup-python@v4
60+
with:
61+
python-version: ${{ matrix.python }}
62+
cache: 'pip'
63+
- name: Install dependencies
64+
run: |
65+
python -m pip install --upgrade pip
66+
pip install -e .[dev,doc]
67+
- name: Build the doc with sphinx
68+
run: |
69+
python -m sphinx build docs docs_build
70+
- name: Upload documentation artifact
71+
uses: actions/upload-artifact@v4
72+
with:
73+
name: docs
74+
path: docs_build

.gitignore

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ todo*
99
TODO*
1010

1111

12+
*.py[cod]
13+
__pycache__
14+
1215
.python-version
1316
docs/generated/*
1417
docs_build
@@ -22,7 +25,32 @@ __pycache__/
2225
_version.py
2326

2427
*.mrd
28+
**/*.mrd
2529
results/
2630
multirun/
2731
outputs/
2832
debug/
33+
docs/auto_*/
34+
docs/sg_execution_times.rst
35+
36+
37+
jupyter_execute/
38+
htmlcov/
39+
.tox/
40+
.nox/
41+
.coverage
42+
.coverage.*
43+
.cache
44+
nosetests.xml
45+
coverage.xml
46+
*.cover
47+
.hypothesis/
48+
.pytest_cache/
49+
50+
.ipynb_checkpoints/*
51+
52+
.python-version
53+
.venv/
54+
.env/
55+
env/
56+
venv/

docs/_ext/GALLERY_HEADER.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Scenarios Gallery
2+
=================
3+
4+
.. This is use as a default file.

docs/_ext/colab_extension.py

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
"""A Sphinx extension to add a button to open a notebook in Google Colab."""
2+
3+
from docutils import nodes
4+
from sphinx.util.docutils import SphinxDirective
5+
from sphinx_gallery.notebook import add_code_cell, add_markdown_cell
6+
7+
import os
8+
import json
9+
10+
11+
class ColabLinkNode(nodes.General, nodes.Element):
12+
"""A custom docutils node to represent the Colab link."""
13+
14+
15+
def visit_colab_link_node_html(self, node):
16+
self.body.append(node["html"])
17+
18+
19+
def depart_colab_link_node_html(self, node):
20+
pass
21+
22+
23+
class ColabLinkDirective(SphinxDirective):
24+
"""Directive to insert a link to open a notebook in Google Colab."""
25+
26+
has_content = True
27+
option_spec = {
28+
"needs_gpu": int,
29+
}
30+
31+
def run(self):
32+
"""Run the directive."""
33+
# Determine the path of the current .rst file
34+
rst_file_path = self.env.doc2path(self.env.docname)
35+
rst_file_dir = os.path.dirname(rst_file_path)
36+
37+
# Determine the notebook file path assuming it is in the same directory as the .rst file
38+
notebook_filename = os.path.basename(rst_file_path).replace(".rst", ".ipynb")
39+
40+
# Full path to the notebook
41+
notebook_full_path = os.path.join(rst_file_dir, notebook_filename)
42+
43+
# Convert the full path back to a relative path from the repo root
44+
# repo_root = self.config.project_root_dir
45+
notebook_repo_relative_path = os.path.relpath(
46+
notebook_full_path, os.path.join(os.getcwd(), "docs")
47+
)
48+
49+
config_ext = self.env.config["colab_notebook"]
50+
base_colab_url = config_ext.get(
51+
"base_colab_url", "https://colab.research.google.com"
52+
)
53+
base_repo = config_ext["repo"]
54+
branch = config_ext["branch"]
55+
path = config_ext["path"]
56+
# Generate the Colab URL based on GitHub repo information
57+
self.colab_url = f"{base_colab_url}/{base_repo}/blob/{branch}/{path}/{notebook_repo_relative_path}"
58+
59+
# Create the HTML button or link
60+
self.html = f"""<div class="colab-button">
61+
<a href="{self.colab_url}" target="_blank">
62+
<img src="https://colab.research.google.com/assets/colab-badge.svg"
63+
alt="Open In Colab"/>
64+
</a>
65+
</div>
66+
"""
67+
self.notebook_modifier(notebook_full_path, "\n".join(self.content))
68+
69+
# Create the node to insert the HTML
70+
node = ColabLinkNode(html=self.html)
71+
return [node]
72+
73+
def notebook_modifier(self, notebook_path, commands):
74+
"""Modify the notebook to add a warning about GPU requirement."""
75+
with open(notebook_path) as f:
76+
notebook = json.load(f)
77+
if "cells" not in notebook:
78+
notebook["cells"] = []
79+
80+
# Add a cell to install the required libraries at the position where we have
81+
# colab link
82+
idx = self.find_index_of_colab_link(notebook)
83+
84+
code_lines = ["# Install libraries"]
85+
code_lines.append(commands)
86+
code_lines.append(
87+
"!pip install" + " ".join(self.env.config["colab_notebook"]["dependencies"])
88+
)
89+
dummy_notebook_content = {"cells": []}
90+
add_code_cell(
91+
dummy_notebook_content,
92+
"\n".join(code_lines),
93+
)
94+
notebook["cells"][idx] = dummy_notebook_content["cells"][0]
95+
96+
needs_GPU = self.options.get("needs_gpu", False)
97+
if needs_GPU:
98+
# Add a warning cell at the top of the notebook
99+
warning_template = "\n".join(
100+
[
101+
"<div class='alert alert-{message_class}'>",
102+
"",
103+
"# Need GPU warning",
104+
"",
105+
"{message}",
106+
"</div>",
107+
self.html,
108+
]
109+
)
110+
message_class = "warning"
111+
message = (
112+
"Running this example requires a GPU, and hence is NOT "
113+
"possible on binder currently We request you to kindly run this notebook "
114+
"on Google Colab by clicking the link below. Additionally, please make "
115+
"sure to set the runtime on Colab to use a GPU and install the below "
116+
"libraries before running."
117+
)
118+
idx = 0
119+
else:
120+
# Add a warning cell at the top of the notebook
121+
warning_template = "\n".join(
122+
[
123+
"<div class='alert alert-{message_class}'>",
124+
"",
125+
"# Install libraries needed for Colab",
126+
"",
127+
"{message}",
128+
"</div>",
129+
self.html,
130+
]
131+
)
132+
message_class = "info"
133+
message = (
134+
"The below installation commands are needed to be run only on "
135+
"Google Colab."
136+
)
137+
138+
dummy_notebook_content = {"cells": []}
139+
add_markdown_cell(
140+
dummy_notebook_content,
141+
warning_template.format(message_class=message_class, message=message),
142+
)
143+
notebook["cells"] = (
144+
notebook["cells"][:idx]
145+
+ dummy_notebook_content["cells"]
146+
+ notebook["cells"][idx:]
147+
)
148+
149+
# Write back updated notebook
150+
with open(notebook_path, "w", encoding="utf-8") as f:
151+
json.dump(notebook, f, ensure_ascii=False, indent=2)
152+
153+
def find_index_of_colab_link(self, notebook):
154+
"""Find the index of the cell containing the Colab link."""
155+
for idx, cell in enumerate(notebook["cells"]):
156+
if cell["cell_type"] == "markdown" and ".. colab-link::" in "".join(
157+
cell.get("source", "")
158+
):
159+
return idx
160+
return 0
161+
162+
163+
def setup(app):
164+
"""Set up the Sphinx extension."""
165+
app.add_config_value("colab_notebook", dict(), "html")
166+
app.add_node(
167+
ColabLinkNode, html=(visit_colab_link_node_html, depart_colab_link_node_html)
168+
)
169+
app.add_directive("colab-link", ColabLinkDirective)
170+
171+
return {
172+
"version": "0.1",
173+
"parallel_read_safe": True,
174+
"parallel_write_safe": True,
175+
}

docs/_ext/numpy_docstring.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# https://github.com/sphinx-extensions2/sphinx-autodoc2/issues/33#issuecomment-2564137728
2+
from docutils import nodes
3+
from myst_parser.parsers.sphinx_ import MystParser
4+
from sphinx.ext.napoleon import docstring
5+
6+
7+
class NapoleonParser(MystParser):
8+
def parse(self, input_string: str, document: nodes.document) -> None:
9+
parsed_content = "```{eval-rst}\n"
10+
parsed_content += str(
11+
docstring.GoogleDocstring(str(docstring.NumpyDocstring(input_string)))
12+
)
13+
parsed_content += "\n```\n"
14+
return super().parse(parsed_content, document)
15+
16+
17+
Parser = NapoleonParser

0 commit comments

Comments
 (0)