pino-source-code / tests /test_genre_challenge_v2.py
Matthew Ford
release: freeze blinded genre challenge v2
f3ff0be
Raw
History Blame Contribute Delete
4.5 kB
from importlib.util import module_from_spec, spec_from_file_location
from pathlib import Path
from pino.registry import AromaRegistry
PATH = Path(__file__).parents[1] / "scripts" / "build_genre_challenge_v2.py"
SPEC = spec_from_file_location("build_genre_challenge_v2", PATH)
MODULE = module_from_spec(SPEC)
assert SPEC.loader
SPEC.loader.exec_module(MODULE)
def record(genre, components):
return {"genre": genre, "formula": components}
def component(cas, smiles=None, weight=0.5):
if smiles is None:
smiles = {"a": "CC", "b": "CCC", "c": "CCCC", "d": "CCCCC", "e": "CCCCCC", "f": "CCCCCCC", "g": "CCCCCCCC"}.get(cas, "CCO")
return {"cas": cas, "smiles": smiles, "weight_fraction": weight}
def test_characterize_excludes_solvent_and_requires_valid_single_fragment_smiles():
row = record("fougere", [component("64-17-5", weight=0.2), component("a"), component("b")])
result = MODULE.characterize(row, 7)
assert result["active_count"] == 2
assert result["structurally_valid"] is True
assert result["source_index"] == 7
invalid = MODULE.characterize(record("fougere", [component("a", "not-smiles"), component("b")]), 8)
assert invalid["structurally_valid"] is False
def test_composition_match_enforces_size_concentration_and_identity_calipers():
base = MODULE.characterize(record("fougere", [component("a"), component("b")]), 0)
matched = MODULE.characterize(record("floral_woody", [component("c"), component("d")]), 1)
overlap = MODULE.characterize(record("floral_woody", [component("a"), component("d")]), 2)
singleton = MODULE.characterize(record("floral_woody", [component("c", weight=1.0)]), 3)
assert MODULE.composition_match(base, matched)
assert not MODULE.composition_match(base, overlap)
assert not MODULE.composition_match(base, singleton)
def test_census_keeps_wildcard_out_of_primary_pool():
rows = [
record("fougere", [component("a"), component("b")]),
record("floral_woody", [component("c"), component("d")]),
record("wildcard", [component("e"), component("f")]),
record("wildcard", [component("g", weight=1.0)]),
]
result = MODULE.census(rows)
assert result["per_substantive_genre"]["fougere"]["composition_matchable"] == 1
assert result["wildcard_open_set_pool"] == {
"multi_component_structurally_valid": 1,
"singleton_sanity_check": 1,
}
def test_characterize_resolves_cas_smiles_keys_expands_naturals_and_aggregates(tmp_path):
registry = AromaRegistry(tmp_path / "registry.db")
registry.add({"cas": "5989-27-5", "name": "limonene", "smiles": "CC1=CCC(CC1)C(=C)C"})
registry.add({"cas": "123-35-3", "name": "myrcene", "smiles": "CC(=CCCC(=C)C=C)C"})
row = record("citrus_cologne", [
component("NATURAL:8008-57-9", smiles="", weight=0.5),
component("SMILES:CCO", smiles="", weight=0.25),
component("5989-27-5", smiles="", weight=0.25),
])
result = MODULE.characterize(row, 0, registry)
registry.close()
assert result["structurally_valid"] is True
assert result["active_count"] == 3
assert result["unresolved_identifiers"] == []
assert len(result["ingredients"]) == 3
def test_characterize_reports_unresolved_identifier(tmp_path):
with AromaRegistry(tmp_path / "registry.db") as registry:
result = MODULE.characterize(record("fougere", [component("unknown", smiles="")]), 0, registry)
assert result["structurally_valid"] is False
assert result["unresolved_identifiers"] == ["unknown"]
def test_duplicate_collapse_is_order_independent_and_conservative():
rows = []
for index, weights in enumerate(((.5, .5), (.51, .49), (.8, .2))):
result = MODULE.characterize(record("fougere", [
component("a", weight=weights[0]), component("b", weight=weights[1])]), index)
result["resolved_components"], _ = MODULE.resolved_active_components(record("fougere", [
component("b", weight=weights[1]), component("a", weight=weights[0])]))
rows.append(result)
kept, audit = MODULE.collapse_duplicates(rows)
assert [row["source_index"] for row in kept] == [0, 2]
assert audit["collapsed_records"] == 1
def test_natural_weight_share_uses_pre_expansion_formula_weight():
row = record("citrus_cologne", [
component("NATURAL:8008-57-9", smiles="", weight=.25),
component("SMILES:CCO", smiles="", weight=.75),
])
assert MODULE.natural_weight_share(row) == .25