Skip to content

Commit 3e42045

Browse files
authored
Moved LIF metadata function to another module to avoid unnecessary client-side dependency installation (#303)
1 parent 97baee4 commit 3e42045

File tree

4 files changed

+36
-40
lines changed

4 files changed

+36
-40
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ classifiers = [
3232
dependencies = [
3333
"defusedxml", # For safely parsing XML files
3434
"pydantic<2", # Pip hops between installing v2.7 or v1.10 depending on which of the additional dependencies are requested
35-
"readlif", # Specific to cryo-CLEM workflow
3635
"requests",
3736
"rich",
3837
"werkzeug",
@@ -65,6 +64,7 @@ server = [
6564
"pillow",
6665
"prometheus_client",
6766
"python-jose[cryptography]",
67+
"readlif", # Specific to cryo-CLEM workflow
6868
"sqlmodel",
6969
"stomp-py<=8.1.0", # 8.1.1 (released 2024-04-06) doesn't work with our project
7070
"tifffile", # Specific to cryo-CLEM workflow

src/murfey/client/contexts/clem.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from murfey.client.context import Context
1818
from murfey.client.instance_environment import MurfeyInstanceEnvironment
1919
from murfey.util import capture_post, get_machine_config, sanitise
20-
from murfey.util.clem import xml
20+
from murfey.util.clem.xml import get_image_elements
2121

2222
# Create logger object
2323
logger = logging.getLogger("murfey.client.contexts.clem")
@@ -59,13 +59,13 @@ def __init__(self, acquisition_software: str, basepath: Path):
5959
super().__init__("CLEM", acquisition_software)
6060
self._basepath = basepath
6161
# CLEM contexts for "auto-save" acquisition mode
62-
self._tiff_series: Dict[str, List[str]] = {} # Series name : List of TIFF paths
63-
self._tiff_timestamps: Dict[str, List[float]] = {} # Series name: Timestamps
64-
self._tiff_sizes: Dict[str, List[int]] = {} # Series name: File sizes
65-
self._series_metadata: Dict[str, str] = {} # Series name: Metadata file path
66-
self._metadata_timestamp: Dict[str, float] = {} # Series name: Timestamp
67-
self._metadata_size: Dict[str, int] = {} # Series name: File size
68-
self._files_in_series: Dict[str, int] = {} # Series name : Total TIFFs
62+
self._tiff_series: Dict[str, List[str]] = {} # {Series name : TIFF path list}
63+
self._tiff_timestamps: Dict[str, List[float]] = {} # {Series name : Timestamps}
64+
self._tiff_sizes: Dict[str, List[int]] = {} # {Series name : File sizes}
65+
self._series_metadata: Dict[str, str] = {} # {Series name : Metadata file path}
66+
self._metadata_timestamp: Dict[str, float] = {} # {Series name : Timestamp}
67+
self._metadata_size: Dict[str, int] = {} # {Series name : File size}
68+
self._files_in_series: Dict[str, int] = {} # {Series name : Total TIFFs}
6969

7070
def post_transfer(
7171
self,
@@ -144,7 +144,7 @@ def post_transfer(
144144

145145
# Extract metadata to get the expected size of the series
146146
metadata = parse(file_path).getroot()
147-
metadata = xml.get_image_elements(metadata)[0]
147+
metadata = get_image_elements(metadata)[0]
148148

149149
# Get channel and dimension information
150150
channels = metadata.findall(

src/murfey/util/clem/lif.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,43 @@
88
import logging
99
import multiprocessing as mp
1010
from pathlib import Path
11+
from typing import Optional
1112
from xml.etree import ElementTree as ET
1213

1314
import numpy as np
1415
from readlif.reader import LifFile
1516

1617
from murfey.util import sanitise
1718
from murfey.util.clem.images import process_img_stk, write_to_tiff
18-
from murfey.util.clem.xml import get_image_elements, get_lif_xml_metadata
19+
from murfey.util.clem.xml import get_image_elements
1920

2021
# Create logger object to output messages with
2122
logger = logging.getLogger("murfey.util.clem.lif")
2223

2324

25+
def get_lif_xml_metadata(
26+
file: LifFile,
27+
save_xml: Optional[Path] = None,
28+
) -> ET.Element:
29+
"""
30+
Extracts and returns the metadata from the LIF file as a formatted XML Element.
31+
It can be optionally saved as an XML file to the specified file path.
32+
"""
33+
34+
# Use readlif function to get XML metadata
35+
xml_root: ET.Element = file.xml_root # This one for navigating
36+
xml_tree = ET.ElementTree(xml_root) # This one for saving
37+
38+
# Skip saving the metadata if save_xml not provided
39+
if save_xml:
40+
xml_file = str(save_xml) # Convert Path to string
41+
ET.indent(xml_tree, " ") # Format with proper indentation
42+
xml_tree.write(xml_file, encoding="utf-8") # Save
43+
logger.info(f"File metadata saved to {sanitise(xml_file)}")
44+
45+
return xml_root
46+
47+
2448
def process_lif_file(
2549
file: Path,
2650
scene_num: int,

src/murfey/util/clem/xml.py

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,41 +8,13 @@
88
"""
99

1010
import logging
11-
from pathlib import Path
12-
from typing import Generator, List, Optional
11+
from typing import Generator, List
1312
from xml.etree import ElementTree as ET
1413

15-
from readlif.reader import LifFile
16-
17-
from murfey.util import sanitise
18-
1914
# Create logger object to output messages with
2015
logger = logging.getLogger("murfey.util.clem.xml")
2116

2217

23-
def get_lif_xml_metadata(
24-
file: LifFile,
25-
save_xml: Optional[Path] = None,
26-
) -> ET.Element:
27-
"""
28-
Extracts and returns the metadata from the LIF file as a formatted XML Element.
29-
It can be optionally saved as an XML file to the specified file path.
30-
"""
31-
32-
# Use readlif function to get XML metadata
33-
xml_root: ET.Element = file.xml_root # This one for navigating
34-
xml_tree = ET.ElementTree(xml_root) # This one for saving
35-
36-
# Skip saving the metadata if save_xml not provided
37-
if save_xml:
38-
xml_file = str(save_xml) # Convert Path to string
39-
ET.indent(xml_tree, " ") # Format with proper indentation
40-
xml_tree.write(xml_file, encoding="utf-8") # Save
41-
logger.info(f"File metadata saved to {sanitise(xml_file)}")
42-
43-
return xml_root
44-
45-
4618
def get_image_elements(root: ET.Element) -> List[ET.Element]:
4719
"""
4820
Searches the XML metadata recursively to find the nodes tagged as "Element" that

0 commit comments

Comments
 (0)