CoolFace
Datasetpublic

ppak10/Agentic-SLS-ASTM

Agentic-SLS-ASTM ASTM mechanical-test specimens (D638 tensile, D790 flex) printed on the Inova Mk1 SLS printer and pulled on an MTS / TestWorks Instron. Each row is a single specimen with full geometry, scalar results, stress–strain + raw DAQ curves, and — for SLS rows — FK references and an embedded snapshot of the upstream print profile from ppak10/Agentic-SLS-Database. Rows are self-contained for ML use: the full PrintProfile JSON is inlined, so features (material/energy… See the full description on the dataset page: https://huggingface.co/datasets/ppak10/Agentic-SLS-ASTM.

sourceHugging Facemitupdated 10d agoView on Hugging Face
0likes771downloads
Dataset Card

Agentic-SLS-ASTM

ASTM mechanical-test specimens (D638 tensile, D790 flex) printed on the Inova Mk1 SLS printer and pulled on an MTS / TestWorks Instron. Each row is a single specimen with full geometry, scalar results, stress–strain + raw DAQ curves, and — for SLS rows — FK references and an embedded snapshot of the upstream print profile from `ppak10/Agentic-SLS-Database`.

Rows are self-contained for ML use: the full PrintProfile JSON is inlined, so features (material/energy profile) and target (mechanical response) live on the same row.

python
from datasets import load_dataset
tensile = load_dataset("ppak10/Agentic-SLS-ASTM", "D638", split="train")
flex    = load_dataset("ppak10/Agentic-SLS-ASTM", "D790", split="train")
Figure style. All figures share one house style (ported from the `AdditiveLLM2-OA` figures): DM Sans typeface, framed axes with inward ticks, a light dashed grid, and dual PNG (dpi 1200) + vector PDF export. The SLS batches are colored by an ordered orange ramp (gold → deep brown, in print chronology, built around #F97415); the FormLabs PA12GF benchtop reference is drawn in a contrasting blue so it reads clearly as the external benchmark.

Batch clusters

Replaces the old overlaid composite (which, at 76–80 curves, was unreadable). Each specimen collapses to a single point at its stress–strain peak — x = strain at peak, y = ultimate strength — and each batch becomes a ±1 SD confidence ellipse (covariance-based) around its specimens' peak points. This carries the headline ultimate-strength number and shows how tightly each batch clusters, with none of the overlaid-curve clutter. (Peak is derived as max(stress) over the saved curve, not read from PeakStress — TestWorks often leaves that scalar null for D638 tensile.) Groups with fewer than 3 specimens draw a connecting segment or a bare marker instead of an ellipse.

D638 (tensile)D790 (three-point flex)
[image][image]

Regenerate with uv run scripts/plots/03_batch_clusters.py.

Per-batch detail

To read the actual stress–strain curves for one batch without cross-batch clutter, each batch (plus the FormLabs PA12GF reference) gets its own figure under `assets/batches/`{standard}_{batch}.png — with each specimen individually colored and keyed by sample_id in the legend. Two examples:

D638 Batch C (tensile)D790 Batch E (flex)
[image][image]

Regenerate with uv run scripts/plots/04_batch_details.py.

Broken-out controls & specimen types

Materials/geometries that don't belong on the batch comparison get their own axes. PLA/PETG filament controls (D638 only) print at much higher stress/strain than either PA12 material; the FormLabs Nylon 12 White control is a second, distinct reference material; and Batch M's 12 Type IV (narrow-section) tensile specimens have a different gauge geometry than its Type I dogbones.

PLA/PETG controls (D638 only — D790 has no filament controls; PLA in blue, PETG in teal):

[image]

FormLabs Nylon 12 White control:

D638 (tensile)D790 (three-point flex)
[image][image]

The D638 export is a raw load/extension curve with no gauge length in the file itself — strain/stress are derived using a user-confirmed 25mm extensometer starting length (gauge_length_mm set explicitly in 31_2026_07_23_tensile_nylon12white_fl.py, not read from the xlsx).

Batch M Type IV (narrow-section) tensile specimens, D638 only — each of the 12 specimens is individually labeled (1-6, 8-11, 13-14; specimen numbers 7 and 12 aren't part of this xlsx export, per the lab's own numbering) rather than grouped into one legend entry:

[image]

Regenerate with uv run scripts/plots/01_controls.py.

Batch averages (SLS Nylon 12 GF only)

One mean stress-strain curve per SLS batch, ± 1 sample standard deviation across specimens (shaded band), for our own Inova Mk1 SLS Nylon 12 GF prints plus the FormLabs PA12GF reference (in blue) — PLA/PETG and the Nylon 12 White control are excluded (their own figures). Each specimen is first trimmed at its stress peak (loading branch only), then linearly interpolated onto a common strain grid bounded by the shortest specimen's peak strain in that batch, so every point in the mean is backed by the same specimen count and no fracture-branch spike distorts the band. See scripts/plots/02_batch_averages.py for the full averaging method (including why one D790 specimen — a degenerate 3-point curve — is dropped from its batch's average).

D638 (tensile)D790 (three-point flex)
[image][image]

The same mean ± 1 SD banding is also rendered for the FormLabs Nylon 12 White control on its own (excluded from the figure above for the same reason as its raw-curve figure — see Composite stress–strain):

D638 (tensile)D790 (three-point flex)
[image][image]

Regenerate with uv run scripts/plots/02_batch_averages.py.


Configs

ConfigDescriptionFiles
D638 (default)Tensile specimens (ASTM D638 Type I, plus 12 Type IV specimens in batch M and Type IV Nylon 11 batches O/P/Q). 115 SLS (batches A–Q) + 3 PLA + 3 PETG + 5 FormLabs PA12GF + 5 FormLabs Nylon 12 White = 131 rows. Batches A–J/J_MB have Database FKs; K–Q don't yet (print jobs not backfilled).data/D638/*.jsonl (one row per file)
D790Three-point flex specimens (ASTM D790 Procedure A). 120 SLS rows (batches C–U; no O or S) + 5 FormLabs PA12GF + 5 FormLabs Nylon 12 White = 130 rows. Batches C–J/J_MB have Database FKs; K–U don't yet.data/D790/*.jsonl (one row per file)

One JSONL file per specimen — SLS rows are named after their sample_id (e.g. data/D638/A1.jsonl, data/D790/E10.jsonl); non-SLS controls use {material}_TSR{n}.jsonl (e.g. data/D638/PLA_TSR6.jsonl, data/D790/PA12GF_FL_TSR1.jsonl). Both configs share the same row schema and are produced by the per-session scripts under scripts/specimens/.

Specimens are labeled with a sample_id of the form {batch_label}{seq} (e.g. A1, C7), where the batch label identifies the print batch they came from. Batch labels are usually a single letter, but J / J_MB are the same 2026-07-06 print batch split by post-processing: J specimens were tested as-printed, J_MB specimens were media blasted before testing. The same sample_id may appear in both configs — C1 in D638 and C1 in D790 are different physical specimens that came from the same Batch C print. Batches O and P (2026-08-03) are the first use of Nylon 11 SLS powder in this dataset — two separate prints, tested only as ASTM D638 Type IV (Batch P also has D790 flex); Batch Q (2026-08-07) is a third Nylon 11 print, D638 Type IV only. Their seq follows each batch's own lab specimen numbering rather than starting at 1: Batch O is O10-O13, Batch P's D638 numbering skips P7 (the xlsx export's own Test Run 7 sheet is labeled "SAMPLE 8"), and Batch Q's numbering skips Q7 (physical specimen 7 broke — its xlsx tab is a "broken" placeholder), giving Q1-Q6, Q8-Q14.

Source Layout

source/
  2026_05_26/          # one folder per test session
    *.tsproj           # TestWorks project pointer
    *.xlsx             # TestWorks Excel export, one sheet per specimen
    TST1.Test/
      TestRuns/
        TSR{n}.TestRun/
          Data/DaqTaskActivity1.h5            # raw DAQ scans (10 Hz)
          AnalysisRuns/ANR1.AnalysisRun/
            persistent.h5                     # analyzed scalars + curves

Test sessions covered:

Session folderSpecimensStandardBatchSource print job (Database)
2026_05_26/5D638A2026-05-25 (d638_type1)
2026_06_01/5D638B2026-05-30 (d638type1engraved)
2026_06_03/7D638C2026-06-02 (d638type1engraved)
2026_06_08/5D638D2026-06-07 (d638type1engraved)
2026_06_10/Tensile Testing/5 SLS + 3 PLA + 3 PETGD638E (SLS only)SLS: 2026-06-07 (d638type1engraved)
2026_06_10/Batch C 3pt test/9D790C2026-06-02 (d790flexspecimen)
2026_06_10/Batch D 3pt test/8D790D2026-06-07 (d790flexspecimen)
2026_06_10/Batch E 3pt test/10D790E2026-06-07 (d790flexspecimen, same print as Batch D)
2026_06_16/Tensile FormLabs Samples/5 (PA12GF_FL)D638— (control, printed vertically)n/a — benchtop comparison filament
2026_06_16/Bending FormLabs Samples/5 (PA12GF_FL)D790— (control)n/a — benchtop comparison filament
2026_06_25/Tensile Data/5D638F2026-06-13 (d638type1engraved, Recycled Powder)
2026_06_25/Flexural Data/9D790F2026-06-13 (d790flexspecimen_shorter, Recycled Powder)
2026_06_26/Tensile/5D638G2026-06-09 (d638type1engraved, Cards)
2026_06_26/Flexural/4D790G2026-06-09 (d790flexspecimen_shorter, Cards)
2026_06_30/Tensile/ (TST1.Test)3D638H2026-06-24 (Recycled Powder, 2a3ba702 24mJ/mm)
2026_06_30/Tensile/ (TST2.Test)5D638I2026-06-25 (Recycled Powder, 60999faa 28mJ/mm)
2026_06_30/Flex 6-30/ (TST1.Test)5D790I2026-06-25 (Recycled Powder, 60999faa 28mJ/mm)
2026_06_30/Flex 6-30/ (xlsx only, no TestRuns folder)5D790H2026-06-24 (Recycled Powder, 2a3ba702 24mJ/mm)
2026_07_06/Tensile/4D638J (not media blasted)2026-06-27 (D790 and D638 and other objects, 2be9f3cd 32mJ/mm higher temp)
2026_07_06/Flex/2D790J (not media blasted)2026-06-27 (same as J tensile)
2026_07_08/Tensile/5D638J_MB (media blasted)same 2026-06-27 print as J
2026_07_08/Flex/2D790J_MB (media blasted)same 2026-06-27 print as J
2026_07_15/Tensile/5D638Knot yet in Database
2026_07_15/Tensile/6D638Lnot yet in Database
2026_07_15/Flexural/3D790Knot yet in Database
2026_07_15/Flexural/4D790Lnot yet in Database
2026_07_21/tensile/ (tensile_m.xlsx, Type I)5D638Mnot yet in Database
2026_07_21/tensile/ (tensile_m_t4.xlsx, Type IV)12D638Mnot yet in Database
2026_07_21/flex/5D790Mnot yet in Database
2026_07_23/tensile/5D638Nnot yet in Database
2026_07_23/flex/5D790Nnot yet in Database
2026_07_23/tensile/ (tensile_nylon12white_fl.xlsx)5 (NYLON12WHITEFL)D638— (control)n/a — benchtop comparison material
2026_07_23/flex/ (flex_nylon12white_fl.xlsx)5 (NYLON12WHITEFL)D790— (control)n/a — benchtop comparison material
2026_08_03/Tensile/ (nylon11_batch1.xlsx, Type IV)4D638Onot yet in Database
2026_08_03/Tensile/ (nylon11_batch2.xlsx, Type IV)11D638Pnot yet in Database
2026_08_03/Flex/ (nylon11_flex2.xlsx)9D790Pnot yet in Database
2026_08_07/Tensile/ (ASTM_D638_type_4.xlsx, Type IV)13D638Qnot yet in Database
2026_08_08/ (ASTM Type 4.xlsx, Type IV)14D638Rnot yet in Database
2026_08_17/ (tensile.xlsx, Type IV)7D638Snot yet in Database
2026_08_18/ (tensile.xlsx, Type IV)14D638Tnot yet in Database
2026_08_19/ (tensile.xlsx, Type IV)14D638Unot yet in Database
2026_08_23/ (Q.xlsx)10D790Qnot yet in Database
2026_08_23/ (R.xlsx)10D790Rnot yet in Database
2026_08_23/ (T.xlsx)10D790Tnot yet in Database
2026_08_23/ (U.xlsx)10D790Unot yet in Database

TSR11 in Batch E 3pt test/ exists on disk but has empty Data/ (aborted run, no DAQ scans) and no corresponding xlsx sheet — it is excluded from the JSONL. TSR4 in Batch I flex (Flex 6-30/) is excluded for a similar reason: test_end_reason is "Test Stopped" rather than a detected break. Batch Q physical specimen 7 broke — its xlsx tab holds only the text "broken" — so it too is excluded, and Batch Q's sample_ids skip Q7.

Batches K through U (2026-07-15 through 2026-08-19) have no raw TestRuns//h5 folders at all — only TestWorks xlsx exports were handed off, so all of these rows are xlsx_only (see scripts/specimens/_lib.py's build_row_from_xlsx). Batch M's 12 Type IV specimens are a narrow-section ASTM D638 geometry (6mm × 4.15mm vs Type I's 12.8mm × 3.1mm) from the same print as its 5 Type I specimens — same batch_label, distinguished by astm.type. Batches O, P, Q, and R are entirely Type IV as well, but of a different SLS powder (Nylon 11, first used in this dataset in these batches — see notes on their rows) rather than a geometry variant of an existing batch, so they're excluded from the batch-average/cluster figures the same way Type IV rows always are, but get their own per-batch detail figures rather than sharing Batch M's combined Type IV figure (see scripts/plots/_lib.py's TYPE_IV_DEDICATED_BATCHES). Batch Q's and R's exports are more minimal still: each sheet holds only the already-analyzed strain/stress curve with no geometry (Width/Thickness) or scalar-metric columns, so those rows' geometry and metrics are null — except peak_stress_pa, which the extract derives from the curve itself (max stress; see derive_d638_peak in scripts/specimens/_lib.py) — while curves.strain/curves.stress_pa are populated (consumers re-derive modulus from the curve). The FormLabs Nylon 12 White tensile control's xlsx export is a raw load/extension curve with no gauge length in the file — strain/stress_pa are derived using a user-confirmed 25mm extensometer gauge length declared in the script itself (see Composite stress–strain above); its flex counterpart derives normally via the D790 chord formulas. The Batch Q, R, T, and U flex specimens (D790, tested 2026-08-23) are curve-only in the opposite way: each sheet holds only the raw load-deflection trace (col A mm deflection, col B N load) with no Width/Thickness, so the D790 chord formulas have no geometry to work from — curves.strain/curves.stress_pa and all metrics (including flexural modulus) are null, and only curves.extension_m/curves.load_n are populated. Consequently these batches do not appear on the D790 stress–strain figures (there is no derivable stress/strain to plot until specimen geometry is supplied).

Batch H's 5 flex specimens (2026_06_30/Flex 6-30/) don't have a raw TestRuns folder — it looks like it was overwritten when the Batch I TestWorks project reused the same default TST1.Test name in the same directory. flex_h_6.30.xlsx is the only surviving record, so those 5 rows are built from that xlsx export alone: the raw load/extension curve (curves.load_n/curves.extension_m) comes from its embedded columns, but curves.strain/curves.stress_pa are empty and several metrics fields (modulus_pa, strain_at_peak, strain_at_yield, etc.) are null, since deriving them requires the support span, which this export doesn't surface. See each row's notes field.

Row shape

json
{
  "sample_id": "A1",
  "batch_label": "A",
  "specimen_id": "2026_05_26/TSR1",
  "test_date": "2026-05-26",
  "session_folder": "2026_05_26",
  "test_run_name": "TSR1",
  "specimen_index": 1,

  "material_class": "SLS",
  "astm": { "standard": "D638", "type": "Type I", "year": "2022" },
  "test_end_reason": "Break Detected",

  "geometry": {
    "width_mm": 12.9, "thickness_mm": 3.2,
    "area_mm2": 41.28, "gauge_length_mm": 103.0
  },

  "job_id":           "ba17a5ba-a5f6-4d60-8832-b6c13a2dfa67",
  "print_date":       "2026-05-25",
  "print_profile_id": "52715389-d580-4be9-9194-ed300bdf911b",
  "object_hash":      "E4251951376A82B4303394F832996A2E9883EAB0",
  "session_id":       null,

  "print_profile_snapshot": { "...full PrintProfile JSON..." },

  "metrics": {
    "modulus_pa": 341090566.27,
    "peak_load_n": null, "peak_stress_pa": null, "strain_at_peak": null,
    "load_at_break_n": null, "stress_at_break_pa": null, "strain_at_break": null,
    "energy_to_break_j": null,
    "yield_stress_pa": null, "strain_at_yield": null
  },

  "curves": {
    "time_s":      [/* N */],
    "extension_m": [/* N */],
    "load_n":      [/* N */],
    "strain":      [/* N */],
    "stress_pa":   [/* N */]
  },

  "notes": "",

  "source_paths": {
    "persistent_h5": "source/2026_05_26/TST1.Test/TestRuns/TSR1.TestRun/AnalysisRuns/ANR1.AnalysisRun/persistent.h5",
    "daq_h5":        "source/2026_05_26/TST1.Test/TestRuns/TSR1.TestRun/Data/DaqTaskActivity1.h5",
    "xlsx":          "source/2026_05_26/tensile_testing_5.26.xlsx",
    "xlsx_sheet":    "Sheet1"
  }
}

Notes on results

  • sample_id and batch_label are null for non-SLS control rows (PLA, PETG, FormLabs PA12GF — they didn't come from an SLS print batch). Filter on material_class == "SLS" to get the rows that link back to Database.
  • Batches E–I currently have job_id, print_profile_id, object_hash, and print_profile_snapshot all null — their source print jobs aren't in Database yet. The mechanical results are still valid.
  • metrics.peak_* and metrics.*_at_break are often null in the D638 tensile rows because TestWorks did not detect a peak/break point on those runs. D790 flex rows have these fields more consistently populated. The curves.stress_pa / curves.strain arrays are populated regardless, so consumers can re-derive peak/break with their own criteria.
  • Batch H's flex rows (data/D790/H1.jsonlH5.jsonl) are the one exception: their raw TestRuns folder is missing (see Test sessions covered above), so they're built from the TestWorks xlsx export alone. curves.strain/curves.stress_pa are empty and most metrics fields are null for these 5 rows specifically — check notes on a row before assuming a null metric means TestWorks failed to detect it.
  • notes is a free-text field, empty for most rows; it's used to flag exceptions like the Batch H flex sourcing above or the FormLabs vertical-print orientation.
  • metrics.modulus_pa matches the kN/mm² value in the TestWorks xlsx after unit conversion (e.g. tensile 0.341 kN/mm² → 3.41 × 10⁸ Pa). For D790, TestWorks computes the flexural modulus via the 3-point-bend formula directly; values may look unintuitive compared to the tensile modulus.
  • DAQ scans are in SI units (m, N, s); stress is Pa and strain is dimensionless.
  • For D790, geometry.gauge_length_mm is always null (gauge length is a tensile concept; flex uses support span which is not surfaced).