diff --git a/doc/.gitignore b/doc/.gitignore
index 2bfdff2d64..cdd244b1ad 100644
--- a/doc/.gitignore
+++ b/doc/.gitignore
@@ -4,3 +4,4 @@ _exhale_cpp_api/
examples/example_presimulation/model_presimulation/
generated/
build_doxygen/
+gfx/usage_by_year.png
diff --git a/doc/conf.py b/doc/conf.py
index 833cf9296f..a294cb2c81 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -9,6 +9,7 @@
import subprocess
import sys
from enum import EnumType
+from pathlib import Path
from unittest import mock
import sphinx
@@ -64,6 +65,16 @@ def install_doxygen():
assert version in res.stdout.decode()
+def execute_pre_sphinx_scripts():
+ """Execute scripts that need to be run before Sphinx is executed."""
+ script_dir = Path(__file__).parent / "pre-sphinx.d"
+ assert script_dir.is_dir()
+
+ for script in sorted(script_dir.glob("*.py")):
+ print(f"Executing pre-Sphinx script {script}")
+ subprocess.run([sys.executable, str(script)], check=True)
+
+
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
@@ -78,6 +89,7 @@ def install_doxygen():
if "READTHEDOCS" in os.environ and os.environ["READTHEDOCS"]:
install_doxygen()
+execute_pre_sphinx_scripts()
# -- Project information -----------------------------------------------------
# The short X.Y version
@@ -186,6 +198,7 @@ def install_doxygen():
# This pattern also affects html_static_path and html_extra_path .
exclude_patterns = [
"_build",
+ "pre-sphinx.d",
"Thumbs.db",
".DS_Store",
"**.ipynb_checkpoints",
diff --git a/doc/pre-sphinx.d/README.md b/doc/pre-sphinx.d/README.md
new file mode 100644
index 0000000000..efaec3cd5d
--- /dev/null
+++ b/doc/pre-sphinx.d/README.md
@@ -0,0 +1,9 @@
+# Pre-sphinx scripts
+
+This directory contains scripts that are executed before the documentation is
+built by Sphinx.
+These scripts are used to generate content that is included in the
+documentation, such as tables, figures, or other data that we do not want to
+have under version control.
+The scripts are executed in lexicographical order,
+see [../conf.py](../conf.py) for details.
diff --git a/doc/pre-sphinx.d/usage_by_year.py b/doc/pre-sphinx.d/usage_by_year.py
new file mode 100755
index 0000000000..3269796836
--- /dev/null
+++ b/doc/pre-sphinx.d/usage_by_year.py
@@ -0,0 +1,35 @@
+#!/usr/bin/env python
+"""Create barplot of AMICI publications by year."""
+
+from pathlib import Path
+
+import matplotlib.pyplot as plt
+import pandas as pd
+
+
+def main():
+ script_path = Path(__file__).parent
+ outfile = script_path.parent / "gfx" / "usage_by_year.png"
+
+ # set rcParams for better readability
+ plt.rcParams.update(
+ {
+ "figure.figsize": (5, 3),
+ "figure.dpi": 150,
+ "axes.titlesize": 14,
+ "axes.labelsize": 12,
+ "xtick.labelsize": 10,
+ "ytick.labelsize": 10,
+ }
+ )
+
+ df = pd.read_csv(script_path.parent / "usage_by_year.csv")
+ plt.bar(df.year, df.citations)
+ plt.xlabel("Year")
+ plt.ylabel("Citations")
+ plt.tight_layout()
+ plt.savefig(outfile)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/doc/recreate_reference_list.py b/doc/recreate_reference_list.py
index 557965d58e..ed6bd23ba8 100755
--- a/doc/recreate_reference_list.py
+++ b/doc/recreate_reference_list.py
@@ -8,16 +8,17 @@
Requires pandoc
"""
-import os
import subprocess
import sys
+from pathlib import Path
import biblib.algo
import biblib.bib
import biblib.messages
+import pandas as pd
-def get_keys_by_year(bibfile):
+def get_keys_by_year(bibfile: Path) -> dict[str, list[str]]:
"""Get bibtex entry keys as dict by year"""
with open(bibfile) as f:
@@ -37,10 +38,9 @@ def get_keys_by_year(bibfile):
return by_year
-def get_sub_bibliography(year, by_year, bibfile):
+def get_sub_bibliography(year, by_year, bibfile: Path):
"""Get HTML bibliography for the given year"""
-
- entries = ",".join(["@" + x for x in by_year[year]])
+ entries = ",".join([f"@{x}" for x in by_year[year]])
stdin_input = (
f'---\nbibliography: {bibfile}\nnocite: "{entries}"\n...\n# {year}'
)
@@ -58,9 +58,9 @@ def get_sub_bibliography(year, by_year, bibfile):
def main():
- script_path = os.path.dirname(os.path.realpath(__file__))
- bibfile = os.path.join(script_path, "amici_refs.bib")
- outfile = os.path.join(script_path, "references.md")
+ script_path = Path(__file__).parent
+ bibfile = script_path / "amici_refs.bib"
+ outfile = script_path / "references.md"
by_year = get_keys_by_year(bibfile)
num_total = sum(map(len, by_year.values()))
@@ -77,6 +77,7 @@ def main():
"?labels=documentation&title=Add+publication"
"&body=AMICI+was+used+in+this+manuscript:+DOI).\n\n"
)
+ f.write("\n\n")
f.write(
"""
\n
"""
)
+
for year in reversed(sorted(by_year.keys())):
cur_bib = get_sub_bibliography(year, by_year, bibfile)
f.write(cur_bib)
+ # Save table with citations / year
+ years = list(sorted(by_year.keys()))
+ citations = [len(by_year[year]) for year in years]
+
+ pd.DataFrame({"year": years, "citations": citations}).to_csv(
+ script_path / "usage_by_year.csv", index=False
+ )
+
if __name__ == "__main__":
main()
diff --git a/doc/references.md b/doc/references.md
index 8de5008aab..4f9267eaf0 100644
--- a/doc/references.md
+++ b/doc/references.md
@@ -5,6 +5,8 @@ List of publications using AMICI. Total number is 111.
If you applied AMICI in your work and your publication is missing, please let us know via a new
[GitHub issue](https://github.com/AMICI-dev/AMICI/issues/new?labels=documentation&title=Add+publication&body=AMICI+was+used+in+this+manuscript:+DOI).
+
+