#' % FIR filter design with Python and SciPy
#' % Matti Pastell
#' % 15th April 2013

#' # Introduction

#' This an example of a script that can be published using
#' [Pweave](http://mpastell.com/pweave). The script can be executed
#' normally using Python or published to HTML with Pweave
#' Text is written in markdown in lines starting with "`#'` " and code
#' is executed and results are included in the published document.
#' The concept is similar to
#' publishing documents with [MATLAB](http://mathworks.com) or using
#' stitch with [Knitr](http://http://yihui.name/knitr/demo/stitch/).

#' Notice that you don't need to define chunk options (see
#' [Pweave docs](http://mpastell.com/pweave/usage.html#code-chunk-options)
#' ),
#' but you do need one line of whitespace between text and code.
#' If you want to define options you can do it on using a line starting with
#' `#+`. just before code e.g. `#+ term=True, caption='Fancy plots.'`. 
#' If you're viewing the HTML version have a look at the
#' [source](FIR_design.py) to see the markup.

#' The code and text below comes mostly
#' from my blog post [FIR design with SciPy](http://mpastell.com/2010/01/18/fir-with-scipy/),
#' but I've updated it to reflect new features in SciPy. 

#' # FIR Filter Design

#' We'll implement lowpass, highpass and ' bandpass FIR filters. If
#' you want to read more about DSP I highly recommend [The Scientist
#' and Engineer's Guide to Digital Signal
#' Processing](http://www.dspguide.com/) which is freely available
#' online.

#' ## Functions for frequency, phase, impulse and step response

#' Let's first define functions to plot filter
#' properties.

from pylab import *
import scipy.signal as signal
    
#Plot frequency and phase response
def mfreqz(b,a=1):
    w,h = signal.freqz(b,a)
    h_dB = 20 * log10 (abs(h))
    subplot(211)
    plot(w/max(w),h_dB)
    ylim(-150, 5)
    ylabel('Magnitude (db)')
    xlabel(r'Normalized Frequency (x$\pi$rad/sample)')
    title(r'Frequency response')
    subplot(212)
    h_Phase = unwrap(arctan2(imag(h),real(h)))
    plot(w/max(w),h_Phase)
    ylabel('Phase (radians)')
    xlabel(r'Normalized Frequency (x$\pi$rad/sample)')
    title(r'Phase response')
    subplots_adjust(hspace=0.5)

#Plot step and impulse response
def impz(b,a=1):
    l = len(b)
    impulse = repeat(0.,l); impulse[0] =1.
    x = arange(0,l)
    response = signal.lfilter(b,a,impulse)
    subplot(211)
    stem(x, response)
    ylabel('Amplitude')
    xlabel(r'n (samples)')
    title(r'Impulse response')
    subplot(212)
    step = cumsum(response)
    stem(x, step)
    ylabel('Amplitude')
    xlabel(r'n (samples)')
    title(r'Step response')
    subplots_adjust(hspace=0.5)

#' ## Lowpass FIR filter

#' Designing a lowpass FIR filter is very simple to do with SciPy, all you
#' need to do is to define the window length, cut off frequency and the
#' window.

#' The Hamming window is defined as:
#' $w(n) = \alpha - \beta\cos\frac{2\pi n}{N-1}$, where $\alpha=0.54$ and $\beta=0.46$ 

#' The next code chunk is executed in term mode, see the [Python script](FIR_design.py) for syntax.
#' Notice also that Pweave can now catch multiple figures/code chunk.

#+ term=True
n = 61
a = signal.firwin(n, cutoff = 0.3, window = "hamming")
#Frequency and phase response
mfreqz(a)
show()
#Impulse and step response
figure(2)
impz(a)
show()


#' ## Highpass FIR Filter

#' Let's define a highpass FIR filter, if you compare to original blog
#' post you'll notice that it has become easier since 2009. You don't
#' need to do ' spectral inversion "manually" anymore!

n = 101
a = signal.firwin(n, cutoff = 0.3, window = "hanning", pass_zero=False)
mfreqz(a)
show()

#' ## Bandpass FIR filter

#' Notice that the plot has a caption defined in code chunk options.

#+ caption = "Bandpass FIR filter."
n = 1001
a = signal.firwin(n, cutoff = [0.2, 0.5], window = 'blackmanharris', pass_zero = False)
mfreqz(a)
show()



