Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure paths mentioned in Sphinx docs are valid #1183

Merged
merged 9 commits into from
Dec 14, 2023
84 changes: 84 additions & 0 deletions docs/source/_repopath.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import functools
import logging
import os
import subprocess
from pathlib import Path
from docutils import nodes

from sphinx.application import Sphinx as SphinxApp
from sphinx.roles import EmphasizedLiteral


_logger = logging.getLogger(f"sphinx.ext.{__name__}")


@functools.lru_cache
def _get_repo_root() -> Path:
try:
repo_root = subprocess.check_output(
["git", "rev-parse", "--show-toplevel"],
text=True,
).strip()
except subprocess.CalledProcessError as e:
raise RuntimeError("Unable to get repository root") from e
return Path(repo_root).resolve()


class RepoPath(EmphasizedLiteral):
@property
def path(self) -> Path:
repo_root = _get_repo_root()
return repo_root / self.text

def run(self):
if not self.path.exists():
_logger.warning("path %r does not exist", self.text)
return super().run()


class PathRoleBase:
def __init__(self, base_path=""):
self.base_path = Path(base_path)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why the Path constructor here? all the usage already passes a Path into the PathRoleBase

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly for robustness/defensiveness: the internals only work if self.base_path is a pathlib.Path, and pathlib.Path instances are immutable so creating a new Path is easier than having isinstance(..., Path) checks.


def validate(self, path: Path) -> None:
if not path.exists():
relpath = path.relative_to(self.base_path)
_logger.warning(
"path %r does not exist within %r", str(relpath), str(self.base_path)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for consistency maybe use os.fspath() rather than str() for both of these

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, I think I was just being lazy 😅

)

def display(self, path: Path, text="") -> str:
raise NotImplementedError

def __call__(
self,
name: str,
rawtext: str,
text: str,
lineno: int,
options: dict = None,
content: list = None,
):

path = self.base_path / text
self.validate(path)
path_to_display = self.display(path=path)
node = nodes.literal(path_to_display, path_to_display)
return [node], []


class Relpath(PathRoleBase):
def display(self, path: Path, text="") -> str:
return os.fspath(path.relative_to(self.base_path))


class Filename(PathRoleBase):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe override validate to add a is_file() check as well for this type

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea, I'll add that.

def display(self, path: Path, text="") -> str:
return path.name
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider returning something like path.name + ", and this file is located in " + os.fspath(path.parent.relative_to(self.base_path)) since that pattern occurs repeatedly in the usage

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good suggestion, maybe to keep in mind for a future iteration? I see the pattern you're referring to, but having the role handle more complicated formatting (since the prose would have to be formatted differently than the actual path) looked quite a bit trickier than the current implementation.



def setup(app: SphinxApp):
repo_root = _get_repo_root()

app.add_role("path", Relpath(repo_root))
app.add_role("filename", Filename(repo_root))
4 changes: 2 additions & 2 deletions docs/source/chapt_HI/tutorial/HI_test.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Tutorial: Heat Integration with FOQUS
=====================================

The files for this tutorial are located in:
**examples/tutorial_files/Heat_Integration**
:path:`examples/tutorial_files/Heat_Integration`

.. note:: |examples_reminder_text|

Expand Down Expand Up @@ -33,7 +33,7 @@ Procedure:
~~~~~~~~~~

#. Firstly, a SimSinter Configuration file must be created corresponding to the Aspen Plus backup file, which is located in
**examples/tutorial_files/Heat_Integration**. The simulation model is available in it.
:path:`examples/tutorial_files/Heat_Integration`. The simulation model is available in it.
Note: Ensure that Aspen v10 is used for this example.
Select the fresh feed flowrate and temperature as “input variables”, and inlet, outlet temperatures of the process streams
passing through all heaters and coolers (F2,F3,RF1,RF2,RP2,RP3,B2,BY-PROD,P1,PROD), along with heat duty of each heater, cooler as
Expand Down
8 changes: 4 additions & 4 deletions docs/source/chapt_flowsheet/tutorial/data.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@ be single runs, part of an optimization problem, or part of a UQ
ensemble. This tutorial provide information about sorting, filtering,
and exporting data.

