spm_dcm_create.m 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. function spm_dcm_create(syn_model,source_model,SNR)
  2. % Create a DCM with simulated data (specified via GUI or an existing model)
  3. % FORMAT spm_dcm_create(syn_model,source_model,SNR)
  4. %
  5. % syn_model - name of the synthetic DCM to be created
  6. % source_model - define new model ('GUI')
  7. % or import existing model via file selector ('import')
  8. % or import existing model (directly specified by directory
  9. % and name)
  10. % [default: 'GUI']
  11. % SNR - signal-to-noise ratio [default: 1]
  12. %
  13. % This function allows to create DCM networks with known connectivity
  14. % parameters from which synthetic data are then generated by calling
  15. % spm_dcm_generate.
  16. %
  17. % This function is very much like spm_dcm_specify_ui but inputs etc. are
  18. % specified either via the user interface or from an existing model.
  19. % Currently, the interface provided by this function does not allow for
  20. % manual specification of nonlinear DCMs; however, these can be imported
  21. % from existing files.
  22. %__________________________________________________________________________
  23. % Copyright (C) 2002-2014 Wellcome Trust Centre for Neuroimaging
  24. % Will Penny & Klaas Enno Stephan & Peter Zeidman
  25. % $Id: spm_dcm_create.m 6037 2014-06-04 09:01:16Z peter $
  26. Finter = spm_figure('GetWin','Interactive');
  27. header = get(Finter,'Name');
  28. set(Finter,'Name','Dynamic Causal Modelling')
  29. %-Check parameters and insert default values, if necessary
  30. %==========================================================================
  31. if nargin == 0
  32. syn_model = spm_input('Name for target DCM_???.mat','+1','s');
  33. SNR = spm_input('Signal-to-noise ratio (SNR)? ','+1','r',[],1);
  34. source_model = 'GUI';
  35. else
  36. try, source_model; catch, source_model = 'GUI'; end
  37. try, SNR; catch, SNR = 1; end
  38. end
  39. %-Outputs
  40. %==========================================================================
  41. switch upper(source_model)
  42. case 'GUI'
  43. %-Define model by GUI
  44. %==================================================================
  45. % Load SPM for experimental timing
  46. %------------------------------------------------------------------
  47. [spm_file, sts] = spm_select(1,'^SPM\.mat$','Select SPM.mat');
  48. if ~sts, return; end
  49. try
  50. SPM = load(spm_file);
  51. SPM = SPM.SPM;
  52. catch
  53. error('Cannot read %s.',spm_file);
  54. end
  55. % Check for which session to create the DCM
  56. %------------------------------------------------------------------
  57. session = length(SPM.Sess);
  58. if session > 1
  59. session = spm_input('which session','!+1','n1',1,session);
  60. if isempty(session) || ~isnumeric(session)
  61. error('A session number is required');
  62. end
  63. end
  64. % Get cell array of region structures
  65. %------------------------------------------------------------------
  66. n = spm_input('Enter number of regions',1,'r',[],1);
  67. for i=1:n
  68. str = sprintf('Region %d',i);
  69. xY(i).name = spm_input(['Name for ',str],'+1','s');
  70. % Make up spurious VOI info
  71. % for compatibility with spm_dcm_display
  72. xY(i).xyz = [i i i]'*10;
  73. xY(i).XYZmm = [i i i]'*10;
  74. xY(i).s = 1;
  75. xY(i).spec = 1;
  76. % for compatibility with spm_dcm_specify
  77. xY(i).Sess = session;
  78. xY(i).u = 1;
  79. xY(i).X0 = [];
  80. end
  81. % Run through standard specification questions
  82. %------------------------------------------------------------------
  83. DCM = spm_dcm_specify_ui(SPM,xY);
  84. % Get desired number of scans
  85. %------------------------------------------------------------------
  86. DCM.v = SPM.nscan(session);
  87. % Set default connection strengths to reasonable values
  88. %------------------------------------------------------------------
  89. DEFAULT_SELF = 0;
  90. DEFAULT_BETWEEN = 0.3;
  91. DEFAULT_DRIVING = 0.8;
  92. def = struct();
  93. def.A = DEFAULT_BETWEEN .* DCM.a;
  94. def.A = def.A - diag(diag(def.A));
  95. def.A = def.A + diag(repmat(DEFAULT_SELF,n,1));
  96. def.B = DEFAULT_BETWEEN .* DCM.b;
  97. def.C = DEFAULT_DRIVING .* DCM.c;
  98. % Build A-matrix
  99. %------------------------------------------------------------------
  100. % Initialize DCM.Ep with prior values
  101. DCM.Ep = spm_dcm_fmri_priors(DCM.a,DCM.b,DCM.c,DCM.d);
  102. enabled = struct('A',DCM.a,'B',DCM.b,'C',DCM.c);
  103. entry_accepted = false;
  104. while ~entry_accepted
  105. % Prompt for A-matrix
  106. str = 'Connectivity for';
  107. con = spm_dcm_connectivity_ui(DCM,'A', str, def, enabled);
  108. DCM.Ep.A = con.A;
  109. % Check stability
  110. if spm_dcm_check_stability(DCM)
  111. entry_accepted = true;
  112. else
  113. % Query for another attempt
  114. qtext = ...
  115. 'Parameters may lead to an unstable estimate. Edit your selection?';
  116. options = struct('Default','Yes','Interpreter','none');
  117. choice = questdlg(qtext,'Stability','Yes','No',options);
  118. entry_accepted = ~strcmp(choice,'Yes');
  119. % Ensure any new values are re-populated
  120. def = struct('A',DCM.Ep.A,'B',DCM.Ep.B,'C',DCM.Ep.C);
  121. end
  122. end
  123. % Build B-matrix and C-matrix
  124. %------------------------------------------------------------------
  125. con = spm_dcm_connectivity_ui(DCM,'B', str, def, enabled);
  126. DCM.Ep.B = con.B;
  127. con = spm_dcm_connectivity_ui(DCM,'C', str, def, enabled);
  128. DCM.Ep.C = con.C;
  129. case 'IMPORT'
  130. % Import existing model - prompt user to choose it
  131. %==================================================================
  132. P = spm_select(1,'^DCM.*\.mat$','Select source DCM_???.mat');
  133. load(P)
  134. otherwise
  135. % Import existing model (directly specified by directory & name)
  136. %==================================================================
  137. try
  138. load(source_model)
  139. catch
  140. error('Cannot load source model');
  141. end
  142. end
  143. % Now set up output structure
  144. %--------------------------------------------------------------------------
  145. X0 = ones(DCM.v,1);
  146. switch upper(source_model)
  147. case 'GUI'
  148. Y = DCM.Y;
  149. DCM.Ep.decay = sparse(DCM.n,1);
  150. DCM.Ep.transit = sparse(DCM.n,1);
  151. DCM.Ep.epsilon = sparse(1,1);
  152. otherwise
  153. try
  154. Y.dt = DCM.Y.dt;
  155. catch
  156. Y.dt = DCM.delays(1);
  157. end
  158. end
  159. Y.X0 = X0;
  160. for i = 1:DCM.n
  161. Y.name{i} = DCM.xY(i).name;
  162. end
  163. Y.Q = spm_Ce(ones(1,DCM.n)*DCM.v);
  164. DCM.Y = Y;
  165. %-Save
  166. %--------------------------------------------------------------------------
  167. dcm_filename = ['DCM_' syn_model '.mat'];
  168. save(dcm_filename,'DCM', spm_get_defaults('mat.format'));
  169. % Generate synthetic output data
  170. %==========================================================================
  171. spm_dcm_generate(dcm_filename,SNR);
  172. spm('FigName',header);