Metadata-Version: 2.3
Name: pyphers
Version: 0.1.0
Summary: cli tool to generate PheRS scores for a cohort of interest
Author: J.T. Baker
Author-email: J.T. Baker <james.baker@vanderbilt.edu>
Requires-Dist: numpy>=2.2.6
Requires-Dist: polars>=2.0.0
Requires-Dist: rich-argparse>=1.6.0
Requires-Python: >=3.10
Description-Content-Type: text/markdown

# PyPheRS (Phenome Risk Score)

A high-performance Python package and CLI tool for calculating Phenome Risk Scores (PheRS) for clinical and genomic cohorts.

PyPheRS calculates an individual's aggregate risk as a linear combination of effect sizes (betas) derived from Phenome-Wide Association Studies (PheWAS):

$$\text{PheRS}_i = \sum_{j \in \mathcal{P}_i} \beta_j \cdot X_{ij}$$

where:
* $\beta_j$ is the PheWAS effect size (beta / log-odds ratio) for phecode $j$.
* $X_{ij}$ is individual $i$'s phenotype feature value for phecode $j$ (binary presence, raw count, or log-transformed count).
* Participants in the cohort who have no recorded matching phecodes receive a score of `0.0`.

---

## Installation

Install from [PyPI](https://pypi.org/project/pyphers/):

```bash
pip install pyphers
```

### Development Installation
To contribute or run tests locally from source:

```bash
git clone https://github.com/j-t-baker/pyphers.git
cd pyphers
uv sync --group dev
```

---

## Usage

### 1. Command-Line Interface (CLI)

Run `pyphers --help` to view all available options:

```bash
pyphers --help
```

#### Basic Example
Calculate binary PheRS scores from phenotypes and weights:

```bash
pyphers \
  --phenotypes data/phenotypes.txt \
  --weights data/weights.txt \
  --output results/phers_scores.txt
```

#### Advanced Options
```bash
pyphers \
  --phenotypes data/phenotypes.csv \
  --weights data/weights.txt.gz \
  --cohort data/cohort_ids.txt \
  --mode count \
  --p-val-threshold 0.05 \
  --output results/phers_scores.txt
```

#### CLI Options
* **Input & Output**:
  * `-p, --phenotypes`: Path to participant phenotype records.
  * `-w, --weights`: Path to PheWAS summary statistics file.
  * `-o, --output`: Path to write calculated PheRS scores.
  * `-c, --cohort`: Optional path to list of all cohort participant IDs to ensure completeness.
* **Scoring Options**:
  * `-m, --mode`: Weighting scheme: `binary` (default), `count`, or `log_count`.
  * `--p-val-threshold`: Exclude weights with p-values exceeding this threshold.
* **Column Mapping**:
  * `--id-col`: Participant ID column name (default: `person_id`).
  * `--phecode-col`: Phecode column name in phenotypes (default: `phecode`).
  * `--weights-phecode-col`: Phecode column name in weights (defaults to `--phecode-col`).
  * `--beta-col`: Effect size column name in weights (default: `beta`).
  * `--pval-col`: P-value column name in weights (default: `p_val`).
  * `--count-col`: Optional column name for pre-aggregated counts in phenotypes.

---

### 2. Python API

You can import `calculate_phers` directly into your Python scripts:

```python
import polars as pl
from pyphers import calculate_phers

# Calculate PheRS directly from file paths or Polars DataFrames/LazyFrames
df_scores = calculate_phers(
    phenotypes="data/phenotypes.txt",
    weights="data/weights.txt",
    cohort="data/cohort.txt",  # or list of IDs: ["P1", "P2", "P3"]
    mode="binary",             # "binary" | "count" | "log_count"
    p_val_threshold=0.05,
    id_col="person_id",
    phecode_col="phecode",
    beta_col="beta",
    pval_col="p_val",
)

# Output is a Polars DataFrame with columns: ['person_id', 'phers']
print(df_scores)
```

---

## Testing

Run unit and integration tests with `pytest`:

```bash
uv run pytest
```

Run tests across multiple Python versions (3.10–3.15) with `nox`:

```bash
uv run nox
```
