A Python toolkit for multi-modal holographic systems and cellular analysis.
Requires Python 3.14+.
# With uv (recommended)
uv add iivs-lib
# With pip
pip install iivs-libThe [image] extra adds imagecodecs, needed only to decode the
LZW-compressed Koala Image/*.tif uint8 previews (uv add "iivs-lib[image]").
The [torch] extra adds PyTorch for iivs.dhm.analysis.pytorch — tensor-in /
tensor-out OPD / dry-mass twins with autograd (uv add "iivs-lib[torch]").
from iivs.dhm.data.phase import PhaseBinFolder, PhaseUnit
from iivs.dhm.analysis import DryMassCalculator
# Lazily open a phase acquisition (a folder of numbered .bin frames).
phase = PhaseBinFolder("scan/Phase/Float/Bin", target_unit=PhaseUnit.RADIANS)
phase.frame_shape # (H, W), shared across frames
img = phase[0] # first frame as a float32 array (decoded on access)
# Per-frame dry mass over a segmented cell:
calc = DryMassCalculator(pixel_size=phase.header.pixel_size)
mass_pg = calc.calc_from_phase(img, mask=cell_mask)Each package ships a detailed README in the source tree — the endpoints,
examples, and the inherited sequence interface:
hologram,
phase,
intensity,
data (overview
and timestamp),
analysis.
Readers, writers, and lazy sequences for Lyncée Tec Koala acquisition data (validated end-to-end against a real Koala acquisition — every format, the sequences, and the round trips between them).
hologram— uint8 holograms:.tifviaload_hologram_tif/save_hologram_tifwithHologramTifFolder/HologramTifList; a single multi-frame.rawviaHologramRawFile(a lazynp.memmap) andread_hologram_raw_header; header-less.npyframes viaHologramNpyFolder.phase— float32.binphase images:load_phase_bin/save_phase_bin/read_phase_bin_header, the typedPhaseBinHeaderandPhaseUnit, andconvert_phase_unit; folder/list sequencesPhaseBinFolder/PhaseBinList. The same quantitative phase from Koala'sFloat/Txtexport viaload_phase_txt,PhaseTxtFolder/PhaseTxtList. The uint8Image/*.tifdisplay previews (not quantitative) viaPhaseTifFolder/PhaseTifList. Header-less.npyframes viaPhaseNpyFolder(pixel_size/unit/height_scalepassed to the constructor;numpy.load, pickle disabled).intensity— float32.binintensity reconstructions (exported alongside phase):load_intensity_bin/save_intensity_bin/read_intensity_bin_header, the typedIntensityBinHeader, and folder/list sequencesIntensityBinFolder/IntensityBinList; plus theFloat/Txttwinsload_intensity_txt,IntensityTxtFolder/IntensityTxtList, the uint8Image/*.tifpreviewsIntensityTifFolder/IntensityTifList, and header-less.npyframes viaIntensityNpyFolder(pixel_sizepassed in). The phase and intensity.binformats share thecommon.KoalaBinHeaderbase.timestamp— per-frame acquisition timing: theTimestamprecord,TimestampsTxtFile(Koalatimestamps.txt), andTimestampsFixedFPS(synthesized from a frame rate).
Every sequence is a kaparoo.data.sequences.DataSequence, so it indexes,
slices, and iterates lazily; same-shape sources also expose frame_shape by
mixing in common.FrameShapedMixin (so a uniform source is its
<Modality>FloatSequence / <Modality>ImageSequence plus that mixin). For
phase and intensity the quantitative float32 sources are
<Modality>FloatSequence and the uint8 Image/*.tif previews are
<Modality>ImageSequence, both under the <Modality>Sequence base.
Numbered-folder sequences share the common.SequentialFileFolder
discovery/validation base, and validate their arrays via
common.validate_float32_image / validate_uint8_image. These cross-modality
building blocks live in iivs.dhm.data.common.
Physical quantities derived from phase, each via an engine object that precomputes its conversion factor (with one-shot function conveniences):
opd— optical path difference (OPD = phase * wavelength / (2*pi), in nm).OPDConverter(convert_to_opd/convert_to_phase, scaleopd_scale);phase_to_opd/opd_to_phase.drymass— dry mass (pg) via the Barer relation.DryMassCalculator(calc_from_opd/calc_from_phaseover a background-corrected, optionally masked map; scaledrymass_scale);calc_drymass/calc_drymass_from_phase.
The convert_* / calc_* methods operate on NumPy arrays. Install the
iivs-lib[torch] extra for iivs.dhm.analysis.pytorch — tensor-in / tensor-out
twins that keep the input tensor's device, dtype, and autograd graph (the
calibration scalars are shared with the NumPy engines):
from iivs.dhm.analysis.pytorch.opd import phase_to_opd
from iivs.dhm.analysis.pytorch.drymass import calc_drymass_from_phase
opd = phase_to_opd(phase, wavelength=666e-9) # Tensor (CPU/GPU), grad kept
mass = calc_drymass_from_phase(phase, pixel_size=px, mask=cell) # 0-dim Tensor, grad keptOr, without the dependency, multiply by the cached scale factors (plain floats) with native ops yourself:
opd = phase * conv.opd_scale # phase: Tensor -> OPD (nm), grad kept
mass = opd[mask].sum() * calc.drymass_scale # OPD -> dry mass (pg), grad keptSee TODO.md for tracked open items.
See CHANGELOG.md for the version history.
The file formats read and written by iivs.dhm.data are
Lyncée Tec's proprietary Koala formats. The .bin
format — Koala's float32 binary container, shared by the phase and intensity
reconstructions — was cross-checked against their reference implementation,
pyKoalaUtils (MIT). iivs-lib is
an independent reimplementation and contains no code from it.
This project is distributed under the terms of the MIT license.