Skip to content

Commit 5611cb9

Browse files
authored
Merge branch 'devel' into bdv_update_library
2 parents 451f84c + 5e72d55 commit 5611cb9

12 files changed

Lines changed: 349 additions & 100 deletions

File tree

.vscode/settings.json

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,35 @@
1111
}
1212
},
1313
"cSpell.words": [
14-
"Prefs"
14+
"acitt",
15+
"bdvp",
16+
"biop",
17+
"imageplus",
18+
"imglib",
19+
"interestpoint",
20+
"intermodes",
21+
"Kheops",
22+
"micrometa",
23+
"multiresolution",
24+
"otsu",
25+
"pathtools",
26+
"Prefs",
27+
"PTBIOP",
28+
"PYENV",
29+
"pylint",
30+
"ransac",
31+
"renyi",
32+
"repartitions",
33+
"RETVAL",
34+
"scijava",
35+
"shanbhag",
36+
"sjlogging",
37+
"spimdata",
38+
"strtools",
39+
"subfolders",
40+
"subsampling",
41+
"trackmate",
42+
"virtualenv",
43+
"virtualfish"
1544
],
1645
}

poetry.lock

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

poetry.lock.md

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ version = "0.0.0"
2020
# - or: python = ">=3.10"
2121

2222
[tool.poetry.dependencies]
23-
imcf-fiji-mocks = ">=0.10.0"
23+
imcf-fiji-mocks = ">=0.13.0"
2424
python = ">=2.7"
2525
python-micrometa = "^15.2.2"
2626
sjlogging = ">=0.5.2"
@@ -53,4 +53,4 @@ ignore = [
5353
]
5454

5555
[tool.ruff.lint.pydocstyle]
56-
convention = "numpy"
56+
convention = "numpy"

src/imcflibs/imagej/bdv.py

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
FuseBigStitcherDatasetIntoOMETiffCommand,
1818
)
1919
from ij import IJ
20+
from java.io import File, FileInputStream, InputStreamReader
21+
from javax.xml.parsers import DocumentBuilderFactory
22+
from org.xml.sax import InputSource
2023

