Metadata-Version: 2.4
Name: maxlfq
Version: 0.1.0
Summary: Readable NumPy/SciPy implementation of the MaxLFQ workflow
License-Expression: Artistic-2.0
Project-URL: Repository, https://github.com/animesh/maxlfq
Project-URL: Issues, https://github.com/animesh/maxlfq/issues
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.23
Requires-Dist: pandas>=1.5
Requires-Dist: scipy>=1.9
Dynamic: license-file

# maxLFQ

A importable NumPy/SciPy implementation of the [notebook-derived MaxLFQ workflow](https://fuzzylife.substack.com/p/maxlfq) for MaxQuant peptide tables. The package extracts the computational workflow from [`maxLFQmo.py`](https://raw.githubusercontent.com/animesh/scripts/refs/heads/master/maxLFQmo.py). The notebook works as an interactive teaching and visualization [wasm](https://molab.marimo.io/github/animesh/scripts/blob/master/maxLFQmo.py/wasm) interface, while this module provides a reusable, testable API and command-line interface.

The package performs:

1. peptide-species construction from sequence, modification, and charge;
2. optional decoy, contaminant, and uniqueness filtering;
3. delayed sample normalization;
4. protein-wise pairwise peptide log-ratios;
5. least-squares protein-profile reconstruction;
6. rescaling to observed peptide intensity anchors.

This is an independent Python implementation intended for transparent analysis and teaching. It is not an [official MaxLFQ](https://pmc.ncbi.nlm.nih.gov/articles/PMC4159666/) implementation.

## Installation

```bash
python -m pip install maxlfq
```

## Small reproducible example

```python
import pandas as pd
from maxlfq import maxlfq

peptides = pd.DataFrame(
    {
        "Leading razor protein": ["P1", "P1", "P2", "P2"],
        "Sequence": ["AAA", "BBB", "CCC", "DDD"],
        "Modifications": ["Unmodified"] * 4,
        "Charge": [2, 2, 3, 2],
        "Intensity A": [100, 200, 50, 150],
        "Intensity B": [200, 400, 100, 300],
        "Intensity C": [50, 100, 25, 75],
    }
)

result = maxlfq(peptides)

print(result.normalization_factors)
print(result.lfq)
```

Expected normalization factors:

```text
A    0.50
B    0.25
C    1.00
```

Expected LFQ values:

```text
         LFQ intensity A  LFQ intensity B  LFQ intensity C
Protein
P1                 150.0            150.0            150.0
P2                 100.0            100.0            100.0
```


For local development:

```bash
python -m pip install -e .
#check
python -c "import pandas as pd; from maxlfq import maxlfq; x=pd.DataFrame({'Leading razor protein':['P1','P1','P2','P2'],'Sequence':['AAA','BBB','CCC','DDD'],'Modifications':['Unmodified']*4,'Charge':[2,2,3,2],'Intensity A':[100,200,50,150],'Intensity B':[200,400,100,300],'Intensity C':[50,100,25,75]}); r=maxlfq(x); print(r.normalization_factors); print(r.lfq)"
A    0.50
B    0.25
C    1.00
Name: normalization_factor, dtype: float64
         LFQ intensity A  LFQ intensity B  LFQ intensity C
Protein
P1                 150.0            150.0            150.0
P2                 100.0            100.0            100.0
```

## Python API

```python
from maxlfq import maxlfq_from_file

result = maxlfq_from_file(
    "peptides.txt",
    ratio_method="median",
    rescale_method="sum",
    minimum_ratio_count=1,
    normalization_anchor="All Samples Maximum",
    filter_decoy=True,
    filter_contaminant=True,
)

result.lfq.to_csv("protein_lfq.tsv", sep="\t")
result.normalization_factors.to_csv("normalization_factors.tsv", sep="\t")
result.pairwise_ratios.to_csv("pairwise_ratios.tsv", sep="\t", index=False)
```

The main result object contains:

- `lfq`: reconstructed protein LFQ matrix;
- `raw_intensity`: protein-wise sums before delayed normalization;
- `normalization_factors`: fitted sample factors;
- `normalized_species`: normalized peptide-species matrix;
- `pairwise_ratios`: protein/sample-pair ratio trace;
- `zero_intensity_proteins`: proteins excluded because all intensities were zero or missing;
- `h_before` and `h_after`: delayed-normalization objectives.

## Command line

```bash
maxlfq peptides.txt protein_lfq.tsv \
  --filter-decoy \
  --filter-contaminant \
  --normalization-factors-output normalization_factors.tsv \
  --pairwise-ratios-output pairwise_ratios.tsv
```

The same command can be run without the installed entry point:

```bash
python -m maxlfq peptides.txt protein_lfq.tsv
```

## Input expectations

By default, the package detects common MaxQuant columns:

```text
Protein:       Leading razor protein, Razor protein, Proteins, or Protein IDs
Sequence:      Sequence, Peptide sequence, or Peptide
Modification:  first column starting with Mod
Charge:        Charge, Charges, or z
Intensity:     columns starting with "Intensity "
```

Zero intensities are interpreted as missing. Nonnumeric and infinite intensity values are converted to missing values.

A peptide species is defined as:

```text
UPPERCASE_SEQUENCE + modification + charge
```

For repeated rows with the same protein/species identifier, the first observed intensity row is retained, matching the original notebook.

## Main parameters

```python
result = maxlfq_from_file(
    "peptides.txt",
    delayed_normalize=True,
    normalization_anchor="All Samples Maximum",
    profile_anchor=None,
    ratio_method="median",
    rescale_method="sum",
    minimum_ratio_count=1,
    filter_decoy=False,
    filter_contaminant=False,
    filter_unique_groups=False,
    filter_unique_proteins=False,
    include_zero_intensity=False,
)
```

`profile_anchor=None` means that profile reconstruction uses the delayed-normalization anchor.

## Delayed normalization

For peptide species `p` and samples `i` and `j`, sample factors are fitted by minimizing:

```text
sum [log(N_i X_p,i) - log(N_j X_p,j)]^2
```

The factors are identifiable only up to one common multiplier. The selected anchor sets that common scale.

## Pairwise ratios

For each protein and sample pair, the package computes the median or mean log2 ratio across shared peptide species:

```text
r_ij = median_p[log2(I_p,i) - log2(I_p,j)]
```

Pairs with fewer than `minimum_ratio_count` shared species are omitted.

## Profile reconstruction

Protein-level relative profiles are reconstructed by least squares from:

```text
log2(I_i) - log2(I_j) = r_ij
```

The relative profile is then rescaled using either summed or maximum observed normalized peptide-species intensity.

## Validation status

The package was checked for:

- source compilation;
- species-matrix construction;
- zero-intensity protein restoration;
- delayed-normalization factors on a known scaling example;
- reduction of the normalization objective;
- pairwise median-ratio construction;
- protein-profile reconstruction;
- API and command-line execution;
- clean wheel contents and installation.

## Reference

Cox J, Hein MY, Luber CA, Paron I, Nagaraj N, Mann M. Accurate proteome-wide label-free quantification by delayed normalization and maximal peptide ratio extraction, termed MaxLFQ. Molecular & Cellular Proteomics. 2014;13(9):2513-2526.

## Citation and attribution

The original MaxLFQ publication above, the [repo](https://github.com/animesh/vsn) and document the [Python package version](https://pypi.org/project/vsn/) used. This project is an independent Python implementation and is not the Bioconductor `vsn` package.
