0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 function dynasim(spec)
0011
0012
0013 if ~strcmp(reportUI,'matlab')
0014 warning('DynaSim GUI is not supported in GNU Octave at this time.');
0015 return
0016 end
0017
0018 global handles SPEC MODEL cfg LASTSPEC LASTCFG
0019 handles=[];
0020
0021 if nargin==0
0022
0023 ina={
0024 'INa(v,m,h) = -gNa.*m.^3.*h.*(v-50); gNa=120';
0025 'dm/dt = aM(v).*(1-m)-bM(v).*m; m(0)=.1';
0026 'dh/dt = aH(v).*(1-h)-bH(v).*h; h(0)=.1';
0027 'aM(v) = (2.5-.1*(v+65))./(exp(2.5-.1*(v+65))-1)';
0028 'bM(v) = 4*exp(-(v+65)/18)';
0029 'aH(v) = .07*exp(-(v+65)/20)';
0030 'bH(v) = 1./(exp(3-.1*(v+65))+1)';
0031 '@current+=INa';
0032 };
0033 ik={
0034 'IK(v,n) = -gK.*n.^4.*(v+77); gK=36';
0035 'dn/dt = aN(v).*(1-n)-bN(v).*n; n(0)=0';
0036 'aN(v) = (.1-.01*(v+65))./(exp(1-.1*(v+65))-1)';
0037 'bN(v) = .125*exp(-(v+65)/80)';
0038 '@current+=IK';
0039 };
0040 iampa={
0041 'gSYN=0.1; ESYN=0; tauD=2; tauR=0.4';
0042 'netcon=ones(N_pre,N_post)';
0043 'ISYN(X,s)=(gSYN.*(s*netcon).*(X-ESYN))';
0044 'ds/dt=-s./tauD+((1-s)/tauR).*(1+tanh(X_pre/10)); s(0)=.1';
0045 '@isyn += -ISYN(X_post,s)';
0046 };
0047 igaba={
0048 'gSYN=0.25; ESYN=-80; tauD=10; tauR=0.4';
0049 'netcon=ones(N_pre,N_post)';
0050 'ISYN(X,s)=(gSYN.*(s*netcon).*(X-ESYN))';
0051 'ds/dt=-s./tauD+((1-s)/tauR).*(1+tanh(X_pre/10)); s(0)=.1';
0052 '@isyn += -ISYN(X_post,s)';
0053 };
0054 input='Iapp=0; noise=0; @input+=Iapp+noise*randn(1,N_pop)';
0055 master_equations='dv/dt=@input+@current+@isyn; v(0)=-65';
0056 mechanism_list={'ina','ik','input1'};
0057
0058
0059 s=[];
0060 s.populations(1).name='E';
0061 s.populations(1).size=8;
0062 s.populations(1).equations=master_equations;
0063 s.populations(1).mechanism_list=mechanism_list;
0064 s.populations(1).parameters={'Iapp',5,'noise',40,'gNa',125};
0065 s.populations(2).name='I';
0066 s.populations(2).size=2;
0067 s.populations(2).equations=master_equations;
0068 s.populations(2).mechanism_list=mechanism_list;
0069 s.populations(2).parameters={'Iapp',0,'noise',40};
0070 s.connections(1).direction='I->E';
0071 s.connections(1).mechanism_list={'igaba'};
0072 s.connections(1).parameters={'tauD',10,'gSYN',.1};
0073 s.connections(2).direction='E->I';
0074 s.connections(2).mechanism_list={'iampa'};
0075 s.connections(2).parameters={'tauD',2,'gSYN',.1};
0076 s.mechanisms(1).name='ina';
0077 s.mechanisms(1).equations=ina;
0078 s.mechanisms(2).name='ik';
0079 s.mechanisms(2).equations=ik;
0080 s.mechanisms(3).name='iampa';
0081 s.mechanisms(3).equations=iampa;
0082 s.mechanisms(4).name='igaba';
0083 s.mechanisms(4).equations=igaba;
0084 s.mechanisms(5).name='input1';
0085 s.mechanisms(5).equations=input;
0086 spec=s;
0087
0088 end
0089
0090 SPEC=dsCheckSpecification(spec);
0091
0092 [SPEC.populations.parameters]=deal([]);
0093 if ~isempty(SPEC.connections)
0094 [SPEC.connections.parameters]=deal([]);
0095 end
0096
0097 MODEL=dsGenerateModel(SPEC);
0098
0099 try
0100 [ODEFUN,IC,elem_names]=dsDynasim2odefun(dsPropagateParameters(MODEL));
0101 catch
0102 ODEFUN='';
0103 IC=[];
0104 elem_names={};
0105 end
0106
0107
0108
0109
0110 cfg.username='anonymous';
0111 cfg.model_text='model equations ...';
0112 cfg.V=linspace(-100,100,20e3);
0113 cfg.linecolors = 'kbrgmy';
0114 cfg.linetype = {'-',':','-.','--'};
0115 cfg.max_num_plots=3;
0116 cfg.num_xticks=5;
0117 cfg.num_steps_per_plot=400;
0118 cfg.sim_paused=-1;
0119 cfg.sim_stopped=0;
0120 cfg.ymin=-90*ones(1,cfg.max_num_plots);
0121 cfg.ymax=50*ones(1,cfg.max_num_plots);
0122 cfg.ModelFontName='Monospaced';
0123 cfg.autoscale_charcode=5864;
0124
0125 cfg.BackgroundColor=[204 204 180]/255;
0126 cfg.ButtonColor=[0 102 153]/255/1.75;
0127 cfg.ButtonFontColor=[240 240 240]/255;
0128
0129
0130
0131
0132
0133
0134 cfg.ODEFUN=ODEFUN;
0135 cfg.IC=IC;
0136 cfg.elem_names=elem_names;
0137 cfg.ntime=20e3+1;
0138 cfg.dt=.01;
0139 cfg.t0=0;
0140 cfg.tf=200;
0141 cfg.t=(0:cfg.ntime-1)'*cfg.dt;
0142 cfg.t_plot_indices=1:cfg.ntime;
0143 cfg.Y=zeros(cfg.ntime,max(1,length(cfg.IC)));
0144 cfg.xtick=linspace(cfg.t(1),cfg.t(end),cfg.num_xticks);
0145 cfg.xticklabel=linspace(cfg.t(1),cfg.t(end),cfg.num_xticks);
0146
0147 if nargin==0
0148 LASTSPEC=SPEC;
0149 LASTCFG=cfg;
0150 end
0151
0152
0153 figure_position=[245 145 1460 770];
0154 handles.fig_main = figure('position',figure_position,'color',cfg.BackgroundColor,'tag','designer','name','DynaSim Model Builder','NumberTitle','off','WindowScrollWheelFcn',@ZoomFunction,'CloseRequestFcn','delete(gcf); clear global H');
0155
0156
0157
0158
0159
0160 set(handles.fig_main,'MenuBar','none');
0161 file_m = uimenu(handles.fig_main,'Label','File');
0162 uimenu(file_m,'Label','New model','Callback','global handles; close(handles.fig_main); dynasim(dsCheckSpecification([]));');
0163 uimenu(file_m,'Label','Open model','Callback',@OpenModel);
0164
0165 uimenu(file_m,'Label','Save model','Callback',@SaveModel);
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178 uimenu(file_m,'Label','Refresh GUI','Callback','global SPEC handles; close(handles.fig_main); dynasim(SPEC);');
0179 uimenu(file_m,'Label','Exit','Callback','global handles cfg; close(handles.fig_main); clear handles cfg; warning on');
0180
0181
0182
0183
0184
0185
0186 InitializeMainGUI;
0187
0188
0189 function InitializeMainGUI
0190 global handles SPEC cfg
0191
0192
0193 pop_names={SPEC.populations.name};
0194 active_model_component=SPEC.populations(1).name;
0195 active_mechanism_list=SPEC.populations(1).mechanism_list;
0196 if isfield(SPEC.populations(1).mechanisms,'equations')
0197 active_mechanism_text=SPEC.populations(1).mechanisms(1).equations;
0198 else
0199 active_mechanism_text='';
0200 end
0201 active_mechanism_userdata=[];
0202
0203 bgcolor=cfg.BackgroundColor;
0204
0205
0206
0207
0208
0209
0210
0211 handles.pview=uipanel('parent',handles.fig_main,'title','','visible','on','units','normalized','position',[.5 0 .5 1]);
0212
0213 handles.bsimview=uicontrol('parent',handles.pview,'style','pushbutton','tag','viewtab','units','normalized','position',[0 .95 .5 .05],'string','Simulation View','fontsize',11,'FontWeight','bold','backgroundcolor',[.7 .7 .7],'callback','set(findobj(''tag'',''viewtoggle''),''visible'',''off''); set(findobj(''tag'',''viewtab''),''backgroundcolor'',[1 1 1]); set(findobj(''userdata'',''handles.psimview''),''visible'',''on''); set(gcbo,''backgroundcolor'',[.7 .7 .7]);');
0214 handles.psimview=uipanel('parent',handles.pview,'backgroundcolor','w','title','','visible','on','tag','viewtoggle','userdata','handles.psimview','units','normalized','position',[0 0 1 .95]);
0215
0216 handles.beqnview=uicontrol('parent',handles.pview,'style','pushbutton','tag','viewtab','units','normalized','position',[.5 .95 .5 .05],'string','Equation View','fontsize',11,'FontWeight','bold','backgroundcolor',[1 1 1],'callback','set(findobj(''tag'',''viewtoggle''),''visible'',''off''); set(findobj(''tag'',''viewtab''),''backgroundcolor'',[1 1 1]); set(findobj(''userdata'',''handles.peqnview''),''visible'',''on''); set(gcbo,''backgroundcolor'',[.7 .7 .7]);');
0217 handles.peqnview=uipanel('parent',handles.pview,'backgroundcolor',[.9 .9 .9],'title','','visible','off','tag','viewtoggle','userdata','handles.peqnview','units','normalized','position',[0 0 1 .95]);
0218 handles.txt_model = uicontrol('parent',handles.peqnview,'style','edit','units','normalized','tag','modeltext','position',[0 0 1 1],'string',cfg.model_text,'ForegroundColor','k','FontName',cfg.ModelFontName,'FontSize',9,'HorizontalAlignment','Left','Max',100,'BackgroundColor',[.95 .95 .95]);
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233 uicontrol('parent',handles.fig_main,'style','text','string','DynaSim Model Designer','fontsize',16,'units','normalized','position',[0 .95 .25 .04],'backgroundcolor',bgcolor,'FontWeight','bold','ForegroundColor',[0 0 0]);
0234 uicontrol('parent',handles.fig_main,'style','pushbutton','units','normalized','position',[.35 .95 .15 .05],'string','SAVE MODEL','backgroundcolor',cfg.ButtonColor,'ForegroundColor',cfg.ButtonFontColor,'ForegroundColor',cfg.ButtonFontColor,'FontWeight','bold','callback',@SaveModel,'FontSize',14);
0235 uicontrol('parent',handles.fig_main,'style','pushbutton','units','normalized','position',[.3 .97 .04 .03],'string','undo','backgroundcolor',cfg.ButtonColor,'ForegroundColor',cfg.ButtonFontColor,'FontWeight','bold','callback',@undo,'visible','on');
0236 bhistory=uicontrol('parent',handles.fig_main,'style','pushbutton','units','normalized','position',[0 .01 .1 .03],'string','View history','backgroundcolor',cfg.ButtonColor,'ForegroundColor',cfg.ButtonFontColor,'FontWeight','bold','callback',[],'Enable','off');
0237 bversion=uicontrol('parent',handles.fig_main,'style','pushbutton','units','normalized','position',[.12 .01 .08 .03],'string','+ Version','backgroundcolor',cfg.ButtonColor,'ForegroundColor',cfg.ButtonFontColor,'FontWeight','bold','callback',[],'Enable','off');
0238 bsimstudy=uicontrol('parent',handles.fig_main,'style','pushbutton','units','normalized','position',[.4 .01 .09 .03],'string','NEW SWEEP','backgroundcolor',cfg.ButtonColor,'ForegroundColor',cfg.ButtonFontColor,'FontWeight','bold','callback',[],'Enable','off');
0239
0240
0241
0242 pcreate=uipanel('parent',handles.fig_main,'backgroundcolor',bgcolor,'title','','visible','on','units','normalized','position',[0 .05 .5 .9],'fontweight','normal');
0243 bnet=uicontrol('parent',pcreate,'style','pushbutton','tag','tab2','units','normalized','position',[.21 .65 .22 .04],'string','connections','backgroundcolor',[1 1 1],'FontWeight','bold','callback','set(findobj(''tag'',''ptoggle2''),''visible'',''off''); set(findobj(''tag'',''tab2''),''backgroundcolor'',[1 1 1]); set(findobj(''userdata'',''pnet''),''visible'',''on''); set(gcbo,''backgroundcolor'',[.7 .7 .7]);');
0244 bmech=uicontrol('parent',pcreate,'style','pushbutton','tag','tab2','units','normalized','position',[.43 .65 .22 .04],'string','mechanisms','backgroundcolor',[.7 .7 .7],'FontWeight','bold','callback','set(findobj(''tag'',''ptoggle2''),''visible'',''off''); set(findobj(''tag'',''tab2''),''backgroundcolor'',[1 1 1]); set(findobj(''userdata'',''pmech''),''visible'',''on''); set(gcbo,''backgroundcolor'',[.7 .7 .7]);');
0245 bcell=uicontrol('visible','off','parent',pcreate,'style','pushbutton','tag','tab2','units','normalized','position',[.65 .65 .22 .04],'string','parameters','backgroundcolor',[1 1 1],'FontWeight','bold','callback','set(findobj(''tag'',''ptoggle2''),''visible'',''off''); set(findobj(''tag'',''tab2''),''backgroundcolor'',[1 1 1]); set(findobj(''userdata'',''pcell''),''visible'',''on''); set(gcbo,''backgroundcolor'',[.7 .7 .7]);');
0246 pmech=uipanel('parent',pcreate,'backgroundcolor',bgcolor,'title','Mechanism Editor','visible','on','tag','ptoggle2','userdata','pmech','units','normalized','position',[0 0 1 .65],'fontweight','bold');
0247 pnet=uipanel('parent',pcreate,'backgroundcolor',bgcolor,'title','connection mechanism lists','visible','off','tag','ptoggle2','userdata','pnet','units','normalized','position',[0 0 1 .65]);
0248 pcell=uipanel('parent',pcreate,'backgroundcolor',bgcolor,'title','parameters','visible','off','tag','ptoggle2','userdata','pcell','units','normalized','position',[0 0 1 .65]);
0249
0250 handles.p_pop_spec = uipanel('parent',pcreate,'BackgroundColor',bgcolor,'Position',[0 .7 1 .29],'BorderWidth',.2,'BorderType','line');
0251 handles.p_net_connect = uipanel('parent',pnet,'BackgroundColor',bgcolor,'Position',[0 .6 1 .4],'BorderWidth',.2,'BorderType','line','title','','fontweight','normal');
0252 p_net_kernel = uipanel('parent',pnet,'BackgroundColor',bgcolor,'Position',[0 0 1 .6],'BorderWidth',.2,'BorderType','line','title','view and edit connectivity matrices');
0253
0254 handles.list_pops = uicontrol('parent',handles.p_pop_spec,'units','normalized','style','listbox','position',[0 0 .2 .9],'value',1:length(pop_names),'string',pop_names,'BackgroundColor',[.9 .9 .9],'Max',5,'Min',0,'Callback',@UpdatePopSelection,'ButtonDownFcn',@RenamePopulation,'TooltipString','Right-click to edit node name','FontName',cfg.ModelFontName);
0255
0256 uicontrol('parent',handles.p_pop_spec,'tag','nodecontrols','BackgroundColor',bgcolor,'units','normalized','style','text','position',[0 .91 .25 .09],'string','populations','ListboxTop',0,'HorizontalAlignment','left','fontsize',10,'fontweight','bold');
0257 uicontrol('parent',handles.p_pop_spec,'tag','nodecontrols','BackgroundColor',bgcolor,'units','normalized','style','text','position',[.25 .91 .06 .09],'string','size','ListboxTop',0,'HorizontalAlignment','left','fontsize',10,'fontweight','normal');
0258 uicontrol('parent',handles.p_pop_spec,'tag','nodecontrols','BackgroundColor',bgcolor,'units','normalized','style','text','position',[.7 .91 .29 .09],'string','intrinsic mechanism lists','ListboxTop',0,'HorizontalAlignment','left','fontsize',10,'fontweight','normal');
0259 uicontrol('parent',handles.p_pop_spec,'tag','nodecontrols','BackgroundColor',bgcolor,'units','normalized','style','text','position',[.31 .91 .25 .09],'string','master equations','ListboxTop',0,'HorizontalAlignment','left','fontsize',10,'fontweight','normal');
0260
0261
0262
0263 handles.list_mechs = uicontrol('units','normalized','position',[0 .42 .2 .58],'parent',pmech,'BackgroundColor',[.9 .9 .9],'style','listbox','value',1,'string',active_mechanism_list,'Max',1,'Callback',@UpdateMechanismEditor,'ButtonDownFcn',@RenameMechanism,'TooltipString','Right-click to edit mechanism name','FontName',cfg.ModelFontName);
0264 handles.edit_mech_eqns = uicontrol('parent',pmech,'style','edit','units','normalized','BackgroundColor','w','callback',@UpdateMechanismEditor,'position',[.2 .42 .8 .58],'string',active_mechanism_text,'userdata',active_mechanism_userdata,'FontName',cfg.ModelFontName,'FontSize',12,'HorizontalAlignment','Left','Max',100);
0265
0266 p_static_plots = uipanel('parent',pmech,'Position',[0 0 1 .4],'BackgroundColor','white','BorderWidth',.2,'BorderType','line','title','');
0267 handles.list_functions = uicontrol('units','normalized','position',[0 0 .2 .95],'parent',p_static_plots,'BackgroundColor',[.9 .9 .9],'style','listbox','value',1:5,'string',{},'Max',50,'Callback',@UpdateMechanismFunctions,'FontName',cfg.ModelFontName);
0268 handles.ax_static_plot = subplot('position',[.23 .1 .75 .78],'parent',p_static_plots,'linewidth',3,'color','w','fontsize',6); box on;
0269 title('functions of one variable');
0270 edit_static_lims=uicontrol('Style','edit', 'Units','normalized','Position',[0.9 0.1 0.1 0.1],'backgroundcolor','w',...
0271 'String',sprintf('[%g,%g]',min(cfg.V),max(cfg.V)),'Callback',{@DrawAuxFunctions,1},'parent',p_static_plots);
0272 btn_static_autoscale=uicontrol('style','pushbutton','fontsize',10,'string','autoscale','parent',p_static_plots,'backgroundcolor',cfg.ButtonColor,'ForegroundColor',cfg.ButtonFontColor,...
0273 'Units','normalized','Position',[0.9 0 0.1 0.1],'callback',@AutoscaleMechPlot);
0274 uicontrol('style','text','parent',p_static_plots,'Units','normalized','Position',[0.88 .12 0.02 0.075],'string','x','backgroundcolor','w');
0275 uicontrol('style','text','parent',p_static_plots,'Units','normalized','Position',[0.88 .02 0.02 0.075],'string','y','backgroundcolor','w');
0276
0277 set(handles.list_functions,'string',{});
0278 set(handles.list_functions,'value',[]);
0279
0280 UpdatePopControls;
0281 UpdateConControls;
0282 UpdateMechanismEditor;
0283 InitializeSimView;
0284 UpdateSimView;
0285 UpdateEqnView;
0286
0287
0288 function UpdatePopControls(src,evnt)
0289
0290 global handles SPEC cfg
0291 c=1.5; dy=-.07*c; ht=.1;
0292 sel = get(handles.list_pops,'value');
0293 l={SPEC.populations(sel).name};
0294 N=[SPEC.populations(sel).size];
0295 mechs={SPEC.populations(sel).mechanism_list};
0296 for i=1:length(sel)
0297 m=mechs{i};
0298 if isempty(m)
0299 str='';
0300 else
0301 [~,str]=fileparts(m{1});
0302 for j=2:length(m)
0303 [~,name]=fileparts(m{j});
0304 str=[str ', ' name];
0305 end
0306 end
0307 if ~isempty(SPEC.populations(sel(i)).equations)
0308 if iscell(SPEC.populations(sel(i)).equations)
0309 pop_equations=[SPEC.populations(sel(i)).equations{:}];
0310 else
0311 pop_equations=SPEC.populations(sel(i)).equations;
0312 end
0313 else
0314 pop_equations='';
0315 end
0316 userdata.index=sel(i);
0317 size_callback='global SPEC LASTSPEC; LASTSPEC=SPEC; u=get(gcbo,''userdata''); SPEC.populations(u.index).size=str2num(get(gcbo,''string''));';
0318 eqn_callback='global SPEC LASTSPEC; LASTSPEC=SPEC; u=get(gcbo,''userdata''); SPEC.populations(u.index).equations=get(gcbo,''string'');';
0319
0320 mechlist_callback='global SPEC LASTSPEC; LASTSPEC=SPEC; u=get(gcbo,''userdata''); tmp=strtrim(regexp(get(gcbo,''string''),'','',''split'',''once'')); if isempty(tmp{1}), tmp=[]; end; SPEC.populations(u.index).mechanism_list=tmp;';
0321 if ~isfield(handles,'btn_pop_delete') || length(handles.btn_pop_delete)<length(sel) || ~ishandle(handles.btn_pop_delete(i))
0322 handles.btn_pop_delete(i) = uicontrol('parent',handles.p_pop_spec,'units','normalized',...
0323 'style','pushbutton','fontsize',10,'string','-','callback',{@RemovePopulation,sel(i)},...
0324 'position',[.205 .8+dy*(i-1) .03 ht],'TooltipString',l{i});
0325 handles.edit_pop_size(i) = uicontrol('parent',handles.p_pop_spec,'units','normalized','userdata',userdata,...
0326 'style','edit','position',[.24 .8+dy*(i-1) .06 ht],'backgroundcolor','w','string',N(i),'FontName',cfg.ModelFontName,...
0327 'HorizontalAlignment','left','Callback',{@UpdateModel,size_callback},'TooltipString',l{i});
0328 handles.edit_pop_equations(i) = uicontrol('parent',handles.p_pop_spec,'units','normalized','userdata',userdata,...
0329 'style','edit','position',[.3 .8+dy*(i-1) .4 ht],'backgroundcolor','w','string',pop_equations,'FontName',cfg.ModelFontName,...
0330 'HorizontalAlignment','left','Callback',{@UpdateModel,eqn_callback},...
0331 'ButtonDownFcn',{@UpdateModel,eqn_callback},'fontsize',9,'TooltipString',l{i});
0332 handles.edit_pop_mechlist(i) = uicontrol('parent',handles.p_pop_spec,'units','normalized','userdata',userdata,...
0333 'style','edit','position',[.7 .8+dy*(i-1) .26 ht],'backgroundcolor','w','string',str,'FontName',cfg.ModelFontName,...
0334 'HorizontalAlignment','left','Callback',{@UpdateModel,mechlist_callback},...
0335 'ButtonDownFcn',{@UpdateModel,mechlist_callback},'fontsize',9,'TooltipString',l{i});
0336 handles.btn_pop_copy(i) = uicontrol('parent',handles.p_pop_spec,'units','normalized',...
0337 'style','pushbutton','fontsize',10,'string','+','callback',{@AddPopulation,sel(i)},...
0338 'position',[.965 .8+dy*(i-1) .03 ht],'TooltipString',l{i});
0339 else
0340
0341 set(handles.edit_pop_equations(i),'string',pop_equations,'visible','on','Callback',{@UpdateModel,eqn_callback},'TooltipString',l{i});
0342 set(handles.edit_pop_size(i),'string',N(i),'visible','on','Callback',{@UpdateModel,size_callback},'TooltipString',l{i});
0343 set(handles.edit_pop_mechlist(i),'string',str,'visible','on','Callback',{@UpdateModel,mechlist_callback},'TooltipString',l{i});
0344 set(handles.btn_pop_copy(i),'callback',{@AddPopulation,sel(i)},'visible','on','TooltipString',l{i});
0345 set(handles.btn_pop_delete(i),'callback',{@RemovePopulation,sel(i)},'visible','on','TooltipString',l{i});
0346 end
0347 if length(handles.btn_pop_delete)>i
0348 set(handles.edit_pop_equations(i+1:end),'visible','off');
0349 set(handles.edit_pop_size(i+1:end),'visible','off');
0350 set(handles.edit_pop_mechlist(i+1:end),'visible','off');
0351 set(handles.btn_pop_copy(i+1:end),'visible','off');
0352 set(handles.btn_pop_delete(i+1:end),'visible','off');
0353 end
0354 end
0355
0356 function UpdateMechanismEditor(src,evnt)
0357
0358 global handles SPEC
0359
0360
0361 fields={'populations','connections'};
0362 userdata=[]; mech_names={}; cnt=1;
0363 for f=1:length(fields)
0364 object=fields{f};
0365 for i=1:length(SPEC.(object))
0366 for j=1:length(SPEC.(object)(i).mechanism_list)
0367 userdata(cnt).object_type=object;
0368 userdata(cnt).object_index=i;
0369 [~,mech_name]=fileparts(SPEC.(object)(i).mechanism_list{j});
0370 userdata(cnt).mechanism_name=mech_name;
0371 userdata(cnt).mechanism_index=j;
0372 if strcmp(object,'populations')
0373 userdata(cnt).object_name=SPEC.(object)(i).name;
0374 elseif strcmp(object,'connections')
0375 userdata(cnt).object_name=[SPEC.(object)(i).source '->' SPEC.(object)(i).target];
0376 end
0377 userdata(cnt).mechanism_list_name=sprintf('%s.%s',userdata(cnt).object_name,userdata(cnt).mechanism_name);
0378 mech_names{cnt}=userdata(cnt).mechanism_list_name;
0379
0380 if ~isfield(SPEC.(object),'mechanisms') || isempty(SPEC.(object)(i).mechanisms) || ~ismember(mech_name,{SPEC.(object)(i).mechanisms.name})
0381 SPEC.(object)(i).mechanisms(end+1).name=mech_name;
0382 SPEC.(object)(i).mechanisms(end).equations='';
0383 end
0384 cnt=cnt+1;
0385 end
0386
0387
0388
0389 end
0390 end
0391
0392
0393 edit_callback='global SPEC handles LASTSPEC; LASTSPEC=SPEC; u=get(handles.list_mechs,''userdata''); if ~isempty(u), u=u(get(handles.list_mechs,''value'')); eqns=get(gcbo,''string''); idx=cellfun(@isempty,regexp(eqns,'';$'')); eqns(idx)=cellfun(@(x)[x '';''],eqns(idx),''uni'',0); SPEC.(u.object_type)(u.object_index).mechanisms(u.mechanism_index).equations=[eqns{:}]; end';
0394
0395
0396
0397
0398 old_mech_index=get(handles.list_mechs,'value');
0399 old_mech_list=get(handles.list_mechs,'string');
0400 new_mech_index=old_mech_index;
0401 new_mech_list=mech_names;
0402 set(handles.list_mechs,'string',new_mech_list,'userdata',userdata);
0403
0404
0405 if ~isempty(userdata)
0406 u=userdata(new_mech_index);
0407 if ~isempty(u)
0408 eqns=SPEC.(u.object_type)(u.object_index).mechanisms(u.mechanism_index).equations;
0409
0410 eqns=strtrim(regexp(eqns,';','split'));
0411 else
0412 eqns='';
0413 end
0414
0415 set(handles.edit_mech_eqns,'string',eqns,'Callback',{@UpdateModel,edit_callback});
0416
0417
0418 UpdateMechanismFunctions;
0419 else
0420 set(handles.edit_mech_eqns,'Callback',{@UpdateModel,edit_callback});
0421 end
0422
0423
0424 function UpdateMechanismFunctions(src,evnt,limflag)
0425
0426 global handles cfg
0427
0428
0429
0430 eqns=get(handles.edit_mech_eqns,'string');
0431
0432
0433
0434
0435 idx=cellfun(@isempty,regexp(eqns,';$'));
0436 eqns(idx)=cellfun(@(x)[x ';'],eqns(idx),'uni',0);
0437 eqns=[eqns{:}];
0438 eqns=regexp(eqns,';','split');
0439 eqns=eqns(cellfun(@ischar,eqns)&(~cellfun(@isempty,eqns)));
0440
0441
0442 idx=(~cellfun(@isempty,regexp(eqns,'^\w+\([a-zA-Z]\w*\)\s*=')));
0443 if ~any(idx)
0444 set(handles.list_functions,'string',{});
0445 set(handles.list_functions,'value',[]);
0446 return;
0447 end
0448 functions=eqns(idx);
0449 LHS=regexp(functions,'^(\w+)\(','tokens','once');
0450 LHS=[LHS{:}];
0451 RHS=regexp(functions,'^\w+(\(.+)','tokens','once');
0452 RHS=strrep([RHS{:}],'=','');
0453
0454 set(handles.list_functions,'string',functions);
0455
0456 if isfield(handles,'static_traces')
0457 axislimits=[get(handles.ax_static_plot,'xlim') get(handles.ax_static_plot,'ylim')];
0458 try delete(handles.static_traces); end
0459 handles=rmfield(handles,'static_traces');
0460 cla(handles.ax_static_plot);
0461 else
0462 axislimits='tight';
0463 end
0464
0465 X=cfg.V; cnt=1;
0466 for i=1:length(LHS)
0467 try
0468 eval(sprintf('%s=@%s;',LHS{i},RHS{i}));
0469 eval(sprintf('Y=%s(X);',LHS{i}));
0470 warning('off','MATLAB:hg:EraseModeIgnored');
0471 handles.static_traces(cnt)=line('parent',handles.ax_static_plot,'color',cfg.linecolors(max(1,mod(i,length(cfg.linecolors)))),...
0472 'LineStyle',cfg.linetype{max(1,mod(i,length(cfg.linetype)))},'xdata',X,'ydata',Y,'zdata',[]);
0473
0474
0475 cnt=cnt+1;
0476 end
0477 end
0478
0479 if isfield(handles,'static_traces') && ~isempty(handles.static_traces)
0480 h=legend(handles.ax_static_plot,LHS); set(h,'fontsize',6,'location','EastOutside');
0481 if strcmp(axislimits,'tight')
0482 axes(handles.ax_static_plot); axis(axislimits);
0483 else
0484 set(handles.ax_static_plot,'xlim',axislimits(1:2),'ylim',axislimits(3:4));
0485 end
0486 end
0487
0488
0489 function UpdateConControls(src,evnt)
0490
0491 global SPEC handles cfg
0492
0493 if isempty(SPEC.connections)
0494 sources={};
0495 targets={};
0496 else
0497 sources={SPEC.connections.source};
0498 targets={SPEC.connections.target};
0499 end
0500
0501 dx=.15; x=.13; c=1.5; dy=-.1*c; ht=.14;
0502 sel_pop_inds = get(handles.list_pops,'value');
0503 num_sel_pops = length(sel_pop_inds);
0504 pop_names={SPEC.populations(sel_pop_inds).name};
0505
0506 for i=1:num_sel_pops
0507 for j=1:num_sel_pops
0508
0509 mech_names = '';
0510 con_index = find(ismember(sources,pop_names{j}) & ismember(targets,pop_names{i}));
0511 if ~isempty(con_index)
0512 for k=1:length(SPEC.connections(con_index).mechanism_list)
0513 [~,mech_name]=fileparts(SPEC.connections(con_index).mechanism_list{k});
0514 mech_names = [mech_names mech_name ', '];
0515 end
0516 mech_names=mech_names(1:end-2);
0517 end
0518
0519 pos = [x+dx*(i-1) .8+dy*(j-1) .9*dx ht];
0520 userdata=[];
0521 userdata.source=pop_names{j};
0522 userdata.target=pop_names{i};
0523 userdata.index=con_index;
0524 con_name = [userdata.source '->' userdata.target];
0525
0526 arrow_right_code=8658;
0527 mechlist_callback='global SPEC LASTSPEC; LASTSPEC=SPEC; u=get(gcbo,''userdata''); if isempty(u.index),u.index=length(SPEC.connections)+1; end; SPEC.connections(u.index).mechanism_list=strtrim(regexp(get(gcbo,''string''),'','',''split'',''once'')); SPEC.connections(u.index).source=u.source; SPEC.connections(u.index).target=u.target;';
0528 if ~isfield(handles,'txt_to') || i>length(handles.txt_from) || j>length(handles.txt_to) || ~ishandle(handles.edit_con_mechlist(i,j)) || handles.edit_con_mechlist(i,j)==0
0529 if i==1
0530 this=zeros(max(sel_pop_inds),1);
0531 this(sel_pop_inds)=j;
0532 handles.txt_to(j) = uicontrol('parent',handles.p_net_connect,'units','normalized',...
0533 'style','text','position',[x+dx*(j-1) .88 .11 ht],'string',[char(arrow_right_code) ' ' pop_names{j}],...
0534 'callback',{@ShowClickMechList,this,'connections'},'backgroundcolor',cfg.BackgroundColor);
0535 end
0536 if j==1
0537 this=ones(1,max(sel_pop_inds));
0538 this(sel_pop_inds)=i;
0539 handles.txt_from(i) = uicontrol('parent',handles.p_net_connect,'units','normalized',...
0540 'style','text','position',[.01 .8+dy*(i-1) .11 ht],'string',[pop_names{i} ' ' char(arrow_right_code)],...
0541 'callback',{@ShowClickMechList,this,'connections'},'backgroundcolor',cfg.BackgroundColor);
0542 end
0543 handles.edit_con_mechlist(i,j) = uicontrol('parent',handles.p_net_connect,'units','normalized',...
0544 'style','edit','position',pos,'backgroundcolor','w','userdata',userdata,...
0545 'string',mech_names,'HorizontalAlignment','left','userdata',userdata);
0546 set(handles.edit_con_mechlist(i,j),'Callback',{@UpdateModel,mechlist_callback},...
0547 'ButtonDownFcn',@RenameMechanism);
0548 handles.p_conn_mechs(i,j) = uipanel('parent',handles.p_net_connect,'units','normalized',...
0549 'position',pos,'visible','off');
0550 else
0551 set(handles.txt_to(i),'string',['--> ' pop_names{i}],'visible','on');
0552 set(handles.txt_from(i),'string',[pop_names{i} ' -->'],'visible','on');
0553 set(handles.p_conn_mechs(i,j),'visible','off');
0554 set(handles.edit_con_mechlist(i,j),'string',mech_names,'userdata',userdata,'Callback',{@UpdateModel,mechlist_callback},...
0555 'ButtonDownFcn',@RenameMechanism,'visible','on');
0556 end
0557 end
0558 end
0559
0560 if isfield(handles,'txt_to') && length(handles.txt_to)>length(sel_pop_inds)
0561 set(handles.txt_to(i+1:end),'visible','off');
0562 set(handles.txt_from(i+1:end),'visible','off');
0563 set(handles.edit_con_mechlist(i+1:end,:),'visible','off');
0564 set(handles.edit_con_mechlist(:,i+1:end),'visible','off');
0565 set(handles.p_conn_mechs(i+1:end,:),'visible','off');
0566 set(handles.p_conn_mechs(:,i+1:end),'visible','off');
0567 end
0568
0569
0570
0571 function UpdateModel(src,evnt,aux_callback)
0572
0573
0574 if nargin>=3
0575 eval(aux_callback);
0576 end
0577
0578 global SPEC MODEL cfg LASTCFG handles
0579
0580
0581 if nargin>0 && isequal(src,handles.edit_mech_eqns)
0582 if isempty(SPEC.populations(1).equations) && isempty(SPEC.populations(1).mechanisms) && isempty(SPEC.populations(1).mechanism_list)
0583
0584 eqns=get(gcbo,'string');
0585 if ischar(eqns)
0586 eqns=cellstr(eqns);
0587 end
0588 idx=cellfun(@isempty,regexp(eqns,';$'));
0589 eqns(idx)=cellfun(@(x)[x ';'],eqns(idx),'uni',0);
0590
0591 SPEC.populations.mechanisms.name='l';
0592 SPEC.populations.mechanisms.equations=[eqns{:}];
0593 SPEC.populations(1).mechanism_list={'l'};
0594 end
0595 end
0596
0597
0598
0599 SPEC=dsCheckSpecification(SPEC);
0600 [SPEC.populations.parameters]=deal([]);
0601 if ~isempty(SPEC.connections)
0602 [SPEC.connections.parameters]=deal([]);
0603 end
0604
0605 MODEL=dsGenerateModel(SPEC);
0606
0607 try
0608 [ODEFUN,IC,elem_names]=dsDynasim2odefun(dsPropagateParameters(MODEL));
0609
0610
0611
0612
0613 LASTCFG=cfg;
0614 if length(IC)~=length(cfg.IC)
0615 cfg.Y=zeros(cfg.ntime,length(IC));
0616 end
0617 cfg.ODEFUN=ODEFUN;
0618 cfg.IC=IC;
0619 cfg.elem_names=elem_names;
0620 end
0621
0622
0623 UpdateViews('model');
0624 UpdateViews('selection');
0625 UpdateMechanismEditor;
0626
0627
0628
0629 function UpdatePopSelection(src,evnt)
0630
0631 UpdatePopControls;
0632 UpdateConControls;
0633 UpdateMechanismEditor;
0634
0635
0636 UpdateViews('selection');
0637
0638
0639
0640 function UpdateViews(update_what)
0641 global handles
0642
0643 switch (update_what)
0644 case 'model'
0645
0646 UpdateEqnView;
0647
0648 case 'selection'
0649 if strcmp('on',get(handles.psimview,'visible'))
0650 UpdateSimView;
0651 end
0652 end
0653
0654
0655
0656 function UpdateEqnView(src,evnt)
0657 global MODEL cfg handles
0658
0659
0660 txt=dsExtractModelStrings(MODEL,'model',0);
0661
0662
0663 txt{end+1}='';
0664 txt{end+1}='% ##############################################################';
0665 txt{end+1}='% Prepare ODEFUN for use with built-in Matlab solvers:';
0666 txt{end+1}='% ##############################################################';
0667 txt{end+1}=sprintf('ODEFUN = %s;',char(cfg.ODEFUN));
0668 txt{end+1}=sprintf('IC = [%s];',num2str(cfg.IC'));
0669 legs={};
0670 for i=1:length(cfg.elem_names), legs{end+1}=['''' cfg.elem_names{i} ''',']; end
0671 legs=[legs{:}];
0672 txt{end+1}=sprintf('elem_names = {%s};',legs(1:end-1));
0673 txt{end+1}='';
0674 txt{end+1}='% Solve system using built-in Matlab solver:';
0675 txt{end+1}='options=odeset(''RelTol'',1e-2,''AbsTol'',1e-4,''InitialStep'',.01);';
0676 txt{end+1}='[t,y]=ode23(ODEFUN,[0 100],IC,options);';
0677 txt{end+1}='figure; plot(t,y);';
0678 txt{end+1}=sprintf('legend(%s,''Location'',''EastOutside'');',strrep(legs(1:end-1),'_','\_'));
0679 cfg.model_text=txt;
0680
0681 set(handles.txt_model,'string',cfg.model_text);
0682
0683
0684
0685
0686
0687 function InitializeSimView(src,evnt)
0688 global handles cfg
0689
0690
0691
0692
0693
0694
0695
0696
0697
0698
0699
0700
0701
0702
0703
0704
0705
0706
0707
0708 dy=-1/cfg.max_num_plots;
0709 yp=1-1/cfg.max_num_plots+.04;
0710 default_visible='on';
0711
0712
0713
0714 handles.p_sim_plots=uipanel('parent',handles.psimview,'units','normalized','position',[0 .15 1 .85],'backgroundcolor','w','title','','visible','on');
0715
0716 handles.p_quicksim_settings=uipanel('parent',handles.psimview,'units','normalized','position',[0 0 .25 .15],'backgroundcolor','w','title','','visible','on');
0717
0718 handles.p_runsim_settings=uipanel('parent',handles.psimview,'units','normalized','position',[.25 0 .75 .15],'backgroundcolor','w','title','','visible','on');
0719
0720
0721 for i=1:cfg.max_num_plots
0722
0723 handles.list_vars(i)=uicontrol('units','normalized','position',[.01 yp+(i-1)*dy .14 -.8*dy],'parent',handles.p_sim_plots,'BackgroundColor',[.9 .9 .9],'style','listbox','value',1,'string',[],'Max',100,'Callback',@UpdateSimView,'TooltipString','Left-click to select variable to plot','visible',default_visible);
0724
0725 handles.list_cells(i)=uicontrol('units','normalized','position',[.15 yp+(i-1)*dy .05 -.8*dy],'parent',handles.p_sim_plots,'BackgroundColor',[.9 .9 .9],'style','listbox','value',[],'string',[],'Max',1000,'Callback',@UpdateSimView,'TooltipString','Left-click to select cells to plot','visible',default_visible);
0726
0727 handles.axes_data_image(i)=subplot('position',[.23 yp+(i-1)*dy .72 -.8*dy],'parent',handles.p_sim_plots,'visible','off','tag','simview_image');
0728 handles.img_data(i) = imagesc(cfg.t,1:length(cfg.IC),cfg.Y); axis xy;
0729 set(handles.img_data(i),'visible','off','tag','simview_image');
0730
0731 handles.axes_data_trace(i)=subplot('position',[.23 yp+(i-1)*dy .72 -.8*dy],'xdata',cfg.t,'ydata',cfg.Y(:,1),'parent',handles.p_sim_plots,'linewidth',3,'color','w','visible',default_visible,'tag','simview_trace');
0732
0733 callback=sprintf('global handles; set(handles.axes_data_trace(%g),''ylim'',[str2double(get(handles.edit_ymin(%g),''string'')) str2double(get(gco,''string''))]); set(handles.axes_data_image(%g),''clim'',[str2double(get(handles.edit_ymin(%g),''string'')) str2double(get(gco,''string''))]); cfg.ymax(%g)=str2double(get(gco,''string''));',i,i,i,i,i);
0734 handles.edit_ymax(i)=uicontrol('style','edit','parent',handles.p_sim_plots,'tag','ymax','units','normalized','position',[.955 .95+dy*(i-1)-.01 .037 .03],'backgroundcolor','w','string',cfg.ymax(i),'HorizontalAlignment','left','Callback',callback,'fontsize',8);
0735
0736 callback=sprintf('global handles; set(handles.axes_data_trace(%g),''ylim'',[str2double(get(gco,''string'')) str2double(get(handles.edit_ymax(%g),''string''))]); set(handles.axes_data_image(%g),''clim'',[str2double(get(gco,''string'')) str2double(get(handles.edit_ymax(%g),''string''))]); cfg.ymin(%g)=str2double(get(gco,''string''));',i,i,i,i,i);
0737 handles.edit_ymin(i)=uicontrol('style','edit','parent',handles.p_sim_plots,'tag','ymin','units','normalized','position',[.955 .95+dy*(i-1)+.8*dy+.03-.01 .037 .03],'backgroundcolor','w','string',cfg.ymin(i),'HorizontalAlignment','left','Callback',callback,'fontsize',8);
0738 handles.btn_sim_autoscale(i)=uicontrol('style','pushbutton','parent',handles.p_sim_plots,'units','normalized','position',[.96 .95+dy*(i-1)+.8*dy/2 .027 .05],'fontsize',12,'fontweight','bold','fontname','Blue Highway','String',char(cfg.autoscale_charcode),'callback',{@AutoscaleSimPlot,i},'visible',default_visible);
0739
0740
0741
0742
0743
0744
0745
0746
0747
0748
0749
0750
0751
0752 end
0753 handles.line_data=[];
0754
0755
0756 handles.btn_quicksim=uicontrol('style','pushbutton','parent',handles.p_quicksim_settings,'units','normalized','position',[.15 .55 .7 .3],'fontsize',12,'fontweight','bold','string','QuickSim','callback',@QuickSim,'backgroundcolor',cfg.ButtonColor,'ForegroundColor',cfg.ButtonFontColor);
0757
0758 handles.edit_t0 = uicontrol('style','edit','parent',handles.p_quicksim_settings,'units','normalized','position',[.15 .15 .3 .3],'fontsize',12,'string','0','HorizontalAlignment','left','backgroundcolor','w','callback','global cfg; cfg.t0=str2num(get(gcbo,''string''));');
0759 uicontrol('style','text','parent',handles.p_quicksim_settings,'units','normalized','position',[.05 .1 .1 .3],'fontsize',10,'string','t0','HorizontalAlignment','center','backgroundcolor','w','callback','global cfg; cfg.dt=str2num(get(gcbo,''string''));');
0760
0761 handles.edit_tf = uicontrol('style','edit','parent',handles.p_quicksim_settings,'units','normalized','position',[.55 .15 .3 .3],'fontsize',12,'string','200','HorizontalAlignment','left','backgroundcolor','w','callback','global cfg; cfg.tf=str2num(get(gcbo,''string''));');
0762 uicontrol('style','text','parent',handles.p_quicksim_settings,'units','normalized','position',[.45 .1 .1 .3],'fontsize',10,'string','tf','HorizontalAlignment','center','backgroundcolor','w','callback','global cfg; cfg.dt=str2num(get(gcbo,''string''));');
0763 handles.check_compile = uicontrol('style','checkbox','parent',handles.p_quicksim_settings,'units','normalized','position',[.15 .05 .85 .1],'string','compile','value',0,'backgroundcolor','w');
0764
0765
0766
0767 handles.btn_start=uicontrol('style','pushbutton','parent',handles.p_runsim_settings,'units','normalized','position',[.05 .55 .15 .3],'fontsize',12,'fontweight','bold','string','Start','callback',@RunSim,'backgroundcolor',cfg.ButtonColor,'ForegroundColor',cfg.ButtonFontColor);
0768
0769 handles.btn_pause=uicontrol('style','pushbutton','parent',handles.p_runsim_settings,'units','normalized','position',[.05 .55 .15 .3],'fontsize',12,'fontweight','bold','string','Pause','callback','global cfg; cfg.sim_paused=-cfg.sim_paused;','visible','off','backgroundcolor',cfg.ButtonColor,'ForegroundColor',cfg.ButtonFontColor);
0770
0771 handles.btn_stop=uicontrol('style','pushbutton','parent',handles.p_runsim_settings,'units','normalized','position',[.05 .15 .15 .3],'fontsize',12,'fontweight','bold','string','Stop','callback','global cfg; cfg.sim_stopped=1; cfg.sim_paused=-1;','visible','off','backgroundcolor',cfg.ButtonColor,'ForegroundColor',cfg.ButtonFontColor);
0772
0773 handles.edit_dt = uicontrol('style','edit','parent',handles.p_runsim_settings,'units','normalized','position',[.23 .55 .07 .3],'fontsize',12,'string','.01','HorizontalAlignment','left','backgroundcolor','w','callback','global cfg; cfg.dt=str2num(get(gcbo,''string''));');
0774 uicontrol('style','text','parent',handles.p_runsim_settings,'units','normalized','position',[.23 .4 .07 .15],'fontsize',10,'string','dt','HorizontalAlignment','center','backgroundcolor','w','callback','global cfg; cfg.dt=str2num(get(gcbo,''string''));');
0775
0776 handles.edit_ntime = uicontrol('style','edit','parent',handles.p_runsim_settings,'units','normalized','position',[.32 .55 .15 .3],'fontsize',12,'string','20001','HorizontalAlignment','left','backgroundcolor','w','callback','global cfg; cfg.ntime=str2num(get(gcbo,''string''));');
0777 uicontrol('style','text','parent',handles.p_runsim_settings,'units','normalized','position',[.32 .4 .15 .15],'fontsize',10,'string','# times','HorizontalAlignment','center','backgroundcolor','w','callback','global cfg; cfg.dt=str2num(get(gcbo,''string''));');
0778
0779 handles.btn_auto_ylim_by_pop=uicontrol('style','pushbutton','parent',handles.p_runsim_settings,'units','normalized','position',[.75 .55 .23 .3],'fontsize',10,'fontweight','bold','string','auto_by_pop','callback',@UpdateSimView,'visible','off','backgroundcolor',cfg.ButtonColor,'ForegroundColor',cfg.ButtonFontColor);
0780
0781 handles.btn_auto_ylim_by_pop=uicontrol('style','pushbutton','parent',handles.p_runsim_settings,'units','normalized','position',[.75 .15 .23 .3],'fontsize',10,'fontweight','bold','string','auto_all_pops','callback',@UpdateSimView,'visible','off','backgroundcolor',cfg.ButtonColor,'ForegroundColor',cfg.ButtonFontColor);
0782
0783
0784
0785
0786 handles.radio_plot_type=uibuttongroup('visible','off','SelectionChangeFcn',@UpdateSimView,'units','normalized','Position',[.55 .07 .15 .85],'parent',handles.p_runsim_settings,'backgroundcolor','w','title','Display');
0787 handles.radio_plot_type_trace=uicontrol('style','radiobutton','string','trace','units','normalized','pos',[.1 .6 .9 .3],'userdata','simview_trace','parent',handles.radio_plot_type,'HandleVisibility','on','backgroundcolor','w');
0788 handles.radio_plot_type_image=uicontrol('style','radiobutton','string','image','units','normalized','pos',[.1 .2 .9 .3],'userdata','simview_image','parent',handles.radio_plot_type,'HandleVisibility','on','backgroundcolor','w');
0789 set(handles.radio_plot_type,'SelectedObject',handles.radio_plot_type_trace,'Visible','on');
0790
0791
0792
0793 handles.check_zscore = uicontrol('style','checkbox','parent',handles.p_runsim_settings,'callback',@UpdateSimView,'units','normalized','position',[.75 .5 .2 .15],'string','zscore','value',0,'backgroundcolor','w');
0794
0795
0796 uicontrol('style','pushbutton','parent',handles.p_runsim_settings,'units','normalized','Position',[.94 .35 .04 .3],'fontsize',12,'fontweight','bold','fontname','Blue Highway','String',char(cfg.autoscale_charcode),'callback',{@AutoscaleSimPlot,0},'visible','on');
0797
0798
0799 function UpdateSimView(src,evnt)
0800
0801 global handles cfg MODEL
0802
0803 if nargin>0 && isequal(src,handles.radio_plot_type)
0804
0805 Children=get(handles.radio_plot_type,'Children');
0806 for i=1:length(Children)
0807 set(findobj('tag',get(Children(i),'userdata')),'visible','off');
0808 end
0809
0810 SelectedObject=get(handles.radio_plot_type,'SelectedObject');
0811 set(findobj('tag',get(SelectedObject,'userdata')),'visible','on');
0812 end
0813
0814 pop_names=get(handles.list_pops,'string');
0815 sel_pop_inds=get(handles.list_pops,'value');
0816 sel_pop_names=pop_names(sel_pop_inds);
0817 num_plots=min(length(sel_pop_inds),cfg.max_num_plots);
0818 all_state_vars=MODEL.state_variables;
0819 if ~isempty(MODEL.monitors)
0820 all_state_vars=cat(2,all_state_vars,fieldnames(MODEL.monitors)');
0821 end
0822
0823 for plot_index=1:num_plots
0824 pop_name=sel_pop_names{plot_index};
0825
0826 pat=['^' pop_name '_'];
0827 sel_state_vars=all_state_vars(~cellfun(@isempty,regexp(all_state_vars,pat,'once')));
0828
0829 num_cells=MODEL.parameters.([pop_name '_Npop']);
0830 str_cell_inds=cellfun(@num2str,num2cell(1:num_cells),'uni',0);
0831 sel_cell_inds=1:length(str_cell_inds);
0832
0833 set(handles.list_vars(plot_index),'string',sel_state_vars);
0834 set(handles.list_cells(plot_index),'string',str_cell_inds);
0835 val=get(handles.list_vars(plot_index),'value');
0836 if isempty(val) || max(val)>length(sel_state_vars)
0837 set(handles.list_vars(plot_index),'value',1);
0838 end
0839 val=get(handles.list_cells(plot_index),'value');
0840 if isempty(val) || max(val)>length(str_cell_inds)
0841 set(handles.list_cells(plot_index),'value',sel_cell_inds);
0842 end
0843 end
0844
0845 for plot_index=1:num_plots
0846 switch get(get(handles.radio_plot_type,'SelectedObject'),'String')
0847 case 'trace'
0848 set(handles.axes_data_trace(plot_index),'visible','on');
0849 if size(handles.line_data,1)>=plot_index
0850 ind=handles.line_data(plot_index,:)~=0;
0851 set(handles.line_data(plot_index,ind),'visible','on');
0852 end
0853 case 'image'
0854 set(handles.axes_data_image(plot_index),'visible','on');
0855 set(handles.img_data(plot_index),'visible','on');
0856 end
0857 set(handles.edit_ymax(plot_index),'visible','on');
0858 set(handles.edit_ymin(plot_index),'visible','on');
0859 set(handles.list_vars(plot_index),'visible','on');
0860 set(handles.list_cells(plot_index),'visible','on');
0861 set(handles.btn_sim_autoscale(plot_index),'visible','on');
0862 end
0863
0864 for plot_index=num_plots+1:cfg.max_num_plots
0865 set(handles.edit_ymax(plot_index),'visible','off');
0866 set(handles.edit_ymin(plot_index),'visible','off');
0867 set(handles.list_vars(plot_index),'visible','off');
0868 set(handles.list_cells(plot_index),'visible','off');
0869 set(handles.axes_data_trace(plot_index),'visible','off');
0870 if size(handles.line_data,1)>=plot_index
0871 ind=find(handles.line_data(plot_index,:)~=0);
0872 set(handles.line_data(plot_index,ind),'visible','off');
0873 end
0874 set(handles.axes_data_image(plot_index),'visible','off');
0875 set(handles.img_data(plot_index),'visible','off');
0876 set(handles.btn_sim_autoscale(plot_index),'visible','off');
0877 end
0878
0879 UpdateSimPlots;
0880
0881
0882 function UpdateSimPlots(src,evnt)
0883
0884 global handles cfg
0885 sel_pop_inds=get(handles.list_pops,'value');
0886 num_plots=min(length(sel_pop_inds),cfg.max_num_plots);
0887
0888 plot_type=get(get(handles.radio_plot_type,'SelectedObject'),'String');
0889
0890 for plot_index=1:num_plots
0891
0892 plot_Y=SelectPlotData(plot_index);
0893 num_elems=size(plot_Y,2);
0894
0895 switch plot_type
0896 case 'trace'
0897
0898 for line_index=1:num_elems
0899
0900 if size(handles.line_data,1)>=plot_index && size(handles.line_data,2)>=line_index && ishandle(handles.line_data(plot_index,line_index)) && handles.line_data(plot_index,line_index)>0
0901 set(handles.line_data(plot_index,line_index),'ydata',plot_Y(:,line_index),'xdata',(0:cfg.ntime-1)*cfg.dt,'visible','on');
0902 else
0903 try
0904 warning('off','MATLAB:hg:EraseModeIgnored');
0905 handles.line_data(plot_index,line_index)=line('parent',handles.axes_data_trace(plot_index),'color',cfg.linecolors(max(1,mod(line_index,length(cfg.linecolors)))),'LineStyle',cfg.linetype{max(1,mod(line_index,length(cfg.linetype)))},'erase','background','xdata',(0:cfg.ntime-1)*cfg.dt,'ydata',plot_Y(:,line_index),'zdata',[],'tag','simview_trace');
0906 catch
0907 handles.line_data(plot_index,line_index)=line('parent',handles.axes_data_trace(plot_index),'color',cfg.linecolors(max(1,mod(line_index,length(cfg.linecolors)))),'LineStyle',cfg.linetype{max(1,mod(line_index,length(cfg.linetype)))},'xdata',(0:cfg.ntime-1)*cfg.dt,'ydata',plot_Y(:,line_index),'zdata',[],'tag','simview_trace');
0908 end
0909 end
0910 end
0911 ax=handles.axes_data_trace(plot_index);
0912 ylims=[cfg.ymin(plot_index) cfg.ymax(plot_index)];
0913
0914 if size(handles.line_data,2)>num_elems
0915 ind=num_elems+1:size(handles.line_data,2);
0916 ind=ind(handles.line_data(plot_index,ind)~=0);
0917 set(handles.line_data(plot_index,ind),'visible','off');
0918 end
0919 case 'image'
0920 set(handles.img_data(plot_index),'cdata',plot_Y','ydata',1:num_elems,'xdata',(0:cfg.ntime-1)*cfg.dt);
0921 ax=handles.axes_data_image(plot_index);
0922 set(ax,'clim',[cfg.ymin(plot_index) cfg.ymax(plot_index)]);
0923 if num_elems>1, ylims=[.5 num_elems+.5]; else ylims=[.5 1.5]; end
0924 end
0925
0926
0927 if ylims(1)~=ylims(2)
0928 set(ax,'ylim',ylims);
0929 end
0930
0931 set(ax,'xlim',[0 cfg.ntime*cfg.dt]);
0932
0933 set(handles.axes_data_trace(plot_index),'xticklabel',cfg.xticklabel,'xtick',cfg.xtick);
0934 set(handles.axes_data_image(plot_index),'xticklabel',cfg.xticklabel,'xtick',cfg.xtick);
0935
0936 end
0937
0938
0939 function AutoscaleSimPlot(src,evnt,plot_index)
0940 global handles cfg
0941
0942
0943 if plot_index==0
0944
0945 datmax=-inf;
0946 datmin=inf;
0947 for i=1:length(handles.edit_ymin)
0948 if strcmp('on',get(handles.axes_data_trace(i),'visible'))
0949 plot_Y=SelectPlotData(i);
0950 datmax=max(datmax,max(plot_Y(:)));
0951 datmin=min(datmin,min(plot_Y(:)));
0952 end
0953 end
0954 plot_index=1:length(handles.edit_ymin);
0955
0956
0957 else
0958
0959 plot_Y=SelectPlotData(plot_index);
0960 datmax=max(plot_Y(:));
0961 datmin=min(plot_Y(:));
0962 end
0963
0964 for i=1:length(plot_index)
0965
0966 switch get(get(handles.radio_plot_type,'SelectedObject'),'String')
0967 case 'trace'
0968
0969
0970
0971 set(handles.axes_data_trace(plot_index(i)),'ylim',[datmin datmax]);
0972
0973 case 'image'
0974 set(handles.axes_data_image(plot_index(i)),'clim',[datmin datmax]);
0975 end
0976 set(handles.edit_ymin(plot_index(i)),'string',datmin);
0977 set(handles.edit_ymax(plot_index(i)),'string',datmax);
0978 cfg.ymin(plot_index(i))=datmin;
0979 cfg.ymax(plot_index(i))=datmax;
0980 end
0981
0982
0983 function AutoscaleMechPlot(src,evnt)
0984 global handles
0985 ymin=inf;
0986 ymax=-inf;
0987 if isfield(handles,'static_traces')
0988 for i=1:length(handles.static_traces)
0989 ymin=min(ymin,min(get(handles.static_traces(i),'ydata')));
0990 ymax=max(ymax,max(get(handles.static_traces(i),'ydata')));
0991 end
0992 set(handles.ax_static_plot,'ylim',[ymin ymax]);
0993 end
0994
0995
0996 function ZoomFunction(src,evnt)
0997 global handles cfg
0998
0999 if ismember(gco,handles.axes_data_trace)
1000 plot_index=find(gco==handles.axes_data_trace);
1001 hplot=handles.axes_data_trace(plot_index);
1002 LIM=[cfg.ymin(plot_index) cfg.ymax(plot_index)];
1003 property='ylim';
1004 elseif ismember(gco,handles.img_data)
1005 disp('asdf')
1006 plot_index=find(gco==handles.img_data);
1007 hplot=handles.axes_data_image(plot_index);
1008 LIM=[cfg.ymin(plot_index) cfg.ymax(plot_index)];
1009 property='clim';
1010 elseif isequal(gco,handles.ax_static_plot)
1011 hplot=handles.ax_static_plot;
1012 LIM=get(hplot,'ylim');
1013 property='ylim';
1014 else
1015 LIM=[];
1016 end
1017
1018 if isempty(LIM) || LIM(1)>=LIM(2) || any(isnan(LIM)) || any(isinf(LIM)), return; end
1019 if evnt.VerticalScrollCount < 0
1020 if LIM(1)>0, LIM(1)=LIM(1)*1.5; else LIM(1)=LIM(1)/1.5; end
1021 if LIM(2)>0, LIM(2)=LIM(2)/1.5; else LIM(1)=LIM(1)*1.5; end
1022 else
1023 if LIM(1)>0, LIM(1)=LIM(1)/1.5; else LIM(1)=LIM(1)*1.5; end
1024 if LIM(2)>0, LIM(2)=LIM(2)*1.5; else LIM(1)=LIM(1)/1.5; end
1025 end
1026
1027 set(hplot,property,LIM);
1028 if ismember(gco,handles.axes_data_trace) || ismember(gco,handles.img_data)
1029 set(handles.edit_ymin(plot_index),'string',LIM(1));
1030 set(handles.edit_ymax(plot_index),'string',LIM(2));
1031 cfg.ymin(plot_index)=LIM(1);
1032 cfg.ymax(plot_index)=LIM(2);
1033 end
1034
1035
1036 function plot_Y=SelectPlotData(plot_index)
1037
1038 global cfg handles
1039
1040 all_var_names=get(handles.list_vars(plot_index),'string');
1041 if ~isempty(all_var_names)
1042 sel_var_names=all_var_names(get(handles.list_vars(plot_index),'value'));
1043 else
1044 sel_var_names=all_var_names;
1045 end
1046 sel_cell_inds=get(handles.list_cells(plot_index),'value');
1047
1048
1049 vind=find(ismember(cfg.elem_names,sel_var_names));
1050 elem_names=cfg.elem_names(vind);
1051
1052
1053 yind=[];
1054 for i=1:length(sel_var_names)
1055 cind=find(strcmp(sel_var_names{i},elem_names));
1056 if max(sel_cell_inds)>length(cind)
1057 sel_cell_inds=sel_cell_inds(sel_cell_inds<=length(cind));
1058 end
1059 yind=[yind vind(cind(sel_cell_inds))];
1060 end
1061 plot_Y=cfg.Y(cfg.t_plot_indices,yind);
1062 sel_elem_names=cfg.elem_names(yind);
1063
1064
1065 if get(handles.check_zscore,'value')==1
1066 uniq_elem_names=unique(sel_elem_names);
1067 for i=1:length(uniq_elem_names)
1068 idx=ismember(sel_elem_names,uniq_elem_names{i});
1069 tmp=plot_Y(:,idx);
1070 plot_Y(:,idx)=(tmp-mean(tmp(:)))/std(tmp(:));
1071 end
1072 end
1073
1074
1075 function RunSim(src,evnt)
1076
1077 global cfg handles t
1078 set(handles.btn_start,'visible','off');
1079 set(handles.btn_pause,'visible','on');
1080 set(handles.btn_stop,'visible','on');
1081 set(handles.btn_quicksim,'Enable','off');
1082 set(handles.btn_start,'Enable','off');
1083
1084
1085 cfg.Y=nan(cfg.ntime,length(cfg.IC));
1086 cfg.Y(1,:)=cfg.IC;
1087 cfg.t=(0:cfg.ntime-1)'*cfg.dt;
1088 X=cfg.IC;
1089 t=0;
1090 t_pointer=2;
1091 cfg.xtick=linspace(cfg.t(1),cfg.t(end),cfg.num_xticks);
1092 cfg.xticklabel=linspace(cfg.t(1),cfg.t(end),cfg.num_xticks);
1093
1094
1095 while cfg.sim_stopped~=1
1096
1097 if cfg.sim_paused==1
1098 set(handles.btn_pause,'string','Resume');
1099 while cfg.sim_paused==1
1100 pause(.1);
1101
1102 end
1103 set(handles.btn_pause,'string','Pause');
1104 end
1105
1106 t=t+cfg.dt;
1107 X=X+cfg.dt*cfg.ODEFUN(t,X);
1108
1109 cfg.Y(t_pointer,:)=X;
1110 cfg.t=cfg.t+cfg.dt;
1111
1112 t_pointer=t_pointer+1;
1113 if t_pointer>cfg.ntime
1114 t_pointer=1;
1115 end
1116
1117 if mod(t_pointer,cfg.num_steps_per_plot)==0
1118
1119 if t<(cfg.ntime*cfg.dt)
1120 cfg.t_plot_indices=1:cfg.ntime;
1121 else
1122 cfg.xticklabel=cfg.xticklabel+cfg.dt*cfg.num_steps_per_plot;
1123 cfg.t_plot_indices=[t_pointer:cfg.ntime 1:t_pointer-1];
1124 end
1125
1126 UpdateSimPlots;
1127 drawnow;
1128 end
1129 end
1130 cfg.sim_stopped=0;
1131 set(handles.btn_start,'visible','on');
1132 set(handles.btn_pause,'visible','off');
1133 set(handles.btn_stop,'visible','off');
1134 set(handles.btn_quicksim,'Enable','on');
1135 set(handles.btn_start,'Enable','on');
1136
1137 function QuickSim(src,evnt)
1138
1139 global DATA SPEC cfg handles MODEL
1140 set(handles.btn_quicksim,'Enable','off');
1141 set(handles.btn_start,'Enable','off');
1142
1143
1144 verbose_flag=1;
1145
1146
1147
1148 try
1149 DATA=dsSimulate(SPEC,'time_limits',[cfg.t0 cfg.tf],'dt',cfg.dt,'solver','euler','compile_flag',get(handles.check_compile,'value'),'verbose_flag',verbose_flag);
1150 catch
1151 set(handles.btn_quicksim,'Enable','on');
1152 set(handles.btn_start,'Enable','on');
1153 end
1154
1155 cfg=data2cfg(DATA);
1156 MODEL=dsGenerateModel(SPEC);
1157 UpdateSimView;
1158 set(handles.btn_quicksim,'Enable','on');
1159 set(handles.btn_start,'Enable','on');
1160 set(handles.edit_ntime,'string',num2str(cfg.ntime));
1161
1162
1163 function cfg=data2cfg(data)
1164 global cfg
1165 elem_names={};
1166 Y=[];
1167 for i=1:length(data.labels)
1168 Y=cat(2,Y,data.(data.labels{i}));
1169 elem_names=cat(2,elem_names,repmat(data.labels(i),[1 size(data.(data.labels{i}),2)]));
1170 end
1171 cfg.t=data.time;
1172 cfg.Y=Y;
1173 cfg.elem_names=elem_names;
1174 cfg.ntime=length(data.time);
1175 cfg.t_plot_indices=1:cfg.ntime;
1176 cfg.dt=data.simulator_options.dt;
1177 cfg.xtick=linspace(cfg.t(1),cfg.t(end),cfg.num_xticks);
1178 cfg.xticklabel=linspace(cfg.t(1),cfg.t(end),cfg.num_xticks);
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189 function AddPopulation(src,evnt,base_pop_index)
1190 global SPEC LASTSPEC handles
1191 LASTSPEC=SPEC;
1192
1193 SPEC.populations(end+1)=SPEC.populations(base_pop_index);
1194
1195 name=sprintf('%s%g',SPEC.populations(end).name,length(SPEC.populations));
1196 SPEC.populations(end).name=name;
1197
1198 val = get(handles.list_pops,'value');
1199 str = get(handles.list_pops,'string');
1200 set(handles.list_pops,'value',[val length(SPEC.populations)]);
1201 set(handles.list_pops,'string',{str{:} name});
1202
1203 UpdateModel;
1204 UpdatePopSelection;
1205
1206
1207 function RemovePopulation(src,evnt,base_pop_index)
1208 global SPEC LASTSPEC handles
1209 LASTSPEC=SPEC;
1210 name=SPEC.populations(base_pop_index).name;
1211
1212 SPEC.populations(base_pop_index)=[];
1213
1214 if ~isempty(SPEC.connections)
1215 idx=ismember({SPEC.connections.source},name) | ismember({SPEC.connections.target},name);
1216 SPEC.connections(idx)=[];
1217 if isempty(SPEC.connections)
1218 SPEC.connections=[];
1219 end
1220 end
1221
1222 val = get(handles.list_pops,'value');
1223 str = get(handles.list_pops,'string');
1224 new_str=setdiff(str,name,'stable');
1225 new_val=find(ismember(new_str,str(val)));
1226 set(handles.list_pops,'value',new_val);
1227 set(handles.list_pops,'string',new_str);
1228
1229 UpdateModel;
1230 UpdatePopSelection;
1231
1232
1233 function RenamePopulation(src,evnt)
1234 global SPEC handles
1235 val = get(handles.list_pops,'value');
1236 str = get(handles.list_pops,'string');
1237 if length(val)>1
1238
1239 return;
1240 end
1241 new_name=inputdlg(['Rename Population: ' str{val}],'New name');
1242 drawnow; pause(0.05);
1243 if isempty(new_name), return; end
1244 new_name=new_name{1};
1245 old_name=str{val};
1246
1247 idx=ismember({SPEC.populations.name},old_name);
1248 SPEC.populations(idx).name=new_name;
1249
1250 if ~isempty(SPEC.connections)
1251 idx=ismember({SPEC.connections.source},old_name);
1252 [SPEC.connections(idx).source]=deal(new_name);
1253 idx=ismember({SPEC.connections.target},old_name);
1254 [SPEC.connections(idx).target]=deal(new_name);
1255 end
1256
1257 str{val}=new_name;
1258 set(handles.list_pops,'string',str);
1259
1260 UpdateModel;
1261 UpdatePopSelection;
1262
1263
1264 function RenameMechanism(src,evnt)
1265 global SPEC handles
1266 ud=get(src,'userdata');
1267 v=get(src,'value');
1268 s=get(src,'string');
1269 if length(v)>1, return; end
1270 this=ud(v);
1271 newname=inputdlg(['Rename Mechanism: ' s{v}],'New name');
1272 drawnow; pause(0.05);
1273 if isempty(newname), return; end
1274 newname=newname{1};
1275
1276
1277 SPEC.(this.object_type)(this.object_index).mechanism_list{this.mechanism_index}=newname;
1278 idx=ismember({SPEC.(this.object_type)(this.object_index).mechanisms.name},this.mechanism_name);
1279 SPEC.(this.object_type)(this.object_index).mechanisms(idx).name=newname;
1280
1281
1282 if ~isfield(SPEC,'mechanisms') || isempty(SPEC.mechanisms)
1283 SPEC.mechanisms=SPEC.(this.object_type)(this.object_index).mechanisms(idx);
1284 elseif ~ismember(newname,{SPEC.mechanisms.name})
1285 SPEC.mechanisms(end+1)=SPEC.(this.object_type)(this.object_index).mechanisms(idx);
1286 end
1287
1288
1289 s{v}=[this.object_name '.' newname];
1290 set(src,'string',s);
1291
1292
1293 this.mechanism_name=newname;
1294 this.mechanism_list_name = [this.object_name '.' newname];
1295 ud(v)=this;
1296 set(src,'userdata',ud);
1297
1298
1299 m=SPEC.(this.object_type)(this.object_index).mechanism_list;
1300 [~,str]=fileparts(m{1});
1301 for j=2:length(m)
1302 [~,name]=fileparts(m{j});
1303 str=[str ', ' name];
1304 end
1305 if strcmp(this.object_type,'populations')
1306 set(handles.edit_pop_mechlist(this.object_index),'string',str);
1307 else
1308
1309
1310
1311 end
1312
1313 UpdateModel;
1314
1315
1316 function SaveModel(src,evnt)
1317
1318 [filename,pathname] = uiputfile({'*.mat;'},'Save as','model-specification.mat');
1319 if isequal(filename,0) || isequal(pathname,0)
1320 return;
1321 end
1322 outfile = fullfile(pathname,filename);
1323 [fpath,fname,fext] = fileparts(outfile);
1324 global SPEC
1325 specification=SPEC;
1326 fprintf('Saving model ''specification'': %s\n',outfile);
1327 save(outfile,'specification');
1328
1329
1330 function OpenModel(src,evnt)
1331
1332
1333 [filename,pathname] = uigetfile({'*.mat'},'Pick a model specification file.','MultiSelect','off');
1334
1335 if isequal(filename,0) || isequal(pathname,0), return; end
1336 if iscell(filename)
1337 datafile = cellfun(@(x)fullfile(pathname,x),filename,'uniformoutput',false);
1338 filename = filename{1};
1339 else
1340 datafile = [pathname filename];
1341 end
1342 if exist(datafile,'file')
1343 fprintf('Loading file: %s\n',datafile);
1344 try
1345 o=load(datafile);
1346 fprintf('Looking for ''specification'' structure...\n');
1347 if isfield(o,'specification')
1348 fprintf('specification found.\n');
1349 global SPEC handles
1350 SPEC=o.specification;
1351 close(handles.fig_main);
1352 dynasim(SPEC);
1353
1354
1355 else
1356 fprintf('specification not found\n');
1357 end
1358 catch
1359 fprintf('failed to load file. check that it is a valid matlab file: %s\n',datafile);
1360 return;
1361 end
1362 end
1363
1364
1365 function eqns=dsExtractModelStrings(MODEL,display_mode,display_flag)
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399 if nargin<3
1400 display_flag=0;
1401 end
1402 if nargin<2 || isempty(display_mode)
1403 display_mode='model';
1404 end
1405
1406 eqns={};
1407 switch lower(display_mode)
1408 case 'model'
1409
1410 MODEL=dsCheckModel(MODEL);
1411
1412 if ~isempty(MODEL.state_variables)
1413 eqns{end+1}='% DIFFERENTIAL EQUATIONS:';
1414 vars=MODEL.state_variables;
1415 for i=1:length(vars)
1416 eqns{end+1}=sprintf('%% %s'' = %s',vars{i},MODEL.ODEs.(vars{i}));
1417 end
1418 eqns{end+1}='%';
1419 eqns{end+1}='% Initial conditions:';
1420 for i=1:length(vars)
1421 eqns{end+1}=sprintf('%% %s(0) = %s',vars{i},MODEL.ICs.(vars{i}));
1422 end
1423 eqns{end+1}='';
1424 end
1425
1426 if ~isempty(MODEL.conditionals)
1427 eqns{end+1}='% CONDITIONALS:';
1428 for i=1:length(MODEL.conditionals)
1429 str=sprintf(' if(%s)then(%s)',MODEL.conditionals(i).condition,MODEL.conditionals(i).action);
1430 if ~isempty(MODEL.conditionals(i).else)
1431 str=sprintf('%selse(%s)',str,MODEL.conditionals(i).else);
1432 end
1433 eqns{end+1}=sprintf('\t%s',str);
1434 end
1435 eqns{end+1}='';
1436 end
1437 types={'parameters','fixed_variables','functions'};
1438 type_headers={'% PARAMETERS:','% FIXED VARIABLES:','% FUNCTIONS:','% MONITORS:'};
1439 for p=1:length(types)
1440 type=types{p};
1441 header=type_headers{p};
1442 if ~isempty(MODEL.(type))
1443 eqns{end+1}=header;
1444 fields=fieldnames(MODEL.(type));
1445 for i=1:length(fields)
1446 val=MODEL.(type).(fields{i});
1447 if ~ischar(val)
1448 val=toString(val,'compact');
1449 end
1450 eqns{end+1}=sprintf(' %s = %s',fields{i},val);
1451 end
1452 end
1453 eqns{end+1}='';
1454 end
1455 case 'odefun'
1456
1457
1458
1459
1460
1461
1462
1463
1464 types={'parameters','fixed_variables','functions'};
1465 for p=1:length(types)
1466 type=types{p};
1467 if ~isempty(MODEL.(type))
1468 fields=fieldnames(MODEL.(type));
1469 for i=1:length(fields)
1470 val=MODEL.(type).(fields{i});
1471 if ~ischar(val)
1472 val=toString(val,'compact');
1473 end
1474
1475 eval(sprintf('%s = %s;',fields{i},val));
1476 end
1477 end
1478 end
1479
1480
1481 num_vars=length(MODEL.state_variables);
1482 num_elems=zeros(1,num_vars);
1483 old_vars=MODEL.state_variables;
1484 new_vars=cell(1,num_vars);
1485 new_inds=cell(1,num_vars);
1486 all_ICs=cell(1,num_vars);
1487 IC_names={};
1488 state_var_index=0;
1489 for i=1:num_vars
1490 var=MODEL.state_variables{i};
1491
1492 ic=eval([MODEL.ICs.(var) ';']);
1493 num_elems(i)=length(ic);
1494
1495 all_ICs{i}=ic;
1496 IC_names{i}=repmat({var},[1 num_elems(i)]);
1497 new_inds{i}=state_var_index+(1:length(ic));
1498 new_vars{i}=sprintf('X(%g:%g)',new_inds{i}(1),new_inds{i}(end));
1499 state_var_index=state_var_index+length(ic);
1500 end
1501
1502
1503 ODEs=strtrim(struct2cell(MODEL.ODEs));
1504 idx=cellfun(@isempty,regexp(ODEs,';$'));
1505 ODEs(idx)=cellfun(@(x)[x ';'],ODEs(idx),'uni',0);
1506 ODEs=[ODEs{:}];
1507 ODEs=strrep(ODEs,';',',');
1508
1509
1510 for i=1:num_vars
1511 ODEs=dynasim_strrep(ODEs,old_vars{i},new_vars{i});
1512 end
1513
1514
1515
1516 ODEFUN = eval(['@(t,X) [' ODEs '];']);
1517 IC=cat(2,all_ICs{:});
1518 elem_names=cat(2,IC_names{:});
1519
1520 eqns{1}=ODEFUN;
1521 eqns{2}=IC;
1522 eqns{3}=elem_names;
1523
1524
1525
1526
1527 eqns=dsExtractModelStrings(MODEL,'odefun',0);
1528 ODEFUN=eqns{1};
1529 IC=eqns{2};
1530 elem_names=eqns{3};
1531
1532 dt=.01; t=0:dt:100;
1533 y=zeros(length(t),length(IC));
1534 y(1,:)=IC;
1535 for i=2:length(t)
1536 y(i,:)=y(i-1,:)+dt*ODEFUN(t,y(i-1,:));
1537 end
1538 figure; plot(t,y); legend(elem_names{:},'Location','EastOutside');
1539
1540 y=IC;
1541 for i=1:1e4
1542 y=y+dt*ODEFUN(0,y);
1543 end;
1544
1545
1546
1547 otherwise
1548 error('options ''specification'' and ''xpp'' not implemented yet.');
1549 end
1550
1551 if display_flag
1552 cellfun(@disp,eqns);
1553 end
1554
1555
1556 function undo(src,evnt)
1557 global SPEC LASTSPEC cfg LASTCFG handles MODEL
1558 s=SPEC;
1559 SPEC=LASTSPEC;
1560 LASTSPEC=s;
1561 c=cfg;
1562 cfg=LASTCFG;
1563 LASTCFG=c;
1564 MODEL=dsGenerateModel(SPEC);
1565
1566 InitializeMainGUI;
1567 UpdateModel;
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616