2124
from .. import pathtools
2225
from ..log import LOG as log
@@ -731,6 +734,22 @@ def get_processing_settings(dimension, selection, value, range_end):
731734
tuple of str
732735
processing_option, dimension_select
733736
"""
737+
processing_option = dimension_select = ""
738+
739+
# Validate inputs according to the function docstring
740+
valid_dimensions = ("angle", "channel", "illumination", "tile", "timepoint")
741+
if dimension not in valid_dimensions:
742+
raise ValueError(
743+
"Invalid dimension '%s', expected one of: %s"
744+
% (dimension, ", ".join(valid_dimensions))
745+
)
746+
747+
valid_selections = ("single", "multiple", "range")
748+
if selection not in valid_selections:
749+
raise ValueError(
750+
"Invalid selection '%s', expected one of: %s"
751+
% (selection, ", ".join(valid_selections))
752+
)
734753

735754
if selection == "single":
736755
processing_option = SINGLE % dimension
@@ -1085,7 +1104,7 @@ def phase_correlation_pairwise_shifts_calculation(
10851104
project_path : str
10861105
Full path to the `.xml` file.
10871106
processing_opts : imcflibs.imagej.bdv.ProcessingOptions, optional
1088-
The `ProcessingOptinos` object defining parameters for the run. Will
1107+
The `ProcessingOptions` object defining parameters for the run. Will
10891108
fall back to the defaults defined in the corresponding class if the
10901109
parameter is `None` or skipped.
10911110
downsampling_xyz : list of int, optional
@@ -1204,7 +1223,7 @@ def optimize_and_apply_shifts(
12041223
project_path : str
12051224
Path to the `.xml` on which to optimize and apply the shifts.
12061225
processing_opts : imcflibs.imagej.bdv.ProcessingOptions, optional
1207-
The `ProcessingOptinos` object defining parameters for the run. Will
1226+
The `ProcessingOptions` object defining parameters for the run. Will
12081227
fall back to the defaults defined in the corresponding class if the
12091228
parameter is `None` or skipped.
12101229
relative_error : float, optional
@@ -1355,11 +1374,13 @@ def interest_points_registration(
13551374
+ "transformation=Affine "
13561375
+ "regularize_model "
13571376
+ "model_to_regularize_with=Affine "
1358-
+ "lamba=0.10 "
1377+
+ "lambda=0.10 "
13591378
+ "number_of_neighbors=3 "
13601379
+ "redundancy=1 "
13611380
+ "significance=3 "
1381+
+ "search_radius=100 "
13621382
+ "allowed_error_for_ransac=5 "
1383+
+ "inlier_factor=3 "
13631384
+ "ransac_iterations=Normal "
13641385
+ "global_optimization_strategy=["
13651386
+ "Two-Round: Handle unconnected tiles, "
@@ -1377,7 +1398,7 @@ def interest_points_registration(
13771398
def duplicate_transformations(
13781399
project_path,
13791400
transformation_type="channel",
1380-
channel_source=None,
1401+
channel_source=0,
13811402
tile_source=None,
13821403
transformation_to_use="[Replace all transformations]",
13831404
):
@@ -1394,7 +1415,7 @@ def duplicate_transformations(
13941415
Transformation mode, one of `channel` (to propagate from one channel to
13951416
all others) and `tiles` (to propagate from one tile to all others).
13961417
channel_source : int, optional
1397-
Reference channel nummber (starting at 1), by default None.
1418+
Reference channel number (starting at 1), by default None.
13981419
tile_source : int, optional
13991420
Reference tile, by default None.
14001421
transformation_to_use : str, optional
@@ -1410,13 +1431,16 @@ def duplicate_transformations(
14101431
tile_apply = ""
14111432
tile_process = ""
14121433

1413-
chnl_apply = ""
1414-
chnl_process = ""
1434+
ch_apply = ""
1435+
ch_process = ""
14151436

14161437
if transformation_type == "channel":
14171438
apply = "[One channel to other channels]"
14181439
target = "[All Channels]"
1419-
source = str(channel_source - 1)
1440+
if channel_source > 0:
1441+
source = str(channel_source - 1)
1442+
else:
1443+
source = "0"
14201444
if tile_source:
14211445
tile_apply = "apply_to_tile=[Single tile (Select from List)] "
14221446
tile_process = "processing_tile=[tile " + str(tile_source) + "] "
@@ -1426,15 +1450,13 @@ def duplicate_transformations(
14261450
apply = "[One tile to other tiles]"
14271451
target = "[All Tiles]"
14281452
source = str(tile_source)
1429-
if channel_source:
1430-
chnl_apply = "apply_to_channel=[Single channel (Select from List)] "
1431-
chnl_process = (
1432-
"processing_channel=[channel " + str(channel_source - 1) + "] "
1433-
)
1453+
if channel_source > 0:
1454+
ch_apply = "apply_to_channel=[Single channel (Select from List)] "
1455+
ch_process = "processing_channel=[channel " + str(channel_source - 1) + "] "
14341456
else:
1435-
chnl_apply = "apply_to_channel=[All channels] "
1457+
ch_apply = "apply_to_channel=[All channels] "
14361458
else:
1437-
sys.exit("Issue with transformation duplication")
1459+
raise ValueError("Invalid transformation type: %s" % transformation_type)
14381460

14391461
options = (
14401462
"apply="
@@ -1447,8 +1469,8 @@ def duplicate_transformations(
14471469
+ "apply_to_illumination=[All illuminations] "
14481470
+ tile_apply
14491471
+ tile_process
1450-
+ chnl_apply
1451-
+ chnl_process
1472+
+ ch_apply
1473+
+ ch_process
14521474
+ "apply_to_timepoint=[All Timepoints] "
14531475
+ "source="
14541476
+ source
@@ -1493,7 +1515,7 @@ def fuse_dataset(
14931515
project_path : str
14941516
Path to the `.xml` on which to run the fusion.
14951517
processing_opts : imcflibs.imagej.bdv.ProcessingOptions, optional
1496-
The `ProcessingOptinos` object defining parameters for the run. Will
1518+
The `ProcessingOptions` object defining parameters for the run. Will
14971519
fall back to the defaults defined in the corresponding class if the
14981520
parameter is `None` or skipped.
14991521
result_path : str, optional

src/imcflibs/imagej/bioformats.py

Lines changed: 46 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,31 @@ def export_using_orig_name(imp, path, orig_name, tag, suffix, overwrite=False):
352352
return out_file
353353

354354

355+
def get_reader(path_to_file, setFlattenedResolutions=False):
356+
"""Get a Bio-Formats ImageReader for the specified file.
357+
358+
Parameters
359+
----------
360+
path_to_file : str
361+
The full path to the image file.
362+
setFlattenedResolutions : bool, optional
363+
Whether to flatten resolutions in the ImageReader (default: False).
364+
365+
Returns
366+
-------
367+
ImageReader
368+
A configured ImageReader instance for the specified file.
369+
"""
370+
reader = ImageReader()
371+
ome_meta = MetadataTools.createOMEXMLMetadata()
372+
reader.setMetadataStore(ome_meta)
373+
m = DynamicMetadataOptions()
374+
m.setBoolean(ZeissCZIReader.ALLOW_AUTOSTITCHING_KEY, False)
375+
reader.setMetadataOptions(m)
376+
reader.setId(str(path_to_file))
377+
return reader, ome_meta
378+
379+
355380
def get_series_info_from_ome_metadata(path_to_file, skip_labels=False):
356381
"""Get the Bio-Formats series information from a file on disk.
357382
@@ -378,44 +403,31 @@ def get_series_info_from_ome_metadata(path_to_file, skip_labels=False):
378403
>>> count, indices = get_series_info_from_ome_metadata("image.nd2", skip_labels=True)
379404
"""
380405

406+
reader, ome_meta = get_reader(path_to_file, skip_labels)
407+
series_count = reader.getSeriesCount()
381408
if not skip_labels:
382-
reader = ImageReader()
383-
reader.setFlattenedResolutions(False)
384-
ome_meta = MetadataTools.createOMEXMLMetadata()
385-
reader.setMetadataStore(ome_meta)
386-
reader.setId(path_to_file)
387-
series_count = reader.getSeriesCount()
388-
389-
reader.close()
409+
# If we are not skipping labels, return the full range
390410
return series_count, range(series_count)
391411

392-
else:
393-
reader = ImageReader()
394-
# reader.setFlattenedResolutions(True)
395-
ome_meta = MetadataTools.createOMEXMLMetadata()
396-
reader.setMetadataStore(ome_meta)
397-
reader.setId(path_to_file)
398-
series_count = reader.getSeriesCount()
399-
400-
series_ids = []
401-
series_names = []
402-
x = 0
403-
y = 0
404-
for i in range(series_count):
405-
reader.setSeries(i)
412+
series_ids = []
413+
series_names = []
414+
x = 0
415+
y = 0
416+
for i in range(series_count):
417+
reader.setSeries(i)
406418

407-
if reader.getSizeX() > x and reader.getSizeY() > y:
408-
name = ome_meta.getImageName(i)
419+
if reader.getSizeX() > x and reader.getSizeY() > y:
420+
name = ome_meta.getImageName(i)
409421

410-
if name not in ["label image", "macro image"]:
411-
series_ids.append(i)
412-
series_names.append(name)
422+
if name not in ["label image", "macro image"]:
423+
series_ids.append(i)
424+
series_names.append(name)
413425

414-
x = reader.getSizeX()
415-
y = reader.getSizeY()
426+
x = reader.getSizeX()
427+
y = reader.getSizeY()
416428

417-
print(series_names)
418-
return len(series_ids), series_ids
429+
print(series_names)
430+
return len(series_ids), series_ids
419431

420432

421433
def write_bf_memoryfile(path_to_file):
@@ -452,10 +464,7 @@ def get_metadata_from_file(path_to_image):
452464
An instance of `imcflibs.imagej.bioformats.ImageMetadata` containing the extracted metadata.
453465
"""
454466

