diff --git a/GUI/Osprey.m b/GUI/Osprey.m index cf563a1d..7376547d 100644 --- a/GUI/Osprey.m +++ b/GUI/Osprey.m @@ -30,7 +30,7 @@ logoFcn = @()imread('osprey.png', 'BackgroundColor', gui.colormap.Background); logoBanner = uiw.utility.loadIcon(logoFcn); % Here the intro banner is created -gui.d = uiw.dialog.About('Name', 'Osprey','Version','2.3.0','Date', 'June 24, 2022',... +gui.d = uiw.dialog.About('Name', 'Osprey','Version','2.4.0','Date', 'August 8, 2022',... 'Timeout', 3,'CustomText', 'Osprey is provided by Johns Hopkins University.',... 'ContactInfo', 'gabamrs@gmail.com','LogoCData', logoBanner); diff --git a/GUI/osp_Toolbox_Check.m b/GUI/osp_Toolbox_Check.m index ee4851da..2affedd7 100644 --- a/GUI/osp_Toolbox_Check.m +++ b/GUI/osp_Toolbox_Check.m @@ -32,7 +32,7 @@ % 2020-05-15: First version of the code. %% % 1. SAVE OSPREY VERSION%%% %%% 1. SAVE OSPREY VERSION%%% -OspreyVersion = 'Osprey 2.3.0'; +OspreyVersion = 'Osprey 2.4.0'; fprintf(['Timestamp %s ' OspreyVersion ' ' Module '\n'], datestr(now,'mmmm dd, yyyy HH:MM:SS')); hasSPM = 1; % For the compiled GUI %% % 2. GET SPMPATH AND TOOLBOXES%%% diff --git a/GUI/osp_onPrint.m b/GUI/osp_onPrint.m index 6a719ad8..a6dfc9e4 100644 --- a/GUI/osp_onPrint.m +++ b/GUI/osp_onPrint.m @@ -376,15 +376,15 @@ function osp_onPrint( ~, ~ ,gui) waterFitRangeString = ['Fitting range: ' num2str(MRSCont.opts.fit.rangeWater(1)) ' to ' num2str(MRSCont.opts.fit.rangeWater(2)) ' ppm']; % Where are the metabolite names stored? if strcmp(gui.fit.Style, 'ref') || strcmp(gui.fit.Style, 'w') - basisSet = MRSCont.fit.resBasisSet.(gui.fit.Style).(['np_sw_' num2str(MRSCont.processed.metab{gui.controls.Selected}.sz(1)) '_' num2str(MRSCont.processed.metab{gui.controls.Selected}.spectralwidth)]){1}; + basisSet = MRSCont.fit.resBasisSet.(gui.fit.Style).(['np_sw_' num2str(round(MRSCont.processed.metab{gui.controls.Selected}.sz(1))) '_' num2str(round(MRSCont.processed.metab{gui.controls.Selected}.spectralwidth))]){1}; basisSetNames = basisSet.name; subSpecName = gui.fit.Style; else if strcmp(gui.fit.Style, 'conc') - basisSet = MRSCont.fit.resBasisSet.(gui.fit.Style).(['np_sw_' num2str(MRSCont.processed.metab{gui.controls.Selected}.sz(1)) '_' num2str(MRSCont.processed.metab{gui.controls.Selected}.spectralwidth)]){basis,1}; + basisSet = MRSCont.fit.resBasisSet.(gui.fit.Style).(['np_sw_' num2str(round(MRSCont.processed.metab{gui.controls.Selected}.sz(1))) '_' num2str(round(MRSCont.processed.metab{gui.controls.Selected}.spectralwidth))]){basis,1}; basisSetNames = basisSet.name; subSpecName = basisSet.names{1}; else - basisSet = MRSCont.fit.resBasisSet.(gui.fit.Style).(['np_sw_' num2str(MRSCont.processed.metab{gui.controls.Selected}.sz(1)) '_' num2str(MRSCont.processed.metab{gui.controls.Selected}.spectralwidth)]){basis,1,subspectrum}; + basisSet = MRSCont.fit.resBasisSet.(gui.fit.Style).(['np_sw_' num2str(round(MRSCont.processed.metab{gui.controls.Selected}.sz(1))) '_' num2str(round(MRSCont.processed.metab{gui.controls.Selected}.spectralwidth))]){basis,1,subspectrum}; basisSetNames = basisSet.name; subSpecName = basisSet.names{1}; end diff --git a/GUI/osp_updateFitWindow.m b/GUI/osp_updateFitWindow.m index 0c8e73f9..ded0afdd 100644 --- a/GUI/osp_updateFitWindow.m +++ b/GUI/osp_updateFitWindow.m @@ -78,13 +78,13 @@ function osp_updateFitWindow(gui) waterFitRangeString = ['Fitting range: ' num2str(MRSCont.opts.fit.rangeWater(1)) ' to ' num2str(MRSCont.opts.fit.rangeWater(2)) ' ppm']; % Where are the metabolite names stored? if strcmp(gui.fit.Style, 'ref') || strcmp(gui.fit.Style, 'w') - basisSet = MRSCont.fit.resBasisSet.(gui.fit.Style).(['np_sw_' num2str(MRSCont.processed.metab{gui.controls.Selected}.sz(1)) '_' num2str(MRSCont.processed.metab{gui.controls.Selected}.spectralwidth)]){1}; + basisSet = MRSCont.fit.resBasisSet.(gui.fit.Style).(['np_sw_' num2str(round(MRSCont.processed.metab{gui.controls.Selected}.sz(1))) '_' num2str(round(MRSCont.processed.metab{gui.controls.Selected}.spectralwidth))]){1}; basisSetNames = basisSet.name; else if strcmp(gui.fit.Style, 'conc') - basisSet = MRSCont.fit.resBasisSet.(gui.fit.Style).(['np_sw_' num2str(MRSCont.processed.metab{gui.controls.Selected}.sz(1)) '_' num2str(MRSCont.processed.metab{gui.controls.Selected}.spectralwidth)]){basis,1}; + basisSet = MRSCont.fit.resBasisSet.(gui.fit.Style).(['np_sw_' num2str(round(MRSCont.processed.metab{gui.controls.Selected}.sz(1))) '_' num2str(round(MRSCont.processed.metab{gui.controls.Selected}.spectralwidth))]){basis,1}; basisSetNames = basisSet.name; else - basisSet = MRSCont.fit.resBasisSet.(gui.fit.Style).(['np_sw_' num2str(MRSCont.processed.metab{gui.controls.Selected}.sz(1)) '_' num2str(MRSCont.processed.metab{gui.controls.Selected}.spectralwidth)]){basis,1,subspectrum}; + basisSet = MRSCont.fit.resBasisSet.(gui.fit.Style).(['np_sw_' num2str(round(MRSCont.processed.metab{gui.controls.Selected}.sz(1))) '_' num2str(round(MRSCont.processed.metab{gui.controls.Selected}.spectralwidth))]){basis,1,subspectrum}; basisSetNames = basisSet.name; end end diff --git a/GUI/osp_updateLoadWindow.m b/GUI/osp_updateLoadWindow.m index 683b0aed..82d49534 100644 --- a/GUI/osp_updateLoadWindow.m +++ b/GUI/osp_updateLoadWindow.m @@ -200,7 +200,11 @@ function osp_updateLoadWindow(gui) set(ViewAxes.Children, 'Parent', gui.Plot.data{gui.load.Selected}.Children); set(gui.Plot.data{gui.load.Selected}.Children.Title, 'String', ViewAxes.Title.String); set(gui.Plot.data{gui.load.Selected}.Children, 'XLim',ViewAxes.XLim); - set(gui.upperBox.data.Info{gui.load.Selected},'Title', ['Actual file: ' MRSCont.files_ref{Exp,gui.controls.Selected}] ); + if ~isempty(MRSCont.files_ref) + set(gui.upperBox.data.Info{gui.load.Selected},'Title', ['Actual file: ' MRSCont.files_ref{Exp,gui.controls.Selected}] ); + else + set(gui.upperBox.data.Info{gui.load.Selected},'Title', ['Actual file: ' MRSCont.files{Exp,gui.controls.Selected}] ); + end case 'MM reference' if Exp > max(MRSCont.opts.MultipleSpectra.mm_ref) Exp = 1; diff --git a/GUI/osp_updateQuantifyWindow.m b/GUI/osp_updateQuantifyWindow.m index 35273d0a..af40b4bb 100644 --- a/GUI/osp_updateQuantifyWindow.m +++ b/GUI/osp_updateQuantifyWindow.m @@ -25,7 +25,7 @@ function osp_updateQuantifyWindow(gui) %%% 1. INITIALIZE %%% MRSCont = getappdata(gui.figure,'MRSCont'); % Get MRSCont from hidden container in gui class gui.layout.EmptyQuantPlot = 0; - basisSet = MRSCont.fit.resBasisSet.metab.(['np_sw_' num2str(MRSCont.processed.metab{gui.controls.Selected}.sz(1)) '_' num2str(MRSCont.processed.metab{gui.controls.Selected}.spectralwidth)]){gui.controls.act_z,1,gui.controls.act_y}; + basisSet = MRSCont.fit.resBasisSet.metab.(['np_sw_' num2str(round(MRSCont.processed.metab{gui.controls.Selected}.sz(1))) '_' num2str(round(MRSCont.processed.metab{gui.controls.Selected}.spectralwidth))]){gui.controls.act_z,1,gui.controls.act_y}; subSpecName = basisSet.names{1}; if ~(isfield(MRSCont.flags,'isPRIAM') || isfield(MRSCont.flags,'isMRSI')) || ~(MRSCont.flags.isPRIAM || MRSCont.flags.isMRSI) gui.upperBox.quant.Info = gui.layout.(gui.layout.quantifyTabhandles{gui.quant.Selected.Model}).Children(2).Children(1); diff --git a/README.md b/README.md index d164bbcc..c4d8e643 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,11 @@ Should you publish material that made use of Osprey, please cite the following p This work has been supported by NIH grants R01 EB016089, P41 EB15909, P41 EB031771, R01 EB023963, and K99 AG062230. -We wish to thank the following individuals for their contributions to the +We wish to thank collaborators and partners for providing LCModel basis sets and control files. If you use these resources for your analysis of the following data types, please mention the respective individuals in your acknowledgements: +- Siemens 7T STEAM (TE = 5 ms): Dr. Dinesh Deelchand (University of Minnesota) +- Siemens 3T and 7T SPECIAL (TE = 8.5/9 ms): Dr. Ariane Fillmer (PTB Berlin) + +We also wish to thank the following individuals for their contributions to the development of Osprey and shared processing code: - Jamie Near (McGill University, Montreal) diff --git a/ci/UnitTest.m b/ci/UnitTest.m index 140f1d46..f404ab00 100644 --- a/ci/UnitTest.m +++ b/ci/UnitTest.m @@ -56,20 +56,6 @@ rt{2} = table(results{2}); end - dir = strrep(which(['ci' filesep 'job' sequence '.m']),['job' sequence '.m'],['rawdata_CI' filesep 'sub-01' filesep 'anat']); - delete(fullfile(dir,'c1sub-01_T1w.nii.gz')); - delete(fullfile(dir,'c2sub-01_T1w.nii.gz')); - delete(fullfile(dir,'c3sub-01_T1w.nii.gz')); - delete(fullfile(dir,'sub-01_T1w.nii')); - delete(fullfile(dir,'sub-01_T1w_seg8.mat')); - - dir = strrep(which(['ci' filesep 'job' sequence '.m']),['job' sequence '.m'],['rawdata_CI' filesep 'sub-02' filesep 'anat']); - delete(fullfile(dir,'c1sub-02_T1w.nii.gz')); - delete(fullfile(dir,'c2sub-02_T1w.nii.gz')); - delete(fullfile(dir,'c3sub-02_T1w.nii.gz')); - delete(fullfile(dir,'sub-02_T1w.nii')); - delete(fullfile(dir,'sub-02_T1w_seg8.mat')); - dir = strrep(which(['ci' filesep 'job' sequence '.m']),['job' sequence '.m'],'derivatives'); rmdir(dir,'s') @@ -82,13 +68,6 @@ results{2} = runtests('Osprey_Plot_GUI_test.m'); rt{2} = table(results{2}); - dir = strrep(which(['ci' filesep 'job' sequence '.m']),['job' sequence '.m'],['rawdata_CI' filesep 'sub-01' filesep 'anat']); - delete(fullfile(dir,'c1sub-01_T1w.nii.gz')); - delete(fullfile(dir,'c2sub-01_T1w.nii.gz')); - delete(fullfile(dir,'c3sub-01_T1w.nii.gz')); - delete(fullfile(dir,'sub-01_T1w.nii')); - delete(fullfile(dir,'sub-01_T1w_seg8.mat')); - dir = strrep(which(['ci' filesep 'job' sequence '.m']),['job' sequence '.m'],'derivatives'); rmdir(dir,'s') end diff --git a/ci/azure-pipelines-develop-pull.yml b/ci/azure-pipelines-develop-pull.yml index 91a9d6c6..979c4ba4 100644 --- a/ci/azure-pipelines-develop-pull.yml +++ b/ci/azure-pipelines-develop-pull.yml @@ -1,5 +1,5 @@ # Pull request CI pipeline for Osprey -# Triggers for each pull request into the develop branch +# Triggers for each pull request into the develop branch # Starts with a quick Single Subject PRESS test # If the first stage is successful a Full PRESS job is triggered diff --git a/coreg/OspreyCoreg.m b/coreg/OspreyCoreg.m index 8e4e8977..28944d8e 100755 --- a/coreg/OspreyCoreg.m +++ b/coreg/OspreyCoreg.m @@ -38,6 +38,17 @@ % Checking for version, toolbox, and previously run modules [~,MRSCont.ver.CheckOsp ] = osp_CheckRunPreviousModule(MRSCont, 'OspreyCoreg'); +%Do some check on the naming convention first to avoid overwriting the +%output due to non BIDS conform data names +SameName = 0; +if MRSCont.nDatasets(1) > 1 + specFile = MRSCont.files{1}; + specFile2 = MRSCont.files{2}; + [~, SpecName, ~] = fileparts(specFile); + [~, SpecName2, ~] = fileparts(specFile2); + SameName = strcmp(SpecName,SpecName2); +end +MRSCont.coreg.SameName = SameName; % Set up saving location saveDestination = fullfile(MRSCont.outputFolder, 'VoxelMasks'); %CWDJ - Address in future update @@ -55,6 +66,12 @@ for kk = 1:MRSCont.nDatasets(1) [~] = printLog('OspreyCoreg',kk,1,MRSCont.nDatasets,progressText,MRSCont.flags.isGUI ,MRSCont.flags.isMRSI); if ~(MRSCont.flags.didCoreg == 1 && MRSCont.flags.speedUp && isfield(MRSCont, 'coreg') && (kk > length(MRSCont.coreg.vol_image))) || ~strcmp(MRSCont.ver.Osp,MRSCont.ver.CheckOsp) + + if SameName + [PreFix] = osp_generate_SubjectAndSessionPrefix(MRSCont.files{kk},kk); + else + PreFix = ''; + end % Get the input file name [~,filename,~] = fileparts(MRSCont.files{kk}); @@ -62,7 +79,7 @@ [~,~,T1ext] = fileparts(MRSCont.files_nii{kk}); %[_space-][_res-