www.gusucode.com > 利用MATLAB GUI设计滤波器界面,可以设计IIR滤波器 > AFD/GuiPlotUserData.m
function varargout = GuiPlotUserData(varargin) % GUIPLOTUSERDATA M-file for GuiPlotUserData.fig % GUIPLOTUSERDATA, by itself, creates a new GUIPLOTUSERDATA or raises the existing % singleton*. % % H = GUIPLOTUSERDATA returns the handle to a new GUIPLOTUSERDATA or the handle to % the existing singleton*. % % GUIPLOTUSERDATA('CALLBACK',hObject,eventData,handles,...) calls the local % function named CALLBACK in GUIPLOTUSERDATA.M with the given input arguments. % % GUIPLOTUSERDATA('Property','Value',...) creates a new GUIPLOTUSERDATA or raises the % existing singleton*. Starting from the left, property value pairs are % applied to the GUI before GuiPlotUserData_OpeningFunction gets called. An % unrecognized property name or invalid value makes property application % stop. All inputs are passed to GuiPlotUserData_OpeningFcn via varargin. % % *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one % instance to run (singleton)". % % See also: GUIDE, GUIDATA, GUIHANDLES % Edit the above text to modify the response to help GuiPlotUserData % Last Modified by GUIDE v2.5 17-Jan-2004 16:25:43 % Begin initialization code - DO NOT EDIT gui_Singleton = 1; gui_State = struct('gui_Name', mfilename, ... 'gui_Singleton', gui_Singleton, ... 'gui_OpeningFcn', @GuiPlotUserData_OpeningFcn, ... 'gui_OutputFcn', @GuiPlotUserData_OutputFcn, ... 'gui_LayoutFcn', [] , ... 'gui_Callback', []); if nargin & isstr(varargin{1}) gui_State.gui_Callback = str2func(varargin{1}); end if nargout [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); else gui_mainfcn(gui_State, varargin{:}); end % End initialization code - DO NOT EDIT % --- Executes just before GuiPlotUserData is made visible. function GuiPlotUserData_OpeningFcn(hObject, eventdata, handles, varargin) global strFilterObject % Load data if isempty(strFilterObject) temp=load('matlab'); disp([mfilename ' called in debug mode using matlab.mat datafile']) strFilterObject = temp.strFilterObject; else strFilterObject=Utility_zpk(strFilterObject); % find poles, zeros end set(handles.uiFilterUserData,'Name',strFilterObject.sTitle) % Initialize the GUI widgets and variables handles = Initialize(handles); % Calculate and plot CalculateAndPlot(handles); % Save handles data in figure guidata(hObject, handles); function varargout = GuiPlotUserData_OutputFcn(hObject, eventdata, handles) return %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Initialize %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function handles = Initialize(handles) global strFilterObject % initialize the Data box fC = strFilterObject.fFc; NSamples = 1001; % samples in the datafile NPeriods = 10; % periods of the waveform fSample = fC*(NSamples-1)/NPeriods; handles.fSample = fSample; handles.xData = sin(linspace(0,NPeriods*2*pi,NSamples)); set(handles.uitxData,'String',['Default ' Utility_EngOutput(fC,'Hz',4) ' sinusoid']) [sMan,fExp]=Utility_EngOutput(fSample,'',4,-3,6); set(handles.uiebData,'String',sMan) set(handles.uipmData,'Value',(fExp/3)+2) % initialize the Time box sTMin = '0'; TMax = (NSamples-1)/fSample; sTMax=Utility_EngOutput(TMax,'s'); [sTMax,sTUnit]=strtok(sTMax,' '); sTUnit(1) = []; set(handles.uiebTMin,'String',sTMin) set(handles.uitxTMin,'String',[sTUnit ' or "default"']) set(handles.uiebTMax,'String',sTMax) set(handles.uitxTMax,'String',[sTUnit ' or "default"']) % initialize the PSD box fFMax = fSample/2; sFMax=Utility_EngOutput(fFMax,'Hz'); [sFMax,sFUnit]=strtok(sFMax,' '); sFUnit(1) = []; set(handles.uiebFMin,'String','0') set(handles.uitxFMin,'String',[sFUnit ' or "default"']) set(handles.uiebFMax,'String',sFMax) set(handles.uitxFMax,'String',[sFUnit ' or "default"']) set(handles.uirbPSDLin,'Value',1) set(handles.uirbPSDdB,'Value',0) set(handles.uirbFLin,'Value',1) set(handles.uirbFLog,'Value',0) % initialize the show box set(handles.uicbUnfiltered,'Value',1) set(handles.uirbFilteredIdeal,'Value',1) set(handles.uirbFilteredStandard,'Value',0) if isempty(strFilterObject.fK1) set(handles.uirbFilteredStandard,'Enable','off') set(handles.uitxShowStandard,'Enable','off') end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % CalculateAndPlot %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function CalculateAndPlot(handles) global strFilterObject % Data box fSample = handles.fSample; xData = handles.xData; tData = linspace(0,(length(xData)-1)/fSample,length(xData)); % Time box tScale = GetScale(get(handles.uitxTMin,'String')); tMin = str2num(get(handles.uiebTMin,'String'))*tScale; tMax = str2num(get(handles.uiebTMax,'String'))*tScale; % PSD box fScale = GetScale(get(handles.uitxFMax,'String')); fMin = str2num(get(handles.uiebFMin,'String'))*fScale; fMax = str2num(get(handles.uiebFMax,'String'))*fScale; bIsPSDLinear = get(handles.uirbPSDLin,'Value'); bIsFreqLinear = get(handles.uirbFLin,'Value'); % Show box bShowX = get(handles.uicbUnfiltered,'Value'); bShowY = get(handles.uirbFilteredIdeal,'Value'); bShowY1 = get(handles.uirbFilteredStandard,'Value'); % Time axis axes(handles.uiaxTime) [dummy,strXLabel]=strtok(Utility_EngOutput(tMax,1,'s'),' '); strXLabel(1)=[]; [dummy,exponent]=Utility_EngOutput(tMax); tScale = 10^exponent; cla, hold on xlabel(strXLabel) sWarn = ''; if bShowX plot(tData/tScale,xData,'b'); end if bShowY z = strFilterObject.vZeros; p = strFilterObject.vPoles; k = strFilterObject.fK; [yData,sWarn] = LinearFilter(z,p,k,xData,tData); plot(tData/tScale,yData,'g') end if bShowY1 z1 = strFilterObject.vZeros1; p1 = strFilterObject.vPoles1; k1 = strFilterObject.fK1; [yData1,sWarn] = LinearFilter(z1,p1,k1,xData,tData); plot(tData/tScale,yData1,'Color',[0.5 0 0]) end v = axis; v(1) = str2num(get(handles.uiebTMin,'String')); v(2) = str2num(get(handles.uiebTMax,'String')); axis(v) set(handles.uiaxTime,'YLimMode','auto') % PSD axis axes(handles.uiaxPSD) cla, hold on % setup axis if bIsFreqLinear [dummy,strXLabel]=strtok(Utility_EngOutput(fMax,1,'Hz'),' '); strXLabel(1)=[]; xlabel(strXLabel) [dummy,exponent]=Utility_EngOutput(fMax); fScale = 10^exponent; else xlabel('Hz') fScale = 1; end if bShowX [XData,f] = MyPSD(xData,fSample); if ~bIsPSDLinear, XData = 10*log10(XData); end plot(f/fScale,XData,'b') end if bShowY [YData,f] = MyPSD(yData,fSample); if ~bIsPSDLinear, YData = 10*log10(YData); end plot(f/fScale,YData,'Color',[0 0.5 0]) end if bShowY1 [YData1,f] = MyPSD(yData1,fSample); if ~bIsPSDLinear, YData1 = 10*log10(YData1); end plot(f/fScale,YData1,'Color',[0.5 0 0]) end if bIsFreqLinear set(handles.uiaxPSD,'XScale','linear') set(handles.uiaxPSD,'XLimMode','auto') else set(handles.uiaxPSD,'XScale','log') set(handles.uiaxPSD,'XLimMode','auto') end if bIsPSDLinear ylabel('Power (linear)') else ylabel('Power (dB)') end v = axis; if bIsFreqLinear fScale = 1; else [dummy,exponent]=Utility_EngOutput(fMax); fScale = 10^exponent; end v(1) = str2num(get(handles.uiebFMin,'String'))*fScale; v(2) = str2num(get(handles.uiebFMax,'String'))*fScale; axis(v) set(handles.uiaxPSD,'YLimMode','auto') if ~isempty(sWarn) warndlg(sWarn,'Warning') end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Data Box Callbacks %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function uipbData_Callback(hObject, eventdata, handles) if exist('handles.sPathName') cd(handles.sPathName) end [sFileName, sPathName] = uigetfile('*.txt','Open user data file'); bGoodData = 0; if sFileName fid = fopen([sPathName sFileName],'rt'); % process first line; look for sample frquency information line1 = fgetl(fid); xData = []; fSample = []; if findstr(lower(line1),'sample') fSample = str2num(strtok(line1)); if isempty(fSample) str1 = 'File format incorrect. '; str2 = 'The first row may either have the first sample alone, or it may have '; str3 = 'the first sample followed by a space and the words "sample frequency".'; errordlg([str1 str2 str3],'Error') else bGoodData = 1; end end while 1 curLine = fgetl(fid); if ~ischar(curLine), break, end % end of file reached curNum = str2num(curLine); if isempty(curNum) || prod(size(curNum)) ~= 1 str1 = 'File format incorrect. '; str2 = 'The file must have a single column of numbers and be in ASCII format.'; errordlg([str1 str2],'Error') bGoodData = 0; break else xData = [xData; curNum]; bGoodData = 1; end end fclose(fid); if ~bGoodData, return, end if ~isempty(fSample) handles.fSample = fSample; % update the data box sample frequency widgets [sMan,fExp]=Utility_EngOutput(fSample,'',4,-3,6); set(handles.uiebData,'String',sMan) set(handles.uipmData,'Value',(fExp/3)+2) % update the PSD box frequency labels fFMax = fSample/2; sFMax=Utility_EngOutput(fFMax,'Hz'); [sFMax,sFUnit]=strtok(sFMax,' '); sFUnit(1) = []; set(handles.uiebFMin,'String','0') set(handles.uitxFMin,'String',[sFUnit ' or "default"']) set(handles.uiebFMax,'String',sFMax) set(handles.uitxFMax,'String',[sFUnit ' or "default"']) set(handles.uirbPSDLin,'Value',1) set(handles.uirbPSDdB,'Value',0) set(handles.uirbFLin,'Value',1) set(handles.uirbFLog,'Value',0) end handles.xData = xData; set(handles.uitxData,'String',sFileName) % initialize the Time box sTMin = '0'; NSamples = length(xData); fSample = handles.fSample; TMax = (NSamples-1)/fSample; sTMax=Utility_EngOutput(TMax,'s'); [sTMax,sTUnit]=strtok(sTMax,' '); sTUnit(1) = []; set(handles.uiebTMin,'String',sTMin); set(handles.uitxTMin,'String',[sTUnit ' or "default"']); set(handles.uiebTMax,'String',sTMax); set(handles.uitxTMax,'String',[sTUnit ' or "default"']); handles.sPathName = sPathName; guidata(hObject, handles); CalculateAndPlot(handles) end function uiebData_Callback(hObject, eventdata, handles) oldFSample = handles.fSample; sSample = get(handles.uiebData,'String'); fSample = str2num(sSample); if isempty(fSample) || fSample < 0 set(handles.uiebData,'String',num2str(handles.fSample)) else handles.fSample = fSample * 10^((get(handles.uipmData,'Value')-2)*3); guidata(hObject, handles); end % initialize the Time box sTMin = '0'; NSamples = length(handles.xData); fSample = handles.fSample; TMax = (NSamples-1)/fSample; sTMax=Utility_EngOutput(TMax,'s'); [sTMax,sTUnit]=strtok(sTMax,' '); sTUnit(1) = []; set(handles.uiebTMin,'String',sTMin); set(handles.uitxTMin,'String',[sTUnit ' or "default"']); set(handles.uiebTMax,'String',sTMax); set(handles.uitxTMax,'String',[sTUnit ' or "default"']); % initialize the PSD box fFMax = fSample/2; sFMax=Utility_EngOutput(fFMax,'Hz'); [sFMax,sFUnit]=strtok(sFMax,' '); sFUnit(1) = []; set(handles.uiebFMin,'String','0') set(handles.uitxFMin,'String',[sFUnit ' or "default"']) set(handles.uiebFMax,'String',sFMax) set(handles.uitxFMax,'String',[sFUnit ' or "default"']) % Make sure if using default data set that it no longer says what freq str = get(handles.uitxData,'String'); [str1,str]=strtok(str); if findstr(str1,'Default') [str2,str]=strtok(str); [str3,str]=strtok(str); OldFreq = str2num(str2)*GetScale(str3); newFreq = OldFreq * fSample/oldFSample; sNewFreq = Utility_EngOutput(newFreq,'Hz'); set(handles.uitxData,'String',['Default ' sNewFreq ' sinusoid']) end % save fSample guidata(hObject, handles); CalculateAndPlot(handles) function uipmData_Callback(hObject, eventdata, handles) uiebData_Callback(hObject, eventdata, handles) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Time Box Callbacks %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function uiebTMin_Callback(hObject, eventdata, handles) sTMin = get(hObject,'String'); if findstr('default',lower(sTMin)) sTMin = '0'; set(hObject,'String',sTMin); end fTMin = str2num(sTMin); if isempty(fTMin) errordlg('Enter the minimum time to plot or "default"','Error') set(hObject,'String','0') elseif fTMin >= str2num(get(handles.uiebTMax,'String')) errordlg('Minimum time to plot must be less than the maximum time to plot','Error') set(hObject,'String','0'); elseif fTMin < 0 errordlg('Minimum time to plot cannot be negative','Error') set(hObject,'String','0'); else CalculateAndPlot(handles) end function uiebTMax_Callback(hObject, eventdata, handles) tScale = GetScale(get(handles.uitxTMax,'String')); tDefault = (length(handles.xData)-1)/handles.fSample/tScale; sTMax = get(hObject,'String'); if findstr('default',lower(sTMax)) sTMax = num2str(tDefault); set(handles.uiebTMax,'String',sTMax) end fTMax = str2num(sTMax); if isempty(fTMax) errordlg('Enter the maximum time to plot or "default"','Error') set(hObject,'String',num2str(tDefault)) elseif fTMax <= str2num(get(handles.uiebTMin,'String')) errordlg('Maximum time to plot must be greater the minimum time to plot','Error') set(hObject,'String',num2str(tDefault)) elseif fTMax > tDefault errordlg('Cannot plot longer than the length of the data. Resetting to length of data.','Error') set(hObject,'String',num2str(tDefault)) else % everything checks OK % rescale things (e.g. from ms into us if a short time is chosen) realTMin = str2num(get(handles.uiebTMin,'String'))*tScale; realTMax = str2num(get(handles.uiebTMax,'String'))*tScale; sTMax=Utility_EngOutput(realTMax,'s'); [sTMax,sTUnit]=strtok(sTMax,' '); sTUnit(1) = []; sTMin = realTMin * GetScale(sTUnit); set(handles.uiebTMin,'String',sTMin); set(handles.uitxTMin,'String',[sTUnit ' or "default"']); set(handles.uiebTMax,'String',sTMax); set(handles.uitxTMax,'String',[sTUnit ' or "default"']); % do the work CalculateAndPlot(handles) end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % PSD Box Callbacks %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function uiebFMin_Callback(hObject, eventdata, handles) global strFilterObject bIsLog = get(handles.uirbFLog,'Value'); if bIsLog fScale = GetScale(get(handles.uitxFMin,'String')); fDefault = strFilterObject.fFc/100/fScale; else fDefault = 0; end sFMin = get(hObject,'String'); if findstr('default',lower(sFMin)) sFMin = num2str(fDefault); set(hObject,'String',sFMin) end fFMin = str2num(sFMin); if isempty(fFMin) errordlg('Enter the minimum frequency to plot or "default"','Error') set(hObject,'String',num2str(fDefault)) elseif fFMin >= str2num(get(handles.uiebFMax,'String')) errordlg('Minimum frequency to plot must be less than the maximum frequency to plot','Error') set(hObject,'String',num2str(fDefault)) elseif fFMin < 0 errordlg('Minimum frequency to plot cannot be negative','Error') set(hObject,'String',num2str(fDefault)) elseif fFMin==0 & bIsLog errordlg('Minimum frequency to plot must be greater than zero if log frequency scale is selected','Error') set(hObject,'String',num2str(fDefault)) else CalculateAndPlot(handles) end function uiebFMax_Callback(hObject, eventdata, handles) fScale = GetScale(get(handles.uitxFMax,'String')); fDefault = handles.fSample/2/fScale; sFMax = get(hObject,'String'); if findstr('default',lower(sFMax)) sFMax = num2str(fDefault); set(handles.uiebFMax,'String',sFMax) end fFMax = str2num(sFMax); if isempty(fFMax) errordlg('Enter the maximum frequency to plot or "default"','Error') set(hObject,'String',num2str(fDefault)) elseif fFMax <= str2num(get(handles.uiebFMin,'String')) errordlg('Maximum frequency to plot must be greater the minimum frequency to plot','Error') set(hObject,'String',num2str(fDefault)) elseif fFMax > fDefault errordlg('Cannot plot higher frequencies than half of the data sampling frequency','Error') set(hObject,'String',num2str(fDefault)) else % rescale things (e.g. from MHz into kHz if a short frequency is chosen) realFMin = str2num(get(handles.uiebFMin,'String'))*fScale; realFMax = str2num(get(handles.uiebFMax,'String'))*fScale; sFMax=Utility_EngOutput(realFMax,'Hz'); [sFMax,sFUnit]=strtok(sFMax,' '); sFUnit(1) = []; sFMin = realFMin / GetScale(sFUnit); set(handles.uiebFMin,'String',sFMin); set(handles.uitxFMin,'String',[sFUnit ' or "default"']); set(handles.uiebFMax,'String',sFMax); set(handles.uitxFMax,'String',[sFUnit ' or "default"']); % do the work CalculateAndPlot(handles) end function uirbPSDLin_Callback(hObject, eventdata, handles) if get(hObject,'Value') == 1 set(handles.uirbPSDdB, 'Value', 0); set(handles.uitxPSDTitle,'String','Power Spectral Density') CalculateAndPlot(handles) else set(hObject,'Value',1) end function uirbPSDdB_Callback(hObject, eventdata, handles) if get(hObject,'Value') == 1 set(handles.uirbPSDLin, 'Value', 0); set(handles.uitxPSDTitle,'String','Power Spectral Density (dB)') CalculateAndPlot(handles) else set(hObject,'Value',1) end function uirbFLin_Callback(hObject, eventdata, handles) if get(hObject,'Value') == 1 set(handles.uirbFLog, 'Value', 0); set(handles.uiebFMin,'String','0') CalculateAndPlot(handles) else set(hObject,'Value',1) end function uiFLog_Callback(hObject, eventdata, handles) if get(hObject,'Value') == 1 global strFilterObject set(handles.uirbFLin, 'Value', 0); % make sure the min frequency is above zero and less than the max frequency fScale = GetScale(get(handles.uitxFMin,'String')); fDefault = strFilterObject.fFc/100/fScale; fMax = str2num(get(handles.uiebFMax,'String')); fMin = min(fDefault,fMax/100); fMin = max(fMin,str2num(get(handles.uiebFMin,'String'))); set(handles.uiebFMin,'String',num2str(fMin)) CalculateAndPlot(handles) else set(hObject,'Value',1) end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Show Box Callbacks %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function uicbUnfiltered_Callback(hObject, eventdata, handles) CalculateAndPlot(handles) function uirbFilteredIdeal_Callback(hObject, eventdata, handles) CalculateAndPlot(handles) function uirbFilteredStandard_Callback(hObject, eventdata, handles) CalculateAndPlot(handles) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Helper Functions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function [y,sWarning]=LinearFilter(z,p,k,u,t) % zpk defines the continuous time filter, u the input, t the time vector u=u(:); [a,b,c,d]=Utility_zpk2ss(z,p,k); % convert to ct ss representation nx = size(a,1); % check for adequate sampling time ts = t(2)-t(1); % sampling time nf = pi/ts; r = p(imag(p)>0 & abs(real(p))<0.2*abs(p)); % resonant modes mf = max(abs(r)); % frequency of fastest resonant mode sWarning=''; if mf>pi/(ts*2) [ff,ee] = log2(pi/2/mf); fMinSample=Utility_EngOutput(1/pow2(ee-1),3,'Hz'); sWarning=sprintf('Input signal is undersampled. Sample at %s or faster.',fMinSample ); end % convert from ct to dt M = [a, b, zeros(nx,1); zeros(1,nx+1), 1/ts ; zeros(1,nx+2)]; s = expm(M*ts); f1 = s(1:nx,nx+1:nx+1); f2 = s(1:nx,nx+2:nx+2); gic = [eye(nx) , -f2]; %DT initial conditions ad = s(1:nx,1:nx); bd = f1 + ad*f2 - f2; cd = c; dd = d + c*f2; % Find time response y x0 = zeros(nx,1); % initial conditions in CT z0 = gic * [x0 ; u(1)]; % initial conditions in DT z = ltitr(ad,bd,u,z0); y = z * cd.' + u * dd.'; function [X, f] = MyPSD(x,Fs) n = length(x); % Number of data points window = hanning(n); x = x(:); xw = window.*(x); Xx = abs(fft(xw,n)).^2; % Select first half if rem(n,2), % nfft odd select = (1:(n+1)/2)'; else select = (1:n/2+1)'; end Xx = Xx(select); X = Xx/norm(window)^2; % normalize f = (select - 1)*Fs/n; function scale = GetScale(stringIn) switch stringIn(1) case 'f', scale = 1e-15; case 'p', scale = 1e-12; case 'n', scale = 1e-9; case 'u', scale = 1e-6; case 'm', scale = 1e-3; case 'k', scale = 1e3; case 'M', scale = 1e6; case 'G', scale = 1e9; otherwise, scale = 1; end