gcode_reader.emulate.diagnostics ================================ .. py:module:: gcode_reader.emulate.diagnostics .. autoapi-nested-parse:: Sanity checks for AdditivePart inputs and derived state. Surfaces common silent-failure modes that otherwise propagate as zero-valued or oddly-shaped statistics: - ``check_extrusion``: extrusion did not register (often a wrong-machine config), no ``is_depositing`` rows, or zero depositing distance/volume. - ``check_geometry``: degenerate bounding-box dimensions, suspicious aspect ratios. - ``check_layer_grouping``: non-monotonic layer ordering, misaligned ``layer_normal``, coordinate-resolution fragmentation, or outlier moves at unrelated heights (the failure mode that motivated the original layer-grouping fix). - ``check_additive_part``: runs all of the above plus cross-cutting checks (1 layer despite measurable build extent, implausible implied layer thickness, zero deposition length/volume despite depositing rows). Each check returns a dict with the raw numbers and a list of human-readable ``warnings``. The ``format_*_report`` helpers render those dicts as text. Functions --------- .. autoapisummary:: gcode_reader.emulate.diagnostics.check_additive_part gcode_reader.emulate.diagnostics.check_extrusion gcode_reader.emulate.diagnostics.check_geometry gcode_reader.emulate.diagnostics.check_layer_grouping gcode_reader.emulate.diagnostics.format_additive_part_report gcode_reader.emulate.diagnostics.format_layer_grouping_report Module Contents --------------- .. py:function:: check_additive_part(part) -> dict Run the full battery of sanity checks on an AdditivePart. Combines ``check_extrusion``, ``check_geometry``, and ``check_layer_grouping``, plus a few cross-cutting checks (layer count plausibility, deposition length). Returns a dict with one sub-dict per check and a flat ``warnings`` list that aggregates every warning, prefixed by which check raised it. .. py:function:: check_extrusion(df: pandas.DataFrame) -> dict Verify that extrusion data is present and non-trivial. A common silent failure mode is configuring the wrong machine/extruder, in which case ``deposited_volume`` stays at zero and ``is_depositing`` is empty even though the G-code clearly contains print moves. Downstream stats (layer count, volume, mass, deposition bounds) then come back as zero or missing with no error raised. Returns a dict with: - ``has_is_depositing_col``, ``has_deposited_volume_col`` - ``n_depositing_rows``: number of rows tagged ``is_depositing == True`` - ``depositing_fraction``: fraction of rows that are depositing - ``total_deposited_volume``: sum of the ``deposited_volume`` column - ``n_depositions``: distinct ``deposition_id`` values among depositing rows - ``warnings``: human-readable flags .. py:function:: check_geometry(part) -> dict Sanity-check the deposition bounding box and overall geometry of an AdditivePart. Flags degenerate dimensions (zero extent in any axis), unusually thin parts (aspect ratio > 1000), and missing bounds. A zero extent in the build direction is often a tell-tale of extrusion not registering or of a single-layer parse. Returns a dict with: - ``bounds``: ``((xmin, ymin, zmin), (xmax, ymax, zmax))`` or None - ``dims``: ``(dx, dy, dz)`` or None - ``aspect_ratio``: max(dim) / min(positive dim), or inf if any dim is zero - ``warnings`` .. py:function:: check_layer_grouping(df: pandas.DataFrame, layer_index_col: str = 'layer_index', layer_height_col: str = 'layer_height', sliver_count: int = 5, max_gap_ratio: float = 10.0) -> dict Compute layer-grouping sanity checks for a tagged G-code DataFrame. :param df: DataFrame with ``layer_index`` and ``layer_height`` columns (the output of ``insert_layer_indices_gcode_dataframe``). :param layer_index_col: Column name for layer indices. :param layer_height_col: Column name for projected heights. :param sliver_count: A layer with fewer than this many rows is flagged as a sliver. :param max_gap_ratio: Gaps between consecutive layers larger than ``max_gap_ratio * median_gap`` are flagged as outliers (e.g. a probe move at an unrelated height). :returns: - ``n_layers``: number of distinct layer indices - ``monotonic``: True if ``layer_index`` is in ascending physical-height order - ``rank_correlation``: Pearson correlation between layer_index and physical height (near +1 = healthy, near 0 = scrambled ordering) - ``min_gap``, ``median_gap``, ``max_gap``: gaps between consecutive layer heights - ``min_spread``, ``median_spread``, ``max_spread``: within-layer height spread (large values relative to gap suggest the normal is misaligned) - ``n_slivers``: number of layers with fewer than ``sliver_count`` rows - ``n_outlier_gaps``: number of gaps larger than ``max_gap_ratio * median_gap`` - ``per_layer``: DataFrame indexed by layer_index with min/max/count/spread columns - ``warnings``: list of human-readable strings flagging anomalies :rtype: A dict with summary statistics and a ``per_layer`` DataFrame. Keys .. py:function:: format_additive_part_report(diagnostics: dict) -> str Render the output of ``check_additive_part`` as a human-readable string. .. py:function:: format_layer_grouping_report(diagnostics: dict) -> str Render the output of ``check_layer_grouping`` as a human-readable string.