Skip to content

Add cofactor-EC coverage as a second, independent cognate-ligand source - #11

Draft
m-crown wants to merge 2 commits into
feature/offline-glycan-translationfrom
feature/cofactor-coverage
Draft

Add cofactor-EC coverage as a second, independent cognate-ligand source#11
m-crown wants to merge 2 commits into
feature/offline-glycan-translationfrom
feature/cofactor-coverage

Conversation

@m-crown

@m-crown m-crown commented Aug 9, 2026

Copy link
Copy Markdown
Member

Summary

  • Closes the cofactor coverage gap described in docs/cofactor_coverage_plan.md: cognate ligands were previously derived only from reaction equations, which structurally misses catalytic/prosthetic cofactors that never appear as a reactant/product (e.g. NAD, FAD, PLP, metal centers).
  • Adds a second, independent source: CoFactor DB 2010 + BRENDA (vendored from RelLig's cofactor_ec.csv/cofactors_details.json) combined with UniProt's structured COFACTOR annotations, built into cofactor_ligands_df.pkl by new nextflow/bin/preprocess_cofactors.py (mirrors preprocess_rhea.py's pattern).
  • get_ec_information.py concats this alongside the existing reaction-derived sources into cognate_ligands_df, tagged via a new ligand_source column (reaction / cofactor, unioned when both apply). Strict addition - existing reaction-derived rows are unaffected (verified by test).
  • Partial ECs from UniProt are handled per the plan's broadcast rule: subsubclass-level wildcards (N.N.N.-) are expanded to matching terminal ECs; class/subclass-level wildcards are dropped rather than broadcast (confirmed during planning that broadcasting those produces nonsense - e.g. a class-level wildcard matching literally every terminal EC in that class).
  • get_chem_comp_descriptors moved from process_all_pdb_contacts.py into utils.py so both scripts can share the CCD→SMILES resolution logic.
  • reference_data_manifest.yaml updated: removed the stale RelLig bulk-TSV entries from an earlier version of the plan (checked against the real files - no EC column in either), added the three sources actually used, all optional and URL-verified.

Test plan

  • nextflow/bin/tests/test_preprocess_cofactors.py - 21 tests covering UniProt parsing, the EC-completeness/broadcast safety rule (including a regression test for the class-level-wildcard bug caught during planning), CoFactor DB table loading, ChEBI resolution, and end-to-end build_cofactor_ligands_df.
  • nextflow/bin/tests/test_utils_ec_broadcast.py - 10 tests for classify_ec_completeness, broadcast_subsubclass_ec, and the moved get_chem_comp_descriptors.
  • nextflow/bin/tests/test_get_ec_information_cofactor_merge.py - 4 tests replicating the cognate_ligands_df concat/groupby block to verify ligand_source plumbing and the strict-addition invariant.
  • Full existing test suite (6 pre-existing test files) still passes unchanged.
  • Full pipeline run against real reference data (not done in this session - needs the full data_dir setup).

Known, explicitly out-of-scope gap: chlorophyll and other free-text-only UniProt COFACTOR annotations (~0.7% of the bulk pull) aren't mechanically resolvable by this path - deferred to a separate LLM-extraction follow-on per the plan doc.

🤖 Generated with Claude Code

m-crown and others added 2 commits August 9, 2026 20:37
Combines CoFactor DB 2010 + BRENDA (vendored from RelLig's cofactor_ec.csv
and cofactors_details.json) with UniProt's structured COFACTOR annotations
into cofactor_ligands_df.pkl (preprocess_cofactors.py, mirrors
preprocess_rhea.py's pattern), then concats it into get_ec_information.py's
cognate_ligands_df alongside the existing reaction-derived sources, tagged
via a new ligand_source column. Partial ECs are handled per the plan doc's
broadcast rule: subsubclass-level wildcards (N.N.N.-) are expanded to
matching terminal ECs, class/subclass-level wildcards are dropped rather
than broadcast (verified unsafe - would match every terminal EC in that
class). See docs/cofactor_coverage_plan.md for the full design and the
coverage numbers behind it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ssing

Found while running preprocess_rhea.py end-to-end for the first time
against real reference data (unrelated to the cofactor-coverage work,
but this script is a prerequisite for it). None of these are cofactor-
specific:

- rdfreader's .metadata property fixed-column-parses a mol block's whole
  header, including the program/timestamp line - Rhea's CDK-written
  molfiles don't conform to that fixed-width format (e.g.
  "  CDK    2/12/10,15:27" instead of MDL's fixed MMDDYY field), which
  broke metadata parsing on ~97% of real Rhea rd/ files. Read the
  molecule name directly from the mol block's raw first line instead,
  since that's all this script actually needed from .metadata.
- Assigning int -1 into a pandas StringDtype column raises under modern
  pandas (silently allowed under older/object-dtype behavior). Assign
  the string "-1" instead - the column gets cast to int on the next line
  regardless.
- ChEBI's names.tsv.gz moved to lowercase columns upstream (already
  documented in download_reference_data.py's derive_chebi_results
  docstring, but never applied here) - rename after reading.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant