Skip to content

eyepy.io.he.e2e_reader

E2EFileStructure()

Bases: E2EStructureMixin

E2E File Structure.

Source code in src/eyepy/io/he/e2e_reader.py
def __init__(self):
    self.substructure: dict[int, E2EPatientStructure] = {}
    self.folders: dict[Union[int, str], list[E2EFolder]] = {}

    self._section_description_parts = []
    self._section_title = ''
    self._section_description = ''

add_folder(folder)

Add a folder to the File Structure.

Parameters:

Name Type Description Default
folder E2EFolder

The folder to add.

required
Source code in src/eyepy/io/he/e2e_reader.py
def add_folder(self, folder: E2EFolder):
    """Add a folder to the File Structure.

    Args:
        folder: The folder to add.
    """
    try:
        self.all_folders.append(folder)
    except AttributeError:
        self.all_folders = [folder]

    if folder.patient_id == -1:
        try:
            self.folders[folder.type].append(folder)
        except KeyError:
            self.folders[folder.type] = [folder]
    else:
        if folder.patient_id not in self.patients:
            self.patients[folder.patient_id] = E2EPatientStructure(
                folder.patient_id)
        self.patients[folder.patient_id].add_folder(folder)

E2EFolder dataclass

Folder data class.

Note

Folders are created during initialization of the HeE2eReader. For accessing the data the respective HeE2eReader has to be used as a Context Manager. This opens the E2E file and allows the E2EFolder to access the data.

with HeE2eReader("path/to/e2e") as reader:
    folder_dict = reader.file_hierarchy.folders
    folder = folder_dict[TypesEnum.YOURTYPE][0]
    data = folder.data

data: Any property

Return the data.

file_object: BufferedReader property

Return the file object.

This refers to the the HeE2eReader file object.

header: ContainerHeader property

Return the data header.

get_bytes()

Return the bytes of the data.

This only works if the HeE2eReader is used as a Context Manager or during initialization of the HeE2eReader. Otherwise the E2E file is not open.

Source code in src/eyepy/io/he/e2e_reader.py
def get_bytes(self) -> bytes:
    """Return the bytes of the data.

    This only works if the HeE2eReader is used as a Context Manager
    or during initialization of the HeE2eReader. Otherwise the E2E
    file is not open.
    """
    self.file_object.seek(self.start + containerheader_format.sizeof())
    return self.file_object.read(self.size)

parse_spec(data_construct, offset=0)

Parse a data specification.

This only works if the HeE2eReader is used as a Context Manager or during initialization of the HeE2eReader. Otherwise the E2E file is not open.

Parameters:

Name Type Description Default
data_construct Construct

The construct to parse the data with. You can Constructs defined in the construct library or those defined in the e2e_format module.

required
offset int

The offset in bytes, 0 by default.

0
Source code in src/eyepy/io/he/e2e_reader.py
def parse_spec(self, data_construct: cs.Construct, offset: int = 0) -> Any:
    """Parse a data specification.

    This only works if the HeE2eReader is used as a Context Manager or during initialization of the HeE2eReader.
    Otherwise the E2E file is not open.



    Args:
        data_construct: The construct to parse the data with. You can Constructs defined in the construct library or those defined in the [e2e_format][eyepy.io.he.e2e_format] module.
        offset: The offset in bytes, 0 by default.
    """
    b = self.get_bytes()
    return data_construct.parse(b[offset:])

E2EPatientStructure(id)

Bases: E2EStructureMixin

E2E Patient Structure.

Source code in src/eyepy/io/he/e2e_reader.py
def __init__(self, id) -> None:
    self.id = id
    self.substructure: dict[int, E2EStudyStructure] = {}
    self.folders: dict[Union[int, str], list[E2EFolder]] = {}

    self._section_description_parts = []
    self._section_title = ''
    self._section_description = ''

add_folder(folder)

Add a folder to the Patient Structure.

Parameters:

Name Type Description Default
folder E2EFolder

The folder to add.

required
Source code in src/eyepy/io/he/e2e_reader.py
def add_folder(self, folder: E2EFolder) -> None:
    """Add a folder to the Patient Structure.

    Args:
        folder: The folder to add.
    """
    if folder.study_id == -1:
        try:
            self.folders[folder.type].append(folder)
        except KeyError:
            self.folders[folder.type] = [folder]
    else:
        if folder.study_id not in self.studies:
            self.studies[folder.study_id] = E2EStudyStructure(
                folder.study_id)
        self.studies[folder.study_id].add_folder(folder)

E2ESeriesStructure(id)

Bases: E2EStructureMixin

E2E Series Structure.

This structure contains folders with data for a single Series/OCT- Volume and provides convenience functions for accessing the data.

Source code in src/eyepy/io/he/e2e_reader.py
def __init__(self, id: int) -> None:
    self.id = id
    self.substructure: dict[int, E2ESliceStructure] = {}
    self.folders: dict[Union[int, str], list[E2EFolder]] = {}

    self._meta = None
    self._bscan_meta = None
    self._localizer_meta = None
    self._section_title = ''
    self._section_description = ''

    # Description used in inspect()
    # Parts are (name, folder_id, index in list of strings)
    self._section_description_parts = [
        ('Structure:', 9005, 0),
        ('Scanpattern:', 9006, 0),
        ('Oct Modality:', 9008, 1),
        ('Enface Modality:', 9007, 1),
    ]

n_bscans: int property

Return the number of B-scans in the series.

slices: dict[int, E2ESliceStructure] property

Alias for substructure.

add_folder(folder)

Add a folder to the Series.

Parameters:

Name Type Description Default
folder E2EFolder

The folder to add.

required
Source code in src/eyepy/io/he/e2e_reader.py
def add_folder(self, folder: E2EFolder) -> None:
    """Add a folder to the Series.

    Args:
        folder: The folder to add.
    """
    if folder.slice_id == -1:
        try:
            self.folders[folder.type].append(folder)
        except KeyError:
            self.folders[folder.type] = [folder]
    else:
        if folder.slice_id not in self.slices:
            self.slices[folder.slice_id] = E2ESliceStructure(
                folder.slice_id)
        self.slices[folder.slice_id].add_folder(folder)

get_bscan_meta()

Return EyeBscanMeta objects for all B-scans in the series.

Source code in src/eyepy/io/he/e2e_reader.py
def get_bscan_meta(self) -> list[EyeBscanMeta]:
    """Return EyeBscanMeta objects for all B-scans in the series."""
    if self._bscan_meta is None:
        self._bscan_meta = sorted(
            [sl.get_meta() for sl in self.slices.values()],
            key=lambda x: x['aktImage'])
    return self._bscan_meta

get_layers()

Return layer height maps for the series as dict of numpy arrays where the key is the layer id.

