# Designing a band pass filter with modeling toolkit

**URL:** <https://discourse.julialang.org/t/designing-a-band-pass-filter-with-modeling-toolkit/99118>\
**Category:** Modelling & Simulations\
**Tags:** question, package, modelingtoolkit\
**Created:** [May 19, 2023, 2:03pm UTC](https://discourse.julialang.org/t/designing-a-band-pass-filter-with-modeling-toolkit/99118 "2023-05-19T14:03:05Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [May 19, 2023, 2:03pm UTC](https://discourse.julialang.org/t/designing-a-band-pass-filter-with-modeling-toolkit/99118/1 "2023-05-19T14:03:05Z")

</div>

What is the best way to design a band pass filter in the continues domain using modelling toolkit?  
Some hints how to do it in Python: [Butterworth Bandpass — SciPy Cookbook documentation](https://scipy-cookbook.readthedocs.io/items/ButterworthBandpass.html)

Update: OK, I can design a filter with DSP.jl: [Filters - filter design and filtering · DSP.jl](https://docs.juliadsp.org/stable/filters/#Filter-design)

But how would I convert such a filter for use with modeling toolkit?

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [May 19, 2023, 2:26pm UTC](https://discourse.julialang.org/t/designing-a-band-pass-filter-with-modeling-toolkit/99118/2 "2023-05-19T14:26:07Z")

</div>

You can `@symbolic_register` the calls

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [May 19, 2023, 3:18pm UTC](https://discourse.julialang.org/t/designing-a-band-pass-filter-with-modeling-toolkit/99118/3 "2023-05-19T15:18:58Z")

</div>

But a simple second degree band pass filter is just a few differential equations… Why not keep it as symbolic linear equations in modelingtoolkit?

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [May 19, 2023, 3:44pm UTC](https://discourse.julialang.org/t/designing-a-band-pass-filter-with-modeling-toolkit/99118/4 "2023-05-19T15:44:21Z")

</div>

You can design the filter using DSP.jl, convert it to a transfer function from ControlSystemsBase, convert that to a statespace system and then use ControlSystemsMTK to convert that to an ODE system. Make sure to perform balancing on the statespace system using `balance_statespace` before converting it to an ODESystem.

Here’s an unfinished PR that adds an interface between DSP and ControlSystems

> <https://github.com/JuliaControl/ControlSystems.jl/pull/489/files>
>
> needs more tests

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [May 19, 2023, 4:03pm UTC](https://discourse.julialang.org/t/designing-a-band-pass-filter-with-modeling-toolkit/99118/5 "2023-05-19T16:03:11Z")

</div>

It would probably be worth adding to the standard library if someone’s up for it.

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [May 22, 2023, 6:51am UTC](https://discourse.julialang.org/t/designing-a-band-pass-filter-with-modeling-toolkit/99118/6 "2023-05-22T06:51:49Z")

</div>

Before doing analog filter design with DSP, beware of [analogfilter design seems to be broken · Issue #341 · JuliaDSP/DSP.jl · GitHub](https://github.com/JuliaDSP/DSP.jl/issues/341)  
TLDR; analog filter design is quite broken in DSP but the problem can be worked around.

Having said that, here’s how you can convert a filter to an MTK system with the PR [#843](https://github.com/JuliaControl/ControlSystems.jl/pull/843)

```julia
using DSP, ControlSystemsBase

# Digital filter
fs = 100
df = digitalfilter(Bandpass(5, 10; fs), Butterworth(2))
G = tf(df, 1/fs)
bodeplot(G, xscale=:identity, yscale=:identity, hz=true)

# Analog filter
af = analogfilter(Bandpass(0.05, 0.30), Butterworth(2))
G = tf(af)
bodeplot(G, xscale=:identity, yscale=:identity, hz=true)

# Convert to statespace for simulation with MTK
sys = ss(G) # This performs numerical scaling automatically

using ControlSystemsMTK
odesys = ODESystem(sys; name=:filter)

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/9/0/9077561cf79764307c5209bd49f1cf82e1ba07bf.png)

The resulting `odesys` will have connectors `input::RealInput` and `output::RealOutput` from ModelingToolkitStandardLibrary.
