Repo Layout & Dependencies¶
Package structure¶
fed-maxfuse/
├── src/
│ ├── fed_maxfuse/ # the algorithm
│ ├── cli/ # Typer command-line interface
│ └── shared/ # cross-cutting types and utilities
├── tests/ # 345 tests across 20 files
├── docs/ # this documentation site
├── data/ # datasets (gitignored)
└── pyproject.toml
src/fed_maxfuse — the algorithm¶
| Path | Responsibility |
|---|---|
models/federated/ |
Federated node + server. model.py, server_functions.py, parameters.py, train.py |
models/regular/ |
Centralized re-implementation |
models/distributed/ |
Distributed (non-privacy-preserving) variant |
models/original/ |
Wrapper around upstream MaxFuse |
models/common/ |
Shared parameter dataclasses: filtering, Leiden, batch splitting, preprocessing |
correlation_utils/cca/centralized/ |
Reference CCA |
correlation_utils/cca/distributed/ |
pls_w2a_node.py, pseudo_cca_node.py — federated Mode B PLS |
correlation_utils/pearson/ |
Correlation computation |
matching/ |
checkpoint.py, conversion.py, utils.py |
data/ |
pre_processor.py, graph.py, singular_value_decomposition.py, synth_generation.py |
evaluation/metrics/supervised/ |
classification.py, cluster.py, local.py |
evaluation/metrics/unsupervised/ |
cluster.py, global_distances.py, local.py |
utils/rna_protein_constant.py |
RNA ↔ protein name mapping |
experiments/generation.py |
Configuration expansion |
Each model variant follows the same triple (model.py, parameters.py, train.py), so adding
an execution mode means adding a sibling directory, not branching inside an existing model.
The federated variant adds server_functions.py for the server side.
src/cli — command line¶
Six Typer sub-applications registered in main_cli.py: generate, data, run, preprocess,
export, analysis. See CLI & API.
src/shared — cross-cutting¶
Enums that define the system's vocabulary:
| Enum | Values |
|---|---|
MaxFuseRunType |
original, regular, distributed, federated |
DatasetID |
cite_seq_and_pbmc, tonsils |
CCAType |
sklearn, pseudo, plswtb, plswtb_rand_init |
FuzzySmoothing |
centroid_shrinkage, graph_smoothing |
BatchingAssignmentMethod |
random, binning |
BatchingMappingScheme |
cyclic, pairwise |
FilteringMatches |
pivot, propagated |
DownloadedDataType |
pbmc, maxfuse, all |
Verbosity |
QUIET, BRIEF, VERBOSE |
ZaduAbbreviationEnum |
Metric names for the ZADU package |
Dependencies¶
Runtime dependencies are exactly pinned:
requires-python = ">=3.10,<4"
dependencies = [
"anndata==0.10.8", "numpy==1.26.4", "pandas==2.2.2",
"leidenalg==0.10.2", "igraph==0.11.5", "matplotlib==3.9.1",
"h5py==3.11.0", "pyarrow==16.1.0", "pynndescent==0.5.13",
"imbalanced-learn==0.12.3", ...
]
Development dependencies live in a dev group: pytest, pytest-xdist, parameterized,
pyfakefs, psutil, ruff, pylint.
Why exact pins
Numerical results depend on floating-point behaviour that is not guaranteed stable across major NumPy or scikit-learn releases. Exact pins mean a run today reproduces a run from the thesis. The trade-off is that upgrading requires deliberate revalidation.
Configuration files¶
Default configurations ship alongside each model variant:
models/federated/default_federated_cite_seq_pbmc_params.json
models/federated/default_federated_cite_seq_pbmc_params_preprocessing.json
models/federated/default_federated_tonsils_params.json
models/federated/default_federated_tonsils_params_preprocessing.json
models/regular/default_regular_{cite_seq_pbmc,tonsils}_params.json
models/original/default_original_{cite_seq_pbmc,tonsils}_params.json
Copy and edit rather than modifying these in place: experiment configurations are generated from master files, and the defaults are the reference point.
Output layout¶
out/
├── Centralized_vs_federated/
│ ├── regular_cite_seq_pbmc_params_{ID}/
│ │ ├── supervised_evaluation_metrics.json
│ │ ├── unsupervised_evaluation_metrics.json
│ │ ├── local_evaluation_metrics.json
│ │ ├── meta_embedding.npy
│ │ ├── non_meta_embedding.npy
│ │ └── matching.csv
│ ├── regular_tonsils_params_{ID}/
│ ├── federated_cite_seq_pbmc_params_{ID}/
│ └── federated_tonsils_params_{ID}/
├── shared_params/
├── cca/
└── batching/
Run IDs combine a UUID with the scheduler-generated job ID. Artifacts are written incrementally so a job that fails partway still leaves usable results on disk.