diff --git a/snpm_cp.m b/snpm_cp.m index becd723..4e80a76 100644 --- a/snpm_cp.m +++ b/snpm_cp.m @@ -217,22 +217,22 @@ function snpm_cp(CWD) if strcmp(sDesFile, 'snpm_pi_OneSampT') || ... strcmp(sDesFile, 'snpm_pi_ANOVAwithinS') % Sign flipping - nidm_json('nidm_ErrorModel/nidm_hasErrorDistribution') = {'obo_nonparametricdistribution', 'obo_symmetricdistribution'}; - nidm_json('nidm_ErrorModel/nidm_errorVarianceHomogeneous') = false; - nidm_json('nidm_ErrorModel/nidm_varianceMapWiseDependence') = 'nidm_IndependentParameter'; - nidm_json('nidm_ErrorModel/nidm_hasErrorDependence') = 'nidm_IndependentError'; + nidm.ErrorModel_hasErrorDistribution = {'obo_nonparametricdistribution', 'obo_symmetricdistribution'}; + nidm.ErrorModel_errorVarianceHomogeneous = false; + nidm.ErrorModel_varianceMapWiseDependence = 'nidm_IndependentParameter'; + nidm.ErrorModel_hasErrorDependence = 'nidm_IndependentError'; else % Permutation - nidm_json('nidm_ErrorModel/nidm_hasErrorDistribution') = 'obo_nonparametricdistribution'; - nidm_json('nidm_ErrorModel/nidm_errorVarianceHomogeneous') = true; - nidm_json('nidm_ErrorModel/nidm_varianceMapWiseDependence') = 'nidm_IndependentParameter'; + nidm.ErrorModel_hasErrorDistribution = 'obo_nonparametricdistribution'; + nidm.ErrorModel_errorVarianceHomogeneous = true; + nidm.ErrorModel_varianceMapWiseDependence = 'nidm_IndependentParameter'; % TODO: the 'obo_exchangeable' term is not yet in STATO - nidm_json('nidm_ErrorModel/nidm_hasErrorDependence') = 'obo_exchangeable'; - nidm_json('nidm_ErrorModel/nidm_dependenceMapWiseDependence') = 'nidm_IndependentParameter'; + nidm.ErrorModel_hasErrorDependence = 'obo_exchangeable'; + nidm.ErrorModel_dependenceMapWiseDependence = 'nidm_IndependentParameter'; end % TODO: check this is correct -nidm_json('nidm_ModelParameterEstimation/nidm_withEstimationMethod') = 'obo_ordinaryleastsquaresestimation'; +nidm.ModelParameterEstimation_withEstimationMethod = 'obo_ordinaryleastsquaresestimation'; if isempty([H C]) error('SnPM:NoModel', 'No model specified; [H C] empty'); @@ -244,44 +244,38 @@ function snpm_cp(CWD) error('SnPM:InvalidContrast','Contrast problem; wrong number of columns'); end -if size(CONT,1) > 1 - contrastMap = containers.Map(); - contrastMap('obo_contrastweightmatrix/prov:value') = CONT; +if size(CONT,1) > 1 % F-contrast + nidm.Contrasts(1).contrastweightmatrix_value = CONT; warning('SnPM:FContrast', ... 'F contrast! F statistic images are being created.'); STAT = 'F'; - contrastMap('nidm_StatisticMap/nidm_statisticType') = 'obo_Fstatistic'; + nidm.Contrasts(1).StatisticMap_statisticType = 'obo_Fstatistic'; + if (CONT(1,:) == -CONT(2,:)) CONT = CONT(1,:); end con_name = 'Positive'; - - nidm_json('Contrasts') = containers.Map({con_name}, {contrastMap}); + nidm.Contrasts(1).StatisticMap_contrastName = con_name; con_neg_name = ''; else - contrast_pos = containers.Map(); - contrast_neg = containers.Map(); % There is no deep copy of - % containers.Map so we need a separate object from the start con_name = 'Positive'; + nidm.Contrasts(1).StatisticMap_contrastName = con_name; + con_neg_name = 'Negative'; + nidm.Contrasts(2).StatisticMap_contrastName = con_neg_name; + STAT = 'T'; if bVarSm - contrast_pos('nidm_StatisticMap/nidm_statisticType') = 'nidm_smoothedtstatistic'; - contrast_neg('nidm_StatisticMap/nidm_statisticType') = 'nidm_smoothedtstatistic'; + nidm.Contrasts(1).StatisticMap_statisticType = 'nidm_smoothedtstatistic'; + nidm.Contrasts(2).StatisticMap_statisticType = 'nidm_smoothedtstatistic'; else - contrast_pos('nidm_StatisticMap/nidm_statisticType') = 'obo_tstatistic'; - contrast_neg('nidm_StatisticMap/nidm_statisticType') = 'obo_tstatistic'; + nidm.Contrasts(1).StatisticMap_statisticType = 'obo_tstatistic'; + nidm.Contrasts(2).StatisticMap_statisticType = 'obo_tstatistic'; end - contrast_pos('nidm_ContrastMap/nidm_contrastName') = ['Positive T-Contrast: [' mat2str(CONT) ']']; - contrast_pos('obo_contrastweightmatrix/prov:value') = CONT; - contrast_neg('nidm_ContrastMap/nidm_contrastName') = ['Negative T-Contrast: [' mat2str(-CONT) ']']; - contrast_neg('obo_contrastweightmatrix/prov:value') = -CONT; - -% nidm_json('Contrasts').(con_name) = contrast_pos; -% nidm_json('Contrasts').(con_neg_name) = contrast_neg; - - nidm_json('Contrasts') = containers.Map({con_name, con_neg_name}, ... - {contrast_pos, contrast_neg}); + nidm.Contrasts(1).ContrastMap_contrastName = ['Positive T-Contrast: [' mat2str(CONT) ']']; + nidm.Contrasts(1).contrastweightmatrix_value = CONT; + nidm.Contrasts(2).ContrastMap_contrastName = ['Negative T-Contrast: [' mat2str(-CONT) ']']; + nidm.Contrasts(2).contrastweightmatrix_value = -CONT; end if rank(CONT) u -tol) / nPermReal; - nidm_inference('nidm_HeightThreshold/prov:type') = 'obo_statistic'; - nidm_inference('nidm_HeightThreshold/prov:value') = u; + nidm.Inferences(1).HeightThreshold_type = 'obo_statistic'; + nidm.Inferences(1).HeightThreshold_value = u; case 'FDRth' alph_FDR = BoundCheck(job.Thr.Vox.VoxSig.FDRth,[0 1],'Invalid FDR level'); alpha_ucp = snpm_uc_FDR(alph_FDR,[],'P',[],sSnPMucp'); - nidm_inference('nidm_HeightThreshold/prov:type') = 'obo_qvalue'; - nidm_inference('nidm_HeightThreshold/prov:value') = alph_FDR; + nidm.Inferences(1).HeightThreshold_type = 'obo_qvalue'; + nidm.Inferences(1).HeightThreshold_value = alph_FDR; case 'FWEth' alph_FWE = BoundCheck(job.Thr.Vox.VoxSig.FWEth,[0 1],'Invalid FWE level'); iFWE = ceil((1-alph_FWE)*nPermReal); @@ -522,14 +521,14 @@ function snpm_pp(CWD,varargin) C_MaxT = 0; end u = C_MaxT; - nidm_inference('nidm_HeightThreshold/prov:type') = 'obo_FWERadjustedpvalue'; - nidm_inference('nidm_HeightThreshold/prov:value') = alph_FWE; + nidm.Inferences(1).HeightThreshold_type = 'obo_FWERadjustedpvalue'; + nidm.Inferences(1).HeightThreshold_value = alph_FWE; otherwise error('Unknown threshold') end % No extent thresholding when voxelwise threshold is requested - nidm_inference('nidm_ExtentThreshold/prov:type') = 'obo_statistic'; - nidm_inference('nidm_ExtentThreshold/nidm_clusterSizeInVoxels') = 0; + nidm.Inferences(1).ExtentThreshold_type = 'obo_statistic'; + nidm.Inferences(1).ExtentThreshold_clusterSizeInVoxels = 0; else % Cluster-wise inference if exist(fullfile(CWD,'SnPM_ST.mat'))~=2 & exist(fullfile(CWD,'STCS.mat'))~=2 @@ -545,11 +544,11 @@ function snpm_pp(CWD,varargin) ST_Ut_0 = ST_Ut; CFth=job.Thr.Clus.ClusSize.CFth; if (CFth<1) - nidm_inference('nidm_HeightThreshold/prov:type') = 'nidm_PValueUncorrected'; - nidm_inference('nidm_HeightThreshold/prov:value') = CFth; + nidm.Inferences(1).HeightThreshold_type = 'nidm_PValueUncorrected'; + nidm.Inferences(1).HeightThreshold_value = CFth; else - nidm_inference('nidm_HeightThreshold/prov:type') = 'obo_statistic'; - nidm_inference('nidm_HeightThreshold/prov:value') = CFth; + nidm.Inferences(1).HeightThreshold_type = 'obo_statistic'; + nidm.Inferences(1).HeightThreshold_value = CFth; end if (CFth<=0) @@ -610,11 +609,11 @@ function snpm_pp(CWD,varargin) error('SnPM:InvalidClusterFormingThresh', sprintf('ERROR: Cluster-forming threshold of T=%0.2f was already set during analysis configuration; hence, in results, cluster-forming threshold must be left as "NaN".\nRe-run results with cluster-forming threshold set to NaN.\n',ST_Ut)) end if (job.Thr.Clus.ClusSize.CFth<1) - nidm_inference('nidm_HeightThreshold/prov:type') = 'nidm_PValueUncorrected'; - nidm_inference('nidm_HeightThreshold/prov:value') = job.Thr.Clus.ClusSize.CFth; + nidm.Inferences(1).HeightThreshold_type = 'nidm_PValueUncorrected'; + nidm.Inferences(1).HeightThreshold_value = job.Thr.Clus.ClusSize.CFth; else - nidm_inference('nidm_HeightThreshold/prov:type') = 'obo_statistic'; - nidm_inference('nidm_HeightThreshold/prov:value') = job.Thr.Clus.ClusSize.CFth; + nidm.Inferences(1).HeightThreshold_type = 'obo_statistic'; + nidm.Inferences(1).HeightThreshold_value = job.Thr.Clus.ClusSize.CFth; end end @@ -624,17 +623,17 @@ function snpm_pp(CWD,varargin) switch tmp{1} case 'Cth' C_STCS = job.Thr.Clus.ClusSize.ClusSig.Cth; - nidm_inference('nidm_ExtentThreshold/prov:type') = 'obo_statistic'; - nidm_inference('nidm_ExtentThreshold/prov:value') = C_STCS; + nidm.Inferences(1).ExtentThreshold_type = 'obo_statistic'; + nidm.Inferences(1).ExtentThreshold_value = C_STCS; case 'PthC' alpha_ucp = BoundCheck(job.Thr.Clus.ClusSize.ClusSig.PthC,[0 1],'Invalid uncorrected P(k)'); - nidm_inference('nidm_ExtentThreshold/prov:type') = 'nidm_PValueUncorrected'; - nidm_inference('nidm_ExtentThreshold/prov:value') = alpha_ucp; + nidm.Inferences(1).ExtentThreshold_type = 'nidm_PValueUncorrected'; + nidm.Inferences(1).ExtentThreshold_value = alpha_ucp; case 'FWEthC' alph_FWE = BoundCheck(job.Thr.Clus.ClusSize.ClusSig.FWEthC,[0 1],'Invalid FWE level (cluster-level inference)'); iFWE = ceil((1-alph_FWE)*nPermReal); - nidm_inference('nidm_ExtentThreshold/prov:type') = 'obo_FWERadjustedpvalue'; - nidm_inference('nidm_ExtentThreshold/prov:value') = alph_FWE; + nidm.Inferences(1).ExtentThreshold_type = 'obo_FWERadjustedpvalue'; + nidm.Inferences(1).ExtentThreshold_value = alph_FWE; end end % END: Cluster-wise inference @@ -819,7 +818,7 @@ function snpm_pp(CWD,varargin) %======================================================================= % TODO: check this is always true -nidm_json('nidm_ClusterDefinitionCriteria/nidm_hasConnectivityCriterion') = 'nidm_voxel18connected'; +nidm.ClusterDefinitionCriteria_hasConnectivityCriterion = 'nidm_voxel18connected'; if bSpatEx fprintf('Working on spatial extent...\n'); @@ -1192,8 +1191,8 @@ function snpm_pp(CWD,varargin) end % Display only if *not* in command line mode -nidm=true; -if ~spm_get_defaults('cmdline') || nidm +nidm_export=true; +if ~spm_get_defaults('cmdline') || nidm_export %======================================================================= %-D I S P L A Y : Max report @@ -1362,11 +1361,8 @@ function snpm_pp(CWD,varargin) %----------------------------------------------------------------------- r = 1; bUsed = zeros(size(STC_SnPMt)); - nidm_clusters = containers.Map(); while max(STC_SnPMt.*(~bUsed)) & (y > 3) - nidm_cluster = containers.Map(); - nidm_peaks = containers.Map(); [null, i] = max(STC_SnPMt.*(~bUsed)); % Largest t value j = find(STC_r == STC_r(i)); % Maxima in same region @@ -1397,24 +1393,21 @@ function snpm_pp(CWD,varargin) text(tCol(9),y,sprintf(Fmtst{9},STC_XYZ(2,i)),'UserData',STC_XYZ(:,i),StrAttrB{:}) text(tCol(10),y,sprintf(Fmtst{10},STC_XYZ(3,i)),'UserData',STC_XYZ(:,i),StrAttrB{:}) - nidm_cluster('nidm_SupraThresholdCluster/nidm_clusterSizeInVoxels') = STC_N(i); - nidm_peaks('Peak_1') = containers.Map(... - { ... - 'nidm_Peak/nidm_pValueFWER', ... - 'nidm_Peak/nidm_qValueFDR', ... - 'nidm_Peak/prov:value', ... - 'nidm_Peak/nidm_pValueUncorrected', ... - 'nidm_Peak/nidm_equivalentZStatistic',... - 'nidm_Coordinate/nidm_coordinateVector', ... - }, ... - {Pt(i), Pfdr(i), STC_SnPMt(i), Pu(i), norminv(1-Pu(i)), STC_XYZ(1:3,i)}); + % TODO: this is overwritten by 1st peak i below + nidm.Inferences(1).Clusters(r).SupraThresholdCluster_clusterSizeInVoxels = STC_N(i); + nidm.Inferences(1).Clusters(r).Peaks(1).Peak_pValueFWER = Pt(i); + nidm.Inferences(1).Clusters(r).Peaks(1).Peak_pValueFDR = Pfdr(i); + nidm.Inferences(1).Clusters(r).Peaks(1).Peak_value = STC_SnPMt(i); + nidm.Inferences(1).Clusters(r).Peaks(1).Peak_pValueUncorrected = Pu(i); + nidm.Inferences(1).Clusters(r).Peaks(1).Peak_equivalentZStatistic = norminv(1-Pu(i)); + nidm.Inferences(1).Clusters(r).Peaks(1).Coordinate_coordinateVector = STC_XYZ(1:3,i); y = y -1; %-Print up to 3 secondary maxima (>8mm apart) %------------------------------------------------------------------- - nidm_json('nidm_PeakDefinitionCriteria/nidm_minDistanceBetweenPeaks') = 8; - nidm_json('nidm_PeakDefinitionCriteria/nidm_maxNumberOfPeaksPerCluster') = 3; + nidm.PeakDefinitionCriteria_minDistanceBetweenPeaks = 8; + nidm.PeakDefinitionCriteria_maxNumberOfPeaksPerCluster = 3; [null, k] = sort(-STC_SnPMt(j)); % Sort on t value D = i; @@ -1436,28 +1429,19 @@ function snpm_pp(CWD,varargin) y = y -1; end end + - nidm_peaks(['Peak_' num2str(i)]) = containers.Map(... - { ... - 'nidm_Peak/nidm_pValueFWER', ... - 'nidm_Peak/nidm_qValueFDR', ... - 'nidm_Peak/prov:value', ... - 'nidm_Peak/nidm_pValueUncorrected', ... - 'nidm_Peak/nidm_equivalentZStatistic',... - 'nidm_Coordinate/nidm_coordinateVector', ... - }, ... - {Pt(d), Pfdr(d), STC_SnPMt(d), Pu(d), norminv(1-Pu(d)), STC_XYZ(1:3,d)}); - + nidm.Inferences(1).Clusters(r).Peaks(i).Peak_pValueFWER = Pt(d); + nidm.Inferences(1).Clusters(r).Peaks(i).Peak_pValueFDR = Pfdr(d); + nidm.Inferences(1).Clusters(r).Peaks(i).Peak_value = STC_SnPMt(d); + nidm.Inferences(1).Clusters(r).Peaks(i).Peak_pValueUncorrected = Pu(d); + nidm.Inferences(1).Clusters(r).Peaks(i).Peak_equivalentZStatistic = norminv(1-Pu(d)); + nidm.Inferences(1).Clusters(r).Peaks(i).Coordinate_coordinateVector = STC_XYZ(1:3,d); end - - nidm_cluster('Peaks') = nidm_peaks; - nidm_clusters(['Cluster_' num2str(r)]) = nidm_cluster; - + bUsed(j) = (bUsed(j) | 1 ); %-Mark maxima as "used" r = r + 1; % Next region end - - nidm_inference('Clusters') = nidm_clusters; clear i j k D d r @@ -1507,10 +1491,10 @@ function snpm_pp(CWD,varargin) search_vol_cmm = S*abs(prod(VOX)); search_vol_vox = S; text(0,y,sprintf('Search vol: %d cmm, %d voxels',search_vol_cmm,search_vol_vox), 'FontSize',8) - nidm_inference('nidm_SearchSpaceMaskMap/nidm_searchVolumeInVoxels') = search_vol_vox; + nidm.SearchSpaceMaskMap_searchVolumeInVoxels = search_vol_vox; % TODO convert back to units - nidm_inference('nidm_SearchSpaceMaskMap/nidm_searchVolumeInUnits') = search_vol_cmm; + nidm.SearchSpaceMaskMap_searchVolumeInUnits = search_vol_cmm; y=y-0.8; text(0.7,y,sprintf('Voxel size: [%5.2f, %5.2f, %5.2f] mm',abs(VOX)), ... @@ -1540,7 +1524,7 @@ function snpm_pp(CWD,varargin) %- Image output? %======================================================================= %-Write out filtered SnPMt? -if WrtFlt || nidm +if WrtFlt || nidm_export Fname = WrtFltFn; @@ -1587,30 +1571,26 @@ function snpm_pp(CWD,varargin) clear t % TODO SearchSpaceMaskMap can be different from analysis mask - nidm_inference('nidm_SearchSpaceMaskMap/prov:atLocation') = 'mask.img'; + nidm.SearchSpaceMaskMap_atLocation = 'mask.img'; % TODO: always stationary?? - nidm_inference('nidm_SearchSpaceMaskMap/nidm_randomFieldStationarity') = true; - - nidm_inference('nidm_ExcursionSetMap/prov:atLocation') = Fname; + nidm.SearchSpaceMaskMap_randomFieldStationarity = true; - nidm_inferences = containers.Map(); - nidm_inferences(contrast_id) = nidm_inference; - nidm_json('Inferences') = nidm_inferences; + nidm.Inferences(1).ExcursionSetMap_atLocation = Fname; - nidm_json('nidm_NIDMResultsExporter/nidm_softwareVersion') = snpm('ver'); - nidm_json('nidm_NeuroimagingAnalysisSoftware/nidm_softwareVersion') = snpm('ver'); + nidm.NIDMResultsExporter_softwareVersion = snpm('ver'); + nidm.NeuroimagingAnalysisSoftware_softwareVersion = snpm('ver'); % TODO: are other units possible in SnPM?? - nidm_json('nidm_CoordinateSpace/units') = {'mm', 'mm', 'mm'}; + nidm.CoordinateSpace_units = {'mm', 'mm', 'mm'}; % TODO: these should be filled in by the user --- - nidm_json('nidm_CoordinateSpace/nidm_inWorldCoordinateSystem') = 'nidm_StandardizedCoordinateSystem'; - nidm_json('nlx_Imaginginstrument/prov:type') = 'nlx_Magneticresonanceimagingscanner'; + nidm.CoordinateSpace_inWorldCoordinateSystem = 'nidm_StandardizedCoordinateSystem'; + nidm.Imaginginstrument_type = 'nlx_Magneticresonanceimagingscanner'; % --- - nidm_json('nidm_NeuroimagingAnalysisSoftware/prov:type') = 'src_SnPM'; - nidm_json('nidm_NeuroimagingAnalysisSoftware/prov:label') = 'SnPM'; + nidm.NeuroimagingAnalysisSoftware_type = 'src_SnPM'; + nidm.NeuroimagingAnalysisSoftware_label = 'SnPM'; % TODO: This temp file should only be produced if NIDM export is requested jsonwrite('snpm_nidm_thresh.json', nidm_json, ... diff --git a/snpm_ui.m b/snpm_ui.m index 21732f2..ce38701 100644 --- a/snpm_ui.m +++ b/snpm_ui.m @@ -123,7 +123,7 @@ function snpm_ui(varargin) % V Memory mapping handles % MASK Filename of explicit mask image % ImMASK Implicit masking; 0=none; 1=zeros are equivalent to NaN -% nidm_json json structure storing minimal information required for a +% nidm json structure storing minimal information required for a % NIDM-Results export % % df degrees of freedom due to error @@ -193,7 +193,7 @@ function snpm_ui(varargin) cd(job.dir{1}) end -nidm_json = containers.Map(); +nidm = struct(); %-Definitions & Design parameters %======================================================================= @@ -383,7 +383,7 @@ function snpm_ui(varargin) end if (iGMsca==2) % CHANGED from 1 to 2 as should not ask for a value if grand mean scaling is not required. - nidm_json('nidm_Data/nidm_grandMeanScaling') = true; + nidm.Data_grandMeanScaling = true; if (iGloNorm==2) % Proportional scaling str = 'PropSca global mean to'; else @@ -397,10 +397,10 @@ function snpm_ui(varargin) case 'gmsca_no', GM = 50; end - nidm_json('nidm_Data/nidm_targetIntensity') = GM; + nidm.Data_targetIntensity = GM; elseif (iGMsca==1) % No grand mean scaling GM = 0; - nidm_json('nidm_Data/nidm_grandMeanScaling') = false; + nidm.Data_grandMeanScaling = false; end @@ -590,15 +590,15 @@ function snpm_ui(varargin) %-Construct full design matrix and name matrices for display %----------------------------------------------------------------------- [nHCBG,HCBGnames] = spm_DesMtx('Sca',H,Hnames,C,Cnames,B,Bnames,G,Gnames); -nidm_json('nidm_DesignMatrix/prov:value') = nHCBG; -nidm_json('nidm_DesignMatrix/nidm_regressorNames') = HCBGnames; +nidm.DesignMatrix_value = nHCBG; +nidm.DesignMatrix_regressorNames = HCBGnames; %-Setup is complete - save SnPMcfg Mat file %----------------------------------------------------------------------- s_SnPMcfg_save = ['s_SnPMcfg_save H C B G HCBGnames P PiCond ',... 'sPiCond bhPerms sHCform iGloNorm sGloNorm GM rg GX GMscale CONT ',... 'THRESH MASK ImMASK TH bVarSm vFWHM sVarSm bVolm bST sDesFile sDesign ',... - 'V pU_ST_Ut df1 nidm_json nPerm_max nidm_json ', ... + 'V pU_ST_Ut df1 nidm nPerm_max nidm_json ', ... 'sDesSave ',sDesSave]; eval(['save SnPMcfg ',s_SnPMcfg_save])