Skip to content

eyepy.io.he.e2e_format

BscanAdapter(*args, **kwargs)

Bases: Adapter

Source code in src/eyepy/io/he/e2e_format.py
def __init__(self, *args: t.Any, **kwargs: t.Any):
    super().__init__(*args, **kwargs)
    self.LUT = self._make_LUT()
    self.inv_LUT = self._make_inv_LUT()

Chunk(chunk_header=csfield(header_format, doc='Each chunk refers to the start position of the previous chunk (`prev` field)'), folders=csfield(cs.Array(cs.this.chunk_header.num_entries, folderheader_format), doc='In the data we have seen each chunk has 512 folders with headers of size 44'), jump=csfield(cs.Seek(cs.this.folders[-1].start + cs.this.folders[-1].size + datacontainer_format.header.sizeof()))) dataclass

Bases: DataclassMixin

Data chunk.

Size: variable

Notes: Every chunk has a header similar to the file header. A chunk then holds the headers of all contained folders sequentially, followed by data containers, that are referenced by the folder headers. A chunk can contain folders with data of different patients, studies, series, slices and types. Each folder contains data for a single (patient, study, series, slice, type) combination which is given in the folder header as well as the data container header. For the last chunk to have 512 folders, empty folders of type=0 are appended.

ContainerHeader(magic3=csfield(cs.PaddedString(12, 'ascii')), unknown0=csfield(cs.Int32ul), header_pos=csfield(cs.Int32ul, doc='Position of the header'), pos=csfield(cs.Int32ul, doc='Position of the data'), size=csfield(cs.Int32ul, doc='Size of the container'), unknown1=csfield(cs.Int32ul, doc="Always 0 (b'\\x00\\x00\\x00\\x00')? At least in our data"), patient_id=csfield(cs.Int32sl, doc='Patient ID'), study_id=csfield(cs.Int32sl, doc='Study ID'), series_id=csfield(cs.Int32sl, doc='Series ID'), slice_id=csfield(cs.Int32sl, doc='Slice ID, has to be divided by 2 to get the correct slice number'), ind=csfield(cs.Int16ul, doc="Takes only values 65333, 0 and 1 (b'ÿÿ', b'\x00\x00', b'\x01\x00') at least in our data - 0 for enface and 1 for bscan for image containers"), unknown2=csfield(cs.Int16ul, doc="Always 0 (b'\x00\x00')? At least in our data"), type=csfield(TEnum(cs.Int32ul, TypesEnum), doc='Type ID of the contained data'), unknown3=csfield(cs.Int32ul, doc='Large integer that increases in steps of folder header size (=44) Maybe the folder header position in HEYEX database not in this file? - Possibly related to the folder header unknown4 value')) dataclass

Bases: DataclassMixin

Container header data.

Size: 60 bytes

Notes:

DataContainer(header=csfield(containerheader_format), item=csfield(item_switch, doc='There are many kinds of DataItems indicated by different type IDs in the folder/container header')) dataclass

Bases: DataclassMixin

Data container.

Size: variable

Notes:

E2EFormat(version=csfield(version_format), header=csfield(header_format, doc='The `prev` field in the main header refers to the start position of the last chunk'), chunks=csfield(cs.GreedyRange(chunk_format), doc='The number and size of the chunks depends on the data')) dataclass

Bases: DataclassMixin

E2E file format.

Size: variable

Notes: An E2E file starts with a version structure, followed by a header structure. After that the data comes in chunks of 512 folders.

