From d619cf5ec5e14be1e44d524093084ee241b00de0 Mon Sep 17 00:00:00 2001 From: Kwok-Shing Chan <39571502+kschan0214@users.noreply.github.com> Date: Sat, 2 Dec 2023 15:07:43 -0500 Subject: [PATCH 1/6] add read IO from pipeline config file --- .../callback/config/set_config_Callback.m | 104 ++++++++++++++++++ sepia_universal_variables.m | 2 +- 2 files changed, 105 insertions(+), 1 deletion(-) diff --git a/gui_func/callback/config/set_config_Callback.m b/gui_func/callback/config/set_config_Callback.m index 11b984b..6d4dcc8 100644 --- a/gui_func/callback/config/set_config_Callback.m +++ b/gui_func/callback/config/set_config_Callback.m @@ -24,7 +24,13 @@ function set_config_Callback(config_filename,h) isModifyUnwrap = false; isModifyBFR = false; isModifyQSM = false; +isModifyIO = false; +str_pattern = 'input'; +idx = regexp(config_txt,str_pattern,'once'); +if ~isempty(idx) + isModifyIO = true; +end str_pattern = '.general.'; idx = regexp(config_txt,str_pattern,'once'); if ~isempty(idx) @@ -47,6 +53,104 @@ function set_config_Callback(config_filename,h) end %% Panel: I/O +if isModifyIO +input_action_handle = h.dataIO.edit.input; +input1_action_handle = h.dataIO.edit.inputData1; +input2_action_handle = h.dataIO.edit.inputData2; +input3_action_handle = h.dataIO.edit.inputData3; +header_action_handle = h.dataIO.edit.inputHeader; +mask_action_handle = h.dataIO.edit.maskdir; +output_action_handle = h.dataIO.edit.output; + +isAllInputEmpty = (isempty(input_action_handle.String) .* isempty(input1_action_handle.String) .* ... + isempty(input2_action_handle.String).* isempty(input3_action_handle.String) .* ... + isempty(header_action_handle.String))>0; + +% check which input method was used in the config file +ind = regexp(config_txt, regexptranslate('wildcard','input(*).name'), 'once'); +if ~isempty(ind) + isFileIO = true; +else + isFileIO = false; +end + +% Directory input method +action_handle = input_action_handle; +if isAllInputEmpty && ~isFileIO % only modify the field if all IO fields are empty + str_pattern = 'input'; + str_end_idx = regexp(config_txt,str_pattern,'end'); + indicator_idx = regexp(config_txt,''''); + str = config_txt(indicator_idx(find(indicator_idx > str_end_idx(1), 1 ))+1:indicator_idx(find(indicator_idx > str_end_idx(1), 1 )+1)-1); + + if ~isnan(str) + set(action_handle,'String',str); + end +end + +% File input method +% input 1 +action_handle = input1_action_handle; +if and(isempty(input_action_handle.String),isempty(get(action_handle,'String'))) + str_pattern = 'input\(1).name'; + str = get_string_as_string(config_txt, str_pattern); + if ~isnan(str) + set(action_handle,'String',str); + end +end + +% input 2 +action_handle = input2_action_handle; +if and(isempty(input_action_handle.String),isempty(get(action_handle,'String'))) + str_pattern = 'input\(2).name'; + str = get_string_as_string(config_txt, str_pattern); + if ~isnan(str) + set(action_handle,'String',str); + end +end + +% input 3 +action_handle = input3_action_handle; +if and(isempty(input_action_handle.String),isempty(get(action_handle,'String'))) + str_pattern = 'input\(3).name'; + str = get_string_as_string(config_txt, str_pattern); + if ~isnan(str) + set(action_handle,'String',str); + end +end + +% header input +action_handle = header_action_handle; +if and(isempty(input_action_handle.String),isempty(get(action_handle,'String'))) + str_pattern = 'input\(4).name'; + str = get_string_as_string(config_txt, str_pattern); + if ~isnan(str) + set(action_handle,'String',str); + end +end + +% mask +action_handle = mask_action_handle; +if isempty(get(action_handle,'String')) + str_pattern = 'mask_filename = '; + str = get_string_as_string(config_txt, str_pattern); + if ~isnan(str) + set(action_handle,'String',str); + end +end + +% output +action_handle = output_action_handle; +if isempty(get(action_handle,'String')) + str_pattern = 'output_basename = '; + str = get_string_as_string(config_txt, str_pattern); + if ~isnan(str) + set(action_handle,'String',str); + end +end + + +end + if isModifyGeneral % invert phase data diff --git a/sepia_universal_variables.m b/sepia_universal_variables.m index 5cc9533..d36f0cb 100755 --- a/sepia_universal_variables.m +++ b/sepia_universal_variables.m @@ -14,7 +14,7 @@ % DO NOT change the order of the entities, add a new one at the end instead % %% Version -SEPIA_version = 'v1.2.2.5'; +SEPIA_version = 'v1.2.2.6'; %% PATH SEPIA_HOME = fileparts(mfilename('fullpath')); From 5021102d1d91eea00be1c5610c5eea1ba56a9c01 Mon Sep 17 00:00:00 2001 From: Kwok-Shing Chan <39571502+kschan0214@users.noreply.github.com> Date: Sat, 2 Dec 2023 16:04:06 -0500 Subject: [PATCH 2/6] Update SpecifyToolboxesDirectory.m --- SpecifyToolboxesDirectory.m | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/SpecifyToolboxesDirectory.m b/SpecifyToolboxesDirectory.m index 785bf86..a00023f 100644 --- a/SpecifyToolboxesDirectory.m +++ b/SpecifyToolboxesDirectory.m @@ -15,12 +15,12 @@ % Date modified: 25 Feb 2022 (v1.2) % %% Specify the directories of the toolbox here -MEDI_HOME = '/path/to/MEDI/Toolboxes/'; +MEDI_HOME = '/path/to/MEDI/Toolbox/'; STISuite_HOME = '/path/to/STI/Suite/'; -FANSI_HOME = '/path/to/FANSI/Toolboxes/'; -SEGUE_HOME = '/path/to/SEGUE/Toolboxes/'; -MRITOOLS_HOME = '/path/to/ROMEO/Toolboxes/'; -MRISC_HOME = '/path/to/MRISusceptibilityCalculationmethods/Toolboxes/'; +FANSI_HOME = '/path/to/FANSI/Toolbox/'; +SEGUE_HOME = '/path/to/SEGUE/Toolbox/'; +MRITOOLS_HOME = '/path/to/MRITOOLS/mritools_ubuntu-20.04_3.6.6/'; +MRISC_HOME = '/path/to/MRISusceptibilityCalculationmethods/Toolbox/'; ANTS_HOME = '/path/to/ANTs/bin/'; %% if you have any missing toolboxes, then specify it as empty array From c7e4c6f5a9d944b2debb343be4d4418f0c44bcf4 Mon Sep 17 00:00:00 2001 From: Kwok-Shing Chan <39571502+kschan0214@users.noreply.github.com> Date: Sun, 3 Dec 2023 15:32:46 -0500 Subject: [PATCH 3/6] Update README.md --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 044a61a..d82c7b2 100755 --- a/README.md +++ b/README.md @@ -41,7 +41,10 @@ If you have a more general question regarding the usage of SEPIA and/or other QS For full update log, please visit https://sepia-documentation.readthedocs.io/en/latest/getting_started/Release-note.html. -### 1.2.2.5 (current master) +### 1.2.2.6 (current master) +* Support read Input/Output information from sepia_config.m + +### 1.2.2.5 (commit 8630efe) * Fix the mismatch between SEPIA defined B0 direction and LPCNN when it is not along the z-direction * Fix the shared library issue when using ROMEO with latest versions of Matlab on Linux (see [here](https://github.com/korbinian90/ROMEO)) * Allow user to define atlases' directory paths From af155b1be4c3ebdd72294d1d621c63234564fe49 Mon Sep 17 00:00:00 2001 From: Kwok-Shing Chan <39571502+kschan0214@users.noreply.github.com> Date: Sun, 3 Dec 2023 16:22:48 -0500 Subject: [PATCH 4/6] bug fix --- .../callback/config/set_config_Callback.m | 26 ++++++++++++++----- utils/get_filename_in_directory.m | 4 +-- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/gui_func/callback/config/set_config_Callback.m b/gui_func/callback/config/set_config_Callback.m index 6d4dcc8..478a3fd 100644 --- a/gui_func/callback/config/set_config_Callback.m +++ b/gui_func/callback/config/set_config_Callback.m @@ -66,6 +66,8 @@ function set_config_Callback(config_filename,h) isempty(input2_action_handle.String).* isempty(input3_action_handle.String) .* ... isempty(header_action_handle.String))>0; +isModifyOutput = true; + % check which input method was used in the config file ind = regexp(config_txt, regexptranslate('wildcard','input(*).name'), 'once'); if ~isempty(ind) @@ -82,8 +84,10 @@ function set_config_Callback(config_filename,h) indicator_idx = regexp(config_txt,''''); str = config_txt(indicator_idx(find(indicator_idx > str_end_idx(1), 1 ))+1:indicator_idx(find(indicator_idx > str_end_idx(1), 1 )+1)-1); - if ~isnan(str) + if prod(~isnan(str)) && isfolder(str) set(action_handle,'String',str); + else + isModifyOutput = false; end end @@ -93,8 +97,10 @@ function set_config_Callback(config_filename,h) if and(isempty(input_action_handle.String),isempty(get(action_handle,'String'))) str_pattern = 'input\(1).name'; str = get_string_as_string(config_txt, str_pattern); - if ~isnan(str) + if prod(~isnan(str)) && isfile(str) set(action_handle,'String',str); + else + isModifyOutput = false; end end @@ -103,8 +109,10 @@ function set_config_Callback(config_filename,h) if and(isempty(input_action_handle.String),isempty(get(action_handle,'String'))) str_pattern = 'input\(2).name'; str = get_string_as_string(config_txt, str_pattern); - if ~isnan(str) + if prod(~isnan(str)) && isfile(str) set(action_handle,'String',str); + else + isModifyOutput = false; end end @@ -113,8 +121,10 @@ function set_config_Callback(config_filename,h) if and(isempty(input_action_handle.String),isempty(get(action_handle,'String'))) str_pattern = 'input\(3).name'; str = get_string_as_string(config_txt, str_pattern); - if ~isnan(str) + if prod(~isnan(str)) && isfile(str) set(action_handle,'String',str); + else + isModifyOutput = false; end end @@ -123,8 +133,10 @@ function set_config_Callback(config_filename,h) if and(isempty(input_action_handle.String),isempty(get(action_handle,'String'))) str_pattern = 'input\(4).name'; str = get_string_as_string(config_txt, str_pattern); - if ~isnan(str) + if prod(~isnan(str)) && isfile(str) set(action_handle,'String',str); + else + isModifyOutput = false; end end @@ -133,7 +145,7 @@ function set_config_Callback(config_filename,h) if isempty(get(action_handle,'String')) str_pattern = 'mask_filename = '; str = get_string_as_string(config_txt, str_pattern); - if ~isnan(str) + if prod(~isnan(str)) set(action_handle,'String',str); end end @@ -143,7 +155,7 @@ function set_config_Callback(config_filename,h) if isempty(get(action_handle,'String')) str_pattern = 'output_basename = '; str = get_string_as_string(config_txt, str_pattern); - if ~isnan(str) + if prod(~isnan(str)) && isModifyOutput set(action_handle,'String',str); end end diff --git a/utils/get_filename_in_directory.m b/utils/get_filename_in_directory.m index e9814d3..1522520 100644 --- a/utils/get_filename_in_directory.m +++ b/utils/get_filename_in_directory.m @@ -32,8 +32,8 @@ numFiles = 0; % check all files in the list -for klist = 1:length(fileList) - if ContainName(fileList(klist).name,pattern) +for klist = 1:length(fileList) % ignore hidden file + if ContainName(fileList(klist).name,pattern) && ~strcmp(fileList(klist).name(1),'.') numFiles = numFiles + 1; file(numFiles).name = fullfile(fileList(klist).folder,fileList(klist).name); end From 73e51e2b07531efd460580435b32c3e0329d01f2 Mon Sep 17 00:00:00 2001 From: Kwok-Shing Chan <39571502+kschan0214@users.noreply.github.com> Date: Sun, 3 Dec 2023 16:30:48 -0500 Subject: [PATCH 5/6] Update DICOM2Phase.m --- utils/DICOM2Phase.m | 35 ++++++----------------------------- 1 file changed, 6 insertions(+), 29 deletions(-) diff --git a/utils/DICOM2Phase.m b/utils/DICOM2Phase.m index 72eb051..1f6df4e 100644 --- a/utils/DICOM2Phase.m +++ b/utils/DICOM2Phase.m @@ -18,37 +18,14 @@ % Date created: 11 April 2018 % Date modified: 12 June 2018 % Date modified: 4 August 2022 (v1.0.1) -% +% Date modified: 3 December 2023 (v1.2.6.6) % function phase = DICOM2Phase(niiPhase) -% % change datatype to double -% dicomPhase = double(niiPhase.img); -% get scale slope -scaleSlope=niiPhase.hdr.dime.scl_slope; -% get scale inetercept -scaleIntercept=niiPhase.hdr.dime.scl_inter; - -% rescale phase -phase_rescale = single(niiPhase.img) * scaleSlope + scaleIntercept; -% find maximum and minimum in the data after rescaling -max_rescale = max(phase_rescale(:)); -min_rescale = min(phase_rescale(:)); - -% rescale phase data between -pi and pi usng the max and min in the data -% the limitation of this method is that if the max and min values might not -% corresponding to pi and -pi -phase = (phase_rescale - min_rescale) / (max_rescale - min_rescale) *2*pi - pi; -% % compute the new maximum value -% newMax = niiPhase.hdr.dime.glmax*scaleSlope + scaleIntercept; -% % compute the new minimum value -% newMin = niiPhase.hdr.dime.glmin*scaleSlope + scaleIntercept; -% % +1 for 0 -% fullRange = newMax-newMin + 1; -% -% % scale to true value of nifti file -% dicomPhaseRescale = (dicomPhase*scaleSlope) + scaleIntercept ; -% % scale the full range to [-pi,pi) -% phase = (dicomPhaseRescale-newMin) / fullRange * 2*pi - pi; +% suggested by Simon +phase = single(niiPhase.img); clear niiPhase; +max_phase = max(phase(:)); +min_phase = min(phase(:)); +phase = (phase - min_phase) / (max_phase - min_phase) *2*pi - pi; end \ No newline at end of file From c4c4e8a2330cac413834f01f914519770f1e24b8 Mon Sep 17 00:00:00 2001 From: Kwok-Shing Chan <39571502+kschan0214@users.noreply.github.com> Date: Sun, 3 Dec 2023 16:32:41 -0500 Subject: [PATCH 6/6] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d82c7b2..ffce2c8 100755 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ For full update log, please visit https://sepia-documentation.readthedocs.io/en/ ### 1.2.2.6 (current master) * Support read Input/Output information from sepia_config.m +* Phase DICOM values are rescaled using the max/min values in the data instead of rescale slope/intercept of the NIFTI ### 1.2.2.5 (commit 8630efe) * Fix the mismatch between SEPIA defined B0 direction and LPCNN when it is not along the z-direction