Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
39d8a73
added support of slicing for IDSStructArray
prasad-sawantdesai Feb 27, 2025
6704375
removed pull_request event
prasad-sawantdesai Mar 17, 2025
3246c71
merged with develop
prasad-sawantdesai Nov 3, 2025
a043911
Merge branch 'develop' into feature/allow-slices-for-IDSStructArray
prasad-sawantdesai Nov 3, 2025
7119a18
added ids_slice.py and updated IDSStructArray to return IDSSlice obje…
prasad-sawantdesai Nov 6, 2025
78727b4
added ids_slice.py and updated IDSStructArray to return IDSSlice obje…
prasad-sawantdesai Nov 6, 2025
67f24c6
removed flake8 issue
prasad-sawantdesai Nov 6, 2025
f389f74
Merge branch 'develop' into feature/allow-slices-for-IDSStructArray
prasad-sawantdesai Nov 6, 2025
88e6310
Merge branch 'iterorganization:develop' into feature/allow-slices-for…
prasad-sawantdesai Nov 6, 2025
c1a5fba
updated documentation and examples of using IDSSlice
prasad-sawantdesai Nov 7, 2025
b5f55de
Merge branch 'feature/allow-slices-for-IDSStructArray' of github.com:…
prasad-sawantdesai Nov 7, 2025
a1091ed
fixed black formatting
prasad-sawantdesai Nov 12, 2025
f30d305
fix flake8 issue
prasad-sawantdesai Nov 12, 2025
674c25f
add array_slicing in the documentation
prasad-sawantdesai Nov 12, 2025
4cf5937
Fix per review comment https://github.com/iterorganization/IMAS-Pytho…
prasad-sawantdesai Nov 21, 2025
c57e64e
Fix as per review comment https://github.com/iterorganization/IMAS-Py…
prasad-sawantdesai Nov 21, 2025
c470bec
Fix as per review comment https://github.com/iterorganization/IMAS-Py…
prasad-sawantdesai Nov 21, 2025
156aded
Fix as per review comment https://github.com/iterorganization/IMAS-Py…
prasad-sawantdesai Nov 21, 2025
87158d2
Fix as per review comment https://github.com/iterorganization/IMAS-Py…
prasad-sawantdesai Nov 21, 2025
94e20f2
Fix as per review comment https://github.com/iterorganization/IMAS-Py…
prasad-sawantdesai Nov 21, 2025
8398537
Fix as per review comment https://github.com/iterorganization/IMAS-Py…
prasad-sawantdesai Nov 21, 2025
18d7fd0
Fix as per review comment https://github.com/iterorganization/IMAS-Py…
prasad-sawantdesai Nov 21, 2025
989513d
Fix as per review comment https://github.com/iterorganization/IMAS-Py…
prasad-sawantdesai Nov 21, 2025
3939e55
Fix as per review comment https://github.com/iterorganization/IMAS-Py…
prasad-sawantdesai Nov 21, 2025
2423a89
Fix as per review comment https://github.com/iterorganization/IMAS-Py…
prasad-sawantdesai Nov 21, 2025
69cb566
formatting with black and flake8
prasad-sawantdesai Nov 21, 2025
e1502f1
refactored code
prasad-sawantdesai Nov 21, 2025
224fbea
Merge branch 'develop' into feature/allow-slices-for-IDSStructArray
prasad-sawantdesai Nov 21, 2025
8099741
updated documentation
prasad-sawantdesai Nov 21, 2025
21ded45
Fix as per review comment https://github.com/iterorganization/IMAS-Py…
prasad-sawantdesai Nov 21, 2025
e94d634
fix issue in sphinx docs
prasad-sawantdesai Nov 21, 2025
e448883
lazy loaded objects supports slicing
prasad-sawantdesai Nov 21, 2025
32265d1
fix representation issue and empty slice raises exception https://git…
prasad-sawantdesai Nov 24, 2025
00752d2
fix first and second point fix __repr__ and Empty slices do not check…
prasad-sawantdesai Nov 28, 2025
93bdb50
fix first and second point fix __repr__ and Empty slices do not check…
prasad-sawantdesai Nov 28, 2025
757af75
added tests
prasad-sawantdesai Nov 28, 2025
d862073
fixed issues with to_array function
prasad-sawantdesai Nov 28, 2025
b2143f8
fixed documentation issue
prasad-sawantdesai Nov 28, 2025
0aa5a2c
fixed issue in sphinx doc generation
prasad-sawantdesai Nov 29, 2025
56f154e
raise value error when ragged arrays found https://github.com/iterorg…
prasad-sawantdesai Jan 5, 2026
b92883c
Removed Union and simplified __getitem__ method https://github.com/it…
prasad-sawantdesai Jan 5, 2026
0a4658d
Check if node is valid and return empty slice if array is empty https…
prasad-sawantdesai Jan 5, 2026
d91d25b
IDSSlice should have valid metadata, https://github.com/iterorganizat…
prasad-sawantdesai Jan 5, 2026
74e0d73
the size of all items is not the same as the first, there may be ragg…
prasad-sawantdesai Jan 5, 2026
16a608a
added property to get ids name in IDSMetadata class, build IDSSlice w…
prasad-sawantdesai Jan 5, 2026
7d8abaa
simplified values method according to suggestions from Maarten https:…
prasad-sawantdesai Jan 5, 2026
f085f82
Simplified __getitem__ method for lazy lading https://github.com/iter…
prasad-sawantdesai Jan 5, 2026
44a1110
simplified to_array method https://github.com/iterorganization/IMAS-P…
prasad-sawantdesai Jan 5, 2026
a3ca48c
fixed __getitem method principle of least astonishment, https://githu…
prasad-sawantdesai Jan 5, 2026
9116f19
fixed formatting
prasad-sawantdesai Jan 5, 2026
57034e4
Merge branch 'iterorganization:develop' into feature/allow-slices-for…
prasad-sawantdesai Jan 5, 2026
23bd921
Merge branch 'iterorganization:develop' into feature/allow-slices-for…
prasad-sawantdesai Jan 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ __pycache__/

