Repository: PTB-MR/mrpro
Pull request #763: Improve string representation
Author: login: fzimmermann89
Created: 2025-04-03T15:21:29Z | Merged: 2025-04-27T19:25:17Z

superseds the [summarize branch](https://github.com/PTB-MR/mrpro/tree/summarize)

Closes #762 

Example:
```
KData with (broadcasted) shape [3, 4, 1, 64, 64].
  data: Tensor<3, 4, 1, 64, 64>, |x| ∈ [0.00295, 33.2], μ=0.756+0.000133j, [-0.1206+0.0778j, -0.0181+0.0176j,  ...,  0.1104-0.0595j, -0.0491-0.0221j]
  traj: KTrajectory with (broadcasted) shape [1, 1, 1, 64, 64].
     kz: Tensor<1, 1, 1, 1, 1>, constant 0
     ky: Tensor<1, 1, 1, 64, 1>, x ∈ [0, 63], μ=31.5, [ 0.,  1.,  ..., 62., 63.]
     kx: Tensor<1, 1, 1, 1, 64>, x ∈ [-32, 31], μ=-0.5, [-32., -31.,  ...,  30.,  31.]
     grid_detection_tolerance: 0.001
     repeat_detection_tolerance: 0.001
  header:  KHeader with (broadcasted) shape [3, 1, 1, 64, 1].
     recon_matrix: z=1, y=64, x=64
     encoding_matrix: z=1, y=64, x=64
     recon_fov: z=0.005, y=0.064, x=0.064
     encoding_fov: z=0.005, y=0.064, x=0.064
     acq_info: AcqInfo<3, 1, 1, 64, 1>
     trajectory: KTrajectoryISMRMRD()
     lamor_frequency_proton: 128000000
     datetime: 1970-01-01 01:00:00
     te: list<1>, constant 0.0023
     ti: list<1>, constant 0
     fa: list<1>, constant 0.209
     tr: list<1>, constant 0.0896
     echo_spacing: list<1>, constant 0.0056
     echo_train_length: 1
     sequence_type: unknown
     model: unknown
     vendor: unknown
     protocol_name: unknown
     trajectory_type: TrajectoryType.RADIAL
     measurement_id: unknown
     patient_name: unknown
```

Linked issue #762: Repr of SpatialDimension
SpatialDimensions used to be displayed e.g.
```
kdata.header.encoding_matrix
SpatialDimension(z=20, y=130, x=256)
```
Currently it looks like this
```
kdata.header.encoding_matrix
SpatialDimension with (broadcasted) shape [] on device "None".
Fields:
   z <int>
   y <int>
   x <int>
```

The reason is I guess that `__repr__` of Dataclass
https://github.com/PTB-MR/mrpro/blob/8c50fcbbb6adfee1c0b96a55d51d506c24464135/src/mrpro/data/Dataclass.py#L566
which does not call the ` __str__` of SpatialDimension
https://github.com/PTB-MR/mrpro/blob/8c50fcbbb6adfee1c0b96a55d51d506c24464135/src/mrpro/data/SpatialDimension.py#L143
Linked issue comments: user: login: ckolbPTB
created_at: 2025-04-03T12:00:56Z
body: We should also add tests to the `__repr__` functions for the data classes. Maybe some for you @Stef-Martin ?
author_association: COLLABORATOR
user: login: Stef-Martin
created_at: 2025-04-03T12:22:22Z
body: Sure, will have a look at it!
author_association: COLLABORATOR
user: login: fzimmermann89
created_at: 2025-04-04T10:00:09Z
body: This is on purpose. There is the `summarize` branch that i now moved to the reshape... stack that implements repr for all dataclasses..
author_association: MEMBER
user: login: fzimmermann89
created_at: 2025-04-04T13:23:08Z
body: So single spatial dimension will have repr as 
```
SpatialDimension.
  z: 1
  y: 2
  x: 3
```

And `print(kdata)` or `repr(kdata)`:
```
KData with (broadcasted) shape [3, 4, 1, 64, 64].
  data: Tensor<3, 4, 1, 64, 64>, |x| ∈ [0.00295, 33.2], μ=0.756+0.000133j, [-0.1206+0.0778j, -0.0181+0.0176j,  ...,  0.1104-0.0595j, -0.0491-0.0221j]
  traj: KTrajectory with (broadcasted) shape [1, 1, 1, 64, 64].
     kz: Tensor<1, 1, 1, 1, 1>, constant 0
     ky: Tensor<1, 1, 1, 64, 1>, x ∈ [0, 63], μ=31.5, [ 0.,  1.,  ..., 62., 63.]
     kx: Tensor<1, 1, 1, 1, 64>, x ∈ [-32, 31], μ=-0.5, [-32., -31.,  ...,  30.,  31.]
     grid_detection_tolerance: 0.001
     repeat_detection_tolerance: 0.001
  header:  KHeader with (broadcasted) shape [3, 1, 1, 64, 1].
     recon_matrix: z=1, y=64, x=64
     encoding_matrix: z=1, y=64, x=64
     recon_fov: z=0.005, y=0.064, x=0.064
     encoding_fov: z=0.005, y=0.064, x=0.064
     acq_info: AcqInfo<3, 1, 1, 64, 1>
     trajectory: KTrajectoryISMRMRD()
     lamor_frequency_proton: 128000000
     datetime: 1970-01-01 01:00:00
     te: list<1>, constant 0.0023
     ti: list<1>, constant 0
     fa: list<1>, constant 0.209
     tr: list<1>, constant 0.0896
     echo_spacing: list<1>, constant 0.0056
     echo_train_length: 1
     sequence_type: unknown
     model: unknown
     vendor: unknown
     protocol_name: unknown
     trajectory_type: TrajectoryType.RADIAL
     measurement_id: unknown
     patient_name: unknown
```


author_association: MEMBER

Diff:
diff --git a/src/mrpro/data/Dataclass.py b/src/mrpro/data/Dataclass.py
index 937d3c7b2..c096327df 100644
--- a/src/mrpro/data/Dataclass.py
+++ b/src/mrpro/data/Dataclass.py
@@ -11,6 +11,7 @@
 
 from mrpro.utils.indexing import HasIndex, Indexer
 from mrpro.utils.reduce_repeat import reduce_repeat
+from mrpro.utils.summarize import summarize_object
 from mrpro.utils.typing import TorchIndexerType
 
 
@@ -608,20 +609,52 @@ def ndim(self) -> int:
 
     # endregion Properties
 
+    # region Representation
     def __repr__(self) -> str:
-        """Representation method for Dataclass."""
+        """Get string representation of Dataclass."""
+        header = [type(self).__name__]
+
+        try:
+            device = self.device
+            if device:
+                header.append(f'on device "{device}"')
+        except RuntimeError:
+            header.append('on mixed devices')
+
         try:
-            device = str(self.device)
+            if shape := self.shape:
+                header.append(f'with (broadcasted) shape {list(shape)!s}')
         except RuntimeError:
-            device = 'mixed'
-        name = type(self).__name__
-        output = f'{name} with (broadcasted) shape {list(self.shape)!s} on device "{device}".\n'
-        output += 'Fields:\n'
+            header.append('with inconsistent shape')
+
+        output = ' '.join(header) + '.\n'
+
         output += '\n'.join(
-            f'   {field.name} <{type(getattr(self, field.name)).__name__}>' for field in dataclasses.fields(self)
+            f'  {field.name}: {summarize_object(value)}'
+            for field in dataclasses.fields(self)
+            if not (field.name.startswith('_') or (value := getattr(self, field.name, None)) is None)
         )
         return output
 
+    # We return the same for __repr__ and __str__.
+    # This break the "_str_ if for users, _repr_ for developers rule" of python.
+    # But it makes interactive work on repl or notebooks easier, as `obj` can be used instead
+    # of `print(obj)`. It would be infeasable for most dataclasses to implement a proper  __repr__
+    # that uniquely describes the data and could be used to recreate the object anyways.
+
+    def __str__(self) -> str:
+        """Return the same as __repr__."""
+        return repr(self)
+
+    def __shortstr__(self) -> str:
+        """Return a short string representation."""
+        output = type(self).__name__
+        if self.shape:
+            output = output + f'<{", ".join(map(str, self.shape))}>'
+        return output
+
+    # endregion Representation
+
     # region Indexing
     def __getitem__(self, index: TorchIndexerType | Indexer) -> Self:
         """Index the dataclass."""
diff --git a/src/mrpro/data/IHeader.py b/src/mrpro/data/IHeader.py
index 367d1725f..d1be5f34a 100644
--- a/src/mrpro/data/IHeader.py
+++ b/src/mrpro/data/IHeader.py
@@ -17,7 +17,6 @@
 from mrpro.data.Rotation import Rotation
 from mrpro.data.SpatialDimension import SpatialDimension
 from mrpro.utils.reduce_repeat import reduce_repeat
-from mrpro.utils.summarize_tensorvalues import summarize_tensorvalues
 from mrpro.utils.unit_conversion import deg_to_rad, mm_to_m, ms_to_s
 
 
@@ -291,11 +290,3 @@ def from_dicom(cls, *dataset: Dataset) -> Self:
             tr=tr,
             te=te,
         )
