77from datetime import datetime
88from pathlib import Path
99from typing import Dict , Generator , List , Optional
10+ from urllib .parse import quote
1011from xml .etree import ElementTree as ET
1112
1213from defusedxml .ElementTree import parse
@@ -92,11 +93,7 @@ def __init__(self, acquisition_software: str, basepath: Path):
9293 self ._basepath = basepath
9394 # CLEM contexts for "auto-save" acquisition mode
9495 self ._tiff_series : Dict [str , List [str ]] = {} # {Series name : TIFF path list}
95- self ._tiff_timestamps : Dict [str , List [float ]] = {} # {Series name : Timestamps}
96- self ._tiff_sizes : Dict [str , List [int ]] = {} # {Series name : File sizes}
9796 self ._series_metadata : Dict [str , str ] = {} # {Series name : Metadata file path}
98- self ._metadata_timestamp : Dict [str , float ] = {} # {Series name : Timestamp}
99- self ._metadata_size : Dict [str , int ] = {} # {Series name : File size}
10097 self ._files_in_series : Dict [str , int ] = {} # {Series name : Total TIFFs}
10198
10299 def post_transfer (
@@ -128,13 +125,13 @@ def post_transfer(
128125 logger .warning (f"No source found for file { transferred_file } " )
129126 return False
130127
131- # Get the Path on the DLS file system
132- file_path = _file_transferred_to (
128+ # Get the file Path at the destination
129+ destination_file = _file_transferred_to (
133130 environment = environment ,
134131 source = source ,
135132 file_path = transferred_file ,
136133 )
137- if not file_path :
134+ if not destination_file :
138135 logger .warning (
139136 f"File { transferred_file .name !r} not found on the storage system"
140137 )
@@ -167,16 +164,22 @@ def post_transfer(
167164 if len (transferred_file .stem .split ("--" )) == 3 :
168165 series_name = "/" .join (
169166 [
170- * file_path .parent .parts [- 2 :], # Upper 2 parent directories
171- file_path .stem .split ("--" )[0 ],
167+ * destination_file .parent .parts [
168+ - 2 :
169+ ], # Upper 2 parent directories
170+ destination_file .stem .split ("--" )[0 ],
172171 ]
173172 )
174173 # When this a repeated position
175174 elif len (transferred_file .stem .split ("--" )) == 4 :
176175 series_name = "/" .join (
177176 [
178- * file_path .parent .parts [- 2 :], # Upper 2 parent directories
179- "--" .join (file_path .stem .split ("--" )[i ] for i in [0 , - 1 ]),
177+ * destination_file .parent .parts [
178+ - 2 :
179+ ], # Upper 2 parent directories
180+ "--" .join (
181+ destination_file .stem .split ("--" )[i ] for i in [0 , - 1 ]
182+ ),
180183 ]
181184 )
182185 else :
@@ -191,20 +194,17 @@ def post_transfer(
191194 # Create key-value pairs containing empty list if not already present
192195 if series_name not in self ._tiff_series .keys ():
193196 self ._tiff_series [series_name ] = []
194- if series_name not in self ._tiff_sizes .keys ():
195- self ._tiff_sizes [series_name ] = []
196- if series_name not in self ._tiff_timestamps .keys ():
197- self ._tiff_timestamps [series_name ] = []
198197 # Append information to list
199- self ._tiff_series [series_name ].append (str (file_path ))
200- self ._tiff_sizes [series_name ].append (transferred_file .stat ().st_size )
201- self ._tiff_timestamps [series_name ].append (
202- transferred_file .stat ().st_ctime
203- )
198+ self ._tiff_series [series_name ].append (str (destination_file ))
204199 logger .debug (
205200 f"Created TIFF file dictionary entries for { series_name !r} "
206201 )
207202
203+ # Register the TIFF file in the database
204+ post_result = self .register_tiff_file (destination_file , environment )
205+ if post_result is False :
206+ return False
207+
208208 # Process XLIF files
209209 if transferred_file .suffix == ".xlif" :
210210
@@ -230,7 +230,7 @@ def post_transfer(
230230 # XLIF files don't have the "--ZXX--CXX" additions in the file name
231231 # But they have "/Metadata/" as the immediate parent
232232 series_name = "/" .join (
233- [* file_path .parent .parent .parts [- 2 :], file_path .stem ]
233+ [* destination_file .parent .parent .parts [- 2 :], destination_file .stem ]
234234 ) # The previous 2 parent directories should be unique enough
235235 logger .debug (
236236 f"File { transferred_file .name !r} given the series name { series_name !r} "
@@ -262,11 +262,12 @@ def post_transfer(
262262
263263 # Update dictionary entries
264264 self ._files_in_series [series_name ] = num_files
265- self ._series_metadata [series_name ] = str (file_path )
266- self ._metadata_size [series_name ] = transferred_file .stat ().st_size
267- self ._metadata_timestamp [series_name ] = transferred_file .stat ().st_ctime
265+ self ._series_metadata [series_name ] = str (destination_file )
268266 logger .debug (f"Created dictionary entries for { series_name !r} metadata" )
269267
268+ # A new copy of the metadata file is created in 'processed', so no need
269+ # to register this instance of it
270+
270271 # Post message if all files for the associated series have been collected
271272 # .get(series_name, 0) returns 0 if no associated key is found
272273 if not len (self ._tiff_series .get (series_name , [])):
@@ -284,27 +285,16 @@ def post_transfer(
284285 f"Collected expected number of TIFF files for series { series_name !r} ; posting job to server"
285286 )
286287
287- # Construct URL for Murfey server to communicate with
288- url = f"{ str (environment .url .geturl ())} /sessions/{ environment .murfey_session } /tiff_to_stack"
289- if not url :
290- logger .warning ("No URL found for the environment" )
291- return True
292-
293288 # Post the message and log any errors that arise
294- capture_post (
295- url ,
296- json = {
297- "series_name" : series_name ,
298- "tiff_files" : self ._tiff_series [series_name ],
299- "tiff_sizes" : self ._tiff_sizes [series_name ],
300- "tiff_timestamps" : self ._tiff_timestamps [series_name ],
301- "series_metadata" : self ._series_metadata [series_name ],
302- "metadata_size" : self ._metadata_size [series_name ],
303- "metadata_timestamp" : self ._metadata_timestamp [series_name ],
304- "description" : "" ,
305- },
306- )
307- return True
289+ tiff_dataset = {
290+ "series_name" : series_name ,
291+ "tiff_files" : self ._tiff_series [series_name ],
292+ "series_metadata" : self ._series_metadata [series_name ],
293+ }
294+ post_result = self .process_tiff_series (tiff_dataset , environment )
295+ if post_result is False :
296+ return False
297+
308298 else :
309299 logger .debug (f"TIFF series { series_name !r} is still being processed" )
310300
@@ -313,42 +303,154 @@ def post_transfer(
313303 # Type checking to satisfy MyPy
314304 if not environment :
315305 logger .warning ("No environment passed in" )
316- return True
306+ return False
317307
318308 # Location of the file on the client PC
319309 source = _get_source (transferred_file , environment )
320310 # Type checking to satisfy MyPy
321311 if not source :
322312 logger .warning (f"No source found for file { transferred_file } " )
323- return True
313+ return False
324314
325315 logger .debug (
326- f"File { transferred_file .name !r} is a valid LIF file; posting job to server "
316+ f"File { transferred_file .name !r} is a valid LIF file; starting processing "
327317 )
328318
329- # Construct the URL for the Murfey server to communicate with
330- url = f"{ str (environment .url .geturl ())} /sessions/{ environment .murfey_session } /lif_to_stack"
331- # Type checking to satisfy MyPy
332- if not url :
333- logger .warning ("No URL found for the environment" )
334- return True
335-
336- # Get the Path on the DLS file system
337- file_path = _file_transferred_to (
319+ # Get the Path at the destination
320+ destination_file = _file_transferred_to (
338321 environment = environment ,
339322 source = source ,
340323 file_path = transferred_file ,
341324 )
325+ if not destination_file :
326+ logger .warning (
327+ f"File { transferred_file .name !r} not found on the storage system"
328+ )
329+ return False
330+
331+ # Post URL to register LIF file in database
332+ post_result = self .register_lif_file (destination_file , environment )
333+ if post_result is False :
334+ return False
335+ logger .info (f"Registered { destination_file .name !r} in the database" )
336+
337+ # Post URL to trigger job and convert LIF file into image stacks
338+ post_result = self .process_lif_file (destination_file , environment )
339+ if post_result is False :
340+ return False
341+ logger .info (f"Started preprocessing of { destination_file .name !r} " )
342+
343+ # Function has completed as expected
344+ return True
345+
346+ def register_lif_file (
347+ self ,
348+ lif_file : Path ,
349+ environment : MurfeyInstanceEnvironment ,
350+ ):
351+ """
352+ Constructs the URL and dictionary to be posted to the server, which will then
353+ register the LIF file in the database correctly as part of the CLEM workflow.
354+ """
355+ try :
356+ # Construct URL to post to post the request to
357+ url = f"{ str (environment .url .geturl ())} /sessions/{ environment .murfey_session } /clem/lif_files?lif_file={ quote (str (lif_file ), safe = '' )} "
358+ # Validate
359+ if not url :
360+ logger .error (
361+ "URL could not be constructed from the environment and file path"
362+ )
363+ return False
364+
365+ # Send the message
366+ capture_post (url )
367+ return True
368+
369+ except Exception as e :
370+ logger .error (
371+ f"Error encountered when registering the LIF file in the database: { e } "
372+ )
373+ return False
374+
375+ def process_lif_file (
376+ self ,
377+ lif_file : Path ,
378+ environment : MurfeyInstanceEnvironment ,
379+ ):
380+ """
381+ Constructs the URL and dictionary to be posted to the server, which will then
382+ trigger the preprocessing of the LIF file.
383+ """
384+
385+ try :
386+ # Construct the URL to post the request to
387+ url = f"{ str (environment .url .geturl ())} /sessions/{ environment .murfey_session } /lif_to_stack?lif_file={ quote (str (lif_file ), safe = '' )} "
388+ # Validate
389+ if not url :
390+ logger .error (
391+ "URL could not be constructed from the environment and file path"
392+ )
393+ return False
394+
395+ # Send the message
396+ capture_post (url )
397+ return True
398+
399+ except Exception as e :
400+ logger .error (f"Error encountered processing LIF file: { e } " )
401+ return False
342402
343- # Post the message and logs it if there's an error
344- capture_post (
345- url ,
346- json = {
347- "name" : str (file_path ),
348- "size" : transferred_file .stat ().st_size , # File size, in bytes
349- "timestamp" : transferred_file .stat ().st_ctime , # For Unix systems, shows last metadata change
350- "description" : "" ,
351- },
403+ def register_tiff_file (
404+ self ,
405+ tiff_file : Path ,
406+ environment : MurfeyInstanceEnvironment ,
407+ ):
408+ """
409+ Constructs the URL and dictionary to be posted to the server, which will then
410+ register the TIFF file in the database correctly as part of the CLEM workflow.
411+ """
412+
413+ try :
414+ url = f"{ str (environment .url .geturl ())} /sessions/{ environment .murfey_session } /clem/tiff_files?tiff_file={ quote (str (tiff_file ), safe = '' )} "
415+ if not url :
416+ logger .error (
417+ "URL could not be constructed from the environment and file path"
418+ )
419+ return False
420+
421+ # Send the message
422+ capture_post (url )
423+ return True
424+
425+ except Exception as e :
426+ logger .error (
427+ f"Error encountered when registering the TIFF file in the database: { e } "
352428 )
429+ return False
430+
431+ def process_tiff_series (
432+ self ,
433+ tiff_dataset : dict ,
434+ environment : MurfeyInstanceEnvironment ,
435+ ):
436+ """
437+ Constructs the URL and dictionary to be posted to the server, which will then
438+ trigger the preprocessing of this instance of a TIFF series.
439+ """
440+
441+ try :
442+ # Construct URL for Murfey server to communicate with
443+ url = f"{ str (environment .url .geturl ())} /sessions/{ environment .murfey_session } /tiff_to_stack"
444+ if not url :
445+ logger .error (
446+ "URL could not be constructed from the environment and file path"
447+ )
448+ return False
449+
450+ # Send the message
451+ capture_post (url , json = tiff_dataset )
353452 return True
354- return True
453+
454+ except Exception as e :
455+ logger .error (f"Error encountered processing the TIFF series: { e } " )
456+ return False
0 commit comments