Skip to content

Commit

Permalink
Add ct2mrireg plugin (#654)
Browse files Browse the repository at this point in the history
* Add "ct2mrireg" as a plugin to perform CT to MRI co-registration

---------

Co-authored-by: rcassani <[email protected]>
  • Loading branch information
chinmaychinara91 and rcassani authored Nov 9, 2023
1 parent 259c409 commit c5ffb02
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 9 deletions.
54 changes: 54 additions & 0 deletions toolbox/anatomy/mri_coregister.m
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
% =============================================================================@
%
% Authors: Francois Tadel, 2016-2023
% Chinmay Chinara, 2023

% ===== LOAD INPUTS =====
% Parse inputs
Expand Down Expand Up @@ -233,7 +234,60 @@
end
% Output file tag
fileTag = '_mni';

% ===== CT2MRIREG =====
case 'ct2mri'
% Check if ct2mrireg plugin is installed
[isInstalled, errMsg] = bst_plugin('Install', 'ct2mrireg');
if ~isInstalled
if ~isProgress
bst_progress('stop');
end
return;
end

% Save files in tmp directory
bst_progress('text', 'Saving temporary files...');
% Get temporary folder
TmpDir = bst_get('BrainstormTmpDir', 0, 'ct2mrireg');
% Save source CT in .nii format
NiiSrcFile = bst_fullfile(TmpDir, 'ct2mri_src.nii');
out_mri_nii(sMriSrc, NiiSrcFile);
% Save reference MRI in .nii format
NiiRefFile = bst_fullfile(TmpDir, 'ct2mri_ref.nii');
out_mri_nii(sMriRef, NiiRefFile);

% Save registered file in .nii.gz format
NiiRegFile = bst_fullfile(TmpDir, 'contrastmri2preMRI.nii.gz');
bst_progress('text', 'Performing co-registration using ct2mrireg plugin...');
NiiRegFile = ct2mrireg(NiiSrcFile, NiiRefFile, NiiRegFile);

% Read output volume
sMriReg = in_mri(NiiRegFile, 'ALL', 0, 0);

% Delete the temporary files
file_delete(TmpDir, 1, 1);
% Output file tag
fileTag = '_ct2mri';

% === UPDATE FIDUCIALS ===
if isReslice
% Use the reference SCS coordinates
if isfield(sMriRef, 'SCS')
sMriReg.SCS = sMriRef.SCS;
end
% Use the reference NCS coordinates
if isfield(sMriRef, 'NCS')
sMriReg.NCS = sMriRef.NCS;
end

% Reslice the volume
[sMriReg, errMsg] = mri_reslice(sMriReg, sMriRef, 'scs', 'scs', isAtlas);
else
isUpdateScs = 1;
isUpdateNcs = 1;
end

% ===== VOX2RAS =====
case 'vox2ras'
% Nothing to do, just reslice if needed
Expand Down
16 changes: 15 additions & 1 deletion toolbox/core/bst_plugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@
% For more information type "brainstorm license" at command prompt.
% =============================================================================@
%
% Authors: Francois Tadel 2021-2023
% Authors: Francois Tadel, 2021-2023

eval(macro_method);
end
Expand Down Expand Up @@ -192,6 +192,20 @@
PlugDesc(end).UnloadPlugs = {'spm12', 'iso2mesh'};
PlugDesc(end).LoadFolders = {'lib/spm12', 'lib/iso2mesh', 'lib/cvx', 'lib/ncs2daprox', 'lib/NIFTI_20110921'};

% === ANATOMY: CT2MRIREG ===
% this plugin is used for performing CT to MRI co-registration
PlugDesc(end+1) = GetStruct('ct2mrireg');
PlugDesc(end).Version = 'github-master';
PlugDesc(end).Category = 'Anatomy';
PlugDesc(end).AutoUpdate = 1;
PlugDesc(end).URLzip = 'https://github.com/ajoshiusc/USCCleveland/archive/master.zip';
PlugDesc(end).URLinfo = 'https://github.com/ajoshiusc/USCCleveland/tree/master/ct2mrireg';
PlugDesc(end).TestFile = 'ct2mrireg.m';
PlugDesc(end).ReadmeFile = 'ct2mrireg/README.md';
PlugDesc(end).CompiledStatus = 2;
PlugDesc(end).LoadFolders = {'ct2mrireg'};
PlugDesc(end).DeleteFiles = {'fmri_analysis', 'for_clio', 'mixed_atlas', 'process_script', 'reg_prepost', 'visualize_channels', '.gitignore', 'README.md'};

% === FORWARD: OPENMEEG ===
PlugDesc(end+1) = GetStruct('openmeeg');
PlugDesc(end).Version = '2.4.1';
Expand Down
37 changes: 29 additions & 8 deletions toolbox/io/import_mri.m
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
function [BstMriFile, sMri, Messages] = import_mri(iSubject, MriFile, FileFormat, isInteractive, isAutoAdjust, Comment, Labels)
% IMPORT_MRI: Import a MRI file in a subject of the Brainstorm database
% IMPORT_MRI: Import a volume file (MRI, Atlas, CT, etc) in a subject of the Brainstorm database
%
% USAGE: [BstMriFile, sMri, Messages] = import_mri(iSubject, MriFile, FileFormat='ALL', isInteractive=0, isAutoAdjust=1, Comment=[], Labels=[])
% BstMriFiles = import_mri(iSubject, MriFiles, ...) % Import multiple volumes at once
Expand Down Expand Up @@ -38,6 +38,7 @@
% =============================================================================@
%
% Authors: Francois Tadel, 2008-2023
% Chinmay Chinara, 2023

%% ===== PARSE INPUTS =====
if (nargin < 3) || isempty(FileFormat)
Expand Down Expand Up @@ -69,6 +70,15 @@
else
sSubject = ProtocolSubjects.Subject(iSubject);
end
% Volume type
volType = 'MRI';
if ~isempty(strfind(Comment, 'CT'))
volType = 'CT';
end
% Get node comment from filename
if ~isempty(strfind(Comment, 'Import'))
Comment = [];
end

%% ===== SELECT MRI FILE =====
% If MRI file to load was not defined : open a dialog box to select it
Expand All @@ -80,9 +90,10 @@
if isempty(DefaultFormats.MriIn)
DefaultFormats.MriIn = 'ALL';
end
% Get MRI file

% Get MRI/CT file
[MriFile, FileFormat, FileFilter] = java_getfile( 'open', ...
'Import MRI...', ... % Window title
['Import ' volType '...'], ... % Window title
LastUsedDirs.ImportAnat, ... % Default directory
'multiple', 'files_and_dirs', ... % Selection mode
bst_get('FileFilters', 'mri'), ...
Expand Down Expand Up @@ -140,7 +151,7 @@
%% ===== LOAD MRI FILE =====
isProgress = bst_progress('isVisible');
if ~isProgress
bst_progress('start', 'Import MRI', 'Loading MRI file...');
bst_progress('start', ['Import ', volType], ['Loading ', volType, ' file...']);
end
% MNI / Atlas?
isMni = ismember(FileFormat, {'ALL-MNI', 'ALL-MNI-ATLAS'});
Expand Down Expand Up @@ -215,7 +226,8 @@
else
% If some transformation where made to the intial volume: apply them to the new one ?
if isfield(sMriRef, 'InitTransf') && ~isempty(sMriRef.InitTransf) && any(ismember(sMriRef.InitTransf(:,1), {'permute', 'flipdim'}))
if ~isInteractive || java_dialog('confirm', ['A transformation was applied to the reference MRI.' 10 10 'Do you want to apply the same transformation to this new volume?' 10 10], 'Import MRI')
isApplyTransformation = java_dialog('confirm', ['A transformation was applied to the reference MRI.' 10 10 'Do you want to apply the same transformation to this new volume?' 10 10], ['Import ', volType]);
if ~isInteractive || isApplyTransformation
% Apply step by step all the transformations that have been applied to the original MRI
for it = 1:size(sMriRef.InitTransf,1)
ttype = sMriRef.InitTransf{it,1};
Expand Down Expand Up @@ -253,11 +265,17 @@
% Register with the MNI transformation
strOptions = [strOptions, '<BR>- <U><B>MNI</B></U>:&nbsp;&nbsp;&nbsp;Compute the MNI transformation for both volumes (inaccurate).'];
cellOptions{end+1} = 'MNI';
if strcmpi(volType, 'CT')
% Register with the ct2mrireg plugin
strOptions = [strOptions, '<BR>- <U><B>CT2MRI</B></U>:&nbsp;&nbsp;&nbsp;Coregister using USC ct2mrireg plugin.'];
cellOptions{end+1} = 'CT2MRI';
end
% Skip registration
strOptions = [strOptions, '<BR>- <U><B>Ignore</B></U>:&nbsp;&nbsp;&nbsp;The two volumes are already registered.'];
cellOptions{end+1} = 'Ignore';
% Ask user to make a choice
RegMethod = java_dialog('question', [strOptions '<BR><BR></HTML>'], 'Import MRI', [], cellOptions, 'Reg+reslice');
RegMethod = java_dialog('question', [strOptions '<BR><BR></HTML>'], ['Import ', volType], [], cellOptions, 'Reg+reslice');

% In non-interactive mode: ignore if possible, or use the first option available
else
RegMethod = 'Ignore';
Expand All @@ -283,9 +301,9 @@
% Ask to reslice
isReslice = java_dialog('confirm', [...
'<HTML><B>Reslice the volume?</B><BR><BR>' ...
'This operation rewrites the new MRI to match the alignment, <BR>size and resolution of the original volume.' ...
['This operation rewrites the new ', volType, ' to match the alignment, <BR>size and resolution of the original volume.'] ...
strSizeWarn ...
'<BR><BR></HTML>'], 'Import MRI');
'<BR><BR></HTML>'], ['Import ', volType]);
% In non-interactive mode: never reslice
else
isReslice = 0;
Expand All @@ -299,6 +317,9 @@
case 'SPM'
% Register the new MRI on the existing one using SPM + RESLICE
[sMri, errMsg, fileTag] = mri_coregister(sMri, sMriRef, 'spm', isReslice, isAtlas);
case 'CT2MRI'
% Register the CT to excisting MRI using USC's ct2mrireg plugin
[sMri, errMsg, fileTag] = mri_coregister(sMri, sMriRef, 'ct2mri', isReslice, isAtlas);
case 'Ignore'
if isReslice
% Register the new MRI on the existing one using the transformation in the input files (files already registered)
Expand Down
1 change: 1 addition & 0 deletions toolbox/tree/tree_callbacks.m
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,7 @@
gui_component('MenuItem', jPopup, [], 'Import anatomy folder', IconLoader.ICON_ANATOMY, [], @(h,ev)bst_call(@import_anatomy, iSubject, 0));
gui_component('MenuItem', jPopup, [], 'Import anatomy folder (auto)', IconLoader.ICON_ANATOMY, [], @(h,ev)bst_call(@import_anatomy, iSubject, 1));
gui_component('MenuItem', jPopup, [], 'Import MRI', IconLoader.ICON_ANATOMY, [], @(h,ev)bst_call(@import_mri, iSubject, [], [], 1));
gui_component('MenuItem', jPopup, [], 'Import CT', IconLoader.ICON_ANATOMY, [], @(h,ev)bst_call(@import_mri, iSubject, [], [], 1, 1, 'Import CT'));
gui_component('MenuItem', jPopup, [], 'Import surfaces', IconLoader.ICON_SURFACE, [], @(h,ev)bst_call(@import_surfaces, iSubject));
gui_component('MenuItem', jPopup, [], 'Import fibers', IconLoader.ICON_FIBERS, [], @(h,ev)bst_call(@import_fibers, iSubject));
gui_component('MenuItem', jPopup, [], 'Convert DWI to DTI', IconLoader.ICON_FIBERS, [], @(h,ev)bst_call(@process_dwi2dti, 'ComputeInteractive', iSubject));
Expand Down

0 comments on commit c5ffb02

Please sign in to comment.