forked from sohamazing/image-stitcher
-
Notifications
You must be signed in to change notification settings - Fork 0
/
parameters.py
108 lines (86 loc) · 3.65 KB
/
parameters.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
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
98
99
100
101
102
103
104
105
106
107
108
# parameters.py
from dataclasses import dataclass
from typing import Dict, Any
import json
import os
from datetime import datetime
@dataclass
class StitchingParameters:
"""Parameters for microscopy image stitching operations."""
# Required parameters
input_folder: str
# Output configuration
output_format: str = '.ome.zarr'
# Image processing options
apply_flatfield: bool = False
# Registration options
use_registration: bool = False
registration_channel: str = '' # Will use first available channel if empty
registration_z_level: int = 0
dynamic_registration: bool = False
# Scanning and stitching configuration
scan_pattern: str = 'Unidirectional' # or 'S-Pattern'
merge_timepoints: bool = False
merge_hcs_regions: bool = False
def __post_init__(self):
"""Validate and process parameters after initialization."""
# Convert relative path to absolute
self.input_folder = os.path.abspath(self.input_folder)
def validate(self) -> None:
"""
Validate parameters and raise appropriate errors.
Raises:
ValueError: If parameters are invalid or incompatible
"""
# Validate input folder
if not os.path.exists(self.input_folder):
raise ValueError(f"Input folder does not exist: {self.input_folder}")
# Validate output format
if self.output_format not in ['.ome.zarr', '.ome.tiff']:
raise ValueError("Output format must be either .ome.zarr or .ome.tiff")
# Validate scan pattern
if self.scan_pattern not in ['Unidirectional', 'S-Pattern']:
raise ValueError("Scan pattern must be either 'Unidirectional' or 'S-Pattern'")
# Validate registration settings
if self.use_registration:
if self.registration_z_level < 0:
raise ValueError("Registration Z-level must be non-negative")
# Note: registration_channel can be empty - will use first available
@property
def stitched_folder(self) -> str:
"""Path to folder containing stitched outputs."""
return os.path.join(self.input_folder + "_stitched_" + datetime.now().strftime('%Y-%m-%d_%H-%M-%S.%f'))
@classmethod
def from_dict(cls, data: Dict[str, Any]) -> 'StitchingParameters':
"""
Create parameters from a dictionary.
Args:
data: Dictionary containing parameter values
Returns:
StitchingParameters: New instance with values from dictionary
"""
valid_fields = {k for k in cls.__dataclass_fields__}
filtered_data = {k: v for k, v in data.items() if k in valid_fields}
return cls(**filtered_data)
@classmethod
def from_json(cls, json_path: str) -> 'StitchingParameters':
"""
Create parameters from a JSON file.
Args:
json_path: Path to JSON file containing parameters
Returns:
StitchingParameters: New instance with values from JSON
"""
with open(json_path) as f:
return cls.from_dict(json.load(f))
def to_dict(self) -> Dict[str, Any]:
"""Convert parameters to a dictionary."""
return {k: getattr(self, k) for k in self.__dataclass_fields__}
def to_json(self, json_path: str) -> None:
"""
Save parameters to a JSON file.
Args:
json_path: Path where JSON file should be saved
"""
with open(json_path, 'w') as f:
json.dump(self.to_dict(), f, indent=2)