diff --git a/DF_processing/calculateT2ExchangeCorrected.m b/DF_processing/calculateT2ExchangeCorrected.m index 784e75bf0063ca6df95c5d34316eea86791171c9..4c5e4390e65450bc471a072ad85a6e463280f4e2 100644 --- a/DF_processing/calculateT2ExchangeCorrected.m +++ b/DF_processing/calculateT2ExchangeCorrected.m @@ -4,7 +4,7 @@ pathName = 'DF data path'; sampleCriteria = {'Output'}; [localFilePathBase] = pathToDataFolder(pathName, sampleCriteria); -localFilePath = [localFilePathBase 'Output\']; +localFilePath = [localFilePathBase 'Output\FWHMBA Results 7.5e-3\']; load([localFilePath 'meanT2s.mat'], 'acceptableMeanT2s', 'acceptableStdT2s', 'metaboliteNamesDisplay'); % exchangeTimes in s-1 from Fichtner 2017 Occipital ROI. diff --git a/DF_processing/doFittingAndT2Calculations_DF.m b/DF_processing/doFittingAndT2Calculations_DF.m index a58b3a8acb7ff7fa6352be083294db1baa218a85..c7c4941d34d99bbb5e7634512d4adb9200becf9e 100644 --- a/DF_processing/doFittingAndT2Calculations_DF.m +++ b/DF_processing/doFittingAndT2Calculations_DF.m @@ -16,7 +16,7 @@ pH_default_Name = '_pH_XXX'; defaultLCModelUser = 'tborbath'; if fitAllSubjects - controlFilesBase = 'fitsettings_Subject_XXXX_'; + controlFilesBase = 'fitsettings_Subject_newNAA_XXXX_'; controlFilesBaseTE = strcat(controlFilesBase, 'TE'); controlFilesBaseSuffix = '_df_withUF_chosen_pH_XXX.control'; outputFileNameBase = strcat(defaultSubject, pH_default_Name, '_TE'); @@ -31,7 +31,7 @@ end if fitAllSubjects %pH_Values per subject - [~, ~, pH_table] = xlsread([localFilePathBase, 'Output/pH_sweep_hCs_shift_fixed_all_TE/pH_Results_Subjects.xlsx']); + [~, ~, pH_table] = xlsread([localFilePathBase, 'Output/pH_sweep_final_settings/pH_Results_Subjects.xlsx']); index_pH_value = 8; if pH_table{1,index_pH_value}~=40 error('I thought you want to use the pH value of the TE 40 for fitting'); diff --git a/DF_processing/doFittingAndT2Calculations_DF_pH.m b/DF_processing/doFittingAndT2Calculations_DF_pH.m index 4928f86a4e38c4604b54bf2bfd052036ca9d461c..6abd34ed254c486cc7cba48ef017e2a688083e78 100644 --- a/DF_processing/doFittingAndT2Calculations_DF_pH.m +++ b/DF_processing/doFittingAndT2Calculations_DF_pH.m @@ -8,7 +8,7 @@ fitAllSubjects = true; orderTEs = {'24' '32' '40' '52' '60'}; % orderTEs = {'40'}; subjects = {'1658';'1717';'2017';'3373';'3490';'5771';'6249';'6971'; '7338'; '7782';'9810'}; -% subjects = {'7338'; '7782';'9810';'1658';}; +% subjects = {'5771'; '9810';}; pH_values = [6.9 6.94 6.98 7.00:0.01:7.15]'; % pH_values = [7.05]'; diff --git a/DF_processing/evaluateFWHMT2Fits.m b/DF_processing/evaluateFWHMT2Fits.m new file mode 100644 index 0000000000000000000000000000000000000000..ac7c57096fc91706ef9ad035e532b135231fffcb --- /dev/null +++ b/DF_processing/evaluateFWHMT2Fits.m @@ -0,0 +1,268 @@ +function [figureIds, sortedIndeces] = evaluateFWHMT2Fits(downField_MM_Met, offsetPlot, figureIds, sortedIndeces) + +if ~exist('downField_MM_Met','var') + downField_MM_Met = 'DF'; +end + +if ~exist('offsetPlot','var') + offsetPlot = 0; +end +if ~exist('figureIds','var') + figureIds = {}; +end + +useTotalNAA = false; +doMetaboliteFWHMs = false; + +if offsetPlot <= 0 + plotColors = {[0 0 1], [1 0 0]}; + plotColors2 = {[0.0 0.4 0.0], [1 0.5 0.3]}; + plotColors2 = {[0.0 0.4 0.0], [0 0 0]}; +% plotColors2 = {[0.3 0.3 0.1], [0.2 0.5 0.05]}; +else + plotColors = {[0.0 0.7 0.9], [1 0 1]}; + plotColors2 = {[0.1 0.9 0.1], [0.9 0.6 0]}; + plotColors2 = {[0.1 0.9 0.1], [0.5 0.5 0.5]}; +end + +usePpm = false; + +if isempty(figureIds) + emptyFigureIds = true; +else + emptyFigureIds = false; +end + +pathNameMM = 'DF data path'; +outputFolder = 'Output\'; + +sampleCriteriaMM = {outputFolder}; +data_path = pathToDataFolder(pathNameMM, sampleCriteriaMM); + +load([data_path outputFolder 'tableT2sSubjects.mat'],'tableT2sSubjects') +load([data_path outputFolder 'tableConcentrationsSubjects.mat'],'tableConcentrationsSubjects') + +doFWHMevalutation = true; +if doFWHMevalutation + load([data_path outputFolder 'tableFWHMSubjects.mat'],'tableFWHMSubjects') + load([data_path outputFolder 'tableFWHMSubjects.mat'],'orderMetFWHMSubjects') +end + + +metaboliteNameOrder = {'Cr-CH3' 'Cr-CH2' 'NAA-ace' 'tCho_PE'}; +metaboliteNameOrderConc = {'Cr' 'Cr_CH2' 'NAA_ac' 'tCho_P'}; +metaboliteNameOrderFWHM = metaboliteNameOrder; +metaboliteNamesDisplay = {'tCr(CH3)';'tCr(CH2)';'NAA(CH3)';'tCho+';}; +subjects = {'1658';'1706';'1717';'2017';'3373';'3490';'5771';'6249';'6971';'7338';'7782';'9810'}; +yAxisLim_FWHM = [-3 28]; +yAxisLim_Res = [-5 5]; + +numberOfMet = length(metaboliteNameOrder); +TEs = [24 32 40 52 60]; +numberOfTEs = 5; +scanFrequency = 399.719; +numOfSubjects = length(tableT2sSubjects); +T2s = cell(numOfSubjects,numberOfMet); +R2s = cell(numOfSubjects,numberOfMet); +concentrations = cell(numOfSubjects, numberOfMet, numberOfTEs); +for indexSubject = 1:numOfSubjects + T2times = tableT2sSubjects{indexSubject}(2,2:end); + R2times = tableT2sSubjects{indexSubject}(3,2:end); + concentrationsSubject = tableConcentrationsSubjects{indexSubject}; + for indexMetabolite = 1:numberOfMet + index = find(strcmp(metaboliteNameOrder(indexMetabolite), tableT2sSubjects{indexSubject}(1,2:end))); + T2s(indexSubject,indexMetabolite) = T2times(index); + R2s(indexSubject,indexMetabolite) = R2times(index); + indexConc = find(strcmp(metaboliteNameOrderConc(indexMetabolite),concentrationsSubject(1,:))); + concentrations(indexSubject, indexMetabolite,:) = concentrationsSubject(2:6,indexConc); + end +end + +concentrations = cell2mat(concentrations); +T2sNumeric = str2double(T2s); +R2sNumeric = str2double(R2s); +nonNegT2s = T2sNumeric; +nonNegT2s(nonNegT2s<0) = NaN; +reshape(nonNegT2s,numberOfMet, numOfSubjects); + +acceptableT2s = nonNegT2s; +acceptableR2s = R2sNumeric; + +acceptableT2s(R2sNumeric<=0.51) = NaN; +acceptableR2s(R2sNumeric<=0.51) = NaN; + +reshape(acceptableT2s,numberOfMet, numOfSubjects); +acceptableMeanT2s = mean(acceptableT2s,1,'omitNaN'); +acceptableStdT2s = std(acceptableT2s,1,'omitNaN'); +acceptableMeanR2s = mean(acceptableR2s,1,'omitNaN'); +acceptableStdR2s = std(acceptableR2s,1,'omitNaN'); + + + +plusMinusSign = [' ' char(177) ' ']; +tableT2Summarized = cell(numberOfMet+1,4); +tableT2Summarized(2:end,1) = metaboliteNamesDisplay; +tableT2Summarized(1,3) = {'Std'}; +tableT2Summarized(1,4) = {['T2' plusMinusSign 'Std']}; +tableT2Summarized(1,5) = {['R2' plusMinusSign 'Std']}; +tableT2Summarized(2:end,2) = cellstr(num2str(acceptableMeanT2s','%.2f')); +tableT2Summarized(2:end,3) = cellstr(num2str(acceptableStdT2s','%.2f')); +tableT2Summarized(1,2) = {'T2 Summed'}; +tableT2Summarized(1,3) = {['T2' plusMinusSign 'Std']}; +tableT2Summarized(1,4) = {['R2' plusMinusSign 'Std']}; +for index=1:numberOfMet + tableT2Summarized{index+1,4} = [num2str(acceptableMeanT2s(index), '%.2f') plusMinusSign num2str(acceptableStdT2s(index), '%.2f')]; + tableT2Summarized{index+1,5} = [num2str(acceptableMeanR2s(index), '%.2f') plusMinusSign num2str(acceptableStdR2s(index), '%.2f')]; + tableT2Summarized{index+1,3} = [num2str(acceptableMeanT2s(index), '%.1f') plusMinusSign num2str(acceptableStdT2s(index), '%.1f')]; + tableT2Summarized{index+1,4} = [num2str(acceptableMeanR2s(index), '%.2f') plusMinusSign num2str(acceptableStdR2s(index), '%.2f')]; +end + +save([data_path , outputFolder, 'meanT2s_met.mat'],'acceptableMeanT2s', 'acceptableStdT2s', 'metaboliteNamesDisplay'); +exportFileXlsx = [data_path , outputFolder, 'T2_Results_Mean_std_met.xlsx']; +xlswrite(exportFileXlsx, tableT2Summarized, 1, 'A1'); + +%% plot the T2 Box plots +if emptyFigureIds + figureIds{1} = figure; +else + figure(figureIds{1}); +end + +positionsTicks = [2.2:1.5:1.5*numberOfMet+1.5]; +positions1 = positionsTicks + offsetPlot; +boxPlotT2 = boxplot(acceptableT2s, metaboliteNamesDisplay,'colors',plotColors{1},'symbol','+','positions',positions1,'width',0.18); +ylabel('T_2 (ms)') +axT2 = get(figureIds{1},'CurrentAxes'); +axT2.XAxis.TickLength = [0,0]; +axT2.YColor = 'k'; + +set(boxPlotT2(:,:),'linewidth',1); + +set(gca, 'YLim', [-5,200]); +set(gca, 'XLim', [positionsTicks(1)-abs(offsetPlot)-0.8 positionsTicks(end)+abs(offsetPlot)+0.8]); + +set(gca, 'YGrid', 'on'); +set(gca, 'XTickMode', 'manual'); +set(gca, 'XTick', positionsTicks); +set(gca, 'XTickLabelRotation', 90.0); +set(gca, 'FontSize', 16); +% title('T_2^\rho Relaxation Times'); +title('T_2 Relaxation Times'); + +%% FWHM +fwhmReshaped = zeros(size(tableFWHMSubjects,1)*size(tableFWHMSubjects,2), numberOfMet); +for indexMetabolite = 1 :numberOfMet + + indexTable = find(strcmp(orderMetFWHMSubjects(:), metaboliteNameOrderFWHM(indexMetabolite))); + + fwhms = tableFWHMSubjects(:,:,indexTable); + fwhms(fwhms>100)= NaN; + fwhmReshaped(:,indexMetabolite) = fwhms(:); +end + +%% T2 corrected FWHM +for i = 1:size(fwhmReshaped,1) + fwhmReshaped3(i,:) = fwhmReshaped(i,:) - 1./(pi*acceptableMeanT2s*1e-3); +end + +fwhmReshaped3 = fwhmReshaped3 - fwhmReshaped3(:,1); + +T2RelaxationLinewidth = 1./(pi*acceptableT2s*1e-3); + +%% plotting of FWHM +if emptyFigureIds + figureIds{2} = plotFWHMs(fwhmReshaped, [], metaboliteNamesDisplay, numberOfMet, scanFrequency, plotColors, '\Delta\nu_{1/2}', usePpm, yAxisLim_FWHM, offsetPlot); + figureIds{3} = plotFWHMs(fwhmReshaped3, [], metaboliteNamesDisplay, numberOfMet, scanFrequency, plotColors2, '\Delta\nu_{residual}', usePpm, yAxisLim_Res, offsetPlot); +else + figureIds{2} = plotFWHMs(fwhmReshaped, [], metaboliteNamesDisplay, numberOfMet, scanFrequency, plotColors, '\Delta \nu_{1/2}', usePpm, yAxisLim_FWHM, offsetPlot, figureIds{2}); + figureIds{3} = plotFWHMs(fwhmReshaped3, [], metaboliteNamesDisplay, numberOfMet, scanFrequency, plotColors2, '\Delta\nu_{residual}', usePpm, yAxisLim_Res, offsetPlot, figureIds{3}); +end + +%% +if emptyFigureIds + figureIds{4} = plotFWHMs(T2RelaxationLinewidth, [], metaboliteNamesDisplay, numberOfMet, scanFrequency, plotColors2, '\Delta\nu_{1/2} vs. (\pi T_2^{app})^{-1}', usePpm, yAxisLim_FWHM, offsetPlot); +else + figureIds{4} = plotFWHMs(T2RelaxationLinewidth, [], metaboliteNamesDisplay, numberOfMet, scanFrequency, plotColors2, '\Delta\nu_{1/2} vs. (\pi T_2^{app})^{-1}', usePpm, yAxisLim_FWHM, offsetPlot, figureIds{4}); +end +figureIds{4} = plotFWHMs(fwhmReshaped, [], metaboliteNamesDisplay, numberOfMet, scanFrequency, plotColors, '\Delta\nu_{1/2} vs. (\pi T_2^{app})^{-1}', usePpm, yAxisLim_FWHM, offsetPlot, figureIds{4}); + + +tableFWHMSummarized = cell(numberOfMet+1,4); +tableFWHMSummarized(2:end,1) = metaboliteNamesDisplay; +tableFWHMSummarized(1,2) = {['FWHM' plusMinusSign 'Std']}; +if usePpm + meanFwhmReshaped = mean(T2RelaxationLinewidth./scanFrequency, 'omitnan'); + stdFwhmReshaped = std(T2RelaxationLinewidth./scanFrequency, 'omitnan'); + writePrecision = '%.3f'; +else + meanFwhmReshaped = mean(T2RelaxationLinewidth, 'omitnan'); + stdFwhmReshaped = std(T2RelaxationLinewidth, 'omitnan'); + writePrecision = '%.2f'; + writePrecision = '%.1f'; +end +for index=1:numberOfMet + tableFWHMSummarized{index+1,2} = [num2str(meanFwhmReshaped(index), writePrecision) plusMinusSign num2str(stdFwhmReshaped(index), writePrecision)]; +end +exportFileXlsx = [data_path ,'Output\FWHM_Results_Mean_std_met.xlsx']; +xlswrite(exportFileXlsx, tableFWHMSummarized, 1, 'A1'); + + +end + +function [figId] = plotFWHMs(fwhmReshaped, FWHMSummedNumeric, metaboliteNames, numberOfMet, scanFrequency, ... + plotColors, titleName, usePpm, yAxisLim, offsetPlot, figId) +%% plot the FWHM Box plots +if ~exist('figId', 'var') + figId = figure; +else + figure(figId); + hold on +end +positionsTicks = 2.2:1.5:1.5*numberOfMet+1.5; +positions = positionsTicks + offsetPlot; +fwhm_plot_limit = 150; + +if (usePpm) + fwhmReshapedPpm = fwhmReshaped ./ scanFrequency; + fwhm_plot_limit_ppm = fwhm_plot_limit ./ scanFrequency; + %set yyaxis left active, hence both + yyaxis left +end + +boxPlotFWHM = boxplot(fwhmReshaped, metaboliteNames,'colors',plotColors{1},'symbol','+','positions',positions); + +if (usePpm) + yyaxis right + boxPlotFWHMPpm = boxplot(fwhmReshapedPpm, metaboliteNames,'colors',plotColors{1},'symbol','+','positions',positions); + set(gca,'YColor','k'); + yyaxis left +end + +ylabel('\Delta\nu (Hz)') +if usePpm + yyaxis right + ylabel('\Delta\nu (ppm)', 'Color', 'k') + yyaxis left +end + +ax = get(figId,'CurrentAxes'); +ax.XAxis.TickLength = [0,0]; +ax.YColor = 'k'; + +set(boxPlotFWHM(:,:),'linewidth',1); +set(gca, 'YGrid', 'on'); +set(gca, 'XTickMode', 'manual'); +set(gca, 'XTick', positionsTicks); +set(gca, 'XLim', [positionsTicks(1)-abs(offsetPlot)-0.8 positionsTicks(end)+abs(offsetPlot)+0.8]); +set(gca, 'XTickLabelRotation', 90.0); +set(gca, 'FontSize', 16); +title(titleName); + +if usePpm + set(gca, 'YLim', [yAxisLim(1),yAxisLim(2)]); + yyaxis right + set(gca, 'YLim', [yAxisLim(1)/scanFrequency,yAxisLim(2)./scanFrequency]); +else + set(gca, 'YLim', [0,yAxisLim(2)]); +end +end diff --git a/DF_processing/evaluate_pH_fit.m b/DF_processing/evaluate_pH_fit.m index c1c91dec6b65243448a3be6e12a05ce35847b6e2..debc067b228b5a3b368ae7f2f9ed9af7ae58d90e 100644 --- a/DF_processing/evaluate_pH_fit.m +++ b/DF_processing/evaluate_pH_fit.m @@ -3,16 +3,18 @@ use_hist = false; if use_hist outputFolder = 'Output\pH_sweep_hCs_hist_shift_fixed_all_TE\'; else - outputFolder = 'Output\pH_sweep\'; + outputFolder = 'Output\pH_sweep_final_settings\'; +% outputFolder = 'Output\pH_sweep_hCs_shift_fixed\'; end pathName = 'DF data path'; sampleCriteria = {outputFolder}; data_path = pathToDataFolder(pathName, sampleCriteria); -pH_values = [6.9:0.01:7.1]'; +pH_values = [6.9:0.01:7.15]'; doSubjects = true; if doSubjects subjects = {'1658';'1717';'2017';'3373';'3490';'5771';'6249';'6971'; '7338'; '7782';'9810'}; +% subjects = {'3373'}; else subjects = {'Summed'}; end diff --git a/DF_processing/lineBroadeningExchangingPeaks.m b/DF_processing/lineBroadeningExchangingPeaks.m new file mode 100644 index 0000000000000000000000000000000000000000..7b3cee705daa589155ab1cbf5ceab7b95b884a2f --- /dev/null +++ b/DF_processing/lineBroadeningExchangingPeaks.m @@ -0,0 +1,138 @@ +function lineBroadeningExchangingPeaks() + +%sample data and the equations from "Spin Dynamics - Malcolm Levitt +% page 520 chapter 19.5.2 and Lorentzian lineshape: pag 97 Chapter 5.8.2 +gamma = [-3000:0.1:3000]*2*pi; +gammaA = -1000*2*pi; +gammaB = 1000*2*pi; +lambda=0; + +plotPpm = false; +[S, figId] = calculateLineShape(gamma, gammaA, gammaB, 0.5*1e3, lambda, plotPpm, []); +[S, figId] = calculateLineShape(gamma, gammaA, gammaB, 1.0*1e3, lambda, plotPpm, [], figId); +[S, figId] = calculateLineShape(gamma, gammaA, gammaB, 2.5*1e3, lambda, plotPpm, [], figId); +[S, figId] = calculateLineShape(gamma, gammaA, gammaB, 3.5*1e3, lambda, plotPpm, [], figId); +[S, figId] = calculateLineShape(gamma, gammaA, gammaB, 6.3*1e3, lambda, plotPpm, [], figId); +legend('k=0.5x10^3s^{-1}','k=1.0x10^3s^{-1}','k=2.5x10^3s^{-1}','k=3.5x10^3s^{-1}','k=6.3x10^3s^{-1}') + +% ------------------------------------------------------------- +water = 0.0; %ppm +ppmRange = [-10:0.0001:10]; + +omega = 42.577 * 9.41 * (5.75-4.7); +scanfrequency = 399*2*pi; +% scanfrequency = 42.57747 * 2.8*2*pi;%3T +gamma = ppmRange * scanfrequency; +gammaWater = water * scanfrequency; +lambda = 0; + +%values from Haris 2012, NMR Biomed +PCr_1 = 2.5; % ppm +PCr_2 = 1.8; % ppm +Cr = 1.8; % ppm +k_PCr_1 = 140;%s-1 +k_PCr_2 = 120;%s-1 +k_Cr = 950;%s-1 + +gammaPCr_1 = PCr_1 * scanfrequency; +gammaPCr_2 = PCr_2 * scanfrequency; +gammaCr = Cr * scanfrequency; +plotPpm = true; +[S, figId] = calculateLineShape(gamma, gammaWater, gammaPCr_1, k_PCr_1, lambda, plotPpm, ppmRange); +[S, figId] = calculateLineShape(gamma, gammaWater, gammaPCr_2, k_PCr_2, lambda, plotPpm, ppmRange, figId); +[S, figId] = calculateLineShape(gamma, gammaWater, gammaCr, k_Cr, lambda, plotPpm, ppmRange, figId); +legend('PCr 2.5ppm k=140s^{-1}', 'PCr 1.8ppm k=120s^{-1}', 'Cr 1.8ppm k=950s^{-1}'); + +Urea = 5.75-4.7; % ppm +k_Urea = 7;% k= 6.76 Hz Occ lobe GM rich; k = 8.00 Hz Parietal WM [Fichtner 9.4T, MRM 2017] + +gammaUrea = Urea * scanfrequency; +plotPpm = true; +[S, figId] = calculateLineShape(gamma, gammaWater, gammaUrea, 0.1, lambda, plotPpm, ppmRange+4.7); +[S, figId] = calculateLineShape(gamma, gammaWater, gammaUrea, k_Urea, lambda, plotPpm, ppmRange+4.7,figId); +[S, figId] = calculateLineShape(gamma, gammaWater, gammaUrea, 13, lambda, plotPpm, ppmRange+4.7,figId); +legend('Urea 5.75ppm k=0.1s^{-1}','Urea 5.75ppm k=7s^{-1}','Urea 5.75ppm k=13s^{-1}'); +if plotPpm + xlim([5.7 5.8]) +else + xlim([410 430]) +end +ylim([-0.001 0.1]) + +%values from [Fichtner 9.4T, MRM 2017] +DF58 = 5.8-4.7; % ppm +DF68 = 6.8-4.7; % ppm +DF82 = 8.2-4.7; % ppm +DF83 = 8.3-4.7; % ppm +DF85 = 8.5-4.7; % ppm +NAA = 7.82-4.7; % ppm +k_DF58 = 6.76;% k= 6.76 Hz Occ lobe GM rich; k = 8.00 Hz Parietal WM +k_DF68 = 2.34;% k= 2.34 Hz Occ lobe GM rich; k = 2.42 Hz Parietal WM +k_DF82 = 9.32;% k= 9.32 Hz Occ lobe GM rich; k = 10.6 Hz Parietal WM +k_DF83 = 13.8;% k= 13.8 Hz Occ lobe GM rich; k = 13.4 Hz Parietal WM +k_DF85 = 3.31;% k= 3.31 Hz Occ lobe GM rich; k = 4.05 Hz Parietal WM +k_NAA = 0.74;% k= 0.74 Hz Occ lobe GM rich; k = 0.92 Hz Parietal WM + +gammaDF58 = DF58 * scanfrequency; +gammaDF68 = DF68 * scanfrequency; +gammaDF82 = DF82 * scanfrequency; +gammaDF83 = DF83 * scanfrequency; +gammaDF85 = DF85 * scanfrequency; +gammaNAA = NAA * scanfrequency; +plotPpm = true; +[S, figId] = calculateLineShape(gamma, gammaWater, gammaDF58, k_DF58, lambda, plotPpm, ppmRange+4.7); +[S, figId] = calculateLineShape(gamma, gammaWater, gammaDF68, k_DF68, lambda, plotPpm, ppmRange+4.7,figId); +[S, figId] = calculateLineShape(gamma, gammaWater, gammaDF82, k_DF82, lambda, plotPpm, ppmRange+4.7,figId); +[S, figId] = calculateLineShape(gamma, gammaWater, gammaDF83, k_DF83, lambda, plotPpm, ppmRange+4.7,figId); +[S, figId] = calculateLineShape(gamma, gammaWater, gammaDF85, k_DF85, lambda, plotPpm, ppmRange+4.7,figId); +[S, figId] = calculateLineShape(gamma, gammaWater, gammaNAA, k_NAA, lambda, plotPpm, ppmRange+4.7,figId); +legend('DF_{5.75} k=6.76s^{-1}','DF_{6.80} k=2.346s^{-1}','DF_{8.20} k=9.32s^{-1}','DF_{8.30} k=13.8s^{-1}','DF_{8.50} k=3.31s^{-1}', 'NAA k=0.74s^{-1}'); +if plotPpm + xlim([5.7 8.6]) + xlim([4.6 8.6]) +else + xlim([400 1600]) +end +ylim([-0.001 0.25]) +set(gca,'xdir','reverse') +xlabel('\delta (ppm)') +ylabel('Signal (arb. u.)') + +% results of FWHM +%DF58 = 2.17 Hz +%DF68 = 0.7581 Hz +%DF82 = 2.95 Hz +%DF83 = 4.389 Hz +%DF85 = 1.0374 Hz +%NAA = 0.2394 Hz +end + +function [S, figId] = calculateLineShape(gamma, gammaA, gammaB, k, lambda, plotPpm, ppmRange, figId) +gammaDif = gammaB-gammaA; +R = sqrt(abs(k^2-(gammaDif/2)^2)); +gammaM = 0.5*(gammaA+gammaB); + +% signal_L = 1 ./ ((lambda+k) + 1i*(gamma-(gammaM+R))); +% signal_R = 1 ./ ((lambda+k) + 1i*(gamma-(gammaM-R))); +% +% S = 0.5 .*(1-1i*k/R) .* signal_L+... +% 0.5 .*(1+1i*k/R) .* signal_R; +S = 0.5 .*(1-1i*k/R) .* lorentz(gamma, gammaM+R, lambda+k)+... + 0.5 .*(1+1i*k/R) .* lorentz(gamma, gammaM-R, lambda+k); + +if exist('figId', 'var') + figure(figId) +else + figId = figure; + hold on +end +if plotPpm + plot(ppmRange, real(S)) +else + plot(gamma/(2*pi), real(S)) +end +end + +function signal = lorentz(gamma,gammaL, lambda) + signal = 1 ./ (lambda + 1i*(gamma-gammaL)); +end \ No newline at end of file diff --git a/DF_processing/plot_mean_std_of_spectra_DF.m b/DF_processing/plot_mean_std_of_spectra_DF.m index 8bd586b63887eb919cd12710ebd325ee6d11621f..f999ab505dae381d576308e0222962e19502fc19 100644 --- a/DF_processing/plot_mean_std_of_spectra_DF.m +++ b/DF_processing/plot_mean_std_of_spectra_DF.m @@ -10,6 +10,7 @@ TEs = [24; 32; 40; 52; 60]; colors = {[0 0.7 0]; [1 0 0]; [0 0 1]; [0 0 0]; [0 0.5 0.5];}; numberOfTEs = length(TEs); offsetStep = 2.7e-5; +offsetStep = 1.e-5; offSetBase = offsetStep * (numberOfTEs + 1); for indexTE = 1:numberOfTEs @@ -99,14 +100,14 @@ end %% figure(1) -stdAlpha = 0.4; -hold on -h = area(ppmScale,[(meanSpectrum - stdSpectrum) + offset (stdSpectrum * 2)]); -h(1).FaceColor = 'none'; -h(2).FaceColor = colorSpectrum; -h(2).FaceAlpha = stdAlpha; -h(1).EdgeColor = 'none'; -h(2).EdgeColor = 'none'; +% stdAlpha = 0.4; +% hold on +% h = area(ppmScale,[(meanSpectrum - stdSpectrum) + offset (stdSpectrum * 2)]); +% h(1).FaceColor = 'none'; +% h(2).FaceColor = colorSpectrum; +% h(2).FaceAlpha = stdAlpha; +% h(1).EdgeColor = 'none'; +% h(2).EdgeColor = 'none'; hold on pSpectrum = plot(ppmScale,meanSpectrum + offset, 'LineWidth',2, 'Color', colorSpectrum); @@ -114,7 +115,8 @@ xlim([5.5 9.5]); set(gca,'xDir','reverse') set(gca,'LineWidth',1); set(gca,'ytick',[]) -xlabel('[ppm]'); +xlabel('\delta (ppm)'); +ylabel('Signal (arb.u.)'); title('Spectra mean and standard deviation') % title(['Spectra TE ' num2str(TE) ' ms']) end \ No newline at end of file diff --git a/DF_processing/plot_pH_sweep.m b/DF_processing/plot_pH_sweep.m index 1c3202b07e42022d087512e731fc2d73bfa1a6b4..e1c967e4d6ed70ebd4238e792904f926593cb5ea 100644 --- a/DF_processing/plot_pH_sweep.m +++ b/DF_processing/plot_pH_sweep.m @@ -9,14 +9,18 @@ data_path = pathToDataFolder(pathName, sampleCriteria); filepath = [data_path outputFolder]; if use_hCs + figure; + subplot(1,2,1) metaboliteName = 'Homocarnosine'; metaboliteAbbr = 'hCs'; else + hold on + subplot(1,2,2) metaboliteName = 'Histidine'; metaboliteAbbr ='hist'; end pH_values =6.91:0.04:7.15; -figure; + hold on for pH_value = pH_values filename = [metaboliteAbbr '_imidazole_pH_' sprintf('%.2f', pH_value) '.RAW']; @@ -29,13 +33,13 @@ end % deltaChar = char(948); % it doesn't take the ASCII character -xlabel('[ppm]'); +xlabel('\delta (ppm)'); xlim([6.9 8.2]) set(gca,'xDir','reverse'); title([metaboliteName ' pH Dependence']); set(gca,'LineWidth',1); yticks([]) -ylabel('[arb. unit]') +ylabel('(arb. unit)') % set(gca,'ytick',[]); set(gca,'fontsize',14); set(gca,'FontWeight','bold'); diff --git a/DF_processing/ureaExchangeRateCalculation.m b/DF_processing/ureaExchangeRateCalculation.m new file mode 100644 index 0000000000000000000000000000000000000000..dcc8226f6fd34ac227c8e72fad5229626aa7d0af --- /dev/null +++ b/DF_processing/ureaExchangeRateCalculation.m @@ -0,0 +1,25 @@ +k_0 = 0; +pKw = 13.617; +k_a = 9.95*1e6; %l/mol*s +k_b = 6.21*1e6; %l/mol*s +R_1s = 1.9; %s-1 +E_Ab= 43.52; %kJ/mol +HR = 55.84; %kJ/mol +R = 8.314; %J/(mol K) +pHs = [6.0:0.01:8.0]; +k_sw = zeros(length(pHs),1); +for index=1:length(pHs) + pH =pHs(index); + k_sw(index) = k_b * 10^(pH-pKw)+k_a *10^(-pH) + k_0; +end +figure +plot(pHs, k_sw) + +T = 310.15; +temp1 = HR / (R*log(10)) * (1/298.15 - 1/T); +temp2 = E_Ab / (R*log(10)) * (1/310.15-1/T); +k_sw = k_b * 10^(pH-14+temp1 + temp2) + +1/R_1s + +pi^2*2.5*1e-3*63.5^2 \ No newline at end of file diff --git a/MM_T1processing/plot_mean_std_of_spectra_MMT1.m b/MM_T1processing/plot_mean_std_of_spectra_MMT1.m index 14fbe603c6d433b6e22e9b1584066c42a23c7f99..26d7983bffc3013bf3a9dbb2688e94104142e394 100644 --- a/MM_T1processing/plot_mean_std_of_spectra_MMT1.m +++ b/MM_T1processing/plot_mean_std_of_spectra_MMT1.m @@ -3,9 +3,11 @@ function plot_mean_std_of_spectra_MM pathName = 'MM data path'; [path] = pathToDataFolder(pathName); -fileNameBase = [path, 'Summed_spectra_TE']; +fileNameBase = [path, 'Summed_spectra_']; TEs = [24; 32; 40; 52; 60]; +TI1 = []; +TI2 = []; colors = {[0 0.7 0]; [1 0 0]; [0 0 1]; [0 0 0]; [0 0.5 0.5];}; numberOfTEs = length(TEs); diff --git a/MM_T1processing/plot_mean_std_of_spectra_T1.m b/MM_T1processing/plot_mean_std_of_spectra_T1.m new file mode 100644 index 0000000000000000000000000000000000000000..f0ad46b3608b789e19fd73309db157b347166e1c --- /dev/null +++ b/MM_T1processing/plot_mean_std_of_spectra_T1.m @@ -0,0 +1,172 @@ +function plot_mean_std_of_spectra_MM + +downField_MM_Met = 'MM'; +switch downField_MM_Met + case 'DF' + pathName = 'DF data path'; + TEs = [24; 24; 32; 40; 52; 60; ]; + colors = {[0 0.7 0]; [0 0.7 0]; [0 0 0]; [0 0 1]; [1 0 0]; [0 0.5 0.5];}; + offsetStep = 2.2e-5; + case 'MM' + pathName = 'MM T1 data path'; + TEs = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; ]; + colors = {[76 187 23]/255; [76 187 23]/255; [76 187 23]/255; [76 187 23]/255; [76 187 23]/255; [1 121 111]/255; [75 0 130]/255; [75 0 130]/255; [75 0 130]/255; [75 0 130]/255; [75 0 130]/255;}; + offsetStep = 7.0e-5; + case 'MM WM' + pathName = 'MM WM T1 data path'; + TEs = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; ]; + colors = {[76 187 23]/255; [76 187 23]/255; [76 187 23]/255; [76 187 23]/255; [76 187 23]/255; [1 121 111]/255; [75 0 130]/255; [75 0 130]/255; [75 0 130]/255; [75 0 130]/255; [75 0 130]/255;}; + offsetStep = 7.0e-5; + case 'Met' + pathName = 'DF data path'; + TEs = [24; 32; 40; 52; 60; ]; + colors = {[0 0.7 0]; [0 0 0]; [0 0 1]; [1 0 0]; [0 0.5 0.5];}; + offsetStep = 2.3e-4; +end + +[path] = pathToDataFolder(pathName); + +fileNameBase = [path, 'Summed_Averaged_TI1_']; + + +numberOfTEs = length(TEs); + +offSetBase = offsetStep * (numberOfTEs + 7); %+7 for WM + +for indexTE = 1:numberOfTEs + fileName = [fileNameBase num2str(TEs(indexTE))]; + offset = offSetBase - indexTE * offsetStep; + if (indexTE == 1) && (strcmp(downField_MM_Met,'DF')) + plotOneTE(fileName, TEs(indexTE), colors{indexTE}, offset+offsetStep/2, 'DF_up'); + else + plotOneTE(fileName, TEs(indexTE), colors{indexTE}, offset, downField_MM_Met); + end +end + +end + +function plotOneTE(fileName, TE, colorSpectrum, offset, downField_MM_Met) +load([fileName '.mat'], 'summedSpectraTI') + +zeroPPM = 4.67; +nTimepoints = size(summedSpectraTI.Data{1},summedSpectraTI.kx_dim); +nAverages = size(summedSpectraTI.Data{1},summedSpectraTI.meas_dim); +waterFreq = summedSpectraTI.Parameter.Headers.ScanFrequency * 1E-6; +bandwidth = summedSpectraTI.Parameter.Headers.Bandwidth_Hz; +frequencyRange = linspace(-bandwidth/2,bandwidth/2,nTimepoints); + +if strcmp(downField_MM_Met,'DF_up') + fidSpectra = summedSpectraTI.Data{1}(:,1,1,1,1,1,1,1,1,1,1,:) * 5; +else + fidSpectra = summedSpectraTI.Data{1}(:,1,1,1,1,1,1,1,1,1,1,:) * 1; +end + +fidWater = summedSpectraTI.Data{1}(:,1,1,1,1,1,1,1,2,1,1,:); +spectra = squeeze(fftshift(fft(fidSpectra))); +water = squeeze(fftshift(fft(fidWater))); +meanSpectrum = mean(spectra,2); +stdSpectrum = std(spectra,[],2); +relativeStd = stdSpectrum ./ max(meanSpectrum) * 100; + +ppmVector = (frequencyRange)/waterFreq+zeroPPM; + +% figure(101) +% plot(ppmVector,relativeStd) +% xlim([0.5 4.2]); +% set(gca,'xDir','reverse') + + +%% +scalingRange = (ppmVector < 1.8) & (ppmVector > 0); +for indexAverage = 1:nAverages + [maxWater,indexMaxWater] = max(abs(real(water(:, indexAverage)))); + + [~, indexMaxWaterInRange] = max(abs(real((water(scalingRange, indexAverage)-mean(water(scalingRange, indexAverage)))))); + + [maxWaterInRange, ~] = max(real(water(scalingRange, indexAverage))); + minWaterInRange = min(real(water(scalingRange, indexAverage))); + + maxSpectraInRange = max(real(spectra(scalingRange, indexAverage))); + minSpectraInRange = min(real(spectra(scalingRange, indexAverage))); + + indexStart = find(scalingRange); + indexMaxWaterInRange = indexMaxWaterInRange + indexStart(1); + referenceLines = zeros(nTimepoints,1); + referenceLines(:) = -maxWaterInRange*2; + referenceLines(indexMaxWaterInRange:indexMaxWater + (indexMaxWater - indexMaxWaterInRange)) = maxWaterInRange*2; + + plotOffset = maxSpectraInRange; +% figWaterSpectra = figure(2); +% hold on +% plot(ppmScale, real(water(:,indexAverage)) - minWaterInRange + plotOffset,'b') +% plotScale = (maxWaterInRange-minWaterInRange); +% ylim([minSpectraInRange-(plotOffset*0.3) plotScale*1.2+plotOffset]); +% hold on +% pSpectra = plot(ppmScale, real(spectra(:,indexAverage)),'r'); +% hold on +% % figure +% plot(ppmScale, referenceLines, 'k--') +% xlim([0 8.5]); +% set(gca,'xDir','reverse') +% set(gca,'LineWidth',1); +% % set(gca,'ytick',[]) +% xlabel('[ppm]'); +% makedatatip(pSpectra,[indexMaxWaterInRange]) +% +% print(['WaterSpectraComparisonPlots\' num2str(indexAverage) '_' fileName],'-dpng') +% close(figWaterSpectra) +end +%% +% figure +% plot(ppmScale, real(spectra)) + +% xlim([0.5 4.2]); +% set(gca,'xDir','reverse') +% set(gca,'LineWidth',1); +% % set(gca,'ytick',[]) +% xlabel('[ppm]'); +% title(['Individual Spectra TE ' num2str(TE) ' ms']) + +%% +figure(1) +stdAlpha = 0.4; +hold on +if strcmp(downField_MM_Met,'DF_up') + indexDFCut = find(ppmVector > 8.6, 1, 'first'); + ppmVector = ppmVector(indexDFCut:end); + meanSpectrum = meanSpectrum(indexDFCut:end); + stdSpectrum = stdSpectrum(indexDFCut:end); +end + +h = area(ppmVector,[(meanSpectrum - stdSpectrum) + offset (stdSpectrum * 2)]); + +h(1).FaceColor = 'none'; +h(2).FaceColor = colorSpectrum; +h(2).FaceAlpha = stdAlpha; +h(1).EdgeColor = 'none'; +h(2).EdgeColor = 'none'; +hold on +pSpectrum = plot(ppmVector,meanSpectrum + offset, 'LineWidth',2, 'Color', colorSpectrum); + +switch downField_MM_Met + case 'DF' + xlim([5.5 9.4]); + case 'DF_up' + xlim([5.5 9.4]); + case 'MM' + xlim([0.5 4.2]); +% ylim([4.5e-6 4.7e-5]); + case 'MM WM' + xlim([0.5 4.2]); + %ylim([2e-6 1.3e-4]); %TODO: check why scaling is different, then MM + case 'Met' + xlim([0.5 4.2]); + ylim([7e-5 1.65e-3]); +end +set(gca,'xDir','reverse') +set(gca,'LineWidth',1); +set(gca,'ytick',[]) +xlabel('[ppm]'); +title('Spectra mean and standard deviation') +% title(['Spectra TE ' num2str(TE) ' ms']) +end \ No newline at end of file diff --git a/MM_T1processing/reconstruct_all_MMT1.m b/MM_T1processing/reconstruct_all_MMT1.m index 3c679cc14b7e25594c4552e89ea11dbb27206525..969d64f796a833cc1b1a89739c5dec4f14c85162 100644 --- a/MM_T1processing/reconstruct_all_MMT1.m +++ b/MM_T1processing/reconstruct_all_MMT1.m @@ -1,19 +1,18 @@ function reconstruct_all_MM() -pathName = 'MM T1 data path'; +pathName = 'MM WM T1 data path'; subjects = { ... -% '1717' ... -% '2016' ... -% '9810' ... -% '3490' ... -% '2017' ... - '7338'... -% '1658'... -% '2349'... -% '7782'... -% '3373'... -% '2020'... - }; + '1717' ... + '2016' ... + '9810' ... + '3490' ... + '2017' ... + '7338'... + '1658'... + '2349'... + '2020'... + }; % '7782'... + % '3373'... pathBase = pathToDataFolder(pathName, subjects); diff --git a/MM_processing/plot_mean_std_of_spectra_MM.m b/MM_processing/plot_mean_std_of_spectra_MM.m index f06457ca18d6b6413ad64b2b3b2002ac0b58f73f..bfbec1a23982461390aeb6dbe2f5c6ddf8061932 100644 --- a/MM_processing/plot_mean_std_of_spectra_MM.m +++ b/MM_processing/plot_mean_std_of_spectra_MM.m @@ -1,6 +1,6 @@ function plot_mean_std_of_spectra_MM -downField_MM_Met = 'MM WM'; +downField_MM_Met = 'MM'; switch downField_MM_Met case 'DF' pathName = 'DF data path'; diff --git a/MM_processing/reconstruct_MM.m b/MM_processing/reconstruct_MM.m index 2f7fd4d7dbc5c75d197079fbe175a20d9b880dd0..581135c80518b902a3735273e3c912eb1aea6d63 100644 --- a/MM_processing/reconstruct_MM.m +++ b/MM_processing/reconstruct_MM.m @@ -5,9 +5,9 @@ end %% a = MR_spectroS(fid_id,1); %% -trunc_ms = 250; -truncPoint = floor( trunc_ms/(a.Parameter.Headers.DwellTimeSig_ns*1e-6)); -a = a.Truncate(truncPoint); +% trunc_ms = 250; +% truncPoint = floor( trunc_ms/(a.Parameter.Headers.DwellTimeSig_ns*1e-6)); +% a = a.Truncate(truncPoint); a = a.FrequencyAlign; a = a.DeleteMovedAverages; @@ -22,10 +22,10 @@ a.Parameter.FreqAlignFreqDomainSettings.selectedMix = 1; %indices of Interest: given in ppm % water peak -a.Parameter.FreqAlignFreqDomainSettings.peaksInPpm = [3.925]; +% a.Parameter.FreqAlignFreqDomainSettings.peaksInPpm = [3.925]; %set zeroFillingParameter to get smooth approximations -a.Parameter.FreqAlignFreqDomainSettings.zeroFillFactor = 50; +% a.Parameter.FreqAlignFreqDomainSettings.zeroFillFactor = 50; %search area (+-) in ppm a.Parameter.FreqAlignFreqDomainSettings.searchArea = 0.1; @@ -37,20 +37,20 @@ a.Parameter.FreqAlignFreqDomainSettings.splineSmoothingCoeff = 0.01; % do the actual Frequency Alignment a = a.FrequencyAlignFreqDomain; %% -a.Parameter.HsvdSettings.bound = [-160 250]; -a.Parameter.HsvdSettings.n = size(a.Data{1},1); -a.Parameter.HsvdSettings.p = 25; -[~, a] = a.Hsvd; +% a.Parameter.HsvdSettings.bound = [-160 160]; +% a.Parameter.HsvdSettings.n = 4096; %size(a.Data{1},1); +% a.Parameter.HsvdSettings.p = 25; +% [~, a] = a.Hsvd; +% %% +% if(doReverse) +% a = a.ReverseMC; +% a.Parameter.HsvdSettings.bound = [-160 160]; +% [~, a] = a.Hsvd; +% end %% -if(doReverse) - a = a.ReverseMC; - a.Parameter.HsvdSettings.bound = [-160 160]; - [~, a] = a.Hsvd; -end -%% -trunc_ms = 150; -truncPoint = floor( trunc_ms/(a.Parameter.Headers.DwellTimeSig_ns*1e-6)); -a = a.Truncate(truncPoint); +% trunc_ms = 150; +% truncPoint = floor( trunc_ms/(a.Parameter.Headers.DwellTimeSig_ns*1e-6)); +% a = a.Truncate(truncPoint); %% Phase correction if ~exist('phase0','var') phase0 = 0; diff --git a/Met_T1processing/plot_mean_std_of_spectra_metT1.m b/Met_T1processing/plot_mean_std_of_spectra_metT1.m new file mode 100644 index 0000000000000000000000000000000000000000..18b35c7933b685c5e26cd378cd6969a01d2c3280 --- /dev/null +++ b/Met_T1processing/plot_mean_std_of_spectra_metT1.m @@ -0,0 +1,172 @@ +function plot_mean_std_of_spectra_metT1 + +downField_MM_Met = 'Met'; +switch downField_MM_Met + case 'DF' + pathName = 'DF data path'; + TEs = [24; 24; 32; 40; 52; 60; ]; + colors = {[0 0.7 0]; [0 0.7 0]; [0 0 0]; [0 0 1]; [1 0 0]; [0 0.5 0.5];}; + offsetStep = 2.2e-5; + case 'MM' + pathName = 'MM T1 data path'; + TEs = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; ]; + colors = {[76 187 23]/255; [76 187 23]/255; [1 121 111]/255; [75 0 130]/255; [75 0 130]/255; [75 0 130]/255; [75 0 130]/255;}; + offsetStep = 7.0e-5; + case 'MM WM' + pathName = 'MM WM T1 data path'; + TEs = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; ]; + colors = {[76 187 23]/255; [76 187 23]/255; [76 187 23]/255; [76 187 23]/255; [76 187 23]/255; [1 121 111]/255; [75 0 130]/255; [75 0 130]/255; [75 0 130]/255; [75 0 130]/255; [75 0 130]/255;}; + offsetStep = 7.0e-5; + case 'Met' + pathName = 'Met T1 WM data path'; + TEs = [2500; 1400; 1000; 700; 400; 100; 20; ]; + colors = {[76 187 23]/255; [76 187 23]/255; [1 121 111]/255; [75 0 130]/255; [75 0 130]/255; [75 0 130]/255; [75 0 130]/255;};%{[0 0.7 0]; [0 0 0]; [0 0 1]; [1 0 0]; [0 0.5 0.5];}; + offsetStep = 40e-4; +end + +[path] = pathToDataFolder(pathName); + +fileNameBase = [path, 'Summed_Averaged_TE']; + + +numberOfTEs = length(TEs); + +offSetBase = offsetStep * (numberOfTEs); %+7 for WM + +for indexTE = 1:numberOfTEs + fileName = [fileNameBase num2str(TEs(indexTE))]; + offset = offSetBase - indexTE * offsetStep; + if (indexTE == 1) && (strcmp(downField_MM_Met,'DF')) + plotOneTE(fileName, TEs(indexTE), colors{indexTE}, offset+offsetStep/2, 'DF_up'); + else + plotOneTE(fileName, TEs(indexTE), colors{indexTE}, offset, downField_MM_Met); + end +end + +end + +function plotOneTE(fileName, TE, colorSpectrum, offset, downField_MM_Met) +load([fileName '.mat'], 'summedSpectraTE') + +zeroPPM = 4.67; +nTimepoints = size(summedSpectraTE.Data{1},summedSpectraTE.kx_dim); +nAverages = size(summedSpectraTE.Data{1},summedSpectraTE.meas_dim); +waterFreq = summedSpectraTE.Parameter.Headers.ScanFrequency * 1E-6; +bandwidth = summedSpectraTE.Parameter.Headers.Bandwidth_Hz; +frequencyRange = linspace(-bandwidth/2,bandwidth/2,nTimepoints); + +if strcmp(downField_MM_Met,'DF_up') + fidSpectra = summedSpectraTE.Data{1}(:,1,1,1,1,1,1,1,1,1,1,:) * 5; +else + fidSpectra = summedSpectraTE.Data{1}(:,1,1,1,1,1,1,1,1,1,1,:) * 1; +end + +fidWater = summedSpectraTE.Data{1}(:,1,1,1,1,1,1,1,2,1,1,:); +spectra = squeeze(fftshift(fft(fidSpectra))); +water = squeeze(fftshift(fft(fidWater))); +meanSpectrum = mean(spectra,2); +stdSpectrum = std(spectra,[],2); +relativeStd = stdSpectrum ./ max(meanSpectrum) * 100; + +ppmVector = (frequencyRange)/waterFreq+zeroPPM; + +% figure(101) +% plot(ppmVector,relativeStd) +% xlim([0.5 4.2]); +% set(gca,'xDir','reverse') + + +%% +scalingRange = (ppmVector < 1.8) & (ppmVector > 0); +for indexAverage = 1:nAverages + [maxWater,indexMaxWater] = max(abs(real(water(:, indexAverage)))); + + [~, indexMaxWaterInRange] = max(abs(real((water(scalingRange, indexAverage)-mean(water(scalingRange, indexAverage)))))); + + [maxWaterInRange, ~] = max(real(water(scalingRange, indexAverage))); + minWaterInRange = min(real(water(scalingRange, indexAverage))); + + maxSpectraInRange = max(real(spectra(scalingRange, indexAverage))); + minSpectraInRange = min(real(spectra(scalingRange, indexAverage))); + + indexStart = find(scalingRange); + indexMaxWaterInRange = indexMaxWaterInRange + indexStart(1); + referenceLines = zeros(nTimepoints,1); + referenceLines(:) = -maxWaterInRange*2; + referenceLines(indexMaxWaterInRange:indexMaxWater + (indexMaxWater - indexMaxWaterInRange)) = maxWaterInRange*2; + + plotOffset = maxSpectraInRange; +% figWaterSpectra = figure(2); +% hold on +% plot(ppmScale, real(water(:,indexAverage)) - minWaterInRange + plotOffset,'b') +% plotScale = (maxWaterInRange-minWaterInRange); +% ylim([minSpectraInRange-(plotOffset*0.3) plotScale*1.2+plotOffset]); +% hold on +% pSpectra = plot(ppmScale, real(spectra(:,indexAverage)),'r'); +% hold on +% % figure +% plot(ppmScale, referenceLines, 'k--') +% xlim([0 8.5]); +% set(gca,'xDir','reverse') +% set(gca,'LineWidth',1); +% % set(gca,'ytick',[]) +% xlabel('[ppm]'); +% makedatatip(pSpectra,[indexMaxWaterInRange]) +% +% print(['WaterSpectraComparisonPlots\' num2str(indexAverage) '_' fileName],'-dpng') +% close(figWaterSpectra) +end +%% +% figure +% plot(ppmScale, real(spectra)) + +% xlim([0.5 4.2]); +% set(gca,'xDir','reverse') +% set(gca,'LineWidth',1); +% % set(gca,'ytick',[]) +% xlabel('[ppm]'); +% title(['Individual Spectra TE ' num2str(TE) ' ms']) + +%% +figure(1) +stdAlpha = 0.4; +hold on +if strcmp(downField_MM_Met,'DF_up') + indexDFCut = find(ppmVector > 8.6, 1, 'first'); + ppmVector = ppmVector(indexDFCut:end); + meanSpectrum = meanSpectrum(indexDFCut:end); +% stdSpectrum = stdSpectrum(indexDFCut:end); +end + +% h = area(ppmVector,[(meanSpectrum - stdSpectrum) + offset (stdSpectrum * 2)]); + +h(1).FaceColor = 'none'; +h(2).FaceColor = colorSpectrum; +h(2).FaceAlpha = stdAlpha; +h(1).EdgeColor = 'none'; +h(2).EdgeColor = 'none'; +hold on +pSpectrum = plot(ppmVector,meanSpectrum + offset, 'LineWidth',2, 'Color', colorSpectrum); + +switch downField_MM_Met + case 'DF' + xlim([5.5 9.4]); + case 'DF_up' + xlim([5.5 9.4]); + case 'MM' + xlim([0.5 4.2]); +% ylim([4.5e-6 4.7e-5]); + case 'MM WM' + xlim([0.5 4.2]); + %ylim([2e-6 1.3e-4]); %TODO: check why scaling is different, then MM + case 'Met' + xlim([0.5 4.2]); +% ylim([5000 5000]); +end +set(gca,'xDir','reverse') +set(gca,'LineWidth',1); +set(gca,'ytick',[]) +xlabel('[ppm]'); +title('Spectra mean and standard deviation') +% title(['Spectra TE ' num2str(TE) ' ms']) +end \ No newline at end of file diff --git a/Met_T1processing/reconstruct_all_MetT1.m b/Met_T1processing/reconstruct_all_MetT1.m index bb75c2afe9a798584e86231be05dd5496465c9d5..9d271c4b9b6bdaf4236f857bfb516a1a7775fb8e 100644 --- a/Met_T1processing/reconstruct_all_MetT1.m +++ b/Met_T1processing/reconstruct_all_MetT1.m @@ -1,6 +1,6 @@ function reconstruct_all_MetT1() -pathName = 'MET_T1 data path'; +pathName = 'Met T1 WM data path'; subjects = { ... '1405' ... '1706' ... @@ -18,7 +18,7 @@ subjects = { ... pathBase = pathToDataFolder(pathName, subjects); TIs = [20; 100; 400; 700; 1000; 1400; 2500]; - +%TIs = [1000]; numberOfSubjects = length(subjects); paths = cell(1,numberOfSubjects); for indexSubj = 1:numberOfSubjects @@ -48,7 +48,7 @@ addSinglet0ppm = 'Yes'; numberOfTIs = length(TIs); filesPath = cell(numberOfTIs,numberOfSubjects); -waterFilesPath = cell(1,numberOfSubjects); +% waterFilesPath = cell(1,numberOfSubjects); files = [files_TI20; files_TI100; files_TI400; files_TI700; files_TI1000; files_TI1400; files_TI2500]; for indexSubj = 1:numberOfSubjects for indexTI = 1:numberOfTIs diff --git a/algorithms/@MR_spectroS/Anonimize_MR_spectroS.m b/algorithms/@MR_spectroS/Anonimize_MR_spectroS.m new file mode 100644 index 0000000000000000000000000000000000000000..c99c6820f04fdf0a57158e0411a4454d69a4ea18 --- /dev/null +++ b/algorithms/@MR_spectroS/Anonimize_MR_spectroS.m @@ -0,0 +1,37 @@ +function this = Anonimize_MR_spectroS(this, subjectNumber) +% subjectNumber should be random, not pseudo-random. + +% if the subjectNumber is not given, use the timestamp of the execution as +% a subjectID. Using the timestamp makes the data anominized, but also +% unique. No other data set will have the same execution timestamp. +if ~exist('subjectNumber','var') + subjectNumber = round(now*1e8); +end +% make subjectNumber a string and give at least 4 digit precision +subjectNumberStr = ['Subj_', num2str(subjectNumber,'%.4d')]; + +%% Header info +patientID = this.Parameter.Headers.PatientID; +this.Parameter.Headers.PatientID = subjectNumber; +this.Parameter.Headers.PatientName = subjectNumber; + +% keep birthday only as year of birth, set rest to 1st of January +birthday = this.Parameter.Headers.BirthDay; +this.Parameter.Headers.BirthDay = round(birthday / 1e4)*1e4+0101; + +%% Filename +% remove MID and FID numbers from filename and add the subjectNumberStr +[~, fileName, extension] = fileparts(this.Parameter.Filename); +fileNameChunks = strsplit(fileName,'_'); +idx = contains(fileNameChunks,'MID'); +fileNameChunks(idx) = []; +idx = contains(fileNameChunks,'FID'); +fileNameChunks(idx) = []; +fileNameAnonimized = [strjoin(fileNameChunks,'_'), '_', subjectNumberStr, extension]; +this.Parameter.Filename = fileNameAnonimized; + +%% Filepath +%filepath may contain patientID. If true, this will replace it +filepath = this.Parameter.Filepath; +this.Parameter.Filepath = strrep(filepath,num2str(patientID),subjectNumberStr); +end \ No newline at end of file diff --git a/algorithms/@MR_spectroS/EddyCurrentCorrection.m b/algorithms/@MR_spectroS/EddyCurrentCorrection.m index 8a7952288d9154c2f8533eec805c67c0711b442e..9b0cc36a2eb9cdba3319508dae390e5bd45a5fb9 100644 --- a/algorithms/@MR_spectroS/EddyCurrentCorrection.m +++ b/algorithms/@MR_spectroS/EddyCurrentCorrection.m @@ -85,9 +85,9 @@ end nBlocks = this.Parameter.AverageSettings.nBlocks; % average the data based on the number of blocks nAverages = size(waterReferenceData, this.meas_dim); - if mod(nAverages, nBlocks)~=0 - error('The number of measurements of the water reference should be multiple of the number of blocks') - end +% if mod(nAverages, nBlocks)~=0 +% error('The number of measurements of the water reference should be multiple of the number of blocks') +% end averagesPerBlock = nAverages/nBlocks; for indexOfBlocks=1:nBlocks @@ -98,7 +98,7 @@ end %% TODO: add combine coils with the weights - one has to add the weights as a parameter %% Apply the actual Eddy Current Correction using the phase of the water reference (Klose correction) - data = data.*exp(-1j*angle(averagedWaterReferenceData)); + data = data.*exp(-1*j*angle(averagedWaterReferenceData)); % end this.Data{1} = data; this.Parameter.ReconFlags.isEddyCurrentCorrected= true; diff --git a/algorithms/@MR_spectroS/ExportLcmRaw.m b/algorithms/@MR_spectroS/ExportLcmRaw.m index 441e92699ae62489d87d04b8ccb6c244c94ad061..46991c0858be9f131f404d840eddac8e6f8ef70a 100644 --- a/algorithms/@MR_spectroS/ExportLcmRaw.m +++ b/algorithms/@MR_spectroS/ExportLcmRaw.m @@ -1,4 +1,4 @@ -function ExportLcmRaw(this, path, name, addSinglet, makeBasisExport, referencePeakPpm, scalingFactorRefPeak) +function ExportLcmRaw(this, path, name, addSinglet, makeBasisExport, referencePeakPpm, scalingFactorRefPeak, MC_mix) % Define the fileptath where the .RAW files will be saved if exist('path','var') @@ -26,6 +26,10 @@ if ~exist('scalingFactorRefPeak','var') scalingFactorRefPeak = 0.05; end +if ~exist('MC_mix','var') + MC_mix = 1; %1 = normal case, export spectra. 2 = export MC water +end + if exist('addSinglet','var') choice = addSinglet; if choice == true @@ -51,7 +55,7 @@ data = this.Data{1}; NMeas = size( data, this.meas_dim); % # Averages %NCha = size( data, this.coil_dim); % # Channels %NRep = size( data, this.dyn_dim); % # Repetitions -%NMix = size( data, this.mix_dim); % # Mixes +NMix = size( data, this.mix_dim); % # Mixes isAveraged = this.Parameter.ReconFlags.isAveraged; isMovingAveraged = this.Parameter.ReconFlags.isfMRSMovingAveraged; isISISAveraged = this.Parameter.ReconFlags.isISISAveraged; @@ -104,7 +108,7 @@ switch makeBasis metaboliteName = 'Leu'; end -dataExport = data(:,1,1,1,1,1,1,1,1,1,1,1); +dataExport = data(:,1,1,1,1,1,1,1,MC_mix,1,1,1); brukerFormat = true; ExportLCModelBasis(dataExport, dwellTime, scanFrequency, filepath, filename, metaboliteName, choice, ... brukerFormat, referencePeakPpm, scalingFactorRefPeak, makeBasis, TE, sequenceName) diff --git a/algorithms/@MR_spectroS/MR_spectroS.m b/algorithms/@MR_spectroS/MR_spectroS.m index ad3a13eef4908b1023dd91ed89287285ac88edc1..baeff2e699388978d2e13b08580f900ec6bff310 100644 --- a/algorithms/@MR_spectroS/MR_spectroS.m +++ b/algorithms/@MR_spectroS/MR_spectroS.m @@ -80,7 +80,7 @@ classdef MR_spectroS this = Filtering( this ); this = Truncate( this, truncPoint) this = RemoveFiltering( this ); - this = ExportLcmRaw( this, path, name, advoigdSinglet, makeBasisExport, referencePeakPpm, scalingFactorRefPeak); + this = ExportLcmRaw( this, path, name, advoigdSinglet, makeBasisExport, referencePeakPpm, scalingFactorRefPeak, MC_mix); this = ExportMruiText(this, path, name, nucleus); this = AverageData( this ); this = DeleteCoilChannels( this, coilChannels2Delete ); @@ -118,6 +118,7 @@ classdef MR_spectroS [this, this2, weights] = ISIS_main_processing(this,verbose); this = ISIS_prep_freqAlign(this, this2, weights); this = FrequencyAlignISIS(this,freqShiftsISISBlock,freqShiftsISISSteps); + this = Anonimize_MR_spectroS(this, subjectNumber); %////////////////////////////////////////////////////////////////////////// diff --git a/algorithms/@MR_spectroS/Sorting.m b/algorithms/@MR_spectroS/Sorting.m index fe41cb7c8d546008ba16a8baffd481e537a2d42d..b1c5f4ad7fb243867819f7252d6e4c96640882a2 100644 --- a/algorithms/@MR_spectroS/Sorting.m +++ b/algorithms/@MR_spectroS/Sorting.m @@ -9,6 +9,7 @@ else nAverages = size(this.Data{1},this.meas_dim); newDataSize = size(this.Data{1}); newDataSize(this.dyn_dim) = 1; + newDataSize(this.extr2_dim) = 1; newDataSize(this.meas_dim) = NDyns*nAverages; newData = zeros(newDataSize); oldData = this.Data{1}; diff --git a/createTestData/compareFitInput_Output.m b/createTestData/compareFitInput_Output.m new file mode 100644 index 0000000000000000000000000000000000000000..c32d238006be761a8fc0ff11798500153c120d63 --- /dev/null +++ b/createTestData/compareFitInput_Output.m @@ -0,0 +1,76 @@ +function [diff_conc, diff_em, diff_gm, diff_pc0, diff_df2, diff_pc12, diff_T2] = compareFitInput_Output(dataExportPath, filenameData, iteration) + +saveFigures = false; + +fileNameOff = strrep(filenameData,'On', 'Off'); +xx = ls([dataExportPath, fileNameOff '*']); + +load([dataExportPath, fileNameOff, '.mat'], 'summedFidWithNoise', 'current_em', 'currentConcentrationRm', ... + 'current_pc0', 'current_pc1', 'current_df2', 'current_gm', 'current_em_std_factor', 'conc_std_factor'); + +fileNameProFit = [filenameData '_profit']; +% close all; +load(strcat(dataExportPath,fileNameProFit, '.mat'),'fitresult'); + +currentFitresult = fitresult{1,iteration}; + +% metabolites and results have to be first sorted +metabolites = {'Asp', 'tCr(CH2)', 'tCr(CH3)', 'GABA', 'Gln', 'Glu', 'Glyc', 'GSH', 'Lac', 'mI', 'NAA(CH3)', 'NAA(CH2)', 'NAAG', 'tCho+', 'Scy', 'Tau', 'MMB'}; +metabolitesName = {'Asp', 'Cr_CH2', 'Cr', 'GABA', 'Gln', 'Glu', 'Glyc', 'GSH', 'Lac', 'mI', 'NAA_ac', 'NAA_as', 'NAAG', 'tCho_P', 'Scyllo', 'Tau', 'Leu'}; + +active_met_names = currentFitresult.met(currentFitresult.active_mets); +sortedIndeces = zeros(length(metabolitesName),1); +for indexMet = 1: length(metabolitesName) + indexX = find(strcmp(metabolitesName{indexMet}, active_met_names)); + sortedIndeces(indexX) = indexMet; +end + +currentConcentrationRm(end) = currentConcentrationRm(end)*1e-8; +diff_conc = currentFitresult.fitted_values.conc * currentFitresult.sub_mask.conc.full - currentConcentrationRm(sortedIndeces); +diff_conc(currentFitresult.fitted_values.conc==0)=NaN; +diff_em = currentFitresult.fitted_values.em * currentFitresult.sub_mask.em.full - current_em(sortedIndeces); +diff_gm = currentFitresult.fitted_values.gm * currentFitresult.sub_mask.gm.full- current_gm; +diff_pc0 = currentFitresult.fitted_values.pc0 * currentFitresult.sub_mask.pc0.full - current_pc0; +diff_df2 = currentFitresult.fitted_values.df2 * currentFitresult.sub_mask.df2.full - current_df2(sortedIndeces); +diff_pc12 = currentFitresult.fitted_values.pc12 * currentFitresult.sub_mask.pc12.full - current_pc1; +diff_T2 = 1./(pi*currentFitresult.fitted_values.em * currentFitresult.sub_mask.em.full) *1e3 - ... + 1./(pi*current_em(sortedIndeces)) * 1e3; + +figId2=figure; +set(figId2,... + 'Position',[350 400 890 600],'Color',[1 1 1]); +crlb_print =currentFitresult.crlb; +crlb_print(abs(crlb_print)>=1000) = 999.9999; +dataOfTable={}; +columnname = {'met','conc', '<html>crlb<br />[%]</html>', ... + '<html>T2<br />[ms]</html>','<html>em<br />[Hz]</html>',... + '<html>gm<br />[Hz]</html>', '<html>em_g<br />[Hz]</html>', ... + '<html>pc0<br />[deg]</html>', '<html>df2<br />[Hz]</html>', ... + '<html>pc12<br />[deg/ppm]</html>'}; +columnformat={'char',[],[],[],[],[],[],[],[],[]}; +concentrations = zeros(1,currentFitresult.nr_act_mets); + +for met_cnt=1:currentFitresult.nr_act_mets + dataOfTable=[dataOfTable;{... + active_met_names{met_cnt},... + num2str(diff_conc(met_cnt),'%6.4f'),... + num2str(crlb_print(currentFitresult.sub_mask.conc.full(:,met_cnt)'),'%6.4f'),... + num2str(diff_T2(met_cnt),'%6.4f'),... + num2str(diff_em(met_cnt),'%6.4f'),... + num2str(diff_gm(met_cnt),'%6.4f'),... + num2str(diff_pc0(met_cnt),'%6.4f'),... + num2str(diff_df2(met_cnt),'%6.4f'),... + num2str(diff_pc12(met_cnt),'%6.4f')... + }]; + concentrations(met_cnt) = currentFitresult.fitted_values.conc(currentFitresult.sub_mask.conc.full(:,met_cnt)'); +end +tableProfit = uitable(...%'Units','normalized',...% + 'Position',[20 20 850 580],'Data', dataOfTable,... + 'ColumnName', columnname,'ColumnFormat',columnformat,... + 'RowName',[],'ColumnWidth',{65}); + +if saveFigures + saveas(figId2, [dataExportPath,fileNameProFit, '_compare_iter', num2str(iteration), '_table.tif']); + savefig(figId2, [dataExportPath,fileNameProFit, '_compare_iter', num2str(iteration), '_table.fig'],'compact'); +end +end diff --git a/createTestData/createSimulatedSpectra.m b/createTestData/createSimulatedSpectra.m index 97634c1e62caaf9870f76d903830ba6f1a5f9d50..a287c53efcb9c4dbab17c43db62c213c2652453a 100644 --- a/createTestData/createSimulatedSpectra.m +++ b/createTestData/createSimulatedSpectra.m @@ -14,7 +14,8 @@ T2_std = [ 12, 10, 16, 35, 20, 25, 10, TE = 24 * 1e-3; numMetabolites = length(metabolites); -saveData = true; +saveData = false; +saveFigures = true; saveRandNumbers = false; %should generally be kept false to have the same random numbers consistently %% path to the export of the spectra @@ -25,11 +26,21 @@ dataExportPathBase = strcat(pathBaseExportFiles, exportFolder{1}, '\'); % think whether to change tCho+ from original (1.0+-0.2) to max(2.5+-0.5) current(1.5+-0.4) to accomodate PE -gaussianValues = [6:2:30]; %Hz -pc0 = [-20:5:20]; %grad -pc1 = [-7.5:2.5:7.5]; %grad/ppm -df2_global = [-15:2.5:15]; % Hz : Global and local shifts -df2_local_std = 5;%7; %Hz coresponds to ~0.02 ppm. This is the maximal shift, which can occur by temperature between moieties (Wermter, MRMP 2017) +gaussianValues = [4:2:32]; %Hz +pc0 = [-35:5:35]; %grad +% The first order phase does not fully mimick in vivo conditions. While we +%could mimick a truncation of the first points, a maximum echo sampling is +%not possible with the normal echo sampling basis set +pc1 = [-17.5:2.5:17.5]; %grad/ppm +% pc1 = [-30:5:30]; %grad/ppm +df2_global = [-17.5:2.5:17.5]; % Hz : Global and local shifts +df2_local_scale = [0.25 0.25 0.5 0.5 0.75 0.75 1 1 1.5 1.5 2 2 3 3 5]; +df2_local_std = 3;% 3 Hz coresponds to ~0.0075 ppm. +% This is the maximal shift, which can occur by temperature between +% moieties (Wermter, MRMP 2017), assuming up to 10°C temperature change. +% pH changes should have a similar order of magnitude. + +em_local_scale = [0.2 0.2 0.4 0.4 0.6 0.6 0.8 0.8 1 1 1.2 1.2 1.5 1.5 2]; % when truncating at 200 ms like used in real spectra, the NAA SNR of the defaultSummedFid corresponds to % Chosen NoiseLevel -> SNR(NAA) % 1 -> SNR = 207; 3 -> SNR = 158; 7 -> SNR = 110; 15 -> SNR = 44; 25 -> SNR = 13 @@ -42,6 +53,7 @@ if saveRandNumbers save([dataExportPathBase, 'df2_local_RandNumbers.mat'], 'df2_local_RandNumbers'); end load([dataExportPathBase, 'df2_local_RandNumbers.mat'], 'df2_local_RandNumbers'); +em_local_RandNumbers = df2_local_RandNumbers; %use the same random numbers for simplicity %% metaboliteFileNames = metabolites; @@ -86,17 +98,19 @@ for indexMetabolite = 1:numMetabolites end end +water_ppm = 4.66; % ppm +referencePeakPpm = -water_ppm; nTimepoints = length(fids{1}); dwellTime = 1/bandwidth; timePointsSampling =(0:nTimepoints - 1) * dwellTime; -referencePeakPpm = -4.7; scalingFactorRefPeak = 0.05; -phase_1_f2_mx = linspace(-1, 1, nTimepoints); -refFreqPpm = -2.3; % the reference Frequency for the excitation pulse, given in ppm compared to the water (minus is upfield, + downfield) -phase_1_f2_mx = phase_1_f2_mx .* bandwidth ./ scanFrequency / 2 + (-referencePeakPpm + refFreqPpm); +refFreqPpm = -0; % the reference Frequency for the excitation pulse, given in ppm compared to the water (minus is upfield, + downfield) +phasePivot_ppm = water_ppm + refFreqPpm;%in ppm ppmVector = ppmVectorFunction(scanFrequency*1e6, bandwidth, nTimepoints, '1H'); +phase_1_f2_mx = ppmVector-phasePivot_ppm; + ppmMask = (ppmVector>0.6) & (ppmVector<4.1); @@ -104,7 +118,8 @@ ppmMask = (ppmVector>0.6) & (ppmVector<4.1); default_pc0 = 0; default_pc1 = 0; default_df2 = zeros(1,numMetabolites); -default_gm = gaussianValues(4); +default_gm = 12; +default_em_std_factor = zeros(1,numMetabolites); default_noiseLevel = 3; noiseVector = wgn(1,nTimepoints, default_noiseLevel); trunc_ms = 200; @@ -115,7 +130,7 @@ current_pc0 = default_pc0; current_pc1 = default_pc1; current_df2 = default_df2; current_gm = default_gm; -current_em_std_factor = 0; %TODO +current_em_std_factor = default_em_std_factor; conc_std_factor = zeros(1,numMetabolites); % generate the default spectrum @@ -123,9 +138,12 @@ conc_std_factor = zeros(1,numMetabolites); createSummedSpectrum(... fids, concentrations, conc_std, T2s, T2_std, TE, metabolites, metaboliteFileNames, timePointsSampling, phase_1_f2_mx, ppmMask, ... current_pc0, current_pc1, current_df2, current_gm, current_em_std_factor, conc_std_factor, noiseVector, ... - truncPoint, saveData, 'meanConc', [], dwellTime * 1e3, scanFrequency, dataExportPathBase, referencePeakPpm, scalingFactorRefPeak); + truncPoint, saveData, 'meanConc', [], dwellTime * 1e3, scanFrequency, dataExportPathBase, water_ppm, scalingFactorRefPeak); -figure; +figure(1); +subplot(5,4,8+7:8+8) +% figure(2); +% subplot(3,4,7:8) plot(ppmVector,real(fftshift(fft(defaultSummedFid)))); %% generate the series of different concentrations @@ -169,7 +187,11 @@ for indexParam = 1:numberConcPermutations % ImportLCModelBasis(dataExportPath, fileName, true, '1H'); end -save([dataExportPathBase, 'concentrations_simulated_', paramKeyword, '.mat'], 'concentrationsRm', 'metabolites', 'metaboliteFileNames'); +titleStr = '{\boldmath$c$}'; +plotSimulationSetup(titleStr, paramKeyword, saveFigures, dataExportPathBase); +if saveData + save([dataExportPathBase, 'concentrations_simulated_', paramKeyword, '.mat'], 'concentrationsRm', 'metabolites', 'metaboliteFileNames'); +end for indexMetabolite = 1:numMetabolites figure; @@ -177,160 +199,219 @@ for indexMetabolite = 1:numMetabolites title(metabolites(indexMetabolite)) end -% %% ############################################################################################# -% % generate the series of different parameters, same concentrations -% % ############################################################################################# -% conc_std_factor = zeros(1,numMetabolites); % reset value -% -% %% gauss -% paramKeyword = 'gauss'; -% dataExportPath = [dataExportPathBase, paramKeyword, '\']; -% concentrationsRm = zeros(length(gaussianValues), numMetabolites); -% -% figure; -% for indexParam = 1:length(gaussianValues) -% -% current_gm = gaussianValues(indexParam); -% [summedFid, summedFidWithNoise, current_em, currentConcentrationRm] = createSummedSpectrum(... -% fids, concentrations, conc_std, T2s, T2_std, TE, metabolites, metaboliteFileNames, timePointsSampling, phase_1_f2_mx, ppmMask, ... -% current_pc0, current_pc1, current_df2, current_gm, current_em_std_factor, conc_std_factor, noiseVector, ... -% truncPoint, saveData, paramKeyword, indexParam, dwellTime * 1e3, scanFrequency, dataExportPath, referencePeakPpm, scalingFactorRefPeak); -% -% concentrationsRm(indexParam,:) = currentConcentrationRm; -% hold on; -% plot(ppmVector,real(fftshift(fft(summedFid)))); -% end -% % reset parameter -% current_gm = default_gm; -% -% save([dataExportPathBase, 'concentrations_simulated_', paramKeyword, '.mat'], 'concentrationsRm', 'metabolites', 'metaboliteFileNames'); -% -% %% pc0 - zero order phase -% paramKeyword = 'pc0'; -% dataExportPath = [dataExportPathBase, paramKeyword, '\']; -% concentrationsRm = zeros(length(pc0), numMetabolites); -% -% figure; -% for indexParam = 1:length(pc0) -% -% current_pc0 = pc0(indexParam); -% [summedFid, summedFidWithNoise, current_em, currentConcentrationRm] = createSummedSpectrum(... -% fids, concentrations, conc_std, T2s, T2_std, TE, metabolites, metaboliteFileNames, timePointsSampling, phase_1_f2_mx, ppmMask, ... -% current_pc0, current_pc1, current_df2, current_gm, current_em_std_factor, conc_std_factor, noiseVector, ... -% truncPoint, saveData, paramKeyword, indexParam, dwellTime * 1e3, scanFrequency, dataExportPath, referencePeakPpm, scalingFactorRefPeak); -% -% concentrationsRm(indexParam,:) = currentConcentrationRm; -% hold on; -% plot(ppmVector,real(fftshift(fft(summedFid)))); -% end -% % reset parameter -% current_pc0 = default_pc0; -% -% save([dataExportPathBase, 'concentrations_simulated_', paramKeyword, '.mat'], 'concentrationsRm', 'metabolites', 'metaboliteFileNames'); -% -% %% pc1 - first order phase -% paramKeyword = 'pc1'; -% dataExportPath = [dataExportPathBase, paramKeyword, '\']; -% concentrationsRm = zeros(length(pc1), numMetabolites); -% -% figure; -% for indexParam = 1:length(pc1) -% -% current_pc1 = pc1(indexParam); -% [summedFid, summedFidWithNoise, current_em, currentConcentrationRm] = createSummedSpectrum(... -% fids, concentrations, conc_std, T2s, T2_std, TE, metabolites, metaboliteFileNames, timePointsSampling, phase_1_f2_mx, ppmMask, ... -% current_pc0, current_pc1, current_df2, current_gm, current_em_std_factor, conc_std_factor, noiseVector, ... -% truncPoint, saveData, paramKeyword, indexParam, dwellTime * 1e3, scanFrequency, dataExportPath, referencePeakPpm, scalingFactorRefPeak); -% -% concentrationsRm(indexParam,:) = currentConcentrationRm; -% hold on; -% plot(ppmVector,real(fftshift(fft(summedFid)))); -% end -% % reset parameter -% current_pc1 = default_pc1; -% -% save([dataExportPathBase, 'concentrations_simulated_', paramKeyword, '.mat'], 'concentrationsRm', 'metabolites', 'metaboliteFileNames'); - -% %% df2 - frequency shifts -% paramKeyword = 'df2'; -% dataExportPath = [dataExportPathBase, paramKeyword, '\']; -% concentrationsRm = zeros(length(df2_global), numMetabolites); -% -% figure; -% for indexParam = 1:length(df2_global) -% -% -% for indexMetabolite = 1:numMetabolites -% % generate a random number between [-stdLim; stdLim] -% stdRand = 2 * df2_local_std * df2_local_RandNumbers(indexParam,indexMetabolite) - df2_local_std; -% switch metabolites{indexMetabolite} -% case 'tCr(CH2)' -% creatineStdRand = stdRand; -% case 'tCr(CH3)' -% stdRand = creatineStdRand; -% case 'NAA(CH3)' -% NaaStdRand = stdRand; -% case 'NAA(CH2)' -% stdRand = NaaStdRand; -% otherwise -% % nothing to do -% end -% current_df2(indexMetabolite) = df2_global(indexParam) + stdRand; -% end -% [summedFid, summedFidWithNoise, current_em, currentConcentrationRm] = createSummedSpectrum(... -% fids, concentrations, conc_std, T2s, T2_std, TE, metabolites, metaboliteFileNames, timePointsSampling, phase_1_f2_mx, ppmMask, ... -% current_pc0, current_pc1, current_df2, current_gm, current_em_std_factor, conc_std_factor, noiseVector, ... -% truncPoint, saveData, paramKeyword, indexParam, dwellTime * 1e3, scanFrequency, dataExportPath, referencePeakPpm, scalingFactorRefPeak); -% -% concentrationsRm(indexParam,:) = currentConcentrationRm; -% hold on; -% plot(ppmVector,real(fftshift(fft(summedFid)))); -% end -% % reset parameter -% current_df2 = default_df2; -% -% save([dataExportPathBase, 'concentrations_simulated_', paramKeyword, '.mat'], 'concentrationsRm', 'metabolites', 'metaboliteFileNames'); - -% %% em - lorentzian components of T2 -% paramKeyword = 'em'; -% dataExportPath = [dataExportPathBase, paramKeyword, '\']; -% concentrationsRm = zeros(length(df2_global), numMetabolites); -% -% figure; -% for indexParam = 1:length(df2_global) -% -% -% for indexMetabolite = 1:numMetabolites -% % generate a random number between [-stdLim; stdLim] -% stdRand = 2 * df2_local_std * df2_local_RandNumbers(indexParam,indexMetabolite) - df2_local_std; -% switch metabolites{indexMetabolite} -% case 'tCr(CH2)' -% creatineStdRand = stdRand; -% case 'tCr(CH3)' -% stdRand = creatineStdRand; -% case 'NAA(CH3)' -% NaaStdRand = stdRand; -% case 'NAA(CH2)' -% stdRand = NaaStdRand; -% otherwise -% % nothing to do -% end -% current_df2(indexMetabolite) = df2_global(indexParam) + stdRand; -% end -% [summedFid, summedFidWithNoise, current_em, currentConcentrationRm] = createSummedSpectrum(... -% fids, concentrations, conc_std, T2s, T2_std, TE, metabolites, metaboliteFileNames, timePointsSampling, phase_1_f2_mx, ppmMask, ... -% current_pc0, current_pc1, current_df2, current_gm, current_em_std_factor, conc_std_factor, noiseVector, ... -% truncPoint, saveData, paramKeyword, indexParam, dwellTime * 1e3, scanFrequency, dataExportPath, referencePeakPpm, scalingFactorRefPeak); -% -% concentrationsRm(indexParam,:) = currentConcentrationRm; -% hold on; -% plot(ppmVector,real(fftshift(fft(summedFid)))); -% end -% % reset parameter -% current_df2 = default_df2; -% -% save([dataExportPathBase, 'concentrations_simulated_', paramKeyword, '.mat'], 'concentrationsRm', 'metabolites', 'metaboliteFileNames'); -% +%% ############################################################################################# +% generate the series of different parameters, same concentrations +% ############################################################################################# +conc_std_factor = zeros(1,numMetabolites); % reset value + +%% gauss +paramKeyword = 'gauss'; +dataExportPath = [dataExportPathBase, paramKeyword, '\']; +concentrationsRm = zeros(length(gaussianValues), numMetabolites); + +figure(1); +subplot(5,4,5:6) +% subplot(2,4,5:6) +for indexParam = 1:length(gaussianValues) + + current_gm = gaussianValues(indexParam); + [summedFid, summedFidWithNoise, current_em, currentConcentrationRm] = createSummedSpectrum(... + fids, concentrations, conc_std, T2s, T2_std, TE, metabolites, metaboliteFileNames, timePointsSampling, phase_1_f2_mx, ppmMask, ... + current_pc0, current_pc1, current_df2, current_gm, current_em_std_factor, conc_std_factor, noiseVector, ... + truncPoint, saveData, paramKeyword, indexParam, dwellTime * 1e3, scanFrequency, dataExportPath, referencePeakPpm, scalingFactorRefPeak); + + concentrationsRm(indexParam,:) = currentConcentrationRm; + hold on; + plot(ppmVector,real(fftshift(fft(summedFid)))); +end +% reset parameter +current_gm = default_gm; + + +titleStr = '$$\nu_{g}$$'; +plotSimulationSetup(titleStr, paramKeyword, saveFigures, dataExportPathBase); +if saveData + save([dataExportPathBase, 'concentrations_simulated_', paramKeyword, '.mat'], 'concentrationsRm', 'metabolites', 'metaboliteFileNames'); +end + +%% pc0 - zero order phase +paramKeyword = 'pc0'; +dataExportPath = [dataExportPathBase, paramKeyword, '\']; +concentrationsRm = zeros(length(pc0), numMetabolites); + +figure(1); +subplot(5,4,1:2) +% subplot(2,4,1:2) +for indexParam = 1:length(pc0) + + current_pc0 = pc0(indexParam); + [summedFid, summedFidWithNoise, current_em, currentConcentrationRm] = createSummedSpectrum(... + fids, concentrations, conc_std, T2s, T2_std, TE, metabolites, metaboliteFileNames, timePointsSampling, phase_1_f2_mx, ppmMask, ... + current_pc0, current_pc1, current_df2, current_gm, current_em_std_factor, conc_std_factor, noiseVector, ... + truncPoint, saveData, paramKeyword, indexParam, dwellTime * 1e3, scanFrequency, dataExportPath, referencePeakPpm, scalingFactorRefPeak); + + concentrationsRm(indexParam,:) = currentConcentrationRm; + hold on; + plot(ppmVector,real(fftshift(fft(summedFid)))); +end +% reset parameter +current_pc0 = default_pc0; + +titleStr = '$$\varphi_{0}$$'; +plotSimulationSetup(titleStr, paramKeyword, saveFigures, dataExportPathBase); +if saveData + save([dataExportPathBase, 'concentrations_simulated_', paramKeyword, '.mat'], 'concentrationsRm', 'metabolites', 'metaboliteFileNames'); +end + +%% pc1 - first order phase +paramKeyword = 'pc1'; +dataExportPath = [dataExportPathBase, paramKeyword, '\']; +concentrationsRm = zeros(length(pc1), numMetabolites); + +figure(1); +subplot(5,4,3:4) +% subplot(2,4,3:4) +for indexParam = 1:length(pc1) + + current_pc1 = pc1(indexParam); + [summedFid, summedFidWithNoise, current_em, currentConcentrationRm] = createSummedSpectrum(... + fids, concentrations, conc_std, T2s, T2_std, TE, metabolites, metaboliteFileNames, timePointsSampling, phase_1_f2_mx, ppmMask, ... + current_pc0, current_pc1, current_df2, current_gm, current_em_std_factor, conc_std_factor, noiseVector, ... + truncPoint, saveData, paramKeyword, indexParam, dwellTime * 1e3, scanFrequency, dataExportPath, referencePeakPpm, scalingFactorRefPeak); + + concentrationsRm(indexParam,:) = currentConcentrationRm; + hold on; + plot(ppmVector,real(fftshift(fft(summedFid)))); +end +% reset parameter +current_pc1 = default_pc1; + +titleStr = '$$\varphi_{1}$$'; +plotSimulationSetup(titleStr, paramKeyword, saveFigures, dataExportPathBase); +if saveData + save([dataExportPathBase, 'concentrations_simulated_', paramKeyword, '.mat'], 'concentrationsRm', 'metabolites', 'metaboliteFileNames'); +end + +%% df2 local - frequency shifts +paramKeyword = 'df2_local'; +dataExportPath = [dataExportPathBase, paramKeyword, '\']; +concentrationsRm = zeros(length(df2_local_scale), numMetabolites); + +figure(1); +subplot(5,4,8+1:8+2) +% figure(2); +% subplot(3,4,1:2) +for indexParam = 1:length(df2_local_scale) + + for indexMetabolite = 1:numMetabolites + % generate a random number between [-stdLim; stdLim] + stdRand = 2 * df2_local_std * df2_local_RandNumbers(indexParam,indexMetabolite) - df2_local_std; + switch metabolites{indexMetabolite} + case 'tCr(CH2)' + creatineStdRand = stdRand; + case 'tCr(CH3)' + stdRand = creatineStdRand; + case 'NAA(CH3)' + NaaStdRand = stdRand; + case 'NAA(CH2)' + stdRand = NaaStdRand; + otherwise + % nothing to do + end + current_df2(indexMetabolite) = df2_local_scale(indexParam) * stdRand; + end + [summedFid, summedFidWithNoise, current_em, currentConcentrationRm] = createSummedSpectrum(... + fids, concentrations, conc_std, T2s, T2_std, TE, metabolites, metaboliteFileNames, timePointsSampling, phase_1_f2_mx, ppmMask, ... + current_pc0, current_pc1, current_df2, current_gm, current_em_std_factor, conc_std_factor, noiseVector, ... + truncPoint, saveData, paramKeyword, indexParam, dwellTime * 1e3, scanFrequency, dataExportPath, water_ppm, scalingFactorRefPeak); + + concentrationsRm(indexParam,:) = currentConcentrationRm; + hold on; + plot(ppmVector,real(fftshift(fft(summedFid)))); +end +% reset parameter +current_df2 = default_df2; + +titleStr = '{\boldmath$\omega_{local}$}'; +plotSimulationSetup(titleStr, paramKeyword, saveFigures, dataExportPathBase); +if saveData + save([dataExportPathBase, 'concentrations_simulated_', paramKeyword, '.mat'], 'concentrationsRm', 'metabolites', 'metaboliteFileNames'); +end + +%% df2 global - frequency shifts +paramKeyword = 'df2_global'; +dataExportPath = [dataExportPathBase, paramKeyword, '\']; +concentrationsRm = zeros(length(df2_global), numMetabolites); + +figure(1); +subplot(5,4,7:8) +% subplot(2,4,7:8) +for indexParam = 1:length(df2_global) + for indexMetabolite = 1:numMetabolites + current_df2(indexMetabolite) = df2_global(indexParam); + end + [summedFid, summedFidWithNoise, current_em, currentConcentrationRm] = createSummedSpectrum(... + fids, concentrations, conc_std, T2s, T2_std, TE, metabolites, metaboliteFileNames, timePointsSampling, phase_1_f2_mx, ppmMask, ... + current_pc0, current_pc1, current_df2, current_gm, current_em_std_factor, conc_std_factor, noiseVector, ... + truncPoint, saveData, paramKeyword, indexParam, dwellTime * 1e3, scanFrequency, dataExportPath, water_ppm, scalingFactorRefPeak); + + concentrationsRm(indexParam,:) = currentConcentrationRm; + hold on; + plot(ppmVector,real(fftshift(fft(summedFid)))); +end +% reset parameter +current_df2 = default_df2; + +titleStr = '$$\omega_{global}$$'; +plotSimulationSetup(titleStr, paramKeyword, saveFigures, dataExportPathBase); +if saveData + save([dataExportPathBase, 'concentrations_simulated_', paramKeyword, '.mat'], 'concentrationsRm', 'metabolites', 'metaboliteFileNames'); +end + +%% em - lorentzian components of T2 +paramKeyword = 'em'; +dataExportPath = [dataExportPathBase, paramKeyword, '\']; +concentrationsRm = zeros(length(df2_global), numMetabolites); + +figure(1); +subplot(5,4,8+3:8+4) +% figure(2); +% subplot(3,4,3:4) +for indexParam = 1:length(df2_global) + for indexMetabolite = 1:numMetabolites + % generate a random number between [-stdLim; stdLim] + stdRand = 2 * em_local_RandNumbers(indexParam,indexMetabolite) - 1; + switch metabolites{indexMetabolite} + case 'tCr(CH2)' + creatineStdRand = stdRand; + case 'tCr(CH3)' + stdRand = creatineStdRand; + case 'NAA(CH3)' + NaaStdRand = stdRand; + case 'NAA(CH2)' + stdRand = NaaStdRand; + otherwise + % nothing to do + end + current_em_std_factor(indexMetabolite) = em_local_scale(indexParam) * stdRand; + end + [summedFid, summedFidWithNoise, current_em, currentConcentrationRm] = createSummedSpectrum(... + fids, concentrations, conc_std, T2s, T2_std, TE, metabolites, metaboliteFileNames, timePointsSampling, phase_1_f2_mx, ppmMask, ... + current_pc0, current_pc1, current_df2, current_gm, current_em_std_factor, conc_std_factor, noiseVector, ... + truncPoint, saveData, paramKeyword, indexParam, dwellTime * 1e3, scanFrequency, dataExportPath, referencePeakPpm, scalingFactorRefPeak); + + concentrationsRm(indexParam,:) = currentConcentrationRm; + hold on; + plot(ppmVector,real(fftshift(fft(summedFid)))); +end +% reset parameter +current_em_std_factor = default_em_std_factor; + +titleStr = '{\boldmath$\nu_{e}$}'; +plotSimulationSetup(titleStr, paramKeyword, saveFigures, dataExportPathBase); +if saveData + save([dataExportPathBase, 'concentrations_simulated_', paramKeyword, '.mat'], 'concentrationsRm', 'metabolites', 'metaboliteFileNames'); +end %% noise - add different noise levels @@ -338,7 +419,10 @@ paramKeyword = 'noise'; dataExportPath = [dataExportPathBase, paramKeyword, '\']; concentrationsRm = zeros(length(noiseLevel), numMetabolites); -figure; +figure(1); +subplot(5,4,8+5:8+6) +% figure(2); +% subplot(3,4,5:6) for indexParam = 1:length(noiseLevel) noiseVector = wgn(1,nTimepoints, noiseLevel(indexParam)); [summedFid, summedFidWithNoise, current_em, currentConcentrationRm] = createSummedSpectrum(... @@ -353,7 +437,64 @@ end % reset parameter noiseVector = wgn(1,nTimepoints, default_noiseLevel); -save([dataExportPathBase, 'concentrations_simulated_', paramKeyword, '.mat'], 'concentrationsRm', 'metabolites', 'metaboliteFileNames'); +titleStr = '{\boldmath$noise$}'; +plotSimulationSetup(titleStr, paramKeyword, saveFigures, dataExportPathBase); +if saveData + save([dataExportPathBase, 'concentrations_simulated_', paramKeyword, '.mat'], 'concentrationsRm', 'metabolites', 'metaboliteFileNames'); +end + +%% noise - add different noise levels +paramKeyword = 'baseline'; +dataExportPath = [dataExportPathBase, paramKeyword, '\']; +concentrationsRm = zeros(length(noiseLevel), numMetabolites); + +baselinesPath = [dataExportPathBase 'Baselines\']; +prefixBaseline = 'Baseline_'; +baselines = {'1Flat_drop_H20'; '2Flat'; '3Flat'; '4Flat'; '5Wildish'; '6Wildish'; '7Very_wild';... + '8Very_wild'; '9Wild'; '10Wild'; '11Wildish'; '12Wildish'; '13Normal'; '14Lipid_1.3'; '15Lipid_1.3_phased'; '16Zero'}; + +figure(1); +subplot(5,4,8+10:8+11) +% figure(2); +% subplot(3,4,10:11) +for indexParam = 1:length(baselines) + baselineFileName = strcat(prefixBaseline, baselines{indexParam}); + [currentBaseline, ~, ~, ~, ~] = ImportLCModelBasis(baselinesPath, baselineFileName, plotBasis, '1H'); + currentBaseline = currentBaseline(1:length(fids{1}));% will fail if the fids are longer than the baseline + [summedFid, summedFidWithNoise, current_em, currentConcentrationRm] = createSummedSpectrum(... + fids, concentrations, conc_std, T2s, T2_std, TE, metabolites, metaboliteFileNames, timePointsSampling, phase_1_f2_mx, ppmMask, ... + current_pc0, current_pc1, current_df2, current_gm, current_em_std_factor, conc_std_factor, noiseVector, ... + truncPoint, saveData, paramKeyword, indexParam, dwellTime * 1e3, scanFrequency, dataExportPath, referencePeakPpm, scalingFactorRefPeak, currentBaseline); + concentrationsRm(indexParam,:) = currentConcentrationRm; + hold on; + plot(ppmVector,real(fftshift(fft(summedFidWithNoise)))); +end +titleStr = '{\boldmath$baseline$}'; +plotSimulationSetup(titleStr, paramKeyword, saveFigures, dataExportPathBase); +if saveData + save([dataExportPathBase, 'concentrations_simulated_', paramKeyword, '.mat'], 'concentrationsRm', 'metabolites', 'metaboliteFileNames'); +end end +function plotSimulationSetup(titleStr, paramKeyword, saveFigures, dataExportPathBase) +FontSize = 12; +LineWidth = 1.5; +xlim([0.6, 4.1]) +xlabel('\delta (ppm)') +ylabel('Signal (arb. u.)') +set(gca,'xDir','reverse') +set(gca,'ytick',[]); +title(['Spectra with ', titleStr, ' variations'], 'Interpreter','latex'); +set(gca,'fontsize',FontSize); +set(gca,'FontWeight','bold'); +h = findobj(gca,'Type','line'); +for plots = h + set(plots,'LineWidth',LineWidth) +end +if saveFigures + fileNameFull = [dataExportPathBase, 'Plots\Simulations_', paramKeyword]; + print([fileNameFull, '.tif'],'-dtiff','-r600'); + savefig(gcf, [fileNameFull, '.fig'],'compact'); +end +end diff --git a/createTestData/createSummedSpectrum.m b/createTestData/createSummedSpectrum.m index daad3df44487fc5165a1757074d7a816240d8266..58bda11a3c7f8be6dbb15e9fb53c3a071840c137 100644 --- a/createTestData/createSummedSpectrum.m +++ b/createTestData/createSummedSpectrum.m @@ -1,17 +1,30 @@ function [summedFid, summedFidWithNoise, current_em, currentConcentrationRm] = createSummedSpectrum( ... fids, concentrations, conc_std, T2s, T2_std, TE, metabolites, metaboliteFileNames, shift_t2_mx, phase_1_f2_mx, ppmMask, ... current_pc0, current_pc1, current_df2, current_gm, current_em_std_factor, conc_std_factor, noiseVector, ... - truncPoint, saveData, paramKeyWord, indexParam, dwellTimeMs, scanFrequency, dataExportPath, referencePeakPpm, scalingFactorRefPeak) + truncPoint, saveData, paramKeyWord, indexParam, dwellTimeMs, scanFrequency, dataExportPath, referencePeakPpm, scalingFactorRefPeak, baseline) + +if ~exist('baseline','var') + baseline = zeros(size(fids{1})); +end summedFid = zeros(size(fids{1})); current_em = size(1,length(metabolites)); currentConcentrationRm = size(1,length(metabolites)); for indexMetabolite = 1:length(metabolites) - current_T2 = T2s(indexMetabolite) + current_em_std_factor * T2_std(indexMetabolite);%in ms + current_T2 = T2s(indexMetabolite) + current_em_std_factor(indexMetabolite) * T2_std(indexMetabolite);%in ms if strcmp(metabolites(indexMetabolite),'MMB') current_em(indexMetabolite) = 1; + %the Gaussian for the acquired MMB should be smaller than the one for + %metabolites, since it was already measured with the inherent + %micro- and macro-susceptibility. It should however not be negative! + if current_gm - 8 > 0 + gm = current_gm - 8; + else + gm = 0; + end else current_em(indexMetabolite) = 1 / (pi * current_T2 * 1e-3);%from ms to s and then Hz + gm = current_gm; end %----- precalculate coefficients for the corrections and filters -----% % zero order phase correction @@ -32,7 +45,7 @@ for indexMetabolite = 1:length(metabolites) % gauss filter % calculate the gauss filter coefficients - gauss_filter_coeff1 = current_gm*pi; + gauss_filter_coeff1 = gm*pi; gauss_filter_coeff2 = -(4*log(2)); gauss_filter_coeff = gauss_filter_coeff1 ^2 /gauss_filter_coeff2; %--------------- end of coefficient precalculations ------------------% @@ -84,7 +97,14 @@ for indexMetabolite = 1:length(metabolites) end -summedFidWithNoise = summedFid + noiseVector; +% the baselines were scaled down to the maximal peak being 1, hence we need +% to rescale the baseline; Use the NAA peak (cheating hard coded points!) +spectrum = fftshift(fft(summedFid)); +% We use abs because of already added phase +maxValueSpectrum = max(abs(spectrum(1400:1600))); +baselineScaled = baseline * maxValueSpectrum; +summedFidWithNoise = summedFid + noiseVector + baselineScaled; +% figure; plot(real(fftshift(fft(summedFid)))); hold on; plot(real(fftshift(fft(baseline*maxValueSpectrum)))) if saveData % export the spectra but also the used concentrations and all parameters @@ -93,13 +113,13 @@ if saveData ExportLCModelBasis(summedFidWithNoise, dwellTimeMs, scanFrequency, dataExportPath, fileName, fileName, 'No', ... true, referencePeakPpm, scalingFactorRefPeak, 'No', TE*1e3, 'sLASER'); save([dataExportPath, fileName, '.mat'], 'summedFidWithNoise', 'current_em', 'currentConcentrationRm', ... - 'current_pc0', 'current_pc1', 'current_df2', 'current_gm', 'current_em_std_factor', 'conc_std_factor'); + 'current_pc0', 'current_pc1', 'current_df2', 'current_gm', 'current_em_std_factor', 'conc_std_factor', 'baselineScaled'); % export truncated data summedFidWithNoise(:, truncPoint:end)=0; fileNameTrunc = ['Simulated_', paramKeyWord, '_', num2str(indexParam) '_truncOn']; ExportLCModelBasis(summedFidWithNoise, dwellTimeMs, scanFrequency, dataExportPath, fileNameTrunc, fileNameTrunc, 'No', ... true, referencePeakPpm, scalingFactorRefPeak, 'No', TE*1e3, 'sLASER'); save([dataExportPath, fileName, '.mat'], 'summedFidWithNoise', 'current_em', 'currentConcentrationRm', ... - 'current_pc0', 'current_pc1', 'current_df2', 'current_gm', 'current_em_std_factor', 'conc_std_factor'); + 'current_pc0', 'current_pc1', 'current_df2', 'current_gm', 'current_em_std_factor', 'conc_std_factor', 'baselineScaled'); end end \ No newline at end of file diff --git a/createTestData/evaluateProFitFittingParameters.m b/createTestData/evaluateProFitFittingParameters.m new file mode 100644 index 0000000000000000000000000000000000000000..df93d774d7475cf6d3e073d9bcece80449c8cb27 --- /dev/null +++ b/createTestData/evaluateProFitFittingParameters.m @@ -0,0 +1,89 @@ +function evaluateProFitFittingParameters() + +folderName = 'final_simulations'; +exportFolder = {'11 Simulations'}; +pathNameExport = 'ProFit test data'; +pathBaseExportFiles = pathToDataFolder(pathNameExport, exportFolder); +% pathBaseExportFiles = pathBaseExportFiles(1:end-1); +% pathBaseExportFiles = [pathBaseExportFiles ' - R3\']; +dataExportPathBase = strcat(pathBaseExportFiles, exportFolder{1}, '\'); +truncSuffix = '_truncOn'; +folderFigures = [pathBaseExportFiles 'Output\' folderName, truncSuffix, '\']; +mkdir(folderFigures) + +folders = {'conc', 'df2', 'pc1', 'pc0', 'gauss', 'conc2', 'conc3', 'noise'}; +folders = {'df2', 'pc1', 'pc0', 'gauss'}; +folders = {'df2_global', 'df2_local', 'pc1', 'pc0', 'gauss', 'em', 'noise', 'baseline'}; +folders = {'pc0', 'pc1', 'gauss', 'df2_global', 'df2_local', ... + 'em', 'noise', 'baseline'}; +xAxisLabels = {'$$\varphi_0$$', '$$\varphi_1$$', '$$\nu_g$$', '$$\omega_{global}$$', '{\boldmath$\omega_{local}$}', ... + '{\boldmath$\nu_{e}$}', '{\boldmath$noise$}', '{\boldmath$baseline$}'}; +legendLabels = {'\varphi_0 :\hspace{3em}', '\varphi_1 :\hspace{3.em}', '\nu_g :\hspace{3.em}', '\omega_{global} :\hspace{1.5em}', '${\boldmath$\omega_{local}$}$:\hspace{1.7em}', ... + '${\boldmath$\nu_{e}$}$:\hspace{3.5em}', '${\boldmath$noise$}$:\hspace{1.5em}', '${\boldmath$baseline$}$:'}; + +parameters = {'pc0', 'pc12', 'gm', 'df2', ... + 'em', 'conc', 'T2'}; +titleLabels = {'\Delta\varphi_0', '\Delta\varphi_1', '\Delta\nu_g', '${\boldmath$\overline{\mid\Delta\omega\mid}$}$', ... + '${\boldmath$\overline{\mid\Delta\nu_{e}\mid}$}$', '${\boldmath$\overline{\mid\Delta c\mid}$}$', '${\boldmath$\overline{\mid\Delta T_{2}\mid}$}$'}; +units = { ' (degrees)', ' (degrees/ppm)', ' (Hz)', ' (Hz)',... + ' (Hz)', ' (mmol/kg)', ' (ms)'}; +% titleOffset = {'\quad variations:\quad\quad','\quad variations:\quad', '\quad variations:\quad\quad\quad', '\quad variations:\quad\quad',... +% '\quad variations:\quad\quad', '\quad variations:\quad', '\quad variations:\quad\quad'}; +titleOffset = {'\quad variations:\quad','\quad variations:\,\,', '\quad variations:\quad\quad', '\quad variations:\quad',... + '\quad variations:\quad', '\quad variations:\,\,', '\quad variations:\quad'}; +% parameters = {'conc'}; + +useSubPlots = true; +if useSubPlots + numParam = length(parameters)-1; + figure; +else + numParam = length(parameters); +end +for iParam = 1: numParam + legendLabels_ = {}; + unitLabel = [titleLabels{iParam}, units{iParam}]; + for iFolder = 1:length(folders) + load([dataExportPathBase, folders{iFolder}, '\Diff_Summaries', truncSuffix, '_no_BL_df3.mat'], 'diff_conc_mat', 'diff_em_mat', 'diff_gm_mat', ... + 'diff_pc0_mat', 'diff_df2_mat', 'diff_pc12_mat', 'diff_T2_mat'); + size1 = size(diff_conc_mat, 1); + size2 = size(diff_conc_mat, 2); + % think about these more + diff_conc_mean = mean(mean(abs(diff_conc_mat))); + diff_conc_std = std(abs(diff_conc_mat)); + + eval(['diff_mat = diff_', parameters{iParam}, '_mat;']); + + diff_mean = mean(mean(abs(diff_mat), 'omitnan')); + diff_std = std(mean(abs(diff_mat), 'omitnan')); +% numberOfNaNs = sum(sum(isnan(diff_mat))) +% numberOfNaNsV = sum((isnan(diff_mat)),2)' + + if useSubPlots + subplot(3,2,iParam) + else + figure(iParam+10); + end + hold on + if strcmp(parameters{iParam},'em') || strcmp(parameters{iParam},'conc') || ... + strcmp(parameters{iParam},'df2') || strcmp(parameters{iParam},'T2') + scatter(zeros(1,size2)+iFolder, mean(abs(diff_mat))); + else + scatter(zeros(1,size2)+iFolder, mean(diff_mat)); + end + title(['$$', titleLabels{iParam}, '$$'],'Interpreter','latex'); + legendLabels_{iFolder}= ['$$' legendLabels{iFolder}, num2str(diff_mean,'%.2f'), ' \pm ', num2str(diff_std,'%.2f'), '$$']; + lgd = legend(legendLabels_,'Interpreter','latex','Location','northwest'); + + title(lgd,{'$$Spectra\,\,with\,\,induced$$',['$$', titleOffset{iParam}, unitLabel,'$$']},'FontSize',8); + end + xlim([0, length(folders)+1]); + xticks(1:length(folders)); + xticklabels(xAxisLabels); + xlabel('Simulations') + set(gca,'YAxisLocation','right') + ylabel(['$$', unitLabel, '$$'],'Interpreter','latex'); + set(gca,'TickLabelInterpreter','latex') + set(gca,'XTickLabelRotation',60) + savefig([folderFigures, parameters{iParam}]) +end \ No newline at end of file diff --git a/createTestData/fittingLCModelWithTransfer.m b/createTestData/fittingLCModelWithTransfer.m index b3040c9eb6e4e326be6292dab472df4078819183..d9a3a4b030d57c3f4817dcb3a3f9fcd5a737a436 100644 --- a/createTestData/fittingLCModelWithTransfer.m +++ b/createTestData/fittingLCModelWithTransfer.m @@ -1,15 +1,23 @@ function fittingLCModelWithTransfer(LCModelCallerInstance, localFilePath, filenameData, dataPath, ... - filenameWater, waterPath, currentTEString, copyFiles) + filenameWater, waterPath, currentTEString, copyFiles, fitWater) +if ~exist('fitWater','var') + fitWater = false; +end + extensionTable = '.table'; extensionCoord = '.coord'; defaultTE = 'TE24'; -defaultLCModelUser = 'tborbath@mpi.localnet'; +defaultLCModelUser = 'tborbath'; defaultSpectraName = 'XXXX'; defaultWaterRefName = 'YYYY'; controlFilesBase = 'fitsettings_'; -controlFilesBaseSuffix = '_Metabolite.control'; +if fitWater + controlFilesBaseSuffix = '_MC_Water.control'; +else %normal case + controlFilesBaseSuffix = '_Metabolite.control'; +end %% file paths setup controlFilesPathLocal = [localFilePath, 'LCModelConfig/']; diff --git a/createTestData/fitting_all_test_data_profit.m b/createTestData/fitting_all_test_data_profit.m index 95105f731fb7b1b3cc23262d677e80d0f7fc1d49..f6e58f48bab1f2ca8d3db32b9526663a04e0affd 100644 --- a/createTestData/fitting_all_test_data_profit.m +++ b/createTestData/fitting_all_test_data_profit.m @@ -6,7 +6,7 @@ use_water_references = true; %TODO change TR = 6000;%ms -reconOption = 4; +reconOption = 2; truncOn = true; exportFolders = {'0 Water References',... @@ -47,20 +47,21 @@ else end subjects = { ... - '1658' ... - '1717' ... - '2017' ... - '3373' ... - '3490' ... - '5771' ... - '6249' ... - '6971' ... - '7338' ... - '7782' ... - '9810' ... +% 'Summed' ... + 'Subj_1' ... + 'Subj_2' ... + 'Subj_3' ... + 'Subj_4' ... + 'Subj_5' ... + 'Subj_6' ... + 'Subj_7' ... + 'Subj_8' ... + 'Subj_9' ... + 'Subj_10' ... + 'Subj_11' ... }; -TEs = [24; 32; 40; 52; 60]; +TEs = [24; ];%32; 40; 52; 60]; numberOfSubjects = length(subjects); waterExportPath = cell(1,numberOfSubjects); @@ -95,6 +96,12 @@ for indexSubj = 1:numberOfSubjects % load([filenameWater '.mat'], 'aWater', 'maxWaterPeak'); concentrations = cell(numberOfTEs,length(namingSuffixesAve)); + concentrations_H2O = cell(numberOfTEs,length(namingSuffixesAve)); + concentrations_MC_H2O = cell(numberOfTEs,length(namingSuffixesAve)); + if ~fitLCModel + FQNs = cell(numberOfTEs,length(namingSuffixesAve)); + FQNs2 = cell(numberOfTEs,length(namingSuffixesAve)); + end %% reconstruct data for indexTE = 1:1%numberOfTEs for indexAverageDelete = 1: length(namingSuffixesAve) @@ -106,6 +113,10 @@ for indexSubj = 1:numberOfSubjects filenameData = [ subjects{indexSubj}, '_', TE_string namingSuffixAve namingSuffixCoil truncSuffix]; dataExportPathTE = [dataExportPath{indexSubj}, '\\', TE_string, '\\']; + load([dataExportPathTE, filenameData, '.mat'],'a') + MC_mix =2; + filenameData_MC_water = [filenameData, '_MC_water']; + a.ExportLcmRaw(dataExportPathTE, filenameData_MC_water, false, 'No', -4.7, 0.05, MC_mix); if fitLCModel if use_water_references try @@ -114,6 +125,12 @@ for indexSubj = 1:numberOfSubjects movefile([outputFilesPathLocal filenameData '.*'], dataExportPathTE); concentrations{indexTE,indexAverageDelete, indexCoilDelete} = ... importConcentrationLCModelTable([filenameData '.table'],dataExportPathTE, TE_string, 'Met moiety'); + %MC_water +% fittingLCModelWithTransfer(LCModelCallerInstance, pathBaseExportFiles, ... +% filenameData_MC_water, dataExportPathTE, filenameWater, waterPath, TE_string, copyFiles, true); +% movefile([outputFilesPathLocal filenameData_MC_water '.*'], dataExportPathTE); +% concentrations_MC_H2O{indexTE,indexAverageDelete, indexCoilDelete} = ... +% importConcentrationLCModelTable([filenameData_MC_water '.table'],dataExportPathTE, TE_string, 'Met moiety'); catch concentrations{indexTE,indexAverageDelete, indexCoilDelete} = {}; continue; @@ -122,14 +139,20 @@ for indexSubj = 1:numberOfSubjects fittingLCModelWithTransfer(LCModelCallerInstance, pathBaseExportFiles, ... filenameData, dataExportPathTE, [], [], TE_string, copyFiles); end - plot_All_Fit_Metabolites([filenameData, '.coord'],dataExportPathTE, 'Met moiety', true); + plot_All_Fit_Metabolites([filenameData, '.coord'],dataExportPathTE, 'Met moiety', true, true); else %TODO if use_water_references fittingProFit(filenameData, dataExportPathTE, filenameWater, waterPath, TEs(indexTE), TR, dataExportPathTE); + fitting_MC_water(filenameData_MC_water, dataExportPathTE, TEs(indexTE), TR, dataExportPathTE) else fittingProFit(filenameData, dataExportPathTE, [], [], TEs(indexTE), TR, dataExportPathTE); end - [concentrations{indexTE,indexAverageDelete, indexCoilDelete}, activeMetabolites] = plot_ProFit_Metabolites_Fit([filenameData, '_profit.mat'],dataExportPathTE, 'Met', true); + [concentrations{indexTE,indexAverageDelete, indexCoilDelete}, activeMetabolites, FQNs{indexTE,indexAverageDelete, indexCoilDelete}, FQNs2{indexTE,indexAverageDelete, indexCoilDelete}] = ... + plot_ProFit_Metabolites_Fit([filenameData, '_profit.mat'],dataExportPathTE, 'Met', true); + load([dataExportPathTE, filenameData, '_profit_H2O.mat'],'concH2O'); + concentrations_H2O{indexTE,indexAverageDelete, indexCoilDelete}=concH2O; + load([dataExportPathTE, filenameData_MC_water, '_profit.mat'],'concH2O'); + concentrations_MC_H2O{indexTE,indexAverageDelete, indexCoilDelete}=concH2O; end close all end @@ -137,8 +160,11 @@ for indexSubj = 1:numberOfSubjects end if fitLCModel save([dataExportPath{indexSubj}, 'concentrations' truncSuffix '.mat'], 'concentrations'); + save([dataExportPath{indexSubj}, 'concentrations', truncSuffix '_MC_H2O.mat'], 'concentrations_MC_H2O'); else - save([dataExportPath{indexSubj}, 'concentrations', truncSuffix '_profit.mat'], 'concentrations', 'activeMetabolites'); + save([dataExportPath{indexSubj}, 'concentrations', truncSuffix '_profit.mat'], 'concentrations', 'activeMetabolites', 'FQNs', 'FQNs2'); + save([dataExportPath{indexSubj}, 'concentrations', truncSuffix '_H2O_profit.mat'], 'concentrations_H2O'); + save([dataExportPath{indexSubj}, 'concentrations', truncSuffix '_MC_H2O_profit.mat'], 'concentrations_MC_H2O'); end end diff --git a/createTestData/fitting_simulated_test_data_profit.m b/createTestData/fitting_simulated_test_data_profit.m index 0fce67f59e065c81d9973e7c5de7d577214fcc9b..f02bd6ebe7da14ede2b2823edbe8455e93623838 100644 --- a/createTestData/fitting_simulated_test_data_profit.m +++ b/createTestData/fitting_simulated_test_data_profit.m @@ -1,6 +1,7 @@ -function fitting_simulated_test_data_profit() - -fitLCModel = false; %false fits profit +function fitting_simulated_test_data_profit(fitLCModel) +if ~exist('fitLCModel','var') + fitLCModel = false; %false fits profit +end %TODO change TR = 6000;%ms @@ -12,12 +13,6 @@ pathNameExport = 'ProFit test data'; pathBaseExportFiles = pathToDataFolder(pathNameExport, exportFolder); dataExportPathBase = strcat(pathBaseExportFiles, exportFolder{1}, '\'); -if truncOn == false - truncSuffix = '_truncOff'; -else - truncSuffix = '_truncOn'; -end - TE = 24; if fitLCModel @@ -36,120 +31,149 @@ else end %% do the actual fitting -numberConcPermutations = 100; -paramKeyword = 'conc'; -truncSuffix = '_truncOn'; -fileNameBase = ['Simulated_', paramKeyword, '_']; -actualFitting(numberConcPermutations, paramKeyword, dataExportPathBase, TE, TR, fileNameBase, ... - truncSuffix, fitLCModel, LCModelCallerInstance, pathBaseExportFiles, copyFiles, outputFilesPathLocal); -% -numberConcPermutations = 100; -paramKeyword = 'conc'; -truncSuffix = '_truncOff'; -fileNameBase = ['Simulated_', paramKeyword, '_']; -actualFitting(numberConcPermutations, paramKeyword, dataExportPathBase, TE, TR, fileNameBase, ... - truncSuffix, fitLCModel, LCModelCallerInstance, pathBaseExportFiles, copyFiles, outputFilesPathLocal); - -numberConcPermutations = 13; -paramKeyword = 'df2'; -truncSuffix = '_truncOn'; -fileNameBase = ['Simulated_', paramKeyword, '_']; -actualFitting(numberConcPermutations, paramKeyword, dataExportPathBase, TE, TR, fileNameBase, ... - truncSuffix, fitLCModel, LCModelCallerInstance, pathBaseExportFiles, copyFiles, outputFilesPathLocal); -% -numberConcPermutations = 13; -paramKeyword = 'df2'; -truncSuffix = '_truncOff'; -fileNameBase = ['Simulated_', paramKeyword, '_']; -actualFitting(numberConcPermutations, paramKeyword, dataExportPathBase, TE, TR, fileNameBase, ... - truncSuffix, fitLCModel, LCModelCallerInstance, pathBaseExportFiles, copyFiles, outputFilesPathLocal); - -numberConcPermutations = 7; -paramKeyword = 'pc1'; -truncSuffix = '_truncOn'; -fileNameBase = ['Simulated_', paramKeyword, '_']; -actualFitting(numberConcPermutations, paramKeyword, dataExportPathBase, TE, TR, fileNameBase, ... - truncSuffix, fitLCModel, LCModelCallerInstance, pathBaseExportFiles, copyFiles, outputFilesPathLocal); -% -numberConcPermutations = 7; -paramKeyword = 'pc1'; -truncSuffix = '_truncOff'; -fileNameBase = ['Simulated_', paramKeyword, '_']; -actualFitting(numberConcPermutations, paramKeyword, dataExportPathBase, TE, TR, fileNameBase, ... - truncSuffix, fitLCModel, LCModelCallerInstance, pathBaseExportFiles, copyFiles, outputFilesPathLocal); - -numberConcPermutations = 9; -paramKeyword = 'pc0'; -truncSuffix = '_truncOn'; -fileNameBase = ['Simulated_', paramKeyword, '_']; -actualFitting(numberConcPermutations, paramKeyword, dataExportPathBase, TE, TR, fileNameBase, ... - truncSuffix, fitLCModel, LCModelCallerInstance, pathBaseExportFiles, copyFiles, outputFilesPathLocal); -% -numberConcPermutations = 9; -paramKeyword = 'pc0'; -truncSuffix = '_truncOff'; -fileNameBase = ['Simulated_', paramKeyword, '_']; -actualFitting(numberConcPermutations, paramKeyword, dataExportPathBase, TE, TR, fileNameBase, ... - truncSuffix, fitLCModel, LCModelCallerInstance, pathBaseExportFiles, copyFiles, outputFilesPathLocal); - -numberConcPermutations = 13; -paramKeyword = 'gauss'; -truncSuffix = '_truncOn'; -fileNameBase = ['Simulated_', paramKeyword, '_']; -actualFitting(numberConcPermutations, paramKeyword, dataExportPathBase, TE, TR, fileNameBase, ... - truncSuffix, fitLCModel, LCModelCallerInstance, pathBaseExportFiles, copyFiles, outputFilesPathLocal); -% -numberConcPermutations = 13; -paramKeyword = 'gauss'; -truncSuffix = '_truncOff'; -fileNameBase = ['Simulated_', paramKeyword, '_']; -actualFitting(numberConcPermutations, paramKeyword, dataExportPathBase, TE, TR, fileNameBase, ... - truncSuffix, fitLCModel, LCModelCallerInstance, pathBaseExportFiles, copyFiles, outputFilesPathLocal); - -% do the actual fitting -numberConcPermutations = 50; -paramKeyword = 'conc2'; -truncSuffix = '_truncOn'; -fileNameBase = ['Simulated_', paramKeyword, '_']; -actualFitting(numberConcPermutations, paramKeyword, dataExportPathBase, TE, TR, fileNameBase, ... - truncSuffix, fitLCModel, LCModelCallerInstance, pathBaseExportFiles, copyFiles, outputFilesPathLocal); - -numberConcPermutations = 50; -paramKeyword = 'conc2'; -truncSuffix = '_truncOff'; -fileNameBase = ['Simulated_', paramKeyword, '_']; -actualFitting(numberConcPermutations, paramKeyword, dataExportPathBase, TE, TR, fileNameBase, ... - truncSuffix, fitLCModel, LCModelCallerInstance, pathBaseExportFiles, copyFiles, outputFilesPathLocal); - -numberConcPermutations = 50; -paramKeyword = 'conc3'; -truncSuffix = '_truncOn'; -fileNameBase = ['Simulated_', paramKeyword, '_']; -actualFitting(numberConcPermutations, paramKeyword, dataExportPathBase, TE, TR, fileNameBase, ... - truncSuffix, fitLCModel, LCModelCallerInstance, pathBaseExportFiles, copyFiles, outputFilesPathLocal); -% -numberConcPermutations = 50; -paramKeyword = 'conc3'; -truncSuffix = '_truncOff'; -fileNameBase = ['Simulated_', paramKeyword, '_']; -actualFitting(numberConcPermutations, paramKeyword, dataExportPathBase, TE, TR, fileNameBase, ... - truncSuffix, fitLCModel, LCModelCallerInstance, pathBaseExportFiles, copyFiles, outputFilesPathLocal); - -% -numberConcPermutations = 25; -paramKeyword = 'noise'; -truncSuffix = '_truncOn'; -fileNameBase = ['Simulated_', paramKeyword, '_']; -actualFitting(numberConcPermutations, paramKeyword, dataExportPathBase, TE, TR, fileNameBase, ... - truncSuffix, fitLCModel, LCModelCallerInstance, pathBaseExportFiles, copyFiles, outputFilesPathLocal); - -numberConcPermutations = 25; -paramKeyword = 'noise'; -truncSuffix = '_truncOff'; -fileNameBase = ['Simulated_', paramKeyword, '_']; -actualFitting(numberConcPermutations, paramKeyword, dataExportPathBase, TE, TR, fileNameBase, ... - truncSuffix, fitLCModel, LCModelCallerInstance, pathBaseExportFiles, copyFiles, outputFilesPathLocal); +if truncOn + numberConcPermutations = 100; + paramKeyword = 'conc'; + truncSuffix = '_truncOn'; + fileNameBase = ['Simulated_', paramKeyword, '_']; + actualFitting(numberConcPermutations, paramKeyword, dataExportPathBase, TE, TR, fileNameBase, ... + truncSuffix, fitLCModel, LCModelCallerInstance, pathBaseExportFiles, copyFiles, outputFilesPathLocal); +else + numberConcPermutations = 100; + paramKeyword = 'conc'; + truncSuffix = '_truncOff'; + fileNameBase = ['Simulated_', paramKeyword, '_']; + actualFitting(numberConcPermutations, paramKeyword, dataExportPathBase, TE, TR, fileNameBase, ... + truncSuffix, fitLCModel, LCModelCallerInstance, pathBaseExportFiles, copyFiles, outputFilesPathLocal); +end + +if truncOn + numberConcPermutations = 15; + paramKeyword = 'df2_local'; + truncSuffix = '_truncOn'; + fileNameBase = ['Simulated_', paramKeyword, '_']; + actualFitting(numberConcPermutations, paramKeyword, dataExportPathBase, TE, TR, fileNameBase, ... + truncSuffix, fitLCModel, LCModelCallerInstance, pathBaseExportFiles, copyFiles, outputFilesPathLocal); +else + numberConcPermutations = 15; + paramKeyword = 'df2_local'; + truncSuffix = '_truncOff'; + fileNameBase = ['Simulated_', paramKeyword, '_']; + actualFitting(numberConcPermutations, paramKeyword, dataExportPathBase, TE, TR, fileNameBase, ... + truncSuffix, fitLCModel, LCModelCallerInstance, pathBaseExportFiles, copyFiles, outputFilesPathLocal); +end + +if truncOn + numberConcPermutations = 15; + paramKeyword = 'df2_global'; + truncSuffix = '_truncOn'; + fileNameBase = ['Simulated_', paramKeyword, '_']; + actualFitting(numberConcPermutations, paramKeyword, dataExportPathBase, TE, TR, fileNameBase, ... + truncSuffix, fitLCModel, LCModelCallerInstance, pathBaseExportFiles, copyFiles, outputFilesPathLocal); +else + numberConcPermutations = 15; + paramKeyword = 'df2_global'; + truncSuffix = '_truncOff'; + fileNameBase = ['Simulated_', paramKeyword, '_']; + actualFitting(numberConcPermutations, paramKeyword, dataExportPathBase, TE, TR, fileNameBase, ... + truncSuffix, fitLCModel, LCModelCallerInstance, pathBaseExportFiles, copyFiles, outputFilesPathLocal); +end + +if truncOn + numberConcPermutations = 15; + paramKeyword = 'pc1'; + truncSuffix = '_truncOn'; + fileNameBase = ['Simulated_', paramKeyword, '_']; + actualFitting(numberConcPermutations, paramKeyword, dataExportPathBase, TE, TR, fileNameBase, ... + truncSuffix, fitLCModel, LCModelCallerInstance, pathBaseExportFiles, copyFiles, outputFilesPathLocal); +else + numberConcPermutations = 15; + paramKeyword = 'pc1'; + truncSuffix = '_truncOff'; + fileNameBase = ['Simulated_', paramKeyword, '_']; + actualFitting(numberConcPermutations, paramKeyword, dataExportPathBase, TE, TR, fileNameBase, ... + truncSuffix, fitLCModel, LCModelCallerInstance, pathBaseExportFiles, copyFiles, outputFilesPathLocal); +end +if truncOn + numberConcPermutations = 15; + paramKeyword = 'pc0'; + truncSuffix = '_truncOn'; + fileNameBase = ['Simulated_', paramKeyword, '_']; + actualFitting(numberConcPermutations, paramKeyword, dataExportPathBase, TE, TR, fileNameBase, ... + truncSuffix, fitLCModel, LCModelCallerInstance, pathBaseExportFiles, copyFiles, outputFilesPathLocal); +else + numberConcPermutations = 15; + paramKeyword = 'pc0'; + truncSuffix = '_truncOff'; + fileNameBase = ['Simulated_', paramKeyword, '_']; + actualFitting(numberConcPermutations, paramKeyword, dataExportPathBase, TE, TR, fileNameBase, ... + truncSuffix, fitLCModel, LCModelCallerInstance, pathBaseExportFiles, copyFiles, outputFilesPathLocal); +end + +if truncOn + numberConcPermutations = 15; + paramKeyword = 'gauss'; + truncSuffix = '_truncOn'; + fileNameBase = ['Simulated_', paramKeyword, '_']; + actualFitting(numberConcPermutations, paramKeyword, dataExportPathBase, TE, TR, fileNameBase, ... + truncSuffix, fitLCModel, LCModelCallerInstance, pathBaseExportFiles, copyFiles, outputFilesPathLocal); +else + numberConcPermutations = 15; + paramKeyword = 'gauss'; + truncSuffix = '_truncOff'; + fileNameBase = ['Simulated_', paramKeyword, '_']; + actualFitting(numberConcPermutations, paramKeyword, dataExportPathBase, TE, TR, fileNameBase, ... + truncSuffix, fitLCModel, LCModelCallerInstance, pathBaseExportFiles, copyFiles, outputFilesPathLocal); +end + +if truncOn + numberConcPermutations = 15; + paramKeyword = 'em'; + truncSuffix = '_truncOn'; + fileNameBase = ['Simulated_', paramKeyword, '_']; + actualFitting(numberConcPermutations, paramKeyword, dataExportPathBase, TE, TR, fileNameBase, ... + truncSuffix, fitLCModel, LCModelCallerInstance, pathBaseExportFiles, copyFiles, outputFilesPathLocal); +else + numberConcPermutations = 15; + paramKeyword = 'em'; + truncSuffix = '_truncOff'; + fileNameBase = ['Simulated_', paramKeyword, '_']; + actualFitting(numberConcPermutations, paramKeyword, dataExportPathBase, TE, TR, fileNameBase, ... + truncSuffix, fitLCModel, LCModelCallerInstance, pathBaseExportFiles, copyFiles, outputFilesPathLocal); +end + +if truncOn + numberConcPermutations = 25; + paramKeyword = 'noise'; + truncSuffix = '_truncOn'; + fileNameBase = ['Simulated_', paramKeyword, '_']; + actualFitting(numberConcPermutations, paramKeyword, dataExportPathBase, TE, TR, fileNameBase, ... + truncSuffix, fitLCModel, LCModelCallerInstance, pathBaseExportFiles, copyFiles, outputFilesPathLocal); +else + numberConcPermutations = 25; + paramKeyword = 'noise'; + truncSuffix = '_truncOff'; + fileNameBase = ['Simulated_', paramKeyword, '_']; + actualFitting(numberConcPermutations, paramKeyword, dataExportPathBase, TE, TR, fileNameBase, ... + truncSuffix, fitLCModel, LCModelCallerInstance, pathBaseExportFiles, copyFiles, outputFilesPathLocal); +end + +if truncOn + numberConcPermutations = 16; + paramKeyword = 'baseline'; + truncSuffix = '_truncOn'; + fileNameBase = ['Simulated_', paramKeyword, '_']; + actualFitting(numberConcPermutations, paramKeyword, dataExportPathBase, TE, TR, fileNameBase, ... + truncSuffix, fitLCModel, LCModelCallerInstance, pathBaseExportFiles, copyFiles, outputFilesPathLocal); +else + numberConcPermutations = 16; + paramKeyword = 'baseline'; + truncSuffix = '_truncOff'; + fileNameBase = ['Simulated_', paramKeyword, '_']; + actualFitting(numberConcPermutations, paramKeyword, dataExportPathBase, TE, TR, fileNameBase, ... + truncSuffix, fitLCModel, LCModelCallerInstance, pathBaseExportFiles, copyFiles, outputFilesPathLocal); +end end function actualFitting(numberConcPermutations, paramKeyword, dataExportPathBase, TE, TR, fileNameBase, ... @@ -157,33 +181,55 @@ function actualFitting(numberConcPermutations, paramKeyword, dataExportPathBase, %% do the actual fitting dataExportPath = [dataExportPathBase, paramKeyword, '/']; concentrations = cell(1,numberConcPermutations); -for indexConc = 1:numberConcPermutations +if ~fitLCModel + diff_conc = cell(1,numberConcPermutations); + diff_em = cell(1,numberConcPermutations); + diff_gm = cell(1,numberConcPermutations); + diff_pc0 = cell(1,numberConcPermutations); + diff_df2 = cell(1,numberConcPermutations); + diff_pc12 = cell(1,numberConcPermutations); + diff_T2 = cell(1,numberConcPermutations); +end +for index = 1:numberConcPermutations %% reconstruct data TE_string = ['TE', num2str(TE)]; - filenameData = [fileNameBase, num2str(indexConc), truncSuffix]; + filenameData = [fileNameBase, num2str(index), truncSuffix]; if fitLCModel fittingLCModelWithTransfer(LCModelCallerInstance, pathBaseExportFiles, ... filenameData, dataExportPath, '', '', TE_string, copyFiles); movefile([outputFilesPathLocal filenameData '.*'], dataExportPath); - concentrations{indexConc} = ... + concentrations{index} = ... importConcentrationLCModelTable([filenameData '.table'],dataExportPath, TE_string, 'Met moiety'); close all; - plot_All_Fit_Metabolites([filenameData, '.coord'],dataExportPath, 'Met moiety', true); + plot_All_Fit_Metabolites([filenameData, '.coord'],dataExportPath, 'Met moiety', true, false); else - fittingProFit(filenameData, dataExportPath, '', '', TE, TR, dataExportPath); -% plot_ProFit_Metabolites_Fit([filenameData, '_profit.mat'],dataExportPath, 'Met moiety', true); - [concentrations{indexConc}, activeMetabolites] = plot_ProFit_Metabolites_Fit([filenameData, '_profit.mat'],dataExportPath, 'Met', true); + refFreqPpm = 0; + fittingProFit(filenameData, dataExportPath, '', '', TE, TR, dataExportPath,refFreqPpm); + [concentrations{index}, activeMetabolites] = plot_ProFit_Metabolites_Fit([filenameData, '_profit.mat'],dataExportPath, 'Met', true, false); + [diff_conc{index}, diff_em{index}, diff_gm{index}, diff_pc0{index}, diff_df2{index}, diff_pc12{index}, diff_T2{index}] = ... + compareFitInput_Output(dataExportPath, filenameData, 3); +% close all; end end + if fitLCModel save([dataExportPathBase, 'concentrations_', paramKeyword, truncSuffix '.mat'], 'concentrations'); else save([dataExportPathBase, 'concentrations_', paramKeyword, truncSuffix '_profit.mat'], 'concentrations', 'activeMetabolites'); + diff_conc_mat = reshape(cell2mat(diff_conc), length(diff_conc{1}), numberConcPermutations); + diff_em_mat = reshape(cell2mat(diff_em), length(diff_em{1}), numberConcPermutations); + diff_gm_mat = reshape(cell2mat(diff_gm), length(diff_gm{1}), numberConcPermutations); + diff_pc0_mat = reshape(cell2mat(diff_pc0), length(diff_pc0{1}), numberConcPermutations); + diff_df2_mat = reshape(cell2mat(diff_df2), length(diff_df2{1}), numberConcPermutations); + diff_pc12_mat = reshape(cell2mat(diff_pc12), length(diff_pc12{1}), numberConcPermutations); + diff_T2_mat = reshape(cell2mat(diff_T2), length(diff_T2{1}), numberConcPermutations); + save([dataExportPathBase, paramKeyword, '\Diff_Summaries', truncSuffix, '_no_BL_df3.mat'], 'diff_conc_mat', 'diff_em_mat', 'diff_gm_mat', ... + 'diff_pc0_mat', 'diff_df2_mat', 'diff_pc12_mat', 'diff_T2_mat'); end close all diff --git a/createTestData/getLCModelBaseline.m b/createTestData/getLCModelBaseline.m new file mode 100644 index 0000000000000000000000000000000000000000..a9fd17ad83bce3a338dff0a7ff6d7723e75aeede --- /dev/null +++ b/createTestData/getLCModelBaseline.m @@ -0,0 +1,135 @@ +function [baselineFid] = getLCModelBaseline() + +exportFolders = {'1 Normal recon', '5 Water Supp Off', '8 Rescale Water Supp Off'}; + +subjects = {{1658; 2017; 5771; 6971;};... + {3373; 7338;}; ... + {3490; 6249; 1717; 3373; 7338; 9810; 7782};}; +Labels = {{'Flat_drop_H20'; 'Flat'; 'Flat'; 'Flat';};... + {'Wildish'; 'Wildish'}; ... + {'Very_wild';'Very_wild';'Wild'; 'Wild';'Wildish'; 'Wildish'; 'Normal'};}; +pathNameExport = 'ProFit test data'; +pathBaseExportFiles = pathToDataFolder(pathNameExport, exportFolders); +pathBaselineExport = strcat(pathBaseExportFiles, '11 Simulations\Baselines\'); +pathBaseExportFiles(end:end+1) = '_\'; +dataPathMatFiles = strcat(pathBaseExportFiles, exportFolders{1}, '\'); + +extensionCoord = '.coord'; +extensionMat = '.mat'; +phase90 = -90 * pi/180; +zeroFillFactor = 2; + +runningIndex = 0; +for indexFolder = 1:3 + LCModelOutputPathBase = strcat(pathBaseExportFiles, exportFolders{indexFolder}, '\'); + for indexSubj = 1 : length(subjects{indexFolder}) + runningIndex = runningIndex + 1; + currentSubject = num2str(subjects{indexFolder}{indexSubj}); + LCModelOutputPath = strcat(LCModelOutputPathBase, currentSubject, '\TE24\'); + + fileName = [currentSubject '_TE24']; + + LCModelTableFitsCoord = strcat(fileName, extensionCoord); + reconstructedSpectra = strcat(dataPathMatFiles, currentSubject, '\TE24\', fileName, extensionMat); + + + load(reconstructedSpectra, 'a'); + currentLCModelCoordFit = LCModelTableFitsCoord; + [nOfPoints, ppmVector_lcm, phasedData_lcm, fitData, baselineData_lcm, residualData, ... + metaboliteNames, metaboliteData, tableConcentrations, ppmStart_lcm, ppmEnd_lcm, ... + scanFrequency, frequencyShift, ppmGap, phase0_deg_lcm, phase1_deg_ppm_lcm] = ... + extractFits(LCModelOutputPath,currentLCModelCoordFit); + + water_ppm = 4.7; + + % align the two spectra + fid = a.Data{1}(:,1,1,1,1,1,1,1,1,1,1,1)'; + + samples = length(fid); + scanFreq = a.Parameter.Headers.ScanFrequency*1e-6; + bandWidth = a.Parameter.Headers.Bandwidth_Hz; + frequencyRange_zf = linspace(-bandWidth/2,bandWidth/2, samples * zeroFillFactor); + ppm_zf = frequencyRange_zf/scanFreq + water_ppm; + + % max of the LCModel fit + maxSpectrum_lcm = max(phasedData_lcm+baselineData_lcm); + baselineData_lcm = baselineData_lcm ./ maxSpectrum_lcm; + + c = polyfit([ppmVector_lcm(end-300:end); ppm_zf(ppm_zf<0)'], [baselineData_lcm(end-300:end); 0*(ppm_zf(ppm_zf<0))'],30); + baselineData_Low = polyval(c,ppm_zf(ppm_zf<ppmEnd_lcm)); + + c = polyfit([ppmVector_lcm(1:300); ppm_zf(ppm_zf>4.7)'], [baselineData_lcm(1:300); 0*(ppm_zf(ppm_zf>4.7))'],30); + baselineData_High = polyval(c,ppm_zf(ppm_zf>ppmStart_lcm)); + + figure; plot(ppmVector_lcm,baselineData_lcm); + hold on; plot(ppm_zf(ppm_zf<ppmEnd_lcm),baselineData_Low) + hold on; plot(ppm_zf(ppm_zf>ppmStart_lcm),baselineData_High) + + baselineFullReal = [baselineData_Low(2:end)'; flipud(baselineData_lcm); baselineData_High(1:end-1)']; + + figure; plot(ppm_zf,baselineFullReal); + + baselineFid = ifft(ifftshift(complex(baselineFullReal))); + baselineFid(length(baselineFid)/2:end)=0; + baselineSpectrumPhased90 = fftshift(fft(baselineFid .* exp(1i*phase90))).*2; %multiply by 2 to account for nulling the half of the FID + baselineFullImag = real(baselineSpectrumPhased90); + baselineFid = ifft(ifftshift(complex(baselineFullReal, baselineFullImag))); + + aBaseline = a; + aBaseline.Data{1} = baselineFid; + aBaseline.ExportLcmRaw(pathBaselineExport,['Baseline_', num2str(runningIndex), Labels{indexFolder}{indexSubj}],false); + end +end + +%% extract a sample dataset with the new data naming. +% currentSubject = 'Subj_1'; +% fileName = [currentSubject '_TE24']; +% reconstructedSpectra = strcat(dataPathMatFiles, currentSubject, '\TE24\', fileName, extensionMat); +% load(reconstructedSpectra, 'a'); +%% single lipid peak 1.3ppm +runningIndex = runningIndex + 1; %would be 14 + +fid = a.Data{1}(:,1,1,1,1,1,1,1,1,1); +ppmVector = a.getPpmVector(); +time = (0:length(fid) - 1)' * (1/a.Parameter.Headers.Bandwidth_Hz); +%create peak to fit gradient modulation downfield +scanFrequency = a.Parameter.Headers.ScanFrequency; +f = (1.3-4.66) *scanFrequency*1E-6; %Hz +T2 = 0.2; %s +singlet = exp(1i*2*pi*f*time).*exp(-time/T2); +Fgau = 400; %parameter that sets the decay rate +W = exp(- time.^2*(Fgau)^2); +singletW = singlet.*W; + +maxValue = max(real(fftshift(fft(singletW)))); +singletW = singletW ./ maxValue .* 0.3; %scale to 0.3 of NAA peak later + +figure; +plot(ppmVector, real(fftshift(fft(singletW)))); +xlim([0.6 4.2]) + +aBaseline = a; +aBaseline.Data{1} = singletW; +aBaseline.ExportLcmRaw(pathBaselineExport,['Baseline_', num2str(runningIndex), 'Lipid_1.3'],false); + +%% phased single lipid peak 1.3ppm +runningIndex = runningIndex + 1; +phasedSingletW = singletW * exp(-pi*1i*90/180); + +figure; +plot(ppmVector, real(fftshift(fft(phasedSingletW)))); +xlim([0.6 4.2]) + +aBaseline = a; +aBaseline.Data{1} = phasedSingletW; +aBaseline.ExportLcmRaw(pathBaselineExport,['Baseline_', num2str(runningIndex), 'Lipid_1.3_phased'],false); + +%% zero baseline +runningIndex = runningIndex + 1; +zeroBaseline = zeros(size(singletW)); + +aBaseline = a; +aBaseline.Data{1} = zeroBaseline; +aBaseline.ExportLcmRaw(pathBaselineExport,['Baseline_', num2str(runningIndex), 'Zero'],false); + +end \ No newline at end of file diff --git a/createTestData/plotBaselines_and_fitted_spectra.m b/createTestData/plotBaselines_and_fitted_spectra.m new file mode 100644 index 0000000000000000000000000000000000000000..3d519c0652607eca535698b46254f40c1b20a026 --- /dev/null +++ b/createTestData/plotBaselines_and_fitted_spectra.m @@ -0,0 +1,258 @@ +function plotBaselines_and_fitted_spectra() + +%% path to the export of the spectra +exportFolder = {'11 Simulations'}; +pathNameExport = 'ProFit test data'; +pathBaseExportFiles = pathToDataFolder(pathNameExport, exportFolder); +pathBaseExportFiles = pathBaseExportFiles(1:end-1); +pathBaseExportFiles = [pathBaseExportFiles ' - R3\']; +dataExportPathBase = strcat(pathBaseExportFiles, exportFolder{1}, '\'); +plotPath = [dataExportPathBase, 'Plots\BaselinePlots\']; + +plot_dkntmn = false; +%% +paramKeyword = 'baseline'; +if plot_dkntmn + dataExportPath_05 = [dataExportPathBase, paramKeyword, ' - dkntmn0.5\']; + dataExportPath_015 = [dataExportPathBase, paramKeyword, ' - dkntmn0.15\']; + dataExportPath = [dataExportPathBase, paramKeyword, ' - dkntmn0.25\']; +else + dataExportPath = [dataExportPathBase, paramKeyword, '\']; +end + +baselines = {'1Flat_drop_H20'; '2Flat'; '3Flat'; '4Flat'; '5Wildish'; '6Wildish'; '7Very_wild';... + '8Very_wild'; '9Wild'; '10Wild'; '11Wildish'; '12Wildish'; '13Normal'; '14Lipid_1.3'; '15Lipid_1.3_phased'; '16Zero'}; + + +bandwidth = 8000; + +trunc = true; +if trunc + truncSuffix = '_truncOn'; +else + truncSuffix = '_truncOff'; +end + +iteration = 4 ; + +colorSpectrum = [0 0.45 0.74]; +colorOriginal = [0 0 0]; +colorProFit = [0.49 0.18 0.56]; +colorLCModel = [0.85 0.33 0.1]; +if plot_dkntmn + colorLCModel_05 = [0.45 0.05 0.]; + colorLCModel_015 = [1 0.53 0.1]; +end +arrowsColor = [0.4 0.4 0.4]; +backgroundInlayColor = [0.8 0.8 0.8]; +LineWidth = 1.5; + +offsetBaseline = 7; % percent of max peak +offsetResidual = 20; % percent of max peak +offsetPlots = 4; % percent of max peak +subplotGridX = 2; +subplotGridY = 2; +nGrid = subplotGridX * subplotGridY; + +sortedFigure = [16, 15, 14, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13]; + +subplotNames = {'A', 'B', 'C', 'D'}; + +for indexParam = 1:length(baselines) + if mod(indexParam-1,nGrid)==0 +% figure; + figure('units','normalized','outerposition',[0.13,-0.014,0.85,0.99]); %Works on the Dell screen + end + indexParamSorted = sortedFigure(indexParam); + %% load data: Input data, LCModel fit, ProFit Fit + % import the spectra but also the used concentrations and all parameters + fileName = ['Simulated_', paramKeyword, '_', num2str(indexParamSorted) '_truncOff']; + load([dataExportPath, fileName, '.mat'], 'summedFidWithNoise', 'current_em', 'currentConcentrationRm', ... + 'current_pc0', 'current_pc1', 'current_df2', 'current_gm', 'current_em_std_factor', 'conc_std_factor', 'baselineScaled'); + if plot_dkntmn + fileName = ['Simulated_', paramKeyword, '_', num2str(indexParamSorted) truncSuffix]; + [~, ~, phasedData_lcm_05, fitData_05, baselineData_lcm_05, residualData_05, ... + ~, ~, ~, ~, ~, ~, ~, ~, ~, ~] = ... + extractFits(dataExportPath_05,[fileName, '.coord']); + [~, ~, phasedData_lcm_015, fitData_015, baselineData_lcm_015, residualData_015, ... + ~, ~, ~, ~, ~, ~, ~, ~, ~, ~] = ... + extractFits(dataExportPath_015,[fileName, '.coord']); + end + [nOfPoints, ppmVector_lcm, phasedData_lcm, fitData, baselineData_lcm, residualData, ... + metaboliteNames, metaboliteData, tableConcentrations, ppmStart_lcm, ppmEnd_lcm, ... + scanFrequency, frequencyShift, ppmGap, phase0_deg_lcm, phase1_deg_ppm_lcm] = ... + extractFits(dataExportPath,[fileName, '.coord']); + + load(strcat(dataExportPath,fileName, '_profit.mat'),'fitresult', 'data'); + + %% process input data + nTimepoints = length(summedFidWithNoise); + ppmVector = ppmVectorFunction(scanFrequency*1e6, bandwidth, nTimepoints, '1H'); + + spectrum = fftshift(fft(summedFidWithNoise)); + baselineSpectrum = fftshift(fft(baselineScaled)); + + indexEnd = find(ppmVector > ppmEnd_lcm, 1); + spectrumInputOffset = real(spectrum(indexEnd)); + baselineInputOffset = real(baselineSpectrum(indexEnd)); + + %% process ProFit data + currentFitresult = fitresult{1,iteration}; + ppm_profit = currentFitresult.common_data.data.fitroi.ppm2; + %phasedData + pData_profit = currentFitresult.processed_spec; + %residual + rData_profit = currentFitresult.residual_spec; + %spline baseline + if ~isempty(currentFitresult.splines_baseline) + spBB = currentFitresult.splines_baseline.basis_matrix; + concSpline = currentFitresult.splines_baseline.coeff; + bData_profit = (spBB * concSpline(1:size(spBB,2)))'; + splines_lambda = currentFitresult.splines_lambda; + splines_ed_vec = currentFitresult.splines_ed_vec; + splines_optim_model_vec = currentFitresult.splines_optim_model_vec; + splines_optim_idx = currentFitresult.splines_optim_idx; + else + bData_profit = zeros(size(currentFitresult.residual_spec)); + splines_lambda = 0; + splines_ed_vec = []; + splines_optim_model_vec = []; + splines_optim_idx = 0; + end + + %% Scale for plotting + % calculate scaling. Maximum has to be from the same fitted range as in LCModel/ProFit + ppmMask = (ppmVector < ppmStart_lcm) & (ppmVector > ppmEnd_lcm); + maxSpectrum = max(real(spectrum(ppmMask))); + maxSpectrum_lcm = max(phasedData_lcm); + maxSpectrum_profit = max(real(pData_profit)); + scalingFactor_lcm = maxSpectrum ./ maxSpectrum_lcm; + scalingFactor_profit = maxSpectrum ./ maxSpectrum_profit; + + minBaseline = min(real(baselineSpectrum(ppmMask))); + + %scale the offsets + offsetBaselineScaled = offsetBaseline * maxSpectrum / 100; + offsetResidualScaled = offsetResidual * maxSpectrum / 100 - minBaseline; + offsetPlotsScaled = offsetPlots * maxSpectrum / 100; + + %% create the figure + indexSubplot = mod(indexParam-1, nGrid)+1; + hs = subplot(subplotGridX,subplotGridY,indexSubplot); + coordinates = hs.Position; + + hold on; %if not alligned, mind that the ppmVector has to be defined with the water resonance at 4.7 ppm + plot(ppmVector,real(spectrum),'LineWidth', LineWidth, 'Color', colorSpectrum); +% plot(ppmVector_lcm,real(phasedData_lcm)*scalingFactor_lcm,'LineWidth', LineWidth, 'Color', colorLCModel); +% plot(ppm_profit,real(pData_profit)*scalingFactor_profit,'LineWidth', LineWidth, 'Color', colorProFit); + + if plot_dkntmn + offsetBaselineScaled = offsetBaselineScaled + offsetPlotsScaled; + plot(ppmVector_lcm,real(baselineData_lcm_05)*scalingFactor_lcm-offsetBaselineScaled+2.4*offsetPlotsScaled,':','LineWidth', LineWidth, 'Color', colorLCModel_05); + plot(ppmVector_lcm,real(baselineData_lcm)*scalingFactor_lcm-offsetBaselineScaled+1.6*offsetPlotsScaled,'-.','LineWidth', LineWidth, 'Color', colorLCModel); + plot(ppmVector_lcm,real(baselineData_lcm_015)*scalingFactor_lcm-offsetBaselineScaled+0.8*offsetPlotsScaled,':','LineWidth', LineWidth, 'Color', colorLCModel_015); + else + plot(ppmVector_lcm,real(baselineData_lcm)*scalingFactor_lcm-offsetBaselineScaled+offsetPlotsScaled,'-.','LineWidth', LineWidth, 'Color', colorLCModel); + end + plot(ppmVector,real(baselineSpectrum)-offsetBaselineScaled,'-.','LineWidth', LineWidth, 'Color', colorOriginal); + plot(ppm_profit,real(bData_profit)*scalingFactor_profit-offsetBaselineScaled-offsetPlotsScaled,'-.','LineWidth', LineWidth, 'Color', colorProFit); + + plot(ppmVector_lcm,real(residualData)*scalingFactor_lcm-offsetResidualScaled,'LineWidth', LineWidth, 'Color', colorLCModel); + plot(ppm_profit,real(rData_profit)*scalingFactor_profit-offsetResidualScaled-offsetPlotsScaled,'LineWidth', LineWidth, 'Color', colorProFit); + set(gca,'xdir','reverse'); + xlim([ppmEnd_lcm, ppmStart_lcm]); + ylim([-offsetResidualScaled-3*offsetPlotsScaled maxSpectrum+5*offsetPlotsScaled]) + xlabel('\delta (ppm)'); + ylabel('Signal (arb. u.)'); + set(gca,'ytick',[]); + + + if plot_dkntmn + legend('Spectrum',sprintf('LCModel baseline\ndkntmn=0.5'),sprintf('LCModel baseline\ndkntmn=0.25'),sprintf('LCModel baseline\ndkntmn=0.15'),'Input baseline','ProFit baseline','LCModel residual','ProFit residual') + else + legend('Spectrum','LCModel baseline','Input baseline','ProFit baseline','LCModel residual','ProFit residual') + end + + %arrows residual + yUpper = -offsetResidualScaled; + yLower = -offsetResidualScaled-offsetPlotsScaled; + xa = [ppmEnd_lcm ppmEnd_lcm]-0.05; + doublePointedArrowInside(xa,yUpper,yLower, arrowsColor); + + %arrows LCModel - Input baseline + yUpper = baselineInputOffset-offsetBaselineScaled; + yLower = baselineInputOffset-offsetBaselineScaled-offsetPlotsScaled; + xa = [ppmEnd_lcm ppmEnd_lcm]-0.05; + doublePointedArrowInside(xa,yUpper,yLower, arrowsColor); + + %arrows Input baseline - ProFit + yUpper = baselineInputOffset-offsetBaselineScaled+offsetPlotsScaled; + yLower = baselineInputOffset-offsetBaselineScaled; + xa = [ppmEnd_lcm ppmEnd_lcm]-0.1; + doublePointedArrowInside(xa,yUpper,yLower, arrowsColor); + + % text box with label "Plot offsets" + xa = [ppmEnd_lcm 0]+0.1; + ya = [spectrumInputOffset-offsetPlotsScaled*2 0]; + [xaf,yaf] = axescoord2figurecoord(xa,ya); + str = {'Plot','offsets'}; + annotation('textbox',[xaf(1) yaf(1)-0.02 0.1 0.1],'String',str,'FitBoxToText','On', ... + 'EdgeColor','none', 'FontWeight','bold','Color',arrowsColor); + + set(gcf,'Color','w') + + annotation('rectangle',[coordinates(1)+coordinates(3)*0.02 coordinates(2)+coordinates(4)*0.62 ... + .35./subplotGridX .4./subplotGridY],'FaceColor', 'w', 'FaceAlpha',0, 'Color',[0 0.4 0.1]) + + axes('Position',[coordinates(1)+coordinates(3)*0.15 coordinates(2)+coordinates(4)*0.81 ... + .2./subplotGridX .2./subplotGridY]) + box on; + plot(splines_ed_vec, splines_optim_model_vec,'Color',[0. 0.5 0.2]); + hold on + if ~isempty(splines_ed_vec(splines_optim_idx)) + xl = xline(splines_ed_vec(splines_optim_idx),'-.', {['ED: ' sprintf('%.f',splines_ed_vec(splines_optim_idx))],... + ['mAIC: ', sprintf('%.1f',splines_optim_model_vec(splines_optim_idx))]}, ... + 'HandleVisibility','off', 'LineWidth', 2); + xl.LabelVerticalAlignment = 'top'; + xl.LabelHorizontalAlignment = 'center'; + xl.FontSize = 9; + end + set(gca,'FontSize',10) + set(gca,'Xscale','log'); +% set(gca,'Color',backgroundInlayColor) + xlabel('Baseline ED / ppm'); + ylabel('mAIC'); + ylim([min(splines_optim_model_vec)*0.99 max(splines_optim_model_vec)*1.01]) + title('ProFit Baseline Smoothness'); + + annotation('textbox',[coordinates(1)+coordinates(3)*0.02-0.03 coordinates(2)+coordinates(4)*0.62 ... + .35./subplotGridX .4./subplotGridY],'String',subplotNames{indexSubplot},'FontSize', 16, 'FontWeight', 'bold','LineStyle','none') + if mod(indexParam,nGrid)==0 + print('-dtiff','-r600',[plotPath, 'Baseline_Fit_',num2str(indexParam),'.tif']) + savefig(gcf,[plotPath, 'Baseline_Fit_',num2str(indexParam),'.fig'], 'compact'); + end +end +end + +function doublePointedArrowInside(xa,yUpper,yLower, arrowsColor) + set(gcf,'Units','normalized'); + yaDown = [yUpper+1e-8 yUpper]; + yaLine = [yLower yUpper]; + yaUp = [yLower-1e-8 yLower]; + [xaf,yafLine] = axescoord2figurecoord(xa,yaLine); + line = annotation('line',xaf,yafLine); + [xaf,yafDown] = axescoord2figurecoord(xa,yaDown); + arDown = annotation('arrow',xaf,yafDown); + [xaf,yafUp] = axescoord2figurecoord(xa,yaUp); + arUp = annotation('arrow',xaf,yafUp); + %styling + line.Color = arrowsColor; + arDown.HeadStyle = 'vback2'; + arDown.HeadLength = 5; + arDown.HeadWidth = 7; + arDown.Color = arrowsColor; + arUp.HeadStyle = 'vback2'; + arUp.HeadLength = 5; + arUp.HeadWidth = 7; + arUp.Color = arrowsColor; +end diff --git a/createTestData/plotSimulationResults.m b/createTestData/plotSimulationResults.m index a577fe094c2eb22929ecafcaa155fd07502e4689..fde9ce3f5f8760969a910c63fd4c1f484c6c8de5 100644 --- a/createTestData/plotSimulationResults.m +++ b/createTestData/plotSimulationResults.m @@ -1,51 +1,73 @@ function plotSimulationResults() - %% path to the export of the spectra exportFolder = {'11 Simulations'}; pathNameExport = 'ProFit test data'; pathBaseExportFiles = pathToDataFolder(pathNameExport, exportFolder); +pathBaseExportFiles = pathBaseExportFiles(1:end-1); +pathBaseExportFiles = [pathBaseExportFiles ' - R3\']; dataExportPathBase = strcat(pathBaseExportFiles, exportFolder{1}, '\'); - -paramKeyword = 'conc'; truncSuffix = '_truncOn'; -if contains(paramKeyword,'conc') - scalingOn = true; -else - scalingOn = false; -end +scalingOn = true; + % name of metabolites in LCModel metabolitesLCModel = {'Asp', 'Cr_CH2', 'Cr', 'GABA', 'Gln', 'Glu', 'Glyc', 'GSH', 'Lac', 'mI', 'NAA_as', 'NAA_ac', 'NAAG', 'tCho_P', 'Scyllo', 'Tau', 'Leu'}; % name of metabolites in ProFit metabolitesProFit = {'Asp', 'Cr_CH2', 'Cr', 'GABA', 'Gln', 'Glu', 'Glyc', 'GSH', 'Lac', 'mI', 'NAA_as', 'NAA_ac', 'NAAG', 'tCho_P', 'Scyllo', 'Tau', 'Leu'}; -%% load simulated data -load([dataExportPathBase, 'concentrations_simulated_', paramKeyword, '.mat'], 'concentrationsRm', 'metabolites', 'metaboliteNames'); +% name of metabolites to display +metabolitesToDisplay = {'Asp', 'tCr(CH_2)', 'tCr(CH_3)', 'GABA', 'Gln', 'Glu', 'Gly', 'GSH', 'Lac', 'mI', 'NAA(CH_2)', 'NAA(CH_3)', 'NAAG', 'tCho+', 'sI', 'Tau', 'MM spectrum'}; +metabolitesLabels = {'Asp', 'tCr(CH2)', 'tCr(CH3)', 'GABA', 'Gln', 'Glu', 'Gly', 'GSH', 'Lac', 'mI', 'NAA(CH2)', 'NAA(CH3)', 'NAAG', 'tCho+', 'sI', 'Tau', 'MM spectrum'}; + +numberOfMet = length(metabolitesLabels); +indexesMainMet = zeros(1,numberOfMet); +mainMetabolites = { 'tCr(CH3)', 'tCr(CH2)', 'Glu', 'mI', 'NAA(CH2)', 'NAA(CH3)', 'tCho+'}; +for indexMet = 1:numberOfMet + indexesMainMet(indexMet) = ~isempty(find(strcmp(mainMetabolites,metabolitesLabels{indexMet}), 1)); +end +indexesMainMet = logical(indexesMainMet); + +numOfParameters = 4; +[metaboliteTable, indexTable] = setupTable(numberOfMet, numOfParameters, metabolitesLabels); + +sumAllMeanProFit = 0; +sumAllStdProFit = 0; +sumAllMeanProFitMain = 0; +sumAllStdProFitMain = 0; + +plotColors = {[0 0 1], [1 0 0], [0 0 0], [1 0.5 0.3], [0.49 0.18 0.56], [0.0 0.4 0.0]}; + +plotCorrelations = false; +plotPrecision = true; -%% load fitted data LCModel +figIds = []; +secondaryFigures =0; +%% +paramKeyword = 'pc0'; +% load simulated data +load([dataExportPathBase, 'concentrations_simulated_', paramKeyword, '.mat'], 'concentrationsRm', 'metabolites', 'metaboliteNames'); +% load fitted data LCModel load([dataExportPathBase, 'concentrations_', paramKeyword, truncSuffix, '.mat'], 'concentrations'); concentrationsLCModel = concentrations; - -%% load fitted data ProFit +% load fitted data ProFit load([dataExportPathBase, 'concentrations_', paramKeyword, truncSuffix, '_profit.mat'], 'concentrations', 'activeMetabolites'); concentrationsProFit = concentrations; - -plotCorrelations = true; -plotColors = {[0 0 1], [1 0 0]}; -% plotColors2 = {[0.0 0.4 0.0], [1 0.5 0.3]}; -plotColors2 = {[0.0 0.4 0.0], [0 0 0], [1 0.5 0.3]}; -offsetPlot = 0.2; -plotPrecision = false; -[allSimulMetConc, allLCModelMetConc, allProFitMetConc, allLCModelMetConcDev, allProFitMetConcDev, ~, figIdsCorr] = getConcentrations(... - metabolites, metabolitesLCModel, metabolitesProFit, ... +offsetPlot = -0.45; +indexTable = indexTable +2; +metaboliteTable{1,indexTable} = paramKeyword; +[allSimulMetConc, allLCModelMetConc, allProFitMetConc, allLCModelMetConcDev, allProFitMetConcDev, metaboliteTable, figIds, ~, ... + allMeanProFit, allStdProFit,allMeanProFitMain, allStdProFitMain] = getConcentrations(... + metabolites, metabolitesLCModel, metabolitesProFit, metabolitesToDisplay, metabolitesLabels, ... concentrationsRm, concentrationsLCModel, concentrationsProFit, activeMetabolites, ... scalingOn, plotCorrelations, dataExportPathBase, paramKeyword, truncSuffix, ... - plotPrecision, plotColors{1}, -offsetPlot, [], []); - -plotPrecision = false; + plotPrecision, plotColors{1}, offsetPlot, figIds, [], metaboliteTable, indexTable, indexesMainMet, secondaryFigures); +sumAllMeanProFit = sumAllMeanProFit + allMeanProFit; +sumAllStdProFit = sumAllStdProFit + allStdProFit; +sumAllMeanProFitMain = sumAllMeanProFitMain + allMeanProFitMain; +sumAllStdProFitMain = sumAllStdProFitMain + allStdProFitMain; %% -paramKeyword = 'conc3'; +paramKeyword = 'pc1'; % load simulated data load([dataExportPathBase, 'concentrations_simulated_', paramKeyword, '.mat'], 'concentrationsRm', 'metabolites', 'metaboliteNames'); % load fitted data LCModel @@ -54,17 +76,21 @@ concentrationsLCModel = concentrations; % load fitted data ProFit load([dataExportPathBase, 'concentrations_', paramKeyword, truncSuffix, '_profit.mat'], 'concentrations', 'activeMetabolites'); concentrationsProFit = concentrations; -[allSimulMetConc, allLCModelMetConc, allProFitMetConc, allLCModelMetConcDev, allProFitMetConcDev, ~, figIdsCorr] = getConcentrations(... - metabolites, metabolitesLCModel, metabolitesProFit, ... +offsetPlot = -0.15; +indexTable = indexTable +2; +metaboliteTable{1,indexTable} = paramKeyword; +[allSimulMetConc, allLCModelMetConc, allProFitMetConc, allLCModelMetConcDev, allProFitMetConcDev, metaboliteTable, figIds, ~,... + allMeanProFit, allStdProFit,allMeanProFitMain, allStdProFitMain] = getConcentrations(... + metabolites, metabolitesLCModel, metabolitesProFit, metabolitesToDisplay, metabolitesLabels, ... concentrationsRm, concentrationsLCModel, concentrationsProFit, activeMetabolites, ... scalingOn, plotCorrelations, dataExportPathBase, paramKeyword, truncSuffix, ... - plotPrecision, plotColors{1}, -offsetPlot, [], figIdsCorr); - - -plotCorrelations = false; -plotPrecision = true; + plotPrecision, plotColors{2}, offsetPlot, figIds, [], metaboliteTable, indexTable, indexesMainMet, secondaryFigures); +sumAllMeanProFit = sumAllMeanProFit + allMeanProFit; +sumAllStdProFit = sumAllStdProFit + allStdProFit; +sumAllMeanProFitMain = sumAllMeanProFitMain + allMeanProFitMain; +sumAllStdProFitMain = sumAllStdProFitMain + allStdProFitMain; %% -paramKeyword = 'pc0'; +paramKeyword = 'df2_global'; % load simulated data load([dataExportPathBase, 'concentrations_simulated_', paramKeyword, '.mat'], 'concentrationsRm', 'metabolites', 'metaboliteNames'); % load fitted data LCModel @@ -73,14 +99,21 @@ concentrationsLCModel = concentrations; % load fitted data ProFit load([dataExportPathBase, 'concentrations_', paramKeyword, truncSuffix, '_profit.mat'], 'concentrations', 'activeMetabolites'); concentrationsProFit = concentrations; -offsetPlot = -0.2; -[allSimulMetConc, allLCModelMetConc, allProFitMetConc, allLCModelMetConcDev, allProFitMetConcDev, figIds] = getConcentrations(... - metabolites, metabolitesLCModel, metabolitesProFit, ... +offsetPlot = 0.15; +indexTable = indexTable +2; +metaboliteTable{1,indexTable} = paramKeyword; +[allSimulMetConc, allLCModelMetConc, allProFitMetConc, allLCModelMetConcDev, allProFitMetConcDev, metaboliteTable, figIds, ~,... + allMeanProFit, allStdProFit,allMeanProFitMain, allStdProFitMain] = getConcentrations(... + metabolites, metabolitesLCModel, metabolitesProFit, metabolitesToDisplay, metabolitesLabels, ... concentrationsRm, concentrationsLCModel, concentrationsProFit, activeMetabolites, ... scalingOn, plotCorrelations, dataExportPathBase, paramKeyword, truncSuffix, ... - plotPrecision, plotColors{1}, offsetPlot, [], []); + plotPrecision, plotColors{3}, offsetPlot, figIds, [], metaboliteTable, indexTable, indexesMainMet, secondaryFigures); +sumAllMeanProFit = sumAllMeanProFit + allMeanProFit; +sumAllStdProFit = sumAllStdProFit + allStdProFit; +sumAllMeanProFitMain = sumAllMeanProFitMain + allMeanProFitMain; +sumAllStdProFitMain = sumAllStdProFitMain + allStdProFitMain; %% -paramKeyword = 'pc1'; +paramKeyword = 'df2_local'; % load simulated data load([dataExportPathBase, 'concentrations_simulated_', paramKeyword, '.mat'], 'concentrationsRm', 'metabolites', 'metaboliteNames'); % load fitted data LCModel @@ -89,12 +122,44 @@ concentrationsLCModel = concentrations; % load fitted data ProFit load([dataExportPathBase, 'concentrations_', paramKeyword, truncSuffix, '_profit.mat'], 'concentrations', 'activeMetabolites'); concentrationsProFit = concentrations; -offsetPlot = 0; -[allSimulMetConc, allLCModelMetConc, allProFitMetConc, allLCModelMetConcDev, allProFitMetConcDev, figIds] = getConcentrations(... - metabolites, metabolitesLCModel, metabolitesProFit, ... +offsetPlot = 0.45; +indexTable = indexTable +2; +metaboliteTable{1,indexTable} = paramKeyword; +[allSimulMetConc, allLCModelMetConc, allProFitMetConc, allLCModelMetConcDev, allProFitMetConcDev, metaboliteTable, figIds, ~,... + allMeanProFit, allStdProFit,allMeanProFitMain, allStdProFitMain] = getConcentrations(... + metabolites, metabolitesLCModel, metabolitesProFit, metabolitesToDisplay, metabolitesLabels, ... concentrationsRm, concentrationsLCModel, concentrationsProFit, activeMetabolites, ... scalingOn, plotCorrelations, dataExportPathBase, paramKeyword, truncSuffix, ... - plotPrecision, plotColors{2}, offsetPlot, figIds, []); + plotPrecision, plotColors{4}, offsetPlot, figIds, [], metaboliteTable, indexTable, indexesMainMet, secondaryFigures); +sumAllMeanProFit = sumAllMeanProFit + allMeanProFit; +sumAllStdProFit = sumAllStdProFit + allStdProFit; +sumAllMeanProFitMain = sumAllMeanProFitMain + allMeanProFitMain; +sumAllStdProFitMain = sumAllStdProFitMain + allStdProFitMain; +%% ----------------------------------------------------------------------------------------------------------- +axes(figIds{1}) +str = {'$$\varphi_0$$', '$$\varphi_1$$', '$$\omega_{global}$$', '{\boldmath$\omega_{local}$}'}; +xOffset = 0.65; +yOffsetRect = 0.085; %0.075; -for two subfigures +for indexSim = 1:4 + yOffset = 0.84;% 4 subfigs%0.80; - Two figs placed lower%0.86 -Two figs + annotation('textbox',[xOffset yOffset 0.1 0.1],'String',str{indexSim},'FitBoxToText','On', ... + 'EdgeColor','none', 'FontSize', 12, 'Interpreter','latex','Color',plotColors{indexSim}) + annotation('rectangle',[xOffset-0.012 yOffset+yOffsetRect 0.01 0.01],'EdgeColor','none', 'FaceColor',plotColors{indexSim}) + yOffset = 0.612;% 4 subfigs%0.37; - Two figs placed lower%0.37 -Two figs + annotation('textbox',[xOffset yOffset 0.1 0.1],'String',str{indexSim},'FitBoxToText','On', ... + 'EdgeColor','none', 'FontSize', 12, 'FontWeight','bold', 'Interpreter','latex','Color',plotColors{indexSim}) + annotation('rectangle',[xOffset-0.012 yOffset+yOffsetRect 0.01 0.01],'EdgeColor','none', 'FaceColor',plotColors{indexSim}) + xOffset = xOffset + 0.004*length(str{indexSim}); +end + +% save Table +xlswrite([dataExportPathBase, 'SimulationsTable1.xlsx'],metaboliteTable); +numOfParameters2 = 5; +[metaboliteTable, indexTable] = setupTable(numberOfMet, numOfParameters2, metabolitesLabels); + +% figIds = []; +secondaryFigures = 2; +%% ----------------------------------------------------------------------------------------------------------- %% paramKeyword = 'gauss'; % load simulated data @@ -105,14 +170,17 @@ concentrationsLCModel = concentrations; % load fitted data ProFit load([dataExportPathBase, 'concentrations_', paramKeyword, truncSuffix, '_profit.mat'], 'concentrations', 'activeMetabolites'); concentrationsProFit = concentrations; -offsetPlot = 0.2; -[allSimulMetConc, allLCModelMetConc, allProFitMetConc, allLCModelMetConcDev, allProFitMetConcDev, figIds] = getConcentrations(... - metabolites, metabolitesLCModel, metabolitesProFit, ... +offsetPlot = -0.45; +indexTable = indexTable +2; +metaboliteTable{1,indexTable} = paramKeyword; +[allSimulMetConc, allLCModelMetConc, allProFitMetConc, allLCModelMetConcDev, allProFitMetConcDev, metaboliteTable, figIds, ~,... + allMeanProFit, allStdProFit,allMeanProFitMain, allStdProFitMain] = getConcentrations(... + metabolites, metabolitesLCModel, metabolitesProFit, metabolitesToDisplay, metabolitesLabels, ... concentrationsRm, concentrationsLCModel, concentrationsProFit, activeMetabolites, ... scalingOn, plotCorrelations, dataExportPathBase, paramKeyword, truncSuffix, ... - plotPrecision, plotColors2{1}, offsetPlot, figIds, []); + plotPrecision, plotColors{1}, offsetPlot, figIds, [], metaboliteTable, indexTable, indexesMainMet, secondaryFigures); %% -paramKeyword = 'df2'; +paramKeyword = 'em'; % load simulated data load([dataExportPathBase, 'concentrations_simulated_', paramKeyword, '.mat'], 'concentrationsRm', 'metabolites', 'metaboliteNames'); % load fitted data LCModel @@ -121,12 +189,19 @@ concentrationsLCModel = concentrations; % load fitted data ProFit load([dataExportPathBase, 'concentrations_', paramKeyword, truncSuffix, '_profit.mat'], 'concentrations', 'activeMetabolites'); concentrationsProFit = concentrations; -offsetPlot = 0.4; -[allSimulMetConc, allLCModelMetConc, allProFitMetConc, allLCModelMetConcDev, allProFitMetConcDev, figIds] = getConcentrations(... - metabolites, metabolitesLCModel, metabolitesProFit, ... +offsetPlot = -0.15; +indexTable = indexTable +2; +metaboliteTable{1,indexTable} = paramKeyword; +[allSimulMetConc, allLCModelMetConc, allProFitMetConc, allLCModelMetConcDev, allProFitMetConcDev, metaboliteTable, figIds, ~,... + allMeanProFit, allStdProFit,allMeanProFitMain, allStdProFitMain] = getConcentrations(... + metabolites, metabolitesLCModel, metabolitesProFit, metabolitesToDisplay, metabolitesLabels, ... concentrationsRm, concentrationsLCModel, concentrationsProFit, activeMetabolites, ... scalingOn, plotCorrelations, dataExportPathBase, paramKeyword, truncSuffix, ... - plotPrecision, plotColors2{2}, offsetPlot, figIds, []); + plotPrecision, plotColors{2}, offsetPlot, figIds, [], metaboliteTable, indexTable, indexesMainMet, secondaryFigures); +sumAllMeanProFit = sumAllMeanProFit + allMeanProFit; +sumAllStdProFit = sumAllStdProFit + allStdProFit; +sumAllMeanProFitMain = sumAllMeanProFitMain + allMeanProFitMain; +sumAllStdProFitMain = sumAllStdProFitMain + allStdProFitMain; %% paramKeyword = 'noise'; % load simulated data @@ -137,139 +212,367 @@ concentrationsLCModel = concentrations; % load fitted data ProFit load([dataExportPathBase, 'concentrations_', paramKeyword, truncSuffix, '_profit.mat'], 'concentrations', 'activeMetabolites'); concentrationsProFit = concentrations; -offsetPlot = 0.6; -[allSimulMetConc, allLCModelMetConc, allProFitMetConc, allLCModelMetConcDev, allProFitMetConcDev, figIds] = getConcentrations(... - metabolites, metabolitesLCModel, metabolitesProFit, ... +offsetPlot = 0.15; +indexTable = indexTable +2; +metaboliteTable{1,indexTable} = paramKeyword; +[allSimulMetConc, allLCModelMetConc, allProFitMetConc, allLCModelMetConcDev, allProFitMetConcDev, metaboliteTable, figIds, ~,... + allMeanProFit, allStdProFit,allMeanProFitMain, allStdProFitMain] = getConcentrations(... + metabolites, metabolitesLCModel, metabolitesProFit, metabolitesToDisplay, metabolitesLabels, ... + concentrationsRm, concentrationsLCModel, concentrationsProFit, activeMetabolites, ... + scalingOn, plotCorrelations, dataExportPathBase, paramKeyword, truncSuffix, ... + plotPrecision, plotColors{3}, offsetPlot, figIds, [], metaboliteTable, indexTable, indexesMainMet, secondaryFigures); +sumAllMeanProFit = sumAllMeanProFit + allMeanProFit; +sumAllStdProFit = sumAllStdProFit + allStdProFit; +sumAllMeanProFitMain = sumAllMeanProFitMain + allMeanProFitMain; +sumAllStdProFitMain = sumAllStdProFitMain + allStdProFitMain; +%% +paramKeyword = 'baseline'; +% load simulated data +load([dataExportPathBase, 'concentrations_simulated_', paramKeyword, '.mat'], 'concentrationsRm', 'metabolites', 'metaboliteNames'); +% load fitted data LCModel +load([dataExportPathBase, 'concentrations_', paramKeyword, truncSuffix, '.mat'], 'concentrations'); +concentrationsLCModel = concentrations; +% load fitted data ProFit +load([dataExportPathBase, 'concentrations_', paramKeyword, truncSuffix, '_profit.mat'], 'concentrations', 'activeMetabolites'); +concentrationsProFit = concentrations; +offsetPlot = 0.45; +indexTable = indexTable +2; +metaboliteTable{1,indexTable} = paramKeyword; +[allSimulMetConc, allLCModelMetConc, allProFitMetConc, allLCModelMetConcDev, allProFitMetConcDev, metaboliteTable, figIds, ~,... + allMeanProFit, allStdProFit,allMeanProFitMain, allStdProFitMain] = getConcentrations(... + metabolites, metabolitesLCModel, metabolitesProFit, metabolitesToDisplay, metabolitesLabels, ... + concentrationsRm, concentrationsLCModel, concentrationsProFit, activeMetabolites, ... + scalingOn, plotCorrelations, dataExportPathBase, paramKeyword, truncSuffix, ... + plotPrecision, plotColors{4}, offsetPlot, figIds, [], metaboliteTable, indexTable, indexesMainMet, secondaryFigures); +sumAllMeanProFit = sumAllMeanProFit + allMeanProFit; +sumAllStdProFit = sumAllStdProFit + allStdProFit; +sumAllMeanProFitMain = sumAllMeanProFitMain + allMeanProFitMain; +sumAllStdProFitMain = sumAllStdProFitMain + allStdProFitMain; + +%% +paramKeyword = 'conc'; +% load simulated data +load([dataExportPathBase, 'concentrations_simulated_', paramKeyword, '.mat'], 'concentrationsRm', 'metabolites', 'metaboliteNames'); +% load fitted data LCModel +load([dataExportPathBase, 'concentrations_', paramKeyword, truncSuffix, '.mat'], 'concentrations'); +concentrationsLCModel = concentrations; +% load fitted data ProFit +load([dataExportPathBase, 'concentrations_', paramKeyword, truncSuffix, '_profit.mat'], 'concentrations', 'activeMetabolites'); +concentrationsProFit = concentrations; + +plotCorrelations = true; +offsetPlot = 0.; +plotPrecision = false; +indexTable = indexTable +2; +metaboliteTable{1,indexTable} = paramKeyword; +[allSimulMetConc, allLCModelMetConc, allProFitMetConc, allLCModelMetConcDev, allProFitMetConcDev, metaboliteTable, ~, figIdsCorr, ... + allMeanProFit, allStdProFit,allMeanProFitMain, allStdProFitMain] = getConcentrations(... + metabolites, metabolitesLCModel, metabolitesProFit, metabolitesToDisplay, metabolitesLabels, ... concentrationsRm, concentrationsLCModel, concentrationsProFit, activeMetabolites, ... scalingOn, plotCorrelations, dataExportPathBase, paramKeyword, truncSuffix, ... - plotPrecision, plotColors2{3}, offsetPlot, figIds, []); + plotPrecision, plotColors{1}, -offsetPlot, [], [], metaboliteTable, indexTable, indexesMainMet, secondaryFigures); +sumAllMeanProFit = sumAllMeanProFit + allMeanProFit; +sumAllStdProFit = sumAllStdProFit + allStdProFit; +sumAllMeanProFitMain = sumAllMeanProFitMain + allMeanProFitMain; +sumAllStdProFitMain = sumAllStdProFitMain + allStdProFitMain; -txt = 'ProFit: blue: $$\varphi_0$$, red:$$\varphi_1$$, green:$$\nu_g$$, black:$$\omega_k$$'; -title(txt, 'Interpreter','latex','FontSize', 20) +%% +sumAllMeanProFit = sumAllMeanProFit / (numOfParameters + numOfParameters2) +sumAllStdProFit = sumAllStdProFit / (numOfParameters + numOfParameters2) +sumAllMeanProFitMain = sumAllMeanProFitMain / (numOfParameters + numOfParameters2) +sumAllStdProFitMain = sumAllStdProFitMain / (numOfParameters + numOfParameters2) +%% +%% ----------------------------------------------------------------------------------------------------------- +axes(figIds{1}) +str = {'$$\nu_g$$', '{\boldmath$\nu_{e}$}', '{\boldmath$noise$}', '{\boldmath$baseline$}'}; +stringLenghts = {13, 13, 19, 27}; +xOffset = 0.63; +yOffsetRect = 0.085; %0.075; -for two subfigures +for indexSim = 1:4 + yOffset = 0.392;% 4 subfigs%0.80; - Two figs placed lower%0.86 -Two figs + annotation('textbox',[xOffset yOffset 0.1 0.1],'String',str{indexSim},'FitBoxToText','On', ... + 'EdgeColor','none', 'FontSize', 12, 'Interpreter','latex','Color',plotColors{indexSim}) + annotation('rectangle',[xOffset-0.012 yOffset+yOffsetRect 0.01 0.01],'EdgeColor','none', 'FaceColor',plotColors{indexSim}) + yOffset = 0.172;% 4 subfigs%0.37; - Two figs placed lower%0.37 -Two figs + annotation('textbox',[xOffset yOffset 0.1 0.1],'String',str{indexSim},'FitBoxToText','On', ... + 'EdgeColor','none', 'FontSize', 12, 'FontWeight','bold', 'Interpreter','latex','Color',plotColors{indexSim}) + annotation('rectangle',[xOffset-0.012 yOffset+yOffsetRect 0.01 0.01],'EdgeColor','none', 'FaceColor',plotColors{indexSim}) + xOffset = xOffset + 0.004*stringLenghts{indexSim}; end -function [allSimulMetConc, allLCModelMetConc, allProFitMetConc, allLCModelMetConcDev, allProFitMetConcDev, figIds, figIdsCorr] = ... - getConcentrations(metabolites, metabolitesLCModel, metabolitesProFit, ... - concentrationsRm, concentrationsLCModel, concentrationsProFit, activeMetabolites, ... - scalingOn, plotCorrelations, dataExportPathBase, paramKeyword, truncSuffix, ... - plotPrecision, plotColors, offsetPlot, figIds, figIdsCorr) - - - if isempty(figIdsCorr) - emptyFigureIdsCorr = true; - figIdsCorr = cell(1,length(metabolites)); - else - emptyFigureIdsCorr = false; +xlswrite([dataExportPathBase, 'SimulationsTable2.xlsx'],metaboliteTable); +end + +%% get metabolite concentrations for a given paramKeyword and create the requested plots +function [allSimulMetConc, allLCModelMetConc, allProFitMetConc, allLCModelMetConcDev, allProFitMetConcDev, metaboliteTable, figIds, figIdsCorr,... + allMeanProFit, allStdProFit,allMeanProFitMain, allStdProFitMain] = ... + getConcentrations(metabolites, metabolitesLCModel, metabolitesProFit, metabolitesToDisplay, metabolitesLabels, ... + concentrationsRm, concentrationsLCModel, concentrationsProFit, activeMetabolites, ... + scalingOn, plotCorrelations, dataExportPathBase, paramKeyword, truncSuffix, ... + plotPrecision, plotColors, offsetPlot, figIds, figIdsCorr, metaboliteTable, indexTable, indexesMainMet, secondaryFigures) +numberOfMet = length(metabolites); + +[allSimulMetConc, allLCModelMetConc, allProFitMetConc, allLCModelMetConcDev, allProFitMetConcDev] = ... + reorganizeMetConcentrationsToMatrices(metabolites, metabolitesLCModel, metabolitesProFit, ... + concentrationsRm, concentrationsLCModel, concentrationsProFit, activeMetabolites, scalingOn); +if plotCorrelations + figIdsCorr = plotCorrelationFigs(concentrationsRm, allLCModelMetConc, allProFitMetConc, metabolitesToDisplay, numberOfMet, ... + dataExportPathBase, paramKeyword, truncSuffix, figIdsCorr); +end +if plotPrecision + figIds = plotPrecisionFigs(figIds, numberOfMet, offsetPlot, secondaryFigures, plotColors, ... + allLCModelMetConcDev, allProFitMetConcDev, metabolitesLabels); +end + +display([paramKeyword, ' NANs:', num2str(sum(isnan(allLCModelMetConcDev)))]); +meanConcDevLCModel = mean(allLCModelMetConcDev,'omitnan'); +stdConcDevLCModel = std(allLCModelMetConcDev,'omitnan'); +display([paramKeyword, ' NANs ProFit:', num2str(sum(isnan(allProFitMetConcDev)))]); +meanConcDevProFit = mean(allProFitMetConcDev,'omitnan'); +stdConcDevProFit = std(allProFitMetConcDev,'omitnan'); + +allMeanLCModel = mean(abs(meanConcDevLCModel)); +allStdLCModel = mean(abs(stdConcDevLCModel)); +allMeanProFit = mean(abs(meanConcDevProFit)); +allStdProFit = mean(abs(stdConcDevProFit)); + +allMeanLCModelMain = mean(abs(meanConcDevLCModel(indexesMainMet))); +allStdLCModelMain = mean(abs(stdConcDevLCModel(indexesMainMet))); +allMeanProFitMain = mean(abs(meanConcDevProFit(indexesMainMet))); +allStdProFitMain = mean(abs(stdConcDevProFit(indexesMainMet))); + +plusMinusSign = char(177); +metaboliteTable{2,indexTable} = 'ProFit'; +metaboliteTable{2,indexTable+1} = 'LCModel'; +for indexMet = 1:numberOfMet + metaboliteTable{indexMet+2,indexTable} = [num2str(meanConcDevProFit(indexMet),'%.1f'), plusMinusSign, num2str(stdConcDevProFit(indexMet),'%.1f')]; + metaboliteTable{indexMet+2,indexTable+1} = [num2str(meanConcDevLCModel(indexMet),'%.1f'), plusMinusSign, num2str(stdConcDevLCModel(indexMet),'%.1f')]; +end + +metaboliteTable{numberOfMet+3,indexTable} = [num2str(allMeanProFit,'%.1f'), plusMinusSign, num2str(allStdProFit,'%.1f')]; +metaboliteTable{numberOfMet+3,indexTable+1} = [num2str(allMeanLCModel,'%.1f'), plusMinusSign, num2str(allStdLCModel,'%.1f')]; + +metaboliteTable{numberOfMet+4,indexTable} = [num2str(allMeanProFitMain,'%.1f'), plusMinusSign, num2str(allStdProFitMain,'%.1f')]; +metaboliteTable{numberOfMet+4,indexTable+1} = [num2str(allMeanLCModelMain,'%.1f'), plusMinusSign, num2str(allStdLCModelMain,'%.1f')]; +end + +%% reorganize the fitted concentrations to 2D tables +function [allSimulMetConc, allLCModelMetConc, allProFitMetConc, allLCModelMetConcDev, allProFitMetConcDev] = ... + reorganizeMetConcentrationsToMatrices(metabolites, metabolitesLCModel, metabolitesProFit, ... + concentrationsRm, concentrationsLCModel, concentrationsProFit, activeMetabolites, scalingOn) + +iterationProFit = 4; +numberOfMet = length(metabolites); +allSimulMetConc = concentrationsRm; +allLCModelMetConc = zeros(size(allSimulMetConc)); +allProFitMetConc = zeros(size(allSimulMetConc)); +allLCModelMetConcDev = zeros(size(allSimulMetConc)); +allProFitMetConcDev = zeros(size(allSimulMetConc)); +for indexMetabolite = 1:numberOfMet + simulatedMetConc = concentrationsRm(:, indexMetabolite); + indexMetSim = find(strcmp(metabolites,'tCr(CH3)')); %'MMB' + fittedMetConcLCModel = zeros(size(simulatedMetConc)); + for indexFit = 1:length(concentrationsLCModel) + currentConcentrationsLCModel = concentrationsLCModel{indexFit}; + indexMetLCModel = find(strcmp(currentConcentrationsLCModel(1,:),'Cr')); %'Leu' + RefConc = currentConcentrationsLCModel{2,indexMetLCModel}; + RefConcSim = concentrationsRm(indexFit,indexMetSim); + if scalingOn + scaling = RefConcSim/RefConc; + else + scaling = 1; + end + indexMetLCModel = find(strcmp(currentConcentrationsLCModel(1,:),metabolitesLCModel(indexMetabolite))); + fittedMetConcLCModel(indexFit) = currentConcentrationsLCModel{2,indexMetLCModel}*scaling; + end + fittedMetConcProFit = zeros(size(simulatedMetConc)); + for indexFit = 1:length(concentrationsProFit) + currentConcentrationsProFit = concentrationsProFit{indexFit}{iterationProFit}; + indexMetProFit = find(strcmp(activeMetabolites{iterationProFit},'Cr')); %'Leu' + RefConc = currentConcentrationsProFit(indexMetProFit); + RefConcSim = concentrationsRm(indexFit,indexMetSim); + if scalingOn + scaling = RefConcSim/RefConc; + else + scaling = 1; + end + indexMetProFit = find(strcmp(activeMetabolites{iterationProFit},metabolitesProFit(indexMetabolite))); + fittedMetConcProFit(indexFit) = currentConcentrationsProFit(indexMetProFit)*scaling; + end + if strcmp(metabolitesProFit(indexMetabolite),'Leu') + fittedMetConcProFit = fittedMetConcProFit *1e8; end - allSimulMetConc = concentrationsRm; - allLCModelMetConc = zeros(size(allSimulMetConc)); - allProFitMetConc = zeros(size(allSimulMetConc)); - allLCModelMetConcDev = zeros(size(allSimulMetConc)); - allProFitMetConcDev = zeros(size(allSimulMetConc)); - for indexMetabolite = 1:length(metabolites) - simulatedMetConc = concentrationsRm(:, indexMetabolite); - indexMetSim = find(strcmp(metabolites,'tCr(CH3)')); %'MMB' - fittedMetConcLCModel = zeros(size(simulatedMetConc)); - for indexFit = 1:length(concentrationsLCModel) - currentConcentrationsLCModel = concentrationsLCModel{indexFit}; - indexMetLCModel = find(strcmp(currentConcentrationsLCModel(1,:),'Cr')); %'Leu' - MMBConc = currentConcentrationsLCModel{2,indexMetLCModel}; - MMBConcSim = concentrationsRm(indexFit,indexMetSim); - if scalingOn - scaling = MMBConcSim/MMBConc; - else - scaling = 1; - end - indexMetLCModel = find(strcmp(currentConcentrationsLCModel(1,:),metabolitesLCModel(indexMetabolite))); - fittedMetConcLCModel(indexFit) = currentConcentrationsLCModel{2,indexMetLCModel}*scaling; + allLCModelMetConc(:, indexMetabolite) = fittedMetConcLCModel; + allProFitMetConc(:, indexMetabolite) = fittedMetConcProFit; + allLCModelMetConcDev(:, indexMetabolite) = (simulatedMetConc-fittedMetConcLCModel)./simulatedMetConc.*100; + allProFitMetConcDev(:, indexMetabolite) = (simulatedMetConc-fittedMetConcProFit)./simulatedMetConc.*100; +end +end + +%% plot Correlation plots between the fitted ProFit, LCModel concentrations and the true simulated concentrations +function figIdsCorr = plotCorrelationFigs(concentrationsRm, allLCModelMetConc, allProFitMetConc,... + metabolitesToDisplay, numberOfMet, dataExportPathBase, paramKeyword, truncSuffix, figIdsCorr) + +if isempty(figIdsCorr) + emptyFigureIdsCorr = true; + figIdsCorr = cell(1,numberOfMet); +else + emptyFigureIdsCorr = false; +end + +% Main Figure = 12 subplots +figureMainRows = 4; +figureMainCols = 3; +metabolitesFigureMain = {'NAA(CH_2)', 'tCr(CH_2)', 'tCho+','Gly','Glu','Gln',... + 'Asp', 'GABA', 'Lac', 'GSH', 'NAAG', 'MM spectrum'}; +figID_Main = figure(); +mainFigureRunningIndex = 0; +% Supporting Figure = 5 subplots +figureSupportingRows = 3; +figureSupportingCols = 4; +metabolitesFigureSupporting = {'tCr(CH_3)', 'mI', 'sI', 'NAA(CH_3)','Tau'}; +figID_Supporting = figure(); +supportingFigureRunningIndex = 0; + +colorOriginal = [0 0 0]; +colorProFit = [0.49 0.18 0.56]; +colorLCModel = [0.85 0.33 0.1]; + +for indexMetabolite = 1:numberOfMet + simulatedMetConc = concentrationsRm(:, indexMetabolite); + fittedMetConcLCModel = allLCModelMetConc(:, indexMetabolite); + fittedMetConcProFit = allProFitMetConc(:, indexMetabolite); +% if emptyFigureIdsCorr +% figIdsCorr{indexMetabolite} = figure; +% end +% figure(figIdsCorr{indexMetabolite}); + if sum(contains(metabolitesFigureMain, metabolitesToDisplay{indexMetabolite})) + figure(figID_Main); + mainFigureRunningIndex = mainFigureRunningIndex + 1; + subplot(figureMainRows, figureMainCols, mainFigureRunningIndex); + if mod(mainFigureRunningIndex,figureMainCols)== 1 + plotYLabel = true; + else + plotYLabel = false; + end + if round((mainFigureRunningIndex+1)/figureMainCols)== figureMainRows + plotXLabel = true; + else + plotXLabel = false; end - fittedMetConcProFit = zeros(size(simulatedMetConc)); - for indexFit = 1:length(concentrationsProFit) - currentConcentrationsProFit = concentrationsProFit{indexFit}{3}; - indexMetProFit = find(strcmp(activeMetabolites{3},'Cr')); %'Leu' - MMBConc = currentConcentrationsProFit(indexMetProFit); - MMBConcSim = concentrationsRm(indexFit,indexMetSim); -% if scalingOn -% scaling = MMBConcSim/MMBConc; -% else - scaling = 1; -% end - indexMetProFit = find(strcmp(activeMetabolites{3},metabolitesProFit(indexMetabolite))); - fittedMetConcProFit(indexFit) = currentConcentrationsProFit(indexMetProFit)*scaling; + elseif sum(contains(metabolitesFigureSupporting, metabolitesToDisplay{indexMetabolite})) + figure(figID_Supporting); + supportingFigureRunningIndex = supportingFigureRunningIndex + 2; + if round((supportingFigureRunningIndex+1)/figureSupportingCols)== figureSupportingRows % offset plot + supportingFigureRunningIndex = supportingFigureRunningIndex + 1; end - if strcmp(metabolitesProFit(indexMetabolite),'Leu') - fittedMetConcProFit = fittedMetConcProFit *1e8; + subplot(figureSupportingRows, figureSupportingCols, supportingFigureRunningIndex-1:supportingFigureRunningIndex) + if mod(supportingFigureRunningIndex-1,figureSupportingCols)<= 2 + plotYLabel = true; + else + plotYLabel = false; end - allLCModelMetConc(:, indexMetabolite) = fittedMetConcLCModel; - allProFitMetConc(:, indexMetabolite) = fittedMetConcProFit; - allLCModelMetConcDev(:, indexMetabolite) = (simulatedMetConc-fittedMetConcLCModel)./simulatedMetConc.*100; - allProFitMetConcDev(:, indexMetabolite) = (simulatedMetConc-fittedMetConcProFit)./simulatedMetConc.*100; - if plotCorrelations - if emptyFigureIdsCorr - figIdsCorr{indexMetabolite} = figure; - end - figure(figIdsCorr{indexMetabolite}); - hold on - scatter(simulatedMetConc, fittedMetConcLCModel); - scatter(simulatedMetConc, fittedMetConcProFit, 'x'); % ### - -% if ~emptyFigureIdsCorr % ### delete this if later - plot(simulatedMetConc,simulatedMetConc); -% end - title(metabolites(indexMetabolite)) - xlabel('Simulated concentrations [mmol/kg]'); - ylabel('Fitted concentrations [mmol/kg]'); - legend('LCModel concentrations', 'ProFit concentrations', 'Identity Line', 'Location', 'Northwest') %## - legend('LCModel concentrations', 'Identity Line', 'Location', 'Northwest') -% legend('\nu_e = all identical T_2', '\nu_e = metabolite specific T_2', 'Identity Line', 'Location', 'Northwest') - xl = xlim; - if xl(2) > max(simulatedMetConc) - xl(2) = max(simulatedMetConc); - end - xlim(xl); - - pathName = [dataExportPathBase, paramKeyword, '/correlations/']; - if ~exist(pathName, 'dir') - mkdir(pathName); - end - fileName = [metabolites{indexMetabolite}, '_', paramKeyword, truncSuffix]; - saveas(figIdsCorr{indexMetabolite}, [pathName, fileName, '.tif']); - savefig(figIdsCorr{indexMetabolite}, [pathName,fileName, '.fig'],'compact'); -% BlandAltman(simulatedMetConc, fittedMetConcLCModel); -% title(metabolites(indexMetabolite)); -% BlandAltman(simulatedMetConc, fittedMetConcProFit); -% title(metabolites(indexMetabolite)); + if round((supportingFigureRunningIndex+1)/figureSupportingCols)>= figureSupportingRows-1 + plotXLabel = true; + else + plotXLabel = false; end + else + warning('Metabolite not associated with either main or supporting figure: ', metabolitesToDisplay{indexMetabolite}); + figure(); + plotYLabel = true; + plotXLabel = true; end - allLCModelMetConcDev = allLCModelMetConcDev - median(allLCModelMetConcDev,1); - allProFitMetConcDev = allProFitMetConcDev - median(allProFitMetConcDev,1); - if plotPrecision - yLimValue = 100; - numberOfMet = length(metabolites); - if isempty(figIds) - figIds{1} = figure; - figIds{2} = figure; - end - positionsTicks = [2.2:1.5:1.5*numberOfMet+1.5]; - positions = positionsTicks + offsetPlot; - figure(figIds{1}) - hold on - boxPlotLCModel = boxplot(allLCModelMetConcDev, metabolites,'colors',plotColors,'symbol','+', 'positions',positions,'width',0.18); - xtickangle(45) - title('LCModel') - ylim([-yLimValue,yLimValue]); - ylabel('Concentration change [%]') - set(boxPlotLCModel(:,:),'linewidth',1); - - %% - figure(figIds{2}) - hold on - boxPlotLCModel = boxplot(allProFitMetConcDev, metabolites,'colors',plotColors,'symbol','+', 'positions',positions,'width',0.18); - xtickangle(45) - title('ProFit') - ylim([-yLimValue,yLimValue]); - ylabel('Concentration change [%]') - set(boxPlotLCModel(:,:),'linewidth',1); + if strcmp(metabolitesToDisplay(indexMetabolite),'MM spectrum') + simulatedMetConc = simulatedMetConc *1e-7; + fittedMetConcLCModel = fittedMetConcLCModel *1e-7; + fittedMetConcProFit = fittedMetConcProFit *1e-7; + end + hold on + scatter(simulatedMetConc, fittedMetConcLCModel, 15, 'MarkerEdgeColor', colorLCModel); + scatter(simulatedMetConc, fittedMetConcProFit, 15, 'x', 'MarkerEdgeColor', colorProFit); + offSetEnds = max(simulatedMetConc)*0.05; + identityLine = min(simulatedMetConc)-offSetEnds:0.01:max(simulatedMetConc)+offSetEnds; + plot(identityLine,identityLine,'color',colorOriginal); + title(metabolitesToDisplay(indexMetabolite)) + + if plotXLabel + xlabel('$c_{k}^{simulated} \,\, (mmol/kg)$', 'Interpreter', 'latex','FontSize', 10) + end + if plotYLabel + ylabel('$c_k^{fitted} \,\, (mmol/kg)$', 'Interpreter', 'latex','FontSize', 10) + end + legend('$LCModel \,\, c_k^{fitted}$', '$ProFit \,\, c_k^{fitted}$', '$Identity \, Line$', 'Location', 'best', 'Interpreter', 'latex', 'FontSize', 8) + + + xlim([min(identityLine),max(identityLine)]) + ylim([min(identityLine),max(identityLine)]) + +% pathName = [dataExportPathBase, paramKeyword, '/correlations/']; +% if ~exist(pathName, 'dir') +% mkdir(pathName); +% end +% fileName = [metabolitesToDisplay{indexMetabolite}, '_', paramKeyword, truncSuffix]; +% saveas(figIdsCorr{indexMetabolite}, [pathName, fileName, '.tif']); +% savefig(figIdsCorr{indexMetabolite}, [pathName,fileName, '.fig'],'compact'); +end +end + +%% plot Precision plots with boxplots showing percentages +function figIds = plotPrecisionFigs(figIds, numberOfMet, offsetPlot, secondaryFigures, plotColors, ... + allLCModelMetConcDev, allProFitMetConcDev, metabolitesLabels) + + yLimValue = 100; + if isempty(figIds) + % figure('Position',[612,509,1132,469],'OuterPosition',[604,501,1148,562], 'Units','pixels') + % figure('Position',[100,275,890,680],'Units','pixels') + % figIds{1} = subplot(2,1,2); + % figIds{2} = subplot(2,1,1);%, 'Position', [0.58,0.16,0.35,0.76], 'Position', [0.13,0.16,0.35,0.76] + % + figure('Position',[-908,-589,890,1400],'Units','pixels') + figIds{1} = subplot(4,1,2); + figIds{2} = subplot(4,1,1); + figIds{3} = subplot(4,1,4); + figIds{4} = subplot(4,1,3); end + positionsTicks = [2.2:1.5:1.5*numberOfMet+1.5]; + positions = positionsTicks + offsetPlot; + axes(figIds{1 + secondaryFigures}) + hold on + boxPlotLCModel = boxplot(allLCModelMetConcDev, metabolitesLabels,'colors',plotColors,'symbol','+', 'positions',positions,'width',0.18); + xticks(positionsTicks) + xticklabels(metabolitesLabels) + xtickangle(45) + xlim([1 27.5]) + title('LCModel') + ylim([-yLimValue,yLimValue]); + xlim([positionsTicks(1)-1, positionsTicks(end)+1]) + set(gca, 'FontSize', 11) + ylabel('$Concentration\,\,change\,\,c^\%_{k}\,(\%)$', 'FontSize', 13, 'Interpreter', 'latex') + set(boxPlotLCModel(:,:),'linewidth',1); + yline(0,':', 'Color',[0.5 0.5 0.5]); + %% + axes(figIds{2 + secondaryFigures}) + hold on + boxPlotProFit = boxplot(allProFitMetConcDev, metabolitesLabels,'colors',plotColors,'symbol','+', 'positions',positions,'width',0.18); + xticks(positionsTicks) + xticklabels(metabolitesLabels) + xtickangle(45) + xlim([1 27.5]) + title('ProFit') + ylim([-yLimValue,yLimValue]); + set(gca, 'FontSize', 11) + ylabel('$Concentration\,\,change\,\,c^\%_{k}\,(\%)$', 'FontSize', 13, 'Interpreter', 'latex') + set(boxPlotProFit(:,:),'linewidth',1); + yline(0,':', 'Color',[0.5 0.5 0.5]); end + +%% setup the table to show metabolite concentration changes +function [metaboliteTable, indexTable] = setupTable(numberOfMet, numOfParameters, metabolitesLabels) +metaboliteTable = cell(numberOfMet+4,numOfParameters*2+1); +metaboliteTable(3:numberOfMet+2,1) = metabolitesLabels; +metaboliteTable{numberOfMet+3,1} = 'Mean'; +metaboliteTable{numberOfMet+4,1} = 'Mean Main Metabolites'; +indexTable = 0; +end \ No newline at end of file diff --git a/createTestData/plotSimulationResults2.m b/createTestData/plotSimulationResults2.m new file mode 100644 index 0000000000000000000000000000000000000000..a420c1679d3d30a3ef8a693393db19ab6eae0172 --- /dev/null +++ b/createTestData/plotSimulationResults2.m @@ -0,0 +1,216 @@ +function plotSimulationResults2() + + +%% path to the export of the spectra +exportFolder = {'11 Simulations'}; +pathNameExport = 'ProFit test data'; +pathBaseExportFiles = pathToDataFolder(pathNameExport, exportFolder); +dataExportPathBase = strcat(pathBaseExportFiles, exportFolder{1}, '\'); + +paramKeyword = 'conc'; +truncSuffix = '_truncOn'; +iterationProFit = 4; +if contains(paramKeyword,'conc') + scalingOn = true; +else + scalingOn = false; +end +% name of metabolites in LCModel +metabolitesLCModel = {'Asp', 'Cr_CH2', 'Cr', 'GABA', 'Gln', 'Glu', 'Glyc', 'GSH', 'Lac', 'mI', 'NAA_as', 'NAA_ac', 'NAAG', 'tCho_P', 'Scyllo', 'Tau', 'Leu'}; + +% name of metabolites in ProFit +metabolitesProFit = {'Asp', 'Cr_CH2', 'Cr', 'GABA', 'Gln', 'Glu', 'Glyc', 'GSH', 'Lac', 'mI', 'NAA_as', 'NAA_ac', 'NAAG', 'tCho_P', 'Scyllo', 'Tau', 'Leu'}; + +%% load simulated data +load([dataExportPathBase, 'concentrations_simulated_', paramKeyword, '.mat'], 'concentrationsRm', 'metabolites', 'metaboliteNames'); + +%% load fitted data LCModel +load([dataExportPathBase, 'concentrations_', paramKeyword, truncSuffix, '.mat'], 'concentrations'); +concentrationsLCModel = concentrations; + +%% load fitted data ProFit +load([dataExportPathBase, 'concentrations_', paramKeyword, truncSuffix, '_profit.mat'], 'concentrations', 'activeMetabolites'); +concentrationsProFit = concentrations; + +plotCorrelations = true; +plotColors = {[0 0 1], [1 0 0]}; +% plotColors2 = {[0.0 0.4 0.0], [1 0.5 0.3]}; +plotColors2 = {[0.0 0.4 0.0], [0 0 0], [1 0.5 0.3], [0.49 0.18 0.56]}; +offsetPlot = 0.2; + +plotCorrelations = false; +plotPrecision = true; + +%% +paramKeyword = 'baseline'; +% load simulated data +load([dataExportPathBase, 'concentrations_simulated_', paramKeyword, '.mat'], 'concentrationsRm', 'metabolites', 'metaboliteNames'); +% load fitted data LCModel +load([dataExportPathBase, 'concentrations_', paramKeyword, '_dkntmn0.15', truncSuffix, '.mat'], 'concentrations'); +concentrationsLCModel = concentrations; +% load fitted data ProFit +load([dataExportPathBase, 'concentrations_', paramKeyword, truncSuffix, '_profit.mat'], 'concentrations', 'activeMetabolites'); +concentrationsProFit = concentrations; +offsetPlot = -0.4; +[allSimulMetConc, allLCModelMetConc, allProFitMetConc, allLCModelMetConcDev, allProFitMetConcDev, figIds, figIdsCorr, meanError_015] = getConcentrations(... + metabolites, metabolitesLCModel, metabolitesProFit, ... + concentrationsRm, concentrationsLCModel, concentrationsProFit, activeMetabolites, ... + scalingOn, plotCorrelations, dataExportPathBase, paramKeyword, truncSuffix, ... + plotPrecision, plotColors2{3}, offsetPlot, [], []); +%% +paramKeyword = 'baseline'; +% load simulated data +load([dataExportPathBase, 'concentrations_simulated_', paramKeyword, '.mat'], 'concentrationsRm', 'metabolites', 'metaboliteNames'); +% load fitted data LCModel +load([dataExportPathBase, 'concentrations_', paramKeyword, '_dkntmn0.25', truncSuffix, '.mat'], 'concentrations'); +concentrationsLCModel = concentrations; +% load fitted data ProFit +load([dataExportPathBase, 'concentrations_', paramKeyword, truncSuffix, '_profit.mat'], 'concentrations', 'activeMetabolites'); +concentrationsProFit = concentrations; +offsetPlot = 0.; +[allSimulMetConc, allLCModelMetConc, allProFitMetConc, allLCModelMetConcDev, allProFitMetConcDev, figIds, figIdsCorr, meanError_025] = getConcentrations(... + metabolites, metabolitesLCModel, metabolitesProFit, ... + concentrationsRm, concentrationsLCModel, concentrationsProFit, activeMetabolites, ... + scalingOn, plotCorrelations, dataExportPathBase, paramKeyword, truncSuffix, ... + plotPrecision, plotColors2{4}, offsetPlot, figIds, []); +%% +paramKeyword = 'baseline'; +% load simulated data +load([dataExportPathBase, 'concentrations_simulated_', paramKeyword, '.mat'], 'concentrationsRm', 'metabolites', 'metaboliteNames'); +% load fitted data LCModel +load([dataExportPathBase, 'concentrations_', paramKeyword, '_dkntmn0.5', truncSuffix, '.mat'], 'concentrations'); +concentrationsLCModel = concentrations; +% load fitted data ProFit +load([dataExportPathBase, 'concentrations_', paramKeyword, truncSuffix, '_profit.mat'], 'concentrations', 'activeMetabolites'); +concentrationsProFit = concentrations; +offsetPlot = 0.4; +[allSimulMetConc, allLCModelMetConc, allProFitMetConc, allLCModelMetConcDev, allProFitMetConcDev, figIds, figIdsCorr, meanError_05] = getConcentrations(... + metabolites, metabolitesLCModel, metabolitesProFit, ... + concentrationsRm, concentrationsLCModel, concentrationsProFit, activeMetabolites, ... + scalingOn, plotCorrelations, dataExportPathBase, paramKeyword, truncSuffix, ... + plotPrecision, plotColors2{2}, offsetPlot, figIds, []); + +txt = {'LCModel Setup/error', ['orange: dkntmn=0.15 / ', num2str(meanError_015,3)], ... + ['purple: dkntmn=0.25 / ', num2str(meanError_025,3)], [' black: dkntmn=0.5 / ', num2str(meanError_05,3)]}; +title(txt, 'Interpreter','latex','FontSize', 14) +end + +function [allSimulMetConc, allLCModelMetConc, allProFitMetConc, allLCModelMetConcDev, allProFitMetConcDev, figIds, figIdsCorr, meanError] = ... + getConcentrations(metabolites, metabolitesLCModel, metabolitesProFit, ... + concentrationsRm, concentrationsLCModel, concentrationsProFit, activeMetabolites, ... + scalingOn, plotCorrelations, dataExportPathBase, paramKeyword, truncSuffix, ... + plotPrecision, plotColors, offsetPlot, figIds, figIdsCorr) + + iterationProFit = 4; + if isempty(figIdsCorr) + emptyFigureIdsCorr = true; + figIdsCorr = cell(1,length(metabolites)); + else + emptyFigureIdsCorr = false; + end + allSimulMetConc = concentrationsRm; + allLCModelMetConc = zeros(size(allSimulMetConc)); + allProFitMetConc = zeros(size(allSimulMetConc)); + allLCModelMetConcDev = zeros(size(allSimulMetConc)); + allProFitMetConcDev = zeros(size(allSimulMetConc)); + for indexMetabolite = 1:length(metabolites) + simulatedMetConc = concentrationsRm(:, indexMetabolite); + indexMetSim = find(strcmp(metabolites,'tCr(CH3)')); %'MMB' + fittedMetConcLCModel = zeros(size(simulatedMetConc)); + for indexFit = 1:length(concentrationsLCModel) + currentConcentrationsLCModel = concentrationsLCModel{indexFit}; + indexMetLCModel = find(strcmp(currentConcentrationsLCModel(1,:),'Cr')); %'Leu' + MMBConc = currentConcentrationsLCModel{2,indexMetLCModel}; + MMBConcSim = concentrationsRm(indexFit,indexMetSim); + if scalingOn + scaling = MMBConcSim/MMBConc; + else + scaling = 1; + end + indexMetLCModel = find(strcmp(currentConcentrationsLCModel(1,:),metabolitesLCModel(indexMetabolite))); + fittedMetConcLCModel(indexFit) = currentConcentrationsLCModel{2,indexMetLCModel}*scaling; + end + fittedMetConcProFit = zeros(size(simulatedMetConc)); +% for indexFit = 1:length(concentrationsProFit) +% currentConcentrationsProFit = concentrationsProFit{indexFit}{iterationProFit}; +% indexMetProFit = find(strcmp(activeMetabolites{iterationProFit},'Cr')); %'Leu' +% MMBConc = currentConcentrationsProFit(indexMetProFit); +% MMBConcSim = concentrationsRm(indexFit,indexMetSim); +% % if scalingOn +% % scaling = MMBConcSim/MMBConc; +% % else +% scaling = 1; +% % end +% indexMetProFit = find(strcmp(activeMetabolites{iterationProFit},metabolitesProFit(indexMetabolite))); +% fittedMetConcProFit(indexFit) = currentConcentrationsProFit(indexMetProFit)*scaling; +% end +% if strcmp(metabolitesProFit(indexMetabolite),'Leu') +% fittedMetConcProFit = fittedMetConcProFit *1e8; +% end + allLCModelMetConc(:, indexMetabolite) = fittedMetConcLCModel; + allProFitMetConc(:, indexMetabolite) = fittedMetConcProFit; + allLCModelMetConcDev(:, indexMetabolite) = (simulatedMetConc-fittedMetConcLCModel)./simulatedMetConc.*100; + allProFitMetConcDev(:, indexMetabolite) = (simulatedMetConc-fittedMetConcProFit)./simulatedMetConc.*100; + if plotCorrelations + if emptyFigureIdsCorr + figIdsCorr{indexMetabolite} = figure; + end + figure(figIdsCorr{indexMetabolite}); + hold on + scatter(simulatedMetConc, fittedMetConcLCModel); + scatter(simulatedMetConc, fittedMetConcProFit, 'x'); % ### + +% if ~emptyFigureIdsCorr % ### delete this if later + plot(simulatedMetConc,simulatedMetConc); +% end + title(metabolites(indexMetabolite)) + xlabel('Simulated concentrations [mmol/kg]'); + ylabel('Fitted concentrations [mmol/kg]'); + legend('LCModel concentrations', 'ProFit concentrations', 'Identity Line', 'Location', 'Northwest') %## +% legend('LCModel concentrations', 'Identity Line', 'Location', 'Northwest') +% legend('\nu_e = all identical T_2', '\nu_e = metabolite specific T_2', 'Identity Line', 'Location', 'Northwest') + xl = xlim; + if xl(2) > max(simulatedMetConc) + xl(2) = max(simulatedMetConc); + end + xlim(xl); + + pathName = [dataExportPathBase, paramKeyword, '/correlations/']; + if ~exist(pathName, 'dir') + mkdir(pathName); + end + fileName = [metabolites{indexMetabolite}, '_', paramKeyword, truncSuffix]; + saveas(figIdsCorr{indexMetabolite}, [pathName, fileName, '.tif']); + savefig(figIdsCorr{indexMetabolite}, [pathName,fileName, '.fig'],'compact'); +% BlandAltman(simulatedMetConc, fittedMetConcLCModel); +% title(metabolites(indexMetabolite)); +% BlandAltman(simulatedMetConc, fittedMetConcProFit); +% title(metabolites(indexMetabolite)); + end + end + + allLCModelMetConcDev = allLCModelMetConcDev - median(allLCModelMetConcDev,1, 'omitnan'); + allProFitMetConcDev = allProFitMetConcDev - median(allProFitMetConcDev,1, 'omitnan'); + meanError =0; + if plotPrecision + yLimValue = 50; + numberOfMet = length(metabolites); + if isempty(figIds) + figIds{1} = figure; + figIds{2} = figure; + end + positionsTicks = [3:1.5:1.5*numberOfMet+1.5]; + positions = positionsTicks + offsetPlot; + figure(figIds{1}) + hold on + boxPlotLCModel = boxplot(allLCModelMetConcDev, metabolites,'colors',plotColors,'symbol','+', 'positions',positions,'width',0.3); + xtickangle(45) + title('LCModel') + ylim([-yLimValue,yLimValue]); + xlim([positionsTicks(1)-1, positionsTicks(end)+1]) + ylabel('Concentration change [%]') + set(boxPlotLCModel(:,:),'linewidth',1); + meanLCModelMetConcDev = mean(abs(allLCModelMetConcDev),1, 'omitnan'); + meanError = mean(meanLCModelMetConcDev) + end +end diff --git a/createTestData/plot_ProFit_Metabolites_Fit.m b/createTestData/plot_ProFit_Metabolites_Fit.m index a5feb5c70ba76f6f8b18f95317af96b8ce85512f..9d7a702829637c758284ba8f5cbbf38a6152edd2 100644 --- a/createTestData/plot_ProFit_Metabolites_Fit.m +++ b/createTestData/plot_ProFit_Metabolites_Fit.m @@ -1,4 +1,4 @@ -function [concentrations, activeMetabolites] = plot_ProFit_Metabolites_Fit(FileName, PathName, downField_MM_Met, saveFigures) +function [concentrations, activeMetabolites, FQNs, FQNs2] = plot_ProFit_Metabolites_Fit(FileName, PathName, downField_MM_Met, saveFigures, displayBaseline) if ~exist('FileName', 'var') [FileName,PathName] = uigetfile('*.mat','Please select .mat files from ProFit output','Multiselect','on'); @@ -14,8 +14,11 @@ end if ~exist('saveFigures','var') saveFigures = false; end +if ~exist('displayBaseline','var') + displayBaseline = false; +end -iterations = 3;%:4; +iterations = 4; switch downField_MM_Met case 'Met moiety' @@ -35,7 +38,7 @@ switch downField_MM_Met metaboliteLabels = {'Asp';'Cr';'PCr';'GABA';'Glu';'Gln';'GSH';'Glyc';'Lac';'mI';'NAA';'NAAG';'Scyllo';'Tau';'PCh';'GPC';'PE'}; metaboliteNames = {'Asp' 'Cr' 'Cr_CH2' 'GABA' 'Glu' 'Gln' 'GSH' 'Glyc' 'Lac' 'mI' 'NAA_as' 'NAA_ac' 'NAAG' 'Scyllo' 'Tau' 'tCho_P'}; - metaboliteLabels = {'Asp';'Cr(CH3)';'Cr(CH2)';'GABA';'Glu';'Gln';'GSH';'Glyc';'Lac';'mI';'NAA(CH2)';'NAA(CH3)'; 'NAAG';'Scyllo';'Tau';'tCho+';}; + metaboliteLabels = {'Asp';'tCr(CH_3)';'tCr(CH_2)';'GABA';'Glu';'Gln';'GSH';'Gly';'Lac';'mI';'NAA(CH_2)';'NAA(CH_3)'; 'NAAG';'sI';'Tau';'tCho+';}; % %Braino % metaboliteNames = {'Cr_CH3' 'Cr_CH2' 'Glu' 'Lac' 'mI' 'NAA_as' 'NAA_ac' 'Cho'}; @@ -82,6 +85,8 @@ rData = {}; % close all; concentrations = cell(length(FileName),length(iterations)); activeMetabolites = cell(length(FileName),length(iterations)); +FQNs = cell(length(FileName),length(iterations)); +FQNs2 = cell(length(FileName),length(iterations)); for iteration = iterations for index =1:length(FileName) @@ -92,39 +97,30 @@ for iteration = iterations % get mean values for pc0, pc1 and df1, df2 % values which should be applied on spectra and not the basis set pc0 = zeros(1, currentFitresult.nr_act_mets); - pc11 = zeros(1, currentFitresult.nr_act_mets); pc12 = zeros(1, currentFitresult.nr_act_mets); - df1 = zeros(1, currentFitresult.nr_act_mets); df2 = zeros(1, currentFitresult.nr_act_mets); for met_cnt=1:currentFitresult.nr_act_mets pc0(met_cnt) = currentFitresult.fitted_values.pc0(currentFitresult.sub_mask.pc0.full(:,met_cnt)); - pc11(met_cnt) = currentFitresult.fitted_values.pc11(currentFitresult.sub_mask.pc11.full(:,met_cnt)); pc12(met_cnt) = currentFitresult.fitted_values.pc12(currentFitresult.sub_mask.pc12.full(:,met_cnt)); - df1(met_cnt) = currentFitresult.fitted_values.df1(currentFitresult.sub_mask.df1.full(:,met_cnt)); df2(met_cnt) = currentFitresult.fitted_values.df2(currentFitresult.sub_mask.df2.full(:,met_cnt)); end - mean_pc0 = mean(pc0); - mean_pc11 = mean(pc11); - mean_pc12 = mean(pc12); - mean_df1 = mean(df1); - mean_df2 = mean(df2); - total_pc0 = currentFitresult.preprocessedValues.pc0 + mean_pc0; - total_df1 = currentFitresult.preprocessedValues.df1 + mean_df1; - total_df2 = currentFitresult.preprocessedValues.df2 + mean_df2; %ppm axis ppm{index} = currentFitresult.common_data.data.fitroi.ppm2; %phaseData - pData{index} = currentFitresult.fitroi_spec; + pData{index} = currentFitresult.processed_spec; %fit data fData{index} = currentFitresult.fitted_spec; %residual rData{index} = currentFitresult.residual_spec; %spline baseline - spBB = currentFitresult.splines_baseline.basis_matrix; - concSpline = currentFitresult.splines_baseline.coeff; - bData{index} = (spBB * concSpline(1:size(spBB,2)))'; - + if ~isempty(currentFitresult.splines_baseline) + spBB = currentFitresult.splines_baseline.basis_matrix; + concSpline = currentFitresult.splines_baseline.coeff; + bData{index} = (spBB * concSpline(1:size(spBB,2)))'; + else + bData{index} = zeros(size(currentFitresult.residual_spec)); + end %Macromolecular baseline if strcmp(downField_MM_Met,'Met') || strcmp(downField_MM_Met,'Met moiety') indexMMB = find(strcmp(currentFitresult.met(currentFitresult.active_mets), 'Leu')); @@ -145,22 +141,38 @@ for iteration = iterations end %scaling calculation - scale = max(pData{index}); + scale = real(max(pData{index})); %plotting hold on - if MMB_available - p = plot(ppm{index}, (pData{index} - bData{index}) ./ scale, ... - ppm{index},(fData{index} - bData{index}) ./ scale, ... - ppm{index}, mmData{index} ./ scale - 0.03, ... - ppm{index},bData{index} ./ scale - offsetBaseline, ... - ppm{index},rData{index} ./ scale - offsetResidual); - text(xLimitsText,-0.03,'MMB', 'FontSize', FontSize); + if displayBaseline + if MMB_available + p = plot(ppm{index}, pData{index} ./ scale, ... + ppm{index},fData{index} ./ scale, ... + ppm{index}, mmData{index} ./ scale - 0.03, ... + ppm{index},bData{index} ./ scale - offsetBaseline, ... + ppm{index},rData{index} ./ scale - offsetResidual); + text(xLimitsText,-0.03,'MM spectrum', 'FontSize', FontSize); + else + p = plot(ppm{index}, pData{index} ./ scale, ... + ppm{index},fData{index} ./ scale, ... + ppm{index},bData{index} ./ scale - offsetBaseline, ... + ppm{index},rData{index} ./ scale - offsetResidual); + end else - p = plot(ppm{index}, (pData{index} - bData{index}) ./ scale, ... - ppm{index},(fData{index} - bData{index}) ./ scale, ... - ppm{index},bData{index} ./ scale - offsetBaseline, ... - ppm{index},rData{index} ./ scale - offsetResidual); + if MMB_available + p = plot(ppm{index}, (pData{index} - bData{index}) ./ scale, ... + ppm{index},(fData{index} - bData{index}) ./ scale, ... + ppm{index}, mmData{index} ./ scale - 0.03, ... + ppm{index},bData{index} ./ scale - offsetBaseline, ... + ppm{index},rData{index} ./ scale - offsetResidual); + text(xLimitsText,-0.03,'MM spectrum', 'FontSize', FontSize); + else + p = plot(ppm{index}, (pData{index} - bData{index}) ./ scale, ... + ppm{index},(fData{index} - bData{index}) ./ scale, ... + ppm{index},bData{index} ./ scale - offsetBaseline, ... + ppm{index},rData{index} ./ scale - offsetResidual); + end end text(xLimitsText,0.05,'Data + Fit', 'FontSize', FontSize); @@ -199,11 +211,18 @@ for iteration = iterations set(gca,'fontsize',FontSize); if saveFigures - set(figId, 'Units', 'Normalized', 'OuterPosition', [0, 0.04, 1, 0.96]); + set(figId, 'Units', 'Normalized', 'OuterPosition', [0, 0.04, 1, 0.96]); + set(gca, 'Position', [0.13,0.11,0.75,0.815]) +% set(gca, 'Position', [0.13,0.11,0.75,0.88]) saveas(figId, [PathName,FileName{index}(1:end-4), '_iter', num2str(iteration), '.tif']); savefig(figId, [PathName,FileName{index}(1:end-4), '_iter', num2str(iteration), '.fig'],'compact'); end [concentrations{index,iteration}, activeMetabolites{index,iteration}] = saveFitResultsTable(currentFitresult, saveFigures, PathName, FileName{index}, iteration); + + FQN2 = calculate_fit_quality_number(currentFitresult.residual_spec, currentFitresult.common_data.data.fitroi.ppm2, ... + currentFitresult.common_data.spec, currentFitresult.common_data.data.ppm2, [1.95 4.0]); + FQNs{index,iteration} = currentFitresult.fit_quality_number; + FQNs2{index,iteration} = FQN2; end end end @@ -218,13 +237,14 @@ active_met_names = currentFitresult.met(currentFitresult.active_mets); dataOfTable={}; columnname = {'met','conc', '/Cr', '<html>crlb<br />[%]</html>', ... '<html>T2<br />[ms]</html>','<html>em<br />[Hz]</html>',... - '<html>gm<br />[Hz]</html>', '<html>em_g<br />[Hz]</html>', ... - '<html>pc0<br />[deg]</html>', '<html>df1<br />[Hz]</html>', ... - '<html>df2<br />[Hz]</html>', '<html>pc11<br />[deg/ppm]</html>', ... + '<html>gm<br />[Hz]</html>', ... + '<html>pc0<br />[deg]</html>', '<html>df2<br />[Hz]</html>', ... '<html>pc12<br />[deg/ppm]</html>'}; -columnformat={'char',[],[],[],[],[],[],[],[],[],[],[],[]}; +columnformat={'char',[],[],[],[],[],[],[],[],[],[]}; concentrations = zeros(1,currentFitresult.nr_act_mets); creatineConc = currentFitresult.GetFittedValues({'Cr'},{'conc'}); + +boundsTable = zeros(currentFitresult.nr_act_mets,10); for met_cnt=1:currentFitresult.nr_act_mets dataOfTable=[dataOfTable;{... active_met_names{met_cnt},... @@ -241,21 +261,46 @@ for met_cnt=1:currentFitresult.nr_act_mets currentFitresult.sub_mask.em.full(:,met_cnt)'),'%6.4f'),... num2str(currentFitresult.fitted_values.gm(... currentFitresult.sub_mask.gm.full(:,met_cnt)'),'%6.4f'),... - num2str(currentFitresult.fitted_values.em_g(... - currentFitresult.sub_mask.em_g.full(:,met_cnt)'),'%6.4f'),... num2str(currentFitresult.fitted_values.pc0(... currentFitresult.sub_mask.pc0.full(:,met_cnt)'),'%6.4f'),... - num2str(currentFitresult.fitted_values.df1(... - currentFitresult.sub_mask.df1.full(:,met_cnt)'),'%6.4f'),... num2str(currentFitresult.fitted_values.df2(... currentFitresult.sub_mask.df2.full(:,met_cnt)'),'%6.4f'),... - num2str(currentFitresult.fitted_values.pc11(... - currentFitresult.sub_mask.pc11.full(:,met_cnt)'),'%6.4f'),... num2str(currentFitresult.fitted_values.pc12(... currentFitresult.sub_mask.pc12.full(:,met_cnt)'),'%6.4f')... }]; concentrations(met_cnt) = currentFitresult.fitted_values.conc(currentFitresult.sub_mask.conc.full(:,met_cnt)'); + boundsTable(met_cnt,:) = [... + 0,... + checkBounds(currentFitresult,'conc', met_cnt),... + 0,... %conc/Cr + 0,... %crlb + 0,... % T2 + checkBounds(currentFitresult,'em', met_cnt),... + checkBounds(currentFitresult,'gm', met_cnt),... + checkBounds(currentFitresult,'pc0', met_cnt),... + checkBounds(currentFitresult,'df2', met_cnt),... + checkBounds(currentFitresult,'pc12', met_cnt),... + ]; end +%reached upper bounds- blue +idx = boundsTable == 1; +dataOfTable(idx) = strcat(... + '<html><span style="color: #0000FF; font-weight: bold;">', ... + dataOfTable(idx), ... + '</span></html>'); +%reached lower bounds - red +idx = boundsTable == -1; +dataOfTable(idx) = strcat(... + '<html><span style="color: #FF0000; font-weight: bold;">', ... + dataOfTable(idx), ... + '</span></html>'); +%reached both bounds - green +idx = isnan(boundsTable); +dataOfTable(idx) = strcat(... + '<html><span style="color: #00FF00; font-weight: bold;">', ... + dataOfTable(idx), ... + '</span></html>'); + tableProfit = uitable(...%'Units','normalized',...% 'Position',[20 20 850 580],'Data', dataOfTable,... 'ColumnName', columnname,'ColumnFormat',columnformat,... @@ -267,21 +312,31 @@ if saveFigures end end -function spec = applyGlobalFactors(spec, pc0, pc12, df1, df2, data) - - spec_roi = [data.fitroi.bounds(1,1) data.fitroi.bounds(1,2); data.fitroi.bounds(2,1) data.fitroi.bounds(2,2)]; - coeff_F2_degree_ppm = 1i*pc12*pi/180; - spec = spec .* exp( ... - ... applying the F2 corrections ... - coeff_F2_degree_ppm * data.phase_1_f2_mx(spec_roi(1,1):spec_roi(2,1), spec_roi(1,2):spec_roi(2,2))); - fid = ifft(ifftshift(spec)); %TODO check, do we need the ifftshift - % zero order phase correction - fid = fid .* exp(1i*-pc0*pi/180*data.phase_0_mx); - - % frequency shift in the F1 - fid = fid .* exp(1i*-df1*2*pi*data.shift_t1_mx); - - % frequency shift in the F2 - fid = fid .* exp(1i*-df2*2*pi*data.shift_t2_mx); - spec = fftshift(fft(fid)); -end \ No newline at end of file +function bounds = checkBounds(currentFitresult,param, met_cnt) + % bounds = 0 : no bounds reached + % bounds = 1 : upper bounds reached + % bounds = -1 : lower bounds reached + % bounds = NaN : both bounds reached + bounds = 0; + factorBounds = 1.1; %within 10% from bound + sub_mask = eval(['currentFitresult.sub_mask.', param, '.full(:,met_cnt)'])'; + preprocessed_value = 0; + try %should work for pc0, pc12, df2 (df2_global is not a parameter of interest) + preprocessed_value = eval(['currentFitresult.preprocessedValues.' param]); + catch + %nothing + end + fitted_value = eval(['currentFitresult.fitted_values.', param])-preprocessed_value; + if (eval(['currentFitresult.full_upper_bounds.', param,'(sub_mask)']) < ... + (fitted_value(sub_mask) * factorBounds)) + bounds = 1; + end + if (eval(['currentFitresult.full_lower_bounds.', param,'(sub_mask)']) > ... + (fitted_value(sub_mask) / factorBounds)) + if bounds == 0 + bounds = -1; %reached only lower bounds + else + bounds = NaN; %reached both bounds + end + end +end diff --git a/createTestData/plot_all_test_data_profit.m b/createTestData/plot_all_test_data_profit.m index e1c45fe62c7aca3cc6be233e073a6bc47030a2c0..bba246e127d4e0b6b907406286a063495378d13c 100644 --- a/createTestData/plot_all_test_data_profit.m +++ b/createTestData/plot_all_test_data_profit.m @@ -1,26 +1,24 @@ function plot_all_test_data_profit() -fitLCModel = true; %false fits profit + reconOption = 5; truncOn = false; offsetScatter = 0.3; markerScatter = 'o'; markerColor = [1 0 0]; -fitLCModel = true; %false fits profit reconOption = 6; truncOn = false; offsetScatter = 0; markerScatter = 'd'; markerColor = [0 1 0]; -% +% reconOption = 2; -truncOn = false; -offsetScatter = -0.3; +truncOn = true; +offsetScatter = 0.15; markerScatter = 'x'; markerColor = [1 0 0]; -plotInSameFigureAllSubjects = true; exportFolders = {'0 Water References',... '1 Normal recon', '2 Removed averages ','3 Removed coils',... @@ -28,6 +26,10 @@ exportFolders = {'0 Water References',... '7 Rescale off', '8 Rescale Water Supp Off'}; pathNameExport = 'ProFit test data'; pathBaseExportFiles = pathToDataFolder(pathNameExport, exportFolders); + +pathBaseExportFiles = pathBaseExportFiles(1:end-1); +pathBaseExportFiles = [pathBaseExportFiles ' - R3\']; + dataExportPathBaseRef = strcat(pathBaseExportFiles, exportFolders{2}, '\'); dataExportPathBase = strcat(pathBaseExportFiles, exportFolders{reconOption+1}, '\'); @@ -60,21 +62,327 @@ else end subjects = { ... - '1658' ... - '1717' ... - '2017' ... - '3373' ... - '3490' ... - '5771' ... - '6249' ... - '6971' ... - '7338' ... - '7782' ... - '9810' ... + 'Subj_1' ... + 'Subj_2' ... + 'Subj_3' ... + 'Subj_4' ... + 'Subj_5' ... + 'Subj_6' ... + 'Subj_7' ... + 'Subj_8' ... + 'Subj_9' ... + 'Subj_10' ... + 'Subj_11' ... }; TEs = [24;];% 32; 40; 52; 60]; +% name of metabolites in LCModel +metabolitesLCModel = {'Asp', 'Cr_CH2', 'Cr', 'GABA', 'Gln', 'Glu', 'Glyc', 'GSH', 'Lac', 'mI', 'NAA_as', 'NAA_ac', 'NAAG', 'tCho_P', 'Scyllo', 'Tau', 'Leu'}; + +% name of metabolites in ProFit +metabolitesProFit = {'Asp', 'Cr_CH2', 'Cr', 'GABA', 'Gln', 'Glu', 'Glyc', 'GSH', 'Lac', 'mI', 'NAA_as', 'NAA_ac', 'NAAG', 'tCho_P', 'Scyllo', 'Tau', 'Leu'}; + +% name of metabolites to display +metabolitesToDisplay = {'Asp', 'tCr(CH_2)', 'tCr(CH_3)', 'GABA', 'Gln', 'Glu', 'Gly', 'GSH', 'Lac', 'mI', 'NAA(CH_2)', 'NAA(CH_3)', 'NAAG', 'tCho+', 'sI', 'Tau', 'MM spectrum'}; +metabolitesLabels = {'Asp', 'tCr(CH2)', 'tCr(CH3)', 'GABA', 'Gln', 'Glu', 'Gly', 'GSH', 'Lac', 'mI', 'NAA(CH2)', 'NAA(CH3)', 'NAAG', 'tCho+', 'sI', 'Tau', 'MM spectrum'}; + +numberOfMet = length(metabolitesLabels); +indecesMainMet = zeros(1,numberOfMet); +mainMetabolites = { 'tCr(CH3)', 'tCr(CH2)', 'Glu', 'mI', 'NAA(CH2)', 'NAA(CH3)', 'tCho+'}; +for indexMet = 1:numberOfMet + indecesMainMet(indexMet) = ~isempty(find(strcmp(mainMetabolites,metabolitesLabels{indexMet}), 1)); +end +indecesMainMet = logical(indecesMainMet); + +fitLCModel = true; %false fits profit +if fitLCModel + SoftwareName = 'LCModel'; +else + SoftwareName = 'ProFit'; +end +[metConcAllSubjLCModel, metConcAllSubjRefLCModel, metConcAllSubjNormLCModel, MC_H2O_ConcAllSubjLCModel, MC_H2O_ConcAllSubjRefLCModel] = ... + getAllMetaboliteConc(dataExportPathBase, dataExportPathBaseRef, truncSuffix, subjects, TEs, ... + namingSuffixesAve, namingSuffixesCoil, fitLCModel, reconOption, ... + numberOfMet, metabolitesLCModel, metabolitesProFit, metabolitesLabels, indecesMainMet, ... + offsetScatter, markerScatter, markerColor); + +fitLCModel = false; %false fits profit +if fitLCModel + SoftwareName = 'LCModel'; +else + SoftwareName = 'ProFit'; +end +[metConcAllSubjProFit, metConcAllSubjRefProFit, metConcAllSubjNormProFit, MC_H2O_ConcAllSubjProFit, MC_H2O_ConcAllSubjRefProFit] = ... + getAllMetaboliteConc(dataExportPathBase, dataExportPathBaseRef, truncSuffix, subjects, TEs, ... + namingSuffixesAve, namingSuffixesCoil, fitLCModel, reconOption, ... + numberOfMet, metabolitesLCModel, metabolitesProFit, metabolitesLabels, indecesMainMet, ... + offsetScatter, markerScatter, markerColor); + +metaboliteRef = 14;%'tCho+' 3;%'tCr(CH3)' 12;%'NAA(CH3)' +metConcAllSubjProFitScaled = metConcAllSubjProFit ./ metConcAllSubjProFit(:,:,metaboliteRef); +metConcAllSubjRefProFitScaled = metConcAllSubjRefProFit ./ metConcAllSubjRefProFit(:,metaboliteRef); +metConcAllSubjLCModelScaled = metConcAllSubjLCModel ./ metConcAllSubjLCModel(:,:,metaboliteRef); +metConcAllSubjRefLCModelScaled = metConcAllSubjRefLCModel ./ metConcAllSubjRefLCModel(:,metaboliteRef); + +metaboliteRef = 0; +metConcAllSubjProFitScaled = metConcAllSubjProFit; +metConcAllSubjRefProFitScaled = metConcAllSubjRefProFit; +metConcAllSubjLCModelScaled = metConcAllSubjLCModel; +metConcAllSubjRefLCModelScaled = metConcAllSubjRefLCModel; + +% BA plot paramters +tit = 'Repeatability '; % figure title +subsets = {'32 ave.1','32 ave.2','32 ave.3', '64 ave.1', '64 ave.2', '64 ave.3'}; +subsets_refit = {'32 ave.', '64 ave.'}; +softwareNames = {'ProFit', 'LCModel'}; +gnames = {subsets, softwareNames}; % names of groups in data {dimension 1 and 2} +label = {'Ref. Fits','Subset Fits','ratio'}; % Names of data sets +label_refit = {'c^{fits1}_{i,k}','c^{fits2}_{i,k}','arb.u.'}; % Names of data sets +label_SW_comp = {'LCModel','ProFit','arb.u.'}; % Names of data sets +corrinfo = {'n','SSE','r2','eq'}; % stats to display of correlation scatter plot +BAinfo = {'RPC','ks'}; % stats to display on Bland-ALtman plot +BAinfo_refit = {''}; % stats to display on Bland-ALtman plot +limits = 'auto'; % how to set the axes limits +if 1 % colors for the data sets may be set as: + colors = 'br'; % character codes +else + colors = [0 0 1;... % or RGB triplets + 1 0 0]; +end + +paramsBA.data1TreatmentMode = 'Compare'; +paramsBA.diffValueMode = 'percent'; + +numOfSimulations = length(namingSuffixesAve)*length(namingSuffixesCoil); + +%there seems to be a fit error in the fitting of even the MC water data. +% BlandAltman(MC_H2O_ConcAllSubjLCModel, MC_H2O_ConcAllSubjProFit*1e-6, label_SW_comp,[tit 'Water'],subsets,... +% 'corrInfo',corrinfo,'baInfo',BAinfo,'axesLimits',limits,'showFitCI',' on',... +% 'baStatsMode','Gaussian','forceZeroIntercept','on', 'diffValueMode', 'percent'); +% +% BlandAltman(MC_H2O_ConcAllSubjRefLCModel, MC_H2O_ConcAllSubjRefProFit*1e-6, label_SW_comp,[tit 'Water'],subsets,... +% 'corrInfo',corrinfo,'baInfo',BAinfo,'axesLimits',limits,'showFitCI',' on',... +% 'baStatsMode','Gaussian','forceZeroIntercept','on', 'diffValueMode', 'percent'); + +rpc_table = cell(numberOfMet+5,5); +rpc_table{1,2} = softwareNames{1}; +rpc_table{1,4} = softwareNames{2}; +rpc_table{2,2} = subsets_refit{1}; +rpc_table{2,3} = subsets_refit{2}; +rpc_table{2,4} = subsets_refit{1}; +rpc_table{2,5} = subsets_refit{2}; +rpc_table(3:end-3,1) = metabolitesToDisplay; +rpc_table{end-1,1} = 'Mean Main'; +rpc_table{end,1} = 'Mean'; + +%title('Reproducibility'); +subplotsX = 4; +subplotsY = 4; +totalSubplots1 = subplotsX * subplotsY; +rpcSum = zeros(1,numberOfMet); +diffMedian = zeros(1,numberOfMet); +for indexMet = 1: numberOfMet + if indexMet == metaboliteRef + continue; + end + if (indexMet == 1) || (indexMet == totalSubplots1/2+1) + figure; + if indexMet >= 8 + subplotsX = 6; + subplotsY = 3; + totalSubplots = subplotsX * subplotsY; + end + end + if indexMet <= totalSubplots1/2 + runningIndexPlot = (indexMet-1)+1+floor((indexMet-1)/subplotsY)*subplotsY-floor((indexMet-1)/totalSubplots1*2)*totalSubplots1; + else + indexMet2 = indexMet - totalSubplots1/2; + runningIndexPlot = (indexMet2-1)+1+floor((indexMet2-1)/subplotsY)*subplotsY-floor((indexMet2-1)/totalSubplots*2)*totalSubplots; + end + + %ProFit Concentrations + metConcAllSubjProFitScaled_ = metConcAllSubjProFitScaled(:, :, indexMet); + metConcAllSubjProFitScaled_ = reshape(metConcAllSubjProFitScaled_,11*3,2);%group same SNR + metConcAllSubjRefProFitScaled_ = metConcAllSubjRefProFitScaled(:, indexMet); + metConcAllSubjRefProFitScaled_ = repmat(metConcAllSubjRefProFitScaled_,1,6); + metConcAllSubjRefProFitScaled_ = reshape(metConcAllSubjRefProFitScaled_,11*3,2);%group same SNR + + %LCModel Concentrations + metConcAllSubjLCModelScaled_ = metConcAllSubjLCModelScaled(:, :, indexMet); + metConcAllSubjLCModelScaled_ = reshape(metConcAllSubjLCModelScaled_,11*3,2);%group same SNR + metConcAllSubjRefLCModelScaled_ = metConcAllSubjRefLCModelScaled(:, indexMet); + metConcAllSubjRefLCModelScaled_ = repmat(metConcAllSubjRefLCModelScaled_,1,6); + metConcAllSubjRefLCModelScaled_ = reshape(metConcAllSubjRefLCModelScaled_,11*3,2);%group same SNR + + %ProFit&LCModel Concentrations + metConcAllSubjScaled_ = cat(3, metConcAllSubjProFitScaled_, metConcAllSubjLCModelScaled_); + metConcAllSubjRefScaled_ = cat(3, metConcAllSubjRefProFitScaled_, metConcAllSubjRefLCModelScaled_); +%% ref Fits vs subfits: Code not used anymore in this style +% BlandAltman(metConcAllSubjRefScaled_, metConcAllSubjScaled_, label,[tit metabolitesLCModel{indexMet}],gnames,... +% 'corrInfo',corrinfo,'baInfo',BAinfo,'axesLimits',limits,'colors',colors, 'showFitCI',' on',... +% 'baStatsMode','non-parametric','forceZeroIntercept','on'); +% % Reference fits vs all per Software +% %ProFit ref Fits vs subfits +% rpcProFit = BlandAltman(metConcAllSubjRefProFitScaled_, metConcAllSubjProFitScaled_, label,[tit softwareNames{1} ' ' metabolitesLCModel{indexMet}],subsets,... +% 'corrInfo',corrinfo,'baInfo',BAinfo,'axesLimits',limits,'colors',[0.75 0.5 0; 0.5 0.2 0], 'showFitCI',' on',... +% 'baStatsMode','Gaussian','forceZeroIntercept','on', 'diffValueMode', 'percent'); +% %LCModel ref Fits vs subfits +% rpcLCModel = BlandAltman(metConcAllSubjRefLCModelScaled_, metConcAllSubjLCModelScaled_, label,[tit softwareNames{2} ' ' metabolitesLCModel{indexMet}],subsets,... +% 'corrInfo',corrinfo,'baInfo',BAinfo,'axesLimits',limits,'colors',[0, 0.5, 0.75; 0, 0.25 0.5], 'showFitCI',' on',... +% 'baStatsMode','Gaussian','forceZeroIntercept','on', 'diffValueMode', 'percent'); +% %rpc_table{indexMet+1,2} = rpcProFit; +% %rpc_table{indexMet+1,3} = rpcLCModel; +%% LCModel vs ProFit +% BlandAltman(metConcAllSubjLCModelScaled_, metConcAllSubjProFitScaled_, label_SW_comp,[tit metabolitesLCModel{indexMet}],subsets,... +% 'corrInfo',corrinfo,'baInfo',BAinfo,'axesLimits',limits,'colors',colors, 'showFitCI',' on',... +% 'baStatsMode','non-parametric','forceZeroIntercept','on', 'diffValueMode', 'percent'); +% [rpc, ~, stat] = BlandAltman(metConcAllSubjRefLCModelScaled_, metConcAllSubjRefProFitScaled_, label_SW_comp,[tit metabolitesLCModel{indexMet}],subsets,... +% 'corrInfo',corrinfo,'baInfo',BAinfo,'axesLimits',limits,'colors',colors, 'showFitCI',' on',... +% 'baStatsMode','non-parametric','forceZeroIntercept','on', 'diffValueMode', 'percent'); +% rpcs(indexMet) = rpc; +% diffMedian(indexMet) = stat.differenceMedian; +%% Subfits vs subfits per Software + %ProFit ref Fits vs subfits + rpc_ProFit_32_ave = calculate_rpc_percent(metConcAllSubjProFitScaled_(1:11,1), metConcAllSubjProFitScaled_(12:22,1)); + rpc_ProFit_64_ave = calculate_rpc_percent(metConcAllSubjProFitScaled_(1:11,2), metConcAllSubjProFitScaled_(12:22,2)); + legendText = {['{\color{blue}\bf32-ave: RPC=' mynum2str(rpc_ProFit_32_ave,2) '%}'];['{\color{red}\bf64-ave: RPC=' mynum2str(rpc_ProFit_64_ave,2) '%}']}; + + sProFit = subplot(subplotsX,subplotsY,runningIndexPlot); + [rpcProFit, fig, stats] = BlandAltmanOnly(sProFit, metConcAllSubjProFitScaled_(1:11,:), metConcAllSubjProFitScaled_(12:22,:),... + label_refit,[metabolitesToDisplay{indexMet}],legendText,... + 'corrInfo',corrinfo,'baInfo',BAinfo_refit,'axesLimits',limits,'colors','br', 'showFitCI',' on',... + 'baStatsMode','Gaussian','forceZeroIntercept','on', 'diffValueMode', 'percent'); + + %LCModel ref Fits vs subfits + rpc_LCModel_32_ave = calculate_rpc_percent(metConcAllSubjLCModelScaled_(1:11,1), metConcAllSubjLCModelScaled_(12:22,1)); + rpc_LCModel_64_ave = calculate_rpc_percent(metConcAllSubjLCModelScaled_(1:11,2), metConcAllSubjLCModelScaled_(12:22,2)); + legendText = {['{\color{blue}\bf32-ave: RPC=' mynum2str(rpc_LCModel_32_ave,2) '%}'];['{\color{red}\bf64-ave: RPC=' mynum2str(rpc_LCModel_64_ave,2) '%}']}; + + sLCModel = subplot(subplotsX,subplotsY,runningIndexPlot+subplotsY); + [rpcLCModel, fig, stats] = BlandAltmanOnly(sLCModel, metConcAllSubjRefLCModelScaled_(1:11,:), metConcAllSubjLCModelScaled_(12:22,:), ... + label_refit,[metabolitesToDisplay{indexMet}], legendText,... + 'corrInfo',corrinfo,'baInfo',BAinfo_refit,'axesLimits',limits,'colors','br', 'showFitCI',' on',... + 'baStatsMode','Gaussian','forceZeroIntercept','on', 'diffValueMode', 'percent'); + + if mod(indexMet,subplotsY)==1 + pos1 = sProFit.Position; + annotation('textarrow', [pos1(1), 0], [pos1(2)+pos1(4)/2, 0],'String',softwareNames{1}, ... + 'HeadStyle','none','LineStyle', 'none', 'TextRotation',90,'units','normalized', 'FontSize', 16, ... + 'FontWeight','bold','HorizontalAlignment','center', 'VerticalAlignment','middle'); + pos2 = sLCModel.Position; + annotation('textarrow', [pos1(1), 0], [pos2(2)+pos2(4)/2, 0],'String',softwareNames{2}, ... + 'HeadStyle','none','LineStyle', 'none', 'TextRotation',90,'units','normalized', 'FontSize', 16, ... + 'FontWeight','bold','HorizontalAlignment','center', 'VerticalAlignment','middle'); + end + rpc_table{indexMet+2,2} = rpc_ProFit_32_ave; + rpc_table{indexMet+2,3} = rpc_ProFit_64_ave; + rpc_table{indexMet+2,4} = rpc_LCModel_32_ave; + rpc_table{indexMet+2,5} = rpc_LCModel_64_ave; +end + +rpc_values = cell2mat(rpc_table(3:end-3,2:5)); +rpc_meanProFit_32ave_main = mean(rpc_values(indecesMainMet,1)); +rpc_meanProFit_64ave_main = mean(rpc_values(indecesMainMet,2)); +rpc_meanLCModel_32ave_main = mean(rpc_values(indecesMainMet,3)); +rpc_meanLCModel_64ave_main = mean(rpc_values(indecesMainMet,4)); +rpc_table(3:end-3,2:5) = sprintfc('%.0f',rpc_values); +rpc_table{end-1,2} = num2str(rpc_meanProFit_32ave_main, '%.0f'); +rpc_table{end-1,3} = num2str(rpc_meanProFit_64ave_main, '%.0f'); +rpc_table{end-1,4} = num2str(rpc_meanLCModel_32ave_main, '%.0f'); +rpc_table{end-1,5} = num2str(rpc_meanLCModel_64ave_main, '%.0f'); +rpc_meanProFit_32ave = mean(rpc_values(:,1)); +rpc_meanProFit_64ave = mean(rpc_values(:,2)); +rpc_meanLCModel_32ave = mean(rpc_values(:,3)); +rpc_meanLCModel_64ave = mean(rpc_values(:,4)); +rpc_table{end,2} = num2str(rpc_meanProFit_32ave, '%.0f'); +rpc_table{end,3} = num2str(rpc_meanProFit_64ave, '%.0f'); +rpc_table{end,4} = num2str(rpc_meanLCModel_32ave, '%.0f'); +rpc_table{end,5} = num2str(rpc_meanLCModel_64ave, '%.0f'); +xlswrite([pathBaseExportFiles, 'InVivoResults_RPC.xlsx'], rpc_table) + +%% code will break here. This used to be the old style plotting/results without Bland-Altman plots. +meanMetDeviation = mean(abs(metaboliteConcentrationsAllSubjNorm), 'omitnan'); +stdMetDeviation = std(abs(metaboliteConcentrationsAllSubjNorm), 'omitnan'); + +meanAllMetDeviation = mean(abs(metaboliteConcentrationsAllSubjNorm(:)), 'omitnan'); +stdAllMetDeviation = std(abs(metaboliteConcentrationsAllSubjNorm(:)), 'omitnan'); + +mainMetaboliteConcentrationsAllSubj = metaboliteConcentrationsAllSubjNorm(:, indecesMainMet); +meanMainMetDeviation = mean(abs(mainMetaboliteConcentrationsAllSubj(:)), 'omitnan'); +stdMainMetDeviation = std(abs(mainMetaboliteConcentrationsAllSubj(:)), 'omitnan'); + +metaboliteTable = cell(numberOfMet+3,2); +metaboliteTable(2:numberOfMet+1,1) = metabolitesLabels; +metaboliteTable{numberOfMet+2,1} = 'Mean'; +metaboliteTable{numberOfMet+3,1} = 'Mean Main Metabolites'; + +plusMinusSign = char(177); +metaboliteTable{1,2} = SoftwareName; + +for indexMet = 1:numberOfMet + metaboliteTable{indexMet+1,2} = [num2str(meanMetDeviation(indexMet),'%.1f'), plusMinusSign, num2str(stdMetDeviation(indexMet),'%.1f')]; +end + +metaboliteTable{numberOfMet+2,2} = [num2str(meanAllMetDeviation,'%.1f'), plusMinusSign, num2str(stdAllMetDeviation,'%.1f')]; +metaboliteTable{numberOfMet+3,2} = [num2str(meanMainMetDeviation,'%.1f'), plusMinusSign, num2str(stdMainMetDeviation,'%.1f')]; + +xlswrite([pathBaseExportFiles, 'InVivoResults' SoftwareName, '.xlsx'], metaboliteTable) +% +% mean(cell2mat(NAA_SNR_all(:,1))) +% std(cell2mat(NAA_SNR_all(:,1))) +% mean(cell2mat(NAA_SNR_all(:,2))) +% mean(cell2mat(NAA_SNR_all(:,3))) +% mean(cell2mat(NAA_SNR_all(:,4))) +% mean(cell2mat(NAA_SNR_all(:,5))) +% std(cell2mat(NAA_SNR_all(:,5))) + +end + +function metaboliteConcentrations = matchFittedMetabolites(fitLCModel, currentConcentration, metabolitesNames, proFitIteration, activeMetabolites) +metaboliteConcentrations = zeros(size(metabolitesNames)); + +if fitLCModel + activeMetabolites = currentConcentration(1,:); + currentConcentration = currentConcentration(2,:); +else + activeMetabolites = activeMetabolites{proFitIteration}; + currentConcentration = currentConcentration{proFitIteration}; +end +for indexMet = 1 : length(metabolitesNames) + indexMetFit = find(strcmp(activeMetabolites,metabolitesNames(indexMet))); + if fitLCModel + metaboliteConcentrations(indexMet) = currentConcentration{indexMetFit}; + else + metaboliteConcentrations(indexMet) = currentConcentration(indexMetFit); + end +end +% metaboliteConcentrations(1) = metaboliteConcentrations(1) / 1e6; % adjust the MMB to be within range +end + +function [metaboliteConcentrationsAllSubj, metaboliteConcentrationsAllSubjRef, metaboliteConcentrationsAllSubjNorm,... + MC_H2O_ConcentrationsAllSubj, MC_H2O_ConcentrationsAllSubjRef] = ... + getAllMetaboliteConc(dataExportPathBase, dataExportPathBaseRef, truncSuffix, subjects, TEs, ... + namingSuffixesAve, namingSuffixesCoil, fitLCModel, reconOption, ... + numberOfMet, metabolitesLCModel, metabolitesProFit, metabolitesLabels, indecesMainMet, ... + offsetScatter, markerScatter, markerColor) +% settings +plotInSameFigureAllSubjects = true; +scalingFactorColor = 1; +yLimValue = 50; +NAA_SNR_global_ref = 700;% 650; for truncOn true + + +if fitLCModel + SoftwareName = 'LCModel'; + indexFigSoftware = 0; +else + SoftwareName = 'ProFit'; + indexFigSoftware = 50; + proFitIteration =4; +end + +% prepare arrays etc numberOfSubjects = length(subjects); dataExportPathRef = cell(1,numberOfSubjects); dataExportPath = cell(1,numberOfSubjects); @@ -82,29 +390,48 @@ for indexSubj = 1:numberOfSubjects dataExportPathRef{indexSubj} = [dataExportPathBaseRef subjects{indexSubj} '\\']; dataExportPath{indexSubj} = [dataExportPathBase subjects{indexSubj} '\\']; end - -numberOfTEs = length(TEs); figId = figure(); colormapVect = colormap(); close(figId); colormapVect = colormapVect(end:-1:1, :); +numberOfTEs = length(TEs); numberOfColors = size(colormapVect,1); -scalingFactorColor = 1; -yLimValue = 50; -NAA_SNR_global_ref = 700;% 650; for truncOn true - -%% do the actual plotting NAA_SNR_all = cell(numberOfSubjects, numberOfTEs); -for indexSubj = 1:numberOfSubjects/2 +meanPercentualChange = 0; +iterator = 0; +nansIterator = 0; +meanFQN = 0; +meanFQN2 = 0; +numOfSimulations = length(namingSuffixesAve)*length(namingSuffixesCoil); +metaboliteConcentrationsAllSubjNorm = zeros(numberOfSubjects * numOfSimulations, numberOfMet); +MC_H2O_ConcentrationsAllSubj = zeros(numberOfSubjects, numOfSimulations); +metaboliteConcentrationsAllSubj = zeros(numberOfSubjects, numOfSimulations, numberOfMet); +metaboliteConcentrationsAllSubjRef = zeros(numberOfSubjects, numberOfMet); +MC_H2O_ConcentrationsAllSubjRef = zeros(numberOfSubjects, 1); +%% do the actual plotting +for indexSubj = 1:numberOfSubjects if fitLCModel load([dataExportPathRef{indexSubj}, 'concentrations' truncSuffix '.mat'], 'concentrations'); + load([dataExportPathRef{indexSubj}, 'concentrations', truncSuffix '_MC_H2O.mat'], 'concentrations_MC_H2O'); concentrationsRef = concentrations; + concentrations_MC_H2ORef = concentrations_MC_H2O; load([dataExportPath{indexSubj}, 'concentrations' truncSuffix '.mat'], 'concentrations'); + load([dataExportPath{indexSubj}, 'concentrations', truncSuffix '_MC_H2O.mat'], 'concentrations_MC_H2O'); else - load([dataExportPathRef{indexSubj}, 'concentrations' truncSuffix '_profit.mat'], 'concentrations', 'activeMetabolites'); - concentrationsRef = concentrations; + load([dataExportPathRef{indexSubj}, 'concentrations' truncSuffix '_profit.mat'], 'concentrations', 'activeMetabolites', 'FQNs', 'FQNs2'); + load([dataExportPathRef{indexSubj}, 'concentrations', truncSuffix '_H2O_profit.mat'], 'concentrations_H2O'); + load([dataExportPathRef{indexSubj}, 'concentrations', truncSuffix '_MC_H2O_profit.mat'], 'concentrations_MC_H2O'); + concentrationsRef = concentrations; + concentrations_H2ORef = cell2mat(concentrations_H2O); + concentrations_MC_H2ORef = cell2mat(concentrations_MC_H2O); activeMetabolitesRef = activeMetabolites; - load([dataExportPath{indexSubj}, 'concentrations' truncSuffix '_profit.mat'], 'concentrations', 'activeMetabolites'); + FQNsRef = FQNs; + FQNsRef2 = FQNs2; + load([dataExportPath{indexSubj}, 'concentrations' truncSuffix '_profit.mat'], 'concentrations', 'activeMetabolites', 'FQNs', 'FQNs2'); + load([dataExportPath{indexSubj}, 'concentrations', truncSuffix '_H2O_profit.mat'], 'concentrations_H2O'); + load([dataExportPath{indexSubj}, 'concentrations', truncSuffix '_MC_H2O_profit.mat'], 'concentrations_MC_H2O'); + concentrations_H2O = cell2mat(concentrations_H2O); + concentrations_MC_H2O = cell2mat(concentrations_MC_H2O); end % load stats (SNR, FWHM, etc) load([dataExportPathRef{indexSubj}, 'stats' truncSuffix '.mat'], 'stats'); @@ -113,9 +440,14 @@ for indexSubj = 1:numberOfSubjects/2 %% for indexTE = 1:numberOfTEs if plotInSameFigureAllSubjects - indexFigure = TEs(indexTE); + indexFigure = TEs(indexTE)+indexFigSoftware; else - indexFigure = str2double(subjects{indexSubj})*100 + TEs(indexTE); + indexFigure = str2double(subjects{indexSubj})*100 + TEs(indexTE)+indexFigSoftware; + meanPercentualChange = 0; + iterator = 0; + nansIterator = 0; + meanFQN = 0; + meanFQN2 = 0; end %get Reference figure(indexFigure); @@ -126,30 +458,39 @@ for indexSubj = 1:numberOfSubjects/2 water_ref_amplitude = currentStatsRef{end,4}; currentColorRef = colormapVect(round(NAA_ref_SNR/NAA_ref_SNR/scalingFactorColor * numberOfColors),:); currentConcentrationRef = concentrationsRef{indexTE,1, 1}; + if fitLCModel - metaboliteNamesRef = currentConcentrationRef(1,2:3:end-2); - metaboliteConcentrationsRef = cell2mat(currentConcentrationRef(2,2:3:end-2)); - metaboliteConcentrationsRef(1) = metaboliteConcentrationsRef(1) / 1e6; % adjust the MMB to be within range +% MC_H2O_ConcentrationsRef = concentrations_MC_H2ORef{indexTE,1, 1}; +% MC_H2O_ConcentrationsAllSubjRef(indexSubj) = MC_H2O_ConcentrationsRef{2,2}; + metaboliteConcentrationsRef = matchFittedMetabolites(fitLCModel, currentConcentrationRef, metabolitesLCModel, [], []); + metaboliteConcentrationsRef(end) = metaboliteConcentrationsRef(end) .* 1e-8; else - metaboliteNamesRef = activeMetabolitesRef{3}; - metaboliteConcentrationsRef = currentConcentrationRef{3}; -% metaboliteConcentrationsRef(1) = metaboliteConcentrationsRef(1) / 1e6; % adjust the MMB to be within range + metaboliteConcentrationsRef_notScaled = matchFittedMetabolites(fitLCModel, currentConcentrationRef, metabolitesProFit, proFitIteration, activeMetabolitesRef); + %scale the concentations similarly as LCModel + metaboliteConcentrationsRef = metaboliteConcentrationsRef_notScaled * 40873 / concentrations_H2ORef * 2; +% MC_H2O_ConcentrationsRef = concentrations_MC_H2ORef * 40873 / concentrations_H2ORef * 2; +% MC_H2O_ConcentrationsAllSubjRef(indexSubj) = MC_H2O_ConcentrationsRef; + end + if ~fitLCModel + currentFQNRef = FQNsRef{indexTE,1, 1}; + FQN_Ref = currentFQNRef{proFitIteration}; + currentFQNRef2 = FQNsRef2{indexTE,1, 1}; + FQN_Ref2 = currentFQNRef2{proFitIteration}; end %scale with the MC water reference amplitude - metaboliteConcentrationsRef = metaboliteConcentrationsRef ./ water_ref_amplitude; metaboliteConcentrationsRefNormalized = (metaboliteConcentrationsRef-metaboliteConcentrationsRef) ./ metaboliteConcentrationsRef *100; - numberMetabolitesRef = length(metaboliteConcentrationsRef); - scatter(1:numberMetabolitesRef,metaboliteConcentrationsRefNormalized,[],'x', 'MarkerEdgeColor', currentColorRef); - -% cb = colorbar; -% cb.Limits = [0 NAA_ref_SNR*scalingFactorColor]; -% cb.Color = colormapVect - - metaboliteConcentrationsAll = zeros(length(namingSuffixesAve)*length(namingSuffixesCoil), numberMetabolitesRef); + scatter([1:numberOfMet]-offsetScatter,metaboliteConcentrationsRefNormalized,[],'d', 'MarkerEdgeColor', currentColorRef); + + metaboliteConcentrationsAllSubjRef(indexSubj, :) = metaboliteConcentrationsRef; + % cb = colorbar; + % cb.Limits = [0 NAA_ref_SNR*scalingFactorColor]; + % cb.Color = colormapVect + + metaboliteConcentrationsAll = zeros(numOfSimulations, numberOfMet); % do plotting for each individual case for indexAverageDelete = 1: length(namingSuffixesAve) for indexCoilDelete = 1: length(namingSuffixesCoil) - runningIndex = indexAverageDelete * length(namingSuffixesCoil) + indexCoilDelete; + runningIndex = (indexAverageDelete-1) * length(namingSuffixesCoil) + indexCoilDelete; currentStats = stats{indexTE,indexAverageDelete, indexCoilDelete}; currentConcentration = concentrations{indexTE,indexAverageDelete, indexCoilDelete}; if ~isempty(currentConcentration) @@ -158,32 +499,50 @@ for indexSubj = 1:numberOfSubjects/2 figure(indexFigure); hold on if fitLCModel - metaboliteNames = currentConcentration(1,2:3:end-2); - metaboliteConcentrations = cell2mat(currentConcentration(2,2:3:end-2)); - metaboliteConcentrations(1) = metaboliteConcentrations(1) / 1e6; % adjust the MMB to be within range +% MC_H2O_Concentrations = concentrations_MC_H2O{indexTE,indexAverageDelete, indexCoilDelete}; +% MC_H2O_ConcentrationsAllSubj(indexSubj, runningIndex) = MC_H2O_Concentrations{2,2}; + metaboliteConcentrations = matchFittedMetabolites(fitLCModel, currentConcentration, metabolitesLCModel, [], []); + metaboliteConcentrations(end) = metaboliteConcentrations(end) .* 1e-8; else - metaboliteNames = activeMetabolites{3}; - metaboliteConcentrations = currentConcentration{3}; - % metaboliteConcentrationsRef(1) = metaboliteConcentrationsRef(1) / 1e6; % adjust the MMB to be within range + metaboliteConcentrations_notScaled = matchFittedMetabolites(fitLCModel, currentConcentration, metabolitesProFit, proFitIteration, activeMetabolites); + %scale the concentations similarly as LCModel + metaboliteConcentrations = metaboliteConcentrations_notScaled * 40873 / concentrations_H2O(runningIndex) * 2; +% MC_H2O_Concentrations = concentrations_MC_H2O(runningIndex) * 40873 / concentrations_H2O(runningIndex) * 2; +% MC_H2O_ConcentrationsAllSubj(indexSubj, runningIndex) = MC_H2O_Concentrations; end - %scale with the MC water reference amplitude - metaboliteConcentrations = metaboliteConcentrations ./ water_amplitude; - numberMetabolites = length(metaboliteConcentrations); - if numberMetabolites ~= numberMetabolitesRef - error('numberMetabolites not identical to numberMetabolitesRef'); + if runningIndex <= 3 %scale with coresponding averages + metaboliteConcentrations = metaboliteConcentrations * 3; + MC_H2O_ConcentrationsAllSubj(indexSubj, runningIndex) = MC_H2O_ConcentrationsAllSubj(indexSubj, runningIndex) * 3; + else + metaboliteConcentrations = metaboliteConcentrations *3/2; + MC_H2O_ConcentrationsAllSubj(indexSubj, runningIndex) = MC_H2O_ConcentrationsAllSubj(indexSubj, runningIndex) *3/2; end + if ~fitLCModel + currentFQN = FQNs{indexTE,indexAverageDelete, indexCoilDelete}; + FQN = currentFQN{proFitIteration}; + meanFQN = meanFQN + FQN; + currentFQN2 = FQNs2{indexTE,indexAverageDelete, indexCoilDelete}; + FQN2 = currentFQN2{proFitIteration}; + meanFQN2 = meanFQN2 + FQN2; + end metaboliteConcentrationsNormalized = (metaboliteConcentrations-metaboliteConcentrationsRef) ... ./ metaboliteConcentrationsRef *100; metaboliteConcentrationsAll(runningIndex, :) = metaboliteConcentrationsNormalized; - metaboliteConcentrationsNormalized(abs(metaboliteConcentrationsNormalized) > yLimValue) = yLimValue; + metaboliteConcentrationsNormalized(abs(metaboliteConcentrationsNormalized) > yLimValue*2) = NaN; %TODO change! This is actually stupid + metaboliteConcentrationsAllSubjNorm(runningIndex + (indexSubj-1)*numOfSimulations, :) = metaboliteConcentrationsNormalized; + metaboliteConcentrationsAllSubj(indexSubj, runningIndex, :) = metaboliteConcentrations; if reconOption>4 %use this scatter if you want to check if there are structural offsets - scatter([1:numberMetabolites]+offsetScatter,metaboliteConcentrationsNormalized, markerScatter, 'MarkerEdgeColor', markerColor, 'LineWidth', 1); +% scatter([1:numberOfMet]+offsetScatter,metaboliteConcentrationsNormalized, markerScatter, 'MarkerEdgeColor', markerColor, 'LineWidth', 1); else % SNR matched currentColor = colormapVect(round(NAA_SNR/NAA_SNR_global_ref/scalingFactorColor * numberOfColors),:); - scatter([1:numberMetabolites]+offsetScatter,metaboliteConcentrationsNormalized, markerScatter, 'MarkerEdgeColor',currentColor, 'LineWidth', 2); +% scatter([1:numberOfMet]+offsetScatter,metaboliteConcentrationsNormalized, markerScatter, 'MarkerEdgeColor',currentColor, 'LineWidth', 2); end + currentNans = isnan(metaboliteConcentrationsNormalized); + nansIterator = nansIterator + currentNans; + meanPercentualChange = meanPercentualChange + abs(metaboliteConcentrationsNormalized); + iterator = iterator + ~(currentNans); end end end @@ -191,25 +550,56 @@ for indexSubj = 1:numberOfSubjects/2 cb = colorbar('XTickLabel',num2str(round(xticksSNR)'), 'Direction','reverse'); ylabel(cb,'SNR_{NAA(CH3)}'); -% boxplot(metaboliteConcentrationsAll); - xticks(1:numberMetabolitesRef); - xticklabels(metaboliteNamesRef); + % boxplot(metaboliteConcentrationsAll); + xticks(1:numberOfMet); + xticklabels(metabolitesLabels); xtickangle(45) - title(['Subject: ', subjects{indexSubj}, ' TE ', num2str(TEs(indexTE)) ' ms']); ylim([-yLimValue,yLimValue]); xlim([0.5,17.5]) - ylabel('Concentration change [%]') - end + ylabel('Concentration change c_{k,%} (%)') + + mainMetMeanChange = meanPercentualChange(indecesMainMet); + mainMetNaNs = nansIterator(indecesMainMet); + mainMetIterator = iterator(indecesMainMet); + + title(SoftwareName) + if fitLCModel + title([SoftwareName ... ' Subject: ', subjects{indexSubj}, ' TE ', num2str(TEs(indexTE)) ' ms'... + ' - mean change (main mets): ', num2str(mean(meanPercentualChange./iterator,'omitnan'),3) '%; '... + ' (', num2str(mean(mainMetMeanChange./mainMetIterator,'omitnan'),3) '%); '... + num2str(sum(nansIterator)), ' (', num2str(sum(mainMetNaNs)), ') NaNs'... + ]); + else + title([SoftwareName ... ' Subject: ', subjects{indexSubj}, ' TE ', num2str(TEs(indexTE)) ' ms'... + ' - mean change (main mets): ', num2str(mean(meanPercentualChange./iterator,'omitnan'),3) '%; '... + ' (', num2str(mean(mainMetMeanChange./mainMetIterator,'omitnan'),3) '%); '... + num2str(sum(nansIterator)), ' (', num2str(sum(mainMetNaNs)), ') NaNs'... + ', FQN_{Ref}:' num2str(FQN_Ref/numberOfSubjects,3), ', FQN_{mean}:' num2str(meanFQN/max(iterator),3)... + ', FQN_{Ref}:' num2str(FQN_Ref2/numberOfSubjects,3), ', FQN_{mean}:' num2str(meanFQN2/max(iterator),3)... + ]); + end + end end -% -% mean(cell2mat(NAA_SNR_all(:,1))) -% std(cell2mat(NAA_SNR_all(:,1))) -% mean(cell2mat(NAA_SNR_all(:,2))) -% mean(cell2mat(NAA_SNR_all(:,3))) -% mean(cell2mat(NAA_SNR_all(:,4))) -% mean(cell2mat(NAA_SNR_all(:,5))) -% std(cell2mat(NAA_SNR_all(:,5))) - end +function rpc = calculate_rpc_percent(dataS1, dataS2) + data.set1 = dataS1; + data.set2 = dataS2; + s = size(data.set1); + if ~isequal(s,size(data.set2)) + error('data1 and data2 must have the same size'); + end + + data.set1 = reshape(data.set1, [numel(data.set1),1]); + data.set2 = reshape(data.set2, [numel(data.set2),1]); + data.mask = isfinite(data.set1) & isnumeric(data.set1) & isfinite(data.set2) & isnumeric(data.set2); + data.maskedSet1 = data.set1(data.mask); + data.maskedSet2 = data.set2(data.mask); + + data.maskedBaRefData = mean([data.maskedSet1,data.maskedSet2],2); + data.maskedDifferences = (data.maskedSet2-data.maskedSet1) ./ data.maskedBaRefData*100; + + differenceSTD = std(data.maskedDifferences, 'omitnan'); + rpc = 1.96*differenceSTD; +end \ No newline at end of file diff --git a/createTestData/reconstruct_all_test_data_profit.m b/createTestData/reconstruct_all_test_data_profit.m index 2164c58662b36e3e993eb81229c2bd87da136fda..37725db861f441041cffb67e2fa55e12bfcc24b5 100644 --- a/createTestData/reconstruct_all_test_data_profit.m +++ b/createTestData/reconstruct_all_test_data_profit.m @@ -1,9 +1,30 @@ -function reconstruct_all_test_data_profit() - -reconstruct_water_references = false; - -reconOption = 4; -truncOn = false; +function rand_indeces = reconstruct_all_test_data_profit(subjects, reconstruct_water_references, reconOption, truncOn, rand_indeces) +% reconstruct test data to +%input arguments: +% subjects - mandatory parameter. Should be a cell array of the subjectIDs +% reconstruct_water_references = true or false: to reconstruct water reference data +% reconOption: +% 0 = Water References +% 1 = Normal recon +% 2 = Removed averages +% 3 = Removed coils +% 4 = Removed averages and coils +% 5 = Water Supp Off +% 6 = Frequency Alignment Off +% 7 = Rescale off +% 8 = Rescale Water Supp Off +% truncOn = true or false: to truncate or not the data: both as first and last step of the data reconstruction +% rand_indeces = random indeces permutating the subjects. Should not be stored to assure correct anonimization + +if ~exist('reconstruct_water_references','var') + reconstruct_water_references = false; +end +if ~exist('reconOption','var') + reconOption = 1; +end +if ~exist('truncOn','var') + truncOn = false; +end exportFolders = {'0 Water References',... '1 Normal recon', '2 Removed averages ','3 Removed coils',... @@ -95,32 +116,27 @@ end %% import file setup pathName = 'DF data path'; -subjects = { ... - '1658' ... - '1717' ... - '2017' ... - '3373' ... - '3490' ... - '5771' ... - '6249' ... - '6971' ... - '7338' ... - '7782' ... - '9810' ... - }; + +numberOfSubjects = length(subjects); +if ~exist('rand_indeces','var') + [~,rand_indeces] = sort(rand(1,numberOfSubjects)); +end +anonimizedSubjects = cell(1,numberOfSubjects); +for indexSubj = 1 : numberOfSubjects + anonimizedSubjects{indexSubj} = strcat('Subj_', num2str(rand_indeces(indexSubj))); +end pathBaseRawFiles = pathToDataFolder(pathName, subjects); TEs = [24; 32; 40; 52; 60]; -numberOfSubjects = length(subjects); paths = cell(1,numberOfSubjects); waterExportPath = cell(1,numberOfSubjects); dataExportPath = cell(1,numberOfSubjects); for indexSubj = 1:numberOfSubjects paths{indexSubj} = [pathBaseRawFiles subjects{indexSubj} '\\']; - waterExportPath{indexSubj} = [waterExportPathBase subjects{indexSubj} '\\']; - dataExportPath{indexSubj} = [dataExportPathBase subjects{indexSubj} '\\']; + waterExportPath{indexSubj} = [waterExportPathBase anonimizedSubjects{indexSubj} '\\']; + dataExportPath{indexSubj} = [dataExportPathBase anonimizedSubjects{indexSubj} '\\']; end files_TE24 = cell(1, numberOfSubjects); @@ -153,19 +169,21 @@ end %% do the actual reconstruction parfor indexSubj = 1:numberOfSubjects - filenameWater = [waterExportPath{indexSubj} subjects{indexSubj} '_water.mat']; + filenameWater = [waterExportPath{indexSubj} anonimizedSubjects{indexSubj} '_water.mat']; if reconstruct_water_references %% water data [aWater] = reconstructWater(waterFilesPath{indexSubj}); mkdir(waterExportPath{indexSubj}); - aWater.ExportLcmRaw(waterExportPath{indexSubj}, [subjects{indexSubj}, '_water'], addSinglet0ppm); + aWater = aWater.Anonimize_MR_spectroS(rand_indeces(indexSubj)); + aWater.ExportLcmRaw(waterExportPath{indexSubj}, [anonimizedSubjects{indexSubj}, '_water'], addSinglet0ppm); %calculate scaling factor the summedSpectra individually according to water peak waterData = aWater.Data{1}; maxWaterPeak = max(real(fftshift(fft(waterData)))); - save(filenameWater, 'aWater', 'maxWaterPeak'); + parsaveWater(filenameWater, aWater, maxWaterPeak); else if exist(filenameWater,'file') % does not work in parfor load(filenameWater,'maxWaterPeak') + maxWaterPeak = parloadWater(filenameWater); else maxWaterPeak = 1; end @@ -184,8 +202,9 @@ parfor indexSubj = 1:numberOfSubjects [a, stats{indexTE,indexAverageDelete, indexCoilDelete}] = ... reconstruct_testData(filesPath{indexTE, indexSubj}, flagsReconstruct, ... averages2Keep, coilChannels2Delete); + a = a.Anonimize_MR_spectroS(rand_indeces(indexSubj)); TE_string = ['TE', num2str(TEs(indexTE))]; - filenameData = [ subjects{indexSubj}, '_', TE_string namingSuffixAve namingSuffixCoil truncSuffix]; + filenameData = [ anonimizedSubjects{indexSubj}, '_', TE_string namingSuffixAve namingSuffixCoil truncSuffix]; mkdir(dataExportPath{indexSubj}); dataExportPathTE = [dataExportPath{indexSubj}, '\\', TE_string, '\\']; mkdir(dataExportPathTE); @@ -208,6 +227,14 @@ close all end +function parsaveWater(fname, aWater, maxWaterPeak) +save(fname, 'aWater', 'maxWaterPeak') +end + +function maxWaterPeak = parloadWater(fname) +load(fname, 'maxWaterPeak') +end + function parsave(fname, a) save(fname, 'a') end diff --git a/createTestData/reconstruct_all_test_data_profit_anonimizing_function.m b/createTestData/reconstruct_all_test_data_profit_anonimizing_function.m new file mode 100644 index 0000000000000000000000000000000000000000..bfdc67340bb304af579b0f53949dad1788dac154 --- /dev/null +++ b/createTestData/reconstruct_all_test_data_profit_anonimizing_function.m @@ -0,0 +1,38 @@ +function reconstruct_all_test_data_profit_anonimizing_function() +% this is not a fully anonimized function. Do not add to final repository +subjects = { ... + '1658' ... + '1717' ... + '2017' ... + '3373' ... + '3490' ... + '5771' ... + '6249' ... + '6971' ... + '7338' ... + '7782' ... + '9810' ... + }; + +[~,rand_indeces] = sort(rand(1,length(subjects))); +save('randIndices.mat','rand_indeces'); %saved only for the case the for loop crashes +for indexTrunc = 1:2 + if indexTrunc == 1 + truncOn = true; + else + truncOn = false; + end + for reconOption = 1:8 + if reconOption == 1 + reconstruct_water_references = true; + reconstruct_all_test_data_profit(subjects, ... + reconstruct_water_references, reconOption, truncOn, rand_indeces); + else + reconstruct_water_references = false; + reconstruct_all_test_data_profit(subjects,... + reconstruct_water_references, reconOption, truncOn, rand_indeces); + end + end +end +delete 'randIndices.mat'; % delete the random indices, and hence assure the additional level of anonimization +end \ No newline at end of file diff --git a/fitting/makeBasis_pH_sweep.m b/fitting/makeBasis_pH_sweep.m index 5959c5063d38c7f9bbba87c43289b3b3c71f0ad9..665fce8be4f37f4a4a0159395e78efc18cd3cb14 100644 --- a/fitting/makeBasis_pH_sweep.m +++ b/fitting/makeBasis_pH_sweep.m @@ -12,7 +12,7 @@ pH_values = [6.9:0.01:7.1]'; pH_values = [7.1:0.01:7.15]'; pH_values = [7.0:0.01:7.09]'; % pH_values = [7.0:0.01:7.15]'; -% pH_values = [6.9:0.01:7.15]'; +pH_values = [6.9:0.01:7.15]'; % pH_values = [7.09]'; pH_valuesSting = cellstr(num2str(pH_values, '%.2f')); pH_default = '7.00'; @@ -24,6 +24,7 @@ if moietyFit if imidazoleFit %DF makeBasisFilesBase = 'sLASER_7ppm_moiety_imidazole_'; + makeBasisFilesBase = 'sLASER_7ppm_moiety_imidazole_newNAA_'; % makeBasisFilesBase = 'deGraaf_sLASER_7ppm_moiety_imidazole_'; else %DF @@ -47,8 +48,8 @@ makeBasisFilesPathRemote = '/Desktop/DATA_df/Basis_sets/pH_sweep/'; makeBasisFilesPathLocal = [localFilePathBase, 'Basis_sets/pH_sweep/']; if imidazoleFit -LCModelBasisOutputFilesPathRemote = '/Desktop/DATA_df/Basis_sets/pH_sweep/BasisImidazole/'; -LCModelBasisOutputPath = [localFilePathBase, 'Basis_sets/pH_sweep/BasisImidazole/']; +LCModelBasisOutputFilesPathRemote = '/Desktop/DATA_df/Basis_sets/pH_sweep/NewBasisImidazole_deGraaf/'; +LCModelBasisOutputPath = [localFilePathBase, 'Basis_sets/pH_sweep/NewBasisImidazole_deGraaf/']; else LCModelBasisOutputFilesPathRemote = '/Desktop/DATA_df/Basis_sets/pH_sweep/BasisFull/'; LCModelBasisOutputPath = [localFilePathBase, 'Basis_sets/pH_sweep/BasisFull/']; diff --git a/howIsFittingDone.m b/howIsFittingDone.m new file mode 100644 index 0000000000000000000000000000000000000000..bb631182c83af1d9ee26fd035891547d80631665 --- /dev/null +++ b/howIsFittingDone.m @@ -0,0 +1,273 @@ +function howIsFittingDone() + +%% Concentrations and T2 values taken from the Murali Manohar MRM 2019 paper +% Concentration values were down or upscaled a bit to match better the literature comparison, if they were needed (Table 3) +% Values were rounded, standard deviations increased for values where possible mismatch with literature could be assumed. Both for concentrations and T2s +% Default T2 value taken for the metabolites, where these were not determined in the paper: GABA, Lac, Scyllo, Tau were taken as 75+-35ms +metabolites = {'Asp', 'tCr(CH2)', 'tCr(CH3)', 'GABA', 'Gln', 'Glu', 'Glyc', 'GSH', 'Lac', 'mI', 'NAA(CH3)', 'NAA(CH2)', 'NAAG', 'tCho+', 'Scy', 'Tau', 'MMB'}; +% filenames = {'Asp', 'Cr_CH2', 'Cr', 'GABA', 'Gln', 'Glu', 'Glyc', 'GSH', 'Lac', 'mI', 'NAA_ac', 'NAA_as', 'NAAG', 'tCho_P', 'Scyllo', 'Tau', 'Leu'}; +concentrations = [ 3, 8.5, 8.5, 1.8, 3, 9, 1.2, 1.4, 0.7, 5.5, 12, 12, 1.4, 1.5, 0.4, 1.5, 1.5e7]; %mmol/kg +conc_std = [0.8, 0.7, 0.7, 0.5, 0.8, 1, 0.3, 0.2, 0.2, 0.5, 1, 1, 0.3, 0.4, 0.1, 0.3, 0.2e7]; %mmol/kg +T2s = [ 54, 82, 100, 75, 50, 85, 60, 75, 75, 90, 110, 100, 45, 90, 75, 75, 25]; %ms +T2_std = [ 12, 10, 16, 35, 20, 25, 10, 35, 35, 20, 30, 25, 20, 25, 35, 35, 10]; %ms + +TE = 24 * 1e-3; +numMetabolites = length(metabolites); + +saveData = false; + +%% path to the export of the spectra +exportFolder = {'11 Simulations'}; +pathNameExport = 'ProFit test data'; +pathBaseExportFiles = pathToDataFolder(pathNameExport, exportFolder); +dataExportPathBase = strcat(pathBaseExportFiles, exportFolder{1}, '\'); + +%% +metaboliteFileNames = metabolites; +% replace the weirdos +metaboliteFileNames = strrep(metaboliteFileNames, 'tCr(CH2)', 'Cr_singlet_tot_3.925'); +metaboliteFileNames = strrep(metaboliteFileNames, 'tCr(CH3)', 'Cr_singlet_tot_3.028'); +metaboliteFileNames = strrep(metaboliteFileNames, 'NAA(CH3)', 'NAA_2'); +metaboliteFileNames = strrep(metaboliteFileNames, 'NAA(CH2)', 'NAA_1'); +metaboliteFileNames = strrep(metaboliteFileNames, 'tCho+', 'tCho_PE'); +metaboliteFileNames = strrep(metaboliteFileNames, 'Scy', 'Scyllo'); +metaboliteFileNames = strrep(metaboliteFileNames, 'MMB', 'MMB_without_metabolite_TE24'); + +%% paths to the basis set files +pathName = 'DF data path'; +sampleCriteria = {'Basis_sets'}; +[filePath] = pathToDataFolder(pathName, sampleCriteria); + + +filePathBasis = strcat(filePath, 'Basis_sets/final_T2_met_MM_paper/'); +pathMM = 'sLASER_MM/'; +pathMetabolites = 'sLASER_new_UF_7ppm/TE24/'; + +fids = cell(1, numMetabolites); +plotBasis = false; + +for indexMetabolite = 1:numMetabolites + fileName = metaboliteFileNames{indexMetabolite}; + if strcmp(metabolites{indexMetabolite},'MMB') + filePathMetabolite = strcat(filePathBasis, pathMM); + else + filePathMetabolite = strcat(filePathBasis, pathMetabolites); + end + [fid, bandwidth, scanFrequency, metaboliteName, singletPresent] = ... + ImportLCModelBasis(filePathMetabolite, fileName, plotBasis, '1H'); + if strcmp(metabolites{indexMetabolite},'NAA_ac') +% fid = fid * 3; + end + if strcmp(metabolites{indexMetabolite},'MMB') + fids{indexMetabolite}(1,:)= fid(1:4096); % stupid change to make all metabolites 4096 long! + else + fids{indexMetabolite}(1,:)= fid; + end +end + +water_ppm = 4.66; % ppm +nTimepoints = length(fids{1}); +dwellTime = 1/bandwidth; +timePointsSampling =(0:nTimepoints - 1) * dwellTime; +scalingFactorRefPeak = 0.05; + +refFreqPpm = -0; % the reference Frequency for the excitation pulse, given in ppm compared to the water (minus is upfield, + downfield) + +phasePivot_ppm = water_ppm + refFreqPpm;%in ppm +ppmVector = ppmVectorFunction(scanFrequency*1e6, bandwidth, nTimepoints, '1H'); +phase_1_f2_mx = ppmVector-phasePivot_ppm; + +ppmMask = (ppmVector>0.6) & (ppmVector<4.1); + +%I didn't like the DSS amplitude, some stupid code for adjusting it. + FWHM = 1.75; %Hz + T2 = 1/(pi*FWHM)*1e+3; %ms + f = -4.7076 *scanFrequency; %Hz + singlet = scalingFactorRefPeak*0.042*exp(1i*2*pi*f*timePointsSampling).*exp(-timePointsSampling*1e3/T2); + FWHM = 3; %Hz + T2 = 1/(pi*FWHM)*1e+3; %ms + f = -4.7077 *scanFrequency; %Hz + singlet2 = scalingFactorRefPeak*0.0278*exp(1i*2*pi*f*timePointsSampling).*exp(-timePointsSampling*1e3/T2); + + +%% set default values for the parameters +default_noiseLevel = 3; +noiseVector = wgn(1,nTimepoints, default_noiseLevel); +trunc_ms = 200; +truncPoint = floor( trunc_ms/(dwellTime*1e+3)); + +%% create the actual spectra +current_pc0 = 0; +current_pc1 = 0; +current_df2 = zeros(1,numMetabolites); +current_gm = 12; +current_em_std_factor = zeros(1,numMetabolites); +conc_std_factor = zeros(1,numMetabolites); + +indexNAA_ac = find(strcmp('NAA(CH3)',metabolites)); +indexNAA_as = find(strcmp('NAA(CH2)',metabolites)); +fid_NAA_ac = fids{indexNAA_ac}; +fid_NAA_as = fids{indexNAA_as}; +fids_NAA = {fid_NAA_ac, fid_NAA_as}; +concentrations_NAA = [concentrations(indexNAA_ac), concentrations(indexNAA_as)]; +conc_std_NAA = [0 0]; +current_df2_NAA = [0 0]; +conc_std_factor_NAA = [0 0]; +T2s_NAA = [T2s(indexNAA_ac), T2s(indexNAA_as)]; +T2_std_NAA = [0 0]; +current_em_std_factor_NAA = [0 0]; +metabolites_NAA = {'NAA(CH3)', 'NAA(CH2)'}; +metaboliteFileNames_NAA = {metaboliteFileNames{indexNAA_ac}, metaboliteFileNames{indexNAA_as}}; +%% +[simulatedNAA, defaultSummedFidWithNoise, defaultCurrent_em, defaultCurrentConcentrationRm] = ... + createSummedSpectrum(... + fids_NAA, concentrations_NAA, conc_std_NAA, [1000 1000], T2_std_NAA, TE, metabolites_NAA, metaboliteFileNames_NAA, timePointsSampling, phase_1_f2_mx, ppmMask, ... + current_pc0, current_pc1, current_df2_NAA, current_gm*0, current_em_std_factor_NAA, conc_std_factor_NAA, noiseVector, ... + truncPoint, saveData, 'meanConc', [], dwellTime * 1e3, scanFrequency, dataExportPathBase, water_ppm, scalingFactorRefPeak); +scalingFactor = 3 * (1 / max(real(fftshift(fft(simulatedNAA))))); +concentrations_NAA = concentrations_NAA * scalingFactor; +[simulatedNAA, defaultSummedFidWithNoise, defaultCurrent_em, defaultCurrentConcentrationRm] = ... + createSummedSpectrum(... + fids_NAA, concentrations_NAA, conc_std_NAA, [1000 1000], T2_std_NAA, TE, metabolites_NAA, metaboliteFileNames_NAA, timePointsSampling, phase_1_f2_mx, ppmMask, ... + current_pc0, current_pc1, current_df2_NAA, current_gm*0, current_em_std_factor_NAA, conc_std_factor_NAA, noiseVector, ... + truncPoint, saveData, 'meanConc', [], dwellTime * 1e3, scanFrequency, dataExportPathBase, water_ppm, scalingFactorRefPeak); +figure; +hold on +plot(ppmVector, real(fftshift(fft(simulatedNAA-singlet+singlet2))));%I didn't like the DSS amplitude +% plot(ppmVector, real(fftshift(fft(simulatedNAA)))); +plotSetup(); +ylim([-0.11; 3.1]) +title('Simulated NAA') +legend('$$NAA$$', 'Interpreter','latex','Location','NorthWest') +xlim([-0.2 8.2]) + +[simulatedNAA_T2, defaultSummedFidWithNoise, defaultCurrent_em, defaultCurrentConcentrationRm] = ... + createSummedSpectrum(... + fids_NAA, concentrations_NAA, conc_std_NAA, T2s_NAA, T2_std_NAA, TE, metabolites_NAA, metaboliteFileNames_NAA, timePointsSampling, phase_1_f2_mx, ppmMask, ... + current_pc0, current_pc1, current_df2_NAA, current_gm*0, current_em_std_factor_NAA, conc_std_factor_NAA, noiseVector, ... + truncPoint, saveData, 'meanConc', [], dwellTime * 1e3, scanFrequency, dataExportPathBase, water_ppm, scalingFactorRefPeak); +figure; +plot(ppmVector, real(fftshift(fft(simulatedNAA)))); +hold on; +plot(ppmVector, real(fftshift(fft(simulatedNAA_T2))),'r'); +plotSetup(); +ylim([-0.11; 3.1]) +title('Simulated NAA') +legend('$$NAA$$', [10, '$$NAA*exp(-\nu_{e,k}\pi(TE+\overrightarrow{t}))$$'],... + 'Interpreter','latex','Location','NorthWest') +figure; +plot(ppmVector, real(fftshift(fft(simulatedNAA)))); +hold on; +plot(ppmVector, real(fftshift(fft(simulatedNAA_T2))),'r'); +plotSetup(); +ylim([-0.11; 1.2]) +title('Simulated NAA') +legend('$$NAA$$', [10, '$$NAA*exp(-\nu_{e,k}\pi(TE+\overrightarrow{t}))$$'],... + 'Interpreter','latex','Location','NorthWest') + +[simulatedNAA_T2_gm, defaultSummedFidWithNoise, defaultCurrent_em, defaultCurrentConcentrationRm] = ... + createSummedSpectrum(... + fids_NAA, concentrations_NAA, conc_std_NAA, T2s_NAA, T2_std_NAA, TE, metabolites_NAA, metaboliteFileNames_NAA, timePointsSampling, phase_1_f2_mx, ppmMask, ... + current_pc0, current_pc1, current_df2_NAA, current_gm, current_em_std_factor_NAA, conc_std_factor_NAA, noiseVector, ... + truncPoint, saveData, 'meanConc', [], dwellTime * 1e3, scanFrequency, dataExportPathBase, water_ppm, scalingFactorRefPeak); + +figure; +plot(ppmVector, real(fftshift(fft(simulatedNAA)))); +hold on; +plot(ppmVector, real(fftshift(fft(simulatedNAA_T2))),'r'); +plot(ppmVector, real(fftshift(fft(simulatedNAA_T2_gm))),'k'); +plotSetup(); +ylim([-0.11; 1.2]) + +legend('$$NAA$$', [10, '$$NAA \cdot exp(-\nu_{e,k}\pi(TE+\overrightarrow{t}))$$'],... + [10,10, '$$NAA \cdot exp(-\nu_{e,k}\pi(TE+\overrightarrow{t}))\cdot$$',10, '$$\exp\left(\frac{\left(\nu_g\pi\,\vec{t}\right)^2}{4ln\left(2\right)}\right)$$'], ... + 'Interpreter','latex','Location','NorthWest') +title('Simulated NAA') + +figure; +plot(ppmVector, real(fftshift(fft(simulatedNAA)))); +hold on; +plot(ppmVector, real(fftshift(fft(simulatedNAA_T2))),'r'); +plot(ppmVector, real(fftshift(fft(simulatedNAA_T2_gm))),'k'); +plotSetup(); +ylim([-0.11; 0.48]) + +legend('$$NAA$$', [10, '$$NAA \cdot exp(-\nu_{e,k}\pi(TE+\overrightarrow{t}))$$'],... + [10,10, '$$NAA \cdot exp(-\nu_{e,k}\pi(TE+\overrightarrow{t}))\cdot$$',10, '$$\exp\left(\frac{\left(\nu_g\pi\,\vec{t}\right)^2}{4ln\left(2\right)}\right)$$'], ... + 'Interpreter','latex','Location','NorthWest') +title('Simulated NAA') + + +% generate the default spectrum +[simulatedSpectrum, defaultSummedFidWithNoise, defaultCurrent_em, defaultCurrentConcentrationRm] = ... + createSummedSpectrum(... + fids(1:end-1), concentrations(1:end-1), conc_std(1:end-1), T2s(1:end-1), T2_std(1:end-1), TE, metabolites(1:end-1), metaboliteFileNames(1:end-1), timePointsSampling, phase_1_f2_mx, ppmMask, ... + current_pc0, current_pc1, current_df2(1:end-1), current_gm, current_em_std_factor(1:end-1), conc_std_factor(1:end-1), noiseVector, ... + truncPoint, saveData, 'meanConc', [], dwellTime * 1e3, scanFrequency, dataExportPathBase, water_ppm, scalingFactorRefPeak); + +figure; +plot(ppmVector,real(fftshift(fft(simulatedSpectrum)))); +plotSetup(); +xlim([0.6 4.1]) +ylim([-130; 7000]) +set(gca,'ytick',[]); +legend('Metabolites','Interpreter','latex','Location','NorthWest') +title('Simulated Metabolite Spectra') + +% generate the default spectrum +[simulatedSpectrum, defaultSummedFidWithNoise, defaultCurrent_em, defaultCurrentConcentrationRm] = ... + createSummedSpectrum(... + fids, concentrations, conc_std, T2s, T2_std, TE, metabolites, metaboliteFileNames, timePointsSampling, phase_1_f2_mx, ppmMask, ... + current_pc0, current_pc1, current_df2, current_gm, current_em_std_factor, conc_std_factor, noiseVector, ... + truncPoint, saveData, 'meanConc', [], dwellTime * 1e3, scanFrequency, dataExportPathBase, water_ppm, scalingFactorRefPeak); + +figure; +plot(ppmVector,real(fftshift(fft(simulatedSpectrum)))); +hold on +plot(ppmVector,real(fftshift(fft(fids{end}.*exp(-pi* abs(TE + timePointsSampling)).*concentrations(end))))) +plotSetup(); +xlim([0.6 4.1]) +ylim([-130; 7000]) +set(gca,'ytick',[]); + +legend('Metabolites and MMs', [10, 'MM spectrum'],'Interpreter','latex','Location','NorthWest') +title('Simulated Metabolite and MM Spectra') + +% generate the realistic spectrum +current_pc0 = -15; +current_pc1 = 8; +current_df2_ = current_df2 + -20; +[simulatedSpectrumWithAll, summedFidWithNoiseAndAll, defaultCurrent_em, defaultCurrentConcentrationRm] = ... + createSummedSpectrum(... + fids, concentrations, conc_std, T2s, T2_std, TE, metabolites, metaboliteFileNames, timePointsSampling, phase_1_f2_mx, ppmMask, ... + current_pc0, current_pc1, current_df2_, current_gm, current_em_std_factor, conc_std_factor, noiseVector, ... + truncPoint, saveData, 'meanConc', [], dwellTime * 1e3, scanFrequency, dataExportPathBase, water_ppm, scalingFactorRefPeak); + +figure; +plot(ppmVector,real(fftshift(fft(simulatedSpectrum)))); +hold on +plot(ppmVector,real(fftshift(fft(summedFidWithNoiseAndAll))),'Color',[0 114/255 104/255]); +plotSetup(); +xlim([0.6 4.1]) +ylim([-130; 7000]) +set(gca,'ytick',[]); + +legend('Metabolites and MMs', [10, 'Actual in vivo quality', 10, '$$with \; \varphi_{0}, \varphi_{1}, \omega_{global}, \: noise$$'],'Interpreter','latex','Location','NorthWest') +title('Simulated in vivo quality spectra') +end + +function plotSetup() +FontSize = 12; +LineWidth = 1.5; +xlim([1.5, 3.0]) +xlabel('\delta (ppm)') +ylabel('Signal (arb. u.)') +set(gca,'xDir','reverse') +% set(gca,'ytick',[]); +set(gca,'fontsize',FontSize); +set(gca,'FontWeight','bold'); +h = findobj(gca,'Type','line'); +for plots = h + set(plots,'LineWidth',LineWidth) +end +end diff --git a/plot_spect/Functions/snr.m b/plot_spect/Functions/snr.m index e093c8db9dded32e454eb5acdab336feed66045a..09bdbdce726d18d4d9759e9c1d1ad391a6df4c63 100644 --- a/plot_spect/Functions/snr.m +++ b/plot_spect/Functions/snr.m @@ -21,7 +21,7 @@ else noise = noise - y;% now the noise does not have linear component noise = std(noise); - snrValue = amplitude;%noise; + snrValue = amplitude/noise; %snrValue = 20*log(amplitude/noise); %in dB diff --git a/postprocessing/calculateMolal_MolarConcentrations.m b/postprocessing/calculateMolal_MolarConcentrations.m index 2ec51e28a721d5fe3e13f452f12b95705e226e25..0c0fdc5958465aa8862af672d153082e87a20c98 100644 --- a/postprocessing/calculateMolal_MolarConcentrations.m +++ b/postprocessing/calculateMolal_MolarConcentrations.m @@ -64,6 +64,13 @@ a_WM = 0.65; a_GM = 0.78; a_CSF = 0.97; +% tissue densities (g/mL) +% (Brooks R. - 1980 - Explanation of cerebral white - gray contrast in computer tomography +% additional reference in Kreis R. & Ernst T. - 1993 - Absolute Quantitation of Water and Metabolites in the Human Brain. I. Compartments and Water) +d_WM = 1.04; +d_GM = 1.04; +d_CSF = 1; + %T1 relaxation times of water in the given tissue type [ms] at 9.4T : From %Gisela Hagberg 2017 Neuroimage T1_GM = 2120; @@ -117,10 +124,12 @@ if strcmpi(doMolal_Molar, 'Molal') %MOLAL calculations %Calculate water fraction from volume fractions obtained from segmentation %and relative water fraction in each segmentation f_sum = fv_GM .* a_GM + fv_WM .* a_WM + fv_CSF .* a_CSF; + %corrected version considering also the water densities + f_sum = fv_GM .* a_GM .* d_GM + fv_WM .* a_WM .* d_WM + fv_CSF .* a_CSF .* d_CSF; - f_GM = fv_GM .* a_GM ./ f_sum; - f_WM = fv_WM .* a_WM ./ f_sum; - f_CSF = fv_CSF .* a_CSF ./f_sum; + f_GM = fv_GM .* a_GM .* d_GM ./ f_sum; + f_WM = fv_WM .* a_WM .* d_WM ./ f_sum; + f_CSF = fv_CSF .* a_CSF .* d_CSF ./f_sum; %% calculate true water concentration for each subject : density terms do not come in molality water_conc_relaxation_corrected = conc_pure_water * ... @@ -136,9 +145,9 @@ else %MOLAR calculations %% calculate true water concentration for each subject water_conc_relaxation_corrected = conc_pure_water * ... - ( fv_GM * a_GM * R_GM + ... correction for gray matter concentration - fv_WM * a_WM * R_WM + ... correction for white matter concentration - fv_CSF * a_CSF * R_CSF ) / ... correction for cerebrospinal fluid concentration + ( fv_GM * a_GM * d_GM * R_GM + ... correction for gray matter concentration + fv_WM * a_WM * d_WM * R_WM + ... correction for white matter concentration + fv_CSF * a_CSF * d_CSF * R_CSF ) / ... correction for cerebrospinal fluid concentration (1 - fv_CSF); end diff --git a/postprocessing/calculate_FWHM.m b/postprocessing/calculate_FWHM.m index ae425726127a24bf23bf6b90d9d4b64bfdaf91dd..d0d3633a039b1e5bc0cad0e0371c97492db4d2b6 100644 --- a/postprocessing/calculate_FWHM.m +++ b/postprocessing/calculate_FWHM.m @@ -12,7 +12,7 @@ end if ~exist('downField_MM_Met', 'var') - downField_MM_Met = 'DF'; + downField_MM_Met = 'MM'; end switch downField_MM_Met @@ -20,10 +20,21 @@ switch downField_MM_Met keyMM_ppmNaming = {'DF58' 'DF60' 'DF61' 'DF68' 'DF70' 'DF73' 'DF75' 'DF82' 'DF83' 'DF835' 'DF85' 'NAAB' 'hCs' 'NAA_DF' 'NAD' 'Cr'};%'hist' orderMet = {'DF58';'DF60';'DF61';'DF68';'DF70';'DF73';'DF75';'DF82';'DF83';'DF835';'DF85';'NAA Broad';'hCs';'NAA'; 'NAD'; 'Cr'};%;'hist' case 'MM' +% keyMM_ppmNaming = {'MM09' 'MM12' 'MM14' 'MM17' 'MM20' 'MM22' 'MM26' 'MM27' ... +% 'MM30' 'MM32' 'MM36' 'MM37' 'MM38' 'Cr39' 'Cr30' 'NAA'}; +% orderMet = { 'M_{0.92}';'M_{1.21}';'M_{1.39}';'M_{1.67}';'M_{2.04}';'M_{2.26}';'M_{2.56}';'M_{2.70}';... +% 'M_{2.99}';'M_{3.21}';'M_{3.62}';'M_{3.75}';'M_{3.86}'; 'tCr(CH_2)'; 'tCr(CH_3)'; 'NAA'}; + +% keyMM_ppmNaming = {'MM09' 'MM12' 'MM14' 'MM17' 'MM20' 'MM22' 'MM26' 'MM27' ... +% 'MM30' 'MM32' 'MM36' 'MM37' 'MM38' 'NAA' 'Creat' 'Cho' 'Glu' 'Tau' 'Glycin' 'PCr'}; +% orderMet = { 'M_{0.92}';'M_{1.21}';'M_{1.39}';'M_{1.67}';'M_{2.04}';'M_{2.26}';'M_{2.56}';'M_{2.70}';... +% 'M_{2.99}';'M_{3.21}';'M_{3.62}';'M_{3.75}';'M_{3.86}'; 'NAA'; 'tCr(CH_3)'; 'tCho'; 'Glu'; 'Tau'; 'Glyc'; 'tCr(CH_2)'}; + keyMM_ppmNaming = {'MM09' 'MM12' 'MM14' 'MM17' 'MM20' 'MM22' 'MM26' 'MM27' ... - 'MM30' 'MM32' 'MM36' 'MM37' 'MM38' 'MM40' 'Cre'}; + 'MM30' 'MM32' 'MM36' 'MM37' 'MM38' 'MM39' 'Cr39' 'NAA' 'NAA_as' 'Cho' 'mI'}; orderMet = { 'M_{0.92}';'M_{1.21}';'M_{1.39}';'M_{1.67}';'M_{2.04}';'M_{2.26}';'M_{2.56}';'M_{2.70}';... - 'M_{2.99}';'M_{3.21}';'M_{3.62}';'M_{3.75}';'M_{3.86}';'M_{4.03}'; 'tCr(CH_2)'}; + 'M_{2.99}';'M_{3.21}';'M_{3.62}';'M_{3.75}';'M_{3.86}'; 'M_{4.03}'; 'tCr(CH_2)'; 'NAA'; 'NAA_{asp}';'tCho'; 'mI'} + case 'MM WM' keyMM_ppmNaming = {'MM09' 'MM12' 'MM14' 'MM17' 'MM20' 'MM22' 'MM26' 'MM27' ... 'MM30' 'MM32' 'MM36' 'MM37' 'MM38' 'MM40' 'Cre'}; @@ -43,15 +54,15 @@ numberOfMet = length(orderMet); %threshold for crlbs threshold_CRLB = 900; FontSize = 14; -LineWidth = 1.5; +LineWidth = 2.5; ppmEnd = 4.2; ppmStart = 0.2; interpolationFactor = 20; %plotting offsets -offsetMetabolite = 0.1; +offsetMetabolite = 0.085; offsetResidual = offsetMetabolite * (numberOfMet+1); -offsetBaseline = offsetResidual + 0.05; +offsetBaseline = offsetResidual + 0.042; %% do the absolute quantification on all files if ~iscell(FileNames) @@ -93,7 +104,7 @@ for index =1:length(FileNames) if strcmp(downField_MM_Met,'DF') xlim([5.5 9.4]); else - xlim([0.5 4.097]); + xlim([0.5 4.02]); end for plots = 1:length(p) set(p(plots),'LineWidth',LineWidth); @@ -112,7 +123,7 @@ for index =1:length(FileNames) pMetabolite = plot(ppmVector{index}, metaboliteSpectrum ./ scale - indexMetabolite * offsetMetabolite); text(0.47, -indexMetabolite * offsetMetabolite,orderMet{indexMetabolite}, 'FontSize', FontSize); set(pMetabolite,'LineWidth',LineWidth); - + if strcmp(downField_MM_Met,'DF') switch keyMM_ppmNaming{indexMetabolite} case 'Cr' @@ -152,11 +163,10 @@ for index =1:length(FileNames) end else % assuming no downfield peaks if ~isempty(ppmGap) - ppmEnd = ppmGap; + % make the downfield 0, if there was a ppmGap + indexDF = find((ppmVector{index} < ppmGap), 1, 'first'); + metaboliteSpectrum(1:indexDF) = 0; end - % ppmEnd is where upfield ends in fit config - indexDF = find((ppmVector{index} < ppmEnd), 1, 'first'); -% metaboliteSpectrum(1:indexDF) = 0; TODO end dataPoints = length(metaboliteSpectrum); diff --git a/postprocessing/doAbsoluteConcentrationProcessing.m b/postprocessing/doAbsoluteConcentrationProcessing.m index 44cc509ce20e4c779d7efabbf4509185e502f141..c5de48cddf8163d9b616b5b610cfa9eedc4ea447 100644 --- a/postprocessing/doAbsoluteConcentrationProcessing.m +++ b/postprocessing/doAbsoluteConcentrationProcessing.m @@ -3,7 +3,7 @@ function [absoluteConcentrations, metaboliteNames, subjectsAbs, data_path] = doA switch compare case 'DF' - outputFolder = 'Output\'; + outputFolder = 'Output\FWHMBA Results 7.5e-3\'; pathName = 'DF data path'; case 'MM' outputFolder = 'OutputMM\'; @@ -114,9 +114,9 @@ end eliminateMetabolites = {'Lac', 'Leu','Cho+GPC+PCh', 'mI+Glyc', 'Glu+Gln', 'Lip13a', 'Lip13b', 'Lip13c', 'Lip13d','Lip20', 'Lip13a+Lip13b'}; if strcmp(compare,'DF') - eliminateMetabolites = {'Asp', 'Cr-CH3', 'Cr-CH2', 'GABA', 'Gln', 'Glu', 'Glyc', 'GSH', 'mI', 'NAA-asp', 'NAA-ace', 'NAAG', 'tCho_PE', 'Scyllo', 'Tau', 'Glx', 'Lac', 'Leu','Cho+GPC+PCh', 'mI+Glyc', 'Glu+Gln', 'Lip13a', 'Lip13b', 'Lip13c', 'Lip13d','Lip20', 'Lip13a+Lip13b'}; - metaboliteNameOrder = {'DF58';'DF60';'DF61';'DF68';'DF70';'DF73';'DF75';'DF82';'DF83';'DF835';'DF85';'NAD';'hCs';'NAA Broad';'NAA';'total NAA';}; - metaboliteNamesDisplay = {'DF5.75';'DF5.97';'DF6.12';'DF6.83';'DF7.04';'DF7.30';'DF7.48';'DF8.18';'DF8.24';'DF8.37';'DF8.49';'NAD+';'hCs';'NAA Broad';'NAA';'total NAA'}; + eliminateMetabolites = {'NAD', 'Asp', 'Cr-CH3', 'Cr-CH2', 'GABA', 'Gln', 'Glu', 'Glyc', 'GSH', 'mI', 'NAA-asp', 'NAA-ace', 'NAAG', 'tCho_PE', 'Scyllo', 'Tau', 'Glx', 'Lac', 'Leu','Cho+GPC+PCh', 'mI+Glyc', 'Glu+Gln', 'Lip13a', 'Lip13b', 'Lip13c', 'Lip13d','Lip20', 'Lip13a+Lip13b'}; + metaboliteNameOrder = {'DF58';'DF60';'DF61';'DF68';'DF70';'DF73';'DF75';'DF82';'DF83';'DF835';'DF85';'hCs';'NAA Broad';'NAA';'total NAA';}; + metaboliteNamesDisplay = {'DF5.75';'DF5.97';'DF6.12';'DF6.83';'DF7.04';'DF7.30';'DF7.48';'DF8.18';'DF8.24';'DF8.37';'DF8.49';'hCs';'NAA Broad';'NAA';'total NAA'}; numberOfMet = length(metaboliteNameOrder); absoluteConcentrationsOrdered = zeros(size(absoluteConcentrations,1), numberOfMet); absoluteConcentrationsOrdered2 = zeros(size(absoluteConcentrations,1), numberOfMet); diff --git a/postprocessing/evaluateT2FitsNew.m b/postprocessing/evaluateT2FitsNew.m index de0d12b1dbdae43ccfa98cee059a7eb29bd229e4..00397f218daf0e1daf122f9ad5cea64e36f20abc 100644 --- a/postprocessing/evaluateT2FitsNew.m +++ b/postprocessing/evaluateT2FitsNew.m @@ -25,8 +25,8 @@ else plotColors2 = {[0.1 0.9 0.1], [0.5 0.5 0.5]}; end -sortT2sDescending = true; -usePpm = true; +sortT2sDescending = false; +usePpm = false; if isempty(figureIds) emptyFigureIds = true; @@ -37,7 +37,7 @@ end switch downField_MM_Met case 'DF' pathNameMM = 'DF data path'; - outputFolder = 'Output\'; + outputFolder = 'Output\FWHMBA Results 7.5e-3\'; case 'Met' pathNameMM = 'DF data path'; outputFolder = 'Output_UF\'; @@ -66,22 +66,22 @@ end switch downField_MM_Met case 'DF' if useTotalNAA - metaboliteNameOrder = {'Cr-CH3';'DF58';'DF60';'DF61';'DF68';'DF70';'DF73';'DF75';'DF82';'DF83';'DF835';'DF85';'NAD';'hCs';'NAA Broad';'NAA';'total NAA'};'ATP';'hist'; - metaboliteNameOrderConc = {'Cr';'DF58';'DF60';'DF61';'DF68';'DF70';'DF73';'DF75';'DF82';'DF83';'DF835';'DF85';'NAD';'hCs';'NAAB';'NAA_DF';'NAAB+NAA_DF'}; - metaboliteNamesDisplay = {'tCr-CH3';'DF5.75';'DF5.97';'DF6.12';'DF6.83';'DF7.04';'DF7.30';'DF7.48';'DF8.18';'DF8.24';'DF8.37';'DF8.49';'NAD+';'hCs';'NAA Broad';'NAA';'total NAA'};'ATP';'hist'; - metaboliteNamesDisplay2 = {'tCr-CH3';'DF_{5.75}';'DF_{5.97}';'DF_{6.12}';'DF_{6.83}';'DF_{7.04}';'DF_{7.30}';'DF_{7.48}';'DF_{8.18}';'DF_{8.24}';'DF_{8.37}';'DF_{8.49}';'NAD^+';'hCs';'NAA Broad';'NAA';'total NAA'};'ATP';'hist'; + metaboliteNameOrder = {'Cr-CH3';'DF58';'DF60';'DF61';'DF68';'DF70';'DF73';'DF75';'DF82';'DF83';'DF835';'DF85';'hCs';'NAA Broad';'NAA';'total NAA'};'ATP';'hist';'NAD'; + metaboliteNameOrderConc = {'Cr';'DF58';'DF60';'DF61';'DF68';'DF70';'DF73';'DF75';'DF82';'DF83';'DF835';'DF85';'hCs';'NAAB';'NAA_DF';'NAAB+NAA_DF'};'NAD'; + metaboliteNamesDisplay = {'tCr-CH3';'DF5.75';'DF5.97';'DF6.12';'DF6.83';'DF7.04';'DF7.30';'DF7.48';'DF8.18';'DF8.24';'DF8.37';'DF8.49';'hCs';'NAA Broad';'NAA';'total NAA'};'ATP';'hist';'NAD+'; + metaboliteNamesDisplay2 = {'tCr-CH3';'DF_{5.75}';'DF_{5.97}';'DF_{6.12}';'DF_{6.83}';'DF_{7.04}';'DF_{7.30}';'DF_{7.48}';'DF_{8.18}';'DF_{8.24}';'DF_{8.37}';'DF_{8.49}';'hCs';'NAA Broad';'NAA';'total NAA'};'ATP';'hist';'NAD^+'; else - metaboliteNameOrder = {'Cr-CH3';'DF58';'DF60';'DF61';'DF68';'DF70';'DF73';'DF75';'DF82';'DF83';'DF835';'DF85';'NAD';'hCs';'NAA Broad';'NAA'};'ATP';'hist'; - metaboliteNameOrderConc = {'Cr';'DF58';'DF60';'DF61';'DF68';'DF70';'DF73';'DF75';'DF82';'DF83';'DF835';'DF85';'NAD';'hCs';'NAAB';'NAA_DF'};'NAAB+NAA_DF' - metaboliteNamesDisplay = {'tCr-CH3';'DF5.75';'DF5.97';'DF6.12';'DF6.83';'DF7.04';'DF7.30';'DF7.48';'DF8.18';'DF8.24';'DF8.37';'DF8.49';'NAD+';'hCs';'NAA Broad';'NAA'};'ATP';'hist'; - metaboliteNamesDisplay2 = {'tCr-CH3';'DF_{5.75}';'DF_{5.97}';'DF_{6.12}';'DF_{6.83}';'DF_{7.04}';'DF_{7.30}';'DF_{7.48}';'DF_{8.18}';'DF_{8.24}';'DF_{8.37}';'DF_{8.49}';'NAD^+';'hCs';'NAA Broad';'NAA';};'ATP';'hist'; + metaboliteNameOrder = {'Cr-CH3';'DF58';'DF60';'DF61';'DF68';'DF70';'DF73';'DF75';'DF82';'DF83';'DF835';'DF85';'hCs';'NAA Broad';'NAA'};'ATP';'hist';'NAD'; + metaboliteNameOrderConc = {'Cr';'DF58';'DF60';'DF61';'DF68';'DF70';'DF73';'DF75';'DF82';'DF83';'DF835';'DF85';'hCs';'NAAB';'NAA_DF'};'ATP';'hist';'NAD'; + metaboliteNamesDisplay = {'tCr-CH3';'DF5.75';'DF5.97';'DF6.12';'DF6.83';'DF7.04';'DF7.30';'DF7.48';'DF8.18';'DF8.24';'DF8.37';'DF8.49';'hCs';'NAA Broad';'NAA'};'ATP';'hist';'NAD+'; + metaboliteNamesDisplay2 = {'tCr-CH3';'DF_{5.75}';'DF_{5.97}';'DF_{6.12}';'DF_{6.83}';'DF_{7.04}';'DF_{7.30}';'DF_{7.48}';'DF_{8.18}';'DF_{8.24}';'DF_{8.37}';'DF_{8.49}';'hCs';'NAA Broad';'NAA';};'ATP';'hist'; 'NAD^+'; end metaboliteNameOrderFWHM = metaboliteNameOrder; metaboliteNameOrderFWHM{1} = 'Cr'; subjects = {'1658';'1717';'2017';'3373';'3490';'5771';'6249';'6971';'7338';'7782';'9810'}; yAxisLim = 65; -% yAxisLim = 90; + yAxisLim = 90; case 'Met' metaboliteNameOrder = {'Leu';'Asp';'Cr-CH3';'Cr-CH2';'GABA';'Glu';'Gln';'GSH_no';'Glyc';'GPC';'mI';'NAA-asp';'NAA-ace';'NAAG';'PCh';'PE';'Scyllo';'Tau';'tCho';'tNAA';'mI+Glyc';'Glx'}; metaboliteNameOrder = {'Leu';'Asp';'Cr-CH3';'Cr-CH2';'GABA';'Glu';'Gln';'GSH_no';'Glyc';'mI';'NAA-asp';'NAA-ace';'NAAG';'Scyllo';'Tau';'tCho_PE';'tNAA';'mI+Glyc';'Glx'; 'Lac'; 'NAA+NAAG'}; @@ -126,6 +126,7 @@ numOfSubjects = length(tableT2sSubjects); T2s = cell(numOfSubjects,numberOfMet); R2s = cell(numOfSubjects,numberOfMet); concentrations = cell(numOfSubjects, numberOfMet, numberOfTEs); +CRLBs = cell(numOfSubjects, numberOfMet, numberOfTEs); for indexSubject = 1:numOfSubjects T2times = tableT2sSubjects{indexSubject}(2,2:end); R2times = tableT2sSubjects{indexSubject}(3,2:end); @@ -136,9 +137,12 @@ for indexSubject = 1:numOfSubjects R2s(indexSubject,indexMetabolite) = R2times(index); indexConc = find(strcmp(metaboliteNameOrderConc(indexMetabolite),concentrationsSubject(1,:))); concentrations(indexSubject, indexMetabolite,:) = concentrationsSubject(2:6,indexConc); + CRLBs(indexSubject, indexMetabolite,:) = concentrationsSubject(2:6,indexConc+1); end end +saveCRLBs(CRLBs, TEs, metaboliteNamesDisplay, data_path, outputFolder) + concentrations = cell2mat(concentrations); T2sNumeric = str2double(T2s); R2sNumeric = str2double(R2s); @@ -152,8 +156,8 @@ acceptableT2s = nonNegT2s; acceptableR2s = R2sNumeric; switch downField_MM_Met case 'DF' - acceptableT2s(R2sNumeric<=0.51) = NaN; - acceptableR2s(R2sNumeric<=0.51) = NaN; + acceptableT2s(R2sNumeric<=0.53) = NaN; + acceptableR2s(R2sNumeric<=0.53) = NaN; for indexSubject = 1:numOfSubjects for indexMetabolite = 1:numberOfMet if R2sNumeric(indexSubject, indexMetabolite) <= 0.5 @@ -212,14 +216,24 @@ for index = 2:numberOfMet % currentLabel = string([metaboliteNamesDisplay2{indexMetabolite}, ' : T_2=' num2str(acceptableMeanT2s(indexMetabolite),2), ' ms']); currentLabel = string([metaboliteNamesDisplay2{indexMetabolite}]); if mod(index,plotGroups) == 2 - figure; + myVal = mod(ceil(index/plotGroups)+1,2)+1; + if myVal == 1 + figure; + sgtitle('Estimated T_2^{app} Decay by Fitting: Signal \propto exp( - TE / T_2^{app} )','FontWeight', 'bold') + end + subplot(1,2, myVal); + if myVal == 1 + text(-0.15,0.98,'A','Units', 'Normalized', 'VerticalAlignment', 'Top', 'FontSize', 12,'FontWeight', 'bold'); + else + text(-0.15,0.98,'B','Units', 'Normalized', 'VerticalAlignment', 'Top', 'FontSize', 12,'FontWeight', 'bold'); + end hold on offsetRec = plotOffset * (plotGroups/2+1.5); for indexTE = 1: numberOfTEs rectangle('position',[TEs(indexTE)-offsetRec -0.92 offsetRec*2 100], 'FaceColor',[0.85 .85 .85], 'LineStyle', 'none') end ylim([-1,0]); - title('T_2 decay curves and measured T_2 times') +% title('T_2 decay curves and measured T_2 times') xlim([20 65]) xlabel('TE (ms)') ylabel('Signal (arb. u.)') @@ -293,6 +307,7 @@ if sortT2sDescending metaboliteNameOrderFWHM = metaboliteNameOrderFWHM(sortedIndeces); acceptableStdT2s = acceptableStdT2s(sortedIndeces); acceptableT2s = acceptableT2s(:, sortedIndeces); + acceptableR2s = acceptableR2s(:, sortedIndeces); R2sNumeric = R2sNumeric(:, sortedIndeces); nonNegT2s = nonNegT2s(:, sortedIndeces); metaboliteNamesDisplay = metaboliteNamesDisplay(sortedIndeces); @@ -309,7 +324,7 @@ end positionsTicks = [2.2:1.5:1.5*numberOfMet+1.5]; positions1 = positionsTicks + offsetPlot; boxPlotT2 = boxplot(acceptableT2s, metaboliteNamesDisplay,'colors',plotColors{1},'symbol','+','positions',positions1,'width',0.18); -ylabel('T_2 (ms)') +ylabel('T_2^{app} (ms)') axT2 = get(figureIds{1},'CurrentAxes'); axT2.XAxis.TickLength = [0,0]; axT2.YColor = 'k'; @@ -317,8 +332,8 @@ axT2.YColor = 'k'; set(boxPlotT2(:,:),'linewidth',1); switch downField_MM_Met case 'DF' - set(gca, 'YLim', [-5,90]); - set(gca, 'XLim', [positionsTicks(1)-abs(offsetPlot)-0.8 positionsTicks(end)+abs(offsetPlot)+0.8]); + set(gca, 'YLim', [-5,70]); + set(gca, 'XLim', [positionsTicks(1)-abs(offsetPlot)-0.8+1.5 positionsTicks(end)+abs(offsetPlot)+0.8]); case 'MM' set(gca, 'YLim', [-5,95]); set(gca, 'XLim', [positionsTicks(2)-abs(offsetPlot)-0.8 positionsTicks(end)+abs(offsetPlot)+0.8]); @@ -335,8 +350,7 @@ set(gca, 'XTickMode', 'manual'); set(gca, 'XTick', positionsTicks); set(gca, 'XTickLabelRotation', 90.0); set(gca, 'FontSize', 16); -% title('T_2^\rho Relaxation Times'); -title('T_2 Relaxation Times'); +title('T_2^{app} Relaxation Times'); %% FWHM if doFWHMevalutation @@ -376,22 +390,28 @@ if doFWHMevalutation %% plotting of FWHM if emptyFigureIds - figureIds{2} = plotFWHMs(fwhmReshaped, [], metaboliteNamesDisplay, numberOfMet, scanFrequency, plotColors, 'Full Width Half Maxima', usePpm, yAxisLim, offsetPlot); - figureIds{3} = plotFWHMs(fwhmReshaped3, [], metaboliteNamesDisplay, numberOfMet, scanFrequency, plotColors2, 'Full-Width-Half-Maxima T_2 and B_0 corrected', usePpm, yAxisLim, offsetPlot); + figureIds{2} = plotFWHMs(fwhmReshaped, [], metaboliteNamesDisplay, numberOfMet, scanFrequency, plotColors, '\Delta\nu_{1/2}', usePpm, yAxisLim, offsetPlot); + figureIds{3} = plotFWHMs(fwhmReshaped3, [], metaboliteNamesDisplay, numberOfMet, scanFrequency, plotColors2, '\Delta\nu_{residual}', usePpm, yAxisLim, offsetPlot); else - figureIds{2} = plotFWHMs(fwhmReshaped, [], metaboliteNamesDisplay, numberOfMet, scanFrequency, plotColors, 'Full Width Half Maxima', usePpm, yAxisLim, offsetPlot, figureIds{2}); - figureIds{3} = plotFWHMs(fwhmReshaped3, [], metaboliteNamesDisplay, numberOfMet, scanFrequency, plotColors2, 'Full-Width-Half-Maxima T_2 and B_0 corrected', usePpm, yAxisLim, offsetPlot, figureIds{3}); + figureIds{2} = plotFWHMs(fwhmReshaped, [], metaboliteNamesDisplay, numberOfMet, scanFrequency, plotColors, '\Delta\nu_{1/2}', usePpm, yAxisLim, offsetPlot, figureIds{2}); + figureIds{3} = plotFWHMs(fwhmReshaped3, [], metaboliteNamesDisplay, numberOfMet, scanFrequency, plotColors2, '\Delta\nu_{residual}', usePpm, yAxisLim, offsetPlot, figureIds{3}); end %% if emptyFigureIds - figureIds{4} = plotFWHMs(T2RelaxationLinewidth, [], metaboliteNamesDisplay, numberOfMet, scanFrequency, plotColors2, 'Full-Width-Half-Maxima vs. Linewidth Component from T_2', usePpm, yAxisLim, offsetPlot); + figureIds{4} = plotFWHMs(T2RelaxationLinewidth, [], metaboliteNamesDisplay, numberOfMet, scanFrequency, plotColors2, '\Delta\nu_{1/2} vs. (\pi T_2^{app})^{-1}', usePpm, yAxisLim, offsetPlot); else - figureIds{4} = plotFWHMs(T2RelaxationLinewidth, [], metaboliteNamesDisplay, numberOfMet, scanFrequency, plotColors2, 'Full-Width-Half-Maxima vs. Linewidth Component from T_2', usePpm, yAxisLim, offsetPlot, figureIds{4}); + figureIds{4} = plotFWHMs(T2RelaxationLinewidth, [], metaboliteNamesDisplay, numberOfMet, scanFrequency, plotColors2, '\Delta\nu_{1/2} vs. (\pi T_2^{app})^{-1}', usePpm, yAxisLim, offsetPlot, figureIds{4}); + end + figureIds{4} = plotFWHMs(fwhmReshaped, [], metaboliteNamesDisplay, numberOfMet, scanFrequency, plotColors, '\Delta\nu_{1/2} vs. (\pi T_2^{app})^{-1}', usePpm, yAxisLim, offsetPlot, figureIds{4}); + if usePpm + text(0.06,1.0,'\Delta\nu_{1/2}','Units', 'Normalized', 'VerticalAlignment', 'Top', ... + 'FontSize', 13,'FontWeight', 'bold', 'Color',[0 0 1]); + text(0.06,0.90,'(\pi T_2^{app})^{-1}','Units', 'Normalized', 'VerticalAlignment', 'Top', ... + 'FontSize', 13,'FontWeight', 'bold', 'Color',[0 0.5 0]); + scatter(2.2,0.217,'filled','s','MarkerEdgeColor',[0,0,1], 'MarkerFaceColor',[0,0,1], 'LineWidth',2) + scatter(2.2,0.187,'filled','s','MarkerEdgeColor',[0,0.5,0], 'MarkerFaceColor',[0,0.5,0], 'LineWidth',2) end - figureIds{4} = plotFWHMs(fwhmReshaped, [], metaboliteNamesDisplay, numberOfMet, scanFrequency, plotColors, 'Full-Width-Half-Maxima vs. Linewidth Component from T_2', usePpm, yAxisLim, offsetPlot, figureIds{4}); - - tableFWHMSummarized = cell(numberOfMet+1,4); tableFWHMSummarized(2:end,1) = metaboliteNamesDisplay; tableFWHMSummarized(1,2) = {['FWHM' plusMinusSign 'Std']}; @@ -408,7 +428,7 @@ if doFWHMevalutation for index=1:numberOfMet tableFWHMSummarized{index+1,2} = [num2str(meanFwhmReshaped(index), writePrecision) plusMinusSign num2str(stdFwhmReshaped(index), writePrecision)]; end - exportFileXlsx = [data_path ,'Output\FWHM_Results_Mean_std.xlsx']; + exportFileXlsx = [data_path , outputFolder, 'FWHM_Results_Mean_std.xlsx']; xlswrite(exportFileXlsx, tableFWHMSummarized, 1, 'A1'); end @@ -450,10 +470,10 @@ end % set(gca, 'YLim', [0,fwhm_plot_limit_ppm]); % end -ylabel('FWHM (Hz)') +ylabel('\Delta\nu (Hz)') if usePpm yyaxis right - ylabel('FWHM (ppm)', 'Color', 'k') + ylabel('\Delta\nu (ppm)', 'Color', 'k') yyaxis left end @@ -481,3 +501,52 @@ else set(gca, 'YLim', [0,yAxisLim]); end end + +function saveCRLBs(CRLBs, TEs, metaboliteNamesDisplay, data_path, outputFolder) +CRLBs = cell2mat(CRLBs(:,2:end,:)); +metaboliteNamesDisplay = metaboliteNamesDisplay(2:end); +CRLBs_mean = squeeze(mean(CRLBs,1, 'omitnan')); +CRLBs_std = squeeze(std(CRLBs,1, 'omitnan')); +numberOfMet = size(CRLBs_mean,1); +plusMinusSign = [' ' char(177) ' ']; +tableCRLBSummarized = cell(numberOfMet+1,6); +tableCRLBSummarized(2:end,1) = metaboliteNamesDisplay; +for indexTE = 1:length(TEs) + tableCRLBSummarized{1,indexTE+1} = ['TE = ', num2str(TEs(indexTE)), ' ms']; + for indexMet=1:numberOfMet + tableCRLBSummarized{indexMet+1,indexTE+1} = [sprintf('%.1f', CRLBs_mean(indexMet, indexTE))... + plusMinusSign sprintf('%.1f', CRLBs_std(indexMet, indexTE))]; + end +end + +exportFileXlsx = [data_path , outputFolder, 'CRLB_Results_Mean_std.xlsx']; +xlswrite(exportFileXlsx, tableCRLBSummarized, 1, 'A1'); + +colors = {[0 0 1]; [0 0 0]; [0 0.5 0]; [0 0 0]; [0.7 0.2 0.2]}; +offsetPlot = 0.25; +positionsTicks = 2.2:1.5:1.5*numberOfMet+1.5; +figId = figure; +hold on +for indexTE = 1:2:length(TEs) + + positions = positionsTicks + offsetPlot * (indexTE-3); + boxplot(CRLBs(:,:,indexTE), metaboliteNamesDisplay,'colors',colors{indexTE},'symbol','+',... + 'positions',positions, 'Widths',0.3); + text(0.3,0.95 - (indexTE-1) * 0.03,['TE = ' num2str(TEs(indexTE)), ' ms'],'Units', 'Normalized', ... + 'VerticalAlignment', 'Top', 'FontSize', 12,'FontWeight', 'bold', 'Color',colors{indexTE}); + scatter(7.5,580 - (indexTE-1) * 20,'filled','s','MarkerEdgeColor',colors{indexTE}, 'MarkerFaceColor',colors{indexTE}, 'LineWidth',1.5); +end + +ylabel('CRLBs (%)') +ylim([0 620]) + +ax = get(figId,'CurrentAxes'); +ax.XAxis.TickLength = [0,0]; +ax.YColor = 'k'; + +set(gca, 'YGrid', 'on'); +set(gca, 'XTickMode', 'manual'); +set(gca, 'XTick', positionsTicks); +set(gca, 'XLim', [positionsTicks(1)-0.8 positionsTicks(end)+0.8]); +set(gca, 'XTickLabelRotation', 90.0); +end \ No newline at end of file diff --git a/postprocessing/extractFits.m b/postprocessing/extractFits.m index 163bb44cdb28ebd5c1521341362f060de9c16c54..72b3ddf32c6436d068f057f75dbf5f59d15ec814 100644 --- a/postprocessing/extractFits.m +++ b/postprocessing/extractFits.m @@ -1,5 +1,6 @@ function [nOfPoints, ppmVector, phasedData, fitData, baselineData, residualData, ... - metaboliteNames, metaboliteData, tableConcentrations, ppmStart, ppmEnd, scanFrequency, frequencyShift, ppmGap] = ... + metaboliteNames, metaboliteData, tableConcentrations, ppmStart, ppmEnd, ... + scanFrequency, frequencyShift, ppmGap, phase0, phase1] = ... extractFits(PathName, FileName) c = textread(strcat(PathName,FileName),'%s'); @@ -87,17 +88,31 @@ for indexMetabolite = 1:numberOfMetabolites end %other information -indexOfValue = find(strcmp(c,'ppmst='))+1; +indexOfValue = find(strcmpi(c,'ppmst='))+1; +if isempty(indexOfValue) + indexOfValue = find(strcmpi(c,'ppmst'))+2; +end ppmStart = str2double( c(indexOfValue,1)); -indexOfValue = find(strcmp(c,'ppmend='))+1; +indexOfValue = find(strcmpi(c,'ppmend='))+1; +if isempty(indexOfValue) + indexOfValue = find(strcmpi(c,'ppmend'))+2; +end ppmEnd = str2double( c(indexOfValue,1)); -indexOfValue = find(strcmp(c,'hzpppm='))+1; +indexOfValue = find(strcmpi(c,'hzpppm='))+1; +if isempty(indexOfValue) + indexOfValue = find(strcmp(c,'hzpppm'))+2; +end scanFrequency = str2double( c(indexOfValue,1)); -indexOfValue = find(strcmp(c,'shift'))+2; % 'Data shift = x.xx ppm' +indexOfValue = find(strcmpi(c,'shift'))+2; % 'Data shift = x.xx ppm' frequencyShift = str2double( c(indexOfValue,1)); +indexOfValue = find(strcmpi(c,'Ph:'))+1; % 'Ph: xx deg xx.x deg/ppm' +phase0 = str2double( c(indexOfValue,1)); +phase1 = str2double( c(indexOfValue+2,1)); + tempX = strfind(c,'ppmgap(2,1)='); indexOfValue = find(~cellfun(@isempty,tempX)); + if isempty(indexOfValue) ppmGap = []; else diff --git a/postprocessing/getRelaxationTimes.m b/postprocessing/getRelaxationTimes.m index 29eebeeccfc8958bc03de6ddc9d68d83e5f3c257..3edf2c3bfbc73671ef6c27980ec6f5d18dc9cd52 100644 --- a/postprocessing/getRelaxationTimes.m +++ b/postprocessing/getRelaxationTimes.m @@ -2,7 +2,7 @@ function [T1_met, T2_met, metaboliteNames] = getRelaxationTimes(compare, metabol %% setting up data paths switch compare case 'DF' - outputFolder = 'Output\'; + outputFolder = 'Output\FWHMBA Results 7.5e-3\'; pathName = 'DF data path'; case 'MM' outputFolder = 'OutputMM\'; @@ -102,9 +102,20 @@ switch compare %values taken from A.Wright ISMRM 2019 abstract metaboliteNamesT1 = {'NAA-asp'; 'NAA-ace'; 'tCho'; 'mI'; 'Gln'; 'Glu'; 'Cr-CH2'; 'Cr-CH3'; 'Tau'; 'GSH'; 'Glx'; 'tNAA'}; %'GABA' T1_met_known = [1158 ; 1602 ; 1111; 1309 ; 1831; 1405 ; 1162 ; 1565 ; 1961 ; 1310 ; 1618 ; 1380 ]; %'966' (Gaba) + %values taken from A.Wright MRM 2021 paper (revision 2) + metaboliteNamesT1 = {'NAA-asp'; 'NAA-ace'; 'tCho'; 'mI'; 'Gln'; 'Glu'; 'Cr-CH2'; 'Cr-CH3'; 'Tau'; 'GSH'; 'Asp'; 'GABA'; 'Glyc'; 'NAAG'; 'PE'; 'Scyllo'; 'Glx'; 'tNAA'; 'tCr'; 'tCho+'; 'mI+Glyc'}; + T1_met_known = [1137 ; 1701 ; 1161; 1499; 1214; 1343 ; 1118 ; 1678 ; 2063; 1505; 1300; 1240; 739; 1185; 1305; 1632; 1366; 1385; 1528; 1241; 1540]; defaultT1 = round(mean(T1_met_known(1:end-1)),2); %average of the MM T1 times - [T1_met, metaboliteNames] = matchRelaxationTimes(T1_met_known, metaboliteNamesT1, defaultT1, metaboliteNames, true, mapMet_Names); + [T1_met, metaboliteNames] = matchRelaxationTimes(T1_met_known, metaboliteNamesT1, defaultT1, metaboliteNames, true, mapMet_Names);%CHECK ME + + Cr_names = {'Cr+PCr'}; + Cr_to_replace = {'Cr', 'PCr', 'Cr+PCr'}; + [T1_met] = replaceRelaxationTimes(T1_met_known, metaboliteNamesT1, defaultT1, Cr_names, true, mapMetNamesDisplay, metaboliteNames, T1_met, Cr_to_replace); + + NAA_names = {'NAA+NAAG'};%trick to use tNAA - for T1 the name was used as NAA(CH2)+NAA(CH3), while normally it means NAA+NAAG + NAA_to_replace = {'NAA','NAA+NAAG'}; + [T1_met] = replaceRelaxationTimes(T1_met_known, metaboliteNamesT1, defaultT1, NAA_names, true, mapMetNamesDisplay, metaboliteNames, T1_met, NAA_to_replace); %get T2 values % load(['D:\Software\Spectro Data\DATA_df\Output_UF\meanT2s.mat'], 'acceptableMeanT2s', 'metaboliteNamesDisplay'); @@ -138,7 +149,7 @@ numberOfDesiredMetabolites = length(desiredMetaboliteNames); desiredRelaxationTimes = zeros(1,numberOfDesiredMetabolites); for index = 1:numberOfDesiredMetabolites if exist('mapMet_Names','var') - desiredMetaboliteName = mapMet_Names(desiredMetaboliteNames{index}) + desiredMetaboliteName = mapMet_Names(desiredMetaboliteNames{index}); else desiredMetaboliteName = desiredMetaboliteNames{index}; end diff --git a/postprocessing/plot_All_Fit_Metabolites.m b/postprocessing/plot_All_Fit_Metabolites.m index 4f0dc25186a13874a1dbf95932a01a09b39b8c18..937fef874c9a47b9c51a07cba4230dc19eaf9980 100644 --- a/postprocessing/plot_All_Fit_Metabolites.m +++ b/postprocessing/plot_All_Fit_Metabolites.m @@ -1,4 +1,4 @@ -function plot_All_Fit_Metabolites(FileName, PathName, downField_MM_Met, saveFigures) +function plot_All_Fit_Metabolites(FileName, PathName, downField_MM_Met, saveFigures, displayBaseline) if ~exist('FileName', 'var') [FileName,PathName] = uigetfile('*.coord','Please select .coord files from LCModel','Multiselect','on'); @@ -8,11 +8,14 @@ if ~iscell(FileName) FileName= {FileName}; end + + if ~exist('downField_MM_Met','var') % downField_MM_Met = 'Met moiety'; downField_MM_Met = 'Met moiety fMRS'; % downField_MM_Met = 'DF'; % downField_MM_Met = 'MM'; + downField_MM_Met = 'fit'; end overviewPlots = false; @@ -21,6 +24,10 @@ if ~exist('saveFigures','var') saveFigures = true; end +if ~exist('displayBaseline','var') + displayBaseline = false; +end + switch downField_MM_Met case 'Met moiety' metaboliteNames = {'Asp' 'Cr' 'Cr_CH2' 'GABA' 'Glu' 'Gln' 'GSH' 'Glyc' 'Lac' 'mI' 'NAA_as' 'NAA_ac' 'NAAG' 'Scyllo' 'Tau' 'tCho_P'}; @@ -40,16 +47,16 @@ switch downField_MM_Met metaboliteLabels = {'NAA' 'NAAG' 'Asp' 'Glu' 'Gln' 'GABA' 'Lac' ... 'tCr' 'tCho' 'mI' 'sI' 'Gly' 'Glc' 'GSH' 'PE' 'Tau'}; - + metaboliteNames = {'Asp' 'Cr' 'PCr' 'GABA' 'Glu' 'Gln' 'GSH' 'Glyc' 'Lac' 'mI' 'NAA_as' 'NAA_ac' 'NAAG' 'Scyllo' 'Tau' 'tCho' 'PE'}; metaboliteLabels = {'Asp';'Cr';'PCr';'GABA';'Glu';'Gln';'GSH';'Glyc';'Lac';'mI';'NAA(CH_2)';'NAA(CH_3)';'NAAG';'Scyllo';'Tau';'tCho';'PE'}; metaboliteNames = {'Asp' 'Cr' 'PCr' 'GABA' 'Glu' 'Gln' 'GSH' 'Glyc' 'Lac' 'mI' 'NAA' 'NAAG' 'Scyllo' 'Tau' 'PCh' 'GPC' 'PE'}; metaboliteLabels = {'Asp';'Cr';'PCr';'GABA';'Glu';'Gln';'GSH';'Glyc';'Lac';'mI';'NAA';'NAAG';'Scyllo';'Tau';'PCh';'GPC';'PE'}; - -% %Braino -% metaboliteNames = {'Cr_CH3' 'Cr_CH2' 'Glu' 'Lac' 'mI' 'NAA_as' 'NAA_ac' 'Cho'}; -% metaboliteLabels = {'Cr_CH3';'Cr_CH2';'Glu';'Lac';'mI';'NAA(CH_2)';'NAA(CH_3)';'Cho'}; - + + % %Braino + % metaboliteNames = {'Cr_CH3' 'Cr_CH2' 'Glu' 'Lac' 'mI' 'NAA_as' 'NAA_ac' 'Cho'}; + % metaboliteLabels = {'Cr_CH3';'Cr_CH2';'Glu';'Lac';'mI';'NAA(CH_2)';'NAA(CH_3)';'Cho'}; + xLimits = [0.5 4.097]; offsetMetabolite = 0.1; @@ -61,7 +68,7 @@ switch downField_MM_Met xLimits = [0.5 9]; metaboliteNames = {'hCs';'DF70';'ATP';'NAA_DF';'NAD';'DF58';'DF60';'DF68';'DF73';'DF75';'DF82';'DF83';'DF835';'NAAB';'DF61';'DF85'}; metaboliteLabels = {'hCs';'DF70';'ATP';'NAA_DF';'NAD';'DF58';'DF60';'DF68';'DF73';'DF75';'DF82';'DF83';'DF835';'NAAB';'DF61';'DF85'}; - + metaboliteNames = {'hCs';'NAA_DF';'NAD'; 'DF58'; 'DF60'; 'DF61'; 'DF68'; 'DF70'; 'DF73'; 'DF75'; 'NAAB'; 'DF82'; 'DF83'; 'DF835'; 'DF85'}; metaboliteLabels = {'hCs';'NAA'; 'NAD^+';'DF_{5.75}';'DF_{5.97}';'DF_{6.12}';'DF_{6.83}';'DF_{7.04}';'DF_{7.30}';'DF_{7.48}';'NAA Broad';'DF_{8.18}';'DF_{8.24}';'DF_{8.37}';'DF_{8.49}'}; xLimits = [5.5 9.4]; @@ -74,15 +81,25 @@ switch downField_MM_Met end case '31P' - metaboliteNames = {'PCr' 'ATP-g' 'ATP-a' 'ATP-b' 'GPC' 'GPE' 'Pi_in' 'Pi_ext' 'PC' 'PE' 'NADH' 'NAD+' 'UDPG'}; - metaboliteLabels = {'PCr' 'ATP-gamma' 'ATP-alpha' 'ATP-beta' 'GPC' 'GPE' 'Pi intra' 'Pi extra' 'PC' 'PE' 'NADH' 'NAD+' 'UDPG'}; - xLimits = [-20 10]; - offsetMetabolite = 0.1; - case 'MM' - metaboliteNames = {'MM09' 'MM12' 'MM14' 'MM17' 'MM20' 'MM22' 'MM26' 'MM27' 'MM30' 'MM32' 'MM36' 'MM37' 'MM38' 'MM40' 'Cre'}; - metaboliteLabels = {'MM09' 'MM12' 'MM14' 'MM17' 'MM20' 'MM22' 'MM26' 'MM27' 'MM30' 'MM32' 'MM36' 'MM37' 'MM38' 'MM40' 'Cre'}; - xLimits = [0.5 4.097]; - offsetMetabolite = 0.1; + + metaboliteNames = {'Cr' 'ATP-g' 'ATP-a' 'GPC' 'GPE' 'Pi_in' 'Pi_ext' 'PC' 'PE' 'NADH' 'NAD' 'UDPG'}; + metaboliteLabels = {'PCr' 'ATP-gamma' 'ATP-alpha' 'GPC' 'GPE' 'Pi intra' 'Pi extra' 'PC' 'PE' 'NADH' 'NAD+' 'UDPG'}; + xLimits = [-10 10]; + case 'fit' + + metaboliteNames = {}; %, 'NAA', 'Cr39', 'MMB_si', 'NAA', 'Cr39', 'Cr30', 'mI' 'combin' + metaboliteLabels = {}; %, 'NAA', 'Cr', 'MM' , 'NAA', 'Cr-CH_2', 'Cr-CH_3', 'mI' 'MM' + xLimits = [0.5 4.05] + offsetMetabolite = 0.15; %0.25 + + case 'MM' + + metaboliteNames = {'MM09', 'MM12', 'MM14', 'MM17', 'MM20', 'MM22', 'MM26', 'MM27', 'MM30', 'MM32', 'MM36', 'MM37', 'MM38', 'Cr39', 'NAA', 'mI' ,'GPC', 'Glu', 'NAA_as'};% %, 'Cho', 'Glu', 'Gln', 'Tau', 'Glycin' 'PCr' %, 'NAA_si', 'Creat', 'PCreat', 'GPC','Glu', 'Gln', 'GABA','NAA_as','Asp','Tau', 'mI', 'Glycin' + metaboliteLabels = {'M_{0.92}', 'M_{1.21}', 'M_{1.39}', 'M_{1.67}', 'M_{2.04}', 'M_{2.26}', 'M_{2.56}', 'M_{2.70}', 'M_{2.99}', 'M_{3.21}', 'M_{3.62}', 'M_{3.75}', 'M_{3.86}' , 'tCr(CH_2)', 'NAA(CH_3)', 'mI', 'GPC', 'Glu', 'NAA_(asp)'}; %%'NAA', 'tCr(CH_{3})', 'tCho', 'Glu', 'Gln', 'Tau', 'Glyc', %, , 'NAA(CH_3)','tCr(CH_3)', 'tCr(CH_2)','GPC','Glu','Gln','GABA','NAA_{asp}', 'Asp', 'Tau', 'mI', 'Glycin' + xLimits = [0.5 4.097] + offsetMetabolite = 0.60; %0.25 + + otherwise error('Not known downField_MM_Met'); end @@ -95,13 +112,15 @@ end numberOfMet = length(metaboliteNames); %plotting offsets + offsetResidual = offsetMetabolite * (numberOfMet+1); offsetBaseline = offsetResidual + offsetMetabolite; -FontSize = 14; +FontSize = 18; % LineWidth = 1.5; -% FontSize = 12; +FontSize = 12; LineWidth = 2; + % ppm = {}; pData = {}; @@ -112,7 +131,7 @@ rData = {}; % close all; for index =1:length(FileName) - figId = figure(index+10); + figId = figure;%(index+10); %I am not sure if we need this indexing anymore. It is useful to have it like this for ProFit comparison %[c1 c2 c3 c4] = textread(strcat(PathName,FileName{i}),'%s %s %s %s'); c = textread(strcat(PathName,FileName{index}),'%s'); nOfPoints = find(strcmp(c ,'points'),1); @@ -156,38 +175,54 @@ for index =1:length(FileName) %residual rData{index} = pData{index} - fData{index}; - %scaling calculation + %scaling calculation scale = max(pData{index}); %plotting hold on - if MMB_available - p = plot(ppm{index}, (pData{index} - bData{index}) ./ scale , ... - ppm{index},(fData{index} - bData{index}) ./ scale , ... - ppm{index},(mmData{index}- bData{index} ) ./ scale - 0.03 , ... - ppm{index},bData{index} ./ scale - offsetBaseline, ... - ppm{index},rData{index} ./ scale - offsetResidual); - text(xLimitsText,-0.03,'MMB', 'FontSize', FontSize, 'FontWeight', 'bold'); + if displayBaseline + if MMB_available + p = plot(ppm{index}, pData{index} ./ scale , ... + ppm{index},fData{index} ./ scale , ... + ppm{index},(mmData{index}- bData{index}) ./ scale - 0.03 , ... + ppm{index},bData{index} ./ scale - offsetBaseline, ... + ppm{index},rData{index} ./ scale - offsetResidual); + text(xLimitsText,-0.03,'MM Spec.', 'FontSize', FontSize, 'FontWeight', 'bold'); + else + p = plot(ppm{index}, pData{index} ./ scale, ... + ppm{index},fData{index} ./ scale, ... + ppm{index},bData{index} ./ scale - offsetBaseline, ... + ppm{index},rData{index} ./ scale - offsetResidual); + end else - p = plot(ppm{index}, (pData{index}- bData{index}) ./ scale, ... - ppm{index},(fData{index}- bData{index}) ./ scale, ... - ppm{index},bData{index} ./ scale - offsetBaseline, ... - ppm{index},rData{index} ./ scale - offsetResidual); + if MMB_available + p = plot(ppm{index}, (pData{index} - bData{index}) ./ scale , ... + ppm{index},(fData{index} - bData{index}) ./ scale , ... + ppm{index},(mmData{index}- bData{index} ) ./ scale - 0.03 , ... + ppm{index},bData{index} ./ scale - offsetBaseline, ... + ppm{index},rData{index} ./ scale - offsetResidual); + text(xLimitsText,-0.03,'MM Spec.', 'FontSize', FontSize, 'FontWeight', 'bold'); + else + p = plot(ppm{index}, (pData{index}- bData{index}) ./ scale, ... + ppm{index},(fData{index}- bData{index}) ./ scale, ... + ppm{index},bData{index} ./ scale - offsetBaseline, ... + ppm{index},rData{index} ./ scale - offsetResidual); + end end - + if overviewPlots && strcmp(downField_MM_Met, 'DF') -% text(xLimitsText,0.05,'Data + Fit', 'FontSize', FontSize, 'FontWeight', 'bold'); + % text(xLimitsText,0.05,'Data + Fit', 'FontSize', FontSize, 'FontWeight', 'bold'); text(xLimitsText,0.07,'Data + Fit', 'FontSize', FontSize, 'FontWeight', 'bold'); else - text(xLimitsText,0.015,'Data + Fit', 'FontSize', FontSize, 'FontWeight', 'bold'); + text(xLimitsText,0.03,'Data + Fit', 'FontSize', FontSize, 'FontWeight', 'bold'); end text(xLimitsText,-offsetResidual,'Residual', 'FontSize', FontSize, 'FontWeight', 'bold'); -% text(xLimitsText,-offsetBaseline,'Baseline', 'FontSize', FontSize, 'FontWeight', 'bold'); + % text(xLimitsText,-offsetBaseline,'Baseline', 'FontSize', FontSize, 'FontWeight', 'bold'); text(xLimitsText,-offsetBaseline-0.01,'Baseline', 'FontSize', FontSize, 'FontWeight', 'bold'); for plots = 1:length(p) set(p(plots),'LineWidth',LineWidth); end - + for indexMetabolite = 1:length(metaboliteNames) %evaluate each metabolite if strcmp(metaboliteNames{indexMetabolite},'NAD+') @@ -204,6 +239,7 @@ for index =1:length(FileName) metaboliteSpectrum = metaboliteSpectrum + str2double(c(indexOfMet:endOfMet,1)) - bData{index}; end end + if MMB_available pMetabolite = plot(ppm{index}, metaboliteSpectrum ./ scale - indexMetabolite * offsetMetabolite); text(xLimitsText, indexMetabolite * -offsetMetabolite,metaboliteLabels{indexMetabolite}, 'FontSize', FontSize, 'FontWeight', 'bold'); @@ -211,14 +247,14 @@ for index =1:length(FileName) pMetabolite = plot(ppm{index}, metaboliteSpectrum ./ scale - (indexMetabolite-1) * offsetMetabolite); text(xLimitsText, (indexMetabolite-1) * -offsetMetabolite,metaboliteLabels{indexMetabolite}, 'FontSize', FontSize, 'FontWeight', 'bold'); end + set(pMetabolite,'LineWidth',LineWidth); end - deltaChar = char(948); - xlim(xLimits); - xlabel([deltaChar ' (ppm)']); - ylim([-offsetBaseline-offsetMetabolite*2 1.1]); + xlabel('\delta (ppm)'); + % ylim([-offsetBaseline-offsetMetabolite*2 0.07]); + ylim([-offsetBaseline-offsetMetabolite*2 1.1]);% for ProFit if strcmp(downField_MM_Met, 'Met moiety') else % ylim([-0.08 0.1]); @@ -228,14 +264,18 @@ for index =1:length(FileName) ylim([-0.21 0.1]); % ylim([-0.16 0.115]); ylim([-2 1.1]); + end + set(gca,'xDir','reverse') set(gca,'ytick',[]); - -% title(['Summed Metabolite Spectrum with Fitted Metabolites TE = 24 ms']) -% title(FileName{index}, 'Interpreter', 'none') + + % title(['Summed Metabolite Spectrum with Fitted Metabolites TE = 24 ms']) + % title(FileName{index}, 'Interpreter', 'none') + set(gca,'fontsize',FontSize); set(gca,'FontWeight','bold'); + clear nOfPoints indexOfMet i if saveFigures diff --git a/postprocessing/subtractMetabolitesFromMMB.m b/postprocessing/subtractMetabolitesFromMMB.m index 9f3a0e6b31266049a98afd760e49db286c80aa74..50a3bffb658bea89c79b44286b5b219b11ceca63 100644 --- a/postprocessing/subtractMetabolitesFromMMB.m +++ b/postprocessing/subtractMetabolitesFromMMB.m @@ -1,16 +1,16 @@ function subtractMetabolitesFromMMB() -pathName = 'MM data path'; -sampleCriteria = {'Output'}; +pathName = 'MM T1 data path'; +sampleCriteria = {'Output_GM_FinalCorrected'}; [localFilePathBase] = pathToDataFolder(pathName, sampleCriteria); -LCModelOutputPath = [localFilePathBase, 'Output/']; +LCModelOutputPath = [localFilePathBase, 'Output_GM_FinalCorrected/']; -outputFileNameBase = 'Summed_Averaged_TE'; -fileNameBaseWithoutMetabolite = 'MMB_without_metabolite_TE'; -orderTEs = {'24' '32' '40' '52' '60'}; +outputFileNameBase = 'Summed_Averaged_TI1_'; +fileNameBaseWithoutMetabolite = 'MMB_without_metabolite_TI1_'; +orderTEs = {'1900'}; %'2360' '2000' '1900' '1800' extensionCoord = '.coord'; extensionMat = '.mat'; -metabolitesToSubtract = {'Cre'}; +metabolitesToSubtract = {'Cr39', 'Cr30', 'NAA', 'Glx'}; doNullingOfDownField = true; LCModelTableFitsCoord = strcat(outputFileNameBase, orderTEs, extensionCoord); reconstructedSpectra = strcat(localFilePathBase, outputFileNameBase, orderTEs, extensionMat); @@ -28,25 +28,25 @@ LineWidth = 1.5; for indexTE = 1:numberOfTEs currentReconstructedSpectra = reconstructedSpectra{indexTE}; - load(currentReconstructedSpectra, 'summedSpectraTE'); + load(currentReconstructedSpectra, 'summedSpectraTI'); currentLCModelCoordFit = LCModelTableFitsCoord{indexTE}; [nOfPoints, ppmVector, phasedData, fitData, baselineData, residualData, ... metaboliteNames, metaboliteData, tableConcentrations, ppmStart, ppmEnd, ... scanFrequency, frequencyShift, ppmGap] = ... extractFits(LCModelOutputPath,currentLCModelCoordFit); - + ppmGap = 4.1 % align the two spectra - fid = summedSpectraTE.Data{1}; + fid = summedSpectraTI.Data{1}; spectrum = fftshift(fft(fid(:,1,1,1,1,1,1,1,1,1,1,1),size(fid,1)*zeroFillFactor)); - ppmSpectrum = summedSpectraTE.getPpmVector(zeroFillFactor); + ppmSpectrum = summedSpectraTI.getPpmVector(zeroFillFactor); [~, maxPpmValueSpectrum] = getMaxPeak(ppmSpectrum', real(spectrum), 3.925, 0.1); [~, maxPpmValueLCModel] = getMaxPeak(ppmVector, phasedData, 3.925, 0.1); frequencyShiftDiff = maxPpmValueSpectrum - maxPpmValueLCModel; - summedSpectraTE = summedSpectraTE.ApplyFrequencyShift(frequencyShiftDiff); + summedSpectraTI = summedSpectraTI.ApplyFrequencyShift(frequencyShiftDiff); %get the aligned reconstructed spectra - fid = summedSpectraTE.Data{1}; + fid = summedSpectraTI.Data{1}; spectrum = fftshift(fft(fid(:,1,1,1,1,1,1,1,1,1,1,1),size(fid,1)*zeroFillFactor)); % max of the reconstructed spectrum if isempty(ppmGap) @@ -122,7 +122,7 @@ for indexTE = 1:numberOfTEs % xlim([0 4.2]) % title(sprintf('Imag MMB TE %s', orderTEs{indexTE})) - MMB_without_metabolite = summedSpectraTE; + MMB_without_metabolite = summedSpectraTI; newFid = ifft(ifftshift(newSpectrum)); MMB_without_metabolite.Data{1} = newFid; diff --git a/reconstruct_all_Met.m b/reconstruct_all_Met.m new file mode 100644 index 0000000000000000000000000000000000000000..11fb0de70cd4fee488a9baa0376a0ee850b1feb1 --- /dev/null +++ b/reconstruct_all_Met.m @@ -0,0 +1,161 @@ +function reconstruct_all_Met() + +pathName = 'Met T1 GM data path'; +subjects = { ... + '1405' ... + '1706' ... + '1717' ... + '2016' ... + '2017' ... + '3373' ... + '3490' ... + '6971' ... + '7338' ... + '7782' ... + '9810' ... + }; + +pathBase = pathToDataFolder(pathName, subjects); + +TI = [20; 100; 400; 700; 1000; 1400; 2500]; + +numberOfSubjects = length(subjects); +paths = cell(1,numberOfSubjects); +for indexSubj = 1:numberOfSubjects + paths{indexSubj} = [pathBase subjects{indexSubj} '\\']; +end + +files_TI_20 = cell(1, numberOfSubjects); +files_TI_100 = cell(1, numberOfSubjects); +files_TI_400 = cell(1, numberOfSubjects); +files_TI_700 = cell(1, numberOfSubjects); +files_TI_1000 = cell(1, numberOfSubjects); +files_TI_1400 = cell(1, numberOfSubjects); +files_TI_2500 = cell(1, numberOfSubjects); + +% water_files = cell(1, numberOfSubjects); +for indexSubject = 1:numberOfSubjects + files_TI_20{indexSubject} = ls([paths{indexSubject}, '*_semiLASER_2360_625_*.dat']); + files_TI_100{indexSubject} = ls([paths{indexSubject}, '*_semiLASER_1800_525_*.dat']); + files_TI_400{indexSubject} = ls([paths{indexSubject}, '*_semiLASER_1900_550_*.dat']); + files_TI_700{indexSubject} = ls([paths{indexSubject}, '*_semiLASER_2000_575_*.dat']); + files_TI_1000{indexSubject} = ls([paths{indexSubject}, '*_semiLASER_2150_600_*.dat']); + files_TI_1400{indexSubject} = ls([paths{indexSubject}, '*_semiLASER_1200_20_*.dat']); + files_TI_2500{indexSubject} = ls([paths{indexSubject}, '*_semiLASER_1250_20_*.dat']); +% files_TI_1300_80{indexSubject} = ls([paths{indexSubject}, '*_semiLASER_1300_80_*.dat']); +% files_TI_1300_60{indexSubject} = ls([paths{indexSubject}, '*_semiLASER_1300_60_*.dat']); +% files_TI_1300_20{indexSubject} = ls([paths{indexSubject}, '*_semiLASER_1300_20_*.dat']); +% files_TI_1050_238{indexSubject} = ls([paths{indexSubject}, '*_semiLASER_1050_238_*.dat']); +% water_files{indexSubject} = ls([paths{indexSubject}, '*_scout_wref_*.dat']); +end + +addSinglet0ppm = 'Yes'; +numberOfTIs = length(TI); + +filesPath = cell(numberOfTIs,numberOfSubjects); +waterFilesPath = cell(1,numberOfSubjects); +files = [files_TI_20; files_TI_100; files_TI_400;files_TI_700;... + files_TI_1000; files_TI_1400; files_TI_2500;]; +for indexSubj = 1:numberOfSubjects + for indexTI = 1:numberOfTIs + filesPath{indexTI, indexSubj} = [paths{indexSubj} files{indexTI, indexSubj}]; + end +% waterFilesPath{indexSubj} = [paths{indexSubj} water_files{indexSubj}]; +end + +summedSpectra = cell(numberOfTIs,1); +indexSubjTIs = zeros(numberOfTIs,1); +for indexSubj = 1:numberOfSubjects + %% water data +% [a] = reconstructWater(waterFilesPath{indexSubj}); +% filename = [paths{indexSubj} subjects{indexSubj} '_water.mat']; +% save(filename, 'a'); +% a.ExportLcmRaw(paths{indexSubj}, strcat(subjects{indexSubj}, '_water'), addSinglet0ppm); + %calculate scaling factor the summedSpectra individually according to water peak +% waterData = a.Data{1}; +% maxWaterPeak = max(real(fftshift(fft(waterData)))); +% %scale the data for equalizing between subjects +% a.Data{1} = a.Data{1}./ maxWaterPeak; + %create summed spectra +% if(indexSubj == 1) +% summedWater = a; +% newDataWater= zeros(length(a.Data{1}),1,1,1,1,1,1,1,1,1,1,numberOfSubjects); +% else +% oldDataWater = summedWater.Data{1}; +% if (ndims(oldDataWater) ~= 12) +% newDataWater(:,1,1,1,1,1,1,1,1,1,1,1) = oldDataWater; +% else +% newDataWater(:,1,1,1,1,1,1,1,1,1,1,:) = oldDataWater; +% end +% newDataWater(:,1,1,1,1,1,1,1,1,1,1,indexSubj) = a.Data{1}; +% summedWater.Data{1} = newDataWater; +% end + + + + %% reconstruct Macromolecule data + for indexTI = 1:numberOfTIs + if((TI(indexTI) == 1300)| (TI(indexTI) ==1250) | (TI(indexTI)==1200)) + doReverse = false; + else + doReverse = false; + end + a = reconstruct(filesPath{indexTI, indexSubj}, 1, 1); + filename = [paths{indexSubj} subjects{indexSubj} '_TI_' num2str(TI(indexTI)) '.mat']; + save(filename, 'a'); + a.ExportLcmRaw(paths{indexSubj}, strcat(subjects{indexSubj}, '_TI1_', num2str(TI(indexTI))) , addSinglet0ppm); + %scale the data for equalizing between subjects +% a.Data{1} = a.Data{1}./ maxWaterPeak; + + % eliminate data with too many deleted averages from the summedSpectra + + deletedAverages = a.Parameter.DeleteMovedAveragesSettings.deletedAverages; + if ~isempty(deletedAverages) + numDeletedAverages = length(deletedAverages); + else + numDeletedAverages = 0; + end + + if numDeletedAverages <= 2 + indexSubjTIs(indexTI) = indexSubjTIs(indexTI) + 1; + %create summed spectra + if(indexSubjTIs(indexTI) == 1) + summedSpectra{indexTI} = a; + newData= zeros(length(a.Data{1}),1,1,1,1,1,1,1,2,1,1,numberOfSubjects); + else + oldData = summedSpectra{indexTI}.Data{1}; + if (ndims(oldData) ~= 12) + newData(:,1,1,1,1,1,1,1,:,1,1,1) = oldData; + else + newData(:,1,1,1,1,1,1,1,:,1,1,:) = oldData; + end + newData(:,1,1,1,1,1,1,1,:,1,1,indexSubjTIs(indexTI)) = a.Data{1}; + summedSpectra{indexTI}.Data{1} = newData; + end + end + end +end + +% + +% filename = [pathBase, 'Summed_water.mat']; +% save(filename, 'summedWater'); +% summedWater = summedWater.AverageData; +% save([pathBase, 'Summed_Averaged_water.mat'], 'summedWater'); +% summedWater.ExportLcmRaw(pathBase, 'Summed_Averaged_water', addSinglet0ppm); +for indexTI = 1:numberOfTIs + filename = [pathBase, 'Summed_spectra_TI' num2str(TI(indexTI)) '.mat']; + summedSpectraTI = summedSpectra{indexTI}; + %store only the data, which was kept after eliminating the deleted ones + actualData = summedSpectraTI.Data{1}./indexSubjTIs(indexTI); + summedSpectraTI.Data{1} = actualData(:,1,1,1,1,1,1,1,:,1,1,1:indexSubjTIs(indexTI)); + save(filename, 'summedSpectraTI'); + %average across subjects + summedSpectraTI = summedSpectraTI.AverageData; + filename = [pathBase, 'Summed_Averaged_TI_' num2str(TI(indexTI)) '.mat']; + save(filename, 'summedSpectraTI'); + summedSpectraTI.ExportLcmRaw(pathBase, strcat('Summed_Averaged_TI_', num2str(TI(indexTI))), addSinglet0ppm); +end + +%summarize_Deleted_Averages(subjects, pathBase, TI1) +close all diff --git a/spant_metabolites_basis_sets_creation.m b/spant_metabolites_basis_sets_creation.m new file mode 100644 index 0000000000000000000000000000000000000000..6810dcadb74eaa725b3cee7c96180a16477e59ad --- /dev/null +++ b/spant_metabolites_basis_sets_creation.m @@ -0,0 +1,61 @@ + +function spant_metabolites_basis_sets_creation() + +plotBasis = false; + +metabolites = {'Asp', 'Cr_singlet_tot_3.925', 'Cr_singlet_tot_3.028', 'GABA', 'Gln', 'Glu', 'Glyc', ... + 'GSH', 'Lac', 'mI', 'NAA_2', 'NAA_1', 'NAAG', 'tCho_PE', 'Scyllo', 'Tau'}; + +numberOfMet = length(metabolites); +abbreviations = metabolites; +metaboliteNames = metabolites; +scalingFactors = zeros(numberOfMet,1)+1; + +abbreviationsUnique = unique(abbreviations); + +pathName = 'DF data path'; +sampleCriteria = {}; +[localFilePathBase] = pathToDataFolder(pathName, sampleCriteria); + +filePathBase = strcat(localFilePathBase, 'Basis_sets/final_T2_met_MM_paper/sLASER_new_UF_7ppm/'); +filePathBaseOut = strcat(filePathBase, 'Out/'); +orderTEs = {'24' '32' '40' '52' '60'}; +filePaths = strcat(filePathBase, 'TE', orderTEs , '\'); +filePathsOut = strcat(filePathBaseOut, 'TE', orderTEs , '\'); + +for indexTE = 1 : length(orderTEs) + filePath = filePaths{indexTE}; + filePathOut = filePathsOut{indexTE}; + for indexMetabolite = 1 : length(abbreviationsUnique) + combined_metabolite_name = abbreviationsUnique{indexMetabolite}; + indeces = strcmp(abbreviations,combined_metabolite_name); + numOfMetToCombine = sum(indeces); + metabolitesToMix = metaboliteNames(indeces); + factorsToMix = scalingFactors(indeces); + % + dataMix = cell(1,numOfMetToCombine); + metaboliteNameMix = cell(1,numOfMetToCombine); + singletPresentMix = cell(1,numOfMetToCombine); + + for indexMetabolitesToMix = 1:numOfMetToCombine + [dataMix{indexMetabolitesToMix}, bandwidth, scanFrequency, metaboliteNameMix{indexMetabolitesToMix}, ... + singletPresentMix{indexMetabolitesToMix}] = ... + ImportLCModelBasis(filePath, metabolitesToMix{indexMetabolitesToMix}, ... + plotBasis); + end + %combine + combinedData = dataMix{1} * factorsToMix(1); + for indexMetabolitesToMix = 2:numOfMetToCombine + % average the contributions. Don't worry about the + % ref. singlet, it does not influence the fitting + combinedData = combinedData + factorsToMix{indexMetabolitesToMix} * ... + dataMix{indexMetabolitesToMix}; + end + + dwellTimeMs = 1/bandwidth * 1e3; + addSinglet = false; + + ExportLCModelBasis(combinedData', dwellTimeMs, scanFrequency, filePathOut, ... + combined_metabolite_name, combined_metabolite_name, addSinglet); + end +end