FolderHeader(pos=csfield(cs.Int32ul, doc='Position of the folder (In a chunk all 512 folder headers are stored sequentially, refering to the data that follows after this header block)'), start=csfield(cs.Int32ul, doc='Start of the data container, after the header block in the chunk'), size=csfield(cs.Int32ul, doc='Size of the data container'), unknown0=csfield(cs.Int32ul, doc="Always 0 (b'\x00\x00')? At leat in our data"), patient_id=csfield(cs.Int32sl, doc='Patient ID'), study_id=csfield(cs.Int32sl, doc='Study ID'), series_id=csfield(cs.Int32sl, doc='Series ID'), slice_id=csfield(cs.Int32sl, doc='Slice ID, has to be divided by 2 to get the correct slice number'), ind=csfield(cs.Int16ul, doc='0 for enface and 1 for bscan for image containers'), unknown1=csfield(cs.Int16ul), type=csfield(TEnum(cs.Int32ul, TypesEnum), doc='Type ID of the contained data'), unknown3=csfield(cs.Int32ul, doc='Large integer possibly related to data_container.unknown5. Maybe the position in HEYEX DB?')) dataclass

Bases: DataclassMixin

Folder header.

Size: 44 bytes

Notes:

Header(magic2=csfield(cs.PaddedString(12, 'ascii')), version=csfield(cs.Int32ul), unknown0=csfield(cs.Array(10, cs.Int16ul)), num_entries=csfield(cs.Int32ul, doc='Number of entries in the chunk'), current=csfield(cs.Int32ul, doc='Position of the current chunk'), prev=csfield(cs.Int32ul, doc='Position of the previous chunk'), unknown1=csfield(cs.Int32ul)) dataclass

Bases: DataclassMixin

Chunk header.

Size: 52 bytes

Notes:

LateralityEnum

Bases: EnumBase

Enum for laterality of eye.

The laterality is stored as single character in ASCII code.

Type10004(unknown0=csfield(cs.Int32ul), size_y=csfield(cs.Int32ul, doc='Bscan height'), size_x=csfield(cs.Int32ul, doc='Bscan width'), start_x=csfield(cs.Float32l, doc='Start X coordinate of Bscan'), start_y=csfield(cs.Float32l, doc='Start Y coordinate of Bscan'), end_x=csfield(cs.Float32l, doc='End X coordinate of Bscan'), end_y=csfield(cs.Float32l, doc='End Y coordinate of Bscan'), zero1=csfield(cs.Int32ul), unknown1=csfield(cs.Float32l), scale_y=csfield(cs.Float32l, doc='Scale of Bscan y-axis (height)'), unknown2=csfield(cs.Float32l), zero2=csfield(cs.Int32ul), unknown3=csfield(cs.Array(2, cs.Float32l)), zero3=csfield(cs.Int32ul), imgSizeWidth=csfield(cs.Int32ul, doc='This might differ from size_x, the actual meaning of this value is unclear, maybe you can compute the x-axis scale from this value.'), n_bscans=csfield(cs.Int32ul, doc='Number of Bscans in the respective volume'), aktImage=csfield(cs.Int32ul, doc='Index of the current Bscan in the volume'), scan_pattern=csfield(cs.Int32ul, doc='Scan pattern of the volume. <br>**Does this corresponds to the scan pattterns in VOL and XML export?**'), center_x=csfield(cs.Float32l, doc='Exactly the average of start_x and end_x.'), center_y=csfield(cs.Float32l, doc='Exactly the average of start_y and end_y.'), unknown4=csfield(cs.Int32ul, doc='Maybe the UTC bias?'), acquisitionTime=csfield(DateTime, doc='Acquisition time of Bscan'), numAve=csfield(cs.Int32ul, doc='Number of averages according to LibE2E<br>**Not coherent with XML export**'), quality=csfield(cs.Float32l, doc='Quality according to LibE2E<br>**Does not match the quality value in the XML export which is an integer compared to a float here with value 0.84 for a complete volume. Maybe this is the focus length, at least it is similar to the value given in the XML (0.87)**'), unknown5=csfield(cs.Float32l)) dataclass

Bases: DataclassMixin, TypeMixin

B-scan Metadata Metadata for a single B-scan.

Size: 428 bytes

Notes: The current Bscan-Meta structure builds on the implementation found in LibE2E.

