@@ -38,6 +38,10 @@ class CLEMPreprocessingResult(BaseModel):
3838 output_files : dict [
3939 Literal ["gray" , "red" , "green" , "blue" , "cyan" , "magenta" , "yellow" ], Path
4040 ]
41+ thumbnails : dict [
42+ Literal ["gray" , "red" , "green" , "blue" , "cyan" , "magenta" , "yellow" ], Path
43+ ] = {}
44+ thumbnail_size : Optional [tuple [int , int ]] = None # height, width
4145 metadata : Path
4246 parent_lif : Optional [Path ] = None
4347 parent_tiffs : dict [
@@ -54,7 +58,10 @@ class CLEMPreprocessingResult(BaseModel):
5458def _is_clem_atlas (result : CLEMPreprocessingResult ):
5559 # If an image has a width/height of at least 1.5 mm, it should qualify as an atlas
5660 return (
57- max (result .pixels_x * result .pixel_size , result .pixels_y * result .pixel_size )
61+ max (
62+ result .pixels_x * result .pixel_size ,
63+ result .pixels_y * result .pixel_size ,
64+ )
5865 >= processing_params .atlas_threshold
5966 )
6067
@@ -149,17 +156,29 @@ def _register_clem_image_series(
149156 murfey_db .commit ()
150157
151158 # Add metadata for this series
152- clem_img_series .search_string = str (output_file .parent / "*tiff" )
159+ clem_img_series .image_search_string = str (output_file .parent / "*tiff" )
153160 clem_img_series .data_type = "atlas" if _is_clem_atlas (result ) else "grid_square"
154161 clem_img_series .number_of_members = result .number_of_members
155- clem_img_series .pixels_x = result .pixels_x
156- clem_img_series .pixels_y = result .pixels_y
157- clem_img_series .pixel_size = result .pixel_size
162+ clem_img_series .image_pixels_x = result .pixels_x
163+ clem_img_series .image_pixels_y = result .pixels_y
164+ clem_img_series .image_pixel_size = result .pixel_size
158165 clem_img_series .units = result .units
159166 clem_img_series .x0 = result .extent [0 ]
160167 clem_img_series .x1 = result .extent [1 ]
161168 clem_img_series .y0 = result .extent [2 ]
162169 clem_img_series .y1 = result .extent [3 ]
170+ # Register thumbnails if they are present
171+ if result .thumbnails and result .thumbnail_size :
172+ thumbnail = list (result .thumbnails .values ())[0 ]
173+ clem_img_series .thumbnail_search_string = str (thumbnail .parent / "*.png" )
174+
175+ thumbnail_height , thumbnail_width = result .thumbnail_size
176+ scaling_factor = min (
177+ thumbnail_height / result .pixels_y , thumbnail_width / result .pixels_x
178+ )
179+ clem_img_series .thumbnail_pixel_size = result .pixel_size / scaling_factor
180+ clem_img_series .thumbnail_pixels_x = int (result .pixels_x * scaling_factor )
181+ clem_img_series .thumbnail_pixels_y = int (result .pixels_y * scaling_factor )
163182 murfey_db .add (clem_img_series )
164183 murfey_db .commit ()
165184 murfey_db .close ()
@@ -189,8 +208,23 @@ def _register_dcg_and_atlas(
189208 # Determine values for atlas
190209 if _is_clem_atlas (result ):
191210 output_file = list (result .output_files .values ())[0 ]
192- atlas_name = str (output_file .parent / "*.tiff" )
193- atlas_pixel_size = result .pixel_size
211+ # Register the thumbnail entries if they are provided
212+ if result .thumbnails and result .thumbnail_size is not None :
213+ # Glob path to the thumbnail files
214+ thumbnail = list (result .thumbnails .values ())[0 ]
215+ atlas_name = str (thumbnail .parent / "*.png" )
216+
217+ # Work out the scaling factor used
218+ thumbnail_height , thumbnail_width = result .thumbnail_size
219+ scaling_factor = min (
220+ thumbnail_width / result .pixels_x ,
221+ thumbnail_height / result .pixels_y ,
222+ )
223+ atlas_pixel_size = result .pixel_size / scaling_factor
224+ # Otherwise, register the TIFF files themselves
225+ else :
226+ atlas_name = str (output_file .parent / "*.tiff" )
227+ atlas_pixel_size = result .pixel_size
194228 else :
195229 atlas_name = ""
196230 atlas_pixel_size = 0.0
@@ -308,8 +342,6 @@ def _register_grid_square(
308342 and atlas_entry .x1 is not None
309343 and atlas_entry .y0 is not None
310344 and atlas_entry .y1 is not None
311- and atlas_entry .pixels_x is not None
312- and atlas_entry .pixels_y is not None
313345 ):
314346 atlas_width_real = atlas_entry .x1 - atlas_entry .x0
315347 atlas_height_real = atlas_entry .y1 - atlas_entry .y0
@@ -318,32 +350,40 @@ def _register_grid_square(
318350 return
319351
320352 for clem_img_series in clem_img_series_to_register :
353+ # Register datasets using thumbnail sizes and scales
321354 if (
322355 clem_img_series .x0 is not None
323356 and clem_img_series .x1 is not None
324357 and clem_img_series .y0 is not None
325358 and clem_img_series .y1 is not None
359+ and clem_img_series .thumbnail_pixels_x is not None
360+ and clem_img_series .thumbnail_pixels_y is not None
361+ and clem_img_series .thumbnail_pixel_size is not None
326362 ):
327363 # Find pixel corresponding to image midpoint on atlas
328364 x_mid_real = (
329365 0.5 * (clem_img_series .x0 + clem_img_series .x1 ) - atlas_entry .x0
330366 )
331- x_mid_px = int (x_mid_real / atlas_width_real * atlas_entry .pixels_x )
367+ x_mid_px = int (
368+ x_mid_real / atlas_width_real * clem_img_series .thumbnail_pixels_x
369+ )
332370 y_mid_real = (
333371 0.5 * (clem_img_series .y0 + clem_img_series .y1 ) - atlas_entry .y0
334372 )
335- y_mid_px = int (y_mid_real / atlas_height_real * atlas_entry .pixels_y )
373+ y_mid_px = int (
374+ y_mid_real / atlas_height_real * clem_img_series .thumbnail_pixels_y
375+ )
336376
337- # Find the number of pixels in width and height the image corresponds to on the atlas
377+ # Find the size of the image, in pixels, when overlaid the atlas
338378 width_scaled = int (
339379 (clem_img_series .x1 - clem_img_series .x0 )
340380 / atlas_width_real
341- * atlas_entry . pixels_x
381+ * clem_img_series . thumbnail_pixels_x
342382 )
343383 height_scaled = int (
344384 (clem_img_series .y1 - clem_img_series .y0 )
345385 / atlas_height_real
346- * atlas_entry . pixels_y
386+ * clem_img_series . thumbnail_pixels_y
347387 )
348388 else :
349389 logger .warning (
@@ -358,14 +398,18 @@ def _register_grid_square(
358398 x_location_scaled = x_mid_px ,
359399 y_location = clem_img_series .y0 ,
360400 y_location_scaled = y_mid_px ,
361- height = clem_img_series .pixels_x ,
362- height_scaled = height_scaled ,
363- width = clem_img_series .pixels_y ,
401+ readout_area_x = clem_img_series .image_pixels_x ,
402+ readout_area_y = clem_img_series .image_pixels_y ,
403+ thumbnail_size_x = clem_img_series .thumbnail_pixels_x ,
404+ thumbnail_size_y = clem_img_series .thumbnail_pixels_y ,
405+ width = clem_img_series .image_pixels_x ,
364406 width_scaled = width_scaled ,
365- x_stage_position = clem_img_series .x0 ,
366- y_stage_position = clem_img_series .y0 ,
367- pixel_size = clem_img_series .pixel_size ,
368- image = clem_img_series .search_string ,
407+ height = clem_img_series .image_pixels_y ,
408+ height_scaled = height_scaled ,
409+ x_stage_position = 0.5 * (clem_img_series .x0 + clem_img_series .x1 ),
410+ y_stage_position = 0.5 * (clem_img_series .y0 + clem_img_series .y1 ),
411+ pixel_size = clem_img_series .image_pixel_size ,
412+ image = clem_img_series .thumbnail_search_string ,
369413 )
370414 # Register or update the grid square entry as required
371415 if grid_square_result := murfey_db .exec (
0 commit comments