Skip to content

Commit dec5daf

Browse files
authored
Merge pull request #1 from maartenpaul/incucyte_reader
Add Incucyte reader
2 parents 2317ed4 + 6ee4546 commit dec5daf

10 files changed

Lines changed: 4040 additions & 25 deletions

File tree

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# SCM syntax highlighting & preventing 3-way merges
2+
pixi.lock merge=binary linguist-language=YAML linguist-generated=true

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,3 +207,7 @@ marimo/_lsp/
207207
__marimo__/
208208
/.idea
209209
/data
210+
211+
# pixi environments
212+
.pixi
213+
*.egg-info

converter.py

Lines changed: 109 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
from src.helper import create_source, create_writer
77
from src.parameters import CONVERSION_ATTEMPTS
8+
from src.util import print_hbytes
89

910

1011
def init_logging(log_filename, verbose=False):
@@ -29,12 +30,13 @@ def init_logging(log_filename, verbose=False):
2930

3031

3132
def convert(input_filename, output_folder, alt_output_folder=None,
32-
output_format='omezarr2', show_progress=False, verbose=False):
33+
output_format='omezarr2', show_progress=False, verbose=False, **kwargs):
3334
attempts = 0
3435
while True:
3536
try:
3637
return _convert(input_filename, output_folder, alt_output_folder=alt_output_folder,
37-
output_format=output_format, show_progress=show_progress, verbose=verbose)
38+
output_format=output_format, show_progress=show_progress, verbose=verbose,
39+
**kwargs)
3840
except Exception as e:
3941
if attempts >= CONVERSION_ATTEMPTS - 1:
4042
logging.error(e)
@@ -43,7 +45,7 @@ def convert(input_filename, output_folder, alt_output_folder=None,
4345

4446

4547
def _convert(input_filename, output_folder, alt_output_folder=None,
46-
output_format='omezarr2', show_progress=False, verbose=False):
48+
output_format='omezarr2', show_progress=False, verbose=False, **kwargs):
4749
"""
4850
Convert an input file to OME format and write to output folder(s).
4951
@@ -58,16 +60,89 @@ def _convert(input_filename, output_folder, alt_output_folder=None,
5860
Returns:
5961
str: JSON string with conversion result info array.
6062
"""
63+
64+
# Check if input is an Incucyte archive and handle multiple plates
65+
input_ext = os.path.splitext(input_filename)[1].lower()
66+
if input_ext == '.icarch':
67+
from src.helper import get_incucyte_plates
68+
69+
available_plates = get_incucyte_plates(input_filename)
70+
71+
# If plate_id not specified, process all plates
72+
if 'plate_id' not in kwargs or kwargs['plate_id'] is None:
73+
plate_list = '", "'.join(available_plates)
74+
logging.info(f'Processing {len(available_plates)} '
75+
f'plate(s): {plate_list}')
76+
results = []
77+
for plate_id in available_plates:
78+
logging.info(f'Processing plate {plate_id}')
79+
plate_kwargs = kwargs.copy()
80+
plate_kwargs['plate_id'] = plate_id
81+
result = _convert_single(
82+
input_filename, output_folder,
83+
alt_output_folder=alt_output_folder,
84+
output_format=output_format,
85+
show_progress=show_progress,
86+
verbose=verbose,
87+
**plate_kwargs)
88+
results.extend(json.loads(result))
89+
return json.dumps(results)
90+
91+
# Single source conversion
92+
return _convert_single(
93+
input_filename, output_folder,
94+
alt_output_folder=alt_output_folder,
95+
output_format=output_format,
96+
show_progress=show_progress,
97+
verbose=verbose,
98+
**kwargs)
99+
100+
101+
def _convert_single(input_filename, output_folder, alt_output_folder=None,
102+
output_format='omezarr2', show_progress=False,
103+
verbose=False, **kwargs):
104+
"""
105+
Convert a single source to OME format.
106+
107+
Args:
108+
input_filename (str): Path to the input file.
109+
output_folder (str): Output folder path.
110+
alt_output_folder (str, optional): Alternative output folder path.
111+
output_format (str): Output format string.
112+
show_progress (bool): If True, print progress.
113+
verbose (bool): If True, enable verbose logging.
114+
**kwargs: Source-specific parameters (e.g., plate_id for Incucyte).
115+
116+
Returns:
117+
str: JSON string with conversion result info array.
118+
"""
61119

