Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions examples/my_nodes/dp_node_ants_apply.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
classdef dp_node_ants_apply < dp_node
% Wrapper around antsApplyTransforms onto a given reference grid
% input.nii_fn : image to be transformed (e.g. atlas labels in MNI)
% input.ref_fn : reference grid / output space (e.g. trimmed FA)
% input.affine_fn, input.invwarp_fn : from dp_node_ants_reg_quick
% output.nii_fn : resampled image in ref_fn space

properties
options = ''; % e.g. ' -n NearestNeighbor' for labels
use_inverse = 1; % default = inverse chain
end

methods

function obj = dp_node_ants_apply(options)
if (nargin>0), obj.options = options; end
obj.output_test = {'nii_fn'};
end

function output = i2o(obj, input)
output.nii_fn = dp.new_fn(input.op, input.nii_fn, '_ants');
output.ref_fn = input.ref_fn;
end

function output = execute(obj, input, output)
msf_mkdir(fileparts(output.nii_fn));
if obj.use_inverse
% apply inverse chain: template→subject (fixed → moving)
t = sprintf('-t "[%s,1]" -t "%s" ', input.affine_fn, input.invwarp_fn);
else
% apply forward chain: subject→template (moving → fixed)
t = sprintf('-t "%s" -t "%s" ', input.warp_fn, input.affine_fn);
end

if isempty(obj.options), obj.options = ' -n NearestNeighbor'; end

% cmd using composed transform chain "t" (forward or inverse, depending on use_inverse)
cmd = sprintf('antsApplyTransforms -d 3 -i "%s" -r "%s" %s -o "%s"%s', ...
input.nii_fn, input.ref_fn, t, output.nii_fn, obj.options);


system(cmd);
end
end
end
64 changes: 64 additions & 0 deletions examples/my_nodes/dp_node_ants_reg_quick.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
classdef dp_node_ants_reg_quick < dp_node
% antsRegistrationSyN.sh (moving = input.nii_fn, fixed = input.target_fn)
% Outputs affine + forward/inverse warps in <input.op>

properties
options = ''; % include threads and preset here, e.g. ' ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS=16 -t s'
end

methods

function obj = dp_node_ants_reg_quick(options)
if (nargin>0), obj.options = options; end
obj.output_test = {'affine_fn','warp_fn','invwarp_fn','warped_fn'};

end

function output = i2o(obj, input)
tmp = msf_fn_append(input.nii_fn, '_mni_');
prefix = msf_fn_new_path(input.op, tmp);
[pdir,pfx,~] = msf_fileparts(prefix);
prefix = fullfile(pdir, pfx); % ANTs prefix base (no ext)

output.prefix = prefix;
output.target_fn = input.target_fn;
output.affine_fn = [prefix '0GenericAffine.mat'];
output.warp_fn = [prefix '1Warp.nii.gz'];
output.invwarp_fn = [prefix '1InverseWarp.nii.gz'];
output.warped_fn = [prefix 'Warped.nii.gz']; % QC, remains in op
end


function output = execute(obj, input, output)
% set threads and build the command
thr = feature('numcores');
envp = sprintf('ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS=%d', thr);

% if user didn’t provide flags, default to symmetric registration (-t s)
if isempty(strtrim(obj.options))
flags = ' -t s';
else
flags = [' ' strtrim(obj.options)];
end

msf_mkdir(fileparts(output.warped_fn));


% full SyN variant
% cmd = sprintf('%s antsRegistrationSyN.sh -d 3 -f "%s" -m "%s" -o "%s"%s', ...
% envp, input.target_fn, input.nii_fn, output.prefix, flags);

% quick SyN variant
cmd = sprintf('%s antsRegistrationSyNQuick.sh -d 3 -f "%s" -m "%s" -o "%s"%s', ...
envp, input.target_fn, input.nii_fn, output.prefix, flags);


% Always save ANTs output to log in the same folder
log_fn = fullfile(fileparts(output.warped_fn), 'ants_registration.log');
cmd = [cmd, sprintf(' > "%s" 2>&1', log_fn)];

system(cmd);
end

end
end
53 changes: 53 additions & 0 deletions examples/my_nodes/dp_node_atlas_crop_to_mask.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
classdef dp_node_atlas_crop_to_mask < dp_node
% Crop an atlas/label map with a provided mask (same grid).
%
% Inputs (from upstream):
% nii_fn - atlas / label image to crop (e.g. warped JHU labels)
% mask_fn - mask in the same space (e.g. trimmed FA brain mask)
% op - optional output directory
%
% Output:
% nii_fn - cropped atlas, saved as <op>/<basename>_crop.nii.gz

properties
suffix = '_crop';
end

