Let a pinned reaction family determine which families are loaded - #1038
Open
calvinp0 wants to merge 1 commit into
Open
Let a pinned reaction family determine which families are loaded#1038calvinp0 wants to merge 1 commit into
calvinp0 wants to merge 1 commit into
Conversation
Copilot stopped reviewing on behalf of
calvinp0 due to an error
September 1, 2026 12:45
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1038 +/- ##
==========================================
- Coverage 65.55% 65.53% -0.02%
==========================================
Files 120 120
Lines 40516 40539 +23
Branches 10441 10446 +5
==========================================
+ Hits 26559 26568 +9
- Misses 10952 10965 +13
- Partials 3005 3006 +1
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:
|
A family pinned on an ARCReaction only filtered among the families that settings['rmg_family_set'] had already loaded. Pinning a family the configured set does not list therefore produced no product dicts and no explanation: no atom label map, no recipe, no family-derived reactive bonds. XY_Addition_MultipleBond is the motivating case - it requires a halogen at *4, so RMG lists it in the halogens set and ARC's shipped 'default' set does not reach it. A pinned family is now the family set that get_product_dicts() loads, which get_all_families() already supports by returning a list of labels as given. RMG families and ARC's own families are both reached this way. determine_family() routes its non-cached branch through get_product_dicts() so the narrowing applies there too, which also removes a duplicated call into the family module. A family the family property determined lazily is not a pinned family and does not narrow anything: the setter records the pin, and lazy determination writes the private attribute directly. A pin that cannot be honoured is now reported instead of yielding nothing. An unavailable family name is rejected by check_family(), which check_attributes() runs at reaction setup, before any job is scheduled. A pin the reaction does not match raises and names the families it does match, looked up across the available families rather than the configured set, so a directory-only family such as H2_Loss is named. check_family_name() takes the family set to look the family up in, and is_family_available() asks whether a family can be loaded by label at all. That union keeps a surface family pinnable, since 'all' skips the surface sets and directories. get_families_from_product_dicts() replaces the dedup loop that restrict_product_dicts_to_family() open-coded.
calvinp0
force-pushed
the
fix_pinned_family_narrows_load_set
branch
from
September 1, 2026 16:43
7b42704 to
472017e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A reaction family pinned in
input.ymlnow determines which families are loaded, instead of merelyfiltering among the families the global setting happened to load.
The problem
ARCReaction.from_dictreads a pinnedfamilyand the setter records it, but the product dicts comefrom the
product_dictsproperty, which callsget_product_dicts()withrmg_family_set=None—and that falls back to
settings['rmg_family_set']. So a pin could only ever select among familiesthat were already loaded.
XY_Addition_MultipleBondis the case that exposes it. Its group definition requires a halogen at*4, so RMG files it under thehalogensset rather thandefault. With ARC's shippedrmg_family_set = 'default'the family is never loaded, and pinning it yields an emptyproduct_dicts— the user named a family and got nothing back.There were two distinct failures, on two paths:
ARCReaction(family='XY_Addition_MultipleBond')raisedValueError: Invalid family name, because__init__'scheck_family_name()validates against the configured set.input.ymlroute (arc/main.py→reaction_dict→from_dict→ the setter) fell silent,because the setter does not validate.
The change
When a family is pinned and no set is named explicitly,
get_product_dictsnarrows the load set tothat family.
get_all_familiesalready returns a list of family labels unchanged when it contains noset names, so this needs no new lookup path.
determine_family's non-cached branch now routes throughget_product_dictsrather than callingget_reaction_family_productsdirectly, which also removes a duplicated call.ARC-native families need no special case.
get_all_families(['ether_hydrolysis'])returns thelabel as-is and
read_groups_file_linesfinds it underdata/families/, so a pinnedcarbonyl_based_hydrolysis,ether_hydrolysisornitrile_hydrolysisresolves by the same route.Reverse discovery is unaffected.
get_reaction_family_productstries both directions for everyfamily regardless of how many are in the list, and
family_own_reversereadsgroups.pydirectly,so it already worked for an out-of-set pin.
Loading one family rather than all of them takes a cold
get_product_dictsfrom 0.28 s to 0.03 s.A pin that cannot be honoured is an error
If the pinned family is available but does not match the reaction,
get_product_dictsraisesReactionErrornaming the families that do match, found by re-scanning under'all':with a distinct message when nothing matches at all. A pin is a statement of intent, so failing to
honour it should stop the run rather than quietly produce a reaction with no family — and the message
carries what the next run should say instead.
A pinned family that is not a real family at all is caught earlier:
check_family()runs fromcheck_attributes()at Scheduler setup, before any job is submitted.Reuse
Searched before writing: every reader of
settings['rmg_family_set'], every.product_dictsand.determine_family(caller, theconsider_*_families=Falsecall sites, and an order-preservingunique helper (
dedup,uniq,dict.fromkeys).get_families_from_product_dicts()inarc/family/family.pyconsolidates a loop thatrestrict_product_dicts_to_familyhad open-coded;check_family_namegains anrmg_family_setargument rather than growing a second copy, andis_family_available()is new.rmg_family_setitself is unchanged and still ships as'default'.Tests
163 pass across
arc/reaction/andarc/family/. Full CI-style run,pytest arc/ -n 6 --dist worksteal: 3173 passed, 43 skipped, 7 failed — all seven pre-existing, sixof them reproduced on an untouched
mainworktree (common_test::test_which, fivetorch_ani_testcases) and the seventh a known worksteal ordering race that passes serially.
Validated by mutation rather than coverage — nine mutants, each killed by a test: the pin stops
narrowing; the gate keyed back on
_familyrather than the pin provenance; the availability checkdropped; the empty-result raise dropped; the diagnostic re-scan reverted to the configured set;
is_family_availablelosing either of its two terms;determine_familyreverted to the direct call;and
check_family_nameignoring its new argument.🤖 Generated with Claude Code
https://claude.ai/code/session_01MbGeU8wLpafo3YFzTky2ho