Conversation
is_species_restricted() returned early for composite/force_field/ semiempirical method types before ever checking number_of_radicals, making the bi-rad-singlet branch (multiplicity 1, number_of_radicals > 1) unreachable for those method types. A G4/CBS-QB3 job for a bi-rad singlet therefore ran as a restricted reference with no 'u' prefix and no guess=mix effect, silently converging to the wrong electronic state. Move the number_of_radicals > 1 check ahead of the reference-agnostic early return so a declared bi-rad singlet is always run unrestricted, including for composite methods (uG4, uCBS-QB3). Plain closed-shell singlets and multiplicity > 1 composite jobs are unaffected.
There was a problem hiding this comment.
🟡 Changes recommended
Preserve force-field reference-agnostic handling before approval.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Fixes unrestricted-reference selection for composite bi-radical singlet jobs.
Changes:
- Prioritizes
number_of_radicals > 1. - Adds regression coverage for composite and Gaussian route generation.
File summaries
| File | Summary |
|---|---|
arc/job/adapters/common.py |
Reorders reference selection; a critical finding notes this can produce uuff for force-field jobs. |
arc/job/adapters/common_test.py |
Adds composite biradical, closed-shell, triplet, and route-generation tests. |
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| logger.info(f'Using an unrestricted method for species {species_label} which has ' | ||
| f'{number_of_radicals} radicals and multiplicity {multiplicity}.') | ||
|
|
||
| if number_of_radicals is not None and number_of_radicals > 1: |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1055 +/- ##
==========================================
- Coverage 66.26% 66.18% -0.09%
==========================================
Files 122 122
Lines 41824 41827 +3
Branches 10751 10751
==========================================
- Hits 27716 27682 -34
- Misses 11062 11090 +28
- Partials 3046 3055 +9
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
ARCSpecies.__init__ and ARCSpecies.from_dict disagreed on the multiplicity of the same species. __init__ reads multiplicity and charge off the molecule built from the adjlist/InChI/SMILES, and only afterwards may replace .mol with one perceived from the coordinates (guarded by regen_mol/keep_mol). from_dict ran that override first, unguarded, and then read the multiplicity off the perceived molecule. The two differ by statement order alone. Perception picks an electronic state, and for an open-shell species it routinely picks a different one from the structure that was given: 'C[C]C#N' (multiplicity 3) perceives from its own optimized coordinates as 'C[C][C][N]' (multiplicity 1). Since a deck travels the from_dict path, a species declared open-shell could run its whole job closed-shell -- the job converges, terminates normally and reports a plausible result for a different electronic state. Same failure shape as the restricted-reference defect this branch already fixes, reached by a different route. Capture multiplicity and charge from the structure-derived molecule before mol_from_xyz() replaces it, and fall back to the perceived molecule only when no structure was given at all. An explicitly declared multiplicity still wins, as before.
|
Added a second, related fix to this branch (51f93ce), since it is the same failure — a job that runs the wrong electronic state and reports it as a normal result — reached by a different route.
xyz = "<the optimized geometry of C[C]C#N>"
ARCSpecies(label="s", smiles="C[C]C#N", xyz=xyz).multiplicity # 3
ARCSpecies(species_dict={"label": "s", "smiles": "C[C]C#N", "xyz": xyz}).multiplicity # 1
A deck travels the The fix captures multiplicity and charge from the structure-derived molecule before the override, falling back to the perceived molecule only when no structure was given at all. An explicitly declared multiplicity still wins. |
What
is_species_restricted()returned early forREFERENCE_AGNOSTIC_METHOD_TYPES(composite,force-field, semiempirical) before reading
number_of_radicals, so the bi-rad-singlet branchbelow it was unreachable for exactly those method types. Move the
number_of_radicals > 1checkahead of that early return.
Why
An open-shell singlet biradical is declared in ARC as an
ARCSpecieswithmultiplicity=1andnumber_of_radicals=2— that is what theARCSpeciesdocstring prescribes, and it is the only wayto express the state. The existing code already knew what to do with it; its own comment says so:
That comment describes a case the function could never reach. Composite methods take
method_type == 'composite', soG4/CBS-QB3returnedTrue(restricted) at the top, and thebranch the comment documents never ran. A declared bi-rad singlet therefore went out as plain
g4with a restricted reference — no
uprefix — and converged to the wrong electronic statewithout warning. Nothing errors; the thermochemistry is simply wrong.
The asymmetry is the whole point: for a composite method an unrestricted reference is applied
automatically when multiplicity > 1, but a bi-rad singlet's multiplicity is 1, so the method
gets no signal and ARC has to say
uG4explicitly.What changed
arc/job/adapters/common.py—number_of_radicals > 1is now evaluated first and returnsunrestricted, then the reference-agnostic early return, then the
multiplicity > 1case. Theexisting
# don't run unrestricted for composite methods...comment is replaced by one thatexplains why the order matters, so the next reader does not "simplify" it back.
Unaffected: plain closed-shell singlets (
number_of_radicalsunset or 1) and composite jobs atmultiplicity > 1 both take exactly the paths they did before.
Testing
arc/job/adapters/common_test.py— 61 passed, with new cases covering a composite bi-rad singlet(unrestricted), a composite closed-shell singlet (restricted), and a composite triplet (unchanged).
Verified end to end on the route section: a
g4job for a species withmultiplicity: 1, number_of_radicals: 2now writesug4.