Overview
In the main branch, project_type was parsed from metadata but used only to set complete=True for gnm. DDBJ submission requirements specific to MAG (Metagenome-Assembled Genome) and MAG-WGS — ENV division, MAG keywords, isolate qualifier, metagenome_source, environmental_sample — were not supported.
This implementation adds the following new features relative to the main branch.
mag now triggers complete=True automatically. project_type is stored in GENOME_CONFIG and propagated throughout the pipeline.DIVISION: ENV and keywords ENV, Metagenome Assembled Genome, MAG are emitted automatically.isolate is now propagated end-to-end: metadata file → GENOME_SOURCE_INFORMATION → Genome object → source feature qualifiers → .ann file.required_for / excluded_for columns added to the TSV. Excluding strain and requiring isolate/metagenome_source/environmental_sample for MAG is now controlled purely via TSV — no code changes needed for future project types.environmental_sample (boolean type) now correctly emits a valueless qualifier row even when the value is empty, enabling its use as a MAG placeholder.project_type Recognition and complete Flag
config_util.py / genome.pyconfig_util.py changes
genome.py changes
| project_type | complete | is_mag |
|---|---|---|
mag | ✔ True | ✔ True |
mag-wgs | — False | ✔ True |
gnm | ✔ True | — False |
wgs | — False | — False |
ENV Division and MAG Keywords
metadata_util.py / genome.pyMAG/MAG-WGS submissions go to DDBJ's ENV division. The COMMON entry in the .ann file must include a dedicated block of division and keyword rows.
WGS (unchanged)
MAG-WGS (new)
GNM / complete (unchanged)
MAG / complete (new)
The internal data_file_division field (used in GenBank/EMBL output) also switches from BCT to ENV via genome.py add_source_information().
isolate Field Added
New
The main branch had no isolate support anywhere. Since MAG submissions use isolate instead of strain as the specimen identifier, it was added throughout the pipeline.
Propagation path
SOURCE line in source feature
isolate is declared required_for=mag,mag-wgs, it is rendered for WGS/GNM too when a value is present — the should_render() rule "value present → always render" applies.
TSV-Driven Conditional Field Control
New Architecture
In the main branch, MetadataField had no concept of project_type, and EX_SOURCE rendering used the simple condition field.value or field.mss_required. This implementation replaces that with two new TSV columns and four new methods.
New and updated rows in metadata_definition.tsv
| Field | type | feature | mss_required | required_for (new) | excluded_for (new) |
|---|---|---|---|---|---|
strain (existing) | string | source | TRUE | — | mag,mag-wgs |
isolate ★ new | string | source | FALSE | mag,mag-wgs | — |
metagenome_source ★ new | string | EX_SOURCE | FALSE | mag,mag-wgs | — |
environmental_sample ★ new | boolean | EX_SOURCE | FALSE | mag,mag-wgs | — |
New methods on MetadataField
def is_required_for(self, project_type: str) -> bool: return project_type in self.required_for def is_excluded_for(self, project_type: str) -> bool: return project_type in self.excluded_for def effective_required(self, project_type: str) -> bool: if project_type in self.excluded_for: return False if project_type in self.required_for: return True return self.mss_required # project_type-independent default def should_render(self, project_type: str) -> bool: if project_type in self.excluded_for: return False # excluded even if value is set if self.value: return True # value present → always render return self.effective_required(project_type) # render placeholder if required
render_ex_source() changes
get_field_definition() — new module-level function
Used by genome.py to look up TSV field definitions when building source feature qualifiers. Parses the TSV once and caches the result.
# module level _FIELD_DEF_CACHE: "dict | None" = None def get_field_definition(name: str): global _FIELD_DEF_CACHE if _FIELD_DEF_CACHE is None: _FIELD_DEF_CACHE = {} # parse TSV once, populate cache ... return _FIELD_DEF_CACHE.get(name)
ff_definition Template Switch
ddbj_submission.py
In the main branch, ff_definition always used @@[strain]@@. For MAG/MAG-WGS, where strain is excluded, it now switches to @@[isolate]@@.
| project_type | ff_definition template |
|---|---|
mag | @@[organism]@@ @@[isolate]@@ DNA, complete genome |
mag-wgs | @@[organism]@@ @@[isolate]@@ DNA, @@[submitter_seqid]@@ |
gnm | @@[organism]@@ @@[strain]@@ DNA, complete genome |
wgs | @@[organism]@@ @@[strain]@@ DNA, @@[submitter_seqid]@@ |
Output File Naming
ddbj_submission.py
The main branch always used the biosample_strain pattern for output file names. Since MAG does not use strain, the identifier is now chosen based on is_mag.
| Condition | Output filename |
|---|---|
| MAG + biosample set + isolate set | SAMDxxxxxxxx_MAG-001.ann |
| MAG + biosample only | SAMDxxxxxxxx.ann |
| WGS + biosample set + strain set | SAMDxxxxxxxx_strain.ann |
| None set | mss.ann |
Boolean Field render() Fix
metadata_util.py
In the main branch, the boolean render path emitted a valueless qualifier only when the value was explicitly set (anything other than "NO"). With an empty value it returned [], making it impossible to emit environmental_sample as a placeholder for MAG submissions.
render() returns [], render_ex_source() adds a fallback valueless placeholder row if should_render() is True. This ensures environmental_sample always appears in MAG output, even when the user has not set a value.
Tests
46 new testsTest categories
| Category | What it covers | Count |
|---|---|---|
| MetadataField unit | should_render, effective_required, is_excluded_for, etc. |
~12 |
| TSV parsing | required_for/excluded_for columns, backward compatibility with 9-column rows |
~6 |
| render_ex_source | Per-field output for MAG/WGS, boolean valueless placeholder | ~8 |
| Genome source features | strain excluded, isolate placeholder, isolate rendered for WGS when set | ~8 |
| render_common_entry | DIVISION/KEYWORD block output for MAG and MAG-WGS | ~4 |
| DDBJ submission output | create_ff_definiton identifier switch, file prefix generation |
~8 |
Changed Files
isolate to GENOME_SOURCE_INFORMATION keys. Added mag to complete=True trigger. Stored project_type in GENOME_CONFIG.
required_for/excluded_for to MetadataField with 4 new methods. Extended TSV parser. Added render_common_entry(project_type) ENV/MAG keyword output. TSV-driven render_ex_source(project_type). New get_field_definition(). Fixed boolean render.
required_for/excluded_for). Added 3 new rows: isolate, metagenome_source, environmental_sample. Set excluded_for=mag,mag-wgs on strain.
self.project_type, self.is_mag, self.isolate. Updated add_source_information() for ENV division and isolate. Changed add_source_features() to TSV-driven strain/isolate logic.
is_mag parameter; replaced with project_type. Switched @@[strain]@@ → @@[isolate]@@ in create_ff_definiton. Updated get_file_prefix() to use isolate for MAG. Added ENV division to JSON conversion.