The FOQUS file for this tutorial is **Simple_flow.foqus**, and
this file is located in: **examples/tutorial_files/Flowsheets/Tutorial_4**
The FOQUS file for this tutorial is :filename:`examples/tutorial_files/Flowsheets/Tutorial_4/Simple_flow.foqus`, and
this file is located in :path:`examples/tutorial_files/Flowsheets/Tutorial_4`.

.. note:: |examples_reminder_text|

The **Simple_flow.foqus** file is
The :filename:`examples/tutorial_files/Flowsheets/Tutorial_4/Simple_flow.foqus` file is
similar to the one created in the tutorial Section
:ref:`tutorial.sim.flowsheet`, but it has been run
an additional 100 times using a UQ ensemble (see :ref:`subsec:uqt_sim`).

#. Open FOQUS.

#. Open the Simple_flow.foqus session from the example files.
#. Open the :path:`examples/tutorial_files/Flowsheets/Tutorial_4/Simple_flow.foqus` session from the example files.

#. Click the **Flowsheet** button from the Home window.

Expand Down
6 changes: 3 additions & 3 deletions docs/source/chapt_flowsheet/tutorial/recycle.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ recycle. Sections :ref:`tutorial.simple.flow` and
for creating flowsheets, in this section a pre-constructed flowsheet is
used.

The file for this tutorial is **Mass_Bal_Test_02.foqus**, and
this file is located in **examples/tutorial_files/Flowsheets/Tutorial_3**
The file for this tutorial is :filename:`examples/tutorial_files/Flowsheets/Tutorial_3/Mass_Bal_Test_02.foqus`, and
this file is located in :path:`examples/tutorial_files/Flowsheets/Tutorial_3`.

.. note:: |examples_reminder_text|

#. Open FOQUS.

3. Open the Mass_Bal_Test_02.foqus file.
3. Open the :path:`examples/tutorial_files/Flowsheets/Tutorial_3/Mass_Bal_Test_02.foqus` file.

#. Open the **Session** drop-down menu on the right side of the
**Session** button (Figure :ref:`fig.recycle.tut1`).
Expand Down
8 changes: 4 additions & 4 deletions docs/source/chapt_flowsheet/tutorial/sim_flowsheet.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ before adding capture) supercritical pulverized coal power plant with
solid sorbent post combustion CO\ :math:`_2` capture process added.

