Skip to content

writeYAMLmodel: drop empty genes/gene_reaction_rule fields - #715

Merged
edkerk merged 3 commits into
develop3from
fix/writeyamlmodel-empty-genes
Aug 28, 2026
Merged

writeYAMLmodel: drop empty genes/gene_reaction_rule fields#715
edkerk merged 3 commits into
develop3from
fix/writeyamlmodel-empty-genes

Conversation

@edkerk

@edkerk edkerk commented Aug 28, 2026

Copy link
Copy Markdown
Member

Summary

Two related empty-field write fixes, both aimed at keeping writeYAMLmodel and raven_toolbox.io.write_yaml_model byte-identical (companion PR: SysBioChalmers/raven-toolbox#112):

  1. Gene-less model: isfield(model,'genes') alone didn't distinguish "no genes field" from "genes field present but empty" — the latter wrote a bare - genes: line, which YAML parses as genes: null, crashing read_yaml_model. genes is one of cobra's required top-level model keys (model_to_dict always includes it, empty or not), so raven-toolbox already writes - genes: [] for this case. Matched that exactly rather than omitting the section, and taught readYAMLmodel.m to recognise the flow-style empty list.
  2. Empty gene_reaction_rule: also one of cobra's required reaction attributes (always written by model_to_dict), but nothing on either read side actually needs the key present — cobra's own Reaction defaults it to '', and read_yaml_model never indexes it directly. Dropped it the same way every other optional field already is. A deliberate divergence from cobra's own writer convention, matching raven-toolbox's companion change.

Resolves SysBioChalmers/raven-gecko-parity#27.

Test plan

  • Built a gene-less model from smallYeast, wrote it — - genes: [], round-trips through both readYAMLmodel and raven_toolbox.io.read_yaml_model cleanly
  • Reproduced the original crash (bare genes:) against the unfixed reader, confirmed it matches the issue exactly, confirmed the fix resolves it
  • smallYeast has 14/53 reactions with no GPR — wrote through both writeYAMLmodel and write_yaml_model, diffed the two outputs: byte-identical (SHA256 match)
  • Cross-read: MATLAB's output through the Python reader, and Python's output through the MATLAB reader — both directions read correctly, GPR values round-trip exactly
  • testing/function_tests/tIO.m — 14 passed, 0 failed (1 pre-existing unrelated skip)

isfield(model,'genes') alone doesn't distinguish "no genes field" from
"genes field present but empty" -- the latter still wrote a bare
"- genes:" line with nothing after it, which YAML parses as
genes: null rather than an empty list. read_yaml_model then crashes
iterating over that None.

Guard on ~isempty(model.genes) too, so an empty gene list is omitted
the same way an absent genes field already is.
@github-actions

github-actions Bot commented Aug 28, 2026

Copy link
Copy Markdown

Function test results

303 tests   276 ✅  52s ⏱️
 25 suites   27 💤
  1 files      0 ❌

Results for commit 92c5a44.

♻️ This comment has been updated with latest results.

genes is one of cobra's required top-level model keys -- model_to_dict
always includes it, empty or not -- so raven_toolbox.io.write_yaml_model
already emits "- genes: []" for a gene-less model. Omitting the section
entirely, as the previous commit did, meant the two writers no longer
agreed on this line. Match cobra's own convention instead, and teach
readYAMLmodel.m to recognise the flow-style empty list.
@edkerk

edkerk commented Aug 28, 2026

Copy link
Copy Markdown
Member Author

Update: the first commit omitted the `genes:` section entirely for a gene-less model. That doesn't actually match raven-toolbox's output — `genes` is one of cobra's required top-level model keys (`model_to_dict` always includes it), so `raven_toolbox.io.write_yaml_model` already writes `- genes: []` for a gene-less model via cobra's own `model_to_dict`. Second commit switches to `- genes: []` instead, matching that exactly, and teaches `readYAMLmodel.m` to recognise the flow-style empty list. Re-verified byte-parity against raven-toolbox's actual output for the same gene-less model, and re-ran `tIO.m` (14/14 passed).

gene_reaction_rule is one of cobra's required reaction attributes
(model_to_dict always writes it), but nothing on either read side
needs the key present: cobra's own Reaction defaults it to '', and
raven_toolbox.io.read_yaml_model never indexes it directly, so an
absent key round-trips identically to an explicit empty one. Write it
like every other optional field instead (txt, not txtReq) --- the
txtReq case is now unused, so it's removed too.

A deliberate divergence from cobra's own convention, not an oversight;
matching raven_toolbox.io.write_yaml_model (companion change there) is
what matters here.
@edkerk edkerk changed the title writeYAMLmodel: omit the genes section for a gene-less model writeYAMLmodel: drop empty genes/gene_reaction_rule fields Aug 28, 2026
@edkerk
edkerk merged commit 2709121 into develop3 Aug 28, 2026
4 checks passed
@edkerk
edkerk deleted the fix/writeyamlmodel-empty-genes branch August 28, 2026 22:28
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