Skip to content

Repository files navigation

Modal Analysis Portfolio

CI Python Streamlit

Live demo: open the Streamlit app

Experimental modal analysis toolkit for demonstrating structural dynamics work in a public portfolio. The project combines a Streamlit analysis UI, a reusable Python modal-analysis core, and a reproducible synthetic benchmark with known ground truth.

Portfolio highlights:

  • shared-pole MIMO modal fitting that can recover modes missed by single-input SIMO setups,
  • LSCF stabilization, CMIF, and band/MIF pole-detection workflows for measured FRF data,
  • mode-shape, MAC, strain, rotational-DOF, and structural-modification views in one app,
  • synthetic validation data and pytest/GitHub Actions checks for repeatable verification.

This repository presents a self-contained Streamlit workflow plus a reusable analysis core (modal_portfolio.py) for modal-analysis demonstrations:

ModalAnalysis overview

Mode shape visualization

  • SIMO and MIMO input topologies, from FRF CSVs or time-history data,
  • initial pole detection with an LSCF stabilization diagram, CMIF, and band indicators,
  • differential-iteration modal fitting with shared poles across all inputs (MIMO),
  • nodal rotational DOF estimation from translational responses,
  • mode shapes, MAC, strain ranking, and 3D geometry views,
  • structural modification simulation (modal projection: frequency shifts and modified FRFs),
  • a fully synthetic, shareable sample dataset with ground truth for quantitative verification.

Quick Start

python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
streamlit run app.py

Requirements: numpy, pandas, scipy, plotly, streamlit (see requirements.txt).

Sample Data

Synthetic frame sample (bundled, default)

The app ships a fully synthetic sample with known ground truth that exercises the entire workflow. data/sample/sample_FRF_synth_X/Y/Z.csv plus nodes_synth.csv / elements_synth.csv are generated by make_synthetic_sample.py (seeded, reproducible); select the "Synthetic frame" geometry and FRF sources in the sidebar to use them:

  • structure: 4-story spring-mass frame tower, 4 grounded base nodes + 16 free nodes (48 response DOFs), axial springs for columns/beams/braces with deliberate stiffness anisotropy and per-element jitter so modes are mostly well separated (with a few moderately close pairs left in for CMIF demonstrations),
  • modal damping 0.5-3% per mode, first mode at 8 Hz, 35 modes below 150 Hz,
  • excitation at node 20 in X/Y/Z (positive sign convention), velocity FRFs in (m/s)/N at 0.25 Hz spacing,
  • noise: 3% multiplicative complex noise plus a 1% additive floor,
  • ground truth (data/sample/sample_synth_truth.csv): true natural frequency and damping ratio per mode, so detection/fit accuracy can be quantified. Verified end-to-end: LSCF detection + MIMO fit over 5-50 Hz recovers 8 of the 9 in-band modes with fn and damping matching the truth table (the remaining one is a weakly excited close mode).

Re-generate (or tweak the structure, damping, or noise) with python make_synthetic_sample.py. A matching structural-modification example (data/modifications/modified_nodes_synth.csv / modified_elements_synth.csv, two added braces on the top story) is bundled for the Modification tab.

Data Inputs

Frequency Response

Use one CSV for SIMO or one CSV per input for MIMO (all files must share the same response point order). Supported format:

  • metadata rows such as Node, Coord/DOF, and Direction,
  • a Frequency column,
  • repeating Magnitude, Phase column pairs for each response DOF.

The UI converts measured displacement, velocity, or acceleration into displacement-domain FRFs before analysis.

Time History

Use a CSV with a time column, input columns, and output columns. For MIMO, the app estimates the FRF matrix with the input cross-spectral matrix:

H(f) = S_yx(f) pinv(S_xx(f))

Output column names such as 12X, 12Y, and 12Z are automatically mapped to node 12 translational DOFs.

Analysis Pipeline

1. Initial pole detection