The files for this tutorial is located in:
**examples/test_files/Optimization/Model_Files/**.
:path:`examples/test_files/Optimization/Model_Files`.

.. note:: |examples_reminder_text|

Expand Down Expand Up @@ -57,9 +57,9 @@ The files for this tutorial is located in:

There are two models needed for this optimization problem: (1) the ACM model for
the BFB capture system and (2) the Excel cost estimating spreadsheet. These
models are provided in the ``example/Optimization/Model_Files/`` directory. There are two SimSinter configuration
files: (1) ``BFB_sinter_config_v6.2.json`` for the process model and (2)
``BFB_cost_v6.2.3.json`` for the cost model. The next step is to upload the models
models are provided in the :path:`examples/test_files/Optimization/Model_Files/` directory. There are two SimSinter configuration
files: (1) :filename:`examples/test_files/Optimization/Model_Files/BFB_sinter_config_v6.2.json` for the process model and (2)
:filename:`examples/test_files/Optimization/Model_Files/BFB_cost_v6.2.3.json` for the cost model. The next step is to upload the models
to Turbine.

6. Open the **Add/Update Model to Turbine** dialog box (Figure
Expand Down
2 changes: 1 addition & 1 deletion docs/source/chapt_flowsheet/tutorial/simple_flowsheet.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ simulation errors can be observed when a negative input value is
provided.

This tutorial will show the user the procedure for creating a flowsheet in FOQUS.
However, if the user is interested, the finished flowsheet is available in: **examples/tutorial_files/Flowsheets/Tutorial_1**
However, if the user is interested, the finished flowsheet is available in: :path:`examples/tutorial_files/Flowsheets/Tutorial_4`

.. note:: |examples_reminder_text|

Expand Down
2 changes: 1 addition & 1 deletion docs/source/chapt_idaes/tutorial/idaes_test.rst
Original file line number Diff line number Diff line change
Expand Up @@ -206,5 +206,5 @@ It should be noted that the values within Node Input Variables can be changed as
It is recommended that FOQUS and IDAES must be installed in the same conda environment for this example to run successfully.

The complete FOQUS file (**FOQUS_IDAES_Example.foqus**), that includes the IDAES model,
is located in: **examples/tutorial_files/IDAES**.
is located in: :path:`examples/tutorial_files/IDAES`.
|examples_reminder_text|
2 changes: 1 addition & 1 deletion docs/source/chapt_odoe/tutorials.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Tutorials

This section walks through a couple of examples of running ODoE.

The files for these tutorials are located in: **examples/tutorial_files/ODOE**
The files for these tutorials are located in: :path:`examples/tutorial_files/ODOE`

The first example will use an existing candidate set and an existing evaluation set.

Expand Down
2 changes: 1 addition & 1 deletion docs/source/chapt_opt/tutorial/simple.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ optimization. This tutorial builds on the tutorial in Section
:ref:`tutorial.sim.flowsheet`.

The files for this tutorial are located in:
**examples/test_files/Optimization/Model_Files/**
:path:`examples/test_files/Optimization/Model_Files/`

.. note:: |examples_reminder_text|

Expand Down
2 changes: 1 addition & 1 deletion docs/source/chapt_ouu/tutorial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Tutorials

This section walks through a few examples of running OUU.

The files for these tutorials are located in: **examples/tutorial_files/OUU**
The files for these tutorials are located in: :path:`examples/tutorial_files/OUU`

.. note:: |examples_reminder_text|

Expand Down
2 changes: 1 addition & 1 deletion docs/source/chapt_pyomo/tutorial/pyomo_test.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Subject to:
ax_1 + bx_2 \geq c

The complete FOQUS file (**Pyomo_Test_Example.foqus**), with the code written,
is located in: **examples/tutorial_files/PYOMO**
is located in: :path:`examples/tutorial_files/PYOMO`

.. note:: |examples_reminder_text|

Expand Down
2 changes: 1 addition & 1 deletion docs/source/chapt_sdoe/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Example NUSF-2 considers a CCSI example, with a non-regular region, and the weig

Example IRSF-1 constructs a set of "best" designs (a Pareto front) along a spectrum of input and response space-filling. The designs are based on a 2-dimensional input space and a 1-dimensional response. Different designs along the Pareto front are compared to illustrate (a) what a Pareto front is and (b) how to choose a design from those on the Pareto front.

The files for these tutorials are located in: **examples/tutorial_files/SDOE**
The files for these tutorials are located in: :path:`examples/tutorial_files/SDOE`

.. note:: |examples_reminder_text|

Expand Down
2 changes: 1 addition & 1 deletion docs/source/chapt_sinter/tutorial/acm.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Tutorial 1: Aspen Custom Modeler (ACM) Configuration
====================================================

The files (both the ACM and the JSON files) for this tutorial
are located in: **examples/test_files/Optimization/Model_Files/**
are located in: :path:`examples/test_files/Optimization/Model_Files/`

.. note:: |examples_reminder_text|

Expand Down
2 changes: 1 addition & 1 deletion docs/source/chapt_sinter/tutorial/ap.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Tutorial 2: Aspen Plus Configuration
====================================

The files (both the Aspen Plus file and the JSON file)
for this tutorial are located in: **examples/tutorial_files/SimSinter/Tutorial_2**
for this tutorial are located in: :path:`examples/tutorial_files/SimSinter/Tutorial_2`

.. note:: |examples_reminder_text|

Expand Down
2 changes: 1 addition & 1 deletion docs/source/chapt_sinter/tutorial/excel.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Tutorial 3: Microsoft Excel Configuration
=========================================

The files (both the Excel and the JSON files) for this tutorial are
located in: **examples/tutorial_files/SimSinter/Tutorial_3**
located in: :path:`examples/tutorial_files/SimSinter/Tutorial_3`

.. note:: |examples_reminder_text|

Expand Down
2 changes: 1 addition & 1 deletion docs/source/chapt_sinter/tutorial/gproms.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ gPROMS simulation be runnable with SimSinter. They are divided up to
make later reference easier.

The files for this tutorial are located in:
**examples/tutorial_files/SimSinter/Tutorial_4**
:path:`examples/tutorial_files/SimSinter/Tutorial_4`

.. note:: |examples_reminder_text|

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ specifying that the CO2 mass % in the vapor phase should be at least 98.5 %. The

Step 1.1 - Setup the Aspen model for flash column as FOQUS simulation node : To setup the Aspen model in the FOQUS flowsheet,
first, create and add the SimSinter json file to turbine. Then, create a node named ‘FLASH’, and load the simulation in the node.
The Aspen and json files (along with the FOQUS file) can be found in the folder: **examples/tutorial_files/SM_Optimizer/Flash_Optimization**.
The Aspen and json files (along with the FOQUS file) can be found in the folder: :path:`examples/tutorial_files/SM_Optimizer/Flash_Optimization`.

.. note:: |examples_reminder_text|

Expand Down Expand Up @@ -207,7 +207,7 @@ MEA Carbon Capture System Optimization
The flue gas flowrate to the absorber is 2266.1 kg/hr with 17.314 % by mass CO2. It is sought to minimize the specific reboiler duty associated with the regenerator,
by varying the CO2 loading in the lean solvent entering the absorber.

Note: The Aspen, json, and FOQUS files for this example can be found in the folder: **examples/tutorial_files/SM_Optimizer/MEA_Optimization**
Note: The Aspen, json, and FOQUS files for this example can be found in the folder: :path:`examples/tutorial_files/SM_Optimizer/MEA_Optimization`

**Result:**
After implementing the SM based optimization solver, the solution is:
Expand Down
2 changes: 1 addition & 1 deletion docs/source/chapt_surrogates/tutorial/acosso.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ This tutorial uses the same flowsheet and sample setup as the ALAMO
tutorial in Section :ref:`sec.surrogate.alamo`.

The FOQUS file for this tutorial is **Surrogate_Tutorial_1.foqus**, and
this file is located in: **examples/tutorial_files/Surrogates**
this file is located in: :path:`examples/tutorial_files/Surrogates`

.. note:: |examples_reminder_text|

Expand Down
2 changes: 1 addition & 1 deletion docs/source/chapt_surrogates/tutorial/alamo.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ executable file must be set in FOQUS settings (see Section

The FOQUS file (**Surrogate_Tutorial_1.foqus**),
where Steps 1 to 42 of this tutorial have been completed
is located in: **examples/tutorial_files/Surrogates**
is located in: :path:`examples/tutorial_files/Surrogates`

.. note:: |examples_reminder_text|

Expand Down
2 changes: 1 addition & 1 deletion docs/source/chapt_surrogates/tutorial/bssanova.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ This tutorial uses the same flowsheet and sample setup as the ALAMO
tutorial in Section :ref:`sec.surrogate.alamo`.

The FOQUS file for this tutorial is **Surrogate_Tutorial_1.foqus**, and
this file is located in: **examples/tutorial_files/Surrogates**
this file is located in: :path:`examples/tutorial_files/Surrogates`

.. note:: |examples_reminder_text|

Expand Down
2 changes: 1 addition & 1 deletion docs/source/chapt_surrogates/tutorial/neural_networks.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ https://scikit-learn.org/stable/index.html and further information on deep learn
https://scikit-learn.org/stable/modules/generated/sklearn.neural_network.MLPRegressor.html#sklearn.neural_network.MLPRegressor.

The FOQUS file for this tutorial is **Simple_flow.foqus**, and
this file is located in: **examples/tutorial_files/Flowsheets/Tutorial_4**
this file is located in: :path:`examples/tutorial_files/Flowsheets/Tutorial_4`

.. note:: |examples_reminder_text|

Expand Down
2 changes: 1 addition & 1 deletion docs/source/chapt_surrogates/tutorial/uq_model.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ been re-associated with other executables (e.g. editors), please change
the association back to python.exe.

The FOQUS file for this tutorial is **Rosenbrock_no_vectors.foqus**, and
this file is located in: **examples/tutorial_files/Surrogates**
this file is located in: :path:`examples/tutorial_files/Surrogates`

.. note:: |examples_reminder_text|

Expand Down
2 changes: 1 addition & 1 deletion docs/source/chapt_uq/tutorial/analysis.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ From the Single-Output Analysis Screen, the user can perform analyses
that are specific to a particular output of interest. Here, the
“removalCO2” output parameter is discussed.

The files for this tutorial are located in: **examples/tutorial_files/UQ/Tutorial_3**
The files for this tutorial are located in: :path:`examples/tutorial_files/UQ/Tutorial_3`

.. note:: |examples_reminder_text|

Expand Down
2 changes: 1 addition & 1 deletion docs/source/chapt_uq/tutorial/data.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ In this tutorial, instructions to change the data before analysis are
described. Current capabilities include sample filtering, input/output
variable deletion, and output value modification.

The files for this tutorial are located in: **examples/tutorial_files/UQ/Tutorial_2**
The files for this tutorial are located in: :path:`examples/tutorial_files/UQ/Tutorial_2`

.. note:: |examples_reminder_text|

Expand Down
2 changes: 1 addition & 1 deletion docs/source/chapt_uq/tutorial/inf.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ previously known (in the form of input prior distributions) and what was
observed currently (in the form of noisy outputs).

The file for this tutorial is **lptau5k_10inputs_4outputs.filtered**, and
this file is located in: **examples/tutorial_files/UQ/Tutorial_5**
this file is located in: :path:`examples/tutorial_files/UQ/Tutorial_5`

.. note:: |examples_reminder_text|

Expand Down
2 changes: 1 addition & 1 deletion docs/source/chapt_uq/tutorial/rs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Alternatively, if the sample size is large enough (one hundred or more),
cubic splines (if installed) may also be feasible.

The file for this tutorial is **lptau100_10inputs_4outputs.dat**, and
this file is located in: **examples/tutorial_files/UQ/Tutorial_4**
this file is located in: :path:`examples/tutorial_files/UQ/Tutorial_4`

.. note:: |examples_reminder_text|

Expand Down
2 changes: 1 addition & 1 deletion docs/source/chapt_uq/tutorial/sim.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Creating a simulation ensemble using the variables' distributions
In this tutorial, a simulation ensemble is created (using FOQUS) and run.

The FOQUS file for this tutorial is **Rosenbrock_no_vectors.foqus**, and
this file is located in: **examples/tutorial_files/UQ/Tutorial_1**
this file is located in: :path:`examples/tutorial_files/UQ/Tutorial_1`

.. note:: |examples_reminder_text|

Expand Down
5 changes: 5 additions & 0 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import sys

sys.path.insert(0, os.path.abspath(".."))
sys.path.insert(0, os.path.abspath("."))

# For Read the Docs theme
import sphinx_rtd_theme
Expand All @@ -56,6 +57,10 @@
"sphinx.ext.githubpages",
"sphinx.ext.napoleon",
"sphinx.ext.autosectionlabel",
# sphinxcontrib.jquery needed for search to work on some versions of RTD theme
# see https://github.com/readthedocs/sphinx_rtd_theme/issues/1452
"sphinxcontrib.jquery",
"_repopath",
# 'sphinxarg.ext',
# 'sphinx-jsonschema'
]
Expand Down
Loading