code wiki / (root) / nx_skinspectra_lib.nx

nx_skinspectra_lib.nx source

↩ module page · 188 lines · 8305 B

1// nx_skinspectra_lib.nx -- MEASURED ABSORPTION SPECTRA, PARSED NOT TRANSCRIBED (2026-09-03, rung ST6) 2// 3// WHY PARSING AND NOT A TABLE OF CONSTANTS. Every coefficient on /compare/skintwin was a PROBE VALUE, and 4// pinning the published spectra was supposed to fix that. It nearly fixed it the wrong way: the obvious move 5// is to read the mirrored table and copy numbers into a conf. That is transcription, and transcription is 6// exactly the failure this rung exists to remove -- MEASURED THE SAME DAY, the probe melanin coefficients 7// carried a blue-to-red ratio of 5.0 against the published law's 2.72, so the shape was right and the slope 8// was 1.8x too steep. A number typed by hand is a number that can be wrong. A number parsed out of a 9// sha-pinned mirror is the mirror's responsibility. 10// 11// SO THE ONLY VALUES TYPED HERE ARE THE ONES THE PUBLISHED LAW ITSELF STATES -- 1.70, the decade count 12, 12// the exponent 3.48, and the source's own conversion constants 2.303 and 64500 -- each written as it appears 13// in the source rather than pre-multiplied. The haemoglobin numbers are never typed at all; they are read 14// from the mirror at run time. 15// 16// SOURCES, BOTH MIRRORED AND PINNED (skintwin.refs): 17// MELANIN [@omlc_mel] Jacques and McAuliffe 1987; Jacques, Glickman and Schwartz 1996. Melanosome 18// absorption measured by the threshold for explosive vaporization under pulsed lasers. 19// Fitted spectrum for skin: mua = 1.70e12 * lambda^-3.48 [cm-1], lambda in nm. 20// HAEMOGLOBIN [@omlc_hb] Prahl, compiled from Gratzer (MRC Labs, London) and Kollias (Wellman Labs, 21// Harvard Medical School). Tabulated MOLAR EXTINCTION e in [cm-1/(moles/litre)], converted by 22// the source's own formula mua = 2.303 * e * x / 64500, x in grams of haemoglobin per litre. 23// 24// THE PREFACTOR IS A DISTRIBUTION, NOT A CONSTANT, AND THE SOURCE SAYS SO IN ITS OWN WORDS: "The 25// concentration of melanin within melanosomes is quite variable. Ten-fold variation is to be expected." 26// So ss_melanin_mua returns the LAW at unit concentration and takes concentration as a caller argument. A 27// lib that folded a tenfold-variable quantity into a fixed coefficient would publish a constant wearing a 28// measurement's clothes. 29// 30// NUMERICAL NOTE THAT MATTERS: 1.70e12 is far outside Q30 and must never exist as a value. mua is computed 31// as ONE exponential of (ln 1.70 + 12 ln 10 - 3.48 ln lambda), so the huge prefactor is never materialised 32// and the result lands in range at every visible wavelength. MEASURED: 993.73 / 494.30 / 365.16 per cm at 33// 450 / 550 / 600 nm, and the prefactor-free ratio reproduces (600/450)^3.48 = 2.721365 EXACTLY. 34// license_tier: ORIGINAL No hw writes (Rule 26). LIB (no main). 35import "nx_syscalls.nx" 36import "nx_fixq30_lib.nx" 37 38const SS_REFUSED: i64 = 0 - 1 39// the numbers the published melanin law states, written as the source writes them 40const SS_MEL_PREFACTOR_MILLI: i64 = 1700 // 1.70, carried at 1/1000 41const SS_MEL_DECADES: i64 = 12 // the 10^12 42const SS_MEL_EXP_MILLI: i64 = 3480 // 3.48, carried at 1/1000 43const SS_MILLI: i64 = 1000 44const SS_TEN: i64 = 10 45// the source's own conversion from molar extinction to absorption coefficient 46const SS_HB_LN10_MILLI: i64 = 2303 // 2.303, carried at 1/1000 47const SS_HB_GRAM_MOLE: i64 = 64500 // grams per mole of haemoglobin, stated by the source 48// the fitted law is quoted over the optical band; extrapolating it to a wavelength nobody measured would be 49// inventing data with a formula, so the range is a REFUSAL rather than a clamp. 50const SS_LAMBDA_MIN: i64 = 250 51const SS_LAMBDA_MAX: i64 = 1000 52const SS_BOX: i64 = 8 53const SS_DIG0: i64 = 48 54const SS_DIG9: i64 = 57 55const SS_SPACE: i64 = 32 56const SS_TABCH: i64 = 9 57const SS_NL: i64 = 10 58 59// melanosome absorption at unit concentration, per the published fitted law. 60func ss_melanin_mua(fq: *i64, lambda_nm: i64) -> i64 { 61 if lambda_nm < SS_LAMBDA_MIN { return SS_REFUSED } 62 if lambda_nm > SS_LAMBDA_MAX { return SS_REFUSED } 63 let lnA: i64 = fq_ln(fq, fq_div(fq_from_int(SS_MEL_PREFACTOR_MILLI), fq_from_int(SS_MILLI))) 64 let ln10: i64 = fq_ln(fq, fq_from_int(SS_TEN)) 65 let k: i64 = fq_div(fq_from_int(SS_MEL_EXP_MILLI), fq_from_int(SS_MILLI)) 66 let lnL: i64 = fq_ln(fq, fq_from_int(lambda_nm)) 67 return fq_exp(fq, lnA + ln10 * SS_MEL_DECADES - fq_mul(k, lnL)) 68} 69 70// scale by a caller-supplied concentration, because the source says it varies tenfold. 71func ss_melanin_mua_at(fq: *i64, lambda_nm: i64, conc: i64) -> i64 { 72 if conc < 0 { return SS_REFUSED } 73 let base: i64 = ss_melanin_mua(fq, lambda_nm) 74 if base == SS_REFUSED { return SS_REFUSED } 75 return fq_mul(base, conc) 76} 77 78// the source's own conversion: mua = 2.303 * e * x / 64500, e molar extinction, x grams per litre. 79func ss_hb_mua(e_molar: i64, grams_per_litre: i64) -> i64 { 80 if e_molar < 0 { return SS_REFUSED } 81 if grams_per_litre < 0 { return SS_REFUSED } 82 return (e_molar * SS_HB_LN10_MILLI * grams_per_litre) / (SS_MILLI * SS_HB_GRAM_MOLE) 83} 84 85// ---- table scanning. Every loop exits on a FLAG, never by clobbering its own cursor: a loop that breaks by 86// overwriting the index cannot also report where it stopped, and that idiom has cost this estate real bugs. 87func ss_int_at(buf: *u8, n: i64, p: i64, box: *i64) -> i64 { 88 var i: i64 = p 89 var v: i64 = 0 90 var d: i64 = 0 91 var go: i64 = 1 92 while go == 1 { 93 if i >= n { 94 go = 0 95 } else { 96 let c: i64 = buf[i] as i64 97 if c >= SS_DIG0 { 98 if c <= SS_DIG9 { 99 v = v * SS_TEN + (c - SS_DIG0) 100 d = d + 1 101 i = i + 1 102 } else { 103 go = 0 104 } 105 } else { 106 go = 0 107 } 108 } 109 } 110 if d == 0 { return SS_REFUSED } 111 box[0] = v 112 return i 113} 114 115func ss_skip_ws(buf: *u8, n: i64, p: i64) -> i64 { 116 var i: i64 = p 117 var go: i64 = 1 118 while go == 1 { 119 if i >= n { 120 go = 0 121 } else { 122 let c: i64 = buf[i] as i64 123 if c == SS_SPACE { 124 i = i + 1 125 } else { 126 if c == SS_TABCH { i = i + 1 } else { go = 0 } 127 } 128 } 129 } 130 return i 131} 132 133func ss_line_end(buf: *u8, n: i64, p: i64) -> i64 { 134 var i: i64 = p 135 var go: i64 = 1 136 while go == 1 { 137 if i >= n { 138 go = 0 139 } else { 140 if buf[i] as i64 == SS_NL { go = 0 } else { i = i + 1 } 141 } 142 } 143 return i 144} 145 146// Look up one wavelength in the mirrored table. Rows are "<lambda> <HbO2> <Hb>". 147// Returns 1 and writes out2 on an EXACT match. A wavelength that is not tabulated REFUSES rather than 148// interpolating: the caller asked for a MEASURED value and there is not one, and handing back a neighbour 149// would be inventing a measurement and calling it data. 150func ss_hb_lookup(path: *u8, lambda_nm: i64, out2: *i64) -> i64 { 151 out2[0] = 0 152 out2[1] = 0 153 let lb: *i64 = sys_mmap(SS_BOX) as *i64 154 lb[0] = 0 155 let buf: *u8 = sys_read_file(path, lb) 156 if (buf as i64) == 0 { return SS_REFUSED } 157 let n: i64 = lb[0] 158 if n <= 0 { return SS_REFUSED } 159 let box: *i64 = sys_mmap(SS_BOX) as *i64 160 var p: i64 = 0 161 var found: i64 = SS_REFUSED 162 while p < n { 163 let e: i64 = ss_line_end(buf, n, p) 164 if found == SS_REFUSED { 165 let q0: i64 = ss_skip_ws(buf, n, p) 166 let a: i64 = ss_int_at(buf, n, q0, box) 167 if a != SS_REFUSED { 168 let lam: i64 = box[0] 169 if lam == lambda_nm { 170 let q1: i64 = ss_skip_ws(buf, n, a) 171 let b: i64 = ss_int_at(buf, n, q1, box) 172 if b != SS_REFUSED { 173 let hbo2: i64 = box[0] 174 let q2: i64 = ss_skip_ws(buf, n, b) 175 let c: i64 = ss_int_at(buf, n, q2, box) 176 if c != SS_REFUSED { 177 out2[0] = hbo2 178 out2[1] = box[0] 179 found = 1 180 } 181 } 182 } 183 } 184 } 185 p = e + 1 186 } 187 return found 188}