SYNONIM Synthetic Community Design via Approximation
- Overview
- Key Features
- Installation
- Quickstart
- Usage
- Configuration & Constraints
- Testing
- Contributing
- Citation
- License
SYNONIM (SYNthetic cOmmunity desigN via approxIMation) is a flexible, modular framework for rationally designing synthetic microbial communities (SynComs). It translates high-dimensional genomic, functional, or ecological data into community designs that best represent input functional profiles.
Use SYNONIM to:
- Select isolate combinations that best represent a functional profile of a target environment e.g. metagenome-derived
- Incorporate metadata (e.g. taxonomy, phylogeny, environmental origin) as constraints into SynCom design
SYNONIM is under active development; expect new features, detailed tutorials, and expanded test coverage soon.
- Objective-driven optimization: Pick mathematical or biologically meaningful objectives (e.g., weight certain functions, ensure certain taxa included)
- Constraint integration: Enforce taxonomic, phylogenetic, environmental, or metadata-based constraints
- Modular components: Swap optimization algorithms (genetic algorithms, MILP)
For development and tests:
git clone https://github.com/bcoltman/SYNONIM.git
cd SYNONIM
pip install -e .[dev]COMING SOON: Install from PyPI or Conda-Forge:
pip install synonim
# or
conda install -c conda-forge synonimLoading binary (presence/absence) and/or abundance tables as pandas DataFrames indexed by feature ID, with columns as sample IDs.
-
Load binary profiles (e.g., isolate or metagenomic function presence/absence data):
import pandas as pd from synonim.io import model_from_frames # Read CSV into presence/abundance frames genomes_info = pd.read_csv("candidates_info.csv") genomes = pd.read_csv("candidates_binary.csv") metagenomes = pd.read_csv("metagenomes_binary.csv")
-
Build a Model:
model = model_from_frames( genomes_binary=genomes, metagenomes_binary=metagenomes, genomes_info=genomes_info, taxonomy_cols=["domain", "genus"] )
-
Instantiate an optimizer (e.g., BinaryGenetic): Specify an upper limit of 1 member from each genera and a total consortia size of 10
from synonim.optimizers.binary import BinaryGenetic optimizer = BinaryGenetic( model=model, consortia_size=10, taxonomy_constraints={"genus": {"default": {"max": 1}}}, taxonomic_levels=["domain", "genus"], population_size=500, generations=100, processes=4 )
-
Run optimization and view results:
solutions = optimizer.optimize() print(solutions)
- Load data: import isolate or metagenomic profiles (CSV, BIOM, or Pandas).
- Configure objectives: customise objective (e.g. for binary, whether mismtaches are penalised).
- Apply constraints: narrow search space via taxonomy, metadata ranges, or co-occurrence networks.
- Run optimization: select from algorithms.
- Inspect results: obtain community composition, predicted functions, and diagnostic plots.
Detailed API docs and examples will be available at synonim.readthedocs.io.
Customize your design by:
- Setting taxonomy-level inclusion/exclusion
- and more ...
SYNONIM defines three core classes for programmatic model construction:
-
Feature: Represents a functional trait (e.g., gene function, pathway). Each
Featurehas:id: unique identifier (string)name: human-readable label
-
Profile: Encapsulates the feature composition of a sample, with attributes:
id,name: identifiers for the sampleprofile_type: either "genome" or "metagenome"metadata: arbitrary key/value pairs describing the sampletaxonomy: taxonomic annotations (for genome profiles)- Features: added via
profile.add_features({Feature: {"presence": int, "abundance": float?}})
-
Model: Container for a set of
FeatureandProfileobjects, ready for optimization. AModelprovides methods:add_features(List[Feature])to register all featuresadd_profiles(List[Profile])to attach sample profiles
Building a Model
-
Instantiate an empty model:
model = Model(id_or_model="my_model", name="Example Model")
-
Create
Featureobjects (e.g., one per feature ID) and add them:features = [Feature(id=fid, name=fid) for fid in ["Feat1", "Feat2", "Feat3"]] model.add_features(features)
-
For each sample, create a
Profile, attach metadata and taxonomy, then add feature values:profile = Profile(id=sample, name=sample, profile_type="genome", metadata=meta_dict, taxonomy=tax_dict) profile.add_features({feature: {"presence": pres, "abundance": ab} for feature, pres, ab in ...}) model.add_profiles([profile])
-
The assembled
Modelcan now be passed toCommunityDesigner:optimizer = BinaryHeuristic(model=model, consortia_size=10) SynCom = designer.optimize()
-
BinaryGenetic: Uses presence/absence matrices to select consortia members. Parameters:
model,consortia_size,taxonomy_constraints,taxonomic_levels,population_size,generations,processes,absence_cover_penalty,absence_match_reward. Usage:optimizer = BinaryGenetic( model=model, consortia_size=5, taxonomy_constraints=tax_constraints, taxonomic_levels=["domain", "genus"], population_size=1000, generations=200, processes=4 ) solutions = optimizer.optimize()
-
BinaryHeuristic: Fast heuristic solver Parameters: same as
BinaryGenetic, plus masking options (mask_covered_absent_features,mask_covered_present_features,mask_covered_isolate_features). Usage:heur = BinaryHeuristic(...) heur_sols = heur.optimize()
-
BinaryMILP: Mixed‑Integer Linear Programming solver for binary design. Parameters: same as
BinaryGenetic, plustime_limit. Usage:milp = BinaryMILP( model=model, consortia_size=5, taxonomy_constraints=tax_constraints, taxonomic_levels=["domain", "genus"], time_limit=86400 ) solutions = milp.optimize()
Run unit and integration tests:
pytestContributions are welcome! Please follow the steps:
- Fork the repository.
- Create a feature branch (
git checkout -b feature/your-feature). - Commit changes with clear messages.
- Submit a pull request and fill out the template.
- We review and iterate!
See CONTRIBUTING.md for details.
If you use SYNONIM in your work, please cite our publication (details coming soon).
For now, feel free to reference this repository or contact the author.
Distributed under the GPL-3.0 License.
Developed by Benjamin Coltman
University of Vienna