9  Fiber sensors: OTDR, distributed sensing, interferometers

Open in Colab  Run this chapter’s code in Google Colab (no installation).

Slides 231–311. The weaknesses of a fiber for telecom (scattering, sensitivity to strain and temperature) become strengths for sensing. Fiber sensors are immune to EMI, need no electrical power at the sensing point, survive harsh environments, and can be distributed along tens of km.

9.1 Optical time-domain reflectometry (slides 245–266)

Send a short pulse and listen to the Rayleigh backscatter. Light returning at time \(t\) comes from

\[ z=\frac{v_g t}{2},\qquad \Delta z_\text{res}=\frac{v_g\tau}{2}\ (\text{pulse width }\tau). \]

The backscattered power from position \(z\) is

\[ P_{bs}(z)=P_0\,S\,\alpha_s\,\frac{v_g\tau}{2}\,e^{-2\alpha z}, \]

where \(S\approx10^{-3}\) is the capture factor and \(\alpha_s\) the scattering coefficient. OTDR traces are plotted in one-way dB, \(5\log_{10}P\), so that the slope reads directly as the fiber attenuation.

9.1.1 Example (slide 262)

Show the Python
P0 = fl.dBm_to_W(13); tau = 10e-6; vg = c0 / 1.468
alpha = 0.33 / 4.343 / 1e3; alpha_s = 0.3 / 4.343 / 1e3; S = 1e-3
for z in [0, 50e3, 100e3]:
    P = P0 * S * alpha_s * vg * tau / 2 * np.exp(-2 * alpha * z)
    print(f"z = {z/1e3:5.0f} km:  P_bs = {P*1e9:9.3f} nW = {fl.W_to_dBm(P):6.1f} dBm")
print(f"Spatial resolution with τ = 10 µs: {vg*tau/2:.0f} m")
z =     0 km:  P_bs =  1407.330 nW =  -28.5 dBm
z =    50 km:  P_bs =     0.705 nW =  -61.5 dBm
z =   100 km:  P_bs =     0.000 nW =  -94.5 dBm
Spatial resolution with τ = 10 µs: 1021 m

9.1.2 Averaging (slides 252–253)

Noise falls as \(\sqrt N\) with \(N\) averaged shots. Each shot must wait one round trip, \(T=2nL/c\).

Show the Python
L = 10e3; T = 2 * 1.468 * L / c0
for t_meas in [1, 180]:
    N = 0.9 * t_meas / T
    print(f"{t_meas:4d} s: N = {N:.3g} shots → noise reduced by √N = {np.sqrt(N):.0f}× "
          f"= {5*np.log10(N):.1f} dB (one-way OTDR scale)")
   1 s: N = 9.19e+03 shots → noise reduced by √N = 96× = 19.8 dB (one-way OTDR scale)
 180 s: N = 1.65e+06 shots → noise reduced by √N = 1286× = 31.1 dB (one-way OTDR scale)

9.1.3 OTDR simulator, live

The fiber below has a front connector, a fusion splice at 8 km, a tight bend at 15 km, a mechanical splice at 22 km and an open end at 30 km. Change the pulse width and the averaging, and look at the trade-off between dynamic range and resolution (slide 256).

9.1.4 Measuring a splice by least squares (slides 263–265)

