From 14dc9eac7c2cf1a2c1a262d734fbd20578003c78 Mon Sep 17 00:00:00 2001 From: kushalbakshi Date: Fri, 7 Oct 2022 10:58:56 -0500 Subject: [PATCH 01/25] Added PrairieViewReader --- CHANGELOG.md | 3 + element_interface/prairieviewreader.py | 82 ++++++++++++++++++++++++++ element_interface/version.py | 2 +- 3 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 element_interface/prairieviewreader.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 88ec7b2..e0f1a99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ Observes [Semantic Versioning](https://semver.org/spec/v2.0.0.html) standard and [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) convention. +## 0.3.0 - 2022-10-7 ++ Add - Function `prairieview_reader` to parse metadata from Bruker PrarieView acquisition system + ## 0.2.1 - 2022-07-13 + Add - Adopt `black` formatting + Add - Code of Conduct diff --git a/element_interface/prairieviewreader.py b/element_interface/prairieviewreader.py new file mode 100644 index 0000000..103cd46 --- /dev/null +++ b/element_interface/prairieviewreader.py @@ -0,0 +1,82 @@ +import os +import glob +import xml.etree.ElementTree as ET +import numpy as np +from datetime import datetime + + + + +def get_pv_metadata(pvfile): + + xml_file = glob.glob1(os.path.split(pvfile)[0], "*.xml")[0] # Returns 3 xml files. Only need one that contains scan metadata. + + tree = ET.parse(xml_file) + root = tree.getroot() + + bidirectional_scan = False # Does not support bidirectional + + nfields = 1 # Always contains 1 field + + # Get all channels and find unique values + channel_list = [] + channels = root.iterfind(".//Sequence/Frame/File/[@channel]") + for channel in channels: + channel_list.append(int(channel.attrib.get('channel'))) + nchannels = np.unique(channel_list).shape[0] + + # One "Frame" per depth. Gets number of frames in first sequence + planes_list = [] + planes = root.findall(".//Sequence/[@cycle='1']/Frame") + for plane in planes: + planes_list.append(int(plane.attrib.get('index'))) + ndepths = np.unique(planes_list).shape[0] + + # Total frames are displayed as number of "cycles" + nframes = int(root.findall('.//Sequence')[-1].attrib.get('cycle')) + + roi = 1 + + x_coordinate = float(root.find(".//PVStateValue/[@key='currentScanCenter']/IndexedValue/[@index='XAxis']").attrib.get('value')) + y_coordinate = float(root.find(".//PVStateValue/[@key='currentScanCenter']/IndexedValue/[@index='YAxis']").attrib.get('value')) + z_coordinate = float(root.find(".//PVStateValue/[@key='positionCurrent']/SubindexedValues/[@index='ZAxis']/SubindexedValue/[@subindex='0']").attrib.get('value')) + + framerate = np.divide(1, float(root.findall('.//PVStateValue/[@key="framePeriod"]')[0].attrib.get('value'))) # rate = 1/framePeriod + + usec_per_line = float(root.findall(".//PVStateValue/[@key='scanLinePeriod']")[0].attrib.get('value')) * 1000 + + scan_datetime = datetime.strptime(root.attrib.get('date'), "%m/%d/%Y %I:%M:%S %p") + + total_duration = float(root.findall(".//Sequence/Frame")[-1].attrib.get('relativeTime')) + + bidirectionalZ = bool(root.find(".//Sequence").attrib.get('bidirectionalZ')) + + px_height = int(root.findall(".//PVStateValue/[@key='pixelsPerLine']")[0].attrib.get('value')) + px_width = px_height # All PrairieView-acquired images have square dimensions (512 x 512; 1024 x 1024) + + um_per_pixel = float(root.find(".//PVStateValue/[@key='micronsPerPixel']/IndexedValue/[@index='XAxis']").attrib.get('value')) + um_height = float(px_height) * um_per_pixel + um_width = um_height # All PrairieView-acquired images have square dimensions (512 x 512 + + metainfo = dict( + num_fields = nfields, + num_channels = nchannels, + num_planes = ndepths, + num_frames = nframes, + num_rois = roi, + x_pos = x_coordinate, + y_pos = y_coordinate, + z_pos = z_coordinate, + frame_rate = framerate, + bidirectional = bidirectional_scan, + bidirectional_z = bidirectionalZ, + scan_datetime = scan_datetime, + usecs_per_line = usec_per_line, + scan_duration = total_duration, + height_in_pixels = px_height, + width_in_pixels = px_width, + height_in_um = um_height, + width_in_um = um_width, + ) + + return metainfo \ No newline at end of file diff --git a/element_interface/version.py b/element_interface/version.py index 164eb7c..5ca6608 100644 --- a/element_interface/version.py +++ b/element_interface/version.py @@ -1,2 +1,2 @@ """Package metadata""" -__version__ = "0.2.1" +__version__ = "0.3.0" From acf60462735f1e4564d6fcfe89c1890127151ab5 Mon Sep 17 00:00:00 2001 From: kushalbakshi Date: Fri, 7 Oct 2022 11:18:37 -0500 Subject: [PATCH 02/25] Typo fixed in CHAGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e0f1a99..3f2a110 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ Observes [Semantic Versioning](https://semver.org/spec/v2.0.0.html) standard and [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) convention. ## 0.3.0 - 2022-10-7 -+ Add - Function `prairieview_reader` to parse metadata from Bruker PrarieView acquisition system ++ Add - Function `prairieviewreader` to parse metadata from Bruker PrarieView acquisition system ## 0.2.1 - 2022-07-13 + Add - Adopt `black` formatting From 1c4ff2de96ee696d992628dc8950c2377d657433 Mon Sep 17 00:00:00 2001 From: kushalbakshi Date: Mon, 10 Oct 2022 09:42:05 -0500 Subject: [PATCH 03/25] Fixed unit conversion error --- element_interface/prairieviewreader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/element_interface/prairieviewreader.py b/element_interface/prairieviewreader.py index 103cd46..fc4ea5a 100644 --- a/element_interface/prairieviewreader.py +++ b/element_interface/prairieviewreader.py @@ -43,7 +43,7 @@ def get_pv_metadata(pvfile): framerate = np.divide(1, float(root.findall('.//PVStateValue/[@key="framePeriod"]')[0].attrib.get('value'))) # rate = 1/framePeriod - usec_per_line = float(root.findall(".//PVStateValue/[@key='scanLinePeriod']")[0].attrib.get('value')) * 1000 + usec_per_line = float(root.findall(".//PVStateValue/[@key='scanLinePeriod']")[0].attrib.get('value')) * 1e6 # Convert from seconds to microseconds scan_datetime = datetime.strptime(root.attrib.get('date'), "%m/%d/%Y %I:%M:%S %p") From f74009fd82e04a2f276989a4ab10190cd0fc7548 Mon Sep 17 00:00:00 2001 From: kushalbakshi Date: Mon, 10 Oct 2022 11:22:06 -0500 Subject: [PATCH 04/25] Added robust search for metadata file --- element_interface/prairieviewreader.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/element_interface/prairieviewreader.py b/element_interface/prairieviewreader.py index fc4ea5a..3277cb6 100644 --- a/element_interface/prairieviewreader.py +++ b/element_interface/prairieviewreader.py @@ -1,4 +1,4 @@ -import os +import pathlib import glob import xml.etree.ElementTree as ET import numpy as np @@ -7,12 +7,17 @@ -def get_pv_metadata(pvfile): +def get_pv_metadata(pvtiffile): - xml_file = glob.glob1(os.path.split(pvfile)[0], "*.xml")[0] # Returns 3 xml files. Only need one that contains scan metadata. + xml_files_list = glob.glob1(pathlib.Path(pvtiffile).parent, '*.xml') # May return multiple xml files. Only need one that contains scan metadata. - tree = ET.parse(xml_file) - root = tree.getroot() + for xml_file in xml_files_list: + tree = ET.parse(pathlib.Path.joinpath(pvtiffile.parent, xml_file)) + root = tree.getroot() + if root.find(".//Sequence"): + break + else: + raise FileNotFoundError(f'No PrarieView metadata XML file found at {pvtiffile.parent}') bidirectional_scan = False # Does not support bidirectional From 5f7bf0e4ba8b6d001fe776c66bfa5c8b82b8be25 Mon Sep 17 00:00:00 2001 From: kushalbakshi Date: Mon, 10 Oct 2022 14:11:18 -0500 Subject: [PATCH 05/25] Extract field x, y, z metadata + black formatting --- element_interface/prairieviewreader.py | 144 ++++++++++++++++--------- 1 file changed, 96 insertions(+), 48 deletions(-) diff --git a/element_interface/prairieviewreader.py b/element_interface/prairieviewreader.py index 3277cb6..4978596 100644 --- a/element_interface/prairieviewreader.py +++ b/element_interface/prairieviewreader.py @@ -5,83 +5,131 @@ from datetime import datetime - - def get_pv_metadata(pvtiffile): - - xml_files_list = glob.glob1(pathlib.Path(pvtiffile).parent, '*.xml') # May return multiple xml files. Only need one that contains scan metadata. + xml_files_list = glob.glob1( + pathlib.Path(pvtiffile).parent, "*.xml" + ) # May return multiple xml files. Only need one that contains scan metadata. for xml_file in xml_files_list: - tree = ET.parse(pathlib.Path.joinpath(pvtiffile.parent, xml_file)) + tree = ET.parse(pathlib.Path.joinpath(pvtiffile.parent, xml_file)) root = tree.getroot() if root.find(".//Sequence"): break else: - raise FileNotFoundError(f'No PrarieView metadata XML file found at {pvtiffile.parent}') - + raise FileNotFoundError( + f"No PrarieView metadata XML file found at {pvtiffile.parent}" + ) + bidirectional_scan = False # Does not support bidirectional - + nfields = 1 # Always contains 1 field - + # Get all channels and find unique values channel_list = [] channels = root.iterfind(".//Sequence/Frame/File/[@channel]") for channel in channels: - channel_list.append(int(channel.attrib.get('channel'))) + channel_list.append(int(channel.attrib.get("channel"))) nchannels = np.unique(channel_list).shape[0] - + # One "Frame" per depth. Gets number of frames in first sequence planes_list = [] planes = root.findall(".//Sequence/[@cycle='1']/Frame") for plane in planes: - planes_list.append(int(plane.attrib.get('index'))) + planes_list.append(int(plane.attrib.get("index"))) ndepths = np.unique(planes_list).shape[0] - + # Total frames are displayed as number of "cycles" - nframes = int(root.findall('.//Sequence')[-1].attrib.get('cycle')) - + nframes = int(root.findall(".//Sequence")[-1].attrib.get("cycle")) + roi = 1 - - x_coordinate = float(root.find(".//PVStateValue/[@key='currentScanCenter']/IndexedValue/[@index='XAxis']").attrib.get('value')) - y_coordinate = float(root.find(".//PVStateValue/[@key='currentScanCenter']/IndexedValue/[@index='YAxis']").attrib.get('value')) - z_coordinate = float(root.find(".//PVStateValue/[@key='positionCurrent']/SubindexedValues/[@index='ZAxis']/SubindexedValue/[@subindex='0']").attrib.get('value')) - framerate = np.divide(1, float(root.findall('.//PVStateValue/[@key="framePeriod"]')[0].attrib.get('value'))) # rate = 1/framePeriod + x_coordinate = float( + root.find( + ".//PVStateValue/[@key='currentScanCenter']/IndexedValue/[@index='XAxis']" + ).attrib.get("value") + ) + y_coordinate = float( + root.find( + ".//PVStateValue/[@key='currentScanCenter']/IndexedValue/[@index='YAxis']" + ).attrib.get("value") + ) + z_coordinate = float( + root.find( + ".//PVStateValue/[@key='positionCurrent']/SubindexedValues/[@index='ZAxis']/SubindexedValue/[@subindex='0']" + ).attrib.get("value") + ) + + framerate = np.divide( + 1, + float( + root.findall('.//PVStateValue/[@key="framePeriod"]')[0].attrib.get("value") + ), + ) # rate = 1/framePeriod - usec_per_line = float(root.findall(".//PVStateValue/[@key='scanLinePeriod']")[0].attrib.get('value')) * 1e6 # Convert from seconds to microseconds + usec_per_line = ( + float( + root.findall(".//PVStateValue/[@key='scanLinePeriod']")[0].attrib.get("value")) * 1e6 + ) # Convert from seconds to microseconds - scan_datetime = datetime.strptime(root.attrib.get('date'), "%m/%d/%Y %I:%M:%S %p") + scan_datetime = datetime.strptime(root.attrib.get("date"), "%m/%d/%Y %I:%M:%S %p") - total_duration = float(root.findall(".//Sequence/Frame")[-1].attrib.get('relativeTime')) + total_duration = float( + root.findall(".//Sequence/Frame")[-1].attrib.get("relativeTime") + ) - bidirectionalZ = bool(root.find(".//Sequence").attrib.get('bidirectionalZ')) + bidirectionalZ = bool(root.find(".//Sequence").attrib.get("bidirectionalZ")) - px_height = int(root.findall(".//PVStateValue/[@key='pixelsPerLine']")[0].attrib.get('value')) - px_width = px_height # All PrairieView-acquired images have square dimensions (512 x 512; 1024 x 1024) - - um_per_pixel = float(root.find(".//PVStateValue/[@key='micronsPerPixel']/IndexedValue/[@index='XAxis']").attrib.get('value')) + px_height = int( + root.findall(".//PVStateValue/[@key='pixelsPerLine']")[0].attrib.get("value") + ) + px_width = px_height # All PrairieView-acquired images have square dimensions (512 x 512; 1024 x 1024) + + um_per_pixel = float( + root.find( + ".//PVStateValue/[@key='micronsPerPixel']/IndexedValue/[@index='XAxis']" + ).attrib.get("value") + ) um_height = float(px_height) * um_per_pixel - um_width = um_height # All PrairieView-acquired images have square dimensions (512 x 512 + um_width = ( + um_height # All PrairieView-acquired images have square dimensions (512 x 512) + ) + + x_field = x_coordinate # X-coordinates do not change during scan + y_field = y_coordinate # Y-coordinates do not change during scan + z_min = root.findall( + ".//Sequence/[@cycle='1']/Frame/PVStateShard/PVStateValue/[@key='positionCurrent']/SubindexedValues/SubindexedValue/[@subindex='0']" + )[0].attrib.get("value") + z_max = root.findall( + ".//Sequence/[@cycle='1']/Frame/PVStateShard/PVStateValue/[@key='positionCurrent']/SubindexedValues/SubindexedValue/[@subindex='0']" + )[-1].attrib.get("value") + z_step = root.find( + ".//PVStateShard/PVStateValue/[@key='micronsPerPixel']/IndexedValue/[@index='ZAxis']" + ).attrib.get("value") + z_fields = np.arange(z_min, z_max + 1, z_step) + assert z_fields.shape[0] == ndepths metainfo = dict( - num_fields = nfields, - num_channels = nchannels, - num_planes = ndepths, - num_frames = nframes, - num_rois = roi, - x_pos = x_coordinate, - y_pos = y_coordinate, - z_pos = z_coordinate, - frame_rate = framerate, - bidirectional = bidirectional_scan, - bidirectional_z = bidirectionalZ, - scan_datetime = scan_datetime, - usecs_per_line = usec_per_line, - scan_duration = total_duration, - height_in_pixels = px_height, - width_in_pixels = px_width, - height_in_um = um_height, - width_in_um = um_width, + num_fields=nfields, + num_channels=nchannels, + num_planes=ndepths, + num_frames=nframes, + num_rois=roi, + x_pos=x_coordinate, + y_pos=y_coordinate, + z_pos=z_coordinate, + frame_rate=framerate, + bidirectional=bidirectional_scan, + bidirectional_z=bidirectionalZ, + scan_datetime=scan_datetime, + usecs_per_line=usec_per_line, + scan_duration=total_duration, + height_in_pixels=px_height, + width_in_pixels=px_width, + height_in_um=um_height, + width_in_um=um_width, + fieldX=x_field, + fieldY=y_field, + fieldZ=z_fields, ) - return metainfo \ No newline at end of file + return metainfo From 60dccce46d32c1873729660f1926f503566a5c32 Mon Sep 17 00:00:00 2001 From: kushalbakshi Date: Mon, 10 Oct 2022 14:45:47 -0500 Subject: [PATCH 06/25] Added function docstring --- element_interface/prairieviewreader.py | 29 +++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/element_interface/prairieviewreader.py b/element_interface/prairieviewreader.py index 4978596..dcd1fcd 100644 --- a/element_interface/prairieviewreader.py +++ b/element_interface/prairieviewreader.py @@ -6,6 +6,29 @@ def get_pv_metadata(pvtiffile): + """Extract metadata for calcium imaging scans generated by Bruker Systems PrairieView acquisition software. + + The PrairieView software generates one .ome.tif imaging file per frame acquired. The metadata for all frames is contained one .xml file. This function locates the .xml file and generates a dictionary necessary to populate the DataJoint ScanInfo and Field tables. + + PrairieView works with resonance scanners with a single field. + + PrairieView does not support bidirectional x and y scanning. + + ROI information is not contained in the .xml file. + + All images generated using PrairieView have square dimensions (e.g. 512x512). + + + Args: + pvtiffile: An absolute path to the .ome.tif image file. + + Raises: + FileNotFoundError: No .xml file containing information about the acquired scan was found at path in parent directory at `pvtiffile`. + + Returns: + metainfo: A dict mapping keys to corresponding metadata values fetched from the .xml file. + """ + xml_files_list = glob.glob1( pathlib.Path(pvtiffile).parent, "*.xml" ) # May return multiple xml files. Only need one that contains scan metadata. @@ -68,7 +91,11 @@ def get_pv_metadata(pvtiffile): usec_per_line = ( float( - root.findall(".//PVStateValue/[@key='scanLinePeriod']")[0].attrib.get("value")) * 1e6 + root.findall(".//PVStateValue/[@key='scanLinePeriod']")[0].attrib.get( + "value" + ) + ) + * 1e6 ) # Convert from seconds to microseconds scan_datetime = datetime.strptime(root.attrib.get("date"), "%m/%d/%Y %I:%M:%S %p") From 64068507a707253b799dfdaf1243edd87f7353a3 Mon Sep 17 00:00:00 2001 From: Kushal Bakshi <52367253+kushalbakshi@users.noreply.github.com> Date: Mon, 10 Oct 2022 14:51:55 -0500 Subject: [PATCH 07/25] Update element_interface/prairieviewreader.py Co-authored-by: Thinh Nguyen --- element_interface/prairieviewreader.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/element_interface/prairieviewreader.py b/element_interface/prairieviewreader.py index dcd1fcd..1a601ca 100644 --- a/element_interface/prairieviewreader.py +++ b/element_interface/prairieviewreader.py @@ -29,12 +29,10 @@ def get_pv_metadata(pvtiffile): metainfo: A dict mapping keys to corresponding metadata values fetched from the .xml file. """ - xml_files_list = glob.glob1( - pathlib.Path(pvtiffile).parent, "*.xml" - ) # May return multiple xml files. Only need one that contains scan metadata. + xml_files = pathlib.Path(pvtiffile).parent.glob("*.xml") # May return multiple xml files. Only need one that contains scan metadata. - for xml_file in xml_files_list: - tree = ET.parse(pathlib.Path.joinpath(pvtiffile.parent, xml_file)) + for xml_file in xml_files : + tree = ET.parse(xml_file) root = tree.getroot() if root.find(".//Sequence"): break From d43e3238f272cfc8be4985efdae1c30fef00cec4 Mon Sep 17 00:00:00 2001 From: kushalbakshi Date: Mon, 10 Oct 2022 15:26:21 -0500 Subject: [PATCH 08/25] Updated CHANGELOG --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f2a110..8245aa0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,4 +22,7 @@ Observes [Semantic Versioning](https://semver.org/spec/v2.0.0.html) standard and + Change - Rename the package `element-data-loader` to `element-interface`. ## 0.1.0a0 - 2021-06-21 -+ Add - Readers for: `ScanImage`, `Suite2p`, `CaImAn`. \ No newline at end of file ++ Add - Readers for: `ScanImage`, `Suite2p`, `CaImAn`. + +[0.3.0]: https://github.com/datajoint/element-interface/compare/0.2.1...0.3.0 +[0.2.1]: https://github.com/datajoint/element-interface/releases/tags/0.2.1 \ No newline at end of file From 189bea7bd9aa6fd28088be004f1b4ba8d077c1ca Mon Sep 17 00:00:00 2001 From: kushalbakshi Date: Mon, 10 Oct 2022 15:57:21 -0500 Subject: [PATCH 09/25] Fixed typo in CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8245aa0..fcb9bc7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,4 +25,4 @@ Observes [Semantic Versioning](https://semver.org/spec/v2.0.0.html) standard and + Add - Readers for: `ScanImage`, `Suite2p`, `CaImAn`. [0.3.0]: https://github.com/datajoint/element-interface/compare/0.2.1...0.3.0 -[0.2.1]: https://github.com/datajoint/element-interface/releases/tags/0.2.1 \ No newline at end of file +[0.2.1]: https://github.com/datajoint/element-interface/releases/tag/0.2.1 \ No newline at end of file From b068c9c69e62d1ccdb4763c592356d5da94f11df Mon Sep 17 00:00:00 2001 From: kushalbakshi Date: Mon, 10 Oct 2022 17:02:18 -0500 Subject: [PATCH 10/25] Updated nframes in prairieviewreader.py --- element_interface/prairieviewreader.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/element_interface/prairieviewreader.py b/element_interface/prairieviewreader.py index 1a601ca..36bde02 100644 --- a/element_interface/prairieviewreader.py +++ b/element_interface/prairieviewreader.py @@ -1,5 +1,4 @@ import pathlib -import glob import xml.etree.ElementTree as ET import numpy as np from datetime import datetime @@ -60,7 +59,7 @@ def get_pv_metadata(pvtiffile): ndepths = np.unique(planes_list).shape[0] # Total frames are displayed as number of "cycles" - nframes = int(root.findall(".//Sequence")[-1].attrib.get("cycle")) + nframes = len(root.findall(".//Sequence/Frame")) roi = 1 From a8b16418681e2b0721273dbab64a092af50a7e71 Mon Sep 17 00:00:00 2001 From: Kushal Bakshi <52367253+kushalbakshi@users.noreply.github.com> Date: Mon, 10 Oct 2022 17:06:53 -0500 Subject: [PATCH 11/25] Update CHANGELOG.md --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fcb9bc7..073af37 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,5 +24,4 @@ Observes [Semantic Versioning](https://semver.org/spec/v2.0.0.html) standard and ## 0.1.0a0 - 2021-06-21 + Add - Readers for: `ScanImage`, `Suite2p`, `CaImAn`. -[0.3.0]: https://github.com/datajoint/element-interface/compare/0.2.1...0.3.0 -[0.2.1]: https://github.com/datajoint/element-interface/releases/tag/0.2.1 \ No newline at end of file +[0.3.0]: https://github.com/datajoint/element-interface/releases/tag/0.3.0 From ae290e5df229f8920c038d009d1394fa3ceaed57 Mon Sep 17 00:00:00 2001 From: Kushal Bakshi <52367253+kushalbakshi@users.noreply.github.com> Date: Tue, 11 Oct 2022 11:18:28 -0500 Subject: [PATCH 12/25] Update CHANGELOG.md Co-authored-by: Kabilar Gunalan --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 073af37..1f205b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ Observes [Semantic Versioning](https://semver.org/spec/v2.0.0.html) standard and [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) convention. -## 0.3.0 - 2022-10-7 +## [0.3.0] - 2022-10-7 + Add - Function `prairieviewreader` to parse metadata from Bruker PrarieView acquisition system ## 0.2.1 - 2022-07-13 From ec01b7dfa4351e77c8593e7877df01563e15949d Mon Sep 17 00:00:00 2001 From: Kushal Bakshi <52367253+kushalbakshi@users.noreply.github.com> Date: Wed, 12 Oct 2022 17:11:19 -0500 Subject: [PATCH 13/25] Update element_interface/prairieviewreader.py Co-authored-by: Dimitri Yatsenko --- element_interface/prairieviewreader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/element_interface/prairieviewreader.py b/element_interface/prairieviewreader.py index 36bde02..440f85c 100644 --- a/element_interface/prairieviewreader.py +++ b/element_interface/prairieviewreader.py @@ -49,7 +49,7 @@ def get_pv_metadata(pvtiffile): channels = root.iterfind(".//Sequence/Frame/File/[@channel]") for channel in channels: channel_list.append(int(channel.attrib.get("channel"))) - nchannels = np.unique(channel_list).shape[0] + nchannels = len(set(channel_list)) # One "Frame" per depth. Gets number of frames in first sequence planes_list = [] From 5059705217e2707c75301305a63920670c3fdddf Mon Sep 17 00:00:00 2001 From: Kushal Bakshi <52367253+kushalbakshi@users.noreply.github.com> Date: Wed, 12 Oct 2022 17:11:29 -0500 Subject: [PATCH 14/25] Update element_interface/prairieviewreader.py Co-authored-by: Dimitri Yatsenko --- element_interface/prairieviewreader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/element_interface/prairieviewreader.py b/element_interface/prairieviewreader.py index 440f85c..b006aa5 100644 --- a/element_interface/prairieviewreader.py +++ b/element_interface/prairieviewreader.py @@ -56,7 +56,7 @@ def get_pv_metadata(pvtiffile): planes = root.findall(".//Sequence/[@cycle='1']/Frame") for plane in planes: planes_list.append(int(plane.attrib.get("index"))) - ndepths = np.unique(planes_list).shape[0] + ndepths = len(set(planes)) # Total frames are displayed as number of "cycles" nframes = len(root.findall(".//Sequence/Frame")) From 7e4b2d99541e3bb0b4a740858cb7a004b7e1f6f4 Mon Sep 17 00:00:00 2001 From: Kushal Bakshi <52367253+kushalbakshi@users.noreply.github.com> Date: Wed, 12 Oct 2022 17:14:52 -0500 Subject: [PATCH 15/25] Update element_interface/prairieviewreader.py Co-authored-by: Dimitri Yatsenko --- element_interface/prairieviewreader.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/element_interface/prairieviewreader.py b/element_interface/prairieviewreader.py index b006aa5..adb00c5 100644 --- a/element_interface/prairieviewreader.py +++ b/element_interface/prairieviewreader.py @@ -52,10 +52,10 @@ def get_pv_metadata(pvtiffile): nchannels = len(set(channel_list)) # One "Frame" per depth. Gets number of frames in first sequence - planes_list = [] - planes = root.findall(".//Sequence/[@cycle='1']/Frame") - for plane in planes: - planes_list.append(int(plane.attrib.get("index"))) + planes = [ + int(plane.attrib.get("index")) + for plane in root.findall(".//Sequence/[@cycle='1']/Frame") + ] ndepths = len(set(planes)) # Total frames are displayed as number of "cycles" From fffc8eff5c6b19f4355275d0aa55898a1c7cde4f Mon Sep 17 00:00:00 2001 From: Kushal Bakshi <52367253+kushalbakshi@users.noreply.github.com> Date: Wed, 12 Oct 2022 17:17:27 -0500 Subject: [PATCH 16/25] Update element_interface/prairieviewreader.py Co-authored-by: Dimitri Yatsenko --- element_interface/prairieviewreader.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/element_interface/prairieviewreader.py b/element_interface/prairieviewreader.py index adb00c5..982293c 100644 --- a/element_interface/prairieviewreader.py +++ b/element_interface/prairieviewreader.py @@ -79,12 +79,8 @@ def get_pv_metadata(pvtiffile): ).attrib.get("value") ) - framerate = np.divide( - 1, - float( - root.findall('.//PVStateValue/[@key="framePeriod"]')[0].attrib.get("value") - ), - ) # rate = 1/framePeriod + framerate = 1 / float( + root.findall('.//PVStateValue/[@key="framePeriod"]')[0].attrib.get("value"))) # rate = 1/framePeriod usec_per_line = ( float( From 21779bde338d4c2ce23048f725a66a8a5f875db6 Mon Sep 17 00:00:00 2001 From: Kushal Bakshi <52367253+kushalbakshi@users.noreply.github.com> Date: Wed, 12 Oct 2022 17:17:45 -0500 Subject: [PATCH 17/25] Update element_interface/prairieviewreader.py Co-authored-by: Dimitri Yatsenko --- element_interface/prairieviewreader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/element_interface/prairieviewreader.py b/element_interface/prairieviewreader.py index 982293c..3c1efc2 100644 --- a/element_interface/prairieviewreader.py +++ b/element_interface/prairieviewreader.py @@ -126,7 +126,7 @@ def get_pv_metadata(pvtiffile): ".//PVStateShard/PVStateValue/[@key='micronsPerPixel']/IndexedValue/[@index='ZAxis']" ).attrib.get("value") z_fields = np.arange(z_min, z_max + 1, z_step) - assert z_fields.shape[0] == ndepths + assert z_fields.size == ndepths metainfo = dict( num_fields=nfields, From 4f6923357e93a38f9938572ba2837f1cefbf5c0a Mon Sep 17 00:00:00 2001 From: Kushal Bakshi <52367253+kushalbakshi@users.noreply.github.com> Date: Wed, 12 Oct 2022 17:18:13 -0500 Subject: [PATCH 18/25] Update element_interface/prairieviewreader.py Co-authored-by: Dimitri Yatsenko --- element_interface/prairieviewreader.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/element_interface/prairieviewreader.py b/element_interface/prairieviewreader.py index 3c1efc2..cb9ad31 100644 --- a/element_interface/prairieviewreader.py +++ b/element_interface/prairieviewreader.py @@ -45,10 +45,10 @@ def get_pv_metadata(pvtiffile): nfields = 1 # Always contains 1 field # Get all channels and find unique values - channel_list = [] - channels = root.iterfind(".//Sequence/Frame/File/[@channel]") - for channel in channels: - channel_list.append(int(channel.attrib.get("channel"))) + channel_list = [ + int(channel.attrib.get("channel")) + for channel in root.iterfind(".//Sequence/Frame/File/[@channel]") + ] nchannels = len(set(channel_list)) # One "Frame" per depth. Gets number of frames in first sequence From 512e8193388d51ac04e8a718bb3f49a166e81425 Mon Sep 17 00:00:00 2001 From: Kushal Bakshi <52367253+kushalbakshi@users.noreply.github.com> Date: Wed, 12 Oct 2022 17:18:51 -0500 Subject: [PATCH 19/25] Update element_interface/prairieviewreader.py Co-authored-by: Dimitri Yatsenko --- element_interface/prairieviewreader.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/element_interface/prairieviewreader.py b/element_interface/prairieviewreader.py index cb9ad31..a251f7a 100644 --- a/element_interface/prairieviewreader.py +++ b/element_interface/prairieviewreader.py @@ -109,10 +109,8 @@ def get_pv_metadata(pvtiffile): ".//PVStateValue/[@key='micronsPerPixel']/IndexedValue/[@index='XAxis']" ).attrib.get("value") ) - um_height = float(px_height) * um_per_pixel - um_width = ( - um_height # All PrairieView-acquired images have square dimensions (512 x 512) - ) + # All PrairieView-acquired images have square dimensions + um_height = um_width = float(px_height) * um_per_pixel x_field = x_coordinate # X-coordinates do not change during scan y_field = y_coordinate # Y-coordinates do not change during scan From 8ce5de0150f1dafcd30e1cb54e5365e358efccb1 Mon Sep 17 00:00:00 2001 From: Kushal Bakshi <52367253+kushalbakshi@users.noreply.github.com> Date: Wed, 12 Oct 2022 17:19:26 -0500 Subject: [PATCH 20/25] Update element_interface/prairieviewreader.py Co-authored-by: Dimitri Yatsenko --- element_interface/prairieviewreader.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/element_interface/prairieviewreader.py b/element_interface/prairieviewreader.py index a251f7a..7b526d4 100644 --- a/element_interface/prairieviewreader.py +++ b/element_interface/prairieviewreader.py @@ -112,8 +112,7 @@ def get_pv_metadata(pvtiffile): # All PrairieView-acquired images have square dimensions um_height = um_width = float(px_height) * um_per_pixel - x_field = x_coordinate # X-coordinates do not change during scan - y_field = y_coordinate # Y-coordinates do not change during scan + x_field, y_field = x_coordinate, y_coordinate # coordinates do not change during scan z_min = root.findall( ".//Sequence/[@cycle='1']/Frame/PVStateShard/PVStateValue/[@key='positionCurrent']/SubindexedValues/SubindexedValue/[@subindex='0']" )[0].attrib.get("value") From 9faaa94d33050767835de10db9a7c3c7158e78ab Mon Sep 17 00:00:00 2001 From: kushalbakshi Date: Wed, 12 Oct 2022 17:21:56 -0500 Subject: [PATCH 21/25] Added fixes after local test --- element_interface/prairieviewreader.py | 58 +++++++++++++++----------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/element_interface/prairieviewreader.py b/element_interface/prairieviewreader.py index 36bde02..92a384d 100644 --- a/element_interface/prairieviewreader.py +++ b/element_interface/prairieviewreader.py @@ -28,9 +28,10 @@ def get_pv_metadata(pvtiffile): metainfo: A dict mapping keys to corresponding metadata values fetched from the .xml file. """ - xml_files = pathlib.Path(pvtiffile).parent.glob("*.xml") # May return multiple xml files. Only need one that contains scan metadata. + # May return multiple xml files. Only need one that contains scan metadata. + xml_files = pathlib.Path(pvtiffile).parent.glob("*.xml") - for xml_file in xml_files : + for xml_file in xml_files: tree = ET.parse(xml_file) root = tree.getroot() if root.find(".//Sequence"): @@ -42,27 +43,27 @@ def get_pv_metadata(pvtiffile): bidirectional_scan = False # Does not support bidirectional - nfields = 1 # Always contains 1 field + n_fields = 1 # Always contains 1 field # Get all channels and find unique values channel_list = [] channels = root.iterfind(".//Sequence/Frame/File/[@channel]") for channel in channels: channel_list.append(int(channel.attrib.get("channel"))) - nchannels = np.unique(channel_list).shape[0] + n_channels = np.unique(channel_list).shape[0] # One "Frame" per depth. Gets number of frames in first sequence planes_list = [] planes = root.findall(".//Sequence/[@cycle='1']/Frame") for plane in planes: planes_list.append(int(plane.attrib.get("index"))) - ndepths = np.unique(planes_list).shape[0] + n_depths = np.unique(planes_list).shape[0] # Total frames are displayed as number of "cycles" - nframes = len(root.findall(".//Sequence/Frame")) + n_frames = len(root.findall(".//Sequence/Frame")) roi = 1 - + # x and y coordinate values x_coordinate = float( root.find( ".//PVStateValue/[@key='currentScanCenter']/IndexedValue/[@index='XAxis']" @@ -82,7 +83,8 @@ def get_pv_metadata(pvtiffile): framerate = np.divide( 1, float( - root.findall('.//PVStateValue/[@key="framePeriod"]')[0].attrib.get("value") + root.findall( + './/PVStateValue/[@key="framePeriod"]')[0].attrib.get("value") ), ) # rate = 1/framePeriod @@ -95,18 +97,22 @@ def get_pv_metadata(pvtiffile): * 1e6 ) # Convert from seconds to microseconds - scan_datetime = datetime.strptime(root.attrib.get("date"), "%m/%d/%Y %I:%M:%S %p") + scan_datetime = datetime.strptime( + root.attrib.get("date"), "%m/%d/%Y %I:%M:%S %p") total_duration = float( root.findall(".//Sequence/Frame")[-1].attrib.get("relativeTime") ) - bidirectionalZ = bool(root.find(".//Sequence").attrib.get("bidirectionalZ")) + bidirection_z = bool( + root.find(".//Sequence").attrib.get("bidirectionalZ")) px_height = int( - root.findall(".//PVStateValue/[@key='pixelsPerLine']")[0].attrib.get("value") + root.findall( + ".//PVStateValue/[@key='pixelsPerLine']")[0].attrib.get("value") ) - px_width = px_height # All PrairieView-acquired images have square dimensions (512 x 512; 1024 x 1024) + # All PrairieView-acquired images have square dimensions (512 x 512; 1024 x 1024) + px_width = px_height um_per_pixel = float( root.find( @@ -115,35 +121,37 @@ def get_pv_metadata(pvtiffile): ) um_height = float(px_height) * um_per_pixel um_width = ( - um_height # All PrairieView-acquired images have square dimensions (512 x 512) + # All PrairieView-acquired images have square dimensions (512 x 512) + um_height ) x_field = x_coordinate # X-coordinates do not change during scan y_field = y_coordinate # Y-coordinates do not change during scan - z_min = root.findall( + + z_min = float(root.findall( ".//Sequence/[@cycle='1']/Frame/PVStateShard/PVStateValue/[@key='positionCurrent']/SubindexedValues/SubindexedValue/[@subindex='0']" - )[0].attrib.get("value") - z_max = root.findall( + )[0].attrib.get("value")) + z_max = float(root.findall( ".//Sequence/[@cycle='1']/Frame/PVStateShard/PVStateValue/[@key='positionCurrent']/SubindexedValues/SubindexedValue/[@subindex='0']" - )[-1].attrib.get("value") - z_step = root.find( + )[-1].attrib.get("value")) + z_step = float(root.find( ".//PVStateShard/PVStateValue/[@key='micronsPerPixel']/IndexedValue/[@index='ZAxis']" - ).attrib.get("value") + ).attrib.get("value")) z_fields = np.arange(z_min, z_max + 1, z_step) - assert z_fields.shape[0] == ndepths + assert z_fields.shape[0] == n_depths metainfo = dict( - num_fields=nfields, - num_channels=nchannels, - num_planes=ndepths, - num_frames=nframes, + num_fields=n_fields, + num_channels=n_channels, + num_planes=n_depths, + num_frames=n_frames, num_rois=roi, x_pos=x_coordinate, y_pos=y_coordinate, z_pos=z_coordinate, frame_rate=framerate, bidirectional=bidirectional_scan, - bidirectional_z=bidirectionalZ, + bidirectional_z=bidirection_z, scan_datetime=scan_datetime, usecs_per_line=usec_per_line, scan_duration=total_duration, From c17d55119249c303bc5397a8a54ee9470858e337 Mon Sep 17 00:00:00 2001 From: kushalbakshi Date: Thu, 13 Oct 2022 09:38:12 -0500 Subject: [PATCH 22/25] Syntax + styling changes --- element_interface/prairieviewreader.py | 41 ++++++++++---------------- 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/element_interface/prairieviewreader.py b/element_interface/prairieviewreader.py index 92a384d..87bd50d 100644 --- a/element_interface/prairieviewreader.py +++ b/element_interface/prairieviewreader.py @@ -46,18 +46,18 @@ def get_pv_metadata(pvtiffile): n_fields = 1 # Always contains 1 field # Get all channels and find unique values - channel_list = [] - channels = root.iterfind(".//Sequence/Frame/File/[@channel]") - for channel in channels: - channel_list.append(int(channel.attrib.get("channel"))) - n_channels = np.unique(channel_list).shape[0] + channel_list = [ + int(channel.attrib.get("channel")) + for channel in root.iterfind(".//Sequence/Frame/File/[@channel]") + ] + n_channels = len(set(channel_list)) # One "Frame" per depth. Gets number of frames in first sequence - planes_list = [] - planes = root.findall(".//Sequence/[@cycle='1']/Frame") - for plane in planes: - planes_list.append(int(plane.attrib.get("index"))) - n_depths = np.unique(planes_list).shape[0] + planes = [ + int(plane.attrib.get("index")) + for plane in root.findall(".//Sequence/[@cycle='1']/Frame") + ] + n_depths = len(set(planes)) # Total frames are displayed as number of "cycles" n_frames = len(root.findall(".//Sequence/Frame")) @@ -80,13 +80,8 @@ def get_pv_metadata(pvtiffile): ).attrib.get("value") ) - framerate = np.divide( - 1, - float( - root.findall( - './/PVStateValue/[@key="framePeriod"]')[0].attrib.get("value") - ), - ) # rate = 1/framePeriod + framerate = 1 / float( + root.findall('.//PVStateValue/[@key="framePeriod"]')[0].attrib.get("value"))) # rate = 1/framePeriod usec_per_line = ( float( @@ -119,14 +114,10 @@ def get_pv_metadata(pvtiffile): ".//PVStateValue/[@key='micronsPerPixel']/IndexedValue/[@index='XAxis']" ).attrib.get("value") ) - um_height = float(px_height) * um_per_pixel - um_width = ( - # All PrairieView-acquired images have square dimensions (512 x 512) - um_height - ) + # All PrairieView-acquired images have square dimensions + um_height = um_width = float(px_height) * um_per_pixel - x_field = x_coordinate # X-coordinates do not change during scan - y_field = y_coordinate # Y-coordinates do not change during scan + x_field, y_field = x_coordinate, y_coordinate # coordinates do not change during scan z_min = float(root.findall( ".//Sequence/[@cycle='1']/Frame/PVStateShard/PVStateValue/[@key='positionCurrent']/SubindexedValues/SubindexedValue/[@subindex='0']" @@ -138,7 +129,7 @@ def get_pv_metadata(pvtiffile): ".//PVStateShard/PVStateValue/[@key='micronsPerPixel']/IndexedValue/[@index='ZAxis']" ).attrib.get("value")) z_fields = np.arange(z_min, z_max + 1, z_step) - assert z_fields.shape[0] == n_depths + assert z_fields.size == n_depths metainfo = dict( num_fields=n_fields, From 37749994ed8979792d106b20ca84d3a96c17e165 Mon Sep 17 00:00:00 2001 From: kushalbakshi Date: Thu, 13 Oct 2022 09:46:34 -0500 Subject: [PATCH 23/25] Fix typo in prairieviewreader.py --- element_interface/prairieviewreader.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/element_interface/prairieviewreader.py b/element_interface/prairieviewreader.py index 87bd50d..5f6412c 100644 --- a/element_interface/prairieviewreader.py +++ b/element_interface/prairieviewreader.py @@ -54,7 +54,7 @@ def get_pv_metadata(pvtiffile): # One "Frame" per depth. Gets number of frames in first sequence planes = [ - int(plane.attrib.get("index")) + int(plane.attrib.get("index")) for plane in root.findall(".//Sequence/[@cycle='1']/Frame") ] n_depths = len(set(planes)) @@ -63,7 +63,7 @@ def get_pv_metadata(pvtiffile): n_frames = len(root.findall(".//Sequence/Frame")) roi = 1 - # x and y coordinate values + # x and y coordinate values x_coordinate = float( root.find( ".//PVStateValue/[@key='currentScanCenter']/IndexedValue/[@index='XAxis']" @@ -81,7 +81,7 @@ def get_pv_metadata(pvtiffile): ) framerate = 1 / float( - root.findall('.//PVStateValue/[@key="framePeriod"]')[0].attrib.get("value"))) # rate = 1/framePeriod + root.findall('.//PVStateValue/[@key="framePeriod"]')[0].attrib.get("value")) # rate = 1/framePeriod usec_per_line = ( float( @@ -117,8 +117,9 @@ def get_pv_metadata(pvtiffile): # All PrairieView-acquired images have square dimensions um_height = um_width = float(px_height) * um_per_pixel - x_field, y_field = x_coordinate, y_coordinate # coordinates do not change during scan - + # coordinates do not change during scan + x_field, y_field = x_coordinate, y_coordinate + z_min = float(root.findall( ".//Sequence/[@cycle='1']/Frame/PVStateShard/PVStateValue/[@key='positionCurrent']/SubindexedValues/SubindexedValue/[@subindex='0']" )[0].attrib.get("value")) From 9f7d52d81321fb2aa3380f43fafc395e1e966fb1 Mon Sep 17 00:00:00 2001 From: kushalbakshi Date: Thu, 13 Oct 2022 09:53:06 -0500 Subject: [PATCH 24/25] Minor styling updates in prairieviewreader.py --- element_interface/prairieviewreader.py | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/element_interface/prairieviewreader.py b/element_interface/prairieviewreader.py index 5f6412c..6d4fd90 100644 --- a/element_interface/prairieviewreader.py +++ b/element_interface/prairieviewreader.py @@ -59,11 +59,10 @@ def get_pv_metadata(pvtiffile): ] n_depths = len(set(planes)) - # Total frames are displayed as number of "cycles" n_frames = len(root.findall(".//Sequence/Frame")) roi = 1 - # x and y coordinate values + # x and y coordinate values for the center of the field x_coordinate = float( root.find( ".//PVStateValue/[@key='currentScanCenter']/IndexedValue/[@index='XAxis']" @@ -83,14 +82,8 @@ def get_pv_metadata(pvtiffile): framerate = 1 / float( root.findall('.//PVStateValue/[@key="framePeriod"]')[0].attrib.get("value")) # rate = 1/framePeriod - usec_per_line = ( - float( - root.findall(".//PVStateValue/[@key='scanLinePeriod']")[0].attrib.get( - "value" - ) - ) - * 1e6 - ) # Convert from seconds to microseconds + usec_per_line = float( + root.findall(".//PVStateValue/[@key='scanLinePeriod']")[0].attrib.get("value")) * 1e6 # Convert from seconds to microseconds scan_datetime = datetime.strptime( root.attrib.get("date"), "%m/%d/%Y %I:%M:%S %p") @@ -114,7 +107,7 @@ def get_pv_metadata(pvtiffile): ".//PVStateValue/[@key='micronsPerPixel']/IndexedValue/[@index='XAxis']" ).attrib.get("value") ) - # All PrairieView-acquired images have square dimensions + um_height = um_width = float(px_height) * um_per_pixel # coordinates do not change during scan From afac09db4990249c1c68e23e3501c5430c77f192 Mon Sep 17 00:00:00 2001 From: kushalbakshi Date: Thu, 13 Oct 2022 17:17:50 -0500 Subject: [PATCH 25/25] x, y, z to None for ScanInfo --- element_interface/prairieviewreader.py | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/element_interface/prairieviewreader.py b/element_interface/prairieviewreader.py index 6d4fd90..e0b740c 100644 --- a/element_interface/prairieviewreader.py +++ b/element_interface/prairieviewreader.py @@ -1,7 +1,7 @@ import pathlib import xml.etree.ElementTree as ET -import numpy as np from datetime import datetime +import numpy as np def get_pv_metadata(pvtiffile): @@ -63,21 +63,16 @@ def get_pv_metadata(pvtiffile): roi = 1 # x and y coordinate values for the center of the field - x_coordinate = float( + x_field = float( root.find( ".//PVStateValue/[@key='currentScanCenter']/IndexedValue/[@index='XAxis']" ).attrib.get("value") ) - y_coordinate = float( + y_field = float( root.find( ".//PVStateValue/[@key='currentScanCenter']/IndexedValue/[@index='YAxis']" ).attrib.get("value") ) - z_coordinate = float( - root.find( - ".//PVStateValue/[@key='positionCurrent']/SubindexedValues/[@index='ZAxis']/SubindexedValue/[@subindex='0']" - ).attrib.get("value") - ) framerate = 1 / float( root.findall('.//PVStateValue/[@key="framePeriod"]')[0].attrib.get("value")) # rate = 1/framePeriod @@ -110,9 +105,6 @@ def get_pv_metadata(pvtiffile): um_height = um_width = float(px_height) * um_per_pixel - # coordinates do not change during scan - x_field, y_field = x_coordinate, y_coordinate - z_min = float(root.findall( ".//Sequence/[@cycle='1']/Frame/PVStateShard/PVStateValue/[@key='positionCurrent']/SubindexedValues/SubindexedValue/[@subindex='0']" )[0].attrib.get("value")) @@ -131,9 +123,9 @@ def get_pv_metadata(pvtiffile): num_planes=n_depths, num_frames=n_frames, num_rois=roi, - x_pos=x_coordinate, - y_pos=y_coordinate, - z_pos=z_coordinate, + x_pos=None, + y_pos=None, + z_pos=None, frame_rate=framerate, bidirectional=bidirectional_scan, bidirectional_z=bidirection_z,