3. Python environment setup

A CAE injury-report pipeline is only as reliable as the environment it runs in. Before a single solver result is parsed or a dashboard cell is colored, you need a Python installation that is reproducible, isolated from other projects, and equipped with the specific libraries that handle numerical arrays, tabular data, Excel output, and plotting. This chapter walks through building that environment from scratch, then wires the libraries into a small but complete data workflow so you can confirm everything works before the real CAE data arrives.

Choosing and Installing the Interpreter

For CAE post-processing, use a current stable CPython release — 3.11 or 3.12 are safe choices at the time of writing, since the scientific stack (NumPy, pandas, openpyxl, matplotlib) publishes prebuilt wheels for them on Windows and Linux. Avoid the very newest minor release for production work: binary wheels for compiled dependencies sometimes lag by weeks, and a source build of NumPy on a workstation without a configured compiler toolchain is a frustrating detour.

On Windows, download the official installer from python.org and, on the first setup screen, tick Add python.exe to PATH before clicking Install. This single checkbox prevents the classic "python is not recognized as an internal or external command" failure. On Linux, prefer the distribution package or pyenv; on macOS, the python.org installer or Homebrew both work. Verify the installation from a fresh terminal:

python --version
# expected: Python 3.12.x

python -c "import sys; print(sys.executable)"
# confirms which interpreter is actually on PATH

If the version prints but points at an unexpected path (for example a Microsoft Store stub or a conda base environment), resolve that now. A pipeline that silently runs under the wrong interpreter is one of the most common causes of "it works on my machine" discrepancies in report automation.

Isolating the Project with a Virtual Environment

Never install CAE libraries into the system interpreter. Create a dedicated virtual environment inside the project folder so that dependency versions travel with the code:

mkdir cae_injury_reports
cd cae_injury_reports
python -m venv .venv

# Windows (PowerShell)
.venv\Scripts\Activate.ps1

# Linux / macOS
source .venv/bin/activate

python -m pip install --upgrade pip

After activation the prompt is prefixed with (.venv). Everything installed from this point lands inside the project, and deleting the folder removes the environment cleanly. Record the exact dependency set in a requirements.txt so a colleague or a CI runner can rebuild it byte-for-byte:

numpy==1.26.4
pandas==2.2.2
openpyxl==3.1.2
xlsxwriter==3.2.0
matplotlib==3.8.4
scipy==1.13.0

Install with python -m pip install -r requirements.txt. Pinning versions matters more in CAE reporting than in many other domains because Excel formatting behavior and pandas dtype handling can shift between minor releases, and a dashboard that silently changes number formatting after an upgrade is hard to diagnose.

What Each Library Contributes

The workflow has four distinct jobs, and each maps to a well-established library. The table below summarizes the division of labor; the sections that follow show how they connect.

StageLibraryRole in the CAE workflow
Ingest & computeNumPyVectorized operations on nodal/element arrays, peak acceleration and HIC integrals
Tabulate & cleanpandasLoad CSV exports, merge run metadata, group by load case, compute summary statistics
Excel outputopenpyxl / XlsxWriterWrite formatted workbooks, conditional formatting, charts, freeze panes
FiguresmatplotlibTime-history plots and bar charts embedded in the report

A useful rule of thumb: use openpyxl when you need to read an existing template workbook and preserve its styling, and XlsxWriter when you are generating a dashboard from scratch and want rich native Excel charts and conditional formats. They cannot both write the same file, so pick one per output path.

Wiring the Workflow: A Minimal End-to-End Check

Before trusting the environment with real solver output, run a small synthetic dataset through every stage. The script below creates a fake acceleration time history, computes a peak value and a simple severity flag, writes a formatted Excel sheet, and saves a plot. It is deliberately short but exercises every library in the stack.

import numpy as np
import pandas as pd
import matplotlib
matplotlib.use("Agg")          # headless-safe backend for batch runs
import matplotlib.pyplot as plt

rng = np.random.default_rng(42)
t = np.linspace(0.0, 0.12, 1200)          # 120 ms impact window
a = 80 * np.sin(2 * np.pi * 45 * t) * np.exp(-t / 0.03)   # g, synthetic
peak_g = float(np.max(np.abs(a)))

df = pd.DataFrame({"time_s": t, "accel_g": a})
summary = pd.DataFrame([{
    "load_case": "SYN-01",
    "peak_accel_g": round(peak_g, 2),
    "severity": "HIGH" if peak_g > 60 else "LOW",
}])

with pd.ExcelWriter("report_check.xlsx", engine="xlsxwriter") as xl:
    summary.to_excel(xl, sheet_name="Summary", index=False)
    df.to_excel(xl, sheet_name="TimeHistory", index=False)

fig, ax = plt.subplots(figsize=(6, 3))
ax.plot(df["time_s"], df["accel_g"], color="#1f77b4")
ax.set_xlabel("Time (s)"); ax.set_ylabel("Acceleration (g)")
fig.tight_layout(); fig.savefig("accel_check.png", dpi=120)

print(f"peak = {peak_g:.2f} g, rows = {len(df)}")

Expected observable output: a console line reporting a peak near 80 g and 1200 rows, a report_check.xlsx containing two sheets, and a accel_check.png showing a decaying oscillation. If the script runs and those three artifacts appear, the environment is sound. The synthetic values are illustrative only — they are not measured crash data and should never be cited as such.

Run the check script from a clean shell with the virtual environment activated, not from inside an IDE that may have cached a different interpreter. IDE interpreter mismatches are the most frequent cause of "module not found" errors that disappear when you run the same file from the terminal.

Common Setup Failures and How to Read Them

Three symptoms account for most setup problems. ModuleNotFoundError after a successful install almost always means the package went into a different interpreter than the one running the script — check sys.executable and confirm the (.venv) prefix is present. PermissionError during pip install indicates you are writing to the system site-packages; activate the virtual environment instead of reaching for sudo. ImportError referencing a DLL on Windows usually points to a NumPy/SciPy wheel built against a different Python ABI; reinstalling with a matching pinned version resolves it.

The diagram below shows how the pieces connect and where each failure mode surfaces, so you can localize a problem to a specific stage rather than reinstalling everything.

CPython 3.12 on PATH .venv isolated packages requirements.txt pinned versions NumPy arrays, HIC pandas tables, grouping openpyxl / XlsxWriter Excel output matplotlib figures report.xlsx Summary + TimeHistory accel_check.png time-history plot Failure localization wrong interpreter → ModuleNotFoundError system install → PermissionError

Read the diagram left to right: the interpreter on PATH feeds the isolated environment, which is rebuilt from the pinned requirements file, which supplies the four libraries, which in turn produce the two output artifacts. The dashed callout on the right maps the three failure symptoms to the layer where they originate, which is the fastest way to decide whether to fix PATH, activation, or a package version.

Making the Environment Reproducible

Two habits keep the setup stable across machines. First, commit requirements.txt to version control and never edit it by hand without re-running the check script. Second, add a one-line guard at the top of the pipeline entry point that fails loudly if a required library is missing, rather than letting the error surface halfway through a batch run:

import importlib
for mod in ("numpy", "pandas", "openpyxl", "xlsxwriter", "matplotlib"):
    importlib.import_module(mod)
print("environment OK")

With the interpreter, virtual environment, pinned dependencies, and end-to-end check in place, the pipeline has a trustworthy foundation. The next stage — ingesting real solver exports — can now be developed against a known-good baseline, and any later anomaly can be attributed to the data or the code rather than to a misconfigured machine.