📄 xferplot.m
字号:
% ---------------------------------------------------------------function update_lines_time_multiframe_onechan(block_data, u)% Multiple frames per horiz span% Single channel[nrows,nchans] = size(u);nframes = block_data.params.HorizSpan;y = get(block_data.hline,'YData')';y(1 : nrows*(nframes-1)) = y(nrows+1:nrows*nframes);y(nrows*(nframes-1)+1 : end) = u;set(block_data.hline, 'YData', y);if strcmp(get(block_data.hstem,'vis'),'on'), % using stem plots: ystem = get(block_data.hstem,'ydata'); ystem(1 : 3*nrows*(nframes-1)) = ystem(3*nrows+1:3*nrows*nframes); ystem( 3*nrows*(nframes-1) + (0:length(u)-1)*3 + 2 ) = u; set(block_data.hstem,'ydata',ystem);end% ---------------------------------------------------------------function init_lines_time_multiframe_multichan(block_data, u)% Multiple frames per horiz span% Multiple channels, multiple frames (matrix input)[nrows,nchans] = size(u);nframes = block_data.params.HorizSpan;hline = block_data.hline;% Use the frame counter to determine where we are:% Counter starts at 0, since it is incremented after% update_lines occurs.d = get(block_data.hframenum(2),'userdata');if strcmp(get(block_data.hstem,'vis'),'on'), % using stem plots: % ystem contains "triplets" of data % [y1top y1bottom NaN y2top y2bottom NaN ...] ystem = get(block_data.hstem,'ydata'); % k = indices of (d+1)th frame k = nrows*d+1 : nrows*(d+1); k = (k-1)*3+2; kdn = k-1; ystem(k) = 0; ystem(kdn) = 0; markerpipestr = block_data.params.LineMarkers; for i = 1:nchans, y = get(hline(i),'YData'); val = u(:,i)'; y(d*nrows+1 : (d+1)*nrows) = val; set(hline(i), 'YData', y); if strcmp(get_pipestr(markerpipestr, i,1), 'stem'), ystem(k) = max(ystem(k), val); ystem(kdn) = min(ystem(kdn), val); end end set(block_data.hstem,'ydata',ystem); else for i = 1:nchans, y = get(hline(i),'YData')'; y(d*nrows+1 : (d+1)*nrows, :) = u(:,i); set(hline(i), 'YData', y); endendif (d >= nframes-1), % install non-init update fcn: % Cache the appropriate line-update function: block_data.UpdateLinesFcn = @update_lines_time_multiframe_multichan; ud=get(block_data.hfig,'userdata'); set_param(ud.block,'userdata',block_data);end% ---------------------------------------------------------------function update_lines_time_multiframe_multichan(block_data, u)% Multiple frames per horiz span% Multiple channels, multiple frames (matrix input)[nrows,nchans] = size(u);nframes = block_data.params.HorizSpan;hline = block_data.hline;if strcmp(get(block_data.hstem,'vis'),'on'), % using stem plots: % ystem contains "triplets" of data % [y1top y1bottom NaN y2top y2bottom NaN ...] ystem = get(block_data.hstem,'ydata'); % copy stem values from last (span-1) frames to first (span-1) frames ystem(1 : 3*nrows*(nframes-1)) = ystem(3*nrows+1:end); % k = indices of last frame k = nrows*(nframes-1)+1 : nrows*nframes; k = (k-1)*3+2; kdn = k-1; ystem(k) = 0; ystem(kdn) = 0; markerpipestr = block_data.params.LineMarkers; for i = 1:nchans, y = get(hline(i),'YData'); y(1 : nrows*(nframes-1)) = y(nrows+1:end); val = u(:,i)'; y(nrows*(nframes-1)+1 : end) = val; set(hline(i), 'YData', y); if strcmp(get_pipestr(markerpipestr, i,1), 'stem'), ystem(k) = max(ystem(k), val); ystem(kdn) = min(ystem(kdn), val); end end set(block_data.hstem,'ydata',ystem); else for i = 1:nchans, y = get(hline(i),'YData'); y(1 : nrows*(nframes-1)) = y(nrows+1:end); y(nrows*(nframes-1)+1 : end) = u(:,i); set(hline(i), 'YData', y); endend% ---------------------------------------------------------------function OpenScope(blk)% Open the scope in response to the 'OpenScopeImmediately' dialog% checkbox being pressed.% If scope is already open, bring it forward and return%block_data = get_param(blk,'UserData');if ~isfield(block_data,'hfig'), return; endif ~isempty(block_data.hfig), % Scope exists % Two options: % 1 - Simply bring existing scope forward and return: % figure(block_data.hfig); % 2 - do nothing return; end% Need to open/re-open scope:status = get_param(bdroot(blk),'simulationstatus');isRunning = ~strcmp(status,'stopped');if isRunning, openScopeWhileRunning(blk);end% ---------------------------------------------------------------function openScopeWhileRunning(blk)% Respond to user request to open the scope% (eg, user pressed button in block dialog)%% We must open GUI; thus, we ignore "OpenScopeAtSimStart" setting in dialog% (pass flag=1 to force GUI to open)resetToFirstCall(blk,1);% nothing else to do% scope will re-open at next time step% ---------------------------------------------------------------function resetToFirstCall(blk, mustOpen)% Sets up block and GUI prior to opening the scope%% Resets hfig handle if not present% Sets firstcall flag to either open the gui on the next% time step, or keep it closed, according to the block% parameter "OpenScopeAtSimStart".%% If mustOpen is passed in, the decision to open a GUI% will come from mustOpen instead of the dialog param.block_data = get_param(blk,'UserData');% Determine if scope should open at next time step:if nargin>1, block_data.firstcall = mustOpen;else % NOTE: This is called before params are set into block_data block_data.firstcall = isOn(get_param(blk,'OpenScopeAtSimStart')); % block_data.firstcall = strcmp(block_data.params.OpenScopeAtSimStart,'on');end% Setup empty figure handle if handle not recorded:if ~isfield(block_data,'hfig'), block_data.hfig = [];endset_param(blk,'UserData',block_data);% ---------------------------------------------------------------function startLineEraseMode(blk)% Set channel lines to proper erase mode at start of simulation.% The lines are set to 'normal' mode when a simulation terminates;% when lines redraw over themselves in "xor" mode, dots are left at% peaks without lines connecting to them. This can be visually misleading.block_data = get_param(blk,'UserData');if isOn(block_data.params.Memory), emode='none'; % Memory modeelse emode='xor';endset([block_data.hline(:) ; block_data.hstem(:)], 'EraseMode',emode);set(block_data.hframenum, 'EraseMode','xor');% ---------------------------------------------------------------function terminateLineEraseMode(blk)% Set channel line erase mode at simulation terminationblock_data = get_param(blk,'UserData');% Skip if HG window is closed:if isempty(block_data.hfig), return;endif isOn(block_data.params.Memory), emode='none'; % Memory modeelse emode='normal';endset([block_data.hline(:) ; block_data.hstem(:)], 'EraseMode',emode);set(block_data.hframenum, 'EraseMode','normal');% ---------------------------------------------------------------function first_update(blk, sfcn_blk, u, params)% FIRST_UPDATE Called the first time the update function is executed% in a simulation run. Creates a new scope GUI if it does not exist,% or restarts an existing scope GUI.% blk: masked subsystem block% sfcn_blk: name of s-function block under the masked subsystem% u: one frame of data% Updates block_datablock_data = get_param(blk,'UserData');% Get dimensions of input port of scope block:% Particularly useful for the Spectrum Scope, where % the internal buffering and FFT blocks may change% the signal width without our knowledge:%inBlk = [blk '/In1'];dimsVect = get_param(inBlk,'CompiledPortDimensions');block_data.inputDims = dimsVect.Outport(2:end);% Record input frame time to the input port of the subsystem% (and not the S-fcn itself!)%% NOTE: This is the per-sample time, NOT the per-frame time%ts = get_param(inBlk,'CompiledSampleTime');block_data.Ts = ts(1) ./ block_data.inputDims(1); % ignore sample offset time% Check sample time:% - disallow continuous signals% - allow fixed- and variable-step discreteif ts(1)==0, error('Continuous-time inputs are not supported.');end% Check input data complexity and type:if ~isreal(u) | ~isa(u,'double'), error('Inputs must be real, double-precision values.');end% Construct new scope figure window, or bring up old one:if isfield(block_data,'hfig'), hfig = block_data.hfig; % scope already existselse hfig = []; % scope was never run beforeendif isfield(block_data,'NChans') & (block_data.NChans ~= size(u,2)), % Close the figure if the # of channels has changed % The GUI may need to be reconfigured significantly for % a change in channel count. CloseFigure([],[],blk); hfig=[];end[block_data.samples_per_frame, block_data.NChans] = size(u);set_param(blk, 'UserData', block_data);% Establish a valid scope GUI:if ~isempty(hfig), % Found existing scope figure window: % Prepare to re-start with existing scope window: fig_data = restart_scope(blk, params); % If things did not go well during restart, say the axis % was somehow deleted from the existing scope figure, etc., % then hfig is left empty, and a new scope must be created. % Get hfig, then check if it is empty later: hfig = fig_data.hfig;endif isempty(hfig), % Initialize new figure window: % Create the scope GUI fig_data = create_scope(blk, params, block_data.NChans);end% Get line handle:hline = fig_data.main.hline;hstem = fig_data.main.hstem;hgrid = fig_data.main.hgrid;% Retain the name of the figure window for use when the% block's name changes. Name is retained in S-fcn block's% user-data:block_data.firstcall = 0; % reset "new simulation" flagblock_data.hfig = fig_data.hfig;block_data.params = params;block_data.hcspec = fig_data.hcspec;block_data.haxis = fig_data.main.haxis;block_data.hline = hline;block_data.hstem = hstem;block_data.hgrid = hgrid;block_data.hframenum = fig_data.main.hframenum;block_data.autoscaling = []; % turn off any autoscaling, if in progressif ~isfield(block_data,'hgridtext'), block_data.hgridtext = []; % only exists in block_data, not fig_dataendif ~isfield(block_data,'hlegend'), block_data.hlegend = []; % dittoend% Cache the appropriate line-update function:block_data.UpdateLinesFcn = select_UpdateLinesFcn(block_data);% Set block's user data:set_param(blk, 'UserData', block_data);% The following block callbacks are assumed to be set% in the library block:%% CopyFcn "sdspfscope2([],[],[],'BlockCopy');"% DeleteFcn "sdspfscope2([],[],[],'BlockDelete');"% NameChangeFcn "sdspfscope2([],[],[],'NameChange');"SetMenuChecks(blk); % update state of menu itemssetup_axes(blk); % send one frame of data for axis setupupdate_lines(block_data, u); % one frame of data% ---------------------------------------------------------------function h = getDisableMenuHandles(blk, lineNum)block_data = get_param(blk,'UserData');hfig = block_data.hfig;fig_data = get(hfig,'UserData');h = fig_data.menu.linedisable(:,lineNum);% ---------------------------------------------------------------function h = getMarkerMenuHandlesFromMarker(blk, lineNum, marker)% If marker is empty, we won't find any match% Just return a quick empty:if isempty(marker), h=[]; return;endblock_data = get_param(blk,'UserData');hfig = block_data.hfig;fig_data = get(hfig,'UserData');% Get handles to just one of the options menu line style items.% The context (and other line #) menus simply contain redundant info.% hmenus = fig_data.menu.linemarker; % [options;context] x [line1 line2 ...]hmarkers = get(hmenus(:,lineNum),'child'); % marker menu items for lineNum menu, options/contexthmarkers = cat(2,hmarkers{:}); % matrix of handles: markers x [options context]menuMarkers = get(hmarkers(:,1),'UserData'); % cell array of marker strings just for options menuh = []; % in case no match is foundfor i=1:size(hmarkers,1), if isequal(marker, menuMarkers{i}), % Found a matching marker entry % Return both Options and Context menu handles for % corresponding style entry for line number lineNum h = hmarkers(i,:); return; endend% ---------------------------------------------------------------function h = getStyleMenuHandlesFromStyle(blk, lineNum, style)% If style is empty, we won't find any match% Just return a quick empty:if isempty(style), h=[]; return;endblock_data = get_param(blk,'UserData');hfig = block_data.hfig;fig_data = get(hfig,'UserData');% Get handles to just one of the options menu line style items.% The context (and other line #) menus simply contain redundant info.% hmenus = fig_data.menu.linestyle; % [options;context] x [line1 line2 ...]hstyles = get(hmenus(:,lineNum),'child'); % style menu items for lineNum menu, options/contexthstyles = cat(2,hstyles{:}); % matrix of handles: styles x [options context]menuStyles = get(hstyles(:,1),'UserData'); % cell array of style strings just for options menuh = []; % in case no match is foundfor i=1:size(hstyles,1), if isequal(style, menuStyles{i}), % Found a matching style entry % Return both Options and Context menu handles for % corresponding style entry for line number lineNum h = hstyles(i,:); return; endend
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -