Add T-3_01 Sobol batch print key (ID-to-spec mapping + as-printed .3mf) - #102
Add T-3_01 Sobol batch print key (ID-to-spec mapping + as-printed .3mf)#102sgbaird wants to merge 15 commits into
Conversation
…sual key The .3mf uploaded in issue #98 names each plate with its print ID and carries one Sobol specimen per plate, recovering the print-to-parameters mapping needed for parsing drop data. Includes the batch design table from PR #35 (32addaf) and flags the Spec 08 official-print discrepancy (dea4ls per .3mf plate label vs bag26v per issue comment). Co-authored-by: Marcus Madsen <265197858+me-madsen@users.noreply.github.com>
|
@claude summarize where we left off from the issue |
|
Claude finished @sgbaird's task in 1m 5s —— View job Where we left off on #98 (T-3_01 Prints)
Printing: completeAll 9 Sobol specimens plus the S0 reference prism now have acceptable-to-test prints (announced 8/19). Documented IDs, mapped to specs via the plate names in the as-printed .3mf:
This PR (#102) commits that key to Testing: campaign underway (tracked in PR #86, not #98)The drop campaign started 8/19 (60 inch drop, 1/2 inch polyurethane mat, 101 drops per specimen, 3 slow-motion videos each). As of the 8/21 analysis on PR #86, 8/9 specimens (942 drops) are analyzed with a BO-ready campaign summary, and the mass-variation question was answered there (the constant-mass constraint holds solid CAD volume constant, not printed grams, so PLA infill vs. near-solid TPU makes printed mass vary by design). BO implementation is with @sgbaird in a separate thread. Open items on #98
|
|
@claude bring in the BO script for ingesting the results from the Sobol sampling #86 which would have been run in #35 I think. Use Honegumi (pip install and also the online tutorials) with "existing data" and "batch", and "fully Bayesian" and "multi-objective" and "visualization" (assuming there were actually multiple objectives at this stage based on the data and discussions in #59 #60 #94 #97 #99). Ingest the results, 8 so far, attaching that as existing data, and set it up to return and record the next suggested experiments. Send a link to the file so I can review it. |
|
Claude finished @sgbaird's task in 15m 37s —— View job Honegumi SAASBO campaign script: 8 results ingested, round-2 batch suggested ✅
The file to review
Choices you'll want to sanity-check
Round-2 suggestions (batch of 9, recorded to
|
| trial | R (mm) | H (mm) | twist (°) | strut Ø (mm) | cable Ø (mm) | pred. t180 | pred. e_rebound |
|---|---|---|---|---|---|---|---|
| 10 | 25.0 | 60.0 | 40.0 | 12.0 | 3.0 | 0.905 ± 0.089 | 0.033 ± 0.017 |
| 11 | 25.0 | 60.0 | 80.0 | 12.0 | 5.5 | 0.903 ± 0.083 | 0.036 ± 0.016 |
| 12 | 40.0 | 60.0 | 80.0 | 12.0 | 5.5 | 0.885 ± 0.084 | 0.045 ± 0.018 |
| 13 | 25.0 | 84.3 | 40.0 | 12.0 | 5.5 | 0.958 ± 0.082 | 0.025 ± 0.018 |
| 14 | 25.0 | 60.0 | 80.0 | 8.2 | 3.0 | 0.942 ± 0.048 | 0.032 ± 0.011 |
| 15 | 25.0 | 60.0 | 62.8 | 12.0 | 3.0 | 0.884 ± 0.069 | 0.037 ± 0.014 |
| 16 | 40.0 | 110.0 | 40.0 | 12.0 | 5.5 | 0.984 ± 0.079 | 0.026 ± 0.017 |
| 17 | 40.0 | 60.0 | 40.0 | 12.0 | 3.0 | 0.890 ± 0.085 | 0.046 ± 0.016 |
| 18 | 40.0 | 60.0 | 40.0 | 12.0 | 5.5 | 0.915 ± 0.093 | 0.038 ± 0.018 |
The batch leans hard into thick struts (8 of 9 at the 12 mm bound; 6lhxfy's 10.9 mm strut was the standout) and short prisms (7 of 9 at H = 60), spreading across the twist/cable/R dimensions where the SAAS model is uncertain. Boundary-seeking is expected for qNEHVI with 7 points in 5D; if 12 mm struts are unprintable or the corners look too aggressive for a physical batch, that's a bounds/constraint conversation before printing.
Everything committed (4e26bb2)
bo/t3_prism_bo_campaign.py— the script (runs in ~5.5 min on the Actions runner)bo/t3-prism-bo-batch-drop-results.csv— snapshot of PR Add drop-test protocol, Edison synthesis, and first-data analysis #86'scampaign_summary.csv(branch commit642b8c0) so the ingest input is on this branchbo/t3-prism-bo-suggestions-round1.csv— the recorded suggestions abovebo/t3-prism-bo-ax-client-round1.json— full AxClient state for reproducibility/warm-startbo/figures/t3-prism-bo-round1-pareto.png— the figure abovebo/README.md— updated with provenance and usage
Not done / for later: re-run once amdjwm is identified and the 9th specimen lands (one command: python bo/t3_prism_bo_campaign.py --round 2); objective thresholds were left to Ax's inference (it chose t180 ≤ 1.023, e_rebound ≤ 0.053); no manufacturability constraints (envelope ≤ 250 cm³, cable-bridge check) are wired into the acquisition yet, since round 1 printed violating designs anyway.
• Branch
…suggest round-2 batch Multi-objective (t180, e_rebound), fully Bayesian, batch, existing-data Honegumi template adapted for the physical campaign: Sobol init step dropped (PR #35 batch was the init), results ingested from the PR #86 campaign_summary.csv snapshot, specs 03/06/07 attached as pending trials, amdjwm skipped until its spec mapping is resolved. Records 9 suggested base-space designs with posterior predictions, the AxClient state, and a Pareto + parameter-space figure. Co-authored-by: Sterling G. Baird <45469701+sgbaird@users.noreply.github.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@claude verify this with Edison scientific. Socratic method or something? Whatever you did before where you didn't just ask it to confirm or deny |
|
Claude encountered an error after 19m 42s —— View job Verifying the BO objectives claim with Edison Scientific
What Edison is being asked, without a confirm/deny framing: Section A (Socratic, data-only): pick your own objectives, decide single vs multi-objective, and state the noise magnitude you'd hand a GP, before seeing our choice. Then attack sections: B) what --- • Branch |
|
@claude make sure to account for the fact that the actual mass is different for each print in terms of the objectives (and therefore the BO suggestions) |
|
Claude encountered an error after 14m 53s —— View job Per-print mass now enters the objectives and the suggestions ✅
What changed and whyThe mass concern is real in the data: corr(mass, t180) = 0.83 across the 7 mapped articles (masses 18.50 to 22.04 g, CV 5.9%). Three changes in
Regenerated round-2 batch (
|
| trial | R | H | twist | strut Ø | cable Ø | pred t180 | pred e_reb (mJ) | pred mass (g) |
|---|---|---|---|---|---|---|---|---|
| 10 | 25 | 60 | 80 | 12.0 | 3.0 | 0.873 ± 0.053 | 11.3 ± 4.3 | 18.3 ± 1.2 |
| 11 | 40 | 60 | 80 | 12.0 | 5.5 | 0.885 ± 0.075 | 12.2 ± 5.7 | 19.4 ± 1.7 |
| 12 | 25 | 60 | 40 | 12.0 | 3.0 | 0.926 ± 0.095 | 9.9 ± 5.0 | 19.8 ± 2.1 |
| 13 | 25 | 60 | 80 | 7.4 | 3.0 | 0.948 ± 0.046 | 8.3 ± 3.2 | 19.4 ± 1.1 |
| 14 | 25 | 60 | 40 | 12.0 | 5.5 | 0.953 ± 0.094 | 9.0 ± 5.6 | 20.5 ± 2.0 |
| 15 | 40 | 60 | 40 | 12.0 | 3.0 | 0.905 ± 0.091 | 13.0 ± 5.1 | 20.1 ± 1.9 |
| 16 | 25 | 60 | 80 | 12.0 | 5.5 | 0.910 ± 0.073 | 10.1 ± 5.2 | 19.2 ± 1.6 |
| 17 | 40 | 110 | 80 | 12.0 | 5.5 | 0.955 ± 0.071 | 10.0 ± 5.3 | 19.8 ± 1.6 |
| 18 | 25 | 60 | 80 | 6.0 | 5.5 | 0.987 ± 0.066 | 8.4 ± 4.3 | 20.5 ± 1.6 |
Versus the pre-mass-aware batch: still short prisms (8/9 at H = 60) and mostly 12 mm struts (7/9), but the batch now leans high-twist (5/9 at 80° vs 3/9 before, chasing 6lhxfy's 77.4°) and probes two mid/thin struts (7.4 and 6.0 mm) it previously ignored, because the energy objective values the low-rebound corner that bpx68c/9hhbkp occupy. On the mass-aware Pareto front, 6lhxfy is still the best attenuator, but its rebound-energy penalty (13.9 mJ, worst in the batch even at the lightest mass) is now explicit, and the S0 reference bpx68c anchors the low-energy end at 6.2 mJ.
Also updated: bo/README.md, bo/t3-prism-bo-ax-client-round1.json (snapshot now carries the mass metric). Spec 08 enters as bag26v at 21.42 g (the tested article); amdjwm is still skipped, and now needs a mass as well as a spec mapping before it can be attached. The Edison verification of the objectives claim (previous comment) is running separately; note its claim under test predates this rename (e_rebound fraction vs e_reb_mJ), so its verdict will speak to the framing, not the exact column.
--- • Branch
Task 3e398131: Edison derives its own objective set from the per-drop campaign data before reading ours, then attacks the three legs of the hand-off claim (t180+e_rebound objective pair, the n=8 trade-off/Pareto framing, and the per-drop-SEM noise model that ignores the ~2% print floor). Bundle: 23 files across three branches (per-drop metrics, series tables, analysis doc+script, print-defect floor study, #97 energy review, BO script). Follows the d9092c5a precedent from PR #86. Co-authored-by: Sterling G. Baird <45469701+sgbaird@users.noreply.github.com>
…_g tracking metric, regenerated round-1 suggestions Co-authored-by: Sterling G. Baird <45469701+sgbaird@users.noreply.github.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
@claude nice plot on the left. Let's use that. We don't need the parallel coordinates one on the right. For the one on the left: make a presentation-ready version of this. Increase font size. Make the unique IDs gray (de-emphasize). No need for the masses. Get me links to the images for the ones on the Pareto front. Put the legend outside of the plot. For the axes, we only need 6 to 14 and 0.8 to 1.1 (or similar) for the axes ticks and we don't need the gridlines. Remove the "objective space" title. |
|
Claude finished @sgbaird's task in 4m 53s —— View job Presentation-ready Pareto figure ✅
Full size: What changed
Two things worth knowing. The front drawn is now the non-dominated set of the observed points rather than Ax's model-predicted front. For round 1 those pick out the same three articles, and plotting observed points means every labeled marker is a physical specimen you can hold up. And the script gained python bo/t3_prism_bo_campaign.py --plot-onlyMass has not left the analysis: it is still inside Photos of the three Pareto-front articles
Left to right: Not done: the round-2 suggestions themselves are unchanged (this was a restyle, not a re-run), and the Edison verification of the objectives claim is still pending from the earlier comment. |
…print-ID labels, legend outside, --plot-only redraw Drops the parallel-coordinates panel and both titles, removes the mass annotations, raises font sizes, moves the legend outside the axes, sets 0.8-1.1 / 6-14 ticks and removes the gridlines (PR #102 review). The Ax imports move into main() so --plot-only redraws the figure from the recorded CSVs with only pandas and matplotlib, no model refit and no change to the recorded round-2 suggestions. Co-authored-by: Sterling G. Baird <45469701+sgbaird@users.noreply.github.com>
|
@claude #102 (comment), y-axis should be horizontal |
|
Claude finished @sgbaird's task in 1m 3s —— View job Horizontal y-axis label ✅
Full size: The label is now horizontal and parked above the y-axis, left-aligned to the axis line, rather than rotated 90°. Rotating in place would have made a two-line label spill into the tick numbers, so Nothing else moved. Same data, same round-2 suggestions, same tick range and legend placement.
|
Co-authored-by: Sterling G. Baird <45469701+sgbaird@users.noreply.github.com> Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Note for us for later (after next week probably), we'll want to adjust the BO script to keep the intended mass constant based on actual infill, you'll probably need to use the bambu lab CLI slicer to check what this actually is. We'll still keep measuring the mass and keeping the objectives normalized by mass. Noting that this requires a special kwarg to be set somewhere within Ax to allow for points outside the design space to be brought in for fitting, even though they are outside the constraints of the search space. A highly thorough search through Ax GitHub would show where this is. Probably something where I've commented on (searching @claude comment on above |
|
Claude finished @sgbaird's task in 3m 42s —— View job Notes on the constant-intended-mass plan
Agreed on all three parts, and the ordering matters: the slicer work has to land before the BO change, because the search space you generate under is only meaningful once the mass constraint is the one you actually intend. 1. What "constant intended mass" changesToday the constraint is constant solid CAD volume, which is not constant grams. PLA struts print at roughly 57% effective density (infill plus walls), TPU cables print near solid, and the PLA:TPU volume split moves with strut diameter, cable diameter, R and H. That is exactly why round 1 spans 18.50 to 22.29 g (CV 5.9%) with corr(mass, t180) = 0.83. So a slice of the projection that "held mass constant" was really holding a proxy constant, and the objectives partly rank designs by how many grams they happen to carry. The fix is to make the projection solve for the scale factor such that
where the (a) Calibrate once, then no slicer in the loop. We already have the paired dataset: the as-printed project (b) Slicer in the loop, root-finding the scale factor per candidate. Exact, but seconds to tens of seconds per candidate and a hard dependency on a working headless slicer. Only worth it if (a)'s residuals exceed the 0.457 g print-to-print scatter we measured from the spec-08 triplicate, in which case the model is not good enough to trust anyway. CLI mechanics, for whoever picks this up: Two things that will bite on the calibration if we are not careful. Flush and prime tower: this is a multi-material H2D plate, so a real fraction of extruded filament is purge, and it is reported in the same totals. Per-object mass has to exclude it or every prediction runs high. And flow calibration bias: slicer grams are an estimate from extruded volume, so expect a few percent systematic offset against the scale. The regression absorbs it, which is another argument for (a) over (b). 2. Objectives stay normalized by measured massAgreed, and that is already the shape of the current script: One consequence worth writing down now so nobody over-reads it later: once intended mass is constant, the mass channel narrows from 3.8 g of design-driven spread down to roughly the 0.46 g print scatter. That is good (it is the point), but it means 3. The Ax kwarg, and the part it does not solveFound it, plus your own comments on the thread. Three caveats before we copy that forward:
The bigger risk here is not bounds, it is definitions. If we keep the same five base coordinates and only change the projection, round-1 points stay nominally in design while the map from coordinates to physical article silently changes underneath them, and no Checklist for when we pick this up
Nothing committed this round: this is a note for later, so I only commented. Say the word if you want the checklist parked in |
|
@claude I just made the following:
Update your code to mimic this, since we'll need a later figure that shows what the new Pareto front is after running the next batch, and showing what the predicted vs. actual was (we'll have the orange diamonds shift to the actual measured in a linear path and convert themselves to unfilled black circles), which I'd like you to prototype briefly (noting this is dummy data! We haven't gotten those new measurements yet) |
|
Claude finished @sgbaird's task in 7m 31s —— View job Figure restyled to your version, plus a round-2 prototype ✅
The restyled round-1 figureFull size: What I copied from yours:
One thing I did differently from a literal copy. Your figure has hand-placed ID labels; I put a greedy declutterer in ( Round-2 prototype: predictions travel to measurementsDummy data. Nothing in round 2 has been printed or dropped. The "measured" points are draws from the model's own posterior for the suggested designs, at 0.3 sd (a full-sd draw scatters the batch clean off the panel, which would make the prototype about the noise rather than the layout). Full size: The grammar, exactly as you described it:
Draw it with: python bo/t3_prism_bo_campaign.py --prototype-next-roundWhen the real numbers land, Two honest limits of the prototype, both from the dummy data rather than the code. Six of nine synthetic points land on the new front, which is optimistic: a real round rarely sweeps the front like that, and the callouts sit where they do because of where these fake points fell. And Also updated: Nothing else moved: same round-1 data, same round-2 suggestions, same objectives. Still outstanding from earlier in this thread: the Edison verification of the objectives claim (task |
…er analogue, sim-vs-measured correlation study, repeat-seed BO campaign - print_infill.py: sub-100% PLA infill (0.565 solid fraction, refit 0.556 from the committed CSVs), effective strut density/modulus (Gibson-Ashby bracket), CAD-vs-model geometry factors, and the PR #35 constant-mass projection. Predicted as-printed mass lands within 0.7 g of the scale readings. - drop_tower_sim.py: MuJoCo analogue of the 60 in / PU-mat drop in the bench's own objectives (CFC-180 transmissibility t180, rebound energy e_reb_mJ), with the mat calibrated to the measured input pulse (208.4 G / 4.08 ms). - pr102_correlation.py: every simulated observable in this directory vs the seven mapped tested articles. Volumetric SEA tracks measured t180 at rho = -0.93; the purpose-built t180 analogue only manages +0.46; nothing predicts e_reb_mJ yet. - pr102_sim_campaign.py: closed-loop simulation-only analogue of PR #102's SAASBO campaign, one run per seed, with cross-seed mean +/- 1 sd figures. - workflows-staged/sim-bo-pr102-matrix.yml: parallel seed matrix for Actions (staged outside .github/workflows, which this app cannot write to). Co-authored-by: Sterling G. Baird <45469701+sgbaird@users.noreply.github.com>
|
@claude also do some Ax visualization to help with interpretability. Feature importance plot (inverse lengthscales), LOOCV plot, you might have to look at old Ax docs (0.5.0) and also Honegumi for some of these, also maybe Ax GitHub issues, and maybe if there's some kind of plot you could do also that would show the contributions, positive or negative, of each parameter (i.e., things like "in general, increasing x1 leads to a net positive effect on y1") |
|
Claude finished @sgbaird's task in 23m 7s —— View job Ax interpretability diagnostics: feature importance, LOOCV, signed parameter effects ✅
New file: python bo/t3_prism_bo_diagnostics.py # all four figures
python bo/t3_prism_bo_diagnostics.py --plot-only # restyle, no refitWhere each came from: Honegumi's 1. Feature importance (inverse lengthscales)
The honest reading: SAAS has not identified a sparse subspace. Every value sits between 0.12 and 0.29 against an equal share of 0.20, and every interquartile band except cable Ø on t180 straddles that line. The sparsity prior needs data to shrink dimensions with, and 7 points in 5-D is not enough. The one thing you can take from it is the t180 ordering, H and strut Ø on top and cable Ø at the bottom, which is at least consistent with the effects below. The rebound panel is flat: the model does not think any single coordinate governs it. 2. Leave-one-out cross-validation
This is the result worth arguing about. The model has real (if weak) out-of-sample skill on t180, and none at all on One gotcha found on the way in, and fixed: 3. Signed parameter effectsThis is the "increasing x1 has a net positive effect on y1" plot. Ax 0.5.0 has nothing for it on a continuous space: Read the two together: the tornado compresses each curve to one number, and a curve that turns mid-range gets an asterisk so you go look at it. Both objectives are minimized, so on the tornado a blue (leftward) bar is an improvement.
Note the apparent tension with panel 1: importance ranks H above strut Ø for t180 while the tornado ranks strut Ø first. Not a contradiction. An inverse lengthscale measures how fast the function wiggles in that direction, a net effect measures end-to-end signed change, and they only agree for a monotonic, evenly-sloped parameter. H's t180 curve is the steeper one but concentrated in its upper half. Caveat that governs all of the above: the shaded bands are ±1 posterior sd, and most curves move by less than their own band. Directions and rankings, not decimals. Committed (
|
| File | What |
|---|---|
bo/t3_prism_bo_diagnostics.py |
the script |
bo/figures/t3-prism-bo-round1-feature-importance.png |
+ .csv with the per-draw quartiles |
bo/figures/t3-prism-bo-round1-loocv.png |
+ loocv.csv, loocv-diagnostics.json |
bo/figures/t3-prism-bo-round1-parameter-effects.png |
+ partial-dependence.csv |
bo/figures/t3-prism-bo-round1-parameter-net-effects.png |
+ parameter-net-effects.csv |
bo/README.md |
new "Model interpretability" section with the API provenance and both gotchas |
.gitignore |
__pycache__/ |
Not done: the round-2 suggestions are untouched (this was diagnostics, not a re-run), and I did not act on what the LOOCV found about e_reb_mJ since changing an objective is your call. Still outstanding from earlier threads: the Edison verification of the objectives claim was submitted (task 3e398131) and never fetched, and amdjwm still has no spec mapping so it stays out of the fit.
• Branch
…dicted-vs-measured view Restyles the objective-space panel to the reference posted on PR #102: leader-line callouts instead of a legend box, detached left/bottom spines, open black circles for tested articles with blue-filled front points, larger type, greedy label decluttering in place of hand-tuned offsets. Adds --prototype-next-round, which draws the post-round-2 layout: each predicted diamond joined by a straight path to where the article actually landed (drawn as an open circle), the front recomputed over both rounds, and the round-1 front left dashed underneath. Round-2 outcomes are SYNTHETIC placeholders; synthesize_round2_outcomes is the single function to swap for the measured summary. Co-authored-by: Sterling G. Baird <45469701+sgbaird@users.noreply.github.com>
|
@claude the dummy data plot in #102 (comment) was meant to be a short mp4 or GIF |
|
Claude finished @sgbaird's task in 7m 31s —— View job Round-2 prototype, animated ✅
Still synthetic. Nothing in round 2 has been printed or dropped; the landing points are the same 0.3-sd draws from the model's own posterior as the still figure used. GIF (683 KB, 980 px, 12 fps, loops) and MP4 (206 KB, 1100 x 700, 25 fps, h.264 yuv420p so it plays in PowerPoint and Keynote as well as a browser). Drop the MP4 on a slide; the GIF is for the thread and the README. How it plays, 7.5 s
Faded diamonds stay at the predicted positions throughout, so predicted-versus-measured is still readable in a freeze frame. CodeOne new function, python bo/t3_prism_bo_campaign.py --prototype-next-round # still + GIF + MP4
python bo/t3_prism_bo_campaign.py --prototype-next-round --no-animation # still onlyThree things worth knowing for when the real numbers land. I also moved two callouts to fixed positions in the animated version ("Existing data" and "Round-1 front"), because the auto-placed ones sat on top of the One cosmetic limit, from the dummy data rather than the code: Also updated: Still outstanding from earlier in this thread, unchanged: the Ax interpretability plots (feature importances, LOOCV, parameter effects) from your previous comment, the Edison verification of the objectives claim (task |
…ions Generate the first model-based batch (PR #102 comment 5365706779, Ax trials 10-18) as a printable H2D IDEX project. bo/t3_prism_sobol_batch.py grows --designs-csv (read the five swept columns from any design table, e.g. a t3-prism-bo-suggestions-roundN.csv emitted by the campaign script) and --out-prefix (so a round lands beside the pinned Sobol batch instead of overwriting it). Each row's Ax trial_index is carried into the batch table as source_trial. Artifacts: bo/t3-prism-bo-round1.{csv,json,scad,stl}, -struts/-cables STLs, plate/iso previews, 9 per-specimen STL pairs, and bo/slices/t3-prism-bo-round1.H2D-MM-PLAstruts-TPUcables.3mf (9 objects, each with a PLA struts part on extruder 1 and a TPU cables part on extruder 2, filament_map_mode=Manual, supports off for manual painting). All 9 hold m* = 30.95 g within tolerance and clear the 250 cm^3 envelope cap; specimens 00/02/05 (trials 10/12/15) drop to 2.6-2.7 mm as-printed cable diameter and are flagged cable_bridge_ok=False. Co-authored-by: Sterling G. Baird <45469701+sgbaird@users.noreply.github.com>
|
@claude #102 (comment) this looks good, but you need to hide the original items afterwards and show just the final figure |
|
Claude finished @sgbaird's task in 5m 49s —— View job Animation now clears its own scaffolding ✅
Still synthetic, same 0.3-sd draws as before. GIF (826 KB) and MP4 (257 KB), now 9.7 s instead of 7.5 s. What happens at the end
Everything the clean-up removes exists only to explain how the batch got there, so it all leaves on one shared fade rather than in stages. "Existing data (round 1)" goes too: once round 2 is measured, every point on the panel is existing data. The resting frame, as a committed stillNew file python bo/t3_prism_bo_campaign.py --prototype-next-roundOne fix that fell out of this: with the diamonds gone, the "Pareto front after round 2" callout was sitting on the front line and striking through the Also updated: Nothing else moved: same round-2 suggestions, same objectives, same round-1 figure. Still outstanding from earlier in this thread: Edison task |
The clip now ends by clearing its own scaffolding. After a beat on predicted-versus-measured, the orange diamonds, travel paths, arrowheads, round-1 front and the callouts that named them fade out together, so the last ~2.4 s is the round-2 Pareto figure alone. render_prediction_vs_actual_figure gains show_predictions=False, which draws that resting state as a still (t3-prism-bo-round2-front-final- PROTOTYPE.png), so the animation's last frame and a committed PNG agree. Also moved the 'Pareto front after round N' callout off the front line, where it collided with the r2-14 label once the diamonds were gone. Co-authored-by: Sterling G. Baird <45469701+sgbaird@users.noreply.github.com>
|
@claude there's a lot of text, and overlapping text as well. It's effective, but just ever too much overlapping at once. For example, redrawing the Pareto front should be it's own step after the points shift over and turn into black dots, and maybe the original Pareto front should be hidden before shifting the points |
|
Claude finished @sgbaird's task in 15m 7s —— View job Re-choreographed: one idea per beat, and the text thinned out ✅
Still synthetic, same 0.3-sd draws. GIF (663 KB) and MP4 (213 KB), 11 s. The new order
Both of your suggestions, and they turned out to depend on each other: once the round-1 front leaves in beat 2, there is no dashed remnant left to compete with the new front in beat 6, so the "Round-1 front" callout could go entirely. Text budget is now three callouts in the opening frame (which is just the round-1 slide), at most one while anything is in motion, and one at rest. The overlapping-text fixThat was a real bug, not just crowding. The label placer tried ten offsets and, if none was clear, silently took whichever happened to be last in the list. It also only knew about markers and other labels, so a series name or its leader line was invisible to it. Now ( The round-2 front callout is anchored below-left of the front, which is a property of a Pareto front (nothing can dominate into that region) rather than a hand-placement that breaks with new data. The two stills are now the two rest pointsInstead of one still that stacked the travel layer and the front on top of each other,
python bo/t3_prism_bo_campaign.py --prototype-next-roundThe round-1 figure got the label fix too ( Nothing else moved: same data, same round-2 suggestions, same objectives. |
The round-2 prototype clip had too much moving and too much text on screen at once (PR #102 review). Re-choreographed so each beat carries one idea: the round-1 front is retired before anything moves, the diamonds then travel on an otherwise clean panel, and the new front is redrawn as its own step, after every article has landed and turned into an open black circle, wiping in along the polyline and filling each article as it reaches it. Text is thinned to match: the Round-1 front callout is gone, at most one callout is lit while anything is in motion, and point labels now dodge the callout text, the callout leaders, the front line and the travel arrows as well as the markers, choosing least-weighted-overlap rather than falling back to whichever candidate offset happened to be last. The two stills become the two rest points of the same story (stage="travel" and stage="front") instead of one still with the front layered on top of the travel layer. Co-authored-by: Sterling G. Baird <45469701+sgbaird@users.noreply.github.com>
…ol seed The repeats shared round 0: every seed attached the nine physically printed articles as completed trials, so the seed reached nothing but the surrogate's own randomness and the seeds agreed to under 2 percent. --init sobol (now the default) draws each repeat's own nine-point round 0 from that repeat's seed; --init printed keeps the PR #102-exact behaviour. The hypervolume reference point moves off the seed's own round 0 onto a fixed one derived from the printed articles, so a repeat that draws a bad initial batch is not handed a generous reference point for it. --jobs runs repeats concurrently, one process per seed, with the numeric libraries pinned to one thread each. Co-authored-by: Sterling G. Baird <45469701+sgbaird@users.noreply.github.com>
Four batches of 9 per repeat, the same per-seed budget as the earlier three-seed run, ten repeats in 1457 s on four cores. The independent draws start far apart and finish close: hypervolume after round 0 spans 13.8 percent of its mean, and 17.50 +/- 0.26 (1.51 percent) after four batches. All ten corner R, H, twist and cable_d identically and leave strut_d loose across the whole box. Co-authored-by: Sterling G. Baird <45469701+sgbaird@users.noreply.github.com>
|
Noting, VERY IMPORTANTLY, that the batch we ran in #35 is #102 (comment) (without the "real" constant mass constraint applied) |
|
@claude #102 (comment) is good, but I think it would be good to hide all of the IDs prior to continuing the animation (8 IDs at first isn't overwhelming, but with so much more text after, it does get overwhelming) |
|
Claude finished @sgbaird's task in 4m 47s —— View job IDs retired with the round-1 front, back only at rest ✅
Still synthetic, same 0.3-sd draws. GIF (705 KB) and MP4 (243 KB), still 11 s: the change is what is on screen, not how long anything takes. Where the IDs live now
The rule the code now follows is simply that nothing is labeled while anything is in motion. That also removes the thing that made the middle busiest: the round-2 IDs used to arrive one at a time as each article landed, so nine labels were appearing during the same beat the diamonds were traveling and the round-1 IDs were still sitting there. Beat 2, everything retired at once: One consequence worth confirmingThe predicted-versus-measured still lost its IDs too, because it is the beat-4 frame and the two are supposed to register. That still is about the arrows, and it was carrying seventeen labels across nine travel paths, which was the most crowded artifact in the set. Identity comes back on the resting still, Say the word if you want the travel still to keep its IDs even though the animation frame it matches does not. CodeSame command, no new flags: python bo/t3_prism_bo_campaign.py --prototype-next-roundIn Nothing else moved: same data, same round-2 suggestions, same objectives, same round-1 figure. Still outstanding from earlier in this thread: Edison task |
|
Also noting that instead of "lower is better", using an '"arrow pointing down" is better' might work out better |
…ck at rest Eight IDs on the opening frame is fine; carrying them through the travel while nine round-2 IDs arrive on top of them is not (PR #102 review). The IDs now leave in beat 2 with the round-1 front and its callouts, nothing is labeled while anything is moving, and every ID fades back in once the figure has come to rest in beat 7. The travel still drops its IDs to match the beat it holds. Co-authored-by: Sterling G. Baird <45469701+sgbaird@users.noreply.github.com>
|
@claude nice, but I need at higher res and I also need an identically sized image of the first frame and an identically sized image of the second frame so that I can line them up on three consecutive powerpoint slides and transition from one to the next |
|
Claude finished @sgbaird's task in 6m 52s —— View job Three registered stills at 2200 x 1400, and the video to match ✅
Everything is 2200 x 1400 px now, stills and video alike (was 1100 x 700). Same 11 x 7 in canvas at 200 dpi instead of 100, so nothing about the layout changed, there is just twice the linear resolution. At 11 in wide that is 200 dpi on a full-bleed slide. The three slides, in order
Slide 1 is new. The other two file names are unchanged, so anything already pointing at them still works. Why they line upThey are frames of the same figure, not three drawings. Checked rather than assumed: the axis furniture is byte-for-byte identical across the three PNGs. Every print ID that appears on both slide 1 and slide 3 ( One thing to know before you place themSlide 1 is not the same panel as Also worth flagging: the The animationSame 11 s and the same beats, now 2200 x 1400 h.264 at 25 fps, crf 18 instead of 20: MP4 (563 KB). Its last frame is slide 3 and its opening frame is slide 1, so the clip and the three slides are interchangeable: use the clip if you want it to play, the three slides if you want to click through it. The GIF went from 980 to 1280 px wide (1.06 MB), but it is still for the thread and the README. Put the MP4 on the slide. CodeSame command, ~1 min: python bo/t3_prism_bo_campaign.py --prototype-next-round # 3 stills + MP4 + GIF
python bo/t3_prism_bo_campaign.py --prototype-next-round --no-animation # 3 stills, ~4 s
Still synthetic, unchanged: the round-2 landing points are 0.3-sd draws from the model's own posterior, and Not done: the standalone round-1 figure is still 200 dpi with a tight bounding box (say the word if you want it on the shared canvas too), and, still open from earlier in this thread, Edison task |
…ive slides The three rest points of the round-2 story are now exported as frames of the animation figure rather than drawn by a second plotting function, so they are identical in pixel size and every element that survives a beat sits at the same pixel in all three. That is what lets them go on three consecutive PowerPoint slides and be transitioned between. - ANIM_DPI 100 -> 200: the MP4 and the stills are 2200 x 1400. - New still: -start-PROTOTYPE.png, the round-1 figure on the round-2 canvas, so slide 1 registers with slides 2 and 3. - render_prediction_vs_actual_figure removed; render_prediction_animation becomes render_round2_prototype and returns (stills, gif, mp4). --no-animation now means stills only, not still-only. - GIF widened to 1280 px with a 128-colour palette; MP4 crf 20 -> 18. Co-authored-by: Sterling G. Baird <45469701+sgbaird@users.noreply.github.com>
|
@claude needs to be 300 dpi. See also #102 (comment) |
|
Claude finished @sgbaird's task in 6m 17s —— View job 300 dpi throughout, and the down-arrow glyph ✅
The three registered stills, now 3300 x 2100
Same 11 x 7 in canvas, now at 300 dpi instead of 200. Layout did not move at all, because matplotlib sizes type and line weights in points: only the pixel count changed, 2200 x 1400 to 3300 x 2100. The MP4 went with them (3300 x 2100 h.264, 827 KB, still 11 s and the same beats), so the clip and the three slides are still interchangeable. Two things checked rather than assumed:
The down-arrow glyphFrom your other note. Both objective axes now read:
Set once as The tornado caption in the diagnostics said "left is better" for the same reason, so it got ← by the same argument. That was the only other instance in the repo; the grep is clean. Diagnostics figures came alongThey were the stragglers at 200 dpi (and 180 for the parameter-sweep grid), so all four are re-rendered from the committed CSVs at 300:
It is one number now: RedrawNo model refit needed for any of this, ~1 min for the whole set: python bo/t3_prism_bo_campaign.py --plot-only # round-1 panel
python bo/t3_prism_bo_campaign.py --prototype-next-round # 3 stills + MP4 + GIF
python bo/t3_prism_bo_diagnostics.py --plot-only # the four diagnosticsThe GIF is deliberately still 1280 px (951 KB): it is for this thread and the README. Put the MP4 on the slide. Still synthetic, unchanged: the round-2 landing points are the same 0.3-sd draws from the model's own posterior. Nothing about the data, the objectives or the round-2 suggestions moved in this commit. Not done, all carried from earlier in this thread: Edison task |
…nce front The PR #102 simulation-only campaign reported a hypervolume trace with nothing to compare it against. Adds pr102_baselines.py: four baselines at the campaign's own 36-design budget over the same ten seeds, plus a reference optimum from a 65,536-design Sobol sweep and a Nelder-Mead polish of 21 weightings. BO reaches 97.1 % of the reference hypervolume, compass search 80.4 %, Sobol 65.6 %, LHS 64.7 %, random 60.3 %; every baseline is completely separated from the BO over ten seeds (Mann-Whitney p = 9.1e-5, the floor at n = 10). The front sits on box bounds, with cable_d and twist pinned low along its whole length. Also fixes the missing running-best e_reb_mJ panel: the column was computed and saved but never plotted, in either the per-seed or the aggregate figure. Every evaluation from every run is written to CSV, including the full reference cloud, so plots can be redone without re-running anything. Co-authored-by: Sterling G. Baird <45469701+sgbaird@users.noreply.github.com>
Every figure written by t3_prism_bo_campaign.py and t3_prism_bo_diagnostics.py now renders at a single FIGURE_DPI = 300 (was 200, and 180 for the parameter sweep grid), with the dpi written into each PNG so PowerPoint places it at its intended physical size. The three registered prototype stills and the MP4 are now 3300 x 2100; layout is unchanged, since matplotlib sizes type in points. Both objective axes mark the good direction with U+2193 rather than the words "lower is better", and the net-effects caption uses U+2190 for the same reason. Co-authored-by: Sterling G. Baird <45469701+sgbaird@users.noreply.github.com>
|
Claude finished @sgbaird's task in 3m 21s —— View job Which designs were actually printed, and did mass enter them
Short answer: two different batches came out of #35, and only the second one is model-based. The one on the printer right now came from 1. The batch that was printed and drop-tested (Sobol, no model)The 9 articles in the print key plus the S0 reference. Not a BO script at all: Its constraint is Route A constant solid mass, m* = 30.95 g of 2. The batch on the printer right now (model-based)Added yesterday: These are Ax trials 10 to 18, exactly the batch in your comment 5365706779. 3. The exact BO script that produced them
Established by matching the file, not by reading commit messages: the
The plate itself was built by python3 bo/t3_prism_sobol_batch.py \
--designs-csv bo/t3-prism-bo-suggestions-round1.csv \
--out-prefix t3-prism-bo-round14. Did mass enter the predictions? Yes, in the objective. No, in the geometry.Both are true at once, and the split is the thing worth knowing: Where mass was used (in
Where mass was not used:
The consequence, which is the part I would flag. Because the plate re-projected onto solid mass, the printed masses the model predicted are not what will come off the printer, and the spread is if anything wider than round 1. Running this PR's calibrated mass model (
17.3 to 22.5 g, CV 8.6%, against round 1's 18.50 to 22.29 g at CV 5.9%. So this round's articles will vary in printed mass more than the Sobol round did, and Also on that plate: specimens 00, 02 and 05 (trials 10, 12, 15) come out at 2.6 to 2.7 mm as-printed cable diameter, flagged 5. What is not on the printerThe One correction while I am here: the Nothing committed this round; this is an answer, not a change. |
…inted mass e_reb_mJ = e_rebound * m * g * h is an absolute energy, so it is proportional to the article's printed mass. evaluate_pr102 was projecting onto PR #35's constant-*solid*-mass manifold (30.95 g), which leaves printed mass free: over the committed 68,944-design reference sweep, printed mass spans 32 %, simulated e_rebound spans 0.34 %, and rho(e_reb_mJ, mass_g) = 0.99993. The objective was the mass. PR #102 fixed the same hole on the bench side in 2f1ca2e by projecting onto constant *printed* mass and carrying mass_printed_g as a sixth BO parameter in a narrow slab (target +/- 0.457 g, the spec-08 triplicate scatter). This ports that projection (pr102_mass_model.py, recalibrated from the CSVs already committed here: residual sd 0.378 g over 12 weighed articles against 0.927 g for the flat two-density fit) and wires it in. Also: simulate() can now pin the article's total mass, so the simulated inertia agrees with the scale; the correlation study scores each article at its own weighed mass; the mat is recalibrated on the new manifold (S0 input peak 208.2 G, pulse 4.08 ms, both exact). Co-authored-by: Sterling G. Baird <45469701+sgbaird@users.noreply.github.com>
Noting that, yes, that is what I thought. This option is probably what I would have preferred if we weren't so time constrained, and I knew that I would need to check the accuracy of this latter one because of what I would expect from the difficulty of implementing it with the API. It's nuanced. |
…und objective, article-level noise; submitted on PR #102, previously unfetched Co-authored-by: Sterling G. Baird <45469701+sgbaird@users.noreply.github.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…33 #94 #97 #85 #86 #98 #101) Pivot from planned-methods SEA/eta_c framing to the executed campaign: drop-tower objectives t180 (filtered peak-acceleration ratio) and rebound energy per drop, SAASBO round 1 on the printed Sobol seed batch (real results table, real Pareto/feature-importance/LOOCV figures with labels regenerated for naming consistency), round-2 batch in fabrication, constant-solid-mass projection + printability screens, as-printed fabrication record (manual painted supports, TPU dry box, high-flow nozzle), corrected J211 filter provenance, simulation screening ladder from PR #33 with honest scorecard, metal-analog metric switched to t180, Edison adversarial objective review reflected in Discussion/round-3 plan. SI rewritten: print key, drop-tower protocol/rig characterization, printed-mass model, simulation ladder. Em-dash sweep per style guide. Rebuilt all four PDFs. Co-authored-by: Sterling G. Baird <45469701+sgbaird@users.noreply.github.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Marcus Madsen <265197858+me-madsen@users.noreply.github.com> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
































Adds the key linking each T-3_01 print ID to its Sobol specimen and parameters, recovered from the plate names in the as-printed .3mf uploaded in #98. Includes the slicer project, a per-print key CSV (mass, RH%, defects, geometry), the batch design table from PR #35 commit 32addaf, and a labeled visual key. Flags the Spec 08 official-print discrepancy (dea4ls per .3mf vs bag26v per issue comment).
Closes nothing; supports #98.
Generated with Claude Code