Skip to content

Commit 90b66c2

Browse files
Merge pull request #155 from AllenNeuralDynamics/seanf-v1
Fixed hard coded min candidate looping to handle any value, replaced …
2 parents 3aff101 + 34a62dd commit 90b66c2

5 files changed

Lines changed: 134 additions & 69 deletions

File tree

Rhapso/matching/ransac_matching.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ def create_candidates(self, desc_a, desc_b):
271271
for b in range(1):
272272

273273
matches = []
274-
for i in range(3):
274+
for i in range(self.num_required_neighbors):
275275
point_match = (desc_a['relative_descriptors'][i], desc_b['relative_descriptors'][i])
276276
matches.append(point_match)
277277

Rhapso/pipelines/ray/aws/config/ray_config_file_template.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,11 @@ setup_commands:
4949
- sudo python3 -m pip install awscli
5050
- sudo python3 -m pip install "ray[default]==2.9.1"
5151
- sudo python3 -m pip install protobuf==4.23.4
52-
# Update this line to point to your whl file (s3://rhapso-whl-v2/Rhapso-0.1.8-py3-none-any.whl)
53-
- aws s3 cp s3://rhapso-whl-v2/Rhapso-0.1.8-py3-none-any.whl /tmp/Rhapso-0.1.8-py3-none-any.whl
52+
# Update this line to point to your whl file ->
53+
- aws s3 cp s3://bucket-name/Rhapso-x.x.x-py3-none-any.whl /tmp/Rhapso-x.x.x-py3-none-any.whl
5454
- echo 'export PATH=$HOME/.local/bin:$PATH' >> ~/.bashrc
5555
- source ~/.bashrc
56-
- pip install /tmp/Rhapso-0.1.8-py3-none-any.whl # ensure this whl version number matches the one above
56+
- pip install /tmp/Rhapso-x.x.x-py3-none-any.whl # ensure this whl version number matches the one above
5757

5858
head_start_ray_commands:
5959
- ray stop

Rhapso/pipelines/ray/local/alignment_pipeline.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
ray.init()
1010

1111
# Point to param file
12-
with open("Rhapso/pipelines/ray/param/exaSPIM_802450.yml", "r") as file:
12+
with open("Rhapso/pipelines/ray/param/exaSPIM_794495.yml", "r") as file:
1313
config = yaml.safe_load(file)
1414

