Public
Edited
Aug 10, 2023
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
filteredSignal_part = mkFilteredSignal(
copy(rawSignal.filter((d) => d.t < partRatio * signalSetup.length))
)
Insert cell
filteredSignal_part
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
filteredSignal = mkFilteredSignal(copy(rawSignal))
Insert cell
filteredSignal
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
mkFilteredSignal = (raw) => {

var tsRaw, tsFiltered, tail;

// Apply bandpass filters to the white noise
var filteredSignal = [];

bandRanges.map((range) => {
const { name, filter } = getBandpassFilter(range);
tsRaw = raw.map((d) => d.value);
tsFiltered = filter.filtfilt(tsRaw);

tail = copy(raw);
tail.map((d, i) =>
Object.assign(d, {
value: tsFiltered[i],
type: name
})
);

filteredSignal = filteredSignal.concat(tail);
});

return filteredSignal;
}
Insert cell
getBandpassFilter = (range) => {
const { name, low, high } = range,
{ Fs } = signalSetup,
coef = iirCalculator.bandpass({
order: 3,
characteristic: "butterworth",
Fs,
Fc: (low + high) / 2,
BW: (high - low) / 2,
gain: 0,
preGain: false
}),
filter = new Fili.IirFilter(coef);

return { name, low, high, coef, filter };
}
Insert cell
rawSignal = {
refresh;

const { Fs, length } = signalSetup,
n = parseInt(Fs * length);

var rnd = d3.randomNormal(),
i2t = d3.scaleLinear().domain([0, n]).range([0, length]);

const timeseries = [...new Array(n)].map((d, i) => {
return { i, t: i2t(i), value: rnd() };
});

return timeseries;
}
Insert cell
rawSignal
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
bandRanges = {
const colors = d3["scheme" + scheme];

const ranges = [
{ low: 1, high: 200, name: "raw" },
{ low: 8, high: 13, name: "alpha" },
{ low: 13, high: 30, name: "beta" },
{ low: 4, high: 8, name: "theta" },
{ low: 30, high: 100, name: "gamma" }
].map((d, i) => Object.assign(d, { color: colors[i % colors.length] }));

return ranges;
}
Insert cell
bandRanges
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
signalSetup = {
return {
Fs: 1000, // sampling frequency
length: 1.0 // Seconds
};
}
Insert cell
Insert cell
minMaxScale = (array) => {
const extent = d3.extent(array),
scale = d3.scaleLinear().domain(extent).range([-1, 1]);

return array.map(scale);
}
Insert cell
copy = (array) => {
return array.map((d) => Object.assign({}, d));
}
Insert cell
// Get available filters
availableFilters = iirCalculator.available()
Insert cell
// Instance of a filter coefficient calculator
iirCalculator = new Fili.CalcCascades()
Insert cell
Fili = require("fili")
Insert cell
schemesName = Object.entries(d3)
.filter(([k]) => k.startsWith("scheme"))
.map(([name, colors]) => name.slice(6))
Insert cell
d3 = require("d3")
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more