From 47d73092519a8789aa9a297e9babf9ac5fa523dd Mon Sep 17 00:00:00 2001 From: eugenegkim <53093555+eugenegkim@users.noreply.github.com> Date: Thu, 30 Apr 2026 12:42:18 +0200 Subject: [PATCH 1/9] add _bin_lap to brainextraction.py --- nirodents/workflows/brainextraction.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/nirodents/workflows/brainextraction.py b/nirodents/workflows/brainextraction.py index b47d46f..899bb7b 100644 --- a/nirodents/workflows/brainextraction.py +++ b/nirodents/workflows/brainextraction.py @@ -490,3 +490,26 @@ def _norm_lap(in_file): hdr.set_data_dtype('float32') img.__class__(data.astype('float32'), img.affine, hdr).to_filename(out_file) return out_file + + +def _bin_lap(in_file): + import numpy as np + import nibabel as nib + from scipy.stats import norm + from pathlib import Path + + img = nb.load(in_file) + data = img.get_fdata() + data_1d = img.ravel() + + lower, upper = np.quantile(data_1d, [0.05, 0.95]) + mu, sigma = norm.fit(data_1d[np.logical_and(data_1d > lower, data_1d < upper)]) + data = data > mu + sigma + + out_file = fname_presuffix( + Path(in_file).name, suffix='_mask', newpath=str(Path.cwd().absolute()) + ) + hdr = img.header.copy() + hdr.set_data_dtype('float32') + img.__class__(data.astype('float32'), img.affine, hdr).to_filename(out_file) + return out_file From 0f5b04cbf2c011f7fbf926f84e158982fef20c19 Mon Sep 17 00:00:00 2001 From: Eilidh MacNicol Date: Thu, 30 Apr 2026 14:43:08 +0200 Subject: [PATCH 2/9] replace normalised laplacian with binarised --- nirodents/workflows/brainextraction.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/nirodents/workflows/brainextraction.py b/nirodents/workflows/brainextraction.py index 899bb7b..6740737 100644 --- a/nirodents/workflows/brainextraction.py +++ b/nirodents/workflows/brainextraction.py @@ -126,12 +126,14 @@ def init_rodent_brain_extraction_wf( niu.Function(function=_lap_sigma), name='tmpl_sigma', run_without_submitting=True ) norm_lap_tmpl = pe.Node(niu.Function(function=_norm_lap), name='norm_lap_tmpl') + bin_lap_tmpl = pe.Node(niu.Function(function=_bin_lap), name='bin_lap_tmpl') lap_target = pe.Node(ImageMath(operation='Laplacian', copy_header=True), name='lap_target') target_sigma = pe.Node( niu.Function(function=_lap_sigma), name='target_sigma', run_without_submitting=True ) norm_lap_target = pe.Node(niu.Function(function=_norm_lap), name='norm_lap_target') + bin_lap_target = pe.Node(niu.Function(function=_bin_lap), name='bin_lap_target') # Set up initial spatial normalization ants_params = 'testing' if debug else 'precise' @@ -195,14 +197,17 @@ def init_rodent_brain_extraction_wf( (lap_target, norm_lap_target, [('output_image', 'in_file')]), (buffernode, mrg_target, [('hires_target', 'in1')]), (norm_lap_target, mrg_target, [('out', 'in2')]), + (norm_lap_target, bin_lap_target, [('out', 'in_file')]), + (bin_lap_target, mrg_target, [('out_file', 'in1')]), # Template massaging (clip_tmpl, res_tmpl, [('out_file', 'in_file')]), (res_tmpl, tmpl_sigma, [('out_file', 'in_file')]), (res_tmpl, lap_tmpl, [('out_file', 'op1')]), (tmpl_sigma, lap_tmpl, [('out', 'op2')]), (lap_tmpl, norm_lap_tmpl, [('output_image', 'in_file')]), + (norm_lap_tmpl, bin_lap_tmpl, [('out', 'in_file')]), (res_tmpl, mrg_tmpl, [('out_file', 'in1')]), - (norm_lap_tmpl, mrg_tmpl, [('out', 'in2')]), + (bin_lap_tmpl, mrg_tmpl, [('out_file', 'in2')]), # Setup inputs to spatial normalization (mrg_target, norm, [('out', 'moving_image')]), (mrg_tmpl, norm, [('out', 'fixed_image')]), From ebbaaf1e61b966dbb47a0979b01b8e9663378e94 Mon Sep 17 00:00:00 2001 From: Eilidh MacNicol Date: Thu, 30 Apr 2026 14:44:44 +0200 Subject: [PATCH 3/9] sty: tidy up _bin_lap function --- nirodents/workflows/brainextraction.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/nirodents/workflows/brainextraction.py b/nirodents/workflows/brainextraction.py index 6740737..7adf76b 100644 --- a/nirodents/workflows/brainextraction.py +++ b/nirodents/workflows/brainextraction.py @@ -498,10 +498,12 @@ def _norm_lap(in_file): def _bin_lap(in_file): + from pathlib import Path + + import nibabel as nb import numpy as np - import nibabel as nib + from nipype.utils.filemanip import fname_presuffix from scipy.stats import norm - from pathlib import Path img = nb.load(in_file) data = img.get_fdata() From fe0c33dc01c86069c7da979ec051063f5cf29dab Mon Sep 17 00:00:00 2001 From: Eugene Kim Date: Thu, 30 Apr 2026 14:59:58 +0200 Subject: [PATCH 4/9] antsRegistration call with binarized laplacians --- .../data/artsBrainExtraction_binlap_T2w.json | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 nirodents/data/artsBrainExtraction_binlap_T2w.json diff --git a/nirodents/data/artsBrainExtraction_binlap_T2w.json b/nirodents/data/artsBrainExtraction_binlap_T2w.json new file mode 100644 index 0000000..c22fae6 --- /dev/null +++ b/nirodents/data/artsBrainExtraction_binlap_T2w.json @@ -0,0 +1,61 @@ +{ + "collapse_output_transforms": true, + "convergence_threshold": [1E-8, 1E-8, 1E-6], + "convergence_window_size": [10, 10, 10], + "dimension": 3, + "interpolation": "LanczosWindowedSinc", + "metric": [ + "MI", + ["MI", "CC"], + ["CC", "CC"] + ], + "metric_weight": [ + 1, + [0.6, 0.4], + [0.4, 0.6] + ], + "number_of_iterations": [ + [1000, 500, 250, 100], + [50, 50, 10], + [100, 50] + ], + "output_transform_prefix": "anat_to_template", + "output_warped_image": true, + "radius_or_number_of_bins": [ + 32, + [32, 4], + [4, 4] + ], + "sampling_percentage": [ + 0.25, + [0.25, 1], + [1, 1] + ], + "sampling_strategy": [ + "Regular", + ["Regular", "None"], + ["None", "None"] + ], + "shrink_factors": [ + [8, 4, 2, 1], + [8, 4, 2], + [4, 2] + ], + "sigma_units": ["vox", "vox", "vox"], + "smoothing_sigmas": [ + [4, 2, 1, 0], + [4, 2, 1], + [2, 1] + ], + "transform_parameters": [ + [0.1], + [0.1], + [0.05, 9.0, 0.0] + ], + "transforms": ["Rigid", "Similarity", "SyN"], + "use_histogram_matching": true, + "verbose": true, + "winsorize_lower_quantile": 0.01, + "winsorize_upper_quantile": 0.975, + "write_composite_transform": false +} \ No newline at end of file From 47a87cf3a4fcd9c456b7f1ca79af2a7c205ce2c4 Mon Sep 17 00:00:00 2001 From: Eilidh MacNicol Date: Thu, 30 Apr 2026 15:04:37 +0200 Subject: [PATCH 5/9] fix: plug in binlap file for ants call --- nirodents/workflows/brainextraction.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nirodents/workflows/brainextraction.py b/nirodents/workflows/brainextraction.py index 7adf76b..9216c9d 100644 --- a/nirodents/workflows/brainextraction.py +++ b/nirodents/workflows/brainextraction.py @@ -136,7 +136,7 @@ def init_rodent_brain_extraction_wf( bin_lap_target = pe.Node(niu.Function(function=_bin_lap), name='bin_lap_target') # Set up initial spatial normalization - ants_params = 'testing' if debug else 'precise' + ants_params = 'testing' if debug else 'binlap' norm = pe.Node( Registration(from_file=load_data(f'artsBrainExtraction_{ants_params}_{mri_scheme}.json')), name='norm', From a3eae6933183fe65b7c9840c884b2e37503b6555 Mon Sep 17 00:00:00 2001 From: Eilidh MacNicol Date: Thu, 30 Apr 2026 15:31:39 +0200 Subject: [PATCH 6/9] fix: workflow connect typo --- nirodents/workflows/brainextraction.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nirodents/workflows/brainextraction.py b/nirodents/workflows/brainextraction.py index 9216c9d..fd79a5f 100644 --- a/nirodents/workflows/brainextraction.py +++ b/nirodents/workflows/brainextraction.py @@ -198,7 +198,7 @@ def init_rodent_brain_extraction_wf( (buffernode, mrg_target, [('hires_target', 'in1')]), (norm_lap_target, mrg_target, [('out', 'in2')]), (norm_lap_target, bin_lap_target, [('out', 'in_file')]), - (bin_lap_target, mrg_target, [('out_file', 'in1')]), + (bin_lap_target, mrg_target, [('out_file', 'in2')]), # Template massaging (clip_tmpl, res_tmpl, [('out_file', 'in_file')]), (res_tmpl, tmpl_sigma, [('out_file', 'in_file')]), From 9e534421747ef5db334a00e42afa6c72295a8c54 Mon Sep 17 00:00:00 2001 From: Eilidh MacNicol Date: Thu, 30 Apr 2026 15:32:59 +0200 Subject: [PATCH 7/9] fix: delete duplicated mrg node --- nirodents/workflows/brainextraction.py | 1 - 1 file changed, 1 deletion(-) diff --git a/nirodents/workflows/brainextraction.py b/nirodents/workflows/brainextraction.py index fd79a5f..fd02dbf 100644 --- a/nirodents/workflows/brainextraction.py +++ b/nirodents/workflows/brainextraction.py @@ -196,7 +196,6 @@ def init_rodent_brain_extraction_wf( (target_sigma, lap_target, [('out', 'op2')]), (lap_target, norm_lap_target, [('output_image', 'in_file')]), (buffernode, mrg_target, [('hires_target', 'in1')]), - (norm_lap_target, mrg_target, [('out', 'in2')]), (norm_lap_target, bin_lap_target, [('out', 'in_file')]), (bin_lap_target, mrg_target, [('out_file', 'in2')]), # Template massaging From dc6104bb47e66d64e2ce2232e09ec1cb94d97fb8 Mon Sep 17 00:00:00 2001 From: Eilidh MacNicol Date: Thu, 30 Apr 2026 15:40:20 +0200 Subject: [PATCH 8/9] fix: img vs data typo --- nirodents/workflows/brainextraction.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nirodents/workflows/brainextraction.py b/nirodents/workflows/brainextraction.py index fd02dbf..89a3e01 100644 --- a/nirodents/workflows/brainextraction.py +++ b/nirodents/workflows/brainextraction.py @@ -506,7 +506,7 @@ def _bin_lap(in_file): img = nb.load(in_file) data = img.get_fdata() - data_1d = img.ravel() + data_1d = data.ravel() lower, upper = np.quantile(data_1d, [0.05, 0.95]) mu, sigma = norm.fit(data_1d[np.logical_and(data_1d > lower, data_1d < upper)]) From 9e7a524dd3d638a1256e4bc877c49dac70295f21 Mon Sep 17 00:00:00 2001 From: Eilidh MacNicol Date: Thu, 30 Apr 2026 15:50:45 +0200 Subject: [PATCH 9/9] fix: _bin_lap output is out not out_file --- nirodents/workflows/brainextraction.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nirodents/workflows/brainextraction.py b/nirodents/workflows/brainextraction.py index 89a3e01..b426006 100644 --- a/nirodents/workflows/brainextraction.py +++ b/nirodents/workflows/brainextraction.py @@ -197,7 +197,7 @@ def init_rodent_brain_extraction_wf( (lap_target, norm_lap_target, [('output_image', 'in_file')]), (buffernode, mrg_target, [('hires_target', 'in1')]), (norm_lap_target, bin_lap_target, [('out', 'in_file')]), - (bin_lap_target, mrg_target, [('out_file', 'in2')]), + (bin_lap_target, mrg_target, [('out', 'in2')]), # Template massaging (clip_tmpl, res_tmpl, [('out_file', 'in_file')]), (res_tmpl, tmpl_sigma, [('out_file', 'in_file')]), @@ -206,7 +206,7 @@ def init_rodent_brain_extraction_wf( (lap_tmpl, norm_lap_tmpl, [('output_image', 'in_file')]), (norm_lap_tmpl, bin_lap_tmpl, [('out', 'in_file')]), (res_tmpl, mrg_tmpl, [('out_file', 'in1')]), - (bin_lap_tmpl, mrg_tmpl, [('out_file', 'in2')]), + (bin_lap_tmpl, mrg_tmpl, [('out', 'in2')]), # Setup inputs to spatial normalization (mrg_target, norm, [('out', 'moving_image')]), (mrg_tmpl, norm, [('out', 'fixed_image')]),