|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +alchemiscale-fah is a Python service that integrates Folding@Home (FAH) as a distributed compute backend for alchemiscale, enabling planetary-scale alchemical free energy calculations. It provides an asynchronous compute service that claims tasks from alchemiscale, submits molecular dynamics simulation jobs to FAH work servers, polls for completion, and returns results. |
| 8 | + |
| 9 | +## Common Commands |
| 10 | + |
| 11 | +### Environment Setup |
| 12 | +```bash |
| 13 | +# Create conda environment (requires micromamba/mamba) |
| 14 | +micromamba create -f devtools/conda-envs/test.yml |
| 15 | +micromamba activate alchemiscale-fah-test |
| 16 | +pip install --no-deps -e . |
| 17 | +``` |
| 18 | + |
| 19 | +### Testing |
| 20 | +```bash |
| 21 | +# Run all tests with coverage |
| 22 | +pytest -v --cov=alchemiscale_fah --cov-report=xml alchemiscale_fah/tests |
| 23 | + |
| 24 | +# Run a single test file |
| 25 | +pytest -v alchemiscale_fah/tests/unit/test_utils.py |
| 26 | + |
| 27 | +# Run a single test |
| 28 | +pytest -v alchemiscale_fah/tests/unit/test_utils.py::test_function_name |
| 29 | +``` |
| 30 | + |
| 31 | +### Formatting |
| 32 | +```bash |
| 33 | +# Check formatting (enforced in CI) |
| 34 | +black --check --diff alchemiscale_fah |
| 35 | + |
| 36 | +# Auto-format |
| 37 | +black alchemiscale_fah |
| 38 | +``` |
| 39 | + |
| 40 | +### CLI |
| 41 | +```bash |
| 42 | +alchemiscale-fah --help |
| 43 | +alchemiscale-fah compute fah-asynchronous --config-file config.yml |
| 44 | +``` |
| 45 | + |
| 46 | +## Architecture |
| 47 | + |
| 48 | +### Core Data Flow |
| 49 | +``` |
| 50 | +alchemiscale server → Task claimed by FahAsynchronousComputeService |
| 51 | +→ ProtocolDAG deserialized → FahSimulationUnits execute asynchronously |
| 52 | +→ Jobs submitted to FAH work server → Service polls for completion |
| 53 | +→ Results retrieved → ProtocolDAGResult assembled → Returned to alchemiscale |
| 54 | +``` |
| 55 | + |
| 56 | +### Key Components |
| 57 | + |
| 58 | +**`compute/service.py` — FahAsynchronousComputeService**: Main orchestrator. Extends alchemiscale's `SynchronousComputeService`. Claims tasks, manages the full lifecycle of ProtocolDAG execution through FAH, and handles async polling for job completion. |
| 59 | + |
| 60 | +**`compute/client.py` — FahAdaptiveSamplingClient**: HTTP/TLS client for FAH assignment and work servers. Handles RSA key generation, CSR creation, certificate renewal, job submission, and result retrieval. |
| 61 | + |
| 62 | +**`compute/index.py` — FahComputeServiceIndex**: LevelDB-backed persistent state store. Tracks active tasks, FAH project/run/clone mappings, and job states. Thread-safe. |
| 63 | + |
| 64 | +**`compute/models.py`**: Pydantic models for FAH data structures (ProjectData, JobData, JobResults, FahProject, FahRun, FahClone, JobStateEnum). |
| 65 | + |
| 66 | +**`compute/settings.py` — FahAsynchronousComputeServiceSettings**: Pydantic-based configuration schema for the compute service. |
| 67 | + |
| 68 | +**`protocols/protocolunit.py` — FahSimulationUnit, FahContext**: Base class for FAH-aware protocol units. `FahContext` is a kw_only dataclass extending GUFE's `Context` that injects FAH-specific dependencies (client, projects, index, poll interval) into unit execution. |
| 69 | + |
| 70 | +**`protocols/feflow/nonequilibrium_cycling.py`**: FAH-optimized implementation of nonequilibrium cycling protocol using OpenMM via feflow. |
| 71 | + |
| 72 | +**`settings/`**: Protocol-level settings schemas — `FahOpenMMCoreSettings` for execution parameters, FAH WS API settings. |
| 73 | + |
| 74 | +**`utils.py`**: Utility functions for effort calculation and credit assignment, including `NonbondedSettings` enum and `NONBONDED_EFFORT` mapping. |
| 75 | + |
| 76 | +### Key Design Patterns |
| 77 | + |
| 78 | +- **Async execution**: `FahSimulationUnit.execute()` is async; the service uses asyncio for non-blocking FAH polling |
| 79 | +- **Context injection**: `FahContext` dataclass provides all FAH dependencies to protocol units during execution |
| 80 | +- **State persistence**: LevelDB index tracks job state across service restarts |
| 81 | +- **Effort-based routing**: Projects are selected based on simulation effort (PME vs NoCutoff nonbonded methods) |
| 82 | + |
| 83 | +### Dependencies |
| 84 | + |
| 85 | +Core ecosystem: `gufe` (protocol framework), `openfe` (chemistry), `feflow` (OpenMM protocols), `alchemiscale` (task orchestration). Python 3.11+. Uses `pytest-asyncio` with `asyncio_mode = "auto"` for testing. |
0 commit comments