Skip to content

Commit 2c8eca3

Browse files
committed
Initial commit of Catalytix: Enzyme Kinetics Fitter
0 parents  commit 2c8eca3

10 files changed

Lines changed: 607 additions & 0 deletions

File tree

.github/workflows/test.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: Run Tests
2+
3+
on: [push, pull_request]
4+
5+
jobs:
6+
test:
7+
runs-on: ubuntu-latest
8+
steps:
9+
- uses: actions/checkout@v3
10+
- name: Set up Python
11+
uses: actions/setup-python@v4
12+
with:
13+
python-version: '3.9'
14+
- name: Install dependencies
15+
run: |
16+
python -m pip install --upgrade pip
17+
pip install -r requirements.txt
18+
- name: Run tests
19+
run: |
20+
pytest

.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
venv/
2+
__pycache__/
3+
*.pyc
4+
.pytest_cache/
5+
.coverage
6+
htmlcov/
7+
dist/
8+
build/
9+
*.egg-info/

README.md

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# Catalytix: Precision Enzyme Kinetics
2+
3+
![License](https://img.shields.io/badge/license-MIT-blue.svg)
4+
![Python](https://img.shields.io/badge/python-3.8%2B-blue)
5+
![Status](https://img.shields.io/badge/status-stable-green)
6+
7+
**Catalytix** is a robust computational biology tool designed to model and analyze enzyme kinetics data. It leverages non-linear least squares regression to fit experimental data to the **Michaelis–Menten** equation, providing precise estimates for $V_{max}$ and $K_m$.
8+
9+
Whether you are a researcher, student, or bioinformatician, Catalytix offers both a command-line interface for batch processing and a modern web interface for interactive exploration.
10+
11+
---
12+
13+
## 🔬 The Science
14+
15+
This tool is built upon the foundational principles of enzyme kinetics established by **Leonor Michaelis** and **Maud Menten** in their seminal 1913 paper, *"Die Kinetik der Invertinwirkung"*.
16+
17+
The model describes the rate of enzymatic reactions ($v$) as a function of substrate concentration ($[S]$):
18+
19+
$$ v = \frac{V_{max} [S]}{K_m + [S]} $$
20+
21+
Where:
22+
- **$V_{max}$**: The maximum reaction velocity achieved at saturating substrate concentrations.
23+
- **$K_m$** (Michaelis constant): The substrate concentration at which the reaction rate is half of $V_{max}$. This is often used as a measure of the enzyme's affinity for its substrate.
24+
25+
Catalytix automates the determination of these critical parameters, replacing error-prone manual linearization methods (like Lineweaver-Burk plots) with direct non-linear regression.
26+
27+
---
28+
29+
## 📊 Visual Output
30+
31+
Catalytix generates high-quality plots showing the experimental data overlaid with the fitted curve, along with a residual plot to assess the goodness of fit.
32+
33+
![Enzyme Kinetics Fit](assets/kinetics_fit.png)
34+
35+
*Figure 1: Example output showing the Michaelis-Menten curve fit (top) and residuals (bottom).*
36+
37+
---
38+
39+
## 🚀 Features
40+
41+
- **Dual Interface**:
42+
- **CLI**: Efficient for scripting and pipelines.
43+
- **Web App**: Interactive Streamlit dashboard for instant visualization.
44+
- **Statistical Rigor**: Calculates standard deviations for parameters and $R^2$ values.
45+
- **Data Agnostic**: Auto-detects numeric columns in your CSV files.
46+
- **Publication Ready**: Exports high-DPI plots suitable for reports and papers.
47+
48+
---
49+
50+
## 🛠️ Installation
51+
52+
### Prerequisites
53+
- Python 3.8 or higher
54+
55+
### Quick Start
56+
Clone the repository and install the dependencies:
57+
58+
```bash
59+
git clone https://github.com/yourusername/catalytix.git
60+
cd catalytix
61+
pip install -r requirements.txt
62+
```
63+
64+
---
65+
66+
## 💻 Usage
67+
68+
### 1. Interactive Web App (Recommended)
69+
Launch the dashboard to upload data and visualize fits instantly:
70+
71+
```bash
72+
streamlit run app.py
73+
```
74+
75+
### 2. Command Line Interface
76+
Run the analysis directly on your data files:
77+
78+
```bash
79+
python enzyme_kinetics_fitter.py --input data.csv --output-plot my_results.png
80+
```
81+
82+
**Arguments:**
83+
- `--input`: Path to your CSV file.
84+
- `--substrate-col`: (Optional) Name of the substrate column.
85+
- `--velocity-col`: (Optional) Name of the velocity column.
86+
- `--output-json`: (Optional) Save parameters to a JSON file.
87+
88+
---
89+
90+
## 📂 Input Data Format
91+
Your CSV file should look like this:
92+
93+
| Substrate_mM | Rate_uM_s |
94+
|--------------|-----------|
95+
| 0.1 | 0.05 |
96+
| 0.2 | 0.09 |
97+
| ... | ... |
98+
99+
---
100+
101+
## 🤝 Contributing
102+
Contributions are welcome! Please feel free to submit a Pull Request.
103+
104+
## 📜 License
105+
This project is licensed under the MIT License.

app.py

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import streamlit as st
2+
import pandas as pd
3+
import numpy as np
4+
import matplotlib.pyplot as plt
5+
from enzyme_kinetics_fitter import fit_michaelis_menten, michaelis_menten
6+
7+
st.set_page_config(page_title="Catalytix: Enzyme Kinetics", page_icon="🧪")
8+
9+
st.title("🧪 Catalytix")
10+
st.markdown("""
11+
This tool fits **Michaelis–Menten** enzyme kinetics data.
12+
Upload a CSV file with substrate concentration $[S]$ and initial velocity $v$.
13+
""")
14+
15+
# Sidebar for inputs
16+
st.sidebar.header("Upload Data")
17+
uploaded_file = st.sidebar.file_uploader("Choose a CSV file", type="csv")
18+
19+
if uploaded_file is not None:
20+
try:
21+
df = pd.read_csv(uploaded_file)
22+
st.write("### Data Preview")
23+
st.dataframe(df.head())
24+
25+
# Column selection
26+
numeric_cols = df.select_dtypes(include=[np.number]).columns.tolist()
27+
28+
if len(numeric_cols) < 2:
29+
st.error("CSV must contain at least two numeric columns.")
30+
else:
31+
st.sidebar.header("Select Columns")
32+
s_col = st.sidebar.selectbox("Substrate Concentration ([S])", numeric_cols, index=0)
33+
v_col = st.sidebar.selectbox("Velocity (v)", numeric_cols, index=1)
34+
35+
if st.sidebar.button("Fit Model"):
36+
S = df[s_col].to_numpy(dtype=float)
37+
v = df[v_col].to_numpy(dtype=float)
38+
39+
try:
40+
fit = fit_michaelis_menten(S, v)
41+
42+
# Display Results
43+
st.success("Fitting successful!")
44+
45+
col1, col2, col3 = st.columns(3)
46+
col1.metric("Vmax", f"{fit.Vmax:.4g}", delta_color="off")
47+
col2.metric("Km", f"{fit.Km:.4g}", delta_color="off")
48+
if fit.r_squared is not None:
49+
col3.metric("R²", f"{fit.r_squared:.4f}", delta_color="off")
50+
51+
# Detailed stats
52+
with st.expander("See detailed statistics"):
53+
st.write(f"**Vmax Std Dev:** {fit.Vmax_std:.4g}" if fit.Vmax_std else "Vmax Std Dev: N/A")
54+
st.write(f"**Km Std Dev:** {fit.Km_std:.4g}" if fit.Km_std else "Km Std Dev: N/A")
55+
56+
# Plotting
57+
st.write("### Fitted Curve")
58+
59+
# Generate plot data
60+
S_range = np.linspace(0, S.max() * 1.1, 200)
61+
v_fit_curve = michaelis_menten(S_range, fit.Vmax, fit.Km)
62+
63+
fig, ax = plt.subplots(figsize=(8, 5))
64+
ax.scatter(S, v, label="Experimental Data", color="black", zorder=5)
65+
ax.plot(S_range, v_fit_curve, label=f"Fit (Vmax={fit.Vmax:.2f}, Km={fit.Km:.2f})", color="red", linewidth=2)
66+
67+
ax.set_xlabel(s_col)
68+
ax.set_ylabel(v_col)
69+
ax.set_title("Michaelis–Menten Fit")
70+
ax.legend()
71+
ax.grid(True, linestyle="--", alpha=0.5)
72+
73+
st.pyplot(fig)
74+
75+
# Residuals
76+
st.write("### Residuals")
77+
v_pred = michaelis_menten(S, fit.Vmax, fit.Km)
78+
residuals = v - v_pred
79+
80+
fig_res, ax_res = plt.subplots(figsize=(8, 3))
81+
ax_res.axhline(0, linestyle="--", color="gray")
82+
ax_res.scatter(S, residuals, color="blue")
83+
ax_res.set_xlabel(s_col)
84+
ax_res.set_ylabel("Residuals")
85+
ax_res.grid(True, linestyle="--", alpha=0.5)
86+
87+
st.pyplot(fig_res)
88+
89+
except Exception as e:
90+
st.error(f"Fitting failed: {e}")
91+
92+
except Exception as e:
93+
st.error(f"Error reading file: {e}")
94+
else:
95+
st.info("Please upload a CSV file to get started.")
96+
97+
# Example data button
98+
if st.button("Load Example Data"):
99+
# Create a dummy dataframe for demonstration
100+
data = {
101+
"Substrate_mM": [0.1, 0.2, 0.5, 1.0, 2.0, 5.0, 10.0],
102+
"Rate_uM_s": [0.05, 0.09, 0.22, 0.38, 0.60, 0.88, 1.05]
103+
}
104+
df_example = pd.DataFrame(data)
105+
csv = df_example.to_csv(index=False).encode('utf-8')
106+
107+
st.download_button(
108+
label="Download Example CSV",
109+
data=csv,
110+
file_name="example_kinetics_data.csv",
111+
mime="text/csv",
112+
)

assets/kinetics_fit.png

175 KB
Loading

0 commit comments

Comments
 (0)