Repository navigation
Add Logistic PCA (LPCA) analysis #500
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Jeebjean
wants to merge
29
commits into
Reed-CompBio:main
Choose a base branch
from
Jeebjean:lpca-integration
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
29 commits
Select commit
Hold shift + click to select a range
1e9b218
Add Logistic PCA (LPCA) analysis
Jeebjean bb338a8
Add LPCA Docker wrapper
Jeebjean efd1005
Add unit tests for LPCA analysis
Jeebjean 8f89119
Add LPCA visualization: generate lpca.png and lpca-coordinates.txt
Jeebjean 3d9a38f
Increase Docker timeout to 600s for large LPCA matrices
Jeebjean e4b4679
Restore config.yaml to main defaults, keep only lpca block
Jeebjean 41b64b7
Skip LPCA tests if Docker image not available
Jeebjean c49362f
Add rARPACK for memory-efficient LPCA with partial_decomp=TRUE
Jeebjean 7536d8c
Address PR review: palette, CV check, KDE note, config docs, rename t…
Jeebjean 63d941d
Remove transpose option, fix m doc, update README, rename party variable
Jeebjean a44bb50
Restore deleted comments in config.yaml
Jeebjean 58ceac3
Pass summarize_networks output to run_lpca, matching PCA convention
Jeebjean 33f0435
Move binary matrix to Snakefile output, pass path to run_lpca
Jeebjean 90b5094
Update tests: remove skipif, use summarize_networks, remove transpose
Jeebjean 20ff901
Add lpca_analysis_all rule for cross-algorithm LPCA
Jeebjean a16ba19
Add dedicated LPCA test inputs and stronger tests
Jeebjean b063bbd
Add LPCA to Docker image build CI workflow
Jeebjean b1905c0
Fix test input files: use tab-separated format
Jeebjean ec14dc8
Add lpca aggregate_per_algorithm option and per-algorithm rule; enabl…
Jeebjean 1704c47
Set lpca include back to false after confirming CI run
Jeebjean 5b64162
Add stronger LPCA test comparing scores to known outputs (sign-robust)
Jeebjean 2ced8af
Add robustness to LPCA R wrapper and test code
agitter e1c0be2
Refactor LPCA wrapper and tests
agitter e2c91d2
Add tests, refactor config and Snakefile
agitter 2d7d91c
Formatting and doc cleanup
agitter 894643d
Config whitespace
agitter f2a24f4
Update comments
agitter 415c799
Memory discussions
agitter 7100ada
Disable LPCA by default
agitter File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| # Logistic PCA (logisticPCA) wrapper for SPRAS. | ||
| # The caller supplies Rscript /app/run_lpca.R and its arguments. | ||
| # Cross-validation is not supported, and no ENTRYPOINT is set. | ||
|
|
||
| # Pinned R version for reproducibility. Bump deliberately, not to :latest. | ||
| FROM rocker/r-base:4.4.2 | ||
|
|
||
| LABEL org.opencontainers.image.source="https://github.com/Reed-CompBio/spras" | ||
| LABEL org.opencontainers.image.description="Logistic PCA (logisticPCA) wrapper for SPRAS" | ||
|
|
||
| # System libraries needed to compile ggplot2 (a hard Import of logisticPCA) | ||
| # and its dependency stack from source on Debian. | ||
| RUN apt-get update && apt-get install -y --no-install-recommends \ | ||
| libcurl4-openssl-dev \ | ||
| libssl-dev \ | ||
| libxml2-dev \ | ||
| libfontconfig1-dev \ | ||
| libfreetype6-dev \ | ||
| libpng-dev \ | ||
| libtiff5-dev \ | ||
| libjpeg-dev \ | ||
| && rm -rf /var/lib/apt/lists/* | ||
|
|
||
| # Install tested versions of required R packages including rARPACK's RSpectra backend. | ||
| # remotes finds these versions in CRAN or its archive. | ||
| # Install only required dependencies and do not upgrade previously installed ones. | ||
| # Transitive and system dependencies are not fully pinned by this Dockerfile. | ||
| RUN Rscript -e "options(repos = c(CRAN = 'https://cran.r-project.org')); \ | ||
| install.packages('remotes'); \ | ||
| versions <- c(RSpectra = '0.16-2', rARPACK = '0.11-0', logisticPCA = '0.2'); \ | ||
| for (pkg in names(versions)) { \ | ||
| remotes::install_version(pkg, version = versions[[pkg]], \ | ||
| dependencies = NA, upgrade = 'never'); \ | ||
| stopifnot(packageVersion(pkg) == package_version(versions[[pkg]])); \ | ||
| }; \ | ||
| library(logisticPCA); library(rARPACK); library(RSpectra)" | ||
|
|
||
| COPY run_lpca.R /app/run_lpca.R | ||
|
|
||
| WORKDIR /app |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,99 @@ | ||
| # LPCA (Logistic PCA) wrapper | ||
|
|
||
|
Jeebjean marked this conversation as resolved.
|
||
| Docker image: https://hub.docker.com/r/reedcompbio/lpca | ||
|
|
||
| This wrapper uses [logisticPCA](https://github.com/andland/logisticPCA) | ||
| ([Landgraf & Lee, 2020](https://doi.org/10.1016/j.jmva.2020.104668)) for an | ||
| exploratory, two-dimensional comparison of reconstructed networks. It calls | ||
| `logisticPCA`, not `logisticSVD`. It supports only `k = 2` components and a fixed, | ||
| finite, strictly positive `m`. Cross-validation for automatic selection of `m` | ||
| and modifying `k` are not supported. | ||
|
|
||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Extra linebreak here |
||
| ## Container interface | ||
|
|
||
| The image contains one R script, invoked explicitly by the caller: | ||
|
|
||
| ```text | ||
| Rscript /app/run_lpca.R <input.csv> <scores.csv> <k=2> <m> <deviance.txt> | ||
| ``` | ||
|
|
||
| ### Input | ||
|
|
||
| The CSV has a header row, a first column of nonempty, unique run identifiers, | ||
| and one column per binary edge feature. Rows are runs, not edges. The caller | ||
| must transpose the edge-by-run matrix returned by `summarize_networks` before | ||
| writing it. | ||
|
|
||
| This wrapper deliberately requires at least three runs, three edge features, | ||
| and three distinct binary network profiles. All feature values must be finite | ||
| numeric zeros or ones. Missing, nonnumeric, and nonbinary entries are errors. | ||
| Duplicate profiles and constant features are | ||
| retained when the input otherwise satisfies these requirements. | ||
|
|
||
| `k` must equal 2. `m` must be finite and strictly positive. | ||
|
|
||
| The default `m=6` is based on the exploratory | ||
| [LPCA-SPRAS experiments](https://github.com/Jeebjean/lpca-spras). | ||
| No single value of `m` was universally best. | ||
|
|
||
| ### Outputs and numerical checks | ||
|
|
||
| The raw scores CSV contains `datapoint_labels`, `PC1`, and `PC2`, with one row | ||
| per input run and no synthetic centroid. It is an intermediate for Python's | ||
| PCA-compatible plotting and coordinate formatting, not a second public | ||
| coordinate table. | ||
|
|
||
| The deviance summary is a small text file: | ||
|
|
||
| ```text | ||
| components: 2 | ||
| m: <fixed positive value> | ||
| percent_deviance_explained: <100 times the package's whole-model statistic> | ||
| ``` | ||
|
|
||
| ## SPRAS configuration | ||
|
|
||
| The `analysis.lpca` config settings are: | ||
|
|
||
| ```yaml | ||
| analysis: | ||
| lpca: | ||
| include: false | ||
| aggregate_per_algorithm: false | ||
| k: 2 | ||
| m: 6 | ||
| labels: true | ||
| ``` | ||
|
|
||
| ## Decomposition | ||
|
|
||
| `partial_decomp=TRUE` is always set. It uses | ||
| `rARPACK` (backed by `RSpectra`) for partial decompositions where supported. The | ||
| package can fall back to full eigendecomposition. It still constructs dense | ||
| edge-by-edge matrices, so memory use can grow quadratically with the number of | ||
| edge features. For example, the `egfr.yaml` configuration (19 runs, 18,851 edge features, `k=2`, `m=6`) | ||
| requires nearly 20GB memory. Completing this run may require modifying the memory | ||
| provided to the running container. | ||
|
|
||
| ## Building and publishing the image | ||
|
|
||
| Replace `<tag>` below with the tag from `LPCA_CONTAINER_SUFFIX` in | ||
| `spras/analysis/lpca.py`. Publishing to the default registry requires access | ||
| to the `reedcompbio` Docker Hub organization: | ||
|
|
||
| docker build -t "reedcompbio/lpca:<tag>" docker-wrappers/LPCA/ | ||
| docker push "reedcompbio/lpca:<tag>" | ||
|
|
||
| ## Testing | ||
| Run the test Python script to test the Docker image | ||
| ```commandline | ||
| python docker-wrappers/LPCA/test_container.py | ||
| ``` | ||
| Expected output will end with | ||
| ```commandline | ||
| === RESULT: 28 passed; 0 failed === | ||
| Container exit status: 0 | ||
| ``` | ||
|
|
||
| ## AI | ||
| GPT 6 Astra was used to refactor these files and write the test code. | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.