Description
I think it would be very helpful if TIFFWriter.write() added the correct metadata to the TIFF Files for at least the X and Y resolutions, which I observe to be present in other datasets (https://www.morphosource.org/concern/media/000905028?locale=en as an example).
This data is available in ImageData.geometry (an ImageGeometry instance), so could be used without cost.
Additionally it would be nice to optionally add a JSON or similar sidecar file to the output with the full ImageGeometry, i.e. writer.write(sidecar="json") would dump a JSON representation of the ImageGeometry next to the TIFF stack.
Aside
As an aside: from what I can tell the NikonDataReader doesn't read the distance units (or at least my AcquisitionGeometry ends up reporting distance_units="distance", though I think maybe distance_units is not suppose to be a unit, but rather a quantity (length, pixel, angle))
In any case, it would be neat if the unit data from NikonDataReader could be propagated throughout a reconstruction pipeline without manually keeping track of it.
Current workaround
I currently create a dataclass:
@dataclass(frozen=True, slots=True)
class ReconstructionGeometry:
voxel_num_x: int
voxel_num_y: int
voxel_num_z: int
voxel_size_x_m: float
voxel_size_y_m: float
voxel_size_z_m: float
center_x_m: float
center_y_m: float
center_z_m: float
@classmethod
def from_cil_image_geometry(
cls, ig: ImageGeometry, physical_unit_scale_to_m: float = 1.0
) -> Self:
return cls(
voxel_num_x=ig.voxel_num_x,
voxel_num_y=ig.voxel_num_y,
voxel_num_z=ig.voxel_num_z,
voxel_size_x_m=ig.voxel_size_x * physical_unit_scale_to_m,
voxel_size_y_m=ig.voxel_size_y * physical_unit_scale_to_m,
voxel_size_z_m=ig.voxel_size_z * physical_unit_scale_to_m,
center_x_m=ig.center_x * physical_unit_scale_to_m,
center_y_m=ig.center_y * physical_unit_scale_to_m,
center_z_m=ig.center_z * physical_unit_scale_to_m,
)
def save_as_json(self, path: str | Path) -> None:
path = Path(path)
with path.open("w") as f:
json.dump(asdict(self), f, indent=4)
Which I then construct with physical_unit_scale_to_m=1e-3 since my Nikon data is in millimeters. I then save the sidecar after doing writer.write().
Environment
import cil, sys
print(cil.version.version, cil.version.commit_hash, sys.version, sys.platform)
> 26.0.0 3.13.15 | packaged by conda-forge | (main, Aug 10 2026, 13:05:01) [GCC 14.4.0] linux
Description
I think it would be very helpful if
TIFFWriter.write()added the correct metadata to the TIFF Files for at least the X and Y resolutions, which I observe to be present in other datasets (https://www.morphosource.org/concern/media/000905028?locale=en as an example).This data is available in
ImageData.geometry(anImageGeometryinstance), so could be used without cost.Additionally it would be nice to optionally add a JSON or similar sidecar file to the output with the full ImageGeometry, i.e.
writer.write(sidecar="json")would dump a JSON representation of the ImageGeometry next to the TIFF stack.Aside
As an aside: from what I can tell the
NikonDataReaderdoesn't read the distance units (or at least myAcquisitionGeometryends up reportingdistance_units="distance", though I think maybedistance_unitsis not suppose to be a unit, but rather a quantity (length, pixel, angle))In any case, it would be neat if the unit data from
NikonDataReadercould be propagated throughout a reconstruction pipeline without manually keeping track of it.Current workaround
I currently create a dataclass:
Which I then construct with
physical_unit_scale_to_m=1e-3since my Nikon data is in millimeters. I then save the sidecar after doingwriter.write().Environment