Source code in src/eyepy/io/he/e2e_reader.py
def get_layers(self) -> dict[int, np.ndarray]:
    """Return layer height maps for the series as dict of numpy arrays where
    the key is the layer id."""
    slice_layers = {}
    layer_ids = set()

    for ind, sl in self.slices.items():
        layers = sl.get_layers()
        [layer_ids.add(k) for k in layers.keys()]
        slice_layers[ind // 2] = layers

    layers = {}
    size_x = self.get_bscan_meta()[0]['size_x']
    for i in layer_ids:
        layer = np.full((self.n_bscans, size_x), np.nan)
        if self.n_bscans == 1:
            layer[0, :] = slice_layers[1][i]
            layers[i] = layer

        else:
            for sl in range(self.n_bscans):
                layer[sl, :] = slice_layers[sl][i]

        layer[layer >= 3.0e+38] = np.nan
        layers[i] = layer

    return layers

get_localizer()

Return EyeEnface object for the localizer image.

Source code in src/eyepy/io/he/e2e_reader.py
def get_localizer(self) -> EyeEnface:
    """Return EyeEnface object for the localizer image."""
    try:
        folders = self.folders[TypesEnum.image]
        if len(folders) > 1:
            logger.warning(
                'There is more than one enface localizer image stored. This is not expected.'
            )

        # Slodata is not always present in E2E files.
        # Todo: Give transform to EyeEnface object where it is applied to the image. EyeEnface then by default has an identity transform.
        #transform = np.array(list(self.slo_data().transform) +
        #                     [0, 0, 1]).reshape((3, 3))
        # transfrom localizer with transform from E2E file
        #transformed_localizer = warp(folders[0].data.data,
        #                             AffineTransform(transform),
        #                             order=1,
        #                             preserve_range=True)
        return EyeEnface(folders[0].data.data, self.localizer_meta())
    except KeyError:
        if self.n_bscans == 1:
            slice_struct = self.slices[2]
            return EyeEnface(slice_struct.get_localizer(),
                             self.localizer_meta())
        else:
            raise ValueError(
                'There is no localizer/fundus image in the E2E file.')

get_meta()

Return EyeVolumeMeta object for the series.

Source code in src/eyepy/io/he/e2e_reader.py
def get_meta(self) -> EyeVolumeMeta:
    """Return EyeVolumeMeta object for the series."""
    if self._meta is None:
        bscan_meta = self.get_bscan_meta()
        self._meta = EyeVolumeMeta(
            scale_x=1,  #0.0114,  # Todo: Where is this in E2E?
            scale_y=1,  #bscan_meta[0]["scale_y"],
            scale_z=1,  #get_bscan_spacing(bscan_meta) if
            #(bscan_meta[0]["scan_pattern"] not in [1, 2]) else 0.03,
            scale_unit='px',
            laterality=self.laterality(),
            visit_date=None,
            exam_time=None,
            bscan_meta=bscan_meta,
            intensity_transform='vol',
        )
    return self._meta

get_volume()

Return EyeVolume object for the series.

Source code in src/eyepy/io/he/e2e_reader.py
def get_volume(self) -> EyeVolume:
    """Return EyeVolume object for the series."""
    ## Check if scan is a volume scan
    volume_meta = self.get_meta()

    scan_pattern = volume_meta['bscan_meta'][0]['scan_pattern']

    ## Check if scan pattern is supported by EyeVolume
    if scan_pattern == 2:
        msg = f'The EyeVolume object does not support scan pattern 2 (one Circular B-scan).'
        raise ValueError(msg)
    elif scan_pattern == 5:
        msg = f'The EyeVolume object does not support scan pattern 5 (Radial scan - star pattern).'
        raise ValueError(msg)

    data = self.get_bscans()

    volume_meta = self.get_meta()
    localizer = self.get_localizer()
    volume = EyeVolume(
        data=data,
        meta=volume_meta,
        localizer=localizer,
        transformation=_compute_localizer_oct_transform(
            volume_meta, localizer.meta, data.shape),
    )

    layer_height_maps = self.get_layers()
    for name, i in SEG_MAPPING.items():
        if i in layer_height_maps:
            volume.add_layer_annotation(layer_height_maps[i], name=name)

    return volume

inspect(recursive=False, ind_prefix='', tables=False)

Inspect the series.

Custom inspect method to print a summary table for the slices belonging to the series.

Parameters:

Name Type Description Default
recursive bool

If True inspect lower level structures recursively.

False
ind_prefix str

Indentation for showing information from lower level structures.

''
tables bool

If True add markdown table overview of the contained folder types.

False
Source code in src/eyepy/io/he/e2e_reader.py
def inspect(self,
            recursive: bool = False,
            ind_prefix: str = '',
            tables: bool = False) -> str:
    """Inspect the series.

    Custom `inspect` method to print a summary table for the slices belonging to the series.

    Args:
        recursive: If True inspect lower level structures recursively.
        ind_prefix: Indentation for showing information from lower level structures.
        tables: If True add markdown table overview of the contained folder types.
    """
    laterality = self.folders[TypesEnum.laterality][
        0].data.laterality.name if TypesEnum.laterality in self.folders else 'Unknown'
    text = self._get_section_title(
    ) + f' - Laterality: {laterality} - B-scans: {self.n_bscans}\n'
    text += self._get_section_description() + '\n'
    if tables:
        text += self._get_folder_summary() + '\n'

    if not recursive:
        return text

    # Describe all slices in one table
    s_data = defaultdict(list)
    for sl in self.slices.values():
        for f_list in sl.folders.values():
            for f in f_list:
                s_data[f.type].append(f.size)

    if len(s_data) == 0 or tables == False:
        text += ''
    else:
        text += '\nE2ESlice Summary:\n'
        text += indent(self._get_table(s_data, 'E2ESliceStructure'),
                       ind_prefix)
        text += '\n'
    return text

localizer_meta()

Return EyeEnfaceMeta object for the localizer image.

Source code in src/eyepy/io/he/e2e_reader.py
def localizer_meta(self) -> EyeEnfaceMeta:
    """Return EyeEnfaceMeta object for the localizer image."""
    if self._localizer_meta is None:
        self._localizer_meta = EyeEnfaceMeta(
            scale_x=1,  #0.0114,  # Todo: Where is this in E2E?
            scale_y=1,  #0.0114,  # Todo: Where is this in E2E?
            scale_unit='px',
            modality=self.enface_modality(),
            laterality=self.laterality(),
            field_size=None,
            scan_focus=None,
            visit_date=None,
            exam_time=None,
        )
    logger.info(
        'The localizer scale is currently hardcoded and not read from the E2E file. If you know how or where to find the scale information let us know by opening an issue.'
    )
    return self._localizer_meta

E2ESliceStructure(id)

Bases: E2EStructureMixin

E2E Slice Structure.

This structure contains folders with data for a single Slice/B-csan and provide convenience functions for accessing the data.

Source code in src/eyepy/io/he/e2e_reader.py
def __init__(self, id: int) -> None:
    self.id = id
    self.folders: dict[Union[int, str], list[E2EFolder]] = {}

    # Empty so inspect() does not fail
    self.substructure = {}

add_folder(folder)

Add a folder to the slice.

Parameters:

Name Type Description Default
folder E2EFolder

The folder to add.

required
Source code in src/eyepy/io/he/e2e_reader.py
def add_folder(self, folder: E2EFolder) -> None:
    """Add a folder to the slice.

    Args:
        folder: The folder to add.
    """
    try:
        self.folders[folder.type].append(folder)
    except KeyError:
        self.folders[folder.type] = [folder]

get_bscan()

Return the slice image (B-scan)

Source code in src/eyepy/io/he/e2e_reader.py
def get_bscan(self) -> np.ndarray:
    """Return the slice image (B-scan)"""
    bscan_folders = [
        f for f in self.folders[TypesEnum.image] if f.data.type == 35652097
    ]
    if len(bscan_folders) > 1:
        logger.warning(
            'There is more than one B-scan per slice. This is not expected.'
        )
    return bscan_folders[0].data.data

get_layers()

Return the layers as a dictionary of layer id and layer data.

Source code in src/eyepy/io/he/e2e_reader.py
def get_layers(self) -> dict[int, np.ndarray]:
    """Return the layers as a dictionary of layer id and layer data."""
    layers = {}
    for layer_folder in self.folders[TypesEnum.layer_annotation]:
        layers[layer_folder.data.id] = layer_folder.data.data
    return layers

get_localizer()

Return the slice image (Localizer/Fundus) For the scanpattern "OCT Bscan" a localizer might be stored in the E2ESliceStructure and not the E2ESeriesStructure.

Source code in src/eyepy/io/he/e2e_reader.py
def get_localizer(self) -> np.ndarray:
    """Return the slice image (Localizer/Fundus) For the scanpattern "OCT
    Bscan" a localizer might be stored in the E2ESliceStructure and not the
    E2ESeriesStructure."""
    localizer_folders = [
        f for f in self.folders[TypesEnum.image] if f.data.type == 33620481
    ]
    if len(localizer_folders) > 1:
        logger.warning(
            'There is more than one localizer per slice. This is not expected.'
        )
    return localizer_folders[0].data.data

get_meta()

Return the slice meta data.

Source code in src/eyepy/io/he/e2e_reader.py
def get_meta(self) -> EyeBscanMeta:
    """Return the slice meta data."""
    if len(self.folders[TypesEnum.bscanmeta]) > 1:
        logger.warning(
            'There is more than one bscanmeta object. This is not expected.'
        )
    meta = self.folders[TypesEnum.bscanmeta][0].data
    return EyeBscanMeta(  #quality=meta.quality,
        start_pos=((meta['start_x'] + 14.86 * 0.29),
                   (meta['start_y'] + 15.02) * 0.29),
        end_pos=((meta['end_x'] + 14.86 * 0.29),
                 (meta['end_y'] + 15.02) * 0.29),
        pos_unit='mm',
        **dataclasses.asdict(meta))

E2EStructureMixin

A Mixin for shared functionality between structures in the E2E hierarchy.

get_folder_data(folder_type, offset=0, data_construct=None)

Return the data of a folder type.

Parameters:

Name Type Description Default
folder_type Union[TypesEnum, int]

Either one of TypesEnum or the type id (int).

required
offset int

Offset to the data in bytes.

0
data_construct Optional[Union[Construct, str]]

A construct to parse the data with (Python construct package) or a string describing one of the basic constructs from the construct package like "Int8ul", or "Float32l"

None

Returns:

Type Description
Any

Parsed data or None if no folder of the given type was found.

Source code in src/eyepy/io/he/e2e_reader.py
def get_folder_data(
    self,
    folder_type: Union[TypesEnum, int],
    offset: int = 0,
    data_construct: Optional[Union[cs.Construct, str]] = None,
) -> Any:
    """Return the data of a folder type.

    Args:
        folder_type: Either one of [TypesEnum][eyepy.io.he.e2e_format.TypesEnum] or the type id (int).
        offset: Offset to the data in bytes.
        data_construct: A construct to parse the data with (Python construct package) or a string describing one of the basic constructs from the construct package like "Int8ul", or "Float32l"

    Returns:
        Parsed data or None if no folder of the given type was found.
    """

    folders: list[E2EFolder] = self.folders[folder_type]

    if len(folders) == 0:
        return None

    if data_construct is None:
        return [f.data for f in folders]
    elif type(data_construct) == str:
        data_construct = getattr(cs, data_construct)

    return [f.parse_spec(data_construct, offset) for f in folders]

inspect(recursive=False, ind_prefix='', tables=False)

Inspect the E2E structure.

Parameters:

Name Type Description Default
recursive bool

If True inspect lower level structures recursively.

False
ind_prefix str

Indentation for showing information from lower level structures.

''
tables bool

If True add markdown table overview of the contained folder types.

False

Returns:

Type Description
str

Information about the E2E structure.

Source code in src/eyepy/io/he/e2e_reader.py
def inspect(self,
            recursive: bool = False,
            ind_prefix: str = '',
            tables: bool = False) -> str:
    """Inspect the E2E structure.

    Args:
        recursive: If True inspect lower level structures recursively.
        ind_prefix: Indentation for showing information from lower level structures.
        tables: If True add markdown table overview of the contained folder types.

    Returns:
        Information about the E2E structure.
    """
    text = self._get_section_title() + '\n'
    text += self._get_section_description() + '\n'
    if tables:
        text += self._get_folder_summary() + '\n'

    if not recursive:
        return text

    for s in self.substructure.values():
        text += '\n'
        text += indent(s.inspect(recursive, ind_prefix, tables),
                       ind_prefix)
    return text

E2EStudyStructure(id)

Bases: E2EStructureMixin

E2E Study Structure.

Source code in src/eyepy/io/he/e2e_reader.py
def __init__(self, id) -> None:
    self.id = id
    self.substructure: dict[int, E2ESeriesStructure] = {}
    self.folders: dict[Union[int, str], list[E2EFolder]] = {}

    self._section_description_parts = [('Device:', 9001, 0),
                                       ('Studyname:', 9000, 0)]
    self._section_title = ''
    self._section_description = ''

add_folder(folder)

Add a folder to the Study.

Parameters:

Name Type Description Default
folder E2EFolder

The folder to add.

required
Source code in src/eyepy/io/he/e2e_reader.py
def add_folder(self, folder: E2EFolder) -> None:
    """Add a folder to the Study.

    Args:
        folder: The folder to add.
    """
    if folder.series_id == -1:
        try:
            self.folders[folder.type].append(folder)
        except KeyError:
            self.folders[folder.type] = [folder]
    else:
        if folder.series_id not in self.series:
            self.series[folder.series_id] = E2ESeriesStructure(
                folder.series_id)
        self.series[folder.series_id].add_folder(folder)

HeE2eReader(path)

Bases: AbstractContextManager

Index an E2E file.

Initialization of the HeE2eReader class indexes the specified E2E file. This allows for printing the reader object for a quick overview of the files contents. If you want to access the data, the reader has to be used as a Context Manager.

with HeE2eReader("path/to/file.e2e") as reader:
    data = reader.volumes

Parameters:

Name Type Description Default
path Union[str, Path]

Path to the e2e file.

required
Source code in src/eyepy/io/he/e2e_reader.py
def __init__(self, path: Union[str, Path]):
    """Index an E2E file.

    Initialization of the HeE2eReader class indexes the specified E2E file. This allows for printing the reader object
    for a quick overview of the files contents. If you want to access the data, the reader has to be used as a Context Manager.

    ```python
    with HeE2eReader("path/to/file.e2e") as reader:
        data = reader.volumes
    ```

    Args:
        path: Path to the e2e file.
    """
    self.path = Path(path)
    self.file_object: BufferedReader

    # Index file to create hierarchy
    self.file_hierarchy = E2EFileStructure()
    self._index_file()

patients: list[E2EPatientStructure] property

List of all patients in the file as E2EPatient objects.

series: list[E2ESeriesStructure] property

List of all series in the file as E2ESeries objects.

studies: list[E2EStudyStructure] property

List of all studies in the file as E2EStudy objects.

volume: EyeVolume property

First EyeVolume object in the E2E file.

Returns:

Type Description
EyeVolume

EyeVolume object for the first Series in the e2e file.

volumes: list[EyeVolume] property

All EyeVolume objects in the E2E file.

Returns:

Type Description
list[EyeVolume]

List with EyeVolume objects for every Series in the e2e file.

find_float(value, excluded_folders=['images', 'layers'], slice_id=None, **kwargs)

Find a float value in the e2e file.

Parameters:

Name Type Description Default
value float

The value to find.

required
excluded_folders list[Union[int, str]]

A list of folders to exclude from the search. None: Exclude no folders. "images": Exclude image data from search. "layers": Exclude layer data from search.

['images', 'layers']
slice_id Optional[int]

The slice to search in. Specify 0 if you do not want to search through all slices but one slice per volume is enough.

None
**kwargs

Keyword arguments passed to find_float.

{}

Returns:

Type Description
dict[int, dict[int, dict[str, list[int]]]]

A dictionary of the form {series_id(int): {folder_type(int): {fmt_string(str): [positions(int)]}}}

Source code in src/eyepy/io/he/e2e_reader.py
def find_float(self,
               value: float,
               excluded_folders: list[Union[int,
                                            str]] = ['images', 'layers'],
               slice_id: Optional[int] = None,
               **kwargs) -> dict[int, dict[int, dict[str, list[int]]]]:
    """Find a float value in the e2e file.

    Args:
        value: The value to find.
        excluded_folders: A list of folders to exclude from the search.
            None: Exclude no folders.
            "images": Exclude image data from search.
            "layers": Exclude layer data from search.
        slice_id: The slice to search in. Specify 0 if you do not want to search through all slices but one slice per volume is enough.
        **kwargs: Keyword arguments passed to [`find_float`][eyepy.io.utils.find_float].

    Returns:
        A dictionary of the form {series_id(int): {folder_type(int): {fmt_string(str): [positions(int)]}}}
    """
    if 'images' in excluded_folders:
        excluded_folders[excluded_folders.index('images')] = 1073741824
    if 'layers' in excluded_folders:
        excluded_folders[excluded_folders.index('layers')] = 10019

    results = defaultdict(dict)
    for folder in self.file_hierarchy.all_folders:
        if not int(folder.type) in excluded_folders and (
                True if slice_id is None else folder.slice_id == slice_id):
            res = find_float(folder.get_bytes(), value, **kwargs)
            if res:
                results[folder.series_id][folder.type] = res
    results = {**results}
    return results

find_int(value, excluded_folders=['images', 'layers'], slice_id=None, **kwargs)

Find an integer value in the e2e file.

Parameters:

Name Type Description Default
value int

The value to find.

required
excluded_folders list[Union[int, str]]

A list of folders to exclude from the search. None: Exclude no folders. "images": Exclude image data from search. "layers": Exclude layer data from search.

['images', 'layers']
slice_id Optional[int]

The slice id to search in.

None
**kwargs

Keyword arguments passed to find_int.

{}

Returns:

Type Description
dict[int, dict[int, dict[str, list[int]]]]

A dictionary of the form {series_id(int): {folder_type(int): {fmt_string(str): [positions(int)]}}}

Source code in src/eyepy/io/he/e2e_reader.py
def find_int(self,
             value: int,
             excluded_folders: list[Union[int,
                                          str]] = ['images', 'layers'],
             slice_id: Optional[int] = None,
             **kwargs) -> dict[int, dict[int, dict[str, list[int]]]]:
    """Find an integer value in the e2e file.

    Args:
        value: The value to find.
        excluded_folders: A list of folders to exclude from the search.
            None: Exclude no folders.
            "images": Exclude image data from search.
            "layers": Exclude layer data from search.
        slice_id: The slice id to search in.
        **kwargs: Keyword arguments passed to [`find_int`][eyepy.io.utils.find_int].

    Returns:
        A dictionary of the form {series_id(int): {folder_type(int): {fmt_string(str): [positions(int)]}}}
    """
    if 'images' in excluded_folders:
        excluded_folders[excluded_folders.index('images')] = 1073741824
    if 'layers' in excluded_folders:
        excluded_folders[excluded_folders.index('layers')] = 10019

    results = defaultdict(dict)
    for folder in self.file_hierarchy.all_folders:
        if not int(folder.type) in excluded_folders and (
                True if slice_id is None else folder.slice_id == slice_id):
            res = find_int(folder.get_bytes(), value, **kwargs)
            if res:
                results[folder.series_id][folder.type] = res
    results = {**results}
    return results

find_number(value, excluded_folders=['images', 'layers'], slice_id=None, **kwargs)

Find a number value in the e2e file.

Use this function if you don't know if the value is an integer or a float. This is just a shortcut for calling find_int and find_float individually.

Parameters:

Name Type Description Default
value Union[int, float]

The value to find.

required
excluded_folders list[Union[int, str]]

A list of folders to exclude from the search. None: Exclude no folders. "images": Exclude image data from search. "layers": Exclude layer data from search.

['images', 'layers']
slice_id Optional[int]

The slice to search in. Specify 0 if you do not want to search through all slices but one slice per volume is enough.

None
**kwargs

Keyword arguments passed to find_int and find_float.

{}

Returns:

Type Description
dict[int, dict[int, dict[str, list[int]]]]

A dictionary of the form {series_id(int): {folder_type(int): {fmt_string(str): [positions(int)]}}}

Source code in src/eyepy/io/he/e2e_reader.py
def find_number(self,
                value: Union[int, float],
                excluded_folders: list[Union[int,
                                             str]] = ['images', 'layers'],
                slice_id: Optional[int] = None,
                **kwargs) -> dict[int, dict[int, dict[str, list[int]]]]:
    """Find a number value in the e2e file.

    Use this function if you don't know if the value is an integer or a float.
    This is just a shortcut for calling [`find_int`][eyepy.io.he.e2e_reader.HeE2eReader.find_int]
    and [`find_float`][eyepy.io.he.e2e_reader.HeE2eReader.find_float] individually.

    Args:
        value: The value to find.
        excluded_folders: A list of folders to exclude from the search.
            None: Exclude no folders.
            "images": Exclude image data from search.
            "layers": Exclude layer data from search.
        slice_id: The slice to search in. Specify 0 if you do not want to search through all slices but one slice per volume is enough.
        **kwargs: Keyword arguments passed to [`find_int`][eyepy.io.utils.find_int] and [`find_float`][eyepy.io.utils.find_float].

    Returns:
        A dictionary of the form {series_id(int): {folder_type(int): {fmt_string(str): [positions(int)]}}}
    """
    results = {
        **self.find_float(value, excluded_folders, slice_id, **kwargs),
        **self.find_int(round(value), excluded_folders, slice_id, **kwargs)
    }
    return results

inspect(recursive=False, ind_prefix='', tables=True)

Inspect the file hierarchy (contents) of the file.

Parameters:

Name Type Description Default
recursive bool

If True inspect lower level structures recursively.

False
ind_prefix str

Indentation for showing information from lower level structures.

''
tables bool

If True add markdown table overview of the contained folder types.

True
Source code in src/eyepy/io/he/e2e_reader.py
def inspect(self,
            recursive: bool = False,
            ind_prefix: str = '',
            tables: bool = True) -> str:
    """Inspect the file hierarchy (contents) of the file.

    Args:
        recursive: If True inspect lower level structures recursively.
        ind_prefix: Indentation for showing information from lower level structures.
        tables: If True add markdown table overview of the contained folder types.
    """
    return self.file_hierarchy.inspect(recursive, ind_prefix, tables)