Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
be10d29
feat: add gh action for test
Nithishwer Nov 12, 2025
ca69f0b
feat: add gh action to develop too
Nithishwer Nov 12, 2025
240883c
feat: add gh action to doc too
Nithishwer Nov 12, 2025
e66c110
feat: add fepa install stel
Nithishwer Nov 12, 2025
bc44422
feat: match python version
Nithishwer Nov 12, 2025
4bb171f
feat: match python version
Nithishwer Nov 12, 2025
016f353
feat: match python 3.10
Nithishwer Nov 12, 2025
5078670
fix: clear caceh
Nithishwer Nov 12, 2025
76c7fdd
fix: remove setup.py
Nithishwer Nov 12, 2025
e55e176
fix: use conda env
Nithishwer Nov 12, 2025
9eb92ae
fix: add salilab conda channel
Nithishwer Nov 12, 2025
99c2e49
fix: loosen modeller version req
Nithishwer Nov 12, 2025
9df1c2f
fix: loosen python requirements
Nithishwer Nov 12, 2025
8e59511
fix: no python req
Nithishwer Nov 12, 2025
5adb225
fix: add requirements yml
Nithishwer Nov 12, 2025
95cf1ec
fix: edit python req
Nithishwer Nov 12, 2025
5615b36
fix: better gh workflow + new how-to-guide
Nithishwer Nov 12, 2025
74e07db
fix: remove python from requirement.yml
Nithishwer Nov 13, 2025
f8a9a64
fix: remove prefix from requirement.yml
Nithishwer Nov 13, 2025
446f285
fix: remove python vers from test.yml
Nithishwer Nov 13, 2025
f3dd7a5
fix: add python 3.10 to req
Nithishwer Nov 13, 2025
45e55ba
fix: add fepa env activate with test
Nithishwer Nov 13, 2025
21fa9b7
fix: using conda for test
Nithishwer Nov 13, 2025
df8f9ed
fix: add pytest to requirements.yml
Nithishwer Nov 13, 2025
960ab00
fix: add umap to requirements,yml
Nithishwer Nov 13, 2025
2142cca
fix: add pymemento to requirement
Nithishwer Nov 13, 2025
65da581
fix: fepa test import
Nithishwer Nov 13, 2025
a20b595
fix: change util import in tests
Nithishwer Nov 13, 2025
0e91b4f
feat: import utils from tests
Nithishwer Nov 13, 2025
9bd6fb2
feat: import utils from tests a1
Nithishwer Nov 13, 2025
ea04ee1
fix: add init.py to test subfolders
Nithishwer Nov 13, 2025
99308db
fix: remove steus utils
Nithishwer Nov 13, 2025
df28023
fix: remove steus mdp
Nithishwer Nov 13, 2025
f755d69
fix: add new runtest in tests.yml actionm
Nithishwer Nov 13, 2025
1cbb222
fix: remove steus flow
Nithishwer Nov 13, 2025
9b53b99
fix: remove steus flow from init
Nithishwer Nov 13, 2025
2c8bddb
fix: reduce comp tolerance
Nithishwer Nov 23, 2025
39f29dc
fix: add badge to readme
Nithishwer Nov 23, 2025
43d0fb9
fix: add badge to readme
Nithishwer Nov 23, 2025
a4a414e
Add LICENSE file
Nithishwer Nov 23, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Tests

on:
push:
branches: [ main, develop, feat/documentation ]
pull_request:
branches: [ main, develop, feat/documentation ]

jobs:
test:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Cache Conda packages
uses: actions/cache@v4
with:
path: ~/.conda/pkgs
key: conda-${{ runner.os }}-${{ hashFiles('requirements.yml') }}
restore-keys: |
conda-${{ runner.os }}-

- name: Set up Conda environment
uses: conda-incubator/setup-miniconda@v3
with:
environment-file: requirements.yml
activate-environment: fepa_env
auto-update-conda: true
use-mamba: true

- name: Install package in editable mode
run: conda run -n fepa_env pip install --no-cache-dir -e .

- name: Run tests
run: |
export PYTHONPATH=$(pwd)
conda run -n fepa_env pytest -v --maxfail=1 --disable-warnings

695 changes: 674 additions & 21 deletions LICENSE

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@

# Getting Started with FEPA