1515
# -- INITIALIZE EACH COMPONENT --
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
2+
# INTEREST POINT DETECTION
3+
# -----------------------------------
4+
5+
xml_file_path_detection: 's3://aind-scratch-data/sean.fite/dataset_794495.xml'
6+
image_file_prefix: 's3://aind-open-data/exaSPIM_794495_2026-01-21_14-25-07_processed_2026-01-29_22-02-08/flatfield_correction/SPIM.ome.zarr/'
7+
xml_output_file_path: &detection_xml_output_file_path 's3://aind-scratch-data/sean.fite/exaSPIM_794495/rhapso-detection.xml'
8+
n5_output_file_prefix: &n5_output_file_prefix 's3://aind-scratch-data/sean.fite/exaSPIM_794495/'
9+
detection_run_type: 'ray'
10+
file_type: 'zarr'
11+
dsxy: 16
12+
dsz: 16
13+
min_intensity: 1 # normalize - dog
14+
max_intensity: 5 # normalize - dog
15+
sigma: 2.0 # blur - dog
16+
threshold: 0.005 # find peaks (min initial peak value) - dog (threshold / 3)
17+
median_filter: 10 # xysubtract - pre-dog
18+
combine_distance: .5
19+
chunks_per_bound: 14 # chunks per bound
20+
max_spots: 10000 # max points per bound
21+
22+
# SOLVER
23+
# -----------------------------------
24+
25+
n5_input_path: *n5_output_file_prefix
26+
metrics_output_path: "metrics/metrics.json"
27+
relative_threshold: 3.5
28+
absolute_threshold: 7.0
29+
min_matches: 3
30+
damp: 1.0
31+
max_iterations: 10000
32+
max_allowed_error: .inf
33+
max_plateauwidth: 200
34+
fixed_tile: False
35+
36+
# -- RIGID --
37+
run_type_solver_rigid: 'rigid'
38+
xml_file_path_solver_rigid: *detection_xml_output_file_path
39+
xml_file_path_output_rigid: &rigid_solver_xml_output 's3://aind-scratch-data/sean.fite/exaSPIM_794495/rhapso-solver-rigid.xml'
40+
regularization_weight_solver_rigid: 1.0
41+
42+
# -- AFFINE --
43+
run_type_solver_affine: 'affine'
44+
xml_file_path_solver_affine: *rigid_solver_xml_output
45+
xml_file_path_output_affine: &affine_solver_xml_output 's3://aind-scratch-data/sean.fite/exaSPIM_794495/rhapso-solver-affine.xml'
46+
regularization_weight_solver_affine: 0.05
47+
48+
# -- SPLIT AFFINE --
49+
run_type_solver_split_affine: 'split-affine'
50+
xml_file_path_solver_split_affine: 's3://aind-scratch-data/sean.fite/exaSPIM_794495/rhapso-split.xml'
51+
xml_file_path_output_split_affine: &split_affine_solver_xml_output 's3://aind-scratch-data/sean.fite/exaSPIM_794495/rhapso-solver-split-affine.xml'
52+
regularization_weight_solver_split_affine: 0.05
53+
54+
# SPLIT DATASET
55+
# -----------------------------------
56+
57+
xml_file_path_split: *affine_solver_xml_output
58+
xml_output_file_path_split: &affine_split_xml_output 's3://aind-scratch-data/sean.fite/exaSPIM_794495/rhapso-split.xml'
59+
n5_path_split: *n5_output_file_prefix
60+
point_density: 100.0
61+
min_points: 20
62+
max_points: 500
63+
error: 0.5
64+
exclude_radius: 200.0
65+
target_image_size: [7040, 7040, 4000]
66+
target_overlap: [128, 128, 128]
67+
68+
69+
# INTEREST POINT MATCHING
70+
# -----------------------------------
71+
72+
input_type: 'zarr'
73+
n5_matching_output_path: *n5_output_file_prefix
74+
75+
# -- RIGID --
76+
match_type_rigid: 'rigid'
77+
xml_file_path_matching_rigid: *detection_xml_output_file_path
78+
79+
# Candidates
80+
num_neighbors_rigid: 2
81+
redundancy_rigid: 0
82+
significance_rigid: 2
83+
search_radius_rigid: 600
84+
num_required_neighbors_rigid: 2
85+
86+
# Ransac
87+
model_min_matches_rigid: 15
88+
inlier_threshold_rigid: 100
89+
min_inlier_ratio_rigid: 0.1
90+
num_iterations_rigid: 10000
91+
regularization_weight_matching_rigid: 1.0
92+
93+
# -- AFFINE --
94+
match_type_affine: 'affine'
95+
xml_file_path_matching_affine: *rigid_solver_xml_output
96+
97+
# Candidates
98+
num_neighbors_affine: 3
99+
redundancy_affine: 0
100+
significance_affine: 3
101+
search_radius_affine: 100
102+
num_required_neighbors_affine: 3
103+
104+
# Ransac
105+
model_min_matches_affine: 20
106+
inlier_threshold_affine: 100
107+
min_inlier_ratio_affine: 0.1
108+
num_iterations_affine: 10000
109+
regularization_weight_matching_affine: 0.05
110+
111+
# -- SPLIT AFFINE --
112+
match_type_split_affine: 'split-affine'
113+
xml_file_path_matching_split_affine: *affine_split_xml_output
114+
115+
# Candidates
116+
num_neighbors_split_affine: 3
117+
redundancy_split_affine: 1
118+
significance_split_affine: 3
119+
search_radius_split_affine: 600
120+
num_required_neighbors_split_affine: 3
121+
122+
# Ransac
123+
model_min_matches_split_affine: 20
124+
inlier_threshold_split_affine: 50
125+
min_inlier_ratio_split_affine: 0.1
126+
num_iterations_split_affine: 10000
127+
regularization_weight_matching_split_affine: 0.05

Rhapso/split_dataset/save_xml.py

