Merge branch 'master' into fix/issue-61
CI / Format (ruff format) (push) Successful in 29s
CI / Lint (ruff check) (push) Successful in 29s
CI / Sync project version with tag (push) Has been skipped
CI / Lint (ruff check) (pull_request) Successful in 29s
CI / Type check (ty) (push) Successful in 32s
CI / Format (ruff format) (pull_request) Successful in 36s
CI / Sync project version with tag (pull_request) Has been skipped
CI / Type check (ty) (pull_request) Successful in 35s
CI / Tests (pull_request) Successful in 4m8s
CI / Tests (push) Successful in 4m15s
CI / Format (ruff format) (push) Successful in 29s
CI / Lint (ruff check) (push) Successful in 29s
CI / Sync project version with tag (push) Has been skipped
CI / Lint (ruff check) (pull_request) Successful in 29s
CI / Type check (ty) (push) Successful in 32s
CI / Format (ruff format) (pull_request) Successful in 36s
CI / Sync project version with tag (pull_request) Has been skipped
CI / Type check (ty) (pull_request) Successful in 35s
CI / Tests (pull_request) Successful in 4m8s
CI / Tests (push) Successful in 4m15s
This commit is contained in:
@@ -627,3 +627,53 @@ def test_decode_secondaries_mass_charge_round_trip_with_normalizer():
|
||||
_, _, sec_mass, sec_charge, _ = decode_secondaries(sec_cont_normed, n_sec, e_sec, pre_dir, sec_phys_normalizer=norm)
|
||||
assert sec_mass[0, 0] == pytest.approx(938.27208943, abs=1e-2)
|
||||
assert sec_charge[0, 0] == pytest.approx(1.0, abs=1e-4)
|
||||
|
||||
|
||||
def test_decode_secondaries_extreme_negative_log_mass_stays_nonnegative():
|
||||
from giant.data.transforms import decode_secondaries, log_transform
|
||||
|
||||
N = 1
|
||||
e_sec = np.array([5.0], dtype=np.float32)
|
||||
n_sec = np.array([1])
|
||||
pre_dir = np.array([[0.0, 0.0, 1.0]], dtype=np.float32)
|
||||
|
||||
sec_cont = np.zeros((N, K_MAX, 6), dtype=np.float32)
|
||||
sec_cont[0, 0, 0] = 10.0 # stick logit -> ~all of e_sec
|
||||
sec_cont[0, 0, 1:4] = [0, 0, 1]
|
||||
sec_cont[0, 0, 4] = -50.0 # raw model prediction: extremely negative log_mass
|
||||
sec_cont[0, 0, 5] = 1.0
|
||||
|
||||
_, _, sec_mass, _, _ = decode_secondaries(sec_cont, n_sec, e_sec, pre_dir)
|
||||
|
||||
# A raw model prediction isn't itself the output of log_transform, so
|
||||
# naively applying inv_log_transform can undershoot zero (see
|
||||
# decode_secondaries) — which then crashes the next log_transform call
|
||||
# once this mass is fed back in as conditioning during rollout. The
|
||||
# float32 residual from clipping can land a hair below zero, but must
|
||||
# stay well above -eps so log_transform(mass) stays finite.
|
||||
assert sec_mass[0, 0] > -1e-8
|
||||
log_transform(sec_mass[0, 0])
|
||||
|
||||
|
||||
def test_decode_secondaries_extreme_positive_log_mass_stays_finite():
|
||||
from giant.data.transforms import decode_secondaries, log_transform
|
||||
|
||||
N = 1
|
||||
e_sec = np.array([5.0], dtype=np.float32)
|
||||
n_sec = np.array([1])
|
||||
pre_dir = np.array([[0.0, 0.0, 1.0]], dtype=np.float32)
|
||||
|
||||
sec_cont = np.zeros((N, K_MAX, 6), dtype=np.float32)
|
||||
sec_cont[0, 0, 0] = 10.0 # stick logit -> ~all of e_sec
|
||||
sec_cont[0, 0, 1:4] = [0, 0, 1]
|
||||
sec_cont[0, 0, 4] = 200.0 # raw model prediction: extremely positive log_mass
|
||||
sec_cont[0, 0, 5] = 1.0
|
||||
|
||||
_, _, sec_mass, _, _ = decode_secondaries(sec_cont, n_sec, e_sec, pre_dir)
|
||||
|
||||
# Mirror image of the extreme-negative case above: exp(log_mass)
|
||||
# overflows float32 to inf for an unclipped raw prediction this large,
|
||||
# which then crashes the next log_transform call the same way a
|
||||
# negative mass would.
|
||||
assert np.isfinite(sec_mass[0, 0])
|
||||
log_transform(sec_mass[0, 0])
|
||||
|
||||
Reference in New Issue
Block a user