[![Tests](https://github.com/Nithishwer/FEPA/actions/workflows/test.yml/badge.svg)](https://github.com/Nithishwer/FEPA/actions/workflows/test.yml)


**FEPA** (Free Energy Perturbation Analysis) is a Python package for analyzing molecular dynamics (MD) trajectories from FEP simulations, particularly **ABFEs**. FEPA allows you to visualize conformational changes and set up simulations to correct free energy estimates.

This guide covers installation, basic usage, and key workflows.
Expand Down
99 changes: 97 additions & 2 deletions docs/how-to-guides/guide-1.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,101 @@
---
icon: lucide/compass
title: How-to-Guide
title: Binding Pocket Resolvation Analysis
---

Put the example analysis in the how to guide section here
Visualizing binding pocket resolvation across ABFE simulations is straightforward with FEPA. We follow a workflow similar to Tutorial 1, but instead of `SelfDistanceFeaturizer`, we use `BPWaterFeaturizer` to quantify water occupancy.

### Load Config and Prepare Paths

```python
import logging, os
from fepa.utils.file_utils import load_config
from fepa.utils.path_utils import load_abfe_paths_for_compound

logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")

config = load_config("../../config/config.json")
analysis_output_dir = "wdir"
cmp = config["compounds"][0]

logging.info("Analyzing compound %s ...", cmp)
cmp_output_dir = os.path.join(analysis_output_dir, cmp)
os.makedirs(cmp_output_dir, exist_ok=True)

logging.info("Loading paths for compound %s...", cmp)
path_dict = load_abfe_paths_for_compound(
config,
cmp,
van_list=[1, 2, 3],
leg_window_list=[f"coul.{i:02d}" for i in range(0, 11)]
+ [f"rest.{i:02d}" for i in range(0, 12)]
+ [f"vdw.{i:02d}" for i in range(0, 21)],
bp_selection_string="name CA and resid 57 58 61 64 83 84 87 88 91 92 173 177 218 221 235 238 239 242 243 246",
apo=False,
)
```

### Load trajectories and featurize waters

```python
from fepa.core.ensemble_handler import EnsembleHandler
from fepa.core.featurizers import BPWaterFeaturizer

logging.info("Loading trajectories for compound %s ...", cmp)
ensemble_handler = EnsembleHandler(path_dict)
ensemble_handler.make_universes()

logging.info("Featurizing binding pocket waters ...")
bp_water_featurizer = BPWaterFeaturizer(ensemble_handler=ensemble_handler)
bp_water_featurizer.featurize(radius=10) # Count waters within 10 Å of pocket COM

logging.info("Saving features for compound %s ...", cmp)
bp_water_featurizer.save_features(cmp_output_dir, overwrite=True)
```

### Plot Water Occupancy Over Time or Windows

```python
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

features_df = pd.read_csv(os.path.join(cmp_output_dir, "WaterOccupancy_features.csv"))

for van in [1, 2, 3]:
van_features_df = features_df[features_df["ensemble"].str.contains(f"van_{van}")]
plt.figure(figsize=(12, 6))
sns.lineplot(data=van_features_df, x="Time (ps)", y="occupancy", hue="ensemble")
plt.title(f"Water Occupancy for {cmp}")
plt.xlabel("Time (ps)")
plt.ylabel("Number of Waters")
plt.xlim(0, 20000)
plt.legend(title="Ensemble", bbox_to_anchor=(1.05, 1), loc="upper left", ncol=2)
plt.tight_layout()
plt.savefig(os.path.join(cmp_output_dir, f"{cmp}_water_occupancy_van{van}.png"))

```

```python
# Extract vanilla replicate and window ID
features_df["van"] = features_df["ensemble"].str.extract(r"van_(\d)")
features_df["id"] = features_df["ensemble"].str.replace(r"_van_\d+", "", regex=True)

# Compute average occupancy
avg_df = features_df.groupby(["id", "van"], as_index=False)["occupancy"].mean()
avg_df.to_csv(os.path.join(cmp_output_dir, "avg_water_occupancy.csv"), index=False)

# Plot average occupancy
plt.figure(figsize=(12, 8))
sns.lineplot(data=avg_df, x="id", y="occupancy", hue="van", palette="tab10")
plt.title(f"Average Water Occupancy Across Windows for {cmp}", fontsize=16, fontweight="bold")
plt.xlabel("Window ID", fontsize=14)
plt.ylabel("Average Number of Waters", fontsize=14)
plt.legend(title="Vanilla Repeat", title_fontsize=12, fontsize=10, loc="upper right")
plt.xticks(rotation=45, fontsize=10)
plt.yticks(fontsize=10)
plt.tight_layout()
plt.savefig(os.path.join(cmp_output_dir, f"{cmp}_water_occupancy_across_windows.png"), dpi=300)
plt.close()

```
2 changes: 1 addition & 1 deletion docs/how-to-guides/guide-2.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
icon: lucide/compass
title: How-to-Guide
title: Side Chain Torsion Analysis
---

Put the example analysis in the how to guide section here
82 changes: 0 additions & 82 deletions fepa/data/template_steus_weight_sampling.mdp

This file was deleted.

5 changes: 0 additions & 5 deletions fepa/flows/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,6 @@
memento_workflow,
)

from .steus_flows import (
steus_weight_sampling_workflow,
steus_umbrella_sampling_workflow,
)

from .torsions_flow import (
torsions_analysis_workflow,
)
Loading
Loading