Lines changed: 2 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,6 @@ def __init__(self, data_global, new_split_interest_points, self_definition, xml_
1313
self.xml_output_path = xml_output_path
1414

1515
def save_tile_attributes_to_xml(self, xml):
16-
"""
17-
Ensure the *last* <ViewSetups> (the outer split one) has:
18-
- <Attributes name="illumination"> old_tile_0..N </Attributes>
19-
- <Attributes name="channel"> ... </Attributes>
20-
- <Attributes name="tile"> with locations from Image Splitting </Attributes>
21-
- <Attributes name="angle"><Angle id=0 name=0/></Attributes>
22-
"""
2316
root = ET.fromstring(xml)
2417

2518
def tagname(el):
@@ -249,26 +242,6 @@ def wrap_image_loader_for_split(self, xml: str) -> str:
249242
"""
250243
Wrap the top-level ImageLoader in <ImageLoader format="split.viewerimgloader">
251244
and move the ORIGINAL ViewSetups/Timepoints/MissingViews into an inner
252-
<SequenceDescription> inside that wrapper.
253-
254-
Resulting structure:
255-
256-
<SpimData>
257-
<BasePath/>
258-
<SequenceDescription>
259-
<ImageLoader format="split.viewerimgloader">
260-
<ImageLoader format="bdv.multimg.zarr"> ... </ImageLoader>
261-
<SequenceDescription>
262-
<ViewSetups> (ORIGINAL) </ViewSetups>
263-
<Timepoints> (ORIGINAL) </Timepoints>
264-
<MissingViews/>
265-
</SequenceDescription>
266-
<!-- SetupIds (for split tiles) will be added later -->
267-
</ImageLoader>
268-
<!-- NEW ViewSetups/Timepoints/MissingViews for split views are added later -->
269-
</SequenceDescription>
270-
<ViewRegistrations> ... </ViewRegistrations>
271-
</SpimData>
272245
"""
273246
root = ET.fromstring(xml)
274247

@@ -309,27 +282,22 @@ def find_one(tag):
309282
if fmt == 'split.viewerimgloader':
310283
return xml
311284

312-
# Collect any other ImageLoader siblings (other sources)
313-
other_imageloaders = []
314285
# Collect ORIGINAL ViewSetups / Timepoints / MissingViews that are siblings
315286
orig_viewsetups = None
316287
orig_timepoints = None
317288
orig_missingviews = None
318289

319290
for ch in children[base_loader_idx + 1:]:
320291
name = tn(ch)
321-
if name == 'ImageLoader':
322-
other_imageloaders.append(ch)
323-
elif name == 'ViewSetups':
292+
if name == 'ViewSetups':
324293
orig_viewsetups = ch
325294
elif name == 'Timepoints':
326295
orig_timepoints = ch
327296
elif name == 'MissingViews':
328297
orig_missingviews = ch
329-
330298

331299
# Remove them from the outer SequenceDescription
332-
for node in (orig_viewsetups, orig_timepoints, orig_missingviews, *other_imageloaders):
300+
for node in (orig_viewsetups, orig_timepoints, orig_missingviews):
333301
if node is not None and node in seq:
334302
seq.remove(node)
335303

@@ -340,12 +308,9 @@ def find_one(tag):
340308
wrapper = ET.Element('ImageLoader', {'format': 'split.viewerimgloader'})
341309
# First child: original loader
342310
wrapper.append(base_loader)
343-
for other_loader in other_imageloaders:
344-
wrapper.append(other_loader)
345311

346312
# Inner <SequenceDescription> that holds the original ViewSetups/Timepoints/MissingViews
347313
inner_seq = ET.Element('SequenceDescription')
348-
349314
if orig_viewsetups is not None:
350315
inner_seq.append(orig_viewsetups)
351316
if orig_timepoints is not None:
@@ -516,33 +481,6 @@ def find_one(tag):
516481
return ET.tostring(root, encoding='unicode')
517482

518483
def save_setup_id_to_xml(self, xml):
519-
"""
520-
Create/overwrite the OUTER <ViewSetups> (split tiles) and ensure outer
521-
<Timepoints> and <MissingViews> exist under the top-level SequenceDescription.
522-
523-
Outer layout target:
524-
525-
<SpimData>
526-
<BasePath/>
527-
<SequenceDescription>
528-
<ImageLoader format="split.viewerimgloader">
529-
...
530-
<SequenceDescription> (original) </SequenceDescription>
531-
<SetupIds> ... </SetupIds> (from save_setup_id_definition_to_xml)
532-
</ImageLoader>
533-
<ViewSetups> <-- created here (ids 0..499)
534-
<ViewSetup>...</ViewSetup>
535-
...
536-
<Attributes ...>...</Attributes>
537-
</ViewSetups>
538-
<Timepoints type="pattern">
539-
<integerpattern>0</integerpattern>
540-
</Timepoints>
541-
<MissingViews/>
542-
</SequenceDescription>
543-
<ViewRegistrations>...</ViewRegistrations>
544-
</SpimData>
545-
"""
546484
root = ET.fromstring(xml)
547485

548486
def tn(el):

0 commit comments

Comments
 (0)