Show the Python
rng = np.random.default_rng(2)
z = np.linspace(0, 20, 2000)
true_loss, zs = 0.25, 9.0
y = -0.2 * z - true_loss * (z > zs) + rng.normal(0, 0.03 + 0.004 * z, z.size)
m1 = (z > 1) & (z < zs - 0.3); m2 = (z > zs + 0.3) & (z < 19)
p1, p2 = np.polyfit(z[m1], y[m1], 1), np.polyfit(z[m2], y[m2], 1)
fig, ax = plt.subplots()
ax.plot(z, y, ".", ms=1.5, color=fl.PALETTE[0], alpha=0.5)
ax.plot(z, np.polyval(p1, z), color=fl.PALETTE[1], label=f"L1: {-p1[0]:.3f} dB/km")
ax.plot(z, np.polyval(p2, z), color=fl.PALETTE[2], label=f"L2: {-p2[0]:.3f} dB/km")
ax.axvline(zs, color=fl.INK2, ls=":")
ax.set_xlabel("distance (km)"); ax.set_ylabel("relative level (dB)"); ax.legend()
plt.show()
print(f"Estimated splice loss = {np.polyval(p1, zs) - np.polyval(p2, zs):.3f} dB (true {true_loss} dB)")
Figure 9.1: A splice loss is measured by fitting straight lines to the backscatter before and after the event and taking their vertical offset at the event position.
Estimated splice loss = 0.257 dB (true 0.25 dB)

9.2 Raman distributed temperature sensing (slides 237–241)

Spontaneous Raman scattering produces a Stokes and an anti-Stokes line shifted by ~13 THz. Only the anti-Stokes line depends strongly on the phonon population, so their ratio is a thermometer:

\[ R(T)=\frac{P_{AS}}{P_S}=\left(\frac{\lambda_S}{\lambda_{AS}}\right)^4\exp\left(-\frac{h\Delta\nu}{k_BT}\right). \]

Show the Python
T = np.linspace(200, 600, 300)
dnu = 13.2e12; nu_p = c0 / 1550e-9
lS, lAS = c0 / (nu_p - dnu), c0 / (nu_p + dnu)
R = (lS / lAS) ** 4 * np.exp(-fl.h * dnu / (fl.kB * T))
fig, ax = plt.subplots()
ax.plot(T - 273.15, R, label="R(T)")
ax2 = ax.twinx(); ax2.grid(False)
ax2.plot(T - 273.15, 100 * fl.h * dnu / (fl.kB * T**2), "--", color=fl.PALETTE[1], label="sensitivity (%/K)")
ax.set_xlabel("T (°C)"); ax.set_ylabel("P_AS / P_S"); ax2.set_ylabel("dR/R per K (%)")
fig.legend(loc="upper center", ncol=2, frameon=False); plt.show()
print(f"Sensitivity at 25 °C: {100*fl.h*dnu/(fl.kB*298.15**2):.2f} %/K")
Figure 9.2: Anti-Stokes/Stokes ratio versus temperature for a 1550 nm pump (Δν = 13.2 THz) and its relative sensitivity (≈ 0.8 %/K at room temperature).
Sensitivity at 25 °C: 0.71 %/K

9.3 Brillouin sensing (slides 242–244)

The backscattered Brillouin line is shifted by \(\nu_B=2nv_a/\lambda\). Its shift depends on both strain and temperature.

Show the Python
n, va = 1.45, 5960
for lam in [1.31e-6, 1.55e-6]:
    print(f"λ = {lam*1e6:.2f} µm: ν_B = {2*n*va/lam/1e9:.2f} GHz")
print("Typical coefficients in SMF at 1550 nm: ≈ 0.05 MHz/µε and ≈ 1.1 MHz/K, with a gain linewidth of ≈ 30 MHz.")
λ = 1.31 µm: ν_B = 13.19 GHz
λ = 1.55 µm: ν_B = 11.15 GHz
Typical coefficients in SMF at 1550 nm: ≈ 0.05 MHz/µε and ≈ 1.1 MHz/K, with a gain linewidth of ≈ 30 MHz.

9.4 Fabry–Perot filters and sensors (slides 271–283)

\[ T=\frac{1}{1+F\sin^2(\delta/2)},\qquad F=\frac{4R}{(1-R)^2},\qquad\delta=\frac{4\pi nd\nu}{c},\qquad \mathrm{FSR}=\frac{c}{2nd},\qquad \mathcal F=\frac{\pi\sqrt R}{1-R}. \]

