visualdynamics.io.rattlesnake¶
rattlesnake
¶
Importer for Rattlesnake vibration controller output files (.nc4).
Rattlesnake streams results to netCDF4 with a channel table that includes engineering units, so imports are fully unit-aware — no unit declaration needed. Layout (file_version 3.x):
- root attrs: sample_rate, hardware, file_version, ...
- time_data (response_channels, time_samples), in channel engineering units
- channels group: node_number, node_direction, unit, channel_type, and other per-channel metadata
- one group per environment (e.g. 'Random') that may carry a specification CPSD matrix (specification_frequency_lines, specification_cpsd_matrix_*) and the bands around it (specification_warning_matrix, specification_abort_matrix, each (2, lines, channels), lower first)
A run saves twice and the two files share nothing: streaming writes the time histories, and a separate save writes what the environment computed from them. Both are read here.
Returns a dict: 'channel_table' -> ChannelTable, and whichever of these the
file holds — 'time_data' -> TimeHistory, '
A modal environment counts every enabled channel as a response and never excludes its references, so the drives appear among them and the saved matrix carries each drive against the drives. Those rows are identity and cross-talk by construction — |H| exactly 1 against itself, numerically zero against the other, coherence exactly 1 — so they are dropped: they are arithmetic rather than measurement, and would put a force-per-force axis on the plot beside the real one.
A spectral file carries neither time data nor, once rattlesnake's own random save has been through it, the root attributes — so the sample rate may be missing and the frequency axis has to come from the specification's own lines. The noise cross spectra a random save also writes are deliberately left alone: they describe the measurement's noise floor and would double the object count for something rarely looked at.
Reading only, and deliberately: a .nc4 records a controller run — hardware
settings, environments, the lot — that visualdynamics does not hold, so a file written
from here would describe a test that never happened. See docs/export.md.
Functions:
| Name | Description |
|---|---|
environment_kinds |
{environment name: kind} the file says it holds. |
run_kind |
What kind of test the file holds, by its own account. |
project_type |
The visualdynamics project this file is a run of, or None if visualdynamics has no |
streamed_sysid_candidate |
Whether a streamed save has the shape a system ID leaves: |
Classes¶
Functions:¶
environment_kinds
¶
{environment name: kind} the file says it holds.
Empty for a file that does not say — an nc4 assembled by hand, or an older save from before the controller wrote its types down.
Source code in src/visualdynamics/io/rattlesnake.py
run_kind
¶
What kind of test the file holds, by its own account.
'modal', 'random', 'transient', 'sine' or 'time' for a run of one kind; 'mixed' when more than one environment drove the article at once, which is what a random-plus-sine-sweep run is; None when the file does not say.
Source code in src/visualdynamics/io/rattlesnake.py
project_type
¶
The visualdynamics project this file is a run of, or None if visualdynamics has no project of that kind — or the file never said what kind it was.
A mixed run answers with its leading half (MIXED_PRECEDENCE):
every environment's specification imports regardless, so the type
only chooses which workflow the tree leads with.
Source code in src/visualdynamics/io/rattlesnake.py
streamed_sysid_candidate
¶
Whether a streamed save has the shape a system ID leaves: exactly two streams, a quiet one then a loud one — the ambient measurement and the driven excitation.
The file itself cannot settle the question (a run of the environment that stopped and restarted its stream once looks the same on paper), so this is grounds to ask the person, never to decide. The quiet-then-loud check is what keeps the question from being asked about every two-stream file: a restarted run's halves play at one level, a system ID's differ by the whole test. Ten decibels is well under any real ambient-to-driven gap and well over a level change within one run.