455-
reader = ImageReader()
456-
ome_meta = MetadataTools.createOMEXMLMetadata()
457-
reader.setMetadataStore(ome_meta)
458-
reader.setId(str(path_to_image))
467+
reader, ome_meta = get_reader(path_to_image)
459468

460469
metadata = ImageMetadata(
461470
unit_width=ome_meta.getPixelsPhysicalSizeX(0).value(),
@@ -507,11 +516,7 @@ def get_stage_coords(filenames):
507516
max_phys_size_z = 0.0
508517

509518
for counter, image in enumerate(filenames):
510-
reader = ImageReader()
511-
reader.setFlattenedResolutions(False)
512-
ome_meta = MetadataTools.createOMEXMLMetadata()
513-
reader.setMetadataStore(ome_meta)
514-
reader.setId(str(image))
519+
reader, ome_meta = get_reader(image)
515520
series_count = reader.getSeriesCount()
516521

517522
# Process only the first image to get values not dependent on series
@@ -569,8 +574,7 @@ def get_stage_coords(filenames):
569574
if series_count > 1 and not str(image).endswith(".vsi"):
570575
series_names.append(ome_meta.getImageName(series))
571576
else:
572-
series_names.append(str(image))
573-
577+
series_names.append(os.path.basename(str(image)))
574578
current_position_x = getattr(
575579
ome_meta.getPlanePositionX(series, 0), "value", lambda: 0
576580
)()

0 commit comments

Comments
 (0)