|
| 1 | +# For Developers: Modifying AlphaQuant |
| 2 | + |
| 3 | +AlphaQuant is designed with modularity in mind to allow practitioners to introduce alternative numerical methods for each module. The codebase follows clear interfaces that make it straightforward to extend or replace statistical methods at different levels of the analysis pipeline. |
| 4 | + |
| 5 | +## ⚠️ Important: Benchmarking and Validation |
| 6 | + |
| 7 | +**Any changes to statistical methods should be thoroughly benchmarked and fine-tuned before use in production analyses.** The default methods in AlphaQuant have been extensively tested and validated on diverse proteomics datasets. When implementing alternative approaches, ensure you carry out appropriate benchmarking using ground truth datasets (e.g., spike-in experiments, mixed-species samples) and evaluate key performance metrics (sensitivity, specificity, false discovery rates, reproducibility). |
| 8 | + |
| 9 | + |
| 10 | +## 1. Ion-Level Statistical Testing |
| 11 | + |
| 12 | +**Where to modify:** `alphaquant/diffquant/diff_analysis.py` |
| 13 | + |
| 14 | +**How it works:** Each ion (fragment, peptide, etc.) is tested independently for differential expression. The test produces three key outputs: `p_val` (p-value), `fc` (log2 fold change), and `z_val` (z-score for aggregation). |
| 15 | + |
| 16 | +**Main class:** |
| 17 | +- **`DifferentialIon`** - The default method that uses intensity-dependent empirical background distributions to compute p-values and z-scores. It accounts for technical variation by comparing observed fold changes against distributions derived from similarly abundant ions in the dataset. The core statistical logic is in the `_calc_diffreg_peptide()` method. |
| 18 | + |
| 19 | +**How to extend:** We've included `DifferentialIonTTest` in the same file as example code demonstrating how to implement alternative tests. This variant uses Welch's t-test with robust variance estimation. Note that this example has not been extensively benchmarked and is included for educational purposes to demonstrate the interface. |
| 20 | + |
| 21 | +1. Create a new class (e.g., `DifferentialIonMyMethod`) with the same interface: |
| 22 | + - `__init__()` should accept `(noNanvals_from, noNanvals_to, ...)` and any method-specific parameters |
| 23 | + - Set attributes: `name`, `p_val`, `fc`, `z_val`, `usable` |
| 24 | +2. Implement your statistical test in a method (e.g., `_calc_mymethod()`) |
| 25 | +3. Modify `alphaquant/diffquant/condpair_analysis.py` (lines 67-70) to instantiate your class |
| 26 | +4. Optionally, add a parameter to `run_pipeline()` to select between methods |
| 27 | + |
| 28 | +The key requirement is that your class must output `p_val`, `fc`, and `z_val` for each ion—these are used by the tree aggregation framework. |
| 29 | + |
| 30 | +## 2. Tree-Based Ion Propagation |
| 31 | + |
| 32 | +**Where to modify:** `alphaquant/cluster/cluster_utils.py` and `alphaquant/cluster/cluster_ions.py` |
| 33 | + |
| 34 | +**How it works:** Statistics from child nodes (e.g., fragments) are aggregated to parent nodes (e.g., peptides → proteins) in a hierarchical tree. Z-values are combined using Stouffer's method, and fold changes are summarized using medians. |
| 35 | + |
| 36 | +**Key functions:** |
| 37 | +- **`aggregate_node_properties()`** - The core function that propagates statistics up the tree. It combines z-values, fold changes, and quality metrics from children to parents. |
| 38 | +- **`sum_and_re_scale_zvalues()`** - Implements Stouffer's Z-score method: sums z-values and divides by sqrt(n), then rescales to maintain standard normal distribution. |
| 39 | +- **`transform_znormed_to_pval()`** - Converts aggregated z-scores back to two-sided p-values. |
| 40 | + |
| 41 | +**How to extend:** If you want to use different aggregation methods: |
| 42 | +1. Modify `sum_and_re_scale_zvalues()` to implement your preferred meta-analysis method (e.g., Fisher's method, weighted Z-scores, etc.) |
| 43 | +2. If your method changes the distribution, update `transform_znormed_to_pval()` accordingly |
| 44 | +3. For fold-change aggregation, modify line 67 in `aggregate_node_properties()` where `node.fc = np.median(fcs)` is set |
| 45 | + |
| 46 | +The tree traversal itself is in `cluster_ions.py`: |
| 47 | +- **`cluster_along_specified_levels()`** - Iterates through tree levels bottom-to-top |
| 48 | +- **`get_scored_clusterselected_ions()`** - Entry point for the hierarchical workflow |
| 49 | + |
| 50 | +## 3. Multiple Testing Correction |
| 51 | + |
| 52 | +**Where to modify:** `alphaquant/tables/diffquant_table.py` and `alphaquant/tables/proteoformtable.py` |
| 53 | + |
| 54 | +**How it works:** FDR correction is applied separately to different result tables during output generation. The method outputs p-values in all tables, so you can always recalculate q-values from the output files. |
| 55 | + |
| 56 | +**Key functions:** |
| 57 | +- **Protein results** (`alphaquant/tables/diffquant_table.py`): |
| 58 | + - `_add_fdr_fc_based_set()` - Applies Benjamini-Hochberg to intensity-based proteins |
| 59 | + - `_add_fdr_counting_based_set()` - Applies adjusted Benjamini-Hochberg to proteins detected only via missing values |
| 60 | + |
| 61 | +- **Proteoform results** (`alphaquant/tables/proteoformtable.py`): |
| 62 | + - `_annotate_fdr_column()` - Applies Benjamini-Hochberg to test if alternative proteoforms differ from the reference |
| 63 | + |
| 64 | +**How to extend:** |
| 65 | +1. Modify the relevant function to use a different method (e.g., Bonferroni, Storey's q-value, etc.) |
| 66 | +2. Replace the `mt.multipletests(..., method='fdr_bh', ...)` call with your preferred correction |
| 67 | +3. Alternatively, use the p-values from output tables and apply your own correction externally |
| 68 | + |
| 69 | +## 4. Outlier Robustness |
| 70 | + |
| 71 | +**Where to modify:** `alphaquant/diffquant/diff_analysis.py` and `alphaquant/cluster/cluster_utils.py` |
| 72 | + |
| 73 | +**How it works:** AlphaQuant applies outlier correction at two levels to make results robust to technical variation and biological heterogeneity. |
| 74 | + |
| 75 | +**Key functions:** |
| 76 | +- **`calc_outlier_scaling_factor()`** (in `diff_analysis.py`) - Compares between-replicate variance to expected technical variance and inflates estimates when replicates show unusual variability |
| 77 | +- **`remove_outlier_fragion_childs()`** (in `cluster_utils.py`) - Filters extreme fragments before aggregating to peptides (keeps the 5 most central fragments when >4 are available) |
| 78 | + |
| 79 | +**How to extend:** |
| 80 | +1. Modify the scaling logic in `calc_outlier_scaling_factor()` to use different robust estimators |
| 81 | +2. Adjust `remove_outlier_fragion_childs()` to change how many fragments are retained or which criteria are used for selection |
| 82 | +3. Set `outlier_correction=False` in `run_pipeline()` to disable this feature entirely |
| 83 | + |
| 84 | +## 5. Main Workflow Orchestration |
| 85 | + |
| 86 | +**Where to modify:** `alphaquant/diffquant/condpair_analysis.py` |
| 87 | + |
| 88 | +**How it works:** The `analyze_condpair()` function coordinates the complete pipeline for comparing two conditions. |
| 89 | + |
| 90 | +**Pipeline steps:** |
| 91 | +1. Load and filter data for the two conditions |
| 92 | +2. Perform normalization (within and between conditions) |
| 93 | +3. Create empirical background distributions |
| 94 | +4. Compute ion-level differential statistics (`DifferentialIon` or `DifferentialIonTTest`) |
| 95 | +5. Build hierarchical trees and perform clustering to identify proteoforms |
| 96 | +6. Apply machine learning quality scoring (if enabled) |
| 97 | +7. Filter outlier peptides (if enabled) |
| 98 | +8. Generate output tables with FDR correction |
| 99 | +9. Create visualization plots |
| 100 | + |
| 101 | +**How to extend:** This file shows how all components connect. To add custom preprocessing, normalization, or post-processing steps, modify this function or create a wrapper that calls it with modified data. |
| 102 | + |
| 103 | +--- |
| 104 | + |
| 105 | +## Additional Resources |
| 106 | + |
| 107 | +For general contribution guidelines, code style, and how to submit pull requests, please see [CONTRIBUTING.md](CONTRIBUTING.md). |
| 108 | + |
| 109 | +For questions or discussions about extending AlphaQuant, please use the [GitHub Discussions](https://github.com/MannLabs/alphaquant/discussions) forum. |
| 110 | + |
0 commit comments