# C extensions
*.so

myenv
# Distribution / packaging
.Python
env/
Expand Down
1 change: 1 addition & 0 deletions docs/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ IMAS-Python IDS manipulation
ids_toplevel.IDSToplevel
ids_primitive.IDSPrimitive
ids_structure.IDSStructure
ids_slice.IDSSlice
ids_struct_array.IDSStructArray
131 changes: 131 additions & 0 deletions docs/source/array_slicing.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
.. _array-slicing:

Array Slicing
=============

The ``IDSStructArray`` class supports Python's standard slicing syntax.

Key Difference
---------------

- ``array[0]`` returns ``IDSStructure`` (single element)
- ``array[:]`` or ``array[1:5]`` returns ``IDSSlice`` (collection with ``values()`` method)

Basic Usage
-----------

.. code-block:: python

import imas

entry = imas.DBEntry("imas:hdf5?path=my-testdb")
cp = entry.get("core_profiles")

# Integer indexing
first = cp.profiles_1d[0] # IDSStructure
last = cp.profiles_1d[-1] # IDSStructure

# Slice operations
subset = cp.profiles_1d[1:5] # IDSSlice
every_other = cp.profiles_1d[::2] # IDSSlice

# Access nested arrays
all_ions = cp.profiles_1d[:].ion[:] # IDSSlice of individual ions

# Extract values
labels = all_ions.label.values()

Multi-Dimensional Slicing
---------------------------

The ``IDSSlice`` class supports multi-dimensional shape tracking and array conversion.

**Check shape of sliced data:**

.. code-block:: python

# Get shape information for multi-dimensional data
print(cp.profiles_1d[:].grid.shape) # (106,)
print(cp.profiles_1d[:].ion.shape) # (106, ~3)
print(cp.profiles_1d[1:3].ion[0].element.shape) # (2, ~3)

**Extract values with shape preservation:**

.. code-block:: python

# Extract as list
grid_values = cp.profiles_1d[:].grid.values()

# Extract as numpy array
grid_array = cp.profiles_1d[:].grid.to_array()

# Extract as numpy array
ion_array = cp.profiles_1d[:].ion.to_array()

**Nested structure access:**

.. code-block:: python

# Access through nested arrays
grid_data = cp.profiles_1d[1:3].grid.rho_tor.to_array()

# Ion properties across multiple profiles
ion_labels = cp.profiles_1d[:].ion[:].label.to_array()
ion_charges = cp.profiles_1d[:].ion[:].z_ion.to_array()

Common Patterns
---------------

**Process a range:**

.. code-block:: python

for element in cp.profiles_1d[5:10]:
print(element.time)

**Iterate over nested arrays:**

.. code-block:: python

for ion in cp.profiles_1d[:].ion[:]:
print(ion.label.value)

**Get all values:**

.. code-block:: python

times = cp.profiles_1d[:].time.values()

# Or as numpy array
times_array = cp.profiles_1d[:].time.to_array()

Important: Array-wise Indexing
-------------------------------

When accessing attributes through a slice of ``IDSStructArray`` elements,
the slice operation automatically applies to each array (array-wise indexing):

.. code-block:: python

# Array-wise indexing: [:] applies to each ion array
all_ions = cp.profiles_1d[:].ion[:]
labels = all_ions.label.values()

# Equivalent to manually iterating:
labels = []
for profile in cp.profiles_1d[:]:
for ion in profile.ion:
labels.append(ion.label.value)

Lazy-Loaded Arrays
-------------------