Three selectable methods (sidebar "Initial pole detection"; visualized in the Modal Fit tab):

  • LSCF + automatic stabilization diagram (default): self-contained common-denominator pole estimation with automatic stable-pole clustering. Poles are computed over increasing model orders; poles that repeat within tolerance are clustered and reported with a stability count. Yields per-mode initial damping directly from the poles.
  • CMIF: SVD of the (output x input) FRF matrix at every frequency line. A mode only needs to be excited by one input to appear in the first singular value; the SV2/SV1 ratio flags repeated/close modes. Damping from half-power bandwidth.
  • Band power + normal MIF (single input): RMS amplitude peaks qualified by the MIF dip at resonance. Average-|FRF| peak picking is retained as a simple fallback.

Detected frequencies pre-fill the initial-frequency field, and "Per-mode initial damping from detection" feeds the per-mode damping estimates into the fit.

2. Differential-iteration modal fitting

Selectable between SIMO fit (one input) and MIMO fit (all inputs simultaneously). The MIMO fit shares poles (wdr, sigma_r) across inputs and additionally estimates input-side coefficients Pr/Qr and per-pair residual terms Y/Z; the input participation table shows which excitation drives which mode. Both fits run on a shared sparse block-diagonal core (kron structure) with an analytic Jacobian validated against synthetic benchmarks within numerical tolerance. See the theory notes for details and the SIMO/MIMO comparison for when each is appropriate.

3. Results

Reconstructed-vs-measured FRF overlays, modal parameter tables, complex mode-shape tables, 3D deformation view, auto-MAC heatmap, strain ranking, and CSV exports.

Rotational DOF Estimation

For each target node, the app uses connected neighboring nodes and solves a small rigid-body least-squares problem:

u_j - u_i ~= theta_i x (x_j - x_i)

This estimates Rx, Ry, and Rz from translational FRFs or time-history-derived FRFs. The method is an engineering approximation for demonstration and screening; detailed validation should still be performed against known rotational measurements or FEM references.

Structural Modification Simulation

The Modification tab provides a modal-projection structural-change workflow: download the modified_nodes / modified_elements templates (examples in data/modifications/), define added beams with rho, E, G, A, Ix, Iy, Iz, and upload both files. After a modal fit, the app mass-normalizes the identified modes with a chosen reference DOF, projects the added beam mass/stiffness onto modal space, and reports the predicted modal frequency shifts alongside baseline-vs-modified FRF overlays. Physics and limitations are documented in the theory note below.

Validation

Reproducible pytest checks under validation/ exercise the SIMO/MIMO fitting behavior, noise robustness, bundled tower sample, and structural-modification path:

pip install -r requirements.txt -r requirements-dev.txt
pytest -q

For a verbose comparison report, run python validation/compare_simo_mimo.py.

Directory Layout

ModalAnalysis/
  app.py                    Streamlit portfolio UI
  modal_portfolio.py        reusable modal-analysis core
  make_synthetic_sample.py  shareable synthetic sample generator (seeded)
  data/
    sample/              app-ready synthetic sample geometry, FRF data, and ground truth
    test/                tiny synthetic/test CSVs used by regression checks
    modifications/       structural modification CSV example (synthetic tower)
  validation/            reproducible comparison and regression scripts
  docs/                  mathematical and project theory notes

See data/README.md for the data-folder conventions.

Portfolio Notes

This project is useful for showing:

  • mechanical engineering and vibration-analysis background,
  • Python-based signal processing and FRF handling,
  • MIMO/SIMO modal-test workflow understanding,
  • practical UI construction for analysis tools,
  • ability to turn experimental scripts into a reproducible application.

Theory Notes

Main Files

  • app.py: Streamlit portfolio UI.
  • modal_portfolio.py: data loading, FRF conversion, pole detection (LSCF/CMIF/MIF), SIMO/MIMO fitting, rotation estimation, and structural modification core.
  • make_synthetic_sample.py: generator for the shareable synthetic sample set (ground truth included).
  • validation/: SIMO/MIMO comparison and structural-modification regression scripts.

About

Experimental modal analysis toolkit: LSCF/CMIF pole detection, shared-pole MIMO fitting with analytic Jacobians, validated against synthetic ground truth (Streamlit + CI)

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages