nx_thermal_profile.nx
buildroot/runtime/nx_thermal_profile.nx
about
nx_thermal_profile.nx -- FOOD-SCIENCE SUITE / PROCESS INTEGRATION rung.
nx_thermal_process evaluates a single hold at a single temperature. A real
retort or HTST run is a CURVE: it comes up to temperature, holds, and cools
back down, and the product is being killed the whole time. This integrates
lethality over that whole profile -- the General Method.
F = SUM over segments of dt_i * 10^((T_i - T_ref)/z)
WHY IT MATTERS, AND IT IS NOT A ROUNDING CORRECTION. Treating a process
as hold-only is conservative, which sounds harmless -- but the come-up on
a typical retort contributes lethality COMPARABLE TO THE ENTIRE HOLD. Ten
minutes ramping from 102 C to 120 C delivers roughly 2 minutes of F0 on
its own, next to a 2.52 minute 12D cook. A process authority that ignores
it does not get a safer product; it gets an OVER-processed one, and
over-processing is exactly how a food is made safe and inedible at the
same time. So the honest direction of the hold-only error is "wasteful",
not "fine".
SEGMENTS LIVE IN MMAP'D ARRAYS, NOT BSS. A module-level `static [N]i64`
silently kills a handler-module process on startup in this toolchain, so
the arrays are lazily mmap'd and reached through pointers -- the standard
workaround here, not a stylistic choice.
EVERY BOUND IS FAIL-CLOSED. A segment past capacity is REFUSED rather
than dropped, because a silently-truncated profile reports LESS lethality
than the process really delivers, and an operator would respond by
cooking longer -- the failure would hide behind a plausible number.
Units match nx_thermal_process exactly: milli-Celsius, milliseconds.
Grounding (cited; researcher-groundable):
bigelow_general_method_thermal_process_integration
stumbo_thermobacteriology_d_z_f0_model
c_botulinum_proteolytic_d121_0_21min_z10
genealogy_id: thermal_process_authority + nishi_food_science_suite
dependencies 3 imports · 1 importers
imports: nx_syscalls.nxnx_pow10.nxnx_thermal_process.nx
imported by: nx_thermal_profile_test.nx
structs
| 45 | struct NxThermalProfile |
consts
| 42 | const TPR_MAX_SEGMENTS: i64 = 256 |
| 43 | const TPR_REFUSED: i64 = 0 - 1 |
functions
| 53 | func nx_thermal_profile_new(cap: i64) -> *NxThermalProfile |
| 69 | func tpr_add_segment(p: *NxThermalProfile, temp_milli: i64, dur_ms: i64) -> i64 |
| 86 | func tpr_add_ramp(p: *NxThermalProfile, t_start_milli: i64, t_end_milli: i64, dur_ms: i64, n_steps: i64) -> i64 |
| 102 | func tpr_total_time_ms(p: *NxThermalProfile) -> i64 called by 1: main |
| 114 | func tpr_peak_temp_milli(p: *NxThermalProfile) -> i64 |
| 134 | func tpr_lethality_ms(p: *NxThermalProfile, t_ref_milli: i64, z_milli: i64) -> i64 |
| 150 | func tpr_f0_ms(p: *NxThermalProfile) -> i64 |
| 154 | func tpr_bot_cook_adequate(p: *NxThermalProfile) -> i64 |
| 163 | func tpr_ramp_credit_ms(p: *NxThermalProfile, hold_ms: i64) -> i64 |
| 173 | func tpr_log_reductions_q3(p: *NxThermalProfile, d_ref_ms: i64, t_ref_milli: i64, z_milli: i64) -> i64 |