Skip to content

Commit 9a76bbc

Browse files
authored
Register all grid squares and foil holes (#455)
1 parent bc3278d commit 9a76bbc

File tree

2 files changed

+100
-36
lines changed

2 files changed

+100
-36
lines changed

src/murfey/client/contexts/spa_metadata.py

Lines changed: 98 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import logging
22
from pathlib import Path
3-
from typing import Optional
3+
from typing import Dict, Optional
44

55
import requests
66
import xmltodict
@@ -9,13 +9,66 @@
99
from murfey.client.contexts.spa import _get_source
1010
from murfey.client.instance_environment import MurfeyInstanceEnvironment, SampleInfo
1111
from murfey.util import authorised_requests, capture_post, get_machine_config_client
12-
from murfey.util.spa_metadata import get_grid_square_atlas_positions
12+
from murfey.util.spa_metadata import FoilHoleInfo, get_grid_square_atlas_positions
1313

1414
logger = logging.getLogger("murfey.client.contexts.spa_metadata")
1515

1616
requests.get, requests.post, requests.put, requests.delete = authorised_requests()
1717

1818

19+
def _foil_hole_positions(xml_path: Path, grid_square: int) -> Dict[str, FoilHoleInfo]:
20+
with open(xml_path, "r") as xml:
21+
for_parsing = xml.read()
22+
data = xmltodict.parse(for_parsing)
23+
data = data["GridSquareXml"]
24+
readout_area = data["MicroscopeImage"]["microscopeData"]["acquisition"]["camera"][
25+
"ReadoutArea"
26+
]
27+
pixel_size = data["MicroscopeImage"]["SpatialScale"]["pixelSize"]["x"][
28+
"numericValue"
29+
]
30+
full_size = (int(readout_area["a:width"]), int(readout_area["a:height"]))
31+
serialization_array = data["TargetLocations"]["TargetLocationsEfficient"][
32+
"a:m_serializationArray"
33+
]
34+
required_key = ""
35+
for key in serialization_array.keys():
36+
if key.startswith("b:KeyValuePairOfintTargetLocation"):
37+
required_key = key
38+
break
39+
if not required_key:
40+
return {}
41+
foil_holes = {}
42+
for fh_block in serialization_array[required_key]:
43+
if fh_block["b:value"]["IsNearGridBar"] == "false":
44+
image_paths = list(
45+
(xml_path.parent.parent).glob(
46+
f"Images-Disc*/GridSquare_{grid_square}/FoilHoles/FoilHole_{fh_block['b:key']}_*.jpg"
47+
)
48+
)
49+
image_paths.sort(key=lambda x: x.stat().st_ctime)
50+
image_path: str = str(image_paths[-1]) if image_paths else ""
51+
pix_loc = fh_block["b:value"]["PixelCenter"]
52+
stage = fh_block["b:value"]["StagePosition"]
53+
diameter = fh_block["b:value"]["PixelWidthHeight"]["c:width"]
54+
foil_holes[fh_block["b:key"]] = FoilHoleInfo(
55+
id=int(fh_block["b:key"]),
56+
grid_square_id=grid_square,
57+
x_location=int(float(pix_loc["c:x"])),
58+
y_location=int(float(pix_loc["c:y"])),
59+
x_stage_position=float(stage["c:X"]),
60+
y_stage_position=float(stage["c:Y"]),
61+
readout_area_x=full_size[0] if image_path else None,
62+
readout_area_y=full_size[1] if image_path else None,
63+
thumbnail_size_x=None,
64+
thumbnail_size_y=None,
65+
pixel_size=float(pixel_size) if image_path else None,
66+
image=str(image_path),
67+
diameter=int(float(diameter)),
68+
)
69+
return foil_holes
70+
71+
1972
def _atlas_destination(
2073
environment: MurfeyInstanceEnvironment, source: Path, file_path: Path
2174
) -> Path:
@@ -109,36 +162,47 @@ def post_transfer(
109162
"atlas_pixel_size": atlas_pixel_size,
110163
}
111164
capture_post(url, json=dcg_data)
112-
registered_grid_squares = (
113-
requests.get(
114-
f"{str(environment.url.geturl())}/sessions/{environment.murfey_session}/grid_squares"
115-
)
116-
.json()
117-
.get(str(source), [])
165+
gs_pix_positions = get_grid_square_atlas_positions(
166+
_atlas_destination(environment, source, transferred_file)
167+
/ environment.samples[source].atlas
168+
)
169+
for gs, pos_data in gs_pix_positions.items():
170+
if pos_data:
171+
capture_post(
172+
f"{str(environment.url.geturl())}/sessions/{environment.murfey_session}/grid_square/{gs}",
173+
json={
174+
"tag": str(source),
175+
"x_location": pos_data[0],
176+
"y_location": pos_data[1],
177+
"x_stage_position": pos_data[2],
178+
"y_stage_position": pos_data[3],
179+
"width": pos_data[4],
180+
"height": pos_data[5],
181+
"angle": pos_data[6],
182+
},
183+
)
184+
185+
elif transferred_file.suffix == ".dm" and environment:
186+
gs_name = transferred_file.name.split("_")[1]
187+
fh_positions = _foil_hole_positions(transferred_file, int(gs_name))
188+
source = _get_source(transferred_file, environment=environment)
189+
visitless_source = str(source).replace(f"/{environment.visit}", "")
190+
for fh, fh_data in fh_positions.items():
191+
capture_post(
192+
f"{str(environment.url.geturl())}/sessions/{environment.murfey_session}/grid_square/{gs_name}/foil_hole",
193+
json={
194+
"name": fh,
195+
"x_location": fh_data.x_location,
196+
"y_location": fh_data.y_location,
197+
"x_stage_position": fh_data.x_stage_position,
198+
"y_stage_position": fh_data.y_stage_position,
199+
"readout_area_x": fh_data.readout_area_x,
200+
"readout_area_y": fh_data.readout_area_y,
201+
"thumbnail_size_x": fh_data.thumbnail_size_x,
202+
"thumbnail_size_y": fh_data.thumbnail_size_y,
203+
"pixel_size": fh_data.pixel_size,
204+
"diameter": fh_data.diameter,
205+
"tag": visitless_source,
206+
"image": fh_data.image,
207+
},
118208
)
119-
if registered_grid_squares:
120-
gs_pix_positions = get_grid_square_atlas_positions(
121-
source_visit_dir / partial_path
122-
)
123-
for gs in registered_grid_squares:
124-
pos_data = gs_pix_positions.get(str(gs["name"]))
125-
if pos_data:
126-
capture_post(
127-
f"{str(environment.url.geturl())}/sessions/{environment.murfey_session}/grid_square/{gs['name']}",
128-
json={
129-
"tag": gs["tag"],
130-
"readout_area_x": gs["readout_area_x"],
131-
"readout_area_y": gs["readout_area_y"],
132-
"thumbnail_size_x": gs["thumbnail_size_x"],
133-
"thumbnail_size_y": gs["thumbnail_size_y"],
134-
"pixel_size": gs["pixel_size"],
135-
"image": gs["image"],
136-
"x_location": pos_data[0],
137-
"y_location": pos_data[1],
138-
"x_stage_position": pos_data[2],
139-
"y_stage_position": pos_data[3],
140-
"width": pos_data[4],
141-
"height": pos_data[5],
142-
"angle": pos_data[6],
143-
},
144-
)

src/murfey/util/spa_metadata.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import logging
22
from pathlib import Path
3-
from typing import Dict, NamedTuple, Optional, Tuple
3+
from typing import Dict, NamedTuple, Optional, Tuple, Union
44

55
import xmltodict
66

@@ -167,7 +167,7 @@ def foil_hole_data(xml_path: Path, foil_hole: int, grid_square: int) -> FoilHole
167167
)
168168
)
169169
image_paths.sort(key=lambda x: x.stat().st_ctime)
170-
image_path: Path | str = image_paths[-1] if image_paths else ""
170+
image_path: Union[Path, str] = image_paths[-1] if image_paths else ""
171171
if image_path:
172172
with open(Path(image_path).with_suffix(".xml")) as fh_xml:
173173
fh_xml_data = xmltodict.parse(fh_xml.read())

0 commit comments

Comments
 (0)