Gather kcats (Python)#

geckopy objects in geckopy.gather_kcats.

Functions#

Function

Summary

apply_force_wildcards

Escalate ec_token by force_level wildcards from the right.

apply_kcat_list

Choose one kcat value per reaction and write it to model.ec.kcat.

assign_kcats

Assign kcats from the kcat source files and apply them, in place.

assign_standard_kcat

Add a "standard" pseudoenzyme to model and assign it to

build_ec_indices

Group BRENDA table row indices by lowercased ec_code.

build_okp_input_csv

Return the OKP input CSV text for the selected reactions.

collect_kcats

Decide one kcat per reaction from the kcat source files.

combine_kcats

One combined kcat per reaction from the kcat lists of several sources.

CombineParams

Bias and error variance per source and evidence bin.

compact_name

A metabolite name as the compact keys of substrates.tsv: without

diamond_hits

DIAMOND hits (query, target, identity as a fraction) of

ec_rxn_keys

Build-independent keys of the model.ec reactions.

ec_stats_from_brenda

Summarise a BrendaData per EC number.

EcStats

What the database holds for one EC number.

ECTree

EC-tree estimates from a BRENDA measurement table (ec, log10_kcat).

escalate_wildcard

Replace the rightmost numeric level of ec_token with -.

evidence_bin

The evidence bin of a source's value from its detail column.

extract_enzyme_substrate_pairs

Enumerate (reaction, gene, substrate, SMILES, sequence) rows for an ec model.

fetch_open_kinetics_predictor

Check an OKP job and, when finished, download + parse the result.

filter_by_organism

Filter rows of table by organism.

filter_by_substrate

find_ec_rows

Return BRENDA row indices matching ec_token.

Finding

One kcat assignment worth a closer look.

findings_tsv

The findings as a TSV document, header included.

format_kcat_source

Build the provenance string written to model.ec.source.

format_number

Whole numbers as integers, others in the shortest decimal form that

fuzzy_kcat_matching

Match each ec reaction to BRENDA kcat data with progressive

iterative_match_one_ec

Escalate wildcards in ec_token until a match is found or

kcat_assignment_config

Read [kcat_assignment] and [kcat_sources] of the adapter.

kcat_source_file

Path of a kcat source file that may be written.

KcatAssignmentConfig

The kcat assignment settings of an adapter, with a preset expanded.

kcats_from_brenda

Gather kcats from BRENDA by fuzzy matching and keep them as brenda.tsv.

kcats_from_dlkcat

Gather kcats from DLKcat and keep them as dlkcat.tsv.

kcats_from_ec_tree

Estimate kcats from the EC tree and keep them as ec_tree.tsv.

kcats_from_homologs

Estimate kcats from measured homologs and keep them as homologs.tsv.

kcats_from_okp

Gather kcats from OpenKineticsPredictor and keep them as okp_<method>.tsv.

load_combine_params

Read kcatCombineParams.tsv.

load_kcat_source

Read a kcat source file and map its rows to the model.ec reactions.

main_match

Try each of the six search levels in MATLAB's order.

match_kcat

One match attempt at one of the six search levels.

merge_dlkcat_and_fuzzy_kcats

Merge DLKcat predictions with fuzzy BRENDA matches.

merge_kcats

Merge any number of kcat lists, keeping the best source per reaction.

metabolite_inchikeys

InChIKey (first 25 characters) per model metabolite id, where known:

normalize_source

Fold a source label to lowercase snake_case.

okp_file

The source file name of an OKP method, e.g. okp_kinform_h.

okp_methods

The OKP methods of the okp source group ([kcat_sources.okp] methods).

OKPClient

Thin wrapper over the OKP REST endpoints.

OKPError

Raised when the OpenKineticsPredictor API returns an error.

parse_okp_output

Parse an OKP result CSV (text or path) into a kcat_list DataFrame.

read_dlkcat_output

Parse DLKcat's output TSV into a kcat_list DataFrame.

read_kcat_source

Read a kcat source file as it is, without a model.

remove_standard_kcat

Remove the standard pseudoenzyme and any standard kcat

resolve_organism_index

Find the model organism's row in PhylDist.

review_assignment

Assignments worth reviewing, most consequential first.

run_dlkcat

Run DLKcat on a prepared input TSV and return the output path.

save_kcat_source

Write a kcat list to the kcat source file <name>.tsv.

Stage

submit_open_kinetics_predictor

Build the OKP input and submit a kcat-prediction job.

update_kcat_sources

Gather the kcat sources that the configuration needs.

write_dlkcat_input

Write a DLKcat-compatible TSV input file.

Reference#

apply_force_wildcards#

apply_force_wildcards(ec_token: str, force_level: int)

Escalate ec_token by force_level wildcards from the right.

A no-op when force_level == 0 (the common case).

apply_kcat_list#

apply_kcat_list(model: 'EcModel', kcat_list: pd.DataFrame, *, criteria: Optional[Literal['max', 'min', 'median', 'mean']]=None, overwrite: _OverwriteMode=True)

Choose one kcat value per reaction and write it to model.ec.kcat.

Ported from GECKO MATLAB: src/geckomat/gather_kcats/selectKcatValue.m.

For each reaction with one or more entries in kcat_list, aggregate the candidate kcats per criteria ("max" is the default and most common) and write the result into model.ec.kcat at the matching model.ec.rxns position. The contributing entry's provenance is recorded in model.ec.source via format_kcat_source: a lowercase string whose first token is the source and whose bracketed detail, for a fuzzy BRENDA match, carries the wildcard level and origin (e.g. "brenda (wc=0, origin=1)"). If the list has no wildcard_level / origin columns the source is the bare token.

Rows with kcat == 0 mark "no match" and are dropped before aggregation.

For criteria="median" or "mean", the aggregated value does not come from a single input row, so the recorded source is that of the first row in the reaction's group. For "max" and "min" the source is unambiguous (the row whose kcat won).

Parameters

model

EcModel with model.ec.rxns, model.ec.kcat, and model.ec.source already allocated. Mutated in place.

kcat_list

DataFrame with at least the columns rxn_id, kcat (1/s, 0 treated as no-match), and source (per-row). Multiple rows for the same reaction are aggregated per criteria.

criteria

How to aggregate multiple candidates per reaction: "max", "min", "median", or "mean". None (default) reads model.adapter.params.kcat_aggregate_candidates if an adapter is attached, falling back to "max" otherwise.

overwrite

True (default) overwrites unconditionally. False only fills entries currently 0 or NaN. "if_higher" only updates when the new kcat exceeds the existing one (with 0/NaN counted as "infinitely small" so they always update).

