Skip to content

Commit ef7a976

Browse files
committed
Updated Murfey's analyser and context handler logic to support CLEM TIFF datasets of any combination of tiles, channels, or image stacks
* Adjusted file parsing logic to look for keywords indicating if the dataset has multiple tiles ('--Stage'), frames ('--Z'), and/or colour channels ('--C') * Take number of tiles, colour channels, and frames into account when calculating the expected number of files to collect
1 parent 6d23984 commit ef7a976

File tree

2 files changed

+38
-60
lines changed

2 files changed

+38
-60
lines changed

src/murfey/client/analyser.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,10 +129,9 @@ def _find_context(self, file_path: Path) -> bool:
129129
self._context = CLEMContext("leica", self._basepath, self._token)
130130
return True
131131
# Look for TIFF files associated with CLEM workflow
132-
# Leica's autosave mode seems to name the TIFFs in the format
133-
# PostionXX--ZXX--CXX.tif
134-
if all(
135-
pattern in file_path.name for pattern in ("--Z", "--C")
132+
# CLEM TIFF files will have "--Stage", "--Z", and/or "--C" in their file stem
133+
if any(
134+
pattern in file_path.stem for pattern in ("--Stage", "--Z", "--C")
136135
) and file_path.suffix in (".tiff", ".tif"):
137136
self._context = CLEMContext("leica", self._basepath, self._token)
138137
return True

src/murfey/client/contexts/clem.py

Lines changed: 35 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -145,58 +145,40 @@ def post_transfer(
145145

146146
# Process TIF/TIFF files
147147
if transferred_file.suffix in (".tif", ".tiff"):
148-
149-
# Files should be named "PositionX--ZXX--CXX.tif" by default
150-
# If Position is repeated, it will add an additional --00X to the end
151-
if len(transferred_file.stem.split("--")) not in [3, 4]:
148+
# CLEM TIFF files will have "--Stage", "--C", and/or "--Z" in their file stem
149+
if not any(
150+
pattern in transferred_file.stem
151+
for pattern in ("--Stage", "--Z", "--C")
152+
):
152153
logger.warning(
153154
f"File {transferred_file.name!r} is likely not part of the CLEM workflow"
154155
)
155156
return False
156-
157157
logger.debug(
158158
f"File {transferred_file.name!r} is part of a TIFF image series"
159159
)
160160

161161
# Create a unique name for the series
162-
# For standard file name
163-
if len(transferred_file.stem.split("--")) == 3:
164-
series_name = "--".join(
165-
[
166-
*destination_file.parent.parts[
167-
-2:
168-
], # Upper 2 parent directories
169-
destination_file.stem.split("--")[0],
170-
]
171-
)
172-
# When this a repeated position
173-
elif len(transferred_file.stem.split("--")) == 4:
174-
series_name = "--".join(
175-
[
176-
*destination_file.parent.parts[
177-
-2:
178-
], # Upper 2 parent directories
179-
"--".join(
180-
destination_file.stem.split("--")[i] for i in [0, -1]
181-
),
182-
]
183-
)
184-
else:
185-
logger.error(
186-
f"Series name could not be generated from file {transferred_file.name!r}"
187-
)
188-
return False
189-
logger.debug(
190-
f"File {transferred_file.name!r} given the series name {series_name!r}"
162+
series_name = "--".join(
163+
[
164+
*destination_file.parent.parts[
165+
-2:
166+
], # Upper 2 parent directories
167+
destination_file.stem.split("--")[0].replace(" ", "_"),
168+
]
191169
)
192170

193171
# Create key-value pairs containing empty list if not already present
194172
if series_name not in self._tiff_series.keys():
195173
self._tiff_series[series_name] = []
174+
logger.debug(
175+
f"Created new dictionary entry for TIFF series {series_name!r}"
176+
)
177+
196178
# Append information to list
197179
self._tiff_series[series_name].append(str(destination_file))
198180
logger.debug(
199-
f"Created TIFF file dictionary entries for {series_name!r}"
181+
f"File {transferred_file.name!r} added to series {series_name!r}"
200182
)
201183

202184
# Register the TIFF file in the database
@@ -230,43 +212,40 @@ def post_transfer(
230212
# XLIF files don't have the "--ZXX--CXX" additions in the file name
231213
# But they have "/Metadata/" as the immediate parent
232214
series_name = "--".join(
233-
[*destination_file.parent.parent.parts[-2:], destination_file.stem]
215+
[
216+
*destination_file.parent.parent.parts[-2:],
217+
destination_file.stem.replace(" ", "_"),
218+
]
234219
) # The previous 2 parent directories should be unique enough
235-
logger.debug(
236-
f"File {transferred_file.name!r} given the series name {series_name!r}"
237-
)
238220

239221
# Extract metadata to get the expected size of the series
240222
metadata = parse(transferred_file).getroot()
241223
metadata = _get_image_elements(metadata)[0]
242224

243225
# Get channel and dimension information
244-
channels = metadata.findall(
245-
"Data/Image/ImageDescription/Channels/ChannelDescription"
246-
)
247-
dimensions = metadata.findall(
248-
"Data/Image/ImageDescription/Dimensions/DimensionDescription"
249-
)
226+
channels = metadata.findall(".//ChannelDescription")
227+
dimensions = metadata.findall(".//DimensionDescription")
250228

251229
# Calculate expected number of files for this series
252230
num_channels = len(channels)
253-
num_frames = (
254-
int(dimensions[2].attrib["NumberOfElements"])
255-
if len(dimensions) > 2
256-
else 1
257-
)
258-
num_files = num_channels * num_frames
231+
num_frames = 1
232+
num_tiles = 1
233+
for dim in dimensions:
234+
if dim.attrib["DimID"] == "3":
235+
num_frames = int(dim.attrib["NumberOfElements"])
236+
if dim.attrib["DimID"] == "10":
237+
num_tiles = int(dim.attrib["NumberOfElements"])
238+
num_files = num_channels * num_frames * num_tiles
259239
logger.debug(
260240
f"Expected number of files in {series_name!r}: {num_files}"
261241
)
262242

263243
# Update dictionary entries
264244
self._files_in_series[series_name] = num_files
265245
self._series_metadata[series_name] = str(destination_file)
266-
logger.debug(f"Created dictionary entries for {series_name!r} metadata")
267-
268-
# A new copy of the metadata file is created in 'processed', so no need
269-
# to register this instance of it
246+
logger.debug(
247+
f"File {transferred_file.name!r} added to series {series_name!r}"
248+
)
270249

271250
# Post message if all files for the associated series have been collected
272251
# .get(series_name, 0) returns 0 if no associated key is found
@@ -280,7 +259,7 @@ def post_transfer(
280259
return True
281260
elif len(
282261
self._tiff_series.get(series_name, [])
283-
) == self._files_in_series.get(series_name, 0):
262+
) >= self._files_in_series.get(series_name, 0):
284263
logger.debug(
285264
f"Collected expected number of TIFF files for series {series_name!r}; posting job to server"
286265
)

0 commit comments

Comments
 (0)