Skip to content

Commit

Permalink
optimize get streams for BrukerTiffSinglePlaneImagingExtractor (#344)
Browse files Browse the repository at this point in the history
* optimize get streams for `BrukerTiffSinglePlaneImagingExtractor`
  • Loading branch information
h-mayorquin authored Jun 12, 2024
1 parent 40629f1 commit a3d0867
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* Add InscopixImagingExtractor: [#276](https://github.com/catalystneuro/roiextractors/pull/276)
* Updated testing workflows to include python 3.12, m1/intel macos, and dev tests to check neuroconv: [PR #317](https://github.com/catalystneuro/roiextractors/pull/317)
* Added API documentation: [#337](https://github.com/catalystneuro/roiextractors/pull/337)
* Optimized `get_streams` for `BrukerTiffSinglePlaneImagingExtractor` by introducing a static function `get_available_channels` which uses lazy parsing of the XML to fetch the available channels: [#344](https://github.com/catalystneuro/roiextractors/pull/344)

### Fixes

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,8 @@ class BrukerTiffSinglePlaneImagingExtractor(MultiImagingExtractor):

@classmethod
def get_streams(cls, folder_path: PathType) -> dict:
"""Get the available streams from the Bruker TIF image files (.ome.tif) and configuration files (.xml, .env).
"""
Get the available streams from the Bruker TIF image files (.ome.tif) and configuration files (.xml, .env).
Parameters
----------
Expand All @@ -315,13 +316,45 @@ def get_streams(cls, folder_path: PathType) -> dict:
streams: dict
The dictionary of available streams.
"""
channel_names = cls.get_available_channels(folder_path=folder_path)

natsort = get_package(package_name="natsort", installation_instructions="pip install natsort")
xml_root = _parse_xml(folder_path=folder_path)
channel_names = [file.attrib["channelName"] for file in xml_root.findall(".//File")]
unique_channel_names = natsort.natsorted(set(channel_names))
unique_channel_names = natsort.natsorted(channel_names)
streams = dict(channel_streams=unique_channel_names)
return streams

@staticmethod
def get_available_channels(folder_path: PathType) -> set[str]:
"""
Extract set of available channel names from the XML configuration file in the specified folder.
Parameters
----------
folder_path : PathType
The path to the folder containing the XML configuration file. It can be either a string
or a Path object.
Returns
-------
Set[str]
A set of channel names available in the first 'Frame' element found in the XML configuration file.
"""
folder_path = Path(folder_path)
xml_file_path = folder_path / f"{folder_path.name}.xml"
assert xml_file_path.is_file(), f"The XML configuration file is not found at '{folder_path}'."

channel_names = set()
for event, elem in ElementTree.iterparse(xml_file_path, events=("start",)):
if elem.tag == "Frame":
# Get all the sub-elements in this Frame element
for subelem in elem:
if subelem.tag == "File":
channel_names.add(subelem.attrib["channelName"])

break

return channel_names

def __init__(self, folder_path: PathType, stream_name: Optional[str] = None):
"""Create a BrukerTiffSinglePlaneImagingExtractor instance from a folder path that contains the image files.
Expand Down

0 comments on commit a3d0867

Please sign in to comment.