@@ -58,6 +58,10 @@ def _find_reference(txrm_file: Path) -> Path | None:
5858 return None
5959
6060
61+ def _get_ole_header_value (ole_file , title : str , dtype : np .dtype ):
62+ return np .frombuffer (ole_file .openstream (title ).getvalue (), dtype )
63+
64+
6165class SXTContext (Context ):
6266 def __init__ (
6367 self ,
@@ -156,69 +160,221 @@ def post_transfer(
156160 environment = environment ,
157161 ** kwargs ,
158162 )
163+ metadata : dict [str , Any ] = {}
164+
165+ if transferred_file .suffix == ".xrm" and environment :
166+ # Make sure we have a dcg for this grid
167+ dcg_tag = ensure_dcg_exists (
168+ collection_type = "sxt" ,
169+ metadata_source = self ._basepath ,
170+ environment = environment ,
171+ machine_config = self ._machine_config ,
172+ token = self ._token ,
173+ )
159174
160- data_suffixes = [".txrm" ]
175+ with OleFileIO (str (transferred_file )) as xrm_ole :
176+ if xrm_ole .exists ("ImageInfo/XPosition" ) and xrm_ole .exists (
177+ "ImageInfo/YPosition"
178+ ):
179+ x_tiles = _get_ole_header_value (
180+ xrm_ole , "ImageInfo/XPosition" , np .float32
181+ ).tolist ()
182+ y_tiles = _get_ole_header_value (
183+ xrm_ole , "ImageInfo/YPosition" , np .float32
184+ ).tolist ()
185+ metadata ["x_position" ] = x_tiles [int (len (x_tiles ) / 2 )]
186+ metadata ["y_position" ] = y_tiles [int (len (y_tiles ) / 2 )]
161187
162- if transferred_file .suffix in data_suffixes and environment :
188+ if xrm_ole .exists ("ImageInfo/PixelSize" ):
189+ metadata ["pixel_size" ] = _get_ole_header_value (
190+ xrm_ole , "ImageInfo/PixelSize" , np .float32
191+ ).tolist ()[0 ]
192+
193+ if xrm_ole .exists ("ImageInfo/ImageHeight" ):
194+ metadata ["height" ] = _get_ole_header_value (
195+ xrm_ole , "ImageInfo/ImageHeight" , np .int32
196+ ).tolist ()[0 ]
197+
198+ if xrm_ole .exists ("ImageInfo/ImageWidth" ):
199+ metadata ["width" ] = _get_ole_header_value (
200+ xrm_ole , "ImageInfo/ImageWidth" , np .int32
201+ ).tolist ()[0 ]
202+
203+ # Find images which are not mosaics (txrm spec typos this as mosiac)
204+ if xrm_ole .exists ("ImageInfo/MosiacRows" ) and xrm_ole .exists (
205+ "ImageInfo/MosiacColumns"
206+ ):
207+ metadata ["mosaic_rows" ] = _get_ole_header_value (
208+ xrm_ole , "ImageInfo/MosiacRows" , np .int32
209+ )[0 ]
210+ metadata ["mosaic_columns" ] = _get_ole_header_value (
211+ xrm_ole , "ImageInfo/MosiacColumns" , np .int32
212+ )[0 ]
213+ metadata ["mosaic_size" ] = int (
214+ metadata ["mosaic_rows" ] * metadata ["mosaic_columns" ]
215+ )
216+
217+ source = _get_source (transferred_file , environment = environment )
218+ if source :
219+ image_path = _file_transferred_to (
220+ environment ,
221+ source ,
222+ transferred_file ,
223+ Path (self ._machine_config .get ("rsync_basepath" , "" )),
224+ )
225+ if (
226+ environment .visit
227+ in Path (environment .default_destinations [source ]).parts
228+ ):
229+ # Split either side of the raw directory
230+ visit_idx = Path (
231+ environment .default_destinations [source ]
232+ ).parts .index (environment .visit )
233+ destination_base = "/" .join (
234+ Path (environment .default_destinations [source ]).parts [
235+ : visit_idx + 1
236+ ]
237+ )
238+ destination_extra = "/" .join (
239+ Path (environment .default_destinations [source ]).parts [
240+ visit_idx + 2 :
241+ ]
242+ )
243+ else :
244+ destination_base = str (
245+ Path (environment .default_destinations [source ])
246+ / environment .visit
247+ )
248+ destination_extra = ""
249+ converted_file_path = (
250+ Path (self ._machine_config .get ("rsync_basepath" , "" ))
251+ / destination_base
252+ / self ._machine_config .get ("processed_directory_name" , "" )
253+ / self ._machine_config .get ("processed_extra_directory" , "" )
254+ / destination_extra
255+ / f"{ transferred_file .relative_to (source ).stem } _Annotated.tiff"
256+ )
257+ capture_post (
258+ base_url = str (environment .url .geturl ()),
259+ router_name = "workflow_sxt.router" ,
260+ function_name = "convert_xrm_to_tiff" ,
261+ token = self ._token ,
262+ instrument_name = environment .instrument_name ,
263+ data = {
264+ "xrm_path" : str (image_path ),
265+ "tiff_path" : str (converted_file_path ),
266+ },
267+ )
268+
269+ if (
270+ metadata .get ("mosaic_size" , 1 ) > 0
271+ and metadata .get ("pixel_size" , 0 ) > 0.1
272+ ):
273+ # Large pixel size, this is an atlas
274+ dcg_data = {
275+ "experiment_type_id" : 44 , # Atlas
276+ "tag" : dcg_tag ,
277+ "atlas" : str (converted_file_path ),
278+ "atlas_pixel_size" : round (metadata .get ("pixel_size" , 0 ), 2 ),
279+ "atlas_x_stage_position" : metadata .get ("x_position" , None ),
280+ "atlas_y_stage_position" : metadata .get ("y_position" , None ),
281+ "atlas_height" : int (
282+ metadata .get ("height" , 0 ) * metadata ["mosaic_rows" ]
283+ ),
284+ "atlas_width" : int (
285+ metadata .get ("width" , 0 ) * metadata ["mosaic_columns" ]
286+ ),
287+ }
288+ capture_post (
289+ base_url = str (environment .url .geturl ()),
290+ router_name = "workflow.router" ,
291+ function_name = "register_dc_group" ,
292+ token = self ._token ,
293+ instrument_name = environment .instrument_name ,
294+ visit_name = environment .visit ,
295+ session_id = environment .murfey_session ,
296+ data = dcg_data ,
297+ )
298+ elif metadata .get ("mosaic_size" , 1 ) > 0 :
299+ # Other mosaic images are of grid squares
300+ capture_post (
301+ base_url = str (environment .url .geturl ()),
302+ router_name = "workflow_sxt.router" ,
303+ function_name = "register_sxt_roi" ,
304+ token = self ._token ,
305+ instrument_name = environment .instrument_name ,
306+ visit_name = environment .visit ,
307+ session_id = environment .murfey_session ,
308+ data = {
309+ "tag" : dcg_tag ,
310+ "name" : transferred_file .stem ,
311+ "x_stage_position" : metadata .get ("x_position" , None ),
312+ "y_stage_position" : metadata .get ("y_position" , None ),
313+ "pixel_size" : round (metadata .get ("pixel_size" , 0 ), 2 ),
314+ "height" : int (
315+ metadata .get ("height" , 0 ) * metadata ["mosaic_rows" ]
316+ ),
317+ "width" : int (
318+ metadata .get ("width" , 0 ) * metadata ["mosaic_columns" ]
319+ ),
320+ "image" : str (converted_file_path ),
321+ },
322+ )
323+
324+ elif transferred_file .suffix == ".txrm" and environment :
163325 source = _get_source (transferred_file , environment )
164326 if not source :
165327 logger .warning (f"No source found for file { transferred_file } " )
166328 return False
167329
168330 # Read the tilt angles and pixel size from the txrm
169331 angles : list = []
170- metadata : dict [str , Any ] = {
171- "source" : str (self ._basepath ),
172- "tilt_series_tag" : transferred_file .stem ,
173- }
332+ metadata ["source" ] = str (self ._basepath )
333+ metadata ["tilt_series_tag" ] = transferred_file .stem
174334 with OleFileIO (str (transferred_file )) as txrm_ole :
175335 if txrm_ole .exists ("ReferenceData/Image" ):
176336 metadata ["has_reference" ] = True
177337
178338 if txrm_ole .exists ("ImageInfo/Angles" ):
179- angles = np . frombuffer (
180- txrm_ole . openstream ( "ImageInfo/Angles" ). getvalue () , np .float32
339+ angles = _get_ole_header_value (
340+ txrm_ole , "ImageInfo/Angles" , np .float32
181341 ).tolist ()
182342 metadata ["minimum_angle" ] = min (angles )
183343 metadata ["maximum_angle" ] = max (angles )
184344
185345 if txrm_ole .exists ("ImageInfo/PixelSize" ):
186- pixel_size_txrm = np .frombuffer (
187- txrm_ole .openstream ("ImageInfo/PixelSize" ).getvalue (),
188- np .float32 ,
346+ pixel_size_txrm = _get_ole_header_value (
347+ txrm_ole , "ImageInfo/PixelSize" , np .float32
189348 ).tolist ()
190349 metadata ["pixel_size" ] = pixel_size_txrm [0 ] * 1e4
191350
192351 if txrm_ole .exists ("ImageInfo/ImageWidth" ):
193- image_width_txrm = np . frombuffer (
194- txrm_ole . openstream ( "ImageInfo/ImageWidth" ). getvalue () , np .int32
352+ image_width_txrm = _get_ole_header_value (
353+ txrm_ole , "ImageInfo/ImageWidth" , np .int32
195354 ).tolist ()
196355 metadata ["image_size_x" ] = image_width_txrm [0 ]
197356
198357 if txrm_ole .exists ("ImageInfo/ImageHeight" ):
199- image_height_txrm = np .frombuffer (
200- txrm_ole .openstream ("ImageInfo/ImageHeight" ).getvalue (),
201- np .int32 ,
358+ image_height_txrm = _get_ole_header_value (
359+ txrm_ole , "ImageInfo/ImageHeight" , np .int32
202360 ).tolist ()
203361 metadata ["image_size_y" ] = image_height_txrm [0 ]
204362
205363 if txrm_ole .exists ("ImageInfo/ExpTimes" ):
206- exposure_time_txrm = np . frombuffer (
207- txrm_ole . openstream ( "ImageInfo/ExpTimes" ). getvalue () , np .float32
364+ exposure_time_txrm = _get_ole_header_value (
365+ txrm_ole , "ImageInfo/ExpTimes" , np .float32
208366 ).tolist ()
209367 metadata ["exposure_time" ] = exposure_time_txrm [0 ]
210368
211369 if txrm_ole .exists ("ImageInfo/XrayMagnification" ):
212- magnification_txrm = np .frombuffer (
213- txrm_ole .openstream ("ImageInfo/XrayMagnification" ).getvalue (),
214- np .float32 ,
370+ magnification_txrm = _get_ole_header_value (
371+ txrm_ole , "ImageInfo/XrayMagnification" , np .float32
215372 ).tolist ()
216373 metadata ["magnification" ] = magnification_txrm [0 ]
217374
218375 if txrm_ole .exists ("ImageInfo/ImagesTaken" ):
219- tilt_count_txrm = np .frombuffer (
220- txrm_ole .openstream ("ImageInfo/ImagesTaken" ).getvalue (),
221- np .int32 ,
376+ tilt_count_txrm = _get_ole_header_value (
377+ txrm_ole , "ImageInfo/ImagesTaken" , np .int32
222378 ).tolist ()
223379 metadata ["tilt_series_length" ] = tilt_count_txrm [0 ]
224380
@@ -235,9 +391,8 @@ def post_transfer(
235391 .split ("\x00 " )
236392 if i
237393 ]
238- axis_values = np .frombuffer (
239- txrm_ole .openstream ("PositionInfo/MotorPositions" ).getvalue (),
240- np .float32 ,
394+ axis_values = _get_ole_header_value (
395+ txrm_ole , "PositionInfo/MotorPositions" , np .float32
241396 )
242397 if "Energy" in axis_names :
243398 energy_index = list (np .array (axis_names ) == "Energy" ).index (
@@ -302,7 +457,7 @@ def post_transfer(
302457 reference_file_transferred_to = None
303458 capture_post (
304459 base_url = str (environment .url .geturl ()),
305- router_name = "workflow.sxt_router " ,
460+ router_name = "workflow_sxt.router " ,
306461 function_name = "process_sxt_tilt_series" ,
307462 token = self ._token ,
308463 instrument_name = environment .instrument_name ,
0 commit comments