0001 function varargout=DIVA(varargin)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070 global DIVA_data
0071 if nargin<1 || (ischar(varargin{1}) && length(varargin{1})>1 && varargin{1}(1)=='-'),
0072
0073 [varargin{1:nargin+2}] = deal('init','default',varargin{:});
0074 nnargin=2+nargin;
0075 else,
0076 nnargin=nargin;
0077 end
0078
0079 switch(lower(varargin{1})),
0080 case 'init',
0081 if nnargin>1 && varargin{2}(1)~='-',
0082
0083 sessionname=lower(varargin{2});
0084 else,
0085
0086 sessionname='default';
0087 end
0088
0089
0090 addpath(genpath([fileparts(which(mfilename)),filesep,'fcn']));
0091 addpath(genpath([fileparts(which(mfilename)),filesep,'data']));
0092
0093 SaveFolder=[fileparts(which(mfilename)),filesep,'Sessiondata',filesep,...
0094 'Session_',sessionname,filesep];
0095
0096 if isempty(dir([SaveFolder,mfilename,'.mat'])),
0097
0098 DIVA_data.params=struct(...
0099 'SessionFolder','Sessiondata',...
0100 'SessionTargetFolder','Sessiontargets',...
0101 'TimeStep',.001,...
0102 'PlotStep',25,...
0103 'StorageTime',10,...
0104 'BlockMode',1,...
0105 'Now',1,...
0106 'status','on',...
0107 'Modules',struct(...
0108 'Cochlea',@DIVA_Cochlea,...
0109 'SoundChannel',@DIVA_SoundChannel,...
0110 'VocalTract',@DIVA_VocalTract,...
0111 'SensoryChannel',@DIVA_SensoryChannel,...
0112 'Sensory',@DIVA_Sensory,...
0113 'ForwardModel',@DIVA_ForwardModel,...
0114 'AuditoryCortex',@DIVA_AuditoryCortex,...
0115 'SomatosensoryCortex',@DIVA_SomatosensoryCortex,...
0116 'AuditoryCortexCategorical',@DIVA_AuditoryCortexCategorical,...
0117 'MotorCortex',@DIVA_MotorCortex,...
0118 'SoundMap',@DIVA_SoundMap,...
0119 'ModelStatePlot',@DIVA_ModelStatePlot,...
0120 'GUI',@DIVA_GUI));
0121 else
0122 data=load([SaveFolder,mfilename,'.mat'],'-mat');
0123 DIVA_data=data.params;
0124 end
0125
0126 DIVA_data.params.Nstep=ceil(DIVA_data.params.StorageTime/DIVA_data.params.TimeStep);
0127 DIVA_data.params.timer=timer('TimerFcn',{@DIVA,'step'},...
0128 'Period',DIVA_data.params.TimeStep,...
0129 'ExecutionMode','fixedRate',...
0130 'BusyMode','queue');
0131
0132
0133
0134 DIVA_data.params.QueueStatus=zeros([1,DIVA_data.params.Nstep]);
0135
0136
0137 DIVA_data.params.busy=[0,0];
0138 DIVA_data.params.SessionName=sessionname;
0139
0140 if strcmp(DIVA_data.params.SessionName,'empty'),
0141 DIVA_data.params.Modules=struct('GUI',@DIVA_GUI);
0142 end;
0143
0144 for n1=1:nnargin,
0145 if varargin{n1}(1)=='-',
0146 DIVA_data.params.Modules=rmfield(DIVA_data.params.Modules,varargin{n1}(2:end));
0147 elseif varargin{n1}(1)=='+',
0148 DIVA_data.params.Modules=setfield(DIVA_data.params.Modules,...
0149 varargin{n1}(2:end),...
0150 ['DIVA_',varargin{n1}(2:end)]);
0151 end
0152 end
0153
0154
0155 warning('off','MATLAB:warn_r14_stucture_assignment');
0156 DIVA_data.Modules=DIVA_data.params.Modules;
0157
0158 for fcn=fieldnames(DIVA_data.params.Modules)',
0159 out=feval(DIVA_data.params.Modules.(fcn{1}),'init',sessionname);
0160
0161 DIVA_data.Modules.(fcn{1}).Channels=struct;
0162 for channel=1:length(out),
0163
0164 DIVA_data.Modules.(fcn{1}).Channels.(out{channel})=zeros(0,DIVA_data.params.Nstep);
0165 end
0166
0167 DIVA_data.Modules.(fcn{1}).ChannelsTouch=zeros([length(out),DIVA_data.params.Nstep]);
0168 end
0169
0170
0171 case 'status',
0172 if nnargin<2,
0173 if isempty(DIVA_data),
0174 varargout{1}='off';
0175 else,
0176 varargout{1}=DIVA_data.params.status;
0177 end
0178 else,
0179 DIVA_data.params.status=varargin{2};
0180 end
0181
0182
0183 case 'clear',
0184
0185 DIVA_data.params.busy=[0,0];
0186 DIVA_data.params.Now=1;
0187 fcns=fieldnames(DIVA_data.params.Modules)';
0188 for fcn=fcns,
0189 channels=fieldnames(DIVA_data.Modules.(fcn{1}).Channels)';
0190 for channel=channels,
0191 DIVA_data.Modules.(fcn{1}).Channels.(channel{1})=zeros(0,DIVA_data.params.Nstep);
0192 end
0193 DIVA_data.Modules.(fcn{1}).ChannelsTouch=...
0194 zeros([length(channels),DIVA_data.params.Nstep]);
0195 end
0196 DIVA_data.params.QueueStatus=zeros([1,DIVA_data.params.Nstep]);
0197
0198
0199 case 'reset',
0200
0201
0202 if(nargin==2)
0203 DIVA('AuditoryCortexCategorical','target',varargin{2});
0204 end
0205 matchstart = DIVA('AuditoryCortexCategorical','ntimepoints')*...
0206 DIVA('AuditoryCortexCategorical','match')+1;
0207 matchend=matchstart+DIVA('AuditoryCortexCategorical','ntimepoints')-1;
0208
0209
0210 motorweight=DIVA('MotorCortex','WeightsFromTargets');
0211 motorweight(:,matchstart:matchend)=...
0212 repmat(DIVA('MotorCortex','default_motorSound'),1,...
0213 DIVA('AuditoryCortexCategorical','ntimepoints'));
0214 DIVA('MotorCortex','WeightsFromTargets',motorweight);
0215
0216
0217 somatoweight=DIVA('SomatosensoryCortex','WeightsFromTargets');
0218 somatoweight(:,matchstart:matchend)=...
0219 repmat(DIVA('SomatosensoryCortex','default_somatosensory'),1,...
0220 DIVA('AuditoryCortexCategorical','ntimepoints'));
0221 DIVA('SomatosensoryCortex','WeightsFromTargets',somatoweight);
0222
0223
0224 tmp=DIVA('AuditoryCortexCategorical','AuditoryTargets');
0225 tmp(DIVA('AuditoryCortexCategorical','match')+1).ntrained=0;
0226 DIVA('AuditoryCortexCategorical','AuditoryTargets',tmp);
0227
0228
0229
0230
0231 case 'plot',
0232 if(nargin>1),
0233 idx=varargin{2};
0234 else
0235 idx=DIVA('TimeStep')*(-1000:0);
0236 end
0237
0238 match=DIVA('AuditoryCortexCategorical','match');
0239 au_info=DIVA('AuditoryCortexCategorical','AuditoryTargets');
0240 name=au_info(match+1).label;
0241 ntimepoints=DIVA('AuditoryCortexCategorical','ntimepoints');
0242 aut=DIVA('AuditoryCortex','WeightsFromTargets');
0243 aut=aut(:,match*ntimepoints+1:match*ntimepoints+ntimepoints);
0244 aut_idx=DIVA('AuditoryCortex','target',[],idx);
0245 aut_idx=max(round(aut_idx)-(match*ntimepoints),0);
0246
0247 tmp=ones(size(aut,1),length(aut_idx));
0248 tmp(:,find(aut_idx==0))=NaN;
0249 tmp(:,find(aut_idx~=0))=aut(:,aut_idx(find(aut_idx~=0)));
0250 aut=tmp;
0251 au=DIVA('AuditoryCortex','sound',[],idx);
0252 m=DIVA('VocalTract','motor',[],idx);
0253 s=DIVA('SomatosensoryCortex','somatosensory',[],idx);
0254 dau=DIVA('MotorCortex','error_sound',[],idx);
0255 ds=DIVA('MotorCortex','error_somatosensory',[],idx);
0256
0257 if(nargout),
0258 tmp.sound=au;
0259 tmp.motor=m;
0260 tmp.somatosensory=s;
0261 tmp.error_sound=dau;
0262 tmp.error_somatosensory=ds;
0263 varargout{1}=tmp;
0264 end
0265 figure,
0266 subplot(5,1,1),plot(au','r'),hold on, plot(aut','k');title('Auditory')
0267 subplot(5,1,2),plot(m');title('Motor')
0268 subplot(5,1,3),plot(s');title('Somatosensory')
0269 subplot(5,1,4),plot(dau');title('Auditory Error')
0270 subplot(5,1,5),plot(ds');title('Somatosensory Error')
0271
0272
0273
0274 case 'addmodule',
0275 DIVA_data.params.Modules.(varargin{2})=varargin{3};
0276 out=feval(DIVA_data.params.Modules.(varargin{2}),'init',DIVA_data.params.SessionName);
0277 DIVA_data.Modules.(varargin{2}).Channels=struct;
0278 for channel=1:length(out),
0279 DIVA_data.Modules.(varargin{2}).Channels.(out{channel})=...
0280 zeros(0,DIVA_data.params.Nstep);
0281 end
0282 DIVA_data.Modules.(varargin{2}).ChannelsTouch=...
0283 zeros([length(out),DIVA_data.params.Nstep]);
0284
0285
0286 case 'removemodule',
0287 if ~isfield(DIVA_data.params.Modules,varargin{2}),
0288 warning([mfilename, ' wrong module name ',varargin{2}]);
0289 else,
0290 DIVA(varargin{2},'exit');
0291 DIVA_data.params.Modules=rmfield(DIVA_data.params.Modules,varargin{2});
0292 end
0293
0294
0295 case 'save',
0296 if nnargin>1,
0297 sessionname=lower(varargin{2});
0298 else,
0299 sessionname=DIVA_data.params.SessionName;
0300 end
0301
0302 Folder1=[fileparts(which(mfilename)),filesep];
0303 Folder2=[DIVA_data.params.SessionFolder,filesep];
0304 Folder3=['Session_',sessionname,filesep];
0305 if ~exist([Folder1,Folder2],'dir'),
0306 mkdir(Folder1,Folder2);
0307 end
0308 if ~exist([Folder1,Folder2,Folder3],'dir'),
0309 mkdir([Folder1,Folder2],Folder3);
0310 disp(['Creating Directory : ',Folder1,Folder2,Folder3]);
0311 end
0312 DIVA_data.params.SessionName=sessionname;
0313
0314 DIVA('*','save',sessionname);
0315 params=DIVA_data;
0316 save([Folder1,Folder2,Folder3,mfilename,'.mat'],'params');
0317
0318
0319 case 'exit',
0320 DIVA('status','off');
0321 DIVA('*','exit');
0322 delete(DIVA_data.params.timer);
0323 clear DIVA_data;
0324
0325
0326 case 'disp',
0327 disp(['--------- ','DIVA',' ---------']);
0328 disp(DIVA_data.params);
0329 fcn=fieldnames(DIVA_data.params.Modules);
0330 for n1=1:length(fcn),
0331 disp(['--------- ',fcn{n1},' ---------']);
0332 feval(DIVA_data.params.Modules.(fcn{n1}),'disp');
0333 end
0334
0335
0336 case '*',
0337 fcn=fieldnames(DIVA_data.params.Modules);
0338 for n1=1:length(fcn),
0339 varargout{n1}=feval(DIVA_data.params.Modules.(fcn{n1}),varargin{2:end});
0340 end
0341
0342
0343 case 'simulate',
0344
0345 if nnargin<2,
0346
0347
0348
0349 while any(DIVA_data.params.QueueStatus),
0350 DIVA('step');
0351 end
0352 else,
0353 if strcmpi(varargin{2},'realtime'),
0354 DIVA('start');
0355 else,
0356
0357 for n1=1:ceil(varargin{2}/DIVA_data.params.TimeStep),
0358 DIVA('step');
0359 end
0360 end
0361 end
0362
0363
0364 case 'start'
0365 start(DIVA_data.params.timer);
0366
0367 case 'stop'
0368 stop(DIVA_data.params.timer);
0369
0370 case 'step',
0371 if ~any(DIVA_data.params.busy),
0372 DIVA_data.params.busy(1) = 1;
0373 Now=DIVA_data.params.Now;
0374 NowAndFuture = ...
0375 1 + mod(DIVA_data.params.Now - 1 +...
0376 (0:DIVA_data.params.Nstep -1),...
0377 DIVA_data.params.Nstep);
0378 for fcn=fieldnames(DIVA_data.params.Modules)',
0379
0380 channels = fieldnames(DIVA_data.Modules.(fcn{1}).Channels);
0381 channelsTouch = find(DIVA_data.Modules.(fcn{1}).ChannelsTouch(:,Now));
0382
0383 if length(channelsTouch) > 0,
0384 if DIVA_data.params.BlockMode,
0385
0386 [nill,idx] = min(DIVA_data.Modules.(fcn{1}).ChannelsTouch(:,NowAndFuture),[],2);
0387 idx = 1:min(idx(idx > 1)) - 1;
0388 else,
0389
0390 idx = 1;
0391 end
0392 options = [];
0393
0394 for channel=1:length(channelsTouch),
0395 options{2 * channel - 1} = channels{channelsTouch(channel)};
0396 options{2 * channel} = DIVA_data.Modules.(fcn{1}).Channels.(channels{channelsTouch(channel)})(:,NowAndFuture(idx));
0397 end
0398
0399 feval(DIVA_data.params.Modules.(fcn{1}),options{:});
0400 DIVA_data.Modules.(fcn{1}).ChannelsTouch(:,NowAndFuture(idx)) = 0;
0401 end
0402 end
0403
0404 DIVA_data.params.QueueStatus(Now) = 0;
0405 DIVA_data.params.Now = 1 + mod(DIVA_data.params.Now,DIVA_data.params.Nstep);
0406 DIVA_data.params.busy(1) = 0;
0407 end
0408
0409
0410 otherwise,
0411 if isfield(DIVA_data.params,varargin{1}),
0412 if nnargin < 2,
0413 if nargout > 0,
0414 [varargout{1:nargout}] = DIVA_data.params.(varargin{1});
0415 end
0416 else,
0417 DIVA_data.params.(varargin{1}) = varargin{2};
0418 end
0419 else,
0420 DIVA_data.params.busy(2) = 1;
0421 indexargin = 1;
0422 while indexargin < nnargin,
0423 if isfield(DIVA_data.params.Modules,varargin{indexargin}),
0424 channel=strmatch(varargin{indexargin + 1},...
0425 fieldnames(DIVA_data.Modules.(varargin{indexargin}).Channels),...
0426 'exact');
0427
0428 if length(channel) > 0 && ~nargout,
0429
0430 if nnargin < indexargin + 3,
0431 varargin{indexargin + 3} = 0;
0432 end
0433 Now = 1 + mod(DIVA_data.params.Now - 1 +...
0434 max(1,round(varargin{indexargin+3}/DIVA_data.params.TimeStep))+...
0435 (0:size(varargin{indexargin+2},2)-1),DIVA_data.params.Nstep);
0436 if length(Now)>DIVA_data.params.Nstep, ...
0437 warning(['DIVA: Data too large for queuing. Increase StorageTime in ',...
0438 mfilename]);
0439 end
0440 DIVA_data.Modules.(varargin{indexargin}).Channels.(varargin{indexargin+1})(1:size(varargin{indexargin+2},1),Now) = varargin{indexargin+2};
0441 DIVA_data.Modules.(varargin{indexargin}).ChannelsTouch(channel,Now) = 1;
0442 DIVA_data.params.QueueStatus(Now) = 1;
0443 indexargin=indexargin+4;
0444
0445 elseif length(channel)>0 && isempty(varargin{indexargin+2}),
0446
0447 Now=1+mod(DIVA_data.params.Now-1+...
0448 round(varargin{indexargin+3}/DIVA_data.params.TimeStep),...
0449 DIVA_data.params.Nstep);
0450 if any(varargin{indexargin+3}<-DIVA_data.params.StorageTime),
0451 warning(['DIVA: Delay too long for queue. Increase StorageTime in ',mfilename]);
0452 end
0453 varargout{1} = ...
0454 DIVA_data.Modules.(varargin{indexargin}).Channels.(varargin{indexargin+1})(:,Now);
0455 indexargin=indexargin+4;
0456
0457 elseif ~isempty(DIVA_data.params.Modules.(varargin{indexargin})),
0458
0459 if ~nargout,
0460 feval(DIVA_data.params.Modules.(varargin{indexargin}),...
0461 varargin{indexargin+1:end});
0462 else,
0463 [varargout{1:nargout}]=...
0464 feval(DIVA_data.params.Modules.(varargin{indexargin}),...
0465 varargin{indexargin+1:end});
0466 end
0467 indexargin=nnargin;
0468 end
0469 else,
0470 warning(['warning: ',mfilename,' non-existing module name ',...
0471 varargin{indexargin}]);
0472 indexargin=nnargin;
0473 end
0474 end
0475 DIVA_data.params.busy(2)=0;
0476 end
0477 end
0478