#!/usr/bin/env bash # # Run a noise-floor capture and analyse it in one step. # # Wraps logger.py -- every logger flag is accepted and passed straight through -- # then runs plot.py and characterize.py on whatever was captured. Works whether # the run ends on --duration or on Ctrl-C. # # ./noise_floor_test.sh --duration 60 # ./noise_floor_test.sh --duration 3600 --cycle-count 400 # ./noise_floor_test.sh # until Ctrl-C # # Anything you pass explicitly wins; otherwise logger.py's defaults apply. set -uo pipefail # deliberately not -e: logger.py exits 1 on a miss, # and a partial capture is still worth analysing. cd "$(dirname "$0")" if [[ ! -f .venv/bin/activate ]]; then echo "No virtualenv found. Run ./setup.sh first." >&2 exit 1 fi # shellcheck disable=SC1091 source .venv/bin/activate args=("$@") has_flag() { local needle=$1 a for a in "${args[@]:-}"; do [[ "$a" == "$needle" || "$a" == "$needle="* ]] && return 0 done return 1 } # The CSV path has to be known up front so the analysis can find it; logger.py # would otherwise pick a timestamped name we cannot predict without racing it. output="" for ((i = 0; i < ${#args[@]}; i++)); do case "${args[i]}" in --output=*) output="${args[i]#--output=}" ;; --output|-o) output="${args[i+1]:-}" ;; esac done if [[ -z "$output" ]]; then output="noise_$(date +%Y%m%d_%H%M%S).csv" args+=(--output "$output") fi has_flag --bus-speed || args+=(--bus-speed 750) echo "=== capture -> $output ===" # Ctrl-C reaches the whole foreground process group. Trapping it here stops bash # killing the script, so logger.py can shut down cleanly and the analysis below # still runs. A no-op trap (not 'ignore') keeps the child's own handling intact. trap ':' INT python logger.py "${args[@]}" capture_rc=$? trap - INT # A non-zero logger exit covers both "aborted mid-capture" and "never started" # (no adapter, bad flag). Whether a usable file exists is what distinguishes # them, so check that before claiming anything about the data. if [[ ! -s "$output" ]]; then echo echo "Capture produced no data (exit $capture_rc); nothing to analyse." >&2 exit 1 fi if [[ "$capture_rc" -ne 0 ]]; then echo echo "Capture ended early (exit $capture_rc). Analysing what was recorded --" \ "it is valid up to that point." >&2 fi echo echo "=== plot ===" python plot.py "$output" plot_rc=$? echo echo "=== characterize ===" python characterize.py "$output" char_rc=$? echo echo "=== outputs ===" base="${output%.csv}" for f in "$output" "$base.png" "${base}_noise.png"; do [[ -f "$f" ]] && printf ' %-40s %8s\n' "$f" "$(du -h "$f" | cut -f1)" done # Non-zero if any stage failed, so this is usable from a scheduler. [[ $capture_rc -eq 0 && $plot_rc -eq 0 && $char_rc -eq 0 ]] || exit 1