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("![AMICI usage over time](gfx/usage_by_year.png)\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). +![AMICI usage over time](gfx/usage_by_year.png) +