Skip to content

Commit dde9321

Browse files
committed
feat: add swc convert example
1 parent 0389909 commit dde9321

File tree

2 files changed

+103
-1
lines changed

2 files changed

+103
-1
lines changed

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,10 @@ cd tests
4040
jest MATCH --config=jest.config.js
4141
```
4242

43-
where `MATCH` is a substring of the test name.
43+
where `MATCH` is a substring of the test name.
44+
45+
### Running local server
46+
47+
```
48+
npx http-server FOLDER_WITH_DATA/ --cors=authorization
49+
```

examples/convert_swc.py

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# See https://github.com/seung-lab/cloud-volume/issues/412
2+
import json
3+
4+
from cloudvolume import Skeleton
5+
from cloudvolume import CloudVolume
6+
from pathlib import Path
7+
from cryoet_data_portal_neuroglancer.models.json_generator import (
8+
SegmentPropertyJSONGenerator,
9+
)
10+
11+
12+
def open_swc(swc_path):
13+
with open(swc_path, "r") as f:
14+
data = f.read()
15+
skeleton = Skeleton.from_swc(data)
16+
17+
return skeleton
18+
19+
20+
def save_swc(skeleton, output_path, id):
21+
info = {
22+
"@type": "neuroglancer_skeletons",
23+
"transform": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0],
24+
# "vertex_attributes": [
25+
# {"id": "radius", "data_type": "float32", "num_components": 1}
26+
# ],
27+
"scales": [
28+
{
29+
"chunk_sizes": [
30+
[256, 256, 256]
31+
], # information required by neuroglancer but not used
32+
"key": "data",
33+
"resolution": [1, 1, 1],
34+
"size": [1024, 1024, 1024],
35+
},
36+
],
37+
"segment_properties": "props",
38+
}
39+
40+
skeleton.id = id
41+
cv = CloudVolume(f"file://{str(output_path)}", info=info, compress=False)
42+
cv.skeleton.meta.info = info
43+
cv.skeleton.meta.commit_info()
44+
cv.skeleton.upload(skeleton)
45+
46+
47+
def generate_properties(output_path, ids, labels):
48+
output_path = Path(output_path)
49+
output_path.mkdir(parents=True, exist_ok=True)
50+
generator = SegmentPropertyJSONGenerator(
51+
ids=ids,
52+
labels=labels,
53+
)
54+
json_res = generator.generate_json()
55+
print(f"Generated properties for {len(ids)} segments.")
56+
output_file = output_path / "info"
57+
output_file.write_text(json.dumps(json_res, indent=2))
58+
59+
60+
def main(output_path, input_folder):
61+
output_path = Path(output_path)
62+
output_path.mkdir(parents=True, exist_ok=True)
63+
input_folder = Path(input_folder)
64+
ids = []
65+
labels = []
66+
for swc_file in input_folder.glob("*.swc"):
67+
print(f"Processing {swc_file}")
68+
skeleton = open_swc(swc_file)
69+
id_string = swc_file.stem.split("_")[-1]
70+
id_ = int(id_string)
71+
rest = swc_file.stem[: -len(id_string) - 1]
72+
label = rest.replace("[", "")
73+
label = label.replace("]", "")
74+
label = label.strip()
75+
ids.append(id_)
76+
labels.append(label)
77+
save_swc(skeleton, output_path, id_)
78+
print(f"Saved skeleton with ID {id_} to {output_path}")
79+
generate_properties(output_path / "skeletons" / "props", ids, labels)
80+
81+
82+
if __name__ == "__main__":
83+
import argparse
84+
85+
parser = argparse.ArgumentParser(
86+
description="Convert SWC files to CloudVolume format."
87+
)
88+
parser.add_argument(
89+
"output_path", type=str, help="Path to the output CloudVolume directory."
90+
)
91+
parser.add_argument(
92+
"input_folder", type=str, help="Path to the folder containing SWC files."
93+
)
94+
95+
args = parser.parse_args()
96+
main(args.output_path, args.input_folder)

0 commit comments

Comments
 (0)