62120
logging.info(f'Importing {input_filename}')
63-
source = create_source(input_filename)
121+
source = create_source(input_filename, **kwargs)
64122
writer, output_ext = create_writer(output_format, verbose=verbose)
65-
if not os.path.exists(output_folder):
66-
os.makedirs(output_folder)
67-
123+
68124
source.init_metadata()
125+
if verbose:
126+
total_size = print_hbytes(source.get_total_data_size())
127+
print(f'Total data size: {total_size}')
128+
69129
name = source.get_name()
70-
output_path = os.path.join(output_folder, name + output_ext)
130+
131+
# For Incucyte sources with plates, organize output in subfolders
132+
from src.IncucyteSource import IncucyteSource
133+
if isinstance(source, IncucyteSource) and source.plate_id:
134+
# Create plate-specific subfolder
135+
plate_folder = f"plate_{source.plate_id}"
136+
plate_output_folder = os.path.join(output_folder, plate_folder)
137+
if not os.path.exists(plate_output_folder):
138+
os.makedirs(plate_output_folder)
139+
output_path = os.path.join(plate_output_folder, name + output_ext)
140+
else:
141+
# Standard output path
142+
if not os.path.exists(output_folder):
143+
os.makedirs(output_folder)
144+
output_path = os.path.join(output_folder, name + output_ext)
145+
71146
full_output_path = writer.write(output_path, source)
72147
source.close()
73148

@@ -83,18 +158,37 @@ def _convert(input_filename, output_folder, alt_output_folder=None,
83158
message = f"Exported {result['full_path']}"
84159

85160
if alt_output_folder:
86-
if not os.path.exists(alt_output_folder):
87-
os.makedirs(alt_output_folder)
88-
alt_output_path = os.path.join(alt_output_folder, name + output_ext)
161+
# Use same subfolder structure for alternative output
162+
if isinstance(source, IncucyteSource) and source.plate_id:
163+
alt_plate_folder = os.path.join(
164+
alt_output_folder, f"plate_{source.plate_id}"
165+
)
166+
if not os.path.exists(alt_plate_folder):
167+
os.makedirs(alt_plate_folder)
168+
alt_output_path = os.path.join(alt_plate_folder, name + output_ext)
169+
else:
170+
if not os.path.exists(alt_output_folder):
171+
os.makedirs(alt_output_folder)
172+
alt_output_path = os.path.join(
173+
alt_output_folder, name + output_ext
174+
)
175+
89176
if isinstance(full_output_path, list):
90177
for path in full_output_path:
91-
alt_output_path = os.path.join(alt_output_folder, os.path.basename(path))
92-
shutil.copy2(path, alt_output_path)
178+
basename = os.path.basename(path)
179+
if isinstance(source, IncucyteSource) and source.plate_id:
180+
alt_path = os.path.join(alt_plate_folder, basename)
181+
else:
182+
alt_path = os.path.join(alt_output_folder, basename)
183+
shutil.copy2(path, alt_path)
93184
elif os.path.isdir(full_output_path):
94-
shutil.copytree(full_output_path, alt_output_path, dirs_exist_ok=True)
185+
shutil.copytree(
186+
full_output_path, alt_output_path, dirs_exist_ok=True
187+
)
95188
else:
96189
shutil.copy2(full_output_path, alt_output_path)
97-
result['alt_path'] = os.path.join(alt_output_folder, os.path.basename(full_path))
190+
191+
result['alt_path'] = alt_output_path
98192
message += f' and {result["alt_path"]}'
99193

100194
logging.info(message)

main.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,25 @@
1111
parser.add_argument('--outputformat', help='output format version', default='omezarr2')
1212
parser.add_argument('--show_progress', action='store_true')
1313
parser.add_argument('--verbose', action='store_true')
14+
# Allow additional arguments for source-specific parameters (e.g., --plateid)
15+
parser.add_argument('--plateid', help='Incucyte plate ID (optional)')
1416
args = parser.parse_args()
1517

1618
init_logging('db_to_zarr.log', verbose=args.verbose)
1719

20+
# Build source-specific kwargs
21+
source_kwargs = {}
22+
if hasattr(args, 'plateid') and args.plateid:
23+
source_kwargs['plate_id'] = args.plateid
24+
1825
result = convert(
1926
args.inputfile,
2027
args.outputfolder,
21-
alt_output_folder = args.altoutputfolder,
22-
output_format = args.outputformat,
23-
show_progress = args.show_progress,
24-
verbose = args.verbose
28+
alt_output_folder=args.altoutputfolder,
29+
output_format=args.outputformat,
30+
show_progress=args.show_progress,
31+
verbose=args.verbose,
32+
**source_kwargs
2533
)
2634

2735
if result and result != '{}':

0 commit comments

Comments
 (0)