From 786d3cfdc781cdcac79c61452340554bcf85fbb0 Mon Sep 17 00:00:00 2001 From: Jola Kopec Date: Mon, 3 Nov 2025 09:07:31 +0000 Subject: [PATCH 01/10] feat: add Docker support for pipeline --- .dockerignore | 62 ++++++++++++++++++++++ .env.example | 26 +++++++++ .gitignore | 14 +++++ Dockerfile | 44 ++++++++++++++++ Dockerfile.ml | 45 ++++++++++++++++ README.Docker.md | 134 +++++++++++++++++++++++++++++++++++++++++++++++ test_docker.py | 82 +++++++++++++++++++++++++++++ 7 files changed, 407 insertions(+) create mode 100644 .dockerignore create mode 100644 .env.example create mode 100644 Dockerfile create mode 100644 Dockerfile.ml create mode 100644 README.Docker.md create mode 100644 test_docker.py diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..02abacd --- /dev/null +++ b/.dockerignore @@ -0,0 +1,62 @@ +# Python +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg + +# Virtual environments +venv/ +ENV/ +env/ +.venv + +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# Git +.git/ +.gitignore + +# Docker +Dockerfile* +docker-compose*.yml +.dockerignore + +# Test outputs (exclude these, but keep test/ directory) +.pytest_cache/ +.coverage +htmlcov/ +test/test_files/out/ + +# Documentation +docs/ +*.md +!README.md + +# Images +*.png +!stcrpy_logo.png + +# OS +.DS_Store +Thumbs.db diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..a3ba223 --- /dev/null +++ b/.env.example @@ -0,0 +1,26 @@ +# STCRpy Docker Environment Configuration +# Copy this file to .env and customize for your setup + +# Host directories (on your computer) +# These will be mounted into the Docker container +DATA_DIR=./data +OUTPUT_DIR=./output +EXAMPLES_DIR=./examples + +# Optional: Absolute paths work too +# DATA_DIR=/home/user/my_tcr_data +# OUTPUT_DIR=/home/user/my_tcr_results + +# Container working directory (inside Docker) +WORKDIR=/app + +# Python optimization +PYTHONUNBUFFERED=1 + +# Optional: GPU configuration (if using ML profile with GPU) +# NVIDIA_VISIBLE_DEVICES=all +# CUDA_VISIBLE_DEVICES=0 + +# Optional: Resource limits +# MEMORY_LIMIT=8g +# CPU_LIMIT=4 diff --git a/.gitignore b/.gitignore index 57777a5..93dd9e3 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,17 @@ test/test_files/out/haddock/*/* test/test_files/out/haddock/** */ test/test_files/** */ test/test_files + +# Docker Environment +.env + +# Data directories (contain user data) +data/* +output/* +models/* +scratch/* + +# Keep directory structure +!data/.gitkeep +!output/.gitkeep +!models/.gitkeep diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..b3cf335 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,44 @@ +FROM python:3.12-slim + +# Install system dependencies including OpenBabel from system packages +# Using python3-openbabel from Debian avoids building from source +ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get update && apt-get install -y \ + build-essential \ + wget \ + git \ + libxml2-dev \ + libxslt1-dev \ + zlib1g-dev \ + openbabel \ + libopenbabel7 \ + libopenbabel-dev \ + python3-openbabel \ + && rm -rf /var/lib/apt/lists/* + +# Install uv +COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv + +# Set working directory +WORKDIR /app + +# Copy project files +COPY . . + +# Create virtual environment with system-site-packages to access python3-openbabel +RUN uv venv /opt/venv --system-site-packages && \ + . /opt/venv/bin/activate && \ + uv pip install -e . && \ + ANARCI --build_models + +# Install PLIP source code directly (avoids pip build issues) +# PLIP is pure Python and uses system openbabel bindings +RUN git clone https://github.com/pharmai/plip.git /opt/plip && \ + ln -s /opt/plip/plip /opt/venv/lib/python3.12/site-packages/plip + +# Set environment to use venv +ENV PATH="/opt/venv/bin:$PATH" +ENV VIRTUAL_ENV="/opt/venv" + +# Default command +CMD ["/bin/bash"] diff --git a/Dockerfile.ml b/Dockerfile.ml new file mode 100644 index 0000000..bb4b381 --- /dev/null +++ b/Dockerfile.ml @@ -0,0 +1,45 @@ +FROM python:3.12-slim + +# Install system dependencies including OpenBabel from system packages +# Using python3-openbabel from Debian avoids building from source +ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get update && apt-get install -y \ + build-essential \ + wget \ + git \ + libxml2-dev \ + libxslt1-dev \ + zlib1g-dev \ + openbabel \ + libopenbabel7 \ + libopenbabel-dev \ + python3-openbabel \ + && rm -rf /var/lib/apt/lists/* + +# Install uv +COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv + +# Set working directory +WORKDIR /app + +# Copy project files +COPY . . + +# Create virtual environment with system-site-packages to access python3-openbabel +RUN uv venv /opt/venv --system-site-packages && \ + . /opt/venv/bin/activate && \ + uv pip install -e ".[ml_datasets]" && \ + uv pip install einops && \ + ANARCI --build_models + +# Install PLIP source code directly (avoids pip build issues) +# PLIP is pure Python and uses system openbabel bindings +RUN git clone https://github.com/pharmai/plip.git /opt/plip && \ + ln -s /opt/plip/plip /opt/venv/lib/python3.12/site-packages/plip + +# Set environment to use venv +ENV PATH="/opt/venv/bin:$PATH" +ENV VIRTUAL_ENV="/opt/venv" + +# Default command +CMD ["/bin/bash"] diff --git a/README.Docker.md b/README.Docker.md new file mode 100644 index 0000000..54ef764 --- /dev/null +++ b/README.Docker.md @@ -0,0 +1,134 @@ +# Docker Setup for STCRpy + +This directory contains Docker configuration for running STCRpy in a containerized environment with uv dependency management. + +## Quick Start + +### Build and run the basic STCRpy container: +```bash +docker-compose up -d stcrpy +docker-compose exec stcrpy bash +``` + +### Build and run with ML dependencies (PyTorch, PyTorch Geometric): +```bash +docker-compose --profile ml up -d stcrpy-ml +docker-compose --profile ml exec stcrpy-ml bash +``` + +## Services + +### `stcrpy` (default) +Basic STCRpy installation with core dependencies: +- BioPython +- PLIP for interaction profiling +- ANARCI for sequence annotation +- All core STCRpy functionality + +### `stcrpy-ml` (ML profile) +STCRpy with machine learning dependencies: +- PyTorch +- PyTorch Geometric +- All features from base image +- Use for graph neural network applications + +### `stcrpy-batch` (batch profile) +For batch processing tasks: +```bash +docker-compose --profile batch run stcrpy-batch python your_script.py +``` + +## Directory Structure + +The following directories are mounted as volumes: +- `./data` → `/app/data` - Input data files +- `./examples` → `/app/examples` - Example scripts and notebooks +- `./output` → `/app/output` - Analysis outputs + +Create these directories before running: +```bash +mkdir -p data output +``` + +## Usage Examples + +### Interactive Python session: +```bash +docker-compose exec stcrpy python +``` + +```python +import stcrpy +tcr = stcrpy.fetch_TCRs("8gvb") +``` + +### Run a script: +```bash +docker-compose exec stcrpy python examples/STCRpy_examples.py +``` + +### Process local PDB files: +```bash +# Place your PDB files in ./data/ +docker-compose exec stcrpy python -c " +import stcrpy +tcr = stcrpy.load_TCR('/app/data/your_file.pdb') +tcr.calculate_geometry() +tcr.save('/app/output/processed.pdb') +" +``` + +## Building Images + +### Build all images: +```bash +docker-compose build +``` + +### Build specific image: +```bash +docker-compose build stcrpy +docker-compose build stcrpy-ml +``` + +## Managing Containers + +### Stop containers: +```bash +docker-compose down +``` + +### View logs: +```bash +docker-compose logs -f stcrpy +``` + +### Remove all containers and volumes: +```bash +docker-compose down -v +``` + +## Notes + +- **uv**: This setup uses [uv](https://github.com/astral-sh/uv) for fast Python package management +- **ANARCI models**: Built automatically during image creation (takes a few minutes) +- **PyMOL**: Not included in Docker images (requires GUI support). For visualization, export files and use local PyMOL installation +- **PLIP**: ✅ **Fully functional!** Interaction profiling is enabled using system OpenBabel packages (python3-openbabel) and PLIP source code +- **Performance**: First build may take 10-15 minutes due to ANARCI model building + +## Troubleshooting + +### ANARCI build fails: +The ANARCI model building is automatic but may fail on some systems. If needed, rebuild manually: +```bash +docker-compose exec stcrpy ANARCI --build_models +``` + +### Permission issues with volumes: +Ensure your user has write permissions to `./data` and `./output` directories. + +### ML dependencies fail: +If PyTorch installation fails, you may need to specify the CPU version: +```bash +docker-compose exec stcrpy-ml uv pip install torch --index-url https://download.pytorch.org/whl/cpu +``` diff --git a/test_docker.py b/test_docker.py new file mode 100644 index 0000000..a47e675 --- /dev/null +++ b/test_docker.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python3 +""" +Simple test script to verify STCRpy installation in Docker +""" + +import sys + +def test_imports(): + """Test that all required modules can be imported""" + print("Testing STCRpy installation...") + + try: + import stcrpy + print("✓ stcrpy imported successfully") + except ImportError as e: + print(f"✗ Failed to import stcrpy: {e}") + return False + + try: + import Bio + print("✓ biopython imported successfully") + except ImportError as e: + print(f"✗ Failed to import biopython: {e}") + return False + + try: + import pandas as pd + print("✓ pandas imported successfully") + except ImportError as e: + print(f"✗ Failed to import pandas: {e}") + return False + + try: + import numpy as np + print("✓ numpy imported successfully") + except ImportError as e: + print(f"✗ Failed to import numpy: {e}") + return False + + return True + +def test_basic_functionality(): + """Test basic STCRpy functionality""" + print("\nTesting basic functionality...") + + try: + import stcrpy + # Try fetching a structure (requires internet) + print("Attempting to fetch TCR structure 8gvb from PDB...") + tcrs = stcrpy.fetch_TCRs("8gvb") + print(f"✓ Successfully fetched {len(tcrs)} TCR structure(s)") + + if tcrs: + tcr = tcrs[0] + print(f" - TCR has {len(list(tcr.get_chains()))} chain(s)") + + return True + except Exception as e: + print(f"✗ Basic functionality test failed: {e}") + return False + +def main(): + """Run all tests""" + print("=" * 60) + print("STCRpy Docker Installation Test") + print("=" * 60) + + # Test imports + if not test_imports(): + print("\n❌ Import tests failed!") + sys.exit(1) + + # Test basic functionality + if not test_basic_functionality(): + print("\n⚠️ Basic functionality test failed (may require internet)") + + print("\n" + "=" * 60) + print("✅ STCRpy is properly installed and ready to use!") + print("=" * 60) + +if __name__ == "__main__": + main() From 7028f053820aa91218dd5209175b888affd6a2d3 Mon Sep 17 00:00:00 2001 From: Jola Kopec Date: Mon, 3 Nov 2025 10:07:49 +0000 Subject: [PATCH 02/10] feat: add PyMOL visualization support --- Dockerfile | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index b3cf335..e6d7cf5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,8 @@ FROM python:3.12-slim -# Install system dependencies including OpenBabel from system packages +# STCRpy Docker Image with full analysis and visualization support +# Includes: STCRpy, PLIP (interaction profiling), PyMOL (3D visualization) +# Install system dependencies including OpenBabel and PyMOL dependencies # Using python3-openbabel from Debian avoids building from source ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y \ @@ -14,6 +16,22 @@ RUN apt-get update && apt-get install -y \ libopenbabel7 \ libopenbabel-dev \ python3-openbabel \ + # PyMOL build dependencies + libglew-dev \ + libpng-dev \ + libfreetype6-dev \ + libmsgpack-dev \ + python3-dev \ + libglm-dev \ + # Qt5 dependencies for PyMOL GUI + libqt5core5a \ + libqt5gui5 \ + libqt5widgets5 \ + libqt5opengl5 \ + qt5-qmake \ + qtbase5-dev \ + libxcb-xinerama0 \ + libxkbcommon-x11-0 \ && rm -rf /var/lib/apt/lists/* # Install uv @@ -29,6 +47,7 @@ COPY . . RUN uv venv /opt/venv --system-site-packages && \ . /opt/venv/bin/activate && \ uv pip install -e . && \ + uv pip install pymol-open-source PyQt5 && \ ANARCI --build_models # Install PLIP source code directly (avoids pip build issues) From 4c9ad1a3088871d43c39d3e29772bd7bd139ba1c Mon Sep 17 00:00:00 2001 From: Jola Kopec Date: Mon, 3 Nov 2025 10:27:30 +0000 Subject: [PATCH 03/10] feat: add PyMOL to ML Docker image --- Dockerfile.ml | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/Dockerfile.ml b/Dockerfile.ml index bb4b381..3126ffa 100644 --- a/Dockerfile.ml +++ b/Dockerfile.ml @@ -1,6 +1,8 @@ FROM python:3.12-slim -# Install system dependencies including OpenBabel from system packages +# STCRpy ML Docker Image with full analysis, ML, and visualization support +# Includes: STCRpy, PLIP, PyMOL, scikit-learn, PyTorch, transformers +# Install system dependencies including OpenBabel and PyMOL dependencies # Using python3-openbabel from Debian avoids building from source ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y \ @@ -14,6 +16,22 @@ RUN apt-get update && apt-get install -y \ libopenbabel7 \ libopenbabel-dev \ python3-openbabel \ + # PyMOL build dependencies + libglew-dev \ + libpng-dev \ + libfreetype6-dev \ + libmsgpack-dev \ + python3-dev \ + libglm-dev \ + # Qt5 dependencies for PyMOL GUI + libqt5core5a \ + libqt5gui5 \ + libqt5widgets5 \ + libqt5opengl5 \ + qt5-qmake \ + qtbase5-dev \ + libxcb-xinerama0 \ + libxkbcommon-x11-0 \ && rm -rf /var/lib/apt/lists/* # Install uv @@ -29,7 +47,7 @@ COPY . . RUN uv venv /opt/venv --system-site-packages && \ . /opt/venv/bin/activate && \ uv pip install -e ".[ml_datasets]" && \ - uv pip install einops && \ + uv pip install einops pymol-open-source PyQt5 && \ ANARCI --build_models # Install PLIP source code directly (avoids pip build issues) From a718aada1c1b2fdf587befc549e91fe419790efb Mon Sep 17 00:00:00 2001 From: Jola Kopec Date: Mon, 3 Nov 2025 15:19:18 +0000 Subject: [PATCH 04/10] fix: track PLIP binding site IDs in interactions --- stcrpy/tcr_interactions/PLIPParser.py | 6 ++-- stcrpy/tcr_interactions/utils.py | 40 +++++++++++++-------------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/stcrpy/tcr_interactions/PLIPParser.py b/stcrpy/tcr_interactions/PLIPParser.py index 4bc44ce..e926d77 100644 --- a/stcrpy/tcr_interactions/PLIPParser.py +++ b/stcrpy/tcr_interactions/PLIPParser.py @@ -29,10 +29,10 @@ def parse_complex( pd.DataFrame: _description_ """ all_interactions = [] - for _, interaction_set in complex.interaction_sets.items(): + for bsid, interaction_set in complex.interaction_sets.items(): for interaction in interaction_set.all_itypes: try: - all_interactions.append(plip_utils.parse_interaction(interaction)) + all_interactions.append(plip_utils.parse_interaction(interaction, bsid)) except NotImplementedError as e: print(e) continue @@ -104,7 +104,7 @@ def _interactions_to_dataframe(self, interaction_list: list) -> pd.DataFrame: "ligand_atom", "distance", "angle", - "plip_id", + "plip_binding_site_id", ] interactions_as_tuples = [ diff --git a/stcrpy/tcr_interactions/utils.py b/stcrpy/tcr_interactions/utils.py index 7f10e79..e78dca2 100644 --- a/stcrpy/tcr_interactions/utils.py +++ b/stcrpy/tcr_interactions/utils.py @@ -38,7 +38,7 @@ def __init__( ligand_atom, distance, angle, - plip_id, + plip_binding_site_id, ) -> None: self.type = type self.protein_atom = protein_atom @@ -48,7 +48,7 @@ def __init__( self.ligand_atom = ligand_atom self.distance = distance self.angle = angle - self.plip_id = plip_id + self.plip_binding_site_id = plip_binding_site_id def to_tuple(self): return ( @@ -60,24 +60,24 @@ def to_tuple(self): self.ligand_atom, self.distance, self.angle, - self.plip_id, + self.plip_binding_site_id, ) -def parse_interaction(interaction) -> Interaction: +def parse_interaction(interaction, bsid=None) -> Interaction: if "saltbridge" in str(type(interaction)): - return Interaction("saltbridge", *process_saltbridge(interaction)) + return Interaction("saltbridge", *process_saltbridge(interaction, bsid)) elif "hydroph" in str(type(interaction)): - return Interaction("hydrophobic", *process_hydrophobic(interaction)) + return Interaction("hydrophobic", *process_hydrophobic(interaction, bsid)) elif "hbond" in str(type(interaction)): - return Interaction("hbond", *process_hbond(interaction)) + return Interaction("hbond", *process_hbond(interaction, bsid)) elif "pistack" in str(type(interaction)): - return Interaction("pistack", *process_pi_stack(interaction)) + return Interaction("pistack", *process_pi_stack(interaction, bsid)) else: raise NotImplementedError(f"Parsing not implemented for {type(interaction)}") -def process_pi_stack(interaction): +def process_pi_stack(interaction, bsid=None): protein_ring_atoms = [ (j.coords, j.atomicnum) for j in interaction.proteinring.atoms ] @@ -87,7 +87,7 @@ def process_pi_stack(interaction): ligand_ring_atoms = [(j.coords, j.atomicnum) for j in interaction.ligandring.atoms] distance = interaction.distance angle = interaction.angle - plip_id = None + plip_binding_site_id = bsid return ( protein_ring_atoms, protein_chain, @@ -96,18 +96,18 @@ def process_pi_stack(interaction): ligand_ring_atoms, distance, angle, - plip_id, + plip_binding_site_id, ) -def process_hydrophobic(interaction): +def process_hydrophobic(interaction, bsid=None): protein_atom = [(interaction.bsatom.coords, interaction.bsatom.atomicnum)] protein_chain = interaction.reschain protein_residue = interaction.restype protein_number = interaction.resnr ligand_atom = [(interaction.ligatom.coords, interaction.ligatom.atomicnum)] distance = interaction.distance - plip_id = None + plip_binding_site_id = bsid return ( protein_atom, protein_chain, @@ -116,11 +116,11 @@ def process_hydrophobic(interaction): ligand_atom, distance, None, - plip_id, + plip_binding_site_id, ) -def process_hbond(interaction): +def process_hbond(interaction, bsid=None): if interaction.protisdon: protein_atom = [(interaction.d.coords, interaction.d.atomicnum)] ligand_atom = [(interaction.a.coords, interaction.a.atomicnum)] @@ -133,7 +133,7 @@ def process_hbond(interaction): protein_number = interaction.resnr distance = interaction.distance_ad angle = interaction.angle - plip_id = None + plip_binding_site_id = bsid return ( protein_atom, protein_chain, @@ -142,11 +142,11 @@ def process_hbond(interaction): ligand_atom, distance, angle, - plip_id, + plip_binding_site_id, ) -def process_saltbridge(interaction): +def process_saltbridge(interaction, bsid=None): if interaction.protispos: protein_atom = [(a.coords, a.atomicnum) for a in interaction.positive.atoms] ligand_atom = [(a.coords, a.atomicnum) for a in interaction.negative.atoms] @@ -157,7 +157,7 @@ def process_saltbridge(interaction): protein_residue = interaction.restype protein_number = interaction.resnr distance = interaction.distance - plip_id = None + plip_binding_site_id = bsid return ( protein_atom, protein_chain, @@ -166,5 +166,5 @@ def process_saltbridge(interaction): ligand_atom, distance, None, - plip_id, + plip_binding_site_id, ) From b445f085d30bb698f266f963226e766b6dba55a5 Mon Sep 17 00:00:00 2001 From: benjiemc Date: Tue, 25 Nov 2025 14:24:48 +0000 Subject: [PATCH 05/10] Merge Docker files --- Dockerfile | 8 +++---- Dockerfile.ml | 63 --------------------------------------------------- 2 files changed, 4 insertions(+), 67 deletions(-) delete mode 100644 Dockerfile.ml diff --git a/Dockerfile b/Dockerfile index e6d7cf5..999c74d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ FROM python:3.12-slim -# STCRpy Docker Image with full analysis and visualization support -# Includes: STCRpy, PLIP (interaction profiling), PyMOL (3D visualization) +# STCRpy Docker Image with full analysis, ML, and visualization support +# Includes: STCRpy, PLIP, PyMOL, scikit-learn, PyTorch, transformers # Install system dependencies including OpenBabel and PyMOL dependencies # Using python3-openbabel from Debian avoids building from source ENV DEBIAN_FRONTEND=noninteractive @@ -46,8 +46,8 @@ COPY . . # Create virtual environment with system-site-packages to access python3-openbabel RUN uv venv /opt/venv --system-site-packages && \ . /opt/venv/bin/activate && \ - uv pip install -e . && \ - uv pip install pymol-open-source PyQt5 && \ + uv pip install -e ".[ml_datasets]" && \ + uv pip install einops pymol-open-source PyQt5 && \ ANARCI --build_models # Install PLIP source code directly (avoids pip build issues) diff --git a/Dockerfile.ml b/Dockerfile.ml deleted file mode 100644 index 3126ffa..0000000 --- a/Dockerfile.ml +++ /dev/null @@ -1,63 +0,0 @@ -FROM python:3.12-slim - -# STCRpy ML Docker Image with full analysis, ML, and visualization support -# Includes: STCRpy, PLIP, PyMOL, scikit-learn, PyTorch, transformers -# Install system dependencies including OpenBabel and PyMOL dependencies -# Using python3-openbabel from Debian avoids building from source -ENV DEBIAN_FRONTEND=noninteractive -RUN apt-get update && apt-get install -y \ - build-essential \ - wget \ - git \ - libxml2-dev \ - libxslt1-dev \ - zlib1g-dev \ - openbabel \ - libopenbabel7 \ - libopenbabel-dev \ - python3-openbabel \ - # PyMOL build dependencies - libglew-dev \ - libpng-dev \ - libfreetype6-dev \ - libmsgpack-dev \ - python3-dev \ - libglm-dev \ - # Qt5 dependencies for PyMOL GUI - libqt5core5a \ - libqt5gui5 \ - libqt5widgets5 \ - libqt5opengl5 \ - qt5-qmake \ - qtbase5-dev \ - libxcb-xinerama0 \ - libxkbcommon-x11-0 \ - && rm -rf /var/lib/apt/lists/* - -# Install uv -COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv - -# Set working directory -WORKDIR /app - -# Copy project files -COPY . . - -# Create virtual environment with system-site-packages to access python3-openbabel -RUN uv venv /opt/venv --system-site-packages && \ - . /opt/venv/bin/activate && \ - uv pip install -e ".[ml_datasets]" && \ - uv pip install einops pymol-open-source PyQt5 && \ - ANARCI --build_models - -# Install PLIP source code directly (avoids pip build issues) -# PLIP is pure Python and uses system openbabel bindings -RUN git clone https://github.com/pharmai/plip.git /opt/plip && \ - ln -s /opt/plip/plip /opt/venv/lib/python3.12/site-packages/plip - -# Set environment to use venv -ENV PATH="/opt/venv/bin:$PATH" -ENV VIRTUAL_ENV="/opt/venv" - -# Default command -CMD ["/bin/bash"] From 6166d69d57aebe3fdb1a25039c0cb0473a3f38c6 Mon Sep 17 00:00:00 2001 From: benjiemc Date: Tue, 25 Nov 2025 14:26:51 +0000 Subject: [PATCH 06/10] Consolidate Docker instructions to README --- README.Docker.md | 134 ----------------------------------------------- README.md | 24 +++++++++ 2 files changed, 24 insertions(+), 134 deletions(-) delete mode 100644 README.Docker.md diff --git a/README.Docker.md b/README.Docker.md deleted file mode 100644 index 54ef764..0000000 --- a/README.Docker.md +++ /dev/null @@ -1,134 +0,0 @@ -# Docker Setup for STCRpy - -This directory contains Docker configuration for running STCRpy in a containerized environment with uv dependency management. - -## Quick Start - -### Build and run the basic STCRpy container: -```bash -docker-compose up -d stcrpy -docker-compose exec stcrpy bash -``` - -### Build and run with ML dependencies (PyTorch, PyTorch Geometric): -```bash -docker-compose --profile ml up -d stcrpy-ml -docker-compose --profile ml exec stcrpy-ml bash -``` - -## Services - -### `stcrpy` (default) -Basic STCRpy installation with core dependencies: -- BioPython -- PLIP for interaction profiling -- ANARCI for sequence annotation -- All core STCRpy functionality - -### `stcrpy-ml` (ML profile) -STCRpy with machine learning dependencies: -- PyTorch -- PyTorch Geometric -- All features from base image -- Use for graph neural network applications - -### `stcrpy-batch` (batch profile) -For batch processing tasks: -```bash -docker-compose --profile batch run stcrpy-batch python your_script.py -``` - -## Directory Structure - -The following directories are mounted as volumes: -- `./data` → `/app/data` - Input data files -- `./examples` → `/app/examples` - Example scripts and notebooks -- `./output` → `/app/output` - Analysis outputs - -Create these directories before running: -```bash -mkdir -p data output -``` - -## Usage Examples - -### Interactive Python session: -```bash -docker-compose exec stcrpy python -``` - -```python -import stcrpy -tcr = stcrpy.fetch_TCRs("8gvb") -``` - -### Run a script: -```bash -docker-compose exec stcrpy python examples/STCRpy_examples.py -``` - -### Process local PDB files: -```bash -# Place your PDB files in ./data/ -docker-compose exec stcrpy python -c " -import stcrpy -tcr = stcrpy.load_TCR('/app/data/your_file.pdb') -tcr.calculate_geometry() -tcr.save('/app/output/processed.pdb') -" -``` - -## Building Images - -### Build all images: -```bash -docker-compose build -``` - -### Build specific image: -```bash -docker-compose build stcrpy -docker-compose build stcrpy-ml -``` - -## Managing Containers - -### Stop containers: -```bash -docker-compose down -``` - -### View logs: -```bash -docker-compose logs -f stcrpy -``` - -### Remove all containers and volumes: -```bash -docker-compose down -v -``` - -## Notes - -- **uv**: This setup uses [uv](https://github.com/astral-sh/uv) for fast Python package management -- **ANARCI models**: Built automatically during image creation (takes a few minutes) -- **PyMOL**: Not included in Docker images (requires GUI support). For visualization, export files and use local PyMOL installation -- **PLIP**: ✅ **Fully functional!** Interaction profiling is enabled using system OpenBabel packages (python3-openbabel) and PLIP source code -- **Performance**: First build may take 10-15 minutes due to ANARCI model building - -## Troubleshooting - -### ANARCI build fails: -The ANARCI model building is automatic but may fail on some systems. If needed, rebuild manually: -```bash -docker-compose exec stcrpy ANARCI --build_models -``` - -### Permission issues with volumes: -Ensure your user has write permissions to `./data` and `./output` directories. - -### ML dependencies fail: -If PyTorch installation fails, you may need to specify the CPU version: -```bash -docker-compose exec stcrpy-ml uv pip install torch --index-url https://download.pytorch.org/whl/cpu -``` diff --git a/README.md b/README.md index f683987..90b08ba 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,30 @@ pip install stcrpy[ml_datasets] > pip install einops > ``` +### Docker container installation + +This directory contains [Docker](https://www.docker.com/) configuration for running STCRpy in a containerized environment with uv dependency management. To build the docker image run: + +``` +docker build -t stcrpy . +``` + +And then run and example with: + +``` +mkdir output +docker run --rm \ + -v $(pwd)/output:/app/output \ + stcrpy python -c " +import stcrpy +tcr = stcrpy.fetch_TCRs('8gvb')[0] +tcr.profile_peptide_interactions() +tcr.get_interaction_heatmap(plotting_kwargs={'save_as': '/app/output/heatmap.png'}) +" +``` + +If all goes well, there should be a heatmap.png file in the "./output" folder. + # Documentation STCRpy [documentation](https://stcrpy.readthedocs.io/en/latest/) is hosted on ReadtheDocs. From 21de9439dc05cc19c41fe3dd9cde1f56e48f3e89 Mon Sep 17 00:00:00 2001 From: benjiemc Date: Tue, 25 Nov 2025 14:27:13 +0000 Subject: [PATCH 07/10] Remove unnescessary docker files --- .env.example | 26 ---------------- test_docker.py | 82 -------------------------------------------------- 2 files changed, 108 deletions(-) delete mode 100644 .env.example delete mode 100644 test_docker.py diff --git a/.env.example b/.env.example deleted file mode 100644 index a3ba223..0000000 --- a/.env.example +++ /dev/null @@ -1,26 +0,0 @@ -# STCRpy Docker Environment Configuration -# Copy this file to .env and customize for your setup - -# Host directories (on your computer) -# These will be mounted into the Docker container -DATA_DIR=./data -OUTPUT_DIR=./output -EXAMPLES_DIR=./examples - -# Optional: Absolute paths work too -# DATA_DIR=/home/user/my_tcr_data -# OUTPUT_DIR=/home/user/my_tcr_results - -# Container working directory (inside Docker) -WORKDIR=/app - -# Python optimization -PYTHONUNBUFFERED=1 - -# Optional: GPU configuration (if using ML profile with GPU) -# NVIDIA_VISIBLE_DEVICES=all -# CUDA_VISIBLE_DEVICES=0 - -# Optional: Resource limits -# MEMORY_LIMIT=8g -# CPU_LIMIT=4 diff --git a/test_docker.py b/test_docker.py deleted file mode 100644 index a47e675..0000000 --- a/test_docker.py +++ /dev/null @@ -1,82 +0,0 @@ -#!/usr/bin/env python3 -""" -Simple test script to verify STCRpy installation in Docker -""" - -import sys - -def test_imports(): - """Test that all required modules can be imported""" - print("Testing STCRpy installation...") - - try: - import stcrpy - print("✓ stcrpy imported successfully") - except ImportError as e: - print(f"✗ Failed to import stcrpy: {e}") - return False - - try: - import Bio - print("✓ biopython imported successfully") - except ImportError as e: - print(f"✗ Failed to import biopython: {e}") - return False - - try: - import pandas as pd - print("✓ pandas imported successfully") - except ImportError as e: - print(f"✗ Failed to import pandas: {e}") - return False - - try: - import numpy as np - print("✓ numpy imported successfully") - except ImportError as e: - print(f"✗ Failed to import numpy: {e}") - return False - - return True - -def test_basic_functionality(): - """Test basic STCRpy functionality""" - print("\nTesting basic functionality...") - - try: - import stcrpy - # Try fetching a structure (requires internet) - print("Attempting to fetch TCR structure 8gvb from PDB...") - tcrs = stcrpy.fetch_TCRs("8gvb") - print(f"✓ Successfully fetched {len(tcrs)} TCR structure(s)") - - if tcrs: - tcr = tcrs[0] - print(f" - TCR has {len(list(tcr.get_chains()))} chain(s)") - - return True - except Exception as e: - print(f"✗ Basic functionality test failed: {e}") - return False - -def main(): - """Run all tests""" - print("=" * 60) - print("STCRpy Docker Installation Test") - print("=" * 60) - - # Test imports - if not test_imports(): - print("\n❌ Import tests failed!") - sys.exit(1) - - # Test basic functionality - if not test_basic_functionality(): - print("\n⚠️ Basic functionality test failed (may require internet)") - - print("\n" + "=" * 60) - print("✅ STCRpy is properly installed and ready to use!") - print("=" * 60) - -if __name__ == "__main__": - main() From ddb07b75b1be326ad7ea0c59105b617873b7631f Mon Sep 17 00:00:00 2001 From: benjiemc Date: Tue, 25 Nov 2025 15:13:47 +0000 Subject: [PATCH 08/10] Remove UV from Docker setup --- Dockerfile | 19 +++++-------------- README.md | 2 +- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/Dockerfile b/Dockerfile index 999c74d..b234217 100644 --- a/Dockerfile +++ b/Dockerfile @@ -34,30 +34,21 @@ RUN apt-get update && apt-get install -y \ libxkbcommon-x11-0 \ && rm -rf /var/lib/apt/lists/* -# Install uv -COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv - # Set working directory WORKDIR /app # Copy project files COPY . . -# Create virtual environment with system-site-packages to access python3-openbabel -RUN uv venv /opt/venv --system-site-packages && \ - . /opt/venv/bin/activate && \ - uv pip install -e ".[ml_datasets]" && \ - uv pip install einops pymol-open-source PyQt5 && \ - ANARCI --build_models +# Install STCRpy and dependencies +RUN pip install --no-cache-dir --root-user-action ignore -e ".[ml_datasets]" \ + && pip install --no-cache-dir --root-user-action ignore einops pymol-open-source PyQt5 \ + && ANARCI --build_models # Install PLIP source code directly (avoids pip build issues) # PLIP is pure Python and uses system openbabel bindings RUN git clone https://github.com/pharmai/plip.git /opt/plip && \ - ln -s /opt/plip/plip /opt/venv/lib/python3.12/site-packages/plip - -# Set environment to use venv -ENV PATH="/opt/venv/bin:$PATH" -ENV VIRTUAL_ENV="/opt/venv" + ln -s /opt/plip/plip /usr/local/lib/python3.12/site-packages/ # Default command CMD ["/bin/bash"] diff --git a/README.md b/README.md index 90b08ba..f889ec2 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,7 @@ pip install stcrpy[ml_datasets] ### Docker container installation -This directory contains [Docker](https://www.docker.com/) configuration for running STCRpy in a containerized environment with uv dependency management. To build the docker image run: +This directory contains [Docker](https://www.docker.com/) configuration for running STCRpy in a containerized environment. To build the docker image run: ``` docker build -t stcrpy . From 25946d5fb662ddd8dcce316a217d960fab87d274 Mon Sep 17 00:00:00 2001 From: benjiemc Date: Tue, 25 Nov 2025 15:14:42 +0000 Subject: [PATCH 09/10] Remove unnescessary comments --- Dockerfile | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index b234217..f13756c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -34,10 +34,7 @@ RUN apt-get update && apt-get install -y \ libxkbcommon-x11-0 \ && rm -rf /var/lib/apt/lists/* -# Set working directory WORKDIR /app - -# Copy project files COPY . . # Install STCRpy and dependencies @@ -50,5 +47,4 @@ RUN pip install --no-cache-dir --root-user-action ignore -e ".[ml_datasets]" \ RUN git clone https://github.com/pharmai/plip.git /opt/plip && \ ln -s /opt/plip/plip /usr/local/lib/python3.12/site-packages/ -# Default command CMD ["/bin/bash"] From 8561e03d6d840655470470ca57d4fb6cebc61af8 Mon Sep 17 00:00:00 2001 From: benjiemc Date: Tue, 25 Nov 2025 15:59:16 +0000 Subject: [PATCH 10/10] Do not add data directories to gitignore --- .gitignore | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/.gitignore b/.gitignore index 93dd9e3..57777a5 100644 --- a/.gitignore +++ b/.gitignore @@ -23,17 +23,3 @@ test/test_files/out/haddock/*/* test/test_files/out/haddock/** */ test/test_files/** */ test/test_files - -# Docker Environment -.env - -# Data directories (contain user data) -data/* -output/* -models/* -scratch/* - -# Keep directory structure -!data/.gitkeep -!output/.gitkeep -!models/.gitkeep