Home > . > h2asq.m

h2asq

PURPOSE ^

H2ASQ - produce a stable linear filter that, applied to strain h,

SYNOPSIS ^

function [b,a] = h2asq(fname,nb,na,woff)

DESCRIPTION ^

 H2ASQ - produce a stable linear filter that, applied to strain h,
 produces AS_Q counts

 [b,a] = h2asq(fname,nb,na,woff)

 fname   file containing frequency, in-phase and quadrature phase
         components from, e.g., swept sine calibration, representing the 
         ratio of the excitation (e.g., ETMX) at that frequency to the AS_Q
         excitation
 nb, na  filter order
 woff    invfreqz produces warnings of poorly conditioned matrices, though
         it does appear to give acceptable results. Setting woff to a
         non-zero value turns off the warning messages. This is here
         because the user should know they are turning-off this warning!
 
 b, a    transfer function s.t. asq = filter(b,a,h);

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function [b,a] = h2asq(fname,nb,na,woff)
0002 % H2ASQ - produce a stable linear filter that, applied to strain h,
0003 % produces AS_Q counts
0004 %
0005 % [b,a] = h2asq(fname,nb,na,woff)
0006 %
0007 % fname   file containing frequency, in-phase and quadrature phase
0008 %         components from, e.g., swept sine calibration, representing the
0009 %         ratio of the excitation (e.g., ETMX) at that frequency to the AS_Q
0010 %         excitation
0011 % nb, na  filter order
0012 % woff    invfreqz produces warnings of poorly conditioned matrices, though
0013 %         it does appear to give acceptable results. Setting woff to a
0014 %         non-zero value turns off the warning messages. This is here
0015 %         because the user should know they are turning-off this warning!
0016 %
0017 % b, a    transfer function s.t. asq = filter(b,a,h);
0018 
0019 % $Id: h2asq.m,v 1.1 2003/09/24 18:59:13 lsf Exp $
0020 % based on Landry's code to produce AS_Q to strain filters
0021 
0022 % Deal with warning message
0023 if (nargin == 4)
0024   if (~isempty(woff))
0025     if (woff ~= 0)
0026       warning off MATLAB:nearlySingularMatrix;
0027     end
0028   end
0029 end
0030 
0031 % Read data file containing frequency, response information
0032 % Each line contains three numbers:
0033 %   frequency (Hz)
0034 %   in-phase component of ratio AS_Q/ETMX
0035 %   quad-phase component of ratio AS_Q/ETMX
0036 [f, Re, Im]=textread(fname,'%f %f %f');
0037 fs = 16384;                % sampling frequency (Hz)
0038 w = 2*pi*f;                % frequency in radians
0039 cr = Re + i*Im;            % complex ratio AS_Q/ETMX;
0040 
0041 
0042 % find transfer function H(z) = B(z)/A(z) s.t. H(exp(2*pi*i*f/fs)) is equal
0043 % to Re + i*Im at each f
0044 % Emphasis to give each frequency in fitting the transfer function
0045 % Landry gives extra emphasis to frequencies in range [40,81] Hz.
0046 % LSF finds that we need to put more emphasis on frequencies in the
0047 % >400 Hz range to get a good fit in the gw band.
0048 wt = ones(size(cr));
0049 %wt(find(40 < f & f < 81)) = 1.3;
0050 wt(find(400 < f)) = 1.5;
0051 % Note: this use of invfreqz guaranteed to produce stable filter
0052 iter = 10*length(f);       % number of iterations for filter finding
0053 [b,a] = invfreqz(cr,w/fs,nb,na,wt,iter,[]);
0054 %[b,a] = invfreqs(cr,w,nb,na,wt,iter);
0055 
0056 % compare
0057 [h,w] = freqz(b,a,w/fs);
0058 subplot(2,1,1);
0059 semilogx(f,20*log10(abs(cr)),f,20*log10(abs(h)));
0060 title(sprintf('[nb, na] = [%d, %d]',nb, na));
0061 legend('Input data','Approx filter');
0062 ylabel('dB');
0063 grid;
0064 subplot(2,1,2);
0065 semilogx(f,abs(h)./abs(cr));
0066 v = axis;
0067 v(3:4) = [1/2,2];
0068 axis(v);
0069 xlabel('Frequency (Hz)');
0070 ylabel('Ratio approx/actual');
0071 grid;
0072 
0073 % convert to zpg filter
0074 [zz,pp,kk]=tf2zp(b,a);
0075 
0076 % add two poles to *excitation* so that excitation becomes strain
0077 % Because H is AS_Q/EXC, this is adding two zeros to H
0078 % Frequency of pendulum is so low compared to Nyquist that we don't need to
0079 % worry the difference between discrete, continuous filter
0080 zz = [zz(:); 2*pi*(0.076 + 0.76i)/fs; 2*pi*(0.076 - 0.76i)/fs];
0081 
0082 % now go back to transfer function form
0083 [b,a] = zp2tf(zz,pp,kk);
0084 
0085 % we be done
0086 return

Generated on Thu 12-May-2005 11:48:48 by m2html © 2003