tud_lbm.io.plotting.regime_map_plot =================================== .. py:module:: tud_lbm.io.plotting.regime_map_plot .. autoapi-nested-parse:: Aggregate Ca(t) regime classification across many run directories. Reads `simulation_data.csv` (building it on demand if missing) for every run directory listed in a plain-text file, classifies each run into pinning/viscous/inertial/unknown (see :mod:`tud_lbm.io.analysis.accelerations.regime_classification`), and plots the result as Bo_parallel vs Oh — the regime map. Classes ------- .. autoapisummary:: tud_lbm.io.plotting.regime_map_plot.RunRegimeEntry Functions --------- .. autoapisummary:: tud_lbm.io.plotting.regime_map_plot.parse_run_dir_list tud_lbm.io.plotting.regime_map_plot.process_run_dir tud_lbm.io.plotting.regime_map_plot.plot_regime_map tud_lbm.io.plotting.regime_map_plot.build_regime_map Module Contents --------------- .. py:class:: RunRegimeEntry One classified run, ready to be plotted on the regime map. .. py:attribute:: run_dir :type: pathlib.Path .. py:attribute:: label :type: str .. py:attribute:: bo_parallel :type: float .. py:attribute:: oh :type: float .. py:attribute:: regime :type: str .. py:function:: parse_run_dir_list(txt_path: str | pathlib.Path, allowed_roots: collections.abc.Sequence[str | pathlib.Path] = ()) -> list[pathlib.Path] Parse one run-dir path per non-blank, non-``#`` line. Lines may be shell-quoted/escaped (e.g. copied from a terminal listing of directory names containing spaces or special characters); such quoting is stripped and backslash escapes are resolved before building the path. This applies whether or not the line is wrapped in quotes — shell tab-completion commonly emits backslash-escaped, *unquoted* lines (e.g. ``\$Bo_\\parallel\ \=\ 0.60\;\ Oh\ \=\ 0.30\$``). A line is only treated as escaped if it contains a backslash before a shell metacharacter (space, ``$``, ``;``, ``=``, a quote, or another backslash) — a lone literal backslash that is simply part of the directory name (e.g. ``\parallel``) is left untouched. Each line is treated as exactly one path, even if it contains (escaped or unescaped) whitespace — word-splitting would silently truncate paths like ``$Bo_\\parallel = 0.60; Oh = 0.30$`` at the first space. Every entry (relative or absolute) must resolve inside at least one trusted root: ``BASE_RESULTS_DIR`` (this project's default results location) plus any extra directories passed via ``allowed_roots``. An entry outside all of them (e.g. a relative ``..`` escape, or an absolute path pointing somewhere untrusted) is rejected with :class:`ValueError`. Unlike the list file's own directory, ``allowed_roots`` are supplied directly by the caller rather than parsed from the list file's content, so they form a real trust boundary rather than one derived from the same untrusted text being validated (see SonarQube rule ``pythonsecurity:S6549`` — a canonicalized path is only "sanitized" if checked against a fixed, independently-supplied root). A directory name containing a literal backslash (as in the ``\parallel`` example above) can only be created on a POSIX filesystem — Windows always treats ``\`` as a path separator, so such a name can never exist as a single path component there. On a Windows host such an entry is instead silently split into nested path components like any other Windows path; this function does not probe the filesystem to disambiguate that case, since doing so on unvalidated, user-controlled path text would make file existence itself an oracle. Callers that hit an unexpectedly missing run directory on Windows should check the list file for a backslash that was meant as a literal character rather than a path separator. ``txt_path`` itself (which may originate from an untrusted CLI argument, e.g. when this tool is driven by an external or automated caller) is resolved to a canonical, absolute path and confirmed to be an existing regular file *before* anything is read from it, so a directory, device file, or nonexistent path is rejected with :class:`ValueError` up front rather than reaching the filesystem read in an unvalidated state. .. py:function:: process_run_dir(run_dir: pathlib.Path, *, smoothing: tud_lbm.io.analysis.accelerations.Smoothing = 'raw') -> RunRegimeEntry | None Classify one run directory, or return ``None`` (with a warning) when unusable. .. py:function:: plot_regime_map(entries: list[RunRegimeEntry], out_path: str | pathlib.Path) -> pathlib.Path Scatter Bo_parallel (x) vs Oh (y), grouped by regime. .. py:function:: build_regime_map(txt_path: str | pathlib.Path, allowed_roots: collections.abc.Sequence[str | pathlib.Path] = (), out_dir: str | pathlib.Path | None = None, *, smoothing: tud_lbm.io.analysis.accelerations.Smoothing = 'raw') -> pathlib.Path | None Classify every run listed in ``txt_path`` and save the regime map. ``allowed_roots`` are additional trusted directories (beyond the default results root) that every run-dir entry must resolve within; see :func:`parse_run_dir_list`. ``smoothing`` controls the acceleration curve used for peak detection in each run's diagnostic plot (see :func:`tud_lbm.io.analysis.accelerations.acceleration_analysis.compute_acceleration`). Returns the path to ``regime_map.png``, or ``None`` if no run produced a usable entry.