In GNU Radio, “2nd order baseline flattening” isn’t a single built-in block—you implement it by estimating a quadratic trend and subtracting it from your signal.
Here are the practical ways to do it in a flowgraph. Note this has not been tested, so I provide no guarentee that it will work!
🔧 Method 1: Python Block (most flexible — recommended)
You fit and remove a 2nd-order polynomial in real time.
Steps
- Add a Stream to Vector block
- Set vector length (e.g. 1024 or 4096 samples)
- Add a Python Block to:
- Fit a quadratic
- Subtract it
Example Python code
import numpy as np
from gnuradio import gr
class blk(gr.sync_block):
def __init__(self, vlen=1024):
gr.sync_block.__init__(
self,
name="2nd_order_baseline_removal",
in_sig=[(np.float32, vlen)],
out_sig=[(np.float32, vlen)]
)
self.vlen = vlen
def work(self, input_items, output_items):
x = np.arange(self.vlen)
for i in range(len(input_items[0])):
y = input_items[0][i]
# Fit 2nd order polynomial
coeffs = np.polyfit(x, y, 2)
baseline = np.polyval(coeffs, x)
# Subtract baseline
output_items[0][i][:] = y - baseline
return len(output_items[0])
- Follow with:
- Vector to Stream
- FFT / display blocks
🔧 Method 2: Approximation using filters (simpler, less precise)
If you don’t want Python:
- Use a high-pass filter to remove slow trends
- Or chain:
- DC Blocker (removes 0th order)
- High-pass (removes low-frequency curvature)
⚠️ This is not true 2nd-order fitting, but often “good enough” for spectra.
🔧 Method 3: Offline (for best accuracy)
If you’re already saving data (which you are with your interferometry setup):
- Export to file
- Use Python/NumPy:
y_corrected = y - np.polyval(np.polyfit(x, y, 2), x)
💡 Practical tips (radio astronomy context)
- Use only baseline regions (exclude strong signals like the 1420 MHz hydrogen line)
- Larger vector sizes = smoother fit
- Don’t overfit (3rd+ order can distort real signals)
🧠 Rule of thumb
- Slight tilt → 1st order
- Gentle curve → 2nd order ✅
- Wavy baseline → filtering or higher order (careful!)