Type10010(unknown=csfield(cs.Bytes(12)), n_bscans=csfield(cs.Int32ul)) dataclass

Bases: DataclassMixin, TypeMixin

Type 10010.

Size: variable

Notes:

Type10012(unknown0=csfield(cs.Bytes(28)), value_1=csfield(cs.Float32l), unknown1=csfield(cs.Bytes(1)), value_2=csfield(cs.Float32l)) dataclass

Bases: DataclassMixin, TypeMixin

Type 10012.

Size: variable

Notes:

Type10013(unknown=csfield(cs.Bytes(12)), n_bscans=csfield(cs.Int32ul)) dataclass

Bases: DataclassMixin, TypeMixin

Type 10013.

Size: variable

Notes:

Type10019(unknown0=csfield(cs.Int32ul), id=csfield(cs.Int32ul, doc='ID of the layer'), unknown1=csfield(cs.Int32ul), width=csfield(cs.Int32ul, doc='Width of the layer'), data=csfield(Segmentation, doc='Layer annotation data')) dataclass

Bases: DataclassMixin, TypeMixin

Layer Annotation Stores one layer for one Bscan.

Size: variable

Notes:

Type10025(unknown=csfield(cs.Bytes(24)), windate=csfield(DateTime), transform=csfield(cs.Array(6, cs.Float32l), doc='Parameters of affine transformation')) dataclass

Bases: DataclassMixin, TypeMixin

Localizer Metadata.

Size: 100 bytes

Notes:

Type1073741824(size=csfield(cs.Int32ul, doc='Size of the data'), type=csfield(cs.Int32ul, doc='Type of the data'), n_values=csfield(cs.Int32ul, doc='Number of values in the data'), height=csfield(cs.Int32ul, doc='Height of the image'), width=csfield(cs.Int32ul, doc='Width of the image'), data=csfield(cs.Switch(cs.this.type, {33620481: LocalizerNIR, 35652097: Bscan}, default=cs.Bytes(cs.this.size)), doc='Image data')) dataclass

Bases: DataclassMixin, TypeMixin

Image data Stores various kinds of images.

Size: variable

Notes: Different kinds of images are stored in this structure. Currently we know the following types:

  • 33620481: LocalizerNIR (int8u)
  • 35652097: Bscan (float16u)

The custom float16u used to store the Bscan data, has no sign, a 6-bit exponent und 10-bit mantissa.

Type11(unknown=csfield(cs.Bytes(14)), laterality=csfield(TEnum(cs.Int8ul, LateralityEnum))) dataclass

Bases: DataclassMixin, TypeMixin

Type 11.

Size: 27 bytes

Notes: We don't know what this data is used for, only that the 15th byte indicates the laterality of the eye.

Type17(n_strings=csfield(cs.Int32ul), string_size=csfield(cs.Int32ul), text=csfield(cs.Array(cs.this.n_strings, cs.PaddedString(cs.this.string_size, 'utf16')))) dataclass

Bases: DataclassMixin, TypeMixin

Diagnose data.

Size: variable

Notes:

Type3(unknown=csfield(cs.Bytes(4)), laterality=csfield(TEnum(cs.Int8ul, LateralityEnum))) dataclass

Bases: DataclassMixin, TypeMixin

Type 3.

Size: 96 bytes

Notes: We don't know what this data is used for, only that the 5th byte indicates the laterality of the eye.

Type5(unknown=csfield(cs.Bytes(2)), laterality=csfield(TEnum(cs.Int8ul, LateralityEnum))) dataclass

Bases: DataclassMixin, TypeMixin

Type 5.

Size: 59 bytes

Notes: We don't know what this data is used for, only that the 3rd byte indicates the laterality of the eye.

Type59(unknown=csfield(cs.Bytes(14)), laterality=csfield(TEnum(cs.Int8ul, LateralityEnum))) dataclass

Bases: DataclassMixin, TypeMixin

