Install
Docker, the one supported path, and what else works
Installation
Docker is the supported path, and it is the one the rest of this page assumes. One image carries Python, R, the CLI and all 69 bundled clocks at pinned versions, so the same input gives the same numbers on your machine and on a reviewer’s. Nothing else to install. Both images are published on Docker Hub and built from the Dockerfiles in this repository. Two commands from nothing to a proven install:
docker pull bhagesh/falconage:1.0.0-cpu
docker run --rm bhagesh/falconage:1.0.0-cpu python -m pytest /opt/falconage/src/python/tests -qThe second line proves it by running the test suite inside the image, against the source it was built from.
Or build the same image from a clone, which takes about ten minutes the first time and is then cached:
git clone https://github.com/bhagesh-h/FALCONAge.git
cd FALCONAge
docker build -f docker/Dockerfile.cpu -t bhagesh/falconage:1.0.0-cpu .Then either open a session in the image:
docker run --rm -it -v "$PWD:/work" -w /work bhagesh/falconage:1.0.0-cpu python
docker run --rm -it -v "$PWD:/work" -w /work bhagesh/falconage:1.0.0-cpu ROr run a single command without opening one:
docker run --rm -v "$PWD:/work" -w /work bhagesh/falconage:1.0.0-cpu \
report betas.csv --outdir results/The image’s entrypoint is the falconage CLI, so the first argument is a verb: report, not falconage report. The exceptions are python, R, Rscript, pytest and bash, which are run as given.
On Windows PowerShell write "${PWD}" for "$PWD". Getting started walks the same ground one command at a time, including the GPU image and a native pip / remotes::install_github install for anyone who already manages their own environment.
If you have never used a terminal, start at the step-by-step walkthrough below instead; it assumes nothing and covers fetching real public data.
"$PWD" means “the folder I am in now”, and the spelling differs:
| Where you are typing | Use |
|---|---|
| macOS Terminal, Linux, Git Bash, WSL | "$PWD" |
| Windows PowerShell | "${PWD}" |
Windows cmd.exe |
"%cd%" |
Everything else is identical. A path error on Windows is almost always this.
pip install "falconage @ git+https://github.com/bhagesh-h/FALCONAge.git#subdirectory=python"import falconage as fa
fa.config()remotes::install_github("bhagesh-h/FALCONAge", subdir = "r")
library(FALCONAge)
falconage_install() # builds the Python environment R calls into; a few minutes
falconage_config() # what resolved: versions, devices, registry sizeThe R package delegates every number to the Python core, so it needs a Python environment either way. On reticulate ≥ 1.41 an ephemeral one is built on first use and falconage_install() is optional; use it when you want a pinned, reproducible one.
Every code example on this page runs unchanged in a native install; only the docker run prefix goes away.
falconage_config() is the first thing to run when anything looks wrong. It reports the interpreter, the registry version, and how many clocks are usable:
FALCONAge 1.0.0
registry 1.1.0 (178 clocks)
availability 69 bundled - 52 untraced - 57 licensed
numpy 2.5.1
torch not installed (the CPU path needs none)
devices cpu
python /usr/local/bin/python
Complete walkthrough, from an empty machine
Everything above, in order, assuming no Python, no R, and no prior experience with either. Each command can be copied one at a time and each says what it does and what you should see. It ends with a scored public dataset and the figures.
Step 0: install Docker
Install Docker Desktop (Windows, macOS) or Docker Engine (Linux), start it, then run:
docker --versionYou should get a version string. If instead you get “command not found” or “cannot connect to the Docker daemon”, Docker is not installed or not running; fix that before going further, because nothing below will work.
If a later command fails with a path error: it is almost certainly the "$PWD" spelling for your shell; see the table above.
Step 1: clone the repository
git clone https://github.com/bhagesh-h/FALCONAge.git
cd FALCONAgeEvery later command is run from inside this FALCONAge folder.
Step 2: obtain the image
One image carries Python, R, the CLI and all 69 bundled clocks. Pull the published one:
docker pull bhagesh/falconage:1.0.0-cpuOr build the same thing from the clone, which takes about ten minutes the first time and is then cached:
docker build -f docker/Dockerfile.cpu -t bhagesh/falconage:1.0.0-cpu .Check it either way:
docker run --rm bhagesh/falconage:1.0.0-cpu python -c "import falconage; print(falconage.__version__)"Step 3: inspect the corpus before downloading it
A second, deliberately tiny image fetches the test corpus. It is separate on purpose: fetching a fixture is the first thing you do when the package itself is broken, so it must not need the package.
docker build -f docker/Dockerfile.testdata -t falconage-testdata:1.0.0 .Now the dry run. This transfers nothing. It prints every group, file count and byte total so you can decide before committing to half a gigabyte:
docker run --rm -v "$PWD/test/data:/data" falconage-testdata:1.0.0 planYou should see:
group files size what it is for
------------------------------------------------------------------------------
bench 14 549.8 MB ComputAgeBench case/control methylation
clinical 3 5.4 MB NHANES blood chemistry with mortality linkage
gestational 1 50.8 MB Umbilical cord blood with gestational age
epicv2 1 41.2 MB EPIC v2 probe-suffix handling
idat 8 60.4 MB Raw IDATs, EPIC v1 and EPIC v2
mammalian 4 9.3 MB Mammalian methylation array, three species
mouse 5 50.2 MB Mouse blood RRBS across the lifespan
------------------------------------------------------------------------------
selected 36 767.1 MB
Step 4: download and verify
docker run --rm -v "$PWD/test/data:/data" falconage-testdata:1.0.0 python
docker run --rm -v "$PWD/test/data:/data" falconage-testdata:1.0.0 verifyThe first fetches 36 files from GEO and Hugging Face into test/data/ on your own disk, never inside the image, so rebuilding never re-downloads. The second re-computes every SHA-256 against checksums.sha256 and fails loudly on a single wrong byte.
Only smaller pieces, if 767 MB is too much:
docker run --rm -v "$PWD/test/data:/data" falconage-testdata:1.0.0 python --groups clinicalNot decoration: the R fetcher writes a byte-identical checksums.sha256, so the two languages are shown to agree on the input before any clock is scored.
docker run --rm -v "$PWD/test/data:/data" falconage-testdata:1.0.0 RStep 5: score it
docker run --rm -v "$PWD:/work" -w /work bhagesh/falconage:1.0.0-cpu \
python test/run_all.pyEvery clock against every dataset. It writes one folder per input under test/output/, every figure under test/output_figures/, and rewrites the generated tables in test/README.md, so the numbers in that document are the numbers the code just produced and cannot drift from them.
To check the install without the corpus, run the unit suite instead, seconds, no data needed:
docker run --rm -v "$PWD:/work" -w /work bhagesh/falconage:1.0.0-cpu \
python -m pytest python/tests -qThe same image. R calls the same Python core through reticulate, so these are the same numbers, not a second implementation that agrees approximately.
docker run --rm -v "$PWD:/work" -w /work bhagesh/falconage:1.0.0-cpu \
Rscript -e 'testthat::test_local("r")'That suite includes the R-versus-Python conformance tests, which assert equality at tolerance exactly zero.
Scoring from R interactively:
docker run --rm -it -v "$PWD:/work" -w /work bhagesh/falconage:1.0.0-cpu Rlibrary(FALCONAge)
falconage_config()
d <- read_betas("test/data/bench/GSE40279.csv")
res <- score(prepare(d), clocks = "compatible")
summary(res)Only worth it if you have an NVIDIA card. Read GPU support first: for the clocks that ship today the GPU is slower than the CPU, which is why device="auto" resolves to CPU even inside this image.
Pull the CUDA image. It is 14.6 GB against the CPU image’s 2.5 GB, because it carries torch built against CUDA 12.4:
docker pull bhagesh/falconage:1.0.0-cudaOr build it:
docker build -f docker/Dockerfile.cuda -t bhagesh/falconage:1.0.0-cuda .Check the card is visible inside a container before anything else:
docker run --rm --gpus all bhagesh/falconage:1.0.0-cuda nvidia-smiNo output or an error here means GPU passthrough is not set up, and every command below will fail. On Linux that is usually a missing nvidia-container-toolkit.
docker run --rm --gpus all -v "$PWD:/work" -w /work bhagesh/falconage:1.0.0-cuda \
python test/gpu_check.pyThis reproduces every number on the GPU page, device resolution, CPU-versus-GPU agreement, the speed table and the profile that explains it. On a machine with no CUDA device it stops after the first step with an explanation rather than an error, so it is safe to run anywhere.
Scoring on the GPU needs --gpus all and --device cuda. Without the flag, --device cuda raises rather than falling back, so a run that asked for a GPU cannot quietly become a very slow success:
docker run --rm --gpus all -v "$PWD:/work" -w /work bhagesh/falconage:1.0.0-cuda \
score --input test/data/prepared.h5ad --device cuda --outdir resultsStep 6: score your own data
Put a beta matrix or a clinical table in a folder, mount it read-only, and mount somewhere for the results to land:
docker run --rm \
-v "$PWD/mydata:/data:ro" \
-v "$PWD/results:/results" \
-v falconage-cache:/opt/falconage/cache \
bhagesh/falconage:1.0.0-cpu \
score --input /data/betas.csv --clocks compatible --outdir /resultsThe named falconage-cache volume is worth adding from the start. Nothing bundled needs it; it keeps what FALCONAge downloads on request, the Illumina manifests fetch_manifest() caches (12 to 26 MB each) and data fetched with fa.download, so a new container does not fetch them again.