Returns

list of str

Reaction IDs whose kcat was updated.

Raises

ValueError

If criteria or overwrite is invalid, or if any rxn_id in kcat_list is absent from model.ec.rxns.

KeyError

If kcat_list is missing the rxn_id, kcat, or source column.

assign_kcats#

assign_kcats(model: 'EcModel', *, adapter: Optional['ModelAdapter']=None, uniprot_db: Optional['UniprotDB']=None, write_report: bool=True)

Assign kcats from the kcat source files and apply them, in place.

Decides one kcat per reaction as collect_kcats does, writes model.ec.kcat and model.ec.source, and applies the kcat constraints. Any kcats the model had are replaced: the source files are the input, and nothing in the model is written back to them.

Returns

(decisions, report)

As returned by collect_kcats.

assign_standard_kcat#

assign_standard_kcat(model: 'EcModel', uniprot_db: 'UniprotDB', *, threshold: int=10, fill_zero_kcat: bool=True)

Add a "standard" pseudoenzyme to model and assign it to

reactions without enzyme constraints.

Ported from GECKO MATLAB: src/geckomat/gather_kcats/getStandardKcat.m.

A standard MW (median of all proteins in uniprot_db) and a standard kcat (median of all non-zero, non-NaN model.ec.kcat values, or a per-subsystem median when the subsystem has at least threshold reactions with a real kcat) are computed. Reactions that lack a GPR rule, or have a GPR but no entry in model.ec.rxns, are added to model.ec with this standard pseudoenzyme.

The function is idempotent: previous "standard" entries (identified by model.ec.source == "standard") are stripped before re-applying.

Filtering: exchange, transport (same metabolite name across compartments), pseudo (name contains "pseudoreaction"), SLIME (name contains "SLIME rxn"), spontaneous (via adapter.get_spontaneous_reactions(model)), and reactions listed in adapter.params.path/data/pseudoRxns.tsv are excluded from receiving the standard pseudoenzyme.

With fill_zero_kcat=True (default), reactions whose existing ec.kcat is 0 or NaN have their kcat replaced with standard_kcat and source set to "standard". They keep their original enzyme assignment.

The function mutates model in place and returns None; the standard MW/kcat and the counts of reactions touched are emitted via logger.info instead.

Parameters

model

EcModel with model.ec already allocated, the protein pool machinery already set up (prot_pool metabolite present in the full-model branch), and model.adapter set. Mutated in place.

uniprot_db

Pre-loaded UniprotDB; used only for the median MW.

threshold

Minimum number of reactions with a real kcat in a subsystem before a subsystem-specific median kcat is used. Subsystems with fewer such reactions fall back to the global standard kcat.

fill_zero_kcat

Whether to replace existing 0/NaN ec.kcat entries with the standard kcat.

Raises

ValueError

If model.adapter is None.

build_ec_indices#

build_ec_indices(table: pd.DataFrame)

Group BRENDA table row indices by lowercased ec_code.

build_okp_input_csv#

build_okp_input_csv(model: 'EcModel', ignore_lists: 'DLKcatIgnoreLists', *, ec_rxns: Optional[Iterable[str]]=None, only_with_smiles: bool=True)

Return the OKP input CSV text for the selected reactions.

Parameters

model

EcModel with ec.sequence and per-metabolite SMILES.

ignore_lists

Loaded DLKcatIgnoreLists (ignored/currency metabolites).

ec_rxns

Optional iterable of reaction IDs (must be in model.ec.rxns). None means all.

only_with_smiles

Drop rows lacking a SMILES when True; otherwise emit "None".

Returns

str

CSV text with header Protein Sequence,Substrate. Duplicate (sequence, SMILES) pairs are collapsed to one row to save quota; the output parser re-maps each prediction back to every matching reaction.

collect_kcats#

collect_kcats(model: 'EcModel', *, adapter: Optional['ModelAdapter']=None, uniprot_db: Optional['UniprotDB']=None, write_report: bool=True)

Decide one kcat per reaction from the kcat source files.

Combines the kcat source files in data/kcats as [kcat_assignment] in model_adapter.toml sets, without changing the model given; assign_kcats applies the decisions.

The order is a preset or [[kcat_assignment.stage]] tables. A stage decides the reactions that are still open:

  • select: the first listed source with a value (see merge_kcats). Sources are source file names and the BRENDA tiers database_exact, database_top and database_bottom, which read brenda.tsv.

  • combine: all listed sources with a value, each corrected for its bias and weighted by its reliability for that reaction (see geckopy.gather_kcats.combine_kcats); ec.source reads combined (sd=<log10 sd>, n=<sources>).

In both, okp stands for the OKP methods of [kcat_sources.okp] methods (default: all methods with combination parameters).

The presets:

  • brenda_ec_tree (the default): custom kcats, the BRENDA median of measurements of the organism on the reaction's substrate (origin 1, without EC wildcards), the EC tree (kcats_from_ec_tree); then the OKP methods combined for the reactions left (without an EC number).

  • ec_tree_homologs: custom kcats, the organism's own BRENDA value; then the EC tree and homologs (kcats_from_homologs) combined; then the OKP methods combined.

  • ec_tree_okp: custom kcats, the organism's own BRENDA value; then the EC tree, homologs and the OKP methods combined; then the OKP methods combined.

  • okp: custom kcats; then the OKP methods combined.

  • gecko_median: custom kcats, the BRENDA median of matches without EC wildcards from the organism or other organisms, with or without the substrate (origin 1 to 4), DLKcat, then the other BRENDA matches (EC wildcards, and specific activities, origin 5 and 6).

  • gecko_classic: as gecko_median with the BRENDA maximum and the specific-activity matches above DLKcat (origin up to 6), as the GECKO 3 tutorial.

Against measured kcats hidden from the search, the EC tree was closer than the BRENDA median at origins 2 and 4 and with EC wildcards and as close at origins 1 and 3; the EC tree combined with the OKP methods was slightly closer than the EC tree, and the OKP methods combined as close. In ecModels, values combined with predictions set high-turnover enzymes such as ATP synthase too low, which is why the default uses predictions only where there is no value from measurements. The BRENDA aggregation is [kcat_sources.brenda] aggregation (see update_kcat_sources).

After the stages: custom kcats of data/customKcats.tsv when a stage lists custom but there is no data/kcats/custom.tsv; with isozymes, kcats from isozymes; with standard, the standard kcat for the rest. A source file a stage names that does not exist is reported and left out.

Parameters

model

The ecModel.

adapter

Model adapter (default: model.adapter).

uniprot_db

