Skip to content

Commit 5352ffb

Browse files
committed
Document both libraries at the repository root
1 parent cec7243 commit 5352ffb

3 files changed

Lines changed: 166 additions & 4 deletions

File tree

.gitignore

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,21 @@
1-
/build/
2-
/fhir_tx_encoder.egg-info/
1+
# Python artefacts. The package moved to python/, so these are no longer
2+
# anchored at the repository root.
3+
python/build/
4+
python/dist/
5+
python/*.egg-info/
6+
__pycache__/
7+
.venv/
38
Pipfile
49
Pipfile.lock
10+
11+
# R artefacts.
12+
.Rproj.user/
13+
.Rhistory
14+
r/*.tar.gz
15+
*.Rcheck/
16+
17+
# Editor state.
18+
.idea/
19+
20+
# Matrix Market exports.
21+
*.mtx

CONTRIBUTING.md

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,66 @@ Thanks for your interest in contributing to "fhir-tx-encoder".
55
You can find out a bit more about the project by reading the [README](README.md)
66
file within this repository.
77

8+
## Repository layout
9+
10+
The repository houses two implementations of the same encoder:
11+
12+
| Directory | Package | Language |
13+
| --------- | ------- | -------- |
14+
| [`python/`](python) | `fhir-tx-encoder` (PyPI) | Python |
15+
| [`r/`](r) | `fhirtxencoder` (GitHub) | R |
16+
17+
The community documents (this file, `README.md`, `LICENSE`,
18+
`CODE_OF_CONDUCT.md`) live at the root and cover both.
19+
20+
### Why `python/LICENSE` is a symlink
21+
22+
`python/LICENSE` is a symbolic link to the repository's root `LICENSE`. It is
23+
not a stray duplicate, and it should not be replaced with a copy or deleted.
24+
25+
`python/setup.py` uses setuptools' default licence-file discovery, which only
26+
looks inside the package directory. Before the Python package moved from the
27+
repository root into `python/`, `LICENSE` sat next to `setup.py` and setuptools
28+
packaged it as `fhir_tx_encoder-<version>.dist-info/licenses/LICENSE`. The
29+
symlink keeps that true after the move, so the published wheel and sdist remain
30+
byte-identical to earlier releases. Removing it would silently drop the licence
31+
from the distributed artefact.
32+
33+
Verify with:
34+
35+
```bash
36+
cd python
37+
uv venv --python 3.11 && uv pip install build && uv run python -m build
38+
unzip -p dist/*.whl 'fhir_tx_encoder-*.dist-info/RECORD' | grep LICENSE
39+
```
40+
41+
## Running the checks
42+
43+
Python:
44+
45+
```bash
46+
cd python
47+
uv venv --python 3.11
48+
uv run python -m build
49+
```
50+
51+
Python 3.11 is pinned here because `setup.py` requires `scipy~=1.11.3`, which
52+
publishes no wheels for later Python versions.
53+
54+
R (see [`r/README.md`](r/README.md) for detail):
55+
56+
```bash
57+
Rscript -e 'devtools::test("r")'
58+
R CMD build r && R CMD check --as-cran fhirtxencoder_1.0.0.tar.gz
59+
Rscript -e 'print(covr::package_coverage("r"))'
60+
```
61+
62+
The R unit suite answers every terminology server request from canned fixtures,
63+
so it needs no network. `r/tests/testthat/test-integration.R` is the exception:
64+
it runs the README example against the live CSIRO public Ontoserver, and is
65+
skipped when `NOT_CRAN` is unset, when the machine is offline, or when `CI` is
66+
set.
67+
868
## Reporting issues
969

1070
Issues can be used to:
@@ -23,8 +83,14 @@ Your branch should be named `issue/[GitHub issue #]`.
2383

2484
### Coding conventions
2585

26-
This repository uses [Black](https://github.com/psf/black), please use it to
27-
reformat your code before pushing.
86+
Python code in `python/` uses [Black](https://github.com/psf/black), please use
87+
it to reformat your code before pushing.
88+
89+
R code in `r/` follows the [tidyverse style guide](https://style.tidyverse.org/)
90+
with an 80 character line limit. Every exported and internal function carries a
91+
roxygen2 block; regenerate `NAMESPACE` and `man/` with
92+
`Rscript -e 'roxygen2::roxygenise("r")'` after changing documentation. New
93+
behaviour needs a test - the R package is held at full line coverage.
2894

2995
## Code of conduct
3096

README.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# FHIR Terminology Encoder
2+
3+
Encoders that use a [FHIR](https://hl7.org/fhir/) terminology server to turn
4+
terminology codes into features for machine learning.
5+
6+
You supply a scope in the form of a FHIR ValueSet URI and a FHIR terminology
7+
endpoint. The encoder expands the scope, retrieves the subsumption
8+
relationships between the concepts within it, and returns a multi-hot encoded
9+
sparse matrix. Each code carries a feature for itself and for every concept
10+
that subsumes it, so ontologically close codes share features. Concept
11+
properties can be included as additional features.
12+
13+
This repository houses two implementations of the same idea:
14+
15+
| Language | Directory | Package |
16+
| -------- | --------- | ------- |
17+
| Python | [`python/`](python) | `fhir-tx-encoder` (PyPI) |
18+
| R | [`r/`](r) | `fhirtxencoder` (GitHub) |
19+
20+
## Python
21+
22+
Install from PyPI:
23+
24+
```bash
25+
pip install fhir-tx-encoder
26+
```
27+
28+
```python
29+
from fhir_tx import FhirTerminologyEncoder
30+
import numpy as np
31+
32+
encoder = FhirTerminologyEncoder(
33+
# Ancestors of the SNOMED CT concept "Malignant neoplastic disease".
34+
scope="http://snomed.info/sct?fhir_vs=ecl/(%3E%3E%20363346000)",
35+
# Include "Associated morphology" (116676008) as a property.
36+
properties=["116676008"],
37+
)
38+
39+
result = encoder.fit_transform(np.array([["399981008"], ["363346000"]]))
40+
print(result.shape) # (2, 9)
41+
print(encoder.feature_names_)
42+
```
43+
44+
The encoder implements the scikit-learn transformer interface, so it can be
45+
used within a `Pipeline`. See [`python/README.md`](python/README.md) for the
46+
full documentation.
47+
48+
## R
49+
50+
Install from GitHub:
51+
52+
```r
53+
remotes::install_github("aehrc/fhir-tx-encoder", subdir = "r")
54+
```
55+
56+
```r
57+
library(fhirtxencoder)
58+
59+
encoder <- fhir_tx_encoder(
60+
# Ancestors of the SNOMED CT concept "Malignant neoplastic disease".
61+
scope = "http://snomed.info/sct?fhir_vs=ecl/(%3E%3E%20363346000)",
62+
# Include "Associated morphology" (116676008) as a property.
63+
properties = c("116676008")
64+
)
65+
66+
result <- transform(encoder, matrix(c("399981008", "363346000"), ncol = 1))
67+
dim(result) # 2 9
68+
encoder$feature_names
69+
```
70+
71+
See [`r/README.md`](r/README.md) for the full documentation.
72+
73+
## Important note
74+
75+
This software is currently in alpha. It is not yet ready for production use.
76+
77+
Copyright © 2026, Commonwealth Scientific and Industrial Research Organisation
78+
(CSIRO) ABN 41 687 119 230. Licensed under the
79+
[Apache License, version 2.0](https://www.apache.org/licenses/LICENSE-2.0).

0 commit comments

Comments
 (0)