From de5ddfd37141c7138f7aea1583894de704c369ad Mon Sep 17 00:00:00 2001
From: "Alex H. Room" <69592136+alexhroom@users.noreply.github.com>
Date: Wed, 19 Feb 2025 10:31:00 +0000
Subject: [PATCH] Adds Jupyter notebooks and MATLAB live scripts to the
examples (#30)
* rearranged examples to make way for python
* script for getting tutorials
* fixed matlab images and made setup tutorial simpler
* split tutorials folder into two
* split tutorials folder into two
* added livescripts to matlab examples
* added nbsphinx to requirements and install pandoc in CI
* removed python-rat data from repo
* made notebooks part of build process
* fix ci
* added prolog to notebooks
* matlab live scripts now have outputs
* updated readme, fixed typo, added examples to header
* update notebooks readme
* tidied up header
* complete rebase (whoops!)
* review fixes
---
.github/workflows/build_docs.yml | 9 ++
.gitignore | 4 +
README.md | 2 +
requirements.txt | 2 +
source/conf.py | 76 ++++++++++++++++-
source/examples.rst | 21 +++++
source/examples/DSPC_custom_XY.rst | 79 ------------------
source/examples/DSPC_custom_layers.rst | 67 ---------------
source/examples/DSPC_standard_layers.rst | 55 ------------
source/examples/convert_r1_project.rst | 52 ------------
source/examples/custom_model_languages.rst | 56 -------------
source/examples/domains_custom_XY.rst | 60 -------------
source/examples/domains_custom_layers.rst | 60 -------------
source/examples/domains_standard_layers.rst | 64 --------------
source/guide.rst | 3 +-
source/index.rst | 9 +-
source/matlab_examples.pdf | Bin 0 -> 45874 bytes
source/matlab_examples/DSPC_custom_XY.rst | 49 +++++++++++
source/matlab_examples/DSPC_custom_layers.rst | 41 +++++++++
.../matlab_examples/DSPC_standard_layers.rst | 30 +++++++
source/matlab_examples/convert_r1_project.rst | 23 +++++
.../custom_model_languages.rst | 36 ++++++++
source/matlab_examples/domains_custom_XY.rst | 33 ++++++++
.../matlab_examples/domains_custom_layers.rst | 33 ++++++++
.../domains_standard_layers.rst | 39 +++++++++
.../imaginary.rst | 0
.../{examples => matlab_examples}/index.rst | 10 +--
source/python_examples/index.rst | 37 ++++++++
source/python_examples/notebooks/README.md | 5 ++
source/reference/index.rst | 24 ++++++
30 files changed, 474 insertions(+), 505 deletions(-)
create mode 100644 source/examples.rst
delete mode 100644 source/examples/DSPC_custom_XY.rst
delete mode 100644 source/examples/DSPC_custom_layers.rst
delete mode 100644 source/examples/DSPC_standard_layers.rst
delete mode 100644 source/examples/convert_r1_project.rst
delete mode 100644 source/examples/custom_model_languages.rst
delete mode 100644 source/examples/domains_custom_XY.rst
delete mode 100644 source/examples/domains_custom_layers.rst
delete mode 100644 source/examples/domains_standard_layers.rst
create mode 100644 source/matlab_examples.pdf
create mode 100644 source/matlab_examples/DSPC_custom_XY.rst
create mode 100644 source/matlab_examples/DSPC_custom_layers.rst
create mode 100644 source/matlab_examples/DSPC_standard_layers.rst
create mode 100644 source/matlab_examples/convert_r1_project.rst
create mode 100644 source/matlab_examples/custom_model_languages.rst
create mode 100644 source/matlab_examples/domains_custom_XY.rst
create mode 100644 source/matlab_examples/domains_custom_layers.rst
create mode 100644 source/matlab_examples/domains_standard_layers.rst
rename source/{examples => matlab_examples}/imaginary.rst (100%)
rename source/{examples => matlab_examples}/index.rst (82%)
create mode 100644 source/python_examples/index.rst
create mode 100644 source/python_examples/notebooks/README.md
create mode 100644 source/reference/index.rst
diff --git a/.github/workflows/build_docs.yml b/.github/workflows/build_docs.yml
index 4ee01d69..815f8ba0 100644
--- a/.github/workflows/build_docs.yml
+++ b/.github/workflows/build_docs.yml
@@ -21,8 +21,17 @@ jobs:
python-version: '3.11'
- name: Build docs
run: |
+ # create an x11 display because otherwise MATLAB refuses to export live scripts...
+ sudo apt install -y xvfb
+ export DISPLAY=':99.0'
+ Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
+
wget https://github.com/RascalSoftware/RAT/releases/download/nightly/Linux.zip
unzip Linux.zip -d API/
+
+ # we get pandoc from web as apt version is outdated
+ wget https://github.com/jgm/pandoc/releases/download/3.6.2/pandoc-3.6.2-1-amd64.deb
+ sudo apt install -y ./pandoc-3.6.2-1-amd64.deb
python -m pip install --upgrade pip
pip install matlabengine==24.1.*
pip install -r requirements.txt
diff --git a/.gitignore b/.gitignore
index c7c5425b..73092706 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,3 +19,7 @@ source/_outputs/
# autogenerated documentation
source/reference/python/RATapi.*
+source/python_examples/data/
+source/matlab_examples/*.html
+source/python_examples/notebooks/*
+!source/python_examples/notebooks/README.md
diff --git a/README.md b/README.md
index 3c88d0ee..c8fe400a 100644
--- a/README.md
+++ b/README.md
@@ -17,6 +17,8 @@ Download the appropriate version of RAT from the GitHub [release](https://github
wget https://github.com/RascalSoftware/RAT/releases/download/nightly/Linux.zip
unzip Linux.zip -d API/
+You also must have `pandoc` installed to build the Python example Jupyter notebooks. See the installation instructions [here](https://pandoc.org/installing.html).
+
To build the HTML docs, type the following into a terminal with access to the Python executable:
diff --git a/requirements.txt b/requirements.txt
index 540e74f2..49410a82 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -3,6 +3,8 @@ sphinxcontrib-matlabdomain==0.18
pydata-sphinx-theme==0.15.2
sphinx_design==0.6.0
sphinx-copybutton==0.5.2
+jupyter==1.0.0
+nbsphinx==0.9.6
RATapi==0.0.0.dev4
autodoc_pydantic==2.2.0
enum-tools[sphinx]==0.12.0
diff --git a/source/conf.py b/source/conf.py
index 29dd9e11..6d05b51f 100644
--- a/source/conf.py
+++ b/source/conf.py
@@ -7,8 +7,13 @@
# documentation root, use os.path.abspath to make it absolute, like shown here.
import os
import sys
+import shutil
import datetime
+import zipfile
+from importlib import metadata
from urllib.parse import urljoin
+from urllib.request import urlretrieve
+from pathlib import Path
# -- Project information -----------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
@@ -33,17 +38,60 @@
sys.path.insert(0, os.path.dirname(os.path.abspath("..")))
from version import get_doc_version
doc_version = get_doc_version()
-
+
# -- General configuration ---------------------------------------------------
# add extensions path for snippets
sys.path.append(os.path.abspath("./_ext"))
-extensions = ['sphinxcontrib.matlab', 'sphinx.ext.napoleon', 'sphinx.ext.autodoc', 'sphinx.ext.autosummary', 'sphinxcontrib.autodoc_pydantic', 'sphinx_design', 'sphinx_copybutton', 'snippets', 'enum_tools.autoenum']
+extensions = ['sphinxcontrib.matlab', 'sphinx.ext.napoleon', 'sphinx.ext.autodoc', 'sphinx.ext.autosummary', 'sphinxcontrib.autodoc_pydantic', 'sphinx_design', 'sphinx_copybutton', 'snippets', 'enum_tools.autoenum', 'nbsphinx']
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
+# -- Setup example files -----------------------------------------------------
+PYTHON_RAT_RELEASE = metadata.version("RATapi")
+
+if not os.path.isdir("./python_examples/data"):
+ zip_dir, headers = urlretrieve(f"https://github.com/RascalSoftware/python-RAT/archive/refs/tags/{PYTHON_RAT_RELEASE}.zip")
+ with zipfile.ZipFile(zip_dir) as zf:
+ zf.extractall()
+ print("Copying Jupyter notebooks...")
+ for directory in ['normal_reflectivity', 'domains', 'absorption']:
+ for file in Path(f"./python-RAT-{PYTHON_RAT_RELEASE}/RATapi/examples/{directory}/").glob('*'):
+ shutil.copy(file, "./python_examples/notebooks/")
+
+ shutil.copytree(f"./python-RAT-{PYTHON_RAT_RELEASE}/RATapi/examples/data", "./python_examples/data", dirs_exist_ok=True)
+
+ shutil.rmtree(f"./python-RAT-{PYTHON_RAT_RELEASE}")
+
+if not os.path.isfile("./matlab_examples/standardLayersDSPCSheet.html"):
+ try:
+ from matlab.engine import start_matlab
+ except ImportError:
+ print("Could not copy MATLAB live scripts as MATLAB is not installed.")
+ else:
+ print("Starting MATLAB Engine...")
+ eng = start_matlab()
+ matlab_examples_path = Path("./matlab_examples").resolve()
+ eng.eval("cd('../API'); addPaths;", nargout=0)
+ for sheet in ['normalReflectivity/standardLayers/standardLayersDSPCSheet',
+ 'normalReflectivity/customLayers/customLayersDSPCSheet',
+ 'normalReflectivity/customXY/customXYDSPCSheet',
+ 'domains/standardLayers/domainsStandardLayersSheet',
+ 'domains/customLayers/domainsCustomLayersSheet',
+ 'domains/customXY/domainsCustomXYSheet',
+ 'miscellaneous/convertRascal1Project/convertRascal',
+ 'miscellaneous/alternativeLanguages/customModelLanguagesSheet',]:
+ filename = Path(sheet).name
+ folder = str(Path(sheet).parent)
+ print(f"exporting {sheet}")
+ eng.cd(f"examples/{folder}", nargout=0)
+ eng.matlab.internal.liveeditor.executeAndSave(str(Path(f"../API/examples/{sheet}.mlx").resolve()), nargout=0)
+ eng.export(f"{filename}.mlx", str(matlab_examples_path / f"{filename}.html"), nargout=0)
+ eng.cd("../../../", nargout=0)
+
+
# -- Options for HTML output -------------------------------------------------
#set primary_domain = 'matlab'
primary_domain = None
@@ -84,6 +132,30 @@
autodoc_typehints = "description"
+nbsphinx_prolog = r"""
+{% set docname = 'doc/' + env.doc2path(env.docname, base=None)|string %}
+
+.. raw:: html
+
+
+
+.. note::
+
+ To get the output project and results from this example in your Python session, run:
+
+ .. code-block:: python
+
+ from RATapi.examples import {{ env.docname.split('/')|last|e }}
+ project, results = {{ env.docname.split('/')|last|e }}()
+
+-------------------------------------------------------------------------------------
+
+"""
+
### autodoc_pydantic settings
# hide JSON schemas by default
autodoc_pydantic_model_show_json = False
diff --git a/source/examples.rst b/source/examples.rst
new file mode 100644
index 00000000..151df19b
--- /dev/null
+++ b/source/examples.rst
@@ -0,0 +1,21 @@
+Examples
+========
+
+Several examples are provided for RAT in both Python and MATLAB:
+
+
+Matlab
+------
+
+.. toctree::
+ :maxdepth: 3
+
+ matlab_examples/index
+
+Python
+------
+
+.. toctree::
+ :maxdepth: 3
+
+ python_examples/index
diff --git a/source/examples/DSPC_custom_XY.rst b/source/examples/DSPC_custom_XY.rst
deleted file mode 100644
index 0697c2a8..00000000
--- a/source/examples/DSPC_custom_XY.rst
+++ /dev/null
@@ -1,79 +0,0 @@
-==============
-DSPC Custom XY
-==============
-
-This shows an example of using a :ref:`custom XY` model to analyse reflectivity from a supported bilayer of DSPC.
-
-Similar to :ref:`DSPC_Custom_Layers`, we can make use of the fact that the volumes, and of course the atomistic composition are known. So,
-for lipid tails for example, then we can take a literature value for the tails volume, have a fittable parameter for the lipid area per molecule, and then the tail thickness will simply be
-
-.. math:: \text{Tail Thick} = \frac{\text{Tail Volume}}{\text{Lipid APM}}.
-
-Since the volume is known, then the SLD of the tails is also obviously easily calculable.
-
-In this model, we make distributions to represent the volume fractions of each of the components in the sample, the convert these to SLD's, as described in :ref:`[1] `.
-
-We also make our volume fractions as optional outputted parameters from our file. The optional nature of this output means we can suppress it to run the model, then
-activate it to make final output plots of our analysis.
-
-.. image:: ../images/examples/volumeFractions.png
- :align: center
- :alt: Volume fractions
-
-This example can be run as a script or interactively using the instructions below.
-
-.. tab-set::
- :sync-group: code
-
- .. tab-item:: Matlab
- :sync: Matlab
-
- .. note:: The custom model used is a MATLAB model - **examples/normalReflectivity/customXY/customXYDSPC.m**.
-
- **Run Script**:
-
- .. code-block:: Matlab
-
- root = getappdata(0, 'root');
- cd(fullfile(root, 'examples', 'normalReflectivity', 'customXY'));
- customXYDSPCScript
-
- **Run Interactively**:
-
- .. code-block:: Matlab
-
- root = getappdata(0, 'root');
- cd(fullfile(root, 'examples', 'normalReflectivity', 'customXY'));
- edit customXYDSPCSheet
-
-
- .. tab-item:: Python
- :sync: Python
-
- .. note:: The custom model used is a Python model - **RATapi.examples.normal_reflectivity.custom_XY_DSPC.py**.
-
-
- **Run Script**:
-
- .. code-block:: console
-
- python RATapi.examples.normal_reflectivity.DSPC_custom_XY.py
-
- **Run as Function**:
-
- .. code-block:: Python
-
- import RATapi as RAT
- problem, results = RAT.examples.normal_reflectivity.DSPC_custom_XY()
-
- **Run Interactively**:
-
- .. code-block:: console
-
- jupyter notebook RATapi.examples.normal_reflectivity.DSPC_custom_XY.ipynb
-
-
-.. _ref_1:
-
-[1] Sheker et al, J. Appl. Phys, 100, 102216 (2011) [`DOI 10.1063/1.3661986 `_]
-
diff --git a/source/examples/DSPC_custom_layers.rst b/source/examples/DSPC_custom_layers.rst
deleted file mode 100644
index 4496f214..00000000
--- a/source/examples/DSPC_custom_layers.rst
+++ /dev/null
@@ -1,67 +0,0 @@
-.. _DSPC_Custom_Layers:
-
-==================
-DSPC Custom Layers
-==================
-
-This shows an example of using a :ref:`custom layers` model to analyse reflectivity from a supported bilayer of DSPC.
-
-In this example, we can make use of the fact that the volumes, and of course the atomistic composition are known. So, for lipid tails for example, then we can
-take a literature value for the tails volume, have a fittable parameter for the lipid area per molecule, and then the tail thickness will simply be
-
-.. math:: Tail Thick = Tail Volume / Lipid APM.
-
-Since the volume is known, then the SLD of the tails is also obviously easily calculable.
-
-In addition, the datasets for this example, have a resolution (per point) in their fourth column. We use this resolution in our analysis, rather than declaring a constant, fittable one.
-
-This example can be run as a script or interactively using the instructions below.
-
-.. tab-set::
- :sync-group: code
-
- .. tab-item:: Matlab
- :sync: Matlab
-
- .. note:: The custom model used is a MATLAB model - **examples/normalReflectivity/customLayers/customBilayerDSPC.m**.
-
- **Run Script**:
-
- .. code-block:: Matlab
-
- root = getappdata(0, 'root');
- cd(fullfile(root, 'examples', 'normalReflectivity', 'customLayers'));
- customLayersDSPCScript
-
- **Run Interactively**:
-
- .. code-block:: Matlab
-
- root = getappdata(0, 'root');
- cd(fullfile(root, 'examples', 'normalReflectivity', 'customLayers'));
- edit customLayersDSPCSheet.mlx
-
-
- .. tab-item:: Python
- :sync: Python
-
- .. note:: The custom model used is a Python model - **RATapi.examples.normal_reflectivity.custom_bilayer_DSPC.py**.
-
- **Run Script**:
-
- .. code-block:: console
-
- python RATapi.examples.normal_reflectivity.DSPC_custom_layers.py
-
- **Run as Function**:
-
- .. code-block:: Python
-
- import RATapi as RAT
- problem, results = RAT.examples.normal_reflectivity.DSPC_custom_layers()
-
- **Run Interactively**:
-
- .. code-block:: console
-
- jupyter notebook RATapi.examples.normal_reflectivity.DSPC_custom_layers.ipynb
diff --git a/source/examples/DSPC_standard_layers.rst b/source/examples/DSPC_standard_layers.rst
deleted file mode 100644
index 7c906e53..00000000
--- a/source/examples/DSPC_standard_layers.rst
+++ /dev/null
@@ -1,55 +0,0 @@
-.. _DSPC_Standard_Layers:
-
-====================
-DSPC Standard Layers
-====================
-This shows an example of using a :ref:`standard layers` model to analyse reflectivity from a floating bilayer of DSPC.
-
-The model is set up in the script, we set Gaussian priors on some of the parameters, build the two contrasts, run the calculation and plot the results.
-
-This example can be run as a script or interactively using the instructions below.
-
-.. tab-set::
- :sync-group: code
-
- .. tab-item:: Matlab
- :sync: Matlab
-
- **Run Script**:
-
- .. code-block:: Matlab
-
- root = getappdata(0, 'root');
- cd(fullfile(root, 'examples', 'normalReflectivity', 'standardLayers'));
- standardLayersDSPCScript
-
- **Run Interactively**:
-
- .. code-block:: Matlab
-
- root = getappdata(0, 'root');
- cd(fullfile(root, 'examples', 'normalReflectivity', 'standardLayers'));
- edit standardLayersDSPCSheet.mlx
-
-
- .. tab-item:: Python
- :sync: Python
-
- **Run Script**:
-
- .. code-block:: console
-
- python RATapi.examples.normal_reflectivity.DSPC_standard_layers.py
-
- **Run as Function**:
-
- .. code-block:: Python
-
- import RATapi as RAT
- problem, results = RAT.examples.normal_reflectivity.DSPC_standard_layers()
-
- **Run Interactively**:
-
- .. code-block:: console
-
- jupyter notebook RATapi.examples.normal_reflectivity.DSPC_standard_layers.ipynb
diff --git a/source/examples/convert_r1_project.rst b/source/examples/convert_r1_project.rst
deleted file mode 100644
index 38dc9145..00000000
--- a/source/examples/convert_r1_project.rst
+++ /dev/null
@@ -1,52 +0,0 @@
-=============================
-Converting a RasCAL-1 Project
-=============================
-
-If you have projects from RasCAL1, there is a simple utility supplied with the toolbox that makes converting between formats easy as explained in :ref:`conversionFuncs`.
-
-This example shows the conversion of a RasCAL-1 custom layers project into a RAT project and vice versa, because this is a custom layers project, the custom model
-function **Model_IIb.m** which in the example directory is required to run the converted RAT project successfully.
-
-This example can be run using the instructions below.
-
-.. tab-set::
- :sync-group: code
-
- .. tab-item:: Matlab
- :sync: Matlab
-
- .. note:: The custom model used is a MATLAB model - **examples/miscellaneous/convertRascal1Project/Model_IIb.m**.
-
- **Run Interactively**:
-
- .. code-block:: Matlab
-
- root = getappdata(0, 'root');
- cd(fullfile(root, 'examples', 'miscellaneous', 'convertRascal1Project'));
- edit convertRascal.mlx
-
-
- .. tab-item:: Python
- :sync: Python
-
- .. note:: The custom model used is a MATLAB model - **RATapi.examples.convert_rascal_project.Model_IIb.m**.
- A python version is provided for the jupyter notebook - **RATapi.examples.convert_rascal_project.Model_IIb.py**
-
- **Run Script**:
-
- .. code-block:: console
-
- python RATapi.examples.convert_rascal_project.convert_rascal.py
-
- **Run as Function**:
-
- .. code-block:: Python
-
- import RATapi as RAT
- problem, results = RAT.examples.convert_rascal_project.convert_rascal()
-
- **Run Interactively**:
-
- .. code-block:: console
-
- jupyter notebook RATapi.examples.convert_rascal_project.convert_rascal.ipynb
diff --git a/source/examples/custom_model_languages.rst b/source/examples/custom_model_languages.rst
deleted file mode 100644
index 80583b4d..00000000
--- a/source/examples/custom_model_languages.rst
+++ /dev/null
@@ -1,56 +0,0 @@
-==================================
-Alternative Custom Model Languages
-==================================
-
-In this example, we setup a :ref:`custom layers` problem using three different programming language (MATLAB, Python, and C++) to write the custom model function.
-The provided C++ function needs to be compiled into a dynamic library using instructions given in :ref:`customLanguages` or instructions specific to your compiler.
-
-
-This example can be run using the instructions below.
-
-.. tab-set::
- :sync-group: code
-
- .. tab-item:: Matlab
- :sync: Matlab
-
- .. note:: The custom models used are -
- **examples/miscellaneous/languages/alloyDomains.m**,
- **examples/miscellaneous/languages/alloyDomains.m**,
- **examples/miscellaneous/languages/alloyDomains.m**.
-
- .. warning:: For Python custom functions, you will need to setup the python environment for MATLAB, see `Setup MATLAB to use Python `_
-
- **Run Script**:
-
- .. code-block:: Matlab
-
- root = getappdata(0, 'root');
- cd(fullfile(root, 'examples', 'miscellaneous', 'alternativeLanguages'));
- customModelLanguagesScript
-
- **Run Interactively**:
-
- .. code-block:: Matlab
-
- root = getappdata(0, 'root');
- cd(fullfile(root, 'examples', 'miscellaneous', 'alternativeLanguages'));
- edit customModelLanguagesSheet.mlx
-
-
- .. tab-item:: Python
- :sync: Python
-
- .. note:: The custom models used are -
- **RATapi.examples.languages.custom_bilayer.cpp**,
- **RATapi.examples.languages.custom_bilayer.py**,
- **RATapi.examples.languages.custom_bilayer.m**.
-
- .. warning:: For MATLAB custom functions, ensure MATLAB and matlabengine are installed :ref:`install`.
-
- **Run Script**:
-
- .. code-block:: console
-
- python RATapi.examples.languages.run_custom_file_languages.py
-
diff --git a/source/examples/domains_custom_XY.rst b/source/examples/domains_custom_XY.rst
deleted file mode 100644
index 7f9bef42..00000000
--- a/source/examples/domains_custom_XY.rst
+++ /dev/null
@@ -1,60 +0,0 @@
-=================================
-Incoherent Summing with Custom XY
-=================================
-
-This is an example of using incoherent summing ('domains') from custom XY models.
-
-The domain custom XY model is similar to a normal custom models, except that the input (function arguments) of the custom function contains an additional 'domains' parameter as described in :ref:`domainsCustomModels`.
-
-This parameter tells the function which is the current domain, so the appropriate layer stack can be generated.
-
-This example can be run as a script or interactively using the instructions below.
-
-.. tab-set::
- :sync-group: code
-
- .. tab-item:: Matlab
- :sync: Matlab
-
- .. note:: The custom model used is a MATLAB model - **examples/domains/customXY/domainsXY.m**.
-
- **Run Script**:
-
- .. code-block:: Matlab
-
- root = getappdata(0, 'root');
- cd(fullfile(root, 'examples', 'domains', 'customXY'));
- domainsCustomXYScript
-
- **Run Interactively**:
-
- .. code-block:: Matlab
-
- root = getappdata(0, 'root');
- cd(fullfile(root, 'examples', 'domains', 'customXY'));
- edit domainsCustomXYSheet.mlx
-
-
- .. tab-item:: Python
- :sync: Python
-
- .. note:: The custom model used is a Python model - **RATapi.examples.domains.domains_XY_model.py**.
-
- **Run Script**:
-
- .. code-block:: console
-
- python RATapi.examples.domains.domains_custom_XY.py
-
- **Run as Function**:
-
- .. code-block:: Python
-
- import RATapi as RAT
- problem, results = RAT.examples.domains.domains_custom_XY()
-
- **Run Interactively**:
-
- .. code-block:: console
-
- jupyter notebook RATapi.examples.domains.domains_custom_XY.ipynb
diff --git a/source/examples/domains_custom_layers.rst b/source/examples/domains_custom_layers.rst
deleted file mode 100644
index 64f39d95..00000000
--- a/source/examples/domains_custom_layers.rst
+++ /dev/null
@@ -1,60 +0,0 @@
-=====================================
-Incoherent Summing with Custom Layers
-=====================================
-
-This is an example of using incoherent summing ('domains') from custom layers models. The sample is a simple two layer of permalloy/gold, with up/down domains
-
-The domain custom model is similar to a normal custom models, except that the input (function arguments) of the custom function contains an additional 'domains' parameter as described in :ref:`domainsCustomModels`.
-
-This parameter tells the function which is the current domain, so the appropriate layer stack can be generated.
-
-This example can be run as a script or interactively using the instructions below.
-
-.. tab-set::
- :sync-group: code
-
- .. tab-item:: Matlab
- :sync: Matlab
-
- .. note:: The custom model used is a MATLAB model - **examples/domains/customLayers/alloyDomains.m**.
-
- **Run Script**:
-
- .. code-block:: Matlab
-
- root = getappdata(0, 'root');
- cd(fullfile(root, 'examples', 'domains', 'customLayers'));
- domainsCustomXYScript
-
- **Run Interactively**:
-
- .. code-block:: Matlab
-
- root = getappdata(0, 'root');
- cd(fullfile(root, 'examples', 'domains', 'customLayers'));
- edit domainsCustomXYSheet.mlx
-
-
- .. tab-item:: Python
- :sync: Python
-
- .. note:: The custom model used is a Python model - **RATapi.examples.domains.alloy_domains.py**.
-
- **Run Script**:
-
- .. code-block:: console
-
- python RATapi.examples.domains.domains_custom_layers.py
-
- **Run as Function**:
-
- .. code-block:: Python
-
- import RATapi as RAT
- problem, results = RAT.examples.domains.domains_custom_layers()
-
- **Run Interactively**:
-
- .. code-block:: console
-
- jupyter notebook RATapi.examples.domains.domains_custom_layers.ipynb
diff --git a/source/examples/domains_standard_layers.rst b/source/examples/domains_standard_layers.rst
deleted file mode 100644
index ece6061a..00000000
--- a/source/examples/domains_standard_layers.rst
+++ /dev/null
@@ -1,64 +0,0 @@
-=======================================
-Incoherent Summing with Standard Layers
-=======================================
-
-Analysing data containing domains using standard layers models is done in a similar way to a normal standard layers model, but with a couple of
-additional steps.
-
-A normal standard layers model defines parameters, which are grouped into layers, and then these are arranged into contrasts. For sample containing domains, the
-layers are first grouped into domain 'contrasts', which are just groupings of layers with none of the additional parameters of a contrast (such as resolutions
-etc). Then, the actual experimental contrasts are built in the usual way, but with the model set as any two of the domains.
-
-.. image:: ../images/domainsGraph.png
- :align: center
- :alt: Domains graph
-
-To control the ratio between the domains, we can add domain ratios as described in :ref:`domainsStanlay`. And each contrast has an additional field
-for domain ratios which is set as one of the values from this block.
-
-This example can be run as a script or interactively using the instructions below.
-
-.. tab-set::
- :sync-group: code
-
- .. tab-item:: Matlab
- :sync: Matlab
-
- **Run Script**:
-
- .. code-block:: Matlab
-
- root = getappdata(0, 'root');
- cd(fullfile(root, 'examples', 'domains', 'standardLayers'));
- domainsStandardLayersScript
-
- **Run Interactively**:
-
- .. code-block:: Matlab
-
- root = getappdata(0, 'root');
- cd(fullfile(root, 'examples', 'domains', 'standardLayers'));
- edit domainsStandardLayersSheet.mlx
-
-
- .. tab-item:: Python
- :sync: Python
-
- **Run Script**:
-
- .. code-block:: console
-
- python RATapi.examples.domains.domains_standard_layers.py
-
- **Run as Function**:
-
- .. code-block:: Python
-
- import RATapi as RAT
- problem, results = RAT.examples.domains.domains_standard_layers()
-
- **Run Interactively**:
-
- .. code-block:: console
-
- jupyter notebook RATapi.examples.domains.domains_standard_layers.ipynb
diff --git a/source/guide.rst b/source/guide.rst
index 3c7c607c..502c74e5 100644
--- a/source/guide.rst
+++ b/source/guide.rst
@@ -8,7 +8,8 @@ User Guide
:maxdepth: 2
tutorial/index
- examples/index
+ matlab_examples/index
+ python_examples/index
algorithms/index
advanced/index
calcTypes/index
diff --git a/source/index.rst b/source/index.rst
index 0b05b0f4..fc8000fa 100644
--- a/source/index.rst
+++ b/source/index.rst
@@ -45,7 +45,9 @@ RAT contains a number of improvements over legacy RasCAL, including:
* :ref:`guide`: Learn the core principles of RAT with code snippets.
- * :ref:`examples`: Jump into some practical examples.
+ * :ref:`matlabExamples`: Jump into some practical examples for the MATLAB interface.
+
+ * :ref:`pythonExamples`: Explore some practical examples for the Python interface.
.. grid-item-card::
@@ -77,6 +79,5 @@ RAT contains a number of improvements over legacy RasCAL, including:
install
guide
- reference/matlab/index
- reference/python/index
-
+ examples
+ reference/index
diff --git a/source/matlab_examples.pdf b/source/matlab_examples.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..086835e9f9ae59c142ee4839e263afbea4c65a10
GIT binary patch
literal 45874
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
YA(F^MtOE!khd|1JfH#(nw3tBu1u~}c)&Kwi
literal 0
HcmV?d00001
diff --git a/source/matlab_examples/DSPC_custom_XY.rst b/source/matlab_examples/DSPC_custom_XY.rst
new file mode 100644
index 00000000..21fab247
--- /dev/null
+++ b/source/matlab_examples/DSPC_custom_XY.rst
@@ -0,0 +1,49 @@
+==============
+DSPC Custom XY
+==============
+
+This shows an example of using a :ref:`custom XY` model to analyse reflectivity from a supported bilayer of DSPC.
+
+Similar to :ref:`DSPC_Custom_Layers`, we can make use of the fact that the volumes, and of course the atomistic composition are known. So,
+for lipid tails for example, then we can take a literature value for the tails volume, have a fittable parameter for the lipid area per molecule, and then the tail thickness will simply be
+
+.. math:: \text{Tail Thick} = \frac{\text{Tail Volume}}{\text{Lipid APM}}.
+
+Since the volume is known, then the SLD of the tails is also obviously easily calculable.
+
+In this model, we make distributions to represent the volume fractions of each of the components in the sample, the convert these to SLD's, as described in :ref:`[1] `.
+
+We also make our volume fractions as optional outputted parameters from our file. The optional nature of this output means we can suppress it to run the model, then
+activate it to make final output plots of our analysis.
+
+.. image:: ../images/examples/volumeFractions.png
+ :align: center
+ :alt: Volume fractions
+
+This example can be run as a script or interactively using the instructions below.
+
+
+.. note:: The custom model used is a MATLAB model - **examples/normalReflectivity/customXY/customXYDSPC.m**.
+
+**Run Script**:
+
+.. code-block:: Matlab
+
+ root = getappdata(0, 'root');
+ cd(fullfile(root, 'examples', 'normalReflectivity', 'customXY'));
+ customXYDSPCScript
+
+**Run Interactively**:
+
+.. code-block:: Matlab
+
+ root = getappdata(0, 'root');
+ cd(fullfile(root, 'examples', 'normalReflectivity', 'customXY'));
+ edit customXYDSPCSheet.mlx
+
+.. _ref_1:
+
+[1] Shekhar et al, J. Appl. Phys, 100, 102216 (2011) [`DOI 10.1063/1.3661986 `_]
+
+.. raw:: html
+ :file: customXYDSPCSheet.html
diff --git a/source/matlab_examples/DSPC_custom_layers.rst b/source/matlab_examples/DSPC_custom_layers.rst
new file mode 100644
index 00000000..b72f0320
--- /dev/null
+++ b/source/matlab_examples/DSPC_custom_layers.rst
@@ -0,0 +1,41 @@
+.. _DSPC_Custom_Layers:
+
+==================
+DSPC Custom Layers
+==================
+
+This shows an example of using a :ref:`custom layers` model to analyse reflectivity from a supported bilayer of DSPC.
+
+In this example, we can make use of the fact that the volumes, and of course the atomistic composition are known. So, for lipid tails for example, then we can
+take a literature value for the tails volume, have a fittable parameter for the lipid area per molecule, and then the tail thickness will simply be
+
+.. math:: Tail Thick = Tail Volume / Lipid APM.
+
+Since the volume is known, then the SLD of the tails is also obviously easily calculable.
+
+In addition, the datasets for this example, have a resolution (per point) in their fourth column. We use this resolution in our analysis, rather than declaring a constant, fittable one.
+
+This example can be run as a script or interactively using the instructions below.
+
+
+.. note:: The custom model used is a MATLAB model - **examples/normalReflectivity/customLayers/customBilayerDSPC.m**.
+
+**Run Script**:
+
+.. code-block:: Matlab
+
+ root = getappdata(0, 'root');
+ cd(fullfile(root, 'examples', 'normalReflectivity', 'customLayers'));
+ customLayersDSPCScript
+
+**Run Interactively**:
+
+.. code-block:: Matlab
+
+ root = getappdata(0, 'root');
+ cd(fullfile(root, 'examples', 'normalReflectivity', 'customLayers'));
+ edit customLayersDSPCSheet.mlx
+
+
+.. raw:: html
+ :file: customLayersDSPCSheet.html
diff --git a/source/matlab_examples/DSPC_standard_layers.rst b/source/matlab_examples/DSPC_standard_layers.rst
new file mode 100644
index 00000000..c4568c74
--- /dev/null
+++ b/source/matlab_examples/DSPC_standard_layers.rst
@@ -0,0 +1,30 @@
+.. _DSPC_Standard_Layers:
+
+====================
+DSPC Standard Layers
+====================
+This shows an example of using a :ref:`standard layers` model to analyse reflectivity from a floating bilayer of DSPC.
+
+The model is set up in the script, we set Gaussian priors on some of the parameters, build the two contrasts, run the calculation and plot the results.
+
+This example can be run as a script or interactively using the instructions below.
+
+
+**Run Script**:
+
+.. code-block:: Matlab
+
+ root = getappdata(0, 'root');
+ cd(fullfile(root, 'examples', 'normalReflectivity', 'standardLayers'));
+ standardLayersDSPCScript
+
+**Run Interactively**:
+
+.. code-block:: Matlab
+
+ root = getappdata(0, 'root');
+ cd(fullfile(root, 'examples', 'normalReflectivity', 'standardLayers'));
+ edit standardLayersDSPCSheet.mlx
+
+.. raw:: html
+ :file: standardLayersDSPCSheet.html
diff --git a/source/matlab_examples/convert_r1_project.rst b/source/matlab_examples/convert_r1_project.rst
new file mode 100644
index 00000000..32ef7d4f
--- /dev/null
+++ b/source/matlab_examples/convert_r1_project.rst
@@ -0,0 +1,23 @@
+=============================
+Converting a RasCAL-1 Project
+=============================
+
+If you have projects from RasCAL1, there is a simple utility supplied with the toolbox that makes converting between formats easy as explained in :ref:`conversionFuncs`.
+
+This example shows the conversion of a RasCAL-1 custom layers project into a RAT project and vice versa, because this is a custom layers project, the custom model
+function **Model_IIb.m** which in the example directory is required to run the converted RAT project successfully.
+
+This example can be run using the instructions below.
+
+.. note:: The custom model used is a MATLAB model - **examples/miscellaneous/convertRascal1Project/Model_IIb.m**.
+
+**Run Interactively**:
+
+.. code-block:: Matlab
+
+ root = getappdata(0, 'root');
+ cd(fullfile(root, 'examples', 'miscellaneous', 'convertRascal1Project'));
+ edit convertRascal.mlx
+
+.. raw:: html
+ :file: convertRascal.html
diff --git a/source/matlab_examples/custom_model_languages.rst b/source/matlab_examples/custom_model_languages.rst
new file mode 100644
index 00000000..e4a06985
--- /dev/null
+++ b/source/matlab_examples/custom_model_languages.rst
@@ -0,0 +1,36 @@
+==================================
+Alternative Custom Model Languages
+==================================
+
+In this example, we setup a :ref:`custom layers` problem using three different programming language (MATLAB, Python, and C++) to write the custom model function.
+The provided C++ function needs to be compiled into a dynamic library using instructions given in :ref:`customLanguages` or instructions specific to your compiler.
+
+
+This example can be run using the instructions below.
+
+
+.. note:: The custom models used are -
+ **examples/miscellaneous/languages/alloyDomains.m**,
+ **examples/miscellaneous/languages/alloyDomains.m**,
+ **examples/miscellaneous/languages/alloyDomains.m**.
+
+.. warning:: For Python custom functions, you will need to setup the python environment for MATLAB, see `Setup MATLAB to use Python `_
+
+**Run Script**:
+
+.. code-block:: Matlab
+
+ root = getappdata(0, 'root');
+ cd(fullfile(root, 'examples', 'miscellaneous', 'alternativeLanguages'));
+ customModelLanguagesScript
+
+**Run Interactively**:
+
+.. code-block:: Matlab
+
+ root = getappdata(0, 'root');
+ cd(fullfile(root, 'examples', 'miscellaneous', 'alternativeLanguages'));
+ edit customModelLanguagesSheet.mlx
+
+.. raw:: html
+ :file: customModelLanguagesSheet.html
diff --git a/source/matlab_examples/domains_custom_XY.rst b/source/matlab_examples/domains_custom_XY.rst
new file mode 100644
index 00000000..bf6080fb
--- /dev/null
+++ b/source/matlab_examples/domains_custom_XY.rst
@@ -0,0 +1,33 @@
+=================================
+Incoherent Summing with Custom XY
+=================================
+
+This is an example of using incoherent summing ('domains') from custom XY models.
+
+The domain custom XY model is similar to a normal custom models, except that the input (function arguments) of the custom function contains an additional 'domains' parameter as described in :ref:`domainsCustomModels`.
+
+This parameter tells the function which is the current domain, so the appropriate layer stack can be generated.
+
+This example can be run as a script or interactively using the instructions below.
+
+
+.. note:: The custom model used is a MATLAB model - **examples/domains/customXY/domainsXY.m**.
+
+**Run Script**:
+
+.. code-block:: Matlab
+
+ root = getappdata(0, 'root');
+ cd(fullfile(root, 'examples', 'domains', 'customXY'));
+ domainsCustomXYScript
+
+**Run Interactively**:
+
+.. code-block:: Matlab
+
+ root = getappdata(0, 'root');
+ cd(fullfile(root, 'examples', 'domains', 'customXY'));
+ edit domainsCustomXYSheet.mlx
+
+.. raw:: html
+ :file: domainsCustomXYSheet.html
diff --git a/source/matlab_examples/domains_custom_layers.rst b/source/matlab_examples/domains_custom_layers.rst
new file mode 100644
index 00000000..b23d161e
--- /dev/null
+++ b/source/matlab_examples/domains_custom_layers.rst
@@ -0,0 +1,33 @@
+=====================================
+Incoherent Summing with Custom Layers
+=====================================
+
+This is an example of using incoherent summing ('domains') from custom layers models. The sample is a simple two layer of permalloy/gold, with up/down domains
+
+The domain custom model is similar to a normal custom models, except that the input (function arguments) of the custom function contains an additional 'domains' parameter as described in :ref:`domainsCustomModels`.
+
+This parameter tells the function which is the current domain, so the appropriate layer stack can be generated.
+
+This example can be run as a script or interactively using the instructions below.
+
+
+.. note:: The custom model used is a MATLAB model - **examples/domains/customLayers/alloyDomains.m**.
+
+**Run Script**:
+
+.. code-block:: Matlab
+
+ root = getappdata(0, 'root');
+ cd(fullfile(root, 'examples', 'domains', 'customLayers'));
+ domainsCustomLayersScript
+
+**Run Interactively**:
+
+.. code-block:: Matlab
+
+ root = getappdata(0, 'root');
+ cd(fullfile(root, 'examples', 'domains', 'customLayers'));
+ edit domainsCustomLayersSheet.mlx
+
+.. raw:: html
+ :file: domainsCustomLayersSheet.html
diff --git a/source/matlab_examples/domains_standard_layers.rst b/source/matlab_examples/domains_standard_layers.rst
new file mode 100644
index 00000000..435b88bc
--- /dev/null
+++ b/source/matlab_examples/domains_standard_layers.rst
@@ -0,0 +1,39 @@
+=======================================
+Incoherent Summing with Standard Layers
+=======================================
+
+Analysing data containing domains using standard layers models is done in a similar way to a normal standard layers model, but with a couple of
+additional steps.
+
+A normal standard layers model defines parameters, which are grouped into layers, and then these are arranged into contrasts. For sample containing domains, the
+layers are first grouped into domain 'contrasts', which are just groupings of layers with none of the additional parameters of a contrast (such as resolutions
+etc). Then, the actual experimental contrasts are built in the usual way, but with the model set as any two of the domains.
+
+.. image:: ../images/domainsGraph.png
+ :align: center
+ :alt: Domains graph
+
+To control the ratio between the domains, we can add domain ratios as described in :ref:`domainsStanlay`. And each contrast has an additional field
+for domain ratios which is set as one of the values from this block.
+
+This example can be run as a script or interactively using the instructions below.
+
+**Run Script**:
+
+.. code-block:: Matlab
+
+ root = getappdata(0, 'root');
+ cd(fullfile(root, 'examples', 'domains', 'standardLayers'));
+ domainsStandardLayersScript
+
+**Run Interactively**:
+
+.. code-block:: Matlab
+
+ root = getappdata(0, 'root');
+ cd(fullfile(root, 'examples', 'domains', 'standardLayers'));
+ edit domainsStandardLayersSheet.mlx
+
+
+.. raw:: html
+ :file: domainsStandardLayersSheet.html
diff --git a/source/examples/imaginary.rst b/source/matlab_examples/imaginary.rst
similarity index 100%
rename from source/examples/imaginary.rst
rename to source/matlab_examples/imaginary.rst
diff --git a/source/examples/index.rst b/source/matlab_examples/index.rst
similarity index 82%
rename from source/examples/index.rst
rename to source/matlab_examples/index.rst
index 339f8b56..c8612d7e 100644
--- a/source/examples/index.rst
+++ b/source/matlab_examples/index.rst
@@ -1,9 +1,9 @@
-.. _examples:
+.. _matlabExamples:
-========
-Examples
-========
-A number of examples are provided to demonstrate the functionality available in the MATLAB and Python interface of RAT.
+===============
+MATLAB Examples
+===============
+A number of examples are provided to demonstrate the functionality available in the MATLAB interface of RAT.
******************
Normal Calculation
diff --git a/source/python_examples/index.rst b/source/python_examples/index.rst
new file mode 100644
index 00000000..b0342dcc
--- /dev/null
+++ b/source/python_examples/index.rst
@@ -0,0 +1,37 @@
+.. _pythonExamples:
+
+===============
+Python Examples
+===============
+A number of examples are provided to demonstrate the functionality available in the Python interface of RAT.
+
+******************
+Normal Calculation
+******************
+
+.. toctree::
+ :maxdepth: 1
+
+ notebooks/DSPC_standard_layers
+ notebooks/DSPC_custom_layers
+ notebooks/DSPC_custom_xy
+
+******************
+Domain Calculation
+******************
+
+.. toctree::
+ :maxdepth: 1
+
+ notebooks/domains_standard_layers
+ notebooks/domains_custom_layers
+ notebooks/domains_custom_XY
+
+*************
+Miscellaneous
+*************
+
+.. toctree::
+ :maxdepth: 1
+
+ notebooks/absorption
diff --git a/source/python_examples/notebooks/README.md b/source/python_examples/notebooks/README.md
new file mode 100644
index 00000000..9048a0c5
--- /dev/null
+++ b/source/python_examples/notebooks/README.md
@@ -0,0 +1,5 @@
+## Notebooks folder
+
+This folder contains the notebooks so they can be built by Sphinx.
+
+It is populated with notebooks by `sphinx build` (see `conf.py`)
diff --git a/source/reference/index.rst b/source/reference/index.rst
new file mode 100644
index 00000000..383aeae5
--- /dev/null
+++ b/source/reference/index.rst
@@ -0,0 +1,24 @@
+API Reference
+=============
+
+This section of the documentation contains API reference information for the
+Python and MATLAB versions of RAT.
+
+MATLAB Reference
+----------------
+
+.. toctree::
+ :maxdepth: 3
+
+ matlab/index
+
+
+Python Reference
+----------------
+
+.. toctree::
+ :maxdepth: 3
+
+ python/index
+
+