Skip to content

refactor(advice): inventory the structure-only heuristics standing in for models #175

Description

@junwen94

Context

Every parameter Core advises has a fallback rule for when the operator gives no
hint. Those rules were written when there was no model to ask, and they are
honest about it — each one records source="analysis" or source="default" and
a reason. They were the right thing to build first.

They are now the thing the roadmap replaces, and no single place records what
they currently are or where each one is wrong. This issue is that inventory. It
proposes no code change on its own; the follow-up work is one issue per setting.

ProvenanceSource already includes "model", so a model-sourced answer has
somewhere to go. What is missing is the models, not the plumbing.

The inventory

Setting Rule Where
Metallicity → smearing every element satisfies Element.is_metallikely_metal; otherwise unknown → fixed occupations analysis.py:_classify_electronic_character
Magnetism any transition metal, lanthanide, or actinide present → spin_polarized=True advice.py:155
Spin–orbit any element with row >= 5 → SOC worth considering advice.py:196
k-points DEFAULT_K_SPACING = 0.2 when no model and no hint advice.py:23, advice.py:92
Convergence conv_thr=1e-6, mixing_beta=0.4, electron_maxstep=80 advice.py:24-26
vdW vacuum or low-dimensional connectivity → D3BJ; otherwise off advice.py:296

Where each one is wrong

Metallicity is the worst of them, and it is the one we can already fix.
The rule requires every element to be metallic, so any compound containing
oxygen, nitrogen, carbon, or a halogen falls to unknown, and unknown means
fixed occupations. RuO₂, ReO₃, LaNiO₃, CrO₂, and TiN are all metallic and all
get no smearing. That is the expensive direction of the error: the calculation
runs, converges badly or to the wrong state, and the number it returns does not
look wrong.

It is also composition-only. Two polymorphs with different electronic character
— VO₂ above and below its transition, say — are indistinguishable to it.

Magnetism triggers on element identity, not on magnetism. is_transition_metal
is true for Zn, Cd, Sc, Ti, and Cu, so ZnO, TiO₂, Cu₂O, and Sc₂O₃ are all
advised spin-polarised. These are common, non-magnetic, and now cost roughly
twice what they should. The error direction is the cheap one, but it is applied
to a large fraction of everything.

Spin–orbit triggers on period, not on atomic number. row >= 5 catches Rb,
Sr, and Ba, where SOC is negligible, alongside Bi and Pb, where it is not.

k-points, convergence, and vdW are constants. DEFAULT_K_SPACING = 0.2
does not depend on the structure at all; it is what happens whenever the model
path is not taken. mixing_beta = 0.4 is applied to metals and insulators
alike, though they want different values. These are defensible defaults rather
than wrong heuristics, but they should be recorded as untuned rather than
chosen.

What can be replaced now

Metallicity. A CGCNN classifier is trained in stfc/goldilocks-ml on 106113
Materials Project structures, grouped by reduced composition. On a held-out test
split of 10625 structures it reaches 0.890 accuracy and 0.779 MCC, against 0.544
accuracy and 0.000 MCC for a majority-class baseline. Its threshold is chosen
under a recall floor, because missing a metal costs more than a false alarm.

The blocker is not the model. It is that Core has nowhere to put a metallicity
answer — it is currently consumed only as an input to the k-distance model's
feature vector. See stfc/goldilocks-ml#15.

Magnetism. Nothing new is needed on the ml side: is_magnetic reuses the
classification path metallicity already uses, and lands in the spin_polarized
field Core already carries. It needs a target contract and a dataset. Note that
the current heuristic, not a majority-class baseline, is the number a model has
to beat — it may already be strong on some chemistries and badly wrong on
others, and nobody has measured which.

What this issue asks for

  1. Agreement that the inventory above is complete and correct.
  2. A decision on whether each rule stays as the no-model fallback or is retired
    once a model exists. They are not the same choice — a fallback still runs
    when a model is unavailable or declines to answer.
  3. One follow-up issue per setting, opened against that decision.

Related: #174 (the seam these predictions would arrive through), stfc/goldilocks-ml#15.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    architectureArchitecture and API boundary workcoreCore package pipeline, contracts, and recommendationsmlMachine-learning model integration and feature extraction

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions