Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# ICARUS charge-scale detector variation
# Revision date: August 13, 2026

__meta__:
kind: mod
name: "charge_scale"
version: "260813"
date: "2026-08-13"
description: "Charge-scale detector variation"
applies_to: [mc]
compatible_with:
model: ">=250303"

override:
model.modules.calibration.response:
# Apply the response variation before charge calibrations.
priority: 10
response_func: 1.0279*x - 0.000287*x*x + 2.4915e-7*x*x*x - 4.522989e-11*x*x*x*x
model.modules.calibration.smearing:
# Apply the smearing after the response function
priority: 9
distribution: normal
mode: multiplicative
mean: 1.0
scale: 0.14953
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ override:
response:
# Apply the response variation before charge calibrations.
priority: 10
response_func: 1.00582*x - 0.0001188*x*x - 4.4164e-8*x*x*x + 1.04071e-11*x*x*x*x
response_func: 0.9894425*x + 7.6032e-7*x*x - 2.552e-7*x*x*x + 6.74704e-11*x*x*x*x
smearing:
# Apply the smearing after the response function
priority: 9
distribution: normal
mode: multiplicative
mean: 1.0
scale: 0.0511

post.apply_calibrations.depositions_source: depositions
61 changes: 61 additions & 0 deletions tests/test_config_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -393,3 +393,64 @@ def test_sbnd_charge_scale_continues_from_varied_depositions(
assert (
config["post"]["apply_calibrations"]["depositions_source"] == "depositions"
)

def test_icarus_charge_scale_only_adds_response_and_smearing(
self, config_infer_root, tmp_path
):
"""The ICARUS variation preserves calibration supplied by the base model."""
icarus_root = config_infer_root / "icarus"
modifier = (
icarus_root / "modifier" / "charge_scale" / "mod_charge_scale_260813.yaml"
)
modifier_config = yaml.safe_load(modifier.read_text(encoding="utf-8"))
assert modifier_config["__meta__"]["compatible_with"] == {"model": ">=250303"}
assert set(modifier_config["override"]) == {
"model.modules.calibration.response",
"model.modules.calibration.smearing",
}

composite = tmp_path / "composite.yaml"
composite.write_text(
yaml.safe_dump(
{
"include": [
str(icarus_root / "full_chain_co_260501.yaml"),
str(modifier),
]
}
),
encoding="utf-8",
)
config = load_config_with_includes(composite)
calibration = config["model"]["modules"]["calibration"]
assert calibration["stage"] == "segmentation"
assert calibration["gain"]["gain"] == 79.9169
assert "recombination" in calibration
assert "lifetime" in calibration
assert "transparency" in calibration
assert calibration["response"]["priority"] == 10
assert calibration["smearing"]["priority"] == 9

def test_icarus_charge_scale_accepts_first_in_chain_calibration(
self, config_infer_root, tmp_path
):
"""The first ICARUS model with in-chain calibration supports the modifier."""
icarus_root = config_infer_root / "icarus"
modifier = (
icarus_root / "modifier" / "charge_scale" / "mod_charge_scale_260813.yaml"
)
composite = tmp_path / "composite.yaml"
composite.write_text(
yaml.safe_dump(
{
"include": [
str(icarus_root / "full_chain_co_250303.yaml"),
str(modifier),
]
}
),
encoding="utf-8",
)

config = load_config_with_includes(composite)
assert "response" in config["model"]["modules"]["calibration"]