methods
function obj = dp_node_atlas_crop_to_mask(suffix)
if nargin > 0
obj.suffix = suffix;
end
obj.output_test = {'nii_fn'};
end

function output = i2o(obj, input)
% Decide output folder
if isfield(input, 'op') && ~isempty(input.op)
op = input.op;
else
[op, ~, ~] = msf_fileparts(input.nii_fn);
end

% Use dp.new_fn to append suffix before extension
output.nii_fn = dp.new_fn(op, input.nii_fn, obj.suffix);
end

function output = execute(obj, input, output)
% Read atlas/labels and mask
[A, Ah] = mdm_nii_read(input.nii_fn);
B = mdm_nii_read(input.mask_fn);

% Basic safety
if ~isequal(size(A), size(B))
error('dp_node_atlas_crop_to_mask: atlas/mask size mismatch');
end

msf_mkdir(fileparts(output.nii_fn));

% Apply crop
mdm_nii_write(A .* (B > 0), output.nii_fn, Ah);

end
end
end
71 changes: 71 additions & 0 deletions examples/my_nodes/dp_node_segm_jhu.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
classdef dp_node_segm_jhu < dp_node_segm

methods (Hidden)
function [labels, ids] = segm_info(obj)

% /usr/local/fsl/data/atlases/JHU-labels.xml

txt = { ...
'0: Unclassified', ... % Unclassified
'1: MCP', ... % Middle cerebellar peduncle
'2: PCT', ... % Pontine crossing tract (a part of MCP)
'3: GCC', ... % Genu of corpus callosum
'4: CCB', ... % Body of corpus callosum
'5: SCC', ... % Splenium of corpus callosum
'6: FX', ... % Fornix (column and body of fornix)
'7: CST_R', ... % Corticospinal tract R
'8: CST_L', ... % Corticospinal tract L
'9: ML_R', ... % Medial lemniscus R
'10: ML_L', ... % Medial lemniscus L
'11: ICP_R', ... % Inferior cerebellar peduncle R
'12: ICP_L', ... % Inferior cerebellar peduncle L
'13: SCP_R', ... % Superior cerebellar peduncle R
'14: SCP_L', ... % Superior cerebellar peduncle L
'15: CP_R', ... % Cerebral peduncle R
'16: CP_L', ... % Cerebral peduncle L
'17: ALIC_R', ... % Anterior limb of internal capsule R
'18: ALIC_L', ... % Anterior limb of internal capsule L
'19: PLIC_R', ... % Posterior limb of internal capsule R
'20: PLIC_L', ... % Posterior limb of internal capsule L
'21: RLIC_R', ... % Retrolenticular part of internal capsule R
'22: RLIC_L', ... % Retrolenticular part of internal capsule L
'23: ACR_R', ... % Anterior corona radiata R
'24: ACR_L', ... % Anterior corona radiata L
'25: SCR_R', ... % Superior corona radiata R
'26: SCR_L', ... % Superior corona radiata L
'27: PCR_R', ... % Posterior corona radiata R
'28: PCR_L', ... % Posterior corona radiata L
'29: PTR_R', ... % Posterior thalamic radiation (include optic radiation) R
'30: PTR_L', ... % Posterior thalamic radiation (include optic radiation) L
'31: SS_R', ... % Sagittal stratum (incl ILF and IFOF) R
'32: SS_L', ... % Sagittal stratum (incl ILF and IFOF) L
'33: EC_R', ... % External capsule R
'34: EC_L', ... % External capsule L
'35: CGC_R', ... % Cingulum (cingulate gyrus) R
'36: CGC_L', ... % Cingulum (cingulate gyrus) L
'37: CGH_R', ... % Cingulum (hippocampus) R
'38: CGH_L', ... % Cingulum (hippocampus) L
'39: FST_R', ... % Fornix (crus) / Stria terminalis R
'40: FST_L', ... % Fornix (crus) / Stria terminalis L
'41: SLF_R', ... % Superior longitudinal fasciculus R
'42: SLF_L', ... % Superior longitudinal fasciculus L
'43: SFOF_R', ... % Superior fronto-occipital fasciculus R
'44: SFOF_L', ... % Superior fronto-occipital fasciculus L
'45: UF_R', ... % Uncinate fasciculus R
'46: UF_L', ... % Uncinate fasciculus L
'47: TAP_R', ... % Tapetum R
'48: TAP_L' ... % Tapetum L
};




a = @(x) strsplit(x, ' ');
b = @(x,i) x{i};
c = @(x) str2num(x(1:(end-1)));

labels = cellfun(@(x) b(a(x),2), txt, 'UniformOutput', false);
ids = cellfun(@(x) c(b(a(x),1)), txt, 'UniformOutput', false);
end
end
end
Loading