kg_microbe.transform_utils.prego package

Submodules

kg_microbe.transform_utils.prego.calibration module

Per-resource confidence calibration for PREGO association scores.

prego_score is not one scale. PREGO’s authors assign the genome-derived channels (Isolates, Genome annotation, MAG, SAG) a flat 4-of-5 and the BioProject/PMID rows a flat 3-of-5 — “assigned arbitrarily a confidence level of four out of five” (Zafeiropoulos et al. 2022, §2.3) — while only the Environmental Samples channel carries a computed, varying score. PREGO computes no cross-channel combined score; the shared (0, 5] range is a display convention.

So a single global cutoff is a provenance filter wearing a confidence filter’s clothes: at >= 4.0 it retains 55% of edges, ~85% of which are flat rows carrying no ordering, while deleting ~87% of the one channel whose score actually varies.

This module implements the alternative used by the same lab for TISSUES and DISEASES, and by STRING for its database channel: monotone per-channel recalibration onto one shared star axis, with degenerate channels pinned to a documented constant tier rather than score-ranked.

  • Continuous channel: star = 4 * F_r(score), where F_r is the empirical CDF within resource r (MGnify / MG-RAST metagenome / MG-RAST amplicon each have their own marginal, so a shared CDF would conflate them).

  • Flat channels: star = <author-assigned constant>.

One user-facing knob, tau in [0, 4]: keep an edge iff star >= tau.

Determinism is a requirement, not a nicety — a calibration that shifts between runs silently changes which edges ship. Cutoffs therefore come from fixed-width binned histograms, which are exact to the bin width, O(1) in memory, and independent of row order. Streaming quantile sketches (t-digest, P-square) are deliberately not used: they are order- and implementation-dependent, so two passes over the same file in different chunk orders can disagree.

class kg_microbe.transform_utils.prego.calibration.ScoreHistogram

Bases: object

Fixed-width histogram of raw scores for one resource.

Accumulates in pass 1; inverted to a cutoff in pass 2. Order-independent by construction, so the cutoff is a pure function of the input bytes.

add(score)

Record one observation.

Parameters:

score (float) – Raw PREGO score.

Return type:

None

as_row(resource, tau)

Return a serializable calibration row for this resource.

kept_fraction is what the cutoff actually achieves, which can differ from the requested 1 - tau/4 when a large tie block straddles the target — reporting the realized value keeps the calibration table honest about that.

Parameters:
  • resource (str) – Resource name this histogram was built from.

  • tau (float) – Star threshold the cutoff was derived for.

Return type:

Dict[str, object]

Returns:

Mapping of column name to value.

cutoff(tau)

Return the smallest raw score whose star rating is at least tau.

Solves 4 * F(s) >= tau for the smallest such s, where F is the fraction of observations at or below s. Filtering with score >= cutoff then retains approximately 1 - tau/4 of the resource.

Ties are never split: every row sharing a bin is kept or dropped together, so the ~13% of rows piled at the score cap move as a unit.

Parameters:

tau (float) – Requested star threshold in [0, STAR_MAX].

Return type:

float

Returns:

Raw-score cutoff. 0.0 keeps everything.

Raises:

ValueError – If the histogram is empty.

cutoff_bin(tau)

Return the lowest histogram bin retained at tau.

Both the calibration table and the row filter compare against this, rather than one using a bin edge and the other a raw score. Those are not interchangeable: int(score / 1e-4) * 1e-4 can exceed score for 11.5% of representable 4-dp values — including 1.71, the measured p50 of the real continuous channel. Mixing the two let the table report a tie block as kept while the filter dropped it, a 40-point divergence on a constructed probe.

Parameters:

tau (float) – Star threshold in [0, STAR_MAX].

Return type:

int

Returns:

Bin index; 0 retains everything.

Raises:

ValueError – If the histogram is empty.

kg_microbe.transform_utils.prego.calibration.build_cutoffs(histograms, tau)

Invert per-resource histograms into per-resource raw-score cutoffs.

Parameters:
  • histograms (Mapping[str, ScoreHistogram]) – Resource name to its accumulated histogram.

  • tau (float) – Star threshold in [0, STAR_MAX].

Return type:

Dict[str, float]

Returns:

Resource name to cutoff BIN INDEX (not a raw score) — the filter and the calibration table must compare on the same quantity.

Raises:

ValueError – If tau is outside [0, STAR_MAX].

kg_microbe.transform_utils.prego.calibration.estimate_retention(channel_shares, tau, continuous_share)

Predict the fraction of edges retained at tau, before running a filter.

Flat channels contribute all-or-nothing at their constant tier; the continuous channel contributes 1 - tau/4 by construction of the percentile remap. Useful for warning that a threshold has become provenance-dominant.

Fails closed on an unrecognised channel. Scoring one as 0.0 and excluding it silently — the previous behaviour — turns a typo or a stale key into a confidently wrong number rather than an error, and this function exists precisely to answer “what will this threshold cost me” before a run. Fed the keys of PREGO_RESOURCE_CLASS_STARS, which are resource classes rather than channels (#712), it returned 0.265 where the answer was 0.734.

Parameters:
  • channel_shares (Mapping[str, float]) – Flat channel name to its share of all edges (0-1). Keys must be CHANNEL_* values, not PREGO resource-class names.

  • tau (float) – Star threshold.

  • continuous_share (float) – Share of all edges in the continuous channel.

Return type:

float

Returns:

Predicted retained fraction in [0, 1].

Raises:

ValueError – If a key is not a recognised flat channel.

kg_microbe.transform_utils.prego.calibration.flat_channel_star(channel)

Return a constant tier for a recognised flat channel, or None.

Only the genome/isolate channel is flat. Its rows carry a score PREGO’s authors assigned by fiat rather than computed, so the value is already on the star axis and star_for_row() uses the row’s own score; this function exists to answer “is this channel recognised”, not to substitute a value. PREGO_RESOURCE_CLASS_STARS documents the expected constants.

Parameters:

channel (str) – Value of the prego_channel column.

Return type:

Optional[float]

Returns:

The channel’s documented constant, or None if unrecognised.

kg_microbe.transform_utils.prego.calibration.is_continuous_channel(channel)

Return True for the channel whose score is computed and varies.

This used to match the shape of an evidence tally (402 of 487 samples) because prego_channel carried PREGO’s column 6 verbatim, which was a grab-bag of tallies, resource classes, citations and habitat names. Since that column now holds the archive-derived channel, the check is a direct comparison — and the shape-matching, which silently defined “continuous” for every measurement in PREGO_SCORE_VALIDATION.md, is gone.

Parameters:

channel (str) – Value of the prego_channel column.

Return type:

bool

Returns:

True if the row’s score is computed and varies within-channel.

kg_microbe.transform_utils.prego.calibration.iter_calibration_rows(histograms, tau)

Yield (resource, row) calibration-table entries in deterministic order.

Parameters:
  • histograms (Mapping[str, ScoreHistogram]) – Resource name to its accumulated histogram.

  • tau (float) – Star threshold the table is being generated for.

Return type:

Iterable[Tuple[str, Dict[str, object]]]

Returns:

Iterable of resource name and serializable row.

kg_microbe.transform_utils.prego.calibration.keep_row(channel, score, resource, cutoffs, tau)

Return whether an edge survives the tau threshold.

An unrecognised channel is kept. Dropping rows we cannot calibrate would silently delete data for a reason unrelated to confidence — the same failure this module exists to prevent.

Parameters:
  • channel (str) – Raw prego_channel value.

  • score (float) – Raw prego_score value.

  • resource (str) – Resource the row came from.

  • cutoffs (Mapping[str, float]) – Per-resource cutoff bin indices.

  • tau (float) – Star threshold in [0, STAR_MAX].

Return type:

bool

Returns:

True if the edge should be emitted.

kg_microbe.transform_utils.prego.calibration.star_for_row(channel, score, resource, cutoffs)

Return the calibrated star rating for one edge, or None if uncalibratable.

Flat channels return their constant tier. Continuous rows are compared against their resource’s cutoff; because the cutoff already encodes tau, this returns STAR_MAX for rows at or above it and 0.0 below, which is all the keep/drop decision needs.

Parameters:
  • channel (str) – Raw prego_channel value.

  • score (float) – Raw prego_score value.

  • resource (str) – Resource the row came from (MGnify, MG-RAST, …).

  • cutoffs (Mapping[str, float]) – Per-resource cutoff bin indices from build_cutoffs().

Return type:

Optional[float]

Returns:

Star rating, or None when the channel is unrecognised.

kg_microbe.transform_utils.prego.calibration.validate_tau(tau)

Reject a threshold outside the star axis.

Above STAR_MAX every channel drops to zero retention, which is never what a caller means; refusing is better than silently emitting nothing.

Parameters:

tau (float) – Requested threshold.

Raises:

ValueError – If tau is negative or exceeds STAR_MAX.

Return type:

None

kg_microbe.transform_utils.prego.prego module

PREGO transform — ingest taxon↔environment/process associations.

Reads the three database_pairs.tsv archives from https://prego.hcmr.gr/download/ (documented in the paper’s Appendix D — see docs/PREGO_INGEST_PLAN.md for the full acquisition trail and schema discovery) and emits KGX-format node + edge TSVs plus an unmapped_associations.tsv curation report for rows that were intentionally skipped.

Phase 6a scope (this module): the associations themselves. Phase 6b (dictionary synonym enrichment from prego_dictionary.tar.gz) is a follow-up per the plan’s own ship-6a-first guidance.

Emitted edge shapes (canonical directions matching KGM convention — see utils.classify_row):

  • NCBITaxon:X biolink:capable_of GO:Y (all 3 GO namespaces)

  • ENVO:Y biolink:location_of NCBITaxon:X (matches bacdive)

  • NCBITaxon:X biolink:associated_with MONDO:Y (DOID routed via xref)

Each edge carries per-row PREGO metadata (score, channel, direct_flag, evidence_url) as extra columns beyond the KGX minimum, so downstream consumers can filter by evidence type or threshold on confidence.

class kg_microbe.transform_utils.prego.prego.PregoTransform(input_dir=None, output_dir=None, min_confidence=None, shapes=None, habitat_min_score=None)

Bases: Transform

Ingest PREGO taxon↔environment/process associations.

TRANSFORM_INPUTS: tuple = ('ontologies',)

Reads this transform’s output; see Transform.TRANSFORM_INPUTS (#845).

run(data_file=None, show_status=True)

Read every PREGO archive and emit nodes + edges + unmapped-associations report.

data_file is accepted for base-class compatibility but ignored. PREGO ingests every *.tar.gz in its raw directory — the full three-channel set (literature / environmental_samples / annotated_genomes_isolates) is the intended production input, but any subset works (e.g. the isolates-only canary). show_status toggles the tqdm progress bar; false is used by the pytest suite to keep captured output clean.

kg_microbe.transform_utils.prego.quality module

Fold-enrichment measurement for PREGO association scores.

The percentile calibration in calibration equalizes rank: at min-confidence 2.0 it keeps the top half of each resource. It makes no claim about quality, because nothing anchors it to an external truth.

TISSUES closes that gap by calibrating against a gold standard — “we select the genes and tissues that are in common between the dataset and the gold standard, sort the gene–tissue pairs by raw expression value and calculate fold enrichment in sliding windows of 100 pairs” (Palasca et al. 2018). This module is the equivalent measurement for taxon→GO associations.

fold enrichment = P(pair in gold | pair in window) / P(pair in gold)

where the denominator is the density of the gold standard over the shared entity space. Fold 1.0 means the window matches that baseline — not that the score carries no information, since the baseline weights every subject x object cell equally and so controls for neither taxon annotation depth nor GO-term ubiquity. A degree-preserving null would be a stronger test and is not implemented here.

What this measured, and why the answer depends on the gold standard. Two were tried, and they disagree — which is the most important result here.

Against UniProt proteome annotations (14.4M taxon→GO pairs derived from kg-microbe-function; 4,209 GO terms, 41% of PREGO’s taxon→GO edges comparable), fold enrichment rises with score across the continuous channel: 0.94x → 0.96x → 1.04x → 1.19x. The flat channels sit at 2.19x.

Against metatraits + madin_etal (trait-derived; 78 GO terms, ~1% comparable), it falls: 1.61x → 1.59x → 1.56x, with the flat channels at 1.00x.

The leading hypothesis for the reversal is provenance alignment, which is not established: UniProt annotations come from genome annotation and PREGO’s flat channels are genome-derived (JGI IMG, Struo-GTDB), so their agreement may reflect a shared source rather than either being right. metatraits is trait/literature-derived. Testing this needs a source-overlap exclusion and a degree-matched comparison; until then treat the UniProt figure for the genome channels as provenance agreement rather than quality, and treat any single-gold-standard verdict as provisional.

Effect sizes, stated per benchmark rather than pooled: against UniProt the continuous channel spans 0.94x-1.19x; against the trait-derived standard it spans 1.56x-1.61x. Neither range is accompanied by an uncertainty estimate. The observations are not independent — edges reuse the same taxa, GO terms and resources — so clustered intervals are needed before any ordering of these point estimates is called directional.

Status of the predicate hypothesis: NOT ESTABLISHED. An earlier version of this docstring stated that the score discriminates on location_of edges and not on capable_of ones, citing 1.57x (18/19 ENVO terms) and 1.94x (7/9 BTO terms). Those figures came from a within-term split that used an index median and therefore split tied scores; tie-safe boundaries give 1.49x (18/20) and 1.69x (6/8). BTO is also not an independent replication — it projects the same BacDive isolation source as ENVO.

Under matched taxa and matched label policy the contrast largely dissolves: interaction +0.281, two-way clustered 95% CI [-0.237, +0.624], 82.5% one-sided. Both predicates show weak positive discrimination (1.40 and 1.12) and the difference between them is not distinguishable from zero.

See docs/PREGO_SCORE_VALIDATION.md for the full record, including the corrections list. Do not cite the withdrawn figures.

Separately, the score tracks evidence volume: a GO term’s edge count correlates with its mean score at Spearman +0.26, driven by rare terms scoring low (mean 0.67 in the lowest-ubiquity decile vs ~2.0 everywhere above). Raising a threshold therefore strips rare, specific annotations first — a coverage bias worth knowing about independent of quality.

class kg_microbe.transform_utils.prego.quality.GoldStandard(pairs)

Bases: object

A set of curated (subject, object) pairs plus the entity space it covers.

The entity sets matter as much as the pairs: fold enrichment is only meaningful over subjects and objects the gold standard actually knows about. Scoring a pair whose object the gold standard has never seen would count as a miss for a reason that has nothing to do with quality.

baseline(subjects, objects)

Return the density of the gold standard over a shared entity space.

This is the rate a random pair drawn from subjects x objects would hit, and the denominator of every fold-enrichment figure.

Parameters:
  • subjects (Set[str]) – Subjects shared with the dataset under test.

  • objects (Set[str]) – Objects shared with the dataset under test.

Return type:

float

Returns:

Expected hit rate in [0, 1]; 0.0 if the space is empty.

Raises:

ValueError – If either shared set is empty.

contains(subject, object_)

Return whether the gold standard asserts this pair.

Parameters:
  • subject (str) – Subject CURIE.

  • object – Object CURIE.

Return type:

bool

Returns:

True if the pair is a curated hit.

covers(subject, object_)

Return whether both endpoints are inside the gold standard’s entity space.

Parameters:
  • subject (str) – Subject CURIE.

  • object – Object CURIE.

Return type:

bool

Returns:

True if the pair is comparable.

class kg_microbe.transform_utils.prego.quality.LabelledEvidence(positives, negatives)

Bases: object

Positive/negative labels for (subject, object) pairs.

Unlike GoldStandard, which only knows which pairs are asserted, this knows which are asserted false. That is what makes precision measurable without a null model.

base_rate()

Return the fraction of labelled pairs that are positive.

This is the precision a selector achieves by picking labelled pairs at random, and the only reference point precision needs — it is measured, not modelled.

Return type:

float

Returns:

Base rate in [0, 1].

Raises:

ValueError – If there are no labelled pairs.

label(subject, object_)

Return True, False, or None when the pair is unlabelled.

Parameters:
  • subject (str) – Subject CURIE.

  • object – Object CURIE.

Return type:

Optional[bool]

Returns:

The label, or None if this evidence says nothing about the pair.

kg_microbe.transform_utils.prego.quality.enrichment_by_window(scored, baseline, windows=5)

Return fold enrichment per equal-count score window, ascending by score.

Equal-count windows rather than equal-width: PREGO’s scores pile up at the cap, so equal-width bins would put most of the mass in one bin and measure nothing.

A window whose score range is a single value is flagged via degenerate. Such a window is an arbitrary slice of tied rows — its hit rate reflects whatever order the ties arrived in, not the score — so it must not be read as signal.

Parameters:
  • scored (Sequence[Tuple[float, bool]]) – (score, is_hit) pairs; sorted internally.

  • baseline (float) – Random-expectation hit rate.

  • windows (int) – Number of equal-count windows.

Return type:

List[Dict[str, float]]

Returns:

One dict per window with score bounds, n, hit rate, and fold.

Raises:

ValueError – If windows is not positive.

kg_microbe.transform_utils.prego.quality.fold_enrichment(hit_rate, baseline)

Return enrichment of an observed hit rate over the random expectation.

Parameters:
  • hit_rate (float) – Observed fraction of pairs that are curated hits.

  • baseline (float) – Expected fraction for a random pair.

Return type:

float

Returns:

Fold enrichment relative to baseline; 1.0 matches it.

Raises:

ValueError – If baseline is not positive.

kg_microbe.transform_utils.prego.quality.is_monotone_increasing(results)

Return whether fold enrichment rises with score across non-degenerate windows.

This is the property a usable confidence score must have: a higher score should mean a higher chance of agreeing with curated knowledge. Whether PREGO’s has it depends on the gold standard — rising against UniProt, falling against metatraits — so this predicate exists to make the question checkable per gold standard rather than a matter of opinion.

Degenerate (all-ties) windows are excluded; their ordering is arbitrary.

Parameters:

results (Sequence[Dict[str, float]]) – Output of enrichment_by_window().

Return type:

bool

Returns:

True if fold is non-decreasing across usable windows.

kg_microbe.transform_utils.prego.quality.lift(precision, base_rate)

Return precision relative to the measured base rate.

Distinct from fold_enrichment() in that the denominator is observed rather than derived from a uniform-cell null, so it carries none of that null’s assumptions about how pairs are drawn.

Parameters:
  • precision (float) – Observed precision.

  • base_rate (float) – Fraction of labelled pairs that are positive.

Return type:

float

Returns:

Lift; 1.0 means no better than picking labelled pairs at random.

Raises:

ValueError – If base_rate is not positive.

kg_microbe.transform_utils.prego.quality.precision_by_window(scored, windows=5)

Return precision per equal-count score window, ascending by score.

Precision is the fraction of labelled edges in the window whose label is positive. Compare against LabelledEvidence.base_rate(); a score that discriminates produces windows rising above it.

Windows break only where the score changes, for the same reason as enrichment_by_window() — an index-based slice would let the sort’s tiebreak decide which tied rows land in which window.

Parameters:
  • scored (Sequence[Tuple[float, bool]]) – (score, is_positive) pairs for labelled edges only.

  • windows (int) – Number of equal-count windows.

Return type:

List[Dict[str, float]]

Returns:

One dict per window with score bounds, n, precision, degenerate.

Raises:

ValueError – If windows is not positive.

kg_microbe.transform_utils.prego.utils module

Helpers for the PREGO transform.

Keeps prego.py focused on row → edge emission. Everything here is a pure function that prego.PregoTransform._process_row() can call without touching the transform’s own state.

The JensenLab tagger convention is documented in docs/PREGO_INGEST_PLAN.md §Phase 3. The nine-column database_pairs.tsv schema and the integer entity-type codes live in the constants below; the canonical-direction filter (classify_row()) implements the dedup step described in the plan’s §Phase 6a (every unique association appears twice in the raw archives as (X, Y) AND as (Y, X) — the filter keeps one canonical direction per row shape and drops the inverse in O(1) memory).

kg_microbe.transform_utils.prego.utils.channel_for_archive(archive_name)

Return the PREGO channel an archive belongs to.

Parameters:

archive_name (str) – Archive filename or stem, e.g. environmental_samples.tar.gz.

Return type:

str

Returns:

One of the CHANNEL_* constants, or the normalised stem when the archive is not one of the three documented channels.

kg_microbe.transform_utils.prego.utils.classify_evidence(value)

Classify a raw PREGO column-6 value.

Parameters:

value (str) – The raw value as shipped.

Return type:

str

Returns:

One of the EVIDENCE_* constants.

kg_microbe.transform_utils.prego.utils.classify_row(entity1_type, entity2_type)

Return a short outcome tag for one raw PREGO row.

Callers use the tag either to route the row to build_edge() (any KEEP_* tag) or to increment the unmapped-associations report bucket (any DROP_* tag). See the module docstring for the canonical-direction dedup rationale.

Return type:

str

kg_microbe.transform_utils.prego.utils.edge_metadata_for(channel, evidence_class)

Return (knowledge_level, agent_type) for a PREGO edge.

PREGO edges shipped with both fields empty, so 44.7M text-mined and statistically-derived associations were indistinguishable from curated assertions anywhere in the merged KG. The values differ by channel because the channels are generated by genuinely different processes — a single constant would misdescribe most of them.

A citation overrides the channel default: the row combines curated metadata with text mining over the linked abstract, which the authors themselves score one tier lower.

Within the genome channel, a habitat value means the association comes from sample/isolation metadata rather than the annotation pipeline the channel is named for, so observation describes it and knowledge_assertion does not (#716).

Note this is not a confidence demotion, and the two signals are orthogonal: measured over the first 3M rows of the real genome archive, all 1,693 habitat rows carry score 4 — PREGO’s highest tier, not its lowest. Biolink’s knowledge_level is an unordered description of how the knowledge was produced, so a high-confidence observation is coherent. An earlier version of this docstring claimed those rows scored 3; that was inherited from a review comment and is false.

The habitat rule is deliberately nested inside the genome-channel branch rather than checked before it. Hoisted, it answered for channels this code knows nothing about — edge_metadata_for("metagenomes", "habitat") returned a confident ("observation", "automated_agent") — which breaks the invariant that an unrecognised channel declines to assert provenance.

Parameters:
  • channel (str) – One of the CHANNEL_* constants.

  • evidence_class (str) – One of the EVIDENCE_* constants.

Return type:

Tuple[str, str]

Returns:

Biolink knowledge_level and agent_type values.

kg_microbe.transform_utils.prego.utils.entity_to_curie(entity_type, source_id)

Return the KG-Microbe CURIE for a tagger (type, source_id) pair, or None.

Handles the direct-mapping types (NCBITaxon, all 3 GO namespaces, ENVO, BTO). DOID is intentionally NOT handled here — DOID→MONDO xref resolution is context-dependent (needs the ontologies output’s xref map) so _load_dictionary routes DOID synonyms to their MONDO CURIEs separately.

Return type:

Optional[str]

kg_microbe.transform_utils.prego.utils.go_category_for_type(entity_type)

Return the biolink category matching a GO tagger type integer.

Return type:

str

kg_microbe.transform_utils.prego.utils.iter_database_pairs(path)

Yield (row, error) pairs from a database_pairs.tsv.

row is the raw split list of exactly nine strings when the row is well-formed and error is None. When a row is malformed, row is the raw list (may be any length) and error is a short reason string. Callers should count malformed rows and continue rather than raise — real files carry ~10^8 rows, and one bad line shouldn’t sink the whole transform.

Encoded as a plain generator over line-oriented reads; the caller is responsible for opening a stream-friendly file handle (raw TSV, or tarfile.extractfile() output). No CSV quoting is expected — PREGO files are pure tab-delimited, no embedded quotes.

Return type:

Iterator[Tuple[list, Optional[str]]]

kg_microbe.transform_utils.prego.utils.iter_dictionary_entities(path)

Yield (serial, entity_type, source_id) triples from prego_entities.tsv.

JensenLab tagger convention: three tab-separated columns per row — serial (unique positive integer), entity type (positive for NCBI-species proteins, negative for the standardized vocabularies), and the source-native identifier. Malformed rows are silently skipped; ~2.5 M well-formed rows in the full PREGO dictionary.

Return type:

Iterator[Tuple[int, int, str]]

kg_microbe.transform_utils.prego.utils.iter_dictionary_names(path)

Yield (serial, synonym) pairs from prego_names.tsv.

~13.9 M rows in the full dictionary. Callers must be O(1) per row — materialising as a list defeats the streaming intent.

Return type:

Iterator[Tuple[int, str]]

kg_microbe.transform_utils.prego.utils.load_doid_to_mondo(mondo_nodes_file)

Build a {DOID:xxx: MONDO:yyy} lookup from the ontologies output.

Reads data/transformed/ontologies/mondo_nodes.tsv, which carries a pipe-delimited xref column containing DOID / MESH / NCIT / … aliases per MONDO term. The lookup is small enough (a few tens of thousands of DOID entries) to sit in memory for the full PREGO run.

Returns an empty dict if the file does not exist — the transform will then log-and-skip every DOID row rather than crash, which is the correct behavior when the ontologies transform hasn’t been re-run.

Return type:

Dict[str, str]

Module contents

PREGO transform package — taxon↔environment/process associations from text-mining.