-
-    def __repr__(self):
-        """Representation method for IHeader class."""
-        te = summarize_tensorvalues(self.te)
-        ti = summarize_tensorvalues(self.ti)
-        fa = summarize_tensorvalues(self.fa)
-        out = f'Resolution [m/pixel]: {self.resolution!s}\nTE [s]: {te}\nTI [s]: {ti}\nFlip angle [rad]: {fa}.'
-        return out
diff --git a/src/mrpro/data/KData.py b/src/mrpro/data/KData.py
index 19bbb2de6..9fe209859 100644
--- a/src/mrpro/data/KData.py
+++ b/src/mrpro/data/KData.py
@@ -3,7 +3,7 @@
 import copy
 import datetime
 import warnings
-from collections.abc import Callable, Sequence
+from collections.abc import Callable, Mapping, Sequence
 from types import EllipsisType
 from typing import Literal, cast
 
@@ -27,6 +27,8 @@
 from mrpro.utils.reduce_repeat import reduce_repeat
 from mrpro.utils.typing import FileOrPath
 
+from ..utils.summarize import summarize_object
+
 RotationOrTensor = TypeVar('RotationOrTensor', bound=torch.Tensor | Rotation)
 
 KDIM_SORT_LABELS = (
@@ -81,7 +83,7 @@ def from_file(
         cls,
         filename: FileOrPath,
         trajectory: KTrajectoryCalculator | KTrajectory | KTrajectoryIsmrmrd,
-        header_overwrites: dict[str, object] | None = None,
+        header_overwrites: Mapping[str, object] | None = None,
         dataset_idx: int = -1,
         acquisition_filter_criterion: Callable = is_image_acquisition,
     ) -> Self:
@@ -346,18 +348,17 @@ def expand(x: T) -> T:
 
     def __repr__(self):
         """Representation method for KData class."""
-        traj = KTrajectory(self.traj.kz, self.traj.ky, self.traj.kx)
-        try:
-            device = str(self.device)
-        except RuntimeError:
-            device = 'mixed'
-        out = (
-            f'{type(self).__name__} with shape {list(self.data.shape)!s} and dtype {self.data.dtype}\n'
-            f'Device: {device}\n'
-            f'{traj}\n'
-            f'{self.header}'
+        traj_info = '\n   '.join(repr(self.traj).splitlines())
+        header_info = '\n   '.join(repr(self.header).splitlines())
+        representation = '\n'.join(
+            [
+                super().__repr__().splitlines()[0],
+                f'  data: {summarize_object(self.data)}',
+                f'  traj: {traj_info}',
+                f'  header:  {header_info}',
+            ]
         )
-        return out
+        return representation
 
     def compress_coils(
         self: Self,
diff --git a/src/mrpro/data/KHeader.py b/src/mrpro/data/KHeader.py
index ffa186c94..8c3a329b0 100644
--- a/src/mrpro/data/KHeader.py
+++ b/src/mrpro/data/KHeader.py
@@ -3,6 +3,7 @@
 import dataclasses
 import datetime as dt
 import warnings
+from collections.abc import Mapping
 from dataclasses import field
 from typing import TYPE_CHECKING
 
@@ -15,7 +16,6 @@
 from mrpro.data.Dataclass import Dataclass
 from mrpro.data.SpatialDimension import SpatialDimension
 from mrpro.data.traj_calculators.KTrajectoryCalculator import KTrajectoryCalculator
-from mrpro.utils.summarize_tensorvalues import summarize_tensorvalues
 from mrpro.utils.unit_conversion import deg_to_rad, mm_to_m, ms_to_s
 
 if TYPE_CHECKING:
@@ -118,7 +118,7 @@ def from_ismrmrd(
         header: ismrmrdschema.ismrmrdHeader,
         acq_info: AcqInfo,
         defaults: dict | None = None,
-        overwrite: dict | None = None,
+        overwrite: Mapping[str, object] | None = None,
         encoding_number: int = 0,
     ) -> Self:
         """Create an Header from ISMRMRD Data.
@@ -232,18 +232,3 @@ def from_ismrmrd(
                 'Consider setting them via the defaults dictionary',
             ) from None
         return instance
-
-    def __repr__(self):
-        """Representation method for KHeader class."""
-        te = summarize_tensorvalues(self.te)
-        ti = summarize_tensorvalues(self.ti)
-        fa = summarize_tensorvalues(self.fa)
-        out = (
-            f'FOV [m]: {self.encoding_fov!s}\n'
-            f'TE [s]: {te}\n'
-            f'TI [s]: {ti}\n'
-            f'Flip angle [rad]: {fa}\n'
-            f'Encoding matrix: {self.encoding_matrix!s} \n'
-            f'Recon matrix: {self.recon_matrix!s} \n'
-        )
-        return out
diff --git a/src/mrpro/data/KTrajectory.py b/src/mrpro/data/KTrajectory.py
index 799ba88a5..9cdd327b0 100644
--- a/src/mrpro/data/KTrajectory.py
+++ b/src/mrpro/data/KTrajectory.py
@@ -13,7 +13,6 @@
 from mrpro.data.SpatialDimension import SpatialDimension
 from mrpro.utils.reduce_repeat import reduce_repeat
 from mrpro.utils.reshape import unsqueeze_at
-from mrpro.utils.summarize_tensorvalues import summarize_tensorvalues
 from mrpro.utils.typing import FileOrPath
 
 
@@ -256,11 +255,3 @@ def as_tensor(self, stack_dim: int = 0) -> torch.Tensor:
         """
         shape = self.shape
         return torch.stack([traj.expand(*shape) for traj in (self.kz, self.ky, self.kx)], dim=stack_dim)
-
-    def __repr__(self):
-        """Representation method for KTrajectory class."""
-        z = summarize_tensorvalues(torch.tensor(self.kz.shape))
-        y = summarize_tensorvalues(torch.tensor(self.ky.shape))
-        x = summarize_tensorvalues(torch.tensor(self.kx.shape))
-        out = f'{type(self).__name__} with shape: kz={z}, ky={y}, kx={x}'
-        return out
diff --git a/src/mrpro/data/SpatialDimension.py b/src/mrpro/data/SpatialDimension.py
index 9315613aa..a695487f2 100644
--- a/src/mrpro/data/SpatialDimension.py
+++ b/src/mrpro/data/SpatialDimension.py
@@ -140,8 +140,10 @@ def zyx(self) -> tuple[T_co, T_co, T_co]:
         """
         return (self.z, self.y, self.x)
 
-    def __str__(self) -> str:
-        """Return a string representation of the SpatialDimension."""
+    def __shortstr__(self) -> str:
+        """Return a short string representation."""
+        if isinstance(self.x, VectorTypes) or isinstance(self.y, VectorTypes) or isinstance(self.z, VectorTypes):
+            super().__shortstr__()
         return f'z={self.z}, y={self.y}, x={self.x}'
 
     def __getitem__(self: SpatialDimension[T_co], idx: type_utils.TorchIndexerType | Indexer) -> SpatialDimension[T_co]:
diff --git a/src/mrpro/data/traj_calculators/KTrajectoryCalculator.py b/src/mrpro/data/traj_calculators/KTrajectoryCalculator.py
index 1f4116dc5..f68d54e84 100644
--- a/src/mrpro/data/traj_calculators/KTrajectoryCalculator.py
+++ b/src/mrpro/data/traj_calculators/KTrajectoryCalculator.py
@@ -91,6 +91,10 @@ def _readout(
             k0[reversed_readout_mask] = torch.flip(k0[reversed_readout_mask], (-1,))
         return k0
 
+    def __repr__(self) -> str:
+        """Get string representation."""
+        return f'{type(self).__name__}()'
+
 
 class DummyTrajectory(KTrajectoryCalculator):
     """Simple Dummy trajectory that returns zeros.
diff --git a/src/mrpro/utils/__init__.py b/src/mrpro/utils/__init__.py
index 4ca2e7ef1..e527a030c 100644
--- a/src/mrpro/utils/__init__.py
+++ b/src/mrpro/utils/__init__.py
@@ -11,6 +11,7 @@
 from mrpro.utils.split_idx import split_idx
 from mrpro.utils.sliding_window import sliding_window
 from mrpro.utils.reshape import broadcast_right, unsqueeze_left, unsqueeze_right, reduce_view, reshape_broadcasted, ravel_multi_index, unsqueeze_tensors_left, unsqueeze_tensors_right, unsqueeze_at, unsqueeze_tensors_at
+from mrpro.utils.summarize import summarize_object, summarize_values
 from mrpro.utils.TensorAttributeMixin import TensorAttributeMixin
 from mrpro.utils.RandomGenerator import RandomGenerator
 
@@ -29,6 +30,8 @@
     "sliding_window",
     "smap",
     "split_idx",
+    "summarize_object",
+    "summarize_values",
     "typing",
     "unit_conversion",
     "unsqueeze_at",
diff --git a/src/mrpro/utils/summarize.py b/src/mrpro/utils/summarize.py
new file mode 100644
index 000000000..68a2b4248
--- /dev/null
+++ b/src/mrpro/utils/summarize.py
@@ -0,0 +1,111 @@
+"""Summarize the values of a tensor to a string."""
+
+from collections.abc import Sequence
+from typing import Protocol, runtime_checkable
+
+import torch
+
+
+@runtime_checkable
+class HasShortStr(Protocol):
+    """Object implemtining shortstr."""
+
+    def __shortstr__(self) -> str:
+        """Return a short string representation."""
+
+
+def summarize_object(obj: object) -> str:
+    """Summarize object to a human readable representation.
+
+    Parameters
+    ----------
+    obj
+        The object to summarize.
+        This method has special cases:
+            For sequences of numeric values and tensors, a summary of shape and value is returned.
+            If __shortstr__ is implemented, it is used.
+            For torch.nn.Modules, only the name is used.
+            For other objects, obj.__str__() will be used.
+
+    Returns
+    -------
+        The string summary/short representation.
+
+    """
+    if isinstance(obj, torch.Tensor):
+        return summarize_values(obj)
+    if isinstance(obj, tuple | list):
+        try:
+            torch.as_tensor(obj)
+        except Exception:  # noqa: BLE001
+            return str(obj)
+        return summarize_values(obj)
+    if isinstance(obj, HasShortStr):
+        return obj.__shortstr__()
+    if isinstance(obj, torch.nn.Module):
+        return f'{type(obj).__name__}(...)'
+    return str(obj)
+
+
+def summarize_values(value: torch.Tensor | Sequence[float], summarization_threshold: int = 6) -> str:
+    """Summarize the values of a tensor or sequence to a string.
+
+    Returns a string representation of the object and its values.
+
+    Parameters
+    ----------
+    value
+        The object to summarize.
+    summarization_threshold
+        The threshold of total array elements triggering summarization.
+
+    Returns
+    -------
+        A string summary of the shape and values.
+    """
+    string = []
+    if isinstance(value, torch.Tensor):
+        if value.shape:
+            string.append(f'Tensor<{", ".join(map(str, value.shape))}>,')
+        elif value.numel():
+            string.append('Tensor:')
+        else:
+            return 'Tensor'
+    elif not len(value):
+        return f'{type(value).__name__}'
+    else:
+        string.append(f'{type(value).__name__}<{len(value)}>,')
+    value = torch.as_tensor(value, device='cpu')
+    constant = False
+    if value.numel() == 0:
+        pass
+    elif value.is_complex():
+        # workaround for missing unique of complex values
+        unique = torch.view_as_complex(torch.unique(torch.view_as_real(value.ravel()), dim=0))
+        if len(unique) == 1:
+            string.append(f'constant {unique.item():.3g}')
+            constant = True
+        elif value.numel() > summarization_threshold:
+            magnitude = value.abs()
+            string.append(
+                f'|x| ∈ [{magnitude.amin().item():.3g}, {magnitude.amax().item():.3g}], μ={value.mean().item():.3g},'
+            )
+    else:  # real valued
+        min_value, max_value = value.min(), value.max()
+        if torch.isclose(min_value, max_value):
+            if min_value.dtype == torch.bool:
+                string.append(f'constant {min_value.item()}')
+            else:
+                string.append(f'constant {min_value.item():.3g}')
+            constant = True
+        elif value.numel() > summarization_threshold:
+            mean = (value + 0.0).mean()  # +0. to force float for dtype.int64
+            string.append(f'x ∈ [{min_value.item():.3g}, {max_value.item():.3g}], μ={mean.item():.3g},')
+    if not constant:  # no need to add values for constant tensor
+        edgeitems = 1 if summarization_threshold < 4 else 2
+        with torch._tensor_str.printoptions(threshold=summarization_threshold, edgeitems=edgeitems):
+            values = ''.join(
+                torch._tensor_str._tensor_str(torch.as_tensor(value.ravel(), device='cpu'), 0).splitlines()
+            )
+            string.append(values)
+    return ' '.join(string)
diff --git a/src/mrpro/utils/summarize_tensorvalues.py b/src/mrpro/utils/summarize_tensorvalues.py
deleted file mode 100644
index a725bb733..000000000
--- a/src/mrpro/utils/summarize_tensorvalues.py
+++ /dev/null
@@ -1,31 +0,0 @@
-"""Summarize the values of a tensor to a string."""
-
-from collections.abc import Sequence
-
-import torch
-
-
-def summarize_tensorvalues(tensor: torch.Tensor | None | Sequence[float], summarization_threshold: int = 7) -> str:
-    """Summarize the values of a tensor to a string.
-
-    Returns a string representation of the tensor values. If the tensor is None, the string 'None' is returned.
-
-    Parameters
-    ----------
-    tensor
-        The tensor to summarize.
-    summarization_threshold
-        The threshold of total array elements triggering summarization.
-    edgeitems
-        Number of elements at the beginning and end of each dimension to show.
-    """
-    if tensor is None:
-        return 'None'
-    if summarization_threshold < 4:
-        edgeitems = 1
-    elif summarization_threshold < 7:
-        edgeitems = 2
-    else:
-        edgeitems = 3
-    with torch._tensor_str.printoptions(threshold=summarization_threshold, edgeitems=edgeitems):
-        return torch._tensor_str._tensor_str(torch.as_tensor(tensor), 0)
diff --git a/tests/data/test_dataclass.py b/tests/data/test_dataclass.py
index 536e1d33f..2826c8c11 100644
--- a/tests/data/test_dataclass.py
+++ b/tests/data/test_dataclass.py
@@ -265,17 +265,22 @@ def test_dataclass_no_new_attributes() -> None:
 
 def test_dataclass_repr() -> None:
     """Test the repr method of the dataclass."""
-    data = B()
+    data = B(
+        floattensor=torch.arange(10)[:, None],
+        complextensor=torch.tensor([[2j]]),
+        booltensor=torch.tensor([[False]]),
+        inttensor=torch.tensor([-10000000]),
+        doubletensor=torch.linspace(-1, 1, 20).double(),
+    )
     actual = repr(data)
-    expected = """B with (broadcasted) shape [10, 20] on device "cpu".
-Fields:
-   child <A>
-   module <SharedModule>
-   floattensor <Tensor>
-   complextensor <Tensor>
-   inttensor <Tensor>
-   booltensor <Tensor>
-   doubletensor <Tensor>"""
+    expected = """B on device "cpu" with (broadcasted) shape [10, 20].
+  child: A<10, 20>
+  module: SharedModule(...)
+  floattensor: Tensor<10, 1>, x ∈ [0, 9], μ=4.5, [0, 1,  ..., 8, 9]
+  complextensor: Tensor<1, 1>, constant 0+2j
+  inttensor: Tensor<1>, constant -1e+07
+  booltensor: Tensor<1, 1>, constant False
+  doubletensor: Tensor<20>, x ∈ [-1, 1], μ=0, [-1.0000, -0.8947,  ...,  0.8947,  1.0000]"""
     assert actual == expected
 
 
diff --git a/tests/data/test_kdata.py b/tests/data/test_kdata.py
index 72cbe37ea..91f1c4d28 100644
--- a/tests/data/test_kdata.py
+++ b/tests/data/test_kdata.py
@@ -1,9 +1,14 @@
 """Tests for the KData class."""
 
+import re
+from collections.abc import Sequence
+from types import EllipsisType
+from typing import Literal
+
 import pytest
 import torch
 from einops import repeat
-from mrpro.data import KData, KTrajectory, SpatialDimension
+from mrpro.data import KData, KHeader, KTrajectory, SpatialDimension
 from mrpro.data.acq_filters import has_n_coils, is_coil_calibration_acquisition, is_image_acquisition
 from mrpro.data.traj_calculators.KTrajectoryCalculator import DummyTrajectory
 from mrpro.operators import FastFourierOp
@@ -19,14 +24,14 @@ def test_KData_from_file(ismrmrd_cart) -> None:
     assert kdata is not None
 
 
-def test_KData_random_cart_undersampling(ismrmrd_cart_random_us):
+def test_KData_random_cart_undersampling(ismrmrd_cart_random_us) -> None:
     """Read data with different random Cartesian undersampling in multiple
     repetitions."""
     kdata = KData.from_file(ismrmrd_cart_random_us.filename, DummyTrajectory())
     assert kdata is not None
 
 
-def test_KData_random_cart_undersampling_shape(ismrmrd_cart_random_us):
+def test_KData_random_cart_undersampling_shape(ismrmrd_cart_random_us) -> None:
     """Check shape of KData with random Cartesian undersampling."""
     kdata = KData.from_file(ismrmrd_cart_random_us.filename, DummyTrajectory())
     # check if the number of repetitions is correct
@@ -35,7 +40,7 @@ def test_KData_random_cart_undersampling_shape(ismrmrd_cart_random_us):
     assert kdata.data.shape[-2] == ismrmrd_cart_random_us.matrix_size // ismrmrd_cart_random_us.acceleration
 
 
-def test_KData_raise_wrong_trajectory_shape(ismrmrd_cart):
+def test_KData_raise_wrong_trajectory_shape(ismrmrd_cart) -> None:
     """Wrong KTrajectory shape raises exception."""
     rng = RandomGenerator(seed=0)
     trajectory = KTrajectory(*rng.float32_tensor((3, 5, 1, 2, 3, 4)))
@@ -43,14 +48,14 @@ def test_KData_raise_wrong_trajectory_shape(ismrmrd_cart):
         _ = KData.from_file(ismrmrd_cart.filename, trajectory)
 
 
-def test_KData_raise_warning_for_bodycoil(ismrmrd_cart_bodycoil_and_surface_coil):
+def test_KData_raise_warning_for_bodycoil(ismrmrd_cart_bodycoil_and_surface_coil) -> None:
     """Mix of bodycoil and surface coil acquisitions leads to warning."""
     with pytest.raises(UserWarning, match='Acquisitions with different number'):
         _ = KData.from_file(ismrmrd_cart_bodycoil_and_surface_coil.filename, DummyTrajectory())
 
 
 @pytest.mark.filterwarnings('ignore:Acquisitions with different number:UserWarning')
-def test_KData_select_bodycoil_via_filter(ismrmrd_cart_bodycoil_and_surface_coil):
+def test_KData_select_bodycoil_via_filter(ismrmrd_cart_bodycoil_and_surface_coil) -> None:
     """Bodycoil can be selected via a custom acquisition filter."""
     # This is the recommended way of selecting the body coil (i.e. 2 receiver elements)
     kdata = KData.from_file(
@@ -61,7 +66,7 @@ def test_KData_select_bodycoil_via_filter(ismrmrd_cart_bodycoil_and_surface_coil
     assert kdata.data.shape[-4] == 2
 
 
-def test_KData_raise_wrong_coil_number(ismrmrd_cart):
+def test_KData_raise_wrong_coil_number(ismrmrd_cart) -> None:
     """Wrong number of coils leads to empty acquisitions."""
     with pytest.raises(ValueError, match='No acquisitions meeting the given filter criteria were found'):
         _ = KData.from_file(
@@ -71,7 +76,7 @@ def test_KData_raise_wrong_coil_number(ismrmrd_cart):
         )
 
 
-def test_KData_from_file_diff_nky_for_rep(ismrmrd_cart_invalid_reps):
+def test_KData_from_file_diff_nky_for_rep(ismrmrd_cart_invalid_reps) -> None:
     """Multiple repetitions with different number of phase encoding lines."""
     with pytest.warns(UserWarning, match=r'different number'):
         kdata = KData.from_file(ismrmrd_cart_invalid_reps.filename, DummyTrajectory())
@@ -79,7 +84,7 @@ def test_KData_from_file_diff_nky_for_rep(ismrmrd_cart_invalid_reps):
     assert kdata.data.shape[-3] == 1, 'k2 should be 1'
 
 
-def test_KData_calibration_lines(ismrmrd_cart_with_calibration_lines):
+def test_KData_calibration_lines(ismrmrd_cart_with_calibration_lines) -> None:
     """Correct handling of calibration lines."""
     # Exclude calibration lines
     kdata = KData.from_file(ismrmrd_cart_with_calibration_lines.filename, DummyTrajectory())
@@ -97,7 +102,7 @@ def test_KData_calibration_lines(ismrmrd_cart_with_calibration_lines):
     assert kdata.data.shape[-2] == ismrmrd_cart_with_calibration_lines.n_separate_calibration_lines
 
 
-def test_KData_kspace(ismrmrd_cart_high_res):
+def test_KData_kspace(ismrmrd_cart_high_res) -> None:
     """Read in data and verify k-space by comparing reconstructed image."""
     kdata = KData.from_file(ismrmrd_cart_high_res.filename, DummyTrajectory())
     ff_op = FastFourierOp(
@@ -114,14 +119,14 @@ def test_KData_kspace(ismrmrd_cart_high_res):
 
 
 @pytest.mark.parametrize(('field', 'value'), [('lamor_frequency_proton', 42.88 * 1e6), ('tr', [24.3])])
-def test_KData_overwrite_header(ismrmrd_cart, field, value):
+def test_KData_overwrite_header(ismrmrd_cart, field: str, value: float) -> None:
     """Overwrite some parameters in the header."""
     parameter_dict = {field: value}
     kdata = KData.from_file(ismrmrd_cart.filename, DummyTrajectory(), header_overwrites=parameter_dict)
     assert getattr(kdata.header, field) == value
 
 
-def test_KData_to_float64tensor(ismrmrd_cart):
+def test_KData_to_float64tensor(ismrmrd_cart) -> None:
     """Change KData dtype to double using other-tensor overload."""
     kdata = KData.from_file(ismrmrd_cart.filename, DummyTrajectory())
     kdata_float64 = kdata.to(torch.ones(1, dtype=torch.float64))
@@ -131,7 +136,7 @@ def test_KData_to_float64tensor(ismrmrd_cart):
 
 
 @pytest.mark.cuda
-def test_KData_to_cudatensor(ismrmrd_cart):
+def test_KData_to_cudatensor(ismrmrd_cart) -> None:
     """Move KData to cuda  using other-tensor overload."""
     kdata = KData.from_file(ismrmrd_cart.filename, DummyTrajectory())
     kdata_cuda = kdata.to(torch.ones(1, device=torch.device('cuda')))
@@ -140,7 +145,7 @@ def test_KData_to_cudatensor(ismrmrd_cart):
     assert kdata_cuda.data.is_cuda
 
 
-def test_Kdata_to_same_copy(ismrmrd_cart):
+def test_Kdata_to_same_copy(ismrmrd_cart) -> None:
     """Call .to with no change in dtype or device."""
     kdata = KData.from_file(ismrmrd_cart.filename, DummyTrajectory())
     kdata2 = kdata.to(copy=True)
@@ -150,7 +155,7 @@ def test_Kdata_to_same_copy(ismrmrd_cart):
     assert kdata2.data.device == kdata.data.device
 
 
-def test_Kdata_to_same_nocopy(ismrmrd_cart):
+def test_Kdata_to_same_nocopy(ismrmrd_cart) -> None:
     """Call .to with no change in dtype or device."""
     kdata = KData.from_file(ismrmrd_cart.filename, DummyTrajectory())
     kdata2 = kdata.to(copy=False)
@@ -158,7 +163,7 @@ def test_Kdata_to_same_nocopy(ismrmrd_cart):
     assert kdata.data is kdata2.data
 
 
-def test_KData_to_complex128_data(ismrmrd_cart):
+def test_KData_to_complex128_data(ismrmrd_cart) -> None:
     """Change KData dtype complex128: test data."""
     kdata = KData.from_file(ismrmrd_cart.filename, DummyTrajectory())
     kdata_complex128 = kdata.to(dtype=torch.complex128)
@@ -167,7 +172,7 @@ def test_KData_to_complex128_data(ismrmrd_cart):
     torch.testing.assert_close(kdata_complex128.data.to(dtype=torch.complex64), kdata.data)
 
 
-def test_KData_to_complex128_traj(ismrmrd_cart):
+def test_KData_to_complex128_traj(ismrmrd_cart) -> None:
     """Change KData dtype complex128: test trajectory."""
     kdata = KData.from_file(ismrmrd_cart.filename, DummyTrajectory())
     kdata_complex128 = kdata.to(dtype=torch.complex128)
@@ -176,7 +181,7 @@ def test_KData_to_complex128_traj(ismrmrd_cart):
     assert kdata_complex128.traj.kz.dtype == torch.float64
 
 
-def test_KData_to_complex128_header(ismrmrd_cart):
+def test_KData_to_complex128_header(ismrmrd_cart) -> None:
     """Change KData dtype complex128: test header"""
     kdata = KData.from_file(ismrmrd_cart.filename, DummyTrajectory())
     kdata_complex128 = kdata.to(dtype=torch.complex128)
@@ -185,7 +190,7 @@ def test_KData_to_complex128_header(ismrmrd_cart):
 
 
 @pytest.mark.cuda
-def test_KData_to_cuda(ismrmrd_cart):
+def test_KData_to_cuda(ismrmrd_cart) -> None:
     """Test KData.to to move data to CUDA memory."""
     kdata = KData.from_file(ismrmrd_cart.filename, DummyTrajectory())
     cuda_device = f'cuda:{torch.cuda.current_device()}'
@@ -197,7 +202,7 @@ def test_KData_to_cuda(ismrmrd_cart):
 
 
 @pytest.mark.cuda
-def test_KData_cuda(ismrmrd_cart):
+def test_KData_cuda(ismrmrd_cart) -> None:
     """Move KData object to CUDA memory."""
     kdata = KData.from_file(ismrmrd_cart.filename, DummyTrajectory())
     kdata_cuda = kdata.cuda()
@@ -213,7 +218,7 @@ def test_KData_cuda(ismrmrd_cart):
 
 
 @pytest.mark.cuda
-def test_KData_cpu(ismrmrd_cart):
+def test_KData_cpu(ismrmrd_cart) -> None:
     """Move KData object to CUDA memory and back to CPU memory."""
     kdata = KData.from_file(ismrmrd_cart.filename, DummyTrajectory())
     kdata_cpu = kdata.cuda().cpu()
@@ -226,7 +231,7 @@ def test_KData_cpu(ismrmrd_cart):
     assert kdata_cpu.header.acq_info.device == torch.device('cpu')
 
 
-def test_Kdata_device_cpu(ismrmrd_cart):
+def test_Kdata_device_cpu(ismrmrd_cart) -> None:
     """Default device is CPU."""
     kdata = KData.from_file(ismrmrd_cart.filename, DummyTrajectory())
     assert kdata.device == torch.device('cpu')
@@ -235,7 +240,7 @@ def test_Kdata_device_cpu(ismrmrd_cart):
 
 
 @pytest.mark.cuda
-def test_KData_inconsistentdevice(ismrmrd_cart):
+def test_KData_inconsistentdevice(ismrmrd_cart) -> None:
     """Inconsistent device raises exception."""
     kdata_cpu = KData.from_file(ismrmrd_cart.filename, DummyTrajectory())
     kdata_cuda = kdata_cpu.to(device='cuda')
@@ -246,7 +251,7 @@ def test_KData_inconsistentdevice(ismrmrd_cart):
         _ = kdata_mix.device
 
 
-def test_KData_clone(ismrmrd_cart):
+def test_KData_clone(ismrmrd_cart) -> None:
     """Test .clone method."""
     kdata = KData.from_file(ismrmrd_cart.filename, DummyTrajectory())
     kdata2 = kdata.clone()
@@ -265,7 +270,9 @@ def test_KData_clone(ismrmrd_cart):
         (7, 'contrast'),
     ],
 )
-def test_KData_split_k1_into_other(consistently_shaped_kdata, n_other_split: int, other_label: str) -> None:
+def test_KData_split_k1_into_other(
+    consistently_shaped_kdata: KData, n_other_split: int, other_label: Literal['average', 'repetition', 'contrast']
+) -> None:
     """Test splitting of the k1 dimension into other."""
     *n_others, n_coils, n_k2, n_k1, n_k0 = consistently_shaped_kdata.data.shape
     n_other = torch.tensor(n_others).prod().item()
@@ -293,7 +300,10 @@ def test_KData_split_k1_into_other(consistently_shaped_kdata, n_other_split: int
     ],
 )
 def test_KData_select_other_subset(
-    consistently_shaped_kdata, monkeypatch, subset_label: str, subset_idx: torch.Tensor
+    consistently_shaped_kdata: KData,
+    monkeypatch,
+    subset_label: Literal['repetition', 'average', 'phase'],
+    subset_idx: torch.Tensor,
 ) -> None:
     """Test selection of a subset from other dimension."""
     # Create KData
@@ -314,7 +324,7 @@ def test_KData_select_other_subset(
     assert all(torch.unique(getattr(kdata_subset.header.acq_info.idx, subset_label)) == torch.unique(subset_idx))
 
 
-def test_KData_remove_readout_os(monkeypatch, random_kheader) -> None:
+def test_KData_remove_readout_os(monkeypatch, random_kheader: KHeader) -> None:
     # Dimensions
     n_coils = 4
     n_k0 = 240
@@ -362,7 +372,7 @@ def test_KData_remove_readout_os(monkeypatch, random_kheader) -> None:
     assert relative_image_difference(torch.abs(img_recon), img_tensor[:, 0, ...]) <= 0.05
 
 
-def test_KData_compress_coils(ismrmrd_cart_high_res):
+def test_KData_compress_coils(ismrmrd_cart_high_res) -> None:
     """Test coil combination does not alter image content (much)."""
     kdata = KData.from_file(ismrmrd_cart_high_res.filename, DummyTrajectory())
     kdata = kdata.compress_coils(n_compressed_coils=4)
@@ -399,7 +409,9 @@ def test_KData_compress_coils(ismrmrd_cart_high_res):
         'single_compression_for_last_3_and_first_dims',
     ],
 )
-def test_KData_compress_coils_diff_batch_joint_dims(consistently_shaped_kdata, batch_dims, joint_dims):
+def test_KData_compress_coils_diff_batch_joint_dims(
+    consistently_shaped_kdata: KData, batch_dims: Sequence[int], joint_dims: Sequence[int] | EllipsisType
+) -> None:
     """Test that all of these options work and yield the same shape."""
     n_compressed_coils = 2
     orig_kdata_shape = consistently_shaped_kdata.data.shape
@@ -407,13 +419,13 @@ def test_KData_compress_coils_diff_batch_joint_dims(consistently_shaped_kdata, b
     assert kdata.data.shape == (*orig_kdata_shape[:-4], n_compressed_coils, *orig_kdata_shape[-3:])
 
 
-def test_KData_compress_coils_error_both_batch_and_joint(consistently_shaped_kdata):
+def test_KData_compress_coils_error_both_batch_and_joint(consistently_shaped_kdata: KData) -> None:
     """Test if error is raised if both batch_dims and joint_dims is defined."""
     with pytest.raises(ValueError, match='Either batch_dims or joint_dims'):
         consistently_shaped_kdata.compress_coils(n_compressed_coils=3, batch_dims=(0,), joint_dims=(0,))
 
 
-def test_KData_compress_coils_error_coil_dim(consistently_shaped_kdata):
+def test_KData_compress_coils_error_coil_dim(consistently_shaped_kdata: KData) -> None:
     """Test if error is raised if coil_dim is in batch_dims or joint_dims."""
     with pytest.raises(ValueError, match='Coil dimension must not'):
         consistently_shaped_kdata.compress_coils(n_compressed_coils=3, batch_dims=(-4,))
@@ -422,8 +434,43 @@ def test_KData_compress_coils_error_coil_dim(consistently_shaped_kdata):
         consistently_shaped_kdata.compress_coils(n_compressed_coils=3, joint_dims=(-4,))
 
 
-def test_KData_compress_coils_error_n_coils(consistently_shaped_kdata):
+def test_KData_compress_coils_error_n_coils(consistently_shaped_kdata: KData) -> None:
     """Test if error is raised if new coils would be larger than existing coils"""
     existing_coils = consistently_shaped_kdata.data.shape[-4]
     with pytest.raises(ValueError, match='greater'):
         consistently_shaped_kdata.compress_coils(existing_coils + 1)
+
+
+def test_KData_repr(consistently_shaped_kdata: KData) -> None:
+    actual_repr = repr(consistently_shaped_kdata)
+    actual_str = str(consistently_shaped_kdata)
+    assert actual_str == actual_repr
+    assert re.match(
+        r"""KData on device "cpu" with \(broadcasted\) shape \[2, 3, 3, 13, 11, 10\]\.
+\s{2}data: Tensor<2, 3, 3, 13, 11, 10>, \|x\| ∈ \[(.*?),\s*(.*?)\]\s*,\s*μ=(.*?),\s*\[(.*?),\s*\.\.\.,\s*(.*?)\]
+\s{2}traj: KTrajectory on device "cpu" with \(broadcasted\) shape \[2, 1, 1, 13, 11, 10\]\.
+\s{5}kz: Tensor<2, 1, 1, 13, 1, 1>, x ∈ \[(.*?),\s*(.*?)\]\s*,\s*μ=(.*?),\s*\[(.*?),\s*\.\.\.,\s*(.*?)\]
+\s{5}ky: Tensor<2, 1, 1, 1, 11, 1>, x ∈ \[(.*?),\s*(.*?)\]\s*,\s*μ=(.*?),\s*\[\s*(.*?),\s*\.\.\.,\s*(.*?)\s*\]
+\s{5}kx: Tensor<2, 1, 1, 1, 1, 10>, x ∈ \[(.*?),\s*(.*?)\]\s*,\s*μ=(.*?),\s*\[(.*?),\s*\.\.\.,\s*(.*?)\]
+\s{5}grid_detection_tolerance:\s*(.*?)
+\s{2}header:\s{2}KHeader on device "cpu" with \(broadcasted\) shape \[2, 1, 1, 13, 11, 1\]\.
+\s{5}recon_matrix: z=17, y=83, x=47
+\s{5}encoding_matrix: z=73, y=81, x=66
+\s{5}recon_fov: z=(.*?),\s*y=(.*?),\s*x=(.*?)
+\s{5}encoding_fov: z=(.*?),\s*y=(.*?),\s*x=(.*?)
+\s{5}acq_info: AcqInfo<2, 1, 1, 13, 11, 1>
+\s{5}te: list
+\s{5}ti: list
+\s{5}fa: list
+\s{5}tr: list
+\s{5}echo_spacing: list
+\s{5}echo_train_length: 1
+\s{5}sequence_type: unknown
+\s{5}model: unknown
+\s{5}vendor: unknown
+\s{5}protocol_name: unknown
+\s{5}trajectory_type: TrajectoryType\.OTHER
+\s{5}measurement_id: unknown
+\s{5}patient_name: unknown""",
+        actual_repr,
+    )
diff --git a/tests/data/test_spatial_dimension.py b/tests/data/test_spatial_dimension.py
index 52010e295..c8ae9acd3 100644
--- a/tests/data/test_spatial_dimension.py
+++ b/tests/data/test_spatial_dimension.py
@@ -106,6 +106,12 @@ def test_spatial_dimension_dtype() -> None:
     assert SpatialDimension(torch.ones(1).int(), torch.ones(1).int(), torch.ones(1).int()).dtype == torch.int32
 
 
+def test_spatial_dimension_int_repr() -> None:
+    """Test repr as edgecase without shape and device."""
+    actual = repr(SpatialDimension(1, 2, 3))
+    assert actual == 'SpatialDimension.\n  z: 1\n  y: 2\n  x: 3'
+
+
 def test_spatial_dimension_apply_() -> None:
     """Test apply_ (in place)"""
 


Reviews:
user: login: ckolbPTB
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-25T11:28:06Z
user: login: fzimmermann89
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-26T19:59:23Z
user: login: ckolbPTB
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-04-27T17:59:15Z

Review comments:
diff_hunk: @@ -608,20 +609,52 @@ def ndim(self) -> int:
 
     # endregion Properties
 
+    # region Representation
     def __repr__(self) -> str:
-        """Representation method for Dataclass."""
+        """Get string representation of Dataclass."""
+        header = [type(self).__name__]
+
+        try:
+            device = self.device
+            if device and device.type != 'cpu':
path: src/mrpro/data/Dataclass.py
user: login: ckolbPTB
body: I would prefer to also display device if it is on cpu. 
created_at: 2025-04-25T11:28:06Z
author_association: COLLABORATOR
diff_hunk: @@ -608,20 +609,52 @@ def ndim(self) -> int:
 
     # endregion Properties
 
+    # region Representation
     def __repr__(self) -> str:
-        """Representation method for Dataclass."""
+        """Get string representation of Dataclass."""
+        header = [type(self).__name__]
+
+        try:
+            device = self.device
+            if device and device.type != 'cpu':
path: src/mrpro/data/Dataclass.py
user: login: fzimmermann89
body: pytorch doesn't, but i dont care either way
created_at: 2025-04-26T19:59:23Z
author_association: MEMBER

PR comments:
user: login: fzimmermann89
created_at: 2025-04-03T15:21:30Z
body: Stack from [ghstack](https://github.com/ezyang/ghstack) (oldest at bottom):
* #766
* #732
* #731
* #730
* #735
* __->__ #763
* #729

author_association: MEMBER
user: login: github-actions[bot]
created_at: 2025-04-03T15:25:16Z
body: <!-- Pytest Coverage Comment: coverage_report_pr -->
<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/README.md"><img alt="Coverage" src="https://img.shields.io/badge/Coverage-92%25-brightgreen.svg" /></a><details><summary>Coverage Report </summary><table><tr><th>File</th><th>Stmts</th><th>Miss</th><th>Cover</th><th>Missing</th></tr><tbody><tr><td colspan="5"><b>src/mrpro</b></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/_version.py">_version.py</a></td><td>6</td><td>2</td><td>67%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/_version.py#L7-L8">7&ndash;8</a></td></tr><tr><td colspan="5"><b>src/mrpro/algorithms/csm</b></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/algorithms/csm/inati.py">inati.py</a></td><td>24</td><td>1</td><td>96%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/algorithms/csm/inati.py#L42">42</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/algorithms/csm/walsh.py">walsh.py</a></td><td>16</td><td>1</td><td>94%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/algorithms/csm/walsh.py#L53">53</a></td></tr><tr><td colspan="5"><b>src/mrpro/algorithms/dcf</b></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/algorithms/dcf/dcf_voronoi.py">dcf_voronoi.py</a></td><td>55</td><td>4</td><td>93%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/algorithms/dcf/dcf_voronoi.py#L15">15</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/algorithms/dcf/dcf_voronoi.py#L55-L56">55&ndash;56</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/algorithms/dcf/dcf_voronoi.py#L89">89</a></td></tr><tr><td colspan="5"><b>src/mrpro/algorithms/optimizers</b></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/algorithms/optimizers/adam.py">adam.py</a></td><td>30</td><td>6</td><td>80%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/algorithms/optimizers/adam.py#L108">108</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/algorithms/optimizers/adam.py#L125-L129">125&ndash;129</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/algorithms/optimizers/cg.py">cg.py</a></td><td>56</td><td>1</td><td>98%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/algorithms/optimizers/cg.py#L139">139</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/algorithms/optimizers/pdhg.py">pdhg.py</a></td><td>81</td><td>3</td><td>96%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/algorithms/optimizers/pdhg.py#L178-L179">178&ndash;179</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/algorithms/optimizers/pdhg.py#L185">185</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/algorithms/optimizers/pgd.py">pgd.py</a></td><td>53</td><td>4</td><td>92%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/algorithms/optimizers/pgd.py#L107">107</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/algorithms/optimizers/pgd.py#L152-L155">152&ndash;155</a></td></tr><tr><td colspan="5"><b>src/mrpro/algorithms/reconstruction</b></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/algorithms/reconstruction/DirectReconstruction.py">DirectReconstruction.py</a></td><td>28</td><td>6</td><td>79%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/algorithms/reconstruction/DirectReconstruction.py#L62">62</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/algorithms/reconstruction/DirectReconstruction.py#L65">65</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/algorithms/reconstruction/DirectReconstruction.py#L70">70</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/algorithms/reconstruction/DirectReconstruction.py#L77-L79">77&ndash;79</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/algorithms/reconstruction/IterativeSENSEReconstruction.py">IterativeSENSEReconstruction.py</a></td><td>13</td><td>1</td><td>92%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/algorithms/reconstruction/IterativeSENSEReconstruction.py#L79">79</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/algorithms/reconstruction/Reconstruction.py">Reconstruction.py</a></td><td>50</td><td>13</td><td>74%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/algorithms/reconstruction/Reconstruction.py#L54-L56">54&ndash;56</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/algorithms/reconstruction/Reconstruction.py#L80-L87">80&ndash;87</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/algorithms/reconstruction/Reconstruction.py#L109">109</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/algorithms/reconstruction/Reconstruction.py#L112">112</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/algorithms/reconstruction/RegularizedIterativeSENSEReconstruction.py">RegularizedIterativeSENSEReconstruction.py</a></td><td>41</td><td>17</td><td>59%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/algorithms/reconstruction/RegularizedIterativeSENSEReconstruction.py#L97-L101">97&ndash;101</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/algorithms/reconstruction/RegularizedIterativeSENSEReconstruction.py#L115-L140">115&ndash;140</a></td></tr><tr><td colspan="5"><b>src/mrpro/data</b></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/AcqInfo.py">AcqInfo.py</a></td><td>141</td><td>5</td><td>96%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/AcqInfo.py#L42">42</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/AcqInfo.py#L120-L121">120&ndash;121</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/AcqInfo.py#L123">123</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/AcqInfo.py#L229">229</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/CsmData.py">CsmData.py</a></td><td>40</td><td>5</td><td>88%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/CsmData.py#L16-L18">16&ndash;18</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/CsmData.py#L165-L167">165&ndash;167</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Dataclass.py">Dataclass.py</a></td><td>227</td><td>20</td><td>91%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Dataclass.py#L40">40</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Dataclass.py#L296">296</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Dataclass.py#L312">312</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Dataclass.py#L378">378</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Dataclass.py#L436-L438">436&ndash;438</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Dataclass.py#L451">451</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Dataclass.py#L533">533</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Dataclass.py#L553-L554">553&ndash;554</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Dataclass.py#L556">556</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Dataclass.py#L571-L572">571&ndash;572</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Dataclass.py#L574">574</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Dataclass.py#L608">608</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Dataclass.py#L621-L622">621&ndash;622</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Dataclass.py#L627-L628">627&ndash;628</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/DcfData.py">DcfData.py</a></td><td>35</td><td>2</td><td>94%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/DcfData.py#L15">15</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/DcfData.py#L62">62</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/EncodingLimits.py">EncodingLimits.py</a></td><td>81</td><td>3</td><td>96%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/EncodingLimits.py#L33">33</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/EncodingLimits.py#L123">123</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/EncodingLimits.py#L126">126</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/IData.py">IData.py</a></td><td>52</td><td>2</td><td>96%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/IData.py#L119">119</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/IData.py#L133">133</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/IHeader.py">IHeader.py</a></td><td>127</td><td>7</td><td>94%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/IHeader.py#L68-L71">68&ndash;71</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/IHeader.py#L250">250</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/IHeader.py#L254">254</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/IHeader.py#L258">258</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/IHeader.py#L262">262</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/KData.py">KData.py</a></td><td>217</td><td>32</td><td>85%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/KData.py#L114-L115">114&ndash;115</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/KData.py#L130">130</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/KData.py#L137">137</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/KData.py#L148-L159">148&ndash;159</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/KData.py#L168">168</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/KData.py#L176">176</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/KData.py#L185">185</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/KData.py#L219">219</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/KData.py#L241-L243">241&ndash;243</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/KData.py#L287-L288">287&ndash;288</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/KData.py#L490">490</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/KData.py#L492">492</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/KData.py#L563">563</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/KData.py#L652-L661">652&ndash;661</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/KHeader.py">KHeader.py</a></td><td>134</td><td>16</td><td>88%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/KHeader.py#L23">23</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/KHeader.py#L107-L113">107&ndash;113</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/KHeader.py#L140">140</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/KHeader.py#L188">188</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/KHeader.py#L195-L196">195&ndash;196</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/KHeader.py#L199">199</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/KHeader.py#L206">206</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/KHeader.py#L223-L230">223&ndash;230</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/KNoise.py">KNoise.py</a></td><td>22</td><td>1</td><td>95%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/KNoise.py#L44">44</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/KTrajectory.py">KTrajectory.py</a></td><td>95</td><td>3</td><td>97%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/KTrajectory.py#L163">163</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/KTrajectory.py#L165">165</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/KTrajectory.py#L185">185</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/QData.py">QData.py</a></td><td>32</td><td>1</td><td>97%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/QData.py#L43">43</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Rotation.py">Rotation.py</a></td><td>737</td><td>37</td><td>95%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Rotation.py#L103">103</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Rotation.py#L201">201</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Rotation.py#L338">338</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Rotation.py#L436">436</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Rotation.py#L480">480</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Rotation.py#L498">498</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Rotation.py#L585">585</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Rotation.py#L587">587</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Rotation.py#L596">596</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Rotation.py#L630">630</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Rotation.py#L632">632</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Rotation.py#L695">695</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Rotation.py#L772">772</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Rotation.py#L777">777</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Rotation.py#L780">780</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Rotation.py#L795">795</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Rotation.py#L812">812</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Rotation.py#L817">817</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Rotation.py#L893">893</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Rotation.py#L1081">1081</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Rotation.py#L1086">1086</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Rotation.py#L1089">1089</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Rotation.py#L1113">1113</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Rotation.py#L1117">1117</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Rotation.py#L1245">1245</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Rotation.py#L1247">1247</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Rotation.py#L1255-L1256">1255&ndash;1256</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Rotation.py#L1320">1320</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Rotation.py#L1402">1402</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Rotation.py#L1647">1647</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Rotation.py#L1731">1731</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Rotation.py#L1883">1883</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Rotation.py#L1918">1918</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Rotation.py#L1922">1922</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Rotation.py#L2098">2098</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/Rotation.py#L2119">2119</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/SpatialDimension.py">SpatialDimension.py</a></td><td>240</td><td>20</td><td>92%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/SpatialDimension.py#L34">34</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/SpatialDimension.py#L103">103</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/SpatialDimension.py#L146">146</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/SpatialDimension.py#L152">152</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/SpatialDimension.py#L158">158</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/SpatialDimension.py#L278-L280">278&ndash;280</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/SpatialDimension.py#L293-L295">293&ndash;295</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/SpatialDimension.py#L329">329</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/SpatialDimension.py#L347">347</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/SpatialDimension.py#L360">360</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/SpatialDimension.py#L373">373</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/SpatialDimension.py#L386">386</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/SpatialDimension.py#L399">399</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/SpatialDimension.py#L408-L409">408&ndash;409</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/SpatialDimension.py#L437">437</a></td></tr><tr><td colspan="5"><b>src/mrpro/data/traj_calculators</b></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/traj_calculators/KTrajectoryCalculator.py">KTrajectoryCalculator.py</a></td><td>29</td><td>2</td><td>93%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/traj_calculators/KTrajectoryCalculator.py#L84">84</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/traj_calculators/KTrajectoryCalculator.py#L96">96</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/traj_calculators/KTrajectoryCartesian.py">KTrajectoryCartesian.py</a></td><td>31</td><td>4</td><td>87%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/traj_calculators/KTrajectoryCartesian.py#L107-L110">107&ndash;110</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/traj_calculators/KTrajectoryCartesian.py#L114">114</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/traj_calculators/KTrajectoryIsmrmrd.py">KTrajectoryIsmrmrd.py</a></td><td>19</td><td>1</td><td>95%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/data/traj_calculators/KTrajectoryIsmrmrd.py#L57">57</a></td></tr><tr><td colspan="5"><b>src/mrpro/operators</b></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/AveragingOp.py">AveragingOp.py</a></td><td>34</td><td>2</td><td>94%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/AveragingOp.py#L53">53</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/AveragingOp.py#L78">78</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/CartesianSamplingOp.py">CartesianSamplingOp.py</a></td><td>97</td><td>4</td><td>96%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/CartesianSamplingOp.py#L141">141</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/CartesianSamplingOp.py#L180">180</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/CartesianSamplingOp.py#L255">255</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/CartesianSamplingOp.py#L322">322</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/ConstraintsOp.py">ConstraintsOp.py</a></td><td>79</td><td>4</td><td>95%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/ConstraintsOp.py#L78">78</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/ConstraintsOp.py#L80">80</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/ConstraintsOp.py#L211">211</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/ConstraintsOp.py#L216">216</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/EndomorphOperator.py">EndomorphOperator.py</a></td><td>32</td><td>2</td><td>94%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/EndomorphOperator.py#L52">52</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/EndomorphOperator.py#L58">58</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/FiniteDifferenceOp.py">FiniteDifferenceOp.py</a></td><td>27</td><td>2</td><td>93%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/FiniteDifferenceOp.py#L40">40</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/FiniteDifferenceOp.py#L105">105</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/FourierOp.py">FourierOp.py</a></td><td>90</td><td>3</td><td>97%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/FourierOp.py#L185">185</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/FourierOp.py#L257">257</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/FourierOp.py#L262">262</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/Functional.py">Functional.py</a></td><td>77</td><td>9</td><td>88%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/Functional.py#L20-L22">20&ndash;22</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/Functional.py#L117">117</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/Functional.py#L119">119</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/Functional.py#L226-L228">226&ndash;228</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/Functional.py#L242">242</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/GridSamplingOp.py">GridSamplingOp.py</a></td><td>136</td><td>9</td><td>93%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/GridSamplingOp.py#L71-L72">71&ndash;72</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/GridSamplingOp.py#L81-L82">81&ndash;82</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/GridSamplingOp.py#L89-L90">89&ndash;90</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/GridSamplingOp.py#L93">93</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/GridSamplingOp.py#L95">95</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/GridSamplingOp.py#L97">97</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/LinearOperator.py">LinearOperator.py</a></td><td>201</td><td>8</td><td>96%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/LinearOperator.py#L107">107</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/LinearOperator.py#L217">217</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/LinearOperator.py#L244">244</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/LinearOperator.py#L251">251</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/LinearOperator.py#L292">292</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/LinearOperator.py#L301">301</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/LinearOperator.py#L309">309</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/LinearOperator.py#L326">326</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/LinearOperatorMatrix.py">LinearOperatorMatrix.py</a></td><td>162</td><td>19</td><td>88%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/LinearOperatorMatrix.py#L82">82</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/LinearOperatorMatrix.py#L119">119</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/LinearOperatorMatrix.py#L152">152</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/LinearOperatorMatrix.py#L161">161</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/LinearOperatorMatrix.py#L166">166</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/LinearOperatorMatrix.py#L175-L178">175&ndash;178</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/LinearOperatorMatrix.py#L191-L194">191&ndash;194</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/LinearOperatorMatrix.py#L202-L203">202&ndash;203</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/LinearOperatorMatrix.py#L208-L209">208&ndash;209</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/LinearOperatorMatrix.py#L221">221</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/LinearOperatorMatrix.py#L310">310</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/LinearOperatorMatrix.py#L340">340</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/LinearOperatorMatrix.py#L367">367</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/MultiIdentityOp.py">MultiIdentityOp.py</a></td><td>13</td><td>2</td><td>85%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/MultiIdentityOp.py#L43">43</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/MultiIdentityOp.py#L48">48</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/NonUniformFastFourierOp.py">NonUniformFastFourierOp.py</a></td><td>190</td><td>10</td><td>95%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/NonUniformFastFourierOp.py#L69">69</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/NonUniformFastFourierOp.py#L96">96</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/NonUniformFastFourierOp.py#L206">206</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/NonUniformFastFourierOp.py#L208">208</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/NonUniformFastFourierOp.py#L242">242</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/NonUniformFastFourierOp.py#L244">244</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/NonUniformFastFourierOp.py#L321">321</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/NonUniformFastFourierOp.py#L379">379</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/NonUniformFastFourierOp.py#L429">429</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/NonUniformFastFourierOp.py#L434">434</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/Operator.py">Operator.py</a></td><td>79</td><td>2</td><td>97%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/Operator.py#L32">32</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/Operator.py#L88">88</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/PatchOp.py">PatchOp.py</a></td><td>47</td><td>3</td><td>94%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/PatchOp.py#L81">81</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/PatchOp.py#L112">112</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/PatchOp.py#L127">127</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/ProximableFunctionalSeparableSum.py">ProximableFunctionalSeparableSum.py</a></td><td>39</td><td>3</td><td>92%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/ProximableFunctionalSeparableSum.py#L50">50</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/ProximableFunctionalSeparableSum.py#L103">103</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/ProximableFunctionalSeparableSum.py#L110">110</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/SliceProjectionOp.py">SliceProjectionOp.py</a></td><td>178</td><td>10</td><td>94%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/SliceProjectionOp.py#L45">45</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/SliceProjectionOp.py#L62">62</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/SliceProjectionOp.py#L64">64</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/SliceProjectionOp.py#L70">70</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/SliceProjectionOp.py#L153">153</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/SliceProjectionOp.py#L179">179</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/SliceProjectionOp.py#L215">215</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/SliceProjectionOp.py#L236">236</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/SliceProjectionOp.py#L269">269</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/SliceProjectionOp.py#L309">309</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/WaveletOp.py">WaveletOp.py</a></td><td>119</td><td>5</td><td>96%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/WaveletOp.py#L151">151</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/WaveletOp.py#L169">169</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/WaveletOp.py#L204">204</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/WaveletOp.py#L209">209</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/WaveletOp.py#L232">232</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/ZeroPadOp.py">ZeroPadOp.py</a></td><td>16</td><td>1</td><td>94%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/ZeroPadOp.py#L30">30</a></td></tr><tr><td colspan="5"><b>src/mrpro/operators/functionals</b></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/functionals/SSIM.py">SSIM.py</a></td><td>71</td><td>7</td><td>90%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/functionals/SSIM.py#L60-L80">60&ndash;80</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/functionals/SSIM.py#L82">82</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/functionals/SSIM.py#L86">86</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/functionals/SSIM.py#L115">115</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/functionals/SSIM.py#L148">148</a></td></tr><tr><td colspan="5"><b>src/mrpro/operators/models</b></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/models/EPG.py">EPG.py</a></td><td>202</td><td>41</td><td>80%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/models/EPG.py#L85-L97">85&ndash;97</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/models/EPG.py#L145-L149">145&ndash;149</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/models/EPG.py#L169-L172">169&ndash;172</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/models/EPG.py#L193-L198">193&ndash;198</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/models/EPG.py#L261">261</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/models/EPG.py#L266">266</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/models/EPG.py#L282-L284">282&ndash;284</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/models/EPG.py#L304-L305">304&ndash;305</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/models/EPG.py#L310">310</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/models/EPG.py#L334">334</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/models/EPG.py#L339">339</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/models/EPG.py#L364">364</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/models/EPG.py#L369">369</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/models/EPG.py#L423">423</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/models/EPG.py#L480">480</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/models/EPG.py#L581">581</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/operators/models/EPG.py#L608">608</a></td></tr><tr><td colspan="5"><b>src/mrpro/phantoms</b></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/phantoms/brainweb.py">brainweb.py</a></td><td>276</td><td>31</td><td>89%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/phantoms/brainweb.py#L326-L336">326&ndash;336</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/phantoms/brainweb.py#L372">372</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/phantoms/brainweb.py#L428-L431">428&ndash;431</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/phantoms/brainweb.py#L453-L454">453&ndash;454</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/phantoms/brainweb.py#L459-L460">459&ndash;460</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/phantoms/brainweb.py#L462-L463">462&ndash;463</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/phantoms/brainweb.py#L467">467</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/phantoms/brainweb.py#L475">475</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/phantoms/brainweb.py#L482-L483">482&ndash;483</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/phantoms/brainweb.py#L521">521</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/phantoms/brainweb.py#L587-L588">587&ndash;588</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/phantoms/brainweb.py#L607-L610">607&ndash;610</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/phantoms/brainweb.py#L621">621</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/phantoms/brainweb.py#L623">623</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/phantoms/brainweb.py#L656-L657">656&ndash;657</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/phantoms/brainweb.py#L670">670</a></td></tr><tr><td colspan="5"><b>src/mrpro/utils</b></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/RandomGenerator.py">RandomGenerator.py</a></td><td>152</td><td>14</td><td>91%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/RandomGenerator.py#L23-L24">23&ndash;24</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/RandomGenerator.py#L36">36</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/RandomGenerator.py#L38">38</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/RandomGenerator.py#L170">170</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/RandomGenerator.py#L194">194</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/RandomGenerator.py#L410">410</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/RandomGenerator.py#L428">428</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/RandomGenerator.py#L510">510</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/RandomGenerator.py#L793-L796">793&ndash;796</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/RandomGenerator.py#L859">859</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/RandomGenerator.py#L862">862</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/filters.py">filters.py</a></td><td>62</td><td>2</td><td>97%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/filters.py#L44">44</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/filters.py#L49">49</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/indexing.py">indexing.py</a></td><td>183</td><td>1</td><td>99%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/indexing.py#L320">320</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/pad_or_crop.py">pad_or_crop.py</a></td><td>31</td><td>6</td><td>81%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/pad_or_crop.py#L26">26</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/pad_or_crop.py#L30">30</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/pad_or_crop.py#L58">58</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/pad_or_crop.py#L61">61</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/pad_or_crop.py#L64">64</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/pad_or_crop.py#L67">67</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/reshape.py">reshape.py</a></td><td>101</td><td>2</td><td>98%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/reshape.py#L111">111</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/reshape.py#L305">305</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/slice_profiles.py">slice_profiles.py</a></td><td>49</td><td>6</td><td>88%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/slice_profiles.py#L21">21</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/slice_profiles.py#L37">37</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/slice_profiles.py#L119-L122">119&ndash;122</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/slice_profiles.py#L155">155</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/split_idx.py">split_idx.py</a></td><td>10</td><td>2</td><td>80%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/split_idx.py#L43">43</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/split_idx.py#L47">47</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/summarize.py">summarize.py</a></td><td>58</td><td>7</td><td>88%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/summarize.py#L40-L41">40&ndash;41</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/summarize.py#L70-L73">70&ndash;73</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/summarize.py#L77">77</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/summarize.py#L81">81</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/typing.py">typing.py</a></td><td>73</td><td>56</td><td>23%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/typing.py#L9-L236">9&ndash;236</a></td></tr><tr><td>&nbsp; &nbsp;<a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/unit_conversion.py">unit_conversion.py</a></td><td>60</td><td>14</td><td>77%</td><td><a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/unit_conversion.py#L32">32</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/unit_conversion.py#L40">40</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/unit_conversion.py#L42">42</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/unit_conversion.py#L49">49</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/unit_conversion.py#L51">51</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/unit_conversion.py#L58">58</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/unit_conversion.py#L60">60</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/unit_conversion.py#L69">69</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/unit_conversion.py#L80">80</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/unit_conversion.py#L82">82</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/unit_conversion.py#L101">101</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/unit_conversion.py#L103">103</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/unit_conversion.py#L124">124</a>, <a href="https://github.com/PTB-MR/mrpro/blob/6e551b5a4b32e18ff498735e57cf72bbd2565812/src/mrpro/utils/unit_conversion.py#L126">126</a></td></tr><tr><td><b>TOTAL</b></td><td><b>6754</b></td><td><b>507</b></td><td><b>92%</b></td><td>&nbsp;</td></tr></tbody></table></details>

| Tests | Skipped | Failures | Errors | Time |
| ----- | ------- | -------- | -------- | ------------------ |
| 2856 | 0 :zzz: | 0 :x: | 0 :fire: | 1m 52s :stopwatch: |

author_association: CONTRIBUTOR
user: login: github-actions[bot]
created_at: 2025-04-03T15:40:50Z
body: <!-- documentation build 763 -->
### :books: Documentation
:file_folder: [Download as zip](https://github.com/PTB-MR/mrpro/actions/runs/14684615507/artifacts/3015287769)
:mag: [View online](https://zimf.de/zipserve/https://github.com/PTB-MR/mrpro/actions/runs/14684615507/artifacts/3015287769/)
author_association: CONTRIBUTOR