Skip to content

io

FormatKeys

Bases: str, Enum

Source code in src/jvol/io.py
15
16
17
18
19
20
21
22
23
24
25
class FormatKeys(str, enum.Enum):
    IJK_TO_RAS = "ijk_to_ras"
    QUANTIZATION_BLOCK = "quantization_block"
    DC_RLE_VALUES = "dc_rle_values"
    DC_RLE_COUNTS = "dc_rle_counts"
    AC_RLE_VALUES = "ac_rle_values"
    AC_RLE_COUNTS = "ac_rle_counts"
    DTYPE = "dtype"
    INTERCEPT = "intercept"
    SLOPE = "slope"
    SHAPE = "shape"

AC_RLE_COUNTS = 'ac_rle_counts' class-attribute instance-attribute

AC_RLE_VALUES = 'ac_rle_values' class-attribute instance-attribute

DC_RLE_COUNTS = 'dc_rle_counts' class-attribute instance-attribute

DC_RLE_VALUES = 'dc_rle_values' class-attribute instance-attribute

DTYPE = 'dtype' class-attribute instance-attribute

IJK_TO_RAS = 'ijk_to_ras' class-attribute instance-attribute

INTERCEPT = 'intercept' class-attribute instance-attribute

QUANTIZATION_BLOCK = 'quantization_block' class-attribute instance-attribute

SHAPE = 'shape' class-attribute instance-attribute

SLOPE = 'slope' class-attribute instance-attribute

fill_ijk_to_ras(ijk_to_ras)

Source code in src/jvol/io.py
118
119
120
def fill_ijk_to_ras(ijk_to_ras: npt.NDArray[np.float64]) -> npt.NDArray[np.float64]:
    last_row = [0, 0, 0, 1]
    return np.vstack((ijk_to_ras, last_row))

open_image(path)

Source code in src/jvol/io.py
28
29
30
def open_image(path: Path) -> tuple[np.ndarray, np.ndarray]:
    _open = open_jvol if path.suffix == ".jvol" else open_itk_image
    return _open(path)

open_itk_image(path)

Source code in src/jvol/io.py
45
46
47
48
49
def open_itk_image(path: Path) -> tuple[np.ndarray, np.ndarray]:
    image = itk.imread(path)
    array = itk.array_view_from_image(image).T
    ijk_to_ras = create_ijk_to_ras_from_itk_image(image)
    return array, ijk_to_ras

open_jvol(path)

Source code in src/jvol/io.py
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
def open_jvol(path: Path) -> tuple[np.ndarray, np.ndarray]:
    loaded = np.load(path)
    ijk_to_ras = fill_ijk_to_ras(loaded[FormatKeys.IJK_TO_RAS.value])
    quantization_block = loaded[FormatKeys.QUANTIZATION_BLOCK.value]
    array = decode_array(
        dc_rle_values=loaded[FormatKeys.DC_RLE_VALUES],
        dc_rle_counts=loaded[FormatKeys.DC_RLE_COUNTS],
        ac_rle_values=loaded[FormatKeys.AC_RLE_VALUES],
        ac_rle_counts=loaded[FormatKeys.AC_RLE_COUNTS],
        quantization_block=quantization_block,
        target_shape=loaded[FormatKeys.SHAPE],
        intercept=loaded[FormatKeys.INTERCEPT],
        slope=loaded[FormatKeys.SLOPE],
        dtype=loaded[FormatKeys.DTYPE].dtype,
    )
    return array, ijk_to_ras

save_image(array, ijk_to_ras, path, **kwargs)

Source code in src/jvol/io.py
33
34
35
36
37
38
39
40
41
42
def save_image(
    array: np.ndarray,
    ijk_to_ras: np.ndarray,
    path: Path,
    **kwargs: int,
) -> None:
    if path.suffix == ".jvol":
        save_jvol(array, ijk_to_ras, path, **kwargs)
    else:
        save_itk_image(array, ijk_to_ras, path)

save_itk_image(array, ijk_to_ras, path)

Source code in src/jvol/io.py
52
53
54
55
56
57
58
def save_itk_image(array: np.ndarray, ijk_to_ras: np.ndarray, path: Path) -> None:
    image = itk.image_view_from_array(array.T.copy())
    origin, rotation, spacing = get_itk_metadata_from_ijk_to_ras(ijk_to_ras)
    image.SetOrigin(origin)
    image.SetDirection(rotation)
    image.SetSpacing(spacing)
    itk.imwrite(image, path)

save_jvol(array, ijk_to_ras, path, block_size=4, quality=60)

Source code in src/jvol/io.py
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
def save_jvol(
    array: np.ndarray,
    ijk_to_ras: np.ndarray,
    path: Path,
    block_size: int = 4,
    quality: int = 60,
) -> None:
    block_shape = block_size, block_size, block_size
    quantization_table = get_quantization_table(block_shape, quality)
    dtype = array.dtype
    intercept = array.min()
    slope = array.max() - intercept
    dc_rle_values, dc_rle_counts, ac_rle_values, ac_rle_counts = encode_array(
        array,
        quantization_table,
    )

    dc_rle_values = dc_rle_values.astype(np.min_scalar_type(dc_rle_values))
    dc_rle_counts = dc_rle_counts.astype(np.min_scalar_type(dc_rle_counts))
    ac_rle_values = ac_rle_values.astype(np.min_scalar_type(ac_rle_values))
    ac_rle_counts = ac_rle_counts.astype(np.min_scalar_type(ac_rle_counts))

    save_dict = {
        FormatKeys.IJK_TO_RAS.value: ijk_to_ras[:3],
        FormatKeys.QUANTIZATION_BLOCK.value: quantization_table,
        FormatKeys.DC_RLE_VALUES.value: dc_rle_values,
        FormatKeys.DC_RLE_COUNTS.value: dc_rle_counts,
        FormatKeys.AC_RLE_VALUES.value: ac_rle_values,
        FormatKeys.AC_RLE_COUNTS.value: ac_rle_counts,
        FormatKeys.DTYPE.value: np.empty((), dtype=dtype),
        FormatKeys.INTERCEPT.value: intercept,
        FormatKeys.SLOPE.value: slope,
        FormatKeys.SHAPE.value: np.array(array.shape, dtype=np.uint16),
    }

    with open(path, "wb") as f:
        np.savez_compressed(f, **save_dict)