Skip to content

Commit 2e0dd66

Browse files
committed
Update docs
- Add some notes on IMAS-less installs - Update installing.rst to match the README.md in https://git.iter.org/projects/IMAS/repos/imaspy/pull-requests/73/overview - Add IMASPy in 5 minutes page - Reduce default sphinx-build output verbosity (to prevent sphinx errors and warnings from being drowned out)
1 parent f79b6de commit 2e0dd66

File tree

5 files changed

+211
-87
lines changed

5 files changed

+211
-87
lines changed

docs/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ help:
2020
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
2121
%: Makefile
2222
@echo Running '$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)'
23-
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -Tvv
23+
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
2424

2525
clean: Makefile
2626
@echo Running '$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)'

docs/source/conf.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@
7575
# unique name: (base URL, label prefix)
7676
extlinks = {
7777
"src": (blob_url + "%s", f"{src_group}/{src_project}/%s"),
78-
"issue": (issue_url + "%s", "#%s"),
78+
"issue": (issue_url + "%s", "%s"),
7979
"merge": (mr_url + "%s", "!%s"),
8080
"netcdf4": (netcdf4_docs + "%s", "netcdf4 %s"),
8181
"dd": (dd_url + "%s", "%s"),
@@ -104,6 +104,7 @@
104104
# ones.
105105
extensions = [
106106
"sphinx.ext.autodoc", # To auto-generate docs from Python docstrings
107+
"sphinx.ext.autosectionlabel",
107108
"sphinx.ext.todo", # nature theme
108109
"sphinx.ext.githubpages", # nature theme
109110
"sphinx.ext.napoleon", # Support for NumPy and Google style docstrings

docs/source/index.rst

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
1-
.. Master "index". This will be converted to a landing index.html by sphinx. We define TOC here, but it'll be put in the sidebar by the theme
1+
..
2+
Master "index". This will be converted to a landing index.html by sphinx. We
3+
define TOC here, but it'll be put in the sidebar by the theme
24
3-
===========================
5+
=============
46
IMASPy Manual
5-
===========================
6-
IMASPy is (yet another) pure-python library to handle arbitrarily nested
7+
=============
8+
9+
IMASPy is a pure-python library to handle arbitrarily nested
710
data structures. IMASPy is designed for, but not necessarily bound to,
811
interacting with Interface Data Structures (IDSs) as defined by the
912
Integrated Modelling & Analysis Suite (IMAS) Data Model.
1013

1114
It provides:
1215

1316
- An easy-to-install and easy-to-get started package by
14-
1517
* Not requiring an IMAS installation
1618
* Not strictly requiring matching a Data Dictionary (DD) version
1719
- A pythonic alternative to the IMAS Python High Level Interface (HLI)
@@ -26,11 +28,14 @@ It provides:
2628

2729
self
2830
installing
31+
intro
2932
api_overview
3033
mdsplus
3134

35+
3236
README
33-
-----------
37+
------
38+
3439
The README is best read on :src:`#imaspy`.
3540

3641
For developers
@@ -47,14 +52,16 @@ For developers
4752
api-hidden
4853

4954

50-
5155
LICENSE
5256
-------
53-
.. literalinclude:: ../../LICENSE
57+
58+
.. literalinclude:: ../../LICENSE.md
59+
:language: text
5460

5561

5662
Sitemap
5763
-------
64+
5865
* :ref:`genindex`
5966
* :ref:`modindex`
6067
* :ref:`search`

docs/source/installing.rst

Lines changed: 38 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,110 +1,71 @@
11
Installing IMASPy
22
=================
33

4-
IMASPy is a Python package with a compiled component, specifically the
5-
:al_cython:`Cython layer of the IMAS Access Layer (AL) <browse>`. This component
6-
is optional, but necessary to interact with the IMAS-AL, and thus with data stored
7-
to disk by said AL.
4+
IMASPy is a pure Python package. For full functionality of the package you need
5+
an installation of `the IMAS Access Layer <https://imas.iter.org/>`_. See
6+
:ref:`IMASPy 5 minute introduction` for an overview of functionality which does
7+
(not) require the IMAS Access Layer available.
88

9-
IMASPy also needs the :al_lib:`IMAS Python helper functions <browse>`. Currently, both
10-
dependencies are pulled it using :std:doc:`GitPython <gitpython:index>`, until the
11-
:issue:`separate Python HLI parts are available as packages <IMAS-584>`.
129

13-
.. :std:doc:`Cython <cython:index>` of the
10+
Installing on the ITER cluster and EuroFusion gateway
11+
-----------------------------------------------------
1412

15-
16-
Python is very flexible, and so is it's install procedure. This is a double-edged sword:
17-
Because of it flexibility, many different install options are available and in use in the
18-
community. For an introduction to the topic, read the
19-
:pypa:`guide to installing Python packaging by the Python Packaging Authority (PyPA) <tutorials/installing-packages/>`.
20-
21-
Installing on the ITER cluster
22-
------------------------------
23-
To interact with the AL, we need the IMAS environment
24-
activated. I'm assuming a bash shell for all these commands:
25-
26-
.. code-block:: bash
27-
28-
module load IMAS-2020a/3.30.0-4.8.5-2020a
29-
30-
This should give us all we need, namely at time of testing:
31-
32-
* ``python`` with a recent version: ``python --version #Python 3.8.2``
33-
* The Python package installer ``pip``:
34-
``pip --version #pip 20.0.2 from /work/imas/opt/EasyBuild/software/Python/3.8.2-GCCcore-9.3.0/lib/python3.8/site-packages/pip-20.0.2-py3.8.egg/pip (python 3.8)``
35-
36-
We are all developers, install imaspy in `pip editable <https://pip.pypa.io/en/stable/reference/pip_install/#options>`_ /`setuptools develop <https://setuptools.readthedocs.io/en/latest/setuptools.html#development-mode>`_ mode. **We are not using PEP517 build isolation to link to the systems numpy.**, **We are not using PyPA's recommended environment management, but instead install into the USER_SITE, this is ~/.local by default.**
13+
There is a `module` available on the ITER and Eurofusion Gateway clusters, so
14+
you can run
3715

3816
.. code-block:: bash
3917
40-
git clone git@git.iter.org/IMAS/imaspy.git
41-
pip install --user -e imaspy
42-
18+
module load IMASPy
4319
44-
We should now be able to run the tests
20+
Additionally, if you wish to use the MDSPlus backend, you should load
4521

4622
.. code-block:: bash
4723
48-
pip install --user -r requirements_test.txt
49-
pytest imaspy/ --mini
50-
51-
Note that at the time of writing access layer version 4.8.5 has an issue which causes
52-
several tests to fail.
53-
54-
Develop install
55-
^^^^^^^^^^^^^^^
24+
module load MDSplus-Java/7.96.17-GCCcore-10.2.0-Java-11
5625
57-
.. note:: Check if this is still needed
5826
59-
pip install --user -e .[backends_al,backends_xarray,test]
27+
Local installation
28+
------------------
6029

61-
Check if you have access to the AL repository. This is currently needed to pull 'secret' dependencies. This will be checked by `pip` too but better to know it now.
62-
63-
* Access to ``libimas.a``, located in ``$IMAS_PREFIX/lib``:
64-
``ls $IMAS_PREFIX/lib/libimas #/work/imas/core/IMAS/3.28.1-4.8.3/lib/libimas.a``
65-
in our ``LD_LIBRARY_PATH=$IMAS_PREFIX/lib:$LD_LIBRARY_PATH``
66-
* A ``UAL_VERSION``, which will be used to pull the low-level AL files from the ITER
67-
repository. ``echo $UAL_VERSION #4.8.3``
30+
We recommend using a :external:py:mod:`venv`. Then, clone the IMASPy repository
31+
and run `pip install`:
6832

6933
.. code-block:: bash
7034
71-
(git ls-remote ssh://git@git.iter.org/imas/access-layer.git > /dev/null) && echo 'Connection successful!' || echo 'Connection failed!'
72-
# Connection successful!
35+
python3 -m venv ./venv
36+
. venv/bin/activate
37+
git clone ssh://git@git.iter.org/imas/imaspy.git
38+
cd imaspy
39+
pip install --upgrade pip
40+
pip install --upgrade wheel setuptools
41+
pip install .
7342
7443
75-
Quick primer on Python packages
76-
-------------------------------
77-
A :pypa:`Python package <glossary/#term-import-package>`, commonly just called 'package', is a collection of :pypa:`Python modules <glossary/#term-module>`; reusable pieces of Python code. After installation, these packages are importable in scripts of other users, with the ``import package_name`` statement. On HPC systems, packages available to the user come from the following common locations:
44+
Development installation
45+
------------------------
7846

79-
1. From the globally installed Python packages. These are installed by the system administrator (e.g. someone with `sudo` rights). For example on the ITER cluster:
47+
For development an installation in editable mode may be more convenient, and you
48+
will need some extra dependencies to run the test suite and build documentation.
8049

8150
.. code-block:: bash
8251
83-
module purge
84-
module load Python/3.6.4-intel-2018a
85-
python -c 'import site; print(site.getsitepackages())'
86-
# ['/work/imas/opt/EasyBuild/software/Python/3.6.4-intel-2018a/lib/python3.6/site-packages']
52+
pip install -e .[test, docs]
8753
88-
2. From imported modules. These are usually centrally managed and also handled by the system administrator. For example on the ITER cluster:
54+
Test your installation by trying
8955

9056
.. code-block:: bash
9157
92-
module purge
93-
module load Python/3.6.4-intel-2018a PyAL
94-
python -m site
95-
# sys.path = [
96-
# <snip>
97-
# '/work/imas/opt/EasyBuild/software/Python/3.6.4-intel-2018a/lib/python3.6/site-packages/numpy-1.14.0-py3.6-linux-x86_64.egg'
98-
# <snip>
99-
# ]
100-
101-
3. From the local user environment, usually in the users' HOME directory:
58+
cd ~
59+
python -c "import imaspy; print(imaspy.__version__)"
10260
103-
.. code-block:: bash
10461
105-
python -c 'import site; print(site.USER_SITE)'
106-
# /home/ITER/vandepk/.local/lib/python3.6/site-packages
62+
Installation without ITER access
63+
--------------------------------
10764

108-
4. From the current working directory. E.g. if I have a file called ``fancy_code.py`` in my current folder, I can call ``from fancy_code import *`` from my other Python files.
65+
The installation script tries to access the `ITER IMAS Core Data Dictionary
66+
repository <https://git.iter.org/projects/IMAS/repos/data-dictionary/browse>`_
67+
to fetch the latest versions. If you do not have git+ssh access there, you can
68+
try to find this repository elsewhere, and do a ``git fetch --tags``.
10969

110-
Installing a Python package just means putting the Python files somewhere the python binary can find it. It does this by walking down the `sys.path` until a package with the right name is found. See :std:doc:`python:library/importlib`
70+
Alternatively you could try to obtain an ``IDSDef.zip`` and place it in
71+
``~/.config/imaspy/``.

docs/source/intro.rst

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
IMASPy 5 minute introduction
2+
----------------------------
3+
4+
.. contents:: Contents
5+
:local:
6+
:depth: 1
7+
8+
9+
Verify your IMAS installation
10+
'''''''''''''''''''''''''''''
11+
12+
Before continuing, verify that your imaspy install is working. Check the
13+
:ref:`Installing IMASPy` page for installation instructions if below fails for
14+
you. Start python and import imaspy. Note that the version in below output may
15+
be outdated.
16+
17+
.. code-block:: python
18+
19+
>>> import imaspy
20+
>>> print(imaspy.__version__)
21+
0.6.2
22+
23+
.. note::
24+
25+
If you have an IMASPy install without the IMAS Access Layer, importing
26+
IMASPy will display an error message. You can still use IMASPy, but not all
27+
functionality is available.
28+
29+
30+
Create and use an IDS
31+
'''''''''''''''''''''
32+
33+
To create an IDS, you must first make an :py:class:`~imaspy.ids_root.IDSRoot`
34+
object. The IDS root is necessary for specifying which version of the IMAS Data
35+
Dictionary you want to use (the last available one, by default). See
36+
:ref:`Loading multiple DD versions in the same environment` for more information
37+
on different Data Dictionary versions.
38+
39+
.. code-block:: python
40+
41+
>>> import imaspy
42+
>>> import numpy as np
43+
>>> ids_root = imaspy.ids_root.IDSRoot()
44+
10:26:51 [INFO] Generating IDS structures for version 3.38.1 @ids_root.py:130
45+
>>> # Create an empty core_profiles IDS
46+
>>> core_profiles = ids_root.core_profiles
47+
>>> # Caution: doing this a second time does not create a new one:
48+
>>> core_profiles2 = ids_root.core_profiles
49+
>>> core_profiles is core_profiles2
50+
True
51+
52+
We can now use this ``core_profiles`` IDS and assign some data to it:
53+
54+
.. code-block:: python
55+
56+
>>> core_profiles.ids_properties.comment = "Testing IMASPy"
57+
>>> core_profiles.ids_properties.homogeneous_time = imaspy.ids_defs.IDS_TIME_MODE_HOMOGENEOUS
58+
>>> # array quantities are automatically converted to the appropriate numpy arrays
59+
>>> core_profiles.time = [1, 2, 3]
60+
>>> # the python list of ints is converted to a 1D array of floats
61+
>>> core_profiles.time.value
62+
array([1., 2., 3.])
63+
>>> # resize the profiles_1d array of structures to match the size of `time`
64+
>>> core_profiles.profiles_1d.resize(3)
65+
>>> len(core_profiles.profiles_1d.value)
66+
3
67+
>>> # assign some data for the first time slice
68+
>>> core_profiles.profiles_1d[0].grid.rho_tor_norm = [0, 0.5, 1.0]
69+
>>> core_profiles.profiles_1d[0].j_tor = [0, 0, 0]
70+
71+
.. note::
72+
73+
Until :issue:`IMAS-4680` is addressed, you should use :code:`.value` to get the
74+
value of a quantity in IMASPy.
75+
76+
As you can see in above example, IMASPy automatically checks the data you try to
77+
assign to an IDS with the data type specified in the Data Dictionary. When
78+
possible, your data is automatically converted to the expected type. You will
79+
get an error message if this is not possible:
80+
81+
.. code-block:: python
82+
83+
>>> core_profiles.time = "Cannot be converted"
84+
ValueError: could not convert string to float: 'Cannot be converted'
85+
>>> core_profiles.time = 1-1j
86+
TypeError: can't convert complex to float
87+
>>> core_profiles.ids_properties.source = 1-1j # automatically converted to str
88+
>>> core_profiles.ids_properties.source.value
89+
'(1-1j)'
90+
91+
92+
Store an IDS to disk
93+
''''''''''''''''''''
94+
95+
.. note::
96+
97+
- This functionality requires the IMAS Access Layer.
98+
- This API will change when IMASPy is moving to Access Layer 5 (expected Q2
99+
2023).
100+
101+
To store an IDS to disk, we need to indicate the following information to the
102+
IMAS Access Layer. Please check the IMAS Access Layer documentation for more
103+
information on this.
104+
105+
- ``shot``
106+
- ``run``
107+
- ``user``
108+
- ``tokamak`` (also known as database)
109+
- ``version`` (major version of the access layer, typically ``"3"``)
110+
- Optional: which backend to use (e.g. the default MDSplus or HDF5).
111+
112+
In IMASPy you do this as follows:
113+
114+
.. code-block:: python
115+
116+
>>> # you can specify shot=10 and run=2 when creating the IDSRoot object
117+
>>> #ids_root = imaspy.ids_root.IDSRoot(s=10, r=2)
118+
>>> # you can also set this after creating the ids_root object
119+
>>> # as long as you do it before create_env_backend
120+
>>> ids_root.shot = 10
121+
>>> ids_root.run = 2
122+
>>> # Create a new IMAS data entry for storing the core_profiles IDS we created earlier
123+
>>> # Here we specify user, tokamak, version and the backend
124+
>>> import os
125+
>>> ids_root.create_env_backend(user=os.environ['USER'], tokamak="ITER", version="3", backend_type=imaspy.ids_defs.HDF5_BACKEND)
126+
10:29:13 [INFO] Opening AL backend HDF5 for ITER (shot 10, run 2, user sebregm, ver 3, mode w) @ids_root.py:337
127+
(0, 1)
128+
>>> # now store the core_profiles IDS we just populated
129+
>>> ids_root.core_profiles.put()
130+
131+
132+
Load an IDS from disk
133+
'''''''''''''''''''''
134+
135+
.. note::
136+
137+
- This functionality requires the IMAS Access Layer.
138+
- This API will change when IMASPy is moving to Access Layer 5 (expected Q2
139+
2023).
140+
141+
To load an IDS from disk, you need to specify the same information as
142+
when storing the IDS (see previous section). Once a data entry is opened, you
143+
can use ``<IDS>.get()`` to load IDS data from disk:
144+
145+
.. code-block:: python
146+
147+
>>> # Now load the core_profiles IDS back into a fresh ids_root object
148+
>>> ids_root2 = imaspy.ids_root.IDSRoot(s=10, r=2)
149+
10:29:56 [INFO] Generating IDS structures for version 3.38.1 @ids_root.py:130
150+
>>> ids_root2.open_env_backend(user=os.environ['USER'], tokamak="ITER", version="3", backend_type=imaspy.ids_defs.HDF5_BACKEND)
151+
10:30:07 [INFO] Opening AL backend HDF5 for ITER (shot 10, run 2, user sebregm, ver 3, mode r) @ids_root.py:337
152+
(0, 2)
153+
>>> ids_root2.core_profiles.get()
154+
>>> print(ids_root2.core_profiles.ids_properties.comment.value)
155+
Testing IMASPy

0 commit comments

Comments
 (0)