Show the Python
nu = np.linspace(10.5e12, 12.5e12, 4000)
fig, ax = plt.subplots()
for k, R in enumerate([0.97, 0.98]):
    ax.plot(nu / 1e12, 10 * np.log10(fl.fabry_perot_T(nu, 100e-6, R)), color=fl.PALETTE[k],
            label=f"R = {R*100:.0f} %, finesse = {np.pi*np.sqrt(R)/(1-R):.0f}")
ax.set_xlabel("f (THz)"); ax.set_ylabel("T (dB)"); ax.set_ylim(-40, 1); ax.legend()
plt.show()
Figure 9.3: Transmission of a Fabry–Perot filter with d = 100 µm (air), R = 97 % and 98 % (slide 277). The FSR is 1.5 THz. A higher R narrows the resonance and deepens the rejection.

A change of the cavity length \(\delta d\) (pressure on a diaphragm, strain, thermal expansion) shifts the fringes by \(\delta\nu/\nu=-\delta d/d\). This makes the Fabry–Perot one of the most sensitive point sensors (slides 279–283).

9.5 The Sagnac effect and fiber-optic gyroscopes (slides 284–311)

In a loop rotating at \(\Omega\), the clockwise and counter-clockwise waves accumulate a phase difference

\[ \Delta\phi_S=\frac{2\pi LD}{\lambda c}\,\Omega=\frac{8\pi NA}{\lambda c}\,\Omega \]

for a coil of length \(L\) wound on a diameter \(D\) (N turns of area A). Nothing else in the loop distinguishes the two directions, so this tiny phase can be measured.

Show the Python
OmE = 7.292e-5                      # Earth rotation [rad/s]
for L, D in [(200, 0.03), (1000, 0.1), (5000, 0.2)]:
    print(f"L = {L:5d} m, D = {D*100:4.0f} cm: scale factor {2*np.pi*L*D/(1.55e-6*c0):.3f} rad/(rad/s), "
          f"Earth rotation → Δφ = {2*np.pi*L*D/(1.55e-6*c0)*OmE*1e6:.1f} µrad")
dphi = np.linspace(-np.pi, np.pi, 400)
fig, ax = plt.subplots()
ax.plot(dphi, (1 + np.cos(dphi)) / 2, label="unbiased: (1 + cos Δφ)/2")
ax.plot(dphi, np.sin(dphi), label="with phase-modulation bias: ∝ sin Δφ")
ax.axvline(0, color=fl.INK2, lw=0.6)
ax.set_xlabel("Sagnac phase Δφ (rad)"); ax.set_ylabel("detected signal (a.u.)"); ax.legend(fontsize=8)
plt.show()
L =   200 m, D =    3 cm: scale factor 0.081 rad/(rad/s), Earth rotation → Δφ = 5.9 µrad
L =  1000 m, D =   10 cm: scale factor 1.352 rad/(rad/s), Earth rotation → Δφ = 98.6 µrad
L =  5000 m, D =   20 cm: scale factor 13.522 rad/(rad/s), Earth rotation → Δφ = 986.0 µrad
Figure 9.4: Open-loop FOG response. Without bias (cos response) the gyro is blind to small rotations and to their sign. A ±π/2 phase modulation turns the response into sin(Δφ), which is linear and signed around zero (slides 295–297).

9.6 Try it yourself

  1. Extend the OTDR simulator with a reflective connector and implement the attenuation dead-zone (receiver saturation and recovery time).
  2. A φ-OTDR (slide 267) uses a highly coherent laser: the backscatter becomes a speckle pattern whose changes reveal vibrations. Simulate it by summing random-phase scatterers inside the pulse and perturbing the phase locally.
  3. Compute the shot-noise-limited angle random walk of a FOG with 1 km coil, 100 µW at the detector. Compare with tactical-grade (~0.1 °/√h) and navigation-grade (<0.001 °/√h) requirements.