Type 59.

Size: 27 bytes

Notes: We don't know what this data is used for, only that the 14th byte indicates the laterality of the eye.

Type7(eye_side=csfield(TEnum(cs.Int8ul, LateralityEnum)), c_curve_mm=csfield(cs.Float64l), refraction_dpt=csfield(cs.Float64l), cylinder_dpt=csfield(cs.Float64l), axis_deg=csfield(cs.Float64l), pupil_size_mm=csfield(cs.Float64l), iop_mmHg=csfield(cs.Float64l), vfield_mean=csfield(cs.Float64l), vfield_var=csfield(cs.Float64l), corrective_lens=csfield(cs.Int16ul), rest=csfield(cs.Bytes(1))) dataclass

Bases: DataclassMixin, TypeMixin

Measurements Global measurements of the eye.

Size: 68 bytes

Notes:

Type9(firstname=csfield(cs.PaddedString(31, 'ascii')), surname=csfield(cs.PaddedString(66, 'ascii')), birthdate=csfield(cs.Int32ul), sex=csfield(cs.PaddedString(1, 'ascii')), patient_id=csfield(cs.PaddedString(25, 'ascii'))) dataclass

Bases: DataclassMixin, TypeMixin

Patient data Personal data of the patient.

Size: 131 bytes

Notes:

Type9000(n_strings=csfield(cs.Int32ul), string_size=csfield(cs.Int32ul), text=csfield(cs.Array(cs.this.n_strings, cs.PaddedString(cs.this.string_size, 'utf16')))) dataclass

Bases: DataclassMixin, TypeMixin

Studyname Name of the study/visit.

Size: 264 bytes

Notes:

Type9001(n_strings=csfield(cs.Int32ul), string_size=csfield(cs.Int32ul), text=csfield(cs.Array(cs.this.n_strings, cs.PaddedString(cs.this.string_size, 'utf16')))) dataclass

Bases: DataclassMixin, TypeMixin

Device Name of the used device.

Size: 776 bytes

Notes:

Type9005(n_strings=csfield(cs.Int32ul), string_size=csfield(cs.Int32ul), text=csfield(cs.Array(cs.this.n_strings, cs.PaddedString(cs.this.string_size, 'utf16')))) dataclass

Bases: DataclassMixin, TypeMixin

Examined structure Name of the examined structure.

Size: 264 bytes

Notes:

Type9006(n_strings=csfield(cs.Int32ul), string_size=csfield(cs.Int32ul), text=csfield(cs.Array(cs.this.n_strings, cs.PaddedString(cs.this.string_size, 'utf16')))) dataclass

Bases: DataclassMixin, TypeMixin

Scan pattern Bscan pattern used for the aquisition.

Size: 520 bytes

Notes:

Type9007(n_strings=csfield(cs.Int32ul), string_size=csfield(cs.Int32ul), text=csfield(cs.Array(cs.this.n_strings, cs.PaddedString(cs.this.string_size, 'utf16')))) dataclass

Bases: DataclassMixin, TypeMixin

Enface Modality Modality of the enface (eg IR)

Size: 520 bytes

Notes:

Type9008(n_strings=csfield(cs.Int32ul), string_size=csfield(cs.Int32ul), text=csfield(cs.Array(cs.this.n_strings, cs.PaddedString(cs.this.string_size, 'utf16')))) dataclass

Bases: DataclassMixin, TypeMixin

OCT Modality Modality of the OCT (eg OCT)

Size: 520 bytes

Notes:

TypesEnum

Bases: EnumBase

Enum for types of data stored in .e2e files.

Version(name=csfield(cs.PaddedString(12, 'ascii'), doc='Name of the version'), version=csfield(cs.Int32ul, doc='Verion of the file'), unknown0=csfield(cs.Array(10, cs.Int16ul))) dataclass

Bases: DataclassMixin

Version header.

Size: 36 bytes

Notes: