tablassert 7.4.14__tar.gz → 7.5.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tablassert-7.5.1/AGENTS.md +57 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/CHANGELOG.md +23 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/PKG-INFO +1 -1
- {tablassert-7.4.14 → tablassert-7.5.1}/docs/api/lib.md +18 -14
- {tablassert-7.4.14 → tablassert-7.5.1}/docs/api/qc.md +6 -6
- {tablassert-7.4.14 → tablassert-7.5.1}/docs/api/utils.md +26 -7
- tablassert-7.5.1/docs/changelog.md +16 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/docs/cli.md +2 -2
- {tablassert-7.4.14 → tablassert-7.5.1}/docs/configuration/advanced-example.md +19 -21
- {tablassert-7.4.14 → tablassert-7.5.1}/docs/configuration/graph.md +16 -16
- {tablassert-7.4.14 → tablassert-7.5.1}/docs/configuration/table.md +37 -30
- {tablassert-7.4.14 → tablassert-7.5.1}/docs/docker.md +6 -4
- {tablassert-7.4.14 → tablassert-7.5.1}/pyproject.toml +1 -1
- {tablassert-7.4.14 → tablassert-7.5.1}/src/tablassert/cli.py +18 -14
- {tablassert-7.4.14 → tablassert-7.5.1}/src/tablassert/lib.py +57 -11
- {tablassert-7.4.14 → tablassert-7.5.1}/src/tablassert/progress.py +13 -5
- {tablassert-7.4.14 → tablassert-7.5.1}/tests/test_lib.py +211 -1
- tablassert-7.5.1/tests/test_progress.py +48 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/uv.lock +1 -1
- tablassert-7.4.14/AGENTS.md +0 -50
- tablassert-7.4.14/docs/changelog.md +0 -25
- {tablassert-7.4.14 → tablassert-7.5.1}/.github/workflows/docker.yml +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/.github/workflows/docs.yml +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/.github/workflows/pipy.yml +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/.gitignore +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/.pre-commit-config.yaml +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/CITATION.cff +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/CONTRIBUTING.md +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/Dockerfile +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/LICENSE +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/README.md +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/docs/api/fullmap.md +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/docs/datassert.md +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/docs/examples/tutorial-data.csv +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/docs/examples/tutorial-graph.yaml +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/docs/examples/tutorial-table.yaml +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/docs/examples.md +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/docs/index.md +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/docs/installation.md +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/docs/tutorial.md +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/llms.txt +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/mkdocs.yml +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/src/tablassert/__init__.py +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/src/tablassert/downloader.py +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/src/tablassert/enums.py +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/src/tablassert/fullmap.py +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/src/tablassert/ingests.py +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/src/tablassert/log.py +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/src/tablassert/models.py +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/src/tablassert/nlp.py +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/src/tablassert/qc.py +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/src/tablassert/utils.py +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/tests/__init__.py +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/tests/conftest.py +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/tests/fixtures/invalid_section_missing_source.yaml +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/tests/fixtures/minimal_section.yaml +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/tests/fixtures/minimal_section_with_sections.yaml +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/tests/test_downloader.py +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/tests/test_enums.py +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/tests/test_fullmap.py +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/tests/test_ingests.py +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/tests/test_models.py +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/tests/test_nlp.py +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/tests/test_qc.py +0 -0
- {tablassert-7.4.14 → tablassert-7.5.1}/tests/test_utils.py +0 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# AGENTS.md — Tablassert
|
|
2
|
+
|
|
3
|
+
## Fast Start
|
|
4
|
+
|
|
5
|
+
- Python package, not a monorepo. Main code lives in `src/tablassert/`; tests live in `tests/`.
|
|
6
|
+
- Install with `uv sync`. Three optional extras:
|
|
7
|
+
- `--extra qc` / `--extra qc-cuda` — installs `onnxruntime` / `onnxruntime-gpu` for QC (strict runtime behavior below).
|
|
8
|
+
- `--extra rt` — runtime-compatible Polars build for CPUs missing required SIMD instructions.
|
|
9
|
+
- CLI entrypoint is `tablassert.cli:APP`. Real user commands:
|
|
10
|
+
- `uv run tablassert build <graph.yaml>` — 6 pipeline stages.
|
|
11
|
+
- `uv run tablassert validate <table.yaml>` — 3 stages, syntax-only.
|
|
12
|
+
|
|
13
|
+
## Source of Truth
|
|
14
|
+
|
|
15
|
+
- When prose docs and code disagree, `src/tablassert/models.py` and `src/tablassert/cli.py` are authoritative. Docs drift: some pages claim shard files are `{0..11}.duckdb` or that only the `rt` extra exists; the code uses `SHARDS = 10` (so `0..9`) and exposes `qc`/`qc-cuda`/`rt` extras.
|
|
16
|
+
|
|
17
|
+
## Verify Changes
|
|
18
|
+
|
|
19
|
+
- Match the repo hooks before finishing: `uv run ruff check --fix .`, `uv run ruff format .`, `uv run pyright`, `uv run pytest`.
|
|
20
|
+
- Full hook run: `uv run pre-commit run --all-files` (ruff, ruff-format, pyright, pytest).
|
|
21
|
+
- Focused test runs:
|
|
22
|
+
- Single test: `uv run pytest tests/test_lib.py::test_name`
|
|
23
|
+
- By keyword: `uv run pytest -k "pattern"`
|
|
24
|
+
- With print output: `uv run pytest -s tests/test_lib.py`
|
|
25
|
+
- Docs build: `uv run --group dev mkdocs build`.
|
|
26
|
+
|
|
27
|
+
## High-Value Structure
|
|
28
|
+
|
|
29
|
+
- `src/tablassert/cli.py` is the wiring layer: `build()` → `build_pipeline()`, `validate()` → `validate_pipeline()`.
|
|
30
|
+
- `src/tablassert/ingests.py` loads YAML and expands table configs into section dicts.
|
|
31
|
+
- `src/tablassert/lib.py` is the core pipeline:
|
|
32
|
+
- `Tcode.collect()` builds the per-section operation list.
|
|
33
|
+
- `compile_subgraph()` executes that list into parquet.
|
|
34
|
+
- `compile_graph()` aggregates subgraph parquets into KGX NDJSON.
|
|
35
|
+
- `resolve_many()` is the direct library API for batch entity resolution.
|
|
36
|
+
- Entity resolution uses DuckDB shard files at `<datassert>/data/{0..9}.duckdb`, opened read-only. `datassert` is a required `Path` field on the `Graph` model (not a fixed location); `src/tablassert/fullmap.py` hardcodes `SHARDS = 10`.
|
|
37
|
+
|
|
38
|
+
## Repo-Specific Gotchas
|
|
39
|
+
|
|
40
|
+
- Heavy dependencies are lazy-loaded per module with `TYPE_CHECKING` + `lazy_loader`. Follow the existing pattern instead of importing heavy packages eagerly. Lazy-loaded: polars, duckdb, orjson, xxhash, polars_hash, yaml, httpx, pyexcel, onnxruntime, sentence_transformers.
|
|
41
|
+
- `tests/conftest.py` autouse-mocks `httpx.head`, so model-URL validation tests never hit the network unless a test opts in.
|
|
42
|
+
- Network-dependent tests are marked `@pytest.mark.network`; GPU QC tests are marked with both `network` and `gpu` in `tests/test_qc.py`.
|
|
43
|
+
- QC runtime selection is strict in `src/tablassert/qc.py`: if `onnxruntime-gpu` is installed but `CUDAExecutionProvider` is unavailable, the code raises (error 06) instead of falling back to CPU. Install `tablassert[qc]` for CPU-only.
|
|
44
|
+
- Downloader behavior in `src/tablassert/downloader.py` is two-path: `direct()` via `httpx` for known file URLs, `browser()` via Playwright fallback for browser-only sources. Keep payload-validation and cleanup tests intact when changing it.
|
|
45
|
+
|
|
46
|
+
## Conventions That Matter Here
|
|
47
|
+
|
|
48
|
+
- Start every module with `from __future__ import annotations`.
|
|
49
|
+
- Annotate every variable, including locals.
|
|
50
|
+
- Use `Optional[T]` / `Union[...]`, not `T | None`. Use `Path`, not `str`, for filesystem paths. Use `# pyright: ignore` to silence lazy-load false positives.
|
|
51
|
+
- No docstrings on functions. Use comment markers on the line above: `# ?` description, `# !` warning, `# *` pipeline stage, `# TODO:` todo.
|
|
52
|
+
- Pydantic models inherit `TablaBase` (`extra="forbid"`, `validate_assignment=True`). Required fields use `Field(...)`; optional use `Optional[T] = Field(None)`. Enums extend `str, Enum` and live in `enums.py`.
|
|
53
|
+
- Per-module logger: `from tablassert.log import cat; logger = cat("MODULE")` (e.g. `cat("FULLMAP")`). The CLI uses the root `from tablassert.log import logger`. Raise `RuntimeError` for failures; `logger.warning()` for non-fatal issues.
|
|
54
|
+
|
|
55
|
+
## Side Effects
|
|
56
|
+
|
|
57
|
+
- The package writes working artifacts to hidden dirs in the repo root, each defined in code: `.storassert/` (`utils.STORE`), `.logassert/` (`log.LOGASSERT`), `.cachassert/` (`models.CACHE`), `.onnxassert/` (`qc.MODEL`).
|
|
@@ -2,6 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project are documented in this file.
|
|
4
4
|
|
|
5
|
+
## 7.5.1 - 2026-07-01
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
- Numeric annotation columns are now coerced and emitted as controlled-notation strings in NDJSON output instead of raw values. Two new pipeline steps wired into `Tcode.collect()` (`lib.py`): `clean_numeric()` lazily casts matching columns to `Float64` with `strict=False` (non-numeric entries drop to null), and `format_numeric()` renders them as strings — p-value columns (any name containing `"p value"`, case-insensitive) in scientific notation (`{:.4e}`), and `relationship strength` / `sample size` in decimal general format (`{:.4g}`, ≥4 significant figures). Non-matching columns are left untouched, and nulls are subsequently dropped by `strip_nulls()`. `math_op()` now also casts with `strict=False` so it tolerates residual junk in numeric annotation columns. `format_numeric()` formats via numpy-backed batch conversion rather than `map_elements` for throughput.
|
|
9
|
+
- Removed dead `pl.Config(set_fmt_float=...)` and `pl.Config(float_precision=...)` context managers from `compile_graph()` (`lib.py`); they were no-ops for NDJSON serialization (`write_ndjson` emits raw f64 via serde shortest-repr and ignores float display options), and the `fmt`/`precision` parameters of `compile_graph()` were removed alongside them.
|
|
10
|
+
- Fixed an off-by-one in the build/validate progress bar so each section loop now shows the configuration currently being processed instead of the last-completed one. `PipelineProgress.section_loop()` (`progress.py`) previously returned a single `advance(info)` callback that set the description and ticked the completed counter together, called after each item's work — so while section *K* ran the bar still displayed section *K−1*. It now returns a `(start, advance)` pair: `start(info)` updates the description to the in-flight item without incrementing, and `advance()` ticks the counter afterwards (so the counter never claims an in-flight item is complete). All five call sites in `cli.py` (TCode build, Collect, Subgraph, Graph, Validate) were updated to `start(...)` before the work and `advance()` after; the long-running Collect and Subgraph stages continue to show the full `format_section_oneline()` summary (including the `CONFIG` name) of the in-flight section.
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- Fifteen regression tests in `test_lib.py` covering `numeric_columns()` detection (p-value substring, exact-name match, case-insensitivity), `clean_numeric()` (parse/coerce numeric and scientific notation, null out non-numeric junk, leave non-matching columns untouched, noop, idempotent on Float64), `format_numeric()` (scientific notation for p-value, decimal general format for relationship strength/sample size, null preservation, floating-point-noise cleaning, noop), null-stripped NDJSON rows, `compile_graph()` NDJSON emission, and `sig()` operating over a cleaned Float64 p-value column.
|
|
14
|
+
- Three regression tests in `tests/test_progress.py` pinning the new two-callback contract: `start` shows the in-flight item with the counter still at zero, `advance` ticks the counter without altering the description, and a `start`/`advance` cycle keeps the description synced to the current item rather than the previous one.
|
|
15
|
+
|
|
16
|
+
## 7.5.0 - 2026-07-01
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
- Publication CURIEs in `compile_subgraph()` (`lib.py`) now use the `PMCID:` namespace prefix for PubMed Central sources. A `repo: PMC` section with `publication: PMC11708054` is emitted as `PMCID:PMC11708054` (previously `PMC:PMC11708054`); non-PMC repos such as `PMID` are unaffected and continue to emit `<repo>:<publication>` (e.g., `PMID:11708054`). The `repository` edge column is unchanged and still records the raw `repo` value. Extracted via a new `publication_curie()` helper.
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
- New `<col> table literal value` edge column for subject, object, and qualifier nodes encoded with `method: column`. Unlike the existing `original <col>` column (which snapshots the value *after* all `fill`/`explode_by`/`regex`/`remove`/`prefix`/`suffix`/`transformations`), `<col> table literal value` captures the pristine source-cell value *before* any transformation. Emitted only for column-encoded nodes; annotations and `method: value` nodes are unaffected. Implemented via a `table_literal` flag on `Tcode.encoding()`, enabled by `Tcode.node()`.
|
|
23
|
+
- Four regression tests in `test_lib.py`: `publication_curie()` for PMC and PMID namespaces, and two `Tcode` tcode-inspection tests covering presence/ordering of the table-literal column for column encodings and its absence for value encodings.
|
|
24
|
+
|
|
25
|
+
### Documentation
|
|
26
|
+
- Comprehensive accuracy pass across the API, configuration, and Docker documentation, reconciling every page against the current codebase. Highlights: corrected invalid examples that would not load (`syntax: TC2`; `publication` integers and missing `PMC` prefixes; a non-existent `Qualifiers` member; `reindex` placed at section level; a subject missing `method: column`), fixed wrong field types (`rows`/`row_slice`/`taxon` → `PositiveInt`, `remove` → regex patterns), corrected the QC fuzzy thresholds (`fuzz.ratio >= 20 OR partial_token_sort_ratio >= 30`), removed a non-existent `uuid:` prefix from `utils.md` return examples, fixed the `resolve_many()` parameter order and added the original-column-capture and optional QC-audit pipeline steps, corrected graph-config path resolution (CWD, not config-relative) and processing-flow ordering, documented the strict QC GPU no-fallback behavior and the `.cachassert/` working directory, and aligned `Categories` enum member names (`GENE`/`PROTEIN`) and Docker CI triggers with the source.
|
|
27
|
+
|
|
5
28
|
## 7.4.14 - 2026-06-30
|
|
6
29
|
|
|
7
30
|
### Changes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tablassert
|
|
3
|
-
Version: 7.
|
|
3
|
+
Version: 7.5.1
|
|
4
4
|
Summary: Extract knowledge assertions from tabular data into NCATS Translator-compliant KGX NDJSON — declaratively, with entity resolution and quality control built in.
|
|
5
5
|
Project-URL: Homepage, https://github.com/SkyeAv/Tablassert
|
|
6
6
|
Project-URL: Source, https://github.com/SkyeAv/Tablassert
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
The `lib` module exposes `resolve_many()`, a high-level convenience function for resolving an iterable of entity strings to CURIEs without requiring manual LazyFrame construction, NLP preprocessing, or DuckDB shard management.
|
|
4
4
|
|
|
5
|
-
It wraps the lower-level [`resolve()`](fullmap.md) pipeline — applying `level_one` and `level_two` normalization, opening all 10 DuckDB shard connections, executing entity resolution, and returning results as a plain Python list of row dictionaries.
|
|
5
|
+
It wraps the lower-level [`resolve()`](fullmap.md) pipeline — preserving the original input text, applying `level_one` and `level_two` normalization, opening all 10 DuckDB shard connections, executing entity resolution, optionally running the QC audit (when `qc=True`), and returning results as a plain Python list of row dictionaries.
|
|
6
6
|
|
|
7
7
|
## resolve_many()
|
|
8
8
|
|
|
@@ -18,8 +18,8 @@ def resolve_many(
|
|
|
18
18
|
taxon: Optional[str] = None,
|
|
19
19
|
prioritize: Optional[list[Categories]] = None,
|
|
20
20
|
avoid: Optional[list[Categories]] = None,
|
|
21
|
-
column_context: bool = True,
|
|
22
21
|
qc: bool = False,
|
|
22
|
+
column_context: bool = True,
|
|
23
23
|
) -> list[dict[str, Any]]
|
|
24
24
|
```
|
|
25
25
|
|
|
@@ -52,29 +52,29 @@ Each shard contains:
|
|
|
52
52
|
|
|
53
53
|
Optional NCBI Taxon ID for filtering results to a specific organism.
|
|
54
54
|
|
|
55
|
-
Example: `"9606"` restricts matches to human-specific
|
|
55
|
+
Example: `"9606"` restricts **gene** matches to human-specific entries; non-gene categories (e.g., diseases, chemicals) are returned regardless of taxon. When `None`, no taxon filtering is applied and matches from all organisms are returned.
|
|
56
56
|
|
|
57
57
|
**`prioritize: Optional[list[Categories]]` (default: `None`)**
|
|
58
58
|
|
|
59
59
|
Optional list of Biolink categories to prefer when multiple matches exist for the same input term. Categories listed here receive higher ranking scores during resolution.
|
|
60
60
|
|
|
61
|
-
Example: `[Categories.
|
|
61
|
+
Example: `[Categories.GENE, Categories.PROTEIN]` prefers gene and protein mappings over other categories like diseases or chemicals.
|
|
62
62
|
|
|
63
63
|
**`avoid: Optional[list[Categories]]` (default: `None`)**
|
|
64
64
|
|
|
65
65
|
Optional list of Biolink categories to exclude from results entirely. Any match belonging to an avoided category is filtered out before ranking.
|
|
66
66
|
|
|
67
|
-
Example: `[Categories.
|
|
67
|
+
Example: `[Categories.GENE]` prevents gene mappings from appearing in the output, even if they would otherwise be the best match.
|
|
68
68
|
|
|
69
69
|
**`column_context: bool` (default: `True`)**
|
|
70
70
|
|
|
71
|
-
Controls category-frequency tie-breaking when multiple matches exist for a term. When `True`, the
|
|
71
|
+
Controls category-frequency tie-breaking when multiple matches exist for a term. When `True`, the deduplication stage adds a category-frequency score (computed in Polars after the SQL query) and prefers the category that appears most frequently across all matched terms in the batch. When `False`, frequency-based tie-breaking is disabled.
|
|
72
72
|
|
|
73
73
|
This is useful when resolving a column of related entities (e.g., all genes) — the shared context helps disambiguate terms that map to multiple categories.
|
|
74
74
|
|
|
75
75
|
**`qc: bool` (default: `False`)**
|
|
76
76
|
|
|
77
|
-
When `True`, runs the QC audit stage after entity resolution. The QC pipeline validates mappings through a three-stage audit: exact match, fuzzy matching via rapidfuzz, and BioBERT sentence embeddings with cosine similarity. Requires a QC runtime to be installed (`tablassert[qc]` or `tablassert[qc-cuda]`). The ONNX Runtime provider is auto-detected based on the installed package — CUDA is preferred when `onnxruntime-gpu` is available
|
|
77
|
+
When `True`, runs the QC audit stage after entity resolution. The QC pipeline validates mappings through a three-stage audit: exact match, fuzzy matching via rapidfuzz, and BioBERT sentence embeddings with cosine similarity. Mappings that fail all three stages are dropped from the returned list (in addition to the unresolved-entity filtering performed by `resolve()`). Requires a QC runtime to be installed (`tablassert[qc]` or `tablassert[qc-cuda]`). The ONNX Runtime provider is auto-detected based on the installed package — CUDA is preferred when `onnxruntime-gpu` is installed and `CUDAExecutionProvider` is available; if only `onnxruntime` (CPU) is installed, CPU is used. Note: if `onnxruntime-gpu` is installed but `CUDAExecutionProvider` is unavailable, QC raises rather than falling back to CPU.
|
|
78
78
|
|
|
79
79
|
### Return Value
|
|
80
80
|
|
|
@@ -101,13 +101,17 @@ Each dictionary contains the following keys (where `{col}` is the value of the `
|
|
|
101
101
|
|
|
102
102
|
1. **Series construction** — Wraps the input iterable in a `pl.Series` with the given column name, then converts to a single-column `pl.LazyFrame`.
|
|
103
103
|
|
|
104
|
-
2. **
|
|
104
|
+
2. **Original column capture** — Copies the raw input column into `original {col}` via `column(lf, add("original ", col), col)` so the pre-normalization text is preserved in the output.
|
|
105
|
+
|
|
106
|
+
3. **NLP normalization** — Applies `level_one()` (whitespace stripping + lowercasing) and `level_two()` (non-word character removal via `\W+`) to produce the two normalized columns required by `resolve()`.
|
|
107
|
+
|
|
108
|
+
4. **DuckDB connection management** — Opens all 10 shard connections inside a `contextlib.ExitStack`, ensuring every connection is properly closed when resolution completes or if an error occurs.
|
|
105
109
|
|
|
106
|
-
|
|
110
|
+
5. **Entity resolution** — Delegates to `fullmap.resolve()` which queries the sharded DuckDB database, ranks matches by category priority, preferred-name exactness, NLP level, and category frequency, then deduplicates to one CURIE per input string.
|
|
107
111
|
|
|
108
|
-
|
|
112
|
+
6. **QC audit (optional)** — When `qc=True`, runs `fullmap_audit()` on the resolved LazyFrame. Rows that fail all three audit stages are dropped from the result.
|
|
109
113
|
|
|
110
|
-
|
|
114
|
+
7. **Collection and conversion** — Collects the lazy result into an eager `pl.DataFrame` and converts to a list of row dictionaries via `to_dicts()`.
|
|
111
115
|
|
|
112
116
|
### Example Usage
|
|
113
117
|
|
|
@@ -126,7 +130,7 @@ result: list[dict[str, Any]] = resolve_many(
|
|
|
126
130
|
entities=["TP53", "BRCA1", "EGFR", "KRAS"],
|
|
127
131
|
datassert=datassert,
|
|
128
132
|
taxon="9606",
|
|
129
|
-
prioritize=[Categories.
|
|
133
|
+
prioritize=[Categories.GENE],
|
|
130
134
|
)
|
|
131
135
|
|
|
132
136
|
# result[0] → {"original gene": "TP53", "gene": "HGNC:11998", "gene name": "TP53", ...}
|
|
@@ -147,7 +151,7 @@ result: list[dict[str, Any]] = resolve_many(
|
|
|
147
151
|
col="disease",
|
|
148
152
|
entities=["diabetes mellitus", "breast cancer", "alzheimer disease"],
|
|
149
153
|
datassert=datassert,
|
|
150
|
-
avoid=[Categories.
|
|
154
|
+
avoid=[Categories.GENE, Categories.PROTEIN],
|
|
151
155
|
)
|
|
152
156
|
|
|
153
157
|
# result[0] → {"original disease": "diabetes mellitus", "disease": "MONDO:0005015", ...}
|
|
@@ -206,7 +210,7 @@ for row in result:
|
|
|
206
210
|
| **Connections** | Managed internally via `ExitStack` | Must be opened externally |
|
|
207
211
|
| **Output** | `list[dict[str, Any]]` | `pl.LazyFrame` |
|
|
208
212
|
| **Logging** | Uses default (`log=True`) | Configurable |
|
|
209
|
-
| **Context params** |
|
|
213
|
+
| **Context params** | `column_context` exposed; `section_hash`, `config_file`, `tag` not exposed | Fully configurable |
|
|
210
214
|
| **Use case** | Standalone batch lookups, scripting, notebooks | Internal pipeline integration |
|
|
211
215
|
|
|
212
216
|
`resolve_many()` is designed for ad-hoc and programmatic use — scripts, notebooks, and one-off lookups. For pipeline integration where you need full control over logging, context metadata, and lazy evaluation, use `resolve()` directly.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
The `qc` module validates entity resolution mappings through a multi-stage pipeline: exact matching, fuzzy matching, and BERT semantic similarity.
|
|
4
4
|
|
|
5
|
-
QC runtime support is optional. Install `tablassert[qc]` for CPU inference or `tablassert[qc-cuda]` for CUDA inference on GPU 0.
|
|
5
|
+
QC runtime support is optional. Install `tablassert[qc]` for CPU inference or `tablassert[qc-cuda]` for CUDA inference on GPU 0. **Strict GPU behavior:** if `onnxruntime-gpu` is installed but `CUDAExecutionProvider` is not available (e.g., a broken CUDA/cuDNN environment), `fullmap_audit()` raises a `RuntimeError` rather than silently falling back to CPU — install `tablassert[qc]` for CPU inference or fix the CUDA environment.
|
|
6
6
|
|
|
7
7
|
## fullmap_audit()
|
|
8
8
|
|
|
@@ -84,7 +84,7 @@ original == preferred_name
|
|
|
84
84
|
|
|
85
85
|
**Performance:** O(1) string comparison
|
|
86
86
|
|
|
87
|
-
Before fuzzy matching, the function also applies rule-based pass-through checks
|
|
87
|
+
Before fuzzy matching, the function also applies rule-based pass-through checks: (1) the resolved CURIE matches an exempt prefix (`CHEBI`, `PR`, `UniProtKB`, `NCBIGene`, `UMLS`, `UNII`, `PUBCHEM`, `MONDO`); (2) the original text contains `:` (looks like a CURIE); (3) the preferred name matches an exception prefix (`^LOC` or `^si:`).
|
|
88
88
|
|
|
89
89
|
#### Stage 2: Fuzzy Matching
|
|
90
90
|
|
|
@@ -94,11 +94,11 @@ Two fuzzy matching algorithms:
|
|
|
94
94
|
1. **Ratio:** Overall string similarity
|
|
95
95
|
2. **Partial token sort ratio:** Combined token/subsequence matching
|
|
96
96
|
|
|
97
|
-
**
|
|
97
|
+
**Thresholds:** `fuzz.ratio` >= 20 OR `fuzz.partial_token_sort_ratio` >= 30
|
|
98
98
|
|
|
99
99
|
```python
|
|
100
100
|
fuzz.ratio(original, preferred) >= 20
|
|
101
|
-
or fuzz.partial_token_sort_ratio(original, preferred) >=
|
|
101
|
+
or fuzz.partial_token_sort_ratio(original, preferred) >= 30
|
|
102
102
|
```
|
|
103
103
|
|
|
104
104
|
**Example passes:**
|
|
@@ -116,8 +116,8 @@ or fuzz.partial_token_sort_ratio(original, preferred) >= 20
|
|
|
116
116
|
3. **Accept** if similarity >= 0.2 (20%)
|
|
117
117
|
|
|
118
118
|
```python
|
|
119
|
-
embeddings =
|
|
120
|
-
similarity = cosine_similarity(
|
|
119
|
+
embeddings = get_biobert(provider).encode(originals + preferreds)
|
|
120
|
+
similarity = cosine_similarity(embeddings[:n], embeddings[n:]).diagonal()
|
|
121
121
|
return similarity >= 0.2
|
|
122
122
|
```
|
|
123
123
|
|
|
@@ -19,10 +19,8 @@ def namespace_uuid(domain: Any, *values: list[Any]) -> str
|
|
|
19
19
|
Domain string used to create the namespace UUID.
|
|
20
20
|
|
|
21
21
|
Converted to string internally. Common domains:
|
|
22
|
-
- `"TABLASSERT"` - Default domain used for
|
|
23
|
-
- `"edges"`
|
|
24
|
-
- `"nodes"` - For custom node IDs
|
|
25
|
-
- `"tablassert"` - For application-specific IDs
|
|
22
|
+
- `"TABLASSERT"` - Default domain used for KGX edge IDs (the value used by `label_edge`)
|
|
23
|
+
- Other domain strings (e.g., `"edges"`, `"nodes"`) may be passed for custom namespaces, though only `"TABLASSERT"` is used internally.
|
|
26
24
|
|
|
27
25
|
**`*values: list[Any]`**
|
|
28
26
|
|
|
@@ -118,7 +116,7 @@ edge_id = namespace_uuid(
|
|
|
118
116
|
"MONDO:0005148", # Type 2 diabetes
|
|
119
117
|
"PMC11708054" # Publication
|
|
120
118
|
)
|
|
121
|
-
# Returns: "
|
|
119
|
+
# Returns: "2cfea591-0f8f-33af-a7df-03da531d3359"
|
|
122
120
|
```
|
|
123
121
|
|
|
124
122
|
**Benefits:**
|
|
@@ -145,7 +143,7 @@ from tablassert.utils import namespace_uuid
|
|
|
145
143
|
|
|
146
144
|
# Generate edge ID
|
|
147
145
|
edge_id = namespace_uuid("edges", "subject", "predicate", "object")
|
|
148
|
-
print(edge_id) # "
|
|
146
|
+
print(edge_id) # "12345678-1234-1234-1234-123456789abc"
|
|
149
147
|
```
|
|
150
148
|
|
|
151
149
|
**With qualifiers:**
|
|
@@ -183,12 +181,33 @@ Suitable for millions of ID generations per second.
|
|
|
183
181
|
**`basespace(domain)`** - Creates namespace UUID from domain
|
|
184
182
|
|
|
185
183
|
```python
|
|
184
|
+
@cache
|
|
186
185
|
def basespace(domain: str) -> UUID:
|
|
187
186
|
namespace = UUID("00000000-0000-0000-0000-000000000000")
|
|
188
187
|
return uuid3(namespace, domain)
|
|
189
188
|
```
|
|
190
189
|
|
|
191
|
-
Used internally by `namespace_uuid()`.
|
|
190
|
+
Used internally by `namespace_uuid()`. Results are memoized per domain.
|
|
191
|
+
|
|
192
|
+
## mkhash()
|
|
193
|
+
|
|
194
|
+
Generates an `xxhash` 64-bit digest (hex string, 16 characters) for arbitrary input.
|
|
195
|
+
|
|
196
|
+
```python
|
|
197
|
+
def mkhash(x: Any) -> str
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Used for compact identifier hashing (e.g., config/file identifiers in the CLI). Returns the `xxh64` hex digest of the input converted to a string.
|
|
201
|
+
|
|
202
|
+
## samphash()
|
|
203
|
+
|
|
204
|
+
Hashes a sampled `polars.DataFrame` for deterministic temp-file naming.
|
|
205
|
+
|
|
206
|
+
```python
|
|
207
|
+
def samphash(df: pl.DataFrame, n: int = 20) -> str
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Samples up to `n` rows (default `20`) from `df`, hashes the sampled bytes via `mkhash()`, and returns the digest string.
|
|
192
211
|
|
|
193
212
|
## Next Steps
|
|
194
213
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
The canonical release history lives in the repository root at [`CHANGELOG.md`](https://github.com/SkyeAv/Tablassert/blob/main/CHANGELOG.md).
|
|
4
|
+
|
|
5
|
+
## Current Release Notes
|
|
6
|
+
|
|
7
|
+
## 7.5.1 - 2026-07-01
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
- Numeric annotation columns are now coerced and emitted as controlled-notation strings in NDJSON output instead of raw values. Two new pipeline steps wired into `Tcode.collect()` (`lib.py`): `clean_numeric()` lazily casts matching columns to `Float64` with `strict=False` (non-numeric entries drop to null), and `format_numeric()` renders them as strings — p-value columns (any name containing `"p value"`, case-insensitive) in scientific notation (`{:.4e}`), and `relationship strength` / `sample size` in decimal general format (`{:.4g}`, ≥4 significant figures). Non-matching columns are left untouched, and nulls are subsequently dropped by `strip_nulls()`. `math_op()` now also casts with `strict=False` so it tolerates residual junk in numeric annotation columns. `format_numeric()` formats via numpy-backed batch conversion rather than `map_elements` for throughput.
|
|
11
|
+
- Removed dead `pl.Config(set_fmt_float=...)` and `pl.Config(float_precision=...)` context managers from `compile_graph()` (`lib.py`); they were no-ops for NDJSON serialization (`write_ndjson` emits raw f64 via serde shortest-repr and ignores float display options), and the `fmt`/`precision` parameters of `compile_graph()` were removed alongside them.
|
|
12
|
+
- Fixed an off-by-one in the build/validate progress bar so each section loop now shows the configuration currently being processed instead of the last-completed one. `PipelineProgress.section_loop()` (`progress.py`) previously returned a single `advance(info)` callback that set the description and ticked the completed counter together, called after each item's work — so while section *K* ran the bar still displayed section *K−1*. It now returns a `(start, advance)` pair: `start(info)` updates the description to the in-flight item without incrementing, and `advance()` ticks the counter afterwards (so the counter never claims an in-flight item is complete). All five call sites in `cli.py` (TCode build, Collect, Subgraph, Graph, Validate) were updated to `start(...)` before the work and `advance()` after; the long-running Collect and Subgraph stages continue to show the full `format_section_oneline()` summary (including the `CONFIG` name) of the in-flight section.
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
- Fifteen regression tests in `test_lib.py` covering `numeric_columns()` detection (p-value substring, exact-name match, case-insensitivity), `clean_numeric()` (parse/coerce numeric and scientific notation, null out non-numeric junk, leave non-matching columns untouched, noop, idempotent on Float64), `format_numeric()` (scientific notation for p-value, decimal general format for relationship strength/sample size, null preservation, floating-point-noise cleaning, noop), null-stripped NDJSON rows, `compile_graph()` NDJSON emission, and `sig()` operating over a cleaned Float64 p-value column.
|
|
16
|
+
- Three regression tests in `tests/test_progress.py` pinning the new two-callback contract: `start` shows the in-flight item with the counter still at zero, `advance` ticks the counter without altering the description, and a `start`/`advance` cycle keeps the description synced to the current item rather than the previous one.
|
|
@@ -26,7 +26,7 @@ Prints the installed Tablassert version to stdout and exits. This is a flag on t
|
|
|
26
26
|
|
|
27
27
|
## build
|
|
28
28
|
|
|
29
|
-
Build
|
|
29
|
+
Build a knowledge graph from a YAML configuration file.
|
|
30
30
|
|
|
31
31
|
### Synopsis
|
|
32
32
|
|
|
@@ -70,7 +70,7 @@ See [Graph Configuration](configuration/graph.md) for details on the YAML schema
|
|
|
70
70
|
|
|
71
71
|
## validate
|
|
72
72
|
|
|
73
|
-
|
|
73
|
+
Validate section syntax from a YAML configuration file.
|
|
74
74
|
|
|
75
75
|
### Synopsis
|
|
76
76
|
|
|
@@ -23,7 +23,7 @@ template:
|
|
|
23
23
|
local: ./DATALAKE/ALAM.XLSX
|
|
24
24
|
url: https://pmc.ncbi.nlm.nih.gov/articles/instance/11708054/bin/mbio.01679-24-s0006.xlsx
|
|
25
25
|
row_slice:
|
|
26
|
-
- 2 # Skip first
|
|
26
|
+
- 2 # Skip the first two rows (title + header)
|
|
27
27
|
- auto # Read to end
|
|
28
28
|
sheet: all correlations
|
|
29
29
|
|
|
@@ -39,9 +39,9 @@ template:
|
|
|
39
39
|
avoid:
|
|
40
40
|
- Gene
|
|
41
41
|
|
|
42
|
-
#
|
|
42
|
+
# Strip non-value text in place (rows are not dropped)
|
|
43
43
|
remove:
|
|
44
|
-
- "^NA " #
|
|
44
|
+
- "^NA " # Cells starting with "NA "
|
|
45
45
|
|
|
46
46
|
# Clean taxonomic names with regex
|
|
47
47
|
regex:
|
|
@@ -66,7 +66,7 @@ template:
|
|
|
66
66
|
# Provenance: Publication and curation info
|
|
67
67
|
provenance:
|
|
68
68
|
repo: PMC
|
|
69
|
-
publication:
|
|
69
|
+
publication: PMC11708054
|
|
70
70
|
contributors:
|
|
71
71
|
- kind: curation
|
|
72
72
|
name: Skye Lane Goetz
|
|
@@ -147,7 +147,7 @@ The subject field uses three regex transformations in sequence:
|
|
|
147
147
|
```
|
|
148
148
|
`"Lactobacillus sp"` → `"Lactobacillus sp. "`
|
|
149
149
|
|
|
150
|
-
> **Regex constraint:** Each `pattern` is handed to Polars `str.replace_all()` (Rust `regex` crate). **
|
|
150
|
+
> **Regex constraint:** Each `pattern` is handed to Polars `str.replace_all()` (Rust `regex` crate). **Backreferences (`\1`, `\2`, …) and lookarounds (`(?=...)`, `(?<=...)`, `(?!...)`, `(?<!...)`) are not allowed** and will fail validation. Plain groups `(...)` and non-capturing groups `(?:...)` *are* supported. Express transformations as a sequence of simple anchored / character-class substitutions where possible — the pipeline above is a deliberate three-step chain. If the transformation can't be expressed without those unsupported features, capture the leftover context in a `miscellaneous notes` annotation rather than fighting the regex engine.
|
|
151
151
|
|
|
152
152
|
### Taxonomic Filtering
|
|
153
153
|
|
|
@@ -226,6 +226,7 @@ template:
|
|
|
226
226
|
|
|
227
227
|
statement:
|
|
228
228
|
subject:
|
|
229
|
+
method: column
|
|
229
230
|
encoding: A
|
|
230
231
|
prioritize: [OrganismTaxon]
|
|
231
232
|
avoid: [Gene]
|
|
@@ -239,18 +240,20 @@ sections:
|
|
|
239
240
|
# Section 1: Positive correlations
|
|
240
241
|
- statement:
|
|
241
242
|
predicate: positively_correlated_with
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
243
|
+
source:
|
|
244
|
+
reindex:
|
|
245
|
+
- column: B # Correlation coefficient
|
|
246
|
+
comparison: gt
|
|
247
|
+
comparator: 0
|
|
246
248
|
|
|
247
249
|
# Section 2: Negative correlations
|
|
248
250
|
- statement:
|
|
249
251
|
predicate: negatively_correlated_with
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
252
|
+
source:
|
|
253
|
+
reindex:
|
|
254
|
+
- column: B
|
|
255
|
+
comparison: lt
|
|
256
|
+
comparator: 0
|
|
254
257
|
```
|
|
255
258
|
|
|
256
259
|
This produces two sets of edges from one table:
|
|
@@ -296,14 +299,9 @@ template:
|
|
|
296
299
|
- pattern: _
|
|
297
300
|
replacement: ' ' # "Lactobacillus_rhamnosus" → "Lactobacillus rhamnosus"
|
|
298
301
|
|
|
299
|
-
qualifiers:
|
|
300
|
-
- qualifier: p value
|
|
301
|
-
method: column
|
|
302
|
-
encoding: E
|
|
303
|
-
|
|
304
302
|
provenance:
|
|
305
303
|
repo: PMC
|
|
306
|
-
publication:
|
|
304
|
+
publication: PMC12345678
|
|
307
305
|
contributors:
|
|
308
306
|
- kind: curation
|
|
309
307
|
name: Skye Lane Goetz
|
|
@@ -324,7 +322,7 @@ template:
|
|
|
324
322
|
|
|
325
323
|
**Both nodes from columns:** Setting `method: column` on both subject and object means both undergo entity resolution via `resolve()`. Each gets its own `prioritize` list to guide disambiguation.
|
|
326
324
|
|
|
327
|
-
**`remove` vs `regex`:** `remove`
|
|
325
|
+
**`remove` vs `regex`:** Both transform cell text in place before resolution (neither drops rows). `remove` strips each listed regex pattern by replacing it with an empty string; `regex` applies an ordered `pattern`→`replacement` substitution list.
|
|
328
326
|
|
|
329
327
|
---
|
|
330
328
|
|
|
@@ -364,7 +362,7 @@ template:
|
|
|
364
362
|
|
|
365
363
|
provenance:
|
|
366
364
|
repo: PMC
|
|
367
|
-
publication:
|
|
365
|
+
publication: PMC87654321
|
|
368
366
|
contributors:
|
|
369
367
|
- kind: curation
|
|
370
368
|
name: Skye Lane Goetz
|
|
@@ -16,7 +16,6 @@ A graph configuration file specifies:
|
|
|
16
16
|
|
|
17
17
|
| Field | Type | Description |
|
|
18
18
|
|-------|------|-------------|
|
|
19
|
-
| `syntax` | String | Configuration version (must be `"GC2"`) |
|
|
20
19
|
| `name` | String | Knowledge graph name (used in output filename) |
|
|
21
20
|
| `version` | String | Knowledge graph version (used in output filename) |
|
|
22
21
|
| `tables` | List[Path] | Paths to table configuration YAML files |
|
|
@@ -26,6 +25,7 @@ A graph configuration file specifies:
|
|
|
26
25
|
|
|
27
26
|
| Field | Type | Description |
|
|
28
27
|
|-------|------|-------------|
|
|
28
|
+
| `syntax` | String | Configuration version. Defaults to `"GC2"` (also accepts `"TC3"`); overriding is not recommended. |
|
|
29
29
|
| `pubmed_db` | Path | Path to SQLite PubMed metadata database |
|
|
30
30
|
| `pmc_db` | Path | Path to SQLite PMC figure captions database |
|
|
31
31
|
| `log` | Boolean | Log unmatched entities and audit details during graph builds |
|
|
@@ -35,7 +35,7 @@ A graph configuration file specifies:
|
|
|
35
35
|
|
|
36
36
|
**`syntax: "GC2"`**
|
|
37
37
|
|
|
38
|
-
Configuration syntax version.
|
|
38
|
+
Configuration syntax version. Defaults to `"GC2"` (the type also accepts `"TC3"`); overriding the default is not recommended.
|
|
39
39
|
|
|
40
40
|
**`name: string`**
|
|
41
41
|
|
|
@@ -61,7 +61,7 @@ This field only controls whether QC runs. Install `tablassert[qc]` or `tablasser
|
|
|
61
61
|
|
|
62
62
|
**`tables: list[path]`**
|
|
63
63
|
|
|
64
|
-
List of table configuration file paths. Can be absolute or relative to graph
|
|
64
|
+
List of table configuration file paths. Can be absolute or relative to the current working directory (paths are resolved against the process CWD, not the graph-config file location).
|
|
65
65
|
|
|
66
66
|
Each table config defines:
|
|
67
67
|
- Data source (Excel/CSV/TSV)
|
|
@@ -101,8 +101,7 @@ When provided, this is used when provenance specifies PMC publications.
|
|
|
101
101
|
|
|
102
102
|
Paths can be:
|
|
103
103
|
- **Absolute:** `/home/user/data/datassert`
|
|
104
|
-
- **Relative to
|
|
105
|
-
- **Relative to current directory:** `../configs/table.yaml`
|
|
104
|
+
- **Relative to the current working directory:** `./tables/table1.yaml` (note: paths are resolved against the process CWD, not the graph-config file location — there is no config-relative resolver)
|
|
106
105
|
|
|
107
106
|
## Minimal Example
|
|
108
107
|
|
|
@@ -139,16 +138,17 @@ pmc_db: /databases/PMCSuppCaptions.db
|
|
|
139
138
|
When you run `tablassert build graph.yaml`:
|
|
140
139
|
|
|
141
140
|
1. **Load graph configuration** - Parse YAML, validate schema
|
|
142
|
-
2. **
|
|
143
|
-
|
|
141
|
+
2. **Load table configurations** - Parse each YAML in `tables`
|
|
142
|
+
3. **Extract sections** - Expand templates into per-section `Tcode` instances
|
|
143
|
+
4. **Collect instructions (per section):**
|
|
144
144
|
- Download source file (if URL specified)
|
|
145
|
-
- Apply transformations
|
|
146
|
-
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
145
|
+
- Apply transformations and resolve entities using `datassert`
|
|
146
|
+
- Validate with the QC audit when `qc: true`
|
|
147
|
+
- Enrich with provenance: query `pubmed_db` (MeSH) and `pmc_db` (captions) when configured
|
|
148
|
+
5. **Build subgraphs** - Compile each section's resolved data into a parquet file
|
|
149
|
+
6. **Compile graph** - Aggregate all subgraph parquets and export `{name}_{version}.nodes.ndjson` / `.edges.ndjson`
|
|
150
|
+
|
|
151
|
+
> Note: provenance enrichment (`with_mesh`/`with_captions`) and QC both run during the per-section Collect Instructions stage, *before* subgraphs are built — not as a separate post-aggregation step.
|
|
152
152
|
|
|
153
153
|
## Output Files
|
|
154
154
|
|
|
@@ -173,8 +173,8 @@ version: UNSTABLE
|
|
|
173
173
|
tables:
|
|
174
174
|
- /local_raid1/sgoetz/STORE/CONFIG/TABLASSERT/TABLE/V6/ALAMV6.yaml
|
|
175
175
|
datassert: /local_raid1/sgoetz/CODE/DATASSERT/datassert
|
|
176
|
-
pubmed_db: /local_raid1/sgoetz/DBSTORE/
|
|
177
|
-
pmc_db: /local_raid1/sgoetz/DBSTORE/
|
|
176
|
+
pubmed_db: /local_raid1/sgoetz/DBSTORE/PUBMED/PubMed.db
|
|
177
|
+
pmc_db: /local_raid1/sgoetz/DBSTORE/CAPTIONS/PMCSuppCaptions.db
|
|
178
178
|
```
|
|
179
179
|
|
|
180
180
|
This processes a single table configuration (ALAMV6.yaml) into a knowledge graph named `MULTIOMICS_KG_UNSTABLE`.
|