44module is `PixelMask`. Any type of region of interest selection results in a `PixelMask` object. A mask can be applied
55to any pixel dataset (EITData, PixelMap) with the same shape.
66
7- Several default masks have been predefined. NB: the right side of the patient is to the left side of the EIT image and
8- vice versa.
9-
10- - `VENTRAL_MASK` includes only the first 16 rows;
11- - `DORSAL_MASK` includes only the last 16 rows;
12- - `ANATOMICAL_RIGHT_MASK` includes only the first 16 columns;
13- - `ANATOMICAL_LEFT_MASK` includes only the last 16 columns;
14- - `QUADRANT_1_MASK` includes the top right quadrant;
15- - `QUADRANT_2_MASK` includes the top left quadrant;
16- - `QUADRANT_3_MASK` includes the bottom right quadrant;
17- - `QUADRANT_4_MASK` includes the bottom left quadrant;
18- - `LAYER_1_MASK` includes only the first 8 rows;
19- - `LAYER_2_MASK` includes only the second set of 8 rows;
20- - `LAYER_3_MASK` includes only the third set of 8 rows;
21- - `LAYER_4_MASK` includes only the last 8 rows.
7+ Predefined default masks can be created using `get_geometric_mask()`. These masks are based on common anatomical regions
8+ of interest.
229"""
2310
2411from __future__ import annotations
@@ -295,7 +282,7 @@ def __eq__(self, other: object) -> bool:
295282 return self .mask .shape == other .mask .shape and np .array_equal (self .mask , other .mask , equal_nan = True )
296283
297284
298- def get_geometric_mask (mask : str , shape : tuple [int , int ] = (32 , 32 )) -> PixelMask :
285+ def get_geometric_mask (mask : str , shape : tuple [int , int ] = (32 , 32 )) -> PixelMask : # noqa: PLR0911
299286 """Get a geometric mask by name.
300287
301288 Masks can be generated for appropriates shapes, provided by the shape` argument, a tuple of two integers
@@ -305,6 +292,7 @@ def get_geometric_mask(mask: str, shape: tuple[int, int] = (32, 32)) -> PixelMas
305292 The function accepts both full names (e.g., "layer 1") and abbreviations (e.g., "L1").
306293
307294 The following masks are available:
295+ - "global" or "G": all pixels in the EIT image.
308296 - "ventral" or "V": the first half rows of the EIT image.
309297 - "dorsal" or "D": the last half rows of the EIT image.
310298 - "anatomical right" or "R": the first half columns of the EIT image.
@@ -331,23 +319,6 @@ def get_geometric_mask(mask: str, shape: tuple[int, int] = (32, 32)) -> PixelMas
331319 ValueError: If an unknown mask name is provided.
332320 ValueError: If the shape is not compatible with the requested mask.
333321 """
334-
335- def _check_dimensions (
336- name : str , shape : tuple [int , int ], * , height_divisor : int | None = None , width_divisor : int | None = None
337- ) -> None :
338- total_height , total_width = shape
339- if isinstance (height_divisor , int ) and total_height % height_divisor != 0 :
340- msg = (
341- f"Shape { shape } is not compatible with a { name } mask. "
342- "The height must be a multiple of {height_divisor}."
343- )
344- raise ValueError (msg )
345- if isinstance (width_divisor , int ) and total_width % width_divisor != 0 :
346- msg = (
347- f"Shape { shape } is not compatible with a { name } mask. The width must be a multiple of { width_divisor } ."
348- )
349- raise ValueError (msg )
350-
351322 total_height , total_width = shape
352323 n_layers_quadrants = 4
353324
@@ -356,6 +327,8 @@ def _check_dimensions(
356327 mask = re .sub (r"^L([1-4]{1})$" , r"layer \1" , mask )
357328
358329 match mask .split (" " ):
330+ case ["global" ] | ["G" ]:
331+ return PixelMask (np .ones (shape ), label = "global" )
359332 case ["ventral" ] | ["V" ]:
360333 _check_dimensions ("ventral" , shape , height_divisor = 2 )
361334 height = total_height // 2
@@ -386,7 +359,7 @@ def _check_dimensions(
386359
387360 case ["layer" , num_str ] if num_str .isdigit () and 1 <= int (num_str ) <= n_layers_quadrants :
388361 num = int (num_str )
389- _check_dimensions ("layer" , shape , height_divisor = 4 )
362+ _check_dimensions ("layer" , shape , height_divisor = n_layers_quadrants )
390363 height = total_height // n_layers_quadrants
391364 return PixelMask (
392365 np .concatenate (
@@ -410,3 +383,17 @@ def _check_dimensions(
410383 case _:
411384 msg = f"Unknown mask name: { mask } ."
412385 raise ValueError (msg )
386+
387+
388+ def _check_dimensions (
389+ name : str , shape : tuple [int , int ], * , height_divisor : int | None = None , width_divisor : int | None = None
390+ ) -> None :
391+ total_height , total_width = shape
392+ if isinstance (height_divisor , int ) and total_height % height_divisor != 0 :
393+ msg = (
394+ f"Shape { shape } is not compatible with a { name } mask. The height must be a multiple of {{height_divisor}}."
395+ )
396+ raise ValueError (msg )
397+ if isinstance (width_divisor , int ) and total_width % width_divisor != 0 :
398+ msg = f"Shape { shape } is not compatible with a { name } mask. The width must be a multiple of { width_divisor } ."
399+ raise ValueError (msg )
0 commit comments