diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml
index 0636152..e1195b9 100644
--- a/.github/workflows/documentation.yml
+++ b/.github/workflows/documentation.yml
@@ -1,10 +1,8 @@
# Build documentation
+# The build is uploaded as artifact if the triggering event is a push for a pull request
+# The build is published to github pages if the triggering event is a push to the master branch (PR merge)
name: Build and upload documentation
-defaults:
- run:
- shell: bash
-
on: # Runs on any push event in a PR or any push event to master
pull_request:
push:
@@ -13,48 +11,4 @@ on: # Runs on any push event in a PR or any push event to master
jobs:
documentation:
- name: ${{ matrix.os }} / ${{ matrix.python-version }}
- runs-on: ${{ matrix.os }}
- strategy:
- matrix: # only lowest supported python on ubuntu-latest
- os: [ubuntu-latest]
- python-version: [3.9]
-
- steps:
- - uses: actions/checkout@v3
-
- - name: Install LaTeX
- run: sudo apt-get install -y texlive-latex-base # texlive-fonts-extra texlive-fonts-recommended texlive-latex-extra texlive-latex-recommended ghostscript
-
- - name: Install optipng
- run: sudo apt-get install -y optipng
-
- - name: Set up Python ${{ matrix.python-version }}
- uses: actions/setup-python@v4
- with:
- python-version: ${{ matrix.python-version }}
-
- - name: Upgrade pip
- run: python -m pip install --upgrade pip
-
- - name: Install dependencies
- run: python -m pip install -r doc/requirements.txt
-
- - name: Build documentation
- run: python -m sphinx -v -b html doc doc_build -d doc_build
-
- - name: Upload build artifacts # upload artifacts so reviewers can have a quick look without building documentation from the branch locally
- if: success() && github.event_name == 'pull_request' # only for pushes in PR
- uses: actions/upload-artifact@v3
- with:
- name: site-build
- path: doc_build
- retention-days: 5
-
- - name: Upload documentation to gh-pages
- if: success() && github.ref == 'refs/heads/master' # only for pushes to master
- uses: JamesIves/github-pages-deploy-action@v4
- with:
- token: ${{ secrets.GITHUB_TOKEN }}
- branch: gh-pages
- folder: doc_build
+ uses: pylhc/.github/.github/workflows/documentation.yml@master
diff --git a/README.md b/README.md
index 26ee69e..6873627 100644
--- a/README.md
+++ b/README.md
@@ -4,23 +4,20 @@
[](https://github.com/pylhc/accelerator_timeline/)
[](https://doi.org/10.5281/zenodo.8316137)
-In this package, the main parameters of major historical, modern and possible future accelerators are
+In this package, the main parameters of major historical, modern and possible future accelerators are
collected, including references to the origin of the collected data, into a single csv:
- - [accelerator-parameters.csv](accelerator-parameters.csv).
+- [accelerator-parameters.csv](accelerator-parameters.csv).
-
-
-## Installation
+## Installation
This package is mostly for collecting and sharing the data of the accelerators within
-the CSV file.
+the CSV file.
-
-To get the data, either download the [accelerator-parameters.csv](accelerator-parameters.csv) directly,
+To get the data, either download the [accelerator-parameters.csv](accelerator-parameters.csv) directly,
or clone the repository via `git`, e.g.::
-```
+```bash
git clone https://github.com/pylhc/accelerator_timeline.git
```
@@ -28,16 +25,23 @@ git clone https://github.com/pylhc/accelerator_timeline.git
In addition, small python scripts are provided to explore the data via and create Livingston-like plots.
These charts are available interactively at:
-
- - [pylhc.github.io/accelerator_timeline](https://pylhc.github.io/accelerator_timeline).
+
+- [pylhc.github.io/accelerator_timeline](https://pylhc.github.io/accelerator_timeline).
The python code itself can be found at
- - [interactive_charts.py](interactive_charts.py), creating the interactive charts via plotly.
- - [export_charts.py](export_charts.py), making publication-grade exports to pdf via matplotlib.
+- [interactive_charts.py](interactive_charts.py), creating the interactive charts via plotly.
+- [export_charts.py](export_charts.py), making publication-grade exports to pdf via matplotlib.
The requirements for the scripts can be found in the respective `requirements_*.txt` file.



+
+## Note for Developers
+
+Updating the data in the CSV will automatically update the charts in the
+[pylhc.github.io/accelerator_timeline](https://pylhc.github.io/accelerator_timeline) website via GitHub Actions.
+The pictures in the `images/` folder (which are also linked in this `README`) are **not** automatically generated
+and need to be updated manually by running the `export_charts.py` script and committing the changes.
diff --git a/accelerator-parameters.csv b/accelerator-parameters.csv
index 8a5157b..d6dff9c 100755
--- a/accelerator-parameters.csv
+++ b/accelerator-parameters.csv
@@ -43,8 +43,8 @@ FCC-ee WW,CERN,Switzerland,2043*,,e+e-,80,,2.8E+035,97750,https://journals.aps.o
FCC-ee ZH,CERN,Switzerland,2045*,,e+e-,120,,8.5E+034,97750,https://journals.aps.org/rmp/pdf/10.1103/RevModPhys.93.015006 https://doi-org.ezproxy.cern.ch/10.1140/epjst/e2019-900045-4
FCC-ee ttbar,CERN,Switzerland,2049*,,e+e-,182.5,,1.55E+034,97750,https://journals.aps.org/rmp/pdf/10.1103/RevModPhys.93.015006 https://doi-org.ezproxy.cern.ch/10.1140/epjst/e2019-900045-4
FCC-hh,CERN,Switzerland,2070*,,p+p+,50000,,3E+035,97750,https://journals.aps.org/rmp/pdf/10.1103/RevModPhys.93.015006
-CEPC,IHEP,China,2035*,,e+e-,45.5,,3.2E+035,100000,https://journals.aps.org/rmp/pdf/10.1103/RevModPhys.93.015006 https://arxiv.org/abs/1809.00285 https://www.researchgate.net/publication/359254433_Snowmass_2021_White_Paper_AF4_-_SPPC
-SppC,IHEP,China,2050*,,p+p+,37500,,1E+035,100000,https://journals.aps.org/rmp/pdf/10.1103/RevModPhys.93.015006 https://www.researchgate.net/publication/359254433_Snowmass_2021_White_Paper_AF4_-_SPPC
+CEPC,IHEP,China,2035*,,e+e-,45.5,,3.2E+035,100000,https://journals.aps.org/rmp/pdf/10.1103/RevModPhys.93.015006 https://arxiv.org/abs/1809.00285 https://doi.org/10.48550/arXiv.2203.07987
+SppC,IHEP,China,2050*,,p+p+,37500,,1E+035,100000,https://journals.aps.org/rmp/pdf/10.1103/RevModPhys.93.015006 https://doi.org/10.48550/arXiv.2203.07987
ILC v1,Fermilab,USA,2035*,,e+e-,125,,1.35E+034,20500,https://journals.aps.org/rmp/pdf/10.1103/RevModPhys.93.015006 https://arxiv.org/pdf/1901.09829.pdf
ILC v2,Fermilab,USA,2040*,,e+e-,250,,1.8E+034,31000,https://journals.aps.org/rmp/pdf/10.1103/RevModPhys.93.015006 https://arxiv.org/pdf/1901.09829.pdf
ILC v3,Fermilab,USA,2045*,,e+e-,500,,4.9E+034,40000,https://journals.aps.org/rmp/pdf/10.1103/RevModPhys.93.015006 https://arxiv.org/pdf/1901.09829.pdf
diff --git a/doc/Makefile b/doc/Makefile
index f720b20..c3598ae 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -51,11 +51,6 @@ html:
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
-josch:
- $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) ../../Documentation/accelerator_timeline-doc
- @echo
- @echo "Build finished. The HTML pages are in ../../Documentation/accelerator_timeline-doc."
-
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
diff --git a/doc/_static/css/custom.css b/doc/_static/css/custom.css
index 454b663..c52d4fb 100644
--- a/doc/_static/css/custom.css
+++ b/doc/_static/css/custom.css
@@ -1,5 +1,5 @@
:root {
- --nav-side-width: 300px; /* default is 300px */
+ --nav-side-width: 250px; /* default is 300px */
/* for 100% width */
/*--nav-content-width: 100%;*/
/*--local-toc-width: 300px;*/
@@ -7,7 +7,7 @@
/*--local-toc-left: calc(100% - var(--local-toc-width)); /* 100% here is w/o sidebar */
/* for fixed widths */
- --nav-content-width: 800px; /* default is 800px */
+ --nav-content-width: 1000px; /* default is 800px */
--nav-content-width-wide: var(--nav-content-width);
--local-toc-width: calc(100% - var(--nav-content-width-wide));
--local-toc-left: calc(var(--nav-content-width-wide) + var(--nav-side-width));
@@ -57,7 +57,7 @@
border: none;
}
-/* Hide the first two entries (combined in the first
) of the nav-bar,
+/* Hide the first two entries (combined in the first ) of the nav-bar,
as they are coming from the included gallery */
.wy-menu-vertical ul:nth-child(-n + 1) {
@@ -198,7 +198,7 @@ em.sig-param span.default_value {
/* Format Tables
- Not sure why the following were in the css,
+ Not sure why the following were in the css,
but some of them break the csv table formatting.
I left those in, that looked good.
*/
diff --git a/doc/conf.py b/doc/conf.py
index 5099856..7317f79 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -1,21 +1,11 @@
-# Configuration file for the Sphinx documentation builder.
-#
-# This file only contains a selection of the most common options. For a full
-# list see the documentation:
-# https://www.sphinx-doc.org/en/master/usage/configuration.html
-
-# -- Path setup --------------------------------------------------------------
-
-# If extensions (or modules to document with autodoc) are in another directory,
-# add these directories to sys.path here. If the directory is relative to the
-# documentation root, use os.path.abspath to make it absolute, like shown here.
-
-import pathlib
import os
+import pathlib
import shutil
import sys
import warnings
+from functools import partial
+# -- Filter Warnings -----------------------------------------------------------
# ignore numpy warnings, see:
# https://stackoverflow.com/questions/40845304/runtimewarning-numpy-dtype-size-changed-may-indicate-binary-incompatibility
warnings.filterwarnings("ignore", message="numpy.dtype size changed")
@@ -25,9 +15,17 @@
warnings.filterwarnings(
"ignore",
category=UserWarning,
- message="Matplotlib is currently using agg, which is a" " non-GUI backend, so cannot show the figure.",
+ message="Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figure.",
)
+# suppress Sphinx cache-related warnings
+suppress_warnings = ["config.cache"]
+
+# -- Path setup ---------------------------------------------------------------
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
TOPLEVEL_DIR = pathlib.Path(__file__).parent.parent.absolute()
ABOUT_FILE = TOPLEVEL_DIR / "__init__.py"
@@ -39,14 +37,16 @@
with ABOUT_FILE.open("r") as f:
exec(f.read(), ABOUT_accelerator_timeline)
+
+# -- Accelerator Timeline specific setup ---------------------------------------
# Set environment variable for scripts to check if we are in sphinx-mode
-from utilities.sphinx_helper import SPHINX_BUILD_ENVIRON
-os.environ[SPHINX_BUILD_ENVIRON] = '1'
+from utilities.sphinx_helper import SPHINX_BUILD_ENVIRON # noqa: E402
+os.environ[SPHINX_BUILD_ENVIRON] = '1'
# Copy accelerator data file
shutil.copy2(
- TOPLEVEL_DIR / "accelerator-parameters.csv",
+ TOPLEVEL_DIR / "accelerator-parameters.csv",
TOPLEVEL_DIR / "doc" / "accelerator-parameters.csv"
)
@@ -69,7 +69,7 @@
# General information about the project.
project = ABOUT_accelerator_timeline["__title__"]
-copyright_ = '2019-2023, pyLHC/OMC-TEAM'
+copyright_ = '2019-2025, pyLHC/OMC-TEAM'
author = ABOUT_accelerator_timeline["__author__"]
rst_prolog = f"""
@@ -113,7 +113,7 @@
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This patterns also effect to html_static_path and html_extra_path
-exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", "docs", "docker", "tests", ".github", ".vscode"]
+exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", "docs", "docker", "tests", ".github", ".vscode", ".venv"]
# The reST default role (used for this markup: `text`) to use for all
# documents.
@@ -189,33 +189,29 @@
# bibtex_reference_style = "label"
# -- Setup scrapers for the gallery ------------------------------------------
-from plotly.io._sg_scraper import plotly_sg_scraper
-import plotly.io as pio
+import plotly.io as pio # noqa: E402
+from plotly.io._sg_scraper import plotly_sg_scraper # noqa: E402
+
pio.renderers.default = 'sphinx_gallery'
# To use SVG outputs when scraping matplotlib figures for the sphinx-gallery
-from sphinx_gallery.scrapers import matplotlib_scraper
-from sphinx_gallery.sorting import ExampleTitleSortKey
-class matplotlib_svg_scraper(object):
- def __repr__(self):
- return self.__class__.__name__
-
- def __call__(self, *args, **kwargs):
- return matplotlib_scraper(*args, format="svg", **kwargs)
+from sphinx_gallery.scrapers import matplotlib_scraper # noqa: E402
+from sphinx_gallery.sorting import ExampleTitleSortKey # noqa: E402
# Config for the matplotlib plot directive
plot_formats = [("svg", 250)]
# image_scrapers = (matplotlib_svg_scraper(), plotly_sg_scraper,)
-image_scrapers = (matplotlib_svg_scraper(),)
+image_scrapers = (partial(matplotlib_scraper, format="svg"), plotly_sg_scraper)
# -- Configuration for the sphinx-gallery extension -------------------------------
+
sphinx_gallery_conf = {
- "examples_dirs": ["../"], # directory where to find plotting scripts
+ "examples_dirs": [TOPLEVEL_DIR], # directory where to find plotting scripts
"gallery_dirs": ["gallery"], # directory where to store generated plots
"filename_pattern": "^((?!sgskip).)*$", # which files to execute
- "subsection_order": ExampleTitleSortKey,
- "within_subsection_order": ExampleTitleSortKey,
+ "subsection_order": ExampleTitleSortKey(TOPLEVEL_DIR),
+ "within_subsection_order": ExampleTitleSortKey(TOPLEVEL_DIR),
"reference_url": {"accelerator_timeline": None}, # Sets up intersphinx in gallery code
"backreferences_dir": "gen_modules/backreferences", # where function/class granular galleries are stored
# Modules for which function/class level galleries are created
@@ -228,6 +224,7 @@ def __call__(self, *args, **kwargs):
"compress_images": ("images", "thumbnails", "-o1"),
"only_warn_on_example_error": True, # keep the build going if an example fails, very important for doc workflow
"download_all_examples": False,
+ "ignore_pattern": r"^(tst_|_|\.).*", # ignore test/private files
}
# Config for the sphinx_panels extension
@@ -247,8 +244,8 @@ def __call__(self, *args, **kwargs):
# documentation.
html_theme_options = {
"collapse_navigation": False,
- "display_version": True,
"logo_only": True,
+ "version_selector": True,
"navigation_depth": 2,
}
@@ -547,7 +544,7 @@ def __call__(self, *args, **kwargs):
# -- Autodoc Configuration ---------------------------------------------------
# Add here all modules to be mocked up. When the dependencies are not met
-# at building time.
+# at building time.
autodoc_mock_imports = []
# -- Instersphinx Configuration ----------------------------------------------
diff --git a/doc/requirements.txt b/doc/requirements.txt
deleted file mode 100644
index 39afde7..0000000
--- a/doc/requirements.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-# 👇️ include packages for the scripts
--r ../requirements_export_charts.txt
--r ../requirements_interactive_charts.txt
-
-# packages for the doc
-sphinx
-sphinx_rtd_theme
-sphinx-gallery
-sphinx-copybutton
\ No newline at end of file
diff --git a/export_charts.py b/export_charts.py
index 836d0e8..4748310 100644
--- a/export_charts.py
+++ b/export_charts.py
@@ -1,13 +1,22 @@
-"""
+"""
Export Accelerator Timeline
***************************
-This is an example script to generate static plots of the accelerator data via
+This is an example script to generate static plots of the accelerator data via
matplotlib.
-To run the script, make sure your environment has the requirements
-of `requirements_export_charts.txt` installed.
+To run the script, make sure your environment has the requirements
+of `export_charts` installed,
+e.g. via `uv pip install -r pyproject.toml --extra export_charts`.
+This is automatically resolved when running this script via `uv run export_charts.py`.
"""
-import os
+# sphinx_gallery_start_ignore
+# /// script
+# dependencies = [
+# "accelerator-timeline[export_charts] @ git+https://github.com/pylhc/accelerator_timeline.git",
+# ]
+# ///
+# sphinx_gallery_end_ignore
+
from pathlib import Path
import matplotlib as mpl
@@ -18,14 +27,21 @@
from matplotlib.figure import Figure
from utilities.csv_reader import Column, import_collider_data
-from utilities.plot_helper import (PARTICLE_TYPES, PLOTLY_MPL_SYMBOL_MAP, EnergyConfiguration,
- LuminosityConfiguration, LuminosityOverEnergyConfiguration,
- PlotConfiguration, assign_textposition, check_all_types_accounted_for)
+from utilities.plot_helper import (
+ PARTICLE_TYPES,
+ PLOTLY_MPL_SYMBOL_MAP,
+ EnergyConfiguration,
+ LuminosityConfiguration,
+ LuminosityOverEnergyConfiguration,
+ PlotConfiguration,
+ assign_textposition,
+ check_all_types_accounted_for,
+)
from utilities.sphinx_helper import get_gallery_dir, is_sphinx_build
def plot(data: pd.DataFrame, configuration: PlotConfiguration) -> Figure:
- """Generate interactive plots with matplotlib, based on the given configuration,
+ """Generate interactive plots with matplotlib, based on the given configuration,
which defines the columns to use, labels and the text positions.
Args:
@@ -33,15 +49,15 @@ def plot(data: pd.DataFrame, configuration: PlotConfiguration) -> Figure:
configuration (PlotConfiguration): See :class:`utilities.plot_helper.PlotConfiguration`
Returns:
- Figure: Matplotlib figure
+ Figure: Matplotlib figure
"""
fig, ax = plt.subplots()
-
+
pad = mpl.rcParams["lines.markersize"]/3
vmap = {"top": pad, "middle": 0, "bottom": -pad}
hmap = {"left": -pad*2, "center": 0, "right": pad*2}
alignment_map = {
- "left": "right", "center": "center", "right": "left",
+ "left": "right", "center": "center", "right": "left",
"top": "bottom", "middle": "center", "bottom": "top"
}
@@ -56,7 +72,7 @@ def plot(data: pd.DataFrame, configuration: PlotConfiguration) -> Figure:
builtmask, fillstyle, legend_prefix = ~data[Column.BUILT], "none", "_"
ax.plot(
- data.loc[mask & builtmask, configuration.xcolumn],
+ data.loc[mask & builtmask, configuration.xcolumn],
data.loc[mask & builtmask, configuration.ycolumn],
linestyle="none",
marker=marker, fillstyle=fillstyle,
@@ -64,14 +80,14 @@ def plot(data: pd.DataFrame, configuration: PlotConfiguration) -> Figure:
label=f"{legend_prefix}{particle_type.latex}",
)
- for x, y, text, textposition in zip(data.loc[mask, configuration.xcolumn],
- data.loc[mask, configuration.ycolumn],
- data.loc[mask, Column.NAME],
+ for x, y, text, textposition in zip(data.loc[mask, configuration.xcolumn],
+ data.loc[mask, configuration.ycolumn],
+ data.loc[mask, Column.NAME],
data.loc[mask, configuration.textposition]):
v, h = textposition.split(" ")
- ax.annotate(text, xy=(x, y),
- xytext=(hmap[h], vmap[v]),
- textcoords="offset pixels",
+ ax.annotate(text, xy=(x, y),
+ xytext=(hmap[h], vmap[v]),
+ textcoords="offset pixels",
ha=alignment_map[h], va=alignment_map[v]
)
@@ -92,7 +108,7 @@ def plot(data: pd.DataFrame, configuration: PlotConfiguration) -> Figure:
ax.legend(loc='upper left', bbox_to_anchor=(1, 1), borderaxespad=0., title='Particles', ncol=1)
- return fig
+ return fig
if __name__ == "__main__":
@@ -108,7 +124,7 @@ def plot(data: pd.DataFrame, configuration: PlotConfiguration) -> Figure:
data = import_collider_data()
data = assign_textposition(data)
check_all_types_accounted_for(data)
-
+
fig_com = plot(data, EnergyConfiguration)
fig_com.savefig(output_dir / "energy.pdf")
fig_com.savefig(output_dir / "energy.png")
@@ -120,7 +136,7 @@ def plot(data: pd.DataFrame, configuration: PlotConfiguration) -> Figure:
fig_lumi_vs_com = plot(data, LuminosityOverEnergyConfiguration)
fig_lumi_vs_com.savefig(output_dir / "luminosity-vs-energy.pdf")
fig_lumi_vs_com.savefig(output_dir / "luminosity-vs-energy.png")
-
+
# plt.show()
# sphinx_gallery_thumbnail_path = 'gallery/luminosity-vs-energy.png'
diff --git a/interactive_charts.py b/interactive_charts.py
index c04b100..9eb3cc4 100644
--- a/interactive_charts.py
+++ b/interactive_charts.py
@@ -4,25 +4,36 @@
This script allows you to interactively explore the accelerator data,
either by running the script and viewing the plots in a browser,
-by running the script in interactive-mode e.g. in vscode
+by running the script in interactive-mode e.g. in vscode
or by checking the from this script generated gallery.
-To run the script, make sure your environment has the requirements
-of `requirements_interactive_charts.txt` installed.
+To run the script, make sure your environment has the requirements
+of `interactive_charts` installed,
+e.g. via `uv pip install -r pyproject.toml --extra interactive_charts`.
+This is automatically resolved when running this script via `uv run interactive_charts.py`.
"""
+# sphinx_gallery_start_ignore
+# /// script
+# dependencies = [
+# "accelerator-timeline[interactive_charts] @ git+https://github.com/pylhc/accelerator_timeline.git",
+# ]
+# ///
+# sphinx_gallery_end_ignore
+
#%%
-# Preparations
+# Preparations
# ------------
-#
+#
# Import modules and define plotting function.
# This code is omitted in the interactive gallery, so that you can immediately enjoy the interactive plots below.
-# Check `interactive.py `_
+# Check `interactive.py `_
# for the full example code.
#
# No code to see here in the interactive gallery or the generated jupyter notebook.
# sphinx_gallery_start_ignore
from pathlib import Path
+
import numpy as np
import pandas as pd
import plotly
@@ -30,12 +41,21 @@
from IPython.display import HTML, display
from utilities.csv_reader import Column, import_collider_data
-from utilities.plot_helper import (PARTICLE_TYPES, EnergyConfiguration, LuminosityConfiguration,
- LuminosityOverEnergyConfiguration, PlotConfiguration,
- assign_textposition, check_all_types_accounted_for)
+from utilities.plot_helper import (
+ PARTICLE_TYPES,
+ EnergyConfiguration,
+ LuminosityConfiguration,
+ LuminosityOverEnergyConfiguration,
+ PlotConfiguration,
+ assign_textposition,
+ check_all_types_accounted_for,
+)
from utilities.sphinx_helper import get_gallery_dir, is_interactive, is_sphinx_build
-# Hack for rendering LaTeX in VSCode
+if is_sphinx_build():
+ plotly.io.get_chrome()
+
+# Hack for rendering LaTeX in VSCode
# (see https://github.com/microsoft/vscode-jupyter/issues/8131#issuecomment-1589961116)
if not is_sphinx_build() and is_interactive():
display(HTML(
@@ -48,11 +68,11 @@
check_all_types_accounted_for(data)
# Plotting Function ---
-# This is the definition of the actual plotting function,
+# This is the definition of the actual plotting function,
# which creates the interactive plotly plots
def plot(data: pd.DataFrame, configuration: PlotConfiguration) -> go.Figure:
- """Generate interactive plots with plotly, based on the given configuration,
+ """Generate interactive plots with plotly, based on the given configuration,
which defines the columns to use and the text positions.
Args:
@@ -60,7 +80,7 @@ def plot(data: pd.DataFrame, configuration: PlotConfiguration) -> go.Figure:
configuration (PlotConfiguration): See :class:`utilities.plot_helper.PlotConfiguration`
Returns:
- go.Figure: plotly figure
+ go.Figure: plotly figure
"""
fig = go.Figure()
@@ -71,20 +91,20 @@ def plot(data: pd.DataFrame, configuration: PlotConfiguration) -> go.Figure:
builtmask, marker_suffix, legend = data[Column.BUILT], "", "built"
else:
builtmask, marker_suffix, legend = ~data[Column.BUILT], "-open", "not built"
-
+
mask = particle_mask & builtmask
fig.add_trace(go.Scatter(
- x=data.loc[mask & builtmask, configuration.xcolumn],
+ x=data.loc[mask & builtmask, configuration.xcolumn],
y=data.loc[mask & builtmask, configuration.ycolumn],
name=legend,
legendgroup=particle_type.name,
legendgrouptitle_text=particle_type.latex,
text=data.loc[mask, Column.NAME],
textposition=data.loc[mask, configuration.textposition],
- mode="markers+text",
- marker={"symbol": f"{particle_type.symbol}{marker_suffix}",
- "color": particle_type.color},
+ mode="markers+text",
+ marker={"symbol": f"{particle_type.symbol}{marker_suffix}",
+ "color": particle_type.color},
customdata=np.transpose([
data.loc[mask, Column.NAME],
[particle_type.name] * sum(mask),
@@ -110,9 +130,9 @@ def plot(data: pd.DataFrame, configuration: PlotConfiguration) -> go.Figure:
logx, logy = "x" in configuration.logscale, "y" in configuration.logscale
fig.update_xaxes(
- title=configuration.xlabel,
+ title=configuration.xlabel,
type="log" if logx else "linear",
- dtick=1 if logx else 10,
+ dtick=1 if logx else 10,
minor=dict(dtick="D1" if logx else 1, ticks="outside"),
ticks='outside',
showline=True,
@@ -120,11 +140,11 @@ def plot(data: pd.DataFrame, configuration: PlotConfiguration) -> go.Figure:
gridcolor='lightgrey'
)
fig.update_yaxes(
- title=configuration.ylabel,
+ title=configuration.ylabel,
type="log" if "y" in configuration.logscale else "linear",
ticks='outside',
- dtick=1 if logy else 10,
- minor=dict(dtick="D1" if logy else None, ticks="outside", showgrid=False),
+ dtick=1 if logy else 10,
+ minor={'dtick': "D1" if logy else None, 'ticks': "outside", 'showgrid': False},
showline=True,
linecolor='black',
gridcolor='lightgrey',
@@ -140,7 +160,7 @@ def plot(data: pd.DataFrame, configuration: PlotConfiguration) -> go.Figure:
#%%
# Energy Timeline
# ---------------
-#
+#
fig_com = plot(data, EnergyConfiguration)
# sphinx_gallery_start_ignore
@@ -162,7 +182,7 @@ def plot(data: pd.DataFrame, configuration: PlotConfiguration) -> go.Figure:
# sphinx_gallery_end_ignore
#%%
-# Luminosity vs. Energy
+# Luminosity vs. Energy
# ---------------------
#
@@ -173,10 +193,10 @@ def plot(data: pd.DataFrame, configuration: PlotConfiguration) -> go.Figure:
fig_lumi_energy
# sphinx_gallery_end_ignore
-#%%
+#%%
# Save plots
# ----------
-#
+#
# Save the plots as PDF and PNG.
output_dir = Path("images")
@@ -185,6 +205,7 @@ def plot(data: pd.DataFrame, configuration: PlotConfiguration) -> go.Figure:
output_dir = get_gallery_dir()
# sphinx_gallery_end_ignore
+output_dir.mkdir(parents=True, exist_ok=True)
plotly.io.write_image(fig_com, output_dir / "energy-plotly.pdf", format="pdf")
plotly.io.write_image(fig_com, output_dir / "energy-plotly.png", format="png")
plotly.io.write_image(fig_lumi, output_dir / "luminosity-plotly.pdf", format="pdf")
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..aa836c2
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,136 @@
+[build-system]
+requires = ["hatchling"]
+build-backend = "hatchling.build"
+
+[tool.hatch.version]
+path = "__init__.py"
+
+[tool.hatch.build.targets.sdist]
+exclude = [
+ "/.github",
+ "/doc",
+ "/images",
+]
+
+[tool.hatch.build.targets.wheel]
+packages = ["accelerator_timeline"]
+
+[project]
+name = "accelerator_timeline"
+readme = "README.md"
+description = "A non-exhaustive collection of past, modern and future accelerators including their main parameters."
+authors = [
+ {name = "OMC Team", email = "pylhc@github.com"}, # see zenodo file / commits for details
+]
+license = "MIT"
+dynamic = ["version"]
+requires-python = ">=3.10"
+
+classifiers = [
+ "Development Status :: 5 - Production/Stable",
+ "Intended Audience :: Science/Research",
+ "Natural Language :: English",
+ "Operating System :: OS Independent",
+ "Programming Language :: Python :: 3 :: Only",
+ "Programming Language :: Python :: 3.10",
+ "Programming Language :: Python :: 3.11",
+ "Programming Language :: Python :: 3.12",
+ "Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: Implementation :: CPython",
+ "Topic :: Scientific/Engineering",
+ "Topic :: Software Development :: Libraries :: Python Modules",
+ "Typing :: Typed",
+]
+
+dependencies = [
+]
+
+[project.optional-dependencies]
+export_charts = [
+ "pandas",
+ "numpy",
+ "matplotlib",
+]
+
+interactive_charts = [
+ "nbformat",
+ "pandas",
+ "plotly",
+ "numpy",
+ "ipython",
+ "ipykernel",
+ "kaleido >= 1.0.0",
+]
+
+doc = [
+ "accelerator_timeline[export_charts]",
+ "accelerator_timeline[interactive_charts]",
+ "sphinx >= 9.0.0",
+ "sphinx_rtd_theme >= 3.1.0rc1",
+ "sphinx-gallery",
+ "sphinx-copybutton",
+]
+
+all = [
+ "accelerator_timeline[doc]", # contains all dependencies
+]
+
+[project.urls]
+homepage = "https://github.com/pylhc/accelerator_timeline"
+repository = "https://github.com/pylhc/accelerator_timeline"
+documentation = "https://pylhc.github.io/accelerator_timeline/"
+changelog = "https://github.com/pylhc/accelerator_timeline/blob/master/CHANGELOG.md"
+
+
+# ----- Dev Tools Configuration ----- #
+
+[tool.ruff]
+exclude = [
+ ".eggs",
+ ".git",
+ ".mypy_cache",
+ ".venv",
+ "_build",
+ "build",
+ "dist",
+]
+
+# Assume Python 3.10+
+target-version = "py310"
+
+line-length = 100
+indent-width = 4
+
+[tool.ruff.lint]
+# Allow unused variables when underscore-prefixed.
+dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
+ignore = [
+ "E501", # line too long
+ "FBT001", # boolean-type-hint-positional-argument
+ "FBT002", # boolean-default-value-positional-argument
+ "PT019", # pytest-fixture-param-without-value (but suggested solution fails)
+]
+extend-select = [
+ "F", # Pyflakes rules
+ "W", # PyCodeStyle warnings
+ "E", # PyCodeStyle errors
+ "I", # Sort imports properly
+ "A", # Detect shadowed builtins
+ "N", # enforce naming conventions, e.g. ClassName vs function_name
+ "UP", # Warn if certain things can changed due to newer Python versions
+ "C4", # Catch incorrect use of comprehensions, dict, list, etc
+ "FA", # Enforce from __future__ import annotations
+ "FBT", # detect boolean traps
+ "ISC", # Good use of string concatenation
+ "BLE", # disallow catch-all exceptions
+ "ICN", # Use common import conventions
+ "RET", # Good return practices
+ "SIM", # Common simplification rules
+ "TID", # Some good import practices
+ "TC", # Enforce importing certain types in a TYPE_CHECKING block
+ "PTH", # Use pathlib instead of os.path
+ "NPY", # Some numpy-specific things
+]
+# Allow fix for all enabled rules (when `--fix`) is provided.
+fixable = ["ALL"]
+unfixable = []
diff --git a/requirements_export_charts.txt b/requirements_export_charts.txt
deleted file mode 100644
index 44974cf..0000000
--- a/requirements_export_charts.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-pandas
-numpy
-matplotlib
\ No newline at end of file
diff --git a/requirements_interactive_charts.txt b/requirements_interactive_charts.txt
deleted file mode 100644
index 4c5e52d..0000000
--- a/requirements_interactive_charts.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-nbformat
-pandas
-plotly
-numpy
-ipython
-ipykernel
-kaleido
\ No newline at end of file
diff --git a/utilities/sphinx_helper.py b/utilities/sphinx_helper.py
index 247ee90..5c99404 100644
--- a/utilities/sphinx_helper.py
+++ b/utilities/sphinx_helper.py
@@ -1,20 +1,20 @@
-"""
+"""
Sphinx Helper
*************
Some functionality to make working with Sphinx easier.
"""
import os
-from pathlib import Path
import sys
+from pathlib import Path
SPHINX_BUILD_ENVIRON = "SPHINX_BUILD"
def get_gallery_dir() -> Path:
- """ Get the gallery directory.
-
+ """ Get the gallery directory.
+
Returns:
Path: Path to the gallery directory.
"""
@@ -36,4 +36,4 @@ def is_interactive() -> bool:
Returns:
bool: True if in interactive mode.
"""
- return bool(getattr(sys, 'ps1', sys.flags.interactive))
\ No newline at end of file
+ return bool(getattr(sys, 'ps1', sys.flags.interactive))