UniProt data for the standard kcat (default: data/uniprot.tsv).

write_report

Write the decisions to output/<model id>_kcatDecisions.tsv.

Returns

(decisions, report, ec_model)

decisions has one row per model.ec reaction: ec_rxn, stage (the stage number, custom, isozymes, standard, or empty without a kcat), source, kcat, candidates (values the deciding source had) and spread_log10. report has the preset, the missing source files and, per source file, its load report. ec_model is a copy of the model with the decided kcats, before apply_kcat_constraints.

combine_kcats#

combine_kcats(lists: dict[str, pd.DataFrame], params: CombineParams)

One combined kcat per reaction from the kcat lists of several sources.

Parameters

lists

Per source name (ec_tree, homologs, okp_<method>) its kcat list as load_kcat_source returns it (rxn_id, kcat, detail). Several rows of one source for a reaction (substrates, isozymes) give that source's median, with the evidence bin of its row of best evidence.

params

From load_combine_params.

Returns

pandas.DataFrame

rxn_id, kcat, sd (log10), n (sources), spread_log10 (range of the sources' values) and sources.

CombineParams#

Bias and error variance per source and evidence bin.

compact_name#

compact_name(name: str)

A metabolite name as the compact keys of substrates.tsv: without

markup, Greek letters spelled out, accents dropped, lower case, and only letters, digits and + kept.

diamond_hits#

diamond_hits(queries: dict[str, str], targets: Path, *, min_identity: float=0.4, coverage: float=0.8, threads: Optional[int]=None, diamond: Optional[str]=None)

DIAMOND hits (query, target, identity as a fraction) of

the query sequences against a FASTA file, best identity per pair.

ec_rxn_keys#

ec_rxn_keys(model: 'EcModel')

Build-independent keys of the model.ec reactions.

Returns

(base_rxns, enzyme_sets)

Per model.ec.rxns entry: the conventional reaction (without a trailing _EXP_<n> in a full model, or a leading <nnn>_ in a light model; a reverse direction keeps its _REV), and the UniProt accessions of its enzymes, sorted and joined by " + " (empty without enzymes).

ec_stats_from_brenda#

ec_stats_from_brenda(brenda)

Summarise a BrendaData per EC number.

EcStats#

What the database holds for one EC number.

ECTree#

EC-tree estimates from a BRENDA measurement table (ec, log10_kcat).

escalate_wildcard#

escalate_wildcard(ec_token: str)

Replace the rightmost numeric level of ec_token with -.

Returns the new token, or None if every level is already - (fully wildcarded).

evidence_bin#

evidence_bin(source: str, detail: str)

The evidence bin of a source's value from its detail column.

extract_enzyme_substrate_pairs#

extract_enzyme_substrate_pairs(model: 'EcModel', ignore_lists: 'DLKcatIgnoreLists', *, ec_rxns: Optional[Iterable[str]]=None, only_with_smiles: bool=True)

Enumerate (reaction, gene, substrate, SMILES, sequence) rows for an ec model.

Shared core of write_dlkcat_input and the OpenKineticsPredictor input builder. Performs the same filtering (ignored metabolites, prot_ pseudometabolites, currency-metabolite pairs) and the same only_with_smiles handling, but does no file I/O.

Parameters

model

EcModel with ec.rxns, ec.genes, ec.sequence and ec.rxn_enz_mat populated, and per-metabolite SMILES in annotation['smiles'].

ignore_lists

Loaded DLKcatIgnoreLists.

ec_rxns

Optional iterable of reaction IDs (must be in model.ec.rxns). None means all.

only_with_smiles

Drop rows with no SMILES when True; otherwise write "None".

Returns

pandas.DataFrame

Columns rxn_id, gene, substrate, smiles, sequence, met_id.

fetch_open_kinetics_predictor#

fetch_open_kinetics_predictor(model: 'EcModel', use_stored: bool=False, *, job_id: Optional[str]=None, wait: bool=False, poll_interval: float=30.0, timeout: float=3600.0, api_key: Optional[str]=None, adapter: Optional['ModelAdapter']=None, base_url: str=_BASE_URL, session: Optional[requests.Session]=None, out_file: Optional[str | Path]=None)

Check an OKP job and, when finished, download + parse the result.

Parameters

model

EcModel used to map results back to reactions.

use_stored

If True, skip the API and parse data/OKP_output.csv.

job_id

OKP job id. If omitted, read from data/OKP_job.txt.

wait

If True, poll until the job finishes (or timeout elapses); if False, report once and return.

poll_interval, timeout

Polling cadence and overall deadline (seconds) when wait.

api_key, adapter, base_url, session

Key resolution / adapter / testing knobs (see submit).

out_file

Where the result is stored, and read from with use_stored (default: data/OKP_output.csv).

Returns

(done, kcat_list)

done is True when a result was obtained; kcat_list is the parsed DataFrame then, otherwise None. The DataFrame matches the read_dlkcat_output / fuzzy_kcat_matching schema and feeds apply_kcat_list.

filter_by_organism#

filter_by_organism(table: pd.DataFrame, rows: np.ndarray, organism: Optional[str], phyl_dist: 'PhylDist', org_index: Optional[int])

Filter rows of table by organism.

If organism is given, an exact case-insensitive match is required. Otherwise the rows are restricted to the phylogenetically closest organism(s) per phyl_dist (using org_index as the model-organism row). If org_index is also None, no filtering is applied -- matches MATLAB when the model organism has no KEGG entry.

filter_by_substrate#

filter_by_substrate(table: pd.DataFrame, rows: np.ndarray, substrates: list[str])

find_ec_rows#

find_ec_rows(ec_token: str, ec_indices: dict[str, np.ndarray])

Return BRENDA row indices matching ec_token.

Wildcard handling: the prefix up to the first - is matched case-insensitively against the start of each EC key. A fully- wildcarded -.-.-.- matches every row.

Finding#

One kcat assignment worth a closer look.

findings_tsv#

findings_tsv(rows: Sequence[Finding])

The findings as a TSV document, header included.

format_kcat_source#

format_kcat_source(source: object, wildcard_level: object=None, origin: object=None)

Build the provenance string written to model.ec.source.

The result is lowercase snake_case: the first token is the source (brenda, sabio_rk, catapro, dlkcat, ...), and for a fuzzy BRENDA match the bracketed detail records how the value was obtained -- its wildcard level and origin, e.g. "brenda (wc=0, origin=1)". Rows without fuzzy metadata (an exact OKP database hit or a prediction) render as the bare token, so the bracket's presence and the wildcard/origin numbers give downstream consumers (notably evotune kcat tuning) a quick read on how uncertain the kcat is.

format_number#

format_number(x: Any)

Whole numbers as integers, others in the shortest decimal form that

reads back as the same float; "Inf" for infinity, "" for NaN. Matches GECKO's saveKcatSource.

fuzzy_kcat_matching#

fuzzy_kcat_matching(model: 'EcModel', brenda: 'BrendaData', phyl_dist: 'PhylDist', *, ec_rxns: Optional[Iterable[str]]=None, force_wildcard_level: int=0, aggregate: Optional[str]=None, adapter: Optional['ModelAdapter']=None)

Match each ec reaction to BRENDA kcat data with progressive

relaxation of EC, substrate, and organism specificity.

Ported from GECKO MATLAB: src/geckomat/gather_kcats/fuzzyKcatMatching.m.

For each selected reaction, the EC string in model.ec.eccodes[i] is split on ; into one or more EC tokens. Each token goes through:

  1. Wildcard cascade (per token): try the token as-is. If no match, replace its rightmost numeric level with - and try again. Repeat until matched or all four levels are wildcards.

  2. Six-level matching (per attempt): try increasingly relaxed criteria:

    • org + correct substrate + KCAT (output origin 1)

    • any organism + correct substrate + KCAT (output origin 2)

    • org + any substrate + KCAT (output origin 3)

    • org + specific activity (output origin 5)

    • any organism + any substrate + KCAT (output origin 4)

    • any organism + SA (output origin 6)

    When the EC has any wildcard, substrate-matching levels are skipped (the substrate field of an EC carries the catalytic specificity that wildcards already discard).

Across the multiple EC tokens of one reaction, the best match is chosen by minimum wildcard count, then the earliest-tried level in the order above (so org + SA, origin 5, beats any organism + any substrate + KCAT, origin 4), then maximum kcat.

The model's organism is read from model.adapter.params.org_name. When BRENDA has no exact organism match, phyl_dist is used to pick the BRENDA row(s) for the phylogenetically closest organism(s) (with genus fallback for organisms missing from KEGG).

The six levels are tried in the fixed order listed above, not in order of output rank: org + SA (origin 5) is tried before any organism + any substrate + KCAT (origin 4), so when both would match, org + SA wins even though origin 4 would otherwise be considered the better rank.

Match statistics (counts per origin and per wildcard level) are logged via logger.info rather than returned.

Parameters

model

EcModel with model.ec.rxns and model.ec.eccodes already populated. Reactions whose ec.eccodes entry is empty contribute a row to the output with kcat=0 and origin=NA.

brenda

BRENDA tables loaded by load_brenda_data.

phyl_dist

KEGG phylogenetic distance loaded by load_phyl_dist.

ec_rxns

Optional iterable of reaction IDs (must appear in model.ec.rxns) restricting which entries are matched. None means match all.

force_wildcard_level

Force at least this many wildcards on every EC token before the iterative escalation begins. Default 0 (no forcing).

aggregate

How to collapse the BRENDA rows matched at a search level to one kcat: "max" (the highest reported turnover) or "median" (more robust to assay outliers / engineered mutants). None (default) reads the value from model.adapter.params.kcat_aggregate_brenda, which itself defaults to "max".

The choice drives both aggregation layers consistently: it picks the matching snapshot view (brenda.kcat_for(aggregate) / brenda.sa_for(aggregate)) and applies the same reduction across whichever rows survive the EC + organism + substrate gates. See docs/kcat_aggregation.md for the empirical rationale.

adapter

Model adapter for org_name and the aggregation default (default: model.adapter).

Returns

pandas.DataFrame

Columns:

============ ============================================================ rxn_id (str) reaction ID, matching model.ec.rxns source (str) "brenda" for every row eccode (str) the ;-joined EC string used (after force_wildcard_level but before iterative escalation) substrates (list[str]) per-row substrate names genes (list[str]) always empty for fuzzy matching; kept for schema compatibility with future DLKcat output kcat (float) selected kcat in 1/s, or 0.0 if no match wildcard_level (Int64) actual wildcard count at match time, or NA origin (Int64) output origin 1..6, or NA if no match ============ ============================================================

iterative_match_one_ec#

iterative_match_one_ec(ec_token: str, substrates: list[str], substrate_coeffs: list[float], brenda_kcat: pd.DataFrame, brenda_sa: pd.DataFrame, kcat_ec_indices: dict[str, np.ndarray], sa_ec_indices: dict[str, np.ndarray], organism_name: str, phyl_dist: 'PhylDist', org_index: Optional[int], aggregate: str='max')

Escalate wildcards in ec_token until a match is found or

every level is wildcarded.

Returns (kcat, output_origin, wildcard_level). On no match, returns (0.0, 0, NO_MATCH_WC).

kcat_assignment_config#

kcat_assignment_config(adapter: 'ModelAdapter')

Read [kcat_assignment] and [kcat_sources] of the adapter.

Without a preset or stages the preset is brenda_ec_tree.

kcat_source_file#

kcat_source_file(name: str, *, model: Optional['EcModel']=None, adapter: Optional['ModelAdapter']=None, folder: Optional[str | Path]=None)

Path of a kcat source file that may be written.

Checks the name, resolves the folder (data/kcats in the project folder by default), and refuses a file curated by hand: named custom.tsv, or whose header says kind: curated or source: custom (in any case).

KcatAssignmentConfig#

The kcat assignment settings of an adapter, with a preset expanded.

kcats_from_brenda#

kcats_from_brenda(model: 'EcModel', *, aggregation: Optional[str]=None, force_wildcard_level: int=0, ec_rxns: Optional[Iterable[str]]=None, brenda: Optional['BrendaData']=None, phyl_dist: Optional['PhylDist']=None, save: bool=True, save_as: str='brenda', adapter: Optional['ModelAdapter']=None)

Gather kcats from BRENDA by fuzzy matching and keep them as brenda.tsv.

Runs locally on the BRENDA files of geckopy (see geckopy.gather_kcats.fuzzy_kcat_matching).

Parameters

model

EcModel with EC numbers.

aggregation

Which BRENDA value per EC number, substrate and organism is used: "max" or "median" (default: params.kcat_aggregate_brenda).

force_wildcard_level

Force a minimum wildcard level in the EC numbers.

ec_rxns

model.ec.rxns to gather kcats for (default: all). With the default save_as the file then only holds those reactions.

brenda, phyl_dist

Loaded BRENDA data and KEGG phylogenetic distances (default: loaded from the adapter's folders; PhylDist.mat is downloaded there when missing).

save, save_as

Write the source file, and its name without .tsv.

adapter

Model adapter (default: model.adapter).

Returns

pandas.DataFrame

The kcat list.

kcats_from_dlkcat#

kcats_from_dlkcat(model: 'EcModel', *, run: bool=False, ec_rxns: Optional[Iterable[str]]=None, save: bool=True, save_as: str='dlkcat', adapter: Optional['ModelAdapter']=None)

Gather kcats from DLKcat and keep them as dlkcat.tsv.

With run=True the DLKcat input is written and DLKcat runs through its Docker image (which needs Docker); otherwise the output of an earlier run in data/DLKcat.tsv is read. A run records how many reactions it covered in data/DLKcat_run.txt, so that the source file says so also when the output is read later.

Parameters

model

EcModel with metabolite SMILES and protein sequences.

run

Write the input and run DLKcat (default False).

ec_rxns

model.ec.rxns to run DLKcat for (default: all); needs run.

save, save_as, adapter

As in kcats_from_brenda.

Returns

pandas.DataFrame

The kcat list.

kcats_from_ec_tree#

kcats_from_ec_tree(model: 'EcModel', *, k: float=5.0, ec_rxns: Optional[Iterable[str]]=None, measurements: Optional[pd.DataFrame]=None, save: bool=True, save_as: str='ec_tree', adapter: Optional['ModelAdapter']=None)

Estimate kcats from the EC tree and keep them as ec_tree.tsv.

Each reaction gets the median kcat of all wild-type BRENDA measurements of its EC number, from any organism and substrate, shrunk toward the median of the EC's 3-digit and 2-digit classes with weight n / (n + k) for n measurements (see geckopy.gather_kcats.ec_tree.ECTree). A reaction with several EC numbers uses the one with most measurements. Reactions without an EC number, or whose EC classes have no measurements, get no value.

Parameters

model

EcModel with EC numbers (model.ec.eccodes).

k

Shrinkage constant: the number of measurements at which an EC's own median and its class count equally.

ec_rxns

model.ec.rxns to estimate kcats for (default: all). With the default save_as the file then only holds those reactions.

measurements

BRENDA measurement table (default: measurements.tsv of the adapter's BRENDA folder, see geckopy.databases.load_brenda_measurements).

save, save_as

Write the source file, and its name without .tsv.

adapter

Model adapter (default: model.adapter).

Returns

pandas.DataFrame

The kcat list; detail has the number of measurements of the EC (n) and the deepest EC level with measurements (depth).

kcats_from_homologs#

kcats_from_homologs(model: 'EcModel', *, k: int=10, min_identity: float=0.4, coverage: float=0.8, threads: Optional[int]=None, diamond: Optional[str]=None, save: bool=True, save_as: str='homologs', adapter: Optional['ModelAdapter']=None)

Estimate kcats from measured homologs and keep them as homologs.tsv.

See geckopy.gather_kcats.homologs. One row per reaction and substrate; for an enzyme complex the median of its subunits' estimates. Reactions without a homolog measured on one of their substrates get no value.

Parameters

model

EcModel with enzyme sequences (ec.sequence).

k

The number of most identical homologs averaged.

min_identity, coverage

DIAMOND thresholds: identity, and coverage of both sequences.

threads, diamond

DIAMOND threads, and its executable (default: found by raven-toolbox, which downloads it when needed).

save, save_as

Write the source file, and its name without .tsv.

adapter

Model adapter (default: model.adapter).

Returns

pandas.DataFrame

The kcat list; detail has the identity of the nearest homolog (identity) and the number of homologs used (n).

kcats_from_okp#

kcats_from_okp(model: 'EcModel', *, method: Optional[str]=None, wait: bool=False, resubmit: bool=False, use_stored: bool=False, ec_rxns: Optional[Iterable[str]]=None, save: bool=True, save_as: Optional[str]=None, adapter: Optional['ModelAdapter']=None)

Gather kcats from OpenKineticsPredictor and keep them as okp_<method>.tsv.

OKP is a web service with a job queue, so this can be called repeatedly: without a job for method it submits one; with a job it fetches the result, and writes the file once the job is done. Each method keeps its own job in data/OKP_job_<method>.txt and its own result in data/OKP_output_<method>.csv, so jobs of several methods can run at the same time. The job file records which job the stored result came from; use_stored only uses a result of the current job. An API key is needed.

Parameters

model

EcModel with metabolite SMILES and protein sequences.

method

OKP method, e.g. "CataPro", "CatRange", "UniKP" (default: params.okp.method).

wait

Wait until the job is done.

resubmit

Submit a new job even if one exists for this method; its earlier result is removed.

use_stored

Read the stored result of this method's job without contacting OKP.

ec_rxns

model.ec.rxns to predict for (default: all); only used when a job is submitted.

save, save_as, adapter

As in kcats_from_brenda; save_as defaults to okp_<method>, in lower case, with other characters than letters and digits as _.

Returns

(kcat_list, done)

The kcat list (None while the job is not done), and whether the result was available.

load_combine_params#

load_combine_params(path: str | Path)

Read kcatCombineParams.tsv.

load_kcat_source#

load_kcat_source(model: 'EcModel', name: str | Path, *, adapter: Optional['ModelAdapter']=None)

Read a kcat source file and map its rows to the model.ec reactions.

  1. A row with rxn and enzymes applies to the model.ec rows with that conventional reaction and that enzyme set.

  2. A row with only enzymes applies to every row with that enzyme set; a row with only rxn to every row of that reaction (curated rows; save_kcat_source always writes both).

  3. A row whose kcat is missing, not a number, infinite, or not above 0 is reported as invalid and not applied.

  4. A row that matches nothing is reported, never dropped silently. If a model.ec row has at least half of the row's enzymes, that partial match is reported as well, but not applied.

The enzymes of a row may be listed in any order.

Parameters

model

The ecModel.

name

Name of the source (data/kcats/<name>.tsv in the project folder), or the path to a kcat source file.

Returns

(kcat_list, report)

kcat_list has one row per applied match, in the kcat-list schema (rxn_id, source, eccode, substrates, genes, kcat, wildcard_level, origin) plus log10_sd, detail (the detail column) and line (the line of the file). report has the invalid, unmatched and partial rows.

main_match#

main_match(ec_token: str, substrates: list[str], substrate_coeffs: list[float], brenda_kcat: pd.DataFrame, brenda_sa: pd.DataFrame, kcat_ec_indices: dict[str, np.ndarray], sa_ec_indices: dict[str, np.ndarray], organism_name: str, phyl_dist: 'PhylDist', org_index: Optional[int], aggregate: str='max')

Try each of the six search levels in MATLAB's order.

Returns (kcat, output_origin, num_matches) from the first level that matches. output_origin == 0 means no match.

match_kcat#

match_kcat(ec_token: str, substrates: list[str], substrate_coeffs: list[float], table: pd.DataFrame, ec_indices: dict[str, np.ndarray], organism: Optional[str], *, substrate_match: bool, sa: bool, phyl_dist: 'PhylDist', org_index: Optional[int], aggregate: str='max')

One match attempt at one of the six search levels.

substrate_match restricts table to rows whose substrate is in substrates before the organism filter runs; sa selects the specific-activity table instead of the kcat table. aggregate ("max" or "median") controls how the surviving rows are collapsed to one value.

Returns (kcat_in_1_per_s, num_matched_rows), where kcat is the value picked by aggregate. num_matched == 0 means no rows survived the filters.

merge_dlkcat_and_fuzzy_kcats#

merge_dlkcat_and_fuzzy_kcats(dlkcat_kcats: pd.DataFrame, fuzzy_kcats: pd.DataFrame, *, top_origin_limit: int=4, bottom_origin_limit: int=6, wildcard_limit: int=3)

Merge DLKcat predictions with fuzzy BRENDA matches.

Deprecated alias for merge_kcats with the tiered priority [database_top, dlkcat, database_bottom] (BRENDA preferred over DLKcat, with weaker fuzzy matches as the final fallback). Will be removed in a future release; switch to merge_kcats.

Priority (highest first):

  1. database_top: fuzzy wildcard_level == 0 AND origin <= top_origin_limit (the best BRENDA matches).

  2. dlkcat: any DLKcat row whose reaction is not covered by (1).

  3. database_bottom: weaker fuzzy matches (wc == 0 AND top < origin <= bottom OR 0 < wc <= wildcard_limit AND origin <= bottom) whose reaction is not covered by (2).

Parameters

dlkcat_kcats

DataFrame produced by read_dlkcat_output.

fuzzy_kcats

DataFrame produced by fuzzy_kcat_matching.

top_origin_limit

Origin upper bound for database_top. Must be in [1, 6].

bottom_origin_limit

Origin upper bound for database_bottom. Must be in [1, 6].

wildcard_limit

Maximum wildcard count for the database_bottom wildcard branch. Must be in [0, 3].

Returns

pandas.DataFrame

Merged kcat list in the canonical 8-column schema.

Raises

ValueError

If any limit is outside its allowed range, or if either input is missing required columns.

merge_kcats#

merge_kcats(*kcat_lists: pd.DataFrame, source_priority: Sequence[str], top_origin_limit: int=4, bottom_origin_limit: int=6, wildcard_limit: int=3, database_sources: Iterable[str]=_DEFAULT_DATABASE_SOURCES)

Merge any number of kcat lists, keeping the best source per reaction.

All input lists are concatenated and each row is assigned a tier (see the module docstring). For every reaction the highest-priority tier present wins, and all rows of that tier for that reaction are kept; rows of lower-priority tiers for the same reaction are dropped.

Rows whose kcat is non-positive or missing carry no usable turnover number and are dropped first. This also removes the kcat == 0 / origin == NA rows that fuzzy_kcat_matching emits for unmatched reactions, so a leftover NA-metadata experimental-database row is unambiguously an exact OKP value and is routed to database_top.

Parameters

*kcat_lists

One or more DataFrames in the canonical 8-column kcat-list schema. A single list may mix several sources.

source_priority

Ordered sequence (best first) of tier tokens / source labels. Tokens are normalised the same way as row sources, except the reserved "database_top" / "database_bottom" tiers. A source not listed here is dropped (with a warning).

top_origin_limit

Origin upper bound for database_top fuzzy rows. [1, 6]. Default 4, not 6: origins 5-6 are specific-activity × molecular-weight derived kcats, which BRENDA's own data quality does not always support treating as better than a prediction (a bad SA/MW join can otherwise silently override a good prediction with an outlier -- see load_brenda_data's filter_outlier_kcats, which removes the worst of these before they reach this function, but does not catch every one).

bottom_origin_limit

Origin upper bound for database_bottom fuzzy rows. [1, 6].

wildcard_limit

Maximum wildcard count for the database_bottom wildcard branch. [0, 3].

database_sources

Source labels treated as experimental databases (routed to the database_* tiers). Defaults to ("brenda", "sabio_rk").

Returns

pandas.DataFrame

Merged kcat list in the canonical 8-column schema. Row order follows the input lists (each list's surviving rows, in turn), matching MATLAB mergeKcats. The original (un-normalised) source strings are preserved.

Raises

ValueError

If no list is given, source_priority is empty, a limit is out of range, or any input list is missing required columns.

metabolite_inchikeys#

metabolite_inchikeys(model: 'EcModel', substrates: pd.DataFrame)

InChIKey (first 25 characters) per model metabolite id, where known:

from its ChEBI annotations, then its MetaNetX annotations, then its name.

normalize_source#

normalize_source(label: object)

Fold a source label to lowercase snake_case.

"Sabio-RK" -> "sabio_rk", "DLKcat" -> "dlkcat", "CataPro" -> "catapro". Runs of non-alphanumeric characters collapse to a single underscore; leading/trailing underscores are stripped.

okp_file#

okp_file(method: str)

The source file name of an OKP method, e.g. okp_kinform_h.

okp_methods#

okp_methods(config: KcatAssignmentConfig)

The OKP methods of the okp source group ([kcat_sources.okp] methods).

OKPClient#

Thin wrapper over the OKP REST endpoints.

The session argument exists so tests can inject a mocked requests.Session; in production a fresh session is created.

OKPError#

Raised when the OpenKineticsPredictor API returns an error.

parse_okp_output#

parse_okp_output(model: 'EcModel', result: str | Path)

Parse an OKP result CSV (text or path) into a kcat_list DataFrame.

Parameters

model

EcModel with ec.rxns, ec.genes, ec.sequence, ec.rxn_enz_mat and per-metabolite SMILES populated.

result

Either the CSV text or a path to the result file. Expected columns include kcat (1/s) (CatRange: Predicted kcat range: kcat (1/s), a number or a class range such as 10 to 100 s^-1), Source kcat, Protein Sequence and Substrate; max similarity to <method> training data, when present, gives similarity.

Returns

pandas.DataFrame

Columns rxn_id, source, eccode, substrates, genes, kcat, wildcard_level, origin, similarity (the enzyme's highest sequence similarity to the method's training data, in percent; NaN without the similarity column). source is the per-row provenance from the Source kcat column (the prediction method such as CataPro, or a database such as BRENDA / Sabio-RK / UniProt), prefixed with OKP- to mark it as having come through this pipeline stage (e.g. OKP-CataPro, OKP-BRENDA). merge_kcats recognizes the prefix (after normalize_source folds it to okp_) and still routes an OKP-BRENDA / OKP-Sabio-RK row to the database tiers.

Raises

ValueError

If the file has no numeric kcat values, lacks the required columns, or none of the rows can be mapped to model.ec.rxns.

read_dlkcat_output#

read_dlkcat_output(model: 'EcModel', file_path: str | Path, *, strict: bool=False)

Parse DLKcat's output TSV into a kcat_list DataFrame.

Ported from GECKO MATLAB: src/geckomat/gather_kcats/readDLKcatOutput.m.

The input file is the 6-column TSV that DLKcat writes (see run_dlkcat), with one header line and columns rxn_id, gene, substrate, smiles, sequence, kcat. Rows whose kcat column is non-numeric ("NA", empty, etc.) are silently dropped before validation against the model.

The output DataFrame matches the schema produced by fuzzy_kcat_matching so downstream functions (apply_kcat_list, merge_kcats) can consume both interchangeably. Columns not produced by DLKcat (eccode, wildcard_level, origin) are filled with "" / <NA>.

Substrate names are matched against model.metabolites case-insensitively, so differences in capitalization between the DLKcat output and the SBML-loaded model do not cause spurious failures. A row whose substrate isn't recognized is dropped (with a warning) rather than aborting the whole read, unless strict=True. Either way, the drop counts for non-numeric kcat and unrecognized substrate are logged separately (a row can be counted under both).

Parameters

model

EcModel with populated ec.rxns and metabolites.

file_path

Path to the DLKcat output TSV.

strict

If True, raise ValueError on any unrecognized substrate name instead of dropping just that row. Default False.

Returns

pandas.DataFrame

Rows where the kcat field was numeric and, unless strict=True let an unrecognized substrate through, the substrate was recognized. Columns as listed above; source is "DLKcat" for every row.

Raises

FileNotFoundError

If file_path does not exist.

ValueError

If the file contains no numeric kcat values; if strict=True and any substrate name from the file is not in model.metabolites.<name> (case-insensitive); or if any rxn_id is not in model.ec.rxns.

read_kcat_source#

read_kcat_source(path: str | Path)

Read a kcat source file as it is, without a model.

The file is read as UTF-8 (a leading byte-order mark is ignored). The # lines before the column header are the header; # lines and blank lines further down are skipped. Fields wrapped in double quotes, as a spreadsheet may save them, are unwrapped. kcat and log10_sd must be plain numbers (12, 0.5, 1e-05); other text, such as 5,5 with a decimal comma, is read as NaN, which load_kcat_source reports. A row with more filled fields than there are columns is an error.

Returns

(records, meta)

records has one row per data row: kcat and log10_sd as floats (NaN when empty or not a number), every other column as text; columns other than the standard ones are kept, and line is the line number of each row in the file. meta holds the # header lines as {key: value}.

remove_standard_kcat#

remove_standard_kcat(model: 'EcModel')

Remove the standard pseudoenzyme and any standard kcat

assignments from model.

Ported from GECKO MATLAB: src/geckomat/gather_kcats/removeStandardKcat.m.

Inverse of assign_standard_kcat. Cleans up:

  1. Reactions in ec.rxns whose row in rxn_enz_mat points to the "standard" pseudoenzyme are dropped from all per-reaction ec fields.

  2. The "standard" entry is dropped from all per-enzyme ec fields, and its column is removed from rxn_enz_mat.

  3. Remaining ec.rxns rows where source == "standard" (these are rxns whose existing kcat was filled by fill_zero_kcat=True, but linked to a real enzyme) have their kcat reset to 0 and source cleared.

  4. apply_kcat_constraints is invoked on the affected rxns to update the S matrix.

  5. prot_standard metabolite, usage_prot_standard reaction, and the "standard" gene are removed from the cobra model (if present).

Idempotent: running on a model with no standard pseudoenzyme is a no-op.

Parameters

model

EcModel with a standard pseudoenzyme installed by assign_standard_kcat. Mutated in place.

resolve_organism_index#

resolve_organism_index(org_name: str, phyl_dist: 'PhylDist')

Find the model organism's row in PhylDist.

Returns None if neither a direct match nor a genus fallback is found (in which case organism filtering is skipped, matching MATLAB).

review_assignment#

review_assignment(rxn_ids: Sequence[str], kcats: np.ndarray, sources: Sequence[str], ec_codes: Sequence[str], *, ec_stats: Optional[Mapping[str, EcStats]]=None, enzymes: Optional[Sequence[Iterable[str]]]=None, names: Optional[Sequence[str]]=None, leverage: Optional[np.ndarray]=None, slow: float=0.01, fast: float=10000.0, ec_max_gap: float=3.0, repeat_min: int=5, include: Sequence[str]=(), coverage: Optional[float]=None, top: Optional[int]=None)

Assignments worth reviewing, most consequential first.

Parameters

ec_stats

Per-EC database summary. Checks needing it are skipped when it is absent, so the function still runs without a database.

enzymes

Protein ids per kcat, used to count how many other reactions share an enzyme -- a change here may imply changes there.

leverage

Per-kcat effect on the distance from a one-at-a-time screen. Without it the findings cannot be ranked and are returned in input order.

coverage, top

Truncate the report. coverage keeps the rows carrying that share of the flagged leverage, so 0.9 drops the tail that together accounts for a tenth of what the findings are worth; it adapts to the model where top does not. Measured against all kcats instead, the threshold would be unreachable, since flagged rows are a minority of the model's leverage.

include

Names from OPTIONAL_CHECKS to report as well.

Returns

list of :class:Finding, one per free parameter. :

run_dlkcat#

run_dlkcat(input_path: str | Path, *, output_path: Optional[str | Path]=None, docker_image: str=_DEFAULT_DOCKER_IMAGE, timeout: Optional[float]=None)

Run DLKcat on a prepared input TSV and return the output path.

Ported from GECKO MATLAB: src/geckomat/gather_kcats/runDLKcat.m.

Requires Docker to be installed and the daemon to be running. The DLKcat invocation uses a published image and may take several minutes (longer on first run when the image is downloaded).

Internally the function copies input_path into a temporary directory, mounts that directory into the Docker container at /data, runs DLKcat, and copies the resulting predictions back to output_path. The temporary directory is cleaned up on exit regardless of success or failure.

Parameters

input_path

Path to the DLKcat input TSV (typically the output of write_dlkcat_input).

output_path

Where to write DLKcat's predictions. If None (default), input_path is overwritten, matching MATLAB.

docker_image

Image tag to invoke. Defaults to the published GECKO build.

timeout

Optional subprocess.run timeout in seconds for the Docker invocation. None (default) disables it.

Returns

pathlib.Path

The path to the output file.

Raises

FileNotFoundError

If input_path does not exist.

RuntimeError

If Docker is not installed, the DLKcat container exits non-zero, or no output file is produced.

save_kcat_source#

save_kcat_source(model: 'EcModel', kcat_list: pd.DataFrame, name: str, *, adapter: Optional['ModelAdapter']=None, folder: Optional[str | Path]=None, generator: str='save_kcat_source', parameters: Optional[dict]=None, data: str='', kind: str='gathered')

Write a kcat list to the kcat source file <name>.tsv.

Left out are rows with kcat 0, NaN or below (no value found), and rows of model.ec reactions without enzymes, which have no enzyme constraint and could not be told apart from their isozymes.

Parameters

model

The ecModel the kcat list refers to.

kcat_list

A kcat list as returned by the kcats_from_* functions, fuzzy_kcat_matching, read_dlkcat_output or merge_kcats: columns rxn_id and kcat, optionally substrates, eccode, wildcard_level, origin, source, log10_sd and detail (further key=value pairs for the detail column).

name

Name of the source; the file is <name>.tsv.

adapter

Model adapter (default: model.adapter); gives the project folder.

folder

Folder to write to (default: data/kcats in the project folder).

generator, parameters, data

What produced the values, its settings (written as JSON with sorted keys) and the version of the data they come from.

kind

"gathered" (default) or "curated".

A file named ``custom.tsv``, or whose header says ``kind: curated`` or :

```source: custom``, is never written.` :

Returns

pathlib.Path

The file written.

Stage#

submit_open_kinetics_predictor#

submit_open_kinetics_predictor(model: 'EcModel', *, overwrite: bool=False, api_key: Optional[str]=None, method: Optional[str]=None, ec_rxns: Optional[Iterable[str]]=None, only_with_smiles: bool=True, ignore_lists: Optional['DLKcatIgnoreLists']=None, adapter: Optional['ModelAdapter']=None, base_url: str=_BASE_URL, session: Optional[requests.Session]=None)

Build the OKP input and submit a kcat-prediction job.

Parameters

model

EcModel with ec.sequence and per-metabolite SMILES.

overwrite

Rebuild data/OKP.csv even if it exists (default False reuses an existing file).

api_key

OKP API key. If omitted, resolved from OKP_API_KEY or data/okpApiKey.txt (see the module docstring).

method

Predictor method. Resolved as: this arg -> params.okp.method -> 'CataPro'.

ec_rxns

Optional iterable of reaction IDs to include (default all).

only_with_smiles

Drop entries without a SMILES (default True).

ignore_lists

Pre-loaded DLKcatIgnoreLists; loaded from the project data folder (with bundled fallback) if omitted.

adapter

Model adapter; falls back to model.adapter.

base_url, session

For testing / custom deployments.

Returns

str

The OKP job id (also written to data/OKP_job.txt).

update_kcat_sources#

update_kcat_sources(model: 'EcModel', *, dry_run: bool=False, adapter: Optional['ModelAdapter']=None)

Gather the kcat sources that the configuration needs.

Lists the source files that [kcat_assignment] uses and gathers those that are missing or outdated with kcats_from_brenda, kcats_from_ec_tree, kcats_from_dlkcat and kcats_from_okp. A file is outdated when its header records other settings than [kcat_sources.<name>] asks for (presets set these for brenda and ec_tree) or, for brenda and ec_tree, another BRENDA release than the BRENDA files in use. DLKcat reads data/DLKcat.tsv if it exists and runs DLKcat (Docker) otherwise; OKP submits or fetches a job and reports it as pending while it runs. custom.tsv and files it cannot gather are left as they are. Calling it again is safe.

Returns

pandas.DataFrame

One row per source: source, status (current, gathered, pending, outdated, missing, failed or skipped) and note.

write_dlkcat_input#

write_dlkcat_input(model: 'EcModel', output_path: str | Path, ignore_lists: 'DLKcatIgnoreLists', *, ec_rxns: Optional[Iterable[str]]=None, only_with_smiles: bool=True, overwrite: bool=False)

Write a DLKcat-compatible TSV input file.

Ported from GECKO MATLAB: src/geckomat/gather_kcats/writeDLKcatInput.m.

For each selected ec.rxn, enumerate (substrate, gene-subunit) pairs from the model's stoichiometry and rxn_enz_mat. Each row of output corresponds to one (rxn_id, gene, substrate) triple, plus the substrate's SMILES and the gene's protein sequence. The output file is tab-separated with no header, matching DLKcat's expected input format.

Filtering steps:

  • Metabolites whose normalized name is in ignore_lists.ignore_names (lowercased, alphanumeric-only) are dropped.

  • Metabolites whose annotation['smiles'] matches one of ignore_lists.ignore_smiles are dropped.

  • Metabolites whose ID starts with prot_ (protein-usage pseudometabolites added by earlier pipeline stages) are dropped.

  • Currency pairs: when both halves of a pair appear in the same reaction, both are removed UNLESS removing them would leave the reaction with no substrates.

  • If only_with_smiles is True, rows whose substrate has no SMILES are dropped from the output. Otherwise the SMILES is written as the literal string "None".

SMILES are read from each metabolite's annotation['smiles'], which cobra returns as a list for a model loaded from a file.

Parameters

model

EcModel with populated ec.rxns, ec.genes, ec.sequence, and ec.rxn_enz_mat.

output_path

Path to the output TSV. Refuses to overwrite an existing file unless overwrite=True.

ignore_lists

Pre-loaded DLKcatIgnoreLists (typically from load_dlkcat_ignore_lists).

ec_rxns

Optional iterable of reaction IDs (must be in model.ec.rxns). None means all.

only_with_smiles

When True (default), drop rows whose substrate has no SMILES. When False, write "None" in the SMILES column instead.

overwrite

Allow overwriting an existing output file.

Returns

pandas.DataFrame

The rows that were written, with columns rxn_id, gene, substrate, smiles, sequence, kcat. Useful for tests and inspection. The on-disk file has no header.

Raises

FileExistsError

If output_path exists and overwrite=False.

ValueError

If any ID in ec_rxns is not present in model.ec.rxns, or if any selected reaction is missing from model.reactions.