Skip to content

Commit 366bbff

Browse files
anna-grimanna-grim
andauthored
bugs: path parser, write (#150)
Co-authored-by: anna-grim <[email protected]>
1 parent 7d75aa3 commit 366bbff

File tree

3 files changed

+49
-46
lines changed

3 files changed

+49
-46
lines changed

src/segmentation_skeleton_metrics/skeleton_graph.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
99
"""
1010

11+
from collections import defaultdict
1112
from io import StringIO
1213
from scipy.spatial import distance
1314

@@ -292,27 +293,28 @@ def to_zipped_swc(self, zip_writer):
292293
zip_writer : zipfile.ZipFile
293294
A ZipFile object that will store the generated SWC file.
294295
"""
296+
# Subroutines
297+
def write_entry(node, parent):
298+
x, y, z = tuple(self.voxels[i] * self.anisotropy)
299+
r = self.node_radius[node] if preserve_radius else 2
300+
node_id = len(node_to_idx) + 1
301+
node_to_idx[node] = node_id
302+
text_buffer.write("\n" + f"{node_id} 2 {x} {y} {z} {r} {parent}")
303+
304+
# Main
295305
with StringIO() as text_buffer:
296306
# Preamble
297-
text_buffer.write(self.get_color())
298307
text_buffer.write("\n" + "# id, type, z, y, x, r, pid")
299308

300309
# Write entries
301-
node_to_idx = dict()
302-
r = 2 if self.is_groundtruth else 3
310+
node_to_idx = defaultdict(lambda: -1)
303311
for i, j in nx.dfs_edges(self):
304312
# Special Case: Root
305-
x, y, z = tuple(self.voxels[i] * self.anisotropy)
306313
if len(node_to_idx) == 0:
307-
parent = -1
308-
node_to_idx[i] = 1
309-
text_buffer.write("\n" + f"1 2 {x} {y} {z} {r} {parent}")
310-
311-
# General Case
312-
node = len(node_to_idx) + 1
313-
parent = node_to_idx[i]
314-
node_to_idx[j] = node
315-
text_buffer.write("\n" + f"{node} 2 {x} {y} {z} {r} {parent}")
314+
write_entry(i, node_to_idx[i])
315+
316+
# General Case: Non-Root
317+
write_entry(j, node_to_idx[i])
316318

317319
# Finish
318320
zip_writer.writestr(self.filename, text_buffer.getvalue())

src/segmentation_skeleton_metrics/utils/swc_util.py

Lines changed: 2 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ def read_from_gcs(self, gcs_path):
293293
names and values from an SWC file.
294294
"""
295295
# List filenames
296-
bucket_name, prefix = parse_cloud_path(gcs_path)
296+
bucket_name, prefix = util.parse_cloud_path(gcs_path)
297297
swc_paths = util.list_gcs_filenames(bucket_name, prefix, ".swc")
298298
zip_paths = util.list_gcs_filenames(bucket_name, prefix, ".zip")
299299

@@ -430,7 +430,7 @@ def read_from_gcs_zip(self, bucket_name, path):
430430

431431
def read_from_s3(self, s3_path):
432432
# List filenames
433-
bucket_name, prefix = parse_cloud_path(s3_path)
433+
bucket_name, prefix = util.parse_cloud_path(s3_path)
434434
swc_paths = util.list_s3_paths(bucket_name, prefix, extension=".swc")
435435

436436
# Parse SWC files
@@ -548,37 +548,6 @@ def read_voxel(self, xyz_str, offset):
548548

549549

550550
# --- Helpers ---
551-
def parse_cloud_path(path):
552-
"""
553-
Parses a cloud storage path into its bucket name and key/prefix. Supports
554-
paths of the form: "{scheme}://bucket_name/prefix" or without a scheme.
555-
556-
Parameters
557-
----------
558-
path : str
559-
Path to be parsed.
560-
561-
Returns
562-
-------
563-
bucket_name : str
564-
Name of the bucket.
565-
prefix : str
566-
Cloud prefix.
567-
"""
568-
# Remove s3:// if present
569-
if path.startswith("s3://"):
570-
path = path[len("s3://"):]
571-
572-
# Remove gs:// if present
573-
if path.startswith("gs://"):
574-
path = path[len("gs://"):]
575-
576-
parts = path.split("/", 1)
577-
bucket_name = parts[0]
578-
prefix = parts[1] if len(parts) > 1 else ""
579-
return bucket_name, prefix
580-
581-
582551
def to_zipped_point(zip_writer, filename, xyz):
583552
"""
584553
Writes a point to an SWC file format, which is then stored in a ZIP

src/segmentation_skeleton_metrics/utils/util.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,38 @@ def kdtree_query(kdtree, xyz):
450450
return tuple(kdtree.data[idx])
451451

452452

453+
def parse_cloud_path(path):
454+
"""
455+
Parses a cloud storage path into its bucket name and key/prefix. Supports
456+
paths of the form: "{scheme}://bucket_name/prefix" or without a scheme.
457+
458+
Parameters
459+
----------
460+
path : str
461+
Path to be parsed.
462+
463+
Returns
464+
-------
465+
bucket_name : str
466+
Name of the bucket.
467+
prefix : str
468+
Cloud prefix.
469+
"""
470+
# Remove s3:// if present
471+
if is_s3_path(path):
472+
path = path[len("s3://"):]
473+
474+
# Remove gs:// if present
475+
if is_gcs_path(path):
476+
path = path[len("gs://"):]
477+
478+
# Extract bucket and prefix
479+
parts = path.split("/", 1)
480+
bucket_name = parts[0]
481+
prefix = parts[1] if len(parts) > 1 else ""
482+
return bucket_name, prefix
483+
484+
453485
def sample_once(my_container):
454486
"""
455487
Samples a single element from "my_container".

0 commit comments

Comments
 (0)