11import multiprocessing as mp
22import os
33import re
4+ import xml .etree .ElementTree as ET
45
56from glob import glob
67from pathlib import Path
@@ -26,7 +27,7 @@ def _read_resolution_and_unit_flamingo(mdata_path):
2627 if resolution is None :
2728 raise RuntimeError
2829
29- unit = "um "
30+ unit = "micrometer "
3031
3132 # NOTE: The resolution for the flamingo system is isotropic.
3233 # So we can just return the plane spacing value to get it.
@@ -59,7 +60,7 @@ def _read_start_position_flamingo(path):
5960 return start_position
6061
6162
62- def read_metadata_flamingo (metadata_path , offset = None ):
63+ def read_metadata_flamingo (metadata_path , offset = None , parse_affine = False ):
6364 resolution , unit = None , None
6465
6566 resolution , unit = _read_resolution_and_unit_flamingo (metadata_path )
@@ -69,8 +70,9 @@ def _pos_to_trafo(pos):
6970 if offset is not None :
7071 pos -= offset
7172
72- # FIXME: dirty hack
73- # scale = 4
73+ # NOTE: the scale should be kept at 1.
74+ # This is only here for development purposes,
75+ # to support handling downsampled datasets.
7476 scale = 1
7577
7678 # The calibration: scale factors on the diagonals.
@@ -94,7 +96,14 @@ def _pos_to_trafo(pos):
9496 }
9597 return trafo
9698
97- transformation = _pos_to_trafo (start_position )
99+ if parse_affine :
100+ transformation = _pos_to_trafo (start_position )
101+ else :
102+ transformation = [
103+ 1.0 , 0.0 , 0.0 , 0.0 ,
104+ 0.0 , 1.0 , 0.0 , 0.0 ,
105+ 0.0 , 0.0 , 1.0 , 0.0 ,
106+ ]
98107 # We have to reverse the resolution because pybdv expects ZYX.
99108 return resolution [::- 1 ], unit , transformation
100109
@@ -184,6 +193,20 @@ def flamingo_filename_parser(file_path, name_mapping):
184193 return timepoint , attributes , attribute_id
185194
186195
196+ def _write_missing_views (out_path ):
197+ xml_path = Path (out_path ).with_suffix (".xml" )
198+ assert os .path .exists (xml_path )
199+
200+ tree = ET .parse (xml_path )
201+ root = tree .getroot ()
202+ seqdesc = root .find ("SequenceDescription" )
203+ ET .SubElement (seqdesc , "MissingViews" )
204+
205+ pybdv .metadata .indent_xml (root )
206+ tree = ET .ElementTree (root )
207+ tree .write (xml_path )
208+
209+
187210def convert_lightsheet_to_bdv (
188211 root : str ,
189212 out_path : str ,
@@ -286,7 +309,11 @@ def convert_lightsheet_to_bdv(
286309 unit = "pixel"
287310
288311 else : # We have metadata and read it.
289- resolution , unit , tile_transformation = read_metadata_flamingo (metadata_file , offset )
312+ # NOTE: we don't add the calibration transformation here, as this
313+ # leads to issues with the BigStitcher export.
314+ resolution , unit , tile_transformation = read_metadata_flamingo (
315+ metadata_file , offset , parse_affine = False
316+ )
290317
291318 print (f"Converting tp={ timepoint } , channel={ attributes ['channel' ]} , tile={ attributes ['tile' ]} " )
292319 try :
@@ -312,6 +339,14 @@ def convert_lightsheet_to_bdv(
312339 setup_id = setup_id ,
313340 )
314341
342+ # We don't need to add additional xml metadata if we convert to ome-zarr.
343+ if convert_to_ome_zarr :
344+ return
345+
346+ # Add an empty missing views field.
347+ # This is expected by BigStitcher.
348+ _write_missing_views (out_path )
349+
315350
316351# TODO expose more arguments via CLI.
317352def convert_lightsheet_to_bdv_cli ():
0 commit comments