diff --git a/detectOS.m b/detectOS.m new file mode 100644 index 00000000..123b5c41 --- /dev/null +++ b/detectOS.m @@ -0,0 +1,166 @@ +function [OS, OSVersion] = detectOS +%DETECTOS Name and version number of the operating system. +% OS = DETECTOS returns the name of the operating system as one of the +% following character vectors: 'windows', 'macos' (which includes OS X), +% 'solaris', 'aix', or another Unix/Linux distro in all lowercase +% characters (such as 'ubuntu' or 'centos'). An error is thrown if the +% operating system cannot be determined. +% +% [~, OSVERSION] = DETECTOS returns the operating system version number +% as a numeric row vector. For example, version 6.1.7601 is reported as +% OSVERSION = [6, 1, 7601]. If the OS version cannot be determined, a +% warning is issued and the empty numeric array is returned. +% +%See also COMPUTER, ISMAC, ISPC, ISUNIX. + +% Created 2016-01-05 by Jorg C. Woehl +% 2016-10-10 (JCW): Converted to standalone function, comments added (v1.0.1). +% 2018-04-20 (JCW): Used the recommended “replace” instead of “strrep”. +% 2021-04-22 (JCW): Version information added (v1.1). + +if ismac + % Mac + % see https://support.apple.com/en-us/HT201260 for version numbers + OS = 'macos'; + [status, OSVersion] = system('sw_vers -productVersion'); + OSVersion = strtrim(OSVersion); + if (~(status == 0) || isempty(OSVersion)) + warning('detectOS:UnknownMacOSVersion',... + 'Unable to determine macOS/OS X version.'); + OSVersion = ''; + end +elseif ispc + % Windows + % see https://en.wikipedia.org/wiki/Ver_(command) for version numbers + OS = 'windows'; + [status, OSVersion] = system('ver'); + OSVersion = regexp(OSVersion, '\d[.\d]*', 'match'); + if (~(status == 0) || isempty(OSVersion)) + warning('detectOS:UnknownWindowsVersion',... + 'Unable to determine Windows version.'); + OSVersion = ''; + end +elseif isunix + % Unix/Linux + % inspired in part by + % http://linuxmafia.com/faq/Admin/release-files.html and + % http://unix.stackexchange.com/questions/92199/how-can-i-reliably-get-the-operating-systems-name/92218#92218 + [status, OS] = system('uname -s'); % results in 'SunOS', 'AIX', or 'Linux' + OS = strtrim(OS); + assert((status == 0), 'detectOS:UnknownUnixDistro',... + 'Unable to determine Unix distribution.'); + if strcmpi(OS, 'SunOS') + OS = 'solaris'; % newer name + [status, OSVersion] = system('uname -v'); % example: + OSVersion = regexp(OSVersion, '\d[.\d]*', 'match'); + if (~(status == 0) || isempty(OSVersion)) + warning('detectOS:UnknownSolarisVersion',... + 'Unable to determine Solaris version.'); + OSVersion = ''; + end + elseif strcmpi(OS, 'AIX') + OS = 'aix'; + [status, OSVersion] = system('oslevel'); % example: 6.1.0.0 + OSVersion = regexp(OSVersion, '\d[.\d]*', 'match'); + if (~(status == 0) || isempty(OSVersion)) + warning('detectOS:UnknownAIXVersion',... + 'Unable to determine AIX version.'); + OSVersion = ''; + end + elseif strcmpi(OS, 'Linux') + OS = ''; + OSVersion = ''; + % first check if /etc/os-release exists and read it + [status, result] = system('cat /etc/os-release'); + if (status == 0) + % add newline to beginning and end of output character vector (makes parsing easier) + result = sprintf('\n%s\n', result); + % determine OS + OS = regexpi(result, '(?<=\nID=).*?(?=\n)', 'match'); % ID=... (shortest match) + OS = lower(strtrim(replace(OS, '"', ''))); % remove quotes, leading/trailing spaces, and make lowercase + if ~isempty(OS) + % convert to character vector + OS = OS{1}; + end + % determine OS version + OSVersion = regexpi(result, '(?<=\nVERSION_ID=)"*\d[.\d]*"*(?=\n)', 'match'); % VERSION_ID=... (longest match) + OSVersion = replace(OSVersion, '"', ''); % remove quotes + else + % check for output from lsb_release (more standardized than /etc/lsb-release itself) + [status, result] = system('lsb_release -a'); + if (status == 0) + % add newline to beginning and end of output character vector (makes parsing easier) + result = sprintf('\n%s\n', result); + % determine OS + OS = regexpi(result, '(?<=\nDistributor ID:\t).*?(?=\n)', 'match'); % Distributor ID: ... (shortest match) + OS = lower(strtrim(OS)); % remove leading/trailing spaces, and convert to lowercase + if ~isempty(OS) + % convert to character vector + OS = OS{1}; + end + % determine OS version + OSVersion = regexpi(result, '(?<=\nRelease:\t)\d[.\d]*(?=\n)', 'match'); % Release: ... (longest match) + else + % extract information from /etc/*release or /etc/*version filename + [status, result] = system('ls -m /etc/*version'); % comma-delimited file listing + fileList = ''; + if (status == 0) + fileList = result; + end + [status, result] = system('ls -m /etc/*release'); % comma-delimited file listing + if (status == 0) + fileList = [fileList ', ' result]; + end + fileList = replace(fileList, ',', ' '); + % remove spaces and trailing newline + fileList = strtrim(fileList); + OSList = regexpi(fileList, '(?<=/etc/).*?(?=[-_][rv])', 'match'); % /etc/ ... -release/version or _release/version + fileList = strtrim(strsplit(fileList)); + % find the first entry that's different from 'os', 'lsb', 'system', '', or 'debian'/'redhat' (unless it's the only one) + ii = 1; + while (ii <= numel(OSList)) + if ~(strcmpi(OSList{ii}, 'os') || strcmpi(OSList{ii}, 'lsb') || strcmpi(OSList{ii}, 'system') || ... + isempty(OSList{ii}) || strcmpi(OSList{ii}, 'redhat') || strcmpi(OSList{ii}, 'debian')) + OS = OSList{ii}; + OSFile = fileList{ii}; + break; + elseif (strcmpi(OSList{ii}, 'redhat') || strcmpi(OSList{ii}, 'debian')) + OS = OSList{ii}; % assign temporarily, but keep going + OSFile = fileList{ii}; + end + ii = ii+1; + end + % determine OS version + if ~isempty(OSFile) + [status, OSVersion] = system(['cat ' OSFile]); + if (status == 0) + OSVersion = regexp(OSVersion, '\d[.\d]*', 'match'); + else + OSVersion = ''; + end + end + end + end + assert(~isempty(OS), 'detectOS:UnknownLinuxDistro',... + 'Unable to determine Linux distribution.'); + if isempty(OSVersion) + warning('detectOS:UnknownLinuxVersion',... + 'Unable to determine Linux version.'); + OSVersion = ''; + end + else + error('detectOS:UnknownUnixDistro',... + 'Unknown Unix distribution.') + end +else + error('detectOS:PlatformNotSupported',... + 'Platform not supported.'); +end + +if iscell(OSVersion) + % convert to character vector + OSVersion = OSVersion{1}; +end +OSVersion = round(str2double(strsplit(OSVersion, '.'))); + +end \ No newline at end of file diff --git a/job/OspreyJob.m b/job/OspreyJob.m index 8aedca03..f94ec9ae 100755 --- a/job/OspreyJob.m +++ b/job/OspreyJob.m @@ -435,6 +435,11 @@ else opts.load.undoPhaseCycle = 1; end + if isfield(jobStruct,'SubSpecOrder') + MRSCont.opts.Order = jobStruct.SubSpecOrder'; + else + MRSCont.opts.Order = []; + end debug = '11'; if isfield(jobStruct,'exportParams') MRSCont.opts.exportParams.flag = 1; diff --git a/libraries/FID-A/inputOutput/io_loadspec_niimrs.m b/libraries/FID-A/inputOutput/io_loadspec_niimrs.m index 65f3d54f..d68cedcd 100644 --- a/libraries/FID-A/inputOutput/io_loadspec_niimrs.m +++ b/libraries/FID-A/inputOutput/io_loadspec_niimrs.m @@ -294,7 +294,7 @@ sqzDims{end+1} = dimsFieldNames{rr}; end end - subspecs = 0; + subspecs = 1; end if length(sqzDims)==5 @@ -348,12 +348,22 @@ undoPhaseCycle = 1; end if isfield(hdr_ext, 'Manufacturer') && strcmp(hdr_ext.Manufacturer,'Philips') && undoPhaseCycle - fids = fids .* repmat(conj(fids(1,:,:,:))./abs(fids(1,:,:,:)),[size(fids,1) 1]); + if hdr_ext.WaterSuppressed && hdr_ext.EchoTime == 0.080 + fids(:,:,:,1:2:end) = -fids(:,:,:,1:2:end); + end + if hdr_ext.WaterSuppressed && hdr_ext.EchoTime == 0.035 + fids(:,:,2:2:end,:) = -fids(:,:,2:2:end,:); + end end - if isfield(hdr_ext, 'Manufacturer') && strcmp(hdr_ext.Manufacturer,'GE') && undoPhaseCycle + if isfield(hdr_ext, 'Manufacturer') && strcmp(hdr_ext.Manufacturer,'GE') && ~strcmp(hdr_ext.SequenceName,'hbcd2') && undoPhaseCycle if hdr_ext.WaterSuppressed && hdr_ext.EchoTime == 0.080 fids(:,:,2:2:end,:) = -fids(:,:,2:2:end,:); end + else if isfield(hdr_ext, 'Manufacturer') && strcmp(hdr_ext.Manufacturer,'GE') && strcmp(hdr_ext.SequenceName,'hbcd2') && undoPhaseCycle + if ~hdr_ext.WaterSuppressed && hdr_ext.EchoTime == 0.080 + fids = -fids; + end + end end %Compared to NIfTI MRS, FID-A needs the conjugate diff --git a/libraries/FID-A/inputOutput/io_loadspec_twix.m b/libraries/FID-A/inputOutput/io_loadspec_twix.m index 375b5e4f..b39635de 100644 --- a/libraries/FID-A/inputOutput/io_loadspec_twix.m +++ b/libraries/FID-A/inputOutput/io_loadspec_twix.m @@ -91,7 +91,8 @@ ~isempty(strfind(sequence,'svs_st'))) && ... % or the Siemens STEAM sequence? isempty(strfind(sequence,'eja_svs')); %And make sure it's not 'eja_svs_steam'. isUniversal = ~isempty(strfind(sequence,'univ')) ||... %Is JHU universal editing sequence - ~isempty(strfind(sequence,'smm_svs_herc')); % Is Pavi's HERCULES sequence + ~isempty(strfind(sequence,'smm_svs_herc')) ||... % Is Pavi's HERCULES sequence + ~isempty(strfind(sequence,'svs_herc_gls')); % Is Gize's HERCULES sequence isDondersMRSfMRI = contains(sequence,'moco_nav_set'); %Is combined fMRI-MRS sequence implemented at Donders Institute NL isConnectom = contains(twix_obj.hdr.Dicom.ManufacturersModelName,'Connectom'); %Is from Connectom scanner (Apparently svs_se Dims are not as expected for vd) @@ -270,6 +271,43 @@ end end +% Product Siemens PRESS/STEAM can also include water reference scans. +if isSiemens && (matches(seq,'PRESS')||matches(seq,'STEAM')) && length(sqzSize)>3 + wRefs=true; + + % First, separate out the reference scans: + Ind = find(matches(sqzDims,'Phs')); + if ~(sqzSize(Ind)==2) + error('Expecting 2 entries in the "Phs" dimension, we found %i!',Ind); + end + fids_w = squeeze(GetSlice(fids,Ind,1)); + fids = squeeze(GetSlice(fids,Ind,2)); + sqzDims(Ind) = []; + sqzSize(Ind) = []; + + % Then, concat the averages and repetitions (if they exist) + if sqzSize(matches(sqzDims,'Rep'))>1 + DimAv = find(matches(sqzDims,'Ave')); + DimRep = find(matches(sqzDims,'Rep')); + + % Reshape the fids: + NewSize = sqzSize; + NewSize(DimAv) = NewSize(DimAv) * NewSize(DimRep); + NewSize(DimRep) = []; + fids = reshape(fids,NewSize); + + sqzSize = size(fids); + sqzDims(DimRep)=[]; + + % Reshape the water fids, throwing out the zero entries + NZ_Avs = find(any(~(squeeze(sum(abs(fids_w),[1,2]))==0),DimRep-2)); % Finds water fids in "averages" which are non-zero + fids_w =fids_w(:,:,NZ_Avs,:); + Sz = size(fids_w); + fids_w = reshape(fids_w,Sz(1),Sz(2),[]); + end + +end + % Extract voxel dimensions if (strcmp(version,'vd') || strcmp(version,'vb') || contains(version,'XA')) TwixHeader.VoI_RoFOV = twix_obj.hdr.Config.VoI_RoFOV; % Voxel size in readout direction [mm] @@ -851,4 +889,31 @@ out_w=[]; end +end %DONE + +function[SlicedArray] = GetSlice(Array, Dim, Idx) +%% function[SlicedArray] = GetSlice(Array, Dim, Idx) +% +% Description: Takes a slice of multi-dimensional array in dimension "Dim" +% at the specified index: Idx. +% +% Input: Array = Aray to be sliced +% Dim = Dimension in which to slice +% Idx = Index (or indices) to extract from dimension "Dim" +% Output: SlicedArray = Subset of array +% +% Example usage: +% For a 7D array, "Data": +% +% SlicedData = GetSlice(Data, 5, 1:5); +% returns 7D array but with only the 1st 5 entries in 5th dim +% +% C.W. Davies-Jenkins, Johns Hopkins University 2024 + +Specification = repmat({':'}, 1, ndims(Array)); % Create an vector whose length matches the dimensionality of the Array +Specification{Dim} = Idx; % At the specified Dim, add the indices we want to extract + +SlicedArray = Array(Specification{:}); % Apply the slicing! + +end diff --git a/plot/OspreyHTMLReport.m b/plot/OspreyHTMLReport.m index ffc5dd71..4c527fa3 100644 --- a/plot/OspreyHTMLReport.m +++ b/plot/OspreyHTMLReport.m @@ -1012,7 +1012,7 @@ end fprintf(fid,'\n\t'); fprintf(fid,'\n\t
fThalamus in voxel [%%] \t%5.2f
',table2array(MRSCont.seg.tables_Voxel_1(kk,4))*100); else @@ -1254,7 +1254,7 @@ fprintf(fid,'\n\t