Both individual indexing and slicing work with lazy loading:

.. code-block:: python

element = lazy_array[0] # OK - loads on demand
subset = lazy_array[1:5] # OK - loads only requested elements on demand

When slicing lazy-loaded arrays, only the elements in the slice range are loaded,
making it memory-efficient for large datasets.
26 changes: 26 additions & 0 deletions docs/source/courses/advanced/explore.rst
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,32 @@ structures (modeled by :py:class:`~imas.ids_struct_array.IDSStructArray`) are (a
name applies) arrays containing :py:class:`~imas.ids_structure.IDSStructure`\ s. Data
nodes can contain scalar or array data of various types.

**Slicing Arrays of Structures**

Arrays of structures support Python slice notation, which returns an
:py:class:`~imas.ids_slice.IDSSlice` object containing matched elements:

.. code-block:: python

import imas

core_profiles = imas.IDSFactory().core_profiles()
core_profiles.profiles_1d.resize(10) # Create 10 profiles

# Integer indexing returns a single structure
first = core_profiles.profiles_1d[0]

# Slice notation returns an IDSSlice
subset = core_profiles.profiles_1d[2:5] # Elements 2, 3, 4
every_other = core_profiles.profiles_1d[::2] # Every second element

# IDSSlice supports array-wise indexing and values() for data access
all_ions = core_profiles.profiles_1d[:].ion[:]
for ion in all_ions:
print(ion.label.value)

For detailed information on slicing operations, see :doc:`../../array_slicing`.

Some methods and properties are defined for all data nodes and arrays of structures:

``len(<node>)``
Expand Down
6 changes: 6 additions & 0 deletions docs/source/imas_architecture.rst
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,12 @@ The following submodules and classes represent IDS nodes.
:py:class:`~imas.ids_struct_array.IDSStructArray` class, which models Arrays of
Structures. It also contains some :ref:`dev lazy loading` logic.

- :py:mod:`imas.ids_slice` contains the
:py:class:`~imas.ids_slice.IDSSlice` class, which represents a collection of IDS
nodes matching a slice expression. It provides slicing operations on
:py:class:`~imas.ids_struct_array.IDSStructArray` elements with array-wise
indexing and supports the ``values()`` method for extracting raw data.

- :py:mod:`imas.ids_structure` contains the
:py:class:`~imas.ids_structure.IDSStructure` class, which models Structures. It
contains the :ref:`lazy instantiation` logic and some of the :ref:`dev lazy loading`
Expand Down
1 change: 1 addition & 0 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ Manual
configuring
cli
netcdf
array_slicing
changelog
examples

Expand Down
35 changes: 35 additions & 0 deletions docs/source/intro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,38 @@ can use ``<IDS>.get()`` to load IDS data from disk:
>>> dbentry2 = imas.DBEntry("mypulsefile.nc","r")
>>> core_profiles2 = dbentry2.get("core_profiles")
>>> print(core_profiles2.ids_properties.comment.value)


.. _`Multi-Dimensional Slicing`:

Multi-Dimensional Slicing
''''''''''''''''''''''''''

IMAS-Python supports advanced slicing of hierarchical data structures with automatic
shape tracking and array conversion to numpy. This enables intuitive access to
multi-dimensional scientific data:

.. code-block:: python

>>> # Load data
>>> entry = imas.DBEntry("mypulsefile.nc","r")
>>> cp = entry.get("core_profiles", autoconvert=False, lazy=True)

>>> # Check shape of sliced data
>>> cp.profiles_1d[:].grid.shape
(106,)
>>> cp.profiles_1d[:].ion.shape
(106, ~3) # ~3 ions per profile

>>> # Extract values
>>> grid_values = cp.profiles_1d[:].grid.to_array()
>>> ion_labels = cp.profiles_1d[:].ion[:].label.to_array()

>>> # Work with subsets
>>> subset_grid = cp.profiles_1d[1:3].grid.to_array()
>>> subset_ions = cp.profiles_1d[1:3].ion.to_array()

The ``IDSSlice`` class tracks multi-dimensional shapes and provides both
``.values()`` and ``.to_array()`` (numpy array)
methods for data extraction. For more details, see :ref:`array-slicing`.

14 changes: 14 additions & 0 deletions imas/ids_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,20 @@ def __getitem__(self, path) -> "IDSMetadata":
) from None
return item

@property
def ids_name(self) -> str:
"""Get the root IDS name (e.g., 'core_profiles', 'equilibrium').

Traverses up the metadata hierarchy to find the toplevel IDS name.

Returns:
The name of the root IDS node.
"""
current = self
while current._parent is not None:
current = current._parent
return current.name

@property
def identifier_enum(self) -> Optional[Type[IDSIdentifier]]:
"""The identifier enum for this IDS node (if available).
Expand Down
Loading
Loading