Spaces:
Sleeping
Sleeping
| import numpy as np | |
| def process_inputs(X: np.ndarray) -> np.ndarray: | |
| """Convert inputs from natural units to normalized model inputs. | |
| Index | Name | Natural unit | Notes | |
| ------|-----------------------|--------------|-------------------------------- | |
| 0 | ambient_temperature_c | °C | Kelvin ratio — never 0 | |
| 1 | build_chamber_temp_c | °C | Kelvin ratio — never 0 | |
| 2 | ambient_humidity_pct | % | floor 0.25 — dry air still allows degradation | |
| 3 | powder_contamination | AQI [0–500] | floor 0.15 — even clean air causes wear | |
| 4 | print_hours | h | 0 → 0 (machine not running) | |
| 5 | build_volume_cm3 | cm³ | 0 → 0 (no active build) | |
| 6 | recoating_speed_mm_s | mm/s | 0 → 0 (recoater stationary) | |
| 7 | recoating_cycles | count | 0 → 0 (no recoating done) | |
| 8 | maintenance_level | [0, 1] | floor 0.2 — even perfect maintenance | |
| | | | cannot eliminate physical wear | |
| The model uses P = ∏ I_c; only a 0 output produces P = 0 (no degradation). | |
| Inputs whose zero value merely means "minimal stress" (temperatures, humidity, | |
| contamination, maintenance) carry a non-zero floor so they never falsely gate | |
| off all degradation. Inputs that are truly "off" when zero (machine not | |
| running, recoater stationary) map 0 → 0. | |
| All outputs are non-negative. The mapping is linear throughout. | |
| """ | |
| X = np.asarray(X, dtype=float) | |
| out = np.empty(9) | |
| # --- Temperatures: T_K / T_ref (Kelvin ratio, never 0 above absolute zero) --- | |
| # Reference points chosen so the maximum expected operating temperature ≈ 1.0. | |
| # Ambient reference: 70 °C = 343.15 K (factory floor upper bound) | |
| # Chamber reference: 350 °C = 623.15 K (upper bound for powder-bed processes) | |
| out[0] = (np.maximum(X[0], -273.15) + 273.15) / 343.15 | |
| out[1] = (np.maximum(X[1], -273.15) + 273.15) / 623.15 | |
| # --- Humidity: non-zero floor, linear --- | |
| # floor=0.25 at 0 %, reaching 1.0 at 100 %. | |
| out[2] = 0.25 + 0.75 * np.clip(X[2], 0.0, 100.0) / 100.0 | |
| # --- Powder contamination (AQI 0–500): non-zero floor, linear --- | |
| # floor=0.15 at AQI=0; reaches 1.0 at AQI=500. | |
| out[3] = 0.15 + 0.85 * np.clip(X[3], 0.0, 500.0) / 500.0 | |
| out[4] = np.clip(X[4], 0.0, 168.0) / 168.0 # print hours (max 168 h/week) | |
| out[5] = np.clip(X[5], 0.0, 15000.0) / 15000.0 # build volume (max 15 000 cm³/week) | |
| out[6] = np.clip(X[6], 0.0, 150.0) / 150.0 # recoating speed (max 150 mm/s) | |
| out[7] = np.clip(X[7], 0.0, 15000.0) / 15000.0 # recoating cycles (max 15 000/week) | |
| # --- Maintenance: non-zero floor, linear --- | |
| # level=0 (perfect) → 0.2 baseline; level=1 (no maintenance) → 1.0. | |
| out[8] = 0.2 + 0.8 * np.clip(X[8], 0.0, 1.0) | |
| return np.maximum(out, 0.0) # guarantee non-negative | |