diff --git a/+nla/+net/+test/KolmogorovSmirnovTest.m b/+nla/+net/+test/KolmogorovSmirnovTest.m deleted file mode 100644 index 1207f222..00000000 --- a/+nla/+net/+test/KolmogorovSmirnovTest.m +++ /dev/null @@ -1,68 +0,0 @@ -classdef KolmogorovSmirnovTest < handle - %KOLMOGOROVSMIRNOVTEST Kolmogorov-Smirnov test - properties (Constant) - name = "kolmogorov_smirnov" - display_name = "Kolmogorov-Smirnov" - statistics = ["ks_statistic", "single_sample_ks_statistic"] - ranking_statistic = "ks_statistic" - end - - methods - function obj = KolmogorovSmirnovTest() - end - - function result = run(obj, test_options, edge_test_results, network_atlas, permutations) - %RUN runs the Kolmogorov-Smirnov goodness of fit test - % test_options: The selected values for the test to be run. Formerly input_struct. Options are in nla.net.genBaseInputs - % edge_test_results: Non-permuted edge test results. Formerly edge_result - % network_atlas: Network atlas for data - - import nla.TriMatrix nla.TriMatrixDiag - - number_of_networks = network_atlas.numNets(); - - % Store results in the 'no_permutations' structure if this is the no-permutation test - permutation_results = "no_permutations"; - ks_statistic = "ks_statistic"; - p_value = "uncorrected_two_sample_p_value"; - single_sample_p_value = "uncorrected_single_sample_p_value"; - single_sample_ks_statistic = "single_sample_ks_statistic"; - if isequal(permutations, true) - % Otherwise, add it on to the back of the 'permutation_results' structure - permutation_results = "permutation_results"; - p_value = "two_sample_p_value_permutations"; - ks_statistic = strcat(ks_statistic, "_permutations"); - single_sample_p_value = "single_sample_p_value_permutations"; - single_sample_ks_statistic = strcat(single_sample_ks_statistic, "_permutations"); - end - - result = nla.net.result.NetworkTestResult(test_options, number_of_networks, obj.name, obj.display_name, obj.statistics, obj.ranking_statistic); - - % Double for-loop to iterate through trimatrix. Network is the row, network2 the column. Since - % we only care about the bottom half, second for-loop is 1:network - for network = 1:number_of_networks - for network2 = 1:network - network_rho = edge_test_results.coeff.get(network_atlas.nets(network).indexes,... - network_atlas.nets(network2).indexes); - [~, p, ks] = kstest2(network_rho, edge_test_results.coeff.v); - result.(permutation_results).(p_value).set(network, network2, p); - result.(permutation_results).(ks_statistic).set(network, network2, ks); - - [~, single_sample_p, single_sample_ks] = kstest(network_rho); - result.(permutation_results).(single_sample_p_value).set(network, network2, single_sample_p); - result.(permutation_results).(single_sample_ks_statistic).set(network, network2, single_sample_ks); - end - end - - end - end - - methods (Static) - function inputs = requiredInputs() - inputs = {... - nla.inputField.Integer('behavior_count', 'Test count:', 1, 1, Inf),... - nla.inputField.Number('prob_max', 'Net-level P threshold <', 0, 0.05, 1),... - }; - end - end -end \ No newline at end of file diff --git a/+nla/+qualityControl/checkNormalityWithKS.m b/+nla/+qualityControl/checkNormalityWithKS.m new file mode 100644 index 00000000..58ad6e39 --- /dev/null +++ b/+nla/+qualityControl/checkNormalityWithKS.m @@ -0,0 +1,64 @@ +function checkNormalityWithKS(fig, input_struct, test_pool) + + prog = uiprogressdlg(... + fig, 'Title', 'Checking Normaility', 'Message', 'Running Kolmogorov-Smirnov Test'... + ); + prog.Value = 0.02; + + prog.Value = 0.25; + edge_test_result = test_pool.runEdgeTest(input_struct); + + prog.Value = 0.5; + ks_result = runKolmogorovSmirnovTest(input_struct, edge_test_result); + + prog.Value = 0.75; + qcKSOutput(ks_result.p, input_struct) + +end + +function ks_result = runKolmogorovSmirnovTest(input_struct, edge_result) + import nla.TriMatrix nla.TriMatrixDiag + + ks_result = struct(); + number_of_networks = input_struct.net_atlas.numNets(); + ks_result.p = TriMatrix(number_of_networks, TriMatrixDiag.KEEP_DIAGONAL); + ks_result.ks = TriMatrix(number_of_networks, TriMatrixDiag.KEEP_DIAGONAL); + + for network1 = 1:number_of_networks + for network2 = 1:network1 + network_rho = edge_result.coeff.get(input_struct.net_atlas.nets(network1).indexes,... + input_struct.net_atlas.nets(network2).indexes); + [~, p, ks] = kstest(network_rho); + ks_result.p.set(network1, network2, p); + ks_result.ks.set(network1, network2, ks); + end + end +end + +function qcKSOutput(ks_result_p_value, edge_test_options) + % This will open the qc figure for the KS test + + network_test_options = nla.net.genBaseInputs(); + network_test_options.full_connectome = false; + network_test_options.within_network_pair = false; + network_test_options.fdr_correction = nla.net.mcc.None(); + edge_test_options.prob_max = 0.05; + default_discrete_colors = 1000; + + p_value_max = network_test_options.fdr_correction.correct(edge_test_options.net_atlas,... + edge_test_options, ''); + + color_map = nla.net.result.NetworkResultPlotParameter.getColormap(default_discrete_colors,... + p_value_max); + + fig = nla.gfx.createFigure(); + % Also remember to move this in read the docs + matrix_plot = nla.gfx.plots.MatrixPlot(fig, sprintf("Non-permuted Kolmogorov-Smirnov Test p-value\nSmaller values are less normal"), ks_result_p_value, edge_test_options.net_atlas.nets, nla.gfx.FigSize.LARGE,... + 'lower_limit', 0.00, 'upper_limit', p_value_max, 'color_map', color_map); + matrix_plot.displayImage(); + width = matrix_plot.image_dimensions('image_width'); + height = matrix_plot.image_dimensions('image_height'); + + fig.Position(3) = width; + fig.Position(4) = height; +end \ No newline at end of file diff --git a/NLAQualityControl.mlapp b/NLAQualityControl.mlapp index 335374a3..97ded08b 100644 Binary files a/NLAQualityControl.mlapp and b/NLAQualityControl.mlapp differ diff --git a/NLA_GUI.mlapp b/NLA_GUI.mlapp index fd6e8f7e..7334fc98 100755 Binary files a/NLA_GUI.mlapp and b/NLA_GUI.mlapp differ diff --git a/NLA_GUI_exported.m b/NLA_GUI_exported.m index 83571bb7..e308bf10 100644 --- a/NLA_GUI_exported.m +++ b/NLA_GUI_exported.m @@ -6,24 +6,25 @@ FileMenu matlab.ui.container.Menu OpenpreviousresultMenu matlab.ui.container.Menu GridLayout matlab.ui.container.GridLayout + Panel_7 matlab.ui.container.Panel + RunQualityControlButton matlab.ui.control.Button + MethodsPanel matlab.ui.container.Panel + NonPermutedCheckBox matlab.ui.control.CheckBox + FullConnCheckBox matlab.ui.control.CheckBox + WithinNetPairCheckBox matlab.ui.control.CheckBox + NetInputsPanel matlab.ui.container.Panel Panel_3 matlab.ui.container.Panel NoneButton matlab.ui.control.Button NetTestSelector matlab.ui.control.ListBox NetworkleveltestsCtrlclickformultipleLabel matlab.ui.control.Label - BranchLabel matlab.ui.control.Label EdgeInputsPanel matlab.ui.container.Panel - NetInputsPanel matlab.ui.container.Panel Panel matlab.ui.container.Panel EdgeTestSelector matlab.ui.control.DropDown EdgeleveltestDropDownLabel matlab.ui.control.Label - Panel_2 matlab.ui.container.Panel + BranchLabel matlab.ui.control.Label + Panel_5 matlab.ui.container.Panel RunButton matlab.ui.control.Button - MethodsPanel matlab.ui.container.Panel - NonPermutedCheckBox matlab.ui.control.CheckBox - FullConnCheckBox matlab.ui.control.CheckBox - WithinNetPairCheckBox matlab.ui.control.CheckBox - RunQualityControlButton matlab.ui.control.Button - PermutationcountLabel matlab.ui.control.Label + PermutationcountEditField_2Label matlab.ui.control.Label PermutationcountEditField matlab.ui.control.NumericEditField end @@ -304,7 +305,7 @@ function createComponents(app) % Create NetworkLevelAnalysisUIFigure and hide until all components are created app.NetworkLevelAnalysisUIFigure = uifigure('Visible', 'off'); - app.NetworkLevelAnalysisUIFigure.Position = [100 100 1151 718]; + app.NetworkLevelAnalysisUIFigure.Position = [100 100 786 620]; app.NetworkLevelAnalysisUIFigure.Name = 'NetworkLevelAnalysis'; % Create FileMenu @@ -319,12 +320,59 @@ function createComponents(app) % Create GridLayout app.GridLayout = uigridlayout(app.NetworkLevelAnalysisUIFigure); - app.GridLayout.ColumnWidth = {'1x', 598}; - app.GridLayout.RowHeight = {38, 100, '1x', 53, 1}; + app.GridLayout.ColumnWidth = {'4x', '2x'}; + app.GridLayout.RowHeight = {38, 200, '1x', 40}; app.GridLayout.ColumnSpacing = 8.66666666666667; app.GridLayout.RowSpacing = 3.4; app.GridLayout.Padding = [8.66666666666667 3.4 8.66666666666667 3.4]; + % Create Panel_7 + app.Panel_7 = uipanel(app.GridLayout); + app.Panel_7.BorderType = 'none'; + app.Panel_7.Layout.Row = 3; + app.Panel_7.Layout.Column = 2; + + % Create RunQualityControlButton + app.RunQualityControlButton = uibutton(app.Panel_7, 'push'); + app.RunQualityControlButton.ButtonPushedFcn = createCallbackFcn(app, @RunQualityControlButtonPushed, true); + app.RunQualityControlButton.Position = [107 8 138 24]; + app.RunQualityControlButton.Text = 'Run Quality Control'; + + % Create MethodsPanel + app.MethodsPanel = uipanel(app.Panel_7); + app.MethodsPanel.Title = 'MethodsPanel'; + app.MethodsPanel.Position = [1 39 253 112]; + + % Create NonPermutedCheckBox + app.NonPermutedCheckBox = uicheckbox(app.MethodsPanel); + app.NonPermutedCheckBox.ValueChangedFcn = createCallbackFcn(app, @MethodButtonGroupSelectionChanged, true); + app.NonPermutedCheckBox.Tag = 'nonpermuted'; + app.NonPermutedCheckBox.Enable = 'off'; + app.NonPermutedCheckBox.Text = 'Non-permuted'; + app.NonPermutedCheckBox.Position = [9 65 99 22]; + app.NonPermutedCheckBox.Value = true; + + % Create FullConnCheckBox + app.FullConnCheckBox = uicheckbox(app.MethodsPanel); + app.FullConnCheckBox.ValueChangedFcn = createCallbackFcn(app, @MethodButtonGroupSelectionChanged, true); + app.FullConnCheckBox.Tag = 'full_con'; + app.FullConnCheckBox.Text = 'Full connectome'; + app.FullConnCheckBox.Position = [9 35 110 22]; + app.FullConnCheckBox.Value = true; + + % Create WithinNetPairCheckBox + app.WithinNetPairCheckBox = uicheckbox(app.MethodsPanel); + app.WithinNetPairCheckBox.ValueChangedFcn = createCallbackFcn(app, @MethodButtonGroupSelectionChanged, true); + app.WithinNetPairCheckBox.Tag = 'within_net_pair'; + app.WithinNetPairCheckBox.Text = 'Within Net-pair'; + app.WithinNetPairCheckBox.Position = [9 5 101 22]; + app.WithinNetPairCheckBox.Value = true; + + % Create NetInputsPanel + app.NetInputsPanel = uipanel(app.Panel_7); + app.NetInputsPanel.Title = 'NetInputsPanel'; + app.NetInputsPanel.Position = [1 164 253 162]; + % Create Panel_3 app.Panel_3 = uipanel(app.GridLayout); app.Panel_3.BorderType = 'none'; @@ -334,7 +382,7 @@ function createComponents(app) % Create NoneButton app.NoneButton = uibutton(app.Panel_3, 'push'); app.NoneButton.ButtonPushedFcn = createCallbackFcn(app, @NoneButtonPushed, true); - app.NoneButton.Position = [85 80 48 21]; + app.NoneButton.Position = [145 206 48 21]; app.NoneButton.Text = 'None'; % Create NetTestSelector @@ -342,34 +390,21 @@ function createComponents(app) app.NetTestSelector.Items = {}; app.NetTestSelector.Multiselect = 'on'; app.NetTestSelector.ValueChangedFcn = createCallbackFcn(app, @NetTestSelectorValueChanged, true); - app.NetTestSelector.Position = [146 2 182 138]; + app.NetTestSelector.Position = [1 8 193 192]; app.NetTestSelector.Value = {}; % Create NetworkleveltestsCtrlclickformultipleLabel app.NetworkleveltestsCtrlclickformultipleLabel = uilabel(app.Panel_3); app.NetworkleveltestsCtrlclickformultipleLabel.HorizontalAlignment = 'right'; - app.NetworkleveltestsCtrlclickformultipleLabel.Position = [6 110 125 28]; + app.NetworkleveltestsCtrlclickformultipleLabel.Position = [1 205 125 28]; app.NetworkleveltestsCtrlclickformultipleLabel.Text = {'Network-level tests'; '(Ctrl+click for multiple)'}; - % Create BranchLabel - app.BranchLabel = uilabel(app.Panel_3); - app.BranchLabel.HorizontalAlignment = 'right'; - app.BranchLabel.FontColor = [0.8 0.8 0.8]; - app.BranchLabel.Position = [336 123 263 22]; - app.BranchLabel.Text = 'gui | unknown_branch:0000000'; - % Create EdgeInputsPanel app.EdgeInputsPanel = uipanel(app.GridLayout); app.EdgeInputsPanel.Title = 'Edge-level inputs'; - app.EdgeInputsPanel.Layout.Row = [2 4]; + app.EdgeInputsPanel.Layout.Row = [2 3]; app.EdgeInputsPanel.Layout.Column = 1; - % Create NetInputsPanel - app.NetInputsPanel = uipanel(app.GridLayout); - app.NetInputsPanel.Title = 'Network-level inputs'; - app.NetInputsPanel.Layout.Row = 3; - app.NetInputsPanel.Layout.Column = 2; - % Create Panel app.Panel = uipanel(app.GridLayout); app.Panel.AutoResizeChildren = 'off'; @@ -390,69 +425,39 @@ function createComponents(app) app.EdgeleveltestDropDownLabel.Position = [1 8 85 22]; app.EdgeleveltestDropDownLabel.Text = 'Edge-level test'; - % Create Panel_2 - app.Panel_2 = uipanel(app.GridLayout); - app.Panel_2.AutoResizeChildren = 'off'; - app.Panel_2.BorderType = 'none'; - app.Panel_2.Layout.Row = 4; - app.Panel_2.Layout.Column = 2; + % Create BranchLabel + app.BranchLabel = uilabel(app.GridLayout); + app.BranchLabel.FontColor = [0.8 0.8 0.8]; + app.BranchLabel.Layout.Row = 4; + app.BranchLabel.Layout.Column = 1; + app.BranchLabel.Text = 'gui | unknown_branch:0000000'; + + % Create Panel_5 + app.Panel_5 = uipanel(app.GridLayout); + app.Panel_5.BorderType = 'none'; + app.Panel_5.Layout.Row = 4; + app.Panel_5.Layout.Column = 2; % Create RunButton - app.RunButton = uibutton(app.Panel_2, 'push'); + app.RunButton = uibutton(app.Panel_5, 'push'); app.RunButton.ButtonPushedFcn = createCallbackFcn(app, @RunButtonPushed, true); - app.RunButton.Position = [544 3 53 20]; + app.RunButton.BackgroundColor = [0.8902 0.9882 0.851]; + app.RunButton.Position = [191 6 53 30]; app.RunButton.Text = 'Run'; - % Create MethodsPanel - app.MethodsPanel = uipanel(app.Panel_2); - app.MethodsPanel.AutoResizeChildren = 'off'; - app.MethodsPanel.Title = 'Methods'; - app.MethodsPanel.Position = [1 2 345 48]; - - % Create NonPermutedCheckBox - app.NonPermutedCheckBox = uicheckbox(app.MethodsPanel); - app.NonPermutedCheckBox.ValueChangedFcn = createCallbackFcn(app, @MethodButtonGroupSelectionChanged, true); - app.NonPermutedCheckBox.Tag = 'nonpermuted'; - app.NonPermutedCheckBox.Enable = 'off'; - app.NonPermutedCheckBox.Text = 'Non-permuted'; - app.NonPermutedCheckBox.Position = [10 3 99 22]; - app.NonPermutedCheckBox.Value = true; - - % Create FullConnCheckBox - app.FullConnCheckBox = uicheckbox(app.MethodsPanel); - app.FullConnCheckBox.ValueChangedFcn = createCallbackFcn(app, @MethodButtonGroupSelectionChanged, true); - app.FullConnCheckBox.Tag = 'full_con'; - app.FullConnCheckBox.Text = 'Full connectome'; - app.FullConnCheckBox.Position = [118 3 110 22]; - app.FullConnCheckBox.Value = true; - - % Create WithinNetPairCheckBox - app.WithinNetPairCheckBox = uicheckbox(app.MethodsPanel); - app.WithinNetPairCheckBox.ValueChangedFcn = createCallbackFcn(app, @MethodButtonGroupSelectionChanged, true); - app.WithinNetPairCheckBox.Tag = 'within_net_pair'; - app.WithinNetPairCheckBox.Text = 'Within Net-pair'; - app.WithinNetPairCheckBox.Position = [236 3 101 22]; - app.WithinNetPairCheckBox.Value = true; - - % Create RunQualityControlButton - app.RunQualityControlButton = uibutton(app.Panel_2, 'push'); - app.RunQualityControlButton.ButtonPushedFcn = createCallbackFcn(app, @RunQualityControlButtonPushed, true); - app.RunQualityControlButton.Position = [472 29 125 21]; - app.RunQualityControlButton.Text = 'Run Quality Control'; - - % Create PermutationcountLabel - app.PermutationcountLabel = uilabel(app.Panel_2); - app.PermutationcountLabel.HorizontalAlignment = 'right'; - app.PermutationcountLabel.Position = [359 2 106 22]; - app.PermutationcountLabel.Text = 'Permutation count:'; + % Create PermutationcountEditField_2Label + app.PermutationcountEditField_2Label = uilabel(app.Panel_5); + app.PermutationcountEditField_2Label.HorizontalAlignment = 'right'; + app.PermutationcountEditField_2Label.Position = [6 8 106 26]; + app.PermutationcountEditField_2Label.Text = 'Permutation count:'; % Create PermutationcountEditField - app.PermutationcountEditField = uieditfield(app.Panel_2, 'numeric'); + app.PermutationcountEditField = uieditfield(app.Panel_5, 'numeric'); app.PermutationcountEditField.Limits = [0 Inf]; app.PermutationcountEditField.RoundFractionalValues = 'on'; app.PermutationcountEditField.ValueDisplayFormat = '%11d'; app.PermutationcountEditField.ValueChangedFcn = createCallbackFcn(app, @PermutationcountEditFieldValueChanged, true); - app.PermutationcountEditField.Position = [480 2 53 22]; + app.PermutationcountEditField.Position = [127 7 53 27]; app.PermutationcountEditField.Value = 10000; % Show the figure after all components are created diff --git a/docs/source/network_level_tests.rst b/docs/source/network_level_tests.rst index db40d8a8..b9eff44b 100644 --- a/docs/source/network_level_tests.rst +++ b/docs/source/network_level_tests.rst @@ -53,16 +53,6 @@ Provided Tests * :math:`\textstyle E_i = \sum_{}\frac{\text{thresholded & binarized ROIs}}{\text{number of ROIs}} \scriptstyle * (\text{number of ROIs in the network-pair of interest})` * :math:`O_i`: non-permuted, nominally thresholded, and binarized edge-level *p*-values for the network-pair of interest -* **Kolmogorov-Smirnov** - - * MATLAB `kstest2 `_ function. - - *Inputs:* - * Edge-level correlation coefficients for the network-pair of interest - * Edge-level correlation coefficients across the full connectome - - * **Note**: This input is not used for single-sample tests - * **Wilcoxon rank-sum test** * MATLAB `ranksum `_ function. diff --git a/docs/source/quality_control.rst b/docs/source/quality_control.rst new file mode 100644 index 00000000..e69de29b