Files (0)
Variables
Derived variables
Formula help
Operators
+ - * / ^ ( )
Functions
sqrt(x), abs(x), log(x), log10(x), power(x,n), root(x,n), diff(x), min(...), max(...)
sin(x), cos(x), tan(x), asin(x), acos(x), atan(x)
Angles are in radians.
sinh(x), cosh(x), tanh(x)
sign(x), step(x)
sign is 1, -1 or 0 — a sample sitting exactly on zero comes out 0. step is 1 from zero upwards and 0 below.
Min / max
Compared sample by sample, over as many operands as you give them:
min(x, 0)a variable and a constantmax(x, y)two variablesmin([x, y, z])a list of variables in square brackets
Time axis
The time vector is an operand like any other — the one tagged "time" in the suggestions. With it you can synthesize a signal instead of only transforming one:
Frequencies read in Hz when the axis is in seconds; a date/time axis counts in milliseconds.
sin(2*pi*1000*time)a pure 1 kHz tonex + 0.1*sin(2*pi*50*time)adds 50 Hz hum to a signal2*step(sin(2*pi*50*time))-1a 50 Hz square wave, strictly +1 or -1
Constants
pi, e
Available whenever your file has no variable of that name — your own variables always win. If one does shadow them, write:
math.pi, math.e
Variables
Start typing to autocomplete variable and function names.
Example
x / y^2 * 100
Data tools
Outlier detection help
Spike/dropout
Uses a moving median and local MAD to catch short gross excursions that return to the neighborhood.
Bounds
Flags finite values outside the physical minimum or maximum you enter.
6
21
Fill methods help
Linear
A straight line in time between the samples either side of the hole.
Cubic
PCHIP never overshoots the values it joins; Akima is smoother through curvature and shrugs off a single wild sample.
Smoothed local trend
Fits a weighted straight line through the surrounding samples, so a noisy signal is bridged along its trend instead of between two noisy readings.
Two kinds of hole
One NaN between two good samples one Δt apart is reconstruction: the signal cannot have gone far in between. Sixty NaN spanning a stretch the file never sampled is invention: the same formula, with nothing to constrain it. The limit below is exactly where you draw that line, which is why the panel quotes the longest run in samples and in time.
Longest gap to fill
Runs longer than this are left as they are. Type a number larger than the slider to go past it.
What it cannot do
It replaces NaN samples in place: same length, same time axis, so the result is a variable of this file. It cannot create rows the file does not have — a stretch where the logger stopped contains no NaN to replace. Resample at the file’s own Δt with Gaps in the source: leave them empty to materialise those rows as NaN, then come back here.
10
21
2
101
4
Hz
Hz
dB
dB
Filter design help
What it does
Turns a specification — family, response, order and cut-off — into the coefficients below, the way MATLAB’s **butter** / **cheby1** / **cheby2** / **besself** and scipy’s **iirfilter** do. The families are the classic analog designs; since the data is sampled, the analog prototype is discretised with the **bilinear transform**, pre-warped so the digital filter lands exactly on the cut-off you typed. The coefficients are written into **b** and **a** so you can copy them into another tool.
Family
**Butterworth** — no ripple anywhere: the passband is as flat as an all-pole filter can be, and the roll-off is gentle. The default, and the right choice unless you know why not.
**Chebyshev I** — a sharper transition than Butterworth at the same order, paid for with ripple in the passband of the depth you set. The cut-off is where the ripple band ends, so the gain there is −(ripple) dB, not −3 dB.
**Chebyshev II** — the same sharpness with the ripple moved into the stopband, so the passband stays flat. The cut-off is where the stopband **begins**: the frequency at which the attenuation you set is first reached.
**Bessel** — the flattest group delay: every frequency in the passband is delayed by about the same amount, so pulses and steps keep their shape instead of ringing. The slowest roll-off of the four. Normalised so the gain is −3 dB at the cut-off.
Order
How many poles the prototype has, and so how steep the roll-off is: a Butterworth falls by about **20·N dB per decade** beyond the cut-off. A band-pass or band-stop of order N is a digital filter of order 2N, because every prototype pole becomes two. Higher orders sharpen the edge and lengthen the transient; 2 to 6 covers most needs.
Sample rate and Nyquist
The sample rate is read off the file’s time axis (1 / median Δt) and shown below the fields. A cut-off must sit below **half** of it — nothing above Nyquist exists in sampled data. With no time axis the rate is one sample per sample and the cut-off is entered in cycles per sample, between 0 and 0.5.
**An irregular Δt refuses the design.** A cut-off in hertz means nothing on data whose samples are not evenly spaced, so the panel will not design a filter for it; resample to a uniform grid first. (Typing b and a still works there — a filter is defined per sample — but its cut-off is then not a frequency.)
How it runs
A designed filter runs as a cascade of **second-order sections**, never as the single polynomial shown in b and a. At order 8 with a cut-off far below Nyquist the polynomial’s own rounding puts a pole outside the unit circle; the sections keep every pole exactly. The b and a boxes are for reading and copying. With **Forward and back** the response is applied twice, so a −3 dB cut-off becomes −6 dB and the effective order doubles.
Direction help
Forward (causal)
Runs from the first sample to the last, so every output uses only the past — exactly what a filter running in real time on an instrument does. The unavoidable price is delay: the output lags the input, and by a different amount at every frequency.
Forward and back (zero phase)
Filters the signal, then filters that result backwards. The second pass applies exactly the opposite delay, so the two cancel and nothing moves in time at all — a feature stays at the sample it happened on.
This makes it a non-causal filter: each output depends on samples that come after it. That is impossible in real time and perfectly ordinary offline, which is what this app does — but it means the result cannot be reproduced by any filter running on live data. Two further consequences: the signal passes through the response twice, so the attenuation is squared (a filter that halves at some frequency now quarters it), and the effective order is doubled.
Initial conditions help
A recursive filter needs a past to start from: y[0] depends on x[−1] and y[−1], which the file does not contain. All four options answer that one question — what was happening just before the data begins — and they only differ in how you would rather say it.
Steady state (no startup transient)
The default. As if the input had been sitting at the first sample forever, so a signal at 300 opens at 300 instead of swinging up from zero. Use it unless you have a reason not to.
Zero (filter starts at rest)
Everything before the start is taken as 0, which is what a real DSP does when it powers up. Reproduces the startup transient of an embedded filter — including the swing from zero, which here is a real part of the answer rather than an artefact.
Constant level before the start
One number: the value the input had been holding before the recording began. Steady state with the level named by you instead of read from the first sample — the right answer when the file starts mid-event and its first sample is not where the signal had been resting.
Past samples of x and y
The fully general option, and the one to reach for when you know the history. Two boxes, N values each for a filter of order N, newest first: the inputs box takes x[−1], x[−2] … and the outputs box takes y[−1], y[−2] …, separated like the coefficients. Each placeholder names its own values.
Give the past outputs too, not just the inputs. Leaving y at zero while x is not describes a filter that was fed a history but had its output memory wiped — a state no running filter is ever in, and it produces a startup kick of its own. If you do not know the past outputs, one of the three options above is a better answer than guessing them.
When it is used
The state is set at the first sample and again at every restart (see Missing values / NaN). Zero phase ignores this setting: it derives its own edges from the reflection padding. Changing b or a clears the values you typed, because a history of the wrong length belongs to a different filter.
Missing values / NaN
samples
Missing values / NaN help
The output
Holes stay holes. The result is missing wherever the input is missing, and wherever the file skipped a stretch of time — nothing is invented across a break. Fill the holes first if you want the filter to run through them; that is a decision with its own parameters, and Fill missing data owns it.
The state is what you configure
A single missing value inside a recursive filter would enter the state and make every later sample missing too, so the recursion cannot simply run on. What the threshold below decides is whether the filter's memory survives a break or is rebuilt on the far side of it.
The unit is samples
Samples, never seconds. The number is how many consecutive sample positions may carry no usable value and still be stepped over. A filter has no notion of time, so counting the break in seconds would mean nothing to it.
What is counted
Two things that look different in the file but are the same break in the signal: rows that exist and hold a missing value, and stretches of time the file simply skipped. The second is measured against the file's own nominal step — a jump of 10 Δt counts as 9 missing samples even though no row is there to see.
0 — restart at every break
The default, and the conservative choice: nothing is carried across a hole. The recursion begins again on the far side under the initial conditions you chose, which costs one settling transient per break.
Higher — step over short breaks
A break of at most this many samples is stepped over with the filter's state left standing, so the signal continues as though the gap had not happened and you spend one transient instead of many. Sound when the hole is short next to the filter's memory, misleading when it is long — the state then carries a memory of a moment that is already far in the past.
Digital filter help
What it computes
a₀·y[n] = b₀·x[n] + b₁·x[n−1] + … − a₁·y[n−1] − a₂·y[n−2] − …
Leave a at 1 for an FIR: with no feedback term the output depends only on the input.
Numerator and denominator
Both are lists in ascending delay order: b is b₀, b₁, b₂ … (weights on x[n], x[n−1], x[n−2] …) and a is a₀, a₁, a₂ … (weights on y[n], y[n−1], y[n−2] …). The lists need not be the same length; the shorter one is padded with zeros.
a₀ need not be 1. It divides every other coefficient, so it may be any non-zero number and the filter is normalised for you — 2, 1 is the same filter as 1, 0.5. Only zero is refused: that is not a difference equation.
Separate the numbers with commas, spaces, semicolons or newlines, and square brackets are accepted so a list can be pasted straight from MATLAB or NumPy. All of these are the same: 0.5, 0.24 · 0.5 0.24 · [0.5 0.24] · [0.5, 0.24]
Long delays: zeros(k)
A run of zeros may be written zeros(k), as in MATLAB: 1 zeros(2399) 0.5 is an echo 2400 samples back. Only the non-zero coefficients cost anything, however long the delay.
Stability
An unstable filter cannot be created: its own output feeds back and grows until every later sample is infinite. The poles of a are checked before anything runs.
Sample rate
A digital filter is defined per SAMPLE, not per second: the coefficients know nothing about the time axis. On a file with an irregular Δt the cut-off is therefore not a fixed frequency in the data's own units, and the panel says so. Resample to a uniform grid first if you need the cut-off to mean a frequency.
Long delays and echoes
Writing the delay
zeros(k) stands for k zeros in the list; zeros(1,k) and zeros(k,1) mean the same, so [1 zeros(1,2399) 0.5] pastes straight from MATLAB. A filter of order 2400 with two non-zero coefficients runs as fast as one of order 2.
The simple echo
y[n] = x[n] + α·x[n−N], with N = round(T·Fs). A 300 ms echo at half amplitude on 8 kHz audio is N = 2400: b = 1 zeros(2399) 0.5, a = 1. Choose Zero (the filter starts at rest) under Initial conditions to take x[n] = 0 before the recording, as the equation does.
Feeding the echo back
For the echo to repeat on itself — y[n] = x[n] + α·y[n−N] — put the delay in the denominator instead: b = 1, a = 1 zeros(2399) −0.5. The stability check then insists on |α| < 1: at α = 1 the echoes never die out.
Limits
Delays up to 2²⁰ samples in b, up to 16 384 in a, and up to 8 192 non-zero coefficients. Past that length the past-samples start is withdrawn — nobody types 4 800 values — and the stability check no longer locates the poles, only decides.
s
detected
Resampling help
Reading the curve
Linear, cubic, nearest and hold read the signal at each new time. Right for upsampling; downsampling this way aliases fast detail into slow structure.
Reducing a bin
Average, median, minimum and maximum reduce every sample around each new time. Average is the anti-aliased downsample; minimum and maximum keep the envelope.
Missing data
A missing VALUE stays missing: a new time surrounded by NaN, or an empty bin, comes out NaN whatever you choose below.
Absent ROWS are the separate question Gaps in the source answers. A file that stopped logging for a minute has no NaN in it at all — the samples either side are perfectly good — so a point method can reach across. The two cases are the same formula with opposite standing: interpolating between two samples one Δt apart reconstructs, interpolating across sixty of them invents.
Leave them empty (the default) marks those samples NaN — which is also what the bin methods have always done with an interval holding nothing — and then Fill NaN values bridges them with a method, a length limit and an edge policy of your choosing. Interpolate across them does it here in one step, with no control over how far is too far. Bin methods never reach across anything, so the choice does not apply to them.
A new file
The result has its own time axis, so it arrives as a new file next to this one rather than as a variable inside it.
s
Cross-correlation help
What it computes
r_xy[k] = Σₙ x[n + k] · y[n], k = −L … L
**x** is the variable chosen above, **y** the second signal. The result is a new dataset on a **lag** axis, in the file’s time unit: how alike the two signals are when one is slid past the other by each lag. Choose the same signal twice for the **autocorrelation**, which is symmetric and largest at lag 0.
The sign of the lag
The convention is MATLAB’s **xcorr(x, y)** and SciPy’s **correlate(x, y)**. A peak at a **positive** lag k means x[n + k] lines up with y[n]: **x runs behind y** by k — x is the delayed signal. A peak at a **negative** lag means y is the delayed one. The message after Create says it in words, and the dataset carries the peak lag and value as parameters.
Normalisation
The four of xcorr. **none** is the raw sum. **biased** divides by N, the length of the series, so the far lags shrink — a consistent estimate of the correlation function. **unbiased** divides by the number of pairs that overlap at each lag (N − |k|), which is unbiased but noisy at the far lags where few pairs remain. **coeff** divides by √(r_xx[0]·r_yy[0]), so the autocorrelation is exactly 1 at lag 0 and every value lies in [−1, 1]; with the means removed it is the Pearson correlation of the two signals at each lag.
Removing the mean
A constant offset correlates with everything: two signals sitting at 300 and 20 have a large, meaningless r at every lag. Removing each signal’s mean first (the default) leaves only how they vary together. Turn it off to reproduce a textbook xcorr on the raw values.
Missing values
A product is counted only when both samples are finite, so a hole in either signal removes pairs rather than poisoning every lag. **unbiased** divides by the pairs that actually exist; **biased** keeps N. A lag with no pair at all comes out NaN.
The lag axis
A lag is a whole number of samples, so it is only a time on a uniform Δt: an irregular axis refuses the tool (resample to a uniform grid first). With no time axis the lag is counted in samples. The maximum lag caps the range; the far lags of a long record are rarely worth the space.
Transformations
Options
Legend
Layout
Hover a panel to split or close it.
Franco FERRUCCI ·
ferrucci-franco.github.io
📁
Drag & drop a result or text file here
or
Loading application...
📁