DEV Community

Somenath Mukhopadhyay
Somenath Mukhopadhyay

Posted on • Originally published at som-itsolutions.blogspot.com on

How Rebuilding My Old FFT Spectrum Analyzer Opened a New Railway Safety Perspective - magic of julia

Back in 2012, I wrote a small experimental piece on building a simple FFT-based spectrum analyzer:

Read here...

FFT Based Spectrum analyzer(https://som-itsolutions.blogspot.com/2012/01/fft-based-simple-spectrum-analyzer.html)

At that time, it was more about curiosity. FFT fascinated me. The idea that a signal in time could reveal its hidden structure in frequency felt almost magical.

Fast forward to today.

I am revisiting that same idea — but this time using Julia , and not just for visualization, but for building something that could contribute to modern railway track safety systems.

And that’s when I realized why Julia is becoming so popular among the SciML (Scientific Machine Learning) community.


The Shift: From Scripting to Scientific Computing

In 2012, building a spectrum analyzer was largely:

  • A signal processing experiment

  • A learning exercise

  • A visualization tool

But today, with Julia, the same FFT analyzer becomes:

  • A condition monitoring prototype

  • A vibration diagnostics engine

  • A predictive maintenance building block

That shift is profound.


Why SciML Engineers Love Julia

The SciML ecosystem — led by projects like SciML — is not just about machine learning. It’s about merging:

  • Differential equations

  • Physics-based modeling

  • Optimization

  • Machine learning

  • High-performance computing

Julia allows all of this in one language.


1️⃣ Performance Without Leaving the Language

FFT in Julia uses FFTW under the hood.

You write:

fft(signal)

Enter fullscreen mode Exit fullscreen mode

And you get near C-level performance.

No bindings.

No external compilation workflow.

No switching between Python and C++.

For someone who enjoys going deep into engineering mathematics, that matters.


2️⃣ Multiple Dispatch Feels Like Engineering Thinking

As someone who loves system design and patterns, I noticed something interesting.

In C++ or Java, you think in terms of classes and inheritance.

In Julia, you think in terms of:

  • Mathematical structures

  • Generic functions

  • Behavior based on types

It feels closer to how engineers think about systems.

Not "object owns behavior" —

but "system responds based on physical type."

That mental alignment is powerful.


3️⃣ From FFT to Railway Safety

Let’s connect this back to my spectrum analyzer journey.

A railway track under load behaves like a vibrating beam.

When a crack develops, stiffness changes.

That produces high-frequency bursts in vibration signals.

With Julia, I can:

  • Simulate the rail as a mass-spring-damper system

  • Inject a stiffness drop

  • Perform FFT

  • Detect high-frequency anomalies

  • Add ML-based classification

All in one environment.

Modern railway systems, including those used by Indian Railways and Deutsche Bahn, rely heavily on:

  • Vibration analytics

  • Spectral energy monitoring

  • Predictive maintenance

What began as a simple FFT experiment now becomes a prototype for rail crack detection.

That evolution mirrors Julia’s evolution.


SciML Is More Than Machine Learning

SciML is about:

  • Embedding physical laws into ML

  • Solving differential equations efficiently

  • Combining simulation with learning

Using Julia, I can go from:

mx¨+cx˙+kx=F(t) m \ddot{x} + c \dot{x} + k x = F(t)

to spectral fault detection

to anomaly classification

without leaving the language.

That continuity is rare.


Why This Matters for Engineers

Many engineers hesitate to enter machine learning because:

  • Python feels high-level but slow

  • C++ feels powerful but heavy

  • MATLAB feels proprietary

Julia sits in a sweet spot:

  • Scientific syntax

  • High performance

  • Open ecosystem

  • Growing SciML community

And most importantly:

It lets you experiment at system level.


My Personal Realization

Rebuilding my old FFT-based spectrum analyzer in Julia was not nostalgia.

It was a rediscovery.

The same math.

The same Fourier transform.

But now:

  • Faster

  • Cleaner

  • Extensible

  • Connected to real-world safety applications

That is why Julia is becoming popular among SciML engineers.

Because it doesn’t just let you code.

It lets you think in equations and deploy in production.


Final Thought

What started as a simple blog post on FFT years ago has evolved into a small predictive maintenance prototype for railway safety.

Julia didn’t just make it easier.

It made it natural.

And when a language feels natural to scientists and engineers —

that’s when it starts becoming popular.

Here's the source code...

############################################################

# Rail Vibration Monitoring Prototype

# CASE B: Rail Crack Simulation

############################################################


using FFTW

using DSP

using Plots

using Statistics

using LinearAlgebra


# -------------------------------

# 1️⃣ System Parameters

# -------------------------------


fs = 5000# Sampling frequency (Hz)

T = 2# Signal duration (seconds)

t = 0:1/fs:T-1/fs

N = length(t)


println("Sampling Frequency = $fs Hz")

println("Total Samples = $N")


# -------------------------------

# 2️⃣ Normal Rail Vibration

# -------------------------------


f\_mode1 = 50

f\_mode2 = 120


signal = 0.7\*sin.(2π\*f\_mode1\*t) .+

0.3\*sin.(2π\*f\_mode2\*t)


# -------------------------------

# 3️⃣ Inject Crack Fault (High-Frequency Burst)

# -------------------------------


crack\_time = 1.0# crack at 1 second

crack\_index = Int(round(crack\_time \* fs))


burst\_length = 200# samples (~40 ms)

crack\_freq = 800# high-frequency crack signature


if crack\_index + burst\_length <= N

 signal[crack\_index : crack\_index + burst\_length] .+=

2\*sin.(2π\*crack\_freq\*t[1:burst\_length+1])

end


# Add background noise

signal .+= 0.2randn(N)


println("Simulated Crack Frequency = $crack\_freq Hz")


# -------------------------------

# 4️⃣ Time Domain Plot

# -------------------------------


p1 = plot(t, signal,

 xlabel="Time (s)",

 ylabel="Amplitude",

 title="Rail Vibration Signal (Crack Simulation)",

 legend=false)


# -------------------------------

# 5️⃣ FFT Processing

# -------------------------------


window = hanning(N)

signal\_w = signal .\* window


fft\_result = fft(signal\_w)

freq = fs\*(0:N-1)/N

magnitude = abs.(fft\_result)/N


halfN = div(N,2)


# -------------------------------

# 6️⃣ Spectrum Plot

# -------------------------------


p2 = plot(freq[1:halfN],

 magnitude[1:halfN],

 xlabel="Frequency (Hz)",

 ylabel="Magnitude",

 title="Frequency Spectrum",

 legend=false,

 xlim=(0,1000)) # Extended to show 800 Hz


# -------------------------------

# 7️⃣ Side-by-Side Display

# -------------------------------


p3 = plot(p1, p2, layout=(1,2), size=(1200,400))

display(p3)


# -------------------------------

# 8️⃣ Crack Detection Logic

# -------------------------------


println("\n🔍 Running Crack Detection...\n")


# Detect energy in high-frequency band

high\_freq\_indices = findall(freq .> 600 .&& freq .< 1000)

high\_freq\_energy = sum(magnitude[high\_freq\_indices])


println("High Frequency Energy = ", round(high\_freq\_energy, digits=4))


if high\_freq\_energy > 0.02

println("⚠️ Possible Rail Crack Detected (High-Frequency Burst)")

else

println("✅ No crack signature detected")

end


# -------------------------------

# 9️⃣ RMS Indicator

# -------------------------------


rms\_value = sqrt(mean(signal.^2))

println("\nRMS Vibration Level = ", round(rms\_value, digits=4))


println("\n--- Rail Crack Monitoring Simulation Complete ---")


wait()
Enter fullscreen mode Exit fullscreen mode

And here's when we run the application...

Railway track fault determination FFT

📈 Time Plot

A sharp disturbance around 1 second.

📊 Frequency Plot

A strong peak near:


800 Hz

Enter fullscreen mode Exit fullscreen mode

🖥 Console Output


⚠️ Possible Rail Crack Detected (High-Frequency Burst)

Enter fullscreen mode